パラレルポートについてメモNo.1の続き。

○D-Sub 25pin Type A (ホスト側)
・メス側ピン配置

・ピン割り当て

ピン Compatible Nibble EPP ECP I/O 対応レジスタ 伝送信号の反転
1 nStrobe HostClock nWrite HostClock C-0
2-9 Data 0-7 Outp Data 0-7 Data 0-7 Data 0-7 入出(※) D-0~D-7 .
10 nAck PtrClock Interrupt PeriphClock S-6 .
11 Busy Input Data 3,7 nWait PeriphAck S-7
12 PaperOut/End Input Data 2,6 未使用 nAckReverse S-5 .
13 Select Input Data 1,5 未使用 Xflag S-4 .
14 nAuto Linefeed HostBusy nData Strobe Host Ack C-1
15 nError/nFault ID0,4/DataAvail 未使用 nPeriphRequest S-3 .
16 nInitialize 常にHigh nReverseRequest nInitialize C-2 .
17 nSelect Printer 常にHigh nAddress Strobe nSelect Printer C-3
18-25 Ground Ground Ground Ground GND x .

※SPPでは出力のみ。

割り当て名の頭にnがつくピンは伝送路上の信号レベルが反転している (Active = Low)
入出力方向はSPP、EPPなどのポートを問わず同じ。
対応ポートのCはコントロールポート、Dはデータポート、Sはステータスポート。
使用するケーブルによるが、18-25ピンの線は1-17ピンの線とツイストペアを構成してノイズを減らす役目をする。

SPP、Bi-Directionalにおいては入出力に気をつければ、データのやり取りは必ずしもこの表の割り当て名に従う必要はない。


○I/O制御
・各種レジスタのI/Oポートアドレス
PC/AT互換機 : 378h - 37Fh (LPT1) ,278h - 27Fh(LPT2) ,3BCh - 3BFh (LPT3)
MDA搭載IBM PC : 3BCh - 3BFh (LPT1(※)) ,378h - 37Fh (LPT2) ,278h - 27Fh (LPT3)
NEC PC-9821(双方向) : 140h - 142h , 149h, 14Bh - 14Eh

※古いIBM PCまたはその互換機でMDA(モノクロディスプレイアダプタ)を接続している時は、MDA上のパラレルポート(3BCh - 3BFh)がLPT1となる。
3BCh - 3BFhではECPを使用できないという制限があり、現在はあまり利用されない。
LPTの順序は上記が一般的だが環境によって違うことがある。実際のI/Oポートアドレスとの関連付けはOSに依存しない方法としては、BIOS Data Areaから読み取る。
NEC PC-9821シリーズでは149hに10hを出力することで双方向モード、00hで従来の簡易セントロニクスモードに切り替える。
古いPC-98、PC-H98はI/Oポートの構成が異なる。ここでは省略。
参考→ http://www.webtech.co.jp/company/doc/undocumented_mem/

以下はI/Oポートの役割。ベースアドレスは各I/Oポートアドレスの先頭(278h,378h,3BChなど)を指す。

・データポート (ベースアドレス +0)
読み書き可。データの入出力を行う。

Bit 意味
7 Data 7
6 Data 6
5 Data 5
4 Data 4
3 Data 3
2 Data 2
1 Data 1
0 Data 0

※2 データポートは読み込み時は直前に出力したデータを返す。
ただしBi-Directionalモードかつ入力モードであれば外部より入力されたデータを返す。

・ステータスポート (ベースアドレス +1)
読み取りのみ。ポートの状態を取得できる。

7 nBusy(n11)
6 nAck(10)
5 Paper Out(12)
4 Select In(13)
3 nError(15)
2 nIRQ(割り込み)
1 (予約)
0 (予約)

bit7-3は信号線の状態を表している。これはプリンタでよく使われる構成ではあるが、全ての機器がこうであるとは限らない。
bit2-0は内部制御用。
NEC PC-9821シリーズではbit 1が[Peripheral Logic High(18)]となっている。

・コントロールポート (ベースアドレス +2)
読み書き可。ポートの制御を行う。

7 (未使用)
6 (未使用)
5 Enable Bi-Directional Port
4 Enable IRQ Via Ack Line
3 Select Printer(n17)
2 nInitialize Printer(16)
1 Auto Linefeed(n14)
0 Strobe(n1)

