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

📄 fl_drver.c

📁 ertfs文件系统里面既有完整ucos程序
💻 C
📖 第 1 页 / 共 5 页
字号:
#if (USE_DMA)

//DM: added
 #if defined(PME)
        // use buffer we created in memory below 1MB
        if (n_todo > DMA_BUF_SECTS)
            n_todo = DMA_BUF_SECTS;
 #else
        /* see how many blocks are left in the dma page containing buffer */
        utemp = fl_dma_chk((DMAPTYPE) buffer);
        if (!utemp)
        {
            /* None left in this page. use a local buffer for 1 block */
            n_todo = 1;
            use_dma_buff = TRUE;
        }
        else
        {
            /* Dma right to user space. Don't wrap the segment */
            use_dma_buff = FALSE;
            if (utemp < n_todo)
                n_todo = utemp;
        }
 #endif /* PME */ //DM: end of added

#endif /* (USE_DMA) */

        utemp = cyl;
        /* Double step on 360 K disks in 1.2M drives */
        if (floppy[unit_number].double_step)
            utemp <<= 1;

        fl_motor_on(unit_number);

        if (!fl_seek(unit_number, utemp, head))
            return(fl_report_error(FLERR_SEEK, FALSE));
#if (!USE_DMA)
        shadow_dig_out &= ~DORB_DMAEN;
        fl_write_dor(shadow_dig_out);
#else
        /* Set up the dma controller */

//DM: added conditional for PME
       #if defined(PME)
        if (!reading)          /* copy to a low buf before writing */
            WriteRealMem(lo_buf_prot, buffer, (n_todo << 9));
        if (!fl_dma_init(lo_buf_real, (word) (n_todo << 9), reading))
            return(fl_report_error(FLERR_DMA, FALSE));
       #else

        if (use_dma_buff)
        {
            if (!reading)       /* copy to a local buf before writing */
                WriteRealMem(dma_buffer, buffer, (n_todo << 9));
            if (!fl_dma_init((DMAPTYPE)dma_buffer, (word) (n_todo << 9), reading))
                return(fl_report_error(FLERR_DMA, FALSE));
        }
        else
        {
            /* Never run in protoected mode */
            if (!fl_dma_init((DMAPTYPE) buffer,(word) (n_todo << 9), reading))
                return(fl_report_error(FLERR_DMA, FALSE));
        }
       #endif // PME
#endif /* USE_DMA */

        /* Send the command to the 765 floppy controller */
        b.n_to_send = 9;       
        b.n_to_get = 7;
#if (USE_DMA)
        if (reading)
            b.commands[0] = MTBIT|MFMBIT|FL_READ;
        else
            b.commands[0] = MTBIT|MFMBIT|FL_WRITE;
#else
        if (reading)
            b.commands[0] = MFMBIT|FL_READ;
        else
            b.commands[0] = MFMBIT|FL_WRITE;
#endif

        b.commands[1] = (byte) ((head << 2)|unit_number);
        b.commands[2] = (byte) cyl;
        b.commands[3] = (byte) head;
        b.commands[4] = (byte) (sec+1);
        b.commands[5] = (byte) 2;               /* byte length 512 */ 
#if (USE_DMA)
        b.commands[6] = (byte) (floppy[unit_number].sectors_per_track);/*  EOT */
#else
        b.commands[6] = (byte) (sec+n_todo); /* HACK SET EOT to the sector */
#endif
        b.commands[7] = (byte) floppy[unit_number].gpl_read;    /*  GPL */
        b.commands[8] = (byte) 0xff;            /*  DTL = ff since N == 512 */

        fl_motor_on(unit_number);
#if (USE_DMA)
        /* Clear any outstanding interrupt complete messages */

        OS_FLOPPY_SIGNAL_BIND(0);
        OS_FLOPPY_SIGNAL_CLEAR(0);
        if (!fl_command_phase(&b))
        {
            return(fl_report_error(FLERR_CHIP_HUNG, FALSE));
        }

        /* Wait for the transfer to complete. (In programmed IO situations
           do the actual transfer) */
        if (!fl_waitdma((int)FLTMO_IO))
            return(fl_report_error(FLERR_IO_TMO, FALSE));

        /* If we read into a local buffer we need to copy it now to user space */
//DM: added PME conditional
       #if defined(PME)
        if (reading)
            ReadRealMem(buffer, lo_buf_prot, (n_todo << 9));
       #else
        if (use_dma_buff && reading)
            ReadRealMem(buffer, dma_buffer, (n_todo << 9));
       #endif // PME
