Files
Sprinter-SDCC/libc/io/lseek.c
T
snark13 4a081501d8 libc: сплит «1 функция = 1 модуль» — вся библиотека, wildcard-сборка
- bios/conio/env/errno/gfx/io/mem/mouse/stdio/stdlib/string/sys/time/
  video разложены по модулям: общие статики и helpers — в internal
  _-модулях (_conio.h/_mouse.h/_gfx.h/_palette.h/_atexit.h/_time.h)
- lib/Makefile: LIBC_C = wildcard libc/*/*.c — гранулярность файлов
  = гранулярность DCE линкера
- эффект _CODE: gfx_text 6986→2568 Б, gfx_mous −1745, gfx_demo/d16
  −542; ранее timedir −3270, ls −3098, stattest −2995
- комментарии оставшихся модулей переведены на русский; puts: убран
  мёртвый pchars; videomode_raw разложен на get/set
- docs/libc-split-asm-cases.md — правила asm-связок между модулями;
  docs/libc-roadmap.md — план этапа
- восстановлен examples/mdview/SAMPLE.MD (нужен make floppy)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 16:08:58 +03:00

73 lines
2.8 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* lseek — 32-битная позиция файла через ESTEX MOVE_FP ($15).
*
* ESTEX MOVE_FP: A=handle, B=whence (0=SET, 1=CUR, 2=END),
* HL=offset high16, IX=offset low16
* возврат: HL:IX = новая абсолютная позиция, CF=err
*
* SDCC __sdcccall(1) на z80 для `long lseek(int fd, long offset, int whence)`:
* - fd — HL (первый 16-битный аргумент в регистре)
* - offset — на стеке двумя 16-битными словами (сначала low, потом high)
* - whence — на стеке (выше offset)
* - 32-битный возврат: DE = low16, HL = high16
* - стек чистит вызывающий (`pop af; pop af; pop af` после call)
*
* IX сохраняется (frame pointer вызывающего).
*/
#include <unistd.h>
long lseek(int fd, long offset, int whence) __naked
{
(void)fd; (void)offset; (void)whence;
__asm
push ix ; сохранить IX вызывающего
;; Раскладка после push:
;; SP+0..1 = сохранённый IX
;; SP+2..3 = адрес возврата
;; SP+4..5 = offset low16
;; SP+6..7 = offset high16
;; SP+8..9 = whence
ld a, l ; A = младший байт fd (был в HL)
;; 5 последовательных байтов стека читаем через HL дешевле,
;; чем IY-индексация: `ld r,(hl); inc hl` (2Б/13Т на байт)
;; против `ld r, n(iy)` (3Б/19Т) при последовательном чтении.
ld hl, #4
add hl, sp ; HL указывает на offset_low
ld e, (hl)
inc hl
ld d, (hl) ; DE = offset_low
push de
pop ix ; IX = offset_low
inc hl
ld e, (hl)
inc hl
ld d, (hl) ; DE = offset_high
inc hl
ld b, (hl) ; B = whence (младший байт)
ex de, hl ; HL = offset_high (ESTEX ждёт его тут)
ld c, #0x15 ; ESTEX MOVE_FP
rst #0x10
jr c, _lseek_err
;; Вернулось HL:IX = новая позиция. Приводим к long-возврату
;; SDCC (DE:HL).
push ix
pop de ; DE = low16 (был IX)
;; HL уже содержит high16
pop ix ; восстановить IX вызывающего
ret
_lseek_err:
call __errno_set
ld hl, #0xFFFF
ld de, #0xFFFF ; long -1
pop ix
ret
__endasm;
}