雑記帳
ここはhideyosiの雑記帳です。テケトーに書き散らしてるだけなので間違っていたりとは普通にしてます。信用度は相当低いことをあらかじめご了承を。またご覧のようにWikiを使ってますが、hideyosi意外は書き込めません。
1: 2007-01-23 (火) 12:01:45 ソース バックアップ No.1 を復元して編集 現: 2024-01-06 (土) 22:39:09 ソース 編集
Line 13: Line 13:
  int p;   int p;
  char reza;   char reza;
 + 
   struct FIFO32 timerfifox;    struct FIFO32 timerfifox;
   struct TIMER *timerx;    struct TIMER *timerx;
   int timerbuf[128];    int timerbuf[128];
 + 
   fifo32_init(&timerfifox,128,timerbuf,0);    fifo32_init(&timerfifox,128,timerbuf,0);
 + 
   timerx = timer_alloc();    timerx = timer_alloc();
   timer_init(timerx,&timerfifox,128);    timer_init(timerx,&timerfifox,128);
   timer_settime(timerx,100);    timer_settime(timerx,100);
- +  
- +  
 + 
  //3秒待ち   //3秒待ち
     for(;;){      for(;;){
Line 31: Line 31:
     p = fifo32_get(&timerfifox);      p = fifo32_get(&timerfifox);
     if (counter == 0){break;}      if (counter == 0){break;}
 + 
     if( p == 128 ){      if( p == 128 ){
     sprintf(s, "Wait %dSec...\n",counter);      sprintf(s, "Wait %dSec...\n",counter);
Line 40: Line 40:
         io_sti();          io_sti();
  }   }
 + 
       io_sti();        io_sti();
 + 
  //0x03f4のチェック   //0x03f4のチェック
     sprintf(s, "Check 0x03f4");      sprintf(s, "Check 0x03f4");
     cons_putstr0(cons, s);      cons_putstr0(cons, s);
     cons_newline(cons);      cons_newline(cons);
 + 
  char a;   char a;
  a = io_in8(0x03f4);a = a & 0x11;   a = io_in8(0x03f4);a = a & 0x11;
Line 55: Line 55:
     cons_newline(cons);      cons_newline(cons);
  }   }
 + 
  //コマンドの送信   //コマンドの送信
     sprintf(s, "Start command send...");      sprintf(s, "Start command send...");
     cons_putstr0(cons, s);      cons_putstr0(cons, s);
     cons_newline(cons);      cons_newline(cons);
- +  
 + 
     while(io_in8(0x03f4) & 0xC0 != 0x80 ){}      while(io_in8(0x03f4) & 0xC0 != 0x80 ){}
     io_out8(0x03f5, 0x07);      io_out8(0x03f5, 0x07);
     sprintf(s, "Send 0x03f5 [0x07]\n");      sprintf(s, "Send 0x03f5 [0x07]\n");
     cons_putstr0(cons, s);      cons_putstr0(cons, s);
 + 
     while(io_in8(0x03f4) & 0xC0 != 0x80 ){}      while(io_in8(0x03f4) & 0xC0 != 0x80 ){}
 + 
     io_out8(0x03f5, 0x00);      io_out8(0x03f5, 0x00);
     sprintf(s, "Send 0x03f5 [0x00]\n");      sprintf(s, "Send 0x03f5 [0x00]\n");
     cons_putstr0(cons, s);      cons_putstr0(cons, s);
     //---------------------------------------      //---------------------------------------
- +  
 + 
     //DMAの初期化      //DMAの初期化
     io_out8(0x00d6, 0xc0); /* マスタのch0をカスケードモードに */      io_out8(0x00d6, 0xc0); /* マスタのch0をカスケードモードに */
     io_out8(0x00c0, 0x00); /* スレーブのDMAを許可 */      io_out8(0x00c0, 0x00); /* スレーブのDMAを許可 */
     io_out8(0x000a, 0x06); /* マスタのch2のDMAをマスク */      io_out8(0x000a, 0x06); /* マスタのch2のDMAをマスク */
 + 
     //読み込み用にセットアップ      //読み込み用にセットアップ
     //モード設定:デマンド・アドレス増加方向・メモリへの書き込み・ch2      //モード設定:デマンド・アドレス増加方向・メモリへの書き込み・ch2
Line 86: Line 86:
     io_out8(0x0005, 0xff);      io_out8(0x0005, 0xff);
     io_out8(0x0005, 1 * 2 - 1);      io_out8(0x0005, 1 * 2 - 1);
