**
from an article by Philippe Rivaillon (privaillon free.fr)
in "l'Amiga Artiste Peintre" - Amiga
News Tech issues 32-33-34 avr/juin 1992
:
PART 1 : The Beginning
PART 2 : Lace and EHB
- PART 3 : HAM and Dual
Playfield
"In the video domain, the Amiga terrace most other
machines in the same category, with its 4096 colors
it can display at the same time ...
The latest models, the A3000 and A500+, have some new
modes: Super Hires with 1280 horizontal pixels
on a standard monitor with 4 among 64 colors, and the
mode Productivity on multisync monitor, which
displays a resolution of 640x480 4-color. Both modes
can be used interlaced, which multiplies by 2 vertical
resolution (1280x400 and 640x960). Finally, a mode named
A2024 10 or 15 Hz can display 1008x800 with 4
gray levels, but only with monochrome monitor A2024
or Viking.
It's good to have a lot of graphics modes available,
but should learn to use them ... Therefore, in this
first part, we will be interested in everything that
concerns the screen graphics. Let's go...
What is a Bit Plane ?
This part is for newbies.
The spot runs through the monitor screen from left to
right and from top to bottom. The contents in memory
to be displayed will be devided into lines beginning
with the data from the left. The vertical resolution
describes the number of lines visible on the screen.
The screen is made of a multitude of bright spots: Pixels
(Picture Element). The number of pixels on a line representing
the horizontal resolution.
On a monochrome monitor (2 colors), each pixel is represented
in memory by a bit: 1 = pixel ON and 0 = pixel OFF.
A line of 320 pixels will be represented by 320 / 8
bits = 40 bytes. For a 320x200 (320x256) screen, it
will 40x200 (40x256) = 8000 (10240) bytes.
All these bits are called a Bit-Plane or BitPlan.
For color, instead of using 1 bitplan, it uses several
using rule : number of colors = 2 ^ number of bitplans.
Taking the first bit of each bitplan, we obtain the
number of the color of the first pixel.
"Ecran, ouvre toi !"
To simplify things, we talk only about the low resolution
mode non-interlaced (320x200 or 256) and high resolution
non-interlaced (640x200 or 256). The rest will be covered
later. The procedure for opening a screen remains the
same.
To open a screen, you must first choose the resolution:
- LoRes : 320 pixels/line, 32 colors maximum
- HiRes : 640 pixels/line, 16 colors maximum
Next, we must define the number of colors required
by fixing the number of bitplans according to the formula
previously. Note that the Amiga enables 5 bitplans to
2 ^ 5 = 32 colors, but some mode as the HAM and Half-Bright
use a 6th plan.
We must initialize the register (write only) :
BPLCON0 - $DFF100 - first bitplans control register
Bit |
Name |
Function |
15 |
Hires |
active hires mode (640 pixels/lines)
$8000 |
14-12 |
BPU2-0 |
3 bits for the number of bitplans
: 1 to 6 = $1000 to $6000 (6=EHB) |
11 |
HOMOD |
Mode Hold and Modify (HAM) $800 |
10 |
DBPLF |
Mode Dual-Playfield $400 |
9 |
COLOR |
Color Output Video (needed!) $200 |
8 |
GAUD |
Genlock |
7-4 |
|
unused |
3 |
LPEN |
Light Pen |
2 |
LACE |
Mode Interlaced (512 lines) $4 |
1 |
ERSY |
external Synchronization |
0 |
|
unused |
le mode Extra-Half-Bright (64 colors) sera sélectionné
automatiquement avec les 6 bitplans activés.
Lorsque le bit LACE est initialisé, le bit LOF-Frame
du registre VPOS est inversé au debut de chaque
nouvelle image afin que le changement entre Long
et Short Frame puisse avoir lieu. (voir Part
2)
Then you have to define colors. Their code is the type
RGB (Red, Green, Blue) to get the color you want, we
must make mixtures of red, green and blue. Each component
is encoded in 4 bits, which allows 16 intensisites per
component (0 to F), thus 16x16x16 = 4096 colors.
The colors are stored in the registers (write only):
COLORx - $DFF180+2*x - color register #x
Bit |
Name |
Function |
15-12 |
|
unused |
11-8 |
R3-R0 |
Red component |
7-4 |
G3-G0 |
Green component |
3-0 |
B3-B0 |
Blue component |
There are 32 registers $DFF180 to $DFF1BE. Color 0
is the background color of the screen.
"Ecran, ouvre toi !" (Bis)
La prochaine etape consiste à definir la largeur,
hauteur et position de l'écran. Il ne s'agit
pas de resolution, mais de fixer les limites de l'ecran
visible.
DIWSTRT - $dff08e - position du coin haut gauche
DIWSTOP - $dff090 - postion du coin bas droit
Bit |
Name |
Function |
15-8 |
VSTART/VSTOP7-0 |
start or end vertical position |
7-0 |
HSTART/HSTOP7-0 |
start of end horizontal position |
registres accessibles en ecriture. les positions sont
toujours spécifiées en basse resolution
non entrelacée quelque soit la resolution réelle.
chaque coordonnée etant sur 8 bits, la limite
de la position du coin superieur gauche de l'ecran visible
est de 256 lignes et 256 points de resolution.
la valeur de HSTOP est toujours ajoutée à
$100 (256). son minimum est 256 et son maximum de 511.
pour VSTOP, il faut choisir un Y entre 128 et 383 (9
bits) et mettre les 8 bits inferieurs dans VSTOP.
la premiere ligne de balayage visible n'est pas 0. il
faut tenir compte du Vertical Blank. Idem pour la premiere
colonne.
Les valeurs normales pour centrer un ecran de 320x200
(ou 256) sont :
DIWSTRT=$2C81 et DIWSTOP=$F4C1(ou 2CC1).
Pour l'Overscan, on se base sur un ecran de 352x265
: DIWSTRT=$2069 et DIWSTOP=$29C9.
DDFSTRT - $DFF092 - horizontal start of the bitplan
DDFSTOP - $DFF094 - horitontal end of the bitplan
Bit |
Function |
15-8 |
unused |
7-2 |
start or end of transfert |
1-0 |
special (always 0) |
ces registres decrivent un intervalle de temps en termes
de cycles DMA : ils indiquent quand l'Amiga doit commencer
et interrompre le transfert des données vidéos
vers l'ecran.
Initialisons le premier registre. Pour celà,
il faut utiliser VSTART (initialisé dans
DIWSTRT) que l'on transformera en nombre de cycles.
Il faut multiplier VSTART par 2 en haute resolution
car il est identique en basse et en haute resolution.
En basse resolution, le hardware a besoin de 8 cycles
DMA pour transferer un mot de données (16 pixels)
depuis la mémoire vers l'écran, alors
qu'il ne lui en faut que 4 en haute resolution.
Un rapide calcul nous permet donc de dire qu'il suffit
de diviser VSTART par 2 pour avoir le nombre de cycles,
quelle que soit la resolution.
De plus, il faut un peu de temps à l'Amiga avant
d'afficher chaque ligne. Il faut retrancher à
DDFSTRT 4.5 pixels en basse resolution et 8.5 pixels
en haute resolution pour tenir compte de ce temps de
repos. Le hardware ne travaillant qu'avec des nombres
entiers, le resultat sera arrondi.
DDFSTRT = (VSTART/2-8.5) in low resolution
DDFSTRT = (VSTART/2-4.5) in high resolution
DDFSTOP is deduced from this result :
low resolution = DDFSTRT+(8*(mots par ligne-1))
high resolution = DDFSTRT+(4*(mots par ligne-2))
4 and 8 represent the numbers of cycles to transfer
a word. -1 And -2 are still quite mysterious.
Examples:
- screen 320x200 : DIWSTRT=$2C81 / DIWSTOP=$F4C1
DDFSTRT = $81/2-8 = $38 / DDFSTOP = $38+8*(320/16-1)
= $D0
- screen 640x200 : DIWSTRT=$2C81 / DIWSTOP=$F4C1
DDFSTRT = $81/2-4 = $3C / DDFSTOP = $3C+4*(640/16-2)
= $D4
There are values to extremes not exceed. Avoid values
below $28 for DDFSTRT and above $D8 for DDFSTOP. But
they are sufficient for the overscan.
"Ecran, ouvre toi !" (ter)
We are going to deal with the plans of bits in memory.
We must clarify 2 things at the Amiga: the address of
each bitplan and value to be added at the end of each
line reading of the screen pointer concerned (Modulo).
BPLxPTH - $DFF0yy - Address of the bitplan x (high
bits)
BPLxPTL - $DFF0zz - Address of the bitplan x (low bits)
with x = # of bitplan 1 to 6, yy=$E0+((x-1)*4), zz=yy+2
The bitplans, like all data used by the DMA, shall
lie in the memory chip. The address is encoded in 19,
20 or 21 bits depending on the model Amiga.
Attention : The contents of these records is permanently
incremented (these are pointers). Any change in use
will be directly visible on the screen. Do not forget
to reset the return of each spot (Blanking) because
Agnus does not take care of its own. Typically, this
task falls to Copper because it is always synchronized
with the display.
Memory transferts to the screen carried word by word.
Pointers must always contain an even address.
BPL1MOD - $DFF108 - Modulo odd bitplans
BPL2MOD - $DFF10A - Modulo even bitplans
When the hardware has finished transmitting a line
of datas, he adds these values, expressed in bytes,
to the bitplans pointers. That allows among others manage
bitplans larger than the visible on the screen and the
scroll easily. They shall only contain even numbers.
It remains only to reserve enough memory for bitplans
(nb bitplans*width in bytes*nb lines) and organize bitplans
the way you want :
- type "normal" : The bitplans are
one after the other in memory and everyone in a single
block (pointer at the beginning of each bitplan).
- type "iff" or "raw blitter"
or "interlaced" : The bitplans tangle
with each other: there is first the first line of the
first bitplan, then the first second, etc ... and it
repeats for each of the other lines.
The advantage of this format is to allow an impact on
all the bitplans in a single transfer Blitter.
For example, in normal mode, it will take as many transfers
as bitplans while in interlaced mode, a single transfer
will suffice. There is no reset several times the Blitter.
To use this method, you must initialize each bitplan
pointer on his first line, calculate and add modulos
(nb bitplan-1)*(bitplan width in bytes).
We just have to start showing. Suffice it to initialize
DMACON : DMA Bitplan (bit 8), DMA Copper (bit 7).
All these informations could be stocked intro the CopperList
: not necessary, but easier. Only pointers address should
be equired.
Full Example :
screen 352x265, 4 colors HiRes. Bitplans : 1024x265
each. In Normal mode, we can see verticals red and green
strips. In Interlaced mode, we can see verticals blue
and black strips inverted after the half of the screen,
with stroked red and green line between 2 halfs.
START:
;...beginning of the program
; initializing bitplans pointers in the copperlist
move.l #Screen,d1
move.w d1,CLplan1+6 ; low bits
swap d1
move.w d1,CLplan1+2 ; high bits
swap d1
add.l #265*(1024/8),d1 ; point to the 2nd bitplan
;add.l #1024/8 ; Interlaced mode Iff
move.w d1,CLplan2+6
swap d1
move.w d1,CLplan2+2
move.w #%0000000000100000,$dff096 ; sprites off
move.w #%1000001110000000,$dff096 ; dma
move.l #copperlist,$dff080
move.w #0,$dff088 ; restart the copper
;...
rts
copperlist:
dc.w $0100,$A200 ; resolution, nb bitplan
dc.w $0180,$0000 ; color 0
dc.w $0182,$0F00 ; color 1 (red)
dc.w $0184,$00F0 ; color 2 (green)
dc.w $0186,$000F ; color 3 (blue)
dc.w $008E,$2069 ; DIWSTRT $20
dc.w $0090,$29C9 ; DIWSTOP $129-$20=265
dc.w $0092,$0030 ; DDFSTRT
dc.w $0094,$00D8 ; DDFSTOP
dc.w $0108,$0028 ; odd modulo 40 (+$80 Iff mode)
dc.w $010A,$0028 ; even modulo
CLplan1:
dc.w $00E0,$0000 ; BPL1PTH bitplan 1
dc.w $00E2,$0000 ; BPL1PTL
CLplan2:
dc.w $00E4,$0000 ; bitplan 2
dc.w $00E6,$0000
dc.w $FFFF,$FFFE ; -2 end of copperlist
Screen:
dcb.b 265*(1024/8),$F0 ; bitplan 1 strips
dcb.b 265*(1024/8),$0F ; bitplan 2 inverted strips"
PART
2 : Lace and EHB - PART
3 : HAM and Dual Playfield
credits: Philippe Rivaillon in "l'Amiga
Artiste Peintre" - ANT issues 32-33-34 avr/juin
1992
|