サブページ
$DFF030

シリアルポートの概要

Amigaは、Paulaカスタムチップに内蔵されたUART(Universal Asynchronous Receiver/Transmitter)によって管理される標準RS232シリアルポートを搭載している。このポートは全二重通信をサポートし、別々の信号線でデータの送信と受信を同時に行える。

RS232コネクタは2種類の信号を持つ:

  1. データ信号 — TXD(送信データ)とRXD(受信データ)。実際のシリアルビットストリームを伝送する。
  2. ハンドシェイク信号 — CTS、RTS、DSR、DTRなど。CIAチップを通じて管理され、CIAのドキュメントで解説済み。

すべてのシリアルデータ転送はTXDとRXDラインで行われる。2台のデバイスを接続する際は、一方のTXDを他方のRXDに、またその逆に配線する(ヌルモデム/クロス配線)。

RS232データフォーマット

各方向のデータは1本のワイヤだけで伝送されるため、バイトをビット単位でシリアル化する必要がある。RS232には独立したクロック信号がないため、送信側と受信側はビットタイミングについて合意しなければならない。これがボーレートであり、1秒あたりの転送ビット数を規定する。一般的なボーレートは300、1200、2400、4800、9600である。

各バイトは以下のようにフレーミングされる:

  1. スタートビット — アイドル状態(ハイ)からローへの遷移で、バイトの開始を示す。
  2. データビット — LSBから順に送信。8ビットまたは9ビットフォーマット。
  3. ストップビット — バイトの終了を示す1つまたは2つのハイビット。

受信側は、前のバイトのストップビットと新しいバイトのスタートビットの間のハイからローへの遷移によって各バイトの開始を検出する。

$DFF030

UARTレジスタ

PaulaのUARTはシリアルデータ転送に3つのレジスタを使用し、さらにADKCONレジスタの1ビットをブレーク制御に使用する。

シリアルポートレジスタ
$DFF030SERDAT — シリアル送信データ(書き込み専用)
$DFF018SERDATR — シリアル受信データ + ステータス(読み取り専用)
$DFF032SERPER — シリアル周期/ボーレート(書き込み専用)
$DFF09EADKCON — ビット11(UARTBRK):TXDをローに強制(書き込み専用)

SERDATR — 受信データとステータス($DFF018、読み取り)

このレジスタは受信データバイトとUARTのステータスフラグの両方を含む。

ビット 名前 機能
15OVRUNオーバーラン — バッファ読み取り前にシフトレジスタが満杯
14RBF受信バッファフル — データ読み取り可能
13TBE送信バッファエンプティ — 次のバイト送信可能
12TSRE送信シフトレジスタエンプティ — 送信完了
11RXDRXD信号ラインの現在のレベル
10未使用
9STPストップビット
8STP/DB8ストップビット(8ビットモード)またはデータビット8(9ビットモード)
7DB7受信データビット7
6DB6受信データビット6
5DB5受信データビット5
4DB4受信データビット4
3DB3受信データビット3
2DB2受信データビット2
1DB1受信データビット1
0DB0受信データビット0

SERPER — 周期レジスタ($DFF032、書き込み)

ビット 名前 機能
15LONG1にセットで9ビット受信モード
14–0RATEボーレートを決定する15ビット周期値
$DFF030

データ受信

シリアル受信はシフトレジスタとデータバッファの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割り込みハンドラ内で処理する。

$DFF030

データ送信

シリアル送信もデータバッファ(SERDAT)と出力シフトレジスタの2段パイプラインを使用する。

データの書き込み

SERDATの送信データフォーマットは、希望するワード長とストップビット数に依存する。データビットはレジスタの下位部分を占め、その直後に1つまたは2つのストップビット(1にセット)が続く。上位ビットはすべて0でなければならない。

8ビットデータ、2ストップビット:

ビット 15–10 9–8 7–0
0 0 0 0 0 01 1(ストップビット)D7–D0(データ)

8ビットデータ、1ストップビット:

ビット 15–9 8 7–0
0 0 0 0 0 0 01(ストップビット)D7–D0(データ)

9ビットデータ、1ストップビット:

ビット 15–10 9 8–0
0 0 0 0 0 01(ストップビット)D8–D0(データ)

SERPERのLONGビットは受信にのみ影響する。送信フォーマットはSERDATに書き込まれた値のみで決定される。

送信ステータスフラグ

TBE(送信バッファエンプティ)は、SERDAT内のデータが出力シフトレジスタに転送されると1にセットされる。バッファは次のワードを受け付ける準備ができる。TBEはINTREQ/INTENのビット0でもある。RBFと同様に、サービス後はINTREQ経由でクリアする必要がある。

TSRE(送信シフトレジスタエンプティ)は、シフトレジスタがすべてのビットの送信を完了し、バッファに新しいデータが待機していないと1にセットされる。これは送信が本当に完了したことを示す。TSREはTBEがクリアされるとリセットされる。

UARTBRK — ブレーク信号

ADKCONレジスタのビット11(UARTBRK)をセットすると、TXD出力ラインがローに強制され、シリアル送信が停止する。これはRS232ライン上に「ブレーク」状態を生成し、リモートデバイスが検出できる。ビットをクリアすると通常動作に復帰する。

ADKCONシリアルビット
$DFF09EADKCONビット11 — UARTBRK:セットでTXDをローに強制(ブレーク状態)
$DFF010ADKCONRビット11 — UARTBRKの状態を読み取り
$DFF030

ボーレート計算

SERPERの下位15ビット(ビット14–0、RATEフィールド)は、ビット周期をバスクロックサイクル数で指定する。1バスクロックサイクルは約279.365ナノ秒(PALシステムクロック3.546895 MHzに基づく)。

希望するボーレートをSERPER値に変換する公式:

SERPER = (1 / (baud_rate * 279.365 * 10^-9)) - 1

同等の式:

SERPER = (3,579,545 / baud_rate) - 1 (NTSCクロック) SERPER = (3,546,895 / baud_rate) - 1 (PALクロック)

一般的なボーレート

ボーレート SERPER値(PAL) SERPER値(NTSC)
3001182211931
120029552982
240014771491
4800738745
9600369372
19200184186
31250(MIDI)112113

計算値は最も近い整数に丸めてSERPERに書き込む:

    move.w #745,$DFF032        ; 4800ボーに設定(NTSC)、LONG=0(8ビット)

9ビット受信モードの場合はビット15をセット:

    move.w #$8000+745,$DFF032  ; 4800ボー、LONG=1(9ビット受信)
$DFF030

割り込みとプログラミング

UARTは2つの割り込み信号を生成し、両方ともINTREQ/INTENで管理される:

INTREQビット 名前 条件 レベル
0TBE送信バッファエンプティ — 次のワード送信可能1
11RBF受信バッファフル — データ利用可能5

典型的な受信ハンドラ

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を待つだけでよい。