Amiga® Hardware Reference Manual: 2 Coprocessor Hardware

In this chapter, you will learn how to use the Amiga's graphics
coprocessor (or Copper) and its simple instruction set to organize
mid-screen register value modifications and pointer register set-up during
the  vertical blanking  interval. The chapter shows how to organize Copper
instructions into Copper lists, how to use Copper lists in interlaced
mode, and how to use the Copper with the blitter. The Copper is discussed
in this chapter in a general fashion. The chapters that deal with
playfields, sprites, audio, and the blitter contain more specific
suggestions for using the Copper.

About the Copper              Putting Together a Copper Instruction List
What is a Copper Instruction? Starting and Stopping the Copper
The MOVE Instruction          Advanced Topics
The WAIT Instruction          Summary of Copper Instructions
Using the Copper Registers

2 Coprocessor Hardware / About the Copper

The Copper is a general purpose coprocessor that resides in one of the
Amiga's custom chips. It retrieves its instructions via direct memory
access (DMA). The Copper can control nearly the entire graphics system,
freeing the 680x0 to execute program logic; it can also directly affect
the contents of most of the chip control registers. It is a very powerful
tool for directing mid-screen modifications in graphics displays and for
directing the register changes that must occur during the
 vertical blanking  periods.  Among other things, it can control register
updates, reposition sprites, change the color palette, update the audio
channels, and control the blitter.

One of the features of the Copper is its ability to  WAIT  for a specific
video beam position, then  MOVE  data into a system register. During the
 WAIT  period, the Copper examines the contents of the video beam position
counter directly. This means that while the Copper is waiting for the beam
to reach a specific position, it does not use the memory bus at all.
Therefore, the bus is freed for use by the other DMA channels or by the

When the  WAIT  condition has been satisfied, the Copper steals memory
cycles from either the blitter or the 680x0 to move the specified data
into the selected special-purpose register.

The Copper is a two-cycle processor that requests the bus only during
odd-numbered memory cycles. This prevents collision with audio, disk,
refresh, sprites, and most low resolution display DMA access, all of which
use only the even-numbered memory cycles. The Copper, therefore, needs
priority over only the 680x0 and the blitter (the DMA channel that handles
animation, line drawing, and polygon filling).

As with all the other DMA channels in the Amiga system, the Copper can
retrieve its instructions only from the chip RAM area of system memory.

2 Coprocessor Hardware / What is a Copper Instruction?

As a coprocessor, the Copper adds its own instruction set to the
instructions already provided by the 680x0 CPU. The Copper has only three
instructions, but you can do a lot with them:

*   WAIT  for aspecific screen position specified as x and y coordinates.

*   MOVE  animmediate data value into one of the special-purpose

*   SKIP . the next instruction if the video beam has already reached
   a specified screen position.

All Copper instructions consist of two 16-bit words in sequential memory
locations. Each time the Copper fetches an instruction, it fetches both

The  MOVE  and  SKIP . instructions require two memory cycles and two
instruction words each. Because only the odd memory cycles are requested by
the Copper, four memory cycle times are required per instruction.  The
 WAIT  instruction requires three memory cycles and six memory cycle
times; it takes one extra memory cycle to wake up.

Although the Copper can directly affect only machine registers, it can also
affect memory indirectly by setting up a blitter operation.  More
information about how to use the Copper in controlling the blitter can be
found in the sections called  Control Register  and
 Using the Copper with the Blitter .

The  WAIT  and  MOVE  instructions are described below. The  SKIP 
instruction is described in the "Advanced Topics" section.

2 Coprocessor Hardware / The MOVE Instruction

The MOVE instruction transfers data from RAM to a register destination.
The transferred data is contained in the second word of the MOVE
instruction; the first word contains the address of the destination
register. This procedure is shown in detail in the section called
 Summary of Copper Instructions .

     Bit 0           Always set to 0.

     Bits 8 - 1      Register destination address (DA8-1).

     Bits 15 - 9     Not used, but should be set to 0.

     Bits 15 - 0     16 bits of data to be transferred (moved)
                     to the register destination.

The Copper can store data into the following registers:

   *  Any register whose address is $20 or above.  (Hexadecimal numbers
      are distinguished from decimal numbers by the $ prefix.)

   *  Any register whose address is between $10 and $20 if the Copper
      danger bit is a 1. The Copper danger bit is in the Copper's control
      register,  COPCON , which is described in the "Control Register"

   *  The Copper cannot write into any register whose address is lower
      than $10.

 Appendix B  contains all of the machine register addresses.

