351 files changed, 3952 insertions(+), 1709 deletions(-)

M jasm/assemble/assembler_impl/assembler_impl.cpp
M jasm/assemble/assembler_impl/assembler_impl.h
M jasm/assemble/assembler_impl/functions_impl.cpp
M jasm/assemble/assembler_impl/methods_impl.cpp
M jasm/assemble/assembler_impl/operators_impl.cpp
M jasm/assemble/assembler_impl/symbols_impl.cpp
M jasm/assemble/assembler_impl/syntax_impl.cpp
M jasm/assemble/functions.cpp
M jasm/assemble/functions.h
M jasm/assemble/methods.cpp
M jasm/assemble/methods.h
M jasm/assemble/value.cpp
M jasm/assemble/value.h
M jasm/docs/jasm.md
M jasm/docs/syntax_highlight.py
M jasm/exceptions/error_codes.h
A => jasm/processor/45gs02/instructions_45gs02.cpp
A => jasm/processor/45gs02/instructions_45gs02.h
A => jasm/processor/45gs02/processor_45gs02.cpp
A => jasm/processor/45gs02/processor_45gs02.h
A => jasm/processor/45gs02/processor_keywords_45gs02.cpp
A => jasm/processor/45gs02/processor_keywords_45gs02.h
M jasm/processor/65c02/processor_65c02.cpp
M jasm/processor/65ce02/instructions_65ce02.cpp
M jasm/processor/65ce02/instructions_65ce02.h
M jasm/processor/65ce02/processor_65ce02.cpp
M jasm/processor/instructions.h
M jasm/processor/processor.cpp
M jasm/processor/processor.h
M jasm/processor/processor_unspecified.cpp => jasm/processor/unspecified/processor_unspecified.cpp
M jasm/processor/processor_unspecified.h => jasm/processor/unspecified/processor_unspecified.h
M jasm/syntax/syntax_parser.cpp
M jasm/syntax/syntax_tokens.h
M jasm/unit_test.py
M jasm/unit_test_generate.py
M jasm/unit_test_run.py
R jasm/unit_tests/results/test_addressing_mode_expected_x_in_indirect_65c02.stdout => 
R jasm/unit_tests/results/test_addressing_mode_expected_y_in_indirect_65c02.stdout => 
A => jasm/unit_tests/results/test_addressing_mode_expected_z_in_indirect_quad_45gs02.stdout
R jasm/unit_tests/results/test_addressing_mode_needs_bit_size_argument_65ce02.stdout => 
R jasm/unit_tests/results/test_addressing_mode_needs_byte_argument_1_65c02.stdout => 
R jasm/unit_tests/results/test_addressing_mode_needs_byte_argument_1_65ce02.stdout => 
R jasm/unit_tests/results/test_addressing_mode_needs_byte_argument_2_65c02.stdout => 
R jasm/unit_tests/results/test_addressing_mode_needs_byte_argument_2_65ce02.stdout => 
R jasm/unit_tests/results/test_addressing_mode_needs_byte_argument_3_65ce02.stdout => 
R jasm/unit_tests/results/test_addressing_mode_needs_integer_argument_1_65c02.stdout => 
R jasm/unit_tests/results/test_addressing_mode_needs_integer_argument_1_65ce02.stdout => 
R jasm/unit_tests/results/test_addressing_mode_needs_integer_argument_2_65ce02.stdout => 
R jasm/unit_tests/results/test_addressing_mode_needs_integer_argument_3_65ce02.stdout => 
R jasm/unit_tests/results/test_addressing_mode_needs_integer_argument_4_65ce02.stdout => 
R jasm/unit_tests/results/test_addressing_mode_needs_positive_argument_1_65c02.stdout => 
R jasm/unit_tests/results/test_addressing_mode_needs_positive_argument_1_65ce02.stdout => 
R jasm/unit_tests/results/test_addressing_mode_needs_positive_argument_2_65ce02.stdout => 
R jasm/unit_tests/results/test_addressing_mode_needs_word_size_argument_1_65c02.stdout => 
R jasm/unit_tests/results/test_addressing_mode_needs_word_size_argument_1_65ce02.stdout => 
R jasm/unit_tests/results/test_addressing_mode_needs_word_size_argument_2_65c02.stdout => 
R jasm/unit_tests/results/test_addressing_mode_needs_word_size_argument_2_65ce02.stdout => 
A => jasm/unit_tests/results/test_all_instructions_45gs02.bin
M jasm/unit_tests/results/test_all_instructions_65c02.bin
M jasm/unit_tests/results/test_all_instructions_65ce02.bin
R jasm/unit_tests/results/test_bank_mode_truncates_address_instructions_65c02.bin => 
R jasm/unit_tests/results/test_bank_mode_truncates_address_instructions_65ce02.bin => 
M jasm/unit_tests/results/test_map_access_missing_key.stdout => jasm/unit_tests/results/test_dict_access_missing_key.stdout
M jasm/unit_tests/results/test_map_clear_on_const_map.stdout => jasm/unit_tests/results/test_dict_clear_on_const_map.stdout
M jasm/unit_tests/results/test_map_clear_removes_keys.stdout => jasm/unit_tests/results/test_dict_clear_removes_keys.stdout
M jasm/unit_tests/results/test_map_construct_arguments.bin => jasm/unit_tests/results/test_dict_construct_arguments.bin
M jasm/unit_tests/results/test_map_construct_empty.bin => jasm/unit_tests/results/test_dict_construct_empty.bin
M jasm/unit_tests/results/test_map_construct_with_duplicate_keys.stdout => jasm/unit_tests/results/test_dict_construct_with_duplicate_keys.stdout
M jasm/unit_tests/results/test_map_construct_with_missing_assignment.stdout => jasm/unit_tests/results/test_dict_construct_with_missing_assignment.stdout
M jasm/unit_tests/results/test_map_construct_with_unsupported_key_type.stdout => jasm/unit_tests/results/test_dict_construct_with_unsupported_key_type.stdout
M jasm/unit_tests/results/test_map_empty_property.bin => jasm/unit_tests/results/test_dict_empty_property.bin
M jasm/unit_tests/results/test_map_erase_removes_key.stdout => jasm/unit_tests/results/test_dict_erase_removes_key.stdout
M jasm/unit_tests/results/test_map_erase_with_missing_key.stdout => jasm/unit_tests/results/test_dict_erase_with_missing_key.stdout
M jasm/unit_tests/results/test_map_erase_with_unsupported_key_type.stdout => jasm/unit_tests/results/test_dict_erase_with_unsupported_key_type.stdout
M jasm/unit_tests/results/test_map_get_with_unsupported_key_type.stdout => jasm/unit_tests/results/test_dict_get_with_unsupported_key_type.stdout
M jasm/unit_tests/results/test_map_get_with_valid_key_types.bin => jasm/unit_tests/results/test_dict_get_with_valid_key_types.bin
M jasm/unit_tests/results/test_map_has_checks_existence.bin => jasm/unit_tests/results/test_dict_has_checks_existence.bin
M jasm/unit_tests/results/test_map_has_with_unsupported_key_type.stdout => jasm/unit_tests/results/test_dict_has_with_unsupported_key_type.stdout
M jasm/unit_tests/results/test_map_key_types.bin => jasm/unit_tests/results/test_dict_key_types.bin
M jasm/unit_tests/results/test_map_length_property.bin => jasm/unit_tests/results/test_dict_length_property.bin
M jasm/unit_tests/results/test_map_overwrite_key.bin => jasm/unit_tests/results/test_dict_overwrite_key.bin
M jasm/unit_tests/results/test_map_range_for_global_loop_variable.bin => jasm/unit_tests/results/test_dict_range_for_global_loop_variable.bin
M jasm/unit_tests/results/test_map_range_for_has_proper_key_reference.bin => jasm/unit_tests/results/test_dict_range_for_has_proper_key_reference.bin
M jasm/unit_tests/results/test_map_range_for_local_loop_variable_doesnt_collide_with_outside.bin => jasm/unit_tests/results/test_dict_range_for_local_loop_variable_doesnt_collide_with_outside.bin
M jasm/unit_tests/results/test_map_range_for_local_loop_variable_reserved_inside_loop_body.stdout => jasm/unit_tests/results/test_dict_range_for_local_loop_variable_reserved_inside_loop_body.stdout
M jasm/unit_tests/results/test_map_range_for_makes_copy_of_map.bin => jasm/unit_tests/results/test_dict_range_for_makes_copy_of_map.bin
M jasm/unit_tests/results/test_map_range_for_requires_iterable_type.stdout => jasm/unit_tests/results/test_dict_range_for_requires_iterable_type.stdout
M jasm/unit_tests/results/test_map_range_for_with_global_variable_collides_with_other.stdout => jasm/unit_tests/results/test_dict_range_for_with_global_variable_collides_with_other.stdout
M jasm/unit_tests/results/test_map_range_for_with_local_loop_variables.bin => jasm/unit_tests/results/test_dict_range_for_with_local_loop_variables.bin
M jasm/unit_tests/results/test_map_range_for_z80.bin => jasm/unit_tests/results/test_dict_range_for_z80.bin
M jasm/unit_tests/results/test_map_set_new_key.bin => jasm/unit_tests/results/test_dict_set_new_key.bin
M jasm/unit_tests/results/test_map_set_on_constant_map.stdout => jasm/unit_tests/results/test_dict_set_on_constant_map.stdout
M jasm/unit_tests/results/test_map_set_with_unsupported_key_type.stdout => jasm/unit_tests/results/test_dict_set_with_unsupported_key_type.stdout
M jasm/unit_tests/results/test_map_with_list_value.bin => jasm/unit_tests/results/test_dict_with_list_value.bin
R jasm/unit_tests/results/test_generate_data_in_instruction_1_65c02.stdout => 
R jasm/unit_tests/results/test_generate_data_in_instruction_1_65ce02.stdout => 
R jasm/unit_tests/results/test_instruction_data_global_label_65c02.bin => 
R jasm/unit_tests/results/test_instruction_data_global_label_65ce02.bin => 
R jasm/unit_tests/results/test_instruction_data_label_cant_have_implied_addressing_mode_65c02.stdout => 
R jasm/unit_tests/results/test_instruction_data_label_cant_have_implied_addressing_mode_65ce02.stdout => 
R jasm/unit_tests/results/test_instruction_data_label_for_wrong_argument_type_3_65ce02.stdout => 
R jasm/unit_tests/results/test_instruction_data_label_has_lo_hi_properties_65c02.bin => 
R jasm/unit_tests/results/test_instruction_data_label_has_lo_hi_properties_65ce02.bin => 
A => jasm/unit_tests/results/test_instruction_data_label_offsets_45gs02.bin
M jasm/unit_tests/results/test_instruction_data_label_offsets_65c02.bin
M jasm/unit_tests/results/test_instruction_data_label_offsets_65ce02.bin
A => jasm/unit_tests/results/test_instruction_data_label_sizes_45gs02.bin
M jasm/unit_tests/results/test_instruction_data_label_sizes_65c02.bin
M jasm/unit_tests/results/test_instruction_data_label_sizes_65ce02.bin
R jasm/unit_tests/results/test_instruction_data_label_with_export_65c02.bin => 
R jasm/unit_tests/results/test_instruction_data_label_with_export_65ce02.bin => 
R jasm/unit_tests/results/test_instruction_data_label_with_local_export_65c02.stdout => 
R jasm/unit_tests/results/test_instruction_data_label_with_local_export_65ce02.stdout => 
R jasm/unit_tests/results/test_instruction_data_local_label_65c02.bin => 
R jasm/unit_tests/results/test_instruction_data_local_label_65ce02.bin => 
R jasm/unit_tests/results/test_instruction_ends_at_newline_1_65c02.bin => 
R jasm/unit_tests/results/test_instruction_ends_at_newline_1_65ce02.bin => 
R jasm/unit_tests/results/test_instruction_ends_at_newline_2_65c02.stdout => 
R jasm/unit_tests/results/test_instruction_ends_at_newline_2_65ce02.stdout => 
R jasm/unit_tests/results/test_instruction_names_can_be_used_in_local_variables_65c02.bin => 
R jasm/unit_tests/results/test_instruction_names_can_be_used_in_local_variables_65ce02.bin => 
A => jasm/unit_tests/results/test_instruction_sizes_45gs02.bin
R jasm/unit_tests/results/test_instructions_must_be_in_code_sections_1_65c02.stdout => 
R jasm/unit_tests/results/test_instructions_must_be_in_code_sections_1_65ce02.stdout => 
R jasm/unit_tests/results/test_instructions_must_be_in_code_sections_2_65c02.stdout => 
R jasm/unit_tests/results/test_instructions_must_be_in_code_sections_2_65ce02.stdout => 
M jasm/unit_tests/results/test_processor_with_invalid_name.stdout
R jasm/unit_tests/results/test_pseudo_instructions_for_branching_65c02.bin => 
M jasm/unit_tests/results/test_pseudo_instructions_for_branching_65ce02.bin
R jasm/unit_tests/results/test_pseudo_instructions_for_incrementing_65ce02.bin => 
M jasm/unit_tests/results/test_pseudo_instructions_in_standard_mode_65c02.stdout
M jasm/unit_tests/results/test_pseudo_instructions_in_standard_mode_65ce02.stdout
R jasm/unit_tests/results/test_pseudo_instructions_use_names_in_standard_mode_65c02.bin => 
R jasm/unit_tests/results/test_pseudo_instructions_use_names_in_standard_mode_65ce02.bin => 
R jasm/unit_tests/results/test_register_names_can_be_used_in_local_names_65c02.bin => 
R jasm/unit_tests/results/test_register_names_can_be_used_in_local_names_65ce02.bin => 
R jasm/unit_tests/results/test_register_names_cant_be_used_as_global_variables_65c02.stdout => 
R jasm/unit_tests/results/test_register_names_cant_be_used_as_global_variables_65ce02.stdout => 
R jasm/unit_tests/results/test_subroutine_call_65c02.bin => 
R jasm/unit_tests/results/test_subroutine_call_65ce02.bin => 
R jasm/unit_tests/results/test_subroutine_call_must_be_in_code_section_65c02.stdout => 
R jasm/unit_tests/results/test_subroutine_call_must_be_in_code_section_65ce02.stdout => 
R jasm/unit_tests/results/test_subroutine_call_negative_argument_65c02.stdout => 
R jasm/unit_tests/results/test_subroutine_call_negative_argument_65ce02.stdout => 
R jasm/unit_tests/results/test_subroutine_call_recursive_data_generation_65c02.stdout => 
R jasm/unit_tests/results/test_subroutine_call_recursive_data_generation_65ce02.stdout => 
R jasm/unit_tests/results/test_subroutine_call_too_large_argument_65c02.stdout => 
R jasm/unit_tests/results/test_subroutine_call_too_large_argument_65ce02.stdout => 
R jasm/unit_tests/results/test_subroutine_call_with_arguments_65c02.stdout => 
R jasm/unit_tests/results/test_subroutine_call_with_arguments_65ce02.stdout => 
R jasm/unit_tests/results/test_subroutine_falls_through_1_65c02.bin => 
R jasm/unit_tests/results/test_subroutine_falls_through_1_65c02.stdout => 
R jasm/unit_tests/results/test_subroutine_falls_through_1_65ce02.bin => 
R jasm/unit_tests/results/test_subroutine_falls_through_1_65ce02.stdout => 
M jasm/unit_tests/results/test_subroutine_falls_through_2_6502.bin
R jasm/unit_tests/results/test_subroutine_falls_through_2_65c02.bin => 
R jasm/unit_tests/results/test_subroutine_falls_through_2_65c02.stdout => 
R jasm/unit_tests/results/test_subroutine_falls_through_2_65ce02.bin => 
R jasm/unit_tests/results/test_subroutine_falls_through_2_65ce02.stdout => 
R jasm/unit_tests/results/test_subroutine_falls_through_3_65c02.bin => 
R jasm/unit_tests/results/test_subroutine_falls_through_3_65c02.stdout => 
R jasm/unit_tests/results/test_subroutine_falls_through_3_65ce02.bin => 
R jasm/unit_tests/results/test_subroutine_falls_through_3_65ce02.stdout => 
R jasm/unit_tests/results/test_subroutine_falls_through_4_65c02.bin => 
R jasm/unit_tests/results/test_subroutine_falls_through_4_65c02.stdout => 
R jasm/unit_tests/results/test_subroutine_falls_through_4_65ce02.bin => 
R jasm/unit_tests/results/test_subroutine_falls_through_4_65ce02.stdout => 
M jasm/unit_tests/test_addressing_mode_branch_too_long_1_65ce02.asm
M jasm/unit_tests/test_addressing_mode_branch_too_long_2_65ce02.asm
M jasm/unit_tests/test_addressing_mode_expected_x_in_indirect_6502.asm
R jasm/unit_tests/test_addressing_mode_expected_x_in_indirect_65c02.asm => 
M jasm/unit_tests/test_addressing_mode_expected_x_in_indirect_65ce02.asm
M jasm/unit_tests/test_addressing_mode_expected_y_in_indirect_6502.asm
R jasm/unit_tests/test_addressing_mode_expected_y_in_indirect_65c02.asm => 
M jasm/unit_tests/test_addressing_mode_expected_y_or_z_in_indirect_65ce02.asm
A => jasm/unit_tests/test_addressing_mode_expected_z_in_indirect_quad_45gs02.asm
M jasm/unit_tests/test_addressing_mode_immediate_value_too_large_65ce02.asm
M jasm/unit_tests/test_addressing_mode_immediate_value_too_small_65ce02.asm
M jasm/unit_tests/test_addressing_mode_is_illegal_65ce02.asm
M jasm/unit_tests/test_addressing_mode_needs_bit_size_argument_65c02.asm
R jasm/unit_tests/test_addressing_mode_needs_bit_size_argument_65ce02.asm => 
M jasm/unit_tests/test_addressing_mode_needs_byte_argument_1_6502.asm
R jasm/unit_tests/test_addressing_mode_needs_byte_argument_1_65c02.asm => 
R jasm/unit_tests/test_addressing_mode_needs_byte_argument_1_65ce02.asm => 
M jasm/unit_tests/test_addressing_mode_needs_byte_argument_2_6502.asm
R jasm/unit_tests/test_addressing_mode_needs_byte_argument_2_65c02.asm => 
R jasm/unit_tests/test_addressing_mode_needs_byte_argument_2_65ce02.asm => 
M jasm/unit_tests/test_addressing_mode_needs_byte_argument_3_65c02.asm
R jasm/unit_tests/test_addressing_mode_needs_byte_argument_3_65ce02.asm => 
M jasm/unit_tests/test_addressing_mode_needs_integer_argument_1_6502.asm
R jasm/unit_tests/test_addressing_mode_needs_integer_argument_1_65c02.asm => 
R jasm/unit_tests/test_addressing_mode_needs_integer_argument_1_65ce02.asm => 
M jasm/unit_tests/test_addressing_mode_needs_integer_argument_2_65c02.asm
R jasm/unit_tests/test_addressing_mode_needs_integer_argument_2_65ce02.asm => 
M jasm/unit_tests/test_addressing_mode_needs_integer_argument_3_65c02.asm
R jasm/unit_tests/test_addressing_mode_needs_integer_argument_3_65ce02.asm => 
M jasm/unit_tests/test_addressing_mode_needs_integer_argument_4_65c02.asm
R jasm/unit_tests/test_addressing_mode_needs_integer_argument_4_65ce02.asm => 
M jasm/unit_tests/test_addressing_mode_needs_positive_argument_1_6502.asm
R jasm/unit_tests/test_addressing_mode_needs_positive_argument_1_65c02.asm => 
R jasm/unit_tests/test_addressing_mode_needs_positive_argument_1_65ce02.asm => 
M jasm/unit_tests/test_addressing_mode_needs_positive_argument_2_65c02.asm
R jasm/unit_tests/test_addressing_mode_needs_positive_argument_2_65ce02.asm => 
M jasm/unit_tests/test_addressing_mode_needs_positive_argument_3_65c02.asm
M jasm/unit_tests/test_addressing_mode_needs_word_size_argument_1_6502.asm
R jasm/unit_tests/test_addressing_mode_needs_word_size_argument_1_65c02.asm => 
R jasm/unit_tests/test_addressing_mode_needs_word_size_argument_1_65ce02.asm => 
M jasm/unit_tests/test_addressing_mode_needs_word_size_argument_2_6502.asm
R jasm/unit_tests/test_addressing_mode_needs_word_size_argument_2_65c02.asm => 
R jasm/unit_tests/test_addressing_mode_needs_word_size_argument_2_65ce02.asm => 
A => jasm/unit_tests/test_all_instructions_45gs02.asm
M jasm/unit_tests/test_all_instructions_6502.asm
M jasm/unit_tests/test_all_instructions_65c02.asm
M jasm/unit_tests/test_all_instructions_65ce02.asm
M jasm/unit_tests/test_bank_mode_truncates_address_instructions_6502.asm
R jasm/unit_tests/test_bank_mode_truncates_address_instructions_65c02.asm => 
R jasm/unit_tests/test_bank_mode_truncates_address_instructions_65ce02.asm => 
M jasm/unit_tests/test_define_array_follows_references.asm
M jasm/unit_tests/test_define_byte_follows_references.asm
M jasm/unit_tests/test_map_access_missing_key.asm => jasm/unit_tests/test_dict_access_missing_key.asm
M jasm/unit_tests/test_map_clear_on_const_map.asm => jasm/unit_tests/test_dict_clear_on_const_map.asm
M jasm/unit_tests/test_map_clear_removes_keys.asm => jasm/unit_tests/test_dict_clear_removes_keys.asm
M jasm/unit_tests/test_map_construct_arguments.asm => jasm/unit_tests/test_dict_construct_arguments.asm
M jasm/unit_tests/test_map_construct_empty.asm => jasm/unit_tests/test_dict_construct_empty.asm
M jasm/unit_tests/test_map_construct_with_duplicate_keys.asm => jasm/unit_tests/test_dict_construct_with_duplicate_keys.asm
M jasm/unit_tests/test_map_construct_with_missing_assignment.asm => jasm/unit_tests/test_dict_construct_with_missing_assignment.asm
M jasm/unit_tests/test_map_construct_with_unsupported_key_type.asm => jasm/unit_tests/test_dict_construct_with_unsupported_key_type.asm
M jasm/unit_tests/test_map_empty_property.asm => jasm/unit_tests/test_dict_empty_property.asm
M jasm/unit_tests/test_map_erase_removes_key.asm => jasm/unit_tests/test_dict_erase_removes_key.asm
M jasm/unit_tests/test_map_erase_with_missing_key.asm => jasm/unit_tests/test_dict_erase_with_missing_key.asm
M jasm/unit_tests/test_map_erase_with_unsupported_key_type.asm => jasm/unit_tests/test_dict_erase_with_unsupported_key_type.asm
M jasm/unit_tests/test_map_get_with_unsupported_key_type.asm => jasm/unit_tests/test_dict_get_with_unsupported_key_type.asm
M jasm/unit_tests/test_map_get_with_valid_key_types.asm => jasm/unit_tests/test_dict_get_with_valid_key_types.asm
M jasm/unit_tests/test_map_has_checks_existence.asm => jasm/unit_tests/test_dict_has_checks_existence.asm
M jasm/unit_tests/test_map_has_with_unsupported_key_type.asm => jasm/unit_tests/test_dict_has_with_unsupported_key_type.asm
M jasm/unit_tests/test_map_key_types.asm => jasm/unit_tests/test_dict_key_types.asm
M jasm/unit_tests/test_map_length_property.asm => jasm/unit_tests/test_dict_length_property.asm
M jasm/unit_tests/test_map_overwrite_key.asm => jasm/unit_tests/test_dict_overwrite_key.asm
M jasm/unit_tests/test_map_range_for_global_loop_variable.asm => jasm/unit_tests/test_dict_range_for_global_loop_variable.asm
M jasm/unit_tests/test_map_range_for_has_proper_key_reference.asm => jasm/unit_tests/test_dict_range_for_has_proper_key_reference.asm
M jasm/unit_tests/test_map_range_for_local_loop_variable_doesnt_collide_with_outside.asm => jasm/unit_tests/test_dict_range_for_local_loop_variable_doesnt_collide_with_outside.asm
M jasm/unit_tests/test_map_range_for_local_loop_variable_reserved_inside_loop_body.asm => jasm/unit_tests/test_dict_range_for_local_loop_variable_reserved_inside_loop_body.asm
M jasm/unit_tests/test_map_range_for_makes_copy_of_map.asm => jasm/unit_tests/test_dict_range_for_makes_copy_of_map.asm
M jasm/unit_tests/test_map_range_for_requires_iterable_type.asm => jasm/unit_tests/test_dict_range_for_requires_iterable_type.asm
M jasm/unit_tests/test_map_range_for_with_global_variable_collides_with_other.asm => jasm/unit_tests/test_dict_range_for_with_global_variable_collides_with_other.asm
M jasm/unit_tests/test_map_range_for_with_local_loop_variables.asm => jasm/unit_tests/test_dict_range_for_with_local_loop_variables.asm
M jasm/unit_tests/test_map_range_for_z80.asm => jasm/unit_tests/test_dict_range_for_z80.asm
M jasm/unit_tests/test_map_set_new_key.asm => jasm/unit_tests/test_dict_set_new_key.asm
M jasm/unit_tests/test_map_set_on_constant_map.asm => jasm/unit_tests/test_dict_set_on_constant_map.asm
M jasm/unit_tests/test_map_set_with_unsupported_key_type.asm => jasm/unit_tests/test_dict_set_with_unsupported_key_type.asm
M jasm/unit_tests/test_map_with_list_value.asm => jasm/unit_tests/test_dict_with_list_value.asm
M jasm/unit_tests/test_generate_data_in_instruction_1_6502.asm
R jasm/unit_tests/test_generate_data_in_instruction_1_65c02.asm => 
R jasm/unit_tests/test_generate_data_in_instruction_1_65ce02.asm => 
M jasm/unit_tests/test_instruction_data_global_label_6502.asm
R jasm/unit_tests/test_instruction_data_global_label_65c02.asm => 
R jasm/unit_tests/test_instruction_data_global_label_65ce02.asm => 
M jasm/unit_tests/test_instruction_data_label_cant_have_implied_addressing_mode_6502.asm
R jasm/unit_tests/test_instruction_data_label_cant_have_implied_addressing_mode_65c02.asm => 
R jasm/unit_tests/test_instruction_data_label_cant_have_implied_addressing_mode_65ce02.asm => 
M jasm/unit_tests/test_instruction_data_label_for_wrong_argument_type_3_65c02.asm
R jasm/unit_tests/test_instruction_data_label_for_wrong_argument_type_3_65ce02.asm => 
M jasm/unit_tests/test_instruction_data_label_has_lo_hi_properties_6502.asm
R jasm/unit_tests/test_instruction_data_label_has_lo_hi_properties_65c02.asm => 
R jasm/unit_tests/test_instruction_data_label_has_lo_hi_properties_65ce02.asm => 
A => jasm/unit_tests/test_instruction_data_label_offsets_45gs02.asm
M jasm/unit_tests/test_instruction_data_label_offsets_6502.asm
M jasm/unit_tests/test_instruction_data_label_offsets_65c02.asm
M jasm/unit_tests/test_instruction_data_label_offsets_65ce02.asm
A => jasm/unit_tests/test_instruction_data_label_sizes_45gs02.asm
M jasm/unit_tests/test_instruction_data_label_sizes_6502.asm
M jasm/unit_tests/test_instruction_data_label_sizes_65c02.asm
M jasm/unit_tests/test_instruction_data_label_sizes_65ce02.asm
M jasm/unit_tests/test_instruction_data_label_with_export_6502.asm
R jasm/unit_tests/test_instruction_data_label_with_export_65c02.asm => 
R jasm/unit_tests/test_instruction_data_label_with_export_65ce02.asm => 
M jasm/unit_tests/test_instruction_data_label_with_local_export_6502.asm
R jasm/unit_tests/test_instruction_data_label_with_local_export_65c02.asm => 
R jasm/unit_tests/test_instruction_data_label_with_local_export_65ce02.asm => 
M jasm/unit_tests/test_instruction_data_local_label_6502.asm
R jasm/unit_tests/test_instruction_data_local_label_65c02.asm => 
R jasm/unit_tests/test_instruction_data_local_label_65ce02.asm => 
M jasm/unit_tests/test_instruction_ends_at_newline_1_6502.asm
R jasm/unit_tests/test_instruction_ends_at_newline_1_65c02.asm => 
R jasm/unit_tests/test_instruction_ends_at_newline_1_65ce02.asm => 
M jasm/unit_tests/test_instruction_ends_at_newline_2_6502.asm
R jasm/unit_tests/test_instruction_ends_at_newline_2_65c02.asm => 
R jasm/unit_tests/test_instruction_ends_at_newline_2_65ce02.asm => 
M jasm/unit_tests/test_instruction_names_can_be_used_in_local_variables_6502.asm
R jasm/unit_tests/test_instruction_names_can_be_used_in_local_variables_65c02.asm => 
R jasm/unit_tests/test_instruction_names_can_be_used_in_local_variables_65ce02.asm => 
A => jasm/unit_tests/test_instruction_sizes_45gs02.asm
M jasm/unit_tests/test_instructions_must_be_in_code_sections_1_6502.asm
R jasm/unit_tests/test_instructions_must_be_in_code_sections_1_65c02.asm => 
R jasm/unit_tests/test_instructions_must_be_in_code_sections_1_65ce02.asm => 
M jasm/unit_tests/test_instructions_must_be_in_code_sections_2_6502.asm
R jasm/unit_tests/test_instructions_must_be_in_code_sections_2_65c02.asm => 
R jasm/unit_tests/test_instructions_must_be_in_code_sections_2_65ce02.asm => 
M jasm/unit_tests/test_pseudo_instructions_for_branching_6502.asm
R jasm/unit_tests/test_pseudo_instructions_for_branching_65c02.asm => 
M jasm/unit_tests/test_pseudo_instructions_for_branching_65ce02.asm
M jasm/unit_tests/test_pseudo_instructions_for_incrementing_65c02.asm
R jasm/unit_tests/test_pseudo_instructions_for_incrementing_65ce02.asm => 
M jasm/unit_tests/test_pseudo_instructions_in_standard_mode_6502.asm
M jasm/unit_tests/test_pseudo_instructions_in_standard_mode_65c02.asm
M jasm/unit_tests/test_pseudo_instructions_in_standard_mode_65ce02.asm
M jasm/unit_tests/test_pseudo_instructions_use_names_in_standard_mode_6502.asm
R jasm/unit_tests/test_pseudo_instructions_use_names_in_standard_mode_65c02.asm => 
R jasm/unit_tests/test_pseudo_instructions_use_names_in_standard_mode_65ce02.asm => 
M jasm/unit_tests/test_register_names_can_be_used_in_local_names_6502.asm
R jasm/unit_tests/test_register_names_can_be_used_in_local_names_65c02.asm => 
R jasm/unit_tests/test_register_names_can_be_used_in_local_names_65ce02.asm => 
M jasm/unit_tests/test_register_names_cant_be_used_as_global_variables_6502.asm
R jasm/unit_tests/test_register_names_cant_be_used_as_global_variables_65c02.asm => 
R jasm/unit_tests/test_register_names_cant_be_used_as_global_variables_65ce02.asm => 
M jasm/unit_tests/test_subroutine_call_6502.asm
R jasm/unit_tests/test_subroutine_call_65c02.asm => 
R jasm/unit_tests/test_subroutine_call_65ce02.asm => 
M jasm/unit_tests/test_subroutine_call_must_be_in_code_section_6502.asm
R jasm/unit_tests/test_subroutine_call_must_be_in_code_section_65c02.asm => 
R jasm/unit_tests/test_subroutine_call_must_be_in_code_section_65ce02.asm => 
M jasm/unit_tests/test_subroutine_call_negative_argument_6502.asm
R jasm/unit_tests/test_subroutine_call_negative_argument_65c02.asm => 
R jasm/unit_tests/test_subroutine_call_negative_argument_65ce02.asm => 
M jasm/unit_tests/test_subroutine_call_recursive_data_generation_6502.asm
R jasm/unit_tests/test_subroutine_call_recursive_data_generation_65c02.asm => 
R jasm/unit_tests/test_subroutine_call_recursive_data_generation_65ce02.asm => 
M jasm/unit_tests/test_subroutine_call_too_large_argument_6502.asm
R jasm/unit_tests/test_subroutine_call_too_large_argument_65c02.asm => 
R jasm/unit_tests/test_subroutine_call_too_large_argument_65ce02.asm => 
M jasm/unit_tests/test_subroutine_call_with_arguments_6502.asm
R jasm/unit_tests/test_subroutine_call_with_arguments_65c02.asm => 
R jasm/unit_tests/test_subroutine_call_with_arguments_65ce02.asm => 
M jasm/unit_tests/test_subroutine_falls_through_1_6502.asm
R jasm/unit_tests/test_subroutine_falls_through_1_65c02.asm => 
R jasm/unit_tests/test_subroutine_falls_through_1_65ce02.asm => 
M jasm/unit_tests/test_subroutine_falls_through_2_6502.asm
R jasm/unit_tests/test_subroutine_falls_through_2_65c02.asm => 
R jasm/unit_tests/test_subroutine_falls_through_2_65ce02.asm => 
M jasm/unit_tests/test_subroutine_falls_through_3_6502.asm
R jasm/unit_tests/test_subroutine_falls_through_3_65c02.asm => 
R jasm/unit_tests/test_subroutine_falls_through_3_65ce02.asm => 
M jasm/unit_tests/test_subroutine_falls_through_4_6502.asm
R jasm/unit_tests/test_subroutine_falls_through_4_65c02.asm => 
R jasm/unit_tests/test_subroutine_falls_through_4_65ce02.asm => 
M jasm/unit_tests/test_subroutine_falls_through_5_65ce02.asm
M jasm/version.h
M jasm/website/site/docs/index.html
M jasm/website/site/index.html
M sublime/m6502/jAsm.sublime-syntax
M sublime/z80/jAsm.sublime-syntax
M jasm/assemble/assembler_impl/assembler_impl.cpp +12 -12
@@ 391,20 391,20 @@ void Assembler::setup_fundamental_types(
 	}
 	{
 		TokenReadPosition p = _current_pass.types.position();
-		uint32_t num_properties = static_cast<uint32_t>(MapProperties::NumProperties);
+		uint32_t num_properties = static_cast<uint32_t>(DictProperties::NumProperties);
 		TypeDescriptionWithPayload &type = reserve_type(num_properties);
-		type.type = ValueType::MapReference;
-//		type.operators[static_cast<uint32_t>(OperatorType::ArrayAccess)] = &Assembler::operator_map_array_access;
-		type.operators[static_cast<uint32_t>(OperatorType::Period)] = &Assembler::operator_map_period;
+		type.type = ValueType::DictReference;
+//		type.operators[static_cast<uint32_t>(OperatorType::ArrayAccess)] = &Assembler::operator_dict_array_access;
+		type.operators[static_cast<uint32_t>(OperatorType::Period)] = &Assembler::operator_dict_period;
 		type.num_properties = num_properties;
-		type.name_hashes[static_cast<uint32_t>(MapProperties::Get)] = hash_constant(0x5c50af7d3aca106dULL, "get");
-		type.name_hashes[static_cast<uint32_t>(MapProperties::Set)] = hash_constant(0x81dc8d337b550fb3ULL, "set");
-		type.name_hashes[static_cast<uint32_t>(MapProperties::Erase)] = hash_constant(0xa55568a0a6adcd51ULL, "erase");
-		type.name_hashes[static_cast<uint32_t>(MapProperties::Clear)] = hash_constant(0xdb95283bae679a06ULL, "clear");
-		type.name_hashes[static_cast<uint32_t>(MapProperties::Has)] = hash_constant(0x451fa349ff1558cbULL, "has");
-		type.name_hashes[static_cast<uint32_t>(MapProperties::Empty)] = hash_constant(0x5ed3e28128ac2df7ULL, "empty");
-		type.name_hashes[static_cast<uint32_t>(MapProperties::Length)] = hash_constant(0xea9dd03ab3c476a3ULL, "length");
-		_static_map_type = add_type_to_type_map(type, p);
+		type.name_hashes[static_cast<uint32_t>(DictProperties::Get)] = hash_constant(0x5c50af7d3aca106dULL, "get");
+		type.name_hashes[static_cast<uint32_t>(DictProperties::Set)] = hash_constant(0x81dc8d337b550fb3ULL, "set");
+		type.name_hashes[static_cast<uint32_t>(DictProperties::Erase)] = hash_constant(0xa55568a0a6adcd51ULL, "erase");
+		type.name_hashes[static_cast<uint32_t>(DictProperties::Clear)] = hash_constant(0xdb95283bae679a06ULL, "clear");
+		type.name_hashes[static_cast<uint32_t>(DictProperties::Has)] = hash_constant(0x451fa349ff1558cbULL, "has");
+		type.name_hashes[static_cast<uint32_t>(DictProperties::Empty)] = hash_constant(0x5ed3e28128ac2df7ULL, "empty");
+		type.name_hashes[static_cast<uint32_t>(DictProperties::Length)] = hash_constant(0xea9dd03ab3c476a3ULL, "length");
+		_static_dict_type = add_type_to_type_map(type, p);
 	}
 }
 

          
