diff --git a/RASCSI_webpage_translated.pdf b/RASCSI_webpage_translated.pdf index 83f834ee..d7ec3d69 100644 Binary files a/RASCSI_webpage_translated.pdf and b/RASCSI_webpage_translated.pdf differ diff --git a/README.md b/README.md index 54161d2f..a5cec848 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,6 @@ -For convenience this is a dump of the RASCSI archive RaSCSI version 1.34 available at: -http://www.geocities.jp/kugimoto0715/rascsi/index.html +For convenience this is a dump of the RASCSI archive RaSCSI version 1.47 available at: +http://retropc.net/gimons/rascsi/ 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... diff --git a/bin/raspberrypi/rascsi.tar.gz b/bin/raspberrypi/rascsi.tar.gz index 61b0b19e..69ee45f3 100644 Binary files a/bin/raspberrypi/rascsi.tar.gz and b/bin/raspberrypi/rascsi.tar.gz differ diff --git a/bin/x68k/RASDRIVER.HDF b/bin/x68k/RASDRIVER.HDF new file mode 100644 index 00000000..a5f97ca1 Binary files /dev/null and b/bin/x68k/RASDRIVER.HDF differ diff --git a/bin/x68k/RASDRIVER.HDS b/bin/x68k/RASDRIVER.HDS new file mode 100644 index 00000000..40c60b88 Binary files /dev/null and b/bin/x68k/RASDRIVER.HDS differ diff --git a/bin/x68k/RASDRIVER.XDF b/bin/x68k/RASDRIVER.XDF new file mode 100644 index 00000000..efcfce30 Binary files /dev/null and b/bin/x68k/RASDRIVER.XDF differ diff --git a/bin/x68k/RASDRV.SYS b/bin/x68k/RASDRV.SYS deleted file mode 100644 index 72700ab6..00000000 Binary files a/bin/x68k/RASDRV.SYS and /dev/null differ diff --git a/bin/x68k/RASETHER.SYS b/bin/x68k/RASETHER.SYS deleted file mode 100644 index 9e5fd2de..00000000 Binary files a/bin/x68k/RASETHER.SYS and /dev/null differ diff --git a/doc/converter.txt b/doc/converter.txt index b9b2fe42..25ea42a7 100644 --- a/doc/converter.txt +++ b/doc/converter.txt @@ -1,158 +1,116 @@ ------------------------------------------------------------------------------- - - SCSI Target Emulator RaSCSI (*^..^*) - version 1.33 for Raspberry Pi - - Powered by XM6 TypeG Technology. - Copyright (C) 2016-2018 GIMONS - ------------------------------------------------------------------------------- - -□変換基板の必要性について - SCSIはTTLレベルで5Vを220Ωと330Ωで分圧(パッシブターミネータの場合)する - ことで各信号線に3V弱の電圧がかかった状態が定常状態(信号的にはネゲート)に - なっています。 - - イニシエータ側もしくはターゲット側が信号をアサートする(=0V)にしようと - すると両端のターミネータから合わせて5000÷220×2=45mAの電流が流れることに - なります(X68000のSCSIコントローラであるMB89352のデータシートを見ればシンク - 電流としてIol48mAとなっています)。 - - RPIのGPIOはこのような大きなシンク電流は吸収できません。電気的に安全な接続 - を行うためには汎用ロジックIC等で変換基板を作る必要があります。汎用ロジック - ICで48mAものシンク電流に耐えるのは74LS06とか07といったオープンコレクタで - ハイパワータイプのものを使用します。 - - 作者は74HC541×3,74HC126×1,74HC04×1で基本的なSCSIの方向制御を行い更に - 74LS07×3を使ってバスをドライブする回路を組んでみたところ問題なく動作する - ことを確認しました。 - - 他にも74LS641の派生版である74LS641-1を使用すると回路はシンプルに構成できる - でしょう。ノーマル品と違ってシンク電流が48mA対応なので74LS07を使用する必要 - はありません。しかし入手性はそれほど良くありません。 - -□変換基板の回路図案 - 同じフォルダに回路図案を入れています。 - - ・target.png - SCSIのターゲットモードを使用するための変換基板回路図です。基本機能である - HDDやMOのエミュレーションを行うのであればこの回路図相当の物を作れば良い - でしょう。使用するGPIOピンも最も少ない構成になります。 - - ピンアサインを変更しなければRaSCSIのstandardディレクトリに含まれる - バイナリを使用することが可能です。 - - ・initiator.png - SCSIのターゲットモードに加えイニシエータモードを使用するための変換基板 - 回路図です。基本機能に加えてRPIがイニシエータとなって物理HDDにコマンド - を発行することが可能になります。モードの制御に追加で一つGPIOピンを消費 - します。このイニシエータモードを使用したサンプルプログラムとしてrasdump - を用意しました。実HDDやMOからイメージファイルにダンプすることができます。 - オプションでリストア機能も使用できます。 - - ピンアサインのカスタマイズでPIN_INDに標準では7を設定してコンパイルする - 必要があります。ピンアサインのカスタマイズを参照してください。 - - ・fullspec.png - SCSIのターゲットモード、イニシエータモードに加えてSCSIの通信をモニター - することができる変換基板回路図です。SCSIプロトコロルを解析する等の特殊 - 要件がある場合はこの回路が最適です。全ての74LS641-1の方向制御をRaSCSI - から行いますのでGPIOピンを三つ余分に使用してしまいます。SCSIの開発に - 興味があればこの回路を組んでみてはどうでしょうか。特徴としてGPIOピン - を余分に使用する代わりに上のイニシエータモードが使用できる基板と比較 - して74LS86が必要にならないため基板がシンプルになるという恩恵があります。 - - ピンアサインのカスタマイズで、PIN_TAD,PIN_IND,PIN_DTDにそれぞれ標準 - では6,7,8を設定してコンパイルする必要があります。ピンアサインの - カスタマイズを参照してください。 - -□既存のものを手に入れる方法 - 最近では主にTwitter界隈を通じてRaSCSI用の変換基板を作成していただいて - いる方々がいらっしゃいます。 - - また秋葉原で委託販売されてます。 - - 家電のKENCHAN 同人ハード(キット)のページ等です。 - http://www.kadenken.com/shopbrand/ct76/" - - 現在のところ市販されているものとして - - ・BELさん開発のあいぼむ版 - ・tomcatさん開発のGAMERnium版 - - があります。 - -□ピンアサインのカスタマイズ - GPIOの信号制御論理やピンアサインはgpiobus.hとrascsidrv.cに定義があります。 - 定義が分かれているのはrascsidrv.cだけGPLなので敢えて分離しています。 - 御察し下さい。 - - カスタマイズ例としてgpiobus.hとrascsidrv.cに下記の二つの変換基板用定義例を - 用意しました。配布物の中にはコンパイル済みバイナリも含まれています。 - - ・BELさん開発のあいぼむ版 - ・tomcatさん開発のGAMERnium版 - -□カスタマイズ方法 - ・RaSCSI起動時のメッセージです。 - CONNECT_DESC - - ・信号制御モードを選択します。 - SIGNAL_CONTROL_MODE - - 0:SCSI論理仕様 - 直結またはHPに公開した74LS641-1等を使用する変換基板 - アーサート:0V - ネゲート :オープンコレクタ出力(バスから切り離す) - - 1:負論理仕様(負論理->SCSI論理への変換基板を使用する場合) - 現時点でこの仕様による変換基板は存在しません - アーサート:0V -> (CONVERT) -> 0V - ネゲート :3.3V -> (CONVERT) -> オープンコレクタ出力 - - 2:正論理仕様(正論理->SCSI論理への変換基板を使用する場合) - RaSCSI Adapter Rev.C @132sync等 - - アーサート:3.3V -> (CONVERT) -> 0V - ネゲート :0V -> (CONVERT) -> オープンコレクタ出力 - - ・制御信号ピンアサイン - PIN_ACT:SCSIコマンドを処理中の状態を示す信号のピン番号。 - PIN_ENB:起動から終了の間の有効信号を示す信号のピン番号。 - PIN_TAD:ターゲット信号(BSY,IO,CD,MSG,REG)の入出力方向を示す信号のピン番号。 - PIN_IND:イニシーエータ信号(SEL,ATN,RST,ACK)の入出力方向を示す信号のピン番号。 - PIN_DTD:データ信号(DT0...DT7,DP)の入出力方向を示す信号のピン番号。 - - ・制御信号出力論理 - 0V:FALSE 3.3V:TRUEで指定します。 - - ACT_ON:PIN_ACT信号の論理です。 - ENB_ON:PIN_ENB信号の論理です。 - TAD_IN:PIN_TAD入力方向時の論理です。 - IND_IN:PIN_ENB入力方向時の論理です。 - DTD_IN:PIN_ENB入力方向時の論理です。 - - ・SCSI信号ピンアサイン - PIN_DT0〜PIN_SEL:それぞれSCSI信号のピン番号です。 - -□コンパイル方法 - - ・実行ファイル(rascsi,rasctl) - gpiobus.hを修正 - make clean - make - - ・カーネルドライバ(rascsidrv.ko) - @OS最新化(必要あれば) - sudo apt-get update - sudo apt-get upgrade - sudo reboot - - Aカーネルヘッダー取得(必要あれば) - sudo apt-get install raspberrypi-kernel-headers - - Bコンパイル - cd kernelmodule - rascsidrv.cの修正 - make -[EOF] +------------------------------------------------------------------------------ + + SCSI Target Emulator RaSCSI for Raspberry Pi + + Powered by XM6 TypeG Technology. + Copyright (C) 2016-2020 GIMONS + +------------------------------------------------------------------------------ + +笆。螟画鋤蝓コ譚ソ縺ョ蠢隕∵ァ縺ォ縺、縺縺ヲ + SCSI縺ッTTL繝ャ繝吶Ν縺ァ5V繧220ホゥ縺ィ330ホゥ縺ァ蛻蝨ァシ医ヱ繝繧キ繝悶ち繝シ繝溘ロ繝シ繧ソ縺ョ蝣エ蜷茨シ峨☆繧 + 縺薙→縺ァ蜷菫。蜿キ邱壹↓3V蠑ア縺ョ髮サ蝨ァ縺後°縺九▲縺溽憾諷九′螳壼クク迥カ諷具シ井ソ。蜿キ逧縺ォ縺ッ繝阪ご繝シ繝)縺ォ + 縺ェ縺」縺ヲ縺縺セ縺吶 + + 繧、繝九す繧ィ繝シ繧ソ蛛エ繧ゅ@縺上ッ繧ソ繝シ繧イ繝繝亥エ縺御ソ。蜿キ繧偵い繧オ繝シ繝医☆繧具シ茨シ0Vシ峨↓縺励h縺縺ィ + 縺吶k縺ィ荳。遶ッ縺ョ繧ソ繝シ繝溘ロ繝シ繧ソ縺九i蜷医o縺帙※5000テキ220テ2=45mA縺ョ髮サ豬√′豬√l繧九%縺ィ縺ォ + 縺ェ繧翫∪縺呻シX68000縺ョSCSI繧ウ繝ウ繝医Ο繝シ繝ゥ縺ァ縺ゅkMB89352縺ョ繝繝シ繧ソ繧キ繝シ繝医r隕九l縺ー繧キ繝ウ繧ッ + 髮サ豬√→縺励※Iol48mA縺ィ縺ェ縺」縺ヲ縺縺セ縺呻シ峨 + + RPI縺ョGPIO縺ッ縺薙ョ繧医≧縺ェ螟ァ縺阪↑繧キ繝ウ繧ッ髮サ豬√ッ蜷ク蜿弱〒縺阪∪縺帙s縲る崕豌礼噪縺ォ螳牙ィ縺ェ謗・邯 + 繧定。後≧縺溘a縺ォ縺ッ豎守畑繝ュ繧ク繝繧ッIC遲峨〒螟画鋤蝓コ譚ソ繧剃ス懊k蠢隕√′縺ゅj縺セ縺吶よア守畑繝ュ繧ク繝繧ッ + IC縺ァ48mA繧ゅョ繧キ繝ウ繧ッ髮サ豬√↓閠舌∴繧九ョ縺ッ74LS06縺ィ縺07縺ィ縺縺」縺溘が繝シ繝励Φ繧ウ繝ャ繧ッ繧ソ縺ァ + 繝上う繝代Ρ繝シ繧ソ繧、繝励ョ繧ゅョ繧剃スソ逕ィ縺励∪縺吶 + + 菴懆縺ッ74HC541テ3,74HC126テ1,74HC04テ1縺ァ蝓コ譛ャ逧縺ェSCSI縺ョ譁ケ蜷大宛蠕。繧定。後>譖エ縺ォ + 74LS07テ3繧剃スソ縺」縺ヲ繝舌せ繧偵ラ繝ゥ繧、繝悶☆繧句屓霍ッ繧堤オ繧薙〒縺ソ縺溘→縺薙m蝠城。後↑縺丞虚菴懊☆繧 + 縺薙→繧堤「コ隱阪@縺セ縺励◆縲 + + 莉悶↓繧74LS641縺ョ豢セ逕溽沿縺ァ縺ゅk74LS641-1繧剃スソ逕ィ縺吶k縺ィ蝗櫁キッ縺ッ繧キ繝ウ繝励Ν縺ォ讒区舌〒縺阪k + 縺ァ縺励g縺縲ゅヮ繝シ繝槭Ν蜩√→驕輔▲縺ヲ繧キ繝ウ繧ッ髮サ豬√′48mA蟇セ蠢懊↑縺ョ縺ァ74LS07繧剃スソ逕ィ縺吶k蠢隕 + 縺ッ縺ゅj縺セ縺帙s縲ゅ@縺九@蜈・謇区ァ縺ッ縺昴l縺サ縺ゥ濶ッ縺上≠繧翫∪縺帙s縲 + +笆。螟画鋤蝓コ譚ソ縺ョ蝗櫁キッ蝗ウ譯 + 蜷後§繝輔か繝ォ繝縺ォ蝗櫁キッ蝗ウ譯医r蜈・繧後※縺縺セ縺吶 + + 繝サtarget.png + SCSI縺ョ繧ソ繝シ繧イ繝繝医Δ繝シ繝峨r菴ソ逕ィ縺吶k縺溘a縺ョ螟画鋤蝓コ譚ソ蝗櫁キッ蝗ウ縺ァ縺吶ょ渕譛ャ讖溯ス縺ァ縺ゅk + HDD繧МO縺ョ繧ィ繝溘Η繝ャ繝シ繧キ繝ァ繝ウ繧定。後≧縺ョ縺ァ縺ゅl縺ー縺薙ョ蝗櫁キッ蝗ウ逶ク蠖薙ョ迚ゥ繧剃ス懊l縺ー濶ッ縺 + 縺ァ縺励g縺縲ゆスソ逕ィ縺吶kGPIO繝斐Φ繧よ怙繧ょー代↑縺讒区舌↓縺ェ繧翫∪縺吶 + + 繝斐Φ繧「繧オ繧、繝ウ繧貞、画峩縺励↑縺代l縺ーRaSCSI縺ョstandard繝繧」繝ャ繧ッ繝医Μ縺ォ蜷ォ縺セ繧後k + 繝舌う繝翫Μ繧剃スソ逕ィ縺吶k縺薙→縺悟庄閭ス縺ァ縺吶 + + 繝サfullspec.png + SCSI縺ョ繧ソ繝シ繧イ繝繝医Δ繝シ繝峨√う繝九す繧ィ繝シ繧ソ繝「繝シ繝峨r蛻ゥ逕ィ縺ァ縺阪k螟画鋤蝓コ譚ソ蝗櫁キッ蝗ウ縺ァ縺吶 + 蜈ィ縺ヲ縺ョ74LS641-1縺ョ譁ケ蜷大宛蠕。繧坦aSCSI縺九i陦後>縺セ縺吶ョ縺ァGPIO繝斐Φ繧剃ク峨▽菴吝縺ォ菴ソ逕ィ + 縺励※縺励∪縺縺セ縺吶 + + 繝斐Φ繧「繧オ繧、繝ウ縺ョ繧ォ繧ケ繧ソ繝槭う繧コ縺ァ縲 ̄IN_TAD,PIN_IND,PIN_DTD縺ォ縺昴l縺槭l讓呎コ + 縺ァ縺ッ6,7,8繧定ィュ螳壹@縺ヲ繧ウ繝ウ繝代う繝ォ縺吶k蠢隕√′縺ゅj縺セ縺吶ゅヴ繝ウ繧「繧オ繧、繝ウ縺ョ + 繧ォ繧ケ繧ソ繝槭う繧コ繧貞盾辣ァ縺励※縺上□縺輔>縲 + +笆。譌「蟄倥ョ繧ゅョ繧呈焔縺ォ蜈・繧後k譁ケ豕 + 譛霑代〒縺ッ荳サ縺ォTwitter逡碁嚠繧帝壹§縺ヲRaSCSI逕ィ縺ョ螟画鋤蝓コ譚ソ繧剃ス懈舌@縺ヲ縺縺溘□縺縺ヲ + 縺繧区婿縲縺後>繧峨▲縺励c縺縺セ縺吶ら峩縺舌↓隕九▽縺九k縺ィ諤昴>縺セ縺吶ョ縺ァ縺薙%縺ァ縺ョ邏ケ莉 + 縺ッ逵∫払縺励∪縺吶よ凾譛溘ッ譛ェ螳壹〒縺吶′蜈ャ蠑冗沿縺ョ譛牙─鬆貞ク繧定ィ育判縺励※縺縺セ縺吶 + +笆。繝斐Φ繧「繧オ繧、繝ウ縺ョ繧ォ繧ケ繧ソ繝槭う繧コ + GPIO縺ョ菫。蜿キ蛻カ蠕。隲也炊繧繝斐Φ繧「繧オ繧、繝ウ縺ッgpiobus.h縺ォ螳夂セゥ縺後≠繧翫∪縺吶 + + 繧ォ繧ケ繧ソ繝槭う繧コ萓九→縺励※gpiobus.h縺ォ荳玖ィ倥ョ莠後▽縺ョ螟画鋤蝓コ譚ソ逕ィ螳夂セゥ萓九r逕ィ諢上@縺セ縺励◆縲 + 驟榊ク迚ゥ縺ョ荳ュ縺ォ縺ッ繧ウ繝ウ繝代う繝ォ貂医∩繝舌う繝翫Μ繧ょ性縺セ繧後※縺縺セ縺吶 + + 繝サ縺ゅ>縺シ繧迚 + 繝サGAMERnium迚 + +笆。繧ォ繧ケ繧ソ繝槭う繧コ譁ケ豕 + 繝サRaSCSI襍キ蜍墓凾縺ョ繝。繝繧サ繝シ繧ク縺ァ縺吶 + CONNECT_DESC + + 繝サ菫。蜿キ蛻カ蠕。繝「繝シ繝峨r驕ク謚槭@縺セ縺吶 + SIGNAL_CONTROL_MODE + + 0:SCSI隲也炊莉墓ァ + 逶エ邨舌∪縺溘ッHP縺ォ蜈ャ髢九@縺74LS641-1遲峨r菴ソ逕ィ縺吶k螟画鋤蝓コ譚ソ + 繧「繝シ繧オ繝シ繝:0V + 繝阪ご繝シ繝 :繧ェ繝シ繝励Φ繧ウ繝ャ繧ッ繧ソ蜃コ蜉(繝舌せ縺九i蛻繧企屬縺) + + 1:雋隲也炊莉墓ァ(雋隲也炊->SCSI隲也炊縺ク縺ョ螟画鋤蝓コ譚ソ繧剃スソ逕ィ縺吶k蝣エ蜷) + 迴セ譎らせ縺ァ縺薙ョ莉墓ァ倥↓繧医k螟画鋤蝓コ譚ソ縺ッ蟄伜惠縺励∪縺帙s + 繧「繝シ繧オ繝シ繝:0V -> (CONVERT) -> 0V + 繝阪ご繝シ繝 :3.3V -> (CONVERT) -> 繧ェ繝シ繝励Φ繧ウ繝ャ繧ッ繧ソ蜃コ蜉 + + 2:豁」隲也炊莉墓ァ(豁」隲也炊->SCSI隲也炊縺ク縺ョ螟画鋤蝓コ譚ソ繧剃スソ逕ィ縺吶k蝣エ蜷) + RaSCSI Adapter Rev.C @132sync遲 + + 繧「繝シ繧オ繝シ繝:3.3V -> (CONVERT) -> 0V + 繝阪ご繝シ繝 :0V -> (CONVERT) -> 繧ェ繝シ繝励Φ繧ウ繝ャ繧ッ繧ソ蜃コ蜉 + + 繝サ蛻カ蠕。菫。蜿キ繝斐Φ繧「繧オ繧、繝ウ + PIN_ACT:SCSI繧ウ繝槭Φ繝峨r蜃ヲ逅荳ュ縺ョ迥カ諷九r遉コ縺吩ソ。蜿キ縺ョ繝斐Φ逡ェ蜿キ縲 + PIN_ENB:襍キ蜍輔°繧臥オゆコ縺ョ髢薙ョ譛牙柑菫。蜿キ繧堤、コ縺吩ソ。蜿キ縺ョ繝斐Φ逡ェ蜿キ縲 + PIN_TAD:繧ソ繝シ繧イ繝繝井ソ。蜿キ(BSY,IO,CD,MSG,REG)縺ョ蜈・蜃コ蜉帶婿蜷代r遉コ縺吩ソ。蜿キ縺ョ繝斐Φ逡ェ蜿キ縲 + PIN_IND:繧、繝九す繝シ繧ィ繝シ繧ソ菫。蜿キ(SEL,ATN,RST,ACK)縺ョ蜈・蜃コ蜉帶婿蜷代r遉コ縺吩ソ。蜿キ縺ョ繝斐Φ逡ェ蜿キ縲 + PIN_DTD:繝繝シ繧ソ菫。蜿キ(DT0...DT7,DP)縺ョ蜈・蜃コ蜉帶婿蜷代r遉コ縺吩ソ。蜿キ縺ョ繝斐Φ逡ェ蜿キ縲 + + 繝サ蛻カ蠕。菫。蜿キ蜃コ蜉幄ォ也炊 + 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ス霸IN_SEL:縺昴l縺槭lSCSI菫。蜿キ縺ョ繝斐Φ逡ェ蜿キ縺ァ縺吶 + +笆。繧ウ繝ウ繝代う繝ォ譁ケ豕 + + 繝サ螳溯。後ヵ繧。繧、繝ォ(rascsi,rasctl) + gpiobus.h繧剃ソョ豁」 + make clean + make + +[EOF] diff --git a/doc/fullspec.png b/doc/fullspec.png index 47692e59..b80fee28 100644 Binary files a/doc/fullspec.png and b/doc/fullspec.png differ diff --git a/doc/initiator.png b/doc/initiator.png deleted file mode 100644 index cabd0051..00000000 Binary files a/doc/initiator.png and /dev/null differ diff --git a/doc/rascsi.txt b/doc/rascsi.txt index c6c90190..6b1c6d90 100644 --- a/doc/rascsi.txt +++ b/doc/rascsi.txt @@ -1,315 +1,335 @@ ------------------------------------------------------------------------------- - - SCSI Target Emulator RaSCSI (*^..^*) - version 1.34 for Raspberry Pi - - Powered by XM6 TypeG Technology. - Copyright (C) 2016-2018 GIMONS - ------------------------------------------------------------------------------- -□RaSCSIとは - RaSCSIはRaspberry Piで動作するSCSIデバイス(ハードディスク,MO,CD-ROM)を - 仮想的に再現するエミュレータです。SCSIを採用したSHARPのX68000で使用する - ことを目的として開発しました。RaSCSIを導入したRaspberry PiをX68000のSCSI - コネクタに接続するだけで物理的なSCSIデバイスとして認識されます。 - - X68000以外にもSCSIを採用したFM TOWNSやPC98等のレトロPCでも使用できるかも - しれません。作者はFM TOWNSとPC9821Ceで動作するところまでは確認しています。 - - RaSCSIはSCSIデバイスをエミュレートするソフトウェアに加えてRaspberry Piの - GPIOコネクタをSCSIコネクタに変換する機構の総称を指します。 - -□動作環境 - (1)Raspberry Pi - Raspberry Pi 3 Model B を推奨します。 - - Raspberry Pi 2 Model BやZeroでも動作すると考えられます。 - ピンアサインを独自に変更しRaspberry Pi 1で動作させたという報告もあります。 - - (2)OS - RASPBIAN STRETCHで開発およびテストしています。 - sudo apt-get update及びsudo apt-get upgradeで最新にしています。 - このドキュメントを記述している時点で"Linux raspberrypi 4.14.34-v7+"です。 - - RaSCSIはSCSI信号をGPIOを利用して制御しているので可能な限り低レイテンシー - の状態で使用する必要があります。したがってCUIモードで利用することを推奨 - します。更に不要なサービスは極力停止して下さい。 - -□SCSIコネクタとの接続方法 - 状況が複雑になってきましたのでRaSCSIのホームページ上で情報提供しています。 - このドキュメントの最後にある公式ホームページを参考にして下さい。 - -□配布物 - 配布するアーカイブには実行ファイル、ドキュメント、ソースコードのそれぞれが - ディレクトリで分かれて含まれています。 - - bin/ ・・・ 実行ファイル - raspberrypi/ ・・・ RPI用のプログラム - rascsi.tar.gz ・・・ 実行ファイルとカーネルモジュールをtar+gzipしたもの。 - - x68k/ ・・・ X68000用のプログラム - RASDRV.SYS ・・・ ホストドライブドライバ - RASETHER.SYS ・・・ イーサネットドライバ - - doc/ ・・・ ドキュメント - rascsi.txt ・・・ 当ドキュメント - x68k.txt ・・・ X68000固有機能の説明 - converter.txt ・・・ 変換基板の説明 - pinassign.png ・・・ ピンアサイン図 - target.png ・・・ 変換基板回路図案(ターゲットモード) - initiator.png ・・・ 変換基板回路図案(イニシエータサポート) - fullspec.png ・・・ 変換基板回路図案(フルスペック) - - src/ ・・・ ソースコード - raspberrypi/ ・・・ RPI用のプログラムソース一式 - x68k/ ・・・ X68000用のプログラム一式 - - - RPIで使用するプログラムはrascsi.tar.gzですのでRPI上に転送してから解凍して - 下さい。パーミッション等を維持するためにRPI上で解凍することを推奨します。 - - rascsi.tar.gzにはstandard,fullspec,aibom,gamerniumのディレクトリが含まれ - ています。通常はstandardディレクトリにある実行ファイルを使用して下さい。 - - aibom,gamerniumディレクトリのものは"あいぼむ版","GAMERnium版"の変換基板を - 使用する時のものです。 - - fullspecディレクトリのものは公開したフルスペック版変換基板の回路図案で - 変換基板を作成した時に使用する時のものです。 - -□RASCI本体の使用方法(rascsi) - - sudo rascsi [-ID{01234567} FILE] ... - - ルート権限が必要ですのでsudo等で起動する必要があります。 - オプションに-hを付けると簡単なHELPが表示されます - - Usage: ./rascsi [-ID{0|1|2|3|4|5|6|7} FILE] ... - - ID is SCSI identification number. - FILE is disk image file. - - Detected images type based on file extension. - hdf : SASI HD image(XM6 SASI HD image) - hds : SCSI HD image(XM6 SCSI HD image) - hdn : SCSI HD image(NEC GENUINE) - hdi : SCSI HD image(Anex86 HD image) - nhd : SCSI HD image(T98Next HD image) - hda : SCSI HD image(APPLE GENUINE) - mos : SCSI MO image(XM6 SCSI MO image) - iso : SCSI CD image(ISO 9660 image) - - 引数では-ID{01234567}とFILEの一組で一つのSCSIデバイスを指定できます。 - - -IDの後ろの番号はSCSI IDです。SCSI IDは0-7を指定できますが通常レトロPC本体 - がイニシエータとしてID7等を使用していると思います。その場合は0-6を指定する - ことになります。 - - FILEは仮想ディスクイメージのファイルパスです。イメージファイル名には拡張子 - が必要です。拡張子によってHD,MO,CDの種別を判定しています。 - - 例)SCSI ID0にHDIMAGE0.HDS,ID1にHDIMAGE1.HDSを指定して起動する場合、 - sudo rascsi -ID0 HDIMAGE0.HDS -ID1 HDIMAGE1.HDS - - 終了する場合はCTRL+Cで停止します。 - バックグラウンドで起動した場合にはkillコマンド該当プロセスにINTシグナルか - HUPシグナルを送ることで終了します。 - - rascsiは起動後にソケット(6868ポート)を開いて外部からの管理コマンドを受け - 付ける状態になります。したがって既に別プロセスとしてrascsiが起動している - 場合はエラーメッセージとともに起動を中断します。 - -□管理ツールの使用方法(rasctl) - バージョン1.10からrasctlという管理ツールを提供します。これはrascsiプロセス - がバックグラウンドで起動(6868ポートで接続待ちの状態)している場合にディスク - 操作のコマンドを発行することが可能となります。コマンドラインは下記の通り。 - - rasctl -i ID [-c CMD] [-t TYPE] [-f FILE] - - ID : SCSI ID - CMD : 操作コマンド - attach : ディスクを取り付ける - detatch : ディスクを取り外す - insert : メディアを挿入する(MOまたはCDのみ) - eject : メディアを取り出す(MOまたはCDのみ) - protect : メディアを書き込み禁止にする(MOのみ) - TYPE : ディスク種別 - hd : ハードディスク(SASI/SCSI) - mo : MO(光磁気ディスク) - cd : CDROM(CDROMドライブ) - bridge : ブリッジデバイス - FILE : ディスクイメージファイルのパス - - IDは必須です。CMDは省略時はattachと解釈します。TYPEはコマンドがattachの - 場合にはFILEの拡張子から自動判定します。FILEはTYPEを明示的に指定している - 場合は拡張子が異なっても構いません。基本的CMD,TYPEの解釈は大文字小文字を - 無視します。現在のところ最初の1文字でのみ判定しています。 - - コマンド例 - rascsi -i 0 -f HDIMAGE0.HDS - - の場合はSCSI IDは0。CMDはデフォルトでattachでありTYPEは拡張子HDSから判断 - するのでhdと推測することになりrascsi起動時のオプション指定と同等です。 - - 現在の状態を確認するにために-lオプションのみを指定するとデバイス一覧が表示 - されます。コマンドラインは下記の通り。 - - rasctl -l - - rasctl自体の起動にはルート権限は必要ありません。 - -□ディスクダンプツールの使用方法(rasdump) - 直結もしくは直結基板、またはイニシエータ対応とした変換基板向けのサンプル - プログラムです。現在のところ変換基板では"あいぼむ版"のみ対応してます。 - - 名前の通りSCSI HDDやMOのイメージをダンプ(オプションでリストア)します。 - 自身のIDはBIDで指定して下さい。省略時は7を使用します。 - - rasdump -i ID [-b BID] -f FILE [-r] - ID : ターゲットデバイスのSCSI ID - BID : RaSCSI自身のSCSI ID - FILE : ダンプファイル名 - -r : リストアモード - - サンプルなので必要最低限の処理しか実装していませんので改造するなりして - ご使用下さい。 - -□カーネルモジュールの導入方法(rascsidrv.ko) - version 1.24から安定化のためにGPIO制御の一部をカーネルモジュールで動作 - させる拡張を加えました。 - - カーネルモジュールを導入しなくても動作できますが、X68000シリーズのSASI - を使用する場合や純正SCSIボードを増設した場合はカーネルモジュールの導入 - を行っていないと動作が不安定になります。 - - カーネルモジュールを有効にするには - - sudo insmod rascsidrv.ko - - を実行してください。 - - カーネルモジュールの起動を確認するにはdmesgコマンドで出力されるログの - 最後に次のような表示がされている筈です。 - - "RaSCSI GPIO Driver Loaded(STANDARD)" - - 注意! - カーネルモジュールは使用中のOSのバージョンに依存します。 - - rascsiやrasctlと同じ階層にあるrascsidrv.koはRaspberry Pi 2/3用の - "Linux raspberrypi 4.14.34-v7+"でコンパイルしたモジュールになります。 - - 同じ階層のrpi1orZero/rascsidrv.koはRaspberry Pi 1/Zero用です。 - "Linux raspberrypi 4.14.34+"でコンパイルしたモジュールになります。 - - 自身でカーネルモジュールをコンパイルする手順を簡単に記しておきます。 - - ・OSの最新化 - sudo apt-get update - sudo apt-get upgrade - sudo reboot - - ・カーネルヘッダー取得 - sudo apt-get install raspberrypi-kernel-headers - - ・コンパイル - cd kernelmodule - make - -□サポートするディスクイメージ - (1)SCSI ハードディスク - HDSファイル形式 (拡張子HDS/HDN/HDI/NHD/HDA) - ファイルサイズは10MB以上4095MB以下の範囲で任意のサイズ(但し512バイト単位) - - 拡張子が"HDN"の場合はNEC純正55ボード(PC-9801-55)向けの純正ハードディスク - エミュレーションを行います。INQUIRYで返却される情報やMODE SENSEのサイズに - に違いがあります。 - - 拡張子が"HDI","NHD"の場合はそれぞれPC98エミュレータであるAnex86及びT98Next - のSCSIハードディスクイメージを使用するものです。HDNの時と同様に一部の情報 - がNEC用に変換されます。 - - 拡張子が"HDA"の場合はAPPLE純正ハードディスクエミュレーションを行います。 - INQUIRY及びMODE SENSEで返却される情報に違いがあります。 - - (2)SASI ハードディスク - HDFファイル形式 (拡張子HDF) - ファイルサイズは10441728バイト、20748288バイト、41496576バイトのいずれか - (それぞれ10MBドライブ、20MBドライブ、40MBドライブに対応) - - (3)SCSI 光磁気(MO)ディスク - MOSファイル形式 (拡張子MOS) - ファイルサイズは次の4種類のいずれか: - 128MBタイプ (127398912バイト) - 230MBタイプ (228518400バイト) - 540MBタイプ (533248000バイト) - 640MBタイプ (635600896バイト) - 128MB,230MB,540MBは512バイト/セクタ、640MBは2048バイト/セクタになります。 - - (4)SCSI CD-ROMディスク - ISOファイル形式 (拡張子ISO、ISO9660ベタイメージ) - モード1(2048バイト/セクタ)で、データのみ格納されたファイルとRAW形式で記録 - されたファイルの両方に対応しています。 - -□ディスクイメージの作成 - RaSCSI自体がX68000エミュレータであるXM6 TypeGの派生物です。従ってディスク - イメージの作成はXM6 TypeGの「ツール」メニューから行うことを前提としています。 - もちろん先に説明した仕様に従えばdd等で空のイメージファイルを作成することも - 可能です。 - - 例)100MBのHDSイメージ(空ファイル)を作る場合 - - dd if=/dev/zero of=HARDDISK.HDS bs=512 count=204800 - -□動作実績 - 作者の開発環境であるX68000 PRO(内蔵SASI/純正SCSIボード)、X68030 内蔵SCSI、 - XVI Compact 内蔵SCSIで動作確認しています。Mach-2でも動作しました。 - - 他にも初代X68000,ACE,EXPERT,XVI,PRO2,SUPER等で動作報告がありましたので、 - X68000シリーズはほぼ問題ないでしょう。 - - その他のレトロPCではFM TOWNSシリーズ、PC98シリーズ、Apple Macintosh、 - MSX(MEGA-SCSI利用)で動作報告があります。 - - その他の機種でもちらほらと動作報告を頂いています。 - -□活用方法 - XM6等のX68000エミュレータを使用している場合はエミュレータで環境構築したHDD - イメージをFTP等でRaspberry Piに転送することでX68000の実機に接続できます。 - またその逆も然りで実機上に存在するファイルを格納したHDDイメージをPCにFTP等 - で転送することでエミュレータで活用することができます。 - -□ライセンス - RaSCSIはカーネルドライバを除きあるがまま"AS IS"で配布されるソフトウェアです。 - カーネルドライバのソースrascsidrv.cのみGPLです(御察っし下さい)。 - - つまり使用者が受けたあらゆる損害に対して一切責任を持ちません。またソフト - ウェアに不備もしくは不具合があったとしてもそれを修正する責任もありません。 - - RaSCSIを利用することでRaspberry PiやレトロPCが故障するリスクがあります。 - あくまで自己責任でチャレンジしてください。 - - XM6 TypeG同様に実験成果公開という性質上私のHP以外での配布を認めておりません。 - - XM6のライセンス条項を継承していますので雑誌/書籍での紹介事前の許諾が必要です。 - そもそも2017年にもなってSCSIに反応するのは限られた人だけだと思います。 - -□変換基板の頒布について - 変換基板の頒布については作者に許諾を得る必要はありません。 - 一応ご連絡いただければ何かとサポートできるかもしれません。 - - 但しレトロPCのSCSI環境改善を応援するという趣旨から、 - 有料の場合は - - 基板製作費 + パーツ費用 + 運送費 +(社会通念上一般的な)手数料 - - を大きく越えるような頒布についてはお止め下さい。 - -□公開ホームページ - http://www.geocities.jp/kugimoto0715/rascsi/index.html - -□連絡先 - twitter https://twitter.com/kugimoto0715 - e-mail kugimoto0715@yahoo.co.jp - -[EOF] +------------------------------------------------------------------------------ + + SCSI Target Emulator RaSCSI (*^..^*) + for Raspberry Pi + + Powered by XM6 TypeG Technology. + Copyright (C) 2016-2020 GIMONS + +------------------------------------------------------------------------------ +笆。RaSCSI縺ィ縺ッ + RaSCSI縺ッRaspberry Pi縺ァ蜍穂ス懊☆繧鬼CSI繝繝舌う繧ケ(繝上シ繝峨ョ繧」繧ケ繧ッシ勲Oシ靴D-ROM)繧 + 莉ョ諠ウ逧縺ォ蜀咲樟縺吶k繧ィ繝溘Η繝ャ繝シ繧ソ縺ァ縺吶4CSI繧呈治逕ィ縺励◆SHARP縺ョX68000縺ァ菴ソ逕ィ縺吶k + 縺薙→繧堤岼逧縺ィ縺励※髢狗匱縺励∪縺励◆縲3aSCSI繧貞ー主・縺励◆Raspberry Pi繧湛68000縺ョSCSI + 繧ウ繝阪け繧ソ縺ォ謗・邯壹☆繧九□縺代〒迚ゥ逅逧縺ェSCSI繝繝舌う繧ケ縺ィ縺励※隱崎ュ倥&繧後∪縺吶 + + X68000莉・螟悶↓繧4CSI繧呈治逕ィ縺励◆FM TOWNS繧ПC98遲峨ョ繝ャ繝医ΟPC縺ァ繧ゆスソ逕ィ縺ァ縺阪k縺九b + 縺励l縺セ縺帙s縲ゆス懆縺ッFM TOWNS縺ィPC9821Ce縺ァ蜍穂ス懊☆繧九→縺薙m縺セ縺ァ縺ッ遒コ隱阪@縺ヲ縺縺セ縺吶 + + RaSCSI縺ッSCSI繝繝舌う繧ケ繧偵お繝溘Η繝ャ繝シ繝医☆繧九た繝輔ヨ繧ヲ繧ァ繧「縺ォ蜉縺医※Raspberry Pi縺ョ + GPIO繧ウ繝阪け繧ソ繧担CSI繧ウ繝阪け繧ソ縺ォ螟画鋤縺吶k讖滓ァ九ョ邱冗ァー繧呈欠縺励∪縺吶 + +笆。蜍穂ス懃腸蠅 + (1)Raspberry Pi + Raspberry Pi Zero + Raspberry Pi Zero W + Raspberry Pi Zero WH + Raspberry Pi 2 Model B + Raspberry Pi 3 Model B(謗ィ螂ィ) + Raspberry Pi 3 Model A+ + Raspberry Pi 3 Model B+ + Raspberry Pi 4 Model B + + Zero/Zero W/Zero WH縺ァ縺ッ諤ァ閭ス逧縺ォ蟆代@荳榊ョ牙ョ壹°繧ゅ@繧後∪縺帙s縲 + + 3 Model A+/3 Model B+/4 Model B縺ッ鬮俶ァ閭ス縺ァ縺吶′辭ア縺ョ蠖ア髻ソ縺ァCPU繧ッ繝ュ繝繧ッ縺 + 螟牙虚縺吶k縺薙→縺後≠繧翫∪縺吶ョ縺ァ蟇セ遲悶′蠢隕√〒縺励g縺縲 + + (2)OS + RASPBIAN BUSTER縺ァ髢狗匱縺翫h縺ウ繝繧ケ繝医@縺ヲ縺縺セ縺吶 + RaSCSI縺ッSCSI菫。蜿キ繧竪PIO繧貞茜逕ィ縺励※蛻カ蠕。縺励※縺繧九ョ縺ァ蜿ッ閭ス縺ェ髯舌j菴弱Ξ繧、繝繝ウ繧キ繝シ + 縺ョ迥カ諷九〒菴ソ逕ィ縺吶k蠢隕√′縺ゅj縺セ縺吶ゅ@縺溘′縺」縺ヲCUI繝「繝シ繝峨〒蛻ゥ逕ィ縺吶k縺薙→繧呈耳螂ィ + 縺励∪縺吶 + +笆。SCSI繧ウ繝阪け繧ソ縺ィ縺ョ謗・邯壽婿豕 + 迥カ豕√′隍髮代↓縺ェ縺」縺ヲ縺阪∪縺励◆縺ョ縺ァRaSCSI縺ョ繝帙シ繝繝壹シ繧ク荳翫〒諠蝣ア謠蝉セ帙@縺ヲ縺縺セ縺吶 + 縺薙ョ繝峨く繝・繝。繝ウ繝医ョ譛蠕後↓縺ゅk蜈ャ蠑上帙シ繝繝壹シ繧ク繧貞盾閠縺ォ縺励※荳九&縺縲 + +笆。驟榊ク迚ゥ + 驟榊ク縺吶k繧「繝シ繧ォ繧、繝悶↓縺ッ螳溯。後ヵ繧。繧、繝ォ縲√ラ繧ュ繝・繝。繝ウ繝医√た繝シ繧ケ繧ウ繝シ繝峨ョ縺昴l縺槭l縺 + 繝繧」繝ャ繧ッ繝医Μ縺ァ蛻縺九l縺ヲ蜷ォ縺セ繧後※縺縺セ縺吶 + + bin/ ス・ス・ス・ 螳溯。後ヵ繧。繧、繝ォ + raspberrypi/ ス・ス・ス・ RPI逕ィ縺ョ繝励Ο繧ー繝ゥ繝 + rascsi.tar.gz ス・ス・ス・ 螳溯。後ヵ繧。繧、繝ォ繧稚ar+gzip縺励◆繧ゅョ縲 + + x68k/ ス・ス・ス・ X68000逕ィ縺ョ蟆ら畑繝峨Λ繧、繝 + RASDRIVER.XDFス・ス・ス・ 莠後▽縺ョ繝峨Λ繧、繝舌r蜷ォ繧繝輔Ο繝繝斐シ繧、繝。繝シ繧ク + RASDRIVER.HDSス・ス・ス・ 莠後▽縺ョ繝峨Λ繧、繝舌r蜷ォ繧SCSI HD繧、繝。繝シ繧ク + RASDRIVER.HDFス・ス・ス・ 莠後▽縺ョ繝峨Λ繧、繝舌r蜷ォ繧SASI HD繧、繝。繝シ繧ク + + doc/ ス・ス・ス・ 繝峨く繝・繝。繝ウ繝 + rascsi.txt ス・ス・ス・ 蠖薙ラ繧ュ繝・繝。繝ウ繝 + x68k.txt ス・ス・ス・ X68000蝗コ譛画ゥ溯ス縺ョ隱ャ譏 + converter.txt ス・ス・ス・ 螟画鋤蝓コ譚ソ縺ョ隱ャ譏 + pinassign.png ス・ス・ス・ 繝斐Φ繧「繧オ繧、繝ウ蝗ウ + target.png ス・ス・ス・ 螟画鋤蝓コ譚ソ蝗櫁キッ蝗ウ譯(繧ソ繝シ繧イ繝繝医Δ繝シ繝) + fullspec.png ス・ス・ス・ 螟画鋤蝓コ譚ソ蝗櫁キッ蝗ウ譯(繝輔Ν繧ケ繝壹ャ繧ッ) + + src/ ス・ス・ス・ 繧ス繝シ繧ケ繧ウ繝シ繝 + raspberrypi/ ス・ス・ス・ RPI逕ィ縺ョ繝励Ο繧ー繝ゥ繝繧ス繝シ繧ケ荳蠑 + x68k/ ス・ス・ス・ X68000逕ィ縺ョ繝励Ο繧ー繝ゥ繝荳蠑 + + + RPI縺ァ菴ソ逕ィ縺吶k繝励Ο繧ー繝ゥ繝縺ッrascsi.tar.gz縺ァ縺吶ョ縺ァRPI荳翫↓霆「騾√@縺ヲ縺九i隗」蜃阪@縺ヲ + 荳九&縺縲ゅヱ繝シ繝溘ャ繧キ繝ァ繝ウ遲峨r邯ュ謖√☆繧九◆繧√↓RPI荳翫〒隗」蜃阪☆繧九%縺ィ繧呈耳螂ィ縺励∪縺吶 + + rascsi.tar.gz縺ォ縺ッstandard,fullspec,aibom,gamernium縺ョ繝繧」繝ャ繧ッ繝医Μ縺悟性縺セ繧 + 縺ヲ縺縺セ縺吶 + + 逶エ邨舌こ繝シ繝悶Ν繧逶エ邨仙渕譚ソ繧剃スソ逕ィ縺吶k蝣エ蜷医ッstandard繝繧」繝ャ繧ッ繝医Μ縺ョ螳溯。後ヵ繧。繧、繝ォ + 繧剃スソ逕ィ縺励※荳九&縺縲 + + 蜷梧ァ倥↓繝輔Ν繧ケ繝壹ャ繧ッ迚医→隱ャ譏弱&繧後◆螟画鋤蝓コ譚ソ縺ョ蝣エ蜷医ッfullspec縺ョ繝繧」繝ャ繧ッ繝医Μ縺ョ + 繧ゅョ繧剃スソ逕ィ縺励∪縺(逶エ邨舌〒繧ょ虚縺上→諤昴>縺セ縺)縲 + + aibom,gamernium繝繧」繝ャ繧ッ繝医Μ縺ョ繧ゅョ縺ッ"縺ゅ>縺シ繧迚","GAMERnium迚"縺ョ螟画鋤蝓コ譚ソ繧 + 菴ソ逕ィ縺吶k譎ゅョ繧ゅョ縺ァ縺吶 + + X68000逕ィ縺ョ繝峨Λ繧、繝舌ッRASDRIVER.XDF繧ゅ@縺上ッRASDRIVER.HDS縺ョ荳ュ縺ォ谺。縺ョ莠後▽縺悟性縺セ + 繧後※縺縺セ縺吶 + RASDRV.SYS ス・ス・ス・ 繝帙せ繝医ラ繝ゥ繧、繝悶ラ繝ゥ繧、繝 + RASETHER.SYS ス・ス・ス・ 繧、繝シ繧オ繝阪ャ繝医ラ繝ゥ繧、繝 + +笆。RASCI譛ャ菴薙ョ菴ソ逕ィ譁ケ豕(rascsi) + + ID謖螳壹ョ蝣エ蜷 + rascsi [-IDn FILE] ... + n:0ス7 + + HD謖螳壹ョ蝣エ蜷(X68000 SASI讖溘ョHD謖螳壻コ呈鋤) + rascsi [-HDn FILE] ... + n:0ス15 + + 繝ォ繝シ繝域ィゥ髯舌′蠢隕√〒縺吶ョ縺ァsudo遲峨〒襍キ蜍輔☆繧句ソ隕√′縺ゅj縺セ縺吶 + 繧ェ繝励す繝ァ繝ウ縺ォ-h繧剃サ倥¢繧九→邁。蜊倥↑HELP縺瑚。ィ遉コ縺輔l縺セ縺 + + Usage: rascsi [-IDn FILE] ... + + n is SCSI identification number(0-7). + FILE is disk image file. + + Usage: rascsi [-HDn FILE] ... + + n is X68000 SASI HD number(0-15). + FILE is disk image file. + + Image type is detected based on file extension. + hdf : SASI HD image(XM6 SASI HD image) + hds : SCSI HD image(XM6 SCSI HD image) + hdn : SCSI HD image(NEC GENUINE) + hdi : SCSI HD image(Anex86 HD image) + nhd : SCSI HD image(T98Next HD image) + hda : SCSI HD image(APPLE GENUINE) + mos : SCSI MO image(XM6 SCSI MO image) + iso : SCSI CD image(ISO 9660 image) + + 蠑墓焚縺ァ縺ッ-IDn繧ゅ@縺上ッ-HDn縺ィFILE縺ョ荳邨縺ァ荳縺、縺ョSCSI(SASI)繝繝舌う繧ケ繧呈欠螳壹〒縺阪∪縺吶 + -ID縺ョ蠕後m縺ョ逡ェ蜿キ縺ッSCSI(SASI) ID縺ァ縺吶ID縺ッ0-7繧呈欠螳壹〒縺阪∪縺吶′騾壼クク繝ャ繝医ΟPC譛ャ菴 + 縺後う繝九す繧ィ繝シ繧ソ縺ィ縺励※ID7遲峨r菴ソ逕ィ縺励※縺繧九→諤昴>縺セ縺吶ゅ◎縺ョ蝣エ蜷医ッ0-6繧呈欠螳壹☆繧 + 縺薙→縺ォ縺ェ繧翫∪縺吶 + + FILE縺ッ莉ョ諠ウ繝繧」繧ケ繧ッ繧、繝。繝シ繧ク縺ョ繝輔ぃ繧、繝ォ繝代せ縺ァ縺吶ゅう繝。繝シ繧ク繝輔ぃ繧、繝ォ蜷阪↓縺ッ諡。蠑オ蟄 + 縺悟ソ隕√〒縺吶よ僑蠑オ蟄舌↓繧医▲縺ヲHD,MO,CD縺ョ遞ョ蛻・繧貞愛螳壹@縺ヲ縺縺セ縺吶 + + 萓)SCSI ID0縺ォHDIMAGE0.HDS,ID1縺ォHDIMAGE1.HDS繧呈欠螳壹@縺ヲ襍キ蜍輔☆繧句エ蜷医 + sudo rascsi -ID0 HDIMAGE0.HDS -ID1 HDIMAGE1.HDS + + 邨ゆコ縺吶k蝣エ蜷医ッCTRL+C縺ァ蛛懈ュ「縺励∪縺吶 + 繝舌ャ繧ッ繧ー繝ゥ繧ヲ繝ウ繝峨〒襍キ蜍輔@縺溷エ蜷医↓縺ッkill繧ウ繝槭Φ繝芽ゥイ蠖薙励Ο繧サ繧ケ縺ォINT繧キ繧ー繝翫Ν縺 + HUP繧キ繧ー繝翫Ν繧帝√k縺薙→縺ァ邨ゆコ縺励∪縺吶 + + rascsi縺ッ襍キ蜍募セ後↓繧ス繧ア繝繝(6868繝昴シ繝)繧帝幕縺縺ヲ螟夜Κ縺九i縺ョ邂。逅繧ウ繝槭Φ繝峨r蜿励¢ + 莉倥¢繧狗憾諷九↓縺ェ繧翫∪縺吶ゅ@縺溘′縺」縺ヲ譌「縺ォ蛻・繝励Ο繧サ繧ケ縺ィ縺励※rascsi縺瑚オキ蜍輔@縺ヲ縺繧 + 蝣エ蜷医ッ繧ィ繝ゥ繝シ繝。繝繧サ繝シ繧ク縺ィ縺ィ繧ゅ↓襍キ蜍輔r荳ュ譁ュ縺励∪縺吶 + +笆。邂。逅繝繝シ繝ォ縺ョ菴ソ逕ィ譁ケ豕(rasctl) + 繝舌シ繧ク繝ァ繝ウ1.10縺九irasctl縺ィ縺縺邂。逅繝繝シ繝ォ繧呈署萓帙@縺セ縺吶ゅ%繧後ッrascsi繝励Ο繧サ繧ケ + 縺後ヰ繝繧ッ繧ー繝ゥ繧ヲ繝ウ繝峨〒襍キ蜍(6868繝昴シ繝医〒謗・邯壼セ縺。縺ョ迥カ諷)縺励※縺繧句エ蜷医↓繝繧」繧ケ繧ッ + 謫堺ス懊ョ繧ウ繝槭Φ繝峨r逋コ陦後☆繧九%縺ィ縺悟庄閭ス縺ィ縺ェ繧翫∪縺吶ゅさ繝槭Φ繝峨Λ繧、繝ウ縺ッ荳玖ィ倥ョ騾壹j縲 + + rasctl -i ID [-u UNIT] [-c CMD] [-t TYPE] [-f FILE] + + ID : SCSI ID(0ス7) + UNIT : 繝ヲ繝九ャ繝育分蜿キ(0縺セ縺溘ッ1) + CMD : 謫堺ス懊さ繝槭Φ繝 + attach : 繝繧」繧ケ繧ッ繧貞叙繧贋サ倥¢繧 + detach : 繝繧」繧ケ繧ッ繧貞叙繧雁、悶☆ + insert : 繝。繝繧」繧「繧呈諺蜈・縺吶k(MO縺セ縺溘ッCD縺ョ縺ソ) + eject : 繝。繝繧」繧「繧貞叙繧雁コ縺(MO縺セ縺溘ッCD縺ョ縺ソ) + protect : 繝。繝繧」繧「繧呈嶌縺崎セシ縺ソ遖∵ュ「縺ォ縺吶k(MO縺ョ縺ソ) + TYPE : 繝繧」繧ケ繧ッ遞ョ蛻・ + hd : 繝上シ繝峨ョ繧」繧ケ繧ッ(SASI/SCSI) + mo : MO(蜈臥」∵ー励ョ繧」繧ケ繧ッ) + cd : CDROM(CDROM繝峨Λ繧、繝) + bridge : 繝悶Μ繝繧ク繝繝舌う繧ケ + FILE : 繝繧」繧ケ繧ッ繧、繝。繝シ繧ク繝輔ぃ繧、繝ォ縺ョ繝代せ + + ID縺ッ蠢鬆医〒縺吶6NIT縺ッ逵∫払譎ゅッ0縺ァ縺(SCSI縺ョ蝣エ蜷医ッ0繧貞渕譛ャ縺ィ縺励∪縺)縲 + CMD縺ッ逵∫払譎ゅッattach縺ィ隗」驥医@縺セ縺吶5YPE縺ッ繧ウ繝槭Φ繝峨′attach縺ョ蝣エ蜷医↓縺ッFILE縺ョ諡。蠑オ蟄 + 縺九i閾ェ蜍募愛螳壹@縺セ縺吶FILE縺ッTYPE繧呈守、コ逧縺ォ謖螳壹@縺ヲ縺繧句エ蜷医ッ諡。蠑オ蟄舌′逡ー縺ェ縺」縺ヲ繧 + 讒九>縺セ縺帙s縲ょ渕譛ャ逧ГMD,TYPE縺ョ隗」驥医ッ螟ァ譁蟄怜ー乗枚蟄励r辟。隕悶@縺セ縺吶よ怙蛻昴ョ1譁蟄励〒縺ョ縺ソ + 蛻、螳壹@縺ヲ縺縺セ縺吶 + + 繧ウ繝槭Φ繝我セ + rasctl -i 0 -f HDIMAGE0.HDS + + 縺ョ蝣エ蜷医ッSCSI ID縺ッ0縲CMD縺ッ繝繝輔か繝ォ繝医〒attach縺ァ縺ゅjTYPE縺ッ諡。蠑オ蟄食DS縺九i蛻、譁ュ + 縺吶k縺ョ縺ァhd縺ィ謗ィ貂ャ縺吶k縺薙→縺ォ縺ェ繧較ascsi襍キ蜍墓凾縺ョ繧ェ繝励す繝ァ繝ウ謖螳壹→蜷檎ュ峨〒縺吶 + + 迴セ蝨ィ縺ョ迥カ諷九r遒コ隱阪☆繧九↓縺溘a縺ォ-l繧ェ繝励す繝ァ繝ウ縺ョ縺ソ繧呈欠螳壹☆繧九→繝繝舌う繧ケ荳隕ァ縺瑚。ィ遉コ + 縺輔l縺セ縺吶ゅさ繝槭Φ繝峨Λ繧、繝ウ縺ッ荳玖ィ倥ョ騾壹j縲 + + rasctl -l + + rasctl閾ェ菴薙ョ襍キ蜍輔↓縺ッ繝ォ繝シ繝域ィゥ髯舌ッ蠢隕√≠繧翫∪縺帙s縲 + +笆。繝繧」繧ケ繧ッ繝繝ウ繝励ヤ繝シ繝ォ縺ョ菴ソ逕ィ譁ケ豕(rasdump) + 逶エ邨舌b縺励¥縺ッ逶エ邨仙渕譚ソ縲√∪縺溘ッ繝輔Ν繧ケ繝壹ャ繧ッ蝓コ譚ソ蜷代¢縺ョ繧オ繝ウ繝励Ν繝励Ο繧ー繝ゥ繝縺ァ縺吶 + + 蜷榊燕縺ョ騾壹jSCSI HDD繧МO縺ョ繧、繝。繝シ繧ク繧偵ム繝ウ繝(繧ェ繝励す繝ァ繝ウ縺ァ繝ェ繧ケ繝医い)縺励∪縺吶 + 閾ェ霄ォ縺ョID縺ッBID縺ァ謖螳壹@縺ヲ荳九&縺縲ら怐逡・譎ゅッ7繧剃スソ逕ィ縺励∪縺吶 + + rasdump -i ID [-b BID] -f FILE [-r] + ID : 繧ソ繝シ繧イ繝繝医ョ繝舌う繧ケ縺ョSCSI ID + BID : RaSCSI閾ェ霄ォ縺ョSCSI ID + FILE : 繝繝ウ繝励ヵ繧。繧、繝ォ蜷 + -r シ 繝ェ繧ケ繝医い繝「繝シ繝 + + 繧オ繝ウ繝励Ν縺ェ縺ョ縺ァ蠢隕∵怙菴朱剞縺ョ蜃ヲ逅縺励°螳溯」縺励※縺縺セ縺帙s縺ョ縺ァ謾ケ騾縺吶k縺ェ繧翫@縺ヲ + 縺比スソ逕ィ荳九&縺縲 + +笆。SASI蟆ら畑繝繧」繧ケ繧ッ繝繝ウ繝励ヤ繝シ繝ォ縺ョ菴ソ逕ィ譁ケ豕(sasidump) + rasdump繧偵吶シ繧ケ縺ォSASI蟆ら畑縺ォ菴懈舌@縺溘ム繝ウ繝励ヤ繝シ繝ォ縺ァ縺吶 + SASI HD繧、繝。繝シ繧ク繧偵ム繝ウ繝(繧ェ繝励す繝ァ繝ウ縺ァ繝ェ繧ケ繝医い)縺励∪縺吶 + + sasidump -i ID [-u UT] [-b BSIZE] -c COUNT -f FILE [-r] + ID : 繧ソ繝シ繧イ繝繝医ョ繝舌う繧ケ縺ョSASI ID + UT : 繧ソ繝シ繧イ繝繝医ョ繝舌う繧ケ縺ョUNIT ID + BSIZE: 繝悶Ο繝繧ッ繧オ繧、繧コ(繝繝輔か繝ォ繝医ッ512) + COUNT: 繝悶Ο繝繧ッ謨ー + FILE : 繝繝ウ繝励ヵ繧。繧、繝ォ蜷 + -r シ 繝ェ繧ケ繝医い繝「繝シ繝 + +笆。繧ス繝シ繧ケ縺九i螳溯。後ヵ繧。繧、繝ォ繧偵さ繝ウ繝代う繝ォ縺吶k蝣エ蜷 + 繧ケ繧ソ繝ウ繝繝シ繝臥沿 + make CONNECT_TYPE=STANDARD + + 繝輔Ν繧ケ繝壹ャ繧ッ迚 + make CONNECT_TYPE=FULLSPEC + + 縺ゅ>縺シ繧迚 + make CONNECT_TYPE=AIBOM + + GAMERnium迚 + make CONNECT_TYPE=GAMERNIUM + +笆。繧オ繝昴シ繝医☆繧九ョ繧」繧ケ繧ッ繧、繝。繝シ繧ク + (1)SCSI 繝上シ繝峨ョ繧」繧ケ繧ッ + HDS繝輔ぃ繧、繝ォ蠖「蠑 (諡。蠑オ蟄食DS/HDN/HDI/NHD/HDA) + 繝輔ぃ繧、繝ォ繧オ繧、繧コ縺ッ10MB莉・荳4095MB莉・荳九ョ遽蝗イ縺ァ莉サ諢上ョ繧オ繧、繧コ(菴縺512繝舌う繝亥腰菴) + + 諡。蠑オ蟄舌′"HDN"縺ョ蝣エ蜷医ッNEC邏疲ュ」55繝懊シ繝(PC-9801-55)蜷代¢縺ョ邏疲ュ」繝上シ繝峨ョ繧」繧ケ繧ッ + 繧ィ繝溘Η繝ャ繝シ繧キ繝ァ繝ウ繧定。後>縺セ縺吶INQUIRY縺ァ霑泌唆縺輔l繧区ュ蝣ア繧МODE SENSE縺ョ繧オ繧、繧コ縺ォ + 縺ォ驕輔>縺後≠繧翫∪縺吶 + + 諡。蠑オ蟄舌′"HDI","NHD"縺ョ蝣エ蜷医ッ縺昴l縺槭lPC98繧ィ繝溘Η繝ャ繝シ繧ソ縺ァ縺ゅkAnex86蜿翫ウT98Next + 縺ョSCSI繝上シ繝峨ョ繧」繧ケ繧ッ繧、繝。繝シ繧ク繧剃スソ逕ィ縺吶k繧ゅョ縺ァ縺吶HDN縺ョ譎ゅ→蜷梧ァ倥↓荳驛ィ縺ョ諠蝣ア + 縺君EC逕ィ縺ォ螟画鋤縺輔l縺セ縺吶 + + 諡。蠑オ蟄舌′"HDA"縺ョ蝣エ蜷医ッAPPLE邏疲ュ」繝上シ繝峨ョ繧」繧ケ繧ッ繧ィ繝溘Η繝ャ繝シ繧キ繝ァ繝ウ繧定。後>縺セ縺吶 + INQUIRY蜿翫ウMODE SENSE縺ァ霑泌唆縺輔l繧区ュ蝣ア縺ォ驕輔>縺後≠繧翫∪縺吶 + + (2)SASI 繝上シ繝峨ョ繧」繧ケ繧ッ + HDF繝輔ぃ繧、繝ォ蠖「蠑 (諡。蠑オ蟄食DF) + 繝輔ぃ繧、繝ォ繧オ繧、繧コ縺ッ10441728繝舌う繝医20748288繝舌う繝医41496576繝舌う繝医ョ縺縺壹l縺 + (縺昴l縺槭l10MB繝峨Λ繧、繝悶20MB繝峨Λ繧、繝悶40MB繝峨Λ繧、繝悶↓蟇セ蠢)繧呈耳螂ィ縺励∪縺吶 + 256繝舌う繝亥腰菴阪〒縺ゅl縺ー10Mス512M縺ョ莉サ諢上ョ繝輔ぃ繧、繝ォ繧オ繧、繧コ縺後槭え繝ウ繝亥庄閭ス縺ァ縺吶 + + Version1.46縺九i22437888繝舌う繝医ョ繧、繝。繝シ繧ク縺ッMZ-2500/MZ-2800 MZ-1F23蟆ら畑縺ョ + 20MB繧、繝。繝シ繧ク縺ィ縺励※隱崎ュ倥@縺セ縺(繝悶Ο繝繧ッ繧オ繧、繧コ縺1024縺ィ縺縺迚ケ谿翫う繝。繝シ繧ク)縲 + + (3)SCSI 蜈臥」∵ー(MO)繝繧」繧ケ繧ッ + MOS繝輔ぃ繧、繝ォ蠖「蠑 (諡。蠑オ蟄信OS) + 繝輔ぃ繧、繝ォ繧オ繧、繧コ縺ッ谺。縺ョ4遞ョ鬘槭ョ縺縺壹l縺具シ + 128MB繧ソ繧、繝 (127398912繝舌う繝) + 230MB繧ソ繧、繝 (228518400繝舌う繝) + 540MB繧ソ繧、繝 (533248000繝舌う繝) + 640MB繧ソ繧、繝 (635600896繝舌う繝) + 128MB,230MB,540MB縺ッ512繝舌う繝/繧サ繧ッ繧ソ縲640MB縺ッ2048繝舌う繝/繧サ繧ッ繧ソ縺ォ縺ェ繧翫∪縺吶 + + (4)SCSI CD-ROM繝繧」繧ケ繧ッ + ISO繝輔ぃ繧、繝ォ蠖「蠑 (諡。蠑オ蟄蝕SO縲!SO9660繝吶ち繧、繝。繝シ繧ク) + 繝「繝シ繝1(2048繝舌う繝/繧サ繧ッ繧ソ)縺ァ縲√ョ繝シ繧ソ縺ョ縺ソ譬シ邏阪&繧後◆繝輔ぃ繧、繝ォ縺ィRAW蠖「蠑上〒險倬鹸 + 縺輔l縺溘ヵ繧。繧、繝ォ縺ョ荳。譁ケ縺ォ蟇セ蠢懊@縺ヲ縺縺セ縺吶 + +笆。繝繧」繧ケ繧ッ繧、繝。繝シ繧ク縺ョ菴懈 + RaSCSI閾ェ菴薙′X68000繧ィ繝溘Η繝ャ繝シ繧ソ縺ァ縺ゅkXM6 TypeG縺ョ豢セ逕溽黄縺ァ縺吶ょセ薙▲縺ヲ繝繧」繧ケ繧ッ + 繧、繝。繝シ繧ク縺ョ菴懈舌ッXM6 TypeG縺ョ縲後ヤ繝シ繝ォ縲阪Γ繝九Η繝シ縺九i陦後≧縺薙→繧貞燕謠舌→縺励※縺縺セ縺吶 + 繧ゅ■繧阪s蜈医↓隱ャ譏弱@縺滉サ墓ァ倥↓蠕薙∴縺ーdd遲峨〒遨コ縺ョ繧、繝。繝シ繧ク繝輔ぃ繧、繝ォ繧剃ス懈舌☆繧九%縺ィ繧 + 蜿ッ閭ス縺ァ縺吶 + + 萓具シ100MB縺ョHDS繧、繝。繝シ繧ク(遨コ繝輔ぃ繧、繝ォ)繧剃ス懊k蝣エ蜷 + + dd if=/dev/zero of=HARDDISK.HDS bs=512 count=204800 + +笆。蜍穂ス懷ョ溽クセ + 菴懆縺ョ髢狗匱迺ー蠅縺ァ縺ゅkX68000 PRO(蜀阡オSASI/邏疲ュ」SCSI繝懊シ繝)縲々68030 蜀阡オSCSI縲 + XVI Compact 蜀阡オSCSI縺ァ蜍穂ス懃「コ隱阪@縺ヲ縺縺セ縺吶Mach-2縺ァ繧ょ虚菴懊@縺セ縺励◆縲 + + 莉悶↓繧ょ昜サ」X68000,ACE,EXPERT,XVI,PRO2,SUPER遲峨〒蜍穂ス懷ア蜻翫′縺ゅj縺セ縺励◆縺ョ縺ァ縲 + X68000繧キ繝ェ繝シ繧コ縺ッ縺サ縺シ蝠城。後↑縺縺ァ縺励g縺縲 + + 縺昴ョ莉悶ョ繝ャ繝医ΟPC縺ァ縺ッFM TOWNS繧キ繝ェ繝シ繧コ縲、pple Macintosh縲`SX(MEGA-SCSI蛻ゥ逕ィ) + 縺ァ蜍穂ス懷ア蜻翫′縺ゅj縺セ縺吶1C98繧キ繝ェ繝シ繧コ縺ッ蜍穂ス懊@縺溘→縺縺蝣ア蜻翫b螟壽焚縺ゅj縺セ縺吶′縲 + SCSI繝懊シ繝峨↓繧医▲縺ヲ縺ッ蜈ィ縺丞虚菴懊@縺ェ縺縺ィ縺縺蝣ア蜻翫b縺ゅj縺セ縺吶 + +笆。豢サ逕ィ譁ケ豕 +縲XM6遲峨ョX68000繧ィ繝溘Η繝ャ繝シ繧ソ繧剃スソ逕ィ縺励※縺繧句エ蜷医ッ繧ィ繝溘Η繝ャ繝シ繧ソ縺ァ迺ー蠅讒狗ッ峨@縺櫞DD + 繧、繝。繝シ繧ク繧巽TP遲峨〒Raspberry Pi縺ォ霆「騾√☆繧九%縺ィ縺ァX68000縺ョ螳滓ゥ溘↓謗・邯壹〒縺阪∪縺吶 + 縺セ縺溘◎縺ョ騾繧ら┯繧翫〒螳滓ゥ滉ク翫↓蟄伜惠縺吶k繝輔ぃ繧、繝ォ繧呈シ邏阪@縺櫞DD繧、繝。繝シ繧ク繧単C縺ォFTP遲 + 縺ァ霆「騾√☆繧九%縺ィ縺ァ繧ィ繝溘Η繝ャ繝シ繧ソ縺ァ豢サ逕ィ縺吶k縺薙→縺後〒縺阪∪縺吶 + +笆。繝ゥ繧、繧サ繝ウ繧ケ + RaSCSI縺ッ縺ゅk縺後∪縺セ"AS IS"縺ァ驟榊ク縺輔l繧九た繝輔ヨ繧ヲ繧ァ繧「縺ァ縺吶 + + 縺、縺セ繧贋スソ逕ィ閠縺悟女縺代◆縺ゅi繧繧区錐螳ウ縺ォ蟇セ縺励※荳蛻雋ャ莉サ繧呈戟縺。縺セ縺帙s縲ゅ∪縺溘た繝輔ヨ + 繧ヲ繧ァ繧「縺ォ荳榊y繧ゅ@縺上ッ荳榊キ蜷医′縺ゅ▲縺溘→縺励※繧ゅ◎繧後r菫ョ豁」縺吶k雋ャ莉サ繧ゅ≠繧翫∪縺帙s縲 + + RaSCSI繧貞茜逕ィ縺吶k縺薙→縺ァRaspberry Pi繧繝ャ繝医ΟPC縺梧腐髫懊☆繧九Μ繧ケ繧ッ縺後≠繧翫∪縺吶 + 縺ゅ¥縺セ縺ァ閾ェ蟾ア雋ャ莉サ縺ァ繝√Ε繝ャ繝ウ繧ク縺励※縺上□縺輔>縲 + + XM6 TypeG蜷梧ァ倥↓螳滄ィ捺先棡蜈ャ髢九→縺縺諤ァ雉ェ荳顔ァ√ョHP莉・螟悶〒縺ョ驟榊ク繧定ェ阪a縺ヲ縺翫j縺セ縺帙s縲 + + XM6縺ョ繝ゥ繧、繧サ繝ウ繧ケ譚。鬆繧堤カ呎価縺励※縺縺セ縺吶ョ縺ァ髮題ェ/譖ク邀阪〒縺ョ邏ケ莉倶コ句燕縺ョ險ア隲セ縺悟ソ隕√〒縺吶 + 縺昴b縺昴b2019蟷エ縺ォ繧ゅ↑縺」縺ヲSCSI縺ォ蜿榊ソ懊☆繧九ョ縺ッ髯舌i繧後◆莠コ縺縺代□縺ィ諤昴>縺セ縺吶 + +笆。螟画鋤蝓コ譚ソ縺ョ鬆貞ク縺ォ縺、縺縺ヲ + 螟画鋤蝓コ譚ソ繧呈怏蜆溘〒鬆貞ク縺吶k蝣エ蜷医ッ荳玖ィ倥ョ譚。莉カ縺ォ蠕薙≧髯舌j菴懆縺ォ險ア隲セ繧貞セ励k蠢隕√ッ + 縺ゅj縺セ縺帙s縲る崎ヲ√↑縺薙→縺ッ蝓コ譚ソ繧定ウシ蜈・縺励◆繝ヲ繝シ繧カ繝シ縺ォ蜊∝縺ェ諠蝣ア繧呈署萓帙☆繧九%縺ィ縺ィ + 蠢蠕励※荳九&縺縲 + + 1.鬆貞ク萓。譬シ + 蝓コ譚ソ陬ス菴懆イサ シ 繝代シ繝雋サ逕ィ シ 驕矩∬イサ シ具シ育、セ莨夐壼ソオ荳贋ク闊ャ逧縺ェシ画焔謨ー譁吶 + + 2.蝗櫁キッ蝗ウ + 雉シ蜈・閠縺ォ蝗櫁キッ蝗ウ繧呈署萓帙@縺ヲ荳九&縺縲ょ渕譚ソ鬆貞ク縺ィ蜷梧凾繧ゅ@縺上ッ蛻・騾斐帙シ繝繝壹シ繧ク縺九i + 縺ョ繝繧ヲ繝ウ繝ュ繝シ繝臥ュ画焔谿オ縺ッ閾ェ逕ア縺ァ縺吶 + + 3.蜍穂ス懈、懆ィシ + X68000螳滓ゥ溽腸蠅縺ョ蜍穂ス懈、懆ィシ縺ッ蠢鬆医→縺励∪縺吶ょョ滓ゥ溘′謇九↓蜈・繧峨↑縺蝣エ蜷医ッX68000 + 繝ヲ繝シ繧カ繝シ縺ョ譁ケ縺ォ讀懆ィシ縺ョ蜊泌鴨繧偵♀鬘倥>縺励※繧ゅh縺縺ァ縺励g縺縲ょ虚菴懈、懆ィシ縺ッ襍キ蜍慕「コ隱堺サ・螟 + 縺ォ譖ク縺崎セシ縺ソ繧雋闕キ繝繧ケ繝医r縺企。倥>縺励∪縺吶よ、懆ィシ邨先棡縺ッ菴ソ逕ィ縺励◆迺ー蠅繧縺ィ蜈ア縺ォ蜈ャ髢 + 縺励※荳九&縺縲 + +笆。螟画鋤蝓コ譚ソシ亥ャ蠑冗沿シ峨↓縺、縺縺ヲ + BOOTH縺ァ2019蟷エ3譛井サ・髯埼榊ク縺励※縺縺セ縺(謨ー縺ォ髯舌j縺後≠繧翫∪縺吶ョ縺ァ荳榊ョ壽悄縺ァ縺)縲 + +笆。蜈ャ髢九帙シ繝繝壹シ繧ク + http://retropc.net/gimons/rascsi/ + +笆。騾」邨。蜈 + twitter https://twitter.com/kugimoto0715 + e-mail gimons.developer.works@gmail.com + +[EOF] diff --git a/doc/target.png b/doc/target.png index 52c28cc5..b25e1049 100644 Binary files a/doc/target.png and b/doc/target.png differ diff --git a/doc/x68k.txt b/doc/x68k.txt index 16bc9dec..de40ac49 100644 --- a/doc/x68k.txt +++ b/doc/x68k.txt @@ -1,109 +1,114 @@ ------------------------------------------------------------------------------- - - SCSI Target Emulator RaSCSI (*^..^*) - version 1.33 for Raspberry Pi - - Powered by XM6 TypeG Technology. - Copyright (C) 2016-2018 GIMONS - ------------------------------------------------------------------------------- -□X68000固有の機能について - RaSCSIにはブリッジデバイスという仮想的なSCSIデバイスが実装されておりX68000と - ホストであるRaspberry Piの橋渡しを行うことができます。このブリッジデバイスと - X68000用の専用ドライバを使用して下記の機能を提供します。 - - ・イーサーネット - Neptune-Xと同様のイーサーネット機能を提供します。SCSI接続のイーサーネット - BOXのようにRaSCSIが振舞います。Raspberry PiのTAPデバイスにパケットを中継 - することで実現しています。Ether+と似たものです。 - - ・ホストファイルシステム - X68000のエミュレーターでは標準的な機能であるWindrv相当の機能を提供します。 - Raspberry Pi上のファイルシステムをリモートドライブとしてマウントすること - ができます。 - -□ブジッジデバイスの起動方法 - RaSCSI起動時にファイル名として"BRIDGE"というキーワードを設定するとそのIDに - 対してブジッリデバイスを生成します。 - - ex) - sudo rascsi -ID0 HDIMAGE0.HDS -ID6 BRIDGE - -□イーサーネット接続 - 配布物に含まれるRASETHER.SYSを使用します。このデバイスドライバがブリッジ - デバイスと連携してイーサーネットのパケット送受信を行うことができます。 - - 以下、Raspberry Piの仮想アダプタ(TAP)のIPアドレスを「192.168.68.1」として、 - X68000側を「192.168.68.3」とするケースで説明します。 - - ・X68000の設定 - RASETHER.SYSはNeptune-X用ドライバを改造して作ったものですので使用方法は - 全く同じです。X68000をネット接続するためには他に環境設定を行う必要があり - ます。設定方法は自力で調べていただくようお願いします。 - - 以下実際に使用しているCONFIG.SYSとAUTOEXEC.BATの抜粋です。 - - [CONFIG.SYS抜粋] - PROCESS = 3 10 10 - DEVICE = \NETWORK\RASETHER.SYS - - [AUTOEXEC.BAT抜粋] - SET SYSROOT=A:/NETWORK/ - SET temp=A:\ - SET tmp=A:\ - SET HOME=A:/NETWORK/ETC/ - SET HOST=X68000 - XIP.X - IFCONFIG.X lp0 up - IFCONFIG.X en0 192.168.68.3 netmask 255.255.255.0 up - INETDCONF.X +router 192.168.68.1 -rip - INETDCONF.X - - ・Raspberry Piの設定 - TAPデバイスというものを利用していますのでTAPを有効にしてください。恐らく - 最近のJessieであれば最初から有効なはずです。確認方法は/dev/net/tunという - ファイルが存在すれば有効となっていると判断できます。 - - 仮想アダプタの作成方法は次の様に行います。 - - [/etc/rc.local等から設定] - ip tuntap add ras0 mode tap user root - ip link set ras0 up - ifconfig ras0 inet 192.168.68.1/8 up - route add -net 192.168.68.0 netmask 255.255.255.0 dev ras0 - - 上記によってRaspberry Pi(192.168.68.1)とX68000(192.168.68.3)の間で通信が - 可能になります。 - - インターネット等と接続する場合はRaspberry Pi側でブリッジやルーティングの - 設定が必要になります。ご自身の環境に合わせて設定してください。無線LANの - 場合にブリッジ構成するには色々と課題があるようなのでフォワーディングと - NAT構成等もお勧めです。作者はrc.localで次のような設定で使用しています。 - - echo 1 > /proc/sys/net/ipv4/ip_forward - iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE - -□ホストファイルシステム連携 - X68000エミュレータでよく利用されるWindrvやWindrvXMと同等の機能を提供します。 - 専用のRASDRV.SYSというデバイスドライバを組み込めばRaspberri Piのファイル - システムがX68000側のドライブに見えて操作できるということです。 - - デバイスドライバの登録は簡単です。 - 例えば - - DEVICE = \SYS\RASDRV.SYS - - この場合はデフォルトでRaspberry Piのルートディレクトリをマウントします。 - デバイスドライバ起動時にどのドライブにマウントされたか表示されます。 - ルートを以外をマウントする場合はディレクトリを指定して下さい。/home/pi等を - マウントするには - - DEVICE = \SYS\RASDRV.SYS /home/pi - - と指定します。複数のディレクトリを指定すれば別々のドライブとしてマウントする - ことが可能です。 - - SUSIEをご利用の方はSUSIEより先にRASDRV.SYSを組み込んで下さい。後に組み込むと - 正しく認識できなくなると報告があります。 - -[EOF] +------------------------------------------------------------------------------ + + SCSI Target Emulator RaSCSII (*^..^*) + for Raspberry Pi + + Powered by XM6 TypeG Technology. + Copyright (C) 2016-2020 GIMONS + +------------------------------------------------------------------------------ +笆。X68000蝗コ譛峨ョ讖溯ス縺ォ縺、縺縺ヲ + RaSCSI縺ォ縺ッ繝悶Μ繝繧ク繝繝舌う繧ケ縺ィ縺縺莉ョ諠ウ逧縺ェSCSI繝繝舌う繧ケ縺悟ョ溯」縺輔l縺ヲ縺翫jX68000縺ィ + 繝帙せ繝医〒縺ゅkRaspberry Pi縺ョ讖区ク。縺励r陦後≧縺薙→縺後〒縺阪∪縺吶ゅ%縺ョ繝悶Μ繝繧ク繝繝舌う繧ケ縺ィ + X68000逕ィ縺ョ蟆ら畑繝峨Λ繧、繝舌r菴ソ逕ィ縺励※荳玖ィ倥ョ讖溯ス繧呈署萓帙@縺セ縺吶 + + 繝サ繧、繝シ繧オ繝シ繝阪ャ繝 + Neptune-X縺ィ蜷梧ァ倥ョ繧、繝シ繧オ繝シ繝阪ャ繝域ゥ溯ス繧呈署萓帙@縺セ縺吶4CSI謗・邯壹ョ繧、繝シ繧オ繝シ繝阪ャ繝 + BOX縺ョ繧医≧縺ォRaSCSI縺梧険闊槭>縺セ縺吶3aspberry Pi縺ョTAP繝繝舌う繧ケ縺ォ繝代こ繝繝医r荳ュ邯 + 縺吶k縺薙→縺ァ螳溽樟縺励※縺縺セ縺吶Ether+縺ィ莨シ縺溘b縺ョ縺ァ縺吶 + + 繝サ繝帙せ繝医ヵ繧。繧、繝ォ繧キ繧ケ繝繝 + X68000縺ョ繧ィ繝溘Η繝ャ繝シ繧ソ繝シ縺ァ縺ッ讓呎コ也噪縺ェ讖溯ス縺ァ縺ゅkWindrv逶ク蠖薙ョ讖溯ス繧呈署萓帙@縺セ縺吶 + Raspberry Pi荳翫ョ繝輔ぃ繧、繝ォ繧キ繧ケ繝繝繧偵Μ繝「繝シ繝医ラ繝ゥ繧、繝悶→縺励※繝槭え繝ウ繝医☆繧九%縺ィ + 縺後〒縺阪∪縺吶 + +笆。繝悶ず繝繧ク繝繝舌う繧ケ縺ョ襍キ蜍墓婿豕 + RaSCSI襍キ蜍墓凾縺ォ繝輔ぃ繧、繝ォ蜷阪→縺励※"BRIDGE"縺ィ縺縺繧ュ繝シ繝ッ繝シ繝峨r險ュ螳壹☆繧九→縺昴ョID縺ォ + 蟇セ縺励※繝悶ず繝繝ェ繝繝舌う繧ケ繧堤函謌舌@縺セ縺吶 + + ex) + sudo rascsi -ID0 HDIMAGE0.HDS -ID6 BRIDGE + +笆。蟆ら畑繝峨Λ繧、繝 + 驟榊ク迚ゥ縺ォ蜷ォ縺セ繧後kRASDRIVER.XDF繧ゅ@縺上ッRASDRIVER.HDS縺ォ莠後▽縺ョ繝峨Λ繧、繝舌′蜷ォ縺セ繧 + 縺ヲ縺縺セ縺吶3aSCSI縺ァRASDRIVER.HDS繧偵槭え繝ウ繝医@驕ゥ螳懊さ繝斐シ縺励◆譁ケ縺悟ョ滓ゥ溘∈縺ョ霆「騾√′ + 邁。蜊倥〒縺励g縺縲 + +笆。繧、繝シ繧オ繝シ繝阪ャ繝域磁邯 + 繧、繝シ繧オ繝阪ャ繝医ラ繝ゥ繧、繝(RASETHER.SYS)縺後ヶ繝ェ繝繧ク繝繝舌う繧ケ縺ィ騾」謳コ縺励※繧、繝シ繧オ繝シ繝阪ャ繝 + 縺ョ繝代こ繝繝磯∝女菫。繧定。後≧縺薙→縺後〒縺阪∪縺吶 + + 莉・荳九ヽaspberry Pi縺ョ莉ョ諠ウ繧「繝繝励ち(TAP)縺ョIP繧「繝峨Ξ繧ケ繧偵192.168.68.1縲阪→縺励※縲 + X68000蛛エ繧偵192.168.68.3縲阪→縺吶k繧ア繝シ繧ケ縺ァ隱ャ譏弱@縺セ縺吶 + + 繝サX68000縺ョ險ュ螳 + RASETHER.SYS縺ッNeptune-X逕ィ繝峨Λ繧、繝舌r謾ケ騾縺励※菴懊▲縺溘b縺ョ縺ァ縺吶ョ縺ァ菴ソ逕ィ譁ケ豕輔ッ + 蜈ィ縺丞酔縺倥〒縺吶968000繧偵ロ繝繝域磁邯壹☆繧九◆繧√↓縺ッ莉悶↓迺ー蠅險ュ螳壹r陦後≧蠢隕√′縺ゅj + 縺セ縺吶りィュ螳壽婿豕輔ッ閾ェ蜉帙〒隱ソ縺ケ縺ヲ縺縺溘□縺上h縺縺企。倥>縺励∪縺吶 + + 莉・荳句ョ滄圀縺ォ菴ソ逕ィ縺励※縺繧気ONFIG.SYS縺ィAUTOEXEC.BAT縺ョ謚懃イ九〒縺吶 + + [CONFIG.SYS謚懃イ犠 + PROCESS = 3 10 10 + DEVICE = \NETWORK\RASETHER.SYS + + [AUTOEXEC.BAT謚懃イ犠 + SET SYSROOT=A:/NETWORK/ + SET temp=A:\ + SET tmp=A:\ + SET HOME=A:/NETWORK/ETC/ + SET HOST=X68000 + XIP.X + IFCONFIG.X lp0 up + IFCONFIG.X en0 192.168.68.3 netmask 255.255.255.0 up + INETDCONF.X +router 192.168.68.1 -rip + INETDCONF.X + + 繝サRaspberry Pi縺ョ險ュ螳 + TAP繝繝舌う繧ケ縺ィ縺縺繧ゅョ繧貞茜逕ィ縺励※縺縺セ縺吶ョ縺ァTAP繧呈怏蜉ケ縺ォ縺励※縺上□縺輔>縲よ$繧峨¥ + 譛霑代ョJessie縺ァ縺ゅl縺ー譛蛻昴°繧画怏蜉ケ縺ェ縺ッ縺壹〒縺吶ら「コ隱肴婿豕輔ッ/dev/net/tun縺ィ縺縺 + 繝輔ぃ繧、繝ォ縺悟ュ伜惠縺吶l縺ー譛牙柑縺ィ縺ェ縺」縺ヲ縺繧九→蛻、譁ュ縺ァ縺阪∪縺吶 + + 莉ョ諠ウ繧「繝繝励ち縺ョ菴懈先婿豕輔ッ谺。縺ョ讒倥↓陦後>縺セ縺吶 + + [/etc/rc.local遲峨°繧芽ィュ螳咯 + ip tuntap add ras0 mode tap user root + ip link set ras0 up + ifconfig ras0 inet 192.168.68.1/8 up + route add -net 192.168.68.0 netmask 255.255.255.0 dev ras0 + + 荳願ィ倥↓繧医▲縺ヲRaspberry Pi(192.168.68.1)縺ィX68000(192.168.68.3)縺ョ髢薙〒騾壻ソ。縺 + 蜿ッ閭ス縺ォ縺ェ繧翫∪縺吶 + + 繧、繝ウ繧ソ繝シ繝阪ャ繝育ュ峨→謗・邯壹☆繧句エ蜷医ッRaspberry Pi蛛エ縺ァ繝悶Μ繝繧ク繧繝ォ繝シ繝繧」繝ウ繧ー縺ョ + 險ュ螳壹′蠢隕√↓縺ェ繧翫∪縺吶ゅ#閾ェ霄ォ縺ョ迺ー蠅縺ォ蜷医o縺帙※險ュ螳壹@縺ヲ縺上□縺輔>縲ら┌邱哭AN縺ョ + 蝣エ蜷医↓繝悶Μ繝繧ク讒区舌☆繧九↓縺ッ濶イ縲縺ィ隱イ鬘後′縺ゅk繧医≧縺ェ縺ョ縺ァ繝輔か繝ッ繝シ繝繧」繝ウ繧ー縺ィ + NAT讒区千ュ峨b縺雁匡繧√〒縺吶ゆス懆縺ッrc.local縺ァ谺。縺ョ繧医≧縺ェ險ュ螳壹〒菴ソ逕ィ縺励※縺縺セ縺吶 + + echo 1 > /proc/sys/net/ipv4/ip_forward + iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE + +笆。繝帙せ繝医ヵ繧。繧、繝ォ繧キ繧ケ繝繝騾」謳コ + X68000繧ィ繝溘Η繝ャ繝シ繧ソ縺ァ繧医¥蛻ゥ逕ィ縺輔l繧妓indrv繧ЦindrvXM縺ィ蜷檎ュ峨ョ讖溯ス繧呈署萓帙@縺セ縺吶 + 蟆ら畑縺ョRASDRV.SYS縺ィ縺縺繝繝舌う繧ケ繝峨Λ繧、繝舌r邨縺ソ霎シ繧√ーRaspberri Pi縺ョ繝輔ぃ繧、繝ォ + 繧キ繧ケ繝繝縺傾68000蛛エ縺ョ繝峨Λ繧、繝悶↓隕九∴縺ヲ謫堺ス懊〒縺阪k縺ィ縺縺縺薙→縺ァ縺吶 + + 繝繝舌う繧ケ繝峨Λ繧、繝舌ョ逋サ骭イ縺ッ邁。蜊倥〒縺吶 + 萓九∴縺ー + + DEVICE = \SYS\RASDRV.SYS + + 縺薙ョ蝣エ蜷医ッ繝繝輔か繝ォ繝医〒Raspberry Pi縺ョ繝ォ繝シ繝医ョ繧」繝ャ繧ッ繝医Μ繧偵槭え繝ウ繝医@縺セ縺吶 + 繝繝舌う繧ケ繝峨Λ繧、繝占オキ蜍墓凾縺ォ縺ゥ縺ョ繝峨Λ繧、繝悶↓繝槭え繝ウ繝医&繧後◆縺玖。ィ遉コ縺輔l縺セ縺吶 + 繝ォ繝シ繝医r莉・螟悶r繝槭え繝ウ繝医☆繧句エ蜷医ッ繝繧」繝ャ繧ッ繝医Μ繧呈欠螳壹@縺ヲ荳九&縺縲/home/pi遲峨r + 繝槭え繝ウ繝医☆繧九↓縺ッ + + DEVICE = \SYS\RASDRV.SYS /home/pi + + 縺ィ謖螳壹@縺セ縺吶り、謨ー縺ョ繝繧」繝ャ繧ッ繝医Μ繧呈欠螳壹☆繧後ー蛻・縲縺ョ繝峨Λ繧、繝悶→縺励※繝槭え繝ウ繝医☆繧 + 縺薙→縺悟庄閭ス縺ァ縺吶 + + SUSIE繧偵#蛻ゥ逕ィ縺ョ譁ケ縺ッSUSIE繧医j蜈医↓RASDRV.SYS繧堤オ縺ソ霎シ繧薙〒荳九&縺縲ょセ後↓邨縺ソ霎シ繧縺ィ + 豁」縺励¥隱崎ュ倥〒縺阪↑縺上↑繧九→蝣ア蜻翫′縺ゅj縺セ縺吶 + +[EOF] diff --git a/src/raspberrypi/Makefile b/src/raspberrypi/Makefile index 70eb4cef..97d7b136 100644 --- a/src/raspberrypi/Makefile +++ b/src/raspberrypi/Makefile @@ -1,13 +1,19 @@ CC = gcc -CFLAGS = -DNDEBUG -O3 +CFLAGS = -DNDEBUG -O3 -Wall 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 RASCTL = rasctl RASDUMP = rasdump +SASIDUMP = sasidump -BIN_ALL = $(RASCSI) $(RASCTL) $(RASDUMP) +BIN_ALL = $(RASCSI) $(RASCTL) $(RASDUMP) $(SASIDUMP) SRC_RASCSI = \ rascsi.cpp \ @@ -29,23 +35,35 @@ SRC_RASDUMP = \ filepath.cpp \ fileio.cpp -OBJ_RASCSI := $(SRC_RASCSI:.cpp=.o) -OBJ_RASCTL := $(SRC_RASCTL:.c=.o) -OBJ_RASDUMP := $(SRC_RASDUMP:.c=.o) +SRC_SASIDUMP = \ + sasidump.cpp \ + scsi.cpp \ + gpiobus.cpp \ + filepath.cpp \ + fileio.cpp -.cpp.o: - $(CXX) $(CXXFLAGS) -c $< +OBJ_RASCSI := $(SRC_RASCSI:%.cpp=%.o) +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) -$(RASCSI): $(OBJ_RASCSI) $ +$(RASCSI): $(OBJ_RASCSI) $(CXX) -o $@ $(OBJ_RASCSI) -lpthread -$(RASCTL): $(OBJ_RASCTL) $ +$(RASCTL): $(OBJ_RASCTL) $(CXX) -o $@ $(OBJ_RASCTL) -$(RASDUMP): $(OBJ_RASDUMP) $ +$(RASDUMP): $(OBJ_RASDUMP) $(CXX) -o $@ $(OBJ_RASDUMP) +$(SASIDUMP): $(OBJ_SASIDUMP) + $(CXX) -o $@ $(OBJ_SASIDUMP) + clean: - rm -f *.o $(BIN_ALL) + rm -f $(OBJ_ALL) $(BIN_ALL) diff --git a/src/raspberrypi/cfilesystem.cpp b/src/raspberrypi/cfilesystem.cpp index 347814da..76ee30db 100644 --- a/src/raspberrypi/cfilesystem.cpp +++ b/src/raspberrypi/cfilesystem.cpp @@ -4,9 +4,10 @@ // for Raspberry Pi // // 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 sava's bugfix patch(in RASDRV DOS edition). // // [ 繝帙せ繝医ヵ繧。繧、繝ォ繧キ繧ケ繝繝 ] // @@ -18,6 +19,36 @@ #include "filepath.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 static char convert_buf[IC_BUF_SIZE]; +#ifndef BAREMETAL #ifndef __NetBSD__ // POSIX.1貅匁侠iconv(3)繧剃スソ逕ィ #define CONVERT(src, dest, inbuf, outbuf, outsize) \ @@ -61,6 +93,18 @@ static void convert(char const *src, char const *dest, iconv_close(cd); *outbuf = '\0'; } +#else +// Newlib縺ョ荳ュ縺ォiconv縺悟性縺セ繧後※縺ェ縺九▲縺溘ョ縺ァ辟。螟画鋤 +// 繝吶い繝。繧ソ繝ォ縺ョFatFS荳翫ッSJIS縺ァ繧0K縺縺ィ諤昴≧繧 +#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 - strcpy(m_szVolumeCache, m_szBase); + strcpy(m_szVolumeCache, "RASDRV "); + if (m_szBase[0]) { + strcat(m_szVolumeCache, m_szBase); + } else { + strcat(m_szVolumeCache, "/"); + } #else m_szVolumeCache[0] = _T('\0'); #endif @@ -578,15 +677,17 @@ CHostPath* CHostDrv::CopyCache(CHostFiles* pFiles) // 繧ュ繝」繝繧キ繝・讀懃エ「 CHostPath* pPath = FindCache(pFiles->GetHumanPath()); - if (pPath == NULL) + if (pPath == NULL) { return NULL; // 繧ィ繝ゥ繝シ: 繧ュ繝」繝繧キ繝・縺ェ縺 + } // 繝ェ繝ウ繧ー蜈磯ュ縺ク遘サ蜍 pPath->Insert(&m_cRing); // 繧ュ繝」繝繧キ繝・譖エ譁ー繝√ぉ繝繧ッ - if (pPath->isRefresh()) + if (pPath->isRefresh()) { return NULL; // 繧ィ繝ゥ繝シ: 繧ュ繝」繝繧キ繝・譖エ譁ー縺悟ソ隕 + } // 繝帙せ繝亥エ縺ョ繝代せ蜷阪r菫晏ュ pFiles->SetResult(pPath->GetHost()); @@ -676,6 +777,9 @@ CHostPath* CHostDrv::MakeCache(CHostFiles* pFiles) // 繧ュ繝」繝繧キ繝・譖エ譁ー繝√ぉ繝繧ッ if (pPath->isRefresh()) { + // 譖エ譁ー + Update(); + // 迥カ諷区峩譁ー pPath->Refresh(); } @@ -1320,6 +1424,13 @@ int CHostPath::Compare(const BYTE* pFirst, const BYTE* pLast, const BYTE* pBufFi if ('A' <= d && d <= 'Z') d += 'a' - 'A'; // 蟆乗枚蟄怜喧 } + // 繝舌ャ繧ッ繧ケ繝ゥ繝繧キ繝・繧偵せ繝ゥ繝繧キ繝・縺ォ邨ア荳縺励※豈碑シ縺吶k + if (c == '\\') { + c = '/'; + } + if (d == '\\') { + d = '/'; + } } else { // c縺縺代′1繝舌う繝育岼 if ((0x80 <= c && c <= 0x9F) || 0xE0 <= c) { // 蜴ウ蟇縺ォ縺ッ 0x81ス0x9F 0xE0ス0xEF bSkip0 = TRUE; @@ -1537,6 +1648,151 @@ BOOL CHostPath::isRefresh() 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; + } + + // 繝ェ繧ケ繝医r蛻晄悄蛟、縺ァ遒コ菫(縺ィ繧翫≠縺医★32) + used = 0; + allocated = 32; + namelist = (dirent **)malloc(allocated * sizeof(dirent *)); + if (!namelist) { + goto error; + } + + // 驟堺ク九ョ繝輔ぃ繧、繝ォ縺セ縺溘ッ繝繧」繝ャ繧ッ繝医Μ繧貞ヲ逅 + i = 0; + while (TRUE) { + if (i == 0) { + // "."繧巽ILINFO縺ォ隕九○縺九¢縺ヲ霑ス蜉 + strcpy(fno.fname, "."); + i++; + } else if (i == 1) { + // ".."繧巽ILINFO縺ォ隕九○縺九¢縺ヲ霑ス蜉 + 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縺九i霑泌唆逕ィ縺ォ繧ウ繝斐シ + memcpy(ent, &went, len); + + // 菴ソ逕ィ驥上′雜翫∴縺昴≧縺ェ繧峨Μ繧ケ繝医r蜀咲「コ菫 + 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繧堤オ檎罰縺帙★縺ォ蜈ィ縺ヲ閾ェ蜑阪〒蜃ヲ逅縺吶k縲 BOOL bUpdate = FALSE; - DIR* pd = NULL; - for (DWORD i = 0; i < XM6_HOST_DIRENTRY_FILE_MAX; i++) { + struct dirent **pd = NULL; + int nument = 0; + int maxent = XM6_HOST_DIRENTRY_FILE_MAX; + for (int i = 0; i < maxent; i++) { TCHAR szFilename[FILEPATH_MAX]; if (pd == NULL) { - pd = opendir(S2U(szPath)); - if (pd == NULL) + nument = scandir(S2U(szPath), &pd, NULL, AsciiSort); + if (nument == -1) { + pd = NULL; break; + } + maxent = nument; } + + // 譛荳贋ス阪ョ繧」繝ャ繧ッ繝医Μ縺ェ繧峨き繝ャ繝ウ繝医→繝代Ξ繝ウ繝医r蟇セ雎。螟悶→縺吶k + 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; + } + } + // 繝輔ぃ繧、繝ォ蜷阪r迯イ蠕 - struct dirent* pe = readdir(pd); - if (pe == NULL) - break; strcpy(szFilename, U2S(pe->d_name)); // 繝輔ぃ繧、繝ォ蜷埼伜沺遒コ菫 @@ -1617,8 +1884,12 @@ void CHostPath::Refresh() // 荳閾エ縺吶k繧ゅョ縺後↑縺代l縺ー縲∝ョ溘ヵ繧。繧、繝ォ縺悟ュ伜惠縺吶k縺狗「コ隱 strcpy(szPath, m_szHost); strcat(szPath, (const char*)pFilename->GetHuman()); /// @warning Unicode譎りヲ∽ソョ豁」 竊 貂 +#ifndef BAREMETAL struct stat sb; if (stat(S2U(szPath), &sb)) +#else + if (f_stat(S2U(szPath), NULL) != FR_OK) +#endif // BAREMETAL break; // 蛻ゥ逕ィ蜿ッ閭ス繝代ち繝シ繝ウ繧堤匱隕 } } @@ -1634,6 +1905,7 @@ void CHostPath::Refresh() strcpy(szPath, m_szHost); strcat(szPath, U2S(pe->d_name)); +#ifndef BAREMETAL struct stat sb; if (stat(S2U(szPath), &sb)) continue; @@ -1660,6 +1932,27 @@ void CHostPath::Refresh() } pFilename->SetEntryDate(nHumanDate); 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); @@ -1679,7 +1972,13 @@ void CHostPath::Refresh() pRing->r.InsertTail(&m_cRing); } - closedir(pd); + // 繝繧」繝ャ繧ッ繝医Μ繧ィ繝ウ繝医Μ繧定ァ」謾セ + if (pd) { + for (int i = 0; i < nument; i++) { + free(pd[i]); + } + free(pd); + } // 谿句ュ倥☆繧九く繝」繝繧キ繝・蜀螳ケ繧貞炎髯、 ring_t* p; @@ -1701,6 +2000,7 @@ void CHostPath::Refresh() //--------------------------------------------------------------------------- void CHostPath::Backup() { +#ifndef BAREMETAL ASSERT(this); ASSERT(m_szHost); ASSERT(strlen(m_szHost) < FILEPATH_MAX); @@ -1718,6 +2018,29 @@ void CHostPath::Backup() if (stat(S2U(szPath), &sb) == 0) 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) { // 繝ォ繝シ繝医ョ繧」繝ャ繧ッ繝医Μ縺ョ蝣エ蜷医ッ菴輔b縺励↑縺 + 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 { +#ifndef BAREMETAL ASSERT(this); ASSERT(m_szHost); ASSERT(strlen(m_szHost) < FILEPATH_MAX); @@ -1746,6 +2070,28 @@ void CHostPath::Restore() const ut.modtime = m_tBackup; 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(); } +//--------------------------------------------------------------------------- +// +/// 繝。繝繧」繧「莠、謠帙メ繧ァ繝繧ッ +// +//--------------------------------------------------------------------------- +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); m_bUpdate = FALSE; +#ifndef BAREMETAL m_pFile = NULL; +#else + memset(&m_File, 0x00, sizeof(FIL)); +#endif } //--------------------------------------------------------------------------- @@ -2388,6 +2766,7 @@ BOOL CHostFcb::SetMode(DWORD nHumanMode) { ASSERT(this); +#ifndef BAREMETAL switch (nHumanMode & Human68k::OP_MASK) { case Human68k::OP_READ: m_pszMode = "rb"; @@ -2401,6 +2780,21 @@ BOOL CHostFcb::SetMode(DWORD nHumanMode) default: 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; @@ -2442,8 +2836,9 @@ void CHostFcb::SetHumanPath(const BYTE* szHumanPath) /// 繧ィ繝ゥ繝シ縺ョ譎ゅッFALSE繧定ソ斐☆縲 // //--------------------------------------------------------------------------- -BOOL CHostFcb::Create(DWORD nHumanAttribute, BOOL bForce) +BOOL CHostFcb::Create(Human68k::fcb_t* pFcb, DWORD nHumanAttribute, BOOL bForce) { +#ifndef BAREMETAL ASSERT(this); ASSERT((nHumanAttribute & (Human68k::AT_DIRECTORY | Human68k::AT_VOLUME)) == 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 逅諠ウ蜍穂ス懊ッ螻樊ァ縺斐→荳頑嶌縺 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() { +#ifndef BAREMETAL struct stat st; - + ASSERT(this); ASSERT(strlen(m_szFilename) > 0); @@ -2488,6 +2907,27 @@ BOOL CHostFcb::Open() m_pFile = fopen(S2U(m_szFilename), m_pszMode); 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) { ASSERT(this); +#ifndef BAREMETAL ASSERT(m_pFile); if (fseek(m_pFile, nOffset, SEEK_SET)) return FALSE; 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) { +#ifndef BAREMETAL ASSERT(this); ASSERT(pBuffer); ASSERT(m_pFile); @@ -2527,6 +2975,19 @@ DWORD CHostFcb::Read(BYTE* pBuffer, DWORD nSize) nResult = (size_t)-1; 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) { +#ifndef BAREMETAL ASSERT(this); ASSERT(pBuffer); ASSERT(m_pFile); @@ -2548,6 +3010,19 @@ DWORD CHostFcb::Write(const BYTE* pBuffer, DWORD nSize) nResult = (size_t)-1; 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() { ASSERT(this); +#ifndef BAREMETAL ASSERT(m_pFile); 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) { +#ifndef BAREMETAL ASSERT(this); ASSERT(nHumanSeek == Human68k::SK_BEGIN || nHumanSeek == Human68k::SK_CURRENT || nHumanSeek == Human68k::SK_END); @@ -2596,6 +3076,30 @@ DWORD CHostFcb::Seek(DWORD nOffset, DWORD nHumanSeek) return (DWORD)-1; 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) { +#ifndef BAREMETAL ASSERT(this); ASSERT(m_pFile || m_bFlag); @@ -2614,7 +3119,7 @@ BOOL CHostFcb::TimeStamp(DWORD nHumanTime) t.tm_year = (nHumanTime >> 25) + 80; t.tm_mon = ((nHumanTime >> 21) - 1) & 15; 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_sec = (nHumanTime & 31) << 1; time_t ti = mktime(&t); @@ -2629,6 +3134,20 @@ BOOL CHostFcb::TimeStamp(DWORD nHumanTime) fflush(m_pFile); return utime(S2U(m_szFilename), &ut) == 0 || m_bFlag; +#else + FILINFO fno; + + ASSERT(this); + ASSERT(m_bFlag); + + // 繧ッ繝ュ繝シ繧コ譎ゅ↓譖エ譁ー譎ょ綾縺御ク頑嶌縺阪&繧後k縺ョ繧帝亟豁「縺吶k縺溘a + // 繧ソ繧、繝繧ケ繧ソ繝ウ繝励ョ譖エ譁ー蜑阪↓繝輔Λ繝繧キ繝・縺励※蜷梧悄縺輔○繧 + 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竊巽ree(蜀驛ィ縺ァ蜀榊コヲClose)縺ィ縺縺豬√l繧ゅ≠繧九ョ縺ァ蠢縺壼晄悄蛹悶☆繧九%縺ィ縲 +#ifndef BAREMETAL if (m_pFile) { fclose(m_pFile); m_pFile = NULL; } +#else + f_close(&m_File); +#endif // BAREMETAL return bResult; } @@ -2813,6 +3336,9 @@ CFileSys::CFileSys() m_nOptionDefault = 0; m_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(); // 繝繧」繝ャ繧ッ繝医Μ菴懈 +#ifndef BAREMETAL if (mkdir(S2U(f.GetPath()), 0777)) +#else + if (f_mkdir(S2U(f.GetPath())) != FR_OK) +#endif // BAREMETAL return FS_INVALIDPATH; // 繧ュ繝」繝繧キ繝・譖エ譁ー @@ -3025,7 +3555,11 @@ int CFileSys::RemoveDir(DWORD nUnit, const Human68k::namests_t* pNamests) m_cEntry.DeleteCache(nUnit, szHuman); // 繝繧」繝ャ繧ッ繝医Μ蜑企勁 +#ifndef BAREMETAL if (rmdir(S2U(f.GetPath()))) +#else + if (f_rmdir(S2U(f.GetPath())) != FR_OK) +#endif // BAREMETAL return FS_CANTDELETE; // 繧ュ繝」繝繧キ繝・譖エ譁ー @@ -3082,7 +3616,11 @@ int CFileSys::Rename(DWORD nUnit, const Human68k::namests_t* pNamests, const Hum char szTo[FILENAME_MAX]; SJIS2UTF8(f.GetPath(), szFrom, FILENAME_MAX); SJIS2UTF8(fNew.GetPath(), szTo, FILENAME_MAX); +#ifndef BAREMETAL if (rename(szFrom, szTo)) { +#else + if (f_rename(szFrom, szTo) != FR_OK) { +#endif // BAREMETAL return FS_FILENOTFND; } @@ -3125,7 +3663,11 @@ int CFileSys::Delete(DWORD nUnit, const Human68k::namests_t* pNamests) return FS_FILENOTFND; // 繝輔ぃ繧、繝ォ蜑企勁 +#ifndef BAREMETAL if (unlink(S2U(f.GetPath()))) +#else + if (f_unlink(S2U(f.GetPath())) != FR_OK) +#endif // BAREMETAL return FS_CANTDELETE; // 繧ュ繝」繝繧キ繝・譖エ譁ー @@ -3177,6 +3719,7 @@ int CFileSys::Attribute(DWORD nUnit, const Human68k::namests_t* pNamests, DWORD DWORD nAttribute = (nHumanAttribute & Human68k::AT_READONLY) | (f.GetAttribute() & ~Human68k::AT_READONLY); if (f.GetAttribute() != nAttribute) { +#ifndef BAREMETAL struct stat sb; if (stat(S2U(f.GetPath()), &sb)) return FS_FILENOTFND; @@ -3189,6 +3732,17 @@ int CFileSys::Attribute(DWORD nUnit, const Human68k::namests_t* pNamests, DWORD // 螻樊ァ險ュ螳 if (chmod(S2U(f.GetPath()), m)) 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); return FS_FILEEXIST; } @@ -4056,7 +4610,13 @@ int CFileSys::CheckMedia(DWORD nUnit) return FS_INVALIDFUNC; // 繝ャ繧ク繝・繝シ繝蠕後↓辟。蜉ケ縺ェ繝峨Λ繧、繝悶〒mint謫堺ス懈凾縺ォ逋ス蟶ッ繧貞コ縺輔↑縺繧医≧謾ケ濶ッ // 繝。繝繧」繧「莠、謠帙メ繧ァ繝繧ッ - m_cEntry.CleanCache(nUnit); + BOOL bResult = m_cEntry.CheckMedia(nUnit); + + // 繝。繝繧」繧「譛ェ謖ソ蜈・縺ェ繧峨お繝ゥ繝シ縺ィ縺吶k + if (bResult == FALSE) { + return FS_INVALIDFUNC; + } + return 0; } diff --git a/src/raspberrypi/cfilesystem.h b/src/raspberrypi/cfilesystem.h index 58dabe8e..6332a2a5 100644 --- a/src/raspberrypi/cfilesystem.h +++ b/src/raspberrypi/cfilesystem.h @@ -4,7 +4,7 @@ // for Raspberry Pi // // Powered by XM6 TypeG Technology. -// Copyright (C) 2016-2018 GIMONS +// Copyright (C) 2016-2020 GIMONS // [ 繝帙せ繝医ヵ繧。繧、繝ォ繧キ繧ケ繝繝 ] // //--------------------------------------------------------------------------- @@ -12,6 +12,11 @@ #ifndef cfilesystem_h #define cfilesystem_h +#ifdef BAREMETAL +#include "ffconf.h" +#include "ff.h" +#endif // BAREMETAL + //--------------------------------------------------------------------------- // // 繧ケ繝繝シ繧ソ繧ケ繧ウ繝シ繝牙ョ夂セゥ @@ -631,7 +636,12 @@ private: ///< 譁蟄怜玲ッ碑シ (繝ッ繧、繝ォ繝峨き繝シ繝牙ッセ蠢) CRing m_cRing; ///< CHostFilename騾」邨千畑 +#ifndef BAREMETAL time_t m_tBackup; ///< 譎ょ綾蠕ゥ蜈逕ィ +#else + WORD m_tBackupD; ///< 譎ょ綾蠕ゥ蜈逕ィ + WORD m_tBackupT; ///< 譎ょ綾蠕ゥ蜈逕ィ +#endif // BAREMETAL BOOL m_bRefresh; ///< 譖エ譁ー繝輔Λ繧ー DWORD m_nId; ///< 隴伜挨ID (蛟、縺悟、牙喧縺励◆蝣エ蜷医ッ譖エ譁ー繧呈э蜻ウ縺吶k) BYTE m_szHuman[HUMAN68K_PATH_MAX]; ///< 隧イ蠖薙お繝ウ繝医Μ縺ョHuman68k蜀驛ィ蜷 @@ -795,7 +805,7 @@ public: const BYTE* GetHumanPath() const { ASSERT(this); return m_szHumanPath; } ///< Human68k繝代せ蜷阪r蜿門セ - BOOL Create(DWORD nHumanAttribute, BOOL bForce); + BOOL Create(Human68k::fcb_t* pFcb, DWORD nHumanAttribute, BOOL bForce); ///< 繝輔ぃ繧、繝ォ菴懈 BOOL Open(); ///< 繝輔ぃ繧、繝ォ繧ェ繝シ繝励Φ @@ -817,8 +827,13 @@ public: private: DWORD m_nKey; ///< Human68k縺ョFCB繝舌ャ繝輔ぃ繧「繝峨Ξ繧ケ (0縺ェ繧画悴菴ソ逕ィ) BOOL m_bUpdate; ///< 譖エ譁ー繝輔Λ繧ー +#ifndef BAREMETAL FILE* m_pFile; ///< 繝帙せ繝亥エ縺ョ繝輔ぃ繧、繝ォ繧ェ繝悶ず繧ァ繧ッ繝 const char* m_pszMode; ///< 繝帙せ繝亥エ縺ョ繝輔ぃ繧、繝ォ繧ェ繝シ繝励Φ繝「繝シ繝 +#else + FIL m_File; ///< 繝帙せ繝亥エ縺ョ繝輔ぃ繧、繝ォ繧ェ繝悶ず繧ァ繧ッ繝 + BYTE m_Mode; ///< 繝帙せ繝亥エ縺ョ繝輔ぃ繧、繝ォ繧ェ繝シ繝励Φ繝「繝シ繝 +#endif // BAREMETAL bool m_bFlag; ///< 繝帙せ繝亥エ縺ョ繝輔ぃ繧、繝ォ繧ェ繝シ繝励Φ繝輔Λ繧ー BYTE m_szHumanPath[HUMAN68K_PATH_MAX]; ///< Human68k縺ョ繝代せ蜷 @@ -889,6 +904,12 @@ public: ///< 繝峨Λ繧、繝也憾諷九ョ蜿門セ void SetEnable(BOOL bEnable); ///< 繝。繝繧」繧「迥カ諷玖ィュ螳 + BOOL CheckMedia(); + ///< 繝。繝繧」繧「莠、謠帙メ繧ァ繝繧ッ + void Update(); + ///< 繝。繝繧」繧「迥カ諷区峩譁ー + void Eject(); + ///< 繧、繧ク繧ァ繧ッ繝 void GetVolume(TCHAR* szLabel); ///< 繝懊Μ繝・繝シ繝繝ゥ繝吶Ν縺ョ蜿門セ BOOL GetVolumeCache(TCHAR* szLabel) const; @@ -987,6 +1008,10 @@ public: ///< 繝。繝繧」繧「繝舌う繝医ョ蜿門セ DWORD GetStatus(DWORD nUnit) const; ///< 繝峨Λ繧、繝也憾諷九ョ蜿門セ + BOOL CheckMedia(DWORD nUnit); + ///< 繝。繝繧」繧「莠、謠帙メ繧ァ繝繧ッ + void Eject(DWORD nUnit); + ///< 繧、繧ク繧ァ繧ッ繝 void GetVolume(DWORD nUnit, TCHAR* szLabel); ///< 繝懊Μ繝・繝シ繝繝ゥ繝吶Ν縺ョ蜿門セ BOOL GetVolumeCache(DWORD nUnit, TCHAR* szLabel) const; diff --git a/src/raspberrypi/cqueue.h b/src/raspberrypi/cqueue.h deleted file mode 100644 index 27802a51..00000000 --- a/src/raspberrypi/cqueue.h +++ /dev/null @@ -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 diff --git a/src/raspberrypi/ctapdriver.cpp b/src/raspberrypi/ctapdriver.cpp index fbcb3d44..4adabab9 100644 --- a/src/raspberrypi/ctapdriver.cpp +++ b/src/raspberrypi/ctapdriver.cpp @@ -4,7 +4,7 @@ // for Raspberry Pi // // 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. // diff --git a/src/raspberrypi/ctapdriver.h b/src/raspberrypi/ctapdriver.h index 9f7b3f44..97ba4e1e 100644 --- a/src/raspberrypi/ctapdriver.h +++ b/src/raspberrypi/ctapdriver.h @@ -4,7 +4,7 @@ // for Raspberry Pi // // 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. // diff --git a/src/raspberrypi/disk.cpp b/src/raspberrypi/disk.cpp index 869e1284..af11ecf1 100644 --- a/src/raspberrypi/disk.cpp +++ b/src/raspberrypi/disk.cpp @@ -3,7 +3,7 @@ // X68000 EMULATOR "XM6" // // Copyright (C) 2001-2006 シーシゥシ(ytanaka@ipc-tokai.or.jp) -// Copyright (C) 2014-2018 GIMONS +// Copyright (C) 2014-2020 GIMONS // // XM6i // Copyright (C) 2010-2015 isaki@NetBSD.org @@ -18,10 +18,13 @@ #include "os.h" #include "xm6.h" +#include "filepath.h" #include "fileio.h" #ifdef RASCSI -#include "filepath.h" +#include "gpiobus.h" +#ifndef BAREMETAL #include "ctapdriver.h" +#endif // BAREMETAL #include "cfilesystem.h" #include "disk.h" #else @@ -82,15 +85,11 @@ DiskTrack::~DiskTrack() { // 繝。繝「繝ェ隗」謾セ縺ッ陦後≧縺後∬ェ蜍輔そ繝シ繝悶ッ縺励↑縺 if (dt.buffer) { -#ifdef RASCSI free(dt.buffer); -#else - delete[] dt.buffer; -#endif // RASCSI dt.buffer = NULL; } if (dt.changemap) { - delete[] dt.changemap; + free(dt.changemap); dt.changemap = NULL; } } @@ -104,7 +103,7 @@ void FASTCALL DiskTrack::Init( int track, int size, int sectors, BOOL raw, off64_t imgoff) { ASSERT(track >= 0); - ASSERT((size == 8) || (size == 9) || (size == 11)); + ASSERT((size >= 8) && (size <= 11)); ASSERT((sectors > 0) && (sectors <= 0x100)); ASSERT(imgoff >= 0); @@ -162,74 +161,59 @@ BOOL FASTCALL DiskTrack::Load(const Filepath& path) length = dt.sectors << dt.size; // 繝舌ャ繝輔ぃ縺ョ繝。繝「繝ェ繧堤「コ菫 - ASSERT((dt.size == 8) || (dt.size == 9) || (dt.size == 11)); + ASSERT((dt.size >= 8) && (dt.size <= 11)); ASSERT((dt.sectors > 0) && (dt.sectors <= 0x100)); - try { - // 繝舌ャ繝輔ぃ髟キ縺檎焚縺ェ繧九↑繧芽ァ」謾セ - if (dt.length != (DWORD)length) { - if (dt.buffer) { -#ifdef RASCSI - free(dt.buffer); -#else - delete[] dt.buffer; -#endif // RASCSI - dt.buffer = NULL; - } - } - // 繝舌ャ繝輔ぃ遒コ菫 - dt.length = length; - if (dt.buffer == NULL) { -#ifdef RASCSI - posix_memalign((void **)&dt.buffer, 512, ((dt.length + 511) / 512) * 512); + if (dt.buffer == NULL) { +#if defined(RASCSI) && !defined(BAREMETAL) + posix_memalign((void **)&dt.buffer, 512, ((length + 511) / 512) * 512); #else - dt.buffer = new BYTE[dt.length]; -#endif // RASCSI - } - } - catch (...) { - dt.length = 0; - dt.buffer = NULL; - return FALSE; + dt.buffer = (BYTE *)malloc(length * sizeof(BYTE)); +#endif // RASCSI && !BAREMETAL + dt.length = length; } + if (!dt.buffer) { return FALSE; } - // 螟画峩繝槭ャ繝励ョ繝。繝「繝ェ繧堤「コ菫 - try { - // 繝舌ャ繝輔ぃ髟キ縺檎焚縺ェ繧九↑繧芽ァ」謾セ - if (dt.maplen != (DWORD)dt.sectors) { - if (dt.changemap) { - delete[] dt.changemap; - dt.changemap = NULL; - } - } + // 繝舌ャ繝輔ぃ髟キ縺檎焚縺ェ繧九↑繧牙咲「コ菫 + if (dt.length != (DWORD)length) { + free(dt.buffer); +#if defined(RASCSI) && !defined(BAREMETAL) + posix_memalign((void **)&dt.buffer, 512, ((length + 511) / 512) * 512); +#else + dt.buffer = (BYTE *)malloc(length * sizeof(BYTE)); +#endif // RASCSI && !BAREMETAL + dt.length = length; + } - // 繝舌ャ繝輔ぃ遒コ菫 + // 螟画峩繝槭ャ繝励ョ繝。繝「繝ェ繧堤「コ菫 + if (dt.changemap == NULL) { + dt.changemap = (BOOL *)malloc(dt.sectors * sizeof(BOOL)); dt.maplen = dt.sectors; - if (dt.changemap == NULL) { - dt.changemap = new BOOL[dt.maplen]; - } - } - catch (...) { - dt.maplen = 0; - dt.changemap = NULL; - return FALSE; } + if (!dt.changemap) { return FALSE; } - // 螟画峩繝槭ャ繝励r繧ッ繝ェ繧「 + // 繝舌ャ繝輔ぃ髟キ縺檎焚縺ェ繧九↑繧牙咲「コ菫 + if (dt.maplen != (DWORD)dt.sectors) { + free(dt.changemap); + dt.changemap = (BOOL *)malloc(dt.sectors * sizeof(BOOL)); + dt.maplen = dt.sectors; + } + + // 螟画峩繝槭ャ繝励け繝ェ繧「 memset(dt.changemap, 0x00, dt.sectors * sizeof(BOOL)); // 繝輔ぃ繧、繝ォ縺九i隱ュ縺ソ霎シ繧 -#ifdef RASCSI +#if defined(RASCSI) && !defined(BAREMETAL) if (!fio.OpenDIO(path, Fileio::ReadOnly)) { #else if (!fio.Open(path, Fileio::ReadOnly)) { -#endif // RASCSI +#endif // RASCSI && !BAREMETAL return FALSE; } if (dt.raw) { @@ -278,8 +262,10 @@ BOOL FASTCALL DiskTrack::Save(const Filepath& path) { off64_t offset; int i; + int j; Fileio fio; int length; + int total; ASSERT(this); @@ -296,7 +282,7 @@ BOOL FASTCALL DiskTrack::Save(const Filepath& path) // 譖ク縺崎セシ繧蠢隕√′縺ゅk ASSERT(dt.buffer); ASSERT(dt.changemap); - ASSERT((dt.size == 8) || (dt.size == 9) || (dt.size == 11)); + ASSERT((dt.size >= 8) && (dt.size <= 11)); ASSERT((dt.sectors > 0) && (dt.sectors <= 0x100)); // RAW繝「繝シ繝峨〒縺ッ譖ク縺崎セシ縺ソ縺ッ縺ゅj縺医↑縺 @@ -317,22 +303,41 @@ BOOL FASTCALL DiskTrack::Save(const Filepath& path) return FALSE; } - // 譖ク縺崎セシ縺ソ繝ォ繝シ繝 - for (i = 0; i < dt.sectors; i++) { + // 驛ィ蛻譖ク縺崎セシ縺ソ繝ォ繝シ繝 + for (i = 0; i < dt.sectors;) { // 螟画峩縺輔l縺ヲ縺繧後ー if (dt.changemap[i]) { - // 繧キ繝シ繧ッ縲∵嶌縺崎セシ縺ソ + // 譖ク縺崎セシ縺ソ繧オ繧、繧コ蛻晄悄蛹 + total = 0; + + // 繧キ繝シ繧ッ if (!fio.Seek(offset + ((off64_t)i << dt.size))) { fio.Close(); return FALSE; } - if (!fio.Write(&dt.buffer[i << dt.size], length)) { + + // 騾」邯壹☆繧九そ繧ッ繧ソ髟キ + for (j = i; j < dt.sectors; j++) { + // 騾泌繧後◆繧臥オゆコ + if (!dt.changemap[j]) { + break; + } + + // 1繧サ繧ッ繧ソ蛻蜉邂 + total += length; + } + + // 譖ク縺崎セシ縺ソ + if (!fio.Write(&dt.buffer[i << dt.size], total)) { fio.Close(); return FALSE; } - // 螟画峩繝輔Λ繧ー繧定誠縺ィ縺 - dt.changemap[i] = FALSE; + // 譛ェ螟画峩縺ョ繧サ繧ッ繧ソ縺ク + i = j; + } else { + // 谺。縺ョ繧サ繧ッ繧ソ + i++; } } @@ -340,6 +345,7 @@ BOOL FASTCALL DiskTrack::Save(const Filepath& path) fio.Close(); // 螟画峩繝輔Λ繧ー繧定誠縺ィ縺励∫オゆコ + memset(dt.changemap, 0x00, dt.sectors * sizeof(BOOL)); dt.changed = FALSE; return TRUE; } @@ -367,7 +373,7 @@ BOOL FASTCALL DiskTrack::Read(BYTE *buf, int sec) const // 繧ウ繝斐シ ASSERT(dt.buffer); - ASSERT((dt.size == 8) || (dt.size == 9) || (dt.size == 11)); + ASSERT((dt.size >= 8) && (dt.size <= 11)); ASSERT((dt.sectors > 0) && (dt.sectors <= 0x100)); memcpy(buf, &dt.buffer[(off64_t)sec << dt.size], (off64_t)1 << dt.size); @@ -406,7 +412,7 @@ BOOL FASTCALL DiskTrack::Write(const BYTE *buf, int sec) // 豈碑シ ASSERT(dt.buffer); - ASSERT((dt.size == 8) || (dt.size == 9) || (dt.size == 11)); + ASSERT((dt.size >= 8) && (dt.size <= 11)); ASSERT((dt.sectors > 0) && (dt.sectors <= 0x100)); if (memcmp(buf, &dt.buffer[offset], length) == 0) { // 蜷後§繧ゅョ繧呈嶌縺崎セシ繧ゅ≧縺ィ縺励※縺繧九ョ縺ァ縲∵ュ」蟶ク邨ゆコ @@ -438,7 +444,7 @@ DiskCache::DiskCache( { int i; - ASSERT((size == 8) || (size == 9) || (size == 11)); + ASSERT((size >= 8) && (size <= 11)); ASSERT(blocks > 0); ASSERT(imgoff >= 0); @@ -998,7 +1004,7 @@ BOOL FASTCALL Disk::Open(const Filepath& path, BOOL /*attn*/) Fileio fio; ASSERT(this); - ASSERT((disk.size == 8) || (disk.size == 9) || (disk.size == 11)); + ASSERT((disk.size >= 8) && (disk.size <= 11)); ASSERT(disk.blocks > 0); // 繝ャ繝繧」 @@ -1006,8 +1012,8 @@ BOOL FASTCALL Disk::Open(const Filepath& path, BOOL /*attn*/) // 繧ュ繝」繝繧キ繝・蛻晄悄蛹 ASSERT(!disk.dcache); - disk.dcache = new DiskCache( - path, disk.size, disk.blocks, disk.imgoffset); + disk.dcache = + new DiskCache(path, disk.size, disk.blocks, disk.imgoffset); // 隱ュ縺ソ譖ク縺阪が繝シ繝励Φ蜿ッ閭ス縺 if (fio.Open(path, Fileio::ReadWrite)) { @@ -1297,7 +1303,8 @@ int FASTCALL Disk::SelectCheck10(const DWORD *cdb) // 窶サdisk.code縺ョ蠖ア髻ソ繧貞女縺代↑縺 // //--------------------------------------------------------------------------- -BOOL FASTCALL Disk::ModeSelect(const DWORD *cdb, const BYTE *buf, int length) +BOOL FASTCALL Disk::ModeSelect( + const DWORD* /*cdb*/, const BYTE *buf, int length) { ASSERT(this); ASSERT(buf); @@ -1805,7 +1812,7 @@ int FASTCALL Disk::AddCDDA(BOOL change, BYTE *buf) // Vendor迚ケ谿翫壹シ繧ク霑ス蜉 // //--------------------------------------------------------------------------- -int FASTCALL Disk::AddVendor(int page, BOOL change, BYTE *buf) +int FASTCALL Disk::AddVendor(int /*page*/, BOOL /*change*/, BYTE *buf) { ASSERT(this); ASSERT(buf); @@ -2036,11 +2043,6 @@ BOOL FASTCALL Disk::Write(const BYTE *buf, DWORD block) return FALSE; } - // 繝ゥ繧、繝医せ繝ォ繝シ繧ュ繝」繝繧キ繝・ - if (!cache_wb) { - Flush(); - } - // 謌仙粥 disk.code = DISK_NOERROR; return TRUE; @@ -2385,17 +2387,46 @@ BOOL FASTCALL SASIHD::Open(const Filepath& path, BOOL /*attn*/) size = fio.GetFileSize(); fio.Close(); +#if defined(USE_MZ1F23_1024_SUPPORT) + // MZ-2500/MZ-2800逕ィ MZ-1F23(SASI 20M/繧サ繧ッ繧ソ繧オ繧、繧コ1024)蟆ら畑 + // 20M(22437888 BS=1024 C=21912) + if (size == 0x1566000) { + // 繧サ繧ッ繧ソ繧オ繧、繧コ縺ィ繝悶Ο繝繧ッ謨ー + disk.size = 10; + disk.blocks = (DWORD)(size >> 10); + + // 蝓コ譛ャ繧ッ繝ゥ繧ケ + return Disk::Open(path); + } +#endif // USE_MZ1F23_1024_SUPPORT + +#if defined(REMOVE_FIXED_SASIHD_SIZE) + // 256繝舌う繝亥腰菴阪〒縺ゅk縺薙→ + if (size & 0xff) { + return FALSE; + } + + // 10MB莉・荳 + if (size < 0x9f5400) { + return FALSE; + } + + // 512MB遞句コヲ縺ォ蛻カ髯舌@縺ヲ縺翫¥ + if (size > 512 * 1024 * 1024) { + return FALSE; + } +#else // 10MB, 20MB, 40MB縺ョ縺ソ switch (size) { - // 10MB + // 10MB(10441728 BS=256 C=40788) case 0x9f5400: break; - // 20MB + // 20MB(20748288 BS=256 C=81048) case 0x13c9800: break; - // 40MB + // 40MB(41496576 BS=256 C=162096) case 0x2793000: break; @@ -2403,6 +2434,7 @@ BOOL FASTCALL SASIHD::Open(const Filepath& path, BOOL /*attn*/) default: return FALSE; } +#endif // REMOVE_FIXED_SASIHD_SIZE // 繧サ繧ッ繧ソ繧オ繧、繧コ縺ィ繝悶Ο繝繧ッ謨ー disk.size = 8; @@ -2429,6 +2461,11 @@ int FASTCALL SASIHD::RequestSense(const DWORD *cdb, BYTE *buf) size = (int)cdb[4]; ASSERT((size >= 0) && (size < 0x100)); + // 繧オ繧、繧コ0縺ョ縺ィ縺阪↓4繝舌う繝郁サ「騾√☆繧(Shugart Associates System Interface莉墓ァ) + if (size == 0) { + size = 4; + } + // SASI縺ッ髱樊僑蠑オ繝輔か繝シ繝槭ャ繝医↓蝗コ螳 memset(buf, 0, size); buf[0] = (BYTE)(disk.code >> 16); @@ -2629,7 +2666,8 @@ BOOL FASTCALL SCSIHD::ModeSelect(const DWORD *cdb, const BYTE *buf, int length) // 繝悶Ο繝繧ッ繝ャ繝ウ繧ー繧ケ縺ョ繝舌う繝域焚繧偵メ繧ァ繝繧ッ size = 1 << disk.size; if (buf[9] != (BYTE)(size >> 16) || - buf[10] != (BYTE)(size >> 8) || buf[11] != (BYTE)size) { + buf[10] != (BYTE)(size >> 8) || + buf[11] != (BYTE)size) { // 莉翫ョ縺ィ縺薙m繧サ繧ッ繧ソ髟キ縺ョ螟画峩縺ッ險ア縺輔↑縺 disk.code = DISK_INVALIDPRM; return FALSE; @@ -2648,7 +2686,8 @@ BOOL FASTCALL SCSIHD::ModeSelect(const DWORD *cdb, const BYTE *buf, int length) case 0x03: // 迚ゥ逅繧サ繧ッ繧ソ縺ョ繝舌う繝域焚繧偵メ繧ァ繝繧ッ size = 1 << disk.size; - if (buf[0xc] != (BYTE)(size >> 8) || buf[0xd] != (BYTE)size) { + if (buf[0xc] != (BYTE)(size >> 8) || + buf[0xd] != (BYTE)size) { // 莉翫ョ縺ィ縺薙m繧サ繧ッ繧ソ髟キ縺ョ螟画峩縺ッ險ア縺輔↑縺 disk.code = DISK_INVALIDPRM; return FALSE; @@ -2695,10 +2734,21 @@ SCSIHD_NEC::SCSIHD_NEC() : SCSIHD() imgsize = 0; } +//--------------------------------------------------------------------------- +// +// 繝ェ繝医Ν繧ィ繝ウ繝繧」繧「繝ウ縺ィ諠ウ螳壹@縺溘Ρ繝シ繝峨r蜿悶j蜃コ縺 +// +//--------------------------------------------------------------------------- static inline WORD getWordLE(const BYTE *b) { return ((WORD)(b[1]) << 8) | b[0]; } + +//--------------------------------------------------------------------------- +// +// 繝ェ繝医Ν繧ィ繝ウ繝繧」繧「繝ウ縺ィ諠ウ螳壹@縺溘Ο繝ウ繧ー繝ッ繝シ繝峨r蜿悶j蜃コ縺 +// +//--------------------------------------------------------------------------- static inline DWORD getDwordLE(const BYTE *b) { return ((DWORD)(b[3]) << 24) | ((DWORD)(b[2]) << 16) | @@ -2710,7 +2760,7 @@ static inline DWORD getDwordLE(const BYTE *b) // 繧ェ繝シ繝励Φ // //--------------------------------------------------------------------------- -BOOL FASTCALL SCSIHD_NEC::Open(const Filepath& path, BOOL attn) +BOOL FASTCALL SCSIHD_NEC::Open(const Filepath& path, BOOL /*attn*/) { Fileio fio; off64_t size; @@ -2729,7 +2779,7 @@ BOOL FASTCALL SCSIHD_NEC::Open(const Filepath& path, BOOL attn) size = fio.GetFileSize(); // 繝倥ャ繝繝シ隱ュ縺ソ霎シ縺ソ - if (size >= sizeof(hdr)) { + if (size >= (off64_t)sizeof(hdr)) { if (!fio.Read(hdr, sizeof(hdr))) { fio.Close(); return FALSE; @@ -2754,7 +2804,7 @@ BOOL FASTCALL SCSIHD_NEC::Open(const Filepath& path, BOOL attn) // 諡。蠑オ蟄仙挨縺ォ繝代Λ繝。繝シ繧ソ繧呈アコ螳 ext = path.GetFileExt(); - if (xstrcasecmp(ext, ".HDN") == 0) { + if (xstrcasecmp(ext, _T(".HDN")) == 0) { // 繝繝輔か繝ォ繝郁ィュ螳壹→縺励※繧サ繧ッ繧ソ繧オ繧、繧コ512,繧サ繧ッ繧ソ謨ー25,繝倥ャ繝画焚8繧呈Φ螳 imgoffset = 0; imgsize = size; @@ -2764,14 +2814,14 @@ BOOL FASTCALL SCSIHD_NEC::Open(const Filepath& path, BOOL attn) cylinders = (int)(size >> 9); cylinders >>= 3; cylinders /= 25; - } else if (xstrcasecmp(ext, ".HDI") == 0) { // Anex86 HD image? + } else if (xstrcasecmp(ext, _T(".HDI")) == 0) { // Anex86 HD image? imgoffset = getDwordLE(&hdr[4 + 4]); imgsize = getDwordLE(&hdr[4 + 4 + 4]); sectorsize = getDwordLE(&hdr[4 + 4 + 4 + 4]); sectors = getDwordLE(&hdr[4 + 4 + 4 + 4 + 4]); heads = getDwordLE(&hdr[4 + 4 + 4 + 4 + 4 + 4]); cylinders = getDwordLE(&hdr[4 + 4 + 4 + 4 + 4 + 4 + 4]); - } else if (xstrcasecmp(ext, ".NHD") == 0 && + } else if (xstrcasecmp(ext, _T(".NHD")) == 0 && memcmp(hdr, "T98HDDIMAGE.R0\0", 15) == 0) { // T98Next HD image? imgoffset = getDwordLE(&hdr[0x10 + 0x100]); cylinders = getDwordLE(&hdr[0x10 + 0x100 + 4]); @@ -2914,8 +2964,6 @@ int FASTCALL SCSIHD_NEC::AddFormat(BOOL change, BYTE *buf) //--------------------------------------------------------------------------- int FASTCALL SCSIHD_NEC::AddDrive(BOOL change, BYTE *buf) { - DWORD cylinder; - ASSERT(this); ASSERT(buf); @@ -3289,7 +3337,8 @@ BOOL FASTCALL SCSIMO::ModeSelect(const DWORD *cdb, const BYTE *buf, int length) case 0x03: // 迚ゥ逅繧サ繧ッ繧ソ縺ョ繝舌う繝域焚繧偵メ繧ァ繝繧ッ size = 1 << disk.size; - if (buf[0xc] != (BYTE)(size >> 8) || buf[0xd] != (BYTE)size) { + if (buf[0xc] != (BYTE)(size >> 8) || + buf[0xd] != (BYTE)size) { // 莉翫ョ縺ィ縺薙m繧サ繧ッ繧ソ髟キ縺ョ螟画峩縺ッ險ア縺輔↑縺 disk.code = DISK_INVALIDPRM; return FALSE; @@ -3804,7 +3853,7 @@ BOOL FASTCALL SCSICD::Open(const Filepath& path, BOOL attn) { Fileio fio; off64_t size; - char file[5]; + TCHAR file[5]; ASSERT(this); ASSERT(!disk.ready); @@ -3842,7 +3891,7 @@ BOOL FASTCALL SCSICD::Open(const Filepath& path, BOOL attn) fio.Close(); // FILE縺ァ蟋九∪縺」縺ヲ縺繧後ー縲,UE繧キ繝シ繝医→縺ソ縺ェ縺 - if (xstrncasecmp(file, "FILE", 4) == 0) { + if (xstrncasecmp(file, _T("FILE"), 4) == 0) { // CUE縺ィ縺励※繧ェ繝シ繝励Φ if (!OpenCue(path)) { return FALSE; @@ -4460,7 +4509,8 @@ BOOL FASTCALL SCSICD::NextFrame() // CD-DA繝舌ャ繝輔ぃ蜿門セ // //--------------------------------------------------------------------------- -void FASTCALL SCSICD::GetBuf(DWORD* /*buffer*/, int /*samples*/, DWORD /*rate*/) +void FASTCALL SCSICD::GetBuf( + DWORD* /*buffer*/, int /*samples*/, DWORD /*rate*/) { ASSERT(this); } @@ -4481,6 +4531,7 @@ SCSIBR::SCSIBR() : Disk() // 繝帙せ繝医ヶ繝ェ繝繧ク disk.id = MAKEID('S', 'C', 'B', 'R'); +#if defined(RASCSI) && !defined(BAREMETAL) // TAP繝峨Λ繧、繝千函謌 tap = new CTapDriver(); m_bTapEnable = tap->Init(); @@ -4494,6 +4545,7 @@ SCSIBR::SCSIBR() : Disk() // 繝代こ繝繝亥女菫。繝輔Λ繧ー繧ェ繝 packet_enable = FALSE; +#endif // RASCSI && !BAREMETAL // 繝帙せ繝医ヵ繧。繧、繝ォ繧キ繧ケ繝繝逕滓 fs = new CFileSys(); @@ -4507,11 +4559,13 @@ SCSIBR::SCSIBR() : Disk() //--------------------------------------------------------------------------- SCSIBR::~SCSIBR() { +#if defined(RASCSI) && !defined(BAREMETAL) // TAP繝峨Λ繧、繝占ァ」謾セ if (tap) { tap->Cleanup(); delete tap; } +#endif // RASCSI && !BAREMETAL // 繝帙せ繝医ヵ繧。繧、繝ォ繧キ繧ケ繝繝隗」謾セ if (fs) { @@ -4576,10 +4630,12 @@ int FASTCALL SCSIBR::Inquiry( // 繧ェ繝励す繝ァ繝ウ讖溯ス譛牙柑繝輔Λ繧ー buf[36] = '0'; +#if defined(RASCSI) && !defined(BAREMETAL) // TAP譛牙柑 if (m_bTapEnable) { buf[37] = '1'; } +#endif // RASCSI && !BAREMETAL // CFileSys譛牙柑 buf[38] = '1'; @@ -4619,23 +4675,28 @@ BOOL FASTCALL SCSIBR::TestUnitReady(const DWORD* /*cdb*/) int FASTCALL SCSIBR::GetMessage10(const DWORD *cdb, BYTE *buf) { int type; - int func; int phase; +#if defined(RASCSI) && !defined(BAREMETAL) + int func; int total_len; int i; +#endif // RASCSI && !BAREMETAL ASSERT(this); // 繧ソ繧、繝 type = cdb[2]; +#if defined(RASCSI) && !defined(BAREMETAL) // 讖溯ス逡ェ蜿キ func = cdb[3]; +#endif // RASCSI && !BAREMETAL // 繝輔ぉ繝シ繧コ phase = cdb[9]; switch (type) { +#if defined(RASCSI) && !defined(BAREMETAL) case 1: // 繧、繝シ繧オ繝阪ャ繝 // TAP辟。蜉ケ縺ェ繧牙ヲ逅縺励↑縺 if (!m_bTapEnable) { @@ -4684,6 +4745,7 @@ int FASTCALL SCSIBR::GetMessage10(const DWORD *cdb, BYTE *buf) return total_len; } break; +#endif // RASCSI && !BAREMETAL case 2: // 繝帙せ繝医ラ繝ゥ繧、繝 switch (phase) { @@ -4737,6 +4799,7 @@ BOOL FASTCALL SCSIBR::SendMessage10(const DWORD *cdb, BYTE *buf) len |= cdb[8]; switch (type) { +#if defined(RASCSI) && !defined(BAREMETAL) case 1: // 繧、繝シ繧オ繝阪ャ繝 // TAP辟。蜉ケ縺ェ繧牙ヲ逅縺励↑縺 if (!m_bTapEnable) { @@ -4753,6 +4816,7 @@ BOOL FASTCALL SCSIBR::SendMessage10(const DWORD *cdb, BYTE *buf) return TRUE; } break; +#endif // RASCSI && !BAREMETAL case 2: // 繝帙せ繝医ラ繝ゥ繧、繝 switch (phase) { @@ -4772,6 +4836,7 @@ BOOL FASTCALL SCSIBR::SendMessage10(const DWORD *cdb, BYTE *buf) return FALSE; } +#if defined(RASCSI) && !defined(BAREMETAL) //--------------------------------------------------------------------------- // // MAC繧「繝峨Ξ繧ケ蜿門セ @@ -4807,7 +4872,6 @@ void FASTCALL SCSIBR::SetMacAddr(BYTE *mac) void FASTCALL SCSIBR::ReceivePacket() { static const BYTE bcast_addr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; - BYTE buf[0x1000]; ASSERT(this); ASSERT(tap); @@ -4879,6 +4943,7 @@ void FASTCALL SCSIBR::SendPacket(BYTE *buf, int len) tap->Tx(buf, len); } +#endif // RASCSI && !BAREMETAL //--------------------------------------------------------------------------- // @@ -5961,8 +6026,11 @@ SASIDEV::SASIDEV(Device *dev) memset(ctrl.cmd, 0x00, sizeof(ctrl.cmd)); ctrl.status = 0x00; ctrl.message = 0x00; +#ifdef RASCSI + ctrl.execstart = 0; +#endif // RASCSI ctrl.bufsize = 0x800; - ctrl.buffer = new BYTE[ctrl.bufsize]; + ctrl.buffer = (BYTE *)malloc(ctrl.bufsize); memset(ctrl.buffer, 0x00, ctrl.bufsize); ctrl.blocks = 0; ctrl.next = 0; @@ -5984,7 +6052,7 @@ SASIDEV::~SASIDEV() { // 繝舌ャ繝輔ぃ繧帝幕謾セ if (ctrl.buffer) { - delete ctrl.buffer; + free(ctrl.buffer); ctrl.buffer = NULL; } } @@ -6005,6 +6073,9 @@ void FASTCALL SASIDEV::Reset() ctrl.phase = BUS::busfree; ctrl.status = 0x00; ctrl.message = 0x00; +#ifdef RASCSI + ctrl.execstart = 0; +#endif // RASCSI memset(ctrl.buffer, 0x00, ctrl.bufsize); ctrl.blocks = 0; ctrl.next = 0; @@ -6284,18 +6355,15 @@ void FASTCALL SASIDEV::BusFree() ctrl.phase = BUS::busfree; // 菫。蜿キ邱 - ctrl.bus->SetBSY(FALSE); + ctrl.bus->SetREQ(FALSE); ctrl.bus->SetMSG(FALSE); ctrl.bus->SetCD(FALSE); ctrl.bus->SetIO(FALSE); - ctrl.bus->SetREQ(FALSE); + ctrl.bus->SetBSY(FALSE); // 繧ケ繝繝シ繧ソ繧ケ縺ィ繝。繝繧サ繝シ繧ク繧貞晄悄蛹 ctrl.status = 0x00; ctrl.message = 0x00; - - // 繝舌せ繧ッ繝ェ繧「繝繧」繝ャ繧、 - ctrl.bus->SleepNsec(Time_phase_bsy); return; } @@ -6330,7 +6398,8 @@ void FASTCALL SASIDEV::Selection() } #if defined(DISK_LOG) - Log(Log::Normal, "繧サ繝ャ繧ッ繧キ繝ァ繝ウ繝輔ぉ繝シ繧コ ID=%d (繝繝舌う繧ケ縺ゅj)", ctrl.id); + Log(Log::Normal, + "繧サ繝ャ繧ッ繧キ繝ァ繝ウ繝輔ぉ繝シ繧コ ID=%d (繝繝舌う繧ケ縺ゅj)", ctrl.id); #endif // DISK_LOG // 繝輔ぉ繝シ繧コ繝√ぉ繝ウ繧ク @@ -6354,8 +6423,11 @@ void FASTCALL SASIDEV::Selection() //--------------------------------------------------------------------------- void FASTCALL SASIDEV::Command() { - BYTE data; +#ifdef RASCSI int count; + int i; +#endif // RASCSI + ASSERT(this); // 繝輔ぉ繝シ繧コ繝√ぉ繝ウ繧ク @@ -6365,9 +6437,6 @@ void FASTCALL SASIDEV::Command() Log(Log::Normal, "繧ウ繝槭Φ繝峨ヵ繧ァ繝シ繧コ"); #endif // DISK_LOG - // 繝輔ぉ繝シ繧コ繝√ぉ繝ウ繧ク蜑阪ョ繧ヲ繧ァ繧、繝 - ctrl.bus->SleepNsec(Time_phase_before); - // 繝輔ぉ繝シ繧コ險ュ螳 ctrl.phase = BUS::command; @@ -6376,37 +6445,63 @@ void FASTCALL SASIDEV::Command() ctrl.bus->SetCD(TRUE); ctrl.bus->SetIO(FALSE); - // 繝輔ぉ繝シ繧コ繝√ぉ繝ウ繧ク蠕後ョ莠亥相譎る俣 - ctrl.bus->SleepNsec(Time_phase_after); - // 繝繝シ繧ソ霆「騾√ッ6繝舌う繝x1繝悶Ο繝繧ッ ctrl.offset = 0; ctrl.length = 6; ctrl.blocks = 1; - // 譛蛻昴ョ1繝舌う繝医r蜿門セ(蜻ス莉、髟キ險育ョ励ョ縺溘a) - count = ctrl.bus->ReceiveHandShake(&data, 1); - ctrl.buffer[ctrl.offset] = data; - - // 繝ェ繧カ繝ォ繝FALSE縺ェ繧峨√せ繝繝シ繧ソ繧ケ繝輔ぉ繝シ繧コ縺ク遘サ陦 - if (count != 1) { +#ifdef RASCSI + // 繧ウ繝槭Φ繝牙女菫。繝上Φ繝峨す繧ァ繧、繧ッ(譛蛻昴ョ繧ウ繝槭Φ繝峨〒閾ェ蜍輔〒10繝舌う繝亥女菫。縺吶k) + count = ctrl.bus->CommandHandShake(ctrl.buffer); + + // 1繝舌う繝医b蜿嶺ソ。縺ァ縺阪↑縺代l縺ー繧ケ繝繝シ繧ソ繧ケ繝輔ぉ繝シ繧コ縺ク遘サ陦 + if (count == 0) { Error(); return; } - + + // 10繝舌う繝CDB縺ョ繝√ぉ繝繧ッ if (ctrl.buffer[0] >= 0x20 && ctrl.buffer[0] <= 0x7D) { - // 10繝舌う繝CDB ctrl.length = 10; } - - // 繧ェ繝輔そ繝繝医→繝ャ繝ウ繧ー繧ケ - ctrl.offset++; - ctrl.length--; + + // 蜈ィ縺ヲ蜿嶺ソ。縺ァ縺阪↑縺代l縺ー繧ケ繝繝シ繧ソ繧ケ繝輔ぉ繝シ繧コ縺ク遘サ陦 + if (count != (int)ctrl.length) { + Error(); + return; + } + + // 繧ウ繝槭Φ繝峨ョ繝シ繧ソ霆「騾 + for (i = 0; i < (int)ctrl.length; i++) { + ctrl.cmd[i] = (DWORD)ctrl.buffer[i]; + } + + // 繝ャ繝ウ繧ー繧ケ縺ィ繝悶Ο繝繧ッ繧偵け繝ェ繧「 + ctrl.length = 0; + ctrl.blocks = 0; + + // 螳溯。後ヵ繧ァ繝シ繧コ + Execute(); +#else + // 繧ウ繝槭Φ繝峨r隕∵ア + ctrl.bus->SetREQ(TRUE); return; +#endif // RASCSI } - - // 蜿嶺ソ。 - Receive(); +#ifndef RASCSI + // 繝ェ繧ッ繧ィ繧ケ繝井クュ + if (ctrl.bus->GetREQ()) { + // 繧、繝九す繧ィ繝シ繧ソ縺碁∽ソ。縺励◆ + if (ctrl.bus->GetACK()) { + Receive(); + } + } else { + // 繧、繝九す繧ィ繝シ繧ソ縺ォ谺。繧定ヲ∵ア + if (!ctrl.bus->GetACK()) { + ReceiveNext(); + } + } +#endif // RASCSI } //--------------------------------------------------------------------------- @@ -6428,6 +6523,9 @@ void FASTCALL SASIDEV::Execute() // 繝繝シ繧ソ霆「騾√ョ縺溘a縺ョ蛻晄悄蛹 ctrl.offset = 0; ctrl.blocks = 1; +#ifdef RASCSI + ctrl.execstart = SysTimer::GetTimerLow(); +#endif // RASCSI // 繧ウ繝槭Φ繝牙挨蜃ヲ逅 switch (ctrl.cmd[0]) { @@ -6499,18 +6597,34 @@ void FASTCALL SASIDEV::Execute() //--------------------------------------------------------------------------- void FASTCALL SASIDEV::Status() { +#ifdef RASCSI + DWORD min_exec_time; + DWORD time; +#endif // RASCSI + ASSERT(this); // 繝輔ぉ繝シ繧コ繝√ぉ繝ウ繧ク if (ctrl.phase != BUS::status) { +#ifdef RASCSI + // 譛蟆丞ョ溯。梧凾髢 + if (ctrl.execstart > 0) { + min_exec_time = IsSASI() ? min_exec_time_sasi : min_exec_time_scsi; + time = SysTimer::GetTimerLow() - ctrl.execstart; + if (time < min_exec_time) { + SysTimer::SleepUsec(min_exec_time - time); + } + ctrl.execstart = 0; + } else { + SysTimer::SleepUsec(5); + } +#endif // RASCSI + #if defined(DISK_LOG) Log(Log::Normal, "繧ケ繝繝シ繧ソ繧ケ繝輔ぉ繝シ繧コ"); #endif // DISK_LOG - // 繝輔ぉ繝シ繧コ繝√ぉ繝ウ繧ク蜑阪ョ繧ヲ繧ァ繧、繝 - ctrl.bus->SleepNsec(Time_phase_before); - // 繝輔ぉ繝シ繧コ險ュ螳 ctrl.phase = BUS::status; @@ -6519,19 +6633,41 @@ void FASTCALL SASIDEV::Status() ctrl.bus->SetCD(TRUE); ctrl.bus->SetIO(TRUE); - // 繝輔ぉ繝シ繧コ繝√ぉ繝ウ繧ク蠕後ョ莠亥相譎る俣 - ctrl.bus->SleepNsec(Time_phase_after_status); - // 繝繝シ繧ソ霆「騾√ッ1繝舌う繝x1繝悶Ο繝繧ッ ctrl.offset = 0; ctrl.length = 1; ctrl.blocks = 1; ctrl.buffer[0] = (BYTE)ctrl.status; + +#ifndef RASCSI + // 繧ケ繝繝シ繧ソ繧ケ繧定ヲ∵ア + ctrl.bus->SetDAT(ctrl.buffer[0]); + ctrl.bus->SetREQ(TRUE); + +#if defined(DISK_LOG) + Log(Log::Normal, "繧ケ繝繝シ繧ソ繧ケ繝輔ぉ繝シ繧コ $%02X", ctrl.status); +#endif // DISK_LOG +#endif // RASCSI return; } +#ifdef RASCSI // 騾∽ソ。 Send(); +#else + // 繝ェ繧ッ繧ィ繧ケ繝井クュ + if (ctrl.bus->GetREQ()) { + // 繧、繝九す繧ィ繝シ繧ソ縺悟女菫。縺励◆ + if (ctrl.bus->GetACK()) { + SendNext(); + } + } else { + // 繧、繝九す繧ィ繝シ繧ソ縺梧ャ。繧定ヲ∵ア + if (!ctrl.bus->GetACK()) { + Send(); + } + } +#endif // RASCSI } //--------------------------------------------------------------------------- @@ -6550,9 +6686,6 @@ void FASTCALL SASIDEV::MsgIn() Log(Log::Normal, "繝。繝繧サ繝シ繧ク繧、繝ウ繝輔ぉ繝シ繧コ"); #endif // DISK_LOG - // 繝輔ぉ繝シ繧コ繝√ぉ繝ウ繧ク蜑阪ョ繧ヲ繧ァ繧、繝 - ctrl.bus->SleepNsec(Time_phase_before); - // 繝輔ぉ繝シ繧コ險ュ螳 ctrl.phase = BUS::msgin; @@ -6561,18 +6694,40 @@ void FASTCALL SASIDEV::MsgIn() ctrl.bus->SetCD(TRUE); ctrl.bus->SetIO(TRUE); - // 繝輔ぉ繝シ繧コ繝√ぉ繝ウ繧ク蠕後ョ莠亥相譎る俣 - ctrl.bus->SleepNsec(Time_phase_after); - // length, blocks縺ッ險ュ螳壽ク医∩ ASSERT(ctrl.length > 0); ASSERT(ctrl.blocks > 0); ctrl.offset = 0; + +#ifndef RASCSI + // 繝。繝繧サ繝シ繧ク繧定ヲ∵ア + ctrl.bus->SetDAT(ctrl.buffer[ctrl.offset]); + ctrl.bus->SetREQ(TRUE); + +#if defined(DISK_LOG) + Log(Log::Normal, "繝。繝繧サ繝シ繧ク繧、繝ウ繝輔ぉ繝シ繧コ $%02X", ctrl.buffer[ctrl.offset]); +#endif // DISK_LOG +#endif // RASCSI return; } +#ifdef RASCSI // 騾∽ソ。 Send(); +#else + // 繝ェ繧ッ繧ィ繧ケ繝井クュ + if (ctrl.bus->GetREQ()) { + // 繧、繝九す繧ィ繝シ繧ソ縺悟女菫。縺励◆ + if (ctrl.bus->GetACK()) { + SendNext(); + } + } else { + // 繧、繝九す繧ィ繝シ繧ソ縺梧ャ。繧定ヲ∵ア + if (!ctrl.bus->GetACK()) { + Send(); + } + } +#endif // RASCSI } //--------------------------------------------------------------------------- @@ -6582,11 +6737,29 @@ void FASTCALL SASIDEV::MsgIn() //--------------------------------------------------------------------------- void FASTCALL SASIDEV::DataIn() { +#ifdef RASCSI + DWORD min_exec_time; + DWORD time; +#endif // RASCSI + ASSERT(this); ASSERT(ctrl.length >= 0); // 繝輔ぉ繝シ繧コ繝√ぉ繝ウ繧ク if (ctrl.phase != BUS::datain) { + +#ifdef RASCSI + // 譛蟆丞ョ溯。梧凾髢 + if (ctrl.execstart > 0) { + min_exec_time = IsSASI() ? min_exec_time_sasi : min_exec_time_scsi; + time = SysTimer::GetTimerLow() - ctrl.execstart; + if (time < min_exec_time) { + SysTimer::SleepUsec(min_exec_time - time); + } + ctrl.execstart = 0; + } +#endif // RASCSI + // 繝ャ繝ウ繧ー繧ケ0縺ェ繧峨√せ繝繝シ繧ソ繧ケ繝輔ぉ繝シ繧コ縺ク if (ctrl.length == 0) { Status(); @@ -6597,9 +6770,6 @@ void FASTCALL SASIDEV::DataIn() Log(Log::Normal, "繝繝シ繧ソ繧、繝ウ繝輔ぉ繝シ繧コ"); #endif // DISK_LOG - // 繝輔ぉ繝シ繧コ繝√ぉ繝ウ繧ク蜑阪ョ繧ヲ繧ァ繧、繝 - ctrl.bus->SleepNsec(Time_phase_before_data); - // 繝輔ぉ繝シ繧コ險ュ螳 ctrl.phase = BUS::datain; @@ -6608,18 +6778,38 @@ void FASTCALL SASIDEV::DataIn() ctrl.bus->SetCD(FALSE); ctrl.bus->SetIO(TRUE); - // 繝輔ぉ繝シ繧コ繝√ぉ繝ウ繧ク蠕後ョ莠亥相譎る俣 - ctrl.bus->SleepNsec(Time_phase_after); - // length, blocks縺ッ險ュ螳壽ク医∩ ASSERT(ctrl.length > 0); ASSERT(ctrl.blocks > 0); ctrl.offset = 0; + +#ifndef RASCSI + // 繝繝シ繧ソ繧定ィュ螳 + ctrl.bus->SetDAT(ctrl.buffer[ctrl.offset]); + + // 繝繝シ繧ソ繧定ヲ∵ア + ctrl.bus->SetREQ(TRUE); +#endif // RASCSI return; } +#ifdef RASCSI // 騾∽ソ。 Send(); +#else + // 繝ェ繧ッ繧ィ繧ケ繝井クュ + if (ctrl.bus->GetREQ()) { + // 繧、繝九す繧ィ繝シ繧ソ縺悟女菫。縺励◆ + if (ctrl.bus->GetACK()) { + SendNext(); + } + } else { + // 繧、繝九す繧ィ繝シ繧ソ縺梧ャ。繧定ヲ∵ア + if (!ctrl.bus->GetACK()) { + Send(); + } + } +#endif // RASCSI } //--------------------------------------------------------------------------- @@ -6629,11 +6819,29 @@ void FASTCALL SASIDEV::DataIn() //--------------------------------------------------------------------------- void FASTCALL SASIDEV::DataOut() { +#ifdef RASCSI + DWORD min_exec_time; + DWORD time; +#endif // RASCSI + ASSERT(this); ASSERT(ctrl.length >= 0); // 繝輔ぉ繝シ繧コ繝√ぉ繝ウ繧ク if (ctrl.phase != BUS::dataout) { + +#ifdef RASCSI + // 譛蟆丞ョ溯。梧凾髢 + if (ctrl.execstart > 0) { + min_exec_time = IsSASI() ? min_exec_time_sasi : min_exec_time_scsi; + time = SysTimer::GetTimerLow() - ctrl.execstart; + if (time < min_exec_time) { + SysTimer::SleepUsec(min_exec_time - time); + } + ctrl.execstart = 0; + } +#endif // RASCSI + // 繝ャ繝ウ繧ー繧ケ0縺ェ繧峨√せ繝繝シ繧ソ繧ケ繝輔ぉ繝シ繧コ縺ク if (ctrl.length == 0) { Status(); @@ -6644,9 +6852,6 @@ void FASTCALL SASIDEV::DataOut() Log(Log::Normal, "繝繝シ繧ソ繧「繧ヲ繝医ヵ繧ァ繝シ繧コ"); #endif // DISK_LOG - // 繝輔ぉ繝シ繧コ繝√ぉ繝ウ繧ク蜑阪ョ繧ヲ繧ァ繧、繝 - ctrl.bus->SleepNsec(Time_phase_before_data); - // 繝輔ぉ繝シ繧コ險ュ螳 ctrl.phase = BUS::dataout; @@ -6655,18 +6860,35 @@ void FASTCALL SASIDEV::DataOut() ctrl.bus->SetCD(FALSE); ctrl.bus->SetIO(FALSE); - // 繝輔ぉ繝シ繧コ繝√ぉ繝ウ繧ク蠕後ョ莠亥相譎る俣 - ctrl.bus->SleepNsec(Time_phase_after); - // length, blocks縺ッ險ュ螳壽ク医∩ ASSERT(ctrl.length > 0); ASSERT(ctrl.blocks > 0); ctrl.offset = 0; + +#ifndef RASCSI + // 繝繝シ繧ソ繧定ヲ∵ア + ctrl.bus->SetREQ(TRUE); +#endif // RASCSI return; } +#ifdef RASCSI // 蜿嶺ソ。 Receive(); +#else + // 繝ェ繧ッ繧ィ繧ケ繝井クュ + if (ctrl.bus->GetREQ()) { + // 繧、繝九す繧ィ繝シ繧ソ縺碁∽ソ。縺励◆ + if (ctrl.bus->GetACK()) { + Receive(); + } + } else { + // 繧、繝九す繧ィ繝シ繧ソ縺ォ谺。繧定ヲ∵ア + if (!ctrl.bus->GetACK()) { + ReceiveNext(); + } + } +#endif // RASCSI } //--------------------------------------------------------------------------- @@ -6918,7 +7140,8 @@ void FASTCALL SASIDEV::CmdRead6() } #if defined(DISK_LOG) - Log(Log::Normal, "READ(6)繧ウ繝槭Φ繝 繝ャ繧ウ繝シ繝=%06X 繝悶Ο繝繧ッ=%d", record, ctrl.blocks); + Log(Log::Normal, + "READ(6)繧ウ繝槭Φ繝 繝ャ繧ウ繝シ繝=%06X 繝悶Ο繝繧ッ=%d", record, ctrl.blocks); #endif // DISK_LOG // 繝峨Λ繧、繝悶〒繧ウ繝槭Φ繝牙ヲ逅 @@ -6967,7 +7190,8 @@ void FASTCALL SASIDEV::CmdWrite6() } #if defined(DISK_LOG) - Log(Log::Normal, "WRITE(6)繧ウ繝槭Φ繝 繝ャ繧ウ繝シ繝=%06X 繝悶Ο繝繧ッ=%d", record, ctrl.blocks); + Log(Log::Normal, + "WRITE(6)繧ウ繝槭Φ繝 繝ャ繧ウ繝シ繝=%06X 繝悶Ο繝繧ッ=%d", record, ctrl.blocks); #endif // DISK_LOG // 繝峨Λ繧、繝悶〒繧ウ繝槭Φ繝牙ヲ逅 @@ -7135,21 +7359,23 @@ void FASTCALL SASIDEV::CmdInvalid() //--------------------------------------------------------------------------- void FASTCALL SASIDEV::Send() { +#ifdef RASCSI int len; +#endif // RASCSI BOOL result; ASSERT(this); ASSERT(!ctrl.bus->GetREQ()); - ASSERT(!ctrl.bus->GetACK()); ASSERT(ctrl.bus->GetIO()); +#ifdef RASCSI // 繝ャ繝ウ繧ー繧ケ!=0縺ェ繧蛾∽ソ。 if (ctrl.length != 0) { len = ctrl.bus->SendHandShake( &ctrl.buffer[ctrl.offset], ctrl.length); // 蜈ィ縺ヲ騾∽ソ。縺ァ縺阪↑縺代l縺ー繧ケ繝繝シ繧ソ繧ケ繝輔ぉ繝シ繧コ縺ク遘サ陦 - if (len != ctrl.length) { + if (len != (int)ctrl.length) { Error(); return; } @@ -7159,6 +7385,19 @@ void FASTCALL SASIDEV::Send() ctrl.length = 0; return; } +#else + // 繧ェ繝輔そ繝繝医→繝ャ繝ウ繧ー繧ケ + ASSERT(ctrl.length >= 1); + ctrl.offset++; + ctrl.length--; + + // ACK繧「繧オ繝シ繝育峩蠕後↓SendNext縺ァ繝繝シ繧ソ險ュ螳壽ク医∩縺ェ繧峨Μ繧ッ繧ィ繧ケ繝医r荳翫£繧 + if (ctrl.length != 0) { + // 繧ソ繝シ繧イ繝繝医′謫堺ス懊☆繧倶ソ。蜿キ邱 + ctrl.bus->SetREQ(TRUE); + return; + } +#endif // RASCSI // 繝悶Ο繝繧ッ貂帷ョ励√Μ繧カ繝ォ繝亥晄悄蛹 ctrl.blocks--; @@ -7169,6 +7408,9 @@ void FASTCALL SASIDEV::Send() if (ctrl.blocks != 0) { // 谺。縺ョ繝舌ャ繝輔ぃ繧定ィュ螳(offset, length繧偵そ繝繝医☆繧九%縺ィ) result = XferIn(ctrl.buffer); +#ifndef RASCSI + ctrl.bus->SetDAT(ctrl.buffer[ctrl.offset]); +#endif // RASCSI } } @@ -7182,6 +7424,10 @@ void FASTCALL SASIDEV::Send() if (ctrl.blocks != 0){ ASSERT(ctrl.length > 0); ASSERT(ctrl.offset == 0); +#ifndef RASCSI + // 繧ソ繝シ繧イ繝繝医′謫堺ス懊☆繧倶ソ。蜿キ邱 + ctrl.bus->SetREQ(TRUE); +#endif // RASCSI return; } @@ -7204,7 +7450,7 @@ void FASTCALL SASIDEV::Send() // 繝。繝繧サ繝シ繧ク繧、繝ウ繝輔ぉ繝シ繧コ ctrl.length = 1; ctrl.blocks = 1; - ctrl.buffer[0] = ctrl.message; + ctrl.buffer[0] = (BYTE)ctrl.message; MsgIn(); break; @@ -7215,6 +7461,31 @@ void FASTCALL SASIDEV::Send() } } +#ifndef RASCSI +//--------------------------------------------------------------------------- +// +// 繝繝シ繧ソ騾∽ソ。邯咏カ +// +//--------------------------------------------------------------------------- +void FASTCALL SASIDEV::SendNext() +{ + ASSERT(this); + + // REQ縺御ク翫′縺」縺ヲ縺繧 + ASSERT(ctrl.bus->GetREQ()); + ASSERT(ctrl.bus->GetIO()); + + // 繧ソ繝シ繧イ繝繝医′謫堺ス懊☆繧倶ソ。蜿キ邱 + ctrl.bus->SetREQ(FALSE); + + // 繝舌ャ繝輔ぃ縺ォ繝繝シ繧ソ縺後≠繧後ー蜈医↓險ュ螳壹☆繧 + if (ctrl.length > 1) { + ctrl.bus->SetDAT(ctrl.buffer[ctrl.offset + 1]); + } +} +#endif // RASCSI + +#ifndef RASCSI //--------------------------------------------------------------------------- // // 繝繝シ繧ソ蜿嶺ソ。 @@ -7222,17 +7493,78 @@ void FASTCALL SASIDEV::Send() //--------------------------------------------------------------------------- void FASTCALL SASIDEV::Receive() { - BOOL result; - int i; - int len; + DWORD data; ASSERT(this); - // REQ,ACK縺御ク九′縺」縺ヲ縺繧九%縺ィ - ASSERT(!ctrl.bus->GetREQ()); - ASSERT(!ctrl.bus->GetACK()); + // REQ縺御ク翫′縺」縺ヲ縺繧 + ASSERT(ctrl.bus->GetREQ()); ASSERT(!ctrl.bus->GetIO()); + // 繝繝シ繧ソ蜿門セ + data = (DWORD)ctrl.bus->GetDAT(); + + // 繧ソ繝シ繧イ繝繝医′謫堺ス懊☆繧倶ソ。蜿キ邱 + ctrl.bus->SetREQ(FALSE); + + switch (ctrl.phase) { + // 繧ウ繝槭Φ繝峨ヵ繧ァ繝シ繧コ + case BUS::command: + ctrl.cmd[ctrl.offset] = data; +#if defined(DISK_LOG) + Log(Log::Normal, "繧ウ繝槭Φ繝峨ヵ繧ァ繝シ繧コ $%02X", data); +#endif // DISK_LOG + + // 譛蛻昴ョ繝繝シ繧ソ(繧ェ繝輔そ繝繝0)縺ォ繧医j繝ャ繝ウ繧ー繧ケ繧貞崎ィュ螳 + if (ctrl.offset == 0) { + if (ctrl.cmd[0] >= 0x20 && ctrl.cmd[0] <= 0x7D) { + // 10繝舌う繝CDB + ctrl.length = 10; + } + } + break; + + // 繝繝シ繧ソ繧「繧ヲ繝医ヵ繧ァ繝シ繧コ + case BUS::dataout: + ctrl.buffer[ctrl.offset] = (BYTE)data; + break; + + // 縺昴ョ莉(縺ゅj縺医↑縺) + default: + ASSERT(FALSE); + break; + } +} +#endif // RASCSI + +#ifdef RASCSI +//--------------------------------------------------------------------------- +// +// 繝繝シ繧ソ蜿嶺ソ。 +// +//--------------------------------------------------------------------------- +void FASTCALL SASIDEV::Receive() +#else +//--------------------------------------------------------------------------- +// +// 繝繝シ繧ソ蜿嶺ソ。邯咏カ +// +//--------------------------------------------------------------------------- +void FASTCALL SASIDEV::ReceiveNext() +#endif // RASCSI +{ +#ifdef RASCSI + int len; +#endif // RASCSI + BOOL result; + + ASSERT(this); + + // REQ縺御ク九′縺」縺ヲ縺繧九%縺ィ + ASSERT(!ctrl.bus->GetREQ()); + ASSERT(!ctrl.bus->GetIO()); + +#ifdef RASCSI // 繝ャ繝ウ繧ー繧ケ!=0縺ェ繧牙女菫。 if (ctrl.length != 0) { // 蜿嶺ソ。 @@ -7240,7 +7572,7 @@ void FASTCALL SASIDEV::Receive() &ctrl.buffer[ctrl.offset], ctrl.length); // 蜈ィ縺ヲ蜿嶺ソ。縺ァ縺阪↑縺代l縺ー繧ケ繝繝シ繧ソ繧ケ繝輔ぉ繝シ繧コ縺ク遘サ陦 - if (len != ctrl.length) { + if (len != (int)ctrl.length) { Error(); return; } @@ -7250,6 +7582,19 @@ void FASTCALL SASIDEV::Receive() ctrl.length = 0; return; } +#else + // 繧ェ繝輔そ繝繝医→繝ャ繝ウ繧ー繧ケ + ASSERT(ctrl.length >= 1); + ctrl.offset++; + ctrl.length--; + + // 繝ャ繝ウ繧ー繧ケ!=0縺ェ繧峨∝阪ウreq繧偵そ繝繝 + if (ctrl.length != 0) { + // 繧ソ繝シ繧イ繝繝医′謫堺ス懊☆繧倶ソ。蜿キ邱 + ctrl.bus->SetREQ(TRUE); + return; + } +#endif // RASCSI // 繝悶Ο繝繧ッ貂帷ョ励√Μ繧カ繝ォ繝亥晄悄蛹 ctrl.blocks--; @@ -7276,32 +7621,28 @@ void FASTCALL SASIDEV::Receive() if (ctrl.blocks != 0){ ASSERT(ctrl.length > 0); ASSERT(ctrl.offset == 0); +#ifndef RASCSI + // 繧ソ繝シ繧イ繝繝医′謫堺ス懊☆繧倶ソ。蜿キ邱 + ctrl.bus->SetREQ(TRUE); +#endif // RASCSI return; } // 谺。繝輔ぉ繝シ繧コ縺ォ遘サ蜍 switch (ctrl.phase) { +#ifndef RASCSI // 繧ウ繝槭Φ繝峨ヵ繧ァ繝シ繧コ case BUS::command: - // 繧ウ繝槭Φ繝峨ョ繝シ繧ソ霆「騾 - len = 6; - if (ctrl.buffer[0] >= 0x20 && ctrl.buffer[0] <= 0x7D) { - // 10繝舌う繝CDB - len = 10; - } - for (i = 0; i < len; i++) { - ctrl.cmd[i] = (DWORD)ctrl.buffer[i]; -#if defined(DISK_LOG) - Log(Log::Normal, "繧ウ繝槭Φ繝 $%02X", ctrl.cmd[i]); -#endif // DISK_LOG - } - // 螳溯。後ヵ繧ァ繝シ繧コ Execute(); break; +#endif // RASCSI // 繝繝シ繧ソ繧「繧ヲ繝医ヵ繧ァ繝シ繧コ case BUS::dataout: + // 繝輔Λ繝繧キ繝・ + FlushUnit(); + // 繧ケ繝繝シ繧ソ繧ケ繝輔ぉ繝シ繧コ Status(); break; @@ -7388,7 +7729,8 @@ BOOL FASTCALL SASIDEV::XferOut(BOOL cont) case 0x15: // MODE SELECT(10) case 0x55: - if (!ctrl.unit[lun]->ModeSelect(ctrl.cmd, ctrl.buffer, ctrl.offset)) { + if (!ctrl.unit[lun]->ModeSelect( + ctrl.cmd, ctrl.buffer, ctrl.offset)) { // MODE SELECT縺ォ螟ア謨 return FALSE; } @@ -7426,7 +7768,7 @@ BOOL FASTCALL SASIDEV::XferOut(BOOL cont) } // 谺。縺ョ繝悶Ο繝繧ッ繧偵メ繧ァ繝繧ッ - ctrl.length = ctrl.unit[lun]->WriteCheck(ctrl.next); + ctrl.length = ctrl.unit[lun]->WriteCheck(ctrl.next - 1); if (ctrl.length <= 0) { // 譖ク縺崎セシ縺ソ縺ァ縺阪↑縺 return FALSE; @@ -7436,6 +7778,10 @@ BOOL FASTCALL SASIDEV::XferOut(BOOL cont) ctrl.offset = 0; break; + // SPECIFY(SASI縺ョ縺ソ) + case 0xc2: + break; + default: ASSERT(FALSE); break; @@ -7445,6 +7791,43 @@ BOOL FASTCALL SASIDEV::XferOut(BOOL cont) return TRUE; } +//--------------------------------------------------------------------------- +// +// 隲也炊繝ヲ繝九ャ繝医ヵ繝ゥ繝繧キ繝・ +// +//--------------------------------------------------------------------------- +void FASTCALL SASIDEV::FlushUnit() +{ + DWORD lun; + + ASSERT(this); + ASSERT(ctrl.phase == BUS::dataout); + + // 隲也炊繝ヲ繝九ャ繝 + lun = (ctrl.cmd[1] >> 5) & 0x07; + if (!ctrl.unit[lun]) { + return; + } + + // WRITE邉サ縺ョ縺ソ + switch (ctrl.cmd[0]) { + // WRITE(6) + case 0x0a: + // WRITE(10) + case 0x2a: + // WRITE AND VERIFY + case 0x2e: + // 繝輔Λ繝繧キ繝・ + if (!ctrl.unit[lun]->IsCacheWB()) { + ctrl.unit[lun]->Flush(); + } + break; + default: + ASSERT(FALSE); + break; + } +} + //--------------------------------------------------------------------------- // // 繝ュ繧ー蜃コ蜉 @@ -7452,6 +7835,7 @@ BOOL FASTCALL SASIDEV::XferOut(BOOL cont) //--------------------------------------------------------------------------- void FASTCALL SASIDEV::Log(Log::loglevel level, const char *format, ...) { +#if !defined(BAREMETAL) char buffer[0x200]; va_list args; va_start(args, format); @@ -7476,6 +7860,7 @@ void FASTCALL SASIDEV::Log(Log::loglevel level, const char *format, ...) #else host->GetVM()->GetLog()->Format(level, host, buffer); #endif // RASCSI +#endif // BAREMETAL } //=========================================================================== @@ -7555,7 +7940,6 @@ BUS::phase_t FASTCALL SCSIDEV::Process() // 繝輔ぉ繝シ繧コ蜃ヲ逅 switch (ctrl.phase) { - // 繝舌せ繝輔Μ繝シ case BUS::busfree: BusFree(); @@ -7631,11 +8015,11 @@ void FASTCALL SCSIDEV::BusFree() ctrl.phase = BUS::busfree; // 菫。蜿キ邱 - ctrl.bus->SetBSY(FALSE); + ctrl.bus->SetREQ(FALSE); ctrl.bus->SetMSG(FALSE); ctrl.bus->SetCD(FALSE); ctrl.bus->SetIO(FALSE); - ctrl.bus->SetREQ(FALSE); + ctrl.bus->SetBSY(FALSE); // 繧ケ繝繝シ繧ソ繧ケ縺ィ繝。繝繧サ繝シ繧ク繧貞晄悄蛹 ctrl.status = 0x00; @@ -7643,10 +8027,6 @@ void FASTCALL SCSIDEV::BusFree() // ATN繝。繝繧サ繝シ繧ク蜿嶺ソ。繧ケ繧ソ繝シ繧ソ繧ケ蛻晄悄蛹 scsi.atnmsg = FALSE; - - // 繝舌せ繧ッ繝ェ繧「繝繧」繝ャ繧、 - ctrl.bus->SleepNsec(Time_phase_bsy); - return; } @@ -7681,7 +8061,8 @@ void FASTCALL SCSIDEV::Selection() } #if defined(DISK_LOG) - Log(Log::Normal, "繧サ繝ャ繧ッ繧キ繝ァ繝ウ繝輔ぉ繝シ繧コ ID=%d (繝繝舌う繧ケ縺ゅj)", ctrl.id); + Log(Log::Normal, + "繧サ繝ャ繧ッ繧キ繝ァ繝ウ繝輔ぉ繝シ繧コ ID=%d (繝繝舌う繧ケ縺ゅj)", ctrl.id); #endif // DISK_LOG // 繝輔ぉ繝シ繧コ險ュ螳 @@ -7722,9 +8103,9 @@ void FASTCALL SCSIDEV::Execute() // 繝繝シ繧ソ霆「騾√ョ縺溘a縺ョ蛻晄悄蛹 ctrl.offset = 0; ctrl.blocks = 1; - - // 蜃ヲ逅譎る俣縺ョ繝繧」繝ャ繧、 - ctrl.bus->SleepNsec(100 * 1000); +#ifdef RASCSI + ctrl.execstart = SysTimer::GetTimerLow(); +#endif // RASCSI // 繧ウ繝槭Φ繝牙挨蜃ヲ逅 switch (ctrl.cmd[0]) { @@ -7867,6 +8248,11 @@ void FASTCALL SCSIDEV::Execute() case 0x5a: CmdModeSense10(); return; + + // SPECIFY(SASI縺ョ縺ソ/SxSI蛻ゥ逕ィ譎ゅョ隴ヲ蜻頑椛蛻カ) + case 0xc2: + CmdInvalid(); + return; } // 縺昴l莉・螟悶ッ蟇セ蠢懊@縺ヲ縺縺ェ縺 @@ -7890,16 +8276,14 @@ void FASTCALL SCSIDEV::MsgOut() Log(Log::Normal, "繝。繝繧サ繝シ繧ク繧「繧ヲ繝医ヵ繧ァ繝シ繧コ"); #endif // DISK_LOG - // 繧サ繝ャ繧ッ繧キ繝ァ繝ウ蠕後ョ繝。繝繧サ繝シ繧ク繧「繧ヲ繝医ヵ繧ァ繝シ繧コ縺ッIDENTIFY繝。繝繧サ繝シ繧ク縺ョ蜃ヲ逅 + // 繧サ繝ャ繧ッ繧キ繝ァ繝ウ蠕後ョ繝。繝繧サ繝シ繧ク繧「繧ヲ繝医ヵ繧ァ繝シ繧コ縺ッ + // IDENTIFY繝。繝繧サ繝シ繧ク縺ョ蜃ヲ逅 if (ctrl.phase == BUS::selection) { scsi.atnmsg = TRUE; scsi.msc = 0; memset(scsi.msb, 0x00, sizeof(scsi.msb)); } - // 繝輔ぉ繝シ繧コ繝√ぉ繝ウ繧ク蜑阪ョ繧ヲ繧ァ繧、繝 - ctrl.bus->SleepNsec(Time_phase_before); - // 繝輔ぉ繝シ繧コ險ュ螳 ctrl.phase = BUS::msgout; @@ -7908,18 +8292,35 @@ void FASTCALL SCSIDEV::MsgOut() ctrl.bus->SetCD(TRUE); ctrl.bus->SetIO(FALSE); - // 繝輔ぉ繝シ繧コ繝√ぉ繝ウ繧ク蠕後ョ莠亥相譎る俣 - ctrl.bus->SleepNsec(Time_phase_after); - // 繝繝シ繧ソ霆「騾√ッ1繝舌う繝x1繝悶Ο繝繧ッ ctrl.offset = 0; ctrl.length = 1; ctrl.blocks = 1; + +#ifndef RASCSI + // 繝。繝繧サ繝シ繧ク繧定ヲ∵ア + ctrl.bus->SetREQ(TRUE); +#endif // RASCSI return; } +#ifdef RASCSI // 蜿嶺ソ。 Receive(); +#else + // 繝ェ繧ッ繧ィ繧ケ繝井クュ + if (ctrl.bus->GetREQ()) { + // 繧、繝九す繧ィ繝シ繧ソ縺碁∽ソ。縺励◆ + if (ctrl.bus->GetACK()) { + Receive(); + } + } else { + // 繧、繝九す繧ィ繝シ繧ソ縺ォ谺。繧定ヲ∵ア + if (!ctrl.bus->GetACK()) { + ReceiveNext(); + } + } +#endif // RASCSI } //--------------------------------------------------------------------------- @@ -8003,7 +8404,8 @@ void FASTCALL SCSIDEV::CmdInquiry() #else host->GetVM()->GetVersion(major, minor); #endif // RASCSI - ctrl.length = ctrl.unit[lun]->Inquiry(ctrl.cmd, ctrl.buffer, major, minor); + ctrl.length = + ctrl.unit[lun]->Inquiry(ctrl.cmd, ctrl.buffer, major, minor); } else { ctrl.length = 0; } @@ -8083,7 +8485,8 @@ void FASTCALL SCSIDEV::CmdModeSense() ctrl.length = ctrl.unit[lun]->ModeSense(ctrl.cmd, ctrl.buffer); ASSERT(ctrl.length >= 0); if (ctrl.length == 0) { - Log(Log::Warning, "繧オ繝昴シ繝医@縺ヲ縺縺ェ縺МODE SENSE繝壹シ繧ク $%02X", ctrl.cmd[2]); + Log(Log::Warning, + "繧オ繝昴シ繝医@縺ヲ縺縺ェ縺МODE SENSE繝壹シ繧ク $%02X", ctrl.cmd[2]); // 螟ア謨(繧ィ繝ゥ繝シ) Error(); @@ -8337,7 +8740,8 @@ void FASTCALL SCSIDEV::CmdWrite10() ctrl.blocks |= ctrl.cmd[8]; #if defined(DISK_LOG) - Log(Log::Normal, "WRTIE(10)繧ウ繝槭Φ繝 繝ャ繧ウ繝シ繝=%08X 繝悶Ο繝繧ッ=%d", record, ctrl.blocks); + Log(Log::Normal, + "WRTIE(10)繧ウ繝槭Φ繝 繝ャ繧ウ繝シ繝=%08X 繝悶Ο繝繧ッ=%d", record, ctrl.blocks); #endif // DISK_LOG // 繝悶Ο繝繧ッ謨ー0縺ッ蜃ヲ逅縺励↑縺 @@ -8429,7 +8833,8 @@ void FASTCALL SCSIDEV::CmdVerify() ctrl.blocks |= ctrl.cmd[8]; #if defined(DISK_LOG) - Log(Log::Normal, "VERIFY繧ウ繝槭Φ繝 繝ャ繧ウ繝シ繝=%08X 繝悶Ο繝繧ッ=%d", record, ctrl.blocks); + Log(Log::Normal, + "VERIFY繧ウ繝槭Φ繝 繝ャ繧ウ繝シ繝=%08X 繝悶Ο繝繧ッ=%d", record, ctrl.blocks); #endif // DISK_LOG // 繝悶Ο繝繧ッ謨ー0縺ッ蜃ヲ逅縺励↑縺 @@ -8710,7 +9115,8 @@ void FASTCALL SCSIDEV::CmdModeSense10() ctrl.length = ctrl.unit[lun]->ModeSense10(ctrl.cmd, ctrl.buffer); ASSERT(ctrl.length >= 0); if (ctrl.length == 0) { - Log(Log::Warning, "繧オ繝昴シ繝医@縺ヲ縺縺ェ縺МODE SENSE(10)繝壹シ繧ク $%02X", ctrl.cmd[2]); + Log(Log::Warning, + "繧オ繝昴シ繝医@縺ヲ縺縺ェ縺МODE SENSE(10)繝壹シ繧ク $%02X", ctrl.cmd[2]); // 螟ア謨(繧ィ繝ゥ繝シ) Error(); @@ -8748,9 +9154,9 @@ void FASTCALL SCSIDEV::CmdGetMessage10() // 繝舌ャ繝輔ぃ縺ョ蜀咲「コ菫(繝悶Ο繝繧ッ豈弱ョ霆「騾√〒縺ッ縺ェ縺縺溘a) if (ctrl.bufsize < 0x1000000) { - delete ctrl.buffer; + free(ctrl.buffer); ctrl.bufsize = 0x1000000; - ctrl.buffer = new BYTE[ctrl.bufsize]; + ctrl.buffer = (BYTE *)malloc(ctrl.bufsize); } // 繝峨Λ繧、繝悶〒蜃ヲ逅縺吶k @@ -8797,9 +9203,9 @@ void FASTCALL SCSIDEV::CmdSendMessage10() // 繝舌ャ繝輔ぃ縺ョ蜀咲「コ菫(繝悶Ο繝繧ッ豈弱ョ霆「騾√〒縺ッ縺ェ縺縺溘a) if (ctrl.bufsize < 0x1000000) { - delete ctrl.buffer; + free(ctrl.buffer); ctrl.bufsize = 0x1000000; - ctrl.buffer = new BYTE[ctrl.bufsize]; + ctrl.buffer = (BYTE *)malloc(ctrl.bufsize); } // 霆「騾驥上r險ュ螳 @@ -8836,21 +9242,23 @@ void FASTCALL SCSIDEV::CmdSendMessage10() //--------------------------------------------------------------------------- void FASTCALL SCSIDEV::Send() { +#ifdef RASCSI int len; +#endif // RASCSI BOOL result; ASSERT(this); ASSERT(!ctrl.bus->GetREQ()); - ASSERT(!ctrl.bus->GetACK()); ASSERT(ctrl.bus->GetIO()); +#ifdef RASCSI // 繝ャ繝ウ繧ー繧ケ!=0縺ェ繧蛾∽ソ。 if (ctrl.length != 0) { len = ctrl.bus->SendHandShake( &ctrl.buffer[ctrl.offset], ctrl.length); // 蜈ィ縺ヲ騾∽ソ。縺ァ縺阪↑縺代l縺ー繧ケ繝繝シ繧ソ繧ケ繝輔ぉ繝シ繧コ縺ク遘サ陦 - if (len != ctrl.length) { + if (len != (int)ctrl.length) { Error(); return; } @@ -8860,6 +9268,19 @@ void FASTCALL SCSIDEV::Send() ctrl.length = 0; return; } +#else + // 繧ェ繝輔そ繝繝医→繝ャ繝ウ繧ー繧ケ + ASSERT(ctrl.length >= 1); + ctrl.offset++; + ctrl.length--; + + // ACK繧「繧オ繝シ繝育峩蠕後↓SendNext縺ァ繝繝シ繧ソ險ュ螳壽ク医∩縺ェ繧峨Μ繧ッ繧ィ繧ケ繝医r荳翫£繧 + if (ctrl.length != 0) { + // 繧ソ繝シ繧イ繝繝医′謫堺ス懊☆繧倶ソ。蜿キ邱 + ctrl.bus->SetREQ(TRUE); + return; + } +#endif // RASCSI // 繝悶Ο繝繧ッ貂帷ョ励√Μ繧カ繝ォ繝亥晄悄蛹 ctrl.blocks--; @@ -8870,6 +9291,9 @@ void FASTCALL SCSIDEV::Send() if (ctrl.blocks != 0) { // 谺。縺ョ繝舌ャ繝輔ぃ繧定ィュ螳(offset, length繧偵そ繝繝医☆繧九%縺ィ) result = XferIn(ctrl.buffer); +#ifndef RASCSI + ctrl.bus->SetDAT(ctrl.buffer[ctrl.offset]); +#endif // RASCSI } } @@ -8883,6 +9307,10 @@ void FASTCALL SCSIDEV::Send() if (ctrl.blocks != 0){ ASSERT(ctrl.length > 0); ASSERT(ctrl.offset == 0); +#ifndef RASCSI + // 繧ソ繝シ繧イ繝繝医′謫堺ス懊☆繧倶ソ。蜿キ邱 + ctrl.bus->SetREQ(TRUE); +#endif // RASCSI return; } @@ -8914,7 +9342,7 @@ void FASTCALL SCSIDEV::Send() // 繝。繝繧サ繝シ繧ク繧、繝ウ繝輔ぉ繝シ繧コ ctrl.length = 1; ctrl.blocks = 1; - ctrl.buffer[0] = ctrl.message; + ctrl.buffer[0] = (BYTE)ctrl.message; MsgIn(); break; @@ -8925,6 +9353,31 @@ void FASTCALL SCSIDEV::Send() } } +#ifndef RASCSI +//--------------------------------------------------------------------------- +// +// 繝繝シ繧ソ騾∽ソ。邯咏カ +// +//--------------------------------------------------------------------------- +void FASTCALL SCSIDEV::SendNext() +{ + ASSERT(this); + + // REQ縺御ク翫′縺」縺ヲ縺繧 + ASSERT(ctrl.bus->GetREQ()); + ASSERT(ctrl.bus->GetIO()); + + // 繧ソ繝シ繧イ繝繝医′謫堺ス懊☆繧倶ソ。蜿キ邱 + ctrl.bus->SetREQ(FALSE); + + // 繝舌ャ繝輔ぃ縺ォ繝繝シ繧ソ縺後≠繧後ー蜈医↓險ュ螳壹☆繧 + if (ctrl.length > 1) { + ctrl.bus->SetDAT(ctrl.buffer[ctrl.offset + 1]); + } +} +#endif // RASCSI + +#ifndef RASCSI //--------------------------------------------------------------------------- // // 繝繝シ繧ソ蜿嶺ソ。 @@ -8932,18 +9385,88 @@ void FASTCALL SCSIDEV::Send() //--------------------------------------------------------------------------- void FASTCALL SCSIDEV::Receive() { - BYTE data; - BOOL result; - int i; - int len; + DWORD data; ASSERT(this); - // REQ,ACK縺御ク九′縺」縺ヲ縺繧九%縺ィ - ASSERT(!ctrl.bus->GetREQ()); - ASSERT(!ctrl.bus->GetACK()); + // REQ縺御ク翫′縺」縺ヲ縺繧 + ASSERT(ctrl.bus->GetREQ()); ASSERT(!ctrl.bus->GetIO()); + // 繝繝シ繧ソ蜿門セ + data = (DWORD)ctrl.bus->GetDAT(); + + // 繧ソ繝シ繧イ繝繝医′謫堺ス懊☆繧倶ソ。蜿キ邱 + ctrl.bus->SetREQ(FALSE); + + switch (ctrl.phase) { + // 繧ウ繝槭Φ繝峨ヵ繧ァ繝シ繧コ + case BUS::command: + ctrl.cmd[ctrl.offset] = data; +#if defined(DISK_LOG) + Log(Log::Normal, "繧ウ繝槭Φ繝峨ヵ繧ァ繝シ繧コ $%02X", data); +#endif // DISK_LOG + + // 譛蛻昴ョ繝繝シ繧ソ(繧ェ繝輔そ繝繝0)縺ォ繧医j繝ャ繝ウ繧ー繧ケ繧貞崎ィュ螳 + if (ctrl.offset == 0) { + if (ctrl.cmd[0] >= 0x20) { + // 10繝舌う繝CDB + ctrl.length = 10; + } + } + break; + + // 繝。繝繧サ繝シ繧ク繧「繧ヲ繝医ヵ繧ァ繝シ繧コ + case BUS::msgout: + ctrl.message = data; +#if defined(DISK_LOG) + Log(Log::Normal, "繝。繝繧サ繝シ繧ク繧「繧ヲ繝医ヵ繧ァ繝シ繧コ $%02X", data); +#endif // DISK_LOG + break; + + // 繝繝シ繧ソ繧「繧ヲ繝医ヵ繧ァ繝シ繧コ + case BUS::dataout: + ctrl.buffer[ctrl.offset] = (BYTE)data; + break; + + // 縺昴ョ莉(縺ゅj縺医↑縺) + default: + ASSERT(FALSE); + break; + } +} +#endif // RASCSI + +#ifdef RASCSI +//--------------------------------------------------------------------------- +// +// 繝繝シ繧ソ蜿嶺ソ。 +// +//--------------------------------------------------------------------------- +void FASTCALL SCSIDEV::Receive() +#else +//--------------------------------------------------------------------------- +// +// 繝繝シ繧ソ蜿嶺ソ。邯咏カ +// +//--------------------------------------------------------------------------- +void FASTCALL SCSIDEV::ReceiveNext() +#endif // RASCSI +{ +#ifdef RASCSI + int len; +#endif // RASCSI + BOOL result; + int i; + BYTE data; + + ASSERT(this); + + // REQ縺御ク九′縺」縺ヲ縺繧九%縺ィ + ASSERT(!ctrl.bus->GetREQ()); + ASSERT(!ctrl.bus->GetIO()); + +#ifdef RASCSI // 繝ャ繝ウ繧ー繧ケ!=0縺ェ繧牙女菫。 if (ctrl.length != 0) { // 蜿嶺ソ。 @@ -8951,7 +9474,7 @@ void FASTCALL SCSIDEV::Receive() &ctrl.buffer[ctrl.offset], ctrl.length); // 蜈ィ縺ヲ蜿嶺ソ。縺ァ縺阪↑縺代l縺ー繧ケ繝繝シ繧ソ繧ケ繝輔ぉ繝シ繧コ縺ク遘サ陦 - if (len != ctrl.length) { + if (len != (int)ctrl.length) { Error(); return; } @@ -8961,6 +9484,19 @@ void FASTCALL SCSIDEV::Receive() ctrl.length = 0;; return; } +#else + // 繧ェ繝輔そ繝繝医→繝ャ繝ウ繧ー繧ケ + ASSERT(ctrl.length >= 1); + ctrl.offset++; + ctrl.length--; + + // 繝ャ繝ウ繧ー繧ケ!=0縺ェ繧峨∝阪ウreq繧偵そ繝繝 + if (ctrl.length != 0) { + // 繧ソ繝シ繧イ繝繝医′謫堺ス懊☆繧倶ソ。蜿キ邱 + ctrl.bus->SetREQ(TRUE); + return; + } +#endif // RASCSI // 繝悶Ο繝繧ッ貂帷ョ励√Μ繧カ繝ォ繝亥晄悄蛹 ctrl.blocks--; @@ -9007,6 +9543,10 @@ void FASTCALL SCSIDEV::Receive() if (ctrl.blocks != 0){ ASSERT(ctrl.length > 0); ASSERT(ctrl.offset == 0); +#ifndef RASCSI + // 繧ソ繝シ繧イ繝繝医′謫堺ス懊☆繧倶ソ。蜿キ邱 + ctrl.bus->SetREQ(TRUE); +#endif // RASCSI return; } @@ -9014,6 +9554,7 @@ void FASTCALL SCSIDEV::Receive() switch (ctrl.phase) { // 繧ウ繝槭Φ繝峨ヵ繧ァ繝シ繧コ case BUS::command: +#ifdef RASCSI // 繧ウ繝槭Φ繝峨ョ繝シ繧ソ霆「騾 len = 6; if (ctrl.buffer[0] >= 0x20 && ctrl.buffer[0] <= 0x7D) { @@ -9026,6 +9567,7 @@ void FASTCALL SCSIDEV::Receive() Log(Log::Normal, "繧ウ繝槭Φ繝 $%02X", ctrl.cmd[i]); #endif // DISK_LOG } +#endif // RASCSI // 螳溯。後ヵ繧ァ繝シ繧コ Execute(); @@ -9039,6 +9581,10 @@ void FASTCALL SCSIDEV::Receive() ctrl.offset = 0; ctrl.length = 1; ctrl.blocks = 1; +#ifndef RASCSI + // 繝。繝繧サ繝シ繧ク繧定ヲ∵ア + ctrl.bus->SetREQ(TRUE); +#endif // RASCSI return; } @@ -9052,7 +9598,8 @@ void FASTCALL SCSIDEV::Receive() // ABORT if (data == 0x06) { #if defined(DISK_LOG) - Log(Log::Normal, "繝。繝繧サ繝シ繧ク繧ウ繝シ繝 ABORT $%02X", data); + Log(Log::Normal, + "繝。繝繧サ繝シ繧ク繧ウ繝シ繝 ABORT $%02X", data); #endif // DISK_LOG BusFree(); return; @@ -9061,7 +9608,8 @@ void FASTCALL SCSIDEV::Receive() // BUS DEVICE RESET if (data == 0x0C) { #if defined(DISK_LOG) - Log(Log::Normal, "繝。繝繧サ繝シ繧ク繧ウ繝シ繝 BUS DEVICE RESET $%02X", data); + Log(Log::Normal, + "繝。繝繧サ繝シ繧ク繧ウ繝シ繝 BUS DEVICE RESET $%02X", data); #endif // DISK_LOG scsi.syncoffset = 0; BusFree(); @@ -9071,14 +9619,16 @@ void FASTCALL SCSIDEV::Receive() // IDENTIFY if (data >= 0x80) { #if defined(DISK_LOG) - Log(Log::Normal, "繝。繝繧サ繝シ繧ク繧ウ繝シ繝 IDENTIFY $%02X", data); + Log(Log::Normal, + "繝。繝繧サ繝シ繧ク繧ウ繝シ繝 IDENTIFY $%02X", data); #endif // DISK_LOG } // 諡。蠑オ繝。繝繧サ繝シ繧ク if (data == 0x01) { #if defined(DISK_LOG) - Log(Log::Normal, "繝。繝繧サ繝シ繧ク繧ウ繝シ繝 EXTENDED MESSAGE $%02X", data); + Log(Log::Normal, + "繝。繝繧サ繝シ繧ク繧ウ繝シ繝 EXTENDED MESSAGE $%02X", data); #endif // DISK_LOG // 蜷梧悄霆「騾√′蜿ッ閭ス縺ェ譎ゅ□縺代メ繧ァ繝繧ッ @@ -9108,8 +9658,8 @@ void FASTCALL SCSIDEV::Receive() ctrl.buffer[0] = 0x01; ctrl.buffer[1] = 0x03; ctrl.buffer[2] = 0x01; - ctrl.buffer[3] = scsi.syncperiod; - ctrl.buffer[4] = scsi.syncoffset; + ctrl.buffer[3] = (BYTE)scsi.syncperiod; + ctrl.buffer[4] = (BYTE)scsi.syncoffset; MsgIn(); return; } @@ -9128,6 +9678,9 @@ void FASTCALL SCSIDEV::Receive() // 繝繝シ繧ソ繧「繧ヲ繝医ヵ繧ァ繝シ繧コ case BUS::dataout: + // 繝輔Λ繝繧キ繝・ + FlushUnit(); + // 繧ケ繝繝シ繧ソ繧ケ繝輔ぉ繝シ繧コ Status(); break; @@ -9151,7 +9704,7 @@ BOOL FASTCALL SCSIDEV::XferMsg(DWORD msg) // 繝。繝繧サ繝シ繧ク繧「繧ヲ繝医ョ繝シ繧ソ縺ョ菫晏ュ if (scsi.atnmsg) { - scsi.msb[scsi.msc] = msg; + scsi.msb[scsi.msc] = (BYTE)msg; scsi.msc++; scsi.msc %= 256; } diff --git a/src/raspberrypi/disk.h b/src/raspberrypi/disk.h index 0d440890..a539c905 100644 --- a/src/raspberrypi/disk.h +++ b/src/raspberrypi/disk.h @@ -3,7 +3,7 @@ // X68000 EMULATOR "XM6" // // Copyright (C) 2001-2006 シーシゥシ(ytanaka@ipc-tokai.or.jp) -// Copyright (C) 2014-2018 GIMONS +// Copyright (C) 2014-2020 GIMONS // // XM6i // Copyright (C) 2010-2015 isaki@NetBSD.org @@ -319,6 +319,8 @@ public: // 繧オ繝昴シ繝医@縺ヲ縺縺ェ縺繧ウ繝槭Φ繝 // 縺昴ョ莉 + BOOL IsCacheWB() { return cache_wb; } + // 繧ュ繝」繝繧キ繝・繝「繝シ繝牙叙蠕 void SetCacheWB(BOOL enable) { cache_wb = enable; } // 繧ュ繝」繝繧キ繝・繝「繝シ繝芽ィュ螳 @@ -703,7 +705,9 @@ private: // SCSI 繝帙せ繝医ヶ繝ェ繝繧ク // //=========================================================================== +#if defined(RASCSI) && !defined(BAREMETAL) class CTapDriver; +#endif // RASCSI && !BAREMETAL class CFileSys; class SCSIBR : public Disk { @@ -725,6 +729,7 @@ public: // SEND MESSAGE10繧ウ繝槭Φ繝 private: +#if defined(RASCSI) && !defined(BAREMETAL) int FASTCALL GetMacAddr(BYTE *buf); // MAC繧「繝峨Ξ繧ケ蜿門セ void FASTCALL SetMacAddr(BYTE *buf); @@ -748,7 +753,7 @@ private: // 蜿嶺ソ。繝代こ繝繝医ヰ繝繝輔ぃ BOOL packet_enable; // 蜿嶺ソ。繝代こ繝繝域怏蜉ケ - +#endif // RASCSI && !BAREMETAL int FASTCALL ReadFsResult(BYTE *buf); // 繝輔ぃ繧、繝ォ繧キ繧ケ繝繝隱ュ縺ソ霎シ縺ソ(邨先棡繧ウ繝シ繝) @@ -840,14 +845,13 @@ public: UnitMax = 8 }; - // 繝輔ぉ繝シ繧コ繧ソ繧、繝溘Φ繧ー(隱ソ謨エ逕ィ) +#ifdef RASCSI + // 繧ソ繧、繝溘Φ繧ー隱ソ謨エ逕ィ enum { - Time_phase_bsy = 800, - Time_phase_before = 6000, // min 4000ns - Time_phase_before_data = 60000, // min 40000ns - Time_phase_after = 6000, // min 4000ns - Time_phase_after_status = 12000, // min 9000ns + min_exec_time_sasi = 100, // SASI BOOT/FORMAT 30:NG 35:OK + min_exec_time_scsi = 50 }; +#endif // RASCSI // 蜀驛ィ繝繝シ繧ソ螳夂セゥ typedef struct { @@ -861,6 +865,11 @@ public: DWORD status; // 繧ケ繝繝シ繧ソ繧ケ繝繝シ繧ソ DWORD message; // 繝。繝繧サ繝シ繧ク繝繝シ繧ソ +#ifdef RASCSI + // 螳溯。 + DWORD execstart; // 螳溯。碁幕蟋区凾髢 +#endif // RASCSI + // 霆「騾 BYTE *buffer; // 霆「騾√ヰ繝繝輔ぃ int bufsize; // 霆「騾√ヰ繝繝輔ぃ繧オ繧、繧コ @@ -919,6 +928,8 @@ public: // 蜀驛ィ諠蝣ア繧「繝峨Ξ繧ケ蜿門セ virtual BOOL FASTCALL IsSASI() const {return TRUE;} // SASI繝√ぉ繝繧ッ + virtual BOOL FASTCALL IsSCSI() const {return FALSE;} + // SCSI繝√ぉ繝繧ッ Disk* FASTCALL GetBusyUnit(); // 繝薙ず繝シ迥カ諷九ョ繝ヲ繝九ャ繝医r蜿門セ @@ -970,13 +981,25 @@ protected: // 繝繝シ繧ソ霆「騾 virtual void FASTCALL Send(); // 繝繝シ繧ソ騾∽ソ。 +#ifndef RASCSI + virtual void FASTCALL SendNext(); + // 繝繝シ繧ソ騾∽ソ。邯咏カ +#endif // RASCSI virtual void FASTCALL Receive(); // 繝繝シ繧ソ蜿嶺ソ。 +#ifndef RASCSI + virtual void FASTCALL ReceiveNext(); + // 繝繝シ繧ソ蜿嶺ソ。邯咏カ +#endif // RASCSI BOOL FASTCALL XferIn(BYTE* buf); // 繝繝シ繧ソ霆「騾!N BOOL FASTCALL XferOut(BOOL cont); // 繝繝シ繧ソ霆「騾^UT + // 迚ケ谿 + void FASTCALL FlushUnit(); + // 隲也炊繝ヲ繝九ャ繝医ヵ繝ゥ繝繧キ繝・ + // 繝ュ繧ー void FASTCALL Log(Log::loglevel level, const char *format, ...); // 繝ュ繧ー蜃コ蜉 @@ -1010,7 +1033,7 @@ public: // ATN繝。繝繧サ繝シ繧ク BOOL atnmsg; int msc; - BOOL msb[256]; + BYTE msb[256]; } scsi_t; public: @@ -1035,6 +1058,8 @@ public: // 縺昴ョ莉 BOOL FASTCALL IsSASI() const {return FALSE;} // SASI繝√ぉ繝繧ッ + BOOL FASTCALL IsSCSI() const {return TRUE;} + // SCSI繝√ぉ繝繧ッ private: // 繝輔ぉ繝シ繧コ @@ -1096,8 +1121,16 @@ private: // 繝繝シ繧ソ霆「騾 void FASTCALL Send(); // 繝繝シ繧ソ騾∽ソ。 +#ifndef RASCSI + void FASTCALL SendNext(); + // 繝繝シ繧ソ騾∽ソ。邯咏カ +#endif // RASCSI void FASTCALL Receive(); // 繝繝シ繧ソ蜿嶺ソ。 +#ifndef RASCSI + void FASTCALL ReceiveNext(); + // 繝繝シ繧ソ蜿嶺ソ。邯咏カ +#endif // RASCSI BOOL FASTCALL XferMsg(DWORD msg); // 繝繝シ繧ソ霆「騾`SG diff --git a/src/raspberrypi/fileio.cpp b/src/raspberrypi/fileio.cpp index c72c4c4c..f5e03e2d 100644 --- a/src/raspberrypi/fileio.cpp +++ b/src/raspberrypi/fileio.cpp @@ -3,7 +3,7 @@ // X68000 EMULATOR "XM6" // // Copyright (C) 2001-2006 シーシゥシ(ytanaka@ipc-tokai.or.jp) -// Copyright (C) 2010-2018 GIMONS +// Copyright (C) 2010-2020 GIMONS // [ 繝輔ぃ繧、繝ォ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; } - // 隱ュ縺ソ霎シ縺ソ + // 譖ク縺崎セシ縺ソ if (!Write(buffer, size)) { Close(); 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(fname); ASSERT(handle < 0); @@ -118,16 +121,19 @@ BOOL FASTCALL Fileio::Open(LPCTSTR fname, OpenMode mode) return FALSE; } + // 繝繝輔か繝ォ繝医Δ繝シ繝 + omode = directIO ? O_DIRECT : 0; + // 繝「繝シ繝牙挨 switch (mode) { // 隱ュ縺ソ霎シ縺ソ縺ョ縺ソ case ReadOnly: - handle = open(fname, O_RDONLY); + handle = open(fname, O_RDONLY | omode); break; // 譖ク縺崎セシ縺ソ縺ョ縺ソ case WriteOnly: - handle = open(fname, O_CREAT | O_WRONLY | O_TRUNC, 0666); + handle = open(fname, O_CREAT | O_WRONLY | O_TRUNC | omode, 0666); break; // 隱ュ縺ソ譖ク縺堺ク。譁ケ @@ -136,12 +142,12 @@ BOOL FASTCALL Fileio::Open(LPCTSTR fname, OpenMode mode) if (access(fname, 0x06) != 0) { return FALSE; } - handle = open(fname, O_RDWR); + handle = open(fname, O_RDWR | omode); break; // 繧「繝壹Φ繝 case Append: - handle = open(fname, O_CREAT | O_WRONLY | O_APPEND, 0666); + handle = open(fname, O_CREAT | O_WRONLY | O_APPEND | omode, 0666); break; // 縺昴l莉・螟 @@ -154,6 +160,7 @@ BOOL FASTCALL Fileio::Open(LPCTSTR fname, OpenMode mode) if (handle == -1) { return FALSE; } + ASSERT(handle >= 0); 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(fname); - ASSERT(handle < 0); - // 繝後Ν譁蟄怜励°繧峨ョ隱ュ縺ソ霎シ縺ソ縺ッ蠢縺壼、ア謨励&縺帙k - 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縺九i縺ョ隱ュ縺ソ霎シ縺ソ縺ッ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; - - // 縺昴l莉・螟 - default: - ASSERT(FALSE); - break; - } - - // 邨先棡隧穂セ。 - if (handle == -1) { - return FALSE; - } - ASSERT(handle >= 0); - return TRUE; + return Open(fname, mode, FALSE); } //--------------------------------------------------------------------------- @@ -227,6 +189,24 @@ BOOL FASTCALL Fileio::Open(const Filepath& path, OpenMode 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(handle >= 0); - // 隱ュ縺ソ霎シ縺ソ + // 譖ク縺崎セシ縺ソ count = write(handle, buffer, size); if (count != size) { return FALSE; @@ -365,3 +345,273 @@ void FASTCALL Fileio::Close() 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); + + // 繝後Ν譁蟄怜励°繧峨ョ隱ュ縺ソ霎シ縺ソ縺ッ蠢縺壼、ア謨励&縺帙k + 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; + + // 縺昴l莉・螟 + 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 \ No newline at end of file diff --git a/src/raspberrypi/fileio.h b/src/raspberrypi/fileio.h index 22f02ac9..fd9c5ce4 100644 --- a/src/raspberrypi/fileio.h +++ b/src/raspberrypi/fileio.h @@ -3,7 +3,7 @@ // X68000 EMULATOR "XM6" // // Copyright (C) 2001-2005 シーシゥシ(ytanaka@ipc-tokai.or.jp) -// Copyright (C) 2013-2018 GIMONS +// Copyright (C) 2013-2020 GIMONS // [ 繝輔ぃ繧、繝ォI/O(RaSCSI逕ィ繧オ繝悶そ繝繝) ] // //--------------------------------------------------------------------------- @@ -11,6 +11,10 @@ #if !defined(fileio_h) #define fileio_h +#ifdef BAREMETAL +#include "ff.h" +#endif // BAREMETAL + //=========================================================================== // // 繝槭け繝ュ(Load,Save逕ィ) @@ -53,12 +57,14 @@ public: BOOL FASTCALL Open(LPCTSTR fname, OpenMode mode); // 繧ェ繝シ繝励Φ - BOOL FASTCALL OpenDIO(LPCTSTR fname, 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); // 繧ェ繝シ繝励Φ +#endif // BAREMETAL BOOL FASTCALL Seek(off64_t offset, BOOL relative = FALSE); // 繧キ繝シ繧ッ BOOL FASTCALL Read(void *buffer, int size); @@ -71,13 +77,22 @@ public: // 繝輔ぃ繧、繝ォ菴咲スョ蜿門セ void FASTCALL Close(); // 繧ッ繝ュ繝シ繧コ +#ifndef BAREMETAL 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: +#ifndef BAREMETAL + BOOL FASTCALL Open(LPCTSTR fname, OpenMode mode, BOOL directIO); + // 繧ェ繝シ繝励Φ + int handle; // 繝輔ぃ繧、繝ォ繝上Φ繝峨Ν +#else + FIL handle; // 繝輔ぃ繧、繝ォ繝上Φ繝峨Ν +#endif // BAREMETAL }; #endif // fileio_h diff --git a/src/raspberrypi/filepath.cpp b/src/raspberrypi/filepath.cpp index 43d2e410..6025f93f 100644 --- a/src/raspberrypi/filepath.cpp +++ b/src/raspberrypi/filepath.cpp @@ -3,7 +3,7 @@ // X68000 EMULATOR "XM6" // // Copyright (C) 2001-2006 シーシゥシ(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(); } +#ifdef BAREMETAL +//--------------------------------------------------------------------------- +// +// 莠呈鋤髢「謨ー(dirname) 邨先棡縺ッ逶エ縺舌↓繧ウ繝斐シ縺帙h +// +//--------------------------------------------------------------------------- +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) 邨先棡縺ッ逶エ縺舌↓繧ウ繝斐シ縺帙h +// +//--------------------------------------------------------------------------- +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) { strcpy(m_szExt, pExtName); - *pExtName = 0; } if (pBaseName) { diff --git a/src/raspberrypi/filepath.h b/src/raspberrypi/filepath.h index 1817a429..b7a1ced9 100644 --- a/src/raspberrypi/filepath.h +++ b/src/raspberrypi/filepath.h @@ -3,7 +3,7 @@ // X68000 EMULATOR "XM6" // // Copyright (C) 2001-2006 シーシゥシ(ytanaka@ipc-tokai.or.jp) -// Copyright (C) 2012-2018 GIMONS +// Copyright (C) 2012-2020 GIMONS // [ 繝輔ぃ繧、繝ォ繝代せ(繧オ繝悶そ繝繝) ] // //--------------------------------------------------------------------------- diff --git a/src/raspberrypi/gpiobus.cpp b/src/raspberrypi/gpiobus.cpp index 792f8070..69ab840c 100644 --- a/src/raspberrypi/gpiobus.cpp +++ b/src/raspberrypi/gpiobus.cpp @@ -4,7 +4,7 @@ // for Raspberry Pi // // 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. // @@ -16,6 +16,7 @@ #include "xm6.h" #include "gpiobus.h" +#ifndef BAREMETAL #ifdef __linux__ //--------------------------------------------------------------------------- // @@ -44,9 +45,16 @@ static DWORD get_dt_ranges(const char *filename, DWORD offset) DWORD bcm_host_get_peripheral_address(void) { DWORD address; - + address = get_dt_ranges("/proc/device-tree/soc/ranges", 4); - return address == (DWORD)~0 ? 0x20000000 : address; + if (address == 0) { + address = get_dt_ranges("/proc/device-tree/soc/ranges", 8); + } + address = (address == (DWORD)~0) ? 0x20000000 : address; +#if 0 + printf("Peripheral address : 0x%lx\n", address); +#endif + return address; } #endif // __linux__ @@ -70,7 +78,43 @@ DWORD bcm_host_get_peripheral_address(void) printf("Peripheral address : 0x%lx\n", address); return address; } -#endif +#endif // __NetBSD__ +#endif // BAREMETAL + +#ifdef BAREMETAL +// IO繝吶シ繧ケ繧「繝峨Ξ繧ケ +extern uint32_t RPi_IO_Base_Addr; + +// 繧ウ繧「蜻ィ豕「謨ー +extern uint32_t RPi_Core_Freq; + +#ifdef USE_SEL_EVENT_ENABLE +//--------------------------------------------------------------------------- +// +// 蜑イ繧願セシ縺ソ蛻カ蠕。髢「謨ー +// +//--------------------------------------------------------------------------- +extern "C" { +extern uintptr_t setIrqFuncAddress (void(*ARMaddress)(void)); +extern void EnableInterrupts (void); +extern void DisableInterrupts (void); +extern void WaitForInterrupts (void); +} + +//--------------------------------------------------------------------------- +// +// 蜑イ繧願セシ縺ソ繝上Φ繝峨Λ +// +//--------------------------------------------------------------------------- +static GPIOBUS *self; +extern "C" +void IrqHandler() +{ + // 蜑イ繧願セシ縺ソ繧ッ繝ェ繧「 + self->ClearSelectEvent(); +} +#endif // USE_SEL_EVENT_ENABLE +#endif // BAREMETAL //--------------------------------------------------------------------------- // @@ -79,6 +123,9 @@ DWORD bcm_host_get_peripheral_address(void) //--------------------------------------------------------------------------- GPIOBUS::GPIOBUS() { +#if defined(USE_SEL_EVENT_ENABLE) && defined(BAREMETAL) + self = this; +#endif // USE_SEL_EVENT_ENABLE && BAREMETAL } //--------------------------------------------------------------------------- @@ -90,186 +137,6 @@ GPIOBUS::~GPIOBUS() { } -//--------------------------------------------------------------------------- -// -// 繝斐Φ讖溯ス險ュ螳(蜈・蜃コ蜉幄ィュ螳) -// -//--------------------------------------------------------------------------- -void FASTCALL GPIOBUS::PinConfig(int pin, int mode) -{ - int index; - DWORD mask; - - // 譛ェ菴ソ逕ィ縺ェ繧臥┌蜉ケ - if (pin < 0) { - return; - } - - index = pin / 10; - mask = ~(0x7 << ((pin % 10) * 3)); - gpio[index] = (gpio[index] & mask) | ((mode & 0x7) << ((pin % 10) * 3)); -} - -//--------------------------------------------------------------------------- -// -// 繝斐Φ讖溯ス險ュ螳(繝励Ν繧「繝繝/繝繧ヲ繝ウ) -// -//--------------------------------------------------------------------------- -void FASTCALL GPIOBUS::PullConfig(int pin, int mode) -{ - // 譛ェ菴ソ逕ィ縺ェ繧臥┌蜉ケ - if (pin < 0) { - return; - } - - gpio[GPIO_PUD] = mode & 0x3; - usleep(1); - gpio[GPIO_CLK_0] = 0x1 << pin; - usleep(1); - gpio[GPIO_PUD] = 0; - gpio[GPIO_CLK_0] = 0; -} - -//--------------------------------------------------------------------------- -// -// Drive Strength險ュ螳 -// -//--------------------------------------------------------------------------- -void FASTCALL GPIOBUS::DrvConfig(DWORD drive) -{ - DWORD data; - - // 繧ォ繝シ繝阪Ν繝峨Λ繧、繝舌′縺ゅl縺ーIOCTL縺ァ萓晞シ縺吶k - if (drvfd >= 0) { - ioctl(drvfd, IOCTL_PADS, (DWORD)drive); - } else { - data = pads[PAD_0_27]; - pads[PAD_0_27] = (0xFFFFFFF8 & data) | drive | 0x5a000000; - } -} - -//--------------------------------------------------------------------------- -// -// 繝斐Φ蜃コ蜉幄ィュ螳 -// -//--------------------------------------------------------------------------- -void FASTCALL GPIOBUS::PinSetSignal(int pin, BOOL ast) -{ - // 譛ェ菴ソ逕ィ縺ェ繧臥┌蜉ケ - if (pin < 0) { - return; - } - - if (ast) { - gpio[GPIO_SET_0] = 0x1 << pin; - } else { - gpio[GPIO_CLR_0] = 0x1 << pin; - } -} - -//--------------------------------------------------------------------------- -// -// 繝ッ繝シ繧ッ繝繝シ繝悶Ν菴懈 -// -//--------------------------------------------------------------------------- -void FASTCALL GPIOBUS::MakeTable(void) -{ - const int pintbl[] = { - PIN_DT0, PIN_DT1, PIN_DT2, PIN_DT3, PIN_DT4, - PIN_DT5, PIN_DT6, PIN_DT7, PIN_DP - }; - - int i; - int j; - BOOL tblParity[256]; - DWORD bits; - DWORD parity; -#if SIGNAL_CONTROL_MODE == 0 - int index; - int shift; -#else - DWORD gpclr; - DWORD gpset; -#endif - - // 繝代Μ繝繧」繝繝シ繝悶Ν菴懈 - for (i = 0; i < 0x100; i++) { - bits = (DWORD)i; - parity = 0; - for (j = 0; j < 8; j++) { - parity ^= bits & 1; - bits >>= 1; - } - parity = ~parity; - tblParity[i] = parity & 1; - } - -#if SIGNAL_CONTROL_MODE == 0 - // 繝槭せ繧ッ縺ィ險ュ螳壹ョ繝シ繧ソ逕滓 - memset(tblDatMsk, 0xff, sizeof(tblDatMsk)); - memset(tblDatSet, 0x00, sizeof(tblDatSet)); - for (i = 0; i < 0x100; i++) { - // 讀懈渊逕ィ繝薙ャ繝亥 - bits = (DWORD)i; - - // 繝代Μ繝繧」蜿門セ - if (tblParity[i]) { - bits |= (1 << 8); - } - - // 繝薙ャ繝域、懈渊 - for (j = 0; j < 9; j++) { - // 繧、繝ウ繝繝繧ッ繧ケ縺ィ繧キ繝輔ヨ驥剰ィ育ョ - index = pintbl[j] / 10; - shift = (pintbl[j] % 10) * 3; - - // 繝槭せ繧ッ繝繝シ繧ソ - tblDatMsk[index][i] &= ~(0x7 << shift); - - // 險ュ螳壹ョ繝シ繧ソ - if (bits & 1) { - tblDatSet[index][i] |= (1 << shift); - } - - bits >>= 1; - } - } -#else - // 繝槭せ繧ッ縺ィ險ュ螳壹ョ繝シ繧ソ逕滓 - memset(tblDatMsk, 0x00, sizeof(tblDatMsk)); - memset(tblDatSet, 0x00, sizeof(tblDatSet)); - for (i = 0; i < 0x100; i++) { - // 讀懈渊逕ィ繝薙ャ繝亥 - bits = (DWORD)i; - - // 繝代Μ繝繧」蜿門セ - if (tblParity[i]) { - bits |= (1 << 8); - } - -#if SIGNAL_CONTROL_MODE == 1 - // 雋隲也炊縺ッ蜿崎サ「 - bits = ~bits; -#endif - - // GPIO繝ャ繧ク繧ケ繧ソ諠蝣ア縺ョ菴懈 - gpclr = 0; - gpset = 0; - for (j = 0; j < 9; j++) { - if (bits & 1) { - gpset |= (1 << pintbl[j]); - } else { - gpclr |= (1 << pintbl[j]); - } - bits >>= 1; - } - - tblDatMsk[i] = gpclr; - tblDatSet[i] = gpset; - } -#endif -} - //--------------------------------------------------------------------------- // // 蛻晄悄蛹 @@ -277,71 +144,104 @@ void FASTCALL GPIOBUS::MakeTable(void) //--------------------------------------------------------------------------- BOOL FASTCALL GPIOBUS::Init(mode_e mode) { - DWORD base; - DWORD addr; - int fd; void *map; int i; int j; int pullmode; +#ifndef BAREMETAL + int fd; +#ifdef USE_SEL_EVENT_ENABLE + struct epoll_event ev; +#endif // USE_SEL_EVENT_ENABLE +#endif // BAREMETAL // 蜍穂ス懊Δ繝シ繝峨ョ菫晏ュ actmode = mode; +#ifdef BAREMETAL // 繝吶シ繧ケ繧「繝峨Ξ繧ケ縺ョ蜿門セ - base = (DWORD)bcm_host_get_peripheral_address(); + baseaddr = RPi_IO_Base_Addr; + map = (void*)baseaddr; +#else + // 繝吶シ繧ケ繧「繝峨Ξ繧ケ縺ョ蜿門セ + baseaddr = (DWORD)bcm_host_get_peripheral_address(); - // 繧ォ繝シ繝阪Ν繝峨Λ繧、繝舌が繝シ繝励Φ - drvfd = open(DRIVER_PATH, O_RDWR); - if (drvfd >= 0) { - printf("Activated RaSCSI GPIO Driver.\n"); - ioctl(drvfd, IOCTL_INIT, base); - ioctl(drvfd, IOCTL_MODE, (DWORD)actmode); - } - - // /dev/mem,/dev/gpiomem縺ョ鬆縺ォ繧ェ繝シ繝励Φ繧定ゥヲ縺ソ繧 - addr = base + GPIO_OFFSET; + // /dev/mem繧ェ繝シ繝励Φ fd = open("/dev/mem", O_RDWR | O_SYNC); if (fd == -1) { - // /dev/gpiomem繧偵が繝シ繝励Φ - addr = 0; - fd = open("/dev/gpiomem", O_RDWR | O_SYNC); - if (fd == -1) { - return FALSE; - } + return FALSE; } - // GPIO縺ョI/O繝昴シ繝医r繝槭ャ繝励☆繧 - map = mmap(NULL, 164, - PROT_READ | PROT_WRITE, MAP_SHARED, fd, addr); + // 繝壹Μ繝輔ぉ繝ゥ繝ォ繝ェ繝シ繧ク繝ァ繝ウ縺ョ繝。繝「繝ェ繧偵槭ャ繝 + map = mmap(NULL, 0x1000100, + PROT_READ | PROT_WRITE, MAP_SHARED, fd, baseaddr); if (map == MAP_FAILED) { close(fd); return FALSE; } +#endif + // 繝吶シ繧ケ繧「繝峨Ξ繧ケ縺九i繝ゥ繧コ繝代う縺ョ繧ソ繧、繝励r豎コ螳 + if (baseaddr == 0xfe000000) { + rpitype = 4; + } else if (baseaddr == 0x3f000000) { + rpitype = 2; + } else { + rpitype = 1; + } - // GPIO縺ョI/O繝昴シ繝医い繝峨Ξ繧ケ遒コ菫 + // GPIO gpio = (DWORD *)map; + gpio += GPIO_OFFSET / sizeof(DWORD); level = &gpio[GPIO_LEV_0]; - // PADS縺ョ蜃ヲ逅縺ッ繧ォ繝シ繝阪Ν繝峨Λ繧、繝舌′辟。縺譎ゅ□縺(sudo縺悟ソ隕√→縺ェ繧) - if (drvfd < 0) { - // /dev/mem繧偵が繝シ繝励Φ - fd = open("/dev/mem", O_RDWR | O_SYNC); - if (fd == -1) { - return FALSE; - } + // PADS + pads = (DWORD *)map; + pads += PADS_OFFSET / sizeof(DWORD); - // PADS縺ョI/O繝昴シ繝医r繝槭ャ繝励☆繧 - map = mmap(NULL, 56, - PROT_READ | PROT_WRITE, MAP_SHARED, fd, base + PADS_OFFSET); - close(fd); - if (map == MAP_FAILED) { - return FALSE; - } + // 繧キ繧ケ繝繝繧ソ繧、繝 + SysTimer::Init( + (DWORD *)map + SYST_OFFSET / sizeof(DWORD), + (DWORD *)map + ARMT_OFFSET / sizeof(DWORD)); - // PADS縺ョI/O繝昴シ繝医い繝峨Ξ繧ケ遒コ菫 - pads = (DWORD *)map; + // 蜑イ繧願セシ縺ソ繧ウ繝ウ繝医Ο繝シ繝ゥ + irpctl = (DWORD *)map; + irpctl += IRPT_OFFSET / sizeof(DWORD); + +#ifndef BAREMETAL + // Quad-A7 control + qa7regs = (DWORD *)map; + qa7regs += QA7_OFFSET / sizeof(DWORD); +#endif // BAREMETAL + +#ifdef BAREMETAL + // GIC縺ョ繝。繝「繝ェ繧偵槭ャ繝 + if (rpitype == 4) { + map = (void*)ARM_GICD_BASE; + gicd = (DWORD *)map; + map = (void*)ARM_GICC_BASE; + gicc = (DWORD *)map; + } else { + gicd = NULL; + gicc = NULL; } +#else + // GIC縺ョ繝。繝「繝ェ繧偵槭ャ繝 + if (rpitype == 4) { + map = mmap(NULL, 8192, + PROT_READ | PROT_WRITE, MAP_SHARED, fd, ARM_GICD_BASE); + if (map == MAP_FAILED) { + close(fd); + return FALSE; + } + gicd = (DWORD *)map; + gicc = (DWORD *)map; + gicc += (ARM_GICC_BASE - ARM_GICD_BASE) / sizeof(DWORD); + } else { + gicd = NULL; + gicc = NULL; + } + close(fd); +#endif // BAREMETAL // Drive Strength繧16mA縺ォ險ュ螳 DrvConfig(7); @@ -373,8 +273,8 @@ BOOL FASTCALL GPIOBUS::Init(mode_e mode) PinConfig(PIN_IND, GPIO_OUTPUT); PinConfig(PIN_DTD, GPIO_OUTPUT); - // 譛牙柑菫。蜿キ繧定ィュ螳 - PinSetSignal(PIN_ENB, ENB_ON); + // ENABLE菫。蜿キ繧定ィュ螳 + PinSetSignal(PIN_ENB, ENB_OFF); PinConfig(PIN_ENB, GPIO_OUTPUT); // GPFSEL繝舌ャ繧ッ繧「繝繝 @@ -383,9 +283,98 @@ BOOL FASTCALL GPIOBUS::Init(mode_e mode) gpfsel[2] = gpio[GPIO_FSEL_2]; gpfsel[3] = gpio[GPIO_FSEL_3]; + // SEL菫。蜿キ蜑イ繧願セシ縺ソ蛻晄悄蛹 +#ifdef USE_SEL_EVENT_ENABLE +#ifndef BAREMETAL + // GPIO繝√ャ繝励が繝シ繝励Φ + fd = open("/dev/gpiochip0", 0); + if (fd == -1) { + return FALSE; + } + + // 繧、繝吶Φ繝郁ヲ∵アりィュ螳 + strcpy(selevreq.consumer_label, "RaSCSI"); + selevreq.lineoffset = PIN_SEL; + selevreq.handleflags = GPIOHANDLE_REQUEST_INPUT; +#if SIGNAL_CONTROL_MODE < 2 + selevreq.eventflags = GPIOEVENT_REQUEST_FALLING_EDGE; +#else + selevreq.eventflags = GPIOEVENT_REQUEST_RISING_EDGE; +#endif // SIGNAL_CONTROL_MODE + + // 繧、繝吶Φ繝郁ヲ∵アょ叙蠕 + if (ioctl(fd, GPIO_GET_LINEEVENT_IOCTL, &selevreq) == -1) { + close(fd); + return FALSE; + } + + // GPIO繝√ャ繝励け繝ュ繝シ繧コ + close(fd); + + // epoll蛻晄悄蛹 + epfd = epoll_create(1); + memset(&ev, 0, sizeof(ev)); + ev.events = EPOLLIN | EPOLLPRI; + ev.data.fd = selevreq.fd; + epoll_ctl(epfd, EPOLL_CTL_ADD, selevreq.fd, &ev); +#else + // 繧ィ繝繧ク讀懷コ險ュ螳 +#if SIGNAL_CONTROL_MODE == 2 + gpio[GPIO_AREN_0] = 1 << PIN_SEL; +#else + gpio[GPIO_AFEN_0] = 1 << PIN_SEL; +#endif // SIGNAL_CONTROL_MODE + + // 繧、繝吶Φ繝医け繝ェ繧「 + gpio[GPIO_EDS_0] = 1 << PIN_SEL; + + // 蜑イ繧願セシ縺ソ繝上Φ繝峨Λ逋サ骭イ + setIrqFuncAddress(IrqHandler); + + // GPIO蜑イ繧願セシ縺ソ險ュ螳 + if (rpitype == 4) { + // GIC辟。蜉ケ + gicd[GICD_CTLR] = 0; + + // 蜈ィ縺ヲ縺ョ蜑イ繧願セシ縺ソ繧偵さ繧「0縺ォ繝ォ繝シ繝繧」繝ウ繧ー + for (i = 0; i < 8; i++) { + gicd[GICD_ICENABLER0 + i] = 0xffffffff; + gicd[GICD_ICPENDR0 + i] = 0xffffffff; + gicd[GICD_ICACTIVER0 + i] = 0xffffffff; + } + for (i = 0; i < 64; i++) { + gicd[GICD_IPRIORITYR0 + i] = 0xa0a0a0a0; + gicd[GICD_ITARGETSR0 + i] = 0x01010101; + } + + // 蜈ィ縺ヲ縺ョ蜑イ繧願セシ縺ソ繧偵Ξ繝吶Ν繝医Μ繧ャ縺ォ險ュ螳 + for (i = 0; i < 16; i++) { + gicd[GICD_ICFGR0 + i] = 0; + } + + // GIC辟。蜉ケ + gicd[GICD_CTLR] = 1; + + // 繧ウ繧「0縺ョCPU繧、繝ウ繧ソ繝シ繝輔ぉ繧ケ繧呈怏蜉ケ縺ォ縺吶k + gicc[GICC_PMR] = 0xf0; + gicc[GICC_CTLR] = 1; + + // 蜑イ繧願セシ縺ソ譛牙柑 + gicd[GICD_ISENABLER0 + (GIC_GPIO_IRQ / 32)] = + 1 << (GIC_GPIO_IRQ % 32); + } else { + // 蜑イ繧願セシ縺ソ譛牙柑 + irpctl[IRPT_ENB_IRQ_2] = (1 << (GPIO_IRQ % 32)); + } +#endif // BAREMETAL +#endif // USE_SEL_EVENT_ENABLE + // 繝ッ繝シ繧ッ繝繝シ繝悶Ν菴懈 MakeTable(); + // 譛蠕後↓ENABLE繧偵が繝ウ + SetControl(PIN_ENB, ENB_ON); + return TRUE; } @@ -397,7 +386,14 @@ BOOL FASTCALL GPIOBUS::Init(mode_e mode) void FASTCALL GPIOBUS::Cleanup() { int i; - int j; + int pin; + + // SEL菫。蜿キ蜑イ繧願セシ縺ソ隗」謾セ +#ifdef USE_SEL_EVENT_ENABLE +#ifndef BAREMETAL + close(selevreq.fd); +#endif // BAREMETAL +#endif // USE_SEL_EVENT_ENABLE // 蛻カ蠕。菫。蜿キ繧定ィュ螳 PinSetSignal(PIN_ENB, FALSE); @@ -412,119 +408,14 @@ void FASTCALL GPIOBUS::Cleanup() // 蜈ィ菫。蜿キ蛻晄悄蛹 for (i = 0; SignalTable[i] >= 0; i++) { - j = SignalTable[i]; - PinSetSignal(j, FALSE); - PinConfig(j, GPIO_INPUT); - PullConfig(j, GPIO_PULLNONE); + pin = SignalTable[i]; + PinSetSignal(pin, FALSE); + PinConfig(pin, GPIO_INPUT); + PullConfig(pin, GPIO_PULLNONE); } // Drive Strength繧8mA縺ォ險ュ螳 DrvConfig(3); - - // 繧ォ繝シ繝阪Ν繝峨Λ繧、繝 - if (drvfd >= 0) { - close(drvfd); - drvfd = -1; - } -} - -//--------------------------------------------------------------------------- -// -// 蛻カ蠕。菫。蜿キ險ュ螳 -// -//--------------------------------------------------------------------------- -void FASTCALL GPIOBUS::SetControl(int pin, BOOL ast) -{ - PinSetSignal(pin, ast); -} - -//--------------------------------------------------------------------------- -// -// 蜈・蜃コ蜉帙Δ繝シ繝芽ィュ螳 -// -//--------------------------------------------------------------------------- -void FASTCALL GPIOBUS::SetMode(int pin, int mode) -{ - int index; - int shift; - DWORD data; - -#if SIGNAL_CONTROL_MODE == 0 - if (mode == OUT) { - return; - } -#endif - - index = pin / 10; - shift = (pin % 10) * 3; - data = gpfsel[index]; - data &= ~(0x7 << shift); - if (mode == OUT) { - data |= (1 << shift); - } - gpio[index] = data; - gpfsel[index] = data; -} - -//--------------------------------------------------------------------------- -// -// 蜈・蜉帑ソ。蜿キ蛟、蜿門セ -// -//--------------------------------------------------------------------------- -BOOL FASTCALL GPIOBUS::GetSignal(int pin) -{ - return (signals >> pin) & 1; -} - -//--------------------------------------------------------------------------- -// -// 蜃コ蜉帑ソ。蜿キ蛟、險ュ螳 -// -//--------------------------------------------------------------------------- -void FASTCALL GPIOBUS::SetSignal(int pin, BOOL ast) -{ -#if SIGNAL_CONTROL_MODE == 0 - int index; - int shift; - DWORD data; - - index = pin / 10; - shift = (pin % 10) * 3; - data = gpfsel[index]; - data &= ~(0x7 << shift); - if (ast) { - data |= (1 << shift); - } - gpio[index] = data; - gpfsel[index] = data; -#elif SIGNAL_CONTROL_MODE == 1 - if (ast) { - gpio[GPIO_CLR_0] = 0x1 << pin; - } else { - gpio[GPIO_SET_0] = 0x1 << pin; - } -#elif SIGNAL_CONTROL_MODE == 2 - if (ast) { - gpio[GPIO_SET_0] = 0x1 << pin; - } else { - gpio[GPIO_CLR_0] = 0x1 << pin; - } -#endif -} - -//--------------------------------------------------------------------------- -// -// 繝翫ヮ遘貞腰菴阪ョ繧ケ繝ェ繝シ繝 -// -//--------------------------------------------------------------------------- -void FASTCALL GPIOBUS::SleepNsec(DWORD nsec) -{ - DWORD count; - - count = (nsec + 8 - 1) / 8; - while (count--) { - gpio[GPIO_PUD] = 0; - } } //--------------------------------------------------------------------------- @@ -626,11 +517,21 @@ DWORD FASTCALL GPIOBUS::Aquire() #if SIGNAL_CONTROL_MODE < 2 // 雋隲也炊縺ェ繧牙渚霆「縺吶k(蜀驛ィ蜃ヲ逅縺ッ豁」隲也炊縺ォ邨ア荳) signals = ~signals; -#endif +#endif // SIGNAL_CONTROL_MODE return signals; } +//--------------------------------------------------------------------------- +// +// ENB繧キ繧ー繝翫Ν險ュ螳 +// +//--------------------------------------------------------------------------- +void FASTCALL GPIOBUS::SetENB(BOOL ast) +{ + PinSetSignal(PIN_ENB, ast ? ENB_ON : ENB_OFF); +} + //--------------------------------------------------------------------------- // // BSY繧キ繧ー繝翫Ν蜿門セ @@ -648,6 +549,9 @@ BOOL FASTCALL GPIOBUS::GetBSY() //--------------------------------------------------------------------------- void FASTCALL GPIOBUS::SetBSY(BOOL ast) { + // BSY菫。蜿キ繧定ィュ螳 + SetSignal(PIN_BSY, ast); + if (actmode == TARGET) { if (ast) { // 繧「繧ッ繝繧」繝紋ソ。蜿キ繧偵が繝ウ @@ -655,27 +559,26 @@ void FASTCALL GPIOBUS::SetBSY(BOOL ast) // 繧ソ繝シ繧イ繝繝井ソ。蜿キ繧貞コ蜉帙↓險ュ螳 SetControl(PIN_TAD, TAD_OUT); + SetMode(PIN_BSY, OUT); SetMode(PIN_MSG, OUT); SetMode(PIN_CD, OUT); SetMode(PIN_REQ, OUT); SetMode(PIN_IO, OUT); } else { + // 繧「繧ッ繝繧」繝紋ソ。蜿キ繧偵が繝 + SetControl(PIN_ACT, ACT_OFF); + // 繧ソ繝シ繧イ繝繝井ソ。蜿キ繧貞・蜉帙↓險ュ螳 SetControl(PIN_TAD, TAD_IN); + SetMode(PIN_BSY, IN); SetMode(PIN_MSG, IN); SetMode(PIN_CD, IN); SetMode(PIN_REQ, IN); SetMode(PIN_IO, IN); - - // 繧「繧ッ繝繧」繝紋ソ。蜿キ繧偵が繝 - SetControl(PIN_ACT, ACT_OFF); } } - - // BSY菫。蜿キ繧定ィュ螳 - SetSignal(PIN_BSY, ast); } //--------------------------------------------------------------------------- @@ -857,6 +760,7 @@ void FASTCALL GPIOBUS::SetIO(BOOL ast) // IO菫。蜿キ縺ォ繧医▲縺ヲ繝繝シ繧ソ縺ョ蜈・蜃コ蜉帶婿蜷代r螟画峩 if (ast) { SetControl(PIN_DTD, DTD_OUT); + SetDAT(0); SetMode(PIN_DT0, OUT); SetMode(PIN_DT1, OUT); SetMode(PIN_DT2, OUT); @@ -933,21 +837,146 @@ void FASTCALL GPIOBUS::SetDAT(BYTE dat) { // 繝昴シ繝医∈譖ク縺崎セシ縺ソ #if SIGNAL_CONTROL_MODE == 0 - gpfsel[0] &= tblDatMsk[0][dat]; - gpfsel[0] |= tblDatSet[0][dat]; - gpio[GPIO_FSEL_0] = gpfsel[0]; + DWORD fsel; - gpfsel[1] &= tblDatMsk[1][dat]; - gpfsel[1] |= tblDatSet[1][dat]; - gpio[GPIO_FSEL_1] = gpfsel[1]; + fsel = gpfsel[0]; + fsel &= tblDatMsk[0][dat]; + fsel |= tblDatSet[0][dat]; + if (fsel != gpfsel[0]) { + gpfsel[0] = fsel; + gpio[GPIO_FSEL_0] = fsel; + } - gpfsel[2] &= tblDatMsk[2][dat]; - gpfsel[2] |= tblDatSet[2][dat]; - gpio[GPIO_FSEL_2] = gpfsel[2]; + fsel = gpfsel[1]; + fsel &= tblDatMsk[1][dat]; + fsel |= tblDatSet[1][dat]; + if (fsel != gpfsel[1]) { + gpfsel[1] = fsel; + gpio[GPIO_FSEL_1] = fsel; + } + + fsel = gpfsel[2]; + fsel &= tblDatMsk[2][dat]; + fsel |= tblDatSet[2][dat]; + if (fsel != gpfsel[2]) { + gpfsel[2] = fsel; + gpio[GPIO_FSEL_2] = fsel; + } #else gpio[GPIO_CLR_0] = tblDatMsk[dat]; gpio[GPIO_SET_0] = tblDatSet[dat]; -#endif +#endif // SIGNAL_CONTROL_MODE +} + +//--------------------------------------------------------------------------- +// +// 繝繝シ繧ソ繝代Μ繝繧」繧キ繧ー繝翫Ν蜿門セ +// +//--------------------------------------------------------------------------- +BOOL FASTCALL GPIOBUS::GetDP() +{ + return GetSignal(PIN_DP); +} + +//--------------------------------------------------------------------------- +// +// 繧ウ繝槭Φ繝牙女菫。繝上Φ繝峨す繧ァ繧、繧ッ +// +//--------------------------------------------------------------------------- +int FASTCALL GPIOBUS::CommandHandShake(BYTE *buf) +{ + int i; + BOOL ret; + int count; + + // 繧ソ繝シ繧イ繝繝医Δ繝シ繝峨ョ縺ソ + if (actmode != TARGET) { + return 0; + } + + // IRQ辟。蜉ケ + DisableIRQ(); + + // 譛蛻昴ョ繧ウ繝槭Φ繝峨ヰ繧、繝医r蜿門セ + i = 0; + + // REQ繧「繧オ繝シ繝 + SetSignal(PIN_REQ, ON); + + // ACK繧「繧オ繝シ繝亥セ縺。 + ret = WaitSignal(PIN_ACK, TRUE); + + // 菫。蜿キ邱壹′螳牙ョ壹☆繧九∪縺ァ繧ヲ繧ァ繧、繝 + SysTimer::SleepNsec(GPIO_DATA_SETTLING); + + // 繝繝シ繧ソ蜿門セ + *buf = GetDAT(); + + // REQ繝阪ご繝シ繝 + SetSignal(PIN_REQ, OFF); + + // ACK繧「繧オ繝シ繝亥セ縺。縺ァ繧ソ繧、繝繧「繧ヲ繝 + if (!ret) { + goto irq_enable_exit; + } + + // ACK繝阪ご繝シ繝亥セ縺。 + ret = WaitSignal(PIN_ACK, FALSE); + + // ACK繝阪ご繝シ繝亥セ縺。縺ァ繧ソ繧、繝繧「繧ヲ繝 + if (!ret) { + goto irq_enable_exit; + } + + // 繧ウ繝槭Φ繝峨′6繝舌う繝医°10繝舌う繝医°隕句縺代k + if (*buf >= 0x20 && *buf <= 0x7D) { + count = 10; + } else { + count = 6; + } + + // 谺。繝繝シ繧ソ縺ク + buf++; + + for (i = 1; i < count; i++) { + // REQ繧「繧オ繝シ繝 + SetSignal(PIN_REQ, ON); + + // ACK繧「繧オ繝シ繝亥セ縺。 + ret = WaitSignal(PIN_ACK, TRUE); + + // 菫。蜿キ邱壹′螳牙ョ壹☆繧九∪縺ァ繧ヲ繧ァ繧、繝 + SysTimer::SleepNsec(GPIO_DATA_SETTLING); + + // 繝繝シ繧ソ蜿門セ + *buf = GetDAT(); + + // REQ繝阪ご繝シ繝 + SetSignal(PIN_REQ, OFF); + + // ACK繧「繧オ繝シ繝亥セ縺。縺ァ繧ソ繧、繝繧「繧ヲ繝 + if (!ret) { + break; + } + + // ACK繝阪ご繝シ繝亥セ縺。 + ret = WaitSignal(PIN_ACK, FALSE); + + // ACK繝阪ご繝シ繝亥セ縺。縺ァ繧ソ繧、繝繧「繧ヲ繝 + if (!ret) { + break; + } + + // 谺。繝繝シ繧ソ縺ク + buf++; + } + +irq_enable_exit: + // IRQ譛牙柑 + EnableIRQ(); + + // 蜿嶺ソ。謨ー繧定ソ泌唆 + return i; } //--------------------------------------------------------------------------- @@ -958,103 +987,98 @@ void FASTCALL GPIOBUS::SetDAT(BYTE dat) int FASTCALL GPIOBUS::ReceiveHandShake(BYTE *buf, int count) { int i; - DWORD loop; + BOOL ret; DWORD phase; - if (drvfd >= 0) { - return read(drvfd, buf, count); + // IRQ辟。蜉ケ + DisableIRQ(); + + if (actmode == TARGET) { + for (i = 0; i < count; i++) { + // REQ繧「繧オ繝シ繝 + SetSignal(PIN_REQ, ON); + + // ACK繧「繧オ繝シ繝亥セ縺。 + ret = WaitSignal(PIN_ACK, TRUE); + + // 菫。蜿キ邱壹′螳牙ョ壹☆繧九∪縺ァ繧ヲ繧ァ繧、繝 + SysTimer::SleepNsec(GPIO_DATA_SETTLING); + + // 繝繝シ繧ソ蜿門セ + *buf = GetDAT(); + + // REQ繝阪ご繝シ繝 + SetSignal(PIN_REQ, OFF); + + // ACK繧「繧オ繝シ繝亥セ縺。縺ァ繧ソ繧、繝繧「繧ヲ繝 + if (!ret) { + break; + } + + // ACK繝阪ご繝シ繝亥セ縺。 + ret = WaitSignal(PIN_ACK, FALSE); + + // ACK繝阪ご繝シ繝亥セ縺。縺ァ繧ソ繧、繝繧「繧ヲ繝 + if (!ret) { + break; + } + + // 谺。繝繝シ繧ソ縺ク + buf++; + } } else { - if (actmode == TARGET) { - for (i = 0; i < count; i++) { - // REQ繧「繧オ繝シ繝 - SetSignal(PIN_REQ, ON); + // 繝輔ぉ繝シ繧コ蜿門セ + phase = Aquire() & GPIO_MCI; - // ACK繧「繧オ繝シ繝亥セ縺。 - loop = 30000000; - do { - Aquire(); - loop--; - } while (!(signals & (1 << PIN_ACK)) && - !(signals & (1 << PIN_RST)) && loop > 0); + for (i = 0; i < count; i++) { + // REQ繧「繧オ繝シ繝亥セ縺。 + ret = WaitSignal(PIN_REQ, TRUE); - // 繝繝シ繧ソ蜿門セ - *buf = GetDAT(); - - // REQ繝阪ご繝シ繝 - SetSignal(PIN_REQ, OFF); - - // ACK繧「繧オ繝シ繝亥セ縺。縺ァ繧ソ繧、繝繧「繧ヲ繝 - if (loop == 0 || (signals & (1 << PIN_RST))) { - break; - } - - // ACK繝阪ご繝シ繝亥セ縺。 - loop = 30000000; - do { - Aquire(); - loop--; - } while ((signals & (1 << PIN_ACK)) && - !(signals & (1 << PIN_RST)) && loop > 0); - - // ACK繝阪ご繝シ繝亥セ縺。縺ァ繧ソ繧、繝繧「繧ヲ繝 - if (loop == 0 || (signals & (1 << PIN_RST))) { - break; - } - - // 谺。繝繝シ繧ソ縺ク - buf++; + // REQ繧「繧オ繝シ繝亥セ縺。縺ァ繧ソ繧、繝繧「繧ヲ繝 + if (!ret) { + break; } - // 蜿嶺ソ。謨ー繧定ソ泌唆 - return i; - } else { - // 繝輔ぉ繝シ繧コ蜿門セ - phase = signals & GPIO_MCI; - - for (i = 0; i < count; i++) { - // REQ繧「繧オ繝シ繝亥セ縺。 - loop = 30000000; - do { - Aquire(); - loop--; - } while (!(signals & (1 << PIN_REQ)) && - ((signals & GPIO_MCI) == phase) && loop > 0); - - // REQ繧「繧オ繝シ繝亥セ縺。縺ァ繧ソ繧、繝繧「繧ヲ繝 - if (loop == 0 || (signals & GPIO_MCI) != phase) { - break; - } - - // 繝繝シ繧ソ蜿門セ - *buf = GetDAT(); - - // ACK繧「繧オ繝シ繝 - SetSignal(PIN_ACK, ON); - - // REQ繝阪ご繝シ繝亥セ縺。 - loop = 30000000; - do { - Aquire(); - loop--; - } while ((signals & (1 << PIN_REQ)) && - ((signals & GPIO_MCI) == phase) && loop > 0); - - // ACK繝阪ご繝シ繝 - SetSignal(PIN_ACK, OFF); - - // REQ繝阪ご繝シ繝亥セ縺。縺ァ繧ソ繧、繝繧「繧ヲ繝 - if (loop == 0 || (signals & GPIO_MCI) != phase) { - break; - } - - // 谺。繝繝シ繧ソ縺ク - buf++; + // 繝輔ぉ繝シ繧コ繧ィ繝ゥ繝シ + if ((signals & GPIO_MCI) != phase) { + break; } - // 蜿嶺ソ。謨ー繧定ソ泌唆 - return i; + // 菫。蜿キ邱壹′螳牙ョ壹☆繧九∪縺ァ繧ヲ繧ァ繧、繝 + SysTimer::SleepNsec(GPIO_DATA_SETTLING); + + // 繝繝シ繧ソ蜿門セ + *buf = GetDAT(); + + // ACK繧「繧オ繝シ繝 + SetSignal(PIN_ACK, ON); + + // REQ繝阪ご繝シ繝亥セ縺。 + ret = WaitSignal(PIN_REQ, FALSE); + + // ACK繝阪ご繝シ繝 + SetSignal(PIN_ACK, OFF); + + // REQ繝阪ご繝シ繝亥セ縺。縺ァ繧ソ繧、繝繧「繧ヲ繝 + if (!ret) { + break; + } + + // 繝輔ぉ繝シ繧コ繧ィ繝ゥ繝シ + if ((signals & GPIO_MCI) != phase) { + break; + } + + // 谺。繝繝シ繧ソ縺ク + buf++; } } + + // IRQ譛牙柑 + EnableIRQ(); + + // 蜿嶺ソ。謨ー繧定ソ泌唆 + return i; } //--------------------------------------------------------------------------- @@ -1065,119 +1089,160 @@ int FASTCALL GPIOBUS::ReceiveHandShake(BYTE *buf, int count) int FASTCALL GPIOBUS::SendHandShake(BYTE *buf, int count) { int i; - DWORD loop; + BOOL ret; DWORD phase; - if (drvfd >= 0) { - return write(drvfd, buf, count); - } else { - if (actmode == TARGET) { - for (i = 0; i < count; i++) { - // 繝繝シ繧ソ險ュ螳 - SetDAT(*buf); + // IRQ辟。蜉ケ + DisableIRQ(); - // 菫。蜿キ邱壹′螳牙ョ壹☆繧九∪縺ァ繧ヲ繧ァ繧、繝 - SleepNsec(150); - - // ACK繝阪ご繝シ繝亥セ縺。 - loop = (DWORD)30000000; - do { - Aquire(); - loop--; - } while ((signals & (1 << PIN_ACK)) && - !(signals & (1 << PIN_RST)) && loop > 0); - - // ACK繝阪ご繝シ繝亥セ縺。縺ァ繧ソ繧、繝繧「繧ヲ繝 - if (loop == 0 || (signals & (1 << PIN_RST))) { - break; - } - - // REQ繧「繧オ繝シ繝 - SetSignal(PIN_REQ, ON); - - // ACK繧「繧オ繝シ繝亥セ縺。 - loop = (DWORD)30000000; - do { - Aquire(); - loop--; - } while (!(signals & (1 << PIN_ACK)) && - !(signals & (1 << PIN_RST)) && loop > 0); - - // REQ繝阪ご繝シ繝 - SetSignal(PIN_REQ, OFF); - - // ACK繧「繧オ繝シ繝亥セ縺。縺ァ繧ソ繧、繝繧「繧ヲ繝 - if (loop == 0 || (signals & (1 << PIN_RST))) { - break; - } - - // 谺。繝繝シ繧ソ縺ク - buf++; - } + if (actmode == TARGET) { + for (i = 0; i < count; i++) { + // 繝繝シ繧ソ險ュ螳 + SetDAT(*buf); // ACK繝阪ご繝シ繝亥セ縺。 - loop = (DWORD)30000000; - do { - Aquire(); - loop--; - } while ((signals & (1 << PIN_ACK)) && - !(signals & (1 << PIN_RST)) && loop > 0); + ret = WaitSignal(PIN_ACK, FALSE); - // 騾∽ソ。謨ー繧定ソ泌唆 - return i; - } else { - // 繝輔ぉ繝シ繧コ蜿門セ - phase = signals & GPIO_MCI; - - for (i = 0; i < count; i++) { - // REQ繧「繧オ繝シ繝亥セ縺。 - loop = (DWORD)30000000; - do { - Aquire(); - loop--; - } while (!(signals & (1 << PIN_REQ)) && - ((signals & GPIO_MCI) == phase) && loop > 0); - - // REQ繧「繧オ繝シ繝亥セ縺。縺ァ繧ソ繧、繝繧「繧ヲ繝 - if (loop == 0 || (signals & GPIO_MCI) != phase) { - break; - } - - // 繝繝シ繧ソ險ュ螳 - SetDAT(*buf); - - // 菫。蜿キ邱壹′螳牙ョ壹☆繧九∪縺ァ繧ヲ繧ァ繧、繝 - SleepNsec(150); - - // ACK繧「繧オ繝シ繝 - SetSignal(PIN_ACK, ON); - - // REQ繝阪ご繝シ繝亥セ縺。 - loop = (DWORD)30000000; - do { - Aquire(); - loop--; - } while ((signals & (1 << PIN_REQ)) && - ((signals & GPIO_MCI) == phase) && loop > 0); - - // ACK繝阪ご繝シ繝 - SetSignal(PIN_ACK, OFF); - - // REQ繝阪ご繝シ繝亥セ縺。縺ァ繧ソ繧、繝繧「繧ヲ繝 - if (loop == 0 || (signals & GPIO_MCI) != phase) { - break; - } - - // 谺。繝繝シ繧ソ縺ク - buf++; + // ACK繝阪ご繝シ繝亥セ縺。縺ァ繧ソ繧、繝繧「繧ヲ繝 + if (!ret) { + break; } - // 騾∽ソ。謨ー繧定ソ泌唆 - return i; + // ACK繝阪ご繝シ繝亥セ縺。縺ァ譌「縺ォ繧ヲ繧ァ繧、繝医′蜈・縺」縺ヲ縺繧 + + // REQ繧「繧オ繝シ繝 + SetSignal(PIN_REQ, ON); + + // ACK繧「繧オ繝シ繝亥セ縺。 + ret = WaitSignal(PIN_ACK, TRUE); + + // REQ繝阪ご繝シ繝 + SetSignal(PIN_REQ, OFF); + + // ACK繧「繧オ繝シ繝亥セ縺。縺ァ繧ソ繧、繝繧「繧ヲ繝 + if (!ret) { + break; + } + + // 谺。繝繝シ繧ソ縺ク + buf++; + } + + // ACK繝阪ご繝シ繝亥セ縺。 + WaitSignal(PIN_ACK, FALSE); + } else { + // 繝輔ぉ繝シ繧コ蜿門セ + phase = Aquire() & GPIO_MCI; + + for (i = 0; i < count; i++) { + // 繝繝シ繧ソ險ュ螳 + SetDAT(*buf); + + // REQ繧「繧オ繝シ繝亥セ縺。 + ret = WaitSignal(PIN_REQ, TRUE); + + // REQ繧「繧オ繝シ繝亥セ縺。縺ァ繧ソ繧、繝繧「繧ヲ繝 + if (!ret) { + break; + } + + // 繝輔ぉ繝シ繧コ繧ィ繝ゥ繝シ + if ((signals & GPIO_MCI) != phase) { + break; + } + + // REQ繧「繧オ繝シ繝亥セ縺。縺ァ譌「縺ォ繧ヲ繧ァ繧、繝医′蜈・縺」縺ヲ縺繧 + + // ACK繧「繧オ繝シ繝 + SetSignal(PIN_ACK, ON); + + // REQ繝阪ご繝シ繝亥セ縺。 + ret = WaitSignal(PIN_REQ, FALSE); + + // ACK繝阪ご繝シ繝 + SetSignal(PIN_ACK, OFF); + + // REQ繝阪ご繝シ繝亥セ縺。縺ァ繧ソ繧、繝繧「繧ヲ繝 + if (!ret) { + break; + } + + // 繝輔ぉ繝シ繧コ繧ィ繝ゥ繝シ + if ((signals & GPIO_MCI) != phase) { + break; + } + + // 谺。繝繝シ繧ソ縺ク + buf++; } } + + // IRQ譛牙柑 + EnableIRQ(); + + // 騾∽ソ。謨ー繧定ソ泌唆 + return i; } +#ifdef USE_SEL_EVENT_ENABLE +//--------------------------------------------------------------------------- +// +// SEL菫。蜿キ繧、繝吶Φ繝医昴シ繝ェ繝ウ繧ー +// +//--------------------------------------------------------------------------- +int FASTCALL GPIOBUS::PollSelectEvent() +{ + // errno繧ッ繝ェ繧「 + errno = 0; + +#ifdef BAREMETAL + // 蜑イ繧願セシ縺ソ譛牙柑 + EnableInterrupts(); + + // 蜑イ繧願セシ縺ソ蠕縺。 + WaitForInterrupts(); + + // 蜑イ繧願セシ縺ソ辟。蜉ケ + DisableInterrupts(); +#else + struct epoll_event epev; + struct gpioevent_data gpev; + + if (epoll_wait(epfd, &epev, 1, -1) <= 0) { + return -1; + } + + read(selevreq.fd, &gpev, sizeof(gpev)); +#endif // BAREMETAL + + return 0; +} + +//--------------------------------------------------------------------------- +// +// SEL菫。蜿キ繧、繝吶Φ繝郁ァ」髯、 +// +//--------------------------------------------------------------------------- +void FASTCALL GPIOBUS::ClearSelectEvent() +{ +#ifdef BAREMETAL + DWORD irq; + + // 繧、繝吶Φ繝医け繝ェ繧「 + gpio[GPIO_EDS_0] = 1 << PIN_SEL; + + // GIC縺ク縺ョ蠢懃ュ + if (rpitype == 4) { + // IRQ逡ェ蜿キ + irq = gicc[GICC_IAR] & 0x3FF; + + // 蜑イ繧願セシ縺ソ蠢懃ュ + gicc[GICC_EOIR] = irq; + } +#endif // BAREMETAL +} +#endif // USE_SEL_EVENT_ENABLE + //--------------------------------------------------------------------------- // // 菫。蜿キ繝繝シ繝悶Ν @@ -1190,3 +1255,502 @@ const int GPIOBUS::SignalTable[19] = { PIN_BSY, PIN_MSG, PIN_CD, PIN_IO, PIN_REQ, -1 }; + +//--------------------------------------------------------------------------- +// +// 繝ッ繝シ繧ッ繝繝シ繝悶Ν菴懈 +// +//--------------------------------------------------------------------------- +void FASTCALL GPIOBUS::MakeTable(void) +{ + const int pintbl[] = { + PIN_DT0, PIN_DT1, PIN_DT2, PIN_DT3, PIN_DT4, + PIN_DT5, PIN_DT6, PIN_DT7, PIN_DP + }; + + int i; + int j; + BOOL tblParity[256]; + DWORD bits; + DWORD parity; +#if SIGNAL_CONTROL_MODE == 0 + int index; + int shift; +#else + DWORD gpclr; + DWORD gpset; +#endif + + // 繝代Μ繝繧」繝繝シ繝悶Ν菴懈 + for (i = 0; i < 0x100; i++) { + bits = (DWORD)i; + parity = 0; + for (j = 0; j < 8; j++) { + parity ^= bits & 1; + bits >>= 1; + } + parity = ~parity; + tblParity[i] = parity & 1; + } + +#if SIGNAL_CONTROL_MODE == 0 + // 繝槭せ繧ッ縺ィ險ュ螳壹ョ繝シ繧ソ逕滓 + memset(tblDatMsk, 0xff, sizeof(tblDatMsk)); + memset(tblDatSet, 0x00, sizeof(tblDatSet)); + for (i = 0; i < 0x100; i++) { + // 讀懈渊逕ィ繝薙ャ繝亥 + bits = (DWORD)i; + + // 繝代Μ繝繧」蜿門セ + if (tblParity[i]) { + bits |= (1 << 8); + } + + // 繝薙ャ繝域、懈渊 + for (j = 0; j < 9; j++) { + // 繧、繝ウ繝繝繧ッ繧ケ縺ィ繧キ繝輔ヨ驥剰ィ育ョ + index = pintbl[j] / 10; + shift = (pintbl[j] % 10) * 3; + + // 繝槭せ繧ッ繝繝シ繧ソ + tblDatMsk[index][i] &= ~(0x7 << shift); + + // 險ュ螳壹ョ繝シ繧ソ + if (bits & 1) { + tblDatSet[index][i] |= (1 << shift); + } + + bits >>= 1; + } + } +#else + // 繝槭せ繧ッ縺ィ險ュ螳壹ョ繝シ繧ソ逕滓 + memset(tblDatMsk, 0x00, sizeof(tblDatMsk)); + memset(tblDatSet, 0x00, sizeof(tblDatSet)); + for (i = 0; i < 0x100; i++) { + // 讀懈渊逕ィ繝薙ャ繝亥 + bits = (DWORD)i; + + // 繝代Μ繝繧」蜿門セ + if (tblParity[i]) { + bits |= (1 << 8); + } + +#if SIGNAL_CONTROL_MODE == 1 + // 雋隲也炊縺ッ蜿崎サ「 + bits = ~bits; +#endif + + // GPIO繝ャ繧ク繧ケ繧ソ諠蝣ア縺ョ菴懈 + gpclr = 0; + gpset = 0; + for (j = 0; j < 9; j++) { + if (bits & 1) { + gpset |= (1 << pintbl[j]); + } else { + gpclr |= (1 << pintbl[j]); + } + bits >>= 1; + } + + tblDatMsk[i] = gpclr; + tblDatSet[i] = gpset; + } +#endif +} + +//--------------------------------------------------------------------------- +// +// 蛻カ蠕。菫。蜿キ險ュ螳 +// +//--------------------------------------------------------------------------- +void FASTCALL GPIOBUS::SetControl(int pin, BOOL ast) +{ + PinSetSignal(pin, ast); +} + +//--------------------------------------------------------------------------- +// +// 蜈・蜃コ蜉帙Δ繝シ繝芽ィュ螳 +// +//--------------------------------------------------------------------------- +void FASTCALL GPIOBUS::SetMode(int pin, int mode) +{ + int index; + int shift; + DWORD data; + +#if SIGNAL_CONTROL_MODE == 0 + if (mode == OUT) { + return; + } +#endif // SIGNAL_CONTROL_MODE + + index = pin / 10; + shift = (pin % 10) * 3; + data = gpfsel[index]; + data &= ~(0x7 << shift); + if (mode == OUT) { + data |= (1 << shift); + } + gpio[index] = data; + gpfsel[index] = data; +} + +//--------------------------------------------------------------------------- +// +// 蜈・蜉帑ソ。蜿キ蛟、蜿門セ +// +//--------------------------------------------------------------------------- +BOOL FASTCALL GPIOBUS::GetSignal(int pin) +{ + return (signals >> pin) & 1; +} + +//--------------------------------------------------------------------------- +// +// 蜃コ蜉帑ソ。蜿キ蛟、險ュ螳 +// +//--------------------------------------------------------------------------- +void FASTCALL GPIOBUS::SetSignal(int pin, BOOL ast) +{ +#if SIGNAL_CONTROL_MODE == 0 + int index; + int shift; + DWORD data; + + index = pin / 10; + shift = (pin % 10) * 3; + data = gpfsel[index]; + if (ast) { + data |= (1 << shift); + } else { + data &= ~(0x7 << shift); + } + gpio[index] = data; + gpfsel[index] = data; +#elif SIGNAL_CONTROL_MODE == 1 + if (ast) { + gpio[GPIO_CLR_0] = 0x1 << pin; + } else { + gpio[GPIO_SET_0] = 0x1 << pin; + } +#elif SIGNAL_CONTROL_MODE == 2 + if (ast) { + gpio[GPIO_SET_0] = 0x1 << pin; + } else { + gpio[GPIO_CLR_0] = 0x1 << pin; + } +#endif // SIGNAL_CONTROL_MODE +} + +//--------------------------------------------------------------------------- +// +// 菫。蜿キ螟牙喧蠕縺。 +// +//--------------------------------------------------------------------------- +BOOL FASTCALL GPIOBUS::WaitSignal(int pin, BOOL ast) +{ + DWORD now; + DWORD timeout; + + // 迴セ蝨ィ + now = SysTimer::GetTimerLow(); + + // 繧ソ繧、繝繧「繧ヲ繝域凾髢(3000ms) + timeout = 3000 * 1000; + + // 螟牙喧縺励◆繧牙叉邨ゆコ + do { + // 繝ェ繧サ繝繝医r蜿嶺ソ。縺励◆繧牙叉邨ゆコ + Aquire(); + if (GetRST()) { + return FALSE; + } + + // 繧ィ繝繧ク繧呈、懷コ縺励◆繧 + if (((signals >> pin) ^ ~ast) & 1) { + return TRUE; + } + } while ((SysTimer::GetTimerLow() - now) < timeout); + + // 繧ソ繧、繝繧「繧ヲ繝 + return FALSE; +} + +//--------------------------------------------------------------------------- +// +// IRQ遖∵ュ「 +// +//--------------------------------------------------------------------------- +void FASTCALL GPIOBUS::DisableIRQ() +{ +#ifndef BAREMETAL + if (rpitype == 4) { + // RPI4縺ッGICC縺ァ蜑イ繧願セシ縺ソ遖∵ュ「縺ォ險ュ螳 + giccpmr = gicc[GICC_PMR]; + gicc[GICC_PMR] = 0; + } else if (rpitype == 2) { + // RPI2,3縺ッ繧ウ繧「繧ソ繧、繝槭シIRQ繧堤┌蜉ケ縺ォ縺吶k + tintcore = sched_getcpu() + QA7_CORE0_TINTC; + tintctl = qa7regs[tintcore]; + qa7regs[tintcore] = 0; + } else { + // 蜑イ繧願セシ縺ソ繧ウ繝ウ繝医Ο繝シ繝ゥ縺ァ繧キ繧ケ繝繝繧ソ繧、繝槭シ蜑イ繧願セシ縺ソ繧呈ュ「繧√k + irptenb = irpctl[IRPT_ENB_IRQ_1]; + irpctl[IRPT_DIS_IRQ_1] = irptenb & 0xf; + } +#endif // BAREMETAL +} + +//--------------------------------------------------------------------------- +// +// IRQ譛牙柑 +// +//--------------------------------------------------------------------------- +void FASTCALL GPIOBUS::EnableIRQ() +{ +#ifndef BAREMETAL + if (rpitype == 4) { + // RPI4縺ッGICC繧貞牡繧願セシ縺ソ險ア蜿ッ縺ォ險ュ螳 + gicc[GICC_PMR] = giccpmr; + } else if (rpitype == 2) { + // RPI2,3縺ッ繧ウ繧「繧ソ繧、繝槭シIRQ繧呈怏蜉ケ縺ォ謌サ縺 + qa7regs[tintcore] = tintctl; + } else { + // 蜑イ繧願セシ縺ソ繧ウ繝ウ繝医Ο繝シ繝ゥ縺ァ繧キ繧ケ繝繝繧ソ繧、繝槭シ蜑イ繧願セシ縺ソ繧貞埼幕 + irpctl[IRPT_ENB_IRQ_1] = irptenb & 0xf; + } +#endif // BAREMETAL +} + +//--------------------------------------------------------------------------- +// +// 繝斐Φ讖溯ス險ュ螳(蜈・蜃コ蜉幄ィュ螳) +// +//--------------------------------------------------------------------------- +void FASTCALL GPIOBUS::PinConfig(int pin, int mode) +{ + int index; + DWORD mask; + + // 譛ェ菴ソ逕ィ縺ェ繧臥┌蜉ケ + if (pin < 0) { + return; + } + + index = pin / 10; + mask = ~(0x7 << ((pin % 10) * 3)); + gpio[index] = (gpio[index] & mask) | ((mode & 0x7) << ((pin % 10) * 3)); +} + +//--------------------------------------------------------------------------- +// +// 繝斐Φ讖溯ス險ュ螳(繝励Ν繧「繝繝/繝繧ヲ繝ウ) +// +//--------------------------------------------------------------------------- +void FASTCALL GPIOBUS::PullConfig(int pin, int mode) +{ + int shift; + DWORD bits; + DWORD pull; + + // 譛ェ菴ソ逕ィ縺ェ繧臥┌蜉ケ + if (pin < 0) { + return; + } + + if (rpitype == 4) { + switch (mode) { + case GPIO_PULLNONE: + pull = 0; + break; + case GPIO_PULLUP: + pull = 1; + break; + case GPIO_PULLDOWN: + pull = 2; + break; + default: + return; + } + + pin &= 0x1f; + shift = (pin & 0xf) << 1; + bits = gpio[GPIO_PUPPDN0 + (pin >> 4)]; + bits &= ~(3 << shift); + bits |= (pull << shift); + gpio[GPIO_PUPPDN0 + (pin >> 4)] = bits; + } else { + pin &= 0x1f; + gpio[GPIO_PUD] = mode & 0x3; + SysTimer::SleepUsec(2); + gpio[GPIO_CLK_0] = 0x1 << pin; + SysTimer::SleepUsec(2); + gpio[GPIO_PUD] = 0; + gpio[GPIO_CLK_0] = 0; + } +} + +//--------------------------------------------------------------------------- +// +// 繝斐Φ蜃コ蜉幄ィュ螳 +// +//--------------------------------------------------------------------------- +void FASTCALL GPIOBUS::PinSetSignal(int pin, BOOL ast) +{ + // 譛ェ菴ソ逕ィ縺ェ繧臥┌蜉ケ + if (pin < 0) { + return; + } + + if (ast) { + gpio[GPIO_SET_0] = 0x1 << pin; + } else { + gpio[GPIO_CLR_0] = 0x1 << pin; + } +} + +//--------------------------------------------------------------------------- +// +// Drive Strength險ュ螳 +// +//--------------------------------------------------------------------------- +void FASTCALL GPIOBUS::DrvConfig(DWORD drive) +{ + DWORD data; + + data = pads[PAD_0_27]; + pads[PAD_0_27] = (0xFFFFFFF8 & data) | drive | 0x5a000000; +} + +//--------------------------------------------------------------------------- +// +// 繧キ繧ケ繝繝繧ソ繧、繝槭い繝峨Ξ繧ケ +// +//--------------------------------------------------------------------------- +volatile DWORD* SysTimer::systaddr; + +//--------------------------------------------------------------------------- +// +// ARM繧ソ繧、繝槭い繝峨Ξ繧ケ +// +//--------------------------------------------------------------------------- +volatile DWORD* SysTimer::armtaddr; + +//--------------------------------------------------------------------------- +// +// 繧ウ繧「蜻ィ豕「謨ー +// +//--------------------------------------------------------------------------- +volatile DWORD SysTimer::corefreq; + +//--------------------------------------------------------------------------- +// +// 繧キ繧ケ繝繝繧ソ繧、繝槫晄悄蛹 +// +//--------------------------------------------------------------------------- +void FASTCALL SysTimer::Init(DWORD *syst, DWORD *armt) +{ +#ifndef BAREMETAL + // RPI Mailbox property interface + // Get max clock rate + // Tag: 0x00030004 + // + // Request: Length: 4 + // Value: u32: clock id + // Response: Length: 8 + // Value: u32: clock id, u32: rate (in Hz) + // + // Clock id + // 0x000000004: CORE + DWORD maxclock[32] = { 32, 0, 0x00030004, 8, 0, 4, 0, 0 }; + int fd; +#endif // BAREMETAL + + // 繝吶シ繧ケ繧「繝峨Ξ繧ケ菫晏ュ + systaddr = syst; + armtaddr = armt; + + // ARM繧ソ繧、繝槭r繝輔Μ繝シ繝ゥ繝ウ繝「繝シ繝峨↓螟画峩 + armtaddr[ARMT_CTRL] = 0x00000282; + + // 繧ウ繧「蜻ィ豕「謨ー蜿門セ +#ifdef BAREMETAL + corefreq = RPi_Core_Freq / 1000000; +#else + corefreq = 0; + fd = open("/dev/vcio", O_RDONLY); + if (fd >= 0) { + ioctl(fd, _IOWR(100, 0, char *), maxclock); + corefreq = maxclock[6] / 1000000; + } + close(fd); +#endif // BAREMETAL +} + +//--------------------------------------------------------------------------- +// +// 繧キ繧ケ繝繝繧ソ繧、繝(LO)蜿門セ +// +//--------------------------------------------------------------------------- +DWORD FASTCALL SysTimer::GetTimerLow() { + return systaddr[SYST_CLO]; +} + +//--------------------------------------------------------------------------- +// +// 繧キ繧ケ繝繝繧ソ繧、繝(HI)蜿門セ +// +//--------------------------------------------------------------------------- +DWORD FASTCALL SysTimer::GetTimerHigh() { + return systaddr[SYST_CHI]; +} + +//--------------------------------------------------------------------------- +// +// 繝翫ヮ遘貞腰菴阪ョ繧ケ繝ェ繝シ繝 +// +//--------------------------------------------------------------------------- +void FASTCALL SysTimer::SleepNsec(DWORD nsec) +{ + DWORD diff; + DWORD start; + + // 繧ヲ繧ァ繧、繝医@縺ェ縺 + if (nsec == 0) { + return; + } + + // 繧ソ繧、繝槭シ蟾ョ繧堤ョ怜コ + diff = corefreq * nsec / 1000; + + // 蠕ョ蟆上↑繧牙セゥ蟶ー + if (diff == 0) { + return; + } + + // 髢句ァ + start = armtaddr[ARMT_FREERUN]; + + // 繧ォ繧ヲ繝ウ繝医が繝シ繝舌シ縺セ縺ァ繝ォ繝シ繝 + while ((armtaddr[ARMT_FREERUN] - start) < diff); +} + +//--------------------------------------------------------------------------- +// +// ホシ遘貞腰菴阪ョ繧ケ繝ェ繝シ繝 +// +//--------------------------------------------------------------------------- +void FASTCALL SysTimer::SleepUsec(DWORD usec) +{ + DWORD now; + + // 繧ヲ繧ァ繧、繝医@縺ェ縺 + if (usec == 0) { + return; + } + + now = GetTimerLow(); + while ((GetTimerLow() - now) < usec); +} diff --git a/src/raspberrypi/gpiobus.h b/src/raspberrypi/gpiobus.h index 82f556f6..f9b9db58 100644 --- a/src/raspberrypi/gpiobus.h +++ b/src/raspberrypi/gpiobus.h @@ -4,7 +4,7 @@ // for Raspberry Pi // // Powered by XM6 TypeG Technology. -// Copyright (C) 2016-2018 GIMONS +// Copyright (C) 2016-2020 GIMONS // [ GPIO-SCSI繝舌せ ] // //--------------------------------------------------------------------------- @@ -19,7 +19,7 @@ // 謗・邯壽婿豕募ョ夂セゥ縺ョ驕ク謚 // //--------------------------------------------------------------------------- -#define CONNECT_TYPE_STANDARD // 讓呎コ(SCSI隲也炊,讓呎コ悶ヴ繝ウ繧「繧オ繧、繝ウ) +//#define CONNECT_TYPE_STANDARD // 讓呎コ(SCSI隲也炊,讓呎コ悶ヴ繝ウ繧「繧オ繧、繝ウ) //#define CONNECT_TYPE_FULLSPEC // 繝輔Ν繧ケ繝壹ャ繧ッ(SCSI隲也炊,讓呎コ悶ヴ繝ウ繧「繧オ繧、繝ウ) //#define CONNECT_TYPE_AIBOM // AIBOM迚(豁」隲也炊,蝗コ譛峨ヴ繝ウ繧「繧オ繧、繝ウ) //#define CONNECT_TYPE_GAMERNIUM // GAMERnium.com迚(讓呎コ冶ォ也炊,蝗コ譛峨ヴ繝ウ繧「繧オ繧、繝ウ) @@ -281,8 +281,12 @@ // 螳壽焚螳」險(GPIO) // //--------------------------------------------------------------------------- -#define GPIO_OFFSET 0x200000 -#define PADS_OFFSET 0x100000 +#define SYST_OFFSET 0x00003000 +#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_OUTPUT 1 #define GPIO_PULLNONE 0 @@ -304,7 +308,40 @@ #define GPIO_AFEN_0 34 #define GPIO_PUD 37 #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 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) | \ (1 << PIN_SEL) | \ @@ -316,6 +353,39 @@ (1 << PIN_CD) | \ (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 DRIVER_PATH "/dev/" DEVICE_NAME -#define IOCTL_INIT 0x100 -#define IOCTL_MODE 0x101 -#define IOCTL_PADS 0x102 +#define GPIO_DATA_SETTLING 100 // 繝繝シ繧ソ繝舌せ縺悟ョ牙ョ壹☆繧区凾髢(ns) //--------------------------------------------------------------------------- // @@ -371,6 +437,9 @@ public: DWORD FASTCALL Aquire(); // 菫。蜿キ蜿悶j霎シ縺ソ + void FASTCALL SetENB(BOOL ast); + // ENB繧キ繧ー繝翫Ν險ュ螳 + BOOL FASTCALL GetBSY(); // BSY繧キ繧ー繝翫Ν蜿門セ void FASTCALL SetBSY(BOOL ast); @@ -420,24 +489,25 @@ public: // 繝繝シ繧ソ繧キ繧ー繝翫Ν蜿門セ void FASTCALL SetDAT(BYTE dat); // 繝繝シ繧ソ繧キ繧ー繝翫Ν險ュ螳 + BOOL FASTCALL GetDP(); + // 繝代Μ繝繧」繧キ繧ー繝翫Ν蜿門セ + int FASTCALL CommandHandShake(BYTE *buf); + // 繧ウ繝槭Φ繝牙女菫。繝上Φ繝峨す繧ァ繧、繧ッ int FASTCALL ReceiveHandShake(BYTE *buf, int count); // 繝繝シ繧ソ蜿嶺ソ。繝上Φ繝峨す繧ァ繧、繧ッ int FASTCALL SendHandShake(BYTE *buf, int count); // 繝繝シ繧ソ騾∽ソ。繝上Φ繝峨す繧ァ繧、繧ッ - // 繧ソ繧、繝樣未菫 - void FASTCALL SleepNsec(DWORD nsec); - // 繝翫ヮ遘貞腰菴阪ョ繧ケ繝ェ繝シ繝 +#ifdef USE_SEL_EVENT_ENABLE + // SEL菫。蜿キ蜑イ繧願セシ縺ソ髢「菫 + int FASTCALL PollSelectEvent(); + // SEL菫。蜿キ繧、繝吶Φ繝医昴シ繝ェ繝ウ繧ー + void FASTCALL ClearSelectEvent(); + // SEL菫。蜿キ繧、繝吶Φ繝医け繝ェ繧「 +#endif // USE_SEL_EVENT_ENABLE private: - void FASTCALL DrvConfig(DWORD drive); - // GPIO繝峨Λ繧、繝冶ス蜉幄ィュ螳 - void FASTCALL PinConfig(int pin, int mode); - // GPIO繝斐Φ讖溯ス險ュ螳(蜈・蜃コ蜉幄ィュ螳) - void FASTCALL PullConfig(int pin, int mode); - // GPIO繝斐Φ讖溯ス險ュ螳(繝励Ν繧「繝繝/繝繧ヲ繝ウ) - void FASTCALL PinSetSignal(int pin, BOOL ast); - // GPIO繝斐Φ蜃コ蜉帑ソ。蜿キ險ュ螳 + // SCSI蜈・蜃コ蜉帑ソ。蜿キ蛻カ蠕。 void FASTCALL MakeTable(); // 繝ッ繝シ繧ッ繝繝シ繝悶Ν菴懈 void FASTCALL SetControl(int pin, BOOL ast); @@ -448,19 +518,66 @@ private: // SCSI蜈・蜉帑ソ。蜿キ蛟、蜿門セ void FASTCALL SetSignal(int pin, BOOL ast); // 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; // 蜍穂ス懊Δ繝シ繝 + DWORD baseaddr; // 繝吶シ繧ケ繧「繝峨Ξ繧ケ + + int rpitype; + // 繝ゥ繧コ繝代う遞ョ蛻・ + volatile DWORD *gpio; // GPIO繝ャ繧ク繧ケ繧ソ volatile DWORD *pads; // PADS繝ャ繧ク繧ケ繧ソ 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 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 DWORD tblDatMsk[3][256]; // 繝繝シ繧ソ繝槭せ繧ッ逕ィ繝繝シ繝悶Ν @@ -471,9 +588,35 @@ private: DWORD tblDatSet[256]; // 繝繝シ繧ソ險ュ螳夂畑繝繝シ繝悶Ν #endif - int drvfd; // 繧ォ繝シ繝阪Ν繝峨Λ繧、繝舌ヵ繧。繧、繝ォ繝繧」繧ケ繧ッ繝励Μ繧ソ - 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 diff --git a/src/raspberrypi/kernelmodule/Makefile b/src/raspberrypi/kernelmodule/Makefile deleted file mode 100644 index 5ed61fdc..00000000 --- a/src/raspberrypi/kernelmodule/Makefile +++ /dev/null @@ -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 diff --git a/src/raspberrypi/kernelmodule/rascsidrv.c b/src/raspberrypi/kernelmodule/rascsidrv.c deleted file mode 100644 index 9dd239f9..00000000 --- a/src/raspberrypi/kernelmodule/rascsidrv.c +++ /dev/null @@ -1,1122 +0,0 @@ -//--------------------------------------------------------------------------- -// -// SCSI Target Emulator RaSCSI (*^..^*) -// for Raspberry Pi -// -// Powered by XM6 TypeG Technology. -// Copyright (C) 2016-2018 GIMONS -// [ GPIO繝峨Λ繧、繝 ] -// -//--------------------------------------------------------------------------- - -#include -#include -#include -#include -#include - -//--------------------------------------------------------------------------- -// -// 蝓コ譛ャ蝙句ョ夂セゥ -// -//--------------------------------------------------------------------------- -typedef unsigned char BYTE; -typedef unsigned short WORD; -typedef unsigned long DWORD; -typedef int BOOL; - -#if !defined(FALSE) -#define FALSE 0 -#endif - -#if !defined(TRUE) -#define TRUE 1 -#endif - -//--------------------------------------------------------------------------- -// -// 謗・邯壽婿豕募ョ夂セゥ縺ョ驕ク謚 -// -//--------------------------------------------------------------------------- -#define CONNECT_TYPE_STANDARD // 讓呎コ(SCSI隲也炊,讓呎コ悶ヴ繝ウ繧「繧オ繧、繝ウ) -//#define CONNECT_TYPE_FULLSPEC // 繝輔Ν繧ケ繝壹ャ繧ッ(SCSI隲也炊,讓呎コ悶ヴ繝ウ繧「繧オ繧、繝ウ) -//#define CONNECT_TYPE_AIBOM // AIBOM迚(豁」隲也炊,蝗コ譛峨ヴ繝ウ繧「繧オ繧、繝ウ) -//#define CONNECT_TYPE_GAMERNIUM // GAMERnium.com迚(讓呎コ冶ォ也炊,蝗コ譛峨ヴ繝ウ繧「繧オ繧、繝ウ) - -//--------------------------------------------------------------------------- -// -// 菫。蜿キ蛻カ蠕。隲也炊蜿翫ウ繝斐Φ繧「繧オ繧、繝ウ繧ォ繧ケ繧ソ繝槭う繧コ -// -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// -// SIGNAL_CONTROL_MODE:菫。蜿キ蛻カ蠕。繝「繝シ繝蛾∈謚 -// Version1.22縺九i菫。蜿キ蛻カ蠕。縺ョ隲也炊繧偵き繧ケ繧ソ繝槭う繧コ縺ァ縺阪∪縺吶 -// -// 0:SCSI隲也炊莉墓ァ -// 逶エ邨舌∪縺溘ッHP縺ォ蜈ャ髢九@縺74LS641-1遲峨r菴ソ逕ィ縺吶k螟画鋤蝓コ譚ソ -// 繧「繝シ繧オ繝シ繝:0V -// 繝阪ご繝シ繝 :繧ェ繝シ繝励Φ繧ウ繝ャ繧ッ繧ソ蜃コ蜉(繝舌せ縺九i蛻繧企屬縺) -// -// 1:雋隲也炊莉墓ァ(雋隲也炊->SCSI隲也炊縺ク縺ョ螟画鋤蝓コ譚ソ繧剃スソ逕ィ縺吶k蝣エ蜷) -// 迴セ譎らせ縺ァ縺薙ョ莉墓ァ倥↓繧医k螟画鋤蝓コ譚ソ縺ッ蟄伜惠縺励∪縺帙s -// 繧「繝シ繧オ繝シ繝:0V -> (CONVERT) -> 0V -// 繝阪ご繝シ繝 :3.3V -> (CONVERT) -> 繧ェ繝シ繝励Φ繧ウ繝ャ繧ッ繧ソ蜃コ蜉 -// -// 2:豁」隲也炊莉墓ァ(豁」隲也炊->SCSI隲也炊縺ク縺ョ螟画鋤蝓コ譚ソ繧剃スソ逕ィ縺吶k蝣エ蜷) -// RaSCSI Adapter Rev.C @132sync遲 -// -// 繧「繝シ繧オ繝シ繝:3.3V -> (CONVERT) -> 0V -// 繝阪ご繝シ繝 :0V -> (CONVERT) -> 繧ェ繝シ繝励Φ繧ウ繝ャ繧ッ繧ソ蜃コ蜉 -// -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// -// 蛻カ蠕。菫。蜿キ繝斐Φ繧「繧オ繧、繝ウ險ュ螳 -// 蛻カ蠕。菫。蜿キ縺ォ蟇セ縺吶kGPIO繝斐Φ縺ョ繝槭ャ繝斐Φ繧ー繝繝シ繝悶Ν縺ァ縺吶 -// -// 蛻カ蠕。菫。蜿キ -// PIN_ACT -// SCSI繧ウ繝槭Φ繝峨r蜃ヲ逅荳ュ縺ョ迥カ諷九r遉コ縺吩ソ。蜿キ縺ョ繝斐Φ逡ェ蜿キ縲 -// PIN_ENB -// 襍キ蜍輔°繧臥オゆコ縺ョ髢薙ョ譛牙柑菫。蜿キ繧堤、コ縺吩ソ。蜿キ縺ョ繝斐Φ逡ェ蜿キ縲 -// PIN_TAD -// 繧ソ繝シ繧イ繝繝井ソ。蜿キ(BSY,IO,CD,MSG,REG)縺ョ蜈・蜃コ蜉帶婿蜷代r遉コ縺吩ソ。蜿キ縺ョ繝斐Φ逡ェ蜿キ縲 -// PIN_IND -// 繧、繝九す繝シ繧ィ繝シ繧ソ菫。蜿キ(SEL,ATN,RST,ACK)縺ョ蜈・蜃コ蜉帶婿蜷代r遉コ縺吩ソ。蜿キ縺ョ繝斐Φ逡ェ蜿キ縲 -// PIN_DTD -// 繝繝シ繧ソ菫。蜿キ(DT0...DT7,DP)縺ョ蜈・蜃コ蜉帶婿蜷代r遉コ縺吩ソ。蜿キ縺ョ繝斐Φ逡ェ蜿キ縲 -// -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// -// 蛻カ蠕。菫。蜿キ蜃コ蜉幄ォ也炊 -// 0V:FALSE 3.3V:TRUE縺ァ謖螳壹@縺セ縺吶 -// -// ACT_ON -// PIN_ACT菫。蜿キ縺ョ隲也炊縺ァ縺吶 -// ENB_ON -// PIN_ENB菫。蜿キ縺ョ隲也炊縺ァ縺吶 -// TAD_IN -// PIN_TAD蜈・蜉帶婿蜷第凾縺ョ隲也炊縺ァ縺吶 -// IND_IN -// PIN_ENB蜈・蜉帶婿蜷第凾縺ョ隲也炊縺ァ縺吶 -// DTD_IN -// PIN_ENB蜈・蜉帶婿蜷第凾縺ョ隲也炊縺ァ縺吶 -// -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// -// SCSI菫。蜿キ繝斐Φ繧「繧オ繧、繝ウ險ュ螳 -// SCSI縺ョ菫。蜿キ縺ォ蟇セ縺吶kGPIO繝斐Φ縺ョ繝槭ャ繝斐Φ繧ー繝繝シ繝悶Ν縺ァ縺吶 -// PIN_DT0ス霸IN_SEL -// -//--------------------------------------------------------------------------- - -#ifdef CONNECT_TYPE_STANDARD -// -// RaSCSI 讓呎コ(SCSI隲也炊,讓呎コ悶ヴ繝ウ繧「繧オ繧、繝ウ) -// -#define CONNECT_DESC "STANDARD" // 襍キ蜍墓凾繝。繝繧サ繝シ繧ク - -// 菫。蜿キ蛻カ蠕。繝「繝シ繝蛾∈謚 -#define SIGNAL_CONTROL_MODE 0 // SCSI隲也炊莉墓ァ - -// 蛻カ蠕。菫。蜿キ繝斐Φ繧「繧オ繧、繝ウ(-1縺ョ蝣エ蜷医ッ蛻カ蠕。辟。縺) -#define PIN_ACT 4 // ACTIVE -#define PIN_ENB 5 // ENABLE -#define PIN_IND -1 // INITIATOR CTRL DIRECTION -#define PIN_TAD -1 // TARGET CTRL DIRECTION -#define PIN_DTD -1 // DATA DIRECTION - -// 蛻カ蠕。菫。蜿キ蜃コ蜉幄ォ也炊 -#define ACT_ON TRUE // ACTIVE SIGNAL ON -#define ENB_ON TRUE // ENABLE SIGNAL ON -#define IND_IN FALSE // INITIATOR SIGNAL INPUT -#define TAD_IN FALSE // TARGET SIGNAL INPUT -#define DTD_IN TRUE // DATA SIGNAL INPUT - -// SCSI菫。蜿キ繝斐Φ繧「繧オ繧、繝ウ -#define PIN_DT0 10 // 繝繝シ繧ソ0 -#define PIN_DT1 11 // 繝繝シ繧ソ1 -#define PIN_DT2 12 // 繝繝シ繧ソ2 -#define PIN_DT3 13 // 繝繝シ繧ソ3 -#define PIN_DT4 14 // 繝繝シ繧ソ4 -#define PIN_DT5 15 // 繝繝シ繧ソ5 -#define PIN_DT6 16 // 繝繝シ繧ソ6 -#define PIN_DT7 17 // 繝繝シ繧ソ7 -#define PIN_DP 18 // 繝代Μ繝繧」 -#define PIN_ATN 19 // ATN -#define PIN_RST 20 // RST -#define PIN_ACK 21 // ACK -#define PIN_REQ 22 // REQ -#define PIN_MSG 23 // MSG -#define PIN_CD 24 // CD -#define PIN_IO 25 // IO -#define PIN_BSY 26 // BSY -#define PIN_SEL 27 // SEL -#endif - -#ifdef CONNECT_TYPE_FULLSPEC -// -// RaSCSI 讓呎コ(SCSI隲也炊,讓呎コ悶ヴ繝ウ繧「繧オ繧、繝ウ) -// -#define CONNECT_DESC "FULLSPEC" // 襍キ蜍墓凾繝。繝繧サ繝シ繧ク - -// 菫。蜿キ蛻カ蠕。繝「繝シ繝蛾∈謚 -#define SIGNAL_CONTROL_MODE 0 // SCSI隲也炊莉墓ァ - -// 蛻カ蠕。菫。蜿キ繝斐Φ繧「繧オ繧、繝ウ(-1縺ョ蝣エ蜷医ッ蛻カ蠕。辟。縺) -#define PIN_ACT 4 // ACTIVE -#define PIN_ENB 5 // ENABLE -#define PIN_IND 6 // INITIATOR CTRL DIRECTION -#define PIN_TAD 7 // TARGET CTRL DIRECTION -#define PIN_DTD 8 // DATA DIRECTION - -// 蛻カ蠕。菫。蜿キ蜃コ蜉幄ォ也炊 -#define ACT_ON TRUE // ACTIVE SIGNAL ON -#define ENB_ON TRUE // ENABLE SIGNAL ON -#define IND_IN FALSE // INITIATOR SIGNAL INPUT -#define TAD_IN FALSE // TARGET SIGNAL INPUT -#define DTD_IN TRUE // DATA SIGNAL INPUT - -// SCSI菫。蜿キ繝斐Φ繧「繧オ繧、繝ウ -#define PIN_DT0 10 // 繝繝シ繧ソ0 -#define PIN_DT1 11 // 繝繝シ繧ソ1 -#define PIN_DT2 12 // 繝繝シ繧ソ2 -#define PIN_DT3 13 // 繝繝シ繧ソ3 -#define PIN_DT4 14 // 繝繝シ繧ソ4 -#define PIN_DT5 15 // 繝繝シ繧ソ5 -#define PIN_DT6 16 // 繝繝シ繧ソ6 -#define PIN_DT7 17 // 繝繝シ繧ソ7 -#define PIN_DP 18 // 繝代Μ繝繧」 -#define PIN_ATN 19 // ATN -#define PIN_RST 20 // RST -#define PIN_ACK 21 // ACK -#define PIN_REQ 22 // REQ -#define PIN_MSG 23 // MSG -#define PIN_CD 24 // CD -#define PIN_IO 25 // IO -#define PIN_BSY 26 // BSY -#define PIN_SEL 27 // SEL -#endif - -#ifdef CONNECT_TYPE_AIBOM -// -// RaSCSI Adapter 縺ゅ>縺シ繧迚 -// - -#define CONNECT_DESC "AIBOM PRODUCTS version" // 襍キ蜍墓凾繝。繝繧サ繝シ繧ク - -// 菫。蜿キ蛻カ蠕。繝「繝シ繝蛾∈謚 -#define SIGNAL_CONTROL_MODE 2 // SCSI豁」隲也炊莉墓ァ - -// 蛻カ蠕。菫。蜿キ蜃コ蜉幄ォ也炊 -#define ACT_ON TRUE // ACTIVE SIGNAL ON -#define ENB_ON TRUE // ENABLE SIGNAL ON -#define IND_IN FALSE // INITIATOR SIGNAL INPUT -#define TAD_IN FALSE // TARGET SIGNAL INPUT -#define DTD_IN FALSE // DATA SIGNAL INPUT - -// 蛻カ蠕。菫。蜿キ繝斐Φ繧「繧オ繧、繝ウ(-1縺ョ蝣エ蜷医ッ蛻カ蠕。辟。縺) -#define PIN_ACT 4 // ACTIVE -#define PIN_ENB 17 // ENABLE -#define PIN_IND 27 // INITIATOR CTRL DIRECTION -#define PIN_TAD -1 // TARGET CTRL DIRECTION -#define PIN_DTD 18 // DATA DIRECTION - -// SCSI菫。蜿キ繝斐Φ繧「繧オ繧、繝ウ -#define PIN_DT0 6 // 繝繝シ繧ソ0 -#define PIN_DT1 12 // 繝繝シ繧ソ1 -#define PIN_DT2 13 // 繝繝シ繧ソ2 -#define PIN_DT3 16 // 繝繝シ繧ソ3 -#define PIN_DT4 19 // 繝繝シ繧ソ4 -#define PIN_DT5 20 // 繝繝シ繧ソ5 -#define PIN_DT6 26 // 繝繝シ繧ソ6 -#define PIN_DT7 21 // 繝繝シ繧ソ7 -#define PIN_DP 5 // 繝代Μ繝繧」 -#define PIN_ATN 22 // ATN -#define PIN_RST 25 // RST -#define PIN_ACK 10 // ACK -#define PIN_REQ 7 // REQ -#define PIN_MSG 9 // MSG -#define PIN_CD 11 // CD -#define PIN_IO 23 // IO -#define PIN_BSY 24 // BSY -#define PIN_SEL 8 // SEL -#endif - -#ifdef CONNECT_TYPE_GAMERNIUM -// -// RaSCSI Adapter GAMERnium.com迚 -// - -#define CONNECT_DESC "GAMERnium.com version"// 襍キ蜍墓凾繝。繝繧サ繝シ繧ク - -// 菫。蜿キ蛻カ蠕。繝「繝シ繝蛾∈謚 -#define SIGNAL_CONTROL_MODE 0 // SCSI隲也炊莉墓ァ - -// 蛻カ蠕。菫。蜿キ蜃コ蜉幄ォ也炊 -#define ACT_ON TRUE // ACTIVE SIGNAL ON -#define ENB_ON TRUE // ENABLE SIGNAL ON -#define IND_IN FALSE // INITIATOR SIGNAL INPUT -#define TAD_IN FALSE // TARGET SIGNAL INPUT -#define DTD_IN TRUE // DATA SIGNAL INPUT - -// 蛻カ蠕。菫。蜿キ繝斐Φ繧「繧オ繧、繝ウ(-1縺ョ蝣エ蜷医ッ蛻カ蠕。辟。縺) -#define PIN_ACT 14 // ACTIVE -#define PIN_ENB 6 // ENABLE -#define PIN_IND 7 // INITIATOR CTRL DIRECTION -#define PIN_TAD 8 // TARGET CTRL DIRECTION -#define PIN_DTD 5 // DATA DIRECTION - -// SCSI菫。蜿キ繝斐Φ繧「繧オ繧、繝ウ -#define PIN_DT0 21 // 繝繝シ繧ソ0 -#define PIN_DT1 26 // 繝繝シ繧ソ1 -#define PIN_DT2 20 // 繝繝シ繧ソ2 -#define PIN_DT3 19 // 繝繝シ繧ソ3 -#define PIN_DT4 16 // 繝繝シ繧ソ4 -#define PIN_DT5 13 // 繝繝シ繧ソ5 -#define PIN_DT6 12 // 繝繝シ繧ソ6 -#define PIN_DT7 11 // 繝繝シ繧ソ7 -#define PIN_DP 25 // 繝代Μ繝繧」 -#define PIN_ATN 10 // ATN -#define PIN_RST 22 // RST -#define PIN_ACK 24 // ACK -#define PIN_REQ 15 // REQ -#define PIN_MSG 17 // MSG -#define PIN_CD 18 // CD -#define PIN_IO 4 // IO -#define PIN_BSY 27 // BSY -#define PIN_SEL 23 // SEL -#endif - -//--------------------------------------------------------------------------- -// -// 螳壽焚螳」險(GPIO) -// -//--------------------------------------------------------------------------- -#define GPIO_OFFSET 0x200000 -#define PADS_OFFSET 0x100000 -#define GPIO_INPUT 0 -#define GPIO_OUTPUT 1 -#define GPIO_PULLNONE 0 -#define GPIO_PULLDOWN 1 -#define GPIO_PULLUP 2 -#define GPIO_FSEL_0 0 -#define GPIO_FSEL_1 1 -#define GPIO_FSEL_2 2 -#define GPIO_FSEL_3 3 -#define GPIO_SET_0 7 -#define GPIO_CLR_0 10 -#define GPIO_LEV_0 13 -#define GPIO_EDS_0 16 -#define GPIO_REN_0 19 -#define GPIO_FEN_0 22 -#define GPIO_HEN_0 25 -#define GPIO_LEN_0 28 -#define GPIO_AREN_0 31 -#define GPIO_AFEN_0 34 -#define GPIO_PUD 37 -#define GPIO_CLK_0 38 -#define PAD_0_27 11 - -#define GPIO_INEDGE ((1 << PIN_BSY) | \ - (1 << PIN_SEL) | \ - (1 << PIN_ATN) | \ - (1 << PIN_ACK) | \ - (1 << PIN_RST)) - -#define GPIO_MCI ((1 << PIN_MSG) | \ - (1 << PIN_CD) | \ - (1 << PIN_IO)) - -//--------------------------------------------------------------------------- -// -// 螳壽焚螳」險(蛻カ蠕。菫。蜿キ) -// -//--------------------------------------------------------------------------- -#define ACT_OFF !ACT_ON -#define ENB_OFF !ENB_ON -#define TAD_OUT !TAD_IN -#define IND_OUT !IND_IN -#define DTD_OUT !DTD_IN - -//--------------------------------------------------------------------------- -// -// 螳壽焚螳」險(SCSI) -// -//--------------------------------------------------------------------------- -#define IN GPIO_INPUT -#define OUT GPIO_OUTPUT -#define ON TRUE -#define OFF FALSE - -//--------------------------------------------------------------------------- -// -// 螳壽焚螳」險(繝峨Λ繧、繝) -// -//--------------------------------------------------------------------------- -#define DEVICE_NAME "rascsidrv" -#define DRIVER_PATH "/dev/" DEVICE_NAME -#define IOCTL_INIT 0x100 -#define IOCTL_MODE 0x101 -#define IOCTL_PADS 0x102 - -//--------------------------------------------------------------------------- -// -// 蜍穂ス懊Δ繝シ繝 -// -//--------------------------------------------------------------------------- -enum mode_e { - TARGET = 0, - INITIATOR = 1, - MONITOR = 2, -}; - -//--------------------------------------------------------------------------- -// -// 繝峨Λ繧、繝宣未謨ー螳」險 -// -//--------------------------------------------------------------------------- -static int drv_init(void); -static void drv_exit(void); - -//--------------------------------------------------------------------------- -// -// 繧ィ繝ウ繝医Μ繝昴う繝ウ繝亥ョ」險 -// -//--------------------------------------------------------------------------- -int drv_open(struct inode *inode, struct file *file); -int drv_close(struct inode *inode, struct file *file); -long drv_ioctl(struct file *file, unsigned int cmd, unsigned long arg); -ssize_t drv_read( - struct file *file, char __user *buf, size_t count, loff_t *fops); -ssize_t drv_write( - struct file *file, const char __user *buf, size_t count, loff_t *fops); -struct file_operations drv_fops = { - .open = drv_open, - .release = drv_close, - .unlocked_ioctl = drv_ioctl, - .read = drv_read, - .write = drv_write, -}; - -//--------------------------------------------------------------------------- -// -// 螟画焚螳」險(繝峨Λ繧、繝千匳骭イ) -// -//--------------------------------------------------------------------------- -static dev_t drv_dev; -static dev_t drv_devno; -static struct cdev drv_cdev; -static struct class *drv_class; - -//--------------------------------------------------------------------------- -// -// 螟画焚螳」險(GPIO蛻カ蠕。) -// -//--------------------------------------------------------------------------- -static DWORD baseaddr; // BASE繧「繝峨Ξ繧ケ -static volatile DWORD *gpio; // GPIO繝ャ繧ク繧ケ繧ソ -static volatile DWORD *level; // GPIO繝ャ繧ク繧ケ繧ソ(繝ャ繝吶Ν) -static volatile DWORD *pads; // PADS繝ャ繧ク繧ケ繧ソ - -#if SIGNAL_CONTROL_MODE == 0 -static DWORD gpfsel[4]; // FSEL繝舌ャ繧ッ繧「繝繝 -#endif - -//--------------------------------------------------------------------------- -// -// 螟画焚螳」險(SCSI蛻カ蠕。) -// -//--------------------------------------------------------------------------- -static enum mode_e actmode; // 蜍穂ス懊Δ繝シ繝 -static DWORD signals; // SCSI蜈ィ菫。蜿キ - -static BOOL tblParity[256]; -#if SIGNAL_CONTROL_MODE == 0 -static DWORD tblDatMsk[3][256]; // 繝繝シ繧ソ繝槭せ繧ッ逕ィ繝繝シ繝悶Ν -static DWORD tblDatSet[3][256]; // 繝繝シ繧ソ險ュ螳夂畑繝繝シ繝悶Ν -#else -static DWORD tblDatMsk[256]; // 繝繝シ繧ソ繝槭せ繧ッ逕ィ繝繝シ繝悶Ν -static DWORD tblDatSet[256]; // 繝繝シ繧ソ險ュ螳夂畑繝繝シ繝悶Ν -#endif - -//--------------------------------------------------------------------------- -// -// 繝ッ繝シ繧ッ繝繝シ繝悶Ν菴懈 -// -//--------------------------------------------------------------------------- -void MakeTable(void) -{ - const int pintbl[] = { - PIN_DT0, PIN_DT1, PIN_DT2, PIN_DT3, PIN_DT4, - PIN_DT5, PIN_DT6, PIN_DT7, PIN_DP - }; - - int i; - int j; - DWORD bits; - DWORD parity; -#if SIGNAL_CONTROL_MODE == 0 - int index; - int shift; -#else - DWORD gpclr; - DWORD gpset; -#endif - - // 繝代Μ繝繧」繝繝シ繝悶Ν菴懈 - for (i = 0; i < 0x100; i++) { - bits = (DWORD)i; - parity = 0; - for (j = 0; j < 8; j++) { - parity ^= bits & 1; - bits >>= 1; - } - parity = ~parity; - tblParity[i] = parity & 1; - } - -#if SIGNAL_CONTROL_MODE == 0 - // 繝槭せ繧ッ縺ィ險ュ螳壹ョ繝シ繧ソ逕滓 - memset(tblDatMsk, 0xff, sizeof(tblDatMsk)); - memset(tblDatSet, 0x00, sizeof(tblDatSet)); - for (i = 0; i < 0x100; i++) { - // 讀懈渊逕ィ繝薙ャ繝亥 - bits = (DWORD)i; - - // 繝代Μ繝繧」蜿門セ - if (tblParity[i]) { - bits |= (1 << 8); - } - - // 繝薙ャ繝域、懈渊 - for (j = 0; j < 9; j++) { - // 繧、繝ウ繝繝繧ッ繧ケ縺ィ繧キ繝輔ヨ驥剰ィ育ョ - index = pintbl[j] / 10; - shift = (pintbl[j] % 10) * 3; - - // 繝槭せ繧ッ繝繝シ繧ソ - tblDatMsk[index][i] &= ~(0x7 << shift); - - // 險ュ螳壹ョ繝シ繧ソ - if (bits & 1) { - tblDatSet[index][i] |= (1 << shift); - } - - bits >>= 1; - } - } -#else - // 繝槭せ繧ッ縺ィ險ュ螳壹ョ繝シ繧ソ逕滓 - memset(tblDatMsk, 0x00, sizeof(tblDatMsk)); - memset(tblDatSet, 0x00, sizeof(tblDatSet)); - for (i = 0; i < 0x100; i++) { - // 讀懈渊逕ィ繝薙ャ繝亥 - bits = (DWORD)i; - - // 繝代Μ繝繧」蜿門セ - if (tblParity[i]) { - bits |= (1 << 8); - } - -#if SIGNAL_CONTROL_MODE == 1 - // 雋隲也炊縺ッ蜿崎サ「 - bits = ~bits; -#endif - - // GPIO繝ャ繧ク繧ケ繧ソ諠蝣ア縺ョ菴懈 - gpclr = 0; - gpset = 0; - for (j = 0; j < 9; j++) { - if (bits & 1) { - gpset |= (1 << pintbl[j]); - } else { - gpclr |= (1 << pintbl[j]); - } - bits >>= 1; - } - - tblDatMsk[i] = gpclr; - tblDatSet[i] = gpset; - } -#endif -} - -//--------------------------------------------------------------------------- -// -// 繝峨Λ繧、繝仙晄悄蛹 -// -//--------------------------------------------------------------------------- -static int drv_init(void) -{ - printk(KERN_INFO "RaSCSI GPIO Driver Loaded(%s)\n", CONNECT_DESC); - - // 繝繝舌う繧ケ逡ェ蜿キ蜿門セ - if (alloc_chrdev_region( - &drv_dev, - 0, - 1, - DEVICE_NAME) < 0) { - printk(KERN_DEBUG "Failed to allocate region\n"); - goto init_error; - } - - // 繧ッ繝ゥ繧ケ逋サ骭イ - if ((drv_class = class_create( - THIS_MODULE, - DEVICE_NAME)) == NULL) { - printk(KERN_DEBUG "Failed to create class\n"); - goto init_error; - } - - // 繝繝舌う繧ケ蛻晄悄蛹 - cdev_init(&drv_cdev, &drv_fops); - drv_cdev.owner = THIS_MODULE; - if (cdev_add(&drv_cdev, drv_dev, 1) < 0) { - printk(KERN_ALERT "Failed to add device\n"); - goto init_error; - } - - // 繝繝舌う繧ケ菴懈 - drv_devno = MKDEV(MAJOR(drv_dev), MINOR(drv_dev)); - if (device_create( - drv_class, - NULL, - drv_devno, - NULL, - DEVICE_NAME) == NULL) { - printk(KERN_DEBUG "Failed to create device\n"); - goto init_error; - } - - // 繝ッ繝シ繧ッ繝繝シ繝悶Ν逕滓 - MakeTable(); - - // 繝ッ繝シ繧ッ繧ッ繝ェ繧「 - baseaddr = ~0; - gpio = NULL; - level = NULL; - pads = NULL; - - return 0; - -init_error: - drv_exit(); - return -1; -} - -//--------------------------------------------------------------------------- -// -// 繝峨Λ繧、繝占ァ」謾セ -// -//--------------------------------------------------------------------------- -static void drv_exit(void) -{ - // 繧ッ繝ゥ繧ケ逋サ骭イ隗」髯、 - if (drv_class) { - device_destroy(drv_class, drv_devno); - class_destroy(drv_class); - drv_class = NULL; - } - - // 繝繝舌う繧ケ逋サ骭イ隗」髯、 - if (drv_dev){ - unregister_chrdev_region(drv_dev, 1); - drv_dev = 0; - } - - printk(KERN_INFO "RaSCSI GPIO Driver Unloaded\n"); -} - -//--------------------------------------------------------------------------- -// -// 繧ェ繝シ繝励Φ -// -//--------------------------------------------------------------------------- -int drv_open(struct inode *inode, struct file *file) -{ - // 蜍穂ス懊Δ繝シ繝牙晄悄蛹 - actmode = TARGET; - - return 0; -} - -//--------------------------------------------------------------------------- -// -// 繧ッ繝ュ繝シ繧コ -// -//--------------------------------------------------------------------------- -int drv_close(struct inode *inode, struct file *file) -{ - // 繧「繝ウ繝槭ャ繝 - if (gpio) { - iounmap(gpio); - gpio = NULL; - } - - if (pads) { - iounmap(pads); - pads = NULL; - } - - // 繝吶シ繧ケ繧「繝峨Ξ繧ケ繧ッ繝ェ繧「 - baseaddr = ~0; - - return 0; -} - -//--------------------------------------------------------------------------- -// -// 繝峨Λ繧、繝 IOCTL -// -//--------------------------------------------------------------------------- -long drv_ioctl( - struct file *file, unsigned int cmd, unsigned long arg) -{ - DWORD data; - DWORD drive; - - switch (cmd) { - case IOCTL_INIT: - // 蛻晄悄蛹悶ッ繧ェ繝シ繝励Φ蠕後↓1蝗樣剞繧 - if (baseaddr != ~0) { - break; - } - - // 繝吶シ繧ケ繧「繝峨Ξ繧ケ - baseaddr = arg; - - // GPIO繝ャ繧ク繧ケ繧ソ繧偵槭ャ繝 - gpio = (DWORD *)ioremap_nocache(baseaddr + GPIO_OFFSET, 164); - level = &gpio[GPIO_LEV_0]; - - // PADS繝ャ繧ク繧ケ繧ソ繧偵槭ャ繝 - pads = (DWORD *)ioremap_nocache(baseaddr + PADS_OFFSET, 56); - break; - - case IOCTL_MODE: - // 蜍穂ス懊Δ繝シ繝牙、画峩 - actmode = (enum mode_e)arg; - break; - - case IOCTL_PADS: - // DriveStrength螟画峩 - if (!pads) { - return -1; - } - - data = pads[PAD_0_27]; - drive = arg; - pads[PAD_0_27] = (0xFFFFFFF8 & data) | drive | 0x5a000000; - break; - - default: - break; - } - - return 0; -} - -//--------------------------------------------------------------------------- -// -// 繝舌せ菫。蜿キ蜿悶j霎シ縺ソ -// -//--------------------------------------------------------------------------- -static inline DWORD Aquire(void) -{ - signals = *level; - -#if SIGNAL_CONTROL_MODE < 2 - // 雋隲也炊縺ェ繧牙渚霆「縺吶k(蜀驛ィ蜃ヲ逅縺ッ豁」隲也炊縺ォ邨ア荳) - signals = ~signals; -#endif - - return signals; -} - -//--------------------------------------------------------------------------- -// -// 繝翫ヮ遘貞腰菴阪ョ繧ケ繝ェ繝シ繝 -// -// GPIO髢「菫ゅョ繝ャ繧ク繧ケ繧ソ縺ッ繧ウ繧「繧ッ繝ュ繝繧ッ縺400縺ョ譎ゅ↓險域クャ縺励◆騾溷コヲ繧貞盾閠縺ォ縺励◆縲 -// 繝ェ繝シ繝:48ns -// 繝ゥ繧、繝: 8ns -// -//--------------------------------------------------------------------------- -static inline void SleepNsec(DWORD nsec) -{ - DWORD count; - - count = (nsec + 8 - 1) / 8; - while (count--) { - gpio[GPIO_PUD] = 0; - } -} - -//--------------------------------------------------------------------------- -// -// 繧キ繧ー繝翫Ν險ュ螳 -// -//--------------------------------------------------------------------------- -static inline void SetSignal(int pin, BOOL ast) -{ -#if SIGNAL_CONTROL_MODE == 0 - int index; - int shift; - DWORD data; - - index = pin / 10; - shift = (pin % 10) * 3; - data = gpfsel[index]; - data &= ~(0x7 << shift); - if (ast) { - data |= (1 << shift); - } - gpio[GPIO_FSEL_0 + index] = data; - gpfsel[index] = data; -#elif SIGNAL_CONTROL_MODE == 1 - if (ast) { - gpio[GPIO_CLR_0] = 0x1 << pin; - } else { - gpio[GPIO_SET_0] = 0x1 << pin; - } -#elif SIGNAL_CONTROL_MODE == 2 - if (ast) { - gpio[GPIO_SET_0] = 0x1 << pin; - } else { - gpio[GPIO_CLR_0] = 0x1 << pin; - } -#endif -} - -//--------------------------------------------------------------------------- -// -// 繝繝シ繧ソ蜿門セ -// -//--------------------------------------------------------------------------- -static inline BYTE GetDAT(void) -{ - DWORD data; - - data = Aquire(); - data = - ((data >> (PIN_DT0 - 0)) & (1 << 0)) | - ((data >> (PIN_DT1 - 1)) & (1 << 1)) | - ((data >> (PIN_DT2 - 2)) & (1 << 2)) | - ((data >> (PIN_DT3 - 3)) & (1 << 3)) | - ((data >> (PIN_DT4 - 4)) & (1 << 4)) | - ((data >> (PIN_DT5 - 5)) & (1 << 5)) | - ((data >> (PIN_DT6 - 6)) & (1 << 6)) | - ((data >> (PIN_DT7 - 7)) & (1 << 7)); - - return (BYTE)data; -} - -//--------------------------------------------------------------------------- -// -// 繝繝シ繧ソ險ュ螳 -// -//--------------------------------------------------------------------------- -static inline void SetDAT(BYTE dat) -{ - // 繝昴シ繝医∈譖ク縺崎セシ縺ソ -#if SIGNAL_CONTROL_MODE == 0 - gpfsel[0] &= tblDatMsk[0][dat]; - gpfsel[0] |= tblDatSet[0][dat]; - gpio[GPIO_FSEL_0] = gpfsel[0]; - - gpfsel[1] &= tblDatMsk[1][dat]; - gpfsel[1] |= tblDatSet[1][dat]; - gpio[GPIO_FSEL_1] = gpfsel[1]; - - gpfsel[2] &= tblDatMsk[2][dat]; - gpfsel[2] |= tblDatSet[2][dat]; - gpio[GPIO_FSEL_2] = gpfsel[2]; -#else - gpio[GPIO_CLR_0] = tblDatMsk[dat]; - gpio[GPIO_SET_0] = tblDatSet[dat]; -#endif -} - -//--------------------------------------------------------------------------- -// -// 繝ェ繝シ繝 -// -//--------------------------------------------------------------------------- -ssize_t drv_read( - struct file *file, char __user *buf, size_t count, loff_t *fops) -{ - ssize_t i; - BYTE data; - DWORD loop; - DWORD phase; - -#if SIGNAL_CONTROL_MODE == 0 - // FSEL莠句燕蜿門セ - gpfsel[0] = gpio[GPIO_FSEL_0]; - gpfsel[1] = gpio[GPIO_FSEL_1]; - gpfsel[2] = gpio[GPIO_FSEL_2]; -#endif - - // 蜑イ繧願セシ縺ソ遖∵ュ「 - local_irq_disable(); - local_fiq_disable(); - - if (actmode == TARGET) { - for (i = 0; i < count; i++) { - // REQ繧「繧オ繝シ繝 - SetSignal(PIN_REQ, TRUE); - - // ACK繧「繧オ繝シ繝亥セ縺。 - loop = (DWORD)30000000; - do { - Aquire(); - loop--; - } while (!(signals & (1 << PIN_ACK)) && - !(signals & (1 << PIN_RST)) && loop > 0); - - // 繝繝シ繧ソ蜿門セ - data = GetDAT(); - - // REQ繝阪ご繝シ繝 - SetSignal(PIN_REQ, FALSE); - - // ACK繧「繧オ繝シ繝亥セ縺。縺ァ繧ソ繧、繝繧「繧ヲ繝 - if (loop == 0 || (signals & (1 << PIN_RST))) { - break; - } - - // ACK繝阪ご繝シ繝亥セ縺。 - loop = (DWORD)30000000; - do { - Aquire(); - loop--; - } while ((signals & (1 << PIN_ACK)) && - !(signals & (1 << PIN_RST)) && loop > 0); - - // ACK繝阪ご繝シ繝亥セ縺。縺ァ繧ソ繧、繝繧「繧ヲ繝 - if (loop == 0 || (signals & (1 << PIN_RST))) { - break; - } - - // 繝繝シ繧ソ霑泌唆 - if (copy_to_user(buf, (unsigned char *)&data, 1)) { - break; - } - - // 谺。繝繝シ繧ソ縺ク - buf++; - } - } else { - // 繝輔ぉ繝シ繧コ蜿門セ - Aquire(); - phase = signals & GPIO_MCI; - - for (i = 0; i < count; i++) { - // REQ繧「繧オ繝シ繝亥セ縺。 - loop = 30000000; - do { - Aquire(); - loop--; - } while (!(signals & (1 << PIN_REQ)) && - ((signals & GPIO_MCI) == phase) && loop > 0); - - // REQ繧「繧オ繝シ繝亥セ縺。縺ァ繧ソ繧、繝繧「繧ヲ繝 - if (loop == 0 || (signals & GPIO_MCI) != phase) { - break; - } - - // 繝繝シ繧ソ蜿門セ - data = GetDAT(); - - // ACK繧「繧オ繝シ繝 - SetSignal(PIN_ACK, TRUE); - - // REQ繝阪ご繝シ繝亥セ縺。 - loop = 30000000; - do { - Aquire(); - loop--; - } while ((signals & (1 << PIN_REQ)) && - ((signals & GPIO_MCI) == phase) && loop > 0); - - // ACK繝阪ご繝シ繝 - SetSignal(PIN_ACK, FALSE); - - // REQ繝阪ご繝シ繝亥セ縺。縺ァ繧ソ繧、繝繧「繧ヲ繝 - if (loop == 0 || (signals & GPIO_MCI) != phase) { - break; - } - - // 繝繝シ繧ソ霑泌唆 - if (copy_to_user(buf, (unsigned char *)&data, 1)) { - break; - } - - // 谺。繝繝シ繧ソ縺ク - buf++; - } - } - - // 蜑イ繧願セシ縺ソ遖∵ュ「隗」髯、 - local_fiq_enable(); - local_irq_enable(); - - return i; -} - -//--------------------------------------------------------------------------- -// -// 繝ゥ繧、繝 -// -//--------------------------------------------------------------------------- -ssize_t drv_write( - struct file *file, const char __user *buf, size_t count, loff_t *fops) -{ - size_t i; - BYTE data; - DWORD loop; - DWORD phase; - - // 蜑イ繧願セシ縺ソ遖∵ュ「 - local_irq_disable(); - local_fiq_disable(); - -#if SIGNAL_CONTROL_MODE == 0 - // FSEL莠句燕蜿門セ - gpfsel[0] = gpio[GPIO_FSEL_0]; - gpfsel[1] = gpio[GPIO_FSEL_1]; - gpfsel[2] = gpio[GPIO_FSEL_2]; -#endif - - if (actmode == TARGET) { - for (i = 0; i < count; i++) { - // 繝繝シ繧ソ蜿悶j霎シ縺ソ - if (copy_from_user((unsigned char *)&data, buf, 1)) { - break; - } - - // 繝繝シ繧ソ險ュ螳 - SetDAT(data); - - // 菫。蜿キ邱壹′螳牙ョ壹☆繧九∪縺ァ繧ヲ繧ァ繧、繝 - SleepNsec(150); - - // ACK繝阪ご繝シ繝亥セ縺。 - loop = (DWORD)30000000; - do { - Aquire(); - loop--; - } while ((signals & (1 << PIN_ACK)) && - !(signals & (1 << PIN_RST)) && loop > 0); - - // ACK繝阪ご繝シ繝亥セ縺。縺ァ繧ソ繧、繝繧「繧ヲ繝 - if (loop == 0 || (signals & (1 << PIN_RST))) { - break; - } - - // REQ繧「繧オ繝シ繝 - SetSignal(PIN_REQ, TRUE); - - // ACK繧「繧オ繝シ繝亥セ縺。 - loop = (DWORD)30000000; - do { - Aquire(); - loop--; - } while (!(signals & (1 << PIN_ACK)) && - !(signals & (1 << PIN_RST)) && loop > 0); - - // REQ繝阪ご繝シ繝 - SetSignal(PIN_REQ, FALSE); - - // ACK繧「繧オ繝シ繝亥セ縺。縺ァ繧ソ繧、繝繧「繧ヲ繝 - if (loop == 0 || (signals & (1 << PIN_RST))) { - break; - } - - // 谺。繝繝シ繧ソ - buf++; - }; - - // ACK繝阪ご繝シ繝亥セ縺。 - loop = (DWORD)30000000; - do { - Aquire(); - loop--; - } while ((signals & (1 << PIN_ACK)) && - !(signals & (1 << PIN_RST)) && loop > 0); - } else { - // 繝輔ぉ繝シ繧コ蜿門セ - Aquire(); - phase = signals & GPIO_MCI; - - for (i = 0; i < count; i++) { - // 繝繝シ繧ソ蜿悶j霎シ縺ソ - if (copy_from_user((unsigned char *)&data, buf, 1)) { - break; - } - - // REQ繧「繧オ繝シ繝亥セ縺。 - loop = (DWORD)30000000; - do { - Aquire(); - loop--; - } while (!(signals & (1 << PIN_REQ)) && - ((signals & GPIO_MCI) == phase) && loop > 0); - - // REQ繧「繧オ繝シ繝亥セ縺。縺ァ繧ソ繧、繝繧「繧ヲ繝 - if (loop == 0 || (signals & GPIO_MCI) != phase) { - break; - } - - // 繝繝シ繧ソ險ュ螳 - SetDAT(data); - - // 菫。蜿キ邱壹′螳牙ョ壹☆繧九∪縺ァ繧ヲ繧ァ繧、繝 - SleepNsec(150); - - // ACK繧「繧オ繝シ繝 - SetSignal(PIN_ACK, TRUE); - - // REQ繝阪ご繝シ繝亥セ縺。 - loop = (DWORD)30000000; - do { - Aquire(); - loop--; - } while ((signals & (1 << PIN_REQ)) && - ((signals & GPIO_MCI) == phase) && loop > 0); - - // ACK繝阪ご繝シ繝 - SetSignal(PIN_ACK, FALSE); - - // REQ繝阪ご繝シ繝亥セ縺。縺ァ繧ソ繧、繝繧「繧ヲ繝 - if (loop == 0 || (signals & GPIO_MCI) != phase) { - break; - } - - // 谺。繝繝シ繧ソ縺ク - buf++; - } - } - - // 蜑イ繧願セシ縺ソ遖∵ュ「隗」髯、 - local_fiq_enable(); - local_irq_enable(); - - return i; -} - -module_init(drv_init); -module_exit(drv_exit); - -MODULE_DESCRIPTION("RASCSI GPIO Driver"); -MODULE_VERSION("1.0"); -MODULE_AUTHOR("GIMONS"); -MODULE_LICENSE("GPL"); diff --git a/src/raspberrypi/log.h b/src/raspberrypi/log.h index 4448418f..617a747e 100644 --- a/src/raspberrypi/log.h +++ b/src/raspberrypi/log.h @@ -4,7 +4,7 @@ // for Raspberry Pi // // Powered by XM6 TypeG Technology. -// Copyright (C) 2016-2018 GIMONS +// Copyright (C) 2016-2020 GIMONS // [ 繝ュ繧ー ] // //--------------------------------------------------------------------------- diff --git a/src/raspberrypi/os.h b/src/raspberrypi/os.h index d2d043e9..1d580b00 100644 --- a/src/raspberrypi/os.h +++ b/src/raspberrypi/os.h @@ -4,7 +4,7 @@ // for Raspberry Pi // // 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. // @@ -48,18 +48,29 @@ #include #include #include -#include #include -#include #include #include #include #include +#include + +#ifndef BAREMETAL +#include +#include #include #include -#include #include +#include #include +#include +#else +#include +#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__) #include @@ -71,8 +82,6 @@ #include #include #include -#else -#error unsupported platform #endif //--------------------------------------------------------------------------- diff --git a/src/raspberrypi/rascsi.cpp b/src/raspberrypi/rascsi.cpp index a697f101..8717daa3 100644 --- a/src/raspberrypi/rascsi.cpp +++ b/src/raspberrypi/rascsi.cpp @@ -4,40 +4,50 @@ // for Raspberry Pi // // Powered by XM6 TypeG Technology. -// Copyright (C) 2016-2018 GIMONS +// Copyright (C) 2016-2020 GIMONS // [ 繝。繧、繝ウ ] // //--------------------------------------------------------------------------- #include "os.h" #include "xm6.h" -#include "fileio.h" #include "filepath.h" +#include "fileio.h" #include "disk.h" #include "gpiobus.h" +//--------------------------------------------------------------------------- +// +// 螳壽焚螳」險 +// +//--------------------------------------------------------------------------- +#define CtrlMax 8 // 譛螟ァSCSI繧ウ繝ウ繝医Ο繝シ繝ゥ謨ー +#define UnitNum 2 // 繧ウ繝ウ繝医Ο繝シ繝ゥ霎コ繧翫ョ繝ヲ繝九ャ繝域焚 +#ifdef BAREMETAL +#define FPRT(fp, ...) printf( __VA_ARGS__ ) +#else +#define FPRT(fp, ...) fprintf(fp, __VA_ARGS__ ) +#endif // BAREMETAL + //--------------------------------------------------------------------------- // // 螟画焚螳」險 // //--------------------------------------------------------------------------- -enum { - CtrlMax = 8, // 譛螟ァSCSI繧ウ繝ウ繝医Ο繝シ繝ゥ謨ー -}; - +static volatile BOOL running; // 螳溯。御クュ繝輔Λ繧ー +static volatile BOOL active; // 蜃ヲ逅荳ュ繝輔Λ繧ー SASIDEV *ctrl[CtrlMax]; // 繧ウ繝ウ繝医Ο繝シ繝ゥ -Disk *disk[CtrlMax]; // 繝繧」繧ケ繧ッ -Filepath image[CtrlMax]; // 繧、繝。繝シ繧ク繝輔ぃ繧、繝ォ繝代せ -GPIOBUS bus; // 繝舌せ -BUS::phase_t phase; // 繝輔ぉ繝シ繧コ -int actid; // 繧「繧ッ繝繧」繝悶↑繧ウ繝ウ繝医Ο繝シ繝ゥID -volatile BOOL bRun; // 螳溯。御クュ繝輔Λ繧ー - -BOOL bServer; // 繧オ繝シ繝舌シ繝「繝シ繝峨ヵ繝ゥ繧ー -int monfd; // 繝「繝九ち繝シ逕ィ繧ス繧ア繝繝FD +Disk *disk[CtrlMax * UnitNum]; // 繝繧」繧ケ繧ッ +GPIOBUS *bus; // GPIO繝舌せ +#ifdef BAREMETAL +FATFS fatfs; // FatFS +#else +int monsocket; // 繝「繝九ち繝シ逕ィ繧ス繧ア繝繝 pthread_t monthread; // 繝「繝九ち繝シ繧ケ繝ャ繝繝 static void *MonThread(void *param); +#endif // BAREMETAL +#ifndef BAREMETAL //--------------------------------------------------------------------------- // // 繧キ繧ー繝翫Ν蜃ヲ逅 @@ -46,43 +56,50 @@ static void *MonThread(void *param); void KillHandler(int sig) { // 蛛懈ュ「謖遉コ - bRun = FALSE; + running = FALSE; } +#endif // BAREMETAL //--------------------------------------------------------------------------- // // 繝舌リ繝シ蜃コ蜉 // //--------------------------------------------------------------------------- -BOOL Banner(int argc, char* argv[]) +void Banner(int argc, char* argv[]) { - printf("SCSI Target Emulator RaSCSI(*^..^*) "); - printf("version %01d.%01d%01d\n", + FPRT(stdout,"SCSI Target Emulator RaSCSI(*^..^*) "); + FPRT(stdout,"version %01d.%01d%01d(%s, %s)\n", (int)((VERSION >> 8) & 0xf), (int)((VERSION >> 4) & 0xf), - (int)((VERSION ) & 0xf)); - printf("Powered by XM6 TypeG Technology / "); - printf("Copyright (C) 2016-2018 GIMONS\n"); - printf("Connect type : %s\n", CONNECT_DESC); + (int)((VERSION ) & 0xf), + __DATE__, + __TIME__); + FPRT(stdout,"Powered by XM6 TypeG Technology / "); + FPRT(stdout,"Copyright (C) 2016-2020 GIMONS\n"); + FPRT(stdout,"Connect type : %s\n", CONNECT_DESC); if (argc > 1 && strcmp(argv[1], "-h") == 0) { - printf("\n"); - printf("Usage: %s [-ID{0|1|2|3|4|5|6|7} FILE] ...\n\n", argv[0]); - printf(" IDn is SCSI identification number.\n"); - printf(" FILE is disk image file.\n\n"); - printf(" Detected images type based on file extension.\n"); - printf(" hdf : SASI HD image(XM6 SASI HD image)\n"); - printf(" hds : SCSI HD image(XM6 SCSI HD image)\n"); - printf(" hdn : SCSI HD image(NEC GENUINE)\n"); - printf(" hdi : SCSI HD image(Anex86 HD image)\n"); - printf(" nhd : SCSI HD image(T98Next HD image)\n"); - printf(" hda : SCSI HD image(APPLE GENUINE)\n"); - printf(" mos : SCSI MO image(XM6 SCSI MO image)\n"); - printf(" iso : SCSI CD image(ISO 9660 image)\n"); - return FALSE; - } + FPRT(stdout,"\n"); + FPRT(stdout,"Usage: %s [-IDn FILE] ...\n\n", argv[0]); + FPRT(stdout," n is SCSI identification number(0-7).\n"); + FPRT(stdout," FILE is disk image file.\n\n"); + FPRT(stdout,"Usage: %s [-HDn FILE] ...\n\n", argv[0]); + FPRT(stdout," n is X68000 SASI HD number(0-15).\n"); + FPRT(stdout," FILE is disk image file.\n\n"); + FPRT(stdout," Image type is detected based on file extension.\n"); + FPRT(stdout," hdf : SASI HD image(XM6 SASI HD image)\n"); + FPRT(stdout," hds : SCSI HD image(XM6 SCSI HD image)\n"); + FPRT(stdout," hdn : SCSI HD image(NEC GENUINE)\n"); + FPRT(stdout," hdi : SCSI HD image(Anex86 HD image)\n"); + FPRT(stdout," nhd : SCSI HD image(T98Next HD image)\n"); + FPRT(stdout," hda : SCSI HD image(APPLE GENUINE)\n"); + FPRT(stdout," mos : SCSI MO image(XM6 SCSI MO image)\n"); + FPRT(stdout," iso : SCSI CD image(ISO 9660 image)\n"); - return TRUE; +#ifndef BAREMETAL + exit(0); +#endif // BAREMETAL + } } //--------------------------------------------------------------------------- @@ -93,25 +110,35 @@ BOOL Banner(int argc, char* argv[]) BOOL Init() { int i; + +#ifndef BAREMETAL struct sockaddr_in server; + int yes; // 繝「繝九ち繝シ逕ィ繧ス繧ア繝繝育函謌 - monfd = socket(PF_INET, SOCK_STREAM, 0); + monsocket = socket(PF_INET, SOCK_STREAM, 0); memset(&server, 0, sizeof(server)); server.sin_family = PF_INET; server.sin_port = htons(6868); - server.sin_addr.s_addr = htonl(INADDR_ANY); - if (bind(monfd, (struct sockaddr *)&server, - sizeof(struct sockaddr_in)) < 0) { - if (errno != EADDRINUSE) { - return FALSE; - } - bServer = FALSE; - return TRUE; - } else { - bServer = TRUE; + server.sin_addr.s_addr = htonl(INADDR_ANY); + + // 繧「繝峨Ξ繧ケ縺ョ蜀榊茜逕ィ繧定ィア蜿ッ縺吶k + yes = 1; + if (setsockopt( + monsocket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0){ + return FALSE; } + // 繝舌う繝ウ繝 + if (bind(monsocket, (struct sockaddr *)&server, + sizeof(struct sockaddr_in)) < 0) { + FPRT(stderr, "Error : Already running?\n"); + return FALSE; + } + + // 繝「繝九ち繝シ繧ケ繝ャ繝繝臥函謌 + pthread_create(&monthread, NULL, MonThread, NULL); + // 蜑イ繧願セシ縺ソ繝上Φ繝峨Λ險ュ螳 if (signal(SIGINT, KillHandler) == SIG_ERR) { return FALSE; @@ -122,12 +149,19 @@ BOOL Init() if (signal(SIGTERM, KillHandler) == SIG_ERR) { return FALSE; } +#endif // BAREMETAL + // GPIOBUS逕滓 + bus = new GPIOBUS(); + // GPIO蛻晄悄蛹 - if (!bus.Init()) { + if (!bus->Init()) { return FALSE; } + // 繝舌せ繝ェ繧サ繝繝 + bus->Reset(); + // 繧ウ繝ウ繝医Ο繝シ繝ゥ蛻晄悄蛹 for (i = 0; i < CtrlMax; i++) { ctrl[i] = NULL; @@ -138,13 +172,9 @@ BOOL Init() disk[i] = NULL; } - // 繧、繝。繝シ繧ク繝代せ蛻晄悄蛹 - for (i = 0; i < CtrlMax; i++) { - image[i].Clear(); - } - - // 繧「繧ッ繝繧」繝蜂D蛻晄悄蛹 - actid = -1; + // 縺昴ョ莉 + running = FALSE; + active = FALSE; return TRUE; } @@ -159,7 +189,7 @@ void Cleanup() int i; // 繝繧」繧ケ繧ッ蜑企勁 - for (i = 0; i < CtrlMax; i++) { + for (i = 0; i < CtrlMax * UnitNum; i++) { if (disk[i]) { delete disk[i]; disk[i] = NULL; @@ -175,12 +205,17 @@ void Cleanup() } // 繝舌せ繧偵け繝ェ繝シ繝ウ繧「繝繝 - bus.Cleanup(); + bus->Cleanup(); + + // GPIOBUS遐エ譽 + delete bus; +#ifndef BAREMETAL // 繝「繝九ち繝シ逕ィ繧ス繧ア繝繝医け繝ュ繝シ繧コ - if (monfd >= 0) { - close(monfd); + if (monsocket >= 0) { + close(monsocket); } +#endif // BAREMETAL } //--------------------------------------------------------------------------- @@ -192,9 +227,6 @@ void Reset() { int i; - // 繧「繧ッ繝繧」繝蜂D蛻晄悄蛹 - actid = -1; - // 繧ウ繝ウ繝医Ο繝シ繝ゥ繝ェ繧サ繝繝 for (i = 0; i < CtrlMax; i++) { if (ctrl[i]) { @@ -203,7 +235,7 @@ void Reset() } // 繝舌せ菫。蜿キ邱壹r繝ェ繧サ繝繝 - bus.Reset(); + bus->Reset(); } //--------------------------------------------------------------------------- @@ -214,59 +246,183 @@ void Reset() void ListDevice(FILE *fp) { int i; + int id; + int un; + Disk *pUnit; Filepath filepath; BOOL find; char type[5]; find = FALSE; type[4] = 0; - for (i = 0; i < 8; i++) { - if (disk[i] == NULL) { + for (i = 0; i < CtrlMax * UnitNum; i++) { + // ID縺ィ繝ヲ繝九ャ繝 + id = i / UnitNum; + un = i % UnitNum; + pUnit = disk[i]; + + // 繝ヲ繝九ャ繝医′蟄伜惠縺励↑縺縺セ縺溘ッ繝後Ν繝繧」繧ケ繧ッ縺ェ繧峨せ繧ュ繝繝 + if (pUnit == NULL || pUnit->IsNULL()) { continue; } // 繝倥ャ繝繝シ蜃コ蜉 if (!find) { - fprintf(fp, "\n"); - fprintf(fp, "---+------+---------------------------------------\n"); - fprintf(fp, "ID | TYPE | DEVICE STATUS\n"); - fprintf(fp, "---+------+---------------------------------------\n"); + FPRT(fp, "\n"); + FPRT(fp, "+----+----+------+-------------------------------------\n"); + FPRT(fp, "| ID | UN | TYPE | DEVICE STATUS\n"); + FPRT(fp, "+----+----+------+-------------------------------------\n"); find = TRUE; } - // ID,繧ソ繧、繝怜コ蜉 - type[0] = (char)(disk[i]->GetID() >> 24); - type[1] = (char)(disk[i]->GetID() >> 16); - type[2] = (char)(disk[i]->GetID() >> 8); - type[3] = (char)(disk[i]->GetID()); - fprintf(fp, " %d | %s | ", i, type); + // ID,UNIT,繧ソ繧、繝怜コ蜉 + type[0] = (char)(pUnit->GetID() >> 24); + type[1] = (char)(pUnit->GetID() >> 16); + type[2] = (char)(pUnit->GetID() >> 8); + type[3] = (char)(pUnit->GetID()); + FPRT(fp, "| %d | %d | %s | ", id, un, type); // 繝槭え繝ウ繝育憾諷句コ蜉 - if (disk[i]->GetID() == MAKEID('S', 'C', 'B', 'R')) { - fprintf(fp, "%s", "RaSCSI BRIDGE"); + if (pUnit->GetID() == MAKEID('S', 'C', 'B', 'R')) { + FPRT(fp, "%s", "HOST BRIDGE"); } else { - disk[i]->GetPath(filepath); - fprintf(fp, "%s", - (disk[i]->IsRemovable() && !disk[i]->IsReady()) ? + pUnit->GetPath(filepath); + FPRT(fp, "%s", + (pUnit->IsRemovable() && !pUnit->IsReady()) ? "NO MEDIA" : filepath.GetPath()); } // 繝ゥ繧、繝医励Ο繝繧ッ繝育憾諷句コ蜉 - if (disk[i]->IsRemovable() && disk[i]->IsReady() && disk[i]->IsWriteP()) { - fprintf(fp, "(WRITEPROTECT)"); + if (pUnit->IsRemovable() && pUnit->IsReady() && pUnit->IsWriteP()) { + FPRT(fp, "(WRITEPROTECT)"); } // 谺。縺ョ陦後∈ - fprintf(fp, "\n"); + FPRT(fp, "\n"); } // 繧ウ繝ウ繝医Ο繝シ繝ゥ縺檎┌縺蝣エ蜷 if (!find) { - fprintf(fp, "No device is installed.\n"); + FPRT(fp, "No device is installed.\n"); return; } - fprintf(fp, "---+------+---------------------------------------\n"); + FPRT(fp, "+----+----+------+-------------------------------------\n"); +} + +//--------------------------------------------------------------------------- +// +// 繧ウ繝ウ繝医Ο繝シ繝ゥ繝槭ャ繝斐Φ繧ー +// +//--------------------------------------------------------------------------- +void MapControler(FILE *fp, Disk **map) +{ + int i; + int j; + int unitno; + int sasi_num; + int scsi_num; + + // 螟画峩縺輔l縺溘Θ繝九ャ繝医ョ鄂ョ縺肴鋤縺 + for (i = 0; i < CtrlMax; i++) { + for (j = 0; j < UnitNum; j++) { + unitno = i * UnitNum + j; + if (disk[unitno] != map[unitno]) { + // 蜈縺ョ繝ヲ繝九ャ繝医′蟄伜惠縺吶k + if (disk[unitno]) { + // 繧ウ繝ウ繝医Ο繝シ繝ゥ縺九i蛻繧企屬縺 + if (ctrl[i]) { + ctrl[i]->SetUnit(j, NULL); + } + + // 繝ヲ繝九ャ繝医r隗」謾セ + delete disk[unitno]; + } + + // 譁ー縺励>繝ヲ繝九ャ繝医ョ險ュ螳 + disk[unitno] = map[unitno]; + } + } + } + + // 蜈ィ繧ウ繝ウ繝医Ο繝シ繝ゥ繧貞肴ァ区 + for (i = 0; i < CtrlMax; i++) { + // 繝ヲ繝九ャ繝域ァ区舌r隱ソ縺ケ繧 + sasi_num = 0; + scsi_num = 0; + for (j = 0; j < UnitNum; j++) { + unitno = i * UnitNum + j; + // 繝ヲ繝九ャ繝医ョ遞ョ鬘槭〒蛻蟯 + if (disk[unitno]) { + if (disk[unitno]->IsSASI()) { + // SASI繝峨Λ繧、繝匁焚蜉邂 + sasi_num++; + } else { + // SCSI繝峨Λ繧、繝匁焚蜉邂 + scsi_num++; + } + } + + // 繝ヲ繝九ャ繝医r蜿悶j螟悶☆ + if (ctrl[i]) { + ctrl[i]->SetUnit(j, NULL); + } + } + + // 謗・邯壹Θ繝九ャ繝医↑縺 + if (sasi_num == 0 && scsi_num == 0) { + if (ctrl[i]) { + delete ctrl[i]; + ctrl[i] = NULL; + continue; + } + } + + // SASI,SCSI豺キ蝨ィ + if (sasi_num > 0 && scsi_num > 0) { + FPRT(fp, "Error : SASI and SCSI can't be mixed\n"); + continue; + } + + if (sasi_num > 0) { + // SASI縺ョ繝ヲ繝九ャ繝医ョ縺ソ + + // 繧ウ繝ウ繝医Ο繝シ繝ゥ縺ョ繧ソ繧、繝励′驕輔≧縺ェ繧芽ァ」謾セ + if (ctrl[i] && !ctrl[i]->IsSASI()) { + delete ctrl[i]; + ctrl[i] = NULL; + } + + // SASI繧ウ繝ウ繝医Ο繝シ繝ゥ逕滓 + if (!ctrl[i]) { + ctrl[i] = new SASIDEV(); + ctrl[i]->Connect(i, bus); + } + } else { + // SCSI縺ョ繝ヲ繝九ャ繝医ョ縺ソ + + // 繧ウ繝ウ繝医Ο繝シ繝ゥ縺ョ繧ソ繧、繝励′驕輔≧縺ェ繧芽ァ」謾セ + if (ctrl[i] && !ctrl[i]->IsSCSI()) { + delete ctrl[i]; + ctrl[i] = NULL; + } + + // SCSI繧ウ繝ウ繝医Ο繝シ繝ゥ逕滓 + if (!ctrl[i]) { + ctrl[i] = new SCSIDEV(); + ctrl[i]->Connect(i, bus); + } + } + + // 蜈ィ繝ヲ繝九ャ繝域磁邯 + for (j = 0; j < UnitNum; j++) { + unitno = i * UnitNum + j; + if (disk[unitno]) { + // 繝ヲ繝九ャ繝域磁邯 + ctrl[i]->SetUnit(j, disk[unitno]); + } + } + } } //--------------------------------------------------------------------------- @@ -274,34 +430,34 @@ void ListDevice(FILE *fp) // 繧ウ繝槭Φ繝牙ヲ逅 // //--------------------------------------------------------------------------- -BOOL ProcessCmd(FILE *fp, int id, int cmd, int type, char *file) +BOOL ProcessCmd(FILE *fp, int id, int un, int cmd, int type, char *file) { + Disk *map[CtrlMax * UnitNum]; int len; char *ext; Filepath filepath; + Disk *pUnit; + + // 繝ヲ繝九ャ繝井ク隕ァ繧定、蜀 + memcpy(map, disk, sizeof(disk)); // ID繝√ぉ繝繧ッ - if (id < 0 || id > 7) { - fprintf(fp, "Error : Invalid ID\n"); + if (id < 0 || id >= CtrlMax) { + FPRT(fp, "Error : Invalid ID\n"); + return FALSE; + } + + // 繝ヲ繝九ャ繝医メ繧ァ繝繧ッ + if (un < 0 || un >= UnitNum) { + FPRT(fp, "Error : Invalid unit number\n"); return FALSE; } // 謗・邯壹さ繝槭Φ繝 if (cmd == 0) { // ATTACH - // 繧ウ繝ウ繝医Ο繝シ繝ゥ繧定ァ」謾セ - if (ctrl[id]) { - ctrl[id]->SetUnit(0, NULL); - delete ctrl[id]; - ctrl[id] = NULL; - } - - // 繝繧」繧ケ繧ッ繧定ァ」謾セ - if (disk[id]) { - delete disk[id]; - disk[id] = NULL; - } - // SASI縺ィSCSI繧定ヲ句縺代k + ext = NULL; + pUnit = NULL; if (type == 0) { // 繝代せ繝√ぉ繝繧ッ if (!file) { @@ -329,96 +485,92 @@ BOOL ProcessCmd(FILE *fp, int id, int cmd, int type, char *file) // 繧ソ繧、繝怜挨縺ョ繧、繝ウ繧ケ繧ソ繝ウ繧ケ繧堤函謌 switch (type) { case 0: // HDF - disk[id] = new SASIHD(); + pUnit = new SASIHD(); break; case 1: // HDS/HDN/HDI/NHD/HDA + if (ext == NULL) { + break; + } if (xstrcasecmp(ext, "hdn") == 0 || xstrcasecmp(ext, "hdi") == 0 || xstrcasecmp(ext, "nhd") == 0) { - disk[id] = new SCSIHD_NEC(); + pUnit = new SCSIHD_NEC(); } else if (xstrcasecmp(ext, "hda") == 0) { - disk[id] = new SCSIHD_APPLE(); + pUnit = new SCSIHD_APPLE(); } else { - disk[id] = new SCSIHD(); + pUnit = new SCSIHD(); } break; case 2: // MO - disk[id] = new SCSIMO(); + pUnit = new SCSIMO(); break; case 3: // CD - disk[id] = new SCSICD(); + pUnit = new SCSICD(); break; case 4: // BRIDGE - disk[id] = new SCSIBR(); + pUnit = new SCSIBR(); break; default: - fprintf(fp, "Error : Invalid device type\n"); + FPRT(fp, "Error : Invalid device type\n"); return FALSE; } - // 繧ソ繧、繝励↓蜷医o縺帙※繧ウ繝ウ繝医Ο繝シ繝ゥ繧剃ス懊k - if (type == 0) { - ctrl[id] = new SASIDEV(); - } else { - ctrl[id] = new SCSIDEV(); - } - // 繝峨Λ繧、繝悶ッ繝輔ぃ繧、繝ォ縺ョ遒コ隱阪r陦後≧ if (type <= 1 || (type <= 3 && xstrcasecmp(file, "-") != 0)) { // 繝代せ繧定ィュ螳 filepath.SetPath(file); // 繧ェ繝シ繝励Φ - if (!disk[id]->Open(filepath)) { - fprintf(fp, "Error : File open error [%s]\n", file); - delete disk[id]; - disk[id] = NULL; - delete ctrl[id]; - ctrl[id] = NULL; + if (!pUnit->Open(filepath)) { + FPRT(fp, "Error : File open error [%s]\n", file); + delete pUnit; return FALSE; } } // 繝ゥ繧、繝医せ繝ォ繝シ縺ォ險ュ螳 - disk[id]->SetCacheWB(FALSE); + pUnit->SetCacheWB(FALSE); - // 譁ー縺溘↑繝繧」繧ケ繧ッ繧呈磁邯 - ctrl[id]->Connect(id, &bus); - ctrl[id]->SetUnit(0, disk[id]); + // 譁ー縺励>繝ヲ繝九ャ繝医〒鄂ョ縺肴鋤縺 + map[id * UnitNum + un] = pUnit; + + // 繧ウ繝ウ繝医Ο繝シ繝ゥ繝槭ャ繝斐Φ繧ー + MapControler(fp, map); return TRUE; } // 譛牙柑縺ェ繧ウ繝槭Φ繝峨° if (cmd > 4) { - fprintf(fp, "Error : Invalid command\n"); + FPRT(fp, "Error : Invalid command\n"); return FALSE; } // 繧ウ繝ウ繝医Ο繝シ繝ゥ縺悟ュ伜惠縺吶k縺 if (ctrl[id] == NULL) { - fprintf(fp, "Error : No such device\n"); + FPRT(fp, "Error : No such device\n"); return FALSE; } - // 繝繧」繧ケ繧ッ縺悟ュ伜惠縺吶k縺 - if (disk[id] == NULL) { - fprintf(fp, "Error : No such device\n"); + // 繝ヲ繝九ャ繝医′蟄伜惠縺吶k縺 + pUnit = disk[id * UnitNum + un]; + if (pUnit == NULL) { + FPRT(fp, "Error : No such device\n"); return FALSE; } // 蛻譁ュ繧ウ繝槭Φ繝 if (cmd == 1) { // DETACH - ctrl[id]->SetUnit(0, NULL); - delete disk[id]; - disk[id] = NULL; - delete ctrl[id]; - ctrl[id] = NULL; + // 譌「蟄倥ョ繝ヲ繝九ャ繝医r隗」謾セ + map[id * UnitNum + un] = NULL; + + // 繧ウ繝ウ繝医Ο繝シ繝ゥ繝槭ャ繝斐Φ繧ー + MapControler(fp, map); return TRUE; } // MO縺気D縺ョ蝣エ蜷医□縺第怏蜉ケ - if (disk[id]->GetID() != MAKEID('S', 'C', 'M', 'O') && - disk[id]->GetID() != MAKEID('S', 'C', 'C', 'D')) { - fprintf(fp, "Error : Operation denied(Deveice isn't MO or CD)\n"); + if (pUnit->GetID() != MAKEID('S', 'C', 'M', 'O') && + pUnit->GetID() != MAKEID('S', 'C', 'C', 'D')) { + FPRT(fp, "Error : Operation denied(Deveice isn't removable)\n"); return FALSE; } @@ -428,22 +580,22 @@ BOOL ProcessCmd(FILE *fp, int id, int cmd, int type, char *file) filepath.SetPath(file); // 繧ェ繝シ繝励Φ - if (!disk[id]->Open(filepath)) { - fprintf(fp, "Error : File open error [%s]\n", file); + if (pUnit->Open(filepath)) { + FPRT(fp, "Error : File open error [%s]\n", file); return FALSE; } break; case 3: // EJECT - disk[id]->Eject(TRUE); + pUnit->Eject(TRUE); break; case 4: // PROTECT - if (disk[id]->GetID() != MAKEID('S', 'C', 'M', 'O')) { - fprintf(fp, "Error : Operation denied(Deveice isn't MO)\n"); + if (pUnit->GetID() != MAKEID('S', 'C', 'M', 'O')) { + FPRT(fp, "Error : Operation denied(Deveice isn't MO)\n"); return FALSE; } - disk[id]->WriteP(!disk[id]->IsWriteP()); + pUnit->WriteP(!pUnit->IsWriteP()); break; default: ASSERT(FALSE); @@ -460,48 +612,148 @@ BOOL ProcessCmd(FILE *fp, int id, int cmd, int type, char *file) //--------------------------------------------------------------------------- BOOL ParseArgument(int argc, char* argv[]) { +#ifdef BAREMETAL + FRESULT fr; + FIL fp; + char line[512]; +#else int i; +#endif // BAREMETAL int id; + int un; int type; char *argID; char *argPath; int len; char *ext; +#ifdef BAREMETAL + // SD繧ォ繝シ繝峨槭え繝ウ繝 + fr = f_mount(&fatfs, "", 1); + if (fr != FR_OK) { + FPRT(stderr, "Error : SD card mount failed.\n"); + return FALSE; + } + + // 險ュ螳壹ヵ繧。繧、繝ォ縺後↑縺代l縺ー蜃ヲ逅繧剃クュ譁ュ + fr = f_open(&fp, "rascsi.ini", FA_READ); + if (fr != FR_OK) { + return FALSE; + } +#else // ID縺ィ繝代せ謖螳壹′縺ェ縺代l縺ー蜃ヲ逅繧剃クュ譁ュ if (argc < 3) { return TRUE; } - - // 蠑墓焚縺ョ隗」隱ュ髢句ァ i = 1; argc--; +#endif // BAREMETAL + + // 隗」隱ュ髢句ァ + + while (TRUE) { +#ifdef BAREMETAL + // 1陦悟叙蠕 + memset(line, 0x00, sizeof(line)); + if (f_gets(line, sizeof(line) -1, &fp) == NULL) { + break; + } + + // CR/LF蜑企勁 + len = strlen(line); + while (len > 0) { + if (line[len - 1] != '\r' && line[len - 1] != '\n') { + break; + } + line[len - 1] = '\0'; + len--; + } +#else + if (argc < 2) { + break; + } - // ID縺ィ繝代せ繧貞叙蠕 - while (argc >= 2) { argc -= 2; +#endif // BAREMETAL + + // ID縺ィ繝代せ繧貞叙蠕 +#ifdef BAREMETAL + argID = &line[0]; + argPath = &line[4]; + line[3] = '\0'; + + // 莠句燕繝√ぉ繝繧ッ + if (argID[0] == '\0' || argPath[0] == '\0') { + continue; + } +#else argID = argv[i++]; argPath = argv[i++]; - // -ID or -id縺ョ蠖「蠑上r繝√ぉ繝繧ッ - if (strlen(argID) != 4 || xstrncasecmp(argID, "-id", 3) != 0) { - fprintf(stderr, - "Error : Invalid argument(-IDn) [%s]\n", argID); - return FALSE; + // 莠句燕繝√ぉ繝繧ッ + if (argID[0] != '-') { + FPRT(stderr, + "Error : Invalid argument(-IDn or -HDn) [%s]\n", argID); + goto parse_error; } + argID++; +#endif // BAREMETAL - // ID逡ェ蜿キ繧偵メ繧ァ繝繧ッ(0-7) - if (argID[3] < '0' || argID[3] > '7') { - fprintf(stderr, - "Error : Invalid argument(-IDn n=0-7) [%c]\n", argID[3]); - return FALSE; + if (strlen(argID) == 3 && xstrncasecmp(argID, "id", 2) == 0) { + // ID or id縺ョ蠖「蠑 + + // ID逡ェ蜿キ繧偵メ繧ァ繝繧ッ(0-7) + if (argID[2] < '0' || argID[2] > '7') { + FPRT(stderr, + "Error : Invalid argument(IDn n=0-7) [%c]\n", argID[2]); + goto parse_error; + } + + // ID,繝ヲ繝九ャ繝育「コ螳 + id = argID[2] - '0'; + un = 0; + } else if (xstrncasecmp(argID, "hd", 2) == 0) { + // HD or hd縺ョ蠖「蠑 + + if (strlen(argID) == 3) { + // HD逡ェ蜿キ繧偵メ繧ァ繝繧ッ(0-9) + if (argID[2] < '0' || argID[2] > '9') { + FPRT(stderr, + "Error : Invalid argument(HDn n=0-15) [%c]\n", argID[2]); + goto parse_error; + } + + // ID,繝ヲ繝九ャ繝育「コ螳 + id = (argID[2] - '0') / UnitNum; + un = (argID[2] - '0') % UnitNum; + } else if (strlen(argID) == 4) { + // HD逡ェ蜿キ繧偵メ繧ァ繝繧ッ(10-15) + if (argID[2] != '1' || argID[3] < '0' || argID[3] > '5') { + FPRT(stderr, + "Error : Invalid argument(HDn n=0-15) [%c]\n", argID[2]); + goto parse_error; + } + + // ID,繝ヲ繝九ャ繝育「コ螳 + id = ((argID[3] - '0') + 10) / UnitNum; + un = ((argID[3] - '0') + 10) % UnitNum; +#ifdef BAREMETAL + argPath++; +#endif // BAREMETAL + } else { + FPRT(stderr, + "Error : Invalid argument(IDn or HDn) [%s]\n", argID); + goto parse_error; + } + } else { + FPRT(stderr, + "Error : Invalid argument(IDn or HDn) [%s]\n", argID); + goto parse_error; } - // ID遒コ螳 - id = argID[3] - '0'; - // 縺吶〒縺ォ繧「繧ッ繝繧」繝悶↑繝繝舌う繧ケ縺後≠繧九↑繧峨せ繧ュ繝繝 - if (disk[id]) { + if (disk[id * UnitNum + un] && + !disk[id * UnitNum + un]->IsNULL()) { continue; } @@ -515,17 +767,17 @@ BOOL ParseArgument(int argc, char* argv[]) // 繝代せ縺ョ髟キ縺輔r繝√ぉ繝繧ッ len = strlen(argPath); if (len < 5) { - fprintf(stderr, + FPRT(stderr, "Error : Invalid argument(File path is short) [%s]\n", argPath); - return FALSE; + goto parse_error; } // 諡。蠑オ蟄舌r謖√▲縺ヲ縺繧九°シ if (argPath[len - 4] != '.') { - fprintf(stderr, + FPRT(stderr, "Error : Invalid argument(No extension) [%s]\n", argPath); - return FALSE; + goto parse_error; } // 繧ソ繧、繝励r豎コ繧√k @@ -545,22 +797,60 @@ BOOL ParseArgument(int argc, char* argv[]) type = 3; } else { // 繧ソ繧、繝励′蛻、蛻・縺ァ縺阪↑縺 - fprintf(stderr, + FPRT(stderr, "Error : Invalid argument(file type) [%s]\n", ext); - return FALSE; + goto parse_error; } } // 繧ウ繝槭Φ繝牙ョ溯。 - if (!ProcessCmd(stderr, id, 0, type, argPath)) { - return FALSE; + if (!ProcessCmd(stderr, id, un, 0, type, argPath)) { + goto parse_error; } } +#ifdef BAREMETAL + // 險ュ螳壹ヵ繧。繧、繝ォ繧ッ繝ュ繝シ繧コ + f_close(&fp); +#endif // BAREMETAL + // 繝繝舌う繧ケ繝ェ繧ケ繝郁。ィ遉コ ListDevice(stdout); return TRUE; + +parse_error: + +#ifdef BAREMETAL + // 險ュ螳壹ヵ繧。繧、繝ォ繧ッ繝ュ繝シ繧コ + f_close(&fp); +#endif // BAREMETAL + + return FALSE; +} + +#ifndef BAREMETAL +//--------------------------------------------------------------------------- +// +// 繧ケ繝ャ繝繝峨r迚ケ螳壹ョCPU縺ォ蝗コ螳壹☆繧 +// +//--------------------------------------------------------------------------- +void FixCpu(int cpu) +{ + cpu_set_t cpuset; + int cpus; + + // CPU謨ー蜿門セ + CPU_ZERO(&cpuset); + sched_getaffinity(0, sizeof(cpu_set_t), &cpuset); + cpus = CPU_COUNT(&cpuset); + + // 繧「繝輔ぅ繝九ユ繧」險ュ螳 + if (cpu < cpus) { + CPU_ZERO(&cpuset); + CPU_SET(cpu, &cpuset); + sched_setaffinity(0, sizeof(cpu_set_t), &cpuset); + } } //--------------------------------------------------------------------------- @@ -570,58 +860,106 @@ BOOL ParseArgument(int argc, char* argv[]) //--------------------------------------------------------------------------- static void *MonThread(void *param) { + struct sched_param schedparam; struct sockaddr_in client; socklen_t len; int fd; FILE *fp; - BYTE buf[BUFSIZ]; + char buf[BUFSIZ]; + char *p; + int i; + char *argv[5]; int id; + int un; int cmd; int type; char *file; - BOOL list; + + // 繧ケ繧ア繧ク繝・繝シ繝ゥ險ュ螳 + schedparam.sched_priority = 0; + sched_setscheduler(0, SCHED_IDLE, &schedparam); + + // CPU繧貞崋螳 + FixCpu(2); + + // 螳溯。碁幕蟋句セ縺。 + while (!running) { + usleep(1); + } // 逶」隕匁コ門y - listen(monfd, 1); + listen(monsocket, 1); while (1) { // 謗・邯壼セ縺。 memset(&client, 0, sizeof(client)); len = sizeof(client); - fd = accept(monfd, (struct sockaddr*)&client, &len); + fd = accept(monsocket, (struct sockaddr*)&client, &len); if (fd < 0) { break; } // 繧ウ繝槭Φ繝牙叙蠕 fp = fdopen(fd, "r+"); - fgets((char *)buf, BUFSIZ, fp); - buf[strlen((const char*)buf) - 1] = 0; + p = fgets(buf, BUFSIZ, fp); - // 繝繝舌う繧ケ繝ェ繧ケ繝郁。ィ遉コ縺ェ縺ョ縺句宛蠕。繧ウ繝槭Φ繝峨°繧貞愛譁ュ - if (strncasecmp((char*)buf, "list", 4) == 0) { - list = TRUE; - } else { - list = FALSE; - id = (int)(buf[0] - '0'); - cmd = (int)(buf[2] - '0'); - type = (int)(buf[4] - '0'); - file = (char*)&buf[6]; + // 繧ウ繝槭Φ繝牙叙蠕励↓螟ア謨 + if (!p) { + goto next; } - // 繝舌せ繝輔Μ繝シ縺ョ繧ソ繧、繝溘Φ繧ー縺セ縺ァ蠕縺、 - while (phase != BUS::busfree) { + // 謾ケ陦梧枚蟄励r蜑企勁 + p[strlen(p) - 1] = 0; + + // 繝繝舌う繧ケ繝ェ繧ケ繝郁。ィ遉コ + if (xstrncasecmp(p, "list", 4) == 0) { + ListDevice(fp); + goto next; + } + + // 繝代Λ繝。繝シ繧ソ縺ョ蛻髮「 + argv[0] = p; + for (i = 1; i < 5; i++) { + // 繝代Λ繝。繝シ繧ソ蛟、繧偵せ繧ュ繝繝 + while (*p && (*p != ' ')) { + p++; + } + + // 繧ケ繝壹シ繧ケ繧誰ULL縺ォ鄂ョ謠 + while (*p && (*p == ' ')) { + *p++ = 0; + } + + // 繝代Λ繝。繝シ繧ソ繧定ヲ句、ア縺」縺 + if (!*p) { + break; + } + + // 繝代Λ繝。繝シ繧ソ縺ィ縺励※隱崎ュ + argv[i] = p; + } + + // 蜈ィ繝代Λ繝。繝シ繧ソ縺ョ蜿門セ怜、ア謨 + if (i < 5) { + goto next; + } + + // ID,繝ヲ繝九ャ繝,繧ウ繝槭Φ繝,繧ソ繧、繝,繝輔ぃ繧、繝ォ + id = atoi(argv[0]); + un = atoi(argv[1]); + cmd = atoi(argv[2]); + type = atoi(argv[3]); + file = argv[4]; + + // 繧「繧、繝峨Ν縺ォ縺ェ繧九∪縺ァ蠕縺、 + while (active) { usleep(500 * 1000); } - if (list) { - // 繝ェ繧ケ繝郁。ィ遉コ - ListDevice(fp); - } else { - // 繧ウ繝槭Φ繝牙ョ溯。 - ProcessCmd(fp, id, cmd, type, file); - } + // 繧ウ繝槭Φ繝牙ョ溯。 + ProcessCmd(fp, id, un, cmd, type, file); +next: // 謗・邯夊ァ」謾セ fclose(fp); close(fd); @@ -629,80 +967,125 @@ static void *MonThread(void *param) return NULL; } +#endif // BAREMETAL //--------------------------------------------------------------------------- // // 荳サ蜃ヲ逅 // //--------------------------------------------------------------------------- +#ifdef BAREMETAL +extern "C" +int startrascsi(void) +{ + int argc = 0; + char** argv = NULL; +#else int main(int argc, char* argv[]) { +#endif // BAREMETAL int i; - DWORD dwBusBak; - DWORD dwBusIn; + int ret; + int actid; + DWORD now; + BUS::phase_t phase; + BYTE data; +#ifndef BAREMETAL struct sched_param schparam; +#endif // BAREMETAL // 繝舌リ繝シ蜃コ蜉 - if (!Banner(argc, argv)) { - exit(0); - } + Banner(argc, argv); // 蛻晄悄蛹 + ret = 0; if (!Init()) { - fprintf(stderr, "Error : Initializing\n"); - - // 諱舌i縺俊oot縺ァ縺ッ辟。縺シ - exit(EPERM); + ret = EPERM; + goto init_exit; } - // 譌「縺ォ襍キ蜍輔@縺ヲ縺繧具シ - if (!bServer) { - fprintf(stderr, "Error : Already running RaSCSI\n"); - exit(0); - } - - // 讒狗ッ - if (!ParseArgument(argc, argv)) { - // 繧ッ繝ェ繝シ繝ウ繧「繝繝 - Cleanup(); - - // 蠑墓焚繧ィ繝ゥ繝シ縺ァ邨ゆコ - exit(EINVAL); - } - - // 繝「繝九ち繝シ繧ケ繝ャ繝繝臥函謌 - bRun = TRUE; - pthread_create(&monthread, NULL, MonThread, NULL); - // 繝ェ繧サ繝繝 Reset(); - // 繝。繧、繝ウ繝ォ繝シ繝玲コ門y - phase = BUS::busfree; - dwBusBak = bus.Aquire(); +#ifdef BAREMETAL + // BUSY繧「繧オ繝シ繝(繝帙せ繝亥エ繧貞セ縺溘○繧九◆繧) + bus->SetBSY(TRUE); +#endif + + // 蠑墓焚蜃ヲ逅 + if (!ParseArgument(argc, argv)) { + ret = EINVAL; + goto err_exit; + } + +#ifdef BAREMETAL + // BUSY繝阪ご繝シ繝(繝帙せ繝亥エ繧貞セ縺溘○繧九◆繧) + bus->SetBSY(FALSE); +#endif + +#ifndef BAREMETAL + // CPU繧貞崋螳 + FixCpu(3); + +#ifdef USE_SEL_EVENT_ENABLE + // 繧ケ繧ア繧ク繝・繝シ繝ェ繝ウ繧ー繝昴Μ繧キ繝シ險ュ螳(譛蜆ェ蜈) + schparam.sched_priority = sched_get_priority_max(SCHED_FIFO); + sched_setscheduler(0, SCHED_FIFO, &schparam); +#endif // USE_SEL_EVENT_ENABLE +#endif // BAREMETAL + + // 螳溯。碁幕蟋 + running = TRUE; // 繝。繧、繝ウ繝ォ繝シ繝 - while(bRun) { - // 繝舌せ縺ョ蜈・蜉帑ソ。蜿キ螟牙喧讀懷コ - dwBusIn = bus.Aquire(); + while (running) { + // 繝ッ繝シ繧ッ蛻晄悄蛹 + actid = -1; + phase = BUS::busfree; - // 蜈・蜉帑ソ。蜿キ螟牙喧讀懷コ - if ((dwBusIn & GPIO_INEDGE) == (dwBusBak & GPIO_INEDGE)) { - usleep(0); +#ifdef USE_SEL_EVENT_ENABLE + // SEL菫。蜿キ繝昴シ繝ェ繝ウ繧ー + if (bus->PollSelectEvent() < 0) { + // 蜑イ繧願セシ縺ソ縺ァ蛛懈ュ「 + if (errno == EINTR) { + break; + } continue; } - // 繝舌せ縺ョ蜈・蜉帑ソ。蜿キ繧剃ソ晏ュ - dwBusBak = dwBusIn; + // 繝舌せ縺ョ迥カ諷句叙蠕 + bus->Aquire(); +#else + bus->Aquire(); + if (!bus->GetSEL()) { +#if !defined(BAREMETAL) + usleep(0); +#endif // !BAREMETAL + continue; + } +#endif // USE_SEL_EVENT_ENABLE - // 縺昴b縺昴b繧サ繝ャ繧ッ繧キ繝ァ繝ウ菫。蜿キ縺檎┌縺代l縺ー辟。隕 - if (!bus.GetSEL() || bus.GetBSY()) { + // 繧、繝九す繧ィ繝シ繧ソ縺栗D險ュ螳壻クュ縺ォ繧「繧オ繝シ繝医@縺ヲ縺繧 + // 蜿ッ閭ス諤ァ縺後≠繧九ョ縺ァBSY縺瑚ァ」髯、縺輔l繧九∪縺ァ蠕縺、(譛螟ァ3遘) + if (bus->GetBSY()) { + now = SysTimer::GetTimerLow(); + while ((SysTimer::GetTimerLow() - now) < 3 * 1000 * 1000) { + bus->Aquire(); + if (!bus->GetBSY()) { + break; + } + } + } + + // 繝薙ず繝シ縲√∪縺溘ッ莉悶ョ繝繝舌う繧ケ縺悟ソ懃ュ斐@縺溘ョ縺ァ豁「繧√k + if (bus->GetBSY() || !bus->GetSEL()) { continue; } // 蜈ィ繧ウ繝ウ繝医Ο繝シ繝ゥ縺ォ騾夂衍 + data = bus->GetDAT(); for (i = 0; i < CtrlMax; i++) { - if (!ctrl[i]) { + if (!ctrl[i] || (data & (1 << i)) == 0) { continue; } @@ -723,13 +1106,16 @@ int main(int argc, char* argv[]) } // 繧ソ繝シ繧イ繝繝郁オー陦碁幕蟋 + active = TRUE; +#if !defined(USE_SEL_EVENT_ENABLE) && !defined(BAREMETAL) // 繧ケ繧ア繧ク繝・繝シ繝ェ繝ウ繧ー繝昴Μ繧キ繝シ險ュ螳(譛蜆ェ蜈) schparam.sched_priority = sched_get_priority_max(SCHED_FIFO); sched_setscheduler(0, SCHED_FIFO, &schparam); +#endif // !USE_SEL_EVENT_ENABLE && !BAREMETAL // 繝舌せ繝輔Μ繝シ縺ォ縺ェ繧九∪縺ァ繝ォ繝シ繝 - while (bRun) { + while (running) { // 繧ソ繝シ繧イ繝繝磯ァ蜍 phase = ctrl[actid]->Process(); @@ -739,20 +1125,24 @@ int main(int argc, char* argv[]) } } - // 繝舌せ繝輔Μ繝シ縺ァ繧サ繝繧キ繝ァ繝ウ邨ゆコ - actid = -1; - phase = BUS::busfree; - bus.Reset(); - dwBusBak = bus.Aquire(); - +#if !defined(USE_SEL_EVENT_ENABLE) && !defined(BAREMETAL) // 繧ケ繧ア繧ク繝・繝シ繝ェ繝ウ繧ー繝昴Μ繧キ繝シ險ュ螳(繝弱シ繝槭Ν) schparam.sched_priority = 0; sched_setscheduler(0, SCHED_OTHER, &schparam); +#endif // !USE_SEL_EVENT_ENABLE && !BAREMETAL + + // 繧ソ繝シ繧イ繝繝郁オー陦檎オゆコ + active = FALSE; } +err_exit: // 繧ッ繝ェ繝シ繝ウ繧「繝繝 Cleanup(); - // 邨ゆコ - exit(0); +init_exit: +#if !defined(BAREMETAL) + exit(ret); +#else + return ret; +#endif // BAREMETAL } diff --git a/src/raspberrypi/rasctl.cpp b/src/raspberrypi/rasctl.cpp index 3759ce8d..75a9d407 100644 --- a/src/raspberrypi/rasctl.cpp +++ b/src/raspberrypi/rasctl.cpp @@ -4,7 +4,7 @@ // for Raspberry Pi // // 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 id; + int un; int cmd; int type; char *file; @@ -74,6 +75,7 @@ int main(int argc, char* argv[]) char buf[BUFSIZ]; id = -1; + un = 0; cmd = -1; type = -1; file = NULL; @@ -83,10 +85,11 @@ int main(int argc, char* argv[]) if (argc < 2) { fprintf(stderr, "SCSI Target Emulator RaSCSI Controller\n"); 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]); 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, " FILE := image file path\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; - 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) { case 'i': id = optarg[0] - '0'; break; + case 'u': + un = optarg[0] - '0'; + break; + case 'c': switch (optarg[0]) { case 'a': // ATTACH @@ -174,6 +181,12 @@ int main(int argc, char* argv[]) exit(EINVAL); } + // 繝ヲ繝九ャ繝医メ繧ァ繝繧ッ + if (un < 0 || un > 1) { + fprintf(stderr, "Error : Invalid UNIT\n"); + exit(EINVAL); + } + // 繧ウ繝槭Φ繝峨メ繧ァ繝繧ッ if (cmd < 0) { cmd = 0; // 繝繝輔か繝ォ繝医ッATTATCH縺ィ縺吶k @@ -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)) { exit(ENOTCONN); } diff --git a/src/raspberrypi/rasdump.cpp b/src/raspberrypi/rasdump.cpp index c1ceef53..bf199545 100644 --- a/src/raspberrypi/rasdump.cpp +++ b/src/raspberrypi/rasdump.cpp @@ -4,7 +4,7 @@ // for Raspberry Pi // // Powered by XM6 TypeG Technology. -// Copyright (C) 2016-2018 GIMONS +// Copyright (C) 2016-2020 GIMONS // [ HDD繝繝ウ繝励Θ繝シ繝繧」繝ェ繝繧」(繧、繝九す繝シ繧ィ繧ソ繝「繝シ繝) ] // //--------------------------------------------------------------------------- @@ -207,29 +207,15 @@ BOOL ParseArgument(int argc, char* argv[]) //--------------------------------------------------------------------------- BOOL WaitPhase(BUS::phase_t phase) { - int count; + DWORD now; - // REQ繧貞セ縺、(6遘) - count = 30000; - do { - usleep(200); + // 繧ソ繧、繝繧「繧ヲ繝(3000ms) + now = SysTimer::GetTimerLow(); + while ((SysTimer::GetTimerLow() - now) < 3 * 1000 * 1000) { bus.Aquire(); - if (bus.GetREQ()) { - break; + if (bus.GetREQ() && bus.GetPhase() == phase) { + return TRUE; } - } while (count--); - - // 繝輔ぉ繝シ繧コ縺御ク閾エ縺吶l縺ーOK - bus.Aquire(); - if (bus.GetPhase() == phase) { - return TRUE; - } - - // 繝輔ぉ繝シ繧コ縺御ク閾エ縺吶l縺ーOK(繝ェ繝医Λ繧、) - usleep(1000 * 1000); - bus.Aquire(); - if (bus.GetPhase() == phase) { - return TRUE; } return FALSE; @@ -242,6 +228,7 @@ BOOL WaitPhase(BUS::phase_t phase) //--------------------------------------------------------------------------- void BusFree() { + // 繝舌せ繝ェ繧サ繝繝 bus.Reset(); } @@ -312,8 +299,6 @@ BOOL Command(BYTE *buf, int length) //--------------------------------------------------------------------------- int DataIn(BYTE *buf, int length) { - int count; - // 繝輔ぉ繝シ繧コ蠕縺。 if (!WaitPhase(BUS::datain)) { return -1; @@ -330,8 +315,6 @@ int DataIn(BYTE *buf, int length) //--------------------------------------------------------------------------- int DataOut(BYTE *buf, int length) { - int count; - // 繝輔ぉ繝シ繧コ蠕縺。 if (!WaitPhase(BUS::dataout)) { return -1; @@ -444,6 +427,7 @@ int RequestSense(int id, BYTE *buf) // 邨先棡繧ウ繝シ繝牙晄悄蛹 result = 0; + count = 0; // SELECTION if (!Selection(id)) { @@ -461,7 +445,7 @@ int RequestSense(int id, BYTE *buf) } // DATAIN - memset(buf, 0x00, sizeof(buf)); + memset(buf, 0x00, 256); count = DataIn(buf, 256); if (count <= 0) { result = -3; @@ -504,6 +488,7 @@ int ModeSense(int id, BYTE *buf) // 邨先棡繧ウ繝シ繝牙晄悄蛹 result = 0; + count = 0; // SELECTION if (!Selection(id)) { @@ -522,7 +507,7 @@ int ModeSense(int id, BYTE *buf) } // DATAIN - memset(buf, 0x00, sizeof(buf)); + memset(buf, 0x00, 256); count = DataIn(buf, 256); if (count <= 0) { result = -3; @@ -565,6 +550,7 @@ int Inquiry(int id, BYTE *buf) // 邨先棡繧ウ繝シ繝牙晄悄蛹 result = 0; + count = 0; // SELECTION if (!Selection(id)) { @@ -582,8 +568,8 @@ int Inquiry(int id, BYTE *buf) } // DATAIN - memset(buf, 0x00, sizeof(buf)); - count = DataIn(buf, 255); + memset(buf, 0x00, 256); + count = DataIn(buf, 256); if (count <= 0) { result = -3; goto exit; @@ -625,6 +611,7 @@ int ReadCapacity(int id, BYTE *buf) // 邨先棡繧ウ繝シ繝牙晄悄蛹 result = 0; + count = 0; // SELECTION if (!Selection(id)) { @@ -641,7 +628,7 @@ int ReadCapacity(int id, BYTE *buf) } // DATAIN - memset(buf, 0x00, sizeof(buf)); + memset(buf, 0x00, 8); count = DataIn(buf, 8); if (count <= 0) { result = -3; @@ -684,6 +671,7 @@ int Read10(int id, DWORD bstart, DWORD blength, DWORD length, BYTE *buf) // 邨先棡繧ウ繝シ繝牙晄悄蛹 result = 0; + count = 0; // SELECTION if (!Selection(id)) { @@ -748,6 +736,7 @@ int Write10(int id, DWORD bstart, DWORD blength, DWORD length, BYTE *buf) // 邨先棡繧ウ繝シ繝牙晄悄蛹 result = 0; + count = 0; // SELECTION if (!Selection(id)) { @@ -815,7 +804,6 @@ int main(int argc, char* argv[]) DWORD duni; DWORD dsiz; DWORD dnum; - DWORD rest; Fileio fio; Fileio::OpenMode omode; off64_t size; @@ -918,18 +906,21 @@ int main(int argc, char* argv[]) (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3]; bnum++; - printf("Number of blocks : %d Blocks\n", bnum); - printf("Block length : %d Bytes\n", bsiz); + printf("Number of blocks : %d Blocks\n", (int)bnum); + printf("Block length : %d Bytes\n", (int)bsiz); printf("Unit Capacity : %d MBytes %d Bytes\n", - bsiz * bnum / 1024 / 1024, - bsiz * bnum); + (int)(bsiz * bnum / 1024 / 1024), + (int)(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 isn't equal to disk 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"); } @@ -947,12 +938,15 @@ int main(int argc, char* argv[]) printf("Dump progress : "); } - for (i = 0; i < dnum; i++) { + for (i = 0; i < (int)dnum; i++) { if (i > 0) { printf("\033[21D"); 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); if (restore) { @@ -974,13 +968,18 @@ int main(int argc, char* argv[]) 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)) { - Write10(targetid, i * duni, duni, dsiz, buffer); + Write10(targetid, i * duni, dnum, dsiz, buffer); } } else { if (Read10(targetid, i * duni, dnum, dsiz, buffer) >= 0) { @@ -990,9 +989,7 @@ int main(int argc, char* argv[]) } // 螳御コ繝。繝繧サ繝シ繧ク - printf("\033[21D"); - printf("\033[0K"); - printf("%3d\%(%7d/%7d)\n", 100, bnum, bnum); + printf("%3d%%(%7d/%7d)\n", 100, (int)bnum, (int)bnum); cleanup_exit: // 繝輔ぃ繧、繝ォ繧ッ繝ュ繝シ繧コ diff --git a/src/raspberrypi/sasidump.cpp b/src/raspberrypi/sasidump.cpp new file mode 100644 index 00000000..4a7b9724 --- /dev/null +++ b/src/raspberrypi/sasidump.cpp @@ -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縺舌i縺縺九↑縺 + +//--------------------------------------------------------------------------- +// +// 螟画焚螳」險 +// +//--------------------------------------------------------------------------- +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() +{ + // 繝舌せ菫。蜿キ邱壹r繝ェ繧サ繝繝 + 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(); + + // 謌仙粥縺ァ縺ゅl縺ー霆「騾∵焚繧定ソ斐☆ + 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(); + + // 謌仙粥縺ァ縺ゅl縺ー霆「騾∵焚繧定ソ斐☆ + 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(); + + // 謌仙粥縺ァ縺ゅl縺ー霆「騾∵焚繧定ソ斐☆ + 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"); + + // 諱舌i縺俊oot縺ァ縺ッ辟。縺シ + 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); +} diff --git a/src/raspberrypi/scsi.cpp b/src/raspberrypi/scsi.cpp index b74e5aa6..914472d1 100644 --- a/src/raspberrypi/scsi.cpp +++ b/src/raspberrypi/scsi.cpp @@ -3,7 +3,7 @@ // X68000 EMULATOR "XM6" // // Copyright (C) 2001-2006 シーシゥシ(ytanaka@ipc-tokai.or.jp) -// Copyright (C) 2014-2018 GIMONS +// Copyright (C) 2014-2020 GIMONS // // [ SCSI蜈ア騾 ] // diff --git a/src/raspberrypi/scsi.h b/src/raspberrypi/scsi.h index 5bed1f73..b4d987dd 100644 --- a/src/raspberrypi/scsi.h +++ b/src/raspberrypi/scsi.h @@ -3,7 +3,7 @@ // X68000 EMULATOR "XM6" // // Copyright (C) 2001-2006 シーシゥシ(ytanaka@ipc-tokai.or.jp) -// Copyright (C) 2014-2018 GIMONS +// Copyright (C) 2014-2020 GIMONS // // [ SCSI蜈ア騾 ] // @@ -111,15 +111,16 @@ public: // 繝繝シ繧ソ繧キ繧ー繝翫Ν蜿門セ 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 SendHandShake(BYTE *buf, int count) = 0; // 繝繝シ繧ソ騾∽ソ。繝上Φ繝峨す繧ァ繧、繧ッ - virtual void FASTCALL SleepNsec(DWORD nsec) = 0; - // 繝翫ヮ遘貞腰菴阪ョ繧ケ繝ェ繝シ繝 - private: static const phase_t phase_table[8]; // 繝輔ぉ繝シ繧コ繝繝シ繝悶Ν diff --git a/src/raspberrypi/xm6.h b/src/raspberrypi/xm6.h index cdd09a2c..6ebda50d 100644 --- a/src/raspberrypi/xm6.h +++ b/src/raspberrypi/xm6.h @@ -4,7 +4,7 @@ // for Raspberry Pi // // Powered by XM6 TypeG Technology. -// Copyright (C) 2016-2018 GIMONS +// Copyright (C) 2016-2020 GIMONS // // [ 蜈ア騾壼ョ夂セゥ ] // @@ -18,7 +18,7 @@ // 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 USE_SEL_EVENT_ENABLE // SEL菫。蜿キ繧偵う繝吶Φ繝医〒繝√ぉ繝繧ッ縺吶k +#define REMOVE_FIXED_SASIHD_SIZE // SASIHD縺ョ繧オ繧、繧コ蛻カ髯舌r隗」髯、縺吶k +#define USE_MZ1F23_1024_SUPPORT // MZ-1F23(SASI 20M/繧サ繧ッ繧ソ繧オ繧、繧コ1024) + //--------------------------------------------------------------------------- // // 繧ッ繝ゥ繧ケ螳」險 diff --git a/src/x68k/RASDRV/BRIDGE.C b/src/x68k/RASDRV/BRIDGE.C index cf0f9918..1ecce912 100644 --- a/src/x68k/RASDRV/BRIDGE.C +++ b/src/x68k/RASDRV/BRIDGE.C @@ -852,6 +852,28 @@ int FS_GetCapacity(capacity_t* cap) //--------------------------------------------------------------------------- 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]; DWORD *dp; int i; @@ -865,6 +887,7 @@ int FS_CtrlDrive(ctrldrive_t* pCtrlDrive) i += 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() { +#if 1 + // 未サポート + return 0; +#else BYTE buf[256]; DWORD *dp; @@ -969,6 +996,7 @@ int FS_Flush() *dp = unit; return SCSI_SendCmd(buf, 4); +#endif } //--------------------------------------------------------------------------- @@ -978,6 +1006,10 @@ int FS_Flush() //--------------------------------------------------------------------------- int FS_CheckMedia() { +#if 1 + // 負荷が高いので暫定処理 + return 0; +#else BYTE buf[256]; DWORD *dp; @@ -985,6 +1017,7 @@ int FS_CheckMedia() *dp = unit; return SCSI_SendCmd(buf, 4); +#endif } //--------------------------------------------------------------------------- @@ -994,6 +1027,10 @@ int FS_CheckMedia() //--------------------------------------------------------------------------- int FS_Lock() { +#if 1 + // 未サポート + return 0; +#else BYTE buf[256]; DWORD *dp; @@ -1001,6 +1038,7 @@ int FS_Lock() *dp = unit; return SCSI_SendCmd(buf, 4); +#endif } //=========================================================================== @@ -2277,25 +2315,11 @@ DWORD Flush(void) //--------------------------------------------------------------------------- DWORD CheckMedia(void) { -#if 1 - static DWORD last = 0; - DWORD now; -#endif int nResult; ASSERT(this); ASSERT(fs); -#if 1 - // 連続で呼び出されるの回避する - now = TIMEGET(); - if ((now - last) < 3) { - return 0; - } else { - last = now; - } -#endif - // ファイルシステム呼び出し nResult = FS_CheckMedia(); @@ -2366,17 +2390,9 @@ DWORD ExecuteCommand() case 0x53: return DiskRead(); // $53 - セクタ読み込み case 0x54: return DiskWrite(); // $54 - セクタ書き込み case 0x55: return Ioctrl(); // $55 - IOCTRL -#if 0 case 0x56: return Flush(); // $56 - フラッシュ -#else - case 0x56: return 0; // $56 - フラッシュ -#endif case 0x57: return CheckMedia(); // $57 - メディア交換チェック -#if 0 case 0x58: return Lock(); // $58 - 排他制御 -#else - case 0x58: return 0; // $58 - 排他制御 -#endif } return FS_FATAL_INVALIDCOMMAND; diff --git a/src/x68k/RASDRV/RASDRV.S b/src/x68k/RASDRV/RASDRV.S index 4bd36f1e..6cb28b1e 100644 --- a/src/x68k/RASDRV/RASDRV.S +++ b/src/x68k/RASDRV/RASDRV.S @@ -4,7 +4,7 @@ * for Raspberry Pi * * Powered by XM6 TypeG Technorogy. -* Copyright (C) 2016-2017 GIMONS +* Copyright (C) 2016-2019 GIMONS * [ ホストファイルシステム ブリッジドライバ ] * * Based on @@ -165,7 +165,7 @@ MESSAGE_DRIVENAME3: MESSAGE_TITLE: DC.B $0D,$0A 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: diff --git a/src/x68k/RASDRV/RASDRV.TXT b/src/x68k/RASDRV/RASDRV.TXT index cbb094e2..f3404ca2 100644 --- a/src/x68k/RASDRV/RASDRV.TXT +++ b/src/x68k/RASDRV/RASDRV.TXT @@ -1,5 +1,5 @@ RaSCSI ファイルシステムドライバ -RASDRV version 1.21 +RASDRV version 1.42 ■概要