The following example MOVE instructions set bitplane pointer 1 to $21000
and bitplane pointer 2 to $25000.  (All sample code segments are in
assembly language.)

        DC.W    $00E0,$0002     ;Move $0002 to register $0E0 (BPL1PTH)
        DC.W    $00E2,$1000     ;Move $1000 to register $0E2 (BPL1PTL)
        DC.W    $00E4,$0002     ;Move $0002 to register $0E4 (BPL2PTH)
        DC.W    $00E6,$5000     ;Move $5000 to register $0E6 (BPL2PTL)

Normally, the appropriate assembler ".i" files are included so that names,
rather than addresses, may be used for referencing hardware registers.  It
is strongly recommended that you reference all hardware addresses via their
defined names in the system include files.  This will allow you to more
easily adapt your software to take advantage of future hardware or
enhancements.  For example:

        INCLUDE "hardware/custom.i"

        DC.W    bplpt+$00,$0002 ;Move $0002 into register $0E0 (BPL1PTH)
        DC.W    bplpt+$02,$1000 ;Move $1000 into register $0E2 (BPL1PTL)
        DC.W    bplpt+$04,$0002 ;Move $0002 into register $0E4 (BPL2PTH)
        DC.W    bplpt+$06,$5000 ;Move $5000 into register $0E6 (BPL2PTL)

For use in the hardware manual examples, we have made a special include
file (see  Appendix I ) that defines all of the hardware register names
based off of the "hardware/custom.i" file.  This was done to make the
examples easier to read from a hardware point of view.  Most of the
examples in this manual are here to help explain the hardware and are, in
most cases, not useful without modification and a good deal of additional

2 Coprocessor Hardware / The WAIT Instruction

The WAIT instruction causes the Copper to wait until the video beam
counters are equal to (or greater than) the coordinates specified in the
instruction. While waiting, the Copper is off the bus and not using memory

The first instruction word contains the vertical and horizontal
coordinates of the beam position. The second word contains enable bits
that are used to form a "mask" that tells the system which bits of the
beam position to use in making the comparison.

     Bit 0           Always set to 1.

     Bits 15 - 8      Vertical beam position  (called VP).

     Bits 7 - 1       Horizontal beam position  (called HP).

     Bit 0           Always set to 0.

     Bit 15          The  blitter-finished-disable bit .  Normally, this
                     bit is a 1. (See the "Advanced Topics" section below.)

     Bits 14 - 8     Vertical position compare enable bits (called VE).

     Bits 7 - 1      Horizontal position compare enable bits (called HE).

The following example WAIT instruction waits for scan line 150 ($96) with
the horizontal position masked off.

        DC.W    $9601,$FF00     ;Wait for line 150,
                                ;   ignore horizontal counters.

The following example WAIT instruction waits for scan line 255 and
horizontal position 254. This event will never occur, so the Copper stops
until the next  vertical blanking  interval begins.

        DC.W    $FFFF,$FFFE     ;Wait for line 255,
                                ;   H = 254 (ends Copper list).

To understand why position VP=$FF HP=$FE will never occur, you must look
at the comparison operation of the Copper and the size restrictions of the
position information. Line number 255 is a valid line to wait for, in fact
it is the maximum value that will fit into this field. Since 255 is the
maximum number, the next line will wrap to zero (line 256 will appear as a
zero in the comparison.) The line number will never be greater than $FF.
The horizontal position has a maximum value of $E2.  This means that the
largest number that will ever appear in the comparison is $FFE2. When
waiting for $FFFE, the line $FF will be reached, but the horizontal
position $FE will never happen. Thus, the position will never reach $FFFE.

You may be tempted to wait for horizontal position $FE (since it will
never happen), and put a smaller number into the vertical position field.
This will not lead to the desired result. The comparison operation is
waiting for the beam position to become greater than or equal to the
entered position. If the vertical position is not $FF, then as soon as the
line number becomes higher than the entered number, the comparison will
evaluate to true and the wait will end.

The following notes on horizontal and vertical beam position apply to both
the WAIT instruction and to the  SKIP . instruction. The  SKIP  instruction
is described below in the  Advanced Topics  section.

 Horizontal Beam Position 
 Vertical Beam Position 
 The Comparison Enable Bits 

2 / The WAIT Instruction / Horizontal Beam Position

