サブページ
CIAの概要
Amigaは、カスタムチップDMAの速度を必要としない周辺I/O用に、2つのMOS 8520 Complex Interface Adapter(CIA)を使用する。8520はCommodore 64で知られる6526の派生型で、レジスタ8〜11のみが異なる(6526のTOD時計がイベントカウンタに置き換えられている)。
各8520は以下を提供する:
- 2つの8ビットプログラマブルパラレルポート(PAとPB)
- 2つの16ビットカウントダウンタイマー(タイマーAとタイマーB)
- アラーム機能付き24ビットイベントカウンタ
- 双方向シリアルシフトレジスタ
- 5つの割り込みソースを持つ割り込み制御レジスタ(ICR)
8520は8ビットの6502ファミリプロセッサ用に設計され、68000とは同期的に通信する。クロックは68000のEクロック、約716kHz。
2つのCIA
アドレス$BFE001――CIA-Aのベース――が本サイトの名前の由来である。キーボード、ディスク状態、ジョイスティックのファイアボタン、電源LEDの状態を確認するためにシステムが最初に読むアドレスである。Amigaプログラマにとって、このアドレスは即座に認識できる存在だ。
CIA-Aはデータバスの下位バイト(D0〜D7)に接続されるため、すべてのレジスタは奇数アドレスに現れる。CIA-Bは上位バイト(D8〜D15)に接続され、レジスタは偶数アドレスに現れる。チップセレクト信号はアドレスラインA12(CIA-A、アクティブロー)とA13(CIA-B、アクティブロー)から導出され、レジスタはアドレスラインA8〜A11をチップ内部のレジスタセレクト(チップ上のA0〜A3)として使用し、256バイト($100)間隔で配置される。
割り込みルーティング
- CIA-AのIRQはPAULAのINT2(PORTS、レベル2割り込み)に接続
- CIA-BのIRQはPAULAのINT6(EXTER、レベル6割り込み)に接続
レジスタマップ
各CIAは16のレジスタを持つ(レジスタ11/$Bは未使用)。256バイト間隔のため、完全なレジスタマップは広いアドレス範囲にまたがる。
パラレルポート
各CIAは2つの8ビット双方向パラレルポート(PAとPB)を持つ。各ビットの方向は対応するデータ方向レジスタ(DDR)で制御される:0ビットはピンを入力に、1ビットは出力に設定する。ポートレジスタの読み取りは、方向設定に関係なく常にピンの実際の状態を返す。
CIA-A ポートA($BFE001)
DDRAのデフォルトは$03(ビット0〜1が出力、ビット2〜7が入力)。/OVLビットはKickstart ROMがアドレス$000000にマップされるか(オーバーレイアクティブ)を制御し、ブートシーケンスで重要な役割を果たす。/LEDビットは電源LEDを直接制御する――おなじみのディスクアクティビティの点滅は、単にソフトウェアがこのビットをトグルしているだけである。
CIA-A ポートB($BFE101)
CIA-AのポートBはパラレル(Centronics)ポートに接続されている。8ビットすべてがプリンタ通信用のデータを伝送する。ハンドシェイク信号PC(/DRDY — データレディ)とFLAG(/ACK — アクノリッジ)が転送を調整する。
CIA-B ポートA($BFD000)
DDRAデフォルト:$C0(ビット6〜7が出力、残りは入力)。
CIA-B ポートB($BFD100)
DDRBデフォルト:$FF(すべて出力)。このポートがフロッピーディスクドライブ機構全体を制御する。
ハンドシェイク(PCとFLAG)
ポートBのデータ転送は2つのハンドシェイク信号で調整できる。PC(ポートコントロール)ピンは、ポートBへのアクセスから3クロックサイクル後にローになり、データが書き込まれたことを通知する。FLAGピンは入力がハイからローに遷移すると発火し、ICRのFLAGビットをセットする。一方のCIAのPCをもう一方のFLAGに接続すると、効率的なハードウェアハンドシェイクが実現する。
CIA-A: SP = KDAT(キーボードシリアルデータ)、CNT = KCLK(キーボードクロック)、PC = /DRDY、FLAG = /ACK。 CIA-B: FLAG = /INDEX(ディスクインデックスパルス)、PCは未使用。
タイマー
各CIAは2つの独立した16ビットカウントダウンタイマーを持つ。タイマーはプリセット値からゼロまでカウントダウンし、ゼロに達するとICRにフラグをセットし、オプションで割り込みを生成する。
タイマーレジスタ
各タイマーは2つの8ビットレジスタを使用する。読み取り時は現在のカウンタ値を返す。書き込み時は値がラッチ(プリスケーラ)に格納され、カウンタには即座にロードされない。
安全なカウンタ読み取り
タイマーは非同期にデクリメントされるため、上位バイトと下位バイトを別々に読むとレースコンディションが発生する可能性がある。例えば、カウンタが$0100の場合、上位バイトの読み取りは$01を返すが、下位バイトの読み取り前にカウンタがデクリメントされると、下位バイトは$FFを返し、不正な値$01FFが得られる。安全な方法は:上位を読み、下位を読み、再度上位を読む。上位バイトが変化していれば、プロセスを繰り返す。
クロックソース
タイマーAはCRAのINMODEビットで制御される2つの入力モードを持つ:
- INMODE = 0:各クロックサイクルでデクリメント(Eクロックから約716kHz)
- INMODE = 1:CNT信号の各正エッジでデクリメント
タイマーBはCRBのビット6〜5で制御される4つの入力モードを持つ:
- 00:クロックサイクル(約716kHz)
- 01:CNT信号の正エッジ
- 10:タイマーAのアンダーフロー(A+Bを32ビットタイマーとして連結)
- 11:CNTハイでゲートされたタイマーAアンダーフロー(CNTパルス幅の測定)
動作モード
RUNMODEビットで選択する:
- 連続モード(RUNMODE = 0):ゼロに達した後、ラッチから再ロードしてカウントを継続
- ワンショットモード(RUNMODE = 1):ゼロに達した後、カウンタが停止しSTARTビットがクリアされる
カウンタのロード
ラッチ値は3つの方法でカウンタに転送される:
- 強制ロード: 制御レジスタのLOADビット(ストローブ)をセットすると、即座にラッチ値がロードされる
- アンダーフロー: カウンタがゼロに達すると自動的にラッチが再ロードされる
- 停止時の自動ロード: タイマーが停止中にタイマー上位バイトに書き込むと自動ロードがトリガーされる
タイマー値を書き込む際は、意図しない自動ロードを避けるため、常に上位バイトを先に、次に下位バイトを書き込むこと。
ポートBへのタイマー出力
各タイマーはオプションでポートBのピンに出力可能:タイマーAはPB6へ、タイマーBはPB7へ。制御レジスタのPBONビットで有効化する。OUTMODEビットで選択:
- パルスモード(OUTMODE = 0):各アンダーフローで1サイクルの正パルス
- トグルモード(OUTMODE = 1):各アンダーフローで出力がトグル
制御レジスタ
制御レジスタA(CRA、レジスタ$E)
制御レジスタB(CRB、レジスタ$F)
Amigaでのタイマー使用
- CIA-A タイマーAはOSがキーボード通信に常時使用
- CIA-A タイマーBは汎用に利用可能
- CIA-B タイマーAはシリアルポートのボーレート生成に使用
- CIA-B タイマーBはBlitterの同期モードで使用
イベントカウンタとシリアルポート
イベントカウンタ(レジスタ$8〜$A)
8520は6526のTOD(Time of Day)時計を単純な24ビットイベントカウンタに置き換えている。0から16,777,215($FFFFFF)までカウントし、TOD入力信号の各正エッジでインクリメントされる。$FFFFFFに達すると0にラップする。
Amigaでは: - CIA-Aのイベントカウンタは電源からの50Hzパルス(商用電源周波数)を受信し、単純な経過時間カウンタとして機能する。 - CIA-Bのイベントカウンタは15,625Hzの水平同期パルスを受信し、高分解能タイミングソースを提供する。
読み書き
カウンタはMSB(レジスタ$A)が読まれたときに値をラッチする。その後のレジスタ$9と$8の読み取りは、内部カウンタが動き続ける間、ラッチされた値を返す。LSB(レジスタ$8)が読まれるとラッチが解放され、次のスナップショットの準備が整う。
書き込み時は、MSBを書き込むとカウンタが停止する。LSBを書き込むと再開する。常にMSBを先に、次にミドルバイト、最後にLSBを書き込むこと。
アラーム機能
CRBのビット7(ALARM)をセットすると、レジスタ$8〜$Aへの書き込みがカウンタ値ではなくアラーム値を設定する。カウンタがアラーム値に達するとICRのAlarmビットがセットされ、割り込みが生成される。レジスタ$8〜$Aの読み取りはALARMビットの状態に関係なく常に現在のカウンタ値を返す。
シリアルシフトレジスタ(レジスタ$C)
シリアルポートはデータレジスタ(SDR)と内部シフトレジスタで構成される。方向はCRAのSPMODEビットで制御される:
入力モード(SPMODE = 0):SPピン上のデータがCNT信号の各正エッジでシフトインされる。8ビット後、シフトレジスタがSDRに転送され、SP割り込みフラグがセットされる。
出力モード(SPMODE = 1):タイマーAがボーレートを制御する。SDRに書き込まれたデータがシフトレジスタに転送され、タイマーA周波数の半分の速度でSPからMSBファーストでクロックアウトされる。CNTピンがクロック信号を出力する。最大出力レートは8520のクロック周波数の4分の1。
CIA-AではSPがキーボードシリアルデータ(KDAT)、CNTがキーボードクロック(KCLK)を伝送する。
割り込み制御レジスタ
ICR(レジスタ$D)は5つの割り込みソースをデュアルレジスタ構造で管理する:データレジスタ(読み取り)とマスクレジスタ(書き込み)で、同じアドレスからアクセスする。
ICRの読み取り(データレジスタ)
ICRを読むとデータレジスタの値が返され、IRを含むすべてのビットがクリアされる。後で値が必要な場合は、読み取り直後にRAMに保存すること。
ICRへの書き込み(マスクレジスタ)
マスクレジスタはDMACONと同じSET/CLR機構を使用する。S/C = 1のとき、書き込み値でセットされたビットがマスクで有効化される。S/C = 0のとき、無効化される。0として書き込まれたビットは影響を受けない。
割り込みは、データレジスタのビットがセットされかつ対応するマスクビットが有効な場合のみ生成される(IRQピンがローになる)。ICRが読まれる(データレジスタがクリアされる)と、IRQラインはハイに戻る。
; CIA-AのタイマーA割り込みを有効化:
MOVE.B #$81,$BFED01 ; S/C=1, TA=1 → マスクでTAを有効化
; 両タイマー割り込みを無効化:
MOVE.B #$03,$BFED01 ; S/C=0, TA=1, TB=1 → マスクでTAとTBをクリア
CIA割り込みの流れ
CIA割り込みが発生すると、以下のシーケンスで処理される:
- ソースがCIAのICRデータレジスタの対応ビットをセット
- 対応するマスクビットがセットされていれば、IRビット(ビット7)がセットされIRQがローになる
- PAULAがIRQを検出し、対応するINTREQビット(CIA-Aはビット3、CIA-Bはビット13)をセット
- INTENAが許可していれば、68000が割り込みを受信
- ハンドラがCIAのICRを読んでソースを特定(CIA側のフラグがクリアされる)
- ハンドラがPAULAのINTREQビットをクリア