diff --git a/frontend/src/__tests__/chipbus-galaksija-computer.test.ts b/frontend/src/__tests__/chipbus-galaksija-computer.test.ts index 8ac4fdf5..41616f86 100644 --- a/frontend/src/__tests__/chipbus-galaksija-computer.test.ts +++ b/frontend/src/__tests__/chipbus-galaksija-computer.test.ts @@ -77,9 +77,9 @@ describe.skipIf(!have)('chipbus Phase 3 — full Galaksija computer renders READ expect(fb, 'display produced a framebuffer').not.toBeNull(); // "READY" lives at video offset 2 (0x2802) -> row 0, cols 2..6. Count lit - // pixels across those five character cells (x 16..55, y 0..7). + // pixels (bright-green G channel) across those five character cells. let litReady = 0; - for (let y = 0; y < 8; y++) for (let x = 16; x < 56; x++) if (fb![(y * 256 + x) * 4] === 0xff) litReady++; + for (let y = 0; y < 8; y++) for (let x = 16; x < 56; x++) if (fb![(y * 256 + x) * 4 + 1] > 0x80) litReady++; expect(litReady, 'the READY prompt is rendered on screen').toBeGreaterThan(20); z80.dispose(); rom.dispose(); ram.dispose(); inv.dispose(); disp.dispose(); diff --git a/frontend/src/__tests__/chipbus-galaksija-display.test.ts b/frontend/src/__tests__/chipbus-galaksija-display.test.ts index 86833c24..563bca86 100644 --- a/frontend/src/__tests__/chipbus-galaksija-display.test.ts +++ b/frontend/src/__tests__/chipbus-galaksija-display.test.ts @@ -51,18 +51,15 @@ describe.skipIf(!have)('chipbus Phase 3 — Galaksija display renders a characte pm.triggerPinChange(WR, true); // rising edge -> latch + render expect(fb, 'framebuffer produced').not.toBeNull(); - // Cell (col 2, row 0) spans x 16..23, y 0..7. Count lit (white) pixels there. - let lit = 0; - for (let y = 0; y < 8; y++) { - for (let x = 16; x < 24; x++) { - const o = (y * 256 + x) * 4; - if (fb![o] === 0xff) lit++; - } - } - expect(lit, 'the R glyph lit some pixels in its cell').toBeGreaterThan(3); + // A lit pixel is bright green (G channel high); background is dark green. + const lit = (x: number, y: number) => fb![(y * 256 + x) * 4 + 1] > 0x80; + // Cell (col 2, row 0) spans x 16..23, y 0..7. Count lit pixels there. + let litCount = 0; + for (let y = 0; y < 8; y++) for (let x = 16; x < 24; x++) if (lit(x, y)) litCount++; + expect(litCount, 'the R glyph lit some pixels in its cell').toBeGreaterThan(3); // A blank cell elsewhere (col 0) stays dark. let litBlank = 0; - for (let y = 0; y < 8; y++) for (let x = 0; x < 8; x++) if (fb![(y * 256 + x) * 4] === 0xff) litBlank++; + for (let y = 0; y < 8; y++) for (let x = 0; x < 8; x++) if (lit(x, y)) litBlank++; expect(litBlank, 'an unwritten cell stays blank').toBe(0); disp.dispose(); diff --git a/frontend/src/__tests__/fixtures/chipbus/galaksija-display.wasm b/frontend/src/__tests__/fixtures/chipbus/galaksija-display.wasm index b3020065..94b81843 100644 Binary files a/frontend/src/__tests__/fixtures/chipbus/galaksija-display.wasm and b/frontend/src/__tests__/fixtures/chipbus/galaksija-display.wasm differ diff --git a/test/test_custom_chips/sdk/examples/galaksija-display.c b/test/test_custom_chips/sdk/examples/galaksija-display.c index 9855bebf..d538e3e9 100644 --- a/test/test_custom_chips/sdk/examples/galaksija-display.c +++ b/test/test_custom_chips/sdk/examples/galaksija-display.c @@ -1,202 +1,102 @@ /* - * galaksija-display — Galaksija (1983) 32x16 text video, rendered from its - * memory-mapped video RAM. Phase 3 of the multi-chip bus track - * (project/multichip-bus/). Public-domain character generator (CHRGEN) by the - * Galaksija project. The chip is a passive BUS SNOOP: it watches WR + the - * address + data bus and, on a write into the 0x2800-0x2BFF video region, - * stores the character and renders that cell into its framebuffer using CHRGEN. - * It never drives the bus. The framebuffer (256x128 = 32x16 chars of 8x8) is - * blitted to the chip canvas by the host (vx_framebuffer_init / vx_buffer_write). + * galaksija-display - Galaksija (1983) 32x16 text video rendered from its + * memory-mapped video RAM (Phase 3, project/multichip-bus/). Passive BUS SNOOP: + * watches WR + address + data; on a write into 0x2800-0x2BFF it renders the + * character into a 256x128 framebuffer. Never drives the bus. * - * CHRGEN: 256 chars x 8 rows, 1 byte per row, bit = 0 -> lit pixel (inverted). + * Galaksija stores ASCII codes in video RAM (the monitor writes READY as + * 0x52,0x45,...). Rendered with the public-domain IBM/VGA 8x8 font (font8x8 by + * Daniel Hepper / Marcel Sondaar) for legible text. font8x8: 1 byte/row, bit 0 + * (LSB) = leftmost pixel, 1 = lit. Green-on-black phosphor look. */ #include "velxio-chip.h" #include #include - #define COLS 32 #define ROWS 16 -#define CW 8 -#define CH 8 -#define FB_W (COLS*CW) -#define FB_H (ROWS*CH) - -static const uint8_t chrgen[2048] = { - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xaf,0xbf,0xaf,0xaf,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xf1,0x1f,0x11,0xff,0xf1,0x1f,0x11,0xff,0xf1,0x1f,0x11,0xff,0xf1,0x1f,0x11, - 0xff,0xf1,0x1f,0x11,0xff,0xf1,0x1f,0x11,0xff,0xf1,0x1f,0x11,0xff,0xf1,0x1f,0x11, - 0xff,0xf1,0x1f,0x11,0xff,0xf1,0x1f,0x11,0xff,0xf1,0x1f,0x11,0xff,0xf1,0x1f,0x11, - 0xff,0xf1,0x1f,0x11,0xff,0xf1,0x1f,0x11,0xff,0xf1,0x1f,0x11,0xff,0xf1,0x1f,0x11, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0xdf,0xdf,0xdf,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xf1,0x1f,0x11,0xff,0xf1,0x1f,0x11,0xff,0xf1,0x1f,0x11,0xff,0xf1,0x1f,0x11, - 0xff,0xf1,0x1f,0x11,0xff,0xf1,0x1f,0x11,0xff,0xf1,0x1f,0x11,0xff,0xf1,0x1f,0x11, - 0xff,0xf1,0x1f,0x11,0xff,0xf1,0x1f,0x11,0xff,0xf1,0x1f,0x11,0xff,0xf1,0x1f,0x11, - 0xff,0xf1,0x1f,0x11,0xff,0xf1,0x1f,0x11,0xff,0xf1,0x1f,0x11,0xff,0xf1,0x1f,0x11, - 0x03,0xcf,0x83,0x87,0x83,0x03,0x03,0x87,0x7b,0xc7,0x03,0x7b,0xfb,0x7b,0x7b,0x87, - 0x83,0x87,0x83,0x87,0x03,0x7b,0x7b,0x7b,0x7b,0x7b,0x03,0x87,0x87,0x03,0x87,0xff, - 0xff,0xef,0xd7,0xb7,0xdf,0xff,0xe7,0xf8,0xdf,0xef,0xff,0xff,0xff,0xff,0xff,0xbf, - 0x87,0xdf,0x87,0x87,0xbf,0x03,0x87,0x03,0x87,0x87,0xff,0xff,0xff,0xff,0xff,0x87, - 0xff,0xf1,0x1f,0x11,0xff,0xf1,0x1f,0x11,0xff,0xf1,0x1f,0x11,0xff,0xf1,0x1f,0x11, - 0xff,0xf1,0x1f,0x11,0xff,0xf1,0x1f,0x11,0xff,0xf1,0x1f,0x11,0xff,0xf1,0x1f,0x11, - 0xff,0xf1,0x1f,0x11,0xff,0xf1,0x1f,0x11,0xff,0xf1,0x1f,0x11,0xff,0xf1,0x1f,0x11, - 0xff,0xf1,0x1f,0x11,0xff,0xf1,0x1f,0x11,0xff,0xf1,0x1f,0x11,0xff,0xf1,0x1f,0x11, - 0xfb,0xb7,0x77,0x7b,0x77,0xfb,0xfb,0x7b,0x7b,0xef,0x7f,0xbb,0xfb,0x33,0x7b,0x7b, - 0x7b,0x7b,0x7b,0x7b,0xef,0x7b,0x7b,0x7b,0x7b,0x7b,0x7f,0x7b,0x7b,0x7f,0x7b,0xff, - 0xff,0xef,0xd7,0xb7,0x07,0x73,0xdb,0xfb,0xef,0xdf,0xef,0xef,0xff,0xff,0xff,0xbf, - 0x7b,0xcf,0x7b,0x7b,0x9f,0xfb,0x7b,0x7b,0x7b,0x7b,0xe7,0xe7,0xbf,0xff,0xf7,0x7b, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xbb,0x7b,0x77,0xfb,0x77,0xfb,0xfb,0xfb,0x7b,0xef,0x7f,0xdb,0xfb,0x33,0x7b,0x7b, - 0x7b,0x7b,0x7b,0xfb,0xef,0x7b,0x7b,0x7b,0x7b,0x7b,0xbf,0xfb,0xfb,0xbf,0xfb,0xff, - 0xff,0xef,0xd7,0xb7,0xdb,0x73,0xdb,0xfb,0xf7,0xbf,0xab,0xef,0xff,0xff,0xff,0xdf, - 0x7b,0xdf,0x7f,0x7f,0xaf,0xfb,0xfb,0x7f,0x7b,0x7b,0xe7,0xe7,0xdf,0xff,0xef,0x7b, - 0xff,0xff,0xff,0xff,0xf1,0xf1,0xf1,0xf1,0x1f,0x1f,0x1f,0x1f,0x11,0x11,0x11,0x11, - 0xff,0xff,0xff,0xff,0xf1,0xf1,0xf1,0xf1,0x1f,0x1f,0x1f,0x1f,0x11,0x11,0x11,0x11, - 0xff,0xff,0xff,0xff,0xf1,0xf1,0xf1,0xf1,0x1f,0x1f,0x1f,0x1f,0x11,0x11,0x11,0x11, - 0xff,0xff,0xff,0xff,0xf1,0xf1,0xf1,0xf1,0x1f,0x1f,0x1f,0x1f,0x11,0x11,0x11,0x11, - 0xfb,0x7b,0x77,0xfb,0x77,0xfb,0xfb,0xfb,0x7b,0xef,0x7f,0xeb,0xfb,0x4b,0x7b,0x7b, - 0x7b,0x7b,0x7b,0xfb,0xef,0x7b,0xb7,0x7b,0xb7,0x7b,0xdf,0xfb,0xfb,0xdf,0xfb,0xff, - 0xff,0xef,0xff,0x03,0xdb,0xbf,0xeb,0xfb,0xf7,0xbf,0xc7,0xef,0xff,0xff,0xff,0xdf, - 0x3b,0xdf,0x7f,0x7f,0xb7,0x83,0x83,0xbf,0x7b,0x7b,0xff,0xff,0xef,0x03,0xdf,0x7f, - 0xff,0xff,0xff,0xff,0xf1,0xf1,0xf1,0xf1,0x1f,0x1f,0x1f,0x1f,0x11,0x11,0x11,0x11, - 0xff,0xff,0xff,0xff,0xf1,0xf1,0xf1,0xf1,0x1f,0x1f,0x1f,0x1f,0x11,0x11,0x11,0x11, - 0xff,0xff,0xff,0xff,0xf1,0xf1,0xf1,0xf1,0x1f,0x1f,0x1f,0x1f,0x11,0x11,0x11,0x11, - 0xff,0xff,0xff,0xff,0xf1,0xf1,0xf1,0xf1,0x1f,0x1f,0x1f,0x1f,0x11,0x11,0x11,0x11, - 0xeb,0x7b,0x87,0xfb,0x77,0x83,0x83,0x1b,0x03,0xef,0x7f,0xf3,0xfb,0x4b,0x73,0x7b, - 0x83,0x7b,0x83,0x87,0xef,0x7b,0xb7,0x7b,0xcf,0x07,0xef,0xfb,0xfb,0xef,0x87,0xff, - 0xff,0xef,0xff,0xb7,0x87,0xdf,0xf7,0xfb,0xf7,0xbf,0x83,0x83,0xff,0x03,0xff,0xef, - 0x5b,0xdf,0xbf,0x9f,0xbb,0x7f,0x7b,0xdf,0x87,0x7b,0xff,0xff,0xf7,0xff,0xbf,0x9f, - 0xff,0xff,0xff,0xff,0xf1,0xf1,0xf1,0xf1,0x1f,0x1f,0x1f,0x1f,0x11,0x11,0x11,0x11, - 0xff,0xff,0xff,0xff,0xf1,0xf1,0xf1,0xf1,0x1f,0x1f,0x1f,0x1f,0x11,0x11,0x11,0x11, - 0xff,0xff,0xff,0xff,0xf1,0xf1,0xf1,0xf1,0x1f,0x1f,0x1f,0x1f,0x11,0x11,0x11,0x11, - 0xff,0xff,0xff,0xff,0xf1,0xf1,0xf1,0xf1,0x1f,0x1f,0x1f,0x1f,0x11,0x11,0x11,0x11, - 0xfb,0x03,0x77,0xfb,0x77,0xfb,0xfb,0x7b,0x7b,0xef,0x7f,0xeb,0xfb,0x7b,0x6b,0x7b, - 0xfb,0x7b,0xeb,0x7f,0xef,0x7b,0xb7,0x4b,0xcf,0x7f,0xf7,0xfb,0xfb,0xf7,0x7f,0xff, - 0xff,0xef,0xff,0xb7,0x6f,0xef,0xeb,0xfb,0xf7,0xbf,0xc7,0xef,0xff,0xff,0xff,0xef, - 0x6b,0xdf,0xc7,0x7f,0xbb,0x7f,0x7b,0xef,0x7b,0x07,0xff,0xff,0xef,0x03,0xdf,0xef, - 0xff,0xff,0xff,0xff,0xf1,0xf1,0xf1,0xf1,0x1f,0x1f,0x1f,0x1f,0x11,0x11,0x11,0x11, - 0xff,0xff,0xff,0xff,0xf1,0xf1,0xf1,0xf1,0x1f,0x1f,0x1f,0x1f,0x11,0x11,0x11,0x11, - 0xff,0xff,0xff,0xff,0xf1,0xf1,0xf1,0xf1,0x1f,0x1f,0x1f,0x1f,0x11,0x11,0x11,0x11, - 0xff,0xff,0xff,0xff,0xf1,0xf1,0xf1,0xf1,0x1f,0x1f,0x1f,0x1f,0x11,0x11,0x11,0x11, - 0xab,0x7b,0x77,0xfb,0x77,0xfb,0xfb,0x7b,0x7b,0xef,0x7b,0xdb,0xfb,0x7b,0x5b,0x7b, - 0xfb,0x5b,0xdb,0x7f,0xef,0x7b,0xcf,0x4b,0xb7,0x7f,0xfb,0xfb,0xfb,0xfb,0x7f,0xff, - 0xff,0xef,0xff,0x03,0x6f,0xf7,0x5b,0xfa,0xf7,0xbf,0xab,0xef,0xe7,0xff,0xff,0xf7, - 0x73,0xdf,0xfb,0x7f,0x03,0x7f,0x7b,0xf7,0x7b,0x7f,0xe7,0xe7,0xdf,0xff,0xef,0xef, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xfb,0x7b,0x77,0x7b,0x77,0xfb,0xfb,0x7b,0x7b,0xef,0x7b,0xbb,0xfb,0x7b,0x3b,0x7b, - 0xfb,0xbb,0xbb,0x7b,0xef,0x7b,0xcf,0x33,0x7b,0x7b,0xfb,0x7b,0x7b,0xfb,0x7b,0xff, - 0xff,0xff,0xff,0xb7,0x83,0x3b,0xbb,0xfb,0xef,0xdf,0xef,0xef,0xe7,0xff,0xe7,0xf7, - 0x7b,0xdf,0xfb,0x7b,0xbf,0x7b,0x7b,0xf7,0x7b,0x7b,0xe7,0xe7,0xbf,0xff,0xf7,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1, - 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, - 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, - 0x03,0x7b,0x83,0x87,0x83,0x03,0xfb,0x07,0x7b,0xc7,0x87,0x7b,0x03,0x7b,0x7b,0x87, - 0xfb,0x47,0x7b,0x87,0xef,0x87,0xcf,0x7b,0x7b,0x87,0x03,0x87,0x87,0x03,0x87,0x03, - 0xff,0xef,0xff,0xb7,0xef,0x3b,0x47,0xf8,0xdf,0xef,0xff,0xff,0xef,0xff,0xe7,0xfb, - 0x87,0x8f,0x03,0x87,0xbf,0x87,0x87,0xf7,0x87,0x87,0xff,0xef,0xff,0xff,0xff,0xef, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1, - 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, - 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7,0xff,0xff,0xfb, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1, - 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, - 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1, - 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, - 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +#define FB_W (COLS*8) +#define FB_H (ROWS*8) +static const uint8_t font8x8[1024] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x3c,0x3c,0x18,0x18,0x00,0x18,0x00, + 0x36,0x36,0x00,0x00,0x00,0x00,0x00,0x00,0x36,0x36,0x7f,0x36,0x7f,0x36,0x36,0x00, + 0x0c,0x3e,0x03,0x1e,0x30,0x1f,0x0c,0x00,0x00,0x63,0x33,0x18,0x0c,0x66,0x63,0x00, + 0x1c,0x36,0x1c,0x6e,0x3b,0x33,0x6e,0x00,0x06,0x06,0x03,0x00,0x00,0x00,0x00,0x00, + 0x18,0x0c,0x06,0x06,0x06,0x0c,0x18,0x00,0x06,0x0c,0x18,0x18,0x18,0x0c,0x06,0x00, + 0x00,0x66,0x3c,0xff,0x3c,0x66,0x00,0x00,0x00,0x0c,0x0c,0x3f,0x0c,0x0c,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x0c,0x0c,0x06,0x00,0x00,0x00,0x3f,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x0c,0x0c,0x00,0x60,0x30,0x18,0x0c,0x06,0x03,0x01,0x00, + 0x3e,0x63,0x73,0x7b,0x6f,0x67,0x3e,0x00,0x0c,0x0e,0x0c,0x0c,0x0c,0x0c,0x3f,0x00, + 0x1e,0x33,0x30,0x1c,0x06,0x33,0x3f,0x00,0x1e,0x33,0x30,0x1c,0x30,0x33,0x1e,0x00, + 0x38,0x3c,0x36,0x33,0x7f,0x30,0x78,0x00,0x3f,0x03,0x1f,0x30,0x30,0x33,0x1e,0x00, + 0x1c,0x06,0x03,0x1f,0x33,0x33,0x1e,0x00,0x3f,0x33,0x30,0x18,0x0c,0x0c,0x0c,0x00, + 0x1e,0x33,0x33,0x1e,0x33,0x33,0x1e,0x00,0x1e,0x33,0x33,0x3e,0x30,0x18,0x0e,0x00, + 0x00,0x0c,0x0c,0x00,0x00,0x0c,0x0c,0x00,0x00,0x0c,0x0c,0x00,0x00,0x0c,0x0c,0x06, + 0x18,0x0c,0x06,0x03,0x06,0x0c,0x18,0x00,0x00,0x00,0x3f,0x00,0x00,0x3f,0x00,0x00, + 0x06,0x0c,0x18,0x30,0x18,0x0c,0x06,0x00,0x1e,0x33,0x30,0x18,0x0c,0x00,0x0c,0x00, + 0x3e,0x63,0x7b,0x7b,0x7b,0x03,0x1e,0x00,0x0c,0x1e,0x33,0x33,0x3f,0x33,0x33,0x00, + 0x3f,0x66,0x66,0x3e,0x66,0x66,0x3f,0x00,0x3c,0x66,0x03,0x03,0x03,0x66,0x3c,0x00, + 0x1f,0x36,0x66,0x66,0x66,0x36,0x1f,0x00,0x7f,0x46,0x16,0x1e,0x16,0x46,0x7f,0x00, + 0x7f,0x46,0x16,0x1e,0x16,0x06,0x0f,0x00,0x3c,0x66,0x03,0x03,0x73,0x66,0x7c,0x00, + 0x33,0x33,0x33,0x3f,0x33,0x33,0x33,0x00,0x1e,0x0c,0x0c,0x0c,0x0c,0x0c,0x1e,0x00, + 0x78,0x30,0x30,0x30,0x33,0x33,0x1e,0x00,0x67,0x66,0x36,0x1e,0x36,0x66,0x67,0x00, + 0x0f,0x06,0x06,0x06,0x46,0x66,0x7f,0x00,0x63,0x77,0x7f,0x7f,0x6b,0x63,0x63,0x00, + 0x63,0x67,0x6f,0x7b,0x73,0x63,0x63,0x00,0x1c,0x36,0x63,0x63,0x63,0x36,0x1c,0x00, + 0x3f,0x66,0x66,0x3e,0x06,0x06,0x0f,0x00,0x1e,0x33,0x33,0x33,0x3b,0x1e,0x38,0x00, + 0x3f,0x66,0x66,0x3e,0x36,0x66,0x67,0x00,0x1e,0x33,0x07,0x0e,0x38,0x33,0x1e,0x00, + 0x3f,0x2d,0x0c,0x0c,0x0c,0x0c,0x1e,0x00,0x33,0x33,0x33,0x33,0x33,0x33,0x3f,0x00, + 0x33,0x33,0x33,0x33,0x33,0x1e,0x0c,0x00,0x63,0x63,0x63,0x6b,0x7f,0x77,0x63,0x00, + 0x63,0x63,0x36,0x1c,0x1c,0x36,0x63,0x00,0x33,0x33,0x33,0x1e,0x0c,0x0c,0x1e,0x00, + 0x7f,0x63,0x31,0x18,0x4c,0x66,0x7f,0x00,0x1e,0x06,0x06,0x06,0x06,0x06,0x1e,0x00, + 0x03,0x06,0x0c,0x18,0x30,0x60,0x40,0x00,0x1e,0x18,0x18,0x18,0x18,0x18,0x1e,0x00, + 0x08,0x1c,0x36,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff, + 0x0c,0x0c,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1e,0x30,0x3e,0x33,0x6e,0x00, + 0x07,0x06,0x06,0x3e,0x66,0x66,0x3b,0x00,0x00,0x00,0x1e,0x33,0x03,0x33,0x1e,0x00, + 0x38,0x30,0x30,0x3e,0x33,0x33,0x6e,0x00,0x00,0x00,0x1e,0x33,0x3f,0x03,0x1e,0x00, + 0x1c,0x36,0x06,0x0f,0x06,0x06,0x0f,0x00,0x00,0x00,0x6e,0x33,0x33,0x3e,0x30,0x1f, + 0x07,0x06,0x36,0x6e,0x66,0x66,0x67,0x00,0x0c,0x00,0x0e,0x0c,0x0c,0x0c,0x1e,0x00, + 0x30,0x00,0x30,0x30,0x30,0x33,0x33,0x1e,0x07,0x06,0x66,0x36,0x1e,0x36,0x67,0x00, + 0x0e,0x0c,0x0c,0x0c,0x0c,0x0c,0x1e,0x00,0x00,0x00,0x33,0x7f,0x7f,0x6b,0x63,0x00, + 0x00,0x00,0x1f,0x33,0x33,0x33,0x33,0x00,0x00,0x00,0x1e,0x33,0x33,0x33,0x1e,0x00, + 0x00,0x00,0x3b,0x66,0x66,0x3e,0x06,0x0f,0x00,0x00,0x6e,0x33,0x33,0x3e,0x30,0x78, + 0x00,0x00,0x3b,0x6e,0x66,0x06,0x0f,0x00,0x00,0x00,0x3e,0x03,0x1e,0x30,0x1f,0x00, + 0x08,0x0c,0x3e,0x0c,0x0c,0x2c,0x18,0x00,0x00,0x00,0x33,0x33,0x33,0x33,0x6e,0x00, + 0x00,0x00,0x33,0x33,0x33,0x1e,0x0c,0x00,0x00,0x00,0x63,0x6b,0x7f,0x7f,0x36,0x00, + 0x00,0x00,0x63,0x36,0x1c,0x36,0x63,0x00,0x00,0x00,0x33,0x33,0x33,0x3e,0x30,0x1f, + 0x00,0x00,0x3f,0x19,0x0c,0x26,0x3f,0x00,0x38,0x0c,0x0c,0x07,0x0c,0x0c,0x38,0x00, + 0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x00,0x07,0x0c,0x0c,0x38,0x0c,0x0c,0x07,0x00, + 0x6e,0x3b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, }; - typedef struct { vx_pin a[14]; vx_pin d[8]; vx_pin wr; int wr_last; vx_buffer fb; } chip_t; static chip_t G; static uint8_t fbpix[FB_W*FB_H*4]; - static uint16_t read_addr(void){ uint16_t v=0; for(int i=0;i<14;i++) if(vx_pin_read(G.a[i])) v|=(1u<=FB_W||y>=FB_H) return; - int o=(y*FB_W+x)*4; uint8_t v=lit?0xFF:0x00; - fbpix[o]=v; fbpix[o+1]=v; fbpix[o+2]=v; fbpix[o+3]=0xFF; -} -static void render_cell(int col,int row,uint8_t ch){ - for(int line=0; line>(7-px))&1) ? 0 : 1; /* 0 bit = lit */ - put_px(col*CW+px, row*CH+line, lit); - } - } - vx_buffer_write(G.fb, 0, fbpix, sizeof(fbpix)); -} - -static void on_wr(void* u, vx_pin p, int value){ - (void)u;(void)p; - /* latch on WR rising edge (data + address valid through the write) */ - if(G.wr_last==0 && value==1){ - uint16_t addr=read_addr(); - /* video region 0x2800-0x2BFF: A13=1,A12=0,A11=1,A10=0 */ - if((addr & 0x3C00) == 0x2800){ - uint16_t off = addr & 0x3FF; /* 0..1023 */ - int row=off/COLS, col=off%COLS; - if(row>px)&1);} vx_buffer_write(G.fb,0,fbpix,sizeof(fbpix)); } +static void on_wr(void* u, vx_pin p, int value){ (void)u;(void)p; if(G.wr_last==0&&value==1){ uint16_t a=read_addr(); if((a&0x3C00)==0x2800){ uint16_t off=a&0x3FF; int row=off/COLS,col=off%COLS; if(row