*FDCドライバもどき・書きかけ
-眺めるだけですよ。実行は超危険です。FDDのモーターが壊れるかもしれません。
-実行はちょっと危険です。
-うちの環境ではまぁ動きますが、もしFDDのモーターが壊れたりしても責任は負いかねます。

**めも
***必要なFIFOバッファ
+「各タスクからfdc_taskにコマンドを送るため」と、「タイマー用」のFIFOバッファ
--コマンド処理後にタイマーを発効する。
--新しいコマンドがきたら中断、来なかったらモーターOFF
+割り込みを受け取るFIFOバッファ
--コイツはちょっとトクベツだ。

***セクタ番号からシリンダ・ヘッド・セクタを計算する
割り算の結果は、小数点以下切捨てで。
-シリンダ
 C = セクタ番号 / 36
-ヘッド
 H = (セクタ番号 - C * 2) / 18
-セクタ
 S = セクタ番号 - C - H + 1

**そーす
+INT06の割り込みがくるようにソース書き換え。
+bootpack.cの最初のほうに張る。
 /* <fdc.c> */
 
 struct FIFO32 *fdc_fifo;
 struct TASK *task_fdc;
 struct FDC_STAT {
     int motorman;
     int result, cylinder;
 } fdc_stat;
 
 void inthandler26(int *esp)
 /* FDCからの割り込み */
 {
     io_in8(0x03f4); /* から読み:IRQにCPUが気づいたことをFDCへ教えてあげる */
     io_out8(PIC0_OCW2, 0x66); /* IRQ-06を終了 */
     fifo32_put(&task_fdc->fifo, 3);
     fifo32_put(fdc_fifo, 3);
     return;
 }
 
 void motor_on(void)
 {
     struct TIMER *timer;
     struct FIFO32 fifo;
     int fifo_buf[32];
     fifo32_init(&fifo, 32, fifo_buf, task_fdc);
     timer = timer_alloc();
     timer_init(timer, &fifo, 1);
 
     if (fdc_stat.motorman == 0) {
         /* モーターON */
         io_out8(0x03f2, 0x1c);
         timer_settime(timer, 125);
         while (fifo32_status(&fifo) == 0) { task_sleep(task_fdc); }
         fifo32_get(&fifo);  // 空読み
         fdc_stat.motorman = 1;
     }
     return;
 }
 
 void fdc_sendcommand(int data)
 {
     /* FDCにコマンドを送る */
     while((io_in8(0x03f4) & 0xc0) != 0x80);
     io_out8(0x03f5, data);
     return;
 }
 
 int fdc_receivedata(void)
 {
     while((io_in8(0x03f4) & 0xc0) != 0xc0);
     return io_in8(0x03f5);
 }
 
 void fdc_getstatus(void)
 {
     int i;
     while((io_in8(0x03f4) & 0x10) != 0) { task_sleep(task_fdc); }   // コマンド送信準備
     fdc_sendcommand(0x08);
     i = fdc_receivedata() & 0xc0;
     if (i == 0x00) {
         /* 正常終了 */
         fdc_stat.result = 1;
     } else if (i == 0x40) {
         /* 異常終了 */
         fdc_stat.result = 2;
     } else {
         /* OSのバグと見ていい */
         fdc_stat.result = 3;
     }
     fdc_stat.cylinder = fdc_receivedata();
     return;
 }
 
 void fdc_seek0(void)
 {
     /* 微妙 */
     motor_on();
     io_cli();
     fifo32_put(&task_fdc->fifo, 1);
     fifo32_put(&task_fdc->fifo, 0x07);
     fifo32_put(&task_fdc->fifo, 0x00);
     io_sti();
     while((io_in8(0x03f4) & 0x11) != 0) { task_sleep(task_fdc); }   // 送信準備
     fdc_sendcommand(0x07);
     fdc_sendcommand(0x00);
     while (fifo32_status(fdc_fifo) == 0) { task_sleep(task_fdc); }  // 割り込み待ち
     fifo32_get(fdc_fifo);
     fdc_getstatus();
     return;
 }
 
 void fdc_seek(int h, int c)
 {
     /* 微妙 */
     motor_on();
     io_cli();
     fifo32_put(&task_fdc->fifo, 1);
     fifo32_put(&task_fdc->fifo, 0x0f);
     fifo32_put(&task_fdc->fifo, h<<2);
     fifo32_put(&task_fdc->fifo, c);
     io_sti();
     while((io_in8(0x03f4) & 0x11) != 0) { task_sleep(task_fdc); }   // 送信準備
     fdc_sendcommand(0x0f);
     fdc_sendcommand(h<<2);
     fdc_sendcommand(c);
     while (fifo32_status(fdc_fifo) == 0) { task_sleep(task_fdc); }  // 割り込み待ち
     fifo32_get(fdc_fifo);
     fdc_getstatus();
     return;
 }
 
 void fdc_task(void)
 {
     int i, j, k;
     int i, j;
     int data[5], c, h, s;
     struct TIMER *timer;
     timer = timer_alloc();
     timer_init(timer, &task_fdc->fifo, 4);
 
     struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO;
     char str[30];
     // putfonts((unsigned int *)(binfo->vram), binfo->scrnx, 0, 0, 0xffffff, "@");
     char s[30];
 
     for (;;) {
         io_cli();
         if (fifo32_status(&task_fdc->fifo) == 0) {
             if (fdc_stat.motorman == 1) {
                 /* 「モーターOFFしてもいいですか。」 */
                 timer_settime(timer, 300);  // 3秒待つ。
             }
             task_sleep(task_fdc);
             io_sti();
 #if 0
             if (fdc_stat.motorman == 1) {
                 /* モーターOFF */
                 timer_settime(timer, 300);
                 while (fifo32_status(&task_fdc->fifo) == 0) { task_sleep(task_fdc); }
                 i = fifo32_get(&task_fdc->fifo);
                 if (i == 4) {
                     /* タイマーがキタ */
                     io_out8(0x03f2, 0x0c);
                     fdc_stat.motorman = 0;
                 } else {
                     /* ちょ、これ次のコマンドwww */
                     timer_cancel(timer);
                     goto skip;
                 }
             }
 #endif
         } else {
             i = fifo32_get(&task_fdc->fifo);
             io_sti();
             if (i == 1) {
                 /* データリード */
                 while((io_in8(0x03f4) & 0x11) != 0) { task_sleep(task_fdc); }   // 0になるまで待つ
                 j = fifo32_status(&task_fdc->fifo);
                 for (k = 0; k < j; k++) {
                     /* 送信アタタタタタ!!! */
                     while((io_in8(0x03f4) & 0xc0) != 0x80);
                     io_out8(0x03f5, fifo32_get(&task_fdc->fifo));
                 /* 動いてるか知らんけどタイマーキャンセル */
                 timer_cancel(timer);
                 /* FIFOからコマンドを5個取得する */
                 for (j = 0; j < 5; j++) {
                     data[j] = fifo32_get(&task_fdc->fifo);
                 }
                 c = data[0] / 36;               // セクタ
                 h = (data[0] - c * 2) / 18;     // ヘッダ
                 s = data[0] - c - h + 1;        // セクタ
                 /* ここにDMACの設定 */
                 fdc_seek(h, c);
 j = fdc_stat.cylinder;
 sprintf(str, "r=%d c=%d", fdc_stat.result, fdc_stat.cylinder);
 putfonts((unsigned int *) (binfo->vram), binfo->scrnx, 280, j, 0xffffff, str);
                 /* コマンド送信アタタタタタ!!!
                 while((io_in8(0x03f4) & 0x11) != 0) { task_sleep(task_fdc); }   // 送信準備
                 fdc_sendcommand(0xE6);  // 読み込みコマンド
                 fdc_sendcommand(c);     // シリンダ
                 fdc_sendcommand(h);     // ヘッダ
                 fdc_sendcommand(s);     // セクタ
                 fdc_sendcommand(0x02);  // 以下おまじない
                 fdc_sendcommand(0x12);
                 fdc_sendcommand(0x01);
                 fdc_sendcommand(0xFF);  // 以上!
                 */
             }
             if (i == 2) {
                 /* データライト */
                 /* 動いてるか知らんけどタイマーキャンセル */
                 timer_cancel(timer);
             }
             if (i == 3) {
                 /* コマンド08 */
                 while((io_in8(0x03f4) & 0x10) != 0) { task_sleep(task_fdc); }   // 0になるまで待つ
                 while((io_in8(0x03f4) & 0xc0) != 0x80);
                 io_out8(0x03f5, 0x08);
                 while((io_in8(0x03f4) & 0xc0) != 0xc0);
                 j = io_in8(0x03f5) & 0xc0;
                 if (j == 0x00) {
                     /* 正常終了 */
                     fdc_stat.result = 1;
                 } else if (j == 0x40) {
                     /* 異常終了 */
                     fdc_stat.result = 2;
                 } else {
                     /* OSのバグと見ていい */
                     fdc_stat.result = 3;
                 }
                 while((io_in8(0x03f4) & 0xc0) != 0xc0) {  }
                 fdc_stat.cylinder = io_in8(0x03f5);
 sprintf(s, "r=%02x c=%d", j, fdc_stat.cylinder);
 putfonts((unsigned int *)(binfo->vram), binfo->scrnx, 0, 0, 0xffffff, s);
             if (i == 4) {
                 /* FDDモーターOFF */
                 io_out8(0x03f2, 0x0c);
                 fdc_stat.motorman = 0;
             }
         }
     }
 }
 
 void fdc_init(struct MEMMAN *memman)
 {
     int *fdc_fifo = (int *) memman_alloc_4k(memman, 128 * 4);
     int *fdc_taskfifobuf = (int *) memman_alloc_4k(memman, 128 * 4);
     int fdc_fifobuf[32];
     task_fdc = task_alloc();
     task_fdc->tss.esp = memman_alloc_4k(memman, 64 * 1024) + 64 * 1024;
     task_fdc->tss.eip = (int) &fdc_task;
     task_fdc->tss.es = 1 * 8;
     task_fdc->tss.cs = 2 * 8;
     task_fdc->tss.ss = 1 * 8;
     task_fdc->tss.ds = 1 * 8;
     task_fdc->tss.fs = 1 * 8;
     task_fdc->tss.gs = 1 * 8;
     task_run(task_fdc, 2, 2);
     fifo32_init(&task_fdc->fifo, 128, fdc_fifo, task_fdc);
 
     fifo32_init(&task_fdc->fifo, 128, fdc_taskfifobuf, task_fdc);   // コマンド・タイマー
     fifo32_init(fdc_fifo, 32, fdc_fifobuf, task_fdc);               // 割り込み
     fdc_stat.motorman = 0;
     return;
 }
 
 /* </fdc.c> */
+HariMainで、何かあいているキー(F12キーとか)を押したときに次のテストコードが実行されるようにしておく。
 io_cli();
 fifo32_put(&task_fdc->fifo, 1);//読み込みコマンドを送る合図1
 fifo32_put(&task_fdc->fifo, 1234);//これがセクタ番号
 fifo32_put(&task_fdc->fifo, 20);//以下、未実装に付き適当
 fifo32_put(&task_fdc->fifo, 1);
 fifo32_put(&task_fdc->fifo, 1);
 fifo32_put(&task_fdc->fifo, 1);//読み込みコマンド1ここまで
 fifo32_put(&task_fdc->fifo, 1);//読み込みコマンドを送る合図2
 fifo32_put(&task_fdc->fifo, 2345);//これがセクタ番号
 fifo32_put(&task_fdc->fifo, 20);//以下、未実装に付き適当
 fifo32_put(&task_fdc->fifo, 1);
 fifo32_put(&task_fdc->fifo, 1);
 fifo32_put(&task_fdc->fifo, 1);//読み込みコマンド2ここまで
 io_sti();
-注意点
++PCがおかしくなってもあっきぃは責任は負わない。
++テストコードは激しく連続実行するとFDDが弱るのでやってはいけない。せいぜい1.5秒間隔で。
++モーター自動ON/OFFがイイカンジ。
++素敵なデバッグ表示つき。

*コメント欄
#pcomment


Wikiの [ 一覧一覧 最終更新最終更新 ヘルプヘルプ   RSSRSS]