Functions | |||||||||
void | fdc_sendbyte (byte b) | ||||||||
Send a byte to the FDC controller.
| |||||||||
int | fdc_getbyte () | ||||||||
Get a byte from the FDC controller.
| |||||||||
void | fdc_motor_on () | ||||||||
Turn the floppy motor on. | |||||||||
void | fdc_motor_off () | ||||||||
Starts the FDC motor kill countdown. | |||||||||
bool | fdc_wait (bool sensei) | ||||||||
Wait for a FDC operation.
| |||||||||
void | fdc_recalibrate () | ||||||||
Recalibrate the floppy drive. | |||||||||
bool | fdc_seek (int track) | ||||||||
Seek a track.
| |||||||||
void | fdc_reset () | ||||||||
Reset the floppy disk controller. | |||||||||
void | lba2chs (int lba, int *track, int *head, int *sector) | ||||||||
Convert from a LBA (Linear Block Address) address to a CHS (Cylinder, Head, Sector) coordinates.
| |||||||||
bool | fdc_rw (int block, byte *buffer, bool do_read) | ||||||||
Perform a read/write operation with the floppy drive using the DMA (Direct Memory Access).
| |||||||||
bool | fdc_read (int block, byte *buffer, uint32_t count) | ||||||||
Read some contiguous blocks from the floppy disk.
| |||||||||
bool | fdc_write (int block, byte *buffer, uint32_t count) | ||||||||
Write some contiguous blocks to the floppy disk.
| |||||||||
bool | fdc_is_changed () | ||||||||
Check if the floppy disk was changed. | |||||||||
void | floppy_thread () | ||||||||
This is a routine called from clock_thread() at every clock tick to perform the floppy motor kill countdown and to control the floppy timeouts. | |||||||||
bool | init_floppy () | ||||||||
Initialize the floppy driver. | |||||||||
Variables | |||||||||
volatile bool | fdc_motor = FALSE | ||||||||
Motor on flag. | |||||||||
volatile int | fdc_timeout = 0 | ||||||||
FDC timeout. | |||||||||
volatile int | fdc_motor_countdown = 0 | ||||||||
Floppy motor kill countdown. | |||||||||
volatile bool | fdc_done = FALSE | ||||||||
FDC operation finish. | |||||||||
volatile bool | fdc_change = FALSE | ||||||||
Disk change flag. | |||||||||
volatile byte | fdc_status [7] = { 0 } | ||||||||
FDC status (result output). | |||||||||
volatile byte | fdc_track = 0xFF | ||||||||
Current head position. | |||||||||
volatile byte | ST0 = 0 | ||||||||
Status register 0. | |||||||||
floppy_struct | floppy_type [] | ||||||||
Floppy types known from the system. | |||||||||
byte | fdc_geometry = 0 | ||||||||
Current floppy geometry. | |||||||||
byte * | fdc_buffer | ||||||||
Floppy r/w buffer. |
|
Get a byte from the FDC controller.
Definition at line 88 of file floppy.c.
|
|
Check if the floppy disk was changed.
Definition at line 411 of file floppy.c.
00412 {
00413 return(fdc_change);
00414 }
|
|
Starts the FDC motor kill countdown.
Definition at line 116 of file floppy.c.
00117 { 00118 if (fdc_motor && (fdc_motor_countdown==-1)) 00119 fdc_motor_countdown = FDC_TIME_MOTOR_OFF/1000*HZ; 00120 } |
|
Turn the floppy motor on.
Definition at line 104 of file floppy.c.
00105 { 00106 if (!fdc_motor) 00107 { 00108 outportb(FDC_DOR, 0x1C); 00109 delay(FDC_TIME_MOTOR_SPINUP); 00110 fdc_motor = TRUE; 00111 } 00112 fdc_motor_countdown = -1; 00113 } |
|
Read some contiguous blocks from the floppy disk.
Definition at line 376 of file floppy.c.
|
|
Recalibrate the floppy drive.
Definition at line 178 of file floppy.c.
00179 { 00180 // Turn the motor on // 00181 fdc_motor_on(); 00182 00183 // Send recalibrate command // 00184 fdc_sendbyte(CMD_RECAL); 00185 fdc_sendbyte(0); 00186 00187 // Wait until recalibrate command is finished // 00188 fdc_wait(TRUE); 00189 00190 // Turn the motor off // 00191 fdc_motor_off(); 00192 } |
|
Reset the floppy disk controller.
Definition at line 235 of file floppy.c.
00236 { 00237 // Stop the motor and disable IRQ // 00238 outportb(FDC_DOR, 0x00); 00239 00240 // Program data rate (500K/s) // 00241 outportb(FDC_DSR, 0x00); 00242 00243 // re-enable floppy IRQ // 00244 outportb(FDC_DOR, 0x0C); 00245 00246 // Wait for fdc // 00247 fdc_done = TRUE; 00248 fdc_wait(TRUE); 00249 00250 // Specify drive timings // 00251 fdc_sendbyte(CMD_SPECIFY); 00252 fdc_sendbyte(0xDF); // SRT = 3ms, HUT = 240ms 00253 fdc_sendbyte(0x02); // HLT = 4ms, ND = 0 (DMA mode selected) 00254 00255 // Clear disk change flag // 00256 fdc_seek(1); 00257 fdc_recalibrate(); 00258 fdc_change = FALSE; 00259 } |
|
Perform a read/write operation with the floppy drive using the DMA (Direct Memory Access).
Definition at line 289 of file floppy.c.
00290 { 00291 int track, head, sector, tries; 00292 00293 // Translate the logical address into CHS address // 00294 lba2chs(block, &track, &head, §or); 00295 00296 // Spin up the motor // 00297 fdc_motor_on(); 00298 00299 if (!do_read) 00300 // Write operation => copy data from buffer into fdc_buffer // 00301 memcpy(fdc_buffer, buffer, FDC_SECTOR_SIZE); 00302 00303 for(tries=0; tries<3; tries++) 00304 { 00305 // Check for disk changed // 00306 if (inportb(FDC_DIR) & 0x80) 00307 { 00308 fdc_change = TRUE; 00309 fdc_seek(1); 00310 fdc_recalibrate(); 00311 fdc_motor_off(); 00312 return(FALSE); 00313 } 00314 // Move the head to the right track // 00315 if (!fdc_seek(track)) 00316 { 00317 fdc_motor_off(); 00318 return(FALSE); 00319 } 00320 // Program data rate // 00321 outportb(FDC_CCR, floppy_type[fdc_geometry].rate); 00322 00323 // Send command // 00324 if (do_read) 00325 { 00326 // Read operation // 00327 dma_xfer(2, (dword)fdc_buffer, FDC_SECTOR_SIZE, FALSE); 00328 fdc_sendbyte(CMD_READ); 00329 } 00330 else 00331 { 00332 // Write operation // 00333 dma_xfer(2, (dword)fdc_buffer, FDC_SECTOR_SIZE, TRUE); 00334 fdc_sendbyte(CMD_WRITE); 00335 } 00336 fdc_sendbyte(head << 2); 00337 fdc_sendbyte(track); 00338 fdc_sendbyte(head); 00339 fdc_sendbyte(sector); 00340 fdc_sendbyte(2); // 512 bytes/sector // 00341 fdc_sendbyte(floppy_type[fdc_geometry].spt); 00342 fdc_sendbyte(floppy_type[fdc_geometry].rwgap); 00343 fdc_sendbyte(0xFF); // DTL = unused // 00344 00345 // Wait for command completion // 00346 if (!fdc_wait(FALSE)) 00347 return(FALSE); // Timed out! // 00348 00349 if ((fdc_status[0] & 0xC0) == 0) break; // Worked! :) // 00350 00351 // Try again... // 00352 fdc_recalibrate(); 00353 } 00354 00355 // Stop the motor // 00356 fdc_motor_off(); 00357 00358 if (do_read) 00359 // Read operation => copy data from fdc_buffer into buffer // 00360 memcpy(buffer, fdc_buffer, FDC_SECTOR_SIZE); 00361 00362 // Return if the R/W operation terminates successfully // 00363 return(tries != 3); 00364 } |
|
Seek a track.
Definition at line 199 of file floppy.c.
00200 { 00201 // If already threre return // 00202 if (fdc_track == track) 00203 return(TRUE); 00204 00205 // Turn the motor on // 00206 fdc_motor_on(); 00207 00208 // Send seek command // 00209 fdc_sendbyte(CMD_SEEK); 00210 fdc_sendbyte(0); 00211 fdc_sendbyte(track); 00212 00213 // Wait until seek is finished // 00214 if (!fdc_wait(TRUE)) 00215 { 00216 // Timeout! // 00217 fdc_motor_off(); 00218 return(FALSE); 00219 } 00220 00221 // Let the head settle for 15msec // 00222 delay(15); 00223 00224 // Turn off the motor // 00225 fdc_motor_off(); 00226 00227 // Check if seek worked // 00228 if ((ST0 != 0x20) || (fdc_track != track)) 00229 return(FALSE); 00230 else 00231 return(TRUE); 00232 } |
|
Send a byte to the FDC controller.
Definition at line 68 of file floppy.c.
|
|
Wait for a FDC operation.
This routine must be invoked every time that we have to verify the correct completion of an operation. If a "sense interrupt status" command is issued, the status of the controller is reported into the ST0 variable and the current track is stored into the fdc_track variable. Definition at line 136 of file floppy.c.
00137 { 00138 byte i; 00139 00140 fdc_timeout = HZ; // timeout = 2 sec // 00141 00142 // Wait for IRQ or timeout // 00143 while((!fdc_done) && (fdc_timeout)) 00144 { 00145 enable(); 00146 idle(); 00147 } 00148 00149 // Read command result bytes // 00150 i = 0; 00151 while ((i < 7) && (inportb(FDC_MSR) & MSR_BUSY)) 00152 fdc_status[i++] = fdc_getbyte(); 00153 00154 // Send a "sense interrupt status" command // 00155 if (sensei) 00156 { 00157 fdc_sendbyte(CMD_SENSEI); 00158 ST0 = fdc_getbyte(); 00159 fdc_track = fdc_getbyte(); 00160 } 00161 00162 // Timed out? // 00163 if (!fdc_done) 00164 { 00165 // Check for disk change // 00166 if (inportb(FDC_DIR) & 0x80) 00167 fdc_change = TRUE; 00168 return(FALSE); 00169 } 00170 else 00171 { 00172 fdc_done = FALSE; 00173 return(TRUE); 00174 } 00175 } |
|
Write some contiguous blocks to the floppy disk.
Definition at line 396 of file floppy.c.
|
|
This is a routine called from clock_thread() at every clock tick to perform the floppy motor kill countdown and to control the floppy timeouts.
Definition at line 422 of file floppy.c.
00423 { 00424 if (fdc_timeout > 0) 00425 fdc_timeout--; 00426 00427 if (fdc_motor_countdown > 0) 00428 fdc_motor_countdown--; 00429 else if (fdc_motor && !fdc_motor_countdown) 00430 { 00431 outportb(FDC_DOR, 0x0C); 00432 fdc_motor = FALSE; 00433 } 00434 } |
|
Initialize the floppy driver.
Definition at line 451 of file floppy.c.
00452 { 00453 int v; 00454 00455 // Install the interrupt handler routine // 00456 install_irq_handler( FLOPPY_IRQ, (void *)floppy_handler ); 00457 00458 // Create the FDC buffer // 00459 fdc_buffer = PHYSICAL( dma_phys_alloc(PAGE_SIZE) ); 00460 00461 // Reset the controller // 00462 fdc_reset(); 00463 00464 // Get floppy controller version // 00465 fdc_sendbyte(CMD_VERSION); 00466 v = fdc_getbyte(); 00467 00468 switch ( v ) 00469 { 00470 case 0xFF: 00471 return( FALSE ); 00472 break; 00473 00474 case 0x90: 00475 kprintf("\n\rEnhanced controller found!"); 00476 return( TRUE ); 00477 break; 00478 00479 default: 00480 kprintf("\n\r8272A/765A controller found! (cmd_version=%02X)", v); 00481 return( TRUE ); 00482 break; 00483 } 00484 } |
|
Convert from a LBA (Linear Block Address) address to a CHS (Cylinder, Head, Sector) coordinates.
Definition at line 268 of file floppy.c.
00269 { 00270 *track = lba / (floppy_type[fdc_geometry].spt * floppy_type[fdc_geometry].heads); 00271 *head = (lba / floppy_type[fdc_geometry].spt) % floppy_type[fdc_geometry].heads; 00272 *sector = (lba % floppy_type[fdc_geometry].spt) + 1; 00273 } |
|
Floppy r/w buffer.
|
|
Disk change flag.
|
|
FDC operation finish.
|
|
Current floppy geometry.
|
|
Motor on flag.
|
|
Floppy motor kill countdown.
|
|
FDC status (result output).
|
|
FDC timeout.
|
|
Current head position.
|
|
Initial value: { { 2880, 18, 2, 80, 0x54, 0x1B, 0x00, "H1440" }, { 3360, 21, 2, 80, 0x0C, 0x1C, 0x00, "H1680" } }
|
|
Status register 0.
|