xref: /plan9/sys/src/9/pc/floppy.h (revision dc5a79c1208f0704eeb474acc990728f8b4854f5)
1 typedef	struct FController FController;
2 typedef	struct FDrive FDrive;
3 typedef struct FType FType;
4 
5 static void floppyintr(Ureg*);
6 static int floppyon(FDrive*);
7 static void floppyoff(FDrive*);
8 static void floppysetdef(FDrive*);
9 
10 /*
11  *  a floppy drive
12  */
13 struct FDrive
14 {
15 	FType	*t;		/* floppy type */
16 	int	dt;		/* drive type */
17 	int	dev;
18 
19 	ulong	lasttouched;	/* time last touched */
20 	int	cyl;		/* current arm position */
21 	int	confused;	/* needs to be recalibrated */
22 	int	vers;
23 	int	maxtries;	/* max read attempts before Eio */
24 
25 	int	tcyl;		/* target cylinder */
26 	int	thead;		/* target head */
27 	int	tsec;		/* target sector */
28 	long	len;		/* size of xfer */
29 
30 	uchar	*cache;		/* track cache */
31 	int	ccyl;
32 	int	chead;
33 };
34 
35 /*
36  *  controller for 4 floppys
37  */
38 struct FController
39 {
40 	QLock;			/* exclusive access to the contoller */
41 
42 	int	ndrive;
43 	FDrive	*d;		/* the floppy drives */
44 	FDrive	*selected;
45 	int	rate;		/* current rate selected */
46 	uchar	cmd[14];	/* command */
47 	int	ncmd;		/* # command bytes */
48 	uchar	stat[14];	/* command status */
49 	int	nstat;		/* # status bytes */
50 	int	confused;	/* controler needs to be reset */
51 	Rendez	r;		/* wait here for command termination */
52 	int	motor;		/* bit mask of spinning disks */
53 };
54 
55 /*
56  *  floppy types (all MFM encoding)
57  */
58 struct FType
59 {
60 	char	*name;
61 	int	dt;		/* compatible drive type */
62 	int	bytes;		/* bytes/sector */
63 	int	sectors;	/* sectors/track */
64 	int	heads;		/* number of heads */
65 	int	steps;		/* steps per cylinder */
66 	int	tracks;		/* tracks/disk */
67 	int	gpl;		/* intersector gap length for read/write */
68 	int	fgpl;		/* intersector gap length for format */
69 	int	rate;		/* rate code */
70 
71 	/*
72 	 *  these depend on previous entries and are set filled in
73 	 *  by floppyinit
74 	 */
75 	int	bcode;		/* coded version of bytes for the controller */
76 	long	cap;		/* drive capacity in bytes */
77 	long	tsize;		/* track size in bytes */
78 };
79 /* bits in the registers */
80 enum
81 {
82 	/* status registers a & b */
83 	Psra=		0x3f0,
84 	Psrb=		0x3f1,
85 
86 	/* digital output register */
87 	Pdor=		0x3f2,
88 	Fintena=	0x8,	/* enable floppy interrupt */
89 	Fena=		0x4,	/* 0 == reset controller */
90 
91 	/* main status register */
92 	Pmsr=		0x3f4,
93 	Fready=		0x80,	/* ready to be touched */
94 	Ffrom=		0x40,	/* data from controller */
95 	Ffloppybusy=	0x10,	/* operation not over */
96 
97 	/* data register */
98 	Pfdata=		0x3f5,
99 	Frecal=		0x07,	/* recalibrate cmd */
100 	Fseek=		0x0f,	/* seek cmd */
101 	Fsense=		0x08,	/* sense cmd */
102 	Fread=		0x66,	/* read cmd */
103 	Freadid=	0x4a,	/* read track id */
104 	Fspec=		0x03,	/* set hold times */
105 	Fwrite=		0x45,	/* write cmd */
106 	Fformat=	0x4d,	/* format cmd */
107 	Fmulti=		0x80,	/* or'd with Fread or Fwrite for multi-head */
108 	Fdumpreg=	0x0e,	/* dump internal registers */
109 
110 	/* digital input register */
111 	Pdir=		0x3F7,	/* disk changed port (read only) */
112 	Pdsr=		0x3F7,	/* data rate select port (write only) */
113 	Fchange=	0x80,	/* disk has changed */
114 
115 	/* status 0 byte */
116 	Drivemask=	3<<0,
117 	Seekend=	1<<5,
118 	Codemask=	(3<<6)|(3<<3),
119 	Cmdexec=	1<<6,
120 
121 	/* status 1 byte */
122 	Overrun=	0x10,
123 };
124 
125 
126 static void
pcfloppyintr(Ureg * ur,void * a)127 pcfloppyintr(Ureg *ur, void *a)
128 {
129 	USED(a);
130 
131 	floppyintr(ur);
132 }
133 
134 void
floppysetup0(FController * fl)135 floppysetup0(FController *fl)
136 {
137 	fl->ndrive = 0;
138 	if(ioalloc(Psra, 6, 0, "floppy") < 0)
139 		return;
140 	if(ioalloc(Pdir, 1, 0, "floppy") < 0){
141 		iofree(Psra);
142 		return;
143 	}
144 	fl->ndrive = 2;
145 }
146 
147 void
floppysetup1(FController * fl)148 floppysetup1(FController *fl)
149 {
150 	uchar equip;
151 
152 	/*
153 	 *  read nvram for types of floppies 0 & 1
154 	 */
155 	equip = nvramread(0x10);
156 	if(fl->ndrive > 0){
157 		fl->d[0].dt = (equip >> 4) & 0xf;
158 		floppysetdef(&fl->d[0]);
159 	}
160 	if(fl->ndrive > 1){
161 		fl->d[1].dt = equip & 0xf;
162 		floppysetdef(&fl->d[1]);
163 	}
164 	intrenable(IrqFLOPPY, pcfloppyintr, fl, BUSUNKNOWN, "floppy");
165 }
166 
167 /*
168  *  eject disk ( unknown on safari )
169  */
170 void
floppyeject(FDrive * dp)171 floppyeject(FDrive *dp)
172 {
173 	floppyon(dp);
174 	dp->vers++;
175 	floppyoff(dp);
176 }
177 
178 int
floppyexec(char * a,long b,int c)179 floppyexec(char *a, long b, int c)
180 {
181 	USED(a, b, c);
182 	return b;
183 }
184