kolibrios/programs/system/terminal/terminal.asm

497 lines
14 KiB
NASM
Raw Permalink Normal View History

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; 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 + 415, 30 shl 16 + 195
mov ebx, 5 shl 16 + 12
mov ecx, 0x90000000
or ecx, [sc.work_text]
mov edx, str_port
mcall 4
add ebx, 25
mov edx, str_speed
mcall
add ebx, 25
mov edx, str_data
mcall
add ebx, 25
mov edx, str_stop
mcall
mov ebx, 195 shl 16 + 12
mov edx, str_parity
mcall
mov ebx, 280 shl 16 + 12
mov edx, str_flow
mcall
edit_boxes_set_sys_color edit1,editboxes_end,sc
invoke edit_box_draw, edit1
invoke edit_box_draw, edit2
invoke edit_box_draw, edit3
invoke edit_box_draw, edit4
option_boxes_set_sys_color sc, Option_boxs1
option_boxes_set_sys_color sc, Option_boxs2
invoke option_box_draw, Option_boxs1
invoke option_box_draw, Option_boxs2
check_boxes_set_sys_color2 ch1,ch1_end,sc ;set color
invoke check_box_draw, ch1
mov esi, [sc.work_button]
mcall 8, 280 shl 16 + 100, 115 shl 16 + 22, 0x10
mov ecx, 0x90000000
or ecx, [sc.work_button_text]
mcall 4, 315 shl 16 + 119, , str_open
mov edx, [sc.work_graph]
mcall 38, 0 shl 16 + 405, 145 shl 16 + 145
mov ecx, 0x90000000
or ecx, [sc.work_text]
mcall 4, 5 shl 16 + 150, , [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_draw',\
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, 112, 10, 0xffffff, 0x6f9480, 0, 0, 0x10000000, 8, ed_port, mouse_dd, ed_focus, 4, 4
edit2 edit_box 60, 112, 35, 0xffffff, 0x6a9480, 0, 0, 0x10000000, 7, ed_speed, mouse_dd, ed_figure_only, 4, 4
edit3 edit_box 60, 112, 60, 0xffffff, 0x6a9480, 0, 0, 0x10000000, 1, ed_data, mouse_dd, ed_figure_only, 1, 1
edit4 edit_box 60, 112, 85, 0xffffff, 0x6a9480, 0, 0, 0x10000000, 1, ed_stop, mouse_dd, ed_figure_only, 1, 1
editboxes_end:
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, 195, 30, 6, 12, 0xffffff, 0, 0, str_none, 4
op2 option_box option_group1, 195, 47, 6, 12, 0xffffff, 0, 0, str_odd, 3
op3 option_box option_group1, 195, 64, 6, 12, 0xffffff, 0, 0, str_even, 4
op4 option_box option_group1, 195, 81, 6, 12, 0xffffff, 0, 0, str_mark, 4
op5 option_box option_group1, 195, 98, 6, 12, 0xffffff, 0, 0, str_space, 5
option_group2 dd op6
op6 option_box option_group2, 280, 30, 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, 119 shl 16 + 12, 5, 0xffffff, 0x000000, 0, str_echo, ch_flag_middle
ch1_end:
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: