Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9ee27c5595 | ||
|
|
dc7d6dd842 | ||
|
|
a8ade5e0c2 |
No files matched your search
@@ -1,54 +0,0 @@
|
||||
# =============================================================================
|
||||
# Apps
|
||||
# User-facing applications, games, multimedia, UI and desktop resources
|
||||
# =============================================================================
|
||||
|
||||
^programs/(cmm|demos|emulator|games|media|other)/.* @KolibriOS/apps
|
||||
^contrib/(games|media|other)/.* @KolibriOS/apps
|
||||
^skins/.* @KolibriOS/apps
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# System
|
||||
# Kernel, drivers, filesystems, SDK, libraries, toolchain and system utilities
|
||||
# =============================================================================
|
||||
|
||||
^kernel/.* @KolibriOS/system
|
||||
^drivers/.* @KolibriOS/system
|
||||
|
||||
^programs/(bcc32|develop|fs|hd_load|system|testing)/.* @KolibriOS/system
|
||||
^contrib/(C_Layer|sdk|toolchain)/.* @KolibriOS/system
|
||||
|
||||
# Shared system/API includes in programs/
|
||||
^programs/[^/]+\\.inc$ @KolibriOS/system
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Network
|
||||
# Network stack, network drivers, protocols, libraries and network applications
|
||||
# =============================================================================
|
||||
|
||||
^kernel/trunk/network/.* @KolibriOS/network
|
||||
|
||||
^drivers/ethernet/.* @KolibriOS/network
|
||||
^drivers/(mii|netdrv)\\.inc$ @KolibriOS/network
|
||||
|
||||
^programs/network/.* @KolibriOS/network
|
||||
^programs/network\\.inc$ @KolibriOS/network
|
||||
|
||||
^programs/develop/libraries/(http|network|kos_mbedtls)/.* @KolibriOS/network
|
||||
|
||||
^contrib/network/.* @KolibriOS/network
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# DevOps
|
||||
# CI/CD, repository infrastructure, build system and autobuild configuration
|
||||
# =============================================================================
|
||||
|
||||
^\\.gitea/.* @KolibriOS/devops
|
||||
^_tools/.* @KolibriOS/devops
|
||||
|
||||
^\\.gitmodules$ @KolibriOS/devops
|
||||
^build\\.txt$ @KolibriOS/devops
|
||||
^tup\\.config\\.template$ @KolibriOS/devops
|
||||
@@ -19,38 +19,3 @@
|
||||
owner: "{{ storage_user }}"
|
||||
group: "{{ storage_user }}"
|
||||
mode: preserve
|
||||
|
||||
# per-program binaries browsable at <version>/<lang>/data/, like on the old builds server
|
||||
- name: Creating build tree folders
|
||||
ansible.builtin.file:
|
||||
path: "{{ storage_path }}/{{ version }}/{{ item | basename | regex_replace('\\.tar\\.gz$', '') }}/data"
|
||||
state: directory
|
||||
owner: "{{ storage_user }}"
|
||||
group: "{{ storage_user }}"
|
||||
mode: '0755'
|
||||
with_fileglob: "{{ tree_artifact_path }}/*.tar.gz"
|
||||
|
||||
- name: Unpacking build trees
|
||||
ansible.builtin.unarchive:
|
||||
src: "{{ item }}"
|
||||
dest: "{{ storage_path }}/{{ version }}/{{ item | basename | regex_replace('\\.tar\\.gz$', '') }}/data"
|
||||
owner: "{{ storage_user }}"
|
||||
group: "{{ storage_user }}"
|
||||
with_fileglob: "{{ tree_artifact_path }}/*.tar.gz"
|
||||
|
||||
# stable URL for the newest build: <storage_path>/latest/<lang>/...
|
||||
- name: Updating latest symlink
|
||||
ansible.builtin.file:
|
||||
src: "{{ version }}"
|
||||
dest: "{{ storage_path }}/latest"
|
||||
state: link
|
||||
force: true
|
||||
owner: "{{ storage_user }}"
|
||||
group: "{{ storage_user }}"
|
||||
|
||||
# emulators hardcode <site root>/<lang>/data/data/kolibri.img; storage_path is the ci folder, one level under the site root
|
||||
- name: Sending bare images to stable emulator paths
|
||||
ansible.builtin.copy:
|
||||
src: "{{ stable_artifact_path }}/"
|
||||
dest: "{{ storage_path }}/../"
|
||||
mode: preserve
|
||||
+22
-83
@@ -162,13 +162,12 @@ jobs:
|
||||
tup init
|
||||
tup variant ${{ matrix.lang }}.config
|
||||
|
||||
# build the image for language variant; keep the tup log for publishing
|
||||
# build the image for language variant
|
||||
- name: Build KolibriOS
|
||||
run: |
|
||||
set -o pipefail
|
||||
export PATH=/home/autobuild/tools/win32/bin:$PATH
|
||||
source kos32-export-env-vars ${{ gitea.workspace }}
|
||||
tup build-${{ matrix.lang }} 2>&1 | tee build.log
|
||||
tup build-${{ matrix.lang }}
|
||||
|
||||
# stamp the cache with its commit so later builds diff against it
|
||||
- name: Record cache base commit
|
||||
@@ -182,26 +181,15 @@ jobs:
|
||||
id: vars
|
||||
run: echo "descr=$(git describe --tags)" >> $GITEA_OUTPUT
|
||||
|
||||
# stage build outputs under their final names, plus distribution kit and checksums
|
||||
- name: Prepare artifacts
|
||||
# rename build outputs to their final names so artifacts are bare files
|
||||
- name: Rename images
|
||||
run: |
|
||||
set -e
|
||||
BASE="kolibrios-${{ steps.vars.outputs.descr }}-${{ matrix.lang }}"
|
||||
for ext in img iso raw; do
|
||||
cp "build-${{ matrix.lang }}/data/kolibri.$ext" "$BASE.$ext"
|
||||
cp "build-${{ matrix.lang }}/data/kolibri.$ext" \
|
||||
"kolibrios-${{ steps.vars.outputs.descr }}-${{ matrix.lang }}.$ext"
|
||||
done
|
||||
# zip: distr targets Windows/DOS users, Explorer opens it natively
|
||||
(cd "build-${{ matrix.lang }}/data" && zip -r -9 -q "${{ gitea.workspace }}/$BASE.distr.zip" distribution_kit)
|
||||
# whole build tree for per-program downloads; the big images ship separately
|
||||
tar -C "build-${{ matrix.lang }}" \
|
||||
--exclude './data/kolibri.iso' \
|
||||
--exclude './data/kolibri.raw' \
|
||||
--exclude './data/distribution_kit' \
|
||||
-czf "$BASE.tree.tar.gz" .
|
||||
sha256sum "$BASE".img "$BASE".iso "$BASE".raw "$BASE".distr.zip > "$BASE.sha256sums.txt"
|
||||
mv build.log "$BASE.build.log"
|
||||
|
||||
# publish the images; longer retention for the floppy image
|
||||
#publish the three images; longer retention for the floppy image.
|
||||
- name: Upload floppy image
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
@@ -223,34 +211,6 @@ jobs:
|
||||
path: kolibrios-${{ steps.vars.outputs.descr }}-${{ matrix.lang }}.raw
|
||||
retention-days: 15
|
||||
|
||||
- name: Upload distribution kit
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: kolibrios-${{ steps.vars.outputs.descr }}-${{ matrix.lang }}.distr.zip
|
||||
path: kolibrios-${{ steps.vars.outputs.descr }}-${{ matrix.lang }}.distr.zip
|
||||
retention-days: 30
|
||||
|
||||
- name: Upload checksums
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: kolibrios-${{ steps.vars.outputs.descr }}-${{ matrix.lang }}.sha256sums.txt
|
||||
path: kolibrios-${{ steps.vars.outputs.descr }}-${{ matrix.lang }}.sha256sums.txt
|
||||
retention-days: 90
|
||||
|
||||
- name: Upload build log
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: kolibrios-${{ steps.vars.outputs.descr }}-${{ matrix.lang }}.build.log
|
||||
path: kolibrios-${{ steps.vars.outputs.descr }}-${{ matrix.lang }}.build.log
|
||||
retention-days: 90
|
||||
|
||||
- name: Upload build tree
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: kolibrios-${{ steps.vars.outputs.descr }}-${{ matrix.lang }}.tree.tar.gz
|
||||
path: kolibrios-${{ steps.vars.outputs.descr }}-${{ matrix.lang }}.tree.tar.gz
|
||||
retention-days: 15
|
||||
|
||||
deploy:
|
||||
name: "Publish Images"
|
||||
runs-on: ubuntu-latest
|
||||
@@ -275,50 +235,31 @@ jobs:
|
||||
run: |
|
||||
set -eu
|
||||
|
||||
rm -rf ./norm-artifacts ./stable-artifacts ./tree-artifacts
|
||||
mkdir -p ./norm-artifacts ./stable-artifacts ./tree-artifacts
|
||||
rm -rf ./norm-artifacts
|
||||
mkdir -p ./norm-artifacts
|
||||
|
||||
find ./artifacts -type f -name 'kolibrios-*' | while read -r file; do
|
||||
fname="$(basename "$file")" # kolibrios-<descr>-<lang>.<suffix>
|
||||
case "$fname" in
|
||||
*.tree.tar.gz) stem="${fname%.tree.tar.gz}";;
|
||||
*.distr.zip) stem="${fname%.distr.zip}";;
|
||||
*.sha256sums.txt) stem="${fname%.sha256sums.txt}";;
|
||||
*.build.log) stem="${fname%.build.log}";;
|
||||
*.img) stem="${fname%.img}";;
|
||||
*.iso) stem="${fname%.iso}";;
|
||||
*.raw) stem="${fname%.raw}";;
|
||||
*) continue;;
|
||||
esac
|
||||
lang="${stem##*-}" # <lang> has no dashes, <descr> may
|
||||
find ./artifacts -type f \( \
|
||||
-name 'kolibrios-*.img' -o \
|
||||
-name 'kolibrios-*.iso' -o \
|
||||
-name 'kolibrios-*.raw' \
|
||||
\) | while read -r file; do
|
||||
fname="$(basename "$file")" # kolibrios-<descr>-<lang>.<ext>
|
||||
name_without_ext="${fname%.*}"
|
||||
lang="${name_without_ext##*-}"
|
||||
|
||||
mkdir -p "./norm-artifacts/$lang"
|
||||
case "$fname" in
|
||||
*.tree.tar.gz)
|
||||
# unpacked on the server into <version>/<lang>/data/ for per-program downloads
|
||||
cp "$file" "./tree-artifacts/$lang.tar.gz";;
|
||||
*.sha256sums.txt)
|
||||
cp "$file" "./norm-artifacts/$lang/sha256sums.txt";;
|
||||
*.build.log)
|
||||
cp "$file" "./norm-artifacts/$lang/build.log";;
|
||||
*.img)
|
||||
cp "$file" "./norm-artifacts/$lang/$fname"
|
||||
# emulators (e.g. v86) hardcode <lang>/data/data/kolibri.img at the site root
|
||||
mkdir -p "./stable-artifacts/$lang/data/data"
|
||||
cp "$file" "./stable-artifacts/$lang/data/data/kolibri.img";;
|
||||
*)
|
||||
cp "$file" "./norm-artifacts/$lang/$fname";;
|
||||
esac
|
||||
cp "$file" "./norm-artifacts/$lang/$fname"
|
||||
done
|
||||
|
||||
# derive the version (git describe) from an artifact name: kolibrios-<descr>-<lang>.iso -> <descr>
|
||||
sample="$(find ./norm-artifacts -type f -name 'kolibrios-*.iso' | head -n1)"
|
||||
# derive the version (git describe) from an artifact name:
|
||||
# kolibrios-<descr>-<lang>.<ext> -> <descr>
|
||||
sample="$(find ./norm-artifacts -type f -name 'kolibrios-*' | head -n1)"
|
||||
base="$(basename "${sample%.*}")" # kolibrios-<descr>-<lang>
|
||||
version="${base%-*}" # kolibrios-<descr>
|
||||
version="${version#kolibrios-}" # <descr>
|
||||
echo "version=$version" >> $GITEA_OUTPUT
|
||||
|
||||
find ./norm-artifacts ./stable-artifacts ./tree-artifacts -type f -print
|
||||
find ./norm-artifacts -type f -print
|
||||
|
||||
- name: Setup SSH
|
||||
run: |
|
||||
@@ -344,6 +285,4 @@ jobs:
|
||||
-e "storage_path=${{ secrets.STORAGE_PATH }}" \
|
||||
-e "version=${{ steps.normalize.outputs.version }}" \
|
||||
-e "artifact_path=${{ gitea.workspace }}/norm-artifacts" \
|
||||
-e "stable_artifact_path=${{ gitea.workspace }}/stable-artifacts" \
|
||||
-e "tree_artifact_path=${{ gitea.workspace }}/tree-artifacts" \
|
||||
-v
|
||||
@@ -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 }}
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
branch = main
|
||||
[submodule "programs/develop/oberon07"]
|
||||
path = programs/develop/oberon07
|
||||
url = https://git.kolibrios.org/KolibriOS/oberon-07-compiler.git
|
||||
url = https://github.com/AntKrotov/oberon-07-compiler.git
|
||||
branch = master
|
||||
[submodule "programs/cmm"]
|
||||
path = programs/cmm
|
||||
|
||||
+1
-3
@@ -427,7 +427,7 @@ tup.append_table(img_files, {
|
||||
{"DOCPACK", VAR_PROGS .. "/system/docpack/docpack"},
|
||||
{"DEFAULT.SKN", VAR_SKINS .. "/../skins/Leency/Shkvorka/Shkvorka.skn"},
|
||||
{"DISPTEST", VAR_PROGS .. "/testing/disptest/disptest"},
|
||||
{"END", VAR_PROGS .. "/system/end/light/end"},
|
||||
{"END", VAR_PROGS .. "/system/end/end"},
|
||||
{"ESKIN", VAR_PROGS .. "/system/eskin/eskin"},
|
||||
{"GMON", VAR_PROGS .. "/system/gmon/gmon"},
|
||||
{"HDD_INFO", VAR_PROGS .. "/system/hdd_info/hdd_info"},
|
||||
@@ -573,7 +573,6 @@ tup.append_table(img_files, {
|
||||
{"DRIVERS/UHCI.SYS", VAR_DRVS .. "/usb/uhci.sys"},
|
||||
{"DRIVERS/OHCI.SYS", VAR_DRVS .. "/usb/ohci.sys"},
|
||||
{"DRIVERS/EHCI.SYS", VAR_DRVS .. "/usb/ehci.sys"},
|
||||
{"DRIVERS/XHCI.SYS", VAR_DRVS .. "/usb/xhci/xhci.sys"},
|
||||
{"DRIVERS/USBHID.SYS", VAR_DRVS .. "/usb/usbhid/usbhid.sys"},
|
||||
{"DRIVERS/USBFTDI.SYS", VAR_DRVS .. "/usb/usbftdi/usbftdi.sys"},
|
||||
{"DRIVERS/USBOTHER.SYS",VAR_DRVS .. "/usb/usbother/usbother.sys"},
|
||||
@@ -598,7 +597,6 @@ tup.append_table(img_files, {
|
||||
{"DRIVERS/VT823X.SYS", VAR_DRVS .. "/audio/vt823x.sys"},
|
||||
{"DRIVERS/SIS.SYS", VAR_DRVS .. "/audio/sis.sys"},
|
||||
{"DRIVERS/SDHCI.SYS", "../drivers/sdhci/sdhci.sys"},
|
||||
{"DRIVERS/I2CHID.SYS", VAR_DRVS .. "/i2chid/i2chid.sys"},
|
||||
})
|
||||
tup.append_table(extra_files, {
|
||||
{"HD_Load/9x2klbr/", VAR_PROGS .. "/hd_load/9x2klbr/9x2klbr.exe"},
|
||||
|
||||
Binary file not shown.
@@ -6,9 +6,8 @@
|
||||
#/SYS/CROPFLAT "XS800 YS480" 1 # set limits of screen
|
||||
#/SYS/LOADDRV COMMOUSE 1 # serial mouse driver
|
||||
#/SYS/DEVELOP/BOARD "" 0 # Load DEBUG board
|
||||
#/SYS/LOADDRV RDC 0 # videodriver for RDC M2010/M2012
|
||||
/SYS/SETUP BOOT 0 # Load device settings
|
||||
/SYS/LOADDRV I2CHID 0 # Start I2C touchpad driver
|
||||
/SYS/LOADDRV RDC 0 # videodriver for RDC M2010/M2012
|
||||
/SYS/@TASKBAR "" 0 # Start taskbar
|
||||
/SYS/ESKIN "" 0 # Set style
|
||||
/SYS/@ICON "" 0 # Multithread desktop icons
|
||||
|
||||
@@ -5,22 +5,6 @@ font smoothing=sbp
|
||||
font height=9
|
||||
speaker mute=off
|
||||
|
||||
[touchpad]
|
||||
speed=100
|
||||
; how far a finger must move before the pointer follows, in pad units;
|
||||
; larger is steadier under a pressing finger, 0 turns the filter off
|
||||
jitter=1
|
||||
; the same, for a finger that landed on the button strip: it is pressing
|
||||
; rather than steering there, so it needs a stricter margin
|
||||
jitter_buttons=45
|
||||
scroll_step=64
|
||||
scroll_invert=0
|
||||
tap_enable=1
|
||||
tap_drag=1
|
||||
right_click=1
|
||||
button_zone=15
|
||||
right_split=50
|
||||
|
||||
[mouse]
|
||||
speed=4
|
||||
acceleration=3
|
||||
|
||||
@@ -273,8 +273,8 @@ RIRB_INT_RESPONSE equ 0x01
|
||||
RIRB_INT_OVERRUN equ 0x04
|
||||
RIRB_INT_MASK equ 0x05
|
||||
|
||||
; STATESTS int mask: SDIWAKE[14:0], a 16-bit register
|
||||
STATESTS_INT_MASK equ 0x7FFF
|
||||
; STATESTS int mask: SD2,SD1,SD0
|
||||
STATESTS_INT_MASK equ 0x07
|
||||
AZX_MAX_CODECS equ 4
|
||||
|
||||
; SD_CTL bits
|
||||
@@ -402,7 +402,6 @@ struc AC_CNTRL ;AC controller base class
|
||||
.response_reset dd 0
|
||||
.polling_mode db 0
|
||||
.poll_count db 0
|
||||
.no_irq db 0 ; no interrupt line: a thread runs hda_irq
|
||||
.posbuf dd ?
|
||||
.start_wallclk dd ? ; start + minimum wallclk
|
||||
.period_wallclk dd ? ; wallclk for period
|
||||
@@ -506,6 +505,8 @@ macro spin_unlock
|
||||
pop ebx eax
|
||||
}
|
||||
|
||||
data fixups
|
||||
end data
|
||||
|
||||
include '../../struct.inc'
|
||||
include '../../macros.inc'
|
||||
@@ -606,6 +607,9 @@ if IRQ_REMAP
|
||||
invoke SysMsgBoardStr
|
||||
end if
|
||||
|
||||
mov ebx, [ctrl.int_line]
|
||||
invoke AttachIntHandler, ebx, hda_irq, dword 0
|
||||
|
||||
;Asper This part is from "azx_probe" proc. [
|
||||
call azx_codec_create
|
||||
cmp eax, 0
|
||||
@@ -854,13 +858,13 @@ end if
|
||||
|
||||
mov edx, ICH6_REG_SD_STS + SDO_OFS
|
||||
call azx_readb
|
||||
mov cl, al
|
||||
mov bl, al
|
||||
|
||||
mov al, SD_INT_MASK
|
||||
mov edx, ICH6_REG_SD_STS + SDO_OFS
|
||||
call azx_writeb
|
||||
|
||||
test cl, SD_INT_COMPLETE
|
||||
test bl, SD_INT_COMPLETE
|
||||
jz @f
|
||||
|
||||
mov eax, [ctrl.civ_val]
|
||||
@@ -897,13 +901,13 @@ end if
|
||||
;if 0
|
||||
; clear state status int
|
||||
mov edx, ICH6_REG_STATESTS
|
||||
call azx_readw
|
||||
and eax, STATESTS_INT_MASK
|
||||
call azx_readb
|
||||
test al, 0x04
|
||||
jz @f
|
||||
|
||||
; ack all state-change bits, else the level IRQ line stays asserted
|
||||
mov al, 0x04
|
||||
mov edx, ICH6_REG_STATESTS
|
||||
call azx_writew
|
||||
call azx_writeb
|
||||
@@:
|
||||
;end if
|
||||
or eax, 1
|
||||
@@ -911,24 +915,6 @@ end if
|
||||
ret
|
||||
endp
|
||||
|
||||
; Stand-in for the interrupt when no interrupt line is available. A thread,
|
||||
; not a TimerHS callback: the kernel calls timer callbacks with the global
|
||||
; timer list lock held, and hda_irq may stall and refill the audio buffer.
|
||||
; hda_irq runs with interrupts off, as it would in IRQ context: it holds
|
||||
; aspinlock, which azx_rirb_get_response waits for with interrupts off, so
|
||||
; a holder that could be preempted would hang the machine.
|
||||
proc hda_poll_thread
|
||||
.loop:
|
||||
pushfd
|
||||
cli
|
||||
call hda_irq
|
||||
popfd
|
||||
mov eax, 5 ; delay, sleeping instead of spinning
|
||||
mov ebx, 1 ; 10 ms; a 16 KB period is ~85 ms at 48 kHz
|
||||
int 0x40
|
||||
jmp .loop
|
||||
endp
|
||||
|
||||
|
||||
align 4
|
||||
proc create_primary_buff
|
||||
@@ -1217,26 +1203,6 @@ end if
|
||||
; allocate CORB/RIRB
|
||||
call azx_alloc_cmd_io
|
||||
|
||||
; attach the IRQ handler BEFORE the controller may raise interrupts:
|
||||
; azx_init_chip enables GIE/CIE and a codec state-change can fire
|
||||
; right away; an unclaimed level IRQ makes the
|
||||
; kernel poll foreign handlers and relink their IRQH nodes onto our
|
||||
; line (see irq_serv .try_other_irqs), corrupting the dispatch list
|
||||
; a warm reboot can leave GIE and a stale completion bit behind, and
|
||||
; civ_val is never resynced, so silence the controller before attaching
|
||||
call azx_int_disable
|
||||
mov ebx, [ctrl.int_line]
|
||||
invoke AttachIntHandler, ebx, hda_irq, dword 0
|
||||
test eax, eax
|
||||
jnz @f
|
||||
; No usable interrupt line (INTLINE=0xFF on boards that route INTx only
|
||||
; through ACPI _PRT or MSI, which the kernel does not parse). The
|
||||
; controller still latches INTSTS/SD_STS, we only lose the wakeup - so
|
||||
; poll the RIRB for codec replies and run the interrupt handler from a
|
||||
; thread. A flag of its own: polling_mode is the timeout recovery state.
|
||||
mov [ctrl.no_irq], 1
|
||||
@@:
|
||||
|
||||
; initialize chip
|
||||
call azx_init_pci
|
||||
|
||||
@@ -1244,32 +1210,6 @@ end if
|
||||
call azx_init_chip
|
||||
;] Asper
|
||||
|
||||
; no IRQ line: let a polling thread stand in for the interrupt.
|
||||
; Started only now - earlier, hda_irq could ack STATESTS in the window
|
||||
; before reset_controller reads it into codec_mask
|
||||
cmp [ctrl.no_irq], 0
|
||||
je @f
|
||||
push esi edi ; CreateThread clobbers them, START needs esi
|
||||
mov ebx, 1
|
||||
mov ecx, hda_poll_thread
|
||||
xor edx, edx
|
||||
invoke CreateThread
|
||||
pop edi esi
|
||||
test eax, eax
|
||||
jns .thread_ok
|
||||
; nothing would ever complete a period and playback would stall,
|
||||
; so fail the init rather than register a service that hangs
|
||||
mov esi, msgNoIrqThread
|
||||
invoke SysMsgBoardStr
|
||||
xor eax, eax
|
||||
ret
|
||||
.thread_ok:
|
||||
if DEBUG
|
||||
mov esi, msgNoIrqPoll
|
||||
invoke SysMsgBoardStr
|
||||
end if
|
||||
@@:
|
||||
|
||||
xor eax, eax
|
||||
inc eax
|
||||
ret
|
||||
@@ -1303,7 +1243,7 @@ endl
|
||||
; clear STATESTS
|
||||
mov eax, STATESTS_INT_MASK
|
||||
mov edx, ICH6_REG_STATESTS
|
||||
call azx_writew
|
||||
call azx_writeb
|
||||
|
||||
; reset controller
|
||||
mov edx, ICH6_REG_GCTL
|
||||
@@ -1514,12 +1454,6 @@ endp
|
||||
|
||||
proc azx_alloc_cmd_io
|
||||
push eax ecx edx
|
||||
; the unsolicited-event ring lives in reserved storage, so its
|
||||
; pointers hold garbage until we clear them here - do it before
|
||||
; reset_controller enables unsolicited responses in GCTL
|
||||
mov [unsol_events.rp], 0
|
||||
mov [unsol_events.wp], 0
|
||||
|
||||
; single page (at least 4096 bytes) must suffice for both ringbuffers
|
||||
invoke KernelAlloc, 4096
|
||||
mov [ctrl.rb], eax
|
||||
@@ -1720,24 +1654,14 @@ endl
|
||||
mov ecx, 1000;+1000
|
||||
.next_try:
|
||||
mov al, [ctrl.polling_mode]
|
||||
or al, [ctrl.no_irq]
|
||||
test al, al
|
||||
jnz .poll
|
||||
mov ah, [do_poll]
|
||||
test ah, ah
|
||||
jz @f
|
||||
.poll:
|
||||
spin_lock_irq
|
||||
; take the lock hda_irq holds so two RIRB readers never overlap
|
||||
push eax ebx
|
||||
mov eax, aspinlock
|
||||
.poll_lock:
|
||||
mov ebx, SPINLOCK_BUSY
|
||||
lock xchg [eax], ebx
|
||||
cmp ebx, SPINLOCK_FREE
|
||||
jnz .poll_lock
|
||||
pop ebx eax
|
||||
call azx_update_rirb
|
||||
mov [aspinlock], SPINLOCK_FREE
|
||||
spin_unlock_irq
|
||||
@@:
|
||||
mov eax, [ctrl.rirb_cmd]
|
||||
@@ -2018,7 +1942,6 @@ proc azx_int_disable
|
||||
mov ebx, ICH6_INT_CTRL_EN or ICH6_INT_GLOBAL_EN
|
||||
xor ebx, -1
|
||||
and eax, ebx
|
||||
mov edx, ICH6_REG_INTCTL ; azx_readl turned edx into the absolute address
|
||||
call azx_writel
|
||||
pop edx ebx eax
|
||||
ret
|
||||
@@ -2034,9 +1957,9 @@ proc azx_int_clear
|
||||
call azx_writeb
|
||||
|
||||
; clear STATESTS
|
||||
mov ax, STATESTS_INT_MASK
|
||||
mov al, STATESTS_INT_MASK
|
||||
mov edx, ICH6_REG_STATESTS
|
||||
call azx_writew
|
||||
call azx_writeb
|
||||
|
||||
; clear rirb status
|
||||
mov al, RIRB_INT_MASK
|
||||
@@ -2773,7 +2696,6 @@ proc snd_hda_queue_unsol_event stdcall, res:dword, res_ex:dword
|
||||
; only carries EBX across iterations and reloads the rest, and TimerHS
|
||||
; preserves EBX too - so by using scratch regs only we need no saves.
|
||||
mov eax, [unsol_events.wp]
|
||||
and eax, HDA_UNSOL_QUEUE_SIZE - 1 ; never index the ring wild
|
||||
lea edx, [eax+1]
|
||||
and edx, HDA_UNSOL_QUEUE_SIZE - 1 ; next write pos (size must be 2^n)
|
||||
cmp edx, [unsol_events.rp]
|
||||
@@ -3076,7 +2998,6 @@ sz_sound_srv db 'SOUND',0
|
||||
|
||||
msgInit db 'detect hardware...',13,10,0
|
||||
msgFail db 'device not found',13,10,0
|
||||
msgNoIrqThread db 'no IRQ line: cannot create polling thread',13,10,0
|
||||
msgAttchIRQ db 'IRQ line not supported', 13,10,0
|
||||
msgInvIRQ db 'IRQ line not assigned or invalid', 13,10,0
|
||||
msgPlay db 'start play', 13,10,0
|
||||
@@ -3146,7 +3067,6 @@ if DEBUG
|
||||
msgTCSEL db 'PCI TCSEL ',0
|
||||
msgTV db 'HDA test version ',TEST_VERSION_NUMBER,13,10,0
|
||||
msgGCap db 'GCAP = ',0
|
||||
msgNoIrqPoll db 'no IRQ line: polling thread',13,10,0
|
||||
end if
|
||||
|
||||
if USE_SINGLE_MODE
|
||||
@@ -3181,11 +3101,6 @@ end if
|
||||
|
||||
;] Asper
|
||||
|
||||
; relocation table lives after all code and initialized data: placed before the
|
||||
; code its size feeds back into every relocation site and fasm may never converge
|
||||
data fixups
|
||||
end data
|
||||
|
||||
aspinlock dd SPINLOCK_FREE
|
||||
|
||||
codec CODEC
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
if tup.getconfig("NO_FASM") ~= "" then return end
|
||||
ROOT = "../.."
|
||||
tup.rule("i2chid.asm", "fasm %f %o " .. tup.getconfig("PESTRIP_CMD") .. tup.getconfig("KPACK_CMD"), "%B.sys")
|
||||
@@ -1,438 +0,0 @@
|
||||
; Synopsys DesignWare I2C master, polled (PIO) mode only.
|
||||
; This is the controller inside Intel LPSS blocks (Skylake and newer, plus
|
||||
; Atom-derived SoCs); the same IP is used by many other vendors.
|
||||
;
|
||||
; The register file is always accessed as dwords. The controller must be
|
||||
; disabled to change IC_TAR, so every transfer disables it, programs the
|
||||
; target address, enables it back and feeds the TX FIFO by hand.
|
||||
|
||||
; ------------------------------ Registers ------------------------------------
|
||||
DwIcCon = 0x00
|
||||
DwIcTar = 0x04
|
||||
DwIcDataCmd = 0x10
|
||||
DwIcSsSclHcnt = 0x14
|
||||
DwIcSsSclLcnt = 0x18
|
||||
DwIcFsSclHcnt = 0x1C
|
||||
DwIcFsSclLcnt = 0x20
|
||||
DwIcIntrStat = 0x2C
|
||||
DwIcIntrMask = 0x30
|
||||
DwIcRawIntrStat = 0x34
|
||||
DwIcRxTl = 0x38
|
||||
DwIcTxTl = 0x3C
|
||||
DwIcClrIntr = 0x40
|
||||
DwIcClrTxAbrt = 0x54
|
||||
DwIcEnable = 0x6C
|
||||
DwIcStatus = 0x70
|
||||
DwIcTxflr = 0x74
|
||||
DwIcRxflr = 0x78
|
||||
DwIcSdaHold = 0x7C
|
||||
DwIcTxAbrtSource = 0x80
|
||||
DwIcEnableStatus = 0x9C
|
||||
DwIcCompParam1 = 0xF4
|
||||
DwIcCompVersion = 0xF8
|
||||
DwIcCompType = 0xFC
|
||||
|
||||
; "DW_apb_i2c" component signature ('DW' + 0x0140).
|
||||
DW_COMP_TYPE_VALUE = 0x44570140
|
||||
|
||||
; IC_CON: master, standard speed (100 kHz), restarts allowed, slave disabled.
|
||||
DW_CON_MASTER = 1 shl 0
|
||||
DW_CON_SPEED_STD = 1 shl 1
|
||||
DW_CON_SPEED_FAST = 2 shl 1
|
||||
DW_CON_RESTART_EN = 1 shl 5
|
||||
DW_CON_SLAVE_DIS = 1 shl 6
|
||||
|
||||
; IC_DATA_CMD bits above the data byte.
|
||||
DW_CMD_READ = 1 shl 8
|
||||
DW_CMD_STOP = 1 shl 9
|
||||
DW_CMD_RESTART = 1 shl 10
|
||||
|
||||
; IC_STATUS bits
|
||||
DW_STAT_TFNF = 1 shl 1 ; TX FIFO not full
|
||||
DW_STAT_TFE = 1 shl 2 ; TX FIFO empty
|
||||
DW_STAT_RFNE = 1 shl 3 ; RX FIFO not empty
|
||||
DW_STAT_MST_ACT = 1 shl 5 ; master FSM busy
|
||||
|
||||
; IC_RAW_INTR_STAT bits
|
||||
DW_INT_TX_ABRT = 1 shl 6
|
||||
|
||||
; SCL timing for standard mode. The LPSS input clock is 100 MHz on the PCH
|
||||
; parts and 133 MHz on the Atom-derived SoCs (Apollo Lake, Gemini Lake), and
|
||||
; nothing in PCI config space says which one this is, so the counts are
|
||||
; picked to satisfy the fast-mode minimums at the fastest of them: at
|
||||
; 133 MHz that is tHIGH = 0.98 us and tLOW = 1.5 us, 400 kHz. On a 100 MHz
|
||||
; part the same counts run the bus at 300 kHz, which is just as legal.
|
||||
; Fast mode rather than standard: HID over I2C requires every device to
|
||||
; support it, that is what Windows drives them at, and a polled host pays
|
||||
; for every byte with busy-waiting - at 100 kHz a 64-byte input read costs
|
||||
; 6 ms, more than a fast pad takes to produce the next report, and the
|
||||
; backlog that builds up plays back as the cursor coasting after the finger
|
||||
; has stopped. SDA hold stays well below tLOW.
|
||||
DW_FS_HCNT = 130
|
||||
DW_FS_LCNT = 200
|
||||
DW_SDA_HOLD = 28
|
||||
; The AMD FCH feeds its DesignWare masters from a 150 MHz reference, so
|
||||
; the same minimums need more counts there: 145/225 give tHIGH = 0.97 us,
|
||||
; tLOW = 1.5 us, again 400 kHz; SDA hold 45 = 300 ns.
|
||||
DW_AMD_FS_HCNT = 145
|
||||
DW_AMD_FS_LCNT = 225
|
||||
DW_AMD_SDA_HOLD = 45
|
||||
|
||||
; A transfer gives up after [XferTimeout] hundredths of a second. The init
|
||||
; value must cover a full report descriptor read: descriptors run up to 2 KB
|
||||
; and the bus may be as slow as 77 kHz, so at 9 SCL cycles per byte a single
|
||||
; transfer takes ~240 ms of wall-clock time. Polling is generous too now that it runs in its own thread
|
||||
; rather than in a timer callback - a wedged bus costs this thread its slice
|
||||
; and nothing else.
|
||||
DW_TIMEOUT_INIT = 60
|
||||
DW_TIMEOUT_POLL = 20
|
||||
|
||||
; Disables the controller and waits until it reports itself disabled.
|
||||
; in: ebx = MMIO base. Clobbers eax, ecx.
|
||||
proc dw_ctrl_disable
|
||||
mov dword [ebx+DwIcEnable], 0
|
||||
mov ecx, 100000
|
||||
@@:
|
||||
test dword [ebx+DwIcEnableStatus], 1
|
||||
jz .done
|
||||
pause
|
||||
loop @b
|
||||
.done:
|
||||
ret
|
||||
endp
|
||||
|
||||
; Aborts a stuck transfer cleanly: the ABORT bit makes the master issue STOP,
|
||||
; flush the TX FIFO and raise TX_ABRT, which releases a slave that is holding
|
||||
; the bus (a clock-stretching touchpad, for instance). Simply disabling the
|
||||
; controller in the middle of a byte would leave SDA held low and every
|
||||
; following transfer would time out too. Older cores without the ABORT bit
|
||||
; just ignore the write and fall through after the wait.
|
||||
; in: ebx = MMIO base. Clobbers eax, ecx.
|
||||
proc dw_ctrl_abort
|
||||
mov dword [ebx+DwIcEnable], 3
|
||||
mov ecx, 100000
|
||||
@@:
|
||||
test dword [ebx+DwIcRawIntrStat], DW_INT_TX_ABRT
|
||||
jnz @f
|
||||
pause
|
||||
loop @b
|
||||
@@:
|
||||
mov eax, [ebx+DwIcClrTxAbrt]
|
||||
call dw_ctrl_disable
|
||||
ret
|
||||
endp
|
||||
|
||||
; One idle step of a transfer wait loop.
|
||||
; A healthy transfer is over within a few milliseconds, well inside the
|
||||
; first two timer ticks, and spins through them: a transfer that yields
|
||||
; its slice is at the scheduler's mercy for the rest of it. Past that the
|
||||
; bus is stuck or crawling, and the wait gives up the CPU a tick at a time
|
||||
; instead of burning a core until XferTimeout.
|
||||
; in: eax = ticks elapsed since the transfer began. Preserves all but eax.
|
||||
DW_SPIN_TICKS = 2
|
||||
|
||||
proc dw_wait_step
|
||||
cmp eax, DW_SPIN_TICKS
|
||||
jae .yield
|
||||
pause
|
||||
ret
|
||||
.yield:
|
||||
push ebx
|
||||
movi ebx, 1
|
||||
invoke Delay ; preserves every register
|
||||
pop ebx
|
||||
ret
|
||||
endp
|
||||
|
||||
; One-time controller setup after mapping.
|
||||
; in: ebx = MMIO base.
|
||||
proc dw_ctrl_init
|
||||
push eax ecx
|
||||
call dw_ctrl_disable
|
||||
mov dword [ebx+DwIcCon], DW_CON_MASTER + DW_CON_SPEED_FAST + \
|
||||
DW_CON_RESTART_EN + DW_CON_SLAVE_DIS
|
||||
; The counts come from variables: they depend on the reference clock, which
|
||||
; is decided by whoever found the controller (PCI LPSS or AMD FCH). The
|
||||
; standard-mode registers get the same values scaled up so that they are
|
||||
; sane should anything ever switch the speed bits back.
|
||||
mov eax, [DwHcnt]
|
||||
mov [ebx+DwIcFsSclHcnt], eax
|
||||
lea eax, [eax*4]
|
||||
mov [ebx+DwIcSsSclHcnt], eax
|
||||
mov eax, [DwLcnt]
|
||||
mov [ebx+DwIcFsSclLcnt], eax
|
||||
lea eax, [eax*4]
|
||||
mov [ebx+DwIcSsSclLcnt], eax
|
||||
mov eax, [DwSdaHold]
|
||||
mov [ebx+DwIcSdaHold], eax
|
||||
mov dword [ebx+DwIcIntrMask], 0
|
||||
mov dword [ebx+DwIcRxTl], 0
|
||||
mov dword [ebx+DwIcTxTl], 0
|
||||
mov eax, [ebx+DwIcClrIntr]
|
||||
pop ecx eax
|
||||
ret
|
||||
endp
|
||||
|
||||
; One combined I2C transaction: optional write phase, then optional read phase
|
||||
; with a repeated START between them. Fully polled.
|
||||
; out: eax = 0 on success, IC_TX_ABRT_SOURCE value on NAK/abort, -1 on timeout.
|
||||
proc dw_xfer stdcall uses ebx esi edi, addr:dword, wbuf:dword, wlen:dword, \
|
||||
rbuf:dword, rlen:dword
|
||||
locals
|
||||
wsent dd ?
|
||||
rqueued dd ?
|
||||
rgot dd ?
|
||||
t0 dd ?
|
||||
endl
|
||||
mov ebx, [I2cMmio]
|
||||
call dw_ctrl_disable
|
||||
mov eax, [addr]
|
||||
mov [ebx+DwIcTar], eax
|
||||
mov eax, [ebx+DwIcClrIntr]
|
||||
mov dword [ebx+DwIcEnable], 1
|
||||
xor eax, eax
|
||||
mov [wsent], eax
|
||||
mov [rqueued], eax
|
||||
mov [rgot], eax
|
||||
invoke GetTimerTicks
|
||||
mov [t0], eax
|
||||
.loop:
|
||||
; Abort (NAK and friends) ends the transfer immediately.
|
||||
test dword [ebx+DwIcRawIntrStat], DW_INT_TX_ABRT
|
||||
jnz .abort
|
||||
; Drain the RX FIFO first so it can never overflow.
|
||||
test dword [ebx+DwIcStatus], DW_STAT_RFNE
|
||||
jz .no_rx
|
||||
mov edx, [rgot]
|
||||
cmp edx, [rlen]
|
||||
jae .no_rx
|
||||
mov eax, [ebx+DwIcDataCmd]
|
||||
mov edi, [rbuf]
|
||||
mov [edi+edx], al
|
||||
inc edx
|
||||
mov [rgot], edx
|
||||
jmp .loop
|
||||
.no_rx:
|
||||
; Feed the write phase.
|
||||
mov eax, [wsent]
|
||||
cmp eax, [wlen]
|
||||
jae .push_reads
|
||||
test dword [ebx+DwIcStatus], DW_STAT_TFNF
|
||||
jz .check_done
|
||||
mov esi, [wbuf]
|
||||
movzx edx, byte [esi+eax]
|
||||
inc eax
|
||||
cmp eax, [wlen]
|
||||
jne @f
|
||||
cmp [rlen], 0
|
||||
jne @f
|
||||
or edx, DW_CMD_STOP ; last byte of a write-only transfer
|
||||
@@:
|
||||
mov [ebx+DwIcDataCmd], edx
|
||||
mov [wsent], eax
|
||||
jmp .loop
|
||||
.push_reads:
|
||||
; Feed read commands, at most 8 outstanding so the RX FIFO keeps up.
|
||||
mov eax, [rqueued]
|
||||
cmp eax, [rlen]
|
||||
jae .check_done
|
||||
mov edx, eax
|
||||
sub edx, [rgot]
|
||||
cmp edx, 8
|
||||
jae .check_done
|
||||
test dword [ebx+DwIcStatus], DW_STAT_TFNF
|
||||
jz .check_done
|
||||
mov edx, DW_CMD_READ
|
||||
test eax, eax
|
||||
jnz @f
|
||||
cmp [wlen], 0
|
||||
je @f
|
||||
or edx, DW_CMD_RESTART ; repeated START after the write phase
|
||||
@@:
|
||||
mov ecx, [rlen]
|
||||
dec ecx
|
||||
cmp eax, ecx
|
||||
jne @f
|
||||
or edx, DW_CMD_STOP
|
||||
@@:
|
||||
mov [ebx+DwIcDataCmd], edx
|
||||
inc eax
|
||||
mov [rqueued], eax
|
||||
jmp .loop
|
||||
.check_done:
|
||||
mov eax, [rgot]
|
||||
cmp eax, [rlen]
|
||||
jne .not_done
|
||||
mov eax, [wsent]
|
||||
cmp eax, [wlen]
|
||||
jne .not_done
|
||||
mov eax, [ebx+DwIcStatus]
|
||||
test eax, DW_STAT_TFE
|
||||
jz .not_done
|
||||
test eax, DW_STAT_MST_ACT
|
||||
jnz .not_done
|
||||
call dw_ctrl_disable
|
||||
xor eax, eax
|
||||
ret
|
||||
.not_done:
|
||||
invoke GetTimerTicks
|
||||
sub eax, [t0]
|
||||
cmp eax, [XferTimeout]
|
||||
jae .timeout
|
||||
call dw_wait_step
|
||||
jmp .loop
|
||||
.abort:
|
||||
mov esi, [ebx+DwIcTxAbrtSource]
|
||||
mov eax, [ebx+DwIcClrTxAbrt]
|
||||
call dw_ctrl_disable
|
||||
mov eax, esi
|
||||
test eax, eax
|
||||
jnz @f
|
||||
or eax, 0x80000000
|
||||
@@:
|
||||
ret
|
||||
.timeout:
|
||||
call dw_ctrl_abort
|
||||
or eax, -1
|
||||
ret
|
||||
endp
|
||||
|
||||
; Reads one HID input report as a single continuous bus transaction, the way
|
||||
; interrupt-driven hosts (Windows, Linux) do it: the optional register-address
|
||||
; write and every read command are queued into the TX FIFO before the bytes
|
||||
; start flowing, so nothing on the wire depends on how fast the host loop
|
||||
; runs. The previous adaptive read (fetch 2 length bytes, decide, fetch the
|
||||
; rest, stop short) was cut down on the wire to 3 bytes for an empty poll -
|
||||
; and the SIPODEV/Hantick touchpad firmwares are exactly the kind of thing
|
||||
; that wedges when an input read is shorter than the frame they prepared.
|
||||
; rlen should not exceed the TX FIFO depth (IC_COMP_PARAM_1 bits 23:16, plus
|
||||
; one) or the queue loop degrades to feeding the FIFO on the fly, which
|
||||
; reintroduces pauses.
|
||||
; in: addr = slave, wlen bytes at wbuf written first (0 = plain read),
|
||||
; rlen bytes read into buf.
|
||||
; out: eax = 0 ok, IC_TX_ABRT_SOURCE on NAK/abort, -1 on timeout.
|
||||
; Timeout check for the dw_read_block wait spots; expands inside the proc so
|
||||
; [t0] and [XferTimeout] resolve in the caller's own frame.
|
||||
macro BLOCK_TICK fail_label {
|
||||
invoke GetTimerTicks
|
||||
sub eax, [t0]
|
||||
cmp eax, [XferTimeout]
|
||||
jae fail_label
|
||||
call dw_wait_step
|
||||
}
|
||||
|
||||
proc dw_read_block stdcall uses ebx esi edi, addr:dword, wbuf:dword, wlen:dword, buf:dword, rlen:dword
|
||||
locals
|
||||
rgot dd ?
|
||||
t0 dd ?
|
||||
endl
|
||||
mov ebx, [I2cMmio]
|
||||
call dw_ctrl_disable
|
||||
mov eax, [addr]
|
||||
mov [ebx+DwIcTar], eax
|
||||
mov eax, [ebx+DwIcClrIntr]
|
||||
mov dword [ebx+DwIcEnable], 1
|
||||
invoke GetTimerTicks
|
||||
mov [t0], eax
|
||||
mov [rgot], 0
|
||||
; Write phase: the register address bytes, no STOP - the read continues the
|
||||
; same transaction after a repeated START.
|
||||
xor ecx, ecx
|
||||
.wr:
|
||||
cmp ecx, [wlen]
|
||||
jae .queue_reads
|
||||
test dword [ebx+DwIcRawIntrStat], DW_INT_TX_ABRT
|
||||
jnz .abort
|
||||
test dword [ebx+DwIcStatus], DW_STAT_TFNF
|
||||
jz .wr_wait
|
||||
mov esi, [wbuf]
|
||||
movzx edx, byte [esi+ecx]
|
||||
mov [ebx+DwIcDataCmd], edx
|
||||
inc ecx
|
||||
jmp .wr
|
||||
.wr_wait:
|
||||
BLOCK_TICK .timeout
|
||||
jmp .wr
|
||||
.queue_reads:
|
||||
xor ecx, ecx
|
||||
.rq:
|
||||
cmp ecx, [rlen]
|
||||
jae .drain
|
||||
test dword [ebx+DwIcRawIntrStat], DW_INT_TX_ABRT
|
||||
jnz .abort
|
||||
test dword [ebx+DwIcStatus], DW_STAT_TFNF
|
||||
jz .rq_wait
|
||||
mov edx, DW_CMD_READ
|
||||
test ecx, ecx
|
||||
jnz .not_first
|
||||
cmp [wlen], 0
|
||||
je .not_first
|
||||
or edx, DW_CMD_RESTART
|
||||
.not_first:
|
||||
mov eax, [rlen]
|
||||
dec eax
|
||||
cmp ecx, eax
|
||||
jne @f
|
||||
or edx, DW_CMD_STOP
|
||||
@@:
|
||||
mov [ebx+DwIcDataCmd], edx
|
||||
inc ecx
|
||||
; Drain opportunistically so a FIFO shallower than rlen cannot deadlock the
|
||||
; queue loop (the RX side fills while the TX side is full).
|
||||
test dword [ebx+DwIcStatus], DW_STAT_RFNE
|
||||
jz .rq
|
||||
call .take_byte
|
||||
jmp .rq
|
||||
.rq_wait:
|
||||
BLOCK_TICK .timeout
|
||||
jmp .rq
|
||||
.drain:
|
||||
test dword [ebx+DwIcRawIntrStat], DW_INT_TX_ABRT
|
||||
jnz .abort
|
||||
test dword [ebx+DwIcStatus], DW_STAT_RFNE
|
||||
jz .chk
|
||||
call .take_byte
|
||||
jmp .drain
|
||||
; Moves one byte from the RX FIFO into the caller's buffer. Exactly rlen
|
||||
; reads are queued into freshly flushed FIFOs, so a byte beyond rlen should
|
||||
; never arrive; if one does anyway it is still taken off the FIFO, so the
|
||||
; drain loop cannot stall on it, but it is dropped rather than written
|
||||
; past the end of the buffer.
|
||||
.take_byte:
|
||||
mov edx, [rgot]
|
||||
mov eax, [ebx+DwIcDataCmd]
|
||||
cmp edx, [rlen]
|
||||
jae @f
|
||||
mov edi, [buf]
|
||||
mov [edi+edx], al
|
||||
inc edx
|
||||
mov [rgot], edx
|
||||
@@:
|
||||
retn
|
||||
.chk:
|
||||
mov eax, [rgot]
|
||||
cmp eax, [rlen]
|
||||
jne .wait
|
||||
test dword [ebx+DwIcStatus], DW_STAT_MST_ACT
|
||||
jnz .wait
|
||||
call dw_ctrl_disable
|
||||
xor eax, eax
|
||||
ret
|
||||
.wait:
|
||||
BLOCK_TICK .timeout
|
||||
jmp .drain
|
||||
.abort:
|
||||
mov esi, [ebx+DwIcTxAbrtSource]
|
||||
mov eax, [ebx+DwIcClrTxAbrt]
|
||||
call dw_ctrl_disable
|
||||
mov eax, esi
|
||||
test eax, eax
|
||||
jnz @f
|
||||
or eax, 0x80000000
|
||||
@@:
|
||||
ret
|
||||
.timeout:
|
||||
call dw_ctrl_abort
|
||||
or eax, -1
|
||||
ret
|
||||
endp
|
||||
@@ -1,646 +0,0 @@
|
||||
; Minimal HID report descriptor parser.
|
||||
;
|
||||
; The goal is not a full HID implementation: the parser walks the descriptor
|
||||
; once and remembers the bit layout of the first input report that contains
|
||||
; relative X and relative Y (Generic Desktop / X, Y) - i.e. the mouse
|
||||
; compatibility collection that every I2C mouse and every Windows Precision
|
||||
; Touchpad exposes. Buttons (Usage Page 9) and a relative wheel found in the
|
||||
; same report are picked up too. Absolute (digitizer) reports are advanced
|
||||
; over but otherwise ignored.
|
||||
;
|
||||
; Report IDs are honoured: bit positions are counted separately per report ID
|
||||
; and the chosen ID is checked in every incoming packet.
|
||||
;
|
||||
; Alongside the mouse report, the parser also maps the touchpad (Windows
|
||||
; Precision Touchpad) report: the report that carries Tip Switch usages.
|
||||
; Each Tip Switch opens a new finger block; the absolute X and Y that follow
|
||||
; it belong to that finger; Contact Count and the Button-page fields of the
|
||||
; same report are recorded too. Once the pad is switched into touchpad mode
|
||||
; those offsets are what the frame decoder reads - every vendor lays the
|
||||
; frame out differently, and only the descriptor knows how.
|
||||
HID_MAX_FINGERS = 5
|
||||
|
||||
HID_MAX_USAGES = 16
|
||||
HID_MAX_REPIDS = 16
|
||||
|
||||
; Returns the pointer to the input bit counter of the current report ID,
|
||||
; allocating a new slot on first use.
|
||||
; out: ebx -> dword bit counter. Clobbers eax, ecx.
|
||||
proc hid_get_bits_slot
|
||||
mov eax, [p_report_id]
|
||||
xor ecx, ecx
|
||||
.scan:
|
||||
cmp ecx, [p_idcnt]
|
||||
jae .add
|
||||
cmp eax, [p_ids+ecx*4]
|
||||
jz .found
|
||||
inc ecx
|
||||
jmp .scan
|
||||
.add:
|
||||
cmp ecx, HID_MAX_REPIDS
|
||||
jb @f
|
||||
dec ecx ; table full: reuse the last slot
|
||||
jmp .found
|
||||
@@:
|
||||
mov [p_ids+ecx*4], eax
|
||||
mov dword [p_bits+ecx*4], 0
|
||||
mov dword [p_fbits+ecx*4], 0
|
||||
inc [p_idcnt]
|
||||
.found:
|
||||
lea ebx, [p_bits+ecx*4]
|
||||
ret
|
||||
endp
|
||||
|
||||
; Handles one Input main item. v_flags = item data (bit 2 = relative).
|
||||
proc hid_process_input
|
||||
push eax ebx ecx edx
|
||||
call hid_get_bits_slot
|
||||
mov eax, [ebx]
|
||||
mov [v_base], eax
|
||||
; Advance the counter over this field right away.
|
||||
mov eax, [p_report_size]
|
||||
imul eax, [p_report_count]
|
||||
add [ebx], eax
|
||||
; Remember the largest logical maximum ever attached to Generic Desktop X
|
||||
; and Y. The mouse collection declares a tiny relative range there while
|
||||
; the touchpad collection declares the real surface extents, so the
|
||||
; maximum over the whole descriptor is the size of the pad - which is what
|
||||
; the button zones are measured against, and it differs per model.
|
||||
cmp [p_usage_cnt], 0
|
||||
je .no_extent
|
||||
xor ecx, ecx
|
||||
.ext_loop:
|
||||
cmp ecx, [p_usage_cnt]
|
||||
jae .no_extent
|
||||
mov eax, [p_usages+ecx*4]
|
||||
cmp eax, 0x00010030
|
||||
jne .ext_y
|
||||
mov eax, [p_log_max]
|
||||
cmp eax, [t_padmaxx]
|
||||
jbe .ext_next
|
||||
mov [t_padmaxx], eax
|
||||
jmp .ext_next
|
||||
.ext_y:
|
||||
cmp eax, 0x00010031
|
||||
jne .ext_next
|
||||
mov eax, [p_log_max]
|
||||
cmp eax, [t_padmaxy]
|
||||
jbe .ext_next
|
||||
mov [t_padmaxy], eax
|
||||
.ext_next:
|
||||
inc ecx
|
||||
jmp .ext_loop
|
||||
.no_extent:
|
||||
; Button-style field: Usage Minimum/Maximum on the Button page.
|
||||
cmp [p_usage_min], -1
|
||||
je .not_buttons
|
||||
cmp [p_usage_max], -1
|
||||
je .not_buttons
|
||||
cmp [p_usage_page], 9
|
||||
jne .not_buttons
|
||||
cmp [p_report_size], 1 ; buttons are always 1-bit fields
|
||||
jne .done
|
||||
mov eax, [v_base]
|
||||
mov ecx, [p_report_count]
|
||||
call hid_note_buttons
|
||||
jmp .done
|
||||
.not_buttons:
|
||||
cmp [p_usage_cnt], 0
|
||||
je .done
|
||||
call hid_note_touchpad
|
||||
; Usage-list field: look for GD/X, GD/Y, GD/Wheel among the usages.
|
||||
test [v_flags], 4 ; only relative fields are interesting
|
||||
jz .done
|
||||
xor ecx, ecx
|
||||
.usage_loop:
|
||||
cmp ecx, [p_report_count]
|
||||
jae .done
|
||||
; usage index = min(field index, usage count - 1): a short usage list
|
||||
; applies its last usage to the remaining fields.
|
||||
mov edx, [p_usage_cnt]
|
||||
dec edx
|
||||
mov eax, ecx
|
||||
cmp eax, edx
|
||||
jbe @f
|
||||
mov eax, edx
|
||||
@@:
|
||||
mov eax, [p_usages+eax*4]
|
||||
cmp eax, 0x00010030
|
||||
je .is_x
|
||||
cmp eax, 0x00010031
|
||||
je .is_y
|
||||
cmp eax, 0x00010038
|
||||
je .is_wheel
|
||||
.next_usage:
|
||||
inc ecx
|
||||
jmp .usage_loop
|
||||
.is_x:
|
||||
test [t_have], 1
|
||||
jnz .next_usage
|
||||
call hid_claim_report_id
|
||||
jc .next_usage
|
||||
call hid_field_offset
|
||||
mov [t_xoff], eax
|
||||
mov eax, [p_report_size]
|
||||
mov [t_xsize], eax
|
||||
or [t_have], 1
|
||||
jmp .next_usage
|
||||
.is_y:
|
||||
test [t_have], 2
|
||||
jnz .next_usage
|
||||
call hid_claim_report_id
|
||||
jc .next_usage
|
||||
call hid_field_offset
|
||||
mov [t_yoff], eax
|
||||
mov eax, [p_report_size]
|
||||
mov [t_ysize], eax
|
||||
or [t_have], 2
|
||||
jmp .next_usage
|
||||
.is_wheel:
|
||||
test [t_have], 8
|
||||
jnz .next_usage
|
||||
mov eax, [t_id]
|
||||
cmp eax, -1 ; wheel never claims a report on its own
|
||||
je .next_usage
|
||||
cmp eax, [p_report_id]
|
||||
jne .next_usage
|
||||
call hid_field_offset
|
||||
mov [t_woff], eax
|
||||
mov eax, [p_report_size]
|
||||
mov [t_wsize], eax
|
||||
or [t_have], 8
|
||||
jmp .next_usage
|
||||
.done:
|
||||
pop edx ecx ebx eax
|
||||
ret
|
||||
endp
|
||||
|
||||
; Records a run of 1-bit Button-page fields starting at bit eax, ecx of them.
|
||||
; The mouse decoder wants the buttons of ITS report: an item from some other
|
||||
; report is kept only until a better one turns up, and .eof drops it if it
|
||||
; still does not match. The touchpad report keeps its own copy.
|
||||
proc hid_note_buttons
|
||||
push eax ecx edx
|
||||
cmp ecx, 8
|
||||
jbe @f
|
||||
mov ecx, 8
|
||||
@@:
|
||||
mov edx, [p_report_id]
|
||||
cmp edx, [t_ptp_id]
|
||||
jne .mouse
|
||||
cmp [t_pbtn_cnt], 0
|
||||
jne .mouse
|
||||
mov [t_pbtn_off], eax
|
||||
mov [t_pbtn_cnt], ecx
|
||||
.mouse:
|
||||
cmp [t_btncnt], 0
|
||||
je .take
|
||||
mov edx, [t_btnid]
|
||||
cmp edx, [t_id] ; already the chosen report's: keep
|
||||
je .done
|
||||
mov edx, [p_report_id]
|
||||
cmp edx, [t_btnid] ; a second run in the same report: keep the first
|
||||
je .done
|
||||
.take:
|
||||
mov [t_btnoff], eax
|
||||
mov [t_btncnt], ecx
|
||||
mov eax, [p_report_id]
|
||||
mov [t_btnid], eax
|
||||
.done:
|
||||
pop edx ecx eax
|
||||
ret
|
||||
endp
|
||||
|
||||
; Walks the usages of the current input item looking for the touchpad
|
||||
; fields. Field k takes usage min(k, count-1), as in the mouse search.
|
||||
proc hid_note_touchpad
|
||||
push eax ebx ecx edx
|
||||
xor ecx, ecx
|
||||
.field:
|
||||
cmp ecx, [p_report_count]
|
||||
jae .done
|
||||
mov edx, [p_usage_cnt]
|
||||
dec edx
|
||||
mov eax, ecx
|
||||
cmp eax, edx
|
||||
jbe @f
|
||||
mov eax, edx
|
||||
@@:
|
||||
mov ebx, [p_usages+eax*4] ; ebx = usage of field ecx
|
||||
call hid_field_offset ; eax = its bit offset
|
||||
cmp ebx, 0x000D0042 ; Tip Switch: a new finger
|
||||
je .tip
|
||||
cmp ebx, 0x000D0054 ; Contact Count
|
||||
je .count
|
||||
cmp ebx, 0x000D0051 ; Contact Identifier
|
||||
je .cid
|
||||
cmp ebx, 0x00010030
|
||||
je .x
|
||||
cmp ebx, 0x00010031
|
||||
je .y
|
||||
shr ebx, 16
|
||||
cmp ebx, 9 ; buttons written as a usage list
|
||||
jne .next
|
||||
push ecx
|
||||
neg ecx
|
||||
add ecx, [p_report_count] ; the fields from here to the end
|
||||
call hid_note_buttons
|
||||
pop ecx
|
||||
jmp .done ; one run per item is enough
|
||||
.tip:
|
||||
cmp [t_ptp_id], -1
|
||||
jne @f
|
||||
mov edx, [p_report_id]
|
||||
mov [t_ptp_id], edx ; the first report with fingers is the one
|
||||
@@:
|
||||
call hid_in_ptp
|
||||
jne .next
|
||||
mov edx, [t_fcount]
|
||||
cmp edx, HID_MAX_FINGERS
|
||||
jae .next
|
||||
mov [t_ftip+edx*4], eax
|
||||
mov dword [t_fxs+edx*4], 0
|
||||
mov dword [t_fys+edx*4], 0
|
||||
mov dword [t_fcids+edx*4], 0
|
||||
inc [t_fcount]
|
||||
jmp .next
|
||||
.cid:
|
||||
call hid_in_ptp
|
||||
jne .next
|
||||
mov edx, [t_fcount]
|
||||
test edx, edx
|
||||
jz .next
|
||||
dec edx
|
||||
cmp dword [t_fcids+edx*4], 0
|
||||
jne .next
|
||||
mov [t_fcid+edx*4], eax
|
||||
mov eax, [p_report_size]
|
||||
mov [t_fcids+edx*4], eax
|
||||
jmp .next
|
||||
.count:
|
||||
call hid_in_ptp
|
||||
jne .next
|
||||
mov [t_ccnt_off], eax
|
||||
mov eax, [p_report_size]
|
||||
mov [t_ccnt_size], eax
|
||||
jmp .next
|
||||
.x:
|
||||
test [v_flags], 4 ; absolute only; relative is the mouse
|
||||
jnz .next
|
||||
call hid_in_ptp
|
||||
jne .next
|
||||
mov edx, [t_fcount]
|
||||
test edx, edx
|
||||
jz .next
|
||||
dec edx
|
||||
cmp dword [t_fxs+edx*4], 0
|
||||
jne .next
|
||||
mov [t_fx+edx*4], eax
|
||||
mov eax, [p_report_size]
|
||||
mov [t_fxs+edx*4], eax
|
||||
jmp .next
|
||||
.y:
|
||||
test [v_flags], 4
|
||||
jnz .next
|
||||
call hid_in_ptp
|
||||
jne .next
|
||||
mov edx, [t_fcount]
|
||||
test edx, edx
|
||||
jz .next
|
||||
dec edx
|
||||
cmp dword [t_fys+edx*4], 0
|
||||
jne .next
|
||||
mov [t_fy+edx*4], eax
|
||||
mov eax, [p_report_size]
|
||||
mov [t_fys+edx*4], eax
|
||||
.next:
|
||||
inc ecx
|
||||
jmp .field
|
||||
.done:
|
||||
pop edx ecx ebx eax
|
||||
ret
|
||||
endp
|
||||
|
||||
; ZF set when the current item belongs to the touchpad report.
|
||||
proc hid_in_ptp
|
||||
push eax
|
||||
mov eax, [p_report_id]
|
||||
cmp eax, [t_ptp_id]
|
||||
pop eax
|
||||
ret
|
||||
endp
|
||||
|
||||
; Size in bytes of the feature report with id eax; 0 when the descriptor
|
||||
; never mentioned one.
|
||||
proc hid_feature_bytes
|
||||
push ecx
|
||||
xor ecx, ecx
|
||||
@@:
|
||||
cmp ecx, [p_idcnt]
|
||||
jae .none
|
||||
cmp eax, [p_ids+ecx*4]
|
||||
je .found
|
||||
inc ecx
|
||||
jmp @b
|
||||
.found:
|
||||
mov eax, [p_fbits+ecx*4]
|
||||
add eax, 7
|
||||
shr eax, 3
|
||||
pop ecx
|
||||
ret
|
||||
.none:
|
||||
xor eax, eax
|
||||
pop ecx
|
||||
ret
|
||||
endp
|
||||
|
||||
; Locks the candidate report ID to the current one, or fails (CF=1) when a
|
||||
; different report already holds X/Y.
|
||||
proc hid_claim_report_id
|
||||
mov eax, [t_id]
|
||||
cmp eax, -1
|
||||
jne @f
|
||||
mov eax, [p_report_id]
|
||||
mov [t_id], eax
|
||||
clc
|
||||
ret
|
||||
@@:
|
||||
cmp eax, [p_report_id]
|
||||
jne .taken
|
||||
clc
|
||||
ret
|
||||
.taken:
|
||||
stc
|
||||
ret
|
||||
endp
|
||||
|
||||
; Bit offset of field #ecx of the current item.
|
||||
; in: ecx = field index. out: eax = v_base + ecx * report_size.
|
||||
proc hid_field_offset
|
||||
mov eax, [p_report_size]
|
||||
imul eax, ecx
|
||||
add eax, [v_base]
|
||||
ret
|
||||
endp
|
||||
|
||||
; Parses the report descriptor.
|
||||
; in: esi -> descriptor, ecx = length.
|
||||
; out: eax = 1 and f_* variables filled if a usable report was found.
|
||||
proc hid_parse_report_desc uses ebx esi edi
|
||||
lea edi, [esi+ecx]
|
||||
xor eax, eax
|
||||
mov [p_usage_page], eax
|
||||
mov [p_report_size], eax
|
||||
mov [p_report_count], eax
|
||||
mov [p_report_id], eax
|
||||
mov [p_uses_repid], eax
|
||||
mov [p_usage_cnt], eax
|
||||
mov [p_idcnt], eax
|
||||
mov [p_log_max], eax
|
||||
mov [t_padmaxx], eax
|
||||
mov [t_padmaxy], eax
|
||||
mov [t_have], eax
|
||||
mov [t_btncnt], eax
|
||||
mov [t_wsize], eax
|
||||
mov [p_usage_min], -1
|
||||
mov [p_usage_max], -1
|
||||
mov [t_id], -1
|
||||
mov [t_btnid], -2
|
||||
mov [t_ptp_id], -1
|
||||
mov [t_fcount], eax
|
||||
mov [t_ccnt_size], eax
|
||||
mov [t_pbtn_cnt], eax
|
||||
mov [t_ptp_bytes], eax
|
||||
.loop:
|
||||
cmp esi, edi
|
||||
jae .eof
|
||||
movzx eax, byte [esi]
|
||||
inc esi
|
||||
cmp al, 0xFE
|
||||
je .long_item
|
||||
mov ecx, eax
|
||||
and ecx, 3
|
||||
cmp ecx, 3
|
||||
jne @f
|
||||
inc ecx ; size code 3 means 4 bytes
|
||||
@@:
|
||||
lea ebx, [esi+ecx]
|
||||
cmp ebx, edi
|
||||
ja .eof
|
||||
xor edx, edx
|
||||
jecxz .no_data
|
||||
cmp ecx, 1
|
||||
jne @f
|
||||
movzx edx, byte [esi]
|
||||
jmp .have_data
|
||||
@@:
|
||||
cmp ecx, 2
|
||||
jne @f
|
||||
movzx edx, word [esi]
|
||||
jmp .have_data
|
||||
@@:
|
||||
mov edx, [esi]
|
||||
.have_data:
|
||||
add esi, ecx
|
||||
.no_data:
|
||||
and eax, 0xFC
|
||||
; Global items
|
||||
cmp al, 0x04
|
||||
je .g_usage_page
|
||||
cmp al, 0x84
|
||||
je .g_report_id
|
||||
cmp al, 0x74
|
||||
je .g_report_size
|
||||
cmp al, 0x94
|
||||
je .g_report_count
|
||||
cmp al, 0x24
|
||||
je .g_log_max
|
||||
; Local items
|
||||
cmp al, 0x08
|
||||
je .l_usage
|
||||
cmp al, 0x18
|
||||
je .l_usage_min
|
||||
cmp al, 0x28
|
||||
je .l_usage_max
|
||||
; Main items
|
||||
cmp al, 0x80
|
||||
je .m_input
|
||||
cmp al, 0x90
|
||||
je .m_clear_locals
|
||||
cmp al, 0xB0
|
||||
je .m_feature
|
||||
cmp al, 0xA0
|
||||
je .m_clear_locals
|
||||
cmp al, 0xC0
|
||||
je .m_clear_locals
|
||||
jmp .loop
|
||||
.g_usage_page:
|
||||
and edx, 0xFFFF
|
||||
mov [p_usage_page], edx
|
||||
jmp .loop
|
||||
.g_report_id:
|
||||
mov [p_report_id], edx
|
||||
mov [p_uses_repid], 1
|
||||
jmp .loop
|
||||
.g_report_size:
|
||||
mov [p_report_size], edx
|
||||
jmp .loop
|
||||
.g_report_count:
|
||||
mov [p_report_count], edx
|
||||
jmp .loop
|
||||
.g_log_max:
|
||||
mov [p_log_max], edx
|
||||
jmp .loop
|
||||
.l_usage:
|
||||
mov ebx, [p_usage_cnt]
|
||||
cmp ebx, HID_MAX_USAGES
|
||||
jae .loop
|
||||
cmp ecx, 4 ; 4-byte usage carries its own page
|
||||
je @f
|
||||
mov eax, [p_usage_page]
|
||||
shl eax, 16
|
||||
or edx, eax
|
||||
@@:
|
||||
mov [p_usages+ebx*4], edx
|
||||
inc [p_usage_cnt]
|
||||
jmp .loop
|
||||
.l_usage_min:
|
||||
mov [p_usage_min], edx
|
||||
jmp .loop
|
||||
.l_usage_max:
|
||||
mov [p_usage_max], edx
|
||||
jmp .loop
|
||||
.m_input:
|
||||
mov [v_flags], edx
|
||||
call hid_process_input
|
||||
jmp .m_clear_locals ; input bits are not feature bits
|
||||
.m_feature:
|
||||
; Feature reports are only ever written, never decoded, but writing one
|
||||
; needs its exact size: a SET_REPORT shorter than the report is ignored by
|
||||
; some firmwares (the Elan Input Mode report has two bytes, mode and the
|
||||
; selective-reporting switches - one byte does nothing there).
|
||||
call hid_get_bits_slot
|
||||
mov eax, [p_report_size]
|
||||
imul eax, [p_report_count]
|
||||
add [p_fbits+ecx*4], eax
|
||||
.m_clear_locals:
|
||||
xor eax, eax
|
||||
mov [p_usage_cnt], eax
|
||||
mov [p_usage_min], -1
|
||||
mov [p_usage_max], -1
|
||||
jmp .loop
|
||||
.long_item:
|
||||
cmp esi, edi
|
||||
jae .eof
|
||||
movzx ecx, byte [esi]
|
||||
lea esi, [esi+ecx+2]
|
||||
jmp .loop
|
||||
.eof:
|
||||
; Size of the touchpad report, when there is one.
|
||||
mov eax, [t_ptp_id]
|
||||
cmp eax, -1
|
||||
je .no_ptp
|
||||
xor ecx, ecx
|
||||
@@:
|
||||
cmp ecx, [p_idcnt]
|
||||
jae .no_ptp
|
||||
cmp eax, [p_ids+ecx*4]
|
||||
je @f
|
||||
inc ecx
|
||||
jmp @b
|
||||
@@:
|
||||
mov eax, [p_bits+ecx*4]
|
||||
add eax, 7
|
||||
shr eax, 3
|
||||
mov [t_ptp_bytes], eax
|
||||
.no_ptp:
|
||||
; Success needs relative X and Y in the same report - or, failing that, a
|
||||
; touchpad report with at least one complete finger, which is then the only
|
||||
; thing the device will be driven through.
|
||||
mov eax, [t_have]
|
||||
and eax, 3
|
||||
cmp eax, 3
|
||||
je .have_mouse
|
||||
cmp [t_fcount], 0
|
||||
je .fail
|
||||
cmp dword [t_fxs], 0
|
||||
je .fail
|
||||
cmp dword [t_fys], 0
|
||||
je .fail
|
||||
mov [f_repid], -1 ; no mouse report to match
|
||||
mov [f_bytes], 0
|
||||
mov [t_btncnt], 0
|
||||
movi eax, 1
|
||||
ret
|
||||
.have_mouse:
|
||||
; Keep buttons/wheel only when they live in the chosen report.
|
||||
mov eax, [t_btnid]
|
||||
cmp eax, [t_id]
|
||||
je @f
|
||||
mov [t_btncnt], 0
|
||||
@@:
|
||||
; Final layout.
|
||||
mov eax, [t_id]
|
||||
mov [f_repid], eax
|
||||
xor ecx, ecx
|
||||
@@:
|
||||
cmp ecx, [p_idcnt]
|
||||
jae .no_bits
|
||||
cmp eax, [p_ids+ecx*4]
|
||||
je .got_bits
|
||||
inc ecx
|
||||
jmp @b
|
||||
.got_bits:
|
||||
mov eax, [p_bits+ecx*4]
|
||||
add eax, 7
|
||||
shr eax, 3
|
||||
mov [f_bytes], eax
|
||||
movi eax, 1
|
||||
ret
|
||||
.no_bits:
|
||||
.fail:
|
||||
xor eax, eax
|
||||
ret
|
||||
endp
|
||||
|
||||
; Extracts an unsigned field from an input report.
|
||||
; in: esi -> report data, eax = bit offset, ecx = bit count (1..24).
|
||||
; out: eax = value.
|
||||
proc hid_extract_u
|
||||
push ebx ecx edx
|
||||
mov edx, eax
|
||||
shr edx, 3
|
||||
mov ebx, [esi+edx] ; buffer has spare bytes at the end
|
||||
and eax, 7
|
||||
push ecx
|
||||
mov ecx, eax
|
||||
shr ebx, cl
|
||||
pop ecx
|
||||
neg ecx
|
||||
add ecx, 32
|
||||
shl ebx, cl
|
||||
shr ebx, cl
|
||||
mov eax, ebx
|
||||
pop edx ecx ebx
|
||||
ret
|
||||
endp
|
||||
|
||||
; Same, sign-extended.
|
||||
proc hid_extract_s
|
||||
push ebx ecx edx
|
||||
mov edx, eax
|
||||
shr edx, 3
|
||||
mov ebx, [esi+edx]
|
||||
and eax, 7
|
||||
push ecx
|
||||
mov ecx, eax
|
||||
shr ebx, cl
|
||||
pop ecx
|
||||
neg ecx
|
||||
add ecx, 32
|
||||
shl ebx, cl
|
||||
sar ebx, cl
|
||||
mov eax, ebx
|
||||
pop edx ecx ebx
|
||||
ret
|
||||
endp
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,26 +0,0 @@
|
||||
[touchpad]
|
||||
; pointer speed in percent of the driver's default (on top of the [mouse]
|
||||
; speed above; pads differ in resolution)
|
||||
speed=100
|
||||
; how far a finger must move before the pointer follows, in pad units;
|
||||
; larger is steadier under a pressing finger, 0 turns the filter off
|
||||
jitter=1
|
||||
; the same, for a finger that landed on the button strip: it is pressing
|
||||
; rather than steering there, so it needs a stricter margin
|
||||
jitter_buttons=45
|
||||
; pad units of two-finger travel per wheel step, and the direction
|
||||
scroll_step=64
|
||||
scroll_invert=0
|
||||
; turn a short, still touch into a click: one finger left, two right,
|
||||
; three middle
|
||||
tap_enable=1
|
||||
; tap, then touch again at once and move: the button stays down for that
|
||||
; second touch - this is how text is selected and how one draws
|
||||
tap_drag=1
|
||||
; right click: 0 never, 1 bottom-right corner, 2 by finger count (two
|
||||
; fingers right, three middle), 3 either
|
||||
right_click=1
|
||||
; button strip along the bottom edge, in percent of the surface: its
|
||||
; height, and where its left half ends
|
||||
button_zone=15
|
||||
right_split=50
|
||||
@@ -1,72 +0,0 @@
|
||||
; Asks the I2C touchpad driver to read its settings again.
|
||||
;
|
||||
; The driver takes everything it can be tuned with from the [touchpad] section
|
||||
; of /sys/settings/system.ini, and it reads that file once while loading. This
|
||||
; tells it to read the file again, so editing a setting takes effect straight
|
||||
; away instead of at the next boot.
|
||||
;
|
||||
; There is no window: the outcome goes to the debug board, the way the driver
|
||||
; reports everything else.
|
||||
|
||||
format binary as ""
|
||||
use32
|
||||
db 'MENUET01'
|
||||
dd 1, start, i_end, mem, mem, 0, 0
|
||||
|
||||
include '../../programs/macros.inc'
|
||||
|
||||
SRV_RELOAD_CONF = 1
|
||||
|
||||
start:
|
||||
; 1. Find the driver's service by name.
|
||||
mcall 68, 16, srv_name
|
||||
test eax, eax
|
||||
jz .no_driver
|
||||
mov [ioctl.handle], eax
|
||||
; 2. Ask it to reload. No data travels either way: the driver reads the file
|
||||
; itself, so the settings file stays the only place they are written down.
|
||||
mcall 68, 17, ioctl
|
||||
test eax, eax
|
||||
jnz .refused
|
||||
mov esi, msg_ok
|
||||
jmp .say
|
||||
.no_driver:
|
||||
mov esi, msg_no_driver
|
||||
jmp .say
|
||||
.refused:
|
||||
mov esi, msg_refused
|
||||
.say:
|
||||
call board_str
|
||||
or eax, -1
|
||||
mcall
|
||||
|
||||
; Writes a zero-terminated string to the debug board.
|
||||
; in: esi -> string
|
||||
board_str:
|
||||
lodsb
|
||||
test al, al
|
||||
jz .done
|
||||
mov cl, al
|
||||
mcall 63, 1
|
||||
jmp board_str
|
||||
.done:
|
||||
ret
|
||||
|
||||
srv_name db 'I2CHID', 0
|
||||
|
||||
align 4
|
||||
ioctl:
|
||||
.handle dd 0
|
||||
.io_code dd SRV_RELOAD_CONF
|
||||
.input dd 0
|
||||
.inp_size dd 0
|
||||
.output dd 0
|
||||
.out_size dd 0
|
||||
|
||||
msg_ok db 'tpreload: touchpad settings reloaded', 13, 10, 0
|
||||
msg_no_driver db 'tpreload: the I2C touchpad driver is not loaded', 13, 10, 0
|
||||
msg_refused db 'tpreload: the driver refused the request', 13, 10, 0
|
||||
|
||||
i_end:
|
||||
rb 1024
|
||||
mem:
|
||||
@@ -139,7 +139,6 @@ import core,\
|
||||
RegKeyboard,\
|
||||
DelKeyboard,\
|
||||
Sleep,\
|
||||
Delay,\
|
||||
GetTimerTicks,\
|
||||
\
|
||||
strncat,\
|
||||
|
||||
@@ -1754,14 +1754,8 @@ proc disk_read_write stdcall uses ebx esi edi, \
|
||||
mov eax, [numsectors]
|
||||
mov eax, [eax]
|
||||
; 2. The transfer length for SCSI_{READ,WRITE}10 commands can not be greater
|
||||
; than 0xFFFF sectors, but that is not the practical limit: the field size is
|
||||
; the only thing the standard bounds, while real sticks hang their firmware on
|
||||
; multi-megabyte single commands. The kernel disk cache asks for as much as
|
||||
; CACHE_MAX_ALLOC_SIZE (4 MB) in one call, i.e. 8192 sectors, and that is
|
||||
; exactly where such sticks stop answering and re-enumerate. Linux caps
|
||||
; usb-storage at 240 sectors (120 KB) for the same reason; do the same and
|
||||
; split larger requests into slices.
|
||||
max_sectors_at_time = 240
|
||||
; than 0xFFFF, so split the request to slices with <= 0xFFFF sectors.
|
||||
max_sectors_at_time = 0xFFFF
|
||||
.split:
|
||||
push eax ; .length_rest
|
||||
cmp eax, max_sectors_at_time
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
if tup.getconfig("NO_FASM") ~= "" then return end
|
||||
ROOT = "../../.."
|
||||
tup.rule("xhci.asm", "fasm %f %o " .. tup.getconfig("PESTRIP_CMD") .. tup.getconfig("KPACK_CMD"), "%B.sys")
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,993 +0,0 @@
|
||||
; Device slots, contexts and pipes for the xHCI driver.
|
||||
; This file is included from xhci.asm.
|
||||
|
||||
; =============================================================================
|
||||
; ============================ Context helpers ================================
|
||||
; =============================================================================
|
||||
|
||||
; Returns the address of one context inside a context structure.
|
||||
; in: eax = base of the structure, ecx = index of the context,
|
||||
; esi -> usb_controller.
|
||||
; out: eax = address of the context.
|
||||
proc xhci_context
|
||||
push ecx edx
|
||||
mov edx, [esi+xhci_controller.ContextSize-XCD]
|
||||
imul edx, ecx
|
||||
add eax, edx
|
||||
pop edx ecx
|
||||
ret
|
||||
endp
|
||||
|
||||
; Zeroes the Input Context. The caller must hold CmdLock.
|
||||
; in: esi -> usb_controller.
|
||||
proc xhci_clear_input_ctx
|
||||
push eax ecx edi
|
||||
mov edi, [esi+xhci_controller.InputCtx-XCD]
|
||||
xor eax, eax
|
||||
mov ecx, 33*64/4
|
||||
rep stosd
|
||||
pop edi ecx eax
|
||||
ret
|
||||
endp
|
||||
|
||||
; Returns the pipe of the default control endpoint of the same device, which
|
||||
; represents the device as a whole.
|
||||
; in: ebx -> xhci_pipe. out: eax -> xhci_pipe or 0.
|
||||
proc xhci_ctrl_pipe
|
||||
mov eax, [ebx+xhci_pipe.DevPage]
|
||||
test eax, eax
|
||||
jz .nothing
|
||||
mov eax, [eax+XHCI_PIPES_OFS+1*4]
|
||||
test eax, eax
|
||||
jz .nothing
|
||||
sub eax, sizeof.xhci_pipe
|
||||
.nothing:
|
||||
ret
|
||||
endp
|
||||
|
||||
; Fills the Slot Context of the Input Context from the device description kept
|
||||
; in a pipe. The caller must hold CmdLock.
|
||||
; in: esi -> usb_controller, ebx -> xhci_pipe describing the device,
|
||||
; ecx = value for the Context Entries field.
|
||||
proc xhci_fill_slot_ctx
|
||||
push eax ecx edx edi
|
||||
mov eax, [esi+xhci_controller.InputCtx-XCD]
|
||||
push ecx
|
||||
movi ecx, 1
|
||||
call xhci_context
|
||||
pop ecx
|
||||
mov edi, eax
|
||||
; dword 0: Route String, Speed and Context Entries.
|
||||
mov eax, [ebx+xhci_pipe.Route]
|
||||
and eax, 0FFFFFh
|
||||
if XHCI_SUPERSPEED
|
||||
; A SuperSpeed root-port device carries the raw PORTSC speed identifier;
|
||||
; its kernel-visible Speed pretends high-speed and must not get here.
|
||||
mov edx, [ebx+xhci_pipe.PSIV]
|
||||
test edx, edx
|
||||
jnz .havespeed
|
||||
end if
|
||||
mov edx, [ebx+xhci_pipe.Speed]
|
||||
cmp edx, USB_SPEED_FS
|
||||
jz .fs
|
||||
cmp edx, USB_SPEED_LS
|
||||
jz .ls
|
||||
movi edx, XHCI_PSI_HS
|
||||
jmp .havespeed
|
||||
.fs:
|
||||
movi edx, XHCI_PSI_FS
|
||||
jmp .havespeed
|
||||
.ls:
|
||||
movi edx, XHCI_PSI_LS
|
||||
.havespeed:
|
||||
shl edx, 20
|
||||
or eax, edx
|
||||
shl ecx, 27
|
||||
or eax, ecx
|
||||
mov [edi], eax
|
||||
; dword 1: Root Hub Port Number.
|
||||
mov eax, [ebx+xhci_pipe.RootPort]
|
||||
shl eax, 16
|
||||
mov [edi+4], eax
|
||||
; dword 2: the Transaction Translator, if the device is served by one.
|
||||
mov eax, [ebx+xhci_pipe.TTSlot]
|
||||
test eax, eax
|
||||
jz @f
|
||||
mov edx, [ebx+xhci_pipe.TTPort]
|
||||
shl edx, 8
|
||||
or eax, edx
|
||||
@@:
|
||||
mov [edi+8], eax
|
||||
and dword [edi+12], 0
|
||||
pop edi edx ecx eax
|
||||
ret
|
||||
endp
|
||||
|
||||
; Fills the Endpoint Context of the Input Context for the given pipe.
|
||||
; The caller must hold CmdLock.
|
||||
; in: esi -> usb_controller, ebx -> xhci_pipe.
|
||||
proc xhci_fill_ep_ctx
|
||||
push eax ecx edx edi
|
||||
mov eax, [esi+xhci_controller.InputCtx-XCD]
|
||||
mov ecx, [ebx+xhci_pipe.DCI]
|
||||
inc ecx
|
||||
call xhci_context
|
||||
mov edi, eax
|
||||
; dword 0: Interval.
|
||||
mov eax, [ebx+xhci_pipe.Interval]
|
||||
shl eax, 16
|
||||
mov [edi], eax
|
||||
; dword 1: Error Count, Endpoint Type, Max Burst Size and Max Packet Size.
|
||||
mov eax, [ebx+xhci_pipe.EpType]
|
||||
shl eax, 3
|
||||
or eax, 3 shl 1 ; three retries before giving up
|
||||
mov edx, [ebx+xhci_pipe.MaxPacket]
|
||||
mov ecx, edx
|
||||
shr ecx, 11
|
||||
and ecx, 3 ; extra transactions per microframe
|
||||
shl ecx, 8
|
||||
or eax, ecx
|
||||
if XHCI_SUPERSPEED
|
||||
; A SuperSpeed bulk endpoint may allow bursts of several packets; the field
|
||||
; shares its bits with the extra-transactions ones, which are zero then.
|
||||
mov ecx, [ebx+xhci_pipe.MaxBurst]
|
||||
shl ecx, 8
|
||||
or eax, ecx
|
||||
end if
|
||||
and edx, 7FFh
|
||||
shl edx, 16
|
||||
or eax, edx
|
||||
mov [edi+4], eax
|
||||
; dwords 2 and 3: the TR Dequeue Pointer with the Dequeue Cycle State.
|
||||
mov eax, [ebx+xhci_pipe.Enqueue]
|
||||
shl eax, 4
|
||||
add eax, [ebx+xhci_pipe.RingPhys]
|
||||
or eax, [ebx+xhci_pipe.Cycle]
|
||||
mov [edi+8], eax
|
||||
and dword [edi+12], 0
|
||||
; dword 4: Average TRB Length, only a hint for the bandwidth scheduler.
|
||||
mov eax, [ebx+xhci_pipe.MaxPacket]
|
||||
and eax, 7FFh
|
||||
cmp [ebx+xhci_pipe.EpType], XHCI_EP_CONTROL
|
||||
jnz @f
|
||||
movi eax, 8
|
||||
@@:
|
||||
mov [edi+16], eax
|
||||
and dword [edi+20], 0
|
||||
pop edi edx ecx eax
|
||||
ret
|
||||
endp
|
||||
|
||||
; =============================================================================
|
||||
; ============================== Slot commands ================================
|
||||
; =============================================================================
|
||||
|
||||
; Issues the Address Device command for a newly created default control pipe.
|
||||
; in: esi -> usb_controller, ebx -> xhci_pipe. out: eax = 0 on failure.
|
||||
proc xhci_address_device
|
||||
push ebx ecx edx edi
|
||||
lea ecx, [esi+xhci_controller.CmdLock-XCD]
|
||||
invoke MutexLock
|
||||
call xhci_clear_input_ctx
|
||||
mov edx, [esi+xhci_controller.InputCtx-XCD]
|
||||
mov dword [edx+4], 3 ; add the Slot Context and endpoint zero
|
||||
movi ecx, 1
|
||||
call xhci_fill_slot_ctx
|
||||
call xhci_fill_ep_ctx
|
||||
mov [ebx+xhci_pipe.MaxDCI], 1
|
||||
; Point the DCBAA entry of the slot at the Device Context.
|
||||
mov eax, [esi+xhci_controller.CommonPage-XCD]
|
||||
mov ecx, [ebx+xhci_pipe.SlotId]
|
||||
mov edx, [ebx+xhci_pipe.DevPagePhys]
|
||||
mov [eax+ecx*8], edx
|
||||
and dword [eax+ecx*8+4], 0
|
||||
mov edx, [ebx+xhci_pipe.SlotId]
|
||||
shl edx, 24
|
||||
or edx, XHCI_TRB_ADDRESS_DEV shl 10
|
||||
mov eax, [esi+xhci_controller.InputCtxPhys-XCD]
|
||||
push ebx
|
||||
xor ebx, ebx
|
||||
xor ecx, ecx
|
||||
call xhci_cmd_submit
|
||||
pop ebx
|
||||
push eax
|
||||
lea ecx, [esi+xhci_controller.CmdLock-XCD]
|
||||
invoke MutexUnlock
|
||||
pop eax
|
||||
cmp eax, XHCI_CC_SUCCESS
|
||||
jz .ok
|
||||
DEBUGF 1,'K : XHCI: Address Device failed, code %d\n',eax
|
||||
xor eax, eax
|
||||
jmp .nothing
|
||||
.ok:
|
||||
movi eax, 1
|
||||
.nothing:
|
||||
pop edi edx ecx ebx
|
||||
ret
|
||||
endp
|
||||
|
||||
; Issues a Configure Endpoint command that adds the given endpoint.
|
||||
; in: esi -> usb_controller, ebx -> xhci_pipe of the endpoint,
|
||||
; edi -> xhci_pipe of the default control endpoint of the same device.
|
||||
; out: eax = completion code.
|
||||
proc xhci_configure_endpoint
|
||||
push ebx ecx edx esi edi
|
||||
lea ecx, [esi+xhci_controller.CmdLock-XCD]
|
||||
invoke MutexLock
|
||||
call xhci_clear_input_ctx
|
||||
; Drop the endpoint and add it again, so that reopening an endpoint that has
|
||||
; been closed before also works.
|
||||
mov ecx, [ebx+xhci_pipe.DCI]
|
||||
movi eax, 1
|
||||
shl eax, cl
|
||||
mov edx, [esi+xhci_controller.InputCtx-XCD]
|
||||
mov [edx], eax
|
||||
or eax, 1 ; the Slot Context is always added
|
||||
mov [edx+4], eax
|
||||
call xhci_fill_ep_ctx
|
||||
; The Context Entries field must cover every endpoint in use by the device.
|
||||
mov ecx, [ebx+xhci_pipe.DCI]
|
||||
cmp ecx, [edi+xhci_pipe.MaxDCI]
|
||||
jae @f
|
||||
mov ecx, [edi+xhci_pipe.MaxDCI]
|
||||
@@:
|
||||
mov [edi+xhci_pipe.MaxDCI], ecx
|
||||
push ebx
|
||||
mov ebx, edi
|
||||
call xhci_fill_slot_ctx
|
||||
pop ebx
|
||||
mov edx, [ebx+xhci_pipe.SlotId]
|
||||
shl edx, 24
|
||||
or edx, XHCI_TRB_CONFIG_EP shl 10
|
||||
mov eax, [esi+xhci_controller.InputCtxPhys-XCD]
|
||||
push ebx
|
||||
xor ebx, ebx
|
||||
xor ecx, ecx
|
||||
call xhci_cmd_submit
|
||||
pop ebx
|
||||
push eax
|
||||
lea ecx, [esi+xhci_controller.CmdLock-XCD]
|
||||
invoke MutexUnlock
|
||||
pop eax
|
||||
pop edi esi edx ecx ebx
|
||||
ret
|
||||
endp
|
||||
|
||||
; Tells the controller where the endpoint has to continue from.
|
||||
; in: esi -> usb_controller, ebx -> xhci_pipe.
|
||||
proc xhci_set_dequeue
|
||||
pushad
|
||||
cmp [ebx+xhci_pipe.SlotId], 0
|
||||
jz .nothing
|
||||
mov eax, [ebx+xhci_pipe.Dequeue]
|
||||
shl eax, 4
|
||||
add eax, [ebx+xhci_pipe.RingPhys]
|
||||
or eax, [ebx+xhci_pipe.Cycle]
|
||||
mov ecx, [ebx+xhci_pipe.DCI]
|
||||
shl ecx, 16
|
||||
mov edx, [ebx+xhci_pipe.SlotId]
|
||||
shl edx, 24
|
||||
or edx, ecx
|
||||
or edx, XHCI_TRB_SET_DEQ shl 10
|
||||
xor ebx, ebx
|
||||
xor ecx, ecx
|
||||
call xhci_cmd_sync
|
||||
cmp eax, XHCI_CC_SUCCESS
|
||||
jz .nothing
|
||||
DEBUGF 1,'K : XHCI: Set TR Dequeue Pointer failed, code %d\n',eax
|
||||
.nothing:
|
||||
popad
|
||||
ret
|
||||
endp
|
||||
|
||||
; =============================================================================
|
||||
; =============================== New device ==================================
|
||||
; =============================================================================
|
||||
|
||||
; Called from xhci_port_init and from the hub support code when a new device
|
||||
; has been connected and reset. Enables a device slot for it and hands it over
|
||||
; to the protocol layer.
|
||||
; in: esi -> usb_controller, eax = speed. out: eax = 0 on failure.
|
||||
proc xhci_new_device
|
||||
push ebx ecx edx edi
|
||||
mov [esi+usb_controller.ResettingSpeed], al
|
||||
; 1. Reserve room for the pseudo-pipe that describes the new device. Only the
|
||||
; fields read by xhci_init_pipe are filled in; the layout matches a real pipe,
|
||||
; so the result can be passed to usb_new_device as a usb_pipe pointer.
|
||||
sub esp, sizeof.xhci_pipe + 4
|
||||
mov ebx, esp
|
||||
push ebx
|
||||
mov edi, ebx
|
||||
xor eax, eax
|
||||
mov ecx, (sizeof.xhci_pipe + 4)/4
|
||||
rep stosd
|
||||
pop ebx
|
||||
mov [ebx+sizeof.xhci_pipe], esi ; usb_pipe.Controller
|
||||
movzx eax, [esi+usb_controller.ResettingSpeed]
|
||||
mov [ebx+xhci_pipe.Speed], eax
|
||||
; 2. Compute the root hub port, the route string and the tier of the device.
|
||||
movzx edx, [esi+usb_controller.ResettingPort]
|
||||
mov edi, [esi+usb_controller.ResettingHub]
|
||||
test edi, edi
|
||||
jnz .behind_hub
|
||||
mov eax, [esi+xhci_controller.PortMap-XCD+edx*4]
|
||||
mov [ebx+xhci_pipe.RootPort], eax
|
||||
if XHCI_SUPERSPEED
|
||||
mov eax, [esi+xhci_controller.ResettingPSIV-XCD]
|
||||
mov [ebx+xhci_pipe.PSIV], eax
|
||||
end if
|
||||
jmp .have_topology
|
||||
.behind_hub:
|
||||
; The parent hub is a device too, and its own pipe carries the topology data.
|
||||
mov eax, [edi+USB_HUB_CONFIGPIPE]
|
||||
sub eax, sizeof.xhci_pipe
|
||||
mov ecx, [eax+xhci_pipe.RootPort]
|
||||
mov [ebx+xhci_pipe.RootPort], ecx
|
||||
mov ecx, [eax+xhci_pipe.Depth]
|
||||
mov eax, [eax+xhci_pipe.Route]
|
||||
; The route string holds one nibble per tier, at most five of them.
|
||||
cmp ecx, 5
|
||||
jae .have_route
|
||||
push ecx edx
|
||||
shl ecx, 2
|
||||
inc edx ; the route uses 1-based port numbers
|
||||
cmp edx, 15
|
||||
jbe @f
|
||||
movi edx, 15
|
||||
@@:
|
||||
shl edx, cl
|
||||
or eax, edx
|
||||
pop edx ecx
|
||||
.have_route:
|
||||
inc ecx
|
||||
mov [ebx+xhci_pipe.Depth], ecx
|
||||
mov [ebx+xhci_pipe.Route], eax
|
||||
; 3. Low- and full-speed devices behind a high-speed hub need the address of
|
||||
; the Transaction Translator that serves them.
|
||||
cmp [ebx+xhci_pipe.Speed], USB_SPEED_HS
|
||||
jz .have_topology
|
||||
push ebx
|
||||
mov ecx, edx
|
||||
mov edx, edi
|
||||
invoke usbhc_api.usb_get_tt
|
||||
pop ebx
|
||||
test edx, edx
|
||||
jz .have_topology
|
||||
sub edx, sizeof.xhci_pipe
|
||||
mov eax, [edx+xhci_pipe.SlotId]
|
||||
mov [ebx+xhci_pipe.TTSlot], eax
|
||||
inc ecx
|
||||
mov [ebx+xhci_pipe.TTPort], ecx
|
||||
.have_topology:
|
||||
; 4. Ask the controller for a device slot.
|
||||
xor eax, eax
|
||||
push ebx
|
||||
xor ebx, ebx
|
||||
xor ecx, ecx
|
||||
mov edx, XHCI_TRB_ENABLE_SLOT shl 10
|
||||
call xhci_cmd_sync
|
||||
pop ebx
|
||||
cmp eax, XHCI_CC_SUCCESS
|
||||
jnz .fail
|
||||
test edx, edx
|
||||
jz .fail
|
||||
mov [ebx+xhci_pipe.SlotId], edx
|
||||
DEBUGF 1,'K : XHCI new device: slot %d, root port %d, route %x, speed %d\n',edx,[ebx+xhci_pipe.RootPort],[ebx+xhci_pipe.Route],[ebx+xhci_pipe.Speed]
|
||||
; 5. Hand the device over to the protocol layer. It opens the pipe of the
|
||||
; default control endpoint, and that is where the slot is really addressed.
|
||||
lea ecx, [ebx+sizeof.xhci_pipe]
|
||||
invoke usbhc_api.usb_new_device
|
||||
test eax, eax
|
||||
jnz .done
|
||||
; 6. The protocol layer has failed; release the slot again.
|
||||
mov edx, [ebx+xhci_pipe.SlotId]
|
||||
shl edx, 24
|
||||
or edx, XHCI_TRB_DISABLE_SLOT shl 10
|
||||
xor eax, eax
|
||||
xor ebx, ebx
|
||||
xor ecx, ecx
|
||||
call xhci_cmd_sync
|
||||
xor eax, eax
|
||||
jmp .done
|
||||
.fail:
|
||||
dbgstr 'XHCI: Enable Slot failed'
|
||||
xor eax, eax
|
||||
.done:
|
||||
add esp, sizeof.xhci_pipe + 4
|
||||
pop edi edx ecx ebx
|
||||
ret
|
||||
endp
|
||||
|
||||
; =============================================================================
|
||||
; ================================= Pipes =====================================
|
||||
; =============================================================================
|
||||
|
||||
proc xhci_alloc_pipe
|
||||
push ebx ecx edi
|
||||
mov ebx, xhci_ep_mutex
|
||||
invoke usbhc_api.usb_allocate_common, sizeof.xhci_pipe + sizeof.usb_pipe
|
||||
test eax, eax
|
||||
jz @f
|
||||
; Zero the whole block: the kernel may call FreePipe for a pipe whose InitPipe
|
||||
; has never run, and that path must not act on garbage.
|
||||
mov edi, eax
|
||||
push eax
|
||||
xor eax, eax
|
||||
movi ecx, (sizeof.xhci_pipe + sizeof.usb_pipe + 3)/4
|
||||
rep stosd
|
||||
pop eax
|
||||
add eax, sizeof.xhci_pipe
|
||||
@@:
|
||||
pop edi ecx ebx
|
||||
ret
|
||||
endp
|
||||
|
||||
proc xhci_free_pipe stdcall, ptr:dword
|
||||
push ebx esi edi
|
||||
mov ebx, [ptr]
|
||||
sub ebx, sizeof.xhci_pipe
|
||||
mov esi, [ebx+sizeof.xhci_pipe+usb_pipe.Controller]
|
||||
test esi, esi
|
||||
jz .free
|
||||
cmp [ebx+xhci_pipe.SlotId], 0
|
||||
jz .drop_pipe
|
||||
cmp [ebx+xhci_pipe.DCI], 1
|
||||
jnz .drop_pipe
|
||||
; This is the default control endpoint, that is, the handle of the whole
|
||||
; device: release the slot together with the per-device page.
|
||||
mov ecx, [ebx+xhci_pipe.SlotId]
|
||||
mov edx, ecx
|
||||
shl edx, 24
|
||||
or edx, XHCI_TRB_DISABLE_SLOT shl 10
|
||||
xor eax, eax
|
||||
push ebx
|
||||
xor ebx, ebx
|
||||
xor ecx, ecx
|
||||
call xhci_cmd_sync
|
||||
pop ebx
|
||||
; The controller may access the Device Context until the command above
|
||||
; completes, so only now may the DCBAA entry and the slot table forget it.
|
||||
mov ecx, [ebx+xhci_pipe.SlotId]
|
||||
mov edi, [esi+xhci_controller.CommonPage-XCD]
|
||||
and dword [edi+ecx*8], 0
|
||||
and dword [edi+ecx*8+4], 0
|
||||
and [esi+xhci_controller.SlotPages-XCD+ecx*4], 0
|
||||
mov eax, [ebx+xhci_pipe.DevPage]
|
||||
test eax, eax
|
||||
jz .drop_ring
|
||||
invoke KernelFree, eax
|
||||
and [ebx+xhci_pipe.DevPage], 0
|
||||
jmp .drop_ring
|
||||
.drop_pipe:
|
||||
; Remove the pipe from the per-device table, if it is still listed there.
|
||||
; On disconnect the kernel releases the pipes of a device in arbitrary order,
|
||||
; and the pipe of the default control endpoint - the owner of the per-device
|
||||
; page - may well be freed before this one, taking the page with it. The
|
||||
; authoritative pointer is the one in SlotPages: it is cleared when the slot
|
||||
; is released, so it can never point to freed memory.
|
||||
mov ecx, [ebx+xhci_pipe.SlotId]
|
||||
test ecx, ecx
|
||||
jz .drop_ring
|
||||
mov eax, [esi+xhci_controller.SlotPages-XCD+ecx*4]
|
||||
test eax, eax
|
||||
jz .drop_ring
|
||||
mov ecx, [ebx+xhci_pipe.DCI]
|
||||
cmp ecx, 32
|
||||
jae .drop_ring
|
||||
and dword [eax+XHCI_PIPES_OFS+ecx*4], 0
|
||||
.drop_ring:
|
||||
mov eax, [ebx+xhci_pipe.Ring]
|
||||
test eax, eax
|
||||
jz @f
|
||||
invoke KernelFree, eax
|
||||
and [ebx+xhci_pipe.Ring], 0
|
||||
@@:
|
||||
mov eax, [ebx+xhci_pipe.RingMap]
|
||||
test eax, eax
|
||||
jz .free
|
||||
invoke KernelFree, eax
|
||||
and [ebx+xhci_pipe.RingMap], 0
|
||||
.free:
|
||||
pop edi esi ebx
|
||||
mov eax, [ptr]
|
||||
sub eax, sizeof.xhci_pipe
|
||||
invoke usbhc_api.usb_free_common, eax
|
||||
ret
|
||||
endp
|
||||
|
||||
; Allocates the transfer ring of a pipe.
|
||||
; in: ebx -> xhci_pipe. out: eax = 0 on failure.
|
||||
proc xhci_alloc_ring
|
||||
push ecx edx
|
||||
call xhci_alloc_page
|
||||
test eax, eax
|
||||
jz .nothing
|
||||
mov [ebx+xhci_pipe.RingMap], eax
|
||||
call xhci_alloc_page
|
||||
test eax, eax
|
||||
jnz @f
|
||||
invoke KernelFree, [ebx+xhci_pipe.RingMap]
|
||||
and [ebx+xhci_pipe.RingMap], 0
|
||||
xor eax, eax
|
||||
jmp .nothing
|
||||
@@:
|
||||
mov [ebx+xhci_pipe.Ring], eax
|
||||
mov [ebx+xhci_pipe.RingPhys], edx
|
||||
; The last entry returns to the beginning of the ring and toggles the cycle.
|
||||
lea ecx, [eax+(XHCI_RING_TRBS-1)*16]
|
||||
mov [ecx], edx
|
||||
mov dword [ecx+12], (XHCI_TRB_LINK shl 10) + XHCI_TRB_TC
|
||||
and [ebx+xhci_pipe.Enqueue], 0
|
||||
and [ebx+xhci_pipe.Dequeue], 0
|
||||
and [ebx+xhci_pipe.Reserved], 0
|
||||
and [ebx+xhci_pipe.FirstFix], 0
|
||||
mov [ebx+xhci_pipe.Cycle], XHCI_TRB_C
|
||||
movi eax, 1
|
||||
.nothing:
|
||||
pop edx ecx
|
||||
ret
|
||||
endp
|
||||
|
||||
; Stores the pipe in the per-device table used by the event ring handler.
|
||||
; in: ebx -> xhci_pipe.
|
||||
proc xhci_register_pipe
|
||||
push eax ecx edx
|
||||
mov eax, [ebx+xhci_pipe.DevPage]
|
||||
test eax, eax
|
||||
jz @f
|
||||
mov ecx, [ebx+xhci_pipe.DCI]
|
||||
cmp ecx, 32
|
||||
jae @f
|
||||
lea edx, [ebx+sizeof.xhci_pipe]
|
||||
mov [eax+XHCI_PIPES_OFS+ecx*4], edx
|
||||
@@:
|
||||
pop edx ecx eax
|
||||
ret
|
||||
endp
|
||||
|
||||
; Computes the Interval field of the Endpoint Context of an interrupt endpoint.
|
||||
; The kernel passes bInterval from the endpoint descriptor: for high-speed
|
||||
; devices it is an exponent of 125 us periods, for low- and full-speed devices
|
||||
; it is a number of frames.
|
||||
; in: ebx -> xhci_pipe, eax = bInterval.
|
||||
proc xhci_calc_interval
|
||||
push eax ecx
|
||||
cmp [ebx+xhci_pipe.Speed], USB_SPEED_HS
|
||||
jnz .low_speed
|
||||
test eax, eax
|
||||
jz @f
|
||||
dec eax
|
||||
@@:
|
||||
jmp .clamp
|
||||
.low_speed:
|
||||
; One frame equals eight periods of 125 us, hence the offset of three.
|
||||
test eax, eax
|
||||
jnz @f
|
||||
movi eax, 1
|
||||
@@:
|
||||
bsr ecx, eax
|
||||
lea eax, [ecx+3]
|
||||
.clamp:
|
||||
cmp eax, 15
|
||||
jbe @f
|
||||
movi eax, 15
|
||||
@@:
|
||||
mov [ebx+xhci_pipe.Interval], eax
|
||||
pop ecx eax
|
||||
ret
|
||||
endp
|
||||
|
||||
; Called from usb_open_pipe.
|
||||
; in: edi -> usb_pipe for the target, ecx -> usb_pipe of the config pipe,
|
||||
; esi -> usb_controller, eax -> usb_gtd of the first descriptor,
|
||||
; [ebp+12] = endpoint, [ebp+16] = maxpacket, [ebp+20] = type,
|
||||
; [ebp+24] = interval.
|
||||
; out: eax = 0 on failure.
|
||||
proc xhci_init_pipe
|
||||
virtual at ebp+8
|
||||
.config_pipe dd ?
|
||||
.endpoint dd ?
|
||||
.maxpacket dd ?
|
||||
.type dd ?
|
||||
.interval dd ?
|
||||
end virtual
|
||||
push ebx
|
||||
sub edi, sizeof.xhci_pipe
|
||||
sub ecx, sizeof.xhci_pipe
|
||||
mov ebx, edi ; ebx -> xhci_pipe being initialized
|
||||
; 1. Copy the description of the device from the config pipe.
|
||||
mov eax, [ecx+xhci_pipe.SlotId]
|
||||
mov [ebx+xhci_pipe.SlotId], eax
|
||||
mov eax, [ecx+xhci_pipe.DevPage]
|
||||
mov [ebx+xhci_pipe.DevPage], eax
|
||||
mov eax, [ecx+xhci_pipe.DevPagePhys]
|
||||
mov [ebx+xhci_pipe.DevPagePhys], eax
|
||||
mov eax, [ecx+xhci_pipe.Speed]
|
||||
mov [ebx+xhci_pipe.Speed], eax
|
||||
mov eax, [ecx+xhci_pipe.RootPort]
|
||||
mov [ebx+xhci_pipe.RootPort], eax
|
||||
mov eax, [ecx+xhci_pipe.Route]
|
||||
mov [ebx+xhci_pipe.Route], eax
|
||||
mov eax, [ecx+xhci_pipe.Depth]
|
||||
mov [ebx+xhci_pipe.Depth], eax
|
||||
mov eax, [ecx+xhci_pipe.TTSlot]
|
||||
mov [ebx+xhci_pipe.TTSlot], eax
|
||||
mov eax, [ecx+xhci_pipe.TTPort]
|
||||
mov [ebx+xhci_pipe.TTPort], eax
|
||||
if XHCI_SUPERSPEED
|
||||
mov eax, [ecx+xhci_pipe.PSIV]
|
||||
mov [ebx+xhci_pipe.PSIV], eax
|
||||
end if
|
||||
; 2. Work out the Device Context Index and the endpoint type.
|
||||
mov eax, [.endpoint]
|
||||
test eax, eax
|
||||
jz .control_ep
|
||||
mov ecx, eax
|
||||
and ecx, 15
|
||||
add ecx, ecx
|
||||
test al, 80h
|
||||
jz @f
|
||||
inc ecx
|
||||
or [ebx+xhci_pipe.Flags], XHCI_PIPE_IN
|
||||
@@:
|
||||
mov [ebx+xhci_pipe.DCI], ecx
|
||||
mov eax, [.type]
|
||||
cmp eax, BULK_PIPE
|
||||
jz .bulk
|
||||
cmp eax, INTERRUPT_PIPE
|
||||
jz .interrupt
|
||||
; A control endpoint other than endpoint zero is unusual but legal.
|
||||
mov [ebx+xhci_pipe.EpType], XHCI_EP_CONTROL
|
||||
jmp .have_type
|
||||
.bulk:
|
||||
movi eax, XHCI_EP_BULK_OUT
|
||||
test [ebx+xhci_pipe.Flags], XHCI_PIPE_IN
|
||||
jz @f
|
||||
movi eax, XHCI_EP_BULK_IN
|
||||
@@:
|
||||
mov [ebx+xhci_pipe.EpType], eax
|
||||
jmp .have_type
|
||||
.interrupt:
|
||||
movi eax, XHCI_EP_INT_OUT
|
||||
test [ebx+xhci_pipe.Flags], XHCI_PIPE_IN
|
||||
jz @f
|
||||
movi eax, XHCI_EP_INT_IN
|
||||
@@:
|
||||
mov [ebx+xhci_pipe.EpType], eax
|
||||
mov eax, [.interval]
|
||||
call xhci_calc_interval
|
||||
.have_type:
|
||||
mov eax, [.maxpacket]
|
||||
mov [ebx+xhci_pipe.MaxPacket], eax
|
||||
if XHCI_SUPERSPEED
|
||||
call xhci_ss_get_burst
|
||||
end if
|
||||
jmp .alloc_ring
|
||||
.control_ep:
|
||||
; The default control endpoint always has index one. Until the real packet size
|
||||
; is known from the device descriptor, use the value the specification requires
|
||||
; for the speed of the device: the kernel asks for 64 regardless of the speed,
|
||||
; which is wrong for low- and full-speed devices.
|
||||
mov [ebx+xhci_pipe.DCI], 1
|
||||
mov [ebx+xhci_pipe.EpType], XHCI_EP_CONTROL
|
||||
movi eax, 64
|
||||
cmp [ebx+xhci_pipe.Speed], USB_SPEED_HS
|
||||
jz @f
|
||||
movi eax, 8
|
||||
@@:
|
||||
if XHCI_SUPERSPEED
|
||||
; A SuperSpeed device always uses 512 bytes on the default control endpoint.
|
||||
cmp [ebx+xhci_pipe.PSIV], XHCI_PSI_SS
|
||||
jb @f
|
||||
mov eax, 512
|
||||
@@:
|
||||
end if
|
||||
mov [ebx+xhci_pipe.MaxPacket], eax
|
||||
.alloc_ring:
|
||||
; 3. Allocate the transfer ring.
|
||||
call xhci_alloc_ring
|
||||
test eax, eax
|
||||
jz .fail
|
||||
; 4. Choose the software list the pipe belongs to and insert it there. The
|
||||
; hardware knows nothing about these lists; they exist only so that the kernel
|
||||
; can walk all pipes and reinsert an aborted one.
|
||||
lea edx, [esi+xhci_controller.ControlED-XCD]
|
||||
cmp [.type], BULK_PIPE
|
||||
jb @f
|
||||
lea edx, [esi+xhci_controller.BulkED-XCD]
|
||||
jz @f
|
||||
lea edx, [esi+xhci_controller.IntED-XCD]
|
||||
@@:
|
||||
lea edi, [ebx+sizeof.xhci_pipe]
|
||||
mov [edi+usb_pipe.BaseList], edx
|
||||
mov ecx, [edx+usb_pipe.NextVirt]
|
||||
mov [edi+usb_pipe.NextVirt], ecx
|
||||
mov [edi+usb_pipe.PrevVirt], edx
|
||||
mov [ecx+usb_pipe.PrevVirt], edi
|
||||
mov [edx+usb_pipe.NextVirt], edi
|
||||
; 5. Now do the hardware part.
|
||||
cmp [.endpoint], 0
|
||||
jz .address_device
|
||||
call xhci_register_pipe
|
||||
mov edi, [.config_pipe]
|
||||
sub edi, sizeof.xhci_pipe
|
||||
call xhci_configure_endpoint
|
||||
xhci_trace 'K : XHCI open pipe: slot %d dci %d\n', [ebx+xhci_pipe.SlotId], [ebx+xhci_pipe.DCI]
|
||||
cmp eax, XHCI_CC_SUCCESS
|
||||
jz .success
|
||||
DEBUGF 1,'K : XHCI: Configure Endpoint failed, code %d\n',eax
|
||||
jmp .unlink_fail
|
||||
.address_device:
|
||||
; 6. This is a new device: allocate its Device Context, publish the slot and
|
||||
; let the controller give the device a bus address.
|
||||
call xhci_alloc_page
|
||||
test eax, eax
|
||||
jz .unlink_fail
|
||||
mov [ebx+xhci_pipe.DevPage], eax
|
||||
mov [ebx+xhci_pipe.DevPagePhys], edx
|
||||
mov ecx, [ebx+xhci_pipe.SlotId]
|
||||
mov [esi+xhci_controller.SlotPages-XCD+ecx*4], eax
|
||||
call xhci_register_pipe
|
||||
call xhci_address_device
|
||||
test eax, eax
|
||||
jz .free_devpage
|
||||
.success:
|
||||
; usb_open_pipe keeps the pointer to the new pipe in edi across this call, so
|
||||
; it has to be handed back untouched; the branch above has overwritten it with
|
||||
; the pipe of the default control endpoint.
|
||||
lea edi, [ebx+sizeof.xhci_pipe]
|
||||
pop ebx
|
||||
movi eax, 1
|
||||
ret
|
||||
.free_devpage:
|
||||
mov ecx, [ebx+xhci_pipe.SlotId]
|
||||
and [esi+xhci_controller.SlotPages-XCD+ecx*4], 0
|
||||
mov eax, [ebx+xhci_pipe.DevPage]
|
||||
invoke KernelFree, eax
|
||||
and [ebx+xhci_pipe.DevPage], 0
|
||||
.unlink_fail:
|
||||
; Undo the insertion into the software list before failing.
|
||||
lea edi, [ebx+sizeof.xhci_pipe]
|
||||
mov eax, [edi+usb_pipe.NextVirt]
|
||||
mov edx, [edi+usb_pipe.PrevVirt]
|
||||
mov [eax+usb_pipe.PrevVirt], edx
|
||||
mov [edx+usb_pipe.NextVirt], eax
|
||||
.fail:
|
||||
lea edi, [ebx+sizeof.xhci_pipe]
|
||||
pop ebx
|
||||
xor eax, eax
|
||||
ret
|
||||
endp
|
||||
|
||||
; Removes the pipe from the hardware configuration of the device.
|
||||
; in: esi -> usb_controller, ebx -> usb_pipe.
|
||||
proc xhci_unlink_pipe
|
||||
pushad
|
||||
sub ebx, sizeof.xhci_pipe
|
||||
cmp [ebx+xhci_pipe.SlotId], 0
|
||||
jz .nothing
|
||||
cmp [ebx+xhci_pipe.DCI], 1
|
||||
jz .nothing ; the slot itself is released by FreePipe
|
||||
call xhci_ctrl_pipe
|
||||
test eax, eax
|
||||
jz .nothing
|
||||
mov edi, eax ; edi -> pipe of endpoint zero
|
||||
lea ecx, [esi+xhci_controller.CmdLock-XCD]
|
||||
invoke MutexLock
|
||||
call xhci_clear_input_ctx
|
||||
mov ecx, [ebx+xhci_pipe.DCI]
|
||||
movi eax, 1
|
||||
shl eax, cl
|
||||
mov edx, [esi+xhci_controller.InputCtx-XCD]
|
||||
mov [edx], eax ; drop this endpoint
|
||||
mov dword [edx+4], 1 ; keep the Slot Context
|
||||
mov ecx, [edi+xhci_pipe.MaxDCI]
|
||||
test ecx, ecx
|
||||
jnz @f
|
||||
movi ecx, 1
|
||||
@@:
|
||||
push ebx
|
||||
mov ebx, edi
|
||||
call xhci_fill_slot_ctx
|
||||
pop ebx
|
||||
mov edx, [ebx+xhci_pipe.SlotId]
|
||||
shl edx, 24
|
||||
or edx, XHCI_TRB_CONFIG_EP shl 10
|
||||
mov eax, [esi+xhci_controller.InputCtxPhys-XCD]
|
||||
xor ebx, ebx
|
||||
xor ecx, ecx
|
||||
call xhci_cmd_submit
|
||||
lea ecx, [esi+xhci_controller.CmdLock-XCD]
|
||||
invoke MutexUnlock
|
||||
.nothing:
|
||||
popad
|
||||
ret
|
||||
endp
|
||||
|
||||
; Temporarily removes the pipe from the hardware schedule.
|
||||
; in: esi -> usb_controller, ebx -> usb_pipe.
|
||||
proc xhci_disable_pipe
|
||||
pushad
|
||||
sub ebx, sizeof.xhci_pipe
|
||||
cmp [ebx+xhci_pipe.SlotId], 0
|
||||
jz .nothing
|
||||
mov ecx, [ebx+xhci_pipe.DCI]
|
||||
shl ecx, 16
|
||||
mov edx, [ebx+xhci_pipe.SlotId]
|
||||
shl edx, 24
|
||||
or edx, ecx
|
||||
or edx, XHCI_TRB_STOP_EP shl 10
|
||||
xor eax, eax
|
||||
xor ebx, ebx
|
||||
xor ecx, ecx
|
||||
call xhci_cmd_sync
|
||||
.nothing:
|
||||
popad
|
||||
ret
|
||||
endp
|
||||
|
||||
; Reinserts the pipe into the hardware schedule after xhci_disable_pipe, with
|
||||
; an empty transfer queue.
|
||||
; in: esi -> usb_controller, ebx -> usb_pipe,
|
||||
; edx -> current descriptor, eax -> new last descriptor.
|
||||
proc xhci_enable_pipe
|
||||
pushad
|
||||
sub ebx, sizeof.xhci_pipe
|
||||
mov eax, [ebx+xhci_pipe.Ring]
|
||||
test eax, eax
|
||||
jz .nothing
|
||||
; The queue is empty now, so the ring can be restarted from its beginning.
|
||||
mov edi, eax
|
||||
xor eax, eax
|
||||
mov ecx, 0x1000/4
|
||||
rep stosd
|
||||
mov edi, [ebx+xhci_pipe.RingMap]
|
||||
mov ecx, 0x1000/4
|
||||
rep stosd
|
||||
mov edi, [ebx+xhci_pipe.Ring]
|
||||
add edi, (XHCI_RING_TRBS-1)*16
|
||||
mov eax, [ebx+xhci_pipe.RingPhys]
|
||||
mov [edi], eax
|
||||
mov dword [edi+12], (XHCI_TRB_LINK shl 10) + XHCI_TRB_TC
|
||||
and [ebx+xhci_pipe.Enqueue], 0
|
||||
and [ebx+xhci_pipe.Dequeue], 0
|
||||
and [ebx+xhci_pipe.Reserved], 0
|
||||
and [ebx+xhci_pipe.FirstFix], 0
|
||||
mov [ebx+xhci_pipe.Cycle], XHCI_TRB_C
|
||||
call xhci_set_dequeue
|
||||
.nothing:
|
||||
popad
|
||||
ret
|
||||
endp
|
||||
|
||||
; =============================================================================
|
||||
; ========================== Address and packet size ==========================
|
||||
; =============================================================================
|
||||
|
||||
; Called from usb_set_address_callback. The bus address is chosen by the
|
||||
; controller itself while executing the Address Device command, so the only
|
||||
; thing left to do is to remember the number the kernel has reserved: it asks
|
||||
; for it back on disconnect in order to mark it free again.
|
||||
; in: esi -> usb_controller, ebx -> usb_pipe, cl = address.
|
||||
proc xhci_set_device_address
|
||||
movzx eax, cl
|
||||
mov [ebx+xhci_pipe.Address-sizeof.xhci_pipe], eax
|
||||
jmp [usbhc_api.usb_subscribe_control]
|
||||
endp
|
||||
|
||||
; in: esi -> usb_controller, ebx -> usb_pipe. out: eax = address.
|
||||
proc xhci_get_device_address
|
||||
mov eax, [ebx+xhci_pipe.Address-sizeof.xhci_pipe]
|
||||
ret
|
||||
endp
|
||||
|
||||
; Called from usb_get_descr8_callback once the real packet size of the default
|
||||
; control endpoint is known. On xHCI that value lives in the Endpoint Context,
|
||||
; so an Evaluate Context command is needed to update it.
|
||||
; in: esi -> usb_controller, ebx -> usb_pipe, ecx = packet size.
|
||||
proc xhci_set_endpoint_packet_size
|
||||
push ebx ecx edx edi
|
||||
sub ebx, sizeof.xhci_pipe
|
||||
if XHCI_SUPERSPEED
|
||||
; For a SuperSpeed device bMaxPacketSize0 is an exponent, and the only value
|
||||
; the specification allows is 9: use 512 directly instead of the raw byte.
|
||||
cmp [ebx+xhci_pipe.PSIV], XHCI_PSI_SS
|
||||
jb @f
|
||||
mov ecx, 512
|
||||
@@:
|
||||
end if
|
||||
mov [ebx+xhci_pipe.MaxPacket], ecx
|
||||
lea ecx, [esi+xhci_controller.CmdLock-XCD]
|
||||
invoke MutexLock
|
||||
call xhci_clear_input_ctx
|
||||
mov edx, [esi+xhci_controller.InputCtx-XCD]
|
||||
mov dword [edx+4], 2 ; evaluate the default control endpoint
|
||||
call xhci_fill_ep_ctx
|
||||
mov edx, [ebx+xhci_pipe.SlotId]
|
||||
shl edx, 24
|
||||
or edx, XHCI_TRB_EVAL_CTX shl 10
|
||||
mov eax, [esi+xhci_controller.InputCtxPhys-XCD]
|
||||
push ebx
|
||||
xor ebx, ebx
|
||||
xor ecx, ecx
|
||||
call xhci_cmd_submit
|
||||
pop ebx
|
||||
cmp eax, XHCI_CC_SUCCESS
|
||||
jz @f
|
||||
DEBUGF 1,'K : XHCI: Evaluate Context failed, code %d\n',eax
|
||||
@@:
|
||||
lea ecx, [esi+xhci_controller.CmdLock-XCD]
|
||||
invoke MutexUnlock
|
||||
pop edi edx ecx ebx
|
||||
jmp [usbhc_api.usb_subscribe_control]
|
||||
endp
|
||||
|
||||
; If the descriptor that has just completed is the answer to a request for the
|
||||
; hub descriptor, tell the controller that the device is a hub: it has to know
|
||||
; that in order to serve the devices behind it.
|
||||
; in: ebx -> usb_gtd.
|
||||
proc xhci_check_hub_descriptor
|
||||
pushad
|
||||
cmp [ebx+usb_gtd.Callback], 0
|
||||
jz .nothing
|
||||
mov eax, [ebx+usb_gtd.Pipe]
|
||||
mov esi, [eax+usb_pipe.Controller]
|
||||
sub eax, sizeof.xhci_pipe
|
||||
test [eax+xhci_pipe.Flags], XHCI_PIPE_HUBPEND
|
||||
jz .nothing
|
||||
and [eax+xhci_pipe.Flags], not XHCI_PIPE_HUBPEND
|
||||
cmp [ebx+xhci_gtd.Status-sizeof.xhci_gtd], XHCI_CC_SUCCESS
|
||||
jnz .nothing
|
||||
mov edx, [eax+xhci_pipe.HubBuf]
|
||||
test edx, edx
|
||||
jz .nothing
|
||||
cmp byte [edx+1], 29h ; bDescriptorType
|
||||
jnz .nothing
|
||||
or [eax+xhci_pipe.Flags], XHCI_PIPE_ISHUB
|
||||
mov ebx, eax ; ebx -> xhci_pipe of the hub
|
||||
movzx edi, byte [edx+2] ; bNbrPorts
|
||||
movzx ebp, byte [edx+3] ; low byte of wHubCharacteristics
|
||||
shr ebp, 5
|
||||
and ebp, 3 ; Transaction Translator Think Time
|
||||
DEBUGF 1,'K : XHCI: device on slot %d is a hub with %d ports\n',[ebx+xhci_pipe.SlotId],edi
|
||||
lea ecx, [esi+xhci_controller.CmdLock-XCD]
|
||||
invoke MutexLock
|
||||
call xhci_clear_input_ctx
|
||||
mov eax, [esi+xhci_controller.InputCtx-XCD]
|
||||
mov dword [eax+4], 1 ; only the Slot Context is evaluated
|
||||
mov ecx, [ebx+xhci_pipe.MaxDCI]
|
||||
test ecx, ecx
|
||||
jnz @f
|
||||
movi ecx, 1
|
||||
@@:
|
||||
call xhci_fill_slot_ctx
|
||||
; Patch the Slot Context with the fields that describe a hub. Only Configure
|
||||
; Endpoint takes them into account, Evaluate Context would ignore them.
|
||||
mov eax, [esi+xhci_controller.InputCtx-XCD]
|
||||
movi ecx, 1
|
||||
call xhci_context
|
||||
or dword [eax], 1 shl 26 ; this device is a hub
|
||||
cmp [ebx+xhci_pipe.Speed], USB_SPEED_HS
|
||||
jnz @f
|
||||
shl ebp, 16
|
||||
or [eax+8], ebp
|
||||
@@:
|
||||
shl edi, 24
|
||||
or [eax+4], edi ; Number of Ports
|
||||
mov edx, [ebx+xhci_pipe.SlotId]
|
||||
shl edx, 24
|
||||
or edx, XHCI_TRB_CONFIG_EP shl 10
|
||||
mov eax, [esi+xhci_controller.InputCtxPhys-XCD]
|
||||
xor ebx, ebx
|
||||
xor ecx, ecx
|
||||
call xhci_cmd_submit
|
||||
cmp eax, XHCI_CC_SUCCESS
|
||||
jz @f
|
||||
DEBUGF 1,'K : XHCI: cannot mark the device as a hub, code %d\n',eax
|
||||
@@:
|
||||
lea ecx, [esi+xhci_controller.CmdLock-XCD]
|
||||
invoke MutexUnlock
|
||||
.nothing:
|
||||
popad
|
||||
ret
|
||||
endp
|
||||
@@ -1,135 +0,0 @@
|
||||
; SuperSpeed support for the xHCI driver, included from xhci.asm when
|
||||
; XHCI_SUPERSPEED is enabled. The pieces too small to live here - the port
|
||||
; map, the Slot Context speed, the 512-byte default control endpoint, the
|
||||
; Max Burst field of the Endpoint Context - sit in the other files under
|
||||
; "if XHCI_SUPERSPEED" guards; this file keeps the self-contained procedures.
|
||||
;
|
||||
; The kernel USB stack knows nothing about SuperSpeed, so it never learns
|
||||
; about it: a SuperSpeed device is announced as a high-speed one, which also
|
||||
; keeps the Transaction Translator logic away from it. The raw PORTSC speed
|
||||
; identifier travels in xhci_pipe.PSIV instead and reaches everything that
|
||||
; really needs it. SuperSpeed hubs are not supported: the kernel only speaks
|
||||
; the USB2 hub protocol, so a device behind a USB3 hub is served by the USB2
|
||||
; half of that hub at high speed.
|
||||
|
||||
; =============================================================================
|
||||
; ============================ SuperSpeed ports ===============================
|
||||
; =============================================================================
|
||||
|
||||
; Called from xhci_new_port for a SuperSpeed root port instead of the USB2
|
||||
; reset entry point: a SuperSpeed link trains itself and the port enables
|
||||
; itself on connect, reporting the speed with no reset at all. When the link
|
||||
; is already up, skip straight to the reset recovery stage, after which
|
||||
; xhci_port_init picks the device up; otherwise try a warm reset.
|
||||
; in: esi -> usb_controller, ecx = port index.
|
||||
proc xhci_ss_start_port
|
||||
push eax edx
|
||||
and [esi+usb_controller.ResettingHub], 0
|
||||
mov [esi+usb_controller.ResettingPort], cl
|
||||
push ecx
|
||||
invoke GetTimerTicks
|
||||
pop ecx
|
||||
mov [esi+usb_controller.ResetTime], eax
|
||||
mov [esi+xhci_controller.ResetStart-XCD], eax
|
||||
call xhci_port_reg
|
||||
mov eax, [edx]
|
||||
test al, XHCI_PORT_PED
|
||||
jz .warm_reset
|
||||
mov [esi+usb_controller.ResettingStatus], 2
|
||||
DEBUGF 1,'K : XHCI %x: SS port %d link is up, PORTSC=%x\n',esi,ecx,eax
|
||||
jmp .nothing
|
||||
.warm_reset:
|
||||
; Connected, but the link has not come up. The Port Reset bit is set while a
|
||||
; warm reset is running, so the ordinary reset-wait machinery in
|
||||
; xhci_port_reset_done serves this case unchanged; the extra WRC change bit is
|
||||
; acknowledged there together with the usual ones.
|
||||
mov dword [edx], XHCI_PORT_PP + XHCI_PORT_WPR
|
||||
mov [esi+usb_controller.ResettingStatus], 1
|
||||
DEBUGF 1,'K : XHCI %x: warm-resetting port %d, PORTSC=%x\n',esi,ecx,eax
|
||||
.nothing:
|
||||
pop edx eax
|
||||
ret
|
||||
endp
|
||||
|
||||
; The kernel restarts pending root ports through the NewPortReset entry of
|
||||
; usb_hardware_func directly, bypassing xhci_new_port; SuperSpeed ports must
|
||||
; not get the USB2 reset on that path either, so the entry points here.
|
||||
; in: esi -> usb_controller, ecx = port index.
|
||||
proc xhci_ss_port_reset
|
||||
bt [esi+xhci_controller.SSPortMask-XCD], ecx
|
||||
jnc xhci_new_port.reset
|
||||
call xhci_ss_start_port
|
||||
ret
|
||||
endp
|
||||
|
||||
; =============================================================================
|
||||
; ===================== Endpoint Companion descriptors ========================
|
||||
; =============================================================================
|
||||
|
||||
; Reads the SuperSpeed Endpoint Companion descriptor of a bulk endpoint and
|
||||
; keeps its bMaxBurst for the Endpoint Context, allowing bursts of up to
|
||||
; bMaxBurst+1 packets per transaction. Zero (no bursts) is always legal, so
|
||||
; any failure just leaves the field alone. Only bulk endpoints are considered:
|
||||
; a nonzero burst on a periodic endpoint would also require the Max ESIT
|
||||
; Payload fields, and real interrupt endpoints do not burst anyway.
|
||||
; Relies on the stack frame of usb_open_pipe exactly like xhci_init_pipe does:
|
||||
; [ebp+8] is the config pipe of the device.
|
||||
; in: ebx -> xhci_pipe of a non-control endpoint being opened.
|
||||
proc xhci_ss_get_burst
|
||||
push eax ecx edx edi
|
||||
; 1. Only SuperSpeed bulk endpoints are of interest.
|
||||
cmp [ebx+xhci_pipe.PSIV], XHCI_PSI_SS
|
||||
jb .nothing
|
||||
mov eax, [ebx+xhci_pipe.EpType]
|
||||
and al, 3
|
||||
cmp al, 2 ; bulk endpoint types are 2 and 6
|
||||
jnz .nothing
|
||||
; 2. Find the configuration data kept by the kernel behind the device
|
||||
; descriptor; it holds the endpoint descriptors with their companions.
|
||||
mov eax, [ebp+8]
|
||||
mov eax, [eax+usb_pipe.DeviceData]
|
||||
test eax, eax
|
||||
jz .nothing
|
||||
movzx edx, [eax+usb_device_data.DeviceDescrSize]
|
||||
mov edi, [eax+usb_device_data.ConfigDataSize]
|
||||
lea ecx, [eax+edx+usb_device_data.DeviceDescriptor]
|
||||
add edi, ecx ; edi -> end of the configuration data
|
||||
; 3. Reconstruct bEndpointAddress from the Device Context Index.
|
||||
mov edx, [ebx+xhci_pipe.DCI]
|
||||
shr edx, 1
|
||||
test [ebx+xhci_pipe.Flags], XHCI_PIPE_IN
|
||||
jz @f
|
||||
or dl, 80h
|
||||
@@:
|
||||
; 4. Walk the descriptors to the one of this endpoint.
|
||||
.walk:
|
||||
lea eax, [ecx+2]
|
||||
cmp eax, edi
|
||||
ja .nothing
|
||||
movzx eax, byte [ecx] ; bLength
|
||||
test eax, eax
|
||||
jz .nothing ; malformed data, stop
|
||||
cmp byte [ecx+1], 5 ; an endpoint descriptor?
|
||||
jnz .advance
|
||||
cmp [ecx+2], dl ; bEndpointAddress
|
||||
jnz .advance
|
||||
; 5. The companion descriptor (type 30h) immediately follows its endpoint.
|
||||
add ecx, eax
|
||||
lea eax, [ecx+3]
|
||||
cmp eax, edi
|
||||
ja .nothing
|
||||
cmp byte [ecx+1], 30h ; SuperSpeed Endpoint Companion
|
||||
jnz .nothing
|
||||
movzx eax, byte [ecx+2] ; bMaxBurst
|
||||
cmp eax, 15
|
||||
ja .nothing
|
||||
mov [ebx+xhci_pipe.MaxBurst], eax
|
||||
DEBUGF 1,'K : XHCI: slot %d dci %d bursts %d+1 packets\n',[ebx+xhci_pipe.SlotId],[ebx+xhci_pipe.DCI],eax
|
||||
jmp .nothing
|
||||
.advance:
|
||||
add ecx, eax
|
||||
jmp .walk
|
||||
.nothing:
|
||||
pop edi edx ecx eax
|
||||
ret
|
||||
endp
|
||||
File diff suppressed because it is too large.
Load diff
@@ -842,7 +842,8 @@ disk_scan_partitions:
|
||||
cmp ebx, mbr_buffer
|
||||
jz .release_partition_buffer
|
||||
; 15b. If we have allocated it, free it.
|
||||
stdcall kernel_free, ebx
|
||||
xchg eax, ebx
|
||||
call free
|
||||
jmp .nothing
|
||||
; 15c. Otherwise, release reference.
|
||||
.release_partition_buffer:
|
||||
|
||||
@@ -18,7 +18,24 @@ saverd_fileinfo:
|
||||
.name:
|
||||
dd ?
|
||||
endg
|
||||
sysfn_saveramdisk: ; 18.6 = SAVE FLOPPY IMAGE (HD version only)
|
||||
sysfn_saveramdisk: ; 18.6 = SAVE RAMDISK IMAGE
|
||||
; ecx -> path to the image file; ecx = 0 - write the image back to the
|
||||
; medium it was booted from (a floppy or the file found by rdload.inc)
|
||||
test ecx, ecx
|
||||
jnz .have_path
|
||||
if ~ defined extended_primary_loader
|
||||
mov ecx, read_image_fsinfo.name
|
||||
cmp [BOOT.rd_load_from], RD_LOAD_FROM_HD
|
||||
je .have_path
|
||||
end if
|
||||
movi eax, ERROR_UNSUPPORTED_FS
|
||||
cmp [BOOT.rd_load_from], RD_LOAD_FROM_FLOPPY
|
||||
jne .done
|
||||
mov ebx, 1
|
||||
call save_image
|
||||
imul eax, ERROR_DEVICE ; 0 -> 0, 1 -> ERROR_DEVICE
|
||||
jmp .done
|
||||
.have_path:
|
||||
mov ebx, saverd_fileinfo
|
||||
mov [ebx+21], ecx
|
||||
mov eax, [ramdisk_actual_size]
|
||||
@@ -27,5 +44,6 @@ sysfn_saveramdisk: ; 18.6 = SAVE FLOPPY IMAGE (HD version only)
|
||||
pushad
|
||||
call file_system_lfn_protected ;in ebx
|
||||
popad
|
||||
.done:
|
||||
mov [esp+32], eax
|
||||
ret
|
||||
@@ -183,8 +183,6 @@ EFLAGS_ID = 0x200000 ; id flag
|
||||
IRQ_PIC = 0
|
||||
IRQ_APIC = 1
|
||||
|
||||
IO_MAP_SIZE = 65536/8 ; 8192 or 2 PAGE_SIZE
|
||||
|
||||
struct TSS
|
||||
_back rw 2
|
||||
_esp0 rd 1
|
||||
@@ -292,9 +290,6 @@ sys_proc = OS_BASE + 0x008E000
|
||||
|
||||
SLOT_BASE = OS_BASE + 0x0090000
|
||||
|
||||
APPDATA_IDLE_THREAD = SLOT_BASE + sizeof.APPDATA*1 ; poiner to IDLE thread
|
||||
APPDATA_OS_THREAD = SLOT_BASE + sizeof.APPDATA*2 ; poiner to OS thread
|
||||
|
||||
VGABasePtr = OS_BASE + 0x00A0000
|
||||
|
||||
virtual at OS_BASE + 0x05FFF80
|
||||
@@ -575,7 +570,7 @@ struct APPDATA
|
||||
ipc_start dd ? ;+160
|
||||
ipc_size dd ? ;+164
|
||||
occurred_events dd ? ;+168 ; mask which accumulates occurred events
|
||||
debugger_thread dd ? ;+172 ; pointer to APPDATA or 0
|
||||
debugger_slot dd ? ;+172 ; index in SLOT_BASE array
|
||||
terminate_protection dd ? ;+176
|
||||
keyboard_mode db ? ;+180
|
||||
rb 3
|
||||
|
||||
+77
-41
@@ -8,8 +8,8 @@
|
||||
|
||||
; diamond, 2006
|
||||
sys_debug_services:
|
||||
cmp ebx, sys_debug_services_table.count
|
||||
jae @f
|
||||
cmp ebx, 9
|
||||
ja @f
|
||||
jmp dword [sys_debug_services_table + ebx*4]
|
||||
@@:
|
||||
ret
|
||||
@@ -26,9 +26,7 @@ sys_debug_services_table:
|
||||
dd debug_write_process_memory
|
||||
dd debug_terminate
|
||||
dd debug_set_drx
|
||||
.count = ($ - sys_debug_services_table)/4
|
||||
endg
|
||||
|
||||
debug_set_event_data:
|
||||
; in: ecx = pointer
|
||||
; destroys eax
|
||||
@@ -36,20 +34,22 @@ debug_set_event_data:
|
||||
mov [eax + APPDATA.dbg_event_mem], ecx
|
||||
ret
|
||||
|
||||
get_debuggee_thread:
|
||||
get_debuggee_slot:
|
||||
; in: ecx=PID
|
||||
; out: CF=1 if error
|
||||
; CF=0 and eax = pointer to APPDATA if ok
|
||||
; CF=0 and eax=slot*0x20 if ok
|
||||
; out: interrupts disabled
|
||||
cli
|
||||
mov eax, ecx
|
||||
call pid_to_thread
|
||||
call pid_to_slot
|
||||
;call pid_to_appdata
|
||||
test eax, eax
|
||||
jz .ret_bad
|
||||
|
||||
shl eax, BSF sizeof.APPDATA
|
||||
push ebx
|
||||
mov ebx, [current_slot]
|
||||
cmp [eax + APPDATA.debugger_thread], ebx
|
||||
mov ebx, [current_slot_idx]
|
||||
cmp [SLOT_BASE + eax + APPDATA.debugger_slot], ebx
|
||||
;cmp [eax + APPDATA.debugger_slot], ebx
|
||||
pop ebx
|
||||
jnz .ret_bad
|
||||
; clc ; automatically
|
||||
@@ -61,9 +61,10 @@ get_debuggee_thread:
|
||||
debug_detach:
|
||||
; in: ecx=pid
|
||||
; destroys eax,ebx
|
||||
call get_debuggee_thread
|
||||
call get_debuggee_slot
|
||||
jc .ret
|
||||
and dword [eax + APPDATA.debugger_thread], 0
|
||||
and dword [eax + SLOT_BASE + APPDATA.debugger_slot], 0
|
||||
;and dword [eax + APPDATA.debugger_slot], 0
|
||||
call do_resume
|
||||
.ret:
|
||||
sti
|
||||
@@ -71,27 +72,40 @@ debug_detach:
|
||||
|
||||
debug_terminate:
|
||||
; in: ecx=pid
|
||||
call get_debuggee_thread
|
||||
call get_debuggee_slot
|
||||
jc debug_detach.ret
|
||||
mov ecx, eax
|
||||
|
||||
movzx ecx, ch ; del when sysfn_term... will using APPDATA
|
||||
shr ecx, BSF sizeof.APPDATA
|
||||
;movzx ecx, ch ; del when sysfn_term... will using APPDATA
|
||||
|
||||
; push 2
|
||||
; pop ebx
|
||||
mov edx, esi ; what?
|
||||
jmp sysfn_terminate
|
||||
|
||||
debug_suspend:
|
||||
; in: ecx=pid
|
||||
; destroys eax,ecx
|
||||
call get_debuggee_thread
|
||||
; { Patch by Coldy (rev. 7125), reason: http://board.kolibrios.org/viewtopic.php?f=1&t=1712&p=75957#p75957
|
||||
; cli
|
||||
; mov eax, ecx
|
||||
; call pid_to_slot
|
||||
; shl eax, 5
|
||||
; jz .ret
|
||||
call get_debuggee_slot
|
||||
jc .ret
|
||||
|
||||
mov cl, [eax + APPDATA.state] ; process state
|
||||
; } End patch
|
||||
mov cl, [SLOT_BASE + eax + APPDATA.state] ; process state
|
||||
;mov cl, [eax + APPDATA.state] ; process state
|
||||
test cl, cl
|
||||
jz .1
|
||||
cmp cl, TSTATE_WAITING
|
||||
jnz .ret
|
||||
mov cl, TSTATE_WAIT_SUSPENDED
|
||||
.2:
|
||||
mov [eax + APPDATA.state], cl
|
||||
mov [SLOT_BASE + eax + APPDATA.state], cl
|
||||
;mov [eax + APPDATA.state], cl
|
||||
.ret:
|
||||
sti
|
||||
ret
|
||||
@@ -100,14 +114,16 @@ debug_suspend:
|
||||
jmp .2
|
||||
|
||||
do_resume:
|
||||
mov cl, [eax + APPDATA.state]
|
||||
mov cl, [SLOT_BASE + eax + APPDATA.state]
|
||||
;mov cl, [eax + APPDATA.state]
|
||||
cmp cl, TSTATE_RUN_SUSPENDED
|
||||
jz .1
|
||||
cmp cl, TSTATE_WAIT_SUSPENDED
|
||||
jnz .ret
|
||||
mov cl, TSTATE_WAITING
|
||||
.2:
|
||||
mov [eax + APPDATA.state], cl
|
||||
mov [SLOT_BASE + eax + APPDATA.state], cl
|
||||
;mov [eax + APPDATA.state], cl
|
||||
.ret:
|
||||
ret
|
||||
.1:
|
||||
@@ -117,9 +133,11 @@ do_resume:
|
||||
debug_resume:
|
||||
; in: ecx=pid
|
||||
; destroys eax,ebx
|
||||
call get_debuggee_thread
|
||||
jc .ret
|
||||
|
||||
cli
|
||||
mov eax, ecx
|
||||
call pid_to_slot
|
||||
shl eax, BSF sizeof.APPDATA
|
||||
jz .ret
|
||||
call do_resume
|
||||
.ret:
|
||||
sti
|
||||
@@ -142,15 +160,21 @@ debug_getcontext:
|
||||
inc ebx ; 1 - get sse context
|
||||
; TODO legacy 32-bit FPU/MMX context
|
||||
.std_ctx:
|
||||
call get_debuggee_thread
|
||||
call get_debuggee_slot
|
||||
jc .ret
|
||||
|
||||
shr eax, BSF sizeof.APPDATA
|
||||
;movzx ebp, ah
|
||||
|
||||
cmp eax, [fpu_owner]
|
||||
;cmp ebp, [fpu_owner]
|
||||
jne @f
|
||||
inc bh ; set swap context flag
|
||||
@@:
|
||||
shl eax, BSF sizeof.APPDATA
|
||||
mov edi, esi
|
||||
mov eax, [eax + APPDATA.pl0_stack]
|
||||
mov eax, [SLOT_BASE + eax + APPDATA.pl0_stack]
|
||||
;mov eax, [eax + APPDATA.pl0_stack]
|
||||
lea esi, [eax + RING0_STACK_SIZE]
|
||||
|
||||
.ring0:
|
||||
@@ -216,10 +240,11 @@ debug_setcontext:
|
||||
cmp edx, 28h
|
||||
jnz .ret
|
||||
|
||||
call get_debuggee_thread
|
||||
call get_debuggee_slot
|
||||
jc .stiret
|
||||
|
||||
mov eax, [eax + APPDATA.pl0_stack]
|
||||
; mov esi, edx
|
||||
mov eax, [eax + SLOT_BASE+APPDATA.pl0_stack]
|
||||
;mov eax, [eax + APPDATA.pl0_stack]
|
||||
lea edi, [eax + RING0_STACK_SIZE]
|
||||
|
||||
.ring0:
|
||||
@@ -252,16 +277,15 @@ debug_setcontext:
|
||||
ret
|
||||
|
||||
debug_set_drx:
|
||||
call get_debuggee_thread
|
||||
call get_debuggee_slot
|
||||
jc .errret
|
||||
|
||||
mov ebp, eax
|
||||
lea eax, [eax + APPDATA.dbg_regs]
|
||||
lea eax, [eax + SLOT_BASE + APPDATA.dbg_regs]
|
||||
;lea eax, [eax + APPDATA.dbg_regs]
|
||||
; [eax]=dr0, [eax+4]=dr1, [eax+8]=dr2, [eax+C]=dr3
|
||||
; [eax+10]=dr7
|
||||
cmp esi, OS_BASE
|
||||
jae .errret
|
||||
|
||||
cmp dl, 3
|
||||
ja .errret
|
||||
mov ecx, dr7
|
||||
@@ -282,7 +306,10 @@ debug_set_drx:
|
||||
btr dword [eax + 10h], edx ; clear L<i> bit
|
||||
test byte [eax + 10h], 55h
|
||||
jnz .okret
|
||||
and [ebp + APPDATA.dbg_state], not 1
|
||||
; imul eax, ebp, tss_step/32
|
||||
; and byte [eax + tss_data + TSS._trap], not 1
|
||||
and [SLOT_BASE + ebp + APPDATA.dbg_state], not 1
|
||||
;and [ebp + APPDATA.dbg_state], not 1
|
||||
.okret:
|
||||
and dword [esp + SYSCALL_STACK.eax], 0
|
||||
sti
|
||||
@@ -327,7 +354,10 @@ debug_set_drx:
|
||||
not ebx
|
||||
and [eax + 10h+2], bx
|
||||
or [eax + 10h+2], dx ; set R/W and LEN fields
|
||||
or [ebp + APPDATA.dbg_state], 1
|
||||
; imul eax, ebp, tss_step/32
|
||||
; or byte [eax + tss_data + TSS._trap], 1
|
||||
or [SLOT_BASE + ebp + APPDATA.dbg_state], 1
|
||||
;or [ebp + APPDATA.dbg_state], 1
|
||||
jmp .okret
|
||||
|
||||
debug_read_process_memory:
|
||||
@@ -338,9 +368,10 @@ debug_read_process_memory:
|
||||
; esi=address in debuggee
|
||||
; out: [esp+36]=sizeof(read)
|
||||
; destroys all
|
||||
call get_debuggee_thread
|
||||
call get_debuggee_slot
|
||||
jc .err
|
||||
|
||||
shr eax, BSF sizeof.APPDATA
|
||||
;movzx eax,ah
|
||||
mov ecx, edi
|
||||
call read_process_memory
|
||||
sti
|
||||
@@ -358,9 +389,10 @@ debug_write_process_memory:
|
||||
; esi=address in debuggee
|
||||
; out: [esp+36]=sizeof(write)
|
||||
; destroys all
|
||||
call get_debuggee_thread
|
||||
call get_debuggee_slot
|
||||
jc debug_read_process_memory.err
|
||||
|
||||
shr eax, BSF sizeof.APPDATA
|
||||
;movzx eax,ah
|
||||
mov ecx, edi
|
||||
call write_process_memory
|
||||
sti
|
||||
@@ -368,7 +400,7 @@ debug_write_process_memory:
|
||||
ret
|
||||
|
||||
debugger_notify:
|
||||
; in: eax=debugger thread
|
||||
; in: eax=debugger slot
|
||||
; ecx=size of debug message
|
||||
; [esp+4]..[esp+4+ecx]=message
|
||||
; interrupts must be disabled!
|
||||
@@ -378,7 +410,9 @@ debugger_notify:
|
||||
mov edi, [timer_ticks]
|
||||
add edi, 500 ; 5 sec timeout
|
||||
.1:
|
||||
mov esi, [ebp + APPDATA.dbg_event_mem]
|
||||
mov eax, ebp
|
||||
shl eax, BSF sizeof.APPDATA
|
||||
mov esi, [SLOT_BASE + eax + APPDATA.dbg_event_mem]
|
||||
test esi, esi
|
||||
jz .ret
|
||||
; read buffer header
|
||||
@@ -432,6 +466,8 @@ debugger_notify:
|
||||
pop edx
|
||||
call write_process_memory
|
||||
; new debug event
|
||||
or [ebp + APPDATA.occurred_events], EVENT_DEBUG
|
||||
mov eax, ebp
|
||||
shl eax, BSF sizeof.APPDATA
|
||||
or [SLOT_BASE + eax + APPDATA.occurred_events], EVENT_DEBUG
|
||||
.ret:
|
||||
ret
|
||||
+37
-49
@@ -150,10 +150,10 @@ init_avx512:
|
||||
|
||||
ret
|
||||
|
||||
; param
|
||||
; eax= 512 bytes memory area aligned on a 16-byte boundary
|
||||
|
||||
align 4
|
||||
; @brief Export function - Save FPU context in buffer
|
||||
; @param eax - 512 bytes memory area aligned on a 16-byte boundary
|
||||
; @return not return
|
||||
fpu_save:
|
||||
push ecx
|
||||
push esi
|
||||
@@ -166,7 +166,7 @@ fpu_save:
|
||||
mov edi, eax
|
||||
|
||||
mov ecx, [fpu_owner]
|
||||
mov esi, [current_slot]
|
||||
mov esi, [current_slot_idx]
|
||||
cmp ecx, esi
|
||||
jne .save
|
||||
|
||||
@@ -175,11 +175,14 @@ fpu_save:
|
||||
.save:
|
||||
mov [fpu_owner], esi
|
||||
|
||||
mov eax, [ecx + APPDATA.fpu_state]
|
||||
shl ecx, BSF sizeof.APPDATA
|
||||
mov eax, [SLOT_BASE + ecx + APPDATA.fpu_state]
|
||||
|
||||
call save_context
|
||||
|
||||
; first 512 bytes of XSAVE area have the same format as FXSAVE
|
||||
mov esi, [esi + APPDATA.fpu_state]
|
||||
shl esi, BSF sizeof.APPDATA
|
||||
mov esi, [SLOT_BASE + esi + APPDATA.fpu_state]
|
||||
mov ecx, 512/4
|
||||
cld
|
||||
rep movsd
|
||||
@@ -191,16 +194,14 @@ fpu_save:
|
||||
pop ecx
|
||||
ret
|
||||
|
||||
; @brief Export function - Get size from AVX context
|
||||
; @return size of buffer
|
||||
avx_save_size:
|
||||
mov eax, [xsave_area_size]
|
||||
ret
|
||||
|
||||
; param
|
||||
; eax= avx_save_size() bytes memory area aligned on a 64-byte boundary
|
||||
|
||||
align 4
|
||||
; @brief Export function - Save AVX context in buffer
|
||||
; @param eax - avx_save_size() bytes memory area aligned on a 64-byte boundary
|
||||
; @return not return
|
||||
avx_save:
|
||||
push ecx
|
||||
push esi
|
||||
@@ -213,7 +214,7 @@ avx_save:
|
||||
mov edi, eax
|
||||
|
||||
mov ecx, [fpu_owner]
|
||||
mov esi, [current_slot]
|
||||
mov esi, [current_slot_idx]
|
||||
cmp ecx, esi
|
||||
jne .save
|
||||
|
||||
@@ -222,10 +223,13 @@ avx_save:
|
||||
.save:
|
||||
mov [fpu_owner], esi
|
||||
|
||||
mov eax, [ecx + APPDATA.fpu_state]
|
||||
shl ecx, BSF sizeof.APPDATA
|
||||
mov eax, [SLOT_BASE + ecx + APPDATA.fpu_state]
|
||||
|
||||
call save_context
|
||||
|
||||
mov esi, [esi + APPDATA.fpu_state]
|
||||
shl esi, BSF sizeof.APPDATA
|
||||
mov esi, [SLOT_BASE + esi + APPDATA.fpu_state]
|
||||
mov ecx, [xsave_area_size]
|
||||
add ecx, 3
|
||||
shr ecx, 2
|
||||
@@ -260,13 +264,9 @@ save_fpu_context:
|
||||
|
||||
|
||||
align 4
|
||||
; @brief Export function - Restore FPU context
|
||||
; @param eax - 512 bytes memory area aligned on a 16-byte boundary
|
||||
; @return not return
|
||||
fpu_restore:
|
||||
push ecx
|
||||
push esi
|
||||
push edi
|
||||
|
||||
mov esi, eax
|
||||
|
||||
@@ -274,7 +274,7 @@ fpu_restore:
|
||||
cli
|
||||
|
||||
mov ecx, [fpu_owner]
|
||||
mov eax, [current_slot]
|
||||
mov eax, [current_slot_idx]
|
||||
cmp ecx, eax
|
||||
jne .copy
|
||||
|
||||
@@ -284,8 +284,6 @@ fpu_restore:
|
||||
|
||||
fxrstor [esi]
|
||||
popfd
|
||||
|
||||
pop edi
|
||||
pop esi
|
||||
pop ecx
|
||||
ret
|
||||
@@ -293,31 +291,24 @@ fpu_restore:
|
||||
fnclex ;fix possible problems
|
||||
frstor [esi]
|
||||
popfd
|
||||
|
||||
pop edi
|
||||
pop esi
|
||||
pop ecx
|
||||
ret
|
||||
.copy:
|
||||
mov edi, [eax + APPDATA.fpu_state]
|
||||
shl eax, BSF sizeof.APPDATA
|
||||
mov edi, [SLOT_BASE + eax + APPDATA.fpu_state]
|
||||
mov ecx, 512/4
|
||||
cld
|
||||
rep movsd
|
||||
popfd
|
||||
|
||||
pop edi
|
||||
pop esi
|
||||
pop ecx
|
||||
ret
|
||||
|
||||
align 4
|
||||
; @brief Export function - Restore AVX context
|
||||
; @param eax - avx_save_size() bytes memory area aligned on a 64-byte boundary
|
||||
; @return not return
|
||||
avx_restore:
|
||||
push ecx
|
||||
push esi
|
||||
push edi
|
||||
|
||||
mov esi, eax
|
||||
|
||||
@@ -325,7 +316,7 @@ avx_restore:
|
||||
cli
|
||||
|
||||
mov ecx, [fpu_owner]
|
||||
mov eax, [current_slot]
|
||||
mov eax, [current_slot_idx]
|
||||
cmp ecx, eax
|
||||
jne .copy
|
||||
|
||||
@@ -338,8 +329,6 @@ avx_restore:
|
||||
xrstor [esi]
|
||||
pop edx
|
||||
popfd
|
||||
|
||||
pop edi
|
||||
pop esi
|
||||
pop ecx
|
||||
ret
|
||||
@@ -349,8 +338,6 @@ avx_restore:
|
||||
|
||||
fxrstor [esi]
|
||||
popfd
|
||||
|
||||
pop edi
|
||||
pop esi
|
||||
pop ecx
|
||||
ret
|
||||
@@ -358,21 +345,18 @@ avx_restore:
|
||||
fnclex ;fix possible problems
|
||||
frstor [esi]
|
||||
popfd
|
||||
|
||||
pop edi
|
||||
pop esi
|
||||
pop ecx
|
||||
ret
|
||||
.copy:
|
||||
mov edi, [eax + APPDATA.fpu_state]
|
||||
shl eax, BSF sizeof.APPDATA
|
||||
mov edi, [SLOT_BASE + eax + APPDATA.fpu_state]
|
||||
mov ecx, [xsave_area_size]
|
||||
add ecx, 3
|
||||
shr ecx, 2
|
||||
cld
|
||||
rep movsd
|
||||
popfd
|
||||
|
||||
pop edi
|
||||
pop esi
|
||||
pop ecx
|
||||
ret
|
||||
@@ -386,19 +370,21 @@ except_7: ;#NM exception handler
|
||||
mov es, ax
|
||||
|
||||
mov ebx, [fpu_owner]
|
||||
cmp ebx, [current_slot]
|
||||
cmp ebx, [current_slot_idx]
|
||||
je .exit
|
||||
|
||||
mov eax, [ebx + APPDATA.fpu_state]
|
||||
shl ebx, BSF sizeof.APPDATA
|
||||
mov eax, [SLOT_BASE + ebx + APPDATA.fpu_state]
|
||||
bt [cpu_caps + (CAPS_OSXSAVE/32)*4], CAPS_OSXSAVE mod 32
|
||||
jnc .no_xsave
|
||||
mov ecx, eax
|
||||
mov eax, [xsave_eax]
|
||||
mov edx, [xsave_edx]
|
||||
xsave [ecx]
|
||||
mov ebx, [current_slot]
|
||||
mov ebx, [current_slot_idx]
|
||||
mov [fpu_owner], ebx
|
||||
mov ecx, [ebx + APPDATA.fpu_state]
|
||||
shl ebx, BSF sizeof.APPDATA
|
||||
mov ecx, [SLOT_BASE + ebx + APPDATA.fpu_state]
|
||||
xrstor [ecx]
|
||||
.exit:
|
||||
restore_ring3_context
|
||||
@@ -408,22 +394,24 @@ except_7: ;#NM exception handler
|
||||
jnc .no_SSE
|
||||
|
||||
fxsave [eax]
|
||||
mov ebx, [current_slot]
|
||||
mov ebx, [current_slot_idx]
|
||||
mov [fpu_owner], ebx
|
||||
mov eax, [ebx + APPDATA.fpu_state]
|
||||
shl ebx, BSF sizeof.APPDATA
|
||||
mov eax, [SLOT_BASE + ebx + APPDATA.fpu_state]
|
||||
fxrstor [eax]
|
||||
restore_ring3_context
|
||||
iret
|
||||
|
||||
.no_SSE:
|
||||
fnsave [eax]
|
||||
mov ebx, [current_slot]
|
||||
mov ebx, [current_slot_idx]
|
||||
mov [fpu_owner], ebx
|
||||
mov eax, [ebx + APPDATA.fpu_state]
|
||||
shl ebx, BSF sizeof.APPDATA
|
||||
mov eax, [SLOT_BASE + ebx + APPDATA.fpu_state]
|
||||
frstor [eax]
|
||||
restore_ring3_context
|
||||
iret
|
||||
|
||||
iglobal
|
||||
fpu_owner dd APPDATA_OS_THREAD
|
||||
fpu_owner dd 2
|
||||
endg
|
||||
@@ -605,7 +605,7 @@ proc page_fault_handler
|
||||
|
||||
mov edi, [.err_addr]
|
||||
and edi, -PAGE_SIZE
|
||||
mov ecx, PAGE_SIZE/4
|
||||
mov ecx, 1024
|
||||
xor eax, eax
|
||||
;cld ;caller is duty for this
|
||||
rep stosd
|
||||
@@ -664,7 +664,7 @@ proc page_fault_handler
|
||||
cmp ebx, tss._io_map_0
|
||||
jb .fail
|
||||
|
||||
cmp ebx, tss._io_map_0 + IO_MAP_SIZE
|
||||
cmp ebx, tss._io_map_0+8192
|
||||
jae .fail
|
||||
|
||||
; io permission map
|
||||
@@ -695,7 +695,7 @@ proc page_fault_handler
|
||||
endp
|
||||
|
||||
; returns number of mapped bytes
|
||||
proc map_mem_ipc stdcall, lin_addr:dword,thread:dword,\
|
||||
proc map_mem_ipc stdcall, lin_addr:dword,slot:dword,\
|
||||
ofs:dword,buf_size:dword,req_access:dword
|
||||
locals
|
||||
count dd ?
|
||||
@@ -706,8 +706,9 @@ proc map_mem_ipc stdcall, lin_addr:dword,thread:dword,\
|
||||
cmp [buf_size], 0
|
||||
jz .exit
|
||||
|
||||
mov eax, [thread]
|
||||
mov eax, [eax + APPDATA.process]
|
||||
mov eax, [slot]
|
||||
shl eax, BSF sizeof.APPDATA
|
||||
mov eax, [SLOT_BASE + eax + APPDATA.process]
|
||||
test eax, eax
|
||||
jz .exit
|
||||
|
||||
@@ -731,7 +732,7 @@ proc map_mem_ipc stdcall, lin_addr:dword,thread:dword,\
|
||||
shr edx, 12
|
||||
and edx, 0x3FF
|
||||
.map:
|
||||
stdcall safe_map_page, [process], [req_access], [ofs]
|
||||
stdcall safe_map_page, [slot], [req_access], [ofs]
|
||||
jnc .exit
|
||||
add [count], PAGE_SIZE
|
||||
add [ofs], PAGE_SIZE
|
||||
@@ -757,7 +758,7 @@ proc map_mem_ipc stdcall, lin_addr:dword,thread:dword,\
|
||||
ret
|
||||
endp
|
||||
|
||||
proc map_memEx stdcall, lin_addr:dword,thread:dword,\
|
||||
proc map_memEx stdcall, lin_addr:dword,slot:dword,\
|
||||
ofs:dword,buf_size:dword,req_access:dword
|
||||
locals
|
||||
count dd ?
|
||||
@@ -768,8 +769,9 @@ proc map_memEx stdcall, lin_addr:dword,thread:dword,\
|
||||
cmp [buf_size], 0
|
||||
jz .exit
|
||||
|
||||
mov eax, [thread]
|
||||
mov eax, [eax + APPDATA.process]
|
||||
mov eax, [slot]
|
||||
shl eax, BSF sizeof.APPDATA
|
||||
mov eax, [SLOT_BASE + eax + APPDATA.process]
|
||||
test eax, eax
|
||||
jz .exit
|
||||
|
||||
@@ -793,7 +795,7 @@ proc map_memEx stdcall, lin_addr:dword,thread:dword,\
|
||||
shr edx, 12
|
||||
and edx, 0x3FF
|
||||
.map:
|
||||
stdcall safe_map_page, [process], [req_access], [ofs]
|
||||
stdcall safe_map_page, [slot], [req_access], [ofs]
|
||||
jnc .exit
|
||||
add [count], PAGE_SIZE
|
||||
add [ofs], PAGE_SIZE
|
||||
@@ -824,7 +826,7 @@ endp
|
||||
; in: edi = linear address to map
|
||||
; out: CF cleared <=> failed
|
||||
; destroys: only eax
|
||||
proc safe_map_page stdcall, process:dword, req_access:dword, ofs:dword
|
||||
proc safe_map_page stdcall, slot:dword, req_access:dword, ofs:dword
|
||||
mov eax, [esi + edx*4]
|
||||
test al, PG_READ
|
||||
jz .not_present
|
||||
@@ -859,7 +861,9 @@ proc safe_map_page stdcall, process:dword, req_access:dword, ofs:dword
|
||||
cli
|
||||
cld
|
||||
push ebx ecx
|
||||
mov eax, [process]
|
||||
mov eax, [slot]
|
||||
shl eax, BSF sizeof.APPDATA
|
||||
mov eax, [SLOT_BASE + eax + APPDATA.process]
|
||||
mov eax, [eax + PROC.dlls_list_ptr]
|
||||
test eax, eax
|
||||
jz .no_hdll
|
||||
@@ -949,7 +953,7 @@ sys_IPC:
|
||||
|
||||
proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
|
||||
locals
|
||||
dst_thread dd ?
|
||||
dst_slot dd ?
|
||||
dst_offset dd ?
|
||||
buf_size dd ?
|
||||
used_buf dd ?
|
||||
@@ -959,12 +963,13 @@ proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
|
||||
cli
|
||||
|
||||
mov eax, [PID]
|
||||
call pid_to_thread
|
||||
call pid_to_slot
|
||||
test eax, eax
|
||||
jz .no_pid
|
||||
|
||||
mov [dst_thread], eax
|
||||
mov edi, [eax + APPDATA.ipc_start] ;is ipc area defined?
|
||||
mov [dst_slot], eax
|
||||
shl eax, BSF sizeof.APPDATA
|
||||
mov edi, [SLOT_BASE + eax + APPDATA.ipc_start] ;is ipc area defined?
|
||||
test edi, edi
|
||||
jz .no_ipc_area
|
||||
|
||||
@@ -972,7 +977,7 @@ proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
|
||||
and ebx, 0xFFF
|
||||
mov [dst_offset], ebx
|
||||
|
||||
mov esi, [eax + APPDATA.ipc_size]
|
||||
mov esi, [SLOT_BASE + eax + APPDATA.ipc_size]
|
||||
mov [buf_size], esi
|
||||
|
||||
mov ecx, [ipc_tmp]
|
||||
@@ -985,7 +990,7 @@ proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
|
||||
pop edi esi
|
||||
@@:
|
||||
mov [used_buf], ecx
|
||||
stdcall map_mem_ipc, ecx, [dst_thread], \
|
||||
stdcall map_mem_ipc, ecx, [dst_slot], \
|
||||
edi, esi, PG_SWR
|
||||
|
||||
mov edi, [dst_offset]
|
||||
@@ -1034,8 +1039,9 @@ proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
|
||||
mov [page_tabs + ebx*4], eax
|
||||
invlpg [edx]
|
||||
|
||||
mov eax, [dst_thread]
|
||||
or [eax + APPDATA.occurred_events], EVENT_IPC
|
||||
mov eax, [dst_slot]
|
||||
shl eax, BSF sizeof.APPDATA
|
||||
or [SLOT_BASE + eax + APPDATA.occurred_events], EVENT_IPC
|
||||
push 0
|
||||
jmp .ret
|
||||
.no_pid:
|
||||
|
||||
@@ -139,13 +139,14 @@ do_change_task:
|
||||
mov eax, [xsave_eax]
|
||||
mov edx, [xsave_edx]
|
||||
xsave [ecx]
|
||||
mov ecx, [current_slot]
|
||||
mov ecx, [current_slot_idx]
|
||||
mov [fpu_owner], ecx
|
||||
mov ecx, [current_slot]
|
||||
mov ecx, [ecx + APPDATA.fpu_state]
|
||||
xrstor [ecx]
|
||||
.no_xsave:
|
||||
; set CR0.TS
|
||||
cmp ebx, [fpu_owner] ;ebx == incoming task (new)
|
||||
cmp bh, byte[fpu_owner] ;bh == incoming task (new)
|
||||
clts ;clear a task switch flag
|
||||
je @f
|
||||
mov eax, cr0 ;and set it again if the owner
|
||||
|
||||
+16
-19
@@ -165,7 +165,7 @@ exc_c: ; exceptions (all but 7th - #NM)
|
||||
jnz IRetToUserHook
|
||||
@@:
|
||||
cli
|
||||
mov eax, [esi + APPDATA.debugger_thread]
|
||||
mov eax, [esi + APPDATA.debugger_slot]
|
||||
test eax, eax
|
||||
jnz .debug
|
||||
; not debuggee => say error and terminate
|
||||
@@ -514,30 +514,28 @@ destroy_thread:
|
||||
@@:
|
||||
mov eax, [esi + APPOBJ.fd]
|
||||
test eax, eax
|
||||
jz @f
|
||||
jz @F
|
||||
|
||||
cmp eax, esi
|
||||
je @f
|
||||
je @F
|
||||
|
||||
push esi
|
||||
call [eax + APPOBJ.destroy]
|
||||
DEBUGF 1,"%s",msg_obj_destroy
|
||||
pop esi
|
||||
jmp @b
|
||||
jmp @B
|
||||
@@:
|
||||
mov esi, [.slot]
|
||||
shl esi, BSF sizeof.APPDATA
|
||||
add esi, SLOT_BASE
|
||||
cmp [fpu_owner], esi ; if user fpu last -> fpu user = 2
|
||||
jne @f
|
||||
jne @F
|
||||
|
||||
mov [fpu_owner], APPDATA_OS_THREAD
|
||||
mov eax, [APPDATA_OS_THREAD + APPDATA.fpu_state]
|
||||
mov [fpu_owner], 2
|
||||
mov eax, [SLOT_BASE + sizeof.APPDATA*2 + APPDATA.fpu_state]
|
||||
clts
|
||||
bt [cpu_caps], CAPS_SSE
|
||||
jnc .no_SSE
|
||||
fxrstor [eax]
|
||||
jmp @f
|
||||
jmp @F
|
||||
.no_SSE:
|
||||
fnclex
|
||||
frstor [eax]
|
||||
@@ -546,8 +544,8 @@ destroy_thread:
|
||||
mov [KEY_COUNT], byte 0 ; empty keyboard buffer
|
||||
mov [BTN_COUNT], byte 0 ; empty button buffer
|
||||
|
||||
|
||||
; remove defined hotkeys
|
||||
mov esi, [.slot]
|
||||
mov eax, hotkey_list
|
||||
.loop:
|
||||
cmp [eax+8], esi
|
||||
@@ -640,7 +638,7 @@ destroy_thread:
|
||||
pushad
|
||||
mov edi, esi
|
||||
shl edi, BSF sizeof.APPDATA
|
||||
mov eax, [SLOT_BASE + edi + APPDATA.debugger_thread]
|
||||
mov eax, [SLOT_BASE + edi + APPDATA.debugger_slot]
|
||||
test eax, eax
|
||||
jz .nodebug
|
||||
movi ecx, 8
|
||||
@@ -668,12 +666,12 @@ destroy_thread:
|
||||
add edi, SLOT_BASE
|
||||
|
||||
mov eax, [edi + APPDATA.io_map]
|
||||
cmp eax, [APPDATA_IDLE_THREAD + APPDATA.io_map]
|
||||
cmp eax, [SLOT_BASE + sizeof.APPDATA+APPDATA.io_map]
|
||||
je @F
|
||||
call free_page
|
||||
@@:
|
||||
mov eax, [edi+APPDATA.io_map+4]
|
||||
cmp eax, [APPDATA_IDLE_THREAD + APPDATA.io_map+4]
|
||||
cmp eax, [SLOT_BASE+sizeof.APPDATA+APPDATA.io_map+4]
|
||||
je @F
|
||||
call free_page
|
||||
@@:
|
||||
@@ -714,12 +712,12 @@ destroy_thread:
|
||||
call free_cd_channel
|
||||
and [cd_status], 0
|
||||
@@:
|
||||
pop esi
|
||||
cmp [bgrlockpid], esi
|
||||
jnz @f
|
||||
and [bgrlockpid], 0
|
||||
and [bgrlock], 0
|
||||
@@:
|
||||
pop esi
|
||||
|
||||
pusha ; remove all port reservations
|
||||
mov edx, esi
|
||||
@@ -780,15 +778,14 @@ destroy_thread:
|
||||
|
||||
mov edi, esi ; do not run this process slot
|
||||
shl edi, BSF sizeof.APPDATA
|
||||
add edi, SLOT_BASE
|
||||
mov [edi + APPDATA.state], TSTATE_FREE
|
||||
mov [SLOT_BASE + edi + APPDATA.state], TSTATE_FREE
|
||||
; debugger test - terminate all debuggees
|
||||
mov eax, 2
|
||||
mov ecx, APPDATA_OS_THREAD + APPDATA.debugger_thread
|
||||
mov ecx, SLOT_BASE + 2*sizeof.APPDATA + APPDATA.debugger_slot
|
||||
.xd0:
|
||||
cmp eax, [thread_count]
|
||||
ja .xd1
|
||||
cmp dword [ecx], edi
|
||||
cmp dword [ecx], esi
|
||||
jnz @f
|
||||
and dword [ecx], 0
|
||||
pushad
|
||||
|
||||
@@ -537,21 +537,21 @@ pid_to_slot:
|
||||
align 4
|
||||
proc read_process_memory
|
||||
;Input:
|
||||
; eax - process thread
|
||||
; eax - process slot
|
||||
; ecx - buffer address
|
||||
; edx - buffer size
|
||||
; esi - start address in other process
|
||||
;Output:
|
||||
; eax - number of bytes read.
|
||||
locals
|
||||
thread dd ?
|
||||
slot dd ?
|
||||
buff dd ?
|
||||
r_count dd ?
|
||||
offset dd ?
|
||||
tmp_r_cnt dd ?
|
||||
endl
|
||||
|
||||
mov [thread], eax
|
||||
mov [slot], eax
|
||||
mov [buff], ecx
|
||||
and [r_count], 0
|
||||
mov [tmp_r_cnt], edx
|
||||
@@ -577,7 +577,7 @@ proc read_process_memory
|
||||
|
||||
push ecx
|
||||
stdcall map_memEx, [proc_mem_map], \
|
||||
[thread], ebx, ecx, PG_READ
|
||||
[slot], ebx, ecx, PG_READ
|
||||
pop ecx
|
||||
|
||||
mov esi, [offset]
|
||||
@@ -607,7 +607,7 @@ endp
|
||||
align 4
|
||||
proc write_process_memory
|
||||
;Input:
|
||||
; eax - process thread
|
||||
; eax - process slot
|
||||
; ecx - buffer address
|
||||
; edx - buffer size
|
||||
; esi - start address in other process
|
||||
@@ -615,14 +615,14 @@ proc write_process_memory
|
||||
; eax - number of bytes written
|
||||
|
||||
locals
|
||||
thread dd ?
|
||||
slot dd ?
|
||||
buff dd ?
|
||||
w_count dd ?
|
||||
offset dd ?
|
||||
tmp_w_cnt dd ?
|
||||
endl
|
||||
|
||||
mov [thread], eax
|
||||
mov [slot], eax
|
||||
mov [buff], ecx
|
||||
and [w_count], 0
|
||||
mov [tmp_w_cnt], edx
|
||||
@@ -647,7 +647,7 @@ proc write_process_memory
|
||||
mov ebx, [offset]
|
||||
push ecx
|
||||
stdcall map_memEx, [proc_mem_map], \
|
||||
[thread], ebx, ecx, PG_SWR
|
||||
[slot], ebx, ecx, PG_SWR
|
||||
pop ecx
|
||||
|
||||
mov edi, [offset]
|
||||
@@ -906,7 +906,7 @@ common_app_entry:
|
||||
stdcall free_kernel_space, [ebp+APP_HDR.img_base]
|
||||
stdcall kernel_free, ebp
|
||||
mov ebx, [current_slot]
|
||||
cmp [ebx + APPDATA.debugger_thread], 0
|
||||
cmp [ebx + APPDATA.debugger_slot], 0
|
||||
je .exit
|
||||
mov [ebx + APPDATA.state], TSTATE_RUN_SUSPENDED
|
||||
mov [ebx + APPDATA.state], TSTATE_RUN_SUSPENDED
|
||||
@@ -1054,8 +1054,8 @@ proc set_app_params stdcall,slot:dword, params:dword, flags:dword
|
||||
; set if debuggee
|
||||
test byte [flags], 1
|
||||
jz .no_debug
|
||||
mov eax, [current_slot]
|
||||
mov [SLOT_BASE + ebx + APPDATA.debugger_thread], eax
|
||||
mov eax, [current_slot_idx]
|
||||
mov [SLOT_BASE + ebx + APPDATA.debugger_slot], eax
|
||||
.no_debug:
|
||||
mov [SLOT_BASE + ebx + APPDATA.state], dl
|
||||
lea edx, [SLOT_BASE + ebx]
|
||||
@@ -1074,24 +1074,27 @@ get_curr_slot:
|
||||
mov eax, [current_slot]
|
||||
ret
|
||||
|
||||
; @brief Get pointer to APPDATA by PID
|
||||
; @param eax - TID of thread
|
||||
; @return eax - 0 - not found or pointer on APPDATA
|
||||
pid_to_thread:
|
||||
pid_to_appdata:
|
||||
;Input:
|
||||
; eax - pid of process
|
||||
;Output:
|
||||
; eax - 0 - not found or pointer on APPDATA
|
||||
push ebx
|
||||
push ecx
|
||||
mov ebx, [thread_count]
|
||||
shl ebx, BSF sizeof.APPDATA ; multiply by size
|
||||
; skip first process in the task table
|
||||
mov ecx, APPDATA_IDLE_THREAD
|
||||
mov ecx, SLOT_BASE
|
||||
add ebx, ecx
|
||||
.loop:
|
||||
add ecx, sizeof.APPDATA
|
||||
cmp [ecx + APPDATA.state], TSTATE_FREE
|
||||
jz @f ;skip empty slots
|
||||
cmp [ecx + APPDATA.tid], eax
|
||||
jz .pid_found
|
||||
@@:
|
||||
add ecx, sizeof.APPDATA
|
||||
dec ebx
|
||||
jnz .loop
|
||||
cmp ecx, ebx
|
||||
jb .loop
|
||||
|
||||
pop ecx
|
||||
pop ebx
|
||||
|
||||
@@ -48,7 +48,7 @@ endg
|
||||
|
||||
; This internal function acquires the lock for the global list.
|
||||
lock_timer_list:
|
||||
mov edx, [current_slot]
|
||||
mov edx, [current_slot_idx]
|
||||
@@:
|
||||
xor eax, eax
|
||||
lock cmpxchg [timer_list_owner], edx
|
||||
|
||||
@@ -781,12 +781,21 @@ picture rb Xsize*Ysize*4 ; 32 бита
|
||||
* ebx = 6 - номер подфункции
|
||||
* ecx = указатель на строку с полным именем файла
|
||||
(например, "/hd0/1/kolibri/kolibri.img")
|
||||
* ecx = 0 - записать образ обратно на носитель, с которого была
|
||||
загружена система: на дискету или в файл образа, найденный при
|
||||
загрузке на разделе жёсткого диска
|
||||
Возвращаемое значение:
|
||||
* eax = 0 - успешно
|
||||
* иначе eax = код ошибки файловой системы
|
||||
Замечания:
|
||||
* Все папки в указанном пути должны существовать, иначе вернётся
|
||||
значение 5, "файл не найден".
|
||||
* Для ecx = 0: если рамдиск не был загружен с перезаписываемого
|
||||
носителя (например, образ заранее загружен в память
|
||||
загрузчиком), вернётся значение 2; ошибка записи на дискету
|
||||
вернёт значение 11.
|
||||
* Устройство-источник загрузки можно заранее узнать подфункцией
|
||||
13 функции 26.
|
||||
|
||||
---------------------- Константы для регистров: ----------------------
|
||||
eax - SF_SYSTEM (18)
|
||||
@@ -1654,6 +1663,27 @@ Remarks:
|
||||
eax - SF_SYSTEM_GET (26)
|
||||
ebx - SSF_ACCESS_PCI (12)
|
||||
======================================================================
|
||||
===== Функция 26, подфункция 13 - откуда загружен рамдиск. ===========
|
||||
======================================================================
|
||||
Параметры:
|
||||
* eax = 26 - номер функции
|
||||
* ebx = 13 - номер подфункции
|
||||
Возвращаемое значение:
|
||||
* eax = устройство, с которого при загрузке был прочитан образ
|
||||
рамдиска:
|
||||
* 1 = дискета
|
||||
* 2 = раздел жёсткого диска
|
||||
* 3 = образ заранее загружен в память загрузчиком
|
||||
* 4 = рамдиск создан пустым (отформатирован при загрузке)
|
||||
* 5 = рамдиска нет
|
||||
Замечания:
|
||||
* Для сохранения рамдиска на загрузочный носитель используйте
|
||||
функцию 18.6 с ecx = 0; она успешна для значений 1 и 2.
|
||||
|
||||
---------------------- Константы для регистров: ----------------------
|
||||
eax - SF_SYSTEM_GET (26)
|
||||
ebx - SSF_RD_BOOT_SOURCE (13)
|
||||
======================================================================
|
||||
================ Функция 29 - получить системную дату. ===============
|
||||
======================================================================
|
||||
Параметры:
|
||||
@@ -5230,7 +5260,7 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
|
||||
-EINVAL (-11), -EFAULT (-14), -ENFILE (-23), -EMFILE (-24)
|
||||
Примечания:
|
||||
* В случае успеха pipefd[0] является дескриптором чтения, а pipefd[1]
|
||||
- дескриптором записи.
|
||||
- дескриптором записи.
|
||||
|
||||
---------------------- Константы для регистров: ----------------------
|
||||
eax - SF_POSIX (77)
|
||||
|
||||
@@ -769,12 +769,20 @@ Parameters:
|
||||
* ebx = 6 - subfunction number
|
||||
* ecx = pointer to the full path to file
|
||||
(for example, "/hd0/1/kolibri/kolibri.img")
|
||||
* ecx = 0 - write the image back to the medium the system was
|
||||
booted from: the floppy drive, or the image file found on a hard
|
||||
disk partition at boot
|
||||
Returned value:
|
||||
* eax = 0 - success
|
||||
* else eax = error code of the file system
|
||||
Remarks:
|
||||
* All folders in the given path must exist, otherwise function
|
||||
returns value 5, "file not found".
|
||||
* For ecx = 0: if the ramdisk was not loaded from a writable
|
||||
medium (e.g. it was preloaded to memory by the loader), function
|
||||
returns value 2; a failed floppy write returns value 11.
|
||||
* The boot source device can be checked in advance with
|
||||
subfunction 13 of function 26.
|
||||
|
||||
---------------------- Constants for registers: ----------------------
|
||||
eax - SF_SYSTEM (18)
|
||||
@@ -1639,6 +1647,26 @@ Remarks:
|
||||
eax - SF_SYSTEM_GET (26)
|
||||
ebx - SSF_ACCESS_PCI (12)
|
||||
======================================================================
|
||||
== Function 26, subfunction 13 - get ramdisk boot source device. =====
|
||||
======================================================================
|
||||
Parameters:
|
||||
* eax = 26 - function number
|
||||
* ebx = 13 - subfunction number
|
||||
Returned value:
|
||||
* eax = device the ramdisk image was loaded from at boot:
|
||||
* 1 = floppy drive
|
||||
* 2 = hard disk partition
|
||||
* 3 = image preloaded to memory by the loader
|
||||
* 4 = ramdisk was created empty (formatted at boot)
|
||||
* 5 = no ramdisk
|
||||
Remarks:
|
||||
* To save the ramdisk back to the boot medium use function 18.6
|
||||
with ecx = 0; it succeeds for values 1 and 2.
|
||||
|
||||
---------------------- Constants for registers: ----------------------
|
||||
eax - SF_SYSTEM_GET (26)
|
||||
ebx - SSF_RD_BOOT_SOURCE (13)
|
||||
======================================================================
|
||||
=================== Function 29 - get system date. ===================
|
||||
======================================================================
|
||||
Parameters:
|
||||
@@ -4148,7 +4176,6 @@ Structure of block of data for folder entry (BDFE):
|
||||
and after archiving this bit is cleared - it can be useful
|
||||
for automatically creating of backup-archives as at writing
|
||||
this bit is usually set
|
||||
* bit 6 (mask 0x40): this is a symbolic link (currently only set by the ext driver).
|
||||
* +4: dword: encoding, equals to field +8 in the information structure
|
||||
* +8: 4*byte: time of file creation
|
||||
* +12 = +0xC: 4*byte: date of file creation
|
||||
|
||||
+49
-749
File diff suppressed because it is too large.
Load diff
@@ -2405,12 +2405,11 @@ fat_Write:
|
||||
; hd_extend_file can return three error codes: FAT table error, device error or disk full.
|
||||
; First two cases are fatal errors, in third case we may write some data
|
||||
cmp al, ERROR_DISK_FULL
|
||||
jnz .noWrite
|
||||
jnz @f
|
||||
; correct number of bytes to write
|
||||
mov ecx, [edi+28]
|
||||
cmp ecx, ebx
|
||||
ja .length_ok
|
||||
.noWrite:
|
||||
push 0
|
||||
.ret:
|
||||
pop eax eax eax ecx ecx
|
||||
|
||||
@@ -193,8 +193,7 @@ align 4
|
||||
;--------------------------------------
|
||||
align 4
|
||||
@@:
|
||||
mov eax, [current_slot]
|
||||
mov eax, [eax + APPDATA.tid]
|
||||
mov eax, [current_slot_idx]
|
||||
mov [bgrlockpid], eax
|
||||
cmp [img_background], static_background_data
|
||||
jz .nomem
|
||||
@@ -242,8 +241,7 @@ nosb6:
|
||||
jnz nosb7
|
||||
cmp [bgrlock], 0
|
||||
jz .err
|
||||
mov eax, [current_slot]
|
||||
mov eax, [eax + APPDATA.tid]
|
||||
mov eax, [current_slot_idx]
|
||||
cmp [bgrlockpid], eax
|
||||
jnz .err
|
||||
mov eax, ecx
|
||||
|
||||
@@ -48,10 +48,6 @@ dtext:
|
||||
add esp, 28
|
||||
ret
|
||||
|
||||
.nomem:
|
||||
add esp, 40
|
||||
ret
|
||||
|
||||
.redirect:
|
||||
mov ebp, [edi]
|
||||
add edi, 8
|
||||
@@ -85,8 +81,6 @@ dtext:
|
||||
mov [esp+32], eax
|
||||
imul ebp, eax
|
||||
stdcall kernel_alloc, ebp
|
||||
test eax, eax
|
||||
jz .nomem
|
||||
mov ecx, ebp
|
||||
shr ecx, 2
|
||||
mov [esp+36], eax
|
||||
|
||||
@@ -1997,8 +1997,6 @@ align 4
|
||||
; esi - slot
|
||||
push eax ecx edx esi
|
||||
xchg eax, esi
|
||||
shl eax, BSF sizeof.APPDATA
|
||||
add eax, SLOT_BASE
|
||||
lea ecx, [esp + 12]
|
||||
mov edx, 1
|
||||
call read_process_memory
|
||||
|
||||
+29
-18
@@ -55,6 +55,7 @@ launcher_start db 1
|
||||
endg
|
||||
|
||||
max_processes = 255
|
||||
tss_step = 128 + 8192 ; tss & i/o - 65535 ports, * 256=557056*4
|
||||
|
||||
os_stack = os_data_l - gdts ; GDTs
|
||||
os_code = os_code_l - gdts
|
||||
@@ -388,7 +389,7 @@ high_code:
|
||||
mov edi, tss._io_map_0
|
||||
xor eax, eax
|
||||
not eax
|
||||
mov ecx, IO_MAP_SIZE/4
|
||||
mov ecx, 8192/4
|
||||
rep stosd ; access to 4096*8=65536 ports
|
||||
|
||||
mov ax, tss0
|
||||
@@ -409,7 +410,7 @@ high_code:
|
||||
stdcall alloc_kernel_space, 0x50000 ; FIXME check size
|
||||
mov [default_io_map], eax
|
||||
|
||||
add eax, IO_MAP_SIZE
|
||||
add eax, 0x2000
|
||||
mov [ipc_tmp], eax
|
||||
mov ebx, 0x1000
|
||||
|
||||
@@ -534,7 +535,7 @@ high_code:
|
||||
dec ecx
|
||||
jns @b
|
||||
|
||||
mov edx, APPDATA_IDLE_THREAD
|
||||
mov edx, SLOT_BASE + sizeof.APPDATA*1
|
||||
mov ebx, [os_stack_seg]
|
||||
add ebx, RING0_STACK_SIZE
|
||||
add ebx, [xsave_area_size]
|
||||
@@ -546,7 +547,7 @@ high_code:
|
||||
mov ecx, IDLE_PRIORITY
|
||||
call scheduler_add_thread
|
||||
|
||||
mov edx, APPDATA_OS_THREAD
|
||||
mov edx, SLOT_BASE + sizeof.APPDATA*2
|
||||
mov ebx, [os_stack_seg]
|
||||
call setup_os_slot
|
||||
mov dword [edx], 'OS'
|
||||
@@ -555,7 +556,7 @@ high_code:
|
||||
|
||||
mov [current_slot_idx], 2
|
||||
mov [thread_count], 2
|
||||
mov [current_slot], APPDATA_OS_THREAD
|
||||
mov [current_slot], SLOT_BASE + sizeof.APPDATA*2
|
||||
|
||||
; Move other CPUs to deep sleep, if it is useful
|
||||
uglobal
|
||||
@@ -847,15 +848,15 @@ include "detect/vortex86.inc" ; Vortex86 SoC detection code
|
||||
call reserve_irqs_ports
|
||||
|
||||
mov [SLOT_BASE + APPDATA.window], window_data
|
||||
mov [APPDATA_IDLE_THREAD + APPDATA.window], background_window
|
||||
mov [APPDATA_OS_THREAD + APPDATA.window], window_data + sizeof.WDATA*2
|
||||
mov [SLOT_BASE + sizeof.APPDATA + APPDATA.window], window_data + sizeof.WDATA
|
||||
mov [SLOT_BASE + sizeof.APPDATA*2 + APPDATA.window], window_data + sizeof.WDATA*2
|
||||
mov [window_data + WDATA.thread], SLOT_BASE
|
||||
mov [background_window + WDATA.thread], APPDATA_IDLE_THREAD
|
||||
mov [window_data + sizeof.WDATA*2 + WDATA.thread], APPDATA_OS_THREAD
|
||||
mov [window_data + sizeof.WDATA + WDATA.thread], SLOT_BASE + sizeof.APPDATA
|
||||
mov [window_data + sizeof.WDATA*2 + WDATA.thread], SLOT_BASE + sizeof.APPDATA*2
|
||||
|
||||
call init_display
|
||||
mov eax, [def_cursor]
|
||||
mov [background_window + WDATA.cursor], eax
|
||||
mov [window_data + sizeof.WDATA + WDATA.cursor], eax
|
||||
mov [window_data + sizeof.WDATA*2 + WDATA.cursor], eax
|
||||
|
||||
; PRINT CPU FREQUENCY
|
||||
@@ -952,14 +953,14 @@ include "detect/vortex86.inc" ; Vortex86 SoC detection code
|
||||
; Protect I/O permission map
|
||||
|
||||
mov esi, [default_io_map]
|
||||
stdcall map_page, esi, [APPDATA_IDLE_THREAD + APPDATA.io_map], PG_READ
|
||||
stdcall map_page, esi, [SLOT_BASE + sizeof.APPDATA + APPDATA.io_map], PG_READ
|
||||
add esi, 0x1000
|
||||
stdcall map_page, esi, [APPDATA_IDLE_THREAD + APPDATA.io_map + 4], PG_READ
|
||||
stdcall map_page, esi, [SLOT_BASE + sizeof.APPDATA + APPDATA.io_map + 4], PG_READ
|
||||
|
||||
stdcall map_page, tss._io_map_0, \
|
||||
[APPDATA_IDLE_THREAD + APPDATA.io_map], PG_READ
|
||||
[SLOT_BASE + sizeof.APPDATA + APPDATA.io_map], PG_READ
|
||||
stdcall map_page, tss._io_map_1, \
|
||||
[APPDATA_IDLE_THREAD + APPDATA.io_map + 4], PG_READ
|
||||
[SLOT_BASE + sizeof.APPDATA + APPDATA.io_map + 4], PG_READ
|
||||
|
||||
; SET KEYBOARD PARAMETERS
|
||||
mov al, 0xf6 ; reset keyboard, scan enabled
|
||||
@@ -1633,6 +1634,7 @@ sys_getsetup:
|
||||
; 10 = not used
|
||||
; 11 = get the state "lba read"
|
||||
; 12 = get the state "pci access"
|
||||
; 13 = get device the ramdisk was loaded from
|
||||
;-----------------------------------------------------------------------------
|
||||
; F.26.2 - get keyboard layout
|
||||
sub ebx, 2
|
||||
@@ -1724,12 +1726,21 @@ sys_getsetup:
|
||||
@@:
|
||||
; F.26.12 - Find out whether low-level PCI access is enabled
|
||||
dec ebx
|
||||
jnz .error
|
||||
jnz @f
|
||||
|
||||
mov eax, [pci_access_enabled]
|
||||
mov [esp + SYSCALL_STACK.eax], eax
|
||||
ret
|
||||
;--------------------------------------
|
||||
@@:
|
||||
; F.26.13 - get device the ramdisk was loaded from, RD_LOAD_FROM_*
|
||||
dec ebx
|
||||
jnz .error
|
||||
|
||||
movzx eax, byte [BOOT.rd_load_from]
|
||||
mov [esp + SYSCALL_STACK.eax], eax
|
||||
ret
|
||||
;--------------------------------------
|
||||
.error:
|
||||
or [esp + SYSCALL_STACK.eax], -1
|
||||
ret
|
||||
@@ -1864,7 +1875,7 @@ sysfn_shutdown: ; 18.9 = system shutdown
|
||||
; out: Z/z -- is/not kernel thread
|
||||
is_kernel_thread:
|
||||
mov eax, [eax + APPDATA.process]
|
||||
cmp eax, [APPDATA_OS_THREAD + APPDATA.process] ; OS
|
||||
cmp eax, [SLOT_BASE + 2*sizeof.APPDATA + APPDATA.process] ; OS
|
||||
ret
|
||||
;------------------------------------------------------------------------------
|
||||
sysfn_terminate: ; 18.2 = TERMINATE
|
||||
@@ -2064,7 +2075,7 @@ sysfn_zmodif:
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
sysfn_getidletime: ; 18.4 = GET IDLETIME
|
||||
mov eax, [APPDATA_IDLE_THREAD + APPDATA.cpu_usage]
|
||||
mov eax, [SLOT_BASE + sizeof.APPDATA + APPDATA.cpu_usage]
|
||||
mov [esp + SYSCALL_STACK.eax], eax
|
||||
ret
|
||||
;------------------------------------------------------------------------------
|
||||
@@ -2824,7 +2835,7 @@ no_mark_system_shutdown:
|
||||
align 4
|
||||
noshutdown:
|
||||
mov eax, [thread_count] ; termination
|
||||
mov ebx, APPDATA_IDLE_THREAD + APPDATA.state
|
||||
mov ebx, SLOT_BASE + sizeof.APPDATA + APPDATA.state
|
||||
mov esi, 1
|
||||
;--------------------------------------
|
||||
align 4
|
||||
|
||||
@@ -2124,11 +2124,11 @@ socket_free:
|
||||
mov ebx, eax
|
||||
cmp [eax + STREAM_SOCKET.rcv.start_ptr], 0
|
||||
je @f
|
||||
stdcall kernel_free, [eax + STREAM_SOCKET.rcv.start_ptr]
|
||||
stdcall free_kernel_space, [eax + STREAM_SOCKET.rcv.start_ptr]
|
||||
@@:
|
||||
cmp [ebx + STREAM_SOCKET.snd.start_ptr], 0
|
||||
je @f
|
||||
stdcall kernel_free, [ebx + STREAM_SOCKET.snd.start_ptr]
|
||||
stdcall free_kernel_space, [ebx + STREAM_SOCKET.snd.start_ptr]
|
||||
@@:
|
||||
mov eax, ebx
|
||||
.no_stream:
|
||||
|
||||
@@ -118,7 +118,7 @@ SS_MORETOCOME = 0x4000
|
||||
SS_BLOCKED = 0x8000
|
||||
|
||||
|
||||
SOCKET_BUFFER_SIZE = 4096*32 ; must be 4096*(power of 2) where 'power of 2' is at least 8
|
||||
SOCKET_BUFFER_SIZE = 4096*8 ; must be 4096*(power of 2) where 'power of 2' is at least 8
|
||||
MAX_backlog = 20 ; maximum backlog for stream sockets
|
||||
|
||||
; Error Codes
|
||||
|
||||
@@ -148,10 +148,9 @@ ReadNoteByte:
|
||||
push esi
|
||||
|
||||
mov eax, [pidProcessNote]
|
||||
call pid_to_thread
|
||||
call pid_to_slot
|
||||
test eax, eax
|
||||
jz .failed
|
||||
|
||||
lea ecx, [esp+12]
|
||||
mov edx, 1
|
||||
mov esi, [memAdrNote]
|
||||
|
||||
+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
|
||||
|
||||
@@ -84,6 +84,12 @@ SF_SCREEN_PUT_IMAGE=25
|
||||
SF_SYSTEM_GET=26
|
||||
SSF_TIME_COUNT=9
|
||||
SSF_TIME_COUNT_PRO=10
|
||||
SSF_RD_BOOT_SOURCE=13
|
||||
RD_LOAD_FROM_FLOPPY=1
|
||||
RD_LOAD_FROM_HD=2
|
||||
RD_LOAD_FROM_MEMORY=3
|
||||
RD_LOAD_FROM_FORMAT=4
|
||||
RD_LOAD_FROM_NONE=5
|
||||
SF_GET_SYS_DATE=29
|
||||
SF_CURRENT_FOLDER=30
|
||||
SSF_SET_CF=1
|
||||
|
||||
+1
-1
Submodule programs/cmm updated: 86b0211da7...4678e1605d.
@@ -1,2 +0,0 @@
|
||||
@fasm free3d04.asm free3d04
|
||||
if not exist free3d04 ( @pause )
|
||||
@@ -1,6 +1,5 @@
|
||||
@erase lang.inc
|
||||
@echo lang fix en_US >lang.inc
|
||||
@fasm end.asm end
|
||||
@kpack end
|
||||
@fasm free3d04.asm free3d04
|
||||
@erase lang.inc
|
||||
@pause
|
||||
@@ -1,6 +1,5 @@
|
||||
@erase lang.inc
|
||||
@echo lang fix ru_RU >lang.inc
|
||||
@fasm end.asm end
|
||||
@kpack end
|
||||
@fasm free3d04.asm free3d04
|
||||
@erase lang.inc
|
||||
@pause
|
||||
@@ -9,10 +9,9 @@
|
||||
;
|
||||
; Compile with FASM for Menuet (requires .INC files - see DATA Section)
|
||||
;
|
||||
; Willow - greatly srinked code size by using packed texture and FPU to calculate sine table
|
||||
; Willow - greatly srinked code size by using GIF texture and FPU to calculate sine table
|
||||
;
|
||||
; Textures are stored as a single 64x512 PNG embedded into the binary and
|
||||
; decoded at startup with libimg.
|
||||
; !!!! Don't use GIF_LITE.INC in your apps - it's modified for FREE3D !!!!
|
||||
;
|
||||
; Heavyiron - new 0-function of drawing window from kolibri (do not work correctly with menuet)
|
||||
|
||||
@@ -39,17 +38,15 @@ use32
|
||||
dd APP_MEM;0x100000 ; memory for app
|
||||
dd APP_MEM;0x100000 ; esp
|
||||
dd 0x0 , 0x0 ; I_Param , I_Icon
|
||||
include 'lang.inc'
|
||||
include '..\..\macros.inc'
|
||||
include '..\..\proc32.inc'
|
||||
include '..\..\dll.inc'
|
||||
include '..\..\develop\libraries\libs-dev\libimg\libimg.inc'
|
||||
COLOR_ORDER equ OTHER
|
||||
include 'gif_lite.inc'
|
||||
|
||||
START: ; start of execution
|
||||
mcall 68,11 ; init heap, libimg needs it
|
||||
stdcall dll.Load,@IMPORT
|
||||
test eax,eax
|
||||
jnz finish
|
||||
call load_textures
|
||||
mov esi,textures
|
||||
mov edi,ceil-8
|
||||
call ReadGIF
|
||||
mov esi,sinus
|
||||
mov ecx,360*10
|
||||
fninit
|
||||
@@ -294,34 +291,6 @@ m_right: ; turn right
|
||||
mcall
|
||||
|
||||
|
||||
; *********************************************
|
||||
; ******* LOAD TEXTURES ********
|
||||
; *********************************************
|
||||
; Decodes the embedded 64x512 PNG (8 stacked 64x64 tiles) into the raw
|
||||
; 0x00RRGGBB texture bank at [ceil].
|
||||
|
||||
load_textures:
|
||||
invoke img.decode,textures,textures.size,0
|
||||
test eax,eax
|
||||
jz finish
|
||||
mov ebx,eax
|
||||
invoke img.convert,ebx,0,Image.bpp32,0,0
|
||||
push eax
|
||||
invoke img.destroy,ebx
|
||||
pop ebx
|
||||
test ebx,ebx
|
||||
jz finish
|
||||
mov esi,[ebx+Image.Data]
|
||||
mov edi,ceil
|
||||
mov ecx,TEX_SIZE*8/4
|
||||
.copy:
|
||||
lodsd
|
||||
and eax,0x00FFFFFF ; drop alpha, the renderer stores 32 bit dwords
|
||||
stosd ; into a 24 bit image buffer
|
||||
loop .copy
|
||||
invoke img.destroy,ebx
|
||||
ret
|
||||
|
||||
; *********************************************
|
||||
; ******* WINDOW DEFINITIONS AND DRAW ********
|
||||
; *********************************************
|
||||
@@ -1011,21 +980,13 @@ dd 0x0001FFFF ; initial player position * 0xFFFF
|
||||
vpy:
|
||||
dd 0x0001FFFF
|
||||
|
||||
title db 'Fisheye Raycasting Engine Etc. FREE3D',0
|
||||
title db 'FISHEYE RAYCASTING ENGINE ETC. FREE3D',0
|
||||
|
||||
sindegree dd 0.0
|
||||
sininc dd 0.0017453292519943295769236907684886
|
||||
sindiv dd 6553.5
|
||||
textures:
|
||||
file 'texture.png'
|
||||
.size = $ - textures
|
||||
|
||||
align 16
|
||||
@IMPORT:
|
||||
|
||||
library libimg , 'libimg.obj'
|
||||
|
||||
import libimg , libimg.init , 'lib_init' , img.decode , 'img_decode' , img.convert , 'img_convert', img.destroy , 'img_destroy'
|
||||
file 'texture.gif'
|
||||
|
||||
align 4
|
||||
|
||||
|
||||
@@ -0,0 +1,487 @@
|
||||
; GIF LITE v3.0 by Willow
|
||||
; Written in pure assembler by Ivushkin Andrey aka Willow
|
||||
; Modified by Diamond
|
||||
;
|
||||
; This include file will contain functions to handle GIF image format
|
||||
;
|
||||
; Created: August 15, 2004
|
||||
; Last changed: June 24, 2007
|
||||
|
||||
; Requires kglobals.inc (iglobal/uglobal macro)
|
||||
; (program must 'include "kglobals.inc"' and say 'IncludeUGlobal'
|
||||
; somewhere in uninitialized data area).
|
||||
|
||||
; Configuration: [changed from program which includes this file]
|
||||
; 1. The constant COLOR_ORDER: must be one of
|
||||
; PALETTE - for 8-bit image with palette (sysfunction 65)
|
||||
; MENUETOS - for MenuetOS and KolibriOS color order (sysfunction 7)
|
||||
; OTHER - for standard color order
|
||||
; 2. Define constant GIF_SUPPORT_INTERLACED if you want to support interlaced
|
||||
; GIFs.
|
||||
; 3. Single image mode vs multiple image mode:
|
||||
; if the program defines the variable 'gif_img_count' of type dword
|
||||
; somewhere, ReadGIF will enter multiple image mode: gif_img_count
|
||||
; will be initialized with image count, output format is GIF_list,
|
||||
; the function GetGIFinfo retrieves Nth image info. Otherwise, ReadGIF
|
||||
; uses single image mode: exit after end of first image, output is
|
||||
; <dd width,height, times width*height[*3] db image>
|
||||
|
||||
if ~ (COLOR_ORDER in <PALETTE,MENUETOS,OTHER>)
|
||||
; This message may not appear under MenuetOS, so watch...
|
||||
display 'Please define COLOR_ORDER: PALETTE, MENUETOS or OTHER',13,10
|
||||
end if
|
||||
|
||||
if defined gif_img_count
|
||||
; virtual structure, used internally
|
||||
|
||||
struct GIF_list
|
||||
NextImg rd 1
|
||||
Left rw 1
|
||||
Top rw 1
|
||||
Width rw 1
|
||||
Height rw 1
|
||||
Delay rd 1
|
||||
Displacement rd 1 ; 0 = not specified
|
||||
; 1 = do not dispose
|
||||
; 2 = restore to background color
|
||||
; 3 = restore to previous
|
||||
if COLOR_ORDER eq PALETTE
|
||||
Image rd 1
|
||||
end if
|
||||
ends
|
||||
|
||||
struct GIF_info
|
||||
Left rw 1
|
||||
Top rw 1
|
||||
Width rw 1
|
||||
Height rw 1
|
||||
Delay rd 1
|
||||
Displacement rd 1
|
||||
if COLOR_ORDER eq PALETTE
|
||||
Palette rd 1
|
||||
end if
|
||||
ends
|
||||
|
||||
; ****************************************
|
||||
; FUNCTION GetGIFinfo - retrieve Nth image info
|
||||
; ****************************************
|
||||
; in:
|
||||
; esi - pointer to image list header
|
||||
; ecx - image_index (0...img_count-1)
|
||||
; edi - pointer to GIF_info structure to be filled
|
||||
|
||||
; out:
|
||||
; eax - pointer to RAW data, or 0, if error
|
||||
|
||||
GetGIFinfo:
|
||||
push esi ecx edi
|
||||
xor eax,eax
|
||||
jecxz .eloop
|
||||
.lp:
|
||||
mov esi,[esi]
|
||||
test esi,esi
|
||||
jz .error
|
||||
loop .lp
|
||||
.eloop:
|
||||
lodsd
|
||||
movsd
|
||||
movsd
|
||||
movsd
|
||||
movsd
|
||||
if COLOR_ORDER eq PALETTE
|
||||
lodsd
|
||||
mov [edi],esi
|
||||
else
|
||||
mov eax,esi
|
||||
end if
|
||||
.error:
|
||||
pop edi ecx esi
|
||||
ret
|
||||
|
||||
end if
|
||||
|
||||
_null fix 0x1000
|
||||
|
||||
; ****************************************
|
||||
; FUNCTION ReadGIF - unpacks GIF image
|
||||
; ****************************************
|
||||
; in:
|
||||
; esi - pointer to GIF file in memory
|
||||
; edi - pointer to output image list
|
||||
|
||||
; out:
|
||||
; eax - 0, all OK;
|
||||
; eax - 1, invalid signature;
|
||||
; eax >=8, unsupported image attributes
|
||||
;
|
||||
|
||||
ReadGIF:
|
||||
push esi edi
|
||||
mov [.cur_info],edi
|
||||
xor eax,eax
|
||||
mov [.globalColor],eax
|
||||
if defined gif_img_count
|
||||
mov [gif_img_count],eax
|
||||
mov [.anim_delay],eax
|
||||
mov [.anim_disp],eax
|
||||
end if
|
||||
inc eax
|
||||
cmp dword[esi],'GIF8'
|
||||
jne .ex ; signature
|
||||
mov ecx,[esi+0xa]
|
||||
add esi,0xd
|
||||
mov edi,esi
|
||||
test cl,cl
|
||||
jns .nextblock
|
||||
mov [.globalColor],esi
|
||||
call .Gif_skipmap
|
||||
.nextblock:
|
||||
cmp byte[edi],0x21
|
||||
jne .noextblock
|
||||
inc edi
|
||||
if defined gif_img_count
|
||||
cmp byte[edi],0xf9 ; Graphic Control Ext
|
||||
jne .no_gc
|
||||
movzx eax,word [edi+3]
|
||||
mov [.anim_delay],eax
|
||||
mov al,[edi+2]
|
||||
shr al,2
|
||||
and eax,7
|
||||
mov [.anim_disp],eax
|
||||
add edi,7
|
||||
jmp .nextblock
|
||||
.no_gc:
|
||||
end if
|
||||
inc edi
|
||||
.block_skip:
|
||||
movzx eax,byte[edi]
|
||||
lea edi,[edi+eax+1]
|
||||
test eax,eax
|
||||
jnz .block_skip
|
||||
jmp .nextblock
|
||||
.noextblock:
|
||||
mov al,8
|
||||
cmp byte[edi],0x2c ; image beginning
|
||||
jne .ex
|
||||
if defined gif_img_count
|
||||
inc [gif_img_count]
|
||||
end if
|
||||
inc edi
|
||||
mov esi,[.cur_info]
|
||||
if defined gif_img_count
|
||||
add esi,4
|
||||
end if
|
||||
xchg esi,edi
|
||||
if defined GIF_SUPPORT_INTERLACED
|
||||
movzx ecx,word[esi+4]
|
||||
mov [.width],ecx
|
||||
movzx eax,word[esi+6]
|
||||
imul eax,ecx
|
||||
if ~(COLOR_ORDER eq PALETTE)
|
||||
lea eax,[eax*3]
|
||||
end if
|
||||
mov [.img_end],eax
|
||||
inc eax
|
||||
mov [.row_end],eax
|
||||
and [.pass],0
|
||||
test byte[esi+8],40h
|
||||
jz @f
|
||||
if ~(COLOR_ORDER eq PALETTE)
|
||||
lea ecx,[ecx*3]
|
||||
end if
|
||||
mov [.row_end],ecx
|
||||
@@:
|
||||
end if
|
||||
if defined gif_img_count
|
||||
movsd
|
||||
movsd
|
||||
mov eax,[.anim_delay]
|
||||
stosd
|
||||
mov eax,[.anim_disp]
|
||||
stosd
|
||||
else
|
||||
movzx eax,word[esi+4]
|
||||
stosd
|
||||
movzx eax,word[esi+6]
|
||||
stosd
|
||||
add esi,8
|
||||
end if
|
||||
push edi
|
||||
mov ecx,[esi]
|
||||
inc esi
|
||||
test cl,cl
|
||||
js .uselocal
|
||||
push [.globalColor]
|
||||
mov edi,esi
|
||||
jmp .setPal
|
||||
.uselocal:
|
||||
call .Gif_skipmap
|
||||
push esi
|
||||
.setPal:
|
||||
movzx ecx,byte[edi]
|
||||
inc ecx
|
||||
mov [.codesize],ecx
|
||||
dec ecx
|
||||
if ~(COLOR_ORDER eq PALETTE)
|
||||
pop [.Palette]
|
||||
end if
|
||||
lea esi,[edi+1]
|
||||
mov edi,.gif_workarea
|
||||
xor eax,eax
|
||||
lodsb ; eax - block_count
|
||||
add eax,esi
|
||||
mov [.block_ofs],eax
|
||||
mov [.bit_count],8
|
||||
mov eax,1
|
||||
shl eax,cl
|
||||
mov [.CC],eax
|
||||
mov ecx,eax
|
||||
inc eax
|
||||
mov [.EOI],eax
|
||||
mov eax, _null shl 16
|
||||
.filltable:
|
||||
stosd
|
||||
inc eax
|
||||
loop .filltable
|
||||
if COLOR_ORDER eq PALETTE
|
||||
pop eax
|
||||
pop edi
|
||||
push edi
|
||||
scasd
|
||||
push esi
|
||||
mov esi,eax
|
||||
mov ecx,[.CC]
|
||||
@@:
|
||||
lodsd
|
||||
dec esi
|
||||
bswap eax
|
||||
shr eax,8
|
||||
stosd
|
||||
loop @b
|
||||
pop esi
|
||||
pop eax
|
||||
mov [eax],edi
|
||||
else
|
||||
pop edi
|
||||
end if
|
||||
if defined GIF_SUPPORT_INTERLACED
|
||||
mov [.img_start],edi
|
||||
add [.img_end],edi
|
||||
add [.row_end],edi
|
||||
end if
|
||||
.reinit:
|
||||
mov edx,[.EOI]
|
||||
inc edx
|
||||
push [.codesize]
|
||||
pop [.compsize]
|
||||
call .Gif_get_sym
|
||||
cmp eax,[.CC]
|
||||
je .reinit
|
||||
call .Gif_output
|
||||
.cycle:
|
||||
movzx ebx,ax
|
||||
call .Gif_get_sym
|
||||
cmp eax,edx
|
||||
jae .notintable
|
||||
cmp eax,[.CC]
|
||||
je .reinit
|
||||
cmp eax,[.EOI]
|
||||
je .end
|
||||
call .Gif_output
|
||||
.add:
|
||||
mov dword [.gif_workarea+edx*4],ebx
|
||||
cmp edx,0xFFF
|
||||
jae .cycle
|
||||
inc edx
|
||||
bsr ebx,edx
|
||||
cmp ebx,[.compsize]
|
||||
jne .noinc
|
||||
inc [.compsize]
|
||||
.noinc:
|
||||
jmp .cycle
|
||||
.notintable:
|
||||
push eax
|
||||
mov eax,ebx
|
||||
call .Gif_output
|
||||
push ebx
|
||||
movzx eax,bx
|
||||
call .Gif_output
|
||||
pop ebx eax
|
||||
jmp .add
|
||||
.end:
|
||||
if defined GIF_SUPPORT_INTERLACED
|
||||
mov edi,[.img_end]
|
||||
end if
|
||||
if defined gif_img_count
|
||||
mov eax,[.cur_info]
|
||||
mov [eax],edi
|
||||
mov [.cur_info],edi
|
||||
add esi,2
|
||||
xchg esi,edi
|
||||
.nxt:
|
||||
cmp byte[edi],0
|
||||
jnz .continue
|
||||
inc edi
|
||||
jmp .nxt
|
||||
.continue:
|
||||
cmp byte[edi],0x3b
|
||||
jne .nextblock
|
||||
xchg esi,edi
|
||||
and dword [eax],0
|
||||
end if
|
||||
xor eax,eax
|
||||
.ex:
|
||||
pop edi esi
|
||||
ret
|
||||
|
||||
.Gif_skipmap:
|
||||
; in: ecx - image descriptor, esi - pointer to colormap
|
||||
; out: edi - pointer to area after colormap
|
||||
|
||||
and ecx,111b
|
||||
inc ecx ; color map size
|
||||
mov ebx,1
|
||||
shl ebx,cl
|
||||
lea ebx,[ebx*2+ebx]
|
||||
lea edi,[esi+ebx]
|
||||
ret
|
||||
|
||||
.Gif_get_sym:
|
||||
mov ecx,[.compsize]
|
||||
push ecx
|
||||
xor eax,eax
|
||||
.shift:
|
||||
ror byte[esi],1
|
||||
rcr eax,1
|
||||
dec [.bit_count]
|
||||
jnz .loop1
|
||||
inc esi
|
||||
cmp esi,[.block_ofs]
|
||||
jb .noblock
|
||||
push eax
|
||||
xor eax,eax
|
||||
lodsb
|
||||
test eax,eax
|
||||
jnz .nextbl
|
||||
mov eax,[.EOI]
|
||||
sub esi,2
|
||||
add esp,8
|
||||
jmp .exx
|
||||
.nextbl:
|
||||
add eax,esi
|
||||
mov [.block_ofs],eax
|
||||
pop eax
|
||||
.noblock:
|
||||
mov [.bit_count],8
|
||||
.loop1:
|
||||
loop .shift
|
||||
pop ecx
|
||||
rol eax,cl
|
||||
.exx:
|
||||
xor ecx,ecx
|
||||
ret
|
||||
|
||||
.Gif_output:
|
||||
push esi eax edx
|
||||
mov edx,.gif_workarea
|
||||
.next:
|
||||
push word[edx+eax*4]
|
||||
mov ax,word[edx+eax*4+2]
|
||||
inc ecx
|
||||
cmp ax,_null
|
||||
jnz .next
|
||||
shl ebx,16
|
||||
mov bx,[esp]
|
||||
.loop2:
|
||||
pop ax
|
||||
|
||||
if COLOR_ORDER eq PALETTE
|
||||
stosb
|
||||
else
|
||||
lea esi,[eax+eax*2]
|
||||
add esi,[.Palette]
|
||||
|
||||
if COLOR_ORDER eq MENUETOS
|
||||
mov esi,[esi]
|
||||
bswap esi
|
||||
shr esi,8
|
||||
mov [edi],esi
|
||||
add edi,3
|
||||
else
|
||||
movsb
|
||||
movsb
|
||||
movsb
|
||||
mov byte [edi],0
|
||||
inc edi
|
||||
end if
|
||||
end if
|
||||
|
||||
if defined GIF_SUPPORT_INTERLACED
|
||||
cmp edi,[.row_end]
|
||||
jb .norowend
|
||||
mov eax,[.width]
|
||||
if ~(COLOR_ORDER eq PALETTE)
|
||||
lea eax,[eax*3]
|
||||
end if
|
||||
push eax
|
||||
sub edi,eax
|
||||
add eax,eax
|
||||
cmp [.pass],3
|
||||
jz @f
|
||||
add eax,eax
|
||||
cmp [.pass],2
|
||||
jz @f
|
||||
add eax,eax
|
||||
@@:
|
||||
add edi,eax
|
||||
pop eax
|
||||
cmp edi,[.img_end]
|
||||
jb .nextrow
|
||||
mov edi,[.img_start]
|
||||
inc [.pass]
|
||||
add edi,eax
|
||||
cmp [.pass],3
|
||||
jz @f
|
||||
add edi,eax
|
||||
cmp [.pass],2
|
||||
jz @f
|
||||
add edi,eax
|
||||
add edi,eax
|
||||
@@:
|
||||
.nextrow:
|
||||
add eax,edi
|
||||
mov [.row_end],eax
|
||||
xor eax,eax
|
||||
.norowend:
|
||||
end if
|
||||
|
||||
loop .loop2
|
||||
pop edx eax esi
|
||||
ret
|
||||
|
||||
uglobal
|
||||
align 4
|
||||
ReadGIF.globalColor rd 1
|
||||
ReadGIF.cur_info rd 1 ; image table pointer
|
||||
ReadGIF.codesize rd 1
|
||||
ReadGIF.compsize rd 1
|
||||
ReadGIF.bit_count rd 1
|
||||
ReadGIF.CC rd 1
|
||||
ReadGIF.EOI rd 1
|
||||
if ~(COLOR_ORDER eq PALETTE)
|
||||
ReadGIF.Palette rd 1
|
||||
end if
|
||||
ReadGIF.block_ofs rd 1
|
||||
if defined GIF_SUPPORT_INTERLACED
|
||||
ReadGIF.row_end rd 1
|
||||
ReadGIF.img_end rd 1
|
||||
ReadGIF.img_start rd 1
|
||||
ReadGIF.pass rd 1
|
||||
ReadGIF.width rd 1
|
||||
end if
|
||||
if defined gif_img_count
|
||||
ReadGIF.anim_delay rd 1
|
||||
ReadGIF.anim_disp rd 1
|
||||
end if
|
||||
ReadGIF.gif_workarea rb 16*1024
|
||||
endg
|
||||
@@ -10,11 +10,11 @@ By Dieter Marfurt
|
||||
|
||||
--------------------------------------------
|
||||
|
||||
Format of the texture file:
|
||||
Format of texture include files:
|
||||
|
||||
texture.png - a 64*512 image holding the 8 textures of 64*64 pixels
|
||||
stacked vertically. It is embedded into the binary and decoded at
|
||||
startup with libimg.
|
||||
dd 0x00RRGGBB,0x00RRGGBB....
|
||||
|
||||
for 64*64 pixels.
|
||||
|
||||
Have fun!
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 28 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 14 KiB |
@@ -238,6 +238,7 @@ BEGIN
|
||||
m.active := FALSE;
|
||||
resetTimer;
|
||||
m.tid := 0;
|
||||
G.destroy(m.canvas);
|
||||
K.Exit
|
||||
END exit;
|
||||
|
||||
@@ -249,6 +250,7 @@ BEGIN
|
||||
resetTimer
|
||||
END;
|
||||
m.tid := 0;
|
||||
G.destroy(m.canvas);
|
||||
K.Exit
|
||||
END escape;
|
||||
|
||||
@@ -354,6 +356,7 @@ BEGIN
|
||||
END;
|
||||
temp := m.tid;
|
||||
m.tid := 0;
|
||||
G.destroy(m.canvas);
|
||||
K.ExitID(temp);
|
||||
m.active := FALSE
|
||||
END
|
||||
@@ -509,6 +512,7 @@ BEGIN
|
||||
IF m.parent # NIL THEN
|
||||
temp := m.parent.tid;
|
||||
m.parent.tid := 0;
|
||||
G.destroy(m.parent.canvas);
|
||||
K.ExitID(temp)
|
||||
END;
|
||||
exit(m)
|
||||
|
||||
@@ -181,7 +181,6 @@ con_cls
|
||||
con_get_cursor_pos
|
||||
con_set_cursor_pos
|
||||
;____TIME____
|
||||
clock
|
||||
mktime
|
||||
time
|
||||
localtime
|
||||
|
||||
@@ -5,7 +5,7 @@ void shell_cls()
|
||||
__shell_init();
|
||||
if (__shell_is_init == __SHELL_INIT_OK)
|
||||
{
|
||||
__shell_shm->cmd = SHELL_CLS;
|
||||
*__shell_shm = SHELL_CLS;
|
||||
__SHELL_WAIT();
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ void shell_exit()
|
||||
{
|
||||
if (__shell_is_init == __SHELL_INIT_OK)
|
||||
{
|
||||
__shell_shm->cmd = SHELL_EXIT;
|
||||
*__shell_shm = SHELL_EXIT;
|
||||
__SHELL_WAIT();
|
||||
_ksys_shm_close(__shell_shm_name);
|
||||
}
|
||||
|
||||
@@ -8,9 +8,9 @@ unsigned shell_get_pid()
|
||||
__shell_init();
|
||||
if (__shell_is_init == __SHELL_INIT_OK)
|
||||
{
|
||||
__shell_shm->cmd = SHELL_PID;
|
||||
*__shell_shm = SHELL_PID;
|
||||
__SHELL_WAIT();
|
||||
memcpy(&pid, __shell_shm->data, sizeof(unsigned));
|
||||
memcpy(&pid, __shell_shm + 1, sizeof(unsigned));
|
||||
}
|
||||
|
||||
return pid;
|
||||
|
||||
@@ -6,10 +6,10 @@ char shell_getc()
|
||||
|
||||
if (__shell_is_init == __SHELL_INIT_OK)
|
||||
{
|
||||
__shell_shm->cmd = SHELL_GETC;
|
||||
*__shell_shm = SHELL_GETC;
|
||||
__SHELL_WAIT();
|
||||
|
||||
return __shell_shm->data[0];
|
||||
return *(__shell_shm + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -7,9 +7,9 @@ void shell_gets(char *str, int n)
|
||||
|
||||
if (__shell_is_init == __SHELL_INIT_OK)
|
||||
{
|
||||
__shell_shm->cmd = SHELL_GETS;
|
||||
*__shell_shm = SHELL_GETS;
|
||||
__SHELL_WAIT();
|
||||
|
||||
strncpy(str, __shell_shm->data, n);
|
||||
strncpy(str, __shell_shm + 1, n);
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
char app_name[13];
|
||||
char __shell_shm_name[32];
|
||||
struct shell_shm_buffer *__shell_shm = NULL;
|
||||
char *__shell_shm = NULL;
|
||||
enum __SHELL_INIT_STATE __shell_is_init = __SHELL_NOT_LOADED;
|
||||
|
||||
int __shell_shm_init()
|
||||
@@ -17,12 +17,12 @@ int __shell_shm_init()
|
||||
|
||||
_ksys_thread_info(&proc_info, -1);
|
||||
PID = proc_info.pid;
|
||||
strncpy(app_name, proc_info.name, sizeof(app_name) - 1);
|
||||
strncpy(app_name, (&proc_info)->name, 12);
|
||||
|
||||
itoa(PID, __shell_shm_name);
|
||||
strcat(__shell_shm_name, "-SHELL");
|
||||
|
||||
return _ksys_shm_open(__shell_shm_name, KSYS_SHM_OPEN_ALWAYS | KSYS_SHM_WRITE, sizeof(*__shell_shm), (char **)&__shell_shm);
|
||||
return _ksys_shm_open(__shell_shm_name, KSYS_SHM_OPEN_ALWAYS | KSYS_SHM_WRITE, SHELL_SHM_MAX, &__shell_shm);
|
||||
}
|
||||
|
||||
void __shell_init()
|
||||
|
||||
@@ -7,12 +7,12 @@
|
||||
|
||||
int shell_ping()
|
||||
{
|
||||
__shell_shm->cmd = SHELL_PING;
|
||||
*__shell_shm = SHELL_PING;
|
||||
|
||||
_ksys_thread_yield(); // hope shell is fast enough
|
||||
|
||||
size_t i = 0;
|
||||
while (__shell_shm->cmd != SHELL_OK)
|
||||
while (*__shell_shm != SHELL_OK)
|
||||
{
|
||||
if (i > (SHELL_PING_TIMEOUT / SHELL_PING_MIN_DELAY))
|
||||
{
|
||||
|
||||
@@ -5,8 +5,8 @@ void shell_printf(const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
vsnprintf(__shell_shm->data, sizeof(__shell_shm->data), format, ap);
|
||||
__shell_shm->cmd = SHELL_PUTS;
|
||||
vsnprintf(__shell_shm + 1, SHELL_SHM_MAX, format, ap);
|
||||
*__shell_shm = SHELL_PUTS;
|
||||
va_end(ap);
|
||||
__SHELL_WAIT();
|
||||
}
|
||||
@@ -6,8 +6,8 @@ void shell_putc(char c)
|
||||
|
||||
if (__shell_is_init == __SHELL_INIT_OK)
|
||||
{
|
||||
__shell_shm->data[0] = c;
|
||||
__shell_shm->cmd = SHELL_PUTC;
|
||||
*(__shell_shm + 1) = c;
|
||||
*__shell_shm = SHELL_PUTC;
|
||||
__SHELL_WAIT();
|
||||
}
|
||||
}
|
||||
@@ -6,16 +6,16 @@ void shell_write_string(const char *s, size_t len)
|
||||
__shell_init();
|
||||
if (__shell_is_init == __SHELL_INIT_OK)
|
||||
{
|
||||
if (len > sizeof(__shell_shm->data) - 1)
|
||||
if (len > SHELL_SHM_MAX - 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.
|
||||
shell_write_string(s, SHELL_SHM_MAX - 1); // Outputs as much as it can.
|
||||
shell_write_string(s + (SHELL_SHM_MAX - 1), len - (SHELL_SHM_MAX - 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);
|
||||
__shell_shm->cmd = SHELL_PUTS;
|
||||
memset(__shell_shm, 0, SHELL_SHM_MAX); // without int shell show \t, \n, lose chars and other trash
|
||||
memcpy(__shell_shm + 1, s, len);
|
||||
*__shell_shm = SHELL_PUTS;
|
||||
__SHELL_WAIT();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,17 +9,15 @@
|
||||
#define __EXTERN extern
|
||||
#endif
|
||||
|
||||
enum SHELL_API_COMMANDS {
|
||||
SHELL_OK = 0,
|
||||
SHELL_EXIT = 1,
|
||||
SHELL_PUTC = 2,
|
||||
SHELL_PUTS = 3,
|
||||
SHELL_GETC = 4,
|
||||
SHELL_GETS = 5,
|
||||
SHELL_CLS = 6,
|
||||
SHELL_PID = 7,
|
||||
SHELL_PING = 8
|
||||
};
|
||||
#define SHELL_OK 0
|
||||
#define SHELL_EXIT 1
|
||||
#define SHELL_PUTC 2
|
||||
#define SHELL_PUTS 3
|
||||
#define SHELL_GETC 4
|
||||
#define SHELL_GETS 5
|
||||
#define SHELL_CLS 6
|
||||
#define SHELL_PID 7
|
||||
#define SHELL_PING 8
|
||||
|
||||
#define SHELL_SHM_MAX 1024 * 16
|
||||
|
||||
@@ -30,22 +28,15 @@ enum __SHELL_INIT_STATE {
|
||||
__SHELL_INIT_FAILED = 3 // fail init shell
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct shell_shm_buffer {
|
||||
uint8_t cmd;
|
||||
char data[SHELL_SHM_MAX - sizeof(((struct shell_shm_buffer*)NULL)->cmd)];
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
__EXTERN char __shell_shm_name[32];
|
||||
__EXTERN struct shell_shm_buffer* __shell_shm;
|
||||
__EXTERN char* __shell_shm;
|
||||
__EXTERN enum __SHELL_INIT_STATE __shell_is_init;
|
||||
__EXTERN void __shell_init();
|
||||
|
||||
#define __SHELL_WAIT() \
|
||||
do { \
|
||||
_ksys_thread_yield(); \
|
||||
} while (__shell_shm->cmd);
|
||||
} while (*__shell_shm);
|
||||
|
||||
__EXTERN int shell_ping();
|
||||
__EXTERN unsigned shell_get_pid();
|
||||
@@ -61,5 +52,4 @@ __EXTERN void shell_printf(const char* format, ...);
|
||||
__EXTERN void shell_write_string(const char* s, size_t len);
|
||||
|
||||
__EXTERN void shell_cls();
|
||||
|
||||
#endif
|
||||
@@ -1,10 +1,11 @@
|
||||
#ifndef _TIME_H_
|
||||
#define _TIME_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <sys/ksys.h>
|
||||
|
||||
typedef unsigned long int clock_t;
|
||||
typedef unsigned long int time_t;
|
||||
#define clock() _ksys_get_clock()
|
||||
#define CLOCKS_PER_SEC 100
|
||||
|
||||
#pragma pack(push, 1)
|
||||
@@ -21,7 +22,6 @@ struct tm {
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
DLLAPI clock_t clock(void);
|
||||
DLLAPI time_t mktime(struct tm* timeptr);
|
||||
DLLAPI time_t time(time_t* timer);
|
||||
DLLAPI struct tm* localtime(const time_t* timer);
|
||||
|
||||
@@ -119,7 +119,6 @@
|
||||
#include "math/sinh.c"
|
||||
#include "math/tanh.c"
|
||||
|
||||
#include "time/clock.c"
|
||||
#include "time/asctime.c"
|
||||
#include "time/difftime.c"
|
||||
#include "time/localtime.c"
|
||||
@@ -339,7 +338,6 @@ ksys_dll_t EXPORTS[] = {
|
||||
{ "con_cls", &con_cls },
|
||||
{ "con_get_cursor_pos", &con_get_cursor_pos },
|
||||
{ "con_set_cursor_pos", &con_set_cursor_pos },
|
||||
{ "clock", &clock },
|
||||
{ "mktime", &mktime },
|
||||
{ "time", &time },
|
||||
{ "localtime", &localtime },
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
#include <time.h>
|
||||
#include <sys/ksys.h>
|
||||
|
||||
clock_t clock(void)
|
||||
{
|
||||
return _ksys_get_tick_count();
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1178,18 +1178,17 @@ proc png_colorspace_set_gamma, png_ptr:dword, colorspace:dword, gAMA:dword
|
||||
; In 1.6.0 this test replaces the ones in pngrutil.c, in the gAMA chunk
|
||||
; handling code, which only required the value to be >0.
|
||||
|
||||
png_debug 1, 'in png_colorspace_set_gamma'
|
||||
; charp errmsg;
|
||||
|
||||
; if (gAMA < 16 || gAMA > 625000000)
|
||||
; errmsg = "gamma value out of range";
|
||||
|
||||
if PNG_READ_gAMA_SUPPORTED eq 1
|
||||
;# ifdef PNG_READ_gAMA_SUPPORTED
|
||||
; Allow the application to set the gamma value more than once
|
||||
; else if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&
|
||||
; (colorspace->flags & PNG_COLORSPACE_FROM_gAMA) != 0)
|
||||
; errmsg = "duplicate";
|
||||
end if
|
||||
;# endif
|
||||
|
||||
; Do nothing if the colorspace is already invalid
|
||||
; else if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0)
|
||||
|
||||
@@ -161,7 +161,8 @@ proc png_set_gAMA_fixed uses eax edi esi, png_ptr:dword, info_ptr:dword, file_ga
|
||||
or esi,esi
|
||||
jz .end_f ;if (..== 0 || ..== 0) return
|
||||
|
||||
lea eax,[esi+png_info_def.colorspace]
|
||||
mov eax,esi
|
||||
add eax,png_info_def.colorspace
|
||||
stdcall png_colorspace_set_gamma, edi, eax, [file_gamma]
|
||||
stdcall png_colorspace_sync_info, edi, esi
|
||||
.end_f:
|
||||
@@ -592,10 +593,8 @@ endp
|
||||
|
||||
;void (png_structrp png_ptr, png_inforp info_ptr, png_colorp palette, int num_palette)
|
||||
align 4
|
||||
proc png_set_PLTE uses eax ecx edi esi, png_ptr:dword, info_ptr:dword, palette:dword, num_palette:dword
|
||||
locals
|
||||
max_palette_length rd 1 ;uint_32
|
||||
endl
|
||||
proc png_set_PLTE uses eax edi esi, png_ptr:dword, info_ptr:dword, palette:dword, num_palette:dword
|
||||
; uint_32 max_palette_length;
|
||||
|
||||
png_debug1 1, 'in %s storage function', 'PLTE'
|
||||
|
||||
@@ -606,53 +605,31 @@ endl
|
||||
or esi,esi
|
||||
jz .end_f ;if (..==0 || ..==0) return
|
||||
|
||||
;max_palette_length = (..==..) ? .. : ..
|
||||
cmp byte[esi+png_info_def.color_type],PNG_COLOR_TYPE_PALETTE
|
||||
jne @f
|
||||
xor eax,eax
|
||||
inc eax
|
||||
movzx ecx,byte[esi+png_info_def.bit_depth]
|
||||
shl eax,cl
|
||||
mov [max_palette_length],eax
|
||||
jmp .end0
|
||||
@@:
|
||||
mov [max_palette_length],PNG_MAX_PALETTE_LENGTH
|
||||
.end0:
|
||||
; max_palette_length = (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ?
|
||||
; (1 << info_ptr->bit_depth) : PNG_MAX_PALETTE_LENGTH;
|
||||
|
||||
;if (..<0 || ..>..)
|
||||
cmp [num_palette],0
|
||||
jl @f
|
||||
mov eax,[max_palette_length]
|
||||
cmp [num_palette],eax
|
||||
jle .end1
|
||||
@@:
|
||||
cmp byte[edi+png_struct.color_type],PNG_COLOR_TYPE_PALETTE ;if (..==..)
|
||||
jne @f
|
||||
png_error edi, 'Invalid palette length'
|
||||
jmp .end1
|
||||
@@: ;else
|
||||
png_warning edi, 'Invalid palette length'
|
||||
jmp .end_f
|
||||
.end1:
|
||||
; if (num_palette < 0 || num_palette > (int) max_palette_length)
|
||||
; {
|
||||
; if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
|
||||
; png_error(png_ptr, "Invalid palette length");
|
||||
|
||||
cmp [num_palette],0
|
||||
jle @f
|
||||
cmp [palette],0
|
||||
je .end2
|
||||
@@:
|
||||
cmp [num_palette],0
|
||||
jne .end3
|
||||
;if ((..>0 && ..==0) || (..==0
|
||||
; else
|
||||
; {
|
||||
; png_warning(png_ptr, "Invalid palette length");
|
||||
|
||||
; return;
|
||||
; }
|
||||
; }
|
||||
|
||||
; if ((num_palette > 0 && palette == NULL) ||
|
||||
; (num_palette == 0
|
||||
if PNG_MNG_FEATURES_SUPPORTED eq 1
|
||||
; && (.. & PNG_FLAG_MNG_EMPTY_PLTE) == 0
|
||||
mov eax,[edi+png_struct.mng_features_permitted]
|
||||
and eax,PNG_FLAG_MNG_EMPTY_PLTE
|
||||
jnz .end3
|
||||
; && (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0
|
||||
end if
|
||||
;))
|
||||
.end2:
|
||||
png_error edi, 'Invalid palette'
|
||||
.end3:
|
||||
; ))
|
||||
; {
|
||||
; png_error(png_ptr, "Invalid palette");
|
||||
; }
|
||||
|
||||
; It may not actually be necessary to set png_ptr->palette here;
|
||||
; we do it for backward compatibility with the way the png_handle_tRNS
|
||||
@@ -667,26 +644,14 @@ end if
|
||||
; of num_palette entries, in case of an invalid PNG file or incorrect
|
||||
; call to png_set_PLTE() with too-large sample values.
|
||||
|
||||
stdcall png_calloc, edi, PNG_MAX_PALETTE_LENGTH*sizeof.png_color
|
||||
mov [edi+png_struct.palette],eax
|
||||
; png_ptr->palette = png_calloc(png_ptr,
|
||||
; PNG_MAX_PALETTE_LENGTH * (sizeof (png_color)));
|
||||
|
||||
;if (..>0)
|
||||
cmp [num_palette],0
|
||||
jle @f
|
||||
push esi edi
|
||||
mov ecx,[num_palette]
|
||||
imul ecx,sizeof.png_color
|
||||
mov esi,[palette]
|
||||
mov edi,eax
|
||||
rep movsb ;memcpy(png_ptr->palette, palette, ...
|
||||
pop edi esi
|
||||
@@:
|
||||
; if (num_palette > 0)
|
||||
; memcpy(png_ptr->palette, palette, num_palette * (sizeof (png_color)));
|
||||
mov eax,[edi+png_struct.palette]
|
||||
mov [esi+png_info_def.palette],eax
|
||||
|
||||
mov eax,[num_palette]
|
||||
mov [edi+png_struct.num_palette],ax
|
||||
mov [esi+png_info_def.num_palette],ax
|
||||
; info_ptr->num_palette = png_ptr->num_palette = (uint_16)num_palette;
|
||||
|
||||
or dword[esi+png_info_def.free_me], PNG_FREE_PLTE
|
||||
or dword[esi+png_info_def.valid], PNG_INFO_PLTE
|
||||
|
||||
@@ -1925,7 +1925,6 @@ locals
|
||||
aindex dd 0 ;int ;= 0
|
||||
y dd ? ;uint_32 ;= image->height
|
||||
endl
|
||||
png_debug 1, 'in png_write_image_16bit'
|
||||
mov ebx,[argument]
|
||||
mov [display],ebx
|
||||
mov edx,[ebx+png_image_write_control.image]
|
||||
@@ -2119,7 +2118,6 @@ locals
|
||||
y dd ? ;uint_32 ;= image->height
|
||||
component dd ? ;uint_32
|
||||
endl
|
||||
png_debug 1, 'in png_write_image_8bit'
|
||||
mov ebx,[argument]
|
||||
mov [display],ebx
|
||||
mov edx,[ebx+png_image_write_control.image]
|
||||
@@ -2259,11 +2257,9 @@ locals
|
||||
afirst dd 0
|
||||
bgr dd 0
|
||||
num_trans dd 0
|
||||
i dd ?
|
||||
palette rb 256*sizeof.png_color
|
||||
tRNS rb 256 ;byte[]
|
||||
endl
|
||||
png_debug 1, 'in png_image_set_PLTE'
|
||||
pushad
|
||||
mov edx,[display]
|
||||
mov ebx,[edx+png_image_write_control.image]
|
||||
@@ -2300,33 +2296,30 @@ if PNG_FORMAT_BGR_SUPPORTED eq 1
|
||||
@@:
|
||||
end if
|
||||
|
||||
; int i;
|
||||
|
||||
xor eax,eax
|
||||
mov ecx,(256*sizeof.png_color)/4
|
||||
lea edi,[ebp-256-256*sizeof.png_color]
|
||||
mov edi,ebp
|
||||
sub edi,256+256*sizeof.png_color
|
||||
rep stosd ;memset(palette, 0, ...
|
||||
not eax
|
||||
mov ecx,256/4
|
||||
;lea edi,[ebp-256] ;if 'tRNS' after 'palette' this code can be comment
|
||||
;;mov edi,ebp ;if 'tRNS' after 'palette' this code can be comment
|
||||
;;sub edi,256
|
||||
rep stosd ;memset(tRNS, 255, ...
|
||||
|
||||
mov [i],0
|
||||
lea edx,[ebp-256] ;edx=&tRNS
|
||||
lea edi,[edx-256*sizeof.png_color]
|
||||
align 4
|
||||
.cycle0: ;for (i=num_trans=0; i<entries; ++i)
|
||||
|
||||
; for (i=num_trans=0; i<entries; ++i)
|
||||
; {
|
||||
; This gets automatically converted to sRGB with reversal of the
|
||||
; pre-multiplication if the color-map has an alpha channel.
|
||||
|
||||
;if ((..&..) != 0)
|
||||
mov eax,[format]
|
||||
and eax,PNG_FORMAT_FLAG_LINEAR
|
||||
or eax,eax
|
||||
jz .end0
|
||||
mov esi,[cmap] ;esi=entry uint_16p
|
||||
mov eax,[channels]
|
||||
mov ecx,eax
|
||||
imul eax,[i]
|
||||
add esi,eax ;+=i*channels;
|
||||
; if ((format & PNG_FORMAT_FLAG_LINEAR) != 0)
|
||||
; {
|
||||
; png_const_uint_16p entry = cmap;
|
||||
|
||||
; entry += i * channels;
|
||||
|
||||
; if ((channels & 1) != 0) /* no alpha */
|
||||
; {
|
||||
@@ -2376,86 +2369,46 @@ align 4
|
||||
; palette[i].blue = palette[i].red = palette[i].green =
|
||||
; png_unpremultiply(entry[afirst], alpha, reciprocal);
|
||||
; }
|
||||
jmp .end1
|
||||
.end0: ;else Color-map has sRGB values
|
||||
mov esi,[cmap] ;esi=entry
|
||||
mov eax,[channels]
|
||||
mov ecx,eax
|
||||
imul eax,[i]
|
||||
add esi,eax ;+=i*channels;
|
||||
; }
|
||||
|
||||
;switch (channels)
|
||||
cmp ecx,4
|
||||
jne .end2
|
||||
mov eax,[afirst]
|
||||
or eax,eax
|
||||
jz @f
|
||||
xor eax,eax
|
||||
jmp .end3
|
||||
@@:
|
||||
mov eax,3
|
||||
.end3:
|
||||
mov al,byte[esi+eax]
|
||||
mov byte[edx],al ;tRNS[i] = entry[afirst ? 0 : 3]
|
||||
cmp al,255 ;if (..<..)
|
||||
je @f
|
||||
mov eax,[i]
|
||||
inc eax
|
||||
mov [num_trans],eax
|
||||
@@:
|
||||
dec ecx ; FALL THROUGH
|
||||
.end2:
|
||||
cmp ecx,3
|
||||
jne @f
|
||||
add esi,[afirst]
|
||||
mov eax,[bgr]
|
||||
xor eax,2
|
||||
lea eax,[esi+eax]
|
||||
mov al,byte[eax]
|
||||
stosb ;palette[i].blue
|
||||
; else /* Color-map has sRGB values */
|
||||
; {
|
||||
; bytep entry = cmap;
|
||||
|
||||
lea eax,[esi+1]
|
||||
mov al,byte[eax]
|
||||
stosb ;palette[i].green
|
||||
; entry += i * channels;
|
||||
|
||||
mov eax,[bgr]
|
||||
lea eax,[esi+eax]
|
||||
mov al,byte[eax]
|
||||
stosb ;palette[i].red
|
||||
jmp .end1
|
||||
@@:
|
||||
cmp ecx,2
|
||||
jne @f
|
||||
xor eax,eax
|
||||
inc eax
|
||||
xor eax,[afirst]
|
||||
mov al,byte[esi+eax]
|
||||
mov byte[edx],al ;tRNS[i] = entry[1 ^ afirst]
|
||||
cmp al,255 ;if (..<..)
|
||||
je @f
|
||||
mov eax,[i]
|
||||
inc eax
|
||||
mov [num_trans],eax
|
||||
@@:
|
||||
dec ecx; FALL THROUGH
|
||||
@@:
|
||||
cmp ecx,1
|
||||
jne .end1
|
||||
mov eax,[afirst]
|
||||
mov al,byte[esi+eax]
|
||||
stosb
|
||||
stosb
|
||||
stosb
|
||||
.end1:
|
||||
inc edx
|
||||
mov eax,[entries]
|
||||
inc [i]
|
||||
cmp [i],eax
|
||||
jl .cycle0
|
||||
.cycle0end:
|
||||
; switch (channels)
|
||||
; {
|
||||
; case 4:
|
||||
; tRNS[i] = entry[afirst ? 0 : 3];
|
||||
; if (tRNS[i] < 255)
|
||||
; num_trans = i+1;
|
||||
; /* FALL THROUGH */
|
||||
; case 3:
|
||||
; palette[i].blue = entry[afirst + (2 ^ bgr)];
|
||||
; palette[i].green = entry[afirst + 1];
|
||||
; palette[i].red = entry[afirst + bgr];
|
||||
; break;
|
||||
|
||||
; case 2:
|
||||
; tRNS[i] = entry[1 ^ afirst];
|
||||
; if (tRNS[i] < 255)
|
||||
; num_trans = i+1;
|
||||
; /* FALL THROUGH */
|
||||
; case 1:
|
||||
; palette[i].blue = palette[i].red = palette[i].green =
|
||||
; entry[afirst];
|
||||
; break;
|
||||
|
||||
; default:
|
||||
; break;
|
||||
; }
|
||||
; }
|
||||
; }
|
||||
|
||||
mov ecx,[ebx+png_image.opaque]
|
||||
lea eax,[ebp-256-256*sizeof.png_color]
|
||||
mov eax,ebp
|
||||
sub eax,256+256*sizeof.png_color
|
||||
stdcall png_set_PLTE, [ecx+png_control.png_ptr], [ecx+png_control.info_ptr], eax, [entries]
|
||||
|
||||
cmp dword[num_trans],0
|
||||
@@ -2867,26 +2820,9 @@ png_debug1 2, 'IDAT compress all len = %d', [len]
|
||||
mov edi,[buf_f]
|
||||
mov esi,[buf]
|
||||
|
||||
cmp eax,PNG_COLOR_TYPE_PALETTE
|
||||
je .cycle7
|
||||
cmp eax,PNG_COLOR_TYPE_RGB
|
||||
je .cycle0
|
||||
cmp eax,PNG_COLOR_TYPE_RGB_ALPHA
|
||||
je .cycle5
|
||||
|
||||
.cycle7: ;8 bit image palette
|
||||
cmp edx,1
|
||||
jl .cycle0end
|
||||
mov ecx,ebx
|
||||
xor al,al
|
||||
stosb ;insert filter (0 - none)
|
||||
align 4
|
||||
rep movsb
|
||||
dec edx
|
||||
jmp .cycle7
|
||||
.cycle7end:
|
||||
jmp .cycle5end
|
||||
|
||||
.cycle0: ;24 bit image
|
||||
cmp edx,1
|
||||
jl .cycle0end
|
||||
|
||||
@@ -1063,8 +1063,8 @@ align 4
|
||||
proc png_write_PLTE, png_ptr:dword, palette:dword, num_pal:dword
|
||||
locals
|
||||
;max_palette_length dd ? ;uint_32
|
||||
;i dd ?
|
||||
;pal_ptr dd ? ;png_const_colorp
|
||||
i dd ?
|
||||
pal_ptr dd ? ;png_const_colorp
|
||||
buf rb 3 ;byte[3]
|
||||
endl
|
||||
png_debug 1, 'in png_write_PLTE'
|
||||
@@ -1085,16 +1085,16 @@ pushad
|
||||
;mov [max_palette_length],eax
|
||||
.end0:
|
||||
|
||||
if PNG_MNG_FEATURES_SUPPORTED eq 1
|
||||
cmp [num_pal],eax
|
||||
jg @f
|
||||
if PNG_MNG_FEATURES_SUPPORTED eq 1
|
||||
mov eax,[edi+png_struct.mng_features_permitted]
|
||||
and eax,PNG_FLAG_MNG_EMPTY_PLTE
|
||||
jnz .end1
|
||||
end if
|
||||
cmp [num_pal],0
|
||||
jne .end1
|
||||
@@:
|
||||
end if
|
||||
|
||||
cmp byte[edi+png_struct.color_type],PNG_COLOR_TYPE_PALETTE ;if (..==..)
|
||||
jne @f
|
||||
@@ -1118,24 +1118,31 @@ end if
|
||||
|
||||
imul eax,3
|
||||
stdcall png_write_chunk_header, edi, png_PLTE, eax
|
||||
if PNG_POINTER_INDEXING_SUPPORTED eq 1
|
||||
|
||||
mov ecx,[num_pal]
|
||||
or ecx,ecx
|
||||
jz .cycle0end
|
||||
mov esi,[palette]
|
||||
lea ebx,[ebp-3] ;ebx = &buf
|
||||
align 4
|
||||
.cycle0: ;for (;;)
|
||||
lodsb
|
||||
mov [ebx],al
|
||||
lodsb
|
||||
mov [ebx+1],al
|
||||
lodsb
|
||||
mov [ebx+2],al
|
||||
stdcall png_write_chunk_data, edi, ebx, 3
|
||||
loop .cycle0
|
||||
.cycle0end:
|
||||
; for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++)
|
||||
; {
|
||||
; buf[0] = pal_ptr->red;
|
||||
; buf[1] = pal_ptr->green;
|
||||
; buf[2] = pal_ptr->blue;
|
||||
; png_write_chunk_data(png_ptr, buf, (png_size_t)3);
|
||||
; }
|
||||
|
||||
else
|
||||
; This is a little slower but some buggy compilers need to do this
|
||||
; instead
|
||||
|
||||
; pal_ptr=palette;
|
||||
|
||||
; for (i = 0; i < num_pal; i++)
|
||||
; {
|
||||
; buf[0] = pal_ptr[i].red;
|
||||
; buf[1] = pal_ptr[i].green;
|
||||
; buf[2] = pal_ptr[i].blue;
|
||||
; png_write_chunk_data(png_ptr, buf, (png_size_t)3);
|
||||
; }
|
||||
|
||||
end if
|
||||
stdcall png_write_chunk_end, edi
|
||||
or dword[edi+png_struct.mode], PNG_HAVE_PLTE
|
||||
.end_f:
|
||||
|
||||
@@ -1163,7 +1163,7 @@ local .l1
|
||||
|
||||
;;================================================================================================;;
|
||||
align 4
|
||||
proc img.encode.png uses ebx edx edi, _img:dword, _common:dword, _specific:dword
|
||||
proc img.encode.png uses ebx edx, _img:dword, _common:dword, _specific:dword
|
||||
;;------------------------------------------------------------------------------------------------;;
|
||||
;? Encode image into raw data in png format ;;
|
||||
;;------------------------------------------------------------------------------------------------;;
|
||||
@@ -1175,15 +1175,12 @@ proc img.encode.png uses ebx edx edi, _img:dword, _common:dword, _specific:dword
|
||||
;< ecx = error code / the size of encoded data ;;
|
||||
;;================================================================================================;;
|
||||
locals
|
||||
colormap dd 0
|
||||
encoded_file rd 1
|
||||
encoded_file_size rd 1
|
||||
simag png_image
|
||||
endl
|
||||
mov ebx,[_img]
|
||||
mov eax,[ebx+Image.Type]
|
||||
cmp eax,Image.bpp8i
|
||||
je @f
|
||||
cmp eax,Image.bpp24
|
||||
je @f
|
||||
cmp eax,Image.bpp32
|
||||
@@ -1195,27 +1192,16 @@ endl
|
||||
mov dword[edx+png_image.version],PNG_IMAGE_VERSION
|
||||
mov ecx,[ebx+Image.Width]
|
||||
mov [edx+png_image.width],ecx ;Image width in pixels (columns)
|
||||
cmp eax,Image.bpp8i
|
||||
jne @f
|
||||
mov dword[edx+png_image.format],PNG_FORMAT_RGBA_COLORMAP
|
||||
mov eax,ecx
|
||||
imul eax,[ebx+Image.Height]
|
||||
add eax,[ebx+Image.Data]
|
||||
add [colormap],eax
|
||||
stdcall get_pallete_colors,eax
|
||||
mov dword[edx+png_image.colormap_entries],eax
|
||||
jmp .init
|
||||
@@:
|
||||
cmp eax,Image.bpp24
|
||||
jne @f
|
||||
mov dword[edx+png_image.format],PNG_FORMAT_RGB
|
||||
imul ecx,3
|
||||
@@:
|
||||
cmp eax,Image.bpp32
|
||||
jne .init
|
||||
jne @f
|
||||
mov dword[edx+png_image.format],PNG_FORMAT_RGBA
|
||||
shl ecx,2
|
||||
.init:
|
||||
@@:
|
||||
mov eax,[ebx+Image.Height]
|
||||
mov [edx+png_image.height],eax ;Image height in pixels (rows)
|
||||
;mov dword[edx+png_image.flags],PNG_IMAGE_FLAG_???
|
||||
@@ -1235,7 +1221,7 @@ endl
|
||||
@@:
|
||||
mov [encoded_file],eax
|
||||
lea edi,[edx-4]
|
||||
stdcall png_image_write_to_memory, edx,eax,edi,0,[ebx+Image.Data],ecx,[colormap]
|
||||
stdcall png_image_write_to_memory, edx,eax,edi,0,[ebx+Image.Data],ecx,0
|
||||
mov eax,[encoded_file]
|
||||
mov ecx,[encoded_file_size]
|
||||
jmp .quit
|
||||
@@ -1245,31 +1231,3 @@ endl
|
||||
.quit:
|
||||
ret
|
||||
endp
|
||||
|
||||
|
||||
|
||||
;;================================================================================================;;
|
||||
align 4
|
||||
proc get_pallete_colors uses ecx edi, palette:dword
|
||||
;;------------------------------------------------------------------------------------------------;;
|
||||
;? Determine the palette size. Locate two adjacent zero-value colors; ;;
|
||||
;? this marks the end of the palette. ;;
|
||||
;;------------------------------------------------------------------------------------------------;;
|
||||
mov ecx,256-1
|
||||
mov edi,[palette]
|
||||
xor eax,eax
|
||||
@@:
|
||||
repne scasd
|
||||
or ecx,ecx
|
||||
jz .max_pal
|
||||
cmp [edi],eax ;second color check
|
||||
jne @b ;find again
|
||||
sub edi,[palette]
|
||||
shr edi,2
|
||||
mov eax,edi
|
||||
jmp @f
|
||||
.max_pal:
|
||||
mov eax,256
|
||||
@@:
|
||||
ret
|
||||
endp
|
||||
@@ -3,7 +3,6 @@ public EXPORTS
|
||||
section '.flat' code readable align 16
|
||||
|
||||
include '../../../macros.inc'
|
||||
include '../../../KOSfuncs.inc'
|
||||
include 'strlen.inc'
|
||||
|
||||
MB_FIRST_BUT_ID equ 3 ;идентификатор 1-й кнопки на сообщении
|
||||
@@ -19,8 +18,14 @@ MB_TEXT_OFFSET equ 2 ;ᬥ饭
|
||||
|
||||
align 4
|
||||
start:
|
||||
mcall SF_STYLE_SETTINGS,SSF_GET_COLORS,sc,sizeof.system_colors
|
||||
mcall SF_SET_EVENTS_MASK, EVM_MOUSE + EVM_BUTTON + EVM_KEY + EVM_REDRAW
|
||||
mov eax,48
|
||||
mov ebx,3
|
||||
mov ecx,sc
|
||||
mov edx,sizeof.system_colors
|
||||
mcall
|
||||
mov eax,40
|
||||
mov ebx,0x27
|
||||
mcall
|
||||
|
||||
;-- clear id pressed button ---
|
||||
mov ebx,[mb_text]
|
||||
@@ -34,7 +39,9 @@ start:
|
||||
|
||||
align 4
|
||||
red_win:
|
||||
mcall SF_REDRAW,SSF_BEGIN_DRAW
|
||||
mov eax,12
|
||||
mov ebx,1
|
||||
mcall
|
||||
|
||||
xor eax,eax
|
||||
mov bx,word[mb_left]
|
||||
@@ -49,7 +56,7 @@ red_win:
|
||||
add edi,MB_TEXT_OFFSET ;Caption
|
||||
mcall
|
||||
|
||||
mcall SF_THREAD_INFO,mb_procinfo,-1
|
||||
mcall 9,mb_procinfo,-1
|
||||
mov eax,dword[mb_procinfo.client_box.width]
|
||||
|
||||
sub eax,[but_width]
|
||||
@@ -57,6 +64,7 @@ red_win:
|
||||
add eax,MB_BUT_OTX_1
|
||||
mov [ot_left],eax
|
||||
|
||||
mov eax,4 ;рисование текста
|
||||
mov bx,MB_BUT_OTX_1
|
||||
shl ebx,16
|
||||
mov bx,MB_BUT_OTY_1
|
||||
@@ -68,12 +76,13 @@ red_win:
|
||||
call strlen
|
||||
call linlen
|
||||
|
||||
or eax,eax
|
||||
jz @f
|
||||
cmp eax,0
|
||||
je @f
|
||||
|
||||
mov esi,eax
|
||||
push eax
|
||||
mcall SF_DRAW_TEXT
|
||||
mov eax,4
|
||||
int 0x40
|
||||
pop eax
|
||||
|
||||
add edx,eax
|
||||
@@ -86,24 +95,25 @@ red_win:
|
||||
@@:
|
||||
|
||||
call MsgBoxDrawAllBut
|
||||
mcall SF_REDRAW,SSF_END_DRAW
|
||||
mcall 12,2
|
||||
|
||||
align 4
|
||||
still:
|
||||
mcall SF_WAIT_EVENT
|
||||
mov eax,10
|
||||
mcall
|
||||
|
||||
cmp al,EV_REDRAW
|
||||
cmp al,1 ;изм. положение окна
|
||||
jz red_win
|
||||
cmp al,EV_KEY
|
||||
cmp al,2
|
||||
jz key
|
||||
cmp al,EV_BUTTON
|
||||
cmp al,3
|
||||
jz button
|
||||
|
||||
jmp still
|
||||
|
||||
align 4
|
||||
key:
|
||||
mcall SF_GET_KEY
|
||||
mcall 2
|
||||
cmp ah,13
|
||||
jne @f
|
||||
mov ah,[mb_key_foc]
|
||||
@@ -143,7 +153,7 @@ key:
|
||||
|
||||
align 4
|
||||
button:
|
||||
mcall SF_GET_BUTTON
|
||||
mcall 17 ;получить код нажатой кнопки
|
||||
cmp ah,MB_FIRST_BUT_ID
|
||||
jge close
|
||||
cmp ah,1
|
||||
@@ -159,8 +169,8 @@ close:
|
||||
mov byte[ebx],ah
|
||||
|
||||
;*** call msgbox functions ***
|
||||
or ah,ah
|
||||
jz @f
|
||||
cmp ah,0
|
||||
je @f
|
||||
cmp dword[mb_funct],0
|
||||
je @f
|
||||
xor ebx,ebx
|
||||
@@ -172,7 +182,7 @@ close:
|
||||
je @f
|
||||
call dword[ebx]
|
||||
@@:
|
||||
mcall SF_TERMINATE_PROCESS
|
||||
mcall -1 ;выход из программы
|
||||
|
||||
align 4
|
||||
MsgBoxDrawAllBut:
|
||||
@@ -192,8 +202,8 @@ MsgBoxDrawAllBut:
|
||||
mov esi,edx
|
||||
call strlen
|
||||
|
||||
or eax,eax
|
||||
jz @f
|
||||
cmp eax,0
|
||||
je @f
|
||||
|
||||
call MsgBoxDrawButton
|
||||
inc ecx
|
||||
@@ -243,7 +253,8 @@ MsgBoxDrawButton:
|
||||
ror ebx,16
|
||||
mov bx,ax
|
||||
|
||||
mcall SF_DEFINE_BUTTON
|
||||
mov eax,8
|
||||
int 0x40
|
||||
pop edx ebx eax
|
||||
|
||||
;caption
|
||||
@@ -253,7 +264,8 @@ MsgBoxDrawButton:
|
||||
mov ecx,[sc.work_button]
|
||||
@@:
|
||||
mov esi,eax
|
||||
mcall SF_DRAW_TEXT
|
||||
mov eax,4
|
||||
int 0x40
|
||||
|
||||
pop ecx
|
||||
ret
|
||||
@@ -272,25 +284,6 @@ MsgBoxReInit:
|
||||
add esi,eax ;add len of caption
|
||||
mov [txtMsg],esi
|
||||
|
||||
;--- calc window width ---
|
||||
push eax ebx esi
|
||||
.cycle:
|
||||
call strlen
|
||||
mov ebx,eax
|
||||
call linlen
|
||||
add esi,eax
|
||||
sub ebx,eax
|
||||
imul eax,6
|
||||
add eax,10+2*SF_DRAW_TEXT
|
||||
cmp [mb_width],ax
|
||||
jge @f
|
||||
mov [mb_width],ax
|
||||
@@:
|
||||
inc esi
|
||||
cmp ebx,5 ;length of the remaining text
|
||||
jg .cycle
|
||||
pop esi ebx eax
|
||||
|
||||
;--- go to first button text --- buttons 1...MB_MAX_BUT
|
||||
mov ebx,txtBut
|
||||
mov cx,MB_MAX_BUT
|
||||
@@ -327,11 +320,12 @@ MsgBoxReInit:
|
||||
add eax,MB_BUT_HEIGHT
|
||||
add ax,5 ;height of border
|
||||
mov [mb_height],ax
|
||||
mcall SF_STYLE_SETTINGS,SSF_GET_SKIN_HEIGHT
|
||||
mcall 48,4 ;skin height
|
||||
add [mb_height],ax
|
||||
|
||||
;--- calc window top ---
|
||||
mcall SF_GET_SCREEN_SIZE
|
||||
mov eax,14
|
||||
int 0x40
|
||||
mov word[mb_top],ax
|
||||
mov ax,word[mb_height]
|
||||
sub word[mb_top],ax
|
||||
@@ -373,7 +367,6 @@ MsgBoxReInit:
|
||||
|
||||
;input:
|
||||
; [esp+8] = pointer to msgbox text
|
||||
; [esp+12] = thread stack
|
||||
align 4
|
||||
MsgBoxCreate:
|
||||
push ebp
|
||||
@@ -381,7 +374,11 @@ MsgBoxCreate:
|
||||
m2m dword[mb_text],dword[ebp+8]
|
||||
push eax ebx ecx edx
|
||||
|
||||
mcall SF_THREAD_CONTROL,SSF_CREATE_THREAD,start,[ebp+12]
|
||||
mov eax,51
|
||||
mov ebx,1
|
||||
mov ecx,start
|
||||
mov edx,dword[ebp+12];thread
|
||||
int 0x40
|
||||
|
||||
mov dword[mb_funct],0
|
||||
pop edx ecx ebx eax
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
format MS COFF
|
||||
public EXPORTS
|
||||
include '../../../KOSfuncs.inc'
|
||||
section '.flat' code readable align 16
|
||||
; void __stdcall START(dword state);
|
||||
DLL_ENTRY equ 1
|
||||
@@ -61,7 +60,6 @@ START:
|
||||
; SORT_BY_ACCESSED = 12, SORT_BY_ACCESSED_REV = 13 };
|
||||
; int __stdcall sort_dir(BDFE* folder_data, unsigned num_folder_entries, sort_mode mode);
|
||||
; return: 0 = ok, 1 = error
|
||||
align 4
|
||||
sort_dir:
|
||||
cmp dword [esp+12], num_compare_fns
|
||||
jae .error
|
||||
@@ -75,9 +73,9 @@ sort_dir:
|
||||
jz .done
|
||||
cmp eax, ecx
|
||||
jae .memok
|
||||
push SF_SYS_MISC
|
||||
push 68
|
||||
pop eax
|
||||
push SSF_MEM_ALLOC
|
||||
push 12
|
||||
pop ebx
|
||||
int 0x40
|
||||
test eax, eax
|
||||
@@ -105,8 +103,6 @@ sort_dir:
|
||||
pop ecx
|
||||
mov ebx, edx
|
||||
sub esp, 304
|
||||
cld
|
||||
align 4
|
||||
.moveloop:
|
||||
mov esi, [ebx]
|
||||
test esi, esi
|
||||
@@ -143,9 +139,9 @@ align 4
|
||||
.done_free:
|
||||
cmp edx, ptr_table
|
||||
jz .done
|
||||
push SF_SYS_MISC
|
||||
push 68
|
||||
pop eax
|
||||
push SSF_MEM_FREE
|
||||
push 13
|
||||
pop ebx
|
||||
mov ecx, edx
|
||||
int 0x40
|
||||
@@ -273,7 +269,6 @@ compare_name_rev:
|
||||
stc
|
||||
ret
|
||||
|
||||
align 4
|
||||
strcmpi:
|
||||
push eax
|
||||
@@:
|
||||
|
||||
@@ -913,7 +913,7 @@ static off_t get_fileinfo(struct reader *rds,char *buf)
|
||||
#define syncsafe_to_long(buf,res) \
|
||||
( \
|
||||
(((buf)[0]|(buf)[1]|(buf)[2]|(buf)[3]) & 0x80) ? 0 : \
|
||||
(res = (((unsigned long) (buf)[0]) << 21) \
|
||||
(res = (((unsigned long) (buf)[0]) << 27) \
|
||||
| (((unsigned long) (buf)[1]) << 14) \
|
||||
| (((unsigned long) (buf)[2]) << 7) \
|
||||
| ((unsigned long) (buf)[3]) \
|
||||
|
||||
@@ -474,7 +474,7 @@ system_dir_ProcLib db '/sys/lib/proc_lib.obj',0
|
||||
;---------------------------------------------------------------------
|
||||
l_libs_start:
|
||||
library01 l_libs system_dir_Boxlib+9, library_path, system_dir_Boxlib, \
|
||||
import_box_lib, plugins_directory
|
||||
Box_lib_import, plugins_directory
|
||||
|
||||
library02 l_libs system_dir_Libini+9, library_path, system_dir_Libini, \
|
||||
Libini_import, plugins_directory
|
||||
@@ -728,7 +728,83 @@ aIni_set_int db 'ini_set_int',0
|
||||
aIni_set_color db 'ini_set_color',0
|
||||
|
||||
;---------------------------------------------------------------------
|
||||
include '../../develop/libraries/box_lib/import.inc'
|
||||
align 4
|
||||
Box_lib_import:
|
||||
;init_lib dd a_init
|
||||
;version_lib dd a_version
|
||||
|
||||
edit_box_draw dd aEdit_box_draw
|
||||
edit_box_key dd aEdit_box_key
|
||||
edit_box_mouse dd aEdit_box_mouse
|
||||
;version_ed dd aVersion_ed
|
||||
|
||||
init_checkbox dd aInit_checkbox
|
||||
check_box_draw dd aCheck_box_draw
|
||||
check_box_mouse dd aCheck_box_mouse
|
||||
;version_ch dd aVersion_ch
|
||||
|
||||
option_box_draw dd aOption_box_draw
|
||||
option_box_mouse dd aOption_box_mouse
|
||||
;version_op dd aVersion_op
|
||||
|
||||
scrollbar_ver_draw dd aScrollbar_ver_draw
|
||||
scrollbar_ver_mouse dd aScrollbar_ver_mouse
|
||||
scrollbar_hor_draw dd aScrollbar_hor_draw
|
||||
scrollbar_hor_mouse dd aScrollbar_hor_mouse
|
||||
;version_scrollbar dd aVersion_scrollbar
|
||||
|
||||
dinamic_button_draw dd aDbutton_draw
|
||||
dinamic_button_mouse dd aDbutton_mouse
|
||||
;version_dbutton dd aVersion_dbutton
|
||||
|
||||
menu_bar_draw dd aMenu_bar_draw
|
||||
menu_bar_mouse dd aMenu_bar_mouse
|
||||
menu_bar_activate dd aMenu_bar_activate
|
||||
;version_menu_bar dd aVersion_menu_bar
|
||||
|
||||
;FileBrowser_draw dd aFileBrowser_draw
|
||||
;FileBrowser_mouse dd aFileBrowser_mouse
|
||||
;FileBrowser_key dd aFileBrowser_key
|
||||
;Version_FileBrowser dd aVersion_FileBrowser
|
||||
dd 0
|
||||
dd 0
|
||||
|
||||
;a_init db 'lib_init',0
|
||||
;a_version db 'version',0
|
||||
|
||||
aEdit_box_draw db 'edit_box_draw',0
|
||||
aEdit_box_key db 'edit_box_key',0
|
||||
aEdit_box_mouse db 'edit_box_mouse',0
|
||||
;aVersion_ed db 'version_ed',0
|
||||
|
||||
aInit_checkbox db 'init_checkbox2',0
|
||||
aCheck_box_draw db 'check_box_draw2',0
|
||||
aCheck_box_mouse db 'check_box_mouse2',0
|
||||
;aVersion_ch db 'version_ch2',0
|
||||
|
||||
aOption_box_draw db 'option_box_draw',0
|
||||
aOption_box_mouse db 'option_box_mouse',0
|
||||
;aVersion_op db 'version_op',0
|
||||
|
||||
aScrollbar_ver_draw db 'scrollbar_v_draw',0
|
||||
aScrollbar_ver_mouse db 'scrollbar_v_mouse',0
|
||||
aScrollbar_hor_draw db 'scrollbar_h_draw',0
|
||||
aScrollbar_hor_mouse db 'scrollbar_h_mouse',0
|
||||
;aVersion_scrollbar db 'version_scrollbar',0
|
||||
|
||||
aDbutton_draw db 'dbutton_draw',0
|
||||
aDbutton_mouse db 'dbutton_mouse',0
|
||||
;aVersion_dbutton db 'version_dbutton',0
|
||||
|
||||
aMenu_bar_draw db 'menu_bar_draw',0
|
||||
aMenu_bar_mouse db 'menu_bar_mouse',0
|
||||
aMenu_bar_activate db 'menu_bar_activate',0
|
||||
;aVersion_menu_bar db 'version_menu_bar',0
|
||||
|
||||
;aFileBrowser_draw db 'FileBrowser_draw',0
|
||||
;aFileBrowser_mouse db 'FileBrowser_mouse',0
|
||||
;aFileBrowser_key db 'FileBrowser_key',0
|
||||
;aVersion_FileBrowser db 'version_FileBrowser',0
|
||||
;---------------------------------------------------------------------
|
||||
align 4
|
||||
load_directory_pointer dd 0
|
||||
|
||||
@@ -421,7 +421,8 @@ draw_scrollbars:
|
||||
jbe @f
|
||||
cmp [scroll_bar_data_vertical.cur_area],0
|
||||
je @f
|
||||
stdcall [scrollbar_v_draw], scroll_bar_data_vertical
|
||||
push dword scroll_bar_data_vertical
|
||||
call [scrollbar_ver_draw]
|
||||
; draw_scroll_bar_vertical scroll_bar_data_vertical
|
||||
inc [draw_scrollbar_counter]
|
||||
@@:
|
||||
@@ -433,7 +434,8 @@ draw_scrollbars:
|
||||
jbe @f
|
||||
cmp [scroll_bar_data_horizontal.cur_area],0
|
||||
je @f
|
||||
stdcall [scrollbar_h_draw], scroll_bar_data_horizontal
|
||||
push dword scroll_bar_data_horizontal
|
||||
call [scrollbar_hor_draw]
|
||||
; draw_scroll_bar_horizontal scroll_bar_data_horizontal
|
||||
inc [draw_scrollbar_counter]
|
||||
@@:
|
||||
|
||||
@@ -18,28 +18,49 @@ draw_window:
|
||||
|
||||
call draw_other
|
||||
|
||||
stdcall [menu_bar_draw], menu_data_1
|
||||
stdcall [menu_bar_draw], menu_data_2
|
||||
stdcall [menu_bar_draw], menu_data_3
|
||||
stdcall [menu_bar_draw], menu_data_4
|
||||
stdcall [menu_bar_draw], menu_data_5
|
||||
stdcall [menu_bar_draw], menu_data_6
|
||||
push dword menu_data_1
|
||||
call [menu_bar_draw]
|
||||
push dword menu_data_2
|
||||
call [menu_bar_draw]
|
||||
push dword menu_data_3
|
||||
call [menu_bar_draw]
|
||||
push dword menu_data_4
|
||||
call [menu_bar_draw]
|
||||
push dword menu_data_5
|
||||
call [menu_bar_draw]
|
||||
push dword menu_data_6
|
||||
call [menu_bar_draw]
|
||||
|
||||
stdcall [dbutton_draw], dinamic_button_data_1
|
||||
stdcall [dbutton_draw], dinamic_button_data_2
|
||||
stdcall [dbutton_draw], dinamic_button_data_3
|
||||
stdcall [dbutton_draw], dinamic_button_data_4
|
||||
stdcall [dbutton_draw], dinamic_button_data_5
|
||||
stdcall [dbutton_draw], dinamic_button_data_6
|
||||
stdcall [dbutton_draw], dinamic_button_data_7
|
||||
stdcall [dbutton_draw], dinamic_button_data_8
|
||||
stdcall [dbutton_draw], dinamic_button_data_9
|
||||
stdcall [dbutton_draw], dinamic_button_data_10
|
||||
stdcall [dbutton_draw], dinamic_button_data_11
|
||||
stdcall [dbutton_draw], dinamic_button_data_12
|
||||
stdcall [dbutton_draw], dinamic_button_data_13
|
||||
stdcall [dbutton_draw], dinamic_button_data_14
|
||||
stdcall [dbutton_draw], dinamic_button_data_15
|
||||
push dword dinamic_button_data_1
|
||||
call [dinamic_button_draw]
|
||||
push dword dinamic_button_data_2
|
||||
call [dinamic_button_draw]
|
||||
push dword dinamic_button_data_3
|
||||
call [dinamic_button_draw]
|
||||
push dword dinamic_button_data_4
|
||||
call [dinamic_button_draw]
|
||||
push dword dinamic_button_data_5
|
||||
call [dinamic_button_draw]
|
||||
push dword dinamic_button_data_6
|
||||
call [dinamic_button_draw]
|
||||
push dword dinamic_button_data_7
|
||||
call [dinamic_button_draw]
|
||||
push dword dinamic_button_data_8
|
||||
call [dinamic_button_draw]
|
||||
push dword dinamic_button_data_9
|
||||
call [dinamic_button_draw]
|
||||
push dword dinamic_button_data_10
|
||||
call [dinamic_button_draw]
|
||||
push dword dinamic_button_data_11
|
||||
call [dinamic_button_draw]
|
||||
push dword dinamic_button_data_12
|
||||
call [dinamic_button_draw]
|
||||
push dword dinamic_button_data_13
|
||||
call [dinamic_button_draw]
|
||||
push dword dinamic_button_data_14
|
||||
call [dinamic_button_draw]
|
||||
push dword dinamic_button_data_15
|
||||
call [dinamic_button_draw]
|
||||
|
||||
mcall 13,<225,2>,<3,22>,0x677EA0 ;0x052B64
|
||||
mcall ,<280,2>
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
;---------------------------------------------------------------------
|
||||
mouse:
|
||||
mcall SF_SYSTEM,SSF_GET_ACTIVE_WINDOW
|
||||
mcall 18,7
|
||||
cmp [active_process],eax
|
||||
jne still
|
||||
|
||||
mcall SF_MOUSE_GET,SSF_SCROLL_DATA
|
||||
mcall 37,7
|
||||
mov [mouse_scroll_data],eax
|
||||
|
||||
mov eax,[mouse_position]
|
||||
mov [mouse_position_old],eax
|
||||
mcall SF_MOUSE_GET,SSF_WINDOW_POSITION
|
||||
mcall 37,1
|
||||
mov [mouse_position],eax
|
||||
|
||||
mov eax,[mouse_keys]
|
||||
mov [mouse_keys_old],eax
|
||||
mcall SF_MOUSE_GET,SSF_BUTTON
|
||||
mcall 37,2
|
||||
mov [mouse_keys],eax
|
||||
|
||||
cmp [soi],dword 0
|
||||
@@ -32,7 +32,8 @@ mouse:
|
||||
cmp eax,[scroll_bar_data_horizontal.cur_area]
|
||||
jbe .vertical
|
||||
|
||||
stdcall [scrollbar_h_mouse], scroll_bar_data_horizontal
|
||||
push dword scroll_bar_data_horizontal
|
||||
call [scrollbar_hor_mouse]
|
||||
|
||||
; mouse_scroll_bar_horizontal scroll_bar_data_horizontal
|
||||
cmp [scroll_bar_data_horizontal.redraw],0
|
||||
@@ -49,7 +50,8 @@ mouse:
|
||||
cmp eax,[scroll_bar_data_vertical.cur_area]
|
||||
jbe .menu_bar
|
||||
|
||||
stdcall [scrollbar_v_mouse], scroll_bar_data_vertical
|
||||
push dword scroll_bar_data_vertical
|
||||
call [scrollbar_ver_mouse]
|
||||
|
||||
; mouse_scroll_bar_vertical scroll_bar_data_vertical
|
||||
cmp [scroll_bar_data_vertical.redraw],0
|
||||
@@ -81,7 +83,8 @@ mouse:
|
||||
.menu_bar_1:
|
||||
call .set_mouse_flag
|
||||
@@:
|
||||
stdcall [menu_bar_mouse], menu_data_1
|
||||
push dword menu_data_1
|
||||
call [menu_bar_mouse]
|
||||
; mouse_menubar menu_data_1
|
||||
cmp [menu_data_1.click],dword 1
|
||||
jne .menu_bar_2
|
||||
@@ -92,7 +95,8 @@ mouse:
|
||||
;--------------------------------------------
|
||||
.menu_bar_2:
|
||||
; Edit
|
||||
stdcall [menu_bar_mouse], menu_data_2
|
||||
push dword menu_data_2
|
||||
call [menu_bar_mouse]
|
||||
; mouse_menubar menu_data_2
|
||||
cmp [menu_data_2.click],dword 1
|
||||
jne .menu_bar_3
|
||||
@@ -103,7 +107,8 @@ mouse:
|
||||
;--------------------------------------------
|
||||
.menu_bar_3:
|
||||
; View
|
||||
stdcall [menu_bar_mouse], menu_data_3
|
||||
push dword menu_data_3
|
||||
call [menu_bar_mouse]
|
||||
; mouse_menubar menu_data_3
|
||||
cmp [menu_data_3.click],dword 1
|
||||
jne .menu_bar_4
|
||||
@@ -114,7 +119,8 @@ mouse:
|
||||
;--------------------------------------------
|
||||
.menu_bar_4:
|
||||
; Zoom
|
||||
stdcall [menu_bar_mouse], menu_data_4
|
||||
push dword menu_data_4
|
||||
call [menu_bar_mouse]
|
||||
; mouse_menubar menu_data_4
|
||||
cmp [menu_data_4.click],dword 1
|
||||
jne .menu_bar_5
|
||||
@@ -125,7 +131,8 @@ mouse:
|
||||
;--------------------------------------------
|
||||
.menu_bar_5:
|
||||
; Tools
|
||||
stdcall [menu_bar_mouse], menu_data_5
|
||||
push dword menu_data_5
|
||||
call [menu_bar_mouse]
|
||||
; mouse_menubar menu_data_5
|
||||
cmp [menu_data_5.click],dword 1
|
||||
jne .menu_bar_6
|
||||
@@ -136,7 +143,8 @@ mouse:
|
||||
;--------------------------------------------
|
||||
.menu_bar_6:
|
||||
; Help
|
||||
stdcall [menu_bar_mouse], menu_data_6
|
||||
push dword menu_data_6
|
||||
call [menu_bar_mouse]
|
||||
; mouse_menubar menu_data_6
|
||||
cmp [menu_data_6.click],dword 1
|
||||
jne .mouse_dinamic_button
|
||||
@@ -147,7 +155,8 @@ mouse:
|
||||
;---------------------------------------------------
|
||||
.mouse_dinamic_button:
|
||||
; open file
|
||||
stdcall [dbutton_mouse], dinamic_button_data_1
|
||||
push dword dinamic_button_data_1
|
||||
call [dinamic_button_mouse]
|
||||
; mouse_dinamic_button dinamic_button_data_1
|
||||
mov eax,dinamic_button_data_1.click
|
||||
cmp [eax],dword 1
|
||||
@@ -157,7 +166,8 @@ mouse:
|
||||
;-------------------------------------------------
|
||||
@@:
|
||||
; reload file
|
||||
stdcall [dbutton_mouse], dinamic_button_data_2
|
||||
push dword dinamic_button_data_2
|
||||
call [dinamic_button_mouse]
|
||||
; mouse_dinamic_button dinamic_button_data_2
|
||||
mov eax,dinamic_button_data_2.click
|
||||
cmp [eax],dword 1
|
||||
@@ -167,7 +177,8 @@ mouse:
|
||||
;-------------------------------------------------
|
||||
@@:
|
||||
; left limit
|
||||
stdcall [dbutton_mouse], dinamic_button_data_3
|
||||
push dword dinamic_button_data_3
|
||||
call [dinamic_button_mouse]
|
||||
; mouse_dinamic_button dinamic_button_data_3
|
||||
mov eax,dinamic_button_data_3.click
|
||||
cmp [eax],dword 1
|
||||
@@ -177,7 +188,8 @@ mouse:
|
||||
;-------------------------------------------------
|
||||
@@:
|
||||
; left arrow
|
||||
stdcall [dbutton_mouse], dinamic_button_data_4
|
||||
push dword dinamic_button_data_4
|
||||
call [dinamic_button_mouse]
|
||||
; mouse_dinamic_button dinamic_button_data_4
|
||||
mov eax,dinamic_button_data_4.click
|
||||
cmp [eax],dword 1
|
||||
@@ -187,7 +199,8 @@ mouse:
|
||||
;-------------------------------------------------
|
||||
@@:
|
||||
; slide show
|
||||
stdcall [dbutton_mouse], dinamic_button_data_5
|
||||
push dword dinamic_button_data_5
|
||||
call [dinamic_button_mouse]
|
||||
; mouse_dinamic_button dinamic_button_data_5
|
||||
mov eax,dinamic_button_data_5.click
|
||||
cmp [eax],dword 1
|
||||
@@ -197,7 +210,8 @@ mouse:
|
||||
;-------------------------------------------------
|
||||
@@:
|
||||
; right arrow
|
||||
stdcall [dbutton_mouse], dinamic_button_data_6
|
||||
push dword dinamic_button_data_6
|
||||
call [dinamic_button_mouse]
|
||||
; mouse_dinamic_button dinamic_button_data_6
|
||||
mov eax,dinamic_button_data_6.click
|
||||
cmp [eax],dword 1
|
||||
@@ -207,7 +221,8 @@ mouse:
|
||||
;-------------------------------------------------
|
||||
@@:
|
||||
; right limit
|
||||
stdcall [dbutton_mouse], dinamic_button_data_7
|
||||
push dword dinamic_button_data_7
|
||||
call [dinamic_button_mouse]
|
||||
; mouse_dinamic_button dinamic_button_data_7
|
||||
mov eax,dinamic_button_data_7.click
|
||||
cmp [eax],dword 1
|
||||
@@ -217,7 +232,8 @@ mouse:
|
||||
;-------------------------------------------------
|
||||
@@:
|
||||
; zoom +
|
||||
stdcall [dbutton_mouse], dinamic_button_data_8
|
||||
push dword dinamic_button_data_8
|
||||
call [dinamic_button_mouse]
|
||||
; mouse_dinamic_button dinamic_button_data_8
|
||||
mov eax,dinamic_button_data_8.click
|
||||
cmp [eax],dword 1
|
||||
@@ -227,7 +243,8 @@ mouse:
|
||||
;-------------------------------------------------
|
||||
@@:
|
||||
; zoom -
|
||||
stdcall [dbutton_mouse], dinamic_button_data_9
|
||||
push dword dinamic_button_data_9
|
||||
call [dinamic_button_mouse]
|
||||
; mouse_dinamic_button dinamic_button_data_9
|
||||
mov eax,dinamic_button_data_9.click
|
||||
cmp [eax],dword 1
|
||||
@@ -237,7 +254,8 @@ mouse:
|
||||
;-------------------------------------------------
|
||||
@@:
|
||||
; zoom 100%
|
||||
stdcall [dbutton_mouse], dinamic_button_data_10
|
||||
push dword dinamic_button_data_10
|
||||
call [dinamic_button_mouse]
|
||||
; mouse_dinamic_button dinamic_button_data_10
|
||||
mov eax,dinamic_button_data_10.click
|
||||
cmp [eax],dword 1
|
||||
@@ -247,7 +265,8 @@ mouse:
|
||||
;-------------------------------------------------
|
||||
@@:
|
||||
; rotate clockwise
|
||||
stdcall [dbutton_mouse], dinamic_button_data_11
|
||||
push dword dinamic_button_data_11
|
||||
call [dinamic_button_mouse]
|
||||
; mouse_dinamic_button dinamic_button_data_11
|
||||
mov eax,dinamic_button_data_11.click
|
||||
cmp [eax],dword 1
|
||||
@@ -257,7 +276,8 @@ mouse:
|
||||
;-------------------------------------------------
|
||||
@@:
|
||||
; rotate counter-clockwise
|
||||
stdcall [dbutton_mouse], dinamic_button_data_12
|
||||
push dword dinamic_button_data_12
|
||||
call [dinamic_button_mouse]
|
||||
; mouse_dinamic_button dinamic_button_data_12
|
||||
mov eax,dinamic_button_data_12.click
|
||||
cmp [eax],dword 1
|
||||
@@ -267,7 +287,8 @@ mouse:
|
||||
;-------------------------------------------------
|
||||
@@:
|
||||
; file information
|
||||
stdcall [dbutton_mouse], dinamic_button_data_13
|
||||
push dword dinamic_button_data_13
|
||||
call [dinamic_button_mouse]
|
||||
; mouse_dinamic_button dinamic_button_data_13
|
||||
mov eax,dinamic_button_data_13.click
|
||||
cmp [eax],dword 1
|
||||
@@ -277,7 +298,8 @@ mouse:
|
||||
;-------------------------------------------------
|
||||
@@:
|
||||
; wallpaper
|
||||
stdcall [dbutton_mouse], dinamic_button_data_14
|
||||
push dword dinamic_button_data_14
|
||||
call [dinamic_button_mouse]
|
||||
; mouse_dinamic_button dinamic_button_data_14
|
||||
mov eax,dinamic_button_data_14.click
|
||||
cmp [eax],dword 1
|
||||
@@ -287,7 +309,8 @@ mouse:
|
||||
;-------------------------------------------------
|
||||
@@:
|
||||
; settings
|
||||
stdcall [dbutton_mouse], dinamic_button_data_15
|
||||
push dword dinamic_button_data_15
|
||||
call [dinamic_button_mouse]
|
||||
; mouse_dinamic_button dinamic_button_data_15
|
||||
mov eax,dinamic_button_data_15.click
|
||||
cmp [eax],dword 1
|
||||
|
||||
@@ -136,48 +136,12 @@ socketerror:
|
||||
sendFTP "425 Can't open data connection"
|
||||
ret
|
||||
|
||||
align 4
|
||||
; Close the data socket if this thread currently owns one. datasocketnum only
|
||||
; holds a live socket in these two modes; in any other mode it is a handle that
|
||||
; has already been closed or was never opened.
|
||||
close_data_sock:
|
||||
cmp [ebp + thread_data.mode], MODE_PASSIVE_OK
|
||||
je @f
|
||||
cmp [ebp + thread_data.mode], MODE_ACTIVE
|
||||
jne .done
|
||||
@@:
|
||||
mov [ebp + thread_data.mode], MODE_NOTREADY
|
||||
mcall close, [ebp + thread_data.datasocketnum]
|
||||
mov [ebp + thread_data.datasocketnum], -1
|
||||
.done:
|
||||
ret
|
||||
|
||||
align 4
|
||||
; Close the passive listening socket if one is still open. It is open only
|
||||
; while waiting for the client (MODE_PASSIVE_WAIT, MODE_PASSIVE_FAILED) or after
|
||||
; a failed listen, so no data connection exists and the mode drops to NOTREADY.
|
||||
close_pasv_sock:
|
||||
cmp [ebp + thread_data.passivesocknum], -1
|
||||
je .done
|
||||
mcall close, [ebp + thread_data.passivesocknum]
|
||||
mov [ebp + thread_data.passivesocknum], -1
|
||||
mov [ebp + thread_data.mode], MODE_NOTREADY
|
||||
.done:
|
||||
ret
|
||||
|
||||
align 4
|
||||
; A data transfer failed with the file in ebx open: close the file and the data
|
||||
; socket, then report the error.
|
||||
transfer_error:
|
||||
invoke file.close, ebx
|
||||
call close_data_sock
|
||||
jmp socketerror
|
||||
|
||||
align 4
|
||||
abort_transfer:
|
||||
and [ebp + thread_data.permissions], not ABORT
|
||||
mov [ebp + thread_data.mode], MODE_NOTREADY
|
||||
invoke file.close, ebx
|
||||
call close_data_sock
|
||||
mcall close, [ebp + thread_data.datasocketnum]
|
||||
|
||||
sendFTP "530 Transfer aborted"
|
||||
ret
|
||||
@@ -363,7 +327,7 @@ open_datasock:
|
||||
.pasv_ok:
|
||||
mov [ebp + thread_data.datasocketnum], eax
|
||||
mov [ebp + thread_data.mode], MODE_PASSIVE_OK
|
||||
mcall close, [ebp + thread_data.passivesocknum]
|
||||
mcall close ; [ebp + thread_data.passivesocknum]
|
||||
mov [ebp + thread_data.passivesocknum], -1
|
||||
invoke con_write_asciiz, str_datasock
|
||||
|
||||
@@ -727,13 +691,13 @@ cmdLIST:
|
||||
mcall send
|
||||
|
||||
; close the data socket..
|
||||
call close_data_sock
|
||||
mov [ebp + thread_data.mode], MODE_NOTREADY
|
||||
mcall close, [ebp + thread_data.datasocketnum]
|
||||
|
||||
sendFTP "226 List OK"
|
||||
ret
|
||||
|
||||
.nosuchdir:
|
||||
call close_data_sock
|
||||
sendFTP "550 Directory does not exist"
|
||||
ret
|
||||
|
||||
@@ -829,9 +793,10 @@ cmdPASS:
|
||||
align 4
|
||||
cmdPASV:
|
||||
|
||||
; Drop whatever data connection the previous PASV/PORT left behind
|
||||
call close_data_sock
|
||||
call close_pasv_sock
|
||||
; cmp [ebp + thread_data.passivesocknum], -1
|
||||
; je @f
|
||||
; mcall close, [ebp + thread_data.passivesocknum] ; if there is still a socket open, close it
|
||||
; @@:
|
||||
|
||||
; Open a new TCP socket
|
||||
mcall socket, AF_INET4, SOCK_STREAM, 0
|
||||
@@ -967,10 +932,6 @@ cmdPWD:
|
||||
align 4
|
||||
cmdPORT:
|
||||
|
||||
; Drop whatever data connection the previous PASV/PORT left behind
|
||||
call close_data_sock
|
||||
call close_pasv_sock
|
||||
|
||||
; PORT a1,a2,a3,a4,p1,p2
|
||||
; IP address a1.a2.a3.a4, port p1*256+p2
|
||||
|
||||
@@ -1011,8 +972,7 @@ align 4
|
||||
cmdQUIT:
|
||||
|
||||
sendFTP "221 Bye!"
|
||||
call close_data_sock
|
||||
call close_pasv_sock
|
||||
mcall close, [ebp + thread_data.datasocketnum]
|
||||
mcall close, [ebp + thread_data.socketnum]
|
||||
|
||||
add esp, 4 ; get rid of call return address
|
||||
@@ -1075,7 +1035,7 @@ cmdRETR:
|
||||
lea eax, [ebp + thread_data.buffer] ; FIXME: use another buffer!! if we receive something on control connection now, we screw up!
|
||||
invoke file.read, ebx, eax, BUFFERSIZE
|
||||
cmp eax, -1
|
||||
je .read_error ; FIXME: this is not the correct error
|
||||
je .cannot_open ; FIXME: this is not the correct error
|
||||
|
||||
push eax
|
||||
invoke con_write_asciiz, str2
|
||||
@@ -1089,7 +1049,7 @@ cmdRETR:
|
||||
mcall send
|
||||
pop ebx ecx
|
||||
cmp eax, -1
|
||||
je transfer_error ; FIXME: not the correct error
|
||||
je socketerror ; FIXME: not the correct error
|
||||
|
||||
; cmp eax, ecx
|
||||
; jne not_all_byes_sent ; TODO
|
||||
@@ -1101,15 +1061,13 @@ cmdRETR:
|
||||
|
||||
invoke con_write_asciiz, str2b
|
||||
|
||||
call close_data_sock
|
||||
mov [ebp + thread_data.mode], MODE_NOTREADY
|
||||
mcall close, [ebp + thread_data.datasocketnum]
|
||||
|
||||
sendFTP "226 Transfer OK, closing connection"
|
||||
ret
|
||||
|
||||
.read_error:
|
||||
invoke file.close, ebx
|
||||
.cannot_open:
|
||||
call close_data_sock
|
||||
invoke con_set_flags, 0x0c
|
||||
invoke con_write_asciiz, str_notfound
|
||||
invoke con_set_flags, 0x07
|
||||
@@ -1168,14 +1126,7 @@ cmdSTOR:
|
||||
test eax, eax
|
||||
jz .cannot_open
|
||||
|
||||
; STOR replaces the file: drop the previous, possibly longer contents
|
||||
push eax
|
||||
invoke file.truncate, eax
|
||||
pop ebx
|
||||
test eax, eax
|
||||
js .truncate_error
|
||||
|
||||
push ebx
|
||||
sendFTP "150 Here it comes.."
|
||||
pop ebx
|
||||
|
||||
@@ -1191,7 +1142,7 @@ cmdSTOR:
|
||||
mcall recv
|
||||
pop ebx ecx
|
||||
cmp eax, -1
|
||||
je transfer_error ; FIXME: not the correct error
|
||||
je socketerror ; FIXME: not the correct error
|
||||
|
||||
test eax, eax
|
||||
jz @f
|
||||
@@ -1203,7 +1154,7 @@ cmdSTOR:
|
||||
pop edx
|
||||
|
||||
cmp eax, -1
|
||||
je .write_error ; FIXME: this is not the correct error
|
||||
je .cannot_open ; FIXME: this is not the correct error
|
||||
|
||||
invoke con_write_asciiz, str2
|
||||
|
||||
@@ -1219,7 +1170,8 @@ cmdSTOR:
|
||||
|
||||
invoke con_write_asciiz, str2b
|
||||
|
||||
call close_data_sock
|
||||
mov [ebp + thread_data.mode], MODE_NOTREADY
|
||||
mcall close, [ebp + thread_data.datasocketnum]
|
||||
|
||||
|
||||
|
||||
@@ -1233,20 +1185,10 @@ cmdSTOR:
|
||||
sendFTP "226 Transfer OK"
|
||||
ret
|
||||
|
||||
.write_error:
|
||||
invoke file.close, ebx
|
||||
.cannot_open:
|
||||
call close_data_sock
|
||||
sendFTP "550 No create file"
|
||||
ret
|
||||
|
||||
.truncate_error:
|
||||
invoke file.close, ebx
|
||||
mov [ebp + thread_data.mode], MODE_NOTREADY
|
||||
mcall close, [ebp + thread_data.datasocketnum]
|
||||
sendFTP "550 Cannot truncate file"
|
||||
ret
|
||||
|
||||
;------------------------------------------------
|
||||
; "SYST"
|
||||
;
|
||||
|
||||
@@ -237,7 +237,6 @@ end if
|
||||
lea eax, [ebp + thread_data.buffer]
|
||||
mov [ebp + thread_data.buffer_ptr], eax
|
||||
mov [ebp + thread_data.passivesocknum], -1
|
||||
mov [ebp + thread_data.datasocketnum], -1
|
||||
|
||||
sendFTP "220 Welcome to KolibriOS FTP daemon" ; fix output code
|
||||
|
||||
@@ -265,7 +264,7 @@ threadloop:
|
||||
je .not_passive
|
||||
mov [ebp + thread_data.datasocketnum], eax
|
||||
mov [ebp + thread_data.mode], MODE_PASSIVE_OK
|
||||
mcall close, [ebp + thread_data.passivesocknum]
|
||||
mcall close ; [ebp + thread_data.passivesocknum]
|
||||
mov [ebp + thread_data.passivesocknum], -1
|
||||
|
||||
invoke con_write_asciiz, str_datasock
|
||||
@@ -448,7 +447,6 @@ import libio,\
|
||||
file.open, 'file_open',\
|
||||
file.read, 'file_read',\
|
||||
file.write, 'file_write',\
|
||||
file.truncate, 'file_truncate',\
|
||||
file.close, 'file_close',\
|
||||
file.find.first, 'file_find_first',\
|
||||
file.find.next, 'file_find_next',\
|
||||
|
||||
@@ -202,8 +202,6 @@ mainloop:
|
||||
mov bh, byte[ebp + interface.number]
|
||||
mov bl, 7
|
||||
mcall 76 ; Number of IP conflicts
|
||||
cmp eax, -1
|
||||
je @f
|
||||
cmp eax, [ebp + interface.ip_conflicts]
|
||||
je @f
|
||||
mov [ebp + interface.ip_conflicts], eax
|
||||
@@ -217,8 +215,8 @@ mainloop:
|
||||
mov bh, byte[ebp + interface.number]
|
||||
mov bl, 0 ; Get device type
|
||||
mcall 74
|
||||
cmp eax, 1
|
||||
jne .link_down
|
||||
test eax, eax ; No device
|
||||
jz .link_down
|
||||
|
||||
; Check if link is still there
|
||||
mov bl, 10 ; Get Link status
|
||||
|
||||
+1
-1
Submodule programs/other/kterm updated: 3490117a33...6fa93f71f1.
@@ -189,8 +189,6 @@ key:
|
||||
mcall 2
|
||||
cmp ah, ' '
|
||||
je button.noclose
|
||||
cmp ah, 9 ; Tab
|
||||
je button.noclose
|
||||
cmp ah, 51 ; F2
|
||||
je open_boardlog
|
||||
jmp still
|
||||
|
||||
@@ -451,19 +451,19 @@ mouse:
|
||||
;--------------------------------------
|
||||
align 4
|
||||
.red:
|
||||
stdcall [scrollbar_v_mouse], scroll_bar_data_red
|
||||
stdcall [scrollbar_ver_mouse], scroll_bar_data_red
|
||||
cmp [scroll_bar_data_red.delta2],0
|
||||
jne @f
|
||||
;--------------------------------------
|
||||
align 4
|
||||
.green:
|
||||
stdcall [scrollbar_v_mouse], scroll_bar_data_green
|
||||
stdcall [scrollbar_ver_mouse], scroll_bar_data_green
|
||||
cmp [scroll_bar_data_green.delta2],0
|
||||
jne @f
|
||||
;--------------------------------------
|
||||
align 4
|
||||
.blue:
|
||||
stdcall [scrollbar_v_mouse], scroll_bar_data_blue
|
||||
stdcall [scrollbar_ver_mouse], scroll_bar_data_blue
|
||||
cmp [scroll_bar_data_blue.delta2],0
|
||||
jne @f
|
||||
;--------------------------------------
|
||||
@@ -499,9 +499,9 @@ draw_tone:
|
||||
;---------------------------------------------------------------------
|
||||
align 4
|
||||
draw_scrollbars:
|
||||
stdcall [scrollbar_v_draw], scroll_bar_data_red
|
||||
stdcall [scrollbar_v_draw], scroll_bar_data_green
|
||||
stdcall [scrollbar_v_draw], scroll_bar_data_blue
|
||||
stdcall [scrollbar_ver_draw], scroll_bar_data_red
|
||||
stdcall [scrollbar_ver_draw], scroll_bar_data_green
|
||||
stdcall [scrollbar_ver_draw], scroll_bar_data_blue
|
||||
ret
|
||||
;---------------------------------------------------------------------
|
||||
align 4
|
||||
@@ -512,7 +512,7 @@ draw_history_frame:
|
||||
mov [frame_data.draw_text_flag],dword 1
|
||||
|
||||
mov [frame_data.text_pointer],dword history_text
|
||||
stdcall [frame_draw], frame_data
|
||||
stdcall [Frame_draw], frame_data
|
||||
ret
|
||||
;---------------------------------------------------------------------
|
||||
align 4
|
||||
@@ -590,7 +590,7 @@ newcol:
|
||||
mov [frame_data.x],ebx
|
||||
mov [frame_data.y],ecx
|
||||
|
||||
stdcall [frame_draw], frame_data
|
||||
stdcall [Frame_draw], frame_data
|
||||
|
||||
pop ecx ebx
|
||||
|
||||
|
||||
@@ -23,11 +23,102 @@ system_dir_Boxlib db '/sys/lib/box_lib.obj',0
|
||||
align 4
|
||||
l_libs_start:
|
||||
library01 l_libs system_dir_Boxlib+9,file_name,system_dir_Boxlib,\
|
||||
import_box_lib,plugins_directory
|
||||
Box_lib_import,plugins_directory
|
||||
|
||||
end_l_libs:
|
||||
;---------------------------------------------------------------------
|
||||
include '../../develop/libraries/box_lib/import.inc'
|
||||
;---------------------------------------------------------------------
|
||||
align 4
|
||||
Box_lib_import:
|
||||
;init_lib dd a_init
|
||||
;version_lib dd a_version
|
||||
|
||||
edit_box_draw dd aEdit_box_draw
|
||||
edit_box_key dd aEdit_box_key
|
||||
edit_box_mouse dd aEdit_box_mouse
|
||||
edit_box_set_text dd aEdit_box_set_text
|
||||
;version_ed dd aVersion_ed
|
||||
|
||||
;check_box_draw dd aCheck_box_draw
|
||||
;check_box_mouse dd aCheck_box_mouse
|
||||
;version_ch dd aVersion_ch
|
||||
|
||||
;option_box_draw dd aOption_box_draw
|
||||
;option_box_mouse dd aOption_box_mouse
|
||||
;version_op dd aVersion_op
|
||||
|
||||
scrollbar_ver_draw dd aScrollbar_ver_draw
|
||||
scrollbar_ver_mouse dd aScrollbar_ver_mouse
|
||||
;scrollbar_hor_draw dd aScrollbar_hor_draw
|
||||
;scrollbar_hor_mouse dd aScrollbar_hor_mouse
|
||||
;version_scrollbar dd aVersion_scrollbar
|
||||
|
||||
;dinamic_button_draw dd aDbutton_draw
|
||||
;dinamic_button_mouse dd aDbutton_mouse
|
||||
;version_dbutton dd aVersion_dbutton
|
||||
|
||||
;menu_bar_draw dd aMenu_bar_draw
|
||||
;menu_bar_mouse dd aMenu_bar_mouse
|
||||
;menu_bar_activate dd aMenu_bar_activate
|
||||
;version_menu_bar dd aVersion_menu_bar
|
||||
|
||||
;FileBrowser_draw dd aFileBrowser_draw
|
||||
;FileBrowser_mouse dd aFileBrowser_mouse
|
||||
;FileBrowser_key dd aFileBrowser_key
|
||||
;Version_FileBrowser dd aVersion_FileBrowser
|
||||
|
||||
;PathShow_prepare dd sz_PathShow_prepare
|
||||
;PathShow_draw dd sz_PathShow_draw
|
||||
;Version_path_show dd szVersion_path_show
|
||||
|
||||
Frame_draw dd sz_Frame_draw
|
||||
;Version_frame dd szVersion_frame
|
||||
|
||||
dd 0,0
|
||||
|
||||
;a_init db 'lib_init',0
|
||||
;a_version db 'version',0
|
||||
|
||||
aEdit_box_draw db 'edit_box_draw',0
|
||||
aEdit_box_key db 'edit_box_key',0
|
||||
aEdit_box_mouse db 'edit_box_mouse',0
|
||||
aEdit_box_set_text db 'edit_box_set_text',0
|
||||
;aVersion_ed db 'version_ed',0
|
||||
|
||||
;aCheck_box_draw db 'check_box_draw',0
|
||||
;aCheck_box_mouse db 'check_box_mouse',0
|
||||
;aVersion_ch db 'version_ch',0
|
||||
|
||||
;aOption_box_draw db 'option_box_draw',0
|
||||
;aOption_box_mouse db 'option_box_mouse',0
|
||||
;aVersion_op db 'version_op',0
|
||||
|
||||
aScrollbar_ver_draw db 'scrollbar_v_draw',0
|
||||
aScrollbar_ver_mouse db 'scrollbar_v_mouse',0
|
||||
;aScrollbar_hor_draw db 'scrollbar_h_draw',0
|
||||
;aScrollbar_hor_mouse db 'scrollbar_h_mouse',0
|
||||
;aVersion_scrollbar db 'version_scrollbar',0
|
||||
|
||||
;aDbutton_draw db 'dbutton_draw',0
|
||||
;aDbutton_mouse db 'dbutton_mouse',0
|
||||
;aVersion_dbutton db 'version_dbutton',0
|
||||
|
||||
;aMenu_bar_draw db 'menu_bar_draw',0
|
||||
;aMenu_bar_mouse db 'menu_bar_mouse',0
|
||||
;aMenu_bar_activate db 'menu_bar_activate',0
|
||||
;aVersion_menu_bar db 'version_menu_bar',0
|
||||
|
||||
;aFileBrowser_draw db 'FileBrowser_draw',0
|
||||
;aFileBrowser_mouse db 'FileBrowser_mouse',0
|
||||
;aFileBrowser_key db 'FileBrowser_key',0
|
||||
;aVersion_FileBrowser db 'version_FileBrowser',0
|
||||
|
||||
;sz_PathShow_prepare db 'PathShow_prepare',0
|
||||
;sz_PathShow_draw db 'PathShow_draw',0
|
||||
;szVersion_path_show db 'version_PathShow',0
|
||||
|
||||
sz_Frame_draw db 'frame_draw',0
|
||||
;szVersion_frame db 'version_frame',0
|
||||
;---------------------------------------------------------------------
|
||||
align 4
|
||||
scroll_bar_data_red:
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
if tup.getconfig("NO_FASM") ~= "" then return end
|
||||
tup.rule("end.asm", "fasm %f %o " .. tup.getconfig("KPACK_CMD"), "end")
|
||||
HELPERDIR = (tup.getconfig("HELPERDIR") == "") and "../.." or tup.getconfig("HELPERDIR")
|
||||
tup.include(HELPERDIR .. "/use_fasm.lua")
|
||||
tup.rule("end.asm", FASM .. " -dlang=" .. tup.getconfig("LANG") .. " %f %o " .. tup.getconfig("KPACK_CMD"), "end")
|
||||
@@ -1 +0,0 @@
|
||||
Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,Гh,╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl╟мl═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s═▓s╚и`пНBГh,Гh,╟мl╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯMЩ{7Гh,Гh,╟мl╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯMЩ{7Гh,Гh,╟мl╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯMЩ{7Гh,Гh,╟мl╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯM─ЯMЩ{7Гh,Гh,╟мl╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С:╢С9╖С7╕С5╕С5╕С5╕С5╕С5╖С7╡С:╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<╡С<Line truncated
|
||||
@@ -1,3 +0,0 @@
|
||||
@fasm end.asm end
|
||||
@kpack end
|
||||
@pause
|
||||
+277
-114
@@ -1,139 +1,302 @@
|
||||
; SPDX-License-Identifier: NOASSERTION
|
||||
;
|
||||
|
||||
; END - the shutdown dialog of KolibriOS
|
||||
;
|
||||
; END
|
||||
; Offers kernel restart / reboot / power off and optionally saves the
|
||||
; RAM-disk before leaving: when the "save changes" checkbox is on, the
|
||||
; image is written back to the boot medium (SF 18.6 with ecx = 0).
|
||||
; A failed save cancels the shutdown so the user never loses changes
|
||||
; silently.
|
||||
;
|
||||
; <diamond> note that 'mov al,xx' is shorter than 'mov eax,xx'
|
||||
; and if we know that high 24 bits of eax are zero, we can use 1st form
|
||||
; the same about ebx,ecx,edx
|
||||
;
|
||||
; 15.02.2007 merge old END with new one (fron Veliant & Leency) by Heavyiron
|
||||
; Authors: Veliant, Leency, Heavyiron, Burer
|
||||
|
||||
include "..\..\macros.inc"
|
||||
use32
|
||||
org 0
|
||||
|
||||
meos_app_start
|
||||
code
|
||||
db 'MENUET01'
|
||||
dd 1
|
||||
dd START
|
||||
dd IM_END
|
||||
dd I_END
|
||||
dd stacktop
|
||||
dd 0
|
||||
dd 0
|
||||
|
||||
draw:
|
||||
include '../../macros.inc'
|
||||
include '../../proc32.inc'
|
||||
include '../../dll.inc'
|
||||
include '../../KOSfuncs.inc'
|
||||
include '../../encoding.inc'
|
||||
include '../../gui_patterns.inc'
|
||||
include '../../string.inc'
|
||||
|
||||
mov al,12 ; eax=12 - tell os about redraw start
|
||||
mov ebx,1
|
||||
mcall
|
||||
WIN_W = 440
|
||||
WIN_H = 200
|
||||
BOT_PANEL_H = 70
|
||||
BUT_W = 116
|
||||
BUT_Y = WIN_H-60
|
||||
|
||||
mov al,14 ; eax=14 - get screen max x & max y
|
||||
mcall
|
||||
BTN_CANCEL = 1
|
||||
BTN_KERNEL = 2
|
||||
BTN_REBOOT = 3
|
||||
BTN_POWEROFF = 4
|
||||
BTN_CHECKBOX = 5
|
||||
|
||||
movzx ecx, ax
|
||||
shr eax, 16
|
||||
shr ecx, 1
|
||||
shr eax, 1
|
||||
sub eax, 157
|
||||
sub ecx, 100
|
||||
mov ebx, eax
|
||||
shl ebx, 16
|
||||
add ebx, 253
|
||||
shl ecx, 16
|
||||
add ecx, 154
|
||||
; mcall 18,9 shutdown codes
|
||||
SHUTDOWN_POWEROFF = 2
|
||||
SHUTDOWN_REBOOT = 3
|
||||
SHUTDOWN_KERNEL = 4
|
||||
|
||||
xor eax,eax ; define and draw window
|
||||
mov edx,0x41ffffff
|
||||
mcall
|
||||
;---------------------------------------------------------------------
|
||||
|
||||
mov al, 7
|
||||
mov ebx, background
|
||||
mov ecx, 254 shl 16 + 155
|
||||
xor edx, edx
|
||||
mcall
|
||||
START:
|
||||
mcall SF_SYS_MISC, SSF_HEAP_INIT
|
||||
mcall SF_SYS_MISC, SSF_MEM_OPEN, checkbox_sharedname
|
||||
mov [checkbox_img], eax
|
||||
|
||||
stdcall dll.Load, importLib
|
||||
test eax, eax
|
||||
jnz .no_ini ; no libini - live without autosave
|
||||
inc [ini_ok]
|
||||
invoke ini_get_int, ini_file, ini_sec, key_autosave, 0
|
||||
mov [autosave], eax
|
||||
.no_ini:
|
||||
|
||||
mov al,8
|
||||
mcall ,58 shl 16 + 32,59 shl 16 + 34, 1 shl 30 + 1
|
||||
inc edx
|
||||
mcall ,110 shl 16 + 32,54 shl 16 + 32
|
||||
inc edx
|
||||
mcall ,161 shl 16 + 32,59 shl 16 + 34
|
||||
inc edx
|
||||
mcall ,193 shl 16 + 43,125 shl 16 + 16,
|
||||
inc edx
|
||||
mcall ,144 shl 16 + 43
|
||||
|
||||
mov al,12 ;end of redraw
|
||||
mov ebx,2
|
||||
mcall
|
||||
redraw:
|
||||
call draw_window
|
||||
|
||||
still:
|
||||
mcall SF_WAIT_EVENT
|
||||
dec eax
|
||||
jz redraw
|
||||
dec eax
|
||||
jz on_key
|
||||
|
||||
; button event
|
||||
mcall SF_GET_BUTTON
|
||||
shr eax, 8
|
||||
cmp eax, BTN_CANCEL
|
||||
je exit
|
||||
cmp eax, BTN_KERNEL
|
||||
je restart_kernel
|
||||
cmp eax, BTN_REBOOT
|
||||
je reboot
|
||||
cmp eax, BTN_POWEROFF
|
||||
je power_off
|
||||
cmp eax, BTN_CHECKBOX
|
||||
je toggle_checkbox
|
||||
jmp still
|
||||
|
||||
mov eax,10 ; wait here for event
|
||||
mcall
|
||||
on_key:
|
||||
mcall SF_GET_KEY
|
||||
cmp ah, 13 ; Enter
|
||||
je reboot
|
||||
cmp ah, 19 ; Ctrl+S
|
||||
je toggle_checkbox
|
||||
cmp ah, 180 ; Home
|
||||
je restart_kernel
|
||||
cmp ah, 181 ; End
|
||||
je power_off
|
||||
cmp ah, 27 ; Esc
|
||||
jne still
|
||||
|
||||
dec eax
|
||||
jz draw
|
||||
dec eax
|
||||
jnz button
|
||||
key:
|
||||
mov al,2 ; now eax=2 - get key code
|
||||
mcall
|
||||
mov al,ah
|
||||
cmp al,13
|
||||
jz restart
|
||||
cmp al,27
|
||||
jz close_1
|
||||
cmp al,180
|
||||
jz restart_kernel
|
||||
cmp al,181
|
||||
jz power_off
|
||||
jmp still
|
||||
exit:
|
||||
mcall SF_TERMINATE_PROCESS
|
||||
|
||||
button:
|
||||
mov al,17 ; now eax=17 - get pressed button id
|
||||
mcall
|
||||
xchg al,ah
|
||||
dec eax
|
||||
jz restart_kernel
|
||||
dec eax
|
||||
jz power_off
|
||||
dec eax
|
||||
jz restart
|
||||
dec eax
|
||||
jnz run_rdsave
|
||||
; we have only one button left, this is close button
|
||||
; dec eax
|
||||
; jnz still
|
||||
close_1:
|
||||
or eax,-1
|
||||
mcall
|
||||
;---------------------------------------------------------------------
|
||||
|
||||
power_off:
|
||||
push 2
|
||||
jmp mcall_and_close
|
||||
power_off:
|
||||
mov [shutdown_code], SHUTDOWN_POWEROFF
|
||||
jmp save_and_shutdown
|
||||
|
||||
restart:
|
||||
push 3
|
||||
jmp mcall_and_close
|
||||
reboot:
|
||||
mov [shutdown_code], SHUTDOWN_REBOOT
|
||||
jmp save_and_shutdown
|
||||
|
||||
restart_kernel:
|
||||
push 4
|
||||
mcall_and_close:
|
||||
pop ecx
|
||||
mcall 18,9
|
||||
jmp close_1
|
||||
restart_kernel:
|
||||
mov [shutdown_code], SHUTDOWN_KERNEL
|
||||
|
||||
run_rdsave:
|
||||
mov eax,70
|
||||
mov ebx,rdsave
|
||||
mcall
|
||||
jmp still
|
||||
save_and_shutdown:
|
||||
cmp [ini_ok], 0
|
||||
je @f
|
||||
invoke ini_set_int, ini_file, ini_sec, key_autosave, [autosave]
|
||||
|
||||
@@:
|
||||
cmp [autosave], 1
|
||||
jne .shutdown
|
||||
|
||||
data
|
||||
background file 'back.raw'
|
||||
rdsave:
|
||||
dd 7
|
||||
dd 0
|
||||
dd 0
|
||||
dd 0
|
||||
dd 0
|
||||
db '/sys/rdsave',0
|
||||
udata
|
||||
mcall SF_DRAW_TEXT, <55,108>, 0x90FF990A, TEXT_SAVING
|
||||
|
||||
meos_app_end
|
||||
mcall SF_SYSTEM, SSF_RD_TO_HDD, 0 ; save back to the boot medium
|
||||
test eax, eax
|
||||
jz .shutdown
|
||||
|
||||
.save_failed: ; the image is not saved - cancel the shutdown
|
||||
call draw_window
|
||||
mcall SF_DRAW_TEXT, <55,108>, 0x90FF5050, TEXT_SAVE_FAILED
|
||||
jmp still
|
||||
|
||||
.shutdown:
|
||||
mcall SF_SYSTEM, SSF_SHUTDOWN, [shutdown_code]
|
||||
mcall SF_TERMINATE_PROCESS
|
||||
|
||||
;---------------------------------------------------------------------
|
||||
|
||||
toggle_checkbox:
|
||||
xor [autosave], 1
|
||||
call draw_checkbox
|
||||
jmp still
|
||||
|
||||
;---------------------------------------------------------------------
|
||||
|
||||
draw_window:
|
||||
mcall SF_REDRAW, SSF_BEGIN_DRAW
|
||||
|
||||
mcall SF_GET_SCREEN_SIZE
|
||||
movzx ecx, ax
|
||||
shr eax, 17
|
||||
shl eax, 16
|
||||
lea ebx, [eax-(WIN_W/2) shl 16+WIN_W-1]
|
||||
shr ecx, 1
|
||||
shl ecx, 16
|
||||
lea ecx, [ecx-(WIN_H/2) shl 16+WIN_H-1]
|
||||
xor eax, eax
|
||||
mov edx, 0x41000000
|
||||
mcall ; borderless window centered on the screen
|
||||
|
||||
DrawWideRectangle 0, 0, WIN_W, WIN_H, 2, 0xA3A7AA
|
||||
mcall SF_DRAW_RECT, <2,WIN_W-4>, <2,WIN_H-BOT_PANEL_H-2>, 0x202020
|
||||
mcall SF_DRAW_RECT, <2,WIN_W-4>, <WIN_H-BOT_PANEL_H-2,BOT_PANEL_H>, 0x4B4B4B
|
||||
|
||||
mcall SF_DRAW_TEXT, <30,21>, 0x91FFFFFF, TEXT_WTITLE
|
||||
mcall SF_DRAW_TEXT, <55,70>, 0x90FFFFFF, TEXT_RDSAVE1
|
||||
mcall SF_DRAW_TEXT, <55,86>, 0x90FFFFFF, TEXT_RDSAVE2
|
||||
mcall SF_DRAW_TEXT, <WIN_W-23,5>, 0x81FFFFFF, TEXT_CANCEL
|
||||
|
||||
mcall SF_DEFINE_BUTTON, <WIN_W-35,32>, <2,22>, BTN_CANCEL+BT_HIDE
|
||||
mcall SF_DEFINE_BUTTON, <32,14>, <70,14>, BTN_CHECKBOX+BT_HIDE
|
||||
mcall SF_DEFINE_BUTTON, <47,WIN_W-47>, <68,34>, BTN_CHECKBOX+BT_HIDE+BT_NOFRAME
|
||||
DrawRectangle3D 32, 70, 14, 14, 0x606060, 0xAFAFAF
|
||||
call draw_checkbox
|
||||
|
||||
stdcall shutdown_button, 20, 0x4E91C5, BTN_KERNEL, TEXT_KERNEL, TEXT_HOME
|
||||
stdcall shutdown_button, 160, 0x41C166, BTN_REBOOT, TEXT_REBOOT, TEXT_ENTER
|
||||
stdcall shutdown_button, 300, 0xC75C54, BTN_POWEROFF, TEXT_OFF, TEXT_END
|
||||
|
||||
mcall SF_REDRAW, SSF_END_DRAW
|
||||
ret
|
||||
|
||||
; one big colored button with a centered caption and a hotkey hint
|
||||
proc shutdown_button x:dword, bgcol:dword, id:dword, caption:dword, hotkey:dword
|
||||
mov ebx, [x]
|
||||
sub ebx, 3
|
||||
mcall SF_DRAW_RECT, <ebx,BUT_W+7>, <BUT_Y-3,43+6>, 0x202020
|
||||
mcall SF_DEFINE_BUTTON, <[x],BUT_W>, <BUT_Y,43-1>, [id], [bgcol]
|
||||
stdcall string.length, [caption]
|
||||
neg eax
|
||||
lea ebx, [eax*4+BUT_W/2] ; center the 8 px wide characters
|
||||
add ebx, [x]
|
||||
mcall SF_DRAW_TEXT, <ebx,BUT_Y+8>, 0x90FFFFFF, [caption]
|
||||
add ebx, 1 shl 16 ; draw twice for a bold effect
|
||||
mcall
|
||||
stdcall string.length, [hotkey]
|
||||
neg eax
|
||||
lea ebx, [eax*3+BUT_W/2] ; center the 6 px wide characters
|
||||
add ebx, [x]
|
||||
shl ebx, 16
|
||||
add ebx, BUT_Y+26
|
||||
mcall SF_DRAW_TEXT, , 0x80FFFFFF, [hotkey]
|
||||
ret
|
||||
endp
|
||||
|
||||
draw_checkbox:
|
||||
cmp [autosave], 0
|
||||
je .unset
|
||||
|
||||
cmp [checkbox_img], 0
|
||||
je .no_image
|
||||
|
||||
mcall SF_PUT_IMAGE, [checkbox_img], <13,13>, <33,71>
|
||||
ret
|
||||
|
||||
.no_image:
|
||||
mcall SF_DRAW_RECT, <33,13>, <71,13>, 0xFFFFFF
|
||||
mcall SF_DRAW_RECT, <34,11>, <72,11>, 0x58C33C
|
||||
ret
|
||||
|
||||
.unset:
|
||||
mcall SF_DRAW_RECT, <33,13>, <71,13>, 0xFFFFFF
|
||||
ret
|
||||
|
||||
;---------------------------------------------------------------------
|
||||
;--- Data ----------------------------------------------------------
|
||||
;---------------------------------------------------------------------
|
||||
|
||||
if lang eq ru_RU
|
||||
TEXT_WTITLE cp866 'Завершение работы',0
|
||||
TEXT_RDSAVE1 cp866 'Сохранить изменения, сделанные в',0
|
||||
TEXT_RDSAVE2 cp866 'процессе работы в системе (Ctrl+S)',0
|
||||
TEXT_KERNEL cp866 'Ядро',0
|
||||
TEXT_REBOOT cp866 'Перезагрузка',0
|
||||
TEXT_OFF cp866 'Выключение',0
|
||||
TEXT_SAVING cp866 'Сохранение образа...',0
|
||||
TEXT_SAVE_FAILED cp866 'Не удалось сохранить образ!',0
|
||||
else if lang eq es_ES
|
||||
TEXT_WTITLE cp850 'Apagar el equipo',0
|
||||
TEXT_RDSAVE1 cp850 'Guardar los cambios hechos durante',0
|
||||
TEXT_RDSAVE2 cp850 'la sesión de trabajo (Ctrl+S)',0
|
||||
TEXT_KERNEL cp850 'Núcleo',0
|
||||
TEXT_REBOOT cp850 'Reiniciar',0
|
||||
TEXT_OFF cp850 'Apagar',0
|
||||
TEXT_SAVING cp850 'Guardando la imagen...',0
|
||||
TEXT_SAVE_FAILED cp850 'No se pudo guardar la imagen!',0
|
||||
else ; Default to en_US
|
||||
TEXT_WTITLE db 'Shutdown computer',0
|
||||
TEXT_RDSAVE1 db 'Save all changes that were done',0
|
||||
TEXT_RDSAVE2 db 'during system work (Ctrl+S)',0
|
||||
TEXT_KERNEL db 'Kernel',0
|
||||
TEXT_REBOOT db 'Reboot',0
|
||||
TEXT_OFF db 'Power off',0
|
||||
TEXT_SAVING db 'Saving RAM-drive...',0
|
||||
TEXT_SAVE_FAILED db 'Failed to save the RAM-drive!',0
|
||||
end if
|
||||
|
||||
TEXT_HOME db 'Home',0
|
||||
TEXT_ENTER db 'Enter',0
|
||||
TEXT_END db 'End',0
|
||||
TEXT_CANCEL db 'x',0
|
||||
|
||||
;---------------------------------------------------------------------
|
||||
|
||||
ini_file db '/sys/settings/app.ini',0
|
||||
ini_sec db 'RDSave',0
|
||||
key_autosave db 'autosave',0
|
||||
|
||||
checkbox_sharedname db 'CHECKBOX',0
|
||||
|
||||
;---------------------------------------------------------------------
|
||||
|
||||
align 4
|
||||
importLib:
|
||||
library libini, 'libini.obj'
|
||||
|
||||
import libini, \
|
||||
ini_get_int, 'ini_get_int', \
|
||||
ini_set_int, 'ini_set_int'
|
||||
|
||||
;---------------------------------------------------------------------
|
||||
|
||||
IM_END:
|
||||
|
||||
align 4
|
||||
checkbox_img rd 1
|
||||
autosave rd 1
|
||||
ini_ok rd 1
|
||||
shutdown_code rd 1
|
||||
|
||||
;---------------------------------------------------------------------
|
||||
|
||||
align 32
|
||||
rb 4096
|
||||
stacktop:
|
||||
I_END:
|
||||
@@ -1,7 +0,0 @@
|
||||
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())
|
||||
|
||||
tup.rule("echo lang fix " .. ((tup.getconfig("LANG") == "") and "en_US" or tup.getconfig("LANG")) .. " > %o", {"lang.inc"})
|
||||
tup.rule({"end.asm", extra_inputs = {"lang.inc"}}, FASM .. " %f %o " .. tup.getconfig("KPACK_CMD"), "end")
|
||||
@@ -1,6 +0,0 @@
|
||||
@erase lang.inc
|
||||
@echo lang fix de_DE >lang.inc
|
||||
@fasm end.asm end
|
||||
@kpack end
|
||||
@erase lang.inc
|
||||
@pause
|
||||
@@ -1,6 +0,0 @@
|
||||
@erase lang.inc
|
||||
@echo lang fix it_IT >lang.inc
|
||||
@fasm end.asm end
|
||||
@kpack end
|
||||
@erase lang.inc
|
||||
@pause
|
||||
@@ -1,71 +0,0 @@
|
||||
WIN_W = 440
|
||||
WIN_H = 200
|
||||
BOT_PANEL_H = 70
|
||||
;---------------------------------------------------------------------
|
||||
CANCEL_BUTTON_ID = 1+BT_HIDE
|
||||
HOME_BUTTON_ID = 2
|
||||
REBOOT_BUTTON_ID = 3
|
||||
POWEROFF_BUTTON_ID = 4
|
||||
CHECKBOX_BUTTON_ID = 5+BT_HIDE
|
||||
;---------------------------------------------------------------------
|
||||
TEXT_HOME: db 'Home',0
|
||||
TEXT_ENTER: db 'Enter',0
|
||||
TEXT_END: db 'End',0
|
||||
TEXT_CANCEL: db 'x',0
|
||||
;---------------------------------------------------------------------
|
||||
|
||||
; Language support for locales: ru_RU (CP866), de_DE, it_IT, en_US
|
||||
|
||||
if lang eq ru_RU
|
||||
TEXT_WTITLE: db 'Завершение работы',0
|
||||
TEXT_RDSAVE1: db 'Сохранить изменения, сделанные в',0
|
||||
TEXT_RDSAVE2: db 'процессе работы в системе (Ctrl+S)',0
|
||||
TEXT_KERNEL: db 'Ядро',0
|
||||
TEXT_REBOOT: db 'Перезагрузка',0
|
||||
TEXT_OFF: db 'Выключение',0
|
||||
TEXT_SAVING: db 'Сохранение образа...',0
|
||||
else if lang eq de_DE
|
||||
TEXT_WTITLE: db 'Shutdown computer',0
|
||||
TEXT_RDSAVE1: db 'Save all changes that were done',0
|
||||
TEXT_RDSAVE2: db 'during system work (Ctrl+S)',0
|
||||
TEXT_KERNEL: db 'Kernel',0
|
||||
TEXT_REBOOT: db 'Neustart',0
|
||||
TEXT_OFF: db 'Beenden',0
|
||||
TEXT_SAVING: db 'Saving RAM-drive...',0
|
||||
else if lang eq it_IT
|
||||
TEXT_WTITLE: db 'Shutdown computer',0
|
||||
TEXT_RDSAVE1: db 'Save all changes that were done',0
|
||||
TEXT_RDSAVE2: db 'during system work (Ctrl+S)',0
|
||||
TEXT_KERNEL: db 'Kernel',0
|
||||
TEXT_REBOOT: db 'Riavvio',0
|
||||
TEXT_OFF: db 'Spegni',0
|
||||
TEXT_SAVING: db 'Saving RAM-drive...',0
|
||||
else ; Default to en_US
|
||||
TEXT_WTITLE: db 'Shutdown computer',0
|
||||
TEXT_RDSAVE1: db 'Save all changes that were done',0
|
||||
TEXT_RDSAVE2: db 'during system work (Ctrl+S)',0
|
||||
TEXT_KERNEL: db 'Kernel',0
|
||||
TEXT_REBOOT: db 'Reboot',0
|
||||
TEXT_OFF: db 'Power off',0
|
||||
TEXT_SAVING: db 'Saving RAM-drive...',0
|
||||
end if
|
||||
;---------------------------------------------------------------------
|
||||
rdsave:
|
||||
dd SSF_START_APP,0,hide,0,0
|
||||
db '/sys/rdsave',0
|
||||
hide db 'h',0
|
||||
asettings db 'settings',0
|
||||
aautosave db 'autosave',0
|
||||
ini_file db '/sys/settings/rdsave.ini',0
|
||||
;---------------------------------------------------------------------
|
||||
importLib:
|
||||
library \
|
||||
libini, 'libini.obj'
|
||||
|
||||
import libini, \
|
||||
ini_set_int ,'ini_set_int', \
|
||||
ini_get_int ,'ini_get_int'
|
||||
;---------------------------------------------------------------------
|
||||
checkbox_sharedname db 'CHECKBOX',0
|
||||
checkbox_img dd ?
|
||||
;---------------------------------------------------------------------
|
||||
@@ -1,221 +0,0 @@
|
||||
; END
|
||||
; KolibriOS Team 2005-2021
|
||||
|
||||
use32 ; включить 32-битный режим ассемблера
|
||||
org 0x0 ; адресация с нуля
|
||||
|
||||
db 'MENUET01' ; 8-байтный идентификатор MenuetOS
|
||||
dd 0x01 ; версия заголовка (всегда 1)
|
||||
dd START ; адрес первой команды
|
||||
dd IM_END ; размер программы
|
||||
dd I_END ; количество памяти
|
||||
dd stacktop ; адрес вершины стека
|
||||
dd 0x0 ; адрес буфера для параметров
|
||||
dd 0x0
|
||||
|
||||
include 'lang.inc'
|
||||
include '../../../macros.inc'
|
||||
include '../../../proc32.inc'
|
||||
include '../../../dll.inc'
|
||||
include '../../../KOSfuncs.inc'
|
||||
include '../../../gui_patterns.inc'
|
||||
include '../../../string.inc'
|
||||
|
||||
START:
|
||||
mcall SF_SYS_MISC, SSF_HEAP_INIT
|
||||
mcall SF_SYS_MISC, SSF_MEM_OPEN, checkbox_sharedname
|
||||
mov [checkbox_img], eax
|
||||
|
||||
stdcall dll.Load,importLib
|
||||
or eax, eax
|
||||
jnz redraw
|
||||
|
||||
invoke ini_get_int,ini_file,asettings,aautosave,0
|
||||
mov [autosave],eax
|
||||
redraw:
|
||||
call draw_window
|
||||
still:
|
||||
mcall SF_WAIT_EVENT ;wait here for event
|
||||
dec eax
|
||||
jz redraw
|
||||
dec eax
|
||||
jz key
|
||||
dec eax
|
||||
jz button
|
||||
jmp still
|
||||
|
||||
key:
|
||||
mcall SF_GET_KEY ;get key code
|
||||
mov al,ah
|
||||
cmp al,13
|
||||
je restart
|
||||
cmp al,19
|
||||
je checkbox
|
||||
cmp al,180
|
||||
je restart_kernel
|
||||
cmp al,181
|
||||
je power_off
|
||||
cmp al,27
|
||||
jne still
|
||||
|
||||
close:
|
||||
mcall SF_TERMINATE_PROCESS
|
||||
|
||||
button:
|
||||
mcall SF_GET_BUTTON ;get pressed button id
|
||||
xchg al,ah
|
||||
dec eax
|
||||
jz close
|
||||
dec eax
|
||||
jz restart_kernel
|
||||
dec eax
|
||||
jz restart
|
||||
dec eax
|
||||
jnz checkbox
|
||||
|
||||
power_off:
|
||||
push 2
|
||||
jmp mcall_and_close
|
||||
|
||||
restart:
|
||||
push 3
|
||||
jmp mcall_and_close
|
||||
|
||||
restart_kernel:
|
||||
push 4
|
||||
|
||||
mcall_and_close:
|
||||
invoke ini_set_int,ini_file,asettings,aautosave,[autosave]
|
||||
cmp [autosave],1
|
||||
jne no_save
|
||||
|
||||
mcall SF_DRAW_TEXT,<55,108>,0x90FF990A,TEXT_SAVING
|
||||
|
||||
mcall SF_FILE,rdsave
|
||||
test eax,eax
|
||||
js no_save
|
||||
mov ecx,eax
|
||||
mcall SF_SYSTEM,SSF_GET_THREAD_SLOT
|
||||
mov ecx,eax
|
||||
@@:
|
||||
push ecx
|
||||
mcall SF_WAIT_EVENT_TIMEOUT,100
|
||||
dec eax
|
||||
jnz no_red
|
||||
call draw_window
|
||||
no_red:
|
||||
pop ecx
|
||||
mcall SF_THREAD_INFO,proc_info
|
||||
cmp [proc_info+50],9
|
||||
je no_save
|
||||
jmp @b
|
||||
no_save:
|
||||
pop ecx
|
||||
mcall SF_SYSTEM,SSF_SHUTDOWN
|
||||
mcall SF_TERMINATE_PROCESS
|
||||
ret
|
||||
|
||||
checkbox:
|
||||
cmp [autosave],1
|
||||
je .1
|
||||
mov [autosave],1
|
||||
jmp .draw
|
||||
.1:
|
||||
mov [autosave],0
|
||||
.draw:
|
||||
call draw_checkbox_flag
|
||||
jmp still
|
||||
|
||||
draw_window:
|
||||
mcall SF_REDRAW,SSF_BEGIN_DRAW
|
||||
|
||||
mcall SF_GET_SCREEN_SIZE
|
||||
movzx ecx,ax
|
||||
shr eax,17
|
||||
shl eax,16
|
||||
lea ebx,[eax-(WIN_W/2) shl 16+WIN_W-1]
|
||||
shr ecx,1
|
||||
shl ecx,16
|
||||
lea ecx,[ecx-(WIN_H/2) shl 16+WIN_H-1]
|
||||
|
||||
xor eax,eax
|
||||
mov edx, 0x41000000
|
||||
mcall ;define and draw window
|
||||
|
||||
DrawWideRectangle 0, 0, WIN_W, WIN_H, 2, 0xA3A7AA
|
||||
mcall SF_DRAW_RECT, <2,WIN_W-4>, <2,WIN_H-BOT_PANEL_H-2>, 0x202020
|
||||
mcall SF_DRAW_RECT, <2,WIN_W-4>, <WIN_H-BOT_PANEL_H-2,BOT_PANEL_H>, 0x4B4B4B
|
||||
|
||||
mcall SF_DRAW_TEXT, <30,21>, 0x91FFFfff, TEXT_WTITLE
|
||||
mcall SF_DRAW_TEXT, <55,70>, 0x90FFFfff, TEXT_RDSAVE1
|
||||
mcall SF_DRAW_TEXT, <55,86>, 0x90FFFfff, TEXT_RDSAVE2
|
||||
mcall SF_DRAW_TEXT, <WIN_W-23,5>, 0x81FFFfff, TEXT_CANCEL
|
||||
|
||||
mcall SF_DEFINE_BUTTON, <WIN_W-35,32>, <2,22>, CANCEL_BUTTON_ID
|
||||
mcall SF_DEFINE_BUTTON, <32,14>, <70,14>, CHECKBOX_BUTTON_ID
|
||||
mcall SF_DEFINE_BUTTON, <47,WIN_W-47>, <68,34>, CHECKBOX_BUTTON_ID+BT_NOFRAME
|
||||
DrawRectangle3D 32, 70, 14, 14, 0x606060, 0xAFAFAF
|
||||
call draw_checkbox_flag
|
||||
|
||||
stdcall EndButton, 20, 0x4E91C5, HOME_BUTTON_ID, TEXT_KERNEL, TEXT_HOME
|
||||
stdcall EndButton, 160, 0x41C166, REBOOT_BUTTON_ID, TEXT_REBOOT, TEXT_ENTER
|
||||
stdcall EndButton, 300, 0xC75C54, POWEROFF_BUTTON_ID, TEXT_OFF, TEXT_END
|
||||
|
||||
mcall SF_REDRAW,SSF_END_DRAW
|
||||
ret
|
||||
|
||||
proc EndButton x, bgcol, id, but_text, hotkey_text
|
||||
BUTY = WIN_H-60
|
||||
BUTW = 116
|
||||
mov ebx,[x]
|
||||
sub ebx,3
|
||||
mcall SF_DRAW_RECT, <ebx,BUTW+7>, <BUTY-3,43+6>, 0x202020
|
||||
mcall SF_DEFINE_BUTTON, <[x],BUTW>, <BUTY,43-1>, [id], [bgcol]
|
||||
; -strlen(but_text)*8 + BUTW / 2 + x, BUTY+8
|
||||
stdcall string.length, [but_text]
|
||||
neg eax
|
||||
lea ebx,[eax*4+BUTW/2]
|
||||
add ebx,[x]
|
||||
mcall SF_DRAW_TEXT, <ebx,BUTY+8>, 0x90FFFfff, [but_text]
|
||||
add ebx,1 shl 16
|
||||
mcall
|
||||
stdcall string.length, [hotkey_text]
|
||||
neg eax
|
||||
lea ebx,[eax*3+BUTW/2]
|
||||
add ebx,[x]
|
||||
shl ebx,16
|
||||
add ebx,BUTY+26
|
||||
mcall SF_DRAW_TEXT, , 0x80FFFfff, [hotkey_text]
|
||||
ret
|
||||
endp
|
||||
|
||||
draw_checkbox_flag:
|
||||
cmp [autosave],0
|
||||
je .flag_unset
|
||||
cmp [checkbox_img],0
|
||||
je .flag_set_but_no_checkbox_img
|
||||
.flag_set:
|
||||
mcall SF_PUT_IMAGE, [checkbox_img], <13,13>, <33,71>
|
||||
ret
|
||||
.flag_set_but_no_checkbox_img:
|
||||
mcall SF_DRAW_RECT, <33,13>, <71,13>, 0xffffff
|
||||
mcall SF_DRAW_RECT, <34,11>, <72,11>, 0x58C33C
|
||||
ret
|
||||
.flag_unset:
|
||||
mcall SF_DRAW_RECT, <33,13>, <71,13>, 0xFFFfff
|
||||
ret
|
||||
;---------------------------------------------------------------------
|
||||
include 'data.inc'
|
||||
;---------------------------------------------------------------------
|
||||
IM_END:
|
||||
;---------------------------------------------------------------------
|
||||
align 4
|
||||
proc_info rb 1024
|
||||
autosave rd 1
|
||||
;---------------------------------------------------------------------
|
||||
library_path rb 4096
|
||||
;---------------------------------------------------------------------
|
||||
align 32
|
||||
rb 4096
|
||||
stacktop:
|
||||
I_END: ; метка конца программы
|
||||
Loaded 100 of 130 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user