- +  
 + 
     /* メモリ番地の設定 */      /* メモリ番地の設定 */
     io_out8(0x0004, 0x000a0000 & 0xff);      io_out8(0x0004, 0x000a0000 & 0xff);
     io_out8(0x0004, (0x000a0000 >> 8) & 0xff);      io_out8(0x0004, (0x000a0000 >> 8) & 0xff);
     io_out8(0x0081, (0x000a0000 >> 16) & 0xff);      io_out8(0x0081, (0x000a0000 >> 16) & 0xff);
- +  
 + 
     io_out8(0x000a, 0x02); /* マスタのch2のDMAをマスク解除 */      io_out8(0x000a, 0x02); /* マスタのch2のDMAをマスク解除 */
 + 
     //読み込み用のFDCコマンド発行!      //読み込み用のFDCコマンド発行!
     //  (FDCへのコマンド送信開始)(FATの情報を)      //  (FDCへのコマンド送信開始)(FATの情報を)
 + 
     //E6] [H<<2] [C] [H] [S] [02] [12] [01] [FF] (INT)      //E6] [H<<2] [C] [H] [S] [02] [12] [01] [FF] (INT)
     //: [ST0] [ST1] [ST2] [C] [H] [S] [02]      //: [ST0] [ST1] [ST2] [C] [H] [S] [02]
 + 
     while(io_in8(0x03f4) & 0xC0 != 0x80 ){}      while(io_in8(0x03f4) & 0xC0 != 0x80 ){}
     io_out8(0x03f5, 0xE6);      io_out8(0x03f5, 0xE6);
     sprintf(s, "Send [E6],");      sprintf(s, "Send [E6],");
     cons_putstr0(cons, s);      cons_putstr0(cons, s);
 + 
     while(io_in8(0x03f4) & 0xC0 != 0x80 ){}      while(io_in8(0x03f4) & 0xC0 != 0x80 ){}
     io_out8(0x03f5, 0x00<<2);      io_out8(0x03f5, 0x00<<2);
     sprintf(s, "[0x00<<2],");      sprintf(s, "[0x00<<2],");
     cons_putstr0(cons, s);      cons_putstr0(cons, s);
 + 
     while(io_in8(0x03f4) & 0xC0 != 0x80 ){}      while(io_in8(0x03f4) & 0xC0 != 0x80 ){}
     io_out8(0x03f5, 0x01);      io_out8(0x03f5, 0x01);
     sprintf(s, "[0x01],");      sprintf(s, "[0x01],");
     cons_putstr0(cons, s);      cons_putstr0(cons, s);
 + 
     while(io_in8(0x03f4) & 0xC0 != 0x80 ){}      while(io_in8(0x03f4) & 0xC0 != 0x80 ){}
     io_out8(0x03f5, 0x00);      io_out8(0x03f5, 0x00);
     sprintf(s, "[0x00],");      sprintf(s, "[0x00],");
     cons_putstr0(cons, s);      cons_putstr0(cons, s);
 + 
     while(io_in8(0x03f4) & 0xC0 != 0x80 ){}      while(io_in8(0x03f4) & 0xC0 != 0x80 ){}
     io_out8(0x03f5, 0x01);      io_out8(0x03f5, 0x01);
     sprintf(s, "[0x01],");      sprintf(s, "[0x01],");
     cons_putstr0(cons, s);      cons_putstr0(cons, s);
 + 
     while(io_in8(0x03f4) & 0xC0 != 0x80 ){}      while(io_in8(0x03f4) & 0xC0 != 0x80 ){}
     io_out8(0x03f5, 0x02);      io_out8(0x03f5, 0x02);
     sprintf(s, "[0x02],");      sprintf(s, "[0x02],");
     cons_putstr0(cons, s);      cons_putstr0(cons, s);
 + 
     while(io_in8(0x03f4) & 0xC0 != 0x80 ){}      while(io_in8(0x03f4) & 0xC0 != 0x80 ){}
     io_out8(0x03f5, 0x12);      io_out8(0x03f5, 0x12);
     sprintf(s, "[0x12],");      sprintf(s, "[0x12],");
     cons_putstr0(cons, s);      cons_putstr0(cons, s);
 + 
     while(io_in8(0x03f4) & 0xC0 != 0x80 ){}      while(io_in8(0x03f4) & 0xC0 != 0x80 ){}
     io_out8(0x03f5, 0x01);      io_out8(0x03f5, 0x01);
     sprintf(s, "[0x01],");      sprintf(s, "[0x01],");
     cons_putstr0(cons, s);      cons_putstr0(cons, s);
 + 
     while(io_in8(0x03f4) & 0xC0 != 0x80 ){}      while(io_in8(0x03f4) & 0xC0 != 0x80 ){}
     io_out8(0x03f5, 0xFF);      io_out8(0x03f5, 0xFF);
     sprintf(s, "[0xFF]\n");      sprintf(s, "[0xFF]\n");
     cons_putstr0(cons, s);      cons_putstr0(cons, s);
 + 
     //  (FDCが実行)      //  (FDCが実行)
 + 
  //3秒待ち   //3秒待ち
     counter=3;      counter=3;
