9f8aa6fc28
Симметрично libbgi (bgi256/bgi256_safe): fast = -DLIBC_NOCHECK, дефолт sprinter-cc; safe линкуется по --safe (флаг уже существовал). Под LIBC_NOCHECK вырезаны ТОЛЬКО параметр-валидации: - fgetc/fputc: NULL-check в горячей asm-обёртке (~11Т на каждый байт); - fgets/fputs/fread/fwrite: NULL ptr/fp и EBADF на неверное направление потока; ftell/fseek/ungetc/fclose: NULL fp; cputs: NULL s. НЕ тронуты: критичный _fd_guard (9-й OPEN вешает DSS — в обеих версиях), функциональная маршрутизация (консоль/направление/hold), cold-path валидации (fopen/cbl_open/irq/settextmode — экономии ноль). libc/Makefile — dual-build по образцу libbgi (build/fast + build/safe, общий стейл-контроль). Корневой Makefile: в TESTS добавлены bgitest, bgi_img, accfill, cblstream — раньше не собирались корневым make и выпадали из size-check при чистой пересборке. Дельты fast vs старая (safe-семантика): filetest -481, fbench -384, solidt -180, errno -71, остальные -3..-9; роста нет. Проверено в MAME: filetest fast и safe (--safe, sprinter_safe.lib) — прогоны идентичны. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
75 lines
2.4 KiB
C
75 lines
2.4 KiB
C
/*
|
||
* cputs — вывод ASCIIZ-строки с текущим атрибутом (Turbo-C conio).
|
||
*
|
||
* Курсор BIOS читается один раз до строки и записывается один раз
|
||
* после. Три пути:
|
||
* g_text_attr == KEEP_EXIST_ATTR → быстрый ESTEX PCHARS ($5C);
|
||
* pc_raw_mode == 1 → BIOS LP_PRINT_LN5 (глифы с атрибутом);
|
||
* иначе → цикл _putch_wrchar (интерпретация
|
||
* BS/TAB/LF/CR).
|
||
* Трансляции '\n' → CR LF нет — вызывающий пишет "\r\n" сам.
|
||
* cputs(NULL) — no-op. Возвращает 0.
|
||
*/
|
||
|
||
#include "_conio.h"
|
||
|
||
char cputs(const char *s) __naked
|
||
{
|
||
(void)s;
|
||
__asm
|
||
;; HL = s на входе; возврат char → A.
|
||
|
||
#ifndef LIBC_NOCHECK
|
||
;; NULL-check: cputs(NULL) → сразу вернуть 0.
|
||
ld a, h
|
||
or a, l
|
||
ret z
|
||
#endif
|
||
|
||
push ix
|
||
|
||
call __get_cursor
|
||
|
||
;; KEEP_EXIST_ATTR? старший байт g_text_attr != 0
|
||
ld a, (_g_text_attr + 1)
|
||
or a, a
|
||
jr nz, _cputs_fast
|
||
|
||
ld a, (_pc_raw_mode)
|
||
or a, a
|
||
jr nz, _cputs_bios
|
||
|
||
push hl
|
||
pop de
|
||
|
||
_cputs_wrloop:
|
||
ld a, (_g_text_attr)
|
||
ld l, a
|
||
ld a, (de) ; загрузить байт
|
||
or a ; установить флаг Z, если A == 0
|
||
jr z, _cputs_ex ; завершить подпрограмму (конец строки)
|
||
push de
|
||
call __putch_wrchar ; вывести символ (A передаётся как аргумент)
|
||
pop de
|
||
inc de ; перейти к следующему байту
|
||
jr _cputs_wrloop ; повторить
|
||
|
||
_cputs_bios:
|
||
ld a, (_g_text_attr)
|
||
ld b, #0xFF
|
||
ld d, #0x0
|
||
ld e, a
|
||
ld c, #0x8B ; BIOS LP_PRINT_LN5
|
||
rst #0x08
|
||
jr _cputs_ex
|
||
_cputs_fast:
|
||
ld c, #0x5C ; ESTEX PCHARS
|
||
rst #0x10
|
||
_cputs_ex:
|
||
call __set_cursor
|
||
pop ix ; восстановить IX вызывающего
|
||
xor a, a ; вернуть 0
|
||
ret
|
||
__endasm;
|
||
}
|