💾 Archived View for mirrors.apple2.org.za › archive › apple.cabi.net › FAQs.and.INFO › DiskDrives › … captured on 2024-12-17 at 12:56:35.

View Raw

More Information

⬅️ Previous capture (2023-01-29)

-=-=-=-=-=-=-

Path: blue.weeg.uiowa.edu!news.uiowa.edu!hobbes.physics.uiowa.edu!math.ohio-state.edu!howland.reston.ans.net!cs.utexas.edu!news.tamu.edu!not-for-mail
From: jdb8042@tamsun.tamu.edu (John Donald Baker)
Newsgroups: comp.sys.apple2
Subject: IDE data definitions.
Date: 6 Oct 1994 16:06:01 -0500
Organization: Texas A&M University, College Station
Lines: 172
Message-ID: <371orp$cnu@tamsun.tamu.edu>
NNTP-Posting-Host: tamsun.tamu.edu

Having received some positive feedback on my earlier IDE article,
I dug up my definitions for IDE registers, bit masks, command
bytes and the elusive ID record.

In general, to operate an IDE drive, wait for the BUSY bit in the
STATUS register to become 0.  Write the appropriate cylinder, sector,
count, drive, and head data to the corresponding Task File registers,
then write the command byte to the command register.  Again, wait for
the BUSY bit to become 0 again.  Then read or write data as appropriate.
The error bits in the STATUS and ERR registers may be read at any time
before the next command is issued.

To read the IDE ID record, issue the IDENTIFY ($EC) command and read
the "sector" that the drive returns.  It's structure is defined below.

Here, then are handy IDE definitions in the form of a C header file:

------------------------begin WD-IDE.H----------------------------------
/* Definitions for communicating with Western Digital WD100x series */
/* of hard disk controllers or with modern IDE drives using an      */
/* appropriate host adapter to map the 16-bit IDE data register to  */
/* a single 8-bit I/O port.                                         */
 
/* Define the symbol IDE_DRV to use an IDE drive.  UNdefine the	    */
/* the symbol (or leave undefined) to use a WD100x controller	    */
 
#ifndef WD_IDE_H	/* to avoid multiple definition */
#define WD_IDE_H
 
 
/* define relative addresses of WD100x and IDE task file registers */
/* add these to the base address for your machine's HD controller */
 
#define O_DATA		0
#define O_ERROR		1	/* read only */
#define O_WR_PRCMP	1	/* write only */
#define O_SEC_CNT	2
#define O_SECTOR	3
#define O_CYL_LOW	4
#define O_CYL_HIGH	5
#define O_SDH		6
#define O_STATUS	7	/* read only */
#define O_COMMAND	7	/* write only */
 
 
/* define additional registers in IDE drive accessed with CS1* line */
 
#ifdef IDE_DRV
#define O_ALTSTAT	6	/* read only */
#define O_DIG_OUT	6	/* write only */
#define O_DRVADDR	7	/* read only */
#endif /* IDE_DRV */
 
 
/* define command bytes common to both the WD100x series of hard disk */
/* controllers and modern IDE drives */
 
#define RESTORE		0x10
#define READSEC		0x20
#define WRITESEC	0x30
#define VERIFY		0x40
#define FORMAT		0x50
#define SEEK		0x70
 
 
/* define extra commands supported only by IDE hard disks */
 
#ifdef IDE_DRV
#define EXEC_DIAG   0x90    /* Execute Diagnosicts */
#define SET_PARM    0x91    /* Set Drive Parameters */
#define STANDBY     0xE0
#define IDE_IDLE    0xE1
#define APD_STNDBY  0xE2    /* APD == Auto Power-Down */
#define	APD_IDLE    0xE3
#define RDSECBUF    0xE4    /* Read from Sector Buffer w/o fetching sector */
#define READ_PWR    0xE5
#define IDE_SLEEP   0xE6
#define WRSECBUF    0xE8    /* Write to Sector Buffer w/o writing to disk */
#define IDENTIFY    0xEC    /* request ID record */
#define CACHE_SW    0xEF
#endif /* IDE_DRV */
 
 
/* define bits in status (and alternate status) register(s) */
 
