Files
Sprinter-SDCC/docs/libc-reference.md
T
snark13 7187752b29 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>
2026-07-06 20:47:33 +03:00

10 KiB
Raw Blame History

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
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 программ.