4
\$\begingroup\$

You can see it live here:

;A very advanced example: Implementing the permutations algorithm in PicoBlaze assembly.

base_decimal

constant NDEBUG, 1
constant address_of_the_current_attempt, 8
constant bottom_of_the_stack, 16

address 0

namereg sf, length_of_the_input

call print_the_introduction_message
load length_of_the_input, 0
beginning_of_the_input_loop:
  call UART_RX
  compare s9, a'x ;The new-line character.
  jump z, end_of_the_input_loop
  store s9, (length_of_the_input)
  add length_of_the_input, 1
  jump beginning_of_the_input_loop
end_of_the_input_loop:
compare length_of_the_input, 0
jump z, 0

beginning_of_the_bubble_sort:
  load s4, 0 ;A boolean indicating
             ;whether a swap has been
             ;performed.
  load s0, 0
  inner_bubble_sort_loop:
    load s1, length_of_the_input
    sub s1, 1
    compare s0, s1
    jump nc, end_of_the_inner_bubble_sort_loop
    load s1, s0
    add s1, 1
    fetch s2, (s0)
    fetch s3, (s1)
    compare s3, s2
    jump nc, do_not_swap
      store s3, (s0)
      store s2, (s1)
      load s4, 1
    do_not_swap:
    add s0, 1
    jump inner_bubble_sort_loop
  end_of_the_inner_bubble_sort_loop:
  compare s4, 0
  jump nz, beginning_of_the_bubble_sort
end_of_the_bubble_sort_loop:

jump NDEBUG ? the_permutations_algorithm : printing_the_sorted_array
printing_the_sorted_array:
call print_the_sorted_array_message
load s0, 0
printing_the_sorted_array_loop:
  compare s0, length_of_the_input
  jump nc, end_of_the_printing_the_sorted_array_loop
  fetch s9, (s0)
  call UART_TX
  add s0, 1
  jump printing_the_sorted_array_loop
end_of_the_printing_the_sorted_array_loop:
load s9, a'x
call UART_TX

