Page 3 of 4
Re:Using floppy disc
Posted: Fri Jul 30, 2004 12:42 pm
by Neo
i think your FDC_cmd_ready() is wrong and so is mine (the C one I shown). I've corrected mine above and yours could be written as shown here
Code: Select all
void FDC_cmd_ready(unsigned char code)
{
while( (in(0x3F4)&0xC0)!=code );
}
BTW the "reset" only involves the
Code: Select all
out(0x3F2,0);
out(0x3F2,0x0C);
fdc_flag=0;
actually what you are doing is trying to initialize the FDC.(There's nothing wrong with naming the function reset() though).
Incidentally i see that you've not set the 'fdc_flag' value anywhere in the code you've shown, how will you know if an IRQ has occured without this?
Re:Using floppy disc
Posted: Fri Jul 30, 2004 3:32 pm
by Brandon
Yeah I changed the "ready" functions...
I set the fdc_flag in my IRQ handler
Code: Select all
void int_38(void)
{
???fdc_flag = 1;
}
the problem has to be in my reset function (the last parts with issueing the command 4 times and send the specify command)
This is ALL my FDC code (except for the ISR written in asm, that will call the int_38(look above) method:
Code: Select all
/* Reset and initialize the fdc */
void reset_floppy() {
???fdc_flag = 0;
???// Reset the floppy
???out(0x3f2, 0);
???out(0x3f2, 0x0C);
???// Set the data rate = 500 kbps
???out(0x3f7, 0);
???wait_for_floppy_irq();???// Wait for IRC
???int i;
???for(i = 0;i<4;i++) {
???send_floppy_command(0x8); // Send the check interrupt cmd
???get_floppy_command(); // Read the data reg
???get_floppy_command(); // Read the data reg
}
send_floppy_command(3);??????// The specify command
send_floppy_command(0); // And the arguments
send_floppy_command(0);
}
/* Wait until we can send a command */
void FDC_cmd_write_ready() {
???while((in(0x3F4) & 0x80) != 0x80);
}
/* Wait untill we can read the result */
void FDC_cmd_read_ready() {
???while((in(0x3F4) & 0xC0) != 0xC0);
}
/* Wait for a floppy IRQ to fire */
void wait_for_floppy_irq() {
???for(;;)
??????if(fdc_flag != 0) {
?????????fdc_flag = 0;
?????????return;
??????}
}
/* Send a command */
void send_floppy_command(unsigned char command) {
???FDC_cmd_write_ready();
???out(0x3f5, command);
}
/* Read a result */
unsigned char get_floppy_command() {
???FDC_cmd_read_ready();
???return in(0x3f5);
}
/* Start the motor */
void start_floppy_motor() {
???out(0x3f2, 0x1C);
}
In the main method, I got something like this:
Code: Select all
unmask_irq(FLOPPY_IRQ);
reset_floppy();
print("Floppy reseted\n", RED_TXT); // This gets printed
start_floppy_motor();
wait_for_floppy_irq(); // Never ends
For some reason the last floppy IRQ never fires (which it should cause I start the motor), so I guess Im doing something wrong in the initialization...been stuck with this stupid problem for days
Re:Using floppy disc
Posted: Sat Jul 31, 2004 12:41 am
by Brendan
Hi,
Brandon wrote:
For some reason the last floppy IRQ never fires (which it should cause I start the motor), so I guess Im doing something wrong in the initialization...been stuck with this stupid problem for days
Starting the floppy motor will not cause an IRQ. This should work properly:
Code: Select all
unmask_irq(FLOPPY_IRQ);
reset_floppy();
print("Floppy reseted\n", RED_TXT);
start_floppy_motor();
Please note that "reset_floppy()" does not reset one of the 4 floppy/tape devices, but instead resets the floppy disk controller.
Cheers,
Brendan
Re:Using floppy disc
Posted: Sat Jul 31, 2004 3:28 am
by Neo
The arguments for the "Specify" command are wrong, i dont think they can be 0. try 0xAF for the 'SRT & HUT' and 0x02 for the 'HLT and NDMA'
(these are the bios default values on my comp)
so the specify part should be
Code: Select all
send_floppy_command(3); // The specify command
send_floppy_command(0xAF); // And the arguments
send_floppy_command(0x02);
Your wait_for_floppy_irq() code could also be made simpler
Code: Select all
/* Wait for a floppy IRQ to fire */
void wait_for_floppy_irq() {
while(!fdc_flag); // wait for the int38() to change it to 1
}
in fact you could just use that one line instead of a function.
The start motor function should also have a delay after starting
Code: Select all
/* Start the motor */
void start_floppy_motor() {
out(0x3f2, 0x1C);
delay(500); // 500 ms delay
}
although i think it may work without this.
Re:Using floppy disc
Posted: Sat Jul 31, 2004 4:42 am
by Brandon
Alright, thank you!
Brendan: Are u sure that starting the motor wont fire an IRQ?
Is there anything else I have to do to "configure" the fdc? When I?ve ran the reset function, is there any way of testing that everything went ok during the initialization?
Re:Using floppy disc
Posted: Sat Jul 31, 2004 5:50 am
by Brendan
Hi,
Brandon wrote:
Brendan: Are u sure that starting the motor wont fire an IRQ?
Yes
It's almost as if the bits in the DOR are directly connected to the floppy motors and nothing else.
Brandon wrote:
Is there anything else I have to do to "configure" the fdc? When I?ve ran the reset function, is there any way of testing that everything went ok during the initialization?
It depends on your OS and what sort of quality you want. You could try to detect which devices are connected (1200 Kb, 1440 Kb, 2880 Kb, tape, etc). You could also detect which floppy controllers are present (ie. first FDC at base IO port 0x03F0, second FDC at 0x0370), and what type they are (see the "version" command 0x10). Then there's the question of how many devices you'd support - the basic FDC chip handles 4 devices, while most motherboards/cards are only capable of handling 2 of them. In theory you could have 4 devices on the primary FDC, another 4 on the secondary FDC (for 8 devices).
Then there's the question of how your OS will handle all this. Some OSs have a single floppy disk driver, while on others you'd have a device driver for each floppy drive controller chip, and seperate drivers for each device.
Reseting a floppy drive device would include the "recalibrate" command, detecting if any media is in the drive and trying to figure out what type of media is inserted (and configuring for that media). Media specific configuration includes the "specify" command 0x03, the data rate, any device driver data (buffers, etc), and any OS specific stuff (for e.g. mounting it at "/dev/fda0").
The most annoying thing is there's no decent way of determining what media is in a device. DOS use the BPB (BIOS Parameter Block) in the first sector, but this is badly named and should be called the DPB (DOS Parameter Block) as it's not required, and not suitable for some of the floppy formats you could create (for e.g. if you use a higher number of sectors per track on the outer cyclinders).
In general I set the data rate to 1 Mb/s and try to read the first sector of the disk. If this doesn't work (or if 1 Mb/s isn't supported) I try 500 Kb/s, then 300 Kb/s, then 250 Kb/s. Sooner or later one of the data rates will work. Then you can try different numbers of sectors per track and/or different numbers of bytes per sector, and/or figure out the highest track number. The more floppy disk formats your OS will handle the harder this will be, which is why a lot of hobby OSs only support 1440 Kb.
Cheers,
Brendan
Re:Using floppy disc
Posted: Sat Jul 31, 2004 7:47 am
by Brandon
Alright thanks ;D
Is it difficult to read / write data to the floppy? I know you can do it with DMA but I also read that you can read each byte from a port? (Right now I dont care if it?s slow, I just want to get a filesystem working)
Re:Using floppy disc
Posted: Sat Jul 31, 2004 8:07 am
by Brendan
Hi,
Brandon wrote:
Alright thanks ;D
Is it difficult to read / write data to the floppy? I know you can do it with DMA but I also read that you can read each byte from a port? (Right now I dont care if it?s slow, I just want to get a filesystem working)
It's not too difficult once it setup properly - just issue the command and transfer data.
You can read (or write) each byte to a port, but I think you get an IRQ for each byte. I also think the transfer takes just as long regardless of how you do it (but handling all those IRQs will slow down anything else the CPU is trying to do).
Cheers,
Brendan
Re:Using floppy disc
Posted: Sat Jul 31, 2004 8:37 am
by Brandon
Hehe well is it difficult to set it up? Wish there was tutorials on this kind of stuff
I cant find anything anywhere
Re:Using floppy disc
Posted: Sat Jul 31, 2004 9:29 am
by Brendan
Hi,
Brandon wrote:
Hehe well is it difficult to set it up? Wish there was tutorials on this kind of stuff
I cant find anything anywhere
I meant "it's not too difficult once the floppy controller and floppy disk drive are setup".
To setup a floppy transfer you'd:
- set the data rate (if it's not already set)
- convert the logical address into CHS
- turn the motor on (if it's not already on)
- give the motor time to reach operating speed (if it wasn't already on)
- do a "seek" and wait for the heads to settle (if it's not already at the right track)
- setup the DMA transfer (if you're using DMA)
- send the command and it's parameters
- wait for an IRQ saying the DMA transfer is done (if using DMA) or wait for an IRQ saying the next byte is ready, transfer the byte and wait for the next IRQ (512 times if you're using 512 byte sectors)
- if an operation on a different floppy drive is next turn this floppy drive motor off and switch to other drive, otherwise if there are no more operations for this drive set the "motor off" delay, and if no more operations arrive for this drive before the delay expires turn the floppy motor off.
I've omitted all error checking/error handling and caching for simplicity. Of course different floppy device drivers may do things differently.
Cheers,
Brendan
Re:Using floppy disc
Posted: Sat Jul 31, 2004 9:34 am
by Brandon
Thank you very much dude! I?ll try it
u know everything, dont u
Re:Using floppy disc
Posted: Sat Jul 31, 2004 11:25 am
by Neo
try searching
www.osdever.net
Try executing the "Recalibrate" command (0x07) to see if you get an IRQ. You have to send the command followed by the drive no. (0 for first one) and then wait for an INT to be generated. After which you should 'Check int Status'.
BTW what about checking the values you get when you execute the commands? they contain values which tell you what may be wrong. You seem to be just reading the values but not checking them or at least printing them out. I'm referring to your
Code: Select all
for(i = 0;i<4;i++) {
send_floppy_command(0x8); // Send the check interrupt cmd
get_floppy_command(); // Read the data reg /* print this out*/
get_floppy_command(); // Read the data reg
}
Re:Using floppy disc
Posted: Sat Jul 31, 2004 11:48 am
by Brandon
I think it works to callibrate it, I get an IRQ and a correct result phase. Then I try a simple seek (0xF) and I think it works, I send 0xF and the "arguments" and then I get an IRQ..
what?s all this about data rate? What is this all about?
I sended this
in the beginning of the initialization. Then I send the stuff you told me when using the specify command. Do these values have to be something special, or will it work with several combinations? What are they for?
Re:Using floppy disc
Posted: Sat Jul 31, 2004 11:54 am
by Neo
check the manual
Re:Using floppy disc
Posted: Mon Aug 02, 2004 6:04 pm
by Brandon
Brendan:
Whats the CSH? And if I chose not to use DMA, how do I read the "next byte". I send a read command, wait for an IRC, but how do I recieve the next byte?
Can I only park the head at a cylinder and not "closer" to where I want?