Graphics

Introduction
Video Interface Chip - (VIC-II)
The screen, and its borders
Bitmap modes
Characterset modes
Sprites

Introduction

The C64 series was designed for use with a video monitor or TV set in mind, and thus it has a built-in TV modulator besides the video output connector. That way, people do not need to spend on a special monitor which was very expensive when the commie was first marketed. This choice, gives however also some limitations for what is needed for display. Pixel resolution of the commie is very like the resolution of a normal TV set (which is not very high), and so using the resolution in full (with all its limitations). This design choice is one of the reasons why the commie became so popular, similar choices has been seen on other similar equipment such as the VIC-20 (precursor of the C64), and series of Amiga (A500, A600, A1200, CDTV and similar), Amstrad, Atari, Nintendo, Sony PlayStation, Xbox... just to name a few... Some of these architectures use an external TV modulator, some have an internal one (which makes it more handy, but the result is the same). However at the time of design of the C64, video circuits and electronics in general, where not that fast (Price/Performance) and so resolution (and the number of colours) of multicolour graphics was implemented (compared to what you would do in our days) in a rather clumsy way. Furthermore, the choice of using video signal compatible to TV standards (either in the form of a TV or video monitor) another issue is introduced - different TV standards around the world.

The Video generation circuit architecture used in C64 was widely based on the experience given by the design of the VIC-20, and the VIC-II is the successor to the VIC used in that microcomputer. The VIC-II has however some adapted features compared to the VIC. And remember the commie is designed somewhere around 1980-1982, based on even older microcomputers (PET, VIC-20 etc.)

As for the, coming later, C128, it was also based on the VIC-II technology, but Commodore had by the time realised that there could be a market to share when it came to people using spreadsheets and word-processors (competitor to IBM and their newly marketed PC, the C128 was superior to the first PC´s on the market... And the price was extremely lower than those). But the 40 char wide screen and such, was not good when using wordprocessors, a chip for displaying 80 chars wide screens was additionally implemented, and a computer monitor was required for that display mode. But this page is mainly about C64, so lets return back to the topic...

 

Video Interface Chip (VIC-II)

The VIC-II has 16 predefined colours, several bitmap- and character-modes and up to 8 sprites. The chip can access 16Kb of memory of choice (Called Graphic-Banks) out of the 64Kb of the address-space, and which bank to be displayed is selected by controlling bit 0 and 1 at Port2 at the CIA#2 (Complex Interface Adapter). The C64 charset is not available at Bank 1 ($4000-$7000) and Bank 3 ($C000-$FFFF).

VIC-II graphics display features

CHARACTER DISPLAY MODES

Standard Character Mode (8*8 pixels)

ROM characters

RAM programmable characters

Multicolour Character Mode (4*8 pixels)

ROM characters

RAM programmable characters

Extended Background Colour Mode ([8,4]*8 pixels)

ROM characters

RAM programmable characters

BIT MAP MODES

Standard bitmap (320*200 pixels)

Multicolour bitmap (160*200 pixels)

8 Sprites/MOBS

Singlecolour Sprites (24*21 pixels)

Multicolour Sprites (12*21 pixels)

Borders

Side border

Upper/bottom border

8 bit scroll in X and/or y direction

 

The VIC-II can handle 16 (predefined) colours.

Rasterhandling, splitscreen or displaying two (or more) frames in turn is possible. Some Illegal-modes are possible, which can be used for some tricks.

Each Sprite can be expanded in X and/or y direction (doubble the size of the pixels). Furthermore, by programming - opening the borders, it is possible to display sprites in the border area.

 

 

 

The Screen and its borders 

The screen is represented with a 320*200 pixels displayfield in the center which can handle characters, bitmap and sprite graphics. The screen mode, which is set via registers in the VIC-II, determines what kind of graphics is displayed in that area. In character mode, a normal character takes 8*8 pixels, and thus making a matrix of 25 lines of 40 characters.

Furthermore, the screen has borders. Usually, no graphics is displayed in the border area. The border has however a colour within the usual palette which can be set in a register. It is possible to perform tricks which "opens" the border, and thus makes it possible to display sprites and the display field background colour in the border area. There are two different kinds of borders, upper/lower and the sideborder. Each type of the border needs its own little tricks in order to open for sprite graphics.

The sprites mentioned, are hardware sprites and they are handled separate from the rest of the graphics. The VIC-II can handle up to 8 hardware sprites at a time. Suitable programming can make a program go beyond this limitation.

 

C64 Screen - Displayfield and borders

The C64 video screen

Showing Upper/Lower border (BrownRed), sideborder (Light blue), display field (Dark blue), and one white sprite (Out of 8 possible).

Note: Upper/Lower border is opened in this case, it require some assembler coding using a simple trick.

 

 

BITMAP modes

