📄 list_ch16_03_uart_rom.psm
字号:
;=========================================================
; Square circuit with UART and multiplier interface
;=========================================================
;Program operation:
; - read a and b from switch
; - calculate a*a + b*b
; - display data on HyperTerminal and 7-seg led
;=========================================================
; Data constants
;=========================================================
;selected ASCII codes
constant ASCII_0, 30
constant ASCII_1, 31
constant ASCII_2, 32
constant ASCII_3, 33
constant ASCII_a, 61
constant ASCII_b, 62
constant ASCII_c, 63
constant ASCII_d, 64
constant ASCII_o, 6F
constant ASCII_r, 72
constant ASCII_E, 45
constant ASCII_S, 53
constant ASCII_Q, 51
constant ASCII_D_U,44 ; upper_case D
constant ASCII_GT, 3E ; >
constant ASCII_SP, 20 ; space
constant ASCII_CR, 0D ; carriage return
constant ASCII_LF, 0A ; line feed
;=========================================================
; Data ram address alias
;=========================================================
constant a_lsb, 00
constant b_lsb, 02
constant aa_lsb, 04
constant aa_msb, 05
constant bb_lsb, 06
constant bb_msb, 07
constant aabb_lsb, 08
constant aabb_msb, 09
constant aabb_cout, 0A
constant led0, 10
constant led1, 11
constant led2, 12
constant led3, 13
;=========================================================
; Register alias
;=========================================================
;commonly used local variables
namereg s0, data ;reg for temporary data
namereg s1, addr ;reg for temporary mem & i/o port addr
namereg s2, i ;general-purpose loop index
;global variables
namereg sc, switch_a_b ;ram offset for current switch input
namereg sd, tx_data ;data to be tx by uart
;=========================================================
; Port alias
;=========================================================
;------------input port definitions---------------------
constant rd_flag_port, 00
; 4 flags (xxxxtrsc):
; t: uart tx full
; r: uart rx not empty
; s: s button flag
; c: c button flag
constant sw_port, 01 ;8-bit switches
constant uart_rx_port, 02 ;uart receiver port
constant mult_prod0_port, 03 ;multiplication product 8 LSBs
constant mult_prod1_port, 04 ;multiplication product 8 MSBs
;------------output port definitions---------------------
constant sseg0_port, 00 ;7-seg led 0
constant sseg1_port, 01 ;7-seg led 1
constant sseg2_port, 02 ;7-seg led 2
constant sseg3_port, 03 ;7-seg led 3
constant uart_tx_port, 04 ;uart receiver port
constant mult_src0_port, 05 ;multiplier operand 0
constant mult_src1_port, 06 ;multiplier operand 1
;=========================================================
; Main program
;=========================================================
;Calling hierarchy:
;
;main
; - init
; - tx_prompt
; - tx_one_byte
; - proc_btn
; - init
; - proc_uart
; - tx_prompt
; - init
; - proc_uart_err
; - tx_one_byte
; - dump_mem
; - tx_prompt
; - disp_ram_addr
; - tx_one_byte
; - disp_ram_data
; - tx_one_byte
; - get_upper_nibble
; - get_lower_nibble
; - hex_to_ascii
; - square
; - mult_hard
; - load_led_pttn
; - get_lower_nibble
; - get_upper_nibble
; - hex_to_led
; - disp_led
;
; =========================================================
call init ;initialization
forever:
;main loop body
call proc_btn ;check & process buttons
call proc_uart ;check & process uart rx
call square ;calculate square
call load_led_pttn ;store led patterns to ram
call disp_led ;output led pattern
jump forever
;=========================================================
;routine: init
; function: perform initialization, clear register/ram
; output register:
; switch_a_b: cleared to 0
; temp register: data, i
;=========================================================
init:
;clear memory
load i, 40 ;unitize loop index to 64
load data, 00
clr_mem_loop:
store data, (i)
sub i, 01 ;dec loop index
jump nz, clr_mem_loop ;repeat until i=0
;clear register
load switch_a_b, 00
call tx_prompt
return
;=========================================================
;routine: proc_btn
; function: check two buttons and process the display
; input reg:
; switch_a_b: ram offset (0 for a and 2 for b)
; output register:
; s3: store input port flag
; switch_a_b: may be toggled
; temp register used: data, addr
;=========================================================
proc_btn:
input s3, rd_flag_port ;get flag
;check and process c button
test s3, 01 ;check c button flag
jump z, chk_btns ;flag not set
call init ;flag set, clear
jump proc_btn_done
chk_btns:
;check and process s button
test s3, 02 ;check s button flag
jump z, proc_btn_done ;flag not set
input data, sw_port ;get switch
load addr, a_lsb ;get addr of a
add addr, switch_a_b ;add offset
store data, (addr) ;write data to ram
;update current disp position
xor switch_a_b, 02 ;toggle between 00, 02
proc_btn_done:
return
;=========================================================
;routine: proc_uart
; function: read uart input char:
; a or b: read a or b from switch;
; c: clear; d: dump/display data ram other: error
; input reg: s3 (input port flag)
; temp register used: data
; s4: store received uart char or 00 (no uart input)
;=========================================================
proc_uart :
test s3, 04 ;check uart rx status
jump z, uart_rx_done ;go to done if rx empty
;process received char
input s4, uart_rx_port ;get char
;check if received char is a
compare s4, ASCII_a ;check ASCII a
jump nz, chk_ascii_b ;no, check next
input data, sw_port ;get switch
store data, a_lsb ;writ a to data ram
call tx_prompt ;new prompt line
jump uart_rx_done
chk_ascii_b:
;check if received char is b
compare s4, ASCII_b ;check ASCII b
jump nz, chk_ascii_c ;no, check next
input data, sw_port ;get switch
store data, b_lsb ;writ b to data ram
call tx_prompt ;new prompt line
jump uart_rx_done
chk_ascii_c:
;check if received char is c
compare s4, ASCII_c ;check ASCII c
jump nz, chk_ascii_d ;no check next
call init ;clear
jump uart_rx_done
chk_ascii_d:
;check if received char is d
compare s4, ASCII_d ;check ASCII d
jump nz, ascii_undefined
call dump_mem ;dump/display ram
jump uart_rx_done
ascii_undefined:
;undefined char
call proc_uart_error
uart_rx_done:
return
;=========================================================
;routine: proc_uart_error
; function: display "Error" for unknown uart char
;=========================================================
proc_uart_error:
load tx_data, ASCII_LF
call tx_one_byte ;transmit LF
load tx_data, ASCII_CR
call tx_one_byte ;transmit CR
load tx_data, ASCII_SP
call tx_one_byte ;transmit SP
call tx_one_byte ;transmit SP
load tx_data, ASCII_E
call tx_one_byte ;transmit E
load tx_data, ASCII_r
call tx_one_byte ;transmit r
load tx_data, ASCII_r
call tx_one_byte ;transmit r
load tx_data, ASCII_o
call tx_one_byte ;transmit o
load tx_data, ASCII_r
call tx_one_byte ;transmit r
call tx_prompt
return
;=========================================================
;routine: dump_mem
; function: when d received, dump 64 bytes of ram as
; 001000 XX XX XX XX XX XX XX XX
; 010000 XX XX XX XX XX XX XX XX
; . . .
; 111000 XX XX XX XX XX XX XX XX
; temp register used:
; s3: as outer loop index
; s4: ram base address
;=========================================================
dump_mem:
load s3, 00 ;addr used as loop index
dump_loop:
;loop body
load s4, s3 ;get ram base addr (xxx000)
sl0 s4
sl0 s4
sl0 s4
call disp_ram_addr
call disp_ram_data
add s3, 01 ;inc loop index
compare s3, 08
jump nz, dump_loop ;loop not reach 8 yet
call tx_prompt ;new prompt
return
;=========================================================
;routine: tx_prompt
; function: generate prompt "SQ>"
; temp register: tx_data
;=========================================================
tx_prompt:
load tx_data, ASCII_LF
call tx_one_byte ;transmit LF
load tx_data, ASCII_CR
call tx_one_byte ;transmit CR
load tx_data, ASCII_S
call tx_one_byte ;transmit S
load tx_data, ASCII_Q
call tx_one_byte ;transmit Q
load tx_data, ASCII_GT
call tx_one_byte ;transmit >
load tx_data, ASCII_SP
call tx_one_byte ;transmit SP
return
;=========================================================
;routine: disp_ram_addr
; function: display 6-bit ram addr
; bbb000
; input register:
; s4: base address
; temp register:
; i, s7: 1-bit mask
;=========================================================
disp_ram_addr:
;new line
load tx_data, ASCII_LF
call tx_one_byte ;transmit LF
load tx_data, ASCII_CR
call tx_one_byte ;transmit CR
load tx_data, ASCII_SP
call tx_one_byte ;transmit SP
call tx_one_byte ;transmit SP
;initialize the loop index and mask
load i, 06 ;addr used as loop index
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -