Files
Sprinter-SDCC/libc/include/conio.h
T
snark13 c71e249a4e Add full compiler toolchain, libc, examples and reference docs
First substantive commit: the entire Sprinter C compiler tree on top of
the bare README+gitignore initial commit.

What's in here:
  bin/sprinter-cc        — driver script invoking SDCC + linker + mkexe
  libc/                  — Sprinter-specific libc layer over ESTEX/BIOS
                           (conio, gfx, io, mem, stdio + headers)
  runtime/               — crt0 variants (default/small/banked/minimal)
                           + heap + bank trampolines
  toolchain/             — mkexe (SprintEXE packer, C + tests)
  examples/              — 30 demo programs (gfx, file I/O, env, time, …)
  lib/Makefile           — builds the libc archive (sprinter.lib)
  docs/                  — converted Sprinter manuals + asm reference samples
  third_party/           — solid-c reference compiler dump + sdcc setup script
  release_docs/          — packaging / release notes

gitignore overhaul:
  • Drop dangerous blanket patterns: *.asm (would hide docs/samples/*.asm)
    and *.exe (case-insensitive match was hiding third_party/solid-c/*.EXE
    on macOS APFS).  Replaced with examples/*/*.{asm,exe,…} and lib/*.lib.
  • Restore tracking of toolchain/mkexe/tests/{one,big}.bin — those are
    INPUT fixtures, not build outputs.
  • Collapse the duplicated SDCC/C/Sdcc sections into one section per
    concern (build outputs / vendored / OS-junk).
  • Add .sprinter-cc-*/, build/ (catches lib/build/ too), .claude/.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-03 16:13:21 +03:00

155 lines
6.2 KiB
C

/*
* conio.h — direct console I/O backed by ESTEX functions.
*
* Two-set output API following the Turbo-C convention:
*
* stdio (fast, no attr — system default colour):
* putchar(c) — one char + '\n' → CR LF translation
* puts(s) — string + trailing newline
* printf(...) — uses putchar internally
*
* conio (slower, applies g_text_attr — set via textcolor / textbackground /
* textattr / set_text_attr):
* putch(c) — one char, NO '\n' translation
* cputs(s) — string, NO trailing newline, NO '\n' translation
* (write "\r\n" yourself for line breaks)
* cprintf(...) — printf with attribute, via vsprintf+cputs internally
*
* The conio set short-circuits to the fast path when
* g_text_attr == KEEP_EXIST_ATTR — useful for "I usually want a
* specific colour but right now don't care".
*
* Other helpers (unchanged):
* kbhit / getch / getche — keyboard
* clrscr / clrscr_attr — clear screen
* gotoxy / wherex / wherey
* wrchar / rdchar — direct VRAM cell access
* get_videotextmode / set_videotextmode (text modes only — see gfx.h
* for graphics mode constants)
*
* Coordinates are 0-based to match ESTEX directly.
*/
#ifndef CONIO_H
#define CONIO_H
#include <stdint.h>
char kbhit (void);
char getch (void);
char getche(void);
char putch (char c);
char cputs (const char *s);
int cprintf(const char *fmt, ...);
void clrscr(void);
void gotoxy(uint8_t x, uint8_t y);
/* Solid-C compatibility helpers. */
#define home() gotoxy(0, 0)
#define inp(port) z80_inp(port)
#define outp(p, v) z80_outp((p), (v))
#define enable() __asm__("ei")
#define disable() __asm__("di")
uint8_t z80_inp(uint8_t port);
void z80_outp(uint8_t port, uint8_t value);
/* Read a line from the console (no echo control — uses getche).
* `buf[0]` must be the max length; on return `buf[1]` is the actual
* length and `buf[2..]` is the NUL-terminated string. */
char *cgets(char *buf);
/* Cursor query via ESTEX $53 CURSOR. Returns 0-based row/column. */
uint8_t wherex (void);
uint8_t wherey (void);
uint16_t wherexy(void); // high byte = Y, low byte = X coords.
/* Direct character/attribute screen access (ESTEX $57 / $58).
* wrchar — write char + attribute at (x, y); does NOT advance the cursor
* and does NOT interpret control characters. Useful for
* coloured text and for painting the last-column-last-row cell
* without triggering ESTEX's auto-scroll on PCHARS/PUTCHAR.
* rdchar — read both character and attribute back; returned as
* (attr<<8 | ch). */
void wrchar(uint8_t x, uint8_t y, char ch, uint8_t attr);
uint16_t rdchar(uint8_t x, uint8_t y);
/* clrscr_attr — wipe the entire 80x32 screen using the given attribute
* byte (fill character = space). Companion to clrscr() which uses the
* default attr 0x0F (bright white on black). */
void clrscr_attr(uint8_t attr);
/* Text video-mode control (ESTEX $50 / $51). These constants and helpers
* cover ONLY text modes; graphics modes live in <gfx.h> as GFX_MODE_*.
* `set_videotextmode()` validates that the argument is a known text mode
* (so calling code that includes conio.h alone cannot accidentally switch
* the screen into graphics — that requires <gfx.h>). */
#define TEXT_MODE_40x32 0x02
#define TEXT_MODE_80x32 0x03
uint8_t get_videotextmode(void);
int set_videotextmode(uint8_t mode); /* 0 OK, -1 + errno on bad mode */
/* ------------------------------------------------------------------ *
* Text-output attribute (used by the conio set: putch / cputs / cprintf).
*
* textcolor(c) — set foreground (preserves background+blink)
* textbackground(c) — set background (preserves foreground+blink)
* textattr(a) — replace the whole attribute byte
* set_text_attr(a) — alias to textattr but returns the previous value
* get_text_attr() — read current attribute
*
* Range 0x00..0xFF is a real attribute byte; KEEP_EXIST_ATTR (0xFFFF)
* means "don't touch attributes — fall through to the fast no-attr path"
* (so putch becomes equivalent to putchar etc.).
*
* Default at startup = 0x0F (bright white on black).
*
* NOTE: stdio's putchar / puts / printf IGNORE this — they always use
* whatever ESTEX has cached for the cursor cell. Use the conio set
* (putch / cputs / cprintf) for coloured output.
* ------------------------------------------------------------------ */
#define KEEP_EXIST_ATTR 0xFFFF
void textcolor(uint8_t fg);
void textbackground(uint8_t bg);
void textattr(uint8_t attr);
int16_t set_text_attr(int16_t attr); /* returns the previous value */
int16_t get_text_attr(void);
/* Control how putch / cputs / cprintf (the WRCHAR path) treat
* control characters (< 0x20):
*
* mode = 0 (default) — interpret BS/TAB/LF/CR:
* 0x08 BS → pc_col-- (clamped at 0)
* 0x09 TAB → pc_col rounded up to next multiple of 8 (clamped 80)
* 0x0A LF → pc_row++ (clamped at 32; no glyph emitted)
* 0x0D CR → pc_col = 0
*
* mode = 1 — print EVERY character as a CP437 glyph (no
* interpretation; useful e.g. for drawing box-drawing
* characters that overlap the 0x00..0x1F range).
*
* Only affects the WRCHAR path (attr ≤ 0xFF). When attr is
* KEEP_EXIST_ATTR, ESTEX's own PUTCHAR/PCHARS rule the cursor and
* pc_raw_mode is irrelevant. */
void set_putch_raw_mode(uint8_t mode);
uint8_t get_putch_raw_mode(void);
/* Sprinter text-mode 03h attribute byte (verified via attr_probe):
* bits 0..3 = foreground (0..15)
* bits 4..6 = background (0..7)
* bit 7 = blink (toggles fg between fg-colour and bg-colour)
* Colour order is standard CGA / Borland-conio.h. Constants 0..7 are
* usable for both fg and bg; 8..15 are foreground-only. */
enum {
COLOR_BLACK = 0, COLOR_BLUE, COLOR_GREEN, COLOR_CYAN,
COLOR_RED, COLOR_MAGENTA, COLOR_BROWN, COLOR_LIGHTGRAY,
COLOR_DARKGRAY, COLOR_LIGHTBLUE, COLOR_LIGHTGREEN, COLOR_LIGHTCYAN,
COLOR_LIGHTRED, COLOR_LIGHTMAGENTA, COLOR_YELLOW, COLOR_WHITE
};
#define COLOR_BLINK 0x80u
#define COLOR(fg, bg) ((uint8_t)((((bg) & 0x07) << 4) | ((fg) & 0x0F)))
#endif