サブページ
$DFF040

Blitterの概要

Blitter(Block Image Transferrer)は、Agnusチップに内蔵された専用ハードウェアユニットで、メモリブロックのコピーと結合を高速に実行する。毎秒1600万ピクセル以上を処理でき、68000 CPUのソフトウェア処理をはるかに上回る速度である。

Blitterには3つの主要動作モードがある。

  • データコピーと論理結合 — 最大3つのソースチャンネルを256種類のブール関数で結合しながらメモリブロックを転送
  • 面塗りつぶし — 単一ピクセル幅のエッジで囲まれた領域を塗りつぶす
  • 直線描画 — Bresenhamアルゴリズムのハードウェア実装により毎秒100万ピクセルで直線を描画

AmigaOSは事実上すべてのグラフィック操作にBlitterを使用する:テキスト描画、ガジェット描画、ウィンドウのスクロール、グラフィカルデータのクリッピングなど。

基本動作

Blitterは矩形メモリ領域(「Blitterウィンドウ」)に対して動作する。最大3つのソースチャンネル — ABC — からデータを読み込み、選択された論理関数に従って結合し、結果をデスティネーションDに書き込む。4つのアドレスはすべてChip RAM($000000〜$07FFFF)内の任意の位置に設定できる。

結合はビット単位で行われる:各ビット位置について、A、B、Cの対応するビットが論理関数に入力され、Dの出力ビットが生成される。

$DFF040

Blitterウィンドウとモジュロ

Blitterウィンドウは1回の操作で処理される矩形メモリ領域を定義する。BLTSIZEレジスタで高さ(ライン数)と幅(ワード数)として指定する。

レジスタ ビット 名前 機能
BLTSIZE 15–6 H9–H0 高さ — 1〜1024ライン(0=1024)
BLTSIZE 5–0 W5–W0 幅 — 1〜64ワード(0=64、最大1024ピクセル)

レジスタ値の計算式:BLTSIZE = 高さ * 64 + 幅

BLTSIZEへの書き込みでBlitterが即座に起動する。 常にBlitter操作で最後にプログラムされるレジスタでなければならない。

ソースとデスティネーションのポインタ

各チャンネルには開始アドレスを保持するポインタレジスタペアがある。

Blitterポインタレジスタ(ライトオンリー)
$DFF050BLTAPTH/L — ソースAポインタ(ビット16–18 / 0–15)
$DFF04CBLTBPTH/L — ソースBポインタ(ビット16–18 / 0–15)
$DFF048BLTCPTH/L — ソースCポインタ(ビット16–18 / 0–15)
$DFF054BLTDPTH/L — デスティネーションDポインタ(ビット16–18 / 0–15)

モジュロ値

Blitterウィンドウが実際のビットマップより小さい場合、モジュロ値が各ライン末尾でスキップするバイト数を指定する。これにより、大きなビットマップの一部分だけをブリットできる。

Blitterモジュロレジスタ(ライトオンリー)
$DFF064BLTAMOD — ソースAモジュロ(バイト、符号付き)
$DFF062BLTBMOD — ソースBモジュロ(バイト、符号付き)
$DFF060BLTCMOD — ソースCモジュロ(バイト、符号付き)
$DFF066BLTDMOD — デスティネーションDモジュロ(バイト、符号付き)

例えば、10ワード幅のグラフィックを20ワード幅のビットプレーンにコピーする場合:ソースモジュロは0(グラフィックの幅がBlitterウィンドウと同じ)、デスティネーションモジュロは(20 - 10) * 2 = 20バイトとなる。

$DFF040

ミンターム(論理関数)

BlitterによるソースA、B、Cの論理結合はミンタームと呼ばれる8ビット(LF0〜LF7)で制御される。これらのビットは8つの入力組み合わせのどれが出力ビットDで1を生成するかを選択する。選択されたすべてのミンタームの結果がOR結合される。

ビット ミンターム 入力ABC 等式(真のとき1)
LF7 ABC 111 A AND B AND C
LF6 ABc 110 A AND B AND (NOT C)
LF5 AbC 101 A AND (NOT B) AND C
LF4 Abc 100 A AND (NOT B) AND (NOT C)
LF3 aBC 011 (NOT A) AND B AND C
LF2 aBc 010 (NOT A) AND B AND (NOT C)
LF1 abC 001 (NOT A) AND (NOT B) AND C
LF0 abc 000 (NOT A) AND (NOT B) AND (NOT C)

よく使うミンターム値

  • D = A(単純コピー):LF7–LF0 = $F0(11110000)。B、Cに関係なくA=1のときD=1。
  • D = NOT A(反転):LF7–LF0 = $0F(00001111)。
  • D = A OR B(ビットプレーンへのグラフィック重ね描き):LF7–LF0 = $FC(11111100)。
  • D = A AND B(マスク):LF7–LF0 = $C0(11000000)。
  • クッキーカット(D = AB + aC、マスク付きブリット):LF7–LF0 = $CA

使用しないソースチャンネルは、そのDMAを無効にし(BLTCON0のUSEx=0)、ミンタームがDに影響しないようにする。

