From c85f112a58e8d16d0555026ef4776f96224db1a1 Mon Sep 17 00:00:00 2001 From: hidnplayr Date: Thu, 16 Jan 2014 22:04:38 +0000 Subject: [PATCH] New terminal application. git-svn-id: svn://kolibrios.org@4462 a494cfbc-eb01-0410-851d-a64ba20cac60 --- programs/system/terminal/terminal.asm | 491 ++++++++++++++++++++++++++ 1 file changed, 491 insertions(+) create mode 100644 programs/system/terminal/terminal.asm diff --git a/programs/system/terminal/terminal.asm b/programs/system/terminal/terminal.asm new file mode 100644 index 0000000000..41a3348e8d --- /dev/null +++ b/programs/system/terminal/terminal.asm @@ -0,0 +1,491 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2014. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; terminal for KolibriOS ;; +;; ;; +;; Written by hidnplayr@kolibrios.org ;; +;; ;; +;; GNU GENERAL PUBLIC LICENSE ;; +;; Version 2, June 1991 ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +format binary as "" + +use32 + org 0x0 + + db 'MENUET01' + dd 0x1 + dd START + dd I_END + dd IM_END+0x1000 + dd IM_END+0x1000 + dd 0, 0 + +include '../../proc32.inc' +include '../../macros.inc' +include '../../dll.inc' +include '../../develop/libraries/box_lib/trunk/box_lib.mac' + + +START: + + mcall 68, 11 + + stdcall dll.Load, @IMPORT + or eax, eax + jnz exit + + mcall 40, EVM_MOUSE + EVM_MOUSE_FILTER + EVM_REDRAW + EVM_BUTTON + EVM_KEY + + invoke init_checkbox, ch1 + +red_win: + call draw_window + +mainloop: + mcall 10 + + dec eax + jz red_win + + dec eax + jz key + + dec eax + jz button + + invoke edit_box_mouse, edit1 + invoke edit_box_mouse, edit2 + invoke edit_box_mouse, edit3 + invoke edit_box_mouse, edit4 + + invoke option_box_mouse, Option_boxs1 + invoke option_box_mouse, Option_boxs2 + + invoke check_box_mouse, ch1 + + jmp mainloop + +button: + mcall 17 + + cmp ah, 0x10 ; connect button + je open_connection + + test ah , ah + jz mainloop +exit: + mcall -1 + +key: + mcall 2 + + cmp ah, 13 ; enter key + je open_connection + + invoke edit_box_key, edit1 + invoke edit_box_key, edit2 + invoke edit_box_key, edit3 + invoke edit_box_key, edit4 + + jmp mainloop + + + +draw_window: +; get system colors + mcall 48, 3, sc, 40 + + mcall 12,1 + mov edx, [sc.work] + or edx, 0x34000000 + xor esi, esi + mov edi, str_title + mcall 0, 50 shl 16 + 400, 30 shl 16 + 180 + + mov ebx, 5 shl 16 + 15 + mov ecx, 0x80000000 + or ecx, [sc.work_text] + mov edx, str_port + mcall 4 + mov ebx, 5 shl 16 + 35 + mov edx, str_speed + mcall + mov ebx, 5 shl 16 + 55 + mov edx, str_data + mcall + mov ebx, 5 shl 16 + 75 + mov edx, str_stop + mcall + + mov ebx, 180 shl 16 + 10 + mov edx, str_parity + mcall + mov ebx, 270 shl 16 + 10 + mov edx, str_flow + mcall + + invoke edit_box_draw, edit1 + invoke edit_box_draw, edit2 + invoke edit_box_draw, edit3 + invoke edit_box_draw, edit4 + + invoke option_box_draw, Option_boxs1 + invoke option_box_draw, Option_boxs2 + + invoke check_box_draw, ch1 + + mov esi, [sc.work_button] + mcall 8, 270 shl 16 + 100, 105 shl 16 + 16, 0x10 + + mov ecx, 0x80000000 + or ecx, [sc.work_button_text] + mcall 4, 300 shl 16 + 110, , str_open + + + mov edx, [sc.work_graph] + mcall 38, 0 shl 16 + 390, 135 shl 16 + 135 + + mov ecx, 0x80000000 + or ecx, [sc.work_text] + mcall 4, 5 shl 16 + 142, , [errormsg] + + mcall 12, 2 + ret + + +open_connection: + + mov [errormsg], err_none ; clear previous error message + +; Read the serial port name, and convert it to a port number + cmp byte[ed_port+4], 0 + jne .port_error + mov eax, dword[ed_port] + or eax, 0x20202020 ; convert to lowercase + cmp eax, 'com1' + je .com1 + cmp eax, 'com2' + je .com2 + cmp eax, 'com3' + je .com3 + cmp eax, 'com4' + je .com4 + .port_error: + mov [errormsg], err_port + jmp red_win + + .com1: + mov [port], 0x3f8 + jmp .port_ok + .com2: + mov [port], 0x2f8 + jmp .port_ok + .com3: + mov [port], 0x3e8 + jmp .port_ok + .com4: + mov [port], 0x2e8 + .port_ok: + +; reserve the com port so we can work with it + xor ebx, ebx + movzx ecx, [port] + mov edx, ecx + add edx, 7 + mcall 46 + test eax, eax + jz .port_reserved + mov [errormsg], err_reserve + jmp red_win + .port_reserved: + +; disable com interrupts +; (We cannot receive them on the application level :( ) + mov dx, [port] + inc dx + mov al, 0 + out dx, al + +; Set speed: +; Convert the ascii decimal number that user entered +; So we can do some math with it + mov esi, ed_speed + xor eax, eax + xor ebx, ebx + .convert_loop: + lodsb + test al, al + jz .convert_done + sub al, '0' + jb .invalid_speed + cmp al, 9 + ja .invalid_speed + lea ebx, [ebx + 4*ebx] + shl ebx, 1 + add ebx, eax + jmp .convert_loop + .invalid_speed: + call free_port + mov [errormsg], err_speed + jmp red_win + .convert_done: + test ebx, ebx + jz .invalid_speed + +; We now have the speed setting in ebx +; calculate the divisor latch value as 115200/ebx + xor edx, edx + mov eax, 115200 + div ebx + test edx, edx + jnz .invalid_speed + cmp eax, 0xffff + ja .invalid_speed + mov bx, ax + +; enable Divisor latch + mov dx, [port] + add dx, 3 + mov al, 1 shl 7 ; dlab bit + out dx, al + +; Set divisor latch value + mov dx, [port] + mov al, bl + out dx, al + inc dx + mov al, bh + out dx, al + +; Check the parity type + xor bl, bl + cmp [option_group1], op1 ; none + je .parity_ok + + mov bl, 001b shl 3 + cmp [option_group1], op2 ; odd + je .parity_ok + + mov bl, 011b shl 3 + cmp [option_group1], op3 ; even + je .parity_ok + + mov bl, 101b shl 3 + cmp [option_group1], op4 ; mark + je .parity_ok + + mov bl, 111b shl 3 + cmp [option_group1], op5 ; space + je .parity_ok + jmp exit2 ; something went terribly wrong + .parity_ok: + +; Check number of stop bits + cmp [ed_stop], '1' + je .stop_ok + cmp [ed_stop], '2' + jne .invalid_stop + or bl, 1 shl 2 ; number of stop bits + jmp .stop_ok + .invalid_stop: + call free_port + mov [errormsg], err_stopbits + jmp red_win + .stop_ok: + +; Check number of data bits + mov al, [ed_data] + cmp al, '8' + ja .invalid_data + sub al, '5' + jae .data_ok + .invalid_data: + call free_port + mov [errormsg], err_databits + jmp red_win + .data_ok: + or al, bl +; Program data bits, stop bits and parity in the UART + mov dx, [port] + add dx, 3 ; Line Control Register + out dx, al + +; clear + enable fifo (64 bytes), 1 byte trigger level + mov dx, [port] + inc dx + inc dx + mov al, 0x7 + 1 shl 5 + out dx, al + +; flow control + mov dx, [port] + add dx, 4 + mov al, 0xb + out dx, al + +; Hide our GUI window and open the console + mcall 40, 0 ; disable all events + mcall 67, 0, 0, 0, 0 ; hide window + mcall 12, 1 + mcall 12, 2 + + invoke con_start, 1 + invoke con_init, 80, 25, 80, 25, str_title + +console_loop: + mcall 5, 1 ; wait 10 ms + + invoke con_get_flags + test eax, 0x200 ; con window closed? + jnz exit2 + + .tx_loop: + invoke con_kbhit + test eax, eax ; did user press a key? + jz .rx_loop + + invoke con_getch2 ; get the pressed key from buffer + mov dx, [port] + out dx, al + + test [ch1.flags], ch_flag_en ; does user want us to echo locally? + je .tx_loop + + and eax, 0xff + push eax + invoke con_write_asciiz, esp ; print the character + pop eax + jmp .tx_loop + + .rx_loop: + mov dx, [port] + add dx, 5 ; Line status register + in al, dx + test al, 1 ; Data ready? + jz console_loop + + mov dx, [port] ; Read character from buffer + in al, dx + + and eax, 0xff + push eax + invoke con_write_asciiz, esp ; print the character + pop eax + + jmp .rx_loop + + +exit2: + + call free_port + mcall -1 ; exit + +free_port: + + xor ebx, ebx + inc ebx + movzx ecx, [port] + mov edx, ecx + add edx, 7 + mcall 46 + + ret + +;------------------------- +; DATA + +align 16 +@IMPORT: + +library box_lib, 'box_lib.obj',\ + console, 'console.obj' + +import box_lib,\ + edit_box_draw, 'edit_box',\ + edit_box_key, 'edit_box_key',\ + edit_box_mouse, 'edit_box_mouse',\ + init_checkbox, 'init_checkbox2',\ + check_box_draw, 'check_box_draw2',\ + check_box_mouse, 'check_box_mouse2',\ + option_box_draw, 'option_box_draw',\ + option_box_mouse, 'option_box_mouse' + +import console,\ + con_start, 'START',\ + con_init, 'con_init',\ + con_exit, 'con_exit',\ + con_getch2, 'con_getch2',\ + con_write_asciiz, 'con_write_asciiz',\ + con_get_flags, 'con_get_flags',\ + con_kbhit, 'con_kbhit' + +edit1 edit_box 60, 90, 10, 0xffffff, 0x6f9480, 0, 0, 0, 8, ed_port, mouse_dd, ed_focus, 4, 4 +edit2 edit_box 60, 90, 30, 0xffffff, 0x6a9480, 0, 0, 0, 7, ed_speed, mouse_dd, ed_figure_only, 4, 4 +edit3 edit_box 60, 90, 50, 0xffffff, 0x6a9480, 0, 0, 0, 1, ed_data, mouse_dd, ed_figure_only, 1, 1 +edit4 edit_box 60, 90, 70, 0xffffff, 0x6a9480, 0, 0, 0, 1, ed_stop, mouse_dd, ed_figure_only, 1, 1 + +ed_port db "COM1",0,0,0,0,0,0 +ed_speed db "9600",0,0,0 +ed_data db "8",0 +ed_stop db "1",0 + +option_group1 dd op1 +op1 option_box option_group1, 180, 27, 6, 12, 0xffffff, 0, 0, str_none, 4 +op2 option_box option_group1, 180, 44, 6, 12, 0xffffff, 0, 0, str_odd, 3 +op3 option_box option_group1, 180, 61, 6, 12, 0xffffff, 0, 0, str_even, 4 +op4 option_box option_group1, 180, 78, 6, 12, 0xffffff, 0, 0, str_mark, 4 +op5 option_box option_group1, 180, 95, 6, 12, 0xffffff, 0, 0, str_space, 5 + +option_group2 dd op6 +op6 option_box option_group2, 270, 27, 6, 12, 0xffffff, 0, 0, str_none, 4 +;op7 option_box option_group2, 270, 44, 6, 12, 0xffffff, 0, 0, str_xon, 8, 10b +;op8 option_box option_group2, 270, 61, 6, 12, 0xffffff, 0, 0, str_rts, 7, 1b +;op9 option_box option_group2, 270, 78, 6, 12, 0xffffff, 0, 0, str_dsr, 7 + +ch1 check_box2 5 shl 16 + 12, 105 shl 16 + 12, 5, 0xffffff, 0x000000, 0x000000, str_echo, ch_flag_middle + +Option_boxs1 dd op1, op2, op3, op4, op5, 0 +Option_boxs2 dd op6, 0 ;op7, op8, op9, 0 + +str_title db 'Terminal', 0 +str_port db 'Serial port:', 0 +str_speed db 'Speed (baud):', 0 +str_data db 'Data bits:', 0 +str_parity db 'Parity:', 0 +str_flow db 'Flow control:', 0 +str_stop db 'Stop bits:', 0 + +str_open db 'Open', 0 + +str_none db 'None' +str_odd db 'Odd' +str_even db 'Even' +str_mark db 'Mark' +str_space db 'Space' +;str_xon db 'XON/XOFF' +;str_rts db 'RTS/CTS' +;str_dsr db 'DSR/DTR' + +str_echo db 'Local echo', 0 + +errormsg dd err_none +err_none db 0 +err_port db 'Invalid serial port.', 0 +err_reserve db 'The port is already in use.', 0 +err_speed db 'Incorrect speed setting.', 0 +err_stopbits db 'Invalid number of stop bits. Must be 1 or 2.', 0 +err_databits db 'Invalid number of data bits. Must be between 5 and 8.', 0 + +I_END: + +mouse_dd dd ? +echo db ? +port dw ? +sc system_colors + +IM_END: \ No newline at end of file