AMOS:Working with bitplanes

From Amiga Coding
Jump to: navigation, search

Amiga 500 display

Amiga uses bitplanes, so instead of using one or more bytes per pixel, the screen is made of several layers (bitplanes).

Each pixel has only one bit by bitplane. So using only one bitplane in a screen, there are only two colors available for a pixel: the color of index 0 (bit=0) and the color of index 1 in the palette (bit=1). Using 2 bitplanes, there are 4 colors available for a pixel : index 0 (bit 0 and bit 0), index 1 (bit 1 and bit 0), index 2 (bit 0 and bit 1) and index 3 (bit 1 and bit 1 of both bitplanes). And so on.

The Amiga 500 has 6 bitplanes. So the color depth for a screen goes from 2 until 2 power 6=64 colors.

For every bitplane added, the maximum amount of colors doubles:

  • 2^1 = 2 = 2 colors
  • 2^2 = 2*2 = 4 colors
  • 2^3 = 2*2*2 = 8 colors
  • 2^4 = 2*2*2*2 = 16 colors
  • 2^5 = 2*2*2*2*2 = 32 colors
  • 2^6 = 2*2*2*2*2*2 = 64 colors

Example (taken from amcaf extension guide) :

We have an 16 colours screen. So it has got 4 bitplanes. Normally, the bitplanes are counted from 0 to n-1...

  Binary 0 1 0 1 = Decimal 5
         | | | |    .---v---v---v---v--------------------
         | | | `----+ 1 |   |   |   | Bitplane 0
         | | |      |--v^--v^--v^--v^--v-------------------
         | | `------+--+ 0 |   |   |   | Bitplane 1
         | |        |  |--v^--v^--v^--v^--v------------------
         | `--------+--+--+ 1 |   |   |   | Bitplane 2
         |          |  |  |--v^--v^--v^--v^--v-----------------
         `----------+--+--+--+ 0 |   |   |   | Bitplane 3
                    |  |  |  |---^---^---^---'
                    |  |  |  |
                    |  |  |
                    |  |

Note 1 : There are in fact 2 special modes : "Extra Half Bright" (64 colors so 6 bitplanes) and Hold And Modify (4096 colors)

Note 2 : if we consider chip memory, one byte in a bitplane is associated to 8 pixels.

If you want to know how many bytes a line takes in a bitplane use this formula:

size of one line within a bitplaneScreenWidth / 8
size of one bitplaneScreenWidth / 8 * ScreenHeight
Size of full pictureScreenWidth / 8 * ScreenHeight * AmountOfBitplanes

Reading and writing to a bitplane

AMOS brought to us the concept of screen : a number of bitplanes (between 1 and 6) with a dimension and a resolution (low, mid or high). Up to 8 different screens can be used at the same time and even displayed with different color depth and dimension at the same time. This powerfull function is actually possible because AMOS programs for us a lot of chipset registers using an important amiga coprocessor called the Copper.

By default, when executing code with the amos editor, a screen is already opened. It has the number 0 and the low resolution 320 x 200 in 16 colors. When we compile our amos code to amiga executable, a compiler option allows us to enable or disable this screen.

Here is a simple example using the ---Screen Open--- instruction.

Screen Open 0,320,100,32,lowres Screen Display 0,128,40,320,100 Screen Open 1,320,100,32,lowres Screen Display 1,128,150,320,100

We open 2 screens and displayed them at the same time, one below the other, with the Screen Display instruction. So we have two part of the global screen with independent 32 colors palette. It is simple and very powerfull thanks to Amos.

Moreover, for each screen, using the double buffer instruction, AMOS has two screen buffers, the physical and logical. The physical screen buffer is the one that's visible and in case you're using double buffered screens the logical contains the screen you're drawing on. You can get the address of these with =Phybase(bitplane) and =Logbase(bitplane). Bitplanes are counted from 0 to 5.

So say you want to copy a bitplane from an AMOS screen to an AMOS bank:

BitplaneSize = Screen Width / 8 * Screen Height

Reserve As Work 10,BitplaneSize Copy Phybase(0),Phybase(0)+BitplaneSize To Start(10) Wsave "RAM:Bitplane",10

Or do it the other way around and copy an bitplane from an AMOS bank to an AMOS screen:

BitplaneSize = Screen Width / 8 * Screen Height

Reserve As Work 10,BitplaneSize Wload "RAM:Bitplane",10 Copy Start(10),Start(10)+BitplaneSize To Phybase(0)

Note 3: the copy instruction uses the 68000. A coprocessor called Blitter knows also to play very well with bitplanes.

If we want to use the possibility of working on logical bitplanes of screen while physical ones are displayed, we have to use the Double Buffer instruction.

Screen Open 0,320,256,32,lowres Double Buffer In this example, Amos swaps automaticaly the logical and physical buffet at each VBL (50 times per second).

If we want to control the swap, the instuctions Autoback and Screen swap allows us to manage that.

Screen Open 0,320,256,32,lowres Double Buffer Autoback 0

Do ' do what you have to do (draw a 3D world ?) Screen Swap Wait vbl Loop In the loop (Do...Loop), at each vbl, physical bitplanes and logical ones are permuted.

Standard instructions like Screen Copy and Set Bob allow to manage bitplanes. Two important extensions : Turbo Extension (1993) and Amcaf (1994) add a lot of instructions to use bitplanes.

To finish with the current version of this small tutorial, here is more complete example mixing Amos screens (Copper), bitplanes and a bob (blitter object). I invite all Amos beginner to look in the manual for each instruction.

Screen Open 0,320,256,4,Lowres Screen Display 0,128,40,320,256 Curs Off : Flash Off : Hide : Rem No mouse, palette flash and curor Palette $0,$FFF,$FF,$FF0 : Paper 0 : Cls : Rem black screen with a simple palette

' Init of bob : a yellow transparent square movable with mouse ' The bob is transparent by playing with bitplane ' Amal is used to move the bob Ink 2 : Bar 0,0 To 32,32 : Get Bob 1,0,0 To 31,31 Cls 0

Double Buffer : Autoback 0 : Bob Update Off

Set Bob 1,,%10, Bob 1,,,1 Channel 1 To Bob 1 Amal 1,"S: L X=XS(0,XM); L Y=YS(0,YM); P; J S" Amal On 1

X=0 L=64

Do Cls 0

' We draw a square of LxL dimension at the x horizontal position Ink 1 : Bar X,100 To X+L,100+L ' draw the transparent bob Bob Draw

X=X+2 If X>Screen Width-L Then X=0

Screen Swap Wait Vbl Loop