From d4ef58f2368b6737d2763e5c65950690eec425bf Mon Sep 17 00:00:00 2001 From: Alexey Ryabov Date: Wed, 7 May 2025 00:23:55 +0500 Subject: [PATCH] Initial commit --- README.md | 39 +++++++ Tupfile.lua | 2 + icons.png | Bin 0 -> 445 bytes kterm.asm | 308 ++++++++++++++++++++++++++++++++++++++++++++++++++++ utils.asm | 76 +++++++++++++ 5 files changed, 425 insertions(+) create mode 100644 README.md create mode 100644 Tupfile.lua create mode 100644 icons.png create mode 100644 kterm.asm create mode 100644 utils.asm diff --git a/README.md b/README.md new file mode 100644 index 0000000..38f934d --- /dev/null +++ b/README.md @@ -0,0 +1,39 @@ +# kterm + +Simple serial terminal for KolibriOS. + +# Requirements + +- [Fasm](https://flatassembler.net/) 1.7x +- [Tup](https://gittup.org/tup/) build system (optional) +- KolibriOS commit `#5593d344cd` or newer + +# Build instructions + +1. Clone the KolibriOS repository: + +```sh +git clone https://git.kolibrios.org/KolibriOS/kolibrios.git +``` + +2. Clone this repository into kolibrios/programs/other/kterm: + +```sh +cd kolibrios/programs/other +git clone https://git.kolibrios.org/b00bl1k/kterm.git +``` + +3. Build using either method: + +With Tup (recommended): + + ```sh + tup init + tup + ``` + +Or directly with FASM: + + ```sh + fasm kterm.asm + ``` diff --git a/Tupfile.lua b/Tupfile.lua new file mode 100644 index 0000000..fb5ce83 --- /dev/null +++ b/Tupfile.lua @@ -0,0 +1,2 @@ +if tup.getconfig("NO_FASM") ~= "" then return end +tup.rule("kterm.asm", "fasm %f %o " .. tup.getconfig("KPACK_CMD"), "kterm") diff --git a/icons.png b/icons.png new file mode 100644 index 0000000000000000000000000000000000000000..c1ba64d83b4790dfc38c35e365ed9c97f4a20500 GIT binary patch literal 445 zcmeAS@N?(olHy`uVBq!ia0vp^B0y}z!3HGL%4UTDDaPU;cPGZ1Cw1z99F}xPUq=Rp zjs4tz5?O(Kg=CK)Uj~LMH3o);76yi2K%s^g3=E|P3=FRl7#OT(FffQ0%-I!a1C-z_ z@Q5sCV9-+rVaAH3_GLgp_7YEDSN4~zEFxm8XAf+$1llL;>Eaj?aro`@vwSTIJT2La zJJs+1x3rvCP@wPK#ByrOpErr7H=7gx=47XHMSpm=tWo^BSl{PGkM|s72%aEz=7oG< zhM>fr#SdcRdA$WA7R)(RlyTj?^Wv2U8C&|N6tDQXc!`3h5KENrO|H8tFORl2mlyaR zJvPlNuzSl&5nYi<^VqnuC0jSSv2OMAh(8dO`Sjw`?>U82I5fBRab~, <100, 250> + + mcall SF_THREAD_INFO, pi, -1 + + ; prevent drawing if the window is collapsed + test [pi.wnd_state], 0x04 + jnz .end_redraw + + mcall SF_DEFINE_BUTTON, <1, 24>, <5, 24>, BTN_SETUP, [sc.work_light] + mcall SF_DEFINE_BUTTON, <30, 24>, <5, 24>, BTN_CONN, [sc.work_light] + mcall SF_DEFINE_BUTTON, <59, 24>, <5, 24>, 123, [sc.work_light] + + mcall SF_PUT_IMAGE_EXT, icons, <20, 20>, <3, 7>, 1, icons.palette, 0 + + mov ebx, icons + 60 ; disconnected icon + mov al, [is_connected] + test al, al + jz @f + add ebx, 60 ; connected icon + @@: + mcall SF_PUT_IMAGE_EXT, , <20, 20>, <32, 7>, 1, icons.palette, 0 + + ; TODO limit minimum window size + + ; status bar + + mov ebx, [pi.client_box.width] + mov edx, [pi.client_box.height] + sub edx, FONT_HEIGHT + WIN_BORDER_WIDTH + mov ecx, edx + shl ecx, 16 + mov cx, dx + mov edx, [sc.work_graph] + mcall SF_DRAW_LINE + + mov ebx, [pi.client_box.height] + sub ebx, FONT_HEIGHT + mov ecx, 0x90000000 + or ecx, [sc.work_text] + mov edx, status_msg + mcall SF_DRAW_TEXT + +.end_redraw: + mcall SF_REDRAW, SSF_END_DRAW + ret + +CONN_WIN_WIDTH = 200 +CONN_WIN_HEIGHT = 250 +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_CLOSE + jne .loop + 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 win_conn_edits_start, win_conn_edits_end, sc + invoke edit_box_draw, ed_port + invoke edit_box_draw, ed_baud + + mcall SF_REDRAW, SSF_END_DRAW + ret + +align 16 +@IMPORT: + +library box_lib, 'box_lib.obj' + +import box_lib,\ + edit_box_draw, 'edit_box_draw',\ + edit_box_key, 'edit_box_key',\ + edit_box_mouse, 'edit_box_mouse' + +win_conn_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 +win_conn_edits_end: + +is_connected db 0 +is_conn_win_opened db 0 +app_name db 'kterm', 0 +conn_win_name db 'Settings', 0 +port_label db 'Port:', 0 +baud_label db 'Baud:', 0 +status_msg db ' ', 0 +port_num dd 0 +port_conf: + dd port_conf_end - port_conf + dd 9600 + db 8, 1, SERIAL_CONF_PARITY_NONE, SERIAL_CONF_FLOW_CTRL_NONE +port_conf_end: + +if __DEBUG__ eq 1 + include_debug_strings +end if + +; https://javl.github.io/image2cpp/ +icons: + ; 'icons', 20x60px + db 0xff, 0xff, 0xf0, 0xfc, 0xff, 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 +.palette: + dd 0xffffff + dd 0x000000 + +i_end: +ed_port_val rb 7 +ed_baud_val rb 7 +mouse_dd dd ? +conn_win_pid dd ? +sc system_colors +pi process_information +conn_win_stack rb CONN_WIN_STACK_SIZE \ No newline at end of file diff --git a/utils.asm b/utils.asm new file mode 100644 index 0000000..3d62c4b --- /dev/null +++ b/utils.asm @@ -0,0 +1,76 @@ +; 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 + +align 4 +proc str_to_uint +; esi = source string +; eax = 0 if success +; ebx = number + xor eax, eax + xor ebx, ebx +.loop: + lodsb + test al, al + jz .exit + sub al, '0' + jb .exit + cmp al, 9 + ja .exit + lea ebx, [ebx + 4 * ebx] + shl ebx, 1 + add ebx, eax + jmp .loop +.exit: + ret +endp + +align 4 +proc int_to_str +; eax = number to convert +; ecx = base +; edi = string buffer address + push ecx edx + or eax, eax + jns @f + mov byte [edi], '-' + inc edi + @@: + call .recurse + pop edx ecx + ret +.recurse: + cmp eax, ecx + jb @f + xor edx, edx + div ecx + push edx + call .recurse + pop eax + @@: + cmp al, 10 + sbb al, 0x69 + das + stosb + retn +endp + +align 4 +proc strlen +; esi = string +; eax = length + push ebx + mov ebx, esi + cld + @@: + lodsb + test al, al + jnz @b + mov eax, esi + sub eax, ebx + dec eax + pop ebx + ret +endp