OXYGENHUB

video: draw 8 bpp bitmap lines without the per-pixel shift and mask 35bd422c9032

At 8 bits a pixel each VRAM byte is one pixel: first_color_pos is 0,
color_fields_max 0 and color_mask $FF, so the general loop's per-pixel
shift, mask and x_add multiply always come to the byte itself. perf on
narvi put that line at 4.6% of the run time drawing on the 320x240x256
bitmap (BASIC's SCREEN $80). An 8 bpp line now takes a loop that reads
the byte; the palette offset is applied as before. Other depths are
unchanged.

Measured with the emulator stepping 600 frames, real-time mode, SDL
dummy drivers, CPU seconds per emulated second, median of 3:

    narvi  busy  1.647 -> 1.579  (61% -> 63% of a real X16)
    narvi  idle  0.698 -> 0.697  (100%, no bitmap)
    x86    busy  0.454 -> 0.408

The determinism check (two of its workloads draw on the 8 bpp bitmap)
matches on x86 and riscv64.
Author
Andy McCall @andymccall <[email protected]>
via
agent agent:claude@andymccall <[email protected]> · keyless, under your grant for changes,refs,seal · key 7f1108192b02
When
· 2026-10-21 02:50 UTC
Signature
◈ sealed by agent:claude@andymccall
Hash
35bd422c903281cc261aa568b0d6fc798d6257121c49444ae49b760750922384
Depends on
03a3459e6372 39d98c9da02a
Depended on by
nothing yet
In bookmarks
main riscv-1
Edits
1 atom, 0 tree operations, 1 file

Browse the tree at this change

modified src/video.c +14 −0
…
988 unchanged lines
989 989
	// Render tile line.
990 990
	// xx is x % tilew, counted up and wrapped rather than divided per pixel.
991 991
	int xx = 0;
992 +
	if (props->bits_per_pixel == 8) {
993 +
		// A byte a pixel: the loop below with its shift of 0 and mask of $FF.
994 +
		for (int x = 0; x < SCREEN_WIDTH; x++, xx = xx + 1 == props->tilew ? 0 : xx + 1) {
995 +
			uint8_t col_index = video_space_read(props->tile_base + y_add + xx);
996 +
			if (col_index > 0 && col_index < 16) {
997 +
				col_index += palette_offset << 4;
998 +
				if (props->text_mode_256c) {
999 +
					col_index |= 0x80;
1000 +
				}
1001 +
			}
1002 +
			layer_line[layer][x] = col_index;
1003 +
		}
1004 +
		return;
1005 +
	}
992 1006
	for (int x = 0; x < SCREEN_WIDTH; x++, xx = xx + 1 == props->tilew ? 0 : xx + 1) {
993 1007
		// additional bytes to reach the correct column of the tile
994 1008
		uint16_t x_add = (xx * props->bits_per_pixel) >> 3;
…
1467 unchanged lines