ザビタン開発日記
2009 | 01
2008 | 01 | 02 | 06 | 12
2007 | 10 | 11 | 12
2007年10月31日(水曜日)
19:55
FDアクセス:実機はアカン?
 
オイラのスットコドッコイな落とし穴で思わぬ回り道をしてしまったが
うっちゃんのおかげでやっとすこし戻ってこれた・・・

さて!
そうなると、再びお勉強の本筋に!
そう。現時点でイマイチ理解ができていない、「割り込み状態取得」である!

えーーーっと・・・・例のここに書いてあるこれかなぁ・・・

  • SEEK系のコマンドの実行が完了すると、割り込みでCPUに知らせてくる。CPUはExecution-Phaseでないときに割り込みを受け取ったら、速やかにSENSE INT STATUSで応じなければならない。これでST0をチェックして、状態遷移割り込みなのか、それともSEEK系の終了割り込みなのかを判断する。
  • 結局、SEEK系のコマンドは、SEEK終了を知らせる割り込みにCPUがSENSE INT STATUSで応じてST0とPCNをリードしおわった時点で、コマンドの実行が完了する(=やっとこのドライブ対して次のコマンドが発行可能になる)。


・・・よくわからないなぁ・・・
こういうことなのかな???

  • 割り込みには二種類ある。
  • 状態遷移割り込みとSEEK系終了割り込み
  • 割り込みが来た場合、その時点ではこの両者は区別できない
  • なので、割り込むが来たらすぐに[08]コマンドを発行してST0やCを読む必要がある
  • 帰ってきた[08]のリザルトにより、どっちの割り込みか判断できる
  • それがSEEK系終了の割り込みだったら一仕事終了。リザルトを受け取る作業に入る
  • ・・・では、状態遷移割り込みだったら??


そもそも、状態遷移割り込みとはどういう状況下で発生するのだろう???

たとえばだが、ヘッドを10シリンダにシークしたいとする。

     いろいろチェック(ステータスとかそういうの)
             ↓
      10Cにシークしろ!と命令(コマンド発行)
             ↓
      命令を受け取ったFDCは動作開始(時間がかかる)
             ↓
    FDC曰く、「できたよーー!」とお返事。(これがIRQ6の割り込み)
             ↓
     待ってたホイ!SEEKが終わったことが解った!
             ↓
    リザルトを取得し、本当にできてるかどうかチェック!
             ↓
     OKOK! 大丈夫みたいね。じゃ、次の指令をば・・・

この流れの中で、状態遷移割り込みという、SEEK終了ではない割り込みが来る!??
いったいなぜ? なんのために??


