Compare commits

...
Author SHA1 Message Date
Burer 743fea2f4e system/docpack: rework the window, add online docs
Test PR / Build (es_ES) (pull_request) Failing after 1m40s
Test PR / Build (en_US) (pull_request) Canceled after 1m43s
Test PR / Build (ru_RU) (pull_request) Canceled after 1m42s
Window:
- the documents in two groups, General and Development, and a group
  with the KolibriOS wiki and the FASM manual, opened in WebView
- buttons in the colours of the skin, 24 px high, 12 px apart; the
  window is centred on the screen
- hotkeys L H K C D S N I O W F on the buttons, the same in every
  language; read by scancode, so any layout and case works
- titles and labels for en_US, ru_RU and es_ES

Fixes:
- the text was sent to CEdit once after a fixed 0.2 s and got lost
  when CEdit started slower; retry for up to the 2 s CEdit waits
- an unknown parameter opened the KFar keys; now it shows the
  window, and the parameter takes the hotkey letters
- show @notify when CEdit or WebView cannot be started

Code:
- piano style: the format macro, KOSfuncs constants, the language
  from -dlang, a 512-byte stack
- embed the documents straight from data/ and kernel/trunk/docs;
  the Tupfile only converts sysfuncr.txt to cp866
- drop the stale build_*.bat and makefile
- take Docs/SysFuncs.txt from kernel/trunk/docs directly
- point the docpack links of the Russian guide to the hotkeys

