c71e249a4e
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>
155 lines
6.2 KiB
C
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
|