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

📄 fd.c

📁 微操作系统(c++)
💻 C
字号:
/*
 *  LittleOS
 *  Copyright (C) 1998 Eran Rundstein
 *
 *  This program 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.
 *
 *  This program 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 this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

/*
 * fd.c - floppy disk handling
 */

#include <kernel.h>
#include <types.h>

static uchar version;
static uchar cmos_type;
static uchar type;

static uchar motor_mask = 0;

static uint cur_op = 0;
static uint cur_drv;
static uint cur_head;
static uint cur_trk;

#define FD_SEEK   0x02

/*
 * max no of floppies supported
 */
#define     NFD      (2)

#define     FD_BASEIO   0x3F0

#define     F_MASTER 	0x80
#define     F_DIR    	0x40
#define     F_CMDBUSY   0x10

#define     FD_DATA     0x05
#define     FD_STATUS   0x04

/* 
 * fdc commands 
 */
#define     FDC_VERSION    0x10
#define     FDC_INTS       0x08  /* SENSEI */
#define     FDC_RESET      0x04  /* SENSE */
#define     FDC_SEEK       0x0F

#define     FDC_VER_765A   0x80
#define     FDC_VER_765B   0x90

#define     FDTYPE_MASK 0x0F

#define     FDTYPE_NONE 0x00
#define     FDTYPE_360  0x01
#define     FDTYPE_1200 0x02
#define     FDTYPE_720  0x03
#define     FDTYPE_1440 0x04
#define     FDTYPE_2880 0x05

#define     ENABLE_INTS 0x0C

#define     FD_MOTOR 	0x02

#define     MOTOR_0     0x10
#define     MOTOR_1     0x20

#define     RTCSEL      0x70
#define     RTCDATA     0x71

#define     NVRAM_FD 	0x10


uchar
fd_in()
{
   uint c;
   int r;

   c = 1000000;

   do {
      r = (inb(FD_BASEIO+FD_STATUS) 
         & (F_MASTER | F_DIR | F_CMDBUSY));
      if( r == (F_MASTER | F_DIR | F_CMDBUSY ))
         break;
      c--;
   } while(c);
   
   if( c == 0 )
      return 0;

   return inb(FD_BASEIO+FD_DATA);
}

void
fd_out(byte val)
{
   uint c;
   int r;

   c = 1000000;

   do {
      r = (inb(FD_BASEIO+FD_STATUS) & (F_MASTER | F_DIR));
      if( r == F_MASTER)
         break;
      c--;
   } while(c);

   if( c == 0 ) {
      printk("fd_out: timeout\n");
      return;
   }
   
   outb(FD_BASEIO+FD_DATA, val);
}

void 
fd_reset()
{
   /*
   outb(0x03f2, 0x08);
   for(c = 0; c < 10000; c++);
   outb(0x03f2, 0x0C);
   */

   int c;

   cli();

   outb(FD_BASEIO+FD_MOTOR, 0);
   outb(FD_BASEIO+FD_MOTOR, ENABLE_INTS);

   sti();

   for(c = 0; c < 10000; c++);
}

void 
fd_start(int drive)
{
   motor_mask |= drive;
   if( drive == 0x00 ) {
      motor_mask |= MOTOR_0;
   } else {
      motor_mask |= MOTOR_1;
   }
   outb(FD_BASEIO+FD_MOTOR, motor_mask);
}

void 
fd_stop(int drive)
{
   if( drive == 0x00 ) {
      motor_mask &= ~MOTOR_0;
   } else {
      motor_mask &= ~MOTOR_1;
   }
   outb(FD_BASEIO+FD_MOTOR, motor_mask);
}

void
fd_seek()
{
   cur_op = FD_SEEK;
   cur_head = 0;
   cur_trk = 0;
   cur_drv = 0;

   fd_out(FDC_SEEK);
   fd_out((cur_head << 2) | cur_drv);
   fd_out(cur_trk);
}


void fd_init()
{
   int c;
   uint l;
   printk("\eRInitializing FDC: \eN");	
   fd_reset();

   fd_out(FDC_VERSION);
   version = fd_in();
   printk("Version %d found: ", version);

   if( version == FDC_VER_765A )
      printk("stardard FDC found\n");
   else
   if( version == FDC_VER_765B )
      printk("enhanced FDC found\n");
   else
   if( version == 0 )
      printk("timeout\n");
   else
      printk("unknown controller\n");

   for(c = 0; c < NFD; ++c) {
      outb(RTCSEL, NVRAM_FD);
      cmos_type = inb(RTCDATA);

      type = (cmos_type >> (4 * (NFD - 1 - c ))) & FDTYPE_MASK;

      switch(type) {
         case FDTYPE_1200:
            printk("\tfd_init -> %d : 1.2MB floppy drive found\n",c);
            break;
         case FDTYPE_1440:
            printk("\tfd_init -> %d : 1.44MB floppy drive found\n",c);
            break;
         default:
            printk("\tfd_init -> %d : no drive\n",c);
            break;
      }
   }

   motor_mask |= (FDC_INTS | FDC_RESET);

   fd_start(0);
   for(l = 0; l < 1000000; l++);
   fd_stop(0);

   /*
   printk("trying to seek...\n");
   fd_start(0);
   fd_seek();
   for(l = 0; l < 10000000; l++);
   fd_stop(0);
   */
}

void fd_isr(unsigned long irq)
{
}

⌨️ 快捷键说明

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