Compare commits
20
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e268b223df | ||
|
|
bd071d588b | ||
|
|
9ec66b0eba | ||
|
|
95bcf78537 | ||
|
|
6f3cae4e0c | ||
|
|
b59e371c0e | ||
|
|
939505198f | ||
|
|
75cb80fd33 | ||
|
|
6ba901606d | ||
|
|
b1d329da2a | ||
|
|
df9946fe80 | ||
|
|
e3d744f1b5 | ||
|
|
8ca3758efb | ||
|
|
02916ed0ee | ||
|
|
873d4de379 | ||
|
|
b2f9cc9809 | ||
|
|
298155191d | ||
|
|
49b8cdcd54 | ||
|
|
c121db7a88 | ||
|
|
9527a0f3d1 |
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
-18
@@ -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"},
|
||||
@@ -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"},
|
||||
@@ -529,6 +523,7 @@ tup.append_table(img_files, {
|
||||
{"LIB/RASTERWORKS.OBJ", VAR_PROGS .. "/develop/libraries/fontRasterWorks_unicode/RasterWorks.obj"},
|
||||
{"LIB/SORT.OBJ", VAR_PROGS .. "/develop/libraries/sorter/sort.obj"},
|
||||
{"LIB/TINYGL.OBJ", VAR_PROGS .. "/develop/libraries/TinyGL/asm_fork/tinygl.obj"},
|
||||
{"LIB/XML.OBJ", VAR_PROGS .. "/develop/libraries/asm-xml/xml.obj"},
|
||||
{"MEDIA/ANIMAGE", VAR_PROGS .. "/media/animage/animage"},
|
||||
{"MEDIA/FILLSCR", VAR_PROGS .. "/media/FillScr/fillscr"},
|
||||
{"MEDIA/KIV", VAR_PROGS .. "/media/kiv/kiv"},
|
||||
@@ -652,20 +647,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'
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 **** Звук и видео
|
||||
|
||||
+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
@@ -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
|
||||
|
||||
+342
-368
@@ -29,33 +29,6 @@ align 4
|
||||
overlapping_of_points_ptr dd overlapping_of_points
|
||||
endg
|
||||
|
||||
; the converter slots are laid out so that bytes_per_pixel indexes them
|
||||
struct putimage_format
|
||||
getter dd ?
|
||||
src_bpp dd ?
|
||||
conv_16 dd ?
|
||||
conv_24 dd ?
|
||||
conv_32 dd ?
|
||||
ends
|
||||
|
||||
iglobal
|
||||
align 4
|
||||
putimage_stores dd 0, 0, putimage_store_16, putimage_store_24, \
|
||||
putimage_store_32
|
||||
putimage_fallbacks dd 0, 0, putimage_conv_any_16, putimage_conv_any_24, \
|
||||
putimage_conv_any_32
|
||||
|
||||
; 1, 2 and 4bpp are absent: their runs cannot be skipped over
|
||||
putimage_formats:
|
||||
dd putimage_get8bpp, 1, 0, 0, putimage_conv_8_32
|
||||
dd putimage_get9bpp, 1, 0, 0, 0
|
||||
dd putimage_get15bpp, 2, 0, 0, 0
|
||||
dd putimage_get16bpp, 2, putimage_conv_16_16, 0, 0
|
||||
dd putimage_get24bpp, 3, 0, putimage_conv_24_24, putimage_conv_24_32
|
||||
dd putimage_get32bpp, 4, 0, 0, putimage_conv_32_32
|
||||
dd 0
|
||||
endg
|
||||
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
; eax = x
|
||||
@@ -176,14 +149,7 @@ virtual at esp
|
||||
.screen_newline dd ?
|
||||
.real_sx_and_abs_cx dd ?
|
||||
.real_sy_and_abs_cy dd ?
|
||||
.conv dd ?
|
||||
.skip dd ?
|
||||
.store dd ?
|
||||
.src_bpp dd ?
|
||||
.dst_bpp dd ?
|
||||
.mask dd ?
|
||||
.row dd ?
|
||||
.stack_data = 4*21
|
||||
.stack_data = 4*14
|
||||
.edi dd ?
|
||||
.esi dd ?
|
||||
.ebp dd ?
|
||||
@@ -299,67 +265,338 @@ end virtual
|
||||
; get process number
|
||||
mov ebx, [current_slot_idx]
|
||||
|
||||
movzx ecx, bl
|
||||
imul ecx, 0x01010101 ; the slot in all four lanes
|
||||
mov [putimg.mask], ecx
|
||||
cmp byte [_display.bits_per_pixel], 16
|
||||
je put_image_end_16
|
||||
cmp byte [_display.bits_per_pixel], 24
|
||||
je put_image_end_24
|
||||
cmp byte [_display.bits_per_pixel], 32
|
||||
je put_image_end_32
|
||||
|
||||
mov [putimg.row], putimage_row
|
||||
cmp [_display.select_cursor], select_cursor
|
||||
jne .row_done
|
||||
mov [putimg.row], putimage_row_cursor
|
||||
.row_done:
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
; _display.bytes_per_pixel is 2, 3 or 4, so it indexes the tables directly
|
||||
mov eax, [_display.bytes_per_pixel]
|
||||
mov [putimg.dst_bpp], eax
|
||||
mov ecx, [putimage_stores + eax*4]
|
||||
mov [putimg.store], ecx
|
||||
mov ecx, [putimage_fallbacks + eax*4]
|
||||
mov [putimg.conv], ecx
|
||||
put_image_end_16:
|
||||
|
||||
mov [putimg.skip], putimage_skip_bytes
|
||||
mov edi, putimage_formats
|
||||
.format:
|
||||
mov ecx, [edi]
|
||||
test ecx, ecx
|
||||
jz .format_stateful
|
||||
cmp ecx, [putimg.ebp]
|
||||
je .format_found
|
||||
add edi, sizeof.putimage_format
|
||||
jmp .format
|
||||
mov edi, [putimg.real_sy]
|
||||
|
||||
; past the table are the getters that carry a bit position between calls
|
||||
.format_stateful:
|
||||
mov [putimg.skip], putimage_skip_getter
|
||||
jmp .format_done
|
||||
; check for hardware cursor
|
||||
mov ecx, [_display.select_cursor]
|
||||
cmp ecx, select_cursor
|
||||
je put_image_end_16_new
|
||||
|
||||
.format_found:
|
||||
mov ecx, [edi + putimage_format.src_bpp]
|
||||
mov [putimg.src_bpp], ecx
|
||||
mov ecx, [edi + eax*4] ; the column for this screen
|
||||
test ecx, ecx
|
||||
jz .format_done
|
||||
mov [putimg.conv], ecx
|
||||
.format_done:
|
||||
.new_line:
|
||||
mov ecx, [putimg.real_sx]
|
||||
.new_x:
|
||||
push [putimg.edi]
|
||||
mov eax, [putimg.ebp + 4]
|
||||
call eax
|
||||
cmp [ebp], bl
|
||||
jne .skip
|
||||
; convert to 16 bpp and store to LFB
|
||||
and eax, 00000000111110001111110011111000b
|
||||
shr ah, 2
|
||||
shr ax, 3
|
||||
ror eax, 8
|
||||
add al, ah
|
||||
rol eax, 8
|
||||
mov [LFB_BASE + edx], ax
|
||||
.skip:
|
||||
add edx, 2
|
||||
inc ebp
|
||||
dec ecx
|
||||
jnz .new_x
|
||||
|
||||
add esi, [putimg.line_increment]
|
||||
add edx, [putimg.screen_newline]
|
||||
add ebp, [putimg.winmap_newline]
|
||||
|
||||
cmp [putimg.ebp], putimage_get1bpp
|
||||
jz .correct
|
||||
cmp [putimg.ebp], putimage_get2bpp
|
||||
jz .correct
|
||||
cmp [putimg.ebp], putimage_get4bpp
|
||||
jnz @f
|
||||
.correct:
|
||||
mov eax, [putimg.edi]
|
||||
mov byte [eax], 80h
|
||||
@@:
|
||||
dec edi
|
||||
jnz .new_line
|
||||
.finish:
|
||||
add esp, putimg.stack_data
|
||||
popad
|
||||
ret
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
align 4
|
||||
put_image_end:
|
||||
|
||||
mov edi, [putimg.real_sy]
|
||||
put_image_end_16_new:
|
||||
|
||||
.new_line:
|
||||
mov ecx, [putimg.real_sx]
|
||||
call [putimg.row]
|
||||
call putimage_next_row
|
||||
|
||||
.new_x:
|
||||
push [putimg.edi]
|
||||
mov eax, [putimg.ebp + 4]
|
||||
call eax
|
||||
|
||||
cmp [ebp], bl
|
||||
jne .skip
|
||||
|
||||
push ecx
|
||||
.sh:
|
||||
neg ecx
|
||||
add ecx, [putimg.real_sx_and_abs_cx + 4]
|
||||
|
||||
; check for X
|
||||
cmp cx, [X_UNDER_sub_CUR_hot_x_add_curh]
|
||||
jae .no_mouse_area
|
||||
|
||||
sub cx, [X_UNDER_subtraction_CUR_hot_x]
|
||||
jb .no_mouse_area
|
||||
|
||||
shl ecx, 16
|
||||
add ecx, [putimg.real_sy_and_abs_cy + 4]
|
||||
sub ecx, edi
|
||||
|
||||
; check for Y
|
||||
cmp cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
|
||||
jae .no_mouse_area
|
||||
|
||||
sub cx, [Y_UNDER_subtraction_CUR_hot_y]
|
||||
jb .no_mouse_area
|
||||
|
||||
; check mouse area for putpixel
|
||||
call check_mouse_area_for_putpixel_new.1
|
||||
cmp ecx, -1 ; MISTAKES HAPPEN?
|
||||
jne .no_mouse_area
|
||||
|
||||
mov ecx, [esp]
|
||||
jmp .sh
|
||||
|
||||
.no_mouse_area:
|
||||
pop ecx
|
||||
; convert to 16 bpp and store to LFB
|
||||
and eax, 00000000111110001111110011111000b
|
||||
shr ah, 2
|
||||
shr ax, 3
|
||||
ror eax, 8
|
||||
add al, ah
|
||||
rol eax, 8
|
||||
mov [LFB_BASE+edx], ax
|
||||
|
||||
.skip:
|
||||
add edx, 2
|
||||
inc ebp
|
||||
dec ecx
|
||||
jnz .new_x
|
||||
|
||||
add esi, [putimg.line_increment]
|
||||
add edx, [putimg.screen_newline]
|
||||
add ebp, [putimg.winmap_newline]
|
||||
|
||||
cmp [putimg.ebp], putimage_get1bpp
|
||||
jz .correct
|
||||
cmp [putimg.ebp], putimage_get2bpp
|
||||
jz .correct
|
||||
cmp [putimg.ebp], putimage_get4bpp
|
||||
jnz @f
|
||||
|
||||
.correct:
|
||||
mov eax, [putimg.edi]
|
||||
mov byte [eax], 80h
|
||||
|
||||
@@:
|
||||
dec edi
|
||||
jnz .new_line
|
||||
jmp put_image_end_16.finish
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
align 4
|
||||
put_image_end_24:
|
||||
|
||||
mov edi, [putimg.real_sy]
|
||||
|
||||
; check for hardware cursor
|
||||
mov ecx, [_display.select_cursor]
|
||||
cmp ecx, select_cursor
|
||||
je put_image_end_24_new
|
||||
|
||||
.new_line:
|
||||
mov ecx, [putimg.real_sx]
|
||||
.new_x:
|
||||
push [putimg.edi]
|
||||
mov eax, [putimg.ebp + 4]
|
||||
call eax
|
||||
cmp [ebp], bl
|
||||
jne .skip
|
||||
|
||||
; store to LFB
|
||||
mov [LFB_BASE + edx], ax
|
||||
shr eax, 16
|
||||
mov [LFB_BASE + edx + 2], al
|
||||
|
||||
.skip:
|
||||
add edx, 3
|
||||
inc ebp
|
||||
dec ecx
|
||||
jnz .new_x
|
||||
|
||||
add esi, [putimg.line_increment]
|
||||
add edx, [putimg.screen_newline]
|
||||
add ebp, [putimg.winmap_newline]
|
||||
|
||||
cmp [putimg.ebp], putimage_get1bpp
|
||||
jz .correct
|
||||
cmp [putimg.ebp], putimage_get2bpp
|
||||
jz .correct
|
||||
cmp [putimg.ebp], putimage_get4bpp
|
||||
jnz @f
|
||||
.correct:
|
||||
mov eax, [putimg.edi]
|
||||
mov byte [eax], 80h
|
||||
@@:
|
||||
dec edi
|
||||
jnz .new_line
|
||||
.finish:
|
||||
add esp, putimg.stack_data
|
||||
popad
|
||||
ret
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
align 4
|
||||
put_image_end_24_new:
|
||||
|
||||
.new_line:
|
||||
mov ecx, [putimg.real_sx]
|
||||
|
||||
.new_x:
|
||||
push [putimg.edi]
|
||||
mov eax, [putimg.ebp + 4]
|
||||
call eax
|
||||
cmp [ebp], bl
|
||||
jne .skip
|
||||
|
||||
push ecx
|
||||
.sh:
|
||||
neg ecx
|
||||
add ecx, [putimg.real_sx_and_abs_cx + 4]
|
||||
|
||||
; check for X
|
||||
cmp cx, [X_UNDER_sub_CUR_hot_x_add_curh]
|
||||
jae .no_mouse_area
|
||||
|
||||
sub cx, [X_UNDER_subtraction_CUR_hot_x]
|
||||
jb .no_mouse_area
|
||||
|
||||
shl ecx, 16
|
||||
|
||||
add ecx, [putimg.real_sy_and_abs_cy + 4]
|
||||
sub ecx, edi
|
||||
|
||||
; check for Y
|
||||
cmp cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
|
||||
jae .no_mouse_area
|
||||
|
||||
sub cx, [Y_UNDER_subtraction_CUR_hot_y]
|
||||
jb .no_mouse_area
|
||||
|
||||
; check mouse area for putpixel
|
||||
call check_mouse_area_for_putpixel_new.1
|
||||
cmp ecx, -1 ; MISTAKES HAPPEN?
|
||||
jne .no_mouse_area
|
||||
|
||||
mov ecx, [esp]
|
||||
jmp .sh
|
||||
|
||||
.no_mouse_area:
|
||||
pop ecx
|
||||
|
||||
; store to LFB
|
||||
mov [LFB_BASE + edx], ax
|
||||
shr eax, 16
|
||||
mov [LFB_BASE + edx + 2], al
|
||||
|
||||
.skip:
|
||||
add edx, 3
|
||||
inc ebp
|
||||
dec ecx
|
||||
jnz .new_x
|
||||
|
||||
add esi, [putimg.line_increment]
|
||||
add edx, [putimg.screen_newline]
|
||||
add ebp, [putimg.winmap_newline]
|
||||
|
||||
cmp [putimg.ebp], putimage_get1bpp
|
||||
jz .correct
|
||||
cmp [putimg.ebp], putimage_get2bpp
|
||||
jz .correct
|
||||
cmp [putimg.ebp], putimage_get4bpp
|
||||
jnz @f
|
||||
|
||||
.correct:
|
||||
mov eax, [putimg.edi]
|
||||
mov byte [eax], 80h
|
||||
|
||||
@@:
|
||||
dec edi
|
||||
jnz .new_line
|
||||
jmp put_image_end_24.finish
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
align 4
|
||||
put_image_end_32:
|
||||
|
||||
mov edi, [putimg.real_sy]
|
||||
|
||||
; check for hardware cursor
|
||||
mov ecx, [_display.select_cursor]
|
||||
cmp ecx, select_cursor
|
||||
je put_image_end_32_new
|
||||
|
||||
.new_line:
|
||||
mov ecx, [putimg.real_sx]
|
||||
|
||||
.new_x:
|
||||
push [putimg.edi]
|
||||
mov eax, [putimg.ebp + 4]
|
||||
call eax
|
||||
cmp [ebp], bl
|
||||
jne .skip
|
||||
|
||||
; store to LFB
|
||||
mov [LFB_BASE + edx], eax
|
||||
|
||||
.skip:
|
||||
add edx, 4
|
||||
inc ebp
|
||||
dec ecx
|
||||
jnz .new_x
|
||||
|
||||
add esi, [putimg.line_increment]
|
||||
add edx, [putimg.screen_newline]
|
||||
add ebp, [putimg.winmap_newline]
|
||||
|
||||
cmp [putimg.ebp], putimage_get1bpp
|
||||
jz .correct
|
||||
cmp [putimg.ebp], putimage_get2bpp
|
||||
jz .correct
|
||||
cmp [putimg.ebp], putimage_get4bpp
|
||||
jnz @f
|
||||
|
||||
.correct:
|
||||
mov eax, [putimg.edi]
|
||||
mov byte [eax], 80h
|
||||
|
||||
@@:
|
||||
dec edi
|
||||
jnz .new_line
|
||||
|
||||
.finish:
|
||||
add esp, putimg.stack_data
|
||||
popad
|
||||
|
||||
cmp [SCR_MODE], 0x12
|
||||
jne @f
|
||||
call VGA__putimage
|
||||
@@ -369,30 +606,24 @@ put_image_end:
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
; a row the software cursor sits on; the rest go to putimage_row untouched
|
||||
; edi = rows left, otherwise as putimage_row; putimg refs carry +4
|
||||
|
||||
align 4
|
||||
putimage_row_cursor:
|
||||
put_image_end_32_new:
|
||||
|
||||
mov eax, [putimg.real_sy_and_abs_cy + 4]
|
||||
sub eax, edi ; screen y of this row
|
||||
cmp ax, [Y_UNDER_sub_CUR_hot_y_add_curh]
|
||||
jae putimage_row
|
||||
sub ax, [Y_UNDER_subtraction_CUR_hot_y]
|
||||
jb putimage_row
|
||||
.new_line:
|
||||
mov ecx, [putimg.real_sx]
|
||||
|
||||
.new_x:
|
||||
push [putimg.edi + 4]
|
||||
mov eax, [putimg.ebp + 8]
|
||||
push [putimg.edi]
|
||||
mov eax, [putimg.ebp + 4]
|
||||
call eax
|
||||
cmp [ebp], bl
|
||||
jne .skip
|
||||
|
||||
push ecx
|
||||
|
||||
.sh:
|
||||
neg ecx
|
||||
add ecx, [putimg.real_sx_and_abs_cx + 8]
|
||||
add ecx, [putimg.real_sx_and_abs_cx + 4]
|
||||
|
||||
; check for X
|
||||
cmp cx, [X_UNDER_sub_CUR_hot_x_add_curh]
|
||||
@@ -401,7 +632,7 @@ putimage_row_cursor:
|
||||
jb .no_mouse_area
|
||||
shl ecx, 16
|
||||
|
||||
add ecx, [putimg.real_sy_and_abs_cy + 8]
|
||||
add ecx, [putimg.real_sy_and_abs_cy + 4]
|
||||
sub ecx, edi
|
||||
|
||||
; check for Y
|
||||
@@ -412,7 +643,7 @@ putimage_row_cursor:
|
||||
|
||||
; check mouse area for putpixel
|
||||
call check_mouse_area_for_putpixel_new.1
|
||||
cmp ecx, -1
|
||||
cmp ecx, -1 ; SHIT HAPPENS?
|
||||
jne .no_mouse_area
|
||||
|
||||
mov ecx, [esp]
|
||||
@@ -420,292 +651,35 @@ putimage_row_cursor:
|
||||
|
||||
.no_mouse_area:
|
||||
pop ecx
|
||||
call [putimg.store + 4]
|
||||
|
||||
; store to LFB
|
||||
mov [LFB_BASE+edx], eax
|
||||
|
||||
.skip:
|
||||
add edx, [putimg.dst_bpp + 4]
|
||||
add edx, 4
|
||||
inc ebp
|
||||
dec ecx
|
||||
jnz .new_x
|
||||
ret
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; the bit position a 1, 2 or 4bpp getter carries between calls
|
||||
add esi, [putimg.line_increment]
|
||||
add edx, [putimg.screen_newline]
|
||||
add ebp, [putimg.winmap_newline]
|
||||
|
||||
align 4
|
||||
putimage_next_row:
|
||||
add esi, [putimg.line_increment + 4]
|
||||
add edx, [putimg.screen_newline + 4]
|
||||
add ebp, [putimg.winmap_newline + 4]
|
||||
cmp [putimg.ebp], putimage_get1bpp
|
||||
jz .correct
|
||||
cmp [putimg.ebp], putimage_get2bpp
|
||||
jz .correct
|
||||
cmp [putimg.ebp], putimage_get4bpp
|
||||
jnz @f
|
||||
|
||||
cmp [putimg.skip + 4], putimage_skip_getter
|
||||
jne .done
|
||||
mov eax, [putimg.edi + 4]
|
||||
.correct:
|
||||
mov eax, [putimg.edi]
|
||||
mov byte [eax], 80h
|
||||
.done:
|
||||
ret
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; esi = source, edx = framebuffer offset, ebp = window map, ecx = width, bl = slot
|
||||
; esi, edx, ebp come back advanced by one row; putimg refs carry +16
|
||||
|
||||
align 4
|
||||
putimage_row:
|
||||
|
||||
push edi ; the caller's row counter
|
||||
lea edi, [LFB_BASE + edx]
|
||||
|
||||
.find:
|
||||
mov eax, [putimg.mask + 8]
|
||||
push ebp ; the run start
|
||||
cmp [ebp], bl
|
||||
je .ours
|
||||
|
||||
.skip_dw:
|
||||
; four at a time: xor turns a slot byte into zero, and zero borrows into bit 7
|
||||
cmp ecx, 4
|
||||
jb .skip_tail
|
||||
mov edx, [ebp]
|
||||
xor edx, eax
|
||||
sub edx, 0x01010101
|
||||
test edx, 0x80808080
|
||||
jnz .skip_scan
|
||||
add ebp, 4
|
||||
sub ecx, 4
|
||||
jmp .skip_dw
|
||||
.skip_tail:
|
||||
jecxz .skip_go ; the dwords took the whole row
|
||||
.skip_scan:
|
||||
inc ebp
|
||||
dec ecx
|
||||
jz .skip_go
|
||||
cmp [ebp], bl
|
||||
jne .skip_scan
|
||||
.skip_go:
|
||||
mov edx, [putimg.skip + 12]
|
||||
jmp .go
|
||||
|
||||
.ours:
|
||||
mov edx, ecx
|
||||
shr edx, 2
|
||||
jz .ours_byte
|
||||
lea ebp, [ebp + edx*4]
|
||||
neg edx
|
||||
.ours_dw:
|
||||
cmp [ebp + edx*4], eax
|
||||
jne .ours_dw_end
|
||||
inc edx
|
||||
jnz .ours_dw
|
||||
.ours_dw_end:
|
||||
lea ebp, [ebp + edx*4]
|
||||
.ours_byte:
|
||||
mov edx, ebp
|
||||
sub edx, [esp]
|
||||
sub ecx, edx ; pixels left past the matched dwords
|
||||
jz .ours_go
|
||||
.ours_scan:
|
||||
cmp [ebp], bl
|
||||
jne .ours_go
|
||||
inc ebp
|
||||
dec ecx
|
||||
jnz .ours_scan
|
||||
.ours_go:
|
||||
mov edx, [putimg.conv + 12]
|
||||
|
||||
.go:
|
||||
pop eax ; the run start
|
||||
push ecx ; pixels left in the row
|
||||
mov ecx, ebp
|
||||
sub ecx, eax ; the run length
|
||||
call edx
|
||||
pop ecx
|
||||
test ecx, ecx
|
||||
jnz .find
|
||||
|
||||
.done:
|
||||
lea edx, [edi - LFB_BASE]
|
||||
pop edi
|
||||
ret
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
align 4
|
||||
putimage_skip_bytes:
|
||||
mov eax, [putimg.dst_bpp + 16]
|
||||
imul eax, ecx
|
||||
add edi, eax
|
||||
mov eax, [putimg.src_bpp + 16]
|
||||
imul eax, ecx
|
||||
add esi, eax
|
||||
ret
|
||||
|
||||
align 4
|
||||
putimage_skip_getter:
|
||||
mov eax, [putimg.dst_bpp + 16]
|
||||
imul eax, ecx
|
||||
add edi, eax
|
||||
.one:
|
||||
push [putimg.edi + 16]
|
||||
mov eax, [putimg.ebp + 20]
|
||||
call eax
|
||||
dec ecx
|
||||
jnz .one
|
||||
ret
|
||||
|
||||
align 4
|
||||
putimage_conv_16_16:
|
||||
; the getter 565 is the screen 565, so the pixels travel untouched
|
||||
shr ecx, 1
|
||||
jnc @f
|
||||
movsw
|
||||
@@:
|
||||
rep movsd
|
||||
ret
|
||||
|
||||
align 4
|
||||
putimage_conv_24_24:
|
||||
lea ecx, [ecx + ecx*2]
|
||||
rep movsb
|
||||
ret
|
||||
|
||||
align 4
|
||||
putimage_conv_8_32:
|
||||
; the palette is the getter argument
|
||||
push ebx
|
||||
mov ebx, [putimg.edi + 20]
|
||||
.one:
|
||||
movzx eax, byte [esi]
|
||||
mov eax, [ebx + eax*4]
|
||||
mov [edi], eax
|
||||
inc esi
|
||||
add edi, 4
|
||||
dec ecx
|
||||
jnz .one
|
||||
pop ebx
|
||||
ret
|
||||
|
||||
align 4
|
||||
putimage_conv_24_32:
|
||||
; a dword read takes a byte of the next pixel, so the last four go slow
|
||||
cmp ecx, 5
|
||||
jb .tail
|
||||
.four:
|
||||
mov eax, [esi]
|
||||
and eax, 0x00FFFFFF
|
||||
mov [edi], eax
|
||||
mov eax, [esi + 3]
|
||||
and eax, 0x00FFFFFF
|
||||
mov [edi + 4], eax
|
||||
mov eax, [esi + 6]
|
||||
and eax, 0x00FFFFFF
|
||||
mov [edi + 8], eax
|
||||
mov eax, [esi + 9]
|
||||
and eax, 0x00FFFFFF
|
||||
mov [edi + 12], eax
|
||||
add esi, 12
|
||||
add edi, 16
|
||||
sub ecx, 4
|
||||
cmp ecx, 5
|
||||
jae .four
|
||||
.tail:
|
||||
.one:
|
||||
movzx eax, byte [esi + 2]
|
||||
shl eax, 16
|
||||
mov ax, [esi]
|
||||
mov [edi], eax
|
||||
add esi, 3
|
||||
add edi, 4
|
||||
dec ecx
|
||||
jnz .one
|
||||
ret
|
||||
|
||||
; esi = source, edi = framebuffer, ecx = pixels, nonzero; both come back past
|
||||
; the run. putimg refs here carry +16, or +20 with something pushed
|
||||
|
||||
align 4
|
||||
putimage_conv_32_32:
|
||||
rep movsd
|
||||
ret
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
;------------------------------------------------------------------------------
|
||||
;------------------------------------------------------------------------------
|
||||
;------------------------------------------------------------------------------
|
||||
;------------------------------------------------------------------------------
|
||||
;------------------------------------------------------------------------------
|
||||
align 4
|
||||
putimage_conv_any_16:
|
||||
.one:
|
||||
push [putimg.edi + 16]
|
||||
mov eax, [putimg.ebp + 20]
|
||||
call eax
|
||||
and eax, 00000000111110001111110011111000b
|
||||
shr ah, 2
|
||||
shr ax, 3
|
||||
ror eax, 8
|
||||
add al, ah
|
||||
rol eax, 8
|
||||
mov [edi], ax
|
||||
add edi, 2
|
||||
dec ecx
|
||||
jnz .one
|
||||
ret
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
align 4
|
||||
putimage_conv_any_24:
|
||||
.one:
|
||||
push [putimg.edi + 16]
|
||||
mov eax, [putimg.ebp + 20]
|
||||
call eax
|
||||
mov [edi], ax
|
||||
shr eax, 16
|
||||
mov [edi + 2], al
|
||||
add edi, 3
|
||||
dec ecx
|
||||
jnz .one
|
||||
ret
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
align 4
|
||||
putimage_conv_any_32:
|
||||
.one:
|
||||
push [putimg.edi + 16]
|
||||
mov eax, [putimg.ebp + 20]
|
||||
call eax
|
||||
mov [edi], eax
|
||||
add edi, 4
|
||||
dec ecx
|
||||
jnz .one
|
||||
ret
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; eax = pixel, edx = framebuffer offset
|
||||
|
||||
align 4
|
||||
putimage_store_16:
|
||||
and eax, 00000000111110001111110011111000b
|
||||
shr ah, 2
|
||||
shr ax, 3
|
||||
ror eax, 8
|
||||
add al, ah
|
||||
rol eax, 8
|
||||
mov [LFB_BASE + edx], ax
|
||||
ret
|
||||
|
||||
align 4
|
||||
putimage_store_24:
|
||||
mov [LFB_BASE + edx], ax
|
||||
shr eax, 16
|
||||
mov [LFB_BASE + edx + 2], al
|
||||
ret
|
||||
|
||||
align 4
|
||||
putimage_store_32:
|
||||
mov [LFB_BASE + edx], eax
|
||||
ret
|
||||
|
||||
|
||||
|
||||
dec edi
|
||||
jnz .new_line
|
||||
jmp put_image_end_32.finish
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; eax = x coordinate
|
||||
|
||||
+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;
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
Copyright (c) 2007-2012, Marc Kerbiquet
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
3. Neither the name of AsmXml nor the names of its contributors may be
|
||||
used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
@@ -0,0 +1,2 @@
|
||||
if tup.getconfig("NO_FASM") ~= "" then return end
|
||||
tup.rule("xml.asm", "fasm %f %o " .. tup.getconfig("KPACK_CMD"), "xml.obj")
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,59 @@
|
||||
; SPDX-License-Identifier: GPL-2.0-only
|
||||
;
|
||||
; xml.obj - AsmXml parser as a KolibriOS library
|
||||
; Copyright (C) KolibriOS team 2026
|
||||
;
|
||||
; asm-xml.asm and LICENSE.txt are the unmodified AsmXml 1.4 release
|
||||
; by Marc Kerbiquet (BSD 3-clause), https://tibleiz.net/asm-xml/
|
||||
|
||||
format MS COFF
|
||||
|
||||
public EXPORTS
|
||||
|
||||
section '.flat' code readable align 16
|
||||
|
||||
; AsmXml calls malloc/free as cdecl, the heap functions given to lib_init
|
||||
; are stdcall: the caller pops the argument they have already taken
|
||||
lib_init:
|
||||
mov [mem.alloc], eax
|
||||
mov [mem.free], ebx
|
||||
mov eax, malloc
|
||||
mov ebx, free
|
||||
jmp initialize
|
||||
|
||||
malloc:
|
||||
push dword [esp + 4]
|
||||
call [mem.alloc]
|
||||
ret
|
||||
|
||||
free:
|
||||
push dword [esp + 4]
|
||||
call [mem.free]
|
||||
ret
|
||||
|
||||
align 4
|
||||
mem.alloc dd ?
|
||||
mem.free dd ?
|
||||
|
||||
align 16
|
||||
EXPORTS:
|
||||
dd sz_lib_init, lib_init
|
||||
dd sz_initializeParser, _initializeParser
|
||||
dd sz_releaseParser, _releaseParser
|
||||
dd sz_parse, _parse
|
||||
dd sz_initializeClassParser, _initializeClassParser
|
||||
dd sz_releaseClassParser, _releaseClassParser
|
||||
dd sz_classFromElement, _classFromElement
|
||||
dd sz_classFromString, _classFromString
|
||||
dd 0, 0
|
||||
|
||||
sz_lib_init db 'lib_init', 0
|
||||
sz_initializeParser db 'ax_initializeParser', 0
|
||||
sz_releaseParser db 'ax_releaseParser', 0
|
||||
sz_parse db 'ax_parse', 0
|
||||
sz_initializeClassParser db 'ax_initializeClassParser', 0
|
||||
sz_releaseClassParser db 'ax_releaseClassParser', 0
|
||||
sz_classFromElement db 'ax_classFromElement', 0
|
||||
sz_classFromString db 'ax_classFromString', 0
|
||||
|
||||
include 'asm-xml.asm'
|
||||
@@ -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,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 ?
|
||||
@@ -847,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
|
||||
@@ -855,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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
@@ -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")
|
||||
|
||||
Reference in new issue
Block a user