Line 155: Line 155:
     p = fifo32_get(&timerfifox);      p = fifo32_get(&timerfifox);
     if (counter == 0){break;}      if (counter == 0){break;}
 + 
     if( p == 128 ){      if( p == 128 ){
     sprintf(s, "Wait %dSec...\n",counter);      sprintf(s, "Wait %dSec...\n",counter);
Line 164: Line 164:
         io_sti();          io_sti();
  }   }
 + 
       io_sti();        io_sti();
- +  
 + 
     //  (FDCからのINT)      //  (FDCからのINT)
     sprintf(s, "Come on! INT!\n");      sprintf(s, "Come on! INT!\n");
     cons_putstr0(cons, s);      cons_putstr0(cons, s);
 + 
     //  (FDCからリザルトステータス読み取り)      //  (FDCからリザルトステータス読み取り)
 + 
     while(io_in8(0x03f4) & 0xC0 != 0xC0 ){}      while(io_in8(0x03f4) & 0xC0 != 0xC0 ){}
     reza = io_in8(0x03f5);      reza = io_in8(0x03f5);
     sprintf(s, "[ST0]&0xC0=%X,",reza & 0xC0);      sprintf(s, "[ST0]&0xC0=%X,",reza & 0xC0);
     cons_putstr0(cons, s);      cons_putstr0(cons, s);
 + 
     while(io_in8(0x03f4) & 0xC0 != 0xC0 ){}      while(io_in8(0x03f4) & 0xC0 != 0xC0 ){}
     reza = io_in8(0x03f5);      reza = io_in8(0x03f5);
     sprintf(s, "ST1=%X,",reza);      sprintf(s, "ST1=%X,",reza);
     cons_putstr0(cons, s);      cons_putstr0(cons, s);
 + 
     while(io_in8(0x03f4) & 0xC0 != 0xC0 ){}      while(io_in8(0x03f4) & 0xC0 != 0xC0 ){}
     reza = io_in8(0x03f5);      reza = io_in8(0x03f5);
     sprintf(s, "ST2=%X,",reza);      sprintf(s, "ST2=%X,",reza);
     cons_putstr0(cons, s);      cons_putstr0(cons, s);
 + 
     while(io_in8(0x03f4) & 0xC0 != 0xC0 ){}      while(io_in8(0x03f4) & 0xC0 != 0xC0 ){}
     reza = io_in8(0x03f5);      reza = io_in8(0x03f5);
     sprintf(s, "[C]=%X,",reza);      sprintf(s, "[C]=%X,",reza);
     cons_putstr0(cons, s);      cons_putstr0(cons, s);
 + 
     while(io_in8(0x03f4) & 0xC0 != 0xC0 ){}      while(io_in8(0x03f4) & 0xC0 != 0xC0 ){}
     reza = io_in8(0x03f5);      reza = io_in8(0x03f5);
     sprintf(s, "[H]=%X,",reza);      sprintf(s, "[H]=%X,",reza);
     cons_putstr0(cons, s);      cons_putstr0(cons, s);
 + 
     while(io_in8(0x03f4) & 0xC0 != 0xC0 ){}      while(io_in8(0x03f4) & 0xC0 != 0xC0 ){}
     reza = io_in8(0x03f5);      reza = io_in8(0x03f5);
     sprintf(s, "[S]=%X\n",reza);      sprintf(s, "[S]=%X\n",reza);
     cons_putstr0(cons, s);      cons_putstr0(cons, s);
 + 
     while(io_in8(0x03f4) & 0xC0 != 0xC0 ){}      while(io_in8(0x03f4) & 0xC0 != 0xC0 ){}
     reza = io_in8(0x03f5);      reza = io_in8(0x03f5);
Line 209: Line 209:
     cons_putstr0(cons, s);      cons_putstr0(cons, s);
   //-------------------------------------------    //-------------------------------------------
 + 
   //マスタのch2のDMAをマスク */    //マスタのch2のDMAをマスク */
   io_out8(0x000a, 0x06);    io_out8(0x000a, 0x06);
