GFX640 — 2D graphics at 640×256×16
GFX640.DLL is an accelerated 2D graphics library for Sprinter in DSS mode
#82 (640×256 pixels, 16 colours). The interface deliberately mirrors
GFX320: the same function numbers 0–35, the same
registers, descriptors, flags, palette and fade. If a program already works
with GFX320, porting it to GFX640 is straightforward — mostly the coordinate
rules change. Coordinates are pixels, colours are 0..15.
The shared rules for loading DLLs and passing arguments are in the libraries overview.
How it differs from GFX320
Section titled “How it differs from GFX320”In mode #82 pixels are packed two per byte: the high nibble is the left
pixel, the low nibble the right one. That drives the main differences:
- Fills, frames and horizontal lines require even X and width. Copy, move
and restore require even source X, destination X and width; scroll requires
even X, width and shift. Violations return
GFX_ERR_ARGUMENTinstead of drawing “almost right”. put_pixel,get_pixel, vertical and sloped lines accept any X — the library does the read-modify-write of the right nibble itself.- A colour above 15 is an argument error.
- A tile here is 32×16 pixels (the same 256 bytes as 16×16 at 256 colours); the screen is a 20×16 tile grid.
For hline and vline the length and flags are packed into a single DE
register: ten bits of length plus four flag bits:
DE = (length & #03FF) | (flags << 10)The C binding does this packing in its wrapper; in assembly the constants
GFX_LENGTH_MASK and GFX_LENGTH_FLAGS_SHIFT from gfx640.inc help.
Transparency
Section titled “Transparency”The hardware key GFX_KEY_FF operates on bytes: a #FF byte skips a whole
pair of colour-15 pixels. For exact per-pixel transparency there are
separate tile entries 36–41 (*_TRANSPARENT): a #F nibble in a #F? or
#?F byte preserves the corresponding background pixel, while a full #FF
is still handled by the hardware. Without the key the same entries draw via
the ordinary accelerated path and colour 15 is opaque.
Example (C, SDCC)
Section titled “Example (C, SDCC)”#include "gfx640.h"
gfx_u8 draw(gfx_u8 handle) { gfx_u8 status;
gfx640_bind(handle); status = gfx640_clear(0, GFX_TARGET_FRONT); if (status) return status;
/* a panel line: even x and width are mandatory */ status = gfx640_hline(16, 80, 288, 15, GFX_TARGET_FRONT); if (status) return status;
/* single pixels can go anywhere, even 639 */ return gfx640_put_pixel(639, 255, 7, GFX_TARGET_FRONT);}The wrapper packs the hline length and flags into the DE word itself and
returns the library status: 0 — success, #10..#17 — GFX_ERR_* codes.
Same as GFX320: the application allocates 16-KB pages (64 tiles per page),
passes the table of physical page numbers to gfx_set_page_table and
addresses tiles by “page + slot”. The packer accepts indexed PNG/BMP images
whose pixel indices are all in 0..15:
python3 gfx640/tools/tilepack.py assets.png build/tiles \ --keyed --transparent-index 0 \ --metatile-width 2 --metatile-height 2With --keyed, every colour-15 pixel becomes transparent — including a
single half of a packed pair, which is exactly what the *_TRANSPARENT
entries handle.
Limitations
Section titled “Limitations”- The application selects video mode
#82; the library never switches it. - Tile operations temporarily map their source into window WIN0 with interrupts disabled — the application’s code and stack must stay out of WIN0.
- The library is not reentrant and must not be called from an interrupt
handler: the ISR only sets a frame flag, while
gfx_swap_buffersandgfx_fade_stepare called from the main loop. - After every operation the library restores the mapped pages and the interrupt state.
Package contents
Section titled “Package contents”| File | Purpose |
|---|---|
GFX640.DLL |
the library |
gfx640.inc |
ABI constants and descriptor offsets for sjasmplus |
bindings/sdcc/gfx640.h, gfx640.lib |
binding for C (SDCC) |
bindings/tpascal/GFX640.INC |
constants and helpers for Turbo Pascal |
tools/tilepack.py |
tile packer for PNG/BMP |
GFX640.EXE |
visual test; applications do not need it |