libc: add bios/text.h BIOS text-output API

Direct __naked z80 wrappers over BIOS LP_PRINT_*/LP_SET_PLACE/LP_GET_PLACE
(RST 8, opcodes 081h-08Eh) for fast text rendering — a single BIOS call
replaces a wrchar() loop for constant-attribute/constant-character runs.
Covered by tests/bios_text.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-23 17:06:13 +03:00
parent bd116d7361
commit c9d5ea35a4
5 changed files with 525 additions and 0 deletions
+110
View File
@@ -0,0 +1,110 @@
#include <stdio.h>
#include <conio.h>
#include <bios/text.h>
/*
* Exercises every BIOS text wrapper from <bios/text.h>:
* bios_set_place / bios_get_place
* bios_fillchar / bios_fillchar_noattr / bios_fillattr
* bios_writeattr / bios_write
* bios_writeattr_until / bios_write_until (pad to length)
* bios_writeattr_stop / bios_write_stop (stop at separator)
* bios_clearwin / bios_clearwin_ch
* bios_scrollwin
*
* `s` below is a static buffer (not a string literal) so its address is
* always inside window 2, as the BIOS print routines require.
*/
static char s[16];
int main(void)
{
clrscr();
/* Step 0 check: does LP_PRINT_LN advance the BIOS "place" cursor
* by the number of characters printed, or leave it untouched?
* "Hello" is 5 chars -> if place advances, before=(20,5),
* after=(20,10); if not, after == before. */
s[0]='H'; s[1]='e'; s[2]='l'; s[3]='l'; s[4]='o';
bios_set_place(20, 5);
{
uint16_t before = bios_get_place();
bios_writeattr(s, 5, COLOR(COLOR_WHITE, COLOR_BLACK));
uint16_t after = bios_get_place();
gotoxy(2, 0);
textattr(0x0F);
printf("STEP0: before row=%u col=%u\n", before >> 8, before & 0xFF);
printf("STEP0: after row=%u col=%u\n", after >> 8, after & 0xFF);
printf("STEP0: expect after col=10 if place advances,\n");
printf(" col=5 if it does NOT advance.\n");
}
(void)getch();
bios_set_place(1, 2);
bios_fillcharattr('*', COLOR(COLOR_YELLOW, COLOR_BLUE), 10);
(void)getch();
bios_set_place(2, 2);
textattr(COLOR(COLOR_WHITE, COLOR_BLACK));
cputs("attr already on screen ->");
(void)getch();
bios_set_place(2, 27);
bios_fillchar('#', 10);
(void)getch();
bios_set_place(3, 2);
bios_fillattr(COLOR(COLOR_BLACK, COLOR_LIGHTGREEN), 20);
(void)getch();
s[0]='H'; s[1]='e'; s[2]='l'; s[3]='l'; s[4]='o';
bios_set_place(5, 2);
bios_writeattr(s, 5, COLOR(COLOR_LIGHTRED, COLOR_BLACK));
(void)getch();
bios_set_place(6, 2);
bios_write(s, 5);
(void)getch();
s[0]='A'; s[1]='B'; s[2]=':'; s[3]='X'; s[4]='Y'; s[5]='Z';
bios_set_place(8, 2);
bios_writeattr_until(s, 12, COLOR(COLOR_CYAN, COLOR_BLACK), ':');
(void)getch();
bios_set_place(9, 2);
bios_write_until(s, 12, ':');
(void)getch();
bios_set_place(10, 2);
bios_writeattr_stop(s, 12, COLOR(COLOR_MAGENTA, COLOR_BLACK), ':');
(void)getch();
bios_set_place(11, 2);
bios_write_stop(s, 12, ':');
(void)getch();
bios_clearwin(13, 2, 4, 20, COLOR(COLOR_BLACK, COLOR_RED));
bios_clearwin_ch(13, 25, 4, 20, COLOR(COLOR_WHITE, COLOR_BLUE), '.');
(void)getch();
bios_set_place(18, 2);
(void)getch();
cputs("place test ->");
{
uint16_t place = bios_get_place();
printf(" row=%u col=%u\n", place >> 8, place & 0xFF);
}
(void)getch();
gotoxy(2, 20);
for (int i = 0; i < 6; i++) {
textattr(0x0F);
printf("scroll line %d\n", i);
}
(void)getch();
bios_scrollwin(BIOS_SCROLL_UP, 20, 3);
(void)getch();
return 0;
}