![]() |
![]() |
#1 |
Zone Friend
Join Date: Apr 2006
Location: Gothenburg/Sweden
Age: 48
Posts: 347
|
Storing data on a floppy?
I'm nowhere near an expert on floppydisk technology and this is probably a stupid question so beware..
![]() If you look on a floppydisk, outer tracks has obviously a larger diameter than the inner tracks. Wouldn't (in theory) be possible to store more data on the outer tracks than the inner tracks with a smaller diameter? |
![]() |
![]() |
#2 |
Registered User
Join Date: Jul 2017
Location: San Jose
Posts: 688
|
That’s what Apple drives and the Commodore 1541 did.
|
![]() |
![]() |
#3 |
Thalion Webshrine
Join Date: Jan 2004
Location: Oxford
Posts: 14,655
|
I believe the drives are CAV (constant angular velocity) and not CLV (constant linear velocity) and so information stored on the outer tracks is "bigger".
To do what you're suggesting you'd need CLV |
![]() |
![]() |
#4 |
Zone Friend
Join Date: Apr 2006
Location: Gothenburg/Sweden
Age: 48
Posts: 347
|
Interesting. The inner tracks are perhaps more sensitive to errors aswell since they're smaller(?)
|
![]() |
![]() |
#5 | |
Registered User
Join Date: Aug 2010
Location: Germany
Posts: 548
|
Quote:
The Amiga disk drive reads/writes a complete track in a single revolution. No matter which track is involved, the approach is always the same. When you write a track, it begins with the "sector gap", followed by the payload which includes information about what format the data is in, which track and sector this is, etc. and also features a low-level checksum. Addendum, some 40 minutes later (thank you, a/b!): Separate checksums cover this header information and the corresponding payload. The further away the read/write head is from the spindle, the wider the recorded bits get "smeared" across the track ![]() Unless you use dedicated hardware, such as the floppy disk adapter which was available for "Emplant" back in the day that allowed for Macintosh 3.5" disks to be read with a standard Amiga external disk drive, you have no way to control the rotational speed of the disk per track. Last edited by Olaf Barthel; 15 August 2024 at 14:52. Reason: Added brief notes on the different checksums for the sector header and its payload (thank you a/b!) |
|
![]() |
![]() |
#6 |
Registered User
Join Date: Jun 2016
Location: europe
Posts: 1,097
|
I'll just add:
- there are 2 checksums per sector, one for header and one for data, - you always write more than it fits on a track (but not too much more, so you don't fully overwrite the gap and then continue overwriting valid data) to ensure you fully overwrite the old data, and there are no extraneous syncwords and corrupt sectors that would throw your decoder out of sync when you are reading it. |
![]() |
![]() |
#7 |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 54
Posts: 4,536
|
The write size of the "track gap" is constant per any floppy device, and depends solely on the rotation speed of the motor (neglecting the friction effects that any inserted floppy disk might add to the equation).
Between the internal and external tracks what changes is only the distance between the magnetic polarity transitions in the flux (because the writing speed of the cells is constant, as is the rotation speed of the motor). So the internal tracks are the most 'difficult' because transitions are too close and can interfere with each other and 'move' the magnetized part on the material. A correct precompensation can help in some cases. About the length of the track in writing: it doesn't matter how much data is written (it can be even double the necessary!), but the important thing is that it is more than the minimum cells that can be written on the track and that the valid data is at the end of the buffer. The best thing would be to measure this value and then dynamically add a safety margin and write that number of cells. Since the valid data is at the end, the data at the buffer start is always part of the gap and if the valid data is less than the maximum for the track there will never be an overwrite of the valid data! On reading the different data density is not a problem (within tolerance limits, which are in any case wide) since a mechanism called DPLL adapts the sampling point where the check for a flux changes is detected (which can dynamically change from the usual 7 CCK to 6 or 8). 'Short' or 'long' tracks are nothing more than tracks where the cell duration is greater or less than the standard 2us (and therefore 'physically' have flux transitions further or closer than normal). The same very long track that is perfectly readable on the outer surface area may be illegible on the inner surface area.. the closely spaced flux changes severely interfere with each other. A good surface material can help. And in fact when they moved on to HD disks they changed the material of the floppy surface. |
![]() |
![]() |
#8 | |
Registered User
Join Date: Aug 2010
Location: Germany
Posts: 548
|
Quote:
![]() A commented 'C' version of the MFM encoding/decoding operation can be found here: https://github.com/obarthel/trackfil...ncode_decode.c Also available is a basic data recovery program which will try to find the best version of a sector in multiple attempts, producing an ADF image file: https://github.com/obarthel/trackfil...ies/raw_disk.c The code shows how "it" can be done, although in a pretty pedestrian and none too efficient manner (I hope it is not wrong). I still do not understand how the original Amiga Unix flopf.c code performs the MFM encoding in just two lines. Naturally, these lines are the only ones which bear a code comment: /* aren't I clever */ |
|
![]() |
![]() |
#9 |
Registered User
Join Date: May 2013
Location: Grimstad / Norway
Posts: 877
|
Is there a measure of how much/how many percent of the cylinder can be written before the size of the head or something interferes with a theoretical 100% of the surface being used?
|
![]() |
![]() |
#10 | |
Registered User
Join Date: Feb 2017
Location: Denmark
Posts: 1,316
|
Quote:
For data bits a and b (in that order), the clock bit for b is: a NOR b (i.e. 0 except for two consecutive 0's). ((d0 << 1) | (d0 >> 1))computes "a OR b" aligned in the clock bit positions (and 0's for the data bits), the bitwise negation makes that NOR. Almost there except we now have 1's in all the data bit positions. That could be corrected by masking with ~mask, or like the code is doing oring with mask before the NOT. I.e. instead of the more obvious ~C & ~M, it does ~(C | M). (De Morgan's law) Last edited by paraj; 17 August 2024 at 11:50. Reason: Simplied.. |
|
![]() |
![]() |
#11 | |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 54
Posts: 4,536
|
Quote:
![]() Why 1660 bytes? This is a selected value because it is 'certainly enough', but not with a defined logic. Or at least it is not specified in the sources, so it is surely a value seen 'somewhere else' and 'if it worked it still works'. And if the logic is that "enough is enough", why wasn't it doubled in the case of the 22 sectors? [note: I didn't look at the code but only read the comments] If I know the duration of a cell, how many cells a sector requires, what is the rotation speed of the floppy and what is the maximum tolerance that I am willing to support as a difference for the speed, I can define and calculate the gap perfectly. But since here we are working with mechanical systems and subjected to various analog problems, even a somewhat random value is fine ![]() |
|
![]() |
![]() |
#12 | |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 54
Posts: 4,536
|
Quote:
So over 99.9% is usable ![]() But I don't know if I understood your question well.. |
|
![]() |
![]() |
#13 |
Registered User
Join Date: Jan 2019
Location: Germany
Posts: 3,499
|
There are values where the trackdisk.device could change that value, however, from the default values, this logic just does not seem to be effective. This said, I found little documentation on how "precompensation" actually works, i.e. what it performs physically. |
![]() |
![]() |
#14 | |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 54
Posts: 4,536
|
Quote:
Sometime it help to reduce this effect to write the '1' center position x_ns closer, so when they move a little they are just at the right position. Amiga can do this using x as a multiple (as usual) of the CCK. Unfortunately it doesn't always have the expected effect or work at all. EDIT: it's not known how Paula does this, but it probably 'anticipates' the normal setting of '1' in the bit-stream by x CCK. The effect is possibly visible with a logic analyzer or similar. Last edited by ross; 17 August 2024 at 12:55. |
|
![]() |
![]() |
#15 |
Registered User
Join Date: Jan 2019
Location: Germany
Posts: 3,499
|
Thanks, helpful. I still wonder what the physical effect is here, but never mind, at least it explains what Paula is supposed to do with this information. Given that it is actually not used, it is probably not overly helpful. Had anyone actually tried to play with this and see how it affects reliability?
|
![]() |
![]() |
#16 | |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 54
Posts: 4,536
|
Quote:
I didn't notice anything for normal MFM encodings (but I don't think it hurts to use it on the inner tracks). in any case the DPLL in reading masks the problem.. But the effect should be visible even now using raw grabs with greaseweazle and similar where sampling is done at much higher rates than 2us, and where cells are at a better distance if precompensation is used in the inner tracks. |
|
![]() |
![]() |
#17 | |
Registered User
Join Date: Aug 2010
Location: Germany
Posts: 548
|
Quote:
![]() In the solution which I came up with, I attempted to go for "readable", with examples of what the operations performed will produce, without trying to be clever. |
|
![]() |
![]() |
#18 | |
Registered User
Join Date: Aug 2010
Location: Germany
Posts: 548
|
Quote:
The 1660 bytes must have been arrived at by setting parameters for how much data should go into a single sector, within the constraints and tolerances for the 3.5" disk drives and also how stable the clock governing the DMA operations is for the interval in which the entire track must be read. For a single MFM-encoded sector, that makes sector header + 512 bytes payload = 2 * (32 + 512) = 1056 bytes. For 11 sectors per track, that would be 11968 bytes. Adding 1660 yields a total of 13628 bytes. Those extra 1660 bytes make up 12% of the total 13628 bytes. Unless I made a mistake there, 12% seem like a lot. |
|
![]() |
![]() |
#19 | |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 54
Posts: 4,536
|
Quote:
You should not consider the percentage of increase significant based on the raw data of the sectors, but on the parameters that I specified before: cell duration, drive rotation speed, supported tolerance. Let's take a practical example: an Amiga with an NTSC crystal clock and a standard 300RPM floppy. I took the NTSC case because it is worse than PAL, the cell duration is lower and therefore more data under the same conditions can be stored on the track. A cell is 1/3579545*7=1.95556us If the floppy disk rotates perfectly at 300RPM the storable data is (60/300)/1.95556~=102273 cells (you can immediately notice that on Amiga this value is greater than the standard one, where the cells expected are 100000) The raw MFM data are then ~12784 bytes [cells/8]. Now let's add to this value the maximum we want to tolerate as a speed difference of a drive installed on an Amiga computer. 5%? This is REALLY a super-bad drive... 12784+5%=13423 rounded to 13424 (our buffer, for DMA words handling) This is now our reference value where we need to 'insert' our raw payload of Amiga sectors (11968 bytes). So finally the gap: 13424-11968=1456 bytes. This is a method with foundation for a gap value ![]() |
|
![]() |
![]() |
#20 | |
Registered User
Join Date: Feb 2017
Location: Denmark
Posts: 1,316
|
Quote:
![]() Not needing ~mask can mean a bit more if you code in asm (freeing up a register), but in your code it likely won't matter much. Since this is .asm I found my own old encoding routine. Snipe away ![]() Code:
; d1 = $55555555 ; d2 = previously encoded long ; a2 = buffer lsr.b #1,d2 ; Previous lsb to x move.l d1,d2 ; d2 = mask and.l (a2),d2 ; d2 = mask & data = data move.l d2,d3 ; d3 = data roxr.l #1,d3 ; d3 = data >> 1 | previous << 31 move.l d2,d4 ; d4 = data add.l d4,d4 ; d4 = data << 1 or.l d4,d3 ; d3 = data >> 1 | previous << 31 | data << 1 = ~clock or.l d1,d3 ; d3 = ~clock | mask not.l d3 ; d3 = clock or.l d3,d2 ; d2 = data | clock move.l d2,(a2)+ ; loop |
|
![]() |
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
![]() |
||||
Thread | Thread Starter | Forum | Replies | Last Post |
Most efficient way of storing x/y values over frames | mcgeezer | Coders. General | 13 | 07 October 2020 02:18 |
Floppy power and data cable too short | OscarBraindeaD | support.Hardware | 5 | 12 May 2013 20:07 |
Can anyone help me access data from a floppy? | clouseau | New to Emulation or Amiga scene | 9 | 01 August 2010 16:47 |
Storing retro computers and consoles | Bloodwych | Retrogaming General Discussion | 1 | 06 April 2008 21:32 |
problem storing games on disc | mrbob2 | support.Hardware | 3 | 22 December 2007 12:33 |
|
|