サブページ
シリアルポートの概要
Amigaは、Paulaカスタムチップに内蔵されたUART(Universal Asynchronous Receiver/Transmitter)によって管理される標準RS232シリアルポートを搭載している。このポートは全二重通信をサポートし、別々の信号線でデータの送信と受信を同時に行える。
RS232コネクタは2種類の信号を持つ:
- データ信号 — TXD(送信データ)とRXD(受信データ)。実際のシリアルビットストリームを伝送する。
- ハンドシェイク信号 — CTS、RTS、DSR、DTRなど。CIAチップを通じて管理され、CIAのドキュメントで解説済み。
すべてのシリアルデータ転送はTXDとRXDラインで行われる。2台のデバイスを接続する際は、一方のTXDを他方のRXDに、またその逆に配線する(ヌルモデム/クロス配線)。
RS232データフォーマット
各方向のデータは1本のワイヤだけで伝送されるため、バイトをビット単位でシリアル化する必要がある。RS232には独立したクロック信号がないため、送信側と受信側はビットタイミングについて合意しなければならない。これがボーレートであり、1秒あたりの転送ビット数を規定する。一般的なボーレートは300、1200、2400、4800、9600である。
各バイトは以下のようにフレーミングされる:
- スタートビット — アイドル状態(ハイ)からローへの遷移で、バイトの開始を示す。
- データビット — LSBから順に送信。8ビットまたは9ビットフォーマット。
- ストップビット — バイトの終了を示す1つまたは2つのハイビット。
受信側は、前のバイトのストップビットと新しいバイトのスタートビットの間のハイからローへの遷移によって各バイトの開始を検出する。
UARTレジスタ
PaulaのUARTはシリアルデータ転送に3つのレジスタを使用し、さらにADKCONレジスタの1ビットをブレーク制御に使用する。
SERDATR — 受信データとステータス($DFF018、読み取り)
このレジスタは受信データバイトとUARTのステータスフラグの両方を含む。
SERPER — 周期レジスタ($DFF032、書き込み)
データ受信
シリアル受信はシフトレジスタとデータバッファの2段階で行われる。
第1段階:シフトレジスタ
RXDピンに到着するビットは、SERPERで設定されたレートでシフトレジスタにクロックインされる。スタートビットがプロセスを開始する:UARTは各ビット期間の中央でRXDをサンプリングし、パラレルデータワードを再構成する。
第2段階:データバッファ
シフトレジスタが満杯になると(すべてのデータビットとストップビットを受信)、その内容が受信バッファ(SERDATRのデータビット)に転送される。シフトレジスタは直ちに次のバイトの受信を開始できる。
データフォーマット
データ幅はSERPERのLONGビットに依存する:
- LONG = 0(8ビットモード): SERDATRのビット7–0に8ビットのデータ。ビット8にストップビット。ビット9に2番目のストップビット(存在する場合)。
- LONG = 1(9ビットモード): ビット8–0に9ビットのデータ。ビット9にストップビット。
ステータスフラグ
RBF(受信バッファフル)は、完全なデータワードがシフトレジスタからバッファに転送されると1にセットされる。このフラグはINTREQ/INTENのビット11にも存在し、割り込みを生成する。データ読み取り後、ソフトウェアはINTREQに書き込んでRBFをクリアする必要がある:
move.w #$0800,$DFF09C ; INTREQ内のRBFをクリア(SERDATRのRBFもクリアされる)
オーバーラン検出
受信バッファが読み取られる前にシフトレジスタが再び満杯になると、オーバーランが発生する。SERDATRのOVRUNビットが1にセットされ、データが失われたことを示す。最終的にRBFがクリアされると、シフトレジスタの内容がバッファに転送されOVRUNがリセットされる。バッファにシフトレジスタからの(遅延した)データが格納されるため、RBFは直ちに再び1になる。
オーバーランを避けるには、SERDATRの読み取りとRBFのクリアを迅速に行うこと。理想的にはRBF割り込みハンドラ内で処理する。
データ送信
シリアル送信もデータバッファ(SERDAT)と出力シフトレジスタの2段パイプラインを使用する。
データの書き込み
SERDATの送信データフォーマットは、希望するワード長とストップビット数に依存する。データビットはレジスタの下位部分を占め、その直後に1つまたは2つのストップビット(1にセット)が続く。上位ビットはすべて0でなければならない。
8ビットデータ、2ストップビット:
8ビットデータ、1ストップビット:
9ビットデータ、1ストップビット:
SERPERのLONGビットは受信にのみ影響する。送信フォーマットはSERDATに書き込まれた値のみで決定される。
送信ステータスフラグ
TBE(送信バッファエンプティ)は、SERDAT内のデータが出力シフトレジスタに転送されると1にセットされる。バッファは次のワードを受け付ける準備ができる。TBEはINTREQ/INTENのビット0でもある。RBFと同様に、サービス後はINTREQ経由でクリアする必要がある。
TSRE(送信シフトレジスタエンプティ)は、シフトレジスタがすべてのビットの送信を完了し、バッファに新しいデータが待機していないと1にセットされる。これは送信が本当に完了したことを示す。TSREはTBEがクリアされるとリセットされる。
UARTBRK — ブレーク信号
ADKCONレジスタのビット11(UARTBRK)をセットすると、TXD出力ラインがローに強制され、シリアル送信が停止する。これはRS232ライン上に「ブレーク」状態を生成し、リモートデバイスが検出できる。ビットをクリアすると通常動作に復帰する。
ボーレート計算
SERPERの下位15ビット(ビット14–0、RATEフィールド)は、ビット周期をバスクロックサイクル数で指定する。1バスクロックサイクルは約279.365ナノ秒(PALシステムクロック3.546895 MHzに基づく)。
希望するボーレートをSERPER値に変換する公式:
同等の式:
一般的なボーレート
計算値は最も近い整数に丸めてSERPERに書き込む:
move.w #745,$DFF032 ; 4800ボーに設定(NTSC)、LONG=0(8ビット)
9ビット受信モードの場合はビット15をセット:
move.w #$8000+745,$DFF032 ; 4800ボー、LONG=1(9ビット受信)
割り込みとプログラミング
UARTは2つの割り込み信号を生成し、両方ともINTREQ/INTENで管理される:
典型的な受信ハンドラ
SerialReceiveISR:
move.w $DFF018,d0 ; SERDATRを読み取る
btst #15,d0 ; OVRUNをチェック
bne .overrun ; オーバーラン状態を処理
and.w #$00FF,d0 ; 8データビットを抽出
; ... d0の受信バイトを処理 ...
move.w #$0800,$DFF09C ; INTREQ内のRBFをクリア
rte
.overrun:
move.w #$0800,$DFF09C ; RBFをクリアして復旧
; ... オーバーランエラーを通知 ...
rte
典型的な送信シーケンス
SendByte:
; d0.b = 送信するバイト
and.w #$00FF,d0 ; 8ビットにマスク
or.w #$0100,d0 ; 1ストップビットを追加(ビット8 = 1)
move.w d0,$DFF030 ; SERDATに書き込む
; 次のバイト送信可能時にTBE割り込みが発生する
rts
PaulaのUARTはスタートビットの挿入とビットのシリアル化を自動的に処理する。ソフトウェアはデータワード(ストップビット付き)をSERDATに書き込み、次のバイトを送信する前にTBEを待つだけでよい。