| ??? 05/14/07 22:17 Read: times |
#139249 - ReceiveString, rev.1 Responding to: ???'s previous message |
;------------------------------------------------------------------------------
; ReceiveString I modified slightly the specs. Comments? JW ;------------------------------------------------------------------------------
; DESCRIPTION: This subroutine is called from many places to receive a line of
; input from a human user via a terminal connected to the onboard
; UART. Each line of input starts with the first character
; entered after this subroutine is called, and ends with a
; carriage return.
;
; This subroutine accumulates the data in a buffer called
; 'RxBuffer', which is located in the internal data RAM and is
; accessed only via indirect addressing (i.e. can be located
; in the upper 128 bytes).
; The symbol RX_BUFFER_SIZE gives the size of the buffer,
; in bytes. Note, that to be able to store the trailing zero,
; the actual number of characters received is maximum
; RX_BUFFER_SIZE-1.
;
; On entry, this function does minor internal housekeeping to
; prepare for a new line of input (i.e. resets the pointer :-)
; It then receives characters one by one from the user.
; It handles each received character as follows:
;
; - Backspace (08h): If the buffer is not empty, removes the
; newest character from the buffer and echoes the
; three-character sequence 08h 20h 08h (backspace space
; backspace) to the terminal to erase the most recently typed
; character from the user's screen. If the buffer is empty
; when the backspace character is received, echoes a single
; 07h (beep) to the terminal.
;
; - Carriage Return (0Dh): Appends zero character to the buffer
; to mark the end of the line and returns to the caller with
; the accumulator set to NO_ERROR.
;
; - Printable characters (20h through 7Eh, inclusive): If the
; buffer is full, echoes a single 07h (beep) to the terminal.
; Otherwise appends the character to the buffer.
;
; - All other characters: Does nothing.
;
; As noted above, this function returns when it receives a
; carriage return. Nothing specific is returned in registers.
;
; The function won't guarantee to keep the value of registers
; (this is the standard behaviour of C routines both in Keil
; and SDCC), although resources usage will be determined and
; noted below.
;
; A test program is written to try the routine, which is not
; part of the routine. Test with Hyperterminal or equivalent,
; 9600 baud, 8N1, no handshake, auto terminal mode.
; Should beep when 10th character is attempted to be entered.
; Deleting should "eat" characters until the last one, after
; it deleting should beep. After enter, should write
; number of characters and the string again.
;
;
;
;
; REVISIONS: 13 May 07 - RAC - Initial specification
; 13 May 07 - JW - modified specification & initial implementation
; -----------------------------------------------------------------------------
;---- TEST main
RxBuffer EQU 30h
RX_BUFFER_SIZE EQU 10
CSEG AT 0
; assumes X=18.432MHz and baud=9600
;-- init first
mov SCON,#52h ;set serial mode 1
ORL PCON,#80h
mov TMOD,#21h ;timer0 16-bit, timer1 autoreload
mov TH1,#-10 ;0FAh ;9600
setb tr1 ;enable timer 1
Loop:
;-- call the ReceiveString itself
call ReceiveString
;-- print a CRLF
call TxCRLF
;-- then print the string length (i.e. exit value of R0 minus the base)
mov a,r0
clr c
subb a,#RxBuffer
call TxHexa
call TxCRLF
;-- finally print the string itself
mov r0,#RxBuffer
Loop1:
mov a,@r0
jz Loop2
call TxChar
inc r0
sjmp Loop1
Loop2:
;-- print a CRLF
call TxCRLF
;-- and loop infinitely
sjmp Loop
;-- some print utilities
TxCRLF:
mov a,#13
call TxChar
mov a,#10
call TxChar
ret
TxHexa:
push acc
swap a
anl a,#0Fh
add a,#TxHexaT-TxHexaX1
movc a,@a+pc
TxHexaX1:
call TxChar
pop acc
anl a,#0Fh
add a,#TxHexaT-TxHexaX2
movc a,@a+pc
TxHexaX2:
;fallover
TxChar:
jnb ti,$
clr ti
mov sbuf,a
ret
TxHexaT:
db '0123456789ABCDEF'
;---- end of TEST
;
;-- uses and destroys r0 and acc only
; no stack, no external memory, no interrupts disable
;
ReceiveString:
mov r0,#RxBuffer ;initialize receiver pointer
jb ti,LoopReceive ;security measure - if somebody forgets to set ti
setb ti ; this prevents deadlock later in sending char
LoopReceive:
jnb ri,$ ;wait until character received
clr ri
mov a,SBUF ;get the received character
jb acc.7,LoopReceive ;if unprintable (>= 80h), ignore it
cjne a,#20h,$+3
jc ControlChars ;if control char (<20h), separate processing
cjne r0,#RxBuffer+RX_BUFFER_SIZE-1,StoreChar
EchoBeep: ;this would overflow - beep
mov a,#07h
sjmp SendChar
StoreChar: ;printable character:
mov @r0,a ;put it into buffer
inc r0 ;bump pointer
SendChar:
jnb ti,$
clr ti
mov SBUF,a
sjmp LoopReceive ;and continue receiving
ControlChars:
cjne a,#08h,NotBackSpace
cjne r0,#RxBuffer,EatCharacter ;if BackSpace, eat last character
sjmp EchoBeep ;if empty buffer, just beep
EatCharacter:
jnb ti,$ ;do what is needed to eat a character
clr ti ;on the terminal
mov SBUF,#08h
jnb ti,$
clr ti
mov SBUF,#' '
jnb ti,$
clr ti
mov SBUF,#08h
dec r0 ;and do the pointer decrement itself
sjmp LoopReceive
NotBackSpace:
cjne a,#0Dh,LoopReceive ;if not Carriage Return, receive more characters
mov @r0,#0 ;put endmark
ret
end
|



