c9d5ea35a4
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>
108 lines
4.9 KiB
C
108 lines
4.9 KiB
C
/*
|
|
* bios/text.h — direct wrappers around the Sprinter BIOS text-output
|
|
* calls (RST 8, function codes 081h..08Eh, "LP_*" in the vendor docs).
|
|
*
|
|
* These bypass ESTEX's own PUTCHAR/PCHARS/WRCHAR (see <conio.h>) and talk
|
|
* straight to the BIOS character-print routines. Use them when you need
|
|
* BIOS-specific behaviour (run-length fills, pad/stop-at-separator field
|
|
* printing, raw window clear/scroll) that ESTEX doesn't expose directly.
|
|
*
|
|
* Coordinates are 0-based (row = vertical, col = horizontal), matching
|
|
* ESTEX/BIOS directly.
|
|
*
|
|
* Original BIOS name -> wrapper, with opcode (docs/converted/bios.txt):
|
|
*
|
|
* 081h LP_PRINT_ALL -> bios_fillchar fill run: char + attr
|
|
* 082h LP_PRINT_SYM -> bios_fillchar_noattr fill run: char only
|
|
* 083h LP_PRINT_ATR -> bios_fillattr fill run: attr only
|
|
* 084h LP_SET_PLACE -> bios_set_place set BIOS print cursor
|
|
* 08Eh LP_GET_PLACE -> bios_get_place read BIOS print cursor
|
|
* 085h LP_PRINT_LN -> bios_writeattr write buf + attr
|
|
* 086h LP_PRINT_LN2 -> bios_write write buf, keep attr
|
|
* 087h LP_PRINT_LN3 -> bios_writeattr_until write to sep, pad + attr
|
|
* 088h LP_PRINT_LN4 -> bios_write_until write to sep, pad
|
|
* 089h LP_CLS_WIN -> bios_clearwin clear window (space fill)
|
|
* 08Ah LP_SCROLL_UD -> bios_scrollwin scroll global window
|
|
* 08Bh LP_PRINT_LN5 -> bios_writeattr_stop write to sep, stop + attr
|
|
* 08Ch LP_PRINT_LN6 -> bios_write_stop write to sep, stop
|
|
* 08Dh LP_CLS_WIN2 -> bios_clearwin_ch clear window (custom fill)
|
|
*
|
|
* "_until" variants print up to `sep` and then PAD the rest of the field
|
|
* with spaces (output is always exactly `len` characters wide).
|
|
* "_stop" variants print up to `sep` and STOP there (no padding; `sep`
|
|
* itself is not printed; `maxlen` is just an upper bound).
|
|
*
|
|
* ABI: stack must already be in window 2 (guaranteed by crt0) — required
|
|
* by the BIOS for its own page-swap scratch use. All registers (main +
|
|
* shadow set) are clobbered except where a function says otherwise.
|
|
*/
|
|
|
|
#ifndef BIOS_TEXT_H
|
|
#define BIOS_TEXT_H
|
|
|
|
#include <stdint.h>
|
|
|
|
/* bios_scrollwin() direction values (BIOS B register). */
|
|
#define BIOS_SCROLL_UP 1
|
|
#define BIOS_SCROLL_DOWN 2
|
|
|
|
/* 081h LP_PRINT_ALL — print `count` copies of `ch` with attribute `attr`
|
|
* starting at the current BIOS print position. Preserves HL and IX. */
|
|
void bios_fillcharattr(char ch, uint8_t attr, uint8_t count);
|
|
|
|
/* 082h LP_PRINT_SYM — print `count` copies of `ch`, attribute unchanged
|
|
* (whatever is already on screen). Preserves HL and IX. */
|
|
void bios_fillchar(char ch, uint8_t count);
|
|
|
|
/* 083h LP_PRINT_ATR — overwrite `count` cells' attribute with `attr`;
|
|
* the characters already on screen are left untouched. Preserves HL
|
|
* and IX. */
|
|
void bios_fillattr(uint8_t attr, uint8_t count);
|
|
|
|
/* 084h LP_SET_PLACE — set the BIOS print cursor. Out-of-range values
|
|
* wrap (BIOS subtracts the window size, not an error). */
|
|
void bios_set_place(uint8_t row, uint8_t col);
|
|
|
|
/* 08Eh LP_GET_PLACE — read the BIOS print cursor: (row << 8) | col. */
|
|
uint16_t bios_get_place(void);
|
|
|
|
/* 085h LP_PRINT_LN — write `len` bytes from `s` with attribute `attr`,
|
|
* starting at the current BIOS print position. `s` must point inside
|
|
* window 2 (#4000..#BFFF). */
|
|
void bios_writeattr(const char *s, uint8_t len, uint8_t attr);
|
|
|
|
/* 086h LP_PRINT_LN2 — like bios_writeattr(), attribute unchanged. */
|
|
void bios_write(const char *s, uint8_t len);
|
|
|
|
/* 087h LP_PRINT_LN3 — write from `s` with attribute `attr` until the
|
|
* byte `sep` is found, then pad with spaces so exactly `len` characters
|
|
* are printed in total. */
|
|
void bios_writeattr_until(const char *s, uint8_t len, uint8_t attr, char sep);
|
|
|
|
/* 088h LP_PRINT_LN4 — like bios_writeattr_until(), attribute unchanged. */
|
|
void bios_write_until(const char *s, uint8_t len, char sep);
|
|
|
|
/* 089h LP_CLS_WIN — clear a `height` x `width` local window at
|
|
* (row, col) by writing spaces with attribute `attr`. */
|
|
void bios_clearwin(uint8_t row, uint8_t col, uint8_t height, uint8_t width,
|
|
uint8_t attr);
|
|
|
|
/* 08Ah LP_SCROLL_UD — scroll `count` whole rows of the global window,
|
|
* starting at `row`, in direction `dir` (BIOS_SCROLL_UP/_DOWN). */
|
|
void bios_scrollwin(uint8_t dir, uint8_t row, uint8_t count);
|
|
|
|
/* 08Bh LP_PRINT_LN5 — write from `s` with attribute `attr`, stopping
|
|
* (without padding) as soon as `sep` is seen; `maxlen` bounds the scan. */
|
|
void bios_writeattr_stop(const char *s, uint8_t maxlen, uint8_t attr,
|
|
char sep);
|
|
|
|
/* 08Ch LP_PRINT_LN6 — like bios_writeattr_stop(), attribute unchanged. */
|
|
void bios_write_stop(const char *s, uint8_t maxlen, char sep);
|
|
|
|
/* 08Dh LP_CLS_WIN2 — like bios_clearwin(), but fills with `fillch`
|
|
* instead of a space. */
|
|
void bios_clearwin_ch(uint8_t row, uint8_t col, uint8_t height,
|
|
uint8_t width, uint8_t attr, char fillch);
|
|
|
|
#endif
|