📄 progctrl.psm
字号:
;
delay_1ms: LOAD s2, 19 ;25 x 40us = 1ms
wait_1ms: CALL delay_40us
SUB s2, 01
JUMP NZ, wait_1ms
RETURN
;
;Delay of 20ms.
;
;Delay of 20ms used during initialisation.
;
;Registers used s0, s1, s2, s3
;
delay_20ms: LOAD s3, 14 ;20 x 1ms = 20ms
wait_20ms: CALL delay_1ms
SUB s3, 01
JUMP NZ, wait_20ms
RETURN
;
;Delay of approximately 1 second.
;
;Registers used s0, s1, s2, s3, s4
;
delay_1s: LOAD s4, 14 ;50 x 20ms = 1000ms
wait_1s: CALL delay_20ms
SUB s4, 01
JUMP NZ, wait_1s
RETURN
;
;
;**************************************************************************************
;UART communication routines
;**************************************************************************************
;
;Read one character from the UART
;
;Character read will be returned in a register called 'UART_data'.
;
;The routine first tests the receiver FIFO buffer to see if data is present.
;If the FIFO is empty, the routine waits until there is a character to read.
;As this could take any amount of time the wait loop could include a call to a
;subroutine which performs a useful function.
;
;If the received character is an XOFF, then the routine will then wait
;for an XON to be received. This means that the rest of the program is held
;in suspense and therefore it can not transmit. Once an XON is received, it will
;again wait for a normal character before returning.
;
;NOTE: Characters between the XOFF and XON will be ignored in this version of the
;program!!!
;
;Interrupt is disabled during this routine to prevent a false situation. If the
;receiver half-full flag went High it should result in an interrupt transmitting
;an XOFF character. However, if this routine were able to read the receiver buffer
;at just about the same as the hardware detects the half-full flag, then it could
;think that an XON needs to be transmitted.
;
;
;Registers used s0 and UART_data
;
read_from_UART: DISABLE INTERRUPT
wait_Rx_character: INPUT s0, status_port ;test Rx_FIFO buffer
TEST s0, rx_data_present
JUMP NZ, read_character
JUMP wait_Rx_character
read_character: INPUT UART_data, UART_read_port ;read from FIFO
COMPARE UART_data, character_XOFF ;test for XOFF
JUMP Z, wait_XON
ENABLE INTERRUPT ;normal finish
RETURN
wait_XON: INPUT s0, status_port ;test Rx_FIFO buffer
TEST s0, rx_data_present
JUMP NZ, read_XON
JUMP wait_XON
read_XON: INPUT UART_data, UART_read_port ;read from FIFO
COMPARE UART_data, character_XON ;test for XON
JUMP Z, wait_Rx_character ;now wait for normal character
JUMP wait_XON ;continue to wait for XON
;
;
;
;Transmit one character to the UART
;
;Character supplied in register called 'UART_data'.
;
;The routine first tests the transmit FIFO buffer is empty.
;If the FIFO currently has any data, the routine waits until it is empty.
;Ultimately this means that only one character is sent at a time which
;could be important if the PC at the other end of the link transmits
;an XOFF and needs the flow of data to terminate as soon as possible.
;
;Registers used s0
;
send_to_UART: INPUT s0, status_port ;test Tx_FIFO buffer
TEST s0, tx_data_present
JUMP Z, UART_write
JUMP send_to_UART
UART_write: OUTPUT UART_data, UART_write_port
RETURN
;
;
;**************************************************************************************
;Useful ASCII conversion and handling routines
;**************************************************************************************
;
;Convert value provided in register s0 into ASCII characters
;
;The value provided must in the range 0 to 99 and will be converted into
;two ASCII characters.
; The number of 'tens' will be represented by an ASCII character returned in register s1.
; The number of 'units' will be represented by an ASCII character returned in register s0.
;
;The ASCII representations of '0' to '9' are 30 to 39 hexadecimal which is simply 30 hex added to
;the actual decimal value.
;
;Registers used s0 and s1.
;
decimal_to_ASCII: LOAD s1, 30 ;load 'tens' counter with ASCII for '0'
test_for_ten: ADD s1, 01 ;increment 'tens' value
SUB s0, 0A ;try to subtract 10 from the supplied value
JUMP NC, test_for_ten ;repeat if subtraction was possible without underflow.
SUB s1, 01 ;'tens' value one less ten due to underflow
ADD s0, 3A ;restore units value (the remainder) and convert to ASCII
RETURN
;
;
;
;Convert character to upper case
;
;The character supplied in register s0.
;If the character is in the range 'a' to 'z', it is converted
;to the equivalent upper case character in the range 'A' to 'Z'.
;All other characters remain unchanged.
;
;Registers used s0.
;
upper_case: COMPARE s0, 61 ;eliminate character codes below 'a' (61 hex)
RETURN C
COMPARE s0, 7B ;eliminate character codes above 'z' (7A hex)
RETURN NC
AND s0, DF ;mask bit5 to convert to upper case
RETURN
;
;
;Convert character '0' to '9' to numerical value in range 0 to 9
;
;The character supplied in register s0. If the character is in the
;range '0' to '9', it is converted to the equivalent decimal value.
;Characters not in the range '0' to '9' are signified by the return
;with the CARRY flag set.
;
;Registers used s0.
;
1char_to_value: ADD s0, C6 ;reject character codes above '9' (39 hex)
RETURN C ;carry flag is set
SUB s0, F6 ;reject character codes below '0' (30 hex)
RETURN ;carry is set if value not in range
;
;
;Determine the numerical value of a two character decimal string held in
;scratch pad memory such the result is in the range 0 to 99 (00 to 63 hex).
;
;The string must be stored in two consecutive memory locations and the
;location of the first (tens) character supplied in the s1 register.
;The result is provided in register s2. Strings not using characters in the
;range '0' to '9' are signified by the return with the CARRY flag set.
;
;Registers used s0, s1 and s2.
;
2char_to_value: FETCH s0, (s1) ;read 'tens' character
CALL 1char_to_value ;convert to numerical value
RETURN C ;bad character - CARRY set
LOAD s2, s0
SL0 s2 ;multiply 'tens' value by 10 (0A hex)
SL0 s2
ADD s2, s0
SL0 s2
ADD s1, 01 ;read 'units' character
FETCH s0, (s1)
CALL 1char_to_value ;convert to numerical value
RETURN C ;bad character - CARRY set
ADD s2, s0 ;add units to result and clear CARRY flag
RETURN
;
;
;Convert hexadecimal value provided in register s0 into ASCII characters
;
;The value provided must can be any value in the range 00 to FF and will be converted into
;two ASCII characters.
; The upper nibble will be represented by an ASCII character returned in register s2.
; The lower nibble will be represented by an ASCII character returned in register s1.
;
;The ASCII representations of '0' to '9' are 30 to 39 hexadecimal which is simply 30 hex
;added to the actual decimal value. The ASCII representations of 'A' to 'F' are 41 to 46
;hexadecimal requiring a further addition of 07 to the 30 already added.
;
;Registers used s0, s1 and s2.
;
hex_byte_to_ASCII: LOAD s1, s0 ;remember value supplied
SR0 s0 ;isolate upper nibble
SR0 s0
SR0 s0
SR0 s0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -