Convert test_case to test_matrix for arith8

old-bit-manip
Nick Krichevsky 2023-10-01 17:13:55 -04:00
parent 784d0ac8db
commit 770073489b
5 changed files with 353 additions and 401 deletions

87
Cargo.lock generated
View File

@ -46,8 +46,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
dependencies = [ dependencies = [
"proc-macro-error-attr", "proc-macro-error-attr",
"proc-macro2 1.0.36", "proc-macro2 1.0.67",
"quote 1.0.17", "quote 1.0.33",
"syn 1.0.90", "syn 1.0.90",
"version_check", "version_check",
] ]
@ -58,8 +58,8 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
dependencies = [ dependencies = [
"proc-macro2 1.0.36", "proc-macro2 1.0.67",
"quote 1.0.17", "quote 1.0.33",
"version_check", "version_check",
] ]
@ -74,11 +74,11 @@ dependencies = [
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.36" version = "1.0.67"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328"
dependencies = [ dependencies = [
"unicode-xid 0.2.2", "unicode-ident",
] ]
[[package]] [[package]]
@ -92,11 +92,11 @@ dependencies = [
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.17" version = "1.0.33"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "632d02bff7f874a36f33ea8bb416cd484b90cc66c1194b1a1110d067a7013f58" checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
dependencies = [ dependencies = [
"proc-macro2 1.0.36", "proc-macro2 1.0.67",
] ]
[[package]] [[package]]
@ -123,8 +123,8 @@ version = "1.0.147"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852" checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852"
dependencies = [ dependencies = [
"proc-macro2 1.0.36", "proc-macro2 1.0.67",
"quote 1.0.17", "quote 1.0.33",
"syn 1.0.90", "syn 1.0.90",
] ]
@ -146,8 +146,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6878079b17446e4d3eba6192bb0a2950d5b14f0ed8424b852310e5a94345d0ef" checksum = "6878079b17446e4d3eba6192bb0a2950d5b14f0ed8424b852310e5a94345d0ef"
dependencies = [ dependencies = [
"heck", "heck",
"proc-macro2 1.0.36", "proc-macro2 1.0.67",
"quote 1.0.17", "quote 1.0.33",
"rustversion", "rustversion",
"syn 1.0.90", "syn 1.0.90",
] ]
@ -169,22 +169,55 @@ version = "1.0.90"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "704df27628939572cd88d33f171cd6f896f4eaca85252c6e0a72d8d8287ee86f" checksum = "704df27628939572cd88d33f171cd6f896f4eaca85252c6e0a72d8d8287ee86f"
dependencies = [ dependencies = [
"proc-macro2 1.0.36", "proc-macro2 1.0.67",
"quote 1.0.17", "quote 1.0.33",
"unicode-xid 0.2.2", "unicode-xid 0.2.2",
] ]
[[package]] [[package]]
name = "test-case" name = "syn"
version = "2.0.2" version = "2.0.37"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6344589a99d3971d6fa4e8314dbcbeca2df6273a6b642e46906971779159af1f" checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8"
dependencies = [
"proc-macro2 1.0.67",
"quote 1.0.33",
"unicode-ident",
]
[[package]]
name = "test-case"
version = "3.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8f1e820b7f1d95a0cdbf97a5df9de10e1be731983ab943e56703ac1b8e9d425"
dependencies = [
"test-case-macros",
]
[[package]]
name = "test-case-core"
version = "3.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54c25e2cb8f5fcd7318157634e8838aa6f7e4715c96637f969fabaccd1ef5462"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"proc-macro-error", "proc-macro-error",
"proc-macro2 1.0.36", "proc-macro2 1.0.67",
"quote 1.0.17", "quote 1.0.33",
"syn 1.0.90", "syn 2.0.37",
]
[[package]]
name = "test-case-macros"
version = "3.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37cfd7bbc88a0104e304229fba519bdc45501a30b760fb72240342f1289ad257"
dependencies = [
"proc-macro-error",
"proc-macro2 1.0.67",
"quote 1.0.33",
"syn 2.0.37",
"test-case-core",
] ]
[[package]] [[package]]
@ -214,11 +247,17 @@ version = "1.0.30"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b"
dependencies = [ dependencies = [
"proc-macro2 1.0.36", "proc-macro2 1.0.67",
"quote 1.0.17", "quote 1.0.33",
"syn 1.0.90", "syn 1.0.90",
] ]
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]] [[package]]
name = "unicode-xid" name = "unicode-xid"
version = "0.1.0" version = "0.1.0"

View File

@ -10,7 +10,7 @@ thiserror = "1.0"
strum_macros = "0.24.0" strum_macros = "0.24.0"
[dev-dependencies] [dev-dependencies]
test-case = "2.0" test-case = "3.2"
serde = "1.0" serde = "1.0"
serde_json = "1.0" serde_json = "1.0"
serde_derive = "1.0" serde_derive = "1.0"

View File

@ -17,7 +17,7 @@ pub fn run_add(processor: &mut Processor, operand: Operand) -> Result<(), Error>
} }
pub fn run_add_with_carry(processor: &mut Processor, operand: Operand) -> Result<(), Error> { pub fn run_add_with_carry(processor: &mut Processor, operand: Operand) -> Result<(), Error> {
run_operation_with_carry(processor, operand, run_add_on_operands) run_operation_with_carry(processor, operand, run_add_on_operands)
} }
fn run_add_on_operands<T>(lhs: u8, rhs: T) -> OperationOutput fn run_add_on_operands<T>(lhs: u8, rhs: T) -> OperationOutput
@ -33,11 +33,11 @@ where
} }
pub fn run_sub(processor: &mut Processor, operand: Operand) -> Result<(), Error> { pub fn run_sub(processor: &mut Processor, operand: Operand) -> Result<(), Error> {
run_operation(processor, operand, run_sub_on_operands) run_operation(processor, operand, run_sub_on_operands)
} }
pub fn run_sub_with_carry(processor: &mut Processor, operand: Operand) -> Result<(), Error> { pub fn run_sub_with_carry(processor: &mut Processor, operand: Operand) -> Result<(), Error> {
run_operation_with_carry(processor, operand, run_sub_on_operands) run_operation_with_carry(processor, operand, run_sub_on_operands)
} }
fn run_sub_on_operands<T>(lhs: u8, rhs: T) -> OperationOutput fn run_sub_on_operands<T>(lhs: u8, rhs: T) -> OperationOutput

View File

