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