mirror of
https://github.com/thewesker/RASCSI.git
synced 2025-12-20 04:11:07 -05:00
Merged in RASCSI version 1.47 and re-generated english PDF
This commit is contained in:
Binary file not shown.
@@ -1,9 +1,6 @@
|
|||||||
For convenience this is a dump of the RASCSI archive RaSCSI version 1.34 available at:
|
For convenience this is a dump of the RASCSI archive RaSCSI version 1.47 available at:
|
||||||
http://www.geocities.jp/kugimoto0715/rascsi/index.html
|
http://retropc.net/gimons/rascsi/
|
||||||
|
|
||||||
Translated copy of original webpage is available as pdf:
|
Translated copy of original webpage is available as pdf:
|
||||||
https://github.com/XReyRobert/RASCSI/blob/master/RASCSI_v1.34_webpage_translated.pdf
|
https://github.com/akuker/RASCSI/blob/master/RASCSI_webpage_translated.pdf
|
||||||
|
|
||||||
------
|
|
||||||
|
|
||||||
Update: Well I did well: the original pages are not available anymore...
|
|
||||||
|
|||||||
Binary file not shown.
BIN
bin/x68k/RASDRIVER.HDF
Normal file
BIN
bin/x68k/RASDRIVER.HDF
Normal file
Binary file not shown.
BIN
bin/x68k/RASDRIVER.HDS
Normal file
BIN
bin/x68k/RASDRIVER.HDS
Normal file
Binary file not shown.
BIN
bin/x68k/RASDRIVER.XDF
Normal file
BIN
bin/x68k/RASDRIVER.XDF
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,158 +1,116 @@
|
|||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
SCSI Target Emulator RaSCSI (*^..^*)
|
SCSI Target Emulator RaSCSI for Raspberry Pi
|
||||||
version 1.33 for Raspberry Pi
|
|
||||||
|
Powered by XM6 TypeG Technology.
|
||||||
Powered by XM6 TypeG Technology.
|
Copyright (C) 2016-2020 GIMONS
|
||||||
Copyright (C) 2016-2018 GIMONS
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
□変換基板の必要性について
|
||||||
□変換基板の必要性について
|
SCSIはTTLレベルで5Vを220Ωと330Ωで分圧(パッシブターミネータの場合)する
|
||||||
SCSIはTTLレベルで5Vを220Ωと330Ωで分圧(パッシブターミネータの場合)する
|
ことで各信号線に3V弱の電圧がかかった状態が定常状態(信号的にはネゲート)に
|
||||||
ことで各信号線に3V弱の電圧がかかった状態が定常状態(信号的にはネゲート)に
|
なっています。
|
||||||
なっています。
|
|
||||||
|
イニシエータ側もしくはターゲット側が信号をアサートする(=0V)にしようと
|
||||||
イニシエータ側もしくはターゲット側が信号をアサートする(=0V)にしようと
|
すると両端のターミネータから合わせて5000÷220×2=45mAの電流が流れることに
|
||||||
すると両端のターミネータから合わせて5000÷220×2=45mAの電流が流れることに
|
なります(X68000のSCSIコントローラであるMB89352のデータシートを見ればシンク
|
||||||
なります(X68000のSCSIコントローラであるMB89352のデータシートを見ればシンク
|
電流としてIol48mAとなっています)。
|
||||||
電流としてIol48mAとなっています)。
|
|
||||||
|
RPIのGPIOはこのような大きなシンク電流は吸収できません。電気的に安全な接続
|
||||||
RPIのGPIOはこのような大きなシンク電流は吸収できません。電気的に安全な接続
|
を行うためには汎用ロジックIC等で変換基板を作る必要があります。汎用ロジック
|
||||||
を行うためには汎用ロジックIC等で変換基板を作る必要があります。汎用ロジック
|
ICで48mAものシンク電流に耐えるのは74LS06とか07といったオープンコレクタで
|
||||||
ICで48mAものシンク電流に耐えるのは74LS06とか07といったオープンコレクタで
|
ハイパワータイプのものを使用します。
|
||||||
ハイパワータイプのものを使用します。
|
|
||||||
|
作者は74HC541×3,74HC126×1,74HC04×1で基本的なSCSIの方向制御を行い更に
|
||||||
作者は74HC541×3,74HC126×1,74HC04×1で基本的なSCSIの方向制御を行い更に
|
74LS07×3を使ってバスをドライブする回路を組んでみたところ問題なく動作する
|
||||||
74LS07×3を使ってバスをドライブする回路を組んでみたところ問題なく動作する
|
ことを確認しました。
|
||||||
ことを確認しました。
|
|
||||||
|
他にも74LS641の派生版である74LS641-1を使用すると回路はシンプルに構成できる
|
||||||
他にも74LS641の派生版である74LS641-1を使用すると回路はシンプルに構成できる
|
でしょう。ノーマル品と違ってシンク電流が48mA対応なので74LS07を使用する必要
|
||||||
でしょう。ノーマル品と違ってシンク電流が48mA対応なので74LS07を使用する必要
|
はありません。しかし入手性はそれほど良くありません。
|
||||||
はありません。しかし入手性はそれほど良くありません。
|
|
||||||
|
□変換基板の回路図案
|
||||||
□変換基板の回路図案
|
同じフォルダに回路図案を入れています。
|
||||||
同じフォルダに回路図案を入れています。
|
|
||||||
|
・target.png
|
||||||
・target.png
|
SCSIのターゲットモードを使用するための変換基板回路図です。基本機能である
|
||||||
SCSIのターゲットモードを使用するための変換基板回路図です。基本機能である
|
HDDやMOのエミュレーションを行うのであればこの回路図相当の物を作れば良い
|
||||||
HDDやMOのエミュレーションを行うのであればこの回路図相当の物を作れば良い
|
でしょう。使用するGPIOピンも最も少ない構成になります。
|
||||||
でしょう。使用するGPIOピンも最も少ない構成になります。
|
|
||||||
|
ピンアサインを変更しなければRaSCSIのstandardディレクトリに含まれる
|
||||||
ピンアサインを変更しなければRaSCSIのstandardディレクトリに含まれる
|
バイナリを使用することが可能です。
|
||||||
バイナリを使用することが可能です。
|
|
||||||
|
・fullspec.png
|
||||||
・initiator.png
|
SCSIのターゲットモード、イニシエータモードを利用できる変換基板回路図です。
|
||||||
SCSIのターゲットモードに加えイニシエータモードを使用するための変換基板
|
全ての74LS641-1の方向制御をRaSCSIから行いますのでGPIOピンを三つ余分に使用
|
||||||
回路図です。基本機能に加えてRPIがイニシエータとなって物理HDDにコマンド
|
してしまいます。
|
||||||
を発行することが可能になります。モードの制御に追加で一つGPIOピンを消費
|
|
||||||
します。このイニシエータモードを使用したサンプルプログラムとしてrasdump
|
ピンアサインのカスタマイズで、PIN_TAD,PIN_IND,PIN_DTDにそれぞれ標準
|
||||||
を用意しました。実HDDやMOからイメージファイルにダンプすることができます。
|
では6,7,8を設定してコンパイルする必要があります。ピンアサインの
|
||||||
オプションでリストア機能も使用できます。
|
カスタマイズを参照してください。
|
||||||
|
|
||||||
ピンアサインのカスタマイズでPIN_INDに標準では7を設定してコンパイルする
|
□既存のものを手に入れる方法
|
||||||
必要があります。ピンアサインのカスタマイズを参照してください。
|
最近では主にTwitter界隈を通じてRaSCSI用の変換基板を作成していただいて
|
||||||
|
いる方々がいらっしゃいます。直ぐに見つかると思いますのでここでの紹介
|
||||||
・fullspec.png
|
は省略します。時期は未定ですが公式版の有償頒布を計画しています。
|
||||||
SCSIのターゲットモード、イニシエータモードに加えてSCSIの通信をモニター
|
|
||||||
することができる変換基板回路図です。SCSIプロトコロルを解析する等の特殊
|
□ピンアサインのカスタマイズ
|
||||||
要件がある場合はこの回路が最適です。全ての74LS641-1の方向制御をRaSCSI
|
GPIOの信号制御論理やピンアサインはgpiobus.hに定義があります。
|
||||||
から行いますのでGPIOピンを三つ余分に使用してしまいます。SCSIの開発に
|
|
||||||
興味があればこの回路を組んでみてはどうでしょうか。特徴としてGPIOピン
|
カスタマイズ例としてgpiobus.hに下記の二つの変換基板用定義例を用意しました。
|
||||||
を余分に使用する代わりに上のイニシエータモードが使用できる基板と比較
|
配布物の中にはコンパイル済みバイナリも含まれています。
|
||||||
して74LS86が必要にならないため基板がシンプルになるという恩恵があります。
|
|
||||||
|
・あいぼむ版
|
||||||
ピンアサインのカスタマイズで、PIN_TAD,PIN_IND,PIN_DTDにそれぞれ標準
|
・GAMERnium版
|
||||||
では6,7,8を設定してコンパイルする必要があります。ピンアサインの
|
|
||||||
カスタマイズを参照してください。
|
□カスタマイズ方法
|
||||||
|
・RaSCSI起動時のメッセージです。
|
||||||
□既存のものを手に入れる方法
|
CONNECT_DESC
|
||||||
最近では主にTwitter界隈を通じてRaSCSI用の変換基板を作成していただいて
|
|
||||||
いる方々がいらっしゃいます。
|
・信号制御モードを選択します。
|
||||||
|
SIGNAL_CONTROL_MODE
|
||||||
また秋葉原で委託販売されてます。
|
|
||||||
|
0:SCSI論理仕様
|
||||||
家電のKENCHAN 同人ハード(キット)のページ等です。
|
直結またはHPに公開した74LS641-1等を使用する変換基板
|
||||||
http://www.kadenken.com/shopbrand/ct76/"
|
アーサート:0V
|
||||||
|
ネゲート :オープンコレクタ出力(バスから切り離す)
|
||||||
現在のところ市販されているものとして
|
|
||||||
|
1:負論理仕様(負論理->SCSI論理への変換基板を使用する場合)
|
||||||
・BELさん開発のあいぼむ版
|
現時点でこの仕様による変換基板は存在しません
|
||||||
・tomcatさん開発のGAMERnium版
|
アーサート:0V -> (CONVERT) -> 0V
|
||||||
|
ネゲート :3.3V -> (CONVERT) -> オープンコレクタ出力
|
||||||
があります。
|
|
||||||
|
2:正論理仕様(正論理->SCSI論理への変換基板を使用する場合)
|
||||||
□ピンアサインのカスタマイズ
|
RaSCSI Adapter Rev.C @132sync等
|
||||||
GPIOの信号制御論理やピンアサインはgpiobus.hとrascsidrv.cに定義があります。
|
|
||||||
定義が分かれているのはrascsidrv.cだけGPLなので敢えて分離しています。
|
アーサート:3.3V -> (CONVERT) -> 0V
|
||||||
御察し下さい。
|
ネゲート :0V -> (CONVERT) -> オープンコレクタ出力
|
||||||
|
|
||||||
カスタマイズ例としてgpiobus.hとrascsidrv.cに下記の二つの変換基板用定義例を
|
・制御信号ピンアサイン
|
||||||
用意しました。配布物の中にはコンパイル済みバイナリも含まれています。
|
PIN_ACT:SCSIコマンドを処理中の状態を示す信号のピン番号。
|
||||||
|
PIN_ENB:起動から終了の間の有効信号を示す信号のピン番号。
|
||||||
・BELさん開発のあいぼむ版
|
PIN_TAD:ターゲット信号(BSY,IO,CD,MSG,REG)の入出力方向を示す信号のピン番号。
|
||||||
・tomcatさん開発のGAMERnium版
|
PIN_IND:イニシーエータ信号(SEL,ATN,RST,ACK)の入出力方向を示す信号のピン番号。
|
||||||
|
PIN_DTD:データ信号(DT0...DT7,DP)の入出力方向を示す信号のピン番号。
|
||||||
□カスタマイズ方法
|
|
||||||
・RaSCSI起動時のメッセージです。
|
・制御信号出力論理
|
||||||
CONNECT_DESC
|
0V:FALSE 3.3V:TRUEで指定します。
|
||||||
|
|
||||||
・信号制御モードを選択します。
|
ACT_ON:PIN_ACT信号の論理です。
|
||||||
SIGNAL_CONTROL_MODE
|
ENB_ON:PIN_ENB信号の論理です。
|
||||||
|
TAD_IN:PIN_TAD入力方向時の論理です。
|
||||||
0:SCSI論理仕様
|
IND_IN:PIN_ENB入力方向時の論理です。
|
||||||
直結またはHPに公開した74LS641-1等を使用する変換基板
|
DTD_IN:PIN_ENB入力方向時の論理です。
|
||||||
アーサート:0V
|
|
||||||
ネゲート :オープンコレクタ出力(バスから切り離す)
|
・SCSI信号ピンアサイン
|
||||||
|
PIN_DT0~PIN_SEL:それぞれSCSI信号のピン番号です。
|
||||||
1:負論理仕様(負論理->SCSI論理への変換基板を使用する場合)
|
|
||||||
現時点でこの仕様による変換基板は存在しません
|
□コンパイル方法
|
||||||
アーサート:0V -> (CONVERT) -> 0V
|
|
||||||
ネゲート :3.3V -> (CONVERT) -> オープンコレクタ出力
|
・実行ファイル(rascsi,rasctl)
|
||||||
|
gpiobus.hを修正
|
||||||
2:正論理仕様(正論理->SCSI論理への変換基板を使用する場合)
|
make clean
|
||||||
RaSCSI Adapter Rev.C @132sync等
|
make
|
||||||
|
|
||||||
アーサート:3.3V -> (CONVERT) -> 0V
|
[EOF]
|
||||||
ネゲート :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
BIN
doc/fullspec.png
Binary file not shown.
|
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 73 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 75 KiB |
650
doc/rascsi.txt
650
doc/rascsi.txt
@@ -1,315 +1,335 @@
|
|||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
SCSI Target Emulator RaSCSI (*^..^*)
|
SCSI Target Emulator RaSCSI (*^..^*)
|
||||||
version 1.34 for Raspberry Pi
|
for Raspberry Pi
|
||||||
|
|
||||||
Powered by XM6 TypeG Technology.
|
Powered by XM6 TypeG Technology.
|
||||||
Copyright (C) 2016-2018 GIMONS
|
Copyright (C) 2016-2020 GIMONS
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
□RaSCSIとは
|
□RaSCSIとは
|
||||||
RaSCSIはRaspberry Piで動作するSCSIデバイス(ハードディスク,MO,CD-ROM)を
|
RaSCSIはRaspberry Piで動作するSCSIデバイス(ハードディスク,MO,CD-ROM)を
|
||||||
仮想的に再現するエミュレータです。SCSIを採用したSHARPのX68000で使用する
|
仮想的に再現するエミュレータです。SCSIを採用したSHARPのX68000で使用する
|
||||||
ことを目的として開発しました。RaSCSIを導入したRaspberry PiをX68000のSCSI
|
ことを目的として開発しました。RaSCSIを導入したRaspberry PiをX68000のSCSI
|
||||||
コネクタに接続するだけで物理的なSCSIデバイスとして認識されます。
|
コネクタに接続するだけで物理的なSCSIデバイスとして認識されます。
|
||||||
|
|
||||||
X68000以外にもSCSIを採用したFM TOWNSやPC98等のレトロPCでも使用できるかも
|
X68000以外にもSCSIを採用したFM TOWNSやPC98等のレトロPCでも使用できるかも
|
||||||
しれません。作者はFM TOWNSとPC9821Ceで動作するところまでは確認しています。
|
しれません。作者はFM TOWNSとPC9821Ceで動作するところまでは確認しています。
|
||||||
|
|
||||||
RaSCSIはSCSIデバイスをエミュレートするソフトウェアに加えてRaspberry Piの
|
RaSCSIはSCSIデバイスをエミュレートするソフトウェアに加えてRaspberry Piの
|
||||||
GPIOコネクタをSCSIコネクタに変換する機構の総称を指します。
|
GPIOコネクタをSCSIコネクタに変換する機構の総称を指します。
|
||||||
|
|
||||||
□動作環境
|
□動作環境
|
||||||
(1)Raspberry Pi
|
(1)Raspberry Pi
|
||||||
Raspberry Pi 3 Model B を推奨します。
|
Raspberry Pi Zero
|
||||||
|
Raspberry Pi Zero W
|
||||||
Raspberry Pi 2 Model BやZeroでも動作すると考えられます。
|
Raspberry Pi Zero WH
|
||||||
ピンアサインを独自に変更しRaspberry Pi 1で動作させたという報告もあります。
|
Raspberry Pi 2 Model B
|
||||||
|
Raspberry Pi 3 Model B(推奨)
|
||||||
(2)OS
|
Raspberry Pi 3 Model A+
|
||||||
RASPBIAN STRETCHで開発およびテストしています。
|
Raspberry Pi 3 Model B+
|
||||||
sudo apt-get update及びsudo apt-get upgradeで最新にしています。
|
Raspberry Pi 4 Model B
|
||||||
このドキュメントを記述している時点で"Linux raspberrypi 4.14.34-v7+"です。
|
|
||||||
|
Zero/Zero W/Zero WHでは性能的に少し不安定かもしれません。
|
||||||
RaSCSIはSCSI信号をGPIOを利用して制御しているので可能な限り低レイテンシー
|
|
||||||
の状態で使用する必要があります。したがってCUIモードで利用することを推奨
|
3 Model A+/3 Model B+/4 Model Bは高性能ですが熱の影響でCPUクロックが
|
||||||
します。更に不要なサービスは極力停止して下さい。
|
変動することがありますので対策が必要でしょう。
|
||||||
|
|
||||||
□SCSIコネクタとの接続方法
|
(2)OS
|
||||||
状況が複雑になってきましたのでRaSCSIのホームページ上で情報提供しています。
|
RASPBIAN BUSTERで開発およびテストしています。
|
||||||
このドキュメントの最後にある公式ホームページを参考にして下さい。
|
RaSCSIはSCSI信号をGPIOを利用して制御しているので可能な限り低レイテンシー
|
||||||
|
の状態で使用する必要があります。したがってCUIモードで利用することを推奨
|
||||||
□配布物
|
します。
|
||||||
配布するアーカイブには実行ファイル、ドキュメント、ソースコードのそれぞれが
|
|
||||||
ディレクトリで分かれて含まれています。
|
□SCSIコネクタとの接続方法
|
||||||
|
状況が複雑になってきましたのでRaSCSIのホームページ上で情報提供しています。
|
||||||
bin/ ・・・ 実行ファイル
|
このドキュメントの最後にある公式ホームページを参考にして下さい。
|
||||||
raspberrypi/ ・・・ RPI用のプログラム
|
|
||||||
rascsi.tar.gz ・・・ 実行ファイルとカーネルモジュールをtar+gzipしたもの。
|
□配布物
|
||||||
|
配布するアーカイブには実行ファイル、ドキュメント、ソースコードのそれぞれが
|
||||||
x68k/ ・・・ X68000用のプログラム
|
ディレクトリで分かれて含まれています。
|
||||||
RASDRV.SYS ・・・ ホストドライブドライバ
|
|
||||||
RASETHER.SYS ・・・ イーサネットドライバ
|
bin/ ・・・ 実行ファイル
|
||||||
|
raspberrypi/ ・・・ RPI用のプログラム
|
||||||
doc/ ・・・ ドキュメント
|
rascsi.tar.gz ・・・ 実行ファイルをtar+gzipしたもの。
|
||||||
rascsi.txt ・・・ 当ドキュメント
|
|
||||||
x68k.txt ・・・ X68000固有機能の説明
|
x68k/ ・・・ X68000用の専用ドライバ
|
||||||
converter.txt ・・・ 変換基板の説明
|
RASDRIVER.XDF・・・ 二つのドライバを含むフロッピーイメージ
|
||||||
pinassign.png ・・・ ピンアサイン図
|
RASDRIVER.HDS・・・ 二つのドライバを含むSCSI HDイメージ
|
||||||
target.png ・・・ 変換基板回路図案(ターゲットモード)
|
RASDRIVER.HDF・・・ 二つのドライバを含むSASI HDイメージ
|
||||||
initiator.png ・・・ 変換基板回路図案(イニシエータサポート)
|
|
||||||
fullspec.png ・・・ 変換基板回路図案(フルスペック)
|
doc/ ・・・ ドキュメント
|
||||||
|
rascsi.txt ・・・ 当ドキュメント
|
||||||
src/ ・・・ ソースコード
|
x68k.txt ・・・ X68000固有機能の説明
|
||||||
raspberrypi/ ・・・ RPI用のプログラムソース一式
|
converter.txt ・・・ 変換基板の説明
|
||||||
x68k/ ・・・ X68000用のプログラム一式
|
pinassign.png ・・・ ピンアサイン図
|
||||||
|
target.png ・・・ 変換基板回路図案(ターゲットモード)
|
||||||
|
fullspec.png ・・・ 変換基板回路図案(フルスペック)
|
||||||
RPIで使用するプログラムはrascsi.tar.gzですのでRPI上に転送してから解凍して
|
|
||||||
下さい。パーミッション等を維持するためにRPI上で解凍することを推奨します。
|
src/ ・・・ ソースコード
|
||||||
|
raspberrypi/ ・・・ RPI用のプログラムソース一式
|
||||||
rascsi.tar.gzにはstandard,fullspec,aibom,gamerniumのディレクトリが含まれ
|
x68k/ ・・・ X68000用のプログラム一式
|
||||||
ています。通常はstandardディレクトリにある実行ファイルを使用して下さい。
|
|
||||||
|
|
||||||
aibom,gamerniumディレクトリのものは"あいぼむ版","GAMERnium版"の変換基板を
|
RPIで使用するプログラムはrascsi.tar.gzですのでRPI上に転送してから解凍して
|
||||||
使用する時のものです。
|
下さい。パーミッション等を維持するためにRPI上で解凍することを推奨します。
|
||||||
|
|
||||||
fullspecディレクトリのものは公開したフルスペック版変換基板の回路図案で
|
rascsi.tar.gzにはstandard,fullspec,aibom,gamerniumのディレクトリが含まれ
|
||||||
変換基板を作成した時に使用する時のものです。
|
ています。
|
||||||
|
|
||||||
□RASCI本体の使用方法(rascsi)
|
直結ケーブルや直結基板を使用する場合はstandardディレクトリの実行ファイル
|
||||||
|
を使用して下さい。
|
||||||
sudo rascsi [-ID{01234567} FILE] ...
|
|
||||||
|
同様にフルスペック版と説明された変換基板の場合はfullspecのディレクトリの
|
||||||
ルート権限が必要ですのでsudo等で起動する必要があります。
|
ものを使用します(直結でも動くと思います)。
|
||||||
オプションに-hを付けると簡単なHELPが表示されます
|
|
||||||
|
aibom,gamerniumディレクトリのものは"あいぼむ版","GAMERnium版"の変換基板を
|
||||||
Usage: ./rascsi [-ID{0|1|2|3|4|5|6|7} FILE] ...
|
使用する時のものです。
|
||||||
|
|
||||||
ID is SCSI identification number.
|
X68000用のドライバはRASDRIVER.XDFもしくはRASDRIVER.HDSの中に次の二つが含ま
|
||||||
FILE is disk image file.
|
れています。
|
||||||
|
RASDRV.SYS ・・・ ホストドライブドライバ
|
||||||
Detected images type based on file extension.
|
RASETHER.SYS ・・・ イーサネットドライバ
|
||||||
hdf : SASI HD image(XM6 SASI HD image)
|
|
||||||
hds : SCSI HD image(XM6 SCSI HD image)
|
□RASCI本体の使用方法(rascsi)
|
||||||
hdn : SCSI HD image(NEC GENUINE)
|
|
||||||
hdi : SCSI HD image(Anex86 HD image)
|
ID指定の場合
|
||||||
nhd : SCSI HD image(T98Next HD image)
|
rascsi [-IDn FILE] ...
|
||||||
hda : SCSI HD image(APPLE GENUINE)
|
n:0~7
|
||||||
mos : SCSI MO image(XM6 SCSI MO image)
|
|
||||||
iso : SCSI CD image(ISO 9660 image)
|
HD指定の場合(X68000 SASI機のHD指定互換)
|
||||||
|
rascsi [-HDn FILE] ...
|
||||||
引数では-ID{01234567}とFILEの一組で一つのSCSIデバイスを指定できます。
|
n:0~15
|
||||||
|
|
||||||
-IDの後ろの番号はSCSI IDです。SCSI IDは0-7を指定できますが通常レトロPC本体
|
ルート権限が必要ですのでsudo等で起動する必要があります。
|
||||||
がイニシエータとしてID7等を使用していると思います。その場合は0-6を指定する
|
オプションに-hを付けると簡単なHELPが表示されます
|
||||||
ことになります。
|
|
||||||
|
Usage: rascsi [-IDn FILE] ...
|
||||||
FILEは仮想ディスクイメージのファイルパスです。イメージファイル名には拡張子
|
|
||||||
が必要です。拡張子によってHD,MO,CDの種別を判定しています。
|
n is SCSI identification number(0-7).
|
||||||
|
FILE is disk image file.
|
||||||
例)SCSI ID0にHDIMAGE0.HDS,ID1にHDIMAGE1.HDSを指定して起動する場合、
|
|
||||||
sudo rascsi -ID0 HDIMAGE0.HDS -ID1 HDIMAGE1.HDS
|
Usage: rascsi [-HDn FILE] ...
|
||||||
|
|
||||||
終了する場合はCTRL+Cで停止します。
|
n is X68000 SASI HD number(0-15).
|
||||||
バックグラウンドで起動した場合にはkillコマンド該当プロセスにINTシグナルか
|
FILE is disk image file.
|
||||||
HUPシグナルを送ることで終了します。
|
|
||||||
|
Image type is detected based on file extension.
|
||||||
rascsiは起動後にソケット(6868ポート)を開いて外部からの管理コマンドを受け
|
hdf : SASI HD image(XM6 SASI HD image)
|
||||||
付ける状態になります。したがって既に別プロセスとしてrascsiが起動している
|
hds : SCSI HD image(XM6 SCSI HD image)
|
||||||
場合はエラーメッセージとともに起動を中断します。
|
hdn : SCSI HD image(NEC GENUINE)
|
||||||
|
hdi : SCSI HD image(Anex86 HD image)
|
||||||
□管理ツールの使用方法(rasctl)
|
nhd : SCSI HD image(T98Next HD image)
|
||||||
バージョン1.10からrasctlという管理ツールを提供します。これはrascsiプロセス
|
hda : SCSI HD image(APPLE GENUINE)
|
||||||
がバックグラウンドで起動(6868ポートで接続待ちの状態)している場合にディスク
|
mos : SCSI MO image(XM6 SCSI MO image)
|
||||||
操作のコマンドを発行することが可能となります。コマンドラインは下記の通り。
|
iso : SCSI CD image(ISO 9660 image)
|
||||||
|
|
||||||
rasctl -i ID [-c CMD] [-t TYPE] [-f FILE]
|
引数では-IDnもしくは-HDnとFILEの一組で一つのSCSI(SASI)デバイスを指定できます。
|
||||||
|
-IDの後ろの番号はSCSI(SASI) IDです。IDは0-7を指定できますが通常レトロPC本体
|
||||||
ID : SCSI ID
|
がイニシエータとしてID7等を使用していると思います。その場合は0-6を指定する
|
||||||
CMD : 操作コマンド
|
ことになります。
|
||||||
attach : ディスクを取り付ける
|
|
||||||
detatch : ディスクを取り外す
|
FILEは仮想ディスクイメージのファイルパスです。イメージファイル名には拡張子
|
||||||
insert : メディアを挿入する(MOまたはCDのみ)
|
が必要です。拡張子によってHD,MO,CDの種別を判定しています。
|
||||||
eject : メディアを取り出す(MOまたはCDのみ)
|
|
||||||
protect : メディアを書き込み禁止にする(MOのみ)
|
例)SCSI ID0にHDIMAGE0.HDS,ID1にHDIMAGE1.HDSを指定して起動する場合、
|
||||||
TYPE : ディスク種別
|
sudo rascsi -ID0 HDIMAGE0.HDS -ID1 HDIMAGE1.HDS
|
||||||
hd : ハードディスク(SASI/SCSI)
|
|
||||||
mo : MO(光磁気ディスク)
|
終了する場合はCTRL+Cで停止します。
|
||||||
cd : CDROM(CDROMドライブ)
|
バックグラウンドで起動した場合にはkillコマンド該当プロセスにINTシグナルか
|
||||||
bridge : ブリッジデバイス
|
HUPシグナルを送ることで終了します。
|
||||||
FILE : ディスクイメージファイルのパス
|
|
||||||
|
rascsiは起動後にソケット(6868ポート)を開いて外部からの管理コマンドを受け
|
||||||
IDは必須です。CMDは省略時はattachと解釈します。TYPEはコマンドがattachの
|
付ける状態になります。したがって既に別プロセスとしてrascsiが起動している
|
||||||
場合にはFILEの拡張子から自動判定します。FILEはTYPEを明示的に指定している
|
場合はエラーメッセージとともに起動を中断します。
|
||||||
場合は拡張子が異なっても構いません。基本的CMD,TYPEの解釈は大文字小文字を
|
|
||||||
無視します。現在のところ最初の1文字でのみ判定しています。
|
□管理ツールの使用方法(rasctl)
|
||||||
|
バージョン1.10からrasctlという管理ツールを提供します。これはrascsiプロセス
|
||||||
コマンド例
|
がバックグラウンドで起動(6868ポートで接続待ちの状態)している場合にディスク
|
||||||
rascsi -i 0 -f HDIMAGE0.HDS
|
操作のコマンドを発行することが可能となります。コマンドラインは下記の通り。
|
||||||
|
|
||||||
の場合はSCSI IDは0。CMDはデフォルトでattachでありTYPEは拡張子HDSから判断
|
rasctl -i ID [-u UNIT] [-c CMD] [-t TYPE] [-f FILE]
|
||||||
するのでhdと推測することになりrascsi起動時のオプション指定と同等です。
|
|
||||||
|
ID : SCSI ID(0~7)
|
||||||
現在の状態を確認するにために-lオプションのみを指定するとデバイス一覧が表示
|
UNIT : ユニット番号(0または1)
|
||||||
されます。コマンドラインは下記の通り。
|
CMD : 操作コマンド
|
||||||
|
attach : ディスクを取り付ける
|
||||||
rasctl -l
|
detach : ディスクを取り外す
|
||||||
|
insert : メディアを挿入する(MOまたはCDのみ)
|
||||||
rasctl自体の起動にはルート権限は必要ありません。
|
eject : メディアを取り出す(MOまたはCDのみ)
|
||||||
|
protect : メディアを書き込み禁止にする(MOのみ)
|
||||||
□ディスクダンプツールの使用方法(rasdump)
|
TYPE : ディスク種別
|
||||||
直結もしくは直結基板、またはイニシエータ対応とした変換基板向けのサンプル
|
hd : ハードディスク(SASI/SCSI)
|
||||||
プログラムです。現在のところ変換基板では"あいぼむ版"のみ対応してます。
|
mo : MO(光磁気ディスク)
|
||||||
|
cd : CDROM(CDROMドライブ)
|
||||||
名前の通りSCSI HDDやMOのイメージをダンプ(オプションでリストア)します。
|
bridge : ブリッジデバイス
|
||||||
自身のIDはBIDで指定して下さい。省略時は7を使用します。
|
FILE : ディスクイメージファイルのパス
|
||||||
|
|
||||||
rasdump -i ID [-b BID] -f FILE [-r]
|
IDは必須です。UNITは省略時は0です(SCSIの場合は0を基本とします)。
|
||||||
ID : ターゲットデバイスのSCSI ID
|
CMDは省略時はattachと解釈します。TYPEはコマンドがattachの場合にはFILEの拡張子
|
||||||
BID : RaSCSI自身のSCSI ID
|
から自動判定します。FILEはTYPEを明示的に指定している場合は拡張子が異なっても
|
||||||
FILE : ダンプファイル名
|
構いません。基本的CMD,TYPEの解釈は大文字小文字を無視します。最初の1文字でのみ
|
||||||
-r : リストアモード
|
判定しています。
|
||||||
|
|
||||||
サンプルなので必要最低限の処理しか実装していませんので改造するなりして
|
コマンド例
|
||||||
ご使用下さい。
|
rasctl -i 0 -f HDIMAGE0.HDS
|
||||||
|
|
||||||
□カーネルモジュールの導入方法(rascsidrv.ko)
|
の場合はSCSI IDは0。CMDはデフォルトでattachでありTYPEは拡張子HDSから判断
|
||||||
version 1.24から安定化のためにGPIO制御の一部をカーネルモジュールで動作
|
するのでhdと推測することになりrascsi起動時のオプション指定と同等です。
|
||||||
させる拡張を加えました。
|
|
||||||
|
現在の状態を確認するにために-lオプションのみを指定するとデバイス一覧が表示
|
||||||
カーネルモジュールを導入しなくても動作できますが、X68000シリーズのSASI
|
されます。コマンドラインは下記の通り。
|
||||||
を使用する場合や純正SCSIボードを増設した場合はカーネルモジュールの導入
|
|
||||||
を行っていないと動作が不安定になります。
|
rasctl -l
|
||||||
|
|
||||||
カーネルモジュールを有効にするには
|
rasctl自体の起動にはルート権限は必要ありません。
|
||||||
|
|
||||||
sudo insmod rascsidrv.ko
|
□ディスクダンプツールの使用方法(rasdump)
|
||||||
|
直結もしくは直結基板、またはフルスペック基板向けのサンプルプログラムです。
|
||||||
を実行してください。
|
|
||||||
|
名前の通りSCSI HDDやMOのイメージをダンプ(オプションでリストア)します。
|
||||||
カーネルモジュールの起動を確認するにはdmesgコマンドで出力されるログの
|
自身のIDはBIDで指定して下さい。省略時は7を使用します。
|
||||||
最後に次のような表示がされている筈です。
|
|
||||||
|
rasdump -i ID [-b BID] -f FILE [-r]
|
||||||
"RaSCSI GPIO Driver Loaded(STANDARD)"
|
ID : ターゲットデバイスのSCSI ID
|
||||||
|
BID : RaSCSI自身のSCSI ID
|
||||||
注意!
|
FILE : ダンプファイル名
|
||||||
カーネルモジュールは使用中のOSのバージョンに依存します。
|
-r : リストアモード
|
||||||
|
|
||||||
rascsiやrasctlと同じ階層にあるrascsidrv.koはRaspberry Pi 2/3用の
|
サンプルなので必要最低限の処理しか実装していませんので改造するなりして
|
||||||
"Linux raspberrypi 4.14.34-v7+"でコンパイルしたモジュールになります。
|
ご使用下さい。
|
||||||
|
|
||||||
同じ階層のrpi1orZero/rascsidrv.koはRaspberry Pi 1/Zero用です。
|
□SASI専用ディスクダンプツールの使用方法(sasidump)
|
||||||
"Linux raspberrypi 4.14.34+"でコンパイルしたモジュールになります。
|
rasdumpをベースにSASI専用に作成したダンプツールです。
|
||||||
|
SASI HDイメージをダンプ(オプションでリストア)します。
|
||||||
自身でカーネルモジュールをコンパイルする手順を簡単に記しておきます。
|
|
||||||
|
sasidump -i ID [-u UT] [-b BSIZE] -c COUNT -f FILE [-r]
|
||||||
・OSの最新化
|
ID : ターゲットデバイスのSASI ID
|
||||||
sudo apt-get update
|
UT : ターゲットデバイスのUNIT ID
|
||||||
sudo apt-get upgrade
|
BSIZE: ブロックサイズ(デフォルトは512)
|
||||||
sudo reboot
|
COUNT: ブロック数
|
||||||
|
FILE : ダンプファイル名
|
||||||
・カーネルヘッダー取得
|
-r : リストアモード
|
||||||
sudo apt-get install raspberrypi-kernel-headers
|
|
||||||
|
□ソースから実行ファイルをコンパイルする場合
|
||||||
・コンパイル
|
スタンダード版
|
||||||
cd kernelmodule
|
make CONNECT_TYPE=STANDARD
|
||||||
make
|
|
||||||
|
フルスペック版
|
||||||
□サポートするディスクイメージ
|
make CONNECT_TYPE=FULLSPEC
|
||||||
(1)SCSI ハードディスク
|
|
||||||
HDSファイル形式 (拡張子HDS/HDN/HDI/NHD/HDA)
|
あいぼむ版
|
||||||
ファイルサイズは10MB以上4095MB以下の範囲で任意のサイズ(但し512バイト単位)
|
make CONNECT_TYPE=AIBOM
|
||||||
|
|
||||||
拡張子が"HDN"の場合はNEC純正55ボード(PC-9801-55)向けの純正ハードディスク
|
GAMERnium版
|
||||||
エミュレーションを行います。INQUIRYで返却される情報やMODE SENSEのサイズに
|
make CONNECT_TYPE=GAMERNIUM
|
||||||
に違いがあります。
|
|
||||||
|
□サポートするディスクイメージ
|
||||||
拡張子が"HDI","NHD"の場合はそれぞれPC98エミュレータであるAnex86及びT98Next
|
(1)SCSI ハードディスク
|
||||||
のSCSIハードディスクイメージを使用するものです。HDNの時と同様に一部の情報
|
HDSファイル形式 (拡張子HDS/HDN/HDI/NHD/HDA)
|
||||||
がNEC用に変換されます。
|
ファイルサイズは10MB以上4095MB以下の範囲で任意のサイズ(但し512バイト単位)
|
||||||
|
|
||||||
拡張子が"HDA"の場合はAPPLE純正ハードディスクエミュレーションを行います。
|
拡張子が"HDN"の場合はNEC純正55ボード(PC-9801-55)向けの純正ハードディスク
|
||||||
INQUIRY及びMODE SENSEで返却される情報に違いがあります。
|
エミュレーションを行います。INQUIRYで返却される情報やMODE SENSEのサイズに
|
||||||
|
に違いがあります。
|
||||||
(2)SASI ハードディスク
|
|
||||||
HDFファイル形式 (拡張子HDF)
|
拡張子が"HDI","NHD"の場合はそれぞれPC98エミュレータであるAnex86及びT98Next
|
||||||
ファイルサイズは10441728バイト、20748288バイト、41496576バイトのいずれか
|
のSCSIハードディスクイメージを使用するものです。HDNの時と同様に一部の情報
|
||||||
(それぞれ10MBドライブ、20MBドライブ、40MBドライブに対応)
|
がNEC用に変換されます。
|
||||||
|
|
||||||
(3)SCSI 光磁気(MO)ディスク
|
拡張子が"HDA"の場合はAPPLE純正ハードディスクエミュレーションを行います。
|
||||||
MOSファイル形式 (拡張子MOS)
|
INQUIRY及びMODE SENSEで返却される情報に違いがあります。
|
||||||
ファイルサイズは次の4種類のいずれか:
|
|
||||||
128MBタイプ (127398912バイト)
|
(2)SASI ハードディスク
|
||||||
230MBタイプ (228518400バイト)
|
HDFファイル形式 (拡張子HDF)
|
||||||
540MBタイプ (533248000バイト)
|
ファイルサイズは10441728バイト、20748288バイト、41496576バイトのいずれか
|
||||||
640MBタイプ (635600896バイト)
|
(それぞれ10MBドライブ、20MBドライブ、40MBドライブに対応)を推奨します。
|
||||||
128MB,230MB,540MBは512バイト/セクタ、640MBは2048バイト/セクタになります。
|
256バイト単位であれば10M~512Mの任意のファイルサイズがマウント可能です。
|
||||||
|
|
||||||
(4)SCSI CD-ROMディスク
|
Version1.46から22437888バイトのイメージはMZ-2500/MZ-2800 MZ-1F23専用の
|
||||||
ISOファイル形式 (拡張子ISO、ISO9660ベタイメージ)
|
20MBイメージとして認識します(ブロックサイズが1024という特殊イメージ)。
|
||||||
モード1(2048バイト/セクタ)で、データのみ格納されたファイルとRAW形式で記録
|
|
||||||
されたファイルの両方に対応しています。
|
(3)SCSI 光磁気(MO)ディスク
|
||||||
|
MOSファイル形式 (拡張子MOS)
|
||||||
□ディスクイメージの作成
|
ファイルサイズは次の4種類のいずれか:
|
||||||
RaSCSI自体がX68000エミュレータであるXM6 TypeGの派生物です。従ってディスク
|
128MBタイプ (127398912バイト)
|
||||||
イメージの作成はXM6 TypeGの「ツール」メニューから行うことを前提としています。
|
230MBタイプ (228518400バイト)
|
||||||
もちろん先に説明した仕様に従えばdd等で空のイメージファイルを作成することも
|
540MBタイプ (533248000バイト)
|
||||||
可能です。
|
640MBタイプ (635600896バイト)
|
||||||
|
128MB,230MB,540MBは512バイト/セクタ、640MBは2048バイト/セクタになります。
|
||||||
例)100MBのHDSイメージ(空ファイル)を作る場合
|
|
||||||
|
(4)SCSI CD-ROMディスク
|
||||||
dd if=/dev/zero of=HARDDISK.HDS bs=512 count=204800
|
ISOファイル形式 (拡張子ISO、ISO9660ベタイメージ)
|
||||||
|
モード1(2048バイト/セクタ)で、データのみ格納されたファイルとRAW形式で記録
|
||||||
□動作実績
|
されたファイルの両方に対応しています。
|
||||||
作者の開発環境であるX68000 PRO(内蔵SASI/純正SCSIボード)、X68030 内蔵SCSI、
|
|
||||||
XVI Compact 内蔵SCSIで動作確認しています。Mach-2でも動作しました。
|
□ディスクイメージの作成
|
||||||
|
RaSCSI自体がX68000エミュレータであるXM6 TypeGの派生物です。従ってディスク
|
||||||
他にも初代X68000,ACE,EXPERT,XVI,PRO2,SUPER等で動作報告がありましたので、
|
イメージの作成はXM6 TypeGの「ツール」メニューから行うことを前提としています。
|
||||||
X68000シリーズはほぼ問題ないでしょう。
|
もちろん先に説明した仕様に従えばdd等で空のイメージファイルを作成することも
|
||||||
|
可能です。
|
||||||
その他のレトロPCではFM TOWNSシリーズ、PC98シリーズ、Apple Macintosh、
|
|
||||||
MSX(MEGA-SCSI利用)で動作報告があります。
|
例)100MBのHDSイメージ(空ファイル)を作る場合
|
||||||
|
|
||||||
その他の機種でもちらほらと動作報告を頂いています。
|
dd if=/dev/zero of=HARDDISK.HDS bs=512 count=204800
|
||||||
|
|
||||||
□活用方法
|
□動作実績
|
||||||
XM6等のX68000エミュレータを使用している場合はエミュレータで環境構築したHDD
|
作者の開発環境であるX68000 PRO(内蔵SASI/純正SCSIボード)、X68030 内蔵SCSI、
|
||||||
イメージをFTP等でRaspberry Piに転送することでX68000の実機に接続できます。
|
XVI Compact 内蔵SCSIで動作確認しています。Mach-2でも動作しました。
|
||||||
またその逆も然りで実機上に存在するファイルを格納したHDDイメージをPCにFTP等
|
|
||||||
で転送することでエミュレータで活用することができます。
|
他にも初代X68000,ACE,EXPERT,XVI,PRO2,SUPER等で動作報告がありましたので、
|
||||||
|
X68000シリーズはほぼ問題ないでしょう。
|
||||||
□ライセンス
|
|
||||||
RaSCSIはカーネルドライバを除きあるがまま"AS IS"で配布されるソフトウェアです。
|
その他のレトロPCではFM TOWNSシリーズ、Apple Macintosh、MSX(MEGA-SCSI利用)
|
||||||
カーネルドライバのソースrascsidrv.cのみGPLです(御察っし下さい)。
|
で動作報告があります。PC98シリーズは動作したという報告も多数ありますが、
|
||||||
|
SCSIボードによっては全く動作しないという報告もあります。
|
||||||
つまり使用者が受けたあらゆる損害に対して一切責任を持ちません。またソフト
|
|
||||||
ウェアに不備もしくは不具合があったとしてもそれを修正する責任もありません。
|
□活用方法
|
||||||
|
XM6等のX68000エミュレータを使用している場合はエミュレータで環境構築したHDD
|
||||||
RaSCSIを利用することでRaspberry PiやレトロPCが故障するリスクがあります。
|
イメージをFTP等でRaspberry Piに転送することでX68000の実機に接続できます。
|
||||||
あくまで自己責任でチャレンジしてください。
|
またその逆も然りで実機上に存在するファイルを格納したHDDイメージをPCにFTP等
|
||||||
|
で転送することでエミュレータで活用することができます。
|
||||||
XM6 TypeG同様に実験成果公開という性質上私のHP以外での配布を認めておりません。
|
|
||||||
|
□ライセンス
|
||||||
XM6のライセンス条項を継承していますので雑誌/書籍での紹介事前の許諾が必要です。
|
RaSCSIはあるがまま"AS IS"で配布されるソフトウェアです。
|
||||||
そもそも2017年にもなってSCSIに反応するのは限られた人だけだと思います。
|
|
||||||
|
つまり使用者が受けたあらゆる損害に対して一切責任を持ちません。またソフト
|
||||||
□変換基板の頒布について
|
ウェアに不備もしくは不具合があったとしてもそれを修正する責任もありません。
|
||||||
変換基板の頒布については作者に許諾を得る必要はありません。
|
|
||||||
一応ご連絡いただければ何かとサポートできるかもしれません。
|
RaSCSIを利用することでRaspberry PiやレトロPCが故障するリスクがあります。
|
||||||
|
あくまで自己責任でチャレンジしてください。
|
||||||
但しレトロPCのSCSI環境改善を応援するという趣旨から、
|
|
||||||
有料の場合は
|
XM6 TypeG同様に実験成果公開という性質上私のHP以外での配布を認めておりません。
|
||||||
|
|
||||||
基板製作費 + パーツ費用 + 運送費 +(社会通念上一般的な)手数料
|
XM6のライセンス条項を継承していますので雑誌/書籍での紹介事前の許諾が必要です。
|
||||||
|
そもそも2019年にもなってSCSIに反応するのは限られた人だけだと思います。
|
||||||
を大きく越えるような頒布についてはお止め下さい。
|
|
||||||
|
□変換基板の頒布について
|
||||||
□公開ホームページ
|
変換基板を有償で頒布する場合は下記の条件に従う限り作者に許諾を得る必要は
|
||||||
http://www.geocities.jp/kugimoto0715/rascsi/index.html
|
ありません。重要なことは基板を購入したユーザーに十分な情報を提供することと
|
||||||
|
心得て下さい。
|
||||||
□連絡先
|
|
||||||
twitter https://twitter.com/kugimoto0715
|
1.頒布価格
|
||||||
e-mail kugimoto0715@yahoo.co.jp
|
基板製作費 + パーツ費用 + 運送費 +(社会通念上一般的な)手数料。
|
||||||
|
|
||||||
[EOF]
|
2.回路図
|
||||||
|
購入者に回路図を提供して下さい。基板頒布と同時もしくは別途ホームページから
|
||||||
|
のダウンロード等手段は自由です。
|
||||||
|
|
||||||
|
3.動作検証
|
||||||
|
X68000実機環境の動作検証は必須とします。実機が手に入らない場合はX68000
|
||||||
|
ユーザーの方に検証の協力をお願いしてもよいでしょう。動作検証は起動確認以外
|
||||||
|
に書き込みや負荷テストをお願いします。検証結果は使用した環境やと共に公開
|
||||||
|
して下さい。
|
||||||
|
|
||||||
|
□変換基板(公式版)について
|
||||||
|
BOOTHで2019年3月以降配布しています(数に限りがありますので不定期です)。
|
||||||
|
|
||||||
|
□公開ホームページ
|
||||||
|
http://retropc.net/gimons/rascsi/
|
||||||
|
|
||||||
|
□連絡先
|
||||||
|
twitter https://twitter.com/kugimoto0715
|
||||||
|
e-mail gimons.developer.works@gmail.com
|
||||||
|
|
||||||
|
[EOF]
|
||||||
|
|||||||
BIN
doc/target.png
BIN
doc/target.png
Binary file not shown.
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
223
doc/x68k.txt
223
doc/x68k.txt
@@ -1,109 +1,114 @@
|
|||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
SCSI Target Emulator RaSCSI (*^..^*)
|
SCSI Target Emulator RaSCSII (*^..^*)
|
||||||
version 1.33 for Raspberry Pi
|
for Raspberry Pi
|
||||||
|
|
||||||
Powered by XM6 TypeG Technology.
|
Powered by XM6 TypeG Technology.
|
||||||
Copyright (C) 2016-2018 GIMONS
|
Copyright (C) 2016-2020 GIMONS
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
□X68000固有の機能について
|
□X68000固有の機能について
|
||||||
RaSCSIにはブリッジデバイスという仮想的なSCSIデバイスが実装されておりX68000と
|
RaSCSIにはブリッジデバイスという仮想的なSCSIデバイスが実装されておりX68000と
|
||||||
ホストであるRaspberry Piの橋渡しを行うことができます。このブリッジデバイスと
|
ホストであるRaspberry Piの橋渡しを行うことができます。このブリッジデバイスと
|
||||||
X68000用の専用ドライバを使用して下記の機能を提供します。
|
X68000用の専用ドライバを使用して下記の機能を提供します。
|
||||||
|
|
||||||
・イーサーネット
|
・イーサーネット
|
||||||
Neptune-Xと同様のイーサーネット機能を提供します。SCSI接続のイーサーネット
|
Neptune-Xと同様のイーサーネット機能を提供します。SCSI接続のイーサーネット
|
||||||
BOXのようにRaSCSIが振舞います。Raspberry PiのTAPデバイスにパケットを中継
|
BOXのようにRaSCSIが振舞います。Raspberry PiのTAPデバイスにパケットを中継
|
||||||
することで実現しています。Ether+と似たものです。
|
することで実現しています。Ether+と似たものです。
|
||||||
|
|
||||||
・ホストファイルシステム
|
・ホストファイルシステム
|
||||||
X68000のエミュレーターでは標準的な機能であるWindrv相当の機能を提供します。
|
X68000のエミュレーターでは標準的な機能であるWindrv相当の機能を提供します。
|
||||||
Raspberry Pi上のファイルシステムをリモートドライブとしてマウントすること
|
Raspberry Pi上のファイルシステムをリモートドライブとしてマウントすること
|
||||||
ができます。
|
ができます。
|
||||||
|
|
||||||
□ブジッジデバイスの起動方法
|
□ブジッジデバイスの起動方法
|
||||||
RaSCSI起動時にファイル名として"BRIDGE"というキーワードを設定するとそのIDに
|
RaSCSI起動時にファイル名として"BRIDGE"というキーワードを設定するとそのIDに
|
||||||
対してブジッリデバイスを生成します。
|
対してブジッリデバイスを生成します。
|
||||||
|
|
||||||
ex)
|
ex)
|
||||||
sudo rascsi -ID0 HDIMAGE0.HDS -ID6 BRIDGE
|
sudo rascsi -ID0 HDIMAGE0.HDS -ID6 BRIDGE
|
||||||
|
|
||||||
□イーサーネット接続
|
□専用ドライバ
|
||||||
配布物に含まれるRASETHER.SYSを使用します。このデバイスドライバがブリッジ
|
配布物に含まれるRASDRIVER.XDFもしくはRASDRIVER.HDSに二つのドライバが含まれ
|
||||||
デバイスと連携してイーサーネットのパケット送受信を行うことができます。
|
ています。RaSCSIでRASDRIVER.HDSをマウントし適宜コピーした方が実機への転送が
|
||||||
|
簡単でしょう。
|
||||||
以下、Raspberry Piの仮想アダプタ(TAP)のIPアドレスを「192.168.68.1」として、
|
|
||||||
X68000側を「192.168.68.3」とするケースで説明します。
|
□イーサーネット接続
|
||||||
|
イーサネットドライバ(RASETHER.SYS)がブリッジデバイスと連携してイーサーネット
|
||||||
・X68000の設定
|
のパケット送受信を行うことができます。
|
||||||
RASETHER.SYSはNeptune-X用ドライバを改造して作ったものですので使用方法は
|
|
||||||
全く同じです。X68000をネット接続するためには他に環境設定を行う必要があり
|
以下、Raspberry Piの仮想アダプタ(TAP)のIPアドレスを「192.168.68.1」として、
|
||||||
ます。設定方法は自力で調べていただくようお願いします。
|
X68000側を「192.168.68.3」とするケースで説明します。
|
||||||
|
|
||||||
以下実際に使用しているCONFIG.SYSとAUTOEXEC.BATの抜粋です。
|
・X68000の設定
|
||||||
|
RASETHER.SYSはNeptune-X用ドライバを改造して作ったものですので使用方法は
|
||||||
[CONFIG.SYS抜粋]
|
全く同じです。X68000をネット接続するためには他に環境設定を行う必要があり
|
||||||
PROCESS = 3 10 10
|
ます。設定方法は自力で調べていただくようお願いします。
|
||||||
DEVICE = \NETWORK\RASETHER.SYS
|
|
||||||
|
以下実際に使用しているCONFIG.SYSとAUTOEXEC.BATの抜粋です。
|
||||||
[AUTOEXEC.BAT抜粋]
|
|
||||||
SET SYSROOT=A:/NETWORK/
|
[CONFIG.SYS抜粋]
|
||||||
SET temp=A:\
|
PROCESS = 3 10 10
|
||||||
SET tmp=A:\
|
DEVICE = \NETWORK\RASETHER.SYS
|
||||||
SET HOME=A:/NETWORK/ETC/
|
|
||||||
SET HOST=X68000
|
[AUTOEXEC.BAT抜粋]
|
||||||
XIP.X
|
SET SYSROOT=A:/NETWORK/
|
||||||
IFCONFIG.X lp0 up
|
SET temp=A:\
|
||||||
IFCONFIG.X en0 192.168.68.3 netmask 255.255.255.0 up
|
SET tmp=A:\
|
||||||
INETDCONF.X +router 192.168.68.1 -rip
|
SET HOME=A:/NETWORK/ETC/
|
||||||
INETDCONF.X
|
SET HOST=X68000
|
||||||
|
XIP.X
|
||||||
・Raspberry Piの設定
|
IFCONFIG.X lp0 up
|
||||||
TAPデバイスというものを利用していますのでTAPを有効にしてください。恐らく
|
IFCONFIG.X en0 192.168.68.3 netmask 255.255.255.0 up
|
||||||
最近のJessieであれば最初から有効なはずです。確認方法は/dev/net/tunという
|
INETDCONF.X +router 192.168.68.1 -rip
|
||||||
ファイルが存在すれば有効となっていると判断できます。
|
INETDCONF.X
|
||||||
|
|
||||||
仮想アダプタの作成方法は次の様に行います。
|
・Raspberry Piの設定
|
||||||
|
TAPデバイスというものを利用していますのでTAPを有効にしてください。恐らく
|
||||||
[/etc/rc.local等から設定]
|
最近のJessieであれば最初から有効なはずです。確認方法は/dev/net/tunという
|
||||||
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
|
|
||||||
|
[/etc/rc.local等から設定]
|
||||||
上記によってRaspberry Pi(192.168.68.1)とX68000(192.168.68.3)の間で通信が
|
ip tuntap add ras0 mode tap user root
|
||||||
可能になります。
|
ip link set ras0 up
|
||||||
|
ifconfig ras0 inet 192.168.68.1/8 up
|
||||||
インターネット等と接続する場合はRaspberry Pi側でブリッジやルーティングの
|
route add -net 192.168.68.0 netmask 255.255.255.0 dev ras0
|
||||||
設定が必要になります。ご自身の環境に合わせて設定してください。無線LANの
|
|
||||||
場合にブリッジ構成するには色々と課題があるようなのでフォワーディングと
|
上記によってRaspberry Pi(192.168.68.1)とX68000(192.168.68.3)の間で通信が
|
||||||
NAT構成等もお勧めです。作者はrc.localで次のような設定で使用しています。
|
可能になります。
|
||||||
|
|
||||||
echo 1 > /proc/sys/net/ipv4/ip_forward
|
インターネット等と接続する場合はRaspberry Pi側でブリッジやルーティングの
|
||||||
iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
|
設定が必要になります。ご自身の環境に合わせて設定してください。無線LANの
|
||||||
|
場合にブリッジ構成するには色々と課題があるようなのでフォワーディングと
|
||||||
□ホストファイルシステム連携
|
NAT構成等もお勧めです。作者はrc.localで次のような設定で使用しています。
|
||||||
X68000エミュレータでよく利用されるWindrvやWindrvXMと同等の機能を提供します。
|
|
||||||
専用のRASDRV.SYSというデバイスドライバを組み込めばRaspberri Piのファイル
|
echo 1 > /proc/sys/net/ipv4/ip_forward
|
||||||
システムがX68000側のドライブに見えて操作できるということです。
|
iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
|
||||||
|
|
||||||
デバイスドライバの登録は簡単です。
|
□ホストファイルシステム連携
|
||||||
例えば
|
X68000エミュレータでよく利用されるWindrvやWindrvXMと同等の機能を提供します。
|
||||||
|
専用のRASDRV.SYSというデバイスドライバを組み込めばRaspberri Piのファイル
|
||||||
DEVICE = \SYS\RASDRV.SYS
|
システムがX68000側のドライブに見えて操作できるということです。
|
||||||
|
|
||||||
この場合はデフォルトでRaspberry Piのルートディレクトリをマウントします。
|
デバイスドライバの登録は簡単です。
|
||||||
デバイスドライバ起動時にどのドライブにマウントされたか表示されます。
|
例えば
|
||||||
ルートを以外をマウントする場合はディレクトリを指定して下さい。/home/pi等を
|
|
||||||
マウントするには
|
DEVICE = \SYS\RASDRV.SYS
|
||||||
|
|
||||||
DEVICE = \SYS\RASDRV.SYS /home/pi
|
この場合はデフォルトでRaspberry Piのルートディレクトリをマウントします。
|
||||||
|
デバイスドライバ起動時にどのドライブにマウントされたか表示されます。
|
||||||
と指定します。複数のディレクトリを指定すれば別々のドライブとしてマウントする
|
ルートを以外をマウントする場合はディレクトリを指定して下さい。/home/pi等を
|
||||||
ことが可能です。
|
マウントするには
|
||||||
|
|
||||||
SUSIEをご利用の方はSUSIEより先にRASDRV.SYSを組み込んで下さい。後に組み込むと
|
DEVICE = \SYS\RASDRV.SYS /home/pi
|
||||||
正しく認識できなくなると報告があります。
|
|
||||||
|
と指定します。複数のディレクトリを指定すれば別々のドライブとしてマウントする
|
||||||
[EOF]
|
ことが可能です。
|
||||||
|
|
||||||
|
SUSIEをご利用の方はSUSIEより先にRASDRV.SYSを組み込んで下さい。後に組み込むと
|
||||||
|
正しく認識できなくなると報告があります。
|
||||||
|
|
||||||
|
[EOF]
|
||||||
|
|||||||
@@ -1,13 +1,19 @@
|
|||||||
CC = gcc
|
CC = gcc
|
||||||
CFLAGS = -DNDEBUG -O3
|
CFLAGS = -DNDEBUG -O3 -Wall
|
||||||
CXX = g++
|
CXX = g++
|
||||||
CXXFLAGS = -DNDEBUG -O3
|
CXXFLAGS = -DNDEBUG -O3 -Wall
|
||||||
|
|
||||||
|
ifdef CONNECT_TYPE
|
||||||
|
CFLAGS += -DCONNECT_TYPE_$(CONNECT_TYPE)
|
||||||
|
CXXFLAGS += -DCONNECT_TYPE_$(CONNECT_TYPE)
|
||||||
|
endif
|
||||||
|
|
||||||
RASCSI = rascsi
|
RASCSI = rascsi
|
||||||
RASCTL = rasctl
|
RASCTL = rasctl
|
||||||
RASDUMP = rasdump
|
RASDUMP = rasdump
|
||||||
|
SASIDUMP = sasidump
|
||||||
|
|
||||||
BIN_ALL = $(RASCSI) $(RASCTL) $(RASDUMP)
|
BIN_ALL = $(RASCSI) $(RASCTL) $(RASDUMP) $(SASIDUMP)
|
||||||
|
|
||||||
SRC_RASCSI = \
|
SRC_RASCSI = \
|
||||||
rascsi.cpp \
|
rascsi.cpp \
|
||||||
@@ -29,23 +35,35 @@ SRC_RASDUMP = \
|
|||||||
filepath.cpp \
|
filepath.cpp \
|
||||||
fileio.cpp
|
fileio.cpp
|
||||||
|
|
||||||
OBJ_RASCSI := $(SRC_RASCSI:.cpp=.o)
|
SRC_SASIDUMP = \
|
||||||
OBJ_RASCTL := $(SRC_RASCTL:.c=.o)
|
sasidump.cpp \
|
||||||
OBJ_RASDUMP := $(SRC_RASDUMP:.c=.o)
|
scsi.cpp \
|
||||||
|
gpiobus.cpp \
|
||||||
|
filepath.cpp \
|
||||||
|
fileio.cpp
|
||||||
|
|
||||||
.cpp.o:
|
OBJ_RASCSI := $(SRC_RASCSI:%.cpp=%.o)
|
||||||
$(CXX) $(CXXFLAGS) -c $<
|
OBJ_RASCTL := $(SRC_RASCTL:%.cpp=%.o)
|
||||||
|
OBJ_RASDUMP := $(SRC_RASDUMP:%.cpp=%.o)
|
||||||
|
OBJ_SASIDUMP := $(SRC_SASIDUMP:%.cpp=%.o)
|
||||||
|
OBJ_ALL := $(OBJ_RASCSI) $(OBJ_RASCTL) $(OBJ_RASDUMP) $(OBJ_SASIDUMP)
|
||||||
|
|
||||||
|
%.o: %.cpp
|
||||||
|
$(CXX) $(CXXFLAGS) -c $< -o $@
|
||||||
|
|
||||||
ALL: $(BIN_ALL)
|
ALL: $(BIN_ALL)
|
||||||
|
|
||||||
$(RASCSI): $(OBJ_RASCSI) $
|
$(RASCSI): $(OBJ_RASCSI)
|
||||||
$(CXX) -o $@ $(OBJ_RASCSI) -lpthread
|
$(CXX) -o $@ $(OBJ_RASCSI) -lpthread
|
||||||
|
|
||||||
$(RASCTL): $(OBJ_RASCTL) $
|
$(RASCTL): $(OBJ_RASCTL)
|
||||||
$(CXX) -o $@ $(OBJ_RASCTL)
|
$(CXX) -o $@ $(OBJ_RASCTL)
|
||||||
|
|
||||||
$(RASDUMP): $(OBJ_RASDUMP) $
|
$(RASDUMP): $(OBJ_RASDUMP)
|
||||||
$(CXX) -o $@ $(OBJ_RASDUMP)
|
$(CXX) -o $@ $(OBJ_RASDUMP)
|
||||||
|
|
||||||
|
$(SASIDUMP): $(OBJ_SASIDUMP)
|
||||||
|
$(CXX) -o $@ $(OBJ_SASIDUMP)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o $(BIN_ALL)
|
rm -f $(OBJ_ALL) $(BIN_ALL)
|
||||||
|
|||||||
@@ -4,9 +4,10 @@
|
|||||||
// for Raspberry Pi
|
// for Raspberry Pi
|
||||||
//
|
//
|
||||||
// Powered by XM6 TypeG Technology.
|
// Powered by XM6 TypeG Technology.
|
||||||
// Copyright (C) 2016-2018 GIMONS
|
// Copyright (C) 2016-2020 GIMONS
|
||||||
//
|
//
|
||||||
// Imported NetBSD support and some optimisation patch by Rin Okuyama.
|
// Imported NetBSD support and some optimisation patch by Rin Okuyama.
|
||||||
|
// Imported sava's bugfix patch(in RASDRV DOS edition).
|
||||||
//
|
//
|
||||||
// [ ホストファイルシステム ]
|
// [ ホストファイルシステム ]
|
||||||
//
|
//
|
||||||
@@ -18,6 +19,36 @@
|
|||||||
#include "filepath.h"
|
#include "filepath.h"
|
||||||
#include "cfilesystem.h"
|
#include "cfilesystem.h"
|
||||||
|
|
||||||
|
#ifdef BAREMETAL
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// FatFs用タイムスタンプ
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
#define FF_NORTC_HOUR 6
|
||||||
|
#define FF_NORTC_MINUTE 8
|
||||||
|
#define FF_NORTC_SECOND 0
|
||||||
|
|
||||||
|
static DWORD fattime = (
|
||||||
|
(DWORD)(FF_NORTC_YEAR - 1980) << 25 |
|
||||||
|
(DWORD)FF_NORTC_MON << 21 |
|
||||||
|
(DWORD)FF_NORTC_MDAY << 16 |
|
||||||
|
(DWORD)(FF_NORTC_HOUR << 11) |
|
||||||
|
(DWORD)(FF_NORTC_MINUTE << 5) |
|
||||||
|
(DWORD)(FF_NORTC_SECOND)
|
||||||
|
);
|
||||||
|
|
||||||
|
DWORD get_fattime(void)
|
||||||
|
{
|
||||||
|
return fattime;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_fattime(DWORD n)
|
||||||
|
{
|
||||||
|
fattime = n;
|
||||||
|
}
|
||||||
|
#endif // BAREMETAL
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// 漢字コード変換
|
// 漢字コード変換
|
||||||
@@ -25,6 +56,7 @@
|
|||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
#define IC_BUF_SIZE 1024
|
#define IC_BUF_SIZE 1024
|
||||||
static char convert_buf[IC_BUF_SIZE];
|
static char convert_buf[IC_BUF_SIZE];
|
||||||
|
#ifndef BAREMETAL
|
||||||
#ifndef __NetBSD__
|
#ifndef __NetBSD__
|
||||||
// POSIX.1準拠iconv(3)を使用
|
// POSIX.1準拠iconv(3)を使用
|
||||||
#define CONVERT(src, dest, inbuf, outbuf, outsize) \
|
#define CONVERT(src, dest, inbuf, outbuf, outsize) \
|
||||||
@@ -61,6 +93,18 @@ static void convert(char const *src, char const *dest,
|
|||||||
iconv_close(cd);
|
iconv_close(cd);
|
||||||
*outbuf = '\0';
|
*outbuf = '\0';
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
// Newlibの中にiconvが含まれてなかったので無変換
|
||||||
|
// ベアメタルのFatFS上はSJISでもOKだと思うよ
|
||||||
|
#define CONVERT(src, dest, inbuf, outbuf, outsize) \
|
||||||
|
convert(src, dest, (char *)inbuf, outbuf, outsize)
|
||||||
|
static void convert(char const *src, char const *dest,
|
||||||
|
char *inbuf, char *outbuf, size_t outsize)
|
||||||
|
{
|
||||||
|
strcpy(outbuf, inbuf);
|
||||||
|
strcpy(convert_buf, inbuf);
|
||||||
|
}
|
||||||
|
#endif // BAREMETAL
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
@@ -361,6 +405,56 @@ void CHostDrv::SetEnable(BOOL bEnable)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
/// メディア交換チェック
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
BOOL CHostDrv::CheckMedia()
|
||||||
|
{
|
||||||
|
ASSERT(this);
|
||||||
|
|
||||||
|
// 状態更新
|
||||||
|
Update();
|
||||||
|
if (m_bEnable == FALSE)
|
||||||
|
CleanCache();
|
||||||
|
|
||||||
|
return m_bEnable;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
/// メディア状態更新
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
void CHostDrv::Update()
|
||||||
|
{
|
||||||
|
ASSERT(this);
|
||||||
|
|
||||||
|
// メディア挿入とみなす
|
||||||
|
BOOL bEnable = TRUE;
|
||||||
|
|
||||||
|
// メディア状態反映
|
||||||
|
SetEnable(bEnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
/// イジェクト
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
void CHostDrv::Eject()
|
||||||
|
{
|
||||||
|
ASSERT(this);
|
||||||
|
|
||||||
|
// メディア排出
|
||||||
|
CleanCache();
|
||||||
|
SetEnable(FALSE);
|
||||||
|
|
||||||
|
// 状態更新
|
||||||
|
Update();
|
||||||
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
/// ボリュームラベルの取得
|
/// ボリュームラベルの取得
|
||||||
@@ -374,7 +468,12 @@ void CHostDrv::GetVolume(TCHAR* szLabel)
|
|||||||
|
|
||||||
// ボリュームラベルの取得
|
// ボリュームラベルの取得
|
||||||
#ifdef RASCSI
|
#ifdef RASCSI
|
||||||
strcpy(m_szVolumeCache, m_szBase);
|
strcpy(m_szVolumeCache, "RASDRV ");
|
||||||
|
if (m_szBase[0]) {
|
||||||
|
strcat(m_szVolumeCache, m_szBase);
|
||||||
|
} else {
|
||||||
|
strcat(m_szVolumeCache, "/");
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
m_szVolumeCache[0] = _T('\0');
|
m_szVolumeCache[0] = _T('\0');
|
||||||
#endif
|
#endif
|
||||||
@@ -578,15 +677,17 @@ CHostPath* CHostDrv::CopyCache(CHostFiles* pFiles)
|
|||||||
|
|
||||||
// キャッシュ検索
|
// キャッシュ検索
|
||||||
CHostPath* pPath = FindCache(pFiles->GetHumanPath());
|
CHostPath* pPath = FindCache(pFiles->GetHumanPath());
|
||||||
if (pPath == NULL)
|
if (pPath == NULL) {
|
||||||
return NULL; // エラー: キャッシュなし
|
return NULL; // エラー: キャッシュなし
|
||||||
|
}
|
||||||
|
|
||||||
// リング先頭へ移動
|
// リング先頭へ移動
|
||||||
pPath->Insert(&m_cRing);
|
pPath->Insert(&m_cRing);
|
||||||
|
|
||||||
// キャッシュ更新チェック
|
// キャッシュ更新チェック
|
||||||
if (pPath->isRefresh())
|
if (pPath->isRefresh()) {
|
||||||
return NULL; // エラー: キャッシュ更新が必要
|
return NULL; // エラー: キャッシュ更新が必要
|
||||||
|
}
|
||||||
|
|
||||||
// ホスト側のパス名を保存
|
// ホスト側のパス名を保存
|
||||||
pFiles->SetResult(pPath->GetHost());
|
pFiles->SetResult(pPath->GetHost());
|
||||||
@@ -676,6 +777,9 @@ CHostPath* CHostDrv::MakeCache(CHostFiles* pFiles)
|
|||||||
|
|
||||||
// キャッシュ更新チェック
|
// キャッシュ更新チェック
|
||||||
if (pPath->isRefresh()) {
|
if (pPath->isRefresh()) {
|
||||||
|
// 更新
|
||||||
|
Update();
|
||||||
|
|
||||||
// 状態更新
|
// 状態更新
|
||||||
pPath->Refresh();
|
pPath->Refresh();
|
||||||
}
|
}
|
||||||
@@ -1320,6 +1424,13 @@ int CHostPath::Compare(const BYTE* pFirst, const BYTE* pLast, const BYTE* pBufFi
|
|||||||
if ('A' <= d && d <= 'Z')
|
if ('A' <= d && d <= 'Z')
|
||||||
d += 'a' - 'A'; // 小文字化
|
d += 'a' - 'A'; // 小文字化
|
||||||
}
|
}
|
||||||
|
// バックスラッシュをスラッシュに統一して比較する
|
||||||
|
if (c == '\\') {
|
||||||
|
c = '/';
|
||||||
|
}
|
||||||
|
if (d == '\\') {
|
||||||
|
d = '/';
|
||||||
|
}
|
||||||
} else { // cだけが1バイト目
|
} else { // cだけが1バイト目
|
||||||
if ((0x80 <= c && c <= 0x9F) || 0xE0 <= c) { // 厳密には 0x81~0x9F 0xE0~0xEF
|
if ((0x80 <= c && c <= 0x9F) || 0xE0 <= c) { // 厳密には 0x81~0x9F 0xE0~0xEF
|
||||||
bSkip0 = TRUE;
|
bSkip0 = TRUE;
|
||||||
@@ -1537,6 +1648,151 @@ BOOL CHostPath::isRefresh()
|
|||||||
return m_bRefresh;
|
return m_bRefresh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef BAREMETAL
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
/// scandirエミュレーション
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
struct dirent {
|
||||||
|
char d_name[_MAX_FNAME];
|
||||||
|
};
|
||||||
|
|
||||||
|
int scandir(const char *dirname,
|
||||||
|
dirent ***ret_namelist,
|
||||||
|
int(*select)(const dirent *),
|
||||||
|
int(*compar)(const dirent **, const dirent **))
|
||||||
|
{
|
||||||
|
FRESULT fr;
|
||||||
|
DIR dir;
|
||||||
|
FILINFO fno;
|
||||||
|
char dirpath[256];
|
||||||
|
int len;
|
||||||
|
dirent went;
|
||||||
|
int used;
|
||||||
|
int allocated;
|
||||||
|
dirent **namelist = NULL;
|
||||||
|
int i;
|
||||||
|
dirent *ent;
|
||||||
|
|
||||||
|
// NULLチェック
|
||||||
|
strcpy(dirpath, dirname);
|
||||||
|
if (dirpath[0] == '\0') {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// '/'はOKだがそれ以外で最後が'/'だとディレクトリと認識されない)
|
||||||
|
if (dirpath[0] != '/' || dirpath[1] != '\0') {
|
||||||
|
len = strlen(dirpath);
|
||||||
|
if (dirpath[len - 1] == '/') {
|
||||||
|
dirpath[len - 1] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ディレクトリオープン
|
||||||
|
fr = f_opendir(&dir, dirpath);
|
||||||
|
if (fr != FR_OK) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// リストを初期値で確保(とりあえず32)
|
||||||
|
used = 0;
|
||||||
|
allocated = 32;
|
||||||
|
namelist = (dirent **)malloc(allocated * sizeof(dirent *));
|
||||||
|
if (!namelist) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 配下のファイルまたはディレクトリを処理
|
||||||
|
i = 0;
|
||||||
|
while (TRUE) {
|
||||||
|
if (i == 0) {
|
||||||
|
// "."をFILINFOに見せかけて追加
|
||||||
|
strcpy(fno.fname, ".");
|
||||||
|
i++;
|
||||||
|
} else if (i == 1) {
|
||||||
|
// ".."をFILINFOに見せかけて追加
|
||||||
|
strcpy(fno.fname, "..");
|
||||||
|
i++;
|
||||||
|
} else if (f_readdir(&dir, &fno) != FR_OK) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// このケースがあるか不明
|
||||||
|
if (fno.fname[0] == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// direntに見せかける
|
||||||
|
strcpy(went.d_name, fno.fname);
|
||||||
|
|
||||||
|
// 対象外のフィルタ処理
|
||||||
|
if (select != NULL && !select(&went)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ファイル名の長さに調整したdirentの領域を確保
|
||||||
|
len = offsetof(dirent, d_name) + strlen(fno.fname) + 1;
|
||||||
|
if ((ent = (dirent *)malloc(len)) == NULL) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ワーク用direntから返却用にコピー
|
||||||
|
memcpy(ent, &went, len);
|
||||||
|
|
||||||
|
// 使用量が越えそうならリストを再確保
|
||||||
|
if (used >= allocated) {
|
||||||
|
allocated *= 2;
|
||||||
|
namelist = (dirent **)realloc(namelist, allocated * sizeof(dirent *));
|
||||||
|
if (!namelist) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// リストに追加
|
||||||
|
namelist[used++] = ent;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ディレクトリクローズ
|
||||||
|
f_closedir(&dir);
|
||||||
|
|
||||||
|
// ソート処理
|
||||||
|
if (compar) {
|
||||||
|
qsort(
|
||||||
|
namelist, used, sizeof(dirent *),
|
||||||
|
(int(*)(const void *, const void *)) compar);
|
||||||
|
}
|
||||||
|
|
||||||
|
// リストとエントリ数を返却
|
||||||
|
*ret_namelist = namelist;
|
||||||
|
return used;
|
||||||
|
|
||||||
|
error:
|
||||||
|
// ディレクトリクローズ
|
||||||
|
f_closedir(&dir);
|
||||||
|
|
||||||
|
// 途中まで確保したバッファをクローズ
|
||||||
|
if (namelist) {
|
||||||
|
while (used > 0) {
|
||||||
|
free(namelist[used - 1]);
|
||||||
|
used--;
|
||||||
|
}
|
||||||
|
free(namelist);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif // BAREMETAL
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
/// ASCIIソート関数
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
int AsciiSort(const dirent **a, const dirent **b)
|
||||||
|
{
|
||||||
|
return strcmp((*a)->d_name, (*b)->d_name);
|
||||||
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
/// ファイル再構成
|
/// ファイル再構成
|
||||||
@@ -1566,18 +1822,29 @@ void CHostPath::Refresh()
|
|||||||
// ファイル名登録
|
// ファイル名登録
|
||||||
/// @todo ファイル重複処理をホスト側APIを経由せずに全て自前で処理する。
|
/// @todo ファイル重複処理をホスト側APIを経由せずに全て自前で処理する。
|
||||||
BOOL bUpdate = FALSE;
|
BOOL bUpdate = FALSE;
|
||||||
DIR* pd = NULL;
|
struct dirent **pd = NULL;
|
||||||
for (DWORD i = 0; i < XM6_HOST_DIRENTRY_FILE_MAX; i++) {
|
int nument = 0;
|
||||||
|
int maxent = XM6_HOST_DIRENTRY_FILE_MAX;
|
||||||
|
for (int i = 0; i < maxent; i++) {
|
||||||
TCHAR szFilename[FILEPATH_MAX];
|
TCHAR szFilename[FILEPATH_MAX];
|
||||||
if (pd == NULL) {
|
if (pd == NULL) {
|
||||||
pd = opendir(S2U(szPath));
|
nument = scandir(S2U(szPath), &pd, NULL, AsciiSort);
|
||||||
if (pd == NULL)
|
if (nument == -1) {
|
||||||
|
pd = NULL;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
maxent = nument;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 最上位ディレクトリならカレントとパレントを対象外とする
|
||||||
|
struct dirent* pe = pd[i];
|
||||||
|
if (m_szHuman[0] == '/' && m_szHuman[1] == 0) {
|
||||||
|
if (strcmp(pe->d_name, ".") == 0 || strcmp(pe->d_name, "..") == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ファイル名を獲得
|
// ファイル名を獲得
|
||||||
struct dirent* pe = readdir(pd);
|
|
||||||
if (pe == NULL)
|
|
||||||
break;
|
|
||||||
strcpy(szFilename, U2S(pe->d_name));
|
strcpy(szFilename, U2S(pe->d_name));
|
||||||
|
|
||||||
// ファイル名領域確保
|
// ファイル名領域確保
|
||||||
@@ -1617,8 +1884,12 @@ void CHostPath::Refresh()
|
|||||||
// 一致するものがなければ、実ファイルが存在するか確認
|
// 一致するものがなければ、実ファイルが存在するか確認
|
||||||
strcpy(szPath, m_szHost);
|
strcpy(szPath, m_szHost);
|
||||||
strcat(szPath, (const char*)pFilename->GetHuman()); /// @warning Unicode時要修正 → 済
|
strcat(szPath, (const char*)pFilename->GetHuman()); /// @warning Unicode時要修正 → 済
|
||||||
|
#ifndef BAREMETAL
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
if (stat(S2U(szPath), &sb))
|
if (stat(S2U(szPath), &sb))
|
||||||
|
#else
|
||||||
|
if (f_stat(S2U(szPath), NULL) != FR_OK)
|
||||||
|
#endif // BAREMETAL
|
||||||
break; // 利用可能パターンを発見
|
break; // 利用可能パターンを発見
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1634,6 +1905,7 @@ void CHostPath::Refresh()
|
|||||||
strcpy(szPath, m_szHost);
|
strcpy(szPath, m_szHost);
|
||||||
strcat(szPath, U2S(pe->d_name));
|
strcat(szPath, U2S(pe->d_name));
|
||||||
|
|
||||||
|
#ifndef BAREMETAL
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
if (stat(S2U(szPath), &sb))
|
if (stat(S2U(szPath), &sb))
|
||||||
continue;
|
continue;
|
||||||
@@ -1660,6 +1932,27 @@ void CHostPath::Refresh()
|
|||||||
}
|
}
|
||||||
pFilename->SetEntryDate(nHumanDate);
|
pFilename->SetEntryDate(nHumanDate);
|
||||||
pFilename->SetEntryTime(nHumanTime);
|
pFilename->SetEntryTime(nHumanTime);
|
||||||
|
#else
|
||||||
|
FILINFO fno;
|
||||||
|
if (f_stat(S2U(szPath), &fno) != FR_OK)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// 属性
|
||||||
|
BYTE nHumanAttribute = Human68k::AT_ARCHIVE;
|
||||||
|
if (fno.fattrib & AM_DIR)
|
||||||
|
nHumanAttribute = Human68k::AT_DIRECTORY;
|
||||||
|
if (fno.fattrib & AM_RDO)
|
||||||
|
nHumanAttribute |= Human68k::AT_READONLY;
|
||||||
|
pFilename->SetEntryAttribute(nHumanAttribute);
|
||||||
|
|
||||||
|
// サイズ
|
||||||
|
DWORD nHumanSize = (DWORD)fno.fsize;
|
||||||
|
pFilename->SetEntrySize(nHumanSize);
|
||||||
|
|
||||||
|
// 日付時刻
|
||||||
|
pFilename->SetEntryDate(fno.fdate);
|
||||||
|
pFilename->SetEntryTime(fno.ftime);
|
||||||
|
#endif // BAREMETAL
|
||||||
|
|
||||||
// クラスタ番号設定
|
// クラスタ番号設定
|
||||||
pFilename->SetEntryCluster(0);
|
pFilename->SetEntryCluster(0);
|
||||||
@@ -1679,7 +1972,13 @@ void CHostPath::Refresh()
|
|||||||
pRing->r.InsertTail(&m_cRing);
|
pRing->r.InsertTail(&m_cRing);
|
||||||
}
|
}
|
||||||
|
|
||||||
closedir(pd);
|
// ディレクトリエントリを解放
|
||||||
|
if (pd) {
|
||||||
|
for (int i = 0; i < nument; i++) {
|
||||||
|
free(pd[i]);
|
||||||
|
}
|
||||||
|
free(pd);
|
||||||
|
}
|
||||||
|
|
||||||
// 残存するキャッシュ内容を削除
|
// 残存するキャッシュ内容を削除
|
||||||
ring_t* p;
|
ring_t* p;
|
||||||
@@ -1701,6 +2000,7 @@ void CHostPath::Refresh()
|
|||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
void CHostPath::Backup()
|
void CHostPath::Backup()
|
||||||
{
|
{
|
||||||
|
#ifndef BAREMETAL
|
||||||
ASSERT(this);
|
ASSERT(this);
|
||||||
ASSERT(m_szHost);
|
ASSERT(m_szHost);
|
||||||
ASSERT(strlen(m_szHost) < FILEPATH_MAX);
|
ASSERT(strlen(m_szHost) < FILEPATH_MAX);
|
||||||
@@ -1718,6 +2018,29 @@ void CHostPath::Backup()
|
|||||||
if (stat(S2U(szPath), &sb) == 0)
|
if (stat(S2U(szPath), &sb) == 0)
|
||||||
m_tBackup = sb.st_mtime;
|
m_tBackup = sb.st_mtime;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
FILINFO fno;
|
||||||
|
|
||||||
|
ASSERT(this);
|
||||||
|
ASSERT(m_szHost);
|
||||||
|
ASSERT(strlen(m_szHost) < FILEPATH_MAX);
|
||||||
|
|
||||||
|
TCHAR szPath[FILEPATH_MAX];
|
||||||
|
strcpy(szPath, m_szHost);
|
||||||
|
size_t len = strlen(szPath);
|
||||||
|
|
||||||
|
m_tBackupD = 0;
|
||||||
|
m_tBackupT = 0;
|
||||||
|
if (len > 1) { // ルートディレクトリの場合は何もしない
|
||||||
|
len--;
|
||||||
|
ASSERT(szPath[len] == _T('/'));
|
||||||
|
szPath[len] = _T('\0');
|
||||||
|
if (f_stat(S2U(szPath), &fno) == FR_OK) {
|
||||||
|
m_tBackupD = fno.fdate;
|
||||||
|
m_tBackupT = fno.ftime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // BAREMETAL
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
@@ -1727,6 +2050,7 @@ void CHostPath::Backup()
|
|||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
void CHostPath::Restore() const
|
void CHostPath::Restore() const
|
||||||
{
|
{
|
||||||
|
#ifndef BAREMETAL
|
||||||
ASSERT(this);
|
ASSERT(this);
|
||||||
ASSERT(m_szHost);
|
ASSERT(m_szHost);
|
||||||
ASSERT(strlen(m_szHost) < FILEPATH_MAX);
|
ASSERT(strlen(m_szHost) < FILEPATH_MAX);
|
||||||
@@ -1746,6 +2070,28 @@ void CHostPath::Restore() const
|
|||||||
ut.modtime = m_tBackup;
|
ut.modtime = m_tBackup;
|
||||||
utime(szPath, &ut);
|
utime(szPath, &ut);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
FILINFO fno;
|
||||||
|
|
||||||
|
ASSERT(this);
|
||||||
|
ASSERT(m_szHost);
|
||||||
|
ASSERT(strlen(m_szHost) < FILEPATH_MAX);
|
||||||
|
|
||||||
|
TCHAR szPath[FILEPATH_MAX];
|
||||||
|
strcpy(szPath, m_szHost);
|
||||||
|
size_t len = strlen(szPath);
|
||||||
|
|
||||||
|
if (m_tBackupD) {
|
||||||
|
ASSERT(len);
|
||||||
|
len--;
|
||||||
|
ASSERT(szPath[len] == _T('/'));
|
||||||
|
szPath[len] = _T('\0');
|
||||||
|
|
||||||
|
fno.fdate = m_tBackupD;
|
||||||
|
fno.ftime = m_tBackupT;
|
||||||
|
f_utime(szPath, &fno);
|
||||||
|
}
|
||||||
|
#endif // BAREMETAL
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
@@ -2007,6 +2353,34 @@ DWORD CHostEntry::GetStatus(DWORD nUnit) const
|
|||||||
return m_pDrv[nUnit]->GetStatus();
|
return m_pDrv[nUnit]->GetStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
/// メディア交換チェック
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
BOOL CHostEntry::CheckMedia(DWORD nUnit)
|
||||||
|
{
|
||||||
|
ASSERT(this);
|
||||||
|
ASSERT(nUnit < DriveMax);
|
||||||
|
ASSERT(m_pDrv[nUnit]);
|
||||||
|
|
||||||
|
return m_pDrv[nUnit]->CheckMedia();
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
/// イジェクト
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
void CHostEntry::Eject(DWORD nUnit)
|
||||||
|
{
|
||||||
|
ASSERT(this);
|
||||||
|
ASSERT(nUnit < DriveMax);
|
||||||
|
ASSERT(m_pDrv[nUnit]);
|
||||||
|
|
||||||
|
m_pDrv[nUnit]->Eject();
|
||||||
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
/// ボリュームラベルの取得
|
/// ボリュームラベルの取得
|
||||||
@@ -2376,7 +2750,11 @@ void CHostFcb::Init()
|
|||||||
ASSERT(this);
|
ASSERT(this);
|
||||||
|
|
||||||
m_bUpdate = FALSE;
|
m_bUpdate = FALSE;
|
||||||
|
#ifndef BAREMETAL
|
||||||
m_pFile = NULL;
|
m_pFile = NULL;
|
||||||
|
#else
|
||||||
|
memset(&m_File, 0x00, sizeof(FIL));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
@@ -2388,6 +2766,7 @@ BOOL CHostFcb::SetMode(DWORD nHumanMode)
|
|||||||
{
|
{
|
||||||
ASSERT(this);
|
ASSERT(this);
|
||||||
|
|
||||||
|
#ifndef BAREMETAL
|
||||||
switch (nHumanMode & Human68k::OP_MASK) {
|
switch (nHumanMode & Human68k::OP_MASK) {
|
||||||
case Human68k::OP_READ:
|
case Human68k::OP_READ:
|
||||||
m_pszMode = "rb";
|
m_pszMode = "rb";
|
||||||
@@ -2401,6 +2780,21 @@ BOOL CHostFcb::SetMode(DWORD nHumanMode)
|
|||||||
default:
|
default:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
switch (nHumanMode & Human68k::OP_MASK) {
|
||||||
|
case Human68k::OP_READ:
|
||||||
|
m_Mode = FA_READ;
|
||||||
|
break;
|
||||||
|
case Human68k::OP_WRITE:
|
||||||
|
m_Mode = FA_WRITE;
|
||||||
|
break;
|
||||||
|
case Human68k::OP_FULL:
|
||||||
|
m_Mode = FA_WRITE | FA_READ;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
#endif // BAREMETAL
|
||||||
|
|
||||||
m_bFlag = (nHumanMode & Human68k::OP_SPECIAL) != 0;
|
m_bFlag = (nHumanMode & Human68k::OP_SPECIAL) != 0;
|
||||||
|
|
||||||
@@ -2442,8 +2836,9 @@ void CHostFcb::SetHumanPath(const BYTE* szHumanPath)
|
|||||||
/// エラーの時はFALSEを返す。
|
/// エラーの時はFALSEを返す。
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
BOOL CHostFcb::Create(DWORD nHumanAttribute, BOOL bForce)
|
BOOL CHostFcb::Create(Human68k::fcb_t* pFcb, DWORD nHumanAttribute, BOOL bForce)
|
||||||
{
|
{
|
||||||
|
#ifndef BAREMETAL
|
||||||
ASSERT(this);
|
ASSERT(this);
|
||||||
ASSERT((nHumanAttribute & (Human68k::AT_DIRECTORY | Human68k::AT_VOLUME)) == 0);
|
ASSERT((nHumanAttribute & (Human68k::AT_DIRECTORY | Human68k::AT_VOLUME)) == 0);
|
||||||
ASSERT(strlen(m_szFilename) > 0);
|
ASSERT(strlen(m_szFilename) > 0);
|
||||||
@@ -2460,6 +2855,29 @@ BOOL CHostFcb::Create(DWORD nHumanAttribute, BOOL bForce)
|
|||||||
m_pFile = fopen(S2U(m_szFilename), "w+b"); /// @warning 理想動作は属性ごと上書き
|
m_pFile = fopen(S2U(m_szFilename), "w+b"); /// @warning 理想動作は属性ごと上書き
|
||||||
|
|
||||||
return m_pFile != NULL;
|
return m_pFile != NULL;
|
||||||
|
#else
|
||||||
|
FRESULT fr;
|
||||||
|
|
||||||
|
ASSERT(this);
|
||||||
|
ASSERT((nHumanAttribute & (Human68k::AT_DIRECTORY | Human68k::AT_VOLUME)) == 0);
|
||||||
|
ASSERT(strlen(m_szFilename) > 0);
|
||||||
|
|
||||||
|
// 重複チェック
|
||||||
|
if (bForce == FALSE) {
|
||||||
|
if (f_stat(S2U(m_szFilename), NULL) == FR_OK)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// RPIのベアメタルではRTCが無いのでHuman側の時刻を反映させる
|
||||||
|
DWORD nHumanTime = ((DWORD)pFcb->date) << 16 | ((DWORD)pFcb->time);
|
||||||
|
set_fattime(nHumanTime);
|
||||||
|
|
||||||
|
// ファイル作成
|
||||||
|
fr = f_open(&m_File, S2U(m_szFilename), FA_CREATE_ALWAYS | FA_WRITE | FA_READ);
|
||||||
|
/// @warning 理想動作は属性ごと上書き
|
||||||
|
|
||||||
|
return fr == FR_OK;
|
||||||
|
#endif // BAREMETAL
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
@@ -2471,8 +2889,9 @@ BOOL CHostFcb::Create(DWORD nHumanAttribute, BOOL bForce)
|
|||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
BOOL CHostFcb::Open()
|
BOOL CHostFcb::Open()
|
||||||
{
|
{
|
||||||
|
#ifndef BAREMETAL
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
ASSERT(this);
|
ASSERT(this);
|
||||||
ASSERT(strlen(m_szFilename) > 0);
|
ASSERT(strlen(m_szFilename) > 0);
|
||||||
|
|
||||||
@@ -2488,6 +2907,27 @@ BOOL CHostFcb::Open()
|
|||||||
m_pFile = fopen(S2U(m_szFilename), m_pszMode);
|
m_pFile = fopen(S2U(m_szFilename), m_pszMode);
|
||||||
|
|
||||||
return m_pFile != NULL || m_bFlag;
|
return m_pFile != NULL || m_bFlag;
|
||||||
|
#else
|
||||||
|
FRESULT fr;
|
||||||
|
FILINFO fno;
|
||||||
|
|
||||||
|
ASSERT(this);
|
||||||
|
ASSERT(strlen(m_szFilename) > 0);
|
||||||
|
|
||||||
|
// ディレクトリなら失敗
|
||||||
|
if (f_stat(S2U(m_szFilename), &fno) == FR_OK) {
|
||||||
|
if (fno.fattrib & AM_DIR) {
|
||||||
|
return FALSE || m_bFlag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ファイルオープン
|
||||||
|
fr = FR_DISK_ERR;
|
||||||
|
if (m_File.obj.fs == NULL)
|
||||||
|
fr = f_open(&m_File, S2U(m_szFilename), m_Mode);
|
||||||
|
|
||||||
|
return fr == FR_OK || m_bFlag;
|
||||||
|
#endif // BAREMETAL
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
@@ -2500,12 +2940,19 @@ BOOL CHostFcb::Open()
|
|||||||
BOOL CHostFcb::Rewind(DWORD nOffset)
|
BOOL CHostFcb::Rewind(DWORD nOffset)
|
||||||
{
|
{
|
||||||
ASSERT(this);
|
ASSERT(this);
|
||||||
|
#ifndef BAREMETAL
|
||||||
ASSERT(m_pFile);
|
ASSERT(m_pFile);
|
||||||
|
|
||||||
if (fseek(m_pFile, nOffset, SEEK_SET))
|
if (fseek(m_pFile, nOffset, SEEK_SET))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
return ftell(m_pFile) != -1L;
|
return ftell(m_pFile) != -1L;
|
||||||
|
#else
|
||||||
|
if (f_lseek(&m_File, nOffset))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return f_tell(&m_File) != (DWORD)-1L;
|
||||||
|
#endif // BAREMETAL
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
@@ -2518,6 +2965,7 @@ BOOL CHostFcb::Rewind(DWORD nOffset)
|
|||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
DWORD CHostFcb::Read(BYTE* pBuffer, DWORD nSize)
|
DWORD CHostFcb::Read(BYTE* pBuffer, DWORD nSize)
|
||||||
{
|
{
|
||||||
|
#ifndef BAREMETAL
|
||||||
ASSERT(this);
|
ASSERT(this);
|
||||||
ASSERT(pBuffer);
|
ASSERT(pBuffer);
|
||||||
ASSERT(m_pFile);
|
ASSERT(m_pFile);
|
||||||
@@ -2527,6 +2975,19 @@ DWORD CHostFcb::Read(BYTE* pBuffer, DWORD nSize)
|
|||||||
nResult = (size_t)-1;
|
nResult = (size_t)-1;
|
||||||
|
|
||||||
return (DWORD)nResult;
|
return (DWORD)nResult;
|
||||||
|
#else
|
||||||
|
FRESULT fr;
|
||||||
|
UINT nResult;
|
||||||
|
|
||||||
|
ASSERT(this);
|
||||||
|
ASSERT(pBuffer);
|
||||||
|
|
||||||
|
fr = f_read(&m_File, pBuffer, nSize, &nResult);
|
||||||
|
if (fr != FR_OK)
|
||||||
|
nResult = (UINT)-1;
|
||||||
|
|
||||||
|
return (DWORD)nResult;
|
||||||
|
#endif // BAREMETAL
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
@@ -2539,6 +3000,7 @@ DWORD CHostFcb::Read(BYTE* pBuffer, DWORD nSize)
|
|||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
DWORD CHostFcb::Write(const BYTE* pBuffer, DWORD nSize)
|
DWORD CHostFcb::Write(const BYTE* pBuffer, DWORD nSize)
|
||||||
{
|
{
|
||||||
|
#ifndef BAREMETAL
|
||||||
ASSERT(this);
|
ASSERT(this);
|
||||||
ASSERT(pBuffer);
|
ASSERT(pBuffer);
|
||||||
ASSERT(m_pFile);
|
ASSERT(m_pFile);
|
||||||
@@ -2548,6 +3010,19 @@ DWORD CHostFcb::Write(const BYTE* pBuffer, DWORD nSize)
|
|||||||
nResult = (size_t)-1;
|
nResult = (size_t)-1;
|
||||||
|
|
||||||
return (DWORD)nResult;
|
return (DWORD)nResult;
|
||||||
|
#else
|
||||||
|
FRESULT fr;
|
||||||
|
UINT nResult;
|
||||||
|
|
||||||
|
ASSERT(this);
|
||||||
|
ASSERT(pBuffer);
|
||||||
|
|
||||||
|
fr = f_write(&m_File, pBuffer, nSize, &nResult);
|
||||||
|
if (fr != FR_OK)
|
||||||
|
nResult = (UINT)-1;
|
||||||
|
|
||||||
|
return (DWORD)nResult;
|
||||||
|
#endif // BAREMETAL
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
@@ -2560,9 +3035,13 @@ DWORD CHostFcb::Write(const BYTE* pBuffer, DWORD nSize)
|
|||||||
BOOL CHostFcb::Truncate()
|
BOOL CHostFcb::Truncate()
|
||||||
{
|
{
|
||||||
ASSERT(this);
|
ASSERT(this);
|
||||||
|
#ifndef BAREMETAL
|
||||||
ASSERT(m_pFile);
|
ASSERT(m_pFile);
|
||||||
|
|
||||||
return ftruncate(fileno(m_pFile), ftell(m_pFile)) == 0;
|
return ftruncate(fileno(m_pFile), ftell(m_pFile)) == 0;
|
||||||
|
#else
|
||||||
|
return f_truncate(&m_File) == FR_OK;
|
||||||
|
#endif // BAREMETAL
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
@@ -2574,6 +3053,7 @@ BOOL CHostFcb::Truncate()
|
|||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
DWORD CHostFcb::Seek(DWORD nOffset, DWORD nHumanSeek)
|
DWORD CHostFcb::Seek(DWORD nOffset, DWORD nHumanSeek)
|
||||||
{
|
{
|
||||||
|
#ifndef BAREMETAL
|
||||||
ASSERT(this);
|
ASSERT(this);
|
||||||
ASSERT(nHumanSeek == Human68k::SK_BEGIN ||
|
ASSERT(nHumanSeek == Human68k::SK_BEGIN ||
|
||||||
nHumanSeek == Human68k::SK_CURRENT || nHumanSeek == Human68k::SK_END);
|
nHumanSeek == Human68k::SK_CURRENT || nHumanSeek == Human68k::SK_END);
|
||||||
@@ -2596,6 +3076,30 @@ DWORD CHostFcb::Seek(DWORD nOffset, DWORD nHumanSeek)
|
|||||||
return (DWORD)-1;
|
return (DWORD)-1;
|
||||||
|
|
||||||
return (DWORD)ftell(m_pFile);
|
return (DWORD)ftell(m_pFile);
|
||||||
|
#else
|
||||||
|
FRESULT fr;
|
||||||
|
|
||||||
|
ASSERT(this);
|
||||||
|
ASSERT(nHumanSeek == Human68k::SK_BEGIN ||
|
||||||
|
nHumanSeek == Human68k::SK_CURRENT || nHumanSeek == Human68k::SK_END);
|
||||||
|
|
||||||
|
switch (nHumanSeek) {
|
||||||
|
case Human68k::SK_BEGIN:
|
||||||
|
fr = f_lseek(&m_File, nOffset);
|
||||||
|
break;
|
||||||
|
case Human68k::SK_CURRENT:
|
||||||
|
fr = f_lseek(&m_File, f_tell(&m_File) + nOffset);
|
||||||
|
break;
|
||||||
|
// case SK_END:
|
||||||
|
default:
|
||||||
|
fr = f_lseek(&m_File, f_size(&m_File) + nOffset);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (fr != FR_OK)
|
||||||
|
return (DWORD)-1;
|
||||||
|
|
||||||
|
return (DWORD)f_tell(&m_File);
|
||||||
|
#endif // BAREMETAL
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
@@ -2607,6 +3111,7 @@ DWORD CHostFcb::Seek(DWORD nOffset, DWORD nHumanSeek)
|
|||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
BOOL CHostFcb::TimeStamp(DWORD nHumanTime)
|
BOOL CHostFcb::TimeStamp(DWORD nHumanTime)
|
||||||
{
|
{
|
||||||
|
#ifndef BAREMETAL
|
||||||
ASSERT(this);
|
ASSERT(this);
|
||||||
ASSERT(m_pFile || m_bFlag);
|
ASSERT(m_pFile || m_bFlag);
|
||||||
|
|
||||||
@@ -2614,7 +3119,7 @@ BOOL CHostFcb::TimeStamp(DWORD nHumanTime)
|
|||||||
t.tm_year = (nHumanTime >> 25) + 80;
|
t.tm_year = (nHumanTime >> 25) + 80;
|
||||||
t.tm_mon = ((nHumanTime >> 21) - 1) & 15;
|
t.tm_mon = ((nHumanTime >> 21) - 1) & 15;
|
||||||
t.tm_mday = (nHumanTime >> 16) & 31;
|
t.tm_mday = (nHumanTime >> 16) & 31;
|
||||||
t.tm_hour = (nHumanTime >> 11) & 15;
|
t.tm_hour = (nHumanTime >> 11) & 31;
|
||||||
t.tm_min = (nHumanTime >> 5) & 63;
|
t.tm_min = (nHumanTime >> 5) & 63;
|
||||||
t.tm_sec = (nHumanTime & 31) << 1;
|
t.tm_sec = (nHumanTime & 31) << 1;
|
||||||
time_t ti = mktime(&t);
|
time_t ti = mktime(&t);
|
||||||
@@ -2629,6 +3134,20 @@ BOOL CHostFcb::TimeStamp(DWORD nHumanTime)
|
|||||||
fflush(m_pFile);
|
fflush(m_pFile);
|
||||||
|
|
||||||
return utime(S2U(m_szFilename), &ut) == 0 || m_bFlag;
|
return utime(S2U(m_szFilename), &ut) == 0 || m_bFlag;
|
||||||
|
#else
|
||||||
|
FILINFO fno;
|
||||||
|
|
||||||
|
ASSERT(this);
|
||||||
|
ASSERT(m_bFlag);
|
||||||
|
|
||||||
|
// クローズ時に更新時刻が上書きされるのを防止するため
|
||||||
|
// タイムスタンプの更新前にフラッシュして同期させる
|
||||||
|
f_sync(&m_File);
|
||||||
|
|
||||||
|
fno.fdate = (WORD)(nHumanTime >> 16);
|
||||||
|
fno.ftime = (WORD)nHumanTime;
|
||||||
|
return f_utime(S2U(m_szFilename), &fno) == FR_OK || m_bFlag;
|
||||||
|
#endif // BAREMETAL
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
@@ -2646,10 +3165,14 @@ BOOL CHostFcb::Close()
|
|||||||
|
|
||||||
// ファイルクローズ
|
// ファイルクローズ
|
||||||
// Close→Free(内部で再度Close)という流れもあるので必ず初期化すること。
|
// Close→Free(内部で再度Close)という流れもあるので必ず初期化すること。
|
||||||
|
#ifndef BAREMETAL
|
||||||
if (m_pFile) {
|
if (m_pFile) {
|
||||||
fclose(m_pFile);
|
fclose(m_pFile);
|
||||||
m_pFile = NULL;
|
m_pFile = NULL;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
f_close(&m_File);
|
||||||
|
#endif // BAREMETAL
|
||||||
|
|
||||||
return bResult;
|
return bResult;
|
||||||
}
|
}
|
||||||
@@ -2813,6 +3336,9 @@ CFileSys::CFileSys()
|
|||||||
m_nOptionDefault = 0;
|
m_nOptionDefault = 0;
|
||||||
m_nOption = 0;
|
m_nOption = 0;
|
||||||
ASSERT(g_nOption == 0);
|
ASSERT(g_nOption == 0);
|
||||||
|
|
||||||
|
// 登録したドライブ数は0
|
||||||
|
m_nUnits = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
@@ -2974,7 +3500,11 @@ int CFileSys::MakeDir(DWORD nUnit, const Human68k::namests_t* pNamests)
|
|||||||
f.AddFilename();
|
f.AddFilename();
|
||||||
|
|
||||||
// ディレクトリ作成
|
// ディレクトリ作成
|
||||||
|
#ifndef BAREMETAL
|
||||||
if (mkdir(S2U(f.GetPath()), 0777))
|
if (mkdir(S2U(f.GetPath()), 0777))
|
||||||
|
#else
|
||||||
|
if (f_mkdir(S2U(f.GetPath())) != FR_OK)
|
||||||
|
#endif // BAREMETAL
|
||||||
return FS_INVALIDPATH;
|
return FS_INVALIDPATH;
|
||||||
|
|
||||||
// キャッシュ更新
|
// キャッシュ更新
|
||||||
@@ -3025,7 +3555,11 @@ int CFileSys::RemoveDir(DWORD nUnit, const Human68k::namests_t* pNamests)
|
|||||||
m_cEntry.DeleteCache(nUnit, szHuman);
|
m_cEntry.DeleteCache(nUnit, szHuman);
|
||||||
|
|
||||||
// ディレクトリ削除
|
// ディレクトリ削除
|
||||||
|
#ifndef BAREMETAL
|
||||||
if (rmdir(S2U(f.GetPath())))
|
if (rmdir(S2U(f.GetPath())))
|
||||||
|
#else
|
||||||
|
if (f_rmdir(S2U(f.GetPath())) != FR_OK)
|
||||||
|
#endif // BAREMETAL
|
||||||
return FS_CANTDELETE;
|
return FS_CANTDELETE;
|
||||||
|
|
||||||
// キャッシュ更新
|
// キャッシュ更新
|
||||||
@@ -3082,7 +3616,11 @@ int CFileSys::Rename(DWORD nUnit, const Human68k::namests_t* pNamests, const Hum
|
|||||||
char szTo[FILENAME_MAX];
|
char szTo[FILENAME_MAX];
|
||||||
SJIS2UTF8(f.GetPath(), szFrom, FILENAME_MAX);
|
SJIS2UTF8(f.GetPath(), szFrom, FILENAME_MAX);
|
||||||
SJIS2UTF8(fNew.GetPath(), szTo, FILENAME_MAX);
|
SJIS2UTF8(fNew.GetPath(), szTo, FILENAME_MAX);
|
||||||
|
#ifndef BAREMETAL
|
||||||
if (rename(szFrom, szTo)) {
|
if (rename(szFrom, szTo)) {
|
||||||
|
#else
|
||||||
|
if (f_rename(szFrom, szTo) != FR_OK) {
|
||||||
|
#endif // BAREMETAL
|
||||||
return FS_FILENOTFND;
|
return FS_FILENOTFND;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3125,7 +3663,11 @@ int CFileSys::Delete(DWORD nUnit, const Human68k::namests_t* pNamests)
|
|||||||
return FS_FILENOTFND;
|
return FS_FILENOTFND;
|
||||||
|
|
||||||
// ファイル削除
|
// ファイル削除
|
||||||
|
#ifndef BAREMETAL
|
||||||
if (unlink(S2U(f.GetPath())))
|
if (unlink(S2U(f.GetPath())))
|
||||||
|
#else
|
||||||
|
if (f_unlink(S2U(f.GetPath())) != FR_OK)
|
||||||
|
#endif // BAREMETAL
|
||||||
return FS_CANTDELETE;
|
return FS_CANTDELETE;
|
||||||
|
|
||||||
// キャッシュ更新
|
// キャッシュ更新
|
||||||
@@ -3177,6 +3719,7 @@ int CFileSys::Attribute(DWORD nUnit, const Human68k::namests_t* pNamests, DWORD
|
|||||||
DWORD nAttribute = (nHumanAttribute & Human68k::AT_READONLY) |
|
DWORD nAttribute = (nHumanAttribute & Human68k::AT_READONLY) |
|
||||||
(f.GetAttribute() & ~Human68k::AT_READONLY);
|
(f.GetAttribute() & ~Human68k::AT_READONLY);
|
||||||
if (f.GetAttribute() != nAttribute) {
|
if (f.GetAttribute() != nAttribute) {
|
||||||
|
#ifndef BAREMETAL
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
if (stat(S2U(f.GetPath()), &sb))
|
if (stat(S2U(f.GetPath()), &sb))
|
||||||
return FS_FILENOTFND;
|
return FS_FILENOTFND;
|
||||||
@@ -3189,6 +3732,17 @@ int CFileSys::Attribute(DWORD nUnit, const Human68k::namests_t* pNamests, DWORD
|
|||||||
// 属性設定
|
// 属性設定
|
||||||
if (chmod(S2U(f.GetPath()), m))
|
if (chmod(S2U(f.GetPath()), m))
|
||||||
return FS_FILENOTFND;
|
return FS_FILENOTFND;
|
||||||
|
#else
|
||||||
|
if (f_stat(S2U(f.GetPath()), NULL) != FR_OK)
|
||||||
|
return FS_FILENOTFND;
|
||||||
|
BYTE m = 0;
|
||||||
|
if (nAttribute & Human68k::AT_READONLY)
|
||||||
|
m = AM_RDO;
|
||||||
|
|
||||||
|
// 属性設定
|
||||||
|
if (f_chmod(S2U(f.GetPath()), m, AM_RDO))
|
||||||
|
return FS_FILENOTFND;
|
||||||
|
#endif // BAREMETAL
|
||||||
}
|
}
|
||||||
|
|
||||||
// キャッシュ更新
|
// キャッシュ更新
|
||||||
@@ -3398,7 +3952,7 @@ int CFileSys::Create(DWORD nUnit, DWORD nKey, const Human68k::namests_t* pNamest
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ファイル作成
|
// ファイル作成
|
||||||
if (pHostFcb->Create(nHumanAttribute, bForce) == FALSE) {
|
if (pHostFcb->Create(pFcb, nHumanAttribute, bForce) == FALSE) {
|
||||||
m_cFcb.Free(pHostFcb);
|
m_cFcb.Free(pHostFcb);
|
||||||
return FS_FILEEXIST;
|
return FS_FILEEXIST;
|
||||||
}
|
}
|
||||||
@@ -4056,7 +4610,13 @@ int CFileSys::CheckMedia(DWORD nUnit)
|
|||||||
return FS_INVALIDFUNC; // レジューム後に無効なドライブでmint操作時に白帯を出さないよう改良
|
return FS_INVALIDFUNC; // レジューム後に無効なドライブでmint操作時に白帯を出さないよう改良
|
||||||
|
|
||||||
// メディア交換チェック
|
// メディア交換チェック
|
||||||
m_cEntry.CleanCache(nUnit);
|
BOOL bResult = m_cEntry.CheckMedia(nUnit);
|
||||||
|
|
||||||
|
// メディア未挿入ならエラーとする
|
||||||
|
if (bResult == FALSE) {
|
||||||
|
return FS_INVALIDFUNC;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
// for Raspberry Pi
|
// for Raspberry Pi
|
||||||
//
|
//
|
||||||
// Powered by XM6 TypeG Technology.
|
// Powered by XM6 TypeG Technology.
|
||||||
// Copyright (C) 2016-2018 GIMONS
|
// Copyright (C) 2016-2020 GIMONS
|
||||||
// [ ホストファイルシステム ]
|
// [ ホストファイルシステム ]
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
@@ -12,6 +12,11 @@
|
|||||||
#ifndef cfilesystem_h
|
#ifndef cfilesystem_h
|
||||||
#define cfilesystem_h
|
#define cfilesystem_h
|
||||||
|
|
||||||
|
#ifdef BAREMETAL
|
||||||
|
#include "ffconf.h"
|
||||||
|
#include "ff.h"
|
||||||
|
#endif // BAREMETAL
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// ステータスコード定義
|
// ステータスコード定義
|
||||||
@@ -631,7 +636,12 @@ private:
|
|||||||
///< 文字列比較 (ワイルドカード対応)
|
///< 文字列比較 (ワイルドカード対応)
|
||||||
|
|
||||||
CRing m_cRing; ///< CHostFilename連結用
|
CRing m_cRing; ///< CHostFilename連結用
|
||||||
|
#ifndef BAREMETAL
|
||||||
time_t m_tBackup; ///< 時刻復元用
|
time_t m_tBackup; ///< 時刻復元用
|
||||||
|
#else
|
||||||
|
WORD m_tBackupD; ///< 時刻復元用
|
||||||
|
WORD m_tBackupT; ///< 時刻復元用
|
||||||
|
#endif // BAREMETAL
|
||||||
BOOL m_bRefresh; ///< 更新フラグ
|
BOOL m_bRefresh; ///< 更新フラグ
|
||||||
DWORD m_nId; ///< 識別ID (値が変化した場合は更新を意味する)
|
DWORD m_nId; ///< 識別ID (値が変化した場合は更新を意味する)
|
||||||
BYTE m_szHuman[HUMAN68K_PATH_MAX]; ///< 該当エントリのHuman68k内部名
|
BYTE m_szHuman[HUMAN68K_PATH_MAX]; ///< 該当エントリのHuman68k内部名
|
||||||
@@ -795,7 +805,7 @@ public:
|
|||||||
const BYTE* GetHumanPath() const { ASSERT(this); return m_szHumanPath; }
|
const BYTE* GetHumanPath() const { ASSERT(this); return m_szHumanPath; }
|
||||||
///< Human68kパス名を取得
|
///< Human68kパス名を取得
|
||||||
|
|
||||||
BOOL Create(DWORD nHumanAttribute, BOOL bForce);
|
BOOL Create(Human68k::fcb_t* pFcb, DWORD nHumanAttribute, BOOL bForce);
|
||||||
///< ファイル作成
|
///< ファイル作成
|
||||||
BOOL Open();
|
BOOL Open();
|
||||||
///< ファイルオープン
|
///< ファイルオープン
|
||||||
@@ -817,8 +827,13 @@ public:
|
|||||||
private:
|
private:
|
||||||
DWORD m_nKey; ///< Human68kのFCBバッファアドレス (0なら未使用)
|
DWORD m_nKey; ///< Human68kのFCBバッファアドレス (0なら未使用)
|
||||||
BOOL m_bUpdate; ///< 更新フラグ
|
BOOL m_bUpdate; ///< 更新フラグ
|
||||||
|
#ifndef BAREMETAL
|
||||||
FILE* m_pFile; ///< ホスト側のファイルオブジェクト
|
FILE* m_pFile; ///< ホスト側のファイルオブジェクト
|
||||||
const char* m_pszMode; ///< ホスト側のファイルオープンモード
|
const char* m_pszMode; ///< ホスト側のファイルオープンモード
|
||||||
|
#else
|
||||||
|
FIL m_File; ///< ホスト側のファイルオブジェクト
|
||||||
|
BYTE m_Mode; ///< ホスト側のファイルオープンモード
|
||||||
|
#endif // BAREMETAL
|
||||||
bool m_bFlag; ///< ホスト側のファイルオープンフラグ
|
bool m_bFlag; ///< ホスト側のファイルオープンフラグ
|
||||||
BYTE m_szHumanPath[HUMAN68K_PATH_MAX];
|
BYTE m_szHumanPath[HUMAN68K_PATH_MAX];
|
||||||
///< Human68kのパス名
|
///< Human68kのパス名
|
||||||
@@ -889,6 +904,12 @@ public:
|
|||||||
///< ドライブ状態の取得
|
///< ドライブ状態の取得
|
||||||
void SetEnable(BOOL bEnable);
|
void SetEnable(BOOL bEnable);
|
||||||
///< メディア状態設定
|
///< メディア状態設定
|
||||||
|
BOOL CheckMedia();
|
||||||
|
///< メディア交換チェック
|
||||||
|
void Update();
|
||||||
|
///< メディア状態更新
|
||||||
|
void Eject();
|
||||||
|
///< イジェクト
|
||||||
void GetVolume(TCHAR* szLabel);
|
void GetVolume(TCHAR* szLabel);
|
||||||
///< ボリュームラベルの取得
|
///< ボリュームラベルの取得
|
||||||
BOOL GetVolumeCache(TCHAR* szLabel) const;
|
BOOL GetVolumeCache(TCHAR* szLabel) const;
|
||||||
@@ -987,6 +1008,10 @@ public:
|
|||||||
///< メディアバイトの取得
|
///< メディアバイトの取得
|
||||||
DWORD GetStatus(DWORD nUnit) const;
|
DWORD GetStatus(DWORD nUnit) const;
|
||||||
///< ドライブ状態の取得
|
///< ドライブ状態の取得
|
||||||
|
BOOL CheckMedia(DWORD nUnit);
|
||||||
|
///< メディア交換チェック
|
||||||
|
void Eject(DWORD nUnit);
|
||||||
|
///< イジェクト
|
||||||
void GetVolume(DWORD nUnit, TCHAR* szLabel);
|
void GetVolume(DWORD nUnit, TCHAR* szLabel);
|
||||||
///< ボリュームラベルの取得
|
///< ボリュームラベルの取得
|
||||||
BOOL GetVolumeCache(DWORD nUnit, TCHAR* szLabel) const;
|
BOOL GetVolumeCache(DWORD nUnit, TCHAR* szLabel) const;
|
||||||
|
|||||||
@@ -1,68 +0,0 @@
|
|||||||
//---------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// 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
|
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
// for Raspberry Pi
|
// for Raspberry Pi
|
||||||
//
|
//
|
||||||
// Powered by XM6 TypeG Technology.
|
// Powered by XM6 TypeG Technology.
|
||||||
// Copyright (C) 2016-2018 GIMONS
|
// Copyright (C) 2016-2020 GIMONS
|
||||||
//
|
//
|
||||||
// Imported NetBSD support and some optimisation patch by Rin Okuyama.
|
// Imported NetBSD support and some optimisation patch by Rin Okuyama.
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
// for Raspberry Pi
|
// for Raspberry Pi
|
||||||
//
|
//
|
||||||
// Powered by XM6 TypeG Technology.
|
// Powered by XM6 TypeG Technology.
|
||||||
// Copyright (C) 2016-2018 GIMONS
|
// Copyright (C) 2016-2020 GIMONS
|
||||||
//
|
//
|
||||||
// Imported NetBSD support and some optimisation patch by Rin Okuyama.
|
// Imported NetBSD support and some optimisation patch by Rin Okuyama.
|
||||||
//
|
//
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,7 @@
|
|||||||
// X68000 EMULATOR "XM6"
|
// X68000 EMULATOR "XM6"
|
||||||
//
|
//
|
||||||
// Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp)
|
// Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp)
|
||||||
// Copyright (C) 2014-2018 GIMONS
|
// Copyright (C) 2014-2020 GIMONS
|
||||||
//
|
//
|
||||||
// XM6i
|
// XM6i
|
||||||
// Copyright (C) 2010-2015 isaki@NetBSD.org
|
// Copyright (C) 2010-2015 isaki@NetBSD.org
|
||||||
@@ -319,6 +319,8 @@ public:
|
|||||||
// サポートしていないコマンド
|
// サポートしていないコマンド
|
||||||
|
|
||||||
// その他
|
// その他
|
||||||
|
BOOL IsCacheWB() { return cache_wb; }
|
||||||
|
// キャッシュモード取得
|
||||||
void SetCacheWB(BOOL enable) { cache_wb = enable; }
|
void SetCacheWB(BOOL enable) { cache_wb = enable; }
|
||||||
// キャッシュモード設定
|
// キャッシュモード設定
|
||||||
|
|
||||||
@@ -703,7 +705,9 @@ private:
|
|||||||
// SCSI ホストブリッジ
|
// SCSI ホストブリッジ
|
||||||
//
|
//
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
#if defined(RASCSI) && !defined(BAREMETAL)
|
||||||
class CTapDriver;
|
class CTapDriver;
|
||||||
|
#endif // RASCSI && !BAREMETAL
|
||||||
class CFileSys;
|
class CFileSys;
|
||||||
class SCSIBR : public Disk
|
class SCSIBR : public Disk
|
||||||
{
|
{
|
||||||
@@ -725,6 +729,7 @@ public:
|
|||||||
// SEND MESSAGE10コマンド
|
// SEND MESSAGE10コマンド
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
#if defined(RASCSI) && !defined(BAREMETAL)
|
||||||
int FASTCALL GetMacAddr(BYTE *buf);
|
int FASTCALL GetMacAddr(BYTE *buf);
|
||||||
// MACアドレス取得
|
// MACアドレス取得
|
||||||
void FASTCALL SetMacAddr(BYTE *buf);
|
void FASTCALL SetMacAddr(BYTE *buf);
|
||||||
@@ -748,7 +753,7 @@ private:
|
|||||||
// 受信パケットバッファ
|
// 受信パケットバッファ
|
||||||
BOOL packet_enable;
|
BOOL packet_enable;
|
||||||
// 受信パケット有効
|
// 受信パケット有効
|
||||||
|
#endif // RASCSI && !BAREMETAL
|
||||||
|
|
||||||
int FASTCALL ReadFsResult(BYTE *buf);
|
int FASTCALL ReadFsResult(BYTE *buf);
|
||||||
// ファイルシステム読み込み(結果コード)
|
// ファイルシステム読み込み(結果コード)
|
||||||
@@ -840,14 +845,13 @@ public:
|
|||||||
UnitMax = 8
|
UnitMax = 8
|
||||||
};
|
};
|
||||||
|
|
||||||
// フェーズタイミング(調整用)
|
#ifdef RASCSI
|
||||||
|
// タイミング調整用
|
||||||
enum {
|
enum {
|
||||||
Time_phase_bsy = 800,
|
min_exec_time_sasi = 100, // SASI BOOT/FORMAT 30:NG 35:OK
|
||||||
Time_phase_before = 6000, // min 4000ns
|
min_exec_time_scsi = 50
|
||||||
Time_phase_before_data = 60000, // min 40000ns
|
|
||||||
Time_phase_after = 6000, // min 4000ns
|
|
||||||
Time_phase_after_status = 12000, // min 9000ns
|
|
||||||
};
|
};
|
||||||
|
#endif // RASCSI
|
||||||
|
|
||||||
// 内部データ定義
|
// 内部データ定義
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -861,6 +865,11 @@ public:
|
|||||||
DWORD status; // ステータスデータ
|
DWORD status; // ステータスデータ
|
||||||
DWORD message; // メッセージデータ
|
DWORD message; // メッセージデータ
|
||||||
|
|
||||||
|
#ifdef RASCSI
|
||||||
|
// 実行
|
||||||
|
DWORD execstart; // 実行開始時間
|
||||||
|
#endif // RASCSI
|
||||||
|
|
||||||
// 転送
|
// 転送
|
||||||
BYTE *buffer; // 転送バッファ
|
BYTE *buffer; // 転送バッファ
|
||||||
int bufsize; // 転送バッファサイズ
|
int bufsize; // 転送バッファサイズ
|
||||||
@@ -919,6 +928,8 @@ public:
|
|||||||
// 内部情報アドレス取得
|
// 内部情報アドレス取得
|
||||||
virtual BOOL FASTCALL IsSASI() const {return TRUE;}
|
virtual BOOL FASTCALL IsSASI() const {return TRUE;}
|
||||||
// SASIチェック
|
// SASIチェック
|
||||||
|
virtual BOOL FASTCALL IsSCSI() const {return FALSE;}
|
||||||
|
// SCSIチェック
|
||||||
Disk* FASTCALL GetBusyUnit();
|
Disk* FASTCALL GetBusyUnit();
|
||||||
// ビジー状態のユニットを取得
|
// ビジー状態のユニットを取得
|
||||||
|
|
||||||
@@ -970,13 +981,25 @@ protected:
|
|||||||
// データ転送
|
// データ転送
|
||||||
virtual void FASTCALL Send();
|
virtual void FASTCALL Send();
|
||||||
// データ送信
|
// データ送信
|
||||||
|
#ifndef RASCSI
|
||||||
|
virtual void FASTCALL SendNext();
|
||||||
|
// データ送信継続
|
||||||
|
#endif // RASCSI
|
||||||
virtual void FASTCALL Receive();
|
virtual void FASTCALL Receive();
|
||||||
// データ受信
|
// データ受信
|
||||||
|
#ifndef RASCSI
|
||||||
|
virtual void FASTCALL ReceiveNext();
|
||||||
|
// データ受信継続
|
||||||
|
#endif // RASCSI
|
||||||
BOOL FASTCALL XferIn(BYTE* buf);
|
BOOL FASTCALL XferIn(BYTE* buf);
|
||||||
// データ転送IN
|
// データ転送IN
|
||||||
BOOL FASTCALL XferOut(BOOL cont);
|
BOOL FASTCALL XferOut(BOOL cont);
|
||||||
// データ転送OUT
|
// データ転送OUT
|
||||||
|
|
||||||
|
// 特殊
|
||||||
|
void FASTCALL FlushUnit();
|
||||||
|
// 論理ユニットフラッシュ
|
||||||
|
|
||||||
// ログ
|
// ログ
|
||||||
void FASTCALL Log(Log::loglevel level, const char *format, ...);
|
void FASTCALL Log(Log::loglevel level, const char *format, ...);
|
||||||
// ログ出力
|
// ログ出力
|
||||||
@@ -1010,7 +1033,7 @@ public:
|
|||||||
// ATNメッセージ
|
// ATNメッセージ
|
||||||
BOOL atnmsg;
|
BOOL atnmsg;
|
||||||
int msc;
|
int msc;
|
||||||
BOOL msb[256];
|
BYTE msb[256];
|
||||||
} scsi_t;
|
} scsi_t;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -1035,6 +1058,8 @@ public:
|
|||||||
// その他
|
// その他
|
||||||
BOOL FASTCALL IsSASI() const {return FALSE;}
|
BOOL FASTCALL IsSASI() const {return FALSE;}
|
||||||
// SASIチェック
|
// SASIチェック
|
||||||
|
BOOL FASTCALL IsSCSI() const {return TRUE;}
|
||||||
|
// SCSIチェック
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// フェーズ
|
// フェーズ
|
||||||
@@ -1096,8 +1121,16 @@ private:
|
|||||||
// データ転送
|
// データ転送
|
||||||
void FASTCALL Send();
|
void FASTCALL Send();
|
||||||
// データ送信
|
// データ送信
|
||||||
|
#ifndef RASCSI
|
||||||
|
void FASTCALL SendNext();
|
||||||
|
// データ送信継続
|
||||||
|
#endif // RASCSI
|
||||||
void FASTCALL Receive();
|
void FASTCALL Receive();
|
||||||
// データ受信
|
// データ受信
|
||||||
|
#ifndef RASCSI
|
||||||
|
void FASTCALL ReceiveNext();
|
||||||
|
// データ受信継続
|
||||||
|
#endif // RASCSI
|
||||||
BOOL FASTCALL XferMsg(DWORD msg);
|
BOOL FASTCALL XferMsg(DWORD msg);
|
||||||
// データ転送MSG
|
// データ転送MSG
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
// X68000 EMULATOR "XM6"
|
// X68000 EMULATOR "XM6"
|
||||||
//
|
//
|
||||||
// Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp)
|
// Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp)
|
||||||
// Copyright (C) 2010-2018 GIMONS
|
// Copyright (C) 2010-2020 GIMONS
|
||||||
// [ ファイルI/O(RaSCSI用サブセット) ]
|
// [ ファイルI/O(RaSCSI用サブセット) ]
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
@@ -19,6 +19,7 @@
|
|||||||
//
|
//
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
|
#ifndef BAREMETAL
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// コンストラクタ
|
// コンストラクタ
|
||||||
@@ -89,7 +90,7 @@ BOOL FASTCALL Fileio::Save(const Filepath& path, void *buffer, int size)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 読み込み
|
// 書き込み
|
||||||
if (!Write(buffer, size)) {
|
if (!Write(buffer, size)) {
|
||||||
Close();
|
Close();
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -106,8 +107,10 @@ BOOL FASTCALL Fileio::Save(const Filepath& path, void *buffer, int size)
|
|||||||
// オープン
|
// オープン
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
BOOL FASTCALL Fileio::Open(LPCTSTR fname, OpenMode mode)
|
BOOL FASTCALL Fileio::Open(LPCTSTR fname, OpenMode mode, BOOL directIO)
|
||||||
{
|
{
|
||||||
|
mode_t omode;
|
||||||
|
|
||||||
ASSERT(this);
|
ASSERT(this);
|
||||||
ASSERT(fname);
|
ASSERT(fname);
|
||||||
ASSERT(handle < 0);
|
ASSERT(handle < 0);
|
||||||
@@ -118,16 +121,19 @@ BOOL FASTCALL Fileio::Open(LPCTSTR fname, OpenMode mode)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// デフォルトモード
|
||||||
|
omode = directIO ? O_DIRECT : 0;
|
||||||
|
|
||||||
// モード別
|
// モード別
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
// 読み込みのみ
|
// 読み込みのみ
|
||||||
case ReadOnly:
|
case ReadOnly:
|
||||||
handle = open(fname, O_RDONLY);
|
handle = open(fname, O_RDONLY | omode);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// 書き込みのみ
|
// 書き込みのみ
|
||||||
case WriteOnly:
|
case WriteOnly:
|
||||||
handle = open(fname, O_CREAT | O_WRONLY | O_TRUNC, 0666);
|
handle = open(fname, O_CREAT | O_WRONLY | O_TRUNC | omode, 0666);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// 読み書き両方
|
// 読み書き両方
|
||||||
@@ -136,12 +142,12 @@ BOOL FASTCALL Fileio::Open(LPCTSTR fname, OpenMode mode)
|
|||||||
if (access(fname, 0x06) != 0) {
|
if (access(fname, 0x06) != 0) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
handle = open(fname, O_RDWR);
|
handle = open(fname, O_RDWR | omode);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// アペンド
|
// アペンド
|
||||||
case Append:
|
case Append:
|
||||||
handle = open(fname, O_CREAT | O_WRONLY | O_APPEND, 0666);
|
handle = open(fname, O_CREAT | O_WRONLY | O_APPEND | omode, 0666);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// それ以外
|
// それ以外
|
||||||
@@ -154,6 +160,7 @@ BOOL FASTCALL Fileio::Open(LPCTSTR fname, OpenMode mode)
|
|||||||
if (handle == -1) {
|
if (handle == -1) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(handle >= 0);
|
ASSERT(handle >= 0);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@@ -163,56 +170,11 @@ BOOL FASTCALL Fileio::Open(LPCTSTR fname, OpenMode mode)
|
|||||||
// オープン
|
// オープン
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
BOOL FASTCALL Fileio::OpenDIO(LPCTSTR fname, OpenMode mode)
|
BOOL FASTCALL Fileio::Open(LPCTSTR fname, OpenMode mode)
|
||||||
{
|
{
|
||||||
ASSERT(this);
|
ASSERT(this);
|
||||||
ASSERT(fname);
|
|
||||||
ASSERT(handle < 0);
|
|
||||||
|
|
||||||
// ヌル文字列からの読み込みは必ず失敗させる
|
return Open(fname, mode, FALSE);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
@@ -227,6 +189,24 @@ BOOL FASTCALL Fileio::Open(const Filepath& path, OpenMode mode)
|
|||||||
return Open(path.GetPath(), mode);
|
return Open(path.GetPath(), mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// オープン
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
BOOL FASTCALL Fileio::OpenDIO(LPCTSTR fname, OpenMode mode)
|
||||||
|
{
|
||||||
|
ASSERT(this);
|
||||||
|
|
||||||
|
// O_DIRECT付きでオープン
|
||||||
|
if (!Open(fname, mode, TRUE)) {
|
||||||
|
// 通常モードリトライ(tmpfs等)
|
||||||
|
return Open(fname, mode, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// オープン
|
// オープン
|
||||||
@@ -276,7 +256,7 @@ BOOL FASTCALL Fileio::Write(const void *buffer, int size)
|
|||||||
ASSERT(size > 0);
|
ASSERT(size > 0);
|
||||||
ASSERT(handle >= 0);
|
ASSERT(handle >= 0);
|
||||||
|
|
||||||
// 読み込み
|
// 書き込み
|
||||||
count = write(handle, buffer, size);
|
count = write(handle, buffer, size);
|
||||||
if (count != size) {
|
if (count != size) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -365,3 +345,273 @@ void FASTCALL Fileio::Close()
|
|||||||
handle = -1;
|
handle = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// コンストラクタ
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
Fileio::Fileio()
|
||||||
|
{
|
||||||
|
// ワーク初期化
|
||||||
|
handle.obj.fs = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// デストラクタ
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
Fileio::~Fileio()
|
||||||
|
{
|
||||||
|
ASSERT(!handle.obj.fs);
|
||||||
|
|
||||||
|
// Releaseでの安全策
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// ロード
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
BOOL FASTCALL Fileio::Load(const Filepath& path, void *buffer, int size)
|
||||||
|
{
|
||||||
|
ASSERT(this);
|
||||||
|
ASSERT(buffer);
|
||||||
|
ASSERT(size > 0);
|
||||||
|
ASSERT(!handle.obj.fs);
|
||||||
|
|
||||||
|
// オープン
|
||||||
|
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.obj.fs);
|
||||||
|
|
||||||
|
// オープン
|
||||||
|
if (!Open(path, WriteOnly)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 書き込み
|
||||||
|
if (!Write(buffer, size)) {
|
||||||
|
Close();
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// クローズ
|
||||||
|
Close();
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// オープン
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
BOOL FASTCALL Fileio::Open(LPCTSTR fname, OpenMode mode)
|
||||||
|
{
|
||||||
|
FRESULT fr;
|
||||||
|
Filepath fpath;
|
||||||
|
ASSERT(this);
|
||||||
|
ASSERT(fname);
|
||||||
|
ASSERT(!handle.obj.fs);
|
||||||
|
|
||||||
|
// ヌル文字列からの読み込みは必ず失敗させる
|
||||||
|
if (fname[0] == _T('\0')) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// モード別
|
||||||
|
switch (mode) {
|
||||||
|
// 読み込みのみ
|
||||||
|
case ReadOnly:
|
||||||
|
fr = f_open(&handle, fname, FA_READ);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// 書き込みのみ
|
||||||
|
case WriteOnly:
|
||||||
|
fr = f_open(&handle, fname, FA_CREATE_ALWAYS | FA_WRITE);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// 読み書き両方
|
||||||
|
case ReadWrite:
|
||||||
|
fr = f_open(&handle, fname, FA_READ | FA_WRITE);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// アペンド
|
||||||
|
case Append:
|
||||||
|
fr = f_open(&handle, fname, FA_OPEN_APPEND | FA_WRITE);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// それ以外
|
||||||
|
default:
|
||||||
|
fr = FR_NO_PATH;
|
||||||
|
ASSERT(FALSE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 結果評価
|
||||||
|
if (fr != FR_OK) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// オープン成功
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// オープン
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
BOOL FASTCALL Fileio::Open(const Filepath& path, OpenMode mode)
|
||||||
|
{
|
||||||
|
ASSERT(this);
|
||||||
|
ASSERT(!handle.obj.fs);
|
||||||
|
|
||||||
|
return Open(path.GetPath(), mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// 読み込み
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
BOOL FASTCALL Fileio::Read(void *buffer, int size)
|
||||||
|
{
|
||||||
|
FRESULT fr;
|
||||||
|
UINT count;
|
||||||
|
|
||||||
|
ASSERT(this);
|
||||||
|
ASSERT(buffer);
|
||||||
|
ASSERT(size > 0);
|
||||||
|
ASSERT(handle.obj.fs);
|
||||||
|
|
||||||
|
// 読み込み
|
||||||
|
fr = f_read(&handle, buffer, size, &count);
|
||||||
|
if (fr != FR_OK || count != (unsigned int)size) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// 書き込み
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
BOOL FASTCALL Fileio::Write(const void *buffer, int size)
|
||||||
|
{
|
||||||
|
FRESULT fr;
|
||||||
|
UINT count;
|
||||||
|
|
||||||
|
ASSERT(this);
|
||||||
|
ASSERT(buffer);
|
||||||
|
ASSERT(size > 0);
|
||||||
|
ASSERT(handle.obj.fs);
|
||||||
|
|
||||||
|
// 書き込み
|
||||||
|
fr = f_write(&handle, buffer, size, &count);
|
||||||
|
if (fr != FR_OK || count != (unsigned int)size) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// シーク
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
BOOL FASTCALL Fileio::Seek(off64_t offset, BOOL relative)
|
||||||
|
{
|
||||||
|
FRESULT fr;
|
||||||
|
|
||||||
|
ASSERT(this);
|
||||||
|
ASSERT(offset >= 0);
|
||||||
|
ASSERT(handle.obj.fs);
|
||||||
|
|
||||||
|
// 相対シークならオフセットに現在値を追加
|
||||||
|
if (relative) {
|
||||||
|
offset += f_tell(&handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
fr = f_lseek(&handle, offset);
|
||||||
|
if (fr != FR_OK) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (f_tell(&handle) != (DWORD)offset) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// ファイルサイズ取得
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
off64_t FASTCALL Fileio::GetFileSize()
|
||||||
|
{
|
||||||
|
ASSERT(this);
|
||||||
|
ASSERT(handle.obj.fs);
|
||||||
|
|
||||||
|
return f_size(&handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// ファイル位置取得
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
off64_t FASTCALL Fileio::GetFilePos() const
|
||||||
|
{
|
||||||
|
ASSERT(this);
|
||||||
|
ASSERT(handle.obj.fs);
|
||||||
|
|
||||||
|
return f_tell(&handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// クローズ
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
void FASTCALL Fileio::Close()
|
||||||
|
{
|
||||||
|
ASSERT(this);
|
||||||
|
|
||||||
|
if (handle.obj.fs) {
|
||||||
|
f_close(&handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif //BAREMETAL
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
// X68000 EMULATOR "XM6"
|
// X68000 EMULATOR "XM6"
|
||||||
//
|
//
|
||||||
// Copyright (C) 2001-2005 PI.(ytanaka@ipc-tokai.or.jp)
|
// Copyright (C) 2001-2005 PI.(ytanaka@ipc-tokai.or.jp)
|
||||||
// Copyright (C) 2013-2018 GIMONS
|
// Copyright (C) 2013-2020 GIMONS
|
||||||
// [ ファイルI/O(RaSCSI用サブセット) ]
|
// [ ファイルI/O(RaSCSI用サブセット) ]
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
@@ -11,6 +11,10 @@
|
|||||||
#if !defined(fileio_h)
|
#if !defined(fileio_h)
|
||||||
#define fileio_h
|
#define fileio_h
|
||||||
|
|
||||||
|
#ifdef BAREMETAL
|
||||||
|
#include "ff.h"
|
||||||
|
#endif // BAREMETAL
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
// マクロ(Load,Save用)
|
// マクロ(Load,Save用)
|
||||||
@@ -53,12 +57,14 @@ public:
|
|||||||
|
|
||||||
BOOL FASTCALL Open(LPCTSTR fname, OpenMode mode);
|
BOOL FASTCALL Open(LPCTSTR fname, OpenMode mode);
|
||||||
// オープン
|
// オープン
|
||||||
BOOL FASTCALL OpenDIO(LPCTSTR fname, OpenMode mode);
|
|
||||||
// オープン
|
|
||||||
BOOL FASTCALL Open(const Filepath& path, OpenMode mode);
|
BOOL FASTCALL Open(const Filepath& path, OpenMode mode);
|
||||||
// オープン
|
// オープン
|
||||||
|
#ifndef BAREMETAL
|
||||||
|
BOOL FASTCALL OpenDIO(LPCTSTR fname, OpenMode mode);
|
||||||
|
// オープン
|
||||||
BOOL FASTCALL OpenDIO(const Filepath& path, OpenMode mode);
|
BOOL FASTCALL OpenDIO(const Filepath& path, OpenMode mode);
|
||||||
// オープン
|
// オープン
|
||||||
|
#endif // BAREMETAL
|
||||||
BOOL FASTCALL Seek(off64_t offset, BOOL relative = FALSE);
|
BOOL FASTCALL Seek(off64_t offset, BOOL relative = FALSE);
|
||||||
// シーク
|
// シーク
|
||||||
BOOL FASTCALL Read(void *buffer, int size);
|
BOOL FASTCALL Read(void *buffer, int size);
|
||||||
@@ -71,13 +77,22 @@ public:
|
|||||||
// ファイル位置取得
|
// ファイル位置取得
|
||||||
void FASTCALL Close();
|
void FASTCALL Close();
|
||||||
// クローズ
|
// クローズ
|
||||||
|
#ifndef BAREMETAL
|
||||||
BOOL FASTCALL IsValid() const { return (BOOL)(handle != -1); }
|
BOOL FASTCALL IsValid() const { return (BOOL)(handle != -1); }
|
||||||
|
#else
|
||||||
|
BOOL FASTCALL IsValid() const { return (BOOL)(handle.obj.fs != 0); }
|
||||||
|
#endif // BAREMETAL
|
||||||
// 有効チェック
|
// 有効チェック
|
||||||
int FASTCALL GetHandle() const { return handle; }
|
|
||||||
// ハンドル取得
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
#ifndef BAREMETAL
|
||||||
|
BOOL FASTCALL Open(LPCTSTR fname, OpenMode mode, BOOL directIO);
|
||||||
|
// オープン
|
||||||
|
|
||||||
int handle; // ファイルハンドル
|
int handle; // ファイルハンドル
|
||||||
|
#else
|
||||||
|
FIL handle; // ファイルハンドル
|
||||||
|
#endif // BAREMETAL
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // fileio_h
|
#endif // fileio_h
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
// X68000 EMULATOR "XM6"
|
// X68000 EMULATOR "XM6"
|
||||||
//
|
//
|
||||||
// Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp)
|
// Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp)
|
||||||
// Copyright (C) 2012-2018 GIMONS
|
// Copyright (C) 2012-2020 GIMONS
|
||||||
// [ ファイルパス(サブセット) ]
|
// [ ファイルパス(サブセット) ]
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
@@ -86,6 +86,80 @@ void FASTCALL Filepath::SetPath(LPCSTR path)
|
|||||||
Split();
|
Split();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef BAREMETAL
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// 互換関数(dirname) 結果は直ぐにコピーせよ
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
static char dirtmp[2];
|
||||||
|
char* dirname(char *path)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
if( path == NULL || *path == '\0' ) {
|
||||||
|
dirtmp[0] = '.';
|
||||||
|
dirtmp[1] = '\0';
|
||||||
|
return dirtmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = path + strlen(path) - 1;
|
||||||
|
while( *p == '/' ) {
|
||||||
|
if( p == path )
|
||||||
|
return path;
|
||||||
|
*p-- = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
while( p >= path && *p != '/' ) {
|
||||||
|
p--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p < path) {
|
||||||
|
dirtmp[0] = '.';
|
||||||
|
dirtmp[1] = '\0';
|
||||||
|
return dirtmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p == path) {
|
||||||
|
dirtmp[0] = '/';
|
||||||
|
dirtmp[1] = '\0';
|
||||||
|
return dirtmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
*p = 0;
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// 互換関数(basename) 結果は直ぐにコピーせよ
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
static char basetmp[2];
|
||||||
|
char* basename(char *path)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
if( path == NULL || *path == '\0' ) {
|
||||||
|
basetmp[0] = '/';
|
||||||
|
basetmp[1] = '\0';
|
||||||
|
return basetmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = path + strlen(path) - 1;
|
||||||
|
while( *p == '/' ) {
|
||||||
|
if( p == path ) {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
*p-- = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
while( p >= path && *p != '/' ) {
|
||||||
|
p--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return p + 1;
|
||||||
|
}
|
||||||
|
#endif // BAREMETAL
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// パス分離
|
// パス分離
|
||||||
@@ -121,7 +195,6 @@ void FASTCALL Filepath::Split()
|
|||||||
|
|
||||||
if (pExtName) {
|
if (pExtName) {
|
||||||
strcpy(m_szExt, pExtName);
|
strcpy(m_szExt, pExtName);
|
||||||
*pExtName = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pBaseName) {
|
if (pBaseName) {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
// X68000 EMULATOR "XM6"
|
// X68000 EMULATOR "XM6"
|
||||||
//
|
//
|
||||||
// Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp)
|
// Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp)
|
||||||
// Copyright (C) 2012-2018 GIMONS
|
// Copyright (C) 2012-2020 GIMONS
|
||||||
// [ ファイルパス(サブセット) ]
|
// [ ファイルパス(サブセット) ]
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,7 @@
|
|||||||
// for Raspberry Pi
|
// for Raspberry Pi
|
||||||
//
|
//
|
||||||
// Powered by XM6 TypeG Technology.
|
// Powered by XM6 TypeG Technology.
|
||||||
// Copyright (C) 2016-2018 GIMONS
|
// Copyright (C) 2016-2020 GIMONS
|
||||||
// [ GPIO-SCSIバス ]
|
// [ GPIO-SCSIバス ]
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
// 接続方法定義の選択
|
// 接続方法定義の選択
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
#define CONNECT_TYPE_STANDARD // 標準(SCSI論理,標準ピンアサイン)
|
//#define CONNECT_TYPE_STANDARD // 標準(SCSI論理,標準ピンアサイン)
|
||||||
//#define CONNECT_TYPE_FULLSPEC // フルスペック(SCSI論理,標準ピンアサイン)
|
//#define CONNECT_TYPE_FULLSPEC // フルスペック(SCSI論理,標準ピンアサイン)
|
||||||
//#define CONNECT_TYPE_AIBOM // AIBOM版(正論理,固有ピンアサイン)
|
//#define CONNECT_TYPE_AIBOM // AIBOM版(正論理,固有ピンアサイン)
|
||||||
//#define CONNECT_TYPE_GAMERNIUM // GAMERnium.com版(標準論理,固有ピンアサイン)
|
//#define CONNECT_TYPE_GAMERNIUM // GAMERnium.com版(標準論理,固有ピンアサイン)
|
||||||
@@ -281,8 +281,12 @@
|
|||||||
// 定数宣言(GPIO)
|
// 定数宣言(GPIO)
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
#define GPIO_OFFSET 0x200000
|
#define SYST_OFFSET 0x00003000
|
||||||
#define PADS_OFFSET 0x100000
|
#define IRPT_OFFSET 0x0000B200
|
||||||
|
#define ARMT_OFFSET 0x0000B400
|
||||||
|
#define PADS_OFFSET 0x00100000
|
||||||
|
#define GPIO_OFFSET 0x00200000
|
||||||
|
#define QA7_OFFSET 0x01000000
|
||||||
#define GPIO_INPUT 0
|
#define GPIO_INPUT 0
|
||||||
#define GPIO_OUTPUT 1
|
#define GPIO_OUTPUT 1
|
||||||
#define GPIO_PULLNONE 0
|
#define GPIO_PULLNONE 0
|
||||||
@@ -304,7 +308,40 @@
|
|||||||
#define GPIO_AFEN_0 34
|
#define GPIO_AFEN_0 34
|
||||||
#define GPIO_PUD 37
|
#define GPIO_PUD 37
|
||||||
#define GPIO_CLK_0 38
|
#define GPIO_CLK_0 38
|
||||||
|
#define GPIO_GPPINMUXSD 52
|
||||||
|
#define GPIO_PUPPDN0 57
|
||||||
|
#define GPIO_PUPPDN1 58
|
||||||
|
#define GPIO_PUPPDN3 59
|
||||||
|
#define GPIO_PUPPDN4 60
|
||||||
#define PAD_0_27 11
|
#define PAD_0_27 11
|
||||||
|
#define SYST_CS 0
|
||||||
|
#define SYST_CLO 1
|
||||||
|
#define SYST_CHI 2
|
||||||
|
#define SYST_C0 3
|
||||||
|
#define SYST_C1 4
|
||||||
|
#define SYST_C2 5
|
||||||
|
#define SYST_C3 6
|
||||||
|
#define ARMT_LOAD 0
|
||||||
|
#define ARMT_VALUE 1
|
||||||
|
#define ARMT_CTRL 2
|
||||||
|
#define ARMT_CLRIRQ 3
|
||||||
|
#define ARMT_RAWIRQ 4
|
||||||
|
#define ARMT_MSKIRQ 5
|
||||||
|
#define ARMT_RELOAD 6
|
||||||
|
#define ARMT_PREDIV 7
|
||||||
|
#define ARMT_FREERUN 8
|
||||||
|
#define IRPT_PND_IRQ_B 0
|
||||||
|
#define IRPT_PND_IRQ_1 1
|
||||||
|
#define IRPT_PND_IRQ_2 2
|
||||||
|
#define IRPT_FIQ_CNTL 3
|
||||||
|
#define IRPT_ENB_IRQ_1 4
|
||||||
|
#define IRPT_ENB_IRQ_2 5
|
||||||
|
#define IRPT_ENB_IRQ_B 6
|
||||||
|
#define IRPT_DIS_IRQ_1 7
|
||||||
|
#define IRPT_DIS_IRQ_2 8
|
||||||
|
#define IRPT_DIS_IRQ_B 9
|
||||||
|
#define QA7_CORE0_TINTC 16
|
||||||
|
#define GPIO_IRQ (32 + 20) // GPIO3
|
||||||
|
|
||||||
#define GPIO_INEDGE ((1 << PIN_BSY) | \
|
#define GPIO_INEDGE ((1 << PIN_BSY) | \
|
||||||
(1 << PIN_SEL) | \
|
(1 << PIN_SEL) | \
|
||||||
@@ -316,6 +353,39 @@
|
|||||||
(1 << PIN_CD) | \
|
(1 << PIN_CD) | \
|
||||||
(1 << PIN_IO))
|
(1 << PIN_IO))
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// 定数宣言(GIC)
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
#define ARM_GICD_BASE 0xFF841000
|
||||||
|
#define ARM_GICC_BASE 0xFF842000
|
||||||
|
#define ARM_GIC_END 0xFF847FFF
|
||||||
|
#define GICD_CTLR 0x000
|
||||||
|
#define GICD_IGROUPR0 0x020
|
||||||
|
#define GICD_ISENABLER0 0x040
|
||||||
|
#define GICD_ICENABLER0 0x060
|
||||||
|
#define GICD_ISPENDR0 0x080
|
||||||
|
#define GICD_ICPENDR0 0x0A0
|
||||||
|
#define GICD_ISACTIVER0 0x0C0
|
||||||
|
#define GICD_ICACTIVER0 0x0E0
|
||||||
|
#define GICD_IPRIORITYR0 0x100
|
||||||
|
#define GICD_ITARGETSR0 0x200
|
||||||
|
#define GICD_ICFGR0 0x300
|
||||||
|
#define GICD_SGIR 0x3C0
|
||||||
|
#define GICC_CTLR 0x000
|
||||||
|
#define GICC_PMR 0x001
|
||||||
|
#define GICC_IAR 0x003
|
||||||
|
#define GICC_EOIR 0x004
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// 定数宣言(GIC IRQ)
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
#define GIC_IRQLOCAL0 (16 + 14)
|
||||||
|
#define GIC_GPIO_IRQ (32 + 116) // GPIO3
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// 定数宣言(制御信号)
|
// 定数宣言(制御信号)
|
||||||
@@ -339,14 +409,10 @@
|
|||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// 定数宣言(ドライバ)
|
// 定数宣言(バス制御タイミング)
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
#define DEVICE_NAME "rascsidrv"
|
#define GPIO_DATA_SETTLING 100 // データバスが安定する時間(ns)
|
||||||
#define DRIVER_PATH "/dev/" DEVICE_NAME
|
|
||||||
#define IOCTL_INIT 0x100
|
|
||||||
#define IOCTL_MODE 0x101
|
|
||||||
#define IOCTL_PADS 0x102
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
@@ -371,6 +437,9 @@ public:
|
|||||||
DWORD FASTCALL Aquire();
|
DWORD FASTCALL Aquire();
|
||||||
// 信号取り込み
|
// 信号取り込み
|
||||||
|
|
||||||
|
void FASTCALL SetENB(BOOL ast);
|
||||||
|
// ENBシグナル設定
|
||||||
|
|
||||||
BOOL FASTCALL GetBSY();
|
BOOL FASTCALL GetBSY();
|
||||||
// BSYシグナル取得
|
// BSYシグナル取得
|
||||||
void FASTCALL SetBSY(BOOL ast);
|
void FASTCALL SetBSY(BOOL ast);
|
||||||
@@ -420,24 +489,25 @@ public:
|
|||||||
// データシグナル取得
|
// データシグナル取得
|
||||||
void FASTCALL SetDAT(BYTE dat);
|
void FASTCALL SetDAT(BYTE dat);
|
||||||
// データシグナル設定
|
// データシグナル設定
|
||||||
|
BOOL FASTCALL GetDP();
|
||||||
|
// パリティシグナル取得
|
||||||
|
int FASTCALL CommandHandShake(BYTE *buf);
|
||||||
|
// コマンド受信ハンドシェイク
|
||||||
int FASTCALL ReceiveHandShake(BYTE *buf, int count);
|
int FASTCALL ReceiveHandShake(BYTE *buf, int count);
|
||||||
// データ受信ハンドシェイク
|
// データ受信ハンドシェイク
|
||||||
int FASTCALL SendHandShake(BYTE *buf, int count);
|
int FASTCALL SendHandShake(BYTE *buf, int count);
|
||||||
// データ送信ハンドシェイク
|
// データ送信ハンドシェイク
|
||||||
|
|
||||||
// タイマ関係
|
#ifdef USE_SEL_EVENT_ENABLE
|
||||||
void FASTCALL SleepNsec(DWORD nsec);
|
// SEL信号割り込み関係
|
||||||
// ナノ秒単位のスリープ
|
int FASTCALL PollSelectEvent();
|
||||||
|
// SEL信号イベントポーリング
|
||||||
|
void FASTCALL ClearSelectEvent();
|
||||||
|
// SEL信号イベントクリア
|
||||||
|
#endif // USE_SEL_EVENT_ENABLE
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void FASTCALL DrvConfig(DWORD drive);
|
// SCSI入出力信号制御
|
||||||
// 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 MakeTable();
|
||||||
// ワークテーブル作成
|
// ワークテーブル作成
|
||||||
void FASTCALL SetControl(int pin, BOOL ast);
|
void FASTCALL SetControl(int pin, BOOL ast);
|
||||||
@@ -448,19 +518,66 @@ private:
|
|||||||
// SCSI入力信号値取得
|
// SCSI入力信号値取得
|
||||||
void FASTCALL SetSignal(int pin, BOOL ast);
|
void FASTCALL SetSignal(int pin, BOOL ast);
|
||||||
// SCSI出力信号値設定
|
// SCSI出力信号値設定
|
||||||
|
BOOL FASTCALL WaitSignal(int pin, BOOL ast);
|
||||||
|
// 信号変化待ち
|
||||||
|
// 割り込み制御
|
||||||
|
void FASTCALL DisableIRQ();
|
||||||
|
// IRQ禁止
|
||||||
|
void FASTCALL EnableIRQ();
|
||||||
|
// IRQ有効
|
||||||
|
|
||||||
|
// 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 DrvConfig(DWORD drive);
|
||||||
|
// GPIOドライブ能力設定
|
||||||
|
|
||||||
|
|
||||||
mode_e actmode; // 動作モード
|
mode_e actmode; // 動作モード
|
||||||
|
|
||||||
|
DWORD baseaddr; // ベースアドレス
|
||||||
|
|
||||||
|
int rpitype;
|
||||||
|
// ラズパイ種別
|
||||||
|
|
||||||
volatile DWORD *gpio; // GPIOレジスタ
|
volatile DWORD *gpio; // GPIOレジスタ
|
||||||
|
|
||||||
volatile DWORD *pads; // PADSレジスタ
|
volatile DWORD *pads; // PADSレジスタ
|
||||||
|
|
||||||
volatile DWORD *level; // GPIO入力レベル
|
volatile DWORD *level; // GPIO入力レベル
|
||||||
|
|
||||||
|
volatile DWORD *irpctl; // 割り込み制御レジスタ
|
||||||
|
|
||||||
|
#ifndef BAREMETAL
|
||||||
|
volatile DWORD irptenb; // 割り込み有効状態
|
||||||
|
|
||||||
|
volatile DWORD *qa7regs; // QA7レジスタ
|
||||||
|
|
||||||
|
volatile int tintcore; // 割り込み制御対象CPU
|
||||||
|
|
||||||
|
volatile DWORD tintctl; // 割り込みコントロール
|
||||||
|
|
||||||
|
volatile DWORD giccpmr; // GICC 優先度設定
|
||||||
|
#endif // BAREMETAL
|
||||||
|
|
||||||
|
volatile DWORD *gicd; // GIC 割り込み分配器レジスタ
|
||||||
|
|
||||||
|
volatile DWORD *gicc; // GIC CPUインターフェースレジスタ
|
||||||
|
|
||||||
DWORD gpfsel[4]; // GPFSEL0-4バックアップ
|
DWORD gpfsel[4]; // GPFSEL0-4バックアップ
|
||||||
|
|
||||||
DWORD signals; // バス全信号
|
DWORD signals; // バス全信号
|
||||||
|
|
||||||
|
#if defined(USE_SEL_EVENT_ENABLE) && !defined(BAREMETAL)
|
||||||
|
struct gpioevent_request selevreq; // SEL信号イベント要求
|
||||||
|
|
||||||
|
int epfd; // epollファイルディスクプリタ
|
||||||
|
#endif // USE_SEL_EVENT_ENABLE && !BAREMETAL
|
||||||
|
|
||||||
#if SIGNAL_CONTROL_MODE == 0
|
#if SIGNAL_CONTROL_MODE == 0
|
||||||
DWORD tblDatMsk[3][256]; // データマスク用テーブル
|
DWORD tblDatMsk[3][256]; // データマスク用テーブル
|
||||||
|
|
||||||
@@ -471,9 +588,35 @@ private:
|
|||||||
DWORD tblDatSet[256]; // データ設定用テーブル
|
DWORD tblDatSet[256]; // データ設定用テーブル
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int drvfd; // カーネルドライバファイルディスクプリタ
|
|
||||||
|
|
||||||
static const int SignalTable[19]; // シグナルテーブル
|
static const int SignalTable[19]; // シグナルテーブル
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// システムタイマ
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
class SysTimer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static void FASTCALL Init(DWORD *syst, DWORD *armt);
|
||||||
|
// 初期化
|
||||||
|
static DWORD FASTCALL GetTimerLow();
|
||||||
|
// システムタイマ(LO)取得
|
||||||
|
static DWORD FASTCALL GetTimerHigh();
|
||||||
|
// システムタイマ(HI)取得
|
||||||
|
static void FASTCALL SleepNsec(DWORD nsec);
|
||||||
|
// ナノ秒単位のスリープ
|
||||||
|
static void FASTCALL SleepUsec(DWORD usec);
|
||||||
|
// μ秒単位のスリープ
|
||||||
|
|
||||||
|
private:
|
||||||
|
static volatile DWORD *systaddr;
|
||||||
|
// システムタイマアドレス
|
||||||
|
static volatile DWORD *armtaddr;
|
||||||
|
// ARMタイマアドレス
|
||||||
|
static volatile DWORD corefreq;
|
||||||
|
// コア周波数
|
||||||
|
};
|
||||||
|
|
||||||
#endif // gpiobus_h
|
#endif // gpiobus_h
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
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
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,7 @@
|
|||||||
// for Raspberry Pi
|
// for Raspberry Pi
|
||||||
//
|
//
|
||||||
// Powered by XM6 TypeG Technology.
|
// Powered by XM6 TypeG Technology.
|
||||||
// Copyright (C) 2016-2018 GIMONS
|
// Copyright (C) 2016-2020 GIMONS
|
||||||
// [ ログ ]
|
// [ ログ ]
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
// for Raspberry Pi
|
// for Raspberry Pi
|
||||||
//
|
//
|
||||||
// Powered by XM6 TypeG Technology.
|
// Powered by XM6 TypeG Technology.
|
||||||
// Copyright (C) 2016-2018 GIMONS
|
// Copyright (C) 2016-2020 GIMONS
|
||||||
//
|
//
|
||||||
// Imported NetBSD support and some optimisation patch by Rin Okuyama.
|
// Imported NetBSD support and some optimisation patch by Rin Okuyama.
|
||||||
//
|
//
|
||||||
@@ -48,18 +48,29 @@
|
|||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
#include <poll.h>
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <dirent.h>
|
|
||||||
#include <iconv.h>
|
#include <iconv.h>
|
||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#ifndef BAREMETAL
|
||||||
|
#include <poll.h>
|
||||||
|
#include <dirent.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/time.h>
|
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <sys/epoll.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
#include <linux/gpio.h>
|
||||||
|
#else
|
||||||
|
#include <machine/endian.h>
|
||||||
|
#define htonl(_x) __htonl(_x)
|
||||||
|
#define htons(_x) __htons(_x)
|
||||||
|
#define ntohl(_x) __ntohl(_x)
|
||||||
|
#define ntohs(_x) __ntohs(_x)
|
||||||
|
#endif // BAREMETAL
|
||||||
|
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
#include <linux/if.h>
|
#include <linux/if.h>
|
||||||
@@ -71,8 +82,6 @@
|
|||||||
#include <net/if_dl.h>
|
#include <net/if_dl.h>
|
||||||
#include <net/if_tap.h>
|
#include <net/if_tap.h>
|
||||||
#include <ifaddrs.h>
|
#include <ifaddrs.h>
|
||||||
#else
|
|
||||||
#error unsupported platform
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,7 @@
|
|||||||
// for Raspberry Pi
|
// for Raspberry Pi
|
||||||
//
|
//
|
||||||
// Powered by XM6 TypeG Technology.
|
// Powered by XM6 TypeG Technology.
|
||||||
// Copyright (C) 2016-2018 GIMONS
|
// Copyright (C) 2016-2020 GIMONS
|
||||||
// [ 制御コマンド送信 ]
|
// [ 制御コマンド送信 ]
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
@@ -65,6 +65,7 @@ int main(int argc, char* argv[])
|
|||||||
{
|
{
|
||||||
int opt;
|
int opt;
|
||||||
int id;
|
int id;
|
||||||
|
int un;
|
||||||
int cmd;
|
int cmd;
|
||||||
int type;
|
int type;
|
||||||
char *file;
|
char *file;
|
||||||
@@ -74,6 +75,7 @@ int main(int argc, char* argv[])
|
|||||||
char buf[BUFSIZ];
|
char buf[BUFSIZ];
|
||||||
|
|
||||||
id = -1;
|
id = -1;
|
||||||
|
un = 0;
|
||||||
cmd = -1;
|
cmd = -1;
|
||||||
type = -1;
|
type = -1;
|
||||||
file = NULL;
|
file = NULL;
|
||||||
@@ -83,10 +85,11 @@ int main(int argc, char* argv[])
|
|||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
fprintf(stderr, "SCSI Target Emulator RaSCSI Controller\n");
|
fprintf(stderr, "SCSI Target Emulator RaSCSI Controller\n");
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Usage: %s -i ID [-c CMD] [-t TYPE] [-f FILE]\n",
|
"Usage: %s -i ID [-u UNIT] [-c CMD] [-t TYPE] [-f FILE]\n",
|
||||||
argv[0]);
|
argv[0]);
|
||||||
fprintf(stderr, " where ID := {0|1|2|3|4|5|6|7}\n");
|
fprintf(stderr, " where ID := {0|1|2|3|4|5|6|7}\n");
|
||||||
fprintf(stderr, " CMD := {attach|detatch|insert|eject|protect}\n");
|
fprintf(stderr, " UNIT := {0|1} default setting is 0.\n");
|
||||||
|
fprintf(stderr, " CMD := {attach|detach|insert|eject|protect}\n");
|
||||||
fprintf(stderr, " TYPE := {hd|mo|cd|bridge}\n");
|
fprintf(stderr, " TYPE := {hd|mo|cd|bridge}\n");
|
||||||
fprintf(stderr, " FILE := image file path\n");
|
fprintf(stderr, " FILE := image file path\n");
|
||||||
fprintf(stderr, " CMD is 'attach' or 'insert' and FILE parameter is required.\n");
|
fprintf(stderr, " CMD is 'attach' or 'insert' and FILE parameter is required.\n");
|
||||||
@@ -97,12 +100,16 @@ int main(int argc, char* argv[])
|
|||||||
|
|
||||||
// 引数解析
|
// 引数解析
|
||||||
opterr = 0;
|
opterr = 0;
|
||||||
while ((opt = getopt(argc, argv, "i:c:t:f:l")) != -1) {
|
while ((opt = getopt(argc, argv, "i:u:c:t:f:l")) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'i':
|
case 'i':
|
||||||
id = optarg[0] - '0';
|
id = optarg[0] - '0';
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'u':
|
||||||
|
un = optarg[0] - '0';
|
||||||
|
break;
|
||||||
|
|
||||||
case 'c':
|
case 'c':
|
||||||
switch (optarg[0]) {
|
switch (optarg[0]) {
|
||||||
case 'a': // ATTACH
|
case 'a': // ATTACH
|
||||||
@@ -174,6 +181,12 @@ int main(int argc, char* argv[])
|
|||||||
exit(EINVAL);
|
exit(EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ユニットチェック
|
||||||
|
if (un < 0 || un > 1) {
|
||||||
|
fprintf(stderr, "Error : Invalid UNIT\n");
|
||||||
|
exit(EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
// コマンドチェック
|
// コマンドチェック
|
||||||
if (cmd < 0) {
|
if (cmd < 0) {
|
||||||
cmd = 0; // デフォルトはATTATCHとする
|
cmd = 0; // デフォルトはATTATCHとする
|
||||||
@@ -231,7 +244,7 @@ int main(int argc, char* argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 送信コマンド生成
|
// 送信コマンド生成
|
||||||
sprintf(buf, "%d %d %d %s\n", id, cmd, type, file ? file : "-");
|
sprintf(buf, "%d %d %d %d %s\n", id, un, cmd, type, file ? file : "-");
|
||||||
if (!SendCommand(buf)) {
|
if (!SendCommand(buf)) {
|
||||||
exit(ENOTCONN);
|
exit(ENOTCONN);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
// for Raspberry Pi
|
// for Raspberry Pi
|
||||||
//
|
//
|
||||||
// Powered by XM6 TypeG Technology.
|
// Powered by XM6 TypeG Technology.
|
||||||
// Copyright (C) 2016-2018 GIMONS
|
// Copyright (C) 2016-2020 GIMONS
|
||||||
// [ HDDダンプユーティリティ(イニシーエタモード) ]
|
// [ HDDダンプユーティリティ(イニシーエタモード) ]
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
@@ -207,29 +207,15 @@ BOOL ParseArgument(int argc, char* argv[])
|
|||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
BOOL WaitPhase(BUS::phase_t phase)
|
BOOL WaitPhase(BUS::phase_t phase)
|
||||||
{
|
{
|
||||||
int count;
|
DWORD now;
|
||||||
|
|
||||||
// REQを待つ(6秒)
|
// タイムアウト(3000ms)
|
||||||
count = 30000;
|
now = SysTimer::GetTimerLow();
|
||||||
do {
|
while ((SysTimer::GetTimerLow() - now) < 3 * 1000 * 1000) {
|
||||||
usleep(200);
|
|
||||||
bus.Aquire();
|
bus.Aquire();
|
||||||
if (bus.GetREQ()) {
|
if (bus.GetREQ() && bus.GetPhase() == phase) {
|
||||||
break;
|
return TRUE;
|
||||||
}
|
}
|
||||||
} while (count--);
|
|
||||||
|
|
||||||
// フェーズが一致すればOK
|
|
||||||
bus.Aquire();
|
|
||||||
if (bus.GetPhase() == phase) {
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// フェーズが一致すればOK(リトライ)
|
|
||||||
usleep(1000 * 1000);
|
|
||||||
bus.Aquire();
|
|
||||||
if (bus.GetPhase() == phase) {
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -242,6 +228,7 @@ BOOL WaitPhase(BUS::phase_t phase)
|
|||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
void BusFree()
|
void BusFree()
|
||||||
{
|
{
|
||||||
|
// バスリセット
|
||||||
bus.Reset();
|
bus.Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -312,8 +299,6 @@ BOOL Command(BYTE *buf, int length)
|
|||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
int DataIn(BYTE *buf, int length)
|
int DataIn(BYTE *buf, int length)
|
||||||
{
|
{
|
||||||
int count;
|
|
||||||
|
|
||||||
// フェーズ待ち
|
// フェーズ待ち
|
||||||
if (!WaitPhase(BUS::datain)) {
|
if (!WaitPhase(BUS::datain)) {
|
||||||
return -1;
|
return -1;
|
||||||
@@ -330,8 +315,6 @@ int DataIn(BYTE *buf, int length)
|
|||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
int DataOut(BYTE *buf, int length)
|
int DataOut(BYTE *buf, int length)
|
||||||
{
|
{
|
||||||
int count;
|
|
||||||
|
|
||||||
// フェーズ待ち
|
// フェーズ待ち
|
||||||
if (!WaitPhase(BUS::dataout)) {
|
if (!WaitPhase(BUS::dataout)) {
|
||||||
return -1;
|
return -1;
|
||||||
@@ -444,6 +427,7 @@ int RequestSense(int id, BYTE *buf)
|
|||||||
|
|
||||||
// 結果コード初期化
|
// 結果コード初期化
|
||||||
result = 0;
|
result = 0;
|
||||||
|
count = 0;
|
||||||
|
|
||||||
// SELECTION
|
// SELECTION
|
||||||
if (!Selection(id)) {
|
if (!Selection(id)) {
|
||||||
@@ -461,7 +445,7 @@ int RequestSense(int id, BYTE *buf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DATAIN
|
// DATAIN
|
||||||
memset(buf, 0x00, sizeof(buf));
|
memset(buf, 0x00, 256);
|
||||||
count = DataIn(buf, 256);
|
count = DataIn(buf, 256);
|
||||||
if (count <= 0) {
|
if (count <= 0) {
|
||||||
result = -3;
|
result = -3;
|
||||||
@@ -504,6 +488,7 @@ int ModeSense(int id, BYTE *buf)
|
|||||||
|
|
||||||
// 結果コード初期化
|
// 結果コード初期化
|
||||||
result = 0;
|
result = 0;
|
||||||
|
count = 0;
|
||||||
|
|
||||||
// SELECTION
|
// SELECTION
|
||||||
if (!Selection(id)) {
|
if (!Selection(id)) {
|
||||||
@@ -522,7 +507,7 @@ int ModeSense(int id, BYTE *buf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DATAIN
|
// DATAIN
|
||||||
memset(buf, 0x00, sizeof(buf));
|
memset(buf, 0x00, 256);
|
||||||
count = DataIn(buf, 256);
|
count = DataIn(buf, 256);
|
||||||
if (count <= 0) {
|
if (count <= 0) {
|
||||||
result = -3;
|
result = -3;
|
||||||
@@ -565,6 +550,7 @@ int Inquiry(int id, BYTE *buf)
|
|||||||
|
|
||||||
// 結果コード初期化
|
// 結果コード初期化
|
||||||
result = 0;
|
result = 0;
|
||||||
|
count = 0;
|
||||||
|
|
||||||
// SELECTION
|
// SELECTION
|
||||||
if (!Selection(id)) {
|
if (!Selection(id)) {
|
||||||
@@ -582,8 +568,8 @@ int Inquiry(int id, BYTE *buf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DATAIN
|
// DATAIN
|
||||||
memset(buf, 0x00, sizeof(buf));
|
memset(buf, 0x00, 256);
|
||||||
count = DataIn(buf, 255);
|
count = DataIn(buf, 256);
|
||||||
if (count <= 0) {
|
if (count <= 0) {
|
||||||
result = -3;
|
result = -3;
|
||||||
goto exit;
|
goto exit;
|
||||||
@@ -625,6 +611,7 @@ int ReadCapacity(int id, BYTE *buf)
|
|||||||
|
|
||||||
// 結果コード初期化
|
// 結果コード初期化
|
||||||
result = 0;
|
result = 0;
|
||||||
|
count = 0;
|
||||||
|
|
||||||
// SELECTION
|
// SELECTION
|
||||||
if (!Selection(id)) {
|
if (!Selection(id)) {
|
||||||
@@ -641,7 +628,7 @@ int ReadCapacity(int id, BYTE *buf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DATAIN
|
// DATAIN
|
||||||
memset(buf, 0x00, sizeof(buf));
|
memset(buf, 0x00, 8);
|
||||||
count = DataIn(buf, 8);
|
count = DataIn(buf, 8);
|
||||||
if (count <= 0) {
|
if (count <= 0) {
|
||||||
result = -3;
|
result = -3;
|
||||||
@@ -684,6 +671,7 @@ int Read10(int id, DWORD bstart, DWORD blength, DWORD length, BYTE *buf)
|
|||||||
|
|
||||||
// 結果コード初期化
|
// 結果コード初期化
|
||||||
result = 0;
|
result = 0;
|
||||||
|
count = 0;
|
||||||
|
|
||||||
// SELECTION
|
// SELECTION
|
||||||
if (!Selection(id)) {
|
if (!Selection(id)) {
|
||||||
@@ -748,6 +736,7 @@ int Write10(int id, DWORD bstart, DWORD blength, DWORD length, BYTE *buf)
|
|||||||
|
|
||||||
// 結果コード初期化
|
// 結果コード初期化
|
||||||
result = 0;
|
result = 0;
|
||||||
|
count = 0;
|
||||||
|
|
||||||
// SELECTION
|
// SELECTION
|
||||||
if (!Selection(id)) {
|
if (!Selection(id)) {
|
||||||
@@ -815,7 +804,6 @@ int main(int argc, char* argv[])
|
|||||||
DWORD duni;
|
DWORD duni;
|
||||||
DWORD dsiz;
|
DWORD dsiz;
|
||||||
DWORD dnum;
|
DWORD dnum;
|
||||||
DWORD rest;
|
|
||||||
Fileio fio;
|
Fileio fio;
|
||||||
Fileio::OpenMode omode;
|
Fileio::OpenMode omode;
|
||||||
off64_t size;
|
off64_t size;
|
||||||
@@ -918,18 +906,21 @@ int main(int argc, char* argv[])
|
|||||||
(buffer[0] << 24) | (buffer[1] << 16) |
|
(buffer[0] << 24) | (buffer[1] << 16) |
|
||||||
(buffer[2] << 8) | buffer[3];
|
(buffer[2] << 8) | buffer[3];
|
||||||
bnum++;
|
bnum++;
|
||||||
printf("Number of blocks : %d Blocks\n", bnum);
|
printf("Number of blocks : %d Blocks\n", (int)bnum);
|
||||||
printf("Block length : %d Bytes\n", bsiz);
|
printf("Block length : %d Bytes\n", (int)bsiz);
|
||||||
printf("Unit Capacity : %d MBytes %d Bytes\n",
|
printf("Unit Capacity : %d MBytes %d Bytes\n",
|
||||||
bsiz * bnum / 1024 / 1024,
|
(int)(bsiz * bnum / 1024 / 1024),
|
||||||
bsiz * bnum);
|
(int)(bsiz * bnum));
|
||||||
|
|
||||||
// リストアファイルサイズの取得
|
// リストアファイルサイズの取得
|
||||||
if (restore) {
|
if (restore) {
|
||||||
size = fio.GetFileSize();
|
size = fio.GetFileSize();
|
||||||
printf("Restore file size : %d bytes", (int)size);
|
printf("Restore file size : %d bytes", (int)size);
|
||||||
if (size != (off64_t)(bsiz * bnum)) {
|
if (size > (off64_t)(bsiz * bnum)) {
|
||||||
printf("(WARNING : File size isn't equal to disk size)");
|
printf("(WARNING : File size is larger than disk size)");
|
||||||
|
} else if (size < (off64_t)(bsiz * bnum)) {
|
||||||
|
printf("(ERROR : File size is smaller than disk size)\n");
|
||||||
|
goto cleanup_exit;
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
@@ -947,12 +938,15 @@ int main(int argc, char* argv[])
|
|||||||
printf("Dump progress : ");
|
printf("Dump progress : ");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < dnum; i++) {
|
for (i = 0; i < (int)dnum; i++) {
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
printf("\033[21D");
|
printf("\033[21D");
|
||||||
printf("\033[0K");
|
printf("\033[0K");
|
||||||
}
|
}
|
||||||
printf("%3d\%(%7d/%7d)", (i + 1) * 100 / dnum, i * duni, bnum);
|
printf("%3d%%(%7d/%7d)",
|
||||||
|
(int)((i + 1) * 100 / dnum),
|
||||||
|
(int)(i * duni),
|
||||||
|
(int)bnum);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
if (restore) {
|
if (restore) {
|
||||||
@@ -974,13 +968,18 @@ int main(int argc, char* argv[])
|
|||||||
goto cleanup_exit;
|
goto cleanup_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dnum > 0) {
|
||||||
|
printf("\033[21D");
|
||||||
|
printf("\033[0K");
|
||||||
|
}
|
||||||
|
|
||||||
// 容量上の端数処理
|
// 容量上の端数処理
|
||||||
dnum = bnum % duni;
|
dnum = bnum % duni;
|
||||||
dsiz = dnum * bsiz;
|
dsiz = dnum * bsiz;
|
||||||
if (dnum > 0) {
|
if (dnum > 0) {
|
||||||
if (restore) {
|
if (restore) {
|
||||||
if (fio.Read(buffer, dsiz)) {
|
if (fio.Read(buffer, dsiz)) {
|
||||||
Write10(targetid, i * duni, duni, dsiz, buffer);
|
Write10(targetid, i * duni, dnum, dsiz, buffer);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (Read10(targetid, i * duni, dnum, dsiz, buffer) >= 0) {
|
if (Read10(targetid, i * duni, dnum, dsiz, buffer) >= 0) {
|
||||||
@@ -990,9 +989,7 @@ int main(int argc, char* argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 完了メッセージ
|
// 完了メッセージ
|
||||||
printf("\033[21D");
|
printf("%3d%%(%7d/%7d)\n", 100, (int)bnum, (int)bnum);
|
||||||
printf("\033[0K");
|
|
||||||
printf("%3d\%(%7d/%7d)\n", 100, bnum, bnum);
|
|
||||||
|
|
||||||
cleanup_exit:
|
cleanup_exit:
|
||||||
// ファイルクローズ
|
// ファイルクローズ
|
||||||
|
|||||||
819
src/raspberrypi/sasidump.cpp
Normal file
819
src/raspberrypi/sasidump.cpp
Normal file
@@ -0,0 +1,819 @@
|
|||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// SCSI Target Emulator RaSCSI (*^..^*)
|
||||||
|
// for Raspberry Pi
|
||||||
|
//
|
||||||
|
// Powered by XM6 TypeG Technology.
|
||||||
|
// Copyright (C) 2016-2020 GIMONS
|
||||||
|
// [ HDDダンプユーティリティ(イニシーエタモード/SASI Version) ]
|
||||||
|
//
|
||||||
|
// SASI IMAGE EXAMPLE
|
||||||
|
// X68000
|
||||||
|
// 10MB(10441728 BS=256 C=40788)
|
||||||
|
// 20MB(20748288 BS=256 C=81048)
|
||||||
|
// 40MB(41496576 BS=256 C=162096)
|
||||||
|
//
|
||||||
|
// MZ-2500/MZ-2800 MZ-1F23
|
||||||
|
// 20MB(22437888 BS=1024 C=21912)
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "os.h"
|
||||||
|
#include "xm6.h"
|
||||||
|
#include "fileio.h"
|
||||||
|
#include "filepath.h"
|
||||||
|
#include "gpiobus.h"
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// 定数宣言
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
#define BUFSIZE 1024 * 64 // 64KBぐらいかなぁ
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// 変数宣言
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
GPIOBUS bus; // バス
|
||||||
|
int targetid; // ターゲットデバイスID
|
||||||
|
int unitid; // ターゲットユニットID
|
||||||
|
int bsiz; // ブロックサイズ
|
||||||
|
int bnum; // ブロック数
|
||||||
|
Filepath hdffile; // HDFファイル
|
||||||
|
BOOL restore; // リストアフラグ
|
||||||
|
BYTE buffer[BUFSIZE]; // ワークバッファ
|
||||||
|
int result; // 結果コード
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// 関数宣言
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
void Cleanup();
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// シグナル処理
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
void KillHandler(int sig)
|
||||||
|
{
|
||||||
|
// 停止指示
|
||||||
|
Cleanup();
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// バナー出力
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
BOOL Banner(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
printf("RaSCSI hard disk dump utility(SASI HDD) ");
|
||||||
|
printf("version %01d.%01d%01d\n",
|
||||||
|
(int)((VERSION >> 8) & 0xf),
|
||||||
|
(int)((VERSION >> 4) & 0xf),
|
||||||
|
(int)((VERSION ) & 0xf));
|
||||||
|
|
||||||
|
if (argc < 2 || strcmp(argv[1], "-h") == 0) {
|
||||||
|
printf("Usage: %s -i ID [-u UT] [-b BSIZE] -c COUNT -f FILE [-r]\n", argv[0]);
|
||||||
|
printf(" ID is target device SASI ID {0|1|2|3|4|5|6|7}.\n");
|
||||||
|
printf(" UT is target unit ID {0|1}. Default is 0.\n");
|
||||||
|
printf(" BSIZE is block size {256|512|1024}. Default is 256.\n");
|
||||||
|
printf(" COUNT is block count.\n");
|
||||||
|
printf(" FILE is HDF file path.\n");
|
||||||
|
printf(" -r is restore operation.\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// 初期化
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
BOOL Init()
|
||||||
|
{
|
||||||
|
// 割り込みハンドラ設定
|
||||||
|
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(BUS::INITIATOR)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ワーク初期化
|
||||||
|
targetid = -1;
|
||||||
|
unitid = 0;
|
||||||
|
bsiz = 256;
|
||||||
|
bnum = -1;
|
||||||
|
restore = FALSE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// クリーンアップ
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
void Cleanup()
|
||||||
|
{
|
||||||
|
// バスをクリーンアップ
|
||||||
|
bus.Cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// リセット
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
void Reset()
|
||||||
|
{
|
||||||
|
// バス信号線をリセット
|
||||||
|
bus.Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// 引数処理
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
BOOL ParseArgument(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
int opt;
|
||||||
|
char *file;
|
||||||
|
|
||||||
|
// 初期化
|
||||||
|
file = NULL;
|
||||||
|
|
||||||
|
// 引数解析
|
||||||
|
opterr = 0;
|
||||||
|
while ((opt = getopt(argc, argv, "i:u:b:c:f:r")) != -1) {
|
||||||
|
switch (opt) {
|
||||||
|
case 'i':
|
||||||
|
targetid = optarg[0] - '0';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'u':
|
||||||
|
unitid = optarg[0] - '0';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'b':
|
||||||
|
bsiz = atoi(optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'c':
|
||||||
|
bnum = atoi(optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'f':
|
||||||
|
file = optarg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'r':
|
||||||
|
restore = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TARGET IDチェック
|
||||||
|
if (targetid < 0 || targetid > 7) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Error : Invalid target id range\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// UNIT IDチェック
|
||||||
|
if (unitid < 0 || unitid > 1) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Error : Invalid unit id range\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// BSIZチェック
|
||||||
|
if (bsiz != 256 && bsiz != 512 && bsiz != 1024) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Error : Invalid block size\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// BNUMチェック
|
||||||
|
if (bnum < 0) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Error : Invalid block count\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ファイルチェック
|
||||||
|
if (!file) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Error : Invalid file path\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
hdffile.SetPath(file);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// フェーズ待ち
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
BOOL WaitPhase(BUS::phase_t phase)
|
||||||
|
{
|
||||||
|
DWORD now;
|
||||||
|
|
||||||
|
// タイムアウト(3000ms)
|
||||||
|
now = SysTimer::GetTimerLow();
|
||||||
|
while ((SysTimer::GetTimerLow() - now) < 3 * 1000 * 1000) {
|
||||||
|
bus.Aquire();
|
||||||
|
if (bus.GetREQ() && bus.GetPhase() == phase) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// バスフリーフェーズ実行
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
void BusFree()
|
||||||
|
{
|
||||||
|
// バスリセット
|
||||||
|
bus.Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// セレクションフェーズ実行
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
BOOL Selection(int id)
|
||||||
|
{
|
||||||
|
BYTE data;
|
||||||
|
int count;
|
||||||
|
|
||||||
|
// ID設定とSELアサート
|
||||||
|
data = 0;
|
||||||
|
data |= (1 << id);
|
||||||
|
bus.SetDAT(data);
|
||||||
|
bus.SetSEL(TRUE);
|
||||||
|
|
||||||
|
// BSYを待つ
|
||||||
|
count = 10000;
|
||||||
|
do {
|
||||||
|
usleep(20);
|
||||||
|
bus.Aquire();
|
||||||
|
if (bus.GetBSY()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (count--);
|
||||||
|
|
||||||
|
// SELネゲート
|
||||||
|
bus.SetSEL(FALSE);
|
||||||
|
|
||||||
|
// ターゲットがビジー状態なら成功
|
||||||
|
return bus.GetBSY();
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// コマンドフェーズ実行
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
BOOL Command(BYTE *buf, int length)
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
|
||||||
|
// フェーズ待ち
|
||||||
|
if (!WaitPhase(BUS::command)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// コマンド送信
|
||||||
|
count = bus.SendHandShake(buf, length);
|
||||||
|
|
||||||
|
// 送信結果が依頼数と同じなら成功
|
||||||
|
if (count == length) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 送信エラー
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// データインフェーズ実行
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
int DataIn(BYTE *buf, int length)
|
||||||
|
{
|
||||||
|
// フェーズ待ち
|
||||||
|
if (!WaitPhase(BUS::datain)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// データ受信
|
||||||
|
return bus.ReceiveHandShake(buf, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// データアウトフェーズ実行
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
int DataOut(BYTE *buf, int length)
|
||||||
|
{
|
||||||
|
// フェーズ待ち
|
||||||
|
if (!WaitPhase(BUS::dataout)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// データ受信
|
||||||
|
return bus.SendHandShake(buf, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// ステータスフェーズ実行
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
int Status()
|
||||||
|
{
|
||||||
|
BYTE buf[256];
|
||||||
|
|
||||||
|
// フェーズ待ち
|
||||||
|
if (!WaitPhase(BUS::status)) {
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// データ受信
|
||||||
|
if (bus.ReceiveHandShake(buf, 1) == 1) {
|
||||||
|
return (int)buf[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 受信エラー
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// メッセージインフェーズ実行
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
int MessageIn()
|
||||||
|
{
|
||||||
|
BYTE buf[256];
|
||||||
|
|
||||||
|
// フェーズ待ち
|
||||||
|
if (!WaitPhase(BUS::msgin)) {
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// データ受信
|
||||||
|
if (bus.ReceiveHandShake(buf, 1) == 1) {
|
||||||
|
return (int)buf[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 受信エラー
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// TEST UNIT READY実行
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
int TestUnitReady(int id)
|
||||||
|
{
|
||||||
|
BYTE cmd[256];
|
||||||
|
|
||||||
|
// 結果コード初期化
|
||||||
|
result = 0;
|
||||||
|
|
||||||
|
// SELECTION
|
||||||
|
if (!Selection(id)) {
|
||||||
|
result = -1;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// COMMAND
|
||||||
|
memset(cmd, 0x00, 6);
|
||||||
|
cmd[0] = 0x00;
|
||||||
|
cmd[1] = unitid << 5;
|
||||||
|
if (!Command(cmd, 6)) {
|
||||||
|
result = -2;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// STATUS
|
||||||
|
if (Status() < 0) {
|
||||||
|
result = -4;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// MESSAGE IN
|
||||||
|
if (MessageIn() < 0) {
|
||||||
|
result = -5;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
// バスフリー
|
||||||
|
BusFree();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// REQUEST SENSE実行
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
int RequestSense(int id, BYTE *buf)
|
||||||
|
{
|
||||||
|
BYTE cmd[256];
|
||||||
|
int count;
|
||||||
|
|
||||||
|
// 結果コード初期化
|
||||||
|
result = 0;
|
||||||
|
count = 0;
|
||||||
|
|
||||||
|
// SELECTION
|
||||||
|
if (!Selection(id)) {
|
||||||
|
result = -1;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// COMMAND
|
||||||
|
memset(cmd, 0x00, 6);
|
||||||
|
cmd[0] = 0x03;
|
||||||
|
cmd[1] = unitid << 5;
|
||||||
|
cmd[4] = 4;
|
||||||
|
if (!Command(cmd, 6)) {
|
||||||
|
result = -2;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DATAIN
|
||||||
|
memset(buf, 0x00, 256);
|
||||||
|
count = DataIn(buf, 256);
|
||||||
|
if (count <= 0) {
|
||||||
|
result = -3;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// STATUS
|
||||||
|
if (Status() < 0) {
|
||||||
|
result = -4;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// MESSAGE IN
|
||||||
|
if (MessageIn() < 0) {
|
||||||
|
result = -5;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
// バスフリー
|
||||||
|
BusFree();
|
||||||
|
|
||||||
|
// 成功であれば転送数を返す
|
||||||
|
if (result == 0) {
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// READ6実行
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
int Read6(int id, DWORD bstart, DWORD blength, DWORD length, BYTE *buf)
|
||||||
|
{
|
||||||
|
BYTE cmd[256];
|
||||||
|
int count;
|
||||||
|
|
||||||
|
// 結果コード初期化
|
||||||
|
result = 0;
|
||||||
|
count = 0;
|
||||||
|
|
||||||
|
// SELECTION
|
||||||
|
if (!Selection(id)) {
|
||||||
|
result = -1;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// COMMAND
|
||||||
|
memset(cmd, 0x00, 10);
|
||||||
|
cmd[0] = 0x8;
|
||||||
|
cmd[1] = (BYTE)(bstart >> 16);
|
||||||
|
cmd[1] &= 0x1f;
|
||||||
|
cmd[1] = unitid << 5;
|
||||||
|
cmd[2] = (BYTE)(bstart >> 8);
|
||||||
|
cmd[3] = (BYTE)bstart;
|
||||||
|
cmd[4] = (BYTE)blength;
|
||||||
|
if (!Command(cmd, 6)) {
|
||||||
|
result = -2;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DATAIN
|
||||||
|
count = DataIn(buf, length);
|
||||||
|
if (count <= 0) {
|
||||||
|
result = -3;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// STATUS
|
||||||
|
if (Status() < 0) {
|
||||||
|
result = -4;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// MESSAGE IN
|
||||||
|
if (MessageIn() < 0) {
|
||||||
|
result = -5;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
// バスフリー
|
||||||
|
BusFree();
|
||||||
|
|
||||||
|
// 成功であれば転送数を返す
|
||||||
|
if (result == 0) {
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// WRITE6実行
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
int Write6(int id, DWORD bstart, DWORD blength, DWORD length, BYTE *buf)
|
||||||
|
{
|
||||||
|
BYTE cmd[256];
|
||||||
|
int count;
|
||||||
|
|
||||||
|
// 結果コード初期化
|
||||||
|
result = 0;
|
||||||
|
count = 0;
|
||||||
|
|
||||||
|
// SELECTION
|
||||||
|
if (!Selection(id)) {
|
||||||
|
result = -1;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// COMMAND
|
||||||
|
memset(cmd, 0x00, 10);
|
||||||
|
cmd[0] = 0xa;
|
||||||
|
cmd[1] = (BYTE)(bstart >> 16);
|
||||||
|
cmd[1] &= 0x1f;
|
||||||
|
cmd[1] = unitid << 5;
|
||||||
|
cmd[2] = (BYTE)(bstart >> 8);
|
||||||
|
cmd[3] = (BYTE)bstart;
|
||||||
|
cmd[4] = (BYTE)blength;
|
||||||
|
if (!Command(cmd, 6)) {
|
||||||
|
result = -2;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DATAOUT
|
||||||
|
count = DataOut(buf, length);
|
||||||
|
if (count <= 0) {
|
||||||
|
result = -3;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// STATUS
|
||||||
|
if (Status() < 0) {
|
||||||
|
result = -4;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// MESSAGE IN
|
||||||
|
if (MessageIn() < 0) {
|
||||||
|
result = -5;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
// バスフリー
|
||||||
|
BusFree();
|
||||||
|
|
||||||
|
// 成功であれば転送数を返す
|
||||||
|
if (result == 0) {
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// 主処理
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int count;
|
||||||
|
DWORD duni;
|
||||||
|
DWORD dsiz;
|
||||||
|
DWORD dnum;
|
||||||
|
Fileio fio;
|
||||||
|
Fileio::OpenMode omode;
|
||||||
|
off64_t size;
|
||||||
|
|
||||||
|
// バナー出力
|
||||||
|
if (!Banner(argc, argv)) {
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初期化
|
||||||
|
if (!Init()) {
|
||||||
|
fprintf(stderr, "Error : Initializing\n");
|
||||||
|
|
||||||
|
// 恐らくrootでは無い?
|
||||||
|
exit(EPERM);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 構築
|
||||||
|
if (!ParseArgument(argc, argv)) {
|
||||||
|
// クリーンアップ
|
||||||
|
Cleanup();
|
||||||
|
|
||||||
|
// 引数エラーで終了
|
||||||
|
exit(EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// リセット
|
||||||
|
Reset();
|
||||||
|
|
||||||
|
// ファイルオープン
|
||||||
|
if (restore) {
|
||||||
|
omode = Fileio::ReadOnly;
|
||||||
|
} else {
|
||||||
|
omode = Fileio::WriteOnly;
|
||||||
|
}
|
||||||
|
if (!fio.Open(hdffile.GetPath(), omode)) {
|
||||||
|
fprintf(stderr, "Error : Can't open hdf file\n");
|
||||||
|
|
||||||
|
// クリーンアップ
|
||||||
|
Cleanup();
|
||||||
|
exit(EPERM);
|
||||||
|
}
|
||||||
|
|
||||||
|
// バスフリー
|
||||||
|
BusFree();
|
||||||
|
|
||||||
|
// RESETシグナル発行
|
||||||
|
bus.SetRST(TRUE);
|
||||||
|
usleep(1000);
|
||||||
|
bus.SetRST(FALSE);
|
||||||
|
|
||||||
|
// ダンプ開始
|
||||||
|
printf("TARGET ID : %d\n", targetid);
|
||||||
|
printf("UNIT ID : %d\n", unitid);
|
||||||
|
|
||||||
|
// TEST UNIT READY
|
||||||
|
count = TestUnitReady(targetid);
|
||||||
|
if (count < 0) {
|
||||||
|
fprintf(stderr, "TEST UNIT READY ERROR %d\n", count);
|
||||||
|
goto cleanup_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// REQUEST SENSE(for CHECK CONDITION)
|
||||||
|
count = RequestSense(targetid, buffer);
|
||||||
|
if (count < 0) {
|
||||||
|
fprintf(stderr, "REQUEST SENSE ERROR %d\n", count);
|
||||||
|
goto cleanup_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ブロックサイズとブロック数の表示
|
||||||
|
printf("Number of blocks : %d Blocks\n", bnum);
|
||||||
|
printf("Block length : %d Bytes\n", bsiz);
|
||||||
|
|
||||||
|
// データサイズの表示
|
||||||
|
printf("Total length : %d MBytes %d Bytes\n",
|
||||||
|
(bsiz * bnum / 1024 / 1024),
|
||||||
|
(bsiz * bnum));
|
||||||
|
|
||||||
|
// リストアファイルサイズの取得
|
||||||
|
if (restore) {
|
||||||
|
size = fio.GetFileSize();
|
||||||
|
printf("Restore file size : %d bytes", (int)size);
|
||||||
|
if (size > (off64_t)(bsiz * bnum)) {
|
||||||
|
printf("(WARNING : File size is larger than disk size)");
|
||||||
|
} else if (size < (off64_t)(bsiz * bnum)) {
|
||||||
|
printf("(ERROR : File size is smaller than disk size)\n");
|
||||||
|
goto cleanup_exit;
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// バッファサイズ毎にダンプする
|
||||||
|
duni = BUFSIZE;
|
||||||
|
duni /= bsiz;
|
||||||
|
dsiz = BUFSIZE;
|
||||||
|
dnum = bnum * bsiz;
|
||||||
|
dnum /= BUFSIZE;
|
||||||
|
|
||||||
|
if (restore) {
|
||||||
|
printf("Restore progress : ");
|
||||||
|
} else {
|
||||||
|
printf("Dump progress : ");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < (int)dnum; i++) {
|
||||||
|
if (i > 0) {
|
||||||
|
printf("\033[21D");
|
||||||
|
printf("\033[0K");
|
||||||
|
}
|
||||||
|
printf("%3d%%(%7d/%7d)",
|
||||||
|
(int)((i + 1) * 100 / dnum),
|
||||||
|
(int)(i * duni),
|
||||||
|
bnum);
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
|
if (restore) {
|
||||||
|
if (fio.Read(buffer, dsiz)) {
|
||||||
|
if (Write6(targetid, i * duni, duni, dsiz, buffer) >= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (Read6(targetid, i * duni, duni, dsiz, buffer) >= 0) {
|
||||||
|
if (fio.Write(buffer, dsiz)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
printf("Error occured and aborted... %d\n", result);
|
||||||
|
goto cleanup_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dnum > 0) {
|
||||||
|
printf("\033[21D");
|
||||||
|
printf("\033[0K");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 容量上の端数処理
|
||||||
|
dnum = bnum % duni;
|
||||||
|
dsiz = dnum * bsiz;
|
||||||
|
|
||||||
|
if (dnum > 0) {
|
||||||
|
if (restore) {
|
||||||
|
if (fio.Read(buffer, dsiz)) {
|
||||||
|
Write6(targetid, i * duni, dnum, dsiz, buffer);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (Read6(targetid, i * duni, dnum, dsiz, buffer) >= 0) {
|
||||||
|
fio.Write(buffer, dsiz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 完了メッセージ
|
||||||
|
printf("%3d%%(%7d/%7d)\n", 100, bnum, bnum);
|
||||||
|
|
||||||
|
cleanup_exit:
|
||||||
|
// ファイルクローズ
|
||||||
|
fio.Close();
|
||||||
|
|
||||||
|
// クリーンアップ
|
||||||
|
Cleanup();
|
||||||
|
|
||||||
|
// 終了
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
// X68000 EMULATOR "XM6"
|
// X68000 EMULATOR "XM6"
|
||||||
//
|
//
|
||||||
// Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp)
|
// Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp)
|
||||||
// Copyright (C) 2014-2018 GIMONS
|
// Copyright (C) 2014-2020 GIMONS
|
||||||
//
|
//
|
||||||
// [ SCSI共通 ]
|
// [ SCSI共通 ]
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
// X68000 EMULATOR "XM6"
|
// X68000 EMULATOR "XM6"
|
||||||
//
|
//
|
||||||
// Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp)
|
// Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp)
|
||||||
// Copyright (C) 2014-2018 GIMONS
|
// Copyright (C) 2014-2020 GIMONS
|
||||||
//
|
//
|
||||||
// [ SCSI共通 ]
|
// [ SCSI共通 ]
|
||||||
//
|
//
|
||||||
@@ -111,15 +111,16 @@ public:
|
|||||||
// データシグナル取得
|
// データシグナル取得
|
||||||
virtual void FASTCALL SetDAT(BYTE dat) = 0;
|
virtual void FASTCALL SetDAT(BYTE dat) = 0;
|
||||||
// データシグナル設定
|
// データシグナル設定
|
||||||
|
virtual BOOL FASTCALL GetDP() = 0;
|
||||||
|
// パリティシグナル取得
|
||||||
|
|
||||||
|
virtual int FASTCALL CommandHandShake(BYTE *buf) = 0;
|
||||||
|
// コマンド受信ハンドシェイク
|
||||||
virtual int FASTCALL ReceiveHandShake(BYTE *buf, int count) = 0;
|
virtual int FASTCALL ReceiveHandShake(BYTE *buf, int count) = 0;
|
||||||
// データ受信ハンドシェイク
|
// データ受信ハンドシェイク
|
||||||
virtual int FASTCALL SendHandShake(BYTE *buf, int count) = 0;
|
virtual int FASTCALL SendHandShake(BYTE *buf, int count) = 0;
|
||||||
// データ送信ハンドシェイク
|
// データ送信ハンドシェイク
|
||||||
|
|
||||||
virtual void FASTCALL SleepNsec(DWORD nsec) = 0;
|
|
||||||
// ナノ秒単位のスリープ
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const phase_t phase_table[8];
|
static const phase_t phase_table[8];
|
||||||
// フェーズテーブル
|
// フェーズテーブル
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
// for Raspberry Pi
|
// for Raspberry Pi
|
||||||
//
|
//
|
||||||
// Powered by XM6 TypeG Technology.
|
// Powered by XM6 TypeG Technology.
|
||||||
// Copyright (C) 2016-2018 GIMONS
|
// Copyright (C) 2016-2020 GIMONS
|
||||||
//
|
//
|
||||||
// [ 共通定義 ]
|
// [ 共通定義 ]
|
||||||
//
|
//
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
// VERSION
|
// VERSION
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
#define VERSION 0x0134
|
#define VERSION 0x0147
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
@@ -34,6 +34,15 @@
|
|||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
#define MAKEID(a, b, c, d) ((DWORD)((a<<24) | (b<<16) | (c<<8) | d))
|
#define MAKEID(a, b, c, d) ((DWORD)((a<<24) | (b<<16) | (c<<8) | d))
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// 各種動作設定
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
#define USE_SEL_EVENT_ENABLE // SEL信号をイベントでチェックする
|
||||||
|
#define REMOVE_FIXED_SASIHD_SIZE // SASIHDのサイズ制限を解除する
|
||||||
|
#define USE_MZ1F23_1024_SUPPORT // MZ-1F23(SASI 20M/セクタサイズ1024)
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// クラス宣言
|
// クラス宣言
|
||||||
|
|||||||
@@ -852,6 +852,28 @@ int FS_GetCapacity(capacity_t* cap)
|
|||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
int FS_CtrlDrive(ctrldrive_t* pCtrlDrive)
|
int FS_CtrlDrive(ctrldrive_t* pCtrlDrive)
|
||||||
{
|
{
|
||||||
|
#if 1
|
||||||
|
// 負荷が高いのでここで暫定処理
|
||||||
|
switch (pCtrlDrive->status) {
|
||||||
|
case 0: // 状態検査
|
||||||
|
case 9: // 状態検査2
|
||||||
|
pCtrlDrive->status = 0x42;
|
||||||
|
return pCtrlDrive->status;
|
||||||
|
case 1: // イジェクト
|
||||||
|
case 2: // イジェクト禁止1 (未実装)
|
||||||
|
case 3: // イジェクト許可1 (未実装)
|
||||||
|
case 4: // メディア未挿入時にLED点滅 (未実装)
|
||||||
|
case 5: // メディア未挿入時にLED消灯 (未実装)
|
||||||
|
case 6: // イジェクト禁止2 (未実装)
|
||||||
|
case 7: // イジェクト許可2 (未実装)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case 8: // イジェクト検査
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
#else
|
||||||
BYTE buf[256];
|
BYTE buf[256];
|
||||||
DWORD *dp;
|
DWORD *dp;
|
||||||
int i;
|
int i;
|
||||||
@@ -865,6 +887,7 @@ int FS_CtrlDrive(ctrldrive_t* pCtrlDrive)
|
|||||||
i += sizeof(ctrldrive_t);
|
i += sizeof(ctrldrive_t);
|
||||||
|
|
||||||
return SCSI_CalCmd(buf, i, (BYTE*)pCtrlDrive, sizeof(ctrldrive_t));
|
return SCSI_CalCmd(buf, i, (BYTE*)pCtrlDrive, sizeof(ctrldrive_t));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
@@ -962,6 +985,10 @@ int FS_Ioctrl(DWORD nFunction, ioctrl_t* pIoctrl)
|
|||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
int FS_Flush()
|
int FS_Flush()
|
||||||
{
|
{
|
||||||
|
#if 1
|
||||||
|
// 未サポート
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
BYTE buf[256];
|
BYTE buf[256];
|
||||||
DWORD *dp;
|
DWORD *dp;
|
||||||
|
|
||||||
@@ -969,6 +996,7 @@ int FS_Flush()
|
|||||||
*dp = unit;
|
*dp = unit;
|
||||||
|
|
||||||
return SCSI_SendCmd(buf, 4);
|
return SCSI_SendCmd(buf, 4);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
@@ -978,6 +1006,10 @@ int FS_Flush()
|
|||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
int FS_CheckMedia()
|
int FS_CheckMedia()
|
||||||
{
|
{
|
||||||
|
#if 1
|
||||||
|
// 負荷が高いので暫定処理
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
BYTE buf[256];
|
BYTE buf[256];
|
||||||
DWORD *dp;
|
DWORD *dp;
|
||||||
|
|
||||||
@@ -985,6 +1017,7 @@ int FS_CheckMedia()
|
|||||||
*dp = unit;
|
*dp = unit;
|
||||||
|
|
||||||
return SCSI_SendCmd(buf, 4);
|
return SCSI_SendCmd(buf, 4);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
@@ -994,6 +1027,10 @@ int FS_CheckMedia()
|
|||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
int FS_Lock()
|
int FS_Lock()
|
||||||
{
|
{
|
||||||
|
#if 1
|
||||||
|
// 未サポート
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
BYTE buf[256];
|
BYTE buf[256];
|
||||||
DWORD *dp;
|
DWORD *dp;
|
||||||
|
|
||||||
@@ -1001,6 +1038,7 @@ int FS_Lock()
|
|||||||
*dp = unit;
|
*dp = unit;
|
||||||
|
|
||||||
return SCSI_SendCmd(buf, 4);
|
return SCSI_SendCmd(buf, 4);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
@@ -2277,25 +2315,11 @@ DWORD Flush(void)
|
|||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
DWORD CheckMedia(void)
|
DWORD CheckMedia(void)
|
||||||
{
|
{
|
||||||
#if 1
|
|
||||||
static DWORD last = 0;
|
|
||||||
DWORD now;
|
|
||||||
#endif
|
|
||||||
int nResult;
|
int nResult;
|
||||||
|
|
||||||
ASSERT(this);
|
ASSERT(this);
|
||||||
ASSERT(fs);
|
ASSERT(fs);
|
||||||
|
|
||||||
#if 1
|
|
||||||
// 連続で呼び出されるの回避する
|
|
||||||
now = TIMEGET();
|
|
||||||
if ((now - last) < 3) {
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
last = now;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ファイルシステム呼び出し
|
// ファイルシステム呼び出し
|
||||||
nResult = FS_CheckMedia();
|
nResult = FS_CheckMedia();
|
||||||
|
|
||||||
@@ -2366,17 +2390,9 @@ DWORD ExecuteCommand()
|
|||||||
case 0x53: return DiskRead(); // $53 - セクタ読み込み
|
case 0x53: return DiskRead(); // $53 - セクタ読み込み
|
||||||
case 0x54: return DiskWrite(); // $54 - セクタ書き込み
|
case 0x54: return DiskWrite(); // $54 - セクタ書き込み
|
||||||
case 0x55: return Ioctrl(); // $55 - IOCTRL
|
case 0x55: return Ioctrl(); // $55 - IOCTRL
|
||||||
#if 0
|
|
||||||
case 0x56: return Flush(); // $56 - フラッシュ
|
case 0x56: return Flush(); // $56 - フラッシュ
|
||||||
#else
|
|
||||||
case 0x56: return 0; // $56 - フラッシュ
|
|
||||||
#endif
|
|
||||||
case 0x57: return CheckMedia(); // $57 - メディア交換チェック
|
case 0x57: return CheckMedia(); // $57 - メディア交換チェック
|
||||||
#if 0
|
|
||||||
case 0x58: return Lock(); // $58 - 排他制御
|
case 0x58: return Lock(); // $58 - 排他制御
|
||||||
#else
|
|
||||||
case 0x58: return 0; // $58 - 排他制御
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return FS_FATAL_INVALIDCOMMAND;
|
return FS_FATAL_INVALIDCOMMAND;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
* for Raspberry Pi
|
* for Raspberry Pi
|
||||||
*
|
*
|
||||||
* Powered by XM6 TypeG Technorogy.
|
* Powered by XM6 TypeG Technorogy.
|
||||||
* Copyright (C) 2016-2017 GIMONS
|
* Copyright (C) 2016-2019 GIMONS
|
||||||
* [ ホストファイルシステム ブリッジドライバ ]
|
* [ ホストファイルシステム ブリッジドライバ ]
|
||||||
*
|
*
|
||||||
* Based on
|
* Based on
|
||||||
@@ -165,7 +165,7 @@ MESSAGE_DRIVENAME3:
|
|||||||
MESSAGE_TITLE:
|
MESSAGE_TITLE:
|
||||||
DC.B $0D,$0A
|
DC.B $0D,$0A
|
||||||
MESSAGE_TITLE2:
|
MESSAGE_TITLE2:
|
||||||
DC.B 'RaSCSI FileSystem Driver version 1.21',$0D,$0A,0
|
DC.B 'RaSCSI FileSystem Driver version 1.42',$0D,$0A,0
|
||||||
|
|
||||||
*ありがとう!
|
*ありがとう!
|
||||||
CREDIT:
|
CREDIT:
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
RaSCSI ファイルシステムドライバ
|
RaSCSI ファイルシステムドライバ
|
||||||
RASDRV version 1.21
|
RASDRV version 1.42
|
||||||
|
|
||||||
■概要
|
■概要
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user