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