mirror of
https://github.com/akuker/RASCSI.git
synced 2024-12-21 08:29:59 +00:00
first commit
This commit is contained in:
commit
35866cfb84
BIN
bin/raspberrypi/rascsi.tar.gz
Normal file
BIN
bin/raspberrypi/rascsi.tar.gz
Normal file
Binary file not shown.
BIN
bin/x68k/RASDRV.SYS
Normal file
BIN
bin/x68k/RASDRV.SYS
Normal file
Binary file not shown.
BIN
bin/x68k/RASETHER.SYS
Normal file
BIN
bin/x68k/RASETHER.SYS
Normal file
Binary file not shown.
158
doc/converter.txt
Normal file
158
doc/converter.txt
Normal file
@ -0,0 +1,158 @@
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
SCSI Target Emulator RaSCSI (*^..^*)
|
||||
version 1.33 for Raspberry Pi
|
||||
|
||||
Powered by XM6 TypeG Technology.
|
||||
Copyright (C) 2016-2018 GIMONS
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
□変換基板の必要性について
|
||||
SCSIはTTLレベルで5Vを220Ωと330Ωで分圧(パッシブターミネータの場合)する
|
||||
ことで各信号線に3V弱の電圧がかかった状態が定常状態(信号的にはネゲート)に
|
||||
なっています。
|
||||
|
||||
イニシエータ側もしくはターゲット側が信号をアサートする(=0V)にしようと
|
||||
すると両端のターミネータから合わせて5000÷220×2=45mAの電流が流れることに
|
||||
なります(X68000のSCSIコントローラであるMB89352のデータシートを見ればシンク
|
||||
電流としてIol48mAとなっています)。
|
||||
|
||||
RPIのGPIOはこのような大きなシンク電流は吸収できません。電気的に安全な接続
|
||||
を行うためには汎用ロジックIC等で変換基板を作る必要があります。汎用ロジック
|
||||
ICで48mAものシンク電流に耐えるのは74LS06とか07といったオープンコレクタで
|
||||
ハイパワータイプのものを使用します。
|
||||
|
||||
作者は74HC541×3,74HC126×1,74HC04×1で基本的なSCSIの方向制御を行い更に
|
||||
74LS07×3を使ってバスをドライブする回路を組んでみたところ問題なく動作する
|
||||
ことを確認しました。
|
||||
|
||||
他にも74LS641の派生版である74LS641-1を使用すると回路はシンプルに構成できる
|
||||
でしょう。ノーマル品と違ってシンク電流が48mA対応なので74LS07を使用する必要
|
||||
はありません。しかし入手性はそれほど良くありません。
|
||||
|
||||
□変換基板の回路図案
|
||||
同じフォルダに回路図案を入れています。
|
||||
|
||||
・target.png
|
||||
SCSIのターゲットモードを使用するための変換基板回路図です。基本機能である
|
||||
HDDやMOのエミュレーションを行うのであればこの回路図相当の物を作れば良い
|
||||
でしょう。使用するGPIOピンも最も少ない構成になります。
|
||||
|
||||
ピンアサインを変更しなければRaSCSIのstandardディレクトリに含まれる
|
||||
バイナリを使用することが可能です。
|
||||
|
||||
・initiator.png
|
||||
SCSIのターゲットモードに加えイニシエータモードを使用するための変換基板
|
||||
回路図です。基本機能に加えてRPIがイニシエータとなって物理HDDにコマンド
|
||||
を発行することが可能になります。モードの制御に追加で一つGPIOピンを消費
|
||||
します。このイニシエータモードを使用したサンプルプログラムとしてrasdump
|
||||
を用意しました。実HDDやMOからイメージファイルにダンプすることができます。
|
||||
オプションでリストア機能も使用できます。
|
||||
|
||||
ピンアサインのカスタマイズでPIN_INDに標準では7を設定してコンパイルする
|
||||
必要があります。ピンアサインのカスタマイズを参照してください。
|
||||
|
||||
・fullspec.png
|
||||
SCSIのターゲットモード、イニシエータモードに加えてSCSIの通信をモニター
|
||||
することができる変換基板回路図です。SCSIプロトコロルを解析する等の特殊
|
||||
要件がある場合はこの回路が最適です。全ての74LS641-1の方向制御をRaSCSI
|
||||
から行いますのでGPIOピンを三つ余分に使用してしまいます。SCSIの開発に
|
||||
興味があればこの回路を組んでみてはどうでしょうか。特徴としてGPIOピン
|
||||
を余分に使用する代わりに上のイニシエータモードが使用できる基板と比較
|
||||
して74LS86が必要にならないため基板がシンプルになるという恩恵があります。
|
||||
|
||||
ピンアサインのカスタマイズで、PIN_TAD,PIN_IND,PIN_DTDにそれぞれ標準
|
||||
では6,7,8を設定してコンパイルする必要があります。ピンアサインの
|
||||
カスタマイズを参照してください。
|
||||
|
||||
□既存のものを手に入れる方法
|
||||
最近では主にTwitter界隈を通じてRaSCSI用の変換基板を作成していただいて
|
||||
いる方々がいらっしゃいます。
|
||||
|
||||
また秋葉原で委託販売されてます。
|
||||
|
||||
家電のKENCHAN 同人ハード(キット)のページ等です。
|
||||
http://www.kadenken.com/shopbrand/ct76/"
|
||||
|
||||
現在のところ市販されているものとして
|
||||
|
||||
・BELさん開発のあいぼむ版
|
||||
・tomcatさん開発のGAMERnium版
|
||||
|
||||
があります。
|
||||
|
||||
□ピンアサインのカスタマイズ
|
||||
GPIOの信号制御論理やピンアサインはgpiobus.hとrascsidrv.cに定義があります。
|
||||
定義が分かれているのはrascsidrv.cだけGPLなので敢えて分離しています。
|
||||
御察し下さい。
|
||||
|
||||
カスタマイズ例としてgpiobus.hとrascsidrv.cに下記の二つの変換基板用定義例を
|
||||
用意しました。配布物の中にはコンパイル済みバイナリも含まれています。
|
||||
|
||||
・BELさん開発のあいぼむ版
|
||||
・tomcatさん開発のGAMERnium版
|
||||
|
||||
□カスタマイズ方法
|
||||
・RaSCSI起動時のメッセージです。
|
||||
CONNECT_DESC
|
||||
|
||||
・信号制御モードを選択します。
|
||||
SIGNAL_CONTROL_MODE
|
||||
|
||||
0:SCSI論理仕様
|
||||
直結またはHPに公開した74LS641-1等を使用する変換基板
|
||||
アーサート:0V
|
||||
ネゲート :オープンコレクタ出力(バスから切り離す)
|
||||
|
||||
1:負論理仕様(負論理->SCSI論理への変換基板を使用する場合)
|
||||
現時点でこの仕様による変換基板は存在しません
|
||||
アーサート:0V -> (CONVERT) -> 0V
|
||||
ネゲート :3.3V -> (CONVERT) -> オープンコレクタ出力
|
||||
|
||||
2:正論理仕様(正論理->SCSI論理への変換基板を使用する場合)
|
||||
RaSCSI Adapter Rev.C @132sync等
|
||||
|
||||
アーサート:3.3V -> (CONVERT) -> 0V
|
||||
ネゲート :0V -> (CONVERT) -> オープンコレクタ出力
|
||||
|
||||
・制御信号ピンアサイン
|
||||
PIN_ACT:SCSIコマンドを処理中の状態を示す信号のピン番号。
|
||||
PIN_ENB:起動から終了の間の有効信号を示す信号のピン番号。
|
||||
PIN_TAD:ターゲット信号(BSY,IO,CD,MSG,REG)の入出力方向を示す信号のピン番号。
|
||||
PIN_IND:イニシーエータ信号(SEL,ATN,RST,ACK)の入出力方向を示す信号のピン番号。
|
||||
PIN_DTD:データ信号(DT0...DT7,DP)の入出力方向を示す信号のピン番号。
|
||||
|
||||
・制御信号出力論理
|
||||
0V:FALSE 3.3V:TRUEで指定します。
|
||||
|
||||
ACT_ON:PIN_ACT信号の論理です。
|
||||
ENB_ON:PIN_ENB信号の論理です。
|
||||
TAD_IN:PIN_TAD入力方向時の論理です。
|
||||
IND_IN:PIN_ENB入力方向時の論理です。
|
||||
DTD_IN:PIN_ENB入力方向時の論理です。
|
||||
|
||||
・SCSI信号ピンアサイン
|
||||
PIN_DT0~PIN_SEL:それぞれSCSI信号のピン番号です。
|
||||
|
||||
□コンパイル方法
|
||||
|
||||
・実行ファイル(rascsi,rasctl)
|
||||
gpiobus.hを修正
|
||||
make clean
|
||||
make
|
||||
|
||||
・カーネルドライバ(rascsidrv.ko)
|
||||
①OS最新化(必要あれば)
|
||||
sudo apt-get update
|
||||
sudo apt-get upgrade
|
||||
sudo reboot
|
||||
|
||||
②カーネルヘッダー取得(必要あれば)
|
||||
sudo apt-get install raspberrypi-kernel-headers
|
||||
|
||||
③コンパイル
|
||||
cd kernelmodule
|
||||
rascsidrv.cの修正
|
||||
make
|
||||
[EOF]
|
BIN
doc/fullspec.png
Normal file
BIN
doc/fullspec.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 73 KiB |
BIN
doc/initiator.png
Normal file
BIN
doc/initiator.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 75 KiB |
BIN
doc/pinassign.png
Normal file
BIN
doc/pinassign.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 335 KiB |
315
doc/rascsi.txt
Normal file
315
doc/rascsi.txt
Normal file
@ -0,0 +1,315 @@
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
SCSI Target Emulator RaSCSI (*^..^*)
|
||||
version 1.34 for Raspberry Pi
|
||||
|
||||
Powered by XM6 TypeG Technology.
|
||||
Copyright (C) 2016-2018 GIMONS
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
□RaSCSIとは
|
||||
RaSCSIはRaspberry Piで動作するSCSIデバイス(ハードディスク,MO,CD-ROM)を
|
||||
仮想的に再現するエミュレータです。SCSIを採用したSHARPのX68000で使用する
|
||||
ことを目的として開発しました。RaSCSIを導入したRaspberry PiをX68000のSCSI
|
||||
コネクタに接続するだけで物理的なSCSIデバイスとして認識されます。
|
||||
|
||||
X68000以外にもSCSIを採用したFM TOWNSやPC98等のレトロPCでも使用できるかも
|
||||
しれません。作者はFM TOWNSとPC9821Ceで動作するところまでは確認しています。
|
||||
|
||||
RaSCSIはSCSIデバイスをエミュレートするソフトウェアに加えてRaspberry Piの
|
||||
GPIOコネクタをSCSIコネクタに変換する機構の総称を指します。
|
||||
|
||||
□動作環境
|
||||
(1)Raspberry Pi
|
||||
Raspberry Pi 3 Model B を推奨します。
|
||||
|
||||
Raspberry Pi 2 Model BやZeroでも動作すると考えられます。
|
||||
ピンアサインを独自に変更しRaspberry Pi 1で動作させたという報告もあります。
|
||||
|
||||
(2)OS
|
||||
RASPBIAN STRETCHで開発およびテストしています。
|
||||
sudo apt-get update及びsudo apt-get upgradeで最新にしています。
|
||||
このドキュメントを記述している時点で"Linux raspberrypi 4.14.34-v7+"です。
|
||||
|
||||
RaSCSIはSCSI信号をGPIOを利用して制御しているので可能な限り低レイテンシー
|
||||
の状態で使用する必要があります。したがってCUIモードで利用することを推奨
|
||||
します。更に不要なサービスは極力停止して下さい。
|
||||
|
||||
□SCSIコネクタとの接続方法
|
||||
状況が複雑になってきましたのでRaSCSIのホームページ上で情報提供しています。
|
||||
このドキュメントの最後にある公式ホームページを参考にして下さい。
|
||||
|
||||
□配布物
|
||||
配布するアーカイブには実行ファイル、ドキュメント、ソースコードのそれぞれが
|
||||
ディレクトリで分かれて含まれています。
|
||||
|
||||
bin/ ・・・ 実行ファイル
|
||||
raspberrypi/ ・・・ RPI用のプログラム
|
||||
rascsi.tar.gz ・・・ 実行ファイルとカーネルモジュールをtar+gzipしたもの。
|
||||
|
||||
x68k/ ・・・ X68000用のプログラム
|
||||
RASDRV.SYS ・・・ ホストドライブドライバ
|
||||
RASETHER.SYS ・・・ イーサネットドライバ
|
||||
|
||||
doc/ ・・・ ドキュメント
|
||||
rascsi.txt ・・・ 当ドキュメント
|
||||
x68k.txt ・・・ X68000固有機能の説明
|
||||
converter.txt ・・・ 変換基板の説明
|
||||
pinassign.png ・・・ ピンアサイン図
|
||||
target.png ・・・ 変換基板回路図案(ターゲットモード)
|
||||
initiator.png ・・・ 変換基板回路図案(イニシエータサポート)
|
||||
fullspec.png ・・・ 変換基板回路図案(フルスペック)
|
||||
|
||||
src/ ・・・ ソースコード
|
||||
raspberrypi/ ・・・ RPI用のプログラムソース一式
|
||||
x68k/ ・・・ X68000用のプログラム一式
|
||||
|
||||
|
||||
RPIで使用するプログラムはrascsi.tar.gzですのでRPI上に転送してから解凍して
|
||||
下さい。パーミッション等を維持するためにRPI上で解凍することを推奨します。
|
||||
|
||||
rascsi.tar.gzにはstandard,fullspec,aibom,gamerniumのディレクトリが含まれ
|
||||
ています。通常はstandardディレクトリにある実行ファイルを使用して下さい。
|
||||
|
||||
aibom,gamerniumディレクトリのものは"あいぼむ版","GAMERnium版"の変換基板を
|
||||
使用する時のものです。
|
||||
|
||||
fullspecディレクトリのものは公開したフルスペック版変換基板の回路図案で
|
||||
変換基板を作成した時に使用する時のものです。
|
||||
|
||||
□RASCI本体の使用方法(rascsi)
|
||||
|
||||
sudo rascsi [-ID{01234567} FILE] ...
|
||||
|
||||
ルート権限が必要ですのでsudo等で起動する必要があります。
|
||||
オプションに-hを付けると簡単なHELPが表示されます
|
||||
|
||||
Usage: ./rascsi [-ID{0|1|2|3|4|5|6|7} FILE] ...
|
||||
|
||||
ID is SCSI identification number.
|
||||
FILE is disk image file.
|
||||
|
||||
Detected images type based on file extension.
|
||||
hdf : SASI HD image(XM6 SASI HD image)
|
||||
hds : SCSI HD image(XM6 SCSI HD image)
|
||||
hdn : SCSI HD image(NEC GENUINE)
|
||||
hdi : SCSI HD image(Anex86 HD image)
|
||||
nhd : SCSI HD image(T98Next HD image)
|
||||
hda : SCSI HD image(APPLE GENUINE)
|
||||
mos : SCSI MO image(XM6 SCSI MO image)
|
||||
iso : SCSI CD image(ISO 9660 image)
|
||||
|
||||
引数では-ID{01234567}とFILEの一組で一つのSCSIデバイスを指定できます。
|
||||
|
||||
-IDの後ろの番号はSCSI IDです。SCSI IDは0-7を指定できますが通常レトロPC本体
|
||||
がイニシエータとしてID7等を使用していると思います。その場合は0-6を指定する
|
||||
ことになります。
|
||||
|
||||
FILEは仮想ディスクイメージのファイルパスです。イメージファイル名には拡張子
|
||||
が必要です。拡張子によってHD,MO,CDの種別を判定しています。
|
||||
|
||||
例)SCSI ID0にHDIMAGE0.HDS,ID1にHDIMAGE1.HDSを指定して起動する場合、
|
||||
sudo rascsi -ID0 HDIMAGE0.HDS -ID1 HDIMAGE1.HDS
|
||||
|
||||
終了する場合はCTRL+Cで停止します。
|
||||
バックグラウンドで起動した場合にはkillコマンド該当プロセスにINTシグナルか
|
||||
HUPシグナルを送ることで終了します。
|
||||
|
||||
rascsiは起動後にソケット(6868ポート)を開いて外部からの管理コマンドを受け
|
||||
付ける状態になります。したがって既に別プロセスとしてrascsiが起動している
|
||||
場合はエラーメッセージとともに起動を中断します。
|
||||
|
||||
□管理ツールの使用方法(rasctl)
|
||||
バージョン1.10からrasctlという管理ツールを提供します。これはrascsiプロセス
|
||||
がバックグラウンドで起動(6868ポートで接続待ちの状態)している場合にディスク
|
||||
操作のコマンドを発行することが可能となります。コマンドラインは下記の通り。
|
||||
|
||||
rasctl -i ID [-c CMD] [-t TYPE] [-f FILE]
|
||||
|
||||
ID : SCSI ID
|
||||
CMD : 操作コマンド
|
||||
attach : ディスクを取り付ける
|
||||
detatch : ディスクを取り外す
|
||||
insert : メディアを挿入する(MOまたはCDのみ)
|
||||
eject : メディアを取り出す(MOまたはCDのみ)
|
||||
protect : メディアを書き込み禁止にする(MOのみ)
|
||||
TYPE : ディスク種別
|
||||
hd : ハードディスク(SASI/SCSI)
|
||||
mo : MO(光磁気ディスク)
|
||||
cd : CDROM(CDROMドライブ)
|
||||
bridge : ブリッジデバイス
|
||||
FILE : ディスクイメージファイルのパス
|
||||
|
||||
IDは必須です。CMDは省略時はattachと解釈します。TYPEはコマンドがattachの
|
||||
場合にはFILEの拡張子から自動判定します。FILEはTYPEを明示的に指定している
|
||||
場合は拡張子が異なっても構いません。基本的CMD,TYPEの解釈は大文字小文字を
|
||||
無視します。現在のところ最初の1文字でのみ判定しています。
|
||||
|
||||
コマンド例
|
||||
rascsi -i 0 -f HDIMAGE0.HDS
|
||||
|
||||
の場合はSCSI IDは0。CMDはデフォルトでattachでありTYPEは拡張子HDSから判断
|
||||
するのでhdと推測することになりrascsi起動時のオプション指定と同等です。
|
||||
|
||||
現在の状態を確認するにために-lオプションのみを指定するとデバイス一覧が表示
|
||||
されます。コマンドラインは下記の通り。
|
||||
|
||||
rasctl -l
|
||||
|
||||
rasctl自体の起動にはルート権限は必要ありません。
|
||||
|
||||
□ディスクダンプツールの使用方法(rasdump)
|
||||
直結もしくは直結基板、またはイニシエータ対応とした変換基板向けのサンプル
|
||||
プログラムです。現在のところ変換基板では"あいぼむ版"のみ対応してます。
|
||||
|
||||
名前の通りSCSI HDDやMOのイメージをダンプ(オプションでリストア)します。
|
||||
自身のIDはBIDで指定して下さい。省略時は7を使用します。
|
||||
|
||||
rasdump -i ID [-b BID] -f FILE [-r]
|
||||
ID : ターゲットデバイスのSCSI ID
|
||||
BID : RaSCSI自身のSCSI ID
|
||||
FILE : ダンプファイル名
|
||||
-r : リストアモード
|
||||
|
||||
サンプルなので必要最低限の処理しか実装していませんので改造するなりして
|
||||
ご使用下さい。
|
||||
|
||||
□カーネルモジュールの導入方法(rascsidrv.ko)
|
||||
version 1.24から安定化のためにGPIO制御の一部をカーネルモジュールで動作
|
||||
させる拡張を加えました。
|
||||
|
||||
カーネルモジュールを導入しなくても動作できますが、X68000シリーズのSASI
|
||||
を使用する場合や純正SCSIボードを増設した場合はカーネルモジュールの導入
|
||||
を行っていないと動作が不安定になります。
|
||||
|
||||
カーネルモジュールを有効にするには
|
||||
|
||||
sudo insmod rascsidrv.ko
|
||||
|
||||
を実行してください。
|
||||
|
||||
カーネルモジュールの起動を確認するにはdmesgコマンドで出力されるログの
|
||||
最後に次のような表示がされている筈です。
|
||||
|
||||
"RaSCSI GPIO Driver Loaded(STANDARD)"
|
||||
|
||||
注意!
|
||||
カーネルモジュールは使用中のOSのバージョンに依存します。
|
||||
|
||||
rascsiやrasctlと同じ階層にあるrascsidrv.koはRaspberry Pi 2/3用の
|
||||
"Linux raspberrypi 4.14.34-v7+"でコンパイルしたモジュールになります。
|
||||
|
||||
同じ階層のrpi1orZero/rascsidrv.koはRaspberry Pi 1/Zero用です。
|
||||
"Linux raspberrypi 4.14.34+"でコンパイルしたモジュールになります。
|
||||
|
||||
自身でカーネルモジュールをコンパイルする手順を簡単に記しておきます。
|
||||
|
||||
・OSの最新化
|
||||
sudo apt-get update
|
||||
sudo apt-get upgrade
|
||||
sudo reboot
|
||||
|
||||
・カーネルヘッダー取得
|
||||
sudo apt-get install raspberrypi-kernel-headers
|
||||
|
||||
・コンパイル
|
||||
cd kernelmodule
|
||||
make
|
||||
|
||||
□サポートするディスクイメージ
|
||||
(1)SCSI ハードディスク
|
||||
HDSファイル形式 (拡張子HDS/HDN/HDI/NHD/HDA)
|
||||
ファイルサイズは10MB以上4095MB以下の範囲で任意のサイズ(但し512バイト単位)
|
||||
|
||||
拡張子が"HDN"の場合はNEC純正55ボード(PC-9801-55)向けの純正ハードディスク
|
||||
エミュレーションを行います。INQUIRYで返却される情報やMODE SENSEのサイズに
|
||||
に違いがあります。
|
||||
|
||||
拡張子が"HDI","NHD"の場合はそれぞれPC98エミュレータであるAnex86及びT98Next
|
||||
のSCSIハードディスクイメージを使用するものです。HDNの時と同様に一部の情報
|
||||
がNEC用に変換されます。
|
||||
|
||||
拡張子が"HDA"の場合はAPPLE純正ハードディスクエミュレーションを行います。
|
||||
INQUIRY及びMODE SENSEで返却される情報に違いがあります。
|
||||
|
||||
(2)SASI ハードディスク
|
||||
HDFファイル形式 (拡張子HDF)
|
||||
ファイルサイズは10441728バイト、20748288バイト、41496576バイトのいずれか
|
||||
(それぞれ10MBドライブ、20MBドライブ、40MBドライブに対応)
|
||||
|
||||
(3)SCSI 光磁気(MO)ディスク
|
||||
MOSファイル形式 (拡張子MOS)
|
||||
ファイルサイズは次の4種類のいずれか:
|
||||
128MBタイプ (127398912バイト)
|
||||
230MBタイプ (228518400バイト)
|
||||
540MBタイプ (533248000バイト)
|
||||
640MBタイプ (635600896バイト)
|
||||
128MB,230MB,540MBは512バイト/セクタ、640MBは2048バイト/セクタになります。
|
||||
|
||||
(4)SCSI CD-ROMディスク
|
||||
ISOファイル形式 (拡張子ISO、ISO9660ベタイメージ)
|
||||
モード1(2048バイト/セクタ)で、データのみ格納されたファイルとRAW形式で記録
|
||||
されたファイルの両方に対応しています。
|
||||
|
||||
□ディスクイメージの作成
|
||||
RaSCSI自体がX68000エミュレータであるXM6 TypeGの派生物です。従ってディスク
|
||||
イメージの作成はXM6 TypeGの「ツール」メニューから行うことを前提としています。
|
||||
もちろん先に説明した仕様に従えばdd等で空のイメージファイルを作成することも
|
||||
可能です。
|
||||
|
||||
例)100MBのHDSイメージ(空ファイル)を作る場合
|
||||
|
||||
dd if=/dev/zero of=HARDDISK.HDS bs=512 count=204800
|
||||
|
||||
□動作実績
|
||||
作者の開発環境であるX68000 PRO(内蔵SASI/純正SCSIボード)、X68030 内蔵SCSI、
|
||||
XVI Compact 内蔵SCSIで動作確認しています。Mach-2でも動作しました。
|
||||
|
||||
他にも初代X68000,ACE,EXPERT,XVI,PRO2,SUPER等で動作報告がありましたので、
|
||||
X68000シリーズはほぼ問題ないでしょう。
|
||||
|
||||
その他のレトロPCではFM TOWNSシリーズ、PC98シリーズ、Apple Macintosh、
|
||||
MSX(MEGA-SCSI利用)で動作報告があります。
|
||||
|
||||
その他の機種でもちらほらと動作報告を頂いています。
|
||||
|
||||
□活用方法
|
||||
XM6等のX68000エミュレータを使用している場合はエミュレータで環境構築したHDD
|
||||
イメージをFTP等でRaspberry Piに転送することでX68000の実機に接続できます。
|
||||
またその逆も然りで実機上に存在するファイルを格納したHDDイメージをPCにFTP等
|
||||
で転送することでエミュレータで活用することができます。
|
||||
|
||||
□ライセンス
|
||||
RaSCSIはカーネルドライバを除きあるがまま"AS IS"で配布されるソフトウェアです。
|
||||
カーネルドライバのソースrascsidrv.cのみGPLです(御察っし下さい)。
|
||||
|
||||
つまり使用者が受けたあらゆる損害に対して一切責任を持ちません。またソフト
|
||||
ウェアに不備もしくは不具合があったとしてもそれを修正する責任もありません。
|
||||
|
||||
RaSCSIを利用することでRaspberry PiやレトロPCが故障するリスクがあります。
|
||||
あくまで自己責任でチャレンジしてください。
|
||||
|
||||
XM6 TypeG同様に実験成果公開という性質上私のHP以外での配布を認めておりません。
|
||||
|
||||
XM6のライセンス条項を継承していますので雑誌/書籍での紹介事前の許諾が必要です。
|
||||
そもそも2017年にもなってSCSIに反応するのは限られた人だけだと思います。
|
||||
|
||||
□変換基板の頒布について
|
||||
変換基板の頒布については作者に許諾を得る必要はありません。
|
||||
一応ご連絡いただければ何かとサポートできるかもしれません。
|
||||
|
||||
但しレトロPCのSCSI環境改善を応援するという趣旨から、
|
||||
有料の場合は
|
||||
|
||||
基板製作費 + パーツ費用 + 運送費 +(社会通念上一般的な)手数料
|
||||
|
||||
を大きく越えるような頒布についてはお止め下さい。
|
||||
|
||||
□公開ホームページ
|
||||
http://www.geocities.jp/kugimoto0715/rascsi/index.html
|
||||
|
||||
□連絡先
|
||||
twitter https://twitter.com/kugimoto0715
|
||||
e-mail kugimoto0715@yahoo.co.jp
|
||||
|
||||
[EOF]
|
BIN
doc/target.png
Normal file
BIN
doc/target.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 72 KiB |
109
doc/x68k.txt
Normal file
109
doc/x68k.txt
Normal file
@ -0,0 +1,109 @@
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
SCSI Target Emulator RaSCSI (*^..^*)
|
||||
version 1.33 for Raspberry Pi
|
||||
|
||||
Powered by XM6 TypeG Technology.
|
||||
Copyright (C) 2016-2018 GIMONS
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
□X68000固有の機能について
|
||||
RaSCSIにはブリッジデバイスという仮想的なSCSIデバイスが実装されておりX68000と
|
||||
ホストであるRaspberry Piの橋渡しを行うことができます。このブリッジデバイスと
|
||||
X68000用の専用ドライバを使用して下記の機能を提供します。
|
||||
|
||||
・イーサーネット
|
||||
Neptune-Xと同様のイーサーネット機能を提供します。SCSI接続のイーサーネット
|
||||
BOXのようにRaSCSIが振舞います。Raspberry PiのTAPデバイスにパケットを中継
|
||||
することで実現しています。Ether+と似たものです。
|
||||
|
||||
・ホストファイルシステム
|
||||
X68000のエミュレーターでは標準的な機能であるWindrv相当の機能を提供します。
|
||||
Raspberry Pi上のファイルシステムをリモートドライブとしてマウントすること
|
||||
ができます。
|
||||
|
||||
□ブジッジデバイスの起動方法
|
||||
RaSCSI起動時にファイル名として"BRIDGE"というキーワードを設定するとそのIDに
|
||||
対してブジッリデバイスを生成します。
|
||||
|
||||
ex)
|
||||
sudo rascsi -ID0 HDIMAGE0.HDS -ID6 BRIDGE
|
||||
|
||||
□イーサーネット接続
|
||||
配布物に含まれるRASETHER.SYSを使用します。このデバイスドライバがブリッジ
|
||||
デバイスと連携してイーサーネットのパケット送受信を行うことができます。
|
||||
|
||||
以下、Raspberry Piの仮想アダプタ(TAP)のIPアドレスを「192.168.68.1」として、
|
||||
X68000側を「192.168.68.3」とするケースで説明します。
|
||||
|
||||
・X68000の設定
|
||||
RASETHER.SYSはNeptune-X用ドライバを改造して作ったものですので使用方法は
|
||||
全く同じです。X68000をネット接続するためには他に環境設定を行う必要があり
|
||||
ます。設定方法は自力で調べていただくようお願いします。
|
||||
|
||||
以下実際に使用しているCONFIG.SYSとAUTOEXEC.BATの抜粋です。
|
||||
|
||||
[CONFIG.SYS抜粋]
|
||||
PROCESS = 3 10 10
|
||||
DEVICE = \NETWORK\RASETHER.SYS
|
||||
|
||||
[AUTOEXEC.BAT抜粋]
|
||||
SET SYSROOT=A:/NETWORK/
|
||||
SET temp=A:\
|
||||
SET tmp=A:\
|
||||
SET HOME=A:/NETWORK/ETC/
|
||||
SET HOST=X68000
|
||||
XIP.X
|
||||
IFCONFIG.X lp0 up
|
||||
IFCONFIG.X en0 192.168.68.3 netmask 255.255.255.0 up
|
||||
INETDCONF.X +router 192.168.68.1 -rip
|
||||
INETDCONF.X
|
||||
|
||||
・Raspberry Piの設定
|
||||
TAPデバイスというものを利用していますのでTAPを有効にしてください。恐らく
|
||||
最近のJessieであれば最初から有効なはずです。確認方法は/dev/net/tunという
|
||||
ファイルが存在すれば有効となっていると判断できます。
|
||||
|
||||
仮想アダプタの作成方法は次の様に行います。
|
||||
|
||||
[/etc/rc.local等から設定]
|
||||
ip tuntap add ras0 mode tap user root
|
||||
ip link set ras0 up
|
||||
ifconfig ras0 inet 192.168.68.1/8 up
|
||||
route add -net 192.168.68.0 netmask 255.255.255.0 dev ras0
|
||||
|
||||
上記によってRaspberry Pi(192.168.68.1)とX68000(192.168.68.3)の間で通信が
|
||||
可能になります。
|
||||
|
||||
インターネット等と接続する場合はRaspberry Pi側でブリッジやルーティングの
|
||||
設定が必要になります。ご自身の環境に合わせて設定してください。無線LANの
|
||||
場合にブリッジ構成するには色々と課題があるようなのでフォワーディングと
|
||||
NAT構成等もお勧めです。作者はrc.localで次のような設定で使用しています。
|
||||
|
||||
echo 1 > /proc/sys/net/ipv4/ip_forward
|
||||
iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
|
||||
|
||||
□ホストファイルシステム連携
|
||||
X68000エミュレータでよく利用されるWindrvやWindrvXMと同等の機能を提供します。
|
||||
専用のRASDRV.SYSというデバイスドライバを組み込めばRaspberri Piのファイル
|
||||
システムがX68000側のドライブに見えて操作できるということです。
|
||||
|
||||
デバイスドライバの登録は簡単です。
|
||||
例えば
|
||||
|
||||
DEVICE = \SYS\RASDRV.SYS
|
||||
|
||||
この場合はデフォルトでRaspberry Piのルートディレクトリをマウントします。
|
||||
デバイスドライバ起動時にどのドライブにマウントされたか表示されます。
|
||||
ルートを以外をマウントする場合はディレクトリを指定して下さい。/home/pi等を
|
||||
マウントするには
|
||||
|
||||
DEVICE = \SYS\RASDRV.SYS /home/pi
|
||||
|
||||
と指定します。複数のディレクトリを指定すれば別々のドライブとしてマウントする
|
||||
ことが可能です。
|
||||
|
||||
SUSIEをご利用の方はSUSIEより先にRASDRV.SYSを組み込んで下さい。後に組み込むと
|
||||
正しく認識できなくなると報告があります。
|
||||
|
||||
[EOF]
|
51
src/raspberrypi/Makefile
Normal file
51
src/raspberrypi/Makefile
Normal file
@ -0,0 +1,51 @@
|
||||
CC = gcc
|
||||
CFLAGS = -DNDEBUG -O3
|
||||
CXX = g++
|
||||
CXXFLAGS = -DNDEBUG -O3
|
||||
|
||||
RASCSI = rascsi
|
||||
RASCTL = rasctl
|
||||
RASDUMP = rasdump
|
||||
|
||||
BIN_ALL = $(RASCSI) $(RASCTL) $(RASDUMP)
|
||||
|
||||
SRC_RASCSI = \
|
||||
rascsi.cpp \
|
||||
scsi.cpp \
|
||||
disk.cpp \
|
||||
gpiobus.cpp \
|
||||
ctapdriver.cpp \
|
||||
cfilesystem.cpp \
|
||||
filepath.cpp \
|
||||
fileio.cpp
|
||||
|
||||
SRC_RASCTL = \
|
||||
rasctl.cpp
|
||||
|
||||
SRC_RASDUMP = \
|
||||
rasdump.cpp \
|
||||
scsi.cpp \
|
||||
gpiobus.cpp \
|
||||
filepath.cpp \
|
||||
fileio.cpp
|
||||
|
||||
OBJ_RASCSI := $(SRC_RASCSI:.cpp=.o)
|
||||
OBJ_RASCTL := $(SRC_RASCTL:.c=.o)
|
||||
OBJ_RASDUMP := $(SRC_RASDUMP:.c=.o)
|
||||
|
||||
.cpp.o:
|
||||
$(CXX) $(CXXFLAGS) -c $<
|
||||
|
||||
ALL: $(BIN_ALL)
|
||||
|
||||
$(RASCSI): $(OBJ_RASCSI) $
|
||||
$(CXX) -o $@ $(OBJ_RASCSI) -lpthread
|
||||
|
||||
$(RASCTL): $(OBJ_RASCTL) $
|
||||
$(CXX) -o $@ $(OBJ_RASCTL)
|
||||
|
||||
$(RASDUMP): $(OBJ_RASDUMP) $
|
||||
$(CXX) -o $@ $(OBJ_RASDUMP)
|
||||
|
||||
clean:
|
||||
rm -f *.o $(BIN_ALL)
|
4228
src/raspberrypi/cfilesystem.cpp
Normal file
4228
src/raspberrypi/cfilesystem.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1157
src/raspberrypi/cfilesystem.h
Normal file
1157
src/raspberrypi/cfilesystem.h
Normal file
File diff suppressed because it is too large
Load Diff
68
src/raspberrypi/cqueue.h
Normal file
68
src/raspberrypi/cqueue.h
Normal file
@ -0,0 +1,68 @@
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// X68000 EMULATOR "XM6"
|
||||
//
|
||||
// Copyright (C) 2001-2004 PI.(ytanaka@ipc-tokai.or.jp)
|
||||
// [ MFC キュー ]
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#if !defined(queue_h)
|
||||
#define queue_h
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// キュー
|
||||
//
|
||||
//===========================================================================
|
||||
class CQueue
|
||||
{
|
||||
public:
|
||||
// 内部データ定義
|
||||
typedef struct _QUQUEINFO {
|
||||
BYTE *pBuf; // バッファ
|
||||
DWORD dwSize; // サイズ
|
||||
DWORD dwMask; // マスク(サイズ-1)
|
||||
DWORD dwRead; // Readポインタ
|
||||
DWORD dwWrite; // Writeポインタ
|
||||
DWORD dwNum; // 個数
|
||||
DWORD dwTotalRead; // 合計Read
|
||||
DWORD dwTotalWrite; // 合計Write
|
||||
} QUEUEINFO, *LPQUEUEINFO;
|
||||
|
||||
// 基本ファンクション
|
||||
CQueue();
|
||||
// コンストラクタ
|
||||
virtual ~CQueue();
|
||||
// デストラクタ
|
||||
BOOL FASTCALL Init(DWORD dwSize);
|
||||
// 初期化
|
||||
|
||||
// API
|
||||
void FASTCALL Clear();
|
||||
// クリア
|
||||
BOOL FASTCALL IsEmpty() const { return (BOOL)(m_Queue.dwNum == 0); }
|
||||
// キューが空かチェック
|
||||
DWORD FASTCALL GetNum() const { return m_Queue.dwNum; }
|
||||
// キューのデータ数を取得
|
||||
DWORD FASTCALL Get(BYTE *pDest);
|
||||
// キュー内のデータをすべて取得
|
||||
DWORD FASTCALL Copy(BYTE *pDest) const;
|
||||
// キュー内のデータをすべて取得(キュー進めない)
|
||||
void FASTCALL Discard(DWORD dwNum);
|
||||
// キューを進める
|
||||
void FASTCALL Back(DWORD dwNum);
|
||||
// キューを戻す
|
||||
DWORD FASTCALL GetFree() const;
|
||||
// キューの空き個数を取得
|
||||
BOOL FASTCALL Insert(const BYTE *pSrc, DWORD dwLength);
|
||||
// キューに挿入
|
||||
void FASTCALL GetQueue(QUEUEINFO *pInfo) const;
|
||||
// キュー情報取得
|
||||
|
||||
private:
|
||||
QUEUEINFO m_Queue;
|
||||
// 内部ワーク
|
||||
};
|
||||
|
||||
#endif // queue_h
|
209
src/raspberrypi/ctapdriver.cpp
Normal file
209
src/raspberrypi/ctapdriver.cpp
Normal file
@ -0,0 +1,209 @@
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI Target Emulator RaSCSI (*^..^*)
|
||||
// for Raspberry Pi
|
||||
//
|
||||
// Powered by XM6 TypeG Technology.
|
||||
// Copyright (C) 2016-2018 GIMONS
|
||||
//
|
||||
// Imported NetBSD support and some optimisation patch by Rin Okuyama.
|
||||
//
|
||||
// [ TAPドライバ ]
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "os.h"
|
||||
#include "xm6.h"
|
||||
#include "ctapdriver.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// コンストラクタ
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
CTapDriver::CTapDriver()
|
||||
{
|
||||
// 初期化
|
||||
m_hTAP = -1;
|
||||
memset(&m_MacAddr, 0, sizeof(m_MacAddr));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// 初期化
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
#ifdef __linux__
|
||||
BOOL FASTCALL CTapDriver::Init()
|
||||
{
|
||||
char dev[IFNAMSIZ] = "ras0";
|
||||
struct ifreq ifr;
|
||||
int ret;
|
||||
|
||||
ASSERT(this);
|
||||
|
||||
// TAPデバイス初期化
|
||||
if ((m_hTAP = open("/dev/net/tun", O_RDWR)) < 0) {
|
||||
printf("Error: can't open tun\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// IFF_NO_PI for no extra packet information
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
|
||||
strncpy(ifr.ifr_name, dev, IFNAMSIZ);
|
||||
if ((ret = ioctl(m_hTAP, TUNSETIFF, (void *)&ifr)) < 0) {
|
||||
printf("Error: can't ioctl TUNSETIFF\n");
|
||||
close(m_hTAP);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// MACアドレス取得
|
||||
ifr.ifr_addr.sa_family = AF_INET;
|
||||
if ((ret = ioctl(m_hTAP, SIOCGIFHWADDR, &ifr)) < 0) {
|
||||
printf("Error: can't ioctl SIOCGIFHWADDR\n");
|
||||
close(m_hTAP);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// MACアドレス保存
|
||||
memcpy(m_MacAddr, ifr.ifr_hwaddr.sa_data, sizeof(m_MacAddr));
|
||||
return TRUE;
|
||||
}
|
||||
#endif // __linux__
|
||||
|
||||
#ifdef __NetBSD__
|
||||
BOOL FASTCALL CTapDriver::Init()
|
||||
{
|
||||
struct ifreq ifr;
|
||||
struct ifaddrs *ifa, *a;
|
||||
|
||||
ASSERT(this);
|
||||
|
||||
// TAPデバイス初期化
|
||||
if ((m_hTAP = open("/dev/tap", O_RDWR)) < 0) {
|
||||
printf("Error: can't open tap\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// デバイス名取得
|
||||
if (ioctl(m_hTAP, TAPGIFNAME, (void *)&ifr) < 0) {
|
||||
printf("Error: can't ioctl TAPGIFNAME\n");
|
||||
close(m_hTAP);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// MACアドレス取得
|
||||
if (getifaddrs(&ifa) == -1) {
|
||||
printf("Error: can't getifaddrs\n");
|
||||
close(m_hTAP);
|
||||
return FALSE;
|
||||
}
|
||||
for (a = ifa; a != NULL; a = a->ifa_next)
|
||||
if (strcmp(ifr.ifr_name, a->ifa_name) == 0 &&
|
||||
a->ifa_addr->sa_family == AF_LINK)
|
||||
break;
|
||||
if (a == NULL) {
|
||||
printf("Error: can't get MAC address\n");
|
||||
close(m_hTAP);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// MACアドレス保存
|
||||
memcpy(m_MacAddr, LLADDR((struct sockaddr_dl *)a->ifa_addr),
|
||||
sizeof(m_MacAddr));
|
||||
freeifaddrs(ifa);
|
||||
|
||||
printf("Tap device : %s\n", ifr.ifr_name);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#endif // __NetBSD__
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// クリーンアップ
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
void FASTCALL CTapDriver::Cleanup()
|
||||
{
|
||||
ASSERT(this);
|
||||
|
||||
// TAPデバイス解放
|
||||
if (m_hTAP != -1) {
|
||||
close(m_hTAP);
|
||||
m_hTAP = -1;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// MACアドレス取得
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
void FASTCALL CTapDriver::GetMacAddr(BYTE *mac)
|
||||
{
|
||||
ASSERT(this);
|
||||
ASSERT(mac);
|
||||
|
||||
memcpy(mac, m_MacAddr, sizeof(m_MacAddr));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// 受信
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
int FASTCALL CTapDriver::Rx(BYTE *buf)
|
||||
{
|
||||
struct pollfd fds;
|
||||
DWORD dwReceived;
|
||||
|
||||
ASSERT(this);
|
||||
ASSERT(m_hTAP != -1);
|
||||
|
||||
// 受信可能なデータがあるか調べる
|
||||
fds.fd = m_hTAP;
|
||||
fds.events = POLLIN | POLLERR;
|
||||
fds.revents = 0;
|
||||
poll(&fds, 1, 0);
|
||||
if (!(fds.revents & POLLIN)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 受信
|
||||
dwReceived = read(m_hTAP, buf, ETH_FRAME_LEN);
|
||||
if (dwReceived == (DWORD)-1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 受信が有効であれば
|
||||
if (dwReceived > 0) {
|
||||
// FCSを除く最小フレームサイズ(60バイト)にパディング
|
||||
if (dwReceived < 60) {
|
||||
memset(buf + dwReceived, 0, 60 - dwReceived);
|
||||
dwReceived = 60;
|
||||
}
|
||||
|
||||
// ダミーのFCSを付加する
|
||||
memset(buf + dwReceived, 0, 4);
|
||||
dwReceived += 4;
|
||||
}
|
||||
|
||||
// バイト数を返却
|
||||
return dwReceived;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// 送信
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
int FASTCALL CTapDriver::Tx(BYTE *buf, int len)
|
||||
{
|
||||
ASSERT(this);
|
||||
ASSERT(m_hTAP != -1);
|
||||
|
||||
// 送信開始
|
||||
return write(m_hTAP, buf, len);
|
||||
}
|
53
src/raspberrypi/ctapdriver.h
Normal file
53
src/raspberrypi/ctapdriver.h
Normal file
@ -0,0 +1,53 @@
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI Target Emulator RaSCSI (*^..^*)
|
||||
// for Raspberry Pi
|
||||
//
|
||||
// Powered by XM6 TypeG Technology.
|
||||
// Copyright (C) 2016-2018 GIMONS
|
||||
//
|
||||
// Imported NetBSD support and some optimisation patch by Rin Okuyama.
|
||||
//
|
||||
// [ TAPドライバ ]
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#if !defined(ctapdriver_h)
|
||||
#define ctapdriver_h
|
||||
|
||||
#ifndef ETH_FRAME_LEN
|
||||
#define ETH_FRAME_LEN 1514
|
||||
#endif
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Tapドライバ
|
||||
//
|
||||
//===========================================================================
|
||||
class CTapDriver
|
||||
{
|
||||
public:
|
||||
// 基本ファンクション
|
||||
CTapDriver();
|
||||
// コンストラクタ
|
||||
BOOL FASTCALL Init();
|
||||
// 初期化
|
||||
void FASTCALL Cleanup();
|
||||
// クリーンアップ
|
||||
void FASTCALL GetMacAddr(BYTE *mac);
|
||||
// MACアドレス取得
|
||||
int FASTCALL Rx(BYTE *buf);
|
||||
// 受信
|
||||
int FASTCALL Tx(BYTE *buf, int len);
|
||||
// 送信
|
||||
|
||||
private:
|
||||
BYTE m_MacAddr[6];
|
||||
// MACアドレス
|
||||
BOOL m_bTxValid;
|
||||
// 送信有効フラグ
|
||||
int m_hTAP;
|
||||
// ディスクプリタ
|
||||
};
|
||||
|
||||
#endif // ctapdriver_h
|
9160
src/raspberrypi/disk.cpp
Normal file
9160
src/raspberrypi/disk.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1108
src/raspberrypi/disk.h
Normal file
1108
src/raspberrypi/disk.h
Normal file
File diff suppressed because it is too large
Load Diff
367
src/raspberrypi/fileio.cpp
Normal file
367
src/raspberrypi/fileio.cpp
Normal file
@ -0,0 +1,367 @@
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// X68000 EMULATOR "XM6"
|
||||
//
|
||||
// Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp)
|
||||
// Copyright (C) 2010-2018 GIMONS
|
||||
// [ ファイルI/O(RaSCSI用サブセット) ]
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "os.h"
|
||||
#include "xm6.h"
|
||||
#include "filepath.h"
|
||||
#include "fileio.h"
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// ファイルI/O
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// コンストラクタ
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
Fileio::Fileio()
|
||||
{
|
||||
// ワーク初期化
|
||||
handle = -1;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// デストラクタ
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
Fileio::~Fileio()
|
||||
{
|
||||
ASSERT(handle == -1);
|
||||
|
||||
// Releaseでの安全策
|
||||
Close();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// ロード
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL FASTCALL Fileio::Load(const Filepath& path, void *buffer, int size)
|
||||
{
|
||||
ASSERT(this);
|
||||
ASSERT(buffer);
|
||||
ASSERT(size > 0);
|
||||
ASSERT(handle < 0);
|
||||
|
||||
// オープン
|
||||
if (!Open(path, ReadOnly)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// 読み込み
|
||||
if (!Read(buffer, size)) {
|
||||
Close();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// クローズ
|
||||
Close();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// セーブ
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL FASTCALL Fileio::Save(const Filepath& path, void *buffer, int size)
|
||||
{
|
||||
ASSERT(this);
|
||||
ASSERT(buffer);
|
||||
ASSERT(size > 0);
|
||||
ASSERT(handle < 0);
|
||||
|
||||
// オープン
|
||||
if (!Open(path, WriteOnly)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// 読み込み
|
||||
if (!Write(buffer, size)) {
|
||||
Close();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// クローズ
|
||||
Close();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// オープン
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL FASTCALL Fileio::Open(LPCTSTR fname, OpenMode mode)
|
||||
{
|
||||
ASSERT(this);
|
||||
ASSERT(fname);
|
||||
ASSERT(handle < 0);
|
||||
|
||||
// ヌル文字列からの読み込みは必ず失敗させる
|
||||
if (fname[0] == _T('\0')) {
|
||||
handle = -1;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// モード別
|
||||
switch (mode) {
|
||||
// 読み込みのみ
|
||||
case ReadOnly:
|
||||
handle = open(fname, O_RDONLY);
|
||||
break;
|
||||
|
||||
// 書き込みのみ
|
||||
case WriteOnly:
|
||||
handle = open(fname, O_CREAT | O_WRONLY | O_TRUNC, 0666);
|
||||
break;
|
||||
|
||||
// 読み書き両方
|
||||
case ReadWrite:
|
||||
// CD-ROMからの読み込みはRWが成功してしまう
|
||||
if (access(fname, 0x06) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
handle = open(fname, O_RDWR);
|
||||
break;
|
||||
|
||||
// アペンド
|
||||
case Append:
|
||||
handle = open(fname, O_CREAT | O_WRONLY | O_APPEND, 0666);
|
||||
break;
|
||||
|
||||
// それ以外
|
||||
default:
|
||||
ASSERT(FALSE);
|
||||
break;
|
||||
}
|
||||
|
||||
// 結果評価
|
||||
if (handle == -1) {
|
||||
return FALSE;
|
||||
}
|
||||
ASSERT(handle >= 0);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// オープン
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL FASTCALL Fileio::OpenDIO(LPCTSTR fname, OpenMode mode)
|
||||
{
|
||||
ASSERT(this);
|
||||
ASSERT(fname);
|
||||
ASSERT(handle < 0);
|
||||
|
||||
// ヌル文字列からの読み込みは必ず失敗させる
|
||||
if (fname[0] == _T('\0')) {
|
||||
handle = -1;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// モード別
|
||||
switch (mode) {
|
||||
// 読み込みのみ
|
||||
case ReadOnly:
|
||||
handle = open(fname, O_RDONLY | O_DIRECT);
|
||||
break;
|
||||
|
||||
// 書き込みのみ
|
||||
case WriteOnly:
|
||||
handle = open(fname, O_CREAT | O_WRONLY | O_TRUNC | O_DIRECT, 0666);
|
||||
break;
|
||||
|
||||
// 読み書き両方
|
||||
case ReadWrite:
|
||||
// CD-ROMからの読み込みはRWが成功してしまう
|
||||
if (access(fname, 0x06) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
handle = open(fname, O_RDWR | O_DIRECT);
|
||||
break;
|
||||
|
||||
// アペンド
|
||||
case Append:
|
||||
handle = open(fname, O_CREAT | O_WRONLY | O_APPEND | O_DIRECT, 0666);
|
||||
break;
|
||||
|
||||
// それ以外
|
||||
default:
|
||||
ASSERT(FALSE);
|
||||
break;
|
||||
}
|
||||
|
||||
// 結果評価
|
||||
if (handle == -1) {
|
||||
return FALSE;
|
||||
}
|
||||
ASSERT(handle >= 0);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// オープン
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL FASTCALL Fileio::Open(const Filepath& path, OpenMode mode)
|
||||
{
|
||||
ASSERT(this);
|
||||
|
||||
return Open(path.GetPath(), mode);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// オープン
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL FASTCALL Fileio::OpenDIO(const Filepath& path, OpenMode mode)
|
||||
{
|
||||
ASSERT(this);
|
||||
|
||||
return OpenDIO(path.GetPath(), mode);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// 読み込み
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL FASTCALL Fileio::Read(void *buffer, int size)
|
||||
{
|
||||
int count;
|
||||
|
||||
ASSERT(this);
|
||||
ASSERT(buffer);
|
||||
ASSERT(size > 0);
|
||||
ASSERT(handle >= 0);
|
||||
|
||||
// 読み込み
|
||||
count = read(handle, buffer, size);
|
||||
if (count != size) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// 書き込み
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL FASTCALL Fileio::Write(const void *buffer, int size)
|
||||
{
|
||||
int count;
|
||||
|
||||
ASSERT(this);
|
||||
ASSERT(buffer);
|
||||
ASSERT(size > 0);
|
||||
ASSERT(handle >= 0);
|
||||
|
||||
// 読み込み
|
||||
count = write(handle, buffer, size);
|
||||
if (count != size) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// シーク
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL FASTCALL Fileio::Seek(off64_t offset, BOOL relative)
|
||||
{
|
||||
ASSERT(this);
|
||||
ASSERT(handle >= 0);
|
||||
ASSERT(offset >= 0);
|
||||
|
||||
// 相対シークならオフセットに現在値を追加
|
||||
if (relative) {
|
||||
offset += GetFilePos();
|
||||
}
|
||||
|
||||
if (lseek(handle, offset, SEEK_SET) != offset) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// ファイルサイズ取得
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
off64_t FASTCALL Fileio::GetFileSize()
|
||||
{
|
||||
off64_t cur;
|
||||
off64_t end;
|
||||
|
||||
ASSERT(this);
|
||||
ASSERT(handle >= 0);
|
||||
|
||||
// ファイル位置を64bitで取得
|
||||
cur = GetFilePos();
|
||||
|
||||
// ファイルサイズを64bitで取得
|
||||
end = lseek(handle, 0, SEEK_END);
|
||||
|
||||
// 位置を元に戻す
|
||||
Seek(cur);
|
||||
|
||||
return end;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// ファイル位置取得
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
off64_t FASTCALL Fileio::GetFilePos() const
|
||||
{
|
||||
off64_t pos;
|
||||
|
||||
ASSERT(this);
|
||||
ASSERT(handle >= 0);
|
||||
|
||||
// ファイル位置を64bitで取得
|
||||
pos = lseek(handle, 0, SEEK_CUR);
|
||||
return pos;
|
||||
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// クローズ
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
void FASTCALL Fileio::Close()
|
||||
{
|
||||
ASSERT(this);
|
||||
|
||||
if (handle != -1) {
|
||||
close(handle);
|
||||
handle = -1;
|
||||
}
|
||||
}
|
83
src/raspberrypi/fileio.h
Normal file
83
src/raspberrypi/fileio.h
Normal file
@ -0,0 +1,83 @@
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// X68000 EMULATOR "XM6"
|
||||
//
|
||||
// Copyright (C) 2001-2005 PI.(ytanaka@ipc-tokai.or.jp)
|
||||
// Copyright (C) 2013-2018 GIMONS
|
||||
// [ ファイルI/O(RaSCSI用サブセット) ]
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#if !defined(fileio_h)
|
||||
#define fileio_h
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// マクロ(Load,Save用)
|
||||
//
|
||||
//===========================================================================
|
||||
#define PROP_IMPORT(f, p) \
|
||||
if (!f->Read(&(p), sizeof(p))) {\
|
||||
return FALSE;\
|
||||
}\
|
||||
|
||||
#define PROP_EXPORT(f, p) \
|
||||
if (!f->Write(&(p), sizeof(p))) {\
|
||||
return FALSE;\
|
||||
}\
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// ファイルI/O
|
||||
//
|
||||
//===========================================================================
|
||||
class Fileio
|
||||
{
|
||||
public:
|
||||
enum OpenMode {
|
||||
ReadOnly, // 読み込みのみ
|
||||
WriteOnly, // 書き込みのみ
|
||||
ReadWrite, // 読み書き両方
|
||||
Append // アペンド
|
||||
};
|
||||
|
||||
public:
|
||||
Fileio();
|
||||
// コンストラクタ
|
||||
virtual ~Fileio();
|
||||
// デストラクタ
|
||||
BOOL FASTCALL Load(const Filepath& path, void *buffer, int size);
|
||||
// ROM,RAMロード
|
||||
BOOL FASTCALL Save(const Filepath& path, void *buffer, int size);
|
||||
// RAMセーブ
|
||||
|
||||
BOOL FASTCALL Open(LPCTSTR fname, OpenMode mode);
|
||||
// オープン
|
||||
BOOL FASTCALL OpenDIO(LPCTSTR fname, OpenMode mode);
|
||||
// オープン
|
||||
BOOL FASTCALL Open(const Filepath& path, OpenMode mode);
|
||||
// オープン
|
||||
BOOL FASTCALL OpenDIO(const Filepath& path, OpenMode mode);
|
||||
// オープン
|
||||
BOOL FASTCALL Seek(off64_t offset, BOOL relative = FALSE);
|
||||
// シーク
|
||||
BOOL FASTCALL Read(void *buffer, int size);
|
||||
// 読み込み
|
||||
BOOL FASTCALL Write(const void *buffer, int size);
|
||||
// 書き込み
|
||||
off64_t FASTCALL GetFileSize();
|
||||
// ファイルサイズ取得
|
||||
off64_t FASTCALL GetFilePos() const;
|
||||
// ファイル位置取得
|
||||
void FASTCALL Close();
|
||||
// クローズ
|
||||
BOOL FASTCALL IsValid() const { return (BOOL)(handle != -1); }
|
||||
// 有効チェック
|
||||
int FASTCALL GetHandle() const { return handle; }
|
||||
// ハンドル取得
|
||||
|
||||
private:
|
||||
int handle; // ファイルハンドル
|
||||
};
|
||||
|
||||
#endif // fileio_h
|
273
src/raspberrypi/filepath.cpp
Normal file
273
src/raspberrypi/filepath.cpp
Normal file
@ -0,0 +1,273 @@
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// X68000 EMULATOR "XM6"
|
||||
//
|
||||
// Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp)
|
||||
// Copyright (C) 2012-2018 GIMONS
|
||||
// [ ファイルパス(サブセット) ]
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "os.h"
|
||||
#include "xm6.h"
|
||||
#include "filepath.h"
|
||||
#include "fileio.h"
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// ファイルパス
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// コンストラクタ
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
Filepath::Filepath()
|
||||
{
|
||||
// クリア
|
||||
Clear();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// デストラクタ
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
Filepath::~Filepath()
|
||||
{
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// 代入演算子
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
Filepath& Filepath::operator=(const Filepath& path)
|
||||
{
|
||||
// パス設定(内部でSplitされる)
|
||||
SetPath(path.GetPath());
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// クリア
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
void FASTCALL Filepath::Clear()
|
||||
{
|
||||
ASSERT(this);
|
||||
|
||||
// パスおよび各部分をクリア
|
||||
m_szPath[0] = _T('\0');
|
||||
m_szDir[0] = _T('\0');
|
||||
m_szFile[0] = _T('\0');
|
||||
m_szExt[0] = _T('\0');
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// ファイル設定(ユーザ) MBCS用
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
void FASTCALL Filepath::SetPath(LPCSTR path)
|
||||
{
|
||||
ASSERT(this);
|
||||
ASSERT(path);
|
||||
ASSERT(strlen(path) < _MAX_PATH);
|
||||
|
||||
// パス名コピー
|
||||
strcpy(m_szPath, (LPTSTR)path);
|
||||
|
||||
// 分離
|
||||
Split();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// パス分離
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
void FASTCALL Filepath::Split()
|
||||
{
|
||||
LPTSTR pDir;
|
||||
LPTSTR pDirName;
|
||||
LPTSTR pBase;
|
||||
LPTSTR pBaseName;
|
||||
LPTSTR pExtName;
|
||||
|
||||
ASSERT(this);
|
||||
|
||||
// パーツを初期化
|
||||
m_szDir[0] = _T('\0');
|
||||
m_szFile[0] = _T('\0');
|
||||
m_szExt[0] = _T('\0');
|
||||
|
||||
// 分離
|
||||
pDir = strdup(m_szPath);
|
||||
pDirName = dirname(pDir);
|
||||
pBase = strdup(m_szPath);
|
||||
pBaseName = basename(pBase);
|
||||
pExtName = strrchr(pBaseName, '.');
|
||||
|
||||
// 転送
|
||||
if (pDirName) {
|
||||
strcpy(m_szDir, pDirName);
|
||||
strcat(m_szDir, "/");
|
||||
}
|
||||
|
||||
if (pExtName) {
|
||||
strcpy(m_szExt, pExtName);
|
||||
*pExtName = 0;
|
||||
}
|
||||
|
||||
if (pBaseName) {
|
||||
strcpy(m_szFile, pBaseName);
|
||||
}
|
||||
|
||||
// 解放
|
||||
free(pDir);
|
||||
free(pBase);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// パス合成
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
void FASTCALL Filepath::Make()
|
||||
{
|
||||
ASSERT(this);
|
||||
|
||||
// パス初期化
|
||||
m_szPath[0] = _T('\0');
|
||||
|
||||
// 合成
|
||||
strcat(m_szPath, m_szDir);
|
||||
strcat(m_szPath, m_szFile);
|
||||
strcat(m_szPath, m_szExt);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// クリアされているか
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL FASTCALL Filepath::IsClear() const
|
||||
{
|
||||
// Clear()の逆
|
||||
if ((m_szPath[0] == _T('\0')) &&
|
||||
(m_szDir[0] == _T('\0')) &&
|
||||
(m_szFile[0] == _T('\0')) &&
|
||||
(m_szExt[0] == _T('\0'))) {
|
||||
// 確かに、クリアされている
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// クリアされていない
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// ショート名取得
|
||||
// ※返されるポインタは一時的なもの。すぐコピーすること
|
||||
// ※FDIDiskのdisk.nameとの関係で、文字列は最大59文字+終端とすること
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
const char* FASTCALL Filepath::GetShort() const
|
||||
{
|
||||
char szFile[_MAX_FNAME];
|
||||
char szExt[_MAX_EXT];
|
||||
|
||||
ASSERT(this);
|
||||
|
||||
// TCHAR文字列からchar文字列へ変換
|
||||
strcpy(szFile, m_szFile);
|
||||
strcpy(szExt, m_szExt);
|
||||
|
||||
// 固定バッファへ合成
|
||||
strcpy(ShortName, szFile);
|
||||
strcat(ShortName, szExt);
|
||||
|
||||
// strlenで調べたとき、最大59になるように細工
|
||||
ShortName[59] = '\0';
|
||||
|
||||
// const charとして返す
|
||||
return (const char*)ShortName;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// ファイル名+拡張子取得
|
||||
// ※返されるポインタは一時的なもの。すぐコピーすること
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
LPCTSTR FASTCALL Filepath::GetFileExt() const
|
||||
{
|
||||
ASSERT(this);
|
||||
|
||||
// 固定バッファへ合成
|
||||
strcpy(FileExt, m_szExt);
|
||||
|
||||
// LPCTSTRとして返す
|
||||
return (LPCTSTR)FileExt;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// パス比較
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL FASTCALL Filepath::CmpPath(const Filepath& path) const
|
||||
{
|
||||
// パスが完全一致していればTRUE
|
||||
if (strcmp(path.GetPath(), GetPath()) == 0) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// セーブ
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL FASTCALL Filepath::Save(Fileio *fio, int /*ver*/)
|
||||
{
|
||||
ASSERT(this);
|
||||
ASSERT(fio);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// ロード
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL FASTCALL Filepath::Load(Fileio *fio, int /*ver*/)
|
||||
{
|
||||
ASSERT(this);
|
||||
ASSERT(fio);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// ショート名
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
char Filepath::ShortName[_MAX_FNAME + _MAX_DIR];
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// ファイル名+拡張子
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
TCHAR Filepath::FileExt[_MAX_FNAME + _MAX_DIR];
|
81
src/raspberrypi/filepath.h
Normal file
81
src/raspberrypi/filepath.h
Normal file
@ -0,0 +1,81 @@
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// X68000 EMULATOR "XM6"
|
||||
//
|
||||
// Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp)
|
||||
// Copyright (C) 2012-2018 GIMONS
|
||||
// [ ファイルパス(サブセット) ]
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#if !defined(filepath_h)
|
||||
#define filepath_h
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// 定数定義
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
#define FILEPATH_MAX _MAX_PATH
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// ファイルパス
|
||||
// ※代入演算子を用意すること
|
||||
//
|
||||
//===========================================================================
|
||||
class Filepath
|
||||
{
|
||||
public:
|
||||
Filepath();
|
||||
// コンストラクタ
|
||||
virtual ~Filepath();
|
||||
// デストラクタ
|
||||
Filepath& operator=(const Filepath& path);
|
||||
// 代入
|
||||
|
||||
void FASTCALL Clear();
|
||||
// クリア
|
||||
void FASTCALL SetPath(LPCSTR path);
|
||||
// ファイル設定(ユーザ) MBCS用
|
||||
BOOL FASTCALL IsClear() const;
|
||||
// クリアされているか
|
||||
LPCTSTR FASTCALL GetPath() const { return m_szPath; }
|
||||
// パス名取得
|
||||
const char* FASTCALL GetShort() const;
|
||||
// ショート名取得(const char*)
|
||||
LPCTSTR FASTCALL GetFileExt() const;
|
||||
// ショート名取得(LPCTSTR)
|
||||
BOOL FASTCALL CmpPath(const Filepath& path) const;
|
||||
// パス比較
|
||||
|
||||
BOOL FASTCALL Save(Fileio *fio, int ver);
|
||||
// セーブ
|
||||
BOOL FASTCALL Load(Fileio *fio, int ver);
|
||||
// ロード
|
||||
|
||||
private:
|
||||
void FASTCALL Split();
|
||||
// パス分割
|
||||
void FASTCALL Make();
|
||||
// パス合成
|
||||
void FASTCALL SetCurDir();
|
||||
// カレントディレクトリ設定
|
||||
TCHAR m_szPath[_MAX_PATH];
|
||||
// ファイルパス
|
||||
TCHAR m_szDrive[_MAX_DRIVE];
|
||||
// ドライブ
|
||||
TCHAR m_szDir[_MAX_DIR];
|
||||
// ディレクトリ
|
||||
TCHAR m_szFile[_MAX_FNAME];
|
||||
// ファイル
|
||||
TCHAR m_szExt[_MAX_EXT];
|
||||
// 拡張子
|
||||
|
||||
static char ShortName[_MAX_FNAME + _MAX_DIR];
|
||||
// ショート名(char)
|
||||
static TCHAR FileExt[_MAX_FNAME + _MAX_DIR];
|
||||
// ショート名(TCHAR)
|
||||
};
|
||||
|
||||
#endif // filepath_h
|
1192
src/raspberrypi/gpiobus.cpp
Normal file
1192
src/raspberrypi/gpiobus.cpp
Normal file
File diff suppressed because it is too large
Load Diff
479
src/raspberrypi/gpiobus.h
Normal file
479
src/raspberrypi/gpiobus.h
Normal file
@ -0,0 +1,479 @@
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI Target Emulator RaSCSI (*^..^*)
|
||||
// for Raspberry Pi
|
||||
//
|
||||
// Powered by XM6 TypeG Technology.
|
||||
// Copyright (C) 2016-2018 GIMONS
|
||||
// [ GPIO-SCSIバス ]
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#if !defined(gpiobus_h)
|
||||
#define gpiobus_h
|
||||
|
||||
#include "scsi.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// 接続方法定義の選択
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
#define CONNECT_TYPE_STANDARD // 標準(SCSI論理,標準ピンアサイン)
|
||||
//#define CONNECT_TYPE_FULLSPEC // フルスペック(SCSI論理,標準ピンアサイン)
|
||||
//#define CONNECT_TYPE_AIBOM // AIBOM版(正論理,固有ピンアサイン)
|
||||
//#define CONNECT_TYPE_GAMERNIUM // GAMERnium.com版(標準論理,固有ピンアサイン)
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// 信号制御論理及びピンアサインカスタマイズ
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SIGNAL_CONTROL_MODE:信号制御モード選択
|
||||
// Version1.22から信号制御の論理をカスタマイズできます。
|
||||
//
|
||||
// 0:SCSI論理仕様
|
||||
// 直結またはHPに公開した74LS641-1等を使用する変換基板
|
||||
// アーサート:0V
|
||||
// ネゲート :オープンコレクタ出力(バスから切り離す)
|
||||
//
|
||||
// 1:負論理仕様(負論理->SCSI論理への変換基板を使用する場合)
|
||||
// 現時点でこの仕様による変換基板は存在しません
|
||||
// アーサート:0V -> (CONVERT) -> 0V
|
||||
// ネゲート :3.3V -> (CONVERT) -> オープンコレクタ出力
|
||||
//
|
||||
// 2:正論理仕様(正論理->SCSI論理への変換基板を使用する場合)
|
||||
// RaSCSI Adapter Rev.C @132sync等
|
||||
//
|
||||
// アーサート:3.3V -> (CONVERT) -> 0V
|
||||
// ネゲート :0V -> (CONVERT) -> オープンコレクタ出力
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// 制御信号ピンアサイン設定
|
||||
// 制御信号に対するGPIOピンのマッピングテーブルです。
|
||||
//
|
||||
// 制御信号
|
||||
// PIN_ACT
|
||||
// SCSIコマンドを処理中の状態を示す信号のピン番号。
|
||||
// PIN_ENB
|
||||
// 起動から終了の間の有効信号を示す信号のピン番号。
|
||||
// PIN_TAD
|
||||
// ターゲット信号(BSY,IO,CD,MSG,REG)の入出力方向を示す信号のピン番号。
|
||||
// PIN_IND
|
||||
// イニシーエータ信号(SEL,ATN,RST,ACK)の入出力方向を示す信号のピン番号。
|
||||
// PIN_DTD
|
||||
// データ信号(DT0...DT7,DP)の入出力方向を示す信号のピン番号。
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// 制御信号出力論理
|
||||
// 0V:FALSE 3.3V:TRUEで指定します。
|
||||
//
|
||||
// ACT_ON
|
||||
// PIN_ACT信号の論理です。
|
||||
// ENB_ON
|
||||
// PIN_ENB信号の論理です。
|
||||
// TAD_IN
|
||||
// PIN_TAD入力方向時の論理です。
|
||||
// IND_IN
|
||||
// PIN_ENB入力方向時の論理です。
|
||||
// DTD_IN
|
||||
// PIN_ENB入力方向時の論理です。
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI信号ピンアサイン設定
|
||||
// SCSIの信号に対するGPIOピンのマッピングテーブルです。
|
||||
// PIN_DT0~PIN_SEL
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifdef CONNECT_TYPE_STANDARD
|
||||
//
|
||||
// RaSCSI 標準(SCSI論理,標準ピンアサイン)
|
||||
//
|
||||
#define CONNECT_DESC "STANDARD" // 起動時メッセージ
|
||||
|
||||
// 信号制御モード選択
|
||||
#define SIGNAL_CONTROL_MODE 0 // SCSI論理仕様
|
||||
|
||||
// 制御信号ピンアサイン(-1の場合は制御無し)
|
||||
#define PIN_ACT 4 // ACTIVE
|
||||
#define PIN_ENB 5 // ENABLE
|
||||
#define PIN_IND -1 // INITIATOR CTRL DIRECTION
|
||||
#define PIN_TAD -1 // TARGET CTRL DIRECTION
|
||||
#define PIN_DTD -1 // DATA DIRECTION
|
||||
|
||||
// 制御信号出力論理
|
||||
#define ACT_ON TRUE // ACTIVE SIGNAL ON
|
||||
#define ENB_ON TRUE // ENABLE SIGNAL ON
|
||||
#define IND_IN FALSE // INITIATOR SIGNAL INPUT
|
||||
#define TAD_IN FALSE // TARGET SIGNAL INPUT
|
||||
#define DTD_IN TRUE // DATA SIGNAL INPUT
|
||||
|
||||
// SCSI信号ピンアサイン
|
||||
#define PIN_DT0 10 // データ0
|
||||
#define PIN_DT1 11 // データ1
|
||||
#define PIN_DT2 12 // データ2
|
||||
#define PIN_DT3 13 // データ3
|
||||
#define PIN_DT4 14 // データ4
|
||||
#define PIN_DT5 15 // データ5
|
||||
#define PIN_DT6 16 // データ6
|
||||
#define PIN_DT7 17 // データ7
|
||||
#define PIN_DP 18 // パリティ
|
||||
#define PIN_ATN 19 // ATN
|
||||
#define PIN_RST 20 // RST
|
||||
#define PIN_ACK 21 // ACK
|
||||
#define PIN_REQ 22 // REQ
|
||||
#define PIN_MSG 23 // MSG
|
||||
#define PIN_CD 24 // CD
|
||||
#define PIN_IO 25 // IO
|
||||
#define PIN_BSY 26 // BSY
|
||||
#define PIN_SEL 27 // SEL
|
||||
#endif
|
||||
|
||||
#ifdef CONNECT_TYPE_FULLSPEC
|
||||
//
|
||||
// RaSCSI 標準(SCSI論理,標準ピンアサイン)
|
||||
//
|
||||
#define CONNECT_DESC "FULLSPEC" // 起動時メッセージ
|
||||
|
||||
// 信号制御モード選択
|
||||
#define SIGNAL_CONTROL_MODE 0 // SCSI論理仕様
|
||||
|
||||
// 制御信号ピンアサイン(-1の場合は制御無し)
|
||||
#define PIN_ACT 4 // ACTIVE
|
||||
#define PIN_ENB 5 // ENABLE
|
||||
#define PIN_IND 6 // INITIATOR CTRL DIRECTION
|
||||
#define PIN_TAD 7 // TARGET CTRL DIRECTION
|
||||
#define PIN_DTD 8 // DATA DIRECTION
|
||||
|
||||
// 制御信号出力論理
|
||||
#define ACT_ON TRUE // ACTIVE SIGNAL ON
|
||||
#define ENB_ON TRUE // ENABLE SIGNAL ON
|
||||
#define IND_IN FALSE // INITIATOR SIGNAL INPUT
|
||||
#define TAD_IN FALSE // TARGET SIGNAL INPUT
|
||||
#define DTD_IN TRUE // DATA SIGNAL INPUT
|
||||
|
||||
// SCSI信号ピンアサイン
|
||||
#define PIN_DT0 10 // データ0
|
||||
#define PIN_DT1 11 // データ1
|
||||
#define PIN_DT2 12 // データ2
|
||||
#define PIN_DT3 13 // データ3
|
||||
#define PIN_DT4 14 // データ4
|
||||
#define PIN_DT5 15 // データ5
|
||||
#define PIN_DT6 16 // データ6
|
||||
#define PIN_DT7 17 // データ7
|
||||
#define PIN_DP 18 // パリティ
|
||||
#define PIN_ATN 19 // ATN
|
||||
#define PIN_RST 20 // RST
|
||||
#define PIN_ACK 21 // ACK
|
||||
#define PIN_REQ 22 // REQ
|
||||
#define PIN_MSG 23 // MSG
|
||||
#define PIN_CD 24 // CD
|
||||
#define PIN_IO 25 // IO
|
||||
#define PIN_BSY 26 // BSY
|
||||
#define PIN_SEL 27 // SEL
|
||||
#endif
|
||||
|
||||
#ifdef CONNECT_TYPE_AIBOM
|
||||
//
|
||||
// RaSCSI Adapter あいぼむ版
|
||||
//
|
||||
|
||||
#define CONNECT_DESC "AIBOM PRODUCTS version" // 起動時メッセージ
|
||||
|
||||
// 信号制御モード選択
|
||||
#define SIGNAL_CONTROL_MODE 2 // SCSI正論理仕様
|
||||
|
||||
// 制御信号出力論理
|
||||
#define ACT_ON TRUE // ACTIVE SIGNAL ON
|
||||
#define ENB_ON TRUE // ENABLE SIGNAL ON
|
||||
#define IND_IN FALSE // INITIATOR SIGNAL INPUT
|
||||
#define TAD_IN FALSE // TARGET SIGNAL INPUT
|
||||
#define DTD_IN FALSE // DATA SIGNAL INPUT
|
||||
|
||||
// 制御信号ピンアサイン(-1の場合は制御無し)
|
||||
#define PIN_ACT 4 // ACTIVE
|
||||
#define PIN_ENB 17 // ENABLE
|
||||
#define PIN_IND 27 // INITIATOR CTRL DIRECTION
|
||||
#define PIN_TAD -1 // TARGET CTRL DIRECTION
|
||||
#define PIN_DTD 18 // DATA DIRECTION
|
||||
|
||||
// SCSI信号ピンアサイン
|
||||
#define PIN_DT0 6 // データ0
|
||||
#define PIN_DT1 12 // データ1
|
||||
#define PIN_DT2 13 // データ2
|
||||
#define PIN_DT3 16 // データ3
|
||||
#define PIN_DT4 19 // データ4
|
||||
#define PIN_DT5 20 // データ5
|
||||
#define PIN_DT6 26 // データ6
|
||||
#define PIN_DT7 21 // データ7
|
||||
#define PIN_DP 5 // パリティ
|
||||
#define PIN_ATN 22 // ATN
|
||||
#define PIN_RST 25 // RST
|
||||
#define PIN_ACK 10 // ACK
|
||||
#define PIN_REQ 7 // REQ
|
||||
#define PIN_MSG 9 // MSG
|
||||
#define PIN_CD 11 // CD
|
||||
#define PIN_IO 23 // IO
|
||||
#define PIN_BSY 24 // BSY
|
||||
#define PIN_SEL 8 // SEL
|
||||
#endif
|
||||
|
||||
#ifdef CONNECT_TYPE_GAMERNIUM
|
||||
//
|
||||
// RaSCSI Adapter GAMERnium.com版
|
||||
//
|
||||
|
||||
#define CONNECT_DESC "GAMERnium.com version"// 起動時メッセージ
|
||||
|
||||
// 信号制御モード選択
|
||||
#define SIGNAL_CONTROL_MODE 0 // SCSI論理仕様
|
||||
|
||||
// 制御信号出力論理
|
||||
#define ACT_ON TRUE // ACTIVE SIGNAL ON
|
||||
#define ENB_ON TRUE // ENABLE SIGNAL ON
|
||||
#define IND_IN FALSE // INITIATOR SIGNAL INPUT
|
||||
#define TAD_IN FALSE // TARGET SIGNAL INPUT
|
||||
#define DTD_IN TRUE // DATA SIGNAL INPUT
|
||||
|
||||
// 制御信号ピンアサイン(-1の場合は制御無し)
|
||||
#define PIN_ACT 14 // ACTIVE
|
||||
#define PIN_ENB 6 // ENABLE
|
||||
#define PIN_IND 7 // INITIATOR CTRL DIRECTION
|
||||
#define PIN_TAD 8 // TARGET CTRL DIRECTION
|
||||
#define PIN_DTD 5 // DATA DIRECTION
|
||||
|
||||
// SCSI信号ピンアサイン
|
||||
#define PIN_DT0 21 // データ0
|
||||
#define PIN_DT1 26 // データ1
|
||||
#define PIN_DT2 20 // データ2
|
||||
#define PIN_DT3 19 // データ3
|
||||
#define PIN_DT4 16 // データ4
|
||||
#define PIN_DT5 13 // データ5
|
||||
#define PIN_DT6 12 // データ6
|
||||
#define PIN_DT7 11 // データ7
|
||||
#define PIN_DP 25 // パリティ
|
||||
#define PIN_ATN 10 // ATN
|
||||
#define PIN_RST 22 // RST
|
||||
#define PIN_ACK 24 // ACK
|
||||
#define PIN_REQ 15 // REQ
|
||||
#define PIN_MSG 17 // MSG
|
||||
#define PIN_CD 18 // CD
|
||||
#define PIN_IO 4 // IO
|
||||
#define PIN_BSY 27 // BSY
|
||||
#define PIN_SEL 23 // SEL
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// 定数宣言(GPIO)
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
#define GPIO_OFFSET 0x200000
|
||||
#define PADS_OFFSET 0x100000
|
||||
#define GPIO_INPUT 0
|
||||
#define GPIO_OUTPUT 1
|
||||
#define GPIO_PULLNONE 0
|
||||
#define GPIO_PULLDOWN 1
|
||||
#define GPIO_PULLUP 2
|
||||
#define GPIO_FSEL_0 0
|
||||
#define GPIO_FSEL_1 1
|
||||
#define GPIO_FSEL_2 2
|
||||
#define GPIO_FSEL_3 3
|
||||
#define GPIO_SET_0 7
|
||||
#define GPIO_CLR_0 10
|
||||
#define GPIO_LEV_0 13
|
||||
#define GPIO_EDS_0 16
|
||||
#define GPIO_REN_0 19
|
||||
#define GPIO_FEN_0 22
|
||||
#define GPIO_HEN_0 25
|
||||
#define GPIO_LEN_0 28
|
||||
#define GPIO_AREN_0 31
|
||||
#define GPIO_AFEN_0 34
|
||||
#define GPIO_PUD 37
|
||||
#define GPIO_CLK_0 38
|
||||
#define PAD_0_27 11
|
||||
|
||||
#define GPIO_INEDGE ((1 << PIN_BSY) | \
|
||||
(1 << PIN_SEL) | \
|
||||
(1 << PIN_ATN) | \
|
||||
(1 << PIN_ACK) | \
|
||||
(1 << PIN_RST))
|
||||
|
||||
#define GPIO_MCI ((1 << PIN_MSG) | \
|
||||
(1 << PIN_CD) | \
|
||||
(1 << PIN_IO))
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// 定数宣言(制御信号)
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
#define ACT_OFF !ACT_ON
|
||||
#define ENB_OFF !ENB_ON
|
||||
#define TAD_OUT !TAD_IN
|
||||
#define IND_OUT !IND_IN
|
||||
#define DTD_OUT !DTD_IN
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// 定数宣言(SCSI)
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
#define IN GPIO_INPUT
|
||||
#define OUT GPIO_OUTPUT
|
||||
#define ON TRUE
|
||||
#define OFF FALSE
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// 定数宣言(ドライバ)
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
#define DEVICE_NAME "rascsidrv"
|
||||
#define DRIVER_PATH "/dev/" DEVICE_NAME
|
||||
#define IOCTL_INIT 0x100
|
||||
#define IOCTL_MODE 0x101
|
||||
#define IOCTL_PADS 0x102
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// クラス定義
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
class GPIOBUS : public BUS
|
||||
{
|
||||
public:
|
||||
// 基本ファンクション
|
||||
GPIOBUS();
|
||||
// コンストラクタ
|
||||
virtual ~GPIOBUS();
|
||||
// デストラクタ
|
||||
BOOL FASTCALL Init(mode_e mode = TARGET);
|
||||
// 初期化
|
||||
void FASTCALL Reset();
|
||||
// リセット
|
||||
void FASTCALL Cleanup();
|
||||
// クリーンアップ
|
||||
|
||||
DWORD FASTCALL Aquire();
|
||||
// 信号取り込み
|
||||
|
||||
BOOL FASTCALL GetBSY();
|
||||
// BSYシグナル取得
|
||||
void FASTCALL SetBSY(BOOL ast);
|
||||
// BSYシグナル設定
|
||||
|
||||
BOOL FASTCALL GetSEL();
|
||||
// SELシグナル取得
|
||||
void FASTCALL SetSEL(BOOL ast);
|
||||
// SELシグナル設定
|
||||
|
||||
BOOL FASTCALL GetATN();
|
||||
// ATNシグナル取得
|
||||
void FASTCALL SetATN(BOOL ast);
|
||||
// ATNシグナル設定
|
||||
|
||||
BOOL FASTCALL GetACK();
|
||||
// ACKシグナル取得
|
||||
void FASTCALL SetACK(BOOL ast);
|
||||
// ACKシグナル設定
|
||||
|
||||
BOOL FASTCALL GetRST();
|
||||
// RSTシグナル取得
|
||||
void FASTCALL SetRST(BOOL ast);
|
||||
// RSTシグナル設定
|
||||
|
||||
BOOL FASTCALL GetMSG();
|
||||
// MSGシグナル取得
|
||||
void FASTCALL SetMSG(BOOL ast);
|
||||
// MSGシグナル設定
|
||||
|
||||
BOOL FASTCALL GetCD();
|
||||
// CDシグナル取得
|
||||
void FASTCALL SetCD(BOOL ast);
|
||||
// CDシグナル設定
|
||||
|
||||
BOOL FASTCALL GetIO();
|
||||
// IOシグナル取得
|
||||
void FASTCALL SetIO(BOOL ast);
|
||||
// IOシグナル設定
|
||||
|
||||
BOOL FASTCALL GetREQ();
|
||||
// REQシグナル取得
|
||||
void FASTCALL SetREQ(BOOL ast);
|
||||
// REQシグナル設定
|
||||
|
||||
BYTE FASTCALL GetDAT();
|
||||
// データシグナル取得
|
||||
void FASTCALL SetDAT(BYTE dat);
|
||||
// データシグナル設定
|
||||
int FASTCALL ReceiveHandShake(BYTE *buf, int count);
|
||||
// データ受信ハンドシェイク
|
||||
int FASTCALL SendHandShake(BYTE *buf, int count);
|
||||
// データ送信ハンドシェイク
|
||||
|
||||
// タイマ関係
|
||||
void FASTCALL SleepNsec(DWORD nsec);
|
||||
// ナノ秒単位のスリープ
|
||||
|
||||
private:
|
||||
void FASTCALL DrvConfig(DWORD drive);
|
||||
// GPIOドライブ能力設定
|
||||
void FASTCALL PinConfig(int pin, int mode);
|
||||
// GPIOピン機能設定(入出力設定)
|
||||
void FASTCALL PullConfig(int pin, int mode);
|
||||
// GPIOピン機能設定(プルアップ/ダウン)
|
||||
void FASTCALL PinSetSignal(int pin, BOOL ast);
|
||||
// GPIOピン出力信号設定
|
||||
void FASTCALL MakeTable();
|
||||
// ワークテーブル作成
|
||||
void FASTCALL SetControl(int pin, BOOL ast);
|
||||
// 制御信号設定
|
||||
void FASTCALL SetMode(int pin, int mode);
|
||||
// SCSI入出力モード設定
|
||||
BOOL FASTCALL GetSignal(int pin);
|
||||
// SCSI入力信号値取得
|
||||
void FASTCALL SetSignal(int pin, BOOL ast);
|
||||
// SCSI出力信号値設定
|
||||
|
||||
mode_e actmode; // 動作モード
|
||||
|
||||
volatile DWORD *gpio; // GPIOレジスタ
|
||||
|
||||
volatile DWORD *pads; // PADSレジスタ
|
||||
|
||||
volatile DWORD *level; // GPIO入力レベル
|
||||
|
||||
DWORD gpfsel[4]; // GPFSEL0-4バックアップ
|
||||
|
||||
DWORD signals; // バス全信号
|
||||
|
||||
#if SIGNAL_CONTROL_MODE == 0
|
||||
DWORD tblDatMsk[3][256]; // データマスク用テーブル
|
||||
|
||||
DWORD tblDatSet[3][256]; // データ設定用テーブル
|
||||
#else
|
||||
DWORD tblDatMsk[256]; // データマスク用テーブル
|
||||
|
||||
DWORD tblDatSet[256]; // データ設定用テーブル
|
||||
#endif
|
||||
|
||||
int drvfd; // カーネルドライバファイルディスクプリタ
|
||||
|
||||
static const int SignalTable[19]; // シグナルテーブル
|
||||
};
|
||||
|
||||
#endif // gpiobus_h
|
9
src/raspberrypi/kernelmodule/Makefile
Normal file
9
src/raspberrypi/kernelmodule/Makefile
Normal file
@ -0,0 +1,9 @@
|
||||
KERNEL_HEADERS=/lib/modules/$(shell uname -r)/build
|
||||
obj-m := rascsidrv.o
|
||||
ccflags-y := -O3
|
||||
|
||||
all:
|
||||
$(MAKE) -C $(KERNEL_HEADERS) M=$(PWD) modules
|
||||
|
||||
clean:
|
||||
$(MAKE) -C $(KERNEL_HEADERS) M=$(PWD) clean
|
1122
src/raspberrypi/kernelmodule/rascsidrv.c
Normal file
1122
src/raspberrypi/kernelmodule/rascsidrv.c
Normal file
File diff suppressed because it is too large
Load Diff
31
src/raspberrypi/log.h
Normal file
31
src/raspberrypi/log.h
Normal file
@ -0,0 +1,31 @@
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI Target Emulator RaSCSI (*^..^*)
|
||||
// for Raspberry Pi
|
||||
//
|
||||
// Powered by XM6 TypeG Technology.
|
||||
// Copyright (C) 2016-2018 GIMONS
|
||||
// [ ログ ]
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#if !defined(log_h)
|
||||
#define log_h
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// ログ
|
||||
//
|
||||
//===========================================================================
|
||||
class Log
|
||||
{
|
||||
public:
|
||||
enum loglevel {
|
||||
Detail, // 詳細レベル
|
||||
Normal, // 通常レベル
|
||||
Warning, // 警告レベル
|
||||
Debug // デバッグレベル
|
||||
};
|
||||
};
|
||||
|
||||
#endif // log_h
|
145
src/raspberrypi/os.h
Normal file
145
src/raspberrypi/os.h
Normal file
@ -0,0 +1,145 @@
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI Target Emulator RaSCSI (*^..^*)
|
||||
// for Raspberry Pi
|
||||
//
|
||||
// Powered by XM6 TypeG Technology.
|
||||
// Copyright (C) 2016-2018 GIMONS
|
||||
//
|
||||
// Imported NetBSD support and some optimisation patch by Rin Okuyama.
|
||||
//
|
||||
// [ OS固有 ]
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#if !defined(os_h)
|
||||
#define os_h
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// #define
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
#ifndef _LARGEFILE64_SOURCE
|
||||
#define _LARGEFILE64_SOURCE
|
||||
#endif
|
||||
|
||||
#ifndef _FILE_OFFSET_BITS
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// #include
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
#include <utime.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <sched.h>
|
||||
#include <poll.h>
|
||||
#include <pthread.h>
|
||||
#include <dirent.h>
|
||||
#include <iconv.h>
|
||||
#include <libgen.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#if defined(__linux__)
|
||||
#include <linux/if.h>
|
||||
#include <linux/if_tun.h>
|
||||
#elif defined(__NetBSD__)
|
||||
#include <sys/param.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_tap.h>
|
||||
#include <ifaddrs.h>
|
||||
#else
|
||||
#error unsupported platform
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// 基本マクロ
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
#undef FASTCALL
|
||||
#define FASTCALL
|
||||
|
||||
#undef CDECL
|
||||
#define CDECL
|
||||
|
||||
#undef INLINE
|
||||
#define INLINE
|
||||
|
||||
#if !defined(ASSERT)
|
||||
#if !defined(NDEBUG)
|
||||
#define ASSERT(cond) assert(cond)
|
||||
#else
|
||||
#define ASSERT(cond) ((void)0)
|
||||
#endif // NDEBUG
|
||||
#endif // ASSERT
|
||||
|
||||
#if !defined(ASSERT_DIAG)
|
||||
#if !defined(NDEBUG)
|
||||
#define ASSERT_DIAG() AssertDiag()
|
||||
#else
|
||||
#define ASSERT_DIAG() ((void)0)
|
||||
#endif // NDEBUG
|
||||
#endif // ASSERT_DIAG
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// 基本型定義
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
typedef unsigned char BYTE;
|
||||
typedef unsigned short WORD;
|
||||
typedef unsigned long DWORD;
|
||||
typedef int BOOL;
|
||||
typedef char TCHAR;
|
||||
typedef char *LPTSTR;
|
||||
typedef const char *LPCTSTR;
|
||||
typedef const char *LPCSTR;
|
||||
|
||||
#if !defined(FALSE)
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#if !defined(TRUE)
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#if !defined(_T)
|
||||
#define _T(x) x
|
||||
#endif
|
||||
|
||||
#define _MAX_PATH 260
|
||||
#define _MAX_DRIVE 3
|
||||
#define _MAX_DIR 256
|
||||
#define _MAX_FNAME 256
|
||||
#define _MAX_EXT 256
|
||||
|
||||
#define off64_t off_t
|
||||
|
||||
#define xstrcasecmp strcasecmp
|
||||
#define xstrncasecmp strncasecmp
|
||||
|
||||
#endif // os_h
|
758
src/raspberrypi/rascsi.cpp
Normal file
758
src/raspberrypi/rascsi.cpp
Normal file
@ -0,0 +1,758 @@
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI Target Emulator RaSCSI (*^..^*)
|
||||
// for Raspberry Pi
|
||||
//
|
||||
// Powered by XM6 TypeG Technology.
|
||||
// Copyright (C) 2016-2018 GIMONS
|
||||
// [ メイン ]
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "os.h"
|
||||
#include "xm6.h"
|
||||
#include "fileio.h"
|
||||
#include "filepath.h"
|
||||
#include "disk.h"
|
||||
#include "gpiobus.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// 変数宣言
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
enum {
|
||||
CtrlMax = 8, // 最大SCSIコントローラ数
|
||||
};
|
||||
|
||||
SASIDEV *ctrl[CtrlMax]; // コントローラ
|
||||
Disk *disk[CtrlMax]; // ディスク
|
||||
Filepath image[CtrlMax]; // イメージファイルパス
|
||||
GPIOBUS bus; // バス
|
||||
BUS::phase_t phase; // フェーズ
|
||||
int actid; // アクティブなコントローラID
|
||||
volatile BOOL bRun; // 実行中フラグ
|
||||
|
||||
BOOL bServer; // サーバーモードフラグ
|
||||
int monfd; // モニター用ソケットFD
|
||||
pthread_t monthread; // モニタースレッド
|
||||
static void *MonThread(void *param);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// シグナル処理
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
void KillHandler(int sig)
|
||||
{
|
||||
// 停止指示
|
||||
bRun = FALSE;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// バナー出力
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL Banner(int argc, char* argv[])
|
||||
{
|
||||
printf("SCSI Target Emulator RaSCSI(*^..^*) ");
|
||||
printf("version %01d.%01d%01d\n",
|
||||
(int)((VERSION >> 8) & 0xf),
|
||||
(int)((VERSION >> 4) & 0xf),
|
||||
(int)((VERSION ) & 0xf));
|
||||
printf("Powered by XM6 TypeG Technology / ");
|
||||
printf("Copyright (C) 2016-2018 GIMONS\n");
|
||||
printf("Connect type : %s\n", CONNECT_DESC);
|
||||
|
||||
if (argc > 1 && strcmp(argv[1], "-h") == 0) {
|
||||
printf("\n");
|
||||
printf("Usage: %s [-ID{0|1|2|3|4|5|6|7} FILE] ...\n\n", argv[0]);
|
||||
printf(" IDn is SCSI identification number.\n");
|
||||
printf(" FILE is disk image file.\n\n");
|
||||
printf(" Detected images type based on file extension.\n");
|
||||
printf(" hdf : SASI HD image(XM6 SASI HD image)\n");
|
||||
printf(" hds : SCSI HD image(XM6 SCSI HD image)\n");
|
||||
printf(" hdn : SCSI HD image(NEC GENUINE)\n");
|
||||
printf(" hdi : SCSI HD image(Anex86 HD image)\n");
|
||||
printf(" nhd : SCSI HD image(T98Next HD image)\n");
|
||||
printf(" hda : SCSI HD image(APPLE GENUINE)\n");
|
||||
printf(" mos : SCSI MO image(XM6 SCSI MO image)\n");
|
||||
printf(" iso : SCSI CD image(ISO 9660 image)\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// 初期化
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL Init()
|
||||
{
|
||||
int i;
|
||||
struct sockaddr_in server;
|
||||
|
||||
// モニター用ソケット生成
|
||||
monfd = socket(PF_INET, SOCK_STREAM, 0);
|
||||
memset(&server, 0, sizeof(server));
|
||||
server.sin_family = PF_INET;
|
||||
server.sin_port = htons(6868);
|
||||
server.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
if (bind(monfd, (struct sockaddr *)&server,
|
||||
sizeof(struct sockaddr_in)) < 0) {
|
||||
if (errno != EADDRINUSE) {
|
||||
return FALSE;
|
||||
}
|
||||
bServer = FALSE;
|
||||
return TRUE;
|
||||
} else {
|
||||
bServer = TRUE;
|
||||
}
|
||||
|
||||
// 割り込みハンドラ設定
|
||||
if (signal(SIGINT, KillHandler) == SIG_ERR) {
|
||||
return FALSE;
|
||||
}
|
||||
if (signal(SIGHUP, KillHandler) == SIG_ERR) {
|
||||
return FALSE;
|
||||
}
|
||||
if (signal(SIGTERM, KillHandler) == SIG_ERR) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// GPIO初期化
|
||||
if (!bus.Init()) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// コントローラ初期化
|
||||
for (i = 0; i < CtrlMax; i++) {
|
||||
ctrl[i] = NULL;
|
||||
}
|
||||
|
||||
// ディスク初期化
|
||||
for (i = 0; i < CtrlMax; i++) {
|
||||
disk[i] = NULL;
|
||||
}
|
||||
|
||||
// イメージパス初期化
|
||||
for (i = 0; i < CtrlMax; i++) {
|
||||
image[i].Clear();
|
||||
}
|
||||
|
||||
// アクティブID初期化
|
||||
actid = -1;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// クリーンアップ
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
void Cleanup()
|
||||
{
|
||||
int i;
|
||||
|
||||
// ディスク削除
|
||||
for (i = 0; i < CtrlMax; i++) {
|
||||
if (disk[i]) {
|
||||
delete disk[i];
|
||||
disk[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// コントローラ削除
|
||||
for (i = 0; i < CtrlMax; i++) {
|
||||
if (ctrl[i]) {
|
||||
delete ctrl[i];
|
||||
ctrl[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// バスをクリーンアップ
|
||||
bus.Cleanup();
|
||||
|
||||
// モニター用ソケットクローズ
|
||||
if (monfd >= 0) {
|
||||
close(monfd);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// リセット
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
void Reset()
|
||||
{
|
||||
int i;
|
||||
|
||||
// アクティブID初期化
|
||||
actid = -1;
|
||||
|
||||
// コントローラリセット
|
||||
for (i = 0; i < CtrlMax; i++) {
|
||||
if (ctrl[i]) {
|
||||
ctrl[i]->Reset();
|
||||
}
|
||||
}
|
||||
|
||||
// バス信号線をリセット
|
||||
bus.Reset();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// デバイス一覧表示
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
void ListDevice(FILE *fp)
|
||||
{
|
||||
int i;
|
||||
Filepath filepath;
|
||||
BOOL find;
|
||||
char type[5];
|
||||
|
||||
find = FALSE;
|
||||
type[4] = 0;
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (disk[i] == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// ヘッダー出力
|
||||
if (!find) {
|
||||
fprintf(fp, "\n");
|
||||
fprintf(fp, "---+------+---------------------------------------\n");
|
||||
fprintf(fp, "ID | TYPE | DEVICE STATUS\n");
|
||||
fprintf(fp, "---+------+---------------------------------------\n");
|
||||
find = TRUE;
|
||||
}
|
||||
|
||||
// ID,タイプ出力
|
||||
type[0] = (char)(disk[i]->GetID() >> 24);
|
||||
type[1] = (char)(disk[i]->GetID() >> 16);
|
||||
type[2] = (char)(disk[i]->GetID() >> 8);
|
||||
type[3] = (char)(disk[i]->GetID());
|
||||
fprintf(fp, " %d | %s | ", i, type);
|
||||
|
||||
// マウント状態出力
|
||||
if (disk[i]->GetID() == MAKEID('S', 'C', 'B', 'R')) {
|
||||
fprintf(fp, "%s", "RaSCSI BRIDGE");
|
||||
} else {
|
||||
disk[i]->GetPath(filepath);
|
||||
fprintf(fp, "%s",
|
||||
(disk[i]->IsRemovable() && !disk[i]->IsReady()) ?
|
||||
"NO MEDIA" : filepath.GetPath());
|
||||
}
|
||||
|
||||
// ライトプロテクト状態出力
|
||||
if (disk[i]->IsRemovable() && disk[i]->IsReady() && disk[i]->IsWriteP()) {
|
||||
fprintf(fp, "(WRITEPROTECT)");
|
||||
}
|
||||
|
||||
// 次の行へ
|
||||
fprintf(fp, "\n");
|
||||
}
|
||||
|
||||
// コントローラが無い場合
|
||||
if (!find) {
|
||||
fprintf(fp, "No device is installed.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(fp, "---+------+---------------------------------------\n");
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// コマンド処理
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL ProcessCmd(FILE *fp, int id, int cmd, int type, char *file)
|
||||
{
|
||||
int len;
|
||||
char *ext;
|
||||
Filepath filepath;
|
||||
|
||||
// IDチェック
|
||||
if (id < 0 || id > 7) {
|
||||
fprintf(fp, "Error : Invalid ID\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// 接続コマンド
|
||||
if (cmd == 0) { // ATTACH
|
||||
// コントローラを解放
|
||||
if (ctrl[id]) {
|
||||
ctrl[id]->SetUnit(0, NULL);
|
||||
delete ctrl[id];
|
||||
ctrl[id] = NULL;
|
||||
}
|
||||
|
||||
// ディスクを解放
|
||||
if (disk[id]) {
|
||||
delete disk[id];
|
||||
disk[id] = NULL;
|
||||
}
|
||||
|
||||
// SASIとSCSIを見分ける
|
||||
if (type == 0) {
|
||||
// パスチェック
|
||||
if (!file) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// 最低5文字
|
||||
len = strlen(file);
|
||||
if (len < 5) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// 拡張子チェック
|
||||
if (file[len - 4] != '.') {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// 拡張子がSASIタイプで無ければSCSIに差し替え
|
||||
ext = &file[len - 3];
|
||||
if (xstrcasecmp(ext, "hdf") != 0) {
|
||||
type = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// タイプ別のインスタンスを生成
|
||||
switch (type) {
|
||||
case 0: // HDF
|
||||
disk[id] = new SASIHD();
|
||||
break;
|
||||
case 1: // HDS/HDN/HDI/NHD/HDA
|
||||
if (xstrcasecmp(ext, "hdn") == 0 ||
|
||||
xstrcasecmp(ext, "hdi") == 0 || xstrcasecmp(ext, "nhd") == 0) {
|
||||
disk[id] = new SCSIHD_NEC();
|
||||
} else if (xstrcasecmp(ext, "hda") == 0) {
|
||||
disk[id] = new SCSIHD_APPLE();
|
||||
} else {
|
||||
disk[id] = new SCSIHD();
|
||||
}
|
||||
break;
|
||||
case 2: // MO
|
||||
disk[id] = new SCSIMO();
|
||||
break;
|
||||
case 3: // CD
|
||||
disk[id] = new SCSICD();
|
||||
break;
|
||||
case 4: // BRIDGE
|
||||
disk[id] = new SCSIBR();
|
||||
break;
|
||||
default:
|
||||
fprintf(fp, "Error : Invalid device type\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// タイプに合わせてコントローラを作る
|
||||
if (type == 0) {
|
||||
ctrl[id] = new SASIDEV();
|
||||
} else {
|
||||
ctrl[id] = new SCSIDEV();
|
||||
}
|
||||
|
||||
// ドライブはファイルの確認を行う
|
||||
if (type <= 1 || (type <= 3 && xstrcasecmp(file, "-") != 0)) {
|
||||
// パスを設定
|
||||
filepath.SetPath(file);
|
||||
|
||||
// オープン
|
||||
if (!disk[id]->Open(filepath)) {
|
||||
fprintf(fp, "Error : File open error [%s]\n", file);
|
||||
delete disk[id];
|
||||
disk[id] = NULL;
|
||||
delete ctrl[id];
|
||||
ctrl[id] = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// ライトスルーに設定
|
||||
disk[id]->SetCacheWB(FALSE);
|
||||
|
||||
// 新たなディスクを接続
|
||||
ctrl[id]->Connect(id, &bus);
|
||||
ctrl[id]->SetUnit(0, disk[id]);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// 有効なコマンドか
|
||||
if (cmd > 4) {
|
||||
fprintf(fp, "Error : Invalid command\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// コントローラが存在するか
|
||||
if (ctrl[id] == NULL) {
|
||||
fprintf(fp, "Error : No such device\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// ディスクが存在するか
|
||||
if (disk[id] == NULL) {
|
||||
fprintf(fp, "Error : No such device\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// 切断コマンド
|
||||
if (cmd == 1) { // DETACH
|
||||
ctrl[id]->SetUnit(0, NULL);
|
||||
delete disk[id];
|
||||
disk[id] = NULL;
|
||||
delete ctrl[id];
|
||||
ctrl[id] = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// MOかCDの場合だけ有効
|
||||
if (disk[id]->GetID() != MAKEID('S', 'C', 'M', 'O') &&
|
||||
disk[id]->GetID() != MAKEID('S', 'C', 'C', 'D')) {
|
||||
fprintf(fp, "Error : Operation denied(Deveice isn't MO or CD)\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case 2: // INSERT
|
||||
// パスを設定
|
||||
filepath.SetPath(file);
|
||||
|
||||
// オープン
|
||||
if (!disk[id]->Open(filepath)) {
|
||||
fprintf(fp, "Error : File open error [%s]\n", file);
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case 3: // EJECT
|
||||
disk[id]->Eject(TRUE);
|
||||
break;
|
||||
|
||||
case 4: // PROTECT
|
||||
if (disk[id]->GetID() != MAKEID('S', 'C', 'M', 'O')) {
|
||||
fprintf(fp, "Error : Operation denied(Deveice isn't MO)\n");
|
||||
return FALSE;
|
||||
}
|
||||
disk[id]->WriteP(!disk[id]->IsWriteP());
|
||||
break;
|
||||
default:
|
||||
ASSERT(FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// 引数処理
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL ParseArgument(int argc, char* argv[])
|
||||
{
|
||||
int i;
|
||||
int id;
|
||||
int type;
|
||||
char *argID;
|
||||
char *argPath;
|
||||
int len;
|
||||
char *ext;
|
||||
|
||||
// IDとパス指定がなければ処理を中断
|
||||
if (argc < 3) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// 引数の解読開始
|
||||
i = 1;
|
||||
argc--;
|
||||
|
||||
// IDとパスを取得
|
||||
while (argc >= 2) {
|
||||
argc -= 2;
|
||||
argID = argv[i++];
|
||||
argPath = argv[i++];
|
||||
|
||||
// -ID or -idの形式をチェック
|
||||
if (strlen(argID) != 4 || xstrncasecmp(argID, "-id", 3) != 0) {
|
||||
fprintf(stderr,
|
||||
"Error : Invalid argument(-IDn) [%s]\n", argID);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// ID番号をチェック(0-7)
|
||||
if (argID[3] < '0' || argID[3] > '7') {
|
||||
fprintf(stderr,
|
||||
"Error : Invalid argument(-IDn n=0-7) [%c]\n", argID[3]);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// ID確定
|
||||
id = argID[3] - '0';
|
||||
|
||||
// すでにアクティブなデバイスがあるならスキップ
|
||||
if (disk[id]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// デバイスタイプを初期化
|
||||
type = -1;
|
||||
|
||||
// イーサネットとホストブリッジのチェック
|
||||
if (xstrcasecmp(argPath, "bridge") == 0) {
|
||||
type = 4;
|
||||
} else {
|
||||
// パスの長さをチェック
|
||||
len = strlen(argPath);
|
||||
if (len < 5) {
|
||||
fprintf(stderr,
|
||||
"Error : Invalid argument(File path is short) [%s]\n",
|
||||
argPath);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// 拡張子を持っているか?
|
||||
if (argPath[len - 4] != '.') {
|
||||
fprintf(stderr,
|
||||
"Error : Invalid argument(No extension) [%s]\n", argPath);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// タイプを決める
|
||||
ext = &argPath[len - 3];
|
||||
if (xstrcasecmp(ext, "hdf") == 0 ||
|
||||
xstrcasecmp(ext, "hds") == 0 ||
|
||||
xstrcasecmp(ext, "hdn") == 0 ||
|
||||
xstrcasecmp(ext, "hdi") == 0 || xstrcasecmp(ext, "nhd") == 0 ||
|
||||
xstrcasecmp(ext, "hda") == 0) {
|
||||
// HD(SASI/SCSI)
|
||||
type = 0;
|
||||
} else if (strcasecmp(ext, "mos") == 0) {
|
||||
// MO
|
||||
type = 2;
|
||||
} else if (strcasecmp(ext, "iso") == 0) {
|
||||
// CD
|
||||
type = 3;
|
||||
} else {
|
||||
// タイプが判別できない
|
||||
fprintf(stderr,
|
||||
"Error : Invalid argument(file type) [%s]\n", ext);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// コマンド実行
|
||||
if (!ProcessCmd(stderr, id, 0, type, argPath)) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// デバイスリスト表示
|
||||
ListDevice(stdout);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// モニタースレッド
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
static void *MonThread(void *param)
|
||||
{
|
||||
struct sockaddr_in client;
|
||||
socklen_t len;
|
||||
int fd;
|
||||
FILE *fp;
|
||||
BYTE buf[BUFSIZ];
|
||||
int id;
|
||||
int cmd;
|
||||
int type;
|
||||
char *file;
|
||||
BOOL list;
|
||||
|
||||
// 監視準備
|
||||
listen(monfd, 1);
|
||||
|
||||
while (1) {
|
||||
// 接続待ち
|
||||
memset(&client, 0, sizeof(client));
|
||||
len = sizeof(client);
|
||||
fd = accept(monfd, (struct sockaddr*)&client, &len);
|
||||
if (fd < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
// コマンド取得
|
||||
fp = fdopen(fd, "r+");
|
||||
fgets((char *)buf, BUFSIZ, fp);
|
||||
buf[strlen((const char*)buf) - 1] = 0;
|
||||
|
||||
// デバイスリスト表示なのか制御コマンドかを判断
|
||||
if (strncasecmp((char*)buf, "list", 4) == 0) {
|
||||
list = TRUE;
|
||||
} else {
|
||||
list = FALSE;
|
||||
id = (int)(buf[0] - '0');
|
||||
cmd = (int)(buf[2] - '0');
|
||||
type = (int)(buf[4] - '0');
|
||||
file = (char*)&buf[6];
|
||||
}
|
||||
|
||||
// バスフリーのタイミングまで待つ
|
||||
while (phase != BUS::busfree) {
|
||||
usleep(500 * 1000);
|
||||
}
|
||||
|
||||
if (list) {
|
||||
// リスト表示
|
||||
ListDevice(fp);
|
||||
} else {
|
||||
// コマンド実行
|
||||
ProcessCmd(fp, id, cmd, type, file);
|
||||
}
|
||||
|
||||
// 接続解放
|
||||
fclose(fp);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// 主処理
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int i;
|
||||
DWORD dwBusBak;
|
||||
DWORD dwBusIn;
|
||||
struct sched_param schparam;
|
||||
|
||||
// バナー出力
|
||||
if (!Banner(argc, argv)) {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// 初期化
|
||||
if (!Init()) {
|
||||
fprintf(stderr, "Error : Initializing\n");
|
||||
|
||||
// 恐らくrootでは無い?
|
||||
exit(EPERM);
|
||||
}
|
||||
|
||||
// 既に起動している?
|
||||
if (!bServer) {
|
||||
fprintf(stderr, "Error : Already running RaSCSI\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// 構築
|
||||
if (!ParseArgument(argc, argv)) {
|
||||
// クリーンアップ
|
||||
Cleanup();
|
||||
|
||||
// 引数エラーで終了
|
||||
exit(EINVAL);
|
||||
}
|
||||
|
||||
// モニタースレッド生成
|
||||
bRun = TRUE;
|
||||
pthread_create(&monthread, NULL, MonThread, NULL);
|
||||
|
||||
// リセット
|
||||
Reset();
|
||||
|
||||
// メインループ準備
|
||||
phase = BUS::busfree;
|
||||
dwBusBak = bus.Aquire();
|
||||
|
||||
// メインループ
|
||||
while(bRun) {
|
||||
// バスの入力信号変化検出
|
||||
dwBusIn = bus.Aquire();
|
||||
|
||||
// 入力信号変化検出
|
||||
if ((dwBusIn & GPIO_INEDGE) == (dwBusBak & GPIO_INEDGE)) {
|
||||
usleep(0);
|
||||
continue;
|
||||
}
|
||||
|
||||
// バスの入力信号を保存
|
||||
dwBusBak = dwBusIn;
|
||||
|
||||
// そもそもセレクション信号が無ければ無視
|
||||
if (!bus.GetSEL() || bus.GetBSY()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 全コントローラに通知
|
||||
for (i = 0; i < CtrlMax; i++) {
|
||||
if (!ctrl[i]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// セレクションフェーズに移行したターゲットを探す
|
||||
if (ctrl[i]->Process() == BUS::selection) {
|
||||
// ターゲットのIDを取得
|
||||
actid = i;
|
||||
|
||||
// セレクションフェーズ
|
||||
phase = BUS::selection;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// セレクションフェーズが開始されていなければバスの監視へ戻る
|
||||
if (phase != BUS::selection) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// ターゲット走行開始
|
||||
|
||||
// スケジューリングポリシー設定(最優先)
|
||||
schparam.sched_priority = sched_get_priority_max(SCHED_FIFO);
|
||||
sched_setscheduler(0, SCHED_FIFO, &schparam);
|
||||
|
||||
// バスフリーになるまでループ
|
||||
while (bRun) {
|
||||
// ターゲット駆動
|
||||
phase = ctrl[actid]->Process();
|
||||
|
||||
// バスフリーになったら終了
|
||||
if (phase == BUS::busfree) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// バスフリーでセッション終了
|
||||
actid = -1;
|
||||
phase = BUS::busfree;
|
||||
bus.Reset();
|
||||
dwBusBak = bus.Aquire();
|
||||
|
||||
// スケジューリングポリシー設定(ノーマル)
|
||||
schparam.sched_priority = 0;
|
||||
sched_setscheduler(0, SCHED_OTHER, &schparam);
|
||||
}
|
||||
|
||||
// クリーンアップ
|
||||
Cleanup();
|
||||
|
||||
// 終了
|
||||
exit(0);
|
||||
}
|
247
src/raspberrypi/rasctl.cpp
Normal file
247
src/raspberrypi/rasctl.cpp
Normal file
@ -0,0 +1,247 @@
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI Target Emulator RaSCSI (*^..^*)
|
||||
// for Raspberry Pi
|
||||
//
|
||||
// Powered by XM6 TypeG Technology.
|
||||
// Copyright (C) 2016-2018 GIMONS
|
||||
// [ 制御コマンド送信 ]
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "os.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// コマンド送信
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL SendCommand(char *buf)
|
||||
{
|
||||
int fd;
|
||||
struct sockaddr_in server;
|
||||
FILE *fp;
|
||||
|
||||
// コマンド用ソケット生成
|
||||
fd = socket(PF_INET, SOCK_STREAM, 0);
|
||||
memset(&server, 0, sizeof(server));
|
||||
server.sin_family = PF_INET;
|
||||
server.sin_port = htons(6868);
|
||||
server.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
|
||||
// 接続
|
||||
if (connect(fd, (struct sockaddr *)&server,
|
||||
sizeof(struct sockaddr_in)) < 0) {
|
||||
fprintf(stderr, "Error : Can't connect to rascsi process\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// 送信
|
||||
fp = fdopen(fd, "r+");
|
||||
setvbuf(fp, NULL, _IONBF, 0);
|
||||
fprintf(fp, buf);
|
||||
|
||||
// メッセージ受信
|
||||
while (1) {
|
||||
if (fgets((char *)buf, BUFSIZ, fp) == NULL) {
|
||||
break;
|
||||
}
|
||||
printf("%s", buf);
|
||||
}
|
||||
|
||||
// ソケットを閉じる
|
||||
fclose(fp);
|
||||
close(fd);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// 主処理
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int opt;
|
||||
int id;
|
||||
int cmd;
|
||||
int type;
|
||||
char *file;
|
||||
BOOL list;
|
||||
int len;
|
||||
char *ext;
|
||||
char buf[BUFSIZ];
|
||||
|
||||
id = -1;
|
||||
cmd = -1;
|
||||
type = -1;
|
||||
file = NULL;
|
||||
list = FALSE;
|
||||
|
||||
// ヘルプの表示
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "SCSI Target Emulator RaSCSI Controller\n");
|
||||
fprintf(stderr,
|
||||
"Usage: %s -i ID [-c CMD] [-t TYPE] [-f FILE]\n",
|
||||
argv[0]);
|
||||
fprintf(stderr, " where ID := {0|1|2|3|4|5|6|7}\n");
|
||||
fprintf(stderr, " CMD := {attach|detatch|insert|eject|protect}\n");
|
||||
fprintf(stderr, " TYPE := {hd|mo|cd|bridge}\n");
|
||||
fprintf(stderr, " FILE := image file path\n");
|
||||
fprintf(stderr, " CMD is 'attach' or 'insert' and FILE parameter is required.\n");
|
||||
fprintf(stderr, "Usage: %s -l\n", argv[0]);
|
||||
fprintf(stderr, " Print device list.\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// 引数解析
|
||||
opterr = 0;
|
||||
while ((opt = getopt(argc, argv, "i:c:t:f:l")) != -1) {
|
||||
switch (opt) {
|
||||
case 'i':
|
||||
id = optarg[0] - '0';
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
switch (optarg[0]) {
|
||||
case 'a': // ATTACH
|
||||
case 'A':
|
||||
cmd = 0;
|
||||
break;
|
||||
case 'd': // DETACH
|
||||
case 'D':
|
||||
cmd = 1;
|
||||
break;
|
||||
case 'i': // INSERT
|
||||
case 'I':
|
||||
cmd = 2;
|
||||
break;
|
||||
case 'e': // EJECT
|
||||
case 'E':
|
||||
cmd = 3;
|
||||
break;
|
||||
case 'p': // PROTECT
|
||||
case 'P':
|
||||
cmd = 4;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 't':
|
||||
switch (optarg[0]) {
|
||||
case 's': // HD(SASI)
|
||||
case 'S':
|
||||
case 'h': // HD(SCSI)
|
||||
case 'H':
|
||||
type = 0;
|
||||
break;
|
||||
case 'm': // MO
|
||||
case 'M':
|
||||
type = 2;
|
||||
break;
|
||||
case 'c': // CD
|
||||
case 'C':
|
||||
type = 3;
|
||||
break;
|
||||
case 'b': // BRIDGE
|
||||
case 'B':
|
||||
type = 4;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
file = optarg;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
list = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// リスト表示のみ
|
||||
if (id < 0 && cmd < 0 && type < 0 && file == NULL && list) {
|
||||
sprintf(buf, "list\n");
|
||||
SendCommand(buf);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// IDチェック
|
||||
if (id < 0 || id > 7) {
|
||||
fprintf(stderr, "Error : Invalid ID\n");
|
||||
exit(EINVAL);
|
||||
}
|
||||
|
||||
// コマンドチェック
|
||||
if (cmd < 0) {
|
||||
cmd = 0; // デフォルトはATTATCHとする
|
||||
}
|
||||
|
||||
// タイプチェック
|
||||
if (cmd == 0 && type < 0) {
|
||||
|
||||
// 拡張子からタイプ判別を試みる
|
||||
len = file ? strlen(file) : 0;
|
||||
if (len > 4 && file[len - 4] == '.') {
|
||||
ext = &file[len - 3];
|
||||
if (xstrcasecmp(ext, "hdf") == 0 ||
|
||||
xstrcasecmp(ext, "hds") == 0 ||
|
||||
xstrcasecmp(ext, "hdn") == 0 ||
|
||||
xstrcasecmp(ext, "hdi") == 0 ||
|
||||
xstrcasecmp(ext, "nhd") == 0 ||
|
||||
xstrcasecmp(ext, "hda") == 0) {
|
||||
// HD(SASI/SCSI)
|
||||
type = 0;
|
||||
} else if (xstrcasecmp(ext, "mos") == 0) {
|
||||
// MO
|
||||
type = 2;
|
||||
} else if (xstrcasecmp(ext, "iso") == 0) {
|
||||
// CD
|
||||
type = 3;
|
||||
}
|
||||
}
|
||||
|
||||
if (type < 0) {
|
||||
fprintf(stderr, "Error : Invalid type\n");
|
||||
exit(EINVAL);
|
||||
}
|
||||
}
|
||||
|
||||
// ファイルチェック(コマンドはATTACHでタイプはHD)
|
||||
if (cmd == 0 && type >= 0 && type <= 1) {
|
||||
if (!file) {
|
||||
fprintf(stderr, "Error : Invalid file path\n");
|
||||
exit(EINVAL);
|
||||
}
|
||||
}
|
||||
|
||||
// ファイルチェック(コマンドはINSERT)
|
||||
if (cmd == 2) {
|
||||
if (!file) {
|
||||
fprintf(stderr, "Error : Invalid file path\n");
|
||||
exit(EINVAL);
|
||||
}
|
||||
}
|
||||
|
||||
// 必要でないtypeは0としておく
|
||||
if (type < 0) {
|
||||
type = 0;
|
||||
}
|
||||
|
||||
// 送信コマンド生成
|
||||
sprintf(buf, "%d %d %d %s\n", id, cmd, type, file ? file : "-");
|
||||
if (!SendCommand(buf)) {
|
||||
exit(ENOTCONN);
|
||||
}
|
||||
|
||||
// リスト表示
|
||||
if (list) {
|
||||
sprintf(buf, "list\n");
|
||||
SendCommand(buf);
|
||||
}
|
||||
|
||||
// 終了
|
||||
exit(0);
|
||||
}
|
1006
src/raspberrypi/rasdump.cpp
Normal file
1006
src/raspberrypi/rasdump.cpp
Normal file
File diff suppressed because it is too large
Load Diff
58
src/raspberrypi/scsi.cpp
Normal file
58
src/raspberrypi/scsi.cpp
Normal file
@ -0,0 +1,58 @@
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// X68000 EMULATOR "XM6"
|
||||
//
|
||||
// Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp)
|
||||
// Copyright (C) 2014-2018 GIMONS
|
||||
//
|
||||
// [ SCSI共通 ]
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "os.h"
|
||||
#include "xm6.h"
|
||||
#include "scsi.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// フェーズ取得
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
BUS::phase_t FASTCALL BUS::GetPhase()
|
||||
{
|
||||
DWORD mci;
|
||||
|
||||
ASSERT(this);
|
||||
|
||||
// セレクションフェーズ
|
||||
if (GetSEL()) {
|
||||
return selection;
|
||||
}
|
||||
|
||||
// バスフリーフェーズ
|
||||
if (!GetBSY()) {
|
||||
return busfree;
|
||||
}
|
||||
|
||||
// バスの信号線からターゲットのフェーズを取得
|
||||
mci = GetMSG() ? 0x04 : 0x00;
|
||||
mci |= GetCD() ? 0x02 : 0x00;
|
||||
mci |= GetIO() ? 0x01 : 0x00;
|
||||
return GetPhase(mci);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// フェーズテーブル
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
const BUS::phase_t BUS::phase_table[8] = {
|
||||
dataout,
|
||||
datain,
|
||||
command,
|
||||
status,
|
||||
reserved,
|
||||
reserved,
|
||||
msgout,
|
||||
msgin
|
||||
};
|
128
src/raspberrypi/scsi.h
Normal file
128
src/raspberrypi/scsi.h
Normal file
@ -0,0 +1,128 @@
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// X68000 EMULATOR "XM6"
|
||||
//
|
||||
// Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp)
|
||||
// Copyright (C) 2014-2018 GIMONS
|
||||
//
|
||||
// [ SCSI共通 ]
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#if !defined(scsi_h)
|
||||
#define scsi_h
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// SASI/SCSI バス
|
||||
//
|
||||
//===========================================================================
|
||||
class BUS
|
||||
{
|
||||
public:
|
||||
// 動作モード定義
|
||||
enum mode_e {
|
||||
TARGET = 0,
|
||||
INITIATOR = 1,
|
||||
MONITOR = 2,
|
||||
};
|
||||
|
||||
// フェーズ定義
|
||||
enum phase_t {
|
||||
busfree, // バスフリーフェーズ
|
||||
arbitration, // アービトレーションフェーズ
|
||||
selection, // セレクションフェーズ
|
||||
reselection, // リセレクションフェーズ
|
||||
command, // コマンドフェーズ
|
||||
execute, // 実行フェーズ
|
||||
datain, // データイン
|
||||
dataout, // データアウト
|
||||
status, // ステータスフェーズ
|
||||
msgin, // メッセージフェーズ
|
||||
msgout, // メッセージアウトフェーズ
|
||||
reserved // 未使用/リザーブ
|
||||
};
|
||||
|
||||
// 基本ファンクション
|
||||
virtual BOOL FASTCALL Init(mode_e mode) = 0;
|
||||
// 初期化
|
||||
virtual void FASTCALL Reset() = 0;
|
||||
// リセット
|
||||
virtual void FASTCALL Cleanup() = 0;
|
||||
// クリーンアップ
|
||||
phase_t FASTCALL GetPhase();
|
||||
// フェーズ取得
|
||||
|
||||
static phase_t FASTCALL GetPhase(DWORD mci)
|
||||
{
|
||||
return phase_table[mci];
|
||||
}
|
||||
// フェーズ取得
|
||||
|
||||
virtual DWORD FASTCALL Aquire() = 0;
|
||||
// 信号取り込み
|
||||
|
||||
virtual BOOL FASTCALL GetBSY() = 0;
|
||||
// BSYシグナル取得
|
||||
virtual void FASTCALL SetBSY(BOOL ast) = 0;
|
||||
// BSYシグナル設定
|
||||
|
||||
virtual BOOL FASTCALL GetSEL() = 0;
|
||||
// SELシグナル取得
|
||||
virtual void FASTCALL SetSEL(BOOL ast) = 0;
|
||||
// SELシグナル設定
|
||||
|
||||
virtual BOOL FASTCALL GetATN() = 0;
|
||||
// ATNシグナル取得
|
||||
virtual void FASTCALL SetATN(BOOL ast) = 0;
|
||||
// ATNシグナル設定
|
||||
|
||||
virtual BOOL FASTCALL GetACK() = 0;
|
||||
// ACKシグナル取得
|
||||
virtual void FASTCALL SetACK(BOOL ast) = 0;
|
||||
// ACKシグナル設定
|
||||
|
||||
virtual BOOL FASTCALL GetRST() = 0;
|
||||
// RSTシグナル取得
|
||||
virtual void FASTCALL SetRST(BOOL ast) = 0;
|
||||
// RSTシグナル設定
|
||||
|
||||
virtual BOOL FASTCALL GetMSG() = 0;
|
||||
// MSGシグナル取得
|
||||
virtual void FASTCALL SetMSG(BOOL ast) = 0;
|
||||
// MSGシグナル設定
|
||||
|
||||
virtual BOOL FASTCALL GetCD() = 0;
|
||||
// CDシグナル取得
|
||||
virtual void FASTCALL SetCD(BOOL ast) = 0;
|
||||
// CDシグナル設定
|
||||
|
||||
virtual BOOL FASTCALL GetIO() = 0;
|
||||
// IOシグナル取得
|
||||
virtual void FASTCALL SetIO(BOOL ast) = 0;
|
||||
// IOシグナル設定
|
||||
|
||||
virtual BOOL FASTCALL GetREQ() = 0;
|
||||
// REQシグナル取得
|
||||
virtual void FASTCALL SetREQ(BOOL ast) = 0;
|
||||
// REQシグナル設定
|
||||
|
||||
virtual BYTE FASTCALL GetDAT() = 0;
|
||||
// データシグナル取得
|
||||
virtual void FASTCALL SetDAT(BYTE dat) = 0;
|
||||
// データシグナル設定
|
||||
|
||||
virtual int FASTCALL ReceiveHandShake(BYTE *buf, int count) = 0;
|
||||
// データ受信ハンドシェイク
|
||||
virtual int FASTCALL SendHandShake(BYTE *buf, int count) = 0;
|
||||
// データ送信ハンドシェイク
|
||||
|
||||
virtual void FASTCALL SleepNsec(DWORD nsec) = 0;
|
||||
// ナノ秒単位のスリープ
|
||||
|
||||
private:
|
||||
static const phase_t phase_table[8];
|
||||
// フェーズテーブル
|
||||
};
|
||||
|
||||
#endif // scsi_h
|
49
src/raspberrypi/xm6.h
Normal file
49
src/raspberrypi/xm6.h
Normal file
@ -0,0 +1,49 @@
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI Target Emulator RaSCSI (*^..^*)
|
||||
// for Raspberry Pi
|
||||
//
|
||||
// Powered by XM6 TypeG Technology.
|
||||
// Copyright (C) 2016-2018 GIMONS
|
||||
//
|
||||
// [ 共通定義 ]
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#if !defined(xm6_h)
|
||||
#define xm6_h
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// VERSION
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
#define VERSION 0x0134
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// RaSCSI
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
#define RASCSI VERSION
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// IDマクロ
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
#define MAKEID(a, b, c, d) ((DWORD)((a<<24) | (b<<16) | (c<<8) | d))
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// クラス宣言
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
class Fileio;
|
||||
// ファイル入出力
|
||||
class Disk;
|
||||
// SASI/SCSIディスク
|
||||
class Filepath;
|
||||
// ファイルパス
|
||||
|
||||
#endif // xm6_h
|
2414
src/x68k/RASDRV/BRIDGE.C
Normal file
2414
src/x68k/RASDRV/BRIDGE.C
Normal file
File diff suppressed because it is too large
Load Diff
256
src/x68k/RASDRV/BRIDGE.H
Normal file
256
src/x68k/RASDRV/BRIDGE.H
Normal file
@ -0,0 +1,256 @@
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI Target Emulator RaSCSI (*^..^*)
|
||||
// for Raspberry Pi
|
||||
//
|
||||
// Powered by XM6 TypeG Technorogy.
|
||||
// Copyright (C) 2016-2017 GIMONS
|
||||
// [ ホストファイルシステム ブリッジドライバ ]
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef bridge_h
|
||||
#define bridge_h
|
||||
|
||||
typedef unsigned char BYTE;
|
||||
typedef unsigned short WORD;
|
||||
typedef unsigned long DWORD;
|
||||
typedef int BOOL;
|
||||
|
||||
#if !defined(FALSE)
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#if !defined(TRUE)
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#define FASTCALL
|
||||
#define ASSERT(x)
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// 定数定義
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
#define FILEPATH_MAX _MAX_PATH
|
||||
#define WINDRV_CLIPSIZE_MAX 0xC00000
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// ステータスコード定義
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
#define FS_INVALIDFUNC 0xFFFFFFFF // 無効なファンクションコードを実行した
|
||||
#define FS_FILENOTFND 0xFFFFFFFE // 指定したファイルが見つからない
|
||||
#define FS_DIRNOTFND 0xFFFFFFFD // 指定したディレクトリが見つからない
|
||||
#define FS_OVEROPENED 0xFFFFFFFC // オープンしているファイルが多すぎる
|
||||
#define FS_CANTACCESS 0xFFFFFFFB // ディレクトリやボリュームラベルはアクセス不可
|
||||
#define FS_NOTOPENED 0xFFFFFFFA // 指定したハンドルはオープンされていない
|
||||
#define FS_INVALIDMEM 0xFFFFFFF9 // メモリ管理領域が破壊された
|
||||
#define FS_OUTOFMEM 0xFFFFFFF8 // 実行に必要なメモリがない
|
||||
#define FS_INVALIDPTR 0xFFFFFFF7 // 無効なメモリ管理ポインタを指定した
|
||||
#define FS_INVALIDENV 0xFFFFFFF6 // 不正な環境を指定した
|
||||
#define FS_ILLEGALFMT 0xFFFFFFF5 // 実行ファイルのフォーマットが異常
|
||||
#define FS_ILLEGALMOD 0xFFFFFFF4 // オープンのアクセスモードが異常
|
||||
#define FS_INVALIDPATH 0xFFFFFFF3 // ファイル名の指定に誤りがある
|
||||
#define FS_INVALIDPRM 0xFFFFFFF2 // 無効なパラメータでコールした
|
||||
#define FS_INVALIDDRV 0xFFFFFFF1 // ドライブ指定に誤りがある
|
||||
#define FS_DELCURDIR 0xFFFFFFF0 // カレントディレクトリは削除できない
|
||||
#define FS_NOTIOCTRL 0xFFFFFFEF // IOCTRLできないデバイス
|
||||
#define FS_LASTFILE 0xFFFFFFEE // これ以上ファイルが見つからない
|
||||
#define FS_CANTWRITE 0xFFFFFFED // 指定のファイルは書き込みできない
|
||||
#define FS_DIRALREADY 0xFFFFFFEC // 指定のディレクトリは既に登録されている
|
||||
#define FS_CANTDELETE 0xFFFFFFEB // ファイルがあるので削除できない
|
||||
#define FS_CANTRENAME 0xFFFFFFEA // ファイルがあるのでリネームできない
|
||||
#define FS_DISKFULL 0xFFFFFFE9 // ディスクが一杯でファイルが作れない
|
||||
#define FS_DIRFULL 0xFFFFFFE8 // ディレクトリが一杯でファイルが作れない
|
||||
#define FS_CANTSEEK 0xFFFFFFE7 // 指定の位置にはシークできない
|
||||
#define FS_SUPERVISOR 0xFFFFFFE6 // スーパーバイザ状態でスーパバイザ指定した
|
||||
#define FS_THREADNAME 0xFFFFFFE5 // 同じスレッド名が存在する
|
||||
#define FS_BUFWRITE 0xFFFFFFE4 // プロセス間通信のバッファが書込み禁止
|
||||
#define FS_BACKGROUND 0xFFFFFFE3 // バックグラウンドプロセスを起動できない
|
||||
#define FS_OUTOFLOCK 0xFFFFFFE0 // ロック領域が足りない
|
||||
#define FS_LOCKED 0xFFFFFFDF // ロックされていてアクセスできない
|
||||
#define FS_DRIVEOPENED 0xFFFFFFDE // 指定のドライブはハンドラがオープンされている
|
||||
#define FS_LINKOVER 0xFFFFFFDD // シンボリックリンクネストが16回を超えた
|
||||
#define FS_FILEEXIST 0xFFFFFFB0 // ファイルが存在する
|
||||
|
||||
#define FS_FATAL_MEDIAOFFLINE 0xFFFFFFA3 // メディアが入っていない
|
||||
#define FS_FATAL_WRITEPROTECT 0xFFFFFFA2 // 書き込み禁止違反
|
||||
#define FS_FATAL_INVALIDCOMMAND 0xFFFFFFA1 // 不正なコマンド番号
|
||||
#define FS_FATAL_INVALIDUNIT 0xFFFFFFA0 // 不正なユニット番号
|
||||
|
||||
#define HUMAN68K_PATH_MAX 96 // Human68kのパス最大長
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
/// Human68k 名前空間
|
||||
//
|
||||
//===========================================================================
|
||||
/// ファイル属性ビット
|
||||
enum attribute_t {
|
||||
AT_READONLY = 0x01, // 読み込み専用属性
|
||||
AT_HIDDEN = 0x02, // 隠し属性
|
||||
AT_SYSTEM = 0x04, // システム属性
|
||||
AT_VOLUME = 0x08, // ボリュームラベル属性
|
||||
AT_DIRECTORY= 0x10, // ディレクトリ属性
|
||||
AT_ARCHIVE = 0x20, // アーカイブ属性
|
||||
AT_ALL = 0xFF, // 全ての属性ビットが1
|
||||
};
|
||||
|
||||
/// ファイルオープンモード
|
||||
enum open_t {
|
||||
OP_READ = 0, // 読み込み
|
||||
OP_WRITE = 1, // 書き込み
|
||||
OP_FULL = 2, // 読み書き
|
||||
OP_MASK = 0x0F, // 判定用マスク
|
||||
OP_SHARE_NONE = 0x10, // 共有禁止
|
||||
OP_SHARE_READ = 0x20, // 読み込み共有
|
||||
OP_SHARE_WRITE = 0x30, // 書き込み共有
|
||||
OP_SHARE_FULL = 0x40, // 読み書き共有
|
||||
OP_SHARE_MASK = 0x70, // 共有判定用マスク
|
||||
OP_SPECIAL = 0x100,// 辞書アクセス
|
||||
};
|
||||
|
||||
/// シーク種類
|
||||
enum seek_t {
|
||||
SK_BEGIN = 0, // ファイル先頭から
|
||||
SK_CURRENT = 1, // 現在位置から
|
||||
SK_END = 2, // ファイル末尾から
|
||||
};
|
||||
|
||||
/// メディアバイト
|
||||
enum media_t {
|
||||
MEDIA_2DD_10 = 0xE0, // 2DD/10セクタ
|
||||
MEDIA_1D_9 = 0xE5, // 1D/9セクタ
|
||||
MEDIA_2D_9 = 0xE6, // 2D/9セクタ
|
||||
MEDIA_1D_8 = 0xE7, // 1D/8セクタ
|
||||
MEDIA_2D_8 = 0xE8, // 2D/8セクタ
|
||||
MEDIA_2HT = 0xEA, // 2HT
|
||||
MEDIA_2HS = 0xEB, // 2HS
|
||||
MEDIA_2HDE = 0xEC, // 2DDE
|
||||
MEDIA_1DD_9 = 0xEE, // 1DD/9セクタ
|
||||
MEDIA_1DD_8 = 0xEF, // 1DD/8セクタ
|
||||
MEDIA_MANUAL = 0xF1, // リモートドライブ (手動イジェクト)
|
||||
MEDIA_REMOVABLE = 0xF2, // リモートドライブ (リムーバブル)
|
||||
MEDIA_REMOTE = 0xF3, // リモートドライブ
|
||||
MEDIA_DAT = 0xF4, // SCSI-DAT
|
||||
MEDIA_CDROM = 0xF5, // SCSI-CDROM
|
||||
MEDIA_MO = 0xF6, // SCSI-MO
|
||||
MEDIA_SCSI_HD = 0xF7, // SCSI-HD
|
||||
MEDIA_SASI_HD = 0xF8, // SASI-HD
|
||||
MEDIA_RAMDISK = 0xF9, // RAMディスク
|
||||
MEDIA_2HQ = 0xFA, // 2HQ
|
||||
MEDIA_2DD_8 = 0xFB, // 2DD/8セクタ
|
||||
MEDIA_2DD_9 = 0xFC, // 2DD/9セクタ
|
||||
MEDIA_2HC = 0xFD, // 2HC
|
||||
MEDIA_2HD = 0xFE, // 2HD
|
||||
};
|
||||
|
||||
/// namests構造体
|
||||
typedef struct {
|
||||
BYTE wildcard; // ワイルドカード文字数
|
||||
BYTE drive; // ドライブ番号
|
||||
BYTE path[65]; // パス(サブディレクトリ+/)
|
||||
BYTE name[8]; // ファイル名 (PADDING 0x20)
|
||||
BYTE ext[3]; // 拡張子 (PADDING 0x20)
|
||||
BYTE add[10]; // ファイル名追加 (PADDING 0x00)
|
||||
} namests_t;
|
||||
|
||||
/// files構造体
|
||||
typedef struct {
|
||||
BYTE fatr; // + 0 検索する属性 読込専用
|
||||
BYTE pad1[3]; // padding
|
||||
// BYTE drive; // + 1 ドライブ番号 読込専用
|
||||
DWORD sector; // + 2 ディレクトリのセクタ DOS _FILES先頭アドレスで代用
|
||||
// WORD cluster; // + 6 ディレクトリのクラスタ 詳細不明 (未使用)
|
||||
WORD offset; // + 8 ディレクトリエントリ 書込専用
|
||||
// BYTE name[8]; // +10 作業用ファイル名 読込専用 (未使用)
|
||||
// BYTE ext[3]; // +18 作業用拡張子 読込専用 (未使用)
|
||||
BYTE attr; // +21 ファイル属性 書込専用
|
||||
BYTE pad2; // padding
|
||||
WORD time; // +22 最終変更時刻 書込専用
|
||||
WORD date; // +24 最終変更月日 書込専用
|
||||
DWORD size; // +26 ファイルサイズ 書込専用
|
||||
BYTE full[23]; // +30 フルファイル名 書込専用
|
||||
BYTE pad3; // padding
|
||||
} files_t;
|
||||
|
||||
/// FCB構造体
|
||||
typedef struct {
|
||||
// BYTE pad00[6]; // + 0~+ 5 (未使用)
|
||||
DWORD fileptr; // + 6~+ 9 ファイルポインタ
|
||||
// BYTE pad01[4]; // +10~+13 (未使用)
|
||||
WORD mode; // +14~+15 オープンモード
|
||||
// BYTE pad02[16]; // +16~+31 (未使用)
|
||||
// DWORD zero; // +32~+35 オープンのとき0が書き込まれている (未使用)
|
||||
// BYTE name[8]; // +36~+43 ファイル名 (PADDING 0x20) (未使用)
|
||||
// BYTE ext[3]; // +44~+46 拡張子 (PADDING 0x20) (未使用)
|
||||
BYTE attr; // +47 ファイル属性
|
||||
BYTE pad; // padding
|
||||
// BYTE add[10]; // +48~+57 ファイル名追加 (PADDING 0x00) (未使用)
|
||||
WORD time; // +58~+59 最終変更時刻
|
||||
WORD date; // +60~+61 最終変更月日
|
||||
// WORD cluster; // +62~+63 クラスタ番号 (未使用)
|
||||
DWORD size; // +64~+67 ファイルサイズ
|
||||
// BYTE pad03[28]; // +68~+95 FATキャッシュ (未使用)
|
||||
} fcb_t;
|
||||
|
||||
/// capacity構造体
|
||||
typedef struct {
|
||||
WORD freearea; // + 0 使用可能なクラスタ数
|
||||
WORD clusters; // + 2 総クラスタ数
|
||||
WORD sectors; // + 4 クラスタあたりのセクタ数
|
||||
WORD bytes; // + 6 セクタ当たりのバイト数
|
||||
} capacity_t;
|
||||
|
||||
/// ctrldrive構造体
|
||||
typedef struct {
|
||||
BYTE status; // +13 状態
|
||||
BYTE pad[3]; // padding
|
||||
} ctrldrive_t;
|
||||
|
||||
/// DPB構造体
|
||||
typedef struct {
|
||||
WORD sector_size; // + 0 1セクタ当りのバイト数
|
||||
BYTE cluster_size; // + 2 1クラスタ当りのセクタ数-1
|
||||
BYTE shift; // + 3 クラスタ→セクタのシフト数
|
||||
WORD fat_sector; // + 4 FATの先頭セクタ番号
|
||||
BYTE fat_max; // + 6 FAT領域の個数
|
||||
BYTE fat_size; // + 7 FATの占めるセクタ数(複写分を除く)
|
||||
WORD file_max; // + 8 ルートディレクトリに入るファイルの個数
|
||||
WORD data_sector; // +10 データ領域の先頭セクタ番号
|
||||
WORD cluster_max; // +12 総クラスタ数+1
|
||||
WORD root_sector; // +14 ルートディレクトリの先頭セクタ番号
|
||||
// DWORD driverentry; // +16 デバイスドライバへのポインタ (未使用)
|
||||
BYTE media; // +20 メディア識別子
|
||||
// BYTE flag; // +21 DPB使用フラグ (未使用)
|
||||
BYTE pad; // padding
|
||||
} dpb_t;
|
||||
|
||||
/// ディレクトリエントリ構造体
|
||||
typedef struct {
|
||||
BYTE name[8]; // + 0 ファイル名 (PADDING 0x20)
|
||||
BYTE ext[3]; // + 8 拡張子 (PADDING 0x20)
|
||||
BYTE attr; // +11 ファイル属性
|
||||
BYTE add[10]; // +12 ファイル名追加 (PADDING 0x00)
|
||||
WORD time; // +22 最終変更時刻
|
||||
WORD date; // +24 最終変更月日
|
||||
WORD cluster; // +26 クラスタ番号
|
||||
DWORD size; // +28 ファイルサイズ
|
||||
} dirent_t;
|
||||
|
||||
/// IOCTRLパラメータ共用体
|
||||
typedef union {
|
||||
BYTE buffer[8]; // バイト単位でのアクセス
|
||||
DWORD param; // パラメータ(先頭4バイト)
|
||||
WORD media; // メディアバイト(先頭2バイト)
|
||||
} ioctrl_t;
|
||||
|
||||
/// コマンドライン引数構造体
|
||||
typedef struct {
|
||||
BYTE buf[256]; // コマンドライン引数
|
||||
} argument_t;
|
||||
|
||||
#endif // bridge_h
|
17
src/x68k/RASDRV/Makefile
Normal file
17
src/x68k/RASDRV/Makefile
Normal file
@ -0,0 +1,17 @@
|
||||
#
|
||||
# Makefile for RASDRV.SYS
|
||||
#
|
||||
|
||||
CC = gcc -O2 -Wall -fomit-frame-pointer
|
||||
AS = has
|
||||
LK = hlk -l -x
|
||||
|
||||
RASDRV.SYS : RASDRV.o BRIDGE.o
|
||||
$(LK) -o $@ $^ libc.a libiocs.a libscsi.a
|
||||
|
||||
RASDRV.o : RASDRV.S
|
||||
$(AS) $^
|
||||
|
||||
BRIDGE.o : BRIDGE.C
|
||||
$(CC) -c -o $@ $^
|
||||
|
193
src/x68k/RASDRV/RASDRV.S
Normal file
193
src/x68k/RASDRV/RASDRV.S
Normal file
@ -0,0 +1,193 @@
|
||||
*---------------------------------------------------------------------------
|
||||
*
|
||||
* SCSI Target Emulator RaSCSI (*^..^*)
|
||||
* for Raspberry Pi
|
||||
*
|
||||
* Powered by XM6 TypeG Technorogy.
|
||||
* Copyright (C) 2016-2017 GIMONS
|
||||
* [ ホストファイルシステム ブリッジドライバ ]
|
||||
*
|
||||
* Based on
|
||||
* X68k Emulator Host Filesystem Driver version 0.27
|
||||
* Programmed By co
|
||||
*
|
||||
*---------------------------------------------------------------------------
|
||||
|
||||
CPU 68010
|
||||
|
||||
INCLUDE DOSCALL.MAC
|
||||
INCLUDE IOCSCALL.MAC
|
||||
|
||||
.XREF _Init, _Process ;bridge.c
|
||||
|
||||
COMMAND EQU 2 コマンド番号
|
||||
ERRLOW EQU 3 エラーコード下位8ビット
|
||||
ERRHIGH EQU 4 エラーコード上位8ビット
|
||||
MXUNIT EQU 13 ユニット数
|
||||
DEVEND EQU 14 ドライバ終了アドレス
|
||||
BDEVNO EQU 22 ベースドライブ番号
|
||||
|
||||
DDHEADER:
|
||||
DC.L -1 +$00 リンクポインタ
|
||||
DC.W $2040 +$04 デバイス属性
|
||||
DC.L DDSTRATEGY +$06
|
||||
DC.L DDENTRY_FIRST +$0A
|
||||
DC.B '*EMUHOST' +$0E デバイス名
|
||||
|
||||
DDREQUEST:
|
||||
DC.L 0
|
||||
|
||||
DDSTRATEGY:
|
||||
MOVE.L A5,DDREQUEST
|
||||
RTS
|
||||
|
||||
*デバイスドライバエントリ
|
||||
DDENTRY:
|
||||
MOVE.L SP,(STACK_BUFF)
|
||||
LEA (DEF_STACK),SP
|
||||
MOVEM.L D1-D3/A0-A2,-(SP)
|
||||
MOVEM.L DDREQUEST(PC),D0 D0.L: リクエストヘッダアドレス
|
||||
MOVE.L D0,-(SP)
|
||||
BSR _Process
|
||||
ADDQ.L #4,SP
|
||||
MOVEM.L (SP)+,D1-D3/A0-A2
|
||||
MOVEA.L (STACK_BUFF),SP
|
||||
RTS
|
||||
|
||||
KEEP_HERE:
|
||||
|
||||
*初回のみのデバイスドライバエントリ
|
||||
DDENTRY_FIRST:
|
||||
MOVEM.L D1-D3/A0-A2/A5,-(SP)
|
||||
MOVEA.L DDREQUEST(PC),A5 A5.L: リクエストヘッダアドレス
|
||||
* CMPI.B #$40,COMMAND(A5) 現行のHuman68kではチェック不要
|
||||
* BNE UNSUPPORTED エラー: 未対応
|
||||
|
||||
*タイトル表示
|
||||
PEA MESSAGE_TITLE(PC)
|
||||
DOS _PRINT
|
||||
ADDQ.L #4,SP
|
||||
|
||||
*デバイスチェック
|
||||
DEVICE_CHECK:
|
||||
BSR _Init
|
||||
|
||||
TST.L D0
|
||||
BEQ NOTFOUND エラー: デバイスが存在しません
|
||||
|
||||
*常駐開始
|
||||
LEA DDENTRY(PC),A1
|
||||
|
||||
LEA DDHEADER+$0A(PC),A0
|
||||
MOVE.L A1,(A0) ドライバエントリを設定
|
||||
MOVE.L #PROG_END,DEVEND(A5) 常駐終了アドレスを設定
|
||||
|
||||
ST.B MXUNIT(A5) ポート未実装の判定のため負の値を設定しておく
|
||||
JSR (A1) ドライバエントリを実行
|
||||
|
||||
TST.B MXUNIT(A5) ユニット数確認
|
||||
BLE NODRIVE エラー: ドライブがありません
|
||||
|
||||
MOVE.B BDEVNO(A5),D0
|
||||
MOVE.B MXUNIT(A5),D1
|
||||
LEA FIRSTDRIVE(PC),A0
|
||||
ADD.B D0,(A0) 開始ドライブ名書き換え
|
||||
ADD.B D1,D0 終了ドライブ名書き換え
|
||||
ADD.B D0,LASTDRIVE-FIRSTDRIVE(A0)
|
||||
|
||||
PEA MESSAGE_DRIVENAME(PC) 正常: ドライブA:
|
||||
DOS _PRINT
|
||||
|
||||
PEA MESSAGE_DRIVENAME2(PC) 正常: からZ:
|
||||
SUBQ.B #2,D1
|
||||
BCS @F
|
||||
DOS _PRINT
|
||||
@@ ADDQ.L #8,SP
|
||||
|
||||
PEA MESSAGE_DRIVENAME3(PC) 正常: を登録しました
|
||||
BRA QUIT
|
||||
|
||||
NOTFOUND:
|
||||
PEA MESSAGE_NOTFOUND(PC) エラー: デバイスが存在しません
|
||||
BRA ABORT
|
||||
|
||||
UNSUPPORTED:
|
||||
PEA MESSAGE_UNSUPPORTED(PC) エラー: 未対応
|
||||
BRA ABORT
|
||||
|
||||
NODRIVE:
|
||||
PEA MESSAGE_NODRIVE(PC) エラー: ドライブがありません
|
||||
|
||||
ABORT:
|
||||
MOVE.B #$0D,ERRLOW(A5)
|
||||
MOVE.B #$70,ERRHIGH(A5)
|
||||
|
||||
QUIT:
|
||||
DOS _PRINT
|
||||
ADDQ.L #4,SP
|
||||
|
||||
MOVEM.L (SP)+,D1-D3/A0-A2/A5
|
||||
RTS
|
||||
|
||||
SECRET:
|
||||
PEA MESSAGE_TITLE2(PC)
|
||||
DOS _PRINT
|
||||
PEA CREDIT(PC)
|
||||
DOS _PRINT
|
||||
ADDQ.L #8,SP
|
||||
DOS _EXIT
|
||||
|
||||
DATA
|
||||
|
||||
*エラーメッセージ
|
||||
MESSAGE_NOTFOUND:
|
||||
DC.B 'デバイスが存在しません',$0D,$0A,0
|
||||
|
||||
MESSAGE_UNSUPPORTED:
|
||||
DC.B '未対応',$0D,$0A,0
|
||||
|
||||
MESSAGE_NODRIVE:
|
||||
DC.B 'ドライブがありません',$0D,$0A,0
|
||||
|
||||
*登録メッセージ
|
||||
MESSAGE_DRIVENAME:
|
||||
DC.B 'ドライブ'
|
||||
FIRSTDRIVE:
|
||||
DC.B 'A:',0
|
||||
MESSAGE_DRIVENAME2:
|
||||
DC.B 'から'
|
||||
LASTDRIVE:
|
||||
DC.B '@:',0
|
||||
MESSAGE_DRIVENAME3:
|
||||
DC.B 'を登録しました',$0D,$0A,0
|
||||
|
||||
*タイトル
|
||||
MESSAGE_TITLE:
|
||||
DC.B $0D,$0A
|
||||
MESSAGE_TITLE2:
|
||||
DC.B 'RaSCSI FileSystem Driver version 1.21',$0D,$0A,0
|
||||
|
||||
*ありがとう!
|
||||
CREDIT:
|
||||
DC.B 'Coded by GIMONS',$0D,$0A
|
||||
DC.B 'Special thanks to',$0D,$0A
|
||||
DC.B 9,'co',$0D,$0A
|
||||
DC.B 9,'PI.',$0D,$0A
|
||||
DC.B 9,'立花@桑島技研',$0D,$0A
|
||||
DC.B 0
|
||||
|
||||
BSS
|
||||
QUAD
|
||||
|
||||
STACK_BUFF:
|
||||
.DS.L 1
|
||||
|
||||
STACK
|
||||
QUAD
|
||||
|
||||
.DS.B 1024*2
|
||||
DEF_STACK:
|
||||
|
||||
|
||||
PROG_END:
|
||||
END SECRET
|
29
src/x68k/RASDRV/RASDRV.TXT
Normal file
29
src/x68k/RASDRV/RASDRV.TXT
Normal file
@ -0,0 +1,29 @@
|
||||
RaSCSI ファイルシステムドライバ
|
||||
RASDRV version 1.21
|
||||
|
||||
■概要
|
||||
|
||||
本プログラムはX68000実機で動作しているHuman68kからRaSCSIのブリッジデバイスを
|
||||
通してRaspberry Pi側のファイルシステムを直接操作するためのデバイスドライバです。
|
||||
X68000エミュレータであるXM6及びXM6改ならびにTypeGのWindrvXMと同等の機能を提供
|
||||
します。
|
||||
|
||||
■解説
|
||||
|
||||
利用するにはRaspberry PiのRaSCSIでブリッジデバイスを有効にする必要があります。
|
||||
例えばSCSI ID6にブリッジデバイスを有効にする場合はrascsi -ID6 BRIDGEといった
|
||||
指定が必要です。
|
||||
|
||||
次にデバイスドライバRASCSI.SYSを実機の環境にコピーします。あとはCONFIG.SYSの
|
||||
後半部分に以下のように記述してください。
|
||||
|
||||
DEVICE = \SYS\RASDRV.SYS
|
||||
|
||||
起動オプションを指定しない場合はRaspberry Piのルートディレクトリ配下をマウント
|
||||
します。引数にディレクトリ名を指定することでそのディレクトリをマウントできます。
|
||||
例えば/home/pi/appと/home/pi/dataというディレクトリをマウントする場合は
|
||||
|
||||
DEVICE = \SYS\RASDRV.SYS /home/pi/app /home/pi/data
|
||||
|
||||
と記述することで二つのディレクトリを別々のドライブとしてマウント可能です。
|
||||
その他のオプションとしてWindrvXMのものが指定可能です。
|
33
src/x68k/RASETHER/Makefile
Normal file
33
src/x68k/RASETHER/Makefile
Normal file
@ -0,0 +1,33 @@
|
||||
#
|
||||
# Makefile for RASETHER.SYS
|
||||
#
|
||||
|
||||
TARGET = RASETHER.SYS
|
||||
|
||||
OBJS = re.o asmsub.o main.o scsictl.o
|
||||
LIBS = libc.a libgnu.a libscsi.a
|
||||
|
||||
CC = gcc -O2 -Wall -fomit-frame-pointer
|
||||
CFLAGS = -D__DOS_INLINE__ -D__IOCS_INLINE__
|
||||
#CFLAGS = -D__DOS_INLINE__ -D__IOCS_INLINE__ -DUSE_DMA
|
||||
|
||||
AS = has
|
||||
ASFLAGS =
|
||||
LD = hlk
|
||||
LDFLAGS = -l -x
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
$(TARGET): $(OBJS)
|
||||
$(LD) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||
|
||||
scsictl.o: scsictl.c scsictl.h
|
||||
$(COMPILE.c) $<
|
||||
|
||||
main.o: main.c main.h scsictl.h
|
||||
$(COMPILE.c) $<
|
||||
|
||||
asmsub.o: asmsub.s
|
||||
|
||||
# EOF
|
||||
|
42
src/x68k/RASETHER/RASETHER.DOC
Normal file
42
src/x68k/RASETHER/RASETHER.DOC
Normal file
@ -0,0 +1,42 @@
|
||||
RaSCSI用 Ethernetドライバ
|
||||
RASETHER version 1.20
|
||||
|
||||
Based on
|
||||
Neptune-X board driver for Human-68k(ESP-X) version 0.03
|
||||
Programed 1996-7 by Shi-MAD.
|
||||
Special thanks to Niggle, FIRST, yamapu ...
|
||||
|
||||
● このプログラムは
|
||||
|
||||
Shi-MAD さんの作られた Ethernet 用 ISA バスブリッジ "Neptune-X" 用デバ
|
||||
イスドライバ ether_ne.sys を改造した ether_ne.sys ver0.03 +M01 +1 +L12を
|
||||
参考にして開発したRaSCSI用のイーサーネット通信ドライバです。
|
||||
|
||||
● 使い方
|
||||
|
||||
基本的にはオリジナルのドライバと同じようにデバイスドライバとしてCONFIG.SYS
|
||||
で組み込んで下さい。
|
||||
|
||||
例)
|
||||
DEVICE = \SYS\RASETHER.SYS
|
||||
|
||||
以下のオプションが指定可能です。
|
||||
-tx [xは数字] : 使用するtrapを指定します。xは0から6が指定可能です。
|
||||
ただし、指定したtrapが使用中である場合は、trap #0から
|
||||
空いている所を自動探索し、見つかった空きtrapを利用し
|
||||
ます。
|
||||
-n : APIにtrapを使用しません。
|
||||
|
||||
RASETHERで拡張したオプションは以下のとおりです。
|
||||
-px [xは数字] : パケット受信のポーリング間隔を指定します1がデフォルトです。
|
||||
1の場合は約16ms毎にポーリングします。2,3・・・8まで指定が可能
|
||||
です。数字が一つ増えるごとに16ms間隔が大きくなります。
|
||||
|
||||
-ix [xは数字] : ポーリングに使用する割り込みのタイプを指定します。
|
||||
デフォルトは0でMFPのGPIP割り込み(V-DISP)を利用します。
|
||||
1を指定するとTimer-A割り込みを使用します。
|
||||
|
||||
|
||||
● このドライバについて
|
||||
オリジナルのether_ne.sys及び改造版のether_ne.sys ver0.03 +M01 +1 +L12の
|
||||
利用規定に従います。
|
22
src/x68k/RASETHER/asmsub.s
Normal file
22
src/x68k/RASETHER/asmsub.s
Normal file
@ -0,0 +1,22 @@
|
||||
* asmsub.s
|
||||
|
||||
.xdef _DI, _EI * ne2000.c nagai.
|
||||
|
||||
.text
|
||||
.even
|
||||
|
||||
|
||||
|
||||
_DI:
|
||||
move.w sr,sendp_sr
|
||||
ori.w #$700,sr
|
||||
rts
|
||||
_EI:
|
||||
move.w sendp_sr,sr
|
||||
rts
|
||||
|
||||
sendp_sr:
|
||||
.ds.w 1
|
||||
|
||||
|
||||
.even
|
282
src/x68k/RASETHER/main.c
Normal file
282
src/x68k/RASETHER/main.c
Normal file
@ -0,0 +1,282 @@
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI Target Emulator RaSCSI (*^..^*)
|
||||
// for Raspberry Pi
|
||||
//
|
||||
// Powered by XM6 TypeG Technorogy.
|
||||
// Copyright (C) 2016-2017 GIMONS
|
||||
// [ RaSCSI イーサーネット メイン ]
|
||||
//
|
||||
// Based on
|
||||
// Neptune-X board driver for Human-68k(ESP-X) version 0.03
|
||||
// Programed 1996-7 by Shi-MAD.
|
||||
// Special thanks to Niggle, FIRST, yamapu ...
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/dos.h>
|
||||
#include "main.h"
|
||||
#include "scsictl.h"
|
||||
|
||||
unsigned int scsiid;
|
||||
int trap_no;
|
||||
int num_of_prt;
|
||||
struct prt PRT_LIST[NPRT];
|
||||
|
||||
// マルチキャスト(未対応)
|
||||
#ifdef MULTICAST
|
||||
int num_of_multicast;
|
||||
struct eaddr multicast_array[NMULTICAST];
|
||||
#endif
|
||||
|
||||
/************************************************
|
||||
* *
|
||||
************************************************/
|
||||
static int sprint_eaddr(unsigned char* dst, void* e)
|
||||
{
|
||||
unsigned char* p = e;
|
||||
|
||||
return sprintf(
|
||||
dst,
|
||||
"%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
|
||||
p[0], p[1], p[2], p[3], p[4], p[5]);
|
||||
}
|
||||
|
||||
/************************************************
|
||||
* TRAP nが使用可能か調べる *
|
||||
************************************************/
|
||||
static int is_valid_trap(int trap_no)
|
||||
{
|
||||
unsigned int addr;
|
||||
|
||||
if (trap_no < 0 || 7 < trap_no) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 使用中かどうかチェック
|
||||
addr = (unsigned int)_dos_intvcg(TRAP_VECNO(trap_no));
|
||||
|
||||
// 処理アドレスの最上位バイトにベクタ番号が入っていれば未使用
|
||||
if (addr & 0xff000000) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/************************************************
|
||||
* 未使用のTRAP nを検索 *
|
||||
************************************************/
|
||||
static int search_trap_no(int def)
|
||||
{
|
||||
int i;
|
||||
|
||||
// もしdefが使用可能ならそれに決定
|
||||
if (is_valid_trap(def)) {
|
||||
return def;
|
||||
}
|
||||
|
||||
for (i = 0; i <= 6; i++) {
|
||||
if (is_valid_trap(i)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/************************************************
|
||||
* vector set *
|
||||
************************************************/
|
||||
static void* trap_vector(int trap_no, void *func)
|
||||
{
|
||||
return _dos_intvcs(TRAP_VECNO(trap_no), func);
|
||||
}
|
||||
|
||||
/************************************************
|
||||
初期化関数(ne.sイニシャライズで呼びます) *
|
||||
************************************************/
|
||||
int Initialize(void)
|
||||
{
|
||||
unsigned char buff[128];
|
||||
unsigned char buff2[32];
|
||||
struct eaddr ether_addr;
|
||||
|
||||
if (SearchRaSCSI())
|
||||
{
|
||||
Print("RaSCSI Ether Adapter の存在を確認できませんでした\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (InitList(NPRT)
|
||||
|| InitRaSCSI())
|
||||
{
|
||||
Print("RaSCSI Ether Adapter Driver の初期化に失敗しました\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(ðer_addr, 0x00, sizeof(ether_addr));
|
||||
GetMacAddr(ðer_addr);
|
||||
|
||||
// 未使用trap番号を調べる(指定番号優先)
|
||||
if (trap_no >= 0) {
|
||||
trap_no = search_trap_no(trap_no);
|
||||
}
|
||||
|
||||
if (trap_no >= 0) {
|
||||
// trapをフックする
|
||||
trap_vector(trap_no, (void*)trap_entry);
|
||||
sprintf(buff, " API trap number:%d ", trap_no);
|
||||
} else {
|
||||
sprintf(buff, " API trap number:n/a ");
|
||||
}
|
||||
Print(buff);
|
||||
|
||||
sprintf(buff, "SCSI ID:%d ", scsiid);
|
||||
Print(buff);
|
||||
|
||||
sprint_eaddr(buff2, ether_addr.eaddr);
|
||||
sprintf(buff, "MAC Addr:%s\r\n", buff2);
|
||||
Print(buff);
|
||||
|
||||
// ポーリング開始
|
||||
RegisterIntProcess(poll_interval);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/************************************************
|
||||
* プロトコルリスト初期化 *
|
||||
************************************************/
|
||||
int InitList(int n)
|
||||
{
|
||||
struct prt* p;
|
||||
int i;
|
||||
|
||||
p = &PRT_LIST[0];
|
||||
for (i = 0; i < NPRT; i++, p++) {
|
||||
p->type = -1;
|
||||
p->func = 0;
|
||||
p->malloc = (malloc_func)-1;
|
||||
}
|
||||
num_of_prt = 0;
|
||||
|
||||
#ifdef MULTICAST
|
||||
num_of_multicast = 0;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/************************************************
|
||||
* 受信ハンドラ(プロトコル)追加 *
|
||||
************************************************/
|
||||
int AddList(int type, int_handler handler)
|
||||
{
|
||||
struct prt* p;
|
||||
int i, result;
|
||||
|
||||
if (type == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
result = -1;
|
||||
|
||||
// overwrite if alreay exist
|
||||
p = &PRT_LIST[0];
|
||||
for (i = 0; i < NPRT; i++, p++) {
|
||||
if ((p->type == type && p->malloc != (malloc_func)-1)
|
||||
|| p->type == -1)
|
||||
{
|
||||
if (p->type == -1)
|
||||
num_of_prt++;
|
||||
|
||||
p->type = type;
|
||||
p->func = handler;
|
||||
p->malloc = (malloc_func)-1;
|
||||
i++;
|
||||
p++;
|
||||
result = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// clear if exist more
|
||||
for (; i < NPRT; i++, p++) {
|
||||
if (p->type == type && p->malloc != (malloc_func)-1) {
|
||||
p->type = -1;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/************************************************
|
||||
* 受信ハンドラ(プロトコル)削除 *
|
||||
************************************************/
|
||||
int DeleteList(int type)
|
||||
{
|
||||
struct prt* p;
|
||||
int i, result;
|
||||
|
||||
if (type == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
result = -1;
|
||||
for (i = 0, p = &PRT_LIST[0]; i < NPRT; i++, p++) {
|
||||
if (p->type == type && p->malloc != (malloc_func)-1) {
|
||||
p->type = -1;
|
||||
result = 0;
|
||||
num_of_prt--;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/************************************************
|
||||
* 受信ハンドラ(プロトコル)サーチ *
|
||||
************************************************/
|
||||
int_handler SearchList(int type)
|
||||
{
|
||||
struct prt* p;
|
||||
int i;
|
||||
|
||||
if (type == -1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0, p = &PRT_LIST[0]; i < NPRT; i++, p++) {
|
||||
if (p->type == type) {
|
||||
return p->func;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
* 受信ハンドラ(プロトコル)サーチ *
|
||||
************************************************/
|
||||
int_handler SearchList2(int type, int n)
|
||||
{
|
||||
struct prt *p;
|
||||
int i, cur;
|
||||
|
||||
if (type == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cur = 0;
|
||||
for (i = 0, p = &PRT_LIST[0]; i < NPRT; i++, p++) {
|
||||
if (p->type == type && cur++ == n) {
|
||||
return p->func;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
81
src/x68k/RASETHER/main.h
Normal file
81
src/x68k/RASETHER/main.h
Normal file
@ -0,0 +1,81 @@
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI Target Emulator RaSCSI (*^..^*)
|
||||
// for Raspberry Pi
|
||||
//
|
||||
// Powered by XM6 TypeG Technorogy.
|
||||
// Copyright (C) 2016-2017 GIMONS
|
||||
// [ RaSCSI イーサーネット メイン ]
|
||||
//
|
||||
// Based on
|
||||
// Neptune-X board driver for Human-68k(ESP-X) version 0.03
|
||||
// Programed 1996-7 by Shi-MAD.
|
||||
// Special thanks to Niggle, FIRST, yamapu ...
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef main_h
|
||||
#define main_h
|
||||
|
||||
#define ID_EN0 (('e'<<24)+('n'<<16)+('0'<<8))
|
||||
#undef MULTICAST
|
||||
|
||||
// number of protocol type we can handle **EDIT this**
|
||||
#define NPRT (16)
|
||||
|
||||
// number of multicast address we can handle **EDIT this**
|
||||
#define NMULTICAST (64)
|
||||
/* ただし、まだマルチキャストには対応していない */
|
||||
|
||||
struct eaddr {
|
||||
unsigned char eaddr [6];
|
||||
};
|
||||
|
||||
typedef void (*int_handler) (int, void*, int);
|
||||
typedef void (*malloc_func) (unsigned int*);
|
||||
|
||||
struct prt {
|
||||
int type;
|
||||
int_handler func;
|
||||
malloc_func malloc;
|
||||
};
|
||||
|
||||
|
||||
// グローバル変数
|
||||
extern unsigned int scsiid;
|
||||
extern int trap_no;
|
||||
extern int num_of_prt;
|
||||
extern struct prt PRT_LIST [NPRT];
|
||||
|
||||
#ifdef MULTICAST
|
||||
extern int num_of_multicast;
|
||||
extern struct eaddr multicast_array [NMULTICAST];
|
||||
#endif
|
||||
|
||||
|
||||
// プロトタイプ宣言
|
||||
extern int Initialize (void);
|
||||
extern int InitList (int);
|
||||
extern int AddList (int, int_handler);
|
||||
extern int DeleteList (int);
|
||||
extern int_handler SearchList (int);
|
||||
extern int_handler SearchList2 (int, int);
|
||||
extern malloc_func GetMallocFunc (int, int);
|
||||
|
||||
#ifdef MULTICAST
|
||||
extern int AddMulticastArray (struct eaddr*);
|
||||
extern void DelMulticastArray (struct eaddr*);
|
||||
extern void MakeMulticastTable (unsigned char*);
|
||||
#endif
|
||||
|
||||
|
||||
// ne.s 内関数
|
||||
extern void trap_entry (void);
|
||||
|
||||
|
||||
#include <sys/iocs.h>
|
||||
#define Print _iocs_b_print
|
||||
|
||||
#define TRAP_VECNO(n) (0x20 + n)
|
||||
|
||||
#endif // main_h
|
574
src/x68k/RASETHER/re.s
Normal file
574
src/x68k/RASETHER/re.s
Normal file
@ -0,0 +1,574 @@
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
** SCSI Target Emulator RaSCSI (*^..^*)
|
||||
** for Raspberry Pi
|
||||
**
|
||||
** Powered by XM6 TypeG Technorogy.
|
||||
** Copyright (C) 2016-2017 GIMONS
|
||||
** [ RaSCSI イーサーネット ドライバ ]
|
||||
**
|
||||
** Based on
|
||||
** Neptune-X board driver for Human-68k(ESP-X) version 0.03
|
||||
** Programed 1996-7 by Shi-MAD.
|
||||
** Special thanks to Niggle, FIRST, yamapu ...
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
|
||||
* Include Files ----------------------- *
|
||||
|
||||
.include doscall.mac
|
||||
.include iocscall.mac
|
||||
|
||||
|
||||
* Global Symbols ---------------------- *
|
||||
|
||||
*
|
||||
* C言語用 外部宣言
|
||||
*
|
||||
.xref _Initialize, _AddList, _SearchList, _DeleteList ;main.c
|
||||
.xref _GetMacAddr, _SetMacAddr ;scsictl.c
|
||||
.xref _SendPacket, _SetPacketReception ;scsictl.c
|
||||
* .xref _AddMulticastAddr, _DelMulticastAddr ;未実装
|
||||
|
||||
*
|
||||
* C言語用 外部変数
|
||||
*
|
||||
.xref _num_of_prt ;main.c 登録プロトコル数
|
||||
.xref _trap_no ;使用trapナンバー
|
||||
.xref _trans_counter ;scsictl.c 送信/受信バイト数
|
||||
.xref _intr_type ;scsictl.c 割り込み種別
|
||||
.xref _poll_interval ;scsictl.c ポーリング間隔
|
||||
|
||||
|
||||
* Text Section -------------------------------- *
|
||||
|
||||
.cpu 68000
|
||||
.text
|
||||
|
||||
|
||||
*
|
||||
* デバイスヘッダー
|
||||
*
|
||||
device_header:
|
||||
.dc.l -1 ;リンクポインター
|
||||
.dc $8000 ;device att.
|
||||
.dc.l strategy_entry ;stategy entry
|
||||
.dc.l interupt_entry ;interupt entry
|
||||
.dc.b '/dev/en0' ;device name
|
||||
.dc.b 'EthD' ;for etherlib.a
|
||||
.dc.b 'RASC' ;driver name (この後にエントリーを置く)
|
||||
|
||||
* 'RASC' から superjsr_entry の間には何も置かないこと
|
||||
|
||||
*
|
||||
* イーサドライバ 関数 エントリー ( for DOS _SUPERJSR )
|
||||
* in: d0: command number
|
||||
* a0: args
|
||||
*
|
||||
superjsr_entry:
|
||||
movem.l d1-d7/a1-a7,-(sp)
|
||||
|
||||
* move.l d0,-(sp)
|
||||
* pea (mes11,pc)
|
||||
* DOS _PRINT
|
||||
* addq.l #4,sp
|
||||
* move.l (sp)+,d0
|
||||
* .data
|
||||
*mes11: .dc.b 'en0:spjEntry',13,10,0
|
||||
* .text
|
||||
|
||||
bsr do_command
|
||||
movem.l (sp)+,d1-d7/a1-a7
|
||||
rts ;普通のリターン
|
||||
|
||||
|
||||
*
|
||||
* イーサドライバ 関数 エントリー ( for trap #n )
|
||||
* in: d0: command number
|
||||
* a0: args
|
||||
*
|
||||
_trap_entry::
|
||||
movem.l d1-d7/a1-a7,-(sp)
|
||||
|
||||
* move.l d0,-(sp)
|
||||
* pea (mes10,pc)
|
||||
* DOS _PRINT
|
||||
* addq.l #4,sp
|
||||
* move.l (sp)+,d0
|
||||
* .data
|
||||
*mes10: .dc.b 'en0:trapEntry',13,10,0
|
||||
* .text
|
||||
|
||||
bsr do_command
|
||||
movem.l (sp)+,d1-d7/a1-a7
|
||||
rte ;割り込みリターン
|
||||
|
||||
|
||||
*
|
||||
* 各処理ふりわけ
|
||||
*
|
||||
do_command:
|
||||
moveq #FUNC_MIN,d1
|
||||
cmp.l d0,d1
|
||||
bgt error ;d0<-2 なら未対応コマンド番号
|
||||
moveq #FUNC_MAX,d1
|
||||
cmp.l d1,d0
|
||||
bgt error ;9<d0 なら未対応コマンド番号
|
||||
|
||||
add d0,d0
|
||||
move (jumptable,pc,d0.w),d0
|
||||
jmp (jumptable,pc,d0.w) ;引数 a0 をレジスタ渡し
|
||||
** rts
|
||||
error:
|
||||
moveq #-1,d0
|
||||
rts
|
||||
|
||||
*
|
||||
* ジャンプテーブル
|
||||
*
|
||||
|
||||
FUNC_MIN: .equ ($-jumptable)/2
|
||||
.dc get_cnt_addr-jumptable ;-2 ... 送受信カウンタのアドレス取得
|
||||
.dc driver_entry-jumptable ;-1 ... 使用trap番号の取得
|
||||
jumptable:
|
||||
.dc get_driver_version-jumptable ;00 ... バージョンの取得
|
||||
.dc get_mac_addr-jumptable ;01 ... 現在のMACアドレス取得
|
||||
.dc get_prom_addr-jumptable ;02 ... PROMに書かれたMACアドレス取得
|
||||
.dc set_mac_addr-jumptable ;03 ... MACアドレスの設定
|
||||
.dc send_packet-jumptable ;04 ... パケット送信
|
||||
.dc set_int_addr-jumptable ;05 ... パケット受信ハンドラ設定
|
||||
.dc get_int_addr-jumptable ;06 ... パケット受信ハンドラのアドレス取得
|
||||
.dc del_int_addr-jumptable ;07 ... ハンドラ削除
|
||||
.dc set_multicast_addr-jumptable ;08 ... (マルチキャストの設定<未対応>)
|
||||
.dc get_statistics-jumptable ;09 ... (統計読み出し<未対応>)
|
||||
FUNC_MAX: .equ ($-jumptable)/2-1
|
||||
|
||||
|
||||
*
|
||||
* コマンド -2: 送受信カウンタのアドレスを返す
|
||||
* return: address
|
||||
*
|
||||
get_cnt_addr:
|
||||
pea (_trans_counter,pc)
|
||||
move.l (sp)+,d0
|
||||
rts
|
||||
|
||||
|
||||
*
|
||||
* コマンド -1: 使用trap番号を返す
|
||||
* return: trap number to use (-1:use SUPERJSR)
|
||||
*
|
||||
driver_entry:
|
||||
* pea (mesff,pc)
|
||||
* DOS _PRINT
|
||||
* addq.l #4,sp
|
||||
* .data
|
||||
*mesff: .dc.b 'DriverEntry',13,10,0
|
||||
* .text
|
||||
|
||||
move.l (_trap_no,pc),d0 ;trap_no ... main.c 変数
|
||||
rts
|
||||
|
||||
|
||||
*
|
||||
* コマンド 00: ドライバーのバージョンを返す
|
||||
* return: version number (例... ver1.00 なら 100 を返す)
|
||||
*
|
||||
get_driver_version:
|
||||
* pea (mes00,pc)
|
||||
* DOS _PRINT
|
||||
* addq.l #4,sp
|
||||
* .data
|
||||
*mes00: .dc.b 'GetDriverVersion',13,10,0
|
||||
* .text
|
||||
|
||||
moveq #3,d0 ;ver 0.03
|
||||
rts
|
||||
|
||||
|
||||
*
|
||||
* コマンド 01: 現在の MAC アドレスの取得
|
||||
* return: same as *dst
|
||||
*
|
||||
get_mac_addr:
|
||||
* pea (mes01,pc)
|
||||
* DOS _PRINT
|
||||
* addq.l #4,sp
|
||||
* .data
|
||||
*mes01: .dc.b 'GetMacAddr',13,10,0
|
||||
* .text
|
||||
|
||||
pea (a0)
|
||||
pea (a0)
|
||||
bsr _GetMacAddr ;scsictl.c 関数
|
||||
addq.l #4,sp
|
||||
move.l (sp)+,d0 ;引数の a0 を d0 にそのまま返す
|
||||
rts
|
||||
|
||||
*
|
||||
* コマンド 02: EEPROM に書かれた MAC アドレスの取得
|
||||
* return: same as *dst
|
||||
*
|
||||
get_prom_addr:
|
||||
* pea (mes02,pc)
|
||||
* DOS _PRINT
|
||||
* addq.l #4,sp
|
||||
* .data
|
||||
*mes02: .dc.b 'GePromAddr',13,10,0
|
||||
* .text
|
||||
|
||||
pea (a0)
|
||||
pea (a0)
|
||||
bsr _GetMacAddr ;scsictl.c 関数
|
||||
addq.l #4,sp
|
||||
move.l (sp)+,d0 ;引数の a0 を d0 にそのまま返す
|
||||
rts
|
||||
|
||||
*
|
||||
* コマンド 03: MACアドレスの設定
|
||||
* return: 0 (if no errors)
|
||||
*
|
||||
set_mac_addr:
|
||||
* pea (mes03,pc)
|
||||
* DOS _PRINT
|
||||
* addq.l #4,sp
|
||||
* .data
|
||||
*mes03: .dc.b 'SetMacAddr',13,10,0
|
||||
* .text
|
||||
|
||||
pea (a0)
|
||||
bsr _SetMacAddr ;scsictl.c 関数
|
||||
addq.l #4,sp
|
||||
rts
|
||||
|
||||
|
||||
*
|
||||
* コマンド 04: パケット送信
|
||||
* packet contents:
|
||||
* Distination MAC: 6 bytes
|
||||
* Source(own) MAC: 6 bytes
|
||||
* Protcol type: 2 bytes
|
||||
* Data: ? bytes
|
||||
* return: 0 (if no errors)
|
||||
*
|
||||
send_packet:
|
||||
* pea (mes04,pc)
|
||||
* DOS _PRINT
|
||||
* addq.l #4,sp
|
||||
|
||||
move.l (a0)+,d0 ;パケットサイズ
|
||||
move.l (a0),-(sp) ;パケットアドレス
|
||||
move.l d0,-(sp)
|
||||
bsr _SendPacket ;scsictl.c 関数
|
||||
addq.l #8,sp
|
||||
|
||||
* move.l d0,-(sp)
|
||||
* pea (mes04e,pc)
|
||||
* DOS _PRINT
|
||||
* addq.l #4,sp
|
||||
* move.l (sp)+,d0
|
||||
* .data
|
||||
*mes04: .dc.b 13,10,'SendPacket,13,10',0
|
||||
*mes04e:.dc.b 13,10,'SendPacketおわり',13,10,0
|
||||
* .text
|
||||
|
||||
rts
|
||||
|
||||
|
||||
*
|
||||
* コマンド 05: 受信割り込みハンドラ追加・設定
|
||||
* type: 0x00000800 IP packet
|
||||
* 0x00000806 ARP packet
|
||||
* return: 0 (if no errors)
|
||||
*
|
||||
set_int_addr:
|
||||
* pea (mes05,pc)
|
||||
* DOS _PRINT
|
||||
* addq.l #4,sp
|
||||
* .data
|
||||
*mes05: .dc.b 'SetIntAddr',13,10,0
|
||||
* .text
|
||||
|
||||
move.l (a0)+,d0 ;プロトコル番号
|
||||
move.l (a0),-(sp) ;ハンドラ関数のアドレス
|
||||
move.l d0,-(sp)
|
||||
bsr _AddList ;main.c 関数
|
||||
addq.l #8,sp
|
||||
tst.l d0
|
||||
bmi set_int_addr_rts ;登録失敗
|
||||
|
||||
cmpi.l #1,(_num_of_prt) ;ハンドラ数が1なら割り込み許可へ
|
||||
bne set_int_addr_rts
|
||||
|
||||
pea (1) ;1=<許可>
|
||||
bsr _SetPacketReception ;割り込み許可 ... scsictl.c
|
||||
addq.l #4,sp
|
||||
|
||||
* moveq #0,d0 ;SetPacketReception() で常に 0 が返るので省略
|
||||
set_int_addr_rts:
|
||||
rts
|
||||
|
||||
|
||||
*
|
||||
* コマンド 06: 割り込みハンドラのアドレス取得
|
||||
* return: interupt address
|
||||
*
|
||||
get_int_addr:
|
||||
* pea (mes07,pc)
|
||||
* DOS _PRINT
|
||||
* addq.l #4,sp
|
||||
* .data
|
||||
*mes07: .dc.b 'GetIntAddr',13,10,0
|
||||
* .text
|
||||
|
||||
pea (a0)
|
||||
bsr _SearchList
|
||||
addq.l #4,sp
|
||||
rts
|
||||
|
||||
|
||||
*
|
||||
* コマンド 07: 割り込みハンドラの削除
|
||||
* return: 0 (if no errors)
|
||||
*
|
||||
del_int_addr:
|
||||
* pea (mes06,pc)
|
||||
* DOS _PRINT
|
||||
* addq.l #4,sp
|
||||
* .data
|
||||
*mes06: .dc.b 'DelIntAddr',13,10,0
|
||||
* .text
|
||||
|
||||
pea (a0)
|
||||
bsr _DeleteList ;main.c 関数
|
||||
move.l d0,(sp)+
|
||||
bmi del_int_addr_ret ;削除失敗
|
||||
|
||||
tst.l (_num_of_prt) ;ハンドラが一つもなくなれば割り込みを禁止する
|
||||
bne del_int_addr_ret
|
||||
|
||||
clr.l -(sp) ;0=<禁止>
|
||||
bsr _SetPacketReception ;割り込み禁止 ... scsictl.c
|
||||
addq.l #4,sp
|
||||
|
||||
* moveq #0,d0 ;SetPacketReception() で常に 0 が返るので省略
|
||||
del_int_addr_ret:
|
||||
rts
|
||||
|
||||
|
||||
*
|
||||
* コマンド 08: マルチキャストアドレスの設定
|
||||
*
|
||||
set_multicast_addr:
|
||||
* pea (mes08,pc)
|
||||
* .data
|
||||
* DOS _PRINT
|
||||
* addq.l #4,sp
|
||||
*mes08: .dc.b 'SetMulticastAddr',13,10,0
|
||||
* .text
|
||||
|
||||
moveq #0,d0
|
||||
rts
|
||||
|
||||
|
||||
*
|
||||
* コマンド 09: 統計読み出し
|
||||
*
|
||||
get_statistics:
|
||||
* pea (mes09,pc)
|
||||
* DOS _PRINT
|
||||
* addq.l #4,sp
|
||||
* .data
|
||||
*mes09: .dc.b 'GetStatistics',13,10,0
|
||||
* .text
|
||||
|
||||
moveq #0,d0
|
||||
rts
|
||||
|
||||
*
|
||||
* デバイスドライバエントリー
|
||||
*
|
||||
strategy_entry:
|
||||
move.l a5,(request_buffer)
|
||||
rts
|
||||
|
||||
|
||||
interupt_entry:
|
||||
move.l sp,(stack_buff) ;自前のスタックエリアを使う
|
||||
lea (def_stack),sp ;
|
||||
|
||||
movem.l d1-d7/a0-a5,-(sp)
|
||||
movea.l (request_buffer,pc),a5
|
||||
tst.b (2,a5)
|
||||
bne errorret
|
||||
|
||||
pea (mestitle,pc)
|
||||
DOS _PRINT
|
||||
addq.l #4,sp
|
||||
movea.l (18,a5),a4
|
||||
@@:
|
||||
tst.b (a4)+
|
||||
bne @b
|
||||
|
||||
moveq #0,d0
|
||||
move.l d0,(_trap_no)
|
||||
move.l d0,(_intr_type)
|
||||
moveq #1,d0
|
||||
move.l d0,(_poll_interval)
|
||||
|
||||
arg_loop:
|
||||
move.b (a4)+,d0
|
||||
beq arg_end
|
||||
cmpi.b #'-',d0
|
||||
beq @f
|
||||
cmpi.b #'/',d0
|
||||
bne param_errret
|
||||
@@:
|
||||
move.b (a4)+,d0
|
||||
beq param_errret
|
||||
opt_loop:
|
||||
andi.b #$df,d0
|
||||
cmpi.b #'I',d0
|
||||
beq opt_i
|
||||
cmpi.b #'P',d0
|
||||
beq opt_p
|
||||
cmpi.b #'T',d0
|
||||
beq opt_t
|
||||
cmpi.b #'N',d0
|
||||
beq opt_n
|
||||
bra param_errret
|
||||
|
||||
opt_n:
|
||||
moveq #-1,d0
|
||||
move.l d0,(_trap_no)
|
||||
move.b (a4)+,d0
|
||||
beq arg_loop
|
||||
bra opt_loop
|
||||
|
||||
opt_t:
|
||||
bsr get_num
|
||||
tst.b d0
|
||||
bne param_errret
|
||||
cmpi #6,d2
|
||||
bgt param_errret
|
||||
move.l d2,(_trap_no)
|
||||
move.b (a4)+,d0
|
||||
beq arg_loop
|
||||
bra opt_loop
|
||||
|
||||
opt_p:
|
||||
bsr get_num
|
||||
tst.b d0
|
||||
bne param_errret
|
||||
cmpi #1,d2
|
||||
blt param_errret
|
||||
cmpi #8,d2
|
||||
bgt param_errret
|
||||
move.l d2,(_poll_interval)
|
||||
move.b (a4)+,d0
|
||||
beq arg_loop
|
||||
bra opt_loop
|
||||
|
||||
opt_i:
|
||||
bsr get_num
|
||||
tst.b d0
|
||||
bne param_errret
|
||||
cmpi #1,d2
|
||||
bgt param_errret
|
||||
move.l d2,(_intr_type)
|
||||
move.b (a4)+,d0
|
||||
beq arg_loop
|
||||
bra opt_loop
|
||||
|
||||
arg_end:
|
||||
bsr _Initialize ;main.c 関数
|
||||
;I/Oアドレス設定
|
||||
;MACアドレス取得
|
||||
;プロトコルリスト初期化
|
||||
;SCSICTL初期化
|
||||
;割り込みハンドラ(ベクタ設定)
|
||||
;trapサービス(ベクタ設定)
|
||||
tst.l d0
|
||||
bne errorret
|
||||
|
||||
* moveq #0,d0
|
||||
move.l #prog_end,(14,a5)
|
||||
bra intret
|
||||
|
||||
|
||||
param_errret:
|
||||
pea (mesparam_err,pc)
|
||||
DOS _PRINT
|
||||
addq.l #4,sp
|
||||
errorret:
|
||||
move #$5003,d0
|
||||
intret:
|
||||
move.b d0,(4,a5)
|
||||
lsr #8,d0
|
||||
move.b d0,(3,a5)
|
||||
movem.l (sp)+,d1-d7/a0-a5
|
||||
|
||||
movea.l (stack_buff,pc),sp ;スタックポインタを元にもどす
|
||||
rts
|
||||
|
||||
get_num:
|
||||
moveq #1,d0
|
||||
moveq #0,d1
|
||||
moveq #0,d2
|
||||
@@:
|
||||
move.b (a4),d1
|
||||
subi.b #'0',d1
|
||||
bcs @f
|
||||
cmpi.b #9,d1
|
||||
bgt @f
|
||||
move.b #0,d0
|
||||
andi #$f,d1
|
||||
mulu #10,d2
|
||||
add d1,d2
|
||||
addq.l #1,a4
|
||||
bra @b
|
||||
@@:
|
||||
rts
|
||||
|
||||
|
||||
* Data Section ------------------------ *
|
||||
|
||||
.data
|
||||
mestitle:
|
||||
.dc.b 13,10
|
||||
.dc.b 'RaSCSI Ethernet Driver version 1.20 / Based on ether_ne.sys+M01L12',13,10
|
||||
.dc.b 0
|
||||
mesparam_err:
|
||||
.dc.b 'パラメータが異常です',13,10,0
|
||||
.even
|
||||
|
||||
|
||||
* BSS --------------------------------- *
|
||||
|
||||
.bss
|
||||
.quad
|
||||
|
||||
stack_buff:
|
||||
.ds.l 1
|
||||
request_buffer:
|
||||
.ds.l 1
|
||||
stack_buff_i:
|
||||
.ds.l 1
|
||||
|
||||
|
||||
* Stack Section ----------------------- *
|
||||
|
||||
.stack
|
||||
.quad
|
||||
|
||||
*
|
||||
* スタックエリア
|
||||
*
|
||||
.ds.b 1024*8
|
||||
def_stack:
|
||||
|
||||
prog_end:
|
||||
.end
|
||||
|
||||
|
||||
* EOF --------------------------------- *
|
537
src/x68k/RASETHER/scsictl.c
Normal file
537
src/x68k/RASETHER/scsictl.c
Normal file
@ -0,0 +1,537 @@
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI Target Emulator RaSCSI (*^..^*)
|
||||
// for Raspberry Pi
|
||||
//
|
||||
// Powered by XM6 TypeG Technorogy.
|
||||
// Copyright (C) 2016-2017 GIMONS
|
||||
// [ RaSCSI イーサーネット SCSI制御部 ]
|
||||
//
|
||||
// Based on
|
||||
// Neptune-X board driver for Human-68k(ESP-X) version 0.03
|
||||
// Programed 1996-7 by Shi-MAD.
|
||||
// Special thanks to Niggle, FIRST, yamapu ...
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/dos.h>
|
||||
#include <sys/scsi.h>
|
||||
#include <iocslib.h>
|
||||
#include "main.h"
|
||||
#include "scsictl.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char DeviceType;
|
||||
char RMB;
|
||||
char ANSI_Ver;
|
||||
char RDF;
|
||||
char AddLen;
|
||||
char RESV0;
|
||||
char RESV1;
|
||||
char OptFunc;
|
||||
char VendorID[8];
|
||||
char ProductID[16];
|
||||
char FirmRev[4];
|
||||
} INQUIRY_T;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
INQUIRY_T info;
|
||||
char options[8];
|
||||
} INQUIRYOPT_T;
|
||||
|
||||
#define MFP_AEB 0xe88003
|
||||
#define MFP_IERB 0xe88009
|
||||
#define MFP_IMRB 0xe88015
|
||||
|
||||
// asmsub.s 内のサブルーチン
|
||||
extern void DI();
|
||||
extern void EI();
|
||||
|
||||
volatile short* iocsexec = (short*)0xa0e; // IOCS実行中ワーク
|
||||
struct trans_counter trans_counter; // 送受信カウンタ
|
||||
unsigned char rx_buff[2048]; // 受信バッファ
|
||||
int imr; // 割り込み許可フラグ
|
||||
int scsistop; // SCSI停止中フラグ
|
||||
int intr_type; // 割り込み種別(0:V-DISP 1:TimerA)
|
||||
int poll_interval; // ポーリング間隔(設定)
|
||||
int poll_current; // ポーリング間隔(現在)
|
||||
int idle; // アイドルカウンタ
|
||||
|
||||
#define POLLING_SLEEP 255 // 4-5s
|
||||
|
||||
/************************************************
|
||||
* MACアドレス取得命令発行 *
|
||||
************************************************/
|
||||
int SCSI_GETMACADDR(unsigned char *mac)
|
||||
{
|
||||
unsigned char cmd[10];
|
||||
unsigned char sts;
|
||||
unsigned char msg;
|
||||
|
||||
if (S_SELECT(scsiid) != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
cmd[0] = 0x28;
|
||||
cmd[1] = 0;
|
||||
cmd[2] = 1;
|
||||
cmd[3] = 0;
|
||||
cmd[4] = 0;
|
||||
cmd[5] = 0;
|
||||
cmd[6] = 0;
|
||||
cmd[7] = 0;
|
||||
cmd[8] = 6;
|
||||
cmd[9] = 0;
|
||||
if (S_CMDOUT(10, cmd) != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef USE_DMA
|
||||
if (S_DATAIN(6, mac) != 0) {
|
||||
#else
|
||||
if (S_DATAIN_P(6, mac) != 0) {
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
S_STSIN(&sts);
|
||||
S_MSGIN(&msg);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/************************************************
|
||||
* MACアドレス設定命令発行 *
|
||||
************************************************/
|
||||
int SCSI_SETMACADDR(const unsigned char *mac)
|
||||
{
|
||||
unsigned char cmd[10];
|
||||
unsigned char sts;
|
||||
unsigned char msg;
|
||||
|
||||
if (S_SELECT(scsiid) != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
cmd[0] = 0x2a;
|
||||
cmd[1] = 0;
|
||||
cmd[2] = 1;
|
||||
cmd[3] = 0;
|
||||
cmd[4] = 0;
|
||||
cmd[5] = 0;
|
||||
cmd[6] = 0;
|
||||
cmd[7] = 0;
|
||||
cmd[8] = 6;
|
||||
cmd[9] = 0;
|
||||
if (S_CMDOUT(10, cmd) != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef USE_DMA
|
||||
S_DATAOUT(6, mac);
|
||||
#else
|
||||
S_DATAOUT_P(6, mac);
|
||||
#endif
|
||||
|
||||
S_STSIN(&sts);
|
||||
S_MSGIN(&msg);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/************************************************
|
||||
* パケット受信サイズ取得命令発行 *
|
||||
************************************************/
|
||||
int SCSI_GETPACKETLEN(int *len)
|
||||
{
|
||||
unsigned char cmd[10];
|
||||
unsigned char buf[2];
|
||||
unsigned char sts;
|
||||
unsigned char msg;
|
||||
|
||||
if (S_SELECT(scsiid) != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
cmd[0] = 0x28;
|
||||
cmd[1] = 0;
|
||||
cmd[2] = 1;
|
||||
cmd[3] = 1;
|
||||
cmd[4] = 0;
|
||||
cmd[5] = 0;
|
||||
cmd[6] = 0;
|
||||
cmd[7] = 0;
|
||||
cmd[8] = 2;
|
||||
cmd[9] = 0;
|
||||
if (S_CMDOUT(10, cmd) != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef USE_DMA
|
||||
if (S_DATAIN(2, buf) != 0) {
|
||||
#else
|
||||
if (S_DATAIN_P(2, buf) != 0) {
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
S_STSIN(&sts);
|
||||
S_MSGIN(&msg);
|
||||
|
||||
*len = (int)(buf[0] << 8) + (int)(buf[1]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/************************************************
|
||||
* パケット受信命令発行 *
|
||||
************************************************/
|
||||
int SCSI_GETPACKETBUF(unsigned char *buf, int len)
|
||||
{
|
||||
unsigned char cmd[10];
|
||||
unsigned char sts;
|
||||
unsigned char msg;
|
||||
|
||||
if (S_SELECT(scsiid) != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
cmd[0] = 0x28;
|
||||
cmd[1] = 0;
|
||||
cmd[2] = 1;
|
||||
cmd[3] = 1;
|
||||
cmd[4] = 0;
|
||||
cmd[5] = 0;
|
||||
cmd[6] = (unsigned char)(len >> 16);
|
||||
cmd[7] = (unsigned char)(len >> 8);
|
||||
cmd[8] = (unsigned char)len;
|
||||
cmd[9] = 1;
|
||||
if (S_CMDOUT(10, cmd) != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef USE_DMA
|
||||
if (S_DATAIN(len, buf) != 0) {
|
||||
#else
|
||||
if (S_DATAIN_P(len, buf) != 0) {
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
S_STSIN(&sts);
|
||||
S_MSGIN(&msg);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/************************************************
|
||||
* パケット送信命令発行 *
|
||||
************************************************/
|
||||
int SCSI_SENDPACKET(const unsigned char *buf, int len)
|
||||
{
|
||||
unsigned char cmd[10];
|
||||
unsigned char sts;
|
||||
unsigned char msg;
|
||||
|
||||
if (S_SELECT(scsiid) != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
cmd[0] = 0x2a;
|
||||
cmd[1] = 0;
|
||||
cmd[2] = 1;
|
||||
cmd[3] = 1;
|
||||
cmd[4] = 0;
|
||||
cmd[5] = 0;
|
||||
cmd[6] = (unsigned char)(len >> 16);
|
||||
cmd[7] = (unsigned char)(len >> 8);
|
||||
cmd[8] = (unsigned char)len;
|
||||
cmd[9] = 0;
|
||||
if (S_CMDOUT(10, cmd) != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef USE_DMA
|
||||
S_DATAOUT(len, buf);
|
||||
#else
|
||||
S_DATAOUT_P(len, buf);
|
||||
#endif
|
||||
S_STSIN(&sts);
|
||||
S_MSGIN(&msg);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/************************************************
|
||||
* MACアドレス取得 *
|
||||
************************************************/
|
||||
int GetMacAddr(struct eaddr* buf)
|
||||
{
|
||||
if (SCSI_GETMACADDR(buf->eaddr) != 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************
|
||||
* MACアドレス設定 *
|
||||
************************************************/
|
||||
int SetMacAddr(const struct eaddr* data)
|
||||
{
|
||||
if (SCSI_SETMACADDR(data->eaddr) != 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************
|
||||
* RaSCSI検索 *
|
||||
************************************************/
|
||||
int SearchRaSCSI()
|
||||
{
|
||||
int i;
|
||||
INQUIRYOPT_T inq;
|
||||
|
||||
for (i = 0; i <= 7; i++) {
|
||||
// BRIDGEデバイス検索
|
||||
if (S_INQUIRY(sizeof(INQUIRY_T) , i, (struct INQUIRY*)&inq) < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (memcmp(&(inq.info.ProductID), "RASCSI BRIDGE", 13) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// TAP初期化状態を取得
|
||||
if (S_INQUIRY(sizeof(INQUIRYOPT_T) , i, (struct INQUIRY*)&inq) < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (inq.options[1] != '1') {
|
||||
continue;
|
||||
}
|
||||
|
||||
// SCSI ID確定
|
||||
scsiid = i;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/************************************************
|
||||
* RaSCSI初期化 関数 *
|
||||
************************************************/
|
||||
int InitRaSCSI(void)
|
||||
{
|
||||
#ifdef MULTICAST
|
||||
unsigned char multicast_table[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
#endif
|
||||
|
||||
imr = 0;
|
||||
scsistop = 0;
|
||||
poll_current = -1;
|
||||
idle = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/************************************************
|
||||
* RaSCSI 割り込み処理 関数(ポーリング) *
|
||||
************************************************/
|
||||
void interrupt IntProcess(void)
|
||||
{
|
||||
unsigned char phase;
|
||||
unsigned int len;
|
||||
int type;
|
||||
int_handler func;
|
||||
int i;
|
||||
|
||||
// V-DISP GPIP割り込みはアイドルカウンタで制御
|
||||
if (intr_type == 0) {
|
||||
// アイドル加算
|
||||
idle++;
|
||||
|
||||
// 次回の処理予定に到達していないならスキップ
|
||||
if (idle < poll_current) {
|
||||
return;
|
||||
}
|
||||
|
||||
// アイドルカウンタをクリア
|
||||
idle = 0;
|
||||
}
|
||||
|
||||
// 割り込み開始
|
||||
|
||||
// 割り込み許可の時だけ
|
||||
if (imr == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// IOCS実行中ならばスキップ
|
||||
if (*iocsexec != -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 受信処理中は割り込み禁止
|
||||
DI ();
|
||||
|
||||
// バスフリーの時だけ
|
||||
phase = S_PHASE();
|
||||
if (phase != 0) {
|
||||
// 終了
|
||||
goto ei_exit;
|
||||
}
|
||||
|
||||
// 受信処理
|
||||
if (SCSI_GETPACKETLEN(&len) == 0) {
|
||||
// RaSCSI停止中
|
||||
scsistop = 1;
|
||||
|
||||
// ポーリング間隔の再設定(寝る)
|
||||
UpdateIntProcess(POLLING_SLEEP);
|
||||
|
||||
// 終了
|
||||
goto ei_exit;
|
||||
}
|
||||
|
||||
// RaSCSIは動作中
|
||||
if (scsistop) {
|
||||
scsistop = 0;
|
||||
|
||||
// ポーリング間隔の再設定(急ぐ)
|
||||
UpdateIntProcess(poll_interval);
|
||||
}
|
||||
|
||||
// パケットは到着してなかった
|
||||
if (len == 0) {
|
||||
// 終了
|
||||
goto ei_exit;
|
||||
}
|
||||
|
||||
// 受信バッファメモリへパケット転送
|
||||
if (SCSI_GETPACKETBUF(rx_buff, len) == 0) {
|
||||
// 失敗
|
||||
goto ei_exit;
|
||||
}
|
||||
|
||||
// 割り込み許可
|
||||
EI ();
|
||||
|
||||
// パケットタイプでデータ分別
|
||||
type = rx_buff[12] * 256 + rx_buff[13];
|
||||
i = 0;
|
||||
while ((func = SearchList2(type, i))) {
|
||||
i++;
|
||||
func(len, (void*)&rx_buff, ID_EN0);
|
||||
}
|
||||
trans_counter.recv_byte += len;
|
||||
return;
|
||||
|
||||
ei_exit:
|
||||
// 割り込み許可
|
||||
EI ();
|
||||
}
|
||||
|
||||
/************************************************
|
||||
* RaSCSI パケット送信 関数 (ne.sから) *
|
||||
************************************************/
|
||||
int SendPacket(int len, const unsigned char* data)
|
||||
{
|
||||
if (len < 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (len > 1514) { // 6 + 6 + 2 + 1500
|
||||
return -1; // エラー
|
||||
}
|
||||
|
||||
// RaSCSI停止中のようならエラー
|
||||
if (scsistop) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 送信処理中は割り込み禁止
|
||||
DI ();
|
||||
|
||||
// 送信処理と送信フラグアップ
|
||||
if (SCSI_SENDPACKET(data, len) == 0) {
|
||||
// 割り込み許可
|
||||
EI ();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 割り込み許可
|
||||
EI ();
|
||||
|
||||
// 送信依頼済み
|
||||
trans_counter.send_byte += len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/************************************************
|
||||
* RaSCSI 割り込み許可、不許可設定 関数 *
|
||||
************************************************/
|
||||
int SetPacketReception(int i)
|
||||
{
|
||||
imr = i;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/************************************************
|
||||
* RaSCSI 割り込み処理登録 *
|
||||
************************************************/
|
||||
void RegisterIntProcess(int n)
|
||||
{
|
||||
volatile unsigned char *p;
|
||||
|
||||
// ポーリング間隔(現在)の更新とアイドルカウンタクリア
|
||||
poll_current = n;
|
||||
idle = 0;
|
||||
|
||||
if (intr_type == 0) {
|
||||
// V-DISP GPIP割り込みベクタを書き換えて
|
||||
// 割り込みを有効にする
|
||||
B_INTVCS(0x46, (int)IntProcess);
|
||||
p = (unsigned char *)MFP_AEB;
|
||||
*p = *p | 0x10;
|
||||
p = (unsigned char *)MFP_IERB;
|
||||
*p = *p | 0x40;
|
||||
p = (unsigned char *)MFP_IMRB;
|
||||
*p = *p | 0x40;
|
||||
} else if (intr_type == 1) {
|
||||
// TimerAはカウントモードを設定
|
||||
VDISPST(NULL, 0, 0);
|
||||
VDISPST(IntProcess, 0, poll_current);
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************
|
||||
* RaSCSI 割り込み処理変更 *
|
||||
************************************************/
|
||||
void UpdateIntProcess(int n)
|
||||
{
|
||||
// ポーリング間隔(現在)と同じなら更新しない
|
||||
if (n == poll_current) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ポーリング間隔(現在)の更新とアイドルカウンタクリア
|
||||
poll_current = n;
|
||||
idle = 0;
|
||||
|
||||
if (intr_type == 1) {
|
||||
// TimerAは再登録必要
|
||||
VDISPST(NULL, 0, 0);
|
||||
VDISPST(IntProcess, 0, poll_current);
|
||||
}
|
||||
}
|
||||
|
||||
// EOF
|
40
src/x68k/RASETHER/scsictl.h
Normal file
40
src/x68k/RASETHER/scsictl.h
Normal file
@ -0,0 +1,40 @@
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI Target Emulator RaSCSI (*^..^*)
|
||||
// for Raspberry Pi
|
||||
//
|
||||
// Powered by XM6 TypeG Technorogy.
|
||||
// Copyright (C) 2016-2017 GIMONS
|
||||
// [ RaSCSI イーサーネット SCSI制御部 ]
|
||||
//
|
||||
// Based on
|
||||
// Neptune-X board driver for Human-68k(ESP-X) version 0.03
|
||||
// Programed 1996-7 by Shi-MAD.
|
||||
// Special thanks to Niggle, FIRST, yamapu ...
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef scsictl_h
|
||||
#define scsictl_h
|
||||
|
||||
// グローバル変数
|
||||
extern int intr_type;
|
||||
extern int poll_interval;
|
||||
|
||||
// 送受信カウンタ
|
||||
struct trans_counter {
|
||||
unsigned int send_byte;
|
||||
unsigned int recv_byte;
|
||||
};
|
||||
extern struct trans_counter trans_counter;
|
||||
|
||||
extern int SearchRaSCSI();
|
||||
extern int InitRaSCSI(void);
|
||||
extern int GetMacAddr(struct eaddr* buf);
|
||||
extern int SetMacAddr(const struct eaddr* data);
|
||||
extern int SetPacketReception(int i);
|
||||
extern int SendPacket(int len, const unsigned char* data);
|
||||
extern void RegisterIntProcess(int n);
|
||||
extern void UpdateIntProcess(int n);
|
||||
|
||||
#endif // scsictl_h
|
Loading…
Reference in New Issue
Block a user