@ -1,7 +1,10 @@
use crate::{ use crate::{
cpu::{ cpu::{
instructions::arith8::Operand, instructions::arith8::Operand,
run::{arithutil::{CarryingAdd, CarryingSub}, Error}, run::{
arithutil::{CarryingAdd, CarryingSub},
Error,
},
Processor, Processor,
}, },
memory, register, memory, register,

View File

@ -5,7 +5,7 @@ use ferris_boi::{
use crate::testutil; use crate::testutil;
use test_case::test_case; use test_case::{test_case, test_matrix};
struct AdditionOperationFlags { struct AdditionOperationFlags {
zero: u8, zero: u8,
@ -55,18 +55,26 @@ fn test_add_to_a_value(opcode: u8, src: register::SingleEightBit) {
assert_eq!(30, processor.registers.a); assert_eq!(30, processor.registers.a);
} }
#[test_case(0x80, register::SingleEightBit::B, 0x00, 0x00, AdditionOperationFlags{zero: 1, half_carry: 0, carry: 0}; "zero flag for zero value")] #[test_matrix(
#[test_case(0x80, register::SingleEightBit::B, 0x00, 0x01, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 0}; "no zero flag for non-zero value")] [
#[test_case(0x81, register::SingleEightBit::C, 0x0F, 0x01, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 0}; "half carry flag")] (0x00, 0x00, AdditionOperationFlags{zero: 1, half_carry: 0, carry: 0}),
#[test_case(0x81, register::SingleEightBit::C, 0x80, 0x80, AdditionOperationFlags{zero: 1, half_carry: 0, carry: 1}; "full carry flag")] (0x00, 0x01, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 0}),
#[test_case(0x81, register::SingleEightBit::C, 0xFF, 0x01, AdditionOperationFlags{zero: 1, half_carry: 1, carry: 1}; "all flags")] (0x0F, 0x01, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 0}),
// 0000 1111 (0x80, 0x80, AdditionOperationFlags{zero: 1, half_carry: 0, carry: 1}),
(0xFF, 0x01, AdditionOperationFlags{zero: 1, half_carry: 1, carry: 1})
],
[
(0x80, register::SingleEightBit::B),
(0x81, register::SingleEightBit::C),
(0x82, register::SingleEightBit::D),
(0x83, register::SingleEightBit::E),
(0x84, register::SingleEightBit::H),
(0x85, register::SingleEightBit::L),
]
)]
fn test_add_register_to_a_flags( fn test_add_register_to_a_flags(
opcode: u8, (a_value, src_value, expected_flags): (u8, u8, AdditionOperationFlags),
src: register::SingleEightBit, (opcode, src): (u8, register::SingleEightBit),
a_value: u8,
src_value: u8,
expected_flags: AdditionOperationFlags,
) { ) {
let mut processor = Processor::default(); let mut processor = Processor::default();
processor.registers.a = a_value; processor.registers.a = a_value;
@ -224,25 +232,23 @@ fn test_add_immediate_to_a_flags(a_value: u8, n: u8, expected_flags: AdditionOpe
); );
} }
#[test_case(0x88, 0x12, 0, register::SingleEightBit::B, 0x5, 0x17; "no carry to register b")] #[test_matrix(
#[test_case(0x88, 0x12, 1, register::SingleEightBit::B, 0x5, 0x18; "carry to register b")] [
#[test_case(0x89, 0x12, 0, register::SingleEightBit::C, 0x5, 0x17; "no carry to register c")] (0x88, register::SingleEightBit::B),
#[test_case(0x89, 0x12, 1, register::SingleEightBit::C, 0x5, 0x18; "carry to register c")] (0x89, register::SingleEightBit::C),
#[test_case(0x8A, 0x12, 0, register::SingleEightBit::D, 0x5, 0x17; "no carry to register d")] (0x8A, register::SingleEightBit::D),
#[test_case(0x8A, 0x12, 1, register::SingleEightBit::D, 0x5, 0x18; "carry to register d")] (0x8B, register::SingleEightBit::E),
#[test_case(0x8B, 0x12, 0, register::SingleEightBit::E, 0x5, 0x17; "no carry to register e")] (0x8C, register::SingleEightBit::H),
#[test_case(0x8B, 0x12, 1, register::SingleEightBit::E, 0x5, 0x18; "carry to register e")] (0x8D, register::SingleEightBit::L),
#[test_case(0x8C, 0x12, 0, register::SingleEightBit::H, 0x5, 0x17; "no carry to register h")] ],
#[test_case(0x8C, 0x12, 1, register::SingleEightBit::H, 0x5, 0x18; "carry to register h")] [
#[test_case(0x8D, 0x12, 0, register::SingleEightBit::L, 0x5, 0x17; "no carry to register l")] (0x12, 0x05, 0, 0x17),
#[test_case(0x8D, 0x12, 1, register::SingleEightBit::L, 0x5, 0x18; "carry to register l")] (0x12, 0x05, 1, 0x18)
]
)]
fn test_add_register_with_carry_to_a_value( fn test_add_register_with_carry_to_a_value(
opcode: u8, (opcode, operand_register): (u8, register::SingleEightBit),
initial_value: u8, (initial_value, operand, carry_bit, expected_value): (u8, u8, u8, u8),
carry_bit: u8,
operand_register: register::SingleEightBit,
operand: u8,
expected_value: u8,
) { ) {
let mut processor = Processor::default(); let mut processor = Processor::default();
processor.registers.a = initial_value; processor.registers.a = initial_value;
@ -262,74 +268,37 @@ fn test_add_register_with_carry_to_a_value(
assert_eq!(expected_value, processor.registers.a); assert_eq!(expected_value, processor.registers.a);
} }
// these parameters are like impossible to read but I can't think of a nicer way to do this right now #[test_matrix(
// B register [
#[test_case(0x88, 0x12, 0, register::SingleEightBit::B, 0x5, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 0}; "no carry bit set, results in no flags, register b")] (0x88, register::SingleEightBit::B),
#[test_case(0x88, 0x12, 1, register::SingleEightBit::B, 0x5, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 0}; "carry bit set, results in no flags, register b")] (0x89, register::SingleEightBit::C),
#[test_case(0x88, 0x00, 0, register::SingleEightBit::B, 0x0, AdditionOperationFlags{zero: 1, half_carry: 0, carry: 0}; "no carry bit set, zero operands result in zero flag set, register b")] (0x8A, register::SingleEightBit::D),
#[test_case(0x88, 0x00, 1, register::SingleEightBit::B, 0x0, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 0}; "carry bit set, zero operands result in no zero flag set, register b")] (0x8B, register::SingleEightBit::E),
#[test_case(0x88, 0x0F, 0, register::SingleEightBit::B, 0x1, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 0}; "no carry bit, half carry, register b")] (0x8C, register::SingleEightBit::H),
#[test_case(0x88, 0x0F, 1, register::SingleEightBit::B, 0x1, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 0}; "carry bit, half carry, register b")] (0x8D, register::SingleEightBit::L),
#[test_case(0x88, 0x0F, 0, register::SingleEightBit::B, 0x0F, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 0}; "no carry bit, full carry, register b")] ],
#[test_case(0x88, 0x0F, 1, register::SingleEightBit::B, 0x0F, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 0}; "carry bit, full carry, register b")] [
#[test_case(0x88, 0xFF, 1, register::SingleEightBit::B, 0xFF, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 1}; "carry bit, both carries, register b")] (0x12, 0x05, 0, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 0}),
// C register (0x12, 0x05, 1, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 0}),
#[test_case(0x89, 0x12, 0, register::SingleEightBit::C, 0x5, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 0}; "no carry bit set, results in no flags, register c")]
#[test_case(0x89, 0x12, 1, register::SingleEightBit::C, 0x5, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 0}; "carry bit set, results in no flags, register c")] (0x00, 0x00, 0, AdditionOperationFlags{zero: 1, half_carry: 0, carry: 0}),
#[test_case(0x89, 0x00, 0, register::SingleEightBit::C, 0x0, AdditionOperationFlags{zero: 1, half_carry: 0, carry: 0}; "no carry bit set, zero operands result in zero flag set, register c")] (0x00, 0x00, 1, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 0}),
#[test_case(0x89, 0x00, 1, register::SingleEightBit::C, 0x0, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 0}; "carry bit set, zero operands result in no zero flag set, register c")]
#[test_case(0x89, 0x0F, 0, register::SingleEightBit::C, 0x1, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 0}; "no carry bit, half carry, register c")] (0x0F, 0x01, 0, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 0}),
#[test_case(0x89, 0x0F, 1, register::SingleEightBit::C, 0x1, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 0}; "carry bit, half carry, register c")] (0x0F, 0x01, 1, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 0}),
#[test_case(0x89, 0x0F, 0, register::SingleEightBit::C, 0x0F, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 0}; "no carry bit, full carry, register c")] (0x0F, 0x0F, 0, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 0}),
#[test_case(0x89, 0x0F, 1, register::SingleEightBit::C, 0x0F, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 0}; "carry bit, full carry, register c")] (0x0F, 0x0F, 1, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 0}),
#[test_case(0x89, 0xFF, 1, register::SingleEightBit::C, 0xFF, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 1}; "carry bit, both carries, register c")]
// D register (0x80, 0x82, 0, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 1}),
#[test_case(0x8A, 0x12, 0, register::SingleEightBit::D, 0x5, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 0}; "no carry bit set, results in no flags, register d")] (0x80, 0x82, 1, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 1}),
#[test_case(0x8A, 0x12, 1, register::SingleEightBit::D, 0x5, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 0}; "carry bit set, results in no flags, register d")]
#[test_case(0x8A, 0x00, 0, register::SingleEightBit::D, 0x0, AdditionOperationFlags{zero: 1, half_carry: 0, carry: 0}; "no carry bit set, zero operands result in zero flag set, register d")] (0x0F, 0xFF, 0, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 1}),
#[test_case(0x8A, 0x00, 1, register::SingleEightBit::D, 0x0, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 0}; "carry bit set, zero operands result in no zero flag set, register d")] (0x7F, 0x80, 1, AdditionOperationFlags{zero: 1, half_carry: 1, carry: 1}),
#[test_case(0x8A, 0x0F, 0, register::SingleEightBit::D, 0x1, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 0}; "no carry bit, half carry, register d")] ]
#[test_case(0x8A, 0x0F, 1, register::SingleEightBit::D, 0x1, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 0}; "carry bit, half carry, register d")] ) ]
#[test_case(0x8A, 0x0F, 0, register::SingleEightBit::D, 0x0F, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 0}; "no carry bit, full carry, register d")]
#[test_case(0x8A, 0x0F, 1, register::SingleEightBit::D, 0x0F, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 0}; "carry bit, full carry, register d")]
#[test_case(0x8A, 0xFF, 1, register::SingleEightBit::D, 0xFF, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 1}; "carry bit, both carries, register d")]
// E register
#[test_case(0x8B, 0x12, 0, register::SingleEightBit::E, 0x5, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 0}; "no carry bit set, results in no flags, register e")]
#[test_case(0x8B, 0x12, 1, register::SingleEightBit::E, 0x5, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 0}; "carry bit set, results in no flags, register e")]
#[test_case(0x8B, 0x00, 0, register::SingleEightBit::E, 0x0, AdditionOperationFlags{zero: 1, half_carry: 0, carry: 0}; "no carry bit set, zero operands result in zero flag set, register e")]
#[test_case(0x8B, 0x00, 1, register::SingleEightBit::E, 0x0, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 0}; "carry bit set, zero operands result in no zero flag set, register e")]
#[test_case(0x8B, 0x0F, 0, register::SingleEightBit::E, 0x1, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 0}; "no carry bit, half carry, register e")]
#[test_case(0x8B, 0x0F, 1, register::SingleEightBit::E, 0x1, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 0}; "carry bit, half carry, register e")]
#[test_case(0x8B, 0x0F, 0, register::SingleEightBit::E, 0x0F, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 0}; "no carry bit, full carry, register e")]
#[test_case(0x8B, 0x0F, 1, register::SingleEightBit::E, 0x0F, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 0}; "carry bit, full carry, register e")]
#[test_case(0x8B, 0xFF, 1, register::SingleEightBit::E, 0xFF, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 1}; "carry bit, both carries, register e")]
// H register
#[test_case(0x8C, 0x12, 0, register::SingleEightBit::H, 0x5, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 0}; "no carry bit set, results in no flags, register h")]
#[test_case(0x8C, 0x12, 1, register::SingleEightBit::H, 0x5, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 0}; "carry bit set, results in no flags, register h")]
#[test_case(0x8C, 0x00, 0, register::SingleEightBit::H, 0x0, AdditionOperationFlags{zero: 1, half_carry: 0, carry: 0}; "no carry bit set, zero operands result in zero flag set, register h")]
#[test_case(0x8C, 0x00, 1, register::SingleEightBit::H, 0x0, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 0}; "carry bit set, zero operands result in no zero flag set, register h")]
#[test_case(0x8C, 0x0F, 0, register::SingleEightBit::H, 0x1, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 0}; "no carry bit, half carry, register h")]
#[test_case(0x8C, 0x0F, 1, register::SingleEightBit::H, 0x1, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 0}; "carry bit, half carry, register h")]
#[test_case(0x8C, 0x0F, 0, register::SingleEightBit::H, 0x0F, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 0}; "no carry bit, full carry, register h")]
#[test_case(0x8C, 0x0F, 1, register::SingleEightBit::H, 0x0F, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 0}; "carry bit, full carry, register h")]
#[test_case(0x8C, 0xFF, 1, register::SingleEightBit::H, 0xFF, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 1}; "carry bit, both carries, register h")]
// L register
#[test_case(0x8D, 0x12, 0, register::SingleEightBit::L, 0x5, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 0}; "no carry bit set, results in no flags, register l")]
#[test_case(0x8D, 0x12, 1, register::SingleEightBit::L, 0x5, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 0}; "carry bit set, results in no flags, register l")]
#[test_case(0x8D, 0x00, 0, register::SingleEightBit::L, 0x0, AdditionOperationFlags{zero: 1, half_carry: 0, carry: 0}; "no carry bit set, zero operands result in zero flag set, register l")]
#[test_case(0x8D, 0x00, 1, register::SingleEightBit::L, 0x0, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 0}; "carry bit set, zero operands result in no zero flag set, register l")]
#[test_case(0x8D, 0x0F, 0, register::SingleEightBit::L, 0x1, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 0}; "no carry bit, half carry, register l")]
#[test_case(0x8D, 0x0F, 1, register::SingleEightBit::L, 0x1, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 0}; "carry bit, half carry, register l")]
#[test_case(0x8D, 0x0F, 0, register::SingleEightBit::L, 0x0F, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 0}; "no carry bit, full carry, register l")]
#[test_case(0x8D, 0x0F, 1, register::SingleEightBit::L, 0x0F, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 0}; "carry bit, full carry, register l")]
#[test_case(0x8D, 0xFF, 1, register::SingleEightBit::L, 0xFF, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 1}; "carry bit, both carries, register l")]
fn test_add_register_with_carry_to_a_flags( fn test_add_register_with_carry_to_a_flags(
opcode: u8, (opcode, operand_register): (u8, register::SingleEightBit),
initial_value: u8, (initial_value, operand, carry_bit, expected_flags): (u8, u8, u8, AdditionOperationFlags),
carry_bit: u8,
operand_register: register::SingleEightBit,
operand: u8,
expected_flags: AdditionOperationFlags,
) { ) {
let mut processor = Processor::default(); let mut processor = Processor::default();
processor.registers.a = initial_value; processor.registers.a = initial_value;
@ -572,18 +541,23 @@ fn test_add_hl_addr_to_a_with_carry_flags(
); );
} }
#[test_case(0x90, 0xFF, 0x0F, register::SingleEightBit::B, 0xF0; "subtract B")] #[test_matrix(
#[test_case(0x91, 0xFF, 0x0F, register::SingleEightBit::C, 0xF0; "subtract C")] [
#[test_case(0x92, 0xFF, 0x0F, register::SingleEightBit::D, 0xF0; "subtract D")] (0x90, register::SingleEightBit::B),
#[test_case(0x93, 0xFF, 0x0F, register::SingleEightBit::E, 0xF0; "subtract E")] (0x91, register::SingleEightBit::C),
#[test_case(0x94, 0xFF, 0x0F, register::SingleEightBit::H, 0xF0; "subtract H")] (0x92, register::SingleEightBit::D),
#[test_case(0x95, 0xFF, 0x0F, register::SingleEightBit::L, 0xF0; "subtract L")] (0x93, register::SingleEightBit::E),
(0x94, register::SingleEightBit::H),
(0x95, register::SingleEightBit::L),
],
[
(0xFF, 0x0F, 0xF0),
(0x00, 0x03, 0xFD),
]
)]
fn test_sub_register_from_a_value( fn test_sub_register_from_a_value(
opcode: u8, (opcode, operand_register): (u8, register::SingleEightBit),
a_value: u8, (a_value, operand, expected): (u8, u8, u8),
operand: u8,
operand_register: register::SingleEightBit,
expected: u8,
) { ) {
let mut processor = Processor::default(); let mut processor = Processor::default();
processor.registers.a = a_value; processor.registers.a = a_value;
@ -601,36 +575,25 @@ fn test_sub_register_from_a_value(
assert_eq!(processor.registers.a, expected); assert_eq!(processor.registers.a, expected);
} }
#[test_case(0x90, 0xFF, 0x0F, register::SingleEightBit::B, AdditionOperationFlags { zero: 0, half_carry: 0, carry: 0 }; "no flags from B")] #[test_matrix(
#[test_case(0x90, 0xF0, 0x0F, register::SingleEightBit::B, AdditionOperationFlags { zero: 0, half_carry: 1, carry: 0 }; "half carry from B")] [
#[test_case(0x90, 0x0F, 0xF0, register::SingleEightBit::B, AdditionOperationFlags { zero: 0, half_carry: 0, carry: 1 }; "full carry from B")] (0x90, register::SingleEightBit::B),
#[test_case(0x90, 0x01, 0x01, register::SingleEightBit::B, AdditionOperationFlags { zero: 1, half_carry: 0, carry: 0 }; "zero from B")] (0x91, register::SingleEightBit::C),
#[test_case(0x91, 0xFF, 0x0F, register::SingleEightBit::C, AdditionOperationFlags { zero: 0, half_carry: 0, carry: 0 }; "no flags from C")] (0x92, register::SingleEightBit::D),
#[test_case(0x91, 0xF0, 0x0F, register::SingleEightBit::C, AdditionOperationFlags { zero: 0, half_carry: 1, carry: 0 }; "half carry from C")] (0x93, register::SingleEightBit::E),
#[test_case(0x91, 0x0F, 0xF0, register::SingleEightBit::C, AdditionOperationFlags { zero: 0, half_carry: 0, carry: 1 }; "full carry from C")] (0x94, register::SingleEightBit::H),
#[test_case(0x91, 0x01, 0x01, register::SingleEightBit::C, AdditionOperationFlags { zero: 1, half_carry: 0, carry: 0 }; "zero from C")] (0x95, register::SingleEightBit::L),
#[test_case(0x92, 0xFF, 0x0F, register::SingleEightBit::D, AdditionOperationFlags { zero: 0, half_carry: 0, carry: 0 }; "no flags from D")] ],
#[test_case(0x92, 0xF0, 0x0F, register::SingleEightBit::D, AdditionOperationFlags { zero: 0, half_carry: 1, carry: 0 }; "half carry from D")] [
#[test_case(0x92, 0x0F, 0xF0, register::SingleEightBit::D, AdditionOperationFlags { zero: 0, half_carry: 0, carry: 1 }; "full carry from D")] (0xFF, 0x0F, AdditionOperationFlags{ zero: 0, half_carry: 0, carry: 0 }),
#[test_case(0x92, 0x01, 0x01, register::SingleEightBit::D, AdditionOperationFlags { zero: 1, half_carry: 0, carry: 0 }; "zero from D")] (0xF0, 0x0F, AdditionOperationFlags{ zero: 0, half_carry: 1, carry: 0 }),
#[test_case(0x93, 0xFF, 0x0F, register::SingleEightBit::E, AdditionOperationFlags { zero: 0, half_carry: 0, carry: 0 }; "no flags from E")] (0x0F, 0xF0, AdditionOperationFlags{ zero: 0, half_carry: 0, carry: 1 }),
#[test_case(0x93, 0xF0, 0x0F, register::SingleEightBit::E, AdditionOperationFlags { zero: 0, half_carry: 1, carry: 0 }; "half carry from E")] (0x01, 0x01, AdditionOperationFlags{ zero: 1, half_carry: 0, carry: 0 })
#[test_case(0x93, 0x0F, 0xF0, register::SingleEightBit::E, AdditionOperationFlags { zero: 0, half_carry: 0, carry: 1 }; "full carry from E")] ]
#[test_case(0x93, 0x01, 0x01, register::SingleEightBit::E, AdditionOperationFlags { zero: 1, half_carry: 0, carry: 0 }; "zero from E")] )]
#[test_case(0x94, 0xFF, 0x0F, register::SingleEightBit::H, AdditionOperationFlags { zero: 0, half_carry: 0, carry: 0 }; "no flags from H")]
#[test_case(0x94, 0xF0, 0x0F, register::SingleEightBit::H, AdditionOperationFlags { zero: 0, half_carry: 1, carry: 0 }; "half carry from H")]
#[test_case(0x94, 0x0F, 0xF0, register::SingleEightBit::H, AdditionOperationFlags { zero: 0, half_carry: 0, carry: 1 }; "full carry from H")]
#[test_case(0x94, 0x01, 0x01, register::SingleEightBit::H, AdditionOperationFlags { zero: 1, half_carry: 0, carry: 0 }; "zero from H")]
#[test_case(0x95, 0xFF, 0x0F, register::SingleEightBit::L, AdditionOperationFlags { zero: 0, half_carry: 0, carry: 0 }; "no flags from L")]
#[test_case(0x95, 0xF0, 0x0F, register::SingleEightBit::L, AdditionOperationFlags { zero: 0, half_carry: 1, carry: 0 }; "half carry from L")]
#[test_case(0x95, 0x0F, 0xF0, register::SingleEightBit::L, AdditionOperationFlags { zero: 0, half_carry: 0, carry: 1 }; "full carry from L")]
#[test_case(0x95, 0x01, 0x01, register::SingleEightBit::L, AdditionOperationFlags { zero: 1, half_carry: 0, carry: 0 }; "zero from L")]
fn test_sub_register_from_a_flags( fn test_sub_register_from_a_flags(
opcode: u8, (opcode, operand_register): (u8, register::SingleEightBit),
a_value: u8, (a_value, operand, expected_flags): (u8, u8, AdditionOperationFlags),
operand: u8,
operand_register: register::SingleEightBit,
expected_flags: AdditionOperationFlags,
) { ) {
let mut processor = Processor::default(); let mut processor = Processor::default();
processor.registers.a = a_value; processor.registers.a = a_value;
@ -689,25 +652,23 @@ fn test_sub_a_from_itself() {
); );
} }
#[test_case(0x98, 0xFF, 0x0F, 0, register::SingleEightBit::B, 0xF0; "subtract B with no carry")] #[test_matrix(
#[test_case(0x98, 0xFF, 0x0F, 1, register::SingleEightBit::B, 0xEF; "subtract B with carry")] [
#[test_case(0x99, 0xFF, 0x0F, 0, register::SingleEightBit::C, 0xF0; "subtract C with no carry")] (0x98, register::SingleEightBit::B),
#[test_case(0x99, 0xFF, 0x0F, 1, register::SingleEightBit::C, 0xEF; "subtract C with carry")] (0x99, register::SingleEightBit::C),
#[test_case(0x9A, 0xFF, 0x0F, 0, register::SingleEightBit::D, 0xF0; "subtract D with no carry")] (0x9A, register::SingleEightBit::D),
#[test_case(0x9A, 0xFF, 0x0F, 1, register::SingleEightBit::D, 0xEF; "subtract D with carry")] (0x9B, register::SingleEightBit::E),
#[test_case(0x9B, 0xFF, 0x0F, 0, register::SingleEightBit::E, 0xF0; "subtract E with no carry")] (0x9C, register::SingleEightBit::H),
#[test_case(0x9B, 0xFF, 0x0F, 1, register::SingleEightBit::E, 0xEF; "subtract E with carry")] (0x9D, register::SingleEightBit::L),
#[test_case(0x9C, 0xFF, 0x0F, 0, register::SingleEightBit::H, 0xF0; "subtract H with no carry")] ],
#[test_case(0x9C, 0xFF, 0x0F, 1, register::SingleEightBit::H, 0xEF; "subtract H with carry")] [
#[test_case(0x9D, 0xFF, 0x0F, 0, register::SingleEightBit::L, 0xF0; "subtract L with no carry")] (0xFF, 0x0F, 0, 0xF0),
#[test_case(0x9D, 0xFF, 0x0F, 1, register::SingleEightBit::L, 0xEF; "subtract L with carry")] (0xFF, 0x0F, 1, 0xEF)
]
)]
fn test_sub_register_with_carry_from_a_value( fn test_sub_register_with_carry_from_a_value(
opcode: u8, (opcode, operand_register): (u8, register::SingleEightBit),
a_value: u8, (a_value, operand, carry_bit, expected): (u8, u8, u8, u8),
operand: u8,
carry_bit: u8,
operand_register: register::SingleEightBit,
expected: u8,
) { ) {
let mut processor = Processor::default(); let mut processor = Processor::default();
processor.registers.a = a_value; processor.registers.a = a_value;
@ -727,74 +688,33 @@ fn test_sub_register_with_carry_from_a_value(
processor.run_instruction(&ins); processor.run_instruction(&ins);
assert_eq!(processor.registers.a, expected); assert_eq!(processor.registers.a, expected);
} }
#[test_matrix(
[
(0x98, register::SingleEightBit::B),
(0x99, register::SingleEightBit::C),
(0x9A, register::SingleEightBit::D),
(0x9B, register::SingleEightBit::E),
(0x9C, register::SingleEightBit::H),
(0x9D, register::SingleEightBit::L),
],
[
(0xFE, 0x01, 0, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 0}),
(0xFE, 0x01, 1, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 0}),
// Register B (0x00, 0x00, 0, AdditionOperationFlags{zero: 1, half_carry: 0, carry: 0}),
#[test_case(0x98, 0xFE, 0, register::SingleEightBit::B, 0x1, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 0}; "no carry bit set, results in no flags, register b")] (0x01, 0x00, 1, AdditionOperationFlags{zero: 1, half_carry: 0, carry: 0}),
#[test_case(0x98, 0xFE, 1, register::SingleEightBit::B, 0x1, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 0}; "carry bit set, results in no flags, register b")] (0x02, 0x02, 0, AdditionOperationFlags{zero: 1, half_carry: 0, carry: 0}),
#[test_case(0x98, 0x00, 0, register::SingleEightBit::B, 0x0, AdditionOperationFlags{zero: 1, half_carry: 0, carry: 0}; "all zero operands give zero flag, register b")]
#[test_case(0x98, 0x01, 1, register::SingleEightBit::B, 0x0, AdditionOperationFlags{zero: 1, half_carry: 0, carry: 0}; "subtracting from 1 gives zero flag with carry bit, register b")] (0xF0, 0x0F, 0, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 0}),
#[test_case(0x98, 0x02, 0, register::SingleEightBit::B, 0x2, AdditionOperationFlags{zero: 1, half_carry: 0, carry: 0}; "subtracting from 2 gives zero flag with no, register b")] (0x0F, 0xF0, 0, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 1}),
#[test_case(0x98, 0xF0, 0, register::SingleEightBit::B, 0x0F, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 0}; "no carry bit set, half carry bit, register b")]
#[test_case(0x98, 0x0F, 0, register::SingleEightBit::B, 0xF0, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 1}; "no carry bit set, full carry bit, register b")] (0xF0, 0x0E, 1, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 0}),
#[test_case(0x98, 0xF0, 1, register::SingleEightBit::B, 0x0E, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 0}; "carry bit set, half carry bit, register b")] (0x0F, 0xEE, 1, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 1}),
#[test_case(0x98, 0x0F, 1, register::SingleEightBit::B, 0xEE, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 1}; "carry bit set, full carry bit, register b")] ]
// Register C )]
#[test_case(0x99, 0xFE, 0, register::SingleEightBit::C, 0x1, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 0}; "no carry bit set, results in no flags, register c")]
#[test_case(0x99, 0xFE, 1, register::SingleEightBit::C, 0x1, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 0}; "carry bit set, results in no flags, register c")]
#[test_case(0x99, 0x00, 0, register::SingleEightBit::C, 0x0, AdditionOperationFlags{zero: 1, half_carry: 0, carry: 0}; "all zero operands give zero flag, register c")]
#[test_case(0x99, 0x01, 1, register::SingleEightBit::C, 0x0, AdditionOperationFlags{zero: 1, half_carry: 0, carry: 0}; "subtracting from 1 gives zero flag with carry bit, register c")]
#[test_case(0x99, 0x02, 0, register::SingleEightBit::C, 0x2, AdditionOperationFlags{zero: 1, half_carry: 0, carry: 0}; "subtracting from 2 gives zero flag with no, register c")]
#[test_case(0x99, 0xF0, 0, register::SingleEightBit::C, 0x0F, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 0}; "no carry bit set, half carry bit, register c")]
#[test_case(0x99, 0x0F, 0, register::SingleEightBit::C, 0xF0, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 1}; "no carry bit set, full carry bit, register c")]
#[test_case(0x99, 0xF0, 1, register::SingleEightBit::C, 0x0E, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 0}; "carry bit set, half carry bit, register c")]
#[test_case(0x99, 0x0F, 1, register::SingleEightBit::C, 0xEE, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 1}; "carry bit set, full carry bit, register c")]
// Register D
#[test_case(0x9A, 0xFE, 0, register::SingleEightBit::D, 0x1, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 0}; "no carry bit set, results in no flags, register d")]
#[test_case(0x9A, 0xFE, 1, register::SingleEightBit::D, 0x1, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 0}; "carry bit set, results in no flags, register d")]
#[test_case(0x9A, 0x00, 0, register::SingleEightBit::D, 0x0, AdditionOperationFlags{zero: 1, half_carry: 0, carry: 0}; "all zero operands give zero flag, register d")]
#[test_case(0x9A, 0x01, 1, register::SingleEightBit::D, 0x0, AdditionOperationFlags{zero: 1, half_carry: 0, carry: 0}; "subtracting from 1 gives zero flag with carry bit, register d")]
#[test_case(0x9A, 0x02, 0, register::SingleEightBit::D, 0x2, AdditionOperationFlags{zero: 1, half_carry: 0, carry: 0}; "subtracting from 2 gives zero flag with no, register d")]
#[test_case(0x9A, 0xF0, 0, register::SingleEightBit::D, 0x0F, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 0}; "no carry bit set, half carry bit, register d")]
#[test_case(0x9A, 0x0F, 0, register::SingleEightBit::D, 0xF0, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 1}; "no carry bit set, full carry bit, register d")]
#[test_case(0x9A, 0xF0, 1, register::SingleEightBit::D, 0x0E, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 0}; "carry bit set, half carry bit, register d")]
#[test_case(0x9A, 0x0F, 1, register::SingleEightBit::D, 0xEE, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 1}; "carry bit set, full carry bit, register d")]
// Register E
#[test_case(0x9B, 0xFE, 0, register::SingleEightBit::E, 0x1, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 0}; "no carry bit set, results in no flags, register e")]
#[test_case(0x9B, 0xFE, 1, register::SingleEightBit::E, 0x1, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 0}; "carry bit set, results in no flags, register e")]
#[test_case(0x9B, 0x00, 0, register::SingleEightBit::E, 0x0, AdditionOperationFlags{zero: 1, half_carry: 0, carry: 0}; "all zero operands give zero flag, register e")]
#[test_case(0x9B, 0x01, 1, register::SingleEightBit::E, 0x0, AdditionOperationFlags{zero: 1, half_carry: 0, carry: 0}; "subtracting from 1 gives zero flag with carry bit, register e")]
#[test_case(0x9B, 0x02, 0, register::SingleEightBit::E, 0x2, AdditionOperationFlags{zero: 1, half_carry: 0, carry: 0}; "subtracting from 2 gives zero flag with no, register e")]
#[test_case(0x9B, 0xF0, 0, register::SingleEightBit::E, 0x0F, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 0}; "no carry bit set, half carry bit, register e")]
#[test_case(0x9B, 0x0F, 0, register::SingleEightBit::E, 0xF0, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 1}; "no carry bit set, full carry bit, register e")]
#[test_case(0x9B, 0xF0, 1, register::SingleEightBit::E, 0x0E, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 0}; "carry bit set, half carry bit, register e")]
#[test_case(0x9B, 0x0F, 1, register::SingleEightBit::E, 0xEE, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 1}; "carry bit set, full carry bit, register e")]
// Register H
#[test_case(0x9C, 0xFE, 0, register::SingleEightBit::H, 0x1, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 0}; "no carry bit set, results in no flags, register h")]
#[test_case(0x9C, 0xFE, 1, register::SingleEightBit::H, 0x1, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 0}; "carry bit set, results in no flags, register h")]
#[test_case(0x9C, 0x00, 0, register::SingleEightBit::H, 0x0, AdditionOperationFlags{zero: 1, half_carry: 0, carry: 0}; "all zero operands give zero flag, register h")]
#[test_case(0x9C, 0x01, 1, register::SingleEightBit::H, 0x0, AdditionOperationFlags{zero: 1, half_carry: 0, carry: 0}; "subtracting from 1 gives zero flag with carry bit, register h")]
#[test_case(0x9C, 0x02, 0, register::SingleEightBit::H, 0x2, AdditionOperationFlags{zero: 1, half_carry: 0, carry: 0}; "subtracting from 2 gives zero flag with no, register h")]
#[test_case(0x9C, 0xF0, 0, register::SingleEightBit::H, 0x0F, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 0}; "no carry bit set, half carry bit, register h")]
#[test_case(0x9C, 0x0F, 0, register::SingleEightBit::H, 0xF0, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 1}; "no carry bit set, full carry bit, register h")]
#[test_case(0x9C, 0xF0, 1, register::SingleEightBit::H, 0x0E, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 0}; "carry bit set, half carry bit, register h")]
#[test_case(0x9C, 0x0F, 1, register::SingleEightBit::H, 0xEE, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 1}; "carry bit set, full carry bit, register h")]
// Register L
#[test_case(0x9D, 0xFE, 0, register::SingleEightBit::L, 0x1, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 0}; "no carry bit set, results in no flags, register l")]
#[test_case(0x9D, 0xFE, 1, register::SingleEightBit::L, 0x1, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 0}; "carry bit set, results in no flags, register l")]
#[test_case(0x9D, 0x00, 0, register::SingleEightBit::L, 0x0, AdditionOperationFlags{zero: 1, half_carry: 0, carry: 0}; "all zero operands give zero flag, register l")]
#[test_case(0x9D, 0x01, 1, register::SingleEightBit::L, 0x0, AdditionOperationFlags{zero: 1, half_carry: 0, carry: 0}; "subtracting from 1 gives zero flag with carry bit, register l")]
#[test_case(0x9D, 0x02, 0, register::SingleEightBit::L, 0x2, AdditionOperationFlags{zero: 1, half_carry: 0, carry: 0}; "subtracting from 2 gives zero flag with no, register l")]
#[test_case(0x9D, 0xF0, 0, register::SingleEightBit::L, 0x0F, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 0}; "no carry bit set, half carry bit, register l")]
#[test_case(0x9D, 0x0F, 0, register::SingleEightBit::L, 0xF0, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 1}; "no carry bit set, full carry bit, register l")]
#[test_case(0x9D, 0xF0, 1, register::SingleEightBit::L, 0x0E, AdditionOperationFlags{zero: 0, half_carry: 1, carry: 0}; "carry bit set, half carry bit, register l")]
#[test_case(0x9D, 0x0F, 1, register::SingleEightBit::L, 0xEE, AdditionOperationFlags{zero: 0, half_carry: 0, carry: 1}; "carry bit set, full carry bit, register l")]
fn test_sub_register_from_carry_from_a_flags( fn test_sub_register_from_carry_from_a_flags(
opcode: u8, (opcode, operand_register): (u8, register::SingleEightBit),
initial_value: u8, (initial_value, operand, carry_bit, expected_flags): (u8, u8, u8, AdditionOperationFlags),
carry_bit: u8,
operand_register: register::SingleEightBit,
operand: u8,
expected_flags: AdditionOperationFlags,
) { ) {
let mut processor = Processor::default(); let mut processor = Processor::default();
processor.registers.a = initial_value; processor.registers.a = initial_value;
@ -1191,20 +1111,21 @@ fn test_and_single_register_with_a_value(
assert_eq!(expected_value, processor.registers.a); assert_eq!(expected_value, processor.registers.a);
} }
#[test_case(0xA0, 0xFA, register::SingleEightBit::B, 0x0F, 0; "AND with B, not zero")] #[test_matrix(
#[test_case(0xA0, 0xFA, register::SingleEightBit::B, 0x00, 1; "AND with B, zero")] [
#[test_case(0xA1, 0xFA, register::SingleEightBit::C, 0x0F, 0; "AND with C, not zero")] (0xA0, register::SingleEightBit::B),
#[test_case(0xA1, 0xFA, register::SingleEightBit::C, 0x00, 1; "AND with C, zero")] (0xA1, register::SingleEightBit::C),
#[test_case(0xA2, 0xFA, register::SingleEightBit::D, 0x0F, 0; "AND with D, not zero")] (0xA2, register::SingleEightBit::D),
#[test_case(0xA2, 0xFA, register::SingleEightBit::D, 0x00, 1; "AND with D, zero")] (0xA3, register::SingleEightBit::E),
#[test_case(0xA3, 0xFA, register::SingleEightBit::E, 0x0F, 0; "AND with E, not zero")] ],
#[test_case(0xA3, 0xFA, register::SingleEightBit::E, 0x00, 1; "AND with E, zero")] [
(0xFA, 0x0F, 0),
(0xFA, 0x00, 1),
]
)]
fn test_and_single_register_with_a_flags( fn test_and_single_register_with_a_flags(
opcode: u8, (opcode, operand_register): (u8, register::SingleEightBit),
a_value: u8, (a_value, operand, expected_zero_flag): (u8, u8, u8),
operand_register: register::SingleEightBit,
operand: u8,
expected_zero_flag: u8,
) { ) {
let mut processor = Processor::default(); let mut processor = Processor::default();
// Set all the register to the opposite we expect to ensure they all get set // Set all the register to the opposite we expect to ensure they all get set
@ -1357,12 +1278,12 @@ fn test_and_immediate_with_a_flags(a_value: u8, operand: u8, expected_zero_flag:
); );
} }
#[test_case(0xA8, 0xFF, register::SingleEightBit::B, 0xCC, 0x33; "register b")] #[test_case(0xA8, 0xFF, register::SingleEightBit::B, 0xCC, 0x33; "register B")]
#[test_case(0xA9, 0xFF, register::SingleEightBit::C, 0x33, 0xCC; "register c")] #[test_case(0xA9, 0xFF, register::SingleEightBit::C, 0x33, 0xCC; "register C")]
#[test_case(0xAA, 0xFF, register::SingleEightBit::D, 0xCC, 0x33; "register d")] #[test_case(0xAA, 0xFF, register::SingleEightBit::D, 0xCC, 0x33; "register D")]
#[test_case(0xAB, 0xFF, register::SingleEightBit::E, 0x33, 0xCC; "register e")] #[test_case(0xAB, 0xFF, register::SingleEightBit::E, 0x33, 0xCC; "register E")]
#[test_case(0xAC, 0xFF, register::SingleEightBit::H, 0xCC, 0x33; "register h")] #[test_case(0xAC, 0xFF, register::SingleEightBit::H, 0xCC, 0x33; "register H")]
#[test_case(0xAD, 0xFF, register::SingleEightBit::L, 0x33, 0xCC; "register l")] #[test_case(0xAD, 0xFF, register::SingleEightBit::L, 0x33, 0xCC; "register L")]
fn test_xor_register_with_a_value( fn test_xor_register_with_a_value(
opcode: u8, opcode: u8,
a_value: u8, a_value: u8,
@ -1387,24 +1308,23 @@ fn test_xor_register_with_a_value(
assert_eq!(expected_value, processor.registers.a); assert_eq!(expected_value, processor.registers.a);
} }
#[test_case(0xA8, 0xFF, register::SingleEightBit::B, 0xCC, 0; "register b, not zero")] #[test_matrix(
#[test_case(0xA8, 0xCC, register::SingleEightBit::B, 0xCC, 1; "register b, zero")] [
#[test_case(0xA9, 0xFF, register::SingleEightBit::C, 0x33, 0; "register c, not zero")] (0xA8, register::SingleEightBit::B),
#[test_case(0xA9, 0x33, register::SingleEightBit::C, 0x33, 1; "register c, zero")] (0xA9, register::SingleEightBit::C),
#[test_case(0xAA, 0xFF, register::SingleEightBit::D, 0xCC, 0; "register d, not zero")] (0xAA, register::SingleEightBit::D),
#[test_case(0xAA, 0xCC, register::SingleEightBit::D, 0xCC, 1; "register d, zero")] (0xAB, register::SingleEightBit::E),
#[test_case(0xAB, 0xFF, register::SingleEightBit::E, 0x33, 0; "register e, not zero")] (0xAC, register::SingleEightBit::H),
#[test_case(0xAB, 0x33, register::SingleEightBit::E, 0x33, 1; "register e, zero")] (0xAD, register::SingleEightBit::L),
#[test_case(0xAC, 0xFF, register::SingleEightBit::H, 0xCC, 0; "register h, not zero")] ],
#[test_case(0xAC, 0xCC, register::SingleEightBit::H, 0xCC, 1; "register h, zero")] [
#[test_case(0xAD, 0xFF, register::SingleEightBit::L, 0x33, 0; "register l, not zero")] (0xFF, 0xCC, 0),
#[test_case(0xAD, 0x33, register::SingleEightBit::L, 0x33, 1; "register l, zero")] (0xCC, 0xCC, 1),
]
)]
fn test_xor_register_with_a_flags( fn test_xor_register_with_a_flags(
opcode: u8, (opcode, operand_register): (u8, register::SingleEightBit),
a_value: u8, (a_value, operand, expected_zero_flag): (u8, u8, u8),
operand_register: register::SingleEightBit,
operand: u8,
expected_zero_flag: u8,
) { ) {
let mut processor = Processor::default(); let mut processor = Processor::default();
// Set all the register to the opposite we expect to ensure they all get set // Set all the register to the opposite we expect to ensure they all get set
@ -1562,18 +1482,23 @@ fn test_xor_immediate_value_with_a_flags(a_value: u8, operand: u8, expected_zero
); );
} }
#[test_case(0xB0, 0xCC, register::SingleEightBit::B, 0x11, 0xDD; "register b")] #[test_matrix(
#[test_case(0xB1, 0xCC, register::SingleEightBit::C, 0x11, 0xDD; "register c")] [
#[test_case(0xB2, 0xCC, register::SingleEightBit::D, 0x11, 0xDD; "register d")] (0xB0, register::SingleEightBit:: B),
#[test_case(0xB3, 0xCC, register::SingleEightBit::E, 0x11, 0xDD; "register e")] (0xB1, register::SingleEightBit:: C),
#[test_case(0xB4, 0xCC, register::SingleEightBit::H, 0x11, 0xDD; "register h")] (0xB2, register::SingleEightBit:: D),
#[test_case(0xB5, 0xCC, register::SingleEightBit::L, 0x11, 0xDD; "register l")] (0xB3, register::SingleEightBit:: E),
(0xB4, register::SingleEightBit:: H),
(0xB5, register::SingleEightBit:: L),
],
[
(0xCC, 0x11, 0xDD),
(0x00, 0x1F, 0x1F)
]
)]
fn test_or_register_with_a_value( fn test_or_register_with_a_value(
opcode: u8, (opcode, operand_register): (u8, register::SingleEightBit),
a_value: u8, (a_value, operand, expected_value): (u8, u8, u8),
operand_register: register::SingleEightBit,
operand: u8,
expected_value: u8,
) { ) {
let mut processor = Processor::default(); let mut processor = Processor::default();
processor processor
@ -1592,24 +1517,23 @@ fn test_or_register_with_a_value(
assert_eq!(expected_value, processor.registers.a); assert_eq!(expected_value, processor.registers.a);
} }
#[test_case(0xB0, 0xCC, register::SingleEightBit::B, 0x22, 0; "register b, not zero")] #[test_matrix(
#[test_case(0xB0, 0x00, register::SingleEightBit::B, 0x00, 1; "register b, zero")] [
#[test_case(0xB1, 0xCC, register::SingleEightBit::C, 0x22, 0; "register c, not zero")] (0xB0, register::SingleEightBit::B),
#[test_case(0xB1, 0x00, register::SingleEightBit::C, 0x00, 1; "register c, zero")] (0xB1, register::SingleEightBit::C),
#[test_case(0xB2, 0xCC, register::SingleEightBit::D, 0x22, 0; "register d, not zero")] (0xB2, register::SingleEightBit::D),
#[test_case(0xB2, 0x00, register::SingleEightBit::D, 0x00, 1; "register d, zero")] (0xB3, register::SingleEightBit::E),
#[test_case(0xB3, 0xCC, register::SingleEightBit::E, 0x22, 0; "register e, not zero")] (0xB4, register::SingleEightBit::H),
#[test_case(0xB3, 0x00, register::SingleEightBit::E, 0x00, 1; "register e, zero")] (0xB5, register::SingleEightBit::L),
#[test_case(0xB4, 0xCC, register::SingleEightBit::H, 0x22, 0; "register h, not zero")] ],
#[test_case(0xB4, 0x00, register::SingleEightBit::H, 0x00, 1; "register h, zero")] [
#[test_case(0xB5, 0xCC, register::SingleEightBit::L, 0x22, 0; "register l, not zero")] (0xCC, 0x22, 0),
#[test_case(0xB5, 0x00, register::SingleEightBit::L, 0x00, 1; "register l, zero")] (0x00, 0x00, 1),
]
)]
fn test_or_register_with_a_flags( fn test_or_register_with_a_flags(
opcode: u8, (opcode, operand_register): (u8, register::SingleEightBit),
a_value: u8, (a_value, operand, expected_zero_flag): (u8, u8, u8),
operand_register: register::SingleEightBit,
operand: u8,
expected_zero_flag: u8,
) { ) {
let mut processor = Processor::default(); let mut processor = Processor::default();
// Set all the register to the opposite we expect to ensure they all get set // Set all the register to the opposite we expect to ensure they all get set
@ -2136,40 +2060,41 @@ fn test_comparing_immediate_value_to_a(
); );
} }
#[test_case(0x04, register::SingleEightBit::B, 0x05, 0x06; "add one, register B")] // increment
#[test_case(0x04, register::SingleEightBit::B, 0xFF, 0x00; "add one with wrapping, register B")] #[test_matrix(
#[test_case(0x0C, register::SingleEightBit::C, 0x05, 0x06; "add one, register C")] [
#[test_case(0x0C, register::SingleEightBit::C, 0xFF, 0x00; "add one with wrapping, register C")] (0x04, register::SingleEightBit:: B),
#[test_case(0x14, register::SingleEightBit::D, 0x05, 0x06; "add one, register D")] (0x0C, register::SingleEightBit:: C),
#[test_case(0x14, register::SingleEightBit::D, 0xFF, 0x00; "add one with wrapping, register D")] (0x14, register::SingleEightBit:: D),
#[test_case(0x1C, register::SingleEightBit::E, 0x05, 0x06; "add one, register E")] (0x1C, register::SingleEightBit:: E),
#[test_case(0x1C, register::SingleEightBit::E, 0xFF, 0x00; "add one with wrapping, register E")] (0x24, register::SingleEightBit:: H),
#[test_case(0x24, register::SingleEightBit::H, 0x05, 0x06; "add one, register H")] (0x2C, register::SingleEightBit:: L),
#[test_case(0x24, register::SingleEightBit::H, 0xFF, 0x00; "add one with wrapping, register H")] (0x3C, register::SingleEightBit:: A),
#[test_case(0x2C, register::SingleEightBit::L, 0x05, 0x06; "add one, register L")] ],
#[test_case(0x2C, register::SingleEightBit::L, 0xFF, 0x00; "add one with wrapping, register L")] [
#[test_case(0x3C, register::SingleEightBit::A, 0x05, 0x06; "add one, register A")] (0x05, 0x06),
#[test_case(0x3C, register::SingleEightBit::A, 0xFF, 0x00; "add one with wrapping, register A")] (0xFF, 0x00),
]
)]
// decrement // decrement
#[test_case(0x05, register::SingleEightBit::B, 0x05, 0x04; "sub one, register B")] #[test_matrix(
#[test_case(0x05, register::SingleEightBit::B, 0x00, 0xFF; "sub one with wrapping, register B")] [
#[test_case(0x0D, register::SingleEightBit::C, 0x05, 0x04; "sub one, register C")] (0x05, register::SingleEightBit:: B),
#[test_case(0x0D, register::SingleEightBit::C, 0x00, 0xFF; "sub one with wrapping, register C")] (0x0D, register::SingleEightBit:: C),
#[test_case(0x15, register::SingleEightBit::D, 0x05, 0x04; "sub one, register D")] (0x15, register::SingleEightBit:: D),
#[test_case(0x15, register::SingleEightBit::D, 0x00, 0xFF; "sub one with wrapping, register D")] (0x1D, register::SingleEightBit:: E),
#[test_case(0x1D, register::SingleEightBit::E, 0x05, 0x04; "sub one, register E")] (0x25, register::SingleEightBit:: H),
#[test_case(0x1D, register::SingleEightBit::E, 0x00, 0xFF; "sub one with wrapping, register E")] (0x2D, register::SingleEightBit:: L),
#[test_case(0x25, register::SingleEightBit::H, 0x05, 0x04; "sub one, register H")] (0x3D, register::SingleEightBit:: A),
#[test_case(0x25, register::SingleEightBit::H, 0x00, 0xFF; "sub one with wrapping, register H")] ],
#[test_case(0x2D, register::SingleEightBit::L, 0x05, 0x04; "sub one, register L")] [
#[test_case(0x2D, register::SingleEightBit::L, 0x00, 0xFF; "sub one with wrapping, register L")] (0x05, 0x04),
#[test_case(0x3D, register::SingleEightBit::A, 0x05, 0x04; "sub one, register A")] (0x00, 0xFF),
#[test_case(0x3D, register::SingleEightBit::A, 0x00, 0xFF; "sub one with wrapping, register A")] ]
)]
fn test_increment_decrement_single_register_value( fn test_increment_decrement_single_register_value(
opcode: u8, (opcode, register): (u8, register::SingleEightBit),
register: register::SingleEightBit, (initial_value, expected_value): (u8, u8),
initial_value: u8,
expected_value: u8,
) { ) {
let mut processor = Processor::default(); let mut processor = Processor::default();
processor processor
@ -2188,61 +2113,42 @@ fn test_increment_decrement_single_register_value(
); );
} }
#[test_case(0x04, register::SingleEightBit::B, 0x05, IncrementOperationFlags { zero: 0, half_carry: 0, subtract: 0}; "increment, register B")] #[test_matrix(
#[test_case(0x04, register::SingleEightBit::B, 0xFF, IncrementOperationFlags { zero: 1, half_carry: 1, subtract: 0}; "increment with wrapping, register B")] [
#[test_case(0x04, register::SingleEightBit::B, 0x0F, IncrementOperationFlags { zero: 0, half_carry: 1, subtract: 0 }; "increment with half carry, register B")] (0x04, register::SingleEightBit::B),
#[test_case(0x0C, register::SingleEightBit::C, 0x05, IncrementOperationFlags { zero: 0, half_carry: 0, subtract: 0 }; "increment, register C")] (0x0C, register::SingleEightBit::C),
#[test_case(0x0C, register::SingleEightBit::C, 0xFF, IncrementOperationFlags { zero: 1, half_carry: 1, subtract: 0 }; "increment with wrapping, register C")] (0x14, register::SingleEightBit::D),
#[test_case(0x0C, register::SingleEightBit::C, 0x0F, IncrementOperationFlags { zero: 0, half_carry: 1, subtract: 0 }; "increment with half carry, register C")] (0x1C, register::SingleEightBit::E),
#[test_case(0x14, register::SingleEightBit::D, 0x05, IncrementOperationFlags { zero: 0, half_carry: 0, subtract: 0 }; "increment, register D")] (0x24, register::SingleEightBit::H),
#[test_case(0x14, register::SingleEightBit::D, 0xFF, IncrementOperationFlags { zero: 1, half_carry: 1, subtract: 0 }; "increment with wrapping, register D")] (0x2C, register::SingleEightBit::L),
#[test_case(0x14, register::SingleEightBit::D, 0x0F, IncrementOperationFlags { zero: 0, half_carry: 1, subtract: 0 }; "increment with half carry, register D")] (0x3C, register::SingleEightBit::A),
#[test_case(0x1C, register::SingleEightBit::E, 0x05, IncrementOperationFlags { zero: 0, half_carry: 0, subtract: 0 }; "increment, register E")] ],
#[test_case(0x1C, register::SingleEightBit::E, 0xFF, IncrementOperationFlags { zero: 1, half_carry: 1, subtract: 0 }; "increment with wrapping, register E")] [
#[test_case(0x1C, register::SingleEightBit::E, 0x0F, IncrementOperationFlags { zero: 0, half_carry: 1, subtract: 0 }; "increment with half carry, register E")] (0x05, IncrementOperationFlags { zero: 0, half_carry: 0, subtract: 0}),
#[test_case(0x24, register::SingleEightBit::H, 0x05, IncrementOperationFlags { zero: 0, half_carry: 0, subtract: 0 }; "increment, register H")] (0xFF, IncrementOperationFlags { zero: 1, half_carry: 1, subtract: 0}),
#[test_case(0x24, register::SingleEightBit::H, 0xFF, IncrementOperationFlags { zero: 1, half_carry: 1, subtract: 0 }; "increment with wrapping, register H")] (0x0F, IncrementOperationFlags { zero: 0, half_carry: 1, subtract: 0}),
#[test_case(0x24, register::SingleEightBit::H, 0x0F, IncrementOperationFlags { zero: 0, half_carry: 1, subtract: 0 }; "increment with half carry, register H")] ]
#[test_case(0x2C, register::SingleEightBit::L, 0x05, IncrementOperationFlags { zero: 0, half_carry: 0, subtract: 0 }; "increment, register L")] )]
#[test_case(0x2C, register::SingleEightBit::L, 0xFF, IncrementOperationFlags { zero: 1, half_carry: 1, subtract: 0 }; "increment with wrapping, register L")] #[test_matrix(
#[test_case(0x2C, register::SingleEightBit::L, 0x0F, IncrementOperationFlags { zero: 0, half_carry: 1, subtract: 0 }; "increment with half carry, register L")] [
#[test_case(0x3C, register::SingleEightBit::A, 0x05, IncrementOperationFlags { zero: 0, half_carry: 0, subtract: 0 }; "increment, register A")] (0x05, register::SingleEightBit::B),
#[test_case(0x3C, register::SingleEightBit::A, 0xFF, IncrementOperationFlags { zero: 1, half_carry: 1, subtract: 0 }; "increment with wrapping, register A")] (0x0D, register::SingleEightBit::C),
#[test_case(0x3C, register::SingleEightBit::A, 0x0F, IncrementOperationFlags { zero: 0, half_carry: 1, subtract: 0 }; "increment with half carry, register A")] (0x15, register::SingleEightBit::D),
// decrement (0x1D, register::SingleEightBit::E),
#[test_case(0x05, register::SingleEightBit::B, 0x05, IncrementOperationFlags { zero: 0, half_carry: 0, subtract: 1}; "decrement, register B")] (0x25, register::SingleEightBit::H),
#[test_case(0x05, register::SingleEightBit::B, 0x00, IncrementOperationFlags { zero: 0, half_carry: 1, subtract: 1}; "decrement with wrapping, register B")] (0x2D, register::SingleEightBit::L),
#[test_case(0x05, register::SingleEightBit::B, 0x01, IncrementOperationFlags { zero: 1, half_carry: 0, subtract: 1}; "decrement to zero, register B")] (0x3D, register::SingleEightBit::A),
#[test_case(0x05, register::SingleEightBit::B, 0x10, IncrementOperationFlags { zero: 0, half_carry: 1, subtract: 1}; "decrement with half carry, register B")] ],
#[test_case(0x0D, register::SingleEightBit::C, 0x05, IncrementOperationFlags { zero: 0, half_carry: 0, subtract: 1}; "decrement, register C")] [
#[test_case(0x0D, register::SingleEightBit::C, 0x00, IncrementOperationFlags { zero: 0, half_carry: 1, subtract: 1}; "decrement with wrapping, register C")] (0x05, IncrementOperationFlags { zero: 0, half_carry: 0, subtract: 1}),
#[test_case(0x0D, register::SingleEightBit::C, 0x01, IncrementOperationFlags { zero: 1, half_carry: 0, subtract: 1}; "decrement to zero, register C")] (0x01, IncrementOperationFlags { zero: 1, half_carry: 0, subtract: 1}),
#[test_case(0x0D, register::SingleEightBit::C, 0x10, IncrementOperationFlags { zero: 0, half_carry: 1, subtract: 1}; "decrement with half carry, register C")] (0x10, IncrementOperationFlags { zero: 0, half_carry: 1, subtract: 1}),
#[test_case(0x15, register::SingleEightBit::D, 0x05, IncrementOperationFlags { zero: 0, half_carry: 0, subtract: 1}; "decrement, register D")] (0x00, IncrementOperationFlags { zero: 0, half_carry: 1, subtract: 1}),
#[test_case(0x15, register::SingleEightBit::D, 0x00, IncrementOperationFlags { zero: 0, half_carry: 1, subtract: 1}; "decrement with wrapping, register D")] ]
#[test_case(0x15, register::SingleEightBit::D, 0x01, IncrementOperationFlags { zero: 1, half_carry: 0, subtract: 1}; "decrement to zero, register D")] )]
#[test_case(0x15, register::SingleEightBit::D, 0x10, IncrementOperationFlags { zero: 0, half_carry: 1, subtract: 1}; "decrement with half carry, register D")]
#[test_case(0x1D, register::SingleEightBit::E, 0x05, IncrementOperationFlags { zero: 0, half_carry: 0, subtract: 1}; "decrement, register E")]
#[test_case(0x1D, register::SingleEightBit::E, 0x00, IncrementOperationFlags { zero: 0, half_carry: 1, subtract: 1}; "decrement with wrapping, register E")]
#[test_case(0x1D, register::SingleEightBit::E, 0x01, IncrementOperationFlags { zero: 1, half_carry: 0, subtract: 1}; "decrement to zero, register E")]
#[test_case(0x1D, register::SingleEightBit::E, 0x10, IncrementOperationFlags { zero: 0, half_carry: 1, subtract: 1}; "decrement with half carry, register E")]
#[test_case(0x25, register::SingleEightBit::H, 0x05, IncrementOperationFlags { zero: 0, half_carry: 0, subtract: 1}; "decrement, register H")]
#[test_case(0x25, register::SingleEightBit::H, 0x00, IncrementOperationFlags { zero: 0, half_carry: 1, subtract: 1}; "decrement with wrapping, register H")]
#[test_case(0x25, register::SingleEightBit::H, 0x01, IncrementOperationFlags { zero: 1, half_carry: 0, subtract: 1}; "decrement to zero, register H")]
#[test_case(0x25, register::SingleEightBit::H, 0x10, IncrementOperationFlags { zero: 0, half_carry: 1, subtract: 1}; "decrement with half carry, register H")]
#[test_case(0x2D, register::SingleEightBit::L, 0x05, IncrementOperationFlags { zero: 0, half_carry: 0, subtract: 1}; "decrement, register L")]
#[test_case(0x2D, register::SingleEightBit::L, 0x00, IncrementOperationFlags { zero: 0, half_carry: 1, subtract: 1}; "decrement with wrapping, register L")]
#[test_case(0x2D, register::SingleEightBit::L, 0x01, IncrementOperationFlags { zero: 1, half_carry: 0, subtract: 1}; "decrement to zero, register L")]
#[test_case(0x2D, register::SingleEightBit::L, 0x10, IncrementOperationFlags { zero: 0, half_carry: 1, subtract: 1}; "decrement with half carry, register L")]
#[test_case(0x3D, register::SingleEightBit::A, 0x05, IncrementOperationFlags { zero: 0, half_carry: 0, subtract: 1}; "decrement, register A")]
#[test_case(0x3D, register::SingleEightBit::A, 0x00, IncrementOperationFlags { zero: 0, half_carry: 1, subtract: 1}; "decrement with wrapping, register A")]
#[test_case(0x3D, register::SingleEightBit::A, 0x01, IncrementOperationFlags { zero: 1, half_carry: 0, subtract: 1}; "decrement to zero, register A")]
#[test_case(0x3D, register::SingleEightBit::A, 0x10, IncrementOperationFlags { zero: 0, half_carry: 1, subtract: 1}; "decrement with half carry, register A")]
fn test_increment_decrement_single_register_flags( fn test_increment_decrement_single_register_flags(
opcode: u8, (opcode, register): (u8, register::SingleEightBit),
register: register::SingleEightBit, (initial_value, expected_flags): (u8, IncrementOperationFlags),
initial_value: u8,
expected_flags: IncrementOperationFlags,
) { ) {
let mut processor = Processor::default(); let mut processor = Processor::default();
processor processor
@ -2313,7 +2219,11 @@ fn test_increment_decrement_hl_value(opcode: u8, initial_value: u8, expected_val
#[test_case(0x35, 0x01, IncrementOperationFlags { zero: 1, half_carry: 0, subtract: 1}; "decrement to zero")] #[test_case(0x35, 0x01, IncrementOperationFlags { zero: 1, half_carry: 0, subtract: 1}; "decrement to zero")]
#[test_case(0x35, 0x00, IncrementOperationFlags { zero: 0, half_carry: 1, subtract: 1}; "decrement with wrapping")] #[test_case(0x35, 0x00, IncrementOperationFlags { zero: 0, half_carry: 1, subtract: 1}; "decrement with wrapping")]
#[test_case(0x35, 0x10, IncrementOperationFlags { zero: 0, half_carry: 1, subtract: 1}; "decrement with half carry")] #[test_case(0x35, 0x10, IncrementOperationFlags { zero: 0, half_carry: 1, subtract: 1}; "decrement with half carry")]
fn test_increment_decrement_hl_flags(opcode: u8, initial_value: u8, expected_flags: IncrementOperationFlags) { fn test_increment_decrement_hl_flags(
opcode: u8,
initial_value: u8,
expected_flags: IncrementOperationFlags,
) {
let mut processor = Processor::default(); let mut processor = Processor::default();
processor processor
.registers .registers