Revised on Jun 28th, 2000 (removed passages concerning hires- and lores version, because there is only one version, the hires one!) Earth, Germany, Aachen, September '95 Documentation for the Graffiti Gfx card for OCS/ECS/AGA Amigas "Someone said, that programmers can't make readable manuals. Here's one from a hardware designer, so don't wonder if it's a complete disaster". 1. What it does Graffiti changes the Amiga bitplaned graphics into a chunky pixel mode. I.e. one byte in memory represents a single pixel. The value of a byte selects it's colour. The colour palette is 256 out of 262144 at a time. Possible resolutions are 640x256, 320x256, 160x256 and 80x256. In each mode, 256 colours are available, interlacing doubles the vertical resolution. 2. How to connect The Graffiti card plugs into the RGB port of the Amiga. The monitor must be connected to the RGB output of the Graffiti, there's no need to open the computer. DIP switches or jumpers are set as described in the manual. 3. System requirements, compatibility, limits The hardware has been successfully tested with all known Amiga models: A500, A600, A1200, A2000, A2500, A3000, Amiga CDTV and the A4000. Even "the" Amiga (later called the Amiga 1000) has been sucsessfully tested. For displaying the output, a standard 15khz RGB-Monitor like the commodore 1081 and 1084 models is required. The commodore A2024 is not supported. The Graffiti is PAL and NTSC compatible. For full speed advantages, AGA Chipset or the A3000 are recommended. For more speed, accelerator cards with burstmode fastmem are recommended. Due to the limited bandwidth of the chipmemory, the frame rate of a motion sequence is limited. At about 7MB/s on AGA-chipsets using 4 Bpls hires, with longword-access about 74 frames/s can be transferred - more than required. Using word access, it's reduced to about 37 frames/s, and with byte access only 18 frames/s are possible, so setting up longwords in the processor registers or in fastmem is recommended. (Numbers assuming a 384x256 window). Using the 160x256 pixel mode or the 80x256 pixel mode, the chunky buffer is completely linear, so you can access four pixels in a row with a single longword move. Colour #0 of the Graffiti (external palette, see further down) must always be set to black (R=G=B=0), because of some monitors trying to adapt to a 0- level after Hsync. This causes vertical brightness fading in the first lines if colour#0 is not set to black. It's different on different monitors, so this cannot be used as an effect. 4. Activating the card, word definitions To activate the card, switch to a hires or SHires screen at 1, 2 or 4 bitplanes, depending on the resolution you want to display. Set the genlock audio bit to 1, otherwise the standard Amiga bitplaned graphics will be displayed. The Graffiti card has got it's own color palette that is called "external palette" from now on. The Amiga-palette that is set in denise/lisa will be called "internal palette". While displaying the chunky pixel mode, the internal palette must be set to one of the following: 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 The See appendix A for softscroll-values and Dip-Switch settings. While displaying a chunky pixel mode, the internal palette and the X- Offset of the bitplanes must not be changed, otherwise the Graffiti does undefined things (don't worry, it won't toast your hamster). Choosing 4 bitplanes hires or 2 bitplanes SHires sets the Graffiti to 320x256 pixel. Setting up 2 bitplanes hires or 1 Bitplane SHires selects 160x256 pixel, and a single bitplane hires selects the 80x256 mode. The highest resolution available is 4 Bitplanes SHires, resulting in a display of 640x256 pixel. The Graffiti is overscan-compatible, so up to 768 pixel and more than 512 lines are possible (depends on PAL or NTSC modes, interlaced or non-interlaced). 5. 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, meaning the bitplane data is interpreted as commands, not as Gfx data. In command mode, the Graffiti shows a black screen, so transferring the palette is invisible for the user. Note that when interlacing, a VBlank splits the two half screens, so you have to send start-Graphic commands every half frame. Commands can only be sent within 4 Bitplanes Hires with the corrosponding internal palette set. A command is composed of two bytes, the command byte and the parameter byte. There are 6 commands: 0 NOP No operation, parameter is ignored. 4 Set colour Parameter sets colour to be set next. 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). 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 ne any ; value. The pixel read mask register can be used for effects, see chapter 8 for suggestions. This should be the first command in a palette sequence. Addressing with postincrement and arranging in Blocks of four sequential move.b's has been proved to be very distinct. 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. The next example sets color #23 to a light blue: 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 don't have to worry if a command sequence crosses a scanline, this can be handled by the Graffiti card. This enables the programmer to set the palette using only the postincrement-moves. To reduce the number of lines for transferring the palette, the complete overscan can be used. The last command in the palette sequence depends on the screenmode you want to display: 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 line, which is not possible with the 24 command: move.b #24,(a0)+ ; Start Hires Graphics move.b #0,(a1)+ ; This byte must be 0, otherwise ; random colours will be displayed The rest of the bytes in the line must be set to 0 if the 24 command is not the last in a line. 6. Using the chunky mode Referring to the Graphics bitplanes I assume that the bitplanepointers now point to new locations in memory, the GFX location (not the commands!). 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? 7. Speeding up I'm no programmer at all, all I can do is some move's, 6502 assembler and boolean equations, so don't take my suggestions too seriously. The aim of the design was to speed up games and animation players, because bitplaned graphics take more CPU time to modify than chunky graphics. However, optimizing your code is still necessary, because fast CPUs are still no standard in the Amiga world. One main problem ist the bandwidth of the chipmem, which is discussed in chapter 3. When playing back animation sequences, triple buffering can speed up, because you don't have to wait for the displaying hardware to display your already-made second picture, which is necessary if you only use two buffers. Using three buffers, you can start drawing the second picture after the one being displayed, so your CPU is not idle. If your routine sometimes takes several frames to render a frame, and sometimes only some scanlines, more buffers could be useful, you have to find this out on your own. If you are using more than one bitplane, horizontal rendering takes much more time than vertical rendering, because you have to spread the data over the bitplanes. If you start four (or two, depending on the number of bitplanes you're using) vertical renderers, each of them can work in its own bitplane, so spreading the data is not necessary. On OCS/ECS machines 4 bpls hires kills bandwidth on chipmem, so turn off the DMA where you can! 8. Suggestions for effects Hardware sprites can be used as objects, but their X-position must be set in 8-hires-pixel-steps (lores display) or 8-SHires-pixel-steps (hires display using SHires bitplanes). As you can see, this is only possible on AGA-machines, the OCS/ECS only allows lores sprites, which is useless for the Graffiti. Set the same number of bitplanes and the same internal colour palette for the sprites. The Graffiti GFX card cannot keep sprite data apart from bitplane data, so sprites use the same external colour palette. If you choose a 16-colour sprite to be 16 pixel wide, the output will be 8 pixel wide. You can also use sprites to increase resolution temporarily: If you're using 2 hires-bitplanes (160 pixel output), a 16- colours sprite will display in standard lores. Problem: The sprite background (the bytes that are covered by the sprite) must be empty, i.e. before you can display a sprite, you have to clear the area it will cover, so this is only useful for small moving objects without a background, or 32-colour sprites with the other 16 colours of the internal palette set to black. Fading in/out I can imagine that 18 bit colour fading looks pretty neat. Due to the fact that the external palette is transferred as GFX data, you can use a single move into the copperlist to choose another colourtable. If you have pre- calculated fading tables, this won't take too much CPU time :-). Hazy picture (Cmdr. La Forge, your visor is dead!) Swapping bitplanes causes pixels to be swapped. If you swap bitplanes 0 and 2 of a 4-bitplane-display every 2nd line, the picture will look hazy as if your glasses are smutty. Changing the bitplanes to be swapped every frame will look like picture noise. You can underline this effect by switching to a grey scale palette. All this can be done by copper - hey, I could do that, too! The Pixel read mask register can be used to reduce the maximum # of colours to be displayed. This is achieved by gating the bytes in the bitplanes with the contents of the pixel read mask register. The operation is a bitwise logical ANDing. The pixel masking operation can be used to alter the displayed colours without changing the contents of the external palette. The effect of this operation is to partition the external palette into a number of colour planes. This can be used for flashing objects, animation or overlays - without software overhead. What about dot-landscapes? Setting a dot means a single move.. It's up to you! Appendix A: Dip switch settings and softscroll-offsets To be compatible to every chipset there is, the programmer has do detect on which machine his program runs on. You can find the version numbers of the chips in some variables of the gfxbase.h (I'd be pleased if someone made a chapter out of this sentence!). AGA machines: Dip 1 = on, Dip 2 = off, Softscroll = 0 OCS/ECS machines: Dip 1 set according to manual, Dip 2= off. Later versions of the Graffiti only have one Jumper. That jumper does the same as Dip 1. Dip 2 never has to be set "on", so a second jumper is not necessary. If you have any questions, feel free to ask via e-mail: jens@siliconsonic.de