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