/* <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?