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

📄 example2.c

📁 ATADRVR是DOS下的磁盘驱动程序,采用PIO传输 ,PCI DMA传输,ATA包,等非常全面代码示例... 内部有C与Asm描述. 编译环境:Borland C/C++ 4.52 与 Bo
💻 C
📖 第 1 页 / 共 2 页
字号:

// Example2.c -- Some ATAPI command examples

#if 0

   Some simple instructions for those of you that would like to
   compile my driver code and try it.

   1) I've always used Borland C (or C++, the driver code is plain C
   code).  One file contains a few lines of embedded ASM code. You will
   need Borland's TASM too.

   2) I've always used small memory model but I think the driver code
   will work with any memory mode. See the MEMMOD variable in the
   make file (EXAMPLE2.MAK).

   3) The EXAMPLE2.EXE program is a DOS real mode program. It will
   not execute in a DOS session (a virtual x86 session) under Windows!
   You should make a DOS boot floppy and boot your system for it and
   execute the EXAMPLE2.EXE program from that floppy.

   4) Here is a very small program that shows how to use the driver
   code to issue some ATAPI commands.
   This program has one required command line parameter to specify
   the device to run on: P0, P1, S0 or S1.

#endif

//---------- option to include PCI Bus Mastering DMA

#define INCL_PCI_DMA 0     // set to 1 to include PCI DMA

//---------- begin

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dos.h>
#include <conio.h>

#include "ataio.h"

int pciBus  = -1;
int pciDev  = -1;
int pciFun  = -1;
int priSec  = -1;
int dev     = -1;
int irqNum  = -1;

unsigned int cmdBase  = 0xffff;
unsigned int ctrlBase = 0xffff;
unsigned int bmcrBase = 0xffff;

unsigned char * devTypeStr[]
       = { "NO DEVICE", "UNKNOWN TYPE", "ATA", "ATAPI" };

unsigned char cdb[16];
unsigned char far * cdbPtr;

#define BUFFER_SIZE 4096
unsigned char buffer[BUFFER_SIZE];
unsigned char far * bufferPtr;

/*********************************************************/

static void pause( void );

static void pause( void )

{

   // clear any queued up keys
   while ( kbhit() )
   {
      if ( getch() == 0 )
         getch();
   }
   // pause until key hit
   printf( "Press any key to continue...\n" );
   while ( ! kbhit() )
      /* do nothing */ ;
   // clear any queued up keys
   while ( kbhit() )
   {
      if ( getch() == 0 )
         getch();
   }
}

/*********************************************************/

static long get_dnumber( unsigned char * s );

static long get_dnumber( unsigned char * s )

{
   char * cp;
   long val;

   strupr( s );
   if ( strspn( s, "0123456789" ) != strlen( s ) )
      return -1L;
   val = strtol( s, & cp, 0 );
   if ( * cp != 0 )
      return -1L;
   return val;
}

/**********************************************************
**
** get a word of PCI config data from BIOS INT 1AH
**
**********************************************************/

unsigned int GetPciWord( unsigned int busNum, unsigned int devNum,
                         unsigned int funNum, unsigned int regNum );

unsigned int GetPciWord( unsigned int busNum, unsigned int devNum,
                         unsigned int funNum, unsigned int regNum )

{
   union REGS ir, or;

   if ( regNum & 0x0001 )
      return 0xffff;
   ir.x.ax = 0xb109;
   ir.x.bx = ( busNum << 8 ) | ( devNum << 3 ) | funNum;
   ir.x.di = regNum;
   int86( 0x1a, & ir, & or );
   if ( or.x.cflag )
      return 0xffff;
   return or.x.cx;
}

//**********************************************

// a little function to display all the error
// and trace information from the driver

void ShowAll( void );

void ShowAll( void )

{
   int lc = 0;
   unsigned char * cp;

   printf( "ERROR !\n" );

   // display the command error information
   trc_err_dump1();           // start
   while ( 1 )
   {
      cp = trc_err_dump2();   // get and display a line
      if ( cp == NULL )
         break;
      printf( "* %s\n", cp );
   }
   pause();

   // display the command history
   trc_cht_dump1();           // start
   while ( 1 )
   {
      cp = trc_cht_dump2();   // get and display a line
      if ( cp == NULL )
         break;
      printf( "* %s\n", cp );
      lc ++ ;
      if ( ! ( lc & 0x000f ) )
         pause();
   }

   // display the low level trace
   trc_llt_dump1();           // start
   while ( 1 )
   {
      cp = trc_llt_dump2();   // get and display a line
      if ( cp == NULL )
         break;
      printf( "* %s\n", cp );
      lc ++ ;
      if ( ! ( lc & 0x000f ) )
         pause();
   }

   if ( lc & 0x000f )
      pause();
}