The horizontal beam position has a value of $0 to $E2. The least
significant bit is not used in the comparison, so there are 113 positions
available for Copper operations. This corresponds to 4 pixels in low
resolution and 8 pixels in high resolution. Horizontal blanking falls in
the range of $0F to $35. The standard screen (320 pixels wide) has an
unused horizontal portion of $04 to $47 (during which only the background
color is displayed).

All lines are not the same length in NTSC. Every other line is a long line
(228  color clocks , 0-$E3), with the others being 227  color clocks 
long. In PAL, they are all 227 long. The display sees all these lines as
227 1/2  color clocks  long, while the Copper sees alternating long and
short lines.

2 / The WAIT Instruction / Vertical Beam Position

The vertical beam position can be resolved to one line, with a maximum
value of 255. There are actually 262 NTSC (312 PAL) possible vertical
positions. Some minor complications can occur if you want something to
happen within these last six or seven scan lines. Because there are only
eight bits of resolution for vertical beam position (allowing 256
different positions), one of the simplest ways to handle this is shown

     Copper Instruction           Explanation
    --------------------          -----------
     WAIT  for position (0,255)   At this point, the vertical
                                  counter appears to wrap to 0
                                  because the comparison works
                                  on the least significant bits
                                  of the vertical count

     WAIT  for any horizontal       Thus the total of 256 + 6 = 262
    position with vertical        lines of video beam travel during
    position 0 through 5,         which  Copper instructions  can be
    covering the last 6 lines     executed
    of the scan before
     vertical blanking  occurs.

    Note that the vertical is like the horizontal.
    There are alternating long and short lines, there are also long and
    short fields (interlace only). In NTSC, the fields are 262, then 263
    lines and in PAL, 312, then 313 lines.  This alternation of lines and
    fields produces the standard NTSC 4 field repeating pattern:

          short field ending on short line
          long  field ending on  long line
          short field ending on  long line
          long  field ending on short line
          and back to the beginning...

One horizontal count takes one cycle of the system clock (processor is
twice this).

          NTSC- 3,579,545 Hz
          PAL - 3,546,895 Hz
          genlocked- basic clock frequency plus or minus about 2%

2 / The WAIT Instruction / The Comparison Enable Bits

Bits 14-1 are normally set to all 1s. The use of the comparison enable
bits is described later in the  Advanced Topics  section.

2 Coprocessor Hardware / Using the Copper Registers

There are several machine registers and strobe addresses dedicated to the

 Location Registers 
 Jump Address Strobes 
 Control Register 

2 / Using the Copper Registers / Location Registers

The Copper has two sets of location registers:

          COP1LCH High 3 bits of first Copper list address.
          COP1LCL Low 16 bits of first Copper list address.
          COP2LCH High 3 bits of second Copper list address.
          COP2LCL Low 16 bits of second Copper list address.

In accessing the hardware directly, you often have to write to a pair of
registers that contains the address of some data. The register with the
lower address always has a name ending in "H" and contains the most
significant data, or high 3 bits of the address. The register with the
higher address has a name ending in "L" and contains the least significant
data, or low 15 bits of the address. Therefore, you write the 18-bit
address by moving one long word to the register whose name ends in "H."
This is because when you write long words with the 680x0, the most
significant word goes in the lower addressed word.

In the case of the Copper location registers, you write the address to
COP1LCH. In the following text, for simplicity, these addresses are
referred to as COP1LC or COP2LC.

The Copper location registers contain the two indirect jump addresses used
by the Copper. The Copper fetches its instructions by using its program
counter and increments the program counter after each fetch. When a
 jump address strobe  is written, the corresponding location register is
loaded into the Copper program counter. This causes the Copper to jump to
a new location, from which its next instruction will be fetched.
Instruction fetch continues sequentially until the Copper is interrupted
by another  jump address strobe .

   About Copper restart.
   At the start of each  vertical blanking  interval, COP1LC is
   automatically used to start the program counter.  That is, no matter
   what the Copper is doing, when the end of  vertical blanking  occurs,
   the Copper is automatically forced to restart its operations at the
   address contained in COP1LC.

2 / Using the Copper Registers / Jump Strobe Address

When you write to a Copper strobe address, the Copper reloads its program
counter from the corresponding  location register . The Copper can write
its own location registers and strobe addresses to perform programmed
jumps. For instance, you might  MOVE  an indirect address into the
 COP2LC  location register. Then, any  MOVE  instruction that addresses
COPJMP2 strobes this indirect address into the program counter.

There are two jump strobe addresses:

     COPJMP1/Restart Copper from address contained in  COP1LC .
     COPJMP2/Restart Copper from address contained in  COP2LC .

