Compare commits
31
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ef1eceaa6c | ||
|
|
3f3770fc57 | ||
|
|
9fe9b676c1 | ||
|
|
3110deedd5 | ||
|
|
0486f294ce | ||
|
|
bd071d588b | ||
|
|
9ec66b0eba | ||
|
|
95bcf78537 | ||
|
|
6f3cae4e0c | ||
|
|
b59e371c0e | ||
|
|
939505198f | ||
|
|
75cb80fd33 | ||
|
|
6ba901606d | ||
|
|
b1d329da2a | ||
|
|
df9946fe80 | ||
|
|
e3d744f1b5 | ||
|
|
8ca3758efb | ||
|
|
02916ed0ee | ||
|
|
873d4de379 | ||
|
|
b2f9cc9809 | ||
|
|
298155191d | ||
|
|
49b8cdcd54 | ||
|
|
c121db7a88 | ||
|
|
9527a0f3d1 | ||
|
|
1e05d19c4c | ||
|
|
ecdebae231 | ||
|
|
0150178c90 | ||
|
|
3caf2a7a72 | ||
|
|
019f2629dc | ||
|
|
63ee53f4a3 | ||
|
|
7c8eba2ed4 |
No files matched your search
@@ -54,3 +54,27 @@
|
||||
src: "{{ stable_artifact_path }}/"
|
||||
dest: "{{ storage_path }}/../"
|
||||
mode: preserve
|
||||
|
||||
# older builds shrink to compressed images and lose their unpacked tree; the newest few keep both
|
||||
- name: Looking for zstd on the storage server
|
||||
ansible.builtin.shell: command -v zstd
|
||||
register: zstd_present
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
|
||||
- name: Requiring zstd for compaction
|
||||
ansible.builtin.assert:
|
||||
that: zstd_present.rc == 0
|
||||
fail_msg: >-
|
||||
zstd is not installed on the storage server, so older builds cannot
|
||||
be compacted. Install it and re-run this build.
|
||||
|
||||
- name: Compacting older builds
|
||||
ansible.builtin.script:
|
||||
cmd: >-
|
||||
../../utils/compact-builds.sh
|
||||
{{ storage_path | quote }}
|
||||
{{ compact_keep | default(5) | int }}
|
||||
{{ compact_max | default(10) | int }}
|
||||
register: compaction
|
||||
changed_when: "'compacted 0 of' not in compaction.stdout"
|
||||
Executable
+74
@@ -0,0 +1,74 @@
|
||||
#!/bin/bash
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
# SPDX-FileCopyrightText: 2026 KolibriOS team
|
||||
|
||||
# Shrink older builds on the storage server: compress their images and drop
|
||||
# their unpacked tree, which is rebuildable from the commit. sha256sums.txt
|
||||
# keeps naming the bare images, so a compacted build has to be decompressed
|
||||
# before it can be verified.
|
||||
#
|
||||
# Layout: <root>/<version>/<lang>/kolibrios-<descr>-<lang>.{img,iso,raw} -> .zst
|
||||
# <root>/<version>/<lang>/data/ -> removed
|
||||
#
|
||||
# Usage: compact-builds.sh <storage-root> [keep] [max-per-run]
|
||||
# DRY_RUN=1 walks the same selection and changes nothing
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
root=${1:?storage root required}
|
||||
# the build just published is always among these, so an upload in flight is safe
|
||||
keep=${2:-5}
|
||||
# a build is hundreds of MiB to re-compress: cap the first pass over the backlog
|
||||
max=${3:-10}
|
||||
dry=${DRY_RUN:-0}
|
||||
verb=compacted
|
||||
[ "$dry" = 1 ] && verb="would compact"
|
||||
|
||||
# --rm drops the source only once the archive is written; the box serves the
|
||||
# site over NFS, so compaction yields to it
|
||||
compress_image() {
|
||||
nice -n 10 ionice -c3 zstd -12 -T1 -q --rm "$1"
|
||||
}
|
||||
export -f compress_image
|
||||
|
||||
leftovers() {
|
||||
local build=$1
|
||||
find "$build" -mindepth 2 -maxdepth 2 \
|
||||
\( -type d -name data \
|
||||
-o -type f \( -name '*.img' -o -name '*.iso' -o -name '*.raw' \) \) \
|
||||
-print -quit
|
||||
}
|
||||
|
||||
compacted=0
|
||||
pending=0
|
||||
|
||||
while IFS= read -r version; do
|
||||
dir="$root/$version"
|
||||
[ -n "$(leftovers "$dir")" ] || continue
|
||||
|
||||
pending=$((pending + 1))
|
||||
[ "$compacted" -lt "$max" ] || continue
|
||||
|
||||
if [ "$dry" = 1 ]; then
|
||||
compacted=$((compacted + 1))
|
||||
echo "$verb $version"
|
||||
continue
|
||||
fi
|
||||
|
||||
# a build holds nine images: one per core, each zstd kept to one thread so
|
||||
# the two levels of parallelism do not fight. Archive before dropping the
|
||||
# tree, so a failure here leaves the build merely uncompacted and the next
|
||||
# run picks it up again
|
||||
find "$dir" -mindepth 2 -maxdepth 2 -type f \
|
||||
\( -name '*.img' -o -name '*.iso' -o -name '*.raw' \) -print0 \
|
||||
| xargs -0 -r -P "$(nproc)" -I{} bash -c 'compress_image "$@"' _ {}
|
||||
|
||||
find "$dir" -mindepth 2 -maxdepth 2 -type d -name data -exec rm -rf {} +
|
||||
|
||||
compacted=$((compacted + 1))
|
||||
echo "$verb $version"
|
||||
# <tag>-<commit count>-g<sha>: order by the count, never by mtime
|
||||
done < <(find "$root" -mindepth 1 -maxdepth 1 -type d -name '*-*-g*' -printf '%f\n' \
|
||||
| sort -t- -k2,2n | head -n "-$keep")
|
||||
|
||||
echo "$verb $compacted of $pending older build(s), $((pending - compacted)) left for the next run"
|
||||
@@ -128,7 +128,8 @@ jobs:
|
||||
fi
|
||||
|
||||
# cache restore resets ctimes; realign tup DB to skip a full rebuild,
|
||||
# but keep files changed since the cache's commit dirty so tup rebuilds them
|
||||
# but keep files changed since the cache's commit dirty so tup rebuilds them.
|
||||
# A submodule bump diffs as a bare gitlink, so expand it to its whole subtree
|
||||
- name: Sync tup DB with filesystem ctime
|
||||
if: steps.check-tup-cache.outputs.cache_restored == 'true'
|
||||
run: |
|
||||
@@ -136,6 +137,10 @@ jobs:
|
||||
BASE=$(cat .tup/build-commit 2>/dev/null || true)
|
||||
if [ -n "$BASE" ] && git cat-file -e "${BASE}^{commit}" 2>/dev/null; then
|
||||
git -c core.quotePath=false diff --name-only "$BASE" HEAD > "$DIRTY"
|
||||
git diff --raw "$BASE" HEAD | awk '$2 == "160000" { print $NF }' |
|
||||
while read -r sub; do
|
||||
git -C "$sub" -c core.quotePath=false ls-files | sed "s|^|$sub/|"
|
||||
done >> "$DIRTY"
|
||||
echo "Cache built at $BASE; $(wc -l < "$DIRTY") changed files kept dirty"
|
||||
python3 .gitea/utils/sync-tup-ctime.py .tup/db "$DIRTY"
|
||||
else
|
||||
|
||||
@@ -34,10 +34,11 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
token: ${{ secrets.BOT_TOKEN }}
|
||||
|
||||
- name: Bump ${{ matrix.name }} and open PR
|
||||
env:
|
||||
TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||
TOKEN: ${{ secrets.BOT_TOKEN }}
|
||||
API: ${{ github.api_url }}
|
||||
REPO: ${{ github.repository }}
|
||||
NAME: ${{ matrix.name }}
|
||||
|
||||
+21
-20
@@ -41,10 +41,6 @@ img_files = {
|
||||
{"LIB/KMENU.OBJ", "common/lib/kmenu.obj"},
|
||||
{"LIB/PIXLIB.OBJ", "common/lib/pixlib.obj"},
|
||||
{"MEDIA/AC97SND", "common/media/ac97snd"},
|
||||
{"MEDIA/IMGF/IMGF", "common/media/ImgF/ImgF"},
|
||||
{"MEDIA/IMGF/CEDG.OBJ", "common/media/ImgF/cEdg.obj"},
|
||||
{"MEDIA/IMGF/DITHER.OBJ", "common/media/ImgF/dither.obj"},
|
||||
{"MEDIA/IMGF/INVSOL.OBJ", "common/media/ImgF/invSol.obj"},
|
||||
{"NETWORK/FTPC.INI", SRC_PROGS .. "/network/ftpc/ftpc.ini"},
|
||||
{"NETWORK/FTPD.INI", "common/network/ftpd.ini"},
|
||||
{"NETWORK/KNMAP", "common/network/knmap"},
|
||||
@@ -58,8 +54,7 @@ img_files = {
|
||||
{"SETTINGS/FB2READ.INI", "common/settings/fb2read.ini"},
|
||||
{"SETTINGS/HA.CFG", SRC_PROGS .. "/other/ha/SETTINGS/HA.CFG"},
|
||||
{"SETTINGS/ICON.INI", build_type .. "/settings/icon.ini"},
|
||||
{"SETTINGS/KEYMAP.KEY", SRC_PROGS .. "/system/taskbar/KEYMAP.KEY"},
|
||||
{"SETTINGS/KOLIBRI.LBL", build_type .. "/settings/kolibri.lbl"},
|
||||
{"SETTINGS/KEYMAP.KEY", VAR_PROGS .. "/system/taskbar/keymap.key.kpack"},
|
||||
{"SETTINGS/LANG.INI", build_type .. "/settings/lang.ini"},
|
||||
{"SETTINGS/MENU.DAT", build_type .. "/settings/menu.dat"},
|
||||
{"SETTINGS/NETWORK.INI", "common/settings/network.ini"},
|
||||
@@ -273,6 +268,10 @@ extra_files = {
|
||||
{"kolibrios/lib/i915_dri.drv", "common/lib/i915_dri.drv"},
|
||||
{"kolibrios/media/fplay", "common/media/fplay"},
|
||||
{"kolibrios/media/fplay_run", "common/media/fplay_run"},
|
||||
{"kolibrios/media/ImgF/ImgF", "common/media/ImgF/ImgF"},
|
||||
{"kolibrios/media/ImgF/cEdg.obj", "common/media/ImgF/cEdg.obj"},
|
||||
{"kolibrios/media/ImgF/dither.obj", "common/media/ImgF/dither.obj"},
|
||||
{"kolibrios/media/ImgF/invSol.obj", "common/media/ImgF/invSol.obj"},
|
||||
{"kolibrios/media/minimp3", "common/media/minimp3"},
|
||||
{"kolibrios/media/updf", SRC .. "/contrib/media/updf/build/uPDF"},
|
||||
{"kolibrios/media/vttf", "common/media/vttf"},
|
||||
@@ -422,7 +421,6 @@ tup.append_table(img_files, {
|
||||
{"CALENDAR", VAR_PROGS .. "/system/calendar/calendar"},
|
||||
{"COLRDIAL", VAR_PROGS .. "/system/colrdial/color_dialog"},
|
||||
{"CROPFLAT", VAR_PROGS .. "/system/cropflat/cropflat"},
|
||||
{"CPU", VAR_PROGS .. "/system/cpu/cpu"},
|
||||
{"CPUID", VAR_PROGS .. "/testing/cpuid/CPUID"},
|
||||
{"DOCPACK", VAR_PROGS .. "/system/docpack/docpack"},
|
||||
{"DEFAULT.SKN", VAR_SKINS .. "/../skins/Leency/Shkvorka/Shkvorka.skn"},
|
||||
@@ -447,6 +445,7 @@ tup.append_table(img_files, {
|
||||
{"SCRSHOOT", VAR_PROGS .. "/media/scrshoot/scrshoot"},
|
||||
{"SETUP", VAR_PROGS .. "/system/setup/setup"},
|
||||
{"SKINCFG", VAR_PROGS .. "/system/skincfg/skincfg"},
|
||||
{"TASKMAN", VAR_PROGS .. "/system/taskman/taskman"},
|
||||
{"TERMINAL", VAR_PROGS .. "/system/terminal/terminal"},
|
||||
{"TEST", VAR_PROGS .. "/testing/protection/test"},
|
||||
{"TINYPAD", VAR_PROGS .. "/develop/tinypad/tinypad"},
|
||||
@@ -487,11 +486,6 @@ tup.append_table(img_files, {
|
||||
{"DEVELOP/MTDBG", VAR_PROGS .. "/develop/mtdbg/mtdbg"},
|
||||
{"DEVELOP/MSTATE", VAR_PROGS .. "/develop/mstate/mstate"},
|
||||
{"DEVELOP/SCANCODE", VAR_PROGS .. "/develop/scancode/scancode"},
|
||||
{"DEVELOP/EXAMPLES/CIRCLE", VAR_PROGS .. "/develop/examples/circle/circle"},
|
||||
{"DEVELOP/EXAMPLES/COLORREF", VAR_PROGS .. "/demos/colorref/colorref"},
|
||||
{"DEVELOP/EXAMPLES/CONGET", VAR_PROGS .. "/develop/libraries/console_coff/examples/test_gets"},
|
||||
{"DEVELOP/EXAMPLES/CSLIDE", VAR_PROGS .. "/demos/cslide/cslide"},
|
||||
{"DEVELOP/EXAMPLES/THREAD", VAR_PROGS .. "/develop/examples/thread/thread"},
|
||||
{"File Managers/KFAR", VAR_PROGS .. "/fs/kfar/kfar"},
|
||||
{"File Managers/OPENDIAL", VAR_PROGS .. "/fs/opendial/opendial"},
|
||||
{"LOD", VAR_PROGS .. "/fs/lod/lod"},
|
||||
@@ -652,20 +646,28 @@ tup.append_table(extra_files, {
|
||||
{"kolibrios/3D/blocks/block.bin", VAR_PROGS .. "/bcc32/games/blocks/block.bin"},
|
||||
{"kolibrios/develop/tcc/lib/crt0.o", VAR_PROGS .. "/develop/ktcc/bin/lib/crt0.o", group = "../programs/develop/ktcc/<crt0.o>"},
|
||||
{"kolibrios/develop/tcc/lib/tiny.o", VAR_PROGS .. "/develop/ktcc/bin/lib/tiny.o", group = "../programs/develop/ktcc/<tiny.o>"},
|
||||
{"kolibrios/develop/tcc/lib/libsound.a", VAR_PROGS .. "/develop/ktcc/bin/lib/libsound.a", group = "../programs/develop/ktcc/<libsound.a>"}
|
||||
{"kolibrios/develop/tcc/lib/libsound.a", VAR_PROGS .. "/develop/ktcc/bin/lib/libsound.a", group = "../programs/develop/ktcc/<libsound.a>"},
|
||||
{"kolibrios/develop/examples/circle", VAR_PROGS .. "/develop/examples/circle/circle"},
|
||||
{"kolibrios/develop/examples/colorref", VAR_PROGS .. "/demos/colorref/colorref"},
|
||||
{"kolibrios/develop/examples/conget", VAR_PROGS .. "/develop/libraries/console_coff/examples/test_gets"},
|
||||
{"kolibrios/develop/examples/cslide", VAR_PROGS .. "/demos/cslide/cslide"},
|
||||
{"kolibrios/develop/examples/thread", VAR_PROGS .. "/develop/examples/thread/thread"}
|
||||
})
|
||||
-- For russian build, add russian-only programs.
|
||||
if build_type == "ru_RU" then tup.append_table(img_files, {
|
||||
{"DEVELOP/EXAMPLES/TESTCON2", VAR_PROGS .. "/develop/libraries/console_coff/examples/testcon2_rus"},
|
||||
}) else tup.append_table(img_files, {
|
||||
{"DEVELOP/EXAMPLES/TESTCON2", VAR_PROGS .. "/develop/libraries/console_coff/examples/testcon2_eng"},
|
||||
}) end
|
||||
-- -- For russian build, add russian-only programs.
|
||||
-- if build_type == "ru_RU" then tup.append_table(img_files, {
|
||||
-- {"DEVELOP/EXAMPLES/TESTCON2", VAR_PROGS .. "/develop/libraries/console_coff/examples/testcon2_rus"},
|
||||
-- }) else tup.append_table(img_files, {
|
||||
-- {"DEVELOP/EXAMPLES/TESTCON2", VAR_PROGS .. "/develop/libraries/console_coff/examples/testcon2_eng"},
|
||||
-- }) end
|
||||
|
||||
if build_type == "ru_RU" then tup.append_table(extra_files, {
|
||||
{"kolibrios/develop/examples/testcon2", VAR_PROGS .. "/develop/libraries/console_coff/examples/testcon2_rus"},
|
||||
{"kolibrios/utils/period", VAR_PROGS .. "/other/period/period"},
|
||||
{"kolibrios/games/Dungeons/Dungeons", VAR_PROGS .. "/games/Dungeons/Dungeons"},
|
||||
{"kolibrios/games/klavisha/klavisha", VAR_PROGS .. "/games/klavisha/klavisha"},
|
||||
{"kolibrios/games/klavisha/basekurs.kla", "ru_RU/games/basekurs.kla"},
|
||||
}) else tup.append_table(extra_files, {
|
||||
{"kolibrios/develop/examples/testcon2", VAR_PROGS .. "/develop/libraries/console_coff/examples/testcon2_eng"},
|
||||
}) end
|
||||
|
||||
end -- tup.getconfig('NO_FASM') ~= 'full'
|
||||
@@ -692,7 +694,6 @@ tup.append_table(img_files, {
|
||||
{"BBENCH", VAR_PROGS .. "/cmm/bbench/bbench.com"},
|
||||
{"SEARCH", VAR_PROGS .. "/cmm/misc/search.com"},
|
||||
{"SYSPANEL", VAR_PROGS .. "/cmm/misc/software_widget.com"},
|
||||
{"SYSMON", VAR_PROGS .. "/cmm/sysmon/sysmon.com"},
|
||||
{"TMPDISK", VAR_PROGS .. "/cmm/tmpdisk/tmpdisk.com"},
|
||||
{"DEVELOP/CLIPVIEW", VAR_PROGS .. "/cmm/clipview/clipview.com"},
|
||||
{"DEVELOP/MENU", VAR_PROGS .. "/cmm/menu/menu.com"},
|
||||
|
||||
@@ -1 +1 @@
|
||||
[@]␍location=3␍fsize=0␍ashow=1␍␍[AppPlus]␍path=/sys/app_plus␍param=␍icon=27␍␍$=1␍␍[KFAR]␍path=/sys/file managers/kfar␍param=␍icon=16␍␍[Pixie2]␍path=/sys/media/pixie␍param=␍icon=65␍␍[IconEdit]␍path=/sys/media/iconedit␍param=␍icon=98␍␍[Calc]␍path=/sys/calc␍param=␍icon=4␍␍[Notes]␍path=/kolibrios/utils/notes␍param=␍icon=117␍␍[Dictionary]␍path=/kolibrios/utils/dicty.kex␍param=␍icon=79␍␍[FB2Read]␍path=/sys/fb2read␍param=␍icon=44␍␍[Animage]␍path=/sys/media/animage␍param=␍icon=15␍␍[RDSave]␍path=/sys/rdsave␍param=␍icon=17␍␍$=1␍␍[Volume]␍path=/sys/@volume␍param=␍icon=64␍␍[NetStatus]␍path=/sys/network/netstat␍param=␍icon=33␍␍[SysMon]␍path=/sys/sysmon␍param=␍icon=57␍␍[SysPanel]␍path=/sys/syspanel␍param=␍icon=6
|
||||
[@]␍location=3␍fsize=0␍ashow=1␍␍[AppPlus]␍path=/sys/app_plus␍param=␍icon=27␍␍$=1␍␍[KFAR]␍path=/sys/file managers/kfar␍param=␍icon=16␍␍[Pixie2]␍path=/sys/media/pixie␍param=␍icon=65␍␍[IconEdit]␍path=/sys/media/iconedit␍param=␍icon=98␍␍[Calc]␍path=/sys/calc␍param=␍icon=4␍␍[Notes]␍path=/kolibrios/utils/notes␍param=␍icon=117␍␍[Dictionary]␍path=/kolibrios/utils/dicty.kex␍param=␍icon=79␍␍[FB2Read]␍path=/sys/fb2read␍param=␍icon=44␍␍[Animage]␍path=/sys/media/animage␍param=␍icon=15␍␍[RDSave]␍path=/sys/rdsave␍param=␍icon=17␍␍$=1␍␍[Volume]␍path=/sys/@volume␍param=␍icon=64␍␍[NetStatus]␍path=/sys/network/netstat␍param=␍icon=33␍␍[TaskMan]␍path=/sys/taskman␍param=␍icon=57␍␍[SysPanel]␍path=/sys/syspanel␍param=␍icon=6
|
||||
@@ -1 +1 @@
|
||||
[rbmenu]␍Диспетчер процессов=/sys/cpu␍Настройка внешнего вида=/kolibrios/utils/appearance␍;Настройка цветов=/sys/skincfg␍;Сплошной фон=/sys/media/palitra␍[01]␍name=FILES␍path=/sys/File Managers/EOLITE␍param=␍ico=7␍x=4␍y=21␍[02]␍name=FPLAY␍path=/kolibrios/media/fplay␍param=␍ico=96␍x=65␍y=21␍[03]␍name=GAMES␍path=/sys/allgames␍param=␍ico=35␍x=125␍y=21␍[04]␍name=TINYPAD␍path=/sys/tinypad␍param=␍ico=9␍x=4␍y=96␍[05]␍name=zSEA␍path=/kolibrios/media/zsea/zsea␍param=␍ico=46␍x=65␍y=96␍[06]␍name=WEBVIEW␍path=/sys/network/webview␍param=␍ico=31␍x=125␍y=96␍␍; =========␍; RIGHT TOP␍; =========␍␍[10]␍name=DEBUG␍path=/SYS/DEVELOP/MTDBG␍param=␍ico=39␍x=-204␍y=21␍[11]␍name=BOARD␍path=/SYS/DEVELOP/BOARD␍param=␍ico=19␍x=-140␍y=21␍[12]␍name=KPACK␍path=/SYS/KPACK␍param=␍ico=99␍x=-77␍y=21␍[13]␍name=DIFF␍path=/sys/develop/diff␍param=␍ico=84␍x=-203␍y=96␍[14]␍name=FASM␍path=/SYS/DEVELOP/FASM␍param=␍ico=10␍x=-141␍y=96␍[15]␍name=DOCPACK␍path=/sys/network/webview␍param=/kolibrios/res/guide/guide.htm␍ico=8␍x=-76␍y=96␍[16]␍name=SHELL␍path=/SYS/SHELL␍param=␍ico=1␍x=-203␍y=166␍[17]␍name=HEXEDIT␍path=/SYS/DEVELOP/HEED␍param=␍ico=22␍x=-141␍y=166␍[18]␍name=CEDIT␍path=/sys/develop/cedit␍param=␍ico=58␍x=-74␍y=166␍
|
||||
[rbmenu]␍Диспетчер задач=/sys/taskman␍Настройка внешнего вида=/kolibrios/utils/appearance␍;Настройка цветов=/sys/skincfg␍;Сплошной фон=/sys/media/palitra␍[01]␍name=FILES␍path=/sys/File Managers/EOLITE␍param=␍ico=7␍x=4␍y=21␍[02]␍name=FPLAY␍path=/kolibrios/media/fplay␍param=␍ico=96␍x=65␍y=21␍[03]␍name=GAMES␍path=/sys/allgames␍param=␍ico=35␍x=125␍y=21␍[04]␍name=TINYPAD␍path=/sys/tinypad␍param=␍ico=9␍x=4␍y=96␍[05]␍name=zSEA␍path=/kolibrios/media/zsea/zsea␍param=␍ico=46␍x=65␍y=96␍[06]␍name=WEBVIEW␍path=/sys/network/webview␍param=␍ico=31␍x=125␍y=96␍␍; =========␍; RIGHT TOP␍; =========␍␍[10]␍name=DEBUG␍path=/SYS/DEVELOP/MTDBG␍param=␍ico=39␍x=-204␍y=21␍[11]␍name=BOARD␍path=/SYS/DEVELOP/BOARD␍param=␍ico=19␍x=-140␍y=21␍[12]␍name=KPACK␍path=/SYS/KPACK␍param=␍ico=99␍x=-77␍y=21␍[13]␍name=DIFF␍path=/sys/develop/diff␍param=␍ico=84␍x=-203␍y=96␍[14]␍name=FASM␍path=/SYS/DEVELOP/FASM␍param=␍ico=10␍x=-141␍y=96␍[15]␍name=DOCPACK␍path=/sys/network/webview␍param=/kolibrios/res/guide/guide.htm␍ico=8␍x=-76␍y=96␍[16]␍name=SHELL␍path=/SYS/SHELL␍param=␍ico=1␍x=-203␍y=166␍[17]␍name=HEXEDIT␍path=/SYS/DEVELOP/HEED␍param=␍ico=22␍x=-141␍y=166␍[18]␍name=CEDIT␍path=/sys/develop/cedit␍param=␍ico=58␍x=-74␍y=166␍
|
||||
@@ -23,8 +23,7 @@ Bus Disconnect=kbd,37
|
||||
System Settings=setup,5
|
||||
|
||||
[Monitoring]
|
||||
Processes=cpu,60
|
||||
System Monitor=sysmon,57
|
||||
Task Manager=taskman,57
|
||||
Ghost Monitor=gmon,107
|
||||
Network Status=network/netstat,33
|
||||
AMDtemp=/k/utils/AMDtemp,128
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[rbmenu]
|
||||
Processes=cpu
|
||||
Task manager=taskman
|
||||
Theme settings=skincfg
|
||||
Background=/sys/media/palitra
|
||||
System panel=syspanel
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
06 zSea Image Viewer * |/kolibrios/media/zsea/zsea
|
||||
38 Animage |media/animage
|
||||
38 IconEdit |media/iconedit
|
||||
40 Image Filtering |media/imgf/imgf
|
||||
40 Image Filtering * |/kolibrios/media/ImgF/ImgF
|
||||
52 Palitra |media/palitra
|
||||
39 Pipet |develop/pipet
|
||||
#4 **** MULTIMEDIA
|
||||
@@ -75,7 +75,7 @@
|
||||
56 Clipboard viewer |develop/clipview
|
||||
62 Calendar |calendar
|
||||
33 Online update * |/kolibrios/utils/osupdate
|
||||
48 Process manager |cpu
|
||||
48 Task manager |taskman
|
||||
24 Terminal |terminal
|
||||
05 Save ramdisk |rdsave
|
||||
24 Shell |shell
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[rbmenu]
|
||||
Processes=cpu
|
||||
Task manager=taskman
|
||||
Theme settings=skincfg
|
||||
Background=/sys/media/palitra
|
||||
System panel=syspanel
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
16 Image viewer KIV |media/kiv
|
||||
16 Image viewer zSea * |/kolibrios/media/zsea/zsea
|
||||
16 Animage |media/animage
|
||||
16 Efectos de imаgenes |media/imgf/imgf
|
||||
16 Efectos de imаgenes * |/kolibrios/media/ImgF/ImgF
|
||||
16 Palitra |media/palitra
|
||||
#4 **** MULTIMEDIA
|
||||
16 Pixie Audioplayer |media/pixie
|
||||
@@ -82,7 +82,7 @@
|
||||
16 Colores y Apariencia |skincfg
|
||||
16 Atajos de teclado |mykey
|
||||
#9 **** SENSORES
|
||||
16 Procesos |cpu
|
||||
16 Gestor de tareas |taskman
|
||||
16 Dispositivos PCI |pcidev
|
||||
16 CPUID |cpuid
|
||||
16 Ghost Monitor |gmon
|
||||
|
||||
@@ -23,8 +23,7 @@ Desconectar bus=kbd,37
|
||||
Ajustes del sistema=setup,5
|
||||
|
||||
[Monitorizacion]
|
||||
Procesos=cpu,60
|
||||
Monitor del sistema=sysmon,57
|
||||
Gestor de tareas=taskman,57
|
||||
Ghost Monitor=gmon,107
|
||||
Estado de red=network/netstat,33
|
||||
AMDtemp=/k/utils/AMDtemp,128
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
06 Image viewer zSea * |/kolibrios/media/zsea/zsea
|
||||
38 Animage |media/animage
|
||||
38 IconEdit |media/iconedit
|
||||
16 Image Filtering |media/imgf/imgf
|
||||
16 Image Filtering * |/kolibrios/media/ImgF/ImgF
|
||||
52 Palitra |media/palitra
|
||||
39 Pipet |develop/pipet
|
||||
#4 **** MULTIMEDIA ****
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
06 Image viewer zSea * |/kolibrios/media/zsea/zsea
|
||||
38 Animage |media/animage
|
||||
38 IconEdit |media/iconedit
|
||||
40 Image Filtering |media/imgf/imgf
|
||||
40 Image Filtering * |/kolibrios/media/ImgF/ImgF
|
||||
52 Palitra |media/palitra
|
||||
39 Pipet |develop/pipet
|
||||
#4 **** MULTIMEDIA
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[rbmenu]
|
||||
Диспетчер процессов=cpu
|
||||
Диспетчер задач=taskman
|
||||
Управление темой=skincfg
|
||||
Настройка фона=/sys/media/palitra
|
||||
Системная панель=syspanel
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
06 Просмотр фото zSea |/kolibrios/media/zsea/zsea
|
||||
38 Редактор Animage |media/animage
|
||||
38 Редактор иконок |media/iconedit
|
||||
40 Наложение фильтров |media/imgf/imgf
|
||||
40 Наложение фильтров * |/kolibrios/media/ImgF/ImgF
|
||||
52 Палитра |media/palitra
|
||||
39 Пипетка |develop/pipet
|
||||
#4 **** Звук и видео
|
||||
@@ -73,6 +73,7 @@
|
||||
00 Файловые менеджеры > |@8
|
||||
00 Спец. возможности > |@9
|
||||
62 Календарь |calendar
|
||||
48 Диспетчер задач |taskman
|
||||
51 Виртуальные диски |tmpdisk
|
||||
24 Терминал |terminal
|
||||
24 Консоль SHELL |shell
|
||||
|
||||
@@ -23,8 +23,7 @@ Hot Angles=HACONFIG,105
|
||||
Системные настройки=setup,5
|
||||
|
||||
[Мониторинг]
|
||||
Процессы=cpu,60
|
||||
Системный монитор=sysmon,57
|
||||
Диспетчер задач=taskman,57
|
||||
Ghost Monitor=gmon,107
|
||||
Статус сети=network/netstat,33
|
||||
AMDtemp=/k/utils/AMDtemp,128
|
||||
|
||||
+100
-14
@@ -130,6 +130,8 @@ RU_STATUS_IDLE = 0000b shl 2
|
||||
RU_STATUS_SUSPENDED = 0001b shl 2
|
||||
RU_STATUS_NO_RESOURCES = 0010b shl 2
|
||||
RU_STATUS_READY = 0100b shl 2
|
||||
SCB_STATUS_CUS = 11000000b ; CU Status
|
||||
CU_STATUS_ACTIVE = 10b shl 6
|
||||
SCB_STATUS_FCP = 1 shl 8 ; Flow Control Pause
|
||||
SCB_STATUS_SWI = 1 shl 10 ; Software Interrupt
|
||||
SCB_STATUS_MDI = 1 shl 11 ; MDI read/write complete
|
||||
@@ -183,6 +185,8 @@ struct txfd
|
||||
|
||||
ends
|
||||
|
||||
TXFD_STATUS_C = 1 shl 15
|
||||
|
||||
TXFD_CMD_IA = 1 shl 0
|
||||
TXFD_CMD_CFG = 1 shl 1
|
||||
TXFD_CMD_TX = 1 shl 2
|
||||
@@ -628,6 +632,9 @@ reset:
|
||||
mov ax, CU_START or INT_MASK
|
||||
out dx, ax
|
||||
call cmd_wait
|
||||
; cmd_wait only means the SCB accepted the command. The Configure below
|
||||
; reuses confcmd, so a slow chip would read it instead of our MAC.
|
||||
call confcmd_wait
|
||||
|
||||
;-------------
|
||||
; Configure CU
|
||||
@@ -652,6 +659,7 @@ reset:
|
||||
mov ax, CU_START ; expect Interrupts from now on
|
||||
out dx, ax
|
||||
call cmd_wait
|
||||
call confcmd_wait
|
||||
|
||||
; Start media check timer
|
||||
mov [ebx + device.state], ETH_LINK_DOWN
|
||||
@@ -678,6 +686,11 @@ init_rx_ring:
|
||||
;---------------------
|
||||
; build rxfd structure
|
||||
|
||||
cmp [ebx + device.rx_desc], 0 ; the RFD of an earlier reset
|
||||
je @f
|
||||
invoke NetFree, [ebx + device.rx_desc]
|
||||
mov [ebx + device.rx_desc], 0
|
||||
@@:
|
||||
invoke NetAlloc, 2000
|
||||
test eax, eax
|
||||
jz .out_of_mem
|
||||
@@ -689,6 +702,7 @@ init_rx_ring:
|
||||
mov [esi + sizeof.NET_BUFF + rxfd.command], RXFD_CMD_EL or RXFD_CMD_SUSPEND
|
||||
mov [esi + sizeof.NET_BUFF + rxfd.link], eax
|
||||
mov [esi + sizeof.NET_BUFF + rxfd.count], 0
|
||||
mov [esi + sizeof.NET_BUFF + rxfd.rx_buf_addr], 0xffffffff ; simplified mode, no RBD
|
||||
mov [esi + sizeof.NET_BUFF + rxfd.size], 1528
|
||||
|
||||
ret
|
||||
@@ -709,6 +723,15 @@ init_tx_ring:
|
||||
invoke GetPhysAddr
|
||||
mov ecx, TX_RING_SIZE
|
||||
.next_desc:
|
||||
; after a reset with frames still unreclaimed: free them, or transmit sees the
|
||||
; descriptor busy (virt_addr) and reports TX overrun forever
|
||||
cmp [esi + txfd.virt_addr], 0
|
||||
je @f
|
||||
push eax ecx
|
||||
invoke NetFree, [esi + txfd.virt_addr]
|
||||
pop ecx eax
|
||||
mov [esi + txfd.virt_addr], 0
|
||||
@@:
|
||||
mov [esi + txfd.status], 0
|
||||
mov [esi + txfd.command], 0
|
||||
lea edx, [eax + txfd.buf_addr]
|
||||
@@ -763,7 +786,7 @@ proc transmit stdcall bufferptr
|
||||
lea edi, [ebx + device.tx_ring + eax]
|
||||
|
||||
; Check if current descriptor is free or still in use
|
||||
cmp [edi + txfd.status], 0
|
||||
cmp [edi + txfd.virt_addr], 0 ; buffer not reclaimed yet
|
||||
jne .overrun
|
||||
|
||||
; Fill in status and command values
|
||||
@@ -786,6 +809,22 @@ proc transmit stdcall bufferptr
|
||||
mov eax, edi
|
||||
invoke GetPhysAddr
|
||||
set_io [ebx + device.io_addr], 0
|
||||
|
||||
; CU_START is only valid while the CU is idle or suspended:
|
||||
; wait for the previous frame to leave (1.2 ms at 10 Mbit)
|
||||
push eax ecx
|
||||
set_io [ebx + device.io_addr], REG_SCB_STATUS
|
||||
mov ecx, 100000
|
||||
.cu_busy:
|
||||
in al, dx
|
||||
and al, SCB_STATUS_CUS
|
||||
cmp al, CU_STATUS_ACTIVE
|
||||
jne .cu_free
|
||||
dec ecx
|
||||
jnz .cu_busy
|
||||
DEBUGF 2, "CU still active, starting anyway\n"
|
||||
.cu_free:
|
||||
pop ecx eax
|
||||
set_io [ebx + device.io_addr], REG_SCB_PTR
|
||||
out dx, eax
|
||||
|
||||
@@ -854,7 +893,7 @@ int_handler:
|
||||
|
||||
DEBUGF 1,"Status: %x\n", ax
|
||||
|
||||
test ax, SCB_STATUS_FR ; did we receive a frame?
|
||||
test ax, SCB_STATUS_FR or SCB_STATUS_RNR ; frame received or receiver stopped?
|
||||
jz .no_rx
|
||||
|
||||
push ax
|
||||
@@ -901,6 +940,7 @@ int_handler:
|
||||
mov [esi + sizeof.NET_BUFF + rxfd.command], RXFD_CMD_EL or RXFD_CMD_SUSPEND
|
||||
mov [esi + sizeof.NET_BUFF + rxfd.link], eax
|
||||
mov [esi + sizeof.NET_BUFF + rxfd.count], 0
|
||||
mov [esi + sizeof.NET_BUFF + rxfd.rx_buf_addr], 0xffffffff ; simplified mode, no RBD
|
||||
mov [esi + sizeof.NET_BUFF + rxfd.size], 1528
|
||||
|
||||
; restart RX
|
||||
@@ -916,11 +956,22 @@ int_handler:
|
||||
mov ax, RX_START
|
||||
out dx, ax
|
||||
call cmd_wait
|
||||
.out_of_mem:
|
||||
|
||||
; Hand the frame over to the kernel
|
||||
jmp [EthInput]
|
||||
|
||||
.out_of_mem:
|
||||
; The buffer is still our only RFD: drop the frame and reuse it
|
||||
mov esi, [esp] ; the buffer
|
||||
mov ecx, [esi + NET_BUFF.length]
|
||||
dec [ebx + device.packets_rx] ; counted above, before the allocation
|
||||
sub dword [ebx + device.bytes_rx], ecx
|
||||
sbb dword [ebx + device.bytes_rx + 4], 0
|
||||
inc [ebx + device.packets_rx_drop]
|
||||
add esp, 12 ; buffer, .rx_loop, ebx
|
||||
mov esi, [ebx + device.rx_desc]
|
||||
jmp .not_ok
|
||||
|
||||
.not_ok:
|
||||
; Reset the FD
|
||||
mov [esi + sizeof.NET_BUFF + rxfd.status], 0
|
||||
@@ -945,6 +996,27 @@ int_handler:
|
||||
|
||||
.no_rx_:
|
||||
DEBUGF 1, "no more data\n"
|
||||
|
||||
; With a single RFD the receiver sits in No Resources/Suspended whenever a
|
||||
; frame arrived before we re-armed it. Nothing restarts it but us.
|
||||
set_io [ebx + device.io_addr], 0
|
||||
set_io [ebx + device.io_addr], REG_SCB_STATUS
|
||||
in al, dx
|
||||
and al, SCB_STATUS_RUS
|
||||
cmp al, RU_STATUS_READY
|
||||
je .ru_ready
|
||||
test byte[esp], 1 ; bit 0 of the saved status is reserved,
|
||||
jnz .ru_ready ; we mark it: one restart per IRQ
|
||||
or byte[esp], 1
|
||||
movzx eax, al
|
||||
DEBUGF 1, "Restarting receiver, RU status %x\n", eax:2
|
||||
mov esi, [ebx + device.rx_desc]
|
||||
push ebx
|
||||
test [esi + sizeof.NET_BUFF + rxfd.status], RXFD_STATUS_C
|
||||
jnz .rx_loop ; a frame completed meanwhile
|
||||
add esp, 4
|
||||
jmp .not_ok ; re-arm the empty RFD
|
||||
.ru_ready:
|
||||
pop ax
|
||||
|
||||
.no_rx:
|
||||
@@ -955,13 +1027,13 @@ int_handler:
|
||||
|
||||
push eax
|
||||
.loop_tx:
|
||||
mov edi, [ebx + device.last_tx]
|
||||
mov eax, sizeof.txfd
|
||||
mul eax
|
||||
mov eax, [ebx + device.last_tx]
|
||||
mov edx, sizeof.txfd
|
||||
mul edx
|
||||
lea edi, [ebx + device.tx_ring + eax]
|
||||
|
||||
cmp [edi + txfd.status], 0
|
||||
je .tx_done
|
||||
test [edi + txfd.status], TXFD_STATUS_C ; sent by the device?
|
||||
jz .tx_done
|
||||
|
||||
cmp [edi + txfd.virt_addr], 0
|
||||
je .tx_done
|
||||
@@ -970,6 +1042,7 @@ int_handler:
|
||||
|
||||
push [edi + txfd.virt_addr]
|
||||
mov [edi + txfd.virt_addr], 0
|
||||
mov [edi + txfd.status], 0 ; free for transmit again
|
||||
invoke NetFree
|
||||
|
||||
inc [ebx + device.last_tx]
|
||||
@@ -980,12 +1053,6 @@ int_handler:
|
||||
pop eax
|
||||
.no_tx:
|
||||
|
||||
test ax, RU_STATUS_NO_RESOURCES
|
||||
jz .not_out_of_resources
|
||||
|
||||
DEBUGF 2, "Out of resources!\n"
|
||||
|
||||
.not_out_of_resources:
|
||||
pop edi esi ebx
|
||||
xor eax, eax
|
||||
inc eax
|
||||
@@ -1079,6 +1146,25 @@ proc check_media_mii stdcall dev:dword
|
||||
endp
|
||||
|
||||
|
||||
; Wait (up to 1 s) until the device has executed the command in confcmd.
|
||||
align 4
|
||||
confcmd_wait:
|
||||
mov ecx, 1000 ; udelay = Sleep(1), 1 ms
|
||||
.loop:
|
||||
test [ebx + device.confcmd.status], TXFD_STATUS_C
|
||||
jnz .done
|
||||
call udelay
|
||||
dec ecx
|
||||
jnz .loop
|
||||
movzx eax, [ebx + device.confcmd.command]
|
||||
DEBUGF 2, "Command 0x%x not completed\n", eax:4
|
||||
ret
|
||||
.done:
|
||||
movzx eax, [ebx + device.confcmd.command]
|
||||
movzx ecx, [ebx + device.confcmd.status]
|
||||
DEBUGF 1, "Command 0x%x done, status 0x%x\n", eax:4, ecx:4
|
||||
ret
|
||||
|
||||
align 4
|
||||
cmd_wait:
|
||||
|
||||
|
||||
@@ -72,9 +72,26 @@ I2CHID_PWR_ON = 0x00
|
||||
; single tick forever.
|
||||
MAX_POLL_ERRORS = 100
|
||||
|
||||
; Polls of silence before the next recovery step is tried (20 ms each).
|
||||
; Polls of silence before the next recovery step is tried (10 ms each).
|
||||
; The ladder exists for bringing up a pad that never reports at all, and is
|
||||
; compiled in only at debug level 1: on a working pad it would run merely
|
||||
; because nobody touched it during the first seconds after boot, and the
|
||||
; power cycle, the second reset and the poll-mode flips it consists of are
|
||||
; exactly the kind of thing a fragile firmware answers with silence.
|
||||
SILENT_LIMIT = 150
|
||||
|
||||
; A pad that has ever answered an idle poll with an empty length, yet keeps
|
||||
; returning one and the same non-empty frame, has stopped producing frames:
|
||||
; a finger on the surface changes the scan time in every report, and a pad
|
||||
; that holds its last frame instead of answering empty (Elan) never counts
|
||||
; here. Seen on the SIPODEV SP1064: a single frame came through and was
|
||||
; then repeated on every poll for good. This many identical answers in a
|
||||
; row, and the device is reset and switched into touchpad mode again; the
|
||||
; limit doubles on each reset, up to the maximum, so a pad that stays wedged
|
||||
; is retried, not hammered.
|
||||
STUCK_DUPS = 100
|
||||
STUCK_DUPS_MAX = 3000
|
||||
|
||||
; ---------------------------- Settings -------------------------------------
|
||||
; Everything below has a built-in default and can be overridden from the
|
||||
; [touchpad] section of /sys/settings/system.ini. The file is read once at
|
||||
@@ -1686,6 +1703,56 @@ proc set_ptp_mode uses ebx esi edi
|
||||
ret
|
||||
endp
|
||||
|
||||
; The pad has wedged (see STUCK_DUPS): drop whatever touch the driver holds,
|
||||
; then bring the device up again the way setup_device did - RESET, a quiet
|
||||
; wait, one read to consume the ack, SET_POWER(ON), and the touchpad mode,
|
||||
; which the reset cleared. Runs in the poll thread.
|
||||
proc reinit_device uses ebx esi edi
|
||||
inc [StReinit]
|
||||
DEBUGF 2, "i2chid: pad stuck: the same frame %u polls in a row, resetting it (%u so far)\n", [DupRun], [StReinit]
|
||||
mov [DupRun], 0
|
||||
mov eax, [StuckLimit]
|
||||
add eax, eax
|
||||
cmp eax, STUCK_DUPS_MAX
|
||||
jbe @f
|
||||
mov eax, STUCK_DUPS_MAX
|
||||
@@:
|
||||
mov [StuckLimit], eax
|
||||
; Whatever the driver was in the middle of is over: no finger, no button.
|
||||
call ptp_forget
|
||||
mov [PrevTip], 0
|
||||
mov [BtnLatch], 0
|
||||
mov [HeldBtn], 0
|
||||
mov [TapHold], 0
|
||||
mov [TapRelease], 0
|
||||
mov [PendingPress], 0
|
||||
mov [DragActive], 0
|
||||
invoke SetMouseData, 0, 0, 0, 0, 0
|
||||
stdcall hid_command, 0, I2CHID_OP_RESET
|
||||
test eax, eax
|
||||
jz @f
|
||||
DEBUGF 2, "i2chid: RESET failed (%x)\n", eax
|
||||
@@:
|
||||
mov esi, 150
|
||||
invoke Sleep
|
||||
stdcall dw_read_block, [SlaveAddr], 0, 0, input_buf, [MaxInput]
|
||||
stdcall hid_command, I2CHID_PWR_ON, I2CHID_OP_SET_POWER
|
||||
test eax, eax
|
||||
jz @f
|
||||
DEBUGF 2, "i2chid: post-reset SET_POWER failed (%x)\n", eax
|
||||
@@:
|
||||
mov esi, 10
|
||||
invoke Sleep
|
||||
call set_ptp_mode
|
||||
mov [PollMode], 0
|
||||
; The held frame is stale now; the next one the pad sends must count as new.
|
||||
mov edi, prev_rep
|
||||
mov ecx, MAX_INPUT_BUF
|
||||
xor eax, eax
|
||||
rep stosb
|
||||
ret
|
||||
endp
|
||||
|
||||
; Asks the device for every report it declared, as both an Input and a
|
||||
; Feature report, and logs each answer. A pad whose sensor is alive but
|
||||
; whose reporting mode was never selected will answer at least one of
|
||||
@@ -1883,8 +1950,8 @@ proc i2chid_thread
|
||||
test edx, edx
|
||||
jnz @f
|
||||
.stats:
|
||||
DEBUGF 2, "i2chid: after %u polls: %u reads, %u reports, %u duplicates, %u empty, at most %u per poll, %u lifts by silence\n", \
|
||||
[StPolls], [StReads], [StReports], [StDups], [StEmpty], [StMaxDrain], [StForced]
|
||||
DEBUGF 2, "i2chid: after %u polls: %u reads, %u reports, %u duplicates, %u empty, at most %u per poll, %u lifts by silence, %u resets\n", \
|
||||
[StPolls], [StReads], [StReports], [StDups], [StEmpty], [StMaxDrain], [StForced], [StReinit]
|
||||
@@:
|
||||
; Syscall 5 is the delay that sleeps on an event and yields; the Sleep import
|
||||
; drivers normally use is delay_ms, which busy-waits and would burn a core.
|
||||
@@ -1965,6 +2032,8 @@ proc i2chid_poll_once uses ebx esi edi
|
||||
mov [GotAny], 1
|
||||
mov [Consumed], 1
|
||||
inc [StReports]
|
||||
mov [DupRun], 0
|
||||
mov [StuckLimit], STUCK_DUPS
|
||||
; The first few reports are dumped raw, before any interpretation, so that a
|
||||
; touchpad which does send data but whose bytes the driver reads wrongly can
|
||||
; be told apart from one that says nothing at all.
|
||||
@@ -2068,9 +2137,17 @@ proc i2chid_poll_once uses ebx esi edi
|
||||
.duplicate:
|
||||
pop eax
|
||||
inc [StDups]
|
||||
cmp [StEmpty], 0
|
||||
je .done ; holding the last frame is this pad's idle
|
||||
inc [DupRun]
|
||||
mov eax, [DupRun]
|
||||
cmp eax, [StuckLimit]
|
||||
jb .done
|
||||
call reinit_device
|
||||
jmp .done
|
||||
.silent:
|
||||
inc [StEmpty]
|
||||
mov [DupRun], 0
|
||||
; Nothing arrived. An idle answer is still evidence: if the device reacts
|
||||
; to a finger at all, something in those bytes changes even when it never
|
||||
; sets a length, so the first answers and every change are logged.
|
||||
@@ -2080,6 +2157,8 @@ proc i2chid_poll_once uses ebx esi edi
|
||||
; If any of them wakes the device, GotAny freezes the ladder for good.
|
||||
cmp [GotAny], 0
|
||||
jnz .done
|
||||
cmp [LadderOn], 0
|
||||
jz .done
|
||||
inc [SilentPolls]
|
||||
cmp [SilentPolls], SILENT_LIMIT
|
||||
jb .done
|
||||
@@ -2759,6 +2838,15 @@ TraceCount dd 8
|
||||
DecodeTrace dd 8
|
||||
GotAny dd 0
|
||||
SilentPolls dd 0
|
||||
DupRun dd 0
|
||||
; The bring-up ladder runs only in a level-1 (chatty) build.
|
||||
if __DEBUG_LEVEL__ > 1
|
||||
LadderOn dd 0
|
||||
else
|
||||
LadderOn dd 1
|
||||
end if
|
||||
StuckLimit dd STUCK_DUPS
|
||||
StReinit dd 0
|
||||
|
||||
; Parser state (see hidmin.inc).
|
||||
p_usage_page dd 0
|
||||
|
||||
+970
-105
File diff suppressed because it is too large.
Load diff
@@ -842,8 +842,7 @@ disk_scan_partitions:
|
||||
cmp ebx, mbr_buffer
|
||||
jz .release_partition_buffer
|
||||
; 15b. If we have allocated it, free it.
|
||||
xchg eax, ebx
|
||||
call free
|
||||
stdcall kernel_free, ebx
|
||||
jmp .nothing
|
||||
; 15c. Otherwise, release reference.
|
||||
.release_partition_buffer:
|
||||
|
||||
@@ -4148,6 +4148,7 @@ Structure of block of data for folder entry (BDFE):
|
||||
and after archiving this bit is cleared - it can be useful
|
||||
for automatically creating of backup-archives as at writing
|
||||
this bit is usually set
|
||||
* bit 6 (mask 0x40): this is a symbolic link (currently only set by the ext driver).
|
||||
* +4: dword: encoding, equals to field +8 in the information structure
|
||||
* +8: 4*byte: time of file creation
|
||||
* +12 = +0xC: 4*byte: date of file creation
|
||||
|
||||
@@ -212,6 +212,7 @@ DIR_DIRECTORY = 2
|
||||
DIR_SYMLINK = 7
|
||||
KOS_HIDDEN = 2
|
||||
KOS_DIRECTORY = 10h
|
||||
KOS_SYMLINK = 40h
|
||||
READ_ONLY = 1
|
||||
SYMLINK_MAX_DEPTH = 40
|
||||
FAST_SYMLINK_MAX_SIZE = 60
|
||||
@@ -3392,6 +3393,11 @@ ext_ReadFolder:
|
||||
stosd
|
||||
mov eax, [esi+INODE.fileSizeHigh]
|
||||
stosd
|
||||
movzx eax, [esi+INODE.accessMode]
|
||||
and eax, TYPE_MASK
|
||||
cmp eax, FLAG_SYMLINK
|
||||
jne @f
|
||||
or dword [edx], KOS_SYMLINK
|
||||
@@:
|
||||
mov esi, [esp+12]
|
||||
movzx ecx, [esi+DIRENTRY.nameLength]
|
||||
|
||||
@@ -2628,7 +2628,7 @@ modify_pce:
|
||||
|
||||
|
||||
iglobal
|
||||
cpustring db 'CPU',0
|
||||
cpustring db 'TASKMAN',0
|
||||
endg
|
||||
|
||||
uglobal
|
||||
|
||||
@@ -83,6 +83,31 @@ macro arp_init {
|
||||
|
||||
}
|
||||
|
||||
;-----------------------------------------------------------------;
|
||||
; ;
|
||||
; arp_clear_device: Empty the ARP table and counters of a removed ;
|
||||
; device. ;
|
||||
; ;
|
||||
; IN: edi = device number * 4 ;
|
||||
; ;
|
||||
;-----------------------------------------------------------------;
|
||||
macro arp_clear_device {
|
||||
|
||||
xor eax, eax
|
||||
mov [ARP_entries + edi], eax
|
||||
mov [ARP_packets_tx + edi], eax
|
||||
mov [ARP_packets_rx + edi], eax
|
||||
mov [ARP_conflicts + edi], eax
|
||||
|
||||
push edi
|
||||
imul edi, (ARP_TABLE_SIZE * sizeof.ARP_entry)/4
|
||||
add edi, ARP_table
|
||||
mov ecx, (ARP_TABLE_SIZE * sizeof.ARP_entry)/2
|
||||
rep stosw
|
||||
pop edi
|
||||
|
||||
}
|
||||
|
||||
;-----------------------------------------------------------------;
|
||||
; ;
|
||||
; arp_decrease_entry_ttls ;
|
||||
@@ -313,6 +338,9 @@ arp_output_request:
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_output_request: ip=%u.%u.%u.%u device=0x%x\n",\
|
||||
[esp]:1, [esp + 1]:1, [esp + 2]:1, [esp + 3]:1, ebx
|
||||
|
||||
test ebx, ebx ; device is gone
|
||||
jz .exit
|
||||
|
||||
mov ax, ETHER_PROTO_ARP
|
||||
mov ecx, sizeof.ARP_header
|
||||
mov edx, ETH_BROADCAST ; broadcast mac
|
||||
|
||||
@@ -105,6 +105,29 @@ macro ipv4_init {
|
||||
}
|
||||
|
||||
|
||||
;-----------------------------------------------------------------;
|
||||
; ;
|
||||
; ipv4_clear_device: Reset the IPv4 settings of a removed device, ;
|
||||
; so no route points to it anymore. ;
|
||||
; ;
|
||||
; IN: edi = device number * 4 ;
|
||||
; ;
|
||||
;-----------------------------------------------------------------;
|
||||
macro ipv4_clear_device {
|
||||
|
||||
xor eax, eax
|
||||
mov [IPv4_address + edi], eax
|
||||
mov [IPv4_subnet + edi], eax
|
||||
mov [IPv4_nameserver + edi], eax
|
||||
mov [IPv4_gateway + edi], eax
|
||||
mov [IPv4_broadcast + edi], eax
|
||||
mov [IPv4_packets_tx + edi], eax
|
||||
mov [IPv4_packets_rx + edi], eax
|
||||
mov [IPv4_packets_dumped + edi], eax
|
||||
|
||||
}
|
||||
|
||||
|
||||
;-----------------------------------------------------------------;
|
||||
; ;
|
||||
; Decrease TimeToLive of all fragment slots ;
|
||||
@@ -757,6 +780,8 @@ ipv4_output_raw:
|
||||
push esi eax
|
||||
|
||||
call ipv4_route
|
||||
test eax, eax
|
||||
jz .arp_error
|
||||
call arp_ip_to_mac
|
||||
|
||||
test eax, 0xffff0000 ; error bits
|
||||
@@ -967,6 +992,8 @@ ipv4_route:
|
||||
; Check for on-link
|
||||
xor edi, edi
|
||||
.loop:
|
||||
cmp [net_device_list + edi], 0 ; skip slots without a device
|
||||
je .next
|
||||
mov ebx, [IPv4_address + edi]
|
||||
and ebx, [IPv4_subnet + edi]
|
||||
jz .next
|
||||
@@ -983,7 +1010,10 @@ ipv4_route:
|
||||
mov edi, 4 ; skip loopback device
|
||||
.loop_gw:
|
||||
cmp [IPv4_gateway + edi], 0
|
||||
je .next_gw
|
||||
cmp [net_device_list + edi], 0
|
||||
jne .found_gw
|
||||
.next_gw:
|
||||
add edi, 4
|
||||
cmp edi, 4*NET_DEVICES_MAX
|
||||
jb .loop_gw
|
||||
@@ -1049,14 +1079,23 @@ ipv4_route:
|
||||
cmp eax, 0xffffffff
|
||||
je @f
|
||||
|
||||
; An interface without an address (DHCP not done yet, or the lease
|
||||
; dropped when the link went down) can send nothing but broadcasts: with
|
||||
; address and mask both zero every destination compared as on-link, and
|
||||
; the stack went asking ARP for internet addresses on behalf of 0.0.0.0.
|
||||
test edx, edx
|
||||
jz .fail
|
||||
|
||||
; Check if we should route to gateway or not
|
||||
mov ebx, [IPv4_address + edi]
|
||||
mov ebx, edx
|
||||
and ebx, [IPv4_subnet + edi]
|
||||
mov ecx, eax
|
||||
and ecx, [IPv4_subnet + edi]
|
||||
cmp ecx, ebx
|
||||
je @f
|
||||
mov eax, [IPv4_gateway + edi]
|
||||
test eax, eax
|
||||
jz .fail ; off-link and no gateway
|
||||
@@:
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_route: %u\n", edi
|
||||
ret
|
||||
|
||||
@@ -61,6 +61,41 @@ macro eth_init {
|
||||
|
||||
}
|
||||
|
||||
;-----------------------------------------------------------------;
|
||||
; ;
|
||||
; eth_clear_device: Drop the frames of a removed device that are ;
|
||||
; still waiting in the input queue, their ;
|
||||
; NET_BUFF.device will not be valid anymore. ;
|
||||
; ;
|
||||
; IN: ebx = device ptr ;
|
||||
; ;
|
||||
;-----------------------------------------------------------------;
|
||||
macro eth_clear_device {
|
||||
|
||||
local .loop, .done
|
||||
|
||||
spin_lock_irqsave
|
||||
mov esi, [ETH_frame_head]
|
||||
.loop:
|
||||
cmp esi, ETH_frame_head
|
||||
je .done
|
||||
mov eax, esi
|
||||
mov esi, [esi + NET_BUFF.NextPtr]
|
||||
cmp [eax + NET_BUFF.device], ebx
|
||||
jne .loop
|
||||
|
||||
; unlink it, ETH_frame_head/tail double as the NextPtr/PrevPtr of the list head
|
||||
mov ecx, [eax + NET_BUFF.PrevPtr]
|
||||
mov [ecx + NET_BUFF.NextPtr], esi
|
||||
mov [esi + NET_BUFF.PrevPtr], ecx
|
||||
dec [ETH_frame_queued]
|
||||
stdcall net_buff_free, eax
|
||||
jmp .loop
|
||||
.done:
|
||||
spin_unlock_irqrestore
|
||||
|
||||
}
|
||||
|
||||
align 4
|
||||
; This function is called by ethernet drivers.
|
||||
; Push the received ethernet packet onto the ethernet input queue.
|
||||
@@ -245,6 +280,9 @@ eth_output:
|
||||
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_output: size=%u device=%x\n", ecx, ebx
|
||||
|
||||
test ebx, ebx
|
||||
jz .no_device
|
||||
|
||||
cmp ecx, [ebx + ETH_DEVICE.mtu]
|
||||
ja .too_large
|
||||
|
||||
@@ -295,11 +333,16 @@ eth_output:
|
||||
ret
|
||||
|
||||
.too_large:
|
||||
inc [eax + NET_DEVICE.packets_tx_err]
|
||||
inc [ebx + NET_DEVICE.packets_tx_err]
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_output: Packet too large!\n"
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
.no_device:
|
||||
DEBUGF DEBUG_NETWORK_ERROR, "ETH_output: no device!\n"
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
|
||||
|
||||
;-----------------------------------------------------------------;
|
||||
|
||||
@@ -597,6 +597,16 @@ net_remove_device:
|
||||
mov dword [edi-4], eax
|
||||
dec [net_device_count]
|
||||
|
||||
;-----------------------------------------------------------------
|
||||
; Forget everything the protocols still know about this interface.
|
||||
; Otherwise its IP address keeps matching in ipv4_route, and output
|
||||
; ends up calling through the now empty net_device_list slot.
|
||||
|
||||
sub edi, net_device_list + 4 ; device number * 4
|
||||
ipv4_clear_device
|
||||
arp_clear_device
|
||||
eth_clear_device
|
||||
|
||||
call net_send_event
|
||||
|
||||
xor eax, eax
|
||||
|
||||
@@ -1422,10 +1422,14 @@ endl
|
||||
test [edx + TCP_header.Flags], TH_ACK
|
||||
jz .drop
|
||||
|
||||
mov eax, ebx
|
||||
push ebx
|
||||
lea ecx, [ebx + SOCKET.mutex]
|
||||
call mutex_unlock
|
||||
pop eax
|
||||
|
||||
mov ebx, ECONNREFUSED
|
||||
call tcp_drop
|
||||
jmp .drop
|
||||
jmp .drop_no_socket
|
||||
@@:
|
||||
|
||||
;-----------------------------------------------------------------------------------
|
||||
|
||||
@@ -234,23 +234,25 @@ endl
|
||||
mov ebx, TCP_max_win
|
||||
shl ebx, cl
|
||||
pop ecx
|
||||
sub ebx, [eax + TCP_SOCKET.RCV_ADV]
|
||||
add ebx, [eax + TCP_SOCKET.RCV_NXT]
|
||||
|
||||
; Clamp to available window first, then subtract what the peer already knows (as in BSD)
|
||||
|
||||
cmp ebx, ecx
|
||||
jl @f
|
||||
jbe @f
|
||||
mov ebx, ecx
|
||||
@@:
|
||||
sub ebx, [eax + TCP_SOCKET.RCV_ADV]
|
||||
add ebx, [eax + TCP_SOCKET.RCV_NXT]
|
||||
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_output: we can increase window by %d bytes\n", ebx
|
||||
|
||||
mov edi, [eax + TCP_SOCKET.t_maxseg]
|
||||
shl edi, 1
|
||||
cmp ebx, edi
|
||||
jae .send
|
||||
cmp ebx, edi ; signed: may be negative if window shrank
|
||||
jge .send
|
||||
|
||||
cmp ebx, SOCKET_BUFFER_SIZE/2
|
||||
jae .send
|
||||
jge .send
|
||||
|
||||
.no_window:
|
||||
|
||||
|
||||
@@ -180,6 +180,8 @@ tcp_connect:
|
||||
|
||||
.nomem:
|
||||
pop edx eax
|
||||
lea ecx, [eax + SOCKET.mutex]
|
||||
call mutex_unlock
|
||||
xor eax, eax
|
||||
dec eax
|
||||
mov ebx, ENOMEM
|
||||
@@ -194,6 +196,8 @@ tcp_connect:
|
||||
.enoroute:
|
||||
pop eax
|
||||
popa
|
||||
lea ecx, [eax + SOCKET.mutex]
|
||||
call mutex_unlock
|
||||
xor eax, eax
|
||||
dec eax
|
||||
mov ebx, EADDRNOTAVAIL
|
||||
|
||||
+1
-1
Submodule programs/cmm updated: 4678e1605d...86b0211da7.
@@ -238,7 +238,6 @@ BEGIN
|
||||
m.active := FALSE;
|
||||
resetTimer;
|
||||
m.tid := 0;
|
||||
G.destroy(m.canvas);
|
||||
K.Exit
|
||||
END exit;
|
||||
|
||||
@@ -250,7 +249,6 @@ BEGIN
|
||||
resetTimer
|
||||
END;
|
||||
m.tid := 0;
|
||||
G.destroy(m.canvas);
|
||||
K.Exit
|
||||
END escape;
|
||||
|
||||
@@ -356,7 +354,6 @@ BEGIN
|
||||
END;
|
||||
temp := m.tid;
|
||||
m.tid := 0;
|
||||
G.destroy(m.canvas);
|
||||
K.ExitID(temp);
|
||||
m.active := FALSE
|
||||
END
|
||||
@@ -512,7 +509,6 @@ BEGIN
|
||||
IF m.parent # NIL THEN
|
||||
temp := m.parent.tid;
|
||||
m.parent.tid := 0;
|
||||
G.destroy(m.parent.canvas);
|
||||
K.ExitID(temp)
|
||||
END;
|
||||
exit(m)
|
||||
|
||||
+1
-1
Submodule programs/develop/cmm updated: 84fdec8562...4aeaee3386.
@@ -1,6 +1,6 @@
|
||||
#include <shell_api.h>
|
||||
|
||||
char shell_getc()
|
||||
int shell_getc()
|
||||
{
|
||||
__shell_init();
|
||||
|
||||
@@ -9,7 +9,7 @@ char shell_getc()
|
||||
__shell_shm->cmd = SHELL_GETC;
|
||||
__SHELL_WAIT();
|
||||
|
||||
return __shell_shm->data[0];
|
||||
return *((int*)__shell_shm->data);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -1,15 +1,28 @@
|
||||
#include <shell_api.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
void shell_gets(char *str, int n)
|
||||
char *shell_gets(char *str, int n)
|
||||
{
|
||||
__shell_init();
|
||||
|
||||
char *ptr = NULL;
|
||||
if (__shell_is_init == __SHELL_INIT_OK)
|
||||
{
|
||||
__shell_shm->cmd = SHELL_GETS;
|
||||
__SHELL_WAIT();
|
||||
|
||||
strncpy(str, __shell_shm->data, n);
|
||||
|
||||
if (__shell_shm->return_value.str == EOF || !__shell_shm->return_value.str)
|
||||
{
|
||||
ptr = __shell_shm->return_value.str;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr = str;
|
||||
}
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
@@ -1,12 +1,13 @@
|
||||
#include <shell_api.h>
|
||||
#include <stdio.h>
|
||||
|
||||
void shell_printf(const char *format, ...)
|
||||
int shell_printf(const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
vsnprintf(__shell_shm->data, sizeof(__shell_shm->data), format, ap);
|
||||
int val = vsnprintf(__shell_shm->data, sizeof(__shell_shm->data), format, ap);
|
||||
__shell_shm->cmd = SHELL_PUTS;
|
||||
va_end(ap);
|
||||
__SHELL_WAIT();
|
||||
return val;
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <shell_api.h>
|
||||
#include <string.h>
|
||||
|
||||
void shell_puts(const char *str)
|
||||
size_t shell_puts(const char *str)
|
||||
{
|
||||
shell_write_string(str, strlen(str));
|
||||
return shell_write_string(str, strlen(str));
|
||||
}
|
||||
@@ -1,22 +1,27 @@
|
||||
#include <shell_api.h>
|
||||
#include <string.h>
|
||||
|
||||
void shell_write_string(const char *s, size_t len)
|
||||
size_t shell_write_string(const char *s, size_t len)
|
||||
{
|
||||
__shell_init();
|
||||
if (__shell_is_init == __SHELL_INIT_OK)
|
||||
{
|
||||
size_t written_bytes = 0;
|
||||
if (len > sizeof(__shell_shm->data) - 1)
|
||||
{
|
||||
shell_write_string(s, sizeof(__shell_shm->data) - 1); // Outputs as much as it can.
|
||||
shell_write_string(s + (sizeof(__shell_shm->data) - 1), len - (sizeof(__shell_shm->data) - 1)); // Outputs the rest.
|
||||
written_bytes += shell_write_string(s, sizeof(__shell_shm->data) - 1); // Outputs as much as it can.
|
||||
written_bytes += shell_write_string(s + (sizeof(__shell_shm->data) - 1), len - (sizeof(__shell_shm->data) - 1)); // Outputs the rest.
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(__shell_shm->data, 0, sizeof(__shell_shm->data)); // without int shell show \t, \n, lose chars and other trash
|
||||
memcpy(__shell_shm->data, s, len);
|
||||
memset(__shell_shm->data, 0, sizeof(__shell_shm->data)); // without int shell show \t, \n, lose chars and other trash
|
||||
memcpy(__shell_shm->data, s, len);
|
||||
__shell_shm->cmd = SHELL_PUTS;
|
||||
__SHELL_WAIT();
|
||||
written_bytes += __shell_shm->return_value.written_bytes;
|
||||
}
|
||||
|
||||
return written_bytes;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -31,9 +31,15 @@ enum __SHELL_INIT_STATE {
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct return_value {
|
||||
size_t written_bytes;
|
||||
char* str;
|
||||
};
|
||||
|
||||
struct shell_shm_buffer {
|
||||
uint8_t cmd;
|
||||
char data[SHELL_SHM_MAX - sizeof(((struct shell_shm_buffer*)NULL)->cmd)];
|
||||
char data[SHELL_SHM_MAX - sizeof(((struct shell_shm_buffer*)NULL)->cmd) - sizeof(struct return_value)];
|
||||
struct return_value return_value;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
@@ -51,14 +57,14 @@ __EXTERN int shell_ping();
|
||||
__EXTERN unsigned shell_get_pid();
|
||||
__EXTERN void shell_exit();
|
||||
|
||||
__EXTERN char shell_getc();
|
||||
__EXTERN void shell_gets(char* str, int n);
|
||||
__EXTERN int shell_getc();
|
||||
__EXTERN char* shell_gets(char* str, int n);
|
||||
|
||||
__EXTERN void shell_putc(char c);
|
||||
__EXTERN void shell_puts(const char* str);
|
||||
__EXTERN void shell_printf(const char* format, ...);
|
||||
__EXTERN size_t shell_puts(const char* str);
|
||||
__EXTERN int shell_printf(const char* format, ...);
|
||||
|
||||
__EXTERN void shell_write_string(const char* s, size_t len);
|
||||
__EXTERN size_t shell_write_string(const char* s, size_t len);
|
||||
|
||||
__EXTERN void shell_cls();
|
||||
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
DLLAPI int puts(const char* str);
|
||||
DLLAPI int printf(const char* format, ...);
|
||||
@@ -50,15 +52,23 @@ typedef size_t fpos_t;
|
||||
#define _FILEMODE_R 1 << 0 // Read
|
||||
#define _FILEMODE_W 1 << 1 // Write
|
||||
#define _FILEMODE_A 1 << 2 // Append
|
||||
#define _FILEMODE_PLUS 1 << 3 // Plus
|
||||
#define _FILEFLAG_ERR 1 << 3 // Error
|
||||
#define _FILEFLAG_EOF 1 << 4 // EOF
|
||||
|
||||
typedef struct FILE_s {
|
||||
char* name;
|
||||
fpos_t position;
|
||||
int error;
|
||||
int eof;
|
||||
int mode; // flags _FILEMODE_*
|
||||
int __ungetc_emu_buff; // Uses __ungetc_emu (temporary solution!)
|
||||
union {
|
||||
struct {
|
||||
bool read : 1;
|
||||
bool write : 1;
|
||||
bool append : 1;
|
||||
bool error : 1;
|
||||
bool eof : 1;
|
||||
};
|
||||
uint32_t val; // exist just because tcc won't optimize bitfields
|
||||
} flags;
|
||||
} FILE;
|
||||
|
||||
#define _IOFBF 0
|
||||
@@ -82,7 +92,7 @@ typedef struct FILE_s {
|
||||
#define TMP_MAX FOPEN_MAX
|
||||
|
||||
#define stderr (FILE*)3
|
||||
#define stdin (FILE*)1
|
||||
#define stdin (FILE*)1
|
||||
#define stdout (FILE*)2
|
||||
|
||||
DLLAPI int fgetc(FILE*);
|
||||
|
||||
@@ -61,6 +61,8 @@
|
||||
/* strntold() is used by vsscanf() below; include its definition first */
|
||||
#include "stdlib/strntold.c"
|
||||
#include "stdio/vsscanf.c"
|
||||
#include "stdio/fclose_r.c"
|
||||
#include "stdio/fopen_r.c"
|
||||
|
||||
#include "string/memccpy.c"
|
||||
#include "string/memchr.c"
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
#ifndef __LIBC_STDIO_H
|
||||
#define __LIBC_STDIO_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int fclose_r(FILE* stream);
|
||||
FILE* fopen_r(const char* restrict name, const char* restrict mode, FILE* restrict stream);
|
||||
|
||||
#endif // __LIBC_STDIO_H
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <stdio.h>
|
||||
|
||||
void clearerr(FILE *stream) {
|
||||
stream->error = 0;
|
||||
stream->eof = 0;
|
||||
void clearerr(FILE* stream)
|
||||
{
|
||||
stream->flags.val &= ~(_FILEFLAG_ERR | _FILEFLAG_EOF);
|
||||
}
|
||||
@@ -1,8 +1,15 @@
|
||||
#include "stddef.h"
|
||||
#include "_stdio.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int fclose(FILE *stream) {
|
||||
int fclose(FILE* stream)
|
||||
{
|
||||
int err = fclose_r(stream);
|
||||
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
free(stream);
|
||||
stream = NULL;
|
||||
return 0;
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "_stdio.h"
|
||||
|
||||
int fclose_r(FILE* stream)
|
||||
{
|
||||
if (stream->name) {
|
||||
free(stream->name);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int feof(FILE *stream) {
|
||||
return stream->eof;
|
||||
int feof(FILE* stream)
|
||||
{
|
||||
return stream->flags.eof;
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int ferror(FILE *stream) {
|
||||
return stream->error;
|
||||
int ferror(FILE* stream)
|
||||
{
|
||||
return stream->flags.error;
|
||||
}
|
||||
@@ -1,7 +1,22 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include "_stdio.h"
|
||||
|
||||
FILE *fopen(const char *restrict _name, const char *restrict _mode) {
|
||||
FILE *out = malloc(sizeof(FILE));
|
||||
return freopen(_name, _mode, out);
|
||||
FILE* fopen(const char* restrict _name, const char* restrict _mode)
|
||||
{
|
||||
FILE* stream = malloc(sizeof(FILE));
|
||||
|
||||
if (stream == NULL) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FILE* out = fopen_r(_name, _mode, stream);
|
||||
|
||||
if (out == NULL) {
|
||||
free(stream);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
#include "_stdio.h"
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/ksys.h>
|
||||
#include <sys/dirent.h>
|
||||
|
||||
/*
|
||||
Open new file
|
||||
*/
|
||||
FILE* fopen_r(const char* restrict _name, const char* restrict _mode, FILE* restrict out)
|
||||
{
|
||||
if (!_name || !_mode || !out) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool file_not_exits = false;
|
||||
ksys_bdfe_t info;
|
||||
{
|
||||
int err = _ksys_file_get_info(_name, &info);
|
||||
|
||||
switch (err) {
|
||||
case KSYS_FS_ERR_SUCCESS:
|
||||
|
||||
if (info.attributes & IS_FOLDER) {
|
||||
errno = EISDIR;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
break;
|
||||
case KSYS_FS_ERR_5:
|
||||
file_not_exits = true;
|
||||
break;
|
||||
default:
|
||||
errno = err;
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
out->flags.val = 0;
|
||||
out->position = 0;
|
||||
out->name = strdup(_name);
|
||||
|
||||
if (strchr(_mode, 'r')) {
|
||||
out->flags.read = true;
|
||||
|
||||
if (file_not_exits) {
|
||||
errno = ENOENT;
|
||||
free(out->name);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (strchr(_mode, 'w')) {
|
||||
out->flags.write = true;
|
||||
}
|
||||
if (strchr(_mode, 'a')) {
|
||||
out->flags.val |= _FILEMODE_W | _FILEMODE_A;
|
||||
}
|
||||
if (strchr(_mode, '+')) {
|
||||
out->flags.val |= _FILEMODE_R | _FILEMODE_W;
|
||||
}
|
||||
|
||||
if (out->flags.write) {
|
||||
if (file_not_exits) {
|
||||
int err = _ksys_file_create(_name);
|
||||
if (err != KSYS_FS_ERR_SUCCESS) {
|
||||
errno = err;
|
||||
free(out->name);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (out->flags.append) {
|
||||
out->position = info.size;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
@@ -14,7 +14,7 @@ size_t fread(void *restrict ptr, size_t size, size_t nmemb, FILE *restrict strea
|
||||
|
||||
if(size<=0 || nmemb<=0){
|
||||
errno = EINVAL;
|
||||
stream->error=errno;
|
||||
stream->flags.error = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ size_t fread(void *restrict ptr, size_t size, size_t nmemb, FILE *restrict strea
|
||||
return nmemb;
|
||||
}
|
||||
|
||||
if(stream->mode != _FILEMODE_W && stream->mode != _FILEMODE_A){
|
||||
if(stream->flags.read){
|
||||
if(!stream->__ungetc_emu_buff){
|
||||
((char*) ptr)[0]=(char)stream->__ungetc_emu_buff;
|
||||
//debug_printf("Ungetc: %x\n", ((char*) ptr)[0]);
|
||||
@@ -31,10 +31,10 @@ size_t fread(void *restrict ptr, size_t size, size_t nmemb, FILE *restrict strea
|
||||
unsigned status = _ksys_file_read_file(stream->name, stream->position, bytes_count, ptr , &bytes_read);
|
||||
if (status != KSYS_FS_ERR_SUCCESS) {
|
||||
if(status == KSYS_FS_ERR_EOF){
|
||||
stream->eof=1;
|
||||
stream->flags.eof = true;
|
||||
}else{
|
||||
errno = EIO;
|
||||
stream->error = errno;
|
||||
stream->flags.error = true;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,62 +1,14 @@
|
||||
#include <stddef.h>
|
||||
#include <sys/ksys.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/dirent.h>
|
||||
#include "_stdio.h"
|
||||
|
||||
FILE* freopen(const char* restrict _name, const char* restrict _mode, FILE* restrict out)
|
||||
{
|
||||
fclose_r(out);
|
||||
|
||||
static FILE* _set_errno(FILE *out, int err){
|
||||
errno = err;
|
||||
if(out){
|
||||
free(out->name);
|
||||
free(out);
|
||||
if (_name == NULL) {
|
||||
_name = out->name;
|
||||
}
|
||||
out = NULL;
|
||||
return out;
|
||||
|
||||
return fopen_r(_name, _mode, out);
|
||||
}
|
||||
|
||||
static void _create_file(char *name, FILE *out){
|
||||
if(_ksys_file_create(name)){
|
||||
_set_errno(out, EIO);
|
||||
}
|
||||
}
|
||||
|
||||
FILE *freopen(const char *restrict _name, const char *restrict _mode, FILE *restrict out) {
|
||||
if(!_name || !_mode || !out){
|
||||
return _set_errno(out, EINVAL);
|
||||
}
|
||||
|
||||
ksys_bdfe_t info;
|
||||
int no_file = _ksys_file_get_info(_name, &info);
|
||||
if(!no_file && info.attributes & IS_FOLDER){
|
||||
return _set_errno(out, EISDIR);
|
||||
}
|
||||
|
||||
out->eof=0;
|
||||
out->error=0;
|
||||
out->position=0;
|
||||
out->name = strdup(_name);
|
||||
|
||||
if (strchr(_mode, 'r')) { out->mode = _FILEMODE_R; }
|
||||
if (strchr(_mode, 'w')) { out->mode = _FILEMODE_W; }
|
||||
if (strchr(_mode, 'a')) { out->mode = _FILEMODE_A; }
|
||||
if (strchr(_mode, '+')) { out->mode |= _FILEMODE_PLUS; }
|
||||
|
||||
if(out->mode & _FILEMODE_A){
|
||||
if(no_file){
|
||||
_create_file(out->name, out);
|
||||
}
|
||||
out->position = info.size;
|
||||
}else if(out->mode & _FILEMODE_W){
|
||||
_create_file(out->name, out);
|
||||
}else if((out->mode & _FILEMODE_R)){
|
||||
if(no_file){
|
||||
_set_errno(out, ENOENT);
|
||||
}
|
||||
}else{
|
||||
_set_errno(out, EINVAL);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
@@ -1,18 +1,19 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/ksys.h>
|
||||
|
||||
int fseek(FILE *stream, long int offset, int whence) {
|
||||
if (whence == SEEK_SET) {
|
||||
stream->position = offset;
|
||||
} else if (whence == SEEK_CUR) {
|
||||
stream->position += offset;
|
||||
} else if (whence == SEEK_END) {
|
||||
ksys_bdfe_t info;
|
||||
if (_ksys_file_get_info(stream->name, &info)) {
|
||||
return -1;
|
||||
}
|
||||
stream->position = info.size + offset;
|
||||
}
|
||||
stream->eof = 0;
|
||||
int fseek(FILE* stream, long int offset, int whence)
|
||||
{
|
||||
if (whence == SEEK_SET) {
|
||||
stream->position = offset;
|
||||
} else if (whence == SEEK_CUR) {
|
||||
stream->position += offset;
|
||||
} else if (whence == SEEK_END) {
|
||||
ksys_bdfe_t info;
|
||||
if (_ksys_file_get_info(stream->name, &info)) {
|
||||
return -1;
|
||||
}
|
||||
stream->position = info.size + offset;
|
||||
}
|
||||
stream->flags.eof = false;
|
||||
return 0;
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int fsetpos(FILE *stream, const fpos_t *pos) {
|
||||
int fsetpos(FILE* stream, const fpos_t* pos)
|
||||
{
|
||||
stream->position = *pos;
|
||||
stream->eof = 0;
|
||||
stream->flags.eof = false;
|
||||
return 0;
|
||||
}
|
||||
@@ -16,7 +16,7 @@ size_t fwrite(const void* restrict ptr, size_t size, size_t nmemb, FILE* restric
|
||||
|
||||
if (size <= 0 || nmemb <= 0) {
|
||||
errno = EINVAL;
|
||||
stream->error = errno;
|
||||
stream->flags.error = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -33,11 +33,11 @@ size_t fwrite(const void* restrict ptr, size_t size, size_t nmemb, FILE* restric
|
||||
return nmemb;
|
||||
}
|
||||
|
||||
if (stream->mode != _FILEMODE_R) {
|
||||
if (stream->flags.write) {
|
||||
unsigned status = _ksys_file_write_file(stream->name, stream->position, bytes_count, ptr, &bytes_written);
|
||||
if (status != KSYS_FS_ERR_SUCCESS) {
|
||||
errno = EIO;
|
||||
stream->error = errno;
|
||||
stream->flags.error = true;
|
||||
return 0;
|
||||
}
|
||||
stream->position += bytes_written;
|
||||
|
||||
@@ -6,22 +6,21 @@ int ungetc(int c, FILE* file)
|
||||
{
|
||||
int res;
|
||||
|
||||
if(!file){
|
||||
errno = EBADF;
|
||||
return EOF;
|
||||
}
|
||||
|
||||
if (file->mode != _FILEMODE_R){
|
||||
errno = EACCES;
|
||||
return EOF;
|
||||
}
|
||||
|
||||
if (file->position == 0 || c == EOF)
|
||||
{
|
||||
errno = EOF;
|
||||
if (!file) {
|
||||
errno = EBADF;
|
||||
return EOF;
|
||||
}
|
||||
|
||||
|
||||
if (!file->flags.read) {
|
||||
errno = EACCES;
|
||||
return EOF;
|
||||
}
|
||||
|
||||
if (file->position == 0 || c == EOF) {
|
||||
errno = EOF;
|
||||
return EOF;
|
||||
}
|
||||
|
||||
file->__ungetc_emu_buff = c;
|
||||
file->position--;
|
||||
return c;
|
||||
|
||||
@@ -1618,21 +1618,23 @@ endl
|
||||
|
||||
; Open a new TCP socket
|
||||
mcall socket, AF_INET4, SOCK_STREAM, 0
|
||||
test eax, eax
|
||||
jz .error3
|
||||
cmp eax, -1
|
||||
je .error3
|
||||
mov [socketnum], eax
|
||||
DEBUGF 1, "Socket: 0x%x\n", eax
|
||||
|
||||
; Connect to the server
|
||||
mcall connect, [socketnum], [sockaddr], 18
|
||||
test eax, eax
|
||||
jnz .error3
|
||||
jnz .error4
|
||||
DEBUGF 1, "Socket is now connected.\n"
|
||||
|
||||
invoke freeaddrinfo ; Free allocated memory
|
||||
mov eax, [socketnum]
|
||||
ret
|
||||
|
||||
.error4:
|
||||
mcall close, [socketnum]
|
||||
.error3:
|
||||
DEBUGF 2, "Could not connect to the remote server\n"
|
||||
invoke freeaddrinfo ; Free allocated memory
|
||||
|
||||
@@ -501,7 +501,8 @@ img.decode.jpg:
|
||||
jnz .no_create_palette
|
||||
push ecx edi
|
||||
mov edi, [eax + Image.Palette]
|
||||
xor eax, eax
|
||||
mov eax, 0xFF000000 ; opaque, like the palettes of the other decoders:
|
||||
; converted to 32 bpp, alpha 0 made the picture invisible
|
||||
mov ecx, 256
|
||||
@@:
|
||||
stosd
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
format MS COFF
|
||||
public EXPORTS
|
||||
include '../../../KOSfuncs.inc'
|
||||
section '.flat' code readable align 16
|
||||
; void __stdcall START(dword state);
|
||||
DLL_ENTRY equ 1
|
||||
@@ -60,6 +61,7 @@ START:
|
||||
; SORT_BY_ACCESSED = 12, SORT_BY_ACCESSED_REV = 13 };
|
||||
; int __stdcall sort_dir(BDFE* folder_data, unsigned num_folder_entries, sort_mode mode);
|
||||
; return: 0 = ok, 1 = error
|
||||
align 4
|
||||
sort_dir:
|
||||
cmp dword [esp+12], num_compare_fns
|
||||
jae .error
|
||||
@@ -73,9 +75,9 @@ sort_dir:
|
||||
jz .done
|
||||
cmp eax, ecx
|
||||
jae .memok
|
||||
push 68
|
||||
push SF_SYS_MISC
|
||||
pop eax
|
||||
push 12
|
||||
push SSF_MEM_ALLOC
|
||||
pop ebx
|
||||
int 0x40
|
||||
test eax, eax
|
||||
@@ -103,6 +105,8 @@ sort_dir:
|
||||
pop ecx
|
||||
mov ebx, edx
|
||||
sub esp, 304
|
||||
cld
|
||||
align 4
|
||||
.moveloop:
|
||||
mov esi, [ebx]
|
||||
test esi, esi
|
||||
@@ -139,9 +143,9 @@ sort_dir:
|
||||
.done_free:
|
||||
cmp edx, ptr_table
|
||||
jz .done
|
||||
push 68
|
||||
push SF_SYS_MISC
|
||||
pop eax
|
||||
push 13
|
||||
push SSF_MEM_FREE
|
||||
pop ebx
|
||||
mov ecx, edx
|
||||
int 0x40
|
||||
@@ -269,6 +273,7 @@ compare_name_rev:
|
||||
stc
|
||||
ret
|
||||
|
||||
align 4
|
||||
strcmpi:
|
||||
push eax
|
||||
@@:
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
|
||||
HISTORY:
|
||||
|
||||
4.1.1 (18/09/2026, Leency)
|
||||
bug-fixes:
|
||||
- fixed crash on deleting the whole text (Ctrl+A, Del)
|
||||
|
||||
4.1 (17/07/2015, Pathoswithin)
|
||||
- various fixes
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
; project name: TINYPAD
|
||||
; compiler: flat assembler 1.67.21
|
||||
; memory to compile: 3.0/9.0 MBytes (without/with size optimizations)
|
||||
; version: SVN (4.1)
|
||||
; last update: 2015-07-17 (Jul 17, 2015)
|
||||
; version: SVN (4.1.1)
|
||||
; last update: 2026-09-18 (Sep 18, 2026)
|
||||
; minimal kernel: revision #4199 (https://git.kolibrios.org/KolibriOS/kolibrios/src/branch/main/kernel/trunk)
|
||||
;-----------------------------------------------------------------------------
|
||||
; originally by: Ville Michael Turjanmaa >> villemt@aton.co.jyu.fi
|
||||
@@ -40,7 +40,7 @@ include 'tinypad.inc'
|
||||
|
||||
__header '01',1,@CODE,TINYPAD_END,STATIC_MEM_END,MAIN_STACK,@PARAMS,ini_path
|
||||
|
||||
APP_VERSION equ '4.1'
|
||||
APP_VERSION equ '4.1.1'
|
||||
|
||||
TRUE = 1
|
||||
FALSE = 0
|
||||
|
||||
@@ -355,7 +355,7 @@ proc line_add_spaces ;////////////////////////////////////////////////////////
|
||||
; ESI = line offset
|
||||
; ECX = needed line length
|
||||
; Output:
|
||||
; EAX = delta
|
||||
; EAX = delta, CF = 1 on failure
|
||||
;-----------------------------------------------------------------------------
|
||||
xor eax,eax
|
||||
pushad
|
||||
@@ -365,6 +365,7 @@ proc line_add_spaces ;////////////////////////////////////////////////////////
|
||||
sub ecx,edx
|
||||
lea eax,[ecx+sizeof.EDITOR_LINE_DATA]
|
||||
call editor_realloc_lines
|
||||
jc .failed
|
||||
mov [esp+4*7],eax
|
||||
add esi,eax
|
||||
push ecx
|
||||
@@ -388,6 +389,26 @@ proc line_add_spaces ;////////////////////////////////////////////////////////
|
||||
rep stosb
|
||||
.exit:
|
||||
popad
|
||||
clc
|
||||
ret
|
||||
.failed:
|
||||
popad
|
||||
stc
|
||||
ret
|
||||
endp
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
proc set_lines_terminator ;///////////////////////////////////////////////////
|
||||
;-----------------------------------------------------------------------------
|
||||
; Lines buffer is terminated by a line header with zero Size, restore it after
|
||||
; the data has been compacted (line count decreased)
|
||||
;-----------------------------------------------------------------------------
|
||||
push ecx esi
|
||||
mov ecx,[cur_editor.Lines.Count]
|
||||
call get_line_offset
|
||||
mov [esi+EDITOR_LINE_DATA.Size],0
|
||||
mov [esi+EDITOR_LINE_DATA.Flags],0
|
||||
pop esi ecx
|
||||
ret
|
||||
endp
|
||||
|
||||
@@ -408,6 +429,7 @@ proc delete_selection ;///////////////////////////////////////////////////////
|
||||
or [esi+EDITOR_LINE_DATA.Flags],EDITOR_LINE_FLAG_MOFIFIED
|
||||
mov ecx,[sel.begin.x]
|
||||
call line_add_spaces
|
||||
jc .abort
|
||||
add esi,eax
|
||||
lea edi,[esi+sizeof.EDITOR_LINE_DATA]
|
||||
mov ecx,[sel.end.y]
|
||||
@@ -456,6 +478,8 @@ proc delete_selection ;///////////////////////////////////////////////////////
|
||||
rep movsb
|
||||
|
||||
.exit:
|
||||
call set_lines_terminator
|
||||
|
||||
mov eax,[sel.begin.x]
|
||||
mov [cur_editor.Caret.X],eax
|
||||
mov [cur_editor.SelStart.X],eax
|
||||
@@ -478,6 +502,11 @@ proc delete_selection ;///////////////////////////////////////////////////////
|
||||
clc
|
||||
ret
|
||||
|
||||
.abort:
|
||||
popad
|
||||
clc
|
||||
ret
|
||||
|
||||
.exit.2:
|
||||
stc
|
||||
ret
|
||||
|
||||
@@ -993,17 +993,30 @@ endp
|
||||
proc editor_realloc_lines ;///// ADD $DELTA$ TO LINES SIZE ///////////////////
|
||||
;-----------------------------------------------------------------------------
|
||||
; EAX = delta
|
||||
; Output:
|
||||
; EAX = buffer displacement, CF = 1 on failure (buffer left untouched)
|
||||
;-----------------------------------------------------------------------------
|
||||
push ebx ecx
|
||||
mov ebx,[cur_editor.Lines.Size]
|
||||
push ebx
|
||||
add ebx,eax
|
||||
mov eax,[cur_editor.Lines]
|
||||
mov [cur_editor.Lines.Size],ebx
|
||||
mov ecx,eax
|
||||
stdcall mem.ReAlloc,eax,ebx
|
||||
test eax,eax
|
||||
jz .failed
|
||||
add esp,4
|
||||
mov [cur_editor.Lines],eax
|
||||
sub eax,ecx
|
||||
pop ecx ebx
|
||||
clc
|
||||
ret
|
||||
.failed:
|
||||
pop [cur_editor.Lines.Size]
|
||||
xor eax,eax
|
||||
pop ecx ebx
|
||||
stc
|
||||
ret
|
||||
endp
|
||||
|
||||
|
||||
@@ -237,6 +237,7 @@ proc load_from_memory ;///////////////////////////////////////////////////////
|
||||
lea edx,[ebx+ecx]
|
||||
imul ebx,eax,16
|
||||
add ebx,edx
|
||||
add ebx,sizeof.EDITOR_LINE_DATA
|
||||
mov [ebp+EDITOR.Lines.Size],ebx
|
||||
stdcall mem.ReAlloc,[ebp+EDITOR.Lines],ebx
|
||||
mov [ebp+EDITOR.Lines],eax
|
||||
|
||||
@@ -591,10 +591,12 @@ proc key.ctrl_v ;///// PASTE ///////////////////////////////////
|
||||
mov eax,[copy_size]
|
||||
sub eax,sizeof.EDITOR_LINE_DATA
|
||||
call editor_realloc_lines
|
||||
jc .exit_1
|
||||
mov ecx,[cur_editor.Caret.Y]
|
||||
call get_line_offset
|
||||
mov ecx,[cur_editor.Caret.X]
|
||||
call line_add_spaces
|
||||
jc .exit_1
|
||||
pushd [esi+EDITOR_LINE_DATA.Size]
|
||||
push esi
|
||||
lea eax,[esi+ecx+sizeof.EDITOR_LINE_DATA]
|
||||
@@ -692,6 +694,7 @@ proc key.ctrl_d ;///// INSERT SEPARATOR ////////////////////////
|
||||
;---------------------------------------------------------------
|
||||
mov eax,90+sizeof.EDITOR_LINE_DATA
|
||||
call editor_realloc_lines
|
||||
jc .exit
|
||||
|
||||
mov ecx,[cur_editor.Caret.Y]
|
||||
call get_line_offset
|
||||
@@ -748,6 +751,7 @@ proc key.ctrl_y ;///// DELETE CURRENT LINE /////////////////////
|
||||
shr ecx,2
|
||||
cld
|
||||
rep movsd
|
||||
call set_lines_terminator
|
||||
|
||||
pop eax
|
||||
add eax,sizeof.EDITOR_LINE_DATA
|
||||
@@ -1151,6 +1155,7 @@ proc key.del ;///// DELETE NEXT CHAR OR SELECTION //////////////
|
||||
|
||||
.ok.dec.lines:
|
||||
dec [cur_editor.Lines.Count]
|
||||
call set_lines_terminator
|
||||
mov eax,[cur_editor.Lines.Count]
|
||||
cmp [cur_editor.Caret.Y],eax
|
||||
jb @f
|
||||
@@ -1264,6 +1269,7 @@ proc key.tab ;///// TABULATE ///////////////////////////////////
|
||||
push eax
|
||||
call editor_realloc_lines
|
||||
pop eax
|
||||
jc .failed
|
||||
mov ecx,[cur_editor.Caret.Y]
|
||||
call get_line_offset
|
||||
and [esi+EDITOR_LINE_DATA.Flags],not EDITOR_LINE_FLAG_SAVED
|
||||
@@ -1282,6 +1288,7 @@ proc key.tab ;///// TABULATE ///////////////////////////////////
|
||||
push eax
|
||||
mov eax,10
|
||||
call editor_realloc_lines
|
||||
jc .failed.1
|
||||
add esi,eax
|
||||
pop eax
|
||||
pushad
|
||||
@@ -1332,6 +1339,12 @@ proc key.tab ;///// TABULATE ///////////////////////////////////
|
||||
|
||||
.exit:
|
||||
ret
|
||||
|
||||
.failed.1:
|
||||
pop eax
|
||||
.failed:
|
||||
add esp,4*2
|
||||
ret
|
||||
endp
|
||||
|
||||
;---------------------------------------------------------------
|
||||
@@ -1342,6 +1355,7 @@ proc key.return ;///// CARRIAGE RETURN /////////////////////////
|
||||
; so you should do a little more value
|
||||
mov eax,14*100
|
||||
call editor_realloc_lines
|
||||
jc .exit
|
||||
|
||||
mov ecx,[cur_editor.Caret.Y]
|
||||
call get_line_offset
|
||||
|
||||
@@ -51,6 +51,7 @@ include '../../load_lib.mac'
|
||||
include '../../dll.inc'
|
||||
include '../../develop/libraries/libs-dev/libio/libio.inc'
|
||||
include '../../develop/libraries/libs-dev/libimg/libimg.inc'
|
||||
include '../../develop/libraries/box_lib/box_lib.mac'
|
||||
;include '../../debug.inc'
|
||||
|
||||
@use_library mem.Alloc,mem.Free,mem.ReAlloc,dll.Load
|
||||
@@ -63,15 +64,16 @@ ci_offs_skin_w equ 5 ;adjustment to the width of the skin frame
|
||||
ci_offs_skin_h equ 24 ;skin height adjustment
|
||||
|
||||
; main window
|
||||
ci_wnd_min_siz_x equ 585 ;minimum size x
|
||||
ci_wnd_min_siz_y equ 400 ;minimum size y
|
||||
ci_wnd_start_siz_x equ 585
|
||||
ci_wnd_start_siz_y equ 400
|
||||
ci_wnd_min_siz_x equ 510 ;minimum size x
|
||||
ci_wnd_min_siz_y equ 180 ;minimum size y
|
||||
|
||||
; toolbar
|
||||
ci_panel_x_pos equ 0 ;coord. x for panel
|
||||
ci_panel_y_pos equ 20 ;coord. y for panel
|
||||
ci_panel_but_y1 equ ci_panel_y_pos +5 ;y coordinate for 1st row of buttons
|
||||
ci_panel_but_y2 equ ci_panel_y_pos+30 ;y coordinate for 2nd row of buttons
|
||||
ci_palete_y_pos equ ci_panel_y_pos+51 ;y coordinate for color palette
|
||||
ci_panel_zoom_x equ 178 ;x coordinate for zoom bar buttons
|
||||
|
||||
; editor window
|
||||
@@ -80,7 +82,7 @@ ci_edit_wnd_y_pos equ 71 ;y coordinate for editor window
|
||||
ci_edit_wnd_border equ 3 ;frame around the editor window
|
||||
|
||||
; scrolling
|
||||
ci_scroll_dim equ 22 ;scroll sizes
|
||||
ci_scroll_dim equ 16 ;scroll sizes
|
||||
ci_scrollh_coord_x_min equ (ci_edit_wnd_x_pos+3) ;x minimum slider position
|
||||
;horizontal scrolling
|
||||
ci_scrollv_coord_y_min equ (ci_edit_wnd_y_pos+3) ;y minimum slider position
|
||||
@@ -149,6 +151,12 @@ include 'init_data.inc'
|
||||
;OpenDialog initialisation
|
||||
stdcall [OpenDialog_Init], OpenDialog_data
|
||||
stdcall [ColorDialog_Init], ColorDialog_data
|
||||
|
||||
mcall SF_REDRAW,SSF_BEGIN_DRAW
|
||||
mov ebx,50 shl 16 + ci_wnd_start_siz_x
|
||||
mov ecx,50 shl 16 + ci_wnd_start_siz_y
|
||||
mcall SF_CREATE_WINDOW,,,0x73aabbcc,,name_of_program
|
||||
mcall SF_REDRAW,SSF_END_DRAW
|
||||
;---------------------------------------------------------------------
|
||||
|
||||
align 4
|
||||
@@ -161,16 +169,16 @@ align 4
|
||||
still:
|
||||
mcall SF_WAIT_EVENT
|
||||
|
||||
cmp eax,1
|
||||
cmp eax,EV_REDRAW
|
||||
je red
|
||||
|
||||
cmp eax,2
|
||||
cmp eax,EV_KEY
|
||||
je keys
|
||||
|
||||
cmp eax,3
|
||||
cmp eax,EV_BUTTON
|
||||
je buttons
|
||||
|
||||
cmp eax,6
|
||||
cmp eax,EV_MOUSE
|
||||
je mouse
|
||||
|
||||
jmp still
|
||||
@@ -186,7 +194,16 @@ copy_str_1:
|
||||
jnz @b
|
||||
ret
|
||||
;---------------------------------------------------------------------
|
||||
include 'events.inc'
|
||||
;description:
|
||||
; move both scrollbars back to the top left corner (0,0)
|
||||
align 4
|
||||
scrollbar_move_00:
|
||||
and [PosX],0
|
||||
and [PosY],0
|
||||
mov [sb_horizont.position],0
|
||||
mov [sb_vertical.position],0
|
||||
ret
|
||||
;---------------------------------------------------------------------
|
||||
include 'events_of_window.inc'
|
||||
include 'events_of_keys.inc'
|
||||
include 'events_of_buttons.inc'
|
||||
@@ -205,7 +222,6 @@ include 'menu.inc'
|
||||
;-----------------------------------------------------------
|
||||
;------------variables and data of program------------------
|
||||
;-----------------------------------------------------------
|
||||
;sound_havent_memory db 150,64,0
|
||||
|
||||
include 'lib_data.inc'
|
||||
include 'panel_data.inc'
|
||||
@@ -240,6 +256,13 @@ spray_cursor:
|
||||
file 'cursors/spray.cur'
|
||||
zoom_cursor:
|
||||
file 'cursors/zoom.cur'
|
||||
|
||||
align 4
|
||||
scroll_drag dd 0
|
||||
sb_horizont scrollbar ci_wnd_start_siz_x-ci_scroll_dim-2*ci_offs_skin_w,0,\
|
||||
ci_scroll_dim,ci_edit_wnd_y_pos+284, 15, 100,30,0, 0xaaaaaa, 0xcccccc,0, 1
|
||||
sb_vertical scrollbar ci_scroll_dim,ci_wnd_start_siz_x-ci_scroll_dim-2*ci_offs_skin_w,\
|
||||
284,ci_edit_wnd_y_pos, 15, 100,30,0, 0xaaaaaa, 0xcccccc,0, 1
|
||||
;----------------------------------------------------------
|
||||
align 4
|
||||
IM_END:
|
||||
@@ -305,20 +328,6 @@ counter2 rd 1
|
||||
number_panel rd 1
|
||||
number_menu rd 1
|
||||
|
||||
Scroll1CoordinatX rd 1 ;scroll x screen position
|
||||
Scroll1CoordinatY rd 1 ;scroll y screen position
|
||||
Scroll1MaxSizeX rd 1
|
||||
Scroll1MaxSizeY rd 1
|
||||
Scroll1SizeX rd 1 ;scroll polzunok size
|
||||
Scroll1FreeX rd 1
|
||||
|
||||
Scroll2CoordinatX rd 1
|
||||
Scroll2CoordinatY rd 1
|
||||
Scroll2MaxSizeX rd 1
|
||||
Scroll2MaxSizeY rd 1
|
||||
Scroll2SizeY rd 1
|
||||
Scroll2FreeY rd 1
|
||||
|
||||
x rd 1
|
||||
y rd 1
|
||||
|
||||
@@ -366,7 +375,7 @@ filename_area rb 256
|
||||
temp_dir_pach rb 4096
|
||||
library_path rb 4096
|
||||
cur_dir_path rb 4096
|
||||
procinfo: rb 1024
|
||||
procinfo process_information
|
||||
align 4
|
||||
syscolors rb 192
|
||||
syscolors_end:
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
;----------------------------------------------------------
|
||||
;---------------------sound of events----------------------
|
||||
;----------------------------------------------------------
|
||||
align 4
|
||||
sound:
|
||||
mcall SF_SPEAKER_PLAY,55
|
||||
ret
|
||||
|
||||
;----------------------------------------------------------
|
||||
;---------------------user events--------------------------
|
||||
;----------------------------------------------------------
|
||||
|
||||
;description:
|
||||
; перемещение скроллингов в левый верхний угол (0,0)
|
||||
align 4
|
||||
scrollbar_move_00:
|
||||
and [PosX],0
|
||||
and [PosY],0
|
||||
mov [Scroll1CoordinatX],ci_scrollh_coord_x_min
|
||||
mov [Scroll2CoordinatY],ci_scrollv_coord_y_min
|
||||
ret
|
||||
@@ -1,17 +1,22 @@
|
||||
;---------------------------------------------
|
||||
;-------------interraction MOUSE--------------
|
||||
;---------------------------------------------
|
||||
align 4
|
||||
mouse:
|
||||
stdcall [kmainmenu_dispatch_cursorevent], [main_menu]
|
||||
|
||||
or ecx,-1
|
||||
mcall SF_THREAD_INFO,procinfo
|
||||
|
||||
mov eax,[procinfo+70] ;staus of window
|
||||
movzx eax,byte [procinfo.wnd_state]
|
||||
test eax,100b
|
||||
jne still
|
||||
|
||||
call GetMouseClick
|
||||
bt [MouseBut],16
|
||||
jnc @f
|
||||
mov [scroll_drag],0
|
||||
@@:
|
||||
|
||||
call GetMouseCoordinats
|
||||
mov eax,[MouseX]
|
||||
@@ -21,6 +26,11 @@ mouse:
|
||||
add ecx,ci_scrollh_coord_x_min
|
||||
add edx,ci_scrollv_coord_y_min
|
||||
|
||||
cmp [scroll_drag],1
|
||||
je sb_hor_mouse
|
||||
cmp [scroll_drag],2
|
||||
je sb_ver_mouse
|
||||
|
||||
cmp eax,ecx
|
||||
jae mouse_scroll
|
||||
|
||||
@@ -36,105 +46,50 @@ mouse_scroll:
|
||||
|
||||
;call GetMouseCoordinats
|
||||
;interraction with horizontal scroller
|
||||
mov eax,[Scroll1CoordinatX]
|
||||
mov ebx,[Scroll1CoordinatY]
|
||||
movzx eax,[sb_horizont.x_pos]
|
||||
movzx ebx,[sb_horizont.y_pos]
|
||||
mov ecx,[MouseX]
|
||||
mov edx,[MouseY]
|
||||
mov esi,[Scroll1MaxSizeX]
|
||||
mov edi,[Scroll1MaxSizeY]
|
||||
movzx esi,[sb_horizont.x_size]
|
||||
movzx edi,[sb_horizont.y_size]
|
||||
call columnus
|
||||
test eax,eax
|
||||
jz no_horizontal
|
||||
|
||||
mov eax,ci_scrollh_coord_x_min
|
||||
mov ebx,[Scroll1CoordinatY]
|
||||
mov ecx,[Scroll1MaxSizeX]
|
||||
inc ecx
|
||||
mov edx,ci_scroll_dim-6
|
||||
mov esi,7
|
||||
call draw_volume_rectangle ; horizontal scrollbar clear
|
||||
|
||||
mov eax,[MouseX]
|
||||
mov ebx,[Scroll1SizeX]
|
||||
shr ebx,1
|
||||
sub eax,ebx
|
||||
mov ecx,[MouseX]
|
||||
add ecx,ebx
|
||||
mov edx,ci_scrollh_coord_x_min
|
||||
add edx,[Scroll1MaxSizeX]
|
||||
mov [Scroll1CoordinatX],eax
|
||||
sub eax,ci_scrollh_coord_x_min
|
||||
jns no_min_scroll
|
||||
|
||||
mov [Scroll1CoordinatX],ci_scrollh_coord_x_min
|
||||
|
||||
no_min_scroll:
|
||||
cmp ecx,edx
|
||||
jl no_max_scroll
|
||||
|
||||
sub edx,ebx
|
||||
sub edx,ebx
|
||||
mov [Scroll1CoordinatX],edx
|
||||
|
||||
no_max_scroll:
|
||||
mov eax,[Scroll1CoordinatX]
|
||||
sub eax,ci_scrollh_coord_x_min
|
||||
bt [MouseBut],8
|
||||
jnc sb_hor_mouse
|
||||
mov [scroll_drag],1
|
||||
sb_hor_mouse:
|
||||
stdcall [scrollbar_h_mouse],sb_horizont
|
||||
mov eax,[sb_horizont.position]
|
||||
mov ebx,[Picture_SizeX]
|
||||
imul eax,ebx
|
||||
mov ebx,[Scroll1MaxSizeX]
|
||||
mov ebx,[sb_horizont.max_area]
|
||||
cdq
|
||||
idiv ebx
|
||||
mov [PosX],eax
|
||||
jmp no_vertical
|
||||
|
||||
no_horizontal:
|
||||
mov eax,[Scroll2CoordinatX]
|
||||
mov ebx,[Scroll2CoordinatY]
|
||||
movzx eax,[sb_vertical.x_pos]
|
||||
movzx ebx,[sb_vertical.y_pos]
|
||||
mov ecx,[MouseX]
|
||||
mov edx,[MouseY]
|
||||
mov esi,[Scroll2MaxSizeX]
|
||||
mov edi,[Scroll2MaxSizeY]
|
||||
movzx esi,[sb_vertical.x_size]
|
||||
movzx edi,[sb_vertical.y_size]
|
||||
call columnus
|
||||
test eax,eax
|
||||
jz no_vertical
|
||||
|
||||
mov eax,[Scroll2CoordinatX]
|
||||
mov ebx,ci_scrollv_coord_y_min
|
||||
mov ecx,ci_scroll_dim-6
|
||||
mov edx,[Scroll2MaxSizeY]
|
||||
inc edx
|
||||
mov esi,7
|
||||
call draw_volume_rectangle ; vertical scrollbar clear
|
||||
|
||||
mov eax,[MouseY]
|
||||
mov ebx,[Scroll2SizeY]
|
||||
shr ebx,1
|
||||
sub eax,ebx
|
||||
mov ecx,[MouseY]
|
||||
add ecx,ebx
|
||||
mov edx,ci_scrollv_coord_y_min
|
||||
add edx,[Scroll2MaxSizeY]
|
||||
mov [Scroll2CoordinatY],eax
|
||||
|
||||
sub eax,ci_scrollv_coord_y_min
|
||||
jns no_min_scroll2
|
||||
|
||||
mov [Scroll2CoordinatY],ci_scrollv_coord_y_min
|
||||
|
||||
no_min_scroll2:
|
||||
cmp ecx,edx
|
||||
jl no_max_scroll2
|
||||
|
||||
sub edx,ebx
|
||||
sub edx,ebx
|
||||
mov [Scroll2CoordinatY],edx
|
||||
|
||||
no_max_scroll2:
|
||||
mov eax,[Scroll2CoordinatY]
|
||||
sub eax,ci_scrollv_coord_y_min
|
||||
bt [MouseBut],8
|
||||
jnc sb_ver_mouse
|
||||
mov [scroll_drag],2
|
||||
sb_ver_mouse:
|
||||
stdcall [scrollbar_v_mouse],sb_vertical
|
||||
mov eax,[sb_vertical.position]
|
||||
mov ebx,[Picture_SizeY]
|
||||
imul eax,ebx
|
||||
mov ebx,[Scroll2MaxSizeY]
|
||||
mov ebx,[sb_vertical.max_area]
|
||||
cdq
|
||||
idiv ebx
|
||||
mov [PosY],eax
|
||||
|
||||
@@ -4,12 +4,11 @@
|
||||
drawwin:
|
||||
or ecx,-1
|
||||
mcall SF_THREAD_INFO,procinfo
|
||||
mov esi,procinfo
|
||||
|
||||
mov eax,[esi+process_information.box.left]
|
||||
mov ebx,[esi+process_information.box.top]
|
||||
mov ecx,[esi+process_information.box.width]
|
||||
mov edx,[esi+process_information.box.height]
|
||||
mov eax,[procinfo.box.left]
|
||||
mov ebx,[procinfo.box.top]
|
||||
mov ecx,[procinfo.box.width]
|
||||
mov edx,[procinfo.box.height]
|
||||
mov [Window_CordinatX],eax
|
||||
mov [Window_CordinatY],ebx
|
||||
|
||||
@@ -23,6 +22,20 @@ drawwin:
|
||||
@@:
|
||||
mov [Window_SizeX],ecx
|
||||
mov [Window_SizeY],edx
|
||||
; keep the size alone for a rolled up window
|
||||
test [procinfo.wnd_state],byte 100b
|
||||
jnz .no_change
|
||||
cmp ecx,[procinfo.box.width]
|
||||
jne @f
|
||||
cmp edx,[procinfo.box.height]
|
||||
jz .no_change
|
||||
@@:
|
||||
push ecx edx esi
|
||||
mov esi,edx
|
||||
mov edx,ecx
|
||||
mcall SF_CHANGE_WINDOW, -1, -1
|
||||
pop esi edx ecx
|
||||
.no_change:
|
||||
mov [MaxWorkScreen_SizeX],ecx
|
||||
mov [MaxWorkScreen_SizeY],edx
|
||||
sub [MaxWorkScreen_SizeX],ci_edit_wnd_x_pos+2*ci_edit_wnd_border\
|
||||
@@ -51,7 +64,7 @@ no_znak2:
|
||||
add ecx, [Window_SizeY]
|
||||
mcall SF_CREATE_WINDOW,,,0x73aabbcc,,name_of_program
|
||||
|
||||
mov eax,[procinfo+70] ;staus of window
|
||||
movzx eax,byte [procinfo.wnd_state]
|
||||
test eax,100b
|
||||
jne .end
|
||||
|
||||
@@ -81,7 +94,7 @@ no_znak2:
|
||||
add ebx,ci_edit_wnd_x_pos+ci_edit_wnd_border
|
||||
mov edx,[Window_SizeX]
|
||||
sub edx,ebx
|
||||
sub edx,ci_scroll_dim+5-ci_edit_wnd_border
|
||||
sub edx,ci_scroll_dim+5+ci_edit_wnd_border
|
||||
shl ebx,16
|
||||
mov bx,dx ;ширина бордюра
|
||||
|
||||
@@ -113,23 +126,6 @@ no_znak2:
|
||||
;------------------------------------------------
|
||||
mcall ,,<ci_edit_wnd_y_pos,ci_edit_wnd_border> ;бордюр под панелью и над окном
|
||||
;------------------------------------------------
|
||||
mov eax,ci_edit_wnd_x_pos
|
||||
mov ebx,[Window_SizeY]
|
||||
mov ecx,[Window_SizeX]
|
||||
mov edx,ci_scroll_dim
|
||||
mov esi,3
|
||||
sub ecx,ci_scroll_dim+5+ci_edit_wnd_x_pos+ci_offs_skin_w
|
||||
sub ebx,ci_scroll_dim+5+ci_offs_skin_h
|
||||
call draw_volume_rectangle ; horizontal scrollbar border
|
||||
;------------------------------------------------
|
||||
mov eax,[Window_SizeX]
|
||||
mov ebx,ci_edit_wnd_y_pos
|
||||
mov ecx,ci_scroll_dim
|
||||
mov edx,[Window_SizeY]
|
||||
mov esi,3
|
||||
sub eax,ci_scroll_dim+5+ci_offs_skin_w
|
||||
sub edx,ci_scroll_dim+5+ci_edit_wnd_y_pos+ci_offs_skin_h
|
||||
call draw_volume_rectangle ; vertical scrollbar border
|
||||
call draw_scrollers
|
||||
;------------------------------------------------
|
||||
mov eax,[Window_SizeX]
|
||||
|
||||
@@ -2,12 +2,14 @@
|
||||
system_dir_1: db '/sys/lib/libimg.obj',0
|
||||
system_dir_2 db '/sys/lib/proc_lib.obj',0
|
||||
system_dir_3: db '/sys/lib/kmenu.obj',0
|
||||
system_dir_4: db '/sys/lib/box_lib.obj',0
|
||||
;---------------------------------------------------------------------
|
||||
align 4
|
||||
l_libs_start:
|
||||
lib1 l_libs system_dir_1+9, library_path, system_dir_1, import_libimg
|
||||
lib2 l_libs system_dir_2+9, library_path, system_dir_2, ProcLib_import
|
||||
lib3 l_libs system_dir_3+9, library_path, system_dir_3, import_libkmenu
|
||||
lib4 l_libs system_dir_4+9, library_path, system_dir_4, import_box_lib
|
||||
end_l_libs:
|
||||
;---------------------------------------------------------------------
|
||||
align 4
|
||||
@@ -79,51 +81,7 @@ colordialog_path:
|
||||
|
||||
path4 db '/sys/noname.bmp',0
|
||||
;---------------------------------------------------------------------
|
||||
align 4
|
||||
import_libimg:
|
||||
dd alib_init1
|
||||
img_is_img dd aimg_is_img
|
||||
img_info dd aimg_info
|
||||
img_from_file dd aimg_from_file
|
||||
img_to_file dd aimg_to_file
|
||||
img_from_rgb dd aimg_from_rgb
|
||||
img_to_rgb dd aimg_to_rgb
|
||||
img_to_rgb2 dd aimg_to_rgb2
|
||||
img_decode dd aimg_decode
|
||||
img_encode dd aimg_encode
|
||||
img_create dd aimg_create
|
||||
img_destroy dd aimg_destroy
|
||||
img_destroy_layer dd aimg_destroy_layer
|
||||
img_count dd aimg_count
|
||||
img_lock_bits dd aimg_lock_bits
|
||||
img_unlock_bits dd aimg_unlock_bits
|
||||
img_flip dd aimg_flip
|
||||
img_flip_layer dd aimg_flip_layer
|
||||
img_rotate dd aimg_rotate
|
||||
img_rotate_layer dd aimg_rotate_layer
|
||||
img_draw dd aimg_draw
|
||||
dd 0,0
|
||||
alib_init1 db 'lib_init',0
|
||||
aimg_is_img db 'img_is_img',0
|
||||
aimg_info db 'img_info',0
|
||||
aimg_from_file db 'img_from_file',0
|
||||
aimg_to_file db 'img_to_file',0
|
||||
aimg_from_rgb db 'img_from_rgb',0
|
||||
aimg_to_rgb db 'img_to_rgb',0
|
||||
aimg_to_rgb2 db 'img_to_rgb2',0
|
||||
aimg_decode db 'img_decode',0
|
||||
aimg_encode db 'img_encode',0
|
||||
aimg_create db 'img_create',0
|
||||
aimg_destroy db 'img_destroy',0
|
||||
aimg_destroy_layer db 'img_destroy_layer',0
|
||||
aimg_count db 'img_count',0
|
||||
aimg_lock_bits db 'img_lock_bits',0
|
||||
aimg_unlock_bits db 'img_unlock_bits',0
|
||||
aimg_flip db 'img_flip',0
|
||||
aimg_flip_layer db 'img_flip_layer',0
|
||||
aimg_rotate db 'img_rotate',0
|
||||
aimg_rotate_layer db 'img_rotate_layer',0
|
||||
aimg_draw db 'img_draw',0
|
||||
include '../../develop/libraries/libs-dev/libimg/import.inc'
|
||||
|
||||
align 4
|
||||
ProcLib_import:
|
||||
@@ -163,4 +121,6 @@ dd 0,0
|
||||
akmenuitem_new db 'kmenuitem_new',0
|
||||
akmenuitem_delete db 'kmenuitem_delete',0
|
||||
akmenuitem_draw db 'kmenuitem_draw',0
|
||||
|
||||
include '../../develop/libraries/box_lib/import.inc'
|
||||
;---------------------------------------------------------------------
|
||||
@@ -1,7 +1,7 @@
|
||||
;**********************************************************
|
||||
;------------------TEXT DATA-------------------------------
|
||||
;**********************************************************
|
||||
name_of_program db 'ANIMAGE graphics editor v1.52',0
|
||||
name_of_program db 'ANIMAGE graphics editor v1.53',0
|
||||
mouse_pos_x db 'X='
|
||||
mouse_pos_y db 'Y='
|
||||
new_text1 db 'PICTURE SIZE X'
|
||||
|
||||
@@ -58,18 +58,16 @@ PrintMousePos:
|
||||
;----------------------------------------------------------
|
||||
;------------draw lines of scoll---------------------------
|
||||
;----------------------------------------------------------
|
||||
align 4
|
||||
draw_scrollers:
|
||||
mov edi,[CounterX]
|
||||
mov eax,[Scroll1CoordinatX]
|
||||
mov ebx,[Window_SizeY]
|
||||
sub ebx,(ci_scroll_dim-3)+5+ci_offs_skin_h
|
||||
sub ebx,ci_scroll_dim+5+ci_offs_skin_h
|
||||
mov ecx,[Window_SizeX]
|
||||
sub ecx,ci_scroll_dim+5+4+ci_scrollh_coord_x_min+ci_offs_skin_w
|
||||
mov edx,ci_scroll_dim-6
|
||||
mov esi,1
|
||||
mov [Scroll1CoordinatY],ebx
|
||||
mov [Scroll1MaxSizeY],edx
|
||||
mov [Scroll1MaxSizeX],ecx
|
||||
sub ecx,ci_scroll_dim+2+ci_scrollh_coord_x_min+ci_offs_skin_w
|
||||
mov [sb_horizont.y_pos],bx
|
||||
mov [sb_horizont.max_area],ecx
|
||||
mov [sb_horizont.x_size],cx
|
||||
imul ecx,edi
|
||||
push eax ebx edx
|
||||
mov eax,ecx
|
||||
@@ -78,22 +76,15 @@ draw_scrollers:
|
||||
idiv ebx
|
||||
mov ecx,eax
|
||||
pop edx ebx eax
|
||||
mov [Scroll1SizeX],ecx
|
||||
mov edi,[Scroll1MaxSizeX]
|
||||
sub edi,ecx
|
||||
mov [Scroll1FreeX],edi
|
||||
call draw_volume_rectangle ; horizontal scrollbar polzunok
|
||||
mov [sb_horizont.cur_area],ecx
|
||||
|
||||
mov eax,[Window_SizeX]
|
||||
sub eax,(ci_scroll_dim-3)+5+ci_offs_skin_w
|
||||
mov ebx,[Scroll2CoordinatY]
|
||||
mov ecx,ci_scroll_dim-6
|
||||
sub eax,ci_scroll_dim+5+ci_offs_skin_w
|
||||
mov edx,[Window_SizeY]
|
||||
sub edx,ci_scroll_dim+5+4+ci_scrollv_coord_y_min+ci_offs_skin_h
|
||||
mov esi,1
|
||||
mov [Scroll2CoordinatX],eax
|
||||
mov [Scroll2MaxSizeX],ecx
|
||||
mov [Scroll2MaxSizeY],edx
|
||||
sub edx,ci_scroll_dim+2+ci_scrollv_coord_y_min+ci_offs_skin_h
|
||||
mov [sb_vertical.x_pos],ax
|
||||
mov [sb_vertical.max_area],edx
|
||||
mov [sb_vertical.y_size],dx
|
||||
|
||||
imul edx,[CounterY]
|
||||
push eax ebx
|
||||
@@ -103,12 +94,12 @@ draw_scrollers:
|
||||
idiv ebx
|
||||
mov edx,eax
|
||||
pop ebx eax
|
||||
mov [Scroll2SizeY],edx
|
||||
mov edi,[Scroll2MaxSizeY]
|
||||
sub edi,edx
|
||||
mov [Scroll2FreeY],edi
|
||||
call draw_volume_rectangle ; vertical scrollbar polzunok
|
||||
mov [sb_vertical.cur_area],edx
|
||||
|
||||
mov [sb_vertical.all_redraw],1
|
||||
stdcall [scrollbar_v_draw],sb_vertical
|
||||
mov [sb_horizont.all_redraw],1
|
||||
stdcall [scrollbar_h_draw],sb_horizont
|
||||
ret
|
||||
|
||||
button_menu_size_x dd 0
|
||||
|
||||
@@ -14,6 +14,7 @@ struct thread_data
|
||||
socketnum dd ? ; Commands socket
|
||||
state dd ? ; disconnected/logging in/logged in/..
|
||||
passivesocknum dd ? ; when in passive mode, this is the listening socket
|
||||
pasv_ports_left dd ? ; ports left to try for the current PASV
|
||||
datasocketnum dd ? ; socket used for data transfers
|
||||
permissions dd ? ; read/write/execute/....
|
||||
buffer_ptr dd ?
|
||||
@@ -136,12 +137,48 @@ socketerror:
|
||||
sendFTP "425 Can't open data connection"
|
||||
ret
|
||||
|
||||
align 4
|
||||
; Close the data socket if this thread currently owns one. datasocketnum only
|
||||
; holds a live socket in these two modes; in any other mode it is a handle that
|
||||
; has already been closed or was never opened.
|
||||
close_data_sock:
|
||||
cmp [ebp + thread_data.mode], MODE_PASSIVE_OK
|
||||
je @f
|
||||
cmp [ebp + thread_data.mode], MODE_ACTIVE
|
||||
jne .done
|
||||
@@:
|
||||
mov [ebp + thread_data.mode], MODE_NOTREADY
|
||||
mcall close, [ebp + thread_data.datasocketnum]
|
||||
mov [ebp + thread_data.datasocketnum], -1
|
||||
.done:
|
||||
ret
|
||||
|
||||
align 4
|
||||
; Close the passive listening socket if one is still open. It is open only
|
||||
; while waiting for the client (MODE_PASSIVE_WAIT, MODE_PASSIVE_FAILED) or after
|
||||
; a failed listen, so no data connection exists and the mode drops to NOTREADY.
|
||||
close_pasv_sock:
|
||||
cmp [ebp + thread_data.passivesocknum], -1
|
||||
je .done
|
||||
mcall close, [ebp + thread_data.passivesocknum]
|
||||
mov [ebp + thread_data.passivesocknum], -1
|
||||
mov [ebp + thread_data.mode], MODE_NOTREADY
|
||||
.done:
|
||||
ret
|
||||
|
||||
align 4
|
||||
; A data transfer failed with the file in ebx open: close the file and the data
|
||||
; socket, then report the error.
|
||||
transfer_error:
|
||||
invoke file.close, ebx
|
||||
call close_data_sock
|
||||
jmp socketerror
|
||||
|
||||
align 4
|
||||
abort_transfer:
|
||||
and [ebp + thread_data.permissions], not ABORT
|
||||
mov [ebp + thread_data.mode], MODE_NOTREADY
|
||||
invoke file.close, ebx
|
||||
mcall close, [ebp + thread_data.datasocketnum]
|
||||
call close_data_sock
|
||||
|
||||
sendFTP "530 Transfer aborted"
|
||||
ret
|
||||
@@ -327,7 +364,7 @@ open_datasock:
|
||||
.pasv_ok:
|
||||
mov [ebp + thread_data.datasocketnum], eax
|
||||
mov [ebp + thread_data.mode], MODE_PASSIVE_OK
|
||||
mcall close ; [ebp + thread_data.passivesocknum]
|
||||
mcall close, [ebp + thread_data.passivesocknum]
|
||||
mov [ebp + thread_data.passivesocknum], -1
|
||||
invoke con_write_asciiz, str_datasock
|
||||
|
||||
@@ -691,13 +728,13 @@ cmdLIST:
|
||||
mcall send
|
||||
|
||||
; close the data socket..
|
||||
mov [ebp + thread_data.mode], MODE_NOTREADY
|
||||
mcall close, [ebp + thread_data.datasocketnum]
|
||||
call close_data_sock
|
||||
|
||||
sendFTP "226 List OK"
|
||||
ret
|
||||
|
||||
.nosuchdir:
|
||||
call close_data_sock
|
||||
sendFTP "550 Directory does not exist"
|
||||
ret
|
||||
|
||||
@@ -793,10 +830,9 @@ cmdPASS:
|
||||
align 4
|
||||
cmdPASV:
|
||||
|
||||
; cmp [ebp + thread_data.passivesocknum], -1
|
||||
; je @f
|
||||
; mcall close, [ebp + thread_data.passivesocknum] ; if there is still a socket open, close it
|
||||
; @@:
|
||||
; Drop whatever data connection the previous PASV/PORT left behind
|
||||
call close_data_sock
|
||||
call close_pasv_sock
|
||||
|
||||
; Open a new TCP socket
|
||||
mcall socket, AF_INET4, SOCK_STREAM, 0
|
||||
@@ -812,7 +848,13 @@ cmdPASV:
|
||||
lea edx, [ebp + thread_data.datasock]
|
||||
mov esi, sizeof.thread_data.datasock
|
||||
|
||||
.next_port: ; TODO: break the endless loop
|
||||
movzx eax, word [pasv_end]
|
||||
movzx ebx, word [pasv_start]
|
||||
sub eax, ebx
|
||||
inc eax
|
||||
mov [ebp + thread_data.pasv_ports_left], eax ; number of ports in the range
|
||||
|
||||
.next_port:
|
||||
call nextpasvport
|
||||
mov ax, [pasv_port]
|
||||
xchg al, ah
|
||||
@@ -820,12 +862,23 @@ cmdPASV:
|
||||
|
||||
mcall bind
|
||||
cmp eax, -1
|
||||
je .next_port
|
||||
jne .bound
|
||||
dec dword [ebp + thread_data.pasv_ports_left] ; only count a port once bind failed
|
||||
jnz .next_port
|
||||
|
||||
; No usable port: the range is exhausted, or listen() refused the bound one.
|
||||
; Give up instead of spinning, and drop the socket before answering 425.
|
||||
.fail:
|
||||
call close_data_sock
|
||||
call close_pasv_sock
|
||||
jmp socketerror
|
||||
|
||||
.bound:
|
||||
|
||||
; And set it to listen!
|
||||
mcall listen, , 1
|
||||
cmp eax, -1
|
||||
je socketerror
|
||||
je .fail
|
||||
|
||||
; Tell our thread we are ready to accept incoming calls
|
||||
mov [ebp + thread_data.mode], MODE_PASSIVE_WAIT
|
||||
@@ -932,6 +985,10 @@ cmdPWD:
|
||||
align 4
|
||||
cmdPORT:
|
||||
|
||||
; Drop whatever data connection the previous PASV/PORT left behind
|
||||
call close_data_sock
|
||||
call close_pasv_sock
|
||||
|
||||
; PORT a1,a2,a3,a4,p1,p2
|
||||
; IP address a1.a2.a3.a4, port p1*256+p2
|
||||
|
||||
@@ -972,7 +1029,8 @@ align 4
|
||||
cmdQUIT:
|
||||
|
||||
sendFTP "221 Bye!"
|
||||
mcall close, [ebp + thread_data.datasocketnum]
|
||||
call close_data_sock
|
||||
call close_pasv_sock
|
||||
mcall close, [ebp + thread_data.socketnum]
|
||||
|
||||
add esp, 4 ; get rid of call return address
|
||||
@@ -1035,7 +1093,7 @@ cmdRETR:
|
||||
lea eax, [ebp + thread_data.buffer] ; FIXME: use another buffer!! if we receive something on control connection now, we screw up!
|
||||
invoke file.read, ebx, eax, BUFFERSIZE
|
||||
cmp eax, -1
|
||||
je .cannot_open ; FIXME: this is not the correct error
|
||||
je .read_error ; FIXME: this is not the correct error
|
||||
|
||||
push eax
|
||||
invoke con_write_asciiz, str2
|
||||
@@ -1049,7 +1107,7 @@ cmdRETR:
|
||||
mcall send
|
||||
pop ebx ecx
|
||||
cmp eax, -1
|
||||
je socketerror ; FIXME: not the correct error
|
||||
je transfer_error ; FIXME: not the correct error
|
||||
|
||||
; cmp eax, ecx
|
||||
; jne not_all_byes_sent ; TODO
|
||||
@@ -1061,13 +1119,15 @@ cmdRETR:
|
||||
|
||||
invoke con_write_asciiz, str2b
|
||||
|
||||
mov [ebp + thread_data.mode], MODE_NOTREADY
|
||||
mcall close, [ebp + thread_data.datasocketnum]
|
||||
call close_data_sock
|
||||
|
||||
sendFTP "226 Transfer OK, closing connection"
|
||||
ret
|
||||
|
||||
.read_error:
|
||||
invoke file.close, ebx
|
||||
.cannot_open:
|
||||
call close_data_sock
|
||||
invoke con_set_flags, 0x0c
|
||||
invoke con_write_asciiz, str_notfound
|
||||
invoke con_set_flags, 0x07
|
||||
@@ -1126,7 +1186,14 @@ cmdSTOR:
|
||||
test eax, eax
|
||||
jz .cannot_open
|
||||
|
||||
; STOR replaces the file: drop the previous, possibly longer contents
|
||||
push eax
|
||||
invoke file.truncate, eax
|
||||
pop ebx
|
||||
test eax, eax
|
||||
js .truncate_error
|
||||
|
||||
push ebx
|
||||
sendFTP "150 Here it comes.."
|
||||
pop ebx
|
||||
|
||||
@@ -1142,7 +1209,7 @@ cmdSTOR:
|
||||
mcall recv
|
||||
pop ebx ecx
|
||||
cmp eax, -1
|
||||
je socketerror ; FIXME: not the correct error
|
||||
je transfer_error ; FIXME: not the correct error
|
||||
|
||||
test eax, eax
|
||||
jz @f
|
||||
@@ -1154,7 +1221,7 @@ cmdSTOR:
|
||||
pop edx
|
||||
|
||||
cmp eax, -1
|
||||
je .cannot_open ; FIXME: this is not the correct error
|
||||
je .write_error ; FIXME: this is not the correct error
|
||||
|
||||
invoke con_write_asciiz, str2
|
||||
|
||||
@@ -1170,8 +1237,7 @@ cmdSTOR:
|
||||
|
||||
invoke con_write_asciiz, str2b
|
||||
|
||||
mov [ebp + thread_data.mode], MODE_NOTREADY
|
||||
mcall close, [ebp + thread_data.datasocketnum]
|
||||
call close_data_sock
|
||||
|
||||
|
||||
|
||||
@@ -1185,10 +1251,20 @@ cmdSTOR:
|
||||
sendFTP "226 Transfer OK"
|
||||
ret
|
||||
|
||||
.write_error:
|
||||
invoke file.close, ebx
|
||||
.cannot_open:
|
||||
call close_data_sock
|
||||
sendFTP "550 No create file"
|
||||
ret
|
||||
|
||||
.truncate_error:
|
||||
invoke file.close, ebx
|
||||
mov [ebp + thread_data.mode], MODE_NOTREADY
|
||||
mcall close, [ebp + thread_data.datasocketnum]
|
||||
sendFTP "550 Cannot truncate file"
|
||||
ret
|
||||
|
||||
;------------------------------------------------
|
||||
; "SYST"
|
||||
;
|
||||
|
||||
@@ -172,6 +172,14 @@ start:
|
||||
invoke ini.get_int, path, str_pasv, str_end, 5000
|
||||
mov [pasv_end], ax
|
||||
|
||||
; an inverted range would leave no port to bind, fall back to the defaults
|
||||
mov ax, [pasv_start]
|
||||
cmp ax, [pasv_end]
|
||||
jbe @f
|
||||
mov word [pasv_start], 2000
|
||||
mov word [pasv_end], 5000
|
||||
@@:
|
||||
|
||||
mov [alive], 1
|
||||
|
||||
mainloop:
|
||||
@@ -237,6 +245,7 @@ end if
|
||||
lea eax, [ebp + thread_data.buffer]
|
||||
mov [ebp + thread_data.buffer_ptr], eax
|
||||
mov [ebp + thread_data.passivesocknum], -1
|
||||
mov [ebp + thread_data.datasocketnum], -1
|
||||
|
||||
sendFTP "220 Welcome to KolibriOS FTP daemon" ; fix output code
|
||||
|
||||
@@ -264,7 +273,7 @@ threadloop:
|
||||
je .not_passive
|
||||
mov [ebp + thread_data.datasocketnum], eax
|
||||
mov [ebp + thread_data.mode], MODE_PASSIVE_OK
|
||||
mcall close ; [ebp + thread_data.passivesocknum]
|
||||
mcall close, [ebp + thread_data.passivesocknum]
|
||||
mov [ebp + thread_data.passivesocknum], -1
|
||||
|
||||
invoke con_write_asciiz, str_datasock
|
||||
@@ -447,6 +456,7 @@ import libio,\
|
||||
file.open, 'file_open',\
|
||||
file.read, 'file_read',\
|
||||
file.write, 'file_write',\
|
||||
file.truncate, 'file_truncate',\
|
||||
file.close, 'file_close',\
|
||||
file.find.first, 'file_find_first',\
|
||||
file.find.next, 'file_find_next',\
|
||||
|
||||
@@ -1,2 +1,5 @@
|
||||
if tup.getconfig("NO_FASM") ~= "" then return end
|
||||
tup.rule("kpack.asm", "fasm %f %o " .. tup.getconfig("KPACK_CMD"), "kpack")
|
||||
-- Native host ports (windowless in-place compressor):
|
||||
tup.rule("kpackw.asm", "fasm %f %o", "kpackw.exe") -- Windows PE
|
||||
tup.rule("kpackl.asm", "fasm %f %o", "kpackl") -- Linux ELF32
|
||||
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
# Build the native Linux port of kpack (windowless, in-place compressor).
|
||||
# Self-contained ELF32 - only FASM is needed, no gcc / no linker.
|
||||
fasm kpackl.asm kpackl
|
||||
chmod +x kpackl
|
||||
@@ -0,0 +1,4 @@
|
||||
@echo off
|
||||
rem Build the native Windows port of kpack (no window, drag-and-drop compressor).
|
||||
rem Requires FASM in PATH (or edit the line below to point at fasm.exe).
|
||||
fasm -m 16384 kpackw.asm kpackw.exe
|
||||
@@ -0,0 +1,795 @@
|
||||
; kpackl = Kolibri Packer, native Linux port (no output, in-place compressor)
|
||||
;
|
||||
; Usage: kpackl <file>
|
||||
; The file is compressed in place (overwritten).
|
||||
; If the file name is "kernel.mnt" it is packed with the "Kernel" option
|
||||
; (self-extracting KERNPACK format), otherwise the normal KPCK format is used.
|
||||
; The program prints nothing; on any problem it just leaves the file alone.
|
||||
;
|
||||
; Self-contained ELF32 using raw Linux int 0x80 syscalls - no libc, no linker.
|
||||
; Compression core (LZMA + calltrick) and the self-extractor stub are the
|
||||
; original KolibriOS kpack sources by diamond; only the OS glue is new.
|
||||
|
||||
format ELF executable 3
|
||||
entry _start
|
||||
|
||||
segment readable writeable executable
|
||||
|
||||
use_lzma = 1
|
||||
use_calltrick1 = 40h
|
||||
use_calltrick2 = 80h
|
||||
|
||||
; Linux i386 syscalls
|
||||
sys_exit = 1
|
||||
sys_read = 3
|
||||
sys_write = 4
|
||||
sys_open = 5
|
||||
sys_close = 6
|
||||
sys_lseek = 19
|
||||
sys_mmap2 = 192
|
||||
|
||||
_start:
|
||||
; ---- get the file argument (argv[1]) ------------------------------
|
||||
mov eax, [esp] ; argc
|
||||
cmp eax, 2
|
||||
jb quit
|
||||
mov esi, [esp+8] ; argv[1]
|
||||
mov [infilename], esi
|
||||
; ---- is the base name "kernel.mnt" ? ------------------------------
|
||||
mov ebx, esi ; ebx = start of base name
|
||||
.bn:
|
||||
mov al, [esi]
|
||||
test al, al
|
||||
jz .bn_done
|
||||
cmp al, '/'
|
||||
jne .bn_n
|
||||
inc esi
|
||||
mov ebx, esi
|
||||
jmp .bn
|
||||
.bn_n:
|
||||
inc esi
|
||||
jmp .bn
|
||||
.bn_done:
|
||||
mov esi, ebx
|
||||
mov edi, kernel_name
|
||||
.cmpk:
|
||||
mov al, [esi]
|
||||
mov ah, [edi]
|
||||
test ah, ah
|
||||
jnz .notend
|
||||
test al, al ; kernel_name ended: match iff input ended too
|
||||
jz do_kerpack
|
||||
jmp do_pack
|
||||
.notend:
|
||||
or al, 20h ; tolower (kernel_name is lowercase)
|
||||
cmp al, ah
|
||||
jne do_pack
|
||||
inc esi
|
||||
inc edi
|
||||
jmp .cmpk
|
||||
|
||||
;=====================================================================
|
||||
; helper: allocate ecx bytes -> eax = ptr, or eax = 0 on failure
|
||||
;=====================================================================
|
||||
alloc:
|
||||
push ebx
|
||||
push edx
|
||||
push esi
|
||||
push edi
|
||||
push ebp
|
||||
mov eax, sys_mmap2
|
||||
xor ebx, ebx ; addr = NULL
|
||||
mov edx, 3 ; PROT_READ|PROT_WRITE
|
||||
mov esi, 22h ; MAP_PRIVATE|MAP_ANONYMOUS
|
||||
or edi, -1 ; fd = -1
|
||||
xor ebp, ebp ; offset = 0
|
||||
int 0x80
|
||||
pop ebp
|
||||
pop edi
|
||||
pop esi
|
||||
pop edx
|
||||
pop ebx
|
||||
cmp eax, 0xFFFFF000 ; -4096..-1 == error
|
||||
jb .ok
|
||||
xor eax, eax
|
||||
.ok:
|
||||
ret
|
||||
|
||||
;=====================================================================
|
||||
; Normal packing (KPCK)
|
||||
;=====================================================================
|
||||
do_pack:
|
||||
; open input (O_RDONLY)
|
||||
mov eax, sys_open
|
||||
mov ebx, [infilename]
|
||||
xor ecx, ecx
|
||||
xor edx, edx
|
||||
int 0x80
|
||||
test eax, eax
|
||||
js quit
|
||||
mov [fd], eax
|
||||
; size = lseek(fd, 0, SEEK_END)
|
||||
mov eax, sys_lseek
|
||||
mov ebx, [fd]
|
||||
xor ecx, ecx
|
||||
mov edx, 2
|
||||
int 0x80
|
||||
test eax, eax
|
||||
jle quit
|
||||
mov [insize], eax
|
||||
; rewind
|
||||
mov eax, sys_lseek
|
||||
mov ebx, [fd]
|
||||
xor ecx, ecx
|
||||
xor edx, edx
|
||||
int 0x80
|
||||
; allocate infile
|
||||
mov ecx, [insize]
|
||||
call alloc
|
||||
test eax, eax
|
||||
jz quit
|
||||
mov [infile], eax
|
||||
; read
|
||||
mov eax, sys_read
|
||||
mov ebx, [fd]
|
||||
mov ecx, [infile]
|
||||
mov edx, [insize]
|
||||
int 0x80
|
||||
; close
|
||||
mov eax, sys_close
|
||||
mov ebx, [fd]
|
||||
int 0x80
|
||||
; maximum output size
|
||||
mov eax, [insize]
|
||||
shr eax, 3
|
||||
add eax, [insize]
|
||||
add eax, 400h
|
||||
mov esi, eax ; esi = maxout (preserved across alloc)
|
||||
add eax, eax
|
||||
mov ecx, eax
|
||||
call alloc
|
||||
test eax, eax
|
||||
jz quit
|
||||
mov [outfile], eax
|
||||
mov [outfile1], eax
|
||||
mov [outfilebest], eax
|
||||
add eax, esi
|
||||
mov [outfile2], eax
|
||||
; KPCK header
|
||||
mov eax, [outfile1]
|
||||
mov dword [eax], 'KPCK'
|
||||
mov ecx, [insize]
|
||||
mov [eax+4], ecx
|
||||
; LZMA dictionary size
|
||||
dec ecx
|
||||
bsr eax, ecx
|
||||
inc eax
|
||||
cmp eax, 28
|
||||
jb @f
|
||||
mov eax, 28
|
||||
@@:
|
||||
push eax
|
||||
push eax
|
||||
call lzma_set_dict_size ; ret 4
|
||||
pop ecx
|
||||
mov eax, 1
|
||||
shl eax, cl
|
||||
; workmem
|
||||
imul eax, 19
|
||||
shr eax, 1
|
||||
add eax, 509000h
|
||||
mov ecx, eax
|
||||
call alloc
|
||||
test eax, eax
|
||||
jz quit
|
||||
mov [workmem], eax
|
||||
; first pass: plain LZMA
|
||||
mov eax, [outfile2]
|
||||
mov [outfile], eax
|
||||
xchg eax, edi
|
||||
mov esi, [outfile1]
|
||||
movsd
|
||||
movsd
|
||||
call pk_pack_lzma
|
||||
mov [outsize], eax
|
||||
mov eax, [outfile]
|
||||
mov [outfilebest], eax
|
||||
mov [method], use_lzma
|
||||
; calltrick 1
|
||||
call pk_preprocess_calltrick
|
||||
test eax, eax
|
||||
jz .noct1
|
||||
call pk_set_outfile
|
||||
call pk_pack_lzma
|
||||
add eax, 5
|
||||
cmp eax, [outsize]
|
||||
jae .noct1
|
||||
mov [outsize], eax
|
||||
mov eax, [outfile]
|
||||
mov [outfilebest], eax
|
||||
mov [method], use_lzma or use_calltrick1
|
||||
.noct1:
|
||||
call pk_set_outfile
|
||||
push dword [ctn]
|
||||
movzx eax, byte [cti]
|
||||
push eax
|
||||
call pk_preprocess_calltrick2
|
||||
test eax, eax
|
||||
jz .noct2
|
||||
call pk_set_outfile
|
||||
call pk_pack_lzma
|
||||
add eax, 5
|
||||
cmp eax, [outsize]
|
||||
jae .noct2
|
||||
mov [outsize], eax
|
||||
mov eax, [outfile]
|
||||
mov [outfilebest], eax
|
||||
mov [method], use_lzma or use_calltrick2
|
||||
pop ecx
|
||||
pop ecx
|
||||
push dword [ctn]
|
||||
movzx eax, byte [cti]
|
||||
push eax
|
||||
.noct2:
|
||||
pop eax
|
||||
mov [cti], al
|
||||
pop eax
|
||||
mov [ctn], eax
|
||||
add dword [outsize], 12
|
||||
mov eax, [outsize]
|
||||
cmp eax, [insize]
|
||||
jb .packed_ok
|
||||
jmp quit ; not smaller: leave original
|
||||
.packed_ok:
|
||||
movzx eax, byte [method]
|
||||
mov edi, [outfilebest]
|
||||
mov [edi+8], eax
|
||||
test al, use_calltrick1 or use_calltrick2
|
||||
jz .save
|
||||
mov ecx, [outsize]
|
||||
add ecx, edi
|
||||
mov eax, [ctn]
|
||||
mov [ecx-5], eax
|
||||
mov al, [cti]
|
||||
mov [ecx-1], al
|
||||
.save:
|
||||
; open(name, O_WRONLY|O_CREAT|O_TRUNC, 0644)
|
||||
mov eax, sys_open
|
||||
mov ebx, [infilename]
|
||||
mov ecx, 0x241
|
||||
mov edx, 0x1A4
|
||||
int 0x80
|
||||
test eax, eax
|
||||
js quit
|
||||
mov [fd], eax
|
||||
mov eax, sys_write
|
||||
mov ebx, [fd]
|
||||
mov ecx, [outfilebest]
|
||||
mov edx, [outsize]
|
||||
int 0x80
|
||||
mov eax, sys_close
|
||||
mov ebx, [fd]
|
||||
int 0x80
|
||||
quit:
|
||||
mov eax, sys_exit
|
||||
xor ebx, ebx
|
||||
int 0x80
|
||||
|
||||
;---------------------------------------------------------------------
|
||||
pk_set_outfile:
|
||||
mov eax, [outfilebest]
|
||||
xor eax, [outfile1]
|
||||
xor eax, [outfile2]
|
||||
mov [outfile], eax
|
||||
ret
|
||||
;---------------------------------------------------------------------
|
||||
pk_pack_lzma:
|
||||
mov eax, [outfile]
|
||||
add eax, 11
|
||||
push [workmem]
|
||||
push [insize]
|
||||
push eax
|
||||
push [infile]
|
||||
call lzma_compress ; ret 16
|
||||
mov ecx, [outfile]
|
||||
mov edx, [ecx+12]
|
||||
bswap edx
|
||||
mov [ecx+12], edx
|
||||
dec eax
|
||||
ret
|
||||
;---------------------------------------------------------------------
|
||||
pk_ct_fail:
|
||||
xor eax, eax
|
||||
mov [ctn], eax
|
||||
ret
|
||||
;---------------------------------------------------------------------
|
||||
pk_preprocess_calltrick:
|
||||
mov ecx, [insize]
|
||||
call alloc
|
||||
test eax, eax
|
||||
jz pk_ct_fail
|
||||
push eax
|
||||
xor eax, eax
|
||||
mov edi, ct1
|
||||
mov ecx, 256/4
|
||||
push edi
|
||||
rep stosd
|
||||
pop edi
|
||||
mov ecx, [insize]
|
||||
mov esi, [infile]
|
||||
xchg eax, edx ; edx = 0
|
||||
pop eax
|
||||
xchg eax, ebx ; ebx = temp buffer
|
||||
push ebx
|
||||
.pre:
|
||||
lodsb
|
||||
sub al, 0E8h
|
||||
cmp al, 1
|
||||
ja .cont
|
||||
cmp ecx, 5
|
||||
jb .done
|
||||
lodsd
|
||||
add eax, esi
|
||||
sub eax, [infile]
|
||||
cmp eax, [insize]
|
||||
jae .xxx
|
||||
cmp eax, 1000000h
|
||||
jae .xxx
|
||||
sub ecx, 4
|
||||
bswap eax
|
||||
mov [esi-4], eax
|
||||
inc edx
|
||||
mov [ebx], esi
|
||||
add ebx, 4
|
||||
jmp .cont
|
||||
.xxx:
|
||||
sub esi, 4
|
||||
movzx eax, byte [esi]
|
||||
mov byte [eax+edi], 1
|
||||
.cont:
|
||||
loop .pre
|
||||
.done:
|
||||
mov [ctn], edx
|
||||
pop edx ; edx = base of temp buffer
|
||||
xor eax, eax
|
||||
mov ecx, 256
|
||||
repnz scasb
|
||||
jnz pk_ct_fail
|
||||
not cl
|
||||
mov [cti], cl
|
||||
@@:
|
||||
cmp ebx, edx
|
||||
jz @f
|
||||
sub ebx, 4
|
||||
mov eax, [ebx]
|
||||
mov [eax-4], cl
|
||||
jmp @b
|
||||
@@:
|
||||
mov al, 1
|
||||
ret
|
||||
;---------------------------------------------------------------------
|
||||
pk_preprocess_calltrick2:
|
||||
; restore input
|
||||
mov esi, [infile]
|
||||
mov ecx, [ctn]
|
||||
jecxz .pre_init
|
||||
.restore:
|
||||
lodsb
|
||||
sub al, 0E8h
|
||||
cmp al, 1
|
||||
ja .restore
|
||||
mov al, [cti]
|
||||
cmp [esi], al
|
||||
jnz .restore
|
||||
lodsd
|
||||
mov al, 0
|
||||
bswap eax
|
||||
sub eax, esi
|
||||
add eax, [infile]
|
||||
mov [esi-4], eax
|
||||
loop .restore
|
||||
.pre_init:
|
||||
mov ecx, [insize]
|
||||
call alloc
|
||||
test eax, eax
|
||||
jz pk_ct_fail
|
||||
mov edi, ct1
|
||||
xchg eax, ebx
|
||||
xor eax, eax
|
||||
push edi
|
||||
mov ecx, 256/4
|
||||
rep stosd
|
||||
pop edi
|
||||
mov ecx, [insize]
|
||||
mov esi, [infile]
|
||||
xchg eax, edx ; edx = 0
|
||||
push ebx
|
||||
.pre:
|
||||
lodsb
|
||||
.chk0f:
|
||||
cmp al, 0Fh
|
||||
jnz .ip1
|
||||
dec ecx
|
||||
jz .done
|
||||
lodsb
|
||||
cmp al, 80h
|
||||
jb .chk0f
|
||||
cmp al, 90h
|
||||
jb .take
|
||||
.ip1:
|
||||
sub al, 0E8h
|
||||
cmp al, 1
|
||||
ja .cont
|
||||
.take:
|
||||
cmp ecx, 5
|
||||
jb .done
|
||||
lodsd
|
||||
add eax, esi
|
||||
sub eax, [infile]
|
||||
cmp eax, [insize]
|
||||
jae .xxx
|
||||
cmp eax, 1000000h
|
||||
jae .xxx
|
||||
sub ecx, 4
|
||||
bswap eax
|
||||
mov [esi-4], eax
|
||||
inc edx
|
||||
mov [ebx], esi
|
||||
add ebx, 4
|
||||
jmp .cont
|
||||
.xxx:
|
||||
sub esi, 4
|
||||
movzx eax, byte [esi]
|
||||
mov byte [eax+edi], 1
|
||||
.cont:
|
||||
loop .pre
|
||||
.done:
|
||||
mov [ctn], edx
|
||||
pop edx
|
||||
xor eax, eax
|
||||
mov ecx, 256
|
||||
repnz scasb
|
||||
jnz pk_ct_fail
|
||||
not cl
|
||||
mov [cti], cl
|
||||
@@:
|
||||
cmp ebx, edx
|
||||
jz @f
|
||||
sub ebx, 4
|
||||
mov eax, [ebx]
|
||||
mov [eax-4], cl
|
||||
jmp @b
|
||||
@@:
|
||||
mov al, 1
|
||||
ret
|
||||
|
||||
;=====================================================================
|
||||
; Kernel packing (self-extracting KERNPACK)
|
||||
;=====================================================================
|
||||
do_kerpack:
|
||||
mov ecx, 300*1024*3 + 6A8000h
|
||||
call alloc
|
||||
test eax, eax
|
||||
jz quit
|
||||
mov [infile], eax
|
||||
add eax, 300*1024
|
||||
mov [inbuftmp], eax
|
||||
add eax, 300*1024
|
||||
mov [outfile], eax
|
||||
add eax, 300*1024
|
||||
mov [workmem], eax
|
||||
; open + read
|
||||
mov eax, sys_open
|
||||
mov ebx, [infilename]
|
||||
xor ecx, ecx
|
||||
xor edx, edx
|
||||
int 0x80
|
||||
test eax, eax
|
||||
js quit
|
||||
mov [fd], eax
|
||||
mov eax, sys_lseek
|
||||
mov ebx, [fd]
|
||||
xor ecx, ecx
|
||||
mov edx, 2
|
||||
int 0x80
|
||||
test eax, eax
|
||||
jle quit
|
||||
cmp eax, 300*1024
|
||||
jbe @f
|
||||
mov eax, 300*1024
|
||||
@@:
|
||||
mov [insize3], eax
|
||||
mov eax, sys_lseek
|
||||
mov ebx, [fd]
|
||||
xor ecx, ecx
|
||||
xor edx, edx
|
||||
int 0x80
|
||||
mov eax, sys_read
|
||||
mov ebx, [fd]
|
||||
mov ecx, [infile]
|
||||
mov edx, [insize3]
|
||||
int 0x80
|
||||
mov eax, sys_close
|
||||
mov ebx, [fd]
|
||||
int 0x80
|
||||
; already packed?
|
||||
mov ebx, [insize3]
|
||||
mov edi, [infile]
|
||||
add edi, ebx
|
||||
cmp dword [edi-8], 'KERN'
|
||||
jnz .go
|
||||
cmp dword [edi-4], 'PACK'
|
||||
jz quit
|
||||
.go:
|
||||
push 18
|
||||
call lzma_set_dict_size
|
||||
; find jump to 32-bit code
|
||||
mov edi, [infile]
|
||||
mov eax, edi
|
||||
add eax, [insize3]
|
||||
dec edi
|
||||
.find:
|
||||
cmp eax, edi
|
||||
je quit ; not a kernel
|
||||
inc edi
|
||||
cmp dword [edi], 0xE88EE08E ; mov fs,ax / mov gs,ax
|
||||
jnz .find
|
||||
cmp dword [edi+4], 0x00BCD08E ; mov ss,ax / mov esp,00xxxxxx
|
||||
jnz .find
|
||||
add edi, 11
|
||||
mov [inptr], edi
|
||||
sub edi, [infile]
|
||||
mov [indelta], edi
|
||||
lea eax, [ebx+0x10000]
|
||||
mov dword [loader_patch3+2], eax
|
||||
sub ebx, edi
|
||||
mov [insize1], ebx
|
||||
call ker_preprocess_calltrick3
|
||||
mov al, [cti]
|
||||
mov [loader_patch5-1], al
|
||||
mov eax, [ctn]
|
||||
mov [loader_patch4+1], eax
|
||||
mov eax, [inptr]
|
||||
add eax, [outfile]
|
||||
sub eax, [infile]
|
||||
add eax, loader_size - 5
|
||||
push [workmem]
|
||||
push [insize1]
|
||||
push eax
|
||||
push [inptr]
|
||||
call lzma_compress
|
||||
add eax, loader_size - 5
|
||||
mov [loader_patch1+6], eax
|
||||
add eax, [indelta]
|
||||
mov [outsize3], eax
|
||||
mov eax, [indelta]
|
||||
mov ecx, eax
|
||||
add ecx, [outfile]
|
||||
mov ecx, [ecx + loader_size - 4]
|
||||
bswap ecx
|
||||
mov [loader_patch2+4], ecx
|
||||
add eax, 0x10000
|
||||
mov [loader_patch1+1], eax
|
||||
mov esi, [infile]
|
||||
mov edi, [outfile]
|
||||
mov ecx, [indelta]
|
||||
rep movsb
|
||||
mov esi, loader_start
|
||||
mov ecx, loader_size
|
||||
rep movsb
|
||||
mov eax, [outfile]
|
||||
add eax, [outsize3]
|
||||
mov dword [eax], 'KERN'
|
||||
mov dword [eax+4], 'PACK'
|
||||
add dword [outsize3], 8
|
||||
; save
|
||||
mov eax, sys_open
|
||||
mov ebx, [infilename]
|
||||
mov ecx, 0x241
|
||||
mov edx, 0x1A4
|
||||
int 0x80
|
||||
test eax, eax
|
||||
js quit
|
||||
mov [fd], eax
|
||||
mov eax, sys_write
|
||||
mov ebx, [fd]
|
||||
mov ecx, [outfile]
|
||||
mov edx, [outsize3]
|
||||
int 0x80
|
||||
mov eax, sys_close
|
||||
mov ebx, [fd]
|
||||
int 0x80
|
||||
jmp quit
|
||||
;---------------------------------------------------------------------
|
||||
ker_preprocess_calltrick3:
|
||||
mov edi, ct1
|
||||
xor eax, eax
|
||||
push edi
|
||||
mov ecx, 256/4
|
||||
rep stosd
|
||||
pop edi
|
||||
mov ecx, ebx ; ecx = insize1
|
||||
mov esi, [inptr]
|
||||
mov ebx, [inbuftmp]
|
||||
xchg eax, edx ; edx = 0
|
||||
.pre:
|
||||
lodsb
|
||||
.chk0f:
|
||||
cmp al, 0Fh
|
||||
jnz .ip1
|
||||
dec ecx
|
||||
jz .done
|
||||
lodsb
|
||||
cmp al, 80h
|
||||
jb .chk0f
|
||||
cmp al, 90h
|
||||
jb .take
|
||||
.ip1:
|
||||
sub al, 0E8h
|
||||
cmp al, 1
|
||||
ja .cont
|
||||
.take:
|
||||
cmp ecx, 5
|
||||
jb .done
|
||||
lodsd
|
||||
add eax, esi
|
||||
sub eax, [inptr]
|
||||
cmp eax, [insize1]
|
||||
jae .xxx
|
||||
cmp eax, 1000000h
|
||||
jae .xxx
|
||||
sub ecx, 4
|
||||
bswap eax
|
||||
mov [esi-4], eax
|
||||
inc edx
|
||||
mov [ebx], esi
|
||||
add ebx, 4
|
||||
jmp .cont
|
||||
.xxx:
|
||||
sub esi, 4
|
||||
movzx eax, byte [esi]
|
||||
mov byte [eax+edi], 1
|
||||
.cont:
|
||||
loop .pre
|
||||
.done:
|
||||
mov [ctn], edx
|
||||
xor eax, eax
|
||||
mov ecx, 256
|
||||
repnz scasb
|
||||
jnz .ret
|
||||
not cl
|
||||
mov [cti], cl
|
||||
@@:
|
||||
cmp ebx, [inbuftmp]
|
||||
jz .ret
|
||||
sub ebx, 4
|
||||
mov eax, [ebx]
|
||||
mov [eax-4], cl
|
||||
jmp @b
|
||||
.ret:
|
||||
ret
|
||||
|
||||
;---------------------------------------------------------------------
|
||||
; LZMA compressor and the self-extractor stub (original diamond code)
|
||||
;---------------------------------------------------------------------
|
||||
include 'lzma_compress.inc'
|
||||
include 'lzma_set_dict_size.inc'
|
||||
include 'loader_lzma.inc'
|
||||
|
||||
;---------------------------------------------------------------------
|
||||
; initialized data
|
||||
;---------------------------------------------------------------------
|
||||
kernel_name db 'kernel.mnt', 0
|
||||
|
||||
align 4
|
||||
LiteralNextStates:
|
||||
db 0,0,0,0,1,2,3,4,5,6,4,5
|
||||
MatchNextStates:
|
||||
db 7,7,7,7,7,7,7,10,10,10,10,10
|
||||
RepNextStates:
|
||||
db 8,8,8,8,8,8,8,11,11,11,11,11
|
||||
ShortRepNextStates:
|
||||
db 9,9,9,9,9,9,9,11,11,11,11,11
|
||||
|
||||
align 4
|
||||
method db 1
|
||||
|
||||
;---------------------------------------------------------------------
|
||||
; uninitialized data (BSS - must stay at the very end of the segment)
|
||||
;---------------------------------------------------------------------
|
||||
align 4
|
||||
infilename dd ?
|
||||
fd dd ?
|
||||
infile dd ?
|
||||
outfile dd ?
|
||||
outfile1 dd ?
|
||||
outfile2 dd ?
|
||||
outfilebest dd ?
|
||||
inbuftmp dd ?
|
||||
workmem dd ?
|
||||
insize dd ?
|
||||
outsize dd ?
|
||||
insize3 dd ?
|
||||
outsize3 dd ?
|
||||
inptr dd ?
|
||||
indelta dd ?
|
||||
insize1 dd ?
|
||||
ctn dd ?
|
||||
cti db ?
|
||||
db 0,0,0
|
||||
ct1 rb 256
|
||||
|
||||
align 4
|
||||
; LZMA compressor work area (from kpack data.inc) - referenced by name
|
||||
; from lzma_compress.inc; must keep this exact layout.
|
||||
_lenEncoder: rd 8451
|
||||
_prices: rd 4384
|
||||
rd 17
|
||||
_finished: rb 1
|
||||
_writeEndMark: rb 1
|
||||
_longestMatchWasFound: rb 1
|
||||
_previousByte: rb 1
|
||||
_longestMatchLength: rd 1
|
||||
g_FastPos: rb 1024
|
||||
_posSlotPrices: rd 256
|
||||
_isRep0Long: rd 192
|
||||
distances: rd 274
|
||||
_optimumCurrentIndex: rd 1
|
||||
_additionalOffset: rd 1
|
||||
_isRepG1: rd 12
|
||||
_isMatch: rd 192
|
||||
_alignPriceCount: rd 1
|
||||
_numLiteralContextBits: rd 1
|
||||
_literalEncoder: rd 114
|
||||
nowPos64: rd 2
|
||||
_distancesPrices: rd 512
|
||||
_repDistances: rd 4
|
||||
_posSlotEncoder: rd 1028
|
||||
lastPosSlotFillingPos: rd 2
|
||||
_numFastBytes: rd 1
|
||||
_posStateMask: rd 1
|
||||
_isRepG0: rd 12
|
||||
_repMatchLenEncoder: rd 8451
|
||||
rd 4384
|
||||
rd 17
|
||||
_isRepG2: rd 12
|
||||
_dictionarySize: rd 1
|
||||
_numLiteralPosStateBits:rd 1
|
||||
_distTableSize: rd 1
|
||||
_optimumEndIndex: rd 1
|
||||
state.State: rb 1
|
||||
state.Prev1IsChar: rb 1
|
||||
state.Prev2: rb 2
|
||||
state.PosPrev2: rd 1
|
||||
state.BackPrev2: rd 1
|
||||
state.Price: rd 1
|
||||
state.PosPrev: rd 1
|
||||
state.BackPrev: rd 1
|
||||
state.Backs: rd 4
|
||||
rd 40950
|
||||
_alignPrices: rd 16
|
||||
_isRep: rd 12
|
||||
_posAlignEncoder: rd 256
|
||||
i_01: rd 1
|
||||
_state: rb 1
|
||||
_cache: rb 1
|
||||
_state.Prev2: rb 2
|
||||
_posEncoders: rd 1
|
||||
_numPrevBits: rd 1
|
||||
_numPosBits: rd 1
|
||||
_posMask: rd 1
|
||||
_posStateBits: rd 1
|
||||
_range: rd 1
|
||||
_cacheSize: rd 1
|
||||
_cyclicBufferSize: rd 1
|
||||
low: rd 2
|
||||
Models: rd 512
|
||||
_matchMaxLen: rd 1
|
||||
pack_pos: rd 1
|
||||
_cutValue: rd 1
|
||||
_hash: rd 1
|
||||
crc_table: rd 256
|
||||
_buffer: rd 1
|
||||
_pos: rd 1
|
||||
_streamPos: rd 1
|
||||
pack_length: rd 1
|
||||
@@ -0,0 +1,890 @@
|
||||
; kpackw = Kolibri Packer, native Windows port (no window, not even a console)
|
||||
;
|
||||
; Usage: drag a file onto kpackw.exe, or kpackw.exe <file>
|
||||
; The file is compressed in place (overwritten).
|
||||
; If the file name is "kernel.mnt" it is packed with the "Kernel" option
|
||||
; (self-extracting KERNPACK format), otherwise the normal KPCK format is used.
|
||||
;
|
||||
; Compression core (LZMA + calltrick) and the self-extractor stub are the
|
||||
; original KolibriOS kpack sources by diamond; only the OS glue is new.
|
||||
|
||||
format PE GUI 4.0
|
||||
entry start
|
||||
|
||||
;=====================================================================
|
||||
section '.text' code readable writeable executable
|
||||
;=====================================================================
|
||||
|
||||
use_lzma = 1
|
||||
use_calltrick1 = 40h
|
||||
use_calltrick2 = 80h
|
||||
|
||||
start:
|
||||
; ---- get command line, extract the file argument ------------------
|
||||
call [GetCommandLineA]
|
||||
mov esi, eax
|
||||
; skip leading spaces
|
||||
.skip1:
|
||||
mov al, [esi]
|
||||
cmp al, ' '
|
||||
jne .arg0
|
||||
inc esi
|
||||
jmp .skip1
|
||||
; skip program name (argv[0])
|
||||
.arg0:
|
||||
cmp byte [esi], '"'
|
||||
jne .arg0_plain
|
||||
inc esi
|
||||
.arg0_q:
|
||||
mov al, [esi]
|
||||
test al, al
|
||||
jz .no_arg
|
||||
inc esi
|
||||
cmp al, '"'
|
||||
jne .arg0_q
|
||||
jmp .skip2
|
||||
.arg0_plain:
|
||||
mov al, [esi]
|
||||
test al, al
|
||||
jz .no_arg
|
||||
cmp al, ' '
|
||||
je .skip2
|
||||
inc esi
|
||||
jmp .arg0_plain
|
||||
; skip spaces between argv[0] and argv[1]
|
||||
.skip2:
|
||||
mov al, [esi]
|
||||
cmp al, ' '
|
||||
jne .arg1
|
||||
inc esi
|
||||
jmp .skip2
|
||||
; read the file name argument into infilename
|
||||
.arg1:
|
||||
mov al, [esi]
|
||||
test al, al
|
||||
jz .no_arg
|
||||
mov edi, infilename
|
||||
cmp al, '"'
|
||||
jne .arg1_plain
|
||||
inc esi
|
||||
.arg1_q:
|
||||
mov al, [esi]
|
||||
test al, al
|
||||
jz .name_done
|
||||
inc esi
|
||||
cmp al, '"'
|
||||
je .name_done
|
||||
stosb
|
||||
jmp .arg1_q
|
||||
.arg1_plain:
|
||||
mov al, [esi]
|
||||
test al, al
|
||||
jz .name_done
|
||||
cmp al, ' '
|
||||
je .name_done
|
||||
inc esi
|
||||
stosb
|
||||
jmp .arg1_plain
|
||||
.name_done:
|
||||
mov byte [edi], 0
|
||||
|
||||
; ---- is the base name "kernel.mnt" ? ------------------------------
|
||||
; find base name (after last '\' or '/')
|
||||
mov esi, infilename
|
||||
mov ebx, esi ; ebx = start of base name
|
||||
.bn:
|
||||
mov al, [esi]
|
||||
test al, al
|
||||
jz .bn_done
|
||||
cmp al, '\'
|
||||
je .bn_sep
|
||||
cmp al, '/'
|
||||
je .bn_sep
|
||||
inc esi
|
||||
jmp .bn
|
||||
.bn_sep:
|
||||
inc esi
|
||||
mov ebx, esi
|
||||
jmp .bn
|
||||
.bn_done:
|
||||
; case-insensitive compare ebx with "kernel.mnt"
|
||||
mov esi, ebx
|
||||
mov edi, kernel_name
|
||||
.cmpk:
|
||||
mov al, [esi]
|
||||
mov ah, [edi]
|
||||
test ah, ah
|
||||
jnz .notend
|
||||
test al, al ; kernel_name ended: match iff input ended too
|
||||
jz do_kerpack
|
||||
jmp do_pack
|
||||
.notend:
|
||||
or al, 20h ; tolower (kernel_name is lowercase)
|
||||
cmp al, ah
|
||||
jne do_pack
|
||||
inc esi
|
||||
inc edi
|
||||
jmp .cmpk
|
||||
|
||||
.no_arg:
|
||||
push 0
|
||||
call [ExitProcess]
|
||||
|
||||
;=====================================================================
|
||||
; Normal packing (KPCK) - transcribed from the KolibriOS/linux kpack
|
||||
;=====================================================================
|
||||
do_pack:
|
||||
; open input
|
||||
push 0
|
||||
push 0
|
||||
push 3 ; OPEN_EXISTING
|
||||
push 0
|
||||
push 1 ; FILE_SHARE_READ
|
||||
push 80000000h ; GENERIC_READ
|
||||
push infilename
|
||||
call [CreateFileA]
|
||||
cmp eax, -1
|
||||
je quit
|
||||
mov esi, eax ; handle
|
||||
push 0
|
||||
push esi
|
||||
call [GetFileSize]
|
||||
cmp eax, -1
|
||||
je quit
|
||||
test eax, eax
|
||||
jz quit
|
||||
mov [insize], eax
|
||||
; allocate infile
|
||||
push 4
|
||||
push 3000h
|
||||
push eax
|
||||
push 0
|
||||
call [VirtualAlloc]
|
||||
test eax, eax
|
||||
jz quit
|
||||
mov [infile], eax
|
||||
; read
|
||||
push 0
|
||||
push bytesdone
|
||||
push [insize]
|
||||
push eax
|
||||
push esi
|
||||
call [ReadFile]
|
||||
test eax, eax
|
||||
jz quit
|
||||
push esi
|
||||
call [CloseHandle]
|
||||
; maximum output size
|
||||
mov eax, [insize]
|
||||
shr eax, 3
|
||||
add eax, [insize]
|
||||
add eax, 400h
|
||||
mov esi, eax ; esi = maxout
|
||||
add eax, eax ; two copies
|
||||
push 4
|
||||
push 3000h
|
||||
push eax
|
||||
push 0
|
||||
call [VirtualAlloc]
|
||||
test eax, eax
|
||||
jz quit
|
||||
mov [outfile], eax
|
||||
mov [outfile1], eax
|
||||
mov [outfilebest], eax
|
||||
add eax, esi
|
||||
mov [outfile2], eax
|
||||
; KPCK header
|
||||
mov eax, [outfile1]
|
||||
mov dword [eax], 'KPCK'
|
||||
mov ecx, [insize]
|
||||
mov [eax+4], ecx
|
||||
; LZMA dictionary size
|
||||
dec ecx
|
||||
bsr eax, ecx
|
||||
inc eax
|
||||
cmp eax, 28
|
||||
jb @f
|
||||
mov eax, 28
|
||||
@@:
|
||||
push eax
|
||||
push eax
|
||||
call lzma_set_dict_size ; ret 4 (pops one)
|
||||
pop ecx ; ecx = log2(dict)
|
||||
mov eax, 1
|
||||
shl eax, cl
|
||||
; workmem
|
||||
imul eax, 19
|
||||
shr eax, 1
|
||||
add eax, 509000h
|
||||
push 4
|
||||
push 3000h
|
||||
push eax
|
||||
push 0
|
||||
call [VirtualAlloc]
|
||||
test eax, eax
|
||||
jz quit
|
||||
mov [workmem], eax
|
||||
; first pass: plain LZMA
|
||||
mov eax, [outfile2]
|
||||
mov [outfile], eax
|
||||
xchg eax, edi
|
||||
mov esi, [outfile1]
|
||||
movsd
|
||||
movsd
|
||||
call pk_pack_lzma
|
||||
mov [outsize], eax
|
||||
mov eax, [outfile]
|
||||
mov [outfilebest], eax
|
||||
mov [method], use_lzma
|
||||
; calltrick 1
|
||||
call pk_preprocess_calltrick
|
||||
test eax, eax
|
||||
jz .noct1
|
||||
call pk_set_outfile
|
||||
call pk_pack_lzma
|
||||
add eax, 5
|
||||
cmp eax, [outsize]
|
||||
jae .noct1
|
||||
mov [outsize], eax
|
||||
mov eax, [outfile]
|
||||
mov [outfilebest], eax
|
||||
mov [method], use_lzma or use_calltrick1
|
||||
.noct1:
|
||||
call pk_set_outfile
|
||||
push dword [ctn]
|
||||
movzx eax, byte [cti]
|
||||
push eax
|
||||
call pk_preprocess_calltrick2
|
||||
test eax, eax
|
||||
jz .noct2
|
||||
call pk_set_outfile
|
||||
call pk_pack_lzma
|
||||
add eax, 5
|
||||
cmp eax, [outsize]
|
||||
jae .noct2
|
||||
mov [outsize], eax
|
||||
mov eax, [outfile]
|
||||
mov [outfilebest], eax
|
||||
mov [method], use_lzma or use_calltrick2
|
||||
pop ecx
|
||||
pop ecx
|
||||
push dword [ctn]
|
||||
movzx eax, byte [cti]
|
||||
push eax
|
||||
.noct2:
|
||||
pop eax
|
||||
mov [cti], al
|
||||
pop eax
|
||||
mov [ctn], eax
|
||||
add dword [outsize], 12
|
||||
mov eax, [outsize]
|
||||
cmp eax, [insize]
|
||||
jb .packed_ok
|
||||
jmp quit ; output not smaller: leave original untouched
|
||||
.packed_ok:
|
||||
movzx eax, byte [method]
|
||||
mov edi, [outfilebest]
|
||||
mov [edi+8], eax
|
||||
test al, use_calltrick1 or use_calltrick2
|
||||
jz .save
|
||||
mov ecx, [outsize]
|
||||
add ecx, edi
|
||||
mov eax, [ctn]
|
||||
mov [ecx-5], eax
|
||||
mov al, [cti]
|
||||
mov [ecx-1], al
|
||||
.save:
|
||||
push 0
|
||||
push 80h ; FILE_ATTRIBUTE_NORMAL
|
||||
push 2 ; CREATE_ALWAYS
|
||||
push 0
|
||||
push 0
|
||||
push 40000000h ; GENERIC_WRITE
|
||||
push infilename
|
||||
call [CreateFileA]
|
||||
cmp eax, -1
|
||||
je quit
|
||||
mov esi, eax
|
||||
push 0
|
||||
push bytesdone
|
||||
push [outsize]
|
||||
push [outfilebest]
|
||||
push esi
|
||||
call [WriteFile]
|
||||
push esi
|
||||
call [CloseHandle]
|
||||
quit:
|
||||
push 0
|
||||
call [ExitProcess]
|
||||
|
||||
;---------------------------------------------------------------------
|
||||
pk_set_outfile:
|
||||
mov eax, [outfilebest]
|
||||
xor eax, [outfile1]
|
||||
xor eax, [outfile2]
|
||||
mov [outfile], eax
|
||||
ret
|
||||
;---------------------------------------------------------------------
|
||||
pk_pack_lzma:
|
||||
mov eax, [outfile]
|
||||
add eax, 11
|
||||
push [workmem]
|
||||
push [insize]
|
||||
push eax
|
||||
push [infile]
|
||||
call lzma_compress ; ret 16
|
||||
mov ecx, [outfile]
|
||||
mov edx, [ecx+12]
|
||||
bswap edx
|
||||
mov [ecx+12], edx
|
||||
dec eax
|
||||
ret
|
||||
;---------------------------------------------------------------------
|
||||
pk_ct_fail:
|
||||
xor eax, eax
|
||||
mov [ctn], eax
|
||||
ret
|
||||
;---------------------------------------------------------------------
|
||||
pk_preprocess_calltrick:
|
||||
push 4
|
||||
push 3000h
|
||||
push [insize]
|
||||
push 0
|
||||
call [VirtualAlloc]
|
||||
test eax, eax
|
||||
jz pk_ct_fail
|
||||
push eax
|
||||
xor eax, eax
|
||||
mov edi, ct1
|
||||
mov ecx, 256/4
|
||||
push edi
|
||||
rep stosd
|
||||
pop edi
|
||||
mov ecx, [insize]
|
||||
mov esi, [infile]
|
||||
xchg eax, edx ; edx = 0
|
||||
pop eax
|
||||
xchg eax, ebx ; ebx = temp buffer
|
||||
push ebx
|
||||
.pre:
|
||||
lodsb
|
||||
sub al, 0E8h
|
||||
cmp al, 1
|
||||
ja .cont
|
||||
cmp ecx, 5
|
||||
jb .done
|
||||
lodsd
|
||||
add eax, esi
|
||||
sub eax, [infile]
|
||||
cmp eax, [insize]
|
||||
jae .xxx
|
||||
cmp eax, 1000000h
|
||||
jae .xxx
|
||||
sub ecx, 4
|
||||
bswap eax
|
||||
mov [esi-4], eax
|
||||
inc edx
|
||||
mov [ebx], esi
|
||||
add ebx, 4
|
||||
jmp .cont
|
||||
.xxx:
|
||||
sub esi, 4
|
||||
movzx eax, byte [esi]
|
||||
mov byte [eax+edi], 1
|
||||
.cont:
|
||||
loop .pre
|
||||
.done:
|
||||
mov [ctn], edx
|
||||
pop edx ; edx = base of temp buffer
|
||||
xor eax, eax
|
||||
mov ecx, 256
|
||||
repnz scasb
|
||||
jnz pk_ct_fail
|
||||
not cl
|
||||
mov [cti], cl
|
||||
@@:
|
||||
cmp ebx, edx
|
||||
jz @f
|
||||
sub ebx, 4
|
||||
mov eax, [ebx]
|
||||
mov [eax-4], cl
|
||||
jmp @b
|
||||
@@:
|
||||
mov al, 1
|
||||
ret
|
||||
;---------------------------------------------------------------------
|
||||
pk_preprocess_calltrick2:
|
||||
; restore input
|
||||
mov esi, [infile]
|
||||
mov ecx, [ctn]
|
||||
jecxz .pre_init
|
||||
.restore:
|
||||
lodsb
|
||||
sub al, 0E8h
|
||||
cmp al, 1
|
||||
ja .restore
|
||||
mov al, [cti]
|
||||
cmp [esi], al
|
||||
jnz .restore
|
||||
lodsd
|
||||
mov al, 0
|
||||
bswap eax
|
||||
sub eax, esi
|
||||
add eax, [infile]
|
||||
mov [esi-4], eax
|
||||
loop .restore
|
||||
.pre_init:
|
||||
push 4
|
||||
push 3000h
|
||||
push [insize]
|
||||
push 0
|
||||
call [VirtualAlloc]
|
||||
test eax, eax
|
||||
jz pk_ct_fail
|
||||
mov edi, ct1
|
||||
xchg eax, ebx
|
||||
xor eax, eax
|
||||
push edi
|
||||
mov ecx, 256/4
|
||||
rep stosd
|
||||
pop edi
|
||||
mov ecx, [insize]
|
||||
mov esi, [infile]
|
||||
xchg eax, edx ; edx = 0
|
||||
push ebx
|
||||
.pre:
|
||||
lodsb
|
||||
.chk0f:
|
||||
cmp al, 0Fh
|
||||
jnz .ip1
|
||||
dec ecx
|
||||
jz .done
|
||||
lodsb
|
||||
cmp al, 80h
|
||||
jb .chk0f
|
||||
cmp al, 90h
|
||||
jb .take
|
||||
.ip1:
|
||||
sub al, 0E8h
|
||||
cmp al, 1
|
||||
ja .cont
|
||||
.take:
|
||||
cmp ecx, 5
|
||||
jb .done
|
||||
lodsd
|
||||
add eax, esi
|
||||
sub eax, [infile]
|
||||
cmp eax, [insize]
|
||||
jae .xxx
|
||||
cmp eax, 1000000h
|
||||
jae .xxx
|
||||
sub ecx, 4
|
||||
bswap eax
|
||||
mov [esi-4], eax
|
||||
inc edx
|
||||
mov [ebx], esi
|
||||
add ebx, 4
|
||||
jmp .cont
|
||||
.xxx:
|
||||
sub esi, 4
|
||||
movzx eax, byte [esi]
|
||||
mov byte [eax+edi], 1
|
||||
.cont:
|
||||
loop .pre
|
||||
.done:
|
||||
mov [ctn], edx
|
||||
pop edx
|
||||
xor eax, eax
|
||||
mov ecx, 256
|
||||
repnz scasb
|
||||
jnz pk_ct_fail
|
||||
not cl
|
||||
mov [cti], cl
|
||||
@@:
|
||||
cmp ebx, edx
|
||||
jz @f
|
||||
sub ebx, 4
|
||||
mov eax, [ebx]
|
||||
mov [eax-4], cl
|
||||
jmp @b
|
||||
@@:
|
||||
mov al, 1
|
||||
ret
|
||||
|
||||
;=====================================================================
|
||||
; Kernel packing (self-extracting KERNPACK) - from kerpack.inc
|
||||
;=====================================================================
|
||||
do_kerpack:
|
||||
push 4
|
||||
push 3000h
|
||||
push 300*1024*3 + 6A8000h
|
||||
push 0
|
||||
call [VirtualAlloc]
|
||||
test eax, eax
|
||||
jz quit
|
||||
mov [infile], eax
|
||||
add eax, 300*1024
|
||||
mov [inbuftmp], eax
|
||||
add eax, 300*1024
|
||||
mov [outfile], eax
|
||||
add eax, 300*1024
|
||||
mov [workmem], eax
|
||||
; open + read
|
||||
push 0
|
||||
push 0
|
||||
push 3
|
||||
push 0
|
||||
push 1
|
||||
push 80000000h
|
||||
push infilename
|
||||
call [CreateFileA]
|
||||
cmp eax, -1
|
||||
je quit
|
||||
mov esi, eax
|
||||
push 0
|
||||
push esi
|
||||
call [GetFileSize]
|
||||
cmp eax, -1
|
||||
je quit
|
||||
test eax, eax
|
||||
jz quit
|
||||
cmp eax, 300*1024
|
||||
jbe @f
|
||||
mov eax, 300*1024
|
||||
@@:
|
||||
mov [insize3], eax
|
||||
push 0
|
||||
push bytesdone
|
||||
push [insize3]
|
||||
push [infile]
|
||||
push esi
|
||||
call [ReadFile]
|
||||
push esi
|
||||
call [CloseHandle]
|
||||
; already packed?
|
||||
mov ebx, [insize3]
|
||||
mov edi, [infile]
|
||||
add edi, ebx
|
||||
cmp dword [edi-8], 'KERN'
|
||||
jnz .go
|
||||
cmp dword [edi-4], 'PACK'
|
||||
jz quit
|
||||
.go:
|
||||
push 18
|
||||
call lzma_set_dict_size
|
||||
; find jump to 32-bit code
|
||||
mov edi, [infile]
|
||||
mov eax, edi
|
||||
add eax, [insize3]
|
||||
dec edi
|
||||
.find:
|
||||
cmp eax, edi
|
||||
je quit ; not a kernel
|
||||
inc edi
|
||||
cmp dword [edi], 0xE88EE08E ; mov fs,ax / mov gs,ax
|
||||
jnz .find
|
||||
cmp dword [edi+4], 0x00BCD08E ; mov ss,ax / mov esp,00xxxxxx
|
||||
jnz .find
|
||||
add edi, 11
|
||||
mov [inptr], edi
|
||||
sub edi, [infile]
|
||||
mov [indelta], edi
|
||||
lea eax, [ebx+0x10000]
|
||||
mov dword [loader_patch3+2], eax
|
||||
sub ebx, edi
|
||||
mov [insize1], ebx
|
||||
call ker_preprocess_calltrick3
|
||||
mov al, [cti]
|
||||
mov [loader_patch5-1], al
|
||||
mov eax, [ctn]
|
||||
mov [loader_patch4+1], eax
|
||||
mov eax, [inptr]
|
||||
add eax, [outfile]
|
||||
sub eax, [infile]
|
||||
add eax, loader_size - 5
|
||||
push [workmem]
|
||||
push [insize1]
|
||||
push eax
|
||||
push [inptr]
|
||||
call lzma_compress
|
||||
add eax, loader_size - 5
|
||||
mov [loader_patch1+6], eax
|
||||
add eax, [indelta]
|
||||
mov [outsize3], eax
|
||||
mov eax, [indelta]
|
||||
mov ecx, eax
|
||||
add ecx, [outfile]
|
||||
mov ecx, [ecx + loader_size - 4]
|
||||
bswap ecx
|
||||
mov [loader_patch2+4], ecx
|
||||
add eax, 0x10000
|
||||
mov [loader_patch1+1], eax
|
||||
mov esi, [infile]
|
||||
mov edi, [outfile]
|
||||
mov ecx, [indelta]
|
||||
rep movsb
|
||||
mov esi, loader_start
|
||||
mov ecx, loader_size
|
||||
rep movsb
|
||||
mov eax, [outfile]
|
||||
add eax, [outsize3]
|
||||
mov dword [eax], 'KERN'
|
||||
mov dword [eax+4], 'PACK'
|
||||
add dword [outsize3], 8
|
||||
; save
|
||||
push 0
|
||||
push 80h
|
||||
push 2
|
||||
push 0
|
||||
push 0
|
||||
push 40000000h
|
||||
push infilename
|
||||
call [CreateFileA]
|
||||
cmp eax, -1
|
||||
je quit
|
||||
mov esi, eax
|
||||
push 0
|
||||
push bytesdone
|
||||
push [outsize3]
|
||||
push [outfile]
|
||||
push esi
|
||||
call [WriteFile]
|
||||
push esi
|
||||
call [CloseHandle]
|
||||
jmp quit
|
||||
;---------------------------------------------------------------------
|
||||
ker_preprocess_calltrick3:
|
||||
mov edi, ct1
|
||||
xor eax, eax
|
||||
push edi
|
||||
mov ecx, 256/4
|
||||
rep stosd
|
||||
pop edi
|
||||
mov ecx, ebx ; ecx = insize1
|
||||
mov esi, [inptr]
|
||||
mov ebx, [inbuftmp]
|
||||
xchg eax, edx ; edx = 0
|
||||
.pre:
|
||||
lodsb
|
||||
.chk0f:
|
||||
cmp al, 0Fh
|
||||
jnz .ip1
|
||||
dec ecx
|
||||
jz .done
|
||||
lodsb
|
||||
cmp al, 80h
|
||||
jb .chk0f
|
||||
cmp al, 90h
|
||||
jb .take
|
||||
.ip1:
|
||||
sub al, 0E8h
|
||||
cmp al, 1
|
||||
ja .cont
|
||||
.take:
|
||||
cmp ecx, 5
|
||||
jb .done
|
||||
lodsd
|
||||
add eax, esi
|
||||
sub eax, [inptr]
|
||||
cmp eax, [insize1]
|
||||
jae .xxx
|
||||
cmp eax, 1000000h
|
||||
jae .xxx
|
||||
sub ecx, 4
|
||||
bswap eax
|
||||
mov [esi-4], eax
|
||||
inc edx
|
||||
mov [ebx], esi
|
||||
add ebx, 4
|
||||
jmp .cont
|
||||
.xxx:
|
||||
sub esi, 4
|
||||
movzx eax, byte [esi]
|
||||
mov byte [eax+edi], 1
|
||||
.cont:
|
||||
loop .pre
|
||||
.done:
|
||||
mov [ctn], edx
|
||||
xor eax, eax
|
||||
mov ecx, 256
|
||||
repnz scasb
|
||||
jnz .ret
|
||||
not cl
|
||||
mov [cti], cl
|
||||
@@:
|
||||
cmp ebx, [inbuftmp]
|
||||
jz .ret
|
||||
sub ebx, 4
|
||||
mov eax, [ebx]
|
||||
mov [eax-4], cl
|
||||
jmp @b
|
||||
.ret:
|
||||
ret
|
||||
|
||||
;---------------------------------------------------------------------
|
||||
; LZMA compressor and the self-extractor stub (original diamond code)
|
||||
;---------------------------------------------------------------------
|
||||
include 'lzma_compress.inc'
|
||||
include 'lzma_set_dict_size.inc'
|
||||
include 'loader_lzma.inc'
|
||||
|
||||
;=====================================================================
|
||||
section '.data' data readable writeable
|
||||
;=====================================================================
|
||||
kernel_name db 'kernel.mnt', 0
|
||||
|
||||
align 4
|
||||
; LZMA state-transition tables (constants, referenced by lzma_compress)
|
||||
LiteralNextStates:
|
||||
db 0,0,0,0,1,2,3,4,5,6,4,5
|
||||
MatchNextStates:
|
||||
db 7,7,7,7,7,7,7,10,10,10,10,10
|
||||
RepNextStates:
|
||||
db 8,8,8,8,8,8,8,11,11,11,11,11
|
||||
ShortRepNextStates:
|
||||
db 9,9,9,9,9,9,9,11,11,11,11,11
|
||||
|
||||
align 4
|
||||
method db 1
|
||||
db 0,0,0
|
||||
infile dd ?
|
||||
outfile dd ?
|
||||
outfile1 dd ?
|
||||
outfile2 dd ?
|
||||
outfilebest dd ?
|
||||
inbuftmp dd ?
|
||||
workmem dd ?
|
||||
insize dd ?
|
||||
outsize dd ?
|
||||
insize3 dd ?
|
||||
outsize3 dd ?
|
||||
inptr dd ?
|
||||
indelta dd ?
|
||||
insize1 dd ?
|
||||
ctn dd ?
|
||||
cti db ?
|
||||
db 0,0,0
|
||||
bytesdone dd ?
|
||||
|
||||
;=====================================================================
|
||||
section '.bss' data readable writeable
|
||||
;=====================================================================
|
||||
infilename rb 1024
|
||||
ct1 rb 256
|
||||
|
||||
align 4
|
||||
;---------------------------------------------------------------------
|
||||
; LZMA compressor work area (from kpack data.inc) - referenced by name
|
||||
; from lzma_compress.inc; must keep this exact layout.
|
||||
;---------------------------------------------------------------------
|
||||
_lenEncoder: rd 8451
|
||||
_prices: rd 4384
|
||||
rd 17
|
||||
_finished: rb 1
|
||||
_writeEndMark: rb 1
|
||||
_longestMatchWasFound: rb 1
|
||||
_previousByte: rb 1
|
||||
_longestMatchLength: rd 1
|
||||
g_FastPos: rb 1024
|
||||
_posSlotPrices: rd 256
|
||||
_isRep0Long: rd 192
|
||||
distances: rd 274
|
||||
_optimumCurrentIndex: rd 1
|
||||
_additionalOffset: rd 1
|
||||
_isRepG1: rd 12
|
||||
_isMatch: rd 192
|
||||
_alignPriceCount: rd 1
|
||||
_numLiteralContextBits: rd 1
|
||||
_literalEncoder: rd 114
|
||||
nowPos64: rd 2
|
||||
_distancesPrices: rd 512
|
||||
_repDistances: rd 4
|
||||
_posSlotEncoder: rd 1028
|
||||
lastPosSlotFillingPos: rd 2
|
||||
_numFastBytes: rd 1
|
||||
_posStateMask: rd 1
|
||||
_isRepG0: rd 12
|
||||
_repMatchLenEncoder: rd 8451
|
||||
rd 4384
|
||||
rd 17
|
||||
_isRepG2: rd 12
|
||||
_dictionarySize: rd 1
|
||||
_numLiteralPosStateBits:rd 1
|
||||
_distTableSize: rd 1
|
||||
_optimumEndIndex: rd 1
|
||||
state.State: rb 1
|
||||
state.Prev1IsChar: rb 1
|
||||
state.Prev2: rb 2
|
||||
state.PosPrev2: rd 1
|
||||
state.BackPrev2: rd 1
|
||||
state.Price: rd 1
|
||||
state.PosPrev: rd 1
|
||||
state.BackPrev: rd 1
|
||||
state.Backs: rd 4
|
||||
rd 40950
|
||||
_alignPrices: rd 16
|
||||
_isRep: rd 12
|
||||
_posAlignEncoder: rd 256
|
||||
i_01: rd 1
|
||||
_state: rb 1
|
||||
_cache: rb 1
|
||||
_state.Prev2: rb 2
|
||||
_posEncoders: rd 1
|
||||
_numPrevBits: rd 1
|
||||
_numPosBits: rd 1
|
||||
_posMask: rd 1
|
||||
_posStateBits: rd 1
|
||||
_range: rd 1
|
||||
_cacheSize: rd 1
|
||||
_cyclicBufferSize: rd 1
|
||||
low: rd 2
|
||||
Models: rd 512
|
||||
_matchMaxLen: rd 1
|
||||
pack_pos: rd 1
|
||||
_cutValue: rd 1
|
||||
_hash: rd 1
|
||||
crc_table: rd 256
|
||||
_buffer: rd 1
|
||||
_pos: rd 1
|
||||
_streamPos: rd 1
|
||||
pack_length: rd 1
|
||||
|
||||
;=====================================================================
|
||||
section '.idata' import data readable writeable
|
||||
;=====================================================================
|
||||
dd 0,0,0, RVA kernel_txt, RVA kernel_iat
|
||||
dd 0,0,0, 0, 0
|
||||
|
||||
kernel_iat:
|
||||
GetCommandLineA dd RVA _GetCommandLineA
|
||||
CreateFileA dd RVA _CreateFileA
|
||||
GetFileSize dd RVA _GetFileSize
|
||||
ReadFile dd RVA _ReadFile
|
||||
WriteFile dd RVA _WriteFile
|
||||
CloseHandle dd RVA _CloseHandle
|
||||
VirtualAlloc dd RVA _VirtualAlloc
|
||||
VirtualFree dd RVA _VirtualFree
|
||||
ExitProcess dd RVA _ExitProcess
|
||||
dd 0
|
||||
|
||||
kernel_txt db 'KERNEL32.DLL', 0
|
||||
|
||||
align 2
|
||||
_GetCommandLineA dw 0
|
||||
db 'GetCommandLineA', 0
|
||||
_CreateFileA dw 0
|
||||
db 'CreateFileA', 0
|
||||
_GetFileSize dw 0
|
||||
db 'GetFileSize', 0
|
||||
_ReadFile dw 0
|
||||
db 'ReadFile', 0
|
||||
_WriteFile dw 0
|
||||
db 'WriteFile', 0
|
||||
_CloseHandle dw 0
|
||||
db 'CloseHandle', 0
|
||||
_VirtualAlloc dw 0
|
||||
db 'VirtualAlloc', 0
|
||||
_VirtualFree dw 0
|
||||
db 'VirtualFree', 0
|
||||
_ExitProcess dw 0
|
||||
db 'ExitProcess', 0
|
||||
@@ -1,5 +1,5 @@
|
||||
[rbmenu]
|
||||
Диспетчер процессов=cpu
|
||||
Диспетчер задач=taskman
|
||||
Управление темой=skincfg
|
||||
Настройка фона=/sys/media/palitra
|
||||
Настройка устройств=setup
|
||||
|
||||
@@ -55,17 +55,18 @@ int program_console(int pid) {
|
||||
break;
|
||||
|
||||
case SHELL_PUTS:
|
||||
printf("%s", &buffer->data );
|
||||
buffer->return_value.written_bytes = printf("%s", &buffer->data );
|
||||
buffer->cmd = SHELL_OK;
|
||||
break;
|
||||
|
||||
case SHELL_GETC:
|
||||
buffer->data[0] = (char) getch() ;
|
||||
*((int *)buffer->data) = getch();
|
||||
buffer->cmd = SHELL_OK;
|
||||
break;
|
||||
|
||||
case SHELL_GETS:
|
||||
gets(buffer->data, size - 2);
|
||||
buffer->return_value.str = gets(buffer->data, size - 2);
|
||||
buffer->return_value.written_bytes = strlen(buffer->data);
|
||||
buffer->cmd = SHELL_OK;
|
||||
break;
|
||||
|
||||
|
||||
@@ -104,10 +104,26 @@ applyKeymap:
|
||||
cmp al, 9
|
||||
jnc @f
|
||||
push eax
|
||||
push esi edi
|
||||
shl eax,7
|
||||
lea eax,[eax*2+eax]
|
||||
mov [point],eax
|
||||
mcall 70,get_key
|
||||
lea edi,[eax*2+eax] ; offset of the layout = index*384
|
||||
cmp [keymap_file],0
|
||||
jnz .loaded
|
||||
mcall 68,27,keymap_path
|
||||
test eax,eax
|
||||
jz .fail
|
||||
mov [keymap_file],eax
|
||||
mov [keymap_size],edx
|
||||
.loaded:
|
||||
lea eax,[edi+384]
|
||||
cmp eax,[keymap_size]
|
||||
ja .fail
|
||||
mov esi,[keymap_file]
|
||||
add esi,edi
|
||||
mov edi,current_keymap
|
||||
mov ecx,384/4
|
||||
rep movsd
|
||||
pop edi esi
|
||||
mcall 21,2,1,current_keymap
|
||||
inc ecx
|
||||
mcall 21,,,current_keymap_shift
|
||||
@@ -118,6 +134,9 @@ applyKeymap:
|
||||
mcall 21,,9
|
||||
@@:
|
||||
ret
|
||||
.fail:
|
||||
pop edi esi eax
|
||||
ret
|
||||
;---------------------------------------------------------------
|
||||
align 4
|
||||
current_keymap rb 128
|
||||
@@ -132,13 +151,9 @@ point2 dd 0
|
||||
dd inicont
|
||||
db '/sys/settings/lang.ini',0
|
||||
|
||||
get_key:
|
||||
dd 0
|
||||
point dd 0
|
||||
dd 0
|
||||
dd 384
|
||||
dd current_keymap
|
||||
db '/sys/settings/keymap.key',0
|
||||
keymap_path db '/sys/settings/keymap.key',0
|
||||
keymap_file dd 0
|
||||
keymap_size dd 0
|
||||
|
||||
key_r db 0
|
||||
key_r2 db 0
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
-- @taskbar loads keymap.key with f68.27, which unpacks kpack'ed files.
|
||||
tup.rule("KEYMAP.KEY", "cp %f %o" .. tup.getconfig("KPACK_CMD"), "keymap.key.kpack")
|
||||
|
||||
if tup.getconfig("NO_FASM") ~= "" then return end
|
||||
HELPERDIR = (tup.getconfig("HELPERDIR") == "") and "../.." or tup.getconfig("HELPERDIR")
|
||||
tup.include(HELPERDIR .. "/use_fasm.lua")
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
## TASKMAN - Task Manager
|
||||
|
||||
Replaces CPU and SYSMON. Starts from the menu, the system panel or by
|
||||
`Ctrl+Alt+Del`.
|
||||
|
||||
* **Processes** - threads with their CPU and memory. `Details` opens
|
||||
TINFO, `End` ends the thread, `Run...` starts a program. System threads
|
||||
(OS, @...) are shown with `System`.
|
||||
* **Performance** - CPU, temperature, memory and network: the values on
|
||||
the left, the history as a graph on the right. Temperature comes from
|
||||
the CPU sensor (Intel, AMD, Hygon, VIA, Zhaoxin) or else from a board
|
||||
monitoring chip (Winbond, ITE, ABIT uGuru); without either there is no
|
||||
temperature graph. `CPUID` starts CPUID.
|
||||
* **Disks** - partitions with label, size and, for memory disks, the
|
||||
space used. `Open` shows the disk in Eolite.
|
||||
* **Drivers** - the drivers the kernel has loaded. `Load...` starts
|
||||
LOADDRV.
|
||||
* **Autorun** - the programs of `/sys/settings/autorun.dat`. A program
|
||||
turned off has `#` before it and is shown pale; `Turn on/off` adds or
|
||||
removes the `#` in the file.
|
||||
|
||||
Lists sort by a click on a column header; a second click reverses the
|
||||
order.
|
||||
|
||||
### Keys
|
||||
|
||||
| Key | Action |
|
||||
|---|---|
|
||||
| `Tab` | Next tab |
|
||||
| `Esc` | Close |
|
||||
| `Up`, `Down`, `PgUp`, `PgDn`, `Home`, `End` | Move in a list |
|
||||
| `Enter` | Processes: Details; Disks: Open |
|
||||
| `Del` | Processes: End |
|
||||
| `Space` | Autorun: turn the program on or off |
|
||||
| Right click on a row | Processes: Details; Disks: Open |
|
||||
| Mouse wheel | Scroll a list |
|
||||
|
||||
### History
|
||||
|
||||
* 2026-10 - First version. Replaces CPU (processes) and SYSMON (system
|
||||
monitor); adds the disks, drivers and autorun tabs and the CPU
|
||||
temperature sensors; the board chips come from GMON.
|
||||
@@ -0,0 +1,4 @@
|
||||
if tup.getconfig("NO_FASM") ~= "" then return end
|
||||
|
||||
lang = (tup.getconfig("LANG") == "") and "en_US" or tup.getconfig("LANG")
|
||||
tup.rule("taskman.asm", "fasm -dlang=" .. lang .. " %f %o " .. tup.getconfig("KPACK_CMD"), "taskman")
|
||||
@@ -0,0 +1,423 @@
|
||||
; Drawing and formatting helpers; they keep all registers unless noted.
|
||||
|
||||
macro __mov reg, a, b { ; mcall loads small constants shorter
|
||||
if (~a eq) & (~b eq)
|
||||
mpack reg, a, b
|
||||
else if (~a eq) & (b eq)
|
||||
movi reg, a
|
||||
end if
|
||||
}
|
||||
|
||||
; An item of a bar: a button with its color, a checkbox with its state or
|
||||
; a gap
|
||||
struct BAR
|
||||
kind db ?
|
||||
text dd ? ; the caption
|
||||
arg dd ? ; -> the color, -> the state as a byte
|
||||
ends
|
||||
BAR_END = 0
|
||||
BAR_BUTTON = 1
|
||||
BAR_CHECK = 2
|
||||
BAR_GAP = 3
|
||||
|
||||
; ebx = x shl 16 + y, ecx = color, edx -> string in UTF-8
|
||||
draw_text:
|
||||
pusha
|
||||
or ecx, TEXT_UTF8
|
||||
mcall SF_DRAW_TEXT
|
||||
popa
|
||||
ret
|
||||
|
||||
; eax -> string; out: eax = width in pixels
|
||||
text_width:
|
||||
push ecx esi
|
||||
mov esi, eax
|
||||
xor ecx, ecx
|
||||
|
||||
.next:
|
||||
lodsb
|
||||
test al, al
|
||||
jz .done
|
||||
call utf8_more
|
||||
je .next
|
||||
add ecx, 8
|
||||
jmp .next
|
||||
|
||||
.done:
|
||||
xchg eax, ecx
|
||||
pop esi ecx
|
||||
ret
|
||||
|
||||
; eax -> caption; out: eax = width of the button
|
||||
button_width:
|
||||
call text_width
|
||||
add eax, BTN_PAD*2
|
||||
ret
|
||||
|
||||
; Frame in the border color filled with edx. ebx = x shl 16 + w, ecx = y shl 16 + h
|
||||
frame_rect:
|
||||
pusha
|
||||
push edx
|
||||
mcall SF_DRAW_RECT, , , [sc.work_graph]
|
||||
pop edx
|
||||
|
||||
add ebx, 1 shl 16 - 2
|
||||
add ecx, 1 shl 16 - 2
|
||||
mcall SF_DRAW_RECT
|
||||
popa
|
||||
ret
|
||||
|
||||
; eax = icon, ebx = x shl 16 + y, edx = the background for its white
|
||||
draw_icon:
|
||||
pusha
|
||||
mov esi, [icons]
|
||||
test esi, esi
|
||||
jz .done
|
||||
|
||||
imul eax, ICON*ICON*4
|
||||
add esi, eax
|
||||
mov edi, icon_buf
|
||||
mov ecx, ICON*ICON
|
||||
@@:
|
||||
lodsd
|
||||
cmp eax, -1
|
||||
jne .pixel
|
||||
mov eax, edx
|
||||
|
||||
.pixel:
|
||||
stosd
|
||||
loop @b
|
||||
|
||||
mov edx, ebx
|
||||
mcall SF_PUT_IMAGE_EXT, icon_buf, (ICON shl 16) + ICON, , 32, 0, 0
|
||||
|
||||
.done:
|
||||
popa
|
||||
ret
|
||||
|
||||
; eax, edx = colors; out: eax = the one half way between them, edx changed
|
||||
mix:
|
||||
and eax, 0xFEFEFE
|
||||
and edx, 0xFEFEFE
|
||||
add eax, edx
|
||||
shr eax, 1
|
||||
ret
|
||||
|
||||
; eax -> caption, edx = id, esi = color
|
||||
bar_button:
|
||||
pusha
|
||||
mov edi, eax
|
||||
call button_width
|
||||
call bar_place
|
||||
|
||||
dec ebx ; the kernel draws one pixel more
|
||||
dec ecx
|
||||
mcall SF_DEFINE_BUTTON
|
||||
|
||||
add ebx, BTN_PAD shl 16
|
||||
mov eax, [sc.work_button_text] ; then bar_text
|
||||
|
||||
; The end of the bar items: edi -> caption, eax = color, ebx = x shl 16,
|
||||
; ecx = y shl 16 of the item
|
||||
bar_text:
|
||||
shr ecx, 16
|
||||
add ecx, (BTN_H - TEXT_H)/2
|
||||
mov bx, cx
|
||||
xchg eax, ecx
|
||||
mov edx, edi
|
||||
call draw_text
|
||||
popa
|
||||
ret
|
||||
|
||||
; eax -> caption, edx = id, ebp = checked
|
||||
bar_checkbox:
|
||||
pusha
|
||||
mov edi, eax
|
||||
call button_width ; the box, PAD, the caption: 2 left
|
||||
call bar_place
|
||||
add [bar_left], 2*PAD + CHECK - 2*BTN_PAD ; then more room
|
||||
|
||||
or edx, BT_HIDE + BT_NOFRAME
|
||||
mcall SF_DEFINE_BUTTON
|
||||
|
||||
mov bx, CHECK
|
||||
add ecx, ((BTN_H - CHECK)/2) shl 16
|
||||
mov cx, CHECK
|
||||
mov [cb.left_s], ebx ; the box of box_lib, the caption
|
||||
mov [cb.top_s], ecx ; as the other ones
|
||||
|
||||
mov eax, [sc.work_light]
|
||||
mov [cb.color], eax
|
||||
mov eax, [sc.work_button] ; the frame and the check
|
||||
mov [cb.border_color], eax
|
||||
lea eax, [ebp + ebp] ; checked
|
||||
mov [cb.flags], eax
|
||||
|
||||
push cb
|
||||
call [check_box_draw2]
|
||||
|
||||
add ebx, (CHECK + PAD) shl 16
|
||||
sub ecx, ((BTN_H - CHECK)/2) shl 16
|
||||
mov eax, [sc.work_text]
|
||||
jmp bar_text
|
||||
|
||||
; Place in the bottom bar: from the left end, or from the right one for ids
|
||||
; with bit 3. eax = width, edx = id; out: ebx = x shl 16 + w, ecx = y shl 16 + h
|
||||
bar_place:
|
||||
lea ebx, [eax + PAD]
|
||||
test dl, 8
|
||||
jnz .right
|
||||
|
||||
xchg ebx, [bar_left]
|
||||
add [bar_left], ebx
|
||||
jmp @f
|
||||
|
||||
.right:
|
||||
sub [bar_right], ebx
|
||||
mov ebx, [bar_right]
|
||||
|
||||
@@:
|
||||
shl ebx, 16
|
||||
mov bx, ax
|
||||
|
||||
mov ecx, [bar_y]
|
||||
shl ecx, 16
|
||||
mov cx, BTN_H
|
||||
ret
|
||||
|
||||
; The items of a bar from the left, esi -> them; the buttons and the
|
||||
; checkboxes get the ids from BTN_OWN on. Changes all registers.
|
||||
bar_draw:
|
||||
mov edx, BTN_OWN
|
||||
|
||||
.item:
|
||||
mov bl, [esi + BAR.kind]
|
||||
mov eax, [esi + BAR.text]
|
||||
mov ecx, [esi + BAR.arg]
|
||||
add esi, sizeof.BAR
|
||||
dec bl
|
||||
js .done
|
||||
jz .button
|
||||
dec bl
|
||||
jz .check
|
||||
add [bar_left], PAD ; a gap
|
||||
jmp .item
|
||||
|
||||
.done:
|
||||
ret
|
||||
|
||||
.button:
|
||||
push esi
|
||||
mov esi, [ecx]
|
||||
call bar_button
|
||||
pop esi
|
||||
inc edx
|
||||
jmp .item
|
||||
|
||||
.check:
|
||||
movzx ebp, byte [ecx]
|
||||
call bar_checkbox
|
||||
inc edx
|
||||
jmp .item
|
||||
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; Formatting: write to edi and leave it at the terminating zero.
|
||||
|
||||
; eax = number; printed as 8 hex digits
|
||||
fmt_hex:
|
||||
pusha
|
||||
mov ebx, 16
|
||||
mov esi, 8
|
||||
jmp fmt_num
|
||||
|
||||
; eax = number
|
||||
fmt_uint:
|
||||
pusha
|
||||
mov ebx, 10
|
||||
xor esi, esi
|
||||
|
||||
fmt_num: ; ebx = base, esi = the fewest digits
|
||||
xor ecx, ecx
|
||||
|
||||
@@:
|
||||
xor edx, edx
|
||||
div ebx
|
||||
push edx
|
||||
inc ecx
|
||||
test eax, eax
|
||||
jnz @b
|
||||
cmp ecx, esi
|
||||
jb @b
|
||||
|
||||
@@:
|
||||
pop eax
|
||||
cmp al, 10 ; 0..15 to '0'..'9', 'A'..'F'
|
||||
sbb al, 0x69
|
||||
das
|
||||
stosb
|
||||
loop @b
|
||||
|
||||
mov [edi], cl
|
||||
mov [esp + PUSHA_EDI], edi
|
||||
popa
|
||||
ret
|
||||
|
||||
; al = a byte of UTF-8; out: ZF = 1 if it goes on with a character
|
||||
utf8_more:
|
||||
push eax
|
||||
and al, 0xC0
|
||||
cmp al, 0x80
|
||||
pop eax
|
||||
ret
|
||||
|
||||
; edx -> string; copies up to (ebx - eax) / 8 characters, TEXT_CHARS at
|
||||
; most, and keeps edi
|
||||
fmt_clip:
|
||||
pusha
|
||||
|
||||
mov esi, edx
|
||||
sub ebx, eax
|
||||
shr ebx, 3
|
||||
cmp ebx, TEXT_CHARS
|
||||
jb @f
|
||||
mov ebx, TEXT_CHARS
|
||||
|
||||
@@:
|
||||
lodsb
|
||||
test al, al
|
||||
jz @f
|
||||
call utf8_more
|
||||
je .put
|
||||
dec ebx
|
||||
js @f
|
||||
|
||||
.put:
|
||||
stosb
|
||||
cmp edi, text_buf + TEXT_CHARS*4
|
||||
jb @b
|
||||
|
||||
@@:
|
||||
mov byte [edi], 0
|
||||
popa
|
||||
ret
|
||||
|
||||
; esi -> string
|
||||
fmt_str:
|
||||
push eax esi
|
||||
@@:
|
||||
lodsb
|
||||
stosb
|
||||
test al, al
|
||||
jnz @b
|
||||
dec edi
|
||||
pop esi eax
|
||||
ret
|
||||
|
||||
; eax -> string
|
||||
fmt_unit:
|
||||
xchg esi, eax
|
||||
call fmt_str
|
||||
xchg esi, eax
|
||||
ret
|
||||
|
||||
; eax = KB; printed as "123 KB", "1.5 MB", "12.3 GB" etc.
|
||||
fmt_size:
|
||||
pusha
|
||||
mov ebx, 1024
|
||||
mov esi, sz_units
|
||||
jmp fmt_scaled
|
||||
|
||||
; eax = bits a second; printed as "500 bit/s", "1.5 Mbit/s" etc.
|
||||
fmt_rate:
|
||||
pusha
|
||||
mov ebx, 1000
|
||||
mov esi, sz_bits ; then fmt_scaled
|
||||
|
||||
; ebx = the step of the units, esi -> the units, each ended with 0: the
|
||||
; number in the largest one it fills, small ones with a decimal but .0
|
||||
fmt_scaled:
|
||||
xor ecx, ecx
|
||||
xor edx, edx
|
||||
|
||||
@@:
|
||||
cmp eax, ebx
|
||||
jb @f
|
||||
xor edx, edx
|
||||
div ebx
|
||||
inc ecx
|
||||
jmp @b
|
||||
|
||||
@@:
|
||||
call fmt_uint
|
||||
|
||||
cmp eax, 100
|
||||
jae .unit
|
||||
imul eax, edx, 10
|
||||
xor edx, edx
|
||||
div ebx
|
||||
test eax, eax
|
||||
jz .unit
|
||||
|
||||
mov byte [edi], "."
|
||||
inc edi
|
||||
call fmt_uint
|
||||
|
||||
.unit:
|
||||
dec ecx
|
||||
js @f
|
||||
|
||||
.skip:
|
||||
lodsb
|
||||
test al, al
|
||||
jnz .skip
|
||||
jmp .unit
|
||||
|
||||
@@:
|
||||
call fmt_str
|
||||
mov [esp + PUSHA_EDI], edi
|
||||
popa
|
||||
ret
|
||||
|
||||
; eax = seconds; printed as "h:mm:ss"
|
||||
fmt_time:
|
||||
pusha
|
||||
xor edx, edx
|
||||
mov ecx, 3600
|
||||
div ecx
|
||||
call fmt_uint
|
||||
|
||||
xchg eax, edx
|
||||
mov cl, 60
|
||||
div cl
|
||||
movzx edx, ah
|
||||
call .two
|
||||
xchg eax, edx
|
||||
call .two
|
||||
|
||||
mov [esp + PUSHA_EDI], edi
|
||||
popa
|
||||
ret
|
||||
|
||||
.two: ; eax = 0..99
|
||||
aam
|
||||
add ax, "00"
|
||||
xchg al, ah
|
||||
shl eax, 8
|
||||
mov al, ":"
|
||||
stosd
|
||||
dec edi
|
||||
ret
|
||||
|
||||
; esi -> path: the program without parameters
|
||||
run_plain:
|
||||
xor edx, edx ; then run_app
|
||||
|
||||
; esi -> path, edx -> parameters or 0
|
||||
run_app:
|
||||
pusha
|
||||
mov [app_info.Flags], edx
|
||||
mov [app_info.FileName], esi
|
||||
mcall SF_FILE, app_info
|
||||
popa
|
||||
ret
|
||||
@@ -0,0 +1,188 @@
|
||||
; The monitoring chips of older boards, ported from GMON: Winbond W836xx and
|
||||
; ITE IT87xx at ports 0x295/0x296, ABIT uGuru at 0xE0/0xE4. Their first
|
||||
; temperature stands in for a CPU without a sensor.
|
||||
|
||||
HWM_PORT = 0x295 ; index, data at + 1
|
||||
SIO_PORT = 0x2E ; Super I/O config, data at + 1
|
||||
UGURU_CMD = 0xE0
|
||||
UGURU_DATA = 0xE4
|
||||
|
||||
WB_BANK = 0x4E ; the registers of Winbond: the bank,
|
||||
WB_VENDOR = 0x4F ; the vendor, 0x80 in WB_BANK: its
|
||||
WB_ID = 0x5CA3 ; high byte
|
||||
WB_TEMP = 0x50 ; in bank 1
|
||||
SIO_CHIP_ID = 0x20 ; of the Super I/O, then of ITE
|
||||
ITE_ID = 0x87 ; the high byte
|
||||
ITE_TEMP = 0x29
|
||||
UGURU_TEMP = 0x2100 ; bank, sensor
|
||||
|
||||
; The chip of the board: hwm_read; out: eax = it, 0 if none: the ports
|
||||
; given back
|
||||
hwm_init:
|
||||
mcall SF_SET_PORTS, 0, HWM_PORT, HWM_PORT + 1
|
||||
test eax, eax
|
||||
jnz .uguru
|
||||
call wb_probe
|
||||
je .found
|
||||
|
||||
mcall SF_SET_PORTS, 0, SIO_PORT, SIO_PORT + 1
|
||||
test eax, eax
|
||||
jnz .uguru
|
||||
call ite_probe
|
||||
je .found
|
||||
|
||||
.uguru:
|
||||
mcall SF_SET_PORTS, 0, UGURU_CMD, UGURU_DATA
|
||||
test eax, eax
|
||||
jnz .none
|
||||
|
||||
in al, UGURU_CMD
|
||||
test al, al
|
||||
jz @f
|
||||
cmp al, 0xAC
|
||||
jne .none
|
||||
|
||||
@@:
|
||||
in al, UGURU_DATA
|
||||
test al, al
|
||||
jz @f
|
||||
cmp al, 8
|
||||
jne .none
|
||||
|
||||
@@:
|
||||
mov eax, uguru_read
|
||||
|
||||
.found:
|
||||
mov [hwm_read], eax
|
||||
ret
|
||||
|
||||
.none:
|
||||
mcall SF_SET_PORTS, 1, HWM_PORT, HWM_PORT + 1
|
||||
mcall SF_SET_PORTS, 1, UGURU_CMD, UGURU_DATA
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
; al = bank (or 0x80: the high byte of the vendor), ah = register; out: eax
|
||||
wb_get:
|
||||
push eax
|
||||
mov ah, WB_BANK
|
||||
call hwm_index
|
||||
pop eax
|
||||
out dx, al ; then hwm_get
|
||||
|
||||
; ah = register; out: eax
|
||||
hwm_get:
|
||||
call hwm_index
|
||||
in al, dx
|
||||
movzx eax, al
|
||||
ret
|
||||
|
||||
hwm_index: ; out: dx = the data port
|
||||
mov dx, HWM_PORT
|
||||
mov al, ah
|
||||
out dx, al
|
||||
inc edx
|
||||
ret
|
||||
|
||||
; out: ZF = 1 and eax = the read procedure if found
|
||||
wb_probe:
|
||||
mov ax, WB_VENDOR shl 8 ; a byte at a time
|
||||
call wb_get
|
||||
xchg ebx, eax
|
||||
mov ax, WB_VENDOR shl 8 + 0x80
|
||||
call wb_get
|
||||
mov bh, al
|
||||
|
||||
cmp bx, WB_ID
|
||||
jne .done
|
||||
|
||||
mov eax, wb_read
|
||||
cmp eax, eax
|
||||
.done:
|
||||
ret
|
||||
|
||||
; out: ZF = 1 and eax = the read procedure if found
|
||||
ite_probe:
|
||||
mov eax, 0x55550187 ; MB PnP mode
|
||||
mov ecx, 4
|
||||
@@:
|
||||
out SIO_PORT, al
|
||||
shr eax, 8
|
||||
loop @b
|
||||
|
||||
mov al, SIO_CHIP_ID
|
||||
out SIO_PORT, al
|
||||
in al, SIO_PORT + 1
|
||||
xchg eax, esi
|
||||
|
||||
mov al, 2 ; leave the mode
|
||||
out SIO_PORT, al
|
||||
out SIO_PORT + 1, al
|
||||
mcall SF_SET_PORTS, 1, SIO_PORT, SIO_PORT + 1
|
||||
|
||||
xchg eax, esi
|
||||
cmp al, ITE_ID
|
||||
mov eax, ite_read
|
||||
ret
|
||||
|
||||
; out: eax = the first temperature
|
||||
wb_read:
|
||||
mov ax, WB_TEMP shl 8 + 1
|
||||
jmp wb_get
|
||||
|
||||
ite_read:
|
||||
mov ah, ITE_TEMP
|
||||
jmp hwm_get
|
||||
|
||||
uguru_read:
|
||||
mov ax, UGURU_TEMP ; then uguru_sensor
|
||||
|
||||
; ax = sensor; out: eax
|
||||
uguru_sensor:
|
||||
push ebx
|
||||
mov ebx, eax
|
||||
mov al, ah ; the bank
|
||||
out UGURU_DATA, al
|
||||
mov ah, 8
|
||||
call .wait
|
||||
|
||||
mov al, bl
|
||||
out UGURU_CMD, al
|
||||
mov ah, 1
|
||||
call .wait
|
||||
|
||||
in al, UGURU_CMD
|
||||
movzx ebx, al
|
||||
|
||||
mov ecx, 1000 ; back to the ready state
|
||||
.ready:
|
||||
in al, UGURU_DATA
|
||||
cmp al, 8
|
||||
je .done
|
||||
xor eax, eax
|
||||
out UGURU_DATA, al
|
||||
mov ah, 9
|
||||
call .wait
|
||||
loop .ready
|
||||
|
||||
.done:
|
||||
xchg eax, ebx
|
||||
pop ebx
|
||||
ret
|
||||
|
||||
.wait: ; for ah at the data port
|
||||
push ecx
|
||||
mov ecx, 1000
|
||||
@@:
|
||||
in al, UGURU_DATA
|
||||
cmp al, ah
|
||||
loopne @b
|
||||
pop ecx
|
||||
ret
|
||||
|
||||
hwm_read dd nothing ; the procedure of the chip
|
||||
|
||||
uglobal
|
||||
align 4
|
||||
hwm_temp dd ? ; degrees
|
||||
endg
|
||||
@@ -0,0 +1,684 @@
|
||||
; List of a tab: rows in columns with a header, a selected row and a scrollbar on
|
||||
; the panel. The columns go from the left, one of them, width 0, takes what
|
||||
; the others leave. A click on a row selects it, then calls the trigger of
|
||||
; that button; a key of the hotkeys calls its trigger. `list` is the list of
|
||||
; the open tab; a closed tab keeps it in its descriptor.
|
||||
|
||||
struct LIST
|
||||
cols dd ? ; the columns
|
||||
cols_end dd ?
|
||||
sort dd ? ; the sorted column
|
||||
left dd ? ; the triggers: a left click,
|
||||
right dd ? ; a right click,
|
||||
keys dd ? ; -> HOTKEYs, ended by 0
|
||||
dim dd ? ; a byte in the row: not 0, it is pale; 0: none
|
||||
count dd ?
|
||||
sel dd ?
|
||||
first dd ?
|
||||
key dd ? ; the first dword of the selected row
|
||||
desc dd ? ; 1: the sorted column goes down
|
||||
view dd ? ; -> the pointers to the rows
|
||||
ends
|
||||
|
||||
struct HOTKEY
|
||||
key db ?
|
||||
trigger dw ?
|
||||
ends
|
||||
|
||||
struct COL
|
||||
caption dd ?
|
||||
field db ? ; offset in the row
|
||||
kind db ?
|
||||
width db ? ; 0: what the others leave
|
||||
ends
|
||||
|
||||
; The list: the header, the rows and the scrollbar.
|
||||
list_draw:
|
||||
mov ebx, [area_w] ; what the others leave to the widest
|
||||
sub ebx, 1 + SB_W
|
||||
mov esi, [list.cols]
|
||||
|
||||
@@:
|
||||
movzx edx, byte [esi + COL.width]
|
||||
sub ebx, edx
|
||||
add esi, sizeof.COL
|
||||
cmp esi, [list.cols_end]
|
||||
jb @b
|
||||
mov [col_rest], ebx
|
||||
|
||||
mov eax, [area_h] ; the rows that fit
|
||||
sub eax, 2 + HDR_H + 1
|
||||
xor edx, edx
|
||||
mov ecx, ROW_H
|
||||
div ecx
|
||||
mov [rows], eax
|
||||
|
||||
mov ebx, PAD shl 16 ; the header and the line under it,
|
||||
mov bx, word [area_w] ; left of the scrollbar
|
||||
sub bx, SB_W - 1
|
||||
mov ecx, (AREA_Y shl 16) + HDR_H + 2
|
||||
mov edx, [mid]
|
||||
call frame_rect
|
||||
|
||||
xor eax, eax
|
||||
mov ebp, AREA_Y + 1 + (HDR_H - TEXT_H)/2
|
||||
call list_line ; then list_rows
|
||||
|
||||
; The rows and the scrollbar only, for new data.
|
||||
list_rows:
|
||||
call list_clamp
|
||||
mov edi, [list.first]
|
||||
mov ecx, ((AREA_Y + HDR_H + 2) shl 16) + ROW_H
|
||||
mov ebp, [rows]
|
||||
|
||||
.row:
|
||||
mov ebx, (PAD + 1) shl 16
|
||||
mov bx, word [area_w]
|
||||
sub bx, 1 + SB_W
|
||||
|
||||
mov edx, [sc.work_light]
|
||||
mov esi, [sc.work_text]
|
||||
cmp edi, [list.sel]
|
||||
jne @f
|
||||
cmp edi, [list.count] ; a row there
|
||||
jae @f
|
||||
mov edx, [sc.work_button]
|
||||
mov esi, [sc.work_button_text]
|
||||
|
||||
@@:
|
||||
mcall SF_DRAW_RECT
|
||||
|
||||
cmp edi, [list.count]
|
||||
jae @f
|
||||
|
||||
pusha
|
||||
mov eax, [list.view]
|
||||
mov eax, [eax + edi*4]
|
||||
mov ebp, ecx
|
||||
shr ebp, 16
|
||||
add ebp, (ROW_H - TEXT_H)/2
|
||||
mov ecx, esi
|
||||
|
||||
mov esi, [list.dim] ; pale: half way to the background
|
||||
test esi, esi
|
||||
jz .line
|
||||
cmp byte [eax + esi], 0
|
||||
je .line
|
||||
|
||||
xchg eax, ecx
|
||||
call mix
|
||||
xchg eax, ecx
|
||||
|
||||
.line:
|
||||
call list_line
|
||||
popa
|
||||
|
||||
@@:
|
||||
add ecx, ROW_H shl 16
|
||||
inc edi
|
||||
dec ebp
|
||||
jg .row ; then sb_draw
|
||||
|
||||
; The scrollbar of box_lib at the right of the list, as high as it
|
||||
sb_draw:
|
||||
call sb_set
|
||||
push sb
|
||||
call [scrollbar_v_draw]
|
||||
ret
|
||||
|
||||
; One line of the list at y = ebp: the captions if eax = 0, lines between
|
||||
; them, the sorted one with an arrow, otherwise the cells of row eax in color
|
||||
; ecx on background edx. Left or right as col_left says.
|
||||
list_line:
|
||||
pusha
|
||||
mov ebx, PAD + 1 ; the left of the column
|
||||
mov esi, [list.cols]
|
||||
|
||||
.col:
|
||||
pusha
|
||||
|
||||
movzx edx, byte [esi + COL.field]
|
||||
add edx, eax
|
||||
test eax, eax
|
||||
jnz .cell
|
||||
|
||||
mov edx, [esi + COL.caption]
|
||||
mov ecx, [sc.work_text]
|
||||
jmp .draw
|
||||
|
||||
.cell:
|
||||
call cell_text
|
||||
|
||||
.draw:
|
||||
call col_width ; the text in the cell
|
||||
lea eax, [ebx + eax - CELL_PAD]
|
||||
xchg eax, ebx
|
||||
add eax, CELL_PAD
|
||||
mov edi, text_buf
|
||||
call fmt_clip
|
||||
|
||||
mov edx, edi
|
||||
call col_left
|
||||
jc @f
|
||||
mov eax, edx
|
||||
call text_width
|
||||
neg eax
|
||||
add eax, ebx
|
||||
|
||||
@@:
|
||||
shl eax, 16
|
||||
mov ax, bp
|
||||
xchg eax, ebx
|
||||
call draw_text
|
||||
|
||||
cmp dword [esp + PUSHA_EAX], 0 ; the captions
|
||||
jne .picture
|
||||
|
||||
cmp esi, [list.cols] ; a line left of the column, but the
|
||||
je @f ; first one at the frame
|
||||
push ebx
|
||||
mov ebx, [esp + 4 + PUSHA_EBX] ; the left
|
||||
shl ebx, 16
|
||||
inc ebx
|
||||
mov ecx, ((AREA_Y + 1) shl 16) + HDR_H
|
||||
mcall SF_DRAW_RECT, , , [sc.work_graph]
|
||||
pop ebx
|
||||
|
||||
@@:
|
||||
cmp esi, [list.sort]
|
||||
jne .next
|
||||
mov edi, [list.desc]
|
||||
|
||||
sub ebx, 5 shl 16 ; 2 pixels before the caption on the
|
||||
call col_left ; right, after the one on the left
|
||||
jnc @f
|
||||
|
||||
mov eax, text_buf
|
||||
call text_width
|
||||
add eax, 11
|
||||
shl eax, 16
|
||||
add ebx, eax
|
||||
|
||||
@@:
|
||||
call draw_arrow
|
||||
jmp .next
|
||||
|
||||
.picture: ; a bar or an icon in a row
|
||||
movzx edx, byte [esi + COL.field]
|
||||
add edx, [esp + PUSHA_EAX] ; the row
|
||||
mov edx, [edx]
|
||||
call col_width
|
||||
cmp byte [esi + COL.kind], KIND_BAR
|
||||
jb .next
|
||||
ja .icon
|
||||
|
||||
mov ebx, [esp + PUSHA_EBX] ; the bar across the cell
|
||||
add ebx, CELL_PAD
|
||||
shl ebx, 16
|
||||
sub eax, 2*CELL_PAD
|
||||
mov bx, ax
|
||||
movzx ecx, bp
|
||||
shl ecx, 16
|
||||
mov cx, TEXT_H
|
||||
xchg eax, edx
|
||||
mov edx, [sc.work_light]
|
||||
call frame_rect
|
||||
|
||||
cmp eax, -1
|
||||
je .next
|
||||
add ebx, 2 shl 16 - 4 ; a light line around it, from the
|
||||
add ecx, 2 shl 16 - 4 ; selected row too
|
||||
movzx edx, bx
|
||||
mul edx
|
||||
shr eax, 10
|
||||
mov bx, ax
|
||||
mcall SF_DRAW_RECT, , , [sc.work_button] ; as the graphs
|
||||
jmp .next
|
||||
|
||||
.icon:
|
||||
sub eax, ICON ; in the middle of the cell
|
||||
shr eax, 1
|
||||
add eax, [esp + PUSHA_EBX]
|
||||
shl eax, 16
|
||||
lea ecx, [ebp - (ICON - TEXT_H)/2]
|
||||
mov ax, cx
|
||||
xchg eax, ebx
|
||||
xchg eax, edx
|
||||
mov edx, [esp + PUSHA_SIZE + PUSHA_EDX] ; of the first one:
|
||||
; the background
|
||||
call draw_icon
|
||||
|
||||
.next:
|
||||
call col_width ; the next column after this one
|
||||
add [esp + PUSHA_EBX], eax ; its left
|
||||
popa
|
||||
|
||||
add esi, sizeof.COL
|
||||
cmp esi, [list.cols_end]
|
||||
jb .col
|
||||
popa
|
||||
ret
|
||||
|
||||
; esi -> column, edx -> its field in the row; out: edx -> the text of the
|
||||
; cell, "" for a bar or an icon
|
||||
cell_text:
|
||||
cmp byte [esi + COL.kind], KIND_STR
|
||||
jb .done
|
||||
mov edx, [edx]
|
||||
je .done
|
||||
|
||||
mov eax, edx
|
||||
mov edi, text_buf
|
||||
mov edx, edi
|
||||
mov byte [edi], 0 ; -1: unknown, nothing to show
|
||||
cmp eax, -1
|
||||
je .done
|
||||
|
||||
cmp byte [esi + COL.kind], KIND_SIZE
|
||||
jb .uint
|
||||
ja .hex
|
||||
jmp fmt_size
|
||||
|
||||
.hex:
|
||||
cmp byte [esi + COL.kind], KIND_HEX ; a bar or an icon: drawn below
|
||||
jne .done
|
||||
jmp fmt_hex
|
||||
|
||||
.uint:
|
||||
call fmt_uint
|
||||
cmp byte [esi + COL.kind], KIND_PCT
|
||||
jne .done
|
||||
mov word [edi], "%"
|
||||
|
||||
.done:
|
||||
ret
|
||||
|
||||
; esi -> column; out: CF = 1 if its caption and text go left: text and the
|
||||
; widest column, but the bar
|
||||
col_left:
|
||||
cmp byte [esi + COL.kind], KIND_NUM ; text: CF = 1
|
||||
jb .done
|
||||
cmp byte [esi + COL.kind], KIND_BAR ; the bar and icons: CF = 0
|
||||
jae .done
|
||||
cmp byte [esi + COL.width], 1 ; the widest: CF = 1
|
||||
|
||||
.done:
|
||||
ret
|
||||
|
||||
; esi -> column; out: eax = its width
|
||||
col_width:
|
||||
movzx eax, byte [esi + COL.width]
|
||||
test eax, eax
|
||||
jnz @f
|
||||
mov eax, [col_rest]
|
||||
|
||||
@@:
|
||||
ret
|
||||
|
||||
; The end of a scan: ebp -> the end of the view.
|
||||
list_done:
|
||||
sub ebp, [list.view]
|
||||
shr ebp, 2
|
||||
mov [list.count], ebp ; then list_sort
|
||||
|
||||
; Sort the view by the sorted column and find the selected row again.
|
||||
list_sort:
|
||||
mov ebp, [list.view]
|
||||
mov ecx, 1 ; insertion sort, stable
|
||||
|
||||
.outer:
|
||||
cmp ecx, [list.count]
|
||||
jae .select
|
||||
mov esi, [ebp + ecx*4]
|
||||
mov ebx, ecx
|
||||
|
||||
.inner:
|
||||
mov edi, [ebp + ebx*4 - 4]
|
||||
call list_less
|
||||
jnc .put
|
||||
mov [ebp + ebx*4], edi
|
||||
dec ebx
|
||||
jnz .inner
|
||||
|
||||
.put:
|
||||
mov [ebp + ebx*4], esi
|
||||
inc ecx
|
||||
jmp .outer
|
||||
|
||||
.select:
|
||||
mov ecx, [list.count]
|
||||
mov eax, [list.key]
|
||||
|
||||
@@:
|
||||
dec ecx
|
||||
js @f
|
||||
mov esi, [ebp + ecx*4]
|
||||
cmp [esi], eax
|
||||
jne @b
|
||||
mov [list.sel], ecx
|
||||
|
||||
@@:
|
||||
ret
|
||||
|
||||
; esi, edi -> rows; out: CF = 1 if esi goes before edi
|
||||
list_less:
|
||||
pusha
|
||||
mov ebx, [list.sort]
|
||||
movzx ecx, byte [ebx + COL.field]
|
||||
add esi, ecx
|
||||
add edi, ecx
|
||||
|
||||
cmp [list.desc], 0
|
||||
je @f
|
||||
xchg esi, edi
|
||||
|
||||
@@:
|
||||
cmp byte [ebx + COL.kind], KIND_STR
|
||||
ja .num
|
||||
jb @f
|
||||
mov esi, [esi] ; the text by its pointer
|
||||
mov edi, [edi]
|
||||
|
||||
@@:
|
||||
lodsb ; the letters of either case alike
|
||||
mov ah, [edi]
|
||||
inc edi
|
||||
mov dl, al
|
||||
or ax, 0x2020
|
||||
cmp al, ah
|
||||
jne @f
|
||||
test dl, dl
|
||||
jz @f
|
||||
cmp byte [edi - 1], 0 ; the end of edi, not a blank
|
||||
jne @b
|
||||
|
||||
@@:
|
||||
popa
|
||||
ret
|
||||
|
||||
.num: ; -1, unknown, before 0
|
||||
mov eax, [esi]
|
||||
inc eax
|
||||
mov edx, [edi]
|
||||
inc edx
|
||||
cmp eax, edx
|
||||
popa
|
||||
ret
|
||||
|
||||
; An arrow up, or down if edi = 1: a triangle of 4 lines, line i of 2*i + 1
|
||||
; pixels, its tip at x = ebx shr 16, around the middle of the capitals of
|
||||
; text at y = bx.
|
||||
draw_arrow:
|
||||
pusha
|
||||
lea ecx, [edi*2 + edi + TEXT_H/2 - 2] ; from the top if it
|
||||
add cx, bx ; goes up, else from the bottom
|
||||
shl ecx, 16
|
||||
inc ecx
|
||||
|
||||
shl edi, 17 ; the next line: 1 down or up
|
||||
neg edi
|
||||
add edi, 1 shl 16
|
||||
|
||||
mov bx, 1
|
||||
mov esi, 4
|
||||
|
||||
@@:
|
||||
mcall SF_DRAW_RECT, , , [sc.work_text]
|
||||
add ebx, (-1 shl 16) + 2
|
||||
add ecx, edi
|
||||
dec esi
|
||||
jnz @b
|
||||
|
||||
popa
|
||||
ret
|
||||
|
||||
; eax = rows the wheel moves, esi = mouse buttons: box_lib moves the list,
|
||||
; again while held; out: ebp = list.first before, drawn again if it changes
|
||||
scroll_mouse:
|
||||
mov ebp, [list.first]
|
||||
add [list.first], eax
|
||||
|
||||
call sb_set
|
||||
|
||||
xor eax, eax
|
||||
mov edi, [rows] ; all rows seen: no thumb to drag
|
||||
cmp edi, [list.count]
|
||||
jae @f
|
||||
|
||||
push sb
|
||||
call [scrollbar_v_mouse]
|
||||
|
||||
mov eax, [sb.position]
|
||||
xchg eax, [list.first]
|
||||
sub eax, [list.first] ; moved while held: again after 10
|
||||
jz @f ; waits of the main loop if pressed
|
||||
|
||||
mov eax, esi ; now, else after 2
|
||||
and eax, MB_LEFT
|
||||
jz @f
|
||||
mov al, 2
|
||||
test esi, MB_LEFT_DOWN
|
||||
jz @f
|
||||
mov al, 10
|
||||
|
||||
@@:
|
||||
mov [repeat_at], eax
|
||||
ret
|
||||
|
||||
sb_set: ; the list state to it
|
||||
mov eax, [area_w]
|
||||
add eax, PAD - SB_W
|
||||
mov [sb.x_pos], ax
|
||||
mov eax, [area_h]
|
||||
mov [sb.y_size], ax
|
||||
|
||||
mov [sb.all_redraw], 1
|
||||
mov edi, sb.max_area
|
||||
|
||||
mov eax, [list.count]
|
||||
stosd
|
||||
mov eax, [rows]
|
||||
stosd
|
||||
mov eax, [list.first]
|
||||
stosd
|
||||
mov eax, [sc.work_dark]
|
||||
stosd
|
||||
mov eax, [mid]
|
||||
stosd
|
||||
mov eax, [sc.work_graph]
|
||||
stosd
|
||||
ret
|
||||
|
||||
; Keep sel and first in range and remember the selected row.
|
||||
list_clamp:
|
||||
pusha
|
||||
mov ecx, [list.count]
|
||||
mov edi, list.sel
|
||||
call clamp
|
||||
|
||||
jecxz @f
|
||||
mov edx, [list.view]
|
||||
mov eax, [edx + eax*4]
|
||||
mov eax, [eax]
|
||||
mov [list.key], eax
|
||||
|
||||
@@:
|
||||
popa
|
||||
|
||||
pusha ; first in range
|
||||
mov ecx, [list.count]
|
||||
sub ecx, [rows]
|
||||
inc ecx
|
||||
mov edi, list.first
|
||||
call clamp
|
||||
popa
|
||||
ret
|
||||
|
||||
clamp: ; [edi] into [0, ecx - 1]
|
||||
mov eax, [edi]
|
||||
cmp eax, ecx
|
||||
jl @f
|
||||
lea eax, [ecx - 1]
|
||||
|
||||
@@:
|
||||
test eax, eax
|
||||
jns @f
|
||||
xor eax, eax
|
||||
|
||||
@@:
|
||||
stosd
|
||||
ret
|
||||
|
||||
list_key: ; al = key
|
||||
mov esi, [list.keys]
|
||||
|
||||
.hotkey:
|
||||
mov ah, [esi + HOTKEY.key]
|
||||
test ah, ah
|
||||
jz .move
|
||||
add esi, sizeof.HOTKEY
|
||||
cmp ah, al
|
||||
jne .hotkey
|
||||
movzx eax, [esi - sizeof.HOTKEY + HOTKEY.trigger]
|
||||
jmp eax
|
||||
|
||||
.move:
|
||||
sub al, KEY_DOWN
|
||||
cmp al, KEY_PGUP - KEY_DOWN
|
||||
ja .done
|
||||
|
||||
movzx eax, al
|
||||
movsx edx, byte [.moves + eax*2 + 1]
|
||||
imul edx, [rows]
|
||||
movsx eax, byte [.moves + eax*2]
|
||||
add edx, eax
|
||||
|
||||
add [list.sel], edx
|
||||
call list_clamp
|
||||
|
||||
mov ebx, [list.sel] ; scroll to the selection
|
||||
mov ecx, [rows]
|
||||
sub ebx, ecx
|
||||
inc ebx
|
||||
sub [list.first], ebx
|
||||
mov edi, list.first
|
||||
call clamp
|
||||
add [list.first], ebx
|
||||
jmp list_rows
|
||||
|
||||
.done:
|
||||
ret
|
||||
|
||||
; rows, pages for the keys KEY_DOWN..KEY_PGUP: down, up, right, home, end,
|
||||
; del, pgdn, pgup
|
||||
.moves db 1, 0, -1, 0, 0, 0, 0, -128, 0, 127, 0, 0, 0, 1, 0, -1
|
||||
|
||||
; Wheel scrolls; left button selects a row, sorts by a column or moves the
|
||||
; scrollbar; right click opens the row.
|
||||
list_mouse:
|
||||
call get_mouse
|
||||
imul eax, 3
|
||||
call scroll_mouse ; every event: it follows a drag
|
||||
|
||||
test esi, MB_LEFT + MB_RIGHT_DOWN
|
||||
jz .moved
|
||||
|
||||
sub ebx, PAD ; inside the list, left of the
|
||||
jle .moved ; scrollbar
|
||||
mov eax, [area_w]
|
||||
sub eax, SB_W
|
||||
cmp ebx, eax
|
||||
jge .moved
|
||||
|
||||
sub ecx, AREA_Y + HDR_H + 2
|
||||
jl .header
|
||||
|
||||
test esi, MB_LEFT_DOWN + MB_RIGHT_DOWN ; a row: not dragged to
|
||||
jz .moved
|
||||
|
||||
xchg eax, ecx
|
||||
xor edx, edx
|
||||
mov ecx, ROW_H
|
||||
div ecx
|
||||
cmp eax, [rows]
|
||||
jae .moved
|
||||
|
||||
add eax, [list.first]
|
||||
cmp eax, [list.count]
|
||||
jae .moved
|
||||
|
||||
mov [list.sel], eax
|
||||
shr esi, 9 ; MB_RIGHT_DOWN: 0 left, 1 right
|
||||
and esi, 1
|
||||
push [list.left + esi*4] ; the selection drawn, then list_rows
|
||||
jmp list_rows ; returns to the trigger
|
||||
|
||||
.moved: ; a drag of the thumb keeps its pixels
|
||||
cmp ebp, [list.first]
|
||||
jne list_rows
|
||||
ret
|
||||
|
||||
.header:
|
||||
cmp ecx, -(HDR_H + 1)
|
||||
jl .moved
|
||||
test esi, MB_LEFT_DOWN
|
||||
jz .moved
|
||||
|
||||
mov esi, [list.cols] ; the column under the cursor
|
||||
dec ebx
|
||||
|
||||
.col:
|
||||
call col_width
|
||||
sub ebx, eax
|
||||
jl .sort
|
||||
add esi, sizeof.COL
|
||||
cmp esi, [list.cols_end]
|
||||
jb .col
|
||||
ret
|
||||
|
||||
.sort: ; again: the other way, else its own
|
||||
xor eax, eax
|
||||
cmp byte [esi + COL.kind], KIND_PCT
|
||||
setae al
|
||||
cmp esi, [list.sort]
|
||||
jne .order
|
||||
mov eax, [list.desc]
|
||||
xor al, 1
|
||||
|
||||
.order:
|
||||
mov [list.desc], eax
|
||||
mov [list.sort], esi
|
||||
call list_sort
|
||||
jmp list_draw
|
||||
|
||||
; out: esi = mouse buttons held, in bits 8.. the ones pressed, not held at
|
||||
; the last event, and the mouse not moved since; ebx, ecx = x, y in the
|
||||
; client area; eax = the wheel
|
||||
get_mouse:
|
||||
mcall SF_MOUSE_GET, SSF_BUTTON_EXT
|
||||
mov esi, eax
|
||||
movzx eax, al
|
||||
xchg al, byte [buttons]
|
||||
shl eax, 8
|
||||
not eax
|
||||
and esi, eax
|
||||
|
||||
mcall SF_MOUSE_GET, SSF_WINDOW_POSITION
|
||||
movsx ecx, ax ; in the client area
|
||||
sar eax, 16
|
||||
xchg edx, eax
|
||||
|
||||
mcall SF_MOUSE_GET, SSF_SCROLL_DATA
|
||||
mov ebx, edx
|
||||
movsx eax, ax ; the wheel
|
||||
ret
|
||||
|
||||
no_keys db 0 ; HOTKEYs of a list without them
|
||||
|
||||
uglobal
|
||||
align 4
|
||||
list LIST
|
||||
rows dd ? ; that fit the panel
|
||||
col_rest dd ? ; the width of the widest column
|
||||
repeat_at dd ? ; waits till a held arrow repeats
|
||||
endg
|
||||
@@ -0,0 +1,94 @@
|
||||
; Strings in UTF-8; the caption starts with its encoding byte.
|
||||
|
||||
if lang eq ru_RU
|
||||
sz_title db 3, "Диспетчер задач", 0
|
||||
sz_tab_procs db "Процессы", 0
|
||||
sz_tab_perf db "Нагрузка", 0
|
||||
sz_tab_disks db "Диски", 0
|
||||
sz_col_free db "Свободно", 0
|
||||
sz_run db "Запустить...", 0
|
||||
sz_kill db "Завершить", 0
|
||||
sz_shutdown db "Завершение работы...", 0
|
||||
sz_info db "Детали", 0
|
||||
sz_system db "Системные", 0
|
||||
sz_col_name db "Имя", 0
|
||||
sz_col_cpu db "ЦП", 0
|
||||
sz_col_mem db "Память", 0
|
||||
sz_freq db "Частота", 0
|
||||
sz_mhz db " МГц", 0
|
||||
sz_uptime db "Время работы", 0
|
||||
sz_threads db "Потоки", 0
|
||||
sz_used db "Занято", 0
|
||||
sz_total db "Всего", 0
|
||||
sz_temp db "Температура", 0
|
||||
sz_net db "Сеть", 0
|
||||
sz_received db "Принято", 0
|
||||
sz_sent db "Отправлено", 0
|
||||
sz_crit db "Критическая", 0
|
||||
sz_units db " КБ", 0, " МБ", 0, " ГБ", 0, " ТБ", 0
|
||||
sz_bits db " бит/с", 0, " Кбит/с", 0, " Мбит/с", 0, " Гбит/с", 0
|
||||
|
||||
else if lang eq es_ES
|
||||
sz_title db 3, "Gestor de tareas", 0
|
||||
sz_tab_procs db "Procesos", 0
|
||||
sz_tab_perf db "Recursos", 0
|
||||
sz_tab_disks db "Discos", 0
|
||||
sz_col_free db "Libre", 0
|
||||
sz_run db "Ejecutar...", 0
|
||||
sz_kill db "Finalizar", 0
|
||||
sz_shutdown db "Apagar el sistema...", 0
|
||||
sz_info db "Detalles", 0
|
||||
sz_system db "Sistema", 0
|
||||
sz_col_name db "Nombre", 0
|
||||
sz_col_cpu db "CPU", 0
|
||||
sz_col_mem db "Memoria", 0
|
||||
sz_freq db "Frecuencia", 0
|
||||
sz_uptime db "Activo", 0
|
||||
sz_threads db "Hilos", 0
|
||||
sz_used db "En uso", 0
|
||||
sz_total db "Total", 0
|
||||
sz_temp db "Temperatura", 0
|
||||
sz_net db "Red", 0
|
||||
sz_received db "Recibido", 0
|
||||
sz_sent db "Enviado", 0
|
||||
sz_crit db "Crítica", 0
|
||||
|
||||
else
|
||||
sz_title db 3, "Task Manager", 0
|
||||
sz_tab_procs db "Processes", 0
|
||||
sz_tab_perf db "Performance", 0
|
||||
sz_tab_disks db "Disks", 0
|
||||
sz_col_free db "Free", 0
|
||||
sz_run db "Run...", 0
|
||||
sz_kill db "End", 0
|
||||
sz_shutdown db "Shut down...", 0
|
||||
sz_info db "Details", 0
|
||||
sz_system db "System", 0
|
||||
sz_col_name db "Name", 0
|
||||
sz_col_cpu db "CPU", 0
|
||||
sz_col_mem db "Memory", 0
|
||||
sz_freq db "Frequency", 0
|
||||
sz_uptime db "Uptime", 0
|
||||
sz_threads db "Threads", 0
|
||||
sz_used db "Used", 0
|
||||
sz_total db "Total", 0
|
||||
sz_temp db "Temperature", 0
|
||||
sz_net db "Network", 0
|
||||
sz_received db "Received", 0
|
||||
sz_sent db "Sent", 0
|
||||
sz_crit db "Critical", 0
|
||||
end if
|
||||
|
||||
if ~ lang eq ru_RU
|
||||
sz_mhz db " MHz", 0
|
||||
sz_units db " KB", 0, " MB", 0, " GB", 0, " TB", 0
|
||||
sz_bits db " bit/s", 0, " kbit/s", 0, " Mbit/s", 0, " Gbit/s", 0
|
||||
end if
|
||||
sz_col_id db "ID", 0
|
||||
if lang eq ru_RU | lang eq es_ES
|
||||
sz_col_num db "Nº", 0
|
||||
else
|
||||
sz_col_num db " #", 0
|
||||
end if
|
||||
sz_deg db " °C", 0
|
||||
sz_pct db "%", 0
|
||||
@@ -0,0 +1,386 @@
|
||||
; Temperature on the Performance tab: the sensor of the CPU (Intel from
|
||||
; Core, AMD from K8, Hygon, VIA C7, Nano and Zhaoxin; the rules are those
|
||||
; of Linux coretemp, k8temp, k10temp and via-cputemp), else the first one
|
||||
; of a monitoring chip of the board (hwmon.inc).
|
||||
|
||||
MSR_THERM_STATUS = 0x19C ; Intel: the core, the package,
|
||||
MSR_PKG_THERM = 0x1B1 ; TjMax in bits 16-23
|
||||
MSR_TEMP_TARGET = 0x1A2
|
||||
MSR_VIA_TEMP = 0x1423 ; Nano and Zhaoxin, C7
|
||||
MSR_C7_TEMP = 0x1169
|
||||
|
||||
AMD_NB = 0xC300 ; PCI 00:18.3, then its registers:
|
||||
K8_THERMTRIP = 0xC3E4 ; K8, the others to Family 16h
|
||||
NB_TEMP = 0xC3A4
|
||||
VENDOR_AMD = 0x1022
|
||||
VENDOR_HYGON = 0x1D94
|
||||
SMN_ZEN_TEMP = 0x59800 ; the address, the index register
|
||||
SMN_ZEN_INDEX = 0x60 ; on the root complex, 00:00.0
|
||||
SMN_F15_TEMP = 0xD8200CA4 ; Family 15h from model 60h
|
||||
SMN_F15_INDEX = 0xB8
|
||||
|
||||
; The sensor of the CPU, else the chip; the temperature graph if any.
|
||||
sensors_init:
|
||||
pusha
|
||||
call cpu_sensor
|
||||
cmp [cpu_temp], chip_temp
|
||||
je .chip
|
||||
|
||||
mcall SF_THREAD_CONTROL, SSF_CREATE_THREAD, msr_probe, probe_stack_top
|
||||
mov esi, 20 ; up to 0.2 s
|
||||
|
||||
@@:
|
||||
cmp [probe], 2
|
||||
je @f
|
||||
mcall SF_SLEEP, 1
|
||||
dec esi
|
||||
jnz @b
|
||||
|
||||
@@:
|
||||
cmp [probe], 0
|
||||
jne @f
|
||||
mov [cpu_temp], chip_temp ; the kernel killed the probe
|
||||
|
||||
@@:
|
||||
cmp [tjmax], 0
|
||||
jne .chip
|
||||
mov byte [tjmax], 100
|
||||
|
||||
.chip:
|
||||
cmp [cpu_temp], chip_temp ; the chip for a CPU without a sensor
|
||||
jne .temp
|
||||
call hwm_init
|
||||
test eax, eax
|
||||
jz @f
|
||||
|
||||
.temp:
|
||||
inc [temp_on] ; a graph for any sensor
|
||||
|
||||
@@:
|
||||
cmp [cpu_temp], intel_temp ; TjMax of Intel only
|
||||
je @f
|
||||
mov [temp_graph.info], no_info
|
||||
|
||||
@@:
|
||||
popa
|
||||
ret
|
||||
|
||||
; cpu_temp and what it reads, by the vendor and the model
|
||||
cpu_sensor:
|
||||
pushfd ; CPUID if the ID flag can be changed
|
||||
pop eax
|
||||
xor eax, 1 shl 21
|
||||
push eax
|
||||
popfd
|
||||
pushfd
|
||||
pop ecx
|
||||
cmp eax, ecx
|
||||
jne .done
|
||||
|
||||
xor eax, eax
|
||||
cpuid
|
||||
mov esi, eax ; the last leaf
|
||||
mov edi, ebx ; vendor
|
||||
|
||||
mov eax, 1
|
||||
cpuid
|
||||
mov ebp, eax ; signature
|
||||
|
||||
movzx ecx, ah
|
||||
and cl, 0xF ; family
|
||||
movzx edx, al
|
||||
shr edx, 4 ; model
|
||||
|
||||
cmp cl, 6
|
||||
jb @f
|
||||
shr eax, 12
|
||||
and al, 0xF0
|
||||
or dl, al
|
||||
cmp cl, 0xF
|
||||
jne @f
|
||||
movzx eax, ah
|
||||
add ecx, eax
|
||||
|
||||
@@:
|
||||
cmp edi, "Genu"
|
||||
je intel_sensor
|
||||
cmp edi, " Sh" ; C7, Nano and Zhaoxin, the probe
|
||||
je via_sensor ; drops the others
|
||||
cmp edi, "Cent"
|
||||
je via_sensor
|
||||
cmp edi, "Auth"
|
||||
je amd_sensor
|
||||
cmp edi, "Hygo"
|
||||
je amd_sensor
|
||||
|
||||
.done:
|
||||
ret
|
||||
|
||||
; ecx = family, edx = model, esi = the last leaf of CPUID, ebp = signature
|
||||
intel_sensor:
|
||||
cmp esi, 6
|
||||
jb .done
|
||||
push ecx edx
|
||||
mov eax, 6
|
||||
cpuid
|
||||
pop edx ecx
|
||||
|
||||
test al, 1 ; digital thermal sensor
|
||||
jz .done
|
||||
mov [cpu_temp], intel_temp
|
||||
test al, 1 shl 6 ; the package one
|
||||
jz @f
|
||||
mov [therm_msr], MSR_PKG_THERM
|
||||
mov [therm_valid], 1 shl 31 ; it has no "reading valid" bit
|
||||
|
||||
@@:
|
||||
cmp ecx, 6 ; TjMax: 100 before Nehalem,
|
||||
jne .done ; then from the CPU but on Atoms
|
||||
cmp edx, 0x1A
|
||||
jb .done
|
||||
mov esi, .atoms
|
||||
@@:
|
||||
lodsw
|
||||
test al, al
|
||||
jz @f ; 0: msr_probe reads it
|
||||
cmp al, dl
|
||||
jne @b
|
||||
@@:
|
||||
mov byte [tjmax], ah
|
||||
|
||||
cmp dl, 0x1C ; Pineview: stepping 10
|
||||
jne .done
|
||||
and ebp, 0xF
|
||||
cmp ebp, 10
|
||||
jne .done
|
||||
mov byte [tjmax], 100
|
||||
|
||||
.done:
|
||||
ret
|
||||
|
||||
; TjMax of Atoms without MSR_TEMPERATURE_TARGET, and Xeon 7400
|
||||
.atoms db 0x1C, 90, 0x1D, 100, 0x26, 90, 0x27, 90, 0x35, 90, 0x36, 100, 0, 0
|
||||
|
||||
; ecx = family, edx = model
|
||||
via_sensor:
|
||||
mov eax, MSR_VIA_TEMP
|
||||
cmp ecx, 6
|
||||
ja @f
|
||||
cmp dl, 0xF
|
||||
jae @f
|
||||
mov ax, MSR_C7_TEMP
|
||||
|
||||
@@:
|
||||
mov [therm_msr], eax
|
||||
mov [cpu_temp], via_temp
|
||||
ret
|
||||
|
||||
; ecx = family, edx = model
|
||||
amd_sensor:
|
||||
cmp ecx, 0xF
|
||||
jb .done
|
||||
ja .k10
|
||||
|
||||
push edx ; K8 with a thermal sensor
|
||||
mov eax, 0x80000007
|
||||
cpuid
|
||||
test dl, 1
|
||||
pop edx
|
||||
jz .done
|
||||
|
||||
cmp dl, 0x69 ; revision G desktops read lower
|
||||
jb @f
|
||||
xchg eax, edx
|
||||
mov edi, .k8_mobile
|
||||
mov ecx, 3
|
||||
repne scasb
|
||||
je @f
|
||||
mov [k8_zero], 49 - 21
|
||||
@@:
|
||||
mov esi, k8_temp
|
||||
jmp .nb
|
||||
|
||||
.k10:
|
||||
mov eax, SMN_ZEN_TEMP ; Zen
|
||||
mov [smn_index], SMN_ZEN_INDEX
|
||||
cmp ecx, 0x17
|
||||
jae .smn
|
||||
|
||||
mov eax, SMN_F15_TEMP
|
||||
mov [smn_index], SMN_F15_INDEX
|
||||
cmp ecx, 0x15
|
||||
jne @f
|
||||
cmp edx, 0x60
|
||||
jae .smn
|
||||
|
||||
@@:
|
||||
cmp ecx, 0x16
|
||||
ja .done
|
||||
mov esi, amd_nb_temp
|
||||
|
||||
.nb:
|
||||
mov ecx, AMD_NB
|
||||
jmp .pci
|
||||
|
||||
.smn:
|
||||
mov [smn_addr], eax
|
||||
xor ecx, ecx
|
||||
mov esi, amd_smn_temp
|
||||
|
||||
.pci: ; esi = the procedure, if the
|
||||
call pci_read ; device is AMD or Hygon
|
||||
cmp ax, VENDOR_AMD
|
||||
je @f
|
||||
cmp ax, VENDOR_HYGON
|
||||
jne .done
|
||||
@@:
|
||||
mov [cpu_temp], esi
|
||||
|
||||
.done:
|
||||
ret
|
||||
|
||||
.k8_mobile db 0x6C, 0x7C, 0xC1
|
||||
|
||||
; ecx = device shl 8 + register on bus 0; out: eax
|
||||
pci_read: ; the callers keep ebx
|
||||
mcall SF_PCI, SSF_READ_DWORD
|
||||
ret
|
||||
|
||||
; out: eax = temperature of the CPU, CF = 1 if unknown
|
||||
via_temp:
|
||||
call read_therm
|
||||
and eax, 0xFFFFFF
|
||||
ret
|
||||
|
||||
; out: eax = the low dword of [therm_msr]
|
||||
read_therm:
|
||||
mcall SF_SYS_MISC, SSF_READ_MSR, , [therm_msr]
|
||||
ret
|
||||
|
||||
intel_temp:
|
||||
call read_therm
|
||||
or eax, [therm_valid] ; the reading is valid
|
||||
jns no_temp
|
||||
|
||||
shr eax, 16
|
||||
and eax, 0x7F
|
||||
neg eax
|
||||
add eax, [tjmax]
|
||||
clc
|
||||
ret
|
||||
|
||||
k8_temp:
|
||||
mov ecx, K8_THERMTRIP
|
||||
call pci_read
|
||||
|
||||
shr eax, 16
|
||||
movzx eax, al
|
||||
sub eax, [k8_zero]
|
||||
clc
|
||||
ret
|
||||
|
||||
amd_smn_temp:
|
||||
mcall SF_PCI, SSF_WRITE_DWORD, [smn_index], [smn_addr]
|
||||
add ecx, 4 ; the data after the index
|
||||
call pci_read
|
||||
|
||||
test eax, 1 shl 19 ; the range is -49..206
|
||||
jz amd_temp
|
||||
or eax, 3 shl 16
|
||||
jmp amd_temp
|
||||
|
||||
amd_nb_temp:
|
||||
mov ecx, NB_TEMP
|
||||
call pci_read ; then amd_temp
|
||||
|
||||
; eax = the reported temperature of AMD
|
||||
amd_temp:
|
||||
mov edx, eax
|
||||
shr eax, 24 ; 1/8 of a degree from bit 21
|
||||
and edx, 3 shl 16
|
||||
cmp edx, 3 shl 16
|
||||
jne @f
|
||||
sub eax, 49
|
||||
|
||||
@@:
|
||||
clc
|
||||
ret
|
||||
|
||||
chip_temp: ; none in the CPU: the first of the chip
|
||||
mov eax, [hwm_temp]
|
||||
jmp @b
|
||||
|
||||
no_temp:
|
||||
stc
|
||||
ret
|
||||
|
||||
; A thread reads the MSRs first: if one is not there, the kernel kills
|
||||
; the thread, not the program.
|
||||
msr_probe:
|
||||
call [cpu_temp]
|
||||
inc [probe]
|
||||
|
||||
cmp [tjmax], 0
|
||||
jne @f
|
||||
mcall SF_SYS_MISC, SSF_READ_MSR, , MSR_TEMP_TARGET
|
||||
shr eax, 16
|
||||
test al, al ; 0 in some virtual machines
|
||||
jz @f
|
||||
mov byte [tjmax], al
|
||||
|
||||
@@:
|
||||
inc [probe]
|
||||
mcall SF_TERMINATE_PROCESS
|
||||
|
||||
; Once a second: the sensors and the temperature for the graph
|
||||
sensors_read:
|
||||
pusha
|
||||
xor eax, eax
|
||||
call [hwm_read]
|
||||
cmp eax, 127 ; 127 and more: no sensor
|
||||
jb @f
|
||||
xor eax, eax
|
||||
@@:
|
||||
mov [hwm_temp], eax
|
||||
|
||||
call [cpu_temp]
|
||||
jnc .got
|
||||
mov eax, [last_temp] ; not valid this time
|
||||
|
||||
.got:
|
||||
mov [last_temp], eax
|
||||
mov edi, last_temp ; not below 0
|
||||
mov ecx, 1000
|
||||
call clamp
|
||||
|
||||
mov ecx, [hist_pos]
|
||||
mov [hist_temp + ecx*4], eax
|
||||
popa
|
||||
ret
|
||||
|
||||
; An ITEM of temp_info
|
||||
get_tjmax:
|
||||
mov eax, [tjmax]
|
||||
call fmt_uint ; then deg_unit
|
||||
|
||||
deg_unit:
|
||||
mov eax, sz_deg
|
||||
jmp fmt_unit
|
||||
|
||||
cpu_temp dd chip_temp ; the procedure
|
||||
therm_msr dd MSR_THERM_STATUS
|
||||
therm_valid dd 0
|
||||
tjmax dd 100
|
||||
k8_zero dd 49
|
||||
|
||||
uglobal
|
||||
align 4
|
||||
temp_on dd ? ; a graph of the temperature
|
||||
smn_addr dd ?
|
||||
smn_index dd ?
|
||||
last_temp dd ?
|
||||
probe dd ? ; 1: the sensor is read, 2: done
|
||||
rb 256
|
||||
probe_stack_top:
|
||||
hist_temp rd HIST_LEN
|
||||
endg
|
||||
@@ -0,0 +1,111 @@
|
||||
; Statistics shared by the tabs, once a second: the threads, their CPU and
|
||||
; memory, the history of the graphs.
|
||||
|
||||
struct PROC ; an item of `procs`
|
||||
pid dd ?
|
||||
cpu dd ? ; cycles / 256, then percent
|
||||
mem dd ? ; KB
|
||||
name rb 12 ; zero padded
|
||||
ends
|
||||
|
||||
struct RAM_INFO ; function 18.20
|
||||
total dd ? ; pages
|
||||
free dd ?
|
||||
page_faults dd ?
|
||||
heap_size dd ? ; the kernel heap, bytes
|
||||
heap_free dd ?
|
||||
heap_blocks dd ?
|
||||
heap_free_blocks dd ?
|
||||
heap_max_free dd ?
|
||||
heap_max_used dd ?
|
||||
ends
|
||||
|
||||
; The threads, their CPU and memory, the history of the graphs.
|
||||
sample:
|
||||
pusha
|
||||
mov edi, procs
|
||||
xor edx, edx ; cycles of all threads / 256
|
||||
xor ecx, ecx
|
||||
|
||||
.slot:
|
||||
inc ecx
|
||||
mcall SF_THREAD_INFO, pinfo
|
||||
mov ebp, eax ; the last slot
|
||||
cmp [pinfo.slot_state], TSTATE_FREE
|
||||
je .next
|
||||
|
||||
mov eax, [ebx + process_information.PID]
|
||||
stosd ; PROC.pid
|
||||
mov eax, [ebx + process_information.cpu_usage]
|
||||
shr eax, 8 ; the sum fits 32 bits
|
||||
stosd ; PROC.cpu
|
||||
add edx, eax
|
||||
mov eax, [ebx + process_information.used_memory]
|
||||
inc eax
|
||||
shr eax, 10
|
||||
stosd ; PROC.mem
|
||||
|
||||
lea esi, [ebx + process_information.process_name]
|
||||
movsd ; PROC.name: 11 bytes and 0
|
||||
movsd
|
||||
movsd
|
||||
mov byte [edi - 1], 0
|
||||
|
||||
cmp edi, procs + MAX_PROCS * sizeof.PROC
|
||||
jae .done
|
||||
|
||||
.next:
|
||||
cmp ecx, ebp
|
||||
jb .slot
|
||||
|
||||
.done:
|
||||
mov [procs_end], edi
|
||||
|
||||
; Percent of CPU = cycles of the thread / 1% of cycles of all threads.
|
||||
xchg eax, edx
|
||||
cdq
|
||||
mov ecx, 100
|
||||
div ecx
|
||||
inc eax
|
||||
xchg eax, ecx
|
||||
|
||||
mov esi, procs
|
||||
@@:
|
||||
mov eax, [esi + PROC.cpu]
|
||||
cdq
|
||||
div ecx
|
||||
mov [esi + PROC.cpu], eax
|
||||
add esi, sizeof.PROC
|
||||
cmp esi, edi
|
||||
jb @b
|
||||
|
||||
inc [hist_pos] ; the place of this sample
|
||||
and [hist_pos], HIST_LEN - 1
|
||||
|
||||
mcall SF_SYSTEM, SSF_GET_RAM_INFO, ram_info
|
||||
mov eax, [ram_info.total]
|
||||
sub eax, [ram_info.free]
|
||||
imul eax, 100
|
||||
cdq
|
||||
div [ram_info.total]
|
||||
|
||||
call sensors_read
|
||||
call net_sample
|
||||
|
||||
mov ecx, [hist_pos]
|
||||
mov [hist_mem + ecx*4], eax
|
||||
mov eax, 100
|
||||
sub eax, dword [procs + PROC.cpu] ; the first thread is IDLE
|
||||
mov [hist_cpu + ecx*4], eax
|
||||
popa
|
||||
ret
|
||||
|
||||
uglobal
|
||||
align 4
|
||||
ram_info RAM_INFO
|
||||
hist_pos dd ?
|
||||
hist_cpu rd HIST_LEN
|
||||
hist_mem rd HIST_LEN
|
||||
procs_end dd ?
|
||||
procs rb MAX_PROCS * sizeof.PROC
|
||||
endg
|
||||
@@ -0,0 +1,231 @@
|
||||
; Autorun tab: the programs /sys/LAUNCHER starts from /sys/settings/autorun.dat.
|
||||
; A line is: program parameters delay; "text" may hold spaces, # starts
|
||||
; a comment. A program after # is turned off: the button or Space turns it
|
||||
; on or off in the file.
|
||||
|
||||
struct AR
|
||||
prog dd ?
|
||||
params dd ?
|
||||
delay dd ?
|
||||
num dd ? ; of the entry
|
||||
off db ? ; 1: after #, turned off
|
||||
ends
|
||||
|
||||
; Read the file, its lines into the list.
|
||||
autorun_load:
|
||||
mcall SF_FILE, autorun_info ; its size; read a byte more to see
|
||||
mov ecx, [autorun_bdfe.FileSizeLow] ; its end
|
||||
test eax, eax
|
||||
jz @f
|
||||
xor ecx, ecx
|
||||
|
||||
@@:
|
||||
inc ecx
|
||||
mov [autorun_file.Count], ecx
|
||||
inc ecx ; a # more, then 0
|
||||
inc ecx
|
||||
mcall SF_SYS_MISC, SSF_MEM_REALLOC, , [autorun_file.Buffer]
|
||||
mov [autorun_file.Buffer], eax
|
||||
mov [autorun_save.Buffer], eax
|
||||
mov ebp, [list.view]
|
||||
test eax, eax
|
||||
jz list_done
|
||||
|
||||
mcall SF_FILE, autorun_file
|
||||
cmp eax, 6 ; the end of the file: all of it
|
||||
je @f
|
||||
xor ebx, ebx
|
||||
|
||||
@@:
|
||||
mov esi, [autorun_file.Buffer]
|
||||
mov byte [esi + ebx], 0
|
||||
add ebx, esi
|
||||
|
||||
mov edi, esi ; the rows: at most the bytes that
|
||||
xor edx, edx ; may end a line, 0..13, and one
|
||||
|
||||
.count:
|
||||
inc edx
|
||||
@@:
|
||||
cmp edi, ebx
|
||||
jae @f
|
||||
cmp byte [edi], 14
|
||||
inc edi
|
||||
jb .count
|
||||
jmp @b
|
||||
|
||||
@@:
|
||||
imul ecx, edx, 4 + sizeof.AR ; the view, then the rows
|
||||
push ebx edx
|
||||
mcall SF_SYS_MISC, SSF_MEM_REALLOC, , [list.view]
|
||||
pop edx ebx
|
||||
mov [list.view], eax
|
||||
mov ebp, eax
|
||||
lea edi, [eax + edx*4]
|
||||
test eax, eax
|
||||
jz list_done
|
||||
|
||||
.line:
|
||||
cmp esi, ebx
|
||||
jae list_done
|
||||
|
||||
push esi
|
||||
@@:
|
||||
lodsb ; find the end of the line
|
||||
cmp al, 13
|
||||
je @f
|
||||
cmp al, 10
|
||||
je @f
|
||||
test al, al
|
||||
jnz @b
|
||||
|
||||
@@:
|
||||
mov byte [esi - 1], 0
|
||||
xchg esi, [esp]
|
||||
|
||||
call get_token ; the row goes to edi, its pointer to ebp
|
||||
cmp byte [eax], 0 ; empty line
|
||||
je .next
|
||||
cmp word [eax], "#/" ; a program turned off
|
||||
je @f
|
||||
cmp byte [eax], "#" ; comment
|
||||
je .next
|
||||
|
||||
@@:
|
||||
mov dl, [eax]
|
||||
mov [ebp], edi
|
||||
add ebp, 4
|
||||
stosd ; AR.prog, params, delay
|
||||
|
||||
call get_token
|
||||
stosd
|
||||
call get_token
|
||||
stosd
|
||||
|
||||
mov eax, ebp
|
||||
sub eax, [list.view]
|
||||
shr eax, 2
|
||||
stosd
|
||||
cmp dl, "#" ; AR.off
|
||||
sete al
|
||||
stosb
|
||||
|
||||
.next:
|
||||
pop esi
|
||||
jmp .line
|
||||
|
||||
; Put # before the selected program or take it away and save the file.
|
||||
autorun_toggle:
|
||||
cmp [list.count], 0 ; no rows, maybe no buffer
|
||||
je .done
|
||||
mcall SF_FILE, autorun_file ; the file again, as it is
|
||||
cmp eax, 6 ; all of it
|
||||
jne .done
|
||||
|
||||
mov edi, [list.key] ; AR.prog: the line in the buffer
|
||||
mov ecx, [autorun_file.Buffer]
|
||||
add ecx, ebx
|
||||
sub ecx, edi ; not past the end: the file was cut
|
||||
jbe .done
|
||||
|
||||
cmp byte [edi], "#"
|
||||
je .on
|
||||
|
||||
lea esi, [edi + ecx - 1] ; one byte on from the end
|
||||
lea edi, [esi + 1]
|
||||
std
|
||||
rep movsb
|
||||
cld
|
||||
|
||||
mov byte [edi], "#"
|
||||
inc ebx
|
||||
jmp .save
|
||||
|
||||
.on:
|
||||
lea esi, [edi + 1]
|
||||
dec ecx
|
||||
rep movsb
|
||||
dec ebx
|
||||
|
||||
.save:
|
||||
mov [autorun_save.Count], ebx
|
||||
mcall SF_FILE, autorun_save
|
||||
call autorun_load
|
||||
jmp list_rows
|
||||
|
||||
.done:
|
||||
ret
|
||||
|
||||
; esi -> text; out: eax -> the next word or "text", cut with zero; esi after it
|
||||
get_token:
|
||||
mov eax, esi
|
||||
mov dh, [esi]
|
||||
test dh, dh
|
||||
jz .done
|
||||
inc esi
|
||||
cmp dh, " " ; skip blanks
|
||||
jbe get_token
|
||||
|
||||
mov cx, " " shl 8 ; a word ends with a blank
|
||||
cmp dh, '"'
|
||||
jne .next
|
||||
mov cx, '"' ; "text" with the quote
|
||||
mov eax, esi
|
||||
|
||||
.next:
|
||||
mov dh, [esi]
|
||||
test dh, dh
|
||||
jz .done
|
||||
inc esi
|
||||
sub dh, cl ; cl..cl + ch ends it
|
||||
cmp dh, ch
|
||||
ja .next
|
||||
|
||||
mov byte [esi - 1], 0
|
||||
.done:
|
||||
ret
|
||||
|
||||
autorun_bar:
|
||||
BAR BAR_BUTTON, sz_ar_toggle, sc.work_button
|
||||
db BAR_END
|
||||
|
||||
autorun_list LIST autorun_cols, autorun_cols_end, autorun_cols, nothing, nothing, autorun_keys, AR.off, 0, 0, 0, 0, 0, 0 ; the view on the heap
|
||||
autorun_keys:
|
||||
HOTKEY KEY_SPACE, autorun_toggle
|
||||
db 0
|
||||
autorun_cols:
|
||||
COL sz_col_num, AR.num, KIND_NUM, ID_W
|
||||
COL sz_col_program, AR.prog, KIND_STR, 0
|
||||
COL sz_col_params, AR.params, KIND_STR, COL_W
|
||||
COL sz_col_delay, AR.delay, KIND_STR, COL_W
|
||||
autorun_cols_end:
|
||||
|
||||
if lang eq ru_RU
|
||||
sz_tab_autorun db "Автозагрузка", 0
|
||||
sz_col_program db "Программа", 0
|
||||
sz_col_params db "Параметры", 0
|
||||
sz_col_delay db "Задержка", 0
|
||||
sz_ar_toggle db "Включить/выключить", 0
|
||||
else if lang eq es_ES
|
||||
sz_tab_autorun db "Inicio", 0
|
||||
sz_col_program db "Programa", 0
|
||||
sz_col_params db "Parámetros", 0
|
||||
sz_col_delay db "Retardo", 0
|
||||
sz_ar_toggle db "Activar/desactivar", 0
|
||||
else
|
||||
sz_tab_autorun db "Autorun", 0
|
||||
sz_col_program db "Program", 0
|
||||
sz_col_params db "Parameters", 0
|
||||
sz_col_delay db "Delay", 0
|
||||
sz_ar_toggle db "Turn on/off", 0
|
||||
end if
|
||||
|
||||
autorun_info FileInfoBlock SSF_GET_INFO, 0, 0, 0, autorun_bdfe, 0, sz_autorun
|
||||
autorun_file FileInfoBlock SSF_READ_FILE, 0, 0, 0, 0, 0, sz_autorun ; the buffer on
|
||||
autorun_save FileInfoBlock SSF_CREATE_FILE, 0, 0, 0, 0, 0, sz_autorun ; the heap
|
||||
sz_autorun db "/sys/settings/autorun.dat", 0
|
||||
|
||||
virtual at tab_data ; only the open tab uses it
|
||||
autorun_bdfe FileInfoA
|
||||
AUTORUN_DATA = $ - tab_data
|
||||
end virtual
|
||||
@@ -0,0 +1,343 @@
|
||||
; Disks tab: the partitions in a sortable list, the used space as a bar
|
||||
; across what the other columns leave. The kernel does not report free
|
||||
; space, so for memory disks (/rd, /tmp*) the space taken by files is summed
|
||||
; up. The disks are found in a thread, the tab is drawn at once.
|
||||
|
||||
struct DISK
|
||||
num dd ? ; in the order found, the key of the row
|
||||
icon dd ? ; in ICONS18, by the kind of the disk
|
||||
fill dd ? ; used, 1/1024 of the size, -1: unknown
|
||||
used dd ? ; KB, -1: unknown
|
||||
total dd ? ; KB
|
||||
name rb 16 ; the path
|
||||
label rb 28
|
||||
ends
|
||||
|
||||
MAX_DISKS = 16
|
||||
WALK_MAX = 1024 ; path length
|
||||
WALK_DEPTH = 16
|
||||
|
||||
; Start the thread that finds the disks.
|
||||
disks_scan:
|
||||
xor eax, eax
|
||||
mov [list.count], eax
|
||||
mov [list.first], eax
|
||||
mov [disk_n], eax
|
||||
mov [walk_stop], eax
|
||||
|
||||
inc [walking]
|
||||
mcall SF_THREAD_CONTROL, SSF_CREATE_THREAD, walker, walk_stack_top
|
||||
|
||||
inc eax ; -1: no thread, nothing to wait for
|
||||
jnz @f
|
||||
and [walking], 0
|
||||
@@:
|
||||
ret
|
||||
|
||||
; The walker found more: the view of the disks found so far, sorted.
|
||||
disks_update:
|
||||
xor eax, eax
|
||||
xchg eax, [walk_new]
|
||||
test eax, eax
|
||||
jz .done
|
||||
|
||||
mov esi, disks
|
||||
mov ebp, disks_view
|
||||
mov ecx, [disk_n]
|
||||
@@:
|
||||
mov [ebp], esi
|
||||
add ebp, 4
|
||||
add esi, sizeof.DISK
|
||||
loop @b
|
||||
|
||||
call list_done
|
||||
jmp list_rows
|
||||
|
||||
.done:
|
||||
ret
|
||||
|
||||
disks_open: ; the selected disk in Eolite
|
||||
cmp [list.count], 0
|
||||
je .done
|
||||
imul edx, [list.key], sizeof.DISK ; DISK.num
|
||||
add edx, disks + DISK.name
|
||||
mov esi, sz_eolite_path
|
||||
jmp run_app
|
||||
|
||||
.done:
|
||||
ret
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; The thread that finds the disks and sums up the files of memory disks.
|
||||
|
||||
disks_find:
|
||||
xor ebp, ebp ; device index in "/"
|
||||
|
||||
.device:
|
||||
mov word [walk_path], "/"
|
||||
call read_entry
|
||||
jnz .done
|
||||
|
||||
mov edi, walk_path + 1
|
||||
call fmt_str
|
||||
mov ecx, edi ; end of "/device"
|
||||
xor edx, edx ; partition index
|
||||
|
||||
.partition:
|
||||
mov byte [ecx], 0
|
||||
xchg ebp, edx
|
||||
call read_entry
|
||||
xchg ebp, edx
|
||||
jnz .device
|
||||
|
||||
cmp [disk_n], MAX_DISKS
|
||||
jae .done
|
||||
|
||||
mov edi, ecx
|
||||
mov byte [edi], "/"
|
||||
inc edi
|
||||
call fmt_str
|
||||
call disk_add
|
||||
jmp .partition
|
||||
|
||||
.done:
|
||||
ret
|
||||
|
||||
; Read entry ebp of the folder [walk_path], ebp to the next one; out:
|
||||
; ZF = 1 if read, esi -> its name
|
||||
read_entry:
|
||||
cmp [walk_stop], 0 ; asked to stop: the thread ends
|
||||
jne walker.stop
|
||||
mov [fs_read.Position], ebp
|
||||
inc ebp
|
||||
mcall SF_FILE, fs_read
|
||||
mov esi, fs_entry.FileName
|
||||
test eax, eax
|
||||
ret
|
||||
|
||||
; [walk_path] = root of the partition, edi -> its end
|
||||
disk_add:
|
||||
pusha
|
||||
mcall SF_FILE, fs_info
|
||||
test eax, eax
|
||||
jnz .done
|
||||
|
||||
mov eax, [disk_n]
|
||||
imul ebx, eax, sizeof.DISK
|
||||
add ebx, disks
|
||||
mov [ebx + DISK.num], eax
|
||||
|
||||
mov ax, word [walk_path + 1] ; the kind by the device
|
||||
mov esi, disk_icons - 3
|
||||
@@:
|
||||
add esi, 3
|
||||
cmp word [esi], 0
|
||||
je @f
|
||||
cmp [esi], ax
|
||||
jne @b
|
||||
|
||||
@@:
|
||||
movzx eax, byte [esi + 2]
|
||||
mov [ebx + DISK.icon], eax
|
||||
|
||||
mov esi, walk_path
|
||||
lea edi, [ebx + DISK.name]
|
||||
mov ecx, DISK.label - DISK.name
|
||||
call copy_cut
|
||||
mov esi, fs_buf + FileInfoA.FileName ; of the partition
|
||||
lea edi, [ebx + DISK.label]
|
||||
mov ecx, sizeof.DISK - DISK.label
|
||||
call copy_cut
|
||||
|
||||
mov eax, [fs_buf + FileInfoA.FileSizeLow]
|
||||
mov edx, [fs_buf + FileInfoA.FileSizeHigh]
|
||||
shrd eax, edx, 10
|
||||
shr edx, 10 ; 4 TB and more: unknown
|
||||
jz @f
|
||||
or eax, -1
|
||||
@@:
|
||||
mov [ebx + DISK.total], eax
|
||||
or dword [ebx + DISK.used], -1
|
||||
or dword [ebx + DISK.fill], -1
|
||||
|
||||
inc [disk_n] ; listed when it is all there
|
||||
mov [walk_new], ebx
|
||||
test eax, eax
|
||||
jz .done
|
||||
|
||||
mov eax, dword [walk_path + 1]
|
||||
cmp ax, "rd"
|
||||
je @f
|
||||
and eax, 0xFFFFFF
|
||||
cmp eax, "tmp"
|
||||
jne .done
|
||||
|
||||
@@:
|
||||
xor ecx, ecx
|
||||
xor edx, edx
|
||||
mov edi, [esp + PUSHA_EDI] ; the end of the path
|
||||
call disk_walk
|
||||
|
||||
cmp ecx, [ebx + DISK.total] ; not more used than there is
|
||||
jbe @f
|
||||
mov ecx, [ebx + DISK.total]
|
||||
|
||||
@@:
|
||||
mov [ebx + DISK.used], ecx
|
||||
xchg eax, ecx
|
||||
mov edx, 1024
|
||||
mul edx
|
||||
div dword [ebx + DISK.total]
|
||||
mov [ebx + DISK.fill], eax
|
||||
mov [walk_new], ebx
|
||||
|
||||
.done:
|
||||
popa
|
||||
ret
|
||||
|
||||
; esi -> text, edi -> a field of ecx bytes: the text, cut to fit it, not in
|
||||
; the middle of a character
|
||||
copy_cut:
|
||||
rep movsb
|
||||
|
||||
@@:
|
||||
dec edi
|
||||
mov al, [edi]
|
||||
and al, 0xC0
|
||||
cmp al, 0x80
|
||||
je @b
|
||||
mov [edi], cl
|
||||
ret
|
||||
|
||||
; The thread.
|
||||
walker:
|
||||
call disks_find
|
||||
|
||||
.stop:
|
||||
and [walking], 0
|
||||
mcall SF_TERMINATE_PROCESS
|
||||
|
||||
; Ask the walker to stop and wait till it is gone.
|
||||
stop_walker:
|
||||
mov [walk_stop], 1
|
||||
|
||||
@@:
|
||||
and [walk_new], 0
|
||||
cmp [walking], 0
|
||||
je @f
|
||||
mcall SF_SLEEP, 1
|
||||
jmp @b
|
||||
|
||||
@@:
|
||||
ret
|
||||
|
||||
; Add the size of files under [walk_path] to ecx, KB; edi -> end of the path,
|
||||
; edx = depth
|
||||
disk_walk:
|
||||
pusha
|
||||
xor ebp, ebp ; index in the folder
|
||||
inc edx
|
||||
|
||||
.next:
|
||||
call read_entry
|
||||
jnz .done
|
||||
|
||||
test byte [fs_entry.Attributes], FA_LABEL
|
||||
jnz .next
|
||||
test byte [fs_entry.Attributes], FA_FOLDER
|
||||
jnz .folder
|
||||
|
||||
mov eax, [fs_entry.FileSizeLow]
|
||||
add eax, 1023
|
||||
shr eax, 10
|
||||
add ecx, eax
|
||||
jmp .next
|
||||
|
||||
.folder:
|
||||
cmp byte [esi], "." ; skip "." and ".."
|
||||
jne @f
|
||||
cmp byte [esi + 1], 0
|
||||
je .next
|
||||
cmp word [esi + 1], "."
|
||||
je .next
|
||||
|
||||
@@:
|
||||
cmp edx, WALK_DEPTH
|
||||
jae .next
|
||||
|
||||
lea eax, [edi + 264]
|
||||
cmp eax, walk_path + WALK_MAX
|
||||
jae .next
|
||||
|
||||
push edi
|
||||
mov byte [edi], "/"
|
||||
inc edi
|
||||
call fmt_str
|
||||
call disk_walk
|
||||
pop edi
|
||||
mov byte [edi], 0
|
||||
jmp .next
|
||||
|
||||
.done:
|
||||
mov [esp + PUSHA_ECX], ecx
|
||||
popa
|
||||
ret
|
||||
|
||||
disks_bar:
|
||||
BAR BAR_BUTTON, sz_open, sc.work_button
|
||||
db BAR_END
|
||||
|
||||
disks_list LIST disks_cols, disks_cols_end, disks_cols + sizeof.COL, nothing, disks_open, disks_keys, 0, 0, 0, 0, 0, 0, tab_data
|
||||
disks_keys:
|
||||
HOTKEY KEY_ENTER, disks_open
|
||||
db 0
|
||||
disks_cols:
|
||||
COL sz_col_num, DISK.icon, KIND_ICON, ID_W
|
||||
COL sz_col_name, DISK.name, KIND_TEXT, COL_W
|
||||
COL sz_col_label, DISK.label, KIND_TEXT, COL_W
|
||||
COL sz_pct, DISK.fill, KIND_BAR, 0
|
||||
COL sz_used, DISK.used, KIND_SIZE, COL_W
|
||||
COL sz_col_size, DISK.total, KIND_SIZE, COL_W
|
||||
disks_cols_end:
|
||||
|
||||
if lang eq ru_RU
|
||||
sz_col_size db "Размер", 0
|
||||
sz_col_label db "Метка", 0
|
||||
sz_open db "Открыть", 0
|
||||
else if lang eq es_ES
|
||||
sz_col_size db "Tamaño", 0
|
||||
sz_col_label db "Etiqueta", 0
|
||||
sz_open db "Abrir", 0
|
||||
else
|
||||
sz_col_size db "Size", 0
|
||||
sz_col_label db "Label", 0
|
||||
sz_open db "Open", 0
|
||||
end if
|
||||
|
||||
sz_eolite_path db "/sys/File Managers/EOLITE", 0
|
||||
|
||||
; the first two letters of the device, the icon; the last one for the others
|
||||
disk_icons db "rd", 58, "tm", 51, "fd", 5, "cd", 19, "us", 57, 0, 0, 50
|
||||
|
||||
fs_read FileInfoBlock SSF_READ_FOLDER, 0, 1, 1, fs_buf, 0, walk_path ; cp866
|
||||
; names, one entry from Position on
|
||||
fs_info FileInfoBlock SSF_GET_INFO, 0, 3, 0, fs_buf, 0, walk_path ; UTF-8
|
||||
; volume label
|
||||
|
||||
uglobal
|
||||
disk_n dd ? ; the disks the walker found
|
||||
walking dd ?
|
||||
walk_stop dd ?
|
||||
walk_new dd ?
|
||||
rb 1024
|
||||
walk_stack_top:
|
||||
endg
|
||||
|
||||
virtual at tab_data ; only the open tab uses it
|
||||
disks_view rd MAX_DISKS
|
||||
disks rb MAX_DISKS * sizeof.DISK
|
||||
fs_buf FileInfoHeader ; then an entry of a folder; a
|
||||
fs_entry FileInfoA ; partition from fs_buf on
|
||||
walk_path rb WALK_MAX
|
||||
DISKS_DATA = $ - tab_data
|
||||
end virtual
|
||||
@@ -0,0 +1,92 @@
|
||||
; Drivers tab: the drivers loaded by the kernel (function 68.31).
|
||||
|
||||
struct DRV
|
||||
num dd ? ; in the list, the key of the row
|
||||
name rb 16 ; from here on the item of the kernel
|
||||
next dd ?
|
||||
handle dd ? ; the kernel keeps the previous item here
|
||||
base dd ?
|
||||
start dd ? ; the entry of the driver
|
||||
service dd ?
|
||||
ends
|
||||
|
||||
MAX_DRIVERS = 64
|
||||
|
||||
; The drivers the kernel has now.
|
||||
drivers_scan:
|
||||
mcall SF_SYS_MISC, SSF_GET_DRIVER_DATA, 1
|
||||
mov esi, ecx ; the last driver
|
||||
mov edx, ebx ; the first one
|
||||
|
||||
mov ebp, drivers_view
|
||||
mov edi, drivers + DRV.name
|
||||
|
||||
.next:
|
||||
cmp ebp, drivers_view + MAX_DRIVERS*4
|
||||
jae list_done
|
||||
|
||||
mcall SF_SYS_MISC, SSF_GET_DRIVER_DATA, 2
|
||||
test eax, eax
|
||||
jnz list_done
|
||||
|
||||
lea eax, [edi - DRV.name]
|
||||
mov [ebp], eax
|
||||
add ebp, 4
|
||||
|
||||
lea eax, [ebp - drivers_view]
|
||||
shr eax, 2
|
||||
mov dword [edi + DRV.num - DRV.name], eax
|
||||
|
||||
mov eax, dword [edi + DRV.next - DRV.name]
|
||||
mov dword [edi + DRV.handle - DRV.name], edx
|
||||
|
||||
add edi, sizeof.DRV
|
||||
cmp edx, esi
|
||||
mov edx, eax
|
||||
jne .next
|
||||
jmp list_done
|
||||
|
||||
drivers_load: ; RUN with the name of the driver to type
|
||||
mov esi, sz_run_path
|
||||
mov edx, sz_loaddrv
|
||||
jmp run_app
|
||||
|
||||
drivers_bar:
|
||||
BAR BAR_BUTTON, sz_load, sc.work_button
|
||||
db BAR_END
|
||||
|
||||
drivers_list LIST drivers_cols, drivers_cols_end, drivers_cols, nothing, nothing, no_keys, 0, 0, 0, 0, 0, 0, tab_data
|
||||
drivers_cols:
|
||||
COL sz_col_num, DRV.num, KIND_NUM, ID_W
|
||||
COL sz_col_name, DRV.name, KIND_TEXT, 0
|
||||
COL sz_col_handle, DRV.handle, KIND_HEX, COL_W
|
||||
COL sz_col_base, DRV.base, KIND_HEX, COL_W
|
||||
COL sz_col_service, DRV.service, KIND_HEX, COL_W
|
||||
drivers_cols_end:
|
||||
|
||||
if lang eq ru_RU
|
||||
sz_tab_drivers db "Драйверы", 0
|
||||
sz_col_handle db "Дескриптор", 0
|
||||
sz_col_base db "База", 0
|
||||
sz_col_service db "Сервис", 0
|
||||
sz_load db "Загрузить...", 0
|
||||
else if lang eq es_ES
|
||||
sz_tab_drivers db "Controladores", 0
|
||||
sz_col_handle db "Manejador", 0
|
||||
sz_col_base db "Base", 0
|
||||
sz_col_service db "Servicio", 0
|
||||
sz_load db "Cargar...", 0
|
||||
else
|
||||
sz_tab_drivers db "Drivers", 0
|
||||
sz_col_handle db "Handle", 0
|
||||
sz_col_base db "Base", 0
|
||||
sz_col_service db "Service", 0
|
||||
sz_load db "Load...", 0
|
||||
end if
|
||||
sz_loaddrv db "/sys/LOADDRV ", 0
|
||||
|
||||
virtual at tab_data ; only the open tab uses it
|
||||
drivers_view rd MAX_DRIVERS
|
||||
drivers rb MAX_DRIVERS * sizeof.DRV
|
||||
DRIVERS_DATA = $ - tab_data
|
||||
end virtual
|
||||
@@ -0,0 +1,532 @@
|
||||
; Performance tab: CPU, temperature when there is a sensor, memory and
|
||||
; network history in rows, lines between them. A row: the icon, the title
|
||||
; and the items on the left, the graph on the right.
|
||||
|
||||
GRAPH_STEP = 4 ; pixels per sample
|
||||
INFO_W = 256 + 2*PAD + ICON ; the icon, the title, the items, PAD
|
||||
NET_DEVICES = 16 ; of the kernel
|
||||
|
||||
struct G ; a graph
|
||||
title dd ?
|
||||
hist dd ? ; dwords up to the top
|
||||
hist2 dd ? ; 0, the network: received, sent
|
||||
info dd ? ; items left of the graph
|
||||
unit dd ? ; of the value in the title
|
||||
top dd ? ; -> the top of the scale
|
||||
on dd ? ; -> not 0 if shown
|
||||
icon dd ? ; before the title
|
||||
ends
|
||||
|
||||
struct ITEM ; a line left of a graph
|
||||
text dd ?
|
||||
get dd ? ; edi -> the text; out: edi after it
|
||||
ends
|
||||
|
||||
struct NET_BYTES ; of all the devices
|
||||
rx dq ?
|
||||
tx dq ?
|
||||
ends
|
||||
|
||||
perf_draw: ; eax = TAB.draw: with the frames,
|
||||
lea esi, [eax - TAB.update] ; TAB.update: esi = 0, without
|
||||
mov edi, shown ; the graphs there is data for
|
||||
mov eax, graphs
|
||||
|
||||
.shown:
|
||||
mov edx, [eax + G.on]
|
||||
cmp dword [edx], 0
|
||||
je @f
|
||||
stosd
|
||||
@@:
|
||||
add eax, sizeof.G
|
||||
cmp eax, graphs_end
|
||||
jb .shown
|
||||
|
||||
sub edi, shown
|
||||
shr edi, 2
|
||||
xchg edi, [shown_n]
|
||||
cmp edi, [shown_n] ; one came or went: all again
|
||||
je .draw
|
||||
test esi, esi
|
||||
jz draw_window
|
||||
|
||||
.draw:
|
||||
xor ebp, ebp
|
||||
.graph:
|
||||
call graph_frame
|
||||
call perf_graph
|
||||
inc ebp
|
||||
cmp ebp, [shown_n]
|
||||
jb .graph
|
||||
ret
|
||||
|
||||
; The button of the bar.
|
||||
perf_cpuid:
|
||||
mov esi, sz_cpuid_path
|
||||
jmp run_plain
|
||||
|
||||
; ebp = graph; out: ebx = x shl 16 + w, ecx = y shl 16 + h of its frame.
|
||||
; Between the rows a line, PAD from both.
|
||||
graph_frame:
|
||||
mov eax, [area_h]
|
||||
dec eax
|
||||
xor edx, edx
|
||||
div [shown_n] ; from a row to the next one
|
||||
|
||||
mov ecx, ebp
|
||||
imul ecx, eax
|
||||
add ecx, AREA_Y + 1 + PAD
|
||||
shl ecx, 16
|
||||
|
||||
sub eax, 2*PAD + 1
|
||||
mov cx, ax
|
||||
|
||||
mov ebx, (3*PAD + 1 + INFO_W) shl 16
|
||||
mov bx, word [area_w]
|
||||
sub bx, 2 + 3*PAD + INFO_W
|
||||
ret
|
||||
|
||||
; ecx = y shl 16 of a frame: the line between its row and the one above
|
||||
row_line:
|
||||
pusha
|
||||
shr ecx, 16
|
||||
sub ecx, PAD + 1 ; the middle of the gap above
|
||||
shl ecx, 16
|
||||
inc ecx
|
||||
|
||||
mov ebx, (PAD + 1) shl 16
|
||||
mov bx, word [area_w]
|
||||
sub bx, 2
|
||||
mcall SF_DRAW_RECT, , , [sc.work_graph]
|
||||
popa
|
||||
ret
|
||||
|
||||
; ebp = graph, ebx and ecx = its frame, esi = 0: no frame
|
||||
perf_graph:
|
||||
pusha
|
||||
test esi, esi
|
||||
jz .title
|
||||
mov edx, [sc.work_light]
|
||||
call frame_rect
|
||||
call row_line ; the first one on the panel border
|
||||
|
||||
.title:
|
||||
mov ebp, [shown + ebp*4]
|
||||
mov esi, [ebp + G.hist]
|
||||
mov edx, [ebp + G.hist2]
|
||||
|
||||
mov edi, [hist_pos] ; the last value
|
||||
mov eax, [esi + edi*4]
|
||||
test edx, edx
|
||||
jz @f
|
||||
add eax, [edx + edi*4] ; the network: both ways
|
||||
mov edi, text_buf
|
||||
call fmt_rate
|
||||
jmp .titled
|
||||
|
||||
@@:
|
||||
mov edi, text_buf
|
||||
call fmt_uint
|
||||
mov eax, [ebp + G.unit]
|
||||
call fmt_unit
|
||||
|
||||
.titled:
|
||||
call info_lines ; the lines left of it
|
||||
|
||||
mov eax, [ebp + G.top] ; the top: 100 %, TjMax, the network:
|
||||
mov eax, [eax] ; the largest rate of the columns
|
||||
|
||||
add ebx, 1 shl 16 - 2 ; bars inside the frame, newest on the right
|
||||
add ecx, 1 shl 16 - 2
|
||||
movzx edi, bx
|
||||
|
||||
test edx, edx
|
||||
jz .scaled
|
||||
call net_scale
|
||||
|
||||
.scaled:
|
||||
mov [scale], eax
|
||||
|
||||
mov ebp, [hist_pos]
|
||||
|
||||
.bar: ; the network: received on the left,
|
||||
mov eax, GRAPH_STEP ; sent on the right, lighter
|
||||
cmp edi, eax
|
||||
jae @f
|
||||
mov eax, edi
|
||||
|
||||
@@:
|
||||
mov bx, ax
|
||||
sub edi, eax
|
||||
pusha
|
||||
shl edi, 16
|
||||
add ebx, edi
|
||||
|
||||
mov edi, [sc.work_button]
|
||||
test edx, edx
|
||||
jz .last
|
||||
|
||||
mov eax, ebx
|
||||
shr ax, 1
|
||||
sub bx, ax
|
||||
call .value
|
||||
shl ebx, 16
|
||||
add eax, ebx
|
||||
xchg eax, ebx
|
||||
|
||||
mov esi, edx
|
||||
mov eax, [sc.work_light] ; sent: half way to the background
|
||||
mov edx, edi
|
||||
call mix
|
||||
xchg eax, edi
|
||||
|
||||
.last:
|
||||
call .value
|
||||
popa
|
||||
|
||||
dec ebp
|
||||
and ebp, HIST_LEN - 1
|
||||
test edi, edi
|
||||
jnz .bar
|
||||
|
||||
test edx, edx ; the network: its top at the top right
|
||||
jz .critical
|
||||
mov edi, text_buf
|
||||
mov eax, [scale]
|
||||
call fmt_rate
|
||||
mov ebx, [area_w]
|
||||
shl ebx, 16
|
||||
mov bx, [esp + PUSHA_ECX + 2] ; y of the frame
|
||||
add ebx, ((-6 - INFO_W + ICON + PAD) shl 16) + 4
|
||||
call info_value
|
||||
|
||||
@@:
|
||||
popa
|
||||
ret
|
||||
|
||||
.critical: ; the temperature: a line 10 below
|
||||
cmp esi, hist_temp ; the top
|
||||
jne @b
|
||||
|
||||
movzx eax, cx
|
||||
imul eax, 10
|
||||
div [scale] ; edx = G.hist2 = 0 here
|
||||
shl eax, 16
|
||||
add ecx, eax
|
||||
mov cx, 1
|
||||
|
||||
mov ebx, [esp + PUSHA_EBX] ; the frame
|
||||
add ebx, 1 shl 16 - 2
|
||||
mcall SF_DRAW_RECT, , , [red]
|
||||
jmp @b
|
||||
|
||||
; esi + ebp*4 -> value, edi = color: its bar at the bottom, the background
|
||||
; above it, not one over the other, so it does not flicker
|
||||
.value:
|
||||
pusha
|
||||
mov eax, [esi + ebp*4]
|
||||
cmp eax, [scale] ; not over the top
|
||||
jb @f
|
||||
mov eax, [scale]
|
||||
|
||||
@@:
|
||||
movzx esi, cx
|
||||
mul esi
|
||||
div [scale]
|
||||
xchg ebp, eax
|
||||
sub cx, bp
|
||||
mcall SF_DRAW_RECT, , , [sc.work_light]
|
||||
|
||||
movzx edx, cx
|
||||
shl edx, 16
|
||||
add ecx, edx
|
||||
mov cx, bp
|
||||
mcall SF_DRAW_RECT, , , edi
|
||||
popa
|
||||
ret
|
||||
|
||||
; esi, edx -> the history received and sent, edi = the width of the graph;
|
||||
; out: eax = its top, the largest rate shown up to 1, 2, 5, 10, 20, 50...
|
||||
; bit/s while it fits
|
||||
net_scale:
|
||||
push edi
|
||||
mov ebp, [hist_pos]
|
||||
xor eax, eax
|
||||
|
||||
.max:
|
||||
cmp eax, [esi + ebp*4]
|
||||
jae @f
|
||||
mov eax, [esi + ebp*4]
|
||||
@@:
|
||||
cmp eax, [edx + ebp*4]
|
||||
jae @f
|
||||
mov eax, [edx + ebp*4]
|
||||
|
||||
@@:
|
||||
dec ebp
|
||||
and ebp, HIST_LEN - 1
|
||||
sub edi, GRAPH_STEP
|
||||
jg .max
|
||||
pop edi
|
||||
|
||||
cmp eax, 2000000000
|
||||
ja .done
|
||||
|
||||
xor ebp, ebp
|
||||
inc ebp
|
||||
@@:
|
||||
cmp ebp, eax
|
||||
jae @f
|
||||
add ebp, ebp
|
||||
cmp ebp, eax
|
||||
jae @f
|
||||
lea ebp, [ebp*4 + ebp]
|
||||
shr ebp, 1
|
||||
cmp ebp, eax
|
||||
jae @f
|
||||
add ebp, ebp
|
||||
jmp @b
|
||||
|
||||
@@:
|
||||
xchg eax, ebp
|
||||
|
||||
.done:
|
||||
ret
|
||||
|
||||
; text_buf on the right of an item line at ebx = x shl 16 + y
|
||||
info_value:
|
||||
pusha
|
||||
mov ecx, [sc.work_text]
|
||||
mov edx, text_buf
|
||||
mov eax, edx
|
||||
call text_width
|
||||
|
||||
neg eax
|
||||
add eax, INFO_W - ICON - PAD
|
||||
shl eax, 16
|
||||
add ebx, eax
|
||||
|
||||
call draw_text
|
||||
popa
|
||||
ret
|
||||
|
||||
; ebp -> graph, ecx = y shl 16 + h of its frame, text_buf = its value:
|
||||
; the title and the items a line each as fit, the label on the left, the
|
||||
; value on the right. The ITEMs end with 0.
|
||||
info_lines:
|
||||
pusha
|
||||
movzx esi, cx ; the height left
|
||||
mov ebx, ((2*PAD + 1) shl 16) + INFO_W
|
||||
mcall SF_DRAW_RECT, , , [sc.work_light]
|
||||
|
||||
mov ebx, ecx ; the icon, the lines after it
|
||||
shr ebx, 16
|
||||
add ebx, (2*PAD + 1) shl 16 - 1
|
||||
mov eax, [ebp + G.icon]
|
||||
mov edx, [sc.work_light]
|
||||
call draw_icon
|
||||
add ebx, ((ICON + PAD) shl 16) + 1
|
||||
|
||||
mov edx, [ebp + G.title]
|
||||
mov ebp, [ebp + G.info]
|
||||
mov ecx, [sc.work_text]
|
||||
jmp .line
|
||||
|
||||
.item:
|
||||
mov edx, [ebp + ITEM.text]
|
||||
test edx, edx
|
||||
jz .done
|
||||
|
||||
mov edi, text_buf
|
||||
pusha
|
||||
call [ebp + ITEM.get]
|
||||
popa
|
||||
add ebp, sizeof.ITEM
|
||||
|
||||
.line:
|
||||
sub esi, 16
|
||||
jb .done
|
||||
call draw_text
|
||||
|
||||
mov eax, edx ; the value in the rest of the line
|
||||
call text_width
|
||||
|
||||
pusha
|
||||
mov ebx, INFO_W - 8 - ICON - PAD
|
||||
mov edx, text_buf
|
||||
mov edi, edx
|
||||
call fmt_clip
|
||||
popa
|
||||
|
||||
call info_value
|
||||
add ebx, 16
|
||||
jmp .item
|
||||
|
||||
.done:
|
||||
popa
|
||||
ret
|
||||
|
||||
; Once a second: the bytes of the network devices, but the loopback.
|
||||
net_sample:
|
||||
pusha
|
||||
mov edi, net_sum
|
||||
xor eax, eax
|
||||
mov ecx, (net_last - net_sum) / 4 ; and net_up
|
||||
rep stosd
|
||||
|
||||
mov ebx, (NET_DEVICES - 1) shl 8
|
||||
|
||||
.device:
|
||||
push ebx ; bl = SSF_DEVICE_TYPE
|
||||
mcall SF_NETWORK_GET
|
||||
test eax, eax ; -1: none, 0: the loopback
|
||||
jle .next
|
||||
|
||||
inc [net_up]
|
||||
mov bl, SSF_RX_BYTE_COUNT
|
||||
mcall SF_NETWORK_GET
|
||||
add dword [net_sum.rx], eax
|
||||
adc dword [net_sum.rx + 4], ebx
|
||||
|
||||
mov ebx, [esp]
|
||||
mov bl, SSF_TX_BYTE_COUNT
|
||||
mcall SF_NETWORK_GET
|
||||
add dword [net_sum.tx], eax
|
||||
adc dword [net_sum.tx + 4], ebx
|
||||
|
||||
.next:
|
||||
pop ebx
|
||||
dec bh
|
||||
jns .device
|
||||
|
||||
mov ecx, [hist_pos]
|
||||
mov esi, net_sum.rx
|
||||
mov ebx, hist_rx
|
||||
call .rate
|
||||
mov ebx, hist_tx
|
||||
call .rate
|
||||
|
||||
or [net_primed], -1
|
||||
popa
|
||||
ret
|
||||
|
||||
.rate: ; since the last second, 0 at first
|
||||
mov eax, [esi]
|
||||
mov edx, [esi + 4]
|
||||
sub eax, [edi]
|
||||
sbb edx, [edi + 4]
|
||||
movsd ; the sum is the last one now
|
||||
movsd
|
||||
jae @f
|
||||
xor eax, eax ; a device went away
|
||||
|
||||
@@:
|
||||
shl eax, 3 ; bits
|
||||
and eax, [net_primed]
|
||||
mov [ebx + ecx*4], eax
|
||||
ret
|
||||
|
||||
; The items of the lines left of the graphs: edi -> the text; out:
|
||||
; edi after it.
|
||||
get_freq:
|
||||
mcall SF_SYSTEM, SSF_GET_CPU_FREQUENCY
|
||||
mov ecx, 1000000
|
||||
call fmt_quot
|
||||
mov eax, sz_mhz
|
||||
jmp fmt_unit
|
||||
|
||||
get_uptime:
|
||||
mcall SF_SYSTEM_GET, SSF_TIME_COUNT
|
||||
xor edx, edx
|
||||
mov ecx, 100
|
||||
div ecx
|
||||
jmp fmt_time
|
||||
|
||||
get_threads:
|
||||
mov eax, [procs_end]
|
||||
sub eax, procs
|
||||
mov ecx, sizeof.PROC ; then fmt_quot
|
||||
|
||||
; eax / ecx, edx = the remainder
|
||||
fmt_quot:
|
||||
xor edx, edx
|
||||
div ecx
|
||||
jmp fmt_uint
|
||||
|
||||
get_used:
|
||||
mov eax, [ram_info.total]
|
||||
sub eax, [ram_info.free]
|
||||
jmp @f
|
||||
|
||||
get_free:
|
||||
mov eax, [ram_info.free]
|
||||
jmp @f
|
||||
|
||||
get_total:
|
||||
mov eax, [ram_info.total]
|
||||
|
||||
@@:
|
||||
shl eax, 2 ; pages to KB
|
||||
jmp fmt_size
|
||||
|
||||
get_rx:
|
||||
mov esi, net_sum.rx
|
||||
mov ebx, hist_rx
|
||||
jmp @f
|
||||
|
||||
get_tx:
|
||||
mov esi, net_sum.tx
|
||||
mov ebx, hist_tx
|
||||
|
||||
@@: ; the rate, then the total
|
||||
mov eax, [hist_pos]
|
||||
mov eax, [ebx + eax*4]
|
||||
call fmt_rate
|
||||
mov word [edi], " ("
|
||||
scasw
|
||||
|
||||
mov eax, [esi]
|
||||
mov edx, [esi + 4]
|
||||
shrd eax, edx, 10
|
||||
call fmt_size
|
||||
mov word [edi], ")"
|
||||
inc edi
|
||||
ret
|
||||
|
||||
graphs:
|
||||
G sz_col_cpu, hist_cpu, 0, cpu_info, sz_pct, pct_top, pct_top, 48
|
||||
temp_graph G sz_temp, hist_temp, 0, temp_info, sz_deg, tjmax, temp_on, 68
|
||||
G sz_col_mem, hist_mem, 0, mem_info, sz_pct, pct_top, pct_top, 51
|
||||
G sz_net, hist_rx, hist_tx, net_info, 0, pct_top, net_up, 12
|
||||
graphs_end:
|
||||
pct_top dd 100
|
||||
perf_bar:
|
||||
BAR BAR_BUTTON, sz_cpuid_path + 5, sc.work_button ; "CPUID"
|
||||
db BAR_END
|
||||
sz_cpuid_path db "/sys/CPUID", 0
|
||||
cpu_info ITEM sz_freq, get_freq
|
||||
ITEM sz_uptime, get_uptime
|
||||
ITEM sz_threads, get_threads
|
||||
dd 0
|
||||
mem_info ITEM sz_used, get_used
|
||||
ITEM sz_col_free, get_free
|
||||
ITEM sz_total, get_total
|
||||
dd 0
|
||||
net_info ITEM sz_received, get_rx
|
||||
ITEM sz_sent, get_tx
|
||||
dd 0
|
||||
temp_info ITEM sz_crit, get_tjmax ; Intel
|
||||
no_info dd 0
|
||||
|
||||
uglobal
|
||||
align 4
|
||||
shown rd 4 ; -> graphs
|
||||
shown_n dd ?
|
||||
net_primed dd ?
|
||||
scale dd ? ; of the bars being drawn
|
||||
net_sum NET_BYTES
|
||||
net_up dd ? ; the devices, but the loopback
|
||||
net_last NET_BYTES
|
||||
hist_rx rd HIST_LEN ; bits a second
|
||||
hist_tx rd HIST_LEN
|
||||
endg
|
||||
@@ -0,0 +1,98 @@
|
||||
; Processes tab: the threads in a sortable list.
|
||||
|
||||
; The threads to show, then the whole list or the rows only.
|
||||
procs_draw:
|
||||
call procs_filter
|
||||
jmp list_draw
|
||||
|
||||
procs_update:
|
||||
call procs_filter
|
||||
jmp list_rows
|
||||
|
||||
; The threads to show, without the system ones unless asked.
|
||||
procs_filter:
|
||||
mov esi, procs
|
||||
mov ebp, procs_view
|
||||
|
||||
.next:
|
||||
cmp esi, [procs_end]
|
||||
jae list_done
|
||||
|
||||
cmp [show_system], 0
|
||||
jne .add
|
||||
|
||||
cmp esi, procs ; IDLE
|
||||
je .skip
|
||||
cmp byte [esi + PROC.name], "@"
|
||||
je .skip
|
||||
cmp dword [esi + PROC.name], "OS"
|
||||
je .skip
|
||||
|
||||
.add:
|
||||
mov [ebp], esi
|
||||
add ebp, 4
|
||||
|
||||
.skip:
|
||||
add esi, sizeof.PROC
|
||||
jmp .next
|
||||
|
||||
procs_button: ; edx = button id
|
||||
jmp [.btns + (edx - BTN_OWN)*4]
|
||||
.btns dd .system, procs_info, procs_kill, procs_run ; as in procs_bar
|
||||
|
||||
.system:
|
||||
xor [show_system], 1
|
||||
jmp draw_window
|
||||
|
||||
; The buttons: Run..., End, Details.
|
||||
procs_run:
|
||||
mov esi, sz_run_path
|
||||
jmp run_plain
|
||||
|
||||
procs_kill: ; the key of a row is its PID
|
||||
mcall SF_SYSTEM, SSF_TERMINATE_THREAD_ID, [list.key]
|
||||
ret
|
||||
|
||||
procs_info:
|
||||
mcall SF_SYSTEM, SSF_GET_THREAD_SLOT, [list.key]
|
||||
test eax, eax
|
||||
jz .done
|
||||
|
||||
mov edi, text_buf
|
||||
call fmt_uint
|
||||
|
||||
mov esi, sz_tinfo_path
|
||||
mov edx, text_buf
|
||||
jmp run_app
|
||||
|
||||
.done:
|
||||
ret
|
||||
|
||||
procs_bar:
|
||||
BAR BAR_CHECK, sz_system, show_system
|
||||
BAR BAR_BUTTON, sz_info, sc.work_button
|
||||
BAR BAR_BUTTON, sz_kill, red
|
||||
BAR BAR_GAP, 0, 0 ; away from End
|
||||
BAR BAR_BUTTON, sz_run, green
|
||||
db BAR_END
|
||||
|
||||
procs_list LIST procs_cols, procs_cols_end, procs_cols, nothing, procs_info, procs_keys, 0, 0, 0, 0, 0, 0, tab_data
|
||||
procs_keys:
|
||||
HOTKEY KEY_ENTER, procs_info
|
||||
HOTKEY KEY_DEL, procs_kill
|
||||
db 0
|
||||
procs_cols:
|
||||
COL sz_col_id, PROC.pid, KIND_NUM, ID_W
|
||||
COL sz_col_name, PROC.name, KIND_TEXT, 0
|
||||
COL sz_col_cpu, PROC.cpu, KIND_PCT, COL_W
|
||||
COL sz_col_mem, PROC.mem, KIND_SIZE, COL_W
|
||||
procs_cols_end:
|
||||
|
||||
uglobal
|
||||
show_system db ?
|
||||
endg
|
||||
|
||||
virtual at tab_data ; only the open tab uses it
|
||||
procs_view rd MAX_PROCS
|
||||
PROCS_DATA = $ - tab_data
|
||||
end virtual
|
||||
@@ -0,0 +1,344 @@
|
||||
; SPDX-License-Identifier: GPL-2.0-only
|
||||
;
|
||||
; Task manager. A tab is a row of the `tabs` table: its caption, list
|
||||
; and handlers. To add a tab, add a row and an .inc file with the handlers.
|
||||
|
||||
include "../../KOSfuncs.inc"
|
||||
include "../../macros.inc"
|
||||
include "../../develop/libraries/box_lib/box_lib.mac"
|
||||
include "../../develop/libraries/libs-dev/libio/libio.inc"
|
||||
|
||||
format meos 01
|
||||
entry start
|
||||
|
||||
include "gui.inc"
|
||||
include "hwmon.inc"
|
||||
include "list.inc"
|
||||
include "locale.inc"
|
||||
include "sensors.inc"
|
||||
include "stats.inc"
|
||||
include "window.inc"
|
||||
|
||||
include "tabs/autorun.inc"
|
||||
include "tabs/disks.inc"
|
||||
include "tabs/drivers.inc"
|
||||
include "tabs/perf.inc"
|
||||
include "tabs/procs.inc"
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
start:
|
||||
mcall SF_SET_EVENTS_MASK, EVENTS
|
||||
|
||||
mcall SF_SYS_MISC, SSF_LOAD_DLL, box_lib_path
|
||||
test eax, eax
|
||||
jz exit
|
||||
xchg ecx, eax
|
||||
mov ebp, box_lib ; the names become the procs
|
||||
|
||||
.import:
|
||||
mov ebx, ecx
|
||||
.export:
|
||||
mov esi, [ebx]
|
||||
test esi, esi
|
||||
jz exit
|
||||
add ebx, 8
|
||||
mov edi, [ebp]
|
||||
@@:
|
||||
lodsb
|
||||
scasb
|
||||
jne .export
|
||||
test al, al
|
||||
jnz @b
|
||||
mov edx, [ebx - 4]
|
||||
mov [ebp], edx
|
||||
add ebp, 4
|
||||
cmp dword [ebp], 0
|
||||
jne .import
|
||||
|
||||
mcall SF_SYS_MISC, SSF_HEAP_INIT
|
||||
mcall SF_SYS_MISC, SSF_MEM_OPEN, icons_name, 0, 0 ; of @RESHARE
|
||||
mov [icons], eax
|
||||
|
||||
call sensors_init
|
||||
|
||||
reopen:
|
||||
call open_tab
|
||||
redraw:
|
||||
call draw_window
|
||||
|
||||
still:
|
||||
mcall SF_SYSTEM_GET, SSF_TIME_COUNT
|
||||
mov ebx, [next_tick]
|
||||
sub ebx, eax
|
||||
jg .wait
|
||||
|
||||
add eax, TICK
|
||||
mov [next_tick], eax
|
||||
call sample
|
||||
|
||||
mcall SF_THREAD_INFO, pinfo, -1
|
||||
test [pinfo.wnd_state], WND_MINIMIZED + WND_ROLLED_UP
|
||||
jnz still
|
||||
mov eax, TAB.update
|
||||
call tab_call
|
||||
jmp still
|
||||
|
||||
.wait:
|
||||
cmp [repeat_at], 0 ; an arrow held: the mouse again soon
|
||||
je @f
|
||||
mov ebx, 4
|
||||
|
||||
@@:
|
||||
mcall SF_WAIT_EVENT_TIMEOUT
|
||||
dec eax ; EV_REDRAW
|
||||
jz redraw
|
||||
dec eax ; EV_KEY
|
||||
jz key
|
||||
dec eax ; EV_BUTTON
|
||||
jz button
|
||||
|
||||
cmp al, EV_MOUSE - EV_BUTTON ; the mouse, or the time with
|
||||
je .mouse ; it held
|
||||
cmp al, EV_IDLE - EV_BUTTON
|
||||
jne still
|
||||
|
||||
cmp [repeat_at], 0 ; a held arrow when it is time
|
||||
je still
|
||||
dec [repeat_at]
|
||||
jnz still
|
||||
|
||||
.mouse:
|
||||
mov eax, TAB.mouse
|
||||
call tab_call
|
||||
jmp still
|
||||
|
||||
key:
|
||||
mcall SF_GET_KEY
|
||||
shr eax, 8
|
||||
|
||||
cmp al, KEY_ESC
|
||||
je exit
|
||||
cmp al, KEY_TAB ; the next tab
|
||||
je next_tab
|
||||
|
||||
call tab_list ; other keys are for lists
|
||||
jz still
|
||||
call list_key
|
||||
jmp still
|
||||
|
||||
button:
|
||||
mcall SF_GET_BUTTON
|
||||
shr eax, 8
|
||||
|
||||
cmp eax, 1
|
||||
je exit
|
||||
|
||||
cmp eax, BTN_OWN
|
||||
jae .own
|
||||
|
||||
sub eax, BTN_TAB
|
||||
cmp eax, BTN_SHUTDOWN - BTN_TAB
|
||||
jb switch_tab
|
||||
|
||||
mov esi, sz_end_path
|
||||
call run_plain
|
||||
jmp still
|
||||
|
||||
.own:
|
||||
xchg eax, edx
|
||||
mov eax, TAB.button
|
||||
call tab_call
|
||||
jmp still
|
||||
|
||||
next_tab:
|
||||
mov eax, [cur_tab]
|
||||
inc eax
|
||||
cmp eax, NTABS
|
||||
jb switch_tab
|
||||
xor eax, eax ; then switch_tab
|
||||
|
||||
switch_tab: ; eax = tab
|
||||
cmp eax, [cur_tab] ; the open one: nothing to do
|
||||
je still
|
||||
push eax
|
||||
call tab_list ; the old tab keeps its list
|
||||
mov esi, list
|
||||
call copy_list
|
||||
pop [cur_tab]
|
||||
jmp reopen
|
||||
|
||||
exit:
|
||||
call stop_walker
|
||||
mcall SF_TERMINATE_PROCESS
|
||||
|
||||
; Open the current tab: its list, then its activate handler.
|
||||
open_tab:
|
||||
and [repeat_at], 0
|
||||
call stop_walker
|
||||
|
||||
call tab_list
|
||||
mov esi, edi
|
||||
mov edi, list
|
||||
call copy_list
|
||||
|
||||
mov eax, TAB.activate
|
||||
tab_call: ; eax = handler in TAB
|
||||
imul ecx, [cur_tab], sizeof.TAB
|
||||
movzx ecx, word [tabs + ecx + eax]
|
||||
jmp ecx
|
||||
|
||||
nothing:
|
||||
ret
|
||||
|
||||
; out: edi -> list of the current tab or 0, ZF = 1 if 0
|
||||
tab_list:
|
||||
imul edi, [cur_tab], sizeof.TAB
|
||||
movzx edi, word [tabs + edi + TAB.list]
|
||||
test edi, edi
|
||||
ret
|
||||
|
||||
; Copy the list at esi to edi unless ZF = 1: the tab has none.
|
||||
copy_list:
|
||||
jz @f
|
||||
mov ecx, sizeof.LIST / 4
|
||||
rep movsd
|
||||
@@:
|
||||
ret
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; Settings
|
||||
MIN_W = 640 ; fits the longest bottom bar (ru_RU)
|
||||
MIN_H = 400 ; four graphs are still readable
|
||||
TICK = 100 ; statistics period, 1/100 s
|
||||
HIST_LEN = 1024 ; power of 2, the bars of a 4K wide window
|
||||
MAX_PROCS = 256
|
||||
|
||||
; Layout
|
||||
PAD = 8 ; margins and gaps
|
||||
TOP = 12 ; above the tabs
|
||||
TAB_H = 24
|
||||
AREA_Y = TOP + TAB_H - 1 ; top of the panel, the bottom of the tabs
|
||||
BTN_H = 24
|
||||
BTN_PAD = 12 ; text to the sides of a button
|
||||
CHECK = 14 ; checkbox
|
||||
ICON = 18 ; icons of @RESHARE
|
||||
TEXT_CHARS = 63 ; the longest text drawn
|
||||
TEXT_H = 14 ; 8x16 glyphs look centered as 14 lines
|
||||
|
||||
; The window and the text
|
||||
EVENTS = EVM_REDRAW + EVM_KEY + EVM_BUTTON + EVM_MOUSE + EVM_MOUSE_FILTER
|
||||
WIN_STYLE = 0x73000000 ; skinned, a caption, coordinates in
|
||||
; the client area, not filled: drawn
|
||||
TEXT_UTF8 = 0xB0000000 ; asciiz, UTF-8, 8x16
|
||||
WND_MAXIMIZED = 1 ; process_information.wnd_state
|
||||
WND_MINIMIZED = 2
|
||||
WND_ROLLED_UP = 4
|
||||
|
||||
; Lists
|
||||
COL_W = 112
|
||||
ID_W = 3*8 + 2*CELL_PAD ; a number: ID, Nº or #, the arrow
|
||||
|
||||
KIND_TEXT = 0 ; zero ended text in the row, sorted ascending
|
||||
KIND_STR = 1 ; pointer to text
|
||||
KIND_NUM = 2
|
||||
KIND_PCT = 3 ; from here on sorted down at first
|
||||
KIND_SIZE = 4
|
||||
KIND_HEX = 5
|
||||
KIND_BAR = 6 ; 1/1024 of the cell filled
|
||||
KIND_ICON = 7 ; in ICONS18
|
||||
|
||||
HDR_H = 24 - 2 ; 24 with its lines, as an arrow
|
||||
ROW_H = 20
|
||||
SB_W = 24 ; scrollbar, as high as the list
|
||||
CELL_PAD = 8
|
||||
|
||||
; Keys and mouse buttons
|
||||
KEY_TAB = 9
|
||||
KEY_ENTER = 13
|
||||
KEY_SPACE = 32
|
||||
KEY_ESC = 27
|
||||
KEY_DOWN = 177 ; the moves in the lists up to
|
||||
KEY_DEL = 182
|
||||
KEY_PGUP = 184 ; here
|
||||
MB_LEFT = 1 ; held
|
||||
MB_LEFT_DOWN = 0x100 ; pressed, not held at the last event
|
||||
MB_RIGHT_DOWN = 0x200
|
||||
|
||||
; pusha: where it keeps the registers
|
||||
PUSHA_EDI = 0
|
||||
PUSHA_EBX = 16
|
||||
PUSHA_EDX = 20
|
||||
PUSHA_ECX = 24
|
||||
PUSHA_EAX = 28
|
||||
PUSHA_SIZE = 32
|
||||
|
||||
; Buttons
|
||||
BTN_TAB = 2
|
||||
BTN_SHUTDOWN = 8 ; ids with bit 3 go to the right
|
||||
BTN_OWN = 16 ; ids from here on belong to the tab
|
||||
|
||||
struct TAB ; a row of `tabs`
|
||||
caption dw ?
|
||||
list dw ? ; LIST or 0
|
||||
activate dw ? ; the tab is opened
|
||||
draw dw ? ; full redraw of the panel
|
||||
update dw ? ; new statistics
|
||||
button dw ? ; edx = button id
|
||||
mouse dw ?
|
||||
bar dw ? ; the items of its bottom bar
|
||||
ends
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
tabs:
|
||||
TAB sz_tab_procs, procs_list, nothing, procs_draw, procs_update, procs_button, list_mouse, procs_bar
|
||||
TAB sz_tab_perf, 0, nothing, perf_draw, perf_draw, perf_cpuid, get_mouse, perf_bar
|
||||
TAB sz_tab_disks, disks_list, disks_scan, list_draw, disks_update, disks_open, list_mouse, disks_bar
|
||||
TAB sz_tab_drivers, drivers_list, drivers_scan, list_draw, nothing, drivers_load, list_mouse, drivers_bar
|
||||
TAB sz_tab_autorun, autorun_list, autorun_load, list_draw, nothing, autorun_toggle, list_mouse, autorun_bar
|
||||
NTABS = ($ - tabs) / sizeof.TAB
|
||||
|
||||
app_info FileInfoBlock SSF_START_APP, 0, 0, 0, 0, 0, 0 ; the parameters, the path
|
||||
sz_run_path db "/sys/RUN", 0
|
||||
sz_end_path db "/sys/END", 0
|
||||
sz_tinfo_path db "/sys/TINFO", 0
|
||||
icons_name db "ICONS18", 0
|
||||
box_lib_path db "/sys/lib/box_lib.obj", 0
|
||||
align 4
|
||||
box_lib:
|
||||
import box_lib, \
|
||||
scrollbar_v_draw, "scrollbar_v_draw", \
|
||||
scrollbar_v_mouse, "scrollbar_v_mouse", \
|
||||
check_box_draw2, "check_box_draw2"
|
||||
sb scrollbar SB_W - 1, 0, 0, AREA_Y, SB_W - 1, 0, 0, 0, 0, 0, 0, 1 ; the sizes - 1:
|
||||
; box_lib draws a pixel more
|
||||
cb check_box2 0, 0, PAD, 0, 0, 0x80000000, cb.size_of_str, 0 ; no text: its length
|
||||
|
||||
IncludeUGlobals
|
||||
align 4
|
||||
sc system_colors ; the button color: the main one
|
||||
green dd ? ; of the button: run
|
||||
red dd ? ; and of high values, end
|
||||
mid dd ? ; the list header, the scrollbar
|
||||
pinfo process_information
|
||||
next_tick dd ?
|
||||
cur_tab dd ?
|
||||
buttons dd ? ; mouse buttons held at the last event
|
||||
area_w dd ? ; panel: x = PAD, y = AREA_Y
|
||||
area_h dd ?
|
||||
bar_y dd ? ; bottom bar
|
||||
bar_left dd ?
|
||||
bar_right dd ? ; left end of the right buttons
|
||||
icons dd ? ; ICONS18 or 0
|
||||
icon_buf rd ICON*ICON
|
||||
text_buf rb TEXT_CHARS * 4 + 1 ; UTF-8 takes up to 4 bytes
|
||||
|
||||
macro max_of name, [value] {
|
||||
common name = 0
|
||||
forward
|
||||
if value > name
|
||||
name = value
|
||||
end if
|
||||
}
|
||||
max_of TAB_DATA, PROCS_DATA, DISKS_DATA, DRIVERS_DATA, AUTORUN_DATA
|
||||
align 4
|
||||
tab_data rb TAB_DATA ; data of the open tab
|
||||
@@ -0,0 +1,240 @@
|
||||
; The window: its colors, size and place, the panel and the tabs, then the
|
||||
; panel of the open tab.
|
||||
|
||||
draw_window:
|
||||
mcall SF_REDRAW, SSF_BEGIN_DRAW
|
||||
mcall SF_STYLE_SETTINGS, SSF_GET_COLORS, sc, sizeof.system_colors
|
||||
|
||||
mov eax, [sc.work_button] ; its channels high to low: al, ah, dl
|
||||
mov edx, eax
|
||||
shr edx, 16
|
||||
cmp al, ah
|
||||
jae @f
|
||||
xchg al, ah
|
||||
@@:
|
||||
cmp al, dl
|
||||
jae @f
|
||||
xchg al, dl
|
||||
@@:
|
||||
cmp ah, dl
|
||||
jae @f
|
||||
xchg ah, dl
|
||||
|
||||
@@:
|
||||
movzx ecx, dl ; blue, green, red
|
||||
shl ecx, 16
|
||||
mov cx, ax
|
||||
mov [sc.work_button], ecx
|
||||
|
||||
mov dl, al ; the low ones half the high one
|
||||
shr dl, 1
|
||||
movzx ecx, dl ; all low, then green, red high
|
||||
imul ecx, 0x10101
|
||||
mov [green], ecx
|
||||
mov byte [green + 1], al
|
||||
mov [red], ecx
|
||||
mov byte [red + 2], al
|
||||
|
||||
mov eax, [sc.work] ; between the window and the panel
|
||||
mov edx, [sc.work_light]
|
||||
call mix
|
||||
mov [mid], eax
|
||||
|
||||
mcall SF_GET_SCREEN_SIZE ; half the screen, the kernel takes
|
||||
shr eax, 1 ; it the first time
|
||||
xchg esi, eax
|
||||
mcall SF_STYLE_SETTINGS, SSF_GET_SCREEN_AREA
|
||||
mov edx, esi
|
||||
shr edx, 16
|
||||
mov ebp, MIN_W - 1
|
||||
call .fit
|
||||
xchg eax, ebx
|
||||
movzx edx, si
|
||||
and dh, 0x7F
|
||||
mov ebp, MIN_H - 1
|
||||
call .fit
|
||||
xchg eax, ecx
|
||||
|
||||
mov edx, [sc.work]
|
||||
or edx, WIN_STYLE
|
||||
mcall SF_CREATE_WINDOW, , , , 0, sz_title
|
||||
|
||||
mcall SF_THREAD_INFO, pinfo, -1
|
||||
test [pinfo.wnd_state], WND_ROLLED_UP
|
||||
jnz .done
|
||||
test [pinfo.wnd_state], WND_MAXIMIZED ; the size it gets
|
||||
jnz .layout
|
||||
|
||||
mov edx, [pinfo.box.width] ; not smaller than the minimum
|
||||
mov esi, [pinfo.box.height]
|
||||
cmp edx, MIN_W - 1 ; the kernel keeps the size - 1
|
||||
jae @f
|
||||
mov edx, MIN_W - 1
|
||||
@@:
|
||||
cmp esi, MIN_H - 1
|
||||
jae @f
|
||||
mov esi, MIN_H - 1
|
||||
@@:
|
||||
cmp edx, [pinfo.box.width]
|
||||
jne @f
|
||||
cmp esi, [pinfo.box.height]
|
||||
je .layout
|
||||
|
||||
@@:
|
||||
mcall SF_CHANGE_WINDOW, -1, -1 ; it sends a new redraw
|
||||
jmp .done
|
||||
|
||||
.layout:
|
||||
mov eax, [pinfo.client_box.width]
|
||||
lea ecx, [eax - PAD*2]
|
||||
mov [area_w], ecx
|
||||
mov [bar_right], eax
|
||||
mov [bar_left], PAD
|
||||
|
||||
mov eax, [pinfo.client_box.height]
|
||||
sub eax, PAD + BTN_H
|
||||
mov [bar_y], eax
|
||||
sub eax, AREA_Y + PAD
|
||||
mov [area_h], eax
|
||||
|
||||
mov ebx, PAD shl 16
|
||||
mov bx, word [area_w]
|
||||
mov ecx, AREA_Y shl 16
|
||||
mov cx, ax
|
||||
mov edx, [sc.work_light]
|
||||
call frame_rect
|
||||
|
||||
mov edx, [sc.work] ; around the tabs and the panel: above,
|
||||
mov ebx, [area_w] ; below with the bar, left, right
|
||||
add ebx, 2*PAD + 1
|
||||
mcall SF_DRAW_RECT, , TOP
|
||||
|
||||
mov ecx, [bar_y]
|
||||
sub ecx, PAD
|
||||
shl ecx, 16
|
||||
mov cx, 2*PAD + BTN_H + 1
|
||||
mcall SF_DRAW_RECT
|
||||
|
||||
mov ecx, [area_h]
|
||||
add ecx, (TOP shl 16) + TAB_H - 1
|
||||
mov ebx, PAD
|
||||
mcall SF_DRAW_RECT
|
||||
|
||||
mov ebx, [area_w]
|
||||
add ebx, PAD
|
||||
shl ebx, 16
|
||||
mov bx, PAD + 1
|
||||
mcall SF_DRAW_RECT
|
||||
|
||||
mov esi, [area_w] ; the tabs as wide as the panel, the
|
||||
add esi, NTABS - 1 ; room left shared alike
|
||||
xor ebp, ebp
|
||||
@@:
|
||||
call .content
|
||||
sub esi, eax
|
||||
inc ebp
|
||||
cmp ebp, NTABS
|
||||
jb @b
|
||||
|
||||
xchg eax, esi
|
||||
xor edx, edx
|
||||
mov ecx, NTABS
|
||||
div ecx
|
||||
xchg eax, esi
|
||||
|
||||
mov ebx, PAD shl 16
|
||||
xor ebp, ebp
|
||||
|
||||
.tab:
|
||||
call .content
|
||||
add eax, esi
|
||||
cmp ebp, NTABS - 1 ; the last one to the end of the panel
|
||||
jne @f
|
||||
mov eax, [area_w]
|
||||
add eax, PAD
|
||||
mov edx, ebx
|
||||
shr edx, 16
|
||||
sub eax, edx
|
||||
|
||||
@@:
|
||||
mov bx, ax
|
||||
call .draw
|
||||
imul eax, ebx, 1 shl 16
|
||||
lea ebx, [ebx + eax - 1 shl 16] ; neighbours share the border
|
||||
inc ebp
|
||||
cmp ebp, NTABS
|
||||
jb .tab
|
||||
|
||||
mov eax, sz_shutdown ; at the right end
|
||||
mov edx, BTN_SHUTDOWN
|
||||
mov esi, [sc.work_graph]
|
||||
call bar_button
|
||||
|
||||
imul esi, [cur_tab], sizeof.TAB ; the bar of the tab, then its
|
||||
movzx esi, word [tabs + esi + TAB.bar] ; panel
|
||||
call bar_draw
|
||||
mov eax, TAB.draw
|
||||
call tab_call
|
||||
|
||||
.done:
|
||||
mcall SF_REDRAW, SSF_END_DRAW
|
||||
ret
|
||||
|
||||
; eax = start shl 16 + end of the work area, edx = the size - 1 wanted,
|
||||
; ebp = the least; out: eax = start shl 16 + size - 1 of the window in its
|
||||
; middle
|
||||
.fit:
|
||||
cmp edx, ebp
|
||||
jae @f
|
||||
mov edx, ebp
|
||||
|
||||
@@:
|
||||
movzx ecx, ax
|
||||
shr eax, 16
|
||||
sub ecx, eax
|
||||
cmp edx, ecx
|
||||
jb @f
|
||||
mov edx, ecx
|
||||
|
||||
@@:
|
||||
sub ecx, edx
|
||||
shr ecx, 1
|
||||
add eax, ecx
|
||||
shl eax, 16
|
||||
mov ax, dx
|
||||
ret
|
||||
|
||||
.draw: ; the caption in the middle
|
||||
pusha
|
||||
mov ecx, (TOP shl 16) + TAB_H
|
||||
mov esi, [sc.work_dark]
|
||||
cmp ebp, [cur_tab]
|
||||
jne @f
|
||||
mov esi, [sc.work_light]
|
||||
|
||||
@@:
|
||||
mov edx, esi
|
||||
call frame_rect
|
||||
|
||||
lea edx, [ebp + BTN_TAB + BT_HIDE + BT_NOFRAME]
|
||||
mcall SF_DEFINE_BUTTON
|
||||
|
||||
call .content
|
||||
movzx ecx, bx
|
||||
sub ecx, eax
|
||||
shr ecx, 1
|
||||
shl ecx, 16
|
||||
add ebx, ecx
|
||||
|
||||
mov ecx, TOP shl 16
|
||||
mov eax, [sc.work_text]
|
||||
jmp bar_text ; as high as the bar items
|
||||
|
||||
; ebp = tab; out: edi -> its caption, eax = its width
|
||||
.content:
|
||||
imul edi, ebp, sizeof.TAB
|
||||
movzx edi, word [tabs + edi + TAB.caption]
|
||||
mov eax, edi
|
||||
call text_width
|
||||
ret
|
||||
|
||||
Reference in new issue
Block a user