;This is an example program that uses ;UART, the interface that PicoBlaze uses ;for connecting to terminals (a DOS-like ;user interface, with a keyboard and a ;screen capable of displaying text). ;It loads base-10 integer numbers from ;the terminal, converts them into binary, ;and then prints the binary ;representations back onto the terminal. ;Example input would be: ;1 ;2 ;4 ;8 ;15 ;127 ;255 ; ;And the expected output is: ;1_(10)=1_(2) ;2_(10)=10_(2) ;4_(10)=100_(2) ;8_(10)=1000_(2) ;15_(10)=1111_(2) ;127_(10)=1111111_(2) ;255_(10)=11111111_(2) ; ;Note that you need to click the ;"Enable UART" button in order to use it. ;Also, the trailing empty line in the ;input is necessary for the result to be ;printed. ;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 ADDRESS 000 START: ;At the beginning, the number is 0. load s0,0 ;And we are storing its string ;representation at the beginning ;of RAM. namereg s3,pointer load pointer,0 ;Now follows a loop to load ;the digits of the number. loading_the_number: ;Load a character from the UART ;terminal. call UART_RX ;Check whether the character is a digit. compare s9,"0" ;If it is not a digit, jump to the ;part of the program for printing ;the number you have got. jump c,print_the_number load s1,"9" compare s1,s9 jump c,print_the_number ;If it is a digit, store it into RAM. store s9,(pointer) add pointer,1 ;Multiply the number you have got by 10. load sf,s0 call multiply_by_10 load s0,se ;Then, convert the digit from ASCII ;into binary. sub s9,"0" ;And then add it to the number you ;have got. add s0,s9 call c,abort ;In case of overflow. jump loading_the_number ;Repeat until a ;non-digit is ;loaded. print_the_number: ;If there are no digits to be printed, ;do not print anything. sub pointer,0 jump z,START print_the_decimal: load s4,pointer load pointer,0 printing_the_decimal_loop: compare pointer,s4 jump nc, end_of_printing_the_decimal fetch s9,(pointer) ;Do some basic sanity check: Is the ;character you are printing indeed ;a decimal digit? compare s9,"0" call c,abort load s1,"9" compare s1,s9 call c,abort ;If it is indeed a decimal digit, ;print it. call UART_TX add pointer,1 jump printing_the_decimal_loop end_of_printing_the_decimal: ;After you have repeated the decimal ;number, print the string "_(10)=". load s9,"_" call UART_TX load s9,"(" call UART_TX load s9,"1" call UART_TX load s9,"0" call UART_TX load s9,")" call UART_TX load s9,"=" call UART_TX ;If the number to be printed is ;equal to zero, print 0. sub s0,0 jump nz,print_the_binary load s9,"0" call UART_TX jump end_of_printing_loop print_the_binary: ;Make the pointer point to the ;beginning of RAM. load pointer,0 ;Now goes a loop which stores the binary ;representation of the number we have ;got into RAM, but reversed. beginning_of_converting_to_binary: sub s0,0 jump z,end_of_converting_to_binary load s9,"0" sr0 s0 jump nc,store_digit_to_memory add s9,1 store_digit_to_memory: store s9,(pointer) add pointer,1 jump beginning_of_converting_to_binary end_of_converting_to_binary: ;Do some basic sanity check, such as that ;the pointer does not point to zero. compare pointer,0 call z,abort ;Something went wrong ;so end the program. ;Check whether there are more than 8 bits. compare pointer,9 call nc,abort ;Now goes a loop which will print ;the binary number in RAM, with digits ;in the correct order. The pointer now ;points at a memory location right after ;the binary number (not at the last digit, ;but after it). beginning_of_printing_loop: sub pointer,1 jump c,end_of_printing_loop fetch s9,(pointer) ;Do some basic sanity check: ;Is the character the pointer points to ;indeed a binary digit? compare s9,"0" jump z,memory_is_fine compare s9,"1" jump z,memory_is_fine call abort ;Something went wrong, ;so end the program. memory_is_fine: ;If everything is fine, print that ;digit. call UART_TX ;Repeat until you have printed all ;digits of the binary number ;stored in RAM. jump beginning_of_printing_loop end_of_printing_loop: ;After you have printed that binary ;number, print the string "_(2)" and ;a new-line. load s9,"_" call UART_TX load s9,"(" call UART_TX load s9,"2" call UART_TX load s9,")" call UART_TX load s9,a ;newline character, 0xa=='\n'. call UART_TX ;The program runs in an infinite loop... JUMP START multiply_by_10: load se,sf add se,se call c,abort add se,se call c,abort add se,sf call c,abort add se,se call c,abort return abort: load s9,"E" call UART_TX load s9,"R" call UART_TX load s9,"R" call UART_TX load s9,"O" call UART_TX load s9,"R" call UART_TX load s9,"!" call UART_TX load s9,a ;newline call UART_TX infinite_loop: jump infinite_loop return ;Now follows some boilerplate code ;we use in our Computer Architecture ;classes... UART_RX: INPUT sA, UART_STATUS_PORT TEST sA, U_RX_D JUMP Z, UART_RX 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
So, what do you think about it? Do you have some suggestions about how to make it better?