bit3-0は信号線の制御用で、bit3,1,0は反転。
bit 5がBi-Directionalモード時の入出力の切り替え。bit 4はACKがアクティブになった時に割り込みを発生させるかどうか。

・アドレスポート (ベースアドレス +3)
読み書き可。EPP対応機器で使用。SPP、ECPでは使用しない。

・データポート (ベースアドレス +4)
読み書き可。EPP対応機器で使用。SPP、ECPでは使用しない。

ベースアドレス+5~+7は未定義。

※1 EPPでは最初の3つのI/OポートはSPPと同じ扱いになる。
※2 割り当て名の頭にnがつくものはその状態とは逆のデータビットを示す。
数字の前にnを付けたのは伝送路上の信号反転、つまり計4つのラインは端子への入力信号と逆のデータビットが示される。
・状態が反転 (10:ACK, 15:Error, 16:InitPrinter) : 1=Inactive=High, 0=Active=Low

・信号が反転 (1:Strobe, 14:AutoLF, 17:SelectPrinter) : 1=Active=Low, 0=Inactive=High

・状態と信号が反転 (11:Busy) : 1=Inactive=Low, 0=Active=High

Busy信号はI/Oポートを見ると反転しているが伝送路上を見ると反転していないため、信号ピンの割り当て名ではnが付かない。


以下はECPを使用している場合のみ有効。

アドレス ポート Read/Write
Base + 0 Data Port (SPP) Write
ECP Address FIFO (ECP Mode) Read/Write
Base + 1 Status Port (All Modes) Read/Write
Base + 2 Control Port (All Modes) Read/Write
Base + 400h Data FIFO (Parallel Port FIFO Mode) Read/Write
Data FIFO (ECP Mode) Read/Write
Test FIFO (Test Mode) Read/Write
Configuration Register A (Configuration Mode) Read/Write
Base + 401h Configuration Register B (Configuration Mode) Read/Write
Base + 402h Extended Control Register (All Modes) Read/Write


この中でもよく使いそうな ECR だけ詳しく見てみることにする。
・ECP拡張コントロールポート (Extended Control Register (ECR)、ベースアドレス +402h)

ビット 意味
7-5 モード選択(3bit)
0 Standard Mode
1 Byte Mode
10 Parallel Port FIFO Mode
11 ECP FIFO Mode
100 EPP Mode
101 (予約)
110 FIFO Test Mode
111 Configuration Mode
4 ECP Interrupt Bit
3 DMA Enable Bit
2 ECP Service Bit
1 FIFO Full
0 FIFO Empty


ECPが有効かつECP対応機器がない場合、通常は互換モード(出力のみ)になる。
旧来の双方向通信(Bi-Directional)を行うにはこれの5ビット目を1にし([ECR]|20h)、Byte Modeに切り替えた上でコントロールポートを操作する。


○直接パラレルポートを制御する方法
・MS-DOS ,Windows 9x
何の前処理もなしにいきなりアクセスできる。
ちょっとした操作ならOSに付属する"debug"コマンドを利用するのが手っ取り早い。
DOS(窓)でdebugを実行して-に続いて下記のようにコマンドを入力する。

入力 : i [ポート番号]
出力 : o [ポート番号] [データ(16進)]
ダンプ : d [開始アドレス] [終了アドレス]
(例えば "d 0:408 40d" でBIOS Data AreaにあるLPTポート番号とI/Oアドレスとの関連付け情報を取り出すことができる。
LPTポートを実装していなくても0以外の値が入っていることがあるので注意。)
debugコマンドを終了 : q

*利用例
debugコマンドを使って出力モードから入力モードに切り替えてみる。
(環境:PC/AT互換機、オンボードのパラレルポート、BIOS設定はEPPモードに設定(ただし外部機器とのネゴシエーションはしていない。)
I/Oポートのベースアドレスは378h。外部機器から常にランダムな8bitデータを送り続けている状態。)

出力テストでは、データポートに出力した値がそのまま返ってくる(出力モードである)ことを確認している。
次に一度コントロールポートの値を見て、bit5が1になるような値をコントロールポートに出力。
入力テストでランダムな値が入ってくることを確認。