$DFF040

シフトとマスク

バレルシフタ

BlitterはソースABのデータを0〜15ビット右にシフトできるバレルシフタを備えている。これにより、ワード境界だけでなく任意のピクセル位置にグラフィックスを正確に配置できる。

シフトはライン全体に適用され、1ワードからシフトアウトしたビットは次のワードに入る。この操作に追加時間は不要で、シフト量に関係なくBlitterは最高速度で動作する。

シフト値は制御レジスタの上位4ビットに格納される。 - ASH3–ASH0(BLTCON0ビット15–12):ソースAのシフト量 - BSH3–BSH0(BLTCON1ビット15–12):ソースBのシフト量

先頭・末尾ワードマスク

グラフィックの端がワード境界に合わない場合、ソースAの先頭ワードマスク末尾ワードマスクで各ラインの先頭と末尾の不要なビットを選択的にマスクできる。

Blitterマスクレジスタ(ライトオンリー)
$DFF044BLTAFWM — ソースA先頭ワードマスク(ビット0–15)
$DFF046BLTALWM — ソースA末尾ワードマスク(ビット0–15)

マスクでセットされたビットのみが通過し、マスクされたビットは0に強制される。Blitterウィンドウが1ワード幅の場合、両方のマスクが同時に適用される(AND結合)。

$DFF040

制御レジスタ

BLTCON0($DFF040、ライトオンリー)

ビット 名前 機能 説明
15–12 ASH3–ASH0 ソースAシフト ソースAデータの右シフト量(0–15)
11 USEA A DMA有効 ソースAのDMAチャンネルを有効化
10 USEB B DMA有効 ソースBのDMAチャンネルを有効化
9 USEC C DMA有効 ソースCのDMAチャンネルを有効化
8 USED D DMA有効 デスティネーションDのDMAチャンネルを有効化
7–0 LF7–LF0 ミンターム 論理関数の選択(上記参照)

USExビットが0の場合、対応するDMAチャンネルは無効になる。Blitterはそのチャンネルのデータレジスタ(BLTxDAT)に最後に書き込まれた値を再利用する。CPUでBLTxDATに値を書き込み、そのチャンネルのDMAを無効にしてBlitterを実行することで、メモリをパターンで塗りつぶすことができる。

BLTCON1($DFF042、ライトオンリー)

ビット 名前 機能 説明
15–12 BSH3–BSH0 ソースBシフト ソースBデータの右シフト量(0–15)
11–5 未使用 コピーモードでは0
4 EFE 排他的塗りつぶし 排他的塗りつぶしモードを有効化
3 IFE 包括的塗りつぶし 包括的塗りつぶしモードを有効化
2 FCI フィルキャリー初期値 フィルキャリービットの初期値
1 DESC 降順モード アドレスを降順で処理
0 LINE 直線描画モード 直線描画モードを有効化(コピー/塗りつぶし時は0)

昇順モード vs 降順モード

昇順モード(DESC=0、デフォルト)では、BlitterはBLTxPTから開始し各ワード後にアドレスをインクリメントする。降順モード(DESC=1)では、BLTxPTから開始しデクリメントする。降順モードはソース領域とデスティネーション領域が重なり、デスティネーションがより高いアドレスにある場合に不可欠である。

モード選択のルール: - 重なりなし:どちらのモードでも正常に動作 - デスティネーションがソースの前:昇順モードのみ - デスティネーションがソースの後:降順モードのみ

降順モードでは、BLTxPTは領域の最後のワード(右下隅)を指す必要がある。

$DFF040

面塗りつぶし

Blitterは各ラインを右から左にスキャンし、セットされたピクセルごとにフィルキャリー(FC)ビットをトグルすることで、囲まれた領域を塗りつぶせる。2つのセットされたピクセル間のすべてのピクセルが塗りつぶされる。

塗りつぶしアルゴリズム:各ラインの最右ビットから開始し、FCビットは初期値0(またはBLTCON1のFCI=1の場合は1)に設定される。各入力ビットについて: - 入力ビットが0の場合、出力は現在のFC値を取る - 入力ビットが1の場合、FCビットがトグル(反転)される

1ラインに奇数個の境界ピクセルがあると塗りつぶしエラーが発生し、ラインの端まで「漏れる」。

包括的 vs 排他的塗りつぶし

  • 包括的塗りつぶし(IFE=1):境界ピクセルが出力に保持される。塗りつぶし領域は両端を含む。
  • 排他的塗りつぶし(EFE=1):左境界ピクセル(FCが1から0に遷移する箇所)がクリアされる。これにより1ピクセル幅の塗りつぶし領域が可能になる。

塗りつぶしの要件

  • 降順モードを使用(DESC=1)— Blitterは右から左に塗りつぶすため、ワードを高アドレスから低アドレスの順で処理する必要がある
  • LINEは0
  • ソースデータには適切な単一ピクセル幅の境界線が必要
  • BLTSIZEは塗りつぶすグラフィックのサイズに設定