Assisted-by: Claude:claude-opus-5-5
2026-10-05 15:55:57 +03:00
Burer 723a1b4437 system/docpack: move the FASM manual out of kolibri.img, fix keys layout in docs (#739)
Build system / Build (en_US) (push) Successful in 4m9s
Build system / Build (ru_RU) (push) Successful in 4m17s
Build system / Build (es_ES) (push) Successful in 4m26s
Build system / Publish Images (push) Successful in 10m49s
Test PR / Build (en_US) (pull_request) Successful in 2m34s
Test PR / Build (es_ES) (pull_request) Successful in 3m30s
Test PR / Build (ru_RU) (pull_request) Successful in 3m29s
- Move the FASM manual out of DOCPACK to `/kolibrios/develop/fasm/fasm.txt` on ISO, next to the Oberon-07 and TCC docs
- Update the document letters in the Russian `guide.htm`, they were one letter off before
- Default document for an unknown parameter stays KFar keys

| DOCPACK, kpacked, sectors | en_US | ru_RU | es_ES |
|---|---|---|---|
| before | 218 + 150 | 232 + 62 | 218 + 199 |
| after | 95 + 468 | 105 + 466 | 95 + 493 |

Reviewed-on: #739
Reviewed-by: Kiril Lipatov <lipatov.kiril@gmail.com>
Reviewed-by: Mikhail Frolov <mixa.frolov2003@gmail.com>
2026-10-04 13:14:51 +00:00
Leency bd071d588b kernel/net: fix use-after-free on refused TCP connections (#622)
Build system / Build (en_US) (push) Successful in 3m2s
Build system / Build (es_ES) (push) Successful in 3m9s
Build system / Build (ru_RU) (push) Successful in 3m15s
Build system / Publish Images (push) Successful in 11m5s
tcp_input: on RST+ACK in SYN_SENT, unlock the socket mutex before
tcp_drop and leave through .drop_no_socket. tcp_drop frees the socket
and locks that mutex itself, so the network thread hung on it.

Assisted-by: Claude:claude-opus-5
Reviewed-on: #622
Reviewed-by: hidnplayr <hidnplayr@gmail.com>
Reviewed-by: Burer <burer@kolibrios.org>
Co-authored-by: Kiril Lipatov <lipatov.kiril@gmail.com>
2026-09-29 19:12:30 +00:00
Leency 9ec66b0eba drivers/i8255x: get to work on a real device (#725)
Build system / Build (en_US) (push) Successful in 3m23s
Build system / Build (es_ES) (push) Successful in 3m27s
Build system / Build (ru_RU) (push) Successful in 3m31s
Build system / Publish Images (push) Successful in 11m54s
- the TX reclaim loop in int_handler multiplied sizeof.txfd by itself  (mul eax) instead of by last_tx, so it looked 1024 bytes past tx_ring and never freed a descriptor
- it also left txfd.status set, and transmit treats a non-zero status as busy, so once the 16-entry ring wrapped every send ended in "TX overrun": DHCP fell back to link-local, ping showed "Socket error", while the link still read as connected
- reclaim only descriptors the device completed (TXFD_STATUS_C) and zero their status; transmit now checks for an unreclaimed buffer (virt_addr)

Seen on an EtherExpress Pro/100 in a Pentium II. Reproduced in QEMU (-cpu pentium2, i82557b): ping stopped at the 12th reply every time; with the fix it runs indefinitely, also under a UDP flood.

Reviewed-on: #725
Reviewed-by: hidnplayr <hidnplayr@gmail.com>
Reviewed-by: Burer <burer@kolibrios.org>
Co-authored-by: leency <lipatov.kiril@gmail.com>
2026-09-29 19:03:24 +00:00
Leency 95bcf78537 kernel/ahci: support CD/DVD drives (ATAPI) (#694)
Build system / Build (es_ES) (push) Successful in 3m34s
Build system / Build (en_US) (push) Successful in 3m39s
Build system / Build (ru_RU) (push) Successful in 3m46s
Build system / Publish Images (push) Successful in 10m4s
Summary: an optical drive on an AHCI port was detected and then ignored,
so CD/DVD only worked with the controller switched to IDE mode. It now
shows up as /srN and ISO9660 discs are readable, including disc changes.

Details:
- ahci_atapi_cmd sends a SCSI command through the ATA PACKET command
  (A bit in the command header, CDB in acmd, DMA when IDENTIFY PACKET
  word 49 allows it, DMADIR when word 62 requires it). Built on top of it:
  TEST UNIT READY, REQUEST SENSE, READ CAPACITY(10), READ(10), READ TOC
  (start of the last session for multisession discs) and START STOP UNIT
  for DISKFUNC.LoadTray.
- Drives are registered as sr0, sr1, ... with DISK_NO_INSERT_NOTIFICATION,
  2048-byte sectors and read-only media; iso9660 mounts them as /srN/1.
  They cannot be named cd*: fs_lfn.inc sends every path starting with "cd"
  to the old ATAPI-over-IDE code.
- Disc change: the kernel lets go of a mounted medium only when querymedia
  fails, so after a UNIT ATTENTION querymedia fails once and the kernel
  immediately mounts the new disc. A READ(10) that hits UNIT ATTENTION
  fails instead of silently reading the new disc.
- One ATAPI transfer is capped at (PRDT_MAX_ENTRIES - 1) * 4096 bytes, so
  the PRDT always covers the whole request. The PRDT builder moved out of
  ahci_rw_sectors into ahci_build_prdt and is shared by both paths.
- A command the drive refuses (an empty tray does that on every TEST UNIT
  READY) restarts the port quietly instead of running the full recovery.
- Optical ports never busy-poll a long command and never switch the whole
  controller to polling: missing interrupts are counted per port and only
  that port's PxIE is turned off.
- Diagnostic output (command statistics, interrupt wakeups, register dumps
  during init) is now behind AHCI_DBGLVL, off by default. Errors and one
  line per detected device are still printed.

Tested: QEMU, VirtualBox and VMware (detection, listings and reads checked
against host checksums; eject/insert in QEMU and VirtualBox, a direct disc
swap in VirtualBox, an empty drive in VMware), SATA disk read/write on the
same controller in QEMU, and a GA-D525TUD (NM10) with an ASUS DRW-24B3ST:
detection, reading, disc change. The debug level change was build-tested
only.

Assisted-by: Claude Opus 5
Reviewed-on: #694
Reviewed-by: Burer <burer@kolibrios.org>
Reviewed-by: Ivan B <1+dunkaist@noreply.localhost>
Co-authored-by: leency <lipatov.kiril@gmail.com>
2026-09-29 15:44:06 +00:00
Leency 6f3cae4e0c kernel/network: fix window-update check in tcp_output (#711)
Build system / Build (en_US) (push) Successful in 4m8s
Build system / Build (es_ES) (push) Successful in 3m58s
Build system / Build (ru_RU) (push) Successful in 4m9s
Build system / Publish Images (push) Successful in 11m38s
`tcp_output`: the window-update check computed `min(free, max_win - advertised)` instead of BSD's `min(free, max_win) - advertised`. With unread data in the receive buffer, every `send()` produced an empty ACK and never reached the persist state: no zero-window probes, and the connection hung.

- Clamp to the free space first, then subtract the advertised window.
- Compare signed: the result is negative when the window shrank.

Tested in QEMU with pcap: ~11000 empty ACKs in 0.6 s and no probe before the fix; 12 ACKs and a 1-byte persist probe after it.

Reviewed-on: #711
Reviewed-by: Burer <burer@kolibrios.org>
Reviewed-by: hidnplayr <hidnplayr@gmail.com>
Co-authored-by: leency <lipatov.kiril@gmail.com>
2026-09-29 13:38:57 +00:00
Leency b59e371c0e kernel/network: forget a network device's state when it is removed (#719)
Build system / Build (en_US) (push) Successful in 5m45s
Build system / Build (es_ES) (push) Successful in 5m55s
Build system / Build (ru_RU) (push) Successful in 6m4s
Build system / Publish Images (push) Failing after 11m50s
- `net_remove_device`: clear the slot's IPv4 settings, ARP table and counters, and drop its frames from the ethernet input queue.
- `ipv4_route`:
  - skip slots without a device;
  - an interface without an address routes broadcasts only;
  - off-link without a gateway fails instead of resolving 0.0.0.0.
- `ipv4_output_raw`: check the route before resolving it.
- `eth_output`, `arp_output_request`: refuse a null device.
- `eth_output`: count a too-large frame on the device, not on `eax`.

Reviewed-on: #719
Reviewed-by: hidnplayr <hidnplayr@gmail.com>
Reviewed-by: Burer <burer@kolibrios.org>
Co-authored-by: leency <lipatov.kiril@gmail.com>
2026-09-29 13:30:00 +00:00
Leency 939505198f http.obj: close the socket when connect() fails; kernel: unlock on tcp_connect errors
Check kernel codestyle / Check kernel codestyle (pull_request) Successful in 25s
Test PR / Build (ru_RU) (pull_request) Successful in 2m2s
Test PR / Build (en_US) (pull_request) Successful in 2m11s
Test PR / Build (es_ES) (pull_request) Successful in 2m18s
Build system / Build (en_US) (push) Successful in 3m50s
Build system / Build (es_ES) (push) Successful in 3m52s
Build system / Build (ru_RU) (push) Successful in 3m55s
Build system / Publish Images (push) Successful in 11m8s
open_connection in http.obj left the socket open whenever connect()
failed. The kernel never reclaims sockets of a finished process
(socket_process_end is a stub), so every failed connect leaked a socket
with its two SOCKET_BUFFER_SIZE rings for good, and a late SYN+ACK could
still connect the orphan. WebView with a few dead image hosts ran the
kernel heap dry ("SOCKET_ring_create: Out of memory!"), after which every
application lost the network. Close the socket on the way out.

The socket() error check compared against 0, but the syscall returns -1
on failure; compare with -1.

The close() above exposed a second bug: tcp_connect took SOCKET.mutex
before creating the rings and returned from .nomem and .enoroute without
releasing it. Any later socket_free on that socket - close() from the
application, once http.obj does it - then waited for the mutex forever
and the thread became unkillable. Unlock on both error exits.

Assisted-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-28 14:38:01 +03:00
Burer 75cb80fd33 ci: compact older builds on the storage server (#697)
Build system / Build (es_ES) (push) Successful in 3m23s
Build system / Build (en_US) (push) Successful in 3m27s
Build system / Build (ru_RU) (push) Successful in 3m28s
Build system / Publish Images (push) Successful in 3m14s
Every push to main publishes 4 images per language plus the unpacked build tree, and nothing on the storage server ever shrinks. `kolibri.raw` is a fixed 128 MiB regardless of content, and `kolibri.img` ends up stored three times per language.

This adds a compaction step at the end of the deploy playbook. It runs on the storage server itself, so nothing extra crosses the network.

- The build that was just published stays as it is: bare images and a browsable tree.
- Every older build keeps its images zipped and loses the unpacked tree, which is rebuildable from the commit anyway.

`*.distr.zip`, `sha256sums.txt` and `build.log` are never touched.

Reviewed-on: #697
Reviewed-by: Gleb Zaharov <risdeveau@lair.moe>
Reviewed-by: Mikhail Frolov <mixa.frolov2003@gmail.com>
2026-09-28 07:32:37 +00:00
Burer 6ba901606d ci: open submodule bump PRs as the bot, not as Actions
Test PR / Build (es_ES) (pull_request) Successful in 4m48s
Test PR / Build (en_US) (pull_request) Successful in 5m3s
Test PR / Build (ru_RU) (pull_request) Successful in 2m18s
Build system / Build (ru_RU) (push) Successful in 4m52s
Build system / Build (es_ES) (push) Successful in 5m11s
Build system / Build (en_US) (push) Successful in 5m16s
Build system / Publish Images (push) Successful in 4m8s
A branch pushed and a pull request opened with the built-in GITEA_TOKEN
come from the Actions user, and events it creates start no workflow run.
Test PR never ran on a bump, so the required check stayed missing and
the PRs could not be merged however many approvals they collected.

Put BOT_TOKEN back in both places: checkout persists it for the push,
and the API call needs it to open the PR under the bot account. This
reverts 882f1f024.

Assisted-by: Claude Opus 5 <noreply@anthropic.com>
2026-09-28 07:17:58 +00:00
kolibrios-bot Bot b1d329da2a chore/submodules: bump cmm to 4aeaee3386dac12fc4ef57ad531b632890df5425
Test PR / Build (es_ES) (pull_request) Successful in 2m22s
Test PR / Build (ru_RU) (pull_request) Successful in 2m25s
Test PR / Build (en_US) (pull_request) Successful in 2m27s
Build system / Build (es_ES) (push) Successful in 6m5s
Build system / Build (en_US) (push) Successful in 6m31s
Build system / Build (ru_RU) (push) Successful in 6m35s
Build system / Publish Images (push) Successful in 5m18s
2026-09-28 07:14:00 +00:00
Leency df9946fe80 libs/libimg: make the grayscale JPEG palette opaque
Test PR / Build (en_US) (pull_request) Successful in 1m55s
Test PR / Build (ru_RU) (pull_request) Successful in 2m1s
Test PR / Build (es_ES) (pull_request) Successful in 2m5s
Build system / Build (es_ES) (push) Successful in 2m59s
Build system / Build (en_US) (push) Successful in 3m5s
Build system / Build (ru_RU) (push) Successful in 3m10s
Build system / Publish Images (push) Successful in 3m27s
A grayscale JPEG is decoded as Image.bpp8i with a 256-level gray
palette built from xor eax, eax, so every entry had alpha 0. After
img.convert to Image.bpp32 the picture was fully transparent: programs
that blend by alpha (WebView) reserved its room and drew nothing.
The palette now starts at 0xFF000000, as the PNG decoder fills its own.

Assisted-by: Claude Opus 5 <noreply@anthropic.com>
2026-09-27 20:13:13 +03:00
22 changed files with 1780 additions and 389 deletions

No files matched your search

+24
View File
@@ -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"
+74
View File
@@ -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"
+2 -1
View File
@@ -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 }}
+2 -1
View File
@@ -166,6 +166,7 @@ extra_files = {
{"kolibrios/demos/rpento.lif", "common/demos/rpento.lif"},
{"kolibrios/develop/fpc/", "common/develop/fpc/*"},
{"kolibrios/develop/fpc/examples/", "../programs/develop/fp/examples/src/*"},
{"kolibrios/develop/fasm/fasm.txt", SRC_PROGS .. "/develop/fasm/1.73/fasm.txt"},
{"kolibrios/develop/oberon07/compiler.kex", SRC_PROGS .. "/develop/oberon07/Compiler.kex"},
{"kolibrios/develop/oberon07/LICENSE", SRC_PROGS .. "/develop/oberon07/LICENSE"},
{"kolibrios/develop/oberon07/doc/CC.txt", SRC_PROGS .. "/develop/oberon07/doc/CC.txt"},
@@ -352,7 +353,7 @@ if build_type == "ru_RU" then tup.append_table(extra_files, {
{"Docs/Hot_Keys.txt", build_type .. "/docs/Hot_Keys.txt"},
{"Docs/Install.txt", build_type .. "/docs/Install.txt"},
{"Docs/Credits.txt", build_type .. "/docs/Credits.txt"},
{"Docs/SysFuncs.txt", VAR_PROGS .. "/system/docpack/SysFuncs.txt"},
{"Docs/SysFuncs.txt", "../kernel/trunk/docs/sysfuncs.txt"},
{"HD_Load/9x2klbr/", SRC_PROGS .. "/hd_load/9x2klbr/readme.txt"},
{"HD_Load/mtldr/install.txt", SRC_PROGS .. "/hd_load/mtldr/install_eng.txt"},
{"HD_Load/USB_Boot/readme.txt", SRC_PROGS .. "/hd_load/usb_boot/readme_eng.txt"},
+4 -4
View File
@@ -20,13 +20,13 @@
<a href="hardware_support.htm">Поддержка оборудования</a>
<strong>Разработка</strong>
<a href="/sys/docpack|f">Справочник по системным функциям Колибри</a>
<a href="/sys/docpack|e">Использование отладчика</a>
<a href="/sys/docpack|d">Руководство FASM</a>
<a href="/sys/docpack|s">Справочник по системным функциям Колибри</a>
<a href="/sys/docpack|d">Использование отладчика</a>
<a href="/kolibrios/develop/fasm/fasm.txt">Руководство FASM</a>
<strong>Использование библиотек</strong>
<a href="/sys/docpack|i">Ini</a>
<a href="/sys/docpack|j">Диалог открытия файла OpenDial</a>
<a href="/sys/docpack|o">Диалог открытия файла OpenDial</a>
<strong>Смотрите также</strong>
Вики проекта <a href="http://wiki.kolibrios.org/">wiki.kolibrios.org</a>
+100 -14
View File
@@ -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:
File diff suppressed because it is too large. Load diff
+28
View File
@@ -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
+40 -1
View File
@@ -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
+44 -1
View File
@@ -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
;-----------------------------------------------------------------;
+10
View File
@@ -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
+6 -2
View File
@@ -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
@@:
;-----------------------------------------------------------------------------------
+8 -6
View File
@@ -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:
+4
View File
@@ -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
+5 -3
View File
@@ -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
+4 -20
View File
@@ -1,24 +1,8 @@
if tup.getconfig("NO_FASM") ~= "" or tup.getconfig("BUILD_TYPE") == "" then return end
if tup.getconfig("NO_FASM") ~= "" then return end
HELPERDIR = (tup.getconfig("HELPERDIR") == "") and "../.." or tup.getconfig("HELPERDIR")
tup.include(HELPERDIR .. "/use_fasm.lua")
add_include(tup.getvariantdir())
deps = tup.rule("echo lang fix " .. ((tup.getconfig("LANG") == "") and "en_US" or tup.getconfig("LANG")) .. " > %o", {"lang.inc"})
DOCDIR = "../../../data/" .. tup.getconfig("BUILD_TYPE") .. "/docs/"
if tup.getconfig("TUP_PLATFORM") == "win32"
then env_prefix = "set DOCDIR=$(DOCDIR)&&"; cp_cmd = "copy %f %o"
else env_prefix = "DOCDIR=$(DOCDIR) "; cp_cmd = "cp %f %o"
end
if tup.getconfig("LANG") == "ru_RU"
then tup.append_table(deps,
tup.rule("../../../kernel/trunk/docs/sysfuncr.txt", "iconv -f utf-8 -t cp866 %f > %o", "SysFuncr.txt"))
else tup.append_table(deps,
tup.rule("../../../kernel/trunk/docs/sysfuncs.txt", cp_cmd, "SysFuncs.txt"))
end
tup.append_table(deps,
tup.rule("../../develop/fasm/1.73/fasm.txt", cp_cmd, "Fasm.txt")
)
tup.append_table(deps,
tup.rule("../../../kernel/trunk/docs/stack.txt", cp_cmd, "Stack.txt")
)
tup.rule({"docpack.asm", extra_inputs = deps}, env_prefix .. FASM .. " %f %o " .. tup.getconfig("KPACK_CMD"), "docpack")
lang = (tup.getconfig("LANG") == "") and "en_US" or tup.getconfig("LANG")
deps = (lang == "ru_RU") and tup.rule("../../../kernel/trunk/docs/sysfuncr.txt", "iconv -f utf-8 -t cp866 %f > %o", "SysFuncr.txt") or {}
tup.rule({"docpack.asm", extra_inputs = deps}, FASM .. " -dlang=" .. lang .. " %f %o " .. tup.getconfig("KPACK_CMD"), "docpack")
-6
View File
@@ -1,6 +0,0 @@
@erase lang.inc
@echo lang fix en_US >lang.inc
@fasm -m 32768 docpack.asm docpack
@erase lang.inc
@kpack docpack
@pause
-6
View File
@@ -1,6 +0,0 @@
@erase lang.inc
@echo lang fix ru_RU >lang.inc
@fasm -m 32768 docpack.asm docpack
@erase lang.inc
@kpack docpack
@pause
+452 -200
View File
@@ -1,227 +1,479 @@
; SPDX-License-Identifier: NOASSERTION
;
;---------------------------------------------------------------------
; DocPack - KolibriOS documentation
; Copyright (C) 2006-2026 KolibriOS team
;
; DOCPAK FOR KOLIBRI v1.2
; Written in pure assembly by Ivushkin Andrey aka Willow
; Authors: Ivushkin Andrey aka Willow, Burer
;
;---------------------------------------------------------------------
; DOCPACK window with the documents and the online documentation
; DOCPACK x open the document or the link of the hotkey x
FILE_COUNT=0
DEF_FILE equ 'g'
; ====================================================================
macro embed_docdir_file fn
{
forward
local label,label2,label3
dd label2-label
dd label-label3
label3:
db fn
label:
file '%DOCDIR%' # fn
label2:
FILE_COUNT=FILE_COUNT+1
}
macro embed_local_file fn
{
forward
local label,label2,label3
dd label2-label
dd label-label3
label3:
db fn
label:
file fn
label2:
FILE_COUNT=FILE_COUNT+1
}
include "../../macros.inc"
include "../../KOSfuncs.inc"
include "../../encoding.inc"
use32
org 0x0
db 'MENUET01' ; 8 byte id
dd 0x01 ; header version
dd start ; start of code
dd I_END ; size of image
dd I_END+0x400 ; memory for app
dd I_END+0x400 ; esp
dd my_param , 0x0 ; I_Param , I_Icon
include '../../macros.inc'
include 'lang.inc' ; Language support for locales: ru_RU, en_US.
format meos 01
entry START
stack 512
start:
cmp [my_param],0
je red
cmp [my_param],'a'
jb .par_a
cmp [my_param],'z'
jbe .ok2
.par_a:
mov [my_param],DEF_FILE
.ok2:
movzx ecx,[my_param]
mov [my_param],'*'
.open:
sub ecx,'a'-1
mov edx,embedded
xor esi,esi
.list:
lea edx,[edx+esi+8]
mov esi,[edx-8]
add edx,[edx-4]
test esi,esi
jz .close
loop .list
push edx
; convert number in esi to decimal representation
mov ecx, 10
push -'0'
mov eax, esi
@@:
xor edx, edx
div ecx
push edx
test eax, eax
jnz @b
mov edi, fsize
@@:
pop eax
add al, '0'
stosb
jnz @b
mcall 70,fileinfo
mov ecx,eax
mcall 5,20
pop edx
mcall 60,2
cmp [my_param],'*'
jne still
.close:
mcall -1
; ====================================================================
red:
mov [my_param],'a'
START:
; "DOCPACK x" opens the item of the hotkey x and exits, any letter case
GetCommandLine eax
mov al, [eax]
or al, 'a' - 'A'
mcall 48, 3, sc, sizeof.system_colors
mov edi, letters
mov ecx, ITEMS
repne scasb
jne .window
mcall 12,1
sub edi, letters + 1
mov ecx, edi
call open
jmp exit
BTN_H equ 21
; no item: the window, its keys come as scancodes
.window:
mcall SF_KEYBOARD, SSF_SET_INPUT_MODE, 1
jmp redraw
mov edx,[sc.work]
or edx,0x34000000
mcall 0, <220,141>, <30,FILECOUNT*(BTN_H+3)+37>, , ,title
mov ecx,FILECOUNT
mov ebx,23 shl 16+100
mov esi,[sc.work_button]
mov edi,5 shl 16+BTN_H
mov edx,10
mov eax,8
.btnlp:
push ecx
mcall ,,edi
add edi,(BTN_H+3) shl 16
inc edx
pop ecx
loop .btnlp
mov ecx,FILECOUNT
mov edx,embedded
xor edi,edi
mov ebx,30 shl 16+8
mov eax,4
.list:
lea edx,[edx+edi+8]
mov edi,[edx-8]
pusha
sub ebx,20 shl 16
mov ecx, [sc.work_text]
or ecx, 0x30000000
mcall ,,,my_param,1
inc [my_param]
popa
push ecx
mov esi, [edx-4]
sub esi, 4 ;remove .txt extension
mov ecx, [sc.work_button_text]
or ecx, 0x30000000
mcall
pop ecx
add esi, 4
add edx, esi
add ebx,(BTN_H+3)
loop .list
mcall 12,2
; ====================================================================
still:
mcall 10
cmp eax,1
je red
cmp eax,2
jne .nokey
mcall 2
cmp ah,27 ;Esc
je start.close
cmp ah,'a'
jb still
cmp ah,'a'+FILECOUNT
jae still
jmp .cxax
.nokey:
mcall 17
cmp ah,1
je start.close
sub ah,10-'a'
.cxax:
movzx ecx,ah
jmp start.open
mcall SF_WAIT_EVENT
fileinfo:
dd 7
dd 0
dd param
dd 0 ,0
db '/sys/develop/cedit',0
cmp al, EV_REDRAW
je redraw
cmp al, EV_KEY
je key
cmp al, EV_BUTTON
je button
param db '*'
fsize:
times 10 db '0'
db 0
jmp still
embedded:
; ====================================================================
; Please use only filenames w/o path!
key:
mcall SF_GET_KEY
; -- Start of embedding area ------
cmp ah, KEY_ESC
je exit
embed_docdir_file 'Copying.txt' ;a
embed_docdir_file 'Hot_Keys.txt' ;b
embed_local_file 'Fasm.txt' ;c
embed_docdir_file 'Mtdbg.txt' ;d
; the item of the hotkey, if it is one
mov al, ah
mov edi, scancodes
mov ecx, ITEMS
repne scasb
jne still
sub edi, scancodes + 1
mov ecx, edi
call open
jmp still
; ====================================================================
button:
mcall SF_GET_BUTTON
cmp ah, 1
je exit
; the item of the button
movzx ecx, ah
sub ecx, ITEM_ID
cmp ecx, ITEMS
jae still
call open
jmp still
exit:
mcall SF_TERMINATE_PROCESS
; ====================================================================
; ecx = number of the item: the documents, then the links
open:
cmp ecx, FILECOUNT
jae .link
; find the document: each one is its size, then its text
mov edx, embedded
jecxz .found
.next:
add edx, [edx]
add edx, 4
loop .next
.found:
mov esi, [edx]
add edx, 4
mcall SF_FILE, cedit_run
test eax, eax
js .no_cedit
; then the text by IPC, once CEdit has set its IPC area
mov ecx, eax
mov edi, SEND_TRIES
.send:
mcall SF_SLEEP, SEND_DELAY
mcall SF_IPC, SSF_SEND_MESSAGE
test eax, eax
jz .done
; 1: no IPC area yet, 2: it is locked
cmp eax, 2
ja .done
dec edi
jnz .send
ret
; a link: WebView with its URL
.link:
mov eax, [urls + ecx*4 - FILECOUNT*4]
mov [webview_run.url], eax
mcall SF_FILE, webview_run
test eax, eax
jns .done
mov [notify_run.text], notify_webview
jmp .notify
.no_cedit:
mov [notify_run.text], notify_cedit
.notify:
mcall SF_FILE, notify_run
.done:
ret
; ====================================================================
redraw:
mcall SF_STYLE_SETTINGS, SSF_GET_COLORS, sc, sizeof.system_colors
mcall SF_REDRAW, SSF_BEGIN_DRAW
; the window in the centre of the screen
mcall SF_STYLE_SETTINGS, SSF_GET_SKIN_HEIGHT
mov esi, eax
add esi, WINDOW_H
mcall SF_GET_SCREEN_SIZE
movzx ecx, ax
sub ecx, esi
shr ecx, 1
shl ecx, 16
add ecx, esi
shr eax, 16
sub eax, WINDOW_W
shr eax, 1
shl eax, 16
mov ebx, eax
add ebx, WINDOW_W
mov edx, [sc.work]
or edx, WINDOW_STYLE
mcall SF_CREATE_WINDOW, , , , 0, title
; the frames of the groups with their titles
xor ebp, ebp
.group:
mov ebx, [boxes + ebp*8]
mov ecx, [boxes + ebp*8 + 4]
call group_box
inc ebp
cmp ebp, GROUPS
jb .group
; the buttons of the items with their labels
xor ebp, ebp
.button:
movzx ebx, [place + ebp*4]
movzx edi, [place + ebp*4 + 2]
shl ebx, 16
add ebx, BTN_W - 1
mov ecx, edi
shl ecx, 16
add ecx, BTN_H - 1
mov edx, ebp
add edx, ITEM_ID
mcall SF_DEFINE_BUTTON, , , , [sc.work_light]
and ebx, 0xFFFF0000
add ebx, (GAP shl 16) + TEXT_DY
add ebx, edi
mov ecx, ebp
mov edx, labels
call nth_string
mov ecx, [sc.work_text]
or ecx, FONT
mcall SF_DRAW_TEXT
inc ebp
cmp ebp, ITEMS
jb .button
mcall SF_REDRAW, SSF_END_DRAW
jmp still
; ====================================================================
; group box: a frame, the title over its top line
; ebp = number of the title, ebx = x shl 16 + width, ecx = y shl 16 + height
group_box:
mcall SF_DRAW_RECT, , , [sc.work_graph]
add ebx, (1 shl 16) - 2
add ecx, (1 shl 16) - 2
mcall SF_DRAW_RECT, , , [sc.work]
; a space, then the letters start where the buttons do
shr ecx, 16
sub ecx, 1 + TITLE_DY
and ebx, 0xFFFF0000
add ebx, (GAP - CHAR_W - 1) shl 16
add ebx, ecx
mov ecx, ebp
mov edx, groups
call nth_string
mov ecx, [sc.work_text]
or ecx, FONT + FILL
mcall SF_DRAW_TEXT, , , , , [sc.work]
ret
; edx = string number ecx of the zero separated list at edx
nth_string:
jecxz .done
.next:
inc edx
cmp byte [edx - 1], 0
jnz .next
loop .next
.done:
ret
; ====================================================================
; font: 8x16, the capitals are its rows 2..11
CHAR_W = 8
CAPS_Y = 2
CAPS_H = 10
; layout
GAP = 12
BTN_H = 24
BTN_W = LABEL_CHARS*CHAR_W + GAP*2
ROW = BTN_H + GAP
ROWS = 5
TEXT_DY = (BTN_H - CAPS_H)/2 - CAPS_Y ; the capitals centred in a button
; the frame of a group crosses the capitals of its title
TITLE_DY = CAPS_Y + CAPS_H/2
TITLE_ABOVE = TITLE_DY - CAPS_Y
TITLE_BELOW = CAPS_Y + CAPS_H - TITLE_DY
; two groups of the documents, GAP from the top to the capitals of the titles
GROUP_Y = GAP + TITLE_ABOVE
GROUP_W = 1 + GAP + BTN_W + GAP + 1
GROUP_H = TITLE_BELOW + GAP + ROWS*ROW + 1
COL1 = GAP + 1 + GAP ; x of the buttons
COL2 = COL1 + GROUP_W + GAP
BTN_Y = GROUP_Y + TITLE_BELOW + GAP ; y of the first row
; the group of the links below them, full width
LINKS_Y = GROUP_Y + GROUP_H + GAP + TITLE_ABOVE
LINKS_H = TITLE_BELOW + GAP + BTN_H + GAP + 1
LINK_Y = LINKS_Y + TITLE_BELOW + GAP
; window
CLIENT_W = GAP + GROUP_W + GAP + GROUP_W + GAP
CLIENT_H = LINKS_Y + LINKS_H + GAP
WINDOW_W = CLIENT_W + 9 ; the borders of a skinned window
WINDOW_H = CLIENT_H + 4 ; and the skin height
WINDOW_STYLE = 0x34000000 ; skinned, fixed size, caption, client coordinates
; text
FONT = 0xB0000000 ; zero terminated, 8x16 UTF-8
FILL = 0x40000000 ; draw the background of the text
; items: the documents, then the links
GROUPS = 3
LINKS = 2
ITEMS = FILECOUNT + LINKS
ITEM_ID = 10 ; the button of the item 0
KEY_ESC = 0x01 ; scancode
; CEdit
SEND_TRIES = 20
SEND_DELAY = 10 ; CEdit waits 2 s for the text
DOC_MAX = 524288 ; the size in cedit_param
; ====================================================================
FILE_COUNT = 0
; a document: its size, then its text
macro embed_file path
{
local label, label2
dd label2 - label
label:
file path
label2:
assert label2 - label <= DOC_MAX
FILE_COUNT = FILE_COUNT + 1
}
; a document of data/<language>/docs
macro embed_doc name
{
if lang eq ru_RU
embed_local_file 'SysFuncr.txt' ;e
else ; Default to en_US
embed_local_file 'SysFuncs.txt' ;e
embed_file "../../../data/ru_RU/docs/" # name
else if lang eq es_ES
embed_file "../../../data/es_ES/docs/" # name
else
embed_file "../../../data/en_US/docs/" # name
end if
embed_local_file 'Stack.txt' ;f
embed_docdir_file 'KFAR_Keys.txt' ;g
embed_docdir_file 'INI.txt' ;h
embed_docdir_file 'OpenDial.txt' ;i
embed_docdir_file 'Credits.txt' ;j
; -- End of embedding area -------
}
; ====================================================================
cedit_run:
dd SSF_START_APP
dd 0
dd cedit_param
dd 0, 0
db "/sys/develop/cedit", 0
webview_run:
dd SSF_START_APP
dd 0
.url dd 0
dd 0, 0
db "/sys/network/webview", 0
notify_run:
dd SSF_START_APP
dd 0
.text dd 0
dd 0, 0
db "/sys/@notify", 0
; the links
urls dd url_wiki, url_fasm
assert ($ - urls)/4 = LINKS
url_fasm db "https://flatassembler.net/docs.php?article=manual", 0
; the hotkeys of the items: on the command line and as scancodes,
; so they work in any layout and case
letters db "lhkcdsniowf"
assert $ - letters = ITEMS
scancodes db 0x26, 0x23, 0x25, 0x2E, 0x20, 0x1F, 0x31, 0x17, 0x18, 0x11, 0x21
assert $ - scancodes = ITEMS
; x shl 16 + width, y shl 16 + height of the groups
boxes dd (GAP shl 16) + GROUP_W, (GROUP_Y shl 16) + GROUP_H
dd ((GAP + GROUP_W + GAP) shl 16) + GROUP_W, (GROUP_Y shl 16) + GROUP_H
dd (GAP shl 16) + CLIENT_W - GAP*2, (LINKS_Y shl 16) + LINKS_H
assert ($ - boxes)/8 = GROUPS
; x, y of the buttons of the items
place dw COL1, BTN_Y, COL1, BTN_Y + ROW, COL1, BTN_Y + 2*ROW, COL1, BTN_Y + 3*ROW
dw COL2, BTN_Y, COL2, BTN_Y + ROW, COL2, BTN_Y + 2*ROW, COL2, BTN_Y + 3*ROW
dw COL2, BTN_Y + 4*ROW
dw COL1, LINK_Y, COL2, LINK_Y
assert ($ - place)/4 = ITEMS
; CEdit takes the size of its IPC buffer after "*", the text comes with
; its own size, so one size for all the documents
cedit_param db "*524288", 0
; ====================================================================
; the labels in the order of the embedded files, then the ones of the links
if lang eq ru_RU
LABEL_CHARS = 21 ; the longest label with its "X | "
title db 3, "Документация KolibriOS", 0
groups db " Общее ", 0, " Разработка ", 0, " Онлайн-документация ", 0
url_wiki db "https://wiki.kolibrios.org/wiki/For_developers/ru", 0
notify_cedit cp866 "'DocPack\nНе удалось запустить /sys/develop/cedit' -tE", 0
notify_webview cp866 "'DocPack\nНе удалось запустить /sys/network/webview' -tE", 0
labels db "L | Лицензия", 0, "H | Горячие клавиши", 0, "K | Клавиши KFar", 0, "C | Благодарности", 0
db "D | Отладчик", 0, "S | Системные функции", 0, "N | Сетевые функции", 0
db "I | Файлы INI", 0, "O | Диалог открытия", 0
db "W | Вики KolibriOS", 0, "F | Руководство FASM", 0
else if lang eq es_ES
LABEL_CHARS = 25
title db 3, "Documentación de KolibriOS", 0
groups db " General ", 0, " Desarrollo ", 0, " Documentación en línea ", 0
url_wiki db "https://wiki.kolibrios.org/wiki/For_developers/en", 0
notify_cedit db "'DocPack\nNo se pudo iniciar /sys/develop/cedit' -tE", 0
notify_webview db "'DocPack\nNo se pudo iniciar /sys/network/webview' -tE", 0
labels db "L | Licencia", 0, "H | Atajos de teclado", 0, "K | Teclas de KFar", 0, "C | Créditos", 0
db "D | Depurador", 0, "S | Funciones del sistema", 0, "N | Funciones de red", 0
db "I | Archivos INI", 0, "O | Diálogo de apertura", 0
db "W | Wiki de KolibriOS", 0, "F | Manual de FASM", 0
else
LABEL_CHARS = 21
title db 3, "KolibriOS Documentation", 0
groups db " General ", 0, " Development ", 0, " Online documentation ", 0
url_wiki db "https://wiki.kolibrios.org/wiki/For_developers/en", 0
notify_cedit db "'DocPack\nCould not start /sys/develop/cedit' -tE", 0
notify_webview db "'DocPack\nCould not start /sys/network/webview' -tE", 0
labels db "L | License", 0, "H | Hotkeys", 0, "K | KFar keys", 0, "C | Credits", 0
db "D | Debugger", 0, "S | System functions", 0, "N | Network functions", 0
db "I | INI files", 0, "O | Open dialog", 0
db "W | KolibriOS Wiki", 0, "F | FASM manual", 0
end if
; ====================================================================
; the documents with their hotkeys
embedded:
embed_doc "Copying.txt" ; L
embed_doc "Hot_Keys.txt" ; H
embed_doc "KFAR_Keys.txt" ; K
embed_doc "Credits.txt" ; C
embed_doc "Mtdbg.txt" ; D
if lang eq ru_RU
embed_file "SysFuncr.txt" ; S
else
embed_file "../../../kernel/trunk/docs/sysfuncs.txt" ; S
end if
embed_file "../../../kernel/trunk/docs/stack.txt" ; N
embed_doc "INI.txt" ; I
embed_doc "OpenDial.txt" ; O
dd 0
FILECOUNT = FILE_COUNT
if ~ FILECOUNT>0
error 'No embedded files'
end if
; ====================================================================
my_param db 0
rb 256
I_END:
title db 'Doc Pack',0
sc system_colors
sc system_colors
-17
View File
@@ -1,17 +0,0 @@
#!gmake
# Macro
FASM=/opt/bin/fasm
KPACK=/opt/bin/kpack
LANG=lang.inc
FILE=docpack
SOURCE=${FILE}.asm
OUT=${FILE}.bin
ru:
echo "lang fix ru_RU" > ${LANG}
${FASM} ${SOURCE} ${OUT}
${KPACK} ${OUT}
clean:
rm -f ${LANG} ${OUT}