VIC-II for Beginners Part 4 - Screen Modes Cheaper by the Dozen
- VIC-II for Beginners Part 1 - When Visibility Matters
- VIC-II for Beginners Part 2 - To have or not to have Character
- VIC-II for Beginners Part 3 - Beyond the Screen, Rasters and Cycles
- VIC-II for Beginners Part 4 - Screen Modes Cheaper by the Dozen
- VIC-II for Beginners Part 5 - Bringing Sprites in good Shape
Screen Modes - Spoilt for Choice
Thanks to the very versatile VIC-II the Commodore C64 has various possibilities to work with the screen. We distinguish between modes which are either Character-based or those which are Bitmap-based. Character-based means that you work in a 8x8 Bit matrix while in a Bitmap-based mode you have control over each individual Pixel on the screen.
Both of the those main modes can be used with a default Standard Color or an alternative Multicolor option. There is only one special Character-based mode called Extended Background Color Mode which can not be used with the Multicolor option. I will go through all combinations and discuss implications in this article. It should be a good reference for later use.
I will explain the official modes in this beginners series - there are plenty of other modes created by developers who exploited VIC-II bugs and came up with some interesting possibilities. Any of the official modes will come with a table which summarizes where the individual data or color for the final output originates from.
The metrics and adresses used in this article assume that we work with the VIC-II in the standard memory configuration with VIC-II looking at Bank 3 ($0000 - $3FFF) and nothing was moved by the user, e.g. the Screen RAM location. If you switch to another bank or move anything within the 16Kb area the VIC-II is looking at you must of course consider this below.
Last but not least all modes can be mixed on the screen using interrupt programming, that is you could have a character-based mode in the lower third of the screen and Bitmap graphics in the upper part - think Graphic Text Adventures. How to do this will be subject to a tutorial.
Character-Based modes work in the 40x25 screen grid with the standard 8x8 Bit Character Sets unless you modify them of course. When writing to the screen you allocate a character to one of the 1000 cells starting at $0400. Color RAM which starts at $D800 maps the 1000 cells of Screen RAM positions 1:1 so $D800 holds Color Information for $0400, $D801 for $0401 etc.
Don't reduce Character-Based Modes to just writing some text to the screen. In fact it is a common pattern to change the original character set of the Commodore C64 for building tiled background graphics for games and demos because it is much more efficient to for example to soft-scroll a background built from characters then doing the same with Bitmap-based graphics.
1. Standard Character Mode
When you turn on your C64 you actually see the first Character-Based Screen Mode - it's the Standard Character Mode. The characters are retrieved from the Character Generator ROM. They share one common Background Color as defined in $D021 and an individual color stored in the lower 4 Bits of Color RAM at the position mapping the corresponding cell in Screen RAM.
- 8x8 Bit Matrix for each cell - supposed to be used with the Standard Character Sets from the Character Generator ROM.
- A single shared background color
- One individual foreground color
2. Multicolor Character Mode
When we enable the multicolor option for that Character Mode by setting Bit#4 in Register $D016 high something very interesting happens. Instead of an 8x8 Matrix we have now a 4x8 Matrix where every two Bits are paired, so instead of a single pixel each "dot" has the length of two pixels next to each other. What this at first strange pattern overcomes is the limitation of only using a single foreground color! Using the 2-Bit wide Pixels we can now encode more information what color to use per each pair.
It is actually pretty clever because if you look at each double-wided pixel it becomes clear that any can hold any of four values, represented in Binary that is %00, %01, %10 and %11. With this we can now refer to one of four sources of color information as opposed to just have options between one foreground and one background color. Two of those sources are the already known Background Color Register $D021 as well as the Color RAM but additionally adds the lower four bits of the two registers $D022 and $D023. If we just switch to Multicolor right after turning the C64 on by setting Bit#4 of $D016 you will instantly notice the difference between the original 8x8 Matrix of Standard Character Mode and the 4x8 Matrix we transit to when adding in the Multicolor Option.
It looks awkward because the Standard Characters are not properly set up for Multicolor at this time and we also use the initial values of $D022 and $D023. By modifying the characters appropriately you could generate some exciting graphics but more importantly colorful tiles for the background of your game or demo.
There is one catch with setting Multicolor though. Turning it on using Bit#4 in $D016 will enable it globally for all Characters, however, you need to enable it on a character-by-character basis to have an effect. This is done by setting Bit#3 in the corresponding Color RAM location. The constraint is notable at once when you think about it. If you put a color code from 0-7 into the Color RAM location of a Character it will be displayed in Standard Mode. If you put in a value of 8-15 into that location - which simply means that Bit#3 is set high - you get a Multicolor-Character. This restricts you in the selection of colors you can actually use in a Multicolor Character.
- Each character has the dimensions 4x8 Pixels where each of the horizontal Bits are paired to have double the width.
- We can now choose up to four colors per character by encoding the appropriate source of color information into each double-wide pixel.
- Three shared colors across all characters come from the registers $D021 - $D023
- One individual Color per Character can be chosen from Color RAM but only the values 8-15 are accepted to have the Character be displayed in Multicolor Mode since Bit#3 determines if the Character is Standard or Multicolor in the first place.
3. Extended Background Color Mode
The final one of our character based modes is actually not so often seen in the wild. I read that Activisions H.E.R.O uses it though. The Extended Background Color Mode let's you choose one in four background colors per 8x8 Bit Character as opposed to just a single background color in Standard Character Mode. The difference to Multicolor Character Mode is that you keep the 8x8 Matrix and have not to cut horizontal resolution by half.
Using this mode comes with a cost though. Like with the Multicolor option two bits are still needed to encode the information from where some color is retrieved from. In the Extended Background Color Mode those two bits are the two highest Bits of the Screen Code of any Character and they determine the Background Color used for this Character across the screen while the individual Foreground Color per cell is still retrieved from Color RAM.
This theft of two Bits to encode a color source comes with a problem of course. Since only 6 Bits per Character can be used now are limited to point to only 64 different characters as opposed to 256 Characters when all Bits being available. If you do a game and want to use some of the Characters for building background graphics plus need some standard letters for text, this will get complicated.
The selection of background colors are defined in the Registers $D021 - $D024 and then displayed accordingly to the Bitmask of the two highest Bit in the Screen Code. For example, the Bit Pattern of the Screen Code for the Letter A is %00000001 . If we want the character to be displayed with the color information from $D023, the Screen Code needs to be changed to %10000001 .
If you turn on the Extended Background Color Mode by setting Bit#6 in $D011 only the blinking cursor will actually change color. The reason is that all Standard Characters have their two high bits not set and the blinking cursor is actually a reversed character and as we already learned this means that in this case the highest bit IS actually set, ultimately making the used Screen Code look like this %10xxxxxx. The reversed version of the cursor therefor uses the color of $D023.
Extended Background Color Mode can not be mixed with the Multicolor Option.
- Characters are displayed in a 8x8 Bit Matrix like in Standard Character Mode.
- Bit#6 and Bit#7 of the Screen Code are used to determine the desired Color source
- Since we lose 2 Bits in the Screen Code, only 64 different Characters can be displayed on the screen.
- Choice of one in four defined Background Colors per Character
- One Individual Foreground Color per Character
This closes our three Character-Based modes, let's turn to Bitmap graphics.
In Bitmap-Mode you control every and each pixel on the screen, that are all of the 64.000 in the 320x200 area - and beyond if you use some tricks to remove the borders. Our 1000 Byte large Screen RAM can not be used anymore for this large amount of data as 64.000 Bits correspondent to about 8KByte memory consumption. If you now recall that the VIC-II actually can only look at 16Kb at a time, losing 8Kb for some Bitmap Graphics sounds wasteful - and it is!
Of course there are ways to overcome limitations like by bank switching but let's for now look at standard way to work with Bitmap Graphics. There are only two Bitmap modes, the Standard Bitmap Mode with Multicolor option turned on, the Multicolor Bitmap Mode. When you understood the difference between Standard Character and Multicolor Character Mode, than you will be familiar with the concept already. Bitmap Mode is turned on by setting Bit#5 of Register $D011 high.
1. Standard Bitmap Mode
Technically there is not so much to talk about graphics in Standard Bitmap Mode. The C64 wants us to reserve a 8Kb large area in the bank the VIC-II is pointing to. This is required to overcome the limitations of the Screen RAM which simply is not big enough to hold a full bitmapped graphics. However, the Screen RAM has now another function - its new job is to be the source for colors for the Bitmap. The Background Pixel Color is defined by Bits#0 - Bit#3 of the corresponding Byte in Screen RAM. The Foreground Pixel Color is defined by Bits#4 - Bits#7 - again from the corresponding Byte in Screen RAM.
So even in Bitmap mode, you define the color for a full 8x8 Matrix using a Byte in Screen RAM. You can not define a color per Pixel - which would be hard to store in the first place. Imagine that a color needs four Bits to cover all 16 combinations. If you multiply this by 64.000 individual Pixels, you would need 250Kb for color information in addition to the 8Kb for the actual Image if every pixel has it's own dedicated color code stored somewhere. Not happening!
- Set or unset any of the 64.000 Pixels on the screen
- Change color for each 8x8 cella using information from Screen RAM
- 8Kb of RAM within the 16Kb area of the VIC-II needs to be reserved to store a full bitmap graphic
- Initial reserved RAM for Bitmap in Bank 3 is $2000 - $3FFF. This can be changed but since 8Kb is required only two possible locations in each 16Kb bank are possible.
2. Multicolor Bitmap Mode
The Multicolor Bitmap Mode follows the principle I explained with the Multicolor Character Mode. It pairs up every two pixel on the screen which ultimately brings us down to a resolution of 160x200 - but with wide Pixels that is. The benefit is that we can now appoint again four different sources of color information within every two-wide Pixel. This makes up for losing half of the horizontal resolution. Where the Bitmask is %00, the Background Color Register $D021 is used. For %01 and %10 the VIC-II retrieves the information from Screen RAM in a similar fashion as in Standard Bitmap Mode. Finally we now also have the 1000 Byte large Color RAM where the lower four Bits of each Byte supply us with the fourth color.
- Horizontal Resolution cut in half to 160x200 to pair up every two pixels and use them as container for color source information.
- Four colors can be appointed for any of the wide Pixels. Background Color is shared from Register $D021 but Color 1 to Color 3 can be freely chosen for each 2x1 Pixel in the Bitmap.
These were all the Screen Modes the VIC-II can officially handle. There are many more often evolved from exploiting VIC-II bugs or the clever combination of the available modes. We will eventually talk about those advanced screen modes at another time.