Having covered sound in the previous post, let’s talk about graphics now.
This is using the Apple II’s low-resolution graphics mode, both because I’m not much of an artist, and this means I can hide that a little better, and because the low-res mode has a number of wonderful callbacks to our earlier explorations of CGA graphics on the IBM PC.
The first is hardware. Look at the colors in use in the screenshot above, and then compare them to the ones we created with chrominance artifacts on the CGA high resolution display:
The colors are very similar. Identical, in fact, though not quite in exactly the same order—the Apple II’s color palette is being generated, at the hardware level, by exactly the technique we deployed in software on the PC.
Meanwhile, on the software side, the technique used for programming is almost exactly the technique we used for the 160x100x16 mode on the PC. Here, however, instead of an 80×100 text display being split into left and right halves, here it is 20 lines of the 40×24 display being split into top and bottom halves. Producing a display is simply a matter of copying a big chunk of data to screen memory. That lets us put the text at the bottom in with the same mechanism, so that’s nice too.
But, sadly, it’s not quite as simple as all that. The Apple II’s screen memory is kind of bonkers.
It starts out much like the Commodore 64’s—memory location 1024 ($0400) is the top left character, and as we advance to the right we find our self at location 1063, 39 spaces over and in the upper right.
The surprise hits at 1064. Instead of being the first character of the second line, it is the first character of the ninth line. Forty more characters down, at 1104, we find ourself at line seventeen. But what of 1144? There are only 24 lines, so one might think that this takes us back to the top for line 2.
It doesn’t. The first character of line 2 is at location 1152 ($0480), 128 bytes after the character above it. That’s a nice round number, but it leaves us a screen hole—a run of 8 bytes that aren’t part of the screen display. Poking around old documentation I get the impression that the screen holes are somehow used by I/O devices or extension cards. At any rate, one isn’t supposed to mess with them.
So that’s a little inconvenient, but it’s not too bad. I used a very simple run-length encoding scheme for the image here, and repurposed the “end of input” marker to also mean “skip 8 bytes, and, oh, by the way, you have to run out of input eight times before you’re done.” After that it was like encoding eight 120-byte lines. Not too bad, and a few runs even get to go multi-line as a result. Not many, but some.
I composed the image here by fiddling around in BASIC for a bit until I got the picture the way I wanted it, and then I decided to not worry about the screen holes and just BSAVEd the screen memory out to a file and encoded it offline. I then encoded a little tune to go with one of the playroutines from last time to make a simple program with graphics and sound. Thanks to Nick Montfort, this has actually been tested on proper hardware and it seems to work as advertised.
Source code for the complete program is up on Github, and actually has been for quite awhile now. I’ve just been incredibly slow in actually writing this project up.
But now it has been, so that’s one more little project down. I’ve got something a bit more ambitious in mind for my next project. We’ll see how that goes.