c64 Interrupts Eng Part04

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 7

RetroProgramming Italia - RP Italia presents :

Interrupts C64 tutorial – Part 4


(Raster Interrupts 1)
By
Attilio Capuozzo – Founder of RetroProgramming Italia
– RP Italia Facebook Group
& Antonio Savona – C64 GameCoder & DemoCoder

In part 3 of this tutorial, we have analysed how a NMI interrupt works and
we have discussed two examples of assembly code in which we have explained
how to set up a simple IRQ or NMI interrupt.

We will now turn to the study of one of the most frequently used sources of
interrupts, particularly in the programming of video games and demos on the
Commodore 64: these are RASTER INTERRUPTS.

The raster interrupt (Fig. 1) is one of the 4 sources of interrupt requests


from the Commodore 64 graphics chip (the VIC):

Figure 1 – interrupt sources from the VIC (c64 graphics processor)


First we need to explain how the image produced by the video processor (or
"FRAME") is displayed on the screen.

The "FRAME" display is generated by the scan of the raster beam, line by line
from left to right and top to bottom to the lower right corner of the screen.
The video display update occurs 50 times per second in the PAL TV standard,
i.e. at a frequency of 50 hertz. In the PAL system, a complete "FRAME"
consists of 312 raster lines (or "Scan Lines"). In the NTSC standard there
are 262 raster lines.

The number of the raster line being scanned (from 0 to 311) is contained in
the frame register, a 9-bit register containing the 8 bits of the $d012
address and the most significant bit (bit 7) of the $d011 address (Fig. 2) :

Figure 2

The area of Commodore 64's screen where text and graphics are usually
displayed is called the "display window" and measures 320*200 pixels by
default. This number of pixels is lower in the 38 column or 24 line display
modes. The display window is surrounded by the screen border, which is an
area where text and graphics are not normally displayed (Fig. 3) :

Figure 3: The display corresponds to the NTSC standard with a total of 262 raster
lines.
The colour of the screen border is determined by the colour code number stored
in the register address $d020 of the VIC.

A distinction is made between the upper and lower part of the vertical edges
and another distinction is made between the left and right part of the
horizontal edges. There are also so-called "BLANKING INTERVALS" outside the
entire visible area of the screen (edges and display window). These are areas
of the screen where, in fact, the video signal is switched off and the
electron beam "jumps" directly to the beginning of each new line without
displaying anything.

It is possible to distinguish a vertical blanking interval (VBlank) before


the top edge and after the bottom edge of the screen and a horizontal blanking
interval (HBlank) before the left edge and after the right edge.

The screen lines visible in the display window range from 51($33) to 250($fa).
In this regard, it should be noted that many sources erroneously indicate
that the first visible raster line has the number 50($32).

In fact, this reference must be applied to the Y-coordinate of the Sprites.


Finally, to position a Sprite at the desired Y coordinate, its vertical
coordinates must have an offset of -1 with respect to the raster line on
which the first pixel line of the Sprite in question will actually be
displayed.

This occurs because the test of correspondence between the Y-coordinate of


the relevant Sprite - stored in one of the Y-position registers (odd records
in the range $d001-$d00f) - and the number of the raster line being scanned,
takes place towards the end of the on-screen generation of that raster line.
Therefore, when these two values coincide, the Sprite will be displayed on
the screen only at the next scan line.

Please note that in the above case, the comparison of the vertical coordinates
of the Sprite is carried out, for obvious reasons, only with the contents of
the address $d012, i.e. with the first 8 bits of the frame register $d012-
$d011.

Below is a table showing how, depending on the horizontal and vertical


coordinates of a standard Sprite of 24*21 pixels or an Enlarged Sprite along
the X and Y axes, the Sprite will be hidden, visible or partially visible.

The table in Fig. 4 shows the values relating to both a standard display
window of 320*200 pixels and a display window of 304*192 pixels (Display
window with 24 lines*38 columns) :
To specify a position on the screen according to the Cartesian system of
abscissa and ordinate, we will use as the vertical Y coordinate the line
number of a raster line - the number whose value is contained in the frame
register $d012-$d011 - while for the horizontal X axis, we will refer to the
Sprite coordinate.

Before continuing the discussion, it should be noted that we will use the
terms "raster line", "scan line", "screen line" and "pixel line" in a fully
equivalent manner. Similarly, the terms "Text line", "Character line" and
"Screen row" should be understood as synonyms.

Each complete screen line, under normal conditions (Standard Raster line),
"lasts" 63 CPU clock cycles (65 cycles in the NTSC system). This is therefore
the calculation time available to the programmer for each standard raster
line.

It should be noted that during each clock cycle, the VIC and the 6510 access
the memory by taking control of the data bus in turn. More precisely, each
clock cycle is broken down into two phases:

During the first phase the VIC accesses the memory in read-only mode.

During the second phase, the 6510 accesses the memory in read/write mode.

During each clock cycle, the VIC generates 8 pixels at a time. 8 raster lines
form one character line of the display window.