- +  
- +  
 + 
       char *vvv;        char *vvv;
       vvv = 0x000a0000;        vvv = 0x000a0000;
 + 
    for(;;){     for(;;){
      vvv++;       vvv++;
Line 224: Line 224:
      cons_putstr0(cons, s);       cons_putstr0(cons, s);
    }     }
 + 
     sprintf(s, "End...\n");      sprintf(s, "End...\n");
     cons_putstr0(cons, s);      cons_putstr0(cons, s);
- +  
- +  
 + 
       timer_free(&timerx);        timer_free(&timerx);
    return;     return;
 }  }
 /*---------------------*/  /*---------------------*/
 +
 +さて、じゃ、なんで前はうまくいかなかったのか?ってことだけど、
 +--送信コマンドを間違えていた <バカ
 +--DMAの設定をイマイチ理解していない
 +
 +まず、送信コマンド。2のコード見てもらえばわかるよね?。間違ってます・・・orz
 +
 +
 +さて、次にもう一個。DMACの設定部分。
 +
 +Kタンのサンプルで一番解らなかったのが、
 +
 + io_out8(0x0005, 0xff); io_out8(0x0005, セクタ数 * 2 - 1); /* バイト数の設定 */
 + io_out8(0x0004, 番地 & 0xff); io_out8(0x0004, (番地 >> 8) & 0xff);
 + io_out8(0x0081, (番地 >> 16) & 0xff); /* メモリ番地の設定 */
 +
 +この、セクタ数や番地のこと。
 +
 +これ、よーく考えてみて初めて意味がわかった。まず、io_out8ってことは、''全てのデータは8bit''だということ!
 +
 +そう。8bit。0x00〜0xFF(十進数で256) までしか設定できないわけ。
 +
 +「え?それじゃ、セクター(512)を設定したり、バッファのメモリ番地を0x000a0000に設定したりはできないの!?」
 +
 +と、こういう話になりますね?。
 +
 +ここらへんのレジスタは特殊で、同じレジスタに連続で2回とか書き込むと16bitや20bitと解釈してくれるという。エラク特殊な形なんですねぇ〜。(なーーんだ!)
 +
 +だから、もう一度上のサンプルを良く見ると、こんなふうに割れませんか?
 +
 + /* バイト数の設定 */
 + io_out8(0x0005, 0xff);
 + io_out8(0x0005, セクタ数 * 2 - 1);
 + 
 + /* メモリ番地の設定 */
 + io_out8(0x0004, 番地 & 0xff);
 + io_out8(0x0004, (番地 >> 8) & 0xff);
 + io_out8(0x0081, (番地 >> 16) & 0xff);
 +
 +そう。こうやって、一見無意味に複数回書き込んでいるのがまさにそれなんです。
 +
 +''さらに!!''。セクタ数や番地の後ろにあるヘンテコな計算式。これは、8bit以上になる各数値を自動的に8bitに切り出してくれる計算式なんですねぇ〜。
 +
 +じゃ、たとえば、セクターを一つだけ。DMAバッファを0x000a0000番地にして読み込みを行いたいとしましょう。
 +
 +セクター1個は通常512バイト。16進数にすると、0x0200になるよね。で、OS-Wikiの資料によると、
 +
 + データ転送はDMAのTC(ターミナルカウント)に依存しており、この仕様のために、カウント値は実際の転送量-1をセットする。
 +
 +とのことなので、ここは 0x0200 - 1 = 0x01FF をセットします。
 +
 +ほらね!!!
 + io_out8(0x0005, 0xFF);
 + io_out8(0x0005, 0x01);  <-  セクタ数(1個) * 2 - 1 = 1なので。
 +
 +同じくDMAバッファのメモリ番地の設定。DMAバッファは仕様上、0x00ffffff以下でないと設置できません。よーく見て。最大は0xffffffでしょ? つまり、8bit三回分だよね?
 +
 +今回の例。0x0a0000を設置したいとした場合、こうなる!
 +
 + io_out8(0x0004, 0x00);  <- 0x0a0000 & 0xff = 0
 + io_out8(0x0004, 0x00);  <- (0x0a0000 >> 8) & 0xff = 0
 + io_out8(0x0081, 0x0a);  <- (0x0a0000 >> 16) & 0xff = 0a
 +
 +ほらね。こういう書式になるわけ。ちょっと値を複雑にしてみるともっと解るよ。
 +
 + 例:0xa1b2c3 番地を設定したい場合
 + 
 + io_out8(0x0004, 0xc3);  <- 0xa1b2c3 & 0xff = c3
 + io_out8(0x0004, 0xb2);  <- (0xa1b2c3 >> 8) & 0xff = b2
 + io_out8(0x0081, 0xa1);  <- (0xa1b2c3 >> 16) & 0xff = a1
 +
 +これでもう、解ったでしょ〜? (^^