Give the screen a bitmap mode

V4. Mode 2 is 320 by 200 with a byte a pixel: no tile to look up and no attribute to add,
the byte IS the palette index. Programs/Examples/picture.asm fills a whole one in 127 bytes
of program and 47,498 cycles.

IT IS THE SAME MEMORY AS THE TILES AND THE MAP, which is what shared video memory has always
been, and there is nowhere else it could be - 64,000 bytes of picture in a 65,536 byte bank
leaves room for nothing beside it. Going to bitmap mode does not clear the text screen, it
stops calling it one, and coming back finds the tiles holding whatever the picture put there.
Taking the screen means taking it.

The palette moves to 0xFC00, the top of video memory, because it is the one thing that has to
mean the same in every mode and 64,000 bytes of picture leaves nowhere in the middle for it
to hide. That is a documented address, so the example, the tests and the manual move with it.

A BITMAP HAS NO COLUMNS AND NO ROWS, and both registers read zero rather than a leftover from
the last mode. The console asks: told there is no character screen, it has nowhere to put a
glyph and draws nothing, while still saying everything down the serial line. The honest
alternative is what a machine with shared video memory really does, which is scribble marks
nobody can read across somebody's picture - honest and useless, since a program that has
taken the screen has not stopped wanting to print.

Six checks in Tests/video.sh, to 55: that the mode is 320 by 200, that a byte is one pixel's
colour and only that pixel, that printing leaves a picture alone while the letter still goes
out, and that the columns register says nought and then forty again.

The example is worth reading for one thing beyond the mode: Fill leaves its destination past
what it touched, so two hundred rows are drawn from one address set once. Working out where
row n begins would be n times 320, and this machine has no multiply.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
This commit is contained in:
Anachronaut
2026-08-29 10:44:15 -04:00
co-authored by Claude Opus 5
parent 1174bd9af5
commit 13b20c8834
10 changed files with 258 additions and 20 deletions
+28 -4
View File
@@ -51,12 +51,30 @@
// Two bytes to a cell: which tile, and how to colour it.
#define VIDEO_CELL_BYTES 2
// ---- A bitmap, over the top of the tiles and the map ----
//
// THE SAME MEMORY MEANING DIFFERENT THINGS IN DIFFERENT MODES, which is what shared video
// memory has always been. There is no room for it to be anywhere else: 320 by 200 at a byte
// a pixel is 64,000 bytes and the whole bank is 65,536, so a bitmap that sat beside the
// tiles rather than on top of them would need a second bank for no reason except tidiness.
//
// What it costs is that the two do not coexist. Going to bitmap mode does not clear the text
// screen; it stops calling it a text screen. Coming back finds the tiles and the map holding
// whatever the picture put there, which is what taking the screen means.
#define VIDEO_BITMAP_BASE 0x0000
#define VIDEO_BITMAP_WIDTH 320
#define VIDEO_BITMAP_HEIGHT 200
// ---- The palette ----
//
// Four bytes an entry rather than three, for the same reason a map row is a page: entry n
// begins at n times four, which is a shift. Three would need a multiply the machine does
// not have. The fourth byte is unused and reads as whatever was put there.
#define VIDEO_PALETTE_BASE 0xC000
//
// At the TOP of video memory, clear of everything else, because it is the one thing that has
// to mean the same in every mode - a bitmap needs colours as much as a tile does, and 64,000
// bytes of picture leaves nowhere in the middle for it to hide.
#define VIDEO_PALETTE_BASE 0xFC00
#define VIDEO_PALETTE_BYTES 4
#define VIDEO_PALETTE_SIZE 256
@@ -65,14 +83,20 @@
// Both are 8x8 cells over the same engine; only how many of them differ. The pixel count
// costs the CPU nothing, because it only ever writes the map - which is why the larger mode
// is affordable at all.
#define VIDEO_MODE_40x25 0
#define VIDEO_MODE_80x50 1
#define VIDEO_MODE_COUNT 2
#define VIDEO_MODE_40x25 0
#define VIDEO_MODE_80x50 1
#define VIDEO_MODE_BITMAP 2
#define VIDEO_MODE_COUNT 3
#define VIDEO_CELL_PIXELS 8
#define VIDEO_MAX_WIDTH (80 * VIDEO_CELL_PIXELS)
#define VIDEO_MAX_HEIGHT (50 * VIDEO_CELL_PIXELS)
// How many characters across and down the screen is, and ZERO IN BITMAP MODE, where there is
// no such thing. The console asks, and a console told there are no columns has nowhere to
// put a glyph and does not try.
int videoTextRows(void);
// ---- Ports ----
//
// Sixteen, like the controller, and it interrupts on its base the way the disk established.