/*
 * 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
