491 lines
14 KiB
NASM
491 lines
14 KiB
NASM
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
;; ;;
|
||
|
;; 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:
|