IPB

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в эту темуОткрыть новую тему
> Истории
SuperMax
сообщение 10.1.2016, 21:39
Сообщение #1


Администратор
*****

Группа: Root Admin
Сообщений: 5 841
Регистрация: 7.1.2006
Из: Красноярск
Пользователь №: 1



отсюда http://shark-ru.livejournal.com/27297.html

Вспомнил один забавный факап, произошедший с одной стороны, из-за чрезмерной унификации, приведшей к избыточности, а с другой стороны из-за вынужденной экономии, приведшей к неполной реализации.

Как-то в молодости прикручивал я к замечательной супер-микро-ЭВМ БК-0011 контроллер винчестера. Это сама по себе забавная история и я её как-нибудь опишу, сейчас суть в другом. Контроллер был успешно прикручен, драйвер был успешно написан, точнее адаптирован из штатного DEC-овского драйвера путём переписывания кусков, использующих команды расширенной арифметики, которые процессор 1801ВМ1 не поддерживал.
(Ёлки-палки, я ещё помню время, когда существовали процессоры без команд умножения и деления!)
Всё бы хорошо, но драйвер иногда, на первый взгляд непредсказуемо, падал с прерыванием по вектору 4 (в архитектуре PDP-11 это исключительная ситуация отсутствия отклика на шине, т.е. мы в устройство чего-то пишем или читаем, а в ответ -- тишина). Разбор полётов показал, что драйвер падает при попытке ЗАПИСАТЬ на диск нечётное количество слов. При этом попытка ПРОЧИТАТЬ нечётное количество слов завершалась успешно!
Обмен с диском происходил секторами по 512 байт (256 слов), для этого у контроллера был буффер, который набивался последовательно через 16-разрядный регистр данных. Т.е. протокол простой: выставили регистры сектора, цилиндра и поверхности, набили 256 слов данных и после записи последнего слова контроллер побежал исполнять операцию: позиционироваться и писать в нужное место на диск. Если клиент драйвера хотел записать меньше слов, чем размер сектора, то драйвер должен был дополнить до целого сектора нулями. Код в драйвере был примерно такой (ассеблер PDP-11, думаю, понятен):
Код

; R2 адрес данных для записи
; R4 длина. для простоты считаем, что не больше 256
; DRDATA адрес регистра данных контроллера
; DRSTAT адрес регистра состояния контроллера
@@1: MOV (R2)+, @#DRDATA
     SOB R4, @@1   ; цикл по R4
@@2  TST @#DRSTAT
     BMI @@3       ; бит 15 (т.е. знак) признак "ЗАНЯТ"
     CLR @#DRDATA  ; забиваем нулями, пока контроллеру не надоест
     BR  @@2
@@3:



Адрес прерывания указывал, что исключение возникает в момент выполнения команды CLR @#DRDATA в этом фрагменте. Т.е. в один прекрасный момент, мы пытаемся записать нулевое слово в регистр данных, а контроллер уже побежал выполнять команду и не реагирует на обращения к регистру данных. При записи нечётного количества слов, ага. А при записи чётного всё классно.

Тут нужно сказать пару слов о системе команд PDP-11. Это была очень хорошая система команд. Как сейчас модно говорить, ортогональная, чем-то отдалённо похожая на систему команд RISC, типа того же ARM. Все регистры (восемь штук, включая SP и PC) были равноправны, а все операнды адресовались одним из восьми способов относительно какого-нибудь регистра. Команды имели длину в одно слово формата (в 8-ичной записи)
CCCCAR для одноадресных команд,
CCARAR для двухадресных команд,
где C - код операции, A - код адресации (три бита, восемь типов), R - номер регистра (три бита, восемь регистров).
(безадресные и другие команды нас тут не интересуют)

Команда CLR (очистка, обнуление операнда), понятное дело, имеет именно такой формат. А какие у нас ещё есть однооперандные команды и что они делают?
Ну, типа
INC op -- прочитать операнд, инкрементировать и записать обратно
DEC op -- прочитать операнд, декрементировать и записать обратно
Принцип ясен, да?
CLR op -- прочитать операнд, обнулить и записать обратно

Т.е. команда CLR выполняла ДВА цикла шины: чтение и запись.
Это особенность именно чипа 1801ВМ1, как, во-первых, очень упрощённого и, во-вторых, спешно перепиленного совсем из другого проекта (этот чип разрабатывался сначала как однокристалка совсем другой архитектуры, в нём ещё много артефактов, например, программируемый таймер, который был доступен и активно использовался БК-шными игрушками, или призрачные регистры, доступные по чтению-записи, но не имеющие никакого эффекта). Структурно этот чип был матричным кристаллом и, видимо, под конкретную систему команд программировался стереотипно, для экономии, тратить лишние ячейки и связи для единственной команды, видимо, было слишком дорого, тем более, что ЛОГИЧЕСКИ это ничего не меняло. Почти ничего.

Дело в том, что разработчики контроллера тоже решили сэкономить. Они решили, что пользователь контроллера, скорее всего, будет человеком вменяемым, и если он перевёл контроллер в режим записи, то читать данные ему в голову не придёт (тем более, что никакого осмысленного результата это операции конструкцией контроллера и не предполагалось). А посему они просто не делали никакой разницы между циклами шины! Они на каждый цикл клали в буфер значение с шины данных. Т.е. команда CLR @#DRDATA записывала в буфер контроллера ДВА нулевых слова, одно на цикл чтения, другое на цикл записи, а общее количество исполненных команд CLR @#DRDATA было в два раза меньше, чем по алгоритму (благо, там цикл не по счётчику, а с предусловием) и если общее количество слов было нечётным, то последний цикл записи приводил к исключению. Э... я сказал: "два нулевых слова"? А, собственно, почему первое слово было нулевым? Ведь на шине не было НИКАКИХ сигналов, и процессор и регистр в этот момент были включены на приём. А потому что линии шины -- типа "открытый коллектор", и притянуты терминаторами к высокому уровню, а логика на шине принята инверсная.

Замена CLR @#DRDATA на MOV #0, @#DRDATA привела к тому, что все жили долго и счастливо. И я там был, мёд-пиво пил, на клаву текло, а в рот не попало.


--------------------
Живы будем - Не помрем !
Пользователь в офлайнеКарточка пользователяОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения

Ответить в эту темуОткрыть новую тему
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 



Текстовая версия Сейчас: 23.9.2019, 0:58