Page 1 of 1
Floppy driver mystery solved!!
Posted: Sun Apr 01, 2007 9:11 am
by mystran
My floppy driver obviously works wonderful in Bochs. It also (sort of) works on real machine... BUT!
I am getting error = end-of-track a lot from reads. If I just retry the read, it'll succeed.. eventually. Now, at the beginning of track (low sector number) I typically get one or two of those. Sector 17 already throws something like 6, and sector 18 can take well over 20 retries.
So obviously something is wrong.... especially as the "other operating systems" around here don't seem to have any trouble with said floppy. I'd suspect a timing issue, but I don't think I'm doing stuff too fast, because I'm waiting a lot all the time. I tried waits as long as second for stuff as simple as settle after seek. Doesn't help.
I also read the sectors sequentially, one at a time, and I tried with or without seeking when I'm already at the right track. So what am I missing? Any suggestions?
Code is essentially slightly messed-around version of the code posted here:
http://www.osdev.org/phpBB2/viewtopic.php?t=13516 (code deleted now though)
Posted: Sun Apr 01, 2007 9:27 am
by mystran
AARARGH... Stupid ugly manuals and impossible to read example code and whatever... now I find this text in one document:
"All data transfers concern all sectors from the start sector to the end of the track. The operation can be stopped earlier by either setting the command byte track length/max. sector number to a value which indicates the last sector to be operated on, or setting the count value of the DMA controller so that it issues a TC (Terminal Count) signal after the required number of sectors are transfered (the latter method is demonstrated in the example DMA code below)."
So does this mean that if I simply issue a command for sector 1, with EOT = 18, I'll get the whole track at once?
Does this also mean that the reason it works in Bochs is because Bochs doesn't properly set the error, and the reason it eventually works on real hardware is because eventually the DMA length will be exhausted...
Hmmh.. seems I gotta fix some stuff then..
Posted: Sun Apr 01, 2007 9:34 am
by mystran
And now if I enable multi-track, I get two tracks for a single request?
So I only ever have to request tracks? Cool...
Posted: Sun Apr 01, 2007 10:22 am
by mystran
Wonderful. Now I've got a floppy driver, that reads 512*18*2 bytes per request. It makes the floppy drive crack exactly 80 times to read a 1.44MB disk complete.
That makes sense. DMA transfer. I've got it right now!
Considering the awful state of floppy-driver tutorials, I'll consider writing one know that I've managed to figure out how stuff really works after wasting the whole night.. mm and .. seems the day as well, reading tutorials presenting example code that "works in Bochs".
Posted: Sun Apr 01, 2007 5:19 pm
by pcmattman
Ironically I found reading and writing to the hard drive so much easier than the hard drive. For a start, I get 100% definite success as long as the drive exists and supports LBA28 (soon to support CHS for older drives and LBA48). My floppy driver, on the other hand, is incredibly temperamental.
I have a feeling that the only thing I'm going to use floppies for anymore is for the installation of my OS.
And please, do write a floppy-driver tutorial. You'll save a lot of people a lot of frustration.
Posted: Mon Apr 02, 2007 5:29 am
by ~
I am working on that; it looks like there are good response from the other OS developers here...
By the way, what do you think about a simplified floppy driver that is hardcoded to read 1 sector at the time and it keeps track of how many sectors it needs to read? Anyway, the floppy is so slow that it wouldn't be much of a performance issue... It worked wonderfully for me, until I destroyed my driver with modifications and now it locks up...
Posted: Tue Apr 03, 2007 12:42 am
by Happy Egghead
Hi, I too am trying to get a floppy driver working.
About the multi track reads - you can only read one entire track at a time, then you MUST transfer to the next track and then read the next track and then the next and so on.
The multi track function reads one track from head one and then one track from head two - the opposite side of the disk (references Indispensable Hardware Book 3rd Ed. page 823; Intel 82077A data sheet page 23). I don't think you want that to happen unless the sectors are stored in that fashion (A fast loading boot disk perhaps?). Essentially the multitrack function is useless for file systems which store all on one side then the next.
From what I've read, some controllers (embedded) don't support multitrack at all.
My floppy driver will cache reads track by track and will 'write combine' the track data on writes. Although this implies a read of a track before a sector can be combined into it and then written back, I'm not all that concerned about squeezing the last ounce of performance from the floppy drive so long as it works.
Hope this saves you a headache or two!
Posted: Tue Apr 03, 2007 5:36 am
by mystran
See "basic concepts" in my tutorial here:
http://www.osdev.org/phpBB2/viewtopic.php?t=13538.
In short: you have one "track" for each cylinder/head-combination. Hence 160 tracks on a 80/2/18/512 disc (normal 1.44MB). Reading whole track gives you blocks x:0:1...x:0:18 and multitracks takes x:1:1...x:1:18 after those with the same command. If you address as C:H:S then this is exactly what you want.
The reason this matters is rotational latency. But ofcourse I already write it all once in my tutorial.
Posted: Wed Apr 04, 2007 4:29 am
by Happy Egghead
Hi,
Great tutorial! My code isn't the same but it's good to see I'm on the right track. I just have to get all my timing right.
I'm still unsure about that multitrack operation though. My driver will read a track at a time using the builtin 'read track' command (0x2). This reads a track from the disk and ends on the sector number or when DMA count runs out. (18 sectors max).
The docs say (Intel 82077AA) -
MT Multi-track selector. When set, this flag selects the multi-track operating mode. In this mode, the 82077AA treats a complete cylinder, under head 0 and 1, as a single track. The 82077AA operates as if this expanded track started at the first sector under head 0 and ended at the last sector under head 1. With this flag set, a multitrack read or write operation will automatically continue to the first sector under head 1 when the 82077AA finishes operating on the last sector under head 0.
To me this seems to mean that a multitrack operation reads 18 sectors from track 0 head 0 then continues onto track 0 head 1 on the other side of the floppy. At most it could read 36 sectors (one track from both sides) and then you would have to send another command to read the next track from both sides.
Another site
http://www.isdaman.com/alsos/hardware/fdc/floppy.htm says
The write sector command transfers one or more sectors from main memory to the controller, from where it is transferred to the disk. As the controller writes each sector, it also writes a valid data address mark to the disk. This command can operate on both heads, starting from the first sector of the second head after reaching the end of the first head.
I could definitely see how it could be useful in a diskcopy program or a backup program where it doesn't matter what's being copied or where the data could be 'massaged' into the format to be written.
As a second thought, it would be possible to use a FAT file system on a disk where data is read / written this way as the FAT holds logical cluster numbers, some being aimed at head 0 tracks/sectors and some being aimed at head 1 tracks/sectors. In a track buffering scheme it could be a lot faster. But that's a problem for the filesystem to handle isn't it?.
As for compatibility I have done some research and found that most multitrack problems were caused by BIOS code. Looking at BOCHS source the floppy controller emulated supports multitrack operations and by extension so should QEMU.
So after all that I've convinced myself this is a good feature and will add a second buffer to my floppy driver to hold the head 1 data as well as the head 0 data. I just have to remember to use the optimisation in the FAT driver.
Now I will shut up.