M jasm/assemble/assembler_impl/assembler_impl.h +20 -15
@@ 24,6 24,10 @@ 
 
 namespace jasm
 {
+	namespace mega45gs02
+	{
+		class Processor45gs02;
+	}
 	namespace mos6502
 	{
 		class Processor6502;

          
@@ 65,6 69,7 @@ constexpr uint32_t max_call_depth = 100;
 /// to form the final hash.
 class Assembler
 {
+	friend mega45gs02::Processor45gs02;
 	friend mos6502::Processor6502;
 	friend z80::ProcessorZ80;
 	friend wdc65c02::Processor65c02;

          
@@ 342,9 347,9 @@ private:
 		return referred_value.type == ValueType::ListReference;
 	}
 
-	inline bool is_map(const Value &value) const
+	inline bool is_dict(const Value &value) const
 	{
-		if (value.type == ValueType::MapReference)
+		if (value.type == ValueType::DictReference)
 			return true;
 
 		if (!value.is_value_reference())

          
@@ 353,7 358,7 @@ private:
 		// value reference type must follow the reference and check its type
 		const Value &referred_value = follow_reference(value);
 
-		return referred_value.type == ValueType::MapReference;
+		return referred_value.type == ValueType::DictReference;
 	}
 
 	inline bool is_valid_key(const Value &value)

          
@@ 361,9 366,9 @@ private:
 		return is_integer(value) || is_string(value) || is_boolean(value);
 	}
 
-	/// Convert the value to a map type. This is only possible with integer types
+	/// Convert the value to a dict type. This is only possible with integer types
 	/// and strings.
-	MapKey to_map_key(const Value &value) const;
+	DictKey to_dict_key(const Value &value) const;
 
 	/// Creating a type is a two step rocket.
 	/// 1) Allocate and clear the type space (this call)

          
@@ 427,7 432,7 @@ private:
 	void set_method(Value &result, MethodType method, const Value &object) const;
 	void set_list(Value &result) const;
 	void set_list_element_reference(Value &result, StorageType storage_type, const Value &list, int32_t index) const;
-	void set_map(Value &result) const;
+	void set_dict(Value &result) const;
 	void set_byte_offset(Value &result, int32_t offset_base, int32_t offset);
 	void set_word_offset(Value &result, int32_t offset_base, int32_t offset);
 	/// @}

          
@@ 603,7 608,7 @@ private:
 	void operator_list_period(bool generate, ValueVector &expression_values, const ExpressionComponent components[], uint32_t operator_index, Value &result, Value &arg1, uint32_t next_index);
 	void operator_list_add(bool generate, ValueVector &expression_values, const ExpressionComponent components[], uint32_t operator_index, Value &result, Value &arg1, const Value &arg2);
 	void operator_list_assignment_add(bool generate, ValueVector &expression_values, const ExpressionComponent components[], uint32_t operator_index, Value &result, Value &ref, Value &arg1, const Value &arg2);
-	void operator_map_period(bool generate, ValueVector &expression_values, const ExpressionComponent components[], uint32_t operator_index, Value &result, Value &arg1, uint32_t next_index);
+	void operator_dict_period(bool generate, ValueVector &expression_values, const ExpressionComponent components[], uint32_t operator_index, Value &result, Value &arg1, uint32_t next_index);
 	void operator_word_offset_period(bool generate, ValueVector &expression_values, const ExpressionComponent components[], uint32_t operator_index, Value &result, Value &arg1, uint32_t next_index);
 	
 	/// Returns a member function pointer that contains a union of member function pointers.

          
@@ 647,7 652,7 @@ private:
 	void function_uppercase(bool generate, ValueVector &expression_values, const ExpressionComponent components[], uint32_t op, uint32_t arg1);
 	void function_lowercase(bool generate, ValueVector &expression_values, const ExpressionComponent components[], uint32_t op, uint32_t arg1);
 	void function_list(bool generate, ValueVector &expression_values, const ExpressionComponent components[], uint32_t op);
-	void function_map(bool generate, ValueVector &expression_values, const ExpressionComponent components[], uint32_t op);
+	void function_dict(bool generate, ValueVector &expression_values, const ExpressionComponent components[], uint32_t op);
 	void function_static_assert(bool generate, ValueVector &expression_values, const ExpressionComponent components[], uint32_t op, uint32_t arg1, uint32_t arg2);
 	void function_format(bool generate, ValueVector &expression_values, const ExpressionComponent components[], uint32_t op, uint32_t arg1);
 	void function_print(bool generate, ValueVector &expression_values, const ExpressionComponent components[], uint32_t op, uint32_t arg1);

          
@@ 717,11 722,11 @@ private:
 	void method_list_erase(bool generate, Value &object, ValueVector &expression_values, uint32_t op, const ExpressionComponent components[], uint32_t arg1);
 	void method_list_keep(bool generate, Value &object, ValueVector &expression_values, uint32_t op, const ExpressionComponent components[], uint32_t arg1);
 	void method_list_clear(bool generate, Value &object, ValueVector &expression_values, const ExpressionComponent components[], uint32_t op);
-	void method_map_get(bool generate, Value &object, ValueVector &expression_values, const ExpressionComponent components[], uint32_t op, uint32_t arg1);
-	void method_map_set(bool generate, Value &object, ValueVector &expression_values, const ExpressionComponent components[], uint32_t op, uint32_t arg1, uint32_t arg2);
-	void method_map_erase(bool generate, Value &object, ValueVector &expression_values, const ExpressionComponent components[], uint32_t op, uint32_t arg1);
-	void method_map_clear(bool generate, Value &object, ValueVector &expression_values, const ExpressionComponent components[], uint32_t op);
-	void method_map_has(bool generate, Value &object, ValueVector &expression_values, const ExpressionComponent components[], uint32_t op, uint32_t arg1);
+	void method_dict_get(bool generate, Value &object, ValueVector &expression_values, const ExpressionComponent components[], uint32_t op, uint32_t arg1);
+	void method_dict_set(bool generate, Value &object, ValueVector &expression_values, const ExpressionComponent components[], uint32_t op, uint32_t arg1, uint32_t arg2);
+	void method_dict_erase(bool generate, Value &object, ValueVector &expression_values, const ExpressionComponent components[], uint32_t op, uint32_t arg1);
+	void method_dict_clear(bool generate, Value &object, ValueVector &expression_values, const ExpressionComponent components[], uint32_t op);
+	void method_dict_has(bool generate, Value &object, ValueVector &expression_values, const ExpressionComponent components[], uint32_t op, uint32_t arg1);
 
 	/// @}
 

          
@@ 947,7 952,7 @@ private:
 
 	/// Parse the loop body over a collection loop.
 	const SyntaxToken *parse_range_list_loop(bool generate, const SyntaxToken *t, const Value &loop_collection, const RangedForLoopToken &loop_token, bool &early_return);
-	const SyntaxToken *parse_range_map_loop(bool generate, const SyntaxToken *t, const Value &loop_collection, const RangedForLoopToken &loop_token, bool &early_return);
+	const SyntaxToken *parse_range_dict_loop(bool generate, const SyntaxToken *t, const Value &loop_collection, const RangedForLoopToken &loop_token, bool &early_return);
 
 	const SyntaxToken *parse_if(bool generate, const SyntaxToken *t, bool &early_return);
 	const SyntaxToken *parse_section(bool generate, const SyntaxToken *t);

          
@@ 1185,7 1190,7 @@ private:
 	uint64_t _static_method_closure_type;
 	uint64_t _static_list_type;
 	uint64_t _static_list_element_type;
-	uint64_t _static_map_type;
+	uint64_t _static_dict_type;
 
 	// section information
 

          
M jasm/assemble/assembler_impl/functions_impl.cpp +19 -19
@@ 55,7 55,7 @@ Function Assembler::function_pointer(Fun
 		{ &Assembler::function_uppercase },
 		{ &Assembler::function_lowercase },
 		{ &Assembler::function_list },
-		{ &Assembler::function_map },
+		{ &Assembler::function_dict },
 		{ &Assembler::function_static_assert },
 		{ &Assembler::function_format },
 		{ &Assembler::function_print },

          
@@ 854,13 854,13 @@ void Assembler::function_list(bool /*gen
 	}
 }
 
-MapKey Assembler::to_map_key(const Value &value) const
+DictKey Assembler::to_dict_key(const Value &value) const
 {
 	const Value &v = follow_reference_or_value(value);
 	switch(v.type)
 	{
 		case ValueType::BoolValue:
-			return MapKey(dereference_boolean(v));
+			return DictKey(dereference_boolean(v));
 
 		case ValueType::IntegerValue:
 		case ValueType::SubroutineValue:

          
@@ 869,10 869,10 @@ MapKey Assembler::to_map_key(const Value
 		case ValueType::LongOffset:
 		case ValueType::StructOffset:
 		case ValueType::ArrayOffset:
-			return MapKey(dereference_integer(v));
+			return DictKey(dereference_integer(v));
 
 		case ValueType::StringValue:
-			return MapKey(v.string_hash);
+			return DictKey(v.string_hash);
 			
 		case ValueType::StringReference:
 			return v.object_reference.deref<StringDynamicObject>().hash(0);

          
@@ 891,22 891,22 @@ MapKey Assembler::to_map_key(const Value
 		case ValueType::ObjectReference:
 		case ValueType::ListReference:
 		case ValueType::ListElementReference:
-		case ValueType::MapReference:
+		case ValueType::DictReference:
 		case ValueType::MethodClosure:
 		case ValueType::NumTypes:
 			assert(false);
-			return MapKey(static_cast<int>(0));
+			return DictKey(static_cast<int>(0));
 	}
 	UNREACHABLE_CODE(throw Exception("internal error"));
 }
 
-void Assembler::function_map(bool generate, ValueVector &expression_values, const ExpressionComponent components[], uint32_t op)
+void Assembler::function_dict(bool generate, ValueVector &expression_values, const ExpressionComponent components[], uint32_t op)
 {
 	Value &result = expression_values[op];
-	// create a new map and fetch a reference to the map contents
-	set_map(result);
+	// create a new dict and fetch a reference to the dict contents
+	set_dict(result);
 	result.storage_type = StorageType::Variable; // a temporary value is writable until stored in constant
-	auto &contents = *result.object_reference.deref<MapDynamicObject>().value;
+	auto &contents = *result.object_reference.deref<DictDynamicObject>().value;
 
 	// first argument is the function itself so that must be skipped to get to the next
 	uint32_t arg_index = components[components[op].first_child].next_sibling;

          
@@ 918,7 918,7 @@ void Assembler::function_map(bool genera
 			std::stringstream ss;
 			ss << "Expected assignment operator.";
 			// fatal error since this is really a parse error and won't be resolved
-			report_fatal_error(equal_op.source_location, AssemblyErrorCodes::MissingKeyAssignmentInMapArgument, ss.str());
+			report_fatal_error(equal_op.source_location, AssemblyErrorCodes::MissingKeyAssignmentInDictArgument, ss.str());
 		}
 
 		// get index to key and value root in expression

          
@@ 931,14 931,14 @@ void Assembler::function_map(bool genera
 
 		const Value &key_value = follow_reference_or_value(expression_values[key_index]);
 		if (is_valid_key(key_value)) {
-			const MapKey &key = to_map_key(key_value);
+			const DictKey &key = to_dict_key(key_value);
 			const Value &value = follow_reference_or_value(expression_values[value_index]);
 
 			if (contents.find(key) != contents.end()) {
 				if (generate) {
 					std::stringstream ss;
-					ss << "Duplicate map key " << to_string(_strings, key_value) << " in map function arguments.";
-					report_error(components[leftmost_node_in_expression(components, key_index)].source_location, AssemblyErrorCodes::DuplicateMapKeys, ss.str());
+					ss << "Duplicate dict key " << to_string(_strings, key_value) << " in dict function arguments.";
+					report_error(components[leftmost_node_in_expression(components, key_index)].source_location, AssemblyErrorCodes::DuplicateDictKeys, ss.str());
 				}
 			}
 

          
@@ 947,8 947,8 @@ void Assembler::function_map(bool genera
 		} else {
 			if (generate) {
 				std::stringstream ss;
-				ss << "Unsupported map key type '" << to_string(key_value.type) << "'.";
-				report_error(components[leftmost_node_in_expression(components, key_index)].source_location, AssemblyErrorCodes::UnsupportedMapKeyType, ss.str());
+				ss << "Unsupported dict key type '" << to_string(key_value.type) << "'.";
+				report_error(components[leftmost_node_in_expression(components, key_index)].source_location, AssemblyErrorCodes::UnsupportedDictKeyType, ss.str());
 			}
 		}
 

          
@@ 1265,9 1265,9 @@ bool Assembler::argument_to_string(bool 
 			return argument_to_string(generate, format_location, format, element_value, arg_string, depth); // no deeper depth because it just follows a pointer, not into another object
 		}
 
-		case ValueType::MapReference:
+		case ValueType::DictReference:
 			// should recurse here
-			arg_string << "[map]";
+			arg_string << "[dict]";
 			break;
 
 		case ValueType::MethodClosure:

          
M jasm/assemble/assembler_impl/methods_impl.cpp +47 -47
@@ 17,11 17,11 @@ Method Assembler::method_pointer(MethodT
 		{ &Assembler::method_list_erase},
 		{ &Assembler::method_list_keep},
 		{ &Assembler::method_list_clear},
-		{ &Assembler::method_map_get},
-		{ &Assembler::method_map_set},
-		{ &Assembler::method_map_erase},
-		{ &Assembler::method_map_clear},
-		{ &Assembler::method_map_has},
+		{ &Assembler::method_dict_get},
+		{ &Assembler::method_dict_set},
+		{ &Assembler::method_dict_erase},
+		{ &Assembler::method_dict_clear},
+		{ &Assembler::method_dict_has},
 	};
 	static_assert(sizeof(pointers) / sizeof(pointers[0]) == static_cast<int>(MethodType::NumTypes), "Number of functions doesn't match number of function pointers");
 	assert(type < MethodType::NumTypes);

          
@@ 229,31 229,31 @@ void Assembler::method_list_clear(bool /
 	result.copy_value(object);
 }
 
-void Assembler::method_map_get(bool generate, Value &object, ValueVector &expression_values, const ExpressionComponent components[], uint32_t op, uint32_t arg1)
+void Assembler::method_dict_get(bool generate, Value &object, ValueVector &expression_values, const ExpressionComponent components[], uint32_t op, uint32_t arg1)
 {
 	Value &result = expression_values[op];
 
-	MapDynamicObject &source_map = object.object_reference.deref<MapDynamicObject>();
+	DictDynamicObject &source_dict = object.object_reference.deref<DictDynamicObject>();
 	Value &arg1_value = follow_reference_or_value(expression_values[arg1]);
 
 	if (!is_valid_key(arg1_value)) {
 		if (generate) {
 			std::stringstream ss;
-			ss << "Unsupported map key type " << to_string(arg1_value.type) << ".";
-			report_error(components[leftmost_node_in_expression(components, arg1)].source_location, AssemblyErrorCodes::UnsupportedMapKeyType, ss.str());
+			ss << "Unsupported dict key type " << to_string(arg1_value.type) << ".";
+			report_error(components[leftmost_node_in_expression(components, arg1)].source_location, AssemblyErrorCodes::UnsupportedDictKeyType, ss.str());
 		}
 		set_unknown(result);
 		return;
 	}
 
 	// find the element
-	MapKey key = to_map_key(arg1_value);
-	auto it = source_map.value->find(key);
-	if (it == source_map.value->end()) {
+	DictKey key = to_dict_key(arg1_value);
+	auto it = source_dict.value->find(key);
+	if (it == source_dict.value->end()) {
 		if (generate) {
 			std::stringstream ss;
-			ss << "Access to missing key " << to_string(_strings, arg1_value) << " in map.";
-			report_error(components[leftmost_node_in_expression(components, arg1)].source_location, AssemblyErrorCodes::AccessToMissingMapKey, ss.str());
+			ss << "Access to missing key " << to_string(_strings, arg1_value) << " in dict.";
+			report_error(components[leftmost_node_in_expression(components, arg1)].source_location, AssemblyErrorCodes::AccessToMissingDictKey, ss.str());
 		}
 		set_unknown(result);
 		return;

          
@@ 262,7 262,7 @@ void Assembler::method_map_get(bool gene
 	result.copy_value(it->second.second);
 }
 
-void Assembler::method_map_set(bool generate, Value &object, ValueVector &expression_values, const ExpressionComponent components[], uint32_t op, uint32_t arg1, uint32_t arg2)
+void Assembler::method_dict_set(bool generate, Value &object, ValueVector &expression_values, const ExpressionComponent components[], uint32_t op, uint32_t arg1, uint32_t arg2)
 {
 	Value &result = expression_values[op];
 	set_none(result); // no return value

          
@@ 273,23 273,23 @@ void Assembler::method_map_set(bool gene
 	if (!is_valid_key(arg1_value)) {
 		if (generate) {
 			std::stringstream ss;
-			ss << "Unsupported map key type " << to_string(arg1_value.type) << ".";
-			report_error(components[leftmost_node_in_expression(components, arg1)].source_location, AssemblyErrorCodes::UnsupportedMapKeyType, ss.str());
+			ss << "Unsupported dict key type " << to_string(arg1_value.type) << ".";
+			report_error(components[leftmost_node_in_expression(components, arg1)].source_location, AssemblyErrorCodes::UnsupportedDictKeyType, ss.str());
 		}
 		return;
 	}
 
-	MapDynamicObject &target_map = object.object_reference.deref<MapDynamicObject>();
-	target_map.prepare_for_write();
-	auto &map_contents = *target_map.value;
+	DictDynamicObject &target_dict = object.object_reference.deref<DictDynamicObject>();
+	target_dict.prepare_for_write();
+	auto &dict_contents = *target_dict.value;
 
-	MapKey key = to_map_key(arg1_value);
-	auto &pair = map_contents[key];
+	DictKey key = to_dict_key(arg1_value);
+	auto &pair = dict_contents[key];
 	pair.first.copy_value(arg1_value);
 	pair.second.copy_value(arg2_value);
 }
 
-void Assembler::method_map_erase(bool generate, Value &object, ValueVector &expression_values, const ExpressionComponent components[], uint32_t op, uint32_t arg1)
+void Assembler::method_dict_erase(bool generate, Value &object, ValueVector &expression_values, const ExpressionComponent components[], uint32_t op, uint32_t arg1)
 {
 	Value &result = expression_values[op];
 	set_none(result); // no return value

          
@@ 299,42 299,42 @@ void Assembler::method_map_erase(bool ge
 	if (!is_valid_key(arg1_value)) {
 		if (generate) {
 			std::stringstream ss;
-			ss << "Unsupported map key type " << to_string(arg1_value.type) << ".";
-			report_error(components[leftmost_node_in_expression(components, arg1)].source_location, AssemblyErrorCodes::UnsupportedMapKeyType, ss.str());
+			ss << "Unsupported dict key type " << to_string(arg1_value.type) << ".";
+			report_error(components[leftmost_node_in_expression(components, arg1)].source_location, AssemblyErrorCodes::UnsupportedDictKeyType, ss.str());
 		}
 		return;
 	}
 
-	MapDynamicObject &target_map = object.object_reference.deref<MapDynamicObject>();
-	target_map.prepare_for_write();
-	auto &map_contents = *target_map.value;
+	DictDynamicObject &target_dict = object.object_reference.deref<DictDynamicObject>();
+	target_dict.prepare_for_write();
+	auto &dict_contents = *target_dict.value;
 
-	MapKey key = to_map_key(arg1_value);
-	auto it = map_contents.find(key);
-	if (it == map_contents.end()) {
+	DictKey key = to_dict_key(arg1_value);
+	auto it = dict_contents.find(key);
+	if (it == dict_contents.end()) {
 		if (generate) {
 			std::stringstream ss;
-			ss << "Access to missing map key " << to_string(_strings, arg1_value) << ".";
-			report_error(components[leftmost_node_in_expression(components, arg1)].source_location, AssemblyErrorCodes::AccessToMissingMapKey, ss.str());
+			ss << "Access to missing dict key " << to_string(_strings, arg1_value) << ".";
+			report_error(components[leftmost_node_in_expression(components, arg1)].source_location, AssemblyErrorCodes::AccessToMissingDictKey, ss.str());
 		}
 		return;
 	}
 
-	map_contents.erase(it);
+	dict_contents.erase(it);
 }
 
-void Assembler::method_map_clear(bool /*generate*/, Value &object, ValueVector &expression_values, const ExpressionComponent /*components*/[], uint32_t op)
+void Assembler::method_dict_clear(bool /*generate*/, Value &object, ValueVector &expression_values, const ExpressionComponent /*components*/[], uint32_t op)
 {
 	Value &result = expression_values[op];
 	set_none(result); // no return value
 
-	MapDynamicObject &target_map = object.object_reference.deref<MapDynamicObject>();
-	target_map.prepare_for_write();
-	auto &map_contents = *target_map.value;
-	map_contents.clear();
+	DictDynamicObject &target_dict = object.object_reference.deref<DictDynamicObject>();
+	target_dict.prepare_for_write();
+	auto &dict_contents = *target_dict.value;
+	dict_contents.clear();
 }
 
-void Assembler::method_map_has(bool generate, Value &object, ValueVector &expression_values, const ExpressionComponent components[], uint32_t op, uint32_t arg1)
+void Assembler::method_dict_has(bool generate, Value &object, ValueVector &expression_values, const ExpressionComponent components[], uint32_t op, uint32_t arg1)
 {
 	Value &result = expression_values[op];
 

          
@@ 343,19 343,19 @@ void Assembler::method_map_has(bool gene
 	if (!is_valid_key(arg1_value)) {
 		if (generate) {
 			std::stringstream ss;
-			ss << "Unsupported map key type " << to_string(arg1_value.type) << ".";
-			report_error(components[leftmost_node_in_expression(components, arg1)].source_location, AssemblyErrorCodes::UnsupportedMapKeyType, ss.str());
+			ss << "Unsupported dict key type " << to_string(arg1_value.type) << ".";
+			report_error(components[leftmost_node_in_expression(components, arg1)].source_location, AssemblyErrorCodes::UnsupportedDictKeyType, ss.str());
 		}
 		set_unknown(result);
 		return;
 	}
 
-	const MapDynamicObject &target_map = object.object_reference.deref<MapDynamicObject>();
-	const auto &map_contents = *target_map.value;
+	const DictDynamicObject &target_dict = object.object_reference.deref<DictDynamicObject>();
+	const auto &dict_contents = *target_dict.value;
 
-	MapKey key = to_map_key(arg1_value);
-	auto it = map_contents.find(key);
-	set_boolean(result, it != map_contents.end());
+	DictKey key = to_dict_key(arg1_value);
+	auto it = dict_contents.find(key);
+	set_boolean(result, it != dict_contents.end());
 }
 
 } // namespace jasm

          
M jasm/assemble/assembler_impl/operators_impl.cpp +14 -14
@@ 81,7 81,7 @@ bool Assembler::verify_comparable_argume
 	case ValueType::EnumReference:
 	case ValueType::ObjectReference:
 	case ValueType::ListReference:
-	case ValueType::MapReference:
+	case ValueType::DictReference:
 	case ValueType::StructTypename:
 		comparable = left_type == right_type;
 		break;

          
@@ 1585,41 1585,41 @@ void Assembler::operator_list_period(boo
 	}
 }
 
-void Assembler::operator_map_period(bool generate, ValueVector &/*expression_values*/, const ExpressionComponent components[], uint32_t /*operator_index*/, Value &result, Value &arg1, uint32_t next_index)
+void Assembler::operator_dict_period(bool generate, ValueVector &/*expression_values*/, const ExpressionComponent components[], uint32_t /*operator_index*/, Value &result, Value &arg1, uint32_t next_index)
 {
 	uint32_t key_index;
 	if (!get_operator_period_property_index(generate, components, result, arg1, next_index, key_index))
 		return;
 
 	// create method closure result which contains the value and method to call
-	switch(static_cast<MapProperties>(key_index))
+	switch(static_cast<DictProperties>(key_index))
 	{
-	case MapProperties::Get:
-	case MapProperties::Set:
-	case MapProperties::Erase:
-	case MapProperties::Clear:
-	case MapProperties::Has:
+	case DictProperties::Get:
+	case DictProperties::Set:
+	case DictProperties::Erase:
+	case DictProperties::Clear:
+	case DictProperties::Has:
 		{
-			MethodType method = static_cast<MethodType>(static_cast<uint32_t>(MethodType::MapStart) + key_index);
+			MethodType method = static_cast<MethodType>(static_cast<uint32_t>(MethodType::DictStart) + key_index);
 			set_method(result, method, arg1);
 		}
 		break;
 		
-	case MapProperties::Empty:
+	case DictProperties::Empty:
 		{
-			bool empty = arg1.object_reference.deref<MapDynamicObject>().value->empty();
+			bool empty = arg1.object_reference.deref<DictDynamicObject>().value->empty();
 			set_boolean(result, empty);
 		}
 		break;
 		
-	case MapProperties::Length:
+	case DictProperties::Length:
 		{
-			size_t length = arg1.object_reference.deref<MapDynamicObject>().value->size();
+			size_t length = arg1.object_reference.deref<DictDynamicObject>().value->size();
 			set_integer(result, static_cast<int32_t>(length));
 		}
 		break;
 		
-	case MapProperties::NumProperties:
+	case DictProperties::NumProperties:
 		assert(false);
 		break;
 	}

          
M jasm/assemble/assembler_impl/symbols_impl.cpp +4 -4
@@ 161,15 161,15 @@ void Assembler::set_list(Value &result) 
 	result.object_reference = new ListDynamicObject();
 }
 
-void Assembler::set_map(Value &result) const
+void Assembler::set_dict(Value &result) const
 {
 	result.set_found_in_current_pass(false);
 	result.union_space1 = 0;
 	result.union_space2 = 0;
 
-	result.type = ValueType::MapReference;
-	result.type_hash = _static_map_type;
-	result.object_reference = new MapDynamicObject();
+	result.type = ValueType::DictReference;
+	result.type_hash = _static_dict_type;
+	result.object_reference = new DictDynamicObject();
 }
 
 void Assembler::set_byte_offset(Value &result, int32_t offset_base, int32_t offset)

          
M jasm/assemble/assembler_impl/syntax_impl.cpp +7 -7
@@ 1219,9 1219,9 @@ const SyntaxToken *Assembler::parse_rang
 	return t;
 }
 
