docs: справочник libc API, правила проекта в CLAUDE.md, актуализация TODO (П7)
- docs/libc-reference.md — сводный справочник по всем заголовкам: сигнатуры + описание + особенности ABI и квирки - CLAUDE.md — сборка/проверка (make, size-check, MAME-workflow), правила libc (1 функция = 1 модуль, internal _-модули, русские комментарии, без = 0, asm-связки), ABI-шпаргалка, структура репо - docs/TODO.md переписан: открытые задачи наверху (MAME/железо, auto-banking, v2: BGI/IM2/audio, gfx-расширения, Port_Y), закрытые этапы 5-10 сжаты в «Историю»; снят протухший пункт «FILE API rewrite для v2» (сделан в v1), fprintf/fscanf и др. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,194 @@
|
||||
# libc — справочник API (2026-07-06)
|
||||
|
||||
Сводка по заголовкам: сигнатура + одна строка + особенности ABI.
|
||||
Детали дизайна: docs/libc-headers.md (контракт затенения SDCC),
|
||||
docs/file-buffering-design.md (FILE*), docs/solid_c_compatibility.md.
|
||||
|
||||
Общие соглашения:
|
||||
- ошибки: возврат -1/NULL/EOF + `errno` (код DSS as-is, см. errno.h);
|
||||
- SDCC `__sdcccall(1)`: 1-й аргумент HL (8-битный — A), 2-й — DE,
|
||||
остальные на стеке; **int/указатель возвращается в DE**;
|
||||
- строки для BIOS-вызовов (rst 8) должны лежать в #4000–#BFFF;
|
||||
- стек при любых ESTEX/BIOS-вызовах — в W2 (обеспечено crt0).
|
||||
|
||||
## <stdio.h> — полная замена SDCC (контракт: printf-семейство из z80.lib)
|
||||
|
||||
Из SDCC z80.lib: `printf sprintf vprintf vsprintf`.
|
||||
|
||||
Консоль (ESTEX, без атрибутов — быстрый путь; цветной вывод — conio):
|
||||
| Сигнатура | Описание |
|
||||
|---|---|
|
||||
| `int putchar(int c)` | символ через PUTCHAR $5B; '\n'→CR LF |
|
||||
| `int getchar(void)` | блокирующий WAITKEY $30, ASCII |
|
||||
| `char puts(const char *s)` | строка + '\n' (посимвольно через putchar) |
|
||||
| `char *gets(char *buf)` | строка с консоли, без контроля длины |
|
||||
| `void dec8/dec16/dec32(v)` | десятичная печать без ведущих нулей |
|
||||
| `void hex8/hex16/hex32(v)` | hex-печать фиксированной ширины |
|
||||
|
||||
FILE* (буферизованный, вариант B+ — единый ленивый буфер BUFSIZ=512
|
||||
на чтение/запись с автопереключением; таблица `OPEN_MAX=8` слотов;
|
||||
exit() сбрасывает всё через atexit; **ошибки записи отложенные —
|
||||
проверять fclose**):
|
||||
| Сигнатура | Описание |
|
||||
|---|---|
|
||||
| `FILE *fopen(path, mode)` | "r/w/a" + '+', 'b/t' игнорируются |
|
||||
| `FILE *fdopen(fd, mode)` | завернуть готовый fd (закрывать fclose!) |
|
||||
| `FILE *freopen(path, mode, fp)` | переоткрыть тот же FILE* |
|
||||
| `int fclose(FILE*)` / `void fclosall(void)` | сброс+закрытие / все потоки |
|
||||
| `int fflush(FILE*)` | сброс записи / откат readahead; NULL = все |
|
||||
| `int fgetc/fputc(...)` | горячий путь на asm; getc/putc — макро-алиасы |
|
||||
| `char *fgets(buf, n, fp)` | до '\n' (сохраняется); блочный LDI-сканер |
|
||||
| `int fputs(s, fp)` | без '\n'; через fwrite |
|
||||
| `size_t fread/fwrite(p, sz, n, fp)` | блоки ≥ 512 идут мимо буфера |
|
||||
| `int ungetc(c, fp)` | 1 байт putback (и на stdin) |
|
||||
| `int fseek(fp, off, whence)` / `long ftell(fp)` | ftell без побочных эффектов |
|
||||
| `void rewind(fp)` | fseek(0) + сброс EOF/ERROR |
|
||||
| `int fgetpos/fsetpos(fp, &pos)` | fpos_t = long |
|
||||
| `int feof/ferror(fp)`, `void clearerr(fp)` | флаги потока |
|
||||
| `int fprintf/vfprintf(fp, fmt, ...)` | vsprintf в статический буфер 256 |
|
||||
| `int scanf/fscanf/sscanf(...)` | %d %u %x %o %c %s, `l`, ширина, %*, %% |
|
||||
| `int rename(old, new)` | ESTEX RENAME $10 |
|
||||
|
||||
`stdin/stdout/stderr` — консольные псевдопотоки (fd 0/-1/-2), не
|
||||
буферизуются; freopen на них меняет только FILE*-операции (printf
|
||||
идёт в ESTEX напрямую).
|
||||
|
||||
## <stdlib.h> — include_next + добавки
|
||||
|
||||
Из SDCC: malloc/free/calloc/realloc (heap в W2), atoi/atol/strtol/
|
||||
strtoul, rand/srand, qsort/bsearch, abs/labs, div/ldiv, exit-типы.
|
||||
Наше: `int16_t min(a,b)`, `int16_t max(a,b)` (функции, как в Solid-C).
|
||||
|
||||
## <string.h> — include_next + добавки
|
||||
|
||||
Из SDCC: mem*/str* полностью. Наше: `char *strlwr/strupr(char *s)` —
|
||||
in-place регистр, латиница + кириллица CP866.
|
||||
|
||||
## <time.h> — полная замена (struct tm в SDCC-ABI, __TIME_UNSIGNED=1)
|
||||
|
||||
| Сигнатура | Описание |
|
||||
|---|---|
|
||||
| `void getdatetime(datetime_t*)` | RTC как есть (ESTEX SYSTIME $21) |
|
||||
| `int setdatetime(const datetime_t*)` | установка RTC ($22) |
|
||||
| `time_t time(time_t*)` | Unix-эпоха из RTC |
|
||||
| `mktime/gmtime/localtime/asctime/ctime` | POSIX поверх RTC (без TZ) |
|
||||
|
||||
`datetime_t`: day/month/year(полный)/hour/minute/second/dow (1=Вс).
|
||||
|
||||
## <unistd.h>, <fcntl.h> — fd-уровень (манипуляторы DSS)
|
||||
|
||||
| Сигнатура | Описание |
|
||||
|---|---|
|
||||
| `int open(path, flags)` | O_RDONLY/WRONLY/RDWR + O_CREAT/TRUNC/EXCL/APPEND (ESTEX $11/$0A/$0B) |
|
||||
| `int creat(path, mode)` | open(W|CREAT|TRUNC); mode игнорируется |
|
||||
| `int read/write(fd, buf, n)` | ESTEX $13/$14. **Квирк WRITE: DE-возврат ненадёжен, успех = CF=0&A=0** (см. memory/estex_write_de_quirk) |
|
||||
| `int close(fd)` | ESTEX $12 |
|
||||
| `long lseek(fd, off, whence)` | 32-битная позиция (MOVE_FP $15) |
|
||||
| `int unlink(path)` | удалить (DELETE $0E) |
|
||||
| `int isatty(fd)` | fd <= 0 (файловые манипуляторы DSS с 1) |
|
||||
| `int mkdir/rmdir/chdir(path)` | ESTEX $1B/$1C/$1D |
|
||||
| `char *getcwd(buf, size)` | буфер 256 байт, size игнорируется |
|
||||
| `void sleep(seconds)` | 50 halt/с по кадровому IRQ |
|
||||
|
||||
**Лимит: 8 одновременных манипуляторов**; 9-й OPEN вешает DSS —
|
||||
libc отказывает сама (EMFILE, предохранитель _fd_guard).
|
||||
|
||||
## <errno.h>
|
||||
|
||||
`errno` (int), коды = коды DSS (EOK..EUNKERR) + POSIX-имена
|
||||
(ENOENT/EBADF/EMFILE/…) + алиасы Solid-C (EZERO/EINVFNC/ENOFILE/…).
|
||||
`const char *strerror(int)`, `void perror(const char*)`.
|
||||
|
||||
## <dos.h> — DOS-слой Solid-C
|
||||
|
||||
| Сигнатура | Описание |
|
||||
|---|---|
|
||||
| `void getdate/gettime(&d)` | struct date/time (Turbo-C; ti_hund=0) |
|
||||
| `int setdate/settime(&d)` | RMW полного datetime |
|
||||
| `uint8_t getdisk(void)` | текущий диск, 0=A (ESTEX $02) |
|
||||
| `int setdisk(uint8_t)` | смена диска; возврат = число дисков ($01) |
|
||||
| `int absread/abswrite(disk, sect, cnt, buf)` | секторы ЛОГИЧЕСКОГО диска (BIOS $55/$56); буфер в #4000–#BFFF; abswrite минует ФС! |
|
||||
|
||||
## <dir.h>
|
||||
|
||||
`int ffirst(pattern, ffblk_t*, attrib)` / `int fnext(ffblk_t*)` —
|
||||
поиск по шаблону (ESTEX $19/$1A). Квирк: "."/".." находятся только
|
||||
итерацией "*.*" (memory/estex_ffirst_dotdot). FA_*-атрибуты.
|
||||
|
||||
## <sys/stat.h>
|
||||
|
||||
`int stat(path, struct stat*)` / `int fstat(fd, ...)` — st_mode
|
||||
(S_ISREG/S_ISDIR), st_size, st_mtime (Unix-эпоха).
|
||||
|
||||
## <conio.h> — текстовый экран с атрибутами (Turbo-C стиль)
|
||||
|
||||
Клавиатура: `kbhit getch getche getkey` (+KEY_* коды позиций),
|
||||
`char *cgets(buf)`.
|
||||
Вывод с атрибутом: `putch cputs cprintf` (~10× медленнее stdio-пути;
|
||||
'\n' НЕ транслируется — писать "\r\n").
|
||||
Атрибуты: `textcolor textbackground textattr`, `set/get_text_attr`,
|
||||
COLOR_*-enum, `COLOR(fg,bg)`, COLOR_BLINK; `set/get_putch_raw_mode`.
|
||||
Экран: `clrscr clrscr_attr gotoxy home() wherex wherey wherexy scroll
|
||||
wrchar rdchar`; режимы `gettextmode/settextmode` (0x02=40×32,
|
||||
0x03=80×32).
|
||||
Порты/IRQ: `inp outp enable() disable()`.
|
||||
Текстовая палитра: `text_pal_load/set_color/get/get_color/reset`
|
||||
(план 0..3 → страница BIOS 4..7).
|
||||
|
||||
## <bios/text.h> — быстрый BIOS-вывод (rst 8, place-based)
|
||||
|
||||
`bios_set_place/get_place`, `bios_write[attr][_until|_stop]`,
|
||||
`bios_fillchar/fillattr/fillcharattr`, `bios_clearwin[_ch]`,
|
||||
`bios_scrollwin`. Строка s — в #4000–#BFFF; place продвигается.
|
||||
|
||||
## <gfx.h> — графика (0x81: 320×256×256; 0x82: 640×256×16)
|
||||
|
||||
Setup: `gfx_init(mode,page)→prev`, `gfx_done(prev)`.
|
||||
Страницы/банк: `gfx_set/get_visible_page`, `gfx_set/get_draw_page`
|
||||
(double buffering), `gfx_set/get_bank` (0x50..0x5F, 0x58 = FF-
|
||||
прозрачность), `gfx_wait_vsync()`.
|
||||
Примитивы (суффикс _256 / _16): `clear putpixel hline vline line
|
||||
rect fill_rect` — через акселератор (hline/vline burst до 256 байт;
|
||||
в 0x82 vline через RMW). Координаты int, клиппинг по краям.
|
||||
Текст: `gfx_putchar256/16, gfx_text256/16` (8×8, fg/bg; в 0x82 x —
|
||||
чётный), `gfx_load_default_font`, `gfx_set_font(ptr)` (interleaved
|
||||
font[row*256+char]).
|
||||
Палитра: `gfx_pal_load/set/get/get_color/reset` (страницы 0..3).
|
||||
|
||||
## <palette.h> — низкий уровень (BIOS $A4/$A6)
|
||||
|
||||
`pal_load pal_get pal_set_color pal_get_color` (страница 0..7,
|
||||
записи B,G,R,0), `pal_reset(type)` / `pal_reset_at(type,page,graph)`;
|
||||
PAL_GRAPH/PAL_SINCLAIR/PAL_CGA.
|
||||
|
||||
## <mouse.h> — драйвер RST 30h
|
||||
|
||||
`mouse_init show hide refresh read(mouse_state_t*) goto bounds_x/y
|
||||
text_cursor load_cursor/get_cursor(mouse_cursor_t*) set_sensitivity
|
||||
get_sensitivity_x/y video_mode_changed`. Sensitivity = делитель
|
||||
(меньше = быстрее). Solid-C алиасы ms_* включены.
|
||||
|
||||
## <sprinter.h> — платформа
|
||||
|
||||
Константы портов (PORT_PAGE_W0..W3, PORT_RGADR, PORT_RGMOD), номера
|
||||
всех ESTEX-функций (ESTEX_*), BIOS EMM ($C0..$C7); `__sfr`-доступ и
|
||||
inline `sprinter_page_w0..w3(page)`; ENV: `getenv putenv sysenv`.
|
||||
|
||||
## <sprinter_mem.h> — EMM-страницы и банковый I/O
|
||||
|
||||
`mem_alloc_pages(n)→blk_id, mem_free_block, mem_get_page(blk,idx),
|
||||
mem_info(&total,&free)` (реализации _bios/_estex; макро-выбор
|
||||
MEM_MANAGE_MODE_*). HOME-резидентный доступ к чужим страницам:
|
||||
`bank_load_byte/store_byte/read/write` (своп W3 внутри; *_w1 —
|
||||
вариант через окно W1).
|
||||
|
||||
## <sprinter_exit.h>
|
||||
|
||||
`atexit` (LIFO, 8 слотов), `exit` (хендлеры+сброс FILE), `_exit`.
|
||||
|
||||
## <sprinter_compat.h> / <sprinter_solid.h>
|
||||
|
||||
Типы (BYTE/BOOL/WORD/uint/FD/f_point), TRUE/FALSE/OK/ERROR,
|
||||
`setmem movmem` (порядок аргументов!), `strerr seek tell ltell
|
||||
remove _ffirst _setargv abort()`, isascii. `<sprinter_solid.h>` —
|
||||
зонтичный: один include для портирования Solid-C программ.
|
||||
Reference in New Issue
Block a user