© Иван Рощин, Москва
| ZXNet | : 500:95/462.53 |
| : bestview@mtu-net.ru | |
| WWW | : http://www.ivr.da.ru |
(«Adventurer» #9,
«Чёрная ворона» #3,
«Радиолюбитель. Ваш
компьютер» 6/2000 (дополненная версия))
Дата последнего редактирования: 11.12.2003.
В компьютере ZX Spectrum выполнение команд обмена информацией между оперативной памятью и диском происходит при непосредственном участии центрального процессора Z80 (рис. 1).
+---+ +---+ +----+ +----------+ -| |- -| |- -| |- |##### | -| |- -| |- -| |- |----------| -|RAM|- <---> -|Z80|- <---> -|ВГ93|- <---> | Диск | -| |- -| |- -| |- | | -| |- -| |- -| |- | | +---+ +---+ +----+ +----------+ |
Если во время выполнения такой команды произойдёт прерывание, Z80 отвлечётся на его обработку и команда завершится с ошибкой «потеря данных». Таким образом, на работу с диском накладываются определённые ограничения.
Следует заметить, что в современных компьютерах используется так
называемый прямой доступ к памяти, когда обмен информацией между памятью и
+-----------+ +----------+ +--+-----+--+
| | <---> | RAM |<--. | |HD | |
| | +----------+ | | +-----+ |
| CPU | | |-----------|
| | +----------+ | | |
| | <---> |Контроллер|<--' ,->| |
+-----------+ |дисковода |<----' +-----------+
+----------+ Диск
|
ZX Spectrum компьютер несовременный, и недостаток аппаратных
средств, которые позволили бы одновременно работать с диском и делать
Примечание: разумеется, всё сказанное о командах чтения относится и к командам записи.
Скорость обмена данными между ВГ93 и Z80 равна 250 кбит/с, а диск вращается со скоростью 300 об/мин. Исходя из этих данных, определим количество байтов на одной дорожке (обратите внимание, что в расчётах 1 кбит это 1000 битов, а не 1024):
(250*1000/8)*60/300 = 6250 байтов.
Примерно такое же значение
Теперь вычислим, сколько прерываний произойдёт в течение одного оборота диска, если их частота известна и равна 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 байтов.
Примечание: на моём «Пентагоне» в результате экспериментов было
установлено, что
Вычислим, чему будет равно время полного чтения диска при запрещённых прерываниях:
0,2*160 = 32 секунды.
Теперь попробуем оценить, во сколько раз замедлится чтение одной дорожки
стандартного
Примечание: будем считать, что при чтении дорожки программа сначала
считывает все сектора подряд (при этом
Необходимо учесть, что если последовательно считываются несколько дорожек (например, 4), и каждая дорожка считывается, например, за 2,5 оборота диска, то все 4 дорожки будут считаны не за 4*2,5=10, а за 4*3=12 оборотов диска. Это связано с тем, что когда мы отдаём команду позиционирования на другую дорожку, а затем отдаём команду чтения сектора, ВГ не сразу начнёт читать сектор, а будет ожидать индексного импульса, указывающего на начало дорожки.*
Очевидно, что время чтения одной дорожки (измеряемое в оборотах диска) будет определяться временем чтения «наихудшего» сектора, т.е. такого сектора, на чтение которого будет затрачено наибольшее количество попыток.
Длина сектора на диске
1 |#-----------| 0 <- Числа справа показывают,
при чтении какого байта
2 |------#-----| 138 <- произошло прерывание.
3 |------------|
|
Т.е. при первом обороте диска прерывание произойдёт при чтении байта со смещением 0, при втором обороте момент наступления прерывания сместится на 138 байтов так, что сектор опять не будет считан, и, наконец, при третьем обороте он прочитается.
Итак, получили, что время чтения одной дорожки замедлится в 3 раза. Соответственно, весь диск прочитается за 32*3=96 секунд, что прекрасно согласуется с экспериментальными данными.
Теперь рассмотрим процесс чтения одной дорожки диска
|
|
Практика показывает, что время чтения одной дорожки диска
Видно, что
А вот работать с диском
Как же реализовано одновременное проигрывание музыки и чтение
диска (без всякого замедления!) в таких demo, как «Power Up» и
«Eye Ache 2»?
P.S. После того, как прошло больше года с тех пор, как эта статья была написана, я решил немного дополнить и уточнить её:
1. О последовательном чтении нескольких дорожек было сказано: если считываются, например, 4 дорожки, каждая за 2,5 оборота диска, то все 4 дорожки будут считаны не за 4*2,5=10, а за 4*3=12 оборотов. Так получилось в результате экспериментального измерения времени чтения. Я объяснял это тем, что когда мы отдаём команду позиционирования на другую дорожку, а затем отдаём команду чтения сектора, ВГ не сразу начнёт читать сектор, а будет ожидать индексного импульса, указывающего на начало дорожки. Видимо, это всё же не совсем так, потому что оказалось, что чтение успешно осуществляется и при полностью заклеенном индексном отверстии. Так что тут нужны дополнительные исследования.
2. Замедление чтения секторов при включённых прерываниях
происходит
А если сделать так: пусть процедура обработки прерываний лишь устанавливает
некоторый флаг, например так: LD D,1: EI: RET. А основная программа в
промежутках между чтением байтов с диска анализирует содержимое флага, и, как
только он станет равным 1, начинает выдавать новые значения в регистры AY
(изменяя в каждом промежутке лишь один регистр). Для этого, разумеется, в
При этом мы и получим возможность проигрывания музыки по прерываниям без всякого замедления. Другое дело, что, насколько мне известно, так ещё никто не делал. И трудности на этом пути понятны, начиная с того, что отсутствует прямой доступ к ВГ.
Но, может быть, как раз у вас это и получится! Помню, в 1997 году в
|
Другие мои статьи о
|