2 / Using the Copper Registers / Control Register

The Copper can access some special-purpose registers all of the time, some
registers only when a special control bit is set to a 1, and some registers
not at all.  The registers that the Copper can always affect are numbered
$80 through $FF inclusive.  (See  Appendix B  for a list of registers in
address order.) Those it cannot affect at all are numbered $00 to $3E
inclusive.  The Copper control register is within this group ($00 to $3E).
The rest of the registers, from $40 to $7E, are protected by a bit in the
Copper control register.

In the Copper control register, called COPCON, only bit 1 is currently in
use by the system. This bit, called CDANG (for Copper Danger Bit) protects
all registers numbered between $40 and $7E inclusive. This range includes
the blitter control registers. When CDANG is 0, these registers cannot be
written by the Copper. When CDANG is 1, these registers can be written by
the Copper. Preventing the Copper from accessing the blitter control
registers prevents a runaway Copper (caused by a poorly formed instruction
list) from accidentally affecting system memory.

   Keep in mind that the CDANG bit is cleared after a reset.

2 Coprocessor Hardware / Putting Together a Copper Instruction List

The Copper instruction list contains all the register resetting done
during the  vertical blanking  interval and the register modifications
necessary for making mid-screen alterations. As you are planning what will
happen during each display field, you may find it easier to think of each
aspect of the display as a separate subsystem, such as playfields,
sprites, audio, interrupts, and so on. Then you can build a separate list
of things that must be done for each subsystem individually at each video
beam position.

When you have created all these intermediate lists of things to be done,
you must merge them together into a single instruction list to be executed
by the Copper once for each display frame. The alternative is to create
this all-inclusive list directly, without the intermediate steps.

For example, the  bitplane pointers  used in playfield displays and the
 sprite pointers  must be rewritten during the vertical blanking  interval
so the data will be properly retrieved when the screen display starts
again. This can be done with a Copper instruction list that does the

    WAIT  until first line of the display
    MOVE  data to bitplane pointer 1
    MOVE  data to bitplane pointer 2
    MOVE  data to sprite pointer 1, and so on.

As another example, the  sprite DMA channels  that create movable objects
can be reused multiple times during the same display field. You can change
the size and shape of the reuses of a sprite; however, every multiple
reuse normally uses the same set of colors during a full display frame.
You can change sprite colors mid-screen with a Copper instruction list
that waits until the last line of the first use of the sprite processor
and changes the colors before the first line of the next use of the same
sprite processor:

    WAIT  for first line of display
    MOVE  firstcolor1 to COLOR17
    MOVE  firstcolor2 to COLOR18
    MOVE  firstcolor3 to COLOR19
    WAIT  for last line +1 of sprite's first use
    MOVE  secondcolor1 to COLOR17
    MOVE  secondcolor2 to COLOR18
    MOVE  secondcolor3 to COLOR19, and so on.

As you create Copper instruction lists, note that the final list must be
in the same order as that in which the video beam creates the display. The
video beam traverses the screen from position (0,0) in the upper left hand
corner of the screen to the end of the display (226,262) NTSC (or
(226,312) PAL) in the lower right hand corner. The first 0 in (0,0)
represents the x position. The second 0 represents the y position. For
example, an instruction that does something at position (0,100) should
come after an instruction that affects the display at position (0,60).

Note that given the form of the  WAIT  instruction, you can sometimes get
away with not sorting the list in strict video beam order.  The  WAIT 
instruction causes the Copper to wait until the value in the beam counter
is equal to or greater than the value in the instruction.

This means, for example, if you have instructions following each other
like this:

    WAIT  for position (64,64)
    MOVE  data

    WAIT  for position (60,60)
    MOVE  data

then the Copper will perform both moves, even though the instructions are
out of sequence.  The "greater than" specification prevents the Copper
from locking up if the beam has already passed the specified position.  A
side effect is that the second  MOVE  below will be performed:

    WAIT  for position (60,60)
    MOVE  data

    WAIT  for position (60,60)
    MOVE  data

At the time of the second  WAIT  in this sequence, the beam counters will
be greater than the position shown in the instructions. Therefore, the
second  MOVE  will also be performed.

Note also that the above sequence of instructions could just as easily be

    WAIT  for position (60,60)
    MOVE  data
    MOVE  data

because multiple  MOVE s can follow a single  WAIT .

 Complete Sample Copper List 

2 / Putting Together a Copper List / Complete Sample Copper List

