diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..2c379c8 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,368 @@ +root = true + +# All files +[*] +indent_style = space + +# Xml files +[*.xml] +indent_size = 2 + +# C# files +[*.cs] + +#### Core EditorConfig Options #### + +# Indentation and spacing +indent_size = 4 +tab_width = 4 + +# New line preferences +end_of_line = crlf +insert_final_newline = false + +#### .NET Coding Conventions #### +[*.{cs,vb}] + +# Organize usings +dotnet_separate_import_directive_groups = false +dotnet_sort_system_directives_first = true +file_header_template = unset +dotnet_diagnostic.IDE0005.severity = warning + +# this. and Me. preferences +dotnet_style_qualification_for_event = false:silent +dotnet_style_qualification_for_field = false:silent +dotnet_style_qualification_for_method = false:silent +dotnet_style_qualification_for_property = false:silent + +# Language keywords vs BCL types preferences +dotnet_style_predefined_type_for_locals_parameters_members = true:silent +dotnet_style_predefined_type_for_member_access = true:silent + +# Parentheses preferences +dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent +dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent +dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent +dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent + +# Modifier preferences +dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent + +# Expression-level preferences +dotnet_style_coalesce_expression = true:suggestion +dotnet_style_collection_initializer = true:suggestion +dotnet_style_explicit_tuple_names = true:suggestion +dotnet_style_null_propagation = true:suggestion +dotnet_style_object_initializer = true:suggestion +dotnet_style_operator_placement_when_wrapping = beginning_of_line +dotnet_style_prefer_auto_properties = true:suggestion +dotnet_style_prefer_compound_assignment = true:suggestion +dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion +dotnet_style_prefer_conditional_expression_over_return = true:suggestion +dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion +dotnet_style_prefer_inferred_tuple_names = true:suggestion +dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion +dotnet_style_prefer_simplified_boolean_expressions = true:suggestion +dotnet_style_prefer_simplified_interpolation = true:suggestion + +# Field preferences +dotnet_style_readonly_field = true:warning + +# Parameter preferences +dotnet_code_quality_unused_parameters = all:suggestion + +# Suppression preferences +dotnet_remove_unnecessary_suppression_exclusions = none + +#### C# Coding Conventions #### +[*.cs] + +# var preferences +csharp_style_var_elsewhere = false:silent +csharp_style_var_for_built_in_types = false:silent +csharp_style_var_when_type_is_apparent = false:silent + +# Expression-bodied members +csharp_style_expression_bodied_accessors = true:silent +csharp_style_expression_bodied_constructors = false:silent +csharp_style_expression_bodied_indexers = true:silent +csharp_style_expression_bodied_lambdas = true:suggestion +csharp_style_expression_bodied_local_functions = false:silent +csharp_style_expression_bodied_methods = false:silent +csharp_style_expression_bodied_operators = false:silent +csharp_style_expression_bodied_properties = true:silent + +# Pattern matching preferences +csharp_style_pattern_matching_over_as_with_null_check = true:suggestion +csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion +csharp_style_prefer_not_pattern = true:suggestion +csharp_style_prefer_pattern_matching = true:silent +csharp_style_prefer_switch_expression = true:suggestion + +# Null-checking preferences +csharp_style_conditional_delegate_call = true:suggestion + +# Modifier preferences +csharp_prefer_static_local_function = true:warning +csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:silent + +# Code-block preferences +csharp_prefer_braces = true:silent +csharp_prefer_simple_using_statement = true:suggestion + +# Expression-level preferences +csharp_prefer_simple_default_expression = true:suggestion +csharp_style_deconstructed_variable_declaration = true:suggestion +csharp_style_inlined_variable_declaration = true:suggestion +csharp_style_pattern_local_over_anonymous_function = true:suggestion +csharp_style_prefer_index_operator = true:suggestion +csharp_style_prefer_range_operator = true:suggestion +csharp_style_throw_expression = true:suggestion +csharp_style_unused_value_assignment_preference = discard_variable:suggestion +csharp_style_unused_value_expression_statement_preference = discard_variable:silent + +# 'using' directive preferences +csharp_using_directive_placement = outside_namespace:silent + +# namespace preferences +csharp_style_namespace_declarations = file_scoped:warning + +#### C# Formatting Rules #### + +# New line preferences +csharp_new_line_before_catch = true +csharp_new_line_before_else = true +csharp_new_line_before_finally = true +csharp_new_line_before_members_in_anonymous_types = true +csharp_new_line_before_members_in_object_initializers = true +csharp_new_line_before_open_brace = all +csharp_new_line_between_query_expression_clauses = true + +# Indentation preferences +csharp_indent_block_contents = true +csharp_indent_braces = false +csharp_indent_case_contents = true +csharp_indent_case_contents_when_block = true +csharp_indent_labels = one_less_than_current +csharp_indent_switch_labels = true + +# Space preferences +csharp_space_after_cast = false +csharp_space_after_colon_in_inheritance_clause = true +csharp_space_after_comma = true +csharp_space_after_dot = false +csharp_space_after_keywords_in_control_flow_statements = true +csharp_space_after_semicolon_in_for_statement = true +csharp_space_around_binary_operators = before_and_after +csharp_space_around_declaration_statements = false +csharp_space_before_colon_in_inheritance_clause = true +csharp_space_before_comma = false +csharp_space_before_dot = false +csharp_space_before_open_square_brackets = false +csharp_space_before_semicolon_in_for_statement = false +csharp_space_between_empty_square_brackets = false +csharp_space_between_method_call_empty_parameter_list_parentheses = false +csharp_space_between_method_call_name_and_opening_parenthesis = false +csharp_space_between_method_call_parameter_list_parentheses = false +csharp_space_between_method_declaration_empty_parameter_list_parentheses = false +csharp_space_between_method_declaration_name_and_open_parenthesis = false +csharp_space_between_method_declaration_parameter_list_parentheses = false +csharp_space_between_parentheses = false +csharp_space_between_square_brackets = false + +# Wrapping preferences +csharp_preserve_single_line_blocks = true +csharp_preserve_single_line_statements = true + +#### Naming styles #### +[*.{cs,vb}] + +# Naming rules + +dotnet_naming_rule.types_and_namespaces_should_be_pascalcase.severity = suggestion +dotnet_naming_rule.types_and_namespaces_should_be_pascalcase.symbols = types_and_namespaces +dotnet_naming_rule.types_and_namespaces_should_be_pascalcase.style = pascalcase + +dotnet_naming_rule.interfaces_should_be_ipascalcase.severity = suggestion +dotnet_naming_rule.interfaces_should_be_ipascalcase.symbols = interfaces +dotnet_naming_rule.interfaces_should_be_ipascalcase.style = ipascalcase + +dotnet_naming_rule.type_parameters_should_be_tpascalcase.severity = suggestion +dotnet_naming_rule.type_parameters_should_be_tpascalcase.symbols = type_parameters +dotnet_naming_rule.type_parameters_should_be_tpascalcase.style = tpascalcase + +dotnet_naming_rule.methods_should_be_pascalcase.severity = suggestion +dotnet_naming_rule.methods_should_be_pascalcase.symbols = methods +dotnet_naming_rule.methods_should_be_pascalcase.style = pascalcase + +dotnet_naming_rule.properties_should_be_pascalcase.severity = suggestion +dotnet_naming_rule.properties_should_be_pascalcase.symbols = properties +dotnet_naming_rule.properties_should_be_pascalcase.style = pascalcase + +dotnet_naming_rule.events_should_be_pascalcase.severity = suggestion +dotnet_naming_rule.events_should_be_pascalcase.symbols = events +dotnet_naming_rule.events_should_be_pascalcase.style = pascalcase + +dotnet_naming_rule.local_variables_should_be_camelcase.severity = suggestion +dotnet_naming_rule.local_variables_should_be_camelcase.symbols = local_variables +dotnet_naming_rule.local_variables_should_be_camelcase.style = camelcase + +dotnet_naming_rule.local_constants_should_be_camelcase.severity = suggestion +dotnet_naming_rule.local_constants_should_be_camelcase.symbols = local_constants +dotnet_naming_rule.local_constants_should_be_camelcase.style = camelcase + +dotnet_naming_rule.parameters_should_be_camelcase.severity = suggestion +dotnet_naming_rule.parameters_should_be_camelcase.symbols = parameters +dotnet_naming_rule.parameters_should_be_camelcase.style = camelcase + +dotnet_naming_rule.public_fields_should_be_pascalcase.severity = suggestion +dotnet_naming_rule.public_fields_should_be_pascalcase.symbols = public_fields +dotnet_naming_rule.public_fields_should_be_pascalcase.style = pascalcase + +dotnet_naming_rule.private_fields_should_be__camelcase.severity = suggestion +dotnet_naming_rule.private_fields_should_be__camelcase.symbols = private_fields +dotnet_naming_rule.private_fields_should_be__camelcase.style = _camelcase + +dotnet_naming_rule.private_static_fields_should_be_s_camelcase.severity = suggestion +dotnet_naming_rule.private_static_fields_should_be_s_camelcase.symbols = private_static_fields +dotnet_naming_rule.private_static_fields_should_be_s_camelcase.style = s_camelcase + +dotnet_naming_rule.public_constant_fields_should_be_pascalcase.severity = suggestion +dotnet_naming_rule.public_constant_fields_should_be_pascalcase.symbols = public_constant_fields +dotnet_naming_rule.public_constant_fields_should_be_pascalcase.style = pascalcase + +dotnet_naming_rule.private_constant_fields_should_be_pascalcase.severity = suggestion +dotnet_naming_rule.private_constant_fields_should_be_pascalcase.symbols = private_constant_fields +dotnet_naming_rule.private_constant_fields_should_be_pascalcase.style = pascalcase + +dotnet_naming_rule.public_static_readonly_fields_should_be_pascalcase.severity = suggestion +dotnet_naming_rule.public_static_readonly_fields_should_be_pascalcase.symbols = public_static_readonly_fields +dotnet_naming_rule.public_static_readonly_fields_should_be_pascalcase.style = pascalcase + +dotnet_naming_rule.private_static_readonly_fields_should_be_pascalcase.severity = suggestion +dotnet_naming_rule.private_static_readonly_fields_should_be_pascalcase.symbols = private_static_readonly_fields +dotnet_naming_rule.private_static_readonly_fields_should_be_pascalcase.style = pascalcase + +dotnet_naming_rule.enums_should_be_pascalcase.severity = suggestion +dotnet_naming_rule.enums_should_be_pascalcase.symbols = enums +dotnet_naming_rule.enums_should_be_pascalcase.style = pascalcase + +dotnet_naming_rule.local_functions_should_be_pascalcase.severity = suggestion +dotnet_naming_rule.local_functions_should_be_pascalcase.symbols = local_functions +dotnet_naming_rule.local_functions_should_be_pascalcase.style = pascalcase + +dotnet_naming_rule.non_field_members_should_be_pascalcase.severity = suggestion +dotnet_naming_rule.non_field_members_should_be_pascalcase.symbols = non_field_members +dotnet_naming_rule.non_field_members_should_be_pascalcase.style = pascalcase + +# Symbol specifications + +dotnet_naming_symbols.interfaces.applicable_kinds = interface +dotnet_naming_symbols.interfaces.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.interfaces.required_modifiers = + +dotnet_naming_symbols.enums.applicable_kinds = enum +dotnet_naming_symbols.enums.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.enums.required_modifiers = + +dotnet_naming_symbols.events.applicable_kinds = event +dotnet_naming_symbols.events.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.events.required_modifiers = + +dotnet_naming_symbols.methods.applicable_kinds = method +dotnet_naming_symbols.methods.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.methods.required_modifiers = + +dotnet_naming_symbols.properties.applicable_kinds = property +dotnet_naming_symbols.properties.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.properties.required_modifiers = + +dotnet_naming_symbols.public_fields.applicable_kinds = field +dotnet_naming_symbols.public_fields.applicable_accessibilities = public, internal +dotnet_naming_symbols.public_fields.required_modifiers = + +dotnet_naming_symbols.private_fields.applicable_kinds = field +dotnet_naming_symbols.private_fields.applicable_accessibilities = private, protected, protected_internal, private_protected +dotnet_naming_symbols.private_fields.required_modifiers = + +dotnet_naming_symbols.private_static_fields.applicable_kinds = field +dotnet_naming_symbols.private_static_fields.applicable_accessibilities = private, protected, protected_internal, private_protected +dotnet_naming_symbols.private_static_fields.required_modifiers = static + +dotnet_naming_symbols.types_and_namespaces.applicable_kinds = namespace, class, struct, interface, enum +dotnet_naming_symbols.types_and_namespaces.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.types_and_namespaces.required_modifiers = + +dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method +dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.non_field_members.required_modifiers = + +dotnet_naming_symbols.type_parameters.applicable_kinds = namespace +dotnet_naming_symbols.type_parameters.applicable_accessibilities = * +dotnet_naming_symbols.type_parameters.required_modifiers = + +dotnet_naming_symbols.private_constant_fields.applicable_kinds = field +dotnet_naming_symbols.private_constant_fields.applicable_accessibilities = private, protected, protected_internal, private_protected +dotnet_naming_symbols.private_constant_fields.required_modifiers = const + +dotnet_naming_symbols.local_variables.applicable_kinds = local +dotnet_naming_symbols.local_variables.applicable_accessibilities = local +dotnet_naming_symbols.local_variables.required_modifiers = + +dotnet_naming_symbols.local_constants.applicable_kinds = local +dotnet_naming_symbols.local_constants.applicable_accessibilities = local +dotnet_naming_symbols.local_constants.required_modifiers = const + +dotnet_naming_symbols.parameters.applicable_kinds = parameter +dotnet_naming_symbols.parameters.applicable_accessibilities = * +dotnet_naming_symbols.parameters.required_modifiers = + +dotnet_naming_symbols.public_constant_fields.applicable_kinds = field +dotnet_naming_symbols.public_constant_fields.applicable_accessibilities = public, internal +dotnet_naming_symbols.public_constant_fields.required_modifiers = const + +dotnet_naming_symbols.public_static_readonly_fields.applicable_kinds = field +dotnet_naming_symbols.public_static_readonly_fields.applicable_accessibilities = public, internal +dotnet_naming_symbols.public_static_readonly_fields.required_modifiers = readonly, static + +dotnet_naming_symbols.private_static_readonly_fields.applicable_kinds = field +dotnet_naming_symbols.private_static_readonly_fields.applicable_accessibilities = private, protected, protected_internal, private_protected +dotnet_naming_symbols.private_static_readonly_fields.required_modifiers = readonly, static + +dotnet_naming_symbols.local_functions.applicable_kinds = local_function +dotnet_naming_symbols.local_functions.applicable_accessibilities = * +dotnet_naming_symbols.local_functions.required_modifiers = + +# Naming styles + +dotnet_naming_style.pascalcase.required_prefix = +dotnet_naming_style.pascalcase.required_suffix = +dotnet_naming_style.pascalcase.word_separator = +dotnet_naming_style.pascalcase.capitalization = pascal_case + +dotnet_naming_style.ipascalcase.required_prefix = I +dotnet_naming_style.ipascalcase.required_suffix = +dotnet_naming_style.ipascalcase.word_separator = +dotnet_naming_style.ipascalcase.capitalization = pascal_case + +dotnet_naming_style.tpascalcase.required_prefix = T +dotnet_naming_style.tpascalcase.required_suffix = +dotnet_naming_style.tpascalcase.word_separator = +dotnet_naming_style.tpascalcase.capitalization = pascal_case + +dotnet_naming_style._camelcase.required_prefix = _ +dotnet_naming_style._camelcase.required_suffix = +dotnet_naming_style._camelcase.word_separator = +dotnet_naming_style._camelcase.capitalization = camel_case + +dotnet_naming_style.camelcase.required_prefix = +dotnet_naming_style.camelcase.required_suffix = +dotnet_naming_style.camelcase.word_separator = +dotnet_naming_style.camelcase.capitalization = camel_case + +dotnet_naming_style.s_camelcase.required_prefix = s_ +dotnet_naming_style.s_camelcase.required_suffix = +dotnet_naming_style.s_camelcase.word_separator = +dotnet_naming_style.s_camelcase.capitalization = camel_case + diff --git a/.github/workflows/dotnet-workflow.yml b/.github/workflows/dotnet-workflow.yml index 907be15..189136b 100644 --- a/.github/workflows/dotnet-workflow.yml +++ b/.github/workflows/dotnet-workflow.yml @@ -9,17 +9,24 @@ on: jobs: build: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Install .NET 6 SDK + + - name: Install .NET 8 SDK uses: actions/setup-dotnet@v3 with: - dotnet-version: 6.0.x + dotnet-version: 8.0.x + - name: Restore projects run: dotnet restore + + - name: Check formatting + run: dotnet format --verify-no-changes + - name: Build projects run: dotnet build --no-restore + - name: Run tests - run: dotnet test --no-build --verbosity normal \ No newline at end of file + run: dotnet test --no-build --verbosity normal diff --git a/Intel8080.Emulator.Tests/FlagTests.cs b/Intel8080.Emulator.Tests/FlagTests.cs index d589bb0..04f3d32 100644 --- a/Intel8080.Emulator.Tests/FlagTests.cs +++ b/Intel8080.Emulator.Tests/FlagTests.cs @@ -1,174 +1,172 @@ -using Intel8080.Emulator; -using Xunit; - -namespace Intel8080.Emulator.Tests -{ - public class FlagTests - { - private Flags _flags; - - public FlagTests() - { - _flags = new Flags(); - - _flags.Clear(); - } - - [Fact] - public void SignBitIsSet_SetSignFlagTrue() - { - // Act - _flags.CalcSignFlag(0x8C); - - // Assert - Assert.True(_flags.Sign); - Assert.Equal(0x82, _flags.F); - } - - [Fact] - public void SignBitIsUnset_SetSignFlagFalse() - { - // Act - _flags.CalcSignFlag(0x7F); - - // Assert - Assert.False(_flags.Sign); - Assert.Equal(0x02, _flags.F); - } - - [Fact] - public void Data_Zero_SetZeroFlagTrue() - { - // Act - _flags.CalcZeroFlag(0x00); - - // Assert - Assert.True(_flags.Zero); - Assert.Equal(0x42, _flags.F); - } - - [Fact] - public void Data_NonZero_SetZeroFlagFalse() - { - // Act - _flags.CalcZeroFlag(0x01); - - // Assert - Assert.False(_flags.Zero); - Assert.Equal(0x02, _flags.F); - } - - [Fact] - public void AuxiliaryCarry_ValueGreaterThan0x0F_SetAuxCarryFlagTrue() - { - // Act - _flags.CalcAuxCarryFlag(0x0F, 1); - - // Assert - Assert.True(_flags.AuxiliaryCarry); - Assert.Equal(0x12, _flags.F); - } - - [Fact] - public void AuxiliaryCarry_ValueLessThan0x0F_SetAuxCarryFlagFalse() - { - // Act - _flags.CalcAuxCarryFlag(0x00, 1); - - // Assert - Assert.False(_flags.AuxiliaryCarry); - Assert.Equal(0x02, _flags.F); - } - - [Fact] - public void Parity_Even_SetParityFlagTrue() - { - // Act - _flags.CalcParityFlag(0x3F); - - // Assert - Assert.True(_flags.Parity); - Assert.Equal(0x06, _flags.F); - } - - [Fact] - public void Parity_Zero_SetParityFlagTrue() - { - // Act - _flags.CalcParityFlag(0x3F); - - // Assert - Assert.True(_flags.Parity); - Assert.Equal(0x06, _flags.F); - } - - [Fact] - public void Parity_Odd_SetParityFlagFalse() - { - // Act - _flags.CalcSignFlag(0x7F); - - // Assert - Assert.False(_flags.Parity); - Assert.Equal(0x02, _flags.F); - } - - [Fact] - public void Carry_ValueGreaterThan0xFF_SetCarryFlagTrue() - { - // Act - _flags.CalcCarryFlag(0x0100); - - // Assert - Assert.True(_flags.Carry); - Assert.Equal(0x03, _flags.F); - } - - [Fact] - public void Carry_ValueEqual0xFF_SetCarryFlagFalse() - { - // Act - _flags.CalcCarryFlag(0xFF); - - // Assert - Assert.False(_flags.Carry); - Assert.Equal(0x02, _flags.F); - } - - [Fact] - public void Carry_ValueGreaterThan0xFFFF_SetCarryFlagTrue() - { - // Act - _flags.CalcCarryFlagRegisterPair(0x010000); - - // Assert - Assert.True(_flags.Carry); - Assert.Equal(0x03, _flags.F); - } - - [Fact] - public void Carry_ValueLessThan0xFFFF_SetCarryFlagFalse() - { - // Act - _flags.CalcCarryFlagRegisterPair(0xFFFF); - - // Assert - Assert.False(_flags.Carry); - Assert.Equal(0x02, _flags.F); - } - - [Fact] - public void Flags_Clear_SetFlagRegisterDefault() - { - // Arrange - _flags.CalcSignFlag(0xC0); - _flags.CalcParityFlag(0x80); - - // Act - _flags.Clear(); - - // Assert - Assert.Equal(0x02, _flags.F); - } - } +using Xunit; + +namespace Intel8080.Emulator.Tests; + +public class FlagTests +{ + private readonly Flags _flags; + + public FlagTests() + { + _flags = new Flags(); + + _flags.Clear(); + } + + [Fact] + public void SignBitIsSet_SetSignFlagTrue() + { + // Act + _flags.CalcSignFlag(0x8C); + + // Assert + Assert.True(_flags.Sign); + Assert.Equal(0x82, _flags.F); + } + + [Fact] + public void SignBitIsUnset_SetSignFlagFalse() + { + // Act + _flags.CalcSignFlag(0x7F); + + // Assert + Assert.False(_flags.Sign); + Assert.Equal(0x02, _flags.F); + } + + [Fact] + public void Data_Zero_SetZeroFlagTrue() + { + // Act + _flags.CalcZeroFlag(0x00); + + // Assert + Assert.True(_flags.Zero); + Assert.Equal(0x42, _flags.F); + } + + [Fact] + public void Data_NonZero_SetZeroFlagFalse() + { + // Act + _flags.CalcZeroFlag(0x01); + + // Assert + Assert.False(_flags.Zero); + Assert.Equal(0x02, _flags.F); + } + + [Fact] + public void AuxiliaryCarry_ValueGreaterThan0x0F_SetAuxCarryFlagTrue() + { + // Act + _flags.CalcAuxCarryFlag(0x0F, 1); + + // Assert + Assert.True(_flags.AuxiliaryCarry); + Assert.Equal(0x12, _flags.F); + } + + [Fact] + public void AuxiliaryCarry_ValueLessThan0x0F_SetAuxCarryFlagFalse() + { + // Act + _flags.CalcAuxCarryFlag(0x00, 1); + + // Assert + Assert.False(_flags.AuxiliaryCarry); + Assert.Equal(0x02, _flags.F); + } + + [Fact] + public void Parity_Even_SetParityFlagTrue() + { + // Act + _flags.CalcParityFlag(0x3F); + + // Assert + Assert.True(_flags.Parity); + Assert.Equal(0x06, _flags.F); + } + + [Fact] + public void Parity_Zero_SetParityFlagTrue() + { + // Act + _flags.CalcParityFlag(0x3F); + + // Assert + Assert.True(_flags.Parity); + Assert.Equal(0x06, _flags.F); + } + + [Fact] + public void Parity_Odd_SetParityFlagFalse() + { + // Act + _flags.CalcSignFlag(0x7F); + + // Assert + Assert.False(_flags.Parity); + Assert.Equal(0x02, _flags.F); + } + + [Fact] + public void Carry_ValueGreaterThan0xFF_SetCarryFlagTrue() + { + // Act + _flags.CalcCarryFlag(0x0100); + + // Assert + Assert.True(_flags.Carry); + Assert.Equal(0x03, _flags.F); + } + + [Fact] + public void Carry_ValueEqual0xFF_SetCarryFlagFalse() + { + // Act + _flags.CalcCarryFlag(0xFF); + + // Assert + Assert.False(_flags.Carry); + Assert.Equal(0x02, _flags.F); + } + + [Fact] + public void Carry_ValueGreaterThan0xFFFF_SetCarryFlagTrue() + { + // Act + _flags.CalcCarryFlagRegisterPair(0x010000); + + // Assert + Assert.True(_flags.Carry); + Assert.Equal(0x03, _flags.F); + } + + [Fact] + public void Carry_ValueLessThan0xFFFF_SetCarryFlagFalse() + { + // Act + _flags.CalcCarryFlagRegisterPair(0xFFFF); + + // Assert + Assert.False(_flags.Carry); + Assert.Equal(0x02, _flags.F); + } + + [Fact] + public void Flags_Clear_SetFlagRegisterDefault() + { + // Arrange + _flags.CalcSignFlag(0xC0); + _flags.CalcParityFlag(0x80); + + // Act + _flags.Clear(); + + // Assert + Assert.Equal(0x02, _flags.F); + } } \ No newline at end of file diff --git a/Intel8080.Emulator.Tests/Instructions/AccumulatorInstructionTests.cs b/Intel8080.Emulator.Tests/Instructions/AccumulatorInstructionTests.cs index 8ca4dc1..258d660 100644 --- a/Intel8080.Emulator.Tests/Instructions/AccumulatorInstructionTests.cs +++ b/Intel8080.Emulator.Tests/Instructions/AccumulatorInstructionTests.cs @@ -1,2354 +1,2352 @@ -using Intel8080.Emulator.Instructions; -using Moq; -using System; -using Xunit; - -namespace Intel8080.Emulator.Tests.Instructions -{ - public class AccumulatorInstructionTests - { - private readonly CPU _cpu; - private readonly Mock _memory; - - public AccumulatorInstructionTests() - { - _memory = new Mock(); - - _cpu = new CPU(_memory.Object); - } - - [Fact] - public void ADD_B_ShouldAddRegBToAccumulator() - { - // Arrange - _cpu.Registers.A = 0x6C; - _cpu.Registers.B = 0x2E; - - // Act - DefaultInstructionSet.ADD_B(_cpu); - - // Assert - Assert.Equal(0x9A, _cpu.Registers.A); - Assert.Equal(0x2E00, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void ADD_C_ShouldAddRegCToAccumulator() - { - // Arrange - _cpu.Registers.A = 0x6C; - _cpu.Registers.C = 0x2E; - - // Act - DefaultInstructionSet.ADD_C(_cpu); - - // Assert - Assert.Equal(0x9A, _cpu.Registers.A); - Assert.Equal(0x002E, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void ADD_D_ShouldAddRegDToAccumulator() - { - // Arrange - _cpu.Registers.A = 0x6C; - _cpu.Registers.D = 0x2E; - - // Act - DefaultInstructionSet.ADD_D(_cpu); - - // Assert - Assert.Equal(0x9A, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x2E00, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void ADD_E_ShouldAddRegEToAccumulator() - { - // Arrange - _cpu.Registers.A = 0x6C; - _cpu.Registers.E = 0x2E; - - // Act - DefaultInstructionSet.ADD_E(_cpu); - - // Assert - Assert.Equal(0x9A, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x002E, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void ADD_H_ShouldAddRegHToAccumulator() - { - // Arrange - _cpu.Registers.A = 0x6C; - _cpu.Registers.H = 0x2E; - - // Act - DefaultInstructionSet.ADD_H(_cpu); - - // Assert - Assert.Equal(0x9A, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x2E00, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void ADD_L_ShouldAddRegLToAccumulator() - { - // Arrange - _cpu.Registers.A = 0x6C; - _cpu.Registers.L = 0x2E; - - // Act - DefaultInstructionSet.ADD_L(_cpu); - - // Assert - Assert.Equal(0x9A, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x002E, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void ADD_M_ShouldAddMemoryByteToAccumulator() - { - // Arrange - _cpu.Registers.A = 0x6C; - _cpu.Registers.HL = 0x0010; - - _memory.Setup(x => x[0x0010]).Returns(0x2E); - - // Act - DefaultInstructionSet.ADD_M(_cpu); - - // Assert - Assert.Equal(0x9A, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0010, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void ADD_A_ShouldDoubleAccumulator() - { - // Arrange - _cpu.Registers.A = 0x6C; - - // Act - DefaultInstructionSet.ADD_A(_cpu); - - // Assert - Assert.Equal(0xD8, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void ADC_B_ShouldAddRegBToAccumulator_NoCarry() - { - // Arrange - _cpu.Registers.A = 0x42; - _cpu.Registers.B = 0x3D; - - _cpu.Flags.Carry = false; - - // Act - DefaultInstructionSet.ADC_B(_cpu); - - // Assert - Assert.Equal(0x7F, _cpu.Registers.A); - Assert.Equal(0x3D00, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void ADC_B_ShouldAddRegBToAccumulator_Carry() - { - // Arrange - _cpu.Registers.A = 0x42; - _cpu.Registers.B = 0x3D; - - _cpu.Flags.Carry = true; - - // Act - DefaultInstructionSet.ADC_B(_cpu); - - // Assert - Assert.Equal(0x80, _cpu.Registers.A); - Assert.Equal(0x3D00, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void ADC_C_ShouldAddRegCToAccumulator_NoCarry() - { - // Arrange - _cpu.Registers.A = 0x42; - _cpu.Registers.C = 0x3D; - - _cpu.Flags.Carry = false; - - // Act - DefaultInstructionSet.ADC_C(_cpu); - - // Assert - Assert.Equal(0x7F, _cpu.Registers.A); - Assert.Equal(0x003D, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void ADC_C_ShouldAddRegCToAccumulator_Carry() - { - // Arrange - _cpu.Registers.A = 0x42; - _cpu.Registers.C = 0x3D; - - _cpu.Flags.Carry = true; - - // Act - DefaultInstructionSet.ADC_C(_cpu); - - // Assert - Assert.Equal(0x80, _cpu.Registers.A); - Assert.Equal(0x003D, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void ADC_D_ShouldAddRegDToAccumulator_NoCarry() - { - // Arrange - _cpu.Registers.A = 0x42; - _cpu.Registers.D = 0x3D; - - _cpu.Flags.Carry = false; - - // Act - DefaultInstructionSet.ADC_D(_cpu); - - // Assert - Assert.Equal(0x7F, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x3D00, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void ADC_D_ShouldAddRegDToAccumulator_Carry() - { - // Arrange - _cpu.Registers.A = 0x42; - _cpu.Registers.D = 0x3D; - - _cpu.Flags.Carry = true; - - // Act - DefaultInstructionSet.ADC_D(_cpu); - - // Assert - Assert.Equal(0x80, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x3D00, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void ADC_E_ShouldAddRegEToAccumulator_NoCarry() - { - // Arrange - _cpu.Registers.A = 0x42; - _cpu.Registers.E = 0x3D; - - _cpu.Flags.Carry = false; - - // Act - DefaultInstructionSet.ADC_E(_cpu); - - // Assert - Assert.Equal(0x7F, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x003D, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void ADC_E_ShouldAddRegEToAccumulator_Carry() - { - // Arrange - _cpu.Registers.A = 0x42; - _cpu.Registers.E = 0x3D; - - _cpu.Flags.Carry = true; - - // Act - DefaultInstructionSet.ADC_E(_cpu); - - // Assert - Assert.Equal(0x80, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x003D, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void ADC_H_ShouldAddRegHToAccumulator_NoCarry() - { - // Arrange - _cpu.Registers.A = 0x42; - _cpu.Registers.H = 0x3D; - - _cpu.Flags.Carry = false; - - // Act - DefaultInstructionSet.ADC_H(_cpu); - - // Assert - Assert.Equal(0x7F, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x3D00, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void ADC_H_ShouldAddRegHToAccumulator_Carry() - { - // Arrange - _cpu.Registers.A = 0x42; - _cpu.Registers.H = 0x3D; - - _cpu.Flags.Carry = true; - - // Act - DefaultInstructionSet.ADC_H(_cpu); - - // Assert - Assert.Equal(0x80, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x3D00, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void ADC_L_ShouldAddRegLToAccumulator_NoCarry() - { - // Arrange - _cpu.Registers.A = 0x42; - _cpu.Registers.L = 0x3D; - - _cpu.Flags.Carry = false; - - // Act - DefaultInstructionSet.ADC_L(_cpu); - - // Assert - Assert.Equal(0x7F, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x003D, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void ADC_L_ShouldAddRegLToAccumulator_Carry() - { - // Arrange - _cpu.Registers.A = 0x42; - _cpu.Registers.L = 0x3D; - - _cpu.Flags.Carry = true; - - // Act - DefaultInstructionSet.ADC_L(_cpu); - - // Assert - Assert.Equal(0x80, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x003D, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void ADC_M_ShouldAddMemoryByteToAccumulator_NoCarry() - { - // Arrange - _cpu.Registers.A = 0x42; - _cpu.Registers.HL = 0x0010; - - _memory.Setup(x => x[0x0010]).Returns(0x3D); - - _cpu.Flags.Carry = false; - - // Act - DefaultInstructionSet.ADC_M(_cpu); - - // Assert - Assert.Equal(0x7F, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0010, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void ADC_M_ShouldAddMemoryByteToAccumulator_Carry() - { - // Arrange - _cpu.Registers.A = 0x42; - _cpu.Registers.HL = 0x0010; - - _memory.Setup(x => x[0x0010]).Returns(0x3D); - - _cpu.Flags.Carry = true; - - // Act - DefaultInstructionSet.ADC_M(_cpu); - - // Assert - Assert.Equal(0x80, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0010, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void ADC_A_ShouldDoubleAccumulator_NoCarry() - { - // Arrange - _cpu.Registers.A = 0x42; - - _cpu.Flags.Carry = false; - - // Act - DefaultInstructionSet.ADC_A(_cpu); - - // Assert - Assert.Equal(0x84, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void ADC_A_ShouldDoubleAccumulator_Carry() - { - // Arrange - _cpu.Registers.A = 0x42; - - _cpu.Flags.Carry = true; - - // Act - DefaultInstructionSet.ADC_A(_cpu); - - // Assert - Assert.Equal(0x85, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void SUB_B_ShouldSubtractRegBFromAccumulator() - { - // Arrange - _cpu.Registers.A = 0x3E; - _cpu.Registers.B = 0x3E; - - // Act - DefaultInstructionSet.SUB_B(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x3E00, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.True(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void SUB_C_ShouldSubtractRegCFromAccumulator() - { - // Arrange - _cpu.Registers.A = 0x3E; - _cpu.Registers.C = 0x3E; - - // Act - DefaultInstructionSet.SUB_C(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x003E, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.True(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void SUB_D_ShouldSubtractRegDFromAccumulator() - { - // Arrange - _cpu.Registers.A = 0x3E; - _cpu.Registers.D = 0x3E; - - // Act - DefaultInstructionSet.SUB_D(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x3E00, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.True(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void SUB_E_ShouldSubtractRegEFromAccumulator() - { - // Arrange - _cpu.Registers.A = 0x3E; - _cpu.Registers.E = 0x3E; - - // Act - DefaultInstructionSet.SUB_E(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x003E, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.True(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void SUB_H_ShouldSubtractRegHFromAccumulator() - { - // Arrange - _cpu.Registers.A = 0x3E; - _cpu.Registers.H = 0x3E; - - // Act - DefaultInstructionSet.SUB_H(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x3E00, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.True(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void SUB_L_ShouldSubtractRegLFromAccumulator() - { - // Arrange - _cpu.Registers.A = 0x3E; - _cpu.Registers.L = 0x3E; - - // Act - DefaultInstructionSet.SUB_L(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x003E, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.True(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void SUB_M_ShouldSubtractMemoryByteFromAccumulator() - { - // Arrange - _cpu.Registers.A = 0x3E; - _cpu.Registers.HL = 0x0010; - - _memory.Setup(x => x[0x0010]).Returns(0x3E); - - // Act - DefaultInstructionSet.SUB_M(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0010, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.True(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void SUB_A_ShouldSubtractRegAFromAccumulator() - { - // Arrange - _cpu.Registers.A = 0x3E; - - // Act - DefaultInstructionSet.SUB_A(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.True(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void SBB_B_ShouldSubtractRegBFromAccumulator_NoCarry() - { - // Arrange - _cpu.Registers.A = 0x04; - _cpu.Registers.B = 0x02; - - _cpu.Flags.Carry = false; - - // Act - DefaultInstructionSet.SBB_B(_cpu); - - // Assert - Assert.Equal(0x02, _cpu.Registers.A); - Assert.Equal(0x0200, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void SBB_B_ShouldSubtractRegBFromAccumulator_Carry() - { - // Arrange - _cpu.Registers.A = 0x04; - _cpu.Registers.B = 0x02; - - _cpu.Flags.Carry = true; - - // Act - DefaultInstructionSet.SBB_B(_cpu); - - // Assert - Assert.Equal(0x01, _cpu.Registers.A); - Assert.Equal(0x0200, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void SBB_C_ShouldSubtractRegCFromAccumulator_NoCarry() - { - // Arrange - _cpu.Registers.A = 0x04; - _cpu.Registers.C = 0x02; - - _cpu.Flags.Carry = false; - - // Act - DefaultInstructionSet.SBB_C(_cpu); - - // Assert - Assert.Equal(0x02, _cpu.Registers.A); - Assert.Equal(0x0002, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void SBB_C_ShouldSubtractRegCFromAccumulator_Carry() - { - // Arrange - _cpu.Registers.A = 0x04; - _cpu.Registers.C = 0x02; - - _cpu.Flags.Carry = true; - - // Act - DefaultInstructionSet.SBB_C(_cpu); - - // Assert - Assert.Equal(0x01, _cpu.Registers.A); - Assert.Equal(0x0002, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void SBB_D_ShouldSubtractRegDFromAccumulator_NoCarry() - { - // Arrange - _cpu.Registers.A = 0x04; - _cpu.Registers.D = 0x02; - - _cpu.Flags.Carry = false; - - // Act - DefaultInstructionSet.SBB_D(_cpu); - - // Assert - Assert.Equal(0x02, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0200, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void SBB_D_ShouldSubtractRegDFromAccumulator_Carry() - { - // Arrange - _cpu.Registers.A = 0x04; - _cpu.Registers.D = 0x02; - - _cpu.Flags.Carry = true; - - // Act - DefaultInstructionSet.SBB_D(_cpu); - - // Assert - Assert.Equal(0x01, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0200, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void SBB_E_ShouldSubtractRegEFromAccumulator_NoCarry() - { - // Arrange - _cpu.Registers.A = 0x04; - _cpu.Registers.E = 0x02; - - _cpu.Flags.Carry = false; - - // Act - DefaultInstructionSet.SBB_E(_cpu); - - // Assert - Assert.Equal(0x02, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0002, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void SBB_E_ShouldSubtractRegEFromAccumulator_Carry() - { - // Arrange - _cpu.Registers.A = 0x04; - _cpu.Registers.E = 0x02; - - _cpu.Flags.Carry = true; - - // Act - DefaultInstructionSet.SBB_E(_cpu); - - // Assert - Assert.Equal(0x01, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0002, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void SBB_H_ShouldSubtractRegHFromAccumulator_NoCarry() - { - // Arrange - _cpu.Registers.A = 0x04; - _cpu.Registers.H = 0x02; - - _cpu.Flags.Carry = false; - - // Act - DefaultInstructionSet.SBB_H(_cpu); - - // Assert - Assert.Equal(0x02, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0200, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void SBB_H_ShouldSubtractRegHFromAccumulator_Carry() - { - // Arrange - _cpu.Registers.A = 0x04; - _cpu.Registers.H = 0x02; - - _cpu.Flags.Carry = true; - - // Act - DefaultInstructionSet.SBB_H(_cpu); - - // Assert - Assert.Equal(0x01, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0200, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void SBB_L_ShouldSubtractRegLFromAccumulator_NoCarry() - { - // Arrange - _cpu.Registers.A = 0x04; - _cpu.Registers.L = 0x02; - - _cpu.Flags.Carry = false; - - // Act - DefaultInstructionSet.SBB_L(_cpu); - - // Assert - Assert.Equal(0x02, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0002, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void SBB_L_ShouldSubtractRegLFromAccumulator_Carry() - { - // Arrange - _cpu.Registers.A = 0x04; - _cpu.Registers.L = 0x02; - - _cpu.Flags.Carry = true; - - // Act - DefaultInstructionSet.SBB_L(_cpu); - - // Assert - Assert.Equal(0x01, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0002, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void SBB_M_ShouldSubtractMemoryByteFromAccumulator_NoCarry() - { - // Arrange - _cpu.Registers.A = 0x04; - _cpu.Registers.HL = 0x0010; - - _memory.Setup(x => x[0x0010]).Returns(0x02); - - _cpu.Flags.Carry = false; - - // Act - DefaultInstructionSet.SBB_M(_cpu); - - // Assert - Assert.Equal(0x02, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0010, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void SBB_M_ShouldSubtractMemoryByteFromAccumulator_Carry() - { - // Arrange - _cpu.Registers.A = 0x04; - _cpu.Registers.HL = 0x0010; - - _memory.Setup(x => x[0x0010]).Returns(0x02); - - _cpu.Flags.Carry = true; - - // Act - DefaultInstructionSet.SBB_M(_cpu); - - // Assert - Assert.Equal(0x01, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0010, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void SBB_A_ShouldSubtractAccumulator_NoCarry() - { - // Arrange - _cpu.Registers.A = 0x04; - - _cpu.Flags.Carry = false; - - // Act - DefaultInstructionSet.SBB_A(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.True(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void SBB_A_ShouldSubtractAccumulator_Carry() - { - // Arrange - _cpu.Registers.A = 0x04; - - _cpu.Flags.Carry = true; - - // Act - DefaultInstructionSet.SBB_A(_cpu); - - // Assert - Assert.Equal(0xFF, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.True(_cpu.Flags.Carry); - } - - [Fact] - public void ANA_B_ShouldBitwiseANDAccumulatorRegB() - { - // Arrange - _cpu.Registers.A = 0xFC; - _cpu.Registers.B = 0x0F; - - // Act - DefaultInstructionSet.ANA_B(_cpu); - - // Assert - Assert.Equal(0x0C, _cpu.Registers.A); - Assert.Equal(0x0F00, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void ANA_C_ShouldBitwiseANDAccumulatorRegC() - { - // Arrange - _cpu.Registers.A = 0xFC; - _cpu.Registers.C = 0x0F; - - // Act - DefaultInstructionSet.ANA_C(_cpu); - - // Assert - Assert.Equal(0x0C, _cpu.Registers.A); - Assert.Equal(0x000F, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void ANA_D_ShouldBitwiseANDAccumulatorRegD() - { - // Arrange - _cpu.Registers.A = 0xFC; - _cpu.Registers.D = 0x0F; - - // Act - DefaultInstructionSet.ANA_D(_cpu); - - // Assert - Assert.Equal(0x0C, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0F00, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void ANA_E_ShouldBitwiseANDAccumulatorRegE() - { - // Arrange - _cpu.Registers.A = 0xFC; - _cpu.Registers.E = 0x0F; - - // Act - DefaultInstructionSet.ANA_E(_cpu); - - // Assert - Assert.Equal(0x0C, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x000F, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void ANA_H_ShouldBitwiseANDAccumulatorRegH() - { - // Arrange - _cpu.Registers.A = 0xFC; - _cpu.Registers.H = 0x0F; - - // Act - DefaultInstructionSet.ANA_H(_cpu); - - // Assert - Assert.Equal(0x0C, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0F00, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void ANA_L_ShouldBitwiseANDAccumulatorRegL() - { - // Arrange - _cpu.Registers.A = 0xFC; - _cpu.Registers.L = 0x0F; - - // Act - DefaultInstructionSet.ANA_L(_cpu); - - // Assert - Assert.Equal(0x0C, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x000F, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void ANA_M_ShouldBitwiseANDAccumulatorMemoryByte() - { - // Arrange - _cpu.Registers.A = 0xFC; - _cpu.Registers.HL = 0x0010; - - _memory.Setup(x => x[0x0010]).Returns(0x0F); - - // Act - DefaultInstructionSet.ANA_M(_cpu); - - // Assert - Assert.Equal(0x0C, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0010, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void ANA_A_ShouldBitwiseANDAccumulatorRegA() - { - // Arrange - _cpu.Registers.A = 0xFF; - - // Act - DefaultInstructionSet.ANA_A(_cpu); - - // Assert - Assert.Equal(0xFF, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void XRA_B_ShouldBitwiseXORAccumulatorRegB() - { - // Arrange - _cpu.Registers.A = 0x5C; - _cpu.Registers.B = 0x78; - - // Act - DefaultInstructionSet.XRA_B(_cpu); - - // Assert - Assert.Equal(0x24, _cpu.Registers.A); - Assert.Equal(0x7800, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void XRA_C_ShouldBitwiseXORAccumulatorRegC() - { - // Arrange - _cpu.Registers.A = 0x5C; - _cpu.Registers.C = 0x78; - - // Act - DefaultInstructionSet.XRA_C(_cpu); - - // Assert - Assert.Equal(0x24, _cpu.Registers.A); - Assert.Equal(0x0078, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void XRA_D_ShouldBitwiseXORAccumulatorRegD() - { - // Arrange - _cpu.Registers.A = 0x5C; - _cpu.Registers.D = 0x78; - - // Act - DefaultInstructionSet.XRA_D(_cpu); - - // Assert - Assert.Equal(0x24, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x7800, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void XRA_E_ShouldBitwiseXORAccumulatorRegD() - { - // Arrange - _cpu.Registers.A = 0x5C; - _cpu.Registers.E = 0x78; - - // Act - DefaultInstructionSet.XRA_E(_cpu); - - // Assert - Assert.Equal(0x24, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0078, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void XRA_H_ShouldBitwiseXORAccumulatorRegH() - { - // Arrange - _cpu.Registers.A = 0x5C; - _cpu.Registers.H = 0x78; - - // Act - DefaultInstructionSet.XRA_H(_cpu); - - // Assert - Assert.Equal(0x24, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x7800, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void XRA_L_ShouldBitwiseXORAccumulatorRegL() - { - // Arrange - _cpu.Registers.A = 0x5C; - _cpu.Registers.L = 0x78; - - // Act - DefaultInstructionSet.XRA_L(_cpu); - - // Assert - Assert.Equal(0x24, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0078, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void XRA_M_ShouldBitwiseXORAccumulatorMemoryByte() - { - // Arrange - _cpu.Registers.A = 0x5C; - _cpu.Registers.HL = 0x0010; - - _memory.Setup(x => x[0x0010]).Returns(0x78); - - // Act - DefaultInstructionSet.XRA_M(_cpu); - - // Assert - Assert.Equal(0x24, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0010, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void XRA_A_ShouldBitwiseXORAccumulatorRegA() - { - // Arrange - _cpu.Registers.A = 0xFF; - - // Act - DefaultInstructionSet.XRA_A(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.True(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void ORA_B_ShouldBitwiseOrAccumulatorRegB() - { - // Arrange - _cpu.Registers.A = 0x33; - _cpu.Registers.B = 0x0F; - - // Act - DefaultInstructionSet.ORA_B(_cpu); - - // Assert - Assert.Equal(0x3F, _cpu.Registers.A); - Assert.Equal(0x0F00, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void ORA_C_ShouldBitwiseOrAccumulatorRegC() - { - // Arrange - _cpu.Registers.A = 0x33; - _cpu.Registers.C = 0x0F; - - // Act - DefaultInstructionSet.ORA_C(_cpu); - - // Assert - Assert.Equal(0x3F, _cpu.Registers.A); - Assert.Equal(0x000F, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void ORA_D_ShouldBitwiseOrAccumulatorRegD() - { - // Arrange - _cpu.Registers.A = 0x33; - _cpu.Registers.D = 0x0F; - - // Act - DefaultInstructionSet.ORA_D(_cpu); - - // Assert - Assert.Equal(0x3F, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0F00, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void ORA_E_ShouldBitwiseOrAccumulatorRegE() - { - // Arrange - _cpu.Registers.A = 0x33; - _cpu.Registers.E = 0x0F; - - // Act - DefaultInstructionSet.ORA_E(_cpu); - - // Assert - Assert.Equal(0x3F, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x000F, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void ORA_H_ShouldBitwiseOrAccumulatorRegH() - { - // Arrange - _cpu.Registers.A = 0x33; - _cpu.Registers.H = 0x0F; - - // Act - DefaultInstructionSet.ORA_H(_cpu); - - // Assert - Assert.Equal(0x3F, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0F00, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void ORA_L_ShouldBitwiseOrAccumulatorRegL() - { - // Arrange - _cpu.Registers.A = 0x33; - _cpu.Registers.L = 0x0F; - - // Act - DefaultInstructionSet.ORA_L(_cpu); - - // Assert - Assert.Equal(0x3F, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x000F, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void ORA_M_ShouldBitwiseOrAccumulatorRegL() - { - // Arrange - _cpu.Registers.A = 0x33; - _cpu.Registers.HL = 0x0010; - - _memory.Setup(x => x[0x0010]).Returns(0x0F); - - // Act - DefaultInstructionSet.ORA_M(_cpu); - - // Assert - Assert.Equal(0x3F, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0010, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void ORA_A_ShouldBitwiseOrAccumulatorRegL() - { - // Arrange - _cpu.Registers.A = 0x33; - - // Act - DefaultInstructionSet.ORA_A(_cpu); - - // Assert - Assert.Equal(0x33, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void CMP_B_BLessThanA_ShouldResetCarry() - { - // Arrange - _cpu.Registers.A = 0x0A; - _cpu.Registers.B = 0x05; - - // Act - DefaultInstructionSet.CMP_B(_cpu); - - // Assert - Assert.Equal(0x0A, _cpu.Registers.A); - Assert.Equal(0x0500, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void CMP_B_BGreaterThanA_ShouldSetCarry() - { - // Arrange - _cpu.Registers.A = 0x02; - _cpu.Registers.B = 0x05; - - // Act - DefaultInstructionSet.CMP_B(_cpu); - - // Assert - Assert.Equal(0x02, _cpu.Registers.A); - Assert.Equal(0x0500, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.True(_cpu.Flags.Carry); - } - - [Fact] - public void CMP_B_BGreaterThanASignDiffer_ShouldResetCarry() - { - // Arrange - _cpu.Registers.A = 0xE5; - _cpu.Registers.B = 0x05; - - // Act - DefaultInstructionSet.CMP_B(_cpu); - - // Assert - Assert.Equal(0xE5, _cpu.Registers.A); - Assert.Equal(0x0500, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void CMP_C_CLessThanA_ShouldResetCarry() - { - // Arrange - _cpu.Registers.A = 0x0A; - _cpu.Registers.C = 0x05; - - // Act - DefaultInstructionSet.CMP_C(_cpu); - - // Assert - Assert.Equal(0x0A, _cpu.Registers.A); - Assert.Equal(0x0005, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void CMP_C_CGreaterThanA_ShouldSetCarry() - { - // Arrange - _cpu.Registers.A = 0x02; - _cpu.Registers.C = 0x05; - - // Act - DefaultInstructionSet.CMP_C(_cpu); - - // Assert - Assert.Equal(0x02, _cpu.Registers.A); - Assert.Equal(0x0005, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.True(_cpu.Flags.Carry); - } - - [Fact] - public void CMP_C_CGreaterThanA_SignDifferShouldResetCarry() - { - // Arrange - _cpu.Registers.A = 0xE5; - _cpu.Registers.C = 0x05; - - // Act - DefaultInstructionSet.CMP_C(_cpu); - - // Assert - Assert.Equal(0xE5, _cpu.Registers.A); - Assert.Equal(0x0005, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void CMP_D_DLessThanA_ShouldResetCarry() - { - // Arrange - _cpu.Registers.A = 0x0A; - _cpu.Registers.D = 0x05; - - // Act - DefaultInstructionSet.CMP_D(_cpu); - - // Assert - Assert.Equal(0x0A, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0500, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void CMP_D_DGreaterThanA_ShouldSetCarry() - { - // Arrange - _cpu.Registers.A = 0x02; - _cpu.Registers.D = 0x05; - - // Act - DefaultInstructionSet.CMP_D(_cpu); - - // Assert - Assert.Equal(0x02, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0500, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.True(_cpu.Flags.Carry); - } - - [Fact] - public void CMP_D_DGreaterThanA_SignDifferShouldResetCarry() - { - // Arrange - _cpu.Registers.A = 0xE5; - _cpu.Registers.D = 0x05; - - // Act - DefaultInstructionSet.CMP_D(_cpu); - - // Assert - Assert.Equal(0xE5, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0500, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void CMP_E_ELessThanA_ShouldResetCarry() - { - // Arrange - _cpu.Registers.A = 0x0A; - _cpu.Registers.E = 0x05; - - // Act - DefaultInstructionSet.CMP_E(_cpu); - - // Assert - Assert.Equal(0x0A, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0005, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void CMP_E_EGreaterThanA_ShouldSetCarry() - { - // Arrange - _cpu.Registers.A = 0x02; - _cpu.Registers.E = 0x05; - - // Act - DefaultInstructionSet.CMP_E(_cpu); - - // Assert - Assert.Equal(0x02, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0005, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.True(_cpu.Flags.Carry); - } - - [Fact] - public void CMP_E_EGreaterThanASignDiffer_ShouldResetCarry() - { - // Arrange - _cpu.Registers.A = 0xE5; - _cpu.Registers.E = 0x05; - - // Act - DefaultInstructionSet.CMP_E(_cpu); - - // Assert - Assert.Equal(0xE5, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0005, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void CMP_H_HLessThanA_ShouldResetCarry() - { - // Arrange - _cpu.Registers.A = 0x0A; - _cpu.Registers.H = 0x05; - - // Act - DefaultInstructionSet.CMP_H(_cpu); - - // Assert - Assert.Equal(0x0A, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0500, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void CMP_H_HGreaterThanA_ShouldSetCarry() - { - // Arrange - _cpu.Registers.A = 0x02; - _cpu.Registers.H = 0x05; - - // Act - DefaultInstructionSet.CMP_H(_cpu); - - // Assert - Assert.Equal(0x02, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0500, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.True(_cpu.Flags.Carry); - } - - [Fact] - public void CMP_H_HGreaterThanASignDiffer_ShouldResetCarry() - { - // Arrange - _cpu.Registers.A = 0xE5; - _cpu.Registers.H = 0x05; - - // Act - DefaultInstructionSet.CMP_H(_cpu); - - // Assert - Assert.Equal(0xE5, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0500, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void CMP_L_LLessThanA_ShouldResetCarry() - { - // Arrange - _cpu.Registers.A = 0x0A; - _cpu.Registers.L = 0x05; - - // Act - DefaultInstructionSet.CMP_L(_cpu); - - // Assert - Assert.Equal(0x0A, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0005, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void CMP_L_LGreaterThanA_ShouldSetCarry() - { - // Arrange - _cpu.Registers.A = 0x02; - _cpu.Registers.L = 0x05; - - // Act - DefaultInstructionSet.CMP_L(_cpu); - - // Assert - Assert.Equal(0x02, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0005, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.True(_cpu.Flags.Carry); - } - - [Fact] - public void CMP_L_LGreaterThanASignDiffer_ShouldResetCarry() - { - // Arrange - _cpu.Registers.A = 0xE5; - _cpu.Registers.L = 0x05; - - // Act - DefaultInstructionSet.CMP_L(_cpu); - - // Assert - Assert.Equal(0xE5, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0005, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void CMP_M_MemoryByteLessThanA_ShouldResetCarry() - { - // Arrange - _cpu.Registers.A = 0x0A; - _cpu.Registers.HL = 0x0010; - - _memory.Setup(x => x[0x0010]).Returns(0x05); - - // Act - DefaultInstructionSet.CMP_M(_cpu); - - // Assert - Assert.Equal(0x0A, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0010, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void CMP_M_MemoryByteGreaterThanA_ShouldSetCarry() - { - // Arrange - _cpu.Registers.A = 0x02; - _cpu.Registers.HL = 0x0010; - - _memory.Setup(x => x[0x0010]).Returns(0x05); - - // Act - DefaultInstructionSet.CMP_M(_cpu); - - // Assert - Assert.Equal(0x02, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0010, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.True(_cpu.Flags.Carry); - } - - [Fact] - public void CMP_M_MemoryByteGreaterThanASignDiffer_ShouldResetCarry() - { - // Arrange - _cpu.Registers.A = 0xE5; - _cpu.Registers.HL = 0x0010; - - _memory.Setup(x => x[0x0010]).Returns(0x05); - - // Act - DefaultInstructionSet.CMP_M(_cpu); - - // Assert - Assert.Equal(0xE5, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0010, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void CMP_A_ShouldSetZeroFlag() - { - // Arrange - _cpu.Registers.A = 0x05; - - // Act - DefaultInstructionSet.CMP_A(_cpu); - - // Assert - Assert.Equal(0x05, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.True(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - } +using Intel8080.Emulator.Instructions; +using Moq; +using Xunit; + +namespace Intel8080.Emulator.Tests.Instructions; + +public class AccumulatorInstructionTests +{ + private readonly CPU _cpu; + private readonly Mock _memory; + + public AccumulatorInstructionTests() + { + _memory = new Mock(); + + _cpu = new CPU(_memory.Object); + } + + [Fact] + public void ADD_B_ShouldAddRegBToAccumulator() + { + // Arrange + _cpu.Registers.A = 0x6C; + _cpu.Registers.B = 0x2E; + + // Act + DefaultInstructionSet.ADD_B(_cpu); + + // Assert + Assert.Equal(0x9A, _cpu.Registers.A); + Assert.Equal(0x2E00, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void ADD_C_ShouldAddRegCToAccumulator() + { + // Arrange + _cpu.Registers.A = 0x6C; + _cpu.Registers.C = 0x2E; + + // Act + DefaultInstructionSet.ADD_C(_cpu); + + // Assert + Assert.Equal(0x9A, _cpu.Registers.A); + Assert.Equal(0x002E, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void ADD_D_ShouldAddRegDToAccumulator() + { + // Arrange + _cpu.Registers.A = 0x6C; + _cpu.Registers.D = 0x2E; + + // Act + DefaultInstructionSet.ADD_D(_cpu); + + // Assert + Assert.Equal(0x9A, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x2E00, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void ADD_E_ShouldAddRegEToAccumulator() + { + // Arrange + _cpu.Registers.A = 0x6C; + _cpu.Registers.E = 0x2E; + + // Act + DefaultInstructionSet.ADD_E(_cpu); + + // Assert + Assert.Equal(0x9A, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x002E, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void ADD_H_ShouldAddRegHToAccumulator() + { + // Arrange + _cpu.Registers.A = 0x6C; + _cpu.Registers.H = 0x2E; + + // Act + DefaultInstructionSet.ADD_H(_cpu); + + // Assert + Assert.Equal(0x9A, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x2E00, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void ADD_L_ShouldAddRegLToAccumulator() + { + // Arrange + _cpu.Registers.A = 0x6C; + _cpu.Registers.L = 0x2E; + + // Act + DefaultInstructionSet.ADD_L(_cpu); + + // Assert + Assert.Equal(0x9A, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x002E, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void ADD_M_ShouldAddMemoryByteToAccumulator() + { + // Arrange + _cpu.Registers.A = 0x6C; + _cpu.Registers.HL = 0x0010; + + _memory.Setup(x => x[0x0010]).Returns(0x2E); + + // Act + DefaultInstructionSet.ADD_M(_cpu); + + // Assert + Assert.Equal(0x9A, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0010, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void ADD_A_ShouldDoubleAccumulator() + { + // Arrange + _cpu.Registers.A = 0x6C; + + // Act + DefaultInstructionSet.ADD_A(_cpu); + + // Assert + Assert.Equal(0xD8, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void ADC_B_ShouldAddRegBToAccumulator_NoCarry() + { + // Arrange + _cpu.Registers.A = 0x42; + _cpu.Registers.B = 0x3D; + + _cpu.Flags.Carry = false; + + // Act + DefaultInstructionSet.ADC_B(_cpu); + + // Assert + Assert.Equal(0x7F, _cpu.Registers.A); + Assert.Equal(0x3D00, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void ADC_B_ShouldAddRegBToAccumulator_Carry() + { + // Arrange + _cpu.Registers.A = 0x42; + _cpu.Registers.B = 0x3D; + + _cpu.Flags.Carry = true; + + // Act + DefaultInstructionSet.ADC_B(_cpu); + + // Assert + Assert.Equal(0x80, _cpu.Registers.A); + Assert.Equal(0x3D00, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void ADC_C_ShouldAddRegCToAccumulator_NoCarry() + { + // Arrange + _cpu.Registers.A = 0x42; + _cpu.Registers.C = 0x3D; + + _cpu.Flags.Carry = false; + + // Act + DefaultInstructionSet.ADC_C(_cpu); + + // Assert + Assert.Equal(0x7F, _cpu.Registers.A); + Assert.Equal(0x003D, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void ADC_C_ShouldAddRegCToAccumulator_Carry() + { + // Arrange + _cpu.Registers.A = 0x42; + _cpu.Registers.C = 0x3D; + + _cpu.Flags.Carry = true; + + // Act + DefaultInstructionSet.ADC_C(_cpu); + + // Assert + Assert.Equal(0x80, _cpu.Registers.A); + Assert.Equal(0x003D, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void ADC_D_ShouldAddRegDToAccumulator_NoCarry() + { + // Arrange + _cpu.Registers.A = 0x42; + _cpu.Registers.D = 0x3D; + + _cpu.Flags.Carry = false; + + // Act + DefaultInstructionSet.ADC_D(_cpu); + + // Assert + Assert.Equal(0x7F, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x3D00, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void ADC_D_ShouldAddRegDToAccumulator_Carry() + { + // Arrange + _cpu.Registers.A = 0x42; + _cpu.Registers.D = 0x3D; + + _cpu.Flags.Carry = true; + + // Act + DefaultInstructionSet.ADC_D(_cpu); + + // Assert + Assert.Equal(0x80, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x3D00, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void ADC_E_ShouldAddRegEToAccumulator_NoCarry() + { + // Arrange + _cpu.Registers.A = 0x42; + _cpu.Registers.E = 0x3D; + + _cpu.Flags.Carry = false; + + // Act + DefaultInstructionSet.ADC_E(_cpu); + + // Assert + Assert.Equal(0x7F, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x003D, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void ADC_E_ShouldAddRegEToAccumulator_Carry() + { + // Arrange + _cpu.Registers.A = 0x42; + _cpu.Registers.E = 0x3D; + + _cpu.Flags.Carry = true; + + // Act + DefaultInstructionSet.ADC_E(_cpu); + + // Assert + Assert.Equal(0x80, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x003D, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void ADC_H_ShouldAddRegHToAccumulator_NoCarry() + { + // Arrange + _cpu.Registers.A = 0x42; + _cpu.Registers.H = 0x3D; + + _cpu.Flags.Carry = false; + + // Act + DefaultInstructionSet.ADC_H(_cpu); + + // Assert + Assert.Equal(0x7F, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x3D00, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void ADC_H_ShouldAddRegHToAccumulator_Carry() + { + // Arrange + _cpu.Registers.A = 0x42; + _cpu.Registers.H = 0x3D; + + _cpu.Flags.Carry = true; + + // Act + DefaultInstructionSet.ADC_H(_cpu); + + // Assert + Assert.Equal(0x80, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x3D00, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void ADC_L_ShouldAddRegLToAccumulator_NoCarry() + { + // Arrange + _cpu.Registers.A = 0x42; + _cpu.Registers.L = 0x3D; + + _cpu.Flags.Carry = false; + + // Act + DefaultInstructionSet.ADC_L(_cpu); + + // Assert + Assert.Equal(0x7F, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x003D, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void ADC_L_ShouldAddRegLToAccumulator_Carry() + { + // Arrange + _cpu.Registers.A = 0x42; + _cpu.Registers.L = 0x3D; + + _cpu.Flags.Carry = true; + + // Act + DefaultInstructionSet.ADC_L(_cpu); + + // Assert + Assert.Equal(0x80, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x003D, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void ADC_M_ShouldAddMemoryByteToAccumulator_NoCarry() + { + // Arrange + _cpu.Registers.A = 0x42; + _cpu.Registers.HL = 0x0010; + + _memory.Setup(x => x[0x0010]).Returns(0x3D); + + _cpu.Flags.Carry = false; + + // Act + DefaultInstructionSet.ADC_M(_cpu); + + // Assert + Assert.Equal(0x7F, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0010, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void ADC_M_ShouldAddMemoryByteToAccumulator_Carry() + { + // Arrange + _cpu.Registers.A = 0x42; + _cpu.Registers.HL = 0x0010; + + _memory.Setup(x => x[0x0010]).Returns(0x3D); + + _cpu.Flags.Carry = true; + + // Act + DefaultInstructionSet.ADC_M(_cpu); + + // Assert + Assert.Equal(0x80, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0010, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void ADC_A_ShouldDoubleAccumulator_NoCarry() + { + // Arrange + _cpu.Registers.A = 0x42; + + _cpu.Flags.Carry = false; + + // Act + DefaultInstructionSet.ADC_A(_cpu); + + // Assert + Assert.Equal(0x84, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void ADC_A_ShouldDoubleAccumulator_Carry() + { + // Arrange + _cpu.Registers.A = 0x42; + + _cpu.Flags.Carry = true; + + // Act + DefaultInstructionSet.ADC_A(_cpu); + + // Assert + Assert.Equal(0x85, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void SUB_B_ShouldSubtractRegBFromAccumulator() + { + // Arrange + _cpu.Registers.A = 0x3E; + _cpu.Registers.B = 0x3E; + + // Act + DefaultInstructionSet.SUB_B(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x3E00, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.True(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void SUB_C_ShouldSubtractRegCFromAccumulator() + { + // Arrange + _cpu.Registers.A = 0x3E; + _cpu.Registers.C = 0x3E; + + // Act + DefaultInstructionSet.SUB_C(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x003E, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.True(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void SUB_D_ShouldSubtractRegDFromAccumulator() + { + // Arrange + _cpu.Registers.A = 0x3E; + _cpu.Registers.D = 0x3E; + + // Act + DefaultInstructionSet.SUB_D(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x3E00, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.True(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void SUB_E_ShouldSubtractRegEFromAccumulator() + { + // Arrange + _cpu.Registers.A = 0x3E; + _cpu.Registers.E = 0x3E; + + // Act + DefaultInstructionSet.SUB_E(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x003E, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.True(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void SUB_H_ShouldSubtractRegHFromAccumulator() + { + // Arrange + _cpu.Registers.A = 0x3E; + _cpu.Registers.H = 0x3E; + + // Act + DefaultInstructionSet.SUB_H(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x3E00, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.True(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void SUB_L_ShouldSubtractRegLFromAccumulator() + { + // Arrange + _cpu.Registers.A = 0x3E; + _cpu.Registers.L = 0x3E; + + // Act + DefaultInstructionSet.SUB_L(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x003E, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.True(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void SUB_M_ShouldSubtractMemoryByteFromAccumulator() + { + // Arrange + _cpu.Registers.A = 0x3E; + _cpu.Registers.HL = 0x0010; + + _memory.Setup(x => x[0x0010]).Returns(0x3E); + + // Act + DefaultInstructionSet.SUB_M(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0010, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.True(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void SUB_A_ShouldSubtractRegAFromAccumulator() + { + // Arrange + _cpu.Registers.A = 0x3E; + + // Act + DefaultInstructionSet.SUB_A(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.True(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void SBB_B_ShouldSubtractRegBFromAccumulator_NoCarry() + { + // Arrange + _cpu.Registers.A = 0x04; + _cpu.Registers.B = 0x02; + + _cpu.Flags.Carry = false; + + // Act + DefaultInstructionSet.SBB_B(_cpu); + + // Assert + Assert.Equal(0x02, _cpu.Registers.A); + Assert.Equal(0x0200, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void SBB_B_ShouldSubtractRegBFromAccumulator_Carry() + { + // Arrange + _cpu.Registers.A = 0x04; + _cpu.Registers.B = 0x02; + + _cpu.Flags.Carry = true; + + // Act + DefaultInstructionSet.SBB_B(_cpu); + + // Assert + Assert.Equal(0x01, _cpu.Registers.A); + Assert.Equal(0x0200, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void SBB_C_ShouldSubtractRegCFromAccumulator_NoCarry() + { + // Arrange + _cpu.Registers.A = 0x04; + _cpu.Registers.C = 0x02; + + _cpu.Flags.Carry = false; + + // Act + DefaultInstructionSet.SBB_C(_cpu); + + // Assert + Assert.Equal(0x02, _cpu.Registers.A); + Assert.Equal(0x0002, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void SBB_C_ShouldSubtractRegCFromAccumulator_Carry() + { + // Arrange + _cpu.Registers.A = 0x04; + _cpu.Registers.C = 0x02; + + _cpu.Flags.Carry = true; + + // Act + DefaultInstructionSet.SBB_C(_cpu); + + // Assert + Assert.Equal(0x01, _cpu.Registers.A); + Assert.Equal(0x0002, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void SBB_D_ShouldSubtractRegDFromAccumulator_NoCarry() + { + // Arrange + _cpu.Registers.A = 0x04; + _cpu.Registers.D = 0x02; + + _cpu.Flags.Carry = false; + + // Act + DefaultInstructionSet.SBB_D(_cpu); + + // Assert + Assert.Equal(0x02, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0200, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void SBB_D_ShouldSubtractRegDFromAccumulator_Carry() + { + // Arrange + _cpu.Registers.A = 0x04; + _cpu.Registers.D = 0x02; + + _cpu.Flags.Carry = true; + + // Act + DefaultInstructionSet.SBB_D(_cpu); + + // Assert + Assert.Equal(0x01, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0200, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void SBB_E_ShouldSubtractRegEFromAccumulator_NoCarry() + { + // Arrange + _cpu.Registers.A = 0x04; + _cpu.Registers.E = 0x02; + + _cpu.Flags.Carry = false; + + // Act + DefaultInstructionSet.SBB_E(_cpu); + + // Assert + Assert.Equal(0x02, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0002, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void SBB_E_ShouldSubtractRegEFromAccumulator_Carry() + { + // Arrange + _cpu.Registers.A = 0x04; + _cpu.Registers.E = 0x02; + + _cpu.Flags.Carry = true; + + // Act + DefaultInstructionSet.SBB_E(_cpu); + + // Assert + Assert.Equal(0x01, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0002, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void SBB_H_ShouldSubtractRegHFromAccumulator_NoCarry() + { + // Arrange + _cpu.Registers.A = 0x04; + _cpu.Registers.H = 0x02; + + _cpu.Flags.Carry = false; + + // Act + DefaultInstructionSet.SBB_H(_cpu); + + // Assert + Assert.Equal(0x02, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0200, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void SBB_H_ShouldSubtractRegHFromAccumulator_Carry() + { + // Arrange + _cpu.Registers.A = 0x04; + _cpu.Registers.H = 0x02; + + _cpu.Flags.Carry = true; + + // Act + DefaultInstructionSet.SBB_H(_cpu); + + // Assert + Assert.Equal(0x01, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0200, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void SBB_L_ShouldSubtractRegLFromAccumulator_NoCarry() + { + // Arrange + _cpu.Registers.A = 0x04; + _cpu.Registers.L = 0x02; + + _cpu.Flags.Carry = false; + + // Act + DefaultInstructionSet.SBB_L(_cpu); + + // Assert + Assert.Equal(0x02, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0002, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void SBB_L_ShouldSubtractRegLFromAccumulator_Carry() + { + // Arrange + _cpu.Registers.A = 0x04; + _cpu.Registers.L = 0x02; + + _cpu.Flags.Carry = true; + + // Act + DefaultInstructionSet.SBB_L(_cpu); + + // Assert + Assert.Equal(0x01, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0002, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void SBB_M_ShouldSubtractMemoryByteFromAccumulator_NoCarry() + { + // Arrange + _cpu.Registers.A = 0x04; + _cpu.Registers.HL = 0x0010; + + _memory.Setup(x => x[0x0010]).Returns(0x02); + + _cpu.Flags.Carry = false; + + // Act + DefaultInstructionSet.SBB_M(_cpu); + + // Assert + Assert.Equal(0x02, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0010, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void SBB_M_ShouldSubtractMemoryByteFromAccumulator_Carry() + { + // Arrange + _cpu.Registers.A = 0x04; + _cpu.Registers.HL = 0x0010; + + _memory.Setup(x => x[0x0010]).Returns(0x02); + + _cpu.Flags.Carry = true; + + // Act + DefaultInstructionSet.SBB_M(_cpu); + + // Assert + Assert.Equal(0x01, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0010, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void SBB_A_ShouldSubtractAccumulator_NoCarry() + { + // Arrange + _cpu.Registers.A = 0x04; + + _cpu.Flags.Carry = false; + + // Act + DefaultInstructionSet.SBB_A(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.True(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void SBB_A_ShouldSubtractAccumulator_Carry() + { + // Arrange + _cpu.Registers.A = 0x04; + + _cpu.Flags.Carry = true; + + // Act + DefaultInstructionSet.SBB_A(_cpu); + + // Assert + Assert.Equal(0xFF, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.True(_cpu.Flags.Carry); + } + + [Fact] + public void ANA_B_ShouldBitwiseANDAccumulatorRegB() + { + // Arrange + _cpu.Registers.A = 0xFC; + _cpu.Registers.B = 0x0F; + + // Act + DefaultInstructionSet.ANA_B(_cpu); + + // Assert + Assert.Equal(0x0C, _cpu.Registers.A); + Assert.Equal(0x0F00, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void ANA_C_ShouldBitwiseANDAccumulatorRegC() + { + // Arrange + _cpu.Registers.A = 0xFC; + _cpu.Registers.C = 0x0F; + + // Act + DefaultInstructionSet.ANA_C(_cpu); + + // Assert + Assert.Equal(0x0C, _cpu.Registers.A); + Assert.Equal(0x000F, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void ANA_D_ShouldBitwiseANDAccumulatorRegD() + { + // Arrange + _cpu.Registers.A = 0xFC; + _cpu.Registers.D = 0x0F; + + // Act + DefaultInstructionSet.ANA_D(_cpu); + + // Assert + Assert.Equal(0x0C, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0F00, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void ANA_E_ShouldBitwiseANDAccumulatorRegE() + { + // Arrange + _cpu.Registers.A = 0xFC; + _cpu.Registers.E = 0x0F; + + // Act + DefaultInstructionSet.ANA_E(_cpu); + + // Assert + Assert.Equal(0x0C, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x000F, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void ANA_H_ShouldBitwiseANDAccumulatorRegH() + { + // Arrange + _cpu.Registers.A = 0xFC; + _cpu.Registers.H = 0x0F; + + // Act + DefaultInstructionSet.ANA_H(_cpu); + + // Assert + Assert.Equal(0x0C, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0F00, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void ANA_L_ShouldBitwiseANDAccumulatorRegL() + { + // Arrange + _cpu.Registers.A = 0xFC; + _cpu.Registers.L = 0x0F; + + // Act + DefaultInstructionSet.ANA_L(_cpu); + + // Assert + Assert.Equal(0x0C, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x000F, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void ANA_M_ShouldBitwiseANDAccumulatorMemoryByte() + { + // Arrange + _cpu.Registers.A = 0xFC; + _cpu.Registers.HL = 0x0010; + + _memory.Setup(x => x[0x0010]).Returns(0x0F); + + // Act + DefaultInstructionSet.ANA_M(_cpu); + + // Assert + Assert.Equal(0x0C, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0010, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void ANA_A_ShouldBitwiseANDAccumulatorRegA() + { + // Arrange + _cpu.Registers.A = 0xFF; + + // Act + DefaultInstructionSet.ANA_A(_cpu); + + // Assert + Assert.Equal(0xFF, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void XRA_B_ShouldBitwiseXORAccumulatorRegB() + { + // Arrange + _cpu.Registers.A = 0x5C; + _cpu.Registers.B = 0x78; + + // Act + DefaultInstructionSet.XRA_B(_cpu); + + // Assert + Assert.Equal(0x24, _cpu.Registers.A); + Assert.Equal(0x7800, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void XRA_C_ShouldBitwiseXORAccumulatorRegC() + { + // Arrange + _cpu.Registers.A = 0x5C; + _cpu.Registers.C = 0x78; + + // Act + DefaultInstructionSet.XRA_C(_cpu); + + // Assert + Assert.Equal(0x24, _cpu.Registers.A); + Assert.Equal(0x0078, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void XRA_D_ShouldBitwiseXORAccumulatorRegD() + { + // Arrange + _cpu.Registers.A = 0x5C; + _cpu.Registers.D = 0x78; + + // Act + DefaultInstructionSet.XRA_D(_cpu); + + // Assert + Assert.Equal(0x24, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x7800, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void XRA_E_ShouldBitwiseXORAccumulatorRegD() + { + // Arrange + _cpu.Registers.A = 0x5C; + _cpu.Registers.E = 0x78; + + // Act + DefaultInstructionSet.XRA_E(_cpu); + + // Assert + Assert.Equal(0x24, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0078, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void XRA_H_ShouldBitwiseXORAccumulatorRegH() + { + // Arrange + _cpu.Registers.A = 0x5C; + _cpu.Registers.H = 0x78; + + // Act + DefaultInstructionSet.XRA_H(_cpu); + + // Assert + Assert.Equal(0x24, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x7800, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void XRA_L_ShouldBitwiseXORAccumulatorRegL() + { + // Arrange + _cpu.Registers.A = 0x5C; + _cpu.Registers.L = 0x78; + + // Act + DefaultInstructionSet.XRA_L(_cpu); + + // Assert + Assert.Equal(0x24, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0078, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void XRA_M_ShouldBitwiseXORAccumulatorMemoryByte() + { + // Arrange + _cpu.Registers.A = 0x5C; + _cpu.Registers.HL = 0x0010; + + _memory.Setup(x => x[0x0010]).Returns(0x78); + + // Act + DefaultInstructionSet.XRA_M(_cpu); + + // Assert + Assert.Equal(0x24, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0010, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void XRA_A_ShouldBitwiseXORAccumulatorRegA() + { + // Arrange + _cpu.Registers.A = 0xFF; + + // Act + DefaultInstructionSet.XRA_A(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.True(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void ORA_B_ShouldBitwiseOrAccumulatorRegB() + { + // Arrange + _cpu.Registers.A = 0x33; + _cpu.Registers.B = 0x0F; + + // Act + DefaultInstructionSet.ORA_B(_cpu); + + // Assert + Assert.Equal(0x3F, _cpu.Registers.A); + Assert.Equal(0x0F00, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void ORA_C_ShouldBitwiseOrAccumulatorRegC() + { + // Arrange + _cpu.Registers.A = 0x33; + _cpu.Registers.C = 0x0F; + + // Act + DefaultInstructionSet.ORA_C(_cpu); + + // Assert + Assert.Equal(0x3F, _cpu.Registers.A); + Assert.Equal(0x000F, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void ORA_D_ShouldBitwiseOrAccumulatorRegD() + { + // Arrange + _cpu.Registers.A = 0x33; + _cpu.Registers.D = 0x0F; + + // Act + DefaultInstructionSet.ORA_D(_cpu); + + // Assert + Assert.Equal(0x3F, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0F00, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void ORA_E_ShouldBitwiseOrAccumulatorRegE() + { + // Arrange + _cpu.Registers.A = 0x33; + _cpu.Registers.E = 0x0F; + + // Act + DefaultInstructionSet.ORA_E(_cpu); + + // Assert + Assert.Equal(0x3F, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x000F, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void ORA_H_ShouldBitwiseOrAccumulatorRegH() + { + // Arrange + _cpu.Registers.A = 0x33; + _cpu.Registers.H = 0x0F; + + // Act + DefaultInstructionSet.ORA_H(_cpu); + + // Assert + Assert.Equal(0x3F, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0F00, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void ORA_L_ShouldBitwiseOrAccumulatorRegL() + { + // Arrange + _cpu.Registers.A = 0x33; + _cpu.Registers.L = 0x0F; + + // Act + DefaultInstructionSet.ORA_L(_cpu); + + // Assert + Assert.Equal(0x3F, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x000F, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void ORA_M_ShouldBitwiseOrAccumulatorRegL() + { + // Arrange + _cpu.Registers.A = 0x33; + _cpu.Registers.HL = 0x0010; + + _memory.Setup(x => x[0x0010]).Returns(0x0F); + + // Act + DefaultInstructionSet.ORA_M(_cpu); + + // Assert + Assert.Equal(0x3F, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0010, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void ORA_A_ShouldBitwiseOrAccumulatorRegL() + { + // Arrange + _cpu.Registers.A = 0x33; + + // Act + DefaultInstructionSet.ORA_A(_cpu); + + // Assert + Assert.Equal(0x33, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void CMP_B_BLessThanA_ShouldResetCarry() + { + // Arrange + _cpu.Registers.A = 0x0A; + _cpu.Registers.B = 0x05; + + // Act + DefaultInstructionSet.CMP_B(_cpu); + + // Assert + Assert.Equal(0x0A, _cpu.Registers.A); + Assert.Equal(0x0500, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void CMP_B_BGreaterThanA_ShouldSetCarry() + { + // Arrange + _cpu.Registers.A = 0x02; + _cpu.Registers.B = 0x05; + + // Act + DefaultInstructionSet.CMP_B(_cpu); + + // Assert + Assert.Equal(0x02, _cpu.Registers.A); + Assert.Equal(0x0500, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.True(_cpu.Flags.Carry); + } + + [Fact] + public void CMP_B_BGreaterThanASignDiffer_ShouldResetCarry() + { + // Arrange + _cpu.Registers.A = 0xE5; + _cpu.Registers.B = 0x05; + + // Act + DefaultInstructionSet.CMP_B(_cpu); + + // Assert + Assert.Equal(0xE5, _cpu.Registers.A); + Assert.Equal(0x0500, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void CMP_C_CLessThanA_ShouldResetCarry() + { + // Arrange + _cpu.Registers.A = 0x0A; + _cpu.Registers.C = 0x05; + + // Act + DefaultInstructionSet.CMP_C(_cpu); + + // Assert + Assert.Equal(0x0A, _cpu.Registers.A); + Assert.Equal(0x0005, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void CMP_C_CGreaterThanA_ShouldSetCarry() + { + // Arrange + _cpu.Registers.A = 0x02; + _cpu.Registers.C = 0x05; + + // Act + DefaultInstructionSet.CMP_C(_cpu); + + // Assert + Assert.Equal(0x02, _cpu.Registers.A); + Assert.Equal(0x0005, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.True(_cpu.Flags.Carry); + } + + [Fact] + public void CMP_C_CGreaterThanA_SignDifferShouldResetCarry() + { + // Arrange + _cpu.Registers.A = 0xE5; + _cpu.Registers.C = 0x05; + + // Act + DefaultInstructionSet.CMP_C(_cpu); + + // Assert + Assert.Equal(0xE5, _cpu.Registers.A); + Assert.Equal(0x0005, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void CMP_D_DLessThanA_ShouldResetCarry() + { + // Arrange + _cpu.Registers.A = 0x0A; + _cpu.Registers.D = 0x05; + + // Act + DefaultInstructionSet.CMP_D(_cpu); + + // Assert + Assert.Equal(0x0A, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0500, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void CMP_D_DGreaterThanA_ShouldSetCarry() + { + // Arrange + _cpu.Registers.A = 0x02; + _cpu.Registers.D = 0x05; + + // Act + DefaultInstructionSet.CMP_D(_cpu); + + // Assert + Assert.Equal(0x02, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0500, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.True(_cpu.Flags.Carry); + } + + [Fact] + public void CMP_D_DGreaterThanA_SignDifferShouldResetCarry() + { + // Arrange + _cpu.Registers.A = 0xE5; + _cpu.Registers.D = 0x05; + + // Act + DefaultInstructionSet.CMP_D(_cpu); + + // Assert + Assert.Equal(0xE5, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0500, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void CMP_E_ELessThanA_ShouldResetCarry() + { + // Arrange + _cpu.Registers.A = 0x0A; + _cpu.Registers.E = 0x05; + + // Act + DefaultInstructionSet.CMP_E(_cpu); + + // Assert + Assert.Equal(0x0A, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0005, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void CMP_E_EGreaterThanA_ShouldSetCarry() + { + // Arrange + _cpu.Registers.A = 0x02; + _cpu.Registers.E = 0x05; + + // Act + DefaultInstructionSet.CMP_E(_cpu); + + // Assert + Assert.Equal(0x02, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0005, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.True(_cpu.Flags.Carry); + } + + [Fact] + public void CMP_E_EGreaterThanASignDiffer_ShouldResetCarry() + { + // Arrange + _cpu.Registers.A = 0xE5; + _cpu.Registers.E = 0x05; + + // Act + DefaultInstructionSet.CMP_E(_cpu); + + // Assert + Assert.Equal(0xE5, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0005, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void CMP_H_HLessThanA_ShouldResetCarry() + { + // Arrange + _cpu.Registers.A = 0x0A; + _cpu.Registers.H = 0x05; + + // Act + DefaultInstructionSet.CMP_H(_cpu); + + // Assert + Assert.Equal(0x0A, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0500, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void CMP_H_HGreaterThanA_ShouldSetCarry() + { + // Arrange + _cpu.Registers.A = 0x02; + _cpu.Registers.H = 0x05; + + // Act + DefaultInstructionSet.CMP_H(_cpu); + + // Assert + Assert.Equal(0x02, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0500, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.True(_cpu.Flags.Carry); + } + + [Fact] + public void CMP_H_HGreaterThanASignDiffer_ShouldResetCarry() + { + // Arrange + _cpu.Registers.A = 0xE5; + _cpu.Registers.H = 0x05; + + // Act + DefaultInstructionSet.CMP_H(_cpu); + + // Assert + Assert.Equal(0xE5, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0500, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void CMP_L_LLessThanA_ShouldResetCarry() + { + // Arrange + _cpu.Registers.A = 0x0A; + _cpu.Registers.L = 0x05; + + // Act + DefaultInstructionSet.CMP_L(_cpu); + + // Assert + Assert.Equal(0x0A, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0005, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void CMP_L_LGreaterThanA_ShouldSetCarry() + { + // Arrange + _cpu.Registers.A = 0x02; + _cpu.Registers.L = 0x05; + + // Act + DefaultInstructionSet.CMP_L(_cpu); + + // Assert + Assert.Equal(0x02, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0005, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.True(_cpu.Flags.Carry); + } + + [Fact] + public void CMP_L_LGreaterThanASignDiffer_ShouldResetCarry() + { + // Arrange + _cpu.Registers.A = 0xE5; + _cpu.Registers.L = 0x05; + + // Act + DefaultInstructionSet.CMP_L(_cpu); + + // Assert + Assert.Equal(0xE5, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0005, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void CMP_M_MemoryByteLessThanA_ShouldResetCarry() + { + // Arrange + _cpu.Registers.A = 0x0A; + _cpu.Registers.HL = 0x0010; + + _memory.Setup(x => x[0x0010]).Returns(0x05); + + // Act + DefaultInstructionSet.CMP_M(_cpu); + + // Assert + Assert.Equal(0x0A, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0010, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void CMP_M_MemoryByteGreaterThanA_ShouldSetCarry() + { + // Arrange + _cpu.Registers.A = 0x02; + _cpu.Registers.HL = 0x0010; + + _memory.Setup(x => x[0x0010]).Returns(0x05); + + // Act + DefaultInstructionSet.CMP_M(_cpu); + + // Assert + Assert.Equal(0x02, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0010, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.True(_cpu.Flags.Carry); + } + + [Fact] + public void CMP_M_MemoryByteGreaterThanASignDiffer_ShouldResetCarry() + { + // Arrange + _cpu.Registers.A = 0xE5; + _cpu.Registers.HL = 0x0010; + + _memory.Setup(x => x[0x0010]).Returns(0x05); + + // Act + DefaultInstructionSet.CMP_M(_cpu); + + // Assert + Assert.Equal(0xE5, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0010, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void CMP_A_ShouldSetZeroFlag() + { + // Arrange + _cpu.Registers.A = 0x05; + + // Act + DefaultInstructionSet.CMP_A(_cpu); + + // Assert + Assert.Equal(0x05, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.True(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } } \ No newline at end of file diff --git a/Intel8080.Emulator.Tests/Instructions/CallInstructionTests.cs b/Intel8080.Emulator.Tests/Instructions/CallInstructionTests.cs index 1862a3c..f6b4ddd 100644 --- a/Intel8080.Emulator.Tests/Instructions/CallInstructionTests.cs +++ b/Intel8080.Emulator.Tests/Instructions/CallInstructionTests.cs @@ -1,499 +1,496 @@ -using Intel8080.Emulator.Instructions; -using Moq; -using System; -using Xunit; - -namespace Intel8080.Emulator.Tests.Instructions -{ - public class CallInstructionTests - { - private readonly CPU _cpu; - private readonly IMemory _memory; - - public CallInstructionTests() - { - _memory = new DefaultMemory(0x100); - - _cpu = new CPU(_memory); - - _cpu.Registers.PC = 1; - } - - [Fact] - public void CALL_ShouldCallSubroutine() - { - // Arrange - _memory[0x0001] = 0x50; - _memory[0x0002] = 0x00; - - _cpu.Registers.SP = 0x0012; - - // Act - DefaultInstructionSet.CALL(_cpu); - - // Assert - Assert.Equal(0x0050, _cpu.Registers.PC); - Assert.Equal(0x0010, _cpu.Registers.SP); - - Assert.Equal(0x03, _memory[0x0010]); - Assert.Equal(0x00, _memory[0x0011]); - } - - [Fact] - public void CNZ_ShouldCallIfZeroFlagFalse() - { - // Arrange - _memory[0x0001] = 0x50; - _memory[0x0002] = 0x00; - - _cpu.Registers.SP = 0x0012; - - _cpu.Flags.Zero = false; - - // Act - DefaultInstructionSet.CNZ(_cpu); - - // Assert - Assert.Equal(0x0050, _cpu.Registers.PC); - Assert.Equal(0x0010, _cpu.Registers.SP); - - Assert.Equal(0x03, _memory[0x0010]); - Assert.Equal(0x00, _memory[0x0011]); - } - - [Fact] - public void CNZ_ShouldNotCallIfZeroFlagSet() - { - // Arrange - _memory[0x0001] = 0x50; - _memory[0x0002] = 0x00; - - _cpu.Registers.SP = 0x0012; - - _cpu.Flags.Zero = true; - - // Act - DefaultInstructionSet.CNZ(_cpu); - - // Assert - Assert.Equal(0x0003, _cpu.Registers.PC); - Assert.Equal(0x0012, _cpu.Registers.SP); - } - - [Fact] - public void CZ_ShouldCallIfZeroFlagSet() - { - // Arrange - _memory[0x0001] = 0x50; - _memory[0x0002] = 0x00; - - _cpu.Registers.SP = 0x0012; - - _cpu.Flags.Zero = true; - - // Act - DefaultInstructionSet.CZ(_cpu); - - // Assert - Assert.Equal(0x0050, _cpu.Registers.PC); - Assert.Equal(0x0010, _cpu.Registers.SP); - - Assert.Equal(0x03, _memory[0x0010]); - Assert.Equal(0x00, _memory[0x0011]); - } - - [Fact] - public void CZ_ShouldNotCallIfZeroFlagFalse() - { - // Arrange - _memory[0x0001] = 0x50; - _memory[0x0002] = 0x00; - - _cpu.Registers.SP = 0x0012; - - _cpu.Flags.Zero = false; - - // Act - DefaultInstructionSet.CZ(_cpu); - - // Assert - Assert.Equal(0x0003, _cpu.Registers.PC); - Assert.Equal(0x0012, _cpu.Registers.SP); - } - - [Fact] - public void RST_0_ShouldCall0x00() - { - _cpu.Registers.SP = 0x0012; - - // Act - DefaultInstructionSet.RST_0(_cpu); - - // Assert - Assert.Equal(0x0000, _cpu.Registers.PC); - Assert.Equal(0x0010, _cpu.Registers.SP); - - Assert.Equal(0x01, _memory[0x0010]); - Assert.Equal(0x00, _memory[0x0011]); - } - - [Fact] - public void RST_1_ShouldCall0x08() - { - _cpu.Registers.SP = 0x0012; - - // Act - DefaultInstructionSet.RST_1(_cpu); - - // Assert - Assert.Equal(0x0008, _cpu.Registers.PC); - Assert.Equal(0x0010, _cpu.Registers.SP); - - Assert.Equal(0x01, _memory[0x0010]); - Assert.Equal(0x00, _memory[0x0011]); - } - - [Fact] - public void RST_2_ShouldCall0x10() - { - _cpu.Registers.SP = 0x0012; - - // Act - DefaultInstructionSet.RST_2(_cpu); - - // Assert - Assert.Equal(0x0010, _cpu.Registers.PC); - Assert.Equal(0x0010, _cpu.Registers.SP); - - Assert.Equal(0x01, _memory[0x0010]); - Assert.Equal(0x00, _memory[0x0011]); - } - - [Fact] - public void RST_3_ShouldCall0x18() - { - _cpu.Registers.SP = 0x0012; - - // Act - DefaultInstructionSet.RST_3(_cpu); - - // Assert - Assert.Equal(0x0018, _cpu.Registers.PC); - Assert.Equal(0x0010, _cpu.Registers.SP); - - Assert.Equal(0x01, _memory[0x0010]); - Assert.Equal(0x00, _memory[0x0011]); - } - - [Fact] - public void RST_4_ShouldCall0x20() - { - _cpu.Registers.SP = 0x0012; - - // Act - DefaultInstructionSet.RST_4(_cpu); - - // Assert - Assert.Equal(0x0020, _cpu.Registers.PC); - Assert.Equal(0x0010, _cpu.Registers.SP); - - Assert.Equal(0x01, _memory[0x0010]); - Assert.Equal(0x00, _memory[0x0011]); - } - - [Fact] - public void RST_5_ShouldCall0x28() - { - _cpu.Registers.SP = 0x0012; - - // Act - DefaultInstructionSet.RST_5(_cpu); - - // Assert - Assert.Equal(0x0028, _cpu.Registers.PC); - Assert.Equal(0x0010, _cpu.Registers.SP); - - Assert.Equal(0x01, _memory[0x0010]); - Assert.Equal(0x00, _memory[0x0011]); - } - - [Fact] - public void RST_6_ShouldCall0x30() - { - _cpu.Registers.SP = 0x0012; - - // Act - DefaultInstructionSet.RST_6(_cpu); - - // Assert - Assert.Equal(0x0030, _cpu.Registers.PC); - Assert.Equal(0x0010, _cpu.Registers.SP); - - Assert.Equal(0x01, _memory[0x0010]); - Assert.Equal(0x00, _memory[0x0011]); - } - - - [Fact] - public void RST_7_ShouldCall0x38() - { - _cpu.Registers.SP = 0x0012; - - // Act - DefaultInstructionSet.RST_7(_cpu); - - // Assert - Assert.Equal(0x0038, _cpu.Registers.PC); - Assert.Equal(0x0010, _cpu.Registers.SP); - - Assert.Equal(0x01, _memory[0x0010]); - Assert.Equal(0x00, _memory[0x0011]); - } - - [Fact] - public void CNC_ShouldCallIfZeroFlagFalse() - { - // Arrange - _memory[0x0001] = 0x50; - _memory[0x0002] = 0x00; - - _cpu.Registers.SP = 0x0012; - - _cpu.Flags.Carry = false; - - // Act - DefaultInstructionSet.CNC(_cpu); - - // Assert - Assert.Equal(0x0050, _cpu.Registers.PC); - Assert.Equal(0x0010, _cpu.Registers.SP); - - Assert.Equal(0x03, _memory[0x0010]); - Assert.Equal(0x00, _memory[0x0011]); - } - - [Fact] - public void CNC_ShouldNotCallIfZeroFlagSet() - { - // Arrange - _memory[0x0001] = 0x50; - _memory[0x0002] = 0x00; - - _cpu.Registers.SP = 0x0012; - - _cpu.Flags.Carry = true; - - // Act - DefaultInstructionSet.CNC(_cpu); - - // Assert - Assert.Equal(0x0003, _cpu.Registers.PC); - Assert.Equal(0x0012, _cpu.Registers.SP); - } - - [Fact] - public void CC_ShouldCallIfZeroFlagSet() - { - // Arrange - _memory[0x0001] = 0x50; - _memory[0x0002] = 0x00; - - _cpu.Registers.SP = 0x0012; - - _cpu.Flags.Carry = true; - - // Act - DefaultInstructionSet.CC(_cpu); - - // Assert - Assert.Equal(0x0050, _cpu.Registers.PC); - Assert.Equal(0x0010, _cpu.Registers.SP); - - Assert.Equal(0x03, _memory[0x0010]); - Assert.Equal(0x00, _memory[0x0011]); - } - - [Fact] - public void CC_ShouldNotCallIfZeroFlagFalse() - { - // Arrange - _memory[0x0001] = 0x50; - _memory[0x0002] = 0x00; - - _cpu.Registers.SP = 0x0012; - - _cpu.Flags.Carry = false; - - // Act - DefaultInstructionSet.CC(_cpu); - - // Assert - Assert.Equal(0x0003, _cpu.Registers.PC); - Assert.Equal(0x0012, _cpu.Registers.SP); - } - - [Fact] - public void CPO_ShouldNotCallIfParityEven() - { - // Arrange - _memory[0x0001] = 0x50; - _memory[0x0002] = 0x00; - - _cpu.Registers.SP = 0x0012; - - _cpu.Flags.Parity = false; - - // Act - DefaultInstructionSet.CPO(_cpu); - - // Assert - Assert.Equal(0x0050, _cpu.Registers.PC); - Assert.Equal(0x0010, _cpu.Registers.SP); - - Assert.Equal(0x03, _memory[0x0010]); - Assert.Equal(0x00, _memory[0x0011]); - } - - [Fact] - public void CPO_ShouldCallIfParityOdd() - { - // Arrange - _memory[0x0001] = 0x50; - _memory[0x0002] = 0x00; - - _cpu.Registers.SP = 0x0012; - - _cpu.Flags.Parity = true; - - // Act - DefaultInstructionSet.CPO(_cpu); - - // Assert - Assert.Equal(0x0003, _cpu.Registers.PC); - Assert.Equal(0x0012, _cpu.Registers.SP); - } - - [Fact] - public void CPE_ShouldNotCallIfParityEven() - { - // Arrange - _memory[0x0001] = 0x50; - _memory[0x0002] = 0x00; - - _cpu.Registers.SP = 0x0012; - - _cpu.Flags.Parity = true; - - // Act - DefaultInstructionSet.CPE(_cpu); - - // Assert - Assert.Equal(0x0050, _cpu.Registers.PC); - Assert.Equal(0x0010, _cpu.Registers.SP); - - Assert.Equal(0x03, _memory[0x0010]); - Assert.Equal(0x00, _memory[0x0011]); - } - - [Fact] - public void CPE_ShouldNotCallIfParityOdd() - { - // Arrange - _memory[0x0001] = 0x50; - _memory[0x0002] = 0x00; - - _cpu.Registers.SP = 0x0012; - - _cpu.Flags.Parity = false; - - // Act - DefaultInstructionSet.CPE(_cpu); - - // Assert - Assert.Equal(0x0003, _cpu.Registers.PC); - Assert.Equal(0x0012, _cpu.Registers.SP); - } - - [Fact] - public void CP_ShouldNotCallIfSignFlagReset() - { - // Arrange - _memory[0x0001] = 0x50; - _memory[0x0002] = 0x00; - - _cpu.Registers.SP = 0x0012; - - _cpu.Flags.Sign = false; - - // Act - DefaultInstructionSet.CP(_cpu); - - // Assert - Assert.Equal(0x0050, _cpu.Registers.PC); - Assert.Equal(0x0010, _cpu.Registers.SP); - - Assert.Equal(0x03, _memory[0x0010]); - Assert.Equal(0x00, _memory[0x0011]); - } - - [Fact] - public void CP_ShouldCallIfSignFlagReset() - { - // Arrange - _memory[0x0001] = 0x50; - _memory[0x0002] = 0x00; - - _cpu.Registers.SP = 0x0012; - - _cpu.Flags.Sign = true; - - // Act - DefaultInstructionSet.CP(_cpu); - - // Assert - Assert.Equal(0x0003, _cpu.Registers.PC); - Assert.Equal(0x0012, _cpu.Registers.SP); - } - - [Fact] - public void CM_ShouldNotCallIfSignFlagSet() - { - // Arrange - _memory[0x0001] = 0x50; - _memory[0x0002] = 0x00; - - _cpu.Registers.SP = 0x0012; - - _cpu.Flags.Sign = true; - - // Act - DefaultInstructionSet.CM(_cpu); - - // Assert - Assert.Equal(0x0050, _cpu.Registers.PC); - Assert.Equal(0x0010, _cpu.Registers.SP); - - Assert.Equal(0x03, _memory[0x0010]); - Assert.Equal(0x00, _memory[0x0011]); - } - - [Fact] - public void CM_ShouldNotCallIfSignFlagReset() - { - // Arrange - _memory[0x0001] = 0x50; - _memory[0x0002] = 0x00; - - _cpu.Registers.SP = 0x0012; - - _cpu.Flags.Parity = false; - - // Act - DefaultInstructionSet.CPE(_cpu); - - // Assert - Assert.Equal(0x0003, _cpu.Registers.PC); - Assert.Equal(0x0012, _cpu.Registers.SP); - } - } +using Intel8080.Emulator.Instructions; +using Xunit; + +namespace Intel8080.Emulator.Tests.Instructions; + +public class CallInstructionTests +{ + private readonly CPU _cpu; + private readonly IMemory _memory; + + public CallInstructionTests() + { + _memory = new DefaultMemory(0x100); + + _cpu = new CPU(_memory); + + _cpu.Registers.PC = 1; + } + + [Fact] + public void CALL_ShouldCallSubroutine() + { + // Arrange + _memory[0x0001] = 0x50; + _memory[0x0002] = 0x00; + + _cpu.Registers.SP = 0x0012; + + // Act + DefaultInstructionSet.CALL(_cpu); + + // Assert + Assert.Equal(0x0050, _cpu.Registers.PC); + Assert.Equal(0x0010, _cpu.Registers.SP); + + Assert.Equal(0x03, _memory[0x0010]); + Assert.Equal(0x00, _memory[0x0011]); + } + + [Fact] + public void CNZ_ShouldCallIfZeroFlagFalse() + { + // Arrange + _memory[0x0001] = 0x50; + _memory[0x0002] = 0x00; + + _cpu.Registers.SP = 0x0012; + + _cpu.Flags.Zero = false; + + // Act + DefaultInstructionSet.CNZ(_cpu); + + // Assert + Assert.Equal(0x0050, _cpu.Registers.PC); + Assert.Equal(0x0010, _cpu.Registers.SP); + + Assert.Equal(0x03, _memory[0x0010]); + Assert.Equal(0x00, _memory[0x0011]); + } + + [Fact] + public void CNZ_ShouldNotCallIfZeroFlagSet() + { + // Arrange + _memory[0x0001] = 0x50; + _memory[0x0002] = 0x00; + + _cpu.Registers.SP = 0x0012; + + _cpu.Flags.Zero = true; + + // Act + DefaultInstructionSet.CNZ(_cpu); + + // Assert + Assert.Equal(0x0003, _cpu.Registers.PC); + Assert.Equal(0x0012, _cpu.Registers.SP); + } + + [Fact] + public void CZ_ShouldCallIfZeroFlagSet() + { + // Arrange + _memory[0x0001] = 0x50; + _memory[0x0002] = 0x00; + + _cpu.Registers.SP = 0x0012; + + _cpu.Flags.Zero = true; + + // Act + DefaultInstructionSet.CZ(_cpu); + + // Assert + Assert.Equal(0x0050, _cpu.Registers.PC); + Assert.Equal(0x0010, _cpu.Registers.SP); + + Assert.Equal(0x03, _memory[0x0010]); + Assert.Equal(0x00, _memory[0x0011]); + } + + [Fact] + public void CZ_ShouldNotCallIfZeroFlagFalse() + { + // Arrange + _memory[0x0001] = 0x50; + _memory[0x0002] = 0x00; + + _cpu.Registers.SP = 0x0012; + + _cpu.Flags.Zero = false; + + // Act + DefaultInstructionSet.CZ(_cpu); + + // Assert + Assert.Equal(0x0003, _cpu.Registers.PC); + Assert.Equal(0x0012, _cpu.Registers.SP); + } + + [Fact] + public void RST_0_ShouldCall0x00() + { + _cpu.Registers.SP = 0x0012; + + // Act + DefaultInstructionSet.RST_0(_cpu); + + // Assert + Assert.Equal(0x0000, _cpu.Registers.PC); + Assert.Equal(0x0010, _cpu.Registers.SP); + + Assert.Equal(0x01, _memory[0x0010]); + Assert.Equal(0x00, _memory[0x0011]); + } + + [Fact] + public void RST_1_ShouldCall0x08() + { + _cpu.Registers.SP = 0x0012; + + // Act + DefaultInstructionSet.RST_1(_cpu); + + // Assert + Assert.Equal(0x0008, _cpu.Registers.PC); + Assert.Equal(0x0010, _cpu.Registers.SP); + + Assert.Equal(0x01, _memory[0x0010]); + Assert.Equal(0x00, _memory[0x0011]); + } + + [Fact] + public void RST_2_ShouldCall0x10() + { + _cpu.Registers.SP = 0x0012; + + // Act + DefaultInstructionSet.RST_2(_cpu); + + // Assert + Assert.Equal(0x0010, _cpu.Registers.PC); + Assert.Equal(0x0010, _cpu.Registers.SP); + + Assert.Equal(0x01, _memory[0x0010]); + Assert.Equal(0x00, _memory[0x0011]); + } + + [Fact] + public void RST_3_ShouldCall0x18() + { + _cpu.Registers.SP = 0x0012; + + // Act + DefaultInstructionSet.RST_3(_cpu); + + // Assert + Assert.Equal(0x0018, _cpu.Registers.PC); + Assert.Equal(0x0010, _cpu.Registers.SP); + + Assert.Equal(0x01, _memory[0x0010]); + Assert.Equal(0x00, _memory[0x0011]); + } + + [Fact] + public void RST_4_ShouldCall0x20() + { + _cpu.Registers.SP = 0x0012; + + // Act + DefaultInstructionSet.RST_4(_cpu); + + // Assert + Assert.Equal(0x0020, _cpu.Registers.PC); + Assert.Equal(0x0010, _cpu.Registers.SP); + + Assert.Equal(0x01, _memory[0x0010]); + Assert.Equal(0x00, _memory[0x0011]); + } + + [Fact] + public void RST_5_ShouldCall0x28() + { + _cpu.Registers.SP = 0x0012; + + // Act + DefaultInstructionSet.RST_5(_cpu); + + // Assert + Assert.Equal(0x0028, _cpu.Registers.PC); + Assert.Equal(0x0010, _cpu.Registers.SP); + + Assert.Equal(0x01, _memory[0x0010]); + Assert.Equal(0x00, _memory[0x0011]); + } + + [Fact] + public void RST_6_ShouldCall0x30() + { + _cpu.Registers.SP = 0x0012; + + // Act + DefaultInstructionSet.RST_6(_cpu); + + // Assert + Assert.Equal(0x0030, _cpu.Registers.PC); + Assert.Equal(0x0010, _cpu.Registers.SP); + + Assert.Equal(0x01, _memory[0x0010]); + Assert.Equal(0x00, _memory[0x0011]); + } + + + [Fact] + public void RST_7_ShouldCall0x38() + { + _cpu.Registers.SP = 0x0012; + + // Act + DefaultInstructionSet.RST_7(_cpu); + + // Assert + Assert.Equal(0x0038, _cpu.Registers.PC); + Assert.Equal(0x0010, _cpu.Registers.SP); + + Assert.Equal(0x01, _memory[0x0010]); + Assert.Equal(0x00, _memory[0x0011]); + } + + [Fact] + public void CNC_ShouldCallIfZeroFlagFalse() + { + // Arrange + _memory[0x0001] = 0x50; + _memory[0x0002] = 0x00; + + _cpu.Registers.SP = 0x0012; + + _cpu.Flags.Carry = false; + + // Act + DefaultInstructionSet.CNC(_cpu); + + // Assert + Assert.Equal(0x0050, _cpu.Registers.PC); + Assert.Equal(0x0010, _cpu.Registers.SP); + + Assert.Equal(0x03, _memory[0x0010]); + Assert.Equal(0x00, _memory[0x0011]); + } + + [Fact] + public void CNC_ShouldNotCallIfZeroFlagSet() + { + // Arrange + _memory[0x0001] = 0x50; + _memory[0x0002] = 0x00; + + _cpu.Registers.SP = 0x0012; + + _cpu.Flags.Carry = true; + + // Act + DefaultInstructionSet.CNC(_cpu); + + // Assert + Assert.Equal(0x0003, _cpu.Registers.PC); + Assert.Equal(0x0012, _cpu.Registers.SP); + } + + [Fact] + public void CC_ShouldCallIfZeroFlagSet() + { + // Arrange + _memory[0x0001] = 0x50; + _memory[0x0002] = 0x00; + + _cpu.Registers.SP = 0x0012; + + _cpu.Flags.Carry = true; + + // Act + DefaultInstructionSet.CC(_cpu); + + // Assert + Assert.Equal(0x0050, _cpu.Registers.PC); + Assert.Equal(0x0010, _cpu.Registers.SP); + + Assert.Equal(0x03, _memory[0x0010]); + Assert.Equal(0x00, _memory[0x0011]); + } + + [Fact] + public void CC_ShouldNotCallIfZeroFlagFalse() + { + // Arrange + _memory[0x0001] = 0x50; + _memory[0x0002] = 0x00; + + _cpu.Registers.SP = 0x0012; + + _cpu.Flags.Carry = false; + + // Act + DefaultInstructionSet.CC(_cpu); + + // Assert + Assert.Equal(0x0003, _cpu.Registers.PC); + Assert.Equal(0x0012, _cpu.Registers.SP); + } + + [Fact] + public void CPO_ShouldNotCallIfParityEven() + { + // Arrange + _memory[0x0001] = 0x50; + _memory[0x0002] = 0x00; + + _cpu.Registers.SP = 0x0012; + + _cpu.Flags.Parity = false; + + // Act + DefaultInstructionSet.CPO(_cpu); + + // Assert + Assert.Equal(0x0050, _cpu.Registers.PC); + Assert.Equal(0x0010, _cpu.Registers.SP); + + Assert.Equal(0x03, _memory[0x0010]); + Assert.Equal(0x00, _memory[0x0011]); + } + + [Fact] + public void CPO_ShouldCallIfParityOdd() + { + // Arrange + _memory[0x0001] = 0x50; + _memory[0x0002] = 0x00; + + _cpu.Registers.SP = 0x0012; + + _cpu.Flags.Parity = true; + + // Act + DefaultInstructionSet.CPO(_cpu); + + // Assert + Assert.Equal(0x0003, _cpu.Registers.PC); + Assert.Equal(0x0012, _cpu.Registers.SP); + } + + [Fact] + public void CPE_ShouldNotCallIfParityEven() + { + // Arrange + _memory[0x0001] = 0x50; + _memory[0x0002] = 0x00; + + _cpu.Registers.SP = 0x0012; + + _cpu.Flags.Parity = true; + + // Act + DefaultInstructionSet.CPE(_cpu); + + // Assert + Assert.Equal(0x0050, _cpu.Registers.PC); + Assert.Equal(0x0010, _cpu.Registers.SP); + + Assert.Equal(0x03, _memory[0x0010]); + Assert.Equal(0x00, _memory[0x0011]); + } + + [Fact] + public void CPE_ShouldNotCallIfParityOdd() + { + // Arrange + _memory[0x0001] = 0x50; + _memory[0x0002] = 0x00; + + _cpu.Registers.SP = 0x0012; + + _cpu.Flags.Parity = false; + + // Act + DefaultInstructionSet.CPE(_cpu); + + // Assert + Assert.Equal(0x0003, _cpu.Registers.PC); + Assert.Equal(0x0012, _cpu.Registers.SP); + } + + [Fact] + public void CP_ShouldNotCallIfSignFlagReset() + { + // Arrange + _memory[0x0001] = 0x50; + _memory[0x0002] = 0x00; + + _cpu.Registers.SP = 0x0012; + + _cpu.Flags.Sign = false; + + // Act + DefaultInstructionSet.CP(_cpu); + + // Assert + Assert.Equal(0x0050, _cpu.Registers.PC); + Assert.Equal(0x0010, _cpu.Registers.SP); + + Assert.Equal(0x03, _memory[0x0010]); + Assert.Equal(0x00, _memory[0x0011]); + } + + [Fact] + public void CP_ShouldCallIfSignFlagReset() + { + // Arrange + _memory[0x0001] = 0x50; + _memory[0x0002] = 0x00; + + _cpu.Registers.SP = 0x0012; + + _cpu.Flags.Sign = true; + + // Act + DefaultInstructionSet.CP(_cpu); + + // Assert + Assert.Equal(0x0003, _cpu.Registers.PC); + Assert.Equal(0x0012, _cpu.Registers.SP); + } + + [Fact] + public void CM_ShouldNotCallIfSignFlagSet() + { + // Arrange + _memory[0x0001] = 0x50; + _memory[0x0002] = 0x00; + + _cpu.Registers.SP = 0x0012; + + _cpu.Flags.Sign = true; + + // Act + DefaultInstructionSet.CM(_cpu); + + // Assert + Assert.Equal(0x0050, _cpu.Registers.PC); + Assert.Equal(0x0010, _cpu.Registers.SP); + + Assert.Equal(0x03, _memory[0x0010]); + Assert.Equal(0x00, _memory[0x0011]); + } + + [Fact] + public void CM_ShouldNotCallIfSignFlagReset() + { + // Arrange + _memory[0x0001] = 0x50; + _memory[0x0002] = 0x00; + + _cpu.Registers.SP = 0x0012; + + _cpu.Flags.Parity = false; + + // Act + DefaultInstructionSet.CPE(_cpu); + + // Assert + Assert.Equal(0x0003, _cpu.Registers.PC); + Assert.Equal(0x0012, _cpu.Registers.SP); + } } \ No newline at end of file diff --git a/Intel8080.Emulator.Tests/Instructions/CarryBitInstructionTests.cs b/Intel8080.Emulator.Tests/Instructions/CarryBitInstructionTests.cs index 865ce5a..f4756d8 100644 --- a/Intel8080.Emulator.Tests/Instructions/CarryBitInstructionTests.cs +++ b/Intel8080.Emulator.Tests/Instructions/CarryBitInstructionTests.cs @@ -1,90 +1,89 @@ -using Intel8080.Emulator.Instructions; -using Moq; -using Xunit; - -namespace Intel8080.Emulator.Tests.Instructions -{ - public class CarryBitInstructionTests - { - private readonly CPU _cpu; - private readonly Mock _memory; - - public CarryBitInstructionTests() - { - _memory = new Mock(); - - _cpu = new CPU(_memory.Object); - } - - [Fact] - public void NOP_ShouldAffectOnlyPCAndCycles() - { - // Act - DefaultInstructionSet.NOP(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void STC_ShouldSetCarry() - { - // Arrange - _cpu.Flags.Carry = false; - - // Act - DefaultInstructionSet.STC(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Carry); - } - - [Fact] - public void CMC_ShouldSetCarryIfCarryIsFalse() - { - // Arrange - _cpu.Flags.Carry = false; - - // Act - DefaultInstructionSet.CMC(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Carry); - } - - [Fact] - public void CMC_ShouldUnsetCarryIfCarryIsTrue() - { - // Arrange - _cpu.Flags.Carry = true; - - // Act - DefaultInstructionSet.CMC(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Carry); - } - } +using Intel8080.Emulator.Instructions; +using Moq; +using Xunit; + +namespace Intel8080.Emulator.Tests.Instructions; + +public class CarryBitInstructionTests +{ + private readonly CPU _cpu; + private readonly Mock _memory; + + public CarryBitInstructionTests() + { + _memory = new Mock(); + + _cpu = new CPU(_memory.Object); + } + + [Fact] + public void NOP_ShouldAffectOnlyPCAndCycles() + { + // Act + DefaultInstructionSet.NOP(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void STC_ShouldSetCarry() + { + // Arrange + _cpu.Flags.Carry = false; + + // Act + DefaultInstructionSet.STC(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Carry); + } + + [Fact] + public void CMC_ShouldSetCarryIfCarryIsFalse() + { + // Arrange + _cpu.Flags.Carry = false; + + // Act + DefaultInstructionSet.CMC(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Carry); + } + + [Fact] + public void CMC_ShouldUnsetCarryIfCarryIsTrue() + { + // Arrange + _cpu.Flags.Carry = true; + + // Act + DefaultInstructionSet.CMC(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Carry); + } } \ No newline at end of file diff --git a/Intel8080.Emulator.Tests/Instructions/ControlInstructionTests.cs b/Intel8080.Emulator.Tests/Instructions/ControlInstructionTests.cs index 4d2ef6d..748ef03 100644 --- a/Intel8080.Emulator.Tests/Instructions/ControlInstructionTests.cs +++ b/Intel8080.Emulator.Tests/Instructions/ControlInstructionTests.cs @@ -1,102 +1,101 @@ -using Intel8080.Emulator.Instructions; -using Intel8080.Emulator.IO; -using Moq; -using Xunit; - -namespace Intel8080.Emulator.Tests.Instructions -{ - public class ControlInstructions - { - private readonly CPU _cpu; - private readonly Mock _memory; - - public ControlInstructions() - { - _memory = new Mock(); - - _cpu = new CPU(_memory.Object); - } - - [Fact] - public void NOP_ShouldAffectOnlyPCAndCycles() - { - // Act - DefaultInstructionSet.NOP(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void HLT_ShouldHaltCPU() - { - // Act - DefaultInstructionSet.HLT(_cpu); - - // Assert - Assert.True(_cpu.Halted); - } - - [Fact] - public void IN_ShouldReadByteFromPort() - { - // Arrange - _memory.Setup(x => x[0x0000]).Returns(0x00); - - var inputDevice = new Mock(); - - _cpu.IOController.AddDevice(inputDevice.Object, 0x00); - - inputDevice.Setup(x => x.Read()).Returns(0x48); - - // Act - DefaultInstructionSet.IN(_cpu); - - // Assert - Assert.Equal(0x48, _cpu.Registers.A); - } - - [Fact] - public void OUT_ShouldWriteByteToPort() - { - // Arrange - _cpu.Registers.A = 0x48; - - _memory.Setup(x => x[0x0000]).Returns(0x00); - - var outputDevice = new Mock(); - - _cpu.IOController.AddDevice(outputDevice.Object, 0x00); - - // Act - DefaultInstructionSet.OUT(_cpu); - - // Assert - outputDevice.Verify(x => x.Write(_cpu.Registers.A), Times.Once); - } - - [Fact] - public void DI_ShouldDisableInterupts() - { - // Act - DefaultInstructionSet.DI(_cpu); - - // Assert - Assert.False(_cpu.InterruptEnabled); - } - - [Fact] - public void EI_ShouldEnableInterupts() - { - // Act - DefaultInstructionSet.EI(_cpu); - - // Assert - Assert.True(_cpu.InterruptEnabled); - } - } +using Intel8080.Emulator.Instructions; +using Intel8080.Emulator.IO; +using Moq; +using Xunit; + +namespace Intel8080.Emulator.Tests.Instructions; + +public class ControlInstructions +{ + private readonly CPU _cpu; + private readonly Mock _memory; + + public ControlInstructions() + { + _memory = new Mock(); + + _cpu = new CPU(_memory.Object); + } + + [Fact] + public void NOP_ShouldAffectOnlyPCAndCycles() + { + // Act + DefaultInstructionSet.NOP(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void HLT_ShouldHaltCPU() + { + // Act + DefaultInstructionSet.HLT(_cpu); + + // Assert + Assert.True(_cpu.Halted); + } + + [Fact] + public void IN_ShouldReadByteFromPort() + { + // Arrange + _memory.Setup(x => x[0x0000]).Returns(0x00); + + var inputDevice = new Mock(); + + _cpu.IOController.AddDevice(inputDevice.Object, 0x00); + + inputDevice.Setup(x => x.Read()).Returns(0x48); + + // Act + DefaultInstructionSet.IN(_cpu); + + // Assert + Assert.Equal(0x48, _cpu.Registers.A); + } + + [Fact] + public void OUT_ShouldWriteByteToPort() + { + // Arrange + _cpu.Registers.A = 0x48; + + _memory.Setup(x => x[0x0000]).Returns(0x00); + + var outputDevice = new Mock(); + + _cpu.IOController.AddDevice(outputDevice.Object, 0x00); + + // Act + DefaultInstructionSet.OUT(_cpu); + + // Assert + outputDevice.Verify(x => x.Write(_cpu.Registers.A), Times.Once); + } + + [Fact] + public void DI_ShouldDisableInterupts() + { + // Act + DefaultInstructionSet.DI(_cpu); + + // Assert + Assert.False(_cpu.InterruptEnabled); + } + + [Fact] + public void EI_ShouldEnableInterupts() + { + // Act + DefaultInstructionSet.EI(_cpu); + + // Assert + Assert.True(_cpu.InterruptEnabled); + } } \ No newline at end of file diff --git a/Intel8080.Emulator.Tests/Instructions/DataTransferInstructionTests.cs b/Intel8080.Emulator.Tests/Instructions/DataTransferInstructionTests.cs index f58848c..dbae29a 100644 --- a/Intel8080.Emulator.Tests/Instructions/DataTransferInstructionTests.cs +++ b/Intel8080.Emulator.Tests/Instructions/DataTransferInstructionTests.cs @@ -1,1226 +1,1224 @@ -using Intel8080.Emulator.Instructions; -using Moq; -using Xunit; - -namespace Intel8080.Emulator.Tests.Instructions -{ - public class DataTransferInstructionTests - { - private readonly CPU _cpu; - private readonly IMemory _memory; - - public DataTransferInstructionTests() - { - _memory = new DefaultMemory(0x100); - - _cpu = new CPU(_memory); - } - - [Fact] - public void STAX_B_StoreAccumulator_LocationBC() - { - // Arrange - _cpu.Registers.A = 0x42; - _cpu.Registers.BC = 0x0010; - - // Act - DefaultInstructionSet.STAX_B(_cpu); - - // Assert - Assert.Equal(0x0042, _memory[0x0010]); - - Assert.Equal(0x42, _cpu.Registers.A); - Assert.Equal(0x0010, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void STAX_D_StoreAccumulator_LocationDE() - { - // Arrange - _cpu.Registers.A = 0x42; - _cpu.Registers.DE = 0x0010; - - // Act - DefaultInstructionSet.STAX_D(_cpu); - - // Assert - Assert.Equal(0x0042, _memory[0x0010]); - - Assert.Equal(0x42, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0010, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void LDAX_B_LoadAcculmulator_LocationBC() - { - // Arrange - _memory[0x0010] = 0x0042; - _cpu.Registers.BC = 0x0010; - - // Act - DefaultInstructionSet.LDAX_B(_cpu); - - // Assert - Assert.Equal(0x42, _cpu.Registers.A); - Assert.Equal(0x0010, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void LDAX_D_LoadAcculmulator_LocationBC() - { - // Arrange - _memory[0x0010] = 0x0042; - _cpu.Registers.DE = 0x0010; - - // Act - DefaultInstructionSet.LDAX_D(_cpu); - - // Assert - Assert.Equal(0x42, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0010, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MOV_B_B_ShouldStoreRegBInRegB() - { - // Arrange - _cpu.Registers.B = 0xFF; - - // Act - DefaultInstructionSet.MOV_B_B(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0xFF00, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MOV_B_C_ShouldStoreRegCInRegB() - { - // Arrange - _cpu.Registers.C = 0xFF; - - // Act - DefaultInstructionSet.MOV_B_C(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0xFFFF, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MOV_B_D_ShouldStoreRegDInRegB() - { - // Arrange - _cpu.Registers.D = 0xFF; - - // Act - DefaultInstructionSet.MOV_B_D(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0xFF00, _cpu.Registers.BC); - Assert.Equal(0xFF00, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MOV_B_E_ShouldStoreRegEInRegB() - { - // Arrange - _cpu.Registers.E = 0xFF; - - // Act - DefaultInstructionSet.MOV_B_E(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0xFF00, _cpu.Registers.BC); - Assert.Equal(0x00FF, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MOV_B_H_ShouldStoreRegHInRegB() - { - // Arrange - _cpu.Registers.H = 0xFF; - - // Act - DefaultInstructionSet.MOV_B_H(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0xFF00, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0xFF00, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MOV_B_L_ShouldStoreRegLInRegB() - { - // Arrange - _cpu.Registers.L = 0xFF; - - // Act - DefaultInstructionSet.MOV_B_L(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0xFF00, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x00FF, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - - [Fact] - public void MOV_B_M_ShouldStoreMemoryByteInRegB() - { - // Arrange - _cpu.Registers.H = 0x00; - _cpu.Registers.L = 0x10; - - _cpu.Memory[0x0010] = 0xFF; - - // Act - DefaultInstructionSet.MOV_B_M(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0xFF00, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0010, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.Equal(0xFF, _cpu.Memory[0x0010]); - } - - [Fact] - public void MOV_B_A_ShouldStoreAccumulatorInRegB() - { - // Arrange - _cpu.Registers.A = 0xFF; - - // Act - DefaultInstructionSet.MOV_B_A(_cpu); - - // Assert - Assert.Equal(0xFF, _cpu.Registers.A); - Assert.Equal(0xFF00, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MOV_C_B_ShouldStoreRegBInRegC() - { - // Arrange - _cpu.Registers.B = 0xFF; - - // Act - DefaultInstructionSet.MOV_C_B(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0xFFFF, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MOV_C_C_ShouldStoreRegCInRegC() - { - // Arrange - _cpu.Registers.C = 0xFF; - - // Act - DefaultInstructionSet.MOV_C_C(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x00FF, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MOV_C_D_ShouldStoreRegDInRegC() - { - // Arrange - _cpu.Registers.D = 0xFF; - - // Act - DefaultInstructionSet.MOV_C_D(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x00FF, _cpu.Registers.BC); - Assert.Equal(0xFF00, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MOV_C_E_ShouldStoreRegEInRegC() - { - // Arrange - _cpu.Registers.E = 0xFF; - - // Act - DefaultInstructionSet.MOV_C_E(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x00FF, _cpu.Registers.BC); - Assert.Equal(0x00FF, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MOV_C_H_ShouldStoreRegHInRegC() - { - // Arrange - _cpu.Registers.H = 0xFF; - - // Act - DefaultInstructionSet.MOV_C_H(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x00FF, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0xFF00, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MOV_C_L_ShouldStoreRegLInRegC() - { - // Arrange - _cpu.Registers.L = 0xFF; - - // Act - DefaultInstructionSet.MOV_C_L(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x00FF, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x00FF, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MOV_C_M_ShouldStoreMemoryByteInRegC() - { - // Arrange - _cpu.Registers.H = 0x00; - _cpu.Registers.L = 0x10; - - _cpu.Memory[0x0010] = 0xFF; - - // Act - DefaultInstructionSet.MOV_C_M(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x00FF, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0010, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.Equal(0xFF, _cpu.Memory[0x0010]); - } - - [Fact] - public void MOV_C_A_ShouldStoreAccumulatorInRegC() - { - // Arrange - _cpu.Registers.A = 0xFF; - - // Act - DefaultInstructionSet.MOV_C_A(_cpu); - - // Assert - Assert.Equal(0xFF, _cpu.Registers.A); - Assert.Equal(0x00FF, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MOV_D_B_ShouldStoreRegBInRegD() - { - // Arrange - _cpu.Registers.B = 0xFF; - - // Act - DefaultInstructionSet.MOV_D_B(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0xFF00, _cpu.Registers.BC); - Assert.Equal(0xFF00, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MOV_D_C_ShouldStoreRegCInRegD() - { - // Arrange - _cpu.Registers.C = 0xFF; - - // Act - DefaultInstructionSet.MOV_D_C(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x00FF, _cpu.Registers.BC); - Assert.Equal(0xFF00, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MOV_D_D_ShouldStoreRegDInRegD() - { - // Arrange - _cpu.Registers.D = 0xFF; - - // Act - DefaultInstructionSet.MOV_D_D(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0xFF00, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MOV_D_E_ShouldStoreRegEInRegD() - { - // Arrange - _cpu.Registers.E = 0xFF; - - // Act - DefaultInstructionSet.MOV_D_E(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0xFFFF, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MOV_D_H_ShouldStoreRegHInRegD() - { - // Arrange - _cpu.Registers.H = 0xFF; - - // Act - DefaultInstructionSet.MOV_D_H(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0xFF00, _cpu.Registers.DE); - Assert.Equal(0xFF00, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MOV_D_L_ShouldStoreRegLInRegD() - { - // Arrange - _cpu.Registers.L = 0xFF; - - // Act - DefaultInstructionSet.MOV_D_L(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0xFF00, _cpu.Registers.DE); - Assert.Equal(0x00FF, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - - [Fact] - public void MOV_D_M_ShouldStoreMemoryByteInRegD() - { - // Arrange - _cpu.Registers.H = 0x00; - _cpu.Registers.L = 0x10; - - _cpu.Memory[0x0010] = 0xFF; - - // Act - DefaultInstructionSet.MOV_D_M(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0xFF00, _cpu.Registers.DE); - Assert.Equal(0x0010, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.Equal(0xFF, _cpu.Memory[0x0010]); - } - - [Fact] - public void MOV_D_A_ShouldStoreAccumulatorInRegD() - { - // Arrange - _cpu.Registers.A = 0xFF; - - // Act - DefaultInstructionSet.MOV_D_A(_cpu); - - // Assert - Assert.Equal(0xFF, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0xFF00, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MOV_E_B_ShouldStoreRegBInRegE() - { - // Arrange - _cpu.Registers.B = 0xFF; - - // Act - DefaultInstructionSet.MOV_E_B(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0xFF00, _cpu.Registers.BC); - Assert.Equal(0x00FF, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MOV_E_C_ShouldStoreRegCInRegE() - { - // Arrange - _cpu.Registers.C = 0xFF; - - // Act - DefaultInstructionSet.MOV_E_C(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x00FF, _cpu.Registers.BC); - Assert.Equal(0x00FF, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MOV_E_D_ShouldStoreRegDInRegE() - { - // Arrange - _cpu.Registers.D = 0xFF; - - // Act - DefaultInstructionSet.MOV_E_D(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0xFFFF, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MOV_E_E_ShouldStoreRegEInRegE() - { - // Arrange - _cpu.Registers.E = 0xFF; - - // Act - DefaultInstructionSet.MOV_E_E(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x00FF, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MOV_E_H_ShouldStoreRegHInRegE() - { - // Arrange - _cpu.Registers.H = 0xFF; - - // Act - DefaultInstructionSet.MOV_E_H(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x00FF, _cpu.Registers.DE); - Assert.Equal(0xFF00, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MOV_E_L_ShouldStoreRegLInRegE() - { - // Arrange - _cpu.Registers.L = 0xFF; - - // Act - DefaultInstructionSet.MOV_E_L(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x00FF, _cpu.Registers.DE); - Assert.Equal(0x00FF, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - - [Fact] - public void MOV_E_M_ShouldStoreMemoryByteInRegE() - { - // Arrange - _cpu.Registers.H = 0x00; - _cpu.Registers.L = 0x10; - - _cpu.Memory[0x0010] = 0xFF; - - // Act - DefaultInstructionSet.MOV_E_M(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x00FF, _cpu.Registers.DE); - Assert.Equal(0x0010, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.Equal(0xFF, _cpu.Memory[0x0010]); - } - - [Fact] - public void MOV_E_A_ShouldStoreAccumulatorInRegE() - { - // Arrange - _cpu.Registers.A = 0xFF; - - // Act - DefaultInstructionSet.MOV_E_A(_cpu); - - // Assert - Assert.Equal(0xFF, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x00FF, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MOV_H_B_ShouldStoreRegBInRegH() - { - // Arrange - _cpu.Registers.B = 0xFF; - - // Act - DefaultInstructionSet.MOV_H_B(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0xFF00, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0xFF00, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MOV_H_C_ShouldStoreRegCInRegH() - { - // Arrange - _cpu.Registers.C = 0xFF; - - // Act - DefaultInstructionSet.MOV_H_C(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x00FF, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0xFF00, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MOV_H_D_ShouldStoreRegDInRegH() - { - // Arrange - _cpu.Registers.D = 0xFF; - - // Act - DefaultInstructionSet.MOV_H_D(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0xFF00, _cpu.Registers.DE); - Assert.Equal(0xFF00, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MOV_H_E_ShouldStoreRegEInRegH() - { - // Arrange - _cpu.Registers.E = 0xFF; - - // Act - DefaultInstructionSet.MOV_H_E(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x00FF, _cpu.Registers.DE); - Assert.Equal(0xFF00, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MOV_H_H_ShouldStoreRegHInRegH() - { - // Arrange - _cpu.Registers.H = 0xFF; - - // Act - DefaultInstructionSet.MOV_H_H(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0xFF00, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MOV_H_L_ShouldStoreRegLInRegH() - { - // Arrange - _cpu.Registers.L = 0xFF; - - // Act - DefaultInstructionSet.MOV_H_L(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0xFFFF, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - - [Fact] - public void MOV_H_M_ShouldStoreMemoryByteInRegH() - { - // Arrange - _cpu.Registers.H = 0x00; - _cpu.Registers.L = 0x10; - - _cpu.Memory[0x0010] = 0xFF; - - // Act - DefaultInstructionSet.MOV_H_M(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0xFF10, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.Equal(0xFF, _cpu.Memory[0x0010]); - } - - [Fact] - public void MOV_H_A_ShouldStoreAccumulatorInRegH() - { - // Arrange - _cpu.Registers.A = 0xFF; - - // Act - DefaultInstructionSet.MOV_H_A(_cpu); - - // Assert - Assert.Equal(0xFF, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0xFF00, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MOV_L_B_ShouldStoreRegBInRegL() - { - // Arrange - _cpu.Registers.B = 0xFF; - - // Act - DefaultInstructionSet.MOV_L_B(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0xFF00, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x00FF, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MOV_L_C_ShouldStoreRegCInRegL() - { - // Arrange - _cpu.Registers.C = 0xFF; - - // Act - DefaultInstructionSet.MOV_L_C(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x00FF, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x00FF, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MOV_L_D_ShouldStoreRegDInRegL() - { - // Arrange - _cpu.Registers.D = 0xFF; - - // Act - DefaultInstructionSet.MOV_L_D(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0xFF00, _cpu.Registers.DE); - Assert.Equal(0x00FF, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MOV_L_E_ShouldStoreRegEInRegL() - { - // Arrange - _cpu.Registers.E = 0xFF; - - // Act - DefaultInstructionSet.MOV_L_E(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x00FF, _cpu.Registers.DE); - Assert.Equal(0x00FF, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MOV_L_H_ShouldStoreRegHInRegL() - { - // Arrange - _cpu.Registers.H = 0xFF; - - // Act - DefaultInstructionSet.MOV_L_H(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0xFFFF, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MOV_L_L_ShouldStoreRegLInRegL() - { - // Arrange - _cpu.Registers.L = 0xFF; - - // Act - DefaultInstructionSet.MOV_L_L(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x00FF, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - - [Fact] - public void MOV_L_M_ShouldStoreMemoryByteInRegL() - { - // Arrange - _cpu.Registers.H = 0x00; - _cpu.Registers.L = 0x10; - - _cpu.Memory[0x0010] = 0xFF; - - // Act - DefaultInstructionSet.MOV_L_M(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x00FF, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.Equal(0xFF, _cpu.Memory[0x0010]); - } - - [Fact] - public void MOV_L_A_ShouldStoreAccumulatorInRegL() - { - // Arrange - _cpu.Registers.A = 0xFF; - - // Act - DefaultInstructionSet.MOV_L_A(_cpu); - - // Assert - Assert.Equal(0xFF, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x00FF, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MOV_M_B_ShouldStoreRegBInMemoryLocation() - { - // Arrange - _cpu.Registers.B = 0xFF; - _cpu.Registers.HL = 0x0010; - - // Act - DefaultInstructionSet.MOV_M_B(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0xFF00, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0010, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.Equal(0xFF, _cpu.Memory[0x0010]); - } - - [Fact] - public void MOV_M_C_ShouldStoreRegCInMemoryLocation() - { - // Arrange - _cpu.Registers.C = 0xFF; - _cpu.Registers.HL = 0x0010; - - // Act - DefaultInstructionSet.MOV_M_C(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x00FF, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0010, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.Equal(0xFF, _cpu.Memory[0x0010]); - } - - [Fact] - public void MOV_M_D_ShouldStoreRegDInMemoryLocation() - { - // Arrange - _cpu.Registers.D = 0xFF; - _cpu.Registers.HL = 0x0010; - - // Act - DefaultInstructionSet.MOV_M_D(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0xFF00, _cpu.Registers.DE); - Assert.Equal(0x0010, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.Equal(0xFF, _cpu.Memory[0x0010]); - } - - [Fact] - public void MOV_M_E_ShouldStoreRegEInMemoryLocation() - { - // Arrange - _cpu.Registers.E = 0xFF; - _cpu.Registers.HL = 0x0010; - - // Act - DefaultInstructionSet.MOV_M_E(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x00FF, _cpu.Registers.DE); - Assert.Equal(0x0010, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.Equal(0xFF, _cpu.Memory[0x0010]); - } - - [Fact] - public void MOV_M_H_ShouldStoreRegHInMemoryLocation() - { - // Arrange - _cpu.Registers.HL = 0x0010; - - // Act - DefaultInstructionSet.MOV_M_H(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0010, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.Equal(0x00, _cpu.Memory[0x0010]); - } - - [Fact] - public void MOV_M_L_ShouldStoreRegLInMemoryLocation() - { - // Arrange - _cpu.Registers.HL = 0x0010; - - // Act - DefaultInstructionSet.MOV_M_L(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0010, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.Equal(0x10, _cpu.Memory[0x0010]); - } - - [Fact] - public void MOV_M_A_ShouldStoreAccumulatorInMemoryLocation() - { - // Arrange - _cpu.Registers.A = 0xFF; - _cpu.Registers.HL = 0x0010; - - // Act - DefaultInstructionSet.MOV_M_A(_cpu); - - // Assert - Assert.Equal(0xFF, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0010, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.Equal(0xFF, _cpu.Memory[0x0010]); - } - - [Fact] - public void MOV_A_B_ShouldStoreRegBInAccumulator() - { - // Arrange - _cpu.Registers.B = 0xFF; - - // Act - DefaultInstructionSet.MOV_A_B(_cpu); - - // Assert - Assert.Equal(0xFF, _cpu.Registers.A); - Assert.Equal(0xFF00, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MOV_A_C_ShouldStoreRegCInAccumulator() - { - // Arrange - _cpu.Registers.C = 0xFF; - - // Act - DefaultInstructionSet.MOV_A_C(_cpu); - - // Assert - Assert.Equal(0xFF, _cpu.Registers.A); - Assert.Equal(0x00FF, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MOV_A_D_ShouldStoreRegDInAccumulator() - { - // Arrange - _cpu.Registers.D = 0xFF; - - // Act - DefaultInstructionSet.MOV_A_D(_cpu); - - // Assert - Assert.Equal(0xFF, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0xFF00, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MOV_A_E_ShouldStoreRegEInAccumulator() - { - // Arrange - _cpu.Registers.E = 0xFF; - - // Act - DefaultInstructionSet.MOV_A_E(_cpu); - - // Assert - Assert.Equal(0xFF, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x00FF, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MOV_A_H_ShouldStoreRegHInAccumulator() - { - // Arrange - _cpu.Registers.H = 0xFF; - - // Act - DefaultInstructionSet.MOV_A_H(_cpu); - - // Assert - Assert.Equal(0xFF, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0xFF00, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MOV_A_L_ShouldStoreRegLInAccumulator() - { - // Arrange - _cpu.Registers.L = 0xFF; - - // Act - DefaultInstructionSet.MOV_A_L(_cpu); - - // Assert - Assert.Equal(0xFF, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x00FF, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - - [Fact] - public void MOV_A_M_ShouldStoreMemoryByteInAccumulator() - { - // Arrange - _cpu.Registers.H = 0x00; - _cpu.Registers.L = 0x10; - - _cpu.Memory[0x0010] = 0xFF; - - // Act - DefaultInstructionSet.MOV_A_M(_cpu); - - // Assert - Assert.Equal(0xFF, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0010, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.Equal(0xFF, _cpu.Memory[0x0010]); - } - - [Fact] - public void MOV_A_A_ShouldStoreAccumulatorInAccumulator() - { - // Arrange - _cpu.Registers.A = 0xFF; - - // Act - DefaultInstructionSet.MOV_A_A(_cpu); - - // Assert - Assert.Equal(0xFF, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - } +using Intel8080.Emulator.Instructions; +using Xunit; + +namespace Intel8080.Emulator.Tests.Instructions; + +public class DataTransferInstructionTests +{ + private readonly CPU _cpu; + private readonly IMemory _memory; + + public DataTransferInstructionTests() + { + _memory = new DefaultMemory(0x100); + + _cpu = new CPU(_memory); + } + + [Fact] + public void STAX_B_StoreAccumulator_LocationBC() + { + // Arrange + _cpu.Registers.A = 0x42; + _cpu.Registers.BC = 0x0010; + + // Act + DefaultInstructionSet.STAX_B(_cpu); + + // Assert + Assert.Equal(0x0042, _memory[0x0010]); + + Assert.Equal(0x42, _cpu.Registers.A); + Assert.Equal(0x0010, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void STAX_D_StoreAccumulator_LocationDE() + { + // Arrange + _cpu.Registers.A = 0x42; + _cpu.Registers.DE = 0x0010; + + // Act + DefaultInstructionSet.STAX_D(_cpu); + + // Assert + Assert.Equal(0x0042, _memory[0x0010]); + + Assert.Equal(0x42, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0010, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void LDAX_B_LoadAcculmulator_LocationBC() + { + // Arrange + _memory[0x0010] = 0x0042; + _cpu.Registers.BC = 0x0010; + + // Act + DefaultInstructionSet.LDAX_B(_cpu); + + // Assert + Assert.Equal(0x42, _cpu.Registers.A); + Assert.Equal(0x0010, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void LDAX_D_LoadAcculmulator_LocationBC() + { + // Arrange + _memory[0x0010] = 0x0042; + _cpu.Registers.DE = 0x0010; + + // Act + DefaultInstructionSet.LDAX_D(_cpu); + + // Assert + Assert.Equal(0x42, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0010, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MOV_B_B_ShouldStoreRegBInRegB() + { + // Arrange + _cpu.Registers.B = 0xFF; + + // Act + DefaultInstructionSet.MOV_B_B(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0xFF00, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MOV_B_C_ShouldStoreRegCInRegB() + { + // Arrange + _cpu.Registers.C = 0xFF; + + // Act + DefaultInstructionSet.MOV_B_C(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0xFFFF, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MOV_B_D_ShouldStoreRegDInRegB() + { + // Arrange + _cpu.Registers.D = 0xFF; + + // Act + DefaultInstructionSet.MOV_B_D(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0xFF00, _cpu.Registers.BC); + Assert.Equal(0xFF00, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MOV_B_E_ShouldStoreRegEInRegB() + { + // Arrange + _cpu.Registers.E = 0xFF; + + // Act + DefaultInstructionSet.MOV_B_E(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0xFF00, _cpu.Registers.BC); + Assert.Equal(0x00FF, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MOV_B_H_ShouldStoreRegHInRegB() + { + // Arrange + _cpu.Registers.H = 0xFF; + + // Act + DefaultInstructionSet.MOV_B_H(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0xFF00, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0xFF00, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MOV_B_L_ShouldStoreRegLInRegB() + { + // Arrange + _cpu.Registers.L = 0xFF; + + // Act + DefaultInstructionSet.MOV_B_L(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0xFF00, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x00FF, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + + [Fact] + public void MOV_B_M_ShouldStoreMemoryByteInRegB() + { + // Arrange + _cpu.Registers.H = 0x00; + _cpu.Registers.L = 0x10; + + _cpu.Memory[0x0010] = 0xFF; + + // Act + DefaultInstructionSet.MOV_B_M(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0xFF00, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0010, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.Equal(0xFF, _cpu.Memory[0x0010]); + } + + [Fact] + public void MOV_B_A_ShouldStoreAccumulatorInRegB() + { + // Arrange + _cpu.Registers.A = 0xFF; + + // Act + DefaultInstructionSet.MOV_B_A(_cpu); + + // Assert + Assert.Equal(0xFF, _cpu.Registers.A); + Assert.Equal(0xFF00, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MOV_C_B_ShouldStoreRegBInRegC() + { + // Arrange + _cpu.Registers.B = 0xFF; + + // Act + DefaultInstructionSet.MOV_C_B(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0xFFFF, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MOV_C_C_ShouldStoreRegCInRegC() + { + // Arrange + _cpu.Registers.C = 0xFF; + + // Act + DefaultInstructionSet.MOV_C_C(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x00FF, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MOV_C_D_ShouldStoreRegDInRegC() + { + // Arrange + _cpu.Registers.D = 0xFF; + + // Act + DefaultInstructionSet.MOV_C_D(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x00FF, _cpu.Registers.BC); + Assert.Equal(0xFF00, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MOV_C_E_ShouldStoreRegEInRegC() + { + // Arrange + _cpu.Registers.E = 0xFF; + + // Act + DefaultInstructionSet.MOV_C_E(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x00FF, _cpu.Registers.BC); + Assert.Equal(0x00FF, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MOV_C_H_ShouldStoreRegHInRegC() + { + // Arrange + _cpu.Registers.H = 0xFF; + + // Act + DefaultInstructionSet.MOV_C_H(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x00FF, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0xFF00, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MOV_C_L_ShouldStoreRegLInRegC() + { + // Arrange + _cpu.Registers.L = 0xFF; + + // Act + DefaultInstructionSet.MOV_C_L(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x00FF, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x00FF, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MOV_C_M_ShouldStoreMemoryByteInRegC() + { + // Arrange + _cpu.Registers.H = 0x00; + _cpu.Registers.L = 0x10; + + _cpu.Memory[0x0010] = 0xFF; + + // Act + DefaultInstructionSet.MOV_C_M(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x00FF, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0010, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.Equal(0xFF, _cpu.Memory[0x0010]); + } + + [Fact] + public void MOV_C_A_ShouldStoreAccumulatorInRegC() + { + // Arrange + _cpu.Registers.A = 0xFF; + + // Act + DefaultInstructionSet.MOV_C_A(_cpu); + + // Assert + Assert.Equal(0xFF, _cpu.Registers.A); + Assert.Equal(0x00FF, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MOV_D_B_ShouldStoreRegBInRegD() + { + // Arrange + _cpu.Registers.B = 0xFF; + + // Act + DefaultInstructionSet.MOV_D_B(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0xFF00, _cpu.Registers.BC); + Assert.Equal(0xFF00, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MOV_D_C_ShouldStoreRegCInRegD() + { + // Arrange + _cpu.Registers.C = 0xFF; + + // Act + DefaultInstructionSet.MOV_D_C(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x00FF, _cpu.Registers.BC); + Assert.Equal(0xFF00, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MOV_D_D_ShouldStoreRegDInRegD() + { + // Arrange + _cpu.Registers.D = 0xFF; + + // Act + DefaultInstructionSet.MOV_D_D(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0xFF00, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MOV_D_E_ShouldStoreRegEInRegD() + { + // Arrange + _cpu.Registers.E = 0xFF; + + // Act + DefaultInstructionSet.MOV_D_E(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0xFFFF, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MOV_D_H_ShouldStoreRegHInRegD() + { + // Arrange + _cpu.Registers.H = 0xFF; + + // Act + DefaultInstructionSet.MOV_D_H(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0xFF00, _cpu.Registers.DE); + Assert.Equal(0xFF00, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MOV_D_L_ShouldStoreRegLInRegD() + { + // Arrange + _cpu.Registers.L = 0xFF; + + // Act + DefaultInstructionSet.MOV_D_L(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0xFF00, _cpu.Registers.DE); + Assert.Equal(0x00FF, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + + [Fact] + public void MOV_D_M_ShouldStoreMemoryByteInRegD() + { + // Arrange + _cpu.Registers.H = 0x00; + _cpu.Registers.L = 0x10; + + _cpu.Memory[0x0010] = 0xFF; + + // Act + DefaultInstructionSet.MOV_D_M(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0xFF00, _cpu.Registers.DE); + Assert.Equal(0x0010, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.Equal(0xFF, _cpu.Memory[0x0010]); + } + + [Fact] + public void MOV_D_A_ShouldStoreAccumulatorInRegD() + { + // Arrange + _cpu.Registers.A = 0xFF; + + // Act + DefaultInstructionSet.MOV_D_A(_cpu); + + // Assert + Assert.Equal(0xFF, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0xFF00, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MOV_E_B_ShouldStoreRegBInRegE() + { + // Arrange + _cpu.Registers.B = 0xFF; + + // Act + DefaultInstructionSet.MOV_E_B(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0xFF00, _cpu.Registers.BC); + Assert.Equal(0x00FF, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MOV_E_C_ShouldStoreRegCInRegE() + { + // Arrange + _cpu.Registers.C = 0xFF; + + // Act + DefaultInstructionSet.MOV_E_C(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x00FF, _cpu.Registers.BC); + Assert.Equal(0x00FF, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MOV_E_D_ShouldStoreRegDInRegE() + { + // Arrange + _cpu.Registers.D = 0xFF; + + // Act + DefaultInstructionSet.MOV_E_D(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0xFFFF, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MOV_E_E_ShouldStoreRegEInRegE() + { + // Arrange + _cpu.Registers.E = 0xFF; + + // Act + DefaultInstructionSet.MOV_E_E(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x00FF, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MOV_E_H_ShouldStoreRegHInRegE() + { + // Arrange + _cpu.Registers.H = 0xFF; + + // Act + DefaultInstructionSet.MOV_E_H(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x00FF, _cpu.Registers.DE); + Assert.Equal(0xFF00, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MOV_E_L_ShouldStoreRegLInRegE() + { + // Arrange + _cpu.Registers.L = 0xFF; + + // Act + DefaultInstructionSet.MOV_E_L(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x00FF, _cpu.Registers.DE); + Assert.Equal(0x00FF, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + + [Fact] + public void MOV_E_M_ShouldStoreMemoryByteInRegE() + { + // Arrange + _cpu.Registers.H = 0x00; + _cpu.Registers.L = 0x10; + + _cpu.Memory[0x0010] = 0xFF; + + // Act + DefaultInstructionSet.MOV_E_M(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x00FF, _cpu.Registers.DE); + Assert.Equal(0x0010, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.Equal(0xFF, _cpu.Memory[0x0010]); + } + + [Fact] + public void MOV_E_A_ShouldStoreAccumulatorInRegE() + { + // Arrange + _cpu.Registers.A = 0xFF; + + // Act + DefaultInstructionSet.MOV_E_A(_cpu); + + // Assert + Assert.Equal(0xFF, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x00FF, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MOV_H_B_ShouldStoreRegBInRegH() + { + // Arrange + _cpu.Registers.B = 0xFF; + + // Act + DefaultInstructionSet.MOV_H_B(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0xFF00, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0xFF00, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MOV_H_C_ShouldStoreRegCInRegH() + { + // Arrange + _cpu.Registers.C = 0xFF; + + // Act + DefaultInstructionSet.MOV_H_C(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x00FF, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0xFF00, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MOV_H_D_ShouldStoreRegDInRegH() + { + // Arrange + _cpu.Registers.D = 0xFF; + + // Act + DefaultInstructionSet.MOV_H_D(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0xFF00, _cpu.Registers.DE); + Assert.Equal(0xFF00, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MOV_H_E_ShouldStoreRegEInRegH() + { + // Arrange + _cpu.Registers.E = 0xFF; + + // Act + DefaultInstructionSet.MOV_H_E(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x00FF, _cpu.Registers.DE); + Assert.Equal(0xFF00, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MOV_H_H_ShouldStoreRegHInRegH() + { + // Arrange + _cpu.Registers.H = 0xFF; + + // Act + DefaultInstructionSet.MOV_H_H(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0xFF00, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MOV_H_L_ShouldStoreRegLInRegH() + { + // Arrange + _cpu.Registers.L = 0xFF; + + // Act + DefaultInstructionSet.MOV_H_L(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0xFFFF, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + + [Fact] + public void MOV_H_M_ShouldStoreMemoryByteInRegH() + { + // Arrange + _cpu.Registers.H = 0x00; + _cpu.Registers.L = 0x10; + + _cpu.Memory[0x0010] = 0xFF; + + // Act + DefaultInstructionSet.MOV_H_M(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0xFF10, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.Equal(0xFF, _cpu.Memory[0x0010]); + } + + [Fact] + public void MOV_H_A_ShouldStoreAccumulatorInRegH() + { + // Arrange + _cpu.Registers.A = 0xFF; + + // Act + DefaultInstructionSet.MOV_H_A(_cpu); + + // Assert + Assert.Equal(0xFF, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0xFF00, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MOV_L_B_ShouldStoreRegBInRegL() + { + // Arrange + _cpu.Registers.B = 0xFF; + + // Act + DefaultInstructionSet.MOV_L_B(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0xFF00, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x00FF, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MOV_L_C_ShouldStoreRegCInRegL() + { + // Arrange + _cpu.Registers.C = 0xFF; + + // Act + DefaultInstructionSet.MOV_L_C(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x00FF, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x00FF, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MOV_L_D_ShouldStoreRegDInRegL() + { + // Arrange + _cpu.Registers.D = 0xFF; + + // Act + DefaultInstructionSet.MOV_L_D(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0xFF00, _cpu.Registers.DE); + Assert.Equal(0x00FF, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MOV_L_E_ShouldStoreRegEInRegL() + { + // Arrange + _cpu.Registers.E = 0xFF; + + // Act + DefaultInstructionSet.MOV_L_E(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x00FF, _cpu.Registers.DE); + Assert.Equal(0x00FF, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MOV_L_H_ShouldStoreRegHInRegL() + { + // Arrange + _cpu.Registers.H = 0xFF; + + // Act + DefaultInstructionSet.MOV_L_H(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0xFFFF, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MOV_L_L_ShouldStoreRegLInRegL() + { + // Arrange + _cpu.Registers.L = 0xFF; + + // Act + DefaultInstructionSet.MOV_L_L(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x00FF, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + + [Fact] + public void MOV_L_M_ShouldStoreMemoryByteInRegL() + { + // Arrange + _cpu.Registers.H = 0x00; + _cpu.Registers.L = 0x10; + + _cpu.Memory[0x0010] = 0xFF; + + // Act + DefaultInstructionSet.MOV_L_M(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x00FF, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.Equal(0xFF, _cpu.Memory[0x0010]); + } + + [Fact] + public void MOV_L_A_ShouldStoreAccumulatorInRegL() + { + // Arrange + _cpu.Registers.A = 0xFF; + + // Act + DefaultInstructionSet.MOV_L_A(_cpu); + + // Assert + Assert.Equal(0xFF, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x00FF, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MOV_M_B_ShouldStoreRegBInMemoryLocation() + { + // Arrange + _cpu.Registers.B = 0xFF; + _cpu.Registers.HL = 0x0010; + + // Act + DefaultInstructionSet.MOV_M_B(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0xFF00, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0010, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.Equal(0xFF, _cpu.Memory[0x0010]); + } + + [Fact] + public void MOV_M_C_ShouldStoreRegCInMemoryLocation() + { + // Arrange + _cpu.Registers.C = 0xFF; + _cpu.Registers.HL = 0x0010; + + // Act + DefaultInstructionSet.MOV_M_C(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x00FF, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0010, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.Equal(0xFF, _cpu.Memory[0x0010]); + } + + [Fact] + public void MOV_M_D_ShouldStoreRegDInMemoryLocation() + { + // Arrange + _cpu.Registers.D = 0xFF; + _cpu.Registers.HL = 0x0010; + + // Act + DefaultInstructionSet.MOV_M_D(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0xFF00, _cpu.Registers.DE); + Assert.Equal(0x0010, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.Equal(0xFF, _cpu.Memory[0x0010]); + } + + [Fact] + public void MOV_M_E_ShouldStoreRegEInMemoryLocation() + { + // Arrange + _cpu.Registers.E = 0xFF; + _cpu.Registers.HL = 0x0010; + + // Act + DefaultInstructionSet.MOV_M_E(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x00FF, _cpu.Registers.DE); + Assert.Equal(0x0010, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.Equal(0xFF, _cpu.Memory[0x0010]); + } + + [Fact] + public void MOV_M_H_ShouldStoreRegHInMemoryLocation() + { + // Arrange + _cpu.Registers.HL = 0x0010; + + // Act + DefaultInstructionSet.MOV_M_H(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0010, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.Equal(0x00, _cpu.Memory[0x0010]); + } + + [Fact] + public void MOV_M_L_ShouldStoreRegLInMemoryLocation() + { + // Arrange + _cpu.Registers.HL = 0x0010; + + // Act + DefaultInstructionSet.MOV_M_L(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0010, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.Equal(0x10, _cpu.Memory[0x0010]); + } + + [Fact] + public void MOV_M_A_ShouldStoreAccumulatorInMemoryLocation() + { + // Arrange + _cpu.Registers.A = 0xFF; + _cpu.Registers.HL = 0x0010; + + // Act + DefaultInstructionSet.MOV_M_A(_cpu); + + // Assert + Assert.Equal(0xFF, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0010, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.Equal(0xFF, _cpu.Memory[0x0010]); + } + + [Fact] + public void MOV_A_B_ShouldStoreRegBInAccumulator() + { + // Arrange + _cpu.Registers.B = 0xFF; + + // Act + DefaultInstructionSet.MOV_A_B(_cpu); + + // Assert + Assert.Equal(0xFF, _cpu.Registers.A); + Assert.Equal(0xFF00, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MOV_A_C_ShouldStoreRegCInAccumulator() + { + // Arrange + _cpu.Registers.C = 0xFF; + + // Act + DefaultInstructionSet.MOV_A_C(_cpu); + + // Assert + Assert.Equal(0xFF, _cpu.Registers.A); + Assert.Equal(0x00FF, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MOV_A_D_ShouldStoreRegDInAccumulator() + { + // Arrange + _cpu.Registers.D = 0xFF; + + // Act + DefaultInstructionSet.MOV_A_D(_cpu); + + // Assert + Assert.Equal(0xFF, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0xFF00, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MOV_A_E_ShouldStoreRegEInAccumulator() + { + // Arrange + _cpu.Registers.E = 0xFF; + + // Act + DefaultInstructionSet.MOV_A_E(_cpu); + + // Assert + Assert.Equal(0xFF, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x00FF, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MOV_A_H_ShouldStoreRegHInAccumulator() + { + // Arrange + _cpu.Registers.H = 0xFF; + + // Act + DefaultInstructionSet.MOV_A_H(_cpu); + + // Assert + Assert.Equal(0xFF, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0xFF00, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MOV_A_L_ShouldStoreRegLInAccumulator() + { + // Arrange + _cpu.Registers.L = 0xFF; + + // Act + DefaultInstructionSet.MOV_A_L(_cpu); + + // Assert + Assert.Equal(0xFF, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x00FF, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + + [Fact] + public void MOV_A_M_ShouldStoreMemoryByteInAccumulator() + { + // Arrange + _cpu.Registers.H = 0x00; + _cpu.Registers.L = 0x10; + + _cpu.Memory[0x0010] = 0xFF; + + // Act + DefaultInstructionSet.MOV_A_M(_cpu); + + // Assert + Assert.Equal(0xFF, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0010, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.Equal(0xFF, _cpu.Memory[0x0010]); + } + + [Fact] + public void MOV_A_A_ShouldStoreAccumulatorInAccumulator() + { + // Arrange + _cpu.Registers.A = 0xFF; + + // Act + DefaultInstructionSet.MOV_A_A(_cpu); + + // Assert + Assert.Equal(0xFF, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } } \ No newline at end of file diff --git a/Intel8080.Emulator.Tests/Instructions/DirectAddressingInstructionTests.cs b/Intel8080.Emulator.Tests/Instructions/DirectAddressingInstructionTests.cs index b724c5d..1684bd3 100644 --- a/Intel8080.Emulator.Tests/Instructions/DirectAddressingInstructionTests.cs +++ b/Intel8080.Emulator.Tests/Instructions/DirectAddressingInstructionTests.cs @@ -1,105 +1,103 @@ -using Intel8080.Emulator.Instructions; -using Moq; -using Xunit; - -namespace Intel8080.Emulator.Tests.Instructions -{ - public class DirectAddressingInstructionTests - { - private readonly CPU _cpu; - private readonly IMemory _memory; - - public DirectAddressingInstructionTests() - { - _memory = new DefaultMemory(0x300); - - _cpu = new CPU(_memory); - - _cpu.Registers.PC = 1; - } - - [Fact] - public void STA_ShouldStoreAccumulatorInMemory() - { - // Arrange - _memory[0x0001] = 0x0A; - _memory[0x0002] = 0x01; - _cpu.Registers.A = 0x42; - - // Act - DefaultInstructionSet.STA(_cpu); - - // Assert - Assert.Equal(0x42, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.Equal(0x42, _memory[0x10A]); - } - - [Fact] - public void SHLD_ShouldStoreHLInMemory() - { - // Arrange - _memory[0x0001] = 0x0A; - _memory[0x0002] = 0x01; - _cpu.Registers.HL = 0xAE29; - - // Act - DefaultInstructionSet.SHLD(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0xAE29, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.Equal(0x29, _memory[0x10A]); - Assert.Equal(0xAE, _memory[0x10B]); - } - - [Fact] - public void LHLD_ShouldStoreMemoryInHL() - { - // Arrange - _memory[0x0001] = 0x5B; - _memory[0x0002] = 0x02; - - _memory[0x25B] = 0xFF; - _memory[0x25C] = 0x03; - - // Act - DefaultInstructionSet.LHLD(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x03FF, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void LDA_ShouldStoreMemoryInAccumulator() - { - // Arrange - _memory[0x0001] = 0x5B; - _memory[0x0002] = 0x02; - - _memory[0x25B] = 0x42; - - // Act - DefaultInstructionSet.LDA(_cpu); - - // Assert - Assert.Equal(0x42, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - } +using Intel8080.Emulator.Instructions; +using Xunit; + +namespace Intel8080.Emulator.Tests.Instructions; + +public class DirectAddressingInstructionTests +{ + private readonly CPU _cpu; + private readonly IMemory _memory; + + public DirectAddressingInstructionTests() + { + _memory = new DefaultMemory(0x300); + + _cpu = new CPU(_memory); + + _cpu.Registers.PC = 1; + } + + [Fact] + public void STA_ShouldStoreAccumulatorInMemory() + { + // Arrange + _memory[0x0001] = 0x0A; + _memory[0x0002] = 0x01; + _cpu.Registers.A = 0x42; + + // Act + DefaultInstructionSet.STA(_cpu); + + // Assert + Assert.Equal(0x42, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.Equal(0x42, _memory[0x10A]); + } + + [Fact] + public void SHLD_ShouldStoreHLInMemory() + { + // Arrange + _memory[0x0001] = 0x0A; + _memory[0x0002] = 0x01; + _cpu.Registers.HL = 0xAE29; + + // Act + DefaultInstructionSet.SHLD(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0xAE29, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.Equal(0x29, _memory[0x10A]); + Assert.Equal(0xAE, _memory[0x10B]); + } + + [Fact] + public void LHLD_ShouldStoreMemoryInHL() + { + // Arrange + _memory[0x0001] = 0x5B; + _memory[0x0002] = 0x02; + + _memory[0x25B] = 0xFF; + _memory[0x25C] = 0x03; + + // Act + DefaultInstructionSet.LHLD(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x03FF, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void LDA_ShouldStoreMemoryInAccumulator() + { + // Arrange + _memory[0x0001] = 0x5B; + _memory[0x0002] = 0x02; + + _memory[0x25B] = 0x42; + + // Act + DefaultInstructionSet.LDA(_cpu); + + // Assert + Assert.Equal(0x42, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } } \ No newline at end of file diff --git a/Intel8080.Emulator.Tests/Instructions/ImmediateInstructionTests.cs b/Intel8080.Emulator.Tests/Instructions/ImmediateInstructionTests.cs index 9eb3a3a..db175f8 100644 --- a/Intel8080.Emulator.Tests/Instructions/ImmediateInstructionTests.cs +++ b/Intel8080.Emulator.Tests/Instructions/ImmediateInstructionTests.cs @@ -1,453 +1,451 @@ -using Intel8080.Emulator.Instructions; -using Moq; -using Xunit; - -namespace Intel8080.Emulator.Tests.Instructions -{ - public class ImmediateInstructionTests - { - private readonly CPU _cpu; - private readonly IMemory _memory; - - public ImmediateInstructionTests() - { - _memory = new DefaultMemory(0x100); - _cpu = new CPU(_memory); - - _cpu.Registers.PC = 1; - } - - [Fact] - public void LXI_B_ShouldStoreImmediateDataInBC() - { - // Arrange - _memory[0x0001] = 0x03; - _memory[0x0002] = 0x01; - - // Act - DefaultInstructionSet.LXI_B(_cpu); - - // Assert - Assert.Equal(0x0000, _cpu.Registers.A); - Assert.Equal(0x0103, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void LXI_D_ShouldStoreImmediateDataInDE() - { - // Arrange - _memory[0x0001] = 0x03; - _memory[0x0002] = 0x01; - - // Act - DefaultInstructionSet.LXI_D(_cpu); - - // Assert - Assert.Equal(0x0000, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0103, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void LXI_H_ShouldStoreImmediateDataInHL() - { - // Arrange - _memory[0x0001] = 0x03; - _memory[0x0002] = 0x01; - - // Act - DefaultInstructionSet.LXI_H(_cpu); - - // Assert - Assert.Equal(0x0000, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0103, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void LXI_SP_ShouldStoreImmediateDataInSP() - { - // Arrange - _memory[0x0001] = 0x03; - _memory[0x0002] = 0x01; - - // Act - DefaultInstructionSet.LXI_SP(_cpu); - - // Assert - Assert.Equal(0x0000, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0103, _cpu.Registers.SP); - } - - [Fact] - public void MVI_B_ShouldStoreImmediateDataInB() - { - // Arrange - _memory[0x0001] = 0xFF; - - // Act - DefaultInstructionSet.MVI_B(_cpu); - - // Assert - Assert.Equal(0x0000, _cpu.Registers.A); - Assert.Equal(0xFF00, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MVI_C_ShouldStoreImmediateDataInC() - { - // Arrange - _memory[0x0001] = 0xFF; - - // Act - DefaultInstructionSet.MVI_C(_cpu); - - // Assert - Assert.Equal(0x0000, _cpu.Registers.A); - Assert.Equal(0x00FF, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MVI_D_ShouldStoreImmediateDataInD() - { - // Arrange - _memory[0x0001] = 0xFF; - - // Act - DefaultInstructionSet.MVI_D(_cpu); - - // Assert - Assert.Equal(0x0000, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0xFF00, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MVI_E_ShouldStoreImmediateDataInE() - { - // Arrange - _memory[0x0001] = 0xFF; - - // Act - DefaultInstructionSet.MVI_E(_cpu); - - // Assert - Assert.Equal(0x0000, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x00FF, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MVI_H_ShouldStoreImmediateDataInH() - { - // Arrange - _memory[0x0001] = 0xFF; - - // Act - DefaultInstructionSet.MVI_H(_cpu); - - // Assert - Assert.Equal(0x0000, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0xFF00, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MVI_L_ShouldStoreImmediateDataInL() - { - // Arrange - _memory[0x0001] = 0xFF; - - // Act - DefaultInstructionSet.MVI_L(_cpu); - - // Assert - Assert.Equal(0x0000, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x00FF, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void MVI_M_ShouldStoreImmediateDataInMemoryLocation() - { - // Arrange - _cpu.Registers.HL = 0x0050; - _memory[0x0001] = 0xFF; - - // Act - DefaultInstructionSet.MVI_M(_cpu); - - // Assert - Assert.Equal(0x0000, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0050, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.Equal(0xFF, _cpu.Memory[0x0050]); - } - - [Fact] - public void MVI_A_ShouldStoreImmediateDataInAccumulator() - { - // Arrange - _memory[0x0001] = 0xFF; - - // Act - DefaultInstructionSet.MVI_A(_cpu); - - // Assert - Assert.Equal(0x00FF, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void ADI_ShouldAddImmediateDataToAccumulator() - { - // Arrange - _cpu.Registers.A = 0x6C; - _memory[0x0001] = 0x2E; - - // Act - DefaultInstructionSet.ADI(_cpu); - - // Assert - Assert.Equal(0x9A, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void ACI_ShouldAddImmediateDataToAccumulator_Carry() - { - // Arrange - _cpu.Registers.A = 0x42; - _memory[0x0001] = 0x3D; - - _cpu.Flags.Carry = true; - - // Act - DefaultInstructionSet.ACI(_cpu); - - // Assert - Assert.Equal(0x80, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void SUI_ShouldSubtractImmediateDataFromAccumulator() - { - // Arrange - _cpu.Registers.A = 0x3E; - _memory[0x01] = 0x3E; - - // Act - DefaultInstructionSet.SUI(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.True(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void SBI_ShouldSubtractImmediateDataFromAccumulator_NoCarry() - { - // Arrange - _cpu.Registers.A = 0x04; - _memory[0x01] = 0x02; - - _cpu.Flags.Carry = false; - - // Act - DefaultInstructionSet.SBI(_cpu); - - // Assert - Assert.Equal(0x02, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void SBI_ShouldSubtractImmediateDataFromAccumulator_Carry() - { - // Arrange - _cpu.Registers.A = 0x04; - _memory[0x01] = 0x02; - - _cpu.Flags.Carry = true; - - // Act - DefaultInstructionSet.SBI(_cpu); - - // Assert - Assert.Equal(0x01, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void ANI_ShouldBitwiseANDAccumulatorImmediateData() - { - // Arrange - _cpu.Registers.A = 0xFC; - _memory[0x0001] = 0x0F; - - // Act - DefaultInstructionSet.ANI(_cpu); - - // Assert - Assert.Equal(0x0C, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void XRI_ShouldBitwiseXORAccumulatorImmediateData() - { - // Arrange - _cpu.Registers.A = 0x5C; - _memory[0x0001] = 0x78; - - // Act - DefaultInstructionSet.XRI(_cpu); - - // Assert - Assert.Equal(0x24, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void ORI_ShouldBitwiseOrAccumulatorImmediateData() - { - // Arrange - _cpu.Registers.A = 0x33; - _cpu.Memory[0x0001] = 0x0F; - - // Act - DefaultInstructionSet.ORI(_cpu); - - // Assert - Assert.Equal(0x3F, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void CPI_ShouldAccumulatorAndImmediateData() - { - // Arrange - _cpu.Registers.A = 0x02; - _cpu.Memory[0x0001] = 0x05; - - // Act - DefaultInstructionSet.CPI(_cpu); - - // Assert - Assert.Equal(0x02, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - Assert.True(_cpu.Flags.Carry); - } - } +using Intel8080.Emulator.Instructions; +using Xunit; + +namespace Intel8080.Emulator.Tests.Instructions; + +public class ImmediateInstructionTests +{ + private readonly CPU _cpu; + private readonly IMemory _memory; + + public ImmediateInstructionTests() + { + _memory = new DefaultMemory(0x100); + _cpu = new CPU(_memory); + + _cpu.Registers.PC = 1; + } + + [Fact] + public void LXI_B_ShouldStoreImmediateDataInBC() + { + // Arrange + _memory[0x0001] = 0x03; + _memory[0x0002] = 0x01; + + // Act + DefaultInstructionSet.LXI_B(_cpu); + + // Assert + Assert.Equal(0x0000, _cpu.Registers.A); + Assert.Equal(0x0103, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void LXI_D_ShouldStoreImmediateDataInDE() + { + // Arrange + _memory[0x0001] = 0x03; + _memory[0x0002] = 0x01; + + // Act + DefaultInstructionSet.LXI_D(_cpu); + + // Assert + Assert.Equal(0x0000, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0103, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void LXI_H_ShouldStoreImmediateDataInHL() + { + // Arrange + _memory[0x0001] = 0x03; + _memory[0x0002] = 0x01; + + // Act + DefaultInstructionSet.LXI_H(_cpu); + + // Assert + Assert.Equal(0x0000, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0103, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void LXI_SP_ShouldStoreImmediateDataInSP() + { + // Arrange + _memory[0x0001] = 0x03; + _memory[0x0002] = 0x01; + + // Act + DefaultInstructionSet.LXI_SP(_cpu); + + // Assert + Assert.Equal(0x0000, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0103, _cpu.Registers.SP); + } + + [Fact] + public void MVI_B_ShouldStoreImmediateDataInB() + { + // Arrange + _memory[0x0001] = 0xFF; + + // Act + DefaultInstructionSet.MVI_B(_cpu); + + // Assert + Assert.Equal(0x0000, _cpu.Registers.A); + Assert.Equal(0xFF00, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MVI_C_ShouldStoreImmediateDataInC() + { + // Arrange + _memory[0x0001] = 0xFF; + + // Act + DefaultInstructionSet.MVI_C(_cpu); + + // Assert + Assert.Equal(0x0000, _cpu.Registers.A); + Assert.Equal(0x00FF, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MVI_D_ShouldStoreImmediateDataInD() + { + // Arrange + _memory[0x0001] = 0xFF; + + // Act + DefaultInstructionSet.MVI_D(_cpu); + + // Assert + Assert.Equal(0x0000, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0xFF00, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MVI_E_ShouldStoreImmediateDataInE() + { + // Arrange + _memory[0x0001] = 0xFF; + + // Act + DefaultInstructionSet.MVI_E(_cpu); + + // Assert + Assert.Equal(0x0000, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x00FF, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MVI_H_ShouldStoreImmediateDataInH() + { + // Arrange + _memory[0x0001] = 0xFF; + + // Act + DefaultInstructionSet.MVI_H(_cpu); + + // Assert + Assert.Equal(0x0000, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0xFF00, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MVI_L_ShouldStoreImmediateDataInL() + { + // Arrange + _memory[0x0001] = 0xFF; + + // Act + DefaultInstructionSet.MVI_L(_cpu); + + // Assert + Assert.Equal(0x0000, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x00FF, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void MVI_M_ShouldStoreImmediateDataInMemoryLocation() + { + // Arrange + _cpu.Registers.HL = 0x0050; + _memory[0x0001] = 0xFF; + + // Act + DefaultInstructionSet.MVI_M(_cpu); + + // Assert + Assert.Equal(0x0000, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0050, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.Equal(0xFF, _cpu.Memory[0x0050]); + } + + [Fact] + public void MVI_A_ShouldStoreImmediateDataInAccumulator() + { + // Arrange + _memory[0x0001] = 0xFF; + + // Act + DefaultInstructionSet.MVI_A(_cpu); + + // Assert + Assert.Equal(0x00FF, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void ADI_ShouldAddImmediateDataToAccumulator() + { + // Arrange + _cpu.Registers.A = 0x6C; + _memory[0x0001] = 0x2E; + + // Act + DefaultInstructionSet.ADI(_cpu); + + // Assert + Assert.Equal(0x9A, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void ACI_ShouldAddImmediateDataToAccumulator_Carry() + { + // Arrange + _cpu.Registers.A = 0x42; + _memory[0x0001] = 0x3D; + + _cpu.Flags.Carry = true; + + // Act + DefaultInstructionSet.ACI(_cpu); + + // Assert + Assert.Equal(0x80, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void SUI_ShouldSubtractImmediateDataFromAccumulator() + { + // Arrange + _cpu.Registers.A = 0x3E; + _memory[0x01] = 0x3E; + + // Act + DefaultInstructionSet.SUI(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.True(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void SBI_ShouldSubtractImmediateDataFromAccumulator_NoCarry() + { + // Arrange + _cpu.Registers.A = 0x04; + _memory[0x01] = 0x02; + + _cpu.Flags.Carry = false; + + // Act + DefaultInstructionSet.SBI(_cpu); + + // Assert + Assert.Equal(0x02, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void SBI_ShouldSubtractImmediateDataFromAccumulator_Carry() + { + // Arrange + _cpu.Registers.A = 0x04; + _memory[0x01] = 0x02; + + _cpu.Flags.Carry = true; + + // Act + DefaultInstructionSet.SBI(_cpu); + + // Assert + Assert.Equal(0x01, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void ANI_ShouldBitwiseANDAccumulatorImmediateData() + { + // Arrange + _cpu.Registers.A = 0xFC; + _memory[0x0001] = 0x0F; + + // Act + DefaultInstructionSet.ANI(_cpu); + + // Assert + Assert.Equal(0x0C, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void XRI_ShouldBitwiseXORAccumulatorImmediateData() + { + // Arrange + _cpu.Registers.A = 0x5C; + _memory[0x0001] = 0x78; + + // Act + DefaultInstructionSet.XRI(_cpu); + + // Assert + Assert.Equal(0x24, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void ORI_ShouldBitwiseOrAccumulatorImmediateData() + { + // Arrange + _cpu.Registers.A = 0x33; + _cpu.Memory[0x0001] = 0x0F; + + // Act + DefaultInstructionSet.ORI(_cpu); + + // Assert + Assert.Equal(0x3F, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void CPI_ShouldAccumulatorAndImmediateData() + { + // Arrange + _cpu.Registers.A = 0x02; + _cpu.Memory[0x0001] = 0x05; + + // Act + DefaultInstructionSet.CPI(_cpu); + + // Assert + Assert.Equal(0x02, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + Assert.True(_cpu.Flags.Carry); + } } \ No newline at end of file diff --git a/Intel8080.Emulator.Tests/Instructions/InstructionMetaDataTests.cs b/Intel8080.Emulator.Tests/Instructions/InstructionMetaDataTests.cs index b7c2345..c337680 100644 --- a/Intel8080.Emulator.Tests/Instructions/InstructionMetaDataTests.cs +++ b/Intel8080.Emulator.Tests/Instructions/InstructionMetaDataTests.cs @@ -1,291 +1,288 @@ -using System; -using System.Collections.Generic; -using Intel8080.Emulator; -using Xunit; - -namespace Intel8080.Emulator.Tests.Instructions -{ - public class InstructionMetaDataTests - { - private Opcode[] _opcodes; - - public static IEnumerable OpcodeData => new List - { - new object[] { 0x00, "NOP", 1, 4, null }, - new object[] { 0x01, "LXI B, d16", 3, 10, null }, - new object[] { 0x02, "STAX B", 1, 7, null }, - new object[] { 0x03, "INX B", 1, 5, null }, - new object[] { 0x04, "INR B", 1, 5, null }, - new object[] { 0x05, "DCR B", 1, 5, null }, - new object[] { 0x06, "MVI B, d8", 2, 7, null }, - new object[] { 0x07, "RLC", 1, 4, null }, - new object[] { 0x08, "*NOP", 1, 4, null }, - new object[] { 0x09, "DAD B", 1, 10, null }, - new object[] { 0x0A, "LDAX B", 1, 7, null }, - new object[] { 0x0B, "DCX B", 1, 5, null }, - new object[] { 0x0C, "INR C", 1, 5, null }, - new object[] { 0x0D, "DCR C", 1, 5, null }, - new object[] { 0x0E, "MVI C, d8", 2, 7, null }, - new object[] { 0x0F, "RRC", 1, 4, null }, - new object[] { 0x10, "*NOP", 1, 4, null }, - new object[] { 0x11, "LXI D, d16", 3, 10, null }, - new object[] { 0x12, "STAX D", 1, 7, null }, - new object[] { 0x13, "INX D", 1, 5, null }, - new object[] { 0x14, "INR D", 1, 5, null }, - new object[] { 0x15, "DCR D", 1, 5, null }, - new object[] { 0x16, "MVI D, d8", 2, 7, null }, - new object[] { 0x17, "RAL", 1, 4, null }, - new object[] { 0x18, "*NOP", 1, 4, null }, - new object[] { 0x19, "DAD D", 1, 10, null }, - new object[] { 0x1A, "LDAX D", 1, 7, null }, - new object[] { 0x1B, "DCX D", 1, 5, null }, - new object[] { 0x1C, "INR E", 1, 5, null }, - new object[] { 0x1D, "DCR E", 1, 5, null }, - new object[] { 0x1E, "MVI E, d8", 2, 7, null }, - new object[] { 0x1F, "RAR", 1, 4, null }, - new object[] { 0x20, "*NOP", 1, 4, null }, - new object[] { 0x21, "LXI H, d16", 3, 10, null }, - new object[] { 0x22, "SHLD a16", 3, 16, null }, - new object[] { 0x23, "INX H", 1, 5, null }, - new object[] { 0x24, "INR H", 1, 5, null }, - new object[] { 0x25, "DCR H", 1, 5, null }, - new object[] { 0x26, "MVI H, d8", 2, 7, null }, - new object[] { 0x27, "DAA", 1, 4, null }, - new object[] { 0x28, "*NOP", 1, 4, null }, - new object[] { 0x29, "DAD H", 1, 10, null }, - new object[] { 0x2A, "LHLD a16", 3, 16, null }, - new object[] { 0x2B, "DCX H", 1, 5, null }, - new object[] { 0x2C, "INR L", 1, 5, null }, - new object[] { 0x2D, "DCR L", 1, 5, null }, - new object[] { 0x2E, "MVI L, d8", 2, 7, null }, - new object[] { 0x2F, "CMA", 1, 4, null }, - new object[] { 0x30, "*NOP", 1, 4, null }, - new object[] { 0x31, "LXI SP, d16", 3, 10, null }, - new object[] { 0x32, "STA a16", 3, 13, null }, - new object[] { 0x33, "INX SP", 1, 5, null }, - new object[] { 0x34, "INR M", 1, 10, null }, - new object[] { 0x35, "DCR M", 1, 10, null }, - new object[] { 0x36, "MVI M, d8", 2, 10, null }, - new object[] { 0x37, "STC", 1, 4, null }, - new object[] { 0x38, "*NOP", 1, 4, null }, - new object[] { 0x39, "DAD SP", 1, 10, null }, - new object[] { 0x3A, "LDA a16", 3, 13, null }, - new object[] { 0x3B, "DCX SP", 1, 5, null }, - new object[] { 0x3C, "INR A", 1, 5, null }, - new object[] { 0x3D, "DCR A", 1, 5, null }, - new object[] { 0x3E, "MVI A, d8", 2, 7, null }, - new object[] { 0x3F, "CMC", 1, 4, null }, - new object[] { 0x40, "MOV B, B", 1, 5, null }, - new object[] { 0x41, "MOV B, C", 1, 5, null }, - new object[] { 0x42, "MOV B, D", 1, 5, null }, - new object[] { 0x43, "MOV B, E", 1, 5, null }, - new object[] { 0x44, "MOV B, H", 1, 5, null }, - new object[] { 0x45, "MOV B, L", 1, 5, null }, - new object[] { 0x46, "MOV B, M", 1, 7, null }, - new object[] { 0x47, "MOV B, A", 1, 5, null }, - new object[] { 0x48, "MOV C, B", 1, 5, null }, - new object[] { 0x49, "MOV C, C", 1, 5, null }, - new object[] { 0x4A, "MOV C, D", 1, 5, null }, - new object[] { 0x4B, "MOV C, E", 1, 5, null }, - new object[] { 0x4C, "MOV C, H", 1, 5, null }, - new object[] { 0x4D, "MOV C, L", 1, 5, null }, - new object[] { 0x4E, "MOV C, M", 1, 7, null }, - new object[] { 0x4F, "MOV C, A", 1, 5, null }, - new object[] { 0x50, "MOV D, B", 1, 5, null }, - new object[] { 0x51, "MOV D, C", 1, 5, null }, - new object[] { 0x52, "MOV D, D", 1, 5, null }, - new object[] { 0x53, "MOV D, E", 1, 5, null }, - new object[] { 0x54, "MOV D, H", 1, 5, null }, - new object[] { 0x55, "MOV D, L", 1, 5, null }, - new object[] { 0x56, "MOV D, M", 1, 7, null }, - new object[] { 0x57, "MOV D, A", 1, 5, null }, - new object[] { 0x58, "MOV E, B", 1, 5, null }, - new object[] { 0x59, "MOV E, C", 1, 5, null }, - new object[] { 0x5A, "MOV E, D", 1, 5, null }, - new object[] { 0x5B, "MOV E, E", 1, 5, null }, - new object[] { 0x5C, "MOV E, H", 1, 5, null }, - new object[] { 0x5D, "MOV E, L", 1, 5, null }, - new object[] { 0x5E, "MOV E, M", 1, 7, null }, - new object[] { 0x5F, "MOV E, A", 1, 5, null }, - new object[] { 0x60, "MOV H, B", 1, 5, null }, - new object[] { 0x61, "MOV H, C", 1, 5, null }, - new object[] { 0x62, "MOV H, D", 1, 5, null }, - new object[] { 0x63, "MOV H, E", 1, 5, null }, - new object[] { 0x64, "MOV H, H", 1, 5, null }, - new object[] { 0x65, "MOV H, L", 1, 5, null }, - new object[] { 0x66, "MOV H, M", 1, 7, null }, - new object[] { 0x67, "MOV H, A", 1, 5, null }, - new object[] { 0x68, "MOV L, B", 1, 5, null }, - new object[] { 0x69, "MOV L, C", 1, 5, null }, - new object[] { 0x6A, "MOV L, D", 1, 5, null }, - new object[] { 0x6B, "MOV L, E", 1, 5, null }, - new object[] { 0x6C, "MOV L, H", 1, 5, null }, - new object[] { 0x6D, "MOV L, L", 1, 5, null }, - new object[] { 0x6E, "MOV L, M", 1, 7, null }, - new object[] { 0x6F, "MOV L, A", 1, 5, null }, - new object[] { 0x70, "MOV M, B", 1, 7, null }, - new object[] { 0x71, "MOV M, C", 1, 7, null }, - new object[] { 0x72, "MOV M, D", 1, 7, null }, - new object[] { 0x73, "MOV M, E", 1, 7, null }, - new object[] { 0x74, "MOV M, H", 1, 7, null }, - new object[] { 0x75, "MOV M, L", 1, 7, null }, - new object[] { 0x76, "HLT", 1, 7, null }, - new object[] { 0x77, "MOV M, A", 1, 7, null }, - new object[] { 0x78, "MOV A, B", 1, 5, null }, - new object[] { 0x79, "MOV A, C", 1, 5, null }, - new object[] { 0x7A, "MOV A, D", 1, 5, null }, - new object[] { 0x7B, "MOV A, E", 1, 5, null }, - new object[] { 0x7C, "MOV A, H", 1, 5, null }, - new object[] { 0x7D, "MOV A, L", 1, 5, null }, - new object[] { 0x7E, "MOV A, M", 1, 7, null }, - new object[] { 0x7F, "MOV A, A", 1, 5, null }, - new object[] { 0x80, "ADD B", 1, 4, null }, - new object[] { 0x81, "ADD C", 1, 4, null }, - new object[] { 0x82, "ADD D", 1, 4, null }, - new object[] { 0x83, "ADD E", 1, 4, null }, - new object[] { 0x84, "ADD H", 1, 4, null }, - new object[] { 0x85, "ADD L", 1, 4, null }, - new object[] { 0x86, "ADD M", 1, 7, null }, - new object[] { 0x87, "ADD A", 1, 4, null }, - new object[] { 0x88, "ADC B", 1, 4, null }, - new object[] { 0x89, "ADC C", 1, 4, null }, - new object[] { 0x8A, "ADC D", 1, 4, null }, - new object[] { 0x8B, "ADC E", 1, 4, null }, - new object[] { 0x8C, "ADC H", 1, 4, null }, - new object[] { 0x8D, "ADC L", 1, 4, null }, - new object[] { 0x8E, "ADC M", 1, 7, null }, - new object[] { 0x8F, "ADC A", 1, 4, null }, - new object[] { 0x90, "SUB B", 1, 4, null }, - new object[] { 0x91, "SUB C", 1, 4, null }, - new object[] { 0x92, "SUB D", 1, 4, null }, - new object[] { 0x93, "SUB E", 1, 4, null }, - new object[] { 0x94, "SUB H", 1, 4, null }, - new object[] { 0x95, "SUB L", 1, 4, null }, - new object[] { 0x96, "SUB M", 1, 7, null }, - new object[] { 0x97, "SUB A", 1, 4, null }, - new object[] { 0x98, "SBB B", 1, 4, null }, - new object[] { 0x99, "SBB C", 1, 4, null }, - new object[] { 0x9A, "SBB D", 1, 4, null }, - new object[] { 0x9B, "SBB E", 1, 4, null }, - new object[] { 0x9C, "SBB H", 1, 4, null }, - new object[] { 0x9D, "SBB L", 1, 4, null }, - new object[] { 0x9E, "SBB M", 1, 7, null }, - new object[] { 0x9F, "SBB A", 1, 4, null }, - new object[] { 0xA0, "ANA B", 1, 4, null }, - new object[] { 0xA1, "ANA C", 1, 4, null }, - new object[] { 0xA2, "ANA D", 1, 4, null }, - new object[] { 0xA3, "ANA E", 1, 4, null }, - new object[] { 0xA4, "ANA H", 1, 4, null }, - new object[] { 0xA5, "ANA L", 1, 4, null }, - new object[] { 0xA6, "ANA M", 1, 7, null }, - new object[] { 0xA7, "ANA A", 1, 4, null }, - new object[] { 0xA8, "XRA B", 1, 4, null }, - new object[] { 0xA9, "XRA C", 1, 4, null }, - new object[] { 0xAA, "XRA D", 1, 4, null }, - new object[] { 0xAB, "XRA E", 1, 4, null }, - new object[] { 0xAC, "XRA H", 1, 4, null }, - new object[] { 0xAD, "XRA L", 1, 4, null }, - new object[] { 0xAE, "XRA M", 1, 7, null }, - new object[] { 0xAF, "XRA A", 1, 4, null }, - new object[] { 0xB0, "ORA B", 1, 4, null }, - new object[] { 0xB1, "ORA C", 1, 4, null }, - new object[] { 0xB2, "ORA D", 1, 4, null }, - new object[] { 0xB3, "ORA E", 1, 4, null }, - new object[] { 0xB4, "ORA H", 1, 4, null }, - new object[] { 0xB5, "ORA L", 1, 4, null }, - new object[] { 0xB6, "ORA M", 1, 7, null }, - new object[] { 0xB7, "ORA A", 1, 4, null }, - new object[] { 0xB8, "CMP B", 1, 4, null }, - new object[] { 0xB9, "CMP C", 1, 4, null }, - new object[] { 0xBA, "CMP D", 1, 4, null }, - new object[] { 0xBB, "CMP E", 1, 4, null }, - new object[] { 0xBC, "CMP H", 1, 4, null }, - new object[] { 0xBD, "CMP L", 1, 4, null }, - new object[] { 0xBE, "CMP M", 1, 7, null }, - new object[] { 0xBF, "CMP A", 1, 4, null }, - new object[] { 0xC0, "RNZ", 1, 5, 11 }, - new object[] { 0xC1, "POP B", 1, 10, null }, - new object[] { 0xC2, "JNZ a16", 3, 10, null }, - new object[] { 0xC3, "JMP a16", 3, 10, null }, - new object[] { 0xC4, "CNZ a16", 3, 11, 17 }, - new object[] { 0xC5, "PUSH B", 1, 11, null }, - new object[] { 0xC6, "ADI d8", 2, 7, null }, - new object[] { 0xC7, "RST 0", 1, 11, null }, - new object[] { 0xC8, "RZ", 1, 5, 11 }, - new object[] { 0xC9, "RET", 1, 10, null }, - new object[] { 0xCA, "JZ a16", 3, 10, null }, - new object[] { 0xCB, "*JMP a16", 3, 10, null }, - new object[] { 0xCC, "CZ a16", 3, 11, 17 }, - new object[] { 0xCD, "CALL a16", 3, 17, null }, - new object[] { 0xCE, "ACI d8", 2, 7, null }, - new object[] { 0xCF, "RST 1", 1, 11, null }, - new object[] { 0xD0, "RNC", 1, 5, 11 }, - new object[] { 0xD1, "POP D", 1, 10, null }, - new object[] { 0xD2, "JNC a16", 3, 10, null }, - new object[] { 0xD3, "OUT d8", 2, 10, null }, - new object[] { 0xD4, "CNC a16", 3, 11, 17 }, - new object[] { 0xD5, "PUSH D", 1, 11, null }, - new object[] { 0xD6, "SUI d8", 2, 7, null }, - new object[] { 0xD7, "RST 2", 1, 11, null }, - new object[] { 0xD8, "RC", 1, 5, 11 }, - new object[] { 0xD9, "*RET", 1, 10, null }, - new object[] { 0xDA, "JC a16", 3, 10, null }, - new object[] { 0xDB, "IN d8", 2, 10, null }, - new object[] { 0xDC, "CC a16", 3, 11, 17 }, - new object[] { 0xDD, "*CALL a16", 3, 17, null }, - new object[] { 0xDE, "SBI d8", 2, 7, null }, - new object[] { 0xDF, "RST 3", 1, 11, null }, - new object[] { 0xE0, "RPO", 1, 5, 11 }, - new object[] { 0xE1, "POP H", 1, 10, null }, - new object[] { 0xE2, "JPO a16", 3, 10, null }, - new object[] { 0xE3, "XTHL", 1, 18, null }, - new object[] { 0xE4, "CPO a16", 3, 11, 17 }, - new object[] { 0xE5, "PUSH H", 1, 11, null }, - new object[] { 0xE6, "ANI d8", 2, 7, null }, - new object[] { 0xE7, "RST 4", 1, 11, null }, - new object[] { 0xE8, "RPE", 1, 5, 11 }, - new object[] { 0xE9, "PCHL", 1, 5, null }, - new object[] { 0xEA, "JPE a16", 3, 10, null }, - new object[] { 0xEB, "XCHG", 1, 5, null }, - new object[] { 0xEC, "CPE a16", 3, 11, 17 }, - new object[] { 0xED, "*CALL a16", 3, 17, null }, - new object[] { 0xEE, "XRI d8", 2, 7, null }, - new object[] { 0xEF, "RST 5", 1, 11, null }, - new object[] { 0xF0, "RP", 1, 5, 11 }, - new object[] { 0xF1, "POP PSW", 1, 10, null }, - new object[] { 0xF2, "JP a16", 3, 10, null }, - new object[] { 0xF3, "DI", 1, 4, null }, - new object[] { 0xF4, "CP a16", 3, 11, 17 }, - new object[] { 0xF5, "PUSH PSW", 1, 11, null }, - new object[] { 0xF6, "ORI d8", 2, 7, null }, - new object[] { 0xF7, "RST 6", 1, 11, null }, - new object[] { 0xF8, "RM", 1, 5, 11 }, - new object[] { 0xF9, "SPHL", 1, 5, null }, - new object[] { 0xFA, "JM a16", 3, 10, null }, - new object[] { 0xFB, "EI", 1, 4, null }, - new object[] { 0xFC, "CM a16", 3, 11, 17 }, - new object[] { 0xFD, "*CALL a16", 3, 17, null }, - new object[] { 0xFE, "CPI d8", 2, 7, null }, - new object[] { 0xFF, "RST 7", 1, 11, null } - }; - - public InstructionMetaDataTests() - { - _opcodes = OpcodeTable.Opcodes; - } - - [Theory] - [MemberData(nameof(OpcodeData))] - public void OpcodeMetaDataShouldMatch(int index, string mnenomic, ushort length, int cycles, int? cyclesBranch) - { - // Act - var op = _opcodes[index]; - - // Assert - Assert.Equal(mnenomic, op.Mnenomic); - Assert.Equal(length, op.Length); - Assert.Equal(cycles, op.Cycles); - Assert.Equal(cyclesBranch, op.CyclesBranch); - } - } +using System.Collections.Generic; +using Xunit; + +namespace Intel8080.Emulator.Tests.Instructions; + +public class InstructionMetaDataTests +{ + private readonly Opcode[] _opcodes; + + public static IEnumerable OpcodeData => new List + { + new object[] { 0x00, "NOP", 1, 4, null }, + new object[] { 0x01, "LXI B, d16", 3, 10, null }, + new object[] { 0x02, "STAX B", 1, 7, null }, + new object[] { 0x03, "INX B", 1, 5, null }, + new object[] { 0x04, "INR B", 1, 5, null }, + new object[] { 0x05, "DCR B", 1, 5, null }, + new object[] { 0x06, "MVI B, d8", 2, 7, null }, + new object[] { 0x07, "RLC", 1, 4, null }, + new object[] { 0x08, "*NOP", 1, 4, null }, + new object[] { 0x09, "DAD B", 1, 10, null }, + new object[] { 0x0A, "LDAX B", 1, 7, null }, + new object[] { 0x0B, "DCX B", 1, 5, null }, + new object[] { 0x0C, "INR C", 1, 5, null }, + new object[] { 0x0D, "DCR C", 1, 5, null }, + new object[] { 0x0E, "MVI C, d8", 2, 7, null }, + new object[] { 0x0F, "RRC", 1, 4, null }, + new object[] { 0x10, "*NOP", 1, 4, null }, + new object[] { 0x11, "LXI D, d16", 3, 10, null }, + new object[] { 0x12, "STAX D", 1, 7, null }, + new object[] { 0x13, "INX D", 1, 5, null }, + new object[] { 0x14, "INR D", 1, 5, null }, + new object[] { 0x15, "DCR D", 1, 5, null }, + new object[] { 0x16, "MVI D, d8", 2, 7, null }, + new object[] { 0x17, "RAL", 1, 4, null }, + new object[] { 0x18, "*NOP", 1, 4, null }, + new object[] { 0x19, "DAD D", 1, 10, null }, + new object[] { 0x1A, "LDAX D", 1, 7, null }, + new object[] { 0x1B, "DCX D", 1, 5, null }, + new object[] { 0x1C, "INR E", 1, 5, null }, + new object[] { 0x1D, "DCR E", 1, 5, null }, + new object[] { 0x1E, "MVI E, d8", 2, 7, null }, + new object[] { 0x1F, "RAR", 1, 4, null }, + new object[] { 0x20, "*NOP", 1, 4, null }, + new object[] { 0x21, "LXI H, d16", 3, 10, null }, + new object[] { 0x22, "SHLD a16", 3, 16, null }, + new object[] { 0x23, "INX H", 1, 5, null }, + new object[] { 0x24, "INR H", 1, 5, null }, + new object[] { 0x25, "DCR H", 1, 5, null }, + new object[] { 0x26, "MVI H, d8", 2, 7, null }, + new object[] { 0x27, "DAA", 1, 4, null }, + new object[] { 0x28, "*NOP", 1, 4, null }, + new object[] { 0x29, "DAD H", 1, 10, null }, + new object[] { 0x2A, "LHLD a16", 3, 16, null }, + new object[] { 0x2B, "DCX H", 1, 5, null }, + new object[] { 0x2C, "INR L", 1, 5, null }, + new object[] { 0x2D, "DCR L", 1, 5, null }, + new object[] { 0x2E, "MVI L, d8", 2, 7, null }, + new object[] { 0x2F, "CMA", 1, 4, null }, + new object[] { 0x30, "*NOP", 1, 4, null }, + new object[] { 0x31, "LXI SP, d16", 3, 10, null }, + new object[] { 0x32, "STA a16", 3, 13, null }, + new object[] { 0x33, "INX SP", 1, 5, null }, + new object[] { 0x34, "INR M", 1, 10, null }, + new object[] { 0x35, "DCR M", 1, 10, null }, + new object[] { 0x36, "MVI M, d8", 2, 10, null }, + new object[] { 0x37, "STC", 1, 4, null }, + new object[] { 0x38, "*NOP", 1, 4, null }, + new object[] { 0x39, "DAD SP", 1, 10, null }, + new object[] { 0x3A, "LDA a16", 3, 13, null }, + new object[] { 0x3B, "DCX SP", 1, 5, null }, + new object[] { 0x3C, "INR A", 1, 5, null }, + new object[] { 0x3D, "DCR A", 1, 5, null }, + new object[] { 0x3E, "MVI A, d8", 2, 7, null }, + new object[] { 0x3F, "CMC", 1, 4, null }, + new object[] { 0x40, "MOV B, B", 1, 5, null }, + new object[] { 0x41, "MOV B, C", 1, 5, null }, + new object[] { 0x42, "MOV B, D", 1, 5, null }, + new object[] { 0x43, "MOV B, E", 1, 5, null }, + new object[] { 0x44, "MOV B, H", 1, 5, null }, + new object[] { 0x45, "MOV B, L", 1, 5, null }, + new object[] { 0x46, "MOV B, M", 1, 7, null }, + new object[] { 0x47, "MOV B, A", 1, 5, null }, + new object[] { 0x48, "MOV C, B", 1, 5, null }, + new object[] { 0x49, "MOV C, C", 1, 5, null }, + new object[] { 0x4A, "MOV C, D", 1, 5, null }, + new object[] { 0x4B, "MOV C, E", 1, 5, null }, + new object[] { 0x4C, "MOV C, H", 1, 5, null }, + new object[] { 0x4D, "MOV C, L", 1, 5, null }, + new object[] { 0x4E, "MOV C, M", 1, 7, null }, + new object[] { 0x4F, "MOV C, A", 1, 5, null }, + new object[] { 0x50, "MOV D, B", 1, 5, null }, + new object[] { 0x51, "MOV D, C", 1, 5, null }, + new object[] { 0x52, "MOV D, D", 1, 5, null }, + new object[] { 0x53, "MOV D, E", 1, 5, null }, + new object[] { 0x54, "MOV D, H", 1, 5, null }, + new object[] { 0x55, "MOV D, L", 1, 5, null }, + new object[] { 0x56, "MOV D, M", 1, 7, null }, + new object[] { 0x57, "MOV D, A", 1, 5, null }, + new object[] { 0x58, "MOV E, B", 1, 5, null }, + new object[] { 0x59, "MOV E, C", 1, 5, null }, + new object[] { 0x5A, "MOV E, D", 1, 5, null }, + new object[] { 0x5B, "MOV E, E", 1, 5, null }, + new object[] { 0x5C, "MOV E, H", 1, 5, null }, + new object[] { 0x5D, "MOV E, L", 1, 5, null }, + new object[] { 0x5E, "MOV E, M", 1, 7, null }, + new object[] { 0x5F, "MOV E, A", 1, 5, null }, + new object[] { 0x60, "MOV H, B", 1, 5, null }, + new object[] { 0x61, "MOV H, C", 1, 5, null }, + new object[] { 0x62, "MOV H, D", 1, 5, null }, + new object[] { 0x63, "MOV H, E", 1, 5, null }, + new object[] { 0x64, "MOV H, H", 1, 5, null }, + new object[] { 0x65, "MOV H, L", 1, 5, null }, + new object[] { 0x66, "MOV H, M", 1, 7, null }, + new object[] { 0x67, "MOV H, A", 1, 5, null }, + new object[] { 0x68, "MOV L, B", 1, 5, null }, + new object[] { 0x69, "MOV L, C", 1, 5, null }, + new object[] { 0x6A, "MOV L, D", 1, 5, null }, + new object[] { 0x6B, "MOV L, E", 1, 5, null }, + new object[] { 0x6C, "MOV L, H", 1, 5, null }, + new object[] { 0x6D, "MOV L, L", 1, 5, null }, + new object[] { 0x6E, "MOV L, M", 1, 7, null }, + new object[] { 0x6F, "MOV L, A", 1, 5, null }, + new object[] { 0x70, "MOV M, B", 1, 7, null }, + new object[] { 0x71, "MOV M, C", 1, 7, null }, + new object[] { 0x72, "MOV M, D", 1, 7, null }, + new object[] { 0x73, "MOV M, E", 1, 7, null }, + new object[] { 0x74, "MOV M, H", 1, 7, null }, + new object[] { 0x75, "MOV M, L", 1, 7, null }, + new object[] { 0x76, "HLT", 1, 7, null }, + new object[] { 0x77, "MOV M, A", 1, 7, null }, + new object[] { 0x78, "MOV A, B", 1, 5, null }, + new object[] { 0x79, "MOV A, C", 1, 5, null }, + new object[] { 0x7A, "MOV A, D", 1, 5, null }, + new object[] { 0x7B, "MOV A, E", 1, 5, null }, + new object[] { 0x7C, "MOV A, H", 1, 5, null }, + new object[] { 0x7D, "MOV A, L", 1, 5, null }, + new object[] { 0x7E, "MOV A, M", 1, 7, null }, + new object[] { 0x7F, "MOV A, A", 1, 5, null }, + new object[] { 0x80, "ADD B", 1, 4, null }, + new object[] { 0x81, "ADD C", 1, 4, null }, + new object[] { 0x82, "ADD D", 1, 4, null }, + new object[] { 0x83, "ADD E", 1, 4, null }, + new object[] { 0x84, "ADD H", 1, 4, null }, + new object[] { 0x85, "ADD L", 1, 4, null }, + new object[] { 0x86, "ADD M", 1, 7, null }, + new object[] { 0x87, "ADD A", 1, 4, null }, + new object[] { 0x88, "ADC B", 1, 4, null }, + new object[] { 0x89, "ADC C", 1, 4, null }, + new object[] { 0x8A, "ADC D", 1, 4, null }, + new object[] { 0x8B, "ADC E", 1, 4, null }, + new object[] { 0x8C, "ADC H", 1, 4, null }, + new object[] { 0x8D, "ADC L", 1, 4, null }, + new object[] { 0x8E, "ADC M", 1, 7, null }, + new object[] { 0x8F, "ADC A", 1, 4, null }, + new object[] { 0x90, "SUB B", 1, 4, null }, + new object[] { 0x91, "SUB C", 1, 4, null }, + new object[] { 0x92, "SUB D", 1, 4, null }, + new object[] { 0x93, "SUB E", 1, 4, null }, + new object[] { 0x94, "SUB H", 1, 4, null }, + new object[] { 0x95, "SUB L", 1, 4, null }, + new object[] { 0x96, "SUB M", 1, 7, null }, + new object[] { 0x97, "SUB A", 1, 4, null }, + new object[] { 0x98, "SBB B", 1, 4, null }, + new object[] { 0x99, "SBB C", 1, 4, null }, + new object[] { 0x9A, "SBB D", 1, 4, null }, + new object[] { 0x9B, "SBB E", 1, 4, null }, + new object[] { 0x9C, "SBB H", 1, 4, null }, + new object[] { 0x9D, "SBB L", 1, 4, null }, + new object[] { 0x9E, "SBB M", 1, 7, null }, + new object[] { 0x9F, "SBB A", 1, 4, null }, + new object[] { 0xA0, "ANA B", 1, 4, null }, + new object[] { 0xA1, "ANA C", 1, 4, null }, + new object[] { 0xA2, "ANA D", 1, 4, null }, + new object[] { 0xA3, "ANA E", 1, 4, null }, + new object[] { 0xA4, "ANA H", 1, 4, null }, + new object[] { 0xA5, "ANA L", 1, 4, null }, + new object[] { 0xA6, "ANA M", 1, 7, null }, + new object[] { 0xA7, "ANA A", 1, 4, null }, + new object[] { 0xA8, "XRA B", 1, 4, null }, + new object[] { 0xA9, "XRA C", 1, 4, null }, + new object[] { 0xAA, "XRA D", 1, 4, null }, + new object[] { 0xAB, "XRA E", 1, 4, null }, + new object[] { 0xAC, "XRA H", 1, 4, null }, + new object[] { 0xAD, "XRA L", 1, 4, null }, + new object[] { 0xAE, "XRA M", 1, 7, null }, + new object[] { 0xAF, "XRA A", 1, 4, null }, + new object[] { 0xB0, "ORA B", 1, 4, null }, + new object[] { 0xB1, "ORA C", 1, 4, null }, + new object[] { 0xB2, "ORA D", 1, 4, null }, + new object[] { 0xB3, "ORA E", 1, 4, null }, + new object[] { 0xB4, "ORA H", 1, 4, null }, + new object[] { 0xB5, "ORA L", 1, 4, null }, + new object[] { 0xB6, "ORA M", 1, 7, null }, + new object[] { 0xB7, "ORA A", 1, 4, null }, + new object[] { 0xB8, "CMP B", 1, 4, null }, + new object[] { 0xB9, "CMP C", 1, 4, null }, + new object[] { 0xBA, "CMP D", 1, 4, null }, + new object[] { 0xBB, "CMP E", 1, 4, null }, + new object[] { 0xBC, "CMP H", 1, 4, null }, + new object[] { 0xBD, "CMP L", 1, 4, null }, + new object[] { 0xBE, "CMP M", 1, 7, null }, + new object[] { 0xBF, "CMP A", 1, 4, null }, + new object[] { 0xC0, "RNZ", 1, 5, 11 }, + new object[] { 0xC1, "POP B", 1, 10, null }, + new object[] { 0xC2, "JNZ a16", 3, 10, null }, + new object[] { 0xC3, "JMP a16", 3, 10, null }, + new object[] { 0xC4, "CNZ a16", 3, 11, 17 }, + new object[] { 0xC5, "PUSH B", 1, 11, null }, + new object[] { 0xC6, "ADI d8", 2, 7, null }, + new object[] { 0xC7, "RST 0", 1, 11, null }, + new object[] { 0xC8, "RZ", 1, 5, 11 }, + new object[] { 0xC9, "RET", 1, 10, null }, + new object[] { 0xCA, "JZ a16", 3, 10, null }, + new object[] { 0xCB, "*JMP a16", 3, 10, null }, + new object[] { 0xCC, "CZ a16", 3, 11, 17 }, + new object[] { 0xCD, "CALL a16", 3, 17, null }, + new object[] { 0xCE, "ACI d8", 2, 7, null }, + new object[] { 0xCF, "RST 1", 1, 11, null }, + new object[] { 0xD0, "RNC", 1, 5, 11 }, + new object[] { 0xD1, "POP D", 1, 10, null }, + new object[] { 0xD2, "JNC a16", 3, 10, null }, + new object[] { 0xD3, "OUT d8", 2, 10, null }, + new object[] { 0xD4, "CNC a16", 3, 11, 17 }, + new object[] { 0xD5, "PUSH D", 1, 11, null }, + new object[] { 0xD6, "SUI d8", 2, 7, null }, + new object[] { 0xD7, "RST 2", 1, 11, null }, + new object[] { 0xD8, "RC", 1, 5, 11 }, + new object[] { 0xD9, "*RET", 1, 10, null }, + new object[] { 0xDA, "JC a16", 3, 10, null }, + new object[] { 0xDB, "IN d8", 2, 10, null }, + new object[] { 0xDC, "CC a16", 3, 11, 17 }, + new object[] { 0xDD, "*CALL a16", 3, 17, null }, + new object[] { 0xDE, "SBI d8", 2, 7, null }, + new object[] { 0xDF, "RST 3", 1, 11, null }, + new object[] { 0xE0, "RPO", 1, 5, 11 }, + new object[] { 0xE1, "POP H", 1, 10, null }, + new object[] { 0xE2, "JPO a16", 3, 10, null }, + new object[] { 0xE3, "XTHL", 1, 18, null }, + new object[] { 0xE4, "CPO a16", 3, 11, 17 }, + new object[] { 0xE5, "PUSH H", 1, 11, null }, + new object[] { 0xE6, "ANI d8", 2, 7, null }, + new object[] { 0xE7, "RST 4", 1, 11, null }, + new object[] { 0xE8, "RPE", 1, 5, 11 }, + new object[] { 0xE9, "PCHL", 1, 5, null }, + new object[] { 0xEA, "JPE a16", 3, 10, null }, + new object[] { 0xEB, "XCHG", 1, 5, null }, + new object[] { 0xEC, "CPE a16", 3, 11, 17 }, + new object[] { 0xED, "*CALL a16", 3, 17, null }, + new object[] { 0xEE, "XRI d8", 2, 7, null }, + new object[] { 0xEF, "RST 5", 1, 11, null }, + new object[] { 0xF0, "RP", 1, 5, 11 }, + new object[] { 0xF1, "POP PSW", 1, 10, null }, + new object[] { 0xF2, "JP a16", 3, 10, null }, + new object[] { 0xF3, "DI", 1, 4, null }, + new object[] { 0xF4, "CP a16", 3, 11, 17 }, + new object[] { 0xF5, "PUSH PSW", 1, 11, null }, + new object[] { 0xF6, "ORI d8", 2, 7, null }, + new object[] { 0xF7, "RST 6", 1, 11, null }, + new object[] { 0xF8, "RM", 1, 5, 11 }, + new object[] { 0xF9, "SPHL", 1, 5, null }, + new object[] { 0xFA, "JM a16", 3, 10, null }, + new object[] { 0xFB, "EI", 1, 4, null }, + new object[] { 0xFC, "CM a16", 3, 11, 17 }, + new object[] { 0xFD, "*CALL a16", 3, 17, null }, + new object[] { 0xFE, "CPI d8", 2, 7, null }, + new object[] { 0xFF, "RST 7", 1, 11, null } + }; + + public InstructionMetaDataTests() + { + _opcodes = OpcodeTable.Opcodes; + } + + [Theory] + [MemberData(nameof(OpcodeData))] + public void OpcodeMetaDataShouldMatch(int index, string mnenomic, ushort length, int cycles, int? cyclesBranch) + { + // Act + var op = _opcodes[index]; + + // Assert + Assert.Equal(mnenomic, op.Mnenomic); + Assert.Equal(length, op.Length); + Assert.Equal(cycles, op.Cycles); + Assert.Equal(cyclesBranch, op.CyclesBranch); + } } \ No newline at end of file diff --git a/Intel8080.Emulator.Tests/Instructions/JumpInstructionTests.cs b/Intel8080.Emulator.Tests/Instructions/JumpInstructionTests.cs index 4171468..5a19bb3 100644 --- a/Intel8080.Emulator.Tests/Instructions/JumpInstructionTests.cs +++ b/Intel8080.Emulator.Tests/Instructions/JumpInstructionTests.cs @@ -1,304 +1,303 @@ -using Intel8080.Emulator.Instructions; -using Moq; -using Xunit; - -namespace Intel8080.Emulator.Tests.Instructions -{ - public class JumpInstructionTests - { - private readonly CPU _cpu; - private readonly Mock _memory; - - public JumpInstructionTests() - { - _memory = new Mock(); - - _cpu = new CPU(_memory.Object); - - _cpu.Registers.PC = 1; - } - - [Fact] - public void JMP_ShouldSetPCToJumpAddr() - { - // Arrange - _memory.Setup(x => x[0x0001]).Returns(0x50); - _memory.Setup(x => x[0x0002]).Returns(0x00); - - // Act - DefaultInstructionSet.JMP(_cpu); - - // Assert - Assert.Equal(0x0050, _cpu.Registers.PC); - } - - [Fact] - public void JNZ_ShouldNotJumpIfZeroFlagIsSet() - { - // Arrange - _memory.Setup(x => x[0x0001]).Returns(0x50); - _memory.Setup(x => x[0x0002]).Returns(0x00); - - _cpu.Flags.Zero = true; - - // Act - DefaultInstructionSet.JNZ(_cpu); - - // Assert - Assert.Equal(0x0003, _cpu.Registers.PC); - } - - [Fact] - public void JNZ_ShouldJumpIfZeroFlagIsFalse() - { - // Arrange - _memory.Setup(x => x[0x0001]).Returns(0x50); - _memory.Setup(x => x[0x0002]).Returns(0x00); - - _cpu.Flags.Zero = false; - - // Act - DefaultInstructionSet.JNZ(_cpu); - - // Assert - Assert.Equal(0x0050, _cpu.Registers.PC); - } - - [Fact] - public void JZ_ShouldNotJumpIfZeroFlagFalse() - { - // Arrange - _memory.Setup(x => x[0x0001]).Returns(0x50); - _memory.Setup(x => x[0x0002]).Returns(0x00); - - _cpu.Flags.Zero = false; - - // Act - DefaultInstructionSet.JZ(_cpu); - - // Assert - Assert.Equal(0x0003, _cpu.Registers.PC); - } - - [Fact] - public void JZ_ShouldJumpIfZeroFlagSet() - { - // Arrange - _memory.Setup(x => x[0x0001]).Returns(0x50); - _memory.Setup(x => x[0x0002]).Returns(0x00); - - _cpu.Flags.Zero = true; - - // Act - DefaultInstructionSet.JZ(_cpu); - - // Assert - Assert.Equal(0x0050, _cpu.Registers.PC); - } - - [Fact] - public void JNC_ShouldNotJumpIfCarryFlagIsSet() - { - // Arrange - _memory.Setup(x => x[0x0001]).Returns(0x50); - _memory.Setup(x => x[0x0002]).Returns(0x00); - - _cpu.Flags.Carry = true; - - // Act - DefaultInstructionSet.JNC(_cpu); - - // Assert - Assert.Equal(0x0003, _cpu.Registers.PC); - } - - [Fact] - public void JNC_ShouldJumpIfCarryFlagIsFalse() - { - // Arrange - _memory.Setup(x => x[0x0001]).Returns(0x50); - _memory.Setup(x => x[0x0002]).Returns(0x00); - - _cpu.Flags.Carry = false; - - // Act - DefaultInstructionSet.JNC(_cpu); - - // Assert - Assert.Equal(0x0050, _cpu.Registers.PC); - } - - [Fact] - public void JC_ShouldNotJumpIfCarryFlagFalse() - { - // Arrange - _memory.Setup(x => x[0x0001]).Returns(0x50); - _memory.Setup(x => x[0x0002]).Returns(0x00); - - _cpu.Flags.Carry = false; - - // Act - DefaultInstructionSet.JC(_cpu); - - // Assert - Assert.Equal(0x0003, _cpu.Registers.PC); - } - - [Fact] - public void JC_ShouldJumpIfCarryFlagSet() - { - // Arrange - _memory.Setup(x => x[0x0001]).Returns(0x50); - _memory.Setup(x => x[0x0002]).Returns(0x00); - - _cpu.Flags.Carry = true; - - // Act - DefaultInstructionSet.JC(_cpu); - - // Assert - Assert.Equal(0x0050, _cpu.Registers.PC); - } - - [Fact] - public void JPO_ShouldNotJumpIfParityEven() - { - // Arrange - _memory.Setup(x => x[0x0001]).Returns(0x50); - _memory.Setup(x => x[0x0002]).Returns(0x00); - - _cpu.Flags.Parity = true; - - // Act - DefaultInstructionSet.JPO(_cpu); - - // Assert - Assert.Equal(0x0003, _cpu.Registers.PC); - } - - [Fact] - public void JPO_ShouldJumpIfParityOdd() - { - // Arrange - _memory.Setup(x => x[0x0001]).Returns(0x50); - _memory.Setup(x => x[0x0002]).Returns(0x00); - - _cpu.Flags.Parity = false; - - // Act - DefaultInstructionSet.JPO(_cpu); - - // Assert - Assert.Equal(0x0050, _cpu.Registers.PC); - } - - [Fact] - public void JPE_ShouldNotJumpIfParityOdd() - { - // Arrange - _memory.Setup(x => x[0x0001]).Returns(0x50); - _memory.Setup(x => x[0x0002]).Returns(0x00); - - _cpu.Flags.Parity = false; - - // Act - DefaultInstructionSet.JPE(_cpu); - - // Assert - Assert.Equal(0x0003, _cpu.Registers.PC); - } - - [Fact] - public void JPE_ShouldJumpIfParityEven() - { - // Arrange - _memory.Setup(x => x[0x0001]).Returns(0x50); - _memory.Setup(x => x[0x0002]).Returns(0x00); - - _cpu.Flags.Parity = true; - - // Act - DefaultInstructionSet.JPE(_cpu); - - // Assert - Assert.Equal(0x0050, _cpu.Registers.PC); - } - - [Fact] - public void JP_ShouldNotJumpIfSignFlagSet() - { - // Arrange - _memory.Setup(x => x[0x0001]).Returns(0x50); - _memory.Setup(x => x[0x0002]).Returns(0x00); - - _cpu.Flags.Sign = true; - - // Act - DefaultInstructionSet.JP(_cpu); - - // Assert - Assert.Equal(0x0003, _cpu.Registers.PC); - } - - [Fact] - public void JP_ShouldJumpIfSignFlagReset() - { - // Arrange - _memory.Setup(x => x[0x0001]).Returns(0x50); - _memory.Setup(x => x[0x0002]).Returns(0x00); - - _cpu.Flags.Sign = false; - - // Act - DefaultInstructionSet.JP(_cpu); - - // Assert - Assert.Equal(0x0050, _cpu.Registers.PC); - } - - [Fact] - public void JM_ShouldNotJumpIfSignFlagReset() - { - // Arrange - _memory.Setup(x => x[0x0001]).Returns(0x50); - _memory.Setup(x => x[0x0002]).Returns(0x00); - - _cpu.Flags.Sign = false; - - // Act - DefaultInstructionSet.JM(_cpu); - - // Assert - Assert.Equal(0x0003, _cpu.Registers.PC); - } - - [Fact] - public void JM_ShouldJumpIfSignFlagSet() - { - // Arrange - _memory.Setup(x => x[0x0001]).Returns(0x50); - _memory.Setup(x => x[0x0002]).Returns(0x00); - - _cpu.Flags.Sign = true; - - // Act - DefaultInstructionSet.JM(_cpu); - - // Assert - Assert.Equal(0x0050, _cpu.Registers.PC); - } - - [Fact] - public void PCHL_ShouldChangePCToHL() - { - // Arrange - _cpu.Registers.HL = 0x413E; - - // Act - DefaultInstructionSet.PCHL(_cpu); - - // Assert - Assert.Equal(0x413E, _cpu.Registers.PC); - } - } +using Intel8080.Emulator.Instructions; +using Moq; +using Xunit; + +namespace Intel8080.Emulator.Tests.Instructions; + +public class JumpInstructionTests +{ + private readonly CPU _cpu; + private readonly Mock _memory; + + public JumpInstructionTests() + { + _memory = new Mock(); + + _cpu = new CPU(_memory.Object); + + _cpu.Registers.PC = 1; + } + + [Fact] + public void JMP_ShouldSetPCToJumpAddr() + { + // Arrange + _memory.Setup(x => x[0x0001]).Returns(0x50); + _memory.Setup(x => x[0x0002]).Returns(0x00); + + // Act + DefaultInstructionSet.JMP(_cpu); + + // Assert + Assert.Equal(0x0050, _cpu.Registers.PC); + } + + [Fact] + public void JNZ_ShouldNotJumpIfZeroFlagIsSet() + { + // Arrange + _memory.Setup(x => x[0x0001]).Returns(0x50); + _memory.Setup(x => x[0x0002]).Returns(0x00); + + _cpu.Flags.Zero = true; + + // Act + DefaultInstructionSet.JNZ(_cpu); + + // Assert + Assert.Equal(0x0003, _cpu.Registers.PC); + } + + [Fact] + public void JNZ_ShouldJumpIfZeroFlagIsFalse() + { + // Arrange + _memory.Setup(x => x[0x0001]).Returns(0x50); + _memory.Setup(x => x[0x0002]).Returns(0x00); + + _cpu.Flags.Zero = false; + + // Act + DefaultInstructionSet.JNZ(_cpu); + + // Assert + Assert.Equal(0x0050, _cpu.Registers.PC); + } + + [Fact] + public void JZ_ShouldNotJumpIfZeroFlagFalse() + { + // Arrange + _memory.Setup(x => x[0x0001]).Returns(0x50); + _memory.Setup(x => x[0x0002]).Returns(0x00); + + _cpu.Flags.Zero = false; + + // Act + DefaultInstructionSet.JZ(_cpu); + + // Assert + Assert.Equal(0x0003, _cpu.Registers.PC); + } + + [Fact] + public void JZ_ShouldJumpIfZeroFlagSet() + { + // Arrange + _memory.Setup(x => x[0x0001]).Returns(0x50); + _memory.Setup(x => x[0x0002]).Returns(0x00); + + _cpu.Flags.Zero = true; + + // Act + DefaultInstructionSet.JZ(_cpu); + + // Assert + Assert.Equal(0x0050, _cpu.Registers.PC); + } + + [Fact] + public void JNC_ShouldNotJumpIfCarryFlagIsSet() + { + // Arrange + _memory.Setup(x => x[0x0001]).Returns(0x50); + _memory.Setup(x => x[0x0002]).Returns(0x00); + + _cpu.Flags.Carry = true; + + // Act + DefaultInstructionSet.JNC(_cpu); + + // Assert + Assert.Equal(0x0003, _cpu.Registers.PC); + } + + [Fact] + public void JNC_ShouldJumpIfCarryFlagIsFalse() + { + // Arrange + _memory.Setup(x => x[0x0001]).Returns(0x50); + _memory.Setup(x => x[0x0002]).Returns(0x00); + + _cpu.Flags.Carry = false; + + // Act + DefaultInstructionSet.JNC(_cpu); + + // Assert + Assert.Equal(0x0050, _cpu.Registers.PC); + } + + [Fact] + public void JC_ShouldNotJumpIfCarryFlagFalse() + { + // Arrange + _memory.Setup(x => x[0x0001]).Returns(0x50); + _memory.Setup(x => x[0x0002]).Returns(0x00); + + _cpu.Flags.Carry = false; + + // Act + DefaultInstructionSet.JC(_cpu); + + // Assert + Assert.Equal(0x0003, _cpu.Registers.PC); + } + + [Fact] + public void JC_ShouldJumpIfCarryFlagSet() + { + // Arrange + _memory.Setup(x => x[0x0001]).Returns(0x50); + _memory.Setup(x => x[0x0002]).Returns(0x00); + + _cpu.Flags.Carry = true; + + // Act + DefaultInstructionSet.JC(_cpu); + + // Assert + Assert.Equal(0x0050, _cpu.Registers.PC); + } + + [Fact] + public void JPO_ShouldNotJumpIfParityEven() + { + // Arrange + _memory.Setup(x => x[0x0001]).Returns(0x50); + _memory.Setup(x => x[0x0002]).Returns(0x00); + + _cpu.Flags.Parity = true; + + // Act + DefaultInstructionSet.JPO(_cpu); + + // Assert + Assert.Equal(0x0003, _cpu.Registers.PC); + } + + [Fact] + public void JPO_ShouldJumpIfParityOdd() + { + // Arrange + _memory.Setup(x => x[0x0001]).Returns(0x50); + _memory.Setup(x => x[0x0002]).Returns(0x00); + + _cpu.Flags.Parity = false; + + // Act + DefaultInstructionSet.JPO(_cpu); + + // Assert + Assert.Equal(0x0050, _cpu.Registers.PC); + } + + [Fact] + public void JPE_ShouldNotJumpIfParityOdd() + { + // Arrange + _memory.Setup(x => x[0x0001]).Returns(0x50); + _memory.Setup(x => x[0x0002]).Returns(0x00); + + _cpu.Flags.Parity = false; + + // Act + DefaultInstructionSet.JPE(_cpu); + + // Assert + Assert.Equal(0x0003, _cpu.Registers.PC); + } + + [Fact] + public void JPE_ShouldJumpIfParityEven() + { + // Arrange + _memory.Setup(x => x[0x0001]).Returns(0x50); + _memory.Setup(x => x[0x0002]).Returns(0x00); + + _cpu.Flags.Parity = true; + + // Act + DefaultInstructionSet.JPE(_cpu); + + // Assert + Assert.Equal(0x0050, _cpu.Registers.PC); + } + + [Fact] + public void JP_ShouldNotJumpIfSignFlagSet() + { + // Arrange + _memory.Setup(x => x[0x0001]).Returns(0x50); + _memory.Setup(x => x[0x0002]).Returns(0x00); + + _cpu.Flags.Sign = true; + + // Act + DefaultInstructionSet.JP(_cpu); + + // Assert + Assert.Equal(0x0003, _cpu.Registers.PC); + } + + [Fact] + public void JP_ShouldJumpIfSignFlagReset() + { + // Arrange + _memory.Setup(x => x[0x0001]).Returns(0x50); + _memory.Setup(x => x[0x0002]).Returns(0x00); + + _cpu.Flags.Sign = false; + + // Act + DefaultInstructionSet.JP(_cpu); + + // Assert + Assert.Equal(0x0050, _cpu.Registers.PC); + } + + [Fact] + public void JM_ShouldNotJumpIfSignFlagReset() + { + // Arrange + _memory.Setup(x => x[0x0001]).Returns(0x50); + _memory.Setup(x => x[0x0002]).Returns(0x00); + + _cpu.Flags.Sign = false; + + // Act + DefaultInstructionSet.JM(_cpu); + + // Assert + Assert.Equal(0x0003, _cpu.Registers.PC); + } + + [Fact] + public void JM_ShouldJumpIfSignFlagSet() + { + // Arrange + _memory.Setup(x => x[0x0001]).Returns(0x50); + _memory.Setup(x => x[0x0002]).Returns(0x00); + + _cpu.Flags.Sign = true; + + // Act + DefaultInstructionSet.JM(_cpu); + + // Assert + Assert.Equal(0x0050, _cpu.Registers.PC); + } + + [Fact] + public void PCHL_ShouldChangePCToHL() + { + // Arrange + _cpu.Registers.HL = 0x413E; + + // Act + DefaultInstructionSet.PCHL(_cpu); + + // Assert + Assert.Equal(0x413E, _cpu.Registers.PC); + } } \ No newline at end of file diff --git a/Intel8080.Emulator.Tests/Instructions/RegisterPairInstructionTests.cs b/Intel8080.Emulator.Tests/Instructions/RegisterPairInstructionTests.cs index 08a96eb..66879cf 100644 --- a/Intel8080.Emulator.Tests/Instructions/RegisterPairInstructionTests.cs +++ b/Intel8080.Emulator.Tests/Instructions/RegisterPairInstructionTests.cs @@ -1,699 +1,698 @@ -using Intel8080.Emulator.Instructions; -using Moq; -using Xunit; - -namespace Intel8080.Emulator.Tests.Instructions -{ - public class RegisterPairInstructionTests - { - private readonly CPU _cpu; - private readonly Mock _memory; - - public RegisterPairInstructionTests() - { - _memory = new Mock(); - _cpu = new CPU(_memory.Object); - } - - [Fact] - public void INX_B_ShouldIncrementByOne() - { - // Arrange - _cpu.Registers.BC = 0x1234; - - // Act - DefaultInstructionSet.INX_B(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x1235, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void INX_B_ShouldBeSetToZeroIfOverflow() - { - // Arrange - _cpu.Registers.BC = 0xFFFF; - - // Act - DefaultInstructionSet.INX_B(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void INX_D_ShouldIncrementByOne() - { - // Arrange - _cpu.Registers.DE = 0x1234; - - // Act - DefaultInstructionSet.INX_D(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x1235, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void INX_D_ShouldBeSetToZeroIfOverflow() - { - // Arrange - _cpu.Registers.DE = 0xFFFF; - - // Act - DefaultInstructionSet.INX_D(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void INX_H_ShouldIncrementByOne() - { - // Arrange - _cpu.Registers.HL = 0x1234; - - // Act - DefaultInstructionSet.INX_H(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x1235, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void INX_H_ShouldBeSetToZeroIfOverflow() - { - // Arrange - _cpu.Registers.HL = 0xFFFF; - - // Act - DefaultInstructionSet.INX_H(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void INX_SP_ShouldIncrementByOne() - { - // Arrange - _cpu.Registers.SP = 0x1234; - - // Act - DefaultInstructionSet.INX_SP(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x1235, _cpu.Registers.SP); - } - - [Fact] - public void INX_SP_ShouldBeSetToZeroIfOverflow() - { - // Arrange - _cpu.Registers.SP = 0xFFFF; - - // Act - DefaultInstructionSet.INX_SP(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void DCX_B_ShouldIncrementByOne() - { - // Arrange - _cpu.Registers.BC = 0x1234; - - // Act - DefaultInstructionSet.DCX_B(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x1233, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void DCX_B_ShouldBeSetToMaxIfUnderflow() - { - // Arrange - _cpu.Registers.BC = 0x0000; - - // Act - DefaultInstructionSet.DCX_B(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0xFFFF, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void DCX_D_ShouldIncrementByOne() - { - // Arrange - _cpu.Registers.DE = 0x1234; - - // Act - DefaultInstructionSet.DCX_D(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x1233, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void DCX_D_ShouldBeSetToMaxIfUnderflow() - { - // Arrange - _cpu.Registers.DE = 0x0000; - - // Act - DefaultInstructionSet.DCX_D(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0xFFFF, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void DCX_H_ShouldIncrementByOne() - { - // Arrange - _cpu.Registers.HL = 0x1234; - - // Act - DefaultInstructionSet.DCX_H(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x1233, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void DCX_H_ShouldBeSetToMaxIfUnderflow() - { - // Arrange - _cpu.Registers.HL = 0x0000; - - // Act - DefaultInstructionSet.DCX_H(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0xFFFF, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void DCX_SP_ShouldDecrementByOne() - { - // Arrange - _cpu.Registers.SP = 0x1234; - - // Act - DefaultInstructionSet.DCX_SP(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x1233, _cpu.Registers.SP); - } - - [Fact] - public void DCX_SP_ShouldBeSetToMaxIfUnderflow() - { - // Arrange - _cpu.Registers.SP = 0x0000; - - // Act - DefaultInstructionSet.DCX_SP(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0xFFFF, _cpu.Registers.SP); - } - - [Fact] - public void DAD_B_ShouldAddBCToHL() - { - // Arrange - _cpu.Registers.BC = 0x339F; - _cpu.Registers.HL = 0xA17B; - - // Act - DefaultInstructionSet.DAD_B(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x339F, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0xD51A, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void DAD_B_ShouldSetCarryFlag() - { - // Arrange - _cpu.Registers.BC = 0x0001; - _cpu.Registers.HL = 0xFFFF; - - // Act - DefaultInstructionSet.DAD_B(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0001, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Carry); - } - - [Fact] - public void DAD_D_ShouldAddDEToHL() - { - // Arrange - _cpu.Registers.DE = 0x339F; - _cpu.Registers.HL = 0xA17B; - - // Act - DefaultInstructionSet.DAD_D(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x339F, _cpu.Registers.DE); - Assert.Equal(0xD51A, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void DAD_D_ShouldSetCarryFlag() - { - // Arrange - _cpu.Registers.DE = 0x0001; - _cpu.Registers.HL = 0xFFFF; - - // Act - DefaultInstructionSet.DAD_D(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0001, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Carry); - } - - [Fact] - public void DAD_H_ShouldAddHLToHL() - { - // Arrange - _cpu.Registers.HL = 0x339F; - - // Act - DefaultInstructionSet.DAD_H(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x673E, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void DAD_H_ShouldSetCarryFlag() - { - // Arrange - _cpu.Registers.HL = 0xFFFF; - - // Act - DefaultInstructionSet.DAD_H(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0xFFFE, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Carry); - } - - [Fact] - public void DAD_SP_ShouldAddSPToHL() - { - // Arrange - _cpu.Registers.HL = 0x339F; - _cpu.Registers.SP = 0xA17B; - - // Act - DefaultInstructionSet.DAD_SP(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0xD51A, _cpu.Registers.HL); - Assert.Equal(0xA17B, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void DAD_SP_ShouldSetCarryFlag() - { - // Arrange - _cpu.Registers.HL = 0xFFFF; - _cpu.Registers.SP = 0x0001; - - // Act - DefaultInstructionSet.DAD_SP(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0001, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Carry); - } - - [Fact] - public void POP_B_ShouldPopStackIntoBC() - { - // Arrange - _memory.Setup(x => x[0x0010]).Returns(0xFF); - _memory.Setup(x => x[0x0011]).Returns(0xFE); - - _cpu.Registers.SP = 0x0010; - - // Act - DefaultInstructionSet.POP_B(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0xFEFF, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0012, _cpu.Registers.SP); - } - - [Fact] - public void PUSH_B_ShouldPushBCToStack() - { - // Arrange - var memory = new DefaultMemory(0x100); - var cpu = new CPU(memory); - - cpu.Registers.BC = 0xFEFF; - - cpu.Registers.SP = 0x0012; - - // Act - DefaultInstructionSet.PUSH_B(cpu); - - // Assert - Assert.Equal(0x00, cpu.Registers.A); - Assert.Equal(0xFEFF, cpu.Registers.BC); - Assert.Equal(0x0000, cpu.Registers.DE); - Assert.Equal(0x0000, cpu.Registers.HL); - Assert.Equal(0x0010, cpu.Registers.SP); - - Assert.Equal(0xFF, cpu.Memory[0x0010]); - Assert.Equal(0xFE, cpu.Memory[0x0011]); - } - - [Fact] - public void POP_D_ShouldPopStackIntoDE() - { - // Arrange - _memory.Setup(x => x[0x0010]).Returns(0xFF); - _memory.Setup(x => x[0x0011]).Returns(0xFE); - - _cpu.Registers.SP = 0x0010; - - // Act - DefaultInstructionSet.POP_D(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0xFEFF, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0012, _cpu.Registers.SP); - } - - [Fact] - public void PUSH_D_ShouldPushDEToStack() - { - // Arrange - var memory = new DefaultMemory(0x100); - var cpu = new CPU(memory); - - cpu.Registers.DE = 0xFEFF; - - cpu.Registers.SP = 0x0012; - - // Act - DefaultInstructionSet.PUSH_D(cpu); - - // Assert - Assert.Equal(0x00, cpu.Registers.A); - Assert.Equal(0x0000, cpu.Registers.BC); - Assert.Equal(0xFEFF, cpu.Registers.DE); - Assert.Equal(0x0000, cpu.Registers.HL); - Assert.Equal(0x0010, cpu.Registers.SP); - - Assert.Equal(0xFF, cpu.Memory[0x0010]); - Assert.Equal(0xFE, cpu.Memory[0x0011]); - } - - [Fact] - public void POP_H_ShouldPopStackIntoHL() - { - // Arrange - _memory.Setup(x => x[0x0010]).Returns(0xFF); - _memory.Setup(x => x[0x0011]).Returns(0xFE); - - _cpu.Registers.SP = 0x0010; - - // Act - DefaultInstructionSet.POP_H(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0xFEFF, _cpu.Registers.HL); - Assert.Equal(0x0012, _cpu.Registers.SP); - } - - [Fact] - public void PUSH_H_ShouldPushHLToStack() - { - // Arrange - var memory = new DefaultMemory(0x100); - var cpu = new CPU(memory); - - cpu.Registers.HL = 0xFEFF; - - cpu.Registers.SP = 0x0012; - - // Act - DefaultInstructionSet.PUSH_H(cpu); - - // Assert - Assert.Equal(0x00, cpu.Registers.A); - Assert.Equal(0x0000, cpu.Registers.BC); - Assert.Equal(0x0000, cpu.Registers.DE); - Assert.Equal(0xFEFF, cpu.Registers.HL); - Assert.Equal(0x0010, cpu.Registers.SP); - - Assert.Equal(0xFF, cpu.Memory[0x0010]); - Assert.Equal(0xFE, cpu.Memory[0x0011]); - } - - [Fact] - public void POP_PSW_ShouldPopStackIntoAandFlags() - { - // Arrange - _memory.Setup(x => x[0x0010]).Returns(0xFF); - _memory.Setup(x => x[0x0011]).Returns(0x42); - - _cpu.Registers.SP = 0x0010; - - // Act - DefaultInstructionSet.POP_PSW(_cpu); - - // Assert - Assert.Equal(0x42, _cpu.Registers.A); - Assert.Equal(0xD7, _cpu.Flags.F); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0012, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.True(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - Assert.True(_cpu.Flags.Carry); - } - - [Fact] - public void PUSH_PSW_ShouldPushAccumulatorAndFlagsOntoStack() - { - // Arrange - var memory = new DefaultMemory(0x100); - var cpu = new CPU(memory); - - cpu.Registers.A = 0x42; - cpu.Flags.F = 0xFF; - - cpu.Registers.SP = 0x0012; - - // Act - DefaultInstructionSet.PUSH_PSW(cpu); - - // Assert - Assert.Equal(0x42, cpu.Registers.A); - Assert.Equal(0x0000, cpu.Registers.BC); - Assert.Equal(0x0000, cpu.Registers.DE); - Assert.Equal(0x0000, cpu.Registers.HL); - Assert.Equal(0x0010, cpu.Registers.SP); - - Assert.Equal(0xFF, cpu.Memory[0x0010]); - Assert.Equal(0x42, cpu.Memory[0x0011]); - } - - [Fact] - public void XCHG_ShouldSwapContentsHLandDE() - { - // Arrange - _cpu.Registers.DE = 0x3355; - _cpu.Registers.HL = 0x00FF; - - // Act - DefaultInstructionSet.XCHG(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x00FF, _cpu.Registers.DE); - Assert.Equal(0x3355, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - - [Fact] - public void XHTL_ShouldLoadHLWithStackMemory() - { - // Arrange - var memory = new DefaultMemory(0x100); - var cpu = new CPU(memory); - - cpu.Registers.HL = 0x0B3C; - - cpu.Registers.SP = 0x0012; - - memory[0x0012] = 0xF0; - memory[0x0013] = 0x0D; - - // Act - DefaultInstructionSet.XTHL(cpu); - - // Assert - Assert.Equal(0x00, cpu.Registers.A); - Assert.Equal(0x0000, cpu.Registers.BC); - Assert.Equal(0x0000, cpu.Registers.DE); - Assert.Equal(0x0DF0, cpu.Registers.HL); - Assert.Equal(0x0012, cpu.Registers.SP); - - Assert.Equal(0x3C, cpu.Memory[0x0012]); - Assert.Equal(0x0B, cpu.Memory[0x0013]); - } - - [Fact] - public void SPHL_ShouldLoadSPWithHLContents() - { - // Arrange - _cpu.Registers.HL = 0x506C; - - // Act - DefaultInstructionSet.SPHL(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x506C, _cpu.Registers.HL); - Assert.Equal(0x506C, _cpu.Registers.SP); - } - } +using Intel8080.Emulator.Instructions; +using Moq; +using Xunit; + +namespace Intel8080.Emulator.Tests.Instructions; + +public class RegisterPairInstructionTests +{ + private readonly CPU _cpu; + private readonly Mock _memory; + + public RegisterPairInstructionTests() + { + _memory = new Mock(); + _cpu = new CPU(_memory.Object); + } + + [Fact] + public void INX_B_ShouldIncrementByOne() + { + // Arrange + _cpu.Registers.BC = 0x1234; + + // Act + DefaultInstructionSet.INX_B(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x1235, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void INX_B_ShouldBeSetToZeroIfOverflow() + { + // Arrange + _cpu.Registers.BC = 0xFFFF; + + // Act + DefaultInstructionSet.INX_B(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void INX_D_ShouldIncrementByOne() + { + // Arrange + _cpu.Registers.DE = 0x1234; + + // Act + DefaultInstructionSet.INX_D(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x1235, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void INX_D_ShouldBeSetToZeroIfOverflow() + { + // Arrange + _cpu.Registers.DE = 0xFFFF; + + // Act + DefaultInstructionSet.INX_D(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void INX_H_ShouldIncrementByOne() + { + // Arrange + _cpu.Registers.HL = 0x1234; + + // Act + DefaultInstructionSet.INX_H(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x1235, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void INX_H_ShouldBeSetToZeroIfOverflow() + { + // Arrange + _cpu.Registers.HL = 0xFFFF; + + // Act + DefaultInstructionSet.INX_H(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void INX_SP_ShouldIncrementByOne() + { + // Arrange + _cpu.Registers.SP = 0x1234; + + // Act + DefaultInstructionSet.INX_SP(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x1235, _cpu.Registers.SP); + } + + [Fact] + public void INX_SP_ShouldBeSetToZeroIfOverflow() + { + // Arrange + _cpu.Registers.SP = 0xFFFF; + + // Act + DefaultInstructionSet.INX_SP(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void DCX_B_ShouldIncrementByOne() + { + // Arrange + _cpu.Registers.BC = 0x1234; + + // Act + DefaultInstructionSet.DCX_B(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x1233, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void DCX_B_ShouldBeSetToMaxIfUnderflow() + { + // Arrange + _cpu.Registers.BC = 0x0000; + + // Act + DefaultInstructionSet.DCX_B(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0xFFFF, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void DCX_D_ShouldIncrementByOne() + { + // Arrange + _cpu.Registers.DE = 0x1234; + + // Act + DefaultInstructionSet.DCX_D(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x1233, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void DCX_D_ShouldBeSetToMaxIfUnderflow() + { + // Arrange + _cpu.Registers.DE = 0x0000; + + // Act + DefaultInstructionSet.DCX_D(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0xFFFF, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void DCX_H_ShouldIncrementByOne() + { + // Arrange + _cpu.Registers.HL = 0x1234; + + // Act + DefaultInstructionSet.DCX_H(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x1233, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void DCX_H_ShouldBeSetToMaxIfUnderflow() + { + // Arrange + _cpu.Registers.HL = 0x0000; + + // Act + DefaultInstructionSet.DCX_H(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0xFFFF, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void DCX_SP_ShouldDecrementByOne() + { + // Arrange + _cpu.Registers.SP = 0x1234; + + // Act + DefaultInstructionSet.DCX_SP(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x1233, _cpu.Registers.SP); + } + + [Fact] + public void DCX_SP_ShouldBeSetToMaxIfUnderflow() + { + // Arrange + _cpu.Registers.SP = 0x0000; + + // Act + DefaultInstructionSet.DCX_SP(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0xFFFF, _cpu.Registers.SP); + } + + [Fact] + public void DAD_B_ShouldAddBCToHL() + { + // Arrange + _cpu.Registers.BC = 0x339F; + _cpu.Registers.HL = 0xA17B; + + // Act + DefaultInstructionSet.DAD_B(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x339F, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0xD51A, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void DAD_B_ShouldSetCarryFlag() + { + // Arrange + _cpu.Registers.BC = 0x0001; + _cpu.Registers.HL = 0xFFFF; + + // Act + DefaultInstructionSet.DAD_B(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0001, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Carry); + } + + [Fact] + public void DAD_D_ShouldAddDEToHL() + { + // Arrange + _cpu.Registers.DE = 0x339F; + _cpu.Registers.HL = 0xA17B; + + // Act + DefaultInstructionSet.DAD_D(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x339F, _cpu.Registers.DE); + Assert.Equal(0xD51A, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void DAD_D_ShouldSetCarryFlag() + { + // Arrange + _cpu.Registers.DE = 0x0001; + _cpu.Registers.HL = 0xFFFF; + + // Act + DefaultInstructionSet.DAD_D(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0001, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Carry); + } + + [Fact] + public void DAD_H_ShouldAddHLToHL() + { + // Arrange + _cpu.Registers.HL = 0x339F; + + // Act + DefaultInstructionSet.DAD_H(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x673E, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void DAD_H_ShouldSetCarryFlag() + { + // Arrange + _cpu.Registers.HL = 0xFFFF; + + // Act + DefaultInstructionSet.DAD_H(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0xFFFE, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Carry); + } + + [Fact] + public void DAD_SP_ShouldAddSPToHL() + { + // Arrange + _cpu.Registers.HL = 0x339F; + _cpu.Registers.SP = 0xA17B; + + // Act + DefaultInstructionSet.DAD_SP(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0xD51A, _cpu.Registers.HL); + Assert.Equal(0xA17B, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void DAD_SP_ShouldSetCarryFlag() + { + // Arrange + _cpu.Registers.HL = 0xFFFF; + _cpu.Registers.SP = 0x0001; + + // Act + DefaultInstructionSet.DAD_SP(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0001, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Carry); + } + + [Fact] + public void POP_B_ShouldPopStackIntoBC() + { + // Arrange + _memory.Setup(x => x[0x0010]).Returns(0xFF); + _memory.Setup(x => x[0x0011]).Returns(0xFE); + + _cpu.Registers.SP = 0x0010; + + // Act + DefaultInstructionSet.POP_B(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0xFEFF, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0012, _cpu.Registers.SP); + } + + [Fact] + public void PUSH_B_ShouldPushBCToStack() + { + // Arrange + var memory = new DefaultMemory(0x100); + var cpu = new CPU(memory); + + cpu.Registers.BC = 0xFEFF; + + cpu.Registers.SP = 0x0012; + + // Act + DefaultInstructionSet.PUSH_B(cpu); + + // Assert + Assert.Equal(0x00, cpu.Registers.A); + Assert.Equal(0xFEFF, cpu.Registers.BC); + Assert.Equal(0x0000, cpu.Registers.DE); + Assert.Equal(0x0000, cpu.Registers.HL); + Assert.Equal(0x0010, cpu.Registers.SP); + + Assert.Equal(0xFF, cpu.Memory[0x0010]); + Assert.Equal(0xFE, cpu.Memory[0x0011]); + } + + [Fact] + public void POP_D_ShouldPopStackIntoDE() + { + // Arrange + _memory.Setup(x => x[0x0010]).Returns(0xFF); + _memory.Setup(x => x[0x0011]).Returns(0xFE); + + _cpu.Registers.SP = 0x0010; + + // Act + DefaultInstructionSet.POP_D(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0xFEFF, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0012, _cpu.Registers.SP); + } + + [Fact] + public void PUSH_D_ShouldPushDEToStack() + { + // Arrange + var memory = new DefaultMemory(0x100); + var cpu = new CPU(memory); + + cpu.Registers.DE = 0xFEFF; + + cpu.Registers.SP = 0x0012; + + // Act + DefaultInstructionSet.PUSH_D(cpu); + + // Assert + Assert.Equal(0x00, cpu.Registers.A); + Assert.Equal(0x0000, cpu.Registers.BC); + Assert.Equal(0xFEFF, cpu.Registers.DE); + Assert.Equal(0x0000, cpu.Registers.HL); + Assert.Equal(0x0010, cpu.Registers.SP); + + Assert.Equal(0xFF, cpu.Memory[0x0010]); + Assert.Equal(0xFE, cpu.Memory[0x0011]); + } + + [Fact] + public void POP_H_ShouldPopStackIntoHL() + { + // Arrange + _memory.Setup(x => x[0x0010]).Returns(0xFF); + _memory.Setup(x => x[0x0011]).Returns(0xFE); + + _cpu.Registers.SP = 0x0010; + + // Act + DefaultInstructionSet.POP_H(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0xFEFF, _cpu.Registers.HL); + Assert.Equal(0x0012, _cpu.Registers.SP); + } + + [Fact] + public void PUSH_H_ShouldPushHLToStack() + { + // Arrange + var memory = new DefaultMemory(0x100); + var cpu = new CPU(memory); + + cpu.Registers.HL = 0xFEFF; + + cpu.Registers.SP = 0x0012; + + // Act + DefaultInstructionSet.PUSH_H(cpu); + + // Assert + Assert.Equal(0x00, cpu.Registers.A); + Assert.Equal(0x0000, cpu.Registers.BC); + Assert.Equal(0x0000, cpu.Registers.DE); + Assert.Equal(0xFEFF, cpu.Registers.HL); + Assert.Equal(0x0010, cpu.Registers.SP); + + Assert.Equal(0xFF, cpu.Memory[0x0010]); + Assert.Equal(0xFE, cpu.Memory[0x0011]); + } + + [Fact] + public void POP_PSW_ShouldPopStackIntoAandFlags() + { + // Arrange + _memory.Setup(x => x[0x0010]).Returns(0xFF); + _memory.Setup(x => x[0x0011]).Returns(0x42); + + _cpu.Registers.SP = 0x0010; + + // Act + DefaultInstructionSet.POP_PSW(_cpu); + + // Assert + Assert.Equal(0x42, _cpu.Registers.A); + Assert.Equal(0xD7, _cpu.Flags.F); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0012, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.True(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + Assert.True(_cpu.Flags.Carry); + } + + [Fact] + public void PUSH_PSW_ShouldPushAccumulatorAndFlagsOntoStack() + { + // Arrange + var memory = new DefaultMemory(0x100); + var cpu = new CPU(memory); + + cpu.Registers.A = 0x42; + cpu.Flags.F = 0xFF; + + cpu.Registers.SP = 0x0012; + + // Act + DefaultInstructionSet.PUSH_PSW(cpu); + + // Assert + Assert.Equal(0x42, cpu.Registers.A); + Assert.Equal(0x0000, cpu.Registers.BC); + Assert.Equal(0x0000, cpu.Registers.DE); + Assert.Equal(0x0000, cpu.Registers.HL); + Assert.Equal(0x0010, cpu.Registers.SP); + + Assert.Equal(0xFF, cpu.Memory[0x0010]); + Assert.Equal(0x42, cpu.Memory[0x0011]); + } + + [Fact] + public void XCHG_ShouldSwapContentsHLandDE() + { + // Arrange + _cpu.Registers.DE = 0x3355; + _cpu.Registers.HL = 0x00FF; + + // Act + DefaultInstructionSet.XCHG(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x00FF, _cpu.Registers.DE); + Assert.Equal(0x3355, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } + + [Fact] + public void XHTL_ShouldLoadHLWithStackMemory() + { + // Arrange + var memory = new DefaultMemory(0x100); + var cpu = new CPU(memory); + + cpu.Registers.HL = 0x0B3C; + + cpu.Registers.SP = 0x0012; + + memory[0x0012] = 0xF0; + memory[0x0013] = 0x0D; + + // Act + DefaultInstructionSet.XTHL(cpu); + + // Assert + Assert.Equal(0x00, cpu.Registers.A); + Assert.Equal(0x0000, cpu.Registers.BC); + Assert.Equal(0x0000, cpu.Registers.DE); + Assert.Equal(0x0DF0, cpu.Registers.HL); + Assert.Equal(0x0012, cpu.Registers.SP); + + Assert.Equal(0x3C, cpu.Memory[0x0012]); + Assert.Equal(0x0B, cpu.Memory[0x0013]); + } + + [Fact] + public void SPHL_ShouldLoadSPWithHLContents() + { + // Arrange + _cpu.Registers.HL = 0x506C; + + // Act + DefaultInstructionSet.SPHL(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x506C, _cpu.Registers.HL); + Assert.Equal(0x506C, _cpu.Registers.SP); + } } \ No newline at end of file diff --git a/Intel8080.Emulator.Tests/Instructions/ReturnInstructionTests.cs b/Intel8080.Emulator.Tests/Instructions/ReturnInstructionTests.cs index 08e5e7e..5a7c2cc 100644 --- a/Intel8080.Emulator.Tests/Instructions/ReturnInstructionTests.cs +++ b/Intel8080.Emulator.Tests/Instructions/ReturnInstructionTests.cs @@ -1,323 +1,322 @@ -using Intel8080.Emulator.Instructions; -using Moq; -using Xunit; - -namespace Intel8080.Emulator.Tests.Instructions -{ - public class ReturnInstructionTests - { - private readonly CPU _cpu; - private readonly Mock _memory; - - public ReturnInstructionTests() - { - _memory = new Mock(); - - _cpu = new CPU(_memory.Object); - } - - [Fact] - public void RET_ShouldReturnFromSubroutine() - { - // Arrange - _memory.Setup(x => x[0x0010]).Returns(0x50); - _memory.Setup(x => x[0x0011]).Returns(0x00); - - _cpu.Registers.SP = 0x0010; - - // Act - DefaultInstructionSet.RET(_cpu); - - // Assert - Assert.Equal(0x0050, _cpu.Registers.PC); - } - - [Fact] - public void RNZ_ShouldNotReturnIfZeroFlagSet() - { - // Arrange - _memory.Setup(x => x[0x0010]).Returns(0x50); - _memory.Setup(x => x[0x0011]).Returns(0x00); - - _cpu.Registers.SP = 0x0010; - - _cpu.Flags.Zero = true; - - // Act - DefaultInstructionSet.RNZ(_cpu); - - // Assert - Assert.Equal(0x0000, _cpu.Registers.PC); - } - - [Fact] - public void RNZ_ShouldReturnIfZeroFlagFalse() - { - // Arrange - _memory.Setup(x => x[0x0010]).Returns(0x50); - _memory.Setup(x => x[0x0011]).Returns(0x00); - - _cpu.Registers.SP = 0x0010; - - _cpu.Flags.Zero = false; - - // Act - DefaultInstructionSet.RNZ(_cpu); - - // Assert - Assert.Equal(0x0050, _cpu.Registers.PC); - } - - [Fact] - public void RZ_ShouldNotReturnIfZeroFlagFalse() - { - // Arrange - _memory.Setup(x => x[0x0010]).Returns(0x50); - _memory.Setup(x => x[0x0011]).Returns(0x00); - - _cpu.Registers.SP = 0x0010; - - _cpu.Flags.Zero = false; - - // Act - DefaultInstructionSet.RZ(_cpu); - - // Assert - Assert.Equal(0x0000, _cpu.Registers.PC); - } - - [Fact] - public void RZ_ShouldReturnIfZeroFlagSet() - { - // Arrange - _memory.Setup(x => x[0x0010]).Returns(0x50); - _memory.Setup(x => x[0x0011]).Returns(0x00); - - _cpu.Registers.SP = 0x0010; - - _cpu.Flags.Zero = true; - - // Act - DefaultInstructionSet.RZ(_cpu); - - // Assert - Assert.Equal(0x0050, _cpu.Registers.PC); - } - - [Fact] - public void RNC_ShouldNotReturnIfCarryFlagSet() - { - // Arrange - _memory.Setup(x => x[0x0010]).Returns(0x50); - _memory.Setup(x => x[0x0011]).Returns(0x00); - - _cpu.Registers.SP = 0x0010; - - _cpu.Flags.Carry = true; - - // Act - DefaultInstructionSet.RNC(_cpu); - - // Assert - Assert.Equal(0x0000, _cpu.Registers.PC); - } - - [Fact] - public void RNC_ShouldReturnIfCarryFlagFalse() - { - // Arrange - _memory.Setup(x => x[0x0010]).Returns(0x50); - _memory.Setup(x => x[0x0011]).Returns(0x00); - - _cpu.Registers.SP = 0x0010; - - _cpu.Flags.Carry = false; - - // Act - DefaultInstructionSet.RNC(_cpu); - - // Assert - Assert.Equal(0x0050, _cpu.Registers.PC); - } - - [Fact] - public void RC_ShouldNotReturnIfCarryFlagFalse() - { - // Arrange - _memory.Setup(x => x[0x0010]).Returns(0x50); - _memory.Setup(x => x[0x0011]).Returns(0x00); - - _cpu.Registers.SP = 0x0010; - - _cpu.Flags.Carry = false; - - // Act - DefaultInstructionSet.RC(_cpu); - - // Assert - Assert.Equal(0x0000, _cpu.Registers.PC); - } - - [Fact] - public void RC_ShouldReturnIfCarryFlagSet() - { - // Arrange - _memory.Setup(x => x[0x0010]).Returns(0x50); - _memory.Setup(x => x[0x0011]).Returns(0x00); - - _cpu.Registers.SP = 0x0010; - - _cpu.Flags.Carry = true; - - // Act - DefaultInstructionSet.RC(_cpu); - - // Assert - Assert.Equal(0x0050, _cpu.Registers.PC); - } - - [Fact] - public void RPO_ShouldNotReturnIfParityEven() - { - // Arrange - _memory.Setup(x => x[0x0010]).Returns(0x50); - _memory.Setup(x => x[0x0011]).Returns(0x00); - - _cpu.Registers.SP = 0x0010; - - _cpu.Flags.Parity = true; - - // Act - DefaultInstructionSet.RPO(_cpu); - - // Assert - Assert.Equal(0x0000, _cpu.Registers.PC); - } - - [Fact] - public void RPO_ShouldReturnIfParityOdd() - { - // Arrange - _memory.Setup(x => x[0x0010]).Returns(0x50); - _memory.Setup(x => x[0x0011]).Returns(0x00); - - _cpu.Registers.SP = 0x0010; - - _cpu.Flags.Parity = false; - - // Act - DefaultInstructionSet.RPO(_cpu); - - // Assert - Assert.Equal(0x0050, _cpu.Registers.PC); - } - - [Fact] - public void RPE_ShouldNotReturnIfParityOdd() - { - // Arrange - _memory.Setup(x => x[0x0010]).Returns(0x50); - _memory.Setup(x => x[0x0011]).Returns(0x00); - - _cpu.Registers.SP = 0x0010; - - _cpu.Flags.Parity = false; - - // Act - DefaultInstructionSet.RPE(_cpu); - - // Assert - Assert.Equal(0x0000, _cpu.Registers.PC); - } - - [Fact] - public void RPE_ShouldReturnIfParityEven() - { - // Arrange - _memory.Setup(x => x[0x0010]).Returns(0x50); - _memory.Setup(x => x[0x0011]).Returns(0x00); - - _cpu.Registers.SP = 0x0010; - - _cpu.Flags.Parity = true; - - // Act - DefaultInstructionSet.RPE(_cpu); - - // Assert - Assert.Equal(0x0050, _cpu.Registers.PC); - } - - [Fact] - public void RP_ShouldNotReturnIfSignFlagIsSet() - { - // Arrange - _memory.Setup(x => x[0x0010]).Returns(0x50); - _memory.Setup(x => x[0x0011]).Returns(0x00); - - _cpu.Registers.SP = 0x0010; - - _cpu.Flags.Sign = true; - - // Act - DefaultInstructionSet.RP(_cpu); - - // Assert - Assert.Equal(0x0000, _cpu.Registers.PC); - } - - [Fact] - public void RP_ShouldReturnIfSignFlagReset() - { - // Arrange - _memory.Setup(x => x[0x0010]).Returns(0x50); - _memory.Setup(x => x[0x0011]).Returns(0x00); - - _cpu.Registers.SP = 0x0010; - - _cpu.Flags.Sign = false; - - // Act - DefaultInstructionSet.RP(_cpu); - - // Assert - Assert.Equal(0x0050, _cpu.Registers.PC); - } - - [Fact] - public void RM_ShouldNotReturnIfSignFlagReset() - { - // Arrange - _memory.Setup(x => x[0x0010]).Returns(0x50); - _memory.Setup(x => x[0x0011]).Returns(0x00); - - _cpu.Registers.SP = 0x0010; - - _cpu.Flags.Sign = false; - - // Act - DefaultInstructionSet.RM(_cpu); - - // Assert - Assert.Equal(0x0000, _cpu.Registers.PC); - } - - [Fact] - public void RM_ShouldReturnIfSignFlagSet() - { - // Arrange - _memory.Setup(x => x[0x0010]).Returns(0x50); - _memory.Setup(x => x[0x0011]).Returns(0x00); - - _cpu.Registers.SP = 0x0010; - - _cpu.Flags.Sign = true; - - // Act - DefaultInstructionSet.RM(_cpu); - - // Assert - Assert.Equal(0x0050, _cpu.Registers.PC); - } - } +using Intel8080.Emulator.Instructions; +using Moq; +using Xunit; + +namespace Intel8080.Emulator.Tests.Instructions; + +public class ReturnInstructionTests +{ + private readonly CPU _cpu; + private readonly Mock _memory; + + public ReturnInstructionTests() + { + _memory = new Mock(); + + _cpu = new CPU(_memory.Object); + } + + [Fact] + public void RET_ShouldReturnFromSubroutine() + { + // Arrange + _memory.Setup(x => x[0x0010]).Returns(0x50); + _memory.Setup(x => x[0x0011]).Returns(0x00); + + _cpu.Registers.SP = 0x0010; + + // Act + DefaultInstructionSet.RET(_cpu); + + // Assert + Assert.Equal(0x0050, _cpu.Registers.PC); + } + + [Fact] + public void RNZ_ShouldNotReturnIfZeroFlagSet() + { + // Arrange + _memory.Setup(x => x[0x0010]).Returns(0x50); + _memory.Setup(x => x[0x0011]).Returns(0x00); + + _cpu.Registers.SP = 0x0010; + + _cpu.Flags.Zero = true; + + // Act + DefaultInstructionSet.RNZ(_cpu); + + // Assert + Assert.Equal(0x0000, _cpu.Registers.PC); + } + + [Fact] + public void RNZ_ShouldReturnIfZeroFlagFalse() + { + // Arrange + _memory.Setup(x => x[0x0010]).Returns(0x50); + _memory.Setup(x => x[0x0011]).Returns(0x00); + + _cpu.Registers.SP = 0x0010; + + _cpu.Flags.Zero = false; + + // Act + DefaultInstructionSet.RNZ(_cpu); + + // Assert + Assert.Equal(0x0050, _cpu.Registers.PC); + } + + [Fact] + public void RZ_ShouldNotReturnIfZeroFlagFalse() + { + // Arrange + _memory.Setup(x => x[0x0010]).Returns(0x50); + _memory.Setup(x => x[0x0011]).Returns(0x00); + + _cpu.Registers.SP = 0x0010; + + _cpu.Flags.Zero = false; + + // Act + DefaultInstructionSet.RZ(_cpu); + + // Assert + Assert.Equal(0x0000, _cpu.Registers.PC); + } + + [Fact] + public void RZ_ShouldReturnIfZeroFlagSet() + { + // Arrange + _memory.Setup(x => x[0x0010]).Returns(0x50); + _memory.Setup(x => x[0x0011]).Returns(0x00); + + _cpu.Registers.SP = 0x0010; + + _cpu.Flags.Zero = true; + + // Act + DefaultInstructionSet.RZ(_cpu); + + // Assert + Assert.Equal(0x0050, _cpu.Registers.PC); + } + + [Fact] + public void RNC_ShouldNotReturnIfCarryFlagSet() + { + // Arrange + _memory.Setup(x => x[0x0010]).Returns(0x50); + _memory.Setup(x => x[0x0011]).Returns(0x00); + + _cpu.Registers.SP = 0x0010; + + _cpu.Flags.Carry = true; + + // Act + DefaultInstructionSet.RNC(_cpu); + + // Assert + Assert.Equal(0x0000, _cpu.Registers.PC); + } + + [Fact] + public void RNC_ShouldReturnIfCarryFlagFalse() + { + // Arrange + _memory.Setup(x => x[0x0010]).Returns(0x50); + _memory.Setup(x => x[0x0011]).Returns(0x00); + + _cpu.Registers.SP = 0x0010; + + _cpu.Flags.Carry = false; + + // Act + DefaultInstructionSet.RNC(_cpu); + + // Assert + Assert.Equal(0x0050, _cpu.Registers.PC); + } + + [Fact] + public void RC_ShouldNotReturnIfCarryFlagFalse() + { + // Arrange + _memory.Setup(x => x[0x0010]).Returns(0x50); + _memory.Setup(x => x[0x0011]).Returns(0x00); + + _cpu.Registers.SP = 0x0010; + + _cpu.Flags.Carry = false; + + // Act + DefaultInstructionSet.RC(_cpu); + + // Assert + Assert.Equal(0x0000, _cpu.Registers.PC); + } + + [Fact] + public void RC_ShouldReturnIfCarryFlagSet() + { + // Arrange + _memory.Setup(x => x[0x0010]).Returns(0x50); + _memory.Setup(x => x[0x0011]).Returns(0x00); + + _cpu.Registers.SP = 0x0010; + + _cpu.Flags.Carry = true; + + // Act + DefaultInstructionSet.RC(_cpu); + + // Assert + Assert.Equal(0x0050, _cpu.Registers.PC); + } + + [Fact] + public void RPO_ShouldNotReturnIfParityEven() + { + // Arrange + _memory.Setup(x => x[0x0010]).Returns(0x50); + _memory.Setup(x => x[0x0011]).Returns(0x00); + + _cpu.Registers.SP = 0x0010; + + _cpu.Flags.Parity = true; + + // Act + DefaultInstructionSet.RPO(_cpu); + + // Assert + Assert.Equal(0x0000, _cpu.Registers.PC); + } + + [Fact] + public void RPO_ShouldReturnIfParityOdd() + { + // Arrange + _memory.Setup(x => x[0x0010]).Returns(0x50); + _memory.Setup(x => x[0x0011]).Returns(0x00); + + _cpu.Registers.SP = 0x0010; + + _cpu.Flags.Parity = false; + + // Act + DefaultInstructionSet.RPO(_cpu); + + // Assert + Assert.Equal(0x0050, _cpu.Registers.PC); + } + + [Fact] + public void RPE_ShouldNotReturnIfParityOdd() + { + // Arrange + _memory.Setup(x => x[0x0010]).Returns(0x50); + _memory.Setup(x => x[0x0011]).Returns(0x00); + + _cpu.Registers.SP = 0x0010; + + _cpu.Flags.Parity = false; + + // Act + DefaultInstructionSet.RPE(_cpu); + + // Assert + Assert.Equal(0x0000, _cpu.Registers.PC); + } + + [Fact] + public void RPE_ShouldReturnIfParityEven() + { + // Arrange + _memory.Setup(x => x[0x0010]).Returns(0x50); + _memory.Setup(x => x[0x0011]).Returns(0x00); + + _cpu.Registers.SP = 0x0010; + + _cpu.Flags.Parity = true; + + // Act + DefaultInstructionSet.RPE(_cpu); + + // Assert + Assert.Equal(0x0050, _cpu.Registers.PC); + } + + [Fact] + public void RP_ShouldNotReturnIfSignFlagIsSet() + { + // Arrange + _memory.Setup(x => x[0x0010]).Returns(0x50); + _memory.Setup(x => x[0x0011]).Returns(0x00); + + _cpu.Registers.SP = 0x0010; + + _cpu.Flags.Sign = true; + + // Act + DefaultInstructionSet.RP(_cpu); + + // Assert + Assert.Equal(0x0000, _cpu.Registers.PC); + } + + [Fact] + public void RP_ShouldReturnIfSignFlagReset() + { + // Arrange + _memory.Setup(x => x[0x0010]).Returns(0x50); + _memory.Setup(x => x[0x0011]).Returns(0x00); + + _cpu.Registers.SP = 0x0010; + + _cpu.Flags.Sign = false; + + // Act + DefaultInstructionSet.RP(_cpu); + + // Assert + Assert.Equal(0x0050, _cpu.Registers.PC); + } + + [Fact] + public void RM_ShouldNotReturnIfSignFlagReset() + { + // Arrange + _memory.Setup(x => x[0x0010]).Returns(0x50); + _memory.Setup(x => x[0x0011]).Returns(0x00); + + _cpu.Registers.SP = 0x0010; + + _cpu.Flags.Sign = false; + + // Act + DefaultInstructionSet.RM(_cpu); + + // Assert + Assert.Equal(0x0000, _cpu.Registers.PC); + } + + [Fact] + public void RM_ShouldReturnIfSignFlagSet() + { + // Arrange + _memory.Setup(x => x[0x0010]).Returns(0x50); + _memory.Setup(x => x[0x0011]).Returns(0x00); + + _cpu.Registers.SP = 0x0010; + + _cpu.Flags.Sign = true; + + // Act + DefaultInstructionSet.RM(_cpu); + + // Assert + Assert.Equal(0x0050, _cpu.Registers.PC); + } } \ No newline at end of file diff --git a/Intel8080.Emulator.Tests/Instructions/RotateInstructionTests.cs b/Intel8080.Emulator.Tests/Instructions/RotateInstructionTests.cs index 5a0cdd7..a7bda4b 100644 --- a/Intel8080.Emulator.Tests/Instructions/RotateInstructionTests.cs +++ b/Intel8080.Emulator.Tests/Instructions/RotateInstructionTests.cs @@ -1,135 +1,134 @@ -using Intel8080.Emulator.Instructions; -using Moq; -using Xunit; - -namespace Intel8080.Emulator.Tests.Instructions -{ - public class RotateInstructionTests - { - private readonly CPU _cpu; - private readonly Mock _memory; - - public RotateInstructionTests() - { - _memory = new Mock(); - _cpu = new CPU(_memory.Object); - } - - [Fact] - public void RLC_ShouldRotateAcculmuatlorLeftAndSetCarry() - { - // Arrange - _cpu.Registers.A = 0xF2; - - // Act - DefaultInstructionSet.RLC(_cpu); - - // Assert - Assert.Equal(0xE5, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Carry); - } - - [Fact] - public void RRC_ShouldRotateARightAndSetCarry() - { - // Arrange - _cpu.Registers.A = 0xF2; - - // Act - DefaultInstructionSet.RRC(_cpu); - - // Assert - Assert.Equal(0x79, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void RAL_ShouldRotateALeftThroughCarry() - { - // Arrange - _cpu.Registers.A = 0xB5; - - // Act - DefaultInstructionSet.RAL(_cpu); - - // Assert - Assert.Equal(0x6A, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Carry); - } - - [Fact] - public void RAL_ShouldRotateALeftThroughCarry_CarrySet() - { - // Arrange - _cpu.Registers.A = 0xB5; - _cpu.Flags.Carry = true; - - - // Act - DefaultInstructionSet.RAL(_cpu); - - // Assert - Assert.Equal(0x6B, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Carry); - } - - [Fact] - public void RAR_ShouldRotateARightThroughCarry_CarryUnset() - { - // Arrange - _cpu.Registers.A = 0x6A; - - // Act - DefaultInstructionSet.RAR(_cpu); - - // Assert - Assert.Equal(0x35, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Carry); - } - - [Fact] - public void RAR_ShouldRotateARightThroughCarry() - { - // Arrange - _cpu.Registers.A = 0x6A; - _cpu.Flags.Carry = true; - - // Act - DefaultInstructionSet.RAR(_cpu); - - // Assert - Assert.Equal(0xB5, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Carry); - } - } +using Intel8080.Emulator.Instructions; +using Moq; +using Xunit; + +namespace Intel8080.Emulator.Tests.Instructions; + +public class RotateInstructionTests +{ + private readonly CPU _cpu; + private readonly Mock _memory; + + public RotateInstructionTests() + { + _memory = new Mock(); + _cpu = new CPU(_memory.Object); + } + + [Fact] + public void RLC_ShouldRotateAcculmuatlorLeftAndSetCarry() + { + // Arrange + _cpu.Registers.A = 0xF2; + + // Act + DefaultInstructionSet.RLC(_cpu); + + // Assert + Assert.Equal(0xE5, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Carry); + } + + [Fact] + public void RRC_ShouldRotateARightAndSetCarry() + { + // Arrange + _cpu.Registers.A = 0xF2; + + // Act + DefaultInstructionSet.RRC(_cpu); + + // Assert + Assert.Equal(0x79, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void RAL_ShouldRotateALeftThroughCarry() + { + // Arrange + _cpu.Registers.A = 0xB5; + + // Act + DefaultInstructionSet.RAL(_cpu); + + // Assert + Assert.Equal(0x6A, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Carry); + } + + [Fact] + public void RAL_ShouldRotateALeftThroughCarry_CarrySet() + { + // Arrange + _cpu.Registers.A = 0xB5; + _cpu.Flags.Carry = true; + + + // Act + DefaultInstructionSet.RAL(_cpu); + + // Assert + Assert.Equal(0x6B, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Carry); + } + + [Fact] + public void RAR_ShouldRotateARightThroughCarry_CarryUnset() + { + // Arrange + _cpu.Registers.A = 0x6A; + + // Act + DefaultInstructionSet.RAR(_cpu); + + // Assert + Assert.Equal(0x35, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Carry); + } + + [Fact] + public void RAR_ShouldRotateARightThroughCarry() + { + // Arrange + _cpu.Registers.A = 0x6A; + _cpu.Flags.Carry = true; + + // Act + DefaultInstructionSet.RAR(_cpu); + + // Assert + Assert.Equal(0xB5, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Carry); + } } \ No newline at end of file diff --git a/Intel8080.Emulator.Tests/Instructions/SingleRegisterInstructionTests.cs b/Intel8080.Emulator.Tests/Instructions/SingleRegisterInstructionTests.cs index c24eec9..879c6e9 100644 --- a/Intel8080.Emulator.Tests/Instructions/SingleRegisterInstructionTests.cs +++ b/Intel8080.Emulator.Tests/Instructions/SingleRegisterInstructionTests.cs @@ -1,749 +1,747 @@ -using Intel8080.Emulator.Instructions; -using Moq; -using Xunit; - -namespace Intel8080.Emulator.Tests.Instructions -{ - public class SingleRegisterInstructionTests - { - private readonly CPU _cpu; - private readonly IMemory _memory; - - public SingleRegisterInstructionTests() - { - _memory = new DefaultMemory(0x100); - _cpu = new CPU(_memory); - } - - [Fact] - public void INR_B_ShouldIncrementByOne() - { - // Arrange - _cpu.Registers.B = 0x99; - - // Act - DefaultInstructionSet.INR_B(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x9A00, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - } - - [Fact] - public void INR_B_ShouldSetAuxCarry() - { - // Arrange - _cpu.Registers.B = 0xFF; - - // Act - DefaultInstructionSet.INR_B(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.True(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - } - - [Fact] - public void INR_C_ShouldIncrementByOne() - { - // Arrange - _cpu.Registers.C = 0x99; - - // Act - DefaultInstructionSet.INR_C(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x009A, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - } - - [Fact] - public void INR_C_ShouldSetAuxCarry() - { - // Arrange - _cpu.Registers.C = 0xFF; - - // Act - DefaultInstructionSet.INR_C(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.True(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - } - - [Fact] - public void INR_D_ShouldIncrementByOne() - { - // Arrange - _cpu.Registers.D = 0x99; - - // Act - DefaultInstructionSet.INR_D(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x9A00, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - } - - [Fact] - public void INR_D_ShouldSetAuxCarry() - { - // Arrange - _cpu.Registers.D = 0xFF; - - // Act - DefaultInstructionSet.INR_D(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.True(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - } - - [Fact] - public void INR_E_ShouldIncrementByOne() - { - // Arrange - _cpu.Registers.E = 0x99; - - // Act - DefaultInstructionSet.INR_E(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x009A, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - } - - [Fact] - public void INR_E_ShouldSetAuxCarry() - { - // Arrange - _cpu.Registers.E = 0xFF; - - // Act - DefaultInstructionSet.INR_E(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.True(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - } - - [Fact] - public void INR_H_ShouldIncrementByOne() - { - // Arrange - _cpu.Registers.H = 0x99; - - // Act - DefaultInstructionSet.INR_H(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x9A00, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - } - - [Fact] - public void INR_H_ShouldSetAuxCarry() - { - // Arrange - _cpu.Registers.H = 0xFF; - - // Act - DefaultInstructionSet.INR_H(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.True(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - } - - [Fact] - public void INR_L_ShouldIncrementByOne() - { - // Arrange - _cpu.Registers.L = 0x99; - - // Act - DefaultInstructionSet.INR_L(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x009A, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - } - - [Fact] - public void INR_L_ShouldSetAuxCarry() - { - // Arrange - _cpu.Registers.L = 0xFF; - - // Act - DefaultInstructionSet.INR_L(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.True(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - } - - [Fact] - public void INR_M_ShouldIncrementByOne() - { - // Arrange - _cpu.Registers.HL = 0x99; - _cpu.Memory[0x99] = 0x40; - - // Act - DefaultInstructionSet.INR_M(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0099, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.Equal(0x41, _cpu.Memory[0x99]); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - } - - [Fact] - public void INR_A_ShouldIncrementByOne() - { - // Arrange - _cpu.Registers.A = 0x99; - - // Act - DefaultInstructionSet.INR_A(_cpu); - - // Assert - Assert.Equal(0x9A, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - } - - [Fact] - public void INR_A_ShouldSetAuxCarry() - { - // Arrange - _cpu.Registers.A = 0xFF; - - // Act - DefaultInstructionSet.INR_A(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.True(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - } - - [Fact] - public void DCR_B_ShouldDecrementByOne() - { - // Arrange - _cpu.Registers.B = 0xFF; - - // Act - DefaultInstructionSet.DCR_B(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0xFE00, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - } - - [Fact] - public void DCR_B_ShouldSetAuxCarry() - { - // Arrange - _cpu.Registers.B = 0x00; - - // Act - DefaultInstructionSet.DCR_B(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0xFF00, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - } - - [Fact] - public void DCR_C_ShouldDecrementByOne() - { - // Arrange - _cpu.Registers.C = 0xFF; - - // Act - DefaultInstructionSet.DCR_C(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x00FE, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - } - - [Fact] - public void DCR_C_ShouldSetAuxCarry() - { - // Arrange - _cpu.Registers.C = 0x00; - - // Act - DefaultInstructionSet.DCR_C(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x00FF, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - } - - [Fact] - public void DCR_D_ShouldDecrementByOne() - { - // Arrange - _cpu.Registers.D = 0xFF; - - // Act - DefaultInstructionSet.DCR_D(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0xFE00, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - } - - [Fact] - public void DCR_D_ShouldSetAuxCarry() - { - // Arrange - _cpu.Registers.D = 0x00; - - // Act - DefaultInstructionSet.DCR_D(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0xFF00, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - } - - [Fact] - public void DCR_E_ShouldDecrementByOne() - { - // Arrange - _cpu.Registers.E = 0xFF; - - // Act - DefaultInstructionSet.DCR_E(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x00FE, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - } - - [Fact] - public void DCR_E_ShouldSetAuxCarry() - { - // Arrange - _cpu.Registers.E = 0x00; - - // Act - DefaultInstructionSet.DCR_E(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x00FF, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - } - - [Fact] - public void DCR_H_ShouldDecrementByOne() - { - // Arrange - _cpu.Registers.H = 0xFF; - - // Act - DefaultInstructionSet.DCR_H(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0xFE00, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - } - - [Fact] - public void DCR_H_ShouldSetAuxCarry() - { - // Arrange - _cpu.Registers.H = 0x00; - - // Act - DefaultInstructionSet.DCR_H(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0xFF00, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - } - - [Fact] - public void DCR_L_ShouldDecrementByOne() - { - // Arrange - _cpu.Registers.L = 0xFF; - - // Act - DefaultInstructionSet.DCR_L(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x00FE, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - } - - [Fact] - public void DCR_L_ShouldSetAuxCarry() - { - // Arrange - _cpu.Registers.L = 0x00; - - // Act - DefaultInstructionSet.DCR_L(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x00FF, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - } - - [Fact] - public void DCR_M_ShouldDecrementByOne() - { - // Arrange - _cpu.Registers.HL = 0x99; - _cpu.Memory[0x99] = 0xFF; - - // Act - DefaultInstructionSet.DCR_M(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0099, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.Equal(0xFE, _cpu.Memory[0x99]); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - } - - [Fact] - public void DCR_M_ShouldSetAuxCarry() - { - // Arrange - _cpu.Registers.HL = 0x99; - _cpu.Memory[0x99] = 0x00; - - // Act - DefaultInstructionSet.DCR_M(_cpu); - - // Assert - Assert.Equal(0x00, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0099, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.Equal(0xFF, _cpu.Memory[0x99]); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - } - - [Fact] - public void DCR_A_ShouldDecrementByOne() - { - // Arrange - _cpu.Registers.A = 0xFF; - - // Act - DefaultInstructionSet.DCR_A(_cpu); - - // Assert - Assert.Equal(0xFE, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.False(_cpu.Flags.Parity); - } - - [Fact] - public void DCR_A_ShouldSetAuxCarry() - { - // Arrange - _cpu.Registers.A = 0x00; - - // Act - DefaultInstructionSet.DCR_A(_cpu); - - // Assert - Assert.Equal(0xFF, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.True(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.False(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Parity); - } - - [Fact] - public void DAA() - { - // Arrange - _cpu.Registers.A = 0x9B; - - // Act - DefaultInstructionSet.DAA(_cpu); - - // Assert - Assert.Equal(0x01, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - - Assert.False(_cpu.Flags.Sign); - Assert.False(_cpu.Flags.Zero); - Assert.True(_cpu.Flags.AuxiliaryCarry); - Assert.True(_cpu.Flags.Carry); - Assert.False(_cpu.Flags.Parity); - } - - [Fact] - public void CMA() - { - // Arrange - _cpu.Registers.A = 0x51; - - // Act - DefaultInstructionSet.CMA(_cpu); - - // Assert - Assert.Equal(0xAE, _cpu.Registers.A); - Assert.Equal(0x0000, _cpu.Registers.BC); - Assert.Equal(0x0000, _cpu.Registers.DE); - Assert.Equal(0x0000, _cpu.Registers.HL); - Assert.Equal(0x0000, _cpu.Registers.SP); - } - } +using Intel8080.Emulator.Instructions; +using Xunit; + +namespace Intel8080.Emulator.Tests.Instructions; + +public class SingleRegisterInstructionTests +{ + private readonly CPU _cpu; + private readonly IMemory _memory; + + public SingleRegisterInstructionTests() + { + _memory = new DefaultMemory(0x100); + _cpu = new CPU(_memory); + } + + [Fact] + public void INR_B_ShouldIncrementByOne() + { + // Arrange + _cpu.Registers.B = 0x99; + + // Act + DefaultInstructionSet.INR_B(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x9A00, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + } + + [Fact] + public void INR_B_ShouldSetAuxCarry() + { + // Arrange + _cpu.Registers.B = 0xFF; + + // Act + DefaultInstructionSet.INR_B(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.True(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + } + + [Fact] + public void INR_C_ShouldIncrementByOne() + { + // Arrange + _cpu.Registers.C = 0x99; + + // Act + DefaultInstructionSet.INR_C(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x009A, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + } + + [Fact] + public void INR_C_ShouldSetAuxCarry() + { + // Arrange + _cpu.Registers.C = 0xFF; + + // Act + DefaultInstructionSet.INR_C(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.True(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + } + + [Fact] + public void INR_D_ShouldIncrementByOne() + { + // Arrange + _cpu.Registers.D = 0x99; + + // Act + DefaultInstructionSet.INR_D(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x9A00, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + } + + [Fact] + public void INR_D_ShouldSetAuxCarry() + { + // Arrange + _cpu.Registers.D = 0xFF; + + // Act + DefaultInstructionSet.INR_D(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.True(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + } + + [Fact] + public void INR_E_ShouldIncrementByOne() + { + // Arrange + _cpu.Registers.E = 0x99; + + // Act + DefaultInstructionSet.INR_E(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x009A, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + } + + [Fact] + public void INR_E_ShouldSetAuxCarry() + { + // Arrange + _cpu.Registers.E = 0xFF; + + // Act + DefaultInstructionSet.INR_E(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.True(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + } + + [Fact] + public void INR_H_ShouldIncrementByOne() + { + // Arrange + _cpu.Registers.H = 0x99; + + // Act + DefaultInstructionSet.INR_H(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x9A00, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + } + + [Fact] + public void INR_H_ShouldSetAuxCarry() + { + // Arrange + _cpu.Registers.H = 0xFF; + + // Act + DefaultInstructionSet.INR_H(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.True(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + } + + [Fact] + public void INR_L_ShouldIncrementByOne() + { + // Arrange + _cpu.Registers.L = 0x99; + + // Act + DefaultInstructionSet.INR_L(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x009A, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + } + + [Fact] + public void INR_L_ShouldSetAuxCarry() + { + // Arrange + _cpu.Registers.L = 0xFF; + + // Act + DefaultInstructionSet.INR_L(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.True(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + } + + [Fact] + public void INR_M_ShouldIncrementByOne() + { + // Arrange + _cpu.Registers.HL = 0x99; + _cpu.Memory[0x99] = 0x40; + + // Act + DefaultInstructionSet.INR_M(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0099, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.Equal(0x41, _cpu.Memory[0x99]); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + } + + [Fact] + public void INR_A_ShouldIncrementByOne() + { + // Arrange + _cpu.Registers.A = 0x99; + + // Act + DefaultInstructionSet.INR_A(_cpu); + + // Assert + Assert.Equal(0x9A, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + } + + [Fact] + public void INR_A_ShouldSetAuxCarry() + { + // Arrange + _cpu.Registers.A = 0xFF; + + // Act + DefaultInstructionSet.INR_A(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.True(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + } + + [Fact] + public void DCR_B_ShouldDecrementByOne() + { + // Arrange + _cpu.Registers.B = 0xFF; + + // Act + DefaultInstructionSet.DCR_B(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0xFE00, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + } + + [Fact] + public void DCR_B_ShouldSetAuxCarry() + { + // Arrange + _cpu.Registers.B = 0x00; + + // Act + DefaultInstructionSet.DCR_B(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0xFF00, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + } + + [Fact] + public void DCR_C_ShouldDecrementByOne() + { + // Arrange + _cpu.Registers.C = 0xFF; + + // Act + DefaultInstructionSet.DCR_C(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x00FE, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + } + + [Fact] + public void DCR_C_ShouldSetAuxCarry() + { + // Arrange + _cpu.Registers.C = 0x00; + + // Act + DefaultInstructionSet.DCR_C(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x00FF, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + } + + [Fact] + public void DCR_D_ShouldDecrementByOne() + { + // Arrange + _cpu.Registers.D = 0xFF; + + // Act + DefaultInstructionSet.DCR_D(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0xFE00, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + } + + [Fact] + public void DCR_D_ShouldSetAuxCarry() + { + // Arrange + _cpu.Registers.D = 0x00; + + // Act + DefaultInstructionSet.DCR_D(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0xFF00, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + } + + [Fact] + public void DCR_E_ShouldDecrementByOne() + { + // Arrange + _cpu.Registers.E = 0xFF; + + // Act + DefaultInstructionSet.DCR_E(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x00FE, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + } + + [Fact] + public void DCR_E_ShouldSetAuxCarry() + { + // Arrange + _cpu.Registers.E = 0x00; + + // Act + DefaultInstructionSet.DCR_E(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x00FF, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + } + + [Fact] + public void DCR_H_ShouldDecrementByOne() + { + // Arrange + _cpu.Registers.H = 0xFF; + + // Act + DefaultInstructionSet.DCR_H(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0xFE00, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + } + + [Fact] + public void DCR_H_ShouldSetAuxCarry() + { + // Arrange + _cpu.Registers.H = 0x00; + + // Act + DefaultInstructionSet.DCR_H(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0xFF00, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + } + + [Fact] + public void DCR_L_ShouldDecrementByOne() + { + // Arrange + _cpu.Registers.L = 0xFF; + + // Act + DefaultInstructionSet.DCR_L(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x00FE, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + } + + [Fact] + public void DCR_L_ShouldSetAuxCarry() + { + // Arrange + _cpu.Registers.L = 0x00; + + // Act + DefaultInstructionSet.DCR_L(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x00FF, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + } + + [Fact] + public void DCR_M_ShouldDecrementByOne() + { + // Arrange + _cpu.Registers.HL = 0x99; + _cpu.Memory[0x99] = 0xFF; + + // Act + DefaultInstructionSet.DCR_M(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0099, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.Equal(0xFE, _cpu.Memory[0x99]); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + } + + [Fact] + public void DCR_M_ShouldSetAuxCarry() + { + // Arrange + _cpu.Registers.HL = 0x99; + _cpu.Memory[0x99] = 0x00; + + // Act + DefaultInstructionSet.DCR_M(_cpu); + + // Assert + Assert.Equal(0x00, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0099, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.Equal(0xFF, _cpu.Memory[0x99]); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + } + + [Fact] + public void DCR_A_ShouldDecrementByOne() + { + // Arrange + _cpu.Registers.A = 0xFF; + + // Act + DefaultInstructionSet.DCR_A(_cpu); + + // Assert + Assert.Equal(0xFE, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.False(_cpu.Flags.Parity); + } + + [Fact] + public void DCR_A_ShouldSetAuxCarry() + { + // Arrange + _cpu.Registers.A = 0x00; + + // Act + DefaultInstructionSet.DCR_A(_cpu); + + // Assert + Assert.Equal(0xFF, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.True(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.False(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Parity); + } + + [Fact] + public void DAA() + { + // Arrange + _cpu.Registers.A = 0x9B; + + // Act + DefaultInstructionSet.DAA(_cpu); + + // Assert + Assert.Equal(0x01, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + + Assert.False(_cpu.Flags.Sign); + Assert.False(_cpu.Flags.Zero); + Assert.True(_cpu.Flags.AuxiliaryCarry); + Assert.True(_cpu.Flags.Carry); + Assert.False(_cpu.Flags.Parity); + } + + [Fact] + public void CMA() + { + // Arrange + _cpu.Registers.A = 0x51; + + // Act + DefaultInstructionSet.CMA(_cpu); + + // Assert + Assert.Equal(0xAE, _cpu.Registers.A); + Assert.Equal(0x0000, _cpu.Registers.BC); + Assert.Equal(0x0000, _cpu.Registers.DE); + Assert.Equal(0x0000, _cpu.Registers.HL); + Assert.Equal(0x0000, _cpu.Registers.SP); + } } \ No newline at end of file diff --git a/Intel8080.Emulator.Tests/Intel8080.Emulator.Tests.csproj b/Intel8080.Emulator.Tests/Intel8080.Emulator.Tests.csproj index 667d61c..0a06806 100644 --- a/Intel8080.Emulator.Tests/Intel8080.Emulator.Tests.csproj +++ b/Intel8080.Emulator.Tests/Intel8080.Emulator.Tests.csproj @@ -1,20 +1,20 @@  - net6.0 + net8.0 false - - - - + + + + runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/Intel8080.Emulator.Tests/RegisterTests.cs b/Intel8080.Emulator.Tests/RegisterTests.cs index 3b3bd59..7dd6786 100644 --- a/Intel8080.Emulator.Tests/RegisterTests.cs +++ b/Intel8080.Emulator.Tests/RegisterTests.cs @@ -1,167 +1,165 @@ -using System.Collections.Generic; -using Intel8080.Emulator; -using Xunit; - -namespace Intel8080.Emulator.Tests -{ - public class RegisterTests - { - private Registers _registers; - - public static IEnumerable SingleRegisterTestData => new List - { - new object[] { 0xFF00, 0xFF, 0x00 }, - new object[] { 0x4200, 0x42, 0x00 }, - new object[] { 0x00FF, 0x00, 0xFF }, - new object[] { 0x0042, 0x00, 0x42 }, - new object[] { 0x12FF, 0x12, 0xFF }, - new object[] { 0xFFFF, 0xFF, 0xFF }, - new object[] { 0x0000, 0x00, 0x00} - }; - - public static IEnumerable RegisterPairTestData => new List - { - new object[] { 0xFFFF, 0xFF, 0xFF }, - new object[] { 0x4200, 0x42, 0x00 }, - new object[] { 0x0042, 0x00, 0x42 } - }; - - public RegisterTests() - { - _registers = new Registers(); - } - - [Fact] - public void Store_Accumulator() - { - // Act - _registers.A = 0xFF; - - // Assert - Assert.Equal(0xFF, _registers.A); - } - - [Fact] - public void Store_ProgramCounter() - { - // Act - _registers.PC = 0xFFFF; - - // Assert - Assert.Equal(0xFFFF, _registers.PC); - } - - [Fact] - public void Store_StackPointer() - { - // Act - _registers.SP = 0xFFFF; - - // Assert - Assert.Equal(0xFFFF, _registers.SP); - } - - [Theory] - [MemberData(nameof(SingleRegisterTestData))] - public void Store_BC_SingleRegister(ushort BC, byte B, byte C) - { - // Act - _registers.B = B; - _registers.C = C; - - // Assert - Assert.Equal(BC, _registers.BC); - Assert.Equal(B, _registers.B); - Assert.Equal(C, _registers.C); - } - - [Theory] - [MemberData(nameof(RegisterPairTestData))] - public void Store_BC_RegisterPair(ushort BC, byte B, byte C) - { - // Act - _registers.BC = BC; - - // Assert - Assert.Equal(BC, _registers.BC); - Assert.Equal(B, _registers.B); - Assert.Equal(C, _registers.C); - } - - [Theory] - [MemberData(nameof(SingleRegisterTestData))] - public void Store_DE_SingleRegister(ushort DE, byte D, byte E) - { - // Act - _registers.D = D; - _registers.E = E; - - // Assert - Assert.Equal(DE, _registers.DE); - Assert.Equal(D, _registers.D); - Assert.Equal(E, _registers.E); - } - - [Theory] - [MemberData(nameof(RegisterPairTestData))] - public void Store_DE_RegisterPair(ushort DE, byte D, byte E) - { - // Act - _registers.DE = DE; - - // Assert - Assert.Equal(DE, _registers.DE); - Assert.Equal(D, _registers.D); - Assert.Equal(E, _registers.E); - } - - [Theory] - [MemberData(nameof(SingleRegisterTestData))] - public void Store_HL_SingleRegister(ushort HL, byte H, byte L) - { - // Act - _registers.H = H; - _registers.L = L; - - // Assert - Assert.Equal(HL, _registers.HL); - Assert.Equal(H, _registers.H); - Assert.Equal(L, _registers.L); - } - - [Theory] - [MemberData(nameof(RegisterPairTestData))] - public void Store_HL_RegisterPair(ushort HL, byte H, byte L) - { - // Act - _registers.HL = HL; - - // Assert - Assert.Equal(HL, _registers.HL); - Assert.Equal(H, _registers.H); - Assert.Equal(L, _registers.L); - } - - [Fact] - public void ClearRegistersShouldSetAllRegistersToZero() - { - // Arrange - _registers.A = 0xFF; - _registers.BC = 0xFFFF; - _registers.DE = 0xFFFF; - _registers.HL = 0xFFFF; - _registers.PC = 0xFFFF; - _registers.SP = 0xFFFF; - - // Act - _registers.Clear(); - - Assert.Equal(0x00, _registers.A); - Assert.Equal(0x0000, _registers.BC); - Assert.Equal(0x0000, _registers.DE); - Assert.Equal(0x0000, _registers.HL); - Assert.Equal(0x0000, _registers.PC); - Assert.Equal(0x0000, _registers.SP); - } - } +using System.Collections.Generic; +using Xunit; + +namespace Intel8080.Emulator.Tests; + +public class RegisterTests +{ + private readonly Registers _registers; + + public static IEnumerable SingleRegisterTestData => new List + { + new object[] { 0xFF00, 0xFF, 0x00 }, + new object[] { 0x4200, 0x42, 0x00 }, + new object[] { 0x00FF, 0x00, 0xFF }, + new object[] { 0x0042, 0x00, 0x42 }, + new object[] { 0x12FF, 0x12, 0xFF }, + new object[] { 0xFFFF, 0xFF, 0xFF }, + new object[] { 0x0000, 0x00, 0x00} + }; + + public static IEnumerable RegisterPairTestData => new List + { + new object[] { 0xFFFF, 0xFF, 0xFF }, + new object[] { 0x4200, 0x42, 0x00 }, + new object[] { 0x0042, 0x00, 0x42 } + }; + + public RegisterTests() + { + _registers = new Registers(); + } + + [Fact] + public void Store_Accumulator() + { + // Act + _registers.A = 0xFF; + + // Assert + Assert.Equal(0xFF, _registers.A); + } + + [Fact] + public void Store_ProgramCounter() + { + // Act + _registers.PC = 0xFFFF; + + // Assert + Assert.Equal(0xFFFF, _registers.PC); + } + + [Fact] + public void Store_StackPointer() + { + // Act + _registers.SP = 0xFFFF; + + // Assert + Assert.Equal(0xFFFF, _registers.SP); + } + + [Theory] + [MemberData(nameof(SingleRegisterTestData))] + public void Store_BC_SingleRegister(ushort BC, byte B, byte C) + { + // Act + _registers.B = B; + _registers.C = C; + + // Assert + Assert.Equal(BC, _registers.BC); + Assert.Equal(B, _registers.B); + Assert.Equal(C, _registers.C); + } + + [Theory] + [MemberData(nameof(RegisterPairTestData))] + public void Store_BC_RegisterPair(ushort BC, byte B, byte C) + { + // Act + _registers.BC = BC; + + // Assert + Assert.Equal(BC, _registers.BC); + Assert.Equal(B, _registers.B); + Assert.Equal(C, _registers.C); + } + + [Theory] + [MemberData(nameof(SingleRegisterTestData))] + public void Store_DE_SingleRegister(ushort DE, byte D, byte E) + { + // Act + _registers.D = D; + _registers.E = E; + + // Assert + Assert.Equal(DE, _registers.DE); + Assert.Equal(D, _registers.D); + Assert.Equal(E, _registers.E); + } + + [Theory] + [MemberData(nameof(RegisterPairTestData))] + public void Store_DE_RegisterPair(ushort DE, byte D, byte E) + { + // Act + _registers.DE = DE; + + // Assert + Assert.Equal(DE, _registers.DE); + Assert.Equal(D, _registers.D); + Assert.Equal(E, _registers.E); + } + + [Theory] + [MemberData(nameof(SingleRegisterTestData))] + public void Store_HL_SingleRegister(ushort HL, byte H, byte L) + { + // Act + _registers.H = H; + _registers.L = L; + + // Assert + Assert.Equal(HL, _registers.HL); + Assert.Equal(H, _registers.H); + Assert.Equal(L, _registers.L); + } + + [Theory] + [MemberData(nameof(RegisterPairTestData))] + public void Store_HL_RegisterPair(ushort HL, byte H, byte L) + { + // Act + _registers.HL = HL; + + // Assert + Assert.Equal(HL, _registers.HL); + Assert.Equal(H, _registers.H); + Assert.Equal(L, _registers.L); + } + + [Fact] + public void ClearRegistersShouldSetAllRegistersToZero() + { + // Arrange + _registers.A = 0xFF; + _registers.BC = 0xFFFF; + _registers.DE = 0xFFFF; + _registers.HL = 0xFFFF; + _registers.PC = 0xFFFF; + _registers.SP = 0xFFFF; + + // Act + _registers.Clear(); + + Assert.Equal(0x00, _registers.A); + Assert.Equal(0x0000, _registers.BC); + Assert.Equal(0x0000, _registers.DE); + Assert.Equal(0x0000, _registers.HL); + Assert.Equal(0x0000, _registers.PC); + Assert.Equal(0x0000, _registers.SP); + } } \ No newline at end of file diff --git a/Intel8080.Emulator/CPU.cs b/Intel8080.Emulator/CPU.cs index a4c4f93..408da70 100644 --- a/Intel8080.Emulator/CPU.cs +++ b/Intel8080.Emulator/CPU.cs @@ -1,103 +1,101 @@ -using System; -using System.Linq; -using Intel8080.Emulator.Instructions; -using Intel8080.Emulator.IO; - -namespace Intel8080.Emulator -{ - public class CPU - { - public IMemory Memory { get; } - - public Registers Registers { get; } - - public Flags Flags { get; } - - public IIOController IOController { get; } - - public long Cycles { get; set; } = 0; - - public bool Halted { get; set; } - - public bool InterruptEnabled { get; set; } = false; - - private readonly Action[] _instructionSet = DefaultInstructionSet.Actions; - - private byte? _interrupt = null; - - public CPU(IMemory memory) - { - Memory = memory; - Registers = new Registers(); - Flags = new Flags(); - IOController = new DefaultIOController(); - } - - public void Run() - { - while (!Halted) - { - Step(); - } - } - - public void Step() - { - byte opcode; - - if (InterruptEnabled && _interrupt != null) - { - opcode = _interrupt.Value; - - InterruptEnabled = false; - _interrupt = null; - } - else - { - opcode = ReadNextByte(); - } - - _instructionSet[opcode](this); - - Cycles += OpcodeTable.Opcodes[opcode].Cycles; - } - - public void Reset() - { - Registers.Clear(); - Flags.Clear(); - } - - public void RaiseInterrupt(byte opcode) - { - _interrupt = opcode; - } - - internal byte ReadByte(int address) - { - return Memory[address]; - } - - internal ushort ReadUshort(int address) - { - var a = ReadByte(address + 1); - var b = ReadByte(address); - - return (ushort)((a << 8) | b); - } - - internal byte ReadNextByte() - { - return ReadByte(Registers.PC++); - } - - internal ushort ReadNextUshort() - { - var res = ReadUshort(Registers.PC); - - Registers.PC += 2; - - return res; - } - } +using System; +using Intel8080.Emulator.Instructions; +using Intel8080.Emulator.IO; + +namespace Intel8080.Emulator; + +public class CPU +{ + public IMemory Memory { get; } + + public Registers Registers { get; } + + public Flags Flags { get; } + + public IIOController IOController { get; } + + public long Cycles { get; set; } = 0; + + public bool Halted { get; set; } + + public bool InterruptEnabled { get; set; } = false; + + private readonly Action[] _instructionSet = DefaultInstructionSet.Actions; + + private byte? _interrupt = null; + + public CPU(IMemory memory) + { + Memory = memory; + Registers = new Registers(); + Flags = new Flags(); + IOController = new DefaultIOController(); + } + + public void Run() + { + while (!Halted) + { + Step(); + } + } + + public void Step() + { + byte opcode; + + if (InterruptEnabled && _interrupt != null) + { + opcode = _interrupt.Value; + + InterruptEnabled = false; + _interrupt = null; + } + else + { + opcode = ReadNextByte(); + } + + _instructionSet[opcode](this); + + Cycles += OpcodeTable.Opcodes[opcode].Cycles; + } + + public void Reset() + { + Registers.Clear(); + Flags.Clear(); + } + + public void RaiseInterrupt(byte opcode) + { + _interrupt = opcode; + } + + internal byte ReadByte(int address) + { + return Memory[address]; + } + + internal ushort ReadUshort(int address) + { + var a = ReadByte(address + 1); + var b = ReadByte(address); + + return (ushort)((a << 8) | b); + } + + internal byte ReadNextByte() + { + return ReadByte(Registers.PC++); + } + + internal ushort ReadNextUshort() + { + var res = ReadUshort(Registers.PC); + + Registers.PC += 2; + + return res; + } } \ No newline at end of file diff --git a/Intel8080.Emulator/DefaultMemory.cs b/Intel8080.Emulator/DefaultMemory.cs index fcf4b8e..b21ecc0 100644 --- a/Intel8080.Emulator/DefaultMemory.cs +++ b/Intel8080.Emulator/DefaultMemory.cs @@ -1,14 +1,13 @@ -namespace Intel8080.Emulator -{ - public class DefaultMemory : IMemory - { - private readonly byte[] _memory; - - public byte this[int index] { get => _memory[index]; set => _memory[index] = value; } - - public DefaultMemory(int size) - { - _memory = new byte[size]; - } - } +namespace Intel8080.Emulator; + +public class DefaultMemory : IMemory +{ + private readonly byte[] _memory; + + public byte this[int index] { get => _memory[index]; set => _memory[index] = value; } + + public DefaultMemory(int size) + { + _memory = new byte[size]; + } } \ No newline at end of file diff --git a/Intel8080.Emulator/Flags.cs b/Intel8080.Emulator/Flags.cs index 9c19cf2..795a3d1 100644 --- a/Intel8080.Emulator/Flags.cs +++ b/Intel8080.Emulator/Flags.cs @@ -1,83 +1,82 @@ -using System.Numerics; - -namespace Intel8080.Emulator -{ - public class Flags - { - private const byte SignMask = 0x80; - private const byte ZeroMask = 0x40; - private const byte AuxCarryMask = 0x10; - private const byte ParityMask = 0x04; - private const byte CarryMask = 0x01; - - public byte F { get; set; } = 0x02; - public bool Sign { get => GetFlag(SignMask); set => SetFlag(value, SignMask); } - public bool Zero { get => GetFlag(ZeroMask); set => SetFlag(value, ZeroMask); } - public bool AuxiliaryCarry { get => GetFlag(AuxCarryMask); set => SetFlag(value, AuxCarryMask); } - public bool Parity { get => GetFlag(ParityMask); set => SetFlag(value, ParityMask); } - public bool Carry { get => GetFlag(CarryMask); set => SetFlag(value, CarryMask); } - - public void CalcSignFlag(byte value) - { - Sign = (value >> 7) == 1; - } - - public void CalcZeroFlag(byte value) - { - Zero = (value == 0); - } - - public void CalcAuxCarryFlag(int a, int b, int cy = 0) - { - int result = (a & 0x0F) + (b & 0x0F) + (cy & 0x0F) & 0x10; - - AuxiliaryCarry = result != 0; - } - - public void CalcParityFlag(byte value) - { - var setBits = BitOperations.PopCount(value); - - Parity = (value == 0) || ((setBits % 2) == 0); - } - - public void CalcCarryFlag(ushort value) - { - Carry = (value > 0xFF); - } - - public void CalcCarryFlagSub(ushort value) - { - Carry = !(value > 0xFF); - } - - public void CalcCarryFlagRegisterPair(int value) - { - Carry = (value > 0xFFFF); - } - - public void Clear() - { - F = 0x02; - } - - public void SetFlagsPSW(byte flags) - { - Sign = (flags & SignMask) != 0; - Zero = (flags & ZeroMask) != 0; - AuxiliaryCarry = (flags & AuxCarryMask) != 0; - Parity = (flags & ParityMask) != 0; - Carry = (flags & CarryMask) != 0; - } - - private bool GetFlag(byte mask) - { - return (F & mask) == mask; - } - - private void SetFlag(bool value, byte mask) - { - F = (byte) (value ? (F | mask) : (F & ~(mask))); - } - } +using System.Numerics; + +namespace Intel8080.Emulator; + +public class Flags +{ + private const byte SignMask = 0x80; + private const byte ZeroMask = 0x40; + private const byte AuxCarryMask = 0x10; + private const byte ParityMask = 0x04; + private const byte CarryMask = 0x01; + + public byte F { get; set; } = 0x02; + public bool Sign { get => GetFlag(SignMask); set => SetFlag(value, SignMask); } + public bool Zero { get => GetFlag(ZeroMask); set => SetFlag(value, ZeroMask); } + public bool AuxiliaryCarry { get => GetFlag(AuxCarryMask); set => SetFlag(value, AuxCarryMask); } + public bool Parity { get => GetFlag(ParityMask); set => SetFlag(value, ParityMask); } + public bool Carry { get => GetFlag(CarryMask); set => SetFlag(value, CarryMask); } + + public void CalcSignFlag(byte value) + { + Sign = (value >> 7) == 1; + } + + public void CalcZeroFlag(byte value) + { + Zero = (value == 0); + } + + public void CalcAuxCarryFlag(int a, int b, int cy = 0) + { + int result = (a & 0x0F) + (b & 0x0F) + (cy & 0x0F) & 0x10; + + AuxiliaryCarry = result != 0; + } + + public void CalcParityFlag(byte value) + { + var setBits = BitOperations.PopCount(value); + + Parity = (value == 0) || ((setBits % 2) == 0); + } + + public void CalcCarryFlag(ushort value) + { + Carry = (value > 0xFF); + } + + public void CalcCarryFlagSub(ushort value) + { + Carry = !(value > 0xFF); + } + + public void CalcCarryFlagRegisterPair(int value) + { + Carry = (value > 0xFFFF); + } + + public void Clear() + { + F = 0x02; + } + + public void SetFlagsPSW(byte flags) + { + Sign = (flags & SignMask) != 0; + Zero = (flags & ZeroMask) != 0; + AuxiliaryCarry = (flags & AuxCarryMask) != 0; + Parity = (flags & ParityMask) != 0; + Carry = (flags & CarryMask) != 0; + } + + private bool GetFlag(byte mask) + { + return (F & mask) == mask; + } + + private void SetFlag(bool value, byte mask) + { + F = (byte)(value ? (F | mask) : (F & ~(mask))); + } } \ No newline at end of file diff --git a/Intel8080.Emulator/IMemory.cs b/Intel8080.Emulator/IMemory.cs index 84ee343..cc2143e 100644 --- a/Intel8080.Emulator/IMemory.cs +++ b/Intel8080.Emulator/IMemory.cs @@ -1,7 +1,6 @@ -namespace Intel8080.Emulator -{ - public interface IMemory - { - public byte this[int index] { get; set; } - } +namespace Intel8080.Emulator; + +public interface IMemory +{ + public byte this[int index] { get; set; } } \ No newline at end of file diff --git a/Intel8080.Emulator/IO/DefaultIOController.cs b/Intel8080.Emulator/IO/DefaultIOController.cs index 98cdae7..46aa29b 100644 --- a/Intel8080.Emulator/IO/DefaultIOController.cs +++ b/Intel8080.Emulator/IO/DefaultIOController.cs @@ -1,36 +1,35 @@ -using System.Collections.Generic; - -namespace Intel8080.Emulator.IO -{ - internal class DefaultIOController : IIOController - { - private readonly Dictionary _inputDevices; - private readonly Dictionary _outputDevices; - - public DefaultIOController() - { - _inputDevices = new Dictionary(); - _outputDevices = new Dictionary(); - } - - public void AddDevice(IInputDevice device, byte port) - { - _inputDevices[port] = device; - } - - public void AddDevice(IOutputDevice device, byte port) - { - _outputDevices[port] = device; - } - - public IInputDevice GetInputDevice(byte port) - { - return _inputDevices[port]; - } - - public IOutputDevice GetOutputDevice(byte port) - { - return _outputDevices[port]; - } - } -} +using System.Collections.Generic; + +namespace Intel8080.Emulator.IO; + +internal class DefaultIOController : IIOController +{ + private readonly Dictionary _inputDevices; + private readonly Dictionary _outputDevices; + + public DefaultIOController() + { + _inputDevices = new Dictionary(); + _outputDevices = new Dictionary(); + } + + public void AddDevice(IInputDevice device, byte port) + { + _inputDevices[port] = device; + } + + public void AddDevice(IOutputDevice device, byte port) + { + _outputDevices[port] = device; + } + + public IInputDevice GetInputDevice(byte port) + { + return _inputDevices[port]; + } + + public IOutputDevice GetOutputDevice(byte port) + { + return _outputDevices[port]; + } +} \ No newline at end of file diff --git a/Intel8080.Emulator/IO/IIOController.cs b/Intel8080.Emulator/IO/IIOController.cs index eba0999..31fa96b 100644 --- a/Intel8080.Emulator/IO/IIOController.cs +++ b/Intel8080.Emulator/IO/IIOController.cs @@ -1,16 +1,12 @@ -using System.Collections; -using System.Collections.Generic; - -namespace Intel8080.Emulator.IO -{ - public interface IIOController - { - public void AddDevice(IInputDevice device, byte port); - - public void AddDevice(IOutputDevice device, byte port); - - public IInputDevice GetInputDevice(byte port); - - public IOutputDevice GetOutputDevice(byte port); - } -} +namespace Intel8080.Emulator.IO; + +public interface IIOController +{ + public void AddDevice(IInputDevice device, byte port); + + public void AddDevice(IOutputDevice device, byte port); + + public IInputDevice GetInputDevice(byte port); + + public IOutputDevice GetOutputDevice(byte port); +} \ No newline at end of file diff --git a/Intel8080.Emulator/IO/IInputDevice.cs b/Intel8080.Emulator/IO/IInputDevice.cs index c4cea4a..e35214f 100644 --- a/Intel8080.Emulator/IO/IInputDevice.cs +++ b/Intel8080.Emulator/IO/IInputDevice.cs @@ -1,13 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Intel8080.Emulator.IO -{ - public interface IInputDevice - { - public byte Read(); - } -} +namespace Intel8080.Emulator.IO; + +public interface IInputDevice +{ + public byte Read(); +} \ No newline at end of file diff --git a/Intel8080.Emulator/IO/IOutputDevice.cs b/Intel8080.Emulator/IO/IOutputDevice.cs index 36cfdfc..438d09b 100644 --- a/Intel8080.Emulator/IO/IOutputDevice.cs +++ b/Intel8080.Emulator/IO/IOutputDevice.cs @@ -1,13 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Intel8080.Emulator.IO -{ - public interface IOutputDevice - { - public void Write(byte data); - } -} +namespace Intel8080.Emulator.IO; + +public interface IOutputDevice +{ + public void Write(byte data); +} \ No newline at end of file diff --git a/Intel8080.Emulator/InstructionData.cs b/Intel8080.Emulator/InstructionData.cs index b6c9af5..8a72733 100644 --- a/Intel8080.Emulator/InstructionData.cs +++ b/Intel8080.Emulator/InstructionData.cs @@ -1,23 +1,20 @@ -using System; - -namespace Intel8080.Emulator -{ - public class Opcode - { - public string Mnenomic { get; set; } = null!; - - public ushort Length { get; set; } - - public int Cycles { get; set; } - - public int? CyclesBranch { get; set; } - - public Opcode(string mnenomic, ushort length, int cycles, int? cyclesBranch) - { - Mnenomic = mnenomic; - Length = length; - Cycles = cycles; - CyclesBranch = cyclesBranch; - } - } +namespace Intel8080.Emulator; + +public class Opcode +{ + public string Mnenomic { get; set; } = null!; + + public ushort Length { get; set; } + + public int Cycles { get; set; } + + public int? CyclesBranch { get; set; } + + public Opcode(string mnenomic, ushort length, int cycles, int? cyclesBranch) + { + Mnenomic = mnenomic; + Length = length; + Cycles = cycles; + CyclesBranch = cyclesBranch; + } } \ No newline at end of file diff --git a/Intel8080.Emulator/Instructions/CallSubroutineInstructions.cs b/Intel8080.Emulator/Instructions/CallSubroutineInstructions.cs index 5cde3d1..ce98266 100644 --- a/Intel8080.Emulator/Instructions/CallSubroutineInstructions.cs +++ b/Intel8080.Emulator/Instructions/CallSubroutineInstructions.cs @@ -1,159 +1,158 @@ -namespace Intel8080.Emulator.Instructions -{ - public static partial class DefaultInstructionSet - { - private static void CALL(CPU cpu, ushort address) - { - PushStack(cpu, cpu.Registers.PC); - - cpu.Registers.PC = address; - } - - public static void CALL(CPU cpu) - { - var location = cpu.ReadNextUshort(); - - CALL(cpu, location); - } - - public static void CNZ(CPU cpu) - { - var location = cpu.ReadNextUshort(); - - if (!cpu.Flags.Zero) - { - CALL(cpu, location); - - cpu.Cycles += 6; - } - } - - - public static void CZ(CPU cpu) - { - var location = cpu.ReadNextUshort(); - - if (cpu.Flags.Zero) - { - CALL(cpu, location); - - cpu.Cycles += 6; - } - } - - public static void CNC(CPU cpu) - { - var location = cpu.ReadNextUshort(); - - if (!cpu.Flags.Carry) - { - CALL(cpu, location); - - cpu.Cycles += 6; - } - } - - - public static void CC(CPU cpu) - { - var location = cpu.ReadNextUshort(); - - if (cpu.Flags.Carry) - { - CALL(cpu, location); - - cpu.Cycles += 6; - } - } - - public static void CPO(CPU cpu) - { - var location = cpu.ReadNextUshort(); - - if (!cpu.Flags.Parity) - { - CALL(cpu, location); - - cpu.Cycles += 6; - } - } - - - public static void CPE(CPU cpu) - { - var location = cpu.ReadNextUshort(); - - if (cpu.Flags.Parity) - { - CALL(cpu, location); - - cpu.Cycles += 6; - } - } - - public static void CP(CPU cpu) - { - var location = cpu.ReadNextUshort(); - - if (!cpu.Flags.Sign) - { - CALL(cpu, location); - - cpu.Cycles += 6; - } - } - - - public static void CM(CPU cpu) - { - var location = cpu.ReadNextUshort(); - - if (cpu.Flags.Sign) - { - CALL(cpu, location); - - cpu.Cycles += 6; - } - } - - public static void RST_0(CPU cpu) - { - CALL(cpu, 0x00); - } - - public static void RST_1(CPU cpu) - { - CALL(cpu, 0x08); - } - - public static void RST_2(CPU cpu) - { - CALL(cpu, 0x10); - } - - public static void RST_3(CPU cpu) - { - CALL(cpu, 0x18); - } - - public static void RST_4(CPU cpu) - { - CALL(cpu, 0x20); - } - - public static void RST_5(CPU cpu) - { - CALL(cpu, 0x28); - } - - public static void RST_6(CPU cpu) - { - CALL(cpu, 0x30); - } - - public static void RST_7(CPU cpu) - { - CALL(cpu, 0x38); - } - } +namespace Intel8080.Emulator.Instructions; + +public static partial class DefaultInstructionSet +{ + private static void CALL(CPU cpu, ushort address) + { + PushStack(cpu, cpu.Registers.PC); + + cpu.Registers.PC = address; + } + + public static void CALL(CPU cpu) + { + var location = cpu.ReadNextUshort(); + + CALL(cpu, location); + } + + public static void CNZ(CPU cpu) + { + var location = cpu.ReadNextUshort(); + + if (!cpu.Flags.Zero) + { + CALL(cpu, location); + + cpu.Cycles += 6; + } + } + + + public static void CZ(CPU cpu) + { + var location = cpu.ReadNextUshort(); + + if (cpu.Flags.Zero) + { + CALL(cpu, location); + + cpu.Cycles += 6; + } + } + + public static void CNC(CPU cpu) + { + var location = cpu.ReadNextUshort(); + + if (!cpu.Flags.Carry) + { + CALL(cpu, location); + + cpu.Cycles += 6; + } + } + + + public static void CC(CPU cpu) + { + var location = cpu.ReadNextUshort(); + + if (cpu.Flags.Carry) + { + CALL(cpu, location); + + cpu.Cycles += 6; + } + } + + public static void CPO(CPU cpu) + { + var location = cpu.ReadNextUshort(); + + if (!cpu.Flags.Parity) + { + CALL(cpu, location); + + cpu.Cycles += 6; + } + } + + + public static void CPE(CPU cpu) + { + var location = cpu.ReadNextUshort(); + + if (cpu.Flags.Parity) + { + CALL(cpu, location); + + cpu.Cycles += 6; + } + } + + public static void CP(CPU cpu) + { + var location = cpu.ReadNextUshort(); + + if (!cpu.Flags.Sign) + { + CALL(cpu, location); + + cpu.Cycles += 6; + } + } + + + public static void CM(CPU cpu) + { + var location = cpu.ReadNextUshort(); + + if (cpu.Flags.Sign) + { + CALL(cpu, location); + + cpu.Cycles += 6; + } + } + + public static void RST_0(CPU cpu) + { + CALL(cpu, 0x00); + } + + public static void RST_1(CPU cpu) + { + CALL(cpu, 0x08); + } + + public static void RST_2(CPU cpu) + { + CALL(cpu, 0x10); + } + + public static void RST_3(CPU cpu) + { + CALL(cpu, 0x18); + } + + public static void RST_4(CPU cpu) + { + CALL(cpu, 0x20); + } + + public static void RST_5(CPU cpu) + { + CALL(cpu, 0x28); + } + + public static void RST_6(CPU cpu) + { + CALL(cpu, 0x30); + } + + public static void RST_7(CPU cpu) + { + CALL(cpu, 0x38); + } } \ No newline at end of file diff --git a/Intel8080.Emulator/Instructions/CarryBitInstructions.cs b/Intel8080.Emulator/Instructions/CarryBitInstructions.cs index 63395e2..2cb07b8 100644 --- a/Intel8080.Emulator/Instructions/CarryBitInstructions.cs +++ b/Intel8080.Emulator/Instructions/CarryBitInstructions.cs @@ -1,23 +1,22 @@ -namespace Intel8080.Emulator.Instructions -{ - public static partial class DefaultInstructionSet - { - // 0x37 - STC - // Bytes - 1 - // Cycles - 4 - // Flags - C - public static void STC(CPU cpu) - { - cpu.Flags.Carry = true; - } - - // 0x3F - CMC - // Bytes - 1 - // Cycles - 4 - // Flags - C - public static void CMC(CPU cpu) - { - cpu.Flags.Carry = !cpu.Flags.Carry; - } - } +namespace Intel8080.Emulator.Instructions; + +public static partial class DefaultInstructionSet +{ + // 0x37 - STC + // Bytes - 1 + // Cycles - 4 + // Flags - C + public static void STC(CPU cpu) + { + cpu.Flags.Carry = true; + } + + // 0x3F - CMC + // Bytes - 1 + // Cycles - 4 + // Flags - C + public static void CMC(CPU cpu) + { + cpu.Flags.Carry = !cpu.Flags.Carry; + } } \ No newline at end of file diff --git a/Intel8080.Emulator/Instructions/ControlInstructions.cs b/Intel8080.Emulator/Instructions/ControlInstructions.cs index aba5c75..6af6fb2 100644 --- a/Intel8080.Emulator/Instructions/ControlInstructions.cs +++ b/Intel8080.Emulator/Instructions/ControlInstructions.cs @@ -1,47 +1,46 @@ -namespace Intel8080.Emulator.Instructions -{ - public static partial class DefaultInstructionSet - { - // 0x00 - NOP - // Bytes - 1 - // Cycles - 4 - // Flags - None - public static void NOP(CPU cpu) - { - return; - } - - // 0x76 - HLT - // Bytes - 1 - // Cycles - 7 - // Flags - None - public static void HLT(CPU cpu) - { - cpu.Halted = true; - } - - public static void OUT(CPU cpu) - { - var device = cpu.IOController.GetOutputDevice(cpu.ReadNextByte()); - - device.Write(cpu.Registers.A); - } - - public static void IN(CPU cpu) - { - var device = cpu.IOController.GetInputDevice(cpu.ReadNextByte()); - - cpu.Registers.A = device.Read(); - } - - public static void DI(CPU cpu) - { - cpu.InterruptEnabled = false; - } - - public static void EI(CPU cpu) - { - cpu.InterruptEnabled = true; - } - } +namespace Intel8080.Emulator.Instructions; + +public static partial class DefaultInstructionSet +{ + // 0x00 - NOP + // Bytes - 1 + // Cycles - 4 + // Flags - None + public static void NOP(CPU cpu) + { + return; + } + + // 0x76 - HLT + // Bytes - 1 + // Cycles - 7 + // Flags - None + public static void HLT(CPU cpu) + { + cpu.Halted = true; + } + + public static void OUT(CPU cpu) + { + var device = cpu.IOController.GetOutputDevice(cpu.ReadNextByte()); + + device.Write(cpu.Registers.A); + } + + public static void IN(CPU cpu) + { + var device = cpu.IOController.GetInputDevice(cpu.ReadNextByte()); + + cpu.Registers.A = device.Read(); + } + + public static void DI(CPU cpu) + { + cpu.InterruptEnabled = false; + } + + public static void EI(CPU cpu) + { + cpu.InterruptEnabled = true; + } } \ No newline at end of file diff --git a/Intel8080.Emulator/Instructions/DataTransferInstructions.cs b/Intel8080.Emulator/Instructions/DataTransferInstructions.cs index 44a4178..4462ad8 100644 --- a/Intel8080.Emulator/Instructions/DataTransferInstructions.cs +++ b/Intel8080.Emulator/Instructions/DataTransferInstructions.cs @@ -1,651 +1,650 @@ -namespace Intel8080.Emulator.Instructions -{ - public static partial class DefaultInstructionSet - { - private static void MOV(ref byte targetReg, ref byte sourceReg) - { - targetReg = sourceReg; - } - - private static void STAX(CPU cpu, ushort reg) - { - cpu.Memory[reg] = cpu.Registers.A; - } - - private static void LDAX(CPU cpu, ushort reg) - { - cpu.Registers.A = cpu.Memory[reg]; - } - - // 0x40 - MOV B, B - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_B_B(CPU cpu) - { - MOV(ref cpu.Registers.B, ref cpu.Registers.B); - } - - // 0x41 - MOV B, C - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_B_C(CPU cpu) - { - MOV(ref cpu.Registers.B, ref cpu.Registers.C); - } - - // 0x42 - MOV B, D - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_B_D(CPU cpu) - { - MOV(ref cpu.Registers.B, ref cpu.Registers.D); - } - - // 0x43 - MOV B, E - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_B_E(CPU cpu) - { - MOV(ref cpu.Registers.B, ref cpu.Registers.E); - } - - // 0x44 - MOV B, H - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_B_H(CPU cpu) - { - MOV(ref cpu.Registers.B, ref cpu.Registers.H); - } - - // 0x45 - MOV B, L - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_B_L(CPU cpu) - { - MOV(ref cpu.Registers.B, ref cpu.Registers.L); - } - - // 0x46 - MOV B, M - // Bytes - 1 - // Cycles - 7 - // Flags - None - public static void MOV_B_M(CPU cpu) - { - var location = GetUshort(cpu.Registers.H, cpu.Registers.L); - - cpu.Registers.B = cpu.Memory[location]; - } - - // 0x47 - MOV B, L - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_B_A(CPU cpu) - { - MOV(ref cpu.Registers.B, ref cpu.Registers.A); - } - - // 0x48 - MOV C, B - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_C_B(CPU cpu) - { - MOV(ref cpu.Registers.C, ref cpu.Registers.B); - } - - // 0x49 - MOV C, C - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_C_C(CPU cpu) - { - MOV(ref cpu.Registers.C, ref cpu.Registers.C); - } - - // 0x4A - MOV C, D - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_C_D(CPU cpu) - { - MOV(ref cpu.Registers.C, ref cpu.Registers.D); - } - - // 0x4B - MOV C, E - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_C_E(CPU cpu) - { - MOV(ref cpu.Registers.C, ref cpu.Registers.E); - } - - // 0x4C - MOV C, H - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_C_H(CPU cpu) - { - MOV(ref cpu.Registers.C, ref cpu.Registers.H); - } - - // 0x4D - MOV C, L - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_C_L(CPU cpu) - { - MOV(ref cpu.Registers.C, ref cpu.Registers.L); - } - - // 0x4E - MOV C, M - // Bytes - 1 - // Cycles - 7 - // Flags - None - public static void MOV_C_M(CPU cpu) - { - var location = GetUshort(cpu.Registers.H, cpu.Registers.L); - - cpu.Registers.C = cpu.Memory[location]; - } - - // 0x4F - MOV C, L - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_C_A(CPU cpu) - { - MOV(ref cpu.Registers.C, ref cpu.Registers.A); - } - - // 0x50 - MOV D, B - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_D_B(CPU cpu) - { - MOV(ref cpu.Registers.D, ref cpu.Registers.B); - } - - // 0x51 - MOV D, C - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_D_C(CPU cpu) - { - MOV(ref cpu.Registers.D, ref cpu.Registers.C); - } - - // 0x52 - MOV D, D - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_D_D(CPU cpu) - { - MOV(ref cpu.Registers.D, ref cpu.Registers.D); - } - - // 0x53 - MOV D, E - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_D_E(CPU cpu) - { - MOV(ref cpu.Registers.D, ref cpu.Registers.E); - } - - // 0x54 - MOV D, H - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_D_H(CPU cpu) - { - MOV(ref cpu.Registers.D, ref cpu.Registers.H); - } - - // 0x55 - MOV D, L - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_D_L(CPU cpu) - { - MOV(ref cpu.Registers.D, ref cpu.Registers.L); - } - - // 0x56 - MOV D, M - // Bytes - 1 - // Cycles - 7 - // Flags - None - public static void MOV_D_M(CPU cpu) - { - var location = GetUshort(cpu.Registers.H, cpu.Registers.L); - - cpu.Registers.D = cpu.Memory[location]; - } - - // 0x57 - MOV D, L - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_D_A(CPU cpu) - { - MOV(ref cpu.Registers.D, ref cpu.Registers.A); - } - - // 0x58 - MOV E, B - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_E_B(CPU cpu) - { - MOV(ref cpu.Registers.E, ref cpu.Registers.B); - } - - // 0x59 - MOV E, C - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_E_C(CPU cpu) - { - MOV(ref cpu.Registers.E, ref cpu.Registers.C); - } - - // 0x5A - MOV E, D - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_E_D(CPU cpu) - { - MOV(ref cpu.Registers.E, ref cpu.Registers.D); - } - - // 0x5B - MOV E, E - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_E_E(CPU cpu) - { - MOV(ref cpu.Registers.E, ref cpu.Registers.E); - } - - // 0x5C - MOV E, H - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_E_H(CPU cpu) - { - MOV(ref cpu.Registers.E, ref cpu.Registers.H); - } - - // 0x5D - MOV E, L - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_E_L(CPU cpu) - { - MOV(ref cpu.Registers.E, ref cpu.Registers.L); - } - - // 0x5E - MOV E, M - // Bytes - 1 - // Cycles - 7 - // Flags - None - public static void MOV_E_M(CPU cpu) - { - var location = GetUshort(cpu.Registers.H, cpu.Registers.L); - - cpu.Registers.E = cpu.Memory[location]; - } - - // 0x5F - MOV E, L - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_E_A(CPU cpu) - { - MOV(ref cpu.Registers.E, ref cpu.Registers.A); - } - - // 0x60 - MOV H, B - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_H_B(CPU cpu) - { - MOV(ref cpu.Registers.H, ref cpu.Registers.B); - } - - // 0x61 - MOV H, C - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_H_C(CPU cpu) - { - MOV(ref cpu.Registers.H, ref cpu.Registers.C); - } - - // 0x62 - MOV H, D - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_H_D(CPU cpu) - { - MOV(ref cpu.Registers.H, ref cpu.Registers.D); - } - - // 0x63 - MOV H, E - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_H_E(CPU cpu) - { - MOV(ref cpu.Registers.H, ref cpu.Registers.E); - } - - // 0x64 - MOV H, H - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_H_H(CPU cpu) - { - MOV(ref cpu.Registers.H, ref cpu.Registers.H); - } - - // 0x65 - MOV H, L - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_H_L(CPU cpu) - { - MOV(ref cpu.Registers.H, ref cpu.Registers.L); - } - - // 0x66 - MOV H, M - // Bytes - 1 - // Cycles - 7 - // Flags - None - public static void MOV_H_M(CPU cpu) - { - var location = GetUshort(cpu.Registers.H, cpu.Registers.L); - - cpu.Registers.H = cpu.Memory[location]; - } - - // 0x67 - MOV H, L - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_H_A(CPU cpu) - { - MOV(ref cpu.Registers.H, ref cpu.Registers.A); - } - - // 0x68 - MOV L, B - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_L_B(CPU cpu) - { - MOV(ref cpu.Registers.L, ref cpu.Registers.B); - } - - // 0x69 - MOV L, C - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_L_C(CPU cpu) - { - MOV(ref cpu.Registers.L, ref cpu.Registers.C); - } - - // 0x6A - MOV L, D - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_L_D(CPU cpu) - { - MOV(ref cpu.Registers.L, ref cpu.Registers.D); - } - - // 0x6B - MOV L, E - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_L_E(CPU cpu) - { - MOV(ref cpu.Registers.L, ref cpu.Registers.E); - } - - // 0x6C - MOV L, H - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_L_H(CPU cpu) - { - MOV(ref cpu.Registers.L, ref cpu.Registers.H); - } - - // 0x6D - MOV L, L - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_L_L(CPU cpu) - { - MOV(ref cpu.Registers.L, ref cpu.Registers.L); - } - - // 0x6E - MOV L, M - // Bytes - 1 - // Cycles - 7 - // Flags - None - public static void MOV_L_M(CPU cpu) - { - var location = GetUshort(cpu.Registers.H, cpu.Registers.L); - - cpu.Registers.L = cpu.Memory[location]; - } - - // 0x6F - MOV L, L - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_L_A(CPU cpu) - { - MOV(ref cpu.Registers.L, ref cpu.Registers.A); - } - - // 0x70 - MOV M, B - // Bytes - 1 - // Cycles - 7 - // Flags - None - public static void MOV_M_B(CPU cpu) - { - var location = GetUshort(cpu.Registers.H, cpu.Registers.L); - - cpu.Memory[location] = cpu.Registers.B; - } - - // 0x71 - MOV M, C - // Bytes - 1 - // Cycles - 7 - // Flags - None - public static void MOV_M_C(CPU cpu) - { - var location = GetUshort(cpu.Registers.H, cpu.Registers.L); - - cpu.Memory[location] = cpu.Registers.C; - } - - // 0x72 - MOV M, D - // Bytes - 1 - // Cycles - 7 - // Flags - None - public static void MOV_M_D(CPU cpu) - { - var location = GetUshort(cpu.Registers.H, cpu.Registers.L); - - cpu.Memory[location] = cpu.Registers.D; - } - - // 0x73 - MOV M, E - // Bytes - 1 - // Cycles - 7 - // Flags - None - public static void MOV_M_E(CPU cpu) - { - var location = GetUshort(cpu.Registers.H, cpu.Registers.L); - - cpu.Memory[location] = cpu.Registers.E; - } - - // 0x74 - MOV M, H - // Bytes - 1 - // Cycles - 7 - // Flags - None - public static void MOV_M_H(CPU cpu) - { - var location = GetUshort(cpu.Registers.H, cpu.Registers.L); - - cpu.Memory[location] = cpu.Registers.H; - } - - // 0x75 - MOV M, L - // Bytes - 1 - // Cycles - 7 - // Flags - None - public static void MOV_M_L(CPU cpu) - { - var location = GetUshort(cpu.Registers.H, cpu.Registers.L); - - cpu.Memory[location] = cpu.Registers.L; - } - - // 0x77 - MOV M, A - // Bytes - 1 - // Cycles - 7 - // Flags - None - public static void MOV_M_A(CPU cpu) - { - var location = GetUshort(cpu.Registers.H, cpu.Registers.L); - - cpu.Memory[location] = cpu.Registers.A; - } - - // 0x78 - MOV A, B - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_A_B(CPU cpu) - { - MOV(ref cpu.Registers.A, ref cpu.Registers.B); - } - - // 0x79 - MOV A, C - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_A_C(CPU cpu) - { - MOV(ref cpu.Registers.A, ref cpu.Registers.C); - } - - // 0x7A - MOV A, D - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_A_D(CPU cpu) - { - MOV(ref cpu.Registers.A, ref cpu.Registers.D); - } - - // 0x7B - MOV A, E - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_A_E(CPU cpu) - { - MOV(ref cpu.Registers.A, ref cpu.Registers.E); - } - - // 0x7C - MOV A, H - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_A_H(CPU cpu) - { - MOV(ref cpu.Registers.A, ref cpu.Registers.H); - } - - // 0x7D - MOV A, L - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_A_L(CPU cpu) - { - MOV(ref cpu.Registers.A, ref cpu.Registers.L); - } - - // 0x7E - MOV A, M - // Bytes - 1 - // Cycles - 7 - // Flags - None - public static void MOV_A_M(CPU cpu) - { - var location = GetUshort(cpu.Registers.H, cpu.Registers.L); - - cpu.Registers.A = cpu.Memory[location]; - } - - // 0x7F - MOV A, A - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void MOV_A_A(CPU cpu) - { - MOV(ref cpu.Registers.A, ref cpu.Registers.A); - } - - // 0x02 - STAX B - // Bytes - 1 - // Cycles - 7 - // Flags - None - public static void STAX_B(CPU cpu) - { - STAX(cpu, cpu.Registers.BC); - } - - // 0x12 - STAX D - // Bytes - 1 - // Cycles - 7 - // Flags - None - public static void STAX_D(CPU cpu) - { - STAX(cpu, cpu.Registers.DE); - } - - // 0x0A - LDAX B - // Bytes - 1 - // Cycles - 7 - // Flags - None - public static void LDAX_B(CPU cpu) - { - LDAX(cpu, cpu.Registers.BC); - } - - // 0x1A - LDAX D - // Bytes - 1 - // Cycles - 7 - // Flags - None - public static void LDAX_D(CPU cpu) - { - LDAX(cpu, cpu.Registers.DE); - } - } +namespace Intel8080.Emulator.Instructions; + +public static partial class DefaultInstructionSet +{ + private static void MOV(ref byte targetReg, ref byte sourceReg) + { + targetReg = sourceReg; + } + + private static void STAX(CPU cpu, ushort reg) + { + cpu.Memory[reg] = cpu.Registers.A; + } + + private static void LDAX(CPU cpu, ushort reg) + { + cpu.Registers.A = cpu.Memory[reg]; + } + + // 0x40 - MOV B, B + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_B_B(CPU cpu) + { + MOV(ref cpu.Registers.B, ref cpu.Registers.B); + } + + // 0x41 - MOV B, C + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_B_C(CPU cpu) + { + MOV(ref cpu.Registers.B, ref cpu.Registers.C); + } + + // 0x42 - MOV B, D + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_B_D(CPU cpu) + { + MOV(ref cpu.Registers.B, ref cpu.Registers.D); + } + + // 0x43 - MOV B, E + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_B_E(CPU cpu) + { + MOV(ref cpu.Registers.B, ref cpu.Registers.E); + } + + // 0x44 - MOV B, H + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_B_H(CPU cpu) + { + MOV(ref cpu.Registers.B, ref cpu.Registers.H); + } + + // 0x45 - MOV B, L + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_B_L(CPU cpu) + { + MOV(ref cpu.Registers.B, ref cpu.Registers.L); + } + + // 0x46 - MOV B, M + // Bytes - 1 + // Cycles - 7 + // Flags - None + public static void MOV_B_M(CPU cpu) + { + var location = GetUshort(cpu.Registers.H, cpu.Registers.L); + + cpu.Registers.B = cpu.Memory[location]; + } + + // 0x47 - MOV B, L + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_B_A(CPU cpu) + { + MOV(ref cpu.Registers.B, ref cpu.Registers.A); + } + + // 0x48 - MOV C, B + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_C_B(CPU cpu) + { + MOV(ref cpu.Registers.C, ref cpu.Registers.B); + } + + // 0x49 - MOV C, C + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_C_C(CPU cpu) + { + MOV(ref cpu.Registers.C, ref cpu.Registers.C); + } + + // 0x4A - MOV C, D + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_C_D(CPU cpu) + { + MOV(ref cpu.Registers.C, ref cpu.Registers.D); + } + + // 0x4B - MOV C, E + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_C_E(CPU cpu) + { + MOV(ref cpu.Registers.C, ref cpu.Registers.E); + } + + // 0x4C - MOV C, H + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_C_H(CPU cpu) + { + MOV(ref cpu.Registers.C, ref cpu.Registers.H); + } + + // 0x4D - MOV C, L + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_C_L(CPU cpu) + { + MOV(ref cpu.Registers.C, ref cpu.Registers.L); + } + + // 0x4E - MOV C, M + // Bytes - 1 + // Cycles - 7 + // Flags - None + public static void MOV_C_M(CPU cpu) + { + var location = GetUshort(cpu.Registers.H, cpu.Registers.L); + + cpu.Registers.C = cpu.Memory[location]; + } + + // 0x4F - MOV C, L + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_C_A(CPU cpu) + { + MOV(ref cpu.Registers.C, ref cpu.Registers.A); + } + + // 0x50 - MOV D, B + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_D_B(CPU cpu) + { + MOV(ref cpu.Registers.D, ref cpu.Registers.B); + } + + // 0x51 - MOV D, C + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_D_C(CPU cpu) + { + MOV(ref cpu.Registers.D, ref cpu.Registers.C); + } + + // 0x52 - MOV D, D + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_D_D(CPU cpu) + { + MOV(ref cpu.Registers.D, ref cpu.Registers.D); + } + + // 0x53 - MOV D, E + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_D_E(CPU cpu) + { + MOV(ref cpu.Registers.D, ref cpu.Registers.E); + } + + // 0x54 - MOV D, H + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_D_H(CPU cpu) + { + MOV(ref cpu.Registers.D, ref cpu.Registers.H); + } + + // 0x55 - MOV D, L + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_D_L(CPU cpu) + { + MOV(ref cpu.Registers.D, ref cpu.Registers.L); + } + + // 0x56 - MOV D, M + // Bytes - 1 + // Cycles - 7 + // Flags - None + public static void MOV_D_M(CPU cpu) + { + var location = GetUshort(cpu.Registers.H, cpu.Registers.L); + + cpu.Registers.D = cpu.Memory[location]; + } + + // 0x57 - MOV D, L + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_D_A(CPU cpu) + { + MOV(ref cpu.Registers.D, ref cpu.Registers.A); + } + + // 0x58 - MOV E, B + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_E_B(CPU cpu) + { + MOV(ref cpu.Registers.E, ref cpu.Registers.B); + } + + // 0x59 - MOV E, C + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_E_C(CPU cpu) + { + MOV(ref cpu.Registers.E, ref cpu.Registers.C); + } + + // 0x5A - MOV E, D + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_E_D(CPU cpu) + { + MOV(ref cpu.Registers.E, ref cpu.Registers.D); + } + + // 0x5B - MOV E, E + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_E_E(CPU cpu) + { + MOV(ref cpu.Registers.E, ref cpu.Registers.E); + } + + // 0x5C - MOV E, H + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_E_H(CPU cpu) + { + MOV(ref cpu.Registers.E, ref cpu.Registers.H); + } + + // 0x5D - MOV E, L + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_E_L(CPU cpu) + { + MOV(ref cpu.Registers.E, ref cpu.Registers.L); + } + + // 0x5E - MOV E, M + // Bytes - 1 + // Cycles - 7 + // Flags - None + public static void MOV_E_M(CPU cpu) + { + var location = GetUshort(cpu.Registers.H, cpu.Registers.L); + + cpu.Registers.E = cpu.Memory[location]; + } + + // 0x5F - MOV E, L + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_E_A(CPU cpu) + { + MOV(ref cpu.Registers.E, ref cpu.Registers.A); + } + + // 0x60 - MOV H, B + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_H_B(CPU cpu) + { + MOV(ref cpu.Registers.H, ref cpu.Registers.B); + } + + // 0x61 - MOV H, C + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_H_C(CPU cpu) + { + MOV(ref cpu.Registers.H, ref cpu.Registers.C); + } + + // 0x62 - MOV H, D + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_H_D(CPU cpu) + { + MOV(ref cpu.Registers.H, ref cpu.Registers.D); + } + + // 0x63 - MOV H, E + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_H_E(CPU cpu) + { + MOV(ref cpu.Registers.H, ref cpu.Registers.E); + } + + // 0x64 - MOV H, H + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_H_H(CPU cpu) + { + MOV(ref cpu.Registers.H, ref cpu.Registers.H); + } + + // 0x65 - MOV H, L + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_H_L(CPU cpu) + { + MOV(ref cpu.Registers.H, ref cpu.Registers.L); + } + + // 0x66 - MOV H, M + // Bytes - 1 + // Cycles - 7 + // Flags - None + public static void MOV_H_M(CPU cpu) + { + var location = GetUshort(cpu.Registers.H, cpu.Registers.L); + + cpu.Registers.H = cpu.Memory[location]; + } + + // 0x67 - MOV H, L + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_H_A(CPU cpu) + { + MOV(ref cpu.Registers.H, ref cpu.Registers.A); + } + + // 0x68 - MOV L, B + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_L_B(CPU cpu) + { + MOV(ref cpu.Registers.L, ref cpu.Registers.B); + } + + // 0x69 - MOV L, C + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_L_C(CPU cpu) + { + MOV(ref cpu.Registers.L, ref cpu.Registers.C); + } + + // 0x6A - MOV L, D + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_L_D(CPU cpu) + { + MOV(ref cpu.Registers.L, ref cpu.Registers.D); + } + + // 0x6B - MOV L, E + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_L_E(CPU cpu) + { + MOV(ref cpu.Registers.L, ref cpu.Registers.E); + } + + // 0x6C - MOV L, H + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_L_H(CPU cpu) + { + MOV(ref cpu.Registers.L, ref cpu.Registers.H); + } + + // 0x6D - MOV L, L + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_L_L(CPU cpu) + { + MOV(ref cpu.Registers.L, ref cpu.Registers.L); + } + + // 0x6E - MOV L, M + // Bytes - 1 + // Cycles - 7 + // Flags - None + public static void MOV_L_M(CPU cpu) + { + var location = GetUshort(cpu.Registers.H, cpu.Registers.L); + + cpu.Registers.L = cpu.Memory[location]; + } + + // 0x6F - MOV L, L + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_L_A(CPU cpu) + { + MOV(ref cpu.Registers.L, ref cpu.Registers.A); + } + + // 0x70 - MOV M, B + // Bytes - 1 + // Cycles - 7 + // Flags - None + public static void MOV_M_B(CPU cpu) + { + var location = GetUshort(cpu.Registers.H, cpu.Registers.L); + + cpu.Memory[location] = cpu.Registers.B; + } + + // 0x71 - MOV M, C + // Bytes - 1 + // Cycles - 7 + // Flags - None + public static void MOV_M_C(CPU cpu) + { + var location = GetUshort(cpu.Registers.H, cpu.Registers.L); + + cpu.Memory[location] = cpu.Registers.C; + } + + // 0x72 - MOV M, D + // Bytes - 1 + // Cycles - 7 + // Flags - None + public static void MOV_M_D(CPU cpu) + { + var location = GetUshort(cpu.Registers.H, cpu.Registers.L); + + cpu.Memory[location] = cpu.Registers.D; + } + + // 0x73 - MOV M, E + // Bytes - 1 + // Cycles - 7 + // Flags - None + public static void MOV_M_E(CPU cpu) + { + var location = GetUshort(cpu.Registers.H, cpu.Registers.L); + + cpu.Memory[location] = cpu.Registers.E; + } + + // 0x74 - MOV M, H + // Bytes - 1 + // Cycles - 7 + // Flags - None + public static void MOV_M_H(CPU cpu) + { + var location = GetUshort(cpu.Registers.H, cpu.Registers.L); + + cpu.Memory[location] = cpu.Registers.H; + } + + // 0x75 - MOV M, L + // Bytes - 1 + // Cycles - 7 + // Flags - None + public static void MOV_M_L(CPU cpu) + { + var location = GetUshort(cpu.Registers.H, cpu.Registers.L); + + cpu.Memory[location] = cpu.Registers.L; + } + + // 0x77 - MOV M, A + // Bytes - 1 + // Cycles - 7 + // Flags - None + public static void MOV_M_A(CPU cpu) + { + var location = GetUshort(cpu.Registers.H, cpu.Registers.L); + + cpu.Memory[location] = cpu.Registers.A; + } + + // 0x78 - MOV A, B + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_A_B(CPU cpu) + { + MOV(ref cpu.Registers.A, ref cpu.Registers.B); + } + + // 0x79 - MOV A, C + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_A_C(CPU cpu) + { + MOV(ref cpu.Registers.A, ref cpu.Registers.C); + } + + // 0x7A - MOV A, D + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_A_D(CPU cpu) + { + MOV(ref cpu.Registers.A, ref cpu.Registers.D); + } + + // 0x7B - MOV A, E + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_A_E(CPU cpu) + { + MOV(ref cpu.Registers.A, ref cpu.Registers.E); + } + + // 0x7C - MOV A, H + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_A_H(CPU cpu) + { + MOV(ref cpu.Registers.A, ref cpu.Registers.H); + } + + // 0x7D - MOV A, L + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_A_L(CPU cpu) + { + MOV(ref cpu.Registers.A, ref cpu.Registers.L); + } + + // 0x7E - MOV A, M + // Bytes - 1 + // Cycles - 7 + // Flags - None + public static void MOV_A_M(CPU cpu) + { + var location = GetUshort(cpu.Registers.H, cpu.Registers.L); + + cpu.Registers.A = cpu.Memory[location]; + } + + // 0x7F - MOV A, A + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void MOV_A_A(CPU cpu) + { + MOV(ref cpu.Registers.A, ref cpu.Registers.A); + } + + // 0x02 - STAX B + // Bytes - 1 + // Cycles - 7 + // Flags - None + public static void STAX_B(CPU cpu) + { + STAX(cpu, cpu.Registers.BC); + } + + // 0x12 - STAX D + // Bytes - 1 + // Cycles - 7 + // Flags - None + public static void STAX_D(CPU cpu) + { + STAX(cpu, cpu.Registers.DE); + } + + // 0x0A - LDAX B + // Bytes - 1 + // Cycles - 7 + // Flags - None + public static void LDAX_B(CPU cpu) + { + LDAX(cpu, cpu.Registers.BC); + } + + // 0x1A - LDAX D + // Bytes - 1 + // Cycles - 7 + // Flags - None + public static void LDAX_D(CPU cpu) + { + LDAX(cpu, cpu.Registers.DE); + } } \ No newline at end of file diff --git a/Intel8080.Emulator/Instructions/DefaultInstructionSet.cs b/Intel8080.Emulator/Instructions/DefaultInstructionSet.cs index 4db12bd..e8e673e 100644 --- a/Intel8080.Emulator/Instructions/DefaultInstructionSet.cs +++ b/Intel8080.Emulator/Instructions/DefaultInstructionSet.cs @@ -1,327 +1,326 @@ -using System; - -namespace Intel8080.Emulator.Instructions -{ - public static partial class DefaultInstructionSet - { - public static readonly Action[] Actions; - - static DefaultInstructionSet() - { - Actions = new Action[0x100]; - - // 0x0X - Actions[0x00] = NOP; - Actions[0x01] = LXI_B; - Actions[0x02] = STAX_B; - Actions[0x03] = INX_B; - Actions[0x04] = INR_B; - Actions[0x05] = DCR_B; - Actions[0x06] = MVI_B; - Actions[0x07] = RLC; - Actions[0x08] = NOP; - Actions[0x09] = DAD_B; - Actions[0x0A] = LDAX_B; - Actions[0x0B] = DCX_B; - Actions[0x0C] = INR_C; - Actions[0x0D] = DCR_C; - Actions[0x0E] = MVI_C; - Actions[0x0F] = RRC; - - // 0x1X - Actions[0x10] = NOP; - Actions[0x11] = LXI_D; - Actions[0x12] = STAX_D; - Actions[0x13] = INX_D; - Actions[0x14] = INR_D; - Actions[0x15] = DCR_D; - Actions[0x16] = MVI_D; - Actions[0x17] = RAL; - Actions[0x18] = NOP; - Actions[0x19] = DAD_D; - Actions[0x1A] = LDAX_D; - Actions[0x1B] = DCX_D; - Actions[0x1C] = INR_E; - Actions[0x1D] = DCR_E; - Actions[0x1E] = MVI_E; - Actions[0x1F] = RAR; - - // 0x2X - Actions[0x20] = NOP; - Actions[0x21] = LXI_H; - Actions[0x22] = SHLD; - Actions[0x23] = INX_H; - Actions[0x24] = INR_H; - Actions[0x25] = DCR_H; - Actions[0x26] = MVI_H; - Actions[0x27] = DAA; - Actions[0x28] = NOP; - Actions[0x29] = DAD_H; - Actions[0x2A] = LHLD; - Actions[0x2B] = DCX_H; - Actions[0x2C] = INR_L; - Actions[0x2D] = DCR_L; - Actions[0x2E] = MVI_L; - Actions[0x2F] = CMA; - - // 0x3X - Actions[0x30] = NOP; - Actions[0x31] = LXI_SP; - Actions[0x32] = STA; - Actions[0x33] = INX_SP; - Actions[0x34] = INR_M; - Actions[0x35] = DCR_M; - Actions[0x36] = MVI_M; - Actions[0x37] = STC; - Actions[0x38] = NOP; - Actions[0x39] = DAD_SP; - Actions[0x3A] = LDA; - Actions[0x3B] = DCX_SP; - Actions[0x3C] = INR_A; - Actions[0x3D] = DCR_A; - Actions[0x3E] = MVI_A; - Actions[0x3F] = CMC; - - // 0x4X - Actions[0x40] = MOV_B_B; - Actions[0x41] = MOV_B_C; - Actions[0x42] = MOV_B_D; - Actions[0x43] = MOV_B_E; - Actions[0x44] = MOV_B_H; - Actions[0x45] = MOV_B_L; - Actions[0x46] = MOV_B_M; - Actions[0x47] = MOV_B_A; - Actions[0x48] = MOV_C_B; - Actions[0x49] = MOV_C_C; - Actions[0x4A] = MOV_C_D; - Actions[0x4B] = MOV_C_E; - Actions[0x4C] = MOV_C_H; - Actions[0x4D] = MOV_C_L; - Actions[0x4E] = MOV_C_M; - Actions[0x4F] = MOV_C_A; - - // 0x5X - Actions[0x50] = MOV_D_B; - Actions[0x51] = MOV_D_C; - Actions[0x52] = MOV_D_D; - Actions[0x53] = MOV_D_E; - Actions[0x54] = MOV_D_H; - Actions[0x55] = MOV_D_L; - Actions[0x56] = MOV_D_M; - Actions[0x57] = MOV_D_A; - Actions[0x58] = MOV_E_B; - Actions[0x59] = MOV_E_C; - Actions[0x5A] = MOV_E_D; - Actions[0x5B] = MOV_E_E; - Actions[0x5C] = MOV_E_H; - Actions[0x5D] = MOV_E_L; - Actions[0x5E] = MOV_E_M; - Actions[0x5F] = MOV_E_A; - - // 0x6x - Actions[0x60] = MOV_H_B; - Actions[0x61] = MOV_H_C; - Actions[0x62] = MOV_H_D; - Actions[0x63] = MOV_H_E; - Actions[0x64] = MOV_H_H; - Actions[0x65] = MOV_H_L; - Actions[0x66] = MOV_H_M; - Actions[0x67] = MOV_H_A; - Actions[0x68] = MOV_L_B; - Actions[0x69] = MOV_L_C; - Actions[0x6A] = MOV_L_D; - Actions[0x6B] = MOV_L_E; - Actions[0x6C] = MOV_L_H; - Actions[0x6D] = MOV_L_L; - Actions[0x6E] = MOV_L_M; - Actions[0x6F] = MOV_L_A; - - // 0x7x - Actions[0x70] = MOV_M_B; - Actions[0x71] = MOV_M_C; - Actions[0x72] = MOV_M_D; - Actions[0x73] = MOV_M_E; - Actions[0x74] = MOV_M_H; - Actions[0x75] = MOV_M_L; - Actions[0x76] = HLT; - Actions[0x77] = MOV_M_A; - Actions[0x78] = MOV_A_B; - Actions[0x79] = MOV_A_C; - Actions[0x7A] = MOV_A_D; - Actions[0x7B] = MOV_A_E; - Actions[0x7C] = MOV_A_H; - Actions[0x7D] = MOV_A_L; - Actions[0x7E] = MOV_A_M; - Actions[0x7F] = MOV_A_A; - - // 0x8x - Actions[0x80] = ADD_B; - Actions[0x81] = ADD_C; - Actions[0x82] = ADD_D; - Actions[0x83] = ADD_E; - Actions[0x84] = ADD_H; - Actions[0x85] = ADD_L; - Actions[0x86] = ADD_M; - Actions[0x87] = ADD_A; - Actions[0x88] = ADC_B; - Actions[0x89] = ADC_C; - Actions[0x8A] = ADC_D; - Actions[0x8B] = ADC_E; - Actions[0x8C] = ADC_H; - Actions[0x8D] = ADC_L; - Actions[0x8E] = ADC_M; - Actions[0x8F] = ADC_A; - - // 0x9x - Actions[0x90] = SUB_B; - Actions[0x91] = SUB_C; - Actions[0x92] = SUB_D; - Actions[0x93] = SUB_E; - Actions[0x94] = SUB_H; - Actions[0x95] = SUB_L; - Actions[0x96] = SUB_M; - Actions[0x97] = SUB_A; - Actions[0x98] = SBB_B; - Actions[0x99] = SBB_C; - Actions[0x9A] = SBB_D; - Actions[0x9B] = SBB_E; - Actions[0x9C] = SBB_H; - Actions[0x9D] = SBB_L; - Actions[0x9E] = SBB_M; - Actions[0x9F] = SBB_A; - - // 0xAx - Actions[0xA0] = ANA_B; - Actions[0xA1] = ANA_C; - Actions[0xA2] = ANA_D; - Actions[0xA3] = ANA_E; - Actions[0xA4] = ANA_H; - Actions[0xA5] = ANA_L; - Actions[0xA6] = ANA_M; - Actions[0xA7] = ANA_A; - Actions[0xA8] = XRA_B; - Actions[0xA9] = XRA_C; - Actions[0xAA] = XRA_D; - Actions[0xAB] = XRA_E; - Actions[0xAC] = XRA_H; - Actions[0xAD] = XRA_L; - Actions[0xAE] = XRA_M; - Actions[0xAF] = XRA_A; - - // 0xBx - Actions[0xB0] = ORA_B; - Actions[0xB1] = ORA_C; - Actions[0xB2] = ORA_D; - Actions[0xB3] = ORA_E; - Actions[0xB4] = ORA_H; - Actions[0xB5] = ORA_L; - Actions[0xB6] = ORA_M; - Actions[0xB7] = ORA_A; - Actions[0xB8] = CMP_B; - Actions[0xB9] = CMP_C; - Actions[0xBA] = CMP_D; - Actions[0xBB] = CMP_E; - Actions[0xBC] = CMP_H; - Actions[0xBD] = CMP_L; - Actions[0xBE] = CMP_M; - Actions[0xBF] = CMP_A; - - // 0xCX - Actions[0xC0] = RNZ; - Actions[0xC1] = POP_B; - Actions[0xC2] = JNZ; - Actions[0xC3] = JMP; - Actions[0xC4] = CNZ; - Actions[0xC5] = PUSH_B; - Actions[0xC6] = ADI; - Actions[0xC7] = RST_0; - Actions[0xC8] = RZ; - Actions[0xC9] = RET; - Actions[0xCA] = JZ; - Actions[0xCB] = JMP; - Actions[0xCC] = CZ; - Actions[0xCD] = CALL; - Actions[0xCE] = ACI; - Actions[0xCF] = RST_1; - - // 0xDX - Actions[0xD0] = RNC; - Actions[0xD1] = POP_D; - Actions[0xD2] = JNC; - Actions[0xD3] = OUT; - Actions[0xD4] = CNC; - Actions[0xD5] = PUSH_D; - Actions[0xD6] = SUI; - Actions[0xD7] = RST_2; - Actions[0xD8] = RC; - Actions[0xD9] = RET; - Actions[0xDA] = JC; - Actions[0xDB] = IN; - Actions[0xDC] = CC; - Actions[0xDD] = CALL; - Actions[0xDE] = SBI; - Actions[0xDF] = RST_3; - - // 0xEX - Actions[0xE0] = RPO; - Actions[0xE1] = POP_H; - Actions[0xE2] = JPO; - Actions[0xE3] = XTHL; - Actions[0xE4] = CPO; - Actions[0xE5] = PUSH_H; - Actions[0xE6] = ANI; - Actions[0xE7] = RST_4; - Actions[0xE8] = RPE; - Actions[0xE9] = PCHL; - Actions[0xEA] = JPE; - Actions[0xEB] = XCHG; - Actions[0xEC] = CPE; - Actions[0xED] = CALL; - Actions[0xEE] = XRI; - Actions[0xEF] = RST_5; - - // 0xFX - Actions[0xF0] = RP; - Actions[0xF1] = POP_PSW; - Actions[0xF2] = JP; - Actions[0xF3] = DI; - Actions[0xF4] = CP; - Actions[0xF5] = PUSH_PSW; - Actions[0xF6] = ORI; - Actions[0xF7] = RST_6; - Actions[0xF8] = RM; - Actions[0xF9] = SPHL; - Actions[0xFA] = JM; - Actions[0xFB] = EI; - Actions[0xFC] = CM; - Actions[0xFD] = CALL; - Actions[0xFE] = CPI; - Actions[0xFF] = RST_7; - } - - private static ushort PopStack(CPU cpu) - { - ushort val = GetUshort( - cpu.Memory[cpu.Registers.SP + 1], - cpu.Memory[cpu.Registers.SP] - ); - - cpu.Registers.SP += 2; - - return val; - } - - private static void PushStack(CPU cpu, ushort data) - { - cpu.Registers.SP -= 2; - - cpu.Memory[cpu.Registers.SP + 1] = (byte) ((data & 0xFF00) >> 8); - cpu.Memory[cpu.Registers.SP] = (byte) (data & 0x00FF); - } - - private static ushort GetUshort(byte a, byte b) - { - return (ushort) ((a << 8) | b); - } - } +using System; + +namespace Intel8080.Emulator.Instructions; + +public static partial class DefaultInstructionSet +{ + public static readonly Action[] Actions; + + static DefaultInstructionSet() + { + Actions = new Action[0x100]; + + // 0x0X + Actions[0x00] = NOP; + Actions[0x01] = LXI_B; + Actions[0x02] = STAX_B; + Actions[0x03] = INX_B; + Actions[0x04] = INR_B; + Actions[0x05] = DCR_B; + Actions[0x06] = MVI_B; + Actions[0x07] = RLC; + Actions[0x08] = NOP; + Actions[0x09] = DAD_B; + Actions[0x0A] = LDAX_B; + Actions[0x0B] = DCX_B; + Actions[0x0C] = INR_C; + Actions[0x0D] = DCR_C; + Actions[0x0E] = MVI_C; + Actions[0x0F] = RRC; + + // 0x1X + Actions[0x10] = NOP; + Actions[0x11] = LXI_D; + Actions[0x12] = STAX_D; + Actions[0x13] = INX_D; + Actions[0x14] = INR_D; + Actions[0x15] = DCR_D; + Actions[0x16] = MVI_D; + Actions[0x17] = RAL; + Actions[0x18] = NOP; + Actions[0x19] = DAD_D; + Actions[0x1A] = LDAX_D; + Actions[0x1B] = DCX_D; + Actions[0x1C] = INR_E; + Actions[0x1D] = DCR_E; + Actions[0x1E] = MVI_E; + Actions[0x1F] = RAR; + + // 0x2X + Actions[0x20] = NOP; + Actions[0x21] = LXI_H; + Actions[0x22] = SHLD; + Actions[0x23] = INX_H; + Actions[0x24] = INR_H; + Actions[0x25] = DCR_H; + Actions[0x26] = MVI_H; + Actions[0x27] = DAA; + Actions[0x28] = NOP; + Actions[0x29] = DAD_H; + Actions[0x2A] = LHLD; + Actions[0x2B] = DCX_H; + Actions[0x2C] = INR_L; + Actions[0x2D] = DCR_L; + Actions[0x2E] = MVI_L; + Actions[0x2F] = CMA; + + // 0x3X + Actions[0x30] = NOP; + Actions[0x31] = LXI_SP; + Actions[0x32] = STA; + Actions[0x33] = INX_SP; + Actions[0x34] = INR_M; + Actions[0x35] = DCR_M; + Actions[0x36] = MVI_M; + Actions[0x37] = STC; + Actions[0x38] = NOP; + Actions[0x39] = DAD_SP; + Actions[0x3A] = LDA; + Actions[0x3B] = DCX_SP; + Actions[0x3C] = INR_A; + Actions[0x3D] = DCR_A; + Actions[0x3E] = MVI_A; + Actions[0x3F] = CMC; + + // 0x4X + Actions[0x40] = MOV_B_B; + Actions[0x41] = MOV_B_C; + Actions[0x42] = MOV_B_D; + Actions[0x43] = MOV_B_E; + Actions[0x44] = MOV_B_H; + Actions[0x45] = MOV_B_L; + Actions[0x46] = MOV_B_M; + Actions[0x47] = MOV_B_A; + Actions[0x48] = MOV_C_B; + Actions[0x49] = MOV_C_C; + Actions[0x4A] = MOV_C_D; + Actions[0x4B] = MOV_C_E; + Actions[0x4C] = MOV_C_H; + Actions[0x4D] = MOV_C_L; + Actions[0x4E] = MOV_C_M; + Actions[0x4F] = MOV_C_A; + + // 0x5X + Actions[0x50] = MOV_D_B; + Actions[0x51] = MOV_D_C; + Actions[0x52] = MOV_D_D; + Actions[0x53] = MOV_D_E; + Actions[0x54] = MOV_D_H; + Actions[0x55] = MOV_D_L; + Actions[0x56] = MOV_D_M; + Actions[0x57] = MOV_D_A; + Actions[0x58] = MOV_E_B; + Actions[0x59] = MOV_E_C; + Actions[0x5A] = MOV_E_D; + Actions[0x5B] = MOV_E_E; + Actions[0x5C] = MOV_E_H; + Actions[0x5D] = MOV_E_L; + Actions[0x5E] = MOV_E_M; + Actions[0x5F] = MOV_E_A; + + // 0x6x + Actions[0x60] = MOV_H_B; + Actions[0x61] = MOV_H_C; + Actions[0x62] = MOV_H_D; + Actions[0x63] = MOV_H_E; + Actions[0x64] = MOV_H_H; + Actions[0x65] = MOV_H_L; + Actions[0x66] = MOV_H_M; + Actions[0x67] = MOV_H_A; + Actions[0x68] = MOV_L_B; + Actions[0x69] = MOV_L_C; + Actions[0x6A] = MOV_L_D; + Actions[0x6B] = MOV_L_E; + Actions[0x6C] = MOV_L_H; + Actions[0x6D] = MOV_L_L; + Actions[0x6E] = MOV_L_M; + Actions[0x6F] = MOV_L_A; + + // 0x7x + Actions[0x70] = MOV_M_B; + Actions[0x71] = MOV_M_C; + Actions[0x72] = MOV_M_D; + Actions[0x73] = MOV_M_E; + Actions[0x74] = MOV_M_H; + Actions[0x75] = MOV_M_L; + Actions[0x76] = HLT; + Actions[0x77] = MOV_M_A; + Actions[0x78] = MOV_A_B; + Actions[0x79] = MOV_A_C; + Actions[0x7A] = MOV_A_D; + Actions[0x7B] = MOV_A_E; + Actions[0x7C] = MOV_A_H; + Actions[0x7D] = MOV_A_L; + Actions[0x7E] = MOV_A_M; + Actions[0x7F] = MOV_A_A; + + // 0x8x + Actions[0x80] = ADD_B; + Actions[0x81] = ADD_C; + Actions[0x82] = ADD_D; + Actions[0x83] = ADD_E; + Actions[0x84] = ADD_H; + Actions[0x85] = ADD_L; + Actions[0x86] = ADD_M; + Actions[0x87] = ADD_A; + Actions[0x88] = ADC_B; + Actions[0x89] = ADC_C; + Actions[0x8A] = ADC_D; + Actions[0x8B] = ADC_E; + Actions[0x8C] = ADC_H; + Actions[0x8D] = ADC_L; + Actions[0x8E] = ADC_M; + Actions[0x8F] = ADC_A; + + // 0x9x + Actions[0x90] = SUB_B; + Actions[0x91] = SUB_C; + Actions[0x92] = SUB_D; + Actions[0x93] = SUB_E; + Actions[0x94] = SUB_H; + Actions[0x95] = SUB_L; + Actions[0x96] = SUB_M; + Actions[0x97] = SUB_A; + Actions[0x98] = SBB_B; + Actions[0x99] = SBB_C; + Actions[0x9A] = SBB_D; + Actions[0x9B] = SBB_E; + Actions[0x9C] = SBB_H; + Actions[0x9D] = SBB_L; + Actions[0x9E] = SBB_M; + Actions[0x9F] = SBB_A; + + // 0xAx + Actions[0xA0] = ANA_B; + Actions[0xA1] = ANA_C; + Actions[0xA2] = ANA_D; + Actions[0xA3] = ANA_E; + Actions[0xA4] = ANA_H; + Actions[0xA5] = ANA_L; + Actions[0xA6] = ANA_M; + Actions[0xA7] = ANA_A; + Actions[0xA8] = XRA_B; + Actions[0xA9] = XRA_C; + Actions[0xAA] = XRA_D; + Actions[0xAB] = XRA_E; + Actions[0xAC] = XRA_H; + Actions[0xAD] = XRA_L; + Actions[0xAE] = XRA_M; + Actions[0xAF] = XRA_A; + + // 0xBx + Actions[0xB0] = ORA_B; + Actions[0xB1] = ORA_C; + Actions[0xB2] = ORA_D; + Actions[0xB3] = ORA_E; + Actions[0xB4] = ORA_H; + Actions[0xB5] = ORA_L; + Actions[0xB6] = ORA_M; + Actions[0xB7] = ORA_A; + Actions[0xB8] = CMP_B; + Actions[0xB9] = CMP_C; + Actions[0xBA] = CMP_D; + Actions[0xBB] = CMP_E; + Actions[0xBC] = CMP_H; + Actions[0xBD] = CMP_L; + Actions[0xBE] = CMP_M; + Actions[0xBF] = CMP_A; + + // 0xCX + Actions[0xC0] = RNZ; + Actions[0xC1] = POP_B; + Actions[0xC2] = JNZ; + Actions[0xC3] = JMP; + Actions[0xC4] = CNZ; + Actions[0xC5] = PUSH_B; + Actions[0xC6] = ADI; + Actions[0xC7] = RST_0; + Actions[0xC8] = RZ; + Actions[0xC9] = RET; + Actions[0xCA] = JZ; + Actions[0xCB] = JMP; + Actions[0xCC] = CZ; + Actions[0xCD] = CALL; + Actions[0xCE] = ACI; + Actions[0xCF] = RST_1; + + // 0xDX + Actions[0xD0] = RNC; + Actions[0xD1] = POP_D; + Actions[0xD2] = JNC; + Actions[0xD3] = OUT; + Actions[0xD4] = CNC; + Actions[0xD5] = PUSH_D; + Actions[0xD6] = SUI; + Actions[0xD7] = RST_2; + Actions[0xD8] = RC; + Actions[0xD9] = RET; + Actions[0xDA] = JC; + Actions[0xDB] = IN; + Actions[0xDC] = CC; + Actions[0xDD] = CALL; + Actions[0xDE] = SBI; + Actions[0xDF] = RST_3; + + // 0xEX + Actions[0xE0] = RPO; + Actions[0xE1] = POP_H; + Actions[0xE2] = JPO; + Actions[0xE3] = XTHL; + Actions[0xE4] = CPO; + Actions[0xE5] = PUSH_H; + Actions[0xE6] = ANI; + Actions[0xE7] = RST_4; + Actions[0xE8] = RPE; + Actions[0xE9] = PCHL; + Actions[0xEA] = JPE; + Actions[0xEB] = XCHG; + Actions[0xEC] = CPE; + Actions[0xED] = CALL; + Actions[0xEE] = XRI; + Actions[0xEF] = RST_5; + + // 0xFX + Actions[0xF0] = RP; + Actions[0xF1] = POP_PSW; + Actions[0xF2] = JP; + Actions[0xF3] = DI; + Actions[0xF4] = CP; + Actions[0xF5] = PUSH_PSW; + Actions[0xF6] = ORI; + Actions[0xF7] = RST_6; + Actions[0xF8] = RM; + Actions[0xF9] = SPHL; + Actions[0xFA] = JM; + Actions[0xFB] = EI; + Actions[0xFC] = CM; + Actions[0xFD] = CALL; + Actions[0xFE] = CPI; + Actions[0xFF] = RST_7; + } + + private static ushort PopStack(CPU cpu) + { + ushort val = GetUshort( + cpu.Memory[cpu.Registers.SP + 1], + cpu.Memory[cpu.Registers.SP] + ); + + cpu.Registers.SP += 2; + + return val; + } + + private static void PushStack(CPU cpu, ushort data) + { + cpu.Registers.SP -= 2; + + cpu.Memory[cpu.Registers.SP + 1] = (byte)((data & 0xFF00) >> 8); + cpu.Memory[cpu.Registers.SP] = (byte)(data & 0x00FF); + } + + private static ushort GetUshort(byte a, byte b) + { + return (ushort)((a << 8) | b); + } } \ No newline at end of file diff --git a/Intel8080.Emulator/Instructions/DirectAddressingInstructions.cs b/Intel8080.Emulator/Instructions/DirectAddressingInstructions.cs index 04eeb25..08bbe59 100644 --- a/Intel8080.Emulator/Instructions/DirectAddressingInstructions.cs +++ b/Intel8080.Emulator/Instructions/DirectAddressingInstructions.cs @@ -1,51 +1,50 @@ -namespace Intel8080.Emulator.Instructions -{ - public static partial class DefaultInstructionSet - { - // 0x32 - STA a16 - // Bytes - 3 - // Cycles - 13 - // Flags - None - public static void STA(CPU cpu) - { - var location = cpu.ReadNextUshort(); - - cpu.Memory[location] = cpu.Registers.A; - } - - // 0x3A - LDA a16 - // Bytes - 3 - // Cycles - 13 - // Flags - C - public static void LDA(CPU cpu) - { - var location = cpu.ReadNextUshort(); - - cpu.Registers.A = cpu.Memory[location]; - } - - // 0x22 - SHLD a16 - // Bytes - 3 - // Cycles - 16 - // Flags - None - public static void SHLD(CPU cpu) - { - var location = cpu.ReadNextUshort(); - - cpu.Memory[location] = cpu.Registers.L; - cpu.Memory[location + 1] = cpu.Registers.H; - } - - // 0x2A - LHLD a16 - // Bytes - 3 - // Cycles - 16 - // Flags - None - public static void LHLD(CPU cpu) - { - var location = cpu.ReadNextUshort(); - - cpu.Registers.L = cpu.Memory[location]; - cpu.Registers.H = cpu.Memory[location + 1]; - } - } +namespace Intel8080.Emulator.Instructions; + +public static partial class DefaultInstructionSet +{ + // 0x32 - STA a16 + // Bytes - 3 + // Cycles - 13 + // Flags - None + public static void STA(CPU cpu) + { + var location = cpu.ReadNextUshort(); + + cpu.Memory[location] = cpu.Registers.A; + } + + // 0x3A - LDA a16 + // Bytes - 3 + // Cycles - 13 + // Flags - C + public static void LDA(CPU cpu) + { + var location = cpu.ReadNextUshort(); + + cpu.Registers.A = cpu.Memory[location]; + } + + // 0x22 - SHLD a16 + // Bytes - 3 + // Cycles - 16 + // Flags - None + public static void SHLD(CPU cpu) + { + var location = cpu.ReadNextUshort(); + + cpu.Memory[location] = cpu.Registers.L; + cpu.Memory[location + 1] = cpu.Registers.H; + } + + // 0x2A - LHLD a16 + // Bytes - 3 + // Cycles - 16 + // Flags - None + public static void LHLD(CPU cpu) + { + var location = cpu.ReadNextUshort(); + + cpu.Registers.L = cpu.Memory[location]; + cpu.Registers.H = cpu.Memory[location + 1]; + } } \ No newline at end of file diff --git a/Intel8080.Emulator/Instructions/ImmediateInstructions.cs b/Intel8080.Emulator/Instructions/ImmediateInstructions.cs index 0d3b90a..f0d98ba 100644 --- a/Intel8080.Emulator/Instructions/ImmediateInstructions.cs +++ b/Intel8080.Emulator/Instructions/ImmediateInstructions.cs @@ -1,183 +1,182 @@ -namespace Intel8080.Emulator.Instructions -{ - public static partial class DefaultInstructionSet - { - private static void LXI(CPU cpu, ref ushort reg) - { - var data = cpu.ReadNextUshort(); - - reg = data; - } - - private static void MVI(CPU cpu, ref byte reg) - { - reg = cpu.ReadNextByte(); - } - - // 0x01 - LXI, B,d16 - // Bytes - 3 - // Cycles - 10 - // Flags - None - public static void LXI_B(CPU cpu) - { - LXI(cpu, ref cpu.Registers.BC); - } - - // 0x11 - LXI D, d16 - // Bytes - 3 - // Cycles - 10 - // Flags - None - public static void LXI_D(CPU cpu) - { - LXI(cpu, ref cpu.Registers.DE); - } - - // 0x21 - LXI H, d16 - // Bytes - 1 - // Cycles - 4 - // Flags - None - public static void LXI_H(CPU cpu) - { - LXI(cpu, ref cpu.Registers.HL); - } - - // 0x31 - LXI SP, d16 - // Bytes - 3 - // Cycles - 10 - // Flags - None - public static void LXI_SP(CPU cpu) - { - LXI(cpu, ref cpu.Registers.SP); - } - - // 0x06 - MVI B,d8 - // Bytes - 2 - // Cycles - 7 - // Flags - None - public static void MVI_B(CPU cpu) - { - MVI(cpu, ref cpu.Registers.B); - } - - // 0x0E - MVI C, d8 - // Bytes - 2 - // Cycles - 7 - // Flags - None - public static void MVI_C(CPU cpu) - { - MVI(cpu, ref cpu.Registers.C); - } - - // 0x16 - MVI D, d8 - // Bytes - 2 - // Cycles - 7 - // Flags - None - public static void MVI_D(CPU cpu) - { - MVI(cpu, ref cpu.Registers.D); - } - - // 0x1E - MVI E, d8 - // Bytes - 2 - // Cycles - 7 - // Flags - None - public static void MVI_E(CPU cpu) - { - MVI(cpu, ref cpu.Registers.E); - } - - // 0x26 - MVI H, d8 - // Bytes - 2 - // Cycles - 7 - // Flags - None - public static void MVI_H(CPU cpu) - { - MVI(cpu, ref cpu.Registers.H); - } - - // 0x2E - MVI L, d8 - // Bytes - 2 - // Cycles - 7 - // Flags - None - public static void MVI_L(CPU cpu) - { - MVI(cpu, ref cpu.Registers.L); - } - - // 0x36 - MVI M - // Bytes - 2 - // Cycles - 10 - // Flags - None - public static void MVI_M(CPU cpu) - { - var location = cpu.Registers.HL; - - cpu.Memory[location] = cpu.ReadNextByte(); - } - - // 0x3E - MVI A, d8 - // Bytes - 2 - // Cycles - 7 - // Flags - None - public static void MVI_A(CPU cpu) - { - MVI(cpu, ref cpu.Registers.A); - } - - public static void ADI(CPU cpu) - { - var data = cpu.ReadNextByte(); - - ADD(cpu, ref data); - } - - public static void ACI(CPU cpu) - { - var data = cpu.ReadNextByte(); - - ADC(cpu, ref data); - } - - public static void SUI(CPU cpu) - { - var data = cpu.ReadNextByte(); - - SUB(cpu, ref data); - } - - public static void SBI(CPU cpu) - { - var data = cpu.ReadNextByte(); - - SBB(cpu, ref data); - } - - public static void ANI(CPU cpu) - { - var data = cpu.ReadNextByte(); - - ANA(cpu, ref data); - } - - public static void XRI(CPU cpu) - { - var data = cpu.ReadNextByte(); - - XRA(cpu, ref data); - } - - public static void ORI(CPU cpu) - { - var data = cpu.ReadNextByte(); - - ORA(cpu, ref data); - } - - public static void CPI(CPU cpu) - { - var data = cpu.ReadNextByte(); - - CMP(cpu, ref data); - } - } +namespace Intel8080.Emulator.Instructions; + +public static partial class DefaultInstructionSet +{ + private static void LXI(CPU cpu, ref ushort reg) + { + var data = cpu.ReadNextUshort(); + + reg = data; + } + + private static void MVI(CPU cpu, ref byte reg) + { + reg = cpu.ReadNextByte(); + } + + // 0x01 - LXI, B,d16 + // Bytes - 3 + // Cycles - 10 + // Flags - None + public static void LXI_B(CPU cpu) + { + LXI(cpu, ref cpu.Registers.BC); + } + + // 0x11 - LXI D, d16 + // Bytes - 3 + // Cycles - 10 + // Flags - None + public static void LXI_D(CPU cpu) + { + LXI(cpu, ref cpu.Registers.DE); + } + + // 0x21 - LXI H, d16 + // Bytes - 1 + // Cycles - 4 + // Flags - None + public static void LXI_H(CPU cpu) + { + LXI(cpu, ref cpu.Registers.HL); + } + + // 0x31 - LXI SP, d16 + // Bytes - 3 + // Cycles - 10 + // Flags - None + public static void LXI_SP(CPU cpu) + { + LXI(cpu, ref cpu.Registers.SP); + } + + // 0x06 - MVI B,d8 + // Bytes - 2 + // Cycles - 7 + // Flags - None + public static void MVI_B(CPU cpu) + { + MVI(cpu, ref cpu.Registers.B); + } + + // 0x0E - MVI C, d8 + // Bytes - 2 + // Cycles - 7 + // Flags - None + public static void MVI_C(CPU cpu) + { + MVI(cpu, ref cpu.Registers.C); + } + + // 0x16 - MVI D, d8 + // Bytes - 2 + // Cycles - 7 + // Flags - None + public static void MVI_D(CPU cpu) + { + MVI(cpu, ref cpu.Registers.D); + } + + // 0x1E - MVI E, d8 + // Bytes - 2 + // Cycles - 7 + // Flags - None + public static void MVI_E(CPU cpu) + { + MVI(cpu, ref cpu.Registers.E); + } + + // 0x26 - MVI H, d8 + // Bytes - 2 + // Cycles - 7 + // Flags - None + public static void MVI_H(CPU cpu) + { + MVI(cpu, ref cpu.Registers.H); + } + + // 0x2E - MVI L, d8 + // Bytes - 2 + // Cycles - 7 + // Flags - None + public static void MVI_L(CPU cpu) + { + MVI(cpu, ref cpu.Registers.L); + } + + // 0x36 - MVI M + // Bytes - 2 + // Cycles - 10 + // Flags - None + public static void MVI_M(CPU cpu) + { + var location = cpu.Registers.HL; + + cpu.Memory[location] = cpu.ReadNextByte(); + } + + // 0x3E - MVI A, d8 + // Bytes - 2 + // Cycles - 7 + // Flags - None + public static void MVI_A(CPU cpu) + { + MVI(cpu, ref cpu.Registers.A); + } + + public static void ADI(CPU cpu) + { + var data = cpu.ReadNextByte(); + + ADD(cpu, ref data); + } + + public static void ACI(CPU cpu) + { + var data = cpu.ReadNextByte(); + + ADC(cpu, ref data); + } + + public static void SUI(CPU cpu) + { + var data = cpu.ReadNextByte(); + + SUB(cpu, ref data); + } + + public static void SBI(CPU cpu) + { + var data = cpu.ReadNextByte(); + + SBB(cpu, ref data); + } + + public static void ANI(CPU cpu) + { + var data = cpu.ReadNextByte(); + + ANA(cpu, ref data); + } + + public static void XRI(CPU cpu) + { + var data = cpu.ReadNextByte(); + + XRA(cpu, ref data); + } + + public static void ORI(CPU cpu) + { + var data = cpu.ReadNextByte(); + + ORA(cpu, ref data); + } + + public static void CPI(CPU cpu) + { + var data = cpu.ReadNextByte(); + + CMP(cpu, ref data); + } } \ No newline at end of file diff --git a/Intel8080.Emulator/Instructions/JumpInstructions.cs b/Intel8080.Emulator/Instructions/JumpInstructions.cs index 32a2262..1de253d 100644 --- a/Intel8080.Emulator/Instructions/JumpInstructions.cs +++ b/Intel8080.Emulator/Instructions/JumpInstructions.cs @@ -1,86 +1,85 @@ -namespace Intel8080.Emulator.Instructions -{ - public static partial class DefaultInstructionSet - { - private static void JMP(CPU cpu, ushort address) - { - cpu.Registers.PC = address; - } - - public static void JMP(CPU cpu) - { - var location = cpu.ReadNextUshort(); - - JMP(cpu, location); - } - - public static void JNZ(CPU cpu) - { - var location = cpu.ReadNextUshort(); - - if (!cpu.Flags.Zero) - JMP(cpu, location); - } - - public static void JZ(CPU cpu) - { - var location = cpu.ReadNextUshort(); - - if (cpu.Flags.Zero) - JMP(cpu, location); - } - - public static void JNC(CPU cpu) - { - var location = cpu.ReadNextUshort(); - - if (!cpu.Flags.Carry) - JMP(cpu, location); - } - - public static void JC(CPU cpu) - { - var location = cpu.ReadNextUshort(); - - if (cpu.Flags.Carry) - JMP(cpu, location); - } - - public static void JPO(CPU cpu) - { - var location = cpu.ReadNextUshort(); - - if (!cpu.Flags.Parity) - JMP(cpu, location); - } - - public static void JPE(CPU cpu) - { - var location = cpu.ReadNextUshort(); - - if (cpu.Flags.Parity) - JMP(cpu, location); - } - - public static void JP(CPU cpu) - { - var location = cpu.ReadNextUshort(); - - if (!cpu.Flags.Sign) - JMP(cpu, location); - } - - public static void JM(CPU cpu) - { - var location = cpu.ReadNextUshort(); - - if (cpu.Flags.Sign) - JMP(cpu, location); - } - - public static void PCHL(CPU cpu) - { - cpu.Registers.PC = cpu.Registers.HL; - } - } +namespace Intel8080.Emulator.Instructions; + +public static partial class DefaultInstructionSet +{ + private static void JMP(CPU cpu, ushort address) + { + cpu.Registers.PC = address; + } + + public static void JMP(CPU cpu) + { + var location = cpu.ReadNextUshort(); + + JMP(cpu, location); + } + + public static void JNZ(CPU cpu) + { + var location = cpu.ReadNextUshort(); + + if (!cpu.Flags.Zero) + JMP(cpu, location); + } + + public static void JZ(CPU cpu) + { + var location = cpu.ReadNextUshort(); + + if (cpu.Flags.Zero) + JMP(cpu, location); + } + + public static void JNC(CPU cpu) + { + var location = cpu.ReadNextUshort(); + + if (!cpu.Flags.Carry) + JMP(cpu, location); + } + + public static void JC(CPU cpu) + { + var location = cpu.ReadNextUshort(); + + if (cpu.Flags.Carry) + JMP(cpu, location); + } + + public static void JPO(CPU cpu) + { + var location = cpu.ReadNextUshort(); + + if (!cpu.Flags.Parity) + JMP(cpu, location); + } + + public static void JPE(CPU cpu) + { + var location = cpu.ReadNextUshort(); + + if (cpu.Flags.Parity) + JMP(cpu, location); + } + + public static void JP(CPU cpu) + { + var location = cpu.ReadNextUshort(); + + if (!cpu.Flags.Sign) + JMP(cpu, location); + } + + public static void JM(CPU cpu) + { + var location = cpu.ReadNextUshort(); + + if (cpu.Flags.Sign) + JMP(cpu, location); + } + + public static void PCHL(CPU cpu) + { + cpu.Registers.PC = cpu.Registers.HL; + } } \ No newline at end of file diff --git a/Intel8080.Emulator/Instructions/RegisterMemoryAccumulator.cs b/Intel8080.Emulator/Instructions/RegisterMemoryAccumulator.cs index 7c89f2b..bd168e9 100644 --- a/Intel8080.Emulator/Instructions/RegisterMemoryAccumulator.cs +++ b/Intel8080.Emulator/Instructions/RegisterMemoryAccumulator.cs @@ -1,647 +1,644 @@ -using System; - -namespace Intel8080.Emulator.Instructions -{ - public static partial class DefaultInstructionSet - { - private static void ADD(CPU cpu, ref byte reg) - { - cpu.Flags.CalcAuxCarryFlag(cpu.Registers.A, reg); - - var result = (ushort)(cpu.Registers.A + reg); - - cpu.Flags.CalcAuxCarryFlag(cpu.Registers.A, reg); - cpu.Flags.CalcCarryFlag(result); - - var resultByte = (byte)(result & 0x00FF); - - cpu.Flags.CalcSignFlag(resultByte); - cpu.Flags.CalcZeroFlag(resultByte); - cpu.Flags.CalcParityFlag(resultByte); - - cpu.Registers.A = resultByte; - } - - private static void ADC(CPU cpu, ref byte reg) - { - var carry = cpu.Flags.Carry ? 1 : 0; - - var result = (ushort)(cpu.Registers.A + reg + carry); - - cpu.Flags.CalcAuxCarryFlag(cpu.Registers.A, reg, carry); - cpu.Flags.CalcCarryFlag(result); - - var resultByte = (byte)(result & 0x00FF); - - cpu.Flags.CalcSignFlag(resultByte); - cpu.Flags.CalcZeroFlag(resultByte); - cpu.Flags.CalcParityFlag(resultByte); - - cpu.Registers.A = resultByte; - } - - private static void SUB(CPU cpu, ref byte reg) - { - var data = (byte)~reg; - - var borrow = 1; - - var result = (ushort)(cpu.Registers.A + data + borrow); - - cpu.Flags.CalcAuxCarryFlag(cpu.Registers.A, data, borrow); - cpu.Flags.CalcCarryFlag(result); - - var resultByte = (byte)(result & 0x00FF); - - cpu.Flags.CalcSignFlag(resultByte); - cpu.Flags.CalcZeroFlag(resultByte); - cpu.Flags.CalcParityFlag(resultByte); - - cpu.Registers.A = resultByte; - - cpu.Flags.Carry = !cpu.Flags.Carry; - } - - private static void SBB(CPU cpu, ref byte reg) - { - var data = (byte)~reg; - - var borrow = !cpu.Flags.Carry ? 1 : 0; - - var result = (ushort)(cpu.Registers.A + data + borrow); - - cpu.Flags.CalcAuxCarryFlag(cpu.Registers.A, data, borrow); - cpu.Flags.CalcCarryFlag(result); - - var resultByte = (byte)(result & 0x00FF); - - cpu.Flags.CalcSignFlag(resultByte); - cpu.Flags.CalcZeroFlag(resultByte); - cpu.Flags.CalcParityFlag(resultByte); - - cpu.Registers.A = resultByte; - - cpu.Flags.Carry = !cpu.Flags.Carry; - } - - private static void ANA(CPU cpu, ref byte reg) - { - cpu.Flags.AuxiliaryCarry = ((cpu.Registers.A & 0x08) | (reg & 0x08)) != 0; - - cpu.Registers.A &= reg; - - cpu.Flags.CalcSignFlag(cpu.Registers.A); - cpu.Flags.CalcZeroFlag(cpu.Registers.A); - cpu.Flags.CalcParityFlag(cpu.Registers.A); - cpu.Flags.Carry = false; - } - - private static void XRA(CPU cpu, ref byte reg) - { - cpu.Registers.A ^= reg; - - cpu.Flags.CalcSignFlag(cpu.Registers.A); - cpu.Flags.CalcZeroFlag(cpu.Registers.A); - cpu.Flags.CalcParityFlag(cpu.Registers.A); - cpu.Flags.Carry = false; - cpu.Flags.AuxiliaryCarry = false; - } - - private static void ORA(CPU cpu, ref byte reg) - { - cpu.Registers.A |= reg; - - cpu.Flags.CalcSignFlag(cpu.Registers.A); - cpu.Flags.CalcZeroFlag(cpu.Registers.A); - cpu.Flags.CalcParityFlag(cpu.Registers.A); - cpu.Flags.Carry = false; - cpu.Flags.AuxiliaryCarry = false; - } - - private static void CMP(CPU cpu, ref byte reg) - { - var data = (byte)~reg; - - var result = (ushort)(cpu.Registers.A + data + 1); - - cpu.Flags.CalcAuxCarryFlag(cpu.Registers.A, data, 1); - cpu.Flags.CalcCarryFlag(result); - - var resultByte = (byte)(result & 0x00FF); - - cpu.Flags.CalcSignFlag(resultByte); - cpu.Flags.CalcZeroFlag(resultByte); - cpu.Flags.CalcParityFlag(resultByte); - - cpu.Flags.Carry = !cpu.Flags.Carry; - } - - // 0x80 - ADD B - // Bytes - 1 - // Cycles - 4 - // Flags - S, Z, A, P, C - public static void ADD_B(CPU cpu) - { - ADD(cpu, ref cpu.Registers.B); - } - - // 0x81 - ADD C - // Bytes - 1 - // Cycles - 4 - // Flags - S, Z, A, P, C - public static void ADD_C(CPU cpu) - { - ADD(cpu, ref cpu.Registers.C); - } - - // 0x82 - ADD D - // Bytes - 1 - // Cycles - 4 - // Flags - S, Z, A, P, C - public static void ADD_D(CPU cpu) - { - ADD(cpu, ref cpu.Registers.D); - } - - // 0x83 - ADD E - // Bytes - 1 - // Cycles - 4 - // Flags - S, Z, A, P, C - public static void ADD_E(CPU cpu) - { - ADD(cpu, ref cpu.Registers.E); - } - - // 0x84 - ADD H - // Bytes - 1 - // Cycles - 4 - // Flags - S, Z, A, P, C - public static void ADD_H(CPU cpu) - { - ADD(cpu, ref cpu.Registers.H); - } - - // 0x85 - ADD L - // Bytes - 1 - // Cycles - 4 - // Flags - S, Z, A, P, C - public static void ADD_L(CPU cpu) - { - ADD(cpu, ref cpu.Registers.L); - } - - // 0x86 - ADD M - // Bytes - 1 - // Cycles - 7 - // Flags - S, Z, A, P, C - public static void ADD_M(CPU cpu) - { - var location = GetUshort(cpu.Registers.H, cpu.Registers.L); - - byte val = cpu.Memory[location]; - - ADD(cpu, ref val); - } - - // 0x87 - ADD A - // Bytes - 1 - // Cycles - 4 - // Flags - S, Z, A, P, C - public static void ADD_A(CPU cpu) - { - ADD(cpu, ref cpu.Registers.A); - } - - // 0x88 - ADC B - // Bytes - 1 - // Cycles - 4 - // Flags - S, Z, A, P, C - public static void ADC_B(CPU cpu) - { - ADC(cpu, ref cpu.Registers.B); - } - - // 0x89 - ADC C - // Bytes - 1 - // Cycles - 4 - // Flags - S, Z, A, P, C - public static void ADC_C(CPU cpu) - { - ADC(cpu, ref cpu.Registers.C); - } - - // 0x8A - ADC D - // Bytes - 1 - // Cycles - 4 - // Flags - S, Z, A, P, C - public static void ADC_D(CPU cpu) - { - ADC(cpu, ref cpu.Registers.D); - } - - // 0x8B - ADC E - // Bytes - 1 - // Cycles - 4 - // Flags - S, Z, A, P, C - public static void ADC_E(CPU cpu) - { - ADC(cpu, ref cpu.Registers.E); - } - - // 0x8C - ADC H - // Bytes - 1 - // Cycles - 4 - // Flags - S, Z, A, P, C - public static void ADC_H(CPU cpu) - { - ADC(cpu, ref cpu.Registers.H); - } - - // 0x8D - ADC L - // Bytes - 1 - // Cycles - 4 - // Flags - S, Z, A, P, C - public static void ADC_L(CPU cpu) - { - ADC(cpu, ref cpu.Registers.L); - } - - // 0x8E - ADD M - // Bytes - 1 - // Cycles - 7 - // Flags - S, Z, A, P, C - public static void ADC_M(CPU cpu) - { - var location = GetUshort(cpu.Registers.H, cpu.Registers.L); - - byte val = cpu.Memory[location]; - - ADC(cpu, ref val); - } - - // 0x8F - ADC A - // Bytes - 1 - // Cycles - 4 - // Flags - S, Z, A, P, C - public static void ADC_A(CPU cpu) - { - ADC(cpu, ref cpu.Registers.A); - } - - // 0x90 - SUB B - // Bytes - 1 - // Cycles - 4 - // Flags - S, Z, A, P, C - public static void SUB_B(CPU cpu) - { - SUB(cpu, ref cpu.Registers.B); - } - - // 0x91 - SUB C - // Bytes - 1 - // Cycles - 4 - // Flags - S, Z, A, P, C - public static void SUB_C(CPU cpu) - { - SUB(cpu, ref cpu.Registers.C); - } - - // 0x92 - SUB D - // Bytes - 1 - // Cycles - 4 - // Flags - S, Z, A, P, C - public static void SUB_D(CPU cpu) - { - SUB(cpu, ref cpu.Registers.D); - } - - // 0x93 - SUB E - // Bytes - 1 - // Cycles - 4 - // Flags - S, Z, A, P, C - public static void SUB_E(CPU cpu) - { - SUB(cpu, ref cpu.Registers.E); - } - - // 0x94 - SUB H - // Bytes - 1 - // Cycles - 4 - // Flags - S, Z, A, P, C - public static void SUB_H(CPU cpu) - { - SUB(cpu, ref cpu.Registers.H); - } - - // 0x95 - SUB L - // Bytes - 1 - // Cycles - 4 - // Flags - S, Z, A, P, C - public static void SUB_L(CPU cpu) - { - SUB(cpu, ref cpu.Registers.L); - } - - // 0x96 - SUB M - // Bytes - 1 - // Cycles - 7 - // Flags - S, Z, A, P, C - public static void SUB_M(CPU cpu) - { - var location = GetUshort(cpu.Registers.H, cpu.Registers.L); - - var val = cpu.Memory[location]; - - SUB(cpu, ref val); - } - - // 0x97 - SUB A - // Bytes - 1 - // Cycles - 4 - // Flags - S, Z, A, P, C - public static void SUB_A(CPU cpu) - { - SUB(cpu, ref cpu.Registers.A); - } - - // 0x98 - SBB B - // Bytes - 1 - // Cycles - 4 - // Flags - S, Z, A, P, C - public static void SBB_B(CPU cpu) - { - SBB(cpu, ref cpu.Registers.B); - } - - // 0x99 - SBB C - // Bytes - 1 - // Cycles - 4 - // Flags - S, Z, A, P, C - public static void SBB_C(CPU cpu) - { - SBB(cpu, ref cpu.Registers.C); - } - - // 0x9A - SBB D - // Bytes - 1 - // Cycles - 4 - // Flags - S, Z, A, P, C - public static void SBB_D(CPU cpu) - { - SBB(cpu, ref cpu.Registers.D); - } - - // 0x9B - SBB E - // Bytes - 1 - // Cycles - 4 - // Flags - S, Z, A, P, C - public static void SBB_E(CPU cpu) - { - SBB(cpu, ref cpu.Registers.E); - } - - // 0x9C - SBB H - // Bytes - 1 - // Cycles - 4 - // Flags - S, Z, A, P, C - public static void SBB_H(CPU cpu) - { - SBB(cpu, ref cpu.Registers.H); - } - - // 0x9D - SBB L - // Bytes - 1 - // Cycles - 4 - // Flags - S, Z, A, P, C - public static void SBB_L(CPU cpu) - { - SBB(cpu, ref cpu.Registers.L); - } - - // 0x9E - SBB M - // Bytes - 1 - // Cycles - 7 - // Flags - S, Z, A, P, C - public static void SBB_M(CPU cpu) - { - var location = GetUshort(cpu.Registers.H, cpu.Registers.L); - - var val = cpu.Memory[location]; - - SBB(cpu, ref val); - } - - // 0x9D - SBB A - // Bytes - 1 - // Cycles - 4 - // Flags - S, Z, A, P, C - public static void SBB_A(CPU cpu) - { - SBB(cpu, ref cpu.Registers.A); - } - - // 0xA0 - ANA B - // Bytes - 1 - // Cycles - 4 - // Flags - S, Z, A, P, C - public static void ANA_B(CPU cpu) - { - ANA(cpu, ref cpu.Registers.B); - } - - // 0xA1 - ANA C - // Bytes - 1 - // Cycles - 4 - // Flags - S, Z, A, P, C - public static void ANA_C(CPU cpu) - { - ANA(cpu, ref cpu.Registers.C); - } - - // 0xA2 - ANA D - // Bytes - 1 - // Cycles - 4 - // Flags - S, Z, A, P, C - public static void ANA_D(CPU cpu) - { - ANA(cpu, ref cpu.Registers.D); - } - - // 0xA3 - ANA E - // Bytes - 1 - // Cycles - 4 - // Flags - S, Z, A, P, C - public static void ANA_E(CPU cpu) - { - ANA(cpu, ref cpu.Registers.E); - } - - // 0xA4 - ANA H - // Bytes - 1 - // Cycles - 4 - // Flags - S, Z, A, P, C - public static void ANA_H(CPU cpu) - { - ANA(cpu, ref cpu.Registers.H); - } - - // 0xA5 - ANA L - // Bytes - 1 - // Cycles - 4 - // Flags - S, Z, A, P, C - public static void ANA_L(CPU cpu) - { - ANA(cpu, ref cpu.Registers.L); - } - - // 0xA6 - ANA M - // Bytes - 1 - // Cycles - 7 - // Flags - S, Z, A, P, C - public static void ANA_M(CPU cpu) - { - var location = GetUshort(cpu.Registers.H, cpu.Registers.L); - var val = cpu.Memory[location]; - - ANA(cpu, ref val); - } - - // 0xA7 - ANA A - // Bytes - 1 - // Cycles - 4 - // Flags - S, Z, A, P, C - public static void ANA_A(CPU cpu) - { - ANA(cpu, ref cpu.Registers.A); - } - - public static void XRA_B(CPU cpu) - { - XRA(cpu, ref cpu.Registers.B); - } - - public static void XRA_C(CPU cpu) - { - XRA(cpu, ref cpu.Registers.C); - } - - public static void XRA_D(CPU cpu) - { - XRA(cpu, ref cpu.Registers.D); - } - - public static void XRA_E(CPU cpu) - { - XRA(cpu, ref cpu.Registers.E); - } - - public static void XRA_H(CPU cpu) - { - XRA(cpu, ref cpu.Registers.H); - } - - public static void XRA_L(CPU cpu) - { - XRA(cpu, ref cpu.Registers.L); - } - - public static void XRA_M(CPU cpu) - { - var location = GetUshort(cpu.Registers.H, cpu.Registers.L); - var val = cpu.Memory[location]; - - XRA(cpu, ref val); - } - - public static void XRA_A(CPU cpu) - { - XRA(cpu, ref cpu.Registers.A); - } - - public static void ORA_B(CPU cpu) - { - ORA(cpu, ref cpu.Registers.B); - } - - public static void ORA_C(CPU cpu) - { - ORA(cpu, ref cpu.Registers.C); - } - - public static void ORA_D(CPU cpu) - { - ORA(cpu, ref cpu.Registers.D); - } - - public static void ORA_E(CPU cpu) - { - ORA(cpu, ref cpu.Registers.E); - } - - public static void ORA_H(CPU cpu) - { - ORA(cpu, ref cpu.Registers.H); - } - - public static void ORA_L(CPU cpu) - { - ORA(cpu, ref cpu.Registers.L); - } - - public static void ORA_M(CPU cpu) - { - var location = GetUshort(cpu.Registers.H, cpu.Registers.L); - var val = cpu.Memory[location]; - - ORA(cpu, ref val); - } - - public static void ORA_A(CPU cpu) - { - ORA(cpu, ref cpu.Registers.A); - } - - public static void CMP_B(CPU cpu) - { - CMP(cpu, ref cpu.Registers.B); - } - - public static void CMP_C(CPU cpu) - { - CMP(cpu, ref cpu.Registers.C); - } - - public static void CMP_D(CPU cpu) - { - CMP(cpu, ref cpu.Registers.D); - } - - public static void CMP_E(CPU cpu) - { - CMP(cpu, ref cpu.Registers.E); - } - - public static void CMP_H(CPU cpu) - { - CMP(cpu, ref cpu.Registers.H); - } - - public static void CMP_L(CPU cpu) - { - CMP(cpu, ref cpu.Registers.L); - } - - public static void CMP_M(CPU cpu) - { - var location = GetUshort(cpu.Registers.H, cpu.Registers.L); - var val = cpu.Memory[location]; - - CMP(cpu, ref val); - } - - public static void CMP_A(CPU cpu) - { - CMP(cpu, ref cpu.Registers.A); - } - } +namespace Intel8080.Emulator.Instructions; + +public static partial class DefaultInstructionSet +{ + private static void ADD(CPU cpu, ref byte reg) + { + cpu.Flags.CalcAuxCarryFlag(cpu.Registers.A, reg); + + var result = (ushort)(cpu.Registers.A + reg); + + cpu.Flags.CalcAuxCarryFlag(cpu.Registers.A, reg); + cpu.Flags.CalcCarryFlag(result); + + var resultByte = (byte)(result & 0x00FF); + + cpu.Flags.CalcSignFlag(resultByte); + cpu.Flags.CalcZeroFlag(resultByte); + cpu.Flags.CalcParityFlag(resultByte); + + cpu.Registers.A = resultByte; + } + + private static void ADC(CPU cpu, ref byte reg) + { + var carry = cpu.Flags.Carry ? 1 : 0; + + var result = (ushort)(cpu.Registers.A + reg + carry); + + cpu.Flags.CalcAuxCarryFlag(cpu.Registers.A, reg, carry); + cpu.Flags.CalcCarryFlag(result); + + var resultByte = (byte)(result & 0x00FF); + + cpu.Flags.CalcSignFlag(resultByte); + cpu.Flags.CalcZeroFlag(resultByte); + cpu.Flags.CalcParityFlag(resultByte); + + cpu.Registers.A = resultByte; + } + + private static void SUB(CPU cpu, ref byte reg) + { + var data = (byte)~reg; + + var borrow = 1; + + var result = (ushort)(cpu.Registers.A + data + borrow); + + cpu.Flags.CalcAuxCarryFlag(cpu.Registers.A, data, borrow); + cpu.Flags.CalcCarryFlag(result); + + var resultByte = (byte)(result & 0x00FF); + + cpu.Flags.CalcSignFlag(resultByte); + cpu.Flags.CalcZeroFlag(resultByte); + cpu.Flags.CalcParityFlag(resultByte); + + cpu.Registers.A = resultByte; + + cpu.Flags.Carry = !cpu.Flags.Carry; + } + + private static void SBB(CPU cpu, ref byte reg) + { + var data = (byte)~reg; + + var borrow = !cpu.Flags.Carry ? 1 : 0; + + var result = (ushort)(cpu.Registers.A + data + borrow); + + cpu.Flags.CalcAuxCarryFlag(cpu.Registers.A, data, borrow); + cpu.Flags.CalcCarryFlag(result); + + var resultByte = (byte)(result & 0x00FF); + + cpu.Flags.CalcSignFlag(resultByte); + cpu.Flags.CalcZeroFlag(resultByte); + cpu.Flags.CalcParityFlag(resultByte); + + cpu.Registers.A = resultByte; + + cpu.Flags.Carry = !cpu.Flags.Carry; + } + + private static void ANA(CPU cpu, ref byte reg) + { + cpu.Flags.AuxiliaryCarry = ((cpu.Registers.A & 0x08) | (reg & 0x08)) != 0; + + cpu.Registers.A &= reg; + + cpu.Flags.CalcSignFlag(cpu.Registers.A); + cpu.Flags.CalcZeroFlag(cpu.Registers.A); + cpu.Flags.CalcParityFlag(cpu.Registers.A); + cpu.Flags.Carry = false; + } + + private static void XRA(CPU cpu, ref byte reg) + { + cpu.Registers.A ^= reg; + + cpu.Flags.CalcSignFlag(cpu.Registers.A); + cpu.Flags.CalcZeroFlag(cpu.Registers.A); + cpu.Flags.CalcParityFlag(cpu.Registers.A); + cpu.Flags.Carry = false; + cpu.Flags.AuxiliaryCarry = false; + } + + private static void ORA(CPU cpu, ref byte reg) + { + cpu.Registers.A |= reg; + + cpu.Flags.CalcSignFlag(cpu.Registers.A); + cpu.Flags.CalcZeroFlag(cpu.Registers.A); + cpu.Flags.CalcParityFlag(cpu.Registers.A); + cpu.Flags.Carry = false; + cpu.Flags.AuxiliaryCarry = false; + } + + private static void CMP(CPU cpu, ref byte reg) + { + var data = (byte)~reg; + + var result = (ushort)(cpu.Registers.A + data + 1); + + cpu.Flags.CalcAuxCarryFlag(cpu.Registers.A, data, 1); + cpu.Flags.CalcCarryFlag(result); + + var resultByte = (byte)(result & 0x00FF); + + cpu.Flags.CalcSignFlag(resultByte); + cpu.Flags.CalcZeroFlag(resultByte); + cpu.Flags.CalcParityFlag(resultByte); + + cpu.Flags.Carry = !cpu.Flags.Carry; + } + + // 0x80 - ADD B + // Bytes - 1 + // Cycles - 4 + // Flags - S, Z, A, P, C + public static void ADD_B(CPU cpu) + { + ADD(cpu, ref cpu.Registers.B); + } + + // 0x81 - ADD C + // Bytes - 1 + // Cycles - 4 + // Flags - S, Z, A, P, C + public static void ADD_C(CPU cpu) + { + ADD(cpu, ref cpu.Registers.C); + } + + // 0x82 - ADD D + // Bytes - 1 + // Cycles - 4 + // Flags - S, Z, A, P, C + public static void ADD_D(CPU cpu) + { + ADD(cpu, ref cpu.Registers.D); + } + + // 0x83 - ADD E + // Bytes - 1 + // Cycles - 4 + // Flags - S, Z, A, P, C + public static void ADD_E(CPU cpu) + { + ADD(cpu, ref cpu.Registers.E); + } + + // 0x84 - ADD H + // Bytes - 1 + // Cycles - 4 + // Flags - S, Z, A, P, C + public static void ADD_H(CPU cpu) + { + ADD(cpu, ref cpu.Registers.H); + } + + // 0x85 - ADD L + // Bytes - 1 + // Cycles - 4 + // Flags - S, Z, A, P, C + public static void ADD_L(CPU cpu) + { + ADD(cpu, ref cpu.Registers.L); + } + + // 0x86 - ADD M + // Bytes - 1 + // Cycles - 7 + // Flags - S, Z, A, P, C + public static void ADD_M(CPU cpu) + { + var location = GetUshort(cpu.Registers.H, cpu.Registers.L); + + byte val = cpu.Memory[location]; + + ADD(cpu, ref val); + } + + // 0x87 - ADD A + // Bytes - 1 + // Cycles - 4 + // Flags - S, Z, A, P, C + public static void ADD_A(CPU cpu) + { + ADD(cpu, ref cpu.Registers.A); + } + + // 0x88 - ADC B + // Bytes - 1 + // Cycles - 4 + // Flags - S, Z, A, P, C + public static void ADC_B(CPU cpu) + { + ADC(cpu, ref cpu.Registers.B); + } + + // 0x89 - ADC C + // Bytes - 1 + // Cycles - 4 + // Flags - S, Z, A, P, C + public static void ADC_C(CPU cpu) + { + ADC(cpu, ref cpu.Registers.C); + } + + // 0x8A - ADC D + // Bytes - 1 + // Cycles - 4 + // Flags - S, Z, A, P, C + public static void ADC_D(CPU cpu) + { + ADC(cpu, ref cpu.Registers.D); + } + + // 0x8B - ADC E + // Bytes - 1 + // Cycles - 4 + // Flags - S, Z, A, P, C + public static void ADC_E(CPU cpu) + { + ADC(cpu, ref cpu.Registers.E); + } + + // 0x8C - ADC H + // Bytes - 1 + // Cycles - 4 + // Flags - S, Z, A, P, C + public static void ADC_H(CPU cpu) + { + ADC(cpu, ref cpu.Registers.H); + } + + // 0x8D - ADC L + // Bytes - 1 + // Cycles - 4 + // Flags - S, Z, A, P, C + public static void ADC_L(CPU cpu) + { + ADC(cpu, ref cpu.Registers.L); + } + + // 0x8E - ADD M + // Bytes - 1 + // Cycles - 7 + // Flags - S, Z, A, P, C + public static void ADC_M(CPU cpu) + { + var location = GetUshort(cpu.Registers.H, cpu.Registers.L); + + byte val = cpu.Memory[location]; + + ADC(cpu, ref val); + } + + // 0x8F - ADC A + // Bytes - 1 + // Cycles - 4 + // Flags - S, Z, A, P, C + public static void ADC_A(CPU cpu) + { + ADC(cpu, ref cpu.Registers.A); + } + + // 0x90 - SUB B + // Bytes - 1 + // Cycles - 4 + // Flags - S, Z, A, P, C + public static void SUB_B(CPU cpu) + { + SUB(cpu, ref cpu.Registers.B); + } + + // 0x91 - SUB C + // Bytes - 1 + // Cycles - 4 + // Flags - S, Z, A, P, C + public static void SUB_C(CPU cpu) + { + SUB(cpu, ref cpu.Registers.C); + } + + // 0x92 - SUB D + // Bytes - 1 + // Cycles - 4 + // Flags - S, Z, A, P, C + public static void SUB_D(CPU cpu) + { + SUB(cpu, ref cpu.Registers.D); + } + + // 0x93 - SUB E + // Bytes - 1 + // Cycles - 4 + // Flags - S, Z, A, P, C + public static void SUB_E(CPU cpu) + { + SUB(cpu, ref cpu.Registers.E); + } + + // 0x94 - SUB H + // Bytes - 1 + // Cycles - 4 + // Flags - S, Z, A, P, C + public static void SUB_H(CPU cpu) + { + SUB(cpu, ref cpu.Registers.H); + } + + // 0x95 - SUB L + // Bytes - 1 + // Cycles - 4 + // Flags - S, Z, A, P, C + public static void SUB_L(CPU cpu) + { + SUB(cpu, ref cpu.Registers.L); + } + + // 0x96 - SUB M + // Bytes - 1 + // Cycles - 7 + // Flags - S, Z, A, P, C + public static void SUB_M(CPU cpu) + { + var location = GetUshort(cpu.Registers.H, cpu.Registers.L); + + var val = cpu.Memory[location]; + + SUB(cpu, ref val); + } + + // 0x97 - SUB A + // Bytes - 1 + // Cycles - 4 + // Flags - S, Z, A, P, C + public static void SUB_A(CPU cpu) + { + SUB(cpu, ref cpu.Registers.A); + } + + // 0x98 - SBB B + // Bytes - 1 + // Cycles - 4 + // Flags - S, Z, A, P, C + public static void SBB_B(CPU cpu) + { + SBB(cpu, ref cpu.Registers.B); + } + + // 0x99 - SBB C + // Bytes - 1 + // Cycles - 4 + // Flags - S, Z, A, P, C + public static void SBB_C(CPU cpu) + { + SBB(cpu, ref cpu.Registers.C); + } + + // 0x9A - SBB D + // Bytes - 1 + // Cycles - 4 + // Flags - S, Z, A, P, C + public static void SBB_D(CPU cpu) + { + SBB(cpu, ref cpu.Registers.D); + } + + // 0x9B - SBB E + // Bytes - 1 + // Cycles - 4 + // Flags - S, Z, A, P, C + public static void SBB_E(CPU cpu) + { + SBB(cpu, ref cpu.Registers.E); + } + + // 0x9C - SBB H + // Bytes - 1 + // Cycles - 4 + // Flags - S, Z, A, P, C + public static void SBB_H(CPU cpu) + { + SBB(cpu, ref cpu.Registers.H); + } + + // 0x9D - SBB L + // Bytes - 1 + // Cycles - 4 + // Flags - S, Z, A, P, C + public static void SBB_L(CPU cpu) + { + SBB(cpu, ref cpu.Registers.L); + } + + // 0x9E - SBB M + // Bytes - 1 + // Cycles - 7 + // Flags - S, Z, A, P, C + public static void SBB_M(CPU cpu) + { + var location = GetUshort(cpu.Registers.H, cpu.Registers.L); + + var val = cpu.Memory[location]; + + SBB(cpu, ref val); + } + + // 0x9D - SBB A + // Bytes - 1 + // Cycles - 4 + // Flags - S, Z, A, P, C + public static void SBB_A(CPU cpu) + { + SBB(cpu, ref cpu.Registers.A); + } + + // 0xA0 - ANA B + // Bytes - 1 + // Cycles - 4 + // Flags - S, Z, A, P, C + public static void ANA_B(CPU cpu) + { + ANA(cpu, ref cpu.Registers.B); + } + + // 0xA1 - ANA C + // Bytes - 1 + // Cycles - 4 + // Flags - S, Z, A, P, C + public static void ANA_C(CPU cpu) + { + ANA(cpu, ref cpu.Registers.C); + } + + // 0xA2 - ANA D + // Bytes - 1 + // Cycles - 4 + // Flags - S, Z, A, P, C + public static void ANA_D(CPU cpu) + { + ANA(cpu, ref cpu.Registers.D); + } + + // 0xA3 - ANA E + // Bytes - 1 + // Cycles - 4 + // Flags - S, Z, A, P, C + public static void ANA_E(CPU cpu) + { + ANA(cpu, ref cpu.Registers.E); + } + + // 0xA4 - ANA H + // Bytes - 1 + // Cycles - 4 + // Flags - S, Z, A, P, C + public static void ANA_H(CPU cpu) + { + ANA(cpu, ref cpu.Registers.H); + } + + // 0xA5 - ANA L + // Bytes - 1 + // Cycles - 4 + // Flags - S, Z, A, P, C + public static void ANA_L(CPU cpu) + { + ANA(cpu, ref cpu.Registers.L); + } + + // 0xA6 - ANA M + // Bytes - 1 + // Cycles - 7 + // Flags - S, Z, A, P, C + public static void ANA_M(CPU cpu) + { + var location = GetUshort(cpu.Registers.H, cpu.Registers.L); + var val = cpu.Memory[location]; + + ANA(cpu, ref val); + } + + // 0xA7 - ANA A + // Bytes - 1 + // Cycles - 4 + // Flags - S, Z, A, P, C + public static void ANA_A(CPU cpu) + { + ANA(cpu, ref cpu.Registers.A); + } + + public static void XRA_B(CPU cpu) + { + XRA(cpu, ref cpu.Registers.B); + } + + public static void XRA_C(CPU cpu) + { + XRA(cpu, ref cpu.Registers.C); + } + + public static void XRA_D(CPU cpu) + { + XRA(cpu, ref cpu.Registers.D); + } + + public static void XRA_E(CPU cpu) + { + XRA(cpu, ref cpu.Registers.E); + } + + public static void XRA_H(CPU cpu) + { + XRA(cpu, ref cpu.Registers.H); + } + + public static void XRA_L(CPU cpu) + { + XRA(cpu, ref cpu.Registers.L); + } + + public static void XRA_M(CPU cpu) + { + var location = GetUshort(cpu.Registers.H, cpu.Registers.L); + var val = cpu.Memory[location]; + + XRA(cpu, ref val); + } + + public static void XRA_A(CPU cpu) + { + XRA(cpu, ref cpu.Registers.A); + } + + public static void ORA_B(CPU cpu) + { + ORA(cpu, ref cpu.Registers.B); + } + + public static void ORA_C(CPU cpu) + { + ORA(cpu, ref cpu.Registers.C); + } + + public static void ORA_D(CPU cpu) + { + ORA(cpu, ref cpu.Registers.D); + } + + public static void ORA_E(CPU cpu) + { + ORA(cpu, ref cpu.Registers.E); + } + + public static void ORA_H(CPU cpu) + { + ORA(cpu, ref cpu.Registers.H); + } + + public static void ORA_L(CPU cpu) + { + ORA(cpu, ref cpu.Registers.L); + } + + public static void ORA_M(CPU cpu) + { + var location = GetUshort(cpu.Registers.H, cpu.Registers.L); + var val = cpu.Memory[location]; + + ORA(cpu, ref val); + } + + public static void ORA_A(CPU cpu) + { + ORA(cpu, ref cpu.Registers.A); + } + + public static void CMP_B(CPU cpu) + { + CMP(cpu, ref cpu.Registers.B); + } + + public static void CMP_C(CPU cpu) + { + CMP(cpu, ref cpu.Registers.C); + } + + public static void CMP_D(CPU cpu) + { + CMP(cpu, ref cpu.Registers.D); + } + + public static void CMP_E(CPU cpu) + { + CMP(cpu, ref cpu.Registers.E); + } + + public static void CMP_H(CPU cpu) + { + CMP(cpu, ref cpu.Registers.H); + } + + public static void CMP_L(CPU cpu) + { + CMP(cpu, ref cpu.Registers.L); + } + + public static void CMP_M(CPU cpu) + { + var location = GetUshort(cpu.Registers.H, cpu.Registers.L); + var val = cpu.Memory[location]; + + CMP(cpu, ref val); + } + + public static void CMP_A(CPU cpu) + { + CMP(cpu, ref cpu.Registers.A); + } } \ No newline at end of file diff --git a/Intel8080.Emulator/Instructions/RegisterPairInstructions.cs b/Intel8080.Emulator/Instructions/RegisterPairInstructions.cs index 66ae34e..8e6c67c 100644 --- a/Intel8080.Emulator/Instructions/RegisterPairInstructions.cs +++ b/Intel8080.Emulator/Instructions/RegisterPairInstructions.cs @@ -1,218 +1,217 @@ -namespace Intel8080.Emulator.Instructions -{ - public static partial class DefaultInstructionSet - { - private static void PUSH(CPU cpu, ref ushort reg) - { - PushStack(cpu, reg); - } - - private static void POP(CPU cpu, ref ushort reg) - { - var data = PopStack(cpu); - - reg = data; - } - - private static void DAD(CPU cpu, ref ushort reg) - { - int result = cpu.Registers.HL + reg; - - cpu.Registers.HL = (ushort) (result & 0xFFFFFFFF); - - cpu.Flags.CalcCarryFlagRegisterPair(result); - } - - private static void INX(CPU cpu, ref ushort reg) - { - reg += 1; - } - - private static void DCX(CPU cpu, ref ushort reg) - { - reg -= 1; - } - - // 0x09 - DAD B - // Bytes - 1 - // Cycles - 10 - // Flags - C - public static void DAD_B(CPU cpu) - { - DAD(cpu, ref cpu.Registers.BC); - } - - // 0x19 - DAD D - // Bytes - 1 - // Cycles - 10 - // Flags - C - public static void DAD_D(CPU cpu) - { - DAD(cpu, ref cpu.Registers.DE); - } - - // 0x29 - DAD H - // Bytes - 1 - // Cycles - 10 - // Flags - C - public static void DAD_H(CPU cpu) - { - DAD(cpu, ref cpu.Registers.HL); - } - - // 0x39 - DAD SP - // Bytes - 1 - // Cycles - 10 - // Flags - C - public static void DAD_SP(CPU cpu) - { - DAD(cpu, ref cpu.Registers.SP); - } - - // 0x03 - INX B - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void INX_B(CPU cpu) - { - INX(cpu, ref cpu.Registers.BC); - } - - // 0x13 - INX D - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void INX_D(CPU cpu) - { - INX(cpu, ref cpu.Registers.DE); - } - - // 0x23 - INX H - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void INX_H(CPU cpu) - { - INX(cpu, ref cpu.Registers.HL); - } - - // 0x33 - INX SP - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void INX_SP(CPU cpu) - { - INX(cpu, ref cpu.Registers.SP); - } - - // 0x0B - DCX B - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void DCX_B(CPU cpu) - { - DCX(cpu, ref cpu.Registers.BC); - } - - // 0x1B - DCX D - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void DCX_D(CPU cpu) - { - DCX(cpu, ref cpu.Registers.DE); - } - - // 0x2B - DCX H - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void DCX_H(CPU cpu) - { - DCX(cpu, ref cpu.Registers.HL); - } - - // 0x3B - DCX SP - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void DCX_SP(CPU cpu) - { - DCX(cpu, ref cpu.Registers.SP); - } - - public static void POP_B(CPU cpu) - { - POP(cpu, ref cpu.Registers.BC); - } - - public static void PUSH_B(CPU cpu) - { - PUSH(cpu, ref cpu.Registers.BC); - } - - public static void POP_D(CPU cpu) - { - POP(cpu, ref cpu.Registers.DE); - } - - public static void PUSH_D(CPU cpu) - { - PUSH(cpu, ref cpu.Registers.DE); - } - - public static void POP_H(CPU cpu) - { - POP(cpu, ref cpu.Registers.HL); - } - - public static void PUSH_H(CPU cpu) - { - PUSH(cpu, ref cpu.Registers.HL); - } - - public static void POP_PSW(CPU cpu) - { - var data = PopStack(cpu); - - cpu.Registers.A = (byte) ((data & 0xFF00) >> 8); - - var flags = (byte) (data & 0x00FF); - - cpu.Flags.SetFlagsPSW(flags); - } - - public static void PUSH_PSW(CPU cpu) - { - var data = GetUshort( - cpu.Registers.A, - cpu.Flags.F - ); - - PUSH(cpu, ref data); - } - - public static void XCHG(CPU cpu) - { - var temp = cpu.Registers.HL; - - cpu.Registers.HL = cpu.Registers.DE; - cpu.Registers.DE = temp; - } - - public static void XTHL(CPU cpu) - { - var temp = cpu.Registers.HL; - - cpu.Registers.HL = cpu.ReadUshort(cpu.Registers.SP); - - cpu.Memory[cpu.Registers.SP] = (byte) (temp & 0xFF); - cpu.Memory[cpu.Registers.SP + 1] = (byte) ((temp & 0xFF00) >> 8); - } - - public static void SPHL(CPU cpu) - { - cpu.Registers.SP = cpu.Registers.HL; - } - } +namespace Intel8080.Emulator.Instructions; + +public static partial class DefaultInstructionSet +{ + private static void PUSH(CPU cpu, ref ushort reg) + { + PushStack(cpu, reg); + } + + private static void POP(CPU cpu, ref ushort reg) + { + var data = PopStack(cpu); + + reg = data; + } + + private static void DAD(CPU cpu, ref ushort reg) + { + int result = cpu.Registers.HL + reg; + + cpu.Registers.HL = (ushort)(result & 0xFFFFFFFF); + + cpu.Flags.CalcCarryFlagRegisterPair(result); + } + + private static void INX(CPU cpu, ref ushort reg) + { + reg += 1; + } + + private static void DCX(CPU cpu, ref ushort reg) + { + reg -= 1; + } + + // 0x09 - DAD B + // Bytes - 1 + // Cycles - 10 + // Flags - C + public static void DAD_B(CPU cpu) + { + DAD(cpu, ref cpu.Registers.BC); + } + + // 0x19 - DAD D + // Bytes - 1 + // Cycles - 10 + // Flags - C + public static void DAD_D(CPU cpu) + { + DAD(cpu, ref cpu.Registers.DE); + } + + // 0x29 - DAD H + // Bytes - 1 + // Cycles - 10 + // Flags - C + public static void DAD_H(CPU cpu) + { + DAD(cpu, ref cpu.Registers.HL); + } + + // 0x39 - DAD SP + // Bytes - 1 + // Cycles - 10 + // Flags - C + public static void DAD_SP(CPU cpu) + { + DAD(cpu, ref cpu.Registers.SP); + } + + // 0x03 - INX B + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void INX_B(CPU cpu) + { + INX(cpu, ref cpu.Registers.BC); + } + + // 0x13 - INX D + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void INX_D(CPU cpu) + { + INX(cpu, ref cpu.Registers.DE); + } + + // 0x23 - INX H + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void INX_H(CPU cpu) + { + INX(cpu, ref cpu.Registers.HL); + } + + // 0x33 - INX SP + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void INX_SP(CPU cpu) + { + INX(cpu, ref cpu.Registers.SP); + } + + // 0x0B - DCX B + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void DCX_B(CPU cpu) + { + DCX(cpu, ref cpu.Registers.BC); + } + + // 0x1B - DCX D + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void DCX_D(CPU cpu) + { + DCX(cpu, ref cpu.Registers.DE); + } + + // 0x2B - DCX H + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void DCX_H(CPU cpu) + { + DCX(cpu, ref cpu.Registers.HL); + } + + // 0x3B - DCX SP + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void DCX_SP(CPU cpu) + { + DCX(cpu, ref cpu.Registers.SP); + } + + public static void POP_B(CPU cpu) + { + POP(cpu, ref cpu.Registers.BC); + } + + public static void PUSH_B(CPU cpu) + { + PUSH(cpu, ref cpu.Registers.BC); + } + + public static void POP_D(CPU cpu) + { + POP(cpu, ref cpu.Registers.DE); + } + + public static void PUSH_D(CPU cpu) + { + PUSH(cpu, ref cpu.Registers.DE); + } + + public static void POP_H(CPU cpu) + { + POP(cpu, ref cpu.Registers.HL); + } + + public static void PUSH_H(CPU cpu) + { + PUSH(cpu, ref cpu.Registers.HL); + } + + public static void POP_PSW(CPU cpu) + { + var data = PopStack(cpu); + + cpu.Registers.A = (byte)((data & 0xFF00) >> 8); + + var flags = (byte)(data & 0x00FF); + + cpu.Flags.SetFlagsPSW(flags); + } + + public static void PUSH_PSW(CPU cpu) + { + var data = GetUshort( + cpu.Registers.A, + cpu.Flags.F + ); + + PUSH(cpu, ref data); + } + + public static void XCHG(CPU cpu) + { + var temp = cpu.Registers.HL; + + cpu.Registers.HL = cpu.Registers.DE; + cpu.Registers.DE = temp; + } + + public static void XTHL(CPU cpu) + { + var temp = cpu.Registers.HL; + + cpu.Registers.HL = cpu.ReadUshort(cpu.Registers.SP); + + cpu.Memory[cpu.Registers.SP] = (byte)(temp & 0xFF); + cpu.Memory[cpu.Registers.SP + 1] = (byte)((temp & 0xFF00) >> 8); + } + + public static void SPHL(CPU cpu) + { + cpu.Registers.SP = cpu.Registers.HL; + } } \ No newline at end of file diff --git a/Intel8080.Emulator/Instructions/ReturnSubroutineInstructions.cs b/Intel8080.Emulator/Instructions/ReturnSubroutineInstructions.cs index 7cdc9f1..a07e8a0 100644 --- a/Intel8080.Emulator/Instructions/ReturnSubroutineInstructions.cs +++ b/Intel8080.Emulator/Instructions/ReturnSubroutineInstructions.cs @@ -1,90 +1,89 @@ -namespace Intel8080.Emulator.Instructions -{ - public static partial class DefaultInstructionSet - { - public static void RET(CPU cpu) - { - cpu.Registers.PC = PopStack(cpu); - } - - public static void RZ(CPU cpu) - { - if (cpu.Flags.Zero) - { - RET(cpu); - - cpu.Cycles += 6; - } - } - - public static void RNZ(CPU cpu) - { - if (!cpu.Flags.Zero) - { - RET(cpu); - - cpu.Cycles += 6; - } - } - - public static void RNC(CPU cpu) - { - if (!cpu.Flags.Carry) - { - RET(cpu); - - cpu.Cycles += 6; - } - } - - public static void RC(CPU cpu) - { - if (cpu.Flags.Carry) - { - RET(cpu); - - cpu.Cycles += 6; - } - } - - public static void RPO(CPU cpu) - { - if (!cpu.Flags.Parity) - { - RET(cpu); - - cpu.Cycles += 6; - } - } - - public static void RPE(CPU cpu) - { - if (cpu.Flags.Parity) - { - RET(cpu); - - cpu.Cycles += 6; - } - } - - public static void RP(CPU cpu) - { - if (!cpu.Flags.Sign) - { - RET(cpu); - - cpu.Cycles += 6; - } - } - - public static void RM(CPU cpu) - { - if (cpu.Flags.Sign) - { - RET(cpu); - - cpu.Cycles += 6; - } - } - } +namespace Intel8080.Emulator.Instructions; + +public static partial class DefaultInstructionSet +{ + public static void RET(CPU cpu) + { + cpu.Registers.PC = PopStack(cpu); + } + + public static void RZ(CPU cpu) + { + if (cpu.Flags.Zero) + { + RET(cpu); + + cpu.Cycles += 6; + } + } + + public static void RNZ(CPU cpu) + { + if (!cpu.Flags.Zero) + { + RET(cpu); + + cpu.Cycles += 6; + } + } + + public static void RNC(CPU cpu) + { + if (!cpu.Flags.Carry) + { + RET(cpu); + + cpu.Cycles += 6; + } + } + + public static void RC(CPU cpu) + { + if (cpu.Flags.Carry) + { + RET(cpu); + + cpu.Cycles += 6; + } + } + + public static void RPO(CPU cpu) + { + if (!cpu.Flags.Parity) + { + RET(cpu); + + cpu.Cycles += 6; + } + } + + public static void RPE(CPU cpu) + { + if (cpu.Flags.Parity) + { + RET(cpu); + + cpu.Cycles += 6; + } + } + + public static void RP(CPU cpu) + { + if (!cpu.Flags.Sign) + { + RET(cpu); + + cpu.Cycles += 6; + } + } + + public static void RM(CPU cpu) + { + if (cpu.Flags.Sign) + { + RET(cpu); + + cpu.Cycles += 6; + } + } } \ No newline at end of file diff --git a/Intel8080.Emulator/Instructions/RotateAccumulatorInststructions.cs b/Intel8080.Emulator/Instructions/RotateAccumulatorInststructions.cs index 0e1e72f..363a95a 100644 --- a/Intel8080.Emulator/Instructions/RotateAccumulatorInststructions.cs +++ b/Intel8080.Emulator/Instructions/RotateAccumulatorInststructions.cs @@ -1,55 +1,54 @@ -namespace Intel8080.Emulator.Instructions -{ - public static partial class DefaultInstructionSet - { - // 0x07 - RLC - // Bytes - 1 - // Cycles - 4 - // Flags - C - public static void RLC(CPU cpu) - { - cpu.Flags.Carry = ((cpu.Registers.A & 0x80) >> 7) == 1; - cpu.Registers.A = (byte) (((cpu.Registers.A & 0x80) >> 7) | (cpu.Registers.A << 1)); - } - - // 0x0F - RRC - // Bytes - 1 - // Cycles - 4 - // Flags - C - public static void RRC(CPU cpu) - { - cpu.Flags.Carry = (cpu.Registers.A & 0x01) == 1; - cpu.Registers.A = (byte) (((cpu.Registers.A & 0x01) << 7) | (cpu.Registers.A >> 1)); - } - - // 0x17 - RAL - // Bytes - 1 - // Cycles - 4 - // Flags - C - public static void RAL(CPU cpu) - { - bool carry = cpu.Flags.Carry; - - cpu.Flags.Carry = ((cpu.Registers.A & 0x80) >> 7) == 1; - - cpu.Registers.A <<= 1; - - if (carry) cpu.Registers.A |= 1; - } - - // 0x1F - RAR - // Bytes - 1 - // Cycles - 4 - // Flags - C - public static void RAR(CPU cpu) - { - bool carry = cpu.Flags.Carry; - - cpu.Flags.Carry = (cpu.Registers.A & 0x01) == 1; - - cpu.Registers.A >>= 1; - - if (carry) cpu.Registers.A |= 0x80; - } - } +namespace Intel8080.Emulator.Instructions; + +public static partial class DefaultInstructionSet +{ + // 0x07 - RLC + // Bytes - 1 + // Cycles - 4 + // Flags - C + public static void RLC(CPU cpu) + { + cpu.Flags.Carry = ((cpu.Registers.A & 0x80) >> 7) == 1; + cpu.Registers.A = (byte)(((cpu.Registers.A & 0x80) >> 7) | (cpu.Registers.A << 1)); + } + + // 0x0F - RRC + // Bytes - 1 + // Cycles - 4 + // Flags - C + public static void RRC(CPU cpu) + { + cpu.Flags.Carry = (cpu.Registers.A & 0x01) == 1; + cpu.Registers.A = (byte)(((cpu.Registers.A & 0x01) << 7) | (cpu.Registers.A >> 1)); + } + + // 0x17 - RAL + // Bytes - 1 + // Cycles - 4 + // Flags - C + public static void RAL(CPU cpu) + { + bool carry = cpu.Flags.Carry; + + cpu.Flags.Carry = ((cpu.Registers.A & 0x80) >> 7) == 1; + + cpu.Registers.A <<= 1; + + if (carry) cpu.Registers.A |= 1; + } + + // 0x1F - RAR + // Bytes - 1 + // Cycles - 4 + // Flags - C + public static void RAR(CPU cpu) + { + bool carry = cpu.Flags.Carry; + + cpu.Flags.Carry = (cpu.Registers.A & 0x01) == 1; + + cpu.Registers.A >>= 1; + + if (carry) cpu.Registers.A |= 0x80; + } } \ No newline at end of file diff --git a/Intel8080.Emulator/Instructions/SingleRegisterInstructions.cs b/Intel8080.Emulator/Instructions/SingleRegisterInstructions.cs index 786240b..9b12773 100644 --- a/Intel8080.Emulator/Instructions/SingleRegisterInstructions.cs +++ b/Intel8080.Emulator/Instructions/SingleRegisterInstructions.cs @@ -1,226 +1,225 @@ -namespace Intel8080.Emulator.Instructions -{ - public static partial class DefaultInstructionSet - { - private static void INR(CPU cpu, ref byte reg) - { - cpu.Flags.CalcAuxCarryFlag(reg, 1); - - reg += 1; - - cpu.Flags.CalcSignFlag(reg); - cpu.Flags.CalcZeroFlag(reg); - cpu.Flags.CalcParityFlag(reg); - } - - private static void DCR(CPU cpu, ref byte reg) - { - cpu.Flags.CalcAuxCarryFlag(reg, -1); - - reg -= 1; - - cpu.Flags.CalcSignFlag(reg); - cpu.Flags.CalcZeroFlag(reg); - cpu.Flags.CalcParityFlag(reg); - } - - // 0x04 - INR B - // Bytes - 1 - // Cycles - 5 - // Flags - S, Z, A, P - public static void INR_B(CPU cpu) - { - INR(cpu, ref cpu.Registers.B); - } - - // 0x0C - INR C - // Bytes - 1 - // Cycles - 5 - // Flags - S, Z, A, P - - public static void INR_C(CPU cpu) - { - INR(cpu, ref cpu.Registers.C); - } - - // 0x14 - INR D - // Bytes - 1 - // Cycles - 5 - // Flags - S, Z, A, P - public static void INR_D(CPU cpu) - { - INR(cpu, ref cpu.Registers.D); - } - - // 0x1C - INR E - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void INR_E(CPU cpu) - { - INR(cpu, ref cpu.Registers.E); - } - - // 0x24 - INR H - // Bytes - 1 - // Cycles - 5 - // Flags - S, Z, A, P - public static void INR_H(CPU cpu) - { - INR(cpu, ref cpu.Registers.H); - } - - // 0x2C - INR L - // Bytes - 1 - // Cycles - 5 - // Flags - S, Z, A, P - public static void INR_L(CPU cpu) - { - INR(cpu, ref cpu.Registers.L); - } - - // 0x34 - INR M - // Bytes - 1 - // Cycles - 10 - // Flags - S, Z, A, P - public static void INR_M(CPU cpu) - { - var location = GetUshort(cpu.Registers.H, cpu.Registers.L); - - cpu.Flags.CalcAuxCarryFlag(cpu.Memory[location], 1); - - cpu.Memory[location] += 1; - - cpu.Flags.CalcSignFlag(cpu.Memory[location]); - cpu.Flags.CalcZeroFlag(cpu.Memory[location]); - cpu.Flags.CalcParityFlag(cpu.Memory[location]); - } - - // 0x3C - INR A - // Bytes - 1 - // Cycles - 5 - // Flags - S, Z, A, P - public static void INR_A(CPU cpu) - { - INR(cpu, ref cpu.Registers.A); - } - - // 0x05 - DCR B - // Bytes - 1 - // Cycles - 5 - // Flags - S, Z, A, P - public static void DCR_B(CPU cpu) - { - DCR(cpu, ref cpu.Registers.B); - } - - // 0x0D - DCR C - // Bytes - 1 - // Cycles - 5 - // Flags - S, Z, A, P - public static void DCR_C(CPU cpu) - { - DCR(cpu, ref cpu.Registers.C); - } - - // 0x15 - DCR D - // Bytes - 1 - // Cycles - 5 - // Flags - S, Z, A, P - public static void DCR_D(CPU cpu) - { - DCR(cpu, ref cpu.Registers.D); - } - - // 0x1D - DCR E - // Bytes - 1 - // Cycles - 5 - // Flags - None - public static void DCR_E(CPU cpu) - { - DCR(cpu, ref cpu.Registers.E); - } - - // 0x25 - DCR H - // Bytes - 1 - // Cycles - 5 - // Flags - S, Z, A, P - public static void DCR_H(CPU cpu) - { - DCR(cpu, ref cpu.Registers.H); - } - - // 0x2D - DCR L - // Bytes - 1 - // Cycles - 5 - // Flags - S, Z, A, P - public static void DCR_L(CPU cpu) - { - DCR(cpu, ref cpu.Registers.L); - } - - // 0x35 - DCR M - // Bytes - 1 - // Cycles - 10 - // Flags - S, Z, A, P - public static void DCR_M(CPU cpu) - { - var location = GetUshort(cpu.Registers.H, cpu.Registers.L); - - cpu.Flags.CalcAuxCarryFlag(cpu.Memory[location], -1); - - cpu.Memory[location] -= 1; - - cpu.Flags.CalcSignFlag(cpu.Memory[location]); - cpu.Flags.CalcZeroFlag(cpu.Memory[location]); - cpu.Flags.CalcParityFlag(cpu.Memory[location]); - } - - // 0x3D - DCR A - // Bytes - 1 - // Cycles - 5 - // Flags - S, Z, A, P - public static void DCR_A(CPU cpu) - { - DCR(cpu, ref cpu.Registers.A); - } - - // 0x2F - CMA - // Bytes - 1 - // Cycles - 4 - // Flags - None - public static void CMA(CPU cpu) - { - cpu.Registers.A = (byte)~cpu.Registers.A; - } - - // 0x27 - DAA - // Bytes - 1 - // Cycles - 4 - // Flags - S Z A P C - public static void DAA(CPU cpu) - { - bool carry = false; - byte correction = 0; - - byte low = (byte)(cpu.Registers.A & 0x0F); - byte high = (byte)((cpu.Registers.A & 0xF0) >> 4); - - if (low > 0x09 | cpu.Flags.AuxiliaryCarry) - { - correction += 0x06; - } - - if (high > 0x09 || (high >= 0x09 && low > 0x09) || cpu.Flags.Carry) - { - // Add 0x06 (0x60 == 0x06 << 4) to Accumulator high bits - correction += 0x60; - carry = true; - } - - ADD(cpu, ref correction); - - cpu.Flags.Carry = carry; - } - } +namespace Intel8080.Emulator.Instructions; + +public static partial class DefaultInstructionSet +{ + private static void INR(CPU cpu, ref byte reg) + { + cpu.Flags.CalcAuxCarryFlag(reg, 1); + + reg += 1; + + cpu.Flags.CalcSignFlag(reg); + cpu.Flags.CalcZeroFlag(reg); + cpu.Flags.CalcParityFlag(reg); + } + + private static void DCR(CPU cpu, ref byte reg) + { + cpu.Flags.CalcAuxCarryFlag(reg, -1); + + reg -= 1; + + cpu.Flags.CalcSignFlag(reg); + cpu.Flags.CalcZeroFlag(reg); + cpu.Flags.CalcParityFlag(reg); + } + + // 0x04 - INR B + // Bytes - 1 + // Cycles - 5 + // Flags - S, Z, A, P + public static void INR_B(CPU cpu) + { + INR(cpu, ref cpu.Registers.B); + } + + // 0x0C - INR C + // Bytes - 1 + // Cycles - 5 + // Flags - S, Z, A, P + + public static void INR_C(CPU cpu) + { + INR(cpu, ref cpu.Registers.C); + } + + // 0x14 - INR D + // Bytes - 1 + // Cycles - 5 + // Flags - S, Z, A, P + public static void INR_D(CPU cpu) + { + INR(cpu, ref cpu.Registers.D); + } + + // 0x1C - INR E + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void INR_E(CPU cpu) + { + INR(cpu, ref cpu.Registers.E); + } + + // 0x24 - INR H + // Bytes - 1 + // Cycles - 5 + // Flags - S, Z, A, P + public static void INR_H(CPU cpu) + { + INR(cpu, ref cpu.Registers.H); + } + + // 0x2C - INR L + // Bytes - 1 + // Cycles - 5 + // Flags - S, Z, A, P + public static void INR_L(CPU cpu) + { + INR(cpu, ref cpu.Registers.L); + } + + // 0x34 - INR M + // Bytes - 1 + // Cycles - 10 + // Flags - S, Z, A, P + public static void INR_M(CPU cpu) + { + var location = GetUshort(cpu.Registers.H, cpu.Registers.L); + + cpu.Flags.CalcAuxCarryFlag(cpu.Memory[location], 1); + + cpu.Memory[location] += 1; + + cpu.Flags.CalcSignFlag(cpu.Memory[location]); + cpu.Flags.CalcZeroFlag(cpu.Memory[location]); + cpu.Flags.CalcParityFlag(cpu.Memory[location]); + } + + // 0x3C - INR A + // Bytes - 1 + // Cycles - 5 + // Flags - S, Z, A, P + public static void INR_A(CPU cpu) + { + INR(cpu, ref cpu.Registers.A); + } + + // 0x05 - DCR B + // Bytes - 1 + // Cycles - 5 + // Flags - S, Z, A, P + public static void DCR_B(CPU cpu) + { + DCR(cpu, ref cpu.Registers.B); + } + + // 0x0D - DCR C + // Bytes - 1 + // Cycles - 5 + // Flags - S, Z, A, P + public static void DCR_C(CPU cpu) + { + DCR(cpu, ref cpu.Registers.C); + } + + // 0x15 - DCR D + // Bytes - 1 + // Cycles - 5 + // Flags - S, Z, A, P + public static void DCR_D(CPU cpu) + { + DCR(cpu, ref cpu.Registers.D); + } + + // 0x1D - DCR E + // Bytes - 1 + // Cycles - 5 + // Flags - None + public static void DCR_E(CPU cpu) + { + DCR(cpu, ref cpu.Registers.E); + } + + // 0x25 - DCR H + // Bytes - 1 + // Cycles - 5 + // Flags - S, Z, A, P + public static void DCR_H(CPU cpu) + { + DCR(cpu, ref cpu.Registers.H); + } + + // 0x2D - DCR L + // Bytes - 1 + // Cycles - 5 + // Flags - S, Z, A, P + public static void DCR_L(CPU cpu) + { + DCR(cpu, ref cpu.Registers.L); + } + + // 0x35 - DCR M + // Bytes - 1 + // Cycles - 10 + // Flags - S, Z, A, P + public static void DCR_M(CPU cpu) + { + var location = GetUshort(cpu.Registers.H, cpu.Registers.L); + + cpu.Flags.CalcAuxCarryFlag(cpu.Memory[location], -1); + + cpu.Memory[location] -= 1; + + cpu.Flags.CalcSignFlag(cpu.Memory[location]); + cpu.Flags.CalcZeroFlag(cpu.Memory[location]); + cpu.Flags.CalcParityFlag(cpu.Memory[location]); + } + + // 0x3D - DCR A + // Bytes - 1 + // Cycles - 5 + // Flags - S, Z, A, P + public static void DCR_A(CPU cpu) + { + DCR(cpu, ref cpu.Registers.A); + } + + // 0x2F - CMA + // Bytes - 1 + // Cycles - 4 + // Flags - None + public static void CMA(CPU cpu) + { + cpu.Registers.A = (byte)~cpu.Registers.A; + } + + // 0x27 - DAA + // Bytes - 1 + // Cycles - 4 + // Flags - S Z A P C + public static void DAA(CPU cpu) + { + bool carry = false; + byte correction = 0; + + byte low = (byte)(cpu.Registers.A & 0x0F); + byte high = (byte)((cpu.Registers.A & 0xF0) >> 4); + + if (low > 0x09 | cpu.Flags.AuxiliaryCarry) + { + correction += 0x06; + } + + if (high > 0x09 || (high >= 0x09 && low > 0x09) || cpu.Flags.Carry) + { + // Add 0x06 (0x60 == 0x06 << 4) to Accumulator high bits + correction += 0x60; + carry = true; + } + + ADD(cpu, ref correction); + + cpu.Flags.Carry = carry; + } } \ No newline at end of file diff --git a/Intel8080.Emulator/Intel8080.Emulator.csproj b/Intel8080.Emulator/Intel8080.Emulator.csproj index 4de8048..8d2b232 100644 --- a/Intel8080.Emulator/Intel8080.Emulator.csproj +++ b/Intel8080.Emulator/Intel8080.Emulator.csproj @@ -1,7 +1,7 @@ - net6.0 + net8.0 enable diff --git a/Intel8080.Emulator/OpcodeTable.cs b/Intel8080.Emulator/OpcodeTable.cs index 526be33..3e43a0b 100644 --- a/Intel8080.Emulator/OpcodeTable.cs +++ b/Intel8080.Emulator/OpcodeTable.cs @@ -1,300 +1,299 @@ -namespace Intel8080.Emulator -{ - public static class OpcodeTable - { - public static readonly Opcode[] Opcodes; - - static OpcodeTable() - { - Opcodes = new Opcode[0x100]; - - // 0x0X - Opcodes[0x00] = new Opcode("NOP", 1, 4, null); - Opcodes[0x01] = new Opcode("LXI B, d16", 3, 10, null); - Opcodes[0x02] = new Opcode("STAX B", 1, 7, null); - Opcodes[0x03] = new Opcode("INX B", 1, 5, null); - Opcodes[0x04] = new Opcode("INR B", 1, 5, null); - Opcodes[0x05] = new Opcode("DCR B", 1, 5, null); - Opcodes[0x06] = new Opcode("MVI B, d8", 2, 7, null); - Opcodes[0x07] = new Opcode("RLC", 1, 4, null); - Opcodes[0x08] = new Opcode("*NOP", 1, 4, null); - Opcodes[0x09] = new Opcode("DAD B", 1, 10, null); - Opcodes[0x0A] = new Opcode("LDAX B", 1, 7, null); - Opcodes[0x0B] = new Opcode("DCX B", 1, 5, null); - Opcodes[0x0C] = new Opcode("INR C", 1, 5, null); - Opcodes[0x0D] = new Opcode("DCR C", 1, 5, null); - Opcodes[0x0E] = new Opcode("MVI C, d8", 2, 7, null); - Opcodes[0x0F] = new Opcode("RRC", 1, 4, null); - - // 0x1X - Opcodes[0x10] = new Opcode("*NOP", 1, 4, null); - Opcodes[0x11] = new Opcode("LXI D, d16", 3, 10, null); - Opcodes[0x12] = new Opcode("STAX D", 1, 7, null); - Opcodes[0x13] = new Opcode("INX D", 1, 5, null); - Opcodes[0x14] = new Opcode("INR D", 1, 5, null); - Opcodes[0x15] = new Opcode("DCR D", 1, 5, null); - Opcodes[0x16] = new Opcode("MVI D, d8", 2, 7, null); - Opcodes[0x17] = new Opcode("RAL", 1, 4, null); - Opcodes[0x18] = new Opcode("*NOP", 1, 4, null); - Opcodes[0x19] = new Opcode("DAD D", 1, 10, null); - Opcodes[0x1A] = new Opcode("LDAX D", 1, 7, null); - Opcodes[0x1B] = new Opcode("DCX D", 1, 5, null); - Opcodes[0x1C] = new Opcode("INR E", 1, 5, null); - Opcodes[0x1D] = new Opcode("DCR E", 1, 5, null); - Opcodes[0x1E] = new Opcode("MVI E, d8", 2, 7, null); - Opcodes[0x1F] = new Opcode("RAR", 1, 4, null); - - // 0x2X - Opcodes[0x20] = new Opcode("*NOP", 1, 4, null); - Opcodes[0x21] = new Opcode("LXI H, d16", 3, 10, null); - Opcodes[0x22] = new Opcode("SHLD a16", 3, 16, null); - Opcodes[0x23] = new Opcode("INX H", 1, 5, null); - Opcodes[0x24] = new Opcode("INR H", 1, 5, null); - Opcodes[0x25] = new Opcode("DCR H", 1, 5, null); - Opcodes[0x26] = new Opcode("MVI H, d8", 2, 7, null); - Opcodes[0x27] = new Opcode("DAA", 1, 4, null); - Opcodes[0x28] = new Opcode("*NOP", 1, 4, null); - Opcodes[0x29] = new Opcode("DAD H", 1, 10, null); - Opcodes[0x2A] = new Opcode("LHLD a16", 3, 16, null); - Opcodes[0x2B] = new Opcode("DCX H", 1, 5, null); - Opcodes[0x2C] = new Opcode("INR L", 1, 5, null); - Opcodes[0x2D] = new Opcode("DCR L", 1, 5, null); - Opcodes[0x2E] = new Opcode("MVI L, d8", 2, 7, null); - Opcodes[0x2F] = new Opcode("CMA", 1, 4, null); - - // 0x3X - Opcodes[0x30] = new Opcode("*NOP", 1, 4, null); - Opcodes[0x31] = new Opcode("LXI SP, d16", 3, 10, null); - Opcodes[0x32] = new Opcode("STA a16", 3, 13, null); - Opcodes[0x33] = new Opcode("INX SP", 1, 5, null); - Opcodes[0x34] = new Opcode("INR M", 1, 10, null); - Opcodes[0x35] = new Opcode("DCR M", 1, 10, null); - Opcodes[0x36] = new Opcode("MVI M, d8", 2, 10, null); - Opcodes[0x37] = new Opcode("STC", 1, 4, null); - Opcodes[0x38] = new Opcode("*NOP", 1, 4, null); - Opcodes[0x39] = new Opcode("DAD SP", 1, 10, null); - Opcodes[0x3A] = new Opcode("LDA a16", 3, 13, null); - Opcodes[0x3B] = new Opcode("DCX SP", 1, 5, null); - Opcodes[0x3C] = new Opcode("INR A", 1, 5, null); - Opcodes[0x3D] = new Opcode("DCR A", 1, 5, null); - Opcodes[0x3E] = new Opcode("MVI A, d8", 2, 7, null); - Opcodes[0x3F] = new Opcode("CMC", 1, 4, null); - - // 0x4X - Opcodes[0x40] = new Opcode("MOV B, B", 1, 5, null); - Opcodes[0x41] = new Opcode("MOV B, C", 1, 5, null); - Opcodes[0x42] = new Opcode("MOV B, D", 1, 5, null); - Opcodes[0x43] = new Opcode("MOV B, E", 1, 5, null); - Opcodes[0x44] = new Opcode("MOV B, H", 1, 5, null); - Opcodes[0x45] = new Opcode("MOV B, L", 1, 5, null); - Opcodes[0x46] = new Opcode("MOV B, M", 1, 7, null); - Opcodes[0x47] = new Opcode("MOV B, A", 1, 5, null); - Opcodes[0x48] = new Opcode("MOV C, B", 1, 5, null); - Opcodes[0x49] = new Opcode("MOV C, C", 1, 5, null); - Opcodes[0x4A] = new Opcode("MOV C, D", 1, 5, null); - Opcodes[0x4B] = new Opcode("MOV C, E", 1, 5, null); - Opcodes[0x4C] = new Opcode("MOV C, H", 1, 5, null); - Opcodes[0x4D] = new Opcode("MOV C, L", 1, 5, null); - Opcodes[0x4E] = new Opcode("MOV C, M", 1, 7, null); - Opcodes[0x4F] = new Opcode("MOV C, A", 1, 5, null); - - // 0x5X - Opcodes[0x50] = new Opcode("MOV D, B", 1, 5, null); - Opcodes[0x51] = new Opcode("MOV D, C", 1, 5, null); - Opcodes[0x52] = new Opcode("MOV D, D", 1, 5, null); - Opcodes[0x53] = new Opcode("MOV D, E", 1, 5, null); - Opcodes[0x54] = new Opcode("MOV D, H", 1, 5, null); - Opcodes[0x55] = new Opcode("MOV D, L", 1, 5, null); - Opcodes[0x56] = new Opcode("MOV D, M", 1, 7, null); - Opcodes[0x57] = new Opcode("MOV D, A", 1, 5, null); - Opcodes[0x58] = new Opcode("MOV E, B", 1, 5, null); - Opcodes[0x59] = new Opcode("MOV E, C", 1, 5, null); - Opcodes[0x5A] = new Opcode("MOV E, D", 1, 5, null); - Opcodes[0x5B] = new Opcode("MOV E, E", 1, 5, null); - Opcodes[0x5C] = new Opcode("MOV E, H", 1, 5, null); - Opcodes[0x5D] = new Opcode("MOV E, L", 1, 5, null); - Opcodes[0x5E] = new Opcode("MOV E, M", 1, 7, null); - Opcodes[0x5F] = new Opcode("MOV E, A", 1, 5, null); - - // 0x6X - Opcodes[0x60] = new Opcode("MOV H, B", 1, 5, null); - Opcodes[0x61] = new Opcode("MOV H, C", 1, 5, null); - Opcodes[0x62] = new Opcode("MOV H, D", 1, 5, null); - Opcodes[0x63] = new Opcode("MOV H, E", 1, 5, null); - Opcodes[0x64] = new Opcode("MOV H, H", 1, 5, null); - Opcodes[0x65] = new Opcode("MOV H, L", 1, 5, null); - Opcodes[0x66] = new Opcode("MOV H, M", 1, 7, null); - Opcodes[0x67] = new Opcode("MOV H, A", 1, 5, null); - Opcodes[0x68] = new Opcode("MOV L, B", 1, 5, null); - Opcodes[0x69] = new Opcode("MOV L, C", 1, 5, null); - Opcodes[0x6A] = new Opcode("MOV L, D", 1, 5, null); - Opcodes[0x6B] = new Opcode("MOV L, E", 1, 5, null); - Opcodes[0x6C] = new Opcode("MOV L, H", 1, 5, null); - Opcodes[0x6D] = new Opcode("MOV L, L", 1, 5, null); - Opcodes[0x6E] = new Opcode("MOV L, M", 1, 7, null); - Opcodes[0x6F] = new Opcode("MOV L, A", 1, 5, null); - - // 0x7X - Opcodes[0x70] = new Opcode("MOV M, B", 1, 7, null); - Opcodes[0x71] = new Opcode("MOV M, C", 1, 7, null); - Opcodes[0x72] = new Opcode("MOV M, D", 1, 7, null); - Opcodes[0x73] = new Opcode("MOV M, E", 1, 7, null); - Opcodes[0x74] = new Opcode("MOV M, H", 1, 7, null); - Opcodes[0x75] = new Opcode("MOV M, L", 1, 7, null); - Opcodes[0x76] = new Opcode("HLT", 1, 7, null); - Opcodes[0x77] = new Opcode("MOV M, A", 1, 7, null); - Opcodes[0x78] = new Opcode("MOV A, B", 1, 5, null); - Opcodes[0x79] = new Opcode("MOV A, C", 1, 5, null); - Opcodes[0x7A] = new Opcode("MOV A, D", 1, 5, null); - Opcodes[0x7B] = new Opcode("MOV A, E", 1, 5, null); - Opcodes[0x7C] = new Opcode("MOV A, H", 1, 5, null); - Opcodes[0x7D] = new Opcode("MOV A, L", 1, 5, null); - Opcodes[0x7E] = new Opcode("MOV A, M", 1, 7, null); - Opcodes[0x7F] = new Opcode("MOV A, A", 1, 5, null); - - // 0x8X - Opcodes[0x80] = new Opcode("ADD B", 1, 4, null); - Opcodes[0x81] = new Opcode("ADD C", 1, 4, null); - Opcodes[0x82] = new Opcode("ADD D", 1, 4, null); - Opcodes[0x83] = new Opcode("ADD E", 1, 4, null); - Opcodes[0x84] = new Opcode("ADD H", 1, 4, null); - Opcodes[0x85] = new Opcode("ADD L", 1, 4, null); - Opcodes[0x86] = new Opcode("ADD M", 1, 7, null); - Opcodes[0x87] = new Opcode("ADD A", 1, 4, null); - Opcodes[0x88] = new Opcode("ADC B", 1, 4, null); - Opcodes[0x89] = new Opcode("ADC C", 1, 4, null); - Opcodes[0x8A] = new Opcode("ADC D", 1, 4, null); - Opcodes[0x8B] = new Opcode("ADC E", 1, 4, null); - Opcodes[0x8C] = new Opcode("ADC H", 1, 4, null); - Opcodes[0x8D] = new Opcode("ADC L", 1, 4, null); - Opcodes[0x8E] = new Opcode("ADC M", 1, 7, null); - Opcodes[0x8F] = new Opcode("ADC A", 1, 4, null); - - // 0x9X - Opcodes[0x90] = new Opcode("SUB B", 1, 4, null); - Opcodes[0x91] = new Opcode("SUB C", 1, 4, null); - Opcodes[0x92] = new Opcode("SUB D", 1, 4, null); - Opcodes[0x93] = new Opcode("SUB E", 1, 4, null); - Opcodes[0x94] = new Opcode("SUB H", 1, 4, null); - Opcodes[0x95] = new Opcode("SUB L", 1, 4, null); - Opcodes[0x96] = new Opcode("SUB M", 1, 7, null); - Opcodes[0x97] = new Opcode("SUB A", 1, 4, null); - Opcodes[0x98] = new Opcode("SBB B", 1, 4, null); - Opcodes[0x99] = new Opcode("SBB C", 1, 4, null); - Opcodes[0x9A] = new Opcode("SBB D", 1, 4, null); - Opcodes[0x9B] = new Opcode("SBB E", 1, 4, null); - Opcodes[0x9C] = new Opcode("SBB H", 1, 4, null); - Opcodes[0x9D] = new Opcode("SBB L", 1, 4, null); - Opcodes[0x9E] = new Opcode("SBB M", 1, 7, null); - Opcodes[0x9F] = new Opcode("SBB A", 1, 4, null); - - // 0xAX - Opcodes[0xA0] = new Opcode("ANA B", 1, 4, null); - Opcodes[0xA1] = new Opcode("ANA C", 1, 4, null); - Opcodes[0xA2] = new Opcode("ANA D", 1, 4, null); - Opcodes[0xA3] = new Opcode("ANA E", 1, 4, null); - Opcodes[0xA4] = new Opcode("ANA H", 1, 4, null); - Opcodes[0xA5] = new Opcode("ANA L", 1, 4, null); - Opcodes[0xA6] = new Opcode("ANA M", 1, 7, null); - Opcodes[0xA7] = new Opcode("ANA A", 1, 4, null); - Opcodes[0xA8] = new Opcode("XRA B", 1, 4, null); - Opcodes[0xA9] = new Opcode("XRA C", 1, 4, null); - Opcodes[0xAA] = new Opcode("XRA D", 1, 4, null); - Opcodes[0xAB] = new Opcode("XRA E", 1, 4, null); - Opcodes[0xAC] = new Opcode("XRA H", 1, 4, null); - Opcodes[0xAD] = new Opcode("XRA L", 1, 4, null); - Opcodes[0xAE] = new Opcode("XRA M", 1, 7, null); - Opcodes[0xAF] = new Opcode("XRA A", 1, 4, null); - - // 0xBX - Opcodes[0xB0] = new Opcode("ORA B", 1, 4, null); - Opcodes[0xB1] = new Opcode("ORA C", 1, 4, null); - Opcodes[0xB2] = new Opcode("ORA D", 1, 4, null); - Opcodes[0xB3] = new Opcode("ORA E", 1, 4, null); - Opcodes[0xB4] = new Opcode("ORA H", 1, 4, null); - Opcodes[0xB5] = new Opcode("ORA L", 1, 4, null); - Opcodes[0xB6] = new Opcode("ORA M", 1, 7, null); - Opcodes[0xB7] = new Opcode("ORA A", 1, 4, null); - Opcodes[0xB8] = new Opcode("CMP B", 1, 4, null); - Opcodes[0xB9] = new Opcode("CMP C", 1, 4, null); - Opcodes[0xBA] = new Opcode("CMP D", 1, 4, null); - Opcodes[0xBB] = new Opcode("CMP E", 1, 4, null); - Opcodes[0xBC] = new Opcode("CMP H", 1, 4, null); - Opcodes[0xBD] = new Opcode("CMP L", 1, 4, null); - Opcodes[0xBE] = new Opcode("CMP M", 1, 7, null); - Opcodes[0xBF] = new Opcode("CMP A", 1, 4, null); - - // 0xCX - Opcodes[0xC0] = new Opcode("RNZ", 1, 5, 11); - Opcodes[0xC1] = new Opcode("POP B", 1, 10, null); - Opcodes[0xC2] = new Opcode("JNZ a16", 3, 10, null); - Opcodes[0xC3] = new Opcode("JMP a16", 3, 10, null); - Opcodes[0xC4] = new Opcode("CNZ a16", 3, 11, 17); - Opcodes[0xC5] = new Opcode("PUSH B", 1, 11, null); - Opcodes[0xC6] = new Opcode("ADI d8", 2, 7, null); - Opcodes[0xC7] = new Opcode("RST 0", 1, 11, null); - Opcodes[0xC8] = new Opcode("RZ", 1, 5, 11); - Opcodes[0xC9] = new Opcode("RET", 1, 10, null); - Opcodes[0xCA] = new Opcode("JZ a16", 3, 10, null); - Opcodes[0xCB] = new Opcode("*JMP a16", 3, 10, null); - Opcodes[0xCC] = new Opcode("CZ a16", 3, 11, 17); - Opcodes[0xCD] = new Opcode("CALL a16", 3, 17, null); - Opcodes[0xCE] = new Opcode("ACI d8", 2, 7, null); - Opcodes[0xCF] = new Opcode("RST 1", 1, 11, null); - - // 0xDX - Opcodes[0xD0] = new Opcode("RNC", 1, 5, 11); - Opcodes[0xD1] = new Opcode("POP D", 1, 10, null); - Opcodes[0xD2] = new Opcode("JNC a16", 3, 10, null); - Opcodes[0xD3] = new Opcode("OUT d8", 2, 10, null); - Opcodes[0xD4] = new Opcode("CNC a16", 3, 11, 17); - Opcodes[0xD5] = new Opcode("PUSH D", 1, 11, null); - Opcodes[0xD6] = new Opcode("SUI d8", 2, 7, null); - Opcodes[0xD7] = new Opcode("RST 2", 1, 11, null); - Opcodes[0xD8] = new Opcode("RC", 1, 5, 11); - Opcodes[0xD9] = new Opcode("*RET", 1, 10, null); - Opcodes[0xDA] = new Opcode("JC a16", 3, 10, null); - Opcodes[0xDB] = new Opcode("IN d8", 2, 10, null); - Opcodes[0xDC] = new Opcode("CC a16", 3, 11, 17); - Opcodes[0xDD] = new Opcode("*CALL a16", 3, 17, null); - Opcodes[0xDE] = new Opcode("SBI d8", 2, 7, null); - Opcodes[0xDF] = new Opcode("RST 3", 1, 11, null); - - // 0xEX - Opcodes[0xE0] = new Opcode("RPO", 1, 5, 11); - Opcodes[0xE1] = new Opcode("POP H", 1, 10, null); - Opcodes[0xE2] = new Opcode("JPO a16", 3, 10, null); - Opcodes[0xE3] = new Opcode("XTHL", 1, 18, null); - Opcodes[0xE4] = new Opcode("CPO a16", 3, 11, 17); - Opcodes[0xE5] = new Opcode("PUSH H", 1, 11, null); - Opcodes[0xE6] = new Opcode("ANI d8", 2, 7, null); - Opcodes[0xE7] = new Opcode("RST 4", 1, 11, null); - Opcodes[0xE8] = new Opcode("RPE", 1, 5, 11); - Opcodes[0xE9] = new Opcode("PCHL", 1, 5, null); - Opcodes[0xEA] = new Opcode("JPE a16", 3, 10, null); - Opcodes[0xEB] = new Opcode("XCHG", 1, 5, null); - Opcodes[0xEC] = new Opcode("CPE a16", 3, 11, 17); - Opcodes[0xED] = new Opcode("*CALL a16", 3, 17, null); - Opcodes[0xEE] = new Opcode("XRI d8", 2, 7, null); - Opcodes[0xEF] = new Opcode("RST 5", 1, 11, null); - - // 0xFX - Opcodes[0xF0] = new Opcode("RP", 1, 5, 11); - Opcodes[0xF1] = new Opcode("POP PSW", 1, 10, null); - Opcodes[0xF2] = new Opcode("JP a16", 3, 10, null); - Opcodes[0xF3] = new Opcode("DI", 1, 4, null); - Opcodes[0xF4] = new Opcode("CP a16", 3, 11, 17); - Opcodes[0xF5] = new Opcode("PUSH PSW", 1, 11, null); - Opcodes[0xF6] = new Opcode("ORI d8", 2, 7, null); - Opcodes[0xF7] = new Opcode("RST 6", 1, 11, null); - Opcodes[0xF8] = new Opcode("RM", 1, 5, 11); - Opcodes[0xF9] = new Opcode("SPHL", 1, 5, null); - Opcodes[0xFA] = new Opcode("JM a16", 3, 10, null); - Opcodes[0xFB] = new Opcode("EI", 1, 4, null); - Opcodes[0xFC] = new Opcode("CM a16", 3, 11, 17); - Opcodes[0xFD] = new Opcode("*CALL a16", 3, 17, null); - Opcodes[0xFE] = new Opcode("CPI d8", 2, 7, null); - Opcodes[0xFF] = new Opcode("RST 7", 1, 11, null); - } - } -} +namespace Intel8080.Emulator; + +public static class OpcodeTable +{ + public static readonly Opcode[] Opcodes; + + static OpcodeTable() + { + Opcodes = new Opcode[0x100]; + + // 0x0X + Opcodes[0x00] = new Opcode("NOP", 1, 4, null); + Opcodes[0x01] = new Opcode("LXI B, d16", 3, 10, null); + Opcodes[0x02] = new Opcode("STAX B", 1, 7, null); + Opcodes[0x03] = new Opcode("INX B", 1, 5, null); + Opcodes[0x04] = new Opcode("INR B", 1, 5, null); + Opcodes[0x05] = new Opcode("DCR B", 1, 5, null); + Opcodes[0x06] = new Opcode("MVI B, d8", 2, 7, null); + Opcodes[0x07] = new Opcode("RLC", 1, 4, null); + Opcodes[0x08] = new Opcode("*NOP", 1, 4, null); + Opcodes[0x09] = new Opcode("DAD B", 1, 10, null); + Opcodes[0x0A] = new Opcode("LDAX B", 1, 7, null); + Opcodes[0x0B] = new Opcode("DCX B", 1, 5, null); + Opcodes[0x0C] = new Opcode("INR C", 1, 5, null); + Opcodes[0x0D] = new Opcode("DCR C", 1, 5, null); + Opcodes[0x0E] = new Opcode("MVI C, d8", 2, 7, null); + Opcodes[0x0F] = new Opcode("RRC", 1, 4, null); + + // 0x1X + Opcodes[0x10] = new Opcode("*NOP", 1, 4, null); + Opcodes[0x11] = new Opcode("LXI D, d16", 3, 10, null); + Opcodes[0x12] = new Opcode("STAX D", 1, 7, null); + Opcodes[0x13] = new Opcode("INX D", 1, 5, null); + Opcodes[0x14] = new Opcode("INR D", 1, 5, null); + Opcodes[0x15] = new Opcode("DCR D", 1, 5, null); + Opcodes[0x16] = new Opcode("MVI D, d8", 2, 7, null); + Opcodes[0x17] = new Opcode("RAL", 1, 4, null); + Opcodes[0x18] = new Opcode("*NOP", 1, 4, null); + Opcodes[0x19] = new Opcode("DAD D", 1, 10, null); + Opcodes[0x1A] = new Opcode("LDAX D", 1, 7, null); + Opcodes[0x1B] = new Opcode("DCX D", 1, 5, null); + Opcodes[0x1C] = new Opcode("INR E", 1, 5, null); + Opcodes[0x1D] = new Opcode("DCR E", 1, 5, null); + Opcodes[0x1E] = new Opcode("MVI E, d8", 2, 7, null); + Opcodes[0x1F] = new Opcode("RAR", 1, 4, null); + + // 0x2X + Opcodes[0x20] = new Opcode("*NOP", 1, 4, null); + Opcodes[0x21] = new Opcode("LXI H, d16", 3, 10, null); + Opcodes[0x22] = new Opcode("SHLD a16", 3, 16, null); + Opcodes[0x23] = new Opcode("INX H", 1, 5, null); + Opcodes[0x24] = new Opcode("INR H", 1, 5, null); + Opcodes[0x25] = new Opcode("DCR H", 1, 5, null); + Opcodes[0x26] = new Opcode("MVI H, d8", 2, 7, null); + Opcodes[0x27] = new Opcode("DAA", 1, 4, null); + Opcodes[0x28] = new Opcode("*NOP", 1, 4, null); + Opcodes[0x29] = new Opcode("DAD H", 1, 10, null); + Opcodes[0x2A] = new Opcode("LHLD a16", 3, 16, null); + Opcodes[0x2B] = new Opcode("DCX H", 1, 5, null); + Opcodes[0x2C] = new Opcode("INR L", 1, 5, null); + Opcodes[0x2D] = new Opcode("DCR L", 1, 5, null); + Opcodes[0x2E] = new Opcode("MVI L, d8", 2, 7, null); + Opcodes[0x2F] = new Opcode("CMA", 1, 4, null); + + // 0x3X + Opcodes[0x30] = new Opcode("*NOP", 1, 4, null); + Opcodes[0x31] = new Opcode("LXI SP, d16", 3, 10, null); + Opcodes[0x32] = new Opcode("STA a16", 3, 13, null); + Opcodes[0x33] = new Opcode("INX SP", 1, 5, null); + Opcodes[0x34] = new Opcode("INR M", 1, 10, null); + Opcodes[0x35] = new Opcode("DCR M", 1, 10, null); + Opcodes[0x36] = new Opcode("MVI M, d8", 2, 10, null); + Opcodes[0x37] = new Opcode("STC", 1, 4, null); + Opcodes[0x38] = new Opcode("*NOP", 1, 4, null); + Opcodes[0x39] = new Opcode("DAD SP", 1, 10, null); + Opcodes[0x3A] = new Opcode("LDA a16", 3, 13, null); + Opcodes[0x3B] = new Opcode("DCX SP", 1, 5, null); + Opcodes[0x3C] = new Opcode("INR A", 1, 5, null); + Opcodes[0x3D] = new Opcode("DCR A", 1, 5, null); + Opcodes[0x3E] = new Opcode("MVI A, d8", 2, 7, null); + Opcodes[0x3F] = new Opcode("CMC", 1, 4, null); + + // 0x4X + Opcodes[0x40] = new Opcode("MOV B, B", 1, 5, null); + Opcodes[0x41] = new Opcode("MOV B, C", 1, 5, null); + Opcodes[0x42] = new Opcode("MOV B, D", 1, 5, null); + Opcodes[0x43] = new Opcode("MOV B, E", 1, 5, null); + Opcodes[0x44] = new Opcode("MOV B, H", 1, 5, null); + Opcodes[0x45] = new Opcode("MOV B, L", 1, 5, null); + Opcodes[0x46] = new Opcode("MOV B, M", 1, 7, null); + Opcodes[0x47] = new Opcode("MOV B, A", 1, 5, null); + Opcodes[0x48] = new Opcode("MOV C, B", 1, 5, null); + Opcodes[0x49] = new Opcode("MOV C, C", 1, 5, null); + Opcodes[0x4A] = new Opcode("MOV C, D", 1, 5, null); + Opcodes[0x4B] = new Opcode("MOV C, E", 1, 5, null); + Opcodes[0x4C] = new Opcode("MOV C, H", 1, 5, null); + Opcodes[0x4D] = new Opcode("MOV C, L", 1, 5, null); + Opcodes[0x4E] = new Opcode("MOV C, M", 1, 7, null); + Opcodes[0x4F] = new Opcode("MOV C, A", 1, 5, null); + + // 0x5X + Opcodes[0x50] = new Opcode("MOV D, B", 1, 5, null); + Opcodes[0x51] = new Opcode("MOV D, C", 1, 5, null); + Opcodes[0x52] = new Opcode("MOV D, D", 1, 5, null); + Opcodes[0x53] = new Opcode("MOV D, E", 1, 5, null); + Opcodes[0x54] = new Opcode("MOV D, H", 1, 5, null); + Opcodes[0x55] = new Opcode("MOV D, L", 1, 5, null); + Opcodes[0x56] = new Opcode("MOV D, M", 1, 7, null); + Opcodes[0x57] = new Opcode("MOV D, A", 1, 5, null); + Opcodes[0x58] = new Opcode("MOV E, B", 1, 5, null); + Opcodes[0x59] = new Opcode("MOV E, C", 1, 5, null); + Opcodes[0x5A] = new Opcode("MOV E, D", 1, 5, null); + Opcodes[0x5B] = new Opcode("MOV E, E", 1, 5, null); + Opcodes[0x5C] = new Opcode("MOV E, H", 1, 5, null); + Opcodes[0x5D] = new Opcode("MOV E, L", 1, 5, null); + Opcodes[0x5E] = new Opcode("MOV E, M", 1, 7, null); + Opcodes[0x5F] = new Opcode("MOV E, A", 1, 5, null); + + // 0x6X + Opcodes[0x60] = new Opcode("MOV H, B", 1, 5, null); + Opcodes[0x61] = new Opcode("MOV H, C", 1, 5, null); + Opcodes[0x62] = new Opcode("MOV H, D", 1, 5, null); + Opcodes[0x63] = new Opcode("MOV H, E", 1, 5, null); + Opcodes[0x64] = new Opcode("MOV H, H", 1, 5, null); + Opcodes[0x65] = new Opcode("MOV H, L", 1, 5, null); + Opcodes[0x66] = new Opcode("MOV H, M", 1, 7, null); + Opcodes[0x67] = new Opcode("MOV H, A", 1, 5, null); + Opcodes[0x68] = new Opcode("MOV L, B", 1, 5, null); + Opcodes[0x69] = new Opcode("MOV L, C", 1, 5, null); + Opcodes[0x6A] = new Opcode("MOV L, D", 1, 5, null); + Opcodes[0x6B] = new Opcode("MOV L, E", 1, 5, null); + Opcodes[0x6C] = new Opcode("MOV L, H", 1, 5, null); + Opcodes[0x6D] = new Opcode("MOV L, L", 1, 5, null); + Opcodes[0x6E] = new Opcode("MOV L, M", 1, 7, null); + Opcodes[0x6F] = new Opcode("MOV L, A", 1, 5, null); + + // 0x7X + Opcodes[0x70] = new Opcode("MOV M, B", 1, 7, null); + Opcodes[0x71] = new Opcode("MOV M, C", 1, 7, null); + Opcodes[0x72] = new Opcode("MOV M, D", 1, 7, null); + Opcodes[0x73] = new Opcode("MOV M, E", 1, 7, null); + Opcodes[0x74] = new Opcode("MOV M, H", 1, 7, null); + Opcodes[0x75] = new Opcode("MOV M, L", 1, 7, null); + Opcodes[0x76] = new Opcode("HLT", 1, 7, null); + Opcodes[0x77] = new Opcode("MOV M, A", 1, 7, null); + Opcodes[0x78] = new Opcode("MOV A, B", 1, 5, null); + Opcodes[0x79] = new Opcode("MOV A, C", 1, 5, null); + Opcodes[0x7A] = new Opcode("MOV A, D", 1, 5, null); + Opcodes[0x7B] = new Opcode("MOV A, E", 1, 5, null); + Opcodes[0x7C] = new Opcode("MOV A, H", 1, 5, null); + Opcodes[0x7D] = new Opcode("MOV A, L", 1, 5, null); + Opcodes[0x7E] = new Opcode("MOV A, M", 1, 7, null); + Opcodes[0x7F] = new Opcode("MOV A, A", 1, 5, null); + + // 0x8X + Opcodes[0x80] = new Opcode("ADD B", 1, 4, null); + Opcodes[0x81] = new Opcode("ADD C", 1, 4, null); + Opcodes[0x82] = new Opcode("ADD D", 1, 4, null); + Opcodes[0x83] = new Opcode("ADD E", 1, 4, null); + Opcodes[0x84] = new Opcode("ADD H", 1, 4, null); + Opcodes[0x85] = new Opcode("ADD L", 1, 4, null); + Opcodes[0x86] = new Opcode("ADD M", 1, 7, null); + Opcodes[0x87] = new Opcode("ADD A", 1, 4, null); + Opcodes[0x88] = new Opcode("ADC B", 1, 4, null); + Opcodes[0x89] = new Opcode("ADC C", 1, 4, null); + Opcodes[0x8A] = new Opcode("ADC D", 1, 4, null); + Opcodes[0x8B] = new Opcode("ADC E", 1, 4, null); + Opcodes[0x8C] = new Opcode("ADC H", 1, 4, null); + Opcodes[0x8D] = new Opcode("ADC L", 1, 4, null); + Opcodes[0x8E] = new Opcode("ADC M", 1, 7, null); + Opcodes[0x8F] = new Opcode("ADC A", 1, 4, null); + + // 0x9X + Opcodes[0x90] = new Opcode("SUB B", 1, 4, null); + Opcodes[0x91] = new Opcode("SUB C", 1, 4, null); + Opcodes[0x92] = new Opcode("SUB D", 1, 4, null); + Opcodes[0x93] = new Opcode("SUB E", 1, 4, null); + Opcodes[0x94] = new Opcode("SUB H", 1, 4, null); + Opcodes[0x95] = new Opcode("SUB L", 1, 4, null); + Opcodes[0x96] = new Opcode("SUB M", 1, 7, null); + Opcodes[0x97] = new Opcode("SUB A", 1, 4, null); + Opcodes[0x98] = new Opcode("SBB B", 1, 4, null); + Opcodes[0x99] = new Opcode("SBB C", 1, 4, null); + Opcodes[0x9A] = new Opcode("SBB D", 1, 4, null); + Opcodes[0x9B] = new Opcode("SBB E", 1, 4, null); + Opcodes[0x9C] = new Opcode("SBB H", 1, 4, null); + Opcodes[0x9D] = new Opcode("SBB L", 1, 4, null); + Opcodes[0x9E] = new Opcode("SBB M", 1, 7, null); + Opcodes[0x9F] = new Opcode("SBB A", 1, 4, null); + + // 0xAX + Opcodes[0xA0] = new Opcode("ANA B", 1, 4, null); + Opcodes[0xA1] = new Opcode("ANA C", 1, 4, null); + Opcodes[0xA2] = new Opcode("ANA D", 1, 4, null); + Opcodes[0xA3] = new Opcode("ANA E", 1, 4, null); + Opcodes[0xA4] = new Opcode("ANA H", 1, 4, null); + Opcodes[0xA5] = new Opcode("ANA L", 1, 4, null); + Opcodes[0xA6] = new Opcode("ANA M", 1, 7, null); + Opcodes[0xA7] = new Opcode("ANA A", 1, 4, null); + Opcodes[0xA8] = new Opcode("XRA B", 1, 4, null); + Opcodes[0xA9] = new Opcode("XRA C", 1, 4, null); + Opcodes[0xAA] = new Opcode("XRA D", 1, 4, null); + Opcodes[0xAB] = new Opcode("XRA E", 1, 4, null); + Opcodes[0xAC] = new Opcode("XRA H", 1, 4, null); + Opcodes[0xAD] = new Opcode("XRA L", 1, 4, null); + Opcodes[0xAE] = new Opcode("XRA M", 1, 7, null); + Opcodes[0xAF] = new Opcode("XRA A", 1, 4, null); + + // 0xBX + Opcodes[0xB0] = new Opcode("ORA B", 1, 4, null); + Opcodes[0xB1] = new Opcode("ORA C", 1, 4, null); + Opcodes[0xB2] = new Opcode("ORA D", 1, 4, null); + Opcodes[0xB3] = new Opcode("ORA E", 1, 4, null); + Opcodes[0xB4] = new Opcode("ORA H", 1, 4, null); + Opcodes[0xB5] = new Opcode("ORA L", 1, 4, null); + Opcodes[0xB6] = new Opcode("ORA M", 1, 7, null); + Opcodes[0xB7] = new Opcode("ORA A", 1, 4, null); + Opcodes[0xB8] = new Opcode("CMP B", 1, 4, null); + Opcodes[0xB9] = new Opcode("CMP C", 1, 4, null); + Opcodes[0xBA] = new Opcode("CMP D", 1, 4, null); + Opcodes[0xBB] = new Opcode("CMP E", 1, 4, null); + Opcodes[0xBC] = new Opcode("CMP H", 1, 4, null); + Opcodes[0xBD] = new Opcode("CMP L", 1, 4, null); + Opcodes[0xBE] = new Opcode("CMP M", 1, 7, null); + Opcodes[0xBF] = new Opcode("CMP A", 1, 4, null); + + // 0xCX + Opcodes[0xC0] = new Opcode("RNZ", 1, 5, 11); + Opcodes[0xC1] = new Opcode("POP B", 1, 10, null); + Opcodes[0xC2] = new Opcode("JNZ a16", 3, 10, null); + Opcodes[0xC3] = new Opcode("JMP a16", 3, 10, null); + Opcodes[0xC4] = new Opcode("CNZ a16", 3, 11, 17); + Opcodes[0xC5] = new Opcode("PUSH B", 1, 11, null); + Opcodes[0xC6] = new Opcode("ADI d8", 2, 7, null); + Opcodes[0xC7] = new Opcode("RST 0", 1, 11, null); + Opcodes[0xC8] = new Opcode("RZ", 1, 5, 11); + Opcodes[0xC9] = new Opcode("RET", 1, 10, null); + Opcodes[0xCA] = new Opcode("JZ a16", 3, 10, null); + Opcodes[0xCB] = new Opcode("*JMP a16", 3, 10, null); + Opcodes[0xCC] = new Opcode("CZ a16", 3, 11, 17); + Opcodes[0xCD] = new Opcode("CALL a16", 3, 17, null); + Opcodes[0xCE] = new Opcode("ACI d8", 2, 7, null); + Opcodes[0xCF] = new Opcode("RST 1", 1, 11, null); + + // 0xDX + Opcodes[0xD0] = new Opcode("RNC", 1, 5, 11); + Opcodes[0xD1] = new Opcode("POP D", 1, 10, null); + Opcodes[0xD2] = new Opcode("JNC a16", 3, 10, null); + Opcodes[0xD3] = new Opcode("OUT d8", 2, 10, null); + Opcodes[0xD4] = new Opcode("CNC a16", 3, 11, 17); + Opcodes[0xD5] = new Opcode("PUSH D", 1, 11, null); + Opcodes[0xD6] = new Opcode("SUI d8", 2, 7, null); + Opcodes[0xD7] = new Opcode("RST 2", 1, 11, null); + Opcodes[0xD8] = new Opcode("RC", 1, 5, 11); + Opcodes[0xD9] = new Opcode("*RET", 1, 10, null); + Opcodes[0xDA] = new Opcode("JC a16", 3, 10, null); + Opcodes[0xDB] = new Opcode("IN d8", 2, 10, null); + Opcodes[0xDC] = new Opcode("CC a16", 3, 11, 17); + Opcodes[0xDD] = new Opcode("*CALL a16", 3, 17, null); + Opcodes[0xDE] = new Opcode("SBI d8", 2, 7, null); + Opcodes[0xDF] = new Opcode("RST 3", 1, 11, null); + + // 0xEX + Opcodes[0xE0] = new Opcode("RPO", 1, 5, 11); + Opcodes[0xE1] = new Opcode("POP H", 1, 10, null); + Opcodes[0xE2] = new Opcode("JPO a16", 3, 10, null); + Opcodes[0xE3] = new Opcode("XTHL", 1, 18, null); + Opcodes[0xE4] = new Opcode("CPO a16", 3, 11, 17); + Opcodes[0xE5] = new Opcode("PUSH H", 1, 11, null); + Opcodes[0xE6] = new Opcode("ANI d8", 2, 7, null); + Opcodes[0xE7] = new Opcode("RST 4", 1, 11, null); + Opcodes[0xE8] = new Opcode("RPE", 1, 5, 11); + Opcodes[0xE9] = new Opcode("PCHL", 1, 5, null); + Opcodes[0xEA] = new Opcode("JPE a16", 3, 10, null); + Opcodes[0xEB] = new Opcode("XCHG", 1, 5, null); + Opcodes[0xEC] = new Opcode("CPE a16", 3, 11, 17); + Opcodes[0xED] = new Opcode("*CALL a16", 3, 17, null); + Opcodes[0xEE] = new Opcode("XRI d8", 2, 7, null); + Opcodes[0xEF] = new Opcode("RST 5", 1, 11, null); + + // 0xFX + Opcodes[0xF0] = new Opcode("RP", 1, 5, 11); + Opcodes[0xF1] = new Opcode("POP PSW", 1, 10, null); + Opcodes[0xF2] = new Opcode("JP a16", 3, 10, null); + Opcodes[0xF3] = new Opcode("DI", 1, 4, null); + Opcodes[0xF4] = new Opcode("CP a16", 3, 11, 17); + Opcodes[0xF5] = new Opcode("PUSH PSW", 1, 11, null); + Opcodes[0xF6] = new Opcode("ORI d8", 2, 7, null); + Opcodes[0xF7] = new Opcode("RST 6", 1, 11, null); + Opcodes[0xF8] = new Opcode("RM", 1, 5, 11); + Opcodes[0xF9] = new Opcode("SPHL", 1, 5, null); + Opcodes[0xFA] = new Opcode("JM a16", 3, 10, null); + Opcodes[0xFB] = new Opcode("EI", 1, 4, null); + Opcodes[0xFC] = new Opcode("CM a16", 3, 11, 17); + Opcodes[0xFD] = new Opcode("*CALL a16", 3, 17, null); + Opcodes[0xFE] = new Opcode("CPI d8", 2, 7, null); + Opcodes[0xFF] = new Opcode("RST 7", 1, 11, null); + } +} \ No newline at end of file diff --git a/Intel8080.Emulator/Registers.cs b/Intel8080.Emulator/Registers.cs index dde44c0..7042323 100644 --- a/Intel8080.Emulator/Registers.cs +++ b/Intel8080.Emulator/Registers.cs @@ -1,48 +1,47 @@ -using System.Runtime.InteropServices; - -namespace Intel8080.Emulator -{ - [StructLayout(LayoutKind.Explicit)] - public class Registers - { - [FieldOffset(0)] - public byte A = 0x00; - - [FieldOffset(1)] - public ushort BC = 0x0000; - [FieldOffset(2)] - public byte B; - [FieldOffset(1)] - public byte C; - - [FieldOffset(3)] - public ushort DE = 0x0000; - [FieldOffset(4)] - public byte D; - [FieldOffset(3)] - public byte E; - - [FieldOffset(5)] - public ushort HL = 0x0000; - [FieldOffset(6)] - public byte H; - [FieldOffset(5)] - public byte L; - - [FieldOffset(7)] - public ushort SP = 0x0000; - - [FieldOffset(9)] - public ushort PC = 0x0000; - - public void Clear() - { - A = 0x00; - BC = 0x0000; - DE = 0x0000; - HL = 0x0000; - PC = 0x0000; - SP = 0x0000; - } - } +using System.Runtime.InteropServices; + +namespace Intel8080.Emulator; + +[StructLayout(LayoutKind.Explicit)] +public class Registers +{ + [FieldOffset(0)] + public byte A = 0x00; + + [FieldOffset(1)] + public ushort BC = 0x0000; + [FieldOffset(2)] + public byte B; + [FieldOffset(1)] + public byte C; + + [FieldOffset(3)] + public ushort DE = 0x0000; + [FieldOffset(4)] + public byte D; + [FieldOffset(3)] + public byte E; + + [FieldOffset(5)] + public ushort HL = 0x0000; + [FieldOffset(6)] + public byte H; + [FieldOffset(5)] + public byte L; + + [FieldOffset(7)] + public ushort SP = 0x0000; + + [FieldOffset(9)] + public ushort PC = 0x0000; + + public void Clear() + { + A = 0x00; + BC = 0x0000; + DE = 0x0000; + HL = 0x0000; + PC = 0x0000; + SP = 0x0000; + } } \ No newline at end of file diff --git a/Intel8080.TestRoms/Devices/TestCompletePort.cs b/Intel8080.TestRoms/Devices/TestCompletePort.cs index 09c3387..1532de7 100644 --- a/Intel8080.TestRoms/Devices/TestCompletePort.cs +++ b/Intel8080.TestRoms/Devices/TestCompletePort.cs @@ -1,16 +1,15 @@ -using Intel8080.Emulator.IO; - -namespace Intel8080.TestRoms.IODevices -{ - internal class TestCompletePort : IOutputDevice - { - public const int PortNo = 0x00; - - public bool TestComplete { get; set; } = false; - - public void Write(byte data) - { - TestComplete = true; - } - } -} +using Intel8080.Emulator.IO; + +namespace Intel8080.TestRoms.IODevices; + +internal class TestCompletePort : IOutputDevice +{ + public const int PortNo = 0x00; + + public bool TestComplete { get; set; } = false; + + public void Write(byte data) + { + TestComplete = true; + } +} \ No newline at end of file diff --git a/Intel8080.TestRoms/Devices/TestOutputPort.cs b/Intel8080.TestRoms/Devices/TestOutputPort.cs index 73e6d86..abf9808 100644 --- a/Intel8080.TestRoms/Devices/TestOutputPort.cs +++ b/Intel8080.TestRoms/Devices/TestOutputPort.cs @@ -1,38 +1,37 @@ -using Intel8080.Emulator; -using Intel8080.Emulator.IO; -using System; - -namespace Intel8080.TestRoms.IODevices -{ - internal class TestOutputPort : IOutputDevice - { - public const int PortNo = 0x01; - - private readonly CPU _cpu; - - public TestOutputPort(CPU cpu) - { - _cpu = cpu; - } - - public void Write(byte data) - { - byte operation = _cpu.Registers.C; - - if (operation == 2) - { - char c = (char)_cpu.Registers.E; - - Console.Write(c); - } - else if (operation == 9) - { - ushort addr = (ushort)((_cpu.Registers.D << 8) | _cpu.Registers.E); - do - { - Console.Write((char)_cpu.Memory[addr++]); - } while (_cpu.Memory[addr] != '$'); - } - } - } -} +using System; +using Intel8080.Emulator; +using Intel8080.Emulator.IO; + +namespace Intel8080.TestRoms.IODevices; + +internal class TestOutputPort : IOutputDevice +{ + public const int PortNo = 0x01; + + private readonly CPU _cpu; + + public TestOutputPort(CPU cpu) + { + _cpu = cpu; + } + + public void Write(byte data) + { + byte operation = _cpu.Registers.C; + + if (operation == 2) + { + char c = (char)_cpu.Registers.E; + + Console.Write(c); + } + else if (operation == 9) + { + ushort addr = (ushort)((_cpu.Registers.D << 8) | _cpu.Registers.E); + do + { + Console.Write((char)_cpu.Memory[addr++]); + } while (_cpu.Memory[addr] != '$'); + } + } +} \ No newline at end of file diff --git a/Intel8080.TestRoms/Intel8080.TestRoms.csproj b/Intel8080.TestRoms/Intel8080.TestRoms.csproj index 24af890..d85e740 100644 --- a/Intel8080.TestRoms/Intel8080.TestRoms.csproj +++ b/Intel8080.TestRoms/Intel8080.TestRoms.csproj @@ -2,7 +2,7 @@ Exe - net6.0 + net8.0 diff --git a/Intel8080.TestRoms/MainMemory.cs b/Intel8080.TestRoms/MainMemory.cs index 737ff20..15d30f0 100644 --- a/Intel8080.TestRoms/MainMemory.cs +++ b/Intel8080.TestRoms/MainMemory.cs @@ -1,25 +1,24 @@ -using Intel8080.Emulator; -using System.IO; - -namespace Intel8080.TestRoms -{ - internal class MainMemory : IMemory - { - private readonly byte[] _memory; - - public byte this[int index] { get => _memory[index]; set => _memory[index] = value; } - - public MainMemory(int size) - { - _memory = new byte[size]; - } - - public void LoadRom(string path, int offset) - { - using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read)) - { - fs.Read(_memory, offset, (int) fs.Length); - } - } - } -} +using System.IO; +using Intel8080.Emulator; + +namespace Intel8080.TestRoms; + +public class MainMemory : IMemory +{ + private readonly byte[] _memory; + + public byte this[int index] { get => _memory[index]; set => _memory[index] = value; } + + public MainMemory(int size) + { + _memory = new byte[size]; + } + + public void LoadRom(string path, int offset) + { + using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read)) + { + fs.Read(_memory, offset, (int)fs.Length); + } + } +} \ No newline at end of file diff --git a/Intel8080.TestRoms/Program.cs b/Intel8080.TestRoms/Program.cs index a8c255c..b9a116f 100644 --- a/Intel8080.TestRoms/Program.cs +++ b/Intel8080.TestRoms/Program.cs @@ -1,12 +1,16 @@ -namespace Intel8080.TestRoms -{ - class Program - { - static void Main(string[] args) - { - var testSuite = new TestSuite(); - - testSuite.RunTests(); - } - } -} +using Intel8080.Emulator; + +namespace Intel8080.TestRoms; + +class Program +{ + static void Main(string[] args) + { + var memory = new MainMemory(0x10000); + var cpu = new CPU(memory); + + var testSuite = new TestSuite(cpu, memory); + + testSuite.RunTests(); + } +} \ No newline at end of file diff --git a/Intel8080.TestRoms/TestSuite.cs b/Intel8080.TestRoms/TestSuite.cs index e225482..ebd1ef1 100644 --- a/Intel8080.TestRoms/TestSuite.cs +++ b/Intel8080.TestRoms/TestSuite.cs @@ -1,77 +1,76 @@ -using Intel8080.Emulator; -using Intel8080.TestRoms.IODevices; -using System; -using System.Collections.Generic; - -namespace Intel8080.TestRoms -{ - public class TestSuite - { - private readonly CPU _cpu; - private readonly MainMemory _memory; - private readonly TestCompletePort _testCompletePort; - private readonly TestOutputPort _textOutputPort; - - private readonly List _testRoms = new List() - { - "Roms/TST8080.COM", - "Roms/CPUTEST.COM", - "Roms/8080PRE.COM", - "Roms/8080EXM.COM" - }; - - public TestSuite() - { - _memory = new MainMemory(0x10000); - _cpu = new CPU(_memory); - - _testCompletePort = new TestCompletePort(); - _textOutputPort = new TestOutputPort(_cpu); - - _cpu.IOController.AddDevice(_testCompletePort, TestCompletePort.PortNo); - _cpu.IOController.AddDevice(_textOutputPort, TestOutputPort.PortNo); - } - - public void RunTests() - { - foreach (var rom in _testRoms) - { - _cpu.Reset(); - - Console.ForegroundColor = ConsoleColor.Green; - Console.WriteLine($"Starting test: {rom}"); - Console.ForegroundColor = ConsoleColor.White; - - _memory.LoadRom(rom, 0x0100); - - RunTest(); - - Console.WriteLine(); - Console.WriteLine(); - } - - Console.ForegroundColor = ConsoleColor.Green; - Console.WriteLine("All tests completed."); - Console.ForegroundColor = ConsoleColor.White; - } - - private void RunTest() - { - _testCompletePort.TestComplete = false; - - _cpu.Registers.PC = 0x100; - - _memory[0x0000] = 0xD3; - _memory[0x0001] = 0x00; - - _memory[0x0005] = 0xD3; - _memory[0x0006] = 0x01; - _memory[0x0007] = 0xC9; - - while (!_testCompletePort.TestComplete) - { - _cpu.Step(); - } - } - } -} +using System; +using System.Collections.Generic; +using Intel8080.Emulator; +using Intel8080.TestRoms.IODevices; + +namespace Intel8080.TestRoms; + +public class TestSuite +{ + private readonly CPU _cpu; + private readonly MainMemory _memory; + private readonly TestCompletePort _testCompletePort; + private readonly TestOutputPort _textOutputPort; + + private readonly List _testRoms = new List() + { + "Roms/TST8080.COM", + "Roms/CPUTEST.COM", + "Roms/8080PRE.COM", + "Roms/8080EXM.COM" + }; + + public TestSuite(CPU cpu, MainMemory memory) + { + _cpu = cpu; + _memory = memory; + + _testCompletePort = new TestCompletePort(); + _textOutputPort = new TestOutputPort(_cpu); + + _cpu.IOController.AddDevice(_testCompletePort, TestCompletePort.PortNo); + _cpu.IOController.AddDevice(_textOutputPort, TestOutputPort.PortNo); + } + + public void RunTests() + { + foreach (var rom in _testRoms) + { + _cpu.Reset(); + + Console.ForegroundColor = ConsoleColor.Green; + Console.WriteLine($"Starting test: {rom}"); + Console.ForegroundColor = ConsoleColor.White; + + _memory.LoadRom(rom, 0x0100); + + RunTest(); + + Console.WriteLine(); + Console.WriteLine(); + } + + Console.ForegroundColor = ConsoleColor.Green; + Console.WriteLine("All tests completed."); + Console.ForegroundColor = ConsoleColor.White; + } + + private void RunTest() + { + _testCompletePort.TestComplete = false; + + _cpu.Registers.PC = 0x100; + + _memory[0x0000] = 0xD3; + _memory[0x0001] = 0x00; + + _memory[0x0005] = 0xD3; + _memory[0x0006] = 0x01; + _memory[0x0007] = 0xC9; + + while (!_testCompletePort.TestComplete) + { + _cpu.Step(); + } + } +} \ No newline at end of file diff --git a/README.md b/README.md index 9a3d76c..ad16cee 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ ## Building ### Requirements - Git -- [.NET 6 SDK](https://dotnet.microsoft.com/en-us/download) +- [.NET 8 SDK](https://dotnet.microsoft.com/en-us/download) ```ps git clone https://github.com/sfitz42/NET8080.git