|
LineMode
Using blitter for line drawing:
Besides copying data and filling areas, the blitter
has one more talent: drawing lines. In line mode,
almost all of the blitter registers change their
functions.
The blitter draws lines at incredible speeds, much
faster than the 68000. Unfortunately, you can't
just give the blitter two points and then tell it to
connect the dots. You need to perform some
calculations first.
Let's say that you want to draw a line from point
(x1,y1) to (x2,y2). From these coordinates you need
to figure out the horizontal and vertical distance
between the line's two end points. This is easily
calculated using the following two formulas:
dx = abs(x1-x2)
dy = abs(y1-y2)
Now you're ready to give the BLTCON1 register at
$dff042 some information about the physical
orientation of the line.
If (dx >= dy) and (x1 >= x2) set bit 2.
If (dx < dy) and (y1 >= y2) set bit 2.
If (dx >= dy) and (y1 >= y2) set bit 3.
If (dx < dy) and (x1 >= x2) set bit 3.
If (dx >=dy) set bit 4.
Together, these bits define the octant (position
relative to the line's starting position) in which
the line will appear. The following shows how the
Amiga divides the screen into octants:
\ | / * = x1,y1
\3 | 1/ Note: The numbers shown in this figure
7 \ | / 6 represent the combined value of BLTCON1's
\|/ bits 2-4. If the line appears on the border
----X---- of two octants, it does not matter which of
/|\ the two octants you select.
5 / | \ 4
/2 | 0\
/ | \
Next, you need to determine which value is larger:
dx or dy. Let dmax equal the greater value, and
dmin the lesser value. Now use these values to set
the following registers:
dmax = max(dx,dy)
dmin = min(dx,dy)
BLTBMOD = 4* dmin
BLTAMOD = 4 * (dmax-dmin)
BLTAPTL = (4 * dmin) - (2 * dmax)
These formulas define the line's slope. If the
result of the last calculation BLTAPTL is negative,
you must store a 1 in the SIGN bit (6) of the
BLTCON1 register.
Besides holding the line's octant number and the
negative/positive status of the line's slope,
BLTCON1 affects the line's physical appearance. If
you're drawing lines to enclose an area that you
plan to fill later using blitter fill mode, you
should set the ONEDOT bit (1) equal to one. This
tells the blitter to draw lines using only one pixel
per raster, thus providing a single pixel border for
your object.
To create textured lines, BLTCON1's bits 12-15 work
in conjunction with the BLTBDAT register ($dff072).
The bit pattern found in BLTBDAT defines the pixel
pattern used to draw lines. For normal solid lines,
set all of BLTBDAT's bits to one. (i.e. $ffff)
Other values create dotted or dashed lines. Bits
12-15 in BLTCON1 allow you to specify which bit in
BLTBDAT, 0-15, defines the status of the first pixel
in the line. For most practical purposes, BLTCON1's
bits 12-15 should be set equal to the value of x1's
lower 4 bits. (i.e. x1 AND $0f) This informs the
blitter to start the line off with the value found
in BLTBDAT's MSB (15). IMPORTANT: ALWAYS SET
BLTCON1 PRIOR TO BLTBDAT!
BLTCON1's bit 5 should always be set to zero, as
should bits 7 through 11. To tell the blitter that
you want to draw lines instead of copy data, the
LINE bit (0) must be set to 1.
The Amiga needs certain information about the size
and location of the screen's bitmap before it can
draw a line. First, store the byte-width (number of
pixels divided by 8) of the bitmap in the BLTCMOD
and BLTDMOD registers ($dff060 and $dff066). Next,
you must put the address of the word containing the
starting point of the line into the BLTCPT and
BLTDPT registers. ($dff048 and $dff054)
Only one bitplane can be written to during a single
blitter operation. So, to draw a line of a
particular color on a multiple bitplane screen, it
may be necessary to perform two or more line blits.
In these cases, you set the registers up for the
first bitplane as usual, and perform the blit; then
for subsequent bitplanes, you simply reinitialize
the registers with the same values EXCEPT for the
registers BLTCPT and BLTDPT, which must contain the
address of the line's starting point within the new
bitplane.
As with blitter copy mode, you must set bits 0-7 in
the BLTCON0 register ($dff040) to choose a miniterm.
Usually, you should store $ca here, but if you
prefer to XOR your line onto the screen (invert all
the pixels found on the line), store a $4a here.
BLTCON0's bits 8-11 should be set equal to $b.
(This activates blitter source A and C, and
destination D.) Store x1's lower four bits (x1 AND
$0f) into BLTCON0's bits 12-15. The blitter uses
this value to determine the bit position of the
line's starting point within the bitplane memory
location specified by registers BLTCPT and BLTDPT.
Now, set BLTADAT ($dff074) equal to $8000. (Set
this register only AFTER you've set BLTCON0) Only
two more registers must be set before you can
activate the blitter: BLTAFWM and BLTALWM.
($dff044 and $dff046) Store a $ffff into both.
Finally, you're ready to start the blitter by
writing to the BLTSIZE register ($dff058). Use the
following formula to determine the value that you
should store into this register:
BLTSIZE = (dmax * 64) + 66
Because writing to BLTSIZE turns on the blitter,
this should be the last register that you set.
|