Okay, so what happened last time? Ah, yes I remember, I was going to explain $D018 does, wasn't I? Okay, well while I'm here I might as well explain some of the rest of the video chip at the same time. First off, there are some conventions that we'll use use here, the bits of a byte are referred to as 0 for the lowest bit through to 7 for the highest.
Okay, so as promised lets start with $D018, which is a pointer to where the screen and character set are stored. And before I go on, a little lesson in architecture is needed. The C64 has, as we know, 64K of memory but the VIC-II chip isn't able to use it all at once, instead it uses one of four "banks" of 16K, bank 0 is the lowest, from the start of memory to $3FFF (and the default, so for now we will keep working in it) whilst bank 3 is the last, at $C000 to $FFFF.
A C64 character set contains 256 characters, so with eight bytes per character thats a total of 2K needed and it's possible to point at any 2K block in the present bank. Bits 1, 2 and 3 of $D018 control this, allowing the VIC-II to see any one of the eight possible starting points for the character data and setting the bits to $0 will put the character set at $0000, using $2 will mean the font is at $0800 all the way up (in steps of two) until we get to $E, which means $3800 has the font data.
Similarly, the C64 needs 1K for a screen and bits 4 to 7 of $D018 are used to represent where the screen is living. Since there are sixteen possible screens in each bankading from, $0 will put it down at $0000 and $F locates it at $3C00. The actual default for $D018 is $14, the upper four bits are set to $1 so the screen is at $0400 and the lower four are $4 so the fifth character set in is used, at $1000. The reason the C64 defaults like this is because a "shadow" copy of the ROM character set is stored at $1000 with the lower case version at $1800.
A quick definition of shadowing is in order, I think. The C64 only has 64K of RAM but the ROM takes another 32K. Because the 6510 can't access more than 64K at any one time (it can only look at $0000 to $FFFF) the ROM has to exist within that space. But that would take up valuable memory from programs. So the ROMs are all shadowed over other memory, the BASIC ROM is at $A000 to $C000 and if you try reading through that memory with the PEEK command you'll be able to see it. But it's *also* possible to store data under that memory, for example graphics, and not have the ROM overwrite it and if we point the VIC-II chip at it we don't see the ROM data, just our graphics.
This means that we get all the ROMs we need and *still* have the space they occupy in the RAM, they're there but in an insubstantial way, hence the name ROM shadow. The character set at $1000 works the other way around, if we point the VIC-II at it we only see the ROM font, no matter what data we put there. But we can happily put data into that RAM, read it out or run program code from there without that font affecting what we're doing (in fact, $1000 is a very commonly used area of memory for music routines for this reason, a convenient 4K block for two fonts that can't be used for graphics).
Another useful location is $D011 and it has a number of uses, bits 0, 1 and 2 are used to set the vertical smooth scrolling and bit 3 controls the scroll masks, when this bit *isn't* set, the border extends into the screen area slightly and masks hides the edges of the screen so that the new data coming on can't be seen until it's ready. Bit 4 controls the screen, if it's set the screen is on, otherwise the border covers it. Turning the screen off may seem a little pointless, but there are purposes, for example hiding the screen until the graphics have been set up.
Bit 5 of $D011 will activate bitmap screen mode if set, instead of the normal 256 character set the VIC chip takes a block of 8,000 bytes, 8 for each character square of the screen, so really it's just like having a *very* large character set. Bitmap mode has a few disadvantages over normal screen modes, it's memory consuming (a bitmapped picture such as a loading screen needs 10,000 bytes of memory all told when the colour is added) and it's difficult to scroll. Not impossible, just difficult. The *advantage* of bitmaps are that they have more colours available to them. I will be covering the basics of bitmaps in more detail a little further on.
$D016 has been covered before, we used it in the Ferris demo to scroll the message across the screen and smooth scrolling is the job of bits 0 to 2, along with bit 3 which controls the masks at the sides of the screen in the same way as $D011. Bit 4 is used to set multicolour mode, one of those little quirks of the C64's video system. When multicolour mode is on the pixels don't just appear as they are stored, instead the bits are grouped together in twos horizontally and the 2 bit number they produce represents one of four colours. This reduces the horizontal resolution of the screen by half because each character is now only four pixels wide (physically they don't change size, but the pixels are now twice as wide) but we do have more colour control.
The character colour, in locations $D800 onwards, is used to control multicolour mode and, as we have done before, when we set it normally we have sixteen colours, values $00 to $0F. But multicolour mode allows us to mix standard characters and multicolour ones because the first eight colours (black, white, red, cyan, purple, green, dark blue and yellow, values $00 to $07) will produce their normal eight pixel wide characters but using colours $08 to $0F produces those eight colours again, but in multicolour mode. So where does the colour information for our two new colours come from? $D022 and $D023 are the multicolour registers. They function just like $D021 (the background colour) but only affect multicolour areas on characters using colours $08 to $0F. Our four possible colours therefore come from the character colour, $D021 for the background colour and the two multicolours, giving four in total.
Bitmaps (and I said I'd get back to them, didn't I?) work a little differently. When we use bitmap mode, the screen becomes the colour information for the bitmap. So, if we set $D011 to $3B to switch bitmap mode on and $D018 to $18, we now have 1,000 "characters" on the screen, each with it's own individual colours. The lower four bits of the screen (in this example at $0400) represent one of the colours and the upper four a second, $00 will set both to black and $FF will make them light grey for example. But the most interesting use for bitmaps is with multicolour on, so we set $D016 to $18 and now we have lots of colours.
Why? Well, at $0400 to $07E7 we have 1,000 bytes of colour information, two colours per character. But in multicolour bitmap mode we *also* have the $D800 colour map, as used by the screen normally to give us a third colour and the background for our forth. And the $D800 colours are not limited to the first seven as with multicolour characters, they can be any colour from $00 to $0F. The only drawback to having this much colour (three colours per character square) is that there are some 10,000 bytes of data required, 8,000 for the bitmap itself and 2,000 over two areas for the colour data, so moving it around is a no-no without some trickery which we will have to leave for a while yet.
Right, well thats the theory over with and indeed the article, but next time I'll be performing a more practical demonstration of how bitmaps work with some example code and a picture to play with. In the meantime, a small challenge regarding $D018, can you work out what the values would be to put the screen at $3400 and the character data at $2800? Work it out on paper then check yourself against the start of the next part and if you have any questions, suggestions or whatever about this or C64 code in general, contact me.