Страница Ивана Рощина > Статьи >

© Иван Рощин, Москва

ZXNet: 500:95/462.53
E-mail: bestview@mtu-net.ru
WWW: http://www.ivr.da.ru

Работа с диском при включённых прерываниях

(«Adventurer» #9,
 «Чёрная ворона» #3,
 «Радиолюбитель. Ваш компьютер» 6/2000 (дополненная версия))
Дата последнего редактирования: 11.12.2003.

В компьютере ZX Spectrum выполнение команд обмена информацией между оперативной памятью и диском происходит при непосредственном участии центрального процессора Z80 (рис. 1).

Рис. 1
 +---+         +---+         +----+        +----------+
-|   |-       -|   |-       -|    |-       |#####     |
-|   |-       -|   |-       -|    |-       |----------|
-|RAM|- <---> -|Z80|- <---> -|ВГ93|- <---> |   Диск   |
-|   |-       -|   |-       -|    |-       |          |
-|   |-       -|   |-       -|    |-       |          |
 +---+         +---+         +----+        +----------+

Если во время выполнения такой команды произойдёт прерывание, Z80 отвлечётся на его обработку и команда завершится с ошибкой «потеря данных». Таким образом, на работу с диском накладываются определённые ограничения.

Следует заметить, что в современных компьютерах используется так называемый прямой доступ к памяти, когда обмен информацией между памятью и каким-либо внешним устройством происходит без участия центрального процессора (рис. 2).

Рис. 2
 +-----------+       +----------+        +--+-----+--+
 |           | <---> |   RAM    |<--.    |  |HD   |  |
 |           |       +----------+   |    |  +-----+  |
 |    CPU    |                      |    |-----------|
 |           |       +----------+   |    |           |
 |           | <---> |Контроллер|<--' ,->|           |
 +-----------+       |дисковода |<----'  +-----------+
                     +----------+            Диск

ZX Spectrum — компьютер несовременный, и недостаток аппаратных средств, которые позволили бы одновременно работать с диском и делать что-то ещё, приходится восполнять программной поддержкой. Для этого прежде всего нужно разобраться, как осуществляется выполнение команд ВГ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
Порядковый номер прерывания Смещение от начала дорожки, байтов
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 байтов. Рассмотрим, как может происходить чтение такого сектора в наихудшем случае (рис. 3).

Рис. 3
1 |#-----------| 0    <- Числа справа показывают,
                         при чтении какого байта
2 |------#-----| 138  <- произошло прерывание.

3 |------------|

Т.е. при первом обороте диска прерывание произойдёт при чтении байта со смещением 0, при втором обороте момент наступления прерывания сместится на 138 байтов так, что сектор опять не будет считан, и, наконец, при третьем обороте он прочитается.

Итак, получили, что время чтения одной дорожки замедлится в 3 раза. Соответственно, весь диск прочитается за 32*3=96 секунд, что прекрасно согласуется с экспериментальными данными.

Теперь рассмотрим процесс чтения одной дорожки диска MS-DOS. Размер сектора — 512 байтов. В этом случае чтение «наихудшего» сектора может происходить по двум возможным сценариям: либо он прочитается на пятом обороте диска (рис. 4 а), либо на девятом (рис. 4 б).

Рис. 4
а)
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»? По-видимому, тут используется такой способ: процедура проигрывания музыки запускается после чтения очередного сектора. Но при этом вызов процедуры не синхронизируется с прерываниями, а ошибки чтения сопровождаются неприятными завываниями.


P.S. После того, как прошло больше года с тех пор, как эта статья была написана, я решил немного дополнить и уточнить её:

1. О последовательном чтении нескольких дорожек было сказано: если считываются, например, 4 дорожки, каждая за 2,5 оборота диска, то все 4 дорожки будут считаны не за 4*2,5=10, а за 4*3=12 оборотов. Так получилось в результате экспериментального измерения времени чтения. Я объяснял это тем, что когда мы отдаём команду позиционирования на другую дорожку, а затем отдаём команду чтения сектора, ВГ не сразу начнёт читать сектор, а будет ожидать индексного импульса, указывающего на начало дорожки. Видимо, это всё же не совсем так, потому что оказалось, что чтение успешно осуществляется и при полностью заклеенном индексном отверстии. Так что тут нужны дополнительные исследования.

2. Замедление чтения секторов при включённых прерываниях происходит из-за того, что, пока Z80 выполняет процедуру обработки прерывания, происходит потеря данных. Это понятно. А отсюда следует вывод: если процедура обработки будет выполняться за время меньшее, чем промежуток между считыванием байтов с диска, то никакого замедления не будет. Но на что же способна столь короткая процедура обработки прерываний? Времени её работы не хватит даже на то, чтобы поместить новые значения в регистры AY.

А если сделать так: пусть процедура обработки прерываний лишь устанавливает некоторый флаг, например так: LD D,1: EI: RET. А основная программа в промежутках между чтением байтов с диска анализирует содержимое флага, и, как только он станет равным 1, начинает выдавать новые значения в регистры AY (изменяя в каждом промежутке лишь один регистр). Для этого, разумеется, в какой-либо области памяти заранее должен быть сформирован «дамп AY» — значения его регистров через каждые 1/50 секунды. Когда во все регистры AY записаны новые значения, флаг сбрасывается (LD D,0).

При этом мы и получим возможность проигрывания музыки по прерываниям без всякого замедления. Другое дело, что, насколько мне известно, так ещё никто не делал. И трудности на этом пути понятны, начиная с того, что отсутствует прямой доступ к ВГ.

Но, может быть, как раз у вас это и получится! Помню, в 1997 году в «ZX-Ревю» была опубликована моя статья «О сокращении времени форматирования». Тогда это тоже казалось невозможным, но ведь сделали же сверхбыстрые форматтеры и копировщики!

Другие мои статьи о TR-DOS:

1. 

«Доступ к порту #1F в TR-DOS 5.03». «ZX-Ревю» 1—2/1997.

2. 

«О сокращении времени форматирования». «ZX-Ревю» 1—2/1997.

3. 

«TR-DOS: как не допустить ошибки?». «ZX-Ревю» 5—6/1997.

4. 

«Вывод трёхсимвольных расширений файлов в операционной системе TR-DOS». «Радиолюбитель. Ваш компьютер» 7/2000.

5. 

«Усовершенствованный алгоритм определения смены диска». «Радиолюбитель. Ваш компьютер» 9/2000.

6. 

«Расширения файлов TR-DOS». «Радиолюбитель. Ваш компьютер» 12/2000, «Радиомир. Ваш компьютер» 9/2001 (под псевдонимом BV_Creator).

7. 

«Обрубаем файлам „хвост“». «Радиомир. Ваш компьютер» 4/2002.

8. 

«Использование избыточной информации для защиты файлов от повреждений». «Радиомир. Ваш компьютер» 11/2002.

9. 

«Проверка корректности файловой структуры дисков TR-DOS». «Радиомир. Ваш компьютер» 6/2004.

Страница Ивана Рощина > Статьи >