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

📄 old-fdc.c

📁 用于汇编领域的,运用于OS的MAIN函数.基于硬件基础的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
        }        else res = FDC_ERROR; /* Seek error */        if (tries != 2) recalibrate(fdd); /* Error, try again... */    }    /* Copy data from the DMA buffer into the caller's buffer */    if ((res == FDC_OK) && buffer)        fd32_memcpy_from_lowmem(buffer, dma_sel, 0, 512 * num_sectors);    motor_down(fdd);    busy = 0;    return res;}/* Writes sectors to the floppy, up to the end of the cylinder. */int fdc_write(Fdd *fdd, const Chs *chs, const BYTE *buffer, unsigned num_sectors){    unsigned tries;    int      res = FDC_ERROR;    if (fdd->dp->cmos_type == 0) return FDC_ERROR; /* Drive not available */    /* TODO: Place a timeout for Busy check */    while (busy); /* Wait while the floppy driver is already busy: BUSY WAIT! */    busy = 1;    motor_on(fdd);    specify(fdd);    fd32_memcpy_to_lowmem(dma_sel, 0, buffer, 512 * num_sectors);    for (tries = 0; tries < 3; tries++)    {        /* Move head to right track */        if (fdc_seek(fdd, chs->c) == FDC_OK)        {            /* If changeline is active, no disk is in drive */            if (fd32_inb(fdd->fdc->base_port + FDC_DIR) & 0x80)            {                LOG_PRINTF(("[FDC] fdc_write: no disk in drive\n"));                res = FDC_NODISK;                break;            }            res = fdc_xfer(fdd, chs, dma_addr, num_sectors, FDC_WRITE);            if (res == FDC_OK) break;        }        else res = FDC_ERROR; /* Seek error */        if (tries != 2) recalibrate(fdd); /* Error, try again... */    }    motor_down(fdd);    busy = 0;    return res;}/* Transfers data between a whole cylinder (both tracks of disk sides) and *//* and the DMA buffer, as fast as possible.                                *//* We get the current head position with READID, so we can start to        *//* transfer sectors from the first sector passing below the head. When the *//* disk completes a revolution, we finish transferring the first sectors.  *//* If buffer is NULL, the read data is discarded (may be used to probe).   */static int fdc_xfer_cylinder(Fdd *fdd, unsigned cyl, FdcTransfer op){    unsigned tries;               /* Count how many retries              */    Chs      chs = { cyl, 0, 1 }; /* Passed to fdc_xfer to read sectors  */    Chs      cur;                 /* Current position returned by READID */    unsigned sec_in_cyl;          /* Zero-based sector we start to read  */    int      res = FDC_ERROR;     /* This function's result...           */    motor_on(fdd);    specify(fdd);    for (tries = 0; tries < 3; tries++)    {        /* Move head to right track */        if (fdc_seek(fdd, cyl) == FDC_OK)        {            /* If changeline is active, no disk is in drive */            if (fd32_inb(fdd->fdc->base_port + FDC_DIR) & 0x80)            {                LOG_PRINTF(("[FDC] fdc_Xfer_cylinder: no disk in drive\n"));                res = FDC_NODISK;                break;            }            readid(fdd, &cur);            LOG_PRINTF(("[FDC] fdc_xfer_cylinder: readid=%u,%u,%u\n", cur.c, cur.h, cur.s));            /* Transfer from the current sector of head 0 to the end of cylinder */            cur.s++; /* The sector we read the Id is gone. Advance a bit */            sec_in_cyl = cur.s - 1;            if (cur.s > fdd->fmt->sec_per_trk)            {                cur.h++;                cur.s -= fdd->fmt->sec_per_trk;            }            chs.h = cur.h;            chs.s = cur.s;            LOG_PRINTF(("[FDC] fdc_xfer_cylinder: first round:%u sectors from %u\n",                        fdd->fmt->sec_per_trk * 2 - sec_in_cyl, sec_in_cyl));            res = fdc_xfer(fdd, &chs, dma_addr + 512 * sec_in_cyl,                           fdd->fmt->sec_per_trk * 2 - sec_in_cyl, op);            /* Read the first sectors, that we missed in the previous revolution */            if ((res == FDC_OK) && (sec_in_cyl > 0))            {                chs.h = 0;                chs.s = 1;                LOG_PRINTF(("[FDC] fdc_read_cylinder: second round:%u sectors from 0\n", sec_in_cyl));                res = fdc_xfer(fdd, &chs, dma_addr, sec_in_cyl, op);            }            if (res == FDC_OK) break;        }        else res = FDC_ERROR; /* Seek error */        if (tries != 2) recalibrate(fdd); /* Error, try again... */    }    motor_down(fdd);    return res;}/* Reads a whole cylinder (both tracks of disk sides) as fast as possible. *//* See fdc_xfer_cylinder for comments.                                     *//* If buffer is NULL, the read data is discarded (may be used to probe).   */int fdc_read_cylinder(Fdd *fdd, unsigned cyl, BYTE *buffer){    int res;    if (fdd->dp->cmos_type == 0) return FDC_ERROR; /* Drive not available */    /* TODO: Place a timeout for Busy check */    while (busy); /* Wait while the floppy driver is already busy: BUSY WAIT! */    busy = 1;    res = fdc_xfer_cylinder(fdd, cyl, FDC_READ);    if ((res == FDC_OK) && buffer)        fd32_memcpy_from_lowmem(buffer, dma_sel, 0, 512 * fdd->fmt->sec_per_trk * 2);    busy = 0;    return res;}/* Writes a whole cylinder (both tracks of disk sides) as fast as possible. *//* See fdc_read_cylinder for comments.                                      */int fdc_write_cylinder(Fdd *fdd, unsigned cyl, const BYTE *buffer){    int res;    if (fdd->dp->cmos_type == 0) return FDC_ERROR; /* Drive not available */    /* TODO: Place a timeout for Busy check */    while (busy); /* Wait while the floppy driver is already busy: BUSY WAIT! */    busy = 1;    fd32_memcpy_to_lowmem(dma_sel, 0, buffer, 512 * fdd->fmt->sec_per_trk * 2);    res = fdc_xfer_cylinder(fdd, cyl, FDC_WRITE);    busy = 0;    return res;}/* Ckecks for the specified disk format, by reading the last sector of the *//* last track of the last side of the specified format.                    *//* Returns zero if format is supported, or a negative value if not.        */static int probe_format(Fdd *fdd, unsigned format){    Chs chs = { 0, 0, 0 };    int res;    fdd->fmt = &floppy_formats[format];    chs.s = fdd->fmt->sec_per_trk;    res = fdc_read(fdd, &chs, NULL, 1);    LOG_PRINTF(("[FDC] probe_format: fdc_read returned %i\n", res));    if (res < 0) return res;    LOG_PRINTF(("%s format detected\n", fdd->fmt->name));    return FDC_OK;}/* Checks disk geometry. Call this after any disk change. *//* Returns 0 on success.                                  */int fdc_log_disk(Fdd *fdd){    unsigned k;    if (fdd->dp->cmos_type == 0) return FDC_ERROR; /* Drive not available */    fdd->fmt = &floppy_formats[fdd->dp->native_fmt];    reset_fdc(fdd->fdc);    reset_drive(fdd);    /* If changeline is active, no disk is in drive */    motor_on(fdd);    if (fd32_inb(fdd->fdc->base_port + FDC_DIR) & 0x80)    {        LOG_PRINTF(("[FDC] fdc_log_disk: no disk in drive\n"));        motor_down(fdd);        return FDC_NODISK;    }    fdd->flags &= ~DF_CHANGED;    for (k = 0; k < 8; k++)        if (probe_format(fdd, fdd->dp->detect[k]) == 0)        {            /* Finetune the probed format with boot sector informations */            int res = floppy_bootsector(fdd, floppy_formats, 32);            if (res >= 0) fdd->fmt = &floppy_formats[res];            return FDC_OK;        }    motor_down(fdd);    fdd->flags |= DF_CHANGED; /* Must log the disk again the next time */    return FDC_ERROR; /* If we arrive here, the autodetection failed */}/* Initializes a drive to a known state */static int setup_drive(Fdc *fdc, unsigned drive, unsigned cmos_type){    fdc->drive[drive].fdc       = fdc;    fdc->drive[drive].dp        = &default_drive_params[0];    /* No need to initialize fdc->drive[drive].fmt */    fdc->drive[drive].number    = drive;    fdc->drive[drive].flags     = 0;    fdc->drive[drive].track     = 0;    fdc->drive[drive].spin_down = -1;    if ((cmos_type > 0) && (cmos_type <= 6))    {        fd32_message("[FLOPPY] Drive %u set to %s\n", drive, default_drive_params[cmos_type].name);        fdc->drive[drive].dp        = &default_drive_params[cmos_type];        fdc->drive[drive].flags     = DF_CHANGED;    }    return FDC_OK;}#endif/* Initializes the low-level driver *///int fdc_setup(FdcSetupCallback *setup_cb)int fdc_setup(void){    unsigned k;    unsigned cmos_drive0;    unsigned cmos_drive1;    int      res;    //WORD     dma_seg, dma_off;    /* Setup IRQ and DMA */    /* TODO: Provide a way to save the old IRQ6 handler */    //fd32_irq_bind(6, irq6);    LOG_PRINTF(("IRQ6 handler installed\n"));    /* TODO: Find a decent size for the DMA buffer */    //dma_sel = fd32_dmamem_get(512 * 18 * 2, &dma_seg, &dma_off);    //if (dma_sel == 0) return FDC_ERROR; /* Unable to allocate DMA buffer */    //dma_addr = ((DWORD) dma_seg << 4) + (DWORD) dma_off;    //LOG_PRINTF(("DMA buffer allocated at physical address %08lxh\n", dma_addr));    /* Reset primary controller */    pri_fdc.base_port = FDC_BPRI;	printk("bef reset fdc\n");    reset_fdc(&pri_fdc);    sendbyte(pri_fdc.base_port, CMD_VERSION);    res = getbyte(pri_fdc.base_port);    //LOG_PRINTF(("Byte got from CMD_VERSION: %x\n", res));    printk("Byte got from CMD_VERSION: %x\n", res);	asm("int $0x25\n\t"::); // check irq 6    switch (res)    {        case 0x80: fd32_message("[FLOPPY] NEC765 FDC found on base port %x\n", pri_fdc.base_port); break;        case 0x90: fd32_message("[FLOPPY] Enhanced FDC found on base port %x\n", pri_fdc.base_port); break;        default  : fd32_message("[FLOPPY] FDC not found on base port %x\n", pri_fdc.base_port);    }   #ifdef MYFDC     /* Read floppy drives types from CMOS memory (up to two drives). */    /* They are supposed to belong to the primary FDC.               */    fd32_outb(0x70, 0x10);    k = fd32_inb(0x71);    cmos_drive0 = k >> 4;    cmos_drive1 = k & 0x0F;    setup_drive(&pri_fdc, 0, cmos_drive0);    setup_drive(&pri_fdc, 1, cmos_drive1);    for (res = FDC_OK, k = 0; k < MAXDRIVES; k++)        if (pri_fdc.drive[k].dp->cmos_type)            if (setup_cb(&pri_fdc.drive[k]) < 0) res = -1;    #ifdef HAS2FDCS    setup_drive(&sec_fdc, 0, 0);    setup_drive(&sec_fdc, 1, 0);    sec_fdc.base_port = FDC_BSEC;    reset_fdc(&sec_fdc);    for (k = 0; k < MAXDRIVES; k++)        if (setup_cb(&sec_fdc.drive[k]) < 0) res = -1;    #endif	#endif    return res;}#ifdef MYFDC /* Frees low-level driver resources */void fdc_dispose(void){    /* TODO: How to restore old handler? *///    fd32_irq_bind(6, &old_irq6);//    LOG_PRINTF(("IRQ6 handler uninstalled\n"));    /* TODO: Find a decent size for the DMA buffer */    fd32_dmamem_free(dma_sel, 512 * 18 * 2);    LOG_PRINTF(("DMA buffer freed\n"));    fd32_outb(pri_fdc.base_port + FDC_DOR, 0x0C); /* Stop motor forcefully */}#endif

⌨️ 快捷键说明

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