Graffiti

Depending on your point of view, this isn't technically a graphics card as such. What it does is supply your Amiga with chunky screen modes which aids speeding up software which requires chunky displays such as emulating an Apple Macintosh.

Palette: 256 out of 262144
Screen Modes:
640x256
320x256
160x256
80x256
(Interlacing supported in all modes)

The Graffiti connects to the RGB port of the Amiga.
Works with all known Amiga models which have this connector.
PAL & NTSC compatible.

The Graffiti card has it's own color palette that is called the "external palette" from now on. The Amiga-palette that is set in denise/lisa will be called the "internal palette."

When using the chunky pixel mode, the internal palette must be set to one of the following: (no matter what version you are programming)


4 bitplanes:  (320 pixel/line at hires, 640 pixel/line at SHires)
               R   G   B
Colour #0      0   0   0
Colour #1      0   0   1
Colour #2      0   0   8
Colour #3      0   0   9
Colour #4      0   8   0
Colour #5      0   8   1
Colour #6      0   8   8
Colour #7      0   8   9
Colour #8      8   0   0
Colour #9      8   0   1
Colour #10     8   0   8
Colour #11     8   0   9
Colour #12     8   8   0
Colour #13     8   8   1
Colour #14     8   8   8
Colour #15     8   8   9

2 bitplanes:  (160 pixel/line at hires, 320 pixel/line at SHires)
               R   G   B
Colour #0      0   0   0
Colour #1      0   0   9
Colour #2      8   8   0
Colour #3      8   8   9

1 bitplane:   (80 pixel/line at hires, 160 pixel/line at SHires)
               R   G   B
Colour #0      0   0   0
Colour #1      8   8   9

Also when using the chunky pixel mode, the internal palette and the bitplane X-offset values must not be changed. If any of these values are modified, the Grafitti card will behave in an undefined manner. Do not worry, it won't damage your monitor or you Amiga.

Preparing The Screen Mode

Choosing either 4 bitplanes hires or 2 bitplanes SHires sets the Graffiti to 320x256 pixel mode. Setting up 2 bitplanes hires or 1 Bitplane SHires selects the 160x256 pixel mode, and a single bitplane hires selects the 80x256 mode. The highest resolution available is 4 Bitplanes SHires, resulting in a 640x256 display mode. The Grafitti card is overscan-compatible, so up to 768 pixels and more than 512 lines are possible (depends on PAL or NTSC modes, interlaced or non-interlaced).

Initializing the card

After power-up, the RamDAC chip on the Graffiti card is in an undefined state. It must be initialized by a sequence of commands sent in the Graphics data. After a VSync, the Graffiti card is in command mode. This means that the bitplane data is interpreted as commands, not as graphics data. In command mode, the Graffiti displays a black screen. This is done so that transferring palette data is "invisible" to the user. Note that when interlacing, a VBlank splits the two half screens. In this case you will have to send start graphic commands every half frame.

Commands can only be sent to the Grafitti card when the Amiga is displaying a 4 bitplane hires screen. Note also that the correct internal palette must be set.

A command is composed of two bytes, the command byte and the parameter byte. There are six commands:


0   NOP                  No operation, parameter is ignored.

4   Set colour           Parameter selects the colour to be set.