断片的にデータを取り扱うのであればdebugコマンドだけでも事足りるのだが、連続データを扱うには別にプログラムが必要になってくるだろう。

・NT系
NT系でアプリケーションから利用するには、まずアクセス権を取得したりドライバを作る必要があったりと面倒。
一応debugコマンドは入っているみたいだが、Win2000ではデータポートやコントロールポートの読み書きができたもののECRにはアクセスできなかった。
(アクセスできないアドレスのデータを読み取ろうとするとFFhが返ってくる。)
とりあえずC#でパラレルポートの状態表示ツールを作ってみた。


・Linux系
Linuxでもいきなり直接いじることはできず、アクセス権を取得する必要がある。
ただ、国内海外サイト共に情報が充実しているのでそれほど苦労しないはず。


○プリンタポートとしての利用
印刷用途で使われることが多いと思うので、一応少しだけ触れておく。
ここまではパラレルポートについての概要と単なるバイナリデータの入出力に必要な情報のみ紹介してきた。
プリンタポートとして使うためにはさらにハンドシェイクの手順、JISコードへの文字コード変換、ESC/P系(EPSON製プリンタ)やPR201系(NEC製プリンタ)などの制御コード体系を知っておく必要がある。

・印刷待機時のパラレルポートの各信号レベル


・SPP互換モードでの印刷データ出力時の信号タイミングチャート(H, Lは伝送路上の状態)

A, B, C, D区間はそれぞれ0.5~1.0マイクロ秒以上の間隔をとること。
BusyがHighからLowになるタイミングは機器や設定によって異なるが、通常はACKがLowになるのと同時にBusyもLowになる。

上の過程をPCから見た場合の各I/Oポートビット値の遷移図


PC側から見たハンドシェイクの手順は
1. データポートにデータを出力。
2. ステータスポートbit7(nBusy)が1になっていることを確認。
3. 1μsほど待ってからコントロールポートのbit0(Strobe)に1を出力。
4. 1μsほど待ってからコントロールポートのbit0(Strobe)に0を出力。
5. 1μsほど待ってからデータポートに次のデータを出力。
6. ステータスポートbit6(nACK)が一度0になり1に戻るか、ステータスポートbit7(nBusy)が1になるまで待つ。
7. 3~6を繰り返す。
以上のように、基本的には同期信号を含めて全てプログラムで制御する。
こちらにあるサンプルプログラムを参考にするとよい。

データポートに出力するデータというのはJISコードや制御コードのことなのだが、これについてはメーカーや機器によって仕様が若干違うので各取扱説明書などを参照すること。制御コードについては『201PL』(NEC)や『ESC/P』(EPSON)でググると資料が出てくる。


旧ブログでのコメント

AUTHOR: Akimax
URL:
DATE: 2013/02/12 09:37:32
参考になりました(感謝)
Windowsのプリンタドライバは、連続用紙をサポートしていないとの情報を聞き、直接プリンタへ打たなければならない状況でした。
この情報のおかげで無事印刷することができました。
ありがとうございました。
ただ、STROBE信号の説明がタイミングチャートと文のH/Lが逆になっています。(文のほうが正しいようです。)
修正して頂けると よろ多くの人に参考になると思います。
では、失礼します。

AUTHOR: akm
URL:
DATE: 2013/02/12 23:56:57
Re: 参考になりました
コメントありがとうございます。お役に立てたようで何よりです。

>STROBE信号の説明がタイミングチャートと文のH/Lが逆になっています。
Strobe信号はI/Oポートの値とは反転しているのでこの図で良いと思うのですが。
まあこの辺りが紛らわしいということは前から思っていたので、
理解しやすいように写真と図を追加しました。
これでも間違っているようでしたらご一報下さい。


※コメント欄が表示されない場合はdisqusについてJavascriptが有効であることを確認して下さい。コメントはスパム防止フィルターによる承認制のため、投稿してもすぐに反映されない場合があります。

管理人 : Akamaki (akm)

は、PCとVTuberに夢中になっている電気技術者です。

私はレトロコンピューティングの愛好家ですが、そのようなリグはもう収集していません。

私の活動はトップページで見ることができます。読んでくれてありがとう!