/* * 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 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 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 ). */ #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