; Author: Pawel Jablonski ; E-mail: pj@xirx.net ; WWW: xirx.net ; GIT: git.xirx.net ; ; License: You can use this code however you like ; but leave information about the original author. ; Code is free for non-commercial and commercial use. map ../../../bin/rom/rom.map ; TX buffer usage counter var txLength ; TX buffer var txBuffer[39] ; RX buffer usage counter var rxLength ; RX buffer var rxBuffer[39] ; Displayed lines counter var lineQuantity ; First label is the entry point .entry: call .main ret ; No arguments ; No return .main: push A ; Reset counters and buffers str 0, *txLength str 0, *txBuffer str 0, *rxLength str 0, *rxBuffer str 0, *lineQuantity ; Clear screen call .xLcdClear ; Show input call .showInput ; Refresh screen call .xLcdRefresh ; Keyboard and rs232 event loop .main_loop: ; Check if key was clicked call .xKeyboardIsDataReady cmp 0, A jne .main_processKey ; Check if RX data is ready to read call .xRS232IsRxDataReady cmp 0, A jne .main_processReceive ; Jump back to the beginning of event loop jmp .main_loop ; Start processing key press event .main_processKey: call .xKeyboardGetChar ; Exit if clicked key is ESC cmp 0x1b, A je .main_end call .processKey ; Jump back to the beginning of event loop jmp .main_loop ; Start processing RX data event .main_processReceive: call .xRS232Receive call .processReceive ; Jump back to the beginning of event loop jmp .main_loop .main_end: pop A ret ; Arguments: ; A - keycode ; No return .processKey: push A ; Check for backspace cmp 0x08, A je .processKey_backspace ; Check for enter cmp 0x0d, A je .processKey_enter ; Check for not printable char ; 0x20 > A cmp 0x20, A jg .processKey_notPrint ; 0x80 <= A cmp 0x80, A jle .processKey_notPrint push B ; Check current length of buffer ldr *txLength, B ; 38 =< B cmp 38, B jle .processKey_bufferFull push X push Y ; Set address to TX buffer mov low(*txBuffer), X mov high(*txBuffer), Y ; Move to working position add B, X incc Y ; Store keycode str A ; Clear register clr A ; Move to next position inc X incc Y ; Store termination code str A ; Increment TX buffer position inc B ; Store current TX buffer position str B, *txLength ; Show input call .showInput ; Refresh screen call .xLcdRefresh .processKey_end: pop Y pop X .processKey_bufferFull: pop B .processKey_notPrint: pop A ret ; Remove last char from TX buffer .processKey_backspace: ; Load TX buffer position ldr *txLength, A ; 0 == A cmp 0, A ; Do nothing if buffer is empty je .processKey_notPrint push X push Y ; Decrement buffer position dec A ; Store current TX buffer position str A, *txLength ; Set address to TX buffer mov low(*txBuffer), X mov high(*txBuffer), Y ; Move to working position add A, X incc Y ; Clear register clr A ; Store termination code str A ; Show input call .showInput ; Refresh screen call .xLcdRefresh pop Y pop X pop A ret ; Enter key was pressed .processKey_enter: ; Load TX buffer position ldr *txLength, A ; 0 == A cmp 0, A ; Do nothing if buffer is empty je .processKey_notPrint ; Send buffer content call .sendString ; Print buffer content call .printSentString ; Reset TX counter and TX buffer str 0, *txLength str 0, *txBuffer ; Show input call .showInput ; Refresh screen call .xLcdRefresh pop A ret ; Arguments ; A - RX data ; No return .processReceive: ; Check for end of string cmp 0, A je .processReceive_endString ; Check for LF code cmp 0x0a, A je .processReceive_endString ; Check for not printable char ; 0x20 > A cmp 0x20, A jg .processReceive_end ; 0x80 <= A cmp 0x80, A jle .processReceive_end push B push X push Y ; Load RX buffer position ldr *rxLength, B ; Set address to RX buffer mov low(*rxBuffer), X mov high(*rxBuffer), Y ; Move to working position add B, X incc Y ; Store RX data str A ; Move to next position inc X incc Y ; Store termination code str 0 ; Increment RX buffer position inc B ; Store current RX buffer position str B, *rxLength pop Y pop X ; Check current length of buffer ; 38 > B cmp 38, B pop B ; Go to end if is is free space in RX buffer jg .processReceive_end push A ; Prepare termination code clr A ; Call itself for process full buffer call .processReceive pop A ret .processReceive_endString: ; Load RX buffer position ldr *rxLength, A ; 0 == A cmp 0, A ; Do not print empty string je .processReceive_end ; Print buffer content call .printReceivedString ; Reset RX counter and RX buffer str 0, *rxLength str 0, *rxBuffer ; Show input call .showInput ; Refresh screen call .xLcdRefresh .processReceive_end: ret ; No arguments ; No return .showInput: push A push B push X push Y ; Set draw start position mov 0, X mov 28, Y call .xStringSetCursor ; Set clear char mov ' ', A ; Reset counter clr B .showInput_blankLoop: ; Print clear char call .xStringPrintChar ; Draw 39+1 times loope 39, B, .showInput_blankLoop ; Change colors for input mov 0xf, A call .xLcdSetBackground mov 0x0, A call .xLcdSetForeground ; Set clear char mov ' ', A ; Reset counter clr B .showInput_inputLoop: call .xStringPrintChar ; Draw 39+1 times loope 39, B, .showInput_inputLoop ; Go back at beginning of row mov 0, A call .xStringSetCursorX ; Print prompt mov '>', A call .xStringPrintChar ; Set address to TX buffer mov low(*txBuffer), X mov high(*txBuffer), Y ; Print buffer content call .xStringPrint ; Print cursor mov 0xDB, A call .xStringPrintChar ; Turn back default colors mov 0x0, A call .xLcdSetBackground mov 0xf, A call .xLcdSetForeground pop Y pop X pop B pop A ret ; No arguments ; No return .sendString: push A push B push X push Y ; Set address to TX buffer mov low(*txBuffer), X mov high(*txBuffer), Y ; Load TX buffer position ldr *txLength, B .sendString_loop: ; Load char to send ldr A ; Check for end of string cmp 0, A jne .sendString_send ; Set LF code mov 0x0a, A .sendString_send: ; Send char call .xRS232Send ; Move to next position inc X incc Y ; Repeat B+1 times loopz B, .sendString_loop pop Y pop X pop B pop A ret ; Arguments: ; X - low address ; Y - high address ; No return .printString: push A ; Load drawn line quantity ldr *lineQuantity, A ; 27 <= A cmp 27, A ; Count only 27+1 first lines else scroll screen jle .printString_scroll ; Increment counter inc A ; Store counter to line quantity str A, *lineQuantity jmp .printString_print .printString_scroll: ; Scroll screen to make a space to draw a new line of text call .xLcdScroll .printString_print: push X push Y ; Move cursor to right place to print mov 0, X mov A, Y call .xStringSetCursor pop Y pop X ; Print string from buffer call .xStringPrint pop A ret ; No arguments ; No return .printSentString: push X push Y ; Set address to TX buffer mov low(*txBuffer), X mov high(*txBuffer), Y ; Print buffer on screen call .printString pop Y pop Y ret ; No arguments ; No return .printReceivedString: push A ; Set foregound color to green mov 0x0a, A call .xLcdSetForeground push X push Y ; Set address to RX buffer mov low(*rxBuffer), X mov high(*rxBuffer), Y ; Print buffer on screen call .printString pop Y pop X ; Set foregound color to default mov 0x0f, A call .xLcdSetForeground pop A ret