The bitmap modes is used for displaying pictures and fonts (in the form of bitmap graphics) in the displayfield, there are two basic modes - Hires and multicolour bitmap mode.

The VIC-II is using a memory format of which the bitmap should be stored, and there are some differences whatever you choose hires or muliticolour bitmap mode. The bitmap (320*200 bits) itself is stored in one memory area. Then a colour matrix area (40*25 bytes - pointed to by a screen pointer) is used for selecting which colour the bits (within each 8*8 bits square) in the bitmap should be displayed as. If multicolour is to be displayed, an additional colour nybble is needed, and this nybble is asways located at $D400 and upwards 1000 bytes. A colour attribute cell is the are covered by the colour matix area and the colour nybble area, together.

With hires it is possible to display 320*200 pixels within the display area. Using multicolour bitmap mode, two bits is used to select the colour the bit represents (given in the colour attribute cell), and thus a resolution of 160*200 pixels is given.

The bitmap areas format is also abit special for the VIC-II, it should be store like this in memory:

1.Byte

9.Byte

 

40 cells (of 8*8 bits) wide (Each cell block refers to the corresponding colour attribute cell - see text)

 

2.Byte

10.Byte

3.Byte

11.Byte

4.Byte

12.Byte

5.Byte

...

6.Byte

...

7.Byte

...

8.Byte

...

320.Byte

329.Byte

...

...

 

 

Standard Bit Map Mode, Hires

Resolution: 320*200 pixels
Total colours, max : 16 (2 in each of the 40*25 colour attributes cells)
Limitations: Max 2 colours within each colour attribute cell (8*8 pixels).
Workaround on limitations: YES! See Note. Similar to multicolour workaround... but the background colour in $D021 is not displayed.
Controlling colours: The upper 4 bits of the bytes stored screen memory becomes the colour of any bits that is set (to 1) in the 8*8 pixels attribute controlled by the screen memory. The lower 4 bits is the colour of any pixels cleared (0).

 

Multicolour Bit Map Mode

Resolution : 160 * 200 pixels.
Total colours, max: 16 (3 in each of the 40*25 colour attribute cells + one shared)
Limitations: Max 3 colours within each colour attribute cell (4*8 pixels)+1 background colour.
Workaround on limitations: YES! See Note. Techniques such as FLI, rasterbars, sprites.... And others
Controlling colours: In Lores bitmap mode each pixel uses 2 bits in the bitmap to represent it´s colour in it´s colour attribute cell:

Bitmask

00

Transparent, Display background ($D021, or a sprite in the background!)

01

High nybble of colour matrix (Screen - 40*25)

10

Low nybble of colour matrix (Screen - 40*25)

11

Colour nybble (4 bits colour matrix, stored at $D800 and forward - 40*25)

 

