/* rcsid[] = "$Header: fd.h,v 800.0 85/08/06 14:13:31 root Exp $" */
/* sccsid[] = "%W% %Y% %Q% %G%" */



		/**************************/
		/*    GLOBAL VARIABLES    */
		/**************************/

#if defined(KERNEL) && !defined(BOOT)
static int oldcyl, fdoffset;
static unsigned char ST0, ST1, ST2, ST3;
struct iobuf fdtab;
struct buf fdrbuf, fdcbuf;
extern unsigned long fd_offset;
#define IO_ERROR	0x10	/* flag for severe i/o errors	*/
#endif /* KERNEL, BOOT */


		/******************/
		/*    MACROS      */
		/******************/

#define FD_NDRIVES	4
#define FD_DRIVEMASK	(FD_NDRIVES - 1)
#define fd_drive(d)	(minor(d)&FD_DRIVEMASK) /* drive number in slot */
#define fd_slot(d)	(((minor(d)>>2)&3)+1)	/* slot numbers start at 0 */
#define fd_part(d)	((minor(d)>>4) &1)	/* partition number */
#define fd_addr(d)	((struct fdregs *)(IOBASE+0x30000)+fd_slot(d))
#define fd_off(d)	(fd_part(d) * fd_offset)

		/*****************************/
		/*     DEVICE STRUCTURES     */
		/*****************************/

	/* structure to hold registers for this device */
struct fdregs {
	unsigned char 	fill0;		/* fill half of word address	*/
	unsigned char	ctlDATA;	/* 	Data register		*/
	unsigned char 	fill1;		/* fill half of word address	*/
	unsigned char	ctlSTATUS;	/*	Status register 	*/
	unsigned char 	fill2;		/* fill half of word address	*/
	unsigned char	ctlCNTR;	/*	Counter			*/
	unsigned char 	fill3;		/* fill half of word address	*/
	unsigned char	ctlBUF;		/*	Buffer			*/
	unsigned char 	fill4;		/* fill half of word address	*/
	unsigned char	ctlLOCAL;	/* 	Local card register 	*/
	unsigned short	fill[11];	/* to make struct 32 bytes	*/
} ;
	/* disk information for each sector size and density */
	/* drive and disk type determined at open time */
struct fd_type {
	short 	f_size;		/* size of disk (8" or 5")		*/
	short 	f_dens;		/* density				*/
	short	f_bytsec;	/* number of bytes per sector		*/
	short	f_sectrk;	/* number of sectors per track 		*/
	short	f_trkcyl;	/* number of tracks/cylinder (sides)	*/
	short	f_cyldsk;	/* number of cylinders per disk		*/
	int	f_gapln;	/* gap 3 length	(for r/w and format) 	*/
	int	f_ctl;		/* extra space for ioctl argument	*/
} fd_type ;

		/*************************************/
		/*     MAIN STATUS REGISTER BITS     */
		/*************************************/

#define D0_BUSY		0x01	/* Drive 0 busy in Seek mode 		*/
#define D1_BUSY		0x02	/* Drive 1 busy in Seek mode 		*/
#define D2_BUSY		0x04	/* Drive 2 busy in Seek mode 		*/
#define D3_BUSY		0x08	/* Drive 3 busy in Seek mode 		*/
#define FDC_BUSY	0x10	/* Controller busy doing read/write 	*/
#define N_DMA		0x20	/* Non-DMA mode operation 		*/
#define DATA_DIR_RD	0x40	/* Data direction bit: input or output  */
#define DREG_RDY	0x80	/* Ready to send/rcv data at data reg 	*/



		/*******************************/
		/*     LOCAL CARD REGISTER     */
		/*******************************/

/* COMMAND BITS (WRITE ONLY) */

#define DEV_SEL0	0x01	/* drive select bit 0			*/
#define DEV_SEL1	0x02	/* drive select bit 1			*/
#define DRV_SEL		0x04	/* drive select enable			*/
#define MOTOR_OFF	0x08	/* contrlr reg motor OFF bit 		*/
#define MOTOR_ON	0x00	/* psuedo flag for mtr on (not mtr off)	*/
#define ENBL_INT	0x20	/* enable interrupt to processor	*/
#define DMA_RD		0x40	/* DMA dir: 1=read, 0=write		*/
#define DMA_WR		0x00	/* psuedo flag for DMA dir		*/
#define RESET		0x80	/* reset FDC				*/

/* STATUS BITS (READ ONLY) */

#define DISKCHG		0x01
#define N_IRQ		0x02
#define N_DRV_RDY	0x40
#define N_MINI		0x80	/* 1=5 1/4in  -  0=8in			*/

		/***************************************/
		/*     RETURN STATUS REGISTER BITS     */
		/***************************************/


	/***ST0*** 	INTERRUPT RETURN FLAGS */

