(C) Иван Рощин
Работа с диском
при включенных прерываниях
1. Теоретические сведения
В компьютере ZX SPECTRUM выполнение
команд обмена информацией между оператив-
ной памятью и диском происходит при не-
посредственном участии центрального про-
цессора Z80 :
┌───┐ ┌───┐ ┌────┐ ┌───────┐
┤ ├ ┤ ├ ┤ ├ │▒▒▒ │
┤ ├ ┤ ├ ┤ ├ ├───────┤
┤RAM├ <-> ┤Z80├ <-> ┤ВГ93├ <-> │ диск │
┤ ├ ┤ ├ ┤ ├ │ │
┤ ├ ┤ ├ ┤ ├ │ │
└───┘ └───┘ └────┘ └───────┘
Как видим, если во время выполнения
такой команды произойдет прерывание, Z80
отвлечется на его обработку и команда за-
вершится с ошибкой "потеря данных". Таким
образом, на работу с диском накладываются
определенные ограничения.
Следует заметить, что в современных
компьютерах используется так называемый
прямой доступ к памяти, когда обмен ин-
формацией между памятью и каким-либо
внешним устройством происходит без учас-
тия центрального процессора:
┌┴┴┴┴┴┴┴┐ ┌┴┴┴┴┴┴┴┴┴┴┐ ┌─┌───┐─┐
┤ ├ <-> │ RAM │<┐ │ │HD │ │
┤ ├ └┬┬┬┬┬┬┬┬┬┬┘ │ │ └───┘ │
┤ CPU ├ │ │▒▒▒▒▒▒▒│
┤ ├ ┌┴┴┴┴┴┴┴┴┴┴┐ │ │▒▒▒▒▒▒▒│
┤ ├ <-> │контроллер│<┘┌─>│▒▒▒▒▒▒▒│
└┬┬┬┬┬┬┬┘ │дисковода │<─┘ └───────┘
└┬┬┬┬┬┬┬┬┬┬┘ диск
Спектрум - компьютер несовременный,
и недостаток аппаратных средств, которые
позволили бы "параллельно" работать с
диском и делать что-то еще, приходится
восполнять программной поддержкой. Для
этого прежде всего нужно разобраться, как
осуществляется выполнение команд ВГ93
(например, "чтение сектора") при включен-
ных прерываниях.
─────────────────────────────────────────
Примечание: разумеется, все сказан-
ное о командах чтения относится и к ко-
мандам записи.
─────────────────────────────────────────
Скорость обмена данными между ВГ93
и Z80 равна 250 Кбит/с, а диск вращается
со скоростью 300 об/мин. Исходя из этих
данных, определим количество байт на од-
ной дорожке (обратите внимание, что в
расчетах 1 Кбит = 1000 бит, а не 1024):
(250*1000/8) *60/300 = 6250 байт
Примерно такое же значение (плюс-ми-
нус пять байт) можно получить, воспользо-
вавшись для определения длины дорожки
программой Afrodita 3.0 .
Теперь вычислим, сколько прерываний
произойдет в течение одного оборота дис-
ка, если их частота известна и равна 50
Гц:
50*60/300 = 10
Таким образом, на каждый оборот дис-
ка приходится ровно десять прерываний.
Как уже было сказано, если прерывание
произойдет во время чтения сектора, то
этот сектор не будет прочитан. Получает-
ся, что этот сектор нельзя будет прочи-
тать и при следующем обороте диска, т. к.
во время его чтения опять произойдет пре-
рывание. И мы приходим к выводу, что чте-
ние секторов при разрешенных прерываниях
совершенно невозможно.
─────────────────────────────────────────
Примечание: все же есть способ осу-
ществить чтение в таких условиях. Если не
удалось прочитать сектор, надо рассинхро-
низировать процесс вращения диска и мо-
менты наступления прерываний. Сделать это
можно очень просто: остановить двигатель
дисковода, а затем снова запустить его.
После этого остается только повторить
чтение нужного сектора.
─────────────────────────────────────────
А как же, спросите вы, работают раз-
личные demo, в которых чтение секторов
совмещено с проигрыванием музыки по пре-
рываниям? Оказывается, не все так плохо.
Дело в том, что на самом деле такой стро-
гой синхронизации нет. Так, на "Пентаго-
не" при тактовой частоте 3, 5 МГц проме-
жуток между прерываниями составляет при-
мерно 71680 тактов. В этом случае частота
прерываний равна:
3500000/71680 = 48, 83 Гц
─────────────────────────────────────────
Примечание: соответственно, такой
же будет и частота кадров у подключенного
к "Пентагону" монитора или телевизора.
Как видим, это немного отличается от
стандарта (50 Гц). Также это приводит к
тому, что используемый во многих програм-
мах таймер, работающий на прерываниях,
будет отставать на 1, 4 секунды в минуту,
в чем можно легко убедиться.
─────────────────────────────────────────
Теперь в течение одного оборота дис-
ка произойдет 48, 83*60/300 = 9, 77 пре-
рываний. Рассмотрим, сколько байт прохо-
дит под магнитной головкой в промежутке
между двумя прерываниями:
6250/9, 77 = 640 байт
Если считать, что первое прерывание
произошло в тот момент, когда магнитная
головка находилась в начале дорожки, по-
лучаем такую таблицу:
┌──────────────────┬────────────────────┐
│ порядковый номер │ смещение от начала │
│ прерывания │ дорожки, байт │
├──────────────────┼────────────────────┤
│ 1 │ 0 │
│ 2 │ 640 │
│ 3 │ 1280 │
│ 4 │ 1920 │
│ 5 │ 2560 │
│ 6 │ 3200 │
│ 7 │ 3840 │
│ 8 │ 4480 │
│ 9 │ 5120 │
│ 10 │ 5760 │
│ 11 │ 150 (след. оборот)│
│ 12 │ 790 │
│ 13 │ 1430 │
│ 14 │ 2070 │
│ 15 │ 2710 │
│ 16 │ 3350 │
│ 17 │ 3990 │
│ 18 │ 4630 │
│ 19 │ 5270 │
│ 20 │ 5910 │
│ 21 │ 300 (след. оборот)│
│ ... │ ... │
└──────────────────┴────────────────────┘
Видно, что даже если сектор не про-
читался на одном обороте дорожки, вполне
возможно, что он будет прочитан на сле-
дующем обороте, т. к. моменты наступления
прерываний будут смещены на 150 байт.
─────────────────────────────────────────
Примечание: на моем "Пентагоне" в
результате экспериментов было установле-
но, что из-за пониженной скорости враще-
ния диска (299, 4 об/мин вместо 300) мо-
менты наступления прерываний смещаются
не на 150, а на 138 байт. В дальнейших
расчетах будет фигурировать именно эта
величина. Для каждого компьютера она
своя, и, как мы увидим, именно от нее за-
висит степень замедления чтения секто-
ров.
─────────────────────────────────────────
Вычислим, чему будет равно время
полного чтения диска при запрещенных пре-
рываниях:
0, 2*160 = 32 секунды
Теперь попробуем оценить, во сколько
раз замедлится чтение одной дорожки стан-
дартного TR-DOS диска при включенных пре-
рываниях.
─────────────────────────────────────────
Примечание: будем считать, что при
чтении дорожки программа сначала считы-
вает все сектора подряд (при этом какие--
то из них, очевидно, не будут правильно
считаны из-за возникшего прерывания), а
затем при каждом следующем обороте диска
пытается прочитать все ранее неправильно
считанные сектора, и так до тех пор, пока
все сектора не будут прочитаны.
Необходимо учесть, что если последо-
вательно считываются несколько дорожек
(например, 4), и каждая дорожка считы-
вается, например, за 2, 5 оборота диска,
то все 4 дорожки будут считаны не за 4*2,
5 = 10, а за 4*3 = 12 оборотов диска. Это
связано с тем, что когда мы отдаем коман-
ду позиционирования на другую дорожку, а
затем отдаем команду чтения сектора, ВГ
не сразу начнет читать сектор, а будет
ожидать индексного импульса, указывающего
на начало дорожки.
─────────────────────────────────────────
Очевидно, что время чтения одной до-
рожки (измеряемое в оборотах диска) будет
определяться временем чтения "наихудшего"
сектора, т. е. такого сектора, на чтение
которого будет затрачено наибольшее коли-
чество попыток.
Длина сектора на диске TR-DOS равна
256 байт. Рассмотрим на схеме, как может
происходить чтение такого сектора в наи-
худшем случае:
1 ├▒───────────┤ 0 <- показывает, при
чтении какого
2 ├──────▒─────┤ 138 <- байта произошло
прерывание
3 ├────────────┤
Т. е. при первом обороте диска пре-
рывание произойдет при чтении байта со
смещением 0, при втором обороте момент
наступления прерывания сместится на 138
байт так, что сектор опять не будет счи-
тан, и, наконец, при третьем обороте он
прочитается.
Итак, получили, что время чтения од-
ной дорожки замедлится в 3 раза. Соот-
ветственно, весь диск прочитается за
32*3=96 секунд, что прекрасно согласуется
с экспериментальными данными.
Теперь рассмотрим процесс чтения од-
ной дорожки диска MS-DOS . Размер сектора
512 байт. В этом случае чтение "наихуд-
шего" сектора может происходить по двум
возможным сценариям: либо он прочитается
на пятом обороте диска, либо на девятом.
Это показано на схеме:
1 ├▒───────────────────────┤ 0
2 ├──────▒─────────────────┤ 138
3 ├────────────▒───────────┤ 276
4 ├──────────────────▒─────┤ 414
5 ├────────────────────────┤
1 ├────▒───────────────────┤ 93
2 ├──────────▒─────────────┤ 231
3 ├────────────────▒───────┤ 369
4 ├──────────────────────▒─┤ 507
5 ├▒───────────────────────┤ 5
6 ├──────▒─────────────────┤ 143
7 ├────────────▒───────────┤ 281
8 ├──────────────────▒─────┤ 419
9 ├────────────────────────┤
Практика показывает, что время чте-
ния одной дорожки MS-DOS диска в среднем
увеличивается в 7, 6 раза, то есть второй
вариант реализуется немного чаще перво-
го.
Видно, что из-за большей длины сек-
тора чтение замедляется еще сильнее, чем
у диска TR-DOS . В этом TR-DOS получает
хоть какое-то преимущество.
А вот работать с диском IS-DOS при
включенных прерываниях вообще нельзя. Ду-
маю, вы уже догадались, почему - сектор
в 1024 байта будет считываться так долго,
что за это время обязательно произойдет
прерывание, а может быть, и не одно. По
той же причине при включенных прерываниях
нельзя форматировать диск или выполнять
команду чтения трека.
Как же реализовано одновременное
проигрывание музыки и чтение диска (без
всякого замедления!) в таких demo, как
POWER UP и EYE ACHE 2 ? По-видимому, тут
используется такой способ: процедура
проигрывания музыки запускается после
чтения очередного сектора. Но при этом
вызов процедуры не синхронизируется с
прерываниями, а ошибки чтения сопровож-
даются неприятными завываниями.