FDCドライバもどき・書きかけ

めも

必要なFIFOバッファ

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

セクタ番号からシリンダ・ヘッド・セクタを計算する

割り算の結果は、小数点以下切捨てで。

そーす

/* <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);
    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_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();
    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();
    return;
}

void fdc_task(void)
{
    int i, j, k;
    struct TIMER *timer;
    timer = timer_alloc();
    timer_init(timer, &task_fdc->fifo, 4);

    struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO;
    // putfonts((unsigned int *)(binfo->vram), binfo->scrnx, 0, 0, 0xffffff, "@");
    char s[30];

    for (;;) {
        io_cli();
        if (fifo32_status(&task_fdc->fifo) == 0) {
            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));
                }
            }
            if (i == 2) {
                /* データライト */
            }
            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);
            }
        }
    }
}

void fdc_init(struct MEMMAN *memman)
{
    int *fdc_fifo = (int *) memman_alloc_4k(memman, 128 * 4);
    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);

    fdc_stat.motorman = 0;
    return;
}

/* </fdc.c> */

コメント欄

コメントはありません。 Comments/tmp/FDC?

お名前:

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