[0m
                    _____     ____       ___       ____      
                   / ___/\   / __ \     / _/      / __ \   
                  / / _/ /  / /  \/\   / /       / /  \/\    
                  \ \ \_/  / /   / /  / /       / /   / /  
                /\ \ \    / /   / /  / /       / /   / /    
               / /__\ \  / /___/ /  / /___/\  / /___/ /   
               \/____\/  \/_____/   \/____\/  \/_____/  [3mPresents...[0m  

                                   THE

                                  AMIGA

                               PROGRAMMERS

                                  GUIDE.

                            By C.J DITCHBURN

                             (V1.0 Edition)

        Manual supplied & typed in by SLIDER of SOLO Productions.


PUBLISHED BY:
                   THE UNIVERSITY OF ST.ANDREW
                   DEPT. OF COMPUTATIONAL SCIENCE.
                   ST.ANDREWS
                   FIFE



Copyright  1990
                [3mAll rights reserved. No part of this book may be reproduced in
                [3many way or by any means, without written permission from the
                [3mpublisher[0m.


                AMIGA A500 IS A REGISTERED TRADEMARK OF COMMODORE AMIGA INC.

             
Page 3.

                [0m[4;29mSECTION I[0m   :   Inside the Amiga A500.

                [0m[4;29mSECTION II[0m  :   Programming the Hardware.

                [0m[4;29mSECTION III[0m :   Game Writing.


Page 5.

                [0m[4;29mSECTION I:[0m Inside the Amiga A500.


                1. Introduction.                           7

                2. The Processor and the Custom Chips.     9

                3. Memory configuration.                   15

                4. DMA Control.                            19


Page 7.

                [0m[4;29m1.   INTRODUCTION.[0m


  The Amiga Games Programmers Guide aims to give the budding Amiga games
programmers a first step in writing a block-busting game.  It introduces
the complex hardware in a simple way, and describes how to manipulate this
powerful machine.


  Areas covered are sprites, audio output, the blitter and many more which
will give the reader an insight into the Amiga's inner workings.
Programming languages are also discussed in later chapters, describing how
to work with the custom circuitry.


  This hardware is the heart of the machine, and must be accessed directly
to get the most from the Amiga.
This book will show you how.


  The Amiga Games Programmers Guide was written by a games programmer, for
games programmers. Whether you want to read about the Amiga, or just want a
simple to understand hardware book - This is it!


Page 9.

                [0m[4;29m2. The Processor and Custom Chips[0m


                2.1   Binary and Hexadecimal               11

                2.2   The Processor and Registers          13

                2.3   Agnus, Denise and Paula              14



Page 11.

                [0m[4;29m2.  The Processor and Custom Chips[0m

                2.1  Binary and Hexidecimal.


  Everyday numbers are in decimal.  This scale uses the ten digits 0-9 and
puts them together to form numbers.
  However, computers only have two digits available to form their numbers.
These two digits represent ON and OFF, which most electrical devices can 
usually be.
  The digits are 0 and 1, and the BINARY system forms them into numbers.

The BINARY DIGITS (BITS) 0 and 1 are grouped together into combinations.

Using ONE bit, the combinations 0,1 are possible.
Using TWO bits, the combinations are 00,01,10,11.
          (Thus two bits can represent 4 numbers)
Similarly, 8 bits give 256 combinations, and thus 256 numbers are possible.
(2\8=256)

The Amiga is a 16-bit machine, meaning that it works with numbers between
0-65535.

A group of 8 bits=  a BYTE
           16 bits= a WORD
           32 bits= a LONG WORD

To illustrate this, some BYTES are shown:

           [0m[4;29m128    64    32    16    8    4    2    1[0m
  5:        0     0     0     0     0    1    0    1      (4+1=5)


           [0m[4;29m128    64    32    16    8    4    2    1[0m
 33:        0     0     1     0     0    0    0    1      (32+1=33)



(% denotes a binary number such that %00100001=33)


Page 12.

                [0m[4;29m2.  The Processor and Custom Chips[0m


  Binary, although perfect for computers, is too confusing for humans. It is
hard to interpreta string of 0's and 1's.
So, a compromise is taken - HEXADECIMAL Notation.

Hexadecimal notation (HEX for short) uses base 16 numbers, ie the decimal
numbers 0-16 are represented by one hex digit. This is alright for numbers
0-9, but the numbers 10-16 use letters A-F to represent them.


  [0m[4;29mHEX:  0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F [0m
  DEC:  0   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15

  (Thus the decimal number 12 is represented by $C.)

  For numbers over 15, TWO hex digits are used:

                              15 =  $0F
                              16 =  $10
                              17 =  $11
                              etc......
                              254 = $FE
                              255 = $FF

  The first digit denotes the number of 16s, and the second, the number of
`units'

  This can be taken a step further, using four digits:

                              255 = $00FF
                              256 = $0100
                              257 = $0101
                              etc........
                             4096 = $1000
                            65535 = $FFFF

  Once you understand binary and hex, the rest comes easy!


Page 13.

                [0m[4;29m2.2 The Processor and Registers[0m


The Amiga is based around a powerful 68000 series microprocessor. Earlier
processors (eg. 6502) were limited in their use, because they only had one
Accumulator, with which the processor did all the arithmetic and logic
functions.

The 68000 has the equivalent of 15 Accumulators, 8 of which are for data 
only, and the other 7 for storing addresses.

The full register set of the 68000 is shown below:

  8 DATA REGISTERS            -   32 BIT (D0-D7)

  7 ADDRESS REGISTERS         -   32 BIT (A0-A6)

  PROGRAM COUNTER             -   24 BIT (PC)

  2 STACK POINTERS            -   32 BIT (SP)

  STATUS REGISTER             -   16 BIT (SR)


The stack pointers are used by both user and operating system, so they have
one (only one) each. (USER/SUPERVISOR STACK POINTERS.)

The status register has 16 bits, giving the status of operations.  The bits
are set out thus:

  [0m[4;29m15   14   13   12   11   10   9   8   7   6   5   4   3   2   1   0[0m
  T    *    S    *    *    |    |   |   *   *   *   X   N   Z   V   C
                            2    1   0

  T   =   Trace mode bit
  S   =   Supervisor state bit
  |   =   Interrupt mask bits
   210
  X   =   Extend bit
  Z   =   Zero flag
  N   =   Negative flag
  V   =   Overflow flag
  C   =   Carry flag


Page 14.

                [0m[4;29m2.  The Processor and Custom Chips[0m


  The 24-bit program counter looks after which instruction is to be executed
next in the program.  It's address range is 2\24, ie 16,777,216 bits (16 Mb)
so it can address any location in the 16Mb range.


                2.2  Agnus, Denise and Paula

  Knowledge of the custom chips is not too vital to the games programmer, so
only an overview is included here.

  Agnus contains the Blitter and DMA circuitry. These are explained later.

  Denise is responsible for graphics and incorporates the copper co-processor.
Denise also looks after sprites and the mouse. (the mouse pointer is a sprite)

  Paula controls the audio output of four-channel stereo sound, and all good
games must have quality sound. so a whole section is devoted to this.


Page 15.

                [0m[4;29m3. Memory Configuration[0m


                3.1  Memory Map                            16

                3.2  Chip RAM                              17

                3.3  Custom Chip RAM                       17

                3.4  CIA Areas                             18

                3.5  Example of register addressing        18


Page 16. 

                [0m[4;29m3. Memory configuration[0m

3.1 Memory Map

As mentioned earlier in section 2.2, the Amiga has a 16Mb address range.
(from $000000 to $FFFFFF)

  This is arranged as follows:


  $000000-$07FFFF   512k Chip RAM located in here

  $080000-$1FFFFF   Reserved.

  $200000-$9FFFFF   8Mb for FAST-RAM

  $A00000-$BFFFFF   CIA Area

  $C00000-$C7FFFF   512k Expansion RAM

  $C80000-$DFEFFF   Reserved.

  $DF0000-$DFFFFF   Custom Chip Area

  $E00000-$FFFFFF   Reserved/ROM


The games programmer is only concerned with areas:

  $000000-$07FFFF   (Chip ram 512k in here),
  $DF0000-$DFFFFF   (Custom Chip area) and
  $A00000-$BFFFFF   (CIA Area).

The rest have no real relevance.


Page 17.

                [0m[4;29m3. Memory Configuration[0m

  3.2 Chip RAM ($000000-$7FFFFF)

  This is the only area of memory which the custom hardware can address, thus
programs and data have to be placed here.
  Since the Amiga uses a dynamic memory management system, an area of memory
in here has to be requested (using the operating system) for any data lists
(such as copperlists and sprite data), and then the data has to be copied, or
directly inserted into here.


                3.3 Custom Chip RAM ($DFF000-$DFFFFF)

  To use the custom chips, registers within the custom chip RAM have to be 
accessed.  These registers are all one word long, and are all on even 
addresses.
  Actually, only addresses $DFF000-DFF1BE are used, and some are read-only,
some are write-only, and some are strobe registers.

  The base address is $DFF000, and subsequent addresses are added on. Some
registers are illustrated here, but all essential ones are explained fully
in relevant sections.


  BASE ADDRESS = $DFF000

  DMACON  -  $002      DMA CONtrol Register
  JOYDAT0 -  $00A      Mouse/Joystick position reg. (port0)
  COLOUR0 -  $180      Colour reg. zero (background colour.)
  
  COP1LCH -  $080      These two registers hold the address
  COP1LCL -  $082      of the first copperlist.


Page 18.

                [0m[4;29m3. Memory configuration[0m

3.4 CIA Areas ($A00000-$BFFFFF)

  CIA stands for Complex Interface Adapter, and there are two of these in the
Amiga- CIA A and CIA B.
  They contain timers and event counters, and more usefully, they tell the 
status of the mouse buttons and joystick fire button.


3.5 Example of register addressing 

  Registers are best addressed by placing the base address of the custom chips
in an address register, and then accesssing the other registers via this.

  For example, to put the colour 0 (Black) into the background colour
register ($180), the following can be done:

  LEA $DFF000,a6           (base address in reg.a6)
  MOVE #$00,$180(a6) 

  It is also possible to write to two registers at once, in the case of
pointers to data lists.
For example COP1LCH and COP1LCL ($080,$082) hold the 19-bit address of the 
first copperlist, split between the two. One write can be made so that both
are written to together:

  LEA $DFF000,a6
  MOVE .L copaddr,$80(a6)

  Since `copaddr' is 19 bits long, the lower 16 bits are placed into $082,
and the other 3 bits into $080.


Page 19.

                [0m[4;29m4. DMA CONTROL[0m


                4.1  What is DMA ?                         20

                4.2  Using DMA                             20





page 20.

                4.1 What is DMA ?

  DMA stands for Direct Memory Access, and is a method of getting at the 
memory locations, without going through the processor. The Amiga incorporates
a DMA controller, which is a processor looking after graphics, sound and the
disk access, and does so independantly of the 68000.
  The DMA has SIX channels for areas which involve lots of data transfer such
as the blitter, but has to channels for simple devices such as the joystick,
(which the 68000 has to service).

  The six channels are for: SPRITES,AUDIO,COPPER,BLITTER,BITPLANES and
  DISK-ACCESS.


  4.2 Using DMA

  The DMA channels can be opened to initiate their device, ie opening the
copper DMA channel will enable the copper.
  All channels are accessed through one register, DMACON which can be read
at $002, and written to at $096.

  The 16-bit DMACON Register has the following configuration. (setting bits
to 1 will enable the device.)

  Bits 0-3        Audio Channels 0-3
  Bit 4           Disk DMA
  Bit 5           Sprite DMA
  Bit 6           Blitter DMA
  Bit 7           Copper DMA
  Bit 8           Bitplane DMA
  Bit 9           DMAENABLE - If set, enables all channels
  Bit 10          BLTPRI - If set, gives blitter priority over 68000.
  Bit 11          [UNUSED]
  Bit 12          [UNUSED]
  Bit 13          BZERO-(read only)-For Blitter operations
  Bit 14          BBUSY-(read only)-For Blitter operations
  Bit 15          SET/CLEAR bits.



Page 21.

                [0m[4;29m4. DMA Control[0m

  Bit 15 in DMACON is a special bit. It must be 1 if bits are to be set in the
register, ie writing a data word with bits 7 & 15 set (%1000000010000000) into
DMACON, will set bit 7, enabling the copper DMA.
  If bit 15 is 0 and bit 7 is (%1000000010000000) then writing this data will
[3mclear[0m bit 7, disabling the copper.


  Bit 9 must be set for any channel to be open, regardless if it is set or
not. If bit 9 is zero, then all channels are rendered inactive.

  Bit 10, if set, will give the blitter a higher priority than the processor,
effectively giving the blitter exclusive access to the chip RAM during a
blitter operation.



page 23.

                [0m[4;29mSECTION II: Programming the Hardware.[0m


                5.  The Copper Co-processor                25

                6.  Screens and Bitplanes                  35

                7.  Sprites                                43

                8.  The Blitter                            47

                9.  Audio Output                           53

                10. Mouse, Joystick and Interupts          59




Page 25.

                [0m[4;29m5. THE COPPER COPROCESSOR[0m


                5.1   Function of the copper               27

                5.2   Copper Control                       27

                5.3   Copper Registers                     28

                5.4   MOVE, WAIT and SKIP                  29

                5.5   Example Copperlist                   30

                5.6   Example Program                      32


Page 27.

  5.1  Function of the Copper


  The copper is a graphics coprocessor, which like the 68000 runs a program
in memory. This program is usually one which controls or monitors the screen
electron beam position, and is called a copperlist.
  Copperlists consist of two-word commands and must be resident in chip ram,
and pointers must be set which point to their locations.



  5.2  Copper Control

  A copperlist is made up of three possible commands:
  MOVE, WAIT and SKIP.

  MOVE: Puts an immediate value into a register in the custom chips.

  e.g.  MOVE #2,$DFF00A   ;puts decimal 2 into $DFF00A.


  WAIT: Wait until a desired screen position x,y is reached.

  e.g.  WAIT (x,y)


  SKIP: This conditional statement will miss out the next command in the
copperlist if a certain screen position is reached.



Page 28.

                [0m[4;29m5. The Copper Coprocessor[0m


  5.3 Copper Registers

  
  The copper has a number of associated registers:

  COP1LC holds the 19-bit address of the first address of the first copper-
list, split between COP1LCL and COP1LCH.

  COP1LCL = $DFF082 - lowest 16 of the 19 bits.
  COP1LCH = $DFF080 - remaining 3 bits.

  Similarly, COP2LCH ($DFF084)
             COP2LCL ($DFF086)
  hold the 19-bit address of the second copperlist.


  The two registers can be written to with one MOVE command, as explained in
section 3.5.

  Once the copperlists have been put into chip ram, and these COPLC pointers
set to where they are, they can be executed by the use of two more registers.

  COPJMP1 ($DFF088) and COPJMP2 ($DFFO8A) are two trigger, or strobe 
registers, which when written to (any value) will start the appropriate
copperlist.


  The address contained in COP1LC is automatically loaded into the copper
program counter at the start of every frame, so each picture runs under the
same copperlist.
  The COPCOON register ($DFF02E) is a single bit register which can be set
to allow the copper to access the blitter registers ($DFF040-$DFF07E).


  5.4  MOVE, WAIT and SKIP

  These commands are represented as two words, and each individual bit has a
function.

  MOVE:
  [0m[4;29mWORD1[0m
            Bit 0      Must be set to 0 for MOVE.
            Bits 1-8   Contain the register address upon which the MOVE
command operates. Only the upper 8 bits of this 9-bit value are held here,
as bit 0 is fixed to 0, so that only even addresses are possible.


Page 29.

                [0m[4;29m5. The Copper Coprocessor[0m


  In simpler terms, all you have to do is write an even 9-bit register
address to WORD 1, and MOVE is automatically registered.
                    Bits 9-15 are unused.

[0m[4;29mWORD2[0m

                    Bits 0-15 contain the data word which is to be
                    MOVEd.

WAIT:
[0m[4;29mWORD1[0m
                    Bit 0 Must be set to 1 for WAIT.
                    Bits 1-7 Contain the horizontal beam position.
                    Bits 8-15 Contain the vertical position.

[0m[4;29mWORD2[0m
                    Bit 0 Must be set to 0 for WAIT.
                    Bits 1-7 Horizontal Masking bits.
                    Bits 8-14 Vertical masking bits.
                    Bit 15 BFD bit.


In word 1, the vertical beam position is specified by 8 bits, giving a range
of 256 beam positions (0-255).
However, there are actually 313 beam positions possible, so to wait for a 
position between 256-313, position 255 must be waited for fist.

           e.g.     WAIT 0,255
                    WAIT 0.0     ;will wait for (0,256)

           and
                    WAIT 0,255
                    WAIT 0,0     ;WILL WAIT FOR (0,286)


  Bits 1-7 contain the upper 7 bits of the 9-bit horizontal beam position.
The first two bits are fixed at 0 so that horizontal positions are waited
for in steps of 4 pixels, (ie 0,4,8,12 etc......).


  The horizontal screen resolution is 0-320, and with 9 bits, there are 512
available positions, making some impossible. 
  Waiting for an impossible position will end the copperlist, and this 
should be done at the end of all copperlists.


Page 30.

                [0m[4;29m5. The Copper Coprocessor[0m


  The masking bits in word 2 are for manipulationg which bits of the positions
are taken into account.
  These should all be set to 1 for normal operation.

  The BFD bit is the Blitter Finish Disable bit, and if set to 0 the copper
will always wait until the blitter is finished before proceeding. It should
be 1 for normal operation, so the blitter is ignored.

  SKIP:
  This command is the same as WAIT, but it will miss the next command upon
reaching the beam position.

  e.g.       SKIP (X,Y)
             MOVE #$00,$180

  will cause the second command to be missed if the position is more or equal
to (X,Y).

  The control words are the same as in move, exept bit 0 in word 2 is 1.
  (0 in WAIT).



  5.5 Example Copperlist

  The following is a procedure to installing a copperlist: 


  1. Request free chip ram for copperlist.
  2. Copy copperlist (or construct directly into the free memory area.)
  3. Turn copper DMA channel OFF
  4. Move addres of copperlist into COP1LC
  5. Activate copperlist (write to COPJMP1)
  6. Turn copper DMA channel ON
  7. Wait for exit, then restore old copperlist.


  A real copperlist looks like this:

                   MOVE #$0000,$180
                   WAIT 15,160
                   MOVE #$FFFF,$180
                   WAIT 255,255

  This puts black ($0000) into colour reg.0 and waits for the middle of the 
screen (15,160) before changing this into white ($FFFF).  Waiting for
(255,255) ends the copperlist.


Page 31.

                [0m[4;29m5. The Coprocessor[0m


  The paired words are constructed thus:

  MOVE #$0000,$180 = $180,$0000
  Bits 0-8 are set in word 1 to $180. This also sets bit 0 to 0, so 
indicating a MOVE. (Bits 9-15 unused.)
  Bits 0-15 in word 2 are $0000, the data word being MOVEd.
  (Note reversal in words.)


  WAIT(15,160) = $A00F,$FFEE
  Bit 0 in word 1 is 0, as needed for a WAIT, and bits 1-7 are set to 15($0F)
Bits 8-15 are 160($A0).
  All masking bits are set in word 2, and bit 0 is 0 for WAIT.


  Similarly,

                   MOVE #$FFFF,$180 = $180,$FFFF
                   WAIT(255,255) = $FFFF,$FFFE


  So the whole copperlist is:
                   
                   $180,$0000
                   $A00F,$FFFE
                   $180,$FFFF
                   $FFFF,$FFFE

Note that the screen position is 15, 160 not 0,160.
This is because the horizontal blanking gap starts at 15, and
this is at the right edge of the screen, making beam position 0
about an inch in from the far right of the screen.
  Any screen changes should be made in an invisible screen position, so
that they are flicker-free.

The horizontal beam positions are from 0-227 ($00-$E3).
  With Horizontal Blanking gap 15-53.

The Vertical beam positions are from 0-312($00-$138)
  With Vertical Blanking gap 0-25.
These beam positions can be read at VHPOS and VPOS.

VHPOS(read)($006)         VHPOS(write)($02C)
VPOS(read)($004)          VPOS(write)($02A)

VHPOS: Bits 0-7 Horizontal beam position(0-227)
       Bits 8-15 Lower 8 Bits of 9-bit Vertical position.

VPOS:  Bit 0  MSB of 9-Bit Vertical Position.
       Bits 1-14 Unused
       Bit 15 LOF(Long Frame) Set to 0 for interlace mode.





Page 32.

                [0m[4;29m5. The Copper Coprocessor.[0m


  The following program installs the copperlist in the previous section.


  incdir  "include/"
  include "graphics/graphics_lib.l"

  *********REQUEST FREE CHIP RAM ADDRESS TO PUT COPPERLIST INTO***********

  move.l $4,a6               ;Puts the base address of the operating system
                              into a6.
  moveq #size,d0             ;Size of copperlist in bytes.
  moveq #2,d1                ;"2" specifies CHIP ram.
  JMP -198(a6)               ;This is the ALLOCMEM operating system call
                              (offset -198). It needs the parameters passed
                              in d0=size of memory needed and d1=Type of
                              memory. (2=chip ram,$10002=chip ram filled
                              with zeros.)

  move.l d0,address          ;Address of free ram is returned by the call in
                              d0, so d0 is moved into `address', which
                              denotes the starting address of the free ram.

  *COPY COPPERLIST FROM PROGRAM DATA INTO CHIP RAM, FROM `ADDRESS' ONWARDS*

  lea start,a0               ;Address of program copper
                              data into a0.
  lea address,a1             ;address of free ram into a1.
  moveq #size-1,d0           ;loop counter value into d0.
  loop move.b (a0)+,(a1)+
  dbf do,loop
  
  **************TURN OFF DMA CHANNELS (copper,bitplane)*******************
                              
  lea $dff000,a5             ;custom chip base to a5.
  move.w #$0380,$96(a5)      ;96=DMACON.
  move.l #address,$80(a5)    ;Put copper start address into COP1LC($80).
  cir.w $88(a5)              ;Start the copperlist by clearing COPJMP($88).

  ******************RE-ENABLE DMA CHANNELS. (copper only)*****************

  move.w #$8280,$96(a5)      

  ***************WAIT FOR MOUSEBUTTON PRESS BEFORE EXITING****************

  pause btst #6,$bfe001      ;CIAPRA=$bfe001, bit 6 of this is set upon
                              pressing the left mouse button.
  bne.s pause                ;wait until it is pressed.

  ***********************RESTORE OLD COPPERLIST***************************

  move.l #name,a1            ;name of graphics lib.
  cir.l d0
  JMP -552(a6)               ;-552 is OPENLIB offset.

  move.l d0,a4               ;address of graphics lib.
                              returned in d0, passed to a4.
  move.l 38(a4),$80(a5)      ;Startup copperlist address is moved from its
                              address in 38 from the graphics base to
                              COP1LC
  cir.w $88(a5)              ;Start copper.
  move.w #$8380,$96(a5)      ;Re-enable Bitplane DMA also

  rts

  ******************************* DATA ***********************************

  address dc.l 0

  start:
  dc.w $000f,$fffe,$180,$0000
  dc.w $a00f,$fffe,$180,$fffe
  dc.w $ffff,$fffe
  cop.end:

  size=cop.end-start

  even
  name dc.b "graphics.library",0


Page 35.

                [0m[4;29m6. SCREEN AND BITMAPS[0m


                6.1   Amiga Colour Graphics                36

                6.2   Bitplanes                            37

                6.3   Constructing Bitplanes               37

                6.4   Setting the screen Window            38

                6.5   Setting Bitplane Size                38

                6.6   Setting Bitplane Addresses           39

                6.7   Bitplane Example                     39

                6.8   Bitplane Program                     40

                6.9   Scrolling                            42


Page 36.

                [0m[4;29m6. Screens and Bitmaps[0m


  6.1 Amiga Colour Graphics

  One main part of a successful game is impressive graphics.  Most games use
the 320x200 screen mode, with up to 32 colours, thus each pixel takes its
colour from one of the 32 colour registers.
  For example, if pixel(100,100) is to be `green', then one register must
contain `green', and the pixel must be told to look at that particular
register for its colour.

  This is done in quite a complex way, but each pixel is assigned a value of
0-31 which tells it to look at the corresponding register.

Colour registers 0-31 are:

                00-$180                etc...
                01-$182                29-$1BA
                02-$184                30-$1BC
                03-$186                31-$1BE.
                04-$188
                05-$18A
                06-$18C
                07-$18E
                etc...


Each colour in the 16 bit register is mixed from red, green and blue
components:

Bits 0-3:  Blue Component $0-$F(16 levels)
Bits 4-7:  Green Component $0-$F(16 levels)
Bits 8-11: Red Component $0-$F(16 levels)
Bits 12-15:Unused

For example:
Black=%xxxx 0000 0000 0000 =$0000
White=%xxxx 1111 1111 1111 =$0fff
Red  =%xxxx 1111 0000 0000 =$0f00


Page 37.

                [0m[4;29m6. Screens and Bitmaps[0m

6.2 Bitplanes.

  The way in which each screen pixel is assigned a value is with a series of 
bitplanes (a bitplane=a grid of bits).
Puttting two bitplanes on top of each other assigns each pixel two bits, one
from each plane.
  Consider the following two 4x4 bitplanes:

                0001                 0001
                0010                 0000
                0100                 0000
                1000                 0001
                 #1                   #2

  The top left pixel has values 0 from plane 1 and 0 from plane 2.
  This gives tells the pixel to look at register 00 for its colour.
  The top right pixel = 1,1 so it looks at register %11=3.
  The bottom right pixel = 0,1 so its register is %01=1.
  The bottom left = 1,0 so it looks at %10=2.

  Adding a third bitplane gives possiblities 000 to 111 for each pixel,
giving 8 colours. With 5 bitplanes, 32 colours are possible.

Each 320x200 bitplane takes up 64000 bits, and 5 bitplanes mean a 32 colour
screen takes up 40K of memory.
  Due to this limitation in memory, few games use fully bitmapped screens, so
to give the illusion of a multiscreen play area, repeating graphical segments
are held in memory, and then copied (and replaced) into the screen memory area
by the blitter, as needed.

  The bitplanes consist of chunks of words, so the first 16 pixels of each
bitplane are contained in its first 16-bit word.
  Each 64000 pixel plane uses 64000/16=4000 words, and these must be reserved
somewhere in chip ram. A block of chip ram is allocated by the ALLOCMEM call,
having size (4000words *2*no. of planes) in bytes.
  Pointers to their starting addresses must also be set so that the DMA
controller can find them in chip ram.


6.3  Constructing Bitplanes

  To construct a bitmap, these are some procedures to undergo:
First, the screen window must be set, then the bitplane size is set and the 
number of bitplanes chosen.


Page 38.

  To set the wndow through which the bitmap is to be viewed, two coordinates 
must be specified.
  The upper left and lower right+1 positions are held in DISplay Window,
START/STOP:
DIWSTART($08e),DIWSTOP($090).
The coordinates must be set as
            Horizontally: pixels (0-320)
            Vertically: raster lines (0-312).

DIWSTART 
Bits 0-7: Contain horizontal start position (0-255 only)
Bits 8-15: Contain the vertical start line (0-255 only)

DIWSTOP
Bits 0-7: Contain horizontal end position from 255 to 320.
              (i.e writing 10 here specifies position 266)
Bits 8-15: Contain the vertical line from 128-312.
              (If bit 15=1, bits define 128-255)
              (If Bit 15=0, bits define 256-312)

NB:- The difference in DIWSTART amd DIWSTOP must always be divisible by 8!


6.5 Setting Bitplane Size

  The DMA must know the size of the bitplanes for it to display them.
Horizontally, the DMA must be told to start to display the bitplane 17 pixels
before the starting position in DIWSTART. This is so that is has enough time
to read the first word of all the bitplanes and the combine them into 
coloured pixels.
  This  starting position is written to DDFSTART (Display Data Fetch START)
at $092.
Bits 3-7 are used here to specify the upper 5 bits of the 9-bit value 
(bits 0-2=zeroed.)
DDFSTOP at $094 specifies the horizontal end position and has the same bit 
layout as DDFSTART. 16 pixels must be substracted from the DDFSTOP value for
the hardware to be able to cope.

DDFSTART is limited to a minimum of 24, and DDFSTOP by a maximum of 216.


Page 39.

                [0m[4;29m6. Screens and Bitmaps[0m

  The values have to be halved before writing them.
An example shows the procedure:

Normal screen starts at 129:
DDFSTART = (129-17)/2 = 56.($38)
DDFSTOP = 56+(320-16)/2 = $d0.


6.6 Setting Bitplane Addresses

  The bitplane data must be constructed in chip ram, and pointers set to 
where it is:

Bitplane 1: BPL1PTH($0E0),BPL1PTL($0E2).
Bitplane 2: BPL2PTH($0E4),BPL2PTL($0E6).
Bitplane 3: BPL3PTH($0E8),BPL3PTL($0EA).
Bitplane 4: BPL4PTH($0EC),BPL4PTL($0EE).
Bitplane 5: BPL5PTH($0F0),BPL5PTL($0F2).
Bitplane 6: BPL6PTH($0F4),BPL6PTL($0F6).


A control register must also be set:
BPLCON0($100) Relevant bits:
         Bit 2 Sets interlace mode if=1
         Bit 10 Sets Dual playfield if=1
         Bit 11 Sets HAM mode if=1
         Bits 12-14 SELECTS no of Bitplanes (0-6).
         Bit 15 Sets HIRES mode if=1


6.7 Bitplane Routine Example

1. Request cleared chip ram for all bitplanes.
2. Request copper chip ram.
3. Copy/construct copperlist into chip ram.
4. Disable DMA.
5. Initialize copper.
6. Put colours into colour register.
7. Set DIWSTART etc.
8. Re-enable DMA.
9. Modify bitplane memory.
10. Upon exiting, restore old copperlist and free memory.


Page 40.

                [0m[4;29m6. Screens and Bitmaps[0m

6.8 Bitplane Program

The copperlist for this program is:

                MOVE PLANE.1.H, PLANE.1.H.POINTER($0E0)
                MOVE PLANE.1.L, PLANE.1.L.POINTER($0E2)
                etc...............
                ...(same for the rest of the planes)...
                WAIT 255,255

Word for word, it should look like this:

                cop.start               $0e0
                cop.start+1             bit.start(Hi)
                cop.start+2             $0e2
                cop.start+3             bit.start(lo)
                cop.start+4             $0e4
                cop.start+5             bit.start(Hi)+8000
                etc...                  .....
                ......                  .....
                cop.start+21            $ffff
                cop.start+22            $fffe

The program splits the 19-bit bit.start into high and low words, and loops
through putting them into appropriate addressed. The SWAP command is used to
swap register halves so that this can be accomplished.

The program:

*****  REQUEST BITPLANE CHIPRAM  *****

       MOVE.L $4, A6
       MOVE.L #(5*8000)*2, 00         ;*5 planes of 8000*2 bytes.
       MOVE.L #$10002, D1             ;*$10002 request nulled ram.
       JSR -198(A6)
       MOVE.L D0, BIT.START

*****  REQUEST COPPER CHIP RAM  *****

       MOVE.L #22*2, 00
       MOVE.L #2, 01
       JSR -1198(A6)
       MOVE.L D0, COP.START

*****  COPY COPPERLIST  *****

       MOVE.L COP.START, A0
       MOVE.L BIT.START, D1
       MOVE.W #4, D4
       MOVE.W #$E0, D2
 LOOP: MOVE.W D2, (A0)+
       SWAP D1
       ADD #2, D2
       MOVE.W D2, (A0)+
       SWAP D1
       MOVE.W D1,(A0)+
       ADD.L #8000,D1
       ADD #2, D2
       DBF D4, LOOP

       MOVE.W #$FFFF, (A0)+
       MOVE.W #$FFFE, (A0)

*****  DISABLE DMA (COPPER, SPRITE, BLITTER AND BITPLANE)  *****

       LEA $DFF000, A5
       MOVE.W #$03E0, $96(A5)

*****  INITIATE COPPER  *****

       MOVE.L COP.START, $80(A5)
       CLR.W $88(A5)

*****  SET COLOURS (ONLY 2 DONE HERE)  *****

       MOVE.W #$0000, $180(A5)
       MOVE.W #$0FFF, $182(A5)

*****  SET DIWSTART ETC  *****

       MOVE.W #$2981, $8E(A5)
       MOVE.W #$29C1, $90(A5)
       MOVE.W #$38, $92(A5)
       MOVE.W #D0, $94(A5)
       MOVE.W #$5000, $100(A5)
       CLR.W $102(A5)
       CLR.W $104(A5)
       CLR.W $108(A5)
       CLR.W $10A(A5)

*****  REENABLE DMA (BITPLANE AND COPPER, NOT BLITTER!)  *****

       MOVE #48380, $96(A5)

*****  MODIFY BITPLANE MEMORY (THIS DRAWS A LINE...)  *****

       MOVE.L BIT.START, A1
       ADD #4000, A1
       MOVE #19, D4
LOOP2: MOVE #$FFFF, (A1)+
       DBF D4, LOOP2

*****  WAIT AND EXIT  *****

PAUSE: BTST #6, $BFE001
       BNE.S PAUSE
       MOVE.W #$8060, $96(A5)

       MOVE.L #NAME, A1
       CLR.L D0
       JSR -552(A6)
       MOVE.L D0, A4
       MOVE.L 38(A4), $80(A5)
       CLR.W $88(A5)

       MOVE.L BIT.START, A1
       MOVE.L #(10*8000),D0
       JSR -210(A6)
       RTS

*****  DATA  *****

BIT.START DC.L 0
COP.START DC.L 0
  EVEN
NAME DC.B "GRAPHICS.LIBRARY", 0


6.9 Scrolling

  Vertical scrolling is achieved by having a longer-than visible block of
words in bitplane memory, ie a normal bitplane is 8000 words, but 16000 words
in chip ram give 2 screens of bitmapped data. Setting pointers to word 1 will
display the first 8000 words, then increasing these pointers in steps of one,
from 1 to 8001 will graduallly scroll the next 8000 words into view.
  The bitplane pointers should be changed in the vertical blanking gap, with
the copper. The copperlist is then changed. Change the pointers by getting
the processor to wait for raster line 16,and then alter the copperlist.


Page 43.

                [0m[4;29m7. SPRITES.[0m


                7.1  Introducing Hardware Sprites          44

                7.2  Colouring Sprites                     44

                7.3  The Sprite Data List                  45

                7.4  Combining Sprites for More Than One
                     Colour                                45

                7.5  Activating Sprites with the DMA       46

                7.6  Collisions.                           46


Page 44.

                [0m[4;29m7. Sprites.[0m

7.1 Introducing Hardware Sprites

  Sprites are special moveable objects which most games feature to some
extent. The sprites are held in memory as small bitplanes, and registers must
be set to look after them. The Amiga can only display up to 8 sprites, but 
there are techniques to make this seem more. Each sprite is 16 pixels wide
and of any height. It can have 3 colours in basic mode, but two sprites can
be combined to give 15 colours. Similarly, sprites can be bolted together to
have more width.


7.2 Colouring Sprites

  The 8 sprites are numbered 0-7 and each pixel is represented by two bits, so
that are 2\2=4 combinations per pixel. This gives 3 colours and one 
`transparent' colour.
  These colours are held in the colour registers, and sprites are allocated
their own registers thus:

sprites 0&1: registers 17,18,19
sprites 2&3: registers 21,22,23
sprites 4&5: registers 25,26,27
sprites 6&7: registers 29,30,31

  The pixel combination choses the register thus:

e.g.         00=transparent.
             01=reg. 17
             10=reg. 18
             11=reg. 19.

Writing colours to these registers is just the same as explained in section
6.1, and their addresses continue from:     #00=$180
                                            #01=$182
                                            etc...
                                            #31=$1BE.

Page 45.

                [0m[4;29m7. Sprites.[0m

7.3 The Sprite Data List

  The sprite data is stored in chip-ram as a list of words paired in this
way:
                Control data:2 words
                Pixel data for line 1:2 words
                Pixel data for line 2:2 words
                etc...  ...  ...
                Pixel data for last line:2 words
                "End of sprite data":2 words of $0,$0.

  The two control words hold information about the sprite's screen position,
and its type: combined or single. The DMA controller reads these words and
then displays the sprite line by line until it reaches the terminator of 0,0.

WORD 1:
Bits 0-7: Lower 8 bits of horizontal start position (HSTART).
Bits 8-15: Lower 8 bits of vertical start position (VSTART).

WORD 2:
Bit 0: 9th bit of HSTART
Bit 1: 9th bit of VSTOP
Bit 2: 9th bit of VSTART
Bits 3-6: Zeroed.
Bit 7: AT bit- Set for combined sprites.
Bits 8-15: Lower 8 bits of VSTOP (End of sprite vertically +1).


Each of the sprite positions is 9 bits long. This gives positions of 0-512
possible ($0-$200).


7.4 Combining Sprites For More Than One Colour

  Sprites are combined together to give 15 colours in a set way:
0&1, 2&3, 4&5, 6&7. Setting the AT bit in the control word of the ODD one 
of the pair will make the pair into one.
  When combined, each pixel now has 4 bits to represent it, one from each of
the now four data words:
                        Bit 0: Sprite 0 1st word
                        Bit 1: Sprite 0 2nd word
                        Bit 2: Sprite 1 1st word
                        Bit 3: Sprite 1 2nd word.

Page 46.

                [0m[4;29m7. Sprites.[0m

7.5 Activating Sprites With The DMA

  Once the sprite data has been copied into chip ram, pointers must be set to
where it is:
            Sprite 0: $120,$122  Sprite 1: $124,$126
            Sprite 2: $128,$12A  Sprite 3: $12C,$12E
            Sprite 4: $130,$132  Sprite 5: $134,$136
            Sprite 6: $138,$13A  Sprite 7: $13C,$13E

The first of these registers conatins the upper 3 bits of the 19-bit pointer.
The lower 16 are in the other register.
  ALL the pointers must be set before enabling the DMA (bit 5 of DMACON) and
if some sprites are not needed, their pointers must point to words containing
sprite data terminators i.e. 0,0.
  As the DMA reads the sprite data, the pointers move down the list
accordingly, so they have to be reset once the sprite has been displayed.
This is done in the vertical blanking gap with a copperlist:

            1. Wait for start of vertical gap.
            2. Set sprite pointers (just like re-setting bitplane pointers.)
            3. End copperlist.

  This will ensure that the pointers are reset for every frame.
  Once displayed, the sprite can be moved on screen by altering the positions
in the control words. This must be done in the vertical blanking gap also,
AFTER the pointers are re-set.

7.6 Collisions

 The screen area where the sprite moves about is called the playfield or
background. Moving sprites usually collide with other sprites or background
segments, and this is signalled in the Collision Control register CLXDAT($00E)
.

Bit 0: Collision between odd and even playfields (made up of odd and even
bitplanes.)
Bit 1: Odd bitplanes and sprite 0 (or sprite 1)
Bit 2: Odd bitplanes and sprite 2 (or 3)
Bits 3-4: like bit1, but for the other sprite pairs.
Bits 5-8: like bits 1-4 but for EVEN bitplanes.
Bit 9: Collision between sprites (0 or 1) and (2 or 3).
Bit 10: Collision between 0,1 and 4,5
Bits 11-14: Similarly, collision between 0/1,6/7;
2/3, 4/5;  2/3,6/7;  4/5,6/7.
Bit 15: Not used.


Page 47.

                [0m[4;29m8. THE BLITTER[0m


                8.1  Blitter function                      48

                8.2  Blitter Windows                       48

                8.3  Blitter Copying                       48

                8.4  Miniterms                             49

                8.5  Blitter Example                       50


Page 48.

                [0m[4;29m8. The Blitter.[0m

8.1 Blitter Function

  The blitter is a special device for copying memory blocks from one area to
another, hence the name "BLock Image TransferER."
  This is useful when displaying graphics, as screen data can be held in
memory, and the blitter used to copy this into bitplane raam so that it is
instantly displayed on screen. The blitter is very fast, handling up to
65535 words in one operation.


8.2 Blitter Window

  The blitter operates on a memory area which must be defined. (This
defining should come last in setting up blitter parameters, since it also
starts the operation.)
  The size of the blitter window is the size of the block to be transfered,
and is held in BLTSIZE($058).
Bits 0-5 Contain the WIDTH as 0-64 words, ie 0-1024 pixels.
Bits 6-15 Contain the HEIGHT in words (0-1024 WORDS.)
NB: Maximum values of 63 and 1023 are available with the above number of bits,
but setting the values to 0 gives 64 and 1024.


8.3 Blitter Copying

  The blitter copies memory blocks as defined above from up to 3 source areas
and into one destination area. The sources (A,B,C) can be combined in many
ways before being sent to the destination area (D).
  Considering the destination area, the blitter sees it as a continuous area
of data, and will display it in a line unless MODULO values are specified.
These values tell the blitter to display the lines of the destination area
under each other, not side by side. The modulo value is specified in bytes:

MODULO = (20 words - source width in words )*2
  The source starting address must also be specified as:
bitplane address+screen position.

An example explains all this:

  One data area of 2 words wide by 4 words high (filled with 1's) will give
a graphic block of 32*4 pixels.
  This makes BLTSIZE=(4*64)+2 = 258($102).


Page 49.

                [0m[4;29m8. The Blitter.[0m

This is to be displayed as a 32*4 Block not a 128 pixel line, so the modulo
value=20 minus word width= 20-2 = 18 words. This must be specified as 36 bytes
in the destination MODULO register.

  The starting address of the graphic is the same as the bitplane starting
address, ie it is displayed in the upper left hand corner.

  The registers can be found at:

Destination Starting Address: $054 upper 3 bits, $056 lower 16 bits.

Source A-Starting Address: $050 upper 3 bits, $052 lower 16 bits.
(Similarly, areas B and C have addresses $04C, $04E ; $048, $04A.)

Modulo Registers    $066 - Destination.
                    $064 - Source A, $062 Source B, $060 Source C.
(The Source Modulo registers allow areas within a larger source area.)


8.4 Miniterms

  A miniterm defines the way in which the source areas are combined into the
destination area.
  The most simple miniterm is the Memory Transfer miniterm (A=D), and means a
direct copy of source area A to the destination area. The actual miniterm
must also take the other sources into account, and for this operation, they
have to be specified as (B OR inverted B.) This effectively sets them to 1,
and so A=D becomes the Boolean expression:

                    A * (B+b) * (C+c) = D.
(b,c mean inverted B,C. ie 0 becomes 1, and 1 becomes 0.)
As a fact, (B+b) ALWAYS=1, so the expression is A*1*1=D, or A=D.

  To tell the blitter to do this particular miniterm, BLTCON0($040) is used.
The lower seven bits of this register specify the six effective source
areas: A,B,C,a,b,c, in the following way:

                  Bit 0: abc      Bit 1: abC       Bit 2: aBc
                  Bit 3: aBC      Bit 4: Abc       Bit 5: AbC
                  Bit 6: ABc      Bit 7: ABC.

Thus for A=D [ie A*(B+b)*(C+c)=D] bits 7,6,5,4, have to be set, giving ABC,
ABc,AbC,Abc, ie AAAA, BBbb, CCcc. The latter 2 cancel out, leaving A=D.


Page 50.

                [0m[4;29m8. The Blitter.[0m

This very complicated procedure is tedious, so the following summaries the
most commonly used miniterms:

A=D (Memory transfer)                  Byte=%11110000 = $F0
a=D (inverted memory transfer)         Byte=%00001111 = $0F
A+B=D (Image mapping)                  Byte=%11111100 = $FC
A+B+C=D (Double image mapping)         Byte=%11111110 = $FE
(A*B)=D (Cross image result)           Byte=%11000000 = $C0

The A+B=D miniterm allows data A to be combined with existing screen data B
and put back to screen as D. This will overlay graphical elements onto a
background screen without wiping out the background as A=D does.
So, just select the operation and write the byte into the lower 8 bits of
BLTCON0. The bits (8-15) are for more blitter functions:
  Bits 8,9,10,11 enable DMA channels for D,C,B,A areas.
  Bits 12-15 contain a SHIFT value (0-15) for source A.
  This shift value operates on the data word coming in through source A. If
the value is zero, A passes through unchanged. If the value is 1, the data
bits gets shifted one bit to the right. The bit shifted off the right gets
putonto the next word, which means all source A words get moved to the right.
  Shift values of 0-15 can be used so that data can be displayed on more
than just word boundaries of the screen, ie on pixels 0,16,32,48... ie a
value of 6 can enable the words to start at pixel 6, not just pixel 0 or 16.

Another blitter register BLTCON1($042) contains similar shift values for
source B in bits 12-15.


8.5 Blitter Example

  The following is a simple routine for copying a graphical block onto the
screen.
       Close blitter DMA channel.
       Set BLTCON0 and BLTCON1.
       SET Pointers and Modulo values.
       Get blitter control by the `Ownblitter' system call.
       Set blitter window (starts blitter operation).
       Open Blitter DMA.

The program is the same as for the Bitplanes, up to and including the 
*****  SET DIWSTART section.


Page 51.

                [0m[4;29m8. Blitter.[0m

Then insert:

  MOVE.W #$09F0, $40(A5)                 ;*SETS MINITERMS AND DMA A,D
  MOVE.W #$0000, $42(A5)                 ;NO SHIFT VALUES, BASIC BLITTER.
  MOVE.L #GRAPHIC.START, $50(A5)         ;POINTER TO SOURCE DATA
  MOVE.L BIT.START, $54(A5)              ;DEST. DATA (=BITPLANE AREA)

  MOVE.L #NAME, A1                       ;OPEN GRAPHICS LIB.
  CLR.L D0
  JSR -552(A6)                           ;GET GRAPHICS BASE
  MOVE.L D0, A6                          ;INTO A6
  JSR -456(A6)                           ;"OWNBLITTER"

  MOVE.W #38, $66(A5)
  MOVE.W #1025, $58(A5)                  ;SETS BLTSIZE TO 16 * 1 WORDS

*****  RE-ENABLE DMA  *****

  MOVE.W #$83C0, $96(A5)

*****  WAIT & RESTORE  *****

  PAUSE BTST #6, $BFE001                 ;PAUSE FOR MOUSE BUTTON
  BNE.S PAUSE

  WAIT BTST #14, $002(A5)                ;WAIT UNTIL BLITTER IS FINISHED
  BNE.S WAIT

  JSR -462(A6)                           ;"DISOWNBLITTER"
  MOVE.L $4, A6                          ;RESTORE EXEC POINTER


Now remove the old *RE-ENABLE DMA up to and including the old pause routine.
The program should continue with:

  MOVE.L #NAME, A1
  CLR.L D0
  etc...

The folowing data should be added to the end:

  GRAPHIC.START:
  DC.W $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF
  DC.W $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF


Page 53.

                [0m[4;29m9. AUDIO OUTPUT[0m


                9.1  Amiga Audio                           54

                9.2  The Procedure For the Output of
                     Sound                                 54

                9.3  Audio Registers                       55

                9.4  Simple Sine Wave Example              56

                9.5  Modulation                            57

                9.6  Music                                 57



Page 54.

                [0m[4;29m9. Audio Output.[0m

  The Amiga has incredible stereo capabilities over 4 channels, and to make
the best use of them it is necessary to understand how the Amiga considers
sound.
  Computers only work with fixed numbers, not analogue sound waves, so these
have to be represented digitally by sampling them. A sound waveform is
sampled at intervals and the values at these intervals are stored as sound
levels.
For example, a sine wave can be represented by the numbers:



          30
       20    20
    10          10
  0[m[4;29m0                0                     0[0m
                     -10             -10
                         -20     -20
                             -30


  This means the Amiga can now work with a numerical representation of
analogue sound. It can effectively read the stored values and play them back,
recreating the sound.
  This becomes easier to understand with an example, but first there are a
few technicslities to go through.
  The Amiga uses 8-Bit samples, giving a range of 128 to -127 sound levels,
whereas high quality CD players use 16 bits. Also sampling sounds takes up
lots of memory. Sampling at the normal 25KHz, for a one second sample uses
25K of ram!


9.2 The Procedure for the Output of Sound

  This done as follows:
           1. Construct waveform data in chip ram.
           2. Disable Audio DMA.
           3. Set Audio pointers
           4. Set the data length registers.
           5. Set the Volume and Frequency.
           6. Enable the DMA.

Page 55.

                [0m[4;29m9. Audio Output[0m

9.3 Audio Registers

  Each channel has pointers to the data it is using:
        Channel 0: $0A0, $0A2, AUD0PTR (Hi 3, Low 16 bits, as before.)
        Channel 1: $0B0, $0B2, AUD1PTR
        Channel 2: $0C0, $0C2, AUD2PTR
        Channel 3: $0D0, $0D2, AUD3PTR

  The number of words in the data must also be specified:
        $0A4  AUD0LEN   (length of data in words.)
        $0B4  AUD1LEN
        $0C4  AUD2LEN
        $0D4  AUD4LEN

  The volume is also set from 0-64 for each channel:
        $0A8  AUD0VOL
        $0B8  AUD1VOL
        $0C8  AUD2VOL
        $0D8  AUD3VOL

  The sound frequency is set in the sample period registers:
        $0A6  AUD0PER
        $0B6  AUD1PER
        $0C6  AUD2PER
        $OD6  AUD3PER

  To calculate the values for the AUDPER registers, use the formula:


VALUE = [0m[4;29m                      1                    [0m
        NO. samples in data*frequency*2.79365*10\-7

(Round to the nearest integer.)

E.g for 32 samples, at a note frequency of 220Hz, the value is:
1/(32*220*2.79366*10\-7) = 508.

(There are limits for AUDPER registers of 124-65535.)


Page 56.

                [0m[4;29m9. Audio Output.[0m

9.4 Simple Sine Wave Example

*****  REQUEST AUDIO DATA CHIP RAM  *****

  MOVE.L $4, A6
  MOVE.L #SIZE, D0
  MOVEQ #2, D1
  JSR -198(A6)
  MOVE.L D0, ADDRESS

*****  COPY AUDIO DATA  *****

  LEA START, A0
  LEA ADDRESS, A1
  MOVEQ #SIZE-1, D0                        ;LOOP COUNTER
LOOP MOVE.B (A0),(A1)+
  DBF D0, LOOP

*****  DISABLE ALL AUDIO CHANNELS  *****

  LEA $DFF000, A5
  MOVE.W #$000F, $96(A5)

*****  SET POINTERS  *****

  MOVE.L #ADDRESS, $0A0(A5)

*****  SET LENGTH, VOLUME AND FREQUENCY  *****

  MOVE.L #(SIZE/2), $A4(A5)
  MOVE.W #64, $A8(A5)
  MOVE.W #10007, $A6(A5)

*****  ENABLE DMA (AUDIO CHANNEL 0)  *****

  MOVE.W #$8201, $96(A5)

WAIT BTST#6, $BFE001
  BNE.S WAIT

*****  DISABLE DMA CHANNEL 0 (STOPS THE SOUND)  *****

  MOVE.W #1, $96(A5)
  RTS

*****  DATA  *****

  ADDRESS DC.L 0
  START:
  DC.B 0,30,60,90,120,90,60,30,0,-30,-60,-90,-120,-90,-60,-30
  AUD.END:
  SIZE=AUD.END-START


(This data list can be changed for a list of sampled bytes.)


Page 57.

                [0m[4;29m9. Audio Output.[0m

  The audio volume and frequency registers can be changed within a program or
one of the other audio channels can be used to change the volume and/or
frequency. For example, the sinewave in section 9.4 was of a fixed volume,
but this can be changed so that it goes quiet and then loud at a rate
specified by one of the other channels. The frequency can be modulated in a
similar way.
  Each channel can only modulate the one below it, and to activate modulation
bits in the ADKCON=Audio and DisK CONtrol register, $9E write, $10 read.)

Bit 0: Channel 0 modulates VOLUME of channel 1.
Bit 1: Channel 1 modulates VOLUME of channel 2.
Bit 2: Channel 2 modulates VOLUME of channel 3.
Bit 3: Channel 3 doesn't modulate a channel.
Bit 4: Channel 0 modulates FREQUENCY of channel 1.
Bit 5: Channel 1 modulates FREQUENCY of channel 2.
Bit 6: Channel 2 modulates FREQUENCY of channel 3.
Bit 7: Channel 3 doesn't modulate a channel.
Bits 8-14: Used by DISK controller.
Bit 15: SET/CLEAR bit as in DMACON.


9.6 Music

  A succession of notes is easily accomplished through a channel by
changing the frequency in the AUDPER register. The list of frequencies to be
changed to can be held in chip-ram as a series of words, pointed to by an
address register and then a routine for calculating the period from them can
be used. This value is put into the AUDPER register and a specified wait time
for the note length is carried out.

It is summarised thus:
             1. Load an address register with base address of the frequency
                list in the chip ram.
             2. Calculate period from the register that the address register
                points to.
             3. Put this into a data register.
             4. Jump to a subroutine which puts the value into AUDPER and
                waits for the note duration.
             5. Increment address register and repeat.


Page 59.

                [0m[4;29m10. MOUSE JOYSTICK AND INTERRUPTS[0m


                10.1  The Mouse                            61

                10.2  Mouse Buttons                        61

                10.3  Joystick                             61

                10.4  Reading Joysticks in-game            62

                10.5  Interrupts                           62



Page 61.

                [0m[4;29m10. Mouse, Joystick and Interrupts[0m

10.1 The Mouse

  The Amiga mouse is a useful input device, and can be used in games to great
effect. Inside the mouse is a rubber ball which moves against two rollers, in
x and y directions. These rollers are wired to counters in the hardware and
these can be read at:

       Port 1: JOYDAT1($00A)      Port 2: JOYDAT2($00C)
           Bits 0-7: Mouse X position (0-255)
           Bits 8-15: Mouse Y position (0-255).

  Note that each of the counters go from 0-255 corresponding to a mouse
movement of 4cm. The mouse pointer is a hardware sprite and the operating
system updates the pointer position in the vertical blanking gap by reading
the counters. To read the mouse position, the sprite registers SPRPOS and
SPRCTL must be used, since these contain the first and second control words
of each sprite. The DMA controller usually writes to these registers, but
they can be changed by the processor (Only HSTART and AT bits must be
specified.)

           SPRPOS0=$140, SPRCTL0=$142
           SPRPOS1=$148, SPRCTL1=$14A
           SPRPOS2=$150, SPRCTL2=$152
           etc...
           SPRPOS7=$178, SPRCTL7=$17A

This allows the mouse pointer to be set on screen, and its position
monitored by setting up customised X,Y position registers which are altered
by a program which reads the sprite pointers. This now enables graphics to
be put at screen locations and the mouse can be used to click over them. A
coordinate match is all that is needed over the range that the graphic covers.
In a full game, the mouse-read routine should also return information about
the speed and direction of the mouse.


10.2  Mouse Buttons

  The left when pressed set bit 6 of $BFE001 as used in the previous programs.
The right button can be read as bit 10 of $DFF016.


10.3  Joystick.

  Probably of more interest to the games programmer is the joystick port,
and this uses the same JOYDAT registers, with only bits 0,1,8,9:
               Right:  Bit 1=1, Bit 0=0
               Left:   Bit 9=1, Bit 8=0
               Up:     Bit 9=1, Bit 8=1
               Down:   Bit 1=1, Bit 0=1.



Page 62.

                [4;29m10. Mouse, Joystick and Interrupts[0m

E.g:
                TEST: BTST #1, $DFF00C
                 BNE DOWN??
                BTST #9, $DDF00C
                 BNE UP??
                 BRA TEST
                DOWN??:
                 BTST #0, $DFF00C
                 BNE DOWN
                 BRA RIGHT
                UP??:
                 BTST #8, $DFF00C
                 BNE UP
                 BRA LEFT

The fire button can be read as bit 6 of $BFE001, and as bit 7 if the joystick
is on port 2 (Normal joystick port.)


10.4 Reading Joystick in-game

  The main loop of a game should consist of a joystick reading routine which
updates the pointers of the main sprite in the vertical blanking gap. Once
this has been done, a second routine can be used to update the whole screen in
one go, moving aliens, bombs etc. to their new positions. A check is then made
to see if any collisions have occured, if not, the main loop is re-executed.
  This procedure is explained fully in the Game Writing section.


10.5 Interrupts

  The processor sees all devices connected to it as memory areas, and these
devices talk to the processor by means of a series of wires called a BUS.
Each device continues operating independantly until the processor ask it what
it has been doing, and asks for its buffer to be sent down the bus. This is
called `polling' the device. However, if the device can't wait to be asked, it
can INTERRUPT the processor and request a service.
  To prevent two or more devices interrupting at once, each is given a 
priority level 0-6 to tell who is first.
  When interrupted, the processor stops what it is doing and processes an
interrupt service routine, found from a vector location.  This is a highly
advanced area and is only outlined here.  This is a highly advanced area and
is only outlined here. The more basic techniques of game routines should be
understood first before attempting to use interrupts.


Page 63.

                [4;29mSECTION III[0m:  Game Writing.



                11. Programming Games

                    11.1 Where to start                    64

                    11.2 Making a Plan                     64

                    11.3 Utilities                         65


                12. Game Structure

                    12.1 The Idea                          67

                    12.2 Progressing from the Idea         67

                    12.3 Animation and Movement            67

                    12.4 Final Touches                     68


                13. Program Structure and Marketing

                    13.1 Planning a Program                69

                    13.2 Example Game Structure            69

                    13.3 Marketing the Game                71




Page 64.

                [4;29m11. Programming Games.[0m


  11.1 Where to start

  Before you start thinking about writing a game, you must have a good basic
understanding of Assembly Language. Other languages such as BASIC and C are
no where near as fast as machine code from assembly language, and speed is the
key to game writing.
  You must appreciate that assembly language is not all that hard once you
understand what it does. Really, it is only a tool for putting things into
registers, and seeing what this does to other registers. It is understanding
the registers that is the hard part.
  If you are really serious about writing game routines, you must get a good
assembler package such as Devpac 2, Assempro, or Argasm. (The programs in this
book were written using Devpac2).
  Next, you must understand that games aren't written all in one go:-routines
are built up into modules and these are put into higher modules which make up
the game. For example, a routine to put a shape on-screen was given in the
Blitter section, and this could be refined to be the shape of a coloured
game character. The joystick read routine could then be added to move the man
around the screen. Further refinements could be to animate the man, and have
obstacles for him to avoid etc.
  The point is this:- ALWAYS START SMALL AND BUILD ON THAT.
Work on routines which do certain things and get them going first.
Examples include:
            1. Moving a shape across the screen using the Blitter
            2. Playing a note
            3. Reading in notes from memory, and playing them
            4. Animating a fixed object (change data pointers)
            5. Cycling colours on screen (change colour registers)
            6. Moving a sprite round the screen with the joystick
            7. Testing for sprite collisions
            8. Explode things
            etc.



11.2 Making a Plan


  All computer programs must start with a plan.
For example, in the real world, building a wall could have a plan:

            1. Clear Site
            2. Put in Foundations
            3. Lay Bricks Until High Enough.



Page 65.

                [4;29m11. Programming Games.[0m


These three steps outline the entire procedure, but each step has to be 
refined in more detail e.g:
Put in Foundations: dig hole, pour in concrete, wait until set.
Each of these sub-tasks must also be refined.


  This method of refinement must continue until the tasks become trivial.
Each task is then programmed and tested and included in the main section of
the program if it works. The method saves hours of time bug-hunting and make
programming much easier.
  Once a suitable plan is established, an assemble/run/edit loop is undertook
to develop the program:
   1. Write program    2. Type it in with an editor
   3. Assemble it      4. Run it
   5. If it dosen't work, change it and go back to 3.


11.3 Utilities

  Much of the time spent on game development is spent on writing support
routines of utilities for it. These consist of such programs as those which
convert DPaint brushes (IFF) into a suitable chip-ram format for the blitter
to get at etc. Public Domain libraries have many such programs available, but
the serious game programmers will write their own utilities.
  Before writing a game, a good sprite/BOB(Blitter Object) development utility
should be written. Here are some guidelines:
1. Write a program to display a BOB on screen.
2. Write a mouse routine which reads the mouse position and checks for clicks
   over certain screen positions.
3. Combine the two so that when one click is made at a certain position, the
   x position of the bob moves +1.
4. Add to this so that the y position can be changed, too.
5. Write a routine which reads a register and puts the decimal value on screen
6. Add this to the bob sizing routine so that the pixel coordinate values are
   displayed as they are changed.


  This routine will move a bob around the screen and displays its coordinates.
It can be implemented into a larger routine which shows a big 16x16 grid and
blocks can be thus placed into the grid. This could be modified to change the
colour of the blocks in the sprite grid, and the routine must then be able to
save the block data to disk, in your own custom format.
  If all this sounds like a lot of hard work - it is.
So, you may be tempted to opt for a commercially available bob/sprite editor.
However, if you [3mcan[0m write such a routine, you have the ability to
write a winning game, and software houses will be very interested in a games
programmer who can write his own utilities.



Page 66.

                [4;29m12. Game Structure[0m


12.1 The Idea


  Thinking of a new idea for a game is arguably harder than writing it.
This is why most games are just variations on a theme, e.g. shoot-em-up,
platfrom-type or 3D filled vector.
  Many Amiga games are not as lasting or addictive as some of the earliest
computer games, but they sell due to the graphics and sound capabilities, and
this is what many programmers dwell on rather than concentrating on the game-
play. A really good game must start with the gameplay idea first.
  Once you have a game idea, it can be quite hard to get it into a program, so
what you have to do before you even think about programming is to develop the
idea mentally. Close your eyes and imagine playing the game - don't imagine 
the graphical details just yet, but get the feel of it, and then write down
and sketch what you saw in your head. Draw lots of pictures and write down
any thoughts you had. Write down everything you can think of, and then leave
it. Come back to it a few days later, and you will be able to see flaws
mentally palyed the game from start to finish.
If you can't do this, you have no chance of writing it.



12.2 Progressing from the Idea


  Next, you must start to think about details, starting with the main 
character. If it's a spaceship, draw lots of little spaceships on paper until
you see one you like, and then use a painting package (e.g.DPaint) and draw it
on the screen. It will always look different on the screen, so keep altering
it until you like it. Do the same for the aliens.
  Now comes the hard bit. You must convert the screen picture into a Blitter
Object and write a program which puts it on the screen independantly of the
paint package. read it into chip-ram and display it as outlined in the blitter
section. If you can get this far, you're almost there!


12.3 Animation and Movement

  The program should be modified so that the main character is under joystick
control. This is done by setting the x and y coordinates for the character and
displaying it at them. The coordinates are changed by the joystick, and the
character is re-displayed there. It is a little more complicated than this,
because the old character has to be removed before the new one is displayed.




Page 68.

                [4;29m12. Game Structure[0m


  At the top of the vertical blanking gap, the bitplane data where the
character data was copied should be blanked with an exact copy of the 
character, and then the data should be put back before the beam comes to 
display it. A more complicated from of double-buffering is used if there is a
background under the bob. Alternatively, sprites can be used - all 8 of them
bolted together to give a larger multi-coloured main character, and bobs used
for the aliens.



12.4 Final Touches

  The background also has to be copied into bitplane chip-ram by the blitter,
and the aliens have to have pre-defined attack waves. These are just lists of
DC.L ...... directives, which specify movement direction and size. Conditional
statements could be built into this to give the aliens some sort of 
intelligence e.g. "If the player is within 10 pixels, drop a bomb on him."


  Collisions have also to be detected for, and sound effects added. The game is
now almost ready. Remember, there is an immense amount of hard work which goes
into game development (hence the high prices) so don't expect miracles over-
night.


Start small and progress. Gain programming experience first, dabble with
routines, don't be afraid to change things and don't be put off by the effort
involved. It pays off in the end.




Page 69.

                [4;29m13. Program Structure and Marketing[m



13.1 Planning a program


  Once you have the game idea and have a number of routines to your name, you
can then start thinking of putting it all together.
  Don't just sit down and start typing in code, but write down on paper the
structure of your program. Refer to the plans given in sections 5.5 and 6.7 to
get the idea.



13.2 Example Game Structure

  The following is an example for one of the simplest games: space invaders
(with one alien). It outlines only the bare bones, but shows the principles
upon which an entire game can be built:


[4;29m1. Initialise Program.[0m
       Request chip-ram for copper, bitplane, audio and sprite data.
       Construct copperlist which resets sprite and bitplane pointers.
       Copy the data into chip-ram.
       Start copperlist and put colours into registers.
       Set screen windows etc.
       Initialise variables (e.g. "bombingflag"=false, means no bombs).


[4;29m2. Main Loop of Program[0m
       Set "lives" register to 3
       game: JSR move.alien
             JSR move.base
             JSR bomb
             JSR bullet
             JSR update.screen
             JSR hit.alien?
             JSR hit.base?
             BRA game


[4;29m3. Other Subroutines[0m

       move.alien: increase alien x vector
       If its actual position is at the end of the screen, move it
       somewhere else.
       (This dosen't move the alien, only changes its vectors, ie how far
                      from its last position it was.) 

       RTS



Page 70.

                [4;29m13. Program Structure and Marketing[0m


move.base       ;read joystick. If centered, RTS. change base vector 
                 accordingly then RTS.

bomb            ;If bombflag=true (ie there is a bomb on screen).
                 increase its vectors and RTS.
                 If bombflag=false, then there is no bomb on screen, so
                 generate a random number (use VPOS register) and randomly
                 select to drop a bomb or not.
                 If the decision is not to bomb, RTS.
                 Otherwise, set bombflag=true, and set bomb just under the
                 alien, then RTS.

bullet           ;If bulletflag=true then increase bullet vectors up the
                  screen and RTS.
                  Else, read joystick button. If not pressed, RTS.
                  Otherwise, set bulletflag=true and position bullet from base

update.screen    ;Wait for vertical blanking gap and add all vectors to 
                  appropriate coordinates.
                  Alter sprite data list and bob pointers based on these new
                  coordinates. RTS.

hit.alien?       ;If bullet coords=alien coords, then JSR explode.
                  If not, are the bulet coords off screen? If so, remove the
                  bullet and set bulletflag=false, so that another can be 
                  fired. RTS.

hit.base?        ;If bomb coords=base coords, then JSR explode.base. If the
                  bomb is off the screen, remove it and set bombflag=false.

explode          ;Change alien data pointers to point to "exploding alien"
                  data. Then remove the alien and increase the score.
                  Display another alien somewhere else.

explode.base     ;Similar to alien, but decrease lives by one. If no lives
                  are left, and the game.



Page 71.

                [4;29m13. Program Structure and Marketing[0m


13.3 Marketing the Game

  After many months of perseverance and hard work, you will probably have a
game which does something, if not much.
  Don't be put off by this, because not all software houses expect perfection
from a novice freelance programmer. Now, you should approach them with a 
sample of your talents - graphics and sound routines etc, and send them your
test `game'.  You should expect some sort of reply, so they now know what to
expect from you.


  Now, you can just approach them with a detailed idea for a new game, and if
you intend to code it yourself, and they feel that you can, they may make a 
small initial payment. However, nothing else will be paid until the game is
complete and play-tested, so make sure you are capable first!
  Most established freelance games programmers do it this way, as the software
houses can trust them to come up with the goods. If you don't feel capable,
many companies are very interested in new ideas and concepts which have
potential. You have to be careful to only appoach reputable companies in this
way, for obvious reasons.


  Alternatively, you can write an entire game first and then send it off to
lots of companies to see if they are interested. If it is not quite up to
scratch, they may even help you to polish it up to a reasonable standard.


  Search through the computer adverts in magazines to see which companies are
looking for games. Write to them, and send them a disk with samples of your
work. Give them a few game ideas too. Even if your programming is not too
good, there is a large scope for graphic artists and sound programmers, so you
may wish to specialise in these areas. You can even answer the `penpals'
section in the Amiga magazines for programming help, and you may even be able
to work on a team program to combine your talents into a good game.


You must appreciate, though, that the software industry is not dripping with
money - and unless you can come up with a brand new concept which everyone
goes for, you shouldn't give up your day job.


  Don't expect to become a millionaire overnight - it takes years for even the
best programmers to earn the big money.
  However, if you get it right, game-writing IS big business, but many don't
even know where to start.
            This book has shown you how.
            the rest is up to you!









 -----------------------------------------------------------------------------
 ........... DOX WERE 100% POWER-TYPED BY SLIDER OF SOLO PRODUCTIONS .........
 -----------------------------------------------------------------------------
 ...........  IF YA MANAGED TO SPOT ANY MISTAKES, CONTACT ME!!!!!!! ..........
 -----------------------------------------------------------------------------
              I MUST ADMIT THIS BOOK IS A LOAD OF SHIT!!!   
                   SO DON'T GO OUT & BUY THE BOOK!!!!   ...SIGNED SLIDER
                                                                        \
 -----------------------------------------------------------------------------




