http://hrb.osask.jp/wiki/index.php?advance%2FFDC
割り算の結果は、小数点以下切捨てで。
C = セクタ番号 / 36
H = (セクタ番号 - C * 2) / 18
S = セクタ番号 - C - H + 1
/* <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(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(); 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(); 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; 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, "@"); 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(); } else { i = fifo32_get(&task_fdc->fifo); io_sti(); if (i == 1) { /* データリード */ /* 動いてるか知らんけどタイマーキャンセル */ 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 == 4) { /* FDDモーターOFF */ io_out8(0x03f2, 0x0c); fdc_stat.motorman = 0; } } } } void fdc_init(struct MEMMAN *memman) { 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_taskfifobuf, task_fdc); // コマンド・タイマー fifo32_init(fdc_fifo, 32, fdc_fifobuf, task_fdc); // 割り込み fdc_stat.motorman = 0; return; } /* </fdc.c> */
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();
コメントはありません。 Comments/tmp/FDC?