*Note 1: The given Colour matrix for each rasterline is normally fetched by the VIC-II on each 8th rasterline (the same rasterline with is referred to as "BAD LINE", and this is the reason why a colour attribute cell covers 8 pixel-lines.. However, it is possible to force the VIC-II to fetch new colour data on each line, and thus, making it possible (in combination of moving the screen pointer/Colour matrix pointer) to have more colours within a colour attribute cell.. Such technique is called FLI (or AFLI depending on mode, and exactly what is implemented) and requres some rather timing critical programming on each rasterline.

 

 

Characters and fonts

In character mode, the display area of the screen can be visualised by a matrix of 40*25 Screen-cells or blocks. Each screen-cell has a value between 0-255, giving a choice by one of 256 different characters in a the font-set. The C64/128 has an embedded charset placed in a ROM, this can be used or you can define your own charsets in RAM, and have the VIC-II point at the charset (following some restrictions, which makes some limitations within reason). Each char can have its own colour defined, but when using multicolour-mode some colours are shared.

Each character in the font is composed by 8 bytes (=8*8 bits), and represents 8*8 pixels in singlecolour mode, and 4*8 pixels in multicolour mode. Techniques such as char-logos, 2*2 charsets, and such, can be realised by placing blocks of two, or more characters next to each other.

The character set/font bitmap areas format is also abit special for the VIC-II, it should be store like this in memory, and thus is very similar to normal bitmap graphics:

Char #0

 Char#1

...256 cells (of 8*8 bits) wide (Each cell block refers to the corresponding colour attribute cell - see text).

 

1.Byte

9.Byte

2.Byte

10.Byte

3.Byte

11.Byte

4.Byte

12.Byte

5.Byte

...

6.Byte

...

7.Byte

...

8.Byte

...

The colours is defined in a way, which is similar, yet different from the method used when handling bitmap graphics. The screen is defined as the usual 40*25 chars, each of these locations have a colour attribute attached (nybbles are defined in the area $D800 and 1000 bytes up), and thus defining the colour of the chars pixels represented as 1´s in that cell (0´s in the charset is transparent).

 

Multicolour Character Mode (4*8 pixels)

When using multicolour mode chars, the scheme is abit strange. When you have put the VIC-II into the mode of handling multicolour chars (by setting a single bit in a special register), the 3th bit of the colour attribute nybble ($D800- and upward 1000 bytes) also determines whatever each char should be displayed as a multicolour or singlecolour char. Furthermore, the colour of the char´s bitpair combination is defined in bits 0-3 (colour nybble) in the colour attribute nybble, other bitpair combinations is represents shared colours defined in registers of the VIC-II.

Bitmask

00

Background #0 ($D021, or a sprite in the background)

01

Background #1 ($D022, or a sprite in the background)

10

Background #2 ($D023, or a sprite in the background)

11

Colour nybble; Bit 3 ALSO determines whatever the char should be displayed as singlecolour (0) or multicolour (1) mode (meaning you can only display colours 8-15 in multicolour mode, or colours 0-7 in singlecolour.

 

Extended Background Colour Mode charsets

Using this mode, it is possible to display an additional background colour within each char on the screen, at the cost of number of chars in the charset (only 64 chars are displayable in this mode). By enabling the extended background colour mode by setting a bit in the VIC-II registers, bit 6 and 7 in the char code will be interpreted as a bitpair selecting which background register is to be displayed at the char location.

Bitmask

Bit 6&7 of screen code

00

Background #0 ($D021, or a sprite in the background)

01

Background #1 ($D022, or a sprite in the background)

10

Background #2 ($D023, or a sprite in the background)

11

Background #3 ($D024, or a sprite in the background)

This mode is used in many disk-noters, as it gives a simple and effective way of adding fading text to to the interface (sometimes implemented by a reversed singlecolour-charset defining char 0-63), fill $D800-$DBE7 with 0, and store e.g. 1 in $D021 (normal text colour) and fade with $D022-$D024 - Simple but effective!)

 

 

SPRITES

The VIC-II is designed in order to handle a total of 8 hardware sprites - suitable programming (like multiplexers) makes it possible to have more than 8 sprites on the screen at a time. Each sprite can be either singlecolour with one colour of choice, or multicolour with one colour of choice + 2 colours which all displayed sprites have in common. Sprites can, independently of each other, be displayed in the foreground or background of screen-graphics (See the Sprite priority and collision detection section), and be expanded to double size - horizontal and/or vertical. And there is the possibility for collision detection to other sprites and background graphics, however... sometimes (read; often) you want to write your own detection scheme. There are other funny details in connection with sprites, for example display of sprites in the border area of the screen by opening the borders.

Spritedata takes 24*21 bits ( 3*21 bytes = 63 bytes) plus one byte not displayed by the VIC-II (a memory align byte), so a total of 64 bytes. This byte can be used to whatever one wants. For example sprite colour (4 bit is enough), expansion information, some layer information or... Some sprite-editors takes advantage of this byte, some don´t.

The format of sprite-graphics data is abit different from all other graphics on the C64;
It is stored like this in memory :

1.Byte

2.Byte

3.Byte

4.Byte

5.Byte

...

... Totally 3*21 bytes
(+ one extra byte)

An so, it is not oriented the same way as hires or charsets, which are cell/attribute oriented.

 

Standard Sprites

The size of a standard sprite is 24*21 pixels. A set pixel in the sprite data is represented by a colour defined in the Sprite colour register of the VIC-II. There are 8 sprite colour registers, each defining the colour of the corresonding sprite.

Multicolour Sprites

Each seperate of the 8 possible sprites can be turned into multicolour mode. The bits in the sprite-map is then handled as bitpairs selecting the source of the pixels colour.

Bitmask

Multicolour Sprites

00

Transparent, Display background (Whatever is there!)

01

Multicolour register #1 ($D025)

10

Sprite X colour register ($D027-$D02E)

11

Multicolour register #2 ($D026)

The size of the sprite is the same, however resolution gets lower (12*21 pixels) as it takes two bits to represent each pixel (just as any other multicolour mode graphics on the C64).

 

Sprite priority and collision detection

Each of the eight (See note *!1*) sprites controlled by the VIC-II has a priority compared to eachother and to the background graphics. Sprite 0 has has higher priority than Sprite 1, Sprite 1 has higher priority than Sprite 2 and soforth.

The VIC-II makes it possible to detect both sprite-sprite, and sprite-graphics collisions. You can poll special registers to check bits, but you have also the possibility to have the detection interrupt-driven. There is however some things to be aware of when it comes to sprite collisions, for example which of the bit combinations in the background graphics generates a collision detection.

The following table shows how sprite priority and detection behaves..

 

Sprite display priority and collision detection table (Preliminary!!)

Front

Back

Front

Back

Single
colour
Spr. 0
Bit= 0
Single
colour
Spr. 0
Bit= 1
Single
colour
Spr. 0
Bit= 0
Single
colour
Spr. 0
Bit= 1
Multi
colour
Spr. 0
Bit=00
Multi
colour
Spr. 0
Bit=01
Multi
colour
Spr. 0
Bit=10
Multi
colour
Spr. 0
Bit=11
Multi
colour
Spr. 0
Bit=00
Multi
colour
Spr. 0
Bit=01
Multi
colour
Spr. 0
Bit=10
Multi
colour
Spr. 0
Bit=11
BMP -0

G

S

G

S

G

S

S

S

G

S

S

S

BMP -1

G

SC

G

GC

G

S

SC

SC

G

G

G

G

MBMP -00

G

S

G

S

G

S

S

S

G

S

S

S

MBMP -01

G

S

G

S

G

S

S

S

G

S

S

S

MBMP -10

G

SC

G

GC

G

S

SC

SC

G

G

GC

GC

MBMP -11

G

SC

G

GC

G

S

SC

SC

G

G

GC

GC

Char - 0

G

S

G

S

G

S

S

S

G

S

S

S

Char -1 

G

SC

G

GC

G

S

SC

SC

G

G

GC

GC

EChar - 0

G

S

G

S

G

S

S

S

G

S

S

S

EChar - 1

G

SC

G

GC

G

S

SC

SC

G

G

GC

GC

MChar - 00

G

S

G

S

G

S

S

S

G

S

S

S

MChar - 01

G

S

G

S

G

S

S

S

G

S

S

S

MChar - 10

G

SC

G

GC

G

S

SC

SC

G

G

GC

GC

MChar - 11

G

SC

G

GC

G

S

SC

SC

G

G

GC

GC

Front

Spr. 1 - 0

G

S0

G

GS0

G

S0

S0

S0

G

GS0

GS0

GS0

Spr. 1 - 1

S1

S0C

GS1

GS1C

S1

S0

S0C

S0C

S1

GS0

GS0C

GS0C

Back

Spr.1 - 0

G

S0

G

GS0

G

S0

S0

S0

G

GS0

GS0

GS0

Spr.1 - 1

GS1

S0C

GS1

GS0C

GS1

S0

S0C

S0C

GS1

GS0

GS0C

GS0C

Front

MSpr.1 - 00

G

S0

G

G

G

S0

S0

S0

G

GS0

GS0

GS0

MSpr.1 - 01

S1

S0

S1

S0C

S1

S0

S0

S0

S1

GS0

GS0

GS0

MSpr.1 - 10

S1

S0C

S1

S0C

S1

S0

S0C

S0C

S1

GS0

GS0C

GS0C

MSpr.1 - 11

S1

S0C

S1

S0C

S1

S0

S0C

S0C

S1

GS0

GS0C

GS0C

Back

MSpr.1 - 00

G

S0

G

GS0

G

S0

S0

S0

G

GS0

GS0

GS0

MSpr.1 - 01

GS1

S0

GS1

GS0

GS1

S0

S0

S0

GS1

GS0

GS0

GS0

MSpr.1 - 10

GS1

S0C

GS1

GS0C

GS1

S0

S0C

S0C

GS1

GS0

GS0C

GS0C

MSpr.1 - 11

GS1

S0C

GS1

GS0C

GS1

S0

S0C

S0C

GS1

GS0

GS0C

GS0C

G = Graphics displayed
S = Sprite displayed (+#)
C = Collision detection
MSpr = Multicolour sprite (#)
Spr = Sprite
Front/Back = Sprite/Background priority register ($D01B)

Note: Sprite/Sprite information should be read in recursive order for proper priority referring to "background" graphics.

See the C64 Programmers Reference Guide for programming information concerning sprites detecting and handling sprites. The book shows the most common techniques for handling sprites and graphics.

Other collision detection schemes can be implemented for special reasons, like handling several layers of graphics, workaround of the nifty bitpairs (which are not detected as collisions), and whatever. These includes use of collision maps in memory (bit combinations in a bitmap not displayed for the user), and detection algorithms reading the memory instead of using the VIC-II.

 

Notes:

*!1* As mentioned; the C64/C128 has registers for displaying 8 sprites on the screen at the time. Programming techniques, which handles the raster, makes it possible to store new values in the registers (each frame) after the sprite has been updated via the VIC-II. This is used in sprite-multiplexers (which also includes a sprite-sort algorithm) and similar techniques. If you are a really bad girl, you can also change the sprite-registers on the same rasterlines as the sprite is displayed in order to do some nice tricks, just take care of your timing. And remember the 8th scanline ("bad lines") where the VIC-II takes over the bus. And remember, that sprites changes the timing, so test your raster-routine with sprites on.. Just an advice!