//**********************************************

void ClearTrace( void );

void ClearTrace( void )

{

   // clear the command history and low level traces
   trc_cht_dump0();     // zero the command history
   trc_llt_dump0();     // zero the low level trace
}

//**********************************************

int main( int ac, char * av[] )
{
   int numDev;
   int ndx;
   int rc;

   printf( "ATADRVR EXAMPLE2 Version " ATA_DRIVER_VERSION ".\n" );

   //---------- initialization and command line option processing

   printf( "Usage: EXAMPLE2 pciBus pciDev pciFun dev irqNum\n" );
                   // av[n]   1      2      3     4     5
   printf( "       If irqNum is zero it will be defaulted.\n" );

   if ( ac != 6 )
   {
      printf( "Missing or extra command line options !\n" );
      return 1;
   }

   pciBus = (int) get_dnumber( av[1] );
   pciDev = (int) get_dnumber( av[2] );
   pciFun = (int) get_dnumber( av[3] );
   if ( ! stricmp( av[4], "P0" ) )
      {  priSec = 0; dev = 0; }
   if ( ! stricmp( av[4], "P1" ) )
      {  priSec = 0; dev = 1; }
   if ( ! stricmp( av[4], "S0" ) )
      {  priSec = 1; dev = 0; }
   if ( ! stricmp( av[4], "S1" ) )
      {  priSec = 1; dev = 1; }
   irqNum = (int) get_dnumber( av[5] );

   printf( "Device %d %d %d %s%d, IRQ %d in not shared mode.\n",
            pciBus, pciDev, pciFun,
            priSec ? "S" : "P", dev,
            irqNum );

   if ( ( pciBus < 0 ) || ( pciDev < 0 ) || ( pciFun < 0 )
        || ( priSec < 0 ) || ( dev < 0 ) || ( irqNum < 0 ) )
   {
      printf( "Invalid command line option(s) !\n" );
      return 1;
   }

   cmdBase  = GetPciWord( pciBus, pciDev, pciFun, 0x10 + ( 8 * priSec ) );
   ctrlBase = GetPciWord( pciBus, pciDev, pciFun, 0x14 + ( 8 * priSec ) );
   bmcrBase = GetPciWord( pciBus, pciDev, pciFun, 0x20 );
   if (    ( cmdBase == 0xffff )
        || ( ctrlBase == 0xffff )
        || ( bmcrBase == 0xffff ) )
   {
      printf( "PCI information invalid !\n" );
      return 1;
   }
   cmdBase &= 0xfffe;
   ctrlBase &= 0xfffe;
   bmcrBase &= 0xfffe;
   if ( cmdBase == 0 )
   {
      cmdBase  = priSec ? 0x170 : 0x1f0;
      ctrlBase = priSec ? 0x370 : 0x3f0;
      irqNum = priSec ? 15 : 14;
   }
   else
   {
      ctrlBase -= 4;
   }
   if ( priSec )
      bmcrBase += 8;
   printf( "ATA CMD base %04X, ATA CTRL base %04X, BMCR base %04X\n",
            cmdBase, ctrlBase, bmcrBase );

   if ( ! irqNum )
   {
      irqNum = GetPciWord( pciBus, pciDev, pciFun, 0x3c );
      irqNum &= 0x00ff;
      printf( "IRQ defaulted to %d\n", irqNum );
   }

   //---------- initialization

   // initialize far pointer to the I/O buffer
   bufferPtr = (unsigned char far *) buffer;

   // tell ATADRVR how big the buffer is
   reg_buffer_size = BUFFER_SIZE;

   // set the ATADRVR command timeout (in seconds)
   tmr_time_out = 20;

   // initialize far pointer to the CBD buffer
   cdbPtr = (unsigned char far *) cdb;

   //---------- ATADRVR initialization

   // 1) must tell the driver what the I/O port addresses.
   //    note that the driver also supports all the PCMCIA
   //    PC Card modes (I/O and memory).
   pio_set_iobase_addr( cmdBase, ctrlBase, bmcrBase );
   printf( "Using I/O base addresses %04X and %04X.\n", cmdBase, ctrlBase );

   // 2) find out what devices are present -- this is the step
   // many driver writers ignore.  You really can't just do
   // resets and commands without first knowing what is out there.
   // Even if you don't care the driver does care.
   numDev = reg_config();
   printf( "Found %d devices, dev 0 is %s, dev 1 is %s.\n",
                  numDev,

⌨️ 快捷键说明

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