OSDev.org https://forum.osdev.org/ |
|
Floppy Disk Driver... https://forum.osdev.org/viewtopic.php?f=1&t=12279 |
Page 1 of 1 |
Author: | CorN_Sk8 [ Fri Nov 24, 2006 9:57 am ] |
Post subject: | Floppy Disk Driver... |
hello progammers, what the steps do make a floppy disk driver ? what i need to know to make it ? somebody have a tutorial step by step ? thanks.. obs: i was using C language and my kernel is in PMode... |
Author: | CorN_Sk8 [ Fri Nov 24, 2006 10:54 am ] |
Post subject: | |
My initial code to the driver is... Code: /*
* Sistema Operacional BrOS * CodeD by CorN_Sk8 * Kernel em C */ #include "include\floppy.h" #include "include\system.h" #include "include\video.h" #include "include\in_out.h" int fdc_flag=0; void reset_floppy(int device){ char devs[] = {0x1C, 0x2D, 0x4E, 0x8F}; irq_install_handler(6, fdc_handler()); outportb(0x3f7, 0x00); outportb(0x3f2, 0x0c); fdc_flag=1; } void init_floppy(int device){ reset_floppy(device); while(fdc_flag); } void fdc_handler(struct regs *r){ fdc_flag = 0; } thanks.. |
Author: | Dex [ Fri Nov 24, 2006 11:26 am ] |
Post subject: | |
Maybe some of the doc's on bubach site, may help: http://bos.asmhackers.net/docs/floppy/ |
Author: | CorN_Sk8 [ Fri Nov 24, 2006 12:11 pm ] |
Post subject: | |
i read some tutorials, but i need help to understand... my atual code is: Code: /*
* Sistema Operacional BrOS * CodeD by CorN_Sk8 * Kernel em C */ #include "include\floppy.h" #include "include\system.h" #include "include\video.h" #include "include\in_out.h" int fdc_flag=0; void fdc_wait(){ fdc_flag=1; while(fdc_flag) ; } void fdc_sendbyte(int b){ outportb(FDC_DATA, b); } int reset_floppy(int device){ char devs[] = {0x1C, 0x2D, 0x4E, 0x8F}; outportb(FDC_DOR, 0x00); outportb(FDC_CCR, 0x00); outportb(FDC_DOR, 0x0C); fdc_wait(); return 1; } void fdc_handler(struct regs *r){ fdc_flag = 0; } int init_floppy(int device){ int flag; // Instal IRQ irq_install_handler(6, fdc_handler); // reset floppy driver flag = reset_floppy(device); if(flag == 0){ printf("\nError on init floppy driver in stage of [Reset].\n"); return 0; } } what the next step ? |
Author: | Brynet-Inc [ Fri Nov 24, 2006 1:05 pm ] |
Post subject: | |
Code: int reset_floppy(int device){
char devs[] = {0x1C, 0x2D, 0x4E, 0x8F}; outportb(FDC_DOR, 0x00); outportb(FDC_CCR, 0x00); outportb(FDC_DOR, 0x0C); fdc_wait(); return 1; } int init_floppy(int device){ int flag; // Instal IRQ irq_install_handler(6, fdc_handler); // reset floppy driver flag = reset_floppy(device); if(flag == 0){ printf("\nError on init floppy driver in stage of [Reset].\n"); return 0; } } I'm confused about that device variable, both init_floppy and reset_floppy seem to declare it, but apparently it's not used for anything.. |
Author: | CorN_Sk8 [ Fri Nov 24, 2006 1:19 pm ] |
Post subject: | |
Code: /*
* Sistema Operacional BrOS * CodeD by CorN_Sk8 * Kernel em C */ #include "include\floppy.h" #include "include\system.h" #include "include\video.h" #include "include\in_out.h" int fdc_flag = 0; int ST0 = 0; int fdc_status[7] = { 0 }; int fdc_track = 0xFF; int fdc_motor = 0; int fdc_motor_countdown = 0; int fdc_device = 0; int *fdc_buffer; static int fdc_wait_until_ready( void ) { int counter, status; for( counter = 0; counter < 10000; counter++ ) { status = inportb( FDC_MSR ); if( status & MSR_READY ) { return( status ); } } return( -1 ); } static int fdc_getbyte() { int msr; msr = fdc_wait_until_ready(); if( msr < 0 ) { return( -1 ); } msr &= MSR_DIR | MSR_READY | MSR_BUSY | MSR_DMA; if( msr == (MSR_DIR | MSR_READY | MSR_BUSY) ) { return( inportb(FDC_DATA) ); } return( -1 ); } static int fdc_sendbyte( int b ) { int msr; msr = fdc_wait_until_ready(); if( msr < 0 ) { return( -1 ); } if( (msr & (MSR_READY | MSR_DIR | MSR_DMA)) == MSR_READY ) { outportb( FDC_DATA, b ); return( 0 ); } return( -1 ); } int fdc_wait(int sensei){ int i; fdc_flag=1; while(fdc_flag) ; i = 0; while( (i < 7) && (inportb(FDC_MSR) & MSR_BUSY) ){ fdc_status[ i++ ] = fdc_getbyte(); } if( sensei ){ fdc_sendbyte( CMD_SENSEI ); ST0 = fdc_getbyte(); fdc_track = fdc_getbyte(); } return 1; } void fdc_motor_on(){ char devs[] = {0x1C, 0x2D, 0x4E, 0x8F}; if(!fdc_motor){ outportb( FDC_DOR, devs[fdc_device] ); timer_wait(100); fdc_motor = 1; } } void fdc_motor_off(){ if(fdc_motor){ outportb( FDC_DOR, 0x0C ); fdc_motor = 1; } } static void fdc_recalibrate() { // Turn the motor on. fdc_motor_on(); // Send recalibrate command. fdc_sendbyte( CMD_RECAL ); fdc_sendbyte( 0 ); // Wait until recalibrate command is finished. fdc_wait( 1 ); // Turn the motor off. fdc_motor_off(); } int __fdc_seek( int track ){ // If already there return. if( fdc_track == track ) { return( 0 ); } // Turn the motor on. fdc_motor_on(); // Send seek command. fdc_sendbyte( CMD_SEEK ); fdc_sendbyte( 0 ); fdc_sendbyte( track ); // Wait until seek is finished. if( fdc_wait(1) == 0 ) { // Timeout! fdc_motor_off(); printf("ERRO"); return 0; } // Let the head settle for 15msec. timer_wait(50); // Turn off the motor. fdc_motor_off(); // Check if seek worked. if( (ST0 == 0x20) && (fdc_track == track) ) { return( 0 ); } return 0; } int reset_floppy(int device){ fdc_device = device; outportb(FDC_DOR, 0x00); outportb(FDC_CCR, 0x00); outportb(FDC_DOR, 0x0C); fdc_wait(1); fdc_sendbyte( CMD_SPECIFY ); fdc_sendbyte( 0xdf ); fdc_sendbyte( 0x02 ); __fdc_seek( 1 ); fdc_recalibrate(); return 1; } void fdc_handler(struct regs *r){ fdc_flag = 0; } int init_floppy(int device){ int flag; int ret; int v; // Instal IRQ irq_install_handler(6, fdc_handler); // reset floppy driver flag = reset_floppy(device); if(flag == 0){ printf("\nError on init floppy driver in stage of [Reset].\n"); return 0; } fdc_sendbyte( CMD_VERSION ); v = fdc_getbyte(); switch ( v ) { case 0xFF: printf(" [ controller not found ]"); ret = 0; break; case 0x80: printf(" [ NEC controller ]"); ret = 1; break; case 0x81: printf(" [ VMware controller ]"); ret = 1; break; case 0x90: printf(" [ enhanced controller ]"); ret = 1; break; default: printf(" [ unknown controller [%d] ]", v); ret = 1; break; } return 1; } now i need write FDC_READ ... |
Author: | pcmattman [ Sat Feb 24, 2007 5:58 am ] |
Post subject: | |
Hmmm... dunno if this is the right place to post but hey, who cares? It's only 3 months old... I came across this in looking up how to control the floppy drive without DMA... now I can actually reset the drive (and stop it from spinning out of control). This is good. But I still have a problem: how do I actually read sectors? I don't care about writing (yet) but I would like to know how to read them... Please, no DMA! |
Author: | bubach [ Sat Feb 24, 2007 1:34 pm ] |
Post subject: | |
I think this has code to read a sector without DMA: http://bos.asmhackers.net/docs/floppy/s ... 6/fdc1.txt |
Author: | pcmattman [ Sat Feb 24, 2007 5:03 pm ] |
Post subject: | |
I'm really confused right now... This is my current floppy driver code: Code: #include "mattise.h"
/**** revision 2 ****/ int floppy_flag = 1; // ports #define DOR 0x3F2 #define CCR 0x3F7 char* drive_types[6] = { "No floppy drive.", "360KB 5.25in floppy", "1.2MB 5.25in floppy", "720KB 3.5in floppy", "1.44MB 3.5in floppy", "2.88MB 3.5in floppy" }; void DetectFloppyDrives() { unsigned char c; outportb( 0x70, 0x10 ); c = inportb( 0x71 ); unsigned char drive1; unsigned char drive2; drive1 = c >> 4; drive2 = c & 0xF; kputs( "Floppy 1: " ); kputs( drive_types[ drive1 ] ); kputs( "\n" ); kputs( "Floppy 2: " ); kputs( drive_types[ drive2 ] ); kputs( "\n" ); } // floppy acessory functions void SendByte_FDC( char b ) { // byte storage unsigned char a = 0; // wait for ready while( true ) { // wait a little while sleep( 100 ); // get a byte from the controller a = inportb( 0x3F4 ); // bitwise and a &= 0x80; // check if( a == 0x80 ) break; } // wait a bit more sleep( 100 ); // send the byte outportb( 0x3F5, b ); } unsigned char RecByte_FDC() { // two byte length storage areas unsigned char a; unsigned char b; // wait for ready while( true ) { // wait a little while sleep( 100 ); // get a byte from the controller a = inportb( 0x3F4 ); // bitwise and a &= 0x80; // check if( a == 0x80 ) break; } // get the byte and return it b = inportb( 0x3F5 ); // return to caller return b; } void Recal() { // recalibrate the floppy drive unsigned char res = 0; unsigned char cres = 0; // main loop - may have to keep recalibrating numerous times while( true ) { // send the recalibrate command SendByte_FDC( 7 ); // send 'drive a' indicator SendByte_FDC( 0 ); // replace 0 with 1 for b // send 'sense interrupt' SendByte_FDC( 0x08 ); // wait for data from controller res = RecByte_FDC(); // play with the byte cres = res & 0x80; // equal? if( cres == 0x80 ) continue; // get another byte res = RecByte_FDC(); // result byte got nothing? if( res == 0 ) break; } } void SeekTrackSide( unsigned char track, unsigned char side ) { // bytes, lots of bytes unsigned char a,b,c; // do something cool while( true ) /* go_and_seek_it_again: */ { // seek command SendByte_FDC( 0x0F ); // send the side SendByte_FDC( side * 4 ); // send the track SendByte_FDC( track ); // sense interrupt SendByte_FDC( 0x08 ); // recieve a byte a = RecByte_FDC(); // bitwise fun a &= 0x80; // checks if( a != 0x80 ) break; // recieve another byte a = RecByte_FDC(); // check if( a == track ) break; } } void MotorOn() { // turn on the motor outportb( DOR, 0x1C ); } void MotorOff() { // turn off the motor outportb( DOR, 0x0 ); } // floppy IRQ handler void FloppyHandler( struct regs* r ) { // reset the flag, say that we // have handled the interrupt // lets the initialization return floppy_flag = 0; } // reset the floppy disk void ResetFloppy() { // reset the drive outportb( DOR, 0x00 ); outportb( DOR, 0x0C ); outportb( CCR, 0x00 ); // set the flag floppy_flag = 1; // wait for the interrupt... while( floppy_flag == 1 ); } // initializes the floppy void InitFloppy() { // install the handler irq_install_handler( 6, FloppyHandler ); } How can I read the sectors I want from the disk? |
Author: | enrico_granata [ Fri Jul 27, 2007 3:32 am ] | ||
Post subject: | General timer | ||
While looking at Teemu Voipio's floppy disk driver, I incurred into a call: Code: timer_sleep(1); // sleep 10 ms
How does he do it? I mean, the timer interrupt has a granularity of around 1/18th second. How can he sleep for 1/100th second? Is there a way to calibrate the clock to trigger at a different interval, or is there some other time-measuring device with a higher precision
|
Author: | JamesM [ Fri Jul 27, 2007 3:58 am ] |
Post subject: | |
bran wrote: The timer will divide it's input clock of 1.19MHz (1193180Hz) by the number you give it in the data register to figure out how many times per second to fire the signal for that channel
The default is for the divisor register to be set so it fires at 18.222Hz. If you set it to 1, you should be able to get interrupts up to 1.19MHz. Impressive bumping, btw JamesM |
Author: | enrico_granata [ Fri Jul 27, 2007 4:01 am ] |
Post subject: | |
I guess this is all detailed in the Wiki about the pit (which I should probably have looked at before posting), right? I'm gonna give a look at that before bothering again |
Author: | enrico_granata [ Sat Jul 28, 2007 5:58 am ] |
Post subject: | |
I am trying to understand the floppy disk driver by comparing the tutorial at http://debs.future.easyspace.com/Programming/Hardware/FDC/floppy.html with Teemu Voipio's driver..but I can't seem to figure out this piece of code (commands being sent to the controller for actual read/write): Code: floppy_write_cmd(base, cmd); // set above for current direction floppy_write_cmd(base, 0); // 0:0:0:0:0:HD:US1:US0 = head and drive floppy_write_cmd(base, cyl); // cylinder floppy_write_cmd(base, 0); // first head (should match with above) floppy_write_cmd(base, 1); // first sector, strangely counts from 1 floppy_write_cmd(base, 2); // bytes/sector, 128*2^x (x=2 -> 512) Shouldn't this be 512? Why is it just 2? Code: floppy_write_cmd(base, 18); // number of tracks to operate on If I write 1 in here, will it just read or write 1 sector? Code: floppy_write_cmd(base, 0x1b); // GAP3 length, 27 is default for 3.5"
floppy_write_cmd(base, 0xff); // data length (0xff if B/S != 0) Thanks for any hints! |
Author: | jnc100 [ Sat Jul 28, 2007 8:01 am ] |
Post subject: | |
enrico granata wrote: Shouldn't this be 512? Why is it just 2?
82077aa datasheet See table 5-2, page 24. Regards, John |
Page 1 of 1 | All times are UTC - 6 hours |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |