 _________________________________________________________________________
/#########################################################################\
|#####...####..######..######......####...####..#####..##......##......###|
|####.....###..######..########..#####.....###...####..##..######..#######|
|###..###..##..######..########..####..###..##....###..##..######..#######|
|###..###..##..######..########..####..###..##..#...#..##..######......###|
|###.......##..######..########..####.......##..##.....##..######..#######|
|###..###..##..######..########..####..###..##..###....##..######..#######|
|###..###..##...#####...#######..####..###..##..####...##..######..#######|
|###..###..##......##......##......##..###..##..#####..##......##......###|
|#########################################################################|
|####################################################################{RB}#|
|=========================================================================|
|									  |
|		           ----> PRESENTS <----				  |
|									  |
|            AMIGA GRAPHICS INSIDE AND OUT - THE COMPLETE BOOK            |
|									  |
| 				> PART 6 <				  |
|									  |
| Typed / Scanned / Edited By : RAZOR BLADE.			          |
| Additional Typing by        : GLITCH ( + 8 pages by Asterix ! ).	  |
| Original Supplied by	      : VIPER					  |
|									  |
|-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-|
| 		CALL THE ALLIANCE WORLD HQ -> THE PLACE TO BE             |
|       UNKNOWN PLEASURES --> +44 (0) 823 322 891 --> SYSOP: BARBARIAN    |
|_________________________________________________________________________|

-----------------------------------------------------------------------------

18.3 AnimObs and AnimComps

Displaying only "static" bobs isn't very exciting. Because of this, a 
special animation system was created specifically for bobs. At the 
beginning of this C language section, you learned one method of animation 
called "color cycling" or color animation. We cycled, or scrolled, the colors 
in the color registers. The contents of the preceding register were 
exchanged for the contents of the current register, etc.

You also learned a second type of animation. When you moved your bobs and 
vsprites they were also animated. You may be thinking that a 
Commodore 64 is also able to do this. Although this is true, the Amiga is 
also capable of animating bobs using the operating system software and 
drawing a bob in different sequences without any commands.

The Amiga can recognise Animation Objects called AnimObs. We define 
AnimObs with AnimationComponents, which are named AnimComps. The AnimComps 
contain our defined bobs. For example, you could create the flight of a 
seagull with different bob sequences. Then you could link these bobs with 
the AnimComps and create an AnimOb.


The first step of this process is to create all your bobs as you usually do. 
In addition to the flags, you must determine how the bob is written into 
the bit-map (OVERLAY, SAVEBACK, etc.) and set the bobs

				PAGE 479

-----------------------------------------------------------------------------

BOBISCOMP flag. This tells the animation software that your bob is an 
animation component. You must also tell the system to which animation 
component your bob belongs. To do this, set the pointer Bob.BobComp for 
the corresponding Animcomp structure. Each animated bob requires its 
own AnimComp structure.

To link the AnimComps together, use the pointers AnimComp.NextComp and
AnimComp.PrevComp. These two pointers point to the previous and next 
AnimComps. Be careful because When you create a loop here it should 
point only to a single AnimComp. Also, for all other AnimComps, you must 
set these pointers to zero. If you don't do this, the system will think 
that an AnimComp in the sequence points to a second bird instead of to the 
one now animated.

Next there is the pointers NextSeq and PrevSeq. From one position you can 
define many positions (as bobs) and then have the animation system page 
through your sequences. This is similar to the old "Thumb movie books" 
which simulated animation when you rapidly paged through a series of 
pictures. Each new page of the bob creates the animation effect.

The next step is to set the sequence to cycle the pages. The pointers 
NextSeq and PrevSeq point to the next and previous page or AnimComp. 
These pointers create a closed ring. This means that you connect all the 
AnimComps to each other with the pointers NextSeq and PrevSeq. The 
previous AnimComp for the first AnimComp is the last AnimComp. 
The next AnimComp from the last AnimComp is the first AnimComp.

				PAGE 480

-----------------------------------------------------------------------------

Setting the RINGTRIGGER flag in the AnimComps(AnimComp.Flags = RINGTRIGGER), 
which defines the ring, klls the system to flip the pages for the different 
AnimComps. You can also set the length of time a specific AnimComp should be 
displayed.

The variable AnimComp.TimeSet determines for how many Animate calls the 
AnimComp will remain visible (Animate is the system routine that uses the 
AnimObs). Animate copies the variable TimeSet to the variable Timer at the 
beginning of a sequence. Timer is decremented with each Animate. Whenever 
Timer equals zero, the next AnimComp in the sequence is displayed.

Now we will continue to define AnimComps and AnimObs. Just as a bob must 
know which AnimComp it belongs to, the AnimComp must also know which bob it 
represents. To accomplish this we point the AnimComp.AnimBob poinkr to the 
specific bob.

To add something special, you can also specify one of your own routines 
that will be executed each time you call Animate to display your AnimComps. 
The pointer AnimComp.AnimCRoutine points to your function. Simply set this 
pointer to zero when you haven't

				PAGE 481

-----------------------------------------------------------------------------

defined a function. When using this function you must remember that it 
returns a word value to your program. This value is not passed to the 
system. Because this declaration affects the AnimComp structure, you should 
check the returned value for any warning from the compiler.

Similar to the collision routines that are used with vsprites and bobs, 
your functions can use the current AnimComp structure. For example, they 
can check for a position and determine a specific action, or determine 
object distances and react.

We are almost finished with our discussion of the AnimComp structure. But 
before we explain our last point, we will discuss the AnimOb structure .

The AnimOb structure can contain many sequence rings. For example, it can 
contain the arms, legs, body and the head of a man. All of these are 
connected to each other and are able to move independently. We define the 
components as a ring sequence which is automatically sequenced by Animate. 
We represent the body with a single AnimComp structure because the body 
itself usually does not move while walking.

The two pointers PrevComp and NextComp point to the AnimComps that display 
the front and back view of the man. To link the AnimComps with the AnimOb 
we use another pointer in the AnimOb structure. The pointer AnimOb.HeadComp 
poinls to the first AnimComp that contains the rest of the objects. 
(You link the components together with PrevComp and NextComp). Each 
AnimComp contains a pointer back to the AnimOb. The pointer AnimComp.HeadOb 
always points to the AnimOb in which the AnimComps are included. 
This way you can easily access, with your routines, the required AnimOb 
through the AnimComp structure.

However, more is required in order to initialise an animOb structure. 
We still must determine where the structure will appear on the scrcen. 
To solve this problem we use the variables Animob.Anx and AnimOb.AnY. 
You cannot specify a coordinate using, for example, 160,100. 
To specify the Animob coordinates, you must use a type of fixed decimal 
method. The lower six bits are positioned after (to the right of) the decimal 
point. To position your Animob you must multiply the RastPort coordinate 
by 64.

You may be wondering why we are using such a strange positioning method. 
However, remember that these variables set not only the objects' position 
but also the velocity.

With each call of Animate the values from AnimOb.XAccel and AnimOb.YAccel 
(X/Y movement) are added to AnimOb.XVel and

				PAGE 482

-----------------------------------------------------------------------------

AnimOb.YVel (speed). The speed is then added to the position set by 
AnimOb.Anx and AnimOb.AnY.

Using normal pixel values for position, speed, and movement could make your 
Animob race across the screen. However, it wouldn't be very useful to have 
Animob that disappears from the screen after the fifth call to Animate. 
To prevent this, an Animob is moved only one pixel for every 64.

At first, it seems like this will be a problem. Multiplying by 64 is 
possible, but using normal methods to move our Animob anywhere in
a RastPort presents a challenge. For the positions (Anx and Any) we have #
only 16 bits available. Normally this would provide values from -32768 to 
+32768. But dividing this value by 64, gives us a range of -512 to +512. 
So in order to position an object at an X coordinate of 629 in a hi-res 
RastPort we have to  use a trick instead of the normal methods.

We can now explain the last feature of AnimComps. It is possible to specify 
the position of the individual animation components relative to animation 
objects (also in steps of 64).

When you use an offset of 128*64 in AnimComp.XTrans for your animation 
components you can reach any coordinate on the screen. Set positions smaller 
than 128 (values between -128 and zero) in AnimOb.AnX. Values between -512 
and +512 for the Y position work in any resolution. To set your components 
relative Y positions, use the variable AnimComp.YTrans.

Two other variables that can be used to position an object are RingxTrans 
and RingYTrans. Simply add, wilhout any changes, the value of these variables 
to the current position. If you do not require any speed or motion, just 
set the corresponding AnimOb variables(Xvel, YVel, XAccel and YAccel ) equal 
to zero. Then initialise RingXTrans and RingYTrans with your desired values. 
Make sure your speed is uniform otherwise it will affect your animation 
sequences. You must synchronize the internal movements of an object 
(like the wings of a bird or rotation of a wheel) with any position changes. 
For example, the rotation of a wheel being slower than the forward movement 
as you increase the forward speed and the wheel always rotates at the same 
speed.

You can also specify a routine for your animation object that is called by 
Animate. The poinler for this routine is named AnimORoutine. It is also of 
the type word and you must specify the AnimOb, not the component

				PAGE 483

-----------------------------------------------------------------------------

Now that we have initialised all the animation structures, the bob, 
the component and the object, the only thing left to do is to display it on 
the screen.

Again we need a completely initialised GelsInfo structure used for bobs and #
linked with a RastPort.

By using AddAnimOb(&AnimOb,&Key,&RastPort) we add all bobs and components of 
the AnimOb to the GelsInfo structure. A required entry named Key is simply a 
pointer to an AnimOb (struct AnimOb *Key = 0) that must be set to zero for 
the first AddAnimOb call.

Because a list doesn't exist for the Animobs, you must know which AnimOb was 
entered last in the GEL list. This helps ensure that the objects have been 
properly linked. Also link the Animobs together by using the Animob.PrevOb 
and AnimOb.NextOb pointers. The Key always points to the last entered Animob.

AddAnimOb handles more than linking the objects and entering the bobs in the 
GEL list. It also sets the Timer variable for the AnimComps to the value 
previously set in TimeSet. This permits decrementing the Timer.

Once you have processed all of the Animobs wilh AddAnimOb you are ready to 
begin. Call Animate and the Timer variable for the current AnimComps is
decremented. When Timer == 0 the next sequence is activated. The position 
controlled by RingXTrans, RingYTrans, Xvel, YVel, XAccel, YAccel, Xtrans and 
YTrans is Calculated and then used lo display the next bob.

When you call SortGList and DrawGList as usual, your AninObs are displayed on 
the screen.

18.3.1  Collisions with AnimObs

Because the smallest element used to display AnimObs are bobs, you can also 
use them for collision control. Set the HitMask and Memask in the vsprite 
structure of the bobs (using the same values for all bobs in one AnimComp 
loop). Then you use SetCollision with your routine and test for collisions.

We have provided another example program so that you can actually see what 
happens. This animation displays a flying seagull with flapping wings 
(in one Animob):

				PAGE 484

-----------------------------------------------------------------------------

/****************************************************************/
/*                              LetsAnimate.c                   */
/*                                                              */
/* This program displays and moves an Amiga AmimOb              */
/* (here a Segull and uses AnmiComps (different                 */
/* wing positions                                               */
/* Compiled with Aztec C V3.6a                                  */
/*              cc +L -S LetsAnimate.c                          */
/*              ln LetsAnimate.o -1c32                          */
/* (c) Program by Bruno Jennrich, Idea and Artwork by           */
/* my little sister Ute.                                        */
/****************************************************************/

#include        "exec/types.h"
#include        "exec/memory.h"
#include        "exec/devices.h"
#include        "devices/keymap.h"
#include        "graphics/gfx.h"
#include        "graphics/gfxmacros.h"
#include        "graphics/copper.h"
#include        "graphics/gels.h"
#include        "graphics/gfxbase.h"
#include        "graphics/regions.h"
#include        "hardware/blit.h"
#include        "hardware/custom.h"
#include        "intuition/intuition.h"
#include        "intuition/intuitionbase.h"
#include        "libraries/diskfont.h"
#include        "hardware/dmabits.h"

extern WORD MoveSeagull();              /*User AnimOb-Routine   */
/* extern WORD Comp();          Optional AnimComp Routine       */

#define RP Screen->RastPort             /* Pointer to RastPort  */
#define MAXBOBS 8                       /* Seagull in in 8 Positions */

#define MAXCOORDS (MAXBOBS*2-2)         /* Sequence consists of */
					/* 14 pictures: 8 'to'  */
					/* and 6 'back'.        */

struct GfxBase *GfxBase;                /* BasePointer          */
struct IntuitionBase *IntuitionBase;

struct NewScreen NewScreen =            /* User Screen          */
		{
		0,0,640,200,1,
		1,0,
		HIRES,
		CUSTOMSCREEN,
		NULL,
		"",
		NULL,NULL
		};

struct Screen *Screen;

struct VSprite Start, Ende,             /* VSprites for GEL     */
	BobsVSprite[MAXCOMPS];          /*List and Bobs         */

struct Bob Bobs [MAXCOMPS];             /* User Bobs            */
					/* Note: 6 Bobs have the*/
					/* same image!!!        */

				PAGE 485

-----------------------------------------------------------------------------

UWORD   *BobBuffer;
	/* MAXBOBS Bobs, 20 Lines of 3 WORDs for        */
	/* one BitPlane */

	/* memory area for SAVEBACK                     */
	/* In this example one buffer                   */
	/* is enough, but because of                    */
	/* the principle and to simply                  */
	/* use new and other Bobs,                      */
	/* we have given each Bob a                     */
	/* 'SaveBuffer'                                 */

UWORD   *BobMask;                       /* Bob collisions-Masks */
					/* Memory               */
					/* (20 Lines * 3 Words) */

UWORD   BobBorderLine[MAXCOMPS][3];     /* Bobs Borderline      */
					/* Memory               */
					/* logical OR of all    */
					/* Bob lines in one     */
					/* line (here:3 Words)  */

/*extern struct Custom custom;          in custom.h */
					/* pointer to Hardware  */
					/* Register for Copper  */

struct UCopList *UCopList;              /* own Copper List      */

struct  AnimComp AnimComp[MAXCOMPS];
					/* seagull 'back and forth     */
					/* bit Start (Sequence 1) and  */
					/* end position (Sequence8)    */
					/* appear in each sequence     */
					/* only once, not twice        */
					/* like the other positions    */
					/* for the Seagull             */

struct AnimOb *HeadOb = 0,              /* Animations Key              */
	Seagull;                        /* our Seagull                 */

struct GelsInfo GelsInfo;               /* GelsInfo initialization     */
					/* must be completed before    */
					/* using the Animation         */
					/* routine!                    */

UWORD   *Image,*Help;
UWORD   BobImage[MAXBOBS][20][3] =
		{{

		{0x0080,0x0000,0x0100}, /* Data for                     */
		{0x0080,0x0000,0x0100}, /* Bob1. Only one               */
		{0x00c0,0x0000,0x0300}, /* BitPlane per                 */
		{0x0040,0x0000,0x0200}, /* Bob                          */
		{0x0060,0x0000,0x0600},
		{0x0030,0x0000,0x0c00}, /* Please use the               */
		{0x0010,0x0000,0x0800}, /* copy function                */
		{0x0018,0x0000,0x1800}, /* of your editor               */
		{0x000c,0x0000,0x3000}, /* and save                     */
		{0x0004,0x0000,0x2000}, /* yourself a lot               */
		{0x0006,0x0000,0x6000}, /* of work!                     */
		{0x0003,0x0000,0xc000},
		{0x0001,0x8001,0x8000},
		{0x0000,0xc003,0x0000},
		{0x0000,0x700e,0x0000},

				PAGE 486

-----------------------------------------------------------------------------

		{0x0000,0x1c38,0x0000}, /* Here is where                */
		{0x0000,0x0660,0x0000}, /* the data                     */
		{0x0000,0x0180,0x0000}, /* for more                     */
		{0x0000,0x0180,0x0000}, /* BitPlanes                    */
		{0x0000,0x0180,0x0000}  /* follows                      */
	},
	{
		{0x0000,0x0000,0x0000}, /* Data for                     */
		{0x0000,0x0000,0x0000}, /* Bob2. Only one               */
		{0x0200,0x0000,0x0040}, /* BitPlane.                    */
		{0x0100,0x0000,0x0080},
		{0x0080,0x0000,0x0100},
		{0x0060,0x0000,0x0600},
		{0x0030,0x0000,0x0c00},
		{0x0018,0x0000,0x1800},
		{0x000c,0x0000,0x3000},
		{0x0006,0x0000,0x6000},
		{0x0003,0x0000,0xc000},
		{0x000l,0x8001,0x8000},
		{0x0000,0xe007,0x0000},
		{0x0000,0x300c,0x0000},
		{0x0000,0x1818,0x0000},
		{0x0000,0x0c30,0x0000}, /* Here is where                */
		{0x0000,0x0660,0x0000}, /* the data                     */
		{0x0000,0x0180,0x0000}, /* for more                     */
		{0x0000,0x0180,0x0000}, /* BitPlanes                    */
		{0x0000,0x0180,0x0000}  /* follows                      */
	},
	{
		{0x0000,0x0000,0x0000}, /* Data for                     */
		{0x0000,0x0000,0x0000}, /* Bob3. Only one               */
		{0x0000,0x0000,0x0000}, /* BitPlane.                    */
		{0x0f00,0x0000,0x00f0},
		{0x00c0,0x0000,0x0300},
		{0x0060,0x0000,0x0600},
		{0x0018,0x0000,0x1800},
		{0x0006,0x0000,0x6000},
		{0x0003,0x0000,0xc000},
		{0x0001,0x8001,0x8000},
		{0x0000,0x4002,0x0000},
		{0x0000,0x2004,0x0000},
		{0x0000,0x1008,0x0000},
		{0x0000,0x0810,0x0000},
		{0x0000,0x0c30,0x0000},
		{0x0000,0x0660,0x0000}, /* Here is where                */
		{0x0000,0x0240,0x0000}, /* the data                     */
		{0x0000,0x03c0,0x0000}, /* for more                     */
		{0x0000,0x0180,0x0000}, /* BitPlanes                    */
		{0x0000,0x0180,0x0000}  /* follows                      */
	},
	{
		{0x0000,0x0000,0x0000}, /* Data for                     */
		{0x0000,0x0000,0x0000}, /* Bob4. Only one               */
		{0x0000,0x0000,0x0000}, /* BitPlane.                    */
		{0x0000,0x0000,0x0000},
		{0x3000,0x0000,0x000c},
		{0x0f80,0x0000,0x01f0},
		{0x0070,0x0000,0x0e00},
		{0x000c,0x0000,0x3000},
		{0x0003,0x0000,0xc000},
		{0x0001,0x8001,0x8000},
		{0x0000,0x6006,0x0000},
		
				PAGE 487

-----------------------------------------------------------------------------

		{0x0000,0x300c,0x0000},
		{0x0000,0x1818,0x0000},
		{0x0000,0x0c30,0x0000},
		{0x0000,0x0420,0x0000},
		{0x0000,0x0240,0x0000}, /* Here is where                */
		{0x0000,0x03c0,0x0000}, /* the data                     */
		{0x0000,0x0180,0x0000}, /* for more                     */
		{0x0000,0x0180,0x0000}, /* BitPlanes                    */
		{0x0000,0x0180,0x0000}  /* follows                      */
	},
	{
		{0x0000,0x0000,0x0000}, /* Data for                     */ 
		{0x0000,0x0000,0x0000}, /* Bob5. Only one               */ 
		{0x0000,0x0000,0x0000}, /* BitPlane.                    */
		{0x0000,0x0000,0x0000},
		{0x0000,0x0000,0x0000},
		{0x0000,0x0000,0x0000},
		{0x7ff0,0x0000,0x0ffe},
		{0x800f,0x0000,0x7001},
		{0x0003,0x8001,0xc000},
		{0x0000,0xc003,0x0000},
		{0x0000,0x2004,0x0000},
		{0x0000,0x1818,0x0000},
		{0x0000,0x0810,0x0000},
		{0x0000,0x0420,0x0000},
		{0x0000,0x0660,0x0000},
		{0x0000,0x0240,0x0000}, /* Here is where                */
		{0x0000,0x0180,0x0000}, /* the data                     */
		{0x0000,0x0180,0x0000}, /* for more                     */
		{0x0000,0x0180,0x0000}, /* BitPlanes                    */
		{0x0000,0x0180,0x0000}  /* follows                      */
	},
	{

		{0x0000,0x0000,0x0000}, /* Data for                     */
		{0x0000,0x0000,0x0000}, /* Bob6. Only one               */
		{0x0000,0x0000,0x0000}, /* BitPlane,                    */
		{0x0000,0x0000,0x0000},
		{0x0000,0x0000,0x0000},
		{0x0000,0x0000,0x0000},
		{0x0000,0x0000,0x0000},
		{0x07e0,0x0000,0x07e0},
		{0x3c3e,0x0000,0x7c3c},
		{0x4003,0x8001,0xc001},
		{0x0000,0x6006,0x0000},
		{0x0000,0x300c,0x0000},
		{0x0000,0x1818,0x0000},
		{0x0000,0x0420,0x0000},
		{0x0000,0x0660,0x0000},
		{0x0000,0x03c0,0x0000}, /* Here is where                */
		{0x0000,0x0180,0x0000}, /* the data                     */
		{0x0000,0x0180,0x0000}, /* for more                     */
		{0x0000,0x0180,0x0000}, /* BitPlanes                    */
		{0x0000,0x0180,0x0000)  /* follows                      */
	},
	{
		{0x0000,0x0000,0x0000}, /* Data for                     */
		{0x0000,0x0000,0x0000}, /* Bob7. Only one               */
		{0x0000,0x0000,0x0000}, /* BitPlane.                    */
		{0x0000,0x0000,0x0000},
		{0x0000,0x0000,0x0000},
		{0x0000,0x0000,0x0000},
		{0x0000,0x0000,0x0000},

				PAGE 488

-----------------------------------------------------------------------------

		{0x03fc,0x0000,0x3fc0},
		{0x0c0f,0x8001,0xe030},
		{0x1000,0xe007,0x0008},
		{0x2000,0x6003,0x0004},
		{0x2000,0x1818,0x0004},
		{0x0000,0x0c60,0x0000},
		{0x0000,0x0660,0x0000},
		{0x0000,0x0240,0x0000},
		{0x0000,0x0240,0x0000}, /* Here is where                */
		{0x0000,0x0180,0x0000}, /* the data                     */
		{0x0000,0x0180,0x0000}, /* for more                     */
		{0x0000,0x0180,0x0000}, /* BitPlanes                    */
		{0x0000,0x0180,0x0000}  /* follows                      */
	},
	{
		{0x0000,0x0000,0x0000}, /* Data for                     */
		{0x0000,0x0000,0x0000}, /* Bob8. Only one               */
		{0x0000,0x0000,0x0000}, /*BitPlane.                     */
		{0x0000,0x0000,0x0000},
		{0x0000,0x0000,0x0000},
		{0x0000,0x0000,0x0000},
		{0x0000,0x0000,0x0000},
		{0x0000,0x0000,0x0000},
		{0x0000,0x0000,0x0000},
		{0x0lfe,0x0000,0x7f80},
		{0x0301,0xc003,0x80c0},
		{0x0400,0x6006,0x0020},
		{0x0800,0x1818,0x0010},
		{0x0800,0x0c30,0x0010},
		{0x1000,0x0420,0x0008},
		{0x1000,0x03c0,0x0008},
		{0x1000,0x0180,0x0008), /* the data                     */
		{0x0000,0x0180,0x0000}, /* for more                     */
		{0x0000,0x0180,0x0000}, /* BitPlanes                    */
		{0x0000,0x0180,0x0000}  /* would follow                 */
		}
	};

