Compare commits

..

49 Commits

Author SHA1 Message Date
170fa3e1b0 libc.obj: add authorship && other 2026-03-06 00:08:10 +05:00
81ea535fed Merge branch 'main' into libc.obj--add-allocator 2026-02-22 10:11:16 +00:00
badae1fbf2 libc.obj: add EXIT_SUCCESS/FAILURE to stdlib.h 2026-02-22 14:47:21 +05:00
01cae0a587 libc.obj: malloc_test: use fprintf(stderr, ...
KolibriOS/kolibrios#311 (comment)
2026-02-22 14:37:41 +05:00
5525fd2a86 translate comments
I didn't notice that forgot
2026-02-22 09:11:57 +00:00
23c75c33b1 lib.obj: kek fix
heh kek
2026-02-22 07:57:59 +00:00
70b90f1d3a libc.obj: Add allocator
just add allocator instead of `_ksys_alloc`, `_ksys_free` and `_ksys_realloc`.
2026-02-22 12:42:48 +05:00
cb1d69ff72 oberon07: Option -nochk a by default
This option disables runtime checks to reduce binary file size.

Signed-off-by: Max Logaev <maxlogaev@proton.me>
2026-02-21 19:22:11 +00:00
b09d09d66b ci/cd: Added checkout of submodules
Signed-off-by: Max Logaev <maxlogaev@proton.me>
2026-02-21 19:22:11 +00:00
3c0f65ed27 cedit: Added to build system
Fixed installation of oberon07 compiler in ISO image

Signed-off-by: Max Logaev <maxlogaev@proton.me>
2026-02-21 19:22:11 +00:00
03efcd7532 oberon07: Added as a git submodule
Signed-off-by: Max Logaev <maxlogaev@proton.me>
2026-02-21 19:22:11 +00:00
7fc1361c4c oberon07: Source code removed
Signed-off-by: Max Logaev <maxlogaev@proton.me>
2026-02-21 19:22:11 +00:00
Igor Shutrov
c8c46d4f60 ftpd: add ip to first message 2026-02-17 22:08:04 +05:00
2ff587a69f libc.obj: Fixed build skip with TCC build enabled
Signed-off-by: Max Logaev <maxlogaev@proton.me>
2026-01-28 17:22:54 +03:00
Igor Shutrov
512dc28549 Cedit: Improve search panel (#313)
Улучшения для Cedit в Панели поиска:
- Добавлен поиск следующего фрагмента текста по нажатию Enter
- Добавлен обратный переход по полям ввода в Панели поиска по Shift-Tab

Co-authored-by: Igor Shutrov <igor@shutrov.ru>
Reviewed-on: KolibriOS/kolibrios#313
Reviewed-by: Burer <burer@noreply.localhost>
Co-authored-by: Igor Shutrov <kolibridev@inbox.ru>
Co-committed-by: Igor Shutrov <kolibridev@inbox.ru>
2026-01-18 16:28:46 +00:00
e8f322ece8 mtdbg: Backtrace implemented (#315)
Added support for backtrace/stacktrace output.
This is useful for high-level languages ​​like C and Oberon07.
If a debug file is provided, searches for the nearest debug symbol.

Reviewed-on: KolibriOS/kolibrios#315
Reviewed-by: Mikhail Frolov <mixa.frolov2003@gmail.com>
Reviewed-by: Burer <burer@noreply.localhost>
2026-01-18 13:08:02 +00:00
6583d79dcf mtdbg: Fixed magic cmd flags
Signed-off-by: Max Logaev <maxlogaev@proton.me>
2026-01-11 13:35:58 +00:00
98028bf4bf libc.obj: Added missing strpbrk() to EXPORTS (#310)
Reviewed-on: KolibriOS/kolibrios#310
Reviewed-by: Max Logaev <maxlogaev@proton.me>
Co-authored-by: Егор <velikiydolbayeb@gmail.com>
Co-committed-by: Егор <velikiydolbayeb@gmail.com>
2026-01-10 23:27:51 +00:00
igorsh
4f79d17ac1 ftpd: Add XPWD and XCWD commands (#309)
Добавлены команды XPWD и XCWD, дублирующие PWD и CWD

Co-authored-by: Igor Shutrov <igor@shutrov.ru>
Co-authored-by: Burer <burer@kolibrios.org>
Reviewed-on: KolibriOS/kolibrios#309
Reviewed-by: Burer <burer@noreply.localhost>
Co-authored-by: igorsh <kolibridev@inbox.ru>
Co-committed-by: igorsh <kolibridev@inbox.ru>
2026-01-08 17:03:23 +00:00
Igor Shutrov
c0d2dd2698 ftpd: Fix typo 2026-01-07 19:41:28 +00:00
Igor Shutrov
f9c519f353 ftpd: Fix typo 2026-01-07 19:41:28 +00:00
Igor Shutrov
6471e7889b ftpd: Fix RETR for small and empty files 2026-01-06 18:20:39 +00:00
cf51adfbbb Info3ds: added resizing of the window with the figure (#241)
info3ds: added resizing of the window with the figure
and the list of vertices in the properties window,

info3ds, info3ds_u: files with menu icons are embedded into the program

Reviewed-on: KolibriOS/kolibrios#241
Reviewed-by: Mikhail Frolov <mixa.frolov2003@gmail.com>
Reviewed-by: Burer <burer@noreply.localhost>
Co-authored-by: IgorA <aie85playm@gmail.com>
Co-committed-by: IgorA <aie85playm@gmail.com>
2025-12-31 07:34:00 +00:00
ba472f07df apps/floppybird: rewrite to c (#284)
What was done:
- [x] Rewritten to C
- [x] Refactored some code
- [x] Fixed window resizing (#182)
- [x] Adaptation for different skin height
- [x] Fixed some tubes leftovers drawing
- [x] Changed tubes generation a little bit
- [x] Changed interface a little bit
- [x] Added Escape key for exit to main menu
- [x] Removed buttons from main menu (hotkeys left) :(

What needs to be done:
- [ ] ~~Fix rolled-up bug?~~
- [ ] ~~Fit it into 2048 bytes?~~
- [ ] ~~Add pause?~~
- [ ] ~~Use buffer for drawing without flickering?~~

P.S. There is no way game with all this changes will fit in 2560 bytes, as previous version, so I decided to skip them.

Reviewed-on: KolibriOS/kolibrios#284
Reviewed-by: Ivan B <dunkaist@noreply.localhost>
Reviewed-by: Mikhail Frolov <mixa.frolov2003@gmail.com>
Co-authored-by: Burer <burer@kolibrios.org>
Co-committed-by: Burer <burer@kolibrios.org>
2025-12-29 06:34:23 +00:00
Igor Shutrov
f081890d8c Remove redundant space before 220 code 2025-12-29 06:32:40 +00:00
manh-td
37fdb91612 Use 64 bit for times in mpeg4_encode_gop_header() 2025-12-20 11:01:45 +00:00
manh-td
bdb5e7570d Fix DoS due to lack of eof check 2025-12-20 11:00:16 +00:00
manh-td
2c1133cbab Fixes out of array access 2025-12-20 10:59:41 +00:00
manh-td
b9136bc2fc Add missing check for av_malloc 2025-12-20 10:37:35 +00:00
6e73b90916 Correcting typos in C_Layer libini (#289)
Change `int_get_color` to `int_get_shortcut` to `ini_get_color` and `ini_get_shortcut` to fix library initialization.

Reviewed-on: KolibriOS/kolibrios#289
Reviewed-by: Gleb Zaharov <risdeveau@codrs.ru>
Reviewed-by: Burer <burer@noreply.localhost>
Co-authored-by: Егор <egor00f@noreply.localhost>
Co-committed-by: Егор <egor00f@noreply.localhost>
2025-12-14 10:02:43 +00:00
47ae7a5e33 [apps/cmm] add new proxy for https sources (#277)
Deployed new https proxy for WebView and Downloader.
Made it configurable through /sys/settings/app.ini.

Reviewed-on: KolibriOS/kolibrios#277
Reviewed-by: Mikhail Frolov <mixa.frolov2003@gmail.com>
Co-authored-by: Burer <burer@kolibrios.org>
Co-committed-by: Burer <burer@kolibrios.org>
2025-10-17 11:04:08 +02:00
dd5eb366d5 programs: Add Uxn emulator (#272)
To build this, a zig compiler (tested: 0.14.1) is needed, run `zig build --release=fast`.
It will download https://github.com/chmod222/zuxn when building.

Co-authored-by: 宋文武 <iyzsong@member.fsf.org>
Reviewed-on: KolibriOS/kolibrios#272
Reviewed-by: Mikhail Frolov <mixa.frolov2003@gmail.com>
Reviewed-by: Burer <burer@kolibrios.org>
Co-authored-by: iyzsong <iyzsong@envs.net>
Co-committed-by: iyzsong <iyzsong@envs.net>
2025-10-13 11:52:24 +02:00
90b1db6408 Webview: Fix many typos with the English translation (#282)
- Fixes a few spelling mistakes and rewords things to sound more natural.
- Reworded to sound more natural in English.
- Fixes many typos on the English homepage of WebView.

Reviewed-on: KolibriOS/kolibrios#282
Reviewed-by: Gleb Zaharov <risdeveau@codrs.ru>
Reviewed-by: Burer <burer@noreply.localhost>
Co-authored-by: Talkashie <talkashie97@gmail.com>
Co-committed-by: Talkashie <talkashie97@gmail.com>
2025-10-08 00:12:15 +02:00
48b91b072d general: Fix brand name to КолибриОС (#280)
- Ensure consistent brand name`КолибриОС`; update Docs and source code. Fixes #6.
- Minimal whitespace clean-up; remove some trailing space from end of lines.

Reviewed-on: KolibriOS/kolibrios#280
Reviewed-by: Burer <burer@noreply.localhost>
Reviewed-by: Mikhail Frolov <mixa.frolov2003@gmail.com>
Co-authored-by: Andrew <dent.ace@gmail.com>
Co-committed-by: Andrew <dent.ace@gmail.com>
2025-09-25 16:39:01 +02:00
1e6587b8e9 Libraries: fixed a bug in lib_init functions (#274)
added verification of the second initialization attempt

Reviewed-on: KolibriOS/kolibrios#274
2025-08-02 18:00:18 +02:00
7e26a74ea3 CtrlDemo: code cleaning, library import optimization (#242)
CtrlDemo, EditboxEx, TooltipDemo:
- code cleaning, library import optimization

Reviewed-on: KolibriOS/kolibrios#242
Reviewed-by: Mikhail Frolov <mixa.frolov2003@gmail.com>
Reviewed-by: Ivan B <dunkaist@noreply.localhost>
Co-authored-by: IgorA <aie85playm@gmail.com>
Co-committed-by: IgorA <aie85playm@gmail.com>
2025-07-14 08:49:18 +02:00
dbea5b03fa Libraries (box_lib, buf2d, libimg, tinygl): optimize function import (#231)
Libraries (box_lib, buf2d, libimg, tinygl): optimize function import

Programs updated:
- gears, test3, test_glu1, test_glu2,
- test_array1, textures0, textures1, textures2,
- ctrldemo, editbox_ex, crypt_files, img_transform,
- scrshoot, t_edit, cnc_control, cnc_editor

Reviewed-on: KolibriOS/kolibrios#231
Reviewed-by: Mikhail Frolov <mixa.frolov2003@gmail.com>
Reviewed-by: Ivan B <dunkaist@noreply.localhost>
Co-authored-by: IgorA <aie85playm@gmail.com>
Co-committed-by: IgorA <aie85playm@gmail.com>
2025-07-14 08:20:32 +02:00
ba7bbb8a77 drivers/usb: add usbother driver and usbdrv.dat config (#253)
This driver loading usb drivers for class and for vendor and product id device.

Co-authored-by: Burer <burer@kolibrios.org>
Reviewed-on: KolibriOS/kolibrios#253
Reviewed-by: Ivan B <dunkaist@noreply.localhost>
Reviewed-by: Burer <burer@noreply.localhost>
2025-07-12 03:31:44 +02:00
f8009ca01e Kernel: Fixed bug in iso9660
Fixed a bug of outputting erroneous file names in iso9660 (not juliet)
2025-06-23 12:54:22 +02:00
7780874199 Kernel: Fixed magic numbers and constants in iso9660 2025-06-23 12:54:22 +02:00
273b2d268b FASM: Remove SVN tagged versions (#268)
- Delete SVN tagged versions `1.68` and `1.71`. We do not need to retain historic FASM versions in KolibriOS source code.

(Work towards #75, point 1)

Reviewed-on: KolibriOS/kolibrios#268
Reviewed-by: Burer <burer@noreply.localhost>
Co-authored-by: Andrew <dent.ace@gmail.com>
Co-committed-by: Andrew <dent.ace@gmail.com>
2025-06-23 09:08:41 +02:00
6d84369dac programs: Optimize GIFs (Pt 2) (#238)
Lossless optimization of GIF image files.
Processed with `gifsicle -O3`(extreme) or `gifsicle --no-loopcount --no-comments` (when only minimal adjustment is permitted).
LZW stream optimized with `flexigif -p -f -a=1`. Methods selected to ensure optimal compression with final KPACK step, since better LZW may reduce LZMA used in bundling programs; evaluated with: `xz --format=lzma --check=none --lzma1=mode=normal,dict=64KiB,nice=273,lc=3,lp=0,pb=2 -k -c in.gif > out.lzma`
QA with [GIF Inspector](https://movableink.github.io/gif-inspector/) and via code review.

📦 Program graphics (compiled or included with software):
- Slimmed `demos/free3d04 `, saved 1489 bytes, ~4%.
- Slimmed `media/midamp/` 3 files, saving 131 bytes, average ~4%.
- Slimmed `testing/cpuid/trunk/cyrix.gif`, saved 25 bytes, ~3%.

📖 Documentation only artwork (distributed outside a program):
- Slimmed `Beat/Beat.gif`, saved 29 bytes, ~0.5%.

🥀 Old vestigial images, no longer used (pending deletion):
- Slimmed `demos/3detx60b/` 2 files, saving 762 bytes, average ~5%.

Reviewed-on: KolibriOS/kolibrios#238
Reviewed-by: Burer <burer@noreply.localhost>
Reviewed-by: Ivan B <dunkaist@noreply.localhost>
Co-authored-by: Andrew <dent.ace@gmail.com>
Co-committed-by: Andrew <dent.ace@gmail.com>
2025-06-18 07:04:52 +02:00
75d622c203 programs/games: Optimize GIFs (#235)
Lossless optimization of GIF image files.
Processed with `gifsicle -O3`(extreme) or `gifsicle --no-loopcount` (when only minimal adjustment is permitted).
LZW stream optimized with `flexigif -p -f -a=1`. Methods selected to ensure optimal compression with final KPACK step, since better LZW may reduce LZMA used in bundling programs, using: `xz --format=lzma --check=none --lzma1=mode=normal,dict=64KiB,nice=273,lc=3,lp=0,pb=2 -k -c in.gif > out.lzma`
QA with [GIF Inspector](https://movableink.github.io/gif-inspector/) and via code review.

📦 Program graphics (compiled or included with software):
- Slimmed `almaz/aniall.gif`, saving 380 bytes, ~9%.
- Slimmed `invaders/` 21 files, saving 1232 bytes, average ~3%.
- Slimmed `megamaze/orientg2.gif`, saving 986 bytes, ~31%.
- Slimmed `phenix/objects.gif`, saving 24 bytes, ~2%.

🥀 Old vestigial images, no longer used:
- Deleted `almaz/explode1.gif`, 4865 bytes.

Reviewed-on: KolibriOS/kolibrios#235
Reviewed-by: Burer <burer@noreply.localhost>
Reviewed-by: Ivan B <dunkaist@noreply.localhost>
Co-authored-by: Andrew <dent.ace@gmail.com>
Co-committed-by: Andrew <dent.ace@gmail.com>
2025-06-17 23:54:40 +02:00
d84f4d875d Return four space indents in kermel Makefile 2025-06-13 18:19:10 +02:00
3f1534fb3d Updated kernel Makefile
TBH it worked even without this but okay.
2025-06-13 18:04:59 +02:00
cfacd6c89e Fixed kernel's Makefile by removing bootbios target 2025-06-13 12:32:32 +02:00
206f9b49fa kernel: Remove SVN tags (#247)
- Delete directories (and files) for SVN tags, as these are captured by Git tags: https://git.kolibrios.org/KolibriOS/kolibrios/tags.

(Work towards #75, point 1)

Reviewed-on: KolibriOS/kolibrios#247
Reviewed-by: Burer <burer@noreply.localhost>
Reviewed-by: Ivan B <dunkaist@noreply.localhost>
Co-authored-by: Andrew <dent.ace@gmail.com>
Co-committed-by: Andrew <dent.ace@gmail.com>
2025-06-12 20:00:14 +02:00
e7318d2202 Fix ftpc crash 2025-06-12 19:31:16 +02:00
eca64295b8 Implement serial reconf 2025-05-22 21:26:05 +05:00
47 changed files with 3528 additions and 1682 deletions

View File

@@ -159,7 +159,7 @@ typedef struct {
typedef union {
struct {
uint32_t cpu_usage; // CPU usage (cycles per secondes)
uint32_t cpu_usage; // CPU usage (cycles per secondgoes)
uint16_t pos_in_window_stack; // position of the thread window in the window stack
uint16_t slot_num_window_stack; // slot number in window stack
uint16_t __reserved1; // reserved
@@ -240,30 +240,6 @@ typedef union {
};
} ksys_signal_info_t;
typedef struct {
uint8_t a, b, c, d;
uint8_t debug_label;
uint8_t ABI_low;
uint8_t ABI_high;
uint32_t commit_id;
uint16_t reserved;
uint16_t commit_count;
} ksys_kernel_version_t;
typedef struct
{
uint32_t total_ram_pages;
uint32_t free_ram_pages;
uint32_t page_faults;
uint32_t kernel_heap_size;
uint32_t kernel_heap_free;
uint32_t kernel_heap_total_blocks;
uint32_t kernel_heap_free_blocks;
uint32_t kernel_heap_largest_free_block;
uint32_t kernel_heap_largest_alloc_block;
} ksys_memory_info_t;
#pragma pack(pop)
typedef rgb_t ksys_bitmap_t;
@@ -809,40 +785,6 @@ KOSAPI void _ksys_shutdown(uint32_t shd_param)
asm_inline("int $0x40" ::"a"(18), "b"(9), "c"(shd_param));
}
/*====== Function 18, subfunction 10 - minimize current window. ========*/
KOSAPI void _ksys_minimize_current_windows()
{
asm_inline(
"int $0x40" ::"a"(18), "b"(10));
}
/*========== Function 18, subfunction 13 - get kernel version. =========*/
KOSAPI int _ksys_get_kernel_version(ksys_kernel_version_t* info)
{
int err;
asm_inline(
"int $0x40"
: "=a"(err)
: "a"(18), "b"(13), "c"(info)
: "memory");
return err;
}
/*========= Function 18, subfunction 15 - move mouse to center. ========*/
KOSAPI int _ksys_center_mouse()
{
int a;
asm_inline(
"int $0x40"
: "=a"(a)
: "a"(18), "b"(15));
return a;
}
/*========= Function 18, subfunction 16 - get size of free RAM. ========*/
KOSAPI size_t _ksys_get_ram_size(void)
@@ -901,19 +843,6 @@ KOSAPI uint32_t _ksys_set_mouse_settings(ksys_mouse_settings_t settings, uint32_
#define _ksys_set_mouse_pos(X, Y) _ksys_set_mouse_settings(KSYS_MOUSE_SET_POS, X * 65536 + Y)
/*===================== Function 18, subfunction 20 ====================*/
KOSAPI int _ksys_get_memory_info(ksys_memory_info_t* info)
{
int total;
asm_inline(
"int $0x40"
: "=a"(total)
: "a"(18), "b"(20), "c"(info)
: "memory");
return total;
}
/*===================== Function 18, subfunction 21 ====================*/
/*=====Get the slot number of the process / thread by identifier.. =====*/
@@ -927,216 +856,6 @@ KOSAPI int _ksys_get_thread_slot(int PID)
return val;
}
/*===================== Function 18, subfunction 22 ====================*/
typedef enum KSYS_WIN_REMOTE_CONTROL {
WIN_MINIMIZE_BY_SLOT = 0,
WIN_MINIMIZE_BY_PID = 1,
WIN_RESTORE_BY_SLOT = 2,
WIN_RESTORE_BY_PID = 3
} ksys_win_remote_control_t;
KOSAPI int _ksys_window_remote_control(ksys_win_remote_control_t type, uint32_t param)
{
int result;
asm_inline(
"int $0x40"
: "=a"(result)
: "a"(18), "b"(22), "c"(type), "d"(param));
return result;
}
/*===================== Function 18, subfunction 23 ====================*/
KOSAPI int _ksys_minimize_all_windows()
{
int count;
asm_inline(
"int $0x40"
: "=a"(count)
: "a"(18), "b"(23));
return count;
}
/*===================== Function 18, subfunction 24 ====================*/
KOSAPI void _ksys_set_draw_limits(unsigned int x, unsigned int y)
{
asm_inline(
"int $0x40" ::"a"(18), "b"(24), "c"(x), "d"(y));
}
/*===================== Function 18, subfunction 25 ====================*/
typedef enum KSYS_ZPOS {
KSYS_ZPOS_DESKTOP = -2,
KSYS_ZPOS_ALWAYS_BACK = -1,
KSYS_ZPOS_NORMAL = 0,
KSYS_ZPOS_ALWAYS_TOP = 1
} ksys_zpos_t;
/*=========== Function 18, subfunction 25, subsubfunction 1 ============*/
KOSAPI ksys_zpos_t _ksys_get_window_zposition(int32_t pid)
{
ksys_zpos_t result_eax;
asm_inline(
"int $0x40"
: "=a"(result_eax)
: "a"(18), "b"(25), "c"(1), "d"(pid));
return result_eax;
}
/*=========== Function 18, subfunction 25, subsubfunction 2 ============*/
KOSAPI int _ksys_set_window_zposition(int32_t pid, ksys_zpos_t position)
{
int err;
asm_inline(
"int $0x40"
: "=a"(err)
: "a"(18), "b"(25), "c"(2), "d"(pid), "S"(position));
return err;
}
/*==================== Function 21, subfunction 2 =====================*/
typedef enum KSYS_KEYBOARD_LAYOUT {
KSYS_KEYBOARD_LAYOUT_NORMAL = 1,
KSYS_KEYBOARD_LAYOUT_SHIFT = 2,
KSYS_KEYBOARD_LAYOUT_ALT = 3
} ksys_keyboard_layout_t;
KOSAPI int _ksys_set_keyboard_layout(ksys_keyboard_layout_t mode, char* table)
{
int err;
asm_inline(
"int $0x40"
: "=a"(err)
: "a"(21), "b"(2), "c"(mode), "d"(table));
return err;
}
typedef enum KSYS_LANG {
KSYS_LANG_ENG = 1,
KSYS_LANG_FI = 2,
KSYS_LANG_GER = 3,
KSYS_LANG_RU = 4
} ksys_lang_t;
KOSAPI int _ksys_set_keyboard_lang(ksys_lang_t lang)
{
int err;
asm_inline(
"int $0x40"
: "=a"(err)
: "a"(21), "b"(2), "c"(9), "d"(lang));
return err;
}
/*==================== Function 21, subfunction 5 =====================*/
KOSAPI int _ksys_set_lang(ksys_lang_t lang)
{
int err;
asm_inline(
"int $0x40"
: "=a"(err)
: "a"(21), "b"(5), "c"(lang));
return err;
}
/*==================== Function 21, subfunction 11 =====================*/
KOSAPI int _ksys_allow_HD(int param)
{
int err;
asm_inline(
"int $0x40"
: "=a"(err)
: "a"(21), "b"(11), "c"(param));
return err;
}
/*==================== Function 21, subfunction 12 =====================*/
KOSAPI int _ksys_allow_PCI(int param)
{
int err;
asm_inline(
"int $0x40"
: "=a"(err)
: "a"(21), "b"(12), "c"(param));
return err;
}
typedef enum KSYS_SET_TIME_ERR {
KSYS_SET_TIME_OK = 0,
KSYS_SET_TIME_WRONG_PARAM = 1,
KSYS_SET_TIME_CMOS = 2
} ksys_set_time_err;
/*============================ Function 22 ============================*/
KOSAPI ksys_set_time_err _ksys_set_time(ksys_time_bcd_t time)
{
ksys_set_time_err err;
asm_inline(
"int $0x40"
: "=a"(err)
: "a"(22), "b"(0), "c"(time));
}
KOSAPI ksys_set_time_err _ksys_set_date(ksys_date_bcd_t date)
{
ksys_set_time_err err;
asm_inline(
"int $0x40"
: "=a"(err)
: "a"(22), "b"(1), "c"(date));
}
/*========= Function 26, subfunction 2 - get keyboard layout. ==========*/
KOSAPI uint32_t _ksys_keyboard_layout(ksys_keyboard_layout_t layout, unsigned char* buf)
{
asm_inline("int $0x40" ::"a"(26), "b"(2), "c"(layout), "d"(buf) : "memory");
}
KOSAPI ksys_lang_t _ksys_get_keyboard_lang()
{
ksys_lang_t lang;
asm_inline(
"int $0x40"
: "=a"(lang)
: "a"(26), "b"(2), "c"(9));
return lang;
}
/*======= Function 26, subfunction 5 - get the system language. ========*/
KOSAPI ksys_lang_t _ksys_get_lang()
{
ksys_lang_t lang;
asm_inline(
"int $0x40"
: "=a"(lang)
: "a"(26), "b"(5));
return lang;
}
/*============= Function 23 - wait for event with timeout. =============*/
KOSAPI uint32_t _ksys_wait_event_timeout(uint32_t timeout)

View File

@@ -25,6 +25,7 @@ img_files = {
{"MACROS.INC", SRC_PROGS .. "/macros.inc"},
-- {"CONFIG.INC", SRC_PROGS .. "/config.inc"},
{"STRUCT.INC", SRC_PROGS .. "/struct.inc"},
{"FB2READ", "common/fb2read"},
{"ALLGAMES", "common/allgames"},
{"HOME.PNG", "common/wallpapers/T_Home.png"},
{"ICONS32.PNG", "common/icons32.png"},
@@ -532,7 +533,6 @@ tup.append_table(img_files, {
{"MEDIA/MP3INFO", VAR_PROGS .. "/media/mp3info/mp3info"},
{"MEDIA/PALITRA", VAR_PROGS .. "/media/palitra/trunk/palitra"},
{"MEDIA/PIANO", VAR_PROGS .. "/media/piano/piano"},
{"MEDIA/PIANO.MAP", VAR_PROGS .. "/media/piano/piano.map"},
{"MEDIA/STARTMUS", VAR_PROGS .. "/media/startmus/trunk/STARTMUS"},
{"NETWORK/PING", VAR_PROGS .. "/network/ping/ping"},
{"NETWORK/NETCFG", VAR_PROGS .. "/network/netcfg/netcfg"},
@@ -735,6 +735,7 @@ tup.append_table(extra_files, {
{"kolibrios/develop/TinyBasic/TinyBasic", VAR_PROGS .. "/develop/tinybasic-1.0.4/tinybasic"},
{"kolibrios/develop/TinyBasic/bas/", SRC_PROGS .. "/develop/tinybasic-1.0.4/bas/*"},
{"kolibrios/develop/TinyBasic/TinyBasic.man", SRC_PROGS .. "/develop/tinybasic-1.0.4/doc/tinybasic.man"},
-- {"kolibrios/utils/teatool", VAR_PROGS .. "/other/TEAtool/teatool"},
{"kolibrios/utils/passwordgen", VAR_PROGS .. "/other/PasswordGen/passwordgen"},
{"kolibrios/utils/kruler", VAR_PROGS .. "/other/kruler/kruler"},
{"kolibrios/media/qr_tool", SRC_PROGS .. "/media/qr_tool/qr_tool"},
@@ -748,7 +749,6 @@ end -- tup.getconfig('NO_TCC') ~= 'full'
if tup.getconfig('NO_OB07') ~= 'full' then
tup.append_table(img_files, {
{"DEVELOP/CEDIT", VAR_PROGS .. "/develop/cedit/cedit"},
{"FB2READ", VAR_PROGS .. "/other/fb2reader/fb2read"},
})
end -- tup.getconfig('NO_OB07') ~= 'full'
@@ -758,6 +758,7 @@ tup.append_table(img_files, {
{"GAMES/REVERSI", VAR_PROGS .. "/games/reversi/reversi"},
{"LIB/BASE64.OBJ", VAR_PROGS .. "/develop/libraries/base64/base64.obj"},
{"LIB/ICONV.OBJ", VAR_PROGS .. "/develop/libraries/iconv/iconv.obj"},
-- {"LIB/MTAR.OBJ", VAR_PROGS .. "/develop/libraries/microtar/mtar.obj"},
})
tup.append_table(extra_files, {
-- {"kolibrios/3D/cubeline", VAR_PROGS .. "/demos/cubeline/trunk/cubeline"},

BIN
data/common/fb2read Normal file

Binary file not shown.

View File

@@ -1985,7 +1985,7 @@ path db 'HD0/1',0
подфункция 2 функции 15.
---------------------- Константы для регистров: ----------------------
eax - SF_BACKGROUND_GET (39)
eax - SF_BACKGROUND_GET_RECT (39)
======================================================================
== Функция 39, подфункция 3 - получить прямоугольную область фона =
======================================================================
@@ -2169,7 +2169,7 @@ path db 'HD0/1',0
* ebx = 2 - номер подфункции
* ecx = указатель на таблицу цветов
* edx = размер таблицы цветов
(до 192 байт; 40 байт для базовой структуры)
(должен быть 40 байт для будущей совместимости)
Формат таблицы цветов указан в описании подфункции 3.
Возвращаемое значение:
* функция не возвращает значения
@@ -2196,33 +2196,32 @@ path db 'HD0/1',0
* ecx = указатель на буфер размером edx байт,
куда будет записана таблица
* edx = размер таблицы цветов
(до 192 байт; 40 байт для базовой структуры)
(должен быть 40 байт для будущей совместимости)
Возвращаемое значение:
* функция не возвращает значения
Формат таблицы цветов: каждый элемент -
dword-значение цвета 0x00RRGGBB
* +0: dword: frame
* +4: dword: grab
* +0: dword: none - зарезервировано
* +4: dword: none - зарезервировано
* +8: dword: work_dark - темный цвет рабочей области для придания
объемна элементам интерфейса
* +12 = +0xC: dword: work_light - светлый цвет рабочей области для
придания объемна элементам интерфейса
* +16 = +0x10: dword: grab_text - цвет текста на заголовке
* +20 = +0x14: dword: work - цвет рабочей области
* +24 = +0x18: dword: work_button - цвет кнопки в рабочей области
* +28 = +0x1C: dword: work_button_text - цвет текста на кнопке
* +24 = +0x18: dword: button - цвет кнопки в рабочей области
* +28 = +0x1C: dword: button_text - цвет текста на кнопке
в рабочей области
* +32 = +0x20: dword: work_text - цвет текста в рабочей области
* +36 = +0x24: dword: graph - цвет графики в рабочей области
Замечания:
* Структура таблицы цветов описана в стандартном включаемом файле
macros.inc под названием system_colors; например, можно писать:
sc system_colors ; объявление переменной
... ; вызов описываемой функции с ecx = sc
mov ecx, [sc.work_button_text] ; устанавливаем цвет текста
; на кнопке в рабочей области
* Таблица может быть больше (до 192 байт); дополнительные поля
копируются как есть и интерпретируются скинами.
sc system_colors ; объявление переменной
... ; где-то надо вызвать
; описываемую функцию с ecx=sc
mov ecx, [sc.button_text] ; читаем цвет текста
; на кнопке в рабочей области
* Использование/неиспользование этих цветов - дело исключительно
самой программы. Для использования нужно просто при вызове функций
рисования указывать цвет, взятый из этой таблицы.
@@ -2492,7 +2491,6 @@ dword-значение цвета 0x00RRGGBB
---------------------- Константы для регистров: ----------------------
eax - SF_SET_WINDOW_SHAPE (50)
======================================================================
===================== Функция 51, подфункция 1 =======================
========================== Создать поток =============================
@@ -2507,19 +2505,16 @@ dword-значение цвета 0x00RRGGBB
* иначе eax = TID - идентификатор потока
---------------------- Константы для регистров: ----------------------
eax - SF_CREATE_THREAD (51) /
ebx - SSF_CREATE_THREAD (1), SSF_GET_CURR_THREAD_SLOT (2),
SSF_GET_THREAD_PRIORITY (3), SSF_SET_THREAD_PRIORITY (4)
eax - SF_CREATE_THREAD (51)
======================================================================
===================== Функция 51, подфункция 2 =======================
============= Получить номер слота текущего потока ===================
=================== Получить номер слота потока ======================
======================================================================
Параметры:
* eax = 51 - номер функции
* ebx = 2 - номер подфункции
Возвращаемое значение:
* eax = номер слота текущего потока
* eax = номер слота потока
======================================================================
===================== Функция 51, подфункция 3 =======================
@@ -2760,10 +2755,10 @@ IPC применяется для посылок сообщений от одн
Программе доступны данные графического экрана (область памяти, которая
собственно и отображает содержимое экрана) напрямую без вызовов
системных функций через селектор gs:
mov eax, [gs:0]
mov eax, [gs:0]
поместит в eax первый dword буфера, содержащий информацию о цвете
левой верхней точки (и, возможно, цвета нескольких следующих).
mov [gs:0], eax
mov [gs:0], eax
при работе в режимах VESA c LFB
установит цвет левой верхней точки
(и возможно, цвета нескольких следующих).
@@ -3361,7 +3356,6 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
---------------------- Константы для регистров: ----------------------
eax - SF_SYS_MISC (68)
ebx - SSF_MEM_FREE (13)
======================================================================
====================== Функция 68, подфункция 14 =====================
====== Ожидать получения сигнала от других приложений/драйверов. =====
@@ -3374,16 +3368,12 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
* eax разрушается
* буфер, на который указывает ecx, содержит следующую информацию:
* +0: dword: идентификатор последующих данных сигнала
* +4: 5 dword: данные принятого сигнала, формат которых
* +4: данные принятого сигнала (20 байт), формат которых
определяется первым dword-ом
Замечания:
* Бесконечно ожидает любое событие в очереди событий текущего потока.
* Сбрасывает байт приоритета в буфере.
---------------------- Константы для регистров: ----------------------
eax - SF_SYS_MISC (68)
ebx - SSF_WAIT_SIGNAL (14)
======================================================================
=========== Функция 68, подфункция 16 - загрузить драйвер. ===========
======================================================================
@@ -3392,20 +3382,19 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
* ebx = 16 - номер подфункции
* ecx = указатель на ASCIIZ-строку с именем драйвера
Возвращаемое значение:
* eax = хэндл драйвера
0 при ошибке
* eax = 0 - неудача
* иначе eax = хэндл драйвера
Замечания:
* Если драйвер ещё не загружен, он загружается;
если драйвер уже загружен, ничего не меняется.
* Имя драйвера чувствительно к регистру символов.
Максимальная длина имени - 16 символов, включая завершающий
нулевой символ, остальные символы игнорируются.
* Драйвер с именем "ABC" загружается из файла /sys/drivers/ABC.sys.
* Драйвер с именем ABC загружается из файла /sys/drivers/ABC.sys.
---------------------- Константы для регистров: ----------------------
eax - SF_SYS_MISC (68)
ebx - SSF_LOAD_DRIVER (16)
======================================================================
========== Функция 68, подфункция 17 - управление драйвером. =========
======================================================================
@@ -3416,21 +3405,19 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
* +0: dword: хэндл драйвера
* +4: dword: код функции драйвера
* +8: dword: указатель на входные данные
* +12 = +0x0C: dword: размер входных данных
* +12 = +0xC: dword: размер входных данных
* +16 = +0x10: dword: указатель на выходные данные
* +20 = +0x14: dword: размер выходных данных
Возвращаемое значение:
* eax = определяется драйвером
-1 при ошибке
Замечания:
* Коды функций и структура входных/выходных данных
определяются драйвером.
* Хэндл драйвера необходимо предварительно получить подфункцией 16.
* Предварительно должен быть получен хэндл драйвера подфункцией 16.
---------------------- Константы для регистров: ----------------------
eax - SF_SYS_MISC (68)
ebx - SSF_CONTROL_DRIVER (17)
======================================================================
== Функция 68, подфункция 18 - загрузить DLL с указанием кодировки. ==
======================================================================
@@ -3495,7 +3482,7 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
Параметры:
* eax = 68 - номер функции
* ebx = 21 - номер подфункции
* ecx = указатель на ASCIIZ-строку с путем к файлу драйвера
* ecx = указатель на ASCIIZ-строку с именем драйвера
* edx = указатель на командную строку
Возвращаемое значение:
* eax = 0 - неудача
@@ -3687,40 +3674,22 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
* функция загружает и, при необходимости, распаковывает файл (kunpack)
======================================================================
======= Функция 68, подфункция 29 - выделить кольцевую память. =======
======== Функция 68, подфункция 29 - allocate ring memory. =========
======================================================================
Параметры:
* eax = 68 - номер функции
* ebx = 29 - номер подфункции
* ecx = требуемый размер в байтах
Возвращаемое значение:
* eax = 0 - неудача
* eax = указатель на выделенную кольцевую память
Замечания:
* Запрошенный размер должен быть кратен размеру страницы (4 Кб).
* Память выделяется так, что доступ за пределами буфера приводит
к чтению/записи в его начало.
Parameters:
* eax = 68 - function number
* ebx = 29 - subfunction number
* ecx = required size in bytes
Returned value:
* eax = 0 - failed
* eax = pointer to the allocated ring
Remarks:
* The requested size must be an exact multiple of pagesize (4 Kb)
* The function allocates memory in such a way that you can read and
write beyond the size of the allocated memory and will reach the
beginning of the buffer again.
======================================================================
=========== Функция 68, подфункция 30 - выгрузить драйвер. ===========
======================================================================
Параметры:
* eax = 68 - номер функции
* ebx = 30 - номер подфункции
* ecx = указатель на структуру SRV (хэндл драйвера)
* edx = указатель на командную строку (может быть 0)
Возвращаемое значение:
* eax = -1 - неверные параметры
* eax = -2 - ошибка при освобождении памяти драйвера
* иначе eax = указатель на следующую структуру SRV (бывший SRV.fd)
Замечания:
* Перед выгрузкой вызывается точка входа драйвера с DRV_EXIT.
---------------------- Константы для регистров: ----------------------
eax - SF_SYS_MISC (68)
ebx - SSF_UNLOAD_DRIVER (30)
======================================================================
======== Функция 68, подфункция 31 - получить данные драйвера. =======
======================================================================
@@ -3819,7 +3788,7 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
и при поступлении нового сообщения система будет ждать.
Для синхронизации обрамляйте всю работу с буфером операциями
блокировки/разблокировки
neg [bufsize]
neg [bufsize]
* Данные в буфере трактуются как массив элементов переменной длины -
сообщений. Формат сообщения указан в общем описании.
@@ -4558,7 +4527,7 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
---------------------- Константы для регистров: ----------------------
eax - SF_NETWORK_GET (74)
bl - SSF_DEVICE_COUNT (-1)
bl - SSF_DEVICE_COUNT (255)
======================================================================
==== Функция 74, подфункция 0, Получить тип сетевого устройства. =====
======================================================================
@@ -4754,11 +4723,10 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
Возвращаемое значение:
* eax = число пакетов, полученных с ошибкой с момента запуска
устройства, -1 при ошибке
---------------------- Константы для регистров: ----------------------
eax - SF_NETWORK_GET (74)
bl - SSF_RX_PACKET_ERROR_COUNT (14)
======================================================================
== Функция 74.15, Получить число пакетов отброшенных при получении. ==
======================================================================
@@ -4772,7 +4740,7 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
---------------------- Константы для регистров: ----------------------
eax - SF_NETWORK_GET (74)
bl - SSF_RX_PACKET_DROP_COUNT (15)
bl - SSF_RX_PACKET_DROP_COUNT (12)
======================================================================
=== Функция 74.16, Получить число пакетов утерянных при получении. ===
======================================================================
@@ -5022,39 +4990,13 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
---------------------- Константы для регистров: ----------------------
eax - SF_NETWORK_PROTOCOL (76)
ebx - SSF_ETHERNET_READ_MAC (0x0000)
ebx - SSF_IP4_PACKETS_SENT (0x10000)
ebx - SSF_IP4_PACKETS_RECEIVED (0x10001)
ebx - SSF_IP4_READ_IP (0x10002)
ebx - SSF_IP4_WRITE_IP (0x10003)
ebx - SSF_IP4_READ_DNS (0x10004)
ebx - SSF_IP4_WRITE_DNS (0x10005)
ebx - SSF_IP4_READ_SUBNET (0x10006)
ebx - SSF_IP4_WRITE_SUBNET (0x10007)
ebx - SSF_IP4_READ_GATEWAY (0x10008)
ebx - SSF_IP4_WRITE_GATEWAY (0x10009)
ebx - SSF_ICMP_PACKETS_SENT (0x20000)
ebx - SSF_ICMP_PACKETS_RECEIVED (0x20001)
ebx - SSF_ICMP_ECHO_REPLY (0x20003)
ebx - SSF_UDP_PACKETS_SENT (0x30000)
ebx - SSF_UDP_PACKETS_RECEIVED (0x30001)
ebx - SSF_TCP_PACKETS_SENT (0x40000)
ebx - SSF_TCP_PACKETS_RECEIVED (0x40001)
ebx - SSF_ARP_PACKETS_SENT (0x50000)
ebx - SSF_ARP_PACKETS_RECEIVED (0x50001)
ebx - SSF_ARP_GET_ENTRY_COUNT (0x50002)
ebx - SSF_ARP_READ_ENTRY (0x50003)
ebx - SSF_ARP_ADD_STATIC_ENTRY (0x50004)
ebx - SSF_ARP_DEL_ENTRY (0x50005)
ebx - SSF_ARP_SEND_ANNOUNCE (0x50006)
ebx - SSF_ARP_CONFLICTS_COUNT (0x50007)
======================================================================
============= Функция 77, подфункция 0, Создать фьютекс. =============
======================================================================
Параметры:
* eax = 77 - номер функции
* ebx = 0 - номер подфункции
* ecx = контрольное значение фьютекса (dword)
* ecx = указатель на контрольное значение фьютекса (dword)
Возвращаемое значение:
* eax = дескриптор фьютекса, 0 при ошибке
@@ -5083,12 +5025,11 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
* eax = 77 - номер функции
* ebx = 2 - номер подфункции
* ecx = дескриптор фьютекса
* edx = контрольное значение фьютекса (dword)
* edx = контрольное значение
* esi = таймаут в сотых секунды, 0 - ждать бесконечно
Возвращаемое значение:
* eax = 0 - успешно,
-1 - таймаут,
-2 - контрольное значение фьютекса не соответствует
* eax = 0 - успешно, -1 - таймаут,
-2 - контрольное значение не соответствует
---------------------- Константы для регистров: ----------------------
eax - SF_FUTEX (77)
@@ -5108,11 +5049,7 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
eax - SF_FUTEX (77)
ebx - SSF_WAKE (3)
======================================================================
Замечания:
* Подфункции 4-7 зарезервированы и сейчас возвращают -1.
* Подфункции 8, 9 и 12 не реализованы и возвращают -EBADF (-9).
======================================================================
=========== Функция 77, подфункция 10, Прочитать из файла. ===========
======= Функция 77, подфункция 10, Прочитать из файла в буфер. =======
======================================================================
Параметры:
* eax = 77 - номер функции
@@ -5122,15 +5059,10 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
* esi = сколько байт прочитать
Возвращаемое значение:
* eax = количество прочитанных байт
0 при EOF
-EBADF (-9) при ошибке
Замечания:
* Поддерживаются только pipe-дескрипторы.
---------------------- Константы для регистров: ----------------------
eax - SF_FUTEX (77)
ebx - SSF_FILE_READ (10)
ebx - ...
======================================================================
======== Функция 77, подфункция 11, Записать из буфера в файл. =======
======================================================================
@@ -5138,19 +5070,14 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
* eax = 77 - номер функции
* ebx = 11 - номер подфункции
* ecx = дескриптор файла
* edx = указатель на буфер, откуда брать данные для записи
* edx = указатель на буфер, откуда брать данные для записи
* esi = сколько байт записать
Возвращаемое значение:
* eax = количество записанных байт
-EBADF (-9) при ошибке
-EPIPE (-32) если нет читателей
Замечания:
* Поддерживаются только pipe-дескрипторы.
---------------------- Константы для регистров: ----------------------
eax - SF_FUTEX (77)
ebx - SSF_FILE_WRITE (11)
ebx - ...
======================================================================
=========== Функция 77, подфункция 13, Создать новый pipe. ===========
======================================================================
@@ -5162,20 +5089,15 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
* eax = 77 - номер функции
* ebx = 13 - номер подфункции
* ecx = адрес pipefd
* edx = флаги. Разрешен только O_CLOEXEC (0x40000).
Любые другие биты приводят к -EINVAL (-11).
* edx = флаги. На данный момент если поднят O_CLOEXEC (0x40000), то
сисфункция завершится с ошибкой. Поэтому в качестве флагов можно
передать просто 0.
Возвращаемое значение:
* eax = 0 если успех,
иначе отрицательный код ошибки:
-EINVAL (-11), -EFAULT (-14), -ENFILE (-23), -EMFILE (-24)
Примечания:
* В случае успеха pipefd[0] является дескриптором чтения, а pipefd[1]
- дескриптором записи.
* eax = 0 если успех, иначе ошибка.
---------------------- Константы для регистров: ----------------------
eax - SF_FUTEX (77)
ebx - SSF_PIPE_CREATE (13)
ebx - ...
======================================================================
========== Функция -1 - завершить выполнение потока/процесса =========
======================================================================
@@ -5193,7 +5115,6 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
---------------------- Константы для регистров: ----------------------
eax - SF_TERMINATE_PROCESS (-1)
======================================================================
=== Функция 80 - работа с файловой системой с указанием кодировки. ===
======================================================================

View File

@@ -1972,7 +1972,7 @@ Remarks:
subfunction 2 of function 15.
---------------------- Constants for registers: ----------------------
eax - SF_BACKGROUND_GET (39)
eax - SF_BACKGROUND_GET_RECT (39)
======================================================================
== Function 39, subfunction 3 - get rect from the background image. =
======================================================================
@@ -2152,7 +2152,7 @@ Parameters:
* ebx = 2 - subfunction number
* ecx = pointer to the color table
* edx = size of the color table
(up to 192 bytes; 40 bytes for the base structure)
(must be 40 bytes for future compatibility)
Format of the color table is shown in description of subfunction 3.
Returned value:
* function does not return value
@@ -2179,21 +2179,21 @@ Parameters:
* ecx = pointer to the buffer with size edx bytes,
where table will be written
* edx = size of color table
(up to 192 bytes; 40 bytes for the base structure)
(must be 40 bytes for future compatibility)
Returned value:
* function does not return value
Format of the color table:
each item is dword-value for color 0x00RRGGBB
* +0: dword: frame
* +4: dword: grab
* +0: dword: none - reserved
* +4: dword: none - reserved
* +8: dword: work_dark - dark color of working area
used to give a user 3D-like feelings about interface elements
* +12 = +0xC: dword: work_light - light color of working area
used to give a user 3D-like feelings about interface elements
* +16 = +0x10: dword: grab_text - color of text on header
* +20 = +0x14: dword: work - color of working area
* +24 = +0x18: dword: work_button - color of button in working area
* +28 = +0x1C: dword: work_button_text - color of text on button
* +24 = +0x18: dword: button - color of button in working area
* +28 = +0x1C: dword: button_text - color of text on button
in working area
* +32 = +0x20: dword: work_text - color of text in working area
* +36 = +0x24: dword: graph - color of graphics in working area
@@ -2206,8 +2206,6 @@ Remarks:
; this function with ecx=sc
mov ecx, [sc.work_button_text] ; read text color on
; button in working area
* The table may be longer (up to 192 bytes); extra fields are copied
as-is and are interpreted by skins.
* A program itself decides to use or not to use color table.
For usage program must simply at calls to drawing functions select
color taken from the table.
@@ -2480,11 +2478,11 @@ Remarks:
---------------------- Constants for registers: ----------------------
eax - SF_SET_WINDOW_SHAPE (50)
======================================================================
============= Function 51, subfunction 1 - create thread. ============
==================== Function 51 - create thread. ====================
======================================================================
Parameters:
* eax = 51 - function number
* ebx = 1 - subfunction number
* ebx = 1 - unique subfunction
* ecx = address of thread entry point (starting eip)
* edx = pointer to thread stack (starting esp)
Returned value:
@@ -2493,49 +2491,6 @@ Returned value:
---------------------- Constants for registers: ----------------------
eax - SF_CREATE_THREAD (51)
ebx - SSF_CREATE_THREAD (1), SSF_GET_CURR_THREAD_SLOT (2),
SSF_GET_THREAD_PRIORITY (3), SSF_SET_THREAD_PRIORITY (4)
======================================================================
================== Function 51, subfunction 2 ========================
================== Get current thread slot number ====================
======================================================================
Parameters:
* eax = 51 - function number
* ebx = 2 - subfunction number
Returned value:
* eax = slot number of the current thread
======================================================================
================== Function 51, subfunction 3 ========================
===================== Get thread priority ============================
======================================================================
Parameters:
* eax = 51 - function number
* ebx = 3 - subfunction number
* ecx = slot number of the thread or -1 (current thread)
Returned value:
* eax = -1 - error (invalid slot number or thread terminated)
* otherwise eax = thread priority
Remarks:
* Priority range is 0..255.
0 is the highest priority and is set by default at creation.
======================================================================
================== Function 51, subfunction 4 ========================
===================== Set thread priority ============================
======================================================================
Parameters:
* eax = 51 - function number
* ebx = 4 - subfunction number
* ecx = slot number of the thread or -1 (current thread)
* edx = new thread priority
Returned value:
* eax = -1 - error (invalid slot number or thread terminated)
* otherwise eax = previous thread priority
Remarks:
* Priority range is 0..255.
0 is the highest priority and is set by default at creation.
======================================================================
==================== Function 54, subfunction 0 ======================
============== Get the number of slots in the clipboard. =============
@@ -3334,63 +3289,61 @@ Remarks:
ebx - SSF_MEM_FREE (13)
======================================================================
===================== Function 68, subfunction 14 ====================
======= Wait for a signal from other applications/drivers. ===========
============ Wait for signal from another program/driver. ============
======================================================================
Parameters:
* eax = 68 - function number
* ebx = 14 - subfunction number
* ecx = pointer to data buffer (6 dword = 24 bytes)
* ecx = pointer to the buffer for information (24 bytes)
Returned value:
* eax is destroyed
* buffer pointed to by ecx contains the following information:
* +0: dword: EVENT.code (identifier of following data)
* +4: 5 dword: EVENT.data, format depends on EVENT.code
Remarks:
* Waits indefinitely for any event in the current thread event queue.
* The priority byte in the buffer is cleared by the kernel.
* +0: dword: identifier for following data of signal
* +4: dword: data of signal (20 bytes), format of which is defined
by the first dword
---------------------- Constants for registers: ----------------------
eax - SF_SYS_MISC (68)
ebx - SSF_WAIT_SIGNAL (14)
======================================================================
=========== Function 68, subfunction 16 - load driver. ===============
============= Function 68, subfunction 16 - load driver. =============
======================================================================
Parameters:
* eax = 68 - function number
* ebx = 16 - subfunction number
* ecx = pointer to ASCIIZ-string with driver name
Returned value:
* eax = driver handle, 0 on error
* eax = 0 - failed
* otherwise eax = driver handle
Remarks:
* If the driver is not loaded yet, it is loaded;
if the driver is already loaded, nothing changes.
* If the driver was not loaded yet, it is loaded;
if the driver was loaded yet, nothing happens.
* Driver name is case-sensitive.
Maximum length of the name is 16 characters, including
terminating null character, the rest is ignored.
* Driver with name "ABC" is loaded from /sys/drivers/ABC.sys.
* Driver ABC is loaded from file /sys/drivers/ABC.sys.
---------------------- Constants for registers: ----------------------
eax - SF_SYS_MISC (68)
ebx - SSF_LOAD_DRIVER (16)
======================================================================
========== Function 68, subfunction 17 - control driver. =============
============ Function 68, subfunction 17 - driver control. ===========
======================================================================
Parameters:
* eax = 68 - function number
* ebx = 17 - subfunction number
* ecx = pointer to the control structure:
* +0: dword: driver handle
* +4: dword: driver function code
* +8: dword: pointer to input data
* +12: dword: size of input data
* +16: dword: pointer to output data
* +20: dword: size of output data
* +0: dword: handle of driver
* +4: dword: code of driver function
* +8: dword: pointer to input data
* +12 = +0xC: dword: size of input data
* +16 = +0x10: dword: pointer to output data
* +20 = +0x14: dword: size of output data
Returned value:
* eax = determined by driver, -1 on error
* eax = determined by driver
Remarks:
* Function codes and the structure of input/output data
are defined by the driver.
* Driver handle can be obtained by subfunction 16.
are defined by driver.
* Previously one must obtain driver handle by subfunction 16.
---------------------- Constants for registers: ----------------------
eax - SF_SYS_MISC (68)
@@ -3458,7 +3411,7 @@ Remarks:
Parameters:
* eax = 68 - function number
* ebx = 21 - subfunction number
* ecx = pointer to ASCIIZ-string with path to driver file
* ecx = pointer to ASCIIZ-string with driver name
* edx = pointer to command line
Returned value:
* eax = 0 - failed
@@ -3663,24 +3616,9 @@ Remarks:
write beyond the size of the allocated memory and will reach the
beginning of the buffer again.
======================================================================
=========== Function 68, subfunction 30 - unload driver. ============
======================================================================
Parameters:
* eax = 68 - function number
* ebx = 30 - subfunction number
* ecx = pointer to SRV structure (driver handle)
* edx = pointer to command line (may be 0)
Returned value:
* eax = -1 - invalid parameters
* eax = -2 - error while freeing driver memory
* otherwise eax = pointer to the next SRV structure (former SRV.fd)
Remarks:
* The driver entry is called with DRV_EXIT before unloading.
---------------------- Constants for registers: ----------------------
eax - SF_SYS_MISC (68)
ebx - SSF_UNLOAD_DRIVER (30)
ebx - SSF_MEM_ALLOC_RING (29)
======================================================================
=========== Function 68, subfunction 31 - get driver data. ===========
@@ -3895,7 +3833,7 @@ Remarks:
eax - SF_DEBUG (69)
ebx - SSF_RESUME (5)
======================================================================
= Function 69, subfunction 6 - read from memory of debugged process. =
= Fucntion 69, subfunction 6 - read from memory of debugged process. =
======================================================================
Parameters:
* eax = 69 - function number
@@ -4504,17 +4442,17 @@ Returned value:
---------------------- Constants for registers: ----------------------
eax - SF_BLITTER (73)
======================================================================
= Function 74, Subfunction -1, Get number of active network devices. =
= Function 74, Subfunction 255, Get number of active network devices. =
======================================================================
Parameters:
* eax = 74 - function number
* bl = -1 - subfunction number
* bl = 255 - subfunction number
Returned value:
* eax = number of active network devices
---------------------- Constants for registers: ----------------------
eax - SF_NETWORK_GET (74)
bl - SSF_DEVICE_COUNT (-1)
bl - SSF_DEVICE_COUNT (255)
======================================================================
======== Function 74, Subfunction 0, Get network device type. ========
======================================================================
@@ -4667,7 +4605,7 @@ Parameters:
* bl = 11 - subfunction number
* bh = device number
Returned value:
* eax = Number of erroneous packets transmitted since device start, -1 on error
* eax = Number of erroneous packets received since device start, -1 on error
---------------------- Constants for registers: ----------------------
eax - SF_NETWORK_GET (74)
@@ -4723,7 +4661,7 @@ Returned value:
---------------------- Constants for registers: ----------------------
eax - SF_NETWORK_GET (74)
bl - SSF_RX_PACKET_DROP_COUNT (15)
bl - SSF_RX_PACKET_DROP_COUNT (12)
======================================================================
==== Function 74, Subfunction 16, Get RX missed packets counter. =====
======================================================================
@@ -5236,41 +5174,19 @@ Returned value:
---------------------- Constants for registers: ----------------------
eax - SF_NETWORK_PROTOCOL (76)
ebx - SSF_ETHERNET_READ_MAC (0x0000)
ebx - SSF_IP4_PACKETS_SENT (0x10000)
ebx - SSF_IP4_PACKETS_RECEIVED (0x10001)
ebx - SSF_IP4_READ_IP (0x10002)
ebx - SSF_IP4_WRITE_IP (0x10003)
ebx - SSF_IP4_READ_DNS (0x10004)
ebx - SSF_IP4_WRITE_DNS (0x10005)
ebx - SSF_IP4_READ_SUBNET (0x10006)
ebx - SSF_IP4_WRITE_SUBNET (0x10007)
ebx - SSF_IP4_READ_GATEWAY (0x10008)
ebx - SSF_IP4_WRITE_GATEWAY (0x10009)
ebx - SSF_ICMP_PACKETS_SENT (0x20000)
ebx - SSF_ICMP_PACKETS_RECEIVED (0x20001)
ebx - SSF_ICMP_ECHO_REPLY (0x20003)
ebx - SSF_UDP_PACKETS_SENT (0x30000)
ebx - SSF_UDP_PACKETS_RECEIVED (0x30001)
ebx - SSF_TCP_PACKETS_SENT (0x40000)
ebx - SSF_TCP_PACKETS_RECEIVED (0x40001)
ebx - SSF_ARP_PACKETS_SENT (0x50000)
ebx - SSF_ARP_PACKETS_RECEIVED (0x50001)
ebx - SSF_ARP_GET_ENTRY_COUNT (0x50002)
ebx - SSF_ARP_READ_ENTRY (0x50003)
ebx - SSF_ARP_ADD_STATIC_ENTRY (0x50004)
ebx - SSF_ARP_DEL_ENTRY (0x50005)
ebx - SSF_ARP_SEND_ANNOUNCE (0x50006)
ebx - SSF_ARP_CONFLICTS_COUNT (0x50007)
======================================================================
========== Function 77, Subfunction 0, Create futex object ===========
======================================================================
Parameters:
* eax = 77 - function number
* ebx = 0 - subfunction number
* ecx = futex control value (dword)
* ecx = pointer to futex dword
Returned value:
* eax = futex handle, 0 on error
Remarks:
* Use subfunction 1 to destroy the futex.
The kernel destroys the futexes automatically when the process
terminates.
---------------------- Constants for registers: ----------------------
eax - SF_FUTEX (77)
@@ -5285,8 +5201,7 @@ Parameters:
Returned value:
* eax = 0 - successfull, -1 on error
Remarks:
* The kernel destroys the futexes automatically when the process
terminates.
* The futex handle must have been created by subfunction 0
---------------------- Constants for registers: ----------------------
eax - SF_FUTEX (77)
@@ -5298,12 +5213,17 @@ Parameters:
* eax = 77 - function number
* ebx = 2 - subfunction number
* ecx = futex handle
* edx = futex control value (dword)
* esi = timeout in hundredths of a second, 0 - wait forever
* edx = control value
* esi = timeout in system ticks or 0 for infinity
Returned value:
* eax = 0 - successfull
-1 - timeout
-2 - futex control value doesn't match
-1 - timeout
-2 - futex dword does not have the same value as edx
Remarks:
* This functionn tests that the value at the futex dword still
contains the expected control value, and if so, then sleeps
waiting for a wake operation on the futex.
* The futex handle must have been created by subfunction 0
---------------------- Constants for registers: ----------------------
eax - SF_FUTEX (77)
@@ -5319,71 +5239,15 @@ Parameters:
Returned value:
* eax = number of waiters that were woken up
Remarks:
* This function wakes at most edx of the waiters that are
waiting (e.g., inside futex wait) on the futex dword
* The futex handle must have been created by subfunction 0
---------------------- Constants for registers: ----------------------
eax - SF_FUTEX (77)
ebx - SSF_WAKE (3)
======================================================================
Remarks:
* Subfunctions 4-7 are reserved and currently return -1.
* Subfunctions 8-9 and 12 are not implemented and return -EBADF (-9).
======================================================================
============ Function 77, Subfunction 10, Read from file. ============
======================================================================
Parameters:
* eax = 77 - function number
* ebx = 10 - subfunction number
* ecx = file handle
* edx = pointer to destination buffer
* esi = number of bytes to read
Returned value:
* eax = number of bytes read,
0 on EOF,
-EBADF (-9) on error
Remarks:
* Only pipe descriptors are supported.
---------------------- Constants for registers: ----------------------
eax - SF_FUTEX (77)
ebx - SSF_FILE_READ (10)
======================================================================
=========== Function 77, Subfunction 11, Write to file. =============
======================================================================
Parameters:
* eax = 77 - function number
* ebx = 11 - subfunction number
* ecx = file handle
* edx = pointer to source buffer
* esi = number of bytes to write
Returned value:
* eax = number of bytes written,
-EBADF (-9) on error,
-EPIPE (-32) if no readers
Remarks:
* Only pipe descriptors are supported.
---------------------- Constants for registers: ----------------------
eax - SF_FUTEX (77)
ebx - SSF_FILE_WRITE (11)
======================================================================
========== Function 77, Subfunction 13, Create pipe. ================
======================================================================
Parameters:
* eax = 77 - function number
* ebx = 13 - subfunction number
* ecx = pointer to pipefd[2] array (two dword handles)
* edx = flags (only O_CLOEXEC is allowed)
Returned value:
* eax = 0 on success,
negative errno value on error:
-EINVAL (-11), -EFAULT (-14), -ENFILE (-23), -EMFILE (-24)
Remarks:
* On success, pipefd[0] is a read handle and pipefd[1] is a
write handle.
---------------------- Constants for registers: ----------------------
eax - SF_FUTEX (77)
ebx - SSF_PIPE_CREATE (13)
======================================================================
=== Function 80 - file system interface with parameter of encoding ===
======================================================================
Parameters:

View File

@@ -70,11 +70,11 @@ SF_SYSTEM=18
SSF_WINDOW_BEHAVIOR=25 ; window focus relation with other windows
SSSF_GET_WB=1
SSSF_SET_WB=2
SF_MIDI=20 ; deprecated/undefined in current kernel
SSF_RESET=1 ; deprecated
SSF_OUTPUT=2 ; deprecated
SF_MIDI=20
SSF_RESET=1
SSF_OUTPUT=2
SF_SYSTEM_SET=21
SSF_MPU_MIDI_BASE=1 ; not used (reserved)
SSF_MPU_MIDI_BASE=1
SSF_KEYBOARD_LAYOUT=2
SSF_SYS_LANG=5
SSF_ACCESS_HD_LBA=11 ; setting of low-level access to HD
@@ -112,7 +112,7 @@ SF_BACKGROUND_GET=39
;SSF_PIXEL_BG=2
;SSF_MODE_BG=4
SF_SET_EVENTS_MASK=40 ; turn on/off desired events
SF_PORT_IN_OUT=43 ; deprecated/undefined in current kernel
SF_PORT_IN_OUT=43 ; input/output to a port
SF_SET_PORTS=46 ; reserve/free a group of input/output ports
SF_DRAW_NUMBER=47 ; draw number to the window
SF_STYLE_SETTINGS=48
@@ -132,10 +132,6 @@ SF_STYLE_SETTINGS=48
SF_APM=49
SF_SET_WINDOW_SHAPE=50
SF_CREATE_THREAD=51
SSF_CREATE_THREAD=1
SSF_GET_CURR_THREAD_SLOT=2
SSF_GET_THREAD_PRIORITY=3
SSF_SET_THREAD_PRIORITY=4
SF_CLIPBOARD=54
SSF_GET_SLOT_COUNT=0 ; get the number of slots in the clipboard
SSF_READ_CB=1
@@ -188,7 +184,7 @@ SF_SYS_MISC=68
SSF_HEAP_INIT=11
SSF_MEM_ALLOC=12
SSF_MEM_FREE=13
SSF_WAIT_SIGNAL=14 ; wait for a signal from other process
SSF_WAIT_SIGNAL=14 ; wait for signal from another program/driver
SSF_LOAD_DRIVER=16
SSF_CONTROL_DRIVER=17
SSF_LOAD_DLL=19
@@ -200,9 +196,6 @@ SF_SYS_MISC=68
SSF_SET_EXCEPTION_STATE=25
SSF_MEM_FREE_EXT=26
SSF_LOAD_FILE=27
SSF_MEM_ALLOC_RING=29
SSF_UNLOAD_DRIVER=30
SSF_GET_DRIVER_DATA=31
SF_DEBUG=69
SSF_SET_MESSAGE_AREA=0
SSF_GET_REGISTERS=1
@@ -228,7 +221,7 @@ SF_FILE=70
SF_SET_CAPTION=71
SF_SEND_MESSAGE=72
SF_BLITTER=73
SF_NETWORK_GET=74
SF_NETWORK_DEVICE=74
SSF_DEVICE_COUNT=255 ; get number of active network devices
SSF_DEVICE_TYPE=0
SSF_DEVICE_NAME=1
@@ -257,7 +250,7 @@ SF_NETWORK_SOCKET=75
SSF_RECEIVE=7
SSF_SET_OPTIONS=8
SSF_GET_OPTIONS=9
SSF_GET_PAIR=10
SSF_SOCKET_PAIR=10
SF_NETWORK_PROTOCOL=76
SSF_ETHERNET_READ_MAC=0
SSF_IP4_PACKETS_SENT=10000h
@@ -290,9 +283,6 @@ SF_FUTEX=77
SSF_DESTROY=1
SSF_WAIT=2
SSF_WAKE=3
SSF_FILE_READ=10
SSF_FILE_WRITE=11
SSF_PIPE_CREATE=13
; File system errors:
FSERR_SUCCESS=0

View File

@@ -172,7 +172,7 @@ else
end if
}
include '../../KOSfuncs.inc'
include 'kosfuncs.inc'
include '../../macros.inc'
include 'font.inc'

View File

@@ -0,0 +1,298 @@
; KolibriOS system functions:
SF_TERMINATE_PROCESS=-1
SF_CREATE_WINDOW=0 ; define and draw the window
SF_PUT_PIXEL=1 ; draw pixel to the window
SF_GET_KEY=2 ; get code of the pressed key
SF_GET_SYS_TIME=3
SF_DRAW_TEXT=4
SF_SLEEP=5 ; pause process
SF_PUT_IMAGE=7 ; draw image to the window
SF_DEFINE_BUTTON=8 ; define/delete the button
SF_THREAD_INFO=9 ; information on execution thread
SF_WAIT_EVENT=10 ; wait for event
SF_CHECK_EVENT=11 ; check for event and return
SF_REDRAW=12
SSF_BEGIN_DRAW=1
SSF_END_DRAW=2
SF_DRAW_RECT=13 ; draw rectangle to the window
SF_GET_SCREEN_SIZE=14 ; get screen resolution
SF_BACKGROUND_SET=15 ; work with desktop background graphics
SSF_SIZE_BG=1 ; set a size of the background image
SSF_PIXEL_BG=2 ; put pixel on the background image
SSF_REDRAW_BG=3 ; redraw background
SSF_MODE_BG=4 ; set drawing mode for the background
SSF_IMAGE_BG=5 ; put block of pixels on the background image
SSF_MAP_BG=6 ; map background image to the address space of the process
SSF_UNMAP_BG=7 ; close mapped background data
SSF_LAST_DRAW=8 ; get coordinates of the last draw to the background
SSF_REDRAW_RECT=9 ; redraws a rectangular part of the background
SF_RD_TO_FLOPPY=16 ; save ramdisk on the floppy
SF_GET_BUTTON=17 ; get ID of the pressed button
SF_SYSTEM=18
SSF_UNFOCUS_WINDOW=1 ; take focus from the window of the given thread
SSF_TERMINATE_THREAD=2 ; terminate process/thread by the slot number
SSF_FOCUS_WINDOW=3 ; give focus to the window of the given thread
SSF_GET_IDLE_COUNT=4 ; get counter of idle cycles per second
SSF_GET_CPU_FREQUENCY=5 ; get CPU clock rate
SSF_RD_TO_HDD=6 ; save ramdisk to the file on hard disk
SSF_GET_ACTIVE_WINDOW=7 ; get slot number of the active window
SSF_SPEAKER=8
SSSF_GET_STATE=1
SSSF_TOGGLE=2
SSF_SHUTDOWN=9 ; system shutdown/reboot
SSF_MINIMIZE_WINDOW=10 ; minimize active window
SSF_INFO_DISC_SYS=11 ; get disk subsystem information
SSF_KERNEL_VERSION=13 ; get kernel version
SSF_WAIT_RETRACE=14 ; wait for screen retrace
SSF_CURSOR_CENTER=15 ; center mouse cursor on the screen
SSF_GET_FREE_RAM=16 ; get size of free RAM
SSF_GET_TOTAL_RAM=17 ; get total amount of RAM
SSF_TERMINATE_THREAD_ID=18 ; Terminate process/thread by the ID
SSF_MOUSE_SETTINGS=19
SSSF_GET_SPEED=0
SSSF_SET_SPEED=1
SSSF_GET_SPEEDUP=2
SSSF_SET_SPEEDUP=3 ; set mouse acceleration
SSSF_SET_POS=4 ; set mouse pointer position
SSSF_SET_BUTTON=5 ; simulate state of mouse buttons
SSSF_GET_DOUBLE_CLICK_DELAY=6
SSSF_SET_DOUBLE_CLICK_DELAY=7
SSF_GET_RAM_INFO=20 ; get information on RAM
SSF_GET_THREAD_SLOT=21 ; get slot number of process/thread by the ID
SSF_FOREIGN_WINDOW=22 ; operations with window of another thread by slot/ID
SSSF_MINIMIZE=0
SSSF_MINIMIZE_ID=1
SSSF_RESTORE=2
SSSF_RESTORE_ID=3
SSF_MINIMIZE_ALL=23
SSF_SET_SCREEN_LIMITS=24
SSF_WINDOW_BEHAVIOR=25 ; window focus relation with other windows
SSSF_GET_WB=1
SSSF_SET_WB=2
SF_MIDI=20
SSF_RESET=1
SSF_OUTPUT=2
SF_SYSTEM_SET=21
SSF_MPU_MIDI_BASE=1
SSF_KEYBOARD_LAYOUT=2
SSF_SYS_LANG=5
SSF_ACCESS_HD_LBA=11 ; setting of low-level access to HD
SSF_ACCESS_PCI=12 ; setting of low-level access to PCI
SF_SET_TIME_DATE=22
SF_WAIT_EVENT_TIMEOUT=23; wait for event with timeout
SF_CD=24
SSF_EJECT_TRAY=4
SSF_INSERT_TRAY=5
SF_SCREEN_PUT_IMAGE=25 ; put image on the background layer
SF_SYSTEM_GET=26
; Same as SF_SYSTEM_SET, plus:
SSF_TIME_COUNT=9
SSF_TIME_COUNT_PRO=10 ; get value of the high precision time counter
SF_GET_SYS_DATE=29
SF_CURRENT_FOLDER=30
SSF_SET_CF=1 ; set current folder for the thread
SSF_GET_CF=2
SSF_ADD_SYS_FOLDER=3 ; install the add.system directory for the kernel
SF_GET_PIXEL_OWNER=34 ; get slot number of the screen pixel owner
SF_GET_PIXEL=35 ; read the screen pixel color
SF_GET_IMAGE=36 ; read the screen area
SF_MOUSE_GET=37
SSF_SCREEN_POSITION=0
SSF_WINDOW_POSITION=1
SSF_BUTTON=2 ; states of the mouse buttons
SSF_BUTTON_EXT=3 ; states and events of the mouse buttons
SSF_LOAD_CURSOR=4
SSF_SET_CURSOR=5
SSF_DEL_CURSOR=6
SSF_SCROLL_DATA=7
SF_DRAW_LINE=38
SF_BACKGROUND_GET=39
;SSF_SIZE_BG=1
;SSF_PIXEL_BG=2
;SSF_MODE_BG=4
SF_SET_EVENTS_MASK=40 ; turn on/off desired events
SF_PORT_IN_OUT=43 ; input/output to a port
SF_SET_PORTS=46 ; reserve/free a group of input/output ports
SF_DRAW_NUMBER=47 ; draw number to the window
SF_STYLE_SETTINGS=48
SSF_APPLY=0 ; apply screen settings
SSF_SET_BUTTON_STYLE=1
SSF_SET_COLORS=2
SSF_GET_COLORS=3 ; get standard window colors
SSF_GET_SKIN_HEIGHT=4
SSF_GET_SCREEN_AREA=5 ; get screen working area
SSF_SET_SCREEN_AREA=6
SSF_GET_SKIN_MARGINS=7
SSF_SET_SKIN=8
SSF_GET_FONT_SMOOTH=9
SSF_SET_FONT_SMOOTH=10
SSF_GET_FONT_SIZE=11
SSF_SET_FONT_SIZE=12
SF_APM=49
SF_SET_WINDOW_SHAPE=50
SF_CREATE_THREAD=51
SF_CLIPBOARD=54
SSF_GET_SLOT_COUNT=0 ; get the number of slots in the clipboard
SSF_READ_CB=1
SSF_WRITE_CB=2
SSF_DEL_SLOT=3 ; delete the last slot in the clipboard
SSF_UNLOCK_BUFFER=4 ; emergency buffer unlock
SF_SPEAKER_PLAY=55
SF_PCI_BIOS=57
SF_IPC=60 ; Inter Process Communication
SSF_SET_AREA=1 ; set area for IPC receiving
SSF_SEND_MESSAGE=2
SF_GET_GRAPHICAL_PARAMS=61
SSF_SCREEN_SIZE=1
SSF_BITS_PER_PIXEL=2
SSF_BYTES_PER_LINE=3
SF_PCI=62
SSF_GET_VERSION=0 ; get version of PCI-interface
SSF_GET_LAST_BUS=1 ; get number of the last PCI-bus
SSF_GET_ADRR_MODE=2 ; get addressing mode of the PCI configuration space
SSF_READ_BYTE=4
SSF_READ_WORD=5
SSF_READ_DWORD=6
SSF_WRITE_BYTE=8
SSF_WRITE_WORD=9
SSF_WRITE_DWORD=10
SF_BOARD=63
SSF_DEBUG_WRITE=1
SSF_DEBUG_READ=2
SF_MEMORY_RESIZE=64 ; resize total application memory
SF_PUT_IMAGE_EXT=65 ; draw image with palette to the window
SF_KEYBOARD=66
SSF_SET_INPUT_MODE=1
SSF_GET_INPUT_MODE=2
SSF_GET_CONTROL_KEYS=3; get status of control keys
SSF_SET_SYS_HOTKEY=4
SSF_DEL_SYS_HOTKEY=5
SSF_LOCK_INPUT=6 ; block normal input
SSF_UNLOCK_INPUT=7 ; restore normal input
SF_CHANGE_WINDOW=67 ; change position/sizes of the window
SF_SYS_MISC=68
SSF_GET_TASK_SWITCH_COUNT=0
SSF_SWITCH_TASK=1
SSF_PERFORMANCE=2
SSSF_ALLOW_RDPMC=0
SSSF_CACHE_STATUS=1
SSSF_CACHE_ON=2
SSSF_CACHE_OFF=3
SSF_READ_MSR=3
SSF_WRITE_MSR=4
SSF_HEAP_INIT=11
SSF_MEM_ALLOC=12
SSF_MEM_FREE=13
SSF_WAIT_SIGNAL=14 ; wait for signal from another program/driver
SSF_LOAD_DRIVER=16
SSF_CONTROL_DRIVER=17
SSF_LOAD_DLL=19
SSF_MEM_REALLOC=20
SSF_LOAD_DRIVER_PE=21
SSF_MEM_OPEN=22 ; open named memory area
SSF_MEM_CLOSE=23
SSF_SET_EXCEPTION_HANDLER=24
SSF_SET_EXCEPTION_STATE=25
SSF_MEM_FREE_EXT=26
SSF_LOAD_FILE=27
SF_DEBUG=69
SSF_SET_MESSAGE_AREA=0
SSF_GET_REGISTERS=1
SSF_SET_REGISTERS=2
SSF_DETACH=3
SSF_SUSPEND=4
SSF_RESUME=5
SSF_READ_MEMORY=6
SSF_WRITE_MEMORY=7
SSF_TERMINATE=8
SSF_DEFINE_BREAKPOINT=9
SF_FILE=70
SSF_READ_FILE=0
SSF_READ_FOLDER=1
SSF_CREATE_FILE=2
SSF_WRITE_FILE=3
SSF_SET_END=4
SSF_GET_INFO=5
SSF_SET_INFO=6
SSF_START_APP=7
SSF_DELETE=8
SSF_CREATE_FOLDER=9
SF_SET_CAPTION=71
SF_SEND_MESSAGE=72
SF_BLITTER=73
SF_NETWORK_DEVICE=74
SSF_DEVICE_COUNT=255 ; get number of active network devices
SSF_DEVICE_TYPE=0
SSF_DEVICE_NAME=1
SSF_RESET_DEVICE=2
SSF_STOP_DEVICE=3
SSF_DEVICE_POINTER=4
SSF_TX_PACKET_COUNT=6
SSF_RX_PACKET_COUNT=7
SSF_TX_BYTE_COUNT=8
SSF_RX_BYTE_COUNT=9
SSF_LINK_STATUS=10
SSF_TX_PACKET_ERROR_COUNT=11
SSF_TX_PACKET_DROP_COUNT=12
SSF_TX_PACKET_MISS_COUNT=13
SSF_RX_PACKET_ERROR_COUNT=14
SSF_RX_PACKET_DROP_COUNT=15
SSF_RX_PACKET_MISS_COUNT=16
SF_NETWORK_SOCKET=75
SSF_OPEN=0
SSF_CLOSE=1
SSF_BIND=2
SSF_LISTEN=3
SSF_CONNECT=4
SSF_ACCEPT=5
SSF_SEND=6
SSF_RECEIVE=7
SSF_SET_OPTIONS=8
SSF_GET_OPTIONS=9
SSF_SOCKET_PAIR=10
SF_NETWORK_PROTOCOL=76
SSF_ETHERNET_READ_MAC=0
SSF_IP4_PACKETS_SENT=10000h
SSF_IP4_PACKETS_RECEIVED=10001h
SSF_IP4_READ_IP=10002h
SSF_IP4_WRITE_IP=10003h
SSF_IP4_READ_DNS=10004h
SSF_IP4_WRITE_DNS=10005h
SSF_IP4_READ_SUBNET=10006h
SSF_IP4_WRITE_SUBNET=10007h
SSF_IP4_READ_GATEWAY=10008h
SSF_IP4_WRITE_GATEWAY=10009h
SSF_ICMP_PACKETS_SENT=20000h
SSF_ICMP_PACKETS_RECEIVED=20001h
SSF_ICMP_ECHO_REPLY=20003h
SSF_UDP_PACKETS_SENT=30000h
SSF_UDP_PACKETS_RECEIVED=30001h
SSF_TCP_PACKETS_SENT=40000h
SSF_TCP_PACKETS_RECEIVED=40001h
SSF_ARP_PACKETS_SENT=50000h
SSF_ARP_PACKETS_RECEIVED=50001h
SSF_ARP_GET_ENTRY_COUNT=50002h
SSF_ARP_READ_ENTRY=50003h
SSF_ARP_ADD_STATIC_ENTRY=50004h
SSF_ARP_DEL_ENTRY=50005h
SSF_ARP_SEND_ANNOUNCE=50006h
SSF_ARP_CONFLICTS_COUNT=50007h
SF_FUTEX=77
SSF_CREATE=0
SSF_DESTROY=1
SSF_WAIT=2
SSF_WAKE=3
; File system errors:
FSERR_SUCCESS=0
FSERR_UNSUPPORTED=2
FSERR_UNKNOWN=3
FSERR_FILE_NOT_FOUND=5
FSERR_END_OF_FILE=6
FSERR_INVALID_BUFFER=7
FSERR_DISK_FULL=8
FSERR_FAIL=9
FSERR_ACCESS_DENIED=10
FSERR_DEVICE_FAIL=11
FSERR_OUT_OF_MEMORY=12

View File

@@ -0,0 +1,4 @@
.tup
*.o
*.obj
*.kex

View File

@@ -8,6 +8,9 @@
#define NULL ((void*)0)
#endif
#define EXIT_SUCCESS 0 // Successful execution of a program
#define EXIT_FAILURE 1 // Unsuccessful execution of a program
#define min(a, b) ((a) < (b) ? (a) : (b))
#define max(a, b) ((a) > (b) ? (a) : (b))

View File

@@ -32,7 +32,6 @@ DLLAPI char* strrchr(const char* s, int c);
DLLAPI size_t strspn(const char* s1, const char* s2);
DLLAPI char* strstr(const char* s1, const char* s2);
DLLAPI char* strtok(char* s1, const char* s2);
DLLAPI char* strtok_r(char* s1, const char* s2, char** saveptr);
DLLAPI char* strerror(int errnum);
DLLAPI size_t strlen(const char* s);
DLLAPI char* strrev(char* str);

View File

@@ -120,7 +120,7 @@ typedef struct {
typedef union {
struct {
uint32_t cpu_usage; // CPU usage (cycles per secondes)
uint32_t cpu_usage; // CPU usage (cycles per secondgoes)
uint16_t pos_in_window_stack; // position of the thread window in the window stack
uint16_t slot_num_window_stack; // slot number in window stack
uint16_t __reserved1; // reserved
@@ -214,30 +214,6 @@ typedef struct {
uint32_t pitch;
} ksys_blitter_params_t;
typedef struct {
uint8_t a, b, c, d;
uint8_t debug_label;
uint8_t ABI_low;
uint8_t ABI_high;
uint32_t commit_id;
uint16_t reserved;
uint16_t commit_count;
} ksys_kernel_version_t;
typedef struct
{
uint32_t total_ram_pages;
uint32_t free_ram_pages;
uint32_t page_faults;
uint32_t kernel_heap_size;
uint32_t kernel_heap_free;
uint32_t kernel_heap_total_blocks;
uint32_t kernel_heap_free_blocks;
uint32_t kernel_heap_largest_free_block;
uint32_t kernel_heap_largest_alloc_block;
} ksys_memory_info_t;
#pragma pack(pop)
typedef rgb_t ksys_bitmap_t;
@@ -382,10 +358,10 @@ enum KSYS_SCANCODES {
KSYS_SCANCODE_EXT_INSERT = 82,
KSYS_SCANCODE_NUMPAD_COMMA = 83,
KSYS_SCANCODE_EXT_DELETE = 83,
// 84-86 doesn't exist
//84-86 doesn't exist
KSYS_SCANCODE_F11 = 87,
KSYS_SCANCODE_F12 = 88,
// 89,90 doesn't exist
//89,90 doesn't exist
KSYS_SCANCODE_EXT_LWIN = 91,
KSYS_SCANCODE_EXT_RWIN = 92,
KSYS_SCANCODE_EXT_MENU = 93,
@@ -783,40 +759,6 @@ KOSAPI void _ksys_shutdown(uint32_t shd_param)
asm_inline("int $0x40" ::"a"(18), "b"(9), "c"(shd_param));
}
/*====== Function 18, subfunction 10 - minimize current window. ========*/
KOSAPI void _ksys_minimize_current_windows()
{
asm_inline(
"int $0x40" ::"a"(18), "b"(10));
}
/*========== Function 18, subfunction 13 - get kernel version. =========*/
KOSAPI int _ksys_get_kernel_version(ksys_kernel_version_t* info)
{
int err;
asm_inline(
"int $0x40"
: "=a"(err)
: "a"(18), "b"(13), "c"(info)
: "memory");
return err;
}
/*========= Function 18, subfunction 15 - move mouse to center. ========*/
KOSAPI int _ksys_center_mouse()
{
int a;
asm_inline(
"int $0x40"
: "=a"(a)
: "a"(18), "b"(15));
return a;
}
/*========= Function 18, subfunction 16 - get size of free RAM. ========*/
KOSAPI size_t _ksys_get_ram_size(void)
@@ -875,19 +817,6 @@ KOSAPI uint32_t _ksys_set_mouse_settings(ksys_mouse_settings_t settings, uint32_
#define _ksys_set_mouse_pos(X, Y) _ksys_set_mouse_settings(KSYS_MOUSE_SET_POS, X * 65536 + Y)
/*===================== Function 18, subfunction 20 ====================*/
KOSAPI int _ksys_get_memory_info(ksys_memory_info_t* info)
{
int total;
asm_inline(
"int $0x40"
: "=a"(total)
: "a"(18), "b"(20), "c"(info)
: "memory");
return total;
}
/*===================== Function 18, subfunction 21 ====================*/
/*=====Get the slot number of the process / thread by identifier.. =====*/
@@ -901,185 +830,6 @@ KOSAPI int _ksys_get_thread_slot(int PID)
return val;
}
/*===================== Function 18, subfunction 22 ====================*/
typedef enum KSYS_WIN_REMOTE_CONTROL {
WIN_MINIMIZE_BY_SLOT = 0,
WIN_MINIMIZE_BY_PID = 1,
WIN_RESTORE_BY_SLOT = 2,
WIN_RESTORE_BY_PID = 3
} ksys_win_remote_control_t;
KOSAPI int _ksys_window_remote_control(ksys_win_remote_control_t type, uint32_t param)
{
int result;
asm_inline(
"int $0x40"
: "=a"(result)
: "a"(18), "b"(22), "c"(type), "d"(param));
return result;
}
/*===================== Function 18, subfunction 23 ====================*/
KOSAPI int _ksys_minimize_all_windows()
{
int count;
asm_inline(
"int $0x40"
: "=a"(count)
: "a"(18), "b"(23));
return count;
}
/*===================== Function 18, subfunction 24 ====================*/
KOSAPI void _ksys_set_draw_limits(unsigned int x, unsigned int y)
{
asm_inline(
"int $0x40" ::"a"(18), "b"(24), "c"(x), "d"(y));
}
/*===================== Function 18, subfunction 25 ====================*/
typedef enum KSYS_ZPOS {
KSYS_ZPOS_DESKTOP = -2,
KSYS_ZPOS_ALWAYS_BACK = -1,
KSYS_ZPOS_NORMAL = 0,
KSYS_ZPOS_ALWAYS_TOP = 1
} ksys_zpos_t;
/*=========== Function 18, subfunction 25, subsubfunction 1 ============*/
KOSAPI ksys_zpos_t _ksys_get_window_zposition(int32_t pid)
{
ksys_zpos_t result_eax;
asm_inline(
"int $0x40"
: "=a"(result_eax)
: "a"(18), "b"(25), "c"(1), "d"(pid));
return result_eax;
}
/*=========== Function 18, subfunction 25, subsubfunction 2 ============*/
KOSAPI int _ksys_set_window_zposition(int32_t pid, ksys_zpos_t position)
{
int err;
asm_inline(
"int $0x40"
: "=a"(err)
: "a"(18), "b"(25), "c"(2), "d"(pid), "S"(position));
return err;
}
/*==================== Function 21, subfunction 2 =====================*/
typedef enum KSYS_KEYBOARD_LAYOUT {
KSYS_KEYBOARD_LAYOUT_NORMAL = 1,
KSYS_KEYBOARD_LAYOUT_SHIFT = 2,
KSYS_KEYBOARD_LAYOUT_ALT = 3
} ksys_keyboard_layout_t;
KOSAPI int _ksys_set_keyboard_layout(ksys_keyboard_layout_t mode, char* table)
{
int err;
asm_inline(
"int $0x40"
: "=a"(err)
: "a"(21), "b"(2), "c"(mode), "d"(table));
return err;
}
typedef enum KSYS_LANG {
KSYS_LANG_ENG = 1,
KSYS_LANG_FI = 2,
KSYS_LANG_GER = 3,
KSYS_LANG_RU = 4
} ksys_lang_t;
KOSAPI int _ksys_set_keyboard_lang(ksys_lang_t lang)
{
int err;
asm_inline(
"int $0x40"
: "=a"(err)
: "a"(21), "b"(2), "c"(9), "d"(lang));
return err;
}
/*==================== Function 21, subfunction 5 =====================*/
KOSAPI int _ksys_set_lang(ksys_lang_t lang)
{
int err;
asm_inline(
"int $0x40"
: "=a"(err)
: "a"(21), "b"(5), "c"(lang));
return err;
}
/*==================== Function 21, subfunction 11 =====================*/
KOSAPI int _ksys_allow_HD(int param)
{
int err;
asm_inline(
"int $0x40"
: "=a"(err)
: "a"(21), "b"(11), "c"(param));
return err;
}
/*==================== Function 21, subfunction 12 =====================*/
KOSAPI int _ksys_allow_PCI(int param)
{
int err;
asm_inline(
"int $0x40"
: "=a"(err)
: "a"(21), "b"(12), "c"(param));
return err;
}
typedef enum KSYS_SET_TIME_ERR {
KSYS_SET_TIME_OK = 0,
KSYS_SET_TIME_WRONG_PARAM = 1,
KSYS_SET_TIME_CMOS = 2
} ksys_set_time_err;
/*============================ Function 22 ============================*/
KOSAPI ksys_set_time_err _ksys_set_time(ksys_time_t time)
{
ksys_set_time_err err;
asm_inline(
"int $0x40"
: "=a"(err)
: "a"(22), "b"(0), "c"(time));
}
KOSAPI ksys_set_time_err _ksys_set_date(ksys_date_t date)
{
ksys_set_time_err err;
asm_inline(
"int $0x40"
: "=a"(err)
: "a"(22), "b"(1), "c"(date));
}
/*============= Function 23 - wait for event with timeout. =============*/
KOSAPI uint32_t _ksys_wait_event_timeout(uint32_t timeout)
@@ -1092,37 +842,19 @@ KOSAPI uint32_t _ksys_wait_event_timeout(uint32_t timeout)
return val;
}
/*========= Function 26, subfunction 2 - get keyboard layout. ==========*/
/*=== Function 26, subfunction 2 - get keynoard layout. ==*/
KOSAPI uint32_t _ksys_keyboard_layout(ksys_keyboard_layout_t layout, unsigned char* buf)
typedef enum KSYS_KEYBOARD_LAYOUT {
KSYS_KEYBOARD_LAYOUT_NORMAL = 1,
KSYS_KEYBOARD_LAYOUT_SHIFT = 2,
KSYS_KEYBOARD_LAYOUT_ALT = 3
} ksys_keyboard_layout_t;
KOSAPI uint32_t _ksys_keyboard_layout(ksys_keyboard_layout_t layout, unsigned char *buf)
{
asm_inline("int $0x40" ::"a"(26), "b"(2), "c"(layout), "d"(buf) : "memory");
}
KOSAPI ksys_lang_t _ksys_get_keyboard_lang()
{
ksys_lang_t lang;
asm_inline(
"int $0x40"
: "=a"(lang)
: "a"(26), "b"(2), "c"(9));
return lang;
}
/*======= Function 26, subfunction 5 - get the system language. ========*/
KOSAPI ksys_lang_t _ksys_get_lang()
{
ksys_lang_t lang;
asm_inline(
"int $0x40"
: "=a"(lang)
: "a"(26), "b"(5));
return lang;
}
/*=== Function 26, subfunction 9 - get the value of the time counter. ==*/
KOSAPI uint32_t _ksys_get_tick_count(void)
@@ -1148,30 +880,6 @@ KOSAPI uint64_t _ksys_get_ns_count(void)
return val;
}
/*===================== Function 26, subfunction 11 ====================*/
KOSAPI int _ksys_get_HD()
{
int val;
asm_inline(
"int $0x40"
: "=a"(val)
: "a"(26), "b"(11));
return val;
}
/*===================== Function 26, subfunction 12 ====================*/
KOSAPI int _ksys_get_PCI()
{
int val;
asm_inline(
"int $0x40"
: "=a"(val)
: "a"(26), "b"(12));
return val;
}
/*=================== Function 29 - get system date. ===================*/
KOSAPI ksys_date_t _ksys_get_date(void)
@@ -1502,7 +1210,7 @@ KOSAPI void _ksys_debug_puts(const char* s)
KOSAPI void ksys_draw_bitmap_palette(void* bitmap, int x, int y, int w, int h, int bpp, void* palette, int offset)
{
asm_inline(
"pushl %%ebp\n\t" // save EBP register
"pushl %%ebp,\n\t" // save EBP register
"movl 0x24(%%ebp), %%ebp\n\t" // 0x24 - "offset" param
"int $0x40\n\t"
"popl %%ebp" // restore EBP register
@@ -1935,7 +1643,7 @@ KOSAPI void _ksys_set_window_title(const char* title)
/*============= Function 73 - blitter =============*/
KOSAPI void _ksys_blitter(uint32_t flags, ksys_blitter_params_t* params)
KOSAPI void _ksys_blitter(uint32_t flags, ksys_blitter_params_t *params)
{
int res;
asm_inline(

View File

@@ -27,7 +27,8 @@ BIN = \
libc_test.kex \
pipe.kex \
defgen.kex \
futex.kex
futex.kex \
malloc_test.kex
all: $(BIN)

View File

@@ -23,5 +23,6 @@ cp clayer/logo.png /tmp0/1/tcc_samples/logo.png
../tcc defgen.c -o /tmp0/1/tcc_samples/defgen
../tcc pipe.c -o /tmp0/1/tcc_samples/pipe
../tcc futex.c -o /tmp0/1/tcc_samples/futex
../tcc malloc_test.c -o /tmp0/1/tcc_samples/malloc_test
"/sys/File managers/Eolite" /tmp0/1/tcc_samples
exit

View File

@@ -0,0 +1,292 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include "../source/stdlib/_mem.h"
#define RUN_TEST(func) \
printf("---\tRUN TEST: %s\t---\n", #func); \
if (func()) { \
printf("[SUCCESS]\tTest %s is ok.\n\n", #func); \
} else { \
fprintf(stderr, "[FAIL]\tTest %s failed.\n\n", #func); \
exit(EXIT_FAILURE); \
}
// c between a and b
#define IN_RANGE(a, b, c, len) ((a > c && c > b) || ((a > c + len && c + len > b)))
bool test_malloc_basic_allocation()
{
void* ptr = malloc(sizeof(int));
if (ptr)
free(ptr);
return ptr;
}
bool test_malloc_zero_bytes()
{
return malloc(0) == NULL;
}
bool test_malloc_multiple_allocations()
{
void* ptr[512];
for (int i = 1; i < sizeof(ptr) / sizeof(*ptr); i++) {
ptr[i] = malloc(i);
if (ptr[i] == NULL) {
return false;
}
}
for (int i = 1; i < sizeof(ptr) / sizeof(*ptr); i++) {
for (int j = 1; j < sizeof(ptr) / sizeof(*ptr); j++) {
if (i != j) {
if (ptr[i] == ptr[j]) {
fprintf(stderr, "ptrs[%d] == ptrs[%d].\n", i, j);
return false;
} else if (IN_RANGE(
(char*)GET_MEM_NODE_HEADER(ptr[i]) + GET_MEM_NODE_HEADER(ptr[i])->size,
(char*)GET_MEM_NODE_HEADER(ptr[i]),
(char*)GET_MEM_NODE_HEADER(ptr[j]),
GET_MEM_NODE_HEADER(ptr[j])->size)) {
fprintf(stderr, "node %p in node %p", GET_MEM_NODE_HEADER(ptr[i]), GET_MEM_NODE_HEADER(ptr[j]));
// additional info, may help with debug
fprintf(stderr, "node %p\n size:%p\n free:%p\n next: %p\n last: %p\n", GET_MEM_NODE_HEADER(ptr[i]), GET_MEM_NODE_HEADER(ptr[i])->size, GET_MEM_NODE_HEADER(ptr[i])->free, GET_MEM_NODE_HEADER(ptr[i])->next, GET_MEM_NODE_HEADER(ptr[i])->last);
fprintf(stderr, "node %p\n size:%p\n free:%p\n next: %p\n last: %p\n", GET_MEM_NODE_HEADER(ptr[j]), GET_MEM_NODE_HEADER(ptr[j])->size, GET_MEM_NODE_HEADER(ptr[j])->free, GET_MEM_NODE_HEADER(ptr[j])->next, GET_MEM_NODE_HEADER(ptr[j])->last);
exit(EXIT_FAILURE);
}
}
}
}
for (int i = 1; i < sizeof(ptr) / sizeof(*ptr); i++) {
free(ptr[i]);
}
return true;
}
bool test_malloc_data_integrity()
{
const char* As = "AAA";
const char* Cs = "CCC";
char* A = (char*)malloc(10);
char* B = (char*)malloc(10);
char* C = (char*)malloc(10);
if (!A || !B || !C) {
printf("can't alloc\n");
free(A);
free(B);
free(C);
return false;
}
strcpy(A, As);
strcpy(C, Cs);
free(B);
if (strcmp(A, As) != 0) {
printf("A data is broken after free(B). A = '%s'\n", A);
free(A);
free(C);
return false;
}
if (strcmp(C, Cs) != 0) {
printf("C data is broken after free(B). C = '%s'\n", C);
free(A);
free(C);
return false;
}
free(A);
free(C);
return true;
}
bool test_malloc_large_allocation()
{
void* ptr = malloc(1024 * 1024 * 16); // alloc 16mb
if (ptr)
free(ptr);
return ptr;
}
bool test_malloc_allocation_and_free()
{
free(malloc(sizeof(int)));
return true;
}
void fill_buffer(void* ptr, size_t size, unsigned char pattern)
{
if (ptr) {
memset(ptr, pattern, size);
}
}
bool check_buffer(void* ptr, size_t size, unsigned char pattern)
{
if (!ptr) {
return false;
}
unsigned char* byte_ptr = (unsigned char*)ptr;
for (size_t i = 0; i < size; ++i) {
if (byte_ptr[i] != pattern) {
fprintf(stderr, "Error: Byte %u does not match pattern. Expected %02X, got %02X\n",
i, pattern, byte_ptr[i]);
return false;
}
}
return true;
}
bool test_realloc_basic_grow()
{
size_t old_size = 10;
size_t new_size = 20;
int* ptr = (int*)malloc(old_size * sizeof(int));
if (ptr == NULL) {
return false;
}
fill_buffer(ptr, old_size * sizeof(int), 0xAA);
int* new_ptr = (int*)realloc(ptr, new_size * sizeof(int));
if (new_ptr == NULL) {
free(ptr);
return false;
}
if (!check_buffer(new_ptr, old_size * sizeof(int), 0xAA)) {
free(new_ptr);
return false;
}
fill_buffer(new_ptr + old_size, (new_size - old_size) * sizeof(int), 0xBB);
if (!check_buffer(new_ptr + old_size, (new_size - old_size) * sizeof(int), 0xBB)) {
free(new_ptr);
return false;
}
free(new_ptr);
return true;
}
bool test_realloc_basic_shrink()
{
size_t old_size = 20;
size_t new_size = 10;
int* ptr = (int*)malloc(old_size * sizeof(int));
if (ptr == NULL) {
return false;
}
fill_buffer(ptr, old_size * sizeof(int), 0xCC);
int* new_ptr = (int*)realloc(ptr, new_size * sizeof(int));
if (new_ptr == NULL) {
free(ptr);
return false;
}
if (!check_buffer(new_ptr, new_size * sizeof(int), 0xCC)) {
free(new_ptr);
return false;
}
free(new_ptr);
return true;
}
bool test_realloc_same_size()
{
size_t size = 15;
int* ptr = (int*)malloc(size * sizeof(int));
if (ptr == NULL) {
return false;
}
fill_buffer(ptr, size * sizeof(int), 0xDD);
int* new_ptr = (int*)realloc(ptr, size * sizeof(int));
if (new_ptr == NULL) {
free(ptr);
return false;
}
if (!check_buffer(new_ptr, size * sizeof(int), 0xDD)) {
free(new_ptr);
return false;
}
free(new_ptr);
return true;
}
bool test_realloc_null_ptr()
{
size_t size = 25;
void* ptr = realloc(NULL, size);
if (ptr == NULL) {
return false;
}
fill_buffer(ptr, size, 0xEE);
if (!check_buffer(ptr, size, 0xEE)) {
free(ptr);
return false;
}
free(ptr);
return true;
}
bool test_realloc_to_zero_size()
{
size_t old_size = 30;
void* ptr = malloc(old_size);
if (ptr == NULL) {
return false;
}
fill_buffer(ptr, old_size, 0xFF);
void* new_ptr = realloc(ptr, 0);
if (new_ptr == NULL) {
printf("realloc(ptr, 0) return NULL.\n");
free(ptr);
} else {
printf("realloc(ptr, 0) return: %p.\n", new_ptr);
free(new_ptr);
}
return true;
}
int main()
{
RUN_TEST(test_malloc_basic_allocation);
RUN_TEST(test_malloc_zero_bytes);
RUN_TEST(test_malloc_multiple_allocations);
RUN_TEST(test_malloc_data_integrity);
RUN_TEST(test_malloc_large_allocation);
RUN_TEST(test_malloc_basic_allocation);
RUN_TEST(test_malloc_allocation_and_free);
RUN_TEST(test_realloc_basic_grow);
RUN_TEST(test_realloc_basic_shrink);
RUN_TEST(test_realloc_same_size);
RUN_TEST(test_realloc_null_ptr);
RUN_TEST(test_realloc_to_zero_size);
return 0;
}

View File

@@ -19,9 +19,6 @@ FILE* out = stdout;
FILE* out = stderr;
#endif
#define EXIT_SUCCESS 0
#define EXIT_FAILURE 1
#define fprintf fprintf
void show_help()

View File

@@ -203,7 +203,6 @@ ksys_dll_t EXPORTS[] = {
{ "strspn", &strspn },
{ "strstr", &strstr },
{ "strtok", &strtok },
{ "strtok_r", &strtok_r },
{ "strxfrm", &strxfrm },
{ "strpbrk", &strpbrk },
{ "__errno", &__errno },

View File

@@ -0,0 +1,87 @@
/*
* SPDX-License-Identifier: GPL-2.0-only
* Copyright (C) 2026 KolibriOS team
* Author: Yarin Egor<y.yarin@inbox.ru>
*/
#ifndef _LIBC_STDLIB__MEM_
#define _LIBC_STDLIB__MEM_
#include <stddef.h>
struct mem_node {
size_t free; // Amount of free space in this node. When equal to size, the entire node is free.
size_t size; // Total size of this memory node.
struct mem_node* last; // Pointer to the previous memory node in the linked list.
struct mem_node* next; // Pointer to the next memory node in the linked list.
};
struct mem_block {
size_t size; // Size of the allocated memory block.
size_t a; // align to 8bytes
};
// Size of the blocks allocated by `_ksys_alloc`
#define ALLOC_BLOCK_SIZE 4096
// Macro to get a pointer to the user data area from a mem_node pointer.
// This is done by adding the size of the mem_node structure to the mem_node pointer.
#define GET_MEM_NODE_PTR(node) (char*)((char*)(node) + sizeof(struct mem_node))
// Macro to check if a memory node is completely free.
#define MEM_NODE_IS_FREE(node) (node->free == node->size)
// Macro to get the amount of used memory in a memory node.
#define GET_MEM_NODE_USED_MEM(node) (node->size - node->free)
// Macro to get a pointer to the mem_node structure from a user data pointer.
// This is done by subtracting the size of the mem_node structure from the user data pointer.
#define GET_MEM_NODE_HEADER(ptr) ((struct mem_node*)(((char*)ptr) - sizeof(struct mem_node)))
// Macro to check if two adjacent memory nodes are in the same block.
// Checks if the end of the left node's allocated space is the start of the right node.
#define MEM_NODES_ARE_IN_ONE_BLOCK(left, right) (GET_MEM_NODE_PTR(left) + ((struct mem_node*)left)->size == (char*)right)
// Macro to merge two adjacent memory nodes.
#define CHECK_SIDE_IN_OTHER_BLOCK(node, side) (side == NULL || ((side != NULL) && !MEM_NODES_ARE_IN_ONE_BLOCK(node, side)))
// align a value to a specified alignment.
// Ensures that the allocated memory is aligned to a certain boundary
inline size_t __mem_align(size_t value, size_t align)
{
return ((value + align - 1) & ~(align - 1));
}
#define __mem_default_align(value) __mem_align(value, 8)
inline struct mem_node* __mem_MERGE_MEM_NODES(struct mem_node* base, struct mem_node* addition)
{
// addition is free && nodes base and addition both in one block, else merge is impossible
if (MEM_NODE_IS_FREE(addition) && MEM_NODES_ARE_IN_ONE_BLOCK(base, addition)) {
// just change size
const size_t s = addition->size + sizeof(struct mem_node);
base->size += s;
base->free += s;
// and delete addition from list
if (addition->next != NULL) {
addition->next->last = base;
base->next = addition->next;
} else {
base->next = NULL;
}
return base;
}
return NULL;
}
// Static pointer to the first memory node in the linked list.
// This acts as the head of the memory pool.
static struct mem_node* __mem_node = NULL;
static struct mem_node* __last_biggest_mem_node = NULL;
#endif // _LIBC_STDLIB_MEM_

View File

@@ -1,14 +1,10 @@
#include <errno.h>
#include <stdlib.h>
#include <sys/ksys.h>
void* calloc(size_t num, size_t size)
{
void* ptr = _ksys_alloc(num * size);
if (!ptr) {
__errno = ENOMEM;
return NULL;
void* ptr = malloc(num * size);
if (ptr) {
memset(ptr, 0, num * size);
}
memset(ptr, 0, num * size);
return ptr;
}

View File

@@ -1,7 +1,103 @@
/*
* SPDX-License-Identifier: GPL-2.0-only
* Copyright (C) 2026 KolibriOS team
* Author: Yarin Egor<y.yarin@inbox.ru>
*/
#include <stdlib.h>
#include <stdbool.h>
#include <sys/ksys.h>
#include "_mem.h"
void free(void* ptr)
{
_ksys_free(ptr);
}
// Handle NULL pointer.
if (ptr == NULL)
return;
// Get a pointer to the mem_node header from the user data pointer.
struct mem_node* node = GET_MEM_NODE_HEADER(ptr);
// Mark the memory node as free.
node->free = node->size;
if (__last_biggest_mem_node == node) {
if (node->last) {
__last_biggest_mem_node = node->last; // anyway node will be merged with next
// and last and last will have size = last + node + next(if its free too)
}
}
// Merge with the next node if possible.
if (node->next != NULL)
__mem_MERGE_MEM_NODES(node, node->next);
// Merge with the previous node if possible.
if (node->last != NULL)
node = __mem_MERGE_MEM_NODES(node->last, node);
if (node) {
// If the current node is not adjacent to either the next or previous node,
// it might be a separate block that can be freed.
if (MEM_NODE_IS_FREE(node) // check it because node maybe was merged with last
&& (node->last == NULL || !MEM_NODES_ARE_IN_ONE_BLOCK(node, node->next))
&& (node->next == NULL || !MEM_NODES_ARE_IN_ONE_BLOCK(node->last, node))) {
// Get a pointer to the mem_block header from the mem_node header.
struct mem_block* block = (struct mem_block*)(((char*)node) - sizeof(struct mem_block));
// Check if the block size matches the node size.
if (block->size == node->size + sizeof(struct mem_block) + sizeof(struct mem_node)) {
// Update the linked list pointers to remove the current node.
if (node->last != NULL)
node->last->next = node->next;
if (node->next != NULL)
node->next->last = node->last;
// Update the head of the linked list if necessary.
if (__mem_node == node) {
if (node->last != NULL) {
__mem_node = node->last;
} else if (node->next != NULL) {
__mem_node = node->next;
} else {
__mem_node = NULL;
}
}
struct mem_node* a = node->next;
struct mem_node* b = node->last;
if (!a && !b) {
__last_biggest_mem_node = NULL;
} else if (a && !b) {
__last_biggest_mem_node = a;
} else if (!a && b) {
__last_biggest_mem_node = b;
} else if (a && b) {
__last_biggest_mem_node = (a->free > b->free) ? a : b;
}
if (__last_biggest_mem_node == node) {
if (node->next && !(node->last)) {
__last_biggest_mem_node = node->next;
} else if (node->last && !(node->next)) {
__last_biggest_mem_node = node->last;
} else if (node->next && node->last) {
if (node->last->free > node->next->free) {
__last_biggest_mem_node = node->last;
} else {
__last_biggest_mem_node = node->next;
}
}
}
// Free the memory block using the ksys_free function.
_ksys_free(block);
}
}
}
}

View File

@@ -1,7 +1,134 @@
/*
* SPDX-License-Identifier: GPL-2.0-only
* Copyright (C) 2026 KolibriOS team
* Author: Yarin Egor<y.yarin@inbox.ru>
*/
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/ksys.h>
#include <stdbool.h>
#include "_mem.h"
static struct mem_node* __new_mem_node_from_exist(struct mem_node* current_node, size_t size, bool* from_empty_node)
{
struct mem_node* new_node = NULL;
// Check if the current node has enough free space for the requested size.
if (size + sizeof(struct mem_node) <= current_node->free) {
*from_empty_node = MEM_NODE_IS_FREE(current_node);
if (*from_empty_node) {
new_node = current_node;
} else {
// Calculate the used memory in current node
const size_t s = GET_MEM_NODE_USED_MEM(current_node);
// Create a new memory node after the current node's used space.
new_node = (struct mem_node*)(GET_MEM_NODE_PTR(current_node) + s);
// Update current node's size
current_node->size = s;
// Set the size of the new node.
// for new node give all free space in current node
new_node->size = current_node->free - sizeof(struct mem_node);
// Mark current node as used.
current_node->free = 0;
}
}
return new_node;
}
void* malloc(size_t size)
{
return _ksys_alloc(size);
}
char b[32];
// Handle zero-size allocation.
if (size == 0) {
return NULL;
}
// Align the size to 8 bytes.
size = __mem_default_align(size);
struct mem_node* current_node = __mem_node;
struct mem_node* new_node = NULL; // Pointer to the new node that will be created.
bool from_empty_node = false;
if (__last_biggest_mem_node != NULL)
new_node = __new_mem_node_from_exist(__last_biggest_mem_node, size, &from_empty_node); // try find free space in last created node
// if cant find in __last_biggest_mem_node
if (new_node == NULL) {
// Iterate through the linked list of memory nodes.
while (current_node != NULL) {
new_node = __new_mem_node_from_exist(current_node, size, &from_empty_node);
if (new_node)
break; // Found a suitable node, exit the loop.
current_node = current_node->next; // Move to the next node in the list.
}
}
// If no suitable node was found in the existing list:
if (new_node == NULL) {
// Calculate the size of the new block, including the mem_block header, mem_node header and alignment.
const size_t s = __mem_align(size + sizeof(struct mem_block) + sizeof(struct mem_node), ALLOC_BLOCK_SIZE);
// Allocate a new block of memory using the ksys_alloc function (presumably a kernel-level allocation function).
struct mem_block* block = (struct mem_block*)_ksys_alloc(s);
// Check if the allocation was successful.
if (block == NULL) {
__errno = ENOMEM; // Set the error number to indicate memory allocation failure.
return NULL; // Return NULL to indicate allocation failure.
}
block->size = s;
// Create a new memory node after the mem_block header.
new_node = (struct mem_node*)(((char*)block) + sizeof(struct mem_block));
// Set the size of the new node.
new_node->size = s - sizeof(struct mem_block) - sizeof(struct mem_node);
}
// Set the free space in the new node.
new_node->free = new_node->size - size;
if (!from_empty_node) {
// Set the last pointer of the new node to the current node.
new_node->last = current_node;
// Link the new node into the linked list.
if (current_node != NULL) {
// Set the next pointer of the current node to the new node.
new_node->next = current_node->next;
// Update the last pointer of the next node, if it exists.
if (current_node->next != NULL) {
current_node->next->last = new_node;
}
current_node->next = new_node;
} else {
// If the current node is NULL, the new node is the first node in the list.
new_node->next = NULL;
}
}
// If the linked list was empty, set the head to the new node.
if (__mem_node == NULL) {
__mem_node = new_node;
}
if (__last_biggest_mem_node == NULL || new_node->free > __last_biggest_mem_node->free) {
__last_biggest_mem_node = new_node;
}
// Return a pointer to the user data area of the new node.
return GET_MEM_NODE_PTR(new_node);
}
#undef __mem_align

View File

@@ -1,7 +1,82 @@
/*
* SPDX-License-Identifier: GPL-2.0-only
* Copyright (C) 2026 KolibriOS team
* Author: Yarin Egor<y.yarin@inbox.ru>
*/
#include <stdlib.h>
#include <string.h>
#include <sys/ksys.h>
#include "_mem.h"
// realloc mem. using if other ways not working
static void* fail_realloc(void* ptr, size_t newsize)
{
// Allocate a new block of memory with the new size.
void* new_ptr = malloc(newsize);
// If both the old pointer and the new pointer are not NULL:
if (ptr != NULL && new_ptr != NULL) {
// Copy the data from the old block to the new block.
memcpy(new_ptr, ptr, min(newsize, GET_MEM_NODE_USED_MEM(GET_MEM_NODE_HEADER(ptr))));
}
if (ptr) {
free(ptr); // Free the old block.
}
return new_ptr;
}
void* realloc(void* ptr, size_t newsize)
{
return _ksys_realloc(ptr, newsize);
}
void* new_ptr = NULL;
struct mem_node* node = NULL;
if (ptr && newsize) {
// Get a pointer to the mem_node header from the user data pointer.
node = GET_MEM_NODE_HEADER(ptr);
newsize = __mem_default_align(newsize);
if (node->size >= newsize) { // current node have enough mem
// it work always if newsize is smaller
// Update the free space in the current node.
node->free = node->size - newsize;
// Return the original pointer.
new_ptr = ptr;
} else if (node->last && MEM_NODE_IS_FREE(node->last) && node->size + node->last->size >= newsize) {
// So what happens here is that the node merges with the last node if their volume is sufficient.
// And a reallock is called in the hopes that the first condition will be met.
// if merge failed realloc anyway return pointer, but it will got from `fail_realloc`
struct mem_node* l = node->last;
l = __mem_MERGE_MEM_NODES(l, node);
if (l) {
memmove(GET_MEM_NODE_PTR(l), ptr, GET_MEM_NODE_USED_MEM(node));
new_ptr = realloc(GET_MEM_NODE_PTR(l), newsize);
}
}
}
if (new_ptr == NULL) {
// Allocate a new block of memory with the new size.
new_ptr = malloc(newsize);
// If both the old pointer and the new pointer are not NULL:
if (ptr != NULL && new_ptr != NULL) {
// Copy the data from the old block to the new block.
memcpy(new_ptr, ptr, min(newsize, GET_MEM_NODE_USED_MEM(GET_MEM_NODE_HEADER(ptr))));
}
if (ptr) {
free(ptr); // Free the old block.
}
}
// Return the new pointer.
return new_ptr;
}

View File

@@ -1,12 +1,14 @@
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
#include <string.h>
char* strtok_r(char* s, const char* delim, char** last)
char* strtok(char* s, const char* delim)
{
char *spanp, *tok;
const char* spanp;
int c, sc;
char* tok;
static char* last;
if (s == NULL && (s = *last) == NULL)
if (s == NULL && (s = last) == NULL)
return (NULL);
/*
@@ -14,13 +16,13 @@ char* strtok_r(char* s, const char* delim, char** last)
*/
cont:
c = *s++;
for (spanp = (char*)delim; (sc = *spanp++) != 0;) {
for (spanp = delim; (sc = *spanp++) != 0;) {
if (c == sc)
goto cont;
}
if (c == 0) { /* no non-delimiter characters */
*last = NULL;
last = NULL;
return (NULL);
}
tok = s - 1;
@@ -31,24 +33,17 @@ cont:
*/
for (;;) {
c = *s++;
spanp = (char*)delim;
spanp = delim;
do {
if ((sc = *spanp++) == c) {
if (c == 0)
s = NULL;
else
s[-1] = '\0';
*last = s;
s[-1] = 0;
last = s;
return (tok);
}
} while (sc != 0);
}
/* NOTREACHED */
}
char *strtok(char *s, const char *delim)
{
static char *last;
return (strtok_r(s, delim, &last));
}

View File

@@ -0,0 +1,19 @@
Copyright (c) 2017 rxi
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,99 @@
# microtar
A lightweight tar library written in ANSI C
## Basic Usage
The library consists of `microtar.c` and `microtar.h`. These two files can be
dropped into an existing project and compiled along with it.
#### Reading
```c
mtar_t tar;
mtar_header_t h;
char *p;
/* Open archive for reading */
mtar_open(&tar, "test.tar", "r");
/* Print all file names and sizes */
while ( (mtar_read_header(&tar, &h)) != MTAR_ENULLRECORD ) {
printf("%s (%d bytes)\n", h.name, h.size);
mtar_next(&tar);
}
/* Load and print contents of file "test.txt" */
mtar_find(&tar, "test.txt", &h);
p = calloc(1, h.size + 1);
mtar_read_data(&tar, p, h.size);
printf("%s", p);
free(p);
/* Close archive */
mtar_close(&tar);
```
#### Writing
```c
mtar_t tar;
const char *str1 = "Hello world";
const char *str2 = "Goodbye world";
/* Open archive for writing */
mtar_open(&tar, "test.tar", "w");
/* Write strings to files `test1.txt` and `test2.txt` */
mtar_write_file_header(&tar, "test1.txt", strlen(str1));
mtar_write_data(&tar, str1, strlen(str1));
mtar_write_file_header(&tar, "test2.txt", strlen(str2));
mtar_write_data(&tar, str2, strlen(str2));
/* Finalize -- this needs to be the last thing done before closing */
mtar_finalize(&tar);
/* Close archive */
mtar_close(&tar);
```
## Error handling
All functions which return an `int` will return `MTAR_ESUCCESS` if the operation
is successful. If an error occurs an error value less-than-zero will be
returned; this value can be passed to the function `mtar_strerror()` to get its
corresponding error string.
## Wrapping a stream
If you want to read or write from something other than a file, the `mtar_t`
struct can be manually initialized with your own callback functions and a
`stream` pointer.
All callback functions are passed a pointer to the `mtar_t` struct as their
first argument. They should return `MTAR_ESUCCESS` if the operation succeeds
without an error, or an integer below zero if an error occurs.
After the `stream` field has been set, all required callbacks have been set and
all unused fields have been zeroset the `mtar_t` struct can be safely used with
the microtar functions. `mtar_open` *should not* be called if the `mtar_t`
struct was initialized manually.
#### Reading
The following callbacks should be set for reading an archive from a stream:
Name | Arguments | Description
--------|------------------------------------------|---------------------------
`read` | `mtar_t *tar, void *data, unsigned size` | Read data from the stream
`seek` | `mtar_t *tar, unsigned pos` | Set the position indicator
`close` | `mtar_t *tar` | Close the stream
#### Writing
The following callbacks should be set for writing an archive to a stream:
Name | Arguments | Description
--------|------------------------------------------------|---------------------
`write` | `mtar_t *tar, const void *data, unsigned size` | Write data to the stream
## License
This library is free software; you can redistribute it and/or modify it under
the terms of the MIT license. See [LICENSE](LICENSE) for details.

View File

@@ -0,0 +1,8 @@
if tup.getconfig("NO_GCC") ~= "" then return end
HELPERDIR = (tup.getconfig("HELPERDIR") == "") and "../../../" or tup.getconfig("HELPERDIR")
tup.include(HELPERDIR .. "/use_gcc.lua")
CFLAGS = " -c -w -nostdinc -DGNUC -DMTAR_OBJ -Os -fno-common -fno-builtin -fno-leading-underscore -fno-pie"
INCLUDES = " -I../include -I../../ktcc/trunk/libc.obj/include"
tup.rule("microtar.c", "kos32-gcc" .. CFLAGS .. INCLUDES .. " -o %o %f " .. tup.getconfig("KPACK_CMD"), "mtar.obj")

View File

@@ -0,0 +1,78 @@
format binary as "kex"
use32
org 0x0
db 'MENUET01'
dd 0x01
dd START
dd IM_END
dd MEM
dd MEM
dd 0
dd 0
include '../../../../macros.inc'
include '../../../../proc32.inc'
include '../../../../KOSfuncs.inc'
include '../../../../dll.inc'
include '../mtar.inc'
;include '../../../../debug-fdo.inc'
;__DEBUG__ = 1
;__DEBUG_LEVEL__ = 2
START:
stdcall dll.Load, @IMPORT ; Имортироуем функции из mtar.obj
test eax, eax
jnz exit
ccall [mtar_init] ; Инициализируем библиотеку (на самом деле подгружается libc.obj
ccall [mtar_open], tar, tar_fname, tar_fmode ; Открываем для чтения файл 'test.tar'
; DEBUGF 2, "%d", eax
print_next:
ccall [mtar_read_header], tar, header ; Читаем заголовок
cmp eax, MTAR_ENULLRECORD ; Если заголовок не был прочитан (return -7) выходим из цикла
je exit
ccall [printf], format_str, header+mtar_header_t.name, dword[header+mtar_header_t.size] ; Выводим в консоль имя файла и размер в байтах
ccall [mtar_next], tar ; Переходим к следующему заголовку
jmp print_next ; прыгаем в начало цикла
exit:
ccall [mtar_close], tar ; Закрываем 'test.tar'
mcall SF_TERMINATE_PROCESS ; Выходим из программы
; data
tar_fname db 'test.tar', 0
tar_fmode db 'r', 0
tar rb sizeof.mtar_t
header rb sizeof.mtar_header_t
format_str db '%-10s (%-4d bytes)', 0x0A,0
align 4
@IMPORT:
library mtar, 'mtar.obj', libc , 'libc.obj'
import mtar, \
mtar_init, 'mtar_init', \
mtar_open, 'mtar_open', \
mtar_next, 'mtar_next', \
mtar_strerror, 'mtar_strerror', \
mtar_read_header, 'mtar_read_header', \
mtar_write_data, 'mtar_write_data', \
mtar_finalize, 'mtar_finalize', \
mtar_close, 'mtar_close'
import libc, \
printf, 'printf'
IM_END:
align 4
rb 4096 ; stack
MEM:

View File

@@ -0,0 +1,70 @@
format binary as "kex"
use32
org 0x0
db 'MENUET01'
dd 0x01
dd START
dd IM_END
dd MEM
dd MEM
dd 0
dd 0
include '../../../../macros.inc'
include '../../../../proc32.inc'
include '../../../../KOSfuncs.inc'
include '../../../../dll.inc'
include '../mtar.inc'
;include '../../../../debug-fdo.inc'
;__DEBUG__ = 1
;__DEBUG_LEVEL__ = 2
START:
stdcall dll.Load, @IMPORT ; Имортироуем функции из mtar.obj
test eax, eax
jnz exit
ccall [mtar_init] ; Инициализируем библиотеку (на самом деле подгружается libc.obj
ccall [mtar_open], tar, tar_fname, tar_fmode ; Создаём новый файл 'test.tar'
ccall [mtar_write_file_header], tar, test1_txt , str1_len ; Создаём внутри 'test.tar' пустрой файл 'test1.txt'
ccall [mtar_write_data], tar, str1, str1_len ; Записываем данныев в этот файл
ccall [mtar_finalize], tar ; Указываем что больше с tar работать не будем
ccall [mtar_close], tar ; Закрываем 'test.tar'
exit:
mcall SF_TERMINATE_PROCESS ; Выходим из программы
; data
str1 db 'Hello world!', 0
str1_len = $ - str1
str2 db 'Goodbye world!', 0
tar_fname db 'test.tar', 0
tar_fmode db 'w', 0
test1_txt db 'test1.txt', 0
tar rb 32
align 4
@IMPORT:
library mtar, 'mtar.obj'
import mtar, \
mtar_init, 'mtar_init', \
mtar_open, 'mtar_open', \
mtar_write_file_header, 'mtar_write_file_header', \
mtar_write_data, 'mtar_write_data', \
mtar_finalize, 'mtar_finalize', \
mtar_close, 'mtar_close'
IM_END:
align 4
rb 4096 ; stack
MEM:

View File

@@ -0,0 +1,450 @@
/*
* Copyright (c) 2017 rxi
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <sys/ksys.h>
#include "microtar.h"
typedef struct {
char name[100];
char mode[8];
char owner[8];
char group[8];
char size[12];
char mtime[12];
char checksum[8];
char type;
char linkname[100];
char _padding[255];
} mtar_raw_header_t;
static void * mtar_memset( void * s, int c, size_t n ){
unsigned char * p = ( unsigned char * ) s;
while ( n-- ){
*p++ = ( unsigned char ) c;
}
return s;
}
#ifdef MTAR_OBJ
// All pointers was changed for compatible to latest version tcc and the libc.obj headers
size_t (*_fread)(void *restrict, size_t size, size_t count, FILE *restrict)=NULL;
size_t (*_fwrite)(const void *restrict, size_t size, size_t count, FILE *restrict)=NULL;
int (*_fclose)(FILE *)=NULL;
FILE* (*_fopen)(const char *restrict, const char *restrict)=NULL;
int (*_fseek)(FILE *, long, int)=NULL;
long (*_ftell)(FILE *)=NULL;
int (*_sprintf)(char* buffer, const char* format, ...)=NULL;
int (*_sscanf)(const char*, const char *restrict, ...)=NULL;
int (*_strcmp)(const char * s1, const char* s2)=NULL;
char* (*_strchr)(const char* s, int c)=NULL;
char* (*_strcpy)(char* s1, const char* s2)=NULL;
#endif
static unsigned round_up(unsigned n, unsigned incr) {
return n + (incr - n % incr) % incr;
}
static unsigned checksum(const mtar_raw_header_t* rh) {
unsigned i;
unsigned char *p = (unsigned char*) rh;
unsigned res = 256;
for (i = 0; i < offsetof(mtar_raw_header_t, checksum); i++) {
res += p[i];
}
for (i = offsetof(mtar_raw_header_t, type); i < sizeof(*rh); i++) {
res += p[i];
}
return res;
}
static int tread(mtar_t *tar, void *data, unsigned size) {
int err = tar->read(tar, data, size);
tar->pos += size;
return err;
}
static int twrite(mtar_t *tar, const void *data, unsigned size) {
int err = tar->write(tar, data, size);
tar->pos += size;
return err;
}
static int write_null_bytes(mtar_t *tar, int n) {
int i, err;
char nul = '\0';
for (i = 0; i < n; i++) {
err = twrite(tar, &nul, 1);
if (err) {
return err;
}
}
return MTAR_ESUCCESS;
}
static int raw_to_header(mtar_header_t *h, const mtar_raw_header_t *rh) {
unsigned chksum1, chksum2;
/* If the checksum starts with a null byte we assume the record is NULL */
if (*rh->checksum == '\0') {
return MTAR_ENULLRECORD;
}
/* Build and compare checksum */
chksum1 = checksum(rh);
_sscanf(rh->checksum, "%o", &chksum2);
if (chksum1 != chksum2) {
return MTAR_EBADCHKSUM;
}
/* Load raw header into header */
_sscanf(rh->mode, "%o", &h->mode);
_sscanf(rh->owner, "%o", &h->owner);
_sscanf(rh->size, "%o", &h->size);
_sscanf(rh->mtime, "%o", &h->mtime);
h->type = rh->type;
_strcpy(h->name, rh->name);
_strcpy(h->linkname, rh->linkname);
return MTAR_ESUCCESS;
}
static int header_to_raw(mtar_raw_header_t *rh, const mtar_header_t *h) {
unsigned chksum;
/* Load header into raw header */
mtar_memset(rh, 0, sizeof(*rh));
_sprintf(rh->mode, "%o", h->mode);
_sprintf(rh->owner, "%o", h->owner);
_sprintf(rh->size, "%o", h->size);
_sprintf(rh->mtime, "%o", h->mtime);
rh->type = h->type ? h->type : MTAR_TREG;
_strcpy(rh->name, h->name);
_strcpy(rh->linkname, h->linkname);
/* Calculate and write checksum */
chksum = checksum(rh);
_sprintf(rh->checksum, "%06o", chksum);
rh->checksum[7] = ' ';
return MTAR_ESUCCESS;
}
const char* mtar_strerror(int err) {
switch (err) {
case MTAR_ESUCCESS : return "success";
case MTAR_EFAILURE : return "failure";
case MTAR_EOPENFAIL : return "could not open";
case MTAR_EREADFAIL : return "could not read";
case MTAR_EWRITEFAIL : return "could not write";
case MTAR_ESEEKFAIL : return "could not seek";
case MTAR_EBADCHKSUM : return "bad checksum";
case MTAR_ENULLRECORD : return "null record";
case MTAR_ENOTFOUND : return "file not found";
}
return "unknown error";
}
static int file_write(mtar_t *tar, const void *data, unsigned size) {
unsigned res = _fwrite(data, 1, size, tar->stream);
return (res == size) ? MTAR_ESUCCESS : MTAR_EWRITEFAIL;
}
static int file_read(mtar_t *tar, void *data, unsigned size) {
unsigned res = _fread(data, 1, size, tar->stream);
return (res == size) ? MTAR_ESUCCESS : MTAR_EREADFAIL;
}
static int file_seek(mtar_t *tar, unsigned offset) {
int res = _fseek(tar->stream, offset, SEEK_SET);
return (res == 0) ? MTAR_ESUCCESS : MTAR_ESEEKFAIL;
}
static int file_close(mtar_t *tar) {
_fclose(tar->stream);
return MTAR_ESUCCESS;
}
int mtar_open(mtar_t *tar, const char *filename, const char *mode) {
int err;
mtar_header_t h;
/* Init tar struct and functions */
mtar_memset(tar, 0, sizeof(*tar));
tar->write = file_write;
tar->read = file_read;
tar->seek = file_seek;
tar->close = file_close;
/* Assure mode is always binary */
if ( _strchr(mode, 'r') ) mode = "rb";
if ( _strchr(mode, 'w') ) mode = "wb";
if ( _strchr(mode, 'a') ) mode = "ab";
/* Open file */
tar->stream = _fopen(filename, mode);
if (!tar->stream) {
return MTAR_EOPENFAIL;
}
/* Read first header to check it is valid if mode is `r` */
if (*mode == 'r') {
err = mtar_read_header(tar, &h);
if (err != MTAR_ESUCCESS) {
mtar_close(tar);
return err;
}
}
/* Return ok */
return MTAR_ESUCCESS;
}
int mtar_close(mtar_t *tar) {
return tar->close(tar);
}
int mtar_seek(mtar_t *tar, unsigned pos) {
int err = tar->seek(tar, pos);
tar->pos = pos;
return err;
}
int mtar_rewind(mtar_t *tar) {
tar->remaining_data = 0;
tar->last_header = 0;
return mtar_seek(tar, 0);
}
int mtar_next(mtar_t *tar) {
int err, n;
mtar_header_t h;
/* Load header */
err = mtar_read_header(tar, &h);
if (err) {
return err;
}
/* Seek to next record */
n = round_up(h.size, 512) + sizeof(mtar_raw_header_t);
return mtar_seek(tar, tar->pos + n);
}
int mtar_find(mtar_t *tar, const char *name, mtar_header_t *h) {
int err;
mtar_header_t header;
/* Start at beginning */
err = mtar_rewind(tar);
if (err) {
return err;
}
/* Iterate all files until we hit an error or find the file */
while ( (err = mtar_read_header(tar, &header)) == MTAR_ESUCCESS ) {
if ( !_strcmp(header.name, name) ) {
if (h) {
*h = header;
}
return MTAR_ESUCCESS;
}
mtar_next(tar);
}
/* Return error */
if (err == MTAR_ENULLRECORD) {
err = MTAR_ENOTFOUND;
}
return err;
}
int mtar_read_header(mtar_t *tar, mtar_header_t *h) {
int err;
mtar_raw_header_t rh;
/* Save header position */
tar->last_header = tar->pos;
/* Read raw header */
err = tread(tar, &rh, sizeof(rh));
if (err) {
return err;
}
/* Seek back to start of header */
err = mtar_seek(tar, tar->last_header);
if (err) {
return err;
}
/* Load raw header into header struct and return */
return raw_to_header(h, &rh);
}
int mtar_read_data(mtar_t *tar, void *ptr, unsigned size) {
int err;
/* If we have no remaining data then this is the first read, we get the size,
* set the remaining data and seek to the beginning of the data */
if (tar->remaining_data == 0) {
mtar_header_t h;
/* Read header */
err = mtar_read_header(tar, &h);
if (err) {
return err;
}
/* Seek past header and init remaining data */
err = mtar_seek(tar, tar->pos + sizeof(mtar_raw_header_t));
if (err) {
return err;
}
tar->remaining_data = h.size;
}
/* Read data */
err = tread(tar, ptr, size);
if (err) {
return err;
}
tar->remaining_data -= size;
/* If there is no remaining data we've finished reading and seek back to the
* header */
if (tar->remaining_data == 0) {
return mtar_seek(tar, tar->last_header);
}
return MTAR_ESUCCESS;
}
int mtar_write_header(mtar_t *tar, const mtar_header_t *h) {
mtar_raw_header_t rh;
/* Build raw header and write */
header_to_raw(&rh, h);
tar->remaining_data = h->size;
return twrite(tar, &rh, sizeof(rh));
}
int mtar_write_file_header(mtar_t *tar, const char *name, unsigned size) {
mtar_header_t h;
/* Build header */
mtar_memset(&h, 0, sizeof(h));
_strcpy(h.name, name);
h.size = size;
h.type = MTAR_TREG;
h.mode = 0664;
/* Write header */
return mtar_write_header(tar, &h);
}
int mtar_write_dir_header(mtar_t *tar, const char *name) {
mtar_header_t h;
/* Build header */
mtar_memset(&h, 0, sizeof(h));
_strcpy(h.name, name);
h.type = MTAR_TDIR;
h.mode = 0775;
/* Write header */
return mtar_write_header(tar, &h);
}
int mtar_write_data(mtar_t *tar, const void *data, unsigned size) {
int err;
/* Write data */
err = twrite(tar, data, size);
if (err) {
return err;
}
tar->remaining_data -= size;
/* Write padding if we've written all the data for this file */
if (tar->remaining_data == 0) {
return write_null_bytes(tar, round_up(tar->pos, 512) - tar->pos);
}
return MTAR_ESUCCESS;
}
int mtar_finalize(mtar_t *tar) {
/* Write two NULL records */
return write_null_bytes(tar, sizeof(mtar_raw_header_t) * 2);
}
/* Load libc.obj */
#ifdef MTAR_OBJ
#include <sys/ksys.h>
int mtar_init(){
ksys_dll_t *libc = _ksys_dlopen("/sys/lib/libc.obj");
if(!libc){
_ksys_debug_puts("mtar.obj: libc.obj not loaded!");
return 1;
}
_fread = _ksys_dlsym(libc, "fread");
_fwrite = _ksys_dlsym(libc, "fwrite");
_fclose = _ksys_dlsym(libc, "fclose");
_fopen = _ksys_dlsym(libc, "fopen");
_fseek = _ksys_dlsym(libc, "fseek");
_ftell = _ksys_dlsym(libc, "ftell");
_sprintf= _ksys_dlsym(libc, "sprintf");
_sscanf = _ksys_dlsym(libc, "sscanf");
_strcmp = _ksys_dlsym(libc, "strcmp");
_strchr = _ksys_dlsym(libc, "strchr");
_strcpy = _ksys_dlsym(libc, "strcpy");
return 0;
}
ksys_dll_t EXPORTS[] = {
{"mtar_init", mtar_init},
{"mtar_open", mtar_open},
{"mtar_close", mtar_close},
{"mtar_seek", mtar_seek},
{"mtar_rewind", mtar_rewind},
{"mtar_next", mtar_next},
{"mtar_find", mtar_find},
{"mtar_read_header", mtar_read_header},
{"mtar_read_data", mtar_read_data},
{"mtar_write_header", mtar_write_header},
{"mtar_write_file_header", mtar_write_file_header},
{"mtar_write_dir_header", mtar_write_dir_header},
{"mtar_write_data",mtar_write_data},
{"mtar_finalize", mtar_finalize},
{"mtar_strerror", mtar_strerror},
NULL
};
#endif

View File

@@ -0,0 +1,91 @@
/**
* Copyright (c) 2017 rxi
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MIT license. See `microtar.c` for details.
*/
#ifndef MICROTAR_H
#define MICROTAR_H
#ifdef __cplusplus
extern "C"
{
#endif
#include <stdio.h>
#include <stdlib.h>
#define MTAR_VERSION "0.1.0"
enum {
MTAR_ESUCCESS = 0,
MTAR_EFAILURE = -1,
MTAR_EOPENFAIL = -2,
MTAR_EREADFAIL = -3,
MTAR_EWRITEFAIL = -4,
MTAR_ESEEKFAIL = -5,
MTAR_EBADCHKSUM = -6,
MTAR_ENULLRECORD = -7,
MTAR_ENOTFOUND = -8
};
enum {
MTAR_TREG = '0',
MTAR_TLNK = '1',
MTAR_TSYM = '2',
MTAR_TCHR = '3',
MTAR_TBLK = '4',
MTAR_TDIR = '5',
MTAR_TFIFO = '6'
};
typedef struct {
unsigned mode;
unsigned owner;
unsigned size;
unsigned mtime;
unsigned type;
char name[100];
char linkname[100];
} mtar_header_t;
typedef struct mtar_t mtar_t;
#pragma pack(push,1)
struct mtar_t {
int (*read)(mtar_t *tar, void *data, unsigned size);
int (*write)(mtar_t *tar, const void *data, unsigned size);
int (*seek)(mtar_t *tar, unsigned pos);
int (*close)(mtar_t *tar);
void *stream;
unsigned pos;
unsigned remaining_data;
unsigned last_header;
};
#pragma pack(pop)
const char* mtar_strerror(int err);
int mtar_open(mtar_t *tar, const char *filename, const char *mode);
int mtar_close(mtar_t *tar);
int mtar_seek(mtar_t *tar, unsigned pos);
int mtar_rewind(mtar_t *tar);
int mtar_next(mtar_t *tar);
int mtar_find(mtar_t *tar, const char *name, mtar_header_t *h);
int mtar_read_header(mtar_t *tar, mtar_header_t *h);
int mtar_read_data(mtar_t *tar, void *ptr, unsigned size);
int mtar_write_header(mtar_t *tar, const mtar_header_t *h);
int mtar_write_file_header(mtar_t *tar, const char *name, unsigned size);
int mtar_write_dir_header(mtar_t *tar, const char *name);
int mtar_write_data(mtar_t *tar, const void *data, unsigned size);
int mtar_finalize(mtar_t *tar);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,38 @@
MTAR_ESUCCESS = 0
MTAR_EFAILURE = -1
MTAR_EOPENFAIL = -2
MTAR_EREADFAIL = -3
MTAR_EWRITEFAIL = -4
MTAR_ESEEKFAIL = -5
MTAR_EBADCHKSUM = -6
MTAR_ENULLRECORD = -7
MTAR_ENOTFOUND = -8
MTAR_TREG = '0'
MTAR_TLNK = '1'
MTAR_TSYM = '2'
MTAR_TCHR = '3'
MTAR_TBLK = '4'
MTAR_TDIR = '5'
MTAR_TFIFO = '6'
struct mtar_header_t
mode dd ?
owner dd ?
size dd ?
mtime dd ?
type dd ?
name rb 100
linkname rb 100
ends
struct mtar_t
read_func dd ?
write_func dd ?
seek_func dd ?
close_func dd ?
stream dd ?
pos dd ?
remaining_data dd ?
last_header dd ?
ends

View File

@@ -1,5 +1,7 @@
if tup.getconfig("NO_FASM") ~= "" then return end
HELPERDIR = (tup.getconfig("HELPERDIR") == "") and "../.." or tup.getconfig("HELPERDIR")
tup.include(HELPERDIR .. "/use_fasm.lua")
tup.rule("keymap.asm", FASM .. " %f %o", "piano.map")
tup.rule("piano.asm", FASM .. " -dlang=" .. tup.getconfig("LANG") .. " %f %o" .. tup.getconfig("KPACK_CMD"), "%B")
add_include(tup.getvariantdir())
tup.rule("echo lang fix " .. ((tup.getconfig("LANG") == "") and "en_US" or tup.getconfig("LANG")) .. " > %o", {"lang.inc"})
tup.rule({"piano.asm", extra_inputs = {"lang.inc"}}, FASM .. " %f %o " .. tup.getconfig("KPACK_CMD"), "piano")

View File

@@ -0,0 +1,4 @@
@echo lang fix en_US >lang.inc
@fasm piano.asm piano
@erase lang.inc
@pause

View File

@@ -1,76 +0,0 @@
; SPDX-License-Identifier: GPL-2.0-only
;
; Piano - Default Keymap (256 bytes)
; Copyright (C) 2025 KolibriOS team
; ====================================================================
format binary as ""
org 0
; ====================================================================
BAD_NOTE = 0xFF
; ====================================================================
keymap:
db BAD_NOTE ; 0x00
db BAD_NOTE ; 0x01
db 0x21 ; 0x02 '1' -> note 0x31
db 0x22 ; 0x03 '2' -> note 0x32
db 0x23 ; 0x04 '3' -> note 0x33
db 0x24 ; 0x05 '4' -> note 0x34
db 0x25 ; 0x06 '5' -> note 0x35
db 0x26 ; 0x07 '6' -> note 0x36
db 0x27 ; 0x08 '7' -> note 0x37
db 0x28 ; 0x09 '8' -> note 0x38
db 0x29 ; 0x0A '9' -> note 0x39
db 0x2A ; 0x0B '0' -> note 0x3A
db 0x2B ; 0x0C '-' -> note 0x3B
db 0x2C ; 0x0D '=' -> note 0x3C
db 0x1C ; 0x0E Backspace -> note 0x2C
db BAD_NOTE ; 0x0F
db 0x31 ; 0x10 'q' -> note 0x41
db 0x32 ; 0x11 'w' -> note 0x42
db 0x33 ; 0x12 'e' -> note 0x43
db 0x34 ; 0x13 'r' -> note 0x44
db 0x35 ; 0x14 't' -> note 0x45
db 0x36 ; 0x15 'y' -> note 0x46
db 0x37 ; 0x16 'u' -> note 0x47
db 0x38 ; 0x17 'i' -> note 0x48
db 0x39 ; 0x18 'o' -> note 0x49
db 0x3A ; 0x19 'p' -> note 0x4A
db 0x3B ; 0x1A '[' -> note 0x4B
db 0x3C ; 0x1B ']' -> note 0x4C
db 0x0C ; 0x1C Enter -> note 0x1C
db BAD_NOTE ; 0x1D
db 0x01 ; 0x1E 'a' -> note 0x11
db 0x02 ; 0x1F 's' -> note 0x12
db 0x03 ; 0x20 'd' -> note 0x13
db 0x04 ; 0x21 'f' -> note 0x14
db 0x05 ; 0x22 'g' -> note 0x15
db 0x06 ; 0x23 'h' -> note 0x16
db 0x07 ; 0x24 'j' -> note 0x17
db 0x08 ; 0x25 'k' -> note 0x18
db 0x09 ; 0x26 'l' -> note 0x19
db 0x0A ; 0x27 ';' -> note 0x1A
db 0x0B ; 0x28 ''' -> note 0x1B
db BAD_NOTE ; 0x29
db BAD_NOTE ; 0x2A
db 0x1B ; 0x2B '\' -> note 0x2B
db 0x11 ; 0x2C 'z' -> note 0x21
db 0x12 ; 0x2D 'x' -> note 0x22
db 0x13 ; 0x2E 'c' -> note 0x23
db 0x14 ; 0x2F 'v' -> note 0x24
db 0x15 ; 0x30 'b' -> note 0x25
db 0x16 ; 0x31 'n' -> note 0x26
db 0x17 ; 0x32 'm' -> note 0x27
db 0x18 ; 0x33 ',' -> note 0x28
db 0x19 ; 0x34 '.' -> note 0x29
db 0x1A ; 0x35 '/' -> note 0x2A
times 256-($-keymap) db BAD_NOTE

File diff suppressed because it is too large Load Diff

View File

@@ -86,7 +86,7 @@ commands: ; all commands must be in uppercase
dd 'CWD', login_first, login_first, login_first, cmdCWD
dd 'XCWD', login_first, login_first, login_first, cmdCWD
dd 'DELE', login_first, login_first, login_first, cmdDELE
dd 'HELP', login_first, login_first, login_first, cmdHELP
; dd 'HELP', login_first, login_first, login_first, cmd_HELP
dd 'LIST', login_first, login_first, login_first, cmdLIST
; dd 'MDTM', login_first, login_first, login_first, cmd_MDTM
; dd 'MKD', login_first, login_first, login_first, cmd_MKD
@@ -1247,68 +1247,6 @@ cmdTYPE:
sendFTP "200 Command ok"
ret
;------------------------------------------------
; "HELP"
;
; Provide help information.
;
;------------------------------------------------
align 4
cmdHELP:
lea edi, [ebp + thread_data.buffer]
mov eax, '214 '
stosd
mov eax, 'Help'
stosd
mov ax, ': '
stosw
mov esi, commands ; pointer to commands table
.next_command:
cmp byte [esi], 0 ; end of table?
je .list_done
; Copy command name (4 bytes), skip null bytes
mov ecx, 4
.copy_name:
mov al, [esi]
test al, al
jz .skip_null
stosb
.skip_null:
inc esi
loop .copy_name
; Add space after command name
mov al, ' '
stosb
; Skip the four address pointers (16 bytes)
add esi, 16
jmp .next_command
.list_done:
; Remove trailing space (if any)
dec edi
; Add CRLF
mov ax, 0x0a0d ; \r\n
stosw
xor al, al ; null terminator
stosb
; Calculate length
lea edx, [ebp + thread_data.buffer]
sub edi, edx
; Send response
mcall send, [ebp + thread_data.socketnum], edx, edi
; Also log to console
invoke con_write_asciiz, edx
ret
;------------------------------------------------
; "USER"
;

View File

@@ -0,0 +1,16 @@
KTCC_DIR=../../develop/ktcc/trunk
NAME=gamehack
KTCC=$(KTCC_DIR)/bin/kos32-tcc
KPACK=kpack
SRC=gh_shell.c
CFLAGS=-I $(KTCC_DIR)/libc/include
LIBS = -lck
all:
$(KTCC) $(CFLAGS) $(SRC) $(LIBS) -o $(NAME)
$(KPACK) $(NAME)
clean:
rm $(NAME)

View File

@@ -0,0 +1,72 @@
int PID=-1;
int kdebugger_write(unsigned ID, unsigned n, unsigned addr, unsigned* buff)
{
int num;
__asm__ __volatile__(
"int $0x40"
:"=a"(num)
:"a"(69), "b"(7), "c"(ID), "d"(n),"S"(addr),"D"(buff)
);
return num;
}
int kdebugger_read(unsigned ID, unsigned n, unsigned addr, unsigned* buff)
{
int num;
__asm__ __volatile__(
"int $0x40"
:"=a"(num)
:"a"(69), "b"(6), "c"(ID), "d"(n),"S"(addr),"D"(buff)
);
return num;
}
void kdebugger_pause(unsigned ID)
{
__asm__ __volatile__(
"int $0x40"
::"a"(69), "b"(4), "c"(ID)
);
}
void kdebugger_play(unsigned ID)
{
__asm__ __volatile__(
"int $0x40"
::"a"(69), "b"(5), "c"(ID)
);
}
void kdebugger_disconnect(unsigned ID)
{
__asm__ __volatile__(
"int $0x40"
::"a"(69), "b"(3), "c"(ID)
);
}
int load_game(char *app_name, char *args)
{
#pragma pack(push, 1)
struct file_op_t
{
unsigned fn;
unsigned flags;
char* args;
unsigned res1, res2;
char zero;
char* app_name __attribute__((packed));
} file_op;
#pragma pack(pop)
memset(&file_op, 0, sizeof(file_op));
file_op.fn = 7;
file_op.flags = 1;
file_op.args = args;
file_op.app_name = app_name;
register int val;
asm volatile ("int $0x40":"=a"(val):"a"(70), "b"(&file_op));
return val;
}

View File

@@ -0,0 +1,96 @@
#include <conio.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <kos32sys1.h>
#include "gh_core.c"
#define CMD_LEN 255
#define TITLE "GameHack 1.0 ALPHA "
char cmd_line[CMD_LEN];
char cmd_line_tmp[CMD_LEN];
void notify_show(char *text)
{
start_app("/sys/@notify", text);
}
void cmd_processing()
{
strcpy(cmd_line_tmp, cmd_line);
char *cmd = strtok(cmd_line_tmp, " \n");
if(!strcmp(cmd, "pause")){
kdebugger_pause(PID);
}
else if(!strcmp(cmd, "play")){
kdebugger_play(PID);
}
else if(!strcmp(cmd, "exit")){
exit(0);
}
else if(!strcmp(cmd, "write")){
unsigned addr=0;
int val =0;
if(sscanf(cmd_line, "%s %x %d %d",cmd_line, &addr, &val, &val)==3){
if(kdebugger_write(PID, sizeof(int), addr, &val)==-1){
puts("Memory write error!");
}
}else{
puts("Invalid arguments!");
}
}
else if(!strcmp(cmd, "read")){
unsigned addr=0;
int val =0;
if(sscanf(cmd_line, "%s %x %x",cmd_line, &addr, &addr)==2){
if(kdebugger_read(PID, sizeof(int), addr, &val)==-1){
puts("Memory read error!");
}
printf("0x%.8X: %d\n", addr, val);
}else{
puts("Invalid arguments!");
}
}
else if(!strcmp(cmd, "help"))
{
puts("Commands:");
puts(" write [addres] [value] - Write DWORD value by address.");
puts(" read [addres] [value] - Read DWORD value by address.");
puts(" pause - Suspend the game (process)." );
puts(" play - Resume running the game(process).");
puts(" find [value] - Search for DWORD value in memory(VIP).");
}
else if(!strcmp(cmd, "find"))
{
puts("Not yet implemented ...");
}
else if(cmd != NULL){
puts("Unknown command!");
}
}
int main(int argc, char* argv[])
{
if (argc!=2 ){
notify_show("'No game selected!' -E");
exit(0);
}
con_init_console_dll();
con_set_title(TITLE);
PID = load_game(argv[1], NULL);
PID = 2;
if(PID<0){
notify_show("'Game not loaded!' -E");
exit(0);
}
kdebugger_play(PID);
while (1){
printf("GameHack> ");
con_gets(cmd_line, CMD_LEN);
cmd_processing();
memset(cmd_line, '\n', CMD_LEN);
}
}

18
programs/other/TEAtool/Makefile Executable file
View File

@@ -0,0 +1,18 @@
KTCC_DIR=../../develop/ktcc/trunk
NAME=teatool
KTCC=$(KTCC_DIR)/bin/kos32-tcc
KPACK=kpack
SRC=teatool.c
CFLAGS=-nostdinc -I $(KTCC_DIR)/libc/include
LFLAGS=-nostdlib -L $(KTCC_DIR)/bin/lib $(KTCC_DIR)/bin/lib/start.o
LIBS = -lck
all:
$(KTCC) $(CFLAGS) $(LFLAGS) $(SRC) $(LIBS) -o $(NAME)
$(KPACK) $(NAME)
clean:
rm $(NAME)

View File

@@ -0,0 +1,49 @@
#include <stdio.h>
#define INVALID_ARG "Invalid arguments! Use the help: -h!\n"
#define KEY_RECORD_IN_FILE "The key is recorded in file: %s\n"
#define INCORRECT_FILE "Error! Incorrect file:'%s'\n"
#define NO_KEY_OR_KEYFILE "No key or key file!\n"
#define INVALID_KEY_FORMAT "Invalid key format!\n"
#define FILE_NOT_FOUND "File '%s' not found!\n"
#define DATA_DECRYPT "Data from file: %s successfully DECRYPTED to file: %s\n"
#define DATA_ENCRYPT "Data from file: %s successfully ENCRYPTED to file: %s\n"
#define FILE_DECRYPTION "File decryption...\n"
#define FILE_ENCRYPTION "File encryption...\n"
#define RECORD_DECRYPT_DATA "Record decryped data...\n"
#define LOAD_IN_RAM "Loading a '%s' file in RAM...\n"
#define RECORD_ENCRYPT_DATA "Record encryped data...\n"
#define MEMORY_ERROR "To big file, not enough memory! Use normal mode."
void show_help()
{
puts("Usage: \nTEAtool [infile] [outfile] [arguments]\n");
puts("Arguments:");
puts("-e [mode] Encrypt file in 'speed' or 'normal' mode.");
puts("-d [mode] Decrypt file in 'speed' or 'normal' mode.");
puts(" In 'speed' mode, file is entirely loaded into RAM.");
puts(" In 'normal' mode, file is loaded with parts in RAM.");
puts("-k [key] 128bit-key in hex format.");
puts("-K [keyfile] Use key from file.");
puts("-r [key] [keyfile].key Key entry to key file.");
puts("-h This reference");
puts("-a About the program \n");
}
void show_about()
{
puts("\n");
puts("-----------TEAtool-ENG-----------\n");
printf(" ) ( Version: \n");
printf(" ( ) ) 1.8-stable \n");
printf(" ) ( ( \n");
printf(" _______)_ Author: \n");
printf(" .-'---------| turbocat2001 \n");
printf("( C|/////////| \n");
printf(" '-./////////| Tester: rgimad \n");
printf(" '_________' \n");
printf(" '-------'' License: GPLv3 \n\n");
printf(" Powered by: \n");
printf(" Tiny Encryption Algorithm. \n\n");
}

View File

@@ -0,0 +1,9 @@
Encrypting the "in.file" file with the "FFAB1100C176001F1ADDB8E792001EA5" key in normal mode:
# teatool in.file out.file -k FFAB1100C176001F1ADDB8E792001EA5 -e normal
Encrypting the "in.file" file with the key-file "my.key" in speed mode:*
# teatool in.file out.file -K my.key -e speed
Writing the "FFAB1100C176001F1ADDB8E792001EA5" key to the key-file "my.key"*
# teatool -r FFAB1100C176001F1ADDB8E792001EA5 my

View File

@@ -0,0 +1,62 @@
#include <stdint.h>
void TEA_encrypt (uint32_t block[2], uint32_t key[4])
{
/* set up */
uint32_t v0 = block[0];
uint32_t v1 = block[1];
uint32_t sum = 0;
uint32_t i;
/* a key schedule constant */
uint32_t delta = 0x9e3779b9;
/* cache key */
uint32_t k0 = key[0];
uint32_t k1 = key[1];
uint32_t k2 = key[2];
uint32_t k3 = key[3];
/* basic cycle start */
for (i = 0; i < 32; i++)
{
sum += delta;
v0 += ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);
v1 += ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);
}
/* end cycle */
block[0] = v0;
block[1] = v1;
}
void TEA_decrypt (uint32_t* block, uint32_t* key)
{
/* set up */
uint32_t v0 = block[0];
uint32_t v1 = block[1];
uint32_t sum = 0xC6EF3720;
uint32_t i;
/* a key schedule constant */
uint32_t delta = 0x9e3779b9;
/* cache key */
uint32_t k0 = key[0];
uint32_t k1 = key[1];
uint32_t k2 = key[2];
uint32_t k3 = key[3];
/* basic cycle start */
for (i = 0; i < 32; i++)
{
v1 -= ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);
v0 -= ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);
sum -= delta;
}
/* end cycle */
block[0] = v0;
block[1] = v1;
}

303
programs/other/TEAtool/teatool.c Executable file
View File

@@ -0,0 +1,303 @@
/* Copyright (C) 2019-2021 Logaev Maxim (turbocat2001), GPLv2 */
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <conio.h>
#include "lang_en.c"
#include "tea.c"
#define ENCRYPT 1
#define DECRYPT 2
typedef unsigned char flag;
uint32_t key[4];
long size_orig_file(FILE* file)
{
fseek(file, 0, SEEK_END);
long size = ftell(file);
fseek(file, 0, SEEK_SET);
return size;
}
long size_xcrypt_file(FILE* file)
{
fseek(file, 0, SEEK_END);
long size = ftell(file);
fseek(file, 0, SEEK_SET);
if(size%8==0) {
return size;
}else{
return (size/8+1)*8;
}
}
void xcrypt_file_speed(char *in_file, char* out_file, char arg)
{
FILE *input, *output;
if((input = fopen(in_file,"rb"))==NULL){
printf(FILE_NOT_FOUND, in_file);
exit(1);
}
output = fopen(out_file,"wb");
long size_f=size_xcrypt_file(input);
uint8_t size_diff;
size_diff=(uint8_t)(size_f-size_orig_file(input));
uint32_t *buff;
buff=malloc(size_f);
if(!buff) {
puts(MEMORY_ERROR);
exit(-1);
}
if(arg==ENCRYPT){
printf(LOAD_IN_RAM,in_file);
fread(buff, 1,size_f, input);
printf(FILE_ENCRYPTION);
for(long i=0; i<(size_f/4); i=i+2)
{
TEA_encrypt(buff+i,key);
}
printf(RECORD_ENCRYPT_DATA);
fwrite(&size_diff,1, 1, output);
fwrite(buff,1,size_f, output);
fclose(input);
fclose(output);
printf(DATA_ENCRYPT,in_file,out_file);
exit(0);
}
else if(arg==DECRYPT){
long size_f=size_orig_file(input);
printf(LOAD_IN_RAM,in_file);
fread(&size_diff,1,1,input);
fread(buff,1,size_f-1, input);
printf(FILE_DECRYPTION);
for(long i=0; i<size_f/4; i=i+2)
{
TEA_decrypt(buff+i,key);
}
printf(RECORD_DECRYPT_DATA);
fwrite(buff,1,size_f-size_diff-1, output);
fclose(input);
fclose(output);
printf(DATA_DECRYPT,in_file,out_file);
exit(0);
}
}
void xcrypt_file(char *in_file, char* out_file, char arg)
{
uint32_t temp_block[2];
FILE *input, *output;
if((input = fopen(in_file,"rb"))==NULL){
printf(FILE_NOT_FOUND, in_file);
exit(1);
}
output = fopen(out_file,"wb");
register long size_f=size_xcrypt_file(input);
uint8_t size_diff=(uint8_t)(size_f-size_orig_file(input));
if(arg==ENCRYPT){
fwrite(&size_diff,1,1,output);
printf(FILE_ENCRYPTION);
while(!feof(input))
{
memset(temp_block, 0x00, 2);
fread(temp_block, sizeof(uint32_t), 2, input) ;
TEA_encrypt(temp_block,key);
fwrite(temp_block, sizeof(uint32_t),2, output);
}
fclose(input);
fclose(output);
printf(DATA_ENCRYPT,in_file,out_file);
exit(0);
}
else if(arg==DECRYPT){
size_f = size_orig_file(input);
fread(&size_diff,1,1,input);
size_f=size_f-size_diff-1;
printf(FILE_DECRYPTION);
while(!feof(input))
{
fread(temp_block, sizeof(uint32_t), 2, input);
TEA_decrypt(temp_block,key);
if(size_f>=8){
fwrite(temp_block,sizeof(uint32_t),2,output);
}else{
fwrite(temp_block,1,size_f,output);
}
size_f=size_f-8;
if(size_f<0){
size_f=0;
}
}
fclose(input);
fclose(output);
printf(DATA_DECRYPT,in_file,out_file);
exit(0);
}
}
void str_to_strkey(char *str, char str_key[4][9])
{
int count=0;
for(int i=0; i<4; i++)
{
int j=0;
while (j<8)
{
str_key[i][j]=str[count];
count++;
j++;
}
}
}
int valid_key(char *str)
{
int count=0;
char hex[]={"abcdefABCDEF0123456789"};
for(int i=0; i<32; i++)
{
if(strchr(hex,str[i])!=NULL){
count++;
}
}
if(count==32){return 1;}
else{ return 0;}
}
void key_con_read(char *str)
{
char str_key[4][9];
if(valid_key(str)&&(strlen(str)==32))
{
for(int i=0; i<4; i++){
str_to_strkey(str, str_key);
key[i]=(uint32_t)strtol(str_key[i],NULL,16);
}
}else{
printf(INVALID_KEY_FORMAT);
exit(-1);
}
}
void key_file_read(char *key_file)
{
FILE *keyfile;
if((keyfile = fopen(key_file,"rb"))==NULL){
printf(FILE_NOT_FOUND, key_file);
exit(-1);
}
if(size_orig_file(keyfile)==16) {
fread(key,sizeof(uint32_t),4, keyfile);
}else{
printf(INVALID_KEY_FORMAT);
exit(-1);
}
fclose(keyfile);
}
void findopt(int argc, char *argv[],char *in_file, char *out_file)
{
char found=0;
for(int j=3; j<argc; j++)
{
if(!strcmp(argv[j],"-k")){
found=1;
key_con_read(argv[j+1]);
break;
}
else if(!strcmp(argv[j],"-K")){
found=1;
key_file_read(argv[j+1]);
break;
}
}
if(!found){
printf(NO_KEY_OR_KEYFILE);
exit(-1);
}
for(int i=3;i<argc; i++){
if(!strcmp(argv[i],"-e"))
{
if(!strcmp(argv[i+1],"normal")){xcrypt_file(in_file, out_file, ENCRYPT);}
if(!strcmp(argv[i+1],"speed")){xcrypt_file_speed(in_file, out_file, ENCRYPT);}
}
if(!strcmp(argv[i],"-d"))
{
if(!strcmp(argv[i+1],"normal")){xcrypt_file(in_file, out_file, DECRYPT);}
if(!strcmp(argv[i+1],"speed")){xcrypt_file_speed(in_file, out_file, DECRYPT);}
}
}
printf(INVALID_ARG);
exit(0);
}
void key_write_in_file(char *keyfilename)
{
FILE *keyfile;
if((keyfile = fopen(strcat(keyfilename, ".key"), "wb"))==NULL){
printf(INCORRECT_FILE, keyfilename);
exit(-1);
}
fwrite(key,sizeof(uint8_t), 16, keyfile);
printf(KEY_RECORD_IN_FILE, keyfilename);
fclose(keyfile);
exit(0);
}
int main(int argc, char **argv)
{
con_init_console_dll();
con_set_title("TEAtool\0");
if(argc==7){
findopt(argc,argv, argv[1],argv[2]);
}
else if(argc==2 && !strcmp(argv[1],"-a")){
show_about();
exit(0);
}
else if(argc==2 && !strcmp(argv[1],"-h")){
show_help();
exit(0);
}
else if(argc==4 && !strcmp(argv[1],"-r")){
key_con_read(argv[2]);
key_write_in_file(argv[3]);
}
else{
printf(INVALID_ARG);
exit(0);
}
return 0;
}

View File

@@ -1,9 +0,0 @@
if tup.getconfig("NO_OB07") ~= "" then return end
if tup.getconfig("HELPERDIR") == ""
then
HELPERDIR = "../../"
end
tup.include(HELPERDIR .. "/use_ob07.lua")
build_ob07({"SRC/FB2READ.ob07"}, "fb2read", "-upper");

View File

@@ -1,7 +1,6 @@
OB07 = tup.getcwd() .. "/develop/oberon07/compiler"
OB07_FLAGS = "-stk 1 -nochk a"
function build_ob07(input, output, extra_flags)
extra_flags = extra_flags or ""
tup.rule(input, OB07 .. " %f kosexe -out %o " .. OB07_FLAGS .. " " .. extra_flags .. " " .. tup.getconfig("KPACK_CMD"), output)
end
OB07 = tup.getcwd() .. "/develop/oberon07/compiler"
OB07_FLAGS = "-stk 1 -nochk a"
function build_ob07(input, output)
tup.rule(input, OB07 .. " %f kosexe -out %o " .. OB07_FLAGS .. " " .. tup.getconfig("KPACK_CMD"), output)
end