ザビタン開発日記
2009 | 01
2008 | 01 | 02 | 06 | 12
2007 | 10 | 11 | 12
10月 30 (火曜日) 2007
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である必要があるということ。



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











 
name: @Guest  Comment:
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の意味などの資料を探さねばいけないかなぁ〜。
 
name: @Guest  Comment:
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@Guest -- 10/30 19:30
質問です。コマンド07を送っていますが、これはシリンダゼロへのシークとほぼ同じです。で、コマンド実行が終了するとIRQ06が発生していると思います。そのときに、ただちにコマンド08を発行して、IRQがおきた理由をFDCに問い合わせていますか?問い合わせなければいけません。

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



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



・・・実はオイラはこれまでシークやリセットは搭載していなかったんです。

もしかしてこれかなぁと思い、シークを搭載してみたら変化が。



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



むむむ・・・

実機Aではあいかわらずだが、実機Bではリザルトが0x40、つまりコマンドの

異常終了になるようになった。

これははたして進歩だろうか・・・orz・・・
 
name: @Guest  Comment:
09:41
FDアクセス:実機はアカン?
 
整理する。



オイラが書いたコード



qemu: リザルトは0x00

実機A(ダイナブックGT475):0x80

実機B(自作機・Celelon700):0xc0

VMWareイメージFD:0x00

VMWare実FD:0x00





コマンド間違い



意図的にコマンドを間違える。S(セクタ)をありえない数値(99)にしてみる



qemu: 0x40

実機A(ダイナブックGT475):0x80

実機B(自作機・Celelon700):0xc0

VMWareイメージFD:回復不能なエラーで落ちた

VMWare実FD:回復不能なエラーで落ちた





コマンド中抜き



意図的にコマンドのひとつを抜く。じゃ、02の送信を抜く



qemu: 0x00

実機A(ダイナブックGT475):0x80

実機B(自作機・Celelon700):0xc0

VMWareイメージFD:0xc0

VMWare実FD:0xc0





コマンド中抜き2



意図的にコマンドを抜く。02、さらに12も抜いてみるく



qemu: 0x00

実機A(ダイナブックGT475):0x80

実機B(自作機・Celelon700):0xc0

VMWareイメージFD:0x00

VMWare実FD:0x00





DMAを開けない



DMAを開ける関数を無効化



qemu: 0xc0

実機A(ダイナブックGT475):0x80

実機B(自作機・Celelon700):0xc0

VMWareイメージFD:回復不能なエラーで落ちた

VMWare実FD:回復不能なエラーで落ちた





DMAを開け、コマンドを送信しない



DMAを開ける関数を無効化



qemu: 0x00

実機A(ダイナブックGT475):0x00

実機B(自作機・Celelon700):0x00

VMWareイメージFD:回復不能なエラーで落ちた

VMWare実FD:回復不能なエラーで落ちた





DMAも開けず、コマンドも送信しない



DMAを開ける関数を無効化し、リードコマンドも送信しない



qemu: 0x00

実機A(ダイナブックGT475):0x00

実機B(自作機・Celelon700):0x00

VMWareイメージFD:回復不能なエラーで落ちた

VMWare実FD:回復不能なエラーで落ちた



分析してみる・・・(ノД`)・・・



  • エミュはかなりアテにならない

  • リザルトは機種により違いが出てしまうようだ

  • DMAの開け閉めそのものはリザルトには影響しない

  • コマンドを送信しなければ0x00なので、リザルトがこれ以外になる(エラー系)のはやはりコマンドになにか問題があると予測される



新たな疑問。

この実験では実機の場合、なにも送信しなければ0x00である。

・・・っということは、0x08なり0x0cなりになるのはどの時点か?





実機A:[0x03f4待ち] [E6] [H<<2] [C] [H] [S] [02] [12] [01] [FF]

00 c0 80 ・・・・・・・・・・・・



実機A:[0x03f4待ち] [E6] [H<<2] [C] [H] [S] [02] [12] [01] [FF]

00 c0 ・・・・・・・



リビジョン52
 
name: @Guest  Comment:
Referer  (4)
(1) 

PopnupBlog V3 Denali created by Bluemoon inc.