雑記帳
ここはhideyosiの雑記帳です。テケトーに書き散らしてるだけなので間違っていたりとは普通にしてます。信用度は相当低いことをあらかじめご了承を。またご覧のようにWikiを使ってますが、hideyosi意外は書き込めません。

FDを読んでみる実験

・・・まてよぉ??。ちょっと解ってきたぞ?

つまり基本的には

      ←-- 0x03f4 -----
   OS                       FDC
      ←-- 0x03f5 ---→

こういうことね?。

えーと。で、読み出せるポートがひとつか二つしかないので、そこにST0だのST1だのがくるわけか。(順番などで判断する) コマンドの成功失敗の判断は [ST0] & 0xc0 が 0x00 : コマンドの正常終了 とあるから ・・・

キタ━━━━(゚∀゚)━━━━ッ

あっきぃさんとこのWikiにヒントが! そうか! 割り込みのマスクをはずしてなかった!。これをはずしたら割り込みもやってきたぞ!。

・・・っということは、オイラの「あの読み方」は正しいということか! わかったぞ!

モーターの回転と停止の実験 anchor.png Edit

こんどはこんなコードで実験!

/*FDの実験*/
void cmd_fdtest(struct CONSOLE *cons)
{
 char s[30];
 char counter = 3;
 int p;

   struct FIFO32 timerfifox;
   struct TIMER *timerx;
   int timerbuf[128];

   fifo32_init(&timerfifox,128,timerbuf,0);

   timerx = timer_alloc();
   timer_init(timerx,&timerfifox,128);
   timer_settime(timerx,100);

  


 //3秒待ち
     for(;;){
       io_cli();
     p = fifo32_get(&timerfifox);
     if (counter == 0){break;}

     if( p == 128 ){
		sprintf(s, "Wait %dSec...\n",counter);
		cons_putstr0(cons, s);
	counter--;
	timer_settime(timerx,100);
   }
         io_sti();
 }
 
       io_sti();




 //0x03f4のチェック
     sprintf(s, "Check 0x03f4");
     cons_putstr0(cons, s);
     cons_newline(cons);

 char a;
 a = io_in8(0x03f4);a = a & 0x11;
 if ( a == 0 ) {
     sprintf(s, "OK! 0x03f4 & 0x11 is 0!");
     cons_putstr0(cons, s);
     cons_newline(cons);
 }

 //コマンドの送信
       sprintf(s, "Start command send...");
     cons_putstr0(cons, s);
     cons_newline(cons);


     while(io_in8(0x03f4) & 0xC0 != 0x80 ){}
     io_out8(0x03f5, 0x07);
     sprintf(s, "Send 0x03f5 [0x07]\n");
     cons_putstr0(cons, s);

     while(io_in8(0x03f4) & 0xC0 != 0x80 ){}

     io_out8(0x03f5, 0x00);
     sprintf(s, "Send 0x03f5 [0x00]\n");
     cons_putstr0(cons, s);

     //モーターの回転&実験
	
     io_out8(0x03f2, 0x1c);
     sprintf(s, "Morter Spin!\n");
     cons_putstr0(cons, s);
     //3秒待ち・・・

 //3秒待ち
     counter = 3;
     for(;;){
       io_cli();
     p = fifo32_get(&timerfifox);
     if (counter == 0){break;}

     if( p == 128 ){
		sprintf(s, "Wait %dSec...\n",counter);
		cons_putstr0(cons, s);
	counter--;
	timer_settime(timerx,100);
   }
         io_sti();
 }
 
       io_sti();


	//モーターストップ
     io_out8(0x03f2, 0x0c);
     sprintf(s, "Morter STOP!!!!!\n");
     cons_putstr0(cons, s);
  

      	timer_free(&timerx);

	return;
}
/*---------------------*/

うーむ。どうもうまくいなかいなぁ。エミュレータではモーターの回転のみとかはできない?それともプログラムに問題が???

いっそ、読み込みやっちゃおうか!!

読み込みのためには、まず

  • DMAの初期化
  • コマンド発行
  • 読み込み開始!
  • 読めたかどうかのチェック

