/* * palette.h — Sprinter palette (low-level). * * The Sprinter has eight 256-colour palette pages, shared by graphics and * text modes: * * pal_num 0..3 — graphics palettes. Each character cell selects which * of the four it uses through bits 7..6 of its mode byte. * Used by graphics modes 0x81 / 0x82. * pal_num 4..7 — text-mode planes — together they form the colour table * of the text-mode attribute byte: * 4 = paper (background, non-blink phase) * 5 = ink (foreground, non-blink phase) * 6 = paper-blink (background during blink half-cycle) * 7 = ink-blink (foreground during blink half-cycle) * Each plane holds 256 BGR colours indexed directly by * the 8-bit attribute byte of the cell. * * Entry format — 4 bytes per colour, in Blue-Green-Red-pad order; the pad * byte is reserved and must be 0. * * Notes on the underlying BIOS ($A4): * - `count = 0` means 256 entries (full plane). * - On write, data is AND-masked against `pal_mask` before reaching * VRAM. pal_load/pal_set_color hard-code mask = 0xFF (no masking). * * Blink semantics (text planes): * The hardware constantly alternates between planes 4↔6 (paper) and * 5↔7 (ink). To DISABLE blink everywhere in IBM-CGA style, copy plane * 4 → 6 and 5 → 7 (so both phases show the same colour). To ENABLE * ZX-Spectrum style flash, swap entries 6 ↔ 7 for the desired attrs. * The system default (PAL_CGA) leaves flash visible only for attribute * bytes with bit 7 set. * * Backed by BIOS PIC_SET_PAL/PIC_GET_PAL ($A4) and SET_PAL_INIT ($A6). * Higher-level wrappers live in (text_pal_*) and * (gfx_pal_*); use those directly unless you need raw plane control. */ #ifndef PALETTE_H #define PALETTE_H #include /* Default-palette types for pal_reset(). Values match BIOS $A6 B-register. */ #define PAL_GRAPH 1 /* graphics palette (planes 0..3) */ #define PAL_SINCLAIR 2 /* Spectrum palette (text planes 4..7, ZX colours) */ #define PAL_CGA 3 /* CGA text palette (text planes 4..7, IBM CGA) */ /* Load a contiguous block of palette entries. * pal_num: 0..7 (0..3 graphics, 4..7 text) * start: first slot (0..255) * count: number of slots (0 means 256) * bgr0: pointer to count entries of 4 bytes each: Blue, Green, Red, 0 */ void pal_load(uint8_t pal_num, uint8_t start, uint8_t count, const uint8_t *bgr0); /* Read a contiguous block of palette entries back into RAM. * Same parameter shape as pal_load — bgr0 here is a write buffer of * count*4 bytes that receives B,G,R,0 quadruples. */ void pal_get (uint8_t pal_num, uint8_t start, uint8_t count, uint8_t *bgr0); /* Convenience: set one entry from an RGB triple. */ void pal_set_color(uint8_t pal_num, uint8_t slot, uint8_t r, uint8_t g, uint8_t b); /* Convenience: read one entry into R,G,B pointers (any may be NULL). */ void pal_get_color(uint8_t pal_num, uint8_t slot, uint8_t *r, uint8_t *g, uint8_t *b); /* Restore a built-in default palette (BIOS $A6 SET_PAL_INIT). * type: PAL_GRAPH / PAL_SINCLAIR / PAL_CGA. * Internally: * PAL_GRAPH → A=0, E=0, B=1 (resets graphics palette 0) * PAL_SINCLAIR → A=0, E=0, B=2 * PAL_CGA → A=0, E=0, B=3 (resets all text planes 4..7) * * Use pal_reset_at() if you need a non-zero page or a non-zero graphics * palette index. */ void pal_reset(uint8_t type); /* Full-control variant of pal_reset. * pal_page: BIOS A register — "palette page" hardware index. * graph_pal: BIOS E register — for PAL_GRAPH, target palette 0..3. * type: BIOS B register — PAL_GRAPH / PAL_SINCLAIR / PAL_CGA. */ void pal_reset_at(uint8_t type, uint8_t pal_page, uint8_t graph_pal); #endif