元祖SCSIチップ

SCSI(Small Computer System Interface)は1980年代に開発されたインターフェースでその最初のチップはNCR社のDIP 40ピンのNCR5380でした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/2dd2ffde-924e-aa76-ea39-3b3a8bc80e7f.png)

その後CMOSにしたNCR53C80（同じDIP 40ピンだが互換なし）を発売して、同じ時期にWestern Digital社のWD33C93や富士通のMB87030などが出てきました。NCRのその後をすこし調べてみました。

![NCR.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/d7edd9a0-2d17-77aa-9adf-21edfc779f71.png)

NCR53C80は初期のMacintoshのSCSIチップとしても使われていました。

NCR53C406はISA PnPでNCR53C500はPCMCIAカードで使われていました。

Am53CF94,96はAMDの製品です。型番からしておそらくセカンドソースではないかと思われます。本家NCRには900番台の製品はないので、Am53C974はAMDが独自拡張したのかもしれません。AMDはWD33C93のコンパチチップも作っていたようで、なんだか節操ありません。

本家NCRのPCI対応製品のNCR53C8xxや32Bit CPU直結のNCR53C7xxなどはアーキテクチャが変わってTherd Generationになっています。

NCR53C406や500はレジスタセットを二つ持っていて切り替えてアクセスできます。0x0dの最上位ビットが0の場合がset 0で1の場合がset 1になります。一度セットするとset 1の16バイトとのレジスタがアクセスできて0x0dをリセットするとset 0の16バイトがアクセスできます。

NCR53C90などはDMAにも対応しています。PC/ATには8257というDMAのチップがのっていてそれを使うことができたのかもしれません。しかし実際にはDMAチャンネルの合理的な管理機構がなかったので、FDC以外は特殊な用途をのぞき8257を使うシステムは存在しなかったと思います。

ちょっと脱線しますが、PCI以降のシステムでは汎用のDMAはなくなりIO側に個別にDMA機能が入るようになりました。これはIOが多様化して汎用化が難しくなったことが要因かも知れません。

NCR53C400や406や500には128バイトx2に拡張されPIO FIFOという呼ばれる仕組みがあります。これによりDMAを使わないでもCPUに負荷をかけずに処理ができるようにしたのではないかと思います。PIOのレジスタは500の場合、set 1にあります。500の場合は、9x由来の16バイトのFIFOと128バイトのFIFOが連携して処理を行っているのではないかと考えられます。

NCR53C400のブロック図

![400.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/e36695f1-9c1b-29de-745c-5221562415e5.png)

この辺のチップは純粋にチップだけの供給でしたが、この後のAdaptecやAdvansysなどはチップを含めたボードーメーカーになりました。このためデーターシートなどの資料が存在しないチップが多くなります。

これを調べていたのはFreeBSDのドライバーの状況を確認するためでした。

おそらくPAO由来のNCR53C500のコードがncvとして入れられて、その後NCR53C90系のespというコードが入ったのではないかと思われます。出所は両方ともNetBSDなのですが、NetBSDの方ではncvを廃止してespに移行したようですが、FreeBSDでは12Rまでncvとespが両方ある状態でした。

ncvはPCMCIA専用だったのでpccardのサポートと一緒に13Rで消されました。

NCRは買収によりSymbios Logicと名前を変えたので後期のSYM53Cxxxという名前に変わっています。同じチップでもNCRとSYMの両方が存在するケースがあります。

SCSIはイニシエーター（ホスト）とターゲット（デバイス）のデータ通信を行う仕組みです。初期の時代のインターフェースチップはイニシエーターでもターゲットでも使えるものがほとんどでしたが、その後イニシエーターに特化したチップに変わって行った様な気がします。

# SCSIの事

SCSIはSmall Computer System Interfaceで設計当初は汎用的な仕組みを考えていたのではないかと思われます。ところが時代的にHDが普及し始めたことと、機能的に複雑な事ができにくいため、ハードディスクのインターフェースとして有名になったようです。

また当初の構想では二台のコンピューターで一台のハードディスクを利用するような事も考えられていたようですが、排他制御の方法がないため、ファイルを壊してしまう可能性があり、実際には使われませんでした。

SCSIは以下のようなフェースでデータのやり取りをします。

SELECTION -> COMMAND -> DATA IN/OUT -> STATUS -> MESSAGE

セレクションはイニシエーターが任意のタイミングでおこないますが、その後の処理の主導権はターゲットが握ります。

セレクションではイニシエーターが8ビットのバスに自分と通信相手のIDを乗せて、反応を確認します。たとえばID 7のイニシエーターが0のターゲットと通信する場合は10000001をバスに乗せて確認します。

ターゲットは自分のビットが確認できた場合、それ以外のビットが相手のイニシエーターのIDであることを識別してACKを返します。

ターゲットとして動作する場合は自分がセレクトされたことを知る事から始まります。

5380などではMode Register-Address 2にTarget modeというフラグがあり、これを設定されるとセレクトを割り込みで確認できました。これはターゲットとイニシエーターが同時に使えない仕様です。

53C90ではTarget modeのフラグがなくなりEnable Selection/Reselectionというコマンドになりました。このコマンドを発行しておくとセレクトされると割り込みが上がるようになります。同時にイニシエータとしても処理が行えます。

イニシエーターにもターゲットにもなれるのがSCSIの本来の仕様で、53C90の方が53C80より正しくSCSIの処理ができるようになったともいえます。

# 最初の一歩

espをいじってしてとりあえずPC-9801とお話できるようにしてみました。

まずidをPC-9801が7を使うのでそれ以外の0を設定します。

Enable Selection/Reselectionコマンドを発行しておきます。

selectの割り込み(0x01)が上がったらFIFOを読みます。

INQUIRY(0x12)が入っているので、FIFOに8バイト突っ込んでSend Dataコマンドを発行します。

Doneの割り込み(0x08)が上がるのでFIFOに2バイト突っ込んでTerminate Stepsコマンドを実行します。

PC-9801のフリーソフトのSCSIというコマンドで見るとID 0にINQUIRYで渡したデータが確認できました。

とりあえずデータのやり取りはできました。