b851e22fa6
print_hex(uint8_t) was an early bare-metal helper doing exactly what
hex8() in the freshly-ported hex_print.c does (two-digit hex via
putchar()). hex8() is smaller (asm cp/sbc/daa nibble trick, no LUT)
and consistent with the dec8/hex16/dec16/hex32/dec32 family.
• Replaced print_hex() calls with hex8() in examples/banked and
examples/bankedbg.
• Removed libc/stdio/print_hex.c, dropped its prototype from
sprinter.h and its entry from lib/Makefile.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
156 lines
5.6 KiB
C
156 lines
5.6 KiB
C
/*
|
|
* sprinter.h — low-level Sprinter platform definitions for C programs.
|
|
*
|
|
* Numbers and behaviour cross-checked against docs/converted/ (IvanMak.txt,
|
|
* DiskSyscalls.txt, BIOS_v3.txt, ProgrammerManual.txt).
|
|
*/
|
|
|
|
#ifndef SPRINTER_H
|
|
#define SPRINTER_H
|
|
|
|
#include <stdint.h>
|
|
|
|
/* ---- I/O ports ----------------------------------------------------- */
|
|
|
|
/* Memory window page-select ports (write 8-bit physical page number). */
|
|
#define PORT_PAGE_W0 0x82 /* window 0: 0x0000-0x3FFF (ESTEX system) */
|
|
#define PORT_PAGE_W1 0xA2 /* window 1: 0x4000-0x7FFF (HOME) */
|
|
#define PORT_PAGE_W2 0xC2 /* window 2: 0x8000-0xBFFF (stack+heap) */
|
|
#define PORT_PAGE_W3 0xE2 /* window 3: 0xC000-0xFFFF (paged) */
|
|
|
|
/* Graphics ports (used in stage 3+). */
|
|
#define PORT_RGADR 0x89 /* graphic Y / Spectrum-page selector */
|
|
#define PORT_RGMOD 0xC9 /* bit 0 = active screen page 0/1 */
|
|
|
|
/* ---- ESTEX RST 10h function numbers -------------------------------- */
|
|
/* Full list in docs/converted/DiskSyscalls.txt (DSS v1.6). */
|
|
|
|
#define ESTEX_VERSION 0x00
|
|
#define ESTEX_CHDISK 0x01
|
|
#define ESTEX_CURDISK 0x02
|
|
#define ESTEX_DSKINFO 0x03
|
|
|
|
#define ESTEX_CREATE 0x0A
|
|
#define ESTEX_CREATE_NEW 0x0B
|
|
#define ESTEX_DELETE 0x0E
|
|
#define ESTEX_RENAME 0x10
|
|
#define ESTEX_OPEN 0x11
|
|
#define ESTEX_CLOSE 0x12
|
|
#define ESTEX_READ 0x13
|
|
#define ESTEX_WRITE 0x14
|
|
#define ESTEX_MOVE_FP 0x15
|
|
#define ESTEX_ATTRIB 0x16
|
|
#define ESTEX_F_FIRST 0x19
|
|
#define ESTEX_F_NEXT 0x1A
|
|
#define ESTEX_MKDIR 0x1B
|
|
#define ESTEX_RMDIR 0x1C
|
|
#define ESTEX_CHDIR 0x1D
|
|
#define ESTEX_CURDIR 0x1E
|
|
|
|
#define ESTEX_SYSTIME 0x21
|
|
|
|
#define ESTEX_WAITKEY 0x30
|
|
#define ESTEX_SCANKEY 0x31
|
|
#define ESTEX_ECHOKEY 0x32
|
|
#define ESTEX_CTRLKEY 0x33
|
|
|
|
#define ESTEX_SETWIN 0x38
|
|
#define ESTEX_SETWIN1 0x39
|
|
#define ESTEX_SETWIN2 0x3A
|
|
#define ESTEX_SETWIN3 0x3B
|
|
#define ESTEX_INFOMEM 0x3C
|
|
#define ESTEX_GETMEM 0x3D
|
|
#define ESTEX_FREEMEM 0x3E
|
|
#define ESTEX_SETMEM 0x3F
|
|
|
|
#define ESTEX_EXEC 0x40
|
|
#define ESTEX_EXIT 0x41
|
|
#define ESTEX_WAIT 0x42
|
|
|
|
#define ESTEX_ENV 0x46 /* env API: B=0 sysenv, B=1 getenv, B=2 putenv */
|
|
|
|
#define ESTEX_SETVMOD 0x50
|
|
#define ESTEX_GETVMOD 0x51
|
|
#define ESTEX_LOCATE 0x52
|
|
#define ESTEX_CURSOR 0x53
|
|
#define ESTEX_SELPAGE 0x54
|
|
#define ESTEX_SCROLL 0x55
|
|
#define ESTEX_CLEAR 0x56
|
|
#define ESTEX_RDCHAR 0x57
|
|
#define ESTEX_WRCHAR 0x58
|
|
#define ESTEX_WINCOPY 0x59
|
|
#define ESTEX_WINREST 0x5A
|
|
#define ESTEX_PUTCHAR 0x5B
|
|
#define ESTEX_PCHARS 0x5C
|
|
#define ESTEX_PRINT 0x5F
|
|
|
|
/* ---- BIOS RST 8 function numbers ----------------------------------- */
|
|
/* Full list in docs/converted/BIOS_v3.txt (BIOS v3.00). */
|
|
|
|
#define BIOS_EMM_INFO 0xC0 /* HL=total pages, BC=free pages */
|
|
#define BIOS_EMM_INIT 0xC1
|
|
#define BIOS_EMM_ALLOC 0xC2 /* B=npages -> A=blk_id */
|
|
#define BIOS_EMM_FREE 0xC3 /* A=blk_id */
|
|
#define BIOS_EMM_GETPAGE 0xC4 /* A=blk_id, B=log -> A=physical */
|
|
#define BIOS_EMM_LIST 0xC5
|
|
#define BIOS_EMM_PORT_FOR 0xC6 /* A=window -> C=port, B=current page */
|
|
#define BIOS_EMM_NEXTPAGE 0xC7
|
|
|
|
/* ---- Inline paging intrinsics -------------------------------------- */
|
|
/*
|
|
* Each generates a single "OUT (port), A" + the load of the literal.
|
|
* Wrap in DI/EI yourself for graphics-grade timing; for one-shot setup
|
|
* the inline form is fine.
|
|
*/
|
|
__sfr __at PORT_PAGE_W0 _io_page_w0;
|
|
__sfr __at PORT_PAGE_W1 _io_page_w1;
|
|
__sfr __at PORT_PAGE_W2 _io_page_w2;
|
|
__sfr __at PORT_PAGE_W3 _io_page_w3;
|
|
|
|
static inline void sprinter_page_w0(uint8_t page) { _io_page_w0 = page; }
|
|
static inline void sprinter_page_w1(uint8_t page) { _io_page_w1 = page; }
|
|
static inline void sprinter_page_w2(uint8_t page) { _io_page_w2 = page; }
|
|
static inline void sprinter_page_w3(uint8_t page) { _io_page_w3 = page; }
|
|
|
|
/* ---- Sprinter-specific debug helpers ------------------------------ */
|
|
/* Use hex8() / hex16() / hex32() from <stdio.h> for hex debug output. */
|
|
|
|
#ifdef DEBUG_RT
|
|
/*
|
|
* Runtime diagnostics — exposed only when the program is built with
|
|
* `sprinter-cc --debug`. The flag below is set by crt0 before main().
|
|
*
|
|
* 0 — crt0 did NOT self-allocate a W2 page (tiny mode never needs to,
|
|
* and in small mode DSS itself maps W2 when the image > 16 KB).
|
|
* 1 — crt0 had to allocate and map a W2 page via ESTEX $3D + $3A
|
|
* (small mode with image ≤ 16 KB).
|
|
*/
|
|
extern uint8_t w2_self_allocated;
|
|
#endif
|
|
|
|
/* ---- Environment (ESTEX $46) -------------------------------------- */
|
|
/*
|
|
* getenv(name) — return pointer to value, or NULL if not set.
|
|
* Returned buffer is ESTEX-owned (shared static);
|
|
* copy if needed before the next getenv() call.
|
|
* putenv("name=value") — add/replace. Pass "name" with no '=' to remove.
|
|
* sysenv(buf) — copy the WHOLE environment into caller's buf,
|
|
* as a series of NUL-terminated "NAME=value"
|
|
* strings followed by an extra NUL marking end:
|
|
* "PATH=...\0SOLID=H\0\0"
|
|
* Caller is responsible for sizing buf large
|
|
* enough for the entire environment.
|
|
*
|
|
* Return values:
|
|
* getenv: pointer to value (NUL-terminated) on success,
|
|
* NULL when the variable is not present (errno unchanged),
|
|
* NULL with errno set on real error.
|
|
* putenv: 0 on success, -1 on error (errno set).
|
|
* sysenv: buf on success, (char*)-1 on error (errno set).
|
|
*/
|
|
char *getenv(const char *name);
|
|
int putenv(const char *namevalue);
|
|
char *sysenv(char *buf);
|
|
|
|
#endif /* SPRINTER_H */
|