"Doing weird things with computers since 1982"

T.M.R's Workstation
General Stuff

 Home Page
 About T.M.R
 Photo Galleries
 Web Links
 Random Quotes
 Old Web Log

8-Bit Stuff

 Projects
 T.M.R's Dev Blog
 The Scrapyard
 Ye Olde Stuff
 Articles

Other Stuff

 Rendered Images
 PHP Toys

Random Quote

"I came back to life before your eyes. I held back death. Look, I can't make your dream come true forever, but I can make it come true today."

The Doctor 
T.M.R'S WORKSTATION :: C64 SCREEN MODES 

C64 SCREEN MODES

Written by T.M.R of Cosine

i've been asked (perhaps nagged is a better word, it's so nice to be wanted!) to do some "beginner's guides" to the C64. The logical starting point seems to be the VIC-II on the grounds that most demo programmers will be wanting to interact with that chip over everything else barring the CPU.

Generally speaking, graphics can be in either 320*200 mode or 160*200 with a fixed palette of 16 colours. The C64 has four possible screen modes (unless you count turning it off and that's not as useless as it sounds) and they're bitmap and character mode in either mono-colour (sometimes called hi-res) or multi-colour. The C64 divides it's RAM into four 16K blocks and the VIC-II chip can only be looking at one of these banks at any one time.

Character Based Screens
When the machine powers up, it's in bank 0 (the lowest) and set up for mono-colour character mode, which uses a 2K character set stored on one of the ROMs, 1,000 bytes of screen memory (which can be relocated) and 1,000 nybbles of colour memory since the value range is $0 to $f. The colour palette is fixed;

$0 = black
$1 = white
$2 = red
$3 = cyan
$4 = purple
$5 = dark green
$6 = dark blue
$7 = yellow
$8 = orange
$9 = brown
$a = light red (pink)
$b = dark grey
$c = medium grey
$d = light green
$e = light blue
$f = light grey

The first byte of the screen memory and colour memory are both the top left corner and they run sequentially across the screen and then down to the next line. The advantages of this mode may not be immediately clear, but it's one of the major "selling points" of the C64's video hardware.

Why? Because the character set can be repositioned, making all 256 characters redefine-able for the programmers own use. On top of that, with a trivial amount of interrupt timing it's possible to change the character sets on the fly during the screen. Probably the most popular mode for C64 games is character screen with multi-colour turned on because even a full-screen scroll in that mode is a mere 1,000 bytes or 2,000 with colour maps; compared to the Speccy, that's a saving of close to 7,000 bytes for a screen and the C64 can multi buffer the screen RAM (not the colour RAM, sadly).

In mono-colour character mode, the screen is divided into 8*8 pixel blocks, 40 across and 25 down. The character data is stored in blocks of 8 bytes and the eight bits simply represent pixels. The colour map is at the fixed location of $d800 and if a pixel is set the colour comes from there, otherwise it's grabbed from the screen colour at $d021.

There is also Extended Background Colour Mode, the character set is reduced to 64 characters and the upper two bits are used to say which one of four background colour registers are used for the off bits; $d021, $d022 (multi-colour register 1), $d023 (multi-colour 2) and $d024 (multi-colour 3) respectively.

The fun starts when multi-colour mode is fired up; now the bits in the character data work together as pairs and represent values from $0 to $3, the two upshots of which are that it's now possible to represent four colours rather than just two and the pixels become "fatter" in that classic C64 way. The colour data is now controlled by $d021 for the %00 bit combination, $d022 for the %01, $d023 for the %10 and $d800 still handles the fully set pixel, in other words %11. $d024 isn't in use in this mode.

The only quirk to this is that because the colour RAM is only a block of nybbles it can't store a value over $0f so the first 8 colours are used to represent mono-colour mode and the second eight now represent those first colours again but in multi-colour. This means that it's possible to mix modes with no difficulty at all, simply change the value in $d800 for a character cell to enable/disable at will.

Hopefully, i've described the above well enough that most programmers can see how multi-colour character mode works in a game environment; the screen can basically be considered a 40*25 byte tile map with 256 possible tiles which allows for a lot of possibilities. Obviously, these "tiles" can be grouped together to make larger and more substantial blocks, 2*2 characters is reasonable and quite popular, as are 4*4 and the "legendary" Shoot-Em-Up Construction Kit uses 5*5.

So if we want to scroll this lot, we have to move all the definitions around right? Nope, Commodore's designers gave us the smooth scroll registers which can smoothly shift the screen around by a distance of eight pixels either vertically or horizontally. That's not very far compared to what a couple of other 8-bits can do with their hardware but enough that a coarse scroll can be done in software to continue the work. Similarly, if we're using double buffering the back buffer has eight frames to re-draw, making scrolling a full screen without colour a fairly trivial job. Even if in multi-colour mode, the horizontal scroll register still moves at a single mono-colour pixel, so it appears to move half pixels.

What is also nice is that the characters can be redefined on the fly, change the definition in the character set data and all incidents of it on screen update instantly. For example, if the gaps in a game background all contain the same character and it's in mono-colour, simply rolling the bits around in the opposite direction as the smooth scroll is going causes the background to sit still whilst the other data slides over the top of it.

In other words, a simple scroll routine is just a matter of idling for eight frames whilst the horizontal smooth scroll does it's work, then resetting the value, shifting 39 bytes over to the left and adding a new one at the end. Piece of piss.

Bitmap Based Screens
Next up we have bitmap mode. Mono-colour bitmap mode is still 40*25 cells in size and again they're 8*8, however this time there are 8,000 bytes of data for the definitions so each cell can be unique. Due to limitations of positioning, there are only six places in RAM where a full bitmap can be stored for display.

Generally speaking, the VIC-II sees the bitmap data as character definitions, just as a 1,000 character set that you can't reposition, which means that the first byte is eight pixels across from the top left, the next seven are stored below that and the ninth byte of data is back at the top line and 8 pixels in at the start of the second cell. The second character line of the screen starts 320 bytes in, the third is 640 and so on.

Mono-colour bitmap is unusual in that it's the only mode the C64 has which doesn't use the $d800 colour map or $d021 background colour. Instead a screen map is used with each byte supplying two nybbles of colour to an 8*8 attribute cell. Off bits in the bitmap data use the high nybble of the byte and on bits the low nybble (yes, it's backwards!) so if the screen map contains $20 the off bits of that cell will be red ($2 is red) and the on bits will be black (guess what $0 is!). Each cell has it's own foreground and background colour.

Multi-colour bitmaps are more "conventional" and again use the bit pair system to represent four possible colours. The difference is that whilst %00 merely represents the $d021 value, %01, %10 and %11 can be specified for each cell and retrieve their data from the high and low nybbles of the screen map and the $d800 colour map respectively. That's four overall colours per cell, three of which are independent of their neighbours.

Once again, the horizontal and vertical smooth scrolling is available and it's possible to scroll the screen using conventional methods (and a lot of pushing) and multiple buffers. Similarly, there are VIC-II "features" that allow the horizontal and vertical repositioning of the screen regardless of mode and even forcing of more "badlines" (when the screen data is fetched into the VIC-II, it only happens once every eight rasterlines) so that the attribute cells become 8*1 pixels in size for two of the three colours in multi-colour mode and all the colours in mono.

And of course, $d021, $d022, $d023 and $d024 can all be split every rasterline for the modes where it's in use, allowing an increase in colour control.

Hardware Sprites
As a finale we come to another major selling point of the C64, hardware sprites. There are eight onboard and they work independently of the screen mode; in other words all eight can be in multi-colour mode and positioned anywhere over the screen or each other whilst the screen itself is in mono-colour. Each sprite can be enabled as need be, has a unique colour, horizontal and vertical expansion, can be in mono or multi-colour and there's a priority register that controls how they react to screen data. Sprite 0 is always on top, sprite 7 is at the back.

A sprite is 63 bytes long, 3 bytes wide and 21 high. The pixels are represented as they would be for mono or multi-colour characters and when in multi-colour there are two shared registers $d025 and $d026 that supply the extra colour data for %01 and %10 bit pairs respectively. If a sprite's pixel isn't set (either mode) it's transparent and the background and any sprite of a lower priority underneath it is visible.

Sprites have their own horizontal and vertical positions (a byte for each axis) and because the screen is over 256 bytes wide a Most Significant Bit can be added. The sprite MSB is one byte which represents the eight sprites and if it's bits are set the appropriate sprite is offset 256 bytes to the right.

The only real hardware limitation to sprites is that there can only be eight in a row, there's no way known to force a sprite to "recycle" on the same rasterline and anything that appears to do that is a trick! However, they can be re-used vertically, as soon as a sprite has finished displaying it can be moved to the next rasterline down and appear again. Similarly, horizontal positions and colours can be split on every rasterline and there is even a "feature" of the vertical expansion that allows it to restart and stretch pixel rows of the sprites to just about any size vertically.

Speaking of "features", it's also possible with a little pushing and shoving to open the borders and place sprites in that area. The upper and lower are incredibly easy, but the sides take a lot more work and cycle-perfect timing to get right but if done well the effect can be very impressive.

Okay, so that's me done for the basics of the C64 video system. If y'have any questions, bung an email at tmr@c64.org and i'll see what i can do to answer them. For further reading on the C64, the C64 Programmers Reference Guide is a good grounding on the machine itself and 6510 machine code to boot and the VIC Article (original name... =-) covers all of the "features" mentioned above and a plethora more.

The Programmers Reference Guide is kept online by Project 64
The VIC Article is available from Fairlight Tools

This article originally appeared on the UKScene website in September 2002.

Site content and design copyright © 2001-2012 T.M.R of Cosine Systems