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>
114 lines
4.2 KiB
C
114 lines
4.2 KiB
C
/*
|
||
* mouse.h — Sprinter mouse driver (RST 30h).
|
||
*
|
||
* The driver is installed in the system shell. After a successful
|
||
* mouse_init(), the driver tracks the hardware and you can query state
|
||
* or move/show/hide the cursor on demand.
|
||
*
|
||
* coordinate units:
|
||
* READ_STATE / GOTO take pixel coordinates. In text mode 03h
|
||
* (80x32) divide x by 8 and y by 8 (NOT 16) to get char-cell
|
||
* position.
|
||
*
|
||
* buttons bitmask:
|
||
* bit 0 = left, bit 1 = right
|
||
*/
|
||
|
||
#ifndef MOUSE_H
|
||
#define MOUSE_H
|
||
|
||
#include <stdint.h>
|
||
|
||
typedef struct {
|
||
uint16_t x; /* pixel coordinate */
|
||
uint16_t y; /* pixel coordinate */
|
||
uint8_t buttons; /* bit 0 = left, bit 1 = right */
|
||
} mouse_state_t;
|
||
|
||
int mouse_init (void); /* 0 OK, -1 if no driver */
|
||
void mouse_show (void);
|
||
void mouse_hide (void);
|
||
void mouse_refresh(void);
|
||
void mouse_read (mouse_state_t *st);
|
||
void mouse_goto (int x, int y);
|
||
void mouse_bounds_x(int xmin, int xmax);
|
||
void mouse_bounds_y(int ymin, int ymax);
|
||
|
||
/* Text-mode cursor shape (function $0A).
|
||
* sym_and / sym_xor — character glyph mask
|
||
* attr_and / attr_xor — attribute byte mask
|
||
* Default cursor is XOR'd inverse video at the cell. */
|
||
void mouse_text_cursor(uint8_t sym_and, uint8_t sym_xor,
|
||
uint8_t attr_and, uint8_t attr_xor);
|
||
|
||
/* ---- Graphics-mode cursor image (functions $09 / $0B) ----------- *
|
||
* The driver accepts an opaque bitmap for the cursor in graphics modes.
|
||
* Doc does not specify the byte layout — empirically size = width*height
|
||
* bytes (1 byte per pixel for 256-colour mode, presumably packed nibbles
|
||
* for 16-colour mode). hot_x / hot_y mark the "click point" within the
|
||
* cursor image (0,0 = top-left).
|
||
*/
|
||
typedef struct {
|
||
const void *image; /* bitmap data */
|
||
uint8_t width;
|
||
uint8_t height;
|
||
uint8_t hot_x;
|
||
uint8_t hot_y;
|
||
} mouse_cursor_t;
|
||
|
||
void mouse_load_cursor(const mouse_cursor_t *c);
|
||
|
||
/* Read back the current cursor.
|
||
* c->image must point to a buffer large enough to hold width*height bytes.
|
||
* width, height, hot_x, hot_y are written by the driver. */
|
||
void mouse_get_cursor(mouse_cursor_t *c);
|
||
|
||
/* ---- Sensitivity (functions $0E / $0F) ------------------------- *
|
||
* Verified empirically (2026-05-31): the value is a DIVIDER — the
|
||
* driver counts that many raw hardware steps from the mouse before
|
||
* advancing the cursor by one screen pixel. So **smaller value = more
|
||
* sensitive** (cursor moves faster), and larger value = slower cursor.
|
||
* (The doc statement "higher = less movement needed" appears to be
|
||
* inverted.) Useful starting point: 2 on both axes. */
|
||
uint8_t mouse_get_sensitivity_x(void);
|
||
uint8_t mouse_get_sensitivity_y(void);
|
||
void mouse_set_sensitivity(uint8_t horz, uint8_t vert);
|
||
|
||
/* ---- Solid-C compatibility ------------------------------------- *
|
||
* Solid-C uses shorter `ms_*` names + typed state structs. The semantics
|
||
* are identical to our `mouse_*` API. */
|
||
|
||
#define LEFT_BUTTON 1
|
||
#define RIGHT_BUTTON 2
|
||
|
||
/* MSGSTAT mirrors mouse_state_t — same field order and types. */
|
||
typedef mouse_state_t MSGSTAT;
|
||
|
||
#define ms_init mouse_init
|
||
#define ms_show mouse_show
|
||
#define ms_hide mouse_hide
|
||
#define ms_ref mouse_refresh
|
||
#define ms_xbnd mouse_bounds_x
|
||
#define ms_ybnd mouse_bounds_y
|
||
#define ms_spos mouse_goto
|
||
#define mssgpos mouse_goto
|
||
#define ms_tcur mouse_text_cursor
|
||
#define ms_scur mouse_load_cursor
|
||
#define ms_gcur mouse_get_cursor
|
||
#define ms_vmod mouse_video_mode_changed
|
||
#define ms_ssen mouse_set_sensitivity
|
||
#define msgstat(st) mouse_read((st))
|
||
|
||
/* ---- $81 CHANGE VIDEO MODE ------------------------------------- *
|
||
* Call after changing the video mode (set_videotextmode or gfx_init) so
|
||
* the driver re-syncs its internal coordinate ranges and cursor image.
|
||
*
|
||
* `mode` is the byte you switched to — TEXT_MODE_* (from <conio.h>) or
|
||
* GFX_MODE_* (from <gfx.h>), e.g. 0x03 for 80×32 text or 0x81 for
|
||
* 320×256×256. The driver REQUIRES the new mode in register A —
|
||
* passing garbage leaves the cursor mis-configured (text-mode XOR
|
||
* pattern applied in graphics, etc.). */
|
||
void mouse_video_mode_changed(uint8_t mode);
|
||
|
||
#endif
|