#else
        for (i = 0; i < 10; i++)
            if ((ready = fl_ready())== FL_TOHOST)
                fl_read_data();
            else
                break;
        for (i = 0; i < b.n_to_send; i++)
        {
            if ((ready = fl_ready()) != FL_FRHOST)
            {
            do {
                fl_read_data();
                } while ((ready = fl_ready())== FL_TOHOST);
            }
            /* Write command bytes. On the last byte call the read routine
               so it can set up the last command byte and be ready to
               read the data without overruns */
            if (i < (b.n_to_send-1))
                fl_write_data(b.commands[i]);
            else
            {
                if (reading)
                    polled_read(buffer, n_todo<<9, b.commands[i]);
                else
                    polled_write(buffer, n_todo<<9, b.commands[i]);
            }
        }
        /* Out of dma mode */
        shadow_dig_out |= DORB_DMAEN;
        fl_write_dor(shadow_dig_out);
#endif /* USE_DMA */

        if (!fl_results_phase(&b))
            return(fl_report_error(FLERR_CHIP_HUNG, FALSE));

#if (USE_DMA)
            /* Check status registers. We will elaborate on this later */
        if (b.results[0] & (BIT7|BIT6))
            return(fl_report_error(FLERR_ABN_TERM, FALSE));

        /* Check the head/sector/track against what it should be */
        final_sec = (word) (sec + n_todo);
        final_cyl = cyl;
        final_head = head;

        if (final_sec > floppy[unit_number].sectors_per_track)
        {
            final_head = 1;
            final_sec = (word) (final_sec - floppy[unit_number].sectors_per_track);
        }

        if (final_sec < floppy[unit_number].sectors_per_track)
            final_sec += (word)1;
        else if (final_sec == floppy[unit_number].sectors_per_track)
        {
            final_sec = 1;
            if (final_head == 1)
            {
                final_cyl += (word)1;
                final_head = 0;
            }
            else
                final_head = 1;
        }

        if ( (b.results[3] != (byte) final_cyl)  ||
             (b.results[4] != (byte) final_head) ||
             (b.results[5] != (byte) final_sec) )
        {
            return(fl_report_error(FLERR_IO_SECTOR, FALSE));
        }
#else
        /* Check status registers. We will elaborate on this later */
        if (b.results[0] & (BIT7|BIT6))
        {
            if ((b.results[0]&(BIT7|BIT6)) == BIT6)
            {
                if (b.results[1] & BIT4)
                {
                    return(FALSE);
                }
                else if (b.results[1] & BIT7)
                {
                    goto ignore_eot;
                }
            }
            return(fl_report_error(FLERR_ABN_TERM, FALSE));
        }
ignore_eot:
        /* Check the head/sector/track against what it should be */
        final_sec = (word) (sec + n_todo);
        final_cyl = cyl;
        final_head = head;
/* NOTE: In nondma mode finals are all set */
        if ( (b.results[3] != (byte) final_cyl)  ||
             (b.results[4] != (byte) final_head) ||
             (b.results[5] != (byte) final_sec) )
        {
                return(fl_report_error(FLERR_IO_SECTOR, FALSE));
        }

#endif
         if (!count)
            break;

        /* Add n transfered to the sector.
           If we wrapped the track reset the sector pointer.
           This wrap will occur almost every time. When we have a dma 
           wrap condition we truncated the sector count and will not
           wrap
        */

        sec = (word) (sec + n_todo);
        if (sec >= floppy[unit_number].sectors_per_track)
        {
            sec = 0;
            if (head)
            { 
                head = 0;
                cyl += (word)1;
            }
            else
                head = 1;
        }

        count = (word) (count - n_todo);
        buffer += (n_todo<<9);

        /* Read the rest of the blocks or to the end of track. Whichever is less */
        /* Note: sec will usually be 0. unless a dma segment wrap occured. */
        utemp = (word) (floppy[unit_number].sectors_per_track - sec);
        if (count < utemp)
            n_todo = count;
        else
            n_todo = utemp;
    }

    return (TRUE);
}


/* floppy_format - Format a floppy disk.
* 
* Summary:
*
* BOOLEAN floppy_format(driveno, drivesize, interleave)
*
*
* Inputs:
*   word driveno      - 0 or 1 = a: b:
*   int drivesize     - 360,1200,1440,720
*   int interleave    - interleave factor. (1 ==s no interleave gap)
*
* Returns:
*   TRUE on success else FALSE.
*   
*   This routine formats every track on the drive. Before doing so it 
*   validates the interleave and returns if it is wrong. The interleave
*   must be either 1 or it must follow these two rules. 
*   It may not divide evenly into sectors/track and if sectors/track is an
*   even number interleave must be odd. If  sectors/track is an odd number
*   interleave must be even.
*
*   This routine is portable
*       
*/

