Well, I'm simply noticing that with your formula, the bitrates are correctly lower for lower data rates, and therefore longer periods, but for higher RPM, they are higher, which doesn't sound right to me, especially considering the fact that at a higher RPM, you can fit less data on the disk than at a lower RPM. Hence why at 500 kbps, you'll fit 12500 bytes onto a single track at 300 rpm, but 10416.6666... bytes at 360 rpm. It's also why 5.25" high density media have lower capacity than their 3.5" counterparts.Are you thinking of bit density on the disc, rather than the bit rate coming into the FDC? Because, given the same disc, a drive spinning at 360 rpm is going to produce a higher bitrate, and hence shorter bitcell period, than one at 300 rpm, simply because it's going faster!
Simply put, if the disk is spinning faster, it's going to reach end of the track (remember, each track is a circle) faster, hence why at the same data rate it's going to be able to write less data onto the track because the end of the track will be reached sooner in time. It's also why formats were chosen in a conservative way, because the floppy drive standard prescribes a +/- 2% tolerance for motor speeds, so a drive can easily spin up to 2% slower, which means it will be able to fit slightly less than what it nominally should onto a single track.
The OS/2 museum mentions this here: http://www.os2museum.com/wp/floppy-capacity-math/ as it's talking about the FD1968 utility:
So as the motor speed goes up, capacity goes down, so the bit cell period should be longer, at 360 rpm it should be about 6/5 or 120% of what it is at 300 rpm, while the bitrate should be 5/6 of what it is. But, I might be misunderstanding what you're saying and therefore be wrong.OS/2 Museum wrote:The reason why this utility remained unknown is that it didn’t work on most systems. The problem is that not all drives run at exactly 300 rpm; even manufacturer specifications typically allow 1-2% slower or faster speed. And if a drive rotates faster, the capacity goes down—because the FDC has less time to read or write the data on each track.
A drive that spins 1.5% faster (304.5 rpm) could only store about 98,522 bits or 12,315 bytes per track. That’s not enough to store 3 sectors holding 12,288 bytes of data due to the required per-sector overhead (which is at least about 30 bytes per sector plus required gaps). A similar problem would occur if the FDC processed data at a rate slightly slower than 500 kbps. Of course if the drive rotated slightly slower, there would be more room on the disk… but that cannot be assumed to be the case.
I find your proposal to be an excellent idea. It would make everything more logical.I'm not denying that all that stuff's needed somewhere, just not necessarily there, and not necessarily calculating it on every access.
I've been doing some thinking about how this is all structured, and I think we should make use of the fact that on mainline (as of v10), FDC, drive and disc are all abstracted from each other, rather than having everything together as was done pre-v10 and in PCem-X. Ideally, I think we should have :
- Core FDC core in fdc.c/h, with SuperIO stuff separate.
- Drive emulation, probably in a new fdd.c/h. This should include motor control (including RPM calculations, based on the pins provided by FDC/SuperIO) and stepping control (separated from the FDC's view of the current track - I believe the FDC should only provide relative rather than absolute track numbers for seek commands, and a seperate recalibrate), providing the other areas with the current motor speed, track 0 state and anything else needed. From my point of view, this is the only section which needs to know what the drive type actually is (3.5" HD, 3-mode, etc)
- Disc emulation, with disc.c/h acting as manager and disc_img/fdi/whatever implementing the actual read/write/format/poll functions for each format. This will also calculate the 'correct' bit rate for the current disc/track/sector (depending on format) given the current motor speed. The fdc_checkrate() equivalent would live here, comparing this bit rate against the one calculated for current selected FDC bit rate and motor speed, and fail the current operation if they don't match. This would allow us to abstract the drive logic out of the main read/write path.
- I was also thinking about moving the poll functions from disc_img/fdi and moving them into common code. My idea was to have two poll functions - one for sector based formats (img) and one for stream based formats. This would simplify the code for adding new formats to having open/track read/track write functions for each format, and providing the common poll code with either a list of sectors, or MFM streams.
To me this seems a logical division of functionality, and should be easier to maintain/extend than having everything in one file. Your thoughts?
True that. However then, the floppy disk periods should be multiplied by a factor of 15 to make them divisible by both 3 and 5, which would cause every possible period you could find on a PC-readable disk to be an integer.Fixed point will probably be better, as that's what the timer routines already use.