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

📄 old-fdc.c

📁 用于汇编领域的,运用于OS的MAIN函数.基于硬件基础的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/************************************************************************** * FreeDOS32 Floppy Driver                                                * * by Salvo Isaja                                                         * *                                                                        * * Copyright (C) 2003-2005, Salvatore Isaja                               * *                                                                        * * This is "fdc.c" - Portable code for Floppy Disk Controller support     * *                                                                        * *                                                                        * * This file is part of the FreeDOS32 Floppy Driver.                      * *                                                                        * * The FreeDOS32 Floppy Driver is free software; you can redistribute     * * it and/or modify it under the terms of the GNU General Public License  * * as published by the Free Software Foundation; either version 2 of the  * * License, or (at your option) any later version.                        * *                                                                        * * The FreeDOS32 Floppy Driver is distributed in the hope that it will    * * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty * * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the       * * GNU General Public License for more details.                           * *                                                                        * * You should have received a copy of the GNU General Public License      * * along with the FreeDOS32 Floppy Driver; see the file COPYING.txt;      * * if not, write to the Free Software Foundation, Inc.,                   * * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                * *                                                                        * * ACKNLOWLEDGEMENT                                                       * * This file is derived from fdc.c, floppy controller handler functions   * * Copyright (C) 1998  Fabian Nunez                                       * * You can download the original library from Cottontail OS Development   * * Library <http://www.0xfi.com/oslib/topx.html>, the file is FDC.ZIP     * * The author can be reached by email at: fabian@cs.uct.ac.za             * * or by airmail at: Fabian Nunez                                         * *                   10 Eastbrooke                                        * *                   Highstead Road                                       * *                   Rondebosch 7700                                      * *                   South Africa                                         * * Floppy formats and drive parameters table are from the Linux driver    * *  linux/kernel/floppy.c                                                 * *  Copyright (C) 1991, 1992  Linus Torvalds                              * *  Copyright (C) 1993, 1994  Alain Knaff                                 * **************************************************************************/#include "hos.h"#define MAXDRIVES 2 /* Newer controllers don't support 4 drives, just 2 */#define SAFESEEK  5 /* Track to seek before issuing a recalibrate       *///#define HAS2FDCS//#define __DEBUG__#define LOG_PRINTF(x) printk(x)#define fd32_message printk/* This is called when fdc_logdisk is able to read sectors from the new disk. *//* It fine-tunes format probing by reading informations in the boot sector.   */extern int floppy_bootsector(Fdd *fdd, const FloppyFormat *formats, unsigned num_formats);/* Floppy Drive Controller IO ports */enum{    FDC_BPRI = 0x3F0, /* Base port of the primary controller   */    FDC_BSEC = 0x370, /* Base port of the secondary controller */    FDC_DOR  = 0x002, /* RW: Digital Output Register           */    FDC_MSR  = 0x004, /* R : Main Status Register              */    FDC_DRS  = 0x004, /* W : Data Rate Select Register         */    FDC_DATA = 0x005, /* RW: Data Register                     */    FDC_DIR  = 0x007, /* R : Digital Input Register            */    FDC_CCR  = 0x007  /* W : Configuration Control Register    */};/* Command bytes (these are NEC765 commands + options such as MFM, etc) */enum{    CMD_SPECIFY = 0x03, /* Specify drive timings   */    CMD_WRITE   = 0xC5, /* Write data (+ MT,MFM)   */    CMD_READ    = 0xE6, /* Read data (+ MT,MFM,SK) */    CMD_SENSEI  = 0x08, /* Sense interrupt status  */    //CMD_FORMAT  = 0x4D, /* Format track (+ MFM)    */    CMD_READID  = 0x4A, /* Read sector Id (+ MFM)  */    CMD_RECAL   = 0x07, /* Recalibrate             */    CMD_SEEK    = 0x0F, /* Seek track              */    CMD_VERSION = 0x10  /* Get FDC version         */};/* Bits for Fdd.flags */enum{    DF_CHANGED = 1 << 0, /* Disk has been changed during the last command */    DF_SPINUP  = 1 << 1, /* Motor spinup time elapsed, ready to transfer  */    DF_SPINDN  = 1 << 2  /* Motor spindown time started                   */};/* Status structure for a Floppy Disk Controller */// moved to fdc.h#ifdef MYFDC typedef struct Fdc{    unsigned base_port;        /* Base port for this controller: XXX0h      */    BYTE     result[7];        /* Stores the result bytes returned          */    BYTE     result_size;      /* Number of result bytes returned           */    BYTE     sr0;              /* Status Register 0 after a sense interrupt */    BYTE     dor;              /* Reflects the Digital Output Register      */    Fdd      drive[4]; /* Drives connected to this controller       */}Fdc;#endif/* All Floppy Drive Controllers issue an IRQ6 to report command completion. *//* The irq_signaled variable let us know when IRQ6 happened.                *//* Since it is a global variable, this makes the driver not reentrant, thus *//* we use a simple busy flag to protect the critical sections (all... :-)   *//* For the same reason, we can use just a single, shared, DMA buffer.       *///static IrqSave      old_irq6;         /* Saves the old IRQ6 handler   *//* TODO: At present we have no means to save the old IRQ6 handler */static volatile int busy         = 0; /* Set if the driver is busy    *///static volatile int irq_signaled = 0; /* Set if IRQ has been signaled */int irq_signaled = 0; /* Set if IRQ has been signaled *///static LOWMEM_ADDR  dma_sel;          /* Selector/address of DMA buf  *///static DWORD        dma_addr;         /* Physical address of DMA buf  */static Fdc          pri_fdc;          /* Status of the primary FDC    */#ifdef HAS2FDCSstatic Fdc          sec_fdc;          /* Status of the secondary FDC  */#endif/* Geometry and other format specifications for floppy disks */static const FloppyFormat floppy_formats[32] ={  /*  SIZE SPT HD TRK STR GAP3  RATE SRHUT GAP3F  NAME          NR DESCRIPTION   */    {    0,  0, 0,  0, 0, 0x00, 0x00, 0x00, 0x00, NULL    }, /*  0 no testing    */    {  720,  9, 2, 40, 0, 0x2A, 0x02, 0xDF, 0x50, "d360"  }, /*  1 360KB PC      */    { 2400, 15, 2, 80, 0, 0x1B, 0x00, 0xDF, 0x54, "h1200" }, /*  2 1.2MB AT      */    {  720,  9, 1, 80, 0, 0x2A, 0x02, 0xDF, 0x50, "D360"  }, /*  3 360KB SS 3.5" */    { 1440,  9, 2, 80, 0, 0x2A, 0x02, 0xDF, 0x50, "D720"  }, /*  4 720KB 3.5"    */    {  720,  9, 2, 40, 1, 0x23, 0x01, 0xDF, 0x50, "h360"  }, /*  5 360KB AT      */    { 1440,  9, 2, 80, 0, 0x23, 0x01, 0xDF, 0x50, "h720"  }, /*  6 720KB AT      *///    { 2880, 18, 2, 80, 0, 0x1B, 0x00, 0xDF, 0x6C, "H1440" }, /*  7 1.44MB 3.5"   */    { 2880, 18, 2, 80, 0, 0x1B, 0x00, 0xCF, 0x6C, "H1440" }, /*  7 1.44MB 3.5"   */    { 5760, 36, 2, 80, 0, 0x1B, 0x43, 0xAF, 0x54, "E2880" }, /*  8 2.88MB 3.5"   */    { 6240, 39, 2, 80, 0, 0x1B, 0x43, 0xAF, 0x28, "E3120" }, /*  9 3.12MB 3.5"   */    { 2880, 18, 2, 80, 0, 0x25, 0x00, 0xDF, 0x02, "h1440" }, /* 10 1.44MB 5.25"  */    { 3360, 21, 2, 80, 0, 0x1C, 0x00, 0xCF, 0x0C, "H1680" }, /* 11 1.68MB 3.5"   */    {  820, 10, 2, 41, 1, 0x25, 0x01, 0xDF, 0x2E, "h410"  }, /* 12 410KB 5.25"   */    { 1640, 10, 2, 82, 0, 0x25, 0x02, 0xDF, 0x2E, "H820"  }, /* 13 820KB 3.5"    */    { 2952, 18, 2, 82, 0, 0x25, 0x00, 0xDF, 0x02, "h1476" }, /* 14 1.48MB 5.25"  */    { 3444, 21, 2, 82, 0, 0x25, 0x00, 0xDF, 0x0C, "H1722" }, /* 15 1.72MB 3.5"   */    {  840, 10, 2, 42, 1, 0x25, 0x01, 0xDF, 0x2E, "h420"  }, /* 16 420KB 5.25"   */    { 1660, 10, 2, 83, 0, 0x25, 0x02, 0xDF, 0x2E, "H830"  }, /* 17 830KB 3.5"    */    { 2988, 18, 2, 83, 0, 0x25, 0x00, 0xDF, 0x02, "h1494" }, /* 18 1.49MB 5.25"  */    { 3486, 21, 2, 83, 0, 0x25, 0x00, 0xDF, 0x0C, "H1743" }, /* 19 1.74MB 3.5"   */    { 1760, 11, 2, 80, 0, 0x1C, 0x09, 0xCF, 0x00, "h880"  }, /* 20 880KB 5.25"   */    { 2080, 13, 2, 80, 0, 0x1C, 0x01, 0xCF, 0x00, "D1040" }, /* 21 1.04MB 3.5"   */    { 2240, 14, 2, 80, 0, 0x1C, 0x19, 0xCF, 0x00, "D1120" }, /* 22 1.12MB 3.5"   */    { 3200, 20, 2, 80, 0, 0x1C, 0x20, 0xCF, 0x2C, "h1600" }, /* 23 1.6MB 5.25"   */    { 3520, 22, 2, 80, 0, 0x1C, 0x08, 0xCF, 0x2e, "H1760" }, /* 24 1.76MB 3.5"   */    { 3840, 24, 2, 80, 0, 0x1C, 0x20, 0xCF, 0x00, "H1920" }, /* 25 1.92MB 3.5"   */    { 6400, 40, 2, 80, 0, 0x25, 0x5B, 0xCF, 0x00, "E3200" }, /* 26 3.20MB 3.5"   */    { 7040, 44, 2, 80, 0, 0x25, 0x5B, 0xCF, 0x00, "E3520" }, /* 27 3.52MB 3.5"   */    { 7680, 48, 2, 80, 0, 0x25, 0x63, 0xCF, 0x00, "E3840" }, /* 28 3.84MB 3.5"   */    { 3680, 23, 2, 80, 0, 0x1C, 0x10, 0xCF, 0x00, "H1840" }, /* 29 1.84MB 3.5"   */    { 1600, 10, 2, 80, 0, 0x25, 0x02, 0xDF, 0x2E, "D800"  }, /* 30 800KB 3.5"    */    { 3200, 20, 2, 80, 0, 0x1C, 0x00, 0xCF, 0x2C, "H1600" }  /* 31 1.6MB 3.5"    */};/* Parameters to manage a floppy disk drive.                                *//* Head load time is 16 ms for all drives except 2880 KiB, that have 15 ms. */#define MS 1000 /* From ms to us */static const DriveParams default_drive_params[] ={   /* T HLT  spin_up  spin_dn  sel_d  int_tmt  Autodetect formats        Nat  Name                     */    { 0,  0, 1000*MS, 3000*MS, 20*MS, 3000*MS, { 7, 4, 8, 2, 1, 5, 3,10 }, 0, "unknown"                },    { 1,  4, 1000*MS, 3000*MS, 20*MS, 3000*MS, { 1, 0, 0, 0, 0, 0, 0, 0 }, 1, "5.25\" DD, 360 KiB"     },    { 2,  8,  400*MS, 3000*MS, 20*MS, 3000*MS, { 2, 5, 6,23,10,20,12, 0 }, 2, "5.25\" HD, 1200 KiB"    },    { 3,  4, 1000*MS, 3000*MS, 20*MS, 3000*MS, { 4,22,21,30, 3, 0, 0, 0 }, 4, "3.5\" DD, 720 KiB"      },    { 4,  8/*1*/,  400*MS, 3000*MS, 20*MS, 1500*MS, { 7, 4,25,22,31,21,29,11 }, 7, "3.5\" HD, 1440 KiB"     },    { 5, 15,  400*MS, 3000*MS, 20*MS, 3000*MS, { 7, 8, 4,25,28,22,31,21 }, 8, "3.5\" ED, 2880 KiB AMI" },    { 6, 15,  400*MS, 3000*MS, 20*MS, 3000*MS, { 7, 8, 4,25,28,22,31,21 }, 8, "3.5\" ED, 2880 KiB"     }};/* Constants for DMA transfers */enum{    DMA_CHANNEL = 2,    /* Number of the DMA channel for floppy transfer */    DMA_PAGE    = 0x81, /* Page register of that DMA channel             */    DMA_OFFSET  = 0x04, /* Offset register of that DMA channel           */    DMA_LENGTH  = 0x05  /* Length register of that DMA channel           */};#ifdef MYFDC /* Sets up a DMA trasfer between a device and memory.              *//* If 'read' is TRUE, then transfer will be from memory to device, *//* else from the device to memory.                                 */static void dma_xfer(DWORD physaddr, unsigned length, int read){    DWORD page, offset;    /* Calculate DMA page and offset */    page    = physaddr >> 16;    offset  = physaddr & 0xffff;    length -= 1; /* with DMA, if you want k bytes, you ask for k - 1 */    fd32_cli();                                          /* Disable IRQs            */    fd32_outb(0x0A, DMA_CHANNEL | 4);                    /* Set channel mask bit    */    fd32_outb(0x0C, 0);                                  /* Clear flip flop         */    fd32_outb(0x0B, (read ? 0x48 : 0x44) + DMA_CHANNEL); /* Mode (write+single+r/w) */    fd32_outb(DMA_PAGE, page);                           /* Page                    */    fd32_outb(DMA_OFFSET, offset & 0xFF);                /* Offset: low byte        */    fd32_outb(DMA_OFFSET, offset >> 8);                  /* Offset: high byte       */    fd32_outb(DMA_LENGTH, length & 0xFF);                /* Length: low byte        */    fd32_outb(DMA_LENGTH, length >> 8);                  /* Length: high byte       */    fd32_outb(0x0A, DMA_CHANNEL);                        /* Clear DMA mask bit      */    fd32_sti();                                          /* enable IRQs             */}#endif/* Sends a byte to the controller FIFO. *//* Returns FDC_TIMEOUT on timeout.      */static int sendbyte(unsigned base_port, unsigned byte){    volatile unsigned msr;    unsigned          tmo;    for (tmo = 0; tmo < 128; tmo++)    {        msr = fd32_inb(base_port + FDC_MSR);        if ((msr & 0xC0) == 0x80)        {            fd32_outb(base_port + FDC_DATA, byte);            return FDC_OK;        }        fd32_inb(0x80); /* delay */    }    return FDC_TIMEOUT; /* write timeout */}/* Gets a byte from the controller FIFO. *//* Returns FDC_TIMEOUT on timeout.       */static int getbyte(unsigned base_port){    volatile unsigned msr;    unsigned          tmo;    for (tmo = 0; tmo < 128; tmo++)    {        msr = fd32_inb(base_port + FDC_MSR);        if ((msr & 0xD0) == 0xD0) return fd32_inb(base_port + FDC_DATA);        fd32_inb(0x80); /* delay */    }    return FDC_TIMEOUT; /* read timeout */}/* Callback function called on IRQ6 timeout */static void irq_timeout_cb(void *params){    *((int *) params) = 1; /* Signal timeout */}#ifdef MYFDC /* Waits for FDC command to complete. Returns FDC_TIMEOUT on time out. */static int wait_fdc(Fdd *fdd){    /* Wait for IRQ6 handler to signal command finished */    volatile int irq_timeout = 0;    int irq_timeout_event = fd32_event_post(fdd->dp->int_tmout, irq_timeout_cb, (void *) &irq_timeout);    /* TODO: Check for FD32_EVENT_NULL */    WFC(!irq_signaled && !irq_timeout);    fd32_event_delete(irq_timeout_event);    /* Read in command result bytes while controller is busy */    fdd->fdc->result_size = 0;    while ((fdd->fdc->result_size < 7) && (fd32_inb(fdd->fdc->base_port + FDC_MSR) & 0x10))        fdd->fdc->result[fdd->fdc->result_size++] = getbyte(fdd->fdc->base_port);    irq_signaled = 0;    if (irq_timeout)    {        LOG_PRINTF(("[FDC] Timeout!\n"));        return FDC_TIMEOUT;    }

⌨️ 快捷键说明

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