-const SyntaxToken *Assembler::parse_range_map_loop(bool generate, const SyntaxToken *t, const Value &loop_collection, const RangedForLoopToken &loop_token, bool &early_return)
+const SyntaxToken *Assembler::parse_range_dict_loop(bool generate, const SyntaxToken *t, const Value &loop_collection, const RangedForLoopToken &loop_token, bool &early_return)
 {
-	assert(loop_collection.type == ValueType::MapReference);
+	assert(loop_collection.type == ValueType::DictReference);
 
 	// store loop position (the read position is already ahead of the for token)
 	const SyntaxToken *first_token = t;

          
@@ 1237,10 1237,10 @@ const SyntaxToken *Assembler::parse_rang
 	Value &loop_value = _current_pass.values.back();
 	size_t new_variable_index = _current_pass.values.size() - 1;
 
-	// make a copy of the loop vector to avoid all kinds of iteration problems since the map can be
+	// make a copy of the loop vector to avoid all kinds of iteration problems since the dict can be
 	// modified while iterating
 
-	MapDynamicObject::MapType collection_copy = *loop_collection.object_reference.deref<MapDynamicObject>().value;
+	DictDynamicObject::DictType collection_copy = *loop_collection.object_reference.deref<DictDynamicObject>().value;
 
 	int32_t loop_counter = 0;
 	for(const auto &pair : collection_copy) {

          
@@ 1306,9 1306,9 @@ const SyntaxToken *Assembler::parse_rang
 	const Value &loop_collection_value = follow_reference_or_value(loop_collection_ref);
 	t = consume_next_token();
 
-	if (loop_token.is_map_range) {
-		if (is_map(loop_collection_value)) {
-			t = parse_range_map_loop(generate, t, loop_collection_value, loop_token, early_return);
+	if (loop_token.is_dict_range) {
+		if (is_dict(loop_collection_value)) {
+			t = parse_range_dict_loop(generate, t, loop_collection_value, loop_token, early_return);
 		} else {
 			if (generate) {
 				std::stringstream ss;

          
M jasm/assemble/functions.cpp +2 -2
@@ 50,7 50,7 @@ const FunctionDesc &function_info(Functi
 		{not_lazy, variable_args, 1}, // uppercase
 		{not_lazy, variable_args, 1}, // lowercase
 		{not_lazy, variable_args, 0}, // list
-		{is_lazy, variable_args, 0}, // map (lazy because it has special handling for key=value arguments)
+		{is_lazy, variable_args, 0}, // dict (lazy because it has special handling for key=value arguments)
 		{not_lazy, fixed_args, 2}, // static_assert
 		{not_lazy, variable_args, 1}, // format
 		{not_lazy, variable_args, 1}, // print

          
@@ 104,7 104,7 @@ std::string_view to_string(FunctionType 
 		std::string_view("uppercase"),
 		std::string_view("lowercase"),
 		std::string_view("list"),
-		std::string_view("map"),
+		std::string_view("dict"),
 		std::string_view("static_assert"),
 		std::string_view("format"),
 		std::string_view("print"),

          
M jasm/assemble/functions.h +1 -1
@@ 45,7 45,7 @@ enum class FunctionType : uint8_t
 	UpperCase,
 	LowerCase,
 	List,
-	Map,
+	Dict,
 	StaticAssert,
 	Format,
 	Print,

          
M jasm/assemble/methods.cpp +5 -5
@@ 22,11 22,11 @@ const MethodDesc &method_info(MethodType
 		{not_lazy, variable_args, mutating, 1}, // list erase
 		{not_lazy, variable_args, mutating, 1}, // list keep
 		{not_lazy, fixed_args, mutating, 0}, // list clear
-		{not_lazy, fixed_args, not_mutating, 1}, // map get
-		{not_lazy, fixed_args, mutating, 2}, // map set
-		{not_lazy, fixed_args, mutating, 1}, // map erase
-		{not_lazy, fixed_args, mutating, 0}, // map clear
-		{not_lazy, fixed_args, not_mutating, 1}, // map has
+		{not_lazy, fixed_args, not_mutating, 1}, // dict get
+		{not_lazy, fixed_args, mutating, 2}, // dict set
+		{not_lazy, fixed_args, mutating, 1}, // dict erase
+		{not_lazy, fixed_args, mutating, 0}, // dict clear
+		{not_lazy, fixed_args, not_mutating, 1}, // dict has
 	};
 	static_assert(sizeof(desc) / sizeof(desc[0]) == static_cast<int>(MethodType::NumTypes), "Number of methods doesn't match number of decl structs");
 

          
M jasm/assemble/methods.h +7 -7
@@ 33,7 33,7 @@ enum class ListProperties : uint8_t
 	NumProperties
 };
 
-enum class MapProperties : uint8_t
+enum class DictProperties : uint8_t
 {
 	// methods first because the sum of this index and the method start enum in MethodType results in an index into a method array
 	Get,

          
@@ 69,12 69,12 @@ enum class MethodType : uint8_t
 	ListKeep,
 	ListClear,
 
-	MapGet,
-	MapStart = MapGet,
-	MapSet,
-	MapErase,
-	MapClear,
-	MapHas,
+	DictGet,
+	DictStart = DictGet,
+	DictSet,
+	DictErase,
+	DictClear,
+	DictHas,
 
 	NumTypes,
 };

          
M jasm/assemble/value.cpp +17 -17
@@ 62,8 62,8 @@ std::string_view to_string(ValueType typ
 		return std::string_view("list");
 	case ValueType::ListElementReference:
 		return std::string_view("list element reference");
-	case ValueType::MapReference:
-		return std::string_view("map");
+	case ValueType::DictReference:
+		return std::string_view("dict");
 	case ValueType::MethodClosure:
 		return std::string_view("method closure");
 	case ValueType::NumTypes:

          
@@ 101,7 101,7 @@ std::string to_string(const StringReposi
 	case ValueType::ObjectReference:
 	case ValueType::ListReference:
 	case ValueType::ListElementReference:
-	case ValueType::MapReference:
+	case ValueType::DictReference:
 	case ValueType::MethodClosure:
 	case ValueType::NumTypes:
 		return "";

          
@@ 269,23 269,23 @@ void ListDynamicObject::prepare_for_writ
 	}
 }
 
-MapDynamicObject::MapDynamicObject()
+DictDynamicObject::DictDynamicObject()
 	: DynamicObject()
-	, value(std::make_shared<MapType>())
+	, value(std::make_shared<DictType>())
 {
 }
 
-bool MapDynamicObject::equal_to(const DynamicObject &other) const
+bool DictDynamicObject::equal_to(const DynamicObject &other) const
 {
-	const MapDynamicObject *other_map = dynamic_cast<const MapDynamicObject *>(&other);
-	assert(other_map != nullptr);
+	const DictDynamicObject *other_dict = dynamic_cast<const DictDynamicObject *>(&other);
+	assert(other_dict != nullptr);
 
-	if (value->size() != other_map->value->size()) {
+	if (value->size() != other_dict->value->size()) {
 		return false;
 	}
-	const MapType &a = *value;
-	const MapType &b = *other_map->value;
-	// it should be enough to run through one map and verify that all keys match same values
+	const DictType &a = *value;
+	const DictType &b = *other_dict->value;
+	// it should be enough to run through one dict and verify that all keys match same values
 	for(const auto &pair : a) {
 		auto it = b.find(pair.first);
 		if (it == b.end()) {

          
@@ 300,7 300,7 @@ bool MapDynamicObject::equal_to(const Dy
 	return true;
 }
 
-uint64_t MapDynamicObject::hash(uint64_t seed) const
+uint64_t DictDynamicObject::hash(uint64_t seed) const
 {
 	// this is more tricky to hash since the order matters
 	std::vector<SortKey> sorted_vector;

          
@@ 321,9 321,9 @@ uint64_t MapDynamicObject::hash(uint64_t
 	return seed;
 }
 
-DynamicObject *MapDynamicObject::copy()
+DynamicObject *DictDynamicObject::copy()
 {
-	std::unique_ptr<MapDynamicObject> new_copy = std::make_unique<MapDynamicObject>();
+	std::unique_ptr<DictDynamicObject> new_copy = std::make_unique<DictDynamicObject>();
 
 	// copy pointer to vector to support copy-on-write semantics
 	new_copy->value = value;

          
@@ 331,12 331,12 @@ DynamicObject *MapDynamicObject::copy()
 	return new_copy.release();
 }
 
-void MapDynamicObject::prepare_for_write()
+void DictDynamicObject::prepare_for_write()
 {
 	// Optimization to avoid copying a list that only has one reference.
 	// Not ok in multiple threads but assembly is a single threaded problem.
 	if (value.use_count() > 1) {
-		value = std::make_shared<MapType>(*value);
+		value = std::make_shared<DictType>(*value);
 	}
 }
 

          
M jasm/assemble/value.h +26 -26
@@ 62,7 62,7 @@ enum class ValueType : uint8_t
 	ObjectReference, ///< Pointer to an object instance
 	ListReference, ///< Pointer to an array
 	ListElementReference, ///< Pointer to a specific array element
-	MapReference, ///< Pointer to a map structure
+	DictReference, ///< Pointer to a dict structure
 	MethodClosure, ///< Closure for method calls. This contains both a value and a method index.
 
 	NumTypes,

          
@@ 206,7 206,7 @@ public:
 	virtual uint64_t hash(uint64_t seed) const = 0;
 
 	/// Create a new object that is a copy of this or return a copy of the this pointer.
-	/// This allows for both copy by value and reference. Lists and maps use value since
+	/// This allows for both copy by value and reference. Lists and dicts use value since
 	/// they have another pointer indirection to be able to refer to and change the contents
 	/// from list and element references.
 	virtual DynamicObject *copy();

          
@@ 288,7 288,7 @@ public:
 	}
 
 	/// Copy the reference and not by value, regardless of type.
-	/// This is used when creating references to list or map items
+	/// This is used when creating references to list or dict items
 	/// to allow modification through the reference object.
 	void copy_reference(const DynamicObjectReference &other) {
 		if (&other != this) {

          
@@ 465,17 465,17 @@ public:
 };
 */
 
-class MapKey;
+class DictKey;
 
-struct MapKeyHash
+struct DictKeyHash
 {
-	inline uint64_t operator()(const MapKey& key) const;
+	inline uint64_t operator()(const DictKey& key) const;
 };
 
-/// This type contains the map key information.
+/// This type contains the dict key information.
 /// It is a simplified value which only contains
 /// integer and string information.
-class MapKey
+class DictKey
 {
 public:
 	enum class Type : uint32_t

          
@@ 485,26 485,26 @@ public:
 		String,
 	};
 
-	MapKey() : _type(Type::Integer), _integer(0), _string_hash(0)
+	DictKey() : _type(Type::Integer), _integer(0), _string_hash(0)
 	{
 	}
 
-	MapKey(bool b) : _type(Type::Bool), _integer(b ? 1 : 0), _string_hash(0)
+	DictKey(bool b) : _type(Type::Bool), _integer(b ? 1 : 0), _string_hash(0)
 	{
 	}
 
-	MapKey(int32_t i) : _type(Type::Integer), _integer(i), _string_hash(0)
+	DictKey(int32_t i) : _type(Type::Integer), _integer(i), _string_hash(0)
 	{
 	}
 
-	MapKey(uint64_t s) : _type(Type::String), _integer(0), _string_hash(s)
+	DictKey(uint64_t s) : _type(Type::String), _integer(0), _string_hash(s)
 	{
 	}
 
-	MapKey(const MapKey &other) = default;
-	MapKey &operator=(const MapKey &other) = default;
+	DictKey(const DictKey &other) = default;
+	DictKey &operator=(const DictKey &other) = default;
 
-	friend bool operator==(const MapKey &mk1, const MapKey &mk2)
+	friend bool operator==(const DictKey &mk1, const DictKey &mk2)
 	{
 		return
 			mk1._type == mk2._type &&

          
@@ 512,7 512,7 @@ public:
 			mk1._string_hash == mk2._string_hash;
 	}
 
-	friend bool operator<(const MapKey &mk1, const MapKey &mk2)
+	friend bool operator<(const DictKey &mk1, const DictKey &mk2)
 	{
 		if (mk1._type != mk2._type) {
 			return mk1._type < mk2._type;

          
@@ 535,20 535,20 @@ private:
 	uint64_t _string_hash;
 };
 
-uint64_t MapKeyHash::operator()(const MapKey& key) const
+uint64_t DictKeyHash::operator()(const DictKey& key) const
 {
 	return key.hash();
 }
 
-class MapDynamicObject : public DynamicObject
+class DictDynamicObject : public DynamicObject
 {
-	/// Type used to sort the keys in the map to get a stable hash.
+	/// Type used to sort the keys in the dict to get a stable hash.
 	struct SortKey
 	{
 		SortKey()
 			: key(static_cast<int>(0))
 		{}
-		SortKey(const MapKey &k, const std::pair<Value, Value> &p)
+		SortKey(const DictKey &k, const std::pair<Value, Value> &p)
 			: key(k)
 			, pair(p)
 		{

          
@@ 560,22 560,22 @@ class MapDynamicObject : public DynamicO
 		}
 
 		uint64_t key_hash;
-		MapKey key;
+		DictKey key;
 		std::pair<Value, Value> pair; // key/value pair
 	};
 
 public:
-	MapDynamicObject();
+	DictDynamicObject();
 
 	virtual bool equal_to(const DynamicObject &other) const override;
 	virtual uint64_t hash(uint64_t seed) const override;
 	virtual DynamicObject *copy() override;
 	virtual void prepare_for_write() override;
 
-	/// This has to be a pointer to allow map element references to redirect a map to a new one.
-	/// In essence, the map has to be a pointer type object itself.
-	using MapType = core::HashMap<MapKey, std::pair<Value, Value>, MapKeyHash>;
-	std::shared_ptr<MapType> value;
+	/// This has to be a pointer to allow dict element references to redirect a dict to a new one.
+	/// In essence, the dict has to be a pointer type object itself.
+	using DictType = core::HashMap<DictKey, std::pair<Value, Value>, DictKeyHash>;
+	std::shared_ptr<DictType> value;
 };
 
 /// @}

          
M jasm/docs/jasm.md +79 -27
@@ 2,7 2,7 @@ 
 
 - - -
 
-This is the documentation for the 6502, 65C02, 65CE02 and Z80 assembler jAsm. It was written in 2015 by me, Jonas Hult&eacute;n, because I used DAsm before and over the years it started to feel outdated. I missed namespaces and I was annoyed by some bugs, like its inability to use local variables as macro arguments. It felt a bit slow on my slow laptop computer as well, although that wasn't a strong argument. Also, I hadn't written a language before and it felt like an interesting challenge.
+This is the documentation for the 6502, 65C02, 65CE02, 45GS02 and Z80 assembler jAsm. It was written in 2015 by me, Jonas Hult&eacute;n, because I used DAsm before and over the years it started to feel outdated. I missed namespaces and I was annoyed by some bugs, like its inability to use local variables as macro arguments. It felt a bit slow on my slow laptop computer as well, although that wasn't a strong argument. Also, I hadn't written a language before and it felt like an interesting challenge.
 
 jAsm was written with two main goals. It should be fast enough to assemble a large program in under a second and it should support everything DAsm can do and more. To reach the required speed it tries to use memory as linearly as possible and it proved to be faster than DAsm in the end.
 

          
@@ 22,6 22,7 @@ This documentation covers the language a
    * [6502](#m6502)
    * [65c02](#wdc65c02)
    * [65ce02](#csg65ce02)
+   * [45gs02](#mega45gs02)
    * [Z80](#z80)
 * [Starter Guide](#starter-guide)
    * [Basic Start](#starter-guide-basic-start)

          
@@ 58,6 59,7 @@ This documentation covers the language a
       * [6502 Pseudo Instructions](#6502-pseudo-instructions)
       * [65c02 Pseudo Instructions](#65c02-pseudo-instructions)
       * [65ce02 Pseudo Instructions](#65ce02-pseudo-instructions)
+      * [45gs02 Pseudo Instructions](#45gs02-pseudo-instructions)
       * [Z80 Pseudo Instructions](#z80-pseudo-instructions)
    * [Verboseness](#verboseness)
    * [Return Codes](#return-codes)

          
@@ 84,7 86,7 @@ This documentation covers the language a
       * [Float Type](#float-type)
       * [String Type](#string-type)
       * [List Type](#list-type)
-      * [Map Type](#map-type)
+      * [Dictionary Type](#dict-type)
    * [Passing Values](#passing-values)
    * [Type Conversions](#type-conversions)
    * [Memory Storage Types](#memory-storage-types)

          
@@ 174,6 176,35 @@ The stack pointer relative access addres
 	[65ce02]
 	lda ($55,sp),y
 
+<div id="mega45gs02"></div>
+## 45GS02
+
+jAsm has experimental support for the new Mega65 instructions of the 45GS02, along with the instructions of CSG4510.
+
+Instructions are written in lower case.
+
+	[45gs02]
+	ldz $d020
+	bru loop
+
+Just like 65CE02, the bit operation instructions don't have the bit in the instruction name as some assemblers do. Instead it is a separate argument. To follow convention, there is no '#' before the bit number to indicate immediate mode, even if that would be more consistent.
+
+	[45gs02]
+	bbr 0, zp, label
+	bbs 1, zp, label
+	rmb 2, zp
+	smb 3, zp
+
+The stack pointer relative access addressing mode is written like this.
+
+	[45gs02]
+	lda ($55,sp),y
+
+The indirect quad addressing mode is written using brackets.
+
+	[45gs02]
+	lda [$55],z
+
 <div id="z80"></div>
 ## Z80
 

          
@@ 379,7 410,7 @@ The `[6502]|if` statement wants a boolea
 	jasm -d C64_BUILD=true main.jasm main.prg
 	jasm -d C64_BUILD=false main.jasm main.prg
 
-<div id="starter-guide-definining-data"></div>
+<div id="starter-guide-defining-data"></div>
 ## Defining Data
 
 Let's try a hello world example. We'll drop the VIC20 support to make the code shorter. We will define the string "hello world!" and print it, character by character. We have already seen how to define a string in memory in the BASIC line. Printing is done with a jump to $ffd2, which prints a single character. Let's add the following naked constant to the c64.jasm file.

          
@@ 414,7 445,7 @@ Now we'll add the loop to print the text
 
 The define now has a name before the equal sign. This becomes a special kind of label. It can be used as a normal label but it also contains information about the defined data. `[6502]|sizeof` is a function that returns the size in bytes of such a labeled object or array.
 
-<div id="starter-guide-coding-for-readabiity"></div>
+<div id="starter-guide-coding-for-readability"></div>
 ## Coding For Readability
 
 This works but is hard to read. It isn't obvious where the loop starts and ends unless we read the instructions. Let's improve it using indentation.

          
@@ 1300,6 1331,27 @@ These are equivalent to the implied mode
 
 This is equivalent to the `[65ce02]|bru` instruction.
 
+<div id="45gs02-pseudo-instructions"></div>
+### 45GS02 pseudo instructions
+
+These are the pseudo instructions for 45GS02.
+
+	[45gs02]
+	bhs addr // branch if higher or same
+	blt addr // branch if lower
+
+These are equivalent to `[45gs02]|bcs` and `[45gs02]|bcc`, respectively.
+
+	[45gs02]
+	dea // decrement A register
+	ina // increment A register
+
+These are equivalent to the implied mode `[45gs02]|dec` and `[45gs02]|inc`, respectively.
+
+	[45gs02]
+	bra label // branch unconditionally
+
+This is equivalent to the `[45gs02]|bru` instruction.
 
 <div id="z80-pseudo-instructions"></div>
 ### Z80 pseudo instructions

          
@@ 1785,7 1837,7 @@ jAsm supports a number of operators, sim
 	<tr><th>Operator</th><th>Type</th><th>Types</th><th>Example</th></tr>
 	<tr><td><code>[6502]|()</code></td><td>call operator</td><td>macro, subroutine</td><td><code>[6502]|mac(aa,bb)</code></td></tr>
 	<tr><td><code>[6502]|[]</code></td><td>array indexing operator</td><td>string, list</td><td><code>[6502]|aa[3]</code></td></tr>
-	<tr><td><code>[6502]|.</code></td><td>property operator</td><td>string, list, map</td><td><code>[6502]|aa.length</code></td></tr>
+	<tr><td><code>[6502]|.</code></td><td>property operator</td><td>string, list, dict</td><td><code>[6502]|aa.length</code></td></tr>
 	<tr><td><code>[6502]|++</code></td><td>postfix increment</td><td>integer</td><td><code>[6502]|aa++</code></td></tr>
 	<tr><td><code>[6502]|--</code></td><td>postfix decrement</td><td>integer</td><td><code>[6502]|aa--</code></td></tr>
 	<tr><td><code>[6502]|++</code></td><td>prefix increment</td><td>integer</td><td><code>[6502]|++aa</code></td></tr>

          
@@ 1865,7 1917,7 @@ jAsm has a couple of built in data types
 * Floating point numbers
 * Strings
 * Lists
-* Maps
+* Dictionaries
 
 <div id="boolean-type"></div>
 ### Boolean Type

          
@@ 2205,13 2257,13 @@ The list type can hold a collection of v
 	</tr>
 </table>
 
-<div id="map-type"></div>
-### Map Type
-
-The map type can hold a collection of values with different types. A map is created using the `[6502]|map` function. This constructs a map containing key and value pairs as arguments.
+<div id="dict-type"></div>
+### Dictionary Type
+
+The dictionary type can hold a collection of values with different types. A dictionary is created using the `[6502]|dict` function. This constructs a dictionary containing key and value pairs as arguments.
 
 	[6502]
-	const FRUITS = map("apples" = 2, "bananas" = 5)
+	const FRUITS = dict("apples" = 2, "bananas" = 5)
 
 Values can be of any type, but keys must be booleans, integers or strings.
 

          
@@ 2219,44 2271,44 @@ Values can be of any type, but keys must
 	<tr>
 		<td><code>[6502]|set(key, value)</code></td>
 		<td>boolean|integer|string, any</td>
-		<td>Adds <code>[6502]|value</code> to be accessible by <code>[6502]|key</code> in the map.</td>
-		<td><code>[6502]|var aa = map()</code><br/><code>[6502]|aa.set("hi", 0)</code></td>
+		<td>Adds <code>[6502]|value</code> to be accessible by <code>[6502]|key</code> in the dict.</td>
+		<td><code>[6502]|var aa = dict()</code><br/><code>[6502]|aa.set("hi", 0)</code></td>
 	</tr>
 	<tr>
 		<td><code>[6502]|get(key)</code></td>
 		<td>boolean|integer|string</td>
 		<td>Fetches the value for a specific key.</td>
-		<td><code>[6502]|var aa = map("a" = 0, "b" = 1)</code><br/><code>[6502]|aa.get("b") // 1</code></td>
+		<td><code>[6502]|var aa = dict("a" = 0, "b" = 1)</code><br/><code>[6502]|aa.get("b") // 1</code></td>
 	</tr>
 	<tr>
 		<td><code>[6502]|erase(key)</code></td>
 		<td>boolean|integer|string</td>
-		<td>Removes a value with the specified key from the map.</td>
-		<td><code>[6502]|var aa = map("a" = 0, "b" = 1)</code><br/><code>[6502]|aa.erase("b")</code></td>
+		<td>Removes a value with the specified key from the dict.</td>
+		<td><code>[6502]|var aa = dict("a" = 0, "b" = 1)</code><br/><code>[6502]|aa.erase("b")</code></td>
 	</tr>
 	<tr>
 		<td><code>[6502]|clear()</code></td>
 		<td></td>
-		<td>Remove all keys and values from the map.</td>
-		<td><code>[6502]|var aa = map("a" = 0, "b" = 1)</code><br/><code>[6502]|aa.clear()</code></td>
+		<td>Remove all keys and values from the dict.</td>
+		<td><code>[6502]|var aa = dict("a" = 0, "b" = 1)</code><br/><code>[6502]|aa.clear()</code></td>
 	</tr>
 	<tr>
 		<td><code>[6502]|has(key)</code><br/></td>
 		<td>boolean|integer|string</td>
-		<td>Return <code>[6502]|true</code> if the key exists in the map, otherwise <code>[6502]|false</code>.</td>
-		<td><code>[6502]|var aa = map("a" = 0, "b" = 1)</code><br/><code>[6502]|aa.has("a") // true</code><br/><code>[6502]|aa.has("c") // false</code></td>
+		<td>Return <code>[6502]|true</code> if the key exists in the dict, otherwise <code>[6502]|false</code>.</td>
+		<td><code>[6502]|var aa = dict("a" = 0, "b" = 1)</code><br/><code>[6502]|aa.has("a") // true</code><br/><code>[6502]|aa.has("c") // false</code></td>
 	</tr>
 	<tr>
 		<td><code>[6502]|empty</code></td>
 		<td></td>
-		<td>Returns <code>[6502]|true</code> if the map is empty, otherwise <code>[6502]|false</code>.</td>
-		<td><code>[6502]|map("one" = 1).empty // false</code><br/><code>[6502]|map().empty // true</code></td>
+		<td>Returns <code>[6502]|true</code> if the dict is empty, otherwise <code>[6502]|false</code>.</td>
+		<td><code>[6502]|dict("one" = 1).empty // false</code><br/><code>[6502]|dict().empty // true</code></td>
 	</tr>
 	<tr>
 		<td><code>[6502]|length</code></td>
 		<td></td>
-		<td>Returns the number of elements in the map.</td>
-		<td><code>[6502]|const aa = map("one" = 1, "two" = 2)</code><br/><code>[6502]|lda #aa.length // 2</code></td>
+		<td>Returns the number of elements in the dict.</td>
+		<td><code>[6502]|const aa = dict("one" = 1, "two" = 2)</code><br/><code>[6502]|lda #aa.length // 2</code></td>
 	</tr>
 </table>
 

          
@@ 3270,10 3322,10 @@ This will generate data for filenames wh
 
 *When the loop starts, a copy of the list will be made. The iteration is done over the copy to avoid problems where the list is accidently modified inside the loop.*
 
-This type of loop can be used on maps as well like this.
+This type of loop can be used on dicts as well like this.
 
 	[6502]
-	const .colors = map("black" = 0, "white" = 1, "red" = 2)
+	const .colors = dict("black" = 0, "white" = 1, "red" = 2)
 
 	for(var .name, .color in .colors)
 	{

          
@@ 3281,7 3333,7 @@ This type of loop can be used on maps as
 		define byte = .color
 	}
 
-Note that the iteration over the map keys and values will not be done in any particular order.
+Note that the iteration over the dict keys and values will not be done in any particular order.
 
 <div id="repeat-loop"></div>
 ### Repeat Loop

          
M jasm/docs/syntax_highlight.py +5 -2
@@ 44,10 44,11 @@ def replace_with_token(text, replace_map
 
 def syntax_highlight_code(code_class, text):
 	keywords = re.compile(r'\b(address|align|basic|bss|byte|code|const|declare|define|dynamic|elif|else|enum|export|fill|for|function|if|import|incbin|include|long|macro|mapping|module|namespace|optimize|part|pop|processor|reserve|return|section|struct|subroutine|using|var|word)\b')
-	functions = re.compile(r'\b(abs|acos|asin|atan|atan2|ceil|clamp|cos|cosh|degrees|exp|float|floor|format|hexstring|int|lerp|log|log10|logn|max|min|modulo|offsetof|pow|print|radians|remainder|round|select|sin|sinh|sizeof|sqrt|static_assert|string|symbol|tan|tanh|unicode|uppercase|lowercase)\b')
+	functions = re.compile(r'\b(abs|acos|asin|atan|atan2|ceil|clamp|cos|cosh|degrees|dict|exp|float|floor|format|hexstring|int|lerp|list|log|log10|logn|max|min|modulo|offsetof|pow|print|radians|remainder|round|select|sin|sinh|sizeof|sqrt|static_assert|string|symbol|tan|tanh|unicode|uppercase|lowercase)\b')
 	instructions_6502 = re.compile(r'\b(adc|and|asl|bcc|bcs|beq|bit|bmi|bne|bpl|brk|bvc|bvs|clc|cld|cli|clv|cmp|cpx|cpy|dec|dex|dey|eor|inc|inx|iny|jmp|jsr|lda|ldx|ldy|lsr|nop|ora|pha|php|pla|plp|rol|ror|rti|rts|sbc|sec|sed|sei|sta|stx|sty|tax|tay|tsx|txa|txs|tya|bhs|blt)\b')
 	instructions_65c02 = re.compile(r'\b(adc|and|asl|bbr|bbs|bcc|bcs|beq|bit|bmi|bne|bpl|bra|brk|bvc|bvs|clc|cld|cli|clv|cmp|cpx|cpy|dec|dex|dey|eor|inc|inx|iny|jmp|jsr|lda|ldx|ldy|lsr|nop|ora|pha|php|phx|phy|pla|plp|plx|ply|rmb|rol|ror|rti|rts|sbc|sec|sed|sei|smb|sta|stp|stx|sty|stz|tax|tay|trb|tsb|tsx|txa|txs|tya|wai|bhs|blt|dea|ina)\b')
 	instructions_65ce02 = re.compile(r'\b(adc|and|asl|asr|asw|bbr|bbs|bcc|bcs|beq|bit|bmi|bne|bpl|bru|brk|bsr|bvc|bvs|clc|cld|cle|cli|clv|cmp|cpx|cpy|cpz|dec|dew|dex|dey|dez|eor|inc|inw|inx|iny|inz|jmp|jsr|lda|ldx|ldy|ldz|lsr|neg|nop|ora|pha|php|phw|phx|phy|phz|pla|plp|plx|ply|plz|rmb|rol|ror|row|rti|rtn|rts|sbc|sec|sed|see|sei|smb|sta|stx|sty|stz|tab|tax|tay|taz|tba|trb|tsb|tsx|tsy|txa|txs|tya|tys|tza|bhs|blt|bra|dea|ina)\b')
+	instructions_45gs02 = re.compile(r'\b(adc|adcq|and|andq|asl|aslq|asr|asrq|asw|bbr|bbs|bcc|bcs|beq|bit|bitq|bmi|bne|bpl|brk|bru|bsr|bvc|bvs|clc|cld|cle|cli|clv|cmp|cmpq|cpx|cpy|cpz|dec|deq|dew|dex|dey|dez|eom|eor|eorq|inc|inq|inw|inx|iny|inz|jmp|jsr|lda|ldq|ldx|ldy|ldz|lsr|lsrq|map|neg|ora|orq|pha|php|phw|phx|phy|phz|pla|plp|plx|ply|plz|rmb|rol|rolq|ror|rorq|row|rti|rtn|rts|sbc|sbcq|sec|sed|see|sei|smb|sta|stq|stx|sty|stz|tab|tax|tay|taz|tba|trb|tsb|tsx|tsy|txa|txs|tya|tys|tza|bhs|blt|bra|dea|ina)\b')
 	instructions_z80 = re.compile(r'\b(adc|add|and|bit|call|ccf|cp|cpd|cpdr|cpi|cpir|cpl|daa|dec|di|djnz|ei|ex|exx|halt|im|in|inc|ind|indr|ini|inir|jp|jr|ld|ldd|lddr|ldi|ldir|neg|nop|or|otdr|otir|out|outd|outi|pop|push|res|ret|reti|retn|rl|rla|rlc|rlca|rld|rr|rra|rrc|rrca|rrd|rst|sbc|scf|set|sla|sra|srl|sub|xor)\b')
 	operators = re.compile(r'(<<=|>>=|&amp;&amp;=|[|][|]=|!=|[+][+]|--|<<|>>|<=|>=|==|&amp;&amp;|[|][|]|[+]=|-=|[*]=|[/]=|&amp;=|[|]=|\^=|::|!|~|[*]|[/]|[+]|-|&lt;|&gt;|&amp;|\^|[|]|=|#|%)')
 	special = re.compile(r'({|}|\(|\)|;|\[|\])')

          
@@ 84,6 85,8 @@ def syntax_highlight_code(code_class, te
 		text = colorize(text, instructions_65c02, "instruction")
 	elif code_class == "[65ce02]":
 		text = colorize(text, instructions_65ce02, "instruction")
+	elif code_class == "[45gs02]":
+		text = colorize(text, instructions_45gs02, "instruction")
 	else:
 		text = colorize(text, instructions_z80, "instruction")
 

          
@@ 117,7 120,7 @@ def syntax_highlight_code(code_class, te
 
 
 def syntax_highlight_text(code_class, code):
-	if code_class == "[6502]" or code_class == "[65c02]" or code_class == "[65ce02]" or code_class == "[z80]":
+	if code_class == "[6502]" or code_class == "[65c02]" or code_class == "[65ce02]" or code_class == "[45gs02]" or code_class == "[z80]":
 		return syntax_highlight_code(code_class, code)
 	elif code_class == "[text]":
 		return code

          
M jasm/exceptions/error_codes.h +4 -4
@@ 185,11 185,11 @@ enum class AssemblyErrorCodes
 	StartAddressTooLargeForFileHeader,
 	RecursiveDataGenerationNotAllowed,
 	UnstableVariableState,
-	MissingKeyAssignmentInMapArgument,
-	UnsupportedMapKeyType,
-	AccessToMissingMapKey,
+	MissingKeyAssignmentInDictArgument,
+	UnsupportedDictKeyType,
+	AccessToMissingDictKey,
 	RangeBasedForRequiresPairEnumeration,
-	DuplicateMapKeys,
+	DuplicateDictKeys,
 	AddressingModeArgumentCannotHaveDataLabel,
 	StringConversionFormatExpected,
 	UnknownStringConversionFormatCombination,

          
A => jasm/processor/45gs02/instructions_45gs02.cpp +823 -0
@@ 0,0 1,823 @@ 
+#include "pch.h"
+
+#include <processor/45gs02/instructions_45gs02.h>
+
+namespace jasm
+{
+	namespace mega45gs02
+	{
+
+using namespace AddressingModeMask;
+
+/// All opcodes for one instruction.
+struct OpCodes
+{
+	OpCode op_codes[static_cast<int>(AddressingModeType::NumAddressingModes)];
+};
+
+constexpr OpCode op()
+{
+	OpCode opcode = {0, {0,0,0,0,0,0,0}};
+	opcode.size = 0;
+	return opcode;
+}
+
+constexpr OpCode op(uint8_t op1)
+{
+	OpCode opcode = {0, {0,0,0,0,0,0,0}};
+	opcode.size = 1;
+	opcode.opcode[0] = op1;
+	return opcode;
+}
+constexpr OpCode op(uint8_t op1, uint8_t op2)
+{
+	OpCode opcode = {0, {0,0,0,0,0,0,0}};
+	opcode.size = 2;
+	opcode.opcode[0] = op1;
+	opcode.opcode[1] = op2;
+	return opcode;
+}
+constexpr OpCode op(uint8_t op1, uint8_t op2, uint8_t op3)
+{
+	OpCode opcode = {0, {0,0,0,0,0,0,0}};
+	opcode.size = 3;
+	opcode.opcode[0] = op1;
+	opcode.opcode[1] = op2;
+	opcode.opcode[2] = op3;
+	return opcode;
+}
+constexpr OpCode op(uint8_t op1, uint8_t op2, uint8_t op3, uint8_t op4)
+{
+	OpCode opcode = {0, {0,0,0,0,0,0,0}};
+	opcode.size = 4;
+	opcode.opcode[0] = op1;
+	opcode.opcode[1] = op2;
+	opcode.opcode[2] = op3;
+	opcode.opcode[3] = op4;
+	return opcode;
+}
+
+uint32_t __addressing_modes_mask[static_cast<int>(InstructionType::NumTypes)] = {
+	/*        Bp   Abs   Bpx   AbsX   Bpy   AbsY   BpIX   IndX   Rel   RelW   BInd   Ind   BpIY   BpIZ | BIQ | BIQZ   SpIY   Imp   Imm   ImmW   Bb   Bbr */
+	/* ADC */ Bp | Abs | Bpx | AbsX | ___ | AbsY | BpIX | ____ | ___ | ____ | ____ | ___ | BpIY | BpIZ | ___ | BIQZ | ____ | ___ | Imm | ____ | __ | ___ ,
+	/* ADCQ*/ Bp | Abs | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | BInd | ___ | ____ | ____ | BIQ | ____ | ____ | ___ | ___ | ____ | __ | ___ ,
+	/* AND */ Bp | Abs | Bpx | AbsX | ___ | AbsY | BpIX | ____ | ___ | ____ | ____ | ___ | BpIY | BpIZ | ___ | BIQZ | ____ | ___ | Imm | ____ | __ | ___ ,
+	/* ANDQ*/ Bp | Abs | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | BInd | ___ | ____ | ____ | BIQ | ____ | ____ | ___ | ___ | ____ | __ | ___ ,
+	/* ASL */ Bp | Abs | Bpx | AbsX | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/*        Bp   Abs   Bpx   AbsX   Bpy   AbsY   BpIX   IndX   Rel   RelW   BInd   Ind   BpIY   BpIZ | BIQ | BIQZ   SpIY   Imp   Imm   ImmW   Bb   Bbr */
+	/* ASLQ*/ Bp | Abs | Bpx | AbsX | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* ASR */ Bp | ___ | Bpx | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* ASRQ*/ Bp | ___ | Bpx | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* ASW */ __ | Abs | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ___ | ____ | __ | ___ ,
+	/* BBR */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ___ | ____ | __ | Bbr ,
+	/*        Bp   Abs   Bpx   AbsX   Bpy   AbsY   BpIX   IndX   Rel   RelW   BInd   Ind   BpIY   BpIZ | BIQ | BIQZ   SpIY   Imp   Imm   ImmW   Bb   Bbr */
+	/* BBS */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ___ | ____ | __ | Bbr ,
+	/* BCC */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | Rel | RelW | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ___ | ____ | __ | ___ ,
+	/* BCS */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | Rel | RelW | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ___ | ____ | __ | ___ ,
+	/* BEQ */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | Rel | RelW | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ___ | ____ | __ | ___ ,
+	/* BIT */ Bp | Abs | Bpx | AbsX | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | Imm | ____ | __ | ___ ,
+	/*        Bp   Abs   Bpx   AbsX   Bpy   AbsY   BpIX   IndX   Rel   RelW   BInd   Ind   BpIY   BpIZ | BIQ | BIQZ   SpIY   Imp   Imm   ImmW   Bb   Bbr */
+	/* BITQ*/ Bp | Abs | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ___ | ____ | __ | ___ ,
+	/* BMI */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | Rel | RelW | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ___ | ____ | __ | ___ ,
+	/* BNE */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | Rel | RelW | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ___ | ____ | __ | ___ ,
+	/* BPL */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | Rel | RelW | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ___ | ____ | __ | ___ ,
+	/* BRK */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/*        Bp   Abs   Bpx   AbsX   Bpy   AbsY   BpIX   IndX   Rel   RelW   BInd   Ind   BpIY   BpIZ | BIQ | BIQZ   SpIY   Imp   Imm   ImmW   Bb   Bbr */
+	/* BRU */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | Rel | RelW | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ___ | ____ | __ | ___ ,
+	/* BSR */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | RelW | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ___ | ____ | __ | ___ ,
+	/* BVC */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | Rel | RelW | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ___ | ____ | __ | ___ ,
+	/* BVS */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | Rel | RelW | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ___ | ____ | __ | ___ ,
+	/* CLC */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/*        Bp   Abs   Bpx   AbsX   Bpy   AbsY   BpIX   IndX   Rel   RelW   BInd   Ind   BpIY   BpIZ | BIQ | BIQZ   SpIY   Imp   Imm   ImmW   Bb   Bbr */
+	/* CLD */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* CLE */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* CLI */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* CLV */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* CMP */ Bp | Abs | Bpx | AbsX | ___ | AbsY | BpIX | ____ | ___ | ____ | ____ | ___ | BpIY | BpIZ | ___ | BIQZ | ____ | ___ | Imm | ____ | __ | ___ ,
+	/*        Bp   Abs   Bpx   AbsX   Bpy   AbsY   BpIX   IndX   Rel   RelW   BInd   Ind   BpIY   BpIZ | BIQ | BIQZ   SpIY   Imp   Imm   ImmW   Bb   Bbr */
+	/* CMPQ*/ Bp | Abs | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | BInd | ___ | ____ | ____ | BIQ | ____ | ____ | ___ | ___ | ____ | __ | ___ ,
+	/* CPX */ Bp | Abs | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | Imm | ____ | __ | ___ ,
+	/* CPY */ Bp | Abs | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | Imm | ____ | __ | ___ ,
+	/* CPZ */ Bp | Abs | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | Imm | ____ | __ | ___ ,
+	/* DEC */ Bp | Abs | Bpx | AbsX | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/*        Bp   Abs   Bpx   AbsX   Bpy   AbsY   BpIX   IndX   Rel   RelW   BInd   Ind   BpIY   BpIZ | BIQ | BIQZ   SpIY   Imp   Imm   ImmW   Bb   Bbr */
+	/* DEQ */ Bp | Abs | Bpx | AbsX | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* DEW */ Bp | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ___ | ____ | __ | ___ ,
+	/* DEX */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* DEY */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* DEZ */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/*        Bp   Abs   Bpx   AbsX   Bpy   AbsY   BpIX   IndX   Rel   RelW   BInd   Ind   BpIY   BpIZ | BIQ | BIQZ   SpIY   Imp   Imm   ImmW   Bb   Bbr */
+	/* EOM */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* EOR */ Bp | Abs | Bpx | AbsX | ___ | AbsY | BpIX | ____ | ___ | ____ | ____ | ___ | BpIY | BpIZ | ___ | BIQZ | ____ | ___ | Imm | ____ | __ | ___ ,
+	/* EORQ*/ Bp | Abs | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | BInd | ___ | ____ | ____ | BIQ | ____ | ____ | ___ | ___ | ____ | __ | ___ ,
+	/* INC */ Bp | Abs | Bpx | AbsX | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* INQ */ Bp | Abs | Bpx | AbsX | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* INW */ Bp | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ___ | ____ | __ | ___ ,
+	/*        Bp   Abs   Bpx   AbsX   Bpy   AbsY   BpIX   IndX   Rel   RelW   BInd   Ind   BpIY   BpIZ | BIQ | BIQZ   SpIY   Imp   Imm   ImmW   Bb   Bbr */
+	/* INX */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* INY */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* INZ */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* JMP */ __ | Abs | ___ | ____ | ___ | ____ | ____ | IndX | ___ | ____ | ____ | Ind | ____ | ____ | ___ | ____ | ____ | ___ | ___ | ____ | __ | ___ ,
+	/* JSR */ __ | Abs | ___ | ____ | ___ | ____ | ____ | IndX | ___ | ____ | ____ | Ind | ____ | ____ | ___ | ____ | ____ | ___ | ___ | ____ | __ | ___ ,
+	/*        Bp   Abs   Bpx   AbsX   Bpy   AbsY   BpIX   IndX   Rel   RelW   BInd   Ind   BpIY   BpIZ | BIQ | BIQZ   SpIY   Imp   Imm   ImmW   Bb   Bbr */
+	/* LDA */ Bp | Abs | Bpx | AbsX | ___ | AbsY | BpIX | ____ | ___ | ____ | ____ | ___ | BpIY | BpIZ | ___ | BIQZ | SpIY | ___ | Imm | ____ | __ | ___ ,
+	/* LDQ */ Bp | Abs | Bpx | AbsX | ___ | AbsY | ____ | ____ | ___ | ____ | BInd | ___ | BpIY | ____ | BIQ | ____ | SpIY | ___ | ___ | ____ | __ | ___ ,
+	/* LDX */ Bp | Abs | ___ | ____ | Bpy | AbsY | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | Imm | ____ | __ | ___ ,
+	/* LDY */ Bp | Abs | Bpx | AbsX | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | Imm | ____ | __ | ___ ,
+	/* LDZ */ __ | Abs | ___ | AbsX | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | Imm | ____ | __ | ___ ,
+	/*        Bp   Abs   Bpx   AbsX   Bpy   AbsY   BpIX   IndX   Rel   RelW   BInd   Ind   BpIY   BpIZ | BIQ | BIQZ   SpIY   Imp   Imm   ImmW   Bb   Bbr */
+	/* LSR */ Bp | Abs | Bpx | AbsX | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* LSRQ*/ Bp | Abs | Bpx | AbsX | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* MAP */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* NEG */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* ORA */ Bp | Abs | Bpx | AbsX | ___ | AbsY | BpIX | ____ | ___ | ____ | ____ | ___ | BpIY | BpIZ | ___ | BIQZ | ____ | ___ | Imm | ____ | __ | ___ ,
+	/*        Bp   Abs   Bpx   AbsX   Bpy   AbsY   BpIX   IndX   Rel   RelW   BInd   Ind   BpIY   BpIZ | BIQ | BIQZ   SpIY   Imp   Imm   ImmW   Bb   Bbr */
+	/* ORQ */ Bp | Abs | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | BInd | ___ | ____ | ____ | BIQ | ____ | ____ | ___ | Imm | ____ | __ | ___ ,
+	/* PHA */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* PHP */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* PHW */ __ | Abs | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ___ | ImmW | __ | ___ ,
+	/* PHX */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/*        Bp   Abs   Bpx   AbsX   Bpy   AbsY   BpIX   IndX   Rel   RelW   BInd   Ind   BpIY   BpIZ | BIQ | BIQZ   SpIY   Imp   Imm   ImmW   Bb   Bbr */
+	/* PHY */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* PHZ */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* PLA */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* PLP */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* PLX */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/*        Bp   Abs   Bpx   AbsX   Bpy   AbsY   BpIX   IndX   Rel   RelW   BInd   Ind   BpIY   BpIZ | BIQ | BIQZ   SpIY   Imp   Imm   ImmW   Bb   Bbr */
+	/* PLY */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* PLZ */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* RMB */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ___ | ____ | Bb | ___ ,
+	/* ROL */ Bp | Abs | Bpx | AbsX | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* ROLQ*/ Bp | Abs | Bpx | AbsX | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/*        Bp   Abs   Bpx   AbsX   Bpy   AbsY   BpIX   IndX   Rel   RelW   BInd   Ind   BpIY   BpIZ | BIQ | BIQZ   SpIY   Imp   Imm   ImmW   Bb   Bbr */
+	/* ROR */ Bp | Abs | Bpx | AbsX | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* RORQ*/ Bp | Abs | Bpx | AbsX | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* ROW */ __ | Abs | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ___ | ____ | __ | ___ ,
+	/* RTI */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* RTN */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | Imm | ____ | __ | ___ ,
+	/*        Bp   Abs   Bpx   AbsX   Bpy   AbsY   BpIX   IndX   Rel   RelW   BInd   Ind   BpIY   BpIZ | BIQ | BIQZ   SpIY   Imp   Imm   ImmW   Bb   Bbr */
+	/* RTS */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* SBC */ Bp | Abs | Bpx | AbsX | ___ | AbsY | BpIX | ____ | ___ | ____ | ____ | ___ | BpIY | BpIZ | ___ | BIQZ | ____ | ___ | Imm | ____ | __ | ___ ,
+	/* SBCQ*/ Bp | Abs | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | BInd | ___ | ____ | ____ | BIQ | ____ | ____ | ___ | ___ | ____ | __ | ___ ,
+	/* SEC */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* SED */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/*        Bp   Abs   Bpx   AbsX   Bpy   AbsY   BpIX   IndX   Rel   RelW   BInd   Ind   BpIY   BpIZ | BIQ | BIQZ   SpIY   Imp   Imm   ImmW   Bb   Bbr */
+	/* SEE */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* SEI */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* SMB */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ___ | ____ | Bb | ___ ,
+	/* STA */ Bp | Abs | Bpx | AbsX | ___ | AbsY | BpIX | ____ | ___ | ____ | ____ | ___ | BpIY | BpIZ | ___ | BIQZ | SpIY | ___ | ___ | ____ | __ | ___ ,
+	/* STQ */ Bp | Abs | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | BInd | ___ | ____ | ____ | BIQ | ____ | SpIY | ___ | ___ | ____ | __ | ___ ,
+	/*        Bp   Abs   Bpx   AbsX   Bpy   AbsY   BpIX   IndX   Rel   RelW   BInd   Ind   BpIY   BpIZ | BIQ | BIQZ   SpIY   Imp   Imm   ImmW   Bb   Bbr */
+	/* STX */ Bp | Abs | ___ | ____ | Bpy | AbsY | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ___ | ____ | __ | ___ ,
+	/* STY */ Bp | Abs | Bpx | AbsX | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ___ | ____ | __ | ___ ,
+	/* STZ */ Bp | Abs | Bpx | AbsX | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ___ | ____ | __ | ___ ,
+	/* TAB */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* TAX */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/*        Bp   Abs   Bpx   AbsX   Bpy   AbsY   BpIX   IndX   Rel   RelW   BInd   Ind   BpIY   BpIZ | BIQ | BIQZ   SpIY   Imp   Imm   ImmW   Bb   Bbr */
+	/* TAY */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* TAZ */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* TBA */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* TRB */ Bp | Abs | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ___ | ____ | __ | ___ ,
+	/* TSB */ Bp | Abs | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ___ | ____ | __ | ___ ,
+	/*        Bp   Abs   Bpx   AbsX   Bpy   AbsY   BpIX   IndX   Rel   RelW   BInd   Ind   BpIY   BpIZ | BIQ | BIQZ   SpIY   Imp   Imm   ImmW   Bb   Bbr */
+	/* TSX */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* TSY */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* TXA */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* TXS */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* TYS */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/*        Bp   Abs   Bpx   AbsX   Bpy   AbsY   BpIX   IndX   Rel   RelW   BInd   Ind   BpIY   BpIZ | BIQ | BIQZ   SpIY   Imp   Imm   ImmW   Bb   Bbr */
+	/* TYA */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* TZA */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+
+	/*        Bp   Abs   Bpx   AbsX   Bpy   AbsY   BpIX   IndX   Rel   RelW   BInd   Ind   BpIY   BpIZ | BIQ | BIQZ   SpIY   Imp   Imm   ImmW   Bb   Bbr */
+	/* BHS */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | Rel | RelW | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ___ | ____ | __ | ___ ,
+	/* BLT */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | Rel | RelW | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ___ | ____ | __ | ___ ,
+	/* BRA */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | Rel | RelW | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ___ | ____ | __ | ___ ,
+	/* DEA */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+	/* INA */ __ | ___ | ___ | ____ | ___ | ____ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | ___ | ____ | ____ | Imp | ___ | ____ | __ | ___ ,
+
+};
+
+OpCodes __opcodes[static_cast<int>(InstructionType::NumTypes)] = {
+	/*          BP,       ABSO,     BPX,      ABSX,     BPY,  ABSY,     BPIX,     INDX, RELA, RELW, BIND, INDI, BPIY,     BPIZ,     BIQ,  BIQZ,          SPIY, IMPL, IMME,     IMMW, BB,   BBR,*/
+	/* ADC */ {{op(0x65), op(0x6d), op(0x75), op(0x7d), op(), op(0x79), op(0x61), op(), op(), op(), op(), op(), op(0x71), op(0x72), op(), op(0xea,0x72), op(), op(), op(0x69), op(), op(), op()}},
+
+	/*          BP,                 ABSO,               BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND,               INDI, BPIY, BPIZ, BIQ,                     BIQZ, SPIY, IMPL, IMME, IMMW, BB,   BBR,*/
+	/* ADCQ*/ {{op(0x42,0x42,0x65), op(0x42,0x42,0x6d), op(), op(), op(), op(), op(), op(), op(), op(), op(0x42,0x42,0x72), op(), op(), op(), op(0x42,0x42,0xea,0x72), op(), op(), op(), op(), op(), op(), op()}},
+
+	/*          BP,       ABSO,     BPX,      ABSX,     BPY,  ABSY,     BPIX,     INDX, RELA, RELW, BIND, INDI, BPIY,     BPIZ,     BIQ,  BIQZ,          SPIY, IMPL, IMME,     IMMW, BB,   BBR,*/
+	/* AND */ {{op(0x25), op(0x2d), op(0x35), op(0x3d), op(), op(0x39), op(0x21), op(), op(), op(), op(), op(), op(0x31), op(0x32), op(), op(0xea,0x32), op(), op(), op(0x29), op(), op(), op()}},
+
+	/*          BP,                 ABSO,               BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND,               INDI, BPIY, BPIZ, BIQ,                     BIQZ, SPIY, IMPL, IMME, IMMW, BB,   BBR,*/
+	/* ANDQ*/ {{op(0x42,0x42,0x25), op(0x42,0x42,0x2d), op(), op(), op(), op(), op(), op(), op(), op(), op(0x42,0x42,0x32), op(), op(), op(), op(0x42,0x42,0xea,0x32), op(), op(), op(), op(), op(), op(), op()}},
+
+	/*          BP,       ABSO,     BPX,      ABSX,     BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* ASL */ {{op(0x06), op(0x0e), op(0x16), op(0x1e), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x0a), op(), op(), op(), op()}},
+
+	/*          BP,                 ABSO,               BPX,                ABSX,               BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,               IMME, IMMW, BB,   BBR,*/
+	/* ASLQ*/ {{op(0x42,0x42,0x06), op(0x42,0x42,0x0e), op(0x42,0x42,0x16), op(0x42,0x42,0x1e), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x42,0x42,0x0a), op(), op(), op(), op()}},
+	
+	/*          BP,       ABSO, BPX,      ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* ASR */ {{op(0x44), op(), op(0x54), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x43), op(), op(), op(), op()}},
+
+	/*          BP,                 ABSO, BPX,                ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,               IMME, IMMW, BB,   BBR,*/
+	/* ASRQ*/ {{op(0x42,0x42,0x44), op(), op(0x42,0x42,0x54), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x42,0x42,0x43), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO,     BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL, IMME, IMMW, BB,   BBR,*/
+	/* ASW */ {{op(), op(0xcb), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL, IMME, IMMW, BB,   BBR,*/
+	/* BBR */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x0f)}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL, IMME, IMMW, BB,   BBR,*/
+	/* BBS */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x8f)}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA,     RELW,     BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL, IMME, IMMW, BB,   BBR,*/
+	/* BCC */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(0x90), op(0x93), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA,     RELW,     BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL, IMME, IMMW, BB,   BBR,*/
+	/* BCS */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(0xb0), op(0xb3), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA,     RELW,     BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL, IMME, IMMW, BB,   BBR,*/
+	/* BEQ */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(0xf0), op(0xf3), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op()}},
+
+	/*          BP,       ABSO,     BPX,      ABSX,     BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL, IMME,     IMMW, BB,   BBR,*/
+	/* BIT */ {{op(0x24), op(0x2c), op(0x34), op(0x3c), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x89), op(), op(), op()}},
+
+	/*          BP,                 ABSO,               BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL, IMME, IMMW, BB,   BBR,*/
+	/* BITQ*/ {{op(0x42,0x42,0x24), op(0x42,0x42,0x2c), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA,     RELW,     BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL, IMME, IMMW, BB,   BBR,*/
+	/* BMI */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(0x30), op(0x33), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA,     RELW,     BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL, IMME, IMMW, BB,   BBR,*/
+	/* BNE */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(0xd0), op(0xd3), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA,     RELW,     BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL, IMME, IMMW, BB,   BBR,*/
+	/* BPL */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(0x10), op(0x13), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* BRK */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x00), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA,     RELW,     BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL, IMME, IMMW, BB,   BBR,*/
+	/* BRU */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(0x80), op(0x83), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW,     BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL, IMME, IMMW, BB,   BBR,*/
+	/* BSR */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x63), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA,     RELW,     BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL, IMME, IMMW, BB,   BBR,*/
+	/* BVC */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(0x50), op(0x53), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA,     RELW,     BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL, IMME, IMMW, BB,   BBR,*/
+	/* BVS */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(0x70), op(0x73), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* CLC */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x18), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* CLD */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0xd8), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* CLE */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x02), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* CLI */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x58), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* CLV */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0xb8), op(), op(), op(), op()}},
+
+	/*          BP,       ABSO,     BPX,      ABSX,     BPY,  ABSY,     BPIX,     INDX, RELA, RELW, BIND, INDI, BPIY,     BPIZ,     BIQ,  BIQZ,          SPIY, IMPL, IMME,     IMMW, BB,   BBR,*/
+	/* CMP */ {{op(0xc5), op(0xcd), op(0xd5), op(0xdd), op(), op(0xd9), op(0xc1), op(), op(), op(), op(), op(), op(0xd1), op(0xd2), op(), op(0xea,0xd2), op(), op(), op(0xc9), op(), op(), op()}},
+
+	/*          BP,                 ABSO,               BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND,               INDI, BPIY, BPIZ, BIQ,                     BIQZ, SPIY, IMPL, IMME, IMMW, BB,   BBR,*/
+	/* CMPQ*/ {{op(0x42,0x42,0xc5), op(0x42,0x42,0xcd), op(), op(), op(), op(), op(), op(), op(), op(), op(0x42,0x42,0xd2), op(), op(), op(), op(0x42,0x42,0xea,0xd2), op(), op(), op(), op(), op(), op(), op()}},
+
+	/*          BP,       ABSO,     BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL, IMME,     IMMW, BB,   BBR,*/
+	/* CPX */ {{op(0xe4), op(0xec), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0xe0), op(), op(), op()}},
+
+	/*          BP,       ABSO,     BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL, IMME,     IMMW, BB,   BBR,*/
+	/* CPY */ {{op(0xc4), op(0xcc), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0xc0), op(), op(), op()}},
+
+	/*          BP,       ABSO,     BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL, IMME,     IMMW, BB,   BBR,*/
+	/* CPZ */ {{op(0xd4), op(0xdc), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0xc2), op(), op(), op()}},
+
+	/*          BP,       ABSO,     BPX,      ABSX,     BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* DEC */ {{op(0xc6), op(0xce), op(0xd6), op(0xde), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x3a), op(), op(), op(), op()}},
+
+	/*          BP,                 ABSO,               BPX,                ABSX,               BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,               IMME, IMMW, BB,   BBR,*/
+	/* DEQ */ {{op(0x42,0x42,0xd6), op(0x42,0x42,0xce), op(0x42,0x42,0xd6), op(0x42,0x42,0xde), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x42,0x42,0x3a), op(), op(), op(), op()}},
+
+	/*          BP,       ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL, IMME, IMMW, BB,   BBR,*/
+	/* DEW */ {{op(0xc3), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* DEX */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0xca), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* DEY */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x88), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* DEZ */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x3b), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* EOM */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0xea), op(), op(), op(), op()}},
+
+	/*          BP,       ABSO,     BPX,      ABSX,     BPY,  ABSY,     BPIX,     INDX, RELA, RELW, BIND, INDI, BPIY,     BPIZ,     BIQ,  BIQZ,          SPIY, IMPL, IMME,     IMMW, BB,   BBR,*/
+	/* EOR */ {{op(0x45), op(0x4d), op(0x55), op(0x5d), op(), op(0x59), op(0x41), op(), op(), op(), op(), op(), op(0x51), op(0x52), op(), op(0xea,0x52), op(), op(), op(0x49), op(), op(), op()}},
+
+	/*          BP,                 ABSO,               BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND,               INDI, BPIY, BPIZ, BIQ,                     BIQZ, SPIY, IMPL, IMME, IMMW, BB,   BBR,*/
+	/* EORQ*/ {{op(0x42,0x42,0x45), op(0x42,0x42,0x4d), op(), op(), op(), op(), op(), op(), op(), op(), op(0x42,0x42,0x52), op(), op(), op(), op(0x42,0x42,0xea,0x52), op(), op(), op(), op(), op(), op(), op()}},
+
+	/*          BP,       ABSO,     BPX,      ABSX,     BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* INC */ {{op(0xe6), op(0xee), op(0xf6), op(0xfe), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x1a), op(), op(), op(), op()}},
+
+	/*          BP,                 ABSO,               BPX,                ABSX,               BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,               IMME, IMMW, BB,   BBR,*/
+	/* INQ */ {{op(0x42,0x42,0xe6), op(0x42,0x42,0xee), op(0x42,0x42,0xf6), op(0x42,0x42,0xfe), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x42,0x42,0x1a), op(), op(), op(), op()}},
+
+	/*          BP,       ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL, IMME, IMMW, BB,   BBR,*/
+	/* INW */ {{op(0xe3), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* INX */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0xe8), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* INY */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0xc8), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* INZ */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x1b), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO,     BPX,  ABSX, BPY,  ABSY, BPIX, INDX,     RELA, RELW, BIND, INDI,     BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL, IMME, IMMW, BB,   BBR,*/
+	/* JMP */ {{op(), op(0x4c), op(), op(), op(), op(), op(), op(0x7c), op(), op(), op(), op(0x6c), op(), op(), op(), op(), op(), op(), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO,     BPX,  ABSX, BPY,  ABSY, BPIX, INDX,     RELA, RELW, BIND, INDI,     BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL, IMME, IMMW, BB,   BBR,*/
+	/* JSR */ {{op(), op(0x20), op(), op(), op(), op(), op(), op(0x23), op(), op(), op(), op(0x22), op(), op(), op(), op(), op(), op(), op(), op(), op(), op()}},
+
+	/*          BP,       ABSO,     BPX,      ABSX,     BPY,  ABSY,     BPIX,     INDX, RELA, RELW, BIND, INDI, BPIY,     BPIZ,     BIQ,  BIQZ,          SPIY,     IMPL, IMME,     IMMW, BB,   BBR,*/
+	/* LDA */ {{op(0xa5), op(0xad), op(0xb5), op(0xbd), op(), op(0xb9), op(0xa1), op(), op(), op(), op(), op(), op(0xb1), op(0xb2), op(), op(0xea,0xb2), op(0xe2), op(), op(0xa9), op(), op(), op()}},
+
+	/*          BP,                 ABSO,               BPX,                ABSX,               BPY,  ABSY,               BPIX, INDX, RELA, RELW, BIND,               INDI, BPIY,               BPIZ, BIQ,                     BIQZ, SPIY,               IMPL, IMME, IMMW, BB,   BBR,*/
+	/* LDQ */ {{op(0x42,0x42,0xa5), op(0x42,0x42,0xad), op(0x42,0x42,0xb5), op(0x42,0x42,0xbd), op(), op(0x42,0x42,0xb9), op(), op(), op(), op(), op(0x42,0x42,0xb2), op(), op(0x42,0x42,0xb1), op(), op(0x42,0x42,0xea,0xb2), op(), op(0x42,0x42,0xe2), op(), op(), op(), op(), op()}},
+
+	/*          BP,       ABSO,     BPX,  ABSX, BPY,      ABSY,     BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL, IMME,     IMMW, BB,   BBR,*/
+	/* LDX */ {{op(0xa6), op(0xae), op(), op(), op(0xb6), op(0xbe), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0xa2), op(), op(), op()}},
+
+	/*          BP,       ABSO,     BPX,      ABSX,     BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL, IMME,     IMMW, BB,   BBR,*/
+	/* LDY */ {{op(0xa4), op(0xac), op(0xb4), op(0xbc), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0xa0), op(), op(), op()}},
+
+	/*          BP,   ABSO,     BPX,  ABSX,     BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL, IMME,     IMMW, BB,   BBR,*/
+	/* LDZ */ {{op(), op(0xab), op(), op(0xbb), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0xa3), op(), op(), op()}},
+
+	/*          BP,       ABSO,     BPX,      ABSX,     BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* LSR */ {{op(0x46), op(0x4e), op(0x56), op(0x5e), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x4a), op(), op(), op(), op()}},
+
+	/*          BP,                 ABSO,               BPX,                ABSX,               BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,               IMME, IMMW, BB,   BBR,*/
+	/* LSRQ*/ {{op(0x42,0x42,0x46), op(0x42,0x42,0x4e), op(0x42,0x42,0x56), op(0x42,0x42,0x5e), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x42,0x42,0x4a), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* MAP */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x5c), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* NEG */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x42), op(), op(), op(), op()}},
+
+	/*          BP,       ABSO,     BPX,      ABSX,     BPY,  ABSY,     BPIX,     INDX, RELA, RELW, BIND, INDI, BPIY,     BPIZ,     BIQ,  BIQZ,          SPIY, IMPL, IMME,     IMMW, BB,   BBR,*/
+	/* ORA */ {{op(0x05), op(0x0d), op(0x15), op(0x1d), op(), op(0x19), op(0x01), op(), op(), op(), op(), op(), op(0x11), op(0x12), op(), op(0xea,0x12), op(), op(), op(0x09), op(), op(), op()}},
+
+	/*          BP,                 ABSO,               BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND,               INDI, BPIY, BPIZ, BIQ,                     BIQZ, SPIY, IMPL, IMME,               IMMW, BB,   BBR,*/
+	/* ORQ */ {{op(0x42,0x42,0x05), op(0x42,0x42,0x0d), op(), op(), op(), op(), op(), op(), op(), op(), op(0x42,0x42,0x12), op(), op(), op(), op(0x42,0x42,0xea,0x12), op(), op(), op(), op(0x42,0x42,0x09), op(), op(), op()}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* PHA */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x48), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* PHP */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x08), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO,     BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL, IMME, IMMW,     BB,   BBR,*/
+	/* PHW */ {{op(), op(0xfc), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0xf4), op(), op()}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* PHX */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0xda), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* PHY */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x5a), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* PHZ */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0xdb), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* PLA */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x68), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* PLP */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x28), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* PLX */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0xfa), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* PLY */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x7a), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* PLZ */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0xfb), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL, IMME, IMMW, BB,       BBR,*/
+	/* RMB */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x07), op()}},
+
+	/*          BP,       ABSO,     BPX,      ABSX,     BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* ROL */ {{op(0x26), op(0x2e), op(0x36), op(0x3e), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x2a), op(), op(), op(), op()}},
+
+	/*          BP,                 ABSO,               BPX,                ABSX,               BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,               IMME, IMMW, BB,   BBR,*/
+	/* ROLQ*/ {{op(0x42,0x42,0x26), op(0x42,0x42,0x2e), op(0x42,0x42,0x36), op(0x42,0x42,0x3e), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x42,0x42,0x2a), op(), op(), op(), op()}},
+
+	/*          BP,       ABSO,     BPX,      ABSX,     BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* ROR */ {{op(0x66), op(0x6e), op(0x76), op(0x7e), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x6a), op(), op(), op(), op()}},
+
+	/*          BP,                 ABSO,               BPX,                ABSX,               BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,               IMME, IMMW, BB,   BBR,*/
+	/* RORQ*/ {{op(0x42,0x42,0x66), op(0x42,0x42,0x6e), op(0x42,0x42,0x76), op(0x42,0x42,0x7e), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x42,0x42,0x6a), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO,     BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL, IMME, IMMW, BB,   BBR,*/
+	/* ROW */ {{op(), op(0xeb), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* RTI */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x40), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL, IMME,     IMMW, BB,   BBR,*/
+	/* RTN */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x62), op(), op(), op()}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* RTS */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x60), op(), op(), op(), op()}},
+
+	/*          BP,       ABSO,     BPX,      ABSX,     BPY,  ABSY,     BPIX,     INDX, RELA, RELW, BIND, INDI, BPIY,     BPIZ,     BIQ,  BIQZ,          SPIY, IMPL, IMME,     IMMW, BB,   BBR,*/
+	/* SBC */ {{op(0xe5), op(0xed), op(0xf5), op(0xfd), op(), op(0xf9), op(0xe1), op(), op(), op(), op(), op(), op(0xf1), op(0xf2), op(), op(0xea,0xf2), op(), op(), op(0xe9), op(), op(), op()}},
+
+	/*          BP,                 ABSO,               BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND,               INDI, BPIY, BPIZ, BIQ,                     BIQZ, SPIY, IMPL, IMME, IMMW, BB,   BBR,*/
+	/* SBCQ*/ {{op(0x42,0x42,0xe5), op(0x42,0x42,0xed), op(), op(), op(), op(), op(), op(), op(), op(), op(0x42,0x42,0xf2), op(), op(), op(), op(0x42,0x42,0xea,0xf2), op(), op(), op(), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* SEC */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x38), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* SED */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0xf8), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* SEE */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x03), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* SEI */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x78), op(), op(), op(), op()}},
+
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL, IMME, IMMW, BB,       BBR,*/
+	/* SMB */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x87), op()}},
+
+	/*          BP,       ABSO,     BPX,      ABSX,     BPY,  ABSY,     BPIX,     INDX, RELA, RELW, BIND, INDI, BPIY,     BPIZ,     BIQ,  BIQZ,          SPIY,     IMPL, IMME, IMMW, BB,   BBR,*/
+	/* STA */ {{op(0x85), op(0x8d), op(0x95), op(0x9d), op(), op(0x99), op(0x81), op(), op(), op(), op(), op(), op(0x91), op(0x92), op(), op(0xea,0x92), op(0x82), op(), op(), op(), op(), op()}},
+
+	/*          BP,                 ABSO,               BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND,               INDI, BPIY, BPIZ, BIQ,                     BIQZ, SPIY,               IMPL, IMME, IMMW, BB,   BBR,*/
+	/* STQ */ {{op(0x42,0x42,0x85), op(0x42,0x42,0x8d), op(), op(), op(), op(), op(), op(), op(), op(), op(0x42,0x42,0x92), op(), op(), op(), op(0x42,0x42,0xea,0x92), op(), op(0x42,0x42,0x82), op(), op(), op(), op(), op()}},
+
+	/*          BP,       ABSO,     BPX,  ABSX, BPY,      ABSY,     BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL, IMME, IMMW, BB,   BBR,*/
+	/* STX */ {{op(0x86), op(0x8e), op(), op(), op(0x96), op(0x9b), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op()}},
+	/*          BP,       ABSO,     BPX,      ABSX,     BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL, IMME, IMMW, BB,   BBR,*/
+	/* STY */ {{op(0x84), op(0x8c), op(0x94), op(0x8b), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op()}},
+	/*          BP,       ABSO,     BPX,      ABSX,     BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL, IMME, IMMW, BB,   BBR,*/
+	/* STZ */ {{op(0x64), op(0x9c), op(0x74), op(0x9e), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op()}},
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* TAB */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x5b), op(), op(), op(), op()}},
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* TAX */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0xaa), op(), op(), op(), op()}},
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* TAY */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0xa8), op(), op(), op(), op()}},
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* TAZ */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x4b), op(), op(), op(), op()}},
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* TBA */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x7b), op(), op(), op(), op()}},
+	/*          BP,       ABSO,     BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL, IMME, IMMW, BB,   BBR,*/
+	/* TRB */ {{op(0x14), op(0x1c), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op()}},
+	/*          BP,       ABSO,     BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL, IMME, IMMW, BB,   BBR,*/
+	/* TSB */ {{op(0x04), op(0x0c), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op()}},
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* TSX */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0xba), op(), op(), op(), op()}},
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* TSY */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x0b), op(), op(), op(), op()}},
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* TXA */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x8a), op(), op(), op(), op()}},
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* TXS */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x9a), op(), op(), op(), op()}},
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* TYA */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x98), op(), op(), op(), op()}},
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* TYS */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x2b), op(), op(), op(), op()}},
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* TZA */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x6b), op(), op(), op(), op()}},
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA,     RELW,     BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL, IMME, IMMW, BB,   BBR,*/
+	/* BHS */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(0xb0), op(0xb3), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op()}},
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA,     RELW,     BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL, IMME, IMMW, BB,   BBR,*/
+	/* BLT */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(0x90), op(0x93), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op()}},
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA,     RELW,     BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL, IMME, IMMW, BB,   BBR,*/
+	/* BRA */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(0x80), op(0x83), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op()}},
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* DEA */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x3a), op(), op(), op(), op()}},
+	/*          BP,   ABSO, BPX,  ABSX, BPY,  ABSY, BPIX, INDX, RELA, RELW, BIND, INDI, BPIY, BPIZ, BIQ,  BIQZ, SPIY, IMPL,     IMME, IMMW, BB,   BBR,*/
+	/* INA */ {{op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(), op(0x1a), op(), op(), op(), op()}},
+};
+
+InstructionType __inverse_branch_instruction[static_cast<int>(InstructionType::NumTypes)] = {
+	/* ADC */ InstructionType::Brk,
+	/* ADCQ*/ InstructionType::Brk,
+	/* AND */ InstructionType::Brk,
+	/* ANDQ*/ InstructionType::Brk,
+	/* ASL */ InstructionType::Brk,
+	/* ASLQ*/ InstructionType::Brk,
+	/* ASR */ InstructionType::Brk,
+	/* ASRQ*/ InstructionType::Brk,
+	/* ASW */ InstructionType::Brk,
+	/* BBR */ InstructionType::Brk,
+	/* BBS */ InstructionType::Brk,
+	/* BCC */ InstructionType::Bcs,
+	/* BCS */ InstructionType::Bcc,
+	/* BEQ */ InstructionType::Bne,
+	/* BIT */ InstructionType::Brk,
+	/* BITQ*/ InstructionType::Brk,
+	/* BMI */ InstructionType::Bpl,
+	/* BNE */ InstructionType::Beq,
+	/* BPL */ InstructionType::Bmi,
+	/* BRK */ InstructionType::Brk,
+	/* BRU */ InstructionType::Brk,
+	/* BSR */ InstructionType::Brk,
+	/* BVC */ InstructionType::Bvs,
+	/* BVS */ InstructionType::Bvc,
+	/* CLC */ InstructionType::Brk,
+	/* CLD */ InstructionType::Brk,
+	/* CLE */ InstructionType::Brk,
+	/* CLI */ InstructionType::Brk,
+	/* CLV */ InstructionType::Brk,
+	/* CMP */ InstructionType::Brk,
+	/* CMPQ*/ InstructionType::Brk,
+	/* CPX */ InstructionType::Brk,
+	/* CPY */ InstructionType::Brk,
+	/* CPZ */ InstructionType::Brk,
+	/* DEC */ InstructionType::Brk,
+	/* DEQ */ InstructionType::Brk,
+	/* DEW */ InstructionType::Brk,
+	/* DEX */ InstructionType::Brk,
+	/* DEY */ InstructionType::Brk,
+	/* DEZ */ InstructionType::Brk,
+	/* EOM */ InstructionType::Brk,
+	/* EOR */ InstructionType::Brk,
+	/* EORQ*/ InstructionType::Brk,
+	/* INC */ InstructionType::Brk,
+	/* INQ */ InstructionType::Brk,
+	/* INW */ InstructionType::Brk,
+	/* INX */ InstructionType::Brk,
+	/* INY */ InstructionType::Brk,
+	/* INZ */ InstructionType::Brk,
+	/* JMP */ InstructionType::Brk,
+	/* JSR */ InstructionType::Brk,
+	/* LDA */ InstructionType::Brk,
+	/* LDQ */ InstructionType::Brk,
+	/* LDX */ InstructionType::Brk,
+	/* LDY */ InstructionType::Brk,
+	/* LDZ */ InstructionType::Brk,
+	/* LSR */ InstructionType::Brk,
+	/* LSRQ*/ InstructionType::Brk,
+	/* MAP */ InstructionType::Brk,
+	/* NEG */ InstructionType::Brk,
+	/* ORA */ InstructionType::Brk,
+	/* ORQ */ InstructionType::Brk,
+	/* PHA */ InstructionType::Brk,
+	/* PHP */ InstructionType::Brk,
+	/* PHW */ InstructionType::Brk,
+	/* PHX */ InstructionType::Brk,
+	/* PHY */ InstructionType::Brk,
+	/* PHZ */ InstructionType::Brk,
+	/* PLA */ InstructionType::Brk,
+	/* PLP */ InstructionType::Brk,
+	/* PLX */ InstructionType::Brk,
+	/* PLY */ InstructionType::Brk,
+	/* PLZ */ InstructionType::Brk,
+	/* RMB */ InstructionType::Brk,
+	/* ROL */ InstructionType::Brk,
+	/* ROLQ*/ InstructionType::Brk,
+	/* ROR */ InstructionType::Brk,
+	/* RORQ*/ InstructionType::Brk,
+	/* RTI */ InstructionType::Brk,
+	/* RTN */ InstructionType::Brk,
+	/* RTS */ InstructionType::Brk,
+	/* SBC */ InstructionType::Brk,
+	/* SBCQ*/ InstructionType::Brk,
+	/* SEC */ InstructionType::Brk,
+	/* SED */ InstructionType::Brk,
+	/* SEI */ InstructionType::Brk,
+	/* SMB */ InstructionType::Brk,
+	/* STA */ InstructionType::Brk,
+	/* STQ */ InstructionType::Brk,
+	/* STX */ InstructionType::Brk,
+	/* STY */ InstructionType::Brk,
+	/* STZ */ InstructionType::Brk,
+	/* TAB */ InstructionType::Brk,
+	/* TAX */ InstructionType::Brk,
+	/* TAY */ InstructionType::Brk,
+	/* TAZ */ InstructionType::Brk,
+	/* TBA */ InstructionType::Brk,
+	/* TRB */ InstructionType::Brk,
+	/* TSB */ InstructionType::Brk,
+	/* TSX */ InstructionType::Brk,
+	/* TSY */ InstructionType::Brk,
+	/* TXA */ InstructionType::Brk,
+	/* TXS */ InstructionType::Brk,
+	/* TYA */ InstructionType::Brk,
+	/* TYS */ InstructionType::Brk,
+	/* TZA */ InstructionType::Brk,
+
+	/* BHS */ InstructionType::Blt,
+	/* BLT */ InstructionType::Bhs,
+	/* BRA */ InstructionType::Brk,
+	/* DEA */ InstructionType::Brk,
+	/* INA */ InstructionType::Brk,
+};
+
+uint32_t addressing_modes(InstructionType instruction)
+{
+	assert(instruction < InstructionType::NumTypes);
+	return __addressing_modes_mask[static_cast<int>(instruction)];
+}
+
+OpCode opcode(InstructionType instruction, AddressingModeType addr_mode)
+{
+	assert(instruction < InstructionType::NumTypes);
+	assert(addr_mode < AddressingModeType::NumAddressingModes);
+	return __opcodes[static_cast<int>(instruction)].op_codes[static_cast<int>(addr_mode)];
+}
+
+InstructionType inverse_branch(InstructionType instruction)
+{
+	assert(instruction < InstructionType::NumTypes);
+	return __inverse_branch_instruction[static_cast<int>(instruction)];
+}
+
+bool is_ending_instruction(InstructionType type)
+{
+	return
+		   type == InstructionType::Brk
+		|| type == InstructionType::Bru
+		|| type == InstructionType::Bra
+		|| type == InstructionType::Jmp
+		|| type == InstructionType::Rti
+		|| type == InstructionType::Rts;
+}
+
+std::string_view to_string(AddressingModeType type)
+{
+	const static std::string_view names[] = {
+		std::string_view("base page address"),
+		std::string_view("absolute address"),
+		std::string_view("base page address with x offset"),
+		std::string_view("absolute address with x offset"),
+		std::string_view("base page address with y offset"),
+		std::string_view("absolute address with y offset"),
+		std::string_view("indirect base page address with x offset"),
+		std::string_view("indirect absolute address with x offset"),
+		std::string_view("byte relative address"),
+		std::string_view("word relative address"),
+		std::string_view("indirect base page address"),
+		std::string_view("indirect absolute address"),
+		std::string_view("indirect base page address with y offset"),
+		std::string_view("indirect base page address with z offset"),
+		std::string_view("indirect base page quad address"),
+		std::string_view("indirect base page quad address with z offset"),
+		std::string_view("indirect stack page address with y offset"),
+		std::string_view("implied"),
+		std::string_view("immediate"),
+		std::string_view("immediate word"),
+		std::string_view("bit, base page"),
+		std::string_view("bit, base page, relative"),
+	};
+	static_assert(sizeof(names) / sizeof(names[0]) == static_cast<size_t>(AddressingModeType::NumAddressingModes), "Number of addressing modes doesn't match number of strings");
+
+	assert(type < AddressingModeType::NumAddressingModes);
+	return names[static_cast<size_t>(type)];
+}
+
+std::string_view to_string(InstructionType type)
+{
+	static const std::string_view names[] = {
+		std::string_view("adc"),
+		std::string_view("adcq"),
+		std::string_view("and"),
+		std::string_view("andq"),
+		std::string_view("asl"),
+		std::string_view("aslq"),
+		std::string_view("asr"),
+		std::string_view("asrq"),
+		std::string_view("asw"),
+		std::string_view("bbr"),
+		std::string_view("bbs"),
+		std::string_view("bcc"),
+		std::string_view("bcs"),
+		std::string_view("beq"),
+		std::string_view("bit"),
+		std::string_view("bitq"),
+		std::string_view("bmi"),
+		std::string_view("bne"),
+		std::string_view("bpl"),
+		std::string_view("brk"),
+		std::string_view("bru"),
+		std::string_view("bsr"),
+		std::string_view("bvc"),
+		std::string_view("bvs"),
+		std::string_view("clc"),
+		std::string_view("cld"),
+		std::string_view("cle"),
+		std::string_view("cli"),
+		std::string_view("clv"),
+		std::string_view("cmp"),
+		std::string_view("cmpq"),
+		std::string_view("cpx"),
+		std::string_view("cpy"),
+		std::string_view("cpz"),
+		std::string_view("dec"),
+		std::string_view("deq"),
+		std::string_view("dew"),
+		std::string_view("dex"),
+		std::string_view("dey"),
+		std::string_view("dez"),
+		std::string_view("eom"),
+		std::string_view("eor"),
+		std::string_view("eorq"),
+		std::string_view("inc"),
+		std::string_view("inq"),
+		std::string_view("inw"),
+		std::string_view("inx"),
+		std::string_view("iny"),
+		std::string_view("inz"),
+		std::string_view("jmp"),
+		std::string_view("jsr"),
+		std::string_view("lda"),
+		std::string_view("ldq"),
+		std::string_view("ldx"),
+		std::string_view("ldy"),
+		std::string_view("ldz"),
+		std::string_view("lsr"),
+		std::string_view("lsrq"),
+		std::string_view("map"),
+		std::string_view("neg"),
+		std::string_view("ora"),
+		std::string_view("orq"),
+		std::string_view("pha"),
+		std::string_view("php"),
+		std::string_view("phw"),
+		std::string_view("phx"),
+		std::string_view("phy"),
+		std::string_view("phz"),
+		std::string_view("pla"),
+		std::string_view("plp"),
+		std::string_view("plx"),
+		std::string_view("ply"),
+		std::string_view("plz"),
+		std::string_view("rmb"),
+		std::string_view("rol"),
+		std::string_view("rolq"),
+		std::string_view("ror"),
+		std::string_view("rorq"),
+		std::string_view("row"),
+		std::string_view("rti"),
+		std::string_view("rtn"),
+		std::string_view("rts"),
+		std::string_view("sbc"),
+		std::string_view("sbcq"),
+		std::string_view("sec"),
+		std::string_view("sed"),
+		std::string_view("see"),
+		std::string_view("sei"),
+		std::string_view("smb"),
+		std::string_view("sta"),
+		std::string_view("stq"),
+		std::string_view("stx"),
+		std::string_view("sty"),
+		std::string_view("stz"),
+		std::string_view("tab"),
+		std::string_view("tax"),
+		std::string_view("tay"),
+		std::string_view("taz"),
+		std::string_view("tba"),
+		std::string_view("trb"),
+		std::string_view("tsb"),
+		std::string_view("tsx"),
+		std::string_view("tsy"),
+		std::string_view("txa"),
+		std::string_view("txs"),
+		std::string_view("tya"),
+		std::string_view("tys"),
+		std::string_view("tza"),
+
+		std::string_view("bhs"),
+		std::string_view("blt"),
+		std::string_view("bra"),
+		std::string_view("dea"),
+		std::string_view("ina"),
+	};
+	static_assert(sizeof(names) / sizeof(names[0]) == static_cast<size_t>(InstructionType::NumTypes), "Number of instructions doesn't match number of strings");
+
+	assert(type < InstructionType::NumTypes);
+	return names[static_cast<size_t>(type)];
+}
+
+	} // namespace mega45gs02
+} // namespace jasm

          
A => jasm/processor/45gs02/instructions_45gs02.h +251 -0
@@ 0,0 1,251 @@ 
+#pragma once
+
+#include <processor/instructions_common.h>
+
+namespace jasm
+{
+	namespace mega45gs02
+	{
+	
+/// @addtogroup assemble
+/// @{
+
+enum class InstructionType : uint8_t
+{
+	Adc,
+	Adcq,
+	And,
+	Andq,
+	Asl,
+	Aslq,
+	Asr,
+	Asrq,
+	Asw,
+	Bbr,
+	Bbs,
+	Bcc,
+	Bcs,
+	Beq,
+	Bit,
+	Bitq,
+	Bmi,
+	Bne,
+	Bpl,
+	Brk,
+	Bru,
+	Bsr,
+	Bvc,
+	Bvs,
+	Clc,
+	Cld,
+	Cle,
+	Cli,
+	Clv,
+	Cmp,
+	Cmpq,
+	Cpx,
+	Cpy,
+	Cpz,
+	Dec,
+	Deq,
+	Dew,
+	Dex,
+	Dey,
+	Dez,
+	Eom,
+	Eor,
+	Eorq,
+	Inc,
+	Inq,
+	Inw,
+	Inx,
+	Iny,
+	Inz,
+	Jmp,
+	Jsr,
+	Lda,
+	Ldq,
+	Ldx,
+	Ldy,
+	Ldz,
+	Lsr,
+	Lsrq,
+	Map,
+	Neg,
+	Ora,
+	Orq,
+	Pha,
+	Php,
+	Phw,
+	Phx,
+	Phy,
+	Phz,
+	Pla,
+	Plp,
+	Plx,
+	Ply,
+	Plz,
+	Rmb,
+	Rol,
+	Rolq,
+	Ror,
+	Rorq,
+	Row,
+	Rti,
+	Rtn,
+	Rts,
+	Sbc,
+	Sbcq,
+	Sec,
+	Sed,
+	See,
+	Sei,
+	Smb,
+	Sta,
+	Stq,
+	Stx,
+	Sty,
+	Stz,
+	Tab,
+	Tax,
+	Tay,
+	Taz,
+	Tba,
+	Trb,
+	Tsb,
+	Tsx,
+	Tsy,
+	Txa,
+	Txs,
+	Tya,
+	Tys,
+	Tza,
+	// end of standard instructions
+	Bhs, // branch if higher or same
+	NumStandard = Bhs,
+	Blt, // branch if less than
+	Bra, // BRU
+	Dea, // DEC A
+	Ina, // INC A
+	
+	NumTypes,
+};
+
+enum class AddressingModeType
+{
+	// these must be in base-page-non-base-page order
+	// because the instruction generation relies on it
+	BasePageAddr,
+	AbsoluteAddr,
+	BasePageIndexX,
+	AbsoluteIndexX,
+	BasePageIndexY,
+	AbsoluteIndexY,
+	BasePageIndirectIndexX,
+	AbsoluteIndirectIndexX,
+	RelativeAddr,
+	RelativeWordAddr,
+	BasePageIndirect,
+	AbsoluteIndirect,
+
+	BasePageIndirectIndexY,
+	BasePageIndirectIndexZ,
+	BasePageIndirectQuad,
+	BasePageIndirectQuadIndexZ,
+	StackIndirectIndexY,
+	Implied,
+	Immediate,
+	ImmediateWord,
+	BitBp,
+	BitBpRel,
+
+	NumAddressingModes,
+};
+
+// fake enum to be able to shorten the table in the cpp file
+namespace AddressingModeMask
+{
+	enum
+	{
+		Bp = 1 << static_cast<int>(AddressingModeType::BasePageAddr),
+		Abs = 1 << static_cast<int>(AddressingModeType::AbsoluteAddr),
+		Bpx = 1 << static_cast<int>(AddressingModeType::BasePageIndexX),
+		AbsX = 1 << static_cast<int>(AddressingModeType::AbsoluteIndexX),
+		Bpy = 1 << static_cast<int>(AddressingModeType::BasePageIndexY),
+		AbsY = 1 << static_cast<int>(AddressingModeType::AbsoluteIndexY),
+		BpIX = 1 << static_cast<int>(AddressingModeType::BasePageIndirectIndexX),
+		IndX = 1 << static_cast<int>(AddressingModeType::AbsoluteIndirectIndexX),
+		Rel = 1 << static_cast<int>(AddressingModeType::RelativeAddr),
+		RelW = 1 << static_cast<int>(AddressingModeType::RelativeWordAddr),
+		BInd = 1 << static_cast<int>(AddressingModeType::BasePageIndirect),
+		Ind = 1 << static_cast<int>(AddressingModeType::AbsoluteIndirect),
+		
+		BpIY = 1 << static_cast<int>(AddressingModeType::BasePageIndirectIndexY),
+		BpIZ = 1 << static_cast<int>(AddressingModeType::BasePageIndirectIndexZ),
+		BIQ = 1 << static_cast<int>(AddressingModeType::BasePageIndirectQuad),
+		BIQZ = 1 << static_cast<int>(AddressingModeType::BasePageIndirectQuadIndexZ),
+		SpIY = 1 << static_cast<int>(AddressingModeType::StackIndirectIndexY),
+		Imp = 1 << static_cast<int>(AddressingModeType::Implied),
+		Imm = 1 << static_cast<int>(AddressingModeType::Immediate),
+		ImmW = 1 << static_cast<int>(AddressingModeType::ImmediateWord),
+		Bb = 1 << static_cast<int>(AddressingModeType::BitBp),
+		Bbr = 1 << static_cast<int>(AddressingModeType::BitBpRel),
+		
+		__ = 0,
+		___ = 0,
+		____ = 0,
+	};
+}
+
+struct OpCode
+{
+	uint8_t size;
+	uint8_t opcode[7];
+};
+
+/// Select the byte mode version of a combined byte and word mode addressing mode.
+inline uint32_t select_byte_mode(uint32_t a)
+{
+	return static_cast<uint32_t>(a & 0b010101010101);
+}
+
+/// Select the word mode version of a combined byte and word mode addressing mode.
+inline uint32_t select_word_mode(uint32_t a)
+{
+	return static_cast<uint32_t>(a & 0b101010101010);
+}
+
+/// Convert a bitmask with one bit set to an addressing mode.
+inline AddressingModeType mask_to_addressing_mode(uint32_t mask)
+{
+	int result = 0;
+	result += ((mask & 0b11111111111111110000000000000000) != 0) ? 16 : 0;
+	result += ((mask & 0b11111111000000001111111100000000) != 0) ? 8 : 0;
+	result += ((mask & 0b11110000111100001111000011110000) != 0) ? 4 : 0;
+	result += ((mask & 0b11001100110011001100110011001100) != 0) ? 2 : 0;
+	result += ((mask & 0b10101010101010101010101010101010) != 0) ? 1 : 0;
+	return static_cast<AddressingModeType>(result);
+}
+
+/// Get the addressing mode mask with bits set for each AddressingModeTypes value.
+uint32_t addressing_modes(InstructionType instruction);
+
+/// Returns the opcode for an instruction and addressing mode.
+OpCode opcode(InstructionType instruction, AddressingModeType addr_mode);
+
+/// Returns the instruction for the opposite branch instruction.
+/// Call it with bcc and get bcs for example.
+InstructionType inverse_branch(InstructionType instruction);
+
+/// Returns true if the instruction doesn't provide a fall-through branch.
+bool is_ending_instruction(InstructionType type);
+
+/// Convert an addressing mode to a string for printing.
+std::string_view to_string(AddressingModeType type);
+
+std::string_view to_string(InstructionType type);
+
+/// @}
+
+	} // namespace mega45gs02
+} // namespace jasm

          
A => jasm/processor/45gs02/processor_45gs02.cpp +1164 -0
@@ 0,0 1,1164 @@ 
+#include "pch.h"
+
+#include <algorithm>
+#include <assemble/assembler_impl/assembler_impl.h>
+#include <assemble/scope_counter.h>
+#include <exceptions/assembly_exception.h>
+#include <io/hex_source_writer.h>
+#include <processor/45gs02/processor_45gs02.h>
+#include <processor/45gs02/processor_keywords_45gs02.h>
+#include <sstream>
+#include <syntax/syntax_parser.h>
+#include <syntax/syntax_tokens.h>
+#include <tokenize/tokens.h>
+
+namespace jasm
+{
+	namespace mega45gs02
+	{
+
+namespace
+{
+	enum
+	{
+		Bp = 1 << static_cast<int>(AddressingModeType::BasePageAddr),
+		Abs = 1 << static_cast<int>(AddressingModeType::AbsoluteAddr),
+		Bpx = 1 << static_cast<int>(AddressingModeType::BasePageIndexX),
+		AbsX = 1 << static_cast<int>(AddressingModeType::AbsoluteIndexX),
+		Bpy = 1 << static_cast<int>(AddressingModeType::BasePageIndexY),
+		AbsY = 1 << static_cast<int>(AddressingModeType::AbsoluteIndexY),
+		BpIX = 1 << static_cast<int>(AddressingModeType::BasePageIndirectIndexX),
+		IndX = 1 << static_cast<int>(AddressingModeType::AbsoluteIndirectIndexX),
+		Rel = 1 << static_cast<int>(AddressingModeType::RelativeAddr),
+		RelW = 1 << static_cast<int>(AddressingModeType::RelativeWordAddr),
+		BInd = 1 << static_cast<int>(AddressingModeType::BasePageIndirect),
+		Ind = 1 << static_cast<int>(AddressingModeType::AbsoluteIndirect),
+		
+		BpIY = 1 << static_cast<int>(AddressingModeType::BasePageIndirectIndexY),
+		BpIZ = 1 << static_cast<int>(AddressingModeType::BasePageIndirectIndexZ),
+		BIQ = 1 << static_cast<int>(AddressingModeType::BasePageIndirectQuad),
+		BIQZ = 1 << static_cast<int>(AddressingModeType::BasePageIndirectQuadIndexZ),
+		SpIY = 1 << static_cast<int>(AddressingModeType::StackIndirectIndexY),
+		Imp = 1 << static_cast<int>(AddressingModeType::Implied),
+		Imm = 1 << static_cast<int>(AddressingModeType::Immediate),
+		ImmW = 1 << static_cast<int>(AddressingModeType::ImmediateWord),
+		Bb = 1 << static_cast<int>(AddressingModeType::BitBp),
+		Bbr = 1 << static_cast<int>(AddressingModeType::BitBpRel),
+	};
+}
+
+struct InstructionToken : public SyntaxToken
+{
+	InstructionType instruction;
+	uint8_t padding1[3];
+	uint32_t addressing_modes; ///< Mask with InstructionType bits set for each possible addressing mode.
+	// 8 byte aligned
+	SourceLocation source_location; ///< Source location to instruction.
+	SourceLocation address_label_location[3]; ///< Source location to address label, if existing.
+	// 8 byte aligned
+	bool has_instruction_data_label[3]; ///< True if there is a label defined that points to the instruction data.
+	bool global_data_label[3]; ///< True if the label is global.
+	uint8_t padding2[2];
+	// 8 byte aligned
+	uint64_t data_label_symbol_hash[3]; ///< Symbol to define as the data label.
+	// 8 byte aligned
+};
+
+void Processor45gs02::register_processor_keywords(std::vector<std::string> &keywords)
+{
+	add_type_tokens<ProcessorKeywordType>(keywords, TokenType::ProcessorKeyword);
+}
+
+void Processor45gs02::register_processor_instructions(bool pseudo_instructions)
+{
+	// generate instruction lookup
+	uint8_t num_instructions = static_cast<uint8_t>(pseudo_instructions ? InstructionType::NumTypes : InstructionType::NumStandard);
+	for (uint8_t i = 0; i < num_instructions; ++i) {
+		const std::string_view name = to_string(static_cast<InstructionType>(i));
+		_instructions.insert(core::murmur_hash3_string_x64_64(name)) = i;
+	}
+}
+
+bool Processor45gs02::allow_processor_keyword_with_prim(uint64_t &/*keyword_hash*/) const
+{
+	// no prim translation
+	return false;
+}
+
+std::string Processor45gs02::token_to_string(const Token &t) const
+{
+	std::stringstream ss;
+	if (jasm::is_instruction(t)) {
+		ss << "instruction";
+	} else {
+		ss << to_string(t.type);
+	}
+
+	switch (t.type) {
+	case TokenType::Whitespace:
+	case TokenType::Char:
+	case TokenType::Integer:
+	case TokenType::Float:
+	case TokenType::String:
+	case TokenType::End:
+	case TokenType::Newline:
+	case TokenType::Processor:
+	case TokenType::NumTypes:
+		break;
+
+	case TokenType::Symbol:
+	{
+		if (t.instruction_index != invalid_instruction) {
+			ss << " " << to_string(static_cast<InstructionType>(t.instruction_index));
+		}
+		break;
+	}
+
+	case TokenType::Boolean:
+		ss << " " << to_string(t.boolean_index);
+		break;
+
+	case TokenType::Operator:
+		ss << " " << to_string(t.operator_index);
+		break;
+
+	case TokenType::Keyword:
+		ss << " " << to_string(t.keyword_index);
+		break;
+
+	case TokenType::ProcessorKeyword:
+		ss << " " << to_string(static_cast<ProcessorKeywordType>(t.processor_keyword_index));
+		break;
+
+	case TokenType::Typename:
+		ss << " " << to_string(t.typename_index);
+		break;
+	}
+	return ss.str();
+}
+
+
+const Token *Processor45gs02::parse_optional_arg_label(SyntaxParser &parser, const Token *t, ArgLabel &label) const
+{
+	t = parser.skip_spaces_and_tabs(t);
+	if (parser.label_definition_follows(t)) {
+		label.enabled = true;
+		label.location = t->source_location;
+
+		t = parser.parse_symbol_definition(t, label.global, label.symbol_hash);
+		t = parser.consume_next_token(); // the colon
+		t = parser.skip_spaces_and_tabs(t);
+	}
+	return t;
+}
+
+const Token *Processor45gs02::skip_optional_arg_label(SyntaxParser &parser, const Token *t, const ArgLabel &label) const
+{
+	t = parser.skip_spaces_and_tabs(t);
+	if (label.enabled) {
+		bool global = false;
+		uint64_t hash = 0;
+		t = parser.parse_symbol_definition(t, global, hash);
+		t = parser.consume_next_token(); // the colon
+		t = parser.skip_spaces_and_tabs(t);
+	}
+	return t;
+}
+
+uint32_t Processor45gs02::try_parse_addressing_mode(SyntaxParser &parser, const std::vector<std::string> &source_files, const Token *t, std::array<ArgLabel, 3> &arg_labels) const
+{
+	// save read state to restore later since we are reading ahead.
+	TokenChainScope rewind_scope(parser.create_rewind_scope());
+
+	t = parse_optional_arg_label(parser, t, arg_labels[0]);
+
+	if (parser.is_operator(t, OperatorType::Hash)) {
+		// #...
+		// Immediate
+		// ImmediateWord
+		return
+			1 << static_cast<int>(AddressingModeType::Immediate) |
+			1 << static_cast<int>(AddressingModeType::ImmediateWord);
+	}
+
+	if (parser.is_operator(t, OperatorType::LeftParenthesis)) {
+		// (<something>
+		// possibly indirect addressing mode but could also be an expression beginning with parenthesis
+		// BasePageAddr
+		// AbsoluteAddr
+		// BasePageIndexX
+		// AbsoluteIndexX
+		// BasePageIndexY
+		// AbsoluteIndexY
+		// BasePageIndirectIndexX
+		// AbsoluteIndirectIndexX
+		// RelativeAddr
+		// RelativeWordAddr
+		// BasePageIndirectIndexY
+		// BasePageIndirectIndexZ
+		// StackIndirectIndexY
+		// BasePageIndirect
+		// AbsoluteIndirect
+		// BitBp
+		// BitBpRel
+
+		// Try to parse an expression, ignoring the first parenthesis. That makes it possible to see
+		// if there is a comma within the parenthesis. This is not optimal for performance because
+		// it does more than it needs to for this.
+		const Token *next;
+		{
+			constexpr bool end_at_unmatched_right_parenthesis = true;
+			constexpr bool end_at_newline = true;
+			next = parser.parse_expression(parser.consume_next_token(), end_at_unmatched_right_parenthesis, end_at_newline);
+		}
+		if (parser.is_operator(next, OperatorType::Comma)) {
+			// (<expression>,
+			// BasePageIndirectIndexX
+			// AbsoluteIndirectIndexX
+			// StackIndirectIndexY
+
+			next = parser.consume_next_token(); // comma
+			next = parser.skip_spaces_and_tabs(next);
+
+			// check if "sp" follows
+			if (next->type == TokenType::ProcessorKeyword && static_cast<ProcessorKeywordType>(next->processor_keyword_index) == ProcessorKeywordType::SP) {
+				// (<expression>,sp
+				next = parser.consume_next_token(); // sp
+				next = parser.skip_spaces_and_tabs(next);
+				
+				if (next->type != TokenType::Operator || next->operator_index != OperatorType::RightParenthesis) {
+					std::stringstream ss;
+					ss << "Expected closing parenthesis in indirect addressing mode, but got " << token_to_string(*next);
+					throw AssemblyException(source_files, next->source_location, AssemblyErrorCodes::ExpectedEndingParenthesisInIndirectAddressingMode, ss.str());
+				}
+				// (<expression>,sp)
+				next = parser.consume_next_token(); // )
+				next = parser.parse_operator_on_same_line(next, OperatorType::Comma);
+				// (<expression>,sp),
+				next = parser.skip_spaces_and_tabs(next);
+				
+				// verify that "y" follows
+				if (next->type != TokenType::ProcessorKeyword || static_cast<ProcessorKeywordType>(next->processor_keyword_index) != ProcessorKeywordType::Y) {
+					std::stringstream ss;
+					ss << "Expected y for stack indirect addressing mode, but got " << token_to_string(*next);
+					throw AssemblyException(source_files, next->source_location, AssemblyErrorCodes::InvalidIndexRegisterInAddressingMode, ss.str());
+				}
+
+				return 1 << static_cast<int>(AddressingModeType::StackIndirectIndexY);
+			}
+			
+			// verify that "x" follows
+			if (next->type != TokenType::ProcessorKeyword || static_cast<ProcessorKeywordType>(next->processor_keyword_index) != ProcessorKeywordType::X) {
+				std::stringstream ss;
+				ss << "Expected x or sp for indirect addressing mode, but got " << token_to_string(*next);
+				throw AssemblyException(source_files, next->source_location, AssemblyErrorCodes::InvalidIndexRegisterInAddressingMode, ss.str());
+			}
+			// (<expression>,x
+
+			// verify that right parenthesis follows
+			next = parser.skip_spaces_and_tabs(parser.consume_next_token());
+			if (next->type != TokenType::Operator || next->operator_index != OperatorType::RightParenthesis) {
+				std::stringstream ss;
+				ss << "Expected closing parenthesis in indirect addressing mode, but got " << token_to_string(*next);
+				throw AssemblyException(source_files, next->source_location, AssemblyErrorCodes::ExpectedEndingParenthesisInIndirectAddressingMode, ss.str());
+			}
+			// (<expression>,x)
+
+			return
+				1 << static_cast<int>(AddressingModeType::BasePageIndirectIndexX) |
+				1 << static_cast<int>(AddressingModeType::AbsoluteIndirectIndexX);
+		}
+
+		if (parser.is_operator(next, OperatorType::RightParenthesis)) {
+			// (<expression>)...
+			// BasePageAddr
+			// AbsoluteAddr
+			// BasePageIndexX
+			// AbsoluteIndexX
+			// BasePageIndexY
+			// AbsoluteIndexY
+			// RelativeAddr
+			// RelativeWordAddr
+			// BasePageIndirectIndexY
+			// BasePageIndirectIndexZ
+			// BasePageIndirect
+			// AbsoluteIndirect
+			// BitBp
+			// BitBpRel
+
+			next = parser.skip_spaces_and_tabs(parser.consume_next_token());
+
+			if (next->type == TokenType::Operator && next->operator_index < OperatorType::NumOperatorFunctions) {
+				// (<expression>)<operator>
+				// BasePageAddr
+				// AbsoluteAddr
+				// BasePageIndexX
+				// AbsoluteIndexX
+				// BasePageIndexY
+				// AbsoluteIndexY
+				// RelativeAddr
+				// RelativeWordAddr
+				// BitBp
+				// BitBpRel
+
+				// go back and parse the whole thing to get to the end of the expression and check if it ends
+				// with ,x or ,y or ,something. This is not optimal from a performance perspective. I could write
+				// specialized code to skip an expression.
+				rewind_scope.rewind();
+				{
+					constexpr bool end_at_unmatched_right_parenthesis = false;
+					constexpr bool end_at_newline = true;
+					next = parser.parse_expression(t, end_at_unmatched_right_parenthesis, end_at_newline);
+				}
+
+				if (parser.is_operator(next, OperatorType::Comma)) {
+					// <expression>,
+					// BasePageIndexX
+					// AbsoluteIndexX
+					// BasePageIndexY
+					// AbsoluteIndexY
+					// BitBp
+					// BitBpRel
+					next = parser.skip_spaces_and_tabs(parser.consume_next_token());
+					if (next->type == TokenType::ProcessorKeyword && static_cast<ProcessorKeywordType>(next->processor_keyword_index) == ProcessorKeywordType::X) {
+						// <expression>,x
+						// BasePageIndexX
+						// AbsoluteIndexX
+						return
+							1 << static_cast<int>(AddressingModeType::BasePageIndexX) |
+							1 << static_cast<int>(AddressingModeType::AbsoluteIndexX);
+					}
+					if (next->type == TokenType::ProcessorKeyword && static_cast<ProcessorKeywordType>(next->processor_keyword_index) == ProcessorKeywordType::Y) {
+						// <expression>,y
+						// BasePageIndexY
+						// AbsoluteIndexY
+						return
+							1 << static_cast<int>(AddressingModeType::BasePageIndexY) |
+							1 << static_cast<int>(AddressingModeType::AbsoluteIndexY);
+					}
+					// <expression>, <expression>...
+					// BitBp
+					// BitBpRel
+					next = parse_optional_arg_label(parser, next, arg_labels[1]);
+					{
+						constexpr bool end_at_unmatched_right_parenthesis = false;
+						constexpr bool end_at_newline = true;
+						next = parser.parse_expression(next, end_at_unmatched_right_parenthesis, end_at_newline);
+					}
+					if (parser.is_operator(next, OperatorType::Comma)) {
+						// <expression>, <expression>, <expression>
+						// BitBpRel
+						next = parser.consume_next_token(); // comma
+						next = parse_optional_arg_label(parser, next, arg_labels[2]);
+						return 1 << static_cast<int>(AddressingModeType::BitBpRel);
+					}
+					
+					// <expression>, <expression>
+					// BitZp
+					return 1 << static_cast<int>(AddressingModeType::BitBp);
+				}
+				// (<expression>)<operator><expression>
+				// BasePageAddr
+				// AbsoluteAddr
+				// RelativeAddr
+				// RelativeWordAddr
+				return
+					1 << static_cast<int>(AddressingModeType::BasePageAddr) |
+					1 << static_cast<int>(AddressingModeType::AbsoluteAddr) |
+					1 << static_cast<int>(AddressingModeType::RelativeAddr) |
+					1 << static_cast<int>(AddressingModeType::RelativeWordAddr);
+			}
+			if (parser.is_operator(next, OperatorType::Comma)) {
+				// (<expression>),
+				// BasePageIndirectIndexY
+				// BasePageIndirectIndexZ
+
+				next = parser.skip_spaces_and_tabs(parser.consume_next_token());
+				if (next->type == TokenType::ProcessorKeyword && static_cast<ProcessorKeywordType>(next->processor_keyword_index) == ProcessorKeywordType::Y) {
+					// (<expression>),y
+					// BasePageIndirectIndexY
+					return 1 << static_cast<int>(AddressingModeType::BasePageIndirectIndexY);
+				}
+				if (next->type == TokenType::ProcessorKeyword && static_cast<ProcessorKeywordType>(next->processor_keyword_index) == ProcessorKeywordType::Z) {
+					// (<expression>),z
+					// BasePageIndirectIndexZ
+					return 1 << static_cast<int>(AddressingModeType::BasePageIndirectIndexZ);
+				}
+				// the index register is invalid
+				std::stringstream ss;
+				ss << "Invalid index register in addressing mode. Expected y or z but got " << token_to_string(*next);
+				throw AssemblyException(source_files, next->source_location, AssemblyErrorCodes::InvalidIndexRegisterInAddressingMode, ss.str());
+			}
+			// (<expression>)
+			// BasePageIndirect
+			// AbsoluteIndirect
+			return
+				1 << static_cast<int>(AddressingModeType::BasePageIndirect) |
+				1 << static_cast<int>(AddressingModeType::AbsoluteIndirect);
+		}
+
+		// no matching parenthesis was found
+		std::stringstream ss;
+		ss << "Unmatched left parenthesis in expression";
+		throw AssemblyException(source_files, t->source_location, AssemblyErrorCodes::UnmatchedLeftParenthesis, ss.str());
+	}
+	
+	if (parser.is_operator(t, OperatorType::LeftBracket)) {
+		// [...
+		// BasePageIndirectQuad
+		// BasePageIndirectQuadIndexZ
+		t =  parser.consume_next_token(); // bracket
+		{
+			constexpr bool end_at_unmatched_right_parenthesis = true;
+			constexpr bool end_at_newline = true;
+			t = parser.parse_expression(t, end_at_unmatched_right_parenthesis, end_at_newline);
+		}
+		t = parser.parse_operator_on_same_line(t, OperatorType::RightBracket);
+		t = parser.skip_spaces_and_tabs(t);
+		if (parser.is_operator(t, OperatorType::Comma)) {
+			// [expression],...
+			// BasePageIndirectQuadIndexZ
+			t =  parser.consume_next_token(); // comma
+			t = parser.skip_spaces_and_tabs(t);
+			if (t->type == TokenType::ProcessorKeyword && static_cast<ProcessorKeywordType>(t->processor_keyword_index) == ProcessorKeywordType::Z) {
+				// [expression],z
+				// BasePageIndirectQuadIndexZ
+				return 1 << static_cast<int>(AddressingModeType::BasePageIndirectQuadIndexZ);
+			} else {
+				// the index register is invalid
+				std::stringstream ss;
+				ss << "Invalid index register in addressing mode. Expected z but got " << token_to_string(*t);
+				throw AssemblyException(source_files, t->source_location, AssemblyErrorCodes::InvalidIndexRegisterInAddressingMode, ss.str());
+			}
+		}
+		// [expression]
+		// BasePageIndirectQuad
+		return 1 << static_cast<int>(AddressingModeType::BasePageIndirectQuad);
+	}
+
+	if (t->type == TokenType::Newline || parser.is_operator(t, OperatorType::Semicolon)) {
+		// Implied
+		return 1 << static_cast<int>(AddressingModeType::Implied);
+	}
+
+	// <expression>...
+	// BasePageAddr
+	// AbsoluteAddr
+	// BasePageIndexX
+	// AbsoluteIndexX
+	// BasePageIndexY
+	// AbsoluteIndexY
+	// RelativeAddr
+	// RelativeWordAddr
+	// BitBp
+	// BitBpRel
+	const Token *next;
+	{
+		constexpr bool end_at_unmatched_right_parenthesis = false;
+		constexpr bool end_at_newline = true;
+		next = parser.parse_expression(t, end_at_unmatched_right_parenthesis, end_at_newline);
+	}
+
+	if (parser.is_operator(next, OperatorType::Comma)) {
+		// <expression>,
+		// BasePageIndexX
+		// AbsoluteIndexX
+		// BasePageIndexY
+		// AbsoluteIndexY
+		// BitBp
+		// BitBpRel
+		next = parser.skip_spaces_and_tabs(parser.consume_next_token());
+		if (next->type == TokenType::ProcessorKeyword && static_cast<ProcessorKeywordType>(next->processor_keyword_index) == ProcessorKeywordType::X) {
+			// <expression>,x
+			// BasePageIndexX
+			// AbsoluteIndexX
+			return
+				1 << static_cast<int>(AddressingModeType::BasePageIndexX) |
+				1 << static_cast<int>(AddressingModeType::AbsoluteIndexX);
+		}
+		if (next->type == TokenType::ProcessorKeyword && static_cast<ProcessorKeywordType>(next->processor_keyword_index) == ProcessorKeywordType::Y) {
+			// <expression>,y
+			// BasePageIndexY
+			// AbsoluteIndexY
+			return
+				1 << static_cast<int>(AddressingModeType::BasePageIndexY) |
+				1 << static_cast<int>(AddressingModeType::AbsoluteIndexY);
+		}
+		// <expression>, <expression>...
+		// BitZp
+		// BitZpRel
+		next = parse_optional_arg_label(parser, next, arg_labels[1]);
+		{
+			constexpr bool end_at_unmatched_right_parenthesis = false;
+			constexpr bool end_at_newline = true;
+			next = parser.parse_expression(next, end_at_unmatched_right_parenthesis, end_at_newline);
+		}
+		if (parser.is_operator(next, OperatorType::Comma)) {
+			// <expression>, <expression>, <expression>
+			next = parser.consume_next_token();
+			next = parse_optional_arg_label(parser, next, arg_labels[2]);
+			return 1 << static_cast<int>(AddressingModeType::BitBpRel);
+		}
+		// <expression>, <expression>
+		// BitZp
+		return 1 << static_cast<int>(AddressingModeType::BitBp);
+	}
+	// <expression>
+	// BasePageAddr
+	// AbsoluteAddr
+	// RelativeAddr
+	// RelativeWordAddr
+	return
+		1 << static_cast<int>(AddressingModeType::BasePageAddr) |
+		1 << static_cast<int>(AddressingModeType::AbsoluteAddr) |
+		1 << static_cast<int>(AddressingModeType::RelativeAddr) |
+		1 << static_cast<int>(AddressingModeType::RelativeWordAddr);
+}
+
+void Processor45gs02::print_addressing_modes(std::stringstream &ss, uint32_t addressing_mode_mask)
+{
+	for (int i = 0; i < static_cast<int>(AddressingModeType::NumAddressingModes); ++i) {
+		if (((1U << i) & addressing_mode_mask) != 0)
+			ss << "\n  " << to_string(static_cast<AddressingModeType>(i));
+	}
+}
+
+const Token *Processor45gs02::parse_instruction(SyntaxParser &parser, const std::vector<std::string> &source_files, const Token *t, uint8_t /*InstructionType*/ instruction_index) const
+{
+	InstructionType instruction = static_cast<InstructionType>(instruction_index);
+	const Token *begin_token = t;
+
+	t = parser.consume_next_token(); // instruction token
+	t = parser.skip_spaces_and_tabs(t);
+
+	// determine possible used addressing modes and compare with existing
+	std::array<ArgLabel, 3> arg_labels;
+	uint32_t parsed_addressing_modes = try_parse_addressing_mode(parser, source_files, t, arg_labels);
+	uint32_t possible_addressing_modes = addressing_modes(instruction);
+	uint32_t selected_addressing_modes = parsed_addressing_modes & possible_addressing_modes;
+	if (selected_addressing_modes == 0) {
+		std::stringstream ss;
+		ss << "Invalid addressing mode used. Code indicates one of the following:";
+		print_addressing_modes(ss, parsed_addressing_modes);
+		ss << "\nbut possible addressing modes for " << to_string(instruction) << " are:";
+		print_addressing_modes(ss, possible_addressing_modes);
+		throw AssemblyException(source_files, t->source_location, AssemblyErrorCodes::InvalidAddressingMode, ss.str());
+	}
+	
+	// store the instruction with addressing mode mask in the output
+	InstructionToken &instruction_token = parser.reserve_token_space<InstructionToken>();
+	instruction_token.type = SyntaxTokenType::Instruction;
+	instruction_token.processor = ProcessorType::Mega45gs02;
+	instruction_token.size = sizeof(InstructionToken);
+	instruction_token.instruction = instruction;
+	instruction_token.addressing_modes = selected_addressing_modes;
+	instruction_token.source_location = begin_token->source_location;
+	instruction_token.has_instruction_data_label[0] = arg_labels[0].enabled;
+	instruction_token.has_instruction_data_label[1] = arg_labels[1].enabled;
+	instruction_token.has_instruction_data_label[2] = arg_labels[2].enabled;
+	instruction_token.global_data_label[0] = arg_labels[0].global;
+	instruction_token.global_data_label[1] = arg_labels[1].global;
+	instruction_token.global_data_label[2] = arg_labels[2].global;
+	instruction_token.address_label_location[0] = arg_labels[0].location;
+	instruction_token.address_label_location[1] = arg_labels[1].location;
+	instruction_token.address_label_location[2] = arg_labels[2].location;
+	instruction_token.data_label_symbol_hash[0] = arg_labels[0].symbol_hash;
+	instruction_token.data_label_symbol_hash[1] = arg_labels[1].symbol_hash;
+	instruction_token.data_label_symbol_hash[2] = arg_labels[2].symbol_hash;
+
+	// now we should be able to parse the operand of the instruction
+	if (selected_addressing_modes == Imp) {
+		if (arg_labels[0].enabled) {
+			std::stringstream ss;
+			ss << "Implied addressing modes cannot have label to instruction data. Add a newline or a semicolon before the label to resolve this.";
+			throw AssemblyException(source_files, arg_labels[0].location, AssemblyErrorCodes::AddressingModeCannotHaveDataLabel, ss.str());
+		}
+		return t;
+	}
+
+	t = skip_optional_arg_label(parser, t, arg_labels[0]);
+
+	if ((selected_addressing_modes & (Imm | ImmW)) != 0) {
+		assert(parser.is_operator(t, OperatorType::Hash));
+		t = parser.consume_next_token(); // hash
+		constexpr bool end_at_unmatched_parenthesis = false;
+		constexpr bool end_at_newline = true;
+		return parser.parse_and_output_expression(t, end_at_unmatched_parenthesis, end_at_newline);
+	}
+
+	// an indirect mode with x or sp inside parenthesis
+	if ((selected_addressing_modes & (BpIX | IndX | SpIY)) != 0) {
+		// skip parenthesis, parse address expression, skip comma and x or sp
+		assert(parser.is_operator(t, OperatorType::LeftParenthesis));
+		t = parser.consume_next_token(); // (
+		constexpr bool end_at_unmatched_parenthesis = false;
+		constexpr bool end_at_newline = true;
+		t = parser.parse_and_output_expression(t, end_at_unmatched_parenthesis, end_at_newline);
+		assert(parser.is_operator(t, OperatorType::Comma));
+		t = parser.consume_next_token(); // comma
+		t = parser.skip_spaces_and_tabs(t);
+		assert(t->type == TokenType::ProcessorKeyword && (static_cast<ProcessorKeywordType>(t->processor_keyword_index) == ProcessorKeywordType::X || static_cast<ProcessorKeywordType>(t->processor_keyword_index) == ProcessorKeywordType::SP));
+		t = parser.consume_next_token(); // x or sp
+		t = parser.skip_spaces_and_tabs(t);
+		assert(parser.is_operator(t, OperatorType::RightParenthesis));
+		t = parser.consume_next_token(); // )
+		
+		if ((selected_addressing_modes & SpIY) != 0) {
+			t = parser.skip_spaces_and_tabs(t);
+			assert(parser.is_operator(t, OperatorType::Comma));
+			t = parser.consume_next_token(); // ,
+			t = parser.skip_spaces_and_tabs(t);
+			assert(t->type == TokenType::ProcessorKeyword && static_cast<ProcessorKeywordType>(t->processor_keyword_index) == ProcessorKeywordType::Y);
+			t = parser.consume_next_token(); // y
+			t = parser.skip_spaces_and_tabs(t);
+		}
+		return t;
+	}
+
+	// an indirect quad mode with optional z register offset
+	if ((selected_addressing_modes & (BIQ | BIQZ)) != 0) {
+		assert(parser.is_operator(t, OperatorType::LeftBracket));
+		t = parser.consume_next_token(); // [
+		constexpr bool end_at_unmatched_parenthesis = true;
+		constexpr bool end_at_newline = true;
+		t = parser.parse_and_output_expression(t, end_at_unmatched_parenthesis, end_at_newline);
+		assert(parser.is_operator(t, OperatorType::RightBracket));
+		t = parser.consume_next_token(); // ]
+		t = parser.skip_spaces_and_tabs(t);
+		if ((selected_addressing_modes & BIQZ) != 0) {
+			assert(parser.is_operator(t, OperatorType::Comma));
+			t = parser.consume_next_token(); // ,
+			t = parser.skip_spaces_and_tabs(t);
+			assert(t->type == TokenType::ProcessorKeyword && static_cast<ProcessorKeywordType>(t->processor_keyword_index) == ProcessorKeywordType::Z);
+			t = parser.consume_next_token(); // z
+			t = parser.skip_spaces_and_tabs(t);
+		}
+		return t;
+	}
+	
+	// parse address expression
+	{
+		constexpr bool end_at_unmatched_parenthesis = false;
+		constexpr bool end_at_newline = true;
+		t = parser.parse_and_output_expression(t, end_at_unmatched_parenthesis, end_at_newline);
+	}
+
+	if ((selected_addressing_modes & (BInd | Ind | BpIY | BpIZ)) != 0) {
+		if ((selected_addressing_modes & (BpIY | BpIZ)) != 0) {
+			// skip comma and y or z
+			assert(parser.is_operator(t, OperatorType::Comma));
+			t = parser.skip_spaces_and_tabs(parser.consume_next_token());
+			assert(t->type == TokenType::ProcessorKeyword && (static_cast<ProcessorKeywordType>(t->processor_keyword_index) == ProcessorKeywordType::Y | static_cast<ProcessorKeywordType>(t->processor_keyword_index) == ProcessorKeywordType::Z));
+			t = parser.skip_spaces_and_tabs(parser.consume_next_token());
+		}
+		return t;
+	}
+	
+	if ((selected_addressing_modes & (Bp | Abs | Rel | RelW)) != 0) {
+		return t;
+	}
+	
+	if ((selected_addressing_modes & (Bpx | AbsX | Bpy | AbsY)) != 0) {
+		// skip comma and x or y
+		assert(parser.is_operator(t, OperatorType::Comma));
+		t = parser.skip_spaces_and_tabs(parser.consume_next_token());
+
+		assert(t->type == TokenType::ProcessorKeyword && (static_cast<ProcessorKeywordType>(t->processor_keyword_index) == ProcessorKeywordType::X | static_cast<ProcessorKeywordType>(t->processor_keyword_index) == ProcessorKeywordType::Y));
+		t = parser.skip_spaces_and_tabs(parser.consume_next_token());
+
+		return t;
+	}
+	
+	// at least two arguments
+	assert(parser.is_operator(t, OperatorType::Comma));
+	t = parser.consume_next_token(); // comma
+	
+	t = skip_optional_arg_label(parser, t, arg_labels[1]);
+
+	if ((selected_addressing_modes & Bb) != 0) {
+		constexpr bool end_at_unmatched_parenthesis = false;
+		constexpr bool end_at_newline = true;
+		t = parser.parse_and_output_expression(t, end_at_unmatched_parenthesis, end_at_newline);
+		return t;
+	}
+	assert((selected_addressing_modes & Bbr) != 0);
+
+	// at least three arguments
+	{
+		constexpr bool end_at_unmatched_parenthesis = false;
+		constexpr bool end_at_newline = true;
+		t = parser.parse_and_output_expression(t, end_at_unmatched_parenthesis, end_at_newline);
+	}
+
+	assert(parser.is_operator(t, OperatorType::Comma));
+	t = parser.consume_next_token(); // comma
+	
+	t = skip_optional_arg_label(parser, t, arg_labels[2]);
+
+	{
+		constexpr bool end_at_unmatched_parenthesis = false;
+		constexpr bool end_at_newline = true;
+		t = parser.parse_and_output_expression(t, end_at_unmatched_parenthesis, end_at_newline);
+	}
+	return t;
+}
+
+uint8_t append_instruction(std::vector<uint8_t> &data_stream, InstructionType instruction, AddressingModeType addr_mode)
+{
+	OpCode opcode_data = opcode(instruction, addr_mode);
+	assert(opcode_data.size != 0);
+	data_stream.insert(std::end(data_stream), std::begin(opcode_data.opcode), std::begin(opcode_data.opcode) + opcode_data.size);
+	return opcode_data.size;
+}
+
+inline uint8_t instruction_size(InstructionType instruction, AddressingModeType addr_mode)
+{
+	return opcode(instruction, addr_mode).size;
+}
+
+void Processor45gs02::generate_subroutine_instruction(Assembler &assembler, bool generate, int32_t address, const SourceLocation &source_location) const
+{
+	// instructions are only allowed within code sections.
+	bool instructions_allowed = assembler.in_code_section();
+	if (UNLIKELY(!instructions_allowed)) {
+		// this is an unrecoverable error
+		std::stringstream ss;
+		ss << "Instructions must be in a code section.";
+		assembler.report_fatal_error(source_location, AssemblyErrorCodes::CodeMustBeInCodeSection, ss.str());
+	}
+
+	// recursive data generation may not be safe
+	if (assembler._data_generation_depth != 0) {
+		// this is an unrecoverable error
+		std::stringstream ss;
+		ss << "Recursive data generation isn't allowed.";
+		assembler.report_fatal_error(source_location, AssemblyErrorCodes::RecursiveDataGenerationNotAllowed, ss.str());
+	}
+	
+	ScopeCounter<uint32_t> sc(assembler._data_generation_depth);
+
+	if (generate && address < 0) {
+		std::stringstream ss;
+		ss << "Addressing mode needs a positive argument. Argument value was evaluated to " << address << ".";
+		assembler.report_error(source_location, AssemblyErrorCodes::AddressingModeRequiresPositiveArgument, ss.str());
+	}
+
+	if (assembler._multi_bank_mode) {
+		// in this mode, addresses gets truncated to support memory banks
+		address &= 0xffff;
+	}
+
+	if (generate) {
+		if (address > 65535) {
+			std::stringstream ss;
+			ss << "Addressing mode needs a word size argument. Argument was evaluated to " << address << ".";
+			assembler.report_error(source_location, AssemblyErrorCodes::AddressingModeRequiresWordSizeArgument, ss.str());
+		}
+		Section::Contents ending_instruction = Section::Contents::ContinueExecutionInstruction;
+		auto &data = assembler._section->generated_data(ending_instruction);
+		uint8_t isize = append_instruction(data, InstructionType::Jsr, AddressingModeType::AbsoluteAddr);
+		data.push_back(static_cast<uint8_t>(address));
+		data.push_back(static_cast<uint8_t>(address >> 8));
+		if (assembler._hex_source_writer != nullptr) {
+			constexpr bool increase = true;
+			assembler._hex_source_writer->write_data(static_cast<uint32_t>(assembler._program_counter.integer_value), &data[data.size() - 3], increase, 3, source_location.file_index, source_location.row, source_location.row + 1);
+		}
+		assembler._program_counter.integer_value += isize + 2;
+	} else {
+		assembler._program_counter.integer_value += instruction_size(InstructionType::Jsr, AddressingModeType::AbsoluteAddr) + 2;
+	}
+}
+
+void Processor45gs02::generate_instruction_data_label(Assembler &assembler, bool generate, bool export_enabled, const InstructionToken &token, uint8_t argument_index, int address, int offset, uint8_t size) const
+{
+	// exporting local variables is not allowed
+	if (generate && export_enabled && !token.global_data_label[argument_index]) {
+		std::stringstream ss;
+		ss << assembler.variable_name(token.data_label_symbol_hash[argument_index], token.global_data_label[argument_index]) << " cannot be exported since it is local.";
+		assembler.report_error(token.address_label_location[argument_index], AssemblyErrorCodes::ExportingLocalIsNotAllowed, ss.str());
+	}
+
+	if (assembler.create_label(generate, token.data_label_symbol_hash[argument_index], token.global_data_label[argument_index], StorageType::Constant, token.address_label_location[argument_index])) {
+		Value &new_label = assembler._current_pass.values.back();
+		if (size == 1) {
+			assembler.set_byte_offset(new_label, address, offset);
+		} else if (size == 2) {
+			assembler.set_word_offset(new_label, address, offset);
+		} else {
+			assert(false);
+		}
+		new_label.set_contains_address(true);
+		if (export_enabled) {
+			new_label.set_is_public(true);
+		}
+	}
+}
+
+const SyntaxToken *Processor45gs02::parse_instruction(Assembler &assembler, bool generate, const SyntaxToken *t, bool export_enabled) const
+{
+	assert(t->type == SyntaxTokenType::Instruction);
+	const InstructionToken &instruction_token = *static_cast<const InstructionToken *>(t);
+
+	// instructions are only allowed within code sections.
+	bool instructions_allowed = assembler.in_code_section();
+	if (UNLIKELY(!instructions_allowed)) {
+		// this is an unrecoverable error
+		std::stringstream ss;
+		ss << "Instructions must be in a code section.";
+		assembler.report_fatal_error(instruction_token.source_location, AssemblyErrorCodes::CodeMustBeInCodeSection, ss.str());
+	}
+
+	// recursive data generation may not be safe
+	if (assembler._data_generation_depth != 0) {
+		// this is an unrecoverable error
+		std::stringstream ss;
+		ss << "Recursive data generation isn't allowed.";
+		assembler.report_fatal_error(instruction_token.source_location, AssemblyErrorCodes::RecursiveDataGenerationNotAllowed, ss.str());
+	}
+	ScopeCounter<uint32_t> sc(assembler._data_generation_depth);
+
+	InstructionType instruction = instruction_token.instruction;
+	uint32_t addr_mode = instruction_token.addressing_modes;
+	Section::Contents ending_instruction = is_ending_instruction(instruction) ? Section::Contents::EndExecutionInstruction : Section::Contents::ContinueExecutionInstruction;
+
+	t = assembler.consume_next_token(); // instruction
+
+	// in the generation pass, the program counter is guaranteed to be an integer value
+	// so there is no need to verify this
+
+	if (addr_mode == AddressingModeMask::Imp) {
+		if (generate) {
+			auto &data = assembler._section->generated_data(ending_instruction);
+			uint8_t isize = append_instruction(data, instruction, AddressingModeType::Implied);
+			if (assembler._hex_source_writer != nullptr) {
+				constexpr bool increase = true;
+				assembler._hex_source_writer->write_data(static_cast<uint32_t>(assembler._program_counter.integer_value), &data[data.size() - 1], increase, 1, instruction_token.source_location.file_index, instruction_token.source_location.row, instruction_token.source_location.row + 1);
+			}
+			assembler._program_counter.integer_value += isize;
+		} else {
+			assembler._program_counter.integer_value += instruction_size(instruction, AddressingModeType::Implied);
+		}
+		return t;
+	}
+
+	// in all other instructions, we have to parse the expression for the first argument
+	const ExpressionToken *expr = static_cast<const ExpressionToken *>(t);
+	const Value argument = assembler.evaluate_expression(generate, t);
+	t = assembler.consume_next_token();
+
+	// The argument is guaranteed to be a valid type in the generation pass.
+	// In an assembly pass this can be Unknown.
+	int32_t argument_value = 0;
+
+	// in case of an assembly pass, unknown will be converted to 0, which is ok for all addressing modes except relative
+	if (assembler.is_integer(argument)) {
+		argument_value = assembler.dereference_integer(argument);
+	} else if (!assembler.is_unknown(argument)) {
+		if (generate) {
+			std::stringstream ss;
+			ss << "Addressing mode needs an integer value. Argument type was " << to_string(assembler.type_of_value(argument)) << ".";
+			assembler.report_error(expr->source_location, AssemblyErrorCodes::AddressingModeRequiresIntegerArgument, ss.str());
+		}
+	}
+
+	if (addr_mode == AddressingModeMask::Imm) {
+		if (generate) {
+			// handle the case where the value doesn't fit in a byte
+			if (argument_value < -128 || argument_value > 255) {
+				std::stringstream ss;
+				ss << "Addressing mode needs a byte size argument. Argument was evaluated to " << argument_value << ".";
+				assembler.report_error(expr->source_location, AssemblyErrorCodes::AddressingModeRequiresByteSizeArgument, ss.str());
+			}
+			auto &data = assembler._section->generated_data(ending_instruction);
+			append_instruction(data, instruction, AddressingModeType::Immediate);
+			data.push_back(static_cast<uint8_t>(argument_value));
+			if (assembler._hex_source_writer != nullptr) {
+				constexpr bool increase = true;
+				assembler._hex_source_writer->write_data(static_cast<uint32_t>(assembler._program_counter.integer_value), &data[data.size() - 2], increase, 2, instruction_token.source_location.file_index, instruction_token.source_location.row, instruction_token.source_location.row + 1);
+			}
+		}
+		uint8_t isize = instruction_size(instruction, AddressingModeType::Immediate);
+		if (UNLIKELY(instruction_token.has_instruction_data_label[0])) {
+			generate_instruction_data_label(assembler, generate, export_enabled, instruction_token, 0, assembler._program_counter.integer_value + isize, 0, 1);
+		}
+
+		assembler._program_counter.integer_value += isize + 1;
+		return t;
+	}
+	if (addr_mode == AddressingModeMask::ImmW) {
+		if (generate) {
+			// handle the case where the value doesn't fit in a word
+			if (argument_value < -32768 || argument_value > 65535) {
+				std::stringstream ss;
+				ss << "Addressing mode needs a word size argument. Argument was evaluated to " << argument_value << ".";
+				assembler.report_error(expr->source_location, AssemblyErrorCodes::AddressingModeRequiresWordSizeArgument, ss.str());
+			}
+			auto &data = assembler._section->generated_data(ending_instruction);
+			append_instruction(data, instruction, AddressingModeType::ImmediateWord);
+			data.push_back(static_cast<uint8_t>(argument_value));
+			data.push_back(static_cast<uint8_t>(argument_value >> 8));
+			if (assembler._hex_source_writer != nullptr) {
+				constexpr bool increase = true;
+				assembler._hex_source_writer->write_data(static_cast<uint32_t>(assembler._program_counter.integer_value), &data[data.size() - 3], increase, 3, instruction_token.source_location.file_index, instruction_token.source_location.row, instruction_token.source_location.row + 1);
+			}
+		}
+		uint8_t isize = instruction_size(instruction, AddressingModeType::ImmediateWord);
+		if (UNLIKELY(instruction_token.has_instruction_data_label[0])) {
+			generate_instruction_data_label(assembler, generate, export_enabled, instruction_token, 0, assembler._program_counter.integer_value + isize, 0, 2);
+		}
+
+		assembler._program_counter.integer_value += isize + 2;
+		return t;
+	}
+
+	if (generate && argument_value < 0) {
+		std::stringstream ss;
+		ss << "Addressing mode needs a positive argument. Argument value was evaluated to " << argument_value << ".";
+		assembler.report_error(expr->source_location, AssemblyErrorCodes::AddressingModeRequiresPositiveArgument, ss.str());
+	}
+
+	if (assembler._multi_bank_mode && (addr_mode != AddressingModeMask::Rel && addr_mode != AddressingModeMask::RelW)) {
+		// in this mode, addresses gets truncated to support memory banks
+		argument_value &= 0xffff;
+	}
+
+	if (addr_mode == (AddressingModeMask::Bp | AddressingModeMask::Abs)
+		|| addr_mode == (AddressingModeMask::Bpx | AddressingModeMask::AbsX)
+		|| addr_mode == (AddressingModeMask::Bpy | AddressingModeMask::AbsY)
+		|| addr_mode == (AddressingModeMask::BpIX | AddressingModeMask::IndX)
+		|| addr_mode == (AddressingModeMask::BInd | AddressingModeMask::Ind)
+	)
+	{
+		// mask off the zero page or absolute addressing mode regardless of modes
+		addr_mode = argument_value > 255 ? select_word_mode(addr_mode) : select_byte_mode(addr_mode);
+	}
+
+	if (addr_mode == AddressingModeMask::Bp
+		|| addr_mode == AddressingModeMask::Bpx
+		|| addr_mode == AddressingModeMask::Bpy
+		|| addr_mode == AddressingModeMask::BpIX
+		|| addr_mode == AddressingModeMask::BpIY
+		|| addr_mode == AddressingModeMask::BpIZ
+		|| addr_mode == AddressingModeMask::SpIY
+		|| addr_mode == AddressingModeMask::BIQ
+		|| addr_mode == AddressingModeMask::BIQZ
+		|| addr_mode == AddressingModeMask::BInd
+	)
+	{
+		if (generate) {
+			if (argument_value > 255) {
+				std::stringstream ss;
+				ss << "Addressing mode needs a byte size argument. Argument was evaluated to " << argument_value << ".";
+				assembler.report_error(expr->source_location, AssemblyErrorCodes::AddressingModeRequiresByteSizeArgument, ss.str());
+			}
+			auto &data = assembler._section->generated_data(ending_instruction);
+			append_instruction(data, instruction, mask_to_addressing_mode(addr_mode));
+			data.push_back(static_cast<uint8_t>(argument_value));
+			if (assembler._hex_source_writer != nullptr) {
+				constexpr bool increase = true;
+				assembler._hex_source_writer->write_data(static_cast<uint32_t>(assembler._program_counter.integer_value), &data[data.size() - 2], increase, 2, instruction_token.source_location.file_index, instruction_token.source_location.row, instruction_token.source_location.row + 1);
+			}
+		}
+		uint8_t isize = instruction_size(instruction, mask_to_addressing_mode(addr_mode));
+		if (UNLIKELY(instruction_token.has_instruction_data_label[0])) {
+			generate_instruction_data_label(assembler, generate, export_enabled, instruction_token, 0, assembler._program_counter.integer_value + isize, 0, 1);
+		}
+		assembler._program_counter.integer_value += isize + 1;
+		return t;
+	}
+
+	if (addr_mode == AddressingModeMask::Abs
+		|| addr_mode == AddressingModeMask::AbsX