と、こうなるね。ではさっそく・・・ えーと。解りやすいってことで、セクター19〜32を対象にしてみよう。(詳しくはここ見てね。

え〜っと。論理セクター19は、ヘッド0でシリンダが1、セクター1がそうだね。ええと、読み込み用のDMSは0x00000000〜0x00ffffffの中にしか取れないのかぁ・・・。ええとどこにしようかな?。とりあえず、P171のメモリマップでみると頭のほうが空いてるみたいだから、0x000A0000〜0x000B0000あたりにしておこうかな。

/*FDの実験*/
void cmd_fdtest(struct CONSOLE *cons)
{
 char s[30];
 char counter = 3;
 int p;
 char reza;

   struct FIFO32 timerfifox;
   struct TIMER *timerx;
   int timerbuf[128];

   fifo32_init(&timerfifox,128,timerbuf,0);

   timerx = timer_alloc();
   timer_init(timerx,&timerfifox,128);
   timer_settime(timerx,100);

  


 //3秒待ち
     for(;;){
       io_cli();
     p = fifo32_get(&timerfifox);
     if (counter == 0){break;}

     if( p == 128 ){
		sprintf(s, "Wait %dSec...\n",counter);
		cons_putstr0(cons, s);
	counter--;
	timer_settime(timerx,100);
   }
         io_sti();
 }
 
       io_sti();




  //0x03f4のチェック
     sprintf(s, "Check 0x03f4");
     cons_putstr0(cons, s);
     cons_newline(cons);

 char a;
 a = io_in8(0x03f4);a = a & 0x11;
 if ( a == 0 ) {
     sprintf(s, "OK! 0x03f4 & 0x11 is 0!");
     cons_putstr0(cons, s);
     cons_newline(cons);
 }

 //コマンドの送信
     sprintf(s, "Start command send...");
     cons_putstr0(cons, s);
     cons_newline(cons);


     while(io_in8(0x03f4) & 0xC0 != 0x80 ){}
     io_out8(0x03f5, 0x07);
     sprintf(s, "Send 0x03f5 [0x07]\n");
     cons_putstr0(cons, s);

     while(io_in8(0x03f4) & 0xC0 != 0x80 ){}

     io_out8(0x03f5, 0x00);
     sprintf(s, "Send 0x03f5 [0x00]\n");
     cons_putstr0(cons, s);
     //---------------------------------------


     //DMAの初期化
     io_out8(0x00d6, 0xc0); /* マスタのch0をカスケードモードに */
     io_out8(0x00c0, 0x00); /* スレーブのDMAを許可 */
     io_out8(0x000a, 0x06); /* マスタのch2のDMAをマスク */      

     //読み込み用にセットアップ
     //モード設定:デマンド・アドレス増加方向・メモリへの書き込み・ch2
     io_out8(0x000b, 0x06);
     // バイト数の設定 
     io_out8(0x0005, 0xff); io_out8(0x0005, 1 * 2 - 1);
     io_out8(0x0004, 0x000a0000 & 0xff);
     io_out8(0x0004, (0x000a0000 >> 8) & 0xff); 

     io_out8(0x0081, (0x000a0000 >> 16) & 0xff); /* メモリ番地の設定 */
     io_out8(0x000a, 0x02); /* マスタのch2のDMAをマスク解除 */

     //読み込み用のFDCコマンド発行!
     //  (FDCへのコマンド送信開始)(FATの情報を)
     
     //E6] [H<<2] [C] [H] [S] [02] [12] [01] [FF] (INT)
     //: [ST0] [ST1] [ST2] [C] [H] [S] [02]

     while(io_in8(0x03f4) & 0xC0 != 0x80 ){}
     io_out8(0x03f5, 0xE6);
     sprintf(s, "Send 0x03f5 [0xE6]\n");
     cons_putstr0(cons, s);

     while(io_in8(0x03f4) & 0xC0 != 0x80 ){}
     io_out8(0x03f5, 0x00<<2);
     sprintf(s, "Send 0x03f5 [0x00<<2]\n");
     cons_putstr0(cons, s);

     while(io_in8(0x03f4) & 0xC0 != 0x80 ){}
     io_out8(0x03f5, 0x01);
     sprintf(s, "Send 0x03f5 [0x01]\n");
     cons_putstr0(cons, s);

     while(io_in8(0x03f4) & 0xC0 != 0x80 ){}
     io_out8(0x03f5, 0x01);
     sprintf(s, "Send 0x03f5 [0x01]\n");
     cons_putstr0(cons, s);

     while(io_in8(0x03f4) & 0xC0 != 0x80 ){}
     io_out8(0x03f5, 0x02);
     sprintf(s, "Send 0x03f5 [0x02]\n");
     cons_putstr0(cons, s);

     while(io_in8(0x03f4) & 0xC0 != 0x80 ){}
     io_out8(0x03f5, 0x7F);
     sprintf(s, "Send 0x03f5 [0x7F]\n");
     cons_putstr0(cons, s);

     while(io_in8(0x03f4) & 0xC0 != 0x80 ){}
     io_out8(0x03f5, 0x12);
     sprintf(s, "Send 0x03f5 [0x12]\n");
     cons_putstr0(cons, s);

     while(io_in8(0x03f4) & 0xC0 != 0x80 ){}
     io_out8(0x03f5, 0xFF);
     sprintf(s, "Send 0x03f5 [0xFF]\n");
     cons_putstr0(cons, s);

     //  (FDCが実行)

 //3秒待ち
     counter=3;
     for(;;){
       io_cli();
     p = fifo32_get(&timerfifox);
     if (counter == 0){break;}

     if( p == 128 ){
		sprintf(s, "Wait %dSec...\n",counter);
		cons_putstr0(cons, s);
	counter--;
	timer_settime(timerx,100);
   }
         io_sti();
 }
 
       io_sti();


     //  (FDCからのINT)
		sprintf(s, "Come on! INT!\n");
		cons_putstr0(cons, s);

     //  (FDCからリザルトステータス読み取り)

     while(io_in8(0x03f4) & 0xC0 != 0xC0 ){}
     reza = io_in8(0x03f5);
     sprintf(s, "[ST0]&0xC0=%X,",reza & 0xC0);
     cons_putstr0(cons, s);

     while(io_in8(0x03f4) & 0xC0 != 0xC0 ){}
     reza = io_in8(0x03f5);
     sprintf(s, "ST1=%X,",reza);
     cons_putstr0(cons, s);

     while(io_in8(0x03f4) & 0xC0 != 0xC0 ){}
     reza = io_in8(0x03f5);
     sprintf(s, "ST2=%X,",reza);
     cons_putstr0(cons, s);

     while(io_in8(0x03f4) & 0xC0 != 0xC0 ){}
     reza = io_in8(0x03f5);
     sprintf(s, "[C]=%X,",reza);
     cons_putstr0(cons, s);

     while(io_in8(0x03f4) & 0xC0 != 0xC0 ){}
     reza = io_in8(0x03f5);
     sprintf(s, "[H]=%X,",reza);
     cons_putstr0(cons, s);

     while(io_in8(0x03f4) & 0xC0 != 0xC0 ){}
     reza = io_in8(0x03f5);
     sprintf(s, "[S]=%X\n",reza);
     cons_putstr0(cons, s);

     while(io_in8(0x03f4) & 0xC0 != 0xC0 ){}
     reza = io_in8(0x03f5);
     sprintf(s, "Last Code =  %X\n",reza);
     cons_putstr0(cons, s);
   //-------------------------------------------

   //マスタのch2のDMAをマスク */
   io_out8(0x000a, 0x06);

      	timer_free(&timerx);
	return;
}
/*---------------------*/

おぉぉぉ!!!  失敗っぽいけど、qemuから

FLOPPY ERROR: fdctrl_read_data: can't read data in CMD state

なるエラーが複数行きているぞ。とにもかくにも、反応はしているようだ。

そうなると怪しいのが、DMACの設定の辺りだと思うが・・・


最終更新: 2024-01-06 (土) 22:39:09 (JST) (101d) by