Ham-8 Mode
Bitplanes:
Set bits 0 to 7 bitplanes as before in BPLCON0 (for 0 to 7 bitplanes)
For 8 bitplanes you should set bit 4 (BPU3) of BPLCON0
bits 12 to 14 (BPU0 to BPU2) should be zero.
Using 64-colour mode (NOT extra halfbrite) requires setting the
KILLEHB (bit 9) in BPLCON2.
Super Hires can be enabled by bit 6 (SHRES) of BPLCON0
Colour Registers
There are now 256 24-bit colour registers, all accessed through the original
32 12-bit colour registers. If you suspect this sounds like it could
be messy, then you're right, it is!
AGA works with 8 differents palettes of 32 colors each, re-using
colour registers from COLOR00 to COLOR31
You can choose the palette you want to access via bits 13 to 15 of
register BPLCON3.
BANK2 BANK1 BANK0
bit 15 | bit 14 | bit 13 | Selected palette
-------+--------+--------+------------------------------
0 | 0 | 0 | Palette 0 (color 0 to 31)
0 | 0 | 1 | Palette 1 (color 32 to 63)
0 | 1 | 0 | Palette 2 (color 64 to 95)
0 | 1 | 1 | Palette 3 (color 96 to 127)
1 | 0 | 0 | Palette 4 (color 128 to 159)
1 | 0 | 1 | Palette 5 (color 160 to 191)
1 | 1 | 0 | Palette 6 (color 192 to 223)
1 | 1 | 1 | Palette 7 (color 224 to 255)
To move a 24-bit colour value into a colour register requires
two writes to the register:
First clear bit 9 (LOCT) of BPLCON3
Move high nibbles of each colour component to colour registers
Then set bit 9 (LOCT) of BPLCON3
Move low nibbles of each colour components to colour registers
For example, to change colour zero to the colour $123456
lea (CUSTOM.L),a0
move.w #$0135,COLOR00(a0)
move.w #$0200,BPLCON3(a0)
move.w #$0246,COLOR00(a0)
move.w #$0000,BPLCON3(a0)
Sprites
To change the resolution of the sprite, just use bit 7 and 6 of
register BPLCON3
bit 7 | bit 6 | Resolution
------+-------+-----------
0 | 0 | ECS Defaults (Lo-res/Hi-res = 140ns, Superhires = 70ns)
0 | 1 | Always lowres (140ns)
0 | 1 | Always hireres (70ns)
1 | 1 | Always superhires (35ns)
--------------------------
For 32-bit and 64-bit wide sprites use bit 3 and 2 of register FMODE
($dff1fc) Sprite format (in particular the control words) vary for each
width.
bit 3 | bit 2 | Wide | Control Words
------+-------+-------------+----------------------------------
0 | 0 | 16 pixels | 2 words (normal)
1 | 0 | 32 pixels | 2 longwords
0 | 1 | 32 pixels | 2 longwords
1 | 1 | 64 pixels | 2 double long words (4 longwords)
---------------------------------------------------------------
Wider sprites are not available under all conditions.
It is possible to choose the color palette of the sprite.
This is done with bits 0 to 3 (even) and 4 to 7 (odd)
of register $010C.
bit 3 | bit 2 | bit 1 | bit 0 | Even sprites
bit 7 | bit 6 | bit 5 | bit 4 | Odd Sprites
------+-------+-------+-------+------------------------------------------
0 | 0 | 0 | 0 | $0180/palette 0 (coulor 0)
0 | 0 | 0 | 1 | $01A0/palette 0 (color 15)
0 | 0 | 1 | 0 | $0180/palette 1 (color 31)
0 | 0 | 1 | 1 | $01A0/palette 1 (color 47)
0 | 1 | 0 | 0 | $0180/palette 2 (color 63)
0 | 1 | 0 | 1 | $01A0/palette 2 (color 79)
0 | 1 | 1 | 0 | $0180/palette 3 (color 95)
0 | 1 | 1 | 1 | $01A0/palette 3 (color 111)
1 | 0 | 0 | 0 | $0180/palette 4 (color 127)
1 | 0 | 0 | 1 | $01A0/palette 4 (color 143)
1 | 0 | 1 | 0 | $0180/palette 5 (color 159)
1 | 0 | 1 | 1 | $01A0/palette 5 (color 175)
1 | 1 | 0 | 0 | $0180/palette 6 (color 191)
1 | 1 | 0 | 1 | $01A0/palette 6 (color 207)
1 | 1 | 1 | 0 | $0180/palette 7 (color 223)
1 | 1 | 1 | 1 | $01A0/palette 7 (color 239)
-------------------------------------------------------------------------
See Resetting sprites for an OS legal method of setting
sprite resolution.
Alignment Restrictions
Bitplanes, sprites and copperlists must be, under
certain circumstances, 64-bit aligned under AGA. Again to benefit from
maximum bandwitdh bitplanes should also only be multiples of 64-bits wide,
so if you want an extra area on the side of your screen for smooth blitter
scrolling it must be *8 bytes* wide, not two as normal.
This also raises another problem. You can no longer use
AllocMem() to allocate bitplane/sprite memory directly.
Either use AllocMem(sizeofplanes+8) and calculate how many
bytes you have to skip at the front to give 64-bit alignment
(remember this assumes either you allocate each bitplane
individually or make sure the bitplane size is also an
exact multiple of 64-bits), or you can use the new V39
function AllocBitMap()
The Magic FMode Register
If you set your 1200/4000 to a hiresmode (such as 1280x512 Superhires
256 colours) and disassemble the copperlist, you find fun things
happen to the FMODE register ($dff1fc). The FMODE register determines
the amount of words transferred between chipram and the Lisa chip
in each data fetch (I think)....
$dff1fc bits 0 and 1 value
$00 - Normal (word aligned bitmaps) - for standard ECS modes
and up to 8 bitplanes 320x256
$01 - Double (longword aligned bitmaps) - for 640x256 modes in
more than 16 colours
$10 - Double (longword aligned bitmaps) - Same effect, for 640x256 modes
but different things happen... Not sure why!
$11 - Quadruple [x4] (64-bit aligned bitmaps) - for 1280x256 modes...
Fetch Mode Required for Displays
*ALL* ECS and lower screenmodes require only 1x datafetch. All modes
run *FASTER* with at least 2x bandwidth, so try and use 2x bandwitdh
if possible.
Planes Colours Fetchmode
LORES (320x256)
6 64 1
7 128 1
8 256 1
8 HAM-8 1
HIRES (640x256) 5 32 2
6 64 2
7 128 2
8 256 2
8 HAM-8 2
SUPER-HIRES 1 2 1
(1280x256) 2 4 1
3 8 2
4 16 2
5 32 4
6 64 4
7 128 4
8 256 4
8 HAM-8 4
PRODUCTIVITY 1 2 1
(640x480,etc) 2 4 1
3 8 2
4 16 2
5 32 4
6 64 4
7 128 4
8 256 4
8 HAM-8 4
This table only shows the minimum required fetchmode for each screen.
You should always try and set the fetchmode as high as possible (if
you are 64-bit aligned and wide, then $11, if 32-bit aligned and wide
$01, etc...)
Bits 2 and 3 do the same for sprite width, as has been mentioned elsewhere...
Remember... To take advantage of the increased fetchmodes (which give
you more processor time to play with!) your bitmaps must be on 64-bit
boundaries and be multiples of 64-bits wide (8 bytes)
Smoother Hardware Scrolling
Extra bits have been added to BPLCON1 to allow smoother hardware
scrolling and scrolling over a larger area.
Bits 8 (PF1H0) and 9 (PF1H1) are the new hi-resolution scroll bits for
playfield 0 and bits 12 (PF2H0) and 13 (PF2H1) are the new bits for
playfield 1.
Another two bits have been added for each bitplane at bits 10 (PF1H6)
and 11 (PF1H7) for playfield 1 and bits 14 (PF2H6) and 15 (PF2H7) to
increase the maximum scroll range from 16 lo-res pixels to 64 lo-res
pixels (or 256 superhires pixels).
Normal 0-16 positions therefore are normal, but it you want to
position your screen at a (super) hires position you need to set
the new bits, or if you require smooth hardware scrolling with either
2x or 4x @{" Fetch Mode " link fetchmode}.
What is HAM-8 Format?
Ham8 mode is enabled when the HAM bit is set in BPLCON0 and 8 bitplanes
are specified.
Ham-8 uses *lower* two bits as the command (either
new register (%00), or alter Red, Green or Blue component, as in
standard HAM), and the *upper* 6 bits (planes 2 to 7) as the
register(0 to 63), or as an 6 bit hold-and-modify value to modify
the top 6 bits of an 8-bit colour component.
The lower two bits of the colour component are not altered, so
initial palettes have to be chosen carefuly (or use Art
Department Professional or anything that selects colours better)
@endnode
Monitor Problems
Unfortunately the A1200/AGA chipset does not have the deinterlacer
circuitry present in the Amiga 3000, but instead has new 'deinterlaced'
modes. This gives the A1200 the capability of running workbench (and
almost all OS legal software) the ability to run flicker free at high
resolution on a multiscan or Super VGA monitor.
Unlike the Amiga 3000 hardware it produces these flicker free modes
by generating a custom copperlist, so any programs that generate
their own copperlists will continue to run at the old flickery 15Khz
frequency unless they add their own deinterlace code.
This is a big problem for many A1200 owners as there are very few multiscan
monitors that support 15Khz displays now. Most multiscan monitors will
not display screen at less than 27Khz. People with A1200/4000 and this
kind of monitor *CANNOT* view any games or demos that write their own
copperlists.
Can you help them out? Unfortunately it's not easy. Deinterlacing is
done in AGA by doing two things.
Firstly different horizontal and vertical frequencies are set (These
are set to unusual values for anyone used to Amiga or PC displays!
For example, DblPal is set by default to 27Khz horizontal and 48Hz
vertical) It's important to realise that the vertical frequency
changes too!
Seondly, for non-interlaced screens, bitplane scandoubling is enabled (bit
BSCAN2 in FMODE) This repeats each scanline twice. A side effect of this is
that the bitplane modulos are unavailable for user control.
So... There are three options.
1. Write nasty copperlist code to work with both standard and
promoted displays (Not a good idea!)
2. Use the OS and set up your displays legally, asking the Display Database
for a screenmode that is available for the current monitor.
3. Give up, and say your demo requires a 15Khz monitor.
I think most people will go for option 3. The Commodore 1084/1085, Phillips
8833/8852 and the Commodore 1950/1960/1940/1942 monitors are all capable
of running 15Khz screens.
exec.library/AllocMem()
AllocMem -- allocate memory given certain requirements
memoryBlock = AllocMem(byteSize, attributes)
D0 -198 D0 D1
void *AllocMem(ULONG, ULONG);
graphics.library/AllocBitMap()
AllocBitMap -- Allocate a bitmap and attach bitplanes to it. (V39)
bitmap=AllocBitMap(sizex,sizey,depth, flags, friend_bitmap)
-918 d0 d1 d2 d3 a0
struct BitMap *AllocBitMap(ULONG,ULONG,ULONG,ULONG, struct BitMap *);
Allocates and initializes a bitmap structure. Allocates and initializes
bitplane data, and sets the bitmap's planes to point to it.
IN:
sizex = the width (in pixels) for the bitmap data.
sizey = the height (in pixels).
depth = the number of bitplanes deep for the allocation.
flags = BMF_CLEAR - Clear the bitmap.
BMF_DISPLAYABLE - bitmap displayable on AGA machines in
all modes.
BMF_INTERLEAVED - bitplanes are interleaved
friend_bitmap = pointer to another bitmap, or NULL. If this pointer
If present, bitmap will be allocated so blitting
between the two is simplified.
SEE ALSO
FreeBitMap()
graphics.library/FreeBitMap()
FreeBitMap -- free a bitmap created by AllocBitMap
FreeBitMap(bm)
-924 a0
VOID FreeBitMap(struct BitMap *)
Frees bitmap and all associated bitplanes
IN:
bm = A pointer to a BitMap.
Resetting AGA sprite resolution
This is a totally OS-legal way of resetting sprite resolution to 140ns
(ECS default). call FixSpritesSetup: *BEFORE* your LoadView(NULL) in your
startup code, and ReturnSpritesToNormal: *BEFORE* the LoadView(wbview)
that returns workbench in your exit code:
Here is the assembler version of the code: See startup.asm
for an integrated example of this code:
; Setup code - assumes V39 Kickstart or higher
FixSpritesSetup:
move.l _IntuitionBase,a6 ; open intuition.library first!
lea wbname,a0
jsr _LVOLockPubScreen(a6)
tst.l d0 ; Could I lock Workbench?
beq.s .error ; if not, error
move.l d0,wbscreen
move.l d0,a0
move.l sc_ViewPort+vp_ColorMap(a0),a0
lea taglist,a1
move.l _GfxBase,a6 ; open graphics.library first!
jsr _LVOVideoControl(a6)
move.l resolution,oldres ; store old resolution
move.l #SPRITERESN_140NS,resolution
move.l #VTAG_SPRITERESN_SET,taglist
move.l wbscreen,a0
move.l sc_ViewPort+vp_ColorMap(a0),a0
lea taglist,a1
jsr _LVOVideoControl(a6) ; set sprites to lores
move.l wbscreen,a0
move.l _IntuitionBase,a6
jsr _LVOMakeScreen(a6)
jsr _LVORethinkDisplay(a6) ; and rebuild system copperlists
; Sprites are now set back to 140ns in a system friendly manner!
.error
rts
ReturnSpritesToNormal:
; If you mess with sprite resolution you must return resolution
; back to workbench standard on return! This code will do that...
move.l wbscreen,d0
beq.s .error
move.l d0,a0
move.l oldres,resolution ; change taglist
lea taglist,a1
move.l sc_ViewPort+vp_ColorMap(a0),a0
move.l _GfxBase,a6
jsr _LVOVideoControl(a6) ; return sprites to normal.
move.l _IntuitionBase,a6
move.l wbscreen,a0
jsr _LVOMakeScreen(a6) ; and rebuild screen
move.l wbscreen,a1
sub.l a0,a0
jsr _LVOUnlockPubScreen(a6)
.error
rts
oldres dc.l 0
wbscreen dc.l 0
taglist dc.l VTAG_SPRITERESN_GET
resolution dc.l SPRITERESN_ECS
dc.l TAG_DONE,0
wbname dc.b "Workbench",0
intuition.library/LocPubScreen()
LockPubScreen -- Put a lock on a Public Screen.
screen = LockPubScreen( Name )
D0 -510 A0
struct Screen *LockPubScreen( UBYTE * );
Prevents a public screen (or the Workbench) from closing.
intuition.library/UnlockPubScreen()
UnlockPubScreen -- Remove lock from a Public Screen.
UnlockPubScreen( Name, [Screen] )
-516 A0 A1
VOID UnlockPubScreen( UBYTE *, struct Screen * );
Releases a lock from @{" LockPubScreen() " link lockpubscreen}
IN:
Usually Name = NULL and Screen = pointer returned by LockPubScreen()
graphics.library/VideoControl()
VideoControl -- Parse tags on viewport colormap.
err = VideoControl( cmap , tags )
d0 -708 a0 a1
ULONG VideoControl( struct ColorMap *, struct TagItem * );
Process the tag commands on the colormap.
IN:
cm = pointer to struct ColorMap
tags = pointer to a table of videocontrol tagitems.
OUT:
error = NULL if no error occured.
graphics.library/SetChipRev()
SetChipRev -- Enables Chip Set features
chipbits = SetChipRev(Rev)
-888 d0
IN:
Rev - Revision to be enabled ($ffffffff for best possible)
OUT:
chipbits - State of chipset on exit.
Only call this routine once. It is called by the OS in SetPatch, but you
should use it if you are writing Non-DOS demos or games.
Main Menu