BOOLEAN floppy_format(int  driveno, int drivesize, int interleave) /*__fn__*/
{
COMMAND_BLOCK b;
int parmindex;
byte cylinder;
byte sector;
byte head;
int index;

//DM: added PME16 case
#if defined(PME16)
byte far *sec_info;
#else
byte *sec_info;
#endif

word utemp;
BLKBUFF *buf;
byte *parms_buffer;
#if (!USE_DMA)
int i;
int ready;
int residual;
#endif    

    if (!interleave)
        return(FALSE);

    buf = pc_scratch_blk();
    parms_buffer = buf->data;

    for (parmindex = 0; fl_devparms[parmindex].drive_size; parmindex++)
    {
        if ( (fl_devparms[parmindex].drive_size == drivesize) &&
            (floppy[driveno].drive_type == fl_devparms[parmindex].drive_type) )
            break;
    }
    if (!fl_devparms[parmindex].drive_size)
     {
          pc_free_buf(buf,TRUE);
        return(fl_report_error(FLERR_UNK_DRIVE, FALSE));
     }

    if ((interleave > 1))
    {
        /* Interleave can not be an even multiple of sec/per track */
        if ( (fl_devparms[parmindex].sectors_per_track%interleave == 0) ||
        /* Must be odd/even  or even/odd */
           ((fl_devparms[parmindex].sectors_per_track & 0x01) == (interleave & 0x01) ) )
              {
                     pc_free_buf(buf,TRUE);
                return(fl_report_error(FLERR_INVALID_INTERLEAVE, FALSE));
              }
    }

    /* load the floppy table from the device desc table. */
    fl_cp_parms(driveno, parmindex);

    fl_write_drr(floppy[driveno].data_rate);
    if (!fl_specify(driveno))
     {
         pc_free_buf(buf,TRUE);
        return(fl_report_error(FLERR_SPECIFY, FALSE));
     }

    fl_motor_on(driveno);
    if (!fl_recalibrate(driveno))
     {
          pc_free_buf(buf,TRUE);
        return(fl_report_error(FLERR_RECAL, FALSE));
     }

    for (cylinder = 0; cylinder < fl_devparms[parmindex].cylinders_per_disk; cylinder++)
    {
     /* print running status */
#if (!defined(ERTFS_SA))
        DEBUG_ERROR("Formatting track of total tracks", EBS_INT2, (int)cylinder, (int)(fl_devparms[parmindex].cylinders_per_disk-1));
#else
        tm_printf_3("Formatting %d track of %d total tracks\r",  (int)cylinder, (int)(fl_devparms[parmindex].cylinders_per_disk-1));
#endif

        fl_motor_on(driveno);
        for (head = 0; head < 2; head++)
        {
            utemp = cylinder;
            if (floppy[driveno].double_step)
                utemp <<= 1;
            if (!fl_seek(driveno, utemp, head))
                {
                     pc_free_buf(buf,TRUE);
                return(fl_report_error(FLERR_SEEK, FALSE));
                }
            index = 0;
            /* build of the sector IDs. Include interleave calculation */
            for (sector = 1; sector <= fl_devparms[parmindex].sectors_per_track; sector++)
            {
//DM: added PME conditional
               #if defined(PME)
                sec_info    = lo_buf_prot+(index*4);
               #else
                sec_info    = &parms_buffer[(index*4)];
               #endif

                *sec_info++ = cylinder;
                *sec_info++ = head;
                *sec_info++ = sector;
                *sec_info   = 0x02;         /* N = 2 for 512 byte sectors */
                /* These three line do the interleave calulation */
                index = (int)(index + interleave);
                if (index >= (int) fl_devparms[parmindex].sectors_per_track)
                    index = (int) (index - fl_devparms[parmindex].sectors_per_track);
            }

            b.n_to_send = 6;       
            b.n_to_get = 7;
            b.commands[0] = (byte) (MFMBIT|FL_FORMAT);
            b.commands[1] = (byte) ((head << 2)|driveno);
            b.commands[2] = (byte) 0x02;   /* bytes/sector */
            b.commands[3] = (byte) fl_devparms[parmindex].sectors_per_track;
            b.commands[4] = (byte) fl_devparms[parmindex].gpl_format;
            b.commands[5] = (byte) FORMAT_FILLER;
#if (USE_DMA)
            /* Set up to write sec_per_track * 4 bytes */
            /* Copy the format parameters to a real mode buffer */
//DM: added PME conditional
           #if defined(PME)
            if (!fl_dma_init((DMAPTYPE) lo_buf_real,(word)((fl_devparms[parmindex].sectors_per_track)<<2), FALSE))
           #else

⌨️ 快捷键说明

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