strange floppy error reading last sector

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
OZ

strange floppy error reading last sector

Post by OZ »

Hello, I'm facing an error which I can't explain, may be one of you knows about my mistake :)
I'm testing my floppy driver in qemu and it works as expected. But if I turn to real hardware something strange happens:

output:

Code: Select all

LBA: 35 >> H: 1 C: 0 S: 18
ST0: 01000000  // ST0 of seek op - success
track: 0 - pcn: 0
seeking done
command sent ... waiting for INT
ST0: 01000000 // ST0 of READ - failed
ST1: 10000000
request failed
this is the error msg I get on real hardware, what now is quite mysterious about it, is the fact, that the error msg delivered says I'm trying to read a sector behind the EOT parameter which is set to 18.
In addtion to this my code seems to work just fine I can read all the other sectors, just the last one of tracks on Head 1 seem to be an issue.

The spec of the floppy controller stats for this error, that it may show up if TC isn't set high by dma controller although the floppy has successfully transfered the read data. For all the other sectors my dma code works - and as this code has no relation to the sector that gets read it shouldn't be an issue here.

What confused me even more is this homepage: http://www.phys.uu.nl/~heukelum/xdflinux/
Although the statement about how linux formats floppy disks - well, I used mformat under linux - would explain why I the sector I try to read should be on the next track, I still don't get why everyone uses the same formular to convert from LBA to CHS?

Code: Select all

void kfd_lba2chs(uint block, uint* cyl, uint* head, uint*sector)   // linear block addressing to cylinder/ track - head - sector addressing
{
   *cyl=0;
   *head=0;
   *sector=0;
   //*cyl = (block / 18) / 2;
   //*head = (block / 18) % 2;
   //*sector = (block % 18) + 1;
   *head = (block % (18 * 2)) / (18);
   *cyl = block / (18 * 2);
   *sector = block % 18 + 1;
   FD_DEBUG("lba: %d >> H: %d C: %d S: %d\n",block,*head,*cyl,*sector);
}
I just commented out my version and used one from a tutorial, but they both deliver the same values and errors.

Any thing special about the last sector of tracks on head 1? It is a 3.5 inch 1.44 mb standard floppy. I did also try to replace it, I don't think it's a bad sector or stuff, cause the disk image I created of it to run in qemu just works fine.
Any suggestions? thx
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re:strange floppy error reading last sector

Post by Brendan »

Hi,
OZ wrote:this is the error msg I get on real hardware, what now is quite mysterious about it, is the fact, that the error msg delivered says I'm trying to read a sector behind the EOT parameter which is set to 18.
I think EOT is meant to be set to "last sector number + 1", or 19 in this case.

The only confusing part is why you didn't get the same error when trying to read from the last sector for head 0 too....

BTW for Bochs (and probably Qemu), AFAIK EOT is never checked. Instead Bochs has it's own internal "sectors per track" variable. This wouldn't be hard to test - just set EOT to 4 and see if your code works on Bochs (and if sector 3 is the last sector real hardware lets you read).


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
oz
Posts: 4
Joined: Wed Oct 18, 2006 4:46 am

FIXED

Post by oz »

Hi,thx for your answer.
well, I tried your proposal to set EOT = 'target sector +1' and another error appeared. This time it didn't complain about the sector being after the end of track, this time the error code said that the sector was not found.

Although the specification stats, that there are two different scenarios which make the FDC enter the result phase:

explicit: The DMA controller is setup for a certain amount of data to be transfered,
by the time it's internal counter hits this limit it pulses the TC line of the floppy controller and the FDC enters the result phase.

implicit: The FDC will enter the result phase aswell, if the read sector equals the EOT parameter of the read/write command.

At least on the two boxes I have here, it seems that one has to fulfil both conditions to read the last sector of tracks on head 1 succesfully.
Therefore I had to set EOT = sector to read and now it works.
A bit weird though, cause logically I would agree to your proposal that setting EOT = sector +1 should work because of the 'explicit dma behaviourr' *g*
oz
Posts: 4
Joined: Wed Oct 18, 2006 4:46 am

Post by oz »

