/* * _putch_wrchar — воркер вывода mode-0: пишет символ в (pc_place) * через ESTEX WRCHAR ($58) атрибутом attr, интерпретируя управляющие: * * 0x08 BS → pc_col-- (если не 0) * 0x09 TAB → pc_col к следующему кратному 8 (потолок 80) * 0x0A LF → pc_row++ (потолок 32; без глифа) * 0x0D CR → pc_col = 0 * прочее → WRCHAR + pc_col++ * * WRCHAR подавляется при pc_col ≥ 80 или pc_row ≥ 32 (вне экрана) — * координаты только [0..79] × [0..31]. * * Курсор BIOS НЕ трогает — вызывающий читает его один раз до серии * вызовов и записывает один раз после: плата BIOS за ОПЕРАЦИЮ, * а не за символ. */ #include "_conio.h" void _putch_wrchar(char ch, uint8_t attr) __naked { (void)ch; (void)attr; __asm ;; __sdcccall(1): ch в A, attr в L. ;; Диспетчеризация по управляющим, пока A держит ch (cp не ;; трогает A). B/C грузятся только на пути вывода, поэтому ;; ветки управляющих символов дешевле. cp #0x08 jr z, _rp0_bs cp #0x09 jr z, _rp0_tab cp #0x0A jr z, _rp0_lf cp #0x0D jr z, _rp0_cr ;; Всё остальное (печатное или незнакомый ctrl) → глиф. _rp0_pri: ld c, a ; C = ch (сохранить до порчи A) ld a, (_pc_place + 1) cp #32 ret nc ; за нижним краем — молча пропустить ld d, a ; D = row (конвенция ESTEX WRCHAR) ld a, (_pc_place) cp #80 ret nc ; за правым краем — молча пропустить ld e, a ; E = col inc a ld (_pc_place), a ; pc_col++ _rp0_wr: ld b, l ; B = attr ld a, c ; A = ch push ix ld c, #0x58 ; ESTEX WRCHAR rst #0x10 pop ix ret _rp0_bs: ld a, (_pc_place) or a, a ret z ; уже в колонке 0 — без изменений dec a ld (_pc_place), a ld e, a ; E = col ld a, (_pc_place + 1) ld d, a ; D = row (конвенция ESTEX WRCHAR) ld c, #0x20 jr _rp0_wr _rp0_tab: ld a, (_pc_place) or #0x07 ; округлить вниз к кратному 8 inc a ; → следующее кратное 8 cp #81 ; сравнить A с 81 (0x51) jr c, _rp0_tab_skip ; если A < 81 (т.е. A ≤ 80), пропустить загрузку ld a, #80 ; иначе A > 80 → установить A = 80 _rp0_tab_skip: ld (_pc_place), a ret _rp0_lf: ld a, (_pc_place + 1) cp #32 ret nc ; уже у нижнего края inc a ld (_pc_place + 1), a ret _rp0_cr: xor a, a ld (_pc_place), a ret __endasm; }