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