hehe seems if I was a bit to early to say it's fixed ... the problem remains.
If I try to read the weird 18th sector and set EOT = sector + 1 the error codes report that the sector which the FDC couldn't find is the 19th. Therefore in this case the dma chips seems not to set TC. Still I don't know why this should happen in this case, as it's functionable afterwards while reading other sectors. If I set EOT = sector it keeps complaining sector is behind end of track. :(
User avatar
Dex
Member
Member
Posts: 1444
Joined: Fri Jan 27, 2006 12:00 am
Contact:

Post by Dex »

Some time if it works ok in emulator, but not on real hardware, it can be a sign it need bigger delays.
blackcatcoder
Member
Member
Posts: 132
Joined: Wed Nov 03, 2004 12:00 am
Location: Austria
Contact:

Post by blackcatcoder »

a year ago i experienced nearly the same problem....

I fixed this by givin' the floppy drive some time to do it's work.
I don't know if you're doing it with polling or irq driven but just try to put some delays in there.
oz
Posts: 4
Joined: Wed Oct 18, 2006 4:46 am

Post by oz »

I'm using interrupts and the thing is that it doesn't time out or anything and the tests after those commands that need some time do work are all positive.
It just ends with a abnormal termination status after the interrupt fired.
The spec stats that in case of the result phase being entered due to the FDC hitting the read sector = EOT condition there might be an abnormal termination status code which may merely be ignored by the host. But the question is, why then the dma chip does not set TC as it does succesfully for all the other sectors except this d*** last one of tracks on head 1.

Does anybody of you who has a nice working floppy driver present issue the proposed READ_ID operation before every READ_DATA / WRITE_DATA operation?
This is almost the only thing that's left in the spec which I don't do at the moment.
theubu
Member
Member
Posts: 38
Joined: Wed Dec 01, 2004 12:00 am
Location: New York
Contact:

Post by theubu »

Just a quick question but are you testing in an emulator or on a real machine?
oz
Posts: 4
Joined: Wed Oct 18, 2006 4:46 am

Post by oz »

I test on both, but on real hardware I encounter this strange behaviour.
But finally I'm a step further - still I don't know how to explain it - but the sector gets transfered successfully by the FDC and the DMA aswell. The thing is that I didn't copy it out of the temporary dma buffer because the floppy code said the transfer was faulty.

Therefore this is such a special case where the host has to decide whether the error code can be ignored like it is mentioned in the spec. Still I'm asking myself why this seems only to be the case for head 1 ... :?
User avatar
Hadrien
Posts: 9
Joined: Thu Oct 19, 2006 2:30 pm

Post by Hadrien »

I faced somehow this kind of problem on my floppy driver too. I could not read the last sector of a disk. The problem was that I was using the value 512 instead of 511 for the byte count when programming the DMA controller.
deathangel
Member
Member
Posts: 31
Joined: Thu Apr 14, 2005 11:00 pm
Location: Planet Earth
Contact:

Post by deathangel »

At least your floppy driver works. I can never get mine to detect an interrupt on a recalibrate or seek command, which is weird because it detects an interrupt on a reset command.
User avatar
Dex
Member
Member
Posts: 1444
Joined: Fri Jan 27, 2006 12:00 am
Contact:

Post by Dex »

This is my floppy driver fasm code, fully working it is commented to go with the per-do code in the intel pdf may help others ?.
http://www.dex4u.com/Redragon/FloppyDriver.zip
deathangel
Member
Member
Posts: 31
Joined: Thu Apr 14, 2005 11:00 pm
Location: Planet Earth
Contact:

Post by deathangel »

How is the timer handled? I see it wait until the timer is done, but where is the code that counts down the timer?
User avatar
Dex
Member
Member
Posts: 1444
Joined: Fri Jan 27, 2006 12:00 am
Contact:

Post by Dex »

In my ClockTick interrupt (which fires just over 18 times a second)
i have something like this:

Code: Select all

test  [TimerOn],-1		                ; See if timer on
jz    NoTimer		                        ; no jump lable
dec   [Timer]		                        ; Yes, decrement
jnz   NoTimer		                        ; Not done
and   [TimerOn],0		                ; finished, inform task
NoTimer:
Note: My OS is pmode, single-tasking, ring0.
deathangel
Member
Member
Posts: 31
Joined: Thu Apr 14, 2005 11:00 pm
Location: Planet Earth
Contact:

Post by deathangel »

Does you OS have a website? I would like to see the full source code. It's interesting, you are doing single-tasking? How do you manage everything that way?
Post Reply