IPB

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

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


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

Группа: Root Admin
Сообщений: 6 276
Регистрация: 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 привела к тому, что все жили долго и счастливо. И я там был, мёд-пиво пил, на клаву текло, а в рот не попало.


--------------------
Живы будем - Не помрем !
Пользователь в офлайнеКарточка пользователяОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
Wesha
сообщение 23.12.2020, 22:16
Сообщение #2


Новичок
*

Группа: Участники
Сообщений: 1
Регистрация: 23.12.2020
Пользователь №: 35 567



Сiдайте в кружок, дорогие мои детишечки. Дід Панас расскажет вам ось якую сказочку.

Сижу я значит, весьма много лет назад, клепаю на дорогой и любимой БК-шке то-то. И писал я программу для работы с клавиатурой. Проверяю разряд 6 в регистре 177716, там единичка, то есть клавиша нажата. Иду брать код в @#177662, и обламываюсь - там какая-то фигня! Проверяю @#177660 - и правда, бит, который говорит о готовности кода с клавиатуры, не установлен! И только после примерно 50-70 циклов SOB он таки появляется.

В общем, оказывается, что между нажатием клавиши (о чём тут же докладает бит в регистре 177716) и появлением готового кода проходит некоторое время, причём разное для разных экземпляров БКшек, но в пределах одного экземпляра - более-менее стабильное. Сначала об этой находке сделал анонс (Дuck Tales #4) - а потом подумал-подумал, и решил (Дuck Tales #7) не раскрывать детали - чтобы любители делать защиты не приняли это на вооружение.

Как я понимаю, величина задержки определялась конкретными экземплярами D4, R4, C3 и D2 (см. схему), установленными в конкретной машине.

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

Сообщение отредактировал Wesha - 26.12.2020, 0:11
Пользователь в офлайнеКарточка пользователяОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения

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

 



Текстовая версия Сейчас: 19.3.2024, 18:14