塗りつぶし速度はコピー速度と同等:毎秒最大1600万ピクセル。

$DFF040

直線描画

Blitterはハードウェア実装のBresenhamスタイルアルゴリズムを使用して、毎秒100万ピクセルで直線を描画できる。2つの端点を単純に与えるのではなく、直線の傾きと方向を定義する事前計算値が必要となる。

オクタント

始点から終点への方向は8つのオクタントの1つに分類される。3つの比較でオクタントが決定される:

  1. X2 >= X1か?(左右の判定)
  2. Y2 >= Y1か?(上下の判定)
  3. DeltaX >= DeltaYか?(主軸の判定)

各オクタントは3つの制御ビットで構成される3ビットコードに対応する。

オクタント 条件 SUD/SUL/AUL コード
0 X1<=X2, Y1<=Y2, dX>=dY 1/1/0 6
1 X1<=X2, Y1<=Y2, dX<=dY 0/0/1 1
2 X1>=X2, Y1<=Y2, dX<=dY 0/1/1 3
3 X1>=X2, Y1<=Y2, dX>=dY 1/1/1 7
4 X1>=X2, Y1>=Y2, dX>=dY 1/0/1 5
5 X1>=X2, Y1>=Y2, dX<=dY 0/1/0 2
6 X1<=X2, Y1>=Y2, dX<=dY 0/0/0 0
7 X1<=X2, Y1>=Y2, dX>=dY 1/0/0 4

傾きの計算

Pdelta = min(DeltaX, DeltaY)、Gdelta = max(DeltaX, DeltaY) とする。Blitterには以下が必要:

  1. 2 * Pdelta(BLTBMODに書き込む)
  2. 2 * Pdelta - Gdelta(BLTAPTLに書き込む)
  3. 2 * Pdelta - 2 * Gdelta(BLTAMODに書き込む)

SIGNフラグ(BLTCON1のビット6)は2 * Pdelta < Gdeltaのとき1にセットする。

直線モードのレジスタ設定

直線モードのBlitterレジスタ
BLTAPTL2 * Pdelta - Gdelta(初期誤差項)
BLTAMOD2 * Pdelta - 2 * Gdelta
BLTBMOD2 * Pdelta
BLTCPT / BLTDPTビットプレーン内の開始ピクセルのアドレス
BLTCMOD / BLTDMODビットプレーンの幅(バイト単位、例:320ピクセル表示で40)
BLTADAT$8000(ビット15に単一ピクセル)
BLTBDAT直線パターンマスク(例:$FFFFで実線)
BLTAFWM$FFFF
BLTSIZE幅=2、高さ=直線の長さ(Gdelta + 1)

直線モードのBLTCON0:ビット15–12 = START位置(X1 AND $F)、ビット11–8 = $B(USEA=1, USEB=0, USEC=1, USED=1)、ビット7–0 = $CA(ミンターム D = aC + AB)。

直線モードのBLTCON1:ビット15–12 = STARTと同値(テクスチャ整列用)、ビット6 = SIGN、ビット4–2 = SUD/SUL/AUL、ビット1 = SING(塗りつぶし境界用に水平ライン1ピクセルのみ)、ビット0 = LINE = 1。

BLTBDATの直線パターンで破線や点線が描ける。$FFFFで実線、$FF00のようなパターンで破線になる。

$DFF040

DMAとステータス

Blitterは4つのDMAチャンネル(ソース/デスティネーション各1つ)を使用し、DMACONBLTENビット(ビット6)で制御される。4チャンネルすべてが同時に有効化される。

Blitterデータレジスタ
$DFF000BLTDDAT — デスティネーションデータ出力(リードオンリー)
$DFF070BLTCDAT — ソースCデータレジスタ
$DFF072BLTBDAT — ソースBデータレジスタ
$DFF074BLTADAT — ソースAデータレジスタ

DMAコンステータスビット

DMACONR($DFF002)の3つのリードオンリービットがBlitterの状態を報告する。

  • ビット14 — BBUSY:Blitter動作中に1にセットされる。BLTSIZEへの書き込み後にBBUSYがセットされ、操作完了時にクリアされる。同時にBlitter完了割り込み(INTREQビット6)がトリガーされる。

  • ビット13 — BZERO:最後の操作ですべての出力ビットがゼロだった場合に1にセットされる。衝突検出に有用:2つのソースが重なった場合のみD=1となるようミンタームを設定し、USEDを無効にして(書き込み回避)、完了後にBZEROを確認する。BZERO=0なら少なくとも1ピクセルが重なっている。

  • ビット10 — BLTPRI:セットすると、Blitterが68000 CPUに対して絶対的なバス優先権を持つ(Blitter nastyモード)。Blitterのスループットは最大化されるが、完了までCPUは完全に停止する。

Blitterの完了待ち

新しいBlitter操作を開始する前に、前の操作が完了していることを必ずBBUSYをポーリングして確認する。

.wait:
    btst    #6,$DFF002     ; DMAコンRのBBUSYをテスト
    bne.s   .wait          ; Blitterがアイドルになるまでループ