The following example shows a complete Copper list. This list is for two
bitplanes -- one at $21000 and one at $25000. At the top of the screen,
the  color registers  are loaded with the following values:

          Register        Color
          --------        -----
          COLOR00         white
          COLOR01         red
          COLOR02         green
          COLOR03         blue

At line 150 on the screen, the  color registers  are reloaded:

          Register        Color
          --------        -----
          COLOR00         black
          COLOR01         yellow
          COLOR02         cyan
          COLOR03         magenta

The complete Copper list follows.

; Notes: 1. Copper lists must be in Chip RAM.
;        2. Bitplane addresses used in the example are arbitrary.
;        3. Destination register addresses in Copper move instructions
;           are offsets from the base address of the custom chips.
;        4. As always, hardware manual examples assume that your
;           application has taken full control of the hardware, and is not
;           conflicting with operating system use of the same hardware.
;        5. Many of the examples just pick memory addresses to be used.
;           Normally you would need to allocate the required type of
;           memory from the system with AllocMem()
;        6. As stated earlier, the code examples are mainly to help
;           clarify the way the hardware works.
;        7. The following INCLUDE files are required by all example code
;           in this chapter.
        INCLUDE "exec/types.i"
        INCLUDE "hardware/custom.i"
        INCLUDE "hardware/dmabits.i"
        INCLUDE "hardware/hw_examples.i"

;  Set up pointers to two bitplanes
        DC.W    BPL1PTH,$0002   ;Move $0002 into register $0E0 (BPL1PTH)
        DC.W    BPL1PTL,$1000   ;Move $1000 into register $0E2 (BPL1PTL)
        DC.W    BPL2PTH,$0002   ;Move $0002 into register $0E4 (BPL2PTH)
        DC.W    BPL2PTL,$5000   ;Move $5000 into register $0E6 (BPL2PTL)
;  Load color registers
        DC.W    COLOR00,$0FFF   ;Move white into register $180 (COLOR00)
        DC.W    COLOR01,$0F00   ;Move red into register   $182 (COLOR01)
        DC.W    COLOR02,$00F0   ;Move green into register $184 (COLOR02)
        DC.W    COLOR03,$000F   ;Move blue into register  $186 (COLOR03)
;   Specify 2 Lores bitplanes
        DC.W    BPLCON0,$2200   ;2 lores planes, coloron
;  Wait for line 150
        DC.W    $9601,$FF00     ;Wait for line 150, ignore horiz. position
;  Change color registers mid-display
        DC.W    COLOR00,$0000  ;Move black into register $0180 (COLOR00)
        DC.W    COLOR01,$0FF0  ;Move yellow into register $0182 (COLOR01)
        DC.W    COLOR02,$00FF  ;Move cyan into register $0184 (COLOR02)
        DC.W    COLOR03,$0F0F  ;Move magenta into register $0186 (COLOR03)
; End Copper list by waiting for the impossible
        DC.W    $FFFF,$FFFE    ;Wait for line 255, H = 254 (never happens)

For more information about  color registers , see Chapter 3, "Playfield

2 Coprocessor Hardware / Starting and Stopping the Copper

 Starting the Copper After Reset 
 Stopping the Copper 

2 / Starting and Stopping the Copper / Starting the Copper After Reset

At power-on or reset time, you must initialize one of the Copper
 location registers (COP1LC or COP2LC)  and write to its 
before Copper DMA is turned on. This ensures a known start address and
known state. Usually,  COP1LC  is used because this particular register is
reused during each vertical blanking  time. The following sequence of
instructions shows how to initialize a  location register . It is assumed
that the user has already created the correct  Copper instruction list  at
location "mycoplist."

; Install the copper list
     LEA     CUSTOM,a1           ; a1 = address of custom chips
     LEA     MYCOPLIST(pc),a0    ; Address of our copper list
     MOVE.L  a0,COP1LC(a1)       ; Write whole longword address
     MOVE.W  COPJMP1(a1),d0      ; Causes copper to load PC from  COP1LC 
; Then enable copper and raster dma

Now, if the contents of  COP1LC  are not changed, every time
 vertical blanking  occurs the Copper will restart at the same location
for each subsequent video screen. This forms a repeatable loop which, if
the list is correctly formulated, will cause the displayed screen to be

2 / Starting and Stopping the Copper / Stopping the Copper

