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 |