the_permutations_algorithm:
namereg se, top_of_the_stack
load top_of_the_stack, bottom_of_the_stack
load s0, 0
store s0, (top_of_the_stack)
add top_of_the_stack, length_of_the_input
add top_of_the_stack, 1
beginning_of_the_permutations_loop:
  compare top_of_the_stack, bottom_of_the_stack
  jump z, end_of_the_permutations_loop
  sub top_of_the_stack, length_of_the_input
  sub top_of_the_stack, 1
  namereg sd, length_of_the_current_attempt
  fetch length_of_the_current_attempt, (top_of_the_stack)
  load s0, address_of_the_current_attempt
  store length_of_the_current_attempt, (s0)
  load s1, 0
  copying_the_current_attempt_from_the_stack_loop:
    compare s1, length_of_the_current_attempt
    jump nc, end_of_copying
    load s0, address_of_the_current_attempt
    add s0, s1
    add s0, 1
    load s3, top_of_the_stack
    add s3, s1
    add s3, 1
    fetch s4, (s3)
    store s4, (s0)
    add s1, 1
    jump copying_the_current_attempt_from_the_stack_loop
  end_of_copying:
  jump NDEBUG ? dont_print_the_current_attempt : print_the_current_attempt
  print_the_current_attempt:
  call print_the_length_of_the_current_attempt_message
  load s9, length_of_the_current_attempt
  add s9, "0"
  call UART_TX
  load s9, a'x
  call UART_TX
  call print_the_current_attempt_message
  load s0, address_of_the_current_attempt + 1
  printing_the_current_attempt_loop:
    load s1, address_of_the_current_attempt + 1
    add s1, length_of_the_current_attempt
    compare s0, s1
    jump nc, end_of_the_printing_the_current_attempt_loop
    fetch s9, (s0)
    call UART_TX
    add s0, 1
    jump printing_the_current_attempt_loop
  end_of_the_printing_the_current_attempt_loop:
  load s9, a'x
  call UART_TX
  dont_print_the_current_attempt:
  compare length_of_the_current_attempt, length_of_the_input
  jump c, current_attempt_is_not_a_solution
    call print_found_a_solution_message
    load s0, address_of_the_current_attempt + 1
    printing_the_solution_loop:
      load s1, address_of_the_current_attempt + 1
      add s1, length_of_the_current_attempt
      compare s0, s1
      jump nc, end_of_the_printing_the_solution_loop
      fetch s9, (s0)
      call UART_TX
      add s0, 1
      jump printing_the_solution_loop
    end_of_the_printing_the_solution_loop:
    load s9, a'x
    call UART_TX
  jump end_of_the_branching
  current_attempt_is_not_a_solution:
    load s0, length_of_the_input
    sub s0, 1
    add_a_new_character_loop:
      compare s0, ff'x ;Overflow
      jump z, end_of_the_add_a_new_character_loop
      namereg sc, character_we_try_to_add
      fetch character_we_try_to_add, (s0)
      load s7, s0
      add s7, 1
      load s8, 0 ;Whether we already tried adding that character.
      check_if_we_already_tried_that_character_loop:
        compare s7, length_of_the_input
        jump nc, end_of_the_check_if_we_already_tried_that_character_loop
        fetch s6, (s7)
        compare s6, character_we_try_to_add
        jump nz, third_characters_are_not_equal_label
          load s8, 1
        third_characters_are_not_equal_label:
        add s7, 1
        jump check_if_we_already_tried_that_character_loop
      end_of_the_check_if_we_already_tried_that_character_loop:
      test s8, s8
      jump nz, dont_add_the_new_character
      jump NDEBUG ? dont_print_the_character_we_are_trying_to_add : print_the_character_we_are_trying_to_add
      print_the_character_we_are_trying_to_add:
        call print_we_are_trying_to_add_message
        load s9, character_we_try_to_add
        call UART_TX
        load s9, a'x
        call UART_TX
      dont_print_the_character_we_are_trying_to_add:
      load s2, 0 ; How many of the chosen character are present in the current attempt.
      load s1, address_of_the_current_attempt + 1
      count_in_the_current_attempt_loop:
        load s4, address_of_the_current_attempt + 1
        add s4, length_of_the_current_attempt
        compare s1, s4
        jump z, end_of_the_count_in_the_current_attempt_loop
        fetch s4, (s1)
        compare s4, character_we_try_to_add
        jump nz, first_the_characters_are_not_equal_label
          add s2, 1
        first_the_characters_are_not_equal_label:
        add s1, 1
        jump count_in_the_current_attempt_loop
      end_of_the_count_in_the_current_attempt_loop:
      jump NDEBUG ? dont_print_how_many_in_the_current_attempt : print_how_many_in_the_current_attempt
      print_how_many_in_the_current_attempt:
        call print_the_current_attempt_count_message
        load s9, s2
        add s9, "0"
        call UART_TX
        load s9, a'x
        call UART_TX
      dont_print_how_many_in_the_current_attempt:
      load s3, 0 ; How many of the chosen character are present in the input.
      load s1, 0
      count_in_the_input_loop:
        compare s1, length_of_the_input
        jump z, end_of_the_count_in_the_input_loop
        fetch s4, (s1)
        compare s4, character_we_try_to_add
        jump nz, second_the_characters_are_not_equal_label
          add s3, 1
        second_the_characters_are_not_equal_label:
        add s1, 1
        jump count_in_the_input_loop
      end_of_the_count_in_the_input_loop:
      jump NDEBUG ? dont_print_how_many_in_the_input : print_how_many_in_the_input
      print_how_many_in_the_input:
        call print_count_in_the_input_message
        load s9, s3
        add s9, "0"
        call UART_TX
        load s9, a'x
        call UART_TX
      dont_print_how_many_in_the_input:
      compare s2, s3
      jump nc, dont_add_the_new_character
        load s1, NDEBUG
        test s1, s1
        call z, print_the_we_are_adding_the_new_character_message
        load s1, top_of_the_stack
        load s2, length_of_the_current_attempt
        add s2, 1
        store s2, (s1)
        add s1, 1
        load s3, address_of_the_current_attempt + 1
        copying_the_new_attempt_loop:
          load s5, address_of_the_current_attempt + 1
          add s5, length_of_the_current_attempt
          compare s3, s5
          jump z, end_of_the_copying_the_new_attempt_loop
          fetch s4, (s3)
          store s4, (s1)
          add s3, 1
          add s1, 1
          jump copying_the_new_attempt_loop
        end_of_the_copying_the_new_attempt_loop:
        load s1, top_of_the_stack
        add s1, length_of_the_current_attempt
        add s1, 1
        store character_we_try_to_add, (s1)
        add top_of_the_stack, length_of_the_input
        add top_of_the_stack, 1
      dont_add_the_new_character:
      sub s0, 1
      jump add_a_new_character_loop
    end_of_the_add_a_new_character_loop:
  jump end_of_the_branching
  end_of_the_branching:
  jump beginning_of_the_permutations_loop
end_of_the_permutations_loop:
call print_the_end_message
jump 0

