⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fdc.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 4 页
字号:
                0x20 | (cur_drv->head << 2) | fdctrl->cur_drv;#endif            fdctrl->fifo[1] = cur_drv->track;            fdctrl_set_fifo(fdctrl, 2, 0);	    fdctrl_reset_irq(fdctrl);	    fdctrl->int_status = 0xC0;            return;        case 0x0E:            /* DUMPREG */            FLOPPY_DPRINTF("DUMPREG command\n");            /* Drives position */            fdctrl->fifo[0] = drv0(fdctrl)->track;            fdctrl->fifo[1] = drv1(fdctrl)->track;            fdctrl->fifo[2] = 0;            fdctrl->fifo[3] = 0;            /* timers */            fdctrl->fifo[4] = fdctrl->timer0;            fdctrl->fifo[5] = (fdctrl->timer1 << 1) | fdctrl->dma_en;            fdctrl->fifo[6] = cur_drv->last_sect;            fdctrl->fifo[7] = (fdctrl->lock << 7) |                    (cur_drv->perpendicular << 2);            fdctrl->fifo[8] = fdctrl->config;            fdctrl->fifo[9] = fdctrl->precomp_trk;            fdctrl_set_fifo(fdctrl, 10, 0);            return;        case 0x0F:            /* SEEK */            FLOPPY_DPRINTF("SEEK command\n");            /* 2 parameters cmd */            fdctrl->data_len = 3;            goto enqueue;        case 0x10:            /* VERSION */            FLOPPY_DPRINTF("VERSION command\n");            /* No parameters cmd */            /* Controller's version */            fdctrl->fifo[0] = fdctrl->version;            fdctrl_set_fifo(fdctrl, 1, 1);            return;        case 0x12:            /* PERPENDICULAR_MODE */            FLOPPY_DPRINTF("PERPENDICULAR_MODE command\n");            /* 1 parameter cmd */            fdctrl->data_len = 2;            goto enqueue;        case 0x13:            /* CONFIGURE */            FLOPPY_DPRINTF("CONFIGURE command\n");            /* 3 parameters cmd */            fdctrl->data_len = 4;            goto enqueue;        case 0x14:            /* UNLOCK */            FLOPPY_DPRINTF("UNLOCK command\n");            /* No parameters cmd */            fdctrl->lock = 0;            fdctrl->fifo[0] = 0;            fdctrl_set_fifo(fdctrl, 1, 0);            return;        case 0x17:            /* POWERDOWN_MODE */            FLOPPY_DPRINTF("POWERDOWN_MODE command\n");            /* 2 parameters cmd */            fdctrl->data_len = 3;            goto enqueue;        case 0x18:            /* PART_ID */            FLOPPY_DPRINTF("PART_ID command\n");            /* No parameters cmd */            fdctrl->fifo[0] = 0x41; /* Stepping 1 */            fdctrl_set_fifo(fdctrl, 1, 0);            return;        case 0x2C:            /* SAVE */            FLOPPY_DPRINTF("SAVE command\n");            /* No parameters cmd */            fdctrl->fifo[0] = 0;            fdctrl->fifo[1] = 0;            /* Drives position */            fdctrl->fifo[2] = drv0(fdctrl)->track;            fdctrl->fifo[3] = drv1(fdctrl)->track;            fdctrl->fifo[4] = 0;            fdctrl->fifo[5] = 0;            /* timers */            fdctrl->fifo[6] = fdctrl->timer0;            fdctrl->fifo[7] = fdctrl->timer1;            fdctrl->fifo[8] = cur_drv->last_sect;            fdctrl->fifo[9] = (fdctrl->lock << 7) |                    (cur_drv->perpendicular << 2);            fdctrl->fifo[10] = fdctrl->config;            fdctrl->fifo[11] = fdctrl->precomp_trk;            fdctrl->fifo[12] = fdctrl->pwrd;            fdctrl->fifo[13] = 0;            fdctrl->fifo[14] = 0;            fdctrl_set_fifo(fdctrl, 15, 1);            return;        case 0x33:            /* OPTION */            FLOPPY_DPRINTF("OPTION command\n");            /* 1 parameter cmd */            fdctrl->data_len = 2;            goto enqueue;        case 0x42:            /* READ_TRACK */            FLOPPY_DPRINTF("READ_TRACK command\n");            /* 8 parameters cmd */            fdctrl->data_len = 9;            goto enqueue;        case 0x4A:            /* READ_ID */            FLOPPY_DPRINTF("READ_ID command\n");            /* 1 parameter cmd */            fdctrl->data_len = 2;            goto enqueue;        case 0x4C:            /* RESTORE */            FLOPPY_DPRINTF("RESTORE command\n");            /* 17 parameters cmd */            fdctrl->data_len = 18;            goto enqueue;        case 0x4D:            /* FORMAT_TRACK */            FLOPPY_DPRINTF("FORMAT_TRACK command\n");            /* 5 parameters cmd */            fdctrl->data_len = 6;            goto enqueue;        case 0x8E:            /* DRIVE_SPECIFICATION_COMMAND */            FLOPPY_DPRINTF("DRIVE_SPECIFICATION_COMMAND command\n");            /* 5 parameters cmd */            fdctrl->data_len = 6;            goto enqueue;        case 0x8F:            /* RELATIVE_SEEK_OUT */            FLOPPY_DPRINTF("RELATIVE_SEEK_OUT command\n");            /* 2 parameters cmd */            fdctrl->data_len = 3;            goto enqueue;        case 0x94:            /* LOCK */            FLOPPY_DPRINTF("LOCK command\n");            /* No parameters cmd */            fdctrl->lock = 1;            fdctrl->fifo[0] = 0x10;            fdctrl_set_fifo(fdctrl, 1, 1);            return;        case 0xCD:            /* FORMAT_AND_WRITE */            FLOPPY_DPRINTF("FORMAT_AND_WRITE command\n");            /* 10 parameters cmd */            fdctrl->data_len = 11;            goto enqueue;        case 0xCF:            /* RELATIVE_SEEK_IN */            FLOPPY_DPRINTF("RELATIVE_SEEK_IN command\n");            /* 2 parameters cmd */            fdctrl->data_len = 3;            goto enqueue;        default:            /* Unknown command */            FLOPPY_ERROR("unknown command: 0x%02x\n", value);            fdctrl_unimplemented(fdctrl);            return;        }    }enqueue:    FLOPPY_DPRINTF("%s: %02x\n", __func__, value);    fdctrl->fifo[fdctrl->data_pos] = value;    if (++fdctrl->data_pos == fdctrl->data_len) {        /* We now have all parameters         * and will be able to treat the command         */	if (fdctrl->data_state & FD_STATE_FORMAT) {	    fdctrl_format_sector(fdctrl);	    return;	}        switch (fdctrl->fifo[0] & 0x1F) {        case 0x06:        {            /* READ variants */            FLOPPY_DPRINTF("treat READ command\n");            fdctrl_start_transfer(fdctrl, FD_DIR_READ);            return;        }        case 0x0C:            /* READ_DELETED variants *///            FLOPPY_DPRINTF("treat READ_DELETED command\n");            FLOPPY_ERROR("treat READ_DELETED command\n");            fdctrl_start_transfer_del(fdctrl, FD_DIR_READ);            return;        case 0x16:            /* VERIFY variants *///            FLOPPY_DPRINTF("treat VERIFY command\n");            FLOPPY_ERROR("treat VERIFY command\n");            fdctrl_stop_transfer(fdctrl, 0x20, 0x00, 0x00);            return;        case 0x10:            /* SCAN_EQUAL variants *///            FLOPPY_DPRINTF("treat SCAN_EQUAL command\n");            FLOPPY_ERROR("treat SCAN_EQUAL command\n");            fdctrl_start_transfer(fdctrl, FD_DIR_SCANE);            return;        case 0x19:            /* SCAN_LOW_OR_EQUAL variants *///            FLOPPY_DPRINTF("treat SCAN_LOW_OR_EQUAL command\n");            FLOPPY_ERROR("treat SCAN_LOW_OR_EQUAL command\n");            fdctrl_start_transfer(fdctrl, FD_DIR_SCANL);            return;        case 0x1D:            /* SCAN_HIGH_OR_EQUAL variants *///            FLOPPY_DPRINTF("treat SCAN_HIGH_OR_EQUAL command\n");            FLOPPY_ERROR("treat SCAN_HIGH_OR_EQUAL command\n");            fdctrl_start_transfer(fdctrl, FD_DIR_SCANH);            return;        default:            break;        }        switch (fdctrl->fifo[0] & 0x3F) {        case 0x05:            /* WRITE variants */            FLOPPY_DPRINTF("treat WRITE command (%02x)\n", fdctrl->fifo[0]);            fdctrl_start_transfer(fdctrl, FD_DIR_WRITE);            return;        case 0x09:            /* WRITE_DELETED variants *///            FLOPPY_DPRINTF("treat WRITE_DELETED command\n");            FLOPPY_ERROR("treat WRITE_DELETED command\n");            fdctrl_start_transfer_del(fdctrl, FD_DIR_WRITE);            return;        default:            break;        }        switch (fdctrl->fifo[0]) {        case 0x03:            /* SPECIFY */            FLOPPY_DPRINTF("treat SPECIFY command\n");            fdctrl->timer0 = (fdctrl->fifo[1] >> 4) & 0xF;            fdctrl->timer1 = fdctrl->fifo[2] >> 1;	    fdctrl->dma_en = 1 - (fdctrl->fifo[2] & 1) ;            /* No result back */            fdctrl_reset_fifo(fdctrl);            break;        case 0x04:            /* SENSE_DRIVE_STATUS */            FLOPPY_DPRINTF("treat SENSE_DRIVE_STATUS command\n");            fdctrl->cur_drv = fdctrl->fifo[1] & 1;	    cur_drv = get_cur_drv(fdctrl);            cur_drv->head = (fdctrl->fifo[1] >> 2) & 1;            /* 1 Byte status back */            fdctrl->fifo[0] = (cur_drv->ro << 6) |                (cur_drv->track == 0 ? 0x10 : 0x00) |                (cur_drv->head << 2) |                fdctrl->cur_drv |                0x28;            fdctrl_set_fifo(fdctrl, 1, 0);            break;        case 0x07:            /* RECALIBRATE */            FLOPPY_DPRINTF("treat RECALIBRATE command\n");            fdctrl->cur_drv = fdctrl->fifo[1] & 1;	    cur_drv = get_cur_drv(fdctrl);            fd_recalibrate(cur_drv);	    fdctrl_reset_fifo(fdctrl);            /* Raise Interrupt */	    fdctrl_raise_irq(fdctrl, 0x20);            break;        case 0x0F:            /* SEEK */            FLOPPY_DPRINTF("treat SEEK command\n");            fdctrl->cur_drv = fdctrl->fifo[1] & 1;	    cur_drv = get_cur_drv(fdctrl);	    fd_start(cur_drv);            if (fdctrl->fifo[2] <= cur_drv->track)                cur_drv->dir = 1;            else                cur_drv->dir = 0;	    fdctrl_reset_fifo(fdctrl);            if (fdctrl->fifo[2] > cur_drv->max_track) {                fdctrl_raise_irq(fdctrl, 0x60);            } else {                cur_drv->track = fdctrl->fifo[2];                /* Raise Interrupt */                fdctrl_raise_irq(fdctrl, 0x20);            }            break;        case 0x12:            /* PERPENDICULAR_MODE */            FLOPPY_DPRINTF("treat PERPENDICULAR_MODE command\n");            if (fdctrl->fifo[1] & 0x80)                cur_drv->perpendicular = fdctrl->fifo[1] & 0x7;            /* No result back */            fdctrl_reset_fifo(fdctrl);            break;        case 0x13:            /* CONFIGURE */            FLOPPY_DPRINTF("treat CONFIGURE command\n");            fdctrl->config = fdctrl->fifo[2];            fdctrl->precomp_trk =  fdctrl->fifo[3];            /* No result back */            fdctrl_reset_fifo(fdctrl);            break;        case 0x17:            /* POWERDOWN_MODE */            FLOPPY_DPRINTF("treat POWERDOWN_MODE command\n");            fdctrl->pwrd = fdctrl->fifo[1];            fdctrl->fifo[0] = fdctrl->fifo[1];            fdctrl_set_fifo(fdctrl, 1, 1);            break;        case 0x33:            /* OPTION */            FLOPPY_DPRINTF("treat OPTION command\n");            /* No result back */            fdctrl_reset_fifo(fdctrl);            break;        case 0x42:            /* READ_TRACK *///            FLOPPY_DPRINTF("treat READ_TRACK command\n");            FLOPPY_ERROR("treat READ_TRACK command\n");            fdctrl_start_transfer(fdctrl, FD_DIR_READ);            break;        case 0x4A:                /* READ_ID */            FLOPPY_DPRINTF("treat READ_ID command\n");            /* XXX: should set main status register to busy */            cur_drv->head = (fdctrl->fifo[1] >> 2) & 1;            qemu_mod_timer(fdctrl->result_timer,                            qemu_get_clock(vm_clock) + (ticks_per_sec / 50));            break;        case 0x4C:            /* RESTORE */            FLOPPY_DPRINTF("treat RESTORE command\n");            /* Drives position */            drv0(fdctrl)->track = fdctrl->fifo[3];            drv1(fdctrl)->track = fdctrl->fifo[4];            /* timers */            fdctrl->timer0 = fdctrl->fifo[7];            fdctrl->timer1 = fdctrl->fifo[8];            cur_drv->last_sect = fdctrl->fifo[9];            fdctrl->lock = fdctrl->fifo[10] >> 7;            cur_drv->perpendicular = (fdctrl->fifo[10] >> 2) & 0xF;            fdctrl->config = fdctrl->fifo[11];            fdctrl->precomp_trk = fdctrl->fifo[12];            fdctrl->pwrd = fdctrl->fifo[13];            fdctrl_reset_fifo(fdctrl);            break;        case 0x4D:            /* FORMAT_TRACK */	    FLOPPY_DPRINTF("treat FORMAT_TRACK command\n");	    fdctrl->cur_drv = fdctrl->fifo[1] & 1;	    cur_drv = get_cur_drv(fdctrl);	    fdctrl->data_state |= FD_STATE_FORMAT;	    if (fdctrl->fifo[0] & 0x80)		fdctrl->data_state |= FD_STATE_MULTI;	    else		fdctrl->data_state &= ~FD_STATE_MULTI;	    fdctrl->data_state &= ~FD_STATE_SEEK;	    cur_drv->bps =		fdctrl->fifo[2] > 7 ? 16384 : 128 << fdctrl->fifo[2];#if 0	    cur_drv->last_sect =		cur_drv->flags & FDISK_DBL_SIDES ? fdctrl->fifo[3] :		fdctrl->fifo[3] / 2;#else	    cur_drv->last_sect = fdctrl->fifo[3];#endif	    /* TODO: implement format using DMA expected by the Bochs BIOS	     * and Linux fdformat (read 3 bytes per sector via DMA and fill	     * the sector with the specified fill byte	     */	    fdctrl->data_state &= ~FD_STATE_FORMAT;	    fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);            break;        case 0x8E:            /* DRIVE_SPECIFICATION_COMMAND */            FLOPPY_DPRINTF("treat DRIVE_SPECIFICATION_COMMAND command\n");            if (fdctrl->fifo[fdctrl->data_pos - 1] & 0x80) {                /* Command parameters done */                if (fdctrl->fifo[fdctrl->data_pos - 1] & 0x40) {                    fdctrl->fifo[0] = fdctrl->fifo[1];                    fdctrl->fifo[2] = 0;                    fdctrl->fifo[3] = 0;                    fdctrl_set_fifo(fdctrl, 4, 1);                } else {                    fdctrl_reset_fifo(fdctrl);                }            } else if (fdctrl->data_len > 7) {                /* ERROR */                fdctrl->fifo[0] = 0x80 |                    (cur_drv->head << 2) | fdctrl->cur_drv;                fdctrl_set_fifo(fdctrl, 1, 1);            }            break;        case 0x8F:            /* RELATIVE_SEEK_OUT */            FLOPPY_DPRINTF("treat RELATIVE_SEEK_OUT command\n");            fdctrl->cur_drv = fdctrl->fifo[1] & 1;	    cur_drv = get_cur_drv(fdctrl);	    fd_start(cur_drv);                cur_drv->dir = 0;            if (fdctrl->fifo[2] + cur_drv->track >= cur_drv->max_track) {		cur_drv->track = cur_drv->max_track - 1;            } else {                cur_drv->track += fdctrl->fifo[2];            }	    fdctrl_reset_fifo(fdctrl);	    fdctrl_raise_irq(fdctrl, 0x20);            break;        case 0xCD:            /* FORMAT_AND_WRITE *///                FLOPPY_DPRINTF("treat FORMAT_AND_WRITE command\n");            FLOPPY_ERROR("treat FORMAT_AND_WRITE command\n");            fdctrl_unimplemented(fdctrl);            break;        case 0xCF:                /* RELATIVE_SEEK_IN */            FLOPPY_DPRINTF("treat RELATIVE_SEEK_IN command\n");            fdctrl->cur_drv = fdctrl->fifo[1] & 1;	    cur_drv = get_cur_drv(fdctrl);	    fd_start(cur_drv);                cur_drv->dir = 1;            if (fdctrl->fifo[2] > cur_drv->track) {		cur_drv->track = 0;            } else {                cur_drv->track -= fdctrl->fifo[2];            }	    fdctrl_reset_fifo(fdctrl);	    /* Raise Interrupt */	    fdctrl_raise_irq(fdctrl, 0x20);            break;        }    }}static void fdctrl_result_timer(void *opaque){    fdctrl_t *fdctrl = opaque;    fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -