ザビタン開発日記
2009 | 01
2008 | 01 | 02 | 06 | 12
2007 | 10 | 11 | 12
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にはコメントできません。
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
 
30日を過ぎたBlogにはコメントできません。

リンク元  (4)
(1) 

PopnupBlog V3 Denali created by Bluemoon inc.