・・・な〜んて書いて、ちょっと一休みしてたら再び勇者うっちゃんが!! (^^

なるほどぉ!つまりこういうことなのかな?

  • 状態遷移割り込みとは本来はディスクの抜き差しを検出して発生する割り込みである
  • 割り込みは仕組み的にパラメータを持たせることができない。とにかく、「発生したぞ!」とだけ知らせることしかできない
  • そのため、割り込みが発生したらそれがSEEK終了なのかディスク抜き差しなのかを判断しなければいけない
  • そのため、FDC側では割り込みを発生させると同時に、「これはxxx割り込みだよ!」ということをレジスタに書き留めておくという動作をする。
  • ゆえに、プログラム側では割り込みが発生したら、仮にどっちの割り込みかを知りたくなくても「読み出す」という作業をしなくてはならない。(一連の動作のひとつとして組み込まれている手順?)
  • しかし、ディスクが動作(SEEK)している最中にディスクの抜き差しなど、普通発生するだろうか?
  • おそらく、「複数ドライブ対応ゆえ」なのだろう。
  • いまでこそ、AT互換機のFDは一基が当然だが、このFDCは能力として4台のドライブまで対応できる設計である。また、別にAT互換機用というものではない汎用的なものだ。
  • ディスクが複数台搭載されているような機械なら、当然A:ドライブで読み込みをしている最中にB:ドライブを抜くなどということは普通に発生が予想されるのだから。
  • ・・・しかし、現実問題として、うっちゃんが示してくれたページを読む限りでは、どうもこの便利な割り込みはAT互換機上では殺されているようである。
  • ・・・っということは、少なくともATでは、事実上状態遷移割り込みは発生しない・ありえないという理解でいいのだろうか?
  • ありえないが、とにかくこのFDCでは割り込みの後、[08]を発行してリザルトを2個取得しなくてはいけない。この手続きそのものまで殺されているわけではないという理解でいいのだろうか?



 
●uchan@ゲスト -- 10/31 20:42
こんなの発見http://osask.jp/boyaki01.html
●hideyosi -- 10/31 21:00
おぉぉぉ! こ・・・これは!! まさにこれですねぇ。はっはぁ〜。そうするとこういう考え方でいいのかな?

30日を過ぎたBlogにはコメントできません。

リンク元  (1)
19:49
FDアクセス:番外
 
ニョニョニョ〜〜〜!!
うっちゃんが須原歯科ヒントを!!

え!? まってまって? じゃ、いままでのwhileでひっかかるのもこれ?
その後のwhileも? じゃ、whileをみんなこのパターンにしてみると???

・・・
・・・・・・
・・・・・・・・・
キタ━━━━━━(゜∀゜)━━━━━━ !!!!!

いや〜・・・
我ながらこんなことも知らんで「OS作成」してるとは・・・

うっちゃんスマソ。ほんと感謝。わざわざURLまで。勉強しまする。
 
30日を過ぎたBlogにはコメントできません。
18:28
FDアクセス:再調査!
 
え”えぇぇぇぇぇ!??

なんかヘンだよ? おかしいよ?
こんどはこんなことしてみたんだけど

// while ( io_in8(0x03f4) & 0x10 != 0 ) {}
char aa;
for (;;)
{
aa = io_in8(0x03f4);
if ( aa & 0x10 == 0 )
{break;}
else
{
sprintf(s, "aa=%08x,%08x",aa,aa & 0x10);
putfonts8_asc_sht(sheet,8*20,16*2,COL8_008484,COL8_FFFFFF,s,20);

}
}

このforを抜け出せない!?
値はちゃんと、「aa=FFFFFF81,00000000」って出てるのに・・・0なのに・・・
ヽ( `Д´)ノ
 
●uchan@ゲスト -- 10/31 19:05
うろ覚えですが、if ( (aa & 0x10) == 0 )としないといけない気がしました。
●uchan@ゲスト -- 10/31 19:40
一応、演算子の優先順位表です。→http://www5c.biglobe.ne.jp/~ecb/c/05_10.html
●hideyosi -- 10/31 19:42
(゜∀゜) ・・・・

30日を過ぎたBlogにはコメントできません。

リンク元  (1)
16:50
FDアクセス:再調査!
 
例の「ひっかかり」の場所。
逆に場所が特定できているんだから、その時のステータスレジスタ(0x03f4)
の値がなにで、どういう状態なのかがこれで読み取れるかもしれない。

//割り込み状態取得
char aa;
aa = io_in8(0x03f4);
while(aa & 0x10 != 0x00 )  //←このwhileから抜け出せない
{
aa = io_in8(0x03f4);
sprintf(s, "aa=%08x",aa);
putfonts8_asc_sht(sheet,8*20,16*2,COL8_008484,COL8_FFFFFF,s,11);
}

こんなことして値を表示させてみたら「0x81」と表示された・・・

さて。0x81ってのはどういう状態なんだろう?。オベンキョしたことを踏まえて・・・

0x81すなわち10000001b。むむむうぅぅ???

  • ドライブ#0動作中
  • ドライブ#1非動作中
  • ドライブ#2非動作中
  • ドライブ#3非動作中
  • FDCはIdle-Phaseである
  • DMAモード?
  • データレジスタの書き込み待ちモード
  • データレジスタは準備完了だ!ドンと来い!


なるほどなるほど・・・・・って、え”

& 0x10 == 0 の待ちなんだから、bit4だけが0ならとりあえずは
ここは通過できるはず。なんで? なんで通過しないの!??
 
30日を過ぎたBlogにはコメントできません。
16:17
FDアクセス:FDCレジスタ
 
大マヌケをこいてしまったが、な〜に!いつものことさ!  orz

●コマンド発行前待ち
io_in8(0x03f4) & 0x11 の値が0になるのを待ちます
0x11すなわち00010001bによる摘出。bit0とbit4摘出ね。
・ドライブ#0が非動作中(bit0)
・FDCがidle-Phaseである(bit4)

ふむ!納得! 理屈どおりだよね?
(・・・でも、bit6やbit7は関係ないのかな???)

●コマンド[08]発行前待ち
io_in8(0x03f4) & 0x10 の値が0になるのを待ちます
0x10すなわち00010000bによる摘出。bit4のみかぁ・・・
・FDCがidle-Phaseである(bit4)

ん?っていうことは、仮にドライブ#0が動作中であってもいい。
もしくはどっちでもいいということかな???

●個々のコマンド送信前待ち
io_in8(0x03f4) & 0xc0 が 0x80 になるのを待つ
0xc0すなわち11000000bによる摘出。bit7とbit6ね。
さらにこれらが0x80なんだから10000000b。bit7が1で、かつ、bit6が0だと。
・データレジスタの準備ができている。いつでも来い!(bit7)
・書き込み待ちの状態(bit6)

・・・なっるほどぉ・・・。bit7やbit6はさっきは無視されたんじゃ
なくて、個別に別々に検査されるわけね。

●個々のリザルトの受信待ち
io_in8(0x03f4) & 0xc0 が 0xc0 になるのを待つ
0xc0すなわち11000000bによる摘出。bit7とbit6ね。
さらにこれらが0xc0なんだから11000000b。bit7、bit6共に1でいてほしいと。
・データレジスタの準備ができている。いつでも来い!(bit7)
・読まれ待ちの状態(bit6)

おおおおお!! なるほど! なんか理屈通りだ! よく解る!

・・・あれ? でも、ちょっと疑問があるなぁ。
リザルト受信を開始する前のチェックというか・・・「コマンド発行前待ち」みたいなチェックってないのかなぁ???

たとえばだけど、
●リザルト発行前待ち
io_in8(0x03f4) & 0x11 の値が0x10になるのを待ちます
0x11すなわち00010001bによる摘出。bit0とbit4摘出ね。
・ドライブ#0が非動作中(bit0) ・・・これはいらないかな?
・FDCがidle-Phase以外(Result-Phase)である(bit4) 

とか・・・・
 
30日を過ぎたBlogにはコメントできません。

リンク元  (3)
15:32
FDアクセス:FDCレジスタ
 
うーむ。どうもわからない。
ここで新しくいろいろと勉強してみたんだけど、いつものところ
まず io_in8(0x03f4) & 0x11 の値が0になるのを待ちます
とある。0x11すなわち00010001bでのAND演算。bit3とbit7の摘出となる。
しかし、資料によるとbit3はドライブ#3の動作状況を示すようだ。
bit0(ドライブ#0)ならまだわかるのだが・・・
また逆に、bit4が検査されていない理由がよくわからない。なんか
これは検査すべき部分のような気がしてならない。

他のものはどうだろうか・・・

●コマンド[08]発行時
io_in8(0x03f4) & 0x10 ==0を待つ。
これはええと・・・
やはりbit3だなぁ。

●コマンド送信待ち
io_in8(0x03f4) & 0xc0 が 0x80 になるのを待つ
bit0とbit1を摘出。その結果が0x80すなわち10000000bであってほしいと。
ドライブ#0が動作中で、かつドライブ#1は非動作中という状態を待っている・・・えぇ?

●リザルト受信前
io_in8(0x03f4) & 0xc0 が 0xc0 になるのを待つ
同じくbit0とbit1の摘出。0xc0すなわち11000000b待ち。
ドライブ#0とドライブ#1両方の動作状態を待つ・・・

・・・おっかしい! どう考えてもこれはおかしい!!

なにかオイラのほうで勘違いや読み違いしてる可能性が濃厚だ!
もう一回復習してみよう・・・

さっそくわかりました!/(^o^)?



bit0とかbit7とかの捕らえ方が、オイラ左右逆でした!


間違い                 正解  
bit0,bit1,bit2,bit2・・・bit7    bit7,bit6・・・bit2,bit1,bit0


全部やりなおし!

 
30日を過ぎたBlogにはコメントできません。
2007年10月30日(火曜日)
23:57
FDアクセス:番外
 
いままでここをベタ〜っと写していたのだがすこし意味などをお勉強。
資料を探していたら・・・あったあった!。ここ! ここ!
・・・でもやっぱしKタンのサイトなのね・・・(^^

うっわあぁぁぁ・・・・むずかしいなぁ。

とりあえずオイラお得意の「まず大雑把に法則化」といきますか!


  • FDCはステータスレジスタとデータレジスタがある
  • ステータス。これは基本的にはリードオンリー。文字通り「今の状態を示す」ためのものね。
  • データ。データとはいうが、「出入り口」と見るのがいいかな
  • データは書き込むことも読み込むこともするし、できる所。
  • 0x03f4がステータス。0x03f5がデータと。
  • ちなみにこれらは全て、8bit(0x00〜0xFF)のみのアクセスとなるので、ステータスから0x123が来たりデータに0x789を書き込んだりとかはない。
  • 念のため。0x03f5等はI/Oポートの番地ね。


ステータスレジスタ


現在、FDD、FDCがどういう状態なのか?を示す。
各ビットに意味がある。

bit4が0ならIdle-Phase
つまりこういう状態。

???0???

FDCに対してコマンドを発行したい場合、
「io_in8(0x03f4) & 0x11 の値が0になるのを待ちます」
とある。これはどういうことなのかというと、bit0とbit7以外は0である必要があるということ。

・・・・だめだなこりゃ。ここいらあたりにまとめよう。





 
30日を過ぎたBlogにはコメントできません。
23:21
FDアクセス:実機はアカン?
 
Kタンからアドバイスがあった。
・・・これはどういうことなのだろう?
オイラが参考にしているここによると、割り込み状態取得とある。
これはいったいなんなのだろう?。割り込みの後やらなければならないとある。
割り込みが発生した場合にはかならず一回行うことが前提となるもの
のようだ。もしかしてこのST0やもうひとつの戻り値であるCなどから
なにかを判断しなければいけないのだろうか?。
また、これはどんな場合でもIRQ6が発生した場合には行うべきこと
なのだろうか?
(たとえばシークでは必要だが書き込み時はいらないとかそういうの)

・・・まあとりあえず、一発実験してみる・・・
そう思ってこんなコードを書いたのだが

(実際には各行間にsprintを割り込ませて状態表示をしている)
//モーターON
fd_moter(1,&fdtime1);

//コマンド待ち
while(io_in8(0x03f4) & 0x11 != 0x00 ){}

while(io_in8(0x03f4) & 0xC0 != 0x80 ){}
io_out8(0x03f5, 0x07);

while(io_in8(0x03f4) & 0xC0 != 0x80 ){}
io_out8(0x03f5, 0x00);

while(fifo32_status(tfifo) == 0){}

err1 = fifo32_get(tfifo);

//割り込み状態取得
while(io_in8(0x03f4) & 0x10 != 0x00 ){} // ←(1)

while(io_in8(0x03f4) & 0xC0 != 0x80 ){}
io_out8(0x03f5, 0x08);

while(io_in8(0x03f4) & 0xC0 != 0xC0 ){}
err2 = io_in8(0x03f5); //ST0

while(io_in8(0x03f4) & 0xC0 != 0xC0 ){}
err2 = io_in8(0x03f5); //C

やはりどうもこの(1)あたりで引っかかってしまう。
「割り込みが来た瞬間」に必要なのかとも思い、inthandler26内に
仕込む等も行ってみたのだが、whileを抜け出せないようで固まって
しまうのと同じになってしまう。
(相変わらずQEMUではツルっと通過してくれるのだが)

やはりこれは、各コマンドやSTの意味などの資料を探さねばいけないかなぁ〜。
 
30日を過ぎたBlogにはコメントできません。
17:46
FDアクセス:実機はアカン?
 
まいったなぁ・・・
初心に戻ってと思い、こんなベタなコードを試してみたんだけど


int err1;
char s[40];

sprintf(s, "test=%02d",99);
putfonts8_asc_sht(sheet,8*20,16*3,COL8_008484,COL8_FFFFFF,s,7);

//モーターON
fd_moter(1,&fdtime1);

//コマンド待ち
while(io_in8(0x03f4) & 0x11 != 0x00 ){}

sprintf(s, "Phase=%02d",1);
putfonts8_asc_sht(sheet,8*8,16*3,COL8_008484,COL8_FFFFFF,s,8);

while(io_in8(0x03f4) & 0xC0 != 0x80 ){}
io_out8(0x03f5, 0x07);

sprintf(s, "Phase=%02d",2);
putfonts8_asc_sht(sheet,8*8,16*3,COL8_008484,COL8_FFFFFF,s,8);

while(io_in8(0x03f4) & 0xC0 != 0x80 ){}
io_out8(0x03f5, 0x00);

sprintf(s, "Phase=%02d",3);
putfonts8_asc_sht(sheet,8*8,16*3,COL8_008484,COL8_FFFFFF,s,8);

while(fifo32_status(tfifo) == 0){}

sprintf(s, "Phase=%02d",4);
putfonts8_asc_sht(sheet,8*8,16*3,COL8_008484,COL8_FFFFFF,s,8);

err1 = fifo32_get(tfifo);



sprintf(s, "test=%02d",err1);
putfonts8_asc_sht(sheet,8*20,16*3,COL8_008484,COL8_FFFFFF,s,7);

/*------------------- 1 -------------------------*/
//シーク
while(io_in8(0x03f4) & 0x11 != 0x00 ){}

sprintf(s, "Phase=%02d",11);
putfonts8_asc_sht(sheet,8*8,16*3,COL8_008484,COL8_FFFFFF,s,8);

while(io_in8(0x03f4) & 0xC0 != 0x80 ){}
io_out8(0x03f5, 0x0F);

sprintf(s, "Phase=%02d",12);
putfonts8_asc_sht(sheet,8*8,16*3,COL8_008484,COL8_FFFFFF,s,8);

while(io_in8(0x03f4) & 0xC0 != 0x80 ){}
io_out8(0x03f5, 0x00 << 2);

sprintf(s, "Phase=%02d",13);
putfonts8_asc_sht(sheet,8*8,16*3,COL8_008484,COL8_FFFFFF,s,8);

while(io_in8(0x03f4) & 0xC0 != 0x80 ){}
io_out8(0x03f5, 0x00);

sprintf(s, "Phase=%02d",14);
putfonts8_asc_sht(sheet,8*8,16*3,COL8_008484,COL8_FFFFFF,s,8);

while(fifo32_status(tfifo) == 0){}

sprintf(s, "Phase=%02d",15);
putfonts8_asc_sht(sheet,8*8,16*3,COL8_008484,COL8_FFFFFF,s,8);

err1 = fifo32_get(tfifo);



sprintf(s, "test=%02d",err1);
putfonts8_asc_sht(sheet,8*20,16*3,COL8_008484,COL8_FFFFFF,s,7);

実機A、実機B共に1のところで止まったキリになっちゃう・・・
(もちろんエミュではOKなのだが・・・)
 
●K@ゲスト -- 10/30 19:30
質問です。コマンド07を送っていますが、これはシリンダゼロへのシークとほぼ同じです。で、コマンド実行が終了するとIRQ06が発生していると思います。そのときに、ただちにコマンド08を発行して、IRQがおきた理由をFDCに問い合わせていますか?問い合わせなければいけません。

30日を過ぎたBlogにはコメントできません。

リンク元  (4)
13:34
FDアクセス:実機はアカン?
 
ちょっと変化がありました。

実機Aは相変わらずなんですが、実機Bで初めて「ぶっ!」っと音が出ました。

・・・実はオイラはこれまでシークやリセットは搭載していなかったんです。
もしかしてこれかなぁと思い、シークを搭載してみたら変化が。

読み取りコマンド前にシークやリセットを挟み込んでさらに実験・・・

むむむ・・・
実機Aではあいかわらずだが、実機Bではリザルトが0x40、つまりコマンドの
異常終了になるようになった。
これははたして進歩だろうか・・・orz・・・
 
30日を過ぎたBlogにはコメントできません。
(1) 2 3 4 5 6 7 » 

PopnupBlog V3 Denali created by Bluemoon inc.