amiga-bootcamp/01_hardware/aga_a1200_a4000/aga_blitter.md

168 lines
6.2 KiB
Markdown
Raw Normal View History

[← Home](../../README.md) · [Hardware](../README.md) · [AGA](README.md)
# AGA Blitter — What It Is, What It Does, and 64-bit Bus Mode
## What Is the Blitter?
The **Blitter** (Block Image Transfer) is a dedicated DMA hardware engine inside every Amiga, designed to move and transform rectangular blocks of bitmap data **without CPU intervention**. While the CPU handles game logic, AI, physics, and sound setup, the Blitter does the heavy graphical lifting in the background.
Think of it as a **hardware GPU for 2D raster operations** — years before PC graphics cards existed.
### What the Blitter Can Do
| Capability | Description | Typical Use |
|---|---|---|
| **Block copy** | Move rectangular bitmap regions | Scrolling backgrounds, restoring screen areas |
| **Cookie-cut blit** | Stamp a shape onto a background using a mask | Drawing game sprites (BOBs) with transparency |
| **Area fill** | Fill arbitrary shapes | Flood-filling polygons, UI element backgrounds |
| **Line drawing** | Draw lines using hardware Bresenham | Vector graphics, wireframe 3D |
| **Clear/set memory** | Zero or fill large memory blocks | Screen clearing between frames |
| **Logic operations** | Combine 3 inputs with any Boolean function | XOR cursors, shadow effects, masking |
| **Shifting** | Shift source data 015 pixels | Sub-word-aligned sprite positioning |
### What the Blitter Cannot Do
| Limitation | Detail |
|---|---|
| No scaling | Cannot resize images — fixed 1:1 pixel mapping |
| No rotation | Cannot rotate — must be pre-rendered in software |
| No 3D | No perspective, texture mapping, or Z-buffer |
| No chunky pixels | Operates on **planar** bitplanes only (1 plane at a time) |
2026-04-26 14:46:18 -04:00
| No color blending | Pure Boolean logic — no alpha, no transparency gradients |
| Word-aligned width | Minimum operation width is 16 pixels (1 word) |
### How Software Uses It
**Games** — The blitter draws BOBs (Blitter Objects = software sprites) by cookie-cutting character graphics onto the playfield. A typical game frame:
1. Blitter restores background behind old sprite positions
2. Game logic updates positions
3. Blitter draws sprites at new positions using cookie-cut
4. Copper switches display to the newly drawn buffer (double-buffering)
**Demos** — Demoscene coders exploit every blitter trick: interleaved bitplane blits, fill-mode for filled vector polygons, line-mode for wireframes, and careful DMA scheduling to run blitter and CPU in parallel.
**Applications** — Workbench uses `BltBitMap()` for window dragging, scrolling text, and refreshing damaged screen areas. The `layers.library` damage repair system depends entirely on blitter operations.
---
## AGA Enhancements
AGA's Alice chip extends the blitter with a **64-bit data bus mode** controlled by the `FMODE` register. This allows the blitter to fetch 2 or 4 words per DMA cycle, dramatically increasing fill and copy throughput for large bitmap operations.
## FMODE Configuration
`FMODE` ($DFF1FC) controls blitter, bitplane, and sprite DMA fetch widths independently:
```
bits 9-8: BLT_FMODE — blitter fetch mode
00 = 16-bit (OCS compatible)
01 = 32-bit
10 = 64-bit
11 = reserved
bits 13-12: BPL_FMODE — bitplane fetch mode (same encoding)
bits 15-14: SPR_FMODE — sprite fetch mode (same encoding)
```
Setting 64-bit blitter mode:
```asm
move.w #$0300, $DFF1FC ; BLT_FMODE = 10 (64-bit)
```
> [!IMPORTANT]
2026-04-26 14:46:18 -04:00
> FMODE must be set **before** loading blitter registers and starting the blit. Changing FMODE mid-blit causes undefined behavior.
## Width Calculation with FMODE
When using wider fetch modes, **BLTSIZE widths must be adjusted**:
| FMODE | Width unit | Width formula |
|---|---|---|
| 1× (16-bit) | 1 word = 16 bits | `width_in_words` |
| 2× (32-bit) | 2 words = 32 bits | `(width_in_words + 1) / 2` |
| 4× (64-bit) | 4 words = 64 bits | `(width_in_words + 3) / 4` |
Example: blitting 320 pixels wide (20 words):
- 1× mode: BLTSIZE width = 20
- 2× mode: BLTSIZE width = 10
- 4× mode: BLTSIZE width = 5
**Modulo values are still in bytes** regardless of FMODE.
## Performance Comparison
For a typical 320×200 blit (simple copy, 1 bitplane):
| Mode | FMODE | Approx time (7 MHz) |
|---|---|---|
| OCS/ECS | 1× | ~1.8 ms |
| AGA 2× | 2× | ~0.9 ms |
| AGA 4× | 4× | ~0.45 ms |
## Alignment Requirements
Wider fetch modes impose alignment constraints on source/destination pointers:
| FMODE | Required alignment |
|---|---|
| 1× | 2 bytes (word) |
| 2× | 4 bytes (long) |
| 4× | 8 bytes (quadword) |
Misaligned pointers with 2× or 4× FMODE produce incorrect blit results.
## Using graphics.library
The OS `BltBitMap()` / `BltBitMapRastPort()` calls are FMODE-aware in OS 3.1+ on AGA hardware:
```c
BltBitMap(src_bm, srcx, srcy, dst_bm, dstx, dsty, width, height,
0xC0, 0xFF, NULL); /* minterm $C0 = copy, all planes */
```
`graphics.library` automatically selects the optimal FMODE for the current hardware.
## BLTCON0 / BLTCON1 — Unchanged in AGA
The minterm logic (`BLTCON0`) and fill/line mode (`BLTCON1`) registers are functionally identical to OCS/ECS. AGA only adds bandwidth, not new logical capabilities.
## Direct AGA Blitter Example (64-bit clear)
```asm
; Clear 320×256 bitmap at address $100000 (20 words wide, 256 lines)
; Using AGA 4× FMODE (5 quads wide)
move.w #$0300, $DFF1FC ; FMODE: BLT_FMODE = 4×
move.w #$0100, BLTCON0+custom ; USE D only, minterm $00 (fill with zero)
move.w #$0000, BLTCON1+custom
move.w #$FFFF, BLTAFWM+custom ; first word mask
move.w #$FFFF, BLTALWM+custom ; last word mask
move.l #$00100000, BLTDPTH+custom+$00 ; dest high word
; (split into high/low)
move.w #$0010, BLTDPTH+custom
move.w #$0000, BLTDPTL+custom
move.w #0, BLTDMOD+custom ; modulo = 0 (contiguous)
; BLTSIZE = (256 lines << 6) | 5 quads width = (256*64)|5 = $4005
move.w #((256<<6)|5), BLTSIZE+custom ; start blit
; wait for completion
WaitBlit:
btst #6, DMACONR+custom+1
bne.s WaitBlit
; Restore FMODE to 1× for safety
move.w #$0000, $DFF1FC
```
## References
- ADCD 2.1 Hardware Manual — AGA blitter section
- NDK39: `hardware/blit.h`, `hardware/custom.h`
- Commodore A1200/A4000 Technical Reference Manuals — Alice section
- graphics.library Autodocs: BltBitMap, BltClear