No stop instruction is provided for the Copper. To ensure that it will
stop and do nothing until the screen display ends and the program counter
starts again at the top of the instruction list, the last instruction
should be to  WAIT  for an event that cannot occur. A typical instruction
is to  WAIT  for VP = $FF and HP = $FE. An HP of greater than $E2 is not
possible. When the screen display ends and  vertical blanking  starts, the
Copper will automatically be pointed to the top of its instruction list,
and this final  WAIT  instruction never finishes.

You can also stop the Copper by disabling its ability to use DMA for
retrieving instructions or placing data. The register called  DMACON 
controls all of the DMA channels. Bit 7, COPEN, enables Copper DMA when
set to 1.

For information about  controlling the DMA , see Chapter 7, "System
Control Hardware."

2 Coprocessor Hardware / Advanced Topics

 The SKIP Instruction 
 Copper Loops and Branches and Comparison Enable 
 A Copper Loop Example 
 Using the Copper in Interlaced Mode 
 Using the Copper with the Blitter 
 The Copper and the 680x0 

2 / Advanced Topics / The SKIP Instruction

The SKIP instruction causes the Copper to skip the next instruction if the
video beam counters are equal to or greater than the value given in the

The contents of the SKIP instruction's words are shown below. They are
identical to the  WAIT  instruction, except that bit 0 of the second
instruction word is a 1 to identify this as a SKIP instruction.

          Bit 0           Always set to 1.

          Bits 15 - 8      Vertical position  (called VP).

          Bits 7 - 1       Horizontal position  (called HP).

                          Skip if the beam counter is equal to or
                          greater than these combined bits
                          (bits 15 through 1).

          Bit 0           Always set to 1.

          Bit 15          The  blitter-finished-disable bit .
                          (See "Using the Copper with the Blitter"

          Bits 14 - 8     Vertical position compare enable bits
                          (called VE).

          Bits 7 - 1      Horizontal position compare enable bits
                          (called HE).

The notes about  horizontal  and  vertical beam position  found in the
discussion of the  WAIT  instruction apply also to the SKIP instruction.

The following example SKIP instruction skips the instruction following it
if VP ( vertical beam position ) is greater than or equal to 100 ($64).

        DC.W    $6401,$FF01     ;If VP >= 100,
                                ;  skip next instruction (ignore HP)

2 / Advanced Topics / Copper Loops and Branches and Comparison Enable

You can change the value in the  location registers  at any time and use
this value to construct loops in the instruction list. Before the next
 vertical blanking  time, however, the  COP1LC  registers must be
repointed to the beginning of the appropriate Copper list. The value in
the  COP1LC  location registers will be restored to the Copper's program
counter at the start of the  vertical blanking  period.

Bits 14-1 of instruction word 2 in the  WAIT  and  SKIP . instructions
specify which bits of the horizontal and vertical position are to be used
for the beam counter comparison. The position in instruction word 1 and
the compare enable bits in instruction word 2 are tested against the
actual beam counters before any further action is taken. A position bit in
instruction word 1 is used in comparing the positions with the actual beam
counters if and only if the corresponding enable bit in instruction word 2
is set to 1. If the corresponding enable bit is 0, the comparison is
always true. For instance, if you care only about the value in the last
four bits of the vertical position, you set only the last four compare
enable bits, bits (11-8) in instruction word 2.

Not all of the bits in the beam counter may be masked.  If you look at the
description of the IR2 (second instruction word) you will notice that bit
15 is the  blitter-finished-disable bit . This bit is not part of the beam
counter comparison mask, it has its own meaning in the Copper  WAIT 
instruction. Thus, you can not mask the most significant bit in  WAIT  or
 SKIP  instructions. In most situations this limitation does not come into
play, however, the following example shows how to deal with it.

2 / Advanced Topics / A Copper Loop Example

This example will instruct the Copper to issue an interrupt every 16 scan
lines.  It might seem that the way to do this would be to use a mask of
$0F and then compare the result with $0F. This should compare "true" for
$1F, $2F, $3F, etc. Since the test is for greater than or equal to, this
would seem to allow checking for every 16th scan line. However, the
highest order bit cannot be masked, so it will always appear in the
comparisons. When the Copper is waiting for $0F and the vertical position
is past 128 (hex $80), this test will always be true. In this case, the
minimum value in the comparison will be $80, which is always greater than
$0F, and the interrupt will happen on every scan line. Remember, the
Copper only checks for greater than or equal to.

In the following example, the Copper lists have been made to loop. The
 COP1LC and COP2LC  values are either set via the CPU or in the Copper
list before this section of Copper code. Also, it is assumed that you have
correctly installed an interrupt server for the Copper interrupt that will
be generated every 16 lines. Note that these are non-interlaced scan lines.

Here's how it works.  Both loops are, for the most part, exactly the same.
In each, the Copper waits until the vertical position register has $xF
(where x is any hex digit) in it, at which point we issue a Copper
interrupt to the Amiga hardware. To make sure that the Copper does not
loop back before the vertical position has changed and cause another
interrupt on the same scan line, wait for the horizontal position to be
$E2 after each interrupt. Position $E2 is horizontal position 113 for the
Copper and the last real horizontal position available. This will force
the Copper to the next line before the next  WAIT . The loop is executed
by writing to the  COPJMP1  register. This causes the Copper to jump to
the address that was initialized in  COP1LC .

The masking problem described above makes this code fail after vertical
position 127.  A separate loop must be executed when vertical position is
greater than or equal 127. When the vertical position becomes greater than
or equal to 127, the the first loop instruction is skipped, dropping the
Copper into the second loop. The second loop is much the same as the
first, except that it waits for $xF with the high bit set (binary
1xxx1111). This is true for both the vertical and the horizontal  WAIT 
instructions. To cause the second loop, write to the  COPJMP2  register.
The list is put into an infinite wait when VP >= 255 so that it will end
before the vertical blank. At the end of the  vertical blanking  period
 COP1LC  is written to by the operating system, causing the first loop to
start up again.

    COP1LC  is written at the end of  vertical blanking .
   The  COP1LC  register is written at the end of the  vertical blanking 
   period by a graphics interrupt handler which is in the vertical blank
   interrupt server chain.  As long as this server is intact,  COP1LC 
   will be correctly strobed at the end of each vertical blank.

;  This is the data for the Copper list.
;  It is assumed that COPPERL1 is loaded into  and
;  that COPPERL2 is loaded into  COP2LC  by some other code.
        DC.W    $0F01,$8F00   ; Wait for VP=0xxx1111
        DC.W    INTREQ,$8010  ; Set the copper interrupt bit...

        DC.W    $00E3,$80FE   ; Wait for Horizontal $E2
                              ; This is so the line gets finished before
                              ; we check if we are there  (The wait above)

        DC.W    $7F01,$7F01   ; Skip if VP>=127
        DC.W    COPJMP1,$0    ; Force a jump to  COP1LC 

        DC.W    $8F01,$8F00   ; Wait for VP=1xxx1111
        DC.W    INTREQ,$8010  ; Set the copper interrupt bit...

        DC.W    $80E3,$80FE   ; Wait for Horizontal $E2
                              ; This is so the line gets finished before
                              ; we check if we are there  (The wait above)

        DC.W    $FF01,$FE01   ; Skip if VP>=255
        DC.W    COPJMP2,$0    ; Force a jump to  COP2LC 

; Whatever cleanup copper code that might be needed here...
; Since there are 262 lines in NTSC, and we stopped at 255, there is a
; bit of time available

        DC.W    $FFFF,$FFFE     ; End of Copper list

2 / Advanced Topics / Using the Copper In Interlaced Mode

An interlaced bitplane display has twice the normal number of vertical
lines on the screen.  Whereas a normal NTSC display has 262 lines, an
interlaced NTSC display has 524 lines.  PAL has 312 lines normally and 625
in interlaced mode.  In interlaced mode, the video beam scans the screen
twice from top to bottom, displaying, in the case of NTSC, 262 lines at a
time. During the first scan, the odd-numbered lines are displayed.  During
the second scan, the even-numbered lines are displayed and interlaced with
the odd-numbered ones.  The scanning circuitry thus treats an interlaced
display as two display fields, one containing the even-numbered lines and
one containing the odd-numbered lines. Figure 2-1 shows how an interlaced
display is stored in memory.

         Odd field             Even field
         (time t)           (time t + 16.6ms)       Data in Memory
     -----------------      -----------------      -----------------
                                                  |                 |
                                                  |        1        |
                                                  |                 |
     _________________      _________________     |        2        |
    |                 |    |                 |    |_________________|
    |        1        |    |        2        |    |                 |
    |_________________|    |_________________|    |        3        |
    |                 |    |                 |    |_________________|
    |        3        |    |        4        |    |                 |
    |_________________|    |_________________|    |        4        |
    |                 |    |                 |    |_________________|
    |        5        |    |        6        |    |                 |
    |_________________|    |_________________|    |        5        |
                                                  |                 |
                                                  |        6        |

                 Figure 2-1: Interlaced Bitplane in RAM

The system retrieves data for bitplane displays by using pointers to the
starting address of the data in memory. As you can see, the starting
address for the even-numbered fields is one line greater than the starting
address for the odd-numbered fields. Therefore, the bitplane pointer must
contain a different value for alternate fields of the interlaced display.

Simply, the organization of the data in memory matches the apparent
organization on the screen (i.e., odd and even lines are interlaced
together). This is accomplished by having a separate
 Copper instruction list  for each field to manage displaying the data.

To get the Copper to execute the correct list, you set an interrupt to the
680x0 just after the first line of the display. When the interrupt is
executed, you change the contents of the  COP1LC  location register to
point to the second list. Then, during the  vertical blanking  interval,
 COP1LC  will be automatically reset to point to the original list.

For more information about  interlaced displays , see Chapter 3,
"Playfield Hardware."

2 / Advanced Topics / Using the Copper with the Blitter

If the Copper is used to start up a sequence of blitter operations, it
must wait for the blitter-finished interrupt before starting another
blitter operation. Changing blitter registers while the blitter is
operating causes unpredictable results. For just this purpose, the  WAIT 
instruction includes an additional control bit, called BFD (for blitter
finished disable). Normally, this bit is a 1 and only the beam counter
comparisons control the  WAIT .

When the BFD bit is a 0, the logic of the Copper  WAIT  instruction is
modified. The Copper will  WAIT  until the beam counter comparison is true
and the blitter has finished. The blitter has finished when the
blitter-finished flag is set. This bit should be unset with caution. It
could possibly prevent some screen displays or prevent objects from being
displayed correctly.

For more information about using the blitter, see
 Chapter 6, Blitter Hardware .

2 / Advanced Topics / The Copper and the 680x0

On those occasions when the Copper's instructions do not suffice, you can
interrupt the 680x0 and use its instruction set instead. The 680x0 can
poll for interrupt flags set in the  INTREQ  register by various devices.
To interrupt the 680x0, use the Copper  MOVE  instruction to store a 1
into the following bits of  INTREQ :

               Table 2-1: Interrupting the 680x0

     Bit Number      Name      Function
     ----------      ----      --------
        15          SET/CLR    Set/Clear control bit.  Determines
                               if bits written with a 1 get set
                               or cleared.

         4           COPEN     Coprocessor interrupting 680x0.

See Chapter 7, "System Control Hardware," for more information about
 interrupts .

2 Coprocessor Hardware / Summary of Copper Instructions

The table below shows a summary of the bit positions for each of the
 Copper instructions . See  Appendix A  for a summary of all registers.

             Table 2-2: Copper Instruction Summary

                   Move             Wait             Skip
                   ----             ----             ----
     Bit#       IR1    IR2       IR1    IR2       IR1    IR2
     ----       ---    ---       ---    ---       ---    ---
     15         X      RD15      VP7    BFD       VP7    BFD
     14         X      RD14      VP6    VE6       VP6    VE6
     13         X      RD13      VP5    VE5       VP5    VE5
     12         X      RD12      VP4    VE4       VP4    VE4
     11         X      RD11      VP3    VE3       VP3    VE3
     10         X      RD10      VP2    VE2       VP2    VE2
     09         X      RD09      VP1    VE1       VP1    VE1
     08         DA8    RD08      VP0    VE0       VP0    VE0
     07         DA7    RD07      HP8    HE8       HP8    HE8
     06         DA6    RD06      HP7    HE7       HP7    HE7
     05         DA5    RD05      HP6    HE6       HP6    HE6
     04         DA4    RD04      HP5    HE5       HP5    HE5
     03         DA3    RD03      HP4    HE4       HP4    HE4
     02         DA2    RD02      HP3    HE3       HP3    HE3
     01         DA1    RD01      HP2    HE2       HP2    HE2
     00         0      RD00      1      0         1      1

     X = don't care, but should be a 0 for upward compatibility
     IR1 = first instruction word
     IR2 = second instruction word
     DA = destination address
     RD = RAM data to be moved to destination register
     VP =  vertical beam position  bit
     HP =  horizontal beam position  bit
     VE = enable comparison (mask bit)
     HE = enable comparison (mask bit)
     BFD =  blitter-finished disable 

   ECS Copper.
   For information relating to the Copper in the Enhanced Chip
   Set (ECS), see  Appendix C .

Converted on 22 Apr 2000 with RexxDoesAmigaGuide2HTML 2.1 by Michael Ranner.