5   Set Mask register    Parameter sets the pixel read mask 
                         register (should be set to #255).

6   Set RGB value        sets the RGB values of the colour 
                         that is defined by the 4-command. 
                         This command must be executed three
                         times in a row, first to set the 
                         red value, then to set the green 
                         value, then to set the blue value.
                         Values must be from 0 to 63, the 
                         upper two bits are ignored.

7   Set read position    not supported, for debugging 
                         purposes.

8   Start lores          Ends the command sequence and 
                         starts lores graphics (use this 
                         command for hires screens).

24  Start hires          Ends the command sequence and 
                         starts hires output (use this 
                         command for SHires screens). This
                         command is only available with the
                         hires version, it's handeled like
                         the 8 command on the lores version.

The first command to be executed is byte 0 in bitplane 0. The corrosponding parameter is located in bitplane 1, byte 0. The second command to be executet is byte 0 in bitplane 2, the corrosponding parameter is byte 0 in bitplane 3. The third command is byte 1 in bitplane 0, the parameter is located in byte 1 of bitplane 1. Example:

Assuming the base addresses of the four bitplanes are located in (a0) to (a3):


move.b #5,(a0)+         ; set pixel read mask register
move.b #255,(a1)+       ; to 255
move.b #0,(a2)+         ; NOP
move.b #0,(a3)+         ; parameter is ignored - can be any
                        ; value.

Setting The Palette

The pixel read mask register can be used for effects,

To set a single palette value, two blocks of four byte moves, using postincrement addressing, can be used. The following sequence sets colour #0 to black (R=G=B=0):

move.b #4,(a0)+         ; set COLOUR #
move.b #0,(a1)+         ; 0 next.
move.b #6,(a2)+         ; Set red value
move.b #0,(a3)+         ; to 0.

move.b #6,(a0)+         ; Set green value
move.b #0,(a1)+         ; to 0.
move.b #6,(a2)+         ; Set blue value
move.b #0,(a3)+         ; to 0.

Colour #23 could be set to a light blue using:

move.b #4,(a0)+         ; set COLOUR #
move.b #23,(a1)+        ; 23  next.
move.b #6,(a2)+         ; Set red value
move.b #0,(a3)+         ; to 0.

move.b #6,(a0)+         ; Set green value
move.b #0,(a1)+         ; to 0.
move.b #6,(a2)+         ; Set blue value
move.b #63,(a3)+        ; to 63.

You do not need to worry about command sequences that cross a scan line, the Grafitti card will handle this transparently. Also, to minimize the number of display lines used to initialize the palette, the full overscan display area can be used.

Starting The Chunky Mode

The final command in the palette sequence starts the display of graphics data. The command used will depend on the screen mode that and the version of the Grafitti card that are being used. If the low res version of the Grafitti card is being used, or if a screen mode is being used that would select a 320x256 graphics mode, the command must be an 8. The following sequence could be used to set this mode:


move.b #8,(a0)+         ; Start lores Graphics
move.b #0,(a1)+         ; This byte will be displayed as
                        ; graphics (Black in this case)

Using the 8 command, graphics can be started within a scan line. This is not possible when using the 24 command. The 24 command can only be used on the hi res version of the Grafitti card when the Amiga is displaying a screen mode that would select a 640x256 screen mode. The following sequence could be used to set this mode:

move.b #24,(a0)+        ; Start Hires Graphics
move.b #0,(a1)+         ; This byte must be 0, otherwise
                        ; random colours will be displayed

The remaining bytes in a scan line after the 24 command must be set to 0. If this is not done, the Grafitti card may behave unpredictably.

Using The Chunky Mode

Referring to the Graphics bitplanes I assume that the bitplane pointers now point to new locations.

If you are using 4 bitplanes, the graphics are displayed this way:

1st pixel is byte 0 in bitplane 0
2nd pixel is byte 0 in bitplane 1
3rd pixel is byte 0 in bitplane 2
4th pixel is byte 0 in bitplane 3
5th pixel is byte 1 in bitplane 0
6th pixel is byte 1 in bitplane 1
7th pixel is byte 1 in bitplane 2
8th pixel is byte 1 in bitplane 3
9th pixel is byte 2 in bitplane 0

and so on. The value of a byte represents the colour of the pixel. As you can see, the bitplanes are displayed in the sequence 0-1-2-3-0-1-2-3.

Using 2 bitplanes, the displaying sequence is 0-1-0-1-0-1..., in other words:

1st pixel is byte 0 in bitplane 0
2nd pixel is byte 0 in bitplane 1
3rd pixel is byte 1 in bitplane 0
4th pixel is byte 1 in bitplane 1
5th pixel is byte 2 in bitplane 0
6th pixel is byte 2 in bitplane 1
7th pixel is byte 3 in bitplane 0
8th pixel is byte 3 in bitplane 1
9th pixel is byte 4 in bitplane 0

Using a single bitplane, the bytes are completely linear aligned, no further explanation necessary, is it?

Speeding Up

The main design goal of the Grafitti card was to accelerate games and animation play back. The planar graphics architecture of the Amiga has proven to be too slow for these uses. However, this card still poses some of the same optimization problems to the programmer as the planar modes. This is mainly due to the limited bandwidth of the Amiga's chipmem.

On technique that can be used to boost performance is triple buffering. For systems that will always take more than one vertical blank to render a frame, the system will never need to wait for the end of a vertical field. When using three buffers, the first buffer is selected for display while the second buffer is being displayed. At this time, the system can immediatly start rendering to the third buffer.

If a mode that uses more than one bitplane is selected, rendering across a scan line can take much more time than rendering by column. This is usually only the case if you do not have four address registers available for pointing into the bit map. If enough address registers are available, it would be wise to partially unroll loops to make proper use of these registers. For example:

.loop:
                ...calculate the Nth pixel
                move.b  d0,(a0)+
                subq.l  #1,d7
                beq.b   .exit

                ...calculate the N+1th pixel
                move.b  d0,(a1)+
                subq.l  #1,d7
                beq.b   .exit

                ...calculate the N+2th pixel
                move.b  d0,(a2)+
                subq.l  #1,d7
                beq.b   .exit

                ...calculate the N+3th pixel
                move.b  d0,(a3)+
                subq.l  #1,d7
                bne.b   .loop
.exit:

This, however, can provide serious performance problems of its own. The largest problem in this case is the limited cache sizes of the 68020 and the 68030. The other problem with this method is the large number of byte accesses to chip memory. On an Amiga 1200, 3000, or 4000, a byte access to chip memory takes the same amount of time as a long word access. In this case it would be best to build four long words (16 pixels) of data at a time and write to the bit map using four long word moves. Quite possibly the single largets speed limiting factor is the bandwidth to chip memory. To this end, it is important to disable bitplane DMA where ever possible. This is especially the case on OCS/ECS Amigas.

Thanks to Jens Schoenfeld