main()
{
	int i,j,k;
	char*LeftMouse = (char*)0xBFE001;
					/* Left mouse button*/
	if ((GfxBase = (struct GfxBase *)
		OpenLibrary("graphics.library",0)) == NULL)
		{
		   printf ("No Graphics !!!\n");
		   exit(0);
		}

	if ((IntuitionBase = (struct IntuitionBase *)
		OpenLibrary("intuition.library",0)) == NULL)
		{
		   printf ("No Intuition !!!\");
		   goto cleanup2;
		}

	if((Screen = (struct Screen *)
		OpenScreen(&NewScreen)) == NULL)
		{
		   printf ("No Screen !!!\n);
		   goto cleanup3;

				PAGE 489

-----------------------------------------------------------------------------

		}

	BobBuffer = (UWORD*) AllocMem(MAXCOMPS*20*3*sizeof(UWORD), 
				MEMF_CLEAR | MEMF_CHIP);

	BobMask = (UWORD*) AllocMem(MAXCOMPS*20*3*sizeof(UWORD), 
				MEMF_CLEAR | MEMF_CHIP);

	Image = (UWORD*) AllocMem(MAXBOBS*20*3*sizeof(UWORD), 
				MEMF_CLEAR | MEMF_CHIP);

	if ((Image == 0) | (BobBuffer == 0) | (BobMask == 0))
		{
		 printf ("No Chip Memory !!\n");
		 goto cleanup4;
		}

	Help = Image;

	for (i=0; i<MAXBOBS;i++)
	    for (j=0;j<20;j++)
		for (k=0;k<3;k++)
		    {
			*Help = BobImage[i][j][k];
			Help++;
		    }

	SetRGB4(&Screen->ViewPort,0,2,8,151); 
	SetRGB4(&Screen->ViewPort,1,0,0,0,);

	SetRast (&RP,0);

	BltClear (&Start, sizeof(struct VSprite),0); 
	BltClear (&Ende, sizeof(struct VSprite),0); 
	BltClear (&GelsInfo, sizeof(struct GelsInfo),0); 
	BltClear (BobsVSprite,
		sizeof struct VSprite)*MAXCOMPS,0); 
	BltClear (Bobs,
		sizeof(struct Bob)*MAXCOMPS,0);
	BltClear (AnimComp,
		 sizeof(struct AnimComp)*MAXCOMPS,0);

	BltClear (&Seagull, sizeof(struct AnimOb),0);

/*****************************************************************/
/* A little Copper-Power                                         */
/*****************************************************************/

UCopList = (struct UCopList *)
    AllocMem (sizeof(struct UCopList),
		MEMF_CHIP | MEMF_CLEAR);

CWAIT (UCopList,150,0);
CMOVE (UCopList,custom.color[0]),0x000f);               /* Sea */
CEND (UCopList);

Screen->ViewPort.UCopIns = UCopList;
					/* Copper list linked           */
RemakeDisplay();                        /* and calculate new            */
	
/****************************************************************/
   GelsInfo.sprRsrvd = 0xff;         /* All Sprites for VSprites*/

				PAGE 490

-----------------------------------------------------------------------------

				     /* Memory for Gelinfo reserved */ 

GelsInfo.nextLine = (WORD *)AllocMem(sizeof (WORD)*8,
		MEMF_PUBLIC | MEMF_CLEAR );

GelsInfo.lastColor = (WORD *)AllocMem(sizeof (LONG)*8, 
		MEMF_PUBLIC | MEMF_CHIP);

GelsInfo.collHandler = (struct collTable *) 
		AllocMem(sizeof (struct collTable),
		MEMF_PUBLIC | MEMF_CLEAR);

if ((GelsInfo.nextLine == 0) | (GelsInfo.lastColor == 0) |
	(GelsInfo.collHandler == 0))
	{
	printf (" No Memory for GelsInfo !!!\n");
	goto cleanup5;
	}

	GelsInfo.leftmost = 0;                  /* Boundary Collisions */        
	GelsInfo.rightmost = 640;               /* Border collisions */       
	GelsInfo.topmost = 0;
	GelsInfo.bottommost = 200;

	InitGels(&Start, &Ende, &Gelsinfo);
						/* GelsInfo initialization */ 
	RP.GelsInfo = &GelsInfo;                /* and in RastPort linked  */

	for (i=0; i<MAXBOBS; i++)
	    {
		Bobs[il.BobVSprite = &BobsVSprite[i];
		BobsVSprite[i].VSBob = &Bobs[i];
		BobsVSprite[i].Width = 3;       /* All Bobs are       */
		BobsVSprite[i].Height = 20;     /* the same size      */
		BobsVSprite[i].Flags = SAVEBACK;
						/* Store background     */
						/* (in BobBuffer) and   */
						/* restore it at a time */ 
		BobsVSprite[i].Depth = 1;
						/* Only one Plane per Bob */

					/* BobsVSprite[i].ImageData */  
					/* initialised in extra loop*/

		BobsVSpriter[i].PlanePick = 1;
					/* Only first plane wriiten */
					/* to Rast Port             */

		BobsVSprite[i].PlaneOnOff=0;
					/* Remaining planes remain 0 */

		BobsVSprite[i].CollMask = BobMask+i*20*3; 
		BobsVSprite[i].BorderLine = &BobBorderLine[i][0];
				/* Memory for CollMask and Borderline */
				/* prepared                           */

		Bobs[i].ImageShadow = BobMask+i*20*3;
				/* Shadow = CollMask                  */
		
		Bobs[i].Flags = BOBISCOMP;
				/* Bob is part of */
		Bobs[i].BobComp=&AnimComp[i];
				/* this Animcomps       */

				   PAGE 491

-----------------------------------------------------------------------------

	Bobs[i].SaveBuffer = BobBuffer+i*20*3;
					/* Memory for SAVEBACK Option */

	BobsVSprite[i].Y = 0;		/* Position word is 	*/
	BobsVSprite[i].X = 0;		/* calculated by the    */ 
					/* animation system! 	*/

	Bobs[i].Before = 0;		/* Priorities too!!!!!  */
	Bobs[i].After = 0;

	InitMasks (&BobsVSprite[i]);
			/* Initialise CollMask and BorderLine. */
			/* (Memory must already be set aside!! */
	}

	for (i=0; i<MAXBOBS; i++)
		BobsVSprite[i].ImageData = Image+i*20*3;
	for (i=MAXBOBS-2; i>0; i--)
		BobsVSprite[MAXCOMPS[i].ImageData=
				Image+i*20*3;
			/* Order the Bobs for 			*/
			/* Sequence animation 			*/
	for (i=0; i<MAXBOBS; i++)
	    {
		AnimComp[i].AnimBob = &Bobs[i] ;
		AnimComp[i].PrevComp = 0; 	/* no further 	*/
		AnimComp[i].NextComp = 0; 	/* AnimComp in 	*/
						/* AnimOb 	*/
		AnimComp[i].TimeSet = 3;	/* 3 mal Animate()     */
						/* before new sequence */
						/* is displayed.       */
		AnimComp[i].Flags = RINGTRIGGER;
					/* Ring-Sequence-Animation     */
		AnimComp[i].XTrans = 128*64;
		AnimComp[i].YTrans = 0;
					/* Offset to AM/AnY in Seagull */
					/* Note: Fixed decimal ! ! !   */ 
		AnimComp[i].AnimCRoutine = NULL; /* comp; 	       */
					/* no AnimComp Routine 	       */ 
		AnimComp[i].HeadOb = &Seagull;
					/* HeadOb for AnimComp (for one */
					/* routine as intersection mark!)*/
	}

	/*Sequence: 		1 2 3 4 5 6 7 8 9 10 11 12 13 14 */
        /*Bobs/AnilComp: 	1 2 3 4 5 6 7 8 9 6  5  4  3  2  */

	for (i=MAXBOBS-2; i>0; i--)
	    {
		AnimComp[14-i].AnimBob = &Bobs[i];
		AnimComp[14-i].PrevComp = 0;
		AnimComp[14-i].NextComp = 0;
		AnimComp[14-i].TimeSet  = 3;
		AnimComp[14-i].Flags = RINGTRIGGER;
		AnimComp[14-i].XTrans = 128*64;
		AnimComp[14-i].YTrans = 0;
		AnimComp[14-i].AnimCRoutine = NULL; 	/* Comp; */
		Bobs[14-i].BobComp = &AnimComp[14-i];
		AnimComp[l4-i].HeadOb = &Seagull;
             }						/* see above */

	for (i=1; i<MAXCOMPS-1; i++)
	     {

				PAGE 492

-----------------------------------------------------------------------------

	AnimComp[i].NextSeq = &AminComp[i+1];
	AnimComp[i].PrevSeq = &AnimComp[i-1];
			/8 intitialize 'Ring' for Ring/Sequence		*/
			/* Animation (PrevComp and NextComp remain	*/
			/* here without action and in this case		*/
			/* are not initialised, but set to 0		*/
	}

	AnimComp[0].NextSeq = &AnimComp[1]; 	/* Close ' Ring '       */
	AnimComp[0].PrevSeq = &AnimComp[13];

	AnimComp[MAXCOMPS-1].NextSeq = &AnimComp[0];
	AnimComp[MAXCOMPS-1].PreqSeq = &AnimComp[12];

	Seagull.HeadComp   = &AnimComp[0];	/* Animobs first 	*/
						/* AnimComp		*/
	Seagull.RingXTrans = 2*64;		/* X/Y Translation      */
  	Seagull.RingYTrans = 1*64;		/* of seagull    	*/
	Seagull.AnX = 0;			/* start position       */
	Seagull.AnY = 0;			/* of XTrans		*/
	Seagull.XAccel = 0x0000;		/* has no movement      */
	Seagull.YAceel = 0x0000;		
	Seagull.XVel =	0x0000;			/* no movement speed	*/
	Seagull.YVel =	0x0000;
	Seagull.AnimORoutine	=	MoveSeagull;
						/* User control	routine	*/

	AddAnimOb(&Seagull,&HeadOb,&RP);
						/* Animob in list	*/
	while (&LeftMouse & 0x40) == 0x40)
	    {
		Animate(&HeadOb,&RP);		/* Sort			*/
		SortGList(&RP) ;		/* Animation		*/
		WaitTOF();	/* to prevent blinking the bobs!	*/
		DrawGList(&RP, &Screen->ViewPort);	/* Draw		*/
	    }
				/* GelsInfo's memory freed */

	cleanup5:
	if (GelsInfo.nextLine != 0)
		FreeMem(GelsInfo.nextLine, sizeof(WORD)*8);
	if (GelsInfo.lastColor != 0)
		FreeMem (GelsInfo.lastColor, sizeof(LONG)*8);
	if (GelsInfo.collHandler != 0)
		FreeMem (GelsInfo.collHandler,
 			sizeof(struct collTable));

	 cleanup4:
	 if (Image != 0)
		FreeMem(Image,MAXBOBS*20*3*sizeof(UWORD));
	 if (BobBuffer != 0)
		FreeMem(BobBuffer,MAXCOMPS*20*3*sizeof(UWORD)); 
         if (BobMask != 0)
		FreeMem(BobMask, MAXCOMPS*20*3*sizeof(UWORD));

	 cleanup3:	CloseScreen(Screen);
	 cleanup2:	CloseLibrary(IntuitionBase);
	 cleanup1:	CloseLibrary(GfxBase);
	}

	/*****************************************************************/
	/* This function is called each time by Animate() 		 */
	/*---------------------------------------------------------------*/

				PAGE 493

-----------------------------------------------------------------------------

	/* Input parameter : AnimOb-Structure, animated with 		*/
	/* 		     Animate(). These parameters are 		*/
	/*		     passed by Animate() 			*/
	/*--------------------------------------------------------------*/
	/* Returnvalue     : none 					*/
	/****************************************************************/
	
	WORD MoveSeagull (Object)
	struct AnimOb *Object;
	{
		if ((Object->AnX < (-128*64)) ||	/* 1st user object */
		(Object->AnX > ((512-48)*64))) 		/* corner? 	   */
		Object->RingXTrans *= -1;

		if ((Object->AnY < (0)) ||
		(Object->AnY > (120*64)))
		Object->RingYTrans *= -1;
	}

	/*****************************************************************/
	/* This function is called each time by Animate() 		 */
	/*---------------------------------------------------------------*/
	/* Input parameter : AnimOb-Structure, animated with 		 */
	/*		     Animate(). These parameters are 	         */
	/*		     passed by Animate() 			 */
	/*---------------------------------------------------------------*/
	/* Returnvalue     : none 					 */
	/*****************************************************************/
	/* WORD Comp(Component)
	struct AnimComp *Component;
	{
		return(0);
	} */

				PAGE 494

-----------------------------------------------------------------------------

19. Copper Programming in C

As you already know from the previous chapters, the Copper is a coprocessor 
of the Amiga. It is responsible for the visible display, which means that 
it determines what appears at a specific position of the electronic beam.

The Copper also helps display sprites and vsprites However, a more 
important feature of the Copper is that it can be programmed by the user. 
Simply insert a pointer to the user Copper list (struct UCopLiSt 
*UserCopperList), which uses the Copper instructions to program the Copper.

However, before you can use this you must assign enough memory for 
your user Copper list: UserCopperList = (struct UCopList *) AllocMem(sizeof 
(struct UCopIns), MEMF_PUBLIC | MEMF_CLEAR).

You must clear the memory for this structure. Do this either directly 
with AllocMem through the MEMF-CLEAR option, or afterwards with BltClear. 
This allows the entry of new Copper instructions and then tells MakeVPort 
that the user Copper list is still empty.

Now that we have explained all the preliminary steps, we can proceed to the 
Copper language. It is very simple and concise of only three instructions, 
CMOVE, CWAIT and CEND. These three instructions are all that is needed 
to program pull down Intuition screens.

The CMOVE instruction enables you to write a value into a specific hardware 
register (see Appendix C). Both the hardware register and the value are 
specified by you with the Custom structure, which allows you to access the 
hardware registers. To create this structure first use extern struct Custom 
custom and then use custom.<Registername> to access the individual 
hardware registers.

Now give the CMOVE instruction as a parameter and, as you may have assumed, 
the absolute address of the desired hardware register. The Copper only 
works with offsets of the registers from $DF000 and CMOVE calculates the 
absolute address for you.

You must provide a pointer to this structure beforehand so that the CMOVE 
instruction also knows where to find the user Copper list.

				PAGE 495

-----------------------------------------------------------------------------

Now you must supply the 16 bit value (Word) that will be wrilten into
the desired hardware register.

A complete call with the CMOVE instruction would look like this:
	
	CMOVE (UserCopperList, Custom.<RegisterName>, Value);

There is a small restriction you should remember when using the	CMOVE 
instruction. Usually you can write to any hardware register numbered higher 
than $20 (dskpt) without any limitations. However, you cannot under any 
circumstances, address register numbers smaller	than $10 (adkconr) through 
the Copper. It is possible to write only to registers that fall between $10 
and $20 after you have set the Copper DangerBit in register (copcon) 
(number $2E).

When discussing sprite collision detection, we explained how you 
access the hardware registers with help from the 68000. Review that
section if necessary.

Another Copper instruction is CWAIT. This instruction enables you to	
wait for the electronic scanning beam to reach a specific position. The
user Copper list doesn't perform any other instructions until the
scanning beam reaches the specified position (The Copper program
won't have any effect on your C program). For example, you could wait 
for any desired position and change the contents of one of the color
registers. You could also use this technique to display one of your
sprites beginning in the middle of the screen.

When you use the CWAIT instruction you must tell the user Copper list 
where your instructions will be located. You must also provide the X and 
Y position that the electronic beam should wait for. The order of the X and 
Y coordinates is very important. First specify the Y coordinate and then 
the X coordinate. Pay close attention to the order of these coordinates 
because using them out of sequence can be very frustrating. Your Copper 
program will not function properly if the Y coordinate isn't first.

CWAIT (&UserCopperList,Y,X) lets you wait for a specific electronic beam 
position. Remember that the Y position must be smaller than 263 and the X 
position must be smaller than 223. Also, you must set the Y position 
relative to the top of your ViewPort and the X position relative to the 
normal scanning position. This means that for the X position you have to 
consider Overscan. The electronic beam actually covers a much larger area 
than is visible on the screen. A good value to use for positioning the 
electronic beam at The left ViewPort border is X=60 plus or minus 2 or 
View.DxOffset/2 plus or minus one.

				PAGE 496

-----------------------------------------------------------------------------

So that the Copper program ends properly, we use the CEND instruction. 
The only parameter needed is the user Copper list that will be ending. 
CEND (&UserCopperList) waits for the electronic beam to reach row position 
10000 and column position 256. Since this position is never reached, 
the user Copper list is no longer used.

When the electronic beam reaches the bottom of the screen, it will start at 
the top row again (Top Of Frame). All Copper lists for the ViewPorts and the 
user Copper Iist are run again.

The Copper can perform raster row interrupts similar to the ones from the 
Commodore 64. However, unlike the Commodore 64, the Copper can also change 
a color in the middle of a raster row. Remember that each CMOVE instruction 
requires a maximum resolution of 8 pixels. This means that with a normal 
resolution, a CMOVE instruction can only by performed every 8 pixels. 
Therefore, between two consecutive CMOVE instructions there must be an 8 
pixel gap.

The CwAIT instruction allows you to wait for electronic beam positions that 
are spaced only 4 pixels apart. However, When a CMOVE instruction follows a 
CWAIT instruction, an 8 pixel gap is still required.

After using the above instruction to create your user Copper list, you must 
provide this information to the ViewPort that will use the list. To do this 
use ViewPort.UCopIns = UserCopperList. When using Intuition screens, use the 
following form, Screen>ViewPort.UCopIns = &UserCopperList.

Now open your own screens by calling MakeVPort and MrgCop.

Intuition screens are handled differently. OpenScreen generates the Copper 
list for the screen. Afterwards, use RemakeDisplay to ensure that the new 
user Copper list is added to the global View Copper list.

FreeVPortCprList and CloseScreen release the dynamically reserved memory for 
the UCopList, a two word pointer that contains your instructions. No 
additional instructions, such as FreeMem need to be executed. Make sure you 
declare your user Copper list as a pointer and reserve the required memory 
for the UCopList structure in your program. FreeVPortCprList and CloseScreen 
free the memory for not only the instruction list, but (also for the 
UCopList Structure.

When you declare the UCopList as a normal structure, the memory that it uses 
is released twice. It is released first by FreeVportCopLists and then by 
your program, which ends by

				PAGE 497

-----------------------------------------------------------------------------

returning all used memory areas to the system. This double release of one 
memory area causes the familiar Guru Meditations.

To avoid this, always declare your UCopList as a pointer that is later used 
to assign your memory.

Finally, another small tip: To change your Copper list in your program you 
must clear your reserved UCopList structure (BltClear is best) and build a 
new list.

/***********************************************************************/
/* 				Copper. c			       */
/*								       */
/* This Program demonstrates how you can access the		       */
/* AMIGA Hardware-Registers with Help from the Copper.                 */
/* Compiled with: Aztec C 3.6a					       */
/* cc +L -s Copper.c						       */
/* ln Copper.0 -lc32						       */
/* (c) Bruno Jennrich						       */
/***********************************************************************/

#include	"exec/types.h"
#include	"exec/nodes.h"
#include	"exec/memory.h"
#include	"graphics/gfx.h"
#include	"graphics/gfxmacros.h"
#include	"graphics/gfxbase.h"
#include	"graphics/text.h"
#include	"graphics/regions.h"
#include	"graphics/clip.h"
#include	"graphics/view.h"
#include	"graphics/copper.h"
#include	"graphics/gels.h"
#include	"hardware/blit.h"
#include	"hardware/custom.h"

#define WIDTH 320
#define HEIGHT 200
   /* PAL 256 HERE */

#define MODES 0

struct	View View;
struct	ViewPort ViewPort;
struct	RasInfo RasInfo;
struct	BitMap BitMap;
struct	RastPort RastPort;

struct GfxBase *GfxBase;

struct View *oldview;

struct UCopList *UserCopperList; 		/* our Copper List */
extern struct ColorMap *GetColorMap();
/* extern struct Custom custom; in custom.h */
						/* For Access to the */
						/* Hardware-Register */

				PAGE 498

-----------------------------------------------------------------------------
	
UWORD Colors[16l = {
		0x000,0x0bbd,0x0f0,0xf00,
		0x123,0x435,0x678,0x009,
		0x123,0x435,0x678,0x009,
		0x123,0x435,0x678,0x009
		};
					/* Own ColorMap.	*/
					/* Color reg. 1 is      */
					/* changed by the       */
					/* Copper		*/
	
char *LeftMouse = (char *)0xbfe001;

char *Texts[15] = {"COPPER-Programming with the AMIGA",
		"";
		"The SPECIAL-EFFECTS Processor in Action";
		"";
		"";
		"Colors underneath the Text";
		"(a standard feature of Games)",
		"and how it is done.";
		"";
		"";
		"";
		"This Effect is especially spectacular";
		"when used with Moving BOBS !";
		"";
		"(MOUSE BUTTON)};

/**************************************************************/
/* Here we go ! 					      */
/**************************************************************/

main()
{
	long i,Len;
	if ((GfxBase = (struct GfxBase *)
		Open Library ("graphics.library",0)) == NULL )
		{
		 printf (" No Graphics !!!\n");
		 Exit(10);
		}

	oldview = GfxBase->ActiView; 		/* Build a Screen as */

	InitView(&View);			/* usual	     */
	InitVPort(&ViewPort);

	View.Modes = MODES;
	View.ViewPort = &ViewPort;
	ViewPort.DWidth = WIDTH;
	ViewPort.DHeight = HEIGHT;
	ViewPort.Modes = MODES;

	RasInfo.RyOffset = 0;
	RasInfo.RxOffset = 0;
	RasInfo.Next = 0;

	ViewPort.RasInfo = &RasInfo;	
	ViewPort.ColorMap = GetColorMap(l6);

				PAGE 499

-----------------------------------------------------------------------------
	
	LoadRGB4 (GViewPort, &Colors, 16) ;

	InitBitMap(@BitMap, 4, WIDTH, HEIGHT);
	for (i=0; i<4; i++)
		
		Bitmap.Planes[i].(PLANEPTR)
			AllocRasteR(WIDTH,HEIGHT);
		if (BitMap.Planes[i] == NULL)
		{
                  printf("No BitMap - Space !!!\n");
		  Exit(0);
		}

	InitRastPort(&RastPort);

	RastPort.BitMap = &BitMap;
	RasInfo.BitMap = &BitMap;

	SetRast (&RastPort,0);

	SetAPen (&RastPort,1);

	for (i=0;i<17;i++)
	    {
		Len = WIDTH/2-
		TextLength(&RastPort,Texts[i], strlen(Texts[i]))/2;

		Move (&RastPort, Len,i*9+63+RastPort.TxBaseline);

		/* Y-Coordinate should be divisible by 9 ! */

		Text (&RastPort,Texts[i],strlen(Texts[i]));

		MakeVPort(&View,@ViewPort); 	/* Display ViewPort. */ 	
		MrgCop(&View); 			/* Makes the difference */
		LoadView(&View);		/* visible.	*/

		UserCopperList = (struct UCopList *)
			AllocMem(sizeof (struct UCopList),MEMF_CHIP); 
				/* Reserve the required Memory */
				/* for the UCopList-Structure  */

		BltClear(UserCopperList, sizeof(struct UCopList),0);
				/* Clear UCopList-Structure */
		for (i=0; i<256; i+=9)
		{
		  CWAIT (UserCopperList,i,view.DxOffset/2);
		  CMOVE (UserCopperList,custom.color[1],0x0fff);
							/* white */

		  CWAIT (UserCopperList,i+3,view.DxOffset/2);
		  CMOVE (UserCopperList,custom.color[1],0x0bbd);
							/* light purple */

		  CWAIT (UserCopperList,i+5,View.DxOffset/2); 
		  CMOVE (UserCopperList,custom.color[1],0x088b);
							/* purple */

		  CWAIT (UserCopperList,i+7,View.DxOffset/2);
		  CMOVE (UserCopperList,custom.color[1],0x0558);
							/* dark purple */
		}

				PAGE 500

-----------------------------------------------------------------------------

		CEND (UserCopperList );			/* End UCopList */

		Delay (100);				/* Wait 2 Seconds */

		ViewPort.UCopIns = UserCopperList;
					    /* Link ViewPort and UCopList */

		MakeVPort (&View,&ViewPort);
			/* Calculate ViewPort Copper-List */ 
			/* with a Intuition Screen using  */
			/* RethinkDisplay()		  */
	
		MrgCop(&View);
		LoadView(&View);

		while ((*LeftMouse @ 0x40) == 0x40);
			/* Wait for Mouseclick */ 
		LoadView (oldview);

		for (i=0; i<4; i++)
		    FreeRaster (BitMap.Planes[i],WIDTH, HEIGHT);

		FreeColorMap(ViewPort.ColorMap);

		FreeVPortCopLists(&ViewPort);
				/* UCopList automatically released */

		FreeCprList(View.LOFCprList);	
		FreeCprList(View.SHFCprList);
				/* View-Copper List FREE */

		CloseLibrary(GfxBase);
		return (0);
	   }
				PAGE 501

--------------------------------------------------------------------------

          		APPENDIX A: STRUCTURE AND INCLUDE FILES.

This appendix contains a listing of all symbolic constants (#define xyz
numerical value) and the include file in which these constants are
located. Also listed are all used structures (struct) and all used C 
macros (#define xyz()). At the end of this appendix we explain the structure
functions and provide more details for the most important structure 
details.


	Declaration 			Include File.
 ------------------------------ 	----------------------------------
	struct AnimOb			"graphics/gels.h"
	struct AnimComp			"graphics/gels.h"
	struct AreaInfo		 	"graphics/rastport.h"
	#define AREAOUTLINE		"graphics/rastport.h"
	struct AvailFonts		"libraries/diskfont.h"
	struct AvailFontsHeader 	"libraries/diskfont.h"
	struct BitMap			"graphics/gfx.h"
	struct Bob			"graphics/gels.h"
	#define BNDRYOFF()      	"graphics/gfxmacros.h"
	#define BOBISCOMP		"graphics/gels.h"
	#define BOBSAWAY		"graphics/gels.h"
	#define BOTTOMHIT		"graphics/collide.h"
	#define CEND0			"graphics/gfxmacros.h"
	#define CMOVE0			"graphics/gfxmacros.h"
	struct ColorMap			"graphics/view.h"
	#define COMPLEMENT 		"graphics/rastport.h"
	struct Custom			"hardware/custom.h"
	#define CUSTOMBITMAP		"intuition/intuition.h"
	#define CUSTOMSCREEN		"intuition/intuition.h"
	#define CWAIT0			"graphics/gfxmacros.h"
	struct DBuffPacket		"graphics/gels.h"
	#define DUALPF			"graphics/view.h"
	#define EXTRA_HALFBRITE		"graphics/view.h"
	struct GelsInfo			"graphics/gels.h"
	#define GELGONE			"graphics/gels.h"
	struct GfxBase			"graphics/gfxbase.h"
	#define HAM			"graphics/view.h"
	#define HIRES			"graphics/view.h"
	#define INVERSVID		"graphics/rastport.h"
	struct IntuitionBase 		"intuition/intuitionbase.h"
	struct IntuiMessage		"intuition/intuition.h"
	
				PAGE 503
 
---------------------------------------------------------------------------

	#define JAM1			"intuition/intuition.h"
	#define JAM2			"intuition/intuition.h"
	#define LACE			"graphics/view.h"
	#define LEFTHIT			"graphics/collide.h"
	struct NewScreen		"intuition/intuition.h"
	struct NewWindow		"intuition/intuition.h"
	#define MEMF_CHIP		"exec/memory.h"
	#define MEMF_PUBLIC		"exec/memory.h"
	struct Menu			"intuition/intuition.h"
	struct MenuItem			"intuition/intuition.h"
	#define OVERLAY			"graphics/gels.h"
	#define PFBA			"graphics/view.h"
	#define RASSIZE()               "graphics/gfx.h"
	struct RasInfo			"graphics/view.h"
	struct Rastport			"graphics/viewport.h"
	#define RemBob()		"graphics/gels.h"
	#define RINGTRIGGER		"graphics/gels.h"
	#define RIGHTHIT		"graphics/collide.h"
	struct Screen			"intuition/intuition.h"
	#define SAVEBACK		"graphics/gels.h"
	#define SAVEBOB			"graphics/gels.h"
	#define SUSERFLAGS		"graphics/gels.h"
	#define SELECTDOWN		"intuition/intuition.h"
	#define SELECTUP		"intuition/intuition.h"
	#define SetOPen()		"graphics/gfxmacros.h"
	#define SetDrPt()		"graphics/gfxmacros.h"
	#define SetWrMsk()		"graphics/gfxmacros.h"
	#define SetAfPt()		"graphics/gfxmacros.h"
	struct SimpleSprite		"graphics/sprite.h"
	#define SPRITE_ATTACHED		"graphics/sprite.h"
	struct TextAttr			"graphics/text.h"
	struct TextFont			"graphics/text.h"
	struct TmpRas			"graphics/rastport.h"
	#define TOPHIT			"graphics/collide.h"
	struct UCopList			"graphics/copper.h"
	typedef ULONG			"exec/types.h"
	typedef UWORD			"exec/types.h"
	struct View			"graphics/view.h"
	struct ViewPort			"graphics/view.h"
	#define VP_HIDE			"graphics/view.h"
	struct VSprite			"graphics/gels.h"
	#define WBENCHSCREEN		"intuition/intuition.h"
	struct Window			"intuition/intuition.h"
	
				PAGE 504
	
-----------------------------------------------------------------------------

struct AnimComp
    {
	WORD Flags;
		THese variables enable you to determine the type of 
		animation to use. When you set the RINGTRIGGER flag it
		means you have set up a ring of ANIMCOMPS. You link the 
		ring through the AnimComp.NextSeq and AnimComp.PrevSeq.
		Animate can automatically display different sequences 
		(like a flying bird) by using the AnimComp ring.
	
		Unless you set RINGTRIGGER, animation is not possible.

	WORD Timer;
		This variable is loaded with the timeset variable and 
		decremented (if set to decrement to zero) with each
		Animate() call. Whenver Timer reaches zero, depending on 
		your setup (RINGTRIGGER), a new sequence is displayed.

	WORD TimeSet;
		The value contained here is written into Time and 
		decremented there by every Animate() call. TimeSet 
		determines how long an animnation sequence is active. The
		next sequence starts after a certain number of Animate()
		calls.

	struct AnimComp *NextComp;
	struct AnimComp *PrevComp;
		These two variables allow you to link many animation 
		objects (AnimOb) together for display by Animate(). For
		example, the AnimObs for the arms, legs and head of a man
		can be linked together. Please remember that NextComp and
		PrevComp should not be used to animate a sequence for 
		moving an arm while walking. You must use NextSeq and
		PrevSeq for these type of animations.

	struct AnimComp *NextSeq;
	struct AnimComp *PrevSeq;
		When you want to repeatedly change an animation component
		define different display (sequences) of an object (for 
		example, an arm). Then use the above two pointers to tell
		Animate() that you want the arm displayed in different 
		positions. You program the various arm movement positions 
		and then they are displayed.

	WORD (*AnimCRoutine)();
		You either set this pointer to zero or point it to a 
		function you have defined. Each call of Animate() that
		displays your components also calls this function. Your
		routine is passed to the current AnimComp structure.
	
				PAGE 505
	
-----------------------------------------------------------------------------

	WORD YTrans, XTrans;
		These two pointers contain the position of the AnimComps
		relative to the AnimObs defined earlier. (Please remember
		to use the fixed decimal arithmetic for these variables).

	struct AnimOb *HeadOb;
		This pointer points to the previously defined AnimOb of 
		which the AnimComp is a part.

	struct Bob *AnimBob;
		Naturally Animate() must also know what should be 
		displayed. For this purpose the AnimComp structure contains
		a pointer to the bob this is associated with the AnimComp.
		(Please make sure that the bob also has its own VSprite 
		structure).
	
    }
	
The AnimComp, or the animation components, determine the connection between
bob and animation object (AnimOb). This is especially important with 
Sequence Animation (RINGTRIGGER) because it connect the individual 
components together in a ring and sets the amount of time each sequence is
active.
	
	
	    -------------------------------------------------------


struct AnimOb
    {
	struct AnimOb *NextOb *PrevOb;
		The variables mkae it possible for you to link many 
		animation object together. The linked objects are then 
		animated with Animate() and then with SortGList(). 
		DrawGList() etc are all displayed on the screen (for 
		example several men).

	LONG Check;
		This variable contains a count of the calls to Animate()
		that have been used for an AnimOb.

	WORD AnOldY AnOldX;
		These variables contain the old position of an animation
		object. We save the old position because the current 
		position (AnX, AnY) does not change until timer reaches
		zero for the current AnimComp. The user can change the 
		position between movements which causes some components to
		be displayed in the wrong positions. For this reason, we 
		store the old position. After numerous Animate() calls the
		actual position is calculated using the old position and 
		the following variables.

	WORD AnX, AnY;
		These variables contain the actual positions of the AnimObs.
		They do not contain values for pixel and row positions 
		within a RastPort. Depending on the speed and motion 
		variables, they contain values in steps of 64 for pixels 
		and lines.

				PAGE 506
	
-----------------------------------------------------------------------------

		This means you must use AnX = Width/2 * 64 and
		AnY = Height/2 * 64 to move AnimOb to the middle of the
		screen. Again we have a problem using horizontal values 
		plus or minus 32768 versus positions over 512 (=32768/64).
		The following trick can help: The variable XTrans (and 
		YTrans) in the AnimComp structure set the position of an
		AnimComp relative to the previously defined AnimOb. When 
		you simply initialise XTrans with a value of 128*64 you 
		can move an object around the entire screen (512+128 = 640)
		even in hires mode.  For horizontal values less than 128
		you simply use negative values with AnX.

	WORD YVel, XVel;
		The speed of an AnimOb is contained in these two variables.
		The values in YVel and XVEL and added to AnY and AnX 
		after every Animate() call. Because Animate() is normally
		called many timed per second it is possible for your object
		to move erratically on the screen. To prevent this, 
		velocity and acceleration are set using step values of 64
		for every Animate() (this is the reason for the unusual 
		method used for the values in AnX and AnY). This means that
		with a value of one in XVel, 64 Animate calls have to 
		occur before the object moves one pixel.

	WORD YAccel, XAccel;
		These variables determine the motion of your AnimOb. These
		variables must also be set in steps of 64. The values in 
		XAccel and YAccel are added to XVel and YVel.

	WORD RingYTrans, RingXTrans;
		These variables set the speed of the AnimOb. They are added
		directly to AnX and AnY. Motion isn't a factor here.

	WORD (*AnimORoutine) ();
		The routine whose addres is specified here is called once
		by every Animate() call. This routine is passed to the 
		current AnimOb stucture so that the actual position of the 
		current AnimOb is controlled and the proper reaction is
		received.

	struct AnimComp *HeadComp;
		This pointer points to the first animation component of an
		AnimOb.

	AUserStuff AUserExt;
		Link your own structures (see VSPRite, VUserStuff) here.
	
    }

The AnimOb structure contains a complete animation object. You use
AddAnimOb() to make this structure available to the system and then use
Animate() for animation.
	
				PAGE 507
	
-----------------------------------------------------------------------------

struct AvailFonts
    {
	OWORD af_Type;
		These variables determine whether the TextAttr structure 
		specified below uses a font in memory (AFF_MEMORY) or a 
		diskfont in the "SYS:fonts" directory (AFF_DISK). This is
		important for determining whether you should use OpenFont()
		or OpenDiskFont() to open a font.

	struct TextAttr af_Attr;
		This is the TextAttr structure returned by AvailFonts().
	
     }

This structure is only used by the routine AvailFonts() (and by you, of 
course). It is written after the AvailFontsHeader is located in a memory 
area where it is available for use by AvailFonts().
	
	
		--------------------------------------------

struct AreaInfo

This structure is required for the Area function. It is initialised with
InitArea and used for the coordinates of a polygon corner points.

		--------------------------------------------

struct AvailFontsHeader

This structure can only be created by using the routine AvailFonts() and
contains only one variable: afh_NumEntries. This variable contains the 
count of the AvailFonts structures written after the AvailFontsHeader in 
the memory area specified by the AvailFonts() routine.
	
		--------------------------------------------

struct BitMap
    {
	UWORD BytePerRow;
		This variable contains the byte count required for one 
		bitmap row (BytesPerRow = Width/8).

	UWORD Rows;
		The line count for a bitmap (height) is contained in this
		variable.
	
	UWORD Flags;
		This variable is only used by the system.
	
				PAGE 508

-----------------------------------------------------------------------------

	UBYTE Depth;
		The number of bitplanes in a bitmap are contained in this
		variable. Please remember that the depth determines the 
		number of available colours (colors = 2^NumBitPlanes).

	UWORD	pad;
		This is one full WORD so the following pointer begins with
		a LONG WORD address.

	PLANEPTR Planes[8];
		These eight pointers contain the addresses of the 
		individual bitplanes for the bitmap. Although now you can
		only use six of the eight pointers you can see that there
		are possibilities for future expansions.
 
   }

The BitMap structure contains the addresses for the individual memory areas
where graphics are stored. In addition, information for the height, width 
and depth of the bitmap are contained here.
	
		--------------------------------------------


struct Bob
    {
	WORD Flags;
		Through these variables the user can determine how the bob
		is handled by the system. The SAVEBOB flag tells the system
		that once the bob is drawn it won't be cleared from the
		RastPort (brush function). You use BOBISCOMP to make the
		bob part of an animation component. Make sure that you 
		also point the pointer BobComp to the corresponding 
		AnimComp structure.

		Not only the user can set the bob flags, the system can 
		also set the so-called status flags. These flags provide
		information about the status of a bob. For example, the 
		flag BOBNIX tells us that the bob has disappeared from the
		RastPort, the background has been restored, and the BOB 
		was removed from the GEL list.

	WORD *SaveBuffer;
		This pointer points to a memory area, reserved by you,
		where the background will be stored when a bob is drawn.
		Because bobs are normally written directly into the bitmap,
		the background where the bob appears is destroyed. When you
		set the SAVEBACK flag in the vsprite structure the background
		is saved to the memory area. This area must be at least as 
		wide an high as the bob being drawn. You must also make sure 
		that for every bitplane of the RastPort being written to 
		(see PlanePick and planeOnOff in the VPsrite structure) a 
		buffer in chip memory is reserved. The background is 
		saved into these memory buffers.
	
				PAGE 509
	
-----------------------------------------------------------------------------

 	WORD *ImageShadow;
		As you may already know, you define a bob bitplane by 
		bitplane and use PlanePick and PlaneOnOff to determine in 
		which plane the bob is drawn. ImageShadow points to a 
		memory buffer that is large enough to store one bitplane
		of your bob. All the set pixels in the individual bitplanes
		for your bob are stored in ImageShadow. In other words, all
		the Bob-Planes are ORed and stored in ImageShadow  (chip
		memory).

	struct Bob *Before;
	struct Bob *After;
		These two pointers determine the order the bobs are drawn.
		They can be used to make the GEL routines use your bobs in a
		specific order. However, since this function removes 
		pointers, you must do this after AddBob().

	struct VSprite *BobVSprite;
		Each bob requires a vsprite structure because the bob 
		structure doesn't contain any variables for positioning.
		In addition, the GEL list is made up of only vsprite 	
		structures and the bob must be in this list somehow. To 
		make this work, this pointer points to the vsprite structure
		for the bob (every bob has its own).

	struct AnimComp *BobComp;
		This pointer points to the AnimComp structure to which the
		bob belongs. You set this pointer only after setting the 
		flag BOBISCOMP.

	struct DBuffPacket *DBuffer;
		When you want to use bobs with a double buffered bitmap, 
		which saves both bitmaps for the background, you must 
		initialise this pointer to DoubleBufferPacket. This makes
		it possible for the GEL software to easily display the
		bobs in both bitmaps, without any extra work (chip mem).

	BUserStuff BUserExt;
		Here you, the user, can add your own extensions to the bob
		structure. Simply used #define BUserStuff to define the 
		type of extension in your program. This extension can then 
		be accessed either by the AnimCRoutines, AnimORoutines or 
		a collision routine. When you don't define BUserStuff, it is
		automatically defined as a SHORT variable.

The bob structure defines the bob (blitter object). Bobs can be as large as 
you want and can contain as many colours as the RastPort in which they are
used.
	
				PAGE 510
	
-----------------------------------------------------------------------------

struct ColorMap

You use this structure to set the colours for a ViewPort. To change them
afterwards use LoadRGB4(), getRGB4() and SetRGB4().

		--------------------------------------------

struct Custom

This structure provides a picture of the hardware registers which helps
you effictively access them with C. The Appendix for the hardware registers
describes all the symbol registers for this structure and how to use them
(chip memory).

		--------------------------------------------

struct DBuffPacket
	
This structure was designed for using bobs in double buffered bitmaps.
The backgrounds from both bitmaps, which are selected by you, are saved
here when the bob is drawn over them. When you set the SAVEBACK flag in
the vsprite structure the background is saved from only one of four 
bitmaps. By installing a DBuffPacket(Bob.DBuffer = &DBuffPacket) for every
bob, you can also save the background of the second bitmap. However, a 
DBuffPacket cannot be generated for only one bob in a GEL list. Either 
all or none of the bobs in the GEL list have a DBuffPacket.
	
You must also provide the DBuffPacket structure and the address of an 
additional memory area in chip memory (DBuffPacket.BufBuffer = &Memory).
This area must be the same size as the Bob.SaveBuffer. The other 
variables for DBuffPackets are handled by the GEL software.
	
		--------------------------------------------

struct GfxBase

GfxBase is your pointer to the graphic function library. You initialise
this library with GfxBase = OpenLibrary("graphics.library",VERSION_NUMBER).
Now you have access to all the graphic functions that the Amiga has 
available.

Also, GfxBase contains a pointer to the currently active View. When you 
use a program that creates its own View, without intuition, you should
save the current View. By using OldView = GfxBase->ActiView you can 
save this pointer, return the intuition View and, thereby, thw workbench 
screen.

Another GfxBase structure variable, GfxBase->SpriteReserved provides 
information on the hardware sprites that are currently available for use.
	
				PAGE 511

-----------------------------------------------------------------------------

There are a few more pointer in GfxBase such as the SystemFont list etc..
that are exclusively for system use. These pointer can also be affected
by the Graphic functions.

		--------------------------------------------

struct GelsInfo
    {
	BYTE sprRsrvd;
		This variable provides information about the sprites 
		available to the vsprite generator. When your program does
		not require the hardware sprites simply set all the bits
		in sprRsrvd. This tells the Amiga to use all the hardware
		sprites as vsprites. If you want to use both hardware 
		sprites and vsprites, you must ensure that your hardware 
		sprites are not used as vsprites. To accomplish this, clear
		the corresponding bit in SprRsrvd (bit 0 for sprite 0 and 
		bit 1 for sprite 1 etc..).

	UBYTE Flags;
		These variables are used only by the system.
	
	struct VSprite *gelHead, *GelTail;
		The GELs (vsprites and bobs) are organised in a GEL list.
		These two pointers point to the beginning and end of this 
		list and are initialised with InitGels().

	WORD *nextLine;
		This pointer points to a memory area that is eight words
		long. It contains information on the highest vertical 
		positions at which a hardware sprite can be displayed 
		by using the vsprite software.

	WORD **lastColor;
		This eight pointer array helps the copper. It stores the
		address of the last color definition that was saved for the
		hardware sprites. This address is compared to the colour 
		table address for the new sprite that will be displayed.
		If they are the same, a color change is not performed by the
		Copper because these colours have already been displayed.
		When all eight pointers point to the same vsprite color
		table you can display up to eight vsprites in one raster
		row instead of only four.
	
	struct collTable *collHandler;
		This is where you store the various addresses for collision
		routines using SetCollision(). Whether or not these are
		called depends on which GELs collide with which collision 
		masks (MeMask and HitMask).
	
	short leftmost, rightmost, topmost, bottommost;
		These four variables are used to set the rectangle 
		boundaries within which your GELs are confined without 
		having a Border_Collision. When you GEL exceeds these 
		boundaries, collision routine zero is called. In order for
		this to function you must set bit zero in the GELs BitMask.

				PAGE 512

-----------------------------------------------------------------------------

	APTR firstBlissObj.lastBlissObj;
		These two pointers are only used by the operating system.

    }

The GElsInfo structure contains very important variables and pointers for 
the GELs (graphic elements). It must be initialised with InitGels() before
the GEL routines (AddBob(), AddVsprite(), Animate(), AddAnimOb()) can be
used. This structure must be passed to the initialised RastPort (RastPort.
GElsInfo = &GelsInfo).
	
		--------------------------------------------

struct IntuiMessage

This structure allows you to intercept and check messages received by
Intuition, such as those from a window. With their help you can determine 
whether or not a menu item has been selected, the mouse has moved or a 
mouse button has been pressed.
	
		--------------------------------------------

struct IntuitionBase

Just as any library, the intuition library also has a BasePointer.
This base pointer is used in the same way as the starting address for 
accessing the library functions.
	
		--------------------------------------------

struct NewWindow
    {
	SHORT LeftEdge, TopEdge;
	SHORT Width, Height;
		These four variables determine the position of a window.
		(LeftEdge (X coordinate), TopEdge (Y coordinate)), width 
		and height.
	
	UBYTE DetailPen, BlockPen;
		These two variables are used to set the color for your
		BlockPen and the Title. The values you use here are the 
		same ones  used for SetAPen() (the number of the colour 
		register).
	
	ULONG IDCMPFlags;
		The IDCMP flags (Intuition Direct Communication Message
		Ports) determine the type of communication between the user
		and Intuition. You can decide what messages are sent, by
		Intuition to your program. You may also want to receive 
		messages for a mouseclick (MOUSEBUTTON) or a key press
		(RAWKEY / VANILLAKEY). Unfortunately, we do not have 
		enough room here to provide a complete listing of all the
		IDCMPs.
	
				PAGE 513

-----------------------------------------------------------------------------

	ULONG Flags;
		By using these flags it is possible to describe a window
		in more detail. For example, you can set BORDERLESS so 
		the window has no border. With ACTIVATE, a window can be
		active as soon as you open it and will immediately become
		the input/output window. Again, a complete list of all the
		possibilities is not possible here.

	struct Gadget *FirstGadget;
		This pointer points to the first gadget you have created.
		Gadgets are similar to the small boxes seen in the upper 
		right corner of system windows, which place the window in 
		the background when they are clicked.

	struct Image *CheckMark;
		This pointer points to the Image structure used for the 
		checkmark, which is used to show static menu items. By 
		entering a zero here you can use the default checkmark.

	UBYTE *Title;
		When you want to use several windows it is easier to give 
		each one a name or title. This name is displayed in the top
		row of the window. Title is the pointer to the first 
		character of your title string (for example, the system 
		window is named AmigaDOS).

	struct Screen *Screen;
		In order for a window to exist, it needs a screen. A window
		must be displayed at some time. This pointer points to an 
		opened screen where the window is later displayed.

	struct BitMap *BitMap;
		When you have set the SUPER_BITMAP flag in the flags 
		variables, this pointer must point to the bitmap you have
		created. It is possible to create a bitmap with 1024*1024
		pixels and display part of it as large as the window on 
		your screen.

	SHORT MinWidth, MinHeight;
	SHORT MaxWidth, MaxHeight;
		Once you have set the WINDOWSIZING flag in the flags
		variables (and also set SIZEBRIGHT (Size Border Right) or
		SIZEBOTTOM (Size Border Bottom) the window sizing gadget 
		will appear. This gadget, located in the bottom right 
		corner of your window, allows you to change the size of 
		your window. You can set the sizing limits by using the
		variables MinHeight, MinWidth, MaxHeight and MaxWidth.
	
				PAGE 514

-----------------------------------------------------------------------------

	USHORT Type;	
		This variable lets you determine whether or not this window
		will appear in the Workbench area (WBENCHSCREEN). Here you
		must set the screen structure pointer to zero otherwise the
		window will appear in its own screen (CUSTOMSCREEN). You 
		must also provide the NewWindow structure with an address
		for the screen where the window should appear.

    }

These structures let you describe a window. After setting all the pointers
and variables, call Window = OpenWindow (&NewWindow). As an example, you 
can now use your window for graphic output.

		--------------------------------------------

struct NewScreen
    {
	SHORT LeftEdge, TopEdge, Width, Height, Depth;
		These variables allow you to set the position, size and
		depth (number of bitplanes) for your screen. While doing
		this, you must also ensure that your window cannot be 
		moved horizontally (in the X direction). Otherwise, values
		for LeftEdge that are not equal to zero will have the same
		effect as if they were equal to zero.
	
	UBYTE DetailPen, BlockPen;
		The colour for text (DetailPen) and title (BlockPen) for
		the top screen row are also set here in the same way as 
		windows.

	USHORT ViewModes;
		In this variable you can set the display resolution mode
		for your screen.

	USHORT Type;
		This variable sets the type of screen and must always be
		specified as CUSTOMSCREEN. When you initialise your own 
		bitmap you also have to set the CUSTOMBITMAP flag.

	struct TextAttr *Font;
		If you want to use a different font with your screen you 
		can select it here. Simply define a TextAttr structure
		describing the new font and provide the address. This
		screen and any windows within it will use the selected 
		font. To use the default font (Topaz) set this variable
		to zero.

	UBYTE *DefaultTitle;
		As with windows, this pointer points to a title text 
		string for the top screen row of your screen. (The 
		Workbench screen has the title "Workbench screen"). If you
		do not want a title set this pointer to zero.
	
				PAGE 515

-----------------------------------------------------------------------------

	struct Gadget *Gadgets;
		Currently this pointer is not used and should be set to 
		zero for guaranteed upward compatibility.

	struct BitMap *CustomeBitMap;
		This pointer points to your bit-map when Type is set to 
		CUSTOMBITMAP.

    }

The NEWSCREEN structure is used to describe a screen. It is opened with 
Screen = OpenScreen (&NewScreen).
	
		--------------------------------------------

struct RastPort
    {
	struct Layer *Layer;
		This pointer points to the Layer structure of the 
		RastPort. Layers are data structures that help manage
		windows. They prevent a window from overwriting another
		by mistake.

	struct BitMap *BitMap;
		This is the pointer to the BitMap used by the RastPort. For
		screens other than Intuiton this must be initialised later.

	USHORT *AreaPtrn;
		This pointer points to the fill pattern of the RastPort.
		Normally an area is filled without any special pattern, but
		by using the macro SetAfPt() you can change the fill pattern.

	struct TmpRas *TmpRas;
		This pointer points to an additional memory area that is
		used for the fill functions Area...() and Flood. This area 
		must be large enough to store the entire area that is being 
		filled.

	struct AreaInfo *AreaInfo;
		This pointer is only used by the Area().. commands. The
		points for a polygon set by AreaDraw() and AreaMove() 
		must be stored in some location. Use InitArea() to 
		initialise an AreaInfo structure that contains sufficient
		memory (five bytes per coordinate). Then link this structure
		to the RastPort for get AREA(RastPort.AreaInfo = 
		&AreaInfo).

	struct GelsInfo *GelsInfo;
		This structure is used to display vsprites and bobs in a 
		RastPort. It contains a linked list of all the graphic
		elements for Vsprites. You can sort and display this list
		by using SortGList() and DrawGList().
	
				PAGE 516
	
-----------------------------------------------------------------------------

	UBYTE Mask;
		This variable contains information about which bitplanes
		of a RastPort are affected by a graphic operation. The 
		normal value is 0xff which means all bitplanes are affected
		(each set bit represents an on bitplane). You can change 
		this variable as required with SetWrMsk(&RastPort, Mask)

	BYTE FgPen;		
		This variable contains the number of the color register
		that is responsible for setting the APen colour. FGPen ==
		APen, the APen was previously named ForegroundPen.

	BYTE BgPen;
		BgPen == BPen. (Bpen was the BackgroundPen).

	BYTE AOIPen;
		AOIPen (Area Outline Pen) == Open
	
	BYTE DrawMode;
		This variable contains the actual drawing mode set by the
		macro SetDrMd().

	BYTE AreaPtSz;
		This variable contains the number of rows that are in the 
		fill pattern. This can always be changed by using SetAfPt(),
		but remember that the height must be set in powers of two.

	BYTE linpatent;
		This help variable is used for drawing lines.

	BYTE dummy;	
	USHORT Flags;
		These variables contain various flags. For example, they 
		can determine whether the first pixel of a line is drawn 
		(FLAGS \= FRST_DOT) or if only one pixel per raster row 
		is drawn (ONE_DOT). Another example is whether Area..()
		frames an area with the color of the OPen (Flags \= 
		AREAOUTLINE).

	USHORT LinePtrn;
		This variable contains the 16 bit line pattern that can be 
		set with the macro SetDrPt().

	SHORT cp_x, cp_y;
		These two variables contain the X and Y position of the
		graphic cursor, which you can position within the bitmap
		with the Move() Command.

	UBYTE minterms[8];
		We do not have much information for this and the following 
		two variables. The reason for this is that these parameters
		dont provide any visible results when they are changed.
	
				PAGE 517

-----------------------------------------------------------------------------

SHORT PenWidth, /* See minterms */
SHORT PenHeight, /* See minterms */

	struct TextFont *Font;
		This pointer points to the TextFont structure for the font 
		currently in use. When the normal font "topaz.font" 
		becomes tiresome you can change fonts by using OpenFont()
		and SetFont().

	UBYTE AlgoStyle;
		This text contains the text style that you set with 
		SetSoftStyle().

	UBYTE TxFlags;
		This variable contains the flags that define your font in 
		detail for the RastPorts. Here you can determine whether 
		a font supports proportional characters (TxFlags ==
		FPF_PROPORTIONAL), is loaded from RAM (FPF_ROMFONT) or 
		from disk (FPF_DISKFONT).

	UWORD TxHeight;
		This variable provides the character height of the current
		RastPort font.

	UWORD TxWidth;
		This is the average width of the individual characters.

	UWORD TxBaseline;
		This variable contains the position of the baseline for the
		font. With the style FPF_UNDERLINED the baseline is drawn
		in with each character for underlining. The most important
		aspect of the baseline is text positioning with Text().
		Strings are not positioned by using a Y position for the
		top line of the text. The string is positioned by a Y 
		position of the graphic cursor and the baseline.
	
	WORD TxSpacing;
		This variable sets the pixel width for each character (the
		width of a character). This apllies to the display of single
		characters but not strings.

	APTR *RP_User;
		This variable is reserved for the user. You can use this 
		variable, for example, to link your own data structures with
		the RastPort for special purposes.

				PAGE 518
	
-----------------------------------------------------------------------------
	
	UWORD wordreserved[7];  /* reserved */
	ULONG longreserved[2];  /* reserved */
	UBYTE reserved[8]; /* reserved */
    }

When changing a bitmap, The RastPort structure is the most important 
structure. Most graphic commands require a RastPort structure because
the actual values of the foreground pen and many other variables are
available

After initialising the RastPort with InitRastPort (&RastPort), simply 
initialise the bitmap pointer with RastPort.BitMap = &BitMap.

		--------------------------------------------

struct Rasinfo
    {
	struct RasInfo *Next;
		When you have set your ViewPort for DUALPF display mode
		(Dual Playfields) you also have to specify two bitmaps that
		overlap in the ViewPort. Here you link two RasInfo 
		structures that point to one of the two BitMaps by using
		RasInfo1.Next = &RasInfo2. Then the first of the two 
		RasInfo structures is made available to the ViewPort with
		ViewPort.RasInfo = &RasInfo1;. The rest happens as usual
		when opening the View and ViewPorts.

	struct BitMap *BitMap;
		This is the pointer to the bitmap of the RasInfo structure
		that will be displayed in the ViewPort.

	SHORT RxOffset, RyOffset;
		These two variables determine which pixel of the BitMap
		lines up with the upper left corner of the ViewPort. They
		are normally set to zero which means that the upper left
		corner of the BitMap and the ViewPort line up exactly. By
		changing these values and then calculating a new Copper 
		list you can achieve a scrolling bitmap.
       		
    }

The RasInfo structure is the referee between ViewPort and BitMap.

		--------------------------------------------

struct Screen

This structure which is similar to the window structure, provides access to 
an already opened screen (Screen = OpenScreen(&NewScreen). All system 
structures, such as those used for graphic output (Screen->RastPort.xxx,
Screen.ViewPort.xxx etc...), are available to you through this structure.

				PAGE 519

-----------------------------------------------------------------------------

struct SimpleSprite
    {
	UWORD *posctldata;
		This pointer points to a memory area in this form;

	struct SpriteData
	    {	
		UWORD posctl[2];
		   /* represents the hardware register 
		      'spr[x].pos' and 'spr[x].ctl' )

		UWORD Appearance[Height*2];
		    /* This array contains the appearance of */
		    /* the sprites row for row defined in     */
		    /* Two UWORDs			      */
	
		UWORD reserved[2] = {0,0};
	    }
	You must create the spritedata structure yourself because it does 
	not exist in an include file.
	
	UWORD Height;
		This variable contains the height of the sprites. Sprites
		are always 16 pixels (1 word) high.

	UWORD x,y;
		These two variables contain the current position of the
		sprites.

	UWORD num;
		This variable contains the number of the hardware sprites
		(0-7) that are described and changed by the SimpleSprite 
		structure.
	
    }

The SimpleSprite structure permits the use if a hardware sprite. Sprites are
always 15 pixels wide and can be any desired height.

You, as the programmer, must provide the strutures that determine the
appearance of the sprites (SpriteData). Then use SimpleSprite.posctldata = 
(UWORD *) &SpriteData to pass this data to the SimpleSprite structure.

		--------------------------------------------

struct TextAttr;
    {
	STRPTR ta_Name;
		This pointer points to the name of the font ("name.font")
		that you want to open with OpenFont() or OpenDiskFont().

				PAGE 520

-----------------------------------------------------------------------------

	UWORD ta_YSize;
		This is where the height in rows is stored for your font.

	UBYTE ta_Style;
		You use this variable to set a beginning style for the
		font you opened above.

	UBYTE ta_Flags;
		This variables tells you whether or not your font can use
		proportional characters.

This structure is used by the command OpenFont() and OpenDiskFont(). The 
variables ta_Name and ta_YSize are used to try to load a specific font and
also find a font that best fits your selected parameters.

		--------------------------------------------

struct TextFont

This structure is used to access a font opened with OpenFont() or 
OpenDiskFont(). It can be linked to a RastPort with SetFont() or added 
to the system font list with AddFont() amd removed with RemFont().

		--------------------------------------------

struct TmpRas;

The TmpRas structure is used by the fill commands Flood and Area.. It 
must be initialised with InitTmpRas and linked to a RastPort. Now you can
use the Area... and Flood commands with this RastPort.

The TmpRas structure is used to make an area of memory available for use.
It must be large enough to store a bitplane of the largest element you
want filled. This is a requirement of the recursive fill algorithm.

		--------------------------------------------

struct View 
    {
	struct ViewPort *ViewPort;			
		This is the pointer for the first ViewPort of the View.

	struct cprlist *LOFCprList;
		This is the pointer to the Copper list created with 
		MrgCop().

	struct cprlist *SHFCprList;
		This is also a pointer to a copper list, but this list is
		only used with interlace mode and is required because 
		LOFCprList is always used.
	
				PAGE 521

-----------------------------------------------------------------------------

	short DyOffset, DxOffset;
		These two variables determine the position of your View on 
		the monitor. They are automatically set by InitView() so 
		you dont have to worry about the View programming.

	UWORD Modes;
		This variable contains the resolution mode of the View. In
		order to use the interlace mode in any particular View, you
		must set it here.

    }

The View structure is the manager of graphic displays and provides the most
important link between you and the system.
	
	
		--------------------------------------------

struct ViewPort
    {
	struct ViewPort *Next;
		Since it is possible to display more than one ViewPort in 
		a View, this is the pointer to the next ViewPort. The
		ViewPorts must also be linked together. After using 
		InitVPort() this pointer equals zero which means that 
		there are no other ViewPorts.

	struct ColorMap *ColorMap;
		This pointer determines the ColorMap of the ViewPort.
		Because every ViewPort has its own colormap it is possible to
		set different colours for each ViewPort within a View.

	struct CopList *DspIns;		/* Display instructions */
	struct CopList *SprIns;		/* Sprite Instructions   */
	struct CopList *ClrIns;		/* Sprite Instructions   */
	struct CopList *UCopList *UCopIns;
		These are the pointers to the intermediate or ViewPort 
		Copper list created with MakeVPort().

	SHORT DWidth, DHeight;
		These two variables determine the height and width of the 
		ViewPort in pixels. For example, the number of lines used 
		for this ViewPorts resolution (hi-res or lace).

	SHORT DxOffset, DyOffset;
		These two variables determine the position of the ViewPort
		within the View. InitVPort() sets these equal to zero, so 
		you will have to change them.

	UWORD Modes;
		This is where you set the resolution mode of the ViewPort.
		You are not limited in choice since HAM, Extra Halfbrite,
		sprites and all the modes are available. Remember to always
		use the highest resolution mode that you will be using in 
		your View.

	UWORD reserved;
	struct RasInfo *RasInfo;
		This pointer makes the link between ViewPort and bitmap
		through the RasInfo structure.
    }

The ViewPort that is described by the ViewPort structure is the window 
through which you can see your bitmap on the monitor.

				PAGE 522

-----------------------------------------------------------------------------

struct VSprite
    {
	struct VSprite *NextVSprite;
	struct VSPrite *PrevVSprite;
		These two pointers are used to create the GEL list which is
		sorted using SortGList() by X and Y values (See below for
		display).

	struct VSprite *DrawPath;
	struct VSprite *ClearPath;
		These pointers are used to display the bobs in an organised
		manner. DrawPath writes the bobs into the RastPort. 
		ClearPath is calculated from DrawPath and, as desired, 
		removes the bobs from the RastPort and restores the 
		background.

	WORD OldY, OldX;
		These two pointers are used to restore the background 
		covered by a bob when a bob moves. By setting the SAVEBACK
		flag in the the VSprite structure for a bob and defining a
		memory buffer area, you can save the background that is 
		hidden when a bob is displayed. When you move the bob and 
		call DrawGList(), the old background is displayed again. The
		old bob position is stored in OldX and OldY so the computer
		knows where to restore the background.

	WORD Flags;
		This variable determines how the system handles the Vsprite.
		When the VSprite structure is being used to display 
		vsprites then Flags = VSPRITE. However, bobs also use this 
		structure.

	WORD Y,X;
		These two variables determine the position of the VSPRITE 
		or bob on the screen.
	
				PAGE 523

-----------------------------------------------------------------------------

	WORD Height;
		This variable sets the number of vertical rows for a 
		vsprite or Bob.

	WORD Width;
		This variable determines how many words are used to display
		one row of a bob. A value of one is used for width when 
		using vsprites because they cannot be wider than 16 pixels
		( = 16 bits = 1 word).

	WORD Depth;
		This is where you set the bitplanes for the bob. This is
		actually how many bitplanes you have defined for the bob.
		Please note that your bob cannot have a depth greater than 
		the RastPort in which it is used. However, a bob can have 
		less bitplanes than the RastPort.
	
	WORD MeMask;
	WORD HitMask;
		You use these two variables to determine which collision
		routine (if any) is executed upon a collision with another
		GEL. The MeMask of one and the hitmask of the other GEL 
		are ANDed and the result bit determines which collision 
		routine is used. (bit 1=> routine 1, bit2 => routine2, ...
		bit 15 => routine 15).

		When you set bit zero in HitMask , a GEL border collision
		calls  routine zero.

	WORD *ImageData;
		This pointer points to the bob/vsprite data that determine
		their appearance. This data must be stored in chip memory.

	WORD *BorderLine;
	WORD *CollMask;
		These two pointers point to memory buffer areas, defined by
		you, for the BorderLine and CollisionMask. They are also 
		used to detect collisions.
	
		The Borderline contains as many words as the width of a 
		bob or vsprite (vsprites are always one word wide). 
		Borderline os a logical OR of all the GEL rows. The ColMask
		is exactly the same size as your GEL, but is only one 
		bitplane deep. ColMask contains a logical OR of all plane
		data. (Both of these buffers must be created by you and are
		initialised with InitMasks(). They must also be located in 
		chip memory.

	WORD *SprColors;
		This pointer points to a three UWORD memory area that 
		contains the VSprite colors.

				PAGE 524
	
-----------------------------------------------------------------------------

	struct Bob *VSBob;
		If you dont set the VSprite.Flag in the VSprite.Flags 
		variables, the system assumes that your vsprite structure
		is being used to describe a bob. This pointer points to the
		bob structure of the vsprite.

	BYTE PlanePick;
	BYTE PlaneOnOff;
		These two variables determine which bit-planes are on 
		(PlanePick) for displaying your bobs and which are passive
		and written with the Bobs ImageShadow.

	VUserStuff VUserExt;
		With the help of this "extension", the user can combine
		his own data into the vsprite. The VUserStuff function 
		can be defined at any point before the #include statements
		are executed (e.g. #define VUserStuff struct Speed (vx,vy);

    }

The vsprite structure is needed for both types of GELs. Both the vsprite
itself and the bob are applications of this structure.


		--------------------------------------------

struct Window

When you open a new window using WINDOW = OpenWindow(NewWindow), you can
write in the window, bypassing the window structure. This is because you
have a RastPort available (Window->RastPort).

In addition, you can get the window information from Intuition. However,
a detailed description of this will go far beyond the scope of this 
Appendix.		
		
				PAGE 525

-----------------------------------------------------------------------------

   		   APPENDIX B - THE LIBRARY FUNCTIONS

This appendix provides the C programmer with information about the 
library routines used in this book.

First you must open the required libaries (with Openibrary()) before you
can use the library routines.

We have organised the following routine listing by library and in 
alphabetical order.

GFXBASE: First the GfxBase routines :

	------------------------------------------------------------------

AddAnimOb(&AnimOb, &AnimKey, &RastPort)

	These routines are used to organise, in the GEL list of a specific
	RastPort, all the bobs for the animation object. This makes it
	possible for DrawGList() to draw the bobs in an orderly manner.
	The AnimKey points to the last added AnimOb. AnimKey must be equal
	to zero for the first AddAnimOb() call (struct AnimOb*AnimKey = 0).

	------------------------------------------------------------------

AddBob(&Bob,&RastPort)

	This routine adds the specified bob structure for the defined bob
	(Blitter object) to the GEL list for the selected RastPort. You 
	must do this so the bob can later be drawn with DrawGList().

	See: AddVSprite(), DrawGList(), SortGList(), InitGList()

	------------------------------------------------------------------

AddFont(&TextFont)

	This function links the specified TextFont structurem which defines
	your font, with the SystemFontList.

	Once this is done, your font is available to any program you are
	using.
	
				PAGE 527
	
-----------------------------------------------------------------------------

AddVSprite(&VSprite,&RastPort)

	This routine adds the specified vsprite structure, which defines 
	your vsprite (virtual sprite), to the GEL list of the selected 
	RastPort. This is needed so that DrawGList() can later display 
	your Vsprite.

	See: AddBob(), DrawGList(), SortGList(), InitGList()

	------------------------------------------------------------------

Pointer = AllocRaster(Width, Height)

	This function enables you to allocate a memory area for a bitplane
	in a size specified by the width and height. After calling this
	routine, the first word of the memory address is returned in
	pointer.

	See: FreeRaster()

	------------------------------------------------------------------

Animate(&AnimOb,&RastPort)

	This routine applies to all animation objects that are linked to 
	an AnimOb. Animate calculates the new object positions and resets 
	Timer for the animation components. In a ring animation 
	(AnimComp.Flags = RINGTRIGGER), when Timer for a component is equal
	to zero the next sequence is activated.

	See: AddAnimOb()

	------------------------------------------------------------------

AreaDraw(&RastPort,x,y)
	
	This function adds a polygon to the AreaInfo structure for the 
	specified RastPort. X and Y determine the coordinates of this 
	point in the BitMap.

	See: AreaMove(), AreaEnd(), InitArea()
	
				PAGE 528

-----------------------------------------------------------------------------

AreaEnd (&RastPort)

	This function executes the drawing of a polygon, which is defined
	with AreaMove() and AreaDraw(). It also fills the polygons with the
	current fill pattern controlled by the current APens, BPens, OPens
	and Draw modes.

	The APen and BPen determine the color of the fill pattern. The 
	OPen sets the framing colour for the polygon.

	Remember that you must first initialise an Area and TmpRas structure
	in the RastPort where the polygon will be drawn. Unless you do 
	this first, filling an area using the Area... function will not 
	function.
	
	See: AreaDraw(), AreaMove(), InitArea(), InitTmpRas.

	------------------------------------------------------------------

error = AreaEllipse(&RastPort, XMiddle, YMiddle, XRadius, YRadius)

	This function allows you to draw an ellipse in the selected RastPort.
	The centre is at XMiddle,YMiddle. XRaduis and YRadius set the
	radius for the ellipse. (When XRadius = YRadius a filled circle 
	is drawn. Remember that XRadius and YRadius must be greater than 
	zero).

	AreaEllipse is an expansion of the Area.. function. This means that
	a filled ellipse is drawn using the current fill pattern.. It also
	means that an AreaInfo amd TmpRas structure must exist in the 
	selected RastPort.

	The variable ERROR provides information about the vector table,
	which contains the coordinates for the polygon plot points in
	AreaInfo. It tells you whether or not there is enough room 
	(minimal (2+1)*5 bytes) for the data required for an ellipse
	(error = 0). If ERROR returns a -1 there isnt enough room.

	You must call AreaEnd() to execute the drawing of the ellipse.

	See: AreaDraw(), AreaEnd(), AreaMove(), InitArea(), InitTmpRas.

				PAGE 529

----------------------------------------------------------------------------

AreaMove(&RastPort,x,y)

AFter building your polygon with AreaDraw(), close it with this routine.
Any additional AreaDraw() functions will start a new polygon with the 
above coordinates.

See: AreaDRaw(), AreaEnd(), InitArea()

	------------------------------------------------------------------

AskFont(&RastPort, &TextAttr)

	This function initialises, in the selected RastPort, the specified
	TextAttr structure with the values of the current font. You can
	use this function to check the RastPort for the currently active
	font.

	See: SetFont()
	
	------------------------------------------------------------------

Style = AskSoftStyle(&RastPort)

	This function moves, into the selected RastPort, all the possible
	font styles that can be set with AskSoftStyle. Each set bit in 
	style represents a font style:

		FSF_UNDERLINED  = Bit 0    = 1 (Underlined)
		FSF_BOLD        = Bit 1    = 2 (Bold)
		FSF_ITALIC      = Bit 2    = 4 (Italic)
		FSF_NORMAL      = No set bit = 0

	See: SetSoftStyle()

	------------------------------------------------------------------

BitPlanes = BltBitMap(&SourceBitMap,X1,Y1,&TargetBitMap,X2,Y2,Width,
		       Height,Minterm,Mask,Buffer).

	This function blitters a rectangle from one bitmap into another 
	bitmap. You must specify the source rectangle coordinates from the 
	SourceBitMap(X1,Y1) and the position for the rectangle in the 
	TargetBitMap(X2,Y2). Since the width and the height are the same for
	both rectangles, they are set only once. You must reference both the
	source and target bitmaps. Remember that these can also be references
	within the same bitmap.

				PAGE 530

-----------------------------------------------------------------------------

	You also specify the minterm which determines how the source and 
	target rectangles are logically mixed. What the minterms do and 
	which ones exist is discussed in Chapter 16.

	The Mask parameter determines which bitplanes are blittered. The
	default value is $ff which means that all bitplanes are referenced.
	You can also filter out specific bitplanes by clearing the 
	corresponding bit (bit zero for bitplane zero etc.).

	Buffer points to a memory area that is used when a target and source
	rectangle overlap in the same bitmap. This buffer must have enough
	memory to store one row of the rectangle. When you are sure that the
	two rectangles do not overlap, you can set the pointer to zero.

	The result returned by this function is from the "Blit" affected
	bitplanes (see Mask).

	Remember that this routine doesnt test whether the target 
	rectangle fits completely within the target bitmap. It is possible 
	to blitter over the edge of a bitmap. This can cause errors which
	results in less bitplanes  being affected than expected. With 
	extreme error conditions you will encounter the familiar Guru
	Meditation.

	See: ClipBlit()

	------------------------------------------------------------------

BltBitMapRastPort(&SourceBitMap,X1,Y1,&TargetRastPort,X2,Y2,Width,
		   Height,Minterm)

	This function performs exactly the same operation as BltBitMap().
	This time you are moving a rectangle from a bitmap into a
	RastPort.
	
	The Mask and Buffer parameters are not required here.

	THe result returned by this function is TRUE = successful,
	FALSE = error.

	See: BltBitMap()
	
	------------------------------------------------------------------

BltClear(&Memory, NumBytes, Flags)

	As the name indicates, this function erases a selected memory area.
	You simply specify the starting address.
	
	The flag parameter determines how the NumBytes value is interpreted:

				PAGE 531
	
-----------------------------------------------------------------------------

	With bit one of the flag parameter set to 1:
	
	The upper 16 bits of NumBytes is the number of lines to erase.
	
	The lower 16 bits of NumBytes is the number of bytes per line 
	to erase.


	Width bit one set to zero NumBytes represents the actual number of 
	bytes to erase.

	Bit zero of the flags parameter determines whether the function is 
	immediately return to the program or wait until the blitter has 
	erased everything.
	
	------------------------------------------------------------------

BltTemplate(&Source, BitPosition, Modulo, &RastPort, X, Y, Width,
	     Height)
	
	This function uses the blitter to transfer data from a packed
	array into a RastPort. You provide the address of the packed 
	array and the bit position within this array, where the data 
	read should start.
	
	Modulo specifies the number of bytes for one row in the data array.
	X,Y, width  and height set where and how much data from the array is
	moved to the RastPort.
	
	------------------------------------------------------------------

ChangeSprite(&ViewPort,&Sprite,&SpriteData)
	
	This function changes the appearance of the specified hardware 
	sprites. Remember that the hardware sprite must be initialised 
	already. This ensures that the height and screen position are already
	set and that the correct hardware sprite (SimpleSprite.num) is 
	affected.
	
	The data used by this function have the following format:
	
	    struct SpriteData
		{
			UWORD posctl[2];
			UWORD Data[Height][2];
			UWORD Reserved[2]; /* = 0,0 */
		}
	
	posctl represents the sprite hardware register spr[x].pos and 
	spr[x].ctl. This allows the user to use GetSprite() to reserve both
	the even and odd numbered sprites and set the SPRITE_ATTACHED bit in
	posctl[l] for attached sprites. When the bit pattern of both sprites
	overlap, they are merged. This permits the use of 15 colors instead
	of only three (plus transparent).

	See: GetSprite(), FreeSprite(), MoveSprite()

				PAGE 532
	
-----------------------------------------------------------------------------

ClearEOL(&RastPort)

	This function deletes one row, in the selected RastPort, that has 
	the height of the character in the current font. This deletion 
	starts at the current graphic cursor position (RastPort.cp_x,
	RastPort.cp_y).

	See: ClearScreen(), Move()
	
	------------------------------------------------------------------

ClearScreen(&RastPort)

	In contrast to the ClearEOL() function, which only clears one row,
	ClearScreen deletes the entire RastPort from the current graphic
	cursor position.
	
	See: ClearEOL(), Move()
	
	------------------------------------------------------------------
	
ClipBlit(&SourceRastPort,X1,Y1,&TargetRastPort,X2,Y2,Width,Height,
	  Minterm)
	
	This function performs exactly the same function as BltBitMap().
	Most of the parameters have the same meaning. But with this function
	we blit from one RastPort to another and any overlapping problems 
	are handled by the routine.
	
	This function is much better because it is easy to use (you do not
	have to reserve a buffer) and it prevents you from creating any 
	error conditions. Blitting over the border of a RastPort does not
	create the problems possible with BltBitMap().
	
	See: BltBitMap(), BltBitMapRastPort()
	
	------------------------------------------------------------------
	
CloseFont(&TextFont)
	
	When you have opened a font with OpenFont() or OpenDiskFont() you
	must also close it again before ending your program. Otherwise the
	memory used by your font is not released back to the system.	
	
	See: OpenFont()
	
				PAGE 533

-----------------------------------------------------------------------------
	
DisownBlitter()
	
	This function releases the blitter from your control and allows
	other programs to use it again.
	
	See: OwnBlitter()
	
	------------------------------------------------------------------

DoCollision(&RastPort)
	
	This routine tests all GELs in the GEL list for a RastPort, for 
	collisions and also executes any collision routines you have set up
	with SetCollision().
	
	However, we must inform you that DoCollision() does not function all 
	the time.
	
	See: SetCollision.
	
	------------------------------------------------------------------
	
Draw(&RastPort,x,y)
	
	This is one of the most important graphic functions. DRAW allows 
	you to draw a line from the current graphic cursor position to the 
	selected X/Y coordinate in the specified RastPort.
	
	See: Move()
	
	------------------------------------------------------------------
	
DrawEllipse(&RastPort, XMiddle, YMiddle, XRadius, YRadius)
	
	This function allows you to draw ellipses or, with XRadius = 
	YRadius, circles. These are not filled as with AreaEllipse; only 
	the outline is drawn.
	
	Remember that XRadius and YRadius must contain values that are 
	greater than zero.
	
				PAGE 534
	
-----------------------------------------------------------------------------

DrawGList(&RastPort,&ViewPort)
	
	DrawGList() performs two functions. First it can draw the bobs, from 
	the GEL list in the selected RastPort. Second, it can link the 
	vsprites, from the ViewPort copper list, with the Selected ViewPort.

	However, vsprites are not drawn after calling DrawGList(). First 
	you have to use MakeVPort() or MakeScreen() to set up the new Copper
	list. Then you use MrgCop() and LoadView() or RethinkDisplay to 
	display them.
	
	See: MakeVPort(), MrgCop(), LoadView(), MakeScreen(), 
	     RethinkDisplay()

	------------------------------------------------------------------
	
Flood(&RastPort, Mode, x, y)
	
	This function enables you to fill an area in a RastPort. All the 
	pixels around the area from the specified X/Y positions are tested 
	and filled according to the mode selected. Mode = 0 tests for the 
	colour of the  Open and mode=1 tests for the color of the starting
	pixel.
	
	Any pixels around your starting point that dont meet the 
	requirements of either mode are filled with the current fill 
	pattern. When the pixel meets one of the mode criteria it is not
	changed.
	
	When all pixels within a closed border meet the mode criteria and 
	are already filled, the fill is cancelled.
	
	Remember that for the Flood() function a TmpRas structure must be
	initialised and must have enough memory  to be used by the Flood()
	function.
	
	See: InitTmpRas()
	
	------------------------------------------------------------------
	
FreeColorMap(&ColorMap)
	
	You use this function to release the memory, which was reserved 
	through GetColorMap() for the ColorMap structure, back to the 
	system.
	
	See: GetColorMap()
	
				PAGE 535
	
-----------------------------------------------------------------------------

FreeCopList(&CopList)

	Call this routine in order to release a single intermediate Copper
	list for a ViewPort (struct CopList), which was created by using 
	MakeVPort(). FreeVPortCopList() uses this routine to release all
	intermediate lists from a ViewPort.

	See: FreeVPortCopList()

	------------------------------------------------------------------

FreeCprList(&cprlist)

	Use this function to release the memory reserved, through 
	View.LOFCprList and View.SHFCprList, for the hardware Copper list.
	These hardware copper lists are calculated from the individual 
	ViewPort Copper lists by using MrgCop().

	See: MrgCop()

	------------------------------------------------------------------

FreeRaster(&BitPlane, Width, Height)

	This function produces the opposite effect of AllocRaster(). It 
	releases all reserved bitplane memory, that was allocated with
	AllocRaster(), back to the system. This makes the memory available
	to other programs again.

	BitPlane points to the memory area that you reserved with 
	AllocRaster. Width and Height must be the same for free and 
	AllocRaster(), otherwise it is possible to release too much or too
	little memory.
	
	See: AllocRaster()

	------------------------------------------------------------------

FreeSprite(SprNumber)

	With FreeSprite you can release a sprite, that was reserved 
	specifically for your through GetSprite() back to the system.
	This makes the sprite available again for full system use 
	(especially the vsprites).

	You just provide the number of the sprite that was reserved with
	GetSprite().
	
				PAGE 536

----------------------------------------------------------------------------

	See: GetSprite(), ChangeSprite(), MoveSprite()

	------------------------------------------------------------------

FreeVPortCopLists(&ViewPort)

	With this function you can release, for the specified ViewPort that
	you generated with MakeVPort(), all the Copper lists for the 
	colour, display, sprites etc...
	
	See: MakeVPort(), FreeCopList()

	------------------------------------------------------------------

*ColorMap = GetColorMap(NumberColors)

	This function create a complete ColorMap structure. All of the 
	required ColorMap structure variables are initialised and enough
	memory is reserved for the specified NumberColors. When sufficient
	memory is not available for the new ColorMap structure or color
	buffer, a ZERO(0) is returned by the routine.
	
	You must link this ColorMap structure to the ViewPort with 
	ViewPort.ColorMap = ColorMap(before using MakeVPort() to calculate
	the Copper list for the ViewPort).

	See: FreeColorMap(), LoadRGB4(), GetRGB4(), SetRGB4()

	------------------------------------------------------------------

Color = GetRGB4(&ColorMap,ColorRegister)

	This function enables you to retrieve the UWORD that determines 
	the color of the selected color register. The 16 bit UWORD 
	which is returned is divided as follows: bits 0-3 are the blue 
	component, bits 4-7 the green and bits 8-11 red.
	
	See: SetRGB4(), LoadRGB4()
	
	------------------------------------------------------------------
	
SprNumber = GetSprite(&SimpleSprite,getSprNumber)
	
	This function allows you to reserve any hardware sprite for your
	personal use. You provide the SimpleSprite structure, that the
	sprite will be associated with, to the function. Also, select the
	desired number (0-7) (if it doesnt matter a -1) of the reserved
	sprite.
	
	The number of the reserved is returned is returned in the 
	SpriteNumber. If the selected sprite is not available, SpriteNumber
	contains a -1.

	See: FreeSprite(), MoveSprite(), FreeSprite()
	
				PAGE 537

-----------------------------------------------------------------------------

InitArea(&AreaInfo,&Buffer,NumCoord)

	This function initialises the selected AreaInfo structure for you.
	The structure contains the specified Buffer and the NumCoord+1
	coordinates required for AreaDraw() and AreaMove(). The buffer 
	should contain at least five time the number of bytes that are
	required for the polygon coordinates which are used with AreaMove()
	and AreaDraw().
	
	Declaring the buffer as a char array is the easiest method. Since
	programs created with the compiler automatically releases arrays,
	you dont have to release the used buffer area again.

	See: AreaDraw(), AreaMove(), AreaEnd()

	------------------------------------------------------------------

InitBitMap(&BitMap, Depth, Width, Height)

	This routine initialises the specified BitMap structures. The
	depth (number of bitplanes), width (in pixels), and the height
	(in rows) is easily set.
	
	See: AllocRaster()

	------------------------------------------------------------------

InitGels(&Begin, &End, &GelsInfo)
	
	This function initialises the selected GelsInfo structure. You need
	this structure in order to display vsprites and bobs in an organised
	manner.

	All the graphic elements (=GEL) are linked in a list through the
	vsprite structures (&Begin, &End). &Begin and &End mark the 
	beginning and end of this GEL list.

	After you have used InitGels() to initialise the GelsInfo structure,
	then simply make them available to your RastPort (RastPort.GelsInfo =
	&GelsInfo). Once this is accomplished, you can start displaying 
	your bobs and vsprites.
	
	
	See: AddVSprite, AddBob()

				PAGE 538

-----------------------------------------------------------------------------

InitMasks(&VSprite)

	You initialise the BorderLine and CollMask for the specified 
	vsprite structure with this routine. The memory buffer for both
	masks must be reserved already and stored in the variables 
	VSprite.BorderLine and VSprite.CollMask.

	------------------------------------------------------------------

InitRastPort (&RastPort)

	You use this routine to initialise the specified RastPort 
	structure. This RastPort structure is the most important connection
        between the user and BitMap.

	The RastPort contains, for example, the color of the current 
	foregroundpen(APen). It also contains a pointer to the bitmap 
	where the graphic functions will be executed and many other 
	important variables and pointers used by the graphic functions.

	------------------------------------------------------------------

TmpRas = InitTmpRas(&TmpRas,&Buffer,BufferSize)

	When you use the Area...() functions within a RastPort, an extra
	memory area is required for these functions. This buffer must be
	at least as large as the object being filled. Because of the 
	recursive algorithm used by fill, extra memory is required as
	workspace.

	This buffer only requires one bitplane which is as large as the 
	largest element. To ensure that you have enough, it is best to 
	reserve one complete bitplane for the temporary raster.

	Now simply pass the initialised TmpRas structure to your RastPort.
	There are two possible ways to do this. You can either use the 
	result returned by the initialised TmpRas structure (RastPort.
	TmpRas= InitTmpRas (....)) or pass the initialised TmpRas structure
	yourself (RastPort.TmpRas = &TmpRas).

				PAGE 539

-----------------------------------------------------------------------------

InitView(&View)

	This function is used to initialise the specified View structure.
	All variables and pointers  for the View structure are first set
	to zero. Then the DxOffset and DyOffset variables are set so that
	the View is positioned approximately two centimetres below the top
	right monitor border. This assumes that the monitor is properly	
	adjusted.

	See: MrgCop(), MakeVPort()

	------------------------------------------------------------------

InitVPort(&ViewPort)

	This function is used to clear all variables and pointers for the
	selected ViewPort structure. This is done so that the individual
	Copper lists for this ViewPort will be correctly calculated with
	MakeVPort(). When a pointer to a ViewPort Copper list is not equal
	to zero, MakeVPort() assumes that a ViewPort Copper list exists
	and does not calculate a new one.

	Undefined Copper lists could be created without this MakeVPort()
	feature.

	See: MakeVPort()

	------------------------------------------------------------------

LoadRGB4(&ViewPort,&Colotpalette[0],Colorentry)

	This routine allows you to load new colour values, ColorEntry from 
	the ColorPalette (UWORD Colorpalette[Colorentry];) into the 
	ColorMap for the selected windows.

	Using this routine is an easy way to change all the colours of a 
	ViewPort at one time. However, the change is not immediate. First
	you have to calculate a new color Copper list for the ViewPort. You
	do this with MakeVPort(), MrgCop() and then LoadView(). When using
	intuition screns substitute RemakeDisplay() for LoadView().

	See: SetRGB4(), GetRGB4()

				PAGE 540

-----------------------------------------------------------------------------

LoadView(&View)

	After calling this function, the selected View and all ViewPorts
	it contains are displayed on the screen. You must first use 
	MakeVPort() for each ViewPort that will be displayed in the View.
	MakeVPort() creates the ViewPort Copper lists that MrgCop() merges
	into a single View Copper list.

	The View Copper list starting address is written by LoadView() in 
	the necessary hardware registers (cop11c, cop21c).

	See: InitView(), InitVPort(), MakeVPort(), MrgCop()

	------------------------------------------------------------------

MakeVPort(&View,&ViewPort)

	This routine calculates the intermediate ViewPort Copper lists for
	the selected ViewPort of the specified View. For example, there are
	ViewPort Copper lists for color display for all colors which are
	written through the Copper to the hardware registers. These color
	copper lists are calculated from the ViewPort colormap. When the 
	color list pointer is equal to zero, the default ColorMap is
	used to calculate the ViewPort color Copper list.

	These lists also contain the various resolution modes for the 
	ViewPorts (many ViewPorts in one View can have different 
	resolutions).

	See: MrgCop(), FreeVPortCopLists()

	------------------------------------------------------------------

Move(&RastPort,X,Y)

	You use this function to position the graphic cursor for the 
	selected RastPort to the specified position (RastPort.cp_x = x;
	RastPort.cp_y = y;)

	At this position you could print text or draw a line to another
	position.

	------------------------------------------------------------------

MoveSprite(&ViewPort,&SimpleSprite, X,Y)

	This function lets you position the selected hardware sprites within
	the selected ViewPort when ViewPort is not equal to zero. Otherwise,
	the sprite will be positioned relative to the View.

	X and Y specify the new position. Remember that the position values
	in hi-res or lace ViewPorts must be multiplied by two so that the
	sprite actually moves.

	See: ChangeSprite(), GetSprite(), FreeSprite()

				PAGE 541

-----------------------------------------------------------------------------

MrgCop&(View)

	This function calculates the View hardware Copper list from the 
	ViewPort Copper lists created with MakeVPort(). Then this list is
	used by the hardware(cop11c,cop21c).
	
	Any change to the colortable or the hardware sprite positions 
	requires a newly calculated copper list. This happens automatically
	when the hardware sprites are moved. When changing the colorpalette
	with LoadRGB4() you must update the Copper list.

	See: MakeVPort(), FreeCprList()

	------------------------------------------------------------------

*TextFont = OpenFont(&TextAttr)

	This function searches through the SystemFontList for a font 
	described by the TextAttr structure. When a font cannot be found
	to match the named TextAttr structure, a value of zero is returned.
	However, when a font is found but has different styles or sizes, a 
	font that best meets the specifications is selected.

	OpenFont() increases user choices when accessing the Systemfonts.
	OpenFont() and CloseFont() must maintain a balance in order to 
	guarantee a clean memory. When a font is no longer required you 
	can remove it from memory with  RemFont().
	
	See: CloseFont(), AddFont(), RemFont(), OpenDiskFont(),
	     AvailFonts().

	------------------------------------------------------------------

OwnBlitter()

	This function informs the Blitter that it is only able to work 
	for you. Other tasks (programs) that are running at the same time
	can no longer use the blitter.

	After OwnBlitter(), you should use WaitBlit() to allow the Blitter 
	to complete any current processing.

	See: DisownBlitter(), WaitBlit()

				PAGE 542

----------------------------------------------------------------------------

PolyDraw(&RastPort.NumCoords, &PixelArray)

	This routine enables you to draw into the selected RastPort by 
	using coordinates from any array you created. Lines are drawn from 
	pixel to pixel as plotted from the array.

	THe pixels are stored in an integer array (int PixelArray	
	[NumCoords][2]) with each coordinate consisting of two array 
	elements. The first element is the X and the second is the Y 
	coordinate for the stored polygon pixels

	NumCoords specifies the number of pixels that will be drawn from 
	the pixel array.

	------------------------------------------------------------------

ColorRegister = ReadPixel(&RastPort, X, Y)

	This function allows you to read the color value of a specific
	pixel at the coordinates you selected.

	When your coordinates are outside the selected RastPort, a value
	of -1 is returned in ColorRegister.

	See: WriteAPen(), SetAPen()

	------------------------------------------------------------------
		
RectFill(&RastPort, X1, Y1, X2, Y2)

	With this function you can fill any desired rectangular area within
	the selected RastPort. The current fill pattern, Drawmodes, APens,
	etc.. affect how your fill is performed.
	
	You just specify the top left corner (X1,Y1) and the lower right
	corner (X2,Y2) of the rectangle you want filled. Make sure that
	the lower right corner really is lower and to the right of the 
	upper left corner. When your coordinates are incorrect the computer
	can crash because your memory will be filled without the proper
	controls.

				PAGE 543

-----------------------------------------------------------------------------

	This function does not require a TmpRas structure like the Flood()
	and Area...() functions.

	------------------------------------------------------------------

RemFont(&TextFont)

	This function removes the selected font from the system font list.
	The font remains available to any programs currently using it.
	After all programs signal, with CloseFont(), that this font is no 
	longer required, the font is pysically removed from memory.
	
	After you have used RemFont() a program that has used CloseFont()
	cannot access the font again.
	
	See: AddFont(); OpenFont(); CloseFont()

	------------------------------------------------------------------
	
RemIBob(&Bob, &RastPort, &ViewPort)
	
	This function immediately removes the selected bob from the GEL,
	list for in RastPort and deletes it from the RastPort.
	
	See: DrawGList(), SortGList(), InitGels()

	------------------------------------------------------------------

RemVSprite(&VSprite)

	This routine deletes the selected vsprite from the current GEL 
	list. However, the sprite does not immediately dissappear from the
	screen. This occurs only after the calls to SortGList(), DrawGList(),
	MakeVPort(), MrgCop(), LoadView().

	See: DrawGList(), SortGList()

	------------------------------------------------------------------

ScrollRaster(&RastPort, DeltaX, DeltaY, X1, Y1, X2, Y2)
	
	This function scrolls the rectangle, specified by X1, Y1, X2, Y2
	(see RectFill), for DeltaX pixels and DeltaY rows. Positive delta
	values scroll up and left. Negative delta values scroll right and
	down. Combatting negative and positive 'Delta' values allows you
	to scroll in any desired direction.
	
				PAGE 544
	
-----------------------------------------------------------------------------

	The areas uncoverd by the scrolled rectangle are filled with the
	color of the BPen.
	
	Please note that this routine is not very fast and can cause some
	flickering during the scrolling.

	------------------------------------------------------------------

ScrollVPort(&ViewPort)

	After you have changed the RxOFfset and RyOffset values in the 
	RasInfo structure of the ViewPort, use ScrollVPort() to display
	a different portion of the bitmap. ScrollVPort calculates the 
	new copper list for the new bitmap position.

	This routine is not fast enough to prevent some flickering on the
	screen. Because of this, you should calculate the new Copper list
	since this can be performed as a background process.

	------------------------------------------------------------------

SetAPen(&RastPort,Colorregister)

	This function allows you to select, in the selected RastPort, a new
	color for the APen.ColorRegister selected the number of the colour
	register in the ViewPort ColorMap.

	See: SetBPen()
	
	------------------------------------------------------------------
	
SetBPen(&RastPort,ColorRegister)

	Just like SetAPen, the color of the BPen is changed in the selected
	RastPort. Again, ColorRegister specifies the number of the color
	register to be used from this point on.
	
	APen and BPen functions differently depending on which drawing mode
	you are using. With JAM2 mode, the BPen functions as the background
	color pen. For example, text would be highlighted with the BPen.
	The BPen has no effect in other draw modes.
		
	See: SetAPen()
		
				PAGE 545

-----------------------------------------------------------------------------
	
SetCollision(Number, Routine, &GelsInfo)
	
	After comparing the MeMask and HitMask, this function sets the 
	collisions routines that are used for collisions between GELs or
	a GEL with a border.

	With GEL to GEL collisions you must pass both vsprite structures to
	your collision routine. The first vsprite structure passed 
	represents the upper left positioned GEL (bob or vsprite).

	With border collisions, you pass the involved vsprite structure
	and a flag to your routine. The flag contains the code for the
	border (TOPHIT, BOTTOMHIT, LEFTHIT, RIGHTHIT) the GEL collided
	with.
	
	See: DoCollision()
	
	------------------------------------------------------------------

SetDrMd(&RastPort, Mode)

	Use this function to set the DrawMode for your RastPort. This sets
	up how lines are drawn, how pixels are set and how text is 
	displayed. The following modes exist:

	JAM1 (0): Only the APen colour is used for drawing.
	JAM2 (1): The BPen colour is used for the background.
	COMPLEMENT(2): Pixels to be drawn are first XORed with the 
		       existing pixels (by bitplane).
	INVERSVID(4) : Pixels are inverted before being drawn (by bitplane).
	
	The modes COMPLEMENT and INVERSVID only function with JAM1 or 
	JAM2.

	------------------------------------------------------------------

SetFont(&RastPort,&Font)

	SetFont() makes a font available to the selected RastPort. This 
	font should have alreay been opened with OpenFont() or
	OpenDiskFont(). Any text you know output with Text() will appear 
	in the new font.

	See: OpenFont(), CloseFont()

				PAGE 546

----------------------------------------------------------------------------

SetRast(&RastPort, Colorregister)

	This function sets all pixels in the selected RastPort bitmap, to 
	the color of the colour register from the ViewPort's colormap
	for this RastPort.
	
	When ColorRegister equals zero, then all the pixels of the ViewPort's
	ColorMap are cleared to colour zero (= background color).

	------------------------------------------------------------------
	
SetRGB4CM(&ColorMap, Colorregister, Red, Green, Blue)
	
	This function works similar to SetRGB4. However, the color change 
	is not immediately visible. This happens only after you 
	calculate the Copper list again with RemakeDisplay.

	The colour change first occurs in the selected colormap before it 
	is allowed to be visible.
	
	Like LoadRGB4, the colormap is initialised with new values in the
	background.
	
	See: LoadRGB4()
	
	------------------------------------------------------------------

SetRGB4(&ViewPort, ColorRegister, Reg, Green, Blue)
	
	This function allows you to change the color of one color register
	in the specified ViewPort. You pass the number of the color register
	and the new red, green and blue components (0-15) for the new
	color value.

	SetRGB4() also changes the color entry in the ColorMap structure of
	the ViewPort amd in the Copper list. This colour change is 
	immediately visible on the screen.
	
	See: LoadRGB4(), GetRGB4()

				PAGE 547

-----------------------------------------------------------------------------

NewStlye = SetSoftStyle(&RastPort, FontStyle, Style)

	This function sets your desired, algorithmically generated font
	style in the selected RastPort. You set the desired style in 
	FontStyle (see AskSoftStyle()) and use the value returned by 
	AskSoftStyle in Style. AskSoftStyle() provides the available 
	styles that can be used for the Style variable. For example,
	it is possible that a font is already italic and after 
	AskSoftStyle() provided that information, it would be useless
	to try to make that font italic.
	
	SetSoftStyle() changes a font only when the style-bits are also 
	set in Style. After the change, NewStyle contains the font 
	generated by SetSoftStyle().
	
	See: AskSoftStyle()
	
	------------------------------------------------------------------

SortGList(&RastPort)

	This routine sorts the GEL list of the selected RastPort. The
	vsprite structures used for positioning vsprites and bobs are 
	sorted by their Y and X coordinates. The sort is performed by the
	Y and then by the X coordinate.
	
	After using SortGList() you use DrawGList() to display the GEL
	list again.
	
	See: DrawGList()
	
	------------------------------------------------------------------
	
Text(&RastPort, &"string", NumCharacters)
	
	This routine lets you display, at the graphic cursor position, any
	desired text in the selected RastPort. You simply provide the 
	starting address of the output string and the number of characters
	to be displayed.
	
	See: TextLength()
	
	------------------------------------------------------------------
	
Length = TextLength(&RastPort, &"String", NumCharacters)

	This function has the same parameters as Text(). The length in 
	pixels for the text string is returned and the RastPorts currently
	active font is used to display the text.
	
				PAGE 548

	See: Text(), SetFont()
	
-----------------------------------------------------------------------------

Position = VBeamPos()
	
	This function returns the current vertical position of the 
	electronic raster beam in "position". The values that are returned
	fall between 0 and 255 on PAL systems. Because the electron beam
	actually scans 262 lines on PAL systems, the positions between
	256 and 262 are returned as values between zero and 6.

	After your program has received it, the value returned by 
	VBeamPos() is usually useless. Due to the Amiga's multitasking
	capabilities, the millisecond reaction time, required by your
	program to react, can be used up by another program or task.

	------------------------------------------------------------------

WaitBlit()
	
	This function pauses your program until the blitter has completed
	its task. Be careful because a processor error can cause WaitBlit()
	to return actually before completing the desired task. Your program
	is then able to continue its tasks before they should occur.
	Most often, this error occurs when you are using hires with 
	four bitplanes.

	------------------------------------------------------------------

WaitBOVP(&ViewPort)	
	
	This function pauses your program until the electron beam reaches 
	the last row of the selected ViewPort (Bottom of ViewPort).
	
	See: WaitTOF()
	
	------------------------------------------------------------------

WiatTOF()

	This function is similar to WaitTOF() except that the pause doesnt
	happen until the end of the ViewPort. WaitTOF() waits for the 
	electronic beam to reach "Vertical Blank" (top of frame) or the
	start of a new scan after completing any cyclic routines 
	(Interrupts)
	
	See: WaitBOVF()
	
				PAGE 549
	
-----------------------------------------------------------------------------

WritePixel(&RastPort,x,y)

	This function sets a pixel at coordinates X and Y, in the APen
        colour in the selected RastPort. Naturally, the current drawing 
	mode of the RastPort is used.

	See: ReadPixel()

/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\

                             DISKFONTBASE
			     ============

Now to the DiskFontBase functions (you must first open the library 
"diskfont.libraries"

	----------------------------------------------------------
	
Error = AvailFonts(&Buffer, BufferSize, Typ)

	This function provides a complete list of the available system 
	fonts. This list is written into the memory area (&Buffer),
	which contains the BuffserSize that you selected.

	The first thing stored in the buffer is the AvailFontsHeader. This
	contains the number of font entries that are stored (in 
	AvailFontsHeader.afh_NumEntries). Then the various AvailFonts 
	entries, which contain the type of font, (either in the system font
	list (AFF_MEMORY) or on disk (AFF_DISK) and the more descriptiive
	TextAttr structure are stored.

	The TextAttr structure can be used to open a font. However, this
	must be done by type (AFF_MEMORY / AFF_DISK) in order to open one
	with OpenFont() or OpenDiskFont().

	THe AvailFonts parameter TYP determines whether the Systemfontlist
	(AFF_MEMORY), SYS:Fonts (AFF_DISK) or both are searched for 
	available fonts.
	
	Please note that AvailFonts() does not verify the TextAttr structure
	contents for SYS:Fonts from disk. When you open fonts using
	OpenDiskFont() with the returned TextAttr structure of AvailFonts(),
	you can encounter such undesired results as a system crash.

	The results returned by AvailFonts() provide information on whether
	or not enough memory is available to store all the AvailFont
	structures. When error equals zero there is enough memory. However,
	when error is not equal to zero or the number of additional bytes
	that are required to contain all the AvailFonts structures is 
	returned instead.

				PAGE 550

-----------------------------------------------------------------------------

*TextFont = OpenDiskFont(&TextAttr)

	This function opens a font described by the TextAttr structure.
	The SYS:Fonts directory is searched for a font that best matches
	the TextAttr structure in style and size. If a matching font in the
	TextAttr structure cannot be found, a value of zero is returned.

	See: OpenFont.

\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\

			   INTUITIONBASE
			   =============

The following are the IntuitionBase routines (IntuitionBase is the 
pointer to the Intuition library that you open with IntuitionBase =
(struct IntuitionBase *) OpenLibrary("intuition.library",0)

		--------------------------------------------

CloseScreen(&Screen)
	
	Use this function to close a screen that was opened earlier with
	OpenScreen(). The memory used for the bitmap and all Intuition
	screen structures (ViewPort, RastPort etc..) is released.

	When you close the last user-opened screen, the workbench screen
	is automatically active again. CloseScreen() does not check 
	whether all windows for a screen have been closed. If any 
	windows are still open a system crash will occur.

	See: OpenScreen()

	-----------------------------------------------------------------

CloseWindow(&Window)

	This function closes a window you have opened with OpenWindow().
	Make sure that you close all the windows in a screen before 
	attempting to close the screen window.

	See: OpenScreen()

	------------------------------------------------------------------

DisplayBeep(&Screen)

	This function blinks the screen by quickly changing the background
	color of the screen. This technique is used in order to make the
	user aware of small errors.
			
				PAGE 551

-----------------------------------------------------------------------------

	By using a zero instead of a screen address you can blink all the
	Intuition screens. However, this should only be used to indicate
	a rather extreme user error.

	------------------------------------------------------------------

MakeScreen(&Screen)

	This function executes MakeVPort() for the ViewPort of the specified
	screen. You can make changes to the intuition screens' ViewPorts
	(such as color changes with LoadRGB4() and inform the copper 
	afterwards).

	See: MakeVPort()

	------------------------------------------------------------------

ModifyIDCMP(&Window,IDCMPFlags)

	This function is used to change the IDCMP flags (Intuition Direct
	Communication Message Ports) for a window. These flags are used
	for various messages that are sent by Intuition to your window.
	However, it is impossible to explain all the possibilities of the 
	IDCMP's in this Appendix.

	------------------------------------------------------------------

OpenScreen(&NewScreen)

	This function opens an Intuition screen that is further described 
	by the selected NewScreen structure. This function creates a 
	ViewPort and all the other required structures (bitmap, RastPort, 
	etc..). The new screen is linked to the Intuition View and
	then displayed.

	See: CloseScreen().

	------------------------------------------------------------------

RemakeDisplay()

	This funnction calculates a new Copper list for all intuition
	screens. This means that for each screen, a MakeScreen() and
	then a ReThinkDisplay() is called. When using this function,
	you should disable multi-tasking for a short time.
	
	See: MakeScreen(), ReThinkDisplay()

				PAGE 552

-----------------------------------------------------------------------------

ReThinkDisplay()

	This function executes MrgCop() and LoadView() for the intuition
	View. Multitasking is turned off shortly while this is executing.
	
	See: MakeScreen(), RemakeDisplay(), MrgCop(), LoadView()

/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\


Here are the DosBase routines (Please note that DosBase, just like the 
ExecBase, dont have to be opened because in these C programs they are 
always open).

Delay(Time)

	This routine pauses you program "Time" * 1/60 seconds. Other 
	running tasks are not paused as with a pause using for().

	------------------------------------------------------------------

Exit(ReturnValue)

	This function allows you to exit a program loop at any time. When
	you run your program as an 'overlay-process', the "return value"
	is passed to your main process. We did not use the program overlay
	technique in our examlple programs.

/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\

EXECBASE : The following are the execbase routines:

*Memory = AllocMem(NumBytes,Use)

	This routine is used to declare NumBytes of memory for your use.
	You must also specify what memory you require. When you use 
	MEMF_CHIP (MEMF = MEMoryFlag) the memory is allocated from the 
	lower 512K bytes area. This is especially important since this
	memory must be used by all the Amiga processors (for example,
	for bitplanes etc..)

	With MEMF_PUBLIC you use a memory area from anywhere. This can
	be an area above 512k bytes if you have more than 512K.

	MEMF_CLEAR allows you to immediately clear the selected memory 
	area. You will receive the address of a completely cleared memory
	area.

	See: FreeMem()

				PAGE 553

-----------------------------------------------------------------------------

CloseLibrary(&BasePointer)

	Use this function to close a library you open earlier with 
	OpenLibrary(). Provide the address pointer that you received when 
	using OpenLibrary() in "BasePointer".

	Please make sure you close all open libraries before exiting 	
	your program.

	See: OpenLibrary()

	------------------------------------------------------------------

FreeMem(&Memory, Size)

	You use this routine to release a memory area that was reserved.
	Simply specify the starting address of the memory area and the 
	number of bytes reserved.

	See: AllocMem()

	------------------------------------------------------------------

Message = GetMsg(&Port)

	By using this function you can intercept messages from Intuition.
	This function waits until a message is sent.

	See: AllocMem()

	------------------------------------------------------------------

OpenLibrary(&LibName,Versionnumber)

	Use this function to open the selected library which gives you
	access to specific operating system routines.

	For example, to use the graphic functions, open the graphic library
	with GfxBase = (struct GfxBase *) OpenLibrary("graphics.
        library",0). GfxBase is the pointer to the requested library
	and must be used with CloseLibrary at the end of your program.

				PAGE 554

-----------------------------------------------------------------------------

	When you dont know the actual version number of the library, use 
	zero, which uses the current library version. However, when a 
	function is available only in a specific version of a library,
	you should quickly exit your program is the library is not found.

	------------------------------------------------------------------

ReplyMsg(&Port)

	Use this function to tell intuition, for example, that you have
	received and processed its messages.

				PAGE 555

-----------------------------------------------------------------------------

		    APPENDIX C - THE HARDWARE REGISTERS
		    ===================================

This appendix provdes an overview of the Amiga hardware registers. Those
registers are useful with Copper programming because they can be easily
changed through the copper.

Use the CMOVE() instruction with the register number that you want to
change. If you want to change a register by using the 68000, you should
only write to specific memory areas.

THe hardware registers are located in a memory area starting at $DFF000.
This means that you must use this address as an offset and then add the
value of the specific register address in order to use the 68000 to
access it.

To access the hardware registers with C, use the Custom structure that 
you create with extern struct Custom custom. As with the Copper or
68000, you can access the individual registers by using custom.Name.

The following list describes hardware registers in detail. We have 
provided the regsiter number as you would define them in your include
file hardware/custom.h. We also show the offset for each register from 
$DFF000. So, both C and machine language programmers have the background
information on the registers and how to use them.

-----------------------------------------------------------------------------

adkcon	$09E  	Audio and disk control (write)
adkconr	$010    Audio and disk control (read)

	As shown, you access these registers differently. You can either 
	write (adkcn) to one, or read (adkconr) from the other.

	The bit structure of both registers is the same. However, even 	
	though bit 15 is not affected by read operations, it is very 
	important for write operations.

    Bit 15 SET/CLR:

	When writing a word with this bit set, all bits (14-0) are written
	into the register. Any unset bits in the word being written do
	not change the corresponding bit already in the register.

				PAGE 557

-----------------------------------------------------------------------------

	If bit 15 is unset in the word being written, all set bits of the
	written word clear any matching set bits in the register. Again,
	any unset register bits are unaffected.

	In order to clearly explain this, we have provided the following 
	short example: When writing the binary value %1111111111111110 all
	bits in the register are set except for zero. With a value of
	%0111111111111110 all bits in the register are cleared except bit
	zero. This type of register control appears very often. Whenever	a CLR/SET bit is used, the above rules will apply.

    Bits 14,13  PRECOMP1/2:
	These bits set the PreComp for disk operations. The value %00 in 
	both registers selects zero ns (nanoseconds). A value of %01
	selects 140ns, %10 selects 280ns and %11 selects 560ns.

    Bit 12 MFMPREC:
	This bit selects the read format for a disk. If it is set, this
	bit selects the normal mfm format. When it is unset, the GCR
	format is selected as for Apple or Commodore 64 disks.

    Bit 11 UARTBRK:
	When this bit is set, all lines of the RS232 interface are set to
	zero (Universal Asynchronous Receiver/Transmitter Break).

    Bit 10 WORDSYNC:
	Setting this bit starts the data transfer over the DMA channel
	and each word read is synchronised with the word in DSKSYNC.

    Bit 9 MSBSYNC:
	This bit determines whether the high bit of a word is synchronised
	in GCR format.

    Bit 8 FAST
	This bit allows you to set the timing for reading a bit from disk.
	Setting this bit selects two microseconds, which is the required
	timing for the MFM format. A value of zero for this bit sets the 
	timing to four microseconds, which is the correct timing for
	GCR type formats. (Apple, Commodore 64).

    Bits 7-4 ATPER3-0:
	These bits allow you to modulate the sampling rate of the 
	inidividual audio channels. Setting ATPER3 stops the sound channel
	output. By setting ATPER2, you can modulate the sampling rate of 
	audio channel three with audio channel two. Setting ATPER1 
	modulates the sampling rate of audio channel two with audio channel
	one. ATPER0 sets the modulation sampling rate between audio 
	channels one and zero.

				PAGE 558

-----------------------------------------------------------------------------

Bits 3-0 ATVOL3-0
	These bits determine the volume modulation of the individual audio 
	channels. The pattern used is the same as ATPER3-0 except that the
	volume is modulated.

	------------------------------------------------------------------

aud[X].ac_ptr $0A0	Audio channel X start address.

	The address for the data that will be sent over the sound DMA 
	channel (direct memory access = without the use of 68000) is
	stored here.
	This is actually a register pair where the data address' lower 15
	bits are stored in $0A2 and the upper three bits are stored in 
	$0A0. Based on the custom declaration in the include file, the
	*ac_ptr is already reserved by the compiler as a long word.

	To directly access this register pair from the C language, you 
	must use an index value between 0 and 3 for the corresponding
	audio channel (aud[X]).

	Machine language programmers must always add X*12 words to access
	a specific sound channel register. This register pair and the 
	following five registers represent a block divided into four
	parts, one after the other. At the end of this Appendix we have
	provided a table showing all the register addresses relative to 
	$DFF000.
	
	Remember that here you can only use 18 bits for addressing. The
	sound chip, as with the Blitter, only uses the lower 512k bytes
	of memory.

	------------------------------------------------------------------

aud[X].ac_len	$0A4	Audio channel X length.

	This register contains a count of the number of words to be sent 
	through the DMA channel for sound generation. You can set the 
	starting addres for these words in the register that is described
	above.

	------------------------------------------------------------------

aud[X].ac_per	$0A6	Audio channel X sounding frequency.
	
	In this register you specify how many bytes per second are used for
	sound generation. Since the sound DMA channel is synchronised with
	the screen DMA channel, only two bytes per raster row can be made
	audible. Theoretically, it is possible to make two (bytes) * 
	262.5 (raster rows) * 59.94 (screen displayed) = 31468.5 bytes
	per second audible in PAL systems.

	Because the DMA controller is responsible for other tasks besides
	sound generation, it is only possible to sample 28867 bytes per
	second.

	This means that you could send one byte through the sound channel
	in 1/28867 seconds = 34.642 microseconds. This provides the value
	for this register: ac_per = 34.642 microseconds/Num_Microseconds 
	for one scan.

				PAGE 559

-----------------------------------------------------------------------------

	The hardware determines the limits for the scan per timing cycle.
	Since the timing cycle is 280 nanoseconds or 0.28 microseconds, 
	a value of 123 (34.643 microseconds / 280 nanoseconds) is the 
	smallest possible value for this register. If you select a smaller
	value the DMA channel can no longer function properly.  
	------------------------------------------------------------------

aud[X].ac_vol	$0A8	Audio channel X volume.

	Use this register to set your audio volume level for channel X.
	Only the lower five bits are essential to volume.

	The maximium volume level is 64; setting this register to zero
	turns off your sound.

	------------------------------------------------------------------
	
aud[X].ac_dat	$0AA	Audio channel X data.

	This register is the audio DMA data buffer. If contains two bytes
	in two compliments which are sequentially sent through the sound
	hardware.

	The DMA controller automatically writes the values read from 	
	ac_ptr into these registers. To create sound without using the DMA
	channels, you can write directly to these register by using the 
	68000. When doing this, make sure that you dont enable DMA access
	at the same time because this will disturb the interrupt timing.

	------------------------------------------------------------------

bltXpt		$050	Blitter pointer.

	This register pair pointer contains an 18 bit pointer to the DMA
	data that the blitter will act upon. X represents a,b,c and d
	which are the three sources (a,b,c) and the target (d) for the 
	blitter operation (Blits).

	The data for a blit operation is read from bltapt, bltbpt and
	bltcpt; it is operation on and stored at bltdpt.

	When the blitter operation is complete, the pointer contains the
	last data address (plus increment and modulo) for the data written
	and read. To include the target (d) in the blit operation, one
	of the sources (a,b or c) must contain the same address as the 
	target (d).

	The blitter is not only responsible for blitting, but also for 
	drawing lines. Because this additional task is integrated into this
	processor, it is easy to understand why the amiga can draw lines
	so quickly.

				PAGE 560

-----------------------------------------------------------------------------

	How the bltapt, bltbpt, bltcpt and bltdpt registers affect line
	drawing is not relevant here because the Draw() instruction was
	designed for this function.

	------------------------------------------------------------------


bltXmod		$064	Blitter Modulo X

	This register contains the modulo for the Blitter sources (a,b and
	c) and the Blitter target (d). Since it is possible to use 
	different sized bitmaps, which we can blit between, we must know
	the size of each  bitmap that the Blitter will work with. A blit
	operation is not limited only to one bitmap.

	You must provide the width for each bitmap, that is used for the 
	blit operation as the modulo parameter. This is how a rectangle to
	be blitted is transferred from one bitmap to the other.

	Remember that the blitter can only operate on data by bitplane.
	This means that when you control the blitter yourself and blit
	a rectangle from one bitmap to another, you must provide, with
	bltxpt, the rectangle position for each bitplane. The modulo is
	read last and added to the written word to locate the start of the
	next row.

	Commodore has provided some bery powerful instructions that 
	fully use the blitter (BltBitMap(), BltTemplate(), ScrollRaster())

	As with drawing lines, the modulo registers also have a specific
	purpose. However, as we said earlier, the Draw() function does all
	the work for you.

	------------------------------------------------------------------

bltafwm		$044 Blitter	First word mask for Source A
bltalwm		$046 Blitter    Last word mask for Source A

	In order to blit a rectangle that starts in the middle of a word 
	instead of at a word address, the first and last word of a row to
	be blitted (the source A) is ANDed with a specific value. The
	remaining bits are changed, reworked and written into the row.

	-----------------------------------------------------------------

bltXdat		$074	Blitter X data register.

	Similar to sound generation, the individual words from source a,b 
	and c are read here before they are logically merged. This action
	is performed by the DMA channel. After the blit of these three 
	words, the resulting word is written, by the DMA channel to the 
	bltdat and then to the target. The entire blit operation is 
	reduced to operating on three words.

				PAGE 561

-----------------------------------------------------------------------------

bltcon0		$040	Blitter control register 0
bltcon1		$042	Blitter control register 1

These two registers are used to control the Blitter operation (blits).
There are two modes, Area and Line, that are selected through bit 0 
of BLTCON1:


The Area Mode	bltcon0

    Bits 15-12	ASH3-0:
	If you have ever moved a bob by pixels, you probably wondered 
	how this was possible since the blitter can only access word
	addresses.

	By using the bits ASH3-0, you can select how many pixels the data 
	from source A is rotated before being written to the target.

    Bits 11-8 	USEx:
	These bits determine which source the blitter can access. If you
	have only two sources, it would be a waste of time to access all 
	three possible sources. Besides, there wouldnt be any data in 
	source C.

	With the USEx bits you can select your source; X stands for the 
	a,b,c and d. Make sure you activate the target, otherwise the 
	data will have no place to go.

    Bits 7-0 LF7-0:
	These bits determine the type of logic operation that will be 
	performed, by the blitter, on your source data. The bit patterns
	written here are also called minterms, which you learned about in 
	connection with the Blitter instructions. Only two sources are
	considered, b and c.

	However, there are three sources you can use. What happens with 
	each source is determined by the individual bits LF7-0.
	
				PAGE 562

-----------------------------------------------------------------------------

	Bits:LF       7     6      5      4      3      2      1      0
                             _     _      __    _      _ _    __     ___ 
        Minterm:     ABC   ABC    ABC    ABC    ABC    ABC    ABC    ABC

        ABC:D = A and B and C
          _
        ABC:D = A and B and !C
         _
        ABC:D = A and !B and C
         __
        ABC:D = A and !B and !C
        _
        ABC:D = !A and B and C
	 .
	 .
	 .

The area mode  bltcon1 has the following bit pattern in area mode:

    Bits 15-12 	BSH3-0:
	These bits have the same meaning as ASH3-0 with bltcon0, except 
	that source B is shifted.

    Bits 11-5: Commodore has not assigned a function to these bits yet.  
    Bits 4, 3	EFE/IFE:
	Earlier we mentioned that the blitter is capable of performing our
	fills. Thses two bits determine the fill mode for an area already
	set for the Blitter. When bit EFE is set (Exclusive Fill Enable),
	the area outline to the left of the filled area is erased after 
	the fill operation. If EFE is unset and IFE is set (Inclusive
	Fill Enable), the area is filled normally. To achieve a clean 
	fill, the area border must fulfill specific requirements: Only
	one single pixel may be set on each horizontal line (see SING).
	
    Bit 2 FCI:
	This bit is the starting value for the fill "flip-flop". Just
	like an electronic flip flop, the Blitter also switches status 
	back and forth while filling. Whenever a specific external event
	occurs, the Blitter switches and then keeps this status until a 
	new event of the same type happens.

	An event for the Blitter looks like this: the Blitter finds a set
	bit in a bitplane row and the status of the Fill Flip Flop is
	toggled. All the following bits that are clear are written with the
	value of FCI. You can also determine whether an area is filled
	inside or outside.
	
    Bit 1 DESC:
	This bit determines the direction in which the Blitter works in the 
	specified data area (source a,b,c and d). When DESC is set, the
	direction is downward from the provided address. When DESC is clear,
	the Blitter works upwards. This bit is very important when target
	and source overlap.

				PAGE 563

-----------------------------------------------------------------------------

    Bit 0 LINE:
	(=0) When this bit is clear the Blitter operates in Area mode.

	When drawing lines all of these bits have new meanings:

BLTCON0
--------

    Bits 15-12 START3-0:
	These bits set the code for the horizontal position of the first
	pixel of the line.
	
	The exact format used by Commodore for START3-0 was not available 
	when this book was written. For this reason we have provided only 
	limited information on drawing lines with the blitter.

    Bits 11, 10, 9, 8 %1011:
	These bits must be initialised to a value of %1011 (only Commodore
	knows why).

   Bits 7-0 LF7-0:
	When drawing patterned lines, the Blitter sources are used in some
	capacity. Again, only Commodore has the complete information.  


BLTCON1
-------
    Bits 15-12 TEXTURE3-0:
	A value (0-15) in these four bits sets the starting bit position
	for the pattern in a line.

    Bits 11-7 %00000
        All these bits be must be cleared.

    Bit 6 SIGN:
	This bit must contain the sign for the rise of the line.
	
    Bit 5 %0
	This bit is reserved for a new mode and should be kept clear for
	upward compatibility with other programs and machines like the
	2000.
	
    Bits 4-2 SUD, SUL, AUL:
	These bits are used for super fast line drawing. This super fast
	method is based on the symmetric characters of a line that the
	blitter uses. You control the drawing of a line with these three
	bits named "sometimes up or down", "sometimes up or left" and 
	"always up or left". Whether they can be set by you or only by the
	blitter is somethinf we were unable to find out.

				PAGE 564

-----------------------------------------------------------------------------

    Bit 1  SING:
	If this bit is set, each line is displayed by only one pixel in 
	each bitplane row. This is important for the blitter when filling
	areas.

    Bit 0  LINE:
	(=1) This bit determines the blitter mode. When set the blitter 
	operates in line mode.

	----------------------------------------------------------------



bltsize	$058	Blitter: start and size (width, height)

This register contains the height and width of the Blitter's operating area. 
All operations occur in this defined window. The starting address is set in 
bltXpt and the operations are determined by bltcon0/1 and other registers.

When you access these registers (through the Copper or 68000), Whether 
reading or writing, the Blitter immediately executes the blit.

This is why you should first initialise all other registers (BLTAF/:WM,
BLTxDAT,BLTCON0/1, BLTxMOD etc..) and then perform the write. This start 
effect also applies to drawing lines.


Bits 15-6 	H9 - H0
	These ten bits determine the number of rows for the Blitter's
	operating area and can contain a value between 0 and 1024.

Bits 5-0 	W5-WO:
	These bits determine the width, in words (64 * 16 bits = 1024), of 
	the Blitter's operation area. Theoretically the Blitter can operate 
	with a memory area of 1024 x 1024 pixels (a superbitmap).

	This register also has a different effect when it used for line 
	drawing. BLTSIZE controls the Iine length and accessing this 
	register tells the Blitter to start drawing the line. The H9-H0 
	bits control the line length (up to 1024 pixels) and bits W5-W0 
	must be initialised to %00010.

	Since we could not provide complete information about the Blitter 
	registers, we recommend that you utilise the libraries and BASIC 
	instructions.

		--------------------------------------------

bplpt[6]	$0E0	Bit-plane X pointer

	This register pair (see ac_ptr) contains the 18 bit pointer to the 
	starting address for bit-plane x (x=1,2,3,4,5,6) DMA data. This 
	register, which must be initialised by the 68000 or the Copper 
	after every raster return, is responsible for making your graphics 
	visible.

				PAGE 565

-----------------------------------------------------------------------------

	Since there are a few more than the 480 visible rows on your screen (
	with interlace and overscan), a scrolling effect can be achieved 
	through this register. However, instead of manipulating the hardware 
	yourself, you can use the RxOffset and RyOffset variables in the 
	RasInfo structure and the library instruction scrollVPort() to 
	scroll an entire bit-map in a ViewPort.

		--------------------------------------------

bpldat[6]	$110	Bit-plane X data

	As with DMA operations, registers are also required for temporary 
	data storage. After the DMA controller stores data in these six 
	registers, they are used by the video hardware (Videoshifter).

		--------------------------------------------

bpl1mod		$108	Bit-plane modulo (odd planes)
bpl2mod		$10A	Bit-plane modulo (even planes)

	These registers contain the modulo (the width) for the even (2,4,6) 
	and odd (1,3,5) bit-planes (seeDBBLPF and bplXmod). The modulos are 
	essential for a correct display.

		--------------------------------------------

bplcon0		$100	Bit-plane control register
bplconl		$102	Bit-plane control register
bplcon2		$1-4	Bit-plane control register

	You can control the video shifter like the Blitter. Use these three 
	registers, which are the core of the entire graphic display.


bplcon0
-------

Bit 15 HIRES: 
	If this bit is set, the display is in high resolution mode (640 *
 	... pixels). In this mode (4 bit-planes), you can only use 16 colors, 
	which are determined by the lower 15 color registers (see COLORxx).

Bits 14-12 BPU2-0: 
	These bits determine how many bit-planes you are using (0-6). Six
	bit-planes are only required for dual playfields (DBLPF), 
	hold-and-modify (HAM), and extra halfbrite modes. The number of 
	bit-planes determines the number of possible colors: colors = 2BPU. 
	So, it is possible to use five bit-planes and 32 colors without 
	hold-and-modify. Setting all of these bits to zero displays only 
	the background color (COLOR00).

Bit 11 HAM:
	This bit switches on the hold-and-modify mode.

Bit 10 DBLPF:	
	This bit switches on the dual playficld mode.	
	
				PAGE 566

-----------------------------------------------------------------------------
	
Bit 9 COLOR:
	Setting this bit sets your display output for a composite monitor. 
	This means that the normal three color (RGB) is no longer used, and 
	a single output for composite is activated.

	All older model monitors are of the composite type. Since the colors 
	must be separated from the single input signal, the picture on a 
	composite isn't as good as one that uses RGB.

Bit 8 GENLOCK:
	With a genlock interface it is possible to display, instead of the 
	background color, the output from a video recorder, videocamera or 
	laser disk. This enables you to overlay the background video with 
	your own title and graphics. In order to use such an interface, your 
	software has to set this bit.

Bit 7 EXTRA_HALFBRITE:
	This bit switches on the halfbrite mode.

Bits 6-4: Not used

Bit 3 LPEN:
	In order to use a light pen, this bit must be set. This tells the 
	Amiga to test for the light pen position through the control port. 
	Light pens can only be used with control port one (see VPOSR).

Bit 2 LACE:
	This bit switches on the interlaced mode, which doubles the vertical 
	display resolution from 200 rows to 400 rows. With interlace the 
	screen is actually displayed twice. The first display is the even 
	numbered rows and the second display is the odd numbered rows of 
	the bit-map.

Bit 1 ERSY:
	This bit enables external synchronization of the electronic scanning 
	beam.

Bit 0:	Not used

bplcon1
-------

Bits 15-8: Not used

Bits 7-4 PF2H3-0,
Bits 3-0 PFlH3-0:
	These bits set the number of pixels that a playfield is horizontally 
	scrolled when displayed. You can use any value between zero and 15 
	pixels.

				PAGE 567

-----------------------------------------------------------------------------

	By using bplpt[x], you can achieve word type scrolling. These bits 
	are also available for finer scrolling.

	However, you can also use ScrollVPort() and RasInfo.RxOffset. So this 
	register is not too important.

bplcon2
-------

Bits 15-7:	Not used

Bit 6 PFsPRI:
	Setting this bit gives playfield 2 complete video priority over 
	playfield 1. Clearing this bit puts playfield 1 in the foreground 
	(PFBA).

Bit 503 PF2P2-0,
Bits 2-0 PF1P2-0:
	The bit combination in these bits set the video priorities between 
	playfield 1 and the sprites and between playfield 2 and the sprites:

	Value 		Priority

	000		PF1/2 > SP0/1 > SP2/3 > SP4/5 > SP6/7
	001		SP0/1 > PF1/2 > SP2/3 > SP4/5 > SP6/7
	010		SP0/1 > SP2/3 > PF1/2 > SP4/5 > SP6/7
	011		SP0/1 > SP2/3 > SP4/5 > PF1/2 > SP6/7
	100		SP0/1 > SP2/3 > SP4/5 > SP6/7 > PF1/2

	('>' means has Priority over)

	You don't have to set the video priority for sprites because the 
	hardware automatically knows that the lower numbered sprites have 
	priority over the higher numbered sprites. The mouse pointer has 
	sprite number zero with priority over all the other sprites.

	When different ViewPorts are displayed, These registers are usually 
	changed many times for each display. If there is only one ViewPort, 
	the Copper changes these every sixtieth of a second.

		--------------------------------------------

clxcon	$098	Collision control

	This register determines what type of collisions (between 
	bit-planes, sprites and bit-planes, or sprites and sprites) are 
	looked for by your Amiga. Through the value stored in clxdat, you 
	can discover which objects have collided. The individual bits for 
	clxcon have the following functions:

Bits 15-12 ENSP7, 5, 3, 1:
	Setting one of these bits allows you to check the odd numbered 
	sprites	(7, 5, 3, 1) for collision control. The even numbered 
	sprits (0, 2, 4, 6) are always checked for collisions, but the odd 
	ones aren't

				PAGE 568

-----------------------------------------------------------------------------

However, unless you are using attached sprites that are at the same position, 
you cannot determine through CLxDAT whether an odd or even numbered sprite 
has collided with an object.

Bits 11-6 ENBPx:
	Use these bits to set which bit-planes (x = 6-1) are tested for 
	collisions. Clearing these bits always indicates one bit-plane 
	collision.

Bits 5-0 MVBP6-1:
	These bits determine whether bit-plane collisions with sprites are 
	registered by set or cleared bits. For example, only one bit-plane 
	collision is registered when a pixel is set in bit-plane 1 and 
	not registered for bit-plane 2 at the same position, etc. This 
	makes it possible to determine if a sprite has collided with a 
	specific colored pixel.

		--------------------------------------------

clxdat	$00E	Collision data register

This register helps you to determine which collisions have occurred.

	Bit 15	unused (usually = 1)
	Bit 14	Sprite 4 (or 5) with sprite 6 (or 7)
	Bit 13	Sprite 2 (or 3) with sprite 6 (or 7)
	Bit 12	Sprite 2 (or 3) with sprite 4 (or 5)
	Bit 11	Sprite 0 (or 1) with sprite 6 (or 7)
	Bit 10	Sprite 0 (or 5) with sprite 4 (or 5)
	Bit  9	Sprite 0 (or 1) with sprite 2 (or 3)
	Bit  8	Playfield 2 with sprite 6 (or 7)
	Bit  7	Playfield 2 with sprite 4 (or 5)
	Bit  6	Playfield 2 with sprite 2 (or 3)
	Bit  5	Playfield 2 with sprite 0 (or 1)
	Bit  4	Playfield 1 with sprite 6 (or 7)
	Bit  3	Playfield 1 with sprite 4 (or 5)
	Bit  2	Playfield 1 with sprite 2 (or 3)
	Bit  1	Playfield 1 with sprite 0 (or 1)
	Bit  0	Playfield 1 with playfield 2

	PIayfield 1 is the odd bit-planes (1, 3, 5) and playfield 2 the 
	even (2, 4, 6).

	This register provides many possibilities for determining sprite 
	collisions. Since bit-plane collisions provide less information, 
	specific determinations are impossible.

	Remember that sprite collisions are first registered when two pixels 
	overlap instead of when the edges collide.

				PAGE 569

-----------------------------------------------------------------------------

Also, when you read this register, it is immediately cleared and not written 
to again until the next raster scan (vertical blank).

		--------------------------------------------

color[32] 	$180	Color register

There are 32 color registers ($180 - $1BE) that contain a 12 bit color code 
for every color that exist in the bit-planes..

The color register that determines the color information for a specific pixel 
is calculated by ORing - the value for all bit-planes for that pixel
position.

The color code is composed of 12 bits which makes 4096 different colors 
possible. You can use a maximum of 32 of the 4096 colors for one screen 
(hold-and-modify is an exception to this rule). Your pixel is then displayed 
in the color calculated for its color register. Here is the bit pattern 
used in all of the color registers:

	Bits 15-12		Unused
	Bits 14-8 Red 3-0	Red component of color
	Bits 7-4 Green 3-0	Green component of color
	Bits 3-0 Blue3-0        Blue component of color

The fourth bit determines the intensity of a color component (red, green, 
blue). It is possible to create almost any color by mixing the three
different colors and their intensities (0 = dark, $0f = light).

		--------------------------------------------

copcon	$02E	Copper control register

This register is a one bit register. Only bit one is used, all the other 
bits are unused.

Some computer users refer to this register as the Copper danger bit. 
Register zero (bltddat) to register 30 (strlong) are exempt from Copper 
manipulation.

Usually, the Copper cannot access registers 31 (bltcon0) to 49 (dsksync). 
Setting the danger bit allows you to use these registers. Any reset clears 
this bit.

		--------------------------------------------

copjump1 $088 (Strobe) Copper Newstart the first list.
copjump2 $08A (Strobe) Copper Newstart the second list.

By accessing these registers, either through the Copper or 68000, causes the 
Copper to execute a Copper list. The starting list address should be in 
cop1lc or cop2lc and the Copper-Program-Counter (PC) is directed to this 
address.

				PAGE 570

-----------------------------------------------------------------------------

The Copper list, whose start address is in cop1lc, is executed with each 
raster scan (vertical blank).

For your own experiment with Copper list it is safer to use the user Copper 
list. The entire display is controlled by the Copper and direct access can 
cause serious problems unless you take control of the entire display.

		--------------------------------------------

cop1lc	$080/$082 Address of first Copper list.
cop2lc	$080/$084 Address of second Copper list.

When you access registers copjmp1 or copjmp2, they contain the starting 
addresses of Copper lists for execution.

The address of the hardware Copper list is loaded into these registers 
through Loadview().Cop2lc is only used with interlace mode for the second 
screen scan. After the first scan the second Copper list is started by the 
first.

		--------------------------------------------

copins	$08C	Copper instruction register

Like the DMA channcl, the Copper also uses a temporary buffer. Two 16 bit 
instruction words are stored in this register and executed sequentially.

The  first instruction word consists of one of the three possible Copper 
instructions, the affccted hardware register and the position of the 
electronic beam that will be waited for.

However, the three possible instructions, CMOVE(), CWAIT() and CEND() aren't 
the only instructions you can use. The instructions Move, Wait and Skip are 
also available.

The reason for this is that the CEND() instruction is actually a 
subinstruction of CWAIT() and the Skip instruction wasn't considered useful 
enough to be includcd in C.

MOVE and WIAT have the same meaning as CMOVE () and CWAIT ().

The skip instruction actually skips the following Copper instructions when 
the electronic beam has reachcd the selected position.

A complete Copper instruction consists of two 16 bit words that are 
loaded and executed sequentially in these registers.

Instruction: MOVE

1. Instruction Word

				PAGE 571

-----------------------------------------------------------------------------

Bits 15-9 Unused

Bits 8-1 DA8-1:
	DAx (Destination Address), which is used by the Move instruction, 
	selects the register the value of the second instruction will be 
	written. DA is specified as an offset from $DFF000 for the selected 
	hardware register.

Bit 0 0: This bit is used to identify a Copper move instruction. Move must 
	always be zero (The first bit of the second instruction word isn't 
	required for decoding this instruction).

2. Instruction Word

This word contains the 16 bit value that will be written to the register 
seleclted by DA.

WAIT
----

1. Instruction Word

Bits 15-9 VP7-VP0:
	VP (Vertical Position) contains the vertical (Y) position of the 
	electronic beam that will be waited for.

	There are 262 different vertical beam positions that can be waited 
	for. Since VP has a data width of only eight bits, a small trick must 
	be used in order to access positions 256 through 262.

	Usually, first you wait for the vertical position 255. Then you use a 
	second wait instruction for a position between zero and six.

Bits 8-1 HP8-HP1:
	HP (horizontal position) contains the horizontal (X) position for the 
	electronic beam that will be waited for. It can contain a position 
	value betweenn zero and 226. Since the available data width is only 
	seven bits, the Copper can access only 113 positions. This limits 
	you to a pixel resolution of four with low-res (HIRES = 0) or eight 
	with hi-res (HIRES = 1).

	It is possible for you to wait for every fourth pixel position. 
	However, this doesn't mean that you can change a register for every 
	four pixels. When you execute two moves, one after the other, there 
	is a gap of eight low-res pixels (with hi-res this value doubles).

Bit 0 1:
	This bit and bit zero of the second instruction word are used to 
	identify the Copper instructions wait and Skip. When bit zero of the 
	first

				PAGE 572

-----------------------------------------------------------------------------

	word is clear, the Copper knows that it is working with a MOVE 
	instruction so it doesn't test the second instruction word.

	When bit zero of the first word is set the Copper knows that it must 
	either wait or skip. Which action is performed is set by you in the 
	instruction word.

	2. Instruction Word

Bit 15 BFD:
	Setting this bit puts the wait instruction on hold until the Blitter 
	says "OK" (Blitter Finished Disable).

Bits 14-8 VE6-VEO:
	VE (Vertical Comparison Enable) and HP (Horizontal Comparison Enable) 
	determine which bits are used for comparing the electronic beam 
	position.

Bits 7-1 HE-8-HE-2:
	This bit has the same meaning for horizontal position as VE does for 
	vertical positioning.

Bit 0 %0: 
	The Copper recognises the WIAT instruction at this location.

	SKIP

	Except for the set or unset status of bit zero of the second 
	instruction word, the bit pattern of the instruction words for SKIP 
	and WAIT are very similar. The meaning of all the other bits is the 
	same.


		--------------------------------------------

diwstrt	$08E	Display window start (top, left position)
diwstop	$090	Display window stop (lower, right position)

	Use these registers to set the actual display (ViewPort) size for 
	your screen. The values in these registers determine the upper left 
	corner and the lower right corner of the screen. Besides the 
	background color (in color[0]), nothing can be displayed outside 
	this screen.

	These positions are specified in normal (not interlaced) raster row 
	and low resolution pixel values. You don't have to change these 
	values to use interlace or hi-res modes.

	The bit pattern of these registers is as follows:

diwstrt

	Bit		Function
	---------	------------------------------------------------
	15-8		VSTART	vertical start position
	7-0		HSTART	horizontal start position

				PAGE 573

-----------------------------------------------------------------------------

	The starting position of your display is set in these two registers. 
	However, you cannot set the starting position of a ViewPort here.

	Because of the eight bit data width of these registers, you can only 
	use horizontal and vertical starting and ending positions between 
	zero and 256 raster rows.

diwstop

	Bit		Function
	15-8		VSTOP	vertical start position
	7-0		HSTOP	horizontal start position

	Diwstop also has the same eight bit pattern. In order to display a 
	window wider than 256 pixels, a value of $100 must be added to the 
	X end coordinate to maintain the actual end position.

	Bit VSTOP7 is very important for calculating the actual vertical end 
	coordinate. The nonexistent VSTOP8 bit is actually the compliment 
	of VSTOP7. If VSTOP7 is cleared, VSTOP8 is set. When VSTOP7 is zero, 
	you simply add 256 to calculate the actual vertical end position.

	lf VSTOP7 is set you can disregard VSTOP8 since it is zero and not 
	active in the calculation.

	When writing to these registers, be aware of "Vertical Blank". The 
	top visible raster is not raster zero just as the first visible 
	column is not the first column raster wise.

	The electronic beam needs some time to recover after reaching the 
	bottom screen border. This is similar to when the beam finishes 
	displaying a raster row.

	Normal values for diwstrt and diwstop are:

		diwstrt=$2c81
		diwstop=$f4c1

	This provides a screen window size of:

		HSTOP+$100-HSTART = $c1-t$100-$81 = $140 = 320 Pixels 
		VSTOP+(VSTOP8 * $100)-VSTART = $F4( = %11110100)+(0*
		$100) - $2c = 200 Normal-Raster rows

	Also remember not to use a vertical starting value smaller than $20 	
	Because, while creating the screen, the vertical blank needs an area 
	for the beam return. Otherwise you wouldn't see anything on the 
	screen. Because the electronic beam wasn't given enough recovery 
	time.

				PAGE 574

-----------------------------------------------------------------------------

ddfstrt	$092	Screen data fetch start
ddfstop	$094	Screen data fetch stop

	These two registers determine when to get the data from memory and 
	display it.

	One timing cycle is used to display two pixels. To determine when to 
	start and stop displaying data, use the values from the diwstrt and 
	diwstop registers. Eventually you will add a small offset to these 
	values and then the desired values for ddfstrt and ddfstop will be 
	available.

	The offset is different for lo-res and hi-res modes. For lo-res the 
	offset is 8.5, and for hiRES is 4.5.

	Start position values are:

		ddfstrt=($81/2-8.5)=$38
		(Hi-res: ddfstrt = ($81/2 - 4.5) = $3C)

	You calculate the value for ddfstop like this:

		ddfstop = ddfstrt + (16/2 *(Number of words per line -1))
			(low-resolution)
		ddfstop = ddfstrt + (16/4 *(Number of words per line -2))
			(high-resolution)

	Again the number of displayed pixels (1 word = 16 pixels) is halved 
	and quartered. The quartered value for hi-res is natural because 
	hi-res displays twice as many pixels in the same amount of time.

	You cannot select these values because they are limited from the 
	hardware side. DDFSTRT cannot be smaller than $18 and DDFSTOP cannot 
	be larger than $D8. These values permit a display of 376 pixels with 
	lo-res (752 with hi-res). By using a DDFSTRT value smaller than $38, 
	you can prevent the display of several sprites.


		--------------------------------------------

dmacon	$096	DMA control register (write)
dmaconr	$002	DMA control register (read)

	These registers are used by the DMA controller to manage the 
	information fed to it by the various processors.

	With dmacon, set which DMA channel is open.

	This is the bit pattern which is the same for both registers:

Bit 15 SET/CLR:
	(see ADKCON)

				PAGE 575

-----------------------------------------------------------------------------

Bit 14	BUSY:
	This bit shows the blitter status. When the blitter is working this
	bit is set.

Bit 13  BZERO:
	This bit is set when all the result bits of a blit (screen area
	copy etc...) were zero.

Bits 12,11:  Unused.

Bit 10	BLTPR1:
	This bit determines the priority between the Blitter and the 68000.
	How the 14mhz clock frequency is divided between the two processors
	is set here.

Bit 9   DMAEN:
	When this bit is set, it is possible to activate all the DMA 
	channels. If this bit is clear the value of all the following
	bits have no effect on the status of the DMA channels that they
	activate. So, DMAEN is the controller of DMA activity.

Bit 8   BPLEN:
	When this bit and DMAEN are set, the DMA channel for screen data
	transfer from the bitplanes is activated.

Bit 7   COPEN:
	This bit sets the Copper status. If it is set, the Copper can work
	and if it is clear, the Copper is shut off.

Bit 6   BLTEN:
	What applies to the Copper with COPEM applies here to the Blitter.

Bit 5   SPREN:	
	Setting this bit enables transfer of sprite data through the DMA
	channels.

Bit 4   DSKEN:
	This bit determines the status of the disk DMA channel. Clearing 
	this bit stops all data transfers between computer and floppy.

Bits 3-0 AUD3-0EN:
	These bits determine the status for the sound DMA channels. 
	Clearing these bits prevents any sound activation through the DMA
	channels.

				PAGE 576

-----------------------------------------------------------------------------
	
dskpt	$020	Disk pointer

	This register pair (also an 18 bit pointer) determines the data read 
	storage address for the disk DMA data that will will be written to 
	disk.

		--------------------------------------------

dsklen	$024	Disk data length

	Thiss register contains the word count of the words to be sent or 
	received through the disk DMA channel. One bit of this register 
	determines the data direction (RAM -> disk or disk -> RAM). Another 
	bit determines whether access to the DMA channel is possible.

	Accessing this register executes the data transfer. The register must 
	be written to twice with the same data. When all data has been 
	transferred a "Disk Block Interrupt" (see INTREQ) is sent that stops 
	the data transfer.

	Just setting the DMA register isn't the only requirement for 
	executing a complete disk operation such as loading a program. 
	You must also set a pair of I/O registers for the CIAs. However, we 
	won't discuss these registers Because they belong in a different book, 
	such as "Amiga System Programmers Guide".

Bit 15 DMAEN:
	Setting this bit enables the data transfer through the DMA channel.

Bit 14 WRITE:
	This bit determines the write/read direction. When set, the data is 
	read from RAM through the DAM channel and written to disk. When 
	clear, the data is read from disk.

Bits 13-0 LENGTH:
	These bits contain the number of words that will be read or written.

		--------------------------------------------

dskdat	$026	Disk DMA data (write)
dskdatr	$008	Disk DMA data (read)

	These registers contain the data that is either read or written 
	through the disk DMA channel.

	You should remember that the dskdatr register is protected from 
	Copper access.

		--------------------------------------------

dskbytr	$01A	Disk databyte and status

	This register is a data buffer that is directly linked to The disk 
	microprocessor. From this register, data is sent to the DMA 
	controller

				PAGE 577

-----------------------------------------------------------------------------

	or received from the disk controller. There are also a few status 
	bits in this register.

Bit 15	DSKBYT: 
	When bytes are read from disk, this bit is set as soon as the
	byte has been completely read.

Bit 14  DMAON: 
	This bit, which has the same value as DMAEN in dislen, is 
	ANDED with bit DMAEN from dmacon. When the result is a one, data 
	transfer from the disk device is possible.

Bit 13  DISKWRITE:
	This bit has the same value and meaning as WRITE in dsklen.

Bit 12	WOREQUAL: 
	This bit is set only When the dsksync register byte data will be, 
	synchronizcd with the word data.

Bits 11-8:	Unused

Bits 7-0: These bits contain the data byte.

		--------------------------------------------

dsksync	$07E	Disk synchronisation register

	This register contains the synchronize code for disk operations.

		--------------------------------------------

intreq	$09C	Interrupt request bits (write)
intreqr	$01E	Interrupt request bits (read)
intena	$09A	Interrupt enable bits (write)
intenar	$01C	Interrupt enable bits (read)

	These are the interrupt requests, interrupt enable or mask bits that 
	determine which interrupts (cyclic breaks) are allowed.

	This is where you can decide between request and enabling. 
	Interrupts can only occur When the corresponding enable bits are 
	set.

	All four registers have the same bit pattern. The request and enable 
	registers are included twice, once for writing and again for reading.

	Here is the bit pattern:

Bit 15 SET/CLR:
	(See ADKCON)

Bit 14 INTEN (Master Interrupt enable):
	When this bit is clear all interrupts for the following bits are 
	disabled.

				PAGE 578

-----------------------------------------------------------------------------

Bit 13 EXTER:
	This bit is used to generate an external interrupt through CIAB 
	(level 6).

Bit 12 DSKSYN:
	This interrupt is executed when data is synchronized with the 
	DSKSYNC register (level 5).

Bit 11 RBF (receive buffer full):
	This is where the interrupt for the serial port is tested. It is 
	executed when the serial input buffer is full and can be read by the 
	user level 5).

Bits 10-7 AUD3-0:
	An interrupt is executed when sound data will be processed through 
	the DMA channel. In manual mode this interrupt is executed when the 
	audio data registers are ready to operate on new data (level 4).

Bit 6 BLIT (blitter finished):
	This bit is set When the Blitter has completed its work (level 3).

Bit 5 VERTB:
	An interrupt routine, which resets many pointers and executes other 
	system tasks, is performed for every raster return.

Bit 4 COPPER:
	COPPER indicates that a Copper interrupt will be executed. Just as 
	it can change almost any register, the Copper can change any of 
	these these bits. After the entire screen has been displayed and 
	the electronic beam reached the DIWSTOP position, the Copper 
	interrupt occurs. This enables the 68000 to process special tasks 
	during the raster return.

Bit 3 PORTS:
	PORTS indicates an interrupt that is executed during the low 
	processor cycle INT2 (level 2).

Bit 2 SOFT:
	This bit is reserved for software interrupts.

Bit 1 DSKBLK (Disk block finished):
	DSKBLK indicates that a dats transfer through the disk DMA channel 
	is complete (level 1).

Bit 0 TBE (transmit buffer empty):
	TBE indicates that the UART (Universal Asynchronous 
	Receiver/Transmitter) output buffer can receive data and you can 
	write into this buffer (level 1).

				PAGE 579

-----------------------------------------------------------------------------

	Usually by setting the processor lines INT0, INT1 and INT2 low, there 
	could be seven different interrupts. These would only be system 
	interrups.

	However, the Amiga further specifies these system interrupts within 
	the intterrupt handler, which produces more than seven possible 
	interrupt levels.

		--------------------------------------------

joy0dat $00A	Joystic/mouse 1 (left port)
joy1dat	$00C	Joystic/mouse 2 (right port)

	These two registers provide information for the status of the entry 
	device (joystick, mouse, lightpen, potentiometer, etc.) that is 
	connected to the related control port. The following applies to the 
	specific entry devices:

Mouse or trackball:
	For these devices the register contains a value that is proportional 
	to the actual movement. This movement is split between the 
	horizontal (x direction) and vertical (Y direction) in the 
	register. Bits 15-8 contain the vertical movement and bits 7-0 
	contain the horizontal movement. These register values come from the 
	rotation of the ball, which turns the raster sliders between 
	light sensors.

	Breaking the light sensor contact and then making contact again 
	represents one impulse. The Amiga mouse sends 200 impulses per inch. 
	These two bytes are then counters of the light impulse breaks.

	The counters increase when you move the mouse left or down and 
	decrease when you move the mouse right or up. To determine the 
	movement direction, compare the difference of the current value to 
	the new value. When the difference is negative, the mouse is moving 
	down or right.

	In order to make the mouse position available to Intuition, this 
	register is read and cleared after each vertical blank.

	The left mouse button is read through bit six of the CIAA register 
	$BFE001. The right mouse button is read from the pot0dat register.

The Joystick:
	Testing for joystick positions is easier than testing mouse 
	movements. When bits one or nine for joyO/1dat are set, the 
	joystick has been moved left or right. To check for up and down 
	movement, you must XOR bit nine and eight with bits one and zero. 
	The fire button for a joystick in the left port is tested the same 
	way as the left mouse button. The fire button for the right joystick 
	is read from bit five of register $BFE001.

				PAGE 580

-----------------------------------------------------------------------------

	The typical programmer shouldn't try direct reading of the joystick 
	and mouse because the system software handles this for you. However, 
	when the system does not satisfy your control requirement, you could 
	experiment with the information presented here.

		--------------------------------------------

joytest	$036	Write all mouse counters

	The values written to this register are transferred to both 
	joy0dat and joy1dat registers. This allows you to initialise both of 
	them at the same time.

pot0dat	$012	Pot counter left (vert, horiz).
pot1dat	$014	Pot counter right (vert, horiz).

	Like most computers, paddles can also be used with the Amiga. 
	Those are simply potentiometers that are read every sixtieth of a 
	second for their current position.

	When you set the starbit in potgo, electricity is sent through the 
	resistor via a capacitor. The capacitor loads for a short time (about 
	eight raster rows) and then unloads. Then the actual Load of the 
	capacitor is compared to a standard value.

	If the current load is higher than the standard, a previously cleared 
	counter is incremented. When the load is smaller, the compare 
	operation is cancelled and the proportional resistance value is 
	stored in this register. You can connect two of these paddles to 
	each control port which is allowed for proportional joysticks. 
	Test the paddle fire buttons as usual through the left and right 
	joystick positions. Here is the bit pattern for these registers:

Bits 15-8 Y7-YO:
	Potentiometer position of pot at pin 9

Bits 7-0 X7-XO:
	Potentiometer position of pot at pin 5

	The electrical resistance, which must be al least 470K Ohms, plus 
	or minus ten percent is sent through pin seven (+5V, 125mA).

		--------------------------------------------

potinp	$034	Pot port data write and start
potgo	$016	Pot port data read

	The control ports also function as 4 bit bidirectional I/O ports. 
	These registers are used to control them:

Bit 15 OUTRY (right Port, Pin9)
Bit 14 DATRY

				PAGE 581

-----------------------------------------------------------------------------

Bit 13 RX    	(right Port, Pin 5)
Bit 12 DATRX
Bit 11 OUTLR	(left Port, Pin 9)
Bit 10 DATLR
Bit 9 OUTLX	(left Port, Pin 5)
Bit 8 DATLX
      The OUTxx bits set the line status. When these bits are set, 
      data DATxx is output. If these bits are cleared, data DATxx is read.

Bits 7-0 0: Reserved

Bit 0 START:
	When this bit is set (potgo), the capacitors are loaded and the 
	counters start counting.

		--------------------------------------------

refptr	$028	Write refresh pointer

	This pointer is used as a RAM refresh pointer. Instead of constantly 
	receiving electricity, the memory bits are loaded every 280 
	nanoseconds (= one memory cycle). Therefore, their old value is 
	constantly kept fresh. Because of this technique, it is possible to 
	use five volt power for most ICs.

	These registers should never be accessed by the 68000 or Copper 
	because this can confuse the intemal timing, which can cause loss of 
	data.

		--------------------------------------------

serdat	$030	Serial port: data and stop bits (write)

	The data that is writtcn to this register is further written to a 
	shifter, which transfers a byte, bit by bit, through the serial bus. 
	When this buffcr can receive data, it sends a TBE (Transmit Buffer 
	Empty) interrupt (see INTREQ). Depending on the setting of the LONG 
	bit in the serper register, either eight or nine data bits are used.

Bits 15-10: 0

Bit 9: 		Stopbit

Bits 8-0: 	Databits

		--------------------------------------------

serdatr $018	Serial port: dats and status (read)

	This register, which is the opposite of serdat, contains the data 
	bits receivcd from the buffer through the shifter. Various interrupt 
	request bits (INTREQ) are also in this register.

				PAGE 582

-----------------------------------------------------------------------------

Bit 15 OVERRUN:
	This bit is set when there is an input buffer overflow. Clearing RBF 
	in INTREQ clears this bit.

Bit 14 RBF:

Bit 13 TBE:
	Sec INTREQ

Bit 12 TSRE:
	This bit is set when the shifter register is empty.

Bit 11 RXD:
	The RXD processor pin receives data directly from the UART. This bit 
	can be tested directly from the 68000.

Bit 10: 0

Bit 9: 	Stopbit

Bit 8: 	Stopbit or D8

Bits 7-0 D7-D0:

		--------------------------------------------

serper	$032	Scrial port: rate and control

	With this register you set the word data width (8 or 9 bits), which 
	the serial port will send or receive. The data transfer speed is 
	also set here.

Bit 15 LONG:
	Setting this bit makes your data word nine bits wide.

Bits 14-0 RATE:
	Thesc bits specify the speed for sending or receiving one bit. 
	To calculatc the time, use the following formula: 
	   (value of the lower 14 bits + 1) * 2794 microscconds.


		--------------------------------------------

sprpt[8] $120	Sprite x Pointer

	This register pair contains the starting data address for every 
	sprite (x = 0, 1, 2, 3, 4, 5, 6, 7). In order to use sprites, this 
	register must be reset by the Copper or 68000 after every raster 
	return. To display sprites, the DMA channel (dmacon/SPREN) must also 
	be active.

				PAGE 583

-----------------------------------------------------------------------------

spr[8].pos	$140	Sprite X vertical & horizontal start position
spr[8].ctl	$142	Sprite X vertical stop position

	These registers work together to control the size, position and other 
	functions connected wilh hardware sprites. They are usually loaded 
	by the DMA conlrollcr durring the horizontal raster beam return.

	The positions are again specified in raster rows or normal pixels.

pos
---

Bits 15-8 SV7-SV0,
Bits 7-0 SH8-S8H1:
	SV7=SV0 sets the vertical (Y direction) start position of sprite x. 
	SH7=SH0 contains the horizontal (X direction) start position of 
	sprite x. There are only eight bits available for each position 
	coordinate. So spr[x].ctl contains the high value bit SV8 and the 
	SH0 contains the low value bit. This allows position values between 
	zero and 512 in both horizontal and vertical directions. The movement 
	of sprites is only possible in steps of low-res pixels and in normal 
	raster rows.

ctl
---

Bits 15-8 EV7-EV0:
	These bits contain the vertical (Y) end position of sprite x. 
	This clearly reveals that sprites can have any desired height 
	(sprites are always 16 pixels wide). Remember that the highesy bit
	(EV8) is bit one.

Bit 7 ATT: 	
	Setting this bit selects paired sprites (0/1, 2/3, 4/5, 6/7 ) that 
	provide 15 colors per sprite instead of only three. Each sprite in a 
	pair can be movcd independantly. The 15 color bit pattern is 
	visible only When the sprites overlap.

Bits 6-4: Unused

Bit 2 SV8: 
	High value bit for SV7-SV0 in spr[x].pos


Bit 1 EV8: see EV7-EV0

Bit 0 SHO: 
	High value bit for SH7-SH0 in spr[x].Pos


		--------------------------------------------

spr[8].dataa	$144	Sprite X Image data register A
spr[8].datab	$146	Sprite X Image data register B

These registers contain the rows of a sprite that will be displayed. dataa 
contains the first word and datab contains the second word of any sprite. 
When dataa is written into the register, it is compared

				PAGE 584

-----------------------------------------------------------------------------

with the actual raster position in SH8-SH0. When both values are the same, 
the sprite row is displayed.

Changing spr[x].ctl affects this comparison. The beam position is compared 
only after dataa is accessed and eventually the sprite is displayed.

		--------------------------------------------

strequ	$038	Strobe for horiz. synchronisation with VB and EQU
strvbl	$03A	Strobe for horiz. synchronisation with VB
strhor	$03C	Strobe for horiz. synchronisation
strlong	$03E	Strobe for identification of a long horizonal.

	These registers are used internally by the video shifter. 
	Unfortunately, we are unable to provide more detailed information 
	about them. However, the typical programmer really doesn't need 
	these registers.

		--------------------------------------------


vposr	$004	Highest value vertical positions bit (read)
vposw	$004	Highest value vertical positions bit (write)

	To synchronize actions of the 68000 with the electronic scanning 
	beam, these registers are used. So, the 68000 can wait for a 
	specific Y coordinate of the electronic beam and then take whatever 	
	action is required by the Program (see WaitTOF).

	These registers only contain the highest value bit for the vertical 
	position and an interlaced flag.

Bit 15 LOF:
	This bit indicates whether or not interlace is switched on.

Bits 14-0: Unused

Bit 0 V8:	
	This is the highest value bit for the vertical electronic beam 
	position. You can also test for rows higher than 256 
	(313 for PAL and 262 for NTSC).

		------------------------------------------------------------------

vhposr	$006	vertical and horizontal electronic beamposition (read)
vhposw	$02C	Vertical and horizontal electronic beamposition (write)

	These registers are used to read the current beam position or to set 
	(write) a new position, which is sometimes necessary when performing 
	tests. Usually these registers aren't used except for diagnostic 
	purposes.

	The bit pattern is as follows:

				PAGE 585

-----------------------------------------------------------------------------

Bits 15-8  V7-V0:
	These bits contain the lowest bit values for the vertical beam 
	position. This high bit is stored in VPOSR.

Bits 7-0 H8-H1:
	These bits contain the actual horizontal position of the beam. The
	resolution value consists of 1/160 of the screen width.

				PAGE 586

-----------------------------------------------------------------------------

The following register list is in offset address order (please remember the 
offset from $DFF000):

	Nr.		Name		Adress
	-------		--------------	----------------
	000		bltddat		$000
	001		dmaconr		$002
	002		vposr		$004
	003		vhposr		$006
	004		dskdatr		$008
	005		joy0dat		$00a
	006		joy1dat		$00c
	007		clxdat		$00e
	008		adconr		$010
	009		pot0dat		$012
	010		pot1dat		$014
	011		potinp		$016
	012		serdatr		$018
	013		dskbytr		$01a
	014		intenar		$01c
	015		intreqr		$01e
	016		dskpt		$020
	017		dsklen		$024
	018		dskdat		$026
	019		reftpr		$028
	020		vposw		$02a
	021		vhposw		$02c
	022		copcon		$02e
	023		serdat		$030
	024		serper		$032
	025		potgo		$034
	026		joytest		$036
	027		strequ		$038
	028		strvbl		$03a
	029		strhor		$03c
	030		strlong		$03e
	031		bltcon0		$040
	032		bltcon1		$042
	033		bltafwm		$044
	034		bltalwm		$046
	035		bltcpt		$048	
	036		bltbpt		$04c
	037		bltapt		$050
	038		bltdpt		$054
	039		bltsize		$058
			--		$05a
			--		$05c

				PAGE 587

-----------------------------------------------------------------------------

	Nr.		Name		Address
	-------		-------------	----------------------------
			--		$05e
	040		bltcmod		$060
	041		bltbmod		$062
	042		bltamod		$064
	044		bltdmod		$066
			--		$068
			--		$06a
			--		$06c
			--		$06e
	045		bltcdat		$070
	046		bltbdat		$072
	048		bladat		$074
			--		$076
			--		$078
			--		$07a
			--		$07c
	049		dsksync		$07e
	050		cop1lc		$080
	051		cop2lc		$084
	052		copjmpl		$088
	053		copjmp2		$08a
	054		copins		$08c
	055		diwstrt		$08e
	056		diwstop		$090
	057		ddfstrt		$092
	058		ddfstop		$094
	059		dmacon		$096
	060		clxcon		$098
	061		intena		$09a
	062		intreq		$09c
	063		adkcon		$09e

	aud[0]

	064		ac_ptr		$0a0
	065		ac_len		$0a4
	066		ac_per		$0a6
	067		ac_vol		$0a8
	068		ac_dat		$0aa
			--		$0ac
			--		$0ae
	
				PAGE 588

-----------------------------------------------------------------------------

	Nr.		Name		Address
	-------		--------------	---------------------------

	aud[l]

	069		ac_ptr		$0b0
	070		ac_len		$0b4
	071		ac_per		$0b6
	072		ac_vol		$0b8
	073		ac_dat		$0ba
			--		$0bc
			--		$0be

	aud[2]

	074		ac_ptr		$0c0
	075		ac_len		$0c4
	076		ac_per		$0c6
	077		ac_vol		$0c8
	078		ac_dat		$0ca
			--		$0cc
			--		$0ce

	aud[3]

	079		ac_ptr		$0d0
	080		ac_len		$0d4
	081		ac_per		$0d6
	082		ac_vol		$0d8
	083		ac_dat		$Oda
			--		$0dc
			--		$0de
	084		bltpt[0]	$0e0
	085		bltpt[1]	$0e4
	086		bltpt[2]	$0e8
	087		bltpt[3]	$0ec
	088		bltpt[4]	$0f0
	089		bllpt[5]	$0f4
			---		$0f8
			--		$0fa
			--		$0fc
			--		$0fe
	090		bplcon0		$100
	091		bplcon1		$102
	092		bplcon2		$104
			--		$106
	093		bpl1mod		$108

				PAGE 589

-----------------------------------------------------------------------------

	Nr.		Name		Address
	-------		--------------	-------------------------
	
	094		bpl2mod		$10a
			--		$10c
			--		$10e
	095		bpl1dat		$110
	096		bpl2dat		$112
	097		bpl3dat		$114
	098		bpl4dat		$116
	099		bpl5dat		$118
	100		bpl6dat		$11a
			--		$11c
			--		$11e
	101		sprpt[0]	$120
	102		sprpt[1]	$124
	103		sprpt[2]	$128
	104		sprpt[3]	$12e
	105		sprpt[4]	$130
	106		sprpt[5]	$134
	107		sprpt[6]	$138
	108		sprpt[7]	$13c

	spr[0]

	109		pos		$140
	110		ctl		$142
	111		dataa		$144
	112		datab		$146

	spr[1]

	113		pos		$148
	114		cd		$14a
	IIS		dataa		$14c
	116		datab		$14e

	spr[2]

	117		pos		$150
	118		cd		$152
	119		dataa		$154
	120		datab		$156

				PAGE 590

-----------------------------------------------------------------------------

	Nr.		Name		Address
	-------		--------------	------------------------------

	spr[3]

	121		pos		$158
	122		ctl		$15a
	123		dataa		$l5c
	12A		datab		$15e

	spr[4]

	125		pos		$160
	126		ctl		$162
	127		dataa		$164
	128		datab		$166

	spr[5]

	129		pos		$168
	130		cd		$16a
	131		dataa		$16c
	132		datab		$16e

	spr[6]

	133		pos		$170
	134		ctl		$172
	135		dataa		$174
	136		datab		$176

	spr[7]

	137		pos		$178
	138		cd		$17a
	139		dataa		$17c
	140		datab		$17c
	
	141		color00		$180
	142		color01		$182
	143		color02		$184
	144		color03		$186
	145		color04		$188
	146		color05		$18a
	147		color06		$18c
	148		color07		$18e
	149		color08		$190
	150		color09		$192

				PAGE 591

-----------------------------------------------------------------------------

	Nr.		Name		Address
	-------		--------------	------------------
	
	151		color10		$194
	152		color11		$196
	153		color12		$198
	154		color13		$19a
	155		color14		$19c
	156		color15		$19e
	157		colorl6		$1a0
	158		colorl7		$1a2
	159		colorl8		$1a4
	160		colorl9		$1a6
	161		color20		$1a8
	162		color21		$1aa
	163		color22		$1ac
	164		color23		$1ae
	165		color24		$1b0
	166		color25		$1b2
	167		color26		$1b4
	168		color27		$1b6
	169		color28		$1b8
	170		color29		$1ba
	171		color30		$1be
	172		color31		$1be
	
	xxx		NO-OP		$1fe

				PAGE 592

--------------------------------------------------------------------------

         		    INDEX
			    ------

3-D effects     	         39	   AnimOb.AnY    		482
1024*1024 paint program         293	   AnimOb.HeadComp		481
				           AnimOb.PrevOb                483
AbortDoubleBuffer	        180	   AnimOb.XAccel		482
Absolute  address		  9	   AnimOb.XVel		        482
absolute coordinades		  9	   AnimOb.YAccel		482
access counter                  216	   AnimOb.YVel		        482
action-verbs		         51	   AnimObs	           479, 484
activity menu 1		          5	   AnimORoutine		        483
AddAnimOb		   483, 527	   AREA		                 31
AddBob (&Bob, &RastPort)        527	   Area... functions		356
AddFont (&Textfont)             527	   AreaDraw (&RastPort, x, y)	528
Addressing		          8	   AreaEllipse		        529
AddVSprite (&VSprite, Rastport)	528	   AreaEnd (&RastPort)		529
AddVSpri@		        455	   AREAFILL	    31, 32, 33, 124
AllocMem (NumBytes, Use)	553	   AreaInfo		        124
AllocMem()            157, 203, 319	   AreaInfo structure	        356
AllocRaster (Width, Height)     528	   AreaMove (&RastPort, x, y)	530
AllocRaster()    170, 203, 204, 319	   AreaPtSz			126
Amiga libraries		        316	   ASCII			709
AND				 53	   ASCII codes			216
Angle parameters		 24	   AskFont (&RastPort &TextAttr	530

Animate (&AnimOb,&RastPort)	528	   AskSoftStyle (&RastPort)	530
Animated bit-planes	 	 80	   aspect ratio	   	     20, 23
Animation		     21, 55	   asynchronous	                274

animation		    479, 481	   AvailFonts (&Buffer, BufferSize, 
							Type)           550
Animation Components        479		
Animation Objects	    479		   AvailFonts			228
AnimComp		    481		   AvailFonts structure		393
AnimComp structure	    480
AnimComp.AnimBob	    481		   Backdrop (Layerbackdrop)	197
AnimComp.AnimCRoutine	    481		   backdrop window		 99
AnimComp.NextComp	    480		   Backup-Register		117
AnimComp.PrevComp	    480		   bar graph			 19
AnimComp.timeset	    481		   BASIC interpreter		 93
AnimComp.XTrans		    482		   binary numbers		 35
AnimComp.YTrans		    483		   binary pattern mask		 36
AnimComps	       479, 482		   bit pattern			355
AnimOb		       481, 482		   Bit-map  117,123,166,319,402,417
AnimOb.AnX		    482		   bit-map structure 		321

				PAGE 593

-----------------------------------------------------------------------------

bit-planes 46,80,81,149,319,355		   CloseScreen(&Screen)		551
			402,415		   CloseWindow(&Window)		551
Bitmap			149,344		   CLS statement		 41
Bitmap Offset		    153		   CMOVE		   495, 497
Blitter	 52, 349, 399, 400, 465		   Collision mask		 76
Blitter objects		    465		   collision			440
BltBitMap	  278, 400, 530		   collision control	   456, 466
BltBitMapRastPort 	    531		   collision detection		496
BltClear  (&Memory, NumBytes, Flags)	   collisions	      456, 458, 484
			    531	           CollMask	      456, 466, 467
BltClear		    399	           COLOR statement		 33
BltTemplate	  407, 412, 532		   color			382
bmap file		     87		   color components		382
Bob.BobComp		    480		   color cycling	    44, 479
Bob.SaveBuffer		    477		   color depth			  4
BOBISCOMP		    480		   color map		        318
bobs 55,85,458,465,466,467,468,		   color pens			339
		  476, 479, 484		   color registers		  4
BOBVSpritee.Depth	    466		   ColorMap		   153, 344
bold print		    215		   ColorMap structure		318
border color		    347	           ColorPattern		        134
borderless window	     99		   colors			 69
BorderLine	       456, 466		   COMPLEMENT	           125, 340
brush effect		      9		   constant			503
byte field		     95	           ConvertFD			 87
				           Copper 	153,180,185,452,495
C language		    315		   Copper list1 53,169,174,181,317,
CEND			    497		    323,384,382,455,477,495,496,542
ChangeSprite	       436, 532		   Copper programming		435
Character spacing           128		   CreateUpFrontLayer	    190,203
Character width		    127		   cursor		        126
CharData		235,412		   CWAIT		    496,497
charLoc			    235
checkmark		 69,105	    	   damage list			195
CHR$(0)			    100		   DBuffPacket		        477

CIRCLE statement  	  24,30		   DECLARE FUNCTION LIBRARY	 90
CIRCLE			     20		   DEFINT			 36
ClearEOL(&RastPort)         533		   Delay (Time)			553
ClearPointer		    109		   DeleteLayer		    190,204
ClearScreen(&RastPort)      533		   Depth			 69
ClipBlit	       402, 533		   DIM instruction		 36
ClipRect	       192, 194		   Disk fonts			221
CLOSE			     50		   diskfont.bmap		 87
Close gadget		     99		   diskfont.libraries		550
CloseFont (&TextFont)       533		   Diskfont.library	        221
CloseLibrary (&BasePointer) 554		   DiskFontBase functions	550
CloseRequest		    199		   DisownBlitter()		534

				PAGE 594

-----------------------------------------------------------------------------

DisplayBeep (&Screen)	    551		   Font Data			216
DMA	                    451		   Font kern			217
DoCollision	    457,464,534		   Font Style Flags		390
dos.bmap		     87		   font				213
doScroll		    205		   font reader		        237
Doulbe Buffering	476,477		   font style 			392
double buffered displays    423		   fonts		219,234,391
double buffering            175	           Fore/background gadget        99
Double Buffering Off        180		   FreeColorMap(&ColorMap)	535
Double Buffering On         179		   FreeColorMap()         	170
DragBar		             99	           FreeCopList(&CopList)	536
Draw()          	332,534		   FreeMem(&Memory,Size)	554
DrawGList                   204		   FreeMem()	            157,204
DrawEllipse		    534	           FreeRaster()       170, 204, 536
DrawGList	        477,535		   FreeSprite(SprNumber)	536
Drawing color		    124		   FreeSprite (Status)		436
Drawing Mode		    125		   FreeVPortCopLists(&ViewPort) 537
drawing			     69		   FreeVPortCopList()   	170
drawing pens	            341		   function plotter	         12
Drawmode		    340	
Dual Playfield mode	    422		   gadget structure	        103
DUALPF flag		    422		   GEL				464
DUALPF mode	       155, 477		   GEL list		   464, 527
dualplayfield		    476		   GELGONE		        464
GelsInfo		    124
Eddi II			     56		   GelsInfo structure		483
ellipsoids                    3		   GelsInfo.lastcolor		452
ERASE			     50		   Genlock Video		155
exec.bmap		     87		   GET 			     46, 71
exec_lib		     87		   GetColorMap (NumberColors)	537
Exit (ReturnValue)	    553		   GetColorMap		   170, 174
EXOR			    340		   GetMsg (&Port)		554
Extra Halfbrite		    155		   GetRGB4		        537
EXTRA_HALFBRITE		    418		   Getsprite	      436, 452, 537
					   GfxBase			316
fd			     67		   GfxBase routines		527
fill			30, 347		   GfxBase structure		324
fill modes		    357		   GimmeZeroZero PArameters	105
fill patterns               354		   GimmeZeroZero windows     99,101
filled rectangles	     17		   graphic cursor		  9
First ClipRect		    192		   graphic elements(GELS)	465
First window		    115		   graphic library		141
FIags			    194		   graphic primitives   122,129,381
flags		        72, 116		   graphic.library	   316, 345
Flood (&RastPort,Mode,x,y)  535		   graphics.bmap		 87
Flood function	            347		   graphics_lib.fd		 87
Font attribute		    215		   Guru Mediation	     93,400

				PAGE 595

-----------------------------------------------------------------------------

Halfbrite	  156, 320, 418		   Inverting graphics		52
HalfBriteOff		    160		   IODRPReg		       259
HalfBriteOn		    160		   IODRPReg structure	       261
HAM		       155, 320
HAM mode	  161, 419, 421		   JAM1			       341
hardcopies	            259		   JAM2			       341
Hardcopy 1		    262	
Hardcopy III		268,271		   Kickstart		       316
Hardcopy II		    265		
Hardcopy V		    274		   LACE flag		       415
hardware registers	    181		   Lattice V3.10 compiler      315
hardware sprites	    435		   Layer		       315
hardware sprites	    451		   Layer data structure	       191
hexadecimal		     35		   Layer backdrop              196
Hi-res			    155   	   LayerInfo		       117
hi-res mode	             15		   Layers		       188
hi-resolution graphics	      1		   layers libraries            190
Hitmask			    457            layers.bmap		        87
hold-and-modify		161,419		   layers_lib			87  
					   Layersimple		       196
I/O Dump RastPort Request   259		   Layersmart		       196
IDCMP FIags		    104		   layersuper		  194, 196
IFF			    279		   LIBRARY CLOSE		88
ILBM files		    291		   LIBRARY statement		88
ILBM graphic		    280		   library		   87, 527
include files		    503	           LINE			  10,19,30     
InitArea		    538		   Line pattern		       126
InitBitMap		    538		   LoadRGB4	     170, 174, 540
InitBitMap()		170,204		   LoadView(&View)         323,541
InitCop()		181,182		   LoadView		   170,174
InitGels		    538		   Lock-Fields		       194
InitMasks(&VSprite)	    539		   Locklayer		       194
InitRastPort (&RastPort)    539		   long field		        95
InitTmpRas	            539		   MakeDoubleBuffer            179
InitView(&View)		    540		   MakeScreen (&Screen)	       552
InitView	       170, 173		   MakeVPort(&View,&ViewPort)  541
InitVPort(&ViewPort)	    540		   MakeVPort		  174, 323
InitVPort	       170, 174	           MakeVPort()		       170
INPUT			     50		   MeMask		       457
Interchange File Format     279		   menu header		       100
Interlaced mode	        155,414		   Message		       251
Intuition		     93		   MESSAGE port	       104,195,260
Intuition.Screen	    476		   message ports	       195
intuition.bmap		     87		   Messages		       195
intuition_lib		     87		   Minterms		   237,401	
IntuitionBase routines	    476	           ModifyIDCMP		       552
INVERSVID	       125, 341

				PAGE 596

-----------------------------------------------------------------------------

Modulo		      216, 412		  Paint-1024 program instructions
								       311
MoirE patterns		    10		  PAL systems			 4
MOUSE function		     2		  palette 41, 42, 43, 80, 318, 382
mouse coordinates      97, 116		  parameters			 4
mouse pointer		   106		  PATTERN		   35, 129

MOVE			   180		  Patterned areas	    34, 35
Move (&RastPort, X, Y)	   541		  PEEK				95
Move()		           141  	  PEEKL				95
MoveSprite		   541		  PEEKW				95
MoveWindow		   109	          pentagram		        32
MrgCop (&View)		   542		  PFBA			       155
MrgCop		       170,174		  pixel				 1
multi-colored patterns 140,355		  PlaneOnOff			82
					  PlanePick		    	81
NewWindow structure	    345		  POINT statement		 7
Next screen		    115		  Pointer to Window	       206
Next ViewPort	        153,168		  POKE				95
NextSeq			    480		  POKEL				95
NTSC video		      4		  POKEW				95
					  Polydraw		       543
					  Preferences		       390
OBJECT statement             74
OBJECT-SHAPE		  56,71		  PRESET		       3,6
OBJECT.AX/Y		     74		  PrevSeq		       480
OBJECT.CLIP		  78,79		  printer.device               259
OBJECT.HIT		  76,79		  proportional font	       217
OBJECT.ON		     74		  PSET		               1,6
OBJECT.PRIORITY		     79		  pseudo menus			15
OBJECT.SHAPE		     74		  PUT		             46,71
OBJECT.START		     74		  PUT-PRESET			53
OBJECT.VX/Y		     74		  PUT-PSET		        53
OBJECT.X/Y		     74
OBJEDIT program		     56		  quix			        11
ON ERROR GOTO		     16
OPEN			     50		  RasInfo		       167
OpenDiskFont (&TextAttr)    551		  RasInfo Block		       154
OpenFont (&TextAttr)	    542		  RasInfo structure	   322,476
OpenFont		    391		  RastPort 100, 117, 122, 148, 192 
								  344, 412
OpenLibrary		    554		
OpenLibrary	            316		  RastPort border 	       101
OpenScreen (&NewScreen)	    552		  RastPort structure   122,123,188 
								       323
OPTION BASE		     38		  ReadPixel (&RastPort, X, Y)  543
OR			     53		  ReadPixel			90
Overlay Flag		     75		  rectangle		   127,349
Overscan		    414		  RectFill		       543
OwnBlitter() 		    542		  refresh mode			99
					  relative address	     9, 30

PAINT			  27,30		  ReMakeDisplay	   157,160,477,552

				PAGE 597

-----------------------------------------------------------------------------

RemFont (&TextFont)	    544		 SetWindowTitles 	   204,205
RemIBob			    544		 Shadow mask 		        75
RemVSprite(&VSprite)	    544		 Simple Refresh (Layersimple)  196
ReplyMsg (&Port)	    555		 SimpleSprite structure	       435
ReplyPort		    278		 SizeWindow		       111
Requester Handling	    100		 sizing gadget		     96,99
requester	            180	         SKIP			       180
resolution		    413		 Smart Refresh (Layersmart)    196
ReThinkDisplay()	    553		 Smart refresh			99
RINGTRIGGER		    481		 Software Failure	       400
RingXTrans		    483		 SortGList (&RastPort)	       548
RingYTrans		    483		 SortGList		       455
ROM routines		    316		 SprColor		    85,454
ROM versions		    316		 Sprite collisions	       440
					 sprite				55
SADD			     88		 sprite image		       104
SaveBack flag		     72		 SPRITE ATTACHED	       439
SaveBob			     75		 SpriteData structure	       439
SAveBuffer		    477		 Sprites   155,435,438,439,495,496
Scaling			     16		 STEP				 9
Screen dimensions	    116		 structAnimComp		       505
Screen Structure	115,120		 struct AnimOb		       506
screen			     68		 struct AreaInfo	       508
screen colors		    117		 struct AvailFonts	       508
screen gadgets		    117		 struct AvailFontsHeader       508
screen title		    105		 struct BitMap		       508
Screen/Intuition	    114		 struct Bob		       509
ScreenByte		    118		 struct ColorMap	       511
Screenhere		    118		 struct Custom		       511
Scrolling		    195		 structDBuffPacket	       511
ScrollLayer()		203,205		 struct GelsInfo	       512
ScrollRaster		    544		 struct GfxBase		       511
Screen			    118		 struct IntuiMessage	       513
ScrollVPort (&ViewPort)	    545		 struct IntuitionBase	       513
SetAPen (&RastPort 
	Colorregister) 	    545		 struct NewScreen	       515
SetBPen(&RastPort, 
	Colorregiter        545		 struct NewWindow	       513
SetCollision 		    546		 struct RasInfo		       519
SetColllision 		    484		 struct RastPort	       516
SetDrMd(&RastPort Mode)	    546		 struct Screen		       519
SetDrMd			125,141		 struct SimpleSprite	       520
SetFont (&RastPort, &Font)  546		 struct TextAttr	       520
SetPointer		    106		 struct TextFont	       521
SetRast (&RastPort, 
	Colorregister)	    547		 struct View		       521
SetRast			    204		 struct ViewPort	       522
SetRG4CM		    547		 struct VSprite		       523
SetRGB4			    547		 struct Window		       525
SetSoftSlyle		    548

				PAGE 598

-----------------------------------------------------------------------------

StyleEnable		    392		 View structure		   	173
Superbit		     99		 ViewAddress			168
Superbilmap (Layersuper)    196		 ViewPort  117,151,166,188,317,323,
Superbitmap 	  194, 204, 293				      344, 381, 413
Superbitmap Paint Program   294		 ViewPort Modes			153
SuperClipRect		    194		 ViewPort structure	   153, 318
supergraphic		    211		 ViewPort			345
SWAP-assignments	     40		 VP_HIDE		   155, 435
switch element		    103		 VSprite			459
synchronous		    274		 VSprite flag		    464,466
system components	    212		 VSprite structure	456,466,453
system crash		     90		 VSprite variables		467
systEm data structure	    212		 VSprite.OldX			477
system libraries	     88		 VSprite.OldY			477
					 Vspritess 435,451,453,456,458,465,
Text			    548					   467, 495
Textheight		    127
text length		    389		 WAIT				180
text styles		    144		 WaitBlit ()			549
Text()			    141		 WaitBOVP (&ViewPort)		549
TextAtt			    218		 WaitTOF	      204, 205, 549
TextAttr structure     390, 393		 wd				 67
TextFont		    214		 width table			217
TextFont data Structure	    215		 WINDOW OUTPUT			 95
TextFont structure  220,235,250		 Window				 93
TextLength		    548		 Window borders			101
TIMER			     29		 Window colors			105
timer			    481		 Window limits			 98
timeset			    483		 Window modes			 99
Title text		    100		 window data structure	    96, 120
TmpRas			    124		 window size			 96
TmpRas			    207		 WINDOW(7)		    93, 103
topaz 8			    213		 WINDOW(8)		   122, 214
topaz 9			    213		 WindowLimits			110
topaz font		    221		 windows		   103, 345
transmit		    179		 WindowToBack		        113
WindowToFront		    113
UCopList		    181		 word field			 95
Undefined function values    16		 WRITE				 50
UnLocklayer		    194		 Writemask			124
user Copper list	    181		WritePixel (&RastPort, X, Y)	550
user data		    117		WritePixel (&RastPort, X, Y)	327
UserCopperList		    495
					XOR				 51
VBeamPos()		    549
View			    167
View		       317, 413

				PAGE 599

-----------------------------------------------------------------------------
				T H E   E N D 
-----------------------------------------------------------------------------
	