#define UNIT0		0x01	/* Drive select 0 			*/
#define UNIT1		0x02	/* Drive select 1 			*/
#define HD_ADDR		0x04	/* Head Address at time of interrupt 	*/
#define FD_N_RDY	0x08	/* Drive not ready 			*/
#define EQUIP_CK	0x10	/* Equipment Check Error - fault signal */
#define SEEK_END	0x20	/* Seek complete 			*/
#define INT_CODE0	0x40	/* Interrupt Code - 			*/
#define INT_CODE1	0x80	/*   00 - normal termination		*/

	/***ST1*** 	ERROR BITS */

#define LOST_ADD_MRK	0x01	/* Missing data addr mark 		*/
#define WR_PROT		0x02	/* Write Protect Error			*/
#define SEC_N_FND	0x04	/* Sector not found error 		*/
/*			0x08	   not used				*/
#define OVERRUN		0x10	/* FDC did not rcv service in time	*/
#define DATA_ERR	0x20	/* CRC error detected in sec data field */
/*			0x40	   not used				*/
#define END_TRK		0x80	/* sec accessed beyond final sec on trk */

	/***ST2***	BITS */

#define LOST_ADD_MRK	0x01	/* Missing data addr mark 		*/
#define BAD_TRK		0x02	/* Bad track error: cyl addr=FF		*/
#define N_SCAN		0x04	/* Scan not satisfied			*/
#define SCAN_HIT	0x08	/* Scan conditin satisfied		*/
#define WRONG_CYL	0x10	/* Cylinder address error		*/
#define DATA_ERR	0x20	/* CRC error detected in sec data field */
#define CTL_MARK	0x40	/* unexpected Control Mark encountered	*/
/*			0x80	   not used				*/

	/***ST3***	 STATUS OF SIGNALS FROM SELECTED DRIVE */

/*#define UNIT0		0x01	/* indicates selected drive 		*/
/*#define UNIT1		0x02	/* indicates selected drive	 	*/
/*#define HD_ADDR	0x04	/* status of side select signal		*/
#define TWO_SIDE	0x08 	/* status of two-sided side signal	*/
#define TRK0		0x10	/* status of track 0 signal		*/
#define RDY		0x20	/* status of ready signal		*/
/*#define WR_PROT	0x40	/* status of write protect signal	*/
#define FAULT		0x80	/* status of fault signal		*/

		/****************************/
		/*     DRIVE PARAMETERS     */
		/****************************/

#define TIMEOUT		50000	/* number of tries for a timeout	*/
#define NSLOT		4	/* number of slots 			*/
#define NDRIVE		3	/* drives per slot 			*/
#define SRT		0x0C 	/* step rate time - ms.			*/
#define HLT		25	/* head load time/2  - ms.		*/
#define HUT		1	/* head unload time/16 - ms.		*/
#define ND		0	/* DMA mode				*/


		/*****************************/
	 	/*    TABLE OF GAP LENGTHS   */
		/*****************************/

/* each integer value for the gap length holds the read/write gap in 	*/
/*	its upper half and the formatting gap in its lower half		*/
unsigned int GAPS[6][2] = {
	{ 0x071B,   0x0000 },	/* 8" s/d & d/d gaps for 128 byts/sec	*/
	{ 0x0E2A,   0x0E36 },	/* 8" s/d & d/d gaps for 256 byts/sec	*/
	{ 0x1B3A,   0x1B54 },	/* 8" s/d & d/d gaps for 512 byts/sec	*/
	{ 0x1019,   0x0000 },	/* 5" s/d & d/d gaps for 128 byts/sec	*/
	{ 0x1830,   0x2032 },	/* 5" s/d & d/d gaps for 256 byts/sec	*/
	{ 0x4687,   0x2A50 }	/* 5" s/d & d/d gaps for 512 byts/sec	*/
};

		/**********************/
		/*    DRIVE STATES    */
		/**********************/

#define S_IDLE		0x01	/* drive busy but idle			*/
#define S_SEEK		0x02	/* drive seeking			*/
#define S_XFER		0x03	/* drive doing a transfer		*/


		/*****************************/
		/*    CONTROLLER COMMANDS    */
		/*****************************/

#define C_VERIFY	0x02	/* read a track and report arrors 	*/
#define C_SPEC		0x03	/* specify				*/
#define C_SDS		0x04	/* sense drive status			*/
#define C_WRITE		0x05	/* write				*/
#define C_READ		0x06	/* read					*/
#define C_RECAL		0x07	/* recal				*/
#define C_SIS		0x08	/* sense interrupt status		*/
#define C_READ_ID	0x0A	/* read first good sector ID on track	*/
#define C_FORMAT	0x0D	/* format a track			*/
#define C_SEEK		0x0F	/* seek					*/
#define C_SET_TYPE	0x10	/* get current type of disk		*/
#define C_TELL_TYPE	0x20	/* set current type of disk		*/
#define C_MFM_BIT	0x40	/* set to double density		*/
#define C_RESET		0x80	/* reset the controller chip		*/