In text mode (or character mode), the default display window consists of 25
rows of 40 columns each, and each character displayed consists of a block of
8*8 pixels.

In bitmap mode, these 25 rows of 40 columns are managed by individually


addressing each of the 320*200 pixels corresponding to 64000 bits in memory
or better, 8K. In bitmap mode, the 8*8 pixel block is also present.

The first scan line of each screen row only "lasts" 23 CPU clock cycles (25
in the NTSC standard), so the programmer has only 23 CPU clock cycles while
the first scan line of each screen row is displayed. In fact, in addition to
the memory accesses made during a standard scan line, the VIC needs 40 "full"
clock cycles to perform additional memory accesses..

These additional memory accesses are:

- In text mode: access to the video matrix (screen memory) to read the 40
character codes (character pointers) of the current screen line and access
to the memory area containing the colour code of each of the characters of
the current screen line ("colour RAM")

- In bitmap mode: access to the screen memory containing the colour


information of the 8*8 pixel block.
The raster lines of 23 clock cycles are called "BAD LINE".

"BAD LINES" exist ONLY in the display window.

The condition for which a "BAD LINE" is generated is the following ("Bad Line
Condition"):

The 3 least significant bits (bit 0-2) of register address $d012 must coincide
with the 3 least significant bits (bit 0-2) of register address $d011.

The default value of bits 0-2 of the $d011 register address is 3 (%011).
Therefore, under normal conditions, the first "BAD LINE" is scan Line 51($33)
(%00110011) which is followed by 7 standard scan lines, the whole constituting
one screen row. The next "BAD LINE" will be Line 59 ($3b) (%00111011) followed
by 7 standard scran lines, and so on.

51 (%00110011) $d011 %xxxxx011 – « BAD LINE »


52 (%00110100) $d011 %xxxxx011
53 (%00110101) $d011 %xxxxx011
54 (%00110110) $d011 %xxxxx011
55 (%00110111) $d011 %xxxxx011
56 (%00111000) $d011 %xxxxx011
57 (%00111001) $d011 %xxxxx011
58 (%00111010) $d011 %xxxxx011
59 (%00111011) $d011 %xxxxx011 – « BAD LINE »

The memory accesses performed by the VIC when the active scan line is a bad
line are not sufficient to generate the characters or bitmap graphics on the
screen. In addition to these memory accesses, the VIC performs other memory
accesses during the generation of all the raster lines of the display window
(i.e. both when the beam draws a bad line and when it draws a standard raster
line).

These memory accesses are as follows:

• In text mode: access to the ROM of the character generator (or


Character User RAM in case of redefined characters) to read the
information that defines the appearance of the characters.

• In bitmap mode: access to 8K bitmap for pixel reading

The above-mentioned accesses are performed by the VIC during the first phase
of the clock cycle and therefore do not lead to the stealing of CPU clock
cycles.

If Sprites are to be displayed, it is necessary to read in the memory the


data pointer of each sprite (sprite data pointer) as well as the data that
defines the shape of the Sprite. We briefly recall that each of the data
pointers points to one of the 256 blocks of 64 bytes in the 16K address space
of the VIC.

The data pointers of each sprite are accessed during the first phase of the
clock cycle and therefore do not cause CPU clock cycles to be stolen. However,
for a given sprite to be displayed on the current scan line, the first and
third bytes are read during the second phase of the clock cycle, while the
second byte is read during the first phase of the clock cycle. As a result,
regardless of the scan line (standard or badline), a number of CPU clock
cycles are subtracted by the VIC when Sprites are to be displayed.
This is a direct consequence of the fact that it is the VIC itself that
generates the system clock frequency.

It should also be noted that the system clock in the PAL standard has a
frequency of 985,248 Hz (or Cycles/Second) while it is 1,022,727 Hz
(Cycles/Second) in the NTSC standard.

Finally, he reminds us that the VIC can be in one of the following two
"states":

The "DISPLAY" state is the state assumed by the VIC when the electron beam
is in the display window and the VIC performs the various memory accesses
for displaying text, graphics and sprites.

The "INACTIVE" state is the state taken by the VIC when the electron beam is
outside the main window (mainly the edges of the screen). In this inactive
state, the VIC always accesses the memory by always reading the same byte
(called "GHOST BYTE") located at the last address of the 16K zone selected
and addressed by the VIC: $3fff or $7fff or $bfff or $ffff (in the case of
the ECM - Extended Color Mode display - access is made at the $39ff address).

We will see in a future example of code that with the "opening" of the
vertical edges and the modification of the bits of the "GHOST BYTE" (which,
by default, has all its bits at 0) we will be able to display black lines in
the upper and lower edges of the screen (the colour code of the "GOSHT BYTE"
is always 0 or black).

Thanks to this long but exhaustive presentation of the functioning of the


video display of the Commodore 64, next time we will be able to approach the
first code examples for the implementation of a RASTER INTERRUPT.

That's all folks!

Attilio Capuozzo – Founder of "RetroProgramming


Italia – RP Italia Facebook" Group
& Antonia Savona – C64 GameCoder & DemoCoder

You might also like