Hi,
Brandon wrote:
Do you guys know anyplace where I can find how to read/write to the floppy? The initialization/ start the motor / seek / works now... Just need to read/write (and I?m not very familiar with DMA)
Download the 82078 FDC datasheet from here (scroll down to the floppy section):
http://www.o3one.org/hwdocs_.html
Once you've downloaded it read it from start to finish (except the pinouts and electrical timing stuff).
Read and write are very similar - the only differences are the direction of the DMA transfer and the command used to start them:
Set data rate (if not already set)
Send the specify command (if necessary)
Clear the time that the "motor off" delay should expire
Start the floppy motor (if not already running)
Seek to correct track/cylinder (if not already there)
Setup DMA transfer using "single mode", autoinitialization disabled and DMA channel 2
Send the command:
The command byte (read/write, multi-track or not, MFM usually set to 1, SK usually set to 1)
Head/drive
Starting Cylinder
Starting Head (again)
Starting Sector
Bytes per sector code (where 2 = 512 bytes)
Sectors per track (18 for 1440 Kb floppy)
Intersector gap length (more on this later)
Sector size (set to 0xFF unless you use 128 byte sectors)
Wait for an IRQ (sent when the DMA transfer is complete)
Read the 7 status bytes and check if everything worked
Set the time that the "motor off" delay should expire
For everything you find confusing in the list above, refer to the 82078 FDC datasheet. The only things that the datasheet won't explain too well is the "Intersector gap length", and the values used for the specify command (SRT, HUT, HLT).
When a sector of data is stored on the disk there's several different components, which are seperated by several different gaps. There's a gap between sectors, a sector start marker, another gap, then some sector addressing data (cylinder, head, sector, etc) used by the hardware to check if it's in the right place, then there's another gap followed by the actual data (then a CRC and the intersector gap again). It looks a bit like this:
...intersector gap | marker | gap1 | preamble | gap2 | data | intersector gap..
Now, when you are formatting a track you specify how long the intersector gap (or the amount of space between sectors) should be, called gap3. This value can be taken from Table 6-8 on page 37 of the 82078 FDC datasheet (in the GPL2 column). When data is being read or written the intersector gap is also needed, but you tell it something shorter so that the floppy drive starts looking for the start of sector marker before it's too late. For this use the GPL1 column in Table 6-8. As these gaps waste space it's possible to reduce the size of the gap in order to squeeze a few extra sectors in (if the floppy is quick enough to handle it. Using this method it's possible to format a 1440 Kb disk as 1680 Kb by squeezing in 21 sectors instead of 18 (all standard warnings apply).
That only leaves the specifiy command. The values you'd need to figure out are:
SRT - Step Rate Time
HUT - Head Unload Time
HLT - Head Load Time
The SRT is the amount of time that should be allowed for the head to move from one track to another (usually around 8 mS). The HUT is the amount of time it takes to unload the head after reading/writing (usually 250 mS). The HLT is the amount of time it takes to get the head ready to start a reading/writing (usually 16 mS). Unfortunately all of these times are based on the frequency of the data rate, so every time the data rate changes these values would also need to be changed. There are some little tables (Table 6-14 and Table 6-15 on page 41), but they don't give enough detail, so here's my magic formulas to convert SRT, HLT & HUT into actual delays (in mS):
STEPmS = 500*(16 - SRT)/DataRate
if(HUT == 0) HUTtemp = 16
else HUTtemp = HUT
HUTmS = 8000*HUTtemp/DataRate
if(HLT == 0) HLTtemp = 128
else HLTtemp = HLT
HLTmS = 1000*HLTtemp/DataRate
Use these formulas (spreadsheets are good) to find the values that are closest to the delay you want.
I generally send the specify command each time I change the data rate, for e.g.:
setDataRate(rate) {
if(currentRate != rate) {
..set the data rate..
..send the specify command..
}
}
This makes it easier to support multiple floppy drives attached to the same controller, where the data rates might be different for each. Also, if you will be supporting multiple disk formats it's good to have a table/structure containing all the details for each format (name string, data rate, heads, sectors per track, tracks, gap lengths, total size, etc).
Cheers,
Brendan