Floppy Disk Driver...
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...
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...
My initial code to the driver is...
thanks..
Code: Select all
/*
* 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;
}
Maybe some of the doc's on bubach site, may help: http://bos.asmhackers.net/docs/floppy/
i read some tutorials, but i need help to understand...
my atual code is:
what the next step ?
my atual code is:
Code: Select all
/*
* 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;
}
}
- Brynet-Inc
- Member
- Posts: 2426
- Joined: Tue Oct 17, 2006 9:29 pm
- Libera.chat IRC: brynet
- Location: Canada
- Contact:
Code: Select all
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;
}
}
Code: Select all
/*
* 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;
}
-
- Member
- Posts: 2566
- Joined: Sun Jan 14, 2007 9:15 pm
- Libera.chat IRC: miselin
- Location: Sydney, Australia (I come from a land down under!)
- Contact:
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!
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!
I think this has code to read a sector without DMA:
http://bos.asmhackers.net/docs/floppy/s ... 6/fdc1.txt
http://bos.asmhackers.net/docs/floppy/s ... 6/fdc1.txt
-
- Member
- Posts: 2566
- Joined: Sun Jan 14, 2007 9:15 pm
- Libera.chat IRC: miselin
- Location: Sydney, Australia (I come from a land down under!)
- Contact:
I'm really confused right now... This is my current floppy driver code:
How can I read the sectors I want from the disk?
Code: Select all
#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 );
}
-
- Posts: 21
- Joined: Tue Jul 24, 2007 1:19 am
General timer
While looking at Teemu Voipio's floppy disk driver, I incurred into a call:
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
Code: Select all
timer_sleep(1); // sleep 10 ms
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
- Attachments
-
- floppy.c
- Teemu Voipio's floppy disk driver
- (16.3 KiB) Downloaded 594 times
Computer science: all about things that "should" work
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.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
Impressive bumping, btw
JamesM
Last edited by JamesM on Fri Jul 27, 2007 4:07 am, edited 1 time in total.
-
- Posts: 21
- Joined: Tue Jul 24, 2007 1:19 am
-
- Posts: 21
- Joined: Tue Jul 24, 2007 1:19 am
I am trying to understand the floppy disk driver by comparing the tutorial at http://debs.future.easyspace.com/Progra ... loppy.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):
Shouldn't this be 512? Why is it just 2?
If I write 1 in here, will it just read or write 1 sector?
Thanks for any hints!
Code: Select all
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)
Code: Select all
floppy_write_cmd(base, 18); // number of tracks to operate on
Code: Select all
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)
Computer science: all about things that "should" work
82077aa datasheetenrico granata wrote:Shouldn't this be 512? Why is it just 2?
See table 5-2, page 24.
Regards,
John