6 Commits

10 changed files with 585 additions and 290 deletions

3
.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
kterm
kterm.kpack
kterm-*.gz

View File

@@ -1,5 +1,26 @@
# Changelog # Changelog
## [0.2.0] - 2025-05-25
### Added
- Option to append LF or CRLF when sending data
- Option to configure data bits
### Fixed
- Properly handle port disconnection
### Changed
- Check serial driver version at startup
- Increase UI margins for better appearance with wide-border skins
- Use system `icons16` instead of embedded icons
## [0.1.1] - 2025-05-12
### Fixed
- Prevent window resize below minimum size
- Don't send message timestamps
## [0.1.0] - 2025-05-11 ## [0.1.0] - 2025-05-11
- First release - First release

21
Makefile Normal file
View File

@@ -0,0 +1,21 @@
VER=$(shell git describe --tags --abbrev=0)
FASM=fasm
KPACK=../kpack/linux/kpack
PKGFILES=kterm kterm.kpack CHANGELOG.md README.md screenshot.png
PKGNAME=kterm-$(VER).tar.gz
.PHONY: clean all
all: $(PKGNAME)
clean:
rm -f kterm kterm.kpack $(PKGNAME)
kterm: kterm.asm
$(FASM) $^ $@
kterm.kpack: kterm
$(KPACK) $^ $@
$(PKGNAME): $(PKGFILES)
tar czf $@ $^

View File

@@ -4,13 +4,13 @@ Simple serial terminal for KolibriOS.
![screenshot](screenshot.png) ![screenshot](screenshot.png)
# Requirements ## Requirements
- [Fasm](https://flatassembler.net/) 1.7x - [Fasm](https://flatassembler.net/) 1.7x
- [Tup](https://gittup.org/tup/) build system (optional) - [Tup](https://gittup.org/tup/) build system (optional)
- KolibriOS commit `#5593d344cd` or newer - KolibriOS commit `#2dfb3ddff3` or newer
# Build instructions ## Build instructions
1. Clone the KolibriOS repository: 1. Clone the KolibriOS repository:

BIN
icons.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 523 B

487
kterm.asm
View File

@@ -15,11 +15,17 @@ use32
dd (i_end + 0x1000) ; esp dd (i_end + 0x1000) ; esp
dd 0, 0 ; I_Param, I_Path dd 0, 0 ; I_Param, I_Path
WIN_BORDER_WIDTH = 5 WIN_MARGIN = 5
WIN_MIN_WIDTH = 150
WIN_MIN_HEIGHT = 200
TOOL_ICON_SIZE = 18
TOOL_BTN_SIZE = 24 ; width and height
SEND_BTN_WIDTH = 40
ED_HEIGHT = 22
FONT_WIDTH = 8 FONT_WIDTH = 8
FONT_HEIGHT = 16 FONT_HEIGHT = 16
SCROLL_WIDTH = 16 SCROLL_WIDTH = 16
SCROLL_TOP = 34 SCROLL_TOP = WIN_MARGIN + TOOL_BTN_SIZE + WIN_MARGIN
RX_BUF_SIZE = 256 RX_BUF_SIZE = 256
LINE_HEADER_LEN = 11 LINE_HEADER_LEN = 11
PORT_STATUS_LEN = 128 PORT_STATUS_LEN = 128
@@ -27,7 +33,11 @@ ED_SEND_MAX_LEN = 256
KEY_ENTER = 13 KEY_ENTER = 13
CONN_WIN_STACK_SIZE = 1024 IMG_RGB_METADATA_SIZE = 8
ICON_SIZE_BYTES = TOOL_ICON_SIZE * TOOL_ICON_SIZE * 3
ICON_SETUP_OFFSET = IMG_RGB_METADATA_SIZE + ICON_SIZE_BYTES * 60
ICON_CONN_OFFSET = IMG_RGB_METADATA_SIZE + ICON_SIZE_BYTES * 4
ICON_CLEAR_OFFSET = IMG_RGB_METADATA_SIZE + ICON_SIZE_BYTES * 63
BTN_CLOSE = 1 BTN_CLOSE = 1
BTN_SETUP = 2 BTN_SETUP = 2
@@ -38,8 +48,11 @@ BTN_SEND = 5
BTN_OK = 2 BTN_OK = 2
BTN_CANCEL = 3 BTN_CANCEL = 3
__DEBUG__ = 0 L_DBG = 0
__DEBUG_LEVEL__ = 0 L_ERR = 1
__DEBUG__ = 1
__DEBUG_LEVEL__ = L_ERR
include '../../proc32.inc' include '../../proc32.inc'
include '../../macros.inc' include '../../macros.inc'
@@ -48,6 +61,8 @@ include '../../dll.inc'
include '../../debug-fdo.inc' include '../../debug-fdo.inc'
include '../../develop/libraries/box_lib/trunk/box_lib.mac' include '../../develop/libraries/box_lib/trunk/box_lib.mac'
include '../../../drivers/serial/common.inc' include '../../../drivers/serial/common.inc'
include 'settings.inc'
include 'textview.inc' include 'textview.inc'
include 'utils.inc' include 'utils.inc'
@@ -57,14 +72,33 @@ start:
call serial_port_init call serial_port_init
test eax, eax test eax, eax
jnz @f jnz @f
DEBUGF L_ERR, "kterm: %s\n", err_driver
mov eax, err_driver mov eax, err_driver
mov [status_msg], eax mov [status_msg], eax
@@: @@:
push 0
stdcall serial_port_get_version, esp
pop eax
DEBUGF L_DBG, "kterm: serial driver version 0x%x\n", eax
shr eax, 16
cmp ax, SERIAL_COMPATIBLE_API_VER
jle @f
mov eax, err_driver_ver
mov [status_msg], eax
@@:
stdcall dll.Load, @IMPORT stdcall dll.Load, @IMPORT
or eax, eax or eax, eax
jnz .exit jnz .exit
invoke img.from_file, icons_file
test eax, eax
jz @f
mov esi, eax
invoke img.to_rgb, esi
mov [icons_rgb], eax
invoke img.destroy, esi
@@:
mcall SF_SET_EVENTS_MASK, EVM_MOUSE + EVM_REDRAW + EVM_BUTTON + EVM_KEY mcall SF_SET_EVENTS_MASK, EVM_MOUSE + EVM_REDRAW + EVM_BUTTON + EVM_KEY
mov byte [ed_send_val], 0 mov byte [ed_send_val], 0
@@ -76,7 +110,7 @@ start:
cmp [is_connected], 0 cmp [is_connected], 0
jz @f jz @f
mov eax, SF_WAIT_EVENT_TIMEOUT mov eax, SF_WAIT_EVENT_TIMEOUT
mov ebx, 100 mov ebx, 10
@@: @@:
mcall mcall
cmp eax, EV_REDRAW cmp eax, EV_REDRAW
@@ -111,7 +145,7 @@ start:
@@: @@:
cmp ah, BTN_SETUP cmp ah, BTN_SETUP
jne @f jne @f
call show_conn_window call show_settings_win
jmp .loop jmp .loop
@@: @@:
cmp ah, BTN_CLEAR cmp ah, BTN_CLEAR
@@ -148,12 +182,6 @@ start:
mcall SF_STYLE_SETTINGS, SSF_GET_COLORS, sc, sizeof.system_colors mcall SF_STYLE_SETTINGS, SSF_GET_COLORS, sc, sizeof.system_colors
mcall SF_REDRAW, SSF_BEGIN_DRAW mcall SF_REDRAW, SSF_BEGIN_DRAW
; fill palette for icons
mov eax, [sc.work_text]
mov [icons.palette], eax
mov eax, [sc.work_light]
mov [icons.palette + 4], eax
mov edx, [sc.work] mov edx, [sc.work]
or edx, 0x33000000 or edx, 0x33000000
xor esi, esi xor esi, esi
@@ -162,42 +190,82 @@ start:
mcall SF_THREAD_INFO, pi, -1 mcall SF_THREAD_INFO, pi, -1
; TODO limit minimum window size
; prevent drawing if the window is collapsed ; prevent drawing if the window is collapsed
test [pi.wnd_state], 0x04 test [pi.wnd_state], 0x04
jnz .end_redraw jnz .end_redraw
mcall SF_DEFINE_BUTTON, <1, 24>, <5, 24>, BTN_SETUP, [sc.work_light] ; prevent resize if smaller
mcall SF_DEFINE_BUTTON, <30, 24>, <5, 24>, BTN_CONN, [sc.work_light] xor eax, eax
mcall SF_DEFINE_BUTTON, <59, 24>, <5, 24>, BTN_CLEAR, [sc.work_light] mov ebx, [pi.box.width]
mov ecx, [pi.box.height]
mov edx, [pi.client_box.width]
mov esi, [pi.client_box.height]
sub ebx, edx
sub ecx, esi
mcall SF_PUT_IMAGE_EXT, icons, <20, 20>, <3, 7>, 1, icons.palette, 0 cmp edx, WIN_MIN_WIDTH
mcall SF_PUT_IMAGE_EXT, icons + 180, <20, 20>, <61, 7>, 1, icons.palette, 0 jae .width_ok
inc eax
mov edx, WIN_MIN_WIDTH
.width_ok:
add edx, ebx
mov ebx, icons + 60 ; disconnected icon cmp esi, WIN_MIN_HEIGHT
mov al, [is_connected] jae .height_ok
test al, al inc eax
mov esi, WIN_MIN_HEIGHT
.height_ok:
add esi, ecx
test eax, eax
jz @f jz @f
add ebx, 60 ; connected icon mcall SF_CHANGE_WINDOW, -1, -1
jmp .end_redraw
@@: @@:
mcall SF_PUT_IMAGE_EXT, , <20, 20>, <32, 7>, 1, icons.palette, 0
mcall SF_DEFINE_BUTTON, <WIN_MARGIN, TOOL_BTN_SIZE>, \
<WIN_MARGIN, TOOL_BTN_SIZE>, \
BTN_SETUP, 0xffffff
mcall SF_DEFINE_BUTTON, <WIN_MARGIN * 2 + TOOL_BTN_SIZE, TOOL_BTN_SIZE>, \
<WIN_MARGIN, TOOL_BTN_SIZE>, \
BTN_CONN, 0xffffff
mcall SF_DEFINE_BUTTON, <WIN_MARGIN * 3 + TOOL_BTN_SIZE * 2, TOOL_BTN_SIZE>, \
<WIN_MARGIN, TOOL_BTN_SIZE>, \
BTN_CLEAR, 0xffffff
mov ebx, [icons_rgb]
test ebx, ebx
jz .no_icons
add ebx, ICON_SETUP_OFFSET
mcall SF_PUT_IMAGE, , <TOOL_ICON_SIZE, TOOL_ICON_SIZE>, \
<WIN_MARGIN + 3, WIN_MARGIN + 3>
mov ebx, [icons_rgb]
add ebx, ICON_CONN_OFFSET
mcall SF_PUT_IMAGE, , <TOOL_ICON_SIZE, TOOL_ICON_SIZE>, \
<WIN_MARGIN * 2 + TOOL_BTN_SIZE + 3, WIN_MARGIN + 3>
mov ebx, [icons_rgb]
add ebx, ICON_CLEAR_OFFSET
mcall SF_PUT_IMAGE, , <TOOL_ICON_SIZE, TOOL_ICON_SIZE>, \
<WIN_MARGIN * 3 + TOOL_BTN_SIZE * 2 + 3, WIN_MARGIN + 3>
.no_icons:
; text view ; text view
mov eax, [sc.work_light] mov eax, 0xffffff
mov [text_view.bg_color], eax mov [text_view.bg_color], eax
mov eax, [sc.work_text] mov eax, [sc.work_graph]
mov [text_view.fg_color], eax mov [text_view.fg_color], eax
mov eax, [sc.work_text]
mov [text_view.text_color], eax
xor eax, eax mov eax, WIN_MARGIN
mov [text_view.left], eax mov [text_view.left], eax
add eax, SCROLL_TOP mov eax, SCROLL_TOP
mov [text_view.top], eax mov [text_view.top], eax
mov eax, [pi.client_box.width] mov eax, [pi.client_box.width]
sub eax, SCROLL_WIDTH + 4 sub eax, SCROLL_WIDTH + WIN_MARGIN * 2 - 1
mov [text_view.width], eax mov [text_view.width], eax
mov eax, [pi.client_box.height] mov eax, [pi.client_box.height]
sub eax, 2 * FONT_HEIGHT + WIN_BORDER_WIDTH + 14 + SCROLL_TOP sub eax, FONT_HEIGHT + ED_HEIGHT + WIN_MARGIN * 4 + SCROLL_TOP
mov [text_view.height], eax mov [text_view.height], eax
stdcall text_view_draw, text_view stdcall text_view_draw, text_view
@@ -205,19 +273,19 @@ start:
mov [vscroll.all_redraw], 1 mov [vscroll.all_redraw], 1
mov eax, [sc.work] mov eax, [sc.work_light]
mov [vscroll.bg_color], eax mov [vscroll.bg_color], eax
mov eax, [sc.work_button] mov eax, [sc.work_light]
mov [vscroll.front_color], eax mov [vscroll.front_color], eax
mov eax, [sc.work_text] mov eax, [sc.work_graph]
mov [vscroll.line_color], eax mov [vscroll.line_color], eax
mov [vscroll.type], 0 mov [vscroll.type], 0
mov eax, [pi.client_box.width] mov eax, [pi.client_box.width]
sub eax, SCROLL_WIDTH + 2 sub eax, SCROLL_WIDTH + WIN_MARGIN
mov [vscroll.x_pos], ax mov [vscroll.x_pos], ax
mov eax, [pi.client_box.height] mov eax, [pi.client_box.height]
sub eax, 2 * FONT_HEIGHT + WIN_BORDER_WIDTH + 14 + SCROLL_TOP sub eax, FONT_HEIGHT + ED_HEIGHT + WIN_MARGIN * 4 + SCROLL_TOP
mov [vscroll.y_size], ax mov [vscroll.y_size], ax
call update_vscroll call update_vscroll
@@ -227,43 +295,46 @@ start:
edit_boxes_set_sys_color main_win_edits_start, main_win_edits_end, sc edit_boxes_set_sys_color main_win_edits_start, main_win_edits_end, sc
mov eax, [pi.client_box.width] mov eax, [pi.client_box.width]
sub eax, 46 sub eax, SEND_BTN_WIDTH + WIN_MARGIN * 3
mov [ed_send.width], eax mov [ed_send.width], eax
mov eax, [pi.client_box.height] mov eax, [pi.client_box.height]
sub eax, 2 * FONT_HEIGHT + WIN_BORDER_WIDTH + 10 sub eax, FONT_HEIGHT + ED_HEIGHT + WIN_MARGIN * 3
mov [ed_send.top], eax mov [ed_send.top], eax
invoke edit_box_draw, ed_send invoke edit_box_draw, ed_send
mov ebx, [pi.client_box.width] mov ebx, [pi.client_box.width]
sub ebx, 42 sub ebx, SEND_BTN_WIDTH + WIN_MARGIN
shl ebx, 16 shl ebx, 16
add ebx, 40 add ebx, SEND_BTN_WIDTH
mov ecx, [pi.client_box.height] mov ecx, [pi.client_box.height]
sub ecx, 2 * FONT_HEIGHT + WIN_BORDER_WIDTH + 10 sub ecx, FONT_HEIGHT + ED_HEIGHT + WIN_MARGIN * 3
shl ecx, 16 shl ecx, 16
add ecx, FONT_HEIGHT + 4 add ecx, FONT_HEIGHT + 5
mcall SF_DEFINE_BUTTON, , , BTN_SEND, [sc.work_button] mcall SF_DEFINE_BUTTON, , , BTN_SEND, [sc.work_button]
add ebx, 4 shl 16 add ebx, 4 shl 16
mov bx, word [pi.client_box.height] mov bx, word [pi.client_box.height]
sub bx, 2 * FONT_HEIGHT + WIN_BORDER_WIDTH + 7 sub bx, FONT_HEIGHT + ED_HEIGHT + WIN_MARGIN * 3 - 4
mov ecx, 0x90000000 mov ecx, 0x90000000
or ecx, [sc.work_button_text] or ecx, [sc.work_button_text]
mcall SF_DRAW_TEXT, , , send_label mcall SF_DRAW_TEXT, , , send_label
; status bar ; status bar
mov ebx, [pi.client_box.width] mov ebx, WIN_MARGIN shl 16
add ebx, [pi.client_box.width]
sub ebx, WIN_MARGIN + 1
mov edx, [pi.client_box.height] mov edx, [pi.client_box.height]
sub edx, FONT_HEIGHT + WIN_BORDER_WIDTH sub edx, FONT_HEIGHT + WIN_MARGIN * 2
mov ecx, edx mov ecx, edx
shl ecx, 16 shl ecx, 16
mov cx, dx mov cx, dx
mov edx, [sc.work_graph] mov edx, [sc.work_graph]
mcall SF_DRAW_LINE mcall SF_DRAW_LINE
mov ebx, [pi.client_box.height] mov ebx, WIN_MARGIN shl 16
sub ebx, FONT_HEIGHT add ebx, [pi.client_box.height]
sub ebx, FONT_HEIGHT + WIN_MARGIN
mov ecx, 0x90000000 mov ecx, 0x90000000
or ecx, [sc.work_text] or ecx, [sc.work_text]
mov edx, [status_msg] mov edx, [status_msg]
@@ -273,134 +344,6 @@ start:
mcall SF_REDRAW, SSF_END_DRAW mcall SF_REDRAW, SSF_END_DRAW
ret ret
CONN_WIN_WIDTH = 200
CONN_WIN_HEIGHT = 250
proc show_conn_window
cmp [is_conn_win_opened], 1
jne @f
mcall SF_SYSTEM, SSF_GET_THREAD_SLOT, [conn_win_pid]
xchg eax, ecx
mcall SF_SYSTEM, SSF_FOCUS_WINDOW
ret
@@:
mcall SF_CREATE_THREAD, 1, .thread, conn_win_stack + CONN_WIN_STACK_SIZE
cmp eax, -1
je @f
mov [conn_win_pid], eax
mov [is_conn_win_opened], 1
@@:
ret
.thread:
mcall SF_SET_EVENTS_MASK, EVM_MOUSE + EVM_MOUSE_FILTER + EVM_REDRAW + EVM_BUTTON + EVM_KEY
mov eax, [port_num]
mov ecx, 10
mov edi, ed_port_val
call int_to_str
and byte [edi], 0
mov esi, ed_port_val
call strlen
mov [ed_port.size], eax
mov [ed_port.pos], eax
mov eax, [port_conf + 4]
mov ecx, 10
mov edi, ed_baud_val
call int_to_str
and byte [edi], 0
mov esi, ed_baud_val
call strlen
mov [ed_baud.size], eax
call .draw_window
.loop:
mcall SF_WAIT_EVENT
dec eax
jz .win
dec eax
jz .key
dec eax
jz .btn
invoke edit_box_mouse, ed_port
invoke edit_box_mouse, ed_baud
jmp .loop
.win:
call .draw_window
jmp .loop
.key:
mcall SF_GET_KEY
invoke edit_box_key, ed_port
invoke edit_box_key, ed_baud
jmp .loop
.btn:
mcall SF_GET_BUTTON
cmp ah, BTN_OK
jne @f
mov esi, ed_port_val
call str_to_uint
mov [port_num], ebx
mov esi, ed_baud_val
call str_to_uint
mov [port_conf + 4], ebx
@@:
and [is_conn_win_opened], 0
mcall SF_TERMINATE_PROCESS
.draw_window:
mcall SF_REDRAW, SSF_BEGIN_DRAW
mov edx, [sc.work]
or edx, 0x34000000
mov esi, [sc.work]
mov edi, conn_win_name
mov ebx, [pi.box.width]
shr ebx, 1
add ebx, [pi.box.left]
sub ebx, CONN_WIN_WIDTH / 2
shl ebx, 16
add ebx, CONN_WIN_WIDTH
mov ecx, [pi.box.height]
shr ecx, 1
add ecx, [pi.box.top]
sub ecx, CONN_WIN_HEIGHT / 2
shl ecx, 16
add ecx, CONN_WIN_HEIGHT
mcall SF_CREATE_WINDOW
mov ecx, 0x90000000
or ecx, [sc.work_text]
mov edx, port_label
mcall SF_DRAW_TEXT, <0, 13>
mov edx, baud_label
mcall SF_DRAW_TEXT, <0, 45>
edit_boxes_set_sys_color conn_win_edits_start, conn_win_edits_end, sc
invoke edit_box_draw, ed_port
invoke edit_box_draw, ed_baud
mcall SF_DEFINE_BUTTON, <CONN_WIN_WIDTH - 137, 60>, \
<CONN_WIN_HEIGHT - 55, 24>, BTN_OK, \
[sc.work_button]
mcall SF_DEFINE_BUTTON, <CONN_WIN_WIDTH - 71, 60>, \
<CONN_WIN_HEIGHT - 55, 24>, BTN_CANCEL, \
[sc.work_button]
mov ecx, 0x90000000
or ecx, [sc.work_button_text]
mcall SF_DRAW_TEXT, <CONN_WIN_WIDTH - 114, CONN_WIN_HEIGHT - 50>, , ok_label
mov ecx, 0x90000000
or ecx, [sc.work_button_text]
mcall SF_DRAW_TEXT, <CONN_WIN_WIDTH - 65, CONN_WIN_HEIGHT - 50>, , cancel_label
mcall SF_REDRAW, SSF_END_DRAW
ret
endp
proc send_text proc send_text
; check for empty string ; check for empty string
cmp byte [ed_send_val], 0 cmp byte [ed_send_val], 0
@@ -410,11 +353,15 @@ proc send_text
or eax, 1 or eax, 1
mov edi, ed_send_header mov edi, ed_send_header
call make_line_header call make_line_header
mov esi, ed_send_header mov esi, ed_send_val
call strlen call strlen
call .append_ending
mov [tx_buf_cnt], eax mov [tx_buf_cnt], eax
stdcall serial_port_write, [port_handle], ed_send_header, tx_buf_cnt stdcall serial_port_write, [port_handle], ed_send_val, tx_buf_cnt
; TODO check for errors and actual size of written data ; TODO check for errors and actual size of written data
mov esi, ed_send_val
call escape_chars
mov byte [esi], 0
stdcall text_view_append_line, text_view, ed_send_header, TV_FLAG_AUTOSCROLL stdcall text_view_append_line, text_view, ed_send_header, TV_FLAG_AUTOSCROLL
xor eax, eax xor eax, eax
push eax push eax
@@ -426,6 +373,22 @@ proc send_text
invoke scrollbar_draw, vscroll invoke scrollbar_draw, vscroll
.exit: .exit:
ret ret
.append_ending:
cmp [text_append], SETTINGS_APPEND_NONE
je .nothing
cmp [text_append], SETTINGS_APPEND_LF
je .append_lf
mov byte [esi], 0x0d
inc esi
inc eax
.append_lf:
mov byte [esi], 0x0a
inc esi
inc eax
.nothing:
mov byte [esi], 0
ret
endp endp
proc update_vscroll proc update_vscroll
@@ -444,7 +407,7 @@ proc btn_conn_click
lea eax, [port_conf] lea eax, [port_conf]
lea ebx, [port_handle] lea ebx, [port_handle]
stdcall serial_port_open, [port_num], eax, ebx stdcall serial_port_open, [port_num], eax, ebx
mov [status_msg], status_ver mov [status_msg], noconn_msg
test eax, eax test eax, eax
jz .opened jz .opened
mov [status_msg], err_port mov [status_msg], err_port
@@ -460,7 +423,8 @@ proc btn_conn_click
jmp .exit jmp .exit
.opened: .opened:
mov [is_connected], 1 mov [is_connected], 1
mov esi, port_label ; make string for status
mov esi, port_lbl
mov edi, port_status mov edi, port_status
mov ecx, 4 mov ecx, 4
cld cld
@@ -470,19 +434,22 @@ proc btn_conn_click
call int_to_str call int_to_str
mov al, ' ' mov al, ' '
stosb stosb
mov eax, [port_conf + 4] mov eax, [port_conf + SP_CONF.baudrate]
mov ecx, 10 mov ecx, 10
call int_to_str call int_to_str
mov eax, ' 8n1' mov al, ' '
stosd
xor al, al
stosb stosb
mov al, [port_conf + SP_CONF.word_size]
add al, '0'
stosb
mov eax, 'n1'
stosd
mov [status_msg], port_status mov [status_msg], port_status
jmp .exit jmp .exit
.close: .close:
stdcall serial_port_close, [port_handle] stdcall serial_port_close, [port_handle]
and [is_connected], 0 and [is_connected], 0
mov [status_msg], status_ver mov [status_msg], noconn_msg
.exit: .exit:
ret ret
endp endp
@@ -490,12 +457,13 @@ endp
proc check_port proc check_port
mov [rx_buf_cnt], RX_BUF_SIZE - 1 mov [rx_buf_cnt], RX_BUF_SIZE - 1
stdcall serial_port_read, [port_handle], rx_buf, rx_buf_cnt stdcall serial_port_read, [port_handle], rx_buf, rx_buf_cnt
; TODO check eax for errors
mov eax, [rx_buf_cnt]
test eax, eax test eax, eax
jnz .error
mov ecx, [rx_buf_cnt]
test ecx, ecx
jz .exit jz .exit
; TODO escape non-print chars mov esi, rx_buf
lea esi, [rx_buf + eax] call escape_chars
mov byte [esi], 0 mov byte [esi], 0
xor eax, eax xor eax, eax
mov edi, rx_header mov edi, rx_header
@@ -504,52 +472,22 @@ proc check_port
stdcall text_view_draw, text_view stdcall text_view_draw, text_view
call update_vscroll call update_vscroll
invoke scrollbar_draw, vscroll invoke scrollbar_draw, vscroll
jmp .exit
.error:
; the port was closed
mov eax, noconn_msg
mov [status_msg], eax
mov [is_connected], 0
call start.draw_window ; TODO redraw status only
.exit: .exit:
ret ret
endp endp
proc make_line_header
; eax = 0 - rx, 1 - tx
; edi = dest buf
push eax
mcall SF_GET_SYS_TIME
mov ebx, eax
mov ecx, 3
; BCD timestamp to string
.loop:
mov al, bl
shr al, 4
add al, '0'
stosb
mov al, bl
and al, 0x0f
add al, '0'
stosb
dec ecx
jz .done
mov al, ':'
stosb
shr ebx, 8
jmp .loop
.done:
mov al, ' '
stosb
mov al, '<'
pop ebx
test ebx, ebx
jz @f
mov al, '>'
@@:
stosb
mov al, ' '
stosb
ret
endp
align 16 align 16
@IMPORT: @IMPORT:
library box_lib, 'box_lib.obj' library box_lib, 'box_lib.obj',\
libimg, 'libimg.obj'
import box_lib,\ import box_lib,\
edit_box_draw, 'edit_box_draw',\ edit_box_draw, 'edit_box_draw',\
@@ -557,19 +495,20 @@ import box_lib,\
edit_box_mouse, 'edit_box_mouse',\ edit_box_mouse, 'edit_box_mouse',\
edit_box_set_text, 'edit_box_set_text',\ edit_box_set_text, 'edit_box_set_text',\
scrollbar_draw, 'scrollbar_v_draw',\ scrollbar_draw, 'scrollbar_v_draw',\
scrollbar_mouse, 'scrollbar_v_mouse' scrollbar_mouse, 'scrollbar_v_mouse',\
option_box_draw, 'option_box_draw',\
option_box_mouse, 'option_box_mouse'
import libimg,\
libimg.init, 'lib_init',\
img.from_file, 'img_from_file',\
img.to_rgb, 'img_to_rgb',\
img.destroy, 'img_destroy'
conn_win_edits_start:
ed_port edit_box 80, CONN_WIN_WIDTH - 80 - 11, 10, 0xffffff, 0x6f9480, \
0, 0, 0x10000000, 6, ed_port_val, mouse_dd, \
ed_focus + ed_figure_only
ed_baud edit_box 80, CONN_WIN_WIDTH - 80 - 11, 42, 0xffffff, 0x6f9480, \
0, 0, 0x10000000, 6, ed_baud_val, mouse_dd, \
ed_figure_only
conn_win_edits_end:
main_win_edits_start: main_win_edits_start:
ed_send edit_box 0, 0, 0, 0xffffff, 0x6f9480, \ ed_send edit_box 0, WIN_MARGIN, 0, 0xffffff, 0x6f9480, \
0, 0, 0x10000000, ED_SEND_MAX_LEN - 1, ed_send_val, mouse_dd, \ 0, 0, 0x10000000, ED_SEND_MAX_LEN - 3, ed_send_val, mouse_dd, \
ed_focus + ed_always_focus, 0, 0 ed_focus + ed_always_focus, 0, 0
main_win_edits_end: main_win_edits_end:
@@ -577,67 +516,43 @@ vscroll scrollbar SCROLL_WIDTH, 0, 0, SCROLL_TOP, SCROLL_WIDTH, 0, 0, 0,
text_view TEXT_VIEW text_view TEXT_VIEW
is_connected db 0 is_connected db 0
is_conn_win_opened db 0 app_name db 'kterm v0.2.0', 0
app_name db 'kterm', 0
conn_win_name db 'Settings', 0
port_label db 'Port:', 0
baud_label db 'Baud:', 0
ok_label db 'Ok', 0
cancel_label db 'Cancel', 0
send_label db 'Send', 0 send_label db 'Send', 0
status_msg dd status_ver noconn_msg db 'Not connected', 0
status_ver db 'v0.1.0', 0 icons_file db '/sys/icons16.png', 0
err_port db 'Invalid serial port.', 0 err_port db 'Invalid serial port', 0
err_busy db 'The port is already in use.', 0 err_busy db 'The port is already in use', 0
err_conf db 'Invalid port configuration.', 0 err_conf db 'Invalid port configuration', 0
err_unknown db 'An unknown error occured.', 0 err_unknown db 'An unknown error occured', 0
err_driver db 'Error loading driver serial.sys.', 0 err_driver db 'Error loading driver serial.sys', 0
err_driver_ver db 'Error serial driver version', 0
align 4
status_msg dd noconn_msg
port_num dd 0 port_num dd 0
icons_rgb dd 0
port_conf: port_conf:
dd port_conf_end - port_conf dd port_conf_end - port_conf
dd 9600 dd 9600
db 8, 1, SERIAL_CONF_PARITY_NONE, SERIAL_CONF_FLOW_CTRL_NONE db 8, SERIAL_CONF_STOP_BITS_1, SERIAL_CONF_PARITY_NONE, SERIAL_CONF_FLOW_CTRL_NONE
port_conf_end: port_conf_end:
text_append db SETTINGS_APPEND_LF
if __DEBUG__ eq 1 IncludeIGlobals
include_debug_strings
end if
; https://javl.github.io/image2cpp/ include_debug_strings
icons:
; 'icons', 20x80px
db 0xff, 0xff, 0xf0, 0xfc, 0x7f, 0xf0, 0xf8, 0x3f, 0xf0, 0xf8, 0x1f, 0xf0, 0xfe, 0x1f, 0xf0, 0xdf
db 0x1f, 0xf0, 0x8e, 0x1f, 0xf0, 0xa4, 0x3f, 0xf0, 0x90, 0x1f, 0xf0, 0xc8, 0x0f, 0xf0, 0xe0, 0x07
db 0xf0, 0xfe, 0x43, 0xf0, 0xff, 0x21, 0xf0, 0xff, 0x90, 0xf0, 0xff, 0xc8, 0x70, 0xff, 0xe4, 0x30
db 0xff, 0xf0, 0x70, 0xff, 0xf8, 0xf0, 0xff, 0xfd, 0xf0, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xf0, 0xff
db 0xff, 0xf0, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xf0, 0xfe, 0xf7, 0xf0, 0xfc, 0xf3, 0xf0, 0xf8, 0xf1
db 0xf0, 0xf8, 0xf1, 0xf0, 0xf0, 0x78, 0xf0, 0x80, 0x78, 0x10, 0x80, 0x78, 0x10, 0xf0, 0x78, 0xf0
db 0xf8, 0xf1, 0xf0, 0xf8, 0xf1, 0xf0, 0xfc, 0xf3, 0xf0, 0xfe, 0xf7, 0xf0, 0xff, 0xff, 0xf0, 0xff
db 0xff, 0xf0, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xf0, 0xff, 0xff
db 0xf0, 0xff, 0xff, 0xf0, 0xff, 0x9f, 0xf0, 0xff, 0x0f, 0xf0, 0xfe, 0x07, 0xf0, 0xfe, 0x07, 0xf0
db 0xfc, 0x03, 0xf0, 0x80, 0x00, 0x10, 0x80, 0x00, 0x10, 0xfc, 0x03, 0xf0, 0xfe, 0x07, 0xf0, 0xfe
db 0x07, 0xf0, 0xff, 0x0f, 0xf0, 0xff, 0x9f, 0xf0, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xf0, 0xff, 0xff
db 0xf0, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xf0, 0xff, 0xe3, 0xf0
db 0xff, 0xc9, 0xf0, 0xff, 0x9c, 0xf0, 0xff, 0x3e, 0x70, 0xfe, 0x7f, 0x70, 0xfc, 0x7f, 0x70, 0xf9
db 0x3e, 0x70, 0xf3, 0x9c, 0xf0, 0xe7, 0xc9, 0xf0, 0xef, 0xe3, 0xf0, 0xe7, 0xe7, 0xf0, 0xf3, 0xcf
db 0xf0, 0xf9, 0x9f, 0xf0, 0xfc, 0x00, 0x70, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xf0
.palette:
dd 0xffffff
dd 0x000000
align 4
i_end: i_end:
ed_port_val rb 7 IncludeUGlobals
ed_baud_val rb 7 mouse_dd dd ?
port_handle dd ?
rx_buf_cnt dd ?
tx_buf_cnt dd ?
ed_send_header rb LINE_HEADER_LEN ed_send_header rb LINE_HEADER_LEN
ed_send_val rb ED_SEND_MAX_LEN ed_send_val rb ED_SEND_MAX_LEN
mouse_dd dd ?
conn_win_pid dd ?
port_handle dd ?
port_status rb PORT_STATUS_LEN port_status rb PORT_STATUS_LEN
rx_header rb LINE_HEADER_LEN rx_header rb LINE_HEADER_LEN
rx_buf rb RX_BUF_SIZE rx_buf rb RX_BUF_SIZE
rx_buf_cnt dd ?
tx_buf_cnt dd ?
sc system_colors sc system_colors
pi process_information pi process_information
conn_win_stack rb CONN_WIN_STACK_SIZE

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

277
settings.inc Normal file
View File

@@ -0,0 +1,277 @@
; Copyright (C) KolibriOS team 2025. All rights reserved.
; Distributed under terms of the GNU General Public License
;
; GNU GENERAL PUBLIC LICENSE
; Version 2, June 1991
SETTINGS_WIN_STACK_SIZE = 1024
SETTINGS_WIN_WIDTH = 350
SETTINGS_WIN_HEIGHT = 250
SETTINGS_BTN_WIDTH = 60
SETTINGS_BTN_HEIGHT = 24
OPT_HEIGHT = 10
COL2 = 190
SETTINGS_APPEND_NONE = 0
SETTINGS_APPEND_LF = 1
SETTINGS_APPEND_CRLF = 2
proc show_settings_win
cmp [settings_is_win_opened], 1
jne @f
mcall SF_SYSTEM, SSF_GET_THREAD_SLOT, [settings_win_pid]
xchg eax, ecx
mcall SF_SYSTEM, SSF_FOCUS_WINDOW
ret
@@:
mcall SF_CREATE_THREAD, 1, .thread, settings_win_stack + SETTINGS_WIN_STACK_SIZE
cmp eax, -1
je @f
mov [settings_win_pid], eax
mov [settings_is_win_opened], 1
@@:
ret
.thread:
mcall SF_SET_EVENTS_MASK, EVM_MOUSE + EVM_MOUSE_FILTER + EVM_REDRAW + EVM_BUTTON + EVM_KEY
call settings_load
call .draw_window
.loop:
mcall SF_WAIT_EVENT
dec eax
jz .win
dec eax
jz .key
dec eax
jz .btn
.mouse:
invoke edit_box_mouse, ed_port
invoke edit_box_mouse, ed_baud
invoke edit_box_mouse, ed_bits
invoke option_box_mouse, op_append
jmp .loop
.win:
call .draw_window
jmp .loop
.key:
mcall SF_GET_KEY
invoke edit_box_key, ed_port
invoke edit_box_key, ed_baud
invoke edit_box_key, ed_bits
jmp .loop
.btn:
mcall SF_GET_BUTTON
cmp ah, BTN_OK
jne @f
call settings_save
@@:
and [settings_is_win_opened], 0
mcall SF_TERMINATE_PROCESS
.draw_window:
mcall SF_REDRAW, SSF_BEGIN_DRAW
mov edx, [sc.work]
or edx, 0x34000000
mov esi, [sc.work]
mov edi, settings_win_name
mov ebx, [pi.box.width]
shr ebx, 1
add ebx, [pi.box.left]
sub ebx, SETTINGS_WIN_WIDTH / 2
shl ebx, 16
add ebx, SETTINGS_WIN_WIDTH
mov ecx, [pi.box.height]
shr ecx, 1
add ecx, [pi.box.top]
sub ecx, SETTINGS_WIN_HEIGHT / 2
shl ecx, 16
add ecx, SETTINGS_WIN_HEIGHT
mcall SF_CREATE_WINDOW
mcall SF_THREAD_INFO, s_pi, -1
; prevent drawing if the window is collapsed
test [s_pi.wnd_state], 0x04
jnz .end_redraw
mov ecx, 0x90000000
or ecx, [sc.work_text]
mcall SF_DRAW_TEXT, <WIN_MARGIN, WIN_MARGIN + 2>, , port_conf_lbl
add ebx, WIN_MARGIN * 2 + FONT_HEIGHT
mcall SF_DRAW_TEXT, , , port_lbl
mov word [ed_port.top], bx
add ebx, WIN_MARGIN + ED_HEIGHT
mcall SF_DRAW_TEXT, , , baud_lbl
mov word [ed_baud.top], bx
add ebx, WIN_MARGIN + ED_HEIGHT
mcall SF_DRAW_TEXT, , , bits_lbl
mov word [ed_bits.top], bx
mcall SF_DRAW_TEXT, <COL2, WIN_MARGIN + 2>, , tx_text_lbl
edit_boxes_set_sys_color settings_win_edits_start, settings_win_edits_end, sc
invoke edit_box_draw, ed_port
invoke edit_box_draw, ed_baud
invoke edit_box_draw, ed_bits
option_boxes_set_sys_color sc, op_append
invoke option_box_draw, op_append
mov ebx, WIN_MARGIN shl 16
add ebx, [s_pi.client_box.width]
sub ebx, WIN_MARGIN + 1
mov edx, [s_pi.client_box.height]
sub edx, SETTINGS_BTN_HEIGHT + WIN_MARGIN * 2
mov ecx, edx
shl ecx, 16
mov cx, dx
mov edx, [sc.work_graph]
mcall SF_DRAW_LINE
mov ebx, [s_pi.client_box.width]
sub ebx, (SETTINGS_BTN_WIDTH + WIN_MARGIN) * 2
shl ebx, 16
add ebx, SETTINGS_BTN_WIDTH
mov ecx, [s_pi.client_box.height]
sub ecx, SETTINGS_BTN_HEIGHT + WIN_MARGIN
shl ecx, 16
add ecx, SETTINGS_BTN_HEIGHT
mcall SF_DEFINE_BUTTON, , , BTN_OK, [sc.work_button]
push ebx ecx
add ebx, 24 shl 16
mov bx, word [s_pi.client_box.height]
sub bx, SETTINGS_BTN_HEIGHT + WIN_MARGIN - 5
mov ecx, 0x90000000
or ecx, [sc.work_button_text]
mcall SF_DRAW_TEXT, , , ok_lbl
pop ecx ebx
add ebx, (SETTINGS_BTN_WIDTH + WIN_MARGIN) shl 16
mcall SF_DEFINE_BUTTON, , , BTN_CANCEL, [sc.work_button]
add ebx, 8 shl 16
mov bx, word [s_pi.client_box.height]
sub bx, SETTINGS_BTN_HEIGHT + WIN_MARGIN - 5
mov ecx, 0x90000000
or ecx, [sc.work_button_text]
mcall SF_DRAW_TEXT, , , cancel_lbl
.end_redraw:
mcall SF_REDRAW, SSF_END_DRAW
ret
endp
proc settings_load
mov eax, [port_num]
mov ecx, 10
mov edi, ed_port_val
call int_to_str
and byte [edi], 0
mov esi, ed_port_val
call strlen
mov [ed_port.size], eax
mov [ed_port.pos], eax
mov eax, [port_conf + SP_CONF.baudrate]
mov ecx, 10
mov edi, ed_baud_val
call int_to_str
and byte [edi], 0
mov esi, ed_baud_val
call strlen
mov [ed_baud.size], eax
mov al, [port_conf + SP_CONF.word_size]
add al, '0'
mov [ed_bits_val], al
mov [ed_bits_val + 1], 0
mov [ed_bits.size], 1
mov al, [text_append]
mov ebx, opt_append_none
cmp al, SETTINGS_APPEND_NONE
je .opt_append_ok
mov ebx, opt_append_lf
cmp al, SETTINGS_APPEND_LF
je .opt_append_ok
mov ebx, opt_append_crlf
.opt_append_ok:
mov [op_append_val], ebx
ret
endp
proc settings_save
mov esi, ed_port_val
call str_to_uint
mov [port_num], ebx
mov esi, ed_baud_val
call str_to_uint
mov [port_conf + SP_CONF.baudrate], ebx
mov al, [ed_bits_val]
sub al, '0'
mov [port_conf + SP_CONF.word_size], al
mov eax, [op_append_val]
mov bl, SETTINGS_APPEND_NONE
cmp eax, opt_append_none
je .opt_append_ok
mov bl, SETTINGS_APPEND_LF
cmp eax, opt_append_lf
je .opt_append_ok
mov bl, SETTINGS_APPEND_CRLF
.opt_append_ok:
mov [text_append], bl
ret
endp
iglobal
settings_is_win_opened db 0
settings_win_edits_start:
ed_port edit_box 70, 100, WIN_MARGIN, 0xffffff, 0x6f9480, \
0, 0, 0x10000000, 6, ed_port_val, mouse_dd, \
ed_focus + ed_figure_only
ed_baud edit_box 70, 100, WIN_MARGIN * 2 + ED_HEIGHT, 0xffffff, 0x6f9480, \
0, 0, 0x10000000, 6, ed_baud_val, mouse_dd, \
ed_figure_only
ed_bits edit_box 40, 100, WIN_MARGIN * 3 + ED_HEIGHT * 2, 0xffffff, 0x6f9480, \
0, 0, 0x10000000, 1, ed_bits_val, mouse_dd, \
ed_figure_only
settings_win_edits_end:
opt_append_none option_box op_append_val, COL2, WIN_MARGIN * 2 + FONT_HEIGHT, 6, 12, 0, 0, 0, opt_lbl_nothing, 14
opt_append_lf option_box op_append_val, COL2, WIN_MARGIN * 3 + OPT_HEIGHT+ FONT_HEIGHT, 6, 12, 0, 0, 0, opt_lbl_lf, 9
opt_append_crlf option_box op_append_val, COL2, WIN_MARGIN * 4 + OPT_HEIGHT * 2+ FONT_HEIGHT, 6, 12, 0, 0, 0, opt_lbl_crlf, 11
op_append dd opt_append_none, opt_append_lf, opt_append_crlf, 0
settings_win_name db 'kterm - settings', 0
port_conf_lbl db 'Port settings', 0
tx_text_lbl db 'Transmitted text', 0
port_lbl db 'Port:', 0
baud_lbl db 'Baudrate:', 0
bits_lbl db 'Data bits:', 0
ok_lbl db 'Ok', 0
cancel_lbl db 'Cancel', 0
opt_lbl_nothing db 'Append nothing', 0
opt_lbl_lf db 'Append LF', 0
opt_lbl_crlf db 'Append CRLF', 0
endg
uglobal
align 4
settings_win_pid dd ?
op_append_val dd ?
s_pi process_information
ed_port_val rb 7
ed_baud_val rb 7
ed_bits_val rb 2
settings_win_stack rb SETTINGS_WIN_STACK_SIZE
endg

View File

@@ -17,6 +17,7 @@ struct TEXT_VIEW
bg_color dd ? bg_color dd ?
fg_color dd ? fg_color dd ?
text_color dd ?
buf_data dd ? buf_data dd ?
buf_size dd ? buf_size dd ?
@@ -207,7 +208,7 @@ proc tv.draw_single_line uses esi
; edi = pointer to the first byte of string in [text_view.buf_data] ; edi = pointer to the first byte of string in [text_view.buf_data]
; return: eax = length of the string ; return: eax = length of the string
mov ecx, 0x10000000 ; fixed-length string mov ecx, 0x10000000 ; fixed-length string
or ecx, [esi + TEXT_VIEW.fg_color] or ecx, [esi + TEXT_VIEW.text_color]
push esi push esi
mov esi, edi mov esi, edi
call strlen call strlen

View File

@@ -71,6 +71,7 @@ proc strlen
mov eax, esi mov eax, esi
sub eax, ebx sub eax, ebx
dec eax dec eax
dec esi
pop ebx pop ebx
ret ret
endp endp
@@ -86,3 +87,59 @@ proc strcpy
jnz @b jnz @b
ret ret
endp endp
proc escape_chars
; esi = source
; ecx = length
.loop:
mov al, [esi]
cmp al, 0x20
jb .escape
cmp al, 0x80
jae .escape
jmp .no_escape
.escape:
mov byte [esi], '.'
.no_escape:
inc esi
loop .loop
ret
endp
proc make_line_header
; eax = 0 - rx, 1 - tx
; edi = dest buf
push eax
mcall SF_GET_SYS_TIME
mov ebx, eax
mov ecx, 3
; BCD timestamp to string
.loop:
mov al, bl
shr al, 4
add al, '0'
stosb
mov al, bl
and al, 0x0f
add al, '0'
stosb
dec ecx
jz .done
mov al, ':'
stosb
shr ebx, 8
jmp .loop
.done:
mov al, ' '
stosb
mov al, '<'
pop ebx
test ebx, ebx
jz @f
mov al, '>'
@@:
stosb
mov al, ' '
stosb
ret
endp