#define BUSY        0x80    /* command in progress, wait until 0 */
#define READY       0x40    /* drive ready */
#define WR_FAULT    0x20    /* WRITE FAULT */
#define SEEK_CMPL   0x10    /* drive seek complete */
#define DRQ         0x08    /* data available or ready to accept data */
#define CORR        0x04    /* ECC corrected an error */
#define INDEX       0x02    /* INDEX pulse from drive not found */
#define ERR         0x01    /* check ERROR register for error status */
 
 
/* define bits in error register */
 
#define BAD_BLK     0x80    /* sector had BAD BLOCK code set */
#define UNCORR      0x40    /* ECC could not correct error */
#define SECID_NF    0x10    /* Sector ID not found */
#define ABORTED     0x04    /* Command aborted */
#define TRK0_ERR    0x02    /* Track 0 not found */
 
 
/* define some maximum values for range checking when forming */
/* values for the SDH register */
 
#ifdef IDE_DRV
#define MAXDRV      1       /* drive mask value */
#define MAXHEAD    15       /* head mask value
#define DRV_SHFT    4       /* shift drive bit right by this much */
#else
#define MAXDRV      3       /* drive mask value */
#define MAXHEAD     7       /* head mask value */
#define DRV_SHFT    3       /* shift drive bits right by this much */
#endif /* IDE_DRV */
 
 
/* define minimum SDH mask.  "OR" this (or add it) to your drive */
/* and head data */
 
#define SDH_MASK    0xA0    /* this sets ECC mode and 512-byte sectors */
 
 
/* define typical minimum drive parameters.  Most IDE drives will */
/* pretend to have at least these parameters */
 
#ifdef IDE_DRV
#define SECSIZE     512     /* IDE only supports 512-byte sectors */
#define MIN_SEC       1     /* IDE sector numbers start at 1 by default */
#else
#define MIN_SEC	      0
#endif /* IDE_DRV */
 
 
/* define structure of IDE drive ID record */
 
#ifdef IDE_DRV
typedef struct _ide_id
  {
    unsigned int config;	/* configuration word */
    unsigned int n_f_cyl;	/* number of fixed cylinders */
    unsigned int n_r_cyl;	/* number of removable cylinders */
    unsigned int n_heads;	/* number of heads */
    unsigned int byt_trk;	/* bytes per track */
    unsigned int byt_sec;	/* bytes per sector */
    unsigned int sec_trk;	/* sectors per track */
    unsigned int byt_isg;	/* # bytes in inter-sector gaps */
    unsigned int byt_sync;	/* # bytes in synch fields */
             int d0;            /* placeholder? */
    char ser_no[20];	        /* controller serial number */
    unsigned int ctltype;	/* controller type */
    unsigned int bufrsize;	/* internal cache size (sectors) */
    unsigned int n_eccbyt;	/* number of ECC bytes */
    char ctlrvsn[8];	        /* controller revision ID */
    char ctlmodl[40];		/* controller model name */
    unsigned int sec_int;	/* sectors per interrupt */
    unsigned int dbl_wrd;	/* Double Word Flag (?) */
    unsigned int wr_prot;	/* drive write protected? */
    char _rsrvd[412];		/* unused bytes in ID record */
  } IDE_ID;
#endif /* IDE_DRV */
 
#endif /* WD_IDE_H */

--------------------------end WD-IDE.H----------------------------


John D. Baker  ->A TransWarp'802'd Apple //e CardZ180 Z-System nut//
Internet:  jdb8042@tamsun.tamu.edu, @blkbox.com, jdbaker@taronga.com
BBSs:  JOHN BAKER on PIC of the Mid-Town [(713) 961-5817] 1:106/31,
The Vector Board [(716) 544-1863], Z-Node #45 [(713) 937-8886]