print_the_introduction_message:
  load s9, "E"
  call UART_TX
  load s9, "n"
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, "e"
  call UART_TX
  load s9, "r"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "a"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "s"
  call UART_TX
  load s9, "h"
  call UART_TX
  load s9, "o"
  call UART_TX
  load s9, "r"
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "s"
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, "r"
  call UART_TX
  load s9, "i"
  call UART_TX
  load s9, "n"
  call UART_TX
  load s9, "g"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "a"
  call UART_TX
  load s9, "n"
  call UART_TX
  load s9, "d"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "p"
  call UART_TX
  load s9, "r"
  call UART_TX
  load s9, "e"
  call UART_TX
  load s9, "s"
  call UART_TX
  load s9, "s"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "e"
  call UART_TX
  load s9, "n"
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, "e"
  call UART_TX
  load s9, "r"
  call UART_TX
  load s9, "."
  call UART_TX
  load s9, a'x
  call UART_TX
return

print_the_sorted_array_message:
  load s9, "A"
  call UART_TX
  load s9, "f"
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, "e"
  call UART_TX
  load s9, "r"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, "h"
  call UART_TX
  load s9, "e"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "B"
  call UART_TX
  load s9, "u"
  call UART_TX
  load s9, "b"
  call UART_TX
  load s9, "b"
  call UART_TX
  load s9, "l"
  call UART_TX
  load s9, "e"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "S"
  call UART_TX
  load s9, "o"
  call UART_TX
  load s9, "r"
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "a"
  call UART_TX
  load s9, "l"
  call UART_TX
  load s9, "g"
  call UART_TX
  load s9, "o"
  call UART_TX
  load s9, "r"
  call UART_TX
  load s9, "i"
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, "h"
  call UART_TX
  load s9, "m"
  call UART_TX
  load s9, ","
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, "h"
  call UART_TX
  load s9, "e"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "i"
  call UART_TX
  load s9, "n"
  call UART_TX
  load s9, "p"
  call UART_TX
  load s9, "u"
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "s"
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, "r"
  call UART_TX
  load s9, "i"
  call UART_TX
  load s9, "n"
  call UART_TX
  load s9, "g"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "l"
  call UART_TX
  load s9, "o"
  call UART_TX
  load s9, "o"
  call UART_TX
  load s9, "k"
  call UART_TX
  load s9, "s"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "l"
  call UART_TX
  load s9, "i"
  call UART_TX
  load s9, "k"
  call UART_TX
  load s9, "e"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, "h"
  call UART_TX
  load s9, "i"
  call UART_TX
  load s9, "s"
  call UART_TX
  load s9, " "
  call UART_TX
return

print_the_current_attempt_message:
  load s9, "T"
  call UART_TX
  load s9, "h"
  call UART_TX
  load s9, "e"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "c"
  call UART_TX
  load s9, "u"
  call UART_TX
  load s9, "r"
  call UART_TX
  load s9, "r"
  call UART_TX
  load s9, "e"
  call UART_TX
  load s9, "n"
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "a"
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, "e"
  call UART_TX
  load s9, "m"
  call UART_TX
  load s9, "p"
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "i"
  call UART_TX
  load s9, "s"
  call UART_TX
  load s9, " "
  call UART_TX
return

print_we_are_trying_to_add_message:
  load s9, "W"
  call UART_TX
  load s9, "e"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "a"
  call UART_TX
  load s9, "r"
  call UART_TX
  load s9, "e"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, "r"
  call UART_TX
  load s9, "y"
  call UART_TX
  load s9, "i"
  call UART_TX
  load s9, "n"
  call UART_TX
  load s9, "g"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, "o"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "a"
  call UART_TX
  load s9, "d"
  call UART_TX
  load s9, "d"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, "h"
  call UART_TX
  load s9, "e"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "c"
  call UART_TX
  load s9, "h"
  call UART_TX
  load s9, "a"
  call UART_TX
  load s9, "r"
  call UART_TX
  load s9, "a"
  call UART_TX
  load s9, "c"
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, "e"
  call UART_TX
  load s9, "r"
  call UART_TX
  load s9, " "
  call UART_TX
return

