home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
392.lha
/
tracksalve_v1.3
/
Tech.doc
< prev
next >
Wrap
Text File
|
1990-07-03
|
19KB
|
319 lines
This text contains some background technical info. It is not a manual,
but it fills in some data regarding the problems with disk control and
how things are implemented. (And I love to talk about it after all this
work)
INTRODUCTION
The rotational speed of an Amiga disk is 300 rpm. The time of one
revolution is .2 seconds. Data is sampled at .5 MHz. So a track on an
Amiga floppy disk contains 100000 bits. This can vary a little due to
motor speed variations. Alas we cannot put any desired pattern in these
bits. Therefore data is converted to patterns which are allowed. This
conversion, called MFM-encoding, has an efficiency of 50 percent. For
every bit of data two bits of the magnetic track are used. We can
picture an encoded sector as follows:
4 bytes inter sector gap
4 bytes sync pattern
8 bytes sector ID
32 bytes label
8 bytes checksum over sector ID and label
8 bytes checksum over data block
1024 bytes data block
Therefore the size of a sector is 1088*8=8704 bits. 100000/8704=11,
remainder 4256. Thus we can store 11 sectors. We have 4256 bits left we
donot use for storage. Instead these bits allow us to accept a motor
speed increase of 4.25 %. If we allow the same speed decrease, we must
be able to supply a non used space of roughly 8500 bits or 1100 bytes.
In fact, Trackdisk is prepared for an unused space of 1660 bytes. (Why
that much?)
Trackdisk does not write separate sectors as found on other systems.
Instead it writes out a complete track, actually reformatting the track.
That is why blocks can be so tight together. (On the other systems you
need gaps between the sectors and between sector ID and data block to
allow soft and hardware to synchronize) If Trackdisk writes out a track,
it begins with the 1660 bytes gap, followed by the sectors. Although
the sectors are written out in order, the first sector can be any of the
eleven. The last sector is written over the begin of the gap, thus
effectively removing old data and patterns. Although Trackdisk allows
for synchronisation with the disk index, this is normaly not used;
Trackdisk just starts writing when it is ready to do so.
Reading is something else. If Trackdisk should wait for the gap to
pass, average halve a tracktime is done nothing. Therefore reading is
started, ignoring where the head is in the track. To ensure that all
sectors are read, the readsize must be one sector larger than the number
of available sectors. And the gap must be read too. This results in a
readsize of 12*1088+1660=14716 bytes or 117728 bits, 18% more than a
physical track. Usually the read is started somewhere within a sector,
continues until the gap, the gap itself and enough sectors after the gap
to cover the whole track. Reading and writing is done by DMA (Direct
Memory Access) and word wide (16 bits). Therefore data read from disk
can be in memory shifted up to 15 bits. The part behind the gap has no
exact relation in position and shift to the first read part. To recover
the track, a search is started for a sync pattern. If found, this
informs us about the shift. Knowing the shift, the following sector id
can be decoded. This sector id has the following form and are all
bytes:
$ff (formatbyte)
tracknumber
sectornumber
number of sectors until gap
The last item "number of sectors until gap" tells us how large the part
is with the current shift. This part is shifted and moved to the begin
of the data part of the trackbuffer. Then a second search for a
syncword is done, starting behind the the first part. The remaining
sectors are found and moved and shifted tight behind the first part.
Now there is in the buffer a block of 11 sectors and after updating the
last items of the sector id's, "number of sectors until gap", the track
is ready to be written again.
But before that a lot can go wrong. If some syncword or intersector gap
is distorted, or one of the 22 checksums is wrong, Trackdisk stops and
returns an error. If the error concerns a syncword or a gap, or if a
faulting checksum belongs to a sector ID, it is likely that all data can
be recovered (exept for the label, but that is not used by Dos). And if
the checksum belongs to a data block, but this data block is not
requested, then the other blocks could be read without a problem. Of
course a track with an error must not be written back to disk.
SALVE FUNCTION
The salve function of TrackSalve reads data from disk in such a large
buffer, that there will be an uninterrupted array of sectors in this
buffer. If one sector can be found with a good checksum over its
header, all data to calculate the position of the other sectors is
available. The data and label blocks are copied to the original buffer,
this time with sector 0 in the first position. If the checksum of the
current block is correct, a corresponding bit is cleared in a word that
is initiated with 11 ones. Such a word exists as well for the data as
the label blocks. There is a byte that contains normally the number of
the first sector, but it will contain an error number if the track is
bad. The Trackdisk errors start at 20, so if the byte is larger than
10, the track is bad. Somewhere within trackdisk this is tested and as
result the tracknumber is set to -1, meaning "trackbuffer not valid".
Therefore any subsequent read request will result in a seek and several
read retries of the track. If the salve function is active, this
invalidation of the tracknumber is prevented. Instead the first sector
byte is tested at a read request and if this indicates an error, the
bitpattern with bad blocks are tested. As soon as the request concerns
a bad block, the error value and the number of transferred bytes is set
and fixed, but transfers continues until the number of requested bytes
are copied. There is no difference between the originial behaviour of
trackdisk and the salve function other than the bonus of the extra
transferred data (IO_ERROR contains the error and IO_ACTUAL contains the
number of bytes without error). If label transfers is switched on,
IO_ACTUAL presents the number of sectorbytes transferred until an error
is encountered in a label OR sector. Some specialised recovery program
can use this info to recover more data at the cost of accuracy, which
may be acceptable in some cases. A write to the same track still will
set this tracknumber to -1, and the normal retry scheme will be used.
The salve function is rather introvert and will at a priority of +5
disturb the feeling of the Amiga. So the priority is lowered to -2
during track salvage.
MFM FLAW
How heavy the tests are on the track read from disk, there is a serious
gap (to my opinion) in these itegrity checks. As stated earlier, not
every pattern is allowed in the magnetic track. A MFM encoded data
block exist of true data bits and timing bits. The databits are always
valid: these are not coded, but the timing bits, these are to be found
between the data bits, are meaningless as data. They are just there to
prevent too much and to less subsequent magnetic transitions. Too much
is beyond the bandwith of the medium and too less may lead to loss of
synchronisation and gives noise a chance. The used recording technique
is a transition on a one and no transition on a zero. MFM coding
defines patterns where a one always is followed by a zero, and there are
never more than three subsequent zeros. What happens if there are two
subsequent ones? Or more than three zeros? The system is not that
sensitive that this immediately will lead to bad reads of the data
containing bits. And Trackdisk maintains checksums over encoded data,
or..? But ONLY over the data bits, NOT over the timing bits! If a
timing bit is read wrong from disk, this will not be detected. The
sector is copied to a new position in the trackbuffer, and if an other
sector is changed, it will be written back to disk with the faulting
timing bit! If the sector is not updated (eg belonging to a program)
this faulting bit wil stay forever. Slowly all timing bits can
disappear due to the retry scheme of trackdisk. At a moment the track
will be unreadable. Especially the roottrack is sensitive for this
phenomen.
TrackSalve has modied Trackdisk in such way that just before a track is
written to disk, all timing bits are set according to the MFM standard.
This takes very little time because it is all done by the blitter. Now
that it is ensured that the track is MFM updated before it goes to disk,
the encoding routines can ignore these bits, and that saves cpu time.
Because the encoding routines were rewritten, it was easy to allow non
chip memory for IO buffers. Non-chip buffers are copied by the cpu at
the most efficient way (cribbed from exec's CopyMem()), although
CopyMem() is used if it is replaced.
BUGS IN TRACKDISK
I knew of two bugs and found a third. These all are repaired in
TrackSalve.
Raw read and write had problems because IO_LENGTH was compared with
$8000 instead of #$8000. The difference is that IO_LENGTH should be
compared with the value 8000 hex. Instead it was compared with some
value that was at memory location 8000 hex.
In a multitasking environt the hardware must be shared between the
concurrent tasks. There can be up to four drives connected to the
Amiga. For each drive a Trackdisk task is started (all executing the
same code but with separate data area's). These four drives are
controlled by one piece of hardware (some custom chip I forgot the name
but I know its address). The TD-tasks use it to control their particlar
drives. The tasks ask permission to the disk.resource to access this
chip directly by a call named GetUnit(). If the task is ready with it,
this is told to the disk.resource by a call named GiveUnit(). Another
TD-task that perhaps was waiting for it, gets access permission. There
is a nasty bug in Trackdisk which could disturb the permission scheme.
Because a branch was too far, a call to GetUnit() was missed if that
drive was empty. The task asumed permission, did some access and called
GiveUnit(). This is not as bad as it looks, because the time of violated
hardware access is very short, and was very short after a permitted
access. But if another TD-task had got permission (and the more drives
the more likely this will happen), the turnips are coocked. The other
tasks commands to the hardware are possibly destroyed and to make
matters worse, it looses its permission to access by the first tasks
call to GiveUnit(). So now this ignorent task is violating the rules.
The patch done by the setpatch program modifies disk.resource in such
way that only GiveUnits() are valid from tasks that did the GetUnit().
The access violation was not repaired.
During the tests with special Trackdisk IO programs, some strange
behaviour of Trackdisk came up. Dos is very precise in its IO with
Trackdisk, but a Trackdisk tester is not. That must explain why this
was not disturbing more general. If a write to a protected disk was
done, this disk became unreadable for all other tracks than that was
just written to. Reads via Dos resulted in a Read/Write error requester
although retry selection solved the problem (CMD_CLEAR). A new bug in
Trackdisk? Yes! If you write a sector to a protected disk, first the
track is read into the trackbuffer, followed by a copy of the sector
into this buffer, replacing the original, and a flag is set, meaning
"trackbuffer changed". If you want to read a sector from another track,
trackdisk tries to flush (write to disk) its trackbuffer. The disk is
protected and the attempt will fail. So you cannot read another track!
But it is even worse if you want to read from the track currently in the
buffer. You think the data is coming from disk, but it might be the
never updated sector! What is the problem? Trackdisk does not check
the protect status before letting a CMD_WRITE modify the trackbuffer.
AUTO UPDATE FUNCTION
There were times when I used Sectorama (I still use this nice program
from the hand of David Joiner), I did not understand why sometimes a
modified and written sector would not stick on disk. Now I know this is
because Trackdisk needs some help. It must be told to flush its
buffers, although this is automaticly done if some data is requested
from another track. Trackdisk also does not switch off its drive motor.
If not be told to switch it off, the motor runs forever. Dos knows
about Td's lack of updating and does some special commands: CMD_UPDATE
and TD_MOTOR. Dos does this well within five seconds. But programs
that directly access Td, may not be aware and leave the motor running
and the buffers unflushed.
There are a lot of timers in Trackdisk, so why does not Td do it by
it self? I do not know, but if you have the function switched on,
Td flushes a modified trackbuffer and switch the motor off after
five seconds idling.
NOCLICK FUNCTION
The presence of a disk in a drive is reflected by a line called CHNG.
This line is asserted if there is no disk in the drive. It stays that
way until a disk in the drive and the head is stepped (and the drive is
selected of course). I asume this is done this way to give the
opportunity to acknowledge an disk extraction. If the line directly
reflects the disk presence state, an extraction can be missed. Well, it
is a way, I know some other, and I know too that the sound of an empty
drive generally is experienced to be annoying. The step direction is
each time reversed, so the head will stay about the same position. This
reverse is done by a CPU instruction "bchg", bitchange. Therefore is
was very simple to implement the noclick function, just change the
instruction into "bset", bit set. Then the head steps to the outside of
the disk and once arrived, it stops because it is blocked there. This
can be by a pillow or by an electrical switch, the latter effectively
preventing stepping. When Kickstart got in rom, this was not that easy
anymore. TrackSalve executes Trackdisk in ram, and the patch is simple
again. But should you have noclick on every drive? Some drives still
make noise, this time not as regular as well in time as in sound. Even
more disturbing! Apart from the fact that I believe that these drives
are not suitable for this method.
VERIFY FUNCTION
A drawback of this whole track read/write system is that a simple verify
is not possible. It is not enough to verify the just written sector,
because ten more sectors are written to disk. These sectors have
probably no connection with the writing program, and a more general
warning must be made. It is the particular Trackdisk task that does a
request and the user must reply on it. The AutoRequest() has been
proven unreliable in low memory situations. It returns "Cancel" if the
function could not be carried out, where it should return "Retry". The
same is true for an Alert(). Therefore TrackSalve build its own
requester.
My mouse is often hard to find, and if found, I have to search for a
surface for it (the screen would be nice but it's too steep). So I like
keyboard shortcuts. This is well implemented in the system requester.
If you build your own requester, suddenly all input is blocked, and I
found no way (other than an special inputhandler, which is beyond I am
willing to implement in a patch) to receive shortcuts. What is a
requester other than a window with some gadgets? Then I can receive
everything I like. But this time Dmouse does not recognize the
requester as a requester. Sigh. It doesn't get any easier with
Intuition.
Do do the verify, the track is read back into another buffer and then
compared with the original. This is broken in two parts, because the
data in the verify buffer probably begins with another sector. The
comparision is done by the blitter, xor-ing both buffers.
The motor is switched off before the requester is displayed. The
writing program however is not notified and may not switch off a motor
of a source. The standard diskcopy is a good example. If you use
diskcopy without its verify function, but with TrackSalve verifying
(which is faster), and a verify error happens, the destination drive
will stop turning. Diskcopy does not know and does not switch off its
source drive. This is a good reason to enable the auto update function
in TrackSalve, which will stop the source's motor.
BUGS?
The preceding release of TrackSalve (1.0) had a bug in it, although it
was extremely unlikely that the buggy code would be executed. This
unlikelyness was the reason that the bug slipped through the the
debugging phase. It brought me to an improved debugging administration
and every single branch is executed under debug control, how trivial a
branch might look. Pieces of code that could behave unexpectable
because of special combinations of parameters, have been run under
simulators producing all possible combinations. This time I would like
to qualify the debugging as "extreme". Again: This program is extremely
debugged!
CONCLUSION
With this patch Trackdisk becomes more efficient in its CPU use,
although slightly slower (well under 2%) in its writing, because of the
MFM update. A lot features are added, which are fully transparant.
Trackdisk has come closer to what I think a floppy disk device driver
should be. Better requireres a complete rewrite. (Sorry Commodore,
but disk drivers are my favorite pastime, yours too?).
D.W.Reisig
Woudweeren 10
1151 AV Broek in Waterland
Holland