xref: /plan9/sys/src/9/pc/floppy.h (revision dc5a79c1208f0704eeb474acc990728f8b4854f5)
17dd7cddfSDavid du Colombier typedef	struct FController FController;
27dd7cddfSDavid du Colombier typedef	struct FDrive FDrive;
37dd7cddfSDavid du Colombier typedef struct FType FType;
47dd7cddfSDavid du Colombier 
57dd7cddfSDavid du Colombier static void floppyintr(Ureg*);
6*59cc4ca5SDavid du Colombier static int floppyon(FDrive*);
77dd7cddfSDavid du Colombier static void floppyoff(FDrive*);
87dd7cddfSDavid du Colombier static void floppysetdef(FDrive*);
97dd7cddfSDavid du Colombier 
107dd7cddfSDavid du Colombier /*
117dd7cddfSDavid du Colombier  *  a floppy drive
127dd7cddfSDavid du Colombier  */
137dd7cddfSDavid du Colombier struct FDrive
147dd7cddfSDavid du Colombier {
157dd7cddfSDavid du Colombier 	FType	*t;		/* floppy type */
167dd7cddfSDavid du Colombier 	int	dt;		/* drive type */
177dd7cddfSDavid du Colombier 	int	dev;
187dd7cddfSDavid du Colombier 
197dd7cddfSDavid du Colombier 	ulong	lasttouched;	/* time last touched */
207dd7cddfSDavid du Colombier 	int	cyl;		/* current arm position */
217dd7cddfSDavid du Colombier 	int	confused;	/* needs to be recalibrated */
227dd7cddfSDavid du Colombier 	int	vers;
23*59cc4ca5SDavid du Colombier 	int	maxtries;	/* max read attempts before Eio */
247dd7cddfSDavid du Colombier 
257dd7cddfSDavid du Colombier 	int	tcyl;		/* target cylinder */
267dd7cddfSDavid du Colombier 	int	thead;		/* target head */
277dd7cddfSDavid du Colombier 	int	tsec;		/* target sector */
287dd7cddfSDavid du Colombier 	long	len;		/* size of xfer */
297dd7cddfSDavid du Colombier 
307dd7cddfSDavid du Colombier 	uchar	*cache;		/* track cache */
317dd7cddfSDavid du Colombier 	int	ccyl;
327dd7cddfSDavid du Colombier 	int	chead;
337dd7cddfSDavid du Colombier };
347dd7cddfSDavid du Colombier 
357dd7cddfSDavid du Colombier /*
367dd7cddfSDavid du Colombier  *  controller for 4 floppys
377dd7cddfSDavid du Colombier  */
387dd7cddfSDavid du Colombier struct FController
397dd7cddfSDavid du Colombier {
407dd7cddfSDavid du Colombier 	QLock;			/* exclusive access to the contoller */
417dd7cddfSDavid du Colombier 
427dd7cddfSDavid du Colombier 	int	ndrive;
437dd7cddfSDavid du Colombier 	FDrive	*d;		/* the floppy drives */
447dd7cddfSDavid du Colombier 	FDrive	*selected;
457dd7cddfSDavid du Colombier 	int	rate;		/* current rate selected */
467dd7cddfSDavid du Colombier 	uchar	cmd[14];	/* command */
477dd7cddfSDavid du Colombier 	int	ncmd;		/* # command bytes */
487dd7cddfSDavid du Colombier 	uchar	stat[14];	/* command status */
497dd7cddfSDavid du Colombier 	int	nstat;		/* # status bytes */
507dd7cddfSDavid du Colombier 	int	confused;	/* controler needs to be reset */
517dd7cddfSDavid du Colombier 	Rendez	r;		/* wait here for command termination */
527dd7cddfSDavid du Colombier 	int	motor;		/* bit mask of spinning disks */
537dd7cddfSDavid du Colombier };
547dd7cddfSDavid du Colombier 
557dd7cddfSDavid du Colombier /*
567dd7cddfSDavid du Colombier  *  floppy types (all MFM encoding)
577dd7cddfSDavid du Colombier  */
587dd7cddfSDavid du Colombier struct FType
597dd7cddfSDavid du Colombier {
607dd7cddfSDavid du Colombier 	char	*name;
617dd7cddfSDavid du Colombier 	int	dt;		/* compatible drive type */
627dd7cddfSDavid du Colombier 	int	bytes;		/* bytes/sector */
637dd7cddfSDavid du Colombier 	int	sectors;	/* sectors/track */
647dd7cddfSDavid du Colombier 	int	heads;		/* number of heads */
657dd7cddfSDavid du Colombier 	int	steps;		/* steps per cylinder */
667dd7cddfSDavid du Colombier 	int	tracks;		/* tracks/disk */
677dd7cddfSDavid du Colombier 	int	gpl;		/* intersector gap length for read/write */
687dd7cddfSDavid du Colombier 	int	fgpl;		/* intersector gap length for format */
697dd7cddfSDavid du Colombier 	int	rate;		/* rate code */
707dd7cddfSDavid du Colombier 
717dd7cddfSDavid du Colombier 	/*
727dd7cddfSDavid du Colombier 	 *  these depend on previous entries and are set filled in
737dd7cddfSDavid du Colombier 	 *  by floppyinit
747dd7cddfSDavid du Colombier 	 */
757dd7cddfSDavid du Colombier 	int	bcode;		/* coded version of bytes for the controller */
767dd7cddfSDavid du Colombier 	long	cap;		/* drive capacity in bytes */
777dd7cddfSDavid du Colombier 	long	tsize;		/* track size in bytes */
787dd7cddfSDavid du Colombier };
797dd7cddfSDavid du Colombier /* bits in the registers */
807dd7cddfSDavid du Colombier enum
817dd7cddfSDavid du Colombier {
827dd7cddfSDavid du Colombier 	/* status registers a & b */
837dd7cddfSDavid du Colombier 	Psra=		0x3f0,
847dd7cddfSDavid du Colombier 	Psrb=		0x3f1,
857dd7cddfSDavid du Colombier 
867dd7cddfSDavid du Colombier 	/* digital output register */
877dd7cddfSDavid du Colombier 	Pdor=		0x3f2,
887dd7cddfSDavid du Colombier 	Fintena=	0x8,	/* enable floppy interrupt */
897dd7cddfSDavid du Colombier 	Fena=		0x4,	/* 0 == reset controller */
907dd7cddfSDavid du Colombier 
917dd7cddfSDavid du Colombier 	/* main status register */
927dd7cddfSDavid du Colombier 	Pmsr=		0x3f4,
937dd7cddfSDavid du Colombier 	Fready=		0x80,	/* ready to be touched */
947dd7cddfSDavid du Colombier 	Ffrom=		0x40,	/* data from controller */
957dd7cddfSDavid du Colombier 	Ffloppybusy=	0x10,	/* operation not over */
967dd7cddfSDavid du Colombier 
977dd7cddfSDavid du Colombier 	/* data register */
987dd7cddfSDavid du Colombier 	Pfdata=		0x3f5,
997dd7cddfSDavid du Colombier 	Frecal=		0x07,	/* recalibrate cmd */
1007dd7cddfSDavid du Colombier 	Fseek=		0x0f,	/* seek cmd */
1017dd7cddfSDavid du Colombier 	Fsense=		0x08,	/* sense cmd */
1027dd7cddfSDavid du Colombier 	Fread=		0x66,	/* read cmd */
1037dd7cddfSDavid du Colombier 	Freadid=	0x4a,	/* read track id */
1047dd7cddfSDavid du Colombier 	Fspec=		0x03,	/* set hold times */
1057dd7cddfSDavid du Colombier 	Fwrite=		0x45,	/* write cmd */
1067dd7cddfSDavid du Colombier 	Fformat=	0x4d,	/* format cmd */
1077dd7cddfSDavid du Colombier 	Fmulti=		0x80,	/* or'd with Fread or Fwrite for multi-head */
1087dd7cddfSDavid du Colombier 	Fdumpreg=	0x0e,	/* dump internal registers */
1097dd7cddfSDavid du Colombier 
1107dd7cddfSDavid du Colombier 	/* digital input register */
1117dd7cddfSDavid du Colombier 	Pdir=		0x3F7,	/* disk changed port (read only) */
1127dd7cddfSDavid du Colombier 	Pdsr=		0x3F7,	/* data rate select port (write only) */
1137dd7cddfSDavid du Colombier 	Fchange=	0x80,	/* disk has changed */
1147dd7cddfSDavid du Colombier 
1157dd7cddfSDavid du Colombier 	/* status 0 byte */
1167dd7cddfSDavid du Colombier 	Drivemask=	3<<0,
1177dd7cddfSDavid du Colombier 	Seekend=	1<<5,
1187dd7cddfSDavid du Colombier 	Codemask=	(3<<6)|(3<<3),
1197dd7cddfSDavid du Colombier 	Cmdexec=	1<<6,
1207dd7cddfSDavid du Colombier 
1217dd7cddfSDavid du Colombier 	/* status 1 byte */
1227dd7cddfSDavid du Colombier 	Overrun=	0x10,
1237dd7cddfSDavid du Colombier };
1247dd7cddfSDavid du Colombier 
1257dd7cddfSDavid du Colombier 
1267dd7cddfSDavid du Colombier static void
pcfloppyintr(Ureg * ur,void * a)1277dd7cddfSDavid du Colombier pcfloppyintr(Ureg *ur, void *a)
1287dd7cddfSDavid du Colombier {
1297dd7cddfSDavid du Colombier 	USED(a);
1307dd7cddfSDavid du Colombier 
1317dd7cddfSDavid du Colombier 	floppyintr(ur);
1327dd7cddfSDavid du Colombier }
1337dd7cddfSDavid du Colombier 
1347dd7cddfSDavid du Colombier void
floppysetup0(FController * fl)1357dd7cddfSDavid du Colombier floppysetup0(FController *fl)
1367dd7cddfSDavid du Colombier {
1377dd7cddfSDavid du Colombier 	fl->ndrive = 0;
1387dd7cddfSDavid du Colombier 	if(ioalloc(Psra, 6, 0, "floppy") < 0)
1397dd7cddfSDavid du Colombier 		return;
1407dd7cddfSDavid du Colombier 	if(ioalloc(Pdir, 1, 0, "floppy") < 0){
1417dd7cddfSDavid du Colombier 		iofree(Psra);
1427dd7cddfSDavid du Colombier 		return;
1437dd7cddfSDavid du Colombier 	}
1447dd7cddfSDavid du Colombier 	fl->ndrive = 2;
1457dd7cddfSDavid du Colombier }
1467dd7cddfSDavid du Colombier 
1477dd7cddfSDavid du Colombier void
floppysetup1(FController * fl)1487dd7cddfSDavid du Colombier floppysetup1(FController *fl)
1497dd7cddfSDavid du Colombier {
1507dd7cddfSDavid du Colombier 	uchar equip;
1517dd7cddfSDavid du Colombier 
1527dd7cddfSDavid du Colombier 	/*
1537dd7cddfSDavid du Colombier 	 *  read nvram for types of floppies 0 & 1
1547dd7cddfSDavid du Colombier 	 */
1557dd7cddfSDavid du Colombier 	equip = nvramread(0x10);
1567dd7cddfSDavid du Colombier 	if(fl->ndrive > 0){
1577dd7cddfSDavid du Colombier 		fl->d[0].dt = (equip >> 4) & 0xf;
1587dd7cddfSDavid du Colombier 		floppysetdef(&fl->d[0]);
1597dd7cddfSDavid du Colombier 	}
1607dd7cddfSDavid du Colombier 	if(fl->ndrive > 1){
1617dd7cddfSDavid du Colombier 		fl->d[1].dt = equip & 0xf;
1627dd7cddfSDavid du Colombier 		floppysetdef(&fl->d[1]);
1637dd7cddfSDavid du Colombier 	}
1647dd7cddfSDavid du Colombier 	intrenable(IrqFLOPPY, pcfloppyintr, fl, BUSUNKNOWN, "floppy");
1657dd7cddfSDavid du Colombier }
1667dd7cddfSDavid du Colombier 
1677dd7cddfSDavid du Colombier /*
1687dd7cddfSDavid du Colombier  *  eject disk ( unknown on safari )
1697dd7cddfSDavid du Colombier  */
1707dd7cddfSDavid du Colombier void
floppyeject(FDrive * dp)1717dd7cddfSDavid du Colombier floppyeject(FDrive *dp)
1727dd7cddfSDavid du Colombier {
1737dd7cddfSDavid du Colombier 	floppyon(dp);
1747dd7cddfSDavid du Colombier 	dp->vers++;
1757dd7cddfSDavid du Colombier 	floppyoff(dp);
1767dd7cddfSDavid du Colombier }
1777dd7cddfSDavid du Colombier 
1787dd7cddfSDavid du Colombier int
floppyexec(char * a,long b,int c)1797dd7cddfSDavid du Colombier floppyexec(char *a, long b, int c)
1807dd7cddfSDavid du Colombier {
1817dd7cddfSDavid du Colombier 	USED(a, b, c);
1827dd7cddfSDavid du Colombier 	return b;
1837dd7cddfSDavid du Colombier }
184