print_the_current_attempt_count_message:
  load s9, "T"
  call UART_TX
  load s9, "h"
  call UART_TX
  load s9, "e"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "c"
  call UART_TX
  load s9, "o"
  call UART_TX
  load s9, "u"
  call UART_TX
  load s9, "n"
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "o"
  call UART_TX
  load s9, "f"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, "h"
  call UART_TX
  load s9, "a"
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "c"
  call UART_TX
  load s9, "h"
  call UART_TX
  load s9, "a"
  call UART_TX
  load s9, "r"
  call UART_TX
  load s9, "a"
  call UART_TX
  load s9, "c"
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, "e"
  call UART_TX
  load s9, "r"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "i"
  call UART_TX
  load s9, "n"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, "h"
  call UART_TX
  load s9, "e"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "c"
  call UART_TX
  load s9, "u"
  call UART_TX
  load s9, "r"
  call UART_TX
  load s9, "r"
  call UART_TX
  load s9, "e"
  call UART_TX
  load s9, "n"
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "a"
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, "e"
  call UART_TX
  load s9, "m"
  call UART_TX
  load s9, "p"
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "i"
  call UART_TX
  load s9, "s"
  call UART_TX
  load s9, " "
  call UART_TX
return

print_count_in_the_input_message:
  load s9, "T"
  call UART_TX
  load s9, "h"
  call UART_TX
  load s9, "e"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "c"
  call UART_TX
  load s9, "o"
  call UART_TX
  load s9, "u"
  call UART_TX
  load s9, "n"
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "o"
  call UART_TX
  load s9, "f"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, "h"
  call UART_TX
  load s9, "a"
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "c"
  call UART_TX
  load s9, "h"
  call UART_TX
  load s9, "a"
  call UART_TX
  load s9, "r"
  call UART_TX
  load s9, "a"
  call UART_TX
  load s9, "c"
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, "e"
  call UART_TX
  load s9, "r"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "i"
  call UART_TX
  load s9, "n"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, "h"
  call UART_TX
  load s9, "e"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "i"
  call UART_TX
  load s9, "n"
  call UART_TX
  load s9, "p"
  call UART_TX
  load s9, "u"
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "s"
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, "r"
  call UART_TX
  load s9, "i"
  call UART_TX
  load s9, "n"
  call UART_TX
  load s9, "g"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "i"
  call UART_TX
  load s9, "s"
  call UART_TX
  load s9, " "
  call UART_TX
return

print_the_we_are_adding_the_new_character_message:
  load s9, "W"
  call UART_TX
  load s9, "e"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "w"
  call UART_TX
  load s9, "i"
  call UART_TX
  load s9, "l"
  call UART_TX
  load s9, "l"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, "r"
  call UART_TX
  load s9, "y"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, "o"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "a"
  call UART_TX
  load s9, "d"
  call UART_TX
  load s9, "d"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, "h"
  call UART_TX
  load s9, "a"
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "c"
  call UART_TX
  load s9, "h"
  call UART_TX
  load s9, "a"
  call UART_TX
  load s9, "r"
  call UART_TX
  load s9, "a"
  call UART_TX
  load s9, "c"
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, "e"
  call UART_TX
  load s9, "r"
  call UART_TX
  load s9, "."
  call UART_TX
  load s9, a'x
  call UART_TX
return

print_found_a_solution_message:
  load s9, "F"
  call UART_TX
  load s9, "o"
  call UART_TX
  load s9, "u"
  call UART_TX
  load s9, "n"
  call UART_TX
  load s9, "d"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "a"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "p"
  call UART_TX
  load s9, "e"
  call UART_TX
  load s9, "r"
  call UART_TX
  load s9, "m"
  call UART_TX
  load s9, "u"
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, "a"
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, "i"
  call UART_TX
  load s9, "o"
  call UART_TX
  load s9, "n"
  call UART_TX
  load s9, " "
  call UART_TX
return

print_the_end_message:
  load s9, "T"
  call UART_TX
  load s9, "h"
  call UART_TX
  load s9, "e"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "e"
  call UART_TX
  load s9, "n"
  call UART_TX
  load s9, "d"
  call UART_TX
  load s9, "!"
  call UART_TX
  load s9, a'x
  call UART_TX
return

print_the_length_of_the_current_attempt_message:
    load s9, "T"
  call UART_TX
  load s9, "h"
  call UART_TX
  load s9, "e"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "l"
  call UART_TX
  load s9, "e"
  call UART_TX
  load s9, "n"
  call UART_TX
  load s9, "g"
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, "h"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "o"
  call UART_TX
  load s9, "f"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, "h"
  call UART_TX
  load s9, "e"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "c"
  call UART_TX
  load s9, "u"
  call UART_TX
  load s9, "r"
  call UART_TX
  load s9, "r"
  call UART_TX
  load s9, "e"
  call UART_TX
  load s9, "n"
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "a"
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, "e"
  call UART_TX
  load s9, "m"
  call UART_TX
  load s9, "p"
  call UART_TX
  load s9, "t"
  call UART_TX
  load s9, " "
  call UART_TX
  load s9, "i"
  call UART_TX
  load s9, "s"
  call UART_TX
  load s9, " "
  call UART_TX
