nckernel  0.1
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
fdc.h
Go to the documentation of this file.
1 
14 enum {
16  FD_HEAD = 2,
17  FD_BLKSZ = 512,
18 };
19 
20 /* 0x3F0 ~ 0x3F7 */
25  FDC_PRIMARY = 0x3F0,
26  FDC_SECONDARY = 0x370,
27  FDC_BASE_MAX = 0xFFFF,
28 };
29 
32  SECTOR_128 = 0,
33  SECTOR_256 = 1,
34  SECTOR_512 = 2,
36 };
37 
38 /* IDX:0, R - SRA */
39 #define REG_SRA(base) (base)
40 #define SRA(reg) ((SRA_t*)(ret))
41 
42 typedef struct status_register SRA_t;
44 #if defined(MODE_PS2)
45  unsigned long dir:1;
46  unsigned long b_wp:1;
47  unsigned long b_idx:1;
48  unsigned long hdsel:1;
49  unsigned long b_trk0:1;
50  unsigned long step:1;
51  unsigned long b_drv2:1;
52  unsigned long interrupted:1;
53 #define SRA_RESET_DONE(reg) (!SRA(reg)->interrupted && !SRA(reg)->step && !SRA(reg)->hdsel && !SRA(reg)->dir)
54 #define SRA_INTERRUPTED(reg) (SRA(reg)->interrupted)
55 
56 #elif defined(MODE_MODEL30)
57  unsigned long b_dir:1;
58  unsigned long wp:1;
59  unsigned long index:1;
60  unsigned long b_hdsel:1;
61  unsigned long trk0:1;
62  unsigned long step_ff:1;
63  unsigned long drq:1; /* DMA Request */
64  unsigned long interrupted:1;
65 
66 #define SRA_RESET_DONE(reg) (!SRA(reg)->step_ff)
67 #define SRA_INTERRUPTED(reg) (((SRA_t*)(reg))->interrupted)
68 
69 #elif defined(MODE_PCAT)
70  unsigned char none;
71 #define SRA_RESET_DONE(reg) 1
72 #define SRA_INTERRUPTED(reg) 0
73 #endif
74 };
75 
76 /* IDX:1, R - SRB */
77 #define REG_SRB(base) ((base) + 0x01)
78 #define SRB(reg) ((SRB_t*)(reg))
79 typedef struct status_register_b SRB_t;
81 #if defined(MODE_PS2)
82  unsigned long motor:2;
83  unsigned long we:1;
84  unsigned long rddata_toggle:1;
85  unsigned long wrdata_toggle:1;
86  unsigned long drive_sel0:1;
87  unsigned long reserved:2; /* 11 */
88 #define SRB_RESET_DONE(reg) (!SRB(reg)->rddata_toggle && !SRB(reg)->wrdata_toggle)
89 #elif defined(MODE_MODEL30)
90  unsigned long b_ds_high:2;
91  unsigned long we_ff:1;
92  unsigned long rddata_ff:1;
93  unsigned long wrdata_ff:1;
94  unsigned long b_ds_low:2;
95  unsigned long b_drv2:1;
96 #define SRB_RESET_DONE(reg) (!SRB(reg)->we_ff && !SRB(reg)->rddata_ff && !SRB(reg)->wrdata_ff)
97 #elif defined(MODE_PCAT)
98  unsigned char none;
99 #define SRB_RESET_DONE(reg) 1
100 #endif
101 };
102 
103 /* IDX2, RW - DOR */
104 #define REG_DOR(base) ((base) + 0x02)
106  DRIVE0 = 0x1C,
107  DRIVE1 = 0x2D,
108  DRIVE2 = 0x4E,
109  DRIVE3 = 0x8F,
110 };
111 
114  unsigned long drive:2;
115  unsigned long b_reset:1;
116  unsigned long b_dma_gate:1;
117  unsigned long motor:4;
118 };
119 
120 enum dma_state {
121  DMA = 0x01,
122  NONDMA = 0x00,
123 };
124 
125 #define DOR_RESET(single) \
126 do { \
127  unsigned reg; \
128  DOR_t *dor = (DOR_t*)® \
129  dor->b_reset = 0; \
130  dor->drive = 0; \
131  dor->b_dma_gate = 0; \
132  dor->motor = 0; \
133  outb(REG_DOR(fdc_single_ctrl(single)), reg); \
134 } while (0)
135 
136 #define DOR_ENABLE(single, drv, dma) \
137 do { \
138  unsigned char reg; \
139  DOR_t *dor = (DOR_t*)® \
140  dor->b_reset = 1; \
141  dor->drive = (drv); \
142  dor->b_dma_gate = (dma); \
143  dor->motor = 0x01 << (drv); \
144  outb(REG_DOR(fdc_single_ctrl(single)), reg); \
145 } while (0)
146 
147 /* IDX:3, RW - TDR */
148 #define REG_TDR(base) ((base) + 0x03)
149 typedef struct tape_drive_register TDR_t;
151  unsigned long tape_sel:2;
152  unsigned long none:6;
153 };
154 
155 /* IDX:4, W - DSR */
156 #define REG_DSR(base) ((base) + 0x04)
159  DELAY_41_67ns = 0x01, /* 1Mbps */
161  DELAY_125ns = 0x03, /* 500Kbps, 300Kbps, 250Kbps */
164  DELAY_250ns = 0x06,
166 };
167 
169  DRATE_1Mbps = 0x03, /* 41.67ns */
170  DRATE_500Kbps = 0x00, /* 125ns */
171  DRATE_300Kbps = 0x01, /* 125ns */
172  DRATE_250Kbps = 0x02, /* 125ns */
173 };
174 
177  unsigned long dratesel:2;
178  unsigned long precomp:3;
179  unsigned long zeroed:1;
180  unsigned long power_down:1;
181  unsigned long sw_reset:1;
182 };
183 
184 #define SELECT_DRATE(reg, rate) \
185 do { \
186  DSR_t *dsr = (DSR_t*)(reg); \
187  dsr->dratesel = rate; \
188  switch (dsr->dratesel) { \
189  case DRATE_1Mbps: \
190  dsr->precomp = DELAY_41_67ns; \
191  break; \
192  case DRATE_500Kbps: \
193  dsr->precomp = DELAY_125ns; \
194  break; \
195  case DRATE_300Kbps: \
196  dsr->precomp = DELAY_125ns; \
197  break; \
198  case DRATE_250Kbps: \
199  dsr->precomp = DELAY_125ns; \
200  break; \
201  default: \
202  break; \
203  } \
204 } while (0)
205 
206 /* Auto-toggle reset_pin */
207 #define DSR_RESET(reg) \
208 do { \
209  DSR_t *dsr = (DSR_t*)(reg); \
210  dsr->sw_reset = 1; \
211  dsr->power_down = 1; \
212 } while (0)
213 
214 /* IDX:4, R - MSR */
215 #define REG_MSR(base) ((base) + 0x04)
217  DRIVE_A = 0x00,
218  DRIVE_B = 0x01,
219  DRIVE_C = 0x02,
220  DRIVE_D = 0x03,
221  DRIVE_MAX = 0xFF,
222 };
223 
225  UNDEFINED = 0x00,
229 };
230 
233  unsigned long drive_busy:4;
234  unsigned long cmd_busy:1;
235  unsigned long non_dma:1; /* 1 = during execution phase */
236  unsigned long DIO:1; /* 1 = read is required, otherwise(0) write is required */
237  unsigned long RQM:1; /* 1 = host can transfer data, otherwise 0 */
238 };
239 
240 #define MSR(reg) ((MSR_t*)(reg))
241 #define DIR_OF_DATA(reg) (MSR(reg)->RQM ? (MSR(reg)->DIO ? READ_REQUIRED : WRITE_REQUIRED) : UNDEFINED)
242 #define IN_RESULT_PHASE(reg) (MSR(reg)->cmd_busy)
243 #define IN_SEEK_PORTION(reg) (MSR(reg)->drive_busy)
244 
245 #define REG_FIFO(base) ((base) + 0x05)
246 /* IDX:5, RW - FIFO */
247 /* NO DATA STRUCTURE */
248 
249 /* IDX:6, RESERVED */
250 
251 /* IDX:7, R - DIR */
252 #define REG_DIR(base) ((base) + 0x07)
255 #if defined(MODE_PCAT)
256  unsigned long none:7;
257  unsigned long disk_change:1;
258 #define DISK_CHANGED(reg) (((DIR_t*)(reg))->disk_change)
259 #elif defined(MODE_PS2)
260  unsigned long b_high_dens:1; /* 500Kbps, 1Mbps -> set 1 */
261  unsigned long drate_sel:2;
262  unsigned long reserved:4; /* set 1 */
263  unsigned long disk_change:1;
264 #define DISK_CHANGED(reg) (((DIR_t*)(reg))->disk_change)
265 #elif defined(MODE_MODEL30)
266  unsigned long drate_sel:2;
267  unsigned long no_prec:1;
268  unsigned long b_dma_gate:1;
269  unsigned long reserved:3; /* set 0 */
270  unsigned long b_disk_change:1;
271 #define DISK_CHANGED(reg) (!((DIR_t*)(reg))->disk_change)
272 #else
273  unsigned char none;
274 #endif
275 };
276 
277 /* IDX:7, W -CCR */
278 #define REG_CCR(base) ((base) + 0x07)
281 #if defined(MODE_PCAT) || defined(MODE_PS2)
282  unsigned long drate_sel:2;
283  unsigned long none:6;
284 #elif defined(MODE_MODEL30)
285  unsigned long drate_sel:2;
286  unsigned long no_prec:1;
287  unsigned long none:5;
288 #endif
289 };
290 
291 #define SET_DRATE(reg, drate) (((CCR_t*)(reg))->drate_sel = (drate))
292 
296 };
297 
299  CMD_READ_TRACK = 0x02,
300  CMD_SPECIFY = 0x03,
302  CMD_WRITE_DATA = 0x05,
303  CMD_READ_DATA = 0x06,
307  CMD_READ_ID = 0x0A,
310  CMD_DUMPREG = 0x0E,
311  CMD_SEEK = 0x0F,
312  CMD_VERSION = 0x10,
315  CMD_CONFIGURE = 0x13,
316  CMD_LOCK = 0x14,
317  CMD_VERIFY = 0x16,
321 
322  CMD_EXT_SKIP = 0x20,
325 };
326 
327 enum symbol {
328  EIS = 0x06,
329  EFIFO = 0x05,
330  POLL = 0x04,
331 };
332 
333 /*
334  * 1 ~ 18 = 0 0
335  * 19 ~37 = 1 1
336  * 38 ~56 = 0 2
337  */
338 
343 #define LBA_TO_CHS(lba, h, t, s) \
344 do { \
345  (h) = ((lba) % (FD_SECTOR_PER_TRACK * FD_HEAD)) / FD_SECTOR_PER_TRACK; \
346  (t) = (lba) / (FD_SECTOR_PER_TRACK * FD_HEAD); \
347  (s) = ((lba) % FD_SECTOR_PER_TRACK) + 1; \
348 } while (0)
349 
350 #define VALIDATE_RESULT(ctx) do { \
351  int ret; \
352  unsigned char byte; \
353  ret = read_byte(ctx, &byte); \
354  if (ret < 0 || byte == 0x80) { \
355  printf("Failed to read\n"); \
356  } \
357 } while (0)
358 
359 struct fdc_context {
361 };
362 
363 extern int fdc_init(void);
364 
365 /* @} End of a file */