チップセットアーキテクチャ
Amigaの強さはカスタムチップセットにあった――3つの専用チップが グラフィックス、サウンド、DMAをCPUから独立して処理していた。Motorola 68000が コードを実行する一方で、カスタムチップがマシンを動かしていた。
RAM
Agnus(後にFat Agnus、さらにAlice)はカスタムチップセットの頭脳だった。 DMAを制御し――他のすべてのチップがCPUに負担をかけずにデータを 読み取れるようメモリアクセスを管理していた。Copper(映像ビームに同期して ハードウェアレジスタを書き換えるプログラマブルコプロセッサ)とBlitter (高速メモリコピー、線描画、塗りつぶし操作のためのハードウェアブロック転送 エンジン)を内蔵していた。
Denise(AGAチップセットではLisa)はすべての映像出力を担当していた: ビットプレーングラフィックス、ハードウェアスプライト、衝突検出、カラーパレット。 Amigaはプレーナーグラフィックスモデルを採用していた――ピクセルをパックされた値として 格納するのではなく、ピクセルの色の各ビットが別々のビットプレーンから来ていた。 これによりスクロールや特定のエフェクトが非常に効率的だった。
Paulaは4つの独立した8ビットオーディオチャンネル(ハードウェアボリュームと 周期制御付き)、ディスクドライブアクセス、シリアルI/O、割り込み管理を担当していた。 MOD音楽が機能したのは、PaulaのDMAチャンネルがチップRAMから波形サンプルを 連続的に読み取る一方でCPUが他の処理を行えたからだ――音楽は文字通り 自分自身で演奏していた。
CIA 8520(×2)――Complex Interface Adapter。CIA-Aは$BFE001に配置され、
キーボード、ゲームポートの発射ボタン、電源LED、オーディオローパスフィルタを
担当していた。CIA-Bは$BFD000に配置され、パラレルポート、シリアル制御線、
ディスクドライブ信号を担当していた。各CIAには2つの16ビットタイマーと
24ビット時刻カウンタが内蔵されていた。
メモリマップ
68000の24ビットアドレスバスは16 MBのアドレス空間を提供していた。すべての ハードウェアには固有の場所があった。メモリアドレスへの書き込みは、マップ上の 位置に応じてデータの格納、グラフィックスの描画、サウンドの再生、 電源LEDの切り替えのいずれかを行った。
電源投入時、CIA-Aのオーバーレイビットがアドレス$000000にROMをマッピングし、
CPUがリセットベクタを読めるようにする。Kickstartが最初に行うことの一つが
このビットをクリアすることで、チップRAMを$000000に入れ替え、ROMを$F80000に
戻す。exec.libraryのジャンプテーブルアーキテクチャにより、ライブラリベースからの
固定された負のオフセットでOS関数を呼び出すことができた――何度も夜を費やして
探究した仕組みだ。
CIA-Aレジスタ
このサイトの名前の由来となったレジスタ。CIA-Aは$BFE001から始まる奇数
アドレスに配置されている(2つのCIAは奇数/偶数アドレスデコーディングを使って
同じ領域を競合なく共有している)。
ビット1が主役。ローにするとパワーLEDが点灯し、オーディオローパスフィルタが 有効になる。Amiga 500ではハードな切り替えだった。Amiga 2000以降では LEDがディミングし――フィルタは約3.3 kHz以上の周波数を滑らかに減衰させた。 ゲームではトンネルを通過するような効果をシミュレートするために切り替えていた: こもった音はソフトウェア処理ではなく、ハードウェアフィルタによるものだった。
命令MOVE.b #$02,$BFE001はビット1をセットし他のすべてをクリアする
――LEDを消灯し、フィルタを無効にする。他のビットに影響を与えずにLEDだけを
切り替えるには、レジスタを読み取り、ビット1をXORし、書き戻す:
BCHG #1,$BFE001。
キーボードはCIA-Aのシリアルポート機構を通じて読み取られた。キー押下ごとに 8ビットのスキャンコードが生成され、KDAT線を介してシリアルに送信され、 KCLKでクロックされた。CIAがビットをシフトインし、1バイト受信完了時に 割り込みを発生させた。Amigaのキーボードは独自のマイクロコントローラを搭載し、 ハンドシェイクプロトコルを実行していた――ホストは次のキーコードが送信される前に 各キーコードを確認応答する必要があった。
CIA-Bレジスタ
CIA-Bは$BFD000から始まる偶数アドレスに配置されている。CIA-Aがユーザー側
(キーボード、LED、ジョイスティックボタン)を向いていたのに対し、CIA-Bは
ペリフェラル側――パラレルポート、フロッピードライブ制御、シリアルハンドシェイク
を担当していた。
CIA-BのポートB($BFD100)はパラレルポートの8本のデータ線を搭載していた
――ビットごとに直接マッピングされていた。$BFD300のデータ方向レジスタが
各線の入力/出力を制御し、ポートを完全な双方向に対応させていた。
2つのCIAはアドレス範囲$A00000〜$BFFFFFを巧妙なトリックで共有していた:
CIA-Aは奇数アドレスのみに応答し(68000の下位データバイトにバイト整列)、
CIA-Bは偶数アドレスのみに応答した。アドレスデコーダのGaryがアドレス線A12を
使って両者を選択し、チップセレクト信号を直接駆動していた。これにより、
両方に同時にアクセスすることは不可能だった。
各CIAの2つの16ビットタイマーは、ワンショットまたは連続モードで動作し、 システムクロックパルスや外部イベントをカウントし、アンダーフロー時に割り込みを 発生させることができた。24ビット時刻カウンタは電源周波数(PAL 50 Hz、 NTSC 60 Hz)でクロックされ、タイマーを消費せずにリアルタイムの計時を提供した。
DMAシステム
AmigaのDMAシステムがその性能の鍵だった。68000は一度に一つのことしかできなかったが、 カスタムチップはCPUの介入なしに25のDMAチャンネルを通じて独立にチップRAMの 読み書きを行えた――すべてAgnusが管理していた。
各走査線は227.5カラークロック(PAL)に分割されていた。各カラークロックには 偶数サイクルと奇数サイクルの2つのバスサイクルが含まれていた。Agnusはこれらの サイクルを固定優先順位で異なるDMAチャンネルに割り当てた。CPUは残りの サイクルを使用した。
優先順位(最高から):ディスク、オーディオ、スプライト、ビットプレーン、 Copper、Blitter、CPU。実際には、通常のロー解像度表示でCPUは約40〜60%の バスサイクルを使用できた。6ビットプレーンのハイレゾ表示は非常に多くのサイクルを 消費し、CPUは事実上枯渇した。
DMAOCONはカスタムチップレジスタ全体で使われるSET/CLR方式を採用していた:
ビット15をセットして書き込むと指定ビットがオンになり、ビット15をクリアして
書き込むと指定ビットがオフになった。これにより、先にレジスタを読む必要がある
リード・モディファイ・ライトの競合状態を回避できた。例えば、
MOVE.w #$8380,$DFF096はマスターDMA、ビットプレーンDMA、Copper DMAを
他に影響を与えずに有効にした。
割り込み
Amigaは68000の7つの優先レベルにマッピングされた14の割り込みソースを持っていた。 Paulaが割り込み要求レジスタとイネーブルレジスタを管理し、すべてのソースを CPUのIPL線に統合していた。
INTENA($09A書き込み、$01C読み取り)も同じレイアウトだった。割り込みが
実際にCPUに届くには、要求ビットとイネーブルビットの両方がセットされ、
さらにマスターイネーブル(ビット14)もセットされている必要があった。
割り込みハンドラは復帰前にINTREQの要求ビットをクリアしなければならず、
さもないと割り込みが即座に再トリガーされた。
レベル3(INT3)が主力だった――垂直ブランクは50 Hz(PAL)または60 Hz(NTSC)で 毎フレーム実行され、ゲームロジック、音楽再生、OSスケジューリングの標準的な ハートビートとなった。Copper割り込みはプログラムが画面上の特定位置でコードを トリガーすることを可能にし、分割画面エフェクトに不可欠だった。
Copper
CopperはAgnus内蔵のシンプルだが非常に強力なコプロセッサだった。命令は MOVE、WAIT、SKIPの3つだけで、カスタムチップレジスタへの書き込みしかできなかった。 しかし映像ビームと同期して実行されるため、画面上の任意の位置でハードウェア状態を 変更することができた。
CopperリストはチップRAMに格納されたプログラムだった。毎フレーム、Copperは
COP1LC($080/$082)のアドレスからリスタートした。COPJMP1($088)への
書き込みは強制的に即時リスタートさせた。COP2LC/COPJMP2は第2のエントリポイント
を提供し、通常は垂直ブランク割り込みでフレーム間のリスト切り替えに使用された。
典型的なCopperリストはディスプレイを設定した:ビットプレーンポインタのロード、 カラー設定、スクロールレジスタの構成。しかし真の魔法は画面途中の変更にあった。 特定のビーム位置を待ってから新しい値を書き込むことで、Copperは静的な レジスタ設定では不可能なエフェクトを生み出せた――グラデーション空、分割解像度、 走査線ごとのカラーサイクリング、さらにはCPU時間をまったく消費しない ラスターバーまで。
WAIT $FFDFFFFE命令は慣例的なリスト終了マーカーだった。ビーム位置V=255
H=223を待つが、PALでは可視領域を超えていた。Copperはそこで次の垂直ブランクが
リスタートさせるまで停滞した。
Copperが$07Fより上のレジスタ(カラーレジスタやスプライトレジスタ)に
書き込むには、COPCON($02E)のビット1――「Copper danger」ビット――をセット
する必要があった。これによりCopperがDMACONやディスクポインタなどの重要な
レジスタを誤って変更することを防いでいた。
プレイフィールド
Amigaはプレーナーグラフィックスモデルを採用していた。各ピクセルをパックされた カラー値として格納する代わりに、画像は最大6つのビットプレーンに分割された ――各ビットプレーンが各ピクセルのカラーインデックスの1ビットを保持した。 これによりスクロールや特定のBlitter操作が非常に効率的になったが、 ピクセル操作はより複雑になった。
ディスプレイウィンドウが可視領域を定義した。DIWSTRT($08E)が開始位置、
DIWSTOP($090)が終了位置を設定し、両方ともビーム座標で指定した。
標準的なPAL値は320×256表示で$2C81(開始)と$2CC1(終了)だった。
データフェッチタイミングはディスプレイウィンドウとは別だった。DDFSTRT($092)
とDDFSTOP($094)がAgnusのビットプレーンデータ読み取り開始・停止を制御した。
標準ロー解像度:DDFSTRT = $0038、DDFSTOP = $00D0。
ハイレゾ:DDFSTRT = $003C、DDFSTOP = $00D4。
各ビットプレーンにはポインタペア(BPL1PTH/Lの$0E0/$0E2から
BPL6PTH/Lの$0EC/$0EEまで)があり、チップRAM内のデータを指していた。
各走査線の後、ポインタにモジュロ値が加算された――BPL1MOD($108)が
奇数ビットプレーン用、BPL2MOD($10A)が偶数ビットプレーン用。モジュロを
表示幅に設定するとビットプレーンが自然にラップし、より大きな値を設定すると
行をスキップしてスムーズな垂直スクロールが可能になった。
水平スクロールはBPLCON1($102)で実現された。プレイフィールド1と
プレイフィールド2に独立した4ビットの遅延値を保持していた。データフェッチ開始と
ビットプレーンポインタの調整と組み合わせることで、CPU負荷ゼロのピクセル精度
スムーズスクロールが可能になった――ハードウェアがすべてを処理した。
スプライト
Amigaには8つのハードウェアスプライトがあり、各スプライトは幅16ピクセル、 高さは任意で、3色+透過をサポートした。プレイフィールドとは完全に独立しており、 DMAが設定されると、ビットプレーン表示の上(または後ろ)にDeniseが描画した ――CPUオーバーヘッドはゼロだった。
各スプライトにはポインタペア(SPR0PTH/Lの$120/$122から
SPR7PTH/Lの$13E/$13Fまで)があり、チップRAM内のスプライトデータを指していた。
データフォーマットはシンプルだった:
スプライトはペア(0+1、2+3、4+5、6+7)でアタッチできた。アタッチ時、 2つのスプライトのビットプレーンを結合して4ビットプレーンの単一スプライトとなり、 15色+透過を実現した――代わりに8つの独立スプライトが4つに減少した。
プレイフィールドに対するスプライトの優先度はBPLCON2($104)で制御された。
各スプライトペアは2つのプレイフィールドの前面、間、または背面に配置できた。
マウスポインタは伝統的にスプライト0だった。
Blitter
BlitterはAgnus内蔵のハードウェアブロック転送エンジンで、3つの操作のために設計 されていた:バルクメモリコピー(論理演算付き)、エリアフィル、線描画。 チップRAMの矩形領域を68000では不可能な速度で操作した。
Blitterには4つのDMAチャンネルがあった:A、B、Cがデータソース、 Dが出力先。処理される各ワードについて、3つのソース値がプログラマブルな 論理関数(ミンターム)を通じて結合され、出力が生成された。この単一の メカニズムで、単純なコピーからクッキーカットスプライト描画まですべてを処理した。
ミンタームバイトはブール関数を真理値表としてエンコードした:各ビット位置が
A、B、C入力の組み合わせに対応した。例えば、$F0 = Aをコピー(D=A)、
$CA = クッキーカット(D=AC+BC̄、つまりCがセットの箇所はA、クリアの箇所はB)、
$00 = ゼロクリア。
Blitterのエリアフィルモードはラインごとに右から左へ動作した。キャリービットを 追跡し、入力のセットビットに遭遇するたびにトグルした――境界ピクセルペア間の 空間を塗りつぶした。包含的フィル(IFE)は出力に境界ピクセルを残し、 排他的フィル(EFE)はそれらを除去した。これにより塗りつぶしポリゴンの描画が 簡単になった:線描画モードでアウトラインを描き、単一のBlitterパスで塗りつぶす。
線描画はハードウェアBresenhamアルゴリズムを使用した。画面は8つのオクタント (0〜7)に分割され、プログラマが線がどのオクタントに属するかを計算し、 BLTCON1のSUD/SUL/AULビットを設定した。Blitterは最大1024ピクセルの線を描画でき、 破線やテクスチャ線用の16ビット繰り返しパターンをオプションで使用できた。
BLTSIZE($058)が操作を開始した:ビット15〜6が高さ(行数)、ビット5〜0が
幅(ワード単位)。BLTSIZEへの書き込みがBlitterをトリガーした――Blitter設定
シーケンスで常に最後に書き込むレジスタだった。
オーディオ
Paulaは4つの独立した8ビットPCMオーディオチャンネルをハードウェアDMA付きで 提供していた。チャンネル0と3は左スピーカー、チャンネル1と2は右スピーカーに ルーティングされた。各チャンネルはチップRAMから波形サンプルを連続的に読み取り、 DACに供給した――音楽はCPUの介入なしに自動再生された。
チャンネル1〜3はオフセット$0B0、$0C0、$0D0に同じレジスタを持っていた。
周期レジスタが再生レートを設定した。PALシステムクロックは3.546895 MHz。 サンプルレート8000 Hzの場合:周期 = 3546895 / (2 × 8000) ≈ 222。 最小実用周期は約124(28.6 kHz)だった――これ以下ではオーディオDMAが バスサイクルを消費しすぎてディスプレイが枯渇した。
Paulaはチャンネルモジュレーションもサポートしていた:1つのチャンネルが
ペア内の次のチャンネルの周期やボリュームを変調できた(0→1、2→3)。
ADKCON($09E)のビット4〜7がこれを制御した。周期変調はFMライクな合成エフェクト
を可能にし、ボリューム変調は振幅変調(トレモロ)を可能にした。これらのモードは
トラッカー音楽では稀にしか使われなかったが、一部のデモエフェクトで登場した。
チャンネルがバッファの再生を完了すると(AUDxLENワードを使い果たすと)、 オーディオ割り込み(INTREQのAUD0〜AUD3)がトリガーされた。割り込みハンドラは 次のバッファを設定でき、ダブルバッファリングのストリーミングオーディオを可能にした。 MODプレーヤーはこの仕組みを利用していた:各チャンネルの割り込みが次のサンプルセット を指し、CPUはミキシングとエフェクトの適用に時間を費やした。
シリアルポート
PaulaにはシリアルLI通信用のUART(Universal Asynchronous Receiver/Transmitter) が内蔵されていた。DB25 RS-232コネクタがデータ線を搬送し、CIA-Bがハンドシェイク 信号(DTR、RTS、CTS、DSR、CD)を処理した。
ボーレートはSERPERを使って以下の式で設定された:
SERPER = (clock / baud_rate) − 1、ここでclock = 3,579,545 Hz。
9600ボー:SERPER = (3579545 / 9600) − 1 ≈ 372 = $0174。
4800ボー:SERPER ≈ 745 = $02E9。
UARTは2つの割り込みを生成した:TBE(送信バッファ空、INTREQビット0、レベル1)は 次のバイトの準備完了時、RBF(受信バッファフル、INTREQビット11、レベル5)は バイト到着時に発生した。rawモード(ハンドシェイク無視)では、Amigaは約292 Kbaud に達することができた――標準RS-232レートをはるかに超えていた。
ディスクコントローラ
Paulaのディスクコントローラは、DMAを使ってチップRAMとフロッピードライブ間で 生のMFMエンコードデータを転送した。CIA-Bが機械的信号(モーター、ステップ、方向、 サイド選択)を制御し、Paulaがデータストリームを処理した。
トラックを読むためのプログラミングシーケンス:
- 書き込み操作が進行中でないことを確認(DSKLENを確認)
- DSKPTH/Lをバッファアドレスに設定
- DSKLENに転送長とDMAENセットを書き込む
- DSKLENに再度書き込む(安全策:DMA開始に2回の書き込みが必要)
- DSKBLK割り込み(INTREQビット1)を待つ
- DSKLENをクリアしてDMAを停止
書き込みシーケンスにはさらなる安全策があった:WRITEビットをセットしたDSKLENを 2回書き込まないと書き込みが始まらなかった。これにより、1回の誤書き込みによる ディスク破壊を防いだ。
ADKCON($09E)はMFM/GCRエンコーディング選択、プリコンペンセーションタイミング、
およびDSKSYNC内の同期ワードを待ってから転送を開始するWORDSYNCモードを制御した。
標準Amiga 3.5インチDDドライブはディスクあたり880 KBを格納:80トラック × 2面 ×
11セクタ × 512バイト。
キーボード
Amiga 500のキーボードには独自の6500/1マイクロコントローラが内蔵されていた。 キーマトリックスを独立にスキャンし、2線プロトコルでCIA-Aに8ビットスキャンコードを シリアル送信した:KDAT(データ)とKCLK(クロック)。
プロトコルはアクティブロー、MSBファーストだった。完全な1バイトを送信した後、 キーボードはホストがKDATを最低85マイクロ秒ローに引くことで確認応答するのを待った。 このハンドシェイクなしでは、キーボードは次のキーコードを送信しなかった ――組み込みのフロー制御を提供していた。
スキャンコードのフォーマット:ビット7 = 0でキー押下、1でキーリリース。 ビット6〜0がキーIDをエンコード。生コードは位置ベースであり、ASCIIではなかった ――OSのキーマップが文字に変換した。
特殊な3キーの組み合わせ(Ctrl + Amiga + Amiga)は/KBRESET線をアサートして ハードリセットをトリガーした。この線はシステムリセット回路に直接配線されていた。 これはすべてのAmigaユーザーが本能的に知っていた悪名高い「三本指の敬礼」だった。
キーボードは電源投入時キーストリームも送信した:起動時のコードシーケンスで、 キーボードの種類と言語レイアウトを識別した。システムはタイムアウト期間内に このストリームをチェックすることでキーボードの存在を検出できた。
コネクタ
Amiga 500の背面パネルには、それぞれ特定の目的を持つコネクタが並んでいた:
底面の86ピン拡張コネクタは68000のアドレスバスとデータバス、制御信号への完全な アクセスを提供した。アクセラレータボード、RAM拡張、CPUバスへの直接アクセスが 必要なあらゆるアドオンへのゲートウェイだった。それはAmigaの最大の強みであり 限界でもあった――完全にオープン、完全に無防備、完全に信頼ベース。
カスタムチップレジスタマップ
すべてのカスタムチップレジスタは$DFF000から始まる512バイトのブロックに
格納されていた。オフセット(例:DMAOCONの$096)がこのベースアドレスに加算された。
レジスタは読み取り専用(R)、書き込み専用(W)、またはストローブ(S ——
任意の値の書き込みでアクションがトリガーされる)のいずれかだった。一部のレジスタ
ペアは読み取りと書き込みで異なる値のためにアドレスを共有していた。
詳細ページ
各サブシステムには、完全なレジスタドキュメント、命令エンコーディング、プログラミング例を含む専用の詳細ページがある――Bible de l'Amigaから翻訳。