return

;Now follows some boilerplate code
;we use in our Computer Architecture
;classes...
CONSTANT LED_PORT,         00
CONSTANT HEX1_PORT,        01
CONSTANT HEX2_PORT,        02
CONSTANT UART_TX_PORT,     03
CONSTANT UART_RESET_PORT,  04
CONSTANT SW_PORT,          00
CONSTANT BTN_PORT,         01
CONSTANT UART_STATUS_PORT, 02
CONSTANT UART_RX_PORT,     03
; Tx data_present
CONSTANT U_TX_D, 00000001'b
; Tx FIFO half_full
CONSTANT U_TX_H, 00000010'b
; TxFIFO full
CONSTANT U_TX_F, 00000100'b
; Rxdata_present
CONSTANT U_RX_D, 00001000'b
; RxFIFO half_full
CONSTANT U_RX_H, 00010000'b
; RxFIFO full
CONSTANT U_RX_F, 00100000'b

UART_RX:
  INPUT sA, UART_STATUS_PORT
  TEST  sA, U_RX_D
  JUMP  NZ, input_not_empty
  LOAD  s0, s0
  JUMP UART_RX
  input_not_empty:
  INPUT s9, UART_RX_PORT
RETURN

UART_TX:
  INPUT  sA, UART_STATUS_PORT
  TEST   sA, U_TX_F
  JUMP   NZ, UART_TX
  OUTPUT s9, UART_TX_PORT
RETURN

As far as I've tested it, it seems to work. But I am not sure how legible it is. I've tried to make it as legible as possible by using long label names and using nameregs sometimes, as well as code indentation.

\$\endgroup\$
0

1 Answer 1

4
\$\begingroup\$

naming nit: an imperative print_foo label would be more usual than printing_foo, whatever.

define constant string

The UART runs at a fixed rate, so it's not like "optimize for speed" is relevant here. I can't imagine any set of time - space tradeoffs or engineering constraints that would motivate generating this code:

print_the_introduction_message:
  load s9, "E"
  call UART_TX
  load s9, "n"
  call UART_TX
  ...

If you really desire that generated machine code as output, at least create a macro so dealing with e.g. "E" takes a single line rather than two.

But what should replace this code is:

introduction_message:  defstring "Enter a short ..."

print_the_introduction_message:
  load s9, introduction_message
  call print_string

Use a wide enough register for a pointer, if s9 is too narrow. Use NUL terminated strings if you like, or a (length, data) tuple.

The print_string utility routine will loop over the input, making calls to UART_TX as it goes. There's already some fragments in the OP code that show how to do that.

\$\endgroup\$
8
  • \$\begingroup\$ I want to generate that machine code because I have almost limitless EPROM memory (for storing instructions), but I only have 256 bytes of RAM. Storing those strings in RAM seems wasteful, doesn't it? \$\endgroup\$ Commented Apr 12 at 14:54
  • 2
    \$\begingroup\$ I don’t understand the “store in RAM” remark. An origin directive or similar should let you allocate a string up in your favorite EPROM address space, and then another origin directive would let you continue on with machine code, keeping it all together. In general, I would expect that the author of an assembly file would have complete control over the memory layout of where things go. I would be very surprised if a DEFBYTE or DEFWORD directive used scratchpad RAM storage, rather than adding output bytes to the read only .text segment. An init routine might copy data down to RAM. \$\endgroup\$ Commented Apr 12 at 17:33
  • \$\begingroup\$ Hmmm, it doesn’t even need to be NUL terminated. Over in codereview.stackexchange.com/questions/295873/… we see an example where the author found the dollar sign “$” character a convenient terminator. \$\endgroup\$ Commented Apr 12 at 17:41
  • 2
    \$\begingroup\$ As someone who spent a lot of time worrying about page zero on 6502 machines, I can’t imagine why that is a desirable architectural feature. But if that is the engineering constraint, then I recommend defining a few routines in EPROM that fill a ram buffer with various constant strings. This allows a more natural calling interface when requesting output to the serial UART device. With judicious use of macros, there should be no need to use more than one source line per character. \$\endgroup\$ Commented Apr 12 at 18:14
  • 3
    \$\begingroup\$ That’s not necessary. You could, for example, use the M4 macro pre-processor to send revised source code into the existing assembler. // i’m just saying that the existing OP source code is distracting. It is not the best way to express the high-level idea to some maintenance engineer who will look at this in a year or two. \$\endgroup\$ Commented Apr 12 at 20:30

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.