В прошедшую субботу решил провести «субботник» и наконец-то навести порядок на полках и в шкафах.
В старых коробках, среди всякого разного оборудования, разных плат, девелопер китов и пачек старых дисков обнаружил несколько интересных экземпляров устройств, просто настоящие артефакты древности. С этими артефактами связана целая история, которую и хотел бы рассказать.
Дело было так. В далеком-далеком году мы получили заказ на разработку прошивки для микросхемы Cypress CY7C63723. Это был такой PS/2-USB микроконтроллер. Задача: написать прошивку к этой микросхеме. Но был один нюанс. Микросхема предназначена для преобразования протокола из PS/2 в USB, а нужно было подключить два устройства PS/2, то есть нужно подключить PS/2 мышь и PS/2 клавиатуру с помощью одной такой микросхемы USB конвертера. Микросхема должна была бы устанавливаться на материнскую плату Jetway (если память не изменяет).
Точнее, дело было даже так: эта задача уже делалась каким-то разработчиком, но у него чего-то не получалось. Нам отдали его исходники и сказали, что нужно срочно починить и переделать, но чтоб работало. Кроме исходных текстов нашего неудачливого предшественника тогда мы получили вот это...
Это прототип конвертера Two-PS/2-to-USB, который и нужно было запрограммировать. На самом деле это только макет, микросхема потом устанавливалась прямо на материнскую плату, чтобы дать дополнительные мышь и клавиатуру. Предполагалось, что это будет материнская плата для двух пользователей одновременно, многопользовательский компьютер.
Эмулятор микросхемы Cypress CY7C63723! Такая маленькая микросхема и такой большой эмулятор. Такие вот технологии. Поскольку микросхема была одноразовая, с однократной прошивкой (OTP — One Time Programmable), то невозможно вот так просто взять и разработать прошивку. Нельзя сразу зашивать и пробовать — это слишком долго и расточительно. Поэтому, компания Cypress снабжала разработчиков вот такими странными устройствами — эмуляторами микросхемы. Скомпилировал программу, загрузил в эмулятор микросхемы, имитатор микросхемы через шлейф вставляется в панельку на плате будущего устройства — смотришь как работает. Вот сейчас не уверен, но кажется там даже внутрисхемный отладчик процессора был.
Вот такой нашелся универсальный программатор. К нему еще были пара десятков чистых чипов Cypress, но где уж они теперь?
Когда обнаружил эти железки в старых коробках появилось любопытство. Смогу ли я найти исходники тех программ? Как давно все это было?
Это сейчас все просто. У меня теперь каждый новый ноутбук имеет жесткий диск существенно больше, чем предыдущий. Получается, что покупаешь ноутбук и переписываешь на его большой диск весь старый маленький диск. Первый ноутбук имел 90 Гбайт, второй 320 Гбайт, а последний ноутбук 1 Тбайт. Опять же — сейчас есть «облака» и GIT. А тогда архивы хранились на CD дисках. Иногда записывали на всякий случай по нескольку дисков, чтоб наверняка.
Вот найти старые программы на старых дисках — вот это действительно сложная задача. Но — нашел! Датируется 2003 годом — это примерно 13 лет назад было. Ну и по случаю, мой совет дня: «Никогда не подписывайте диски фразой Current Versions».
Итак… Нас в команде на эту задачу было 2 человека, мы взялись со всем рвением, хотя не имели ни малейшего представления ни про USB, ни про микросхемы Cypress.
Чтобы описать суть происходящего, немного расскажу про микросхему CY7C63723. В этом микроконтроллере жили-были:
- 14-ти битный указатель на исполняемую команду PC (Program Counter);
- 8-ми битный аккумулятор, A;
- 8-ми битный индексный регистр, X;
- 8-ми указатель стека команд, PSP (Program Stack Pointer);
- 8-ми указатель стека данных, DSP (Data Stack Pointer);
И это почти все… ну конечно, разные способы адресации — это понятно. Писать нужно, естественно, на ассемблере. Конечно, внутри микроконтроллера еще есть всякая периферия, традиционная для микроконтроллеров: таймер, GPIO и прерывания от них, USB-функция и так далее.
Это я сейчас, рассматривая старую документацию на эту микросхему (нашел таки ее на дисках), вспоминаю этот проект и удивляюсь этому чуду. Чтобы вы в полной мере ощутили всю мощь микроконтроллера приведу фрагмент списка команд:
NOP — 4 такта
INC A — 4 такта
INC X — 4 такта
INC [EXPR] — 7 тактов
INC [X+EXPR] — 8 тактов
ADD A,EXPR — 4 такта
ADD A,[EXPR] — 6 тактов
ADD A,[X+EXPR] — 7 тактов
…
Несмотря на тактовую частоту микроконтроллера в 12МГц, на деле он оказался совсем не быстрым — все мегагерцы съели такты-на-команду.
Самое интересно, что мы смогли довольно быстро разобраться, как оно должно работать, быстро все починили, прошили первые чипы, испытали, и клавиатура и мышь работают, светодиоды на клавиатуре CAPS, NUM, LOCK — работают. Ура, все хорошо, все довольны и счастливы!
Но — нет. Через неделю или две заказчик говорит, что не работает. Пытаемся выяснять — ничего толком понять нельзя. Между нами и конечным заказчиком есть посредник. То есть, нам заказывает немецкая компания, а им заказывает тайваньская компания. Электронные письма с Тайваня прочитать почти нельзя. Они написаны на «чинглише» — это когда человек думает на китайском языке, а пишет по английски — с трудом поддается расшифровке. В конце концов договорились, что они нам пришлют программу в которой не работает наш PS/2-USB конвертер. Они говорят, что во всех программах работает, а конкретно в этой программе — нет.
Ну ладно — пытаемся выкачать их тестовую программу. 2003-й год, у нас еще используется диал-ап модем, соединение все время рвется, программа очень большая выкачать никак не удается. С какой-то там N-ной попытки выкачиваем… (барабанная дробь) Doom2. Но что? Почему? Как так?
Оказывается все очень просто: нужно нажимая часто на клавиши клавиатуры идти, бежать и прыгать и одновременно мышью вращать и стрелять. А мы так НИКОГДА НЕ ДЕЛАЛИ. Мы то ведь пробовали как все нормальные люди: попробовали клавиши клавиатуры — символы в редакторе набираются, потом попробовали мышь — ездит. Вот бывает же…
Пришлось полностью пересмотреть программу микроконтроллера. Теперь уже при детальном анализе стало понятно, что при одновременно летящих символах из обоих PS/2 устройств обработать сигналы DATA и CLK на двух портах чрезвычайно трудно. Не буду приводить здесь осциллограммы сигналов, их легко можно найти в интернете, хотя бы вот здесь marsohod.org/11-blog/56-ps2. Частота сигнала CLK в PS/2 может быть до 18КГц. Вроде бы очень низкая частота, но если посчитать, то получается совсем не весело. Соотношение частот PS/2 CLK и частоты процессора микроконтроллера: 12000000/18000=666 (о ужас). При средней длине команды 5 тактов получается, что между двумя фронтами PS/2 клока может исполниться не более 130 команд микроконтроллера. А у нас прерывания настроены на четыре сигнала двух портов PS/2: от DATA0, от CLK0, от DATA1, и от CLK1. Самый худший случай — когда фронты некоторых сигналов случайно совпадут — порты же асинхронные. Если подряд два прерывания от разных портов, то получится вообще на прерывание остается тактов по 60…
В общем, пришлось буквально учитывать длительность каждой команды. Приведу фрагмент ассемблерного кода обработчика прерывания, там на многих строках стоит сколько тактов уйдет на команду:
org 0d00h
snd_recv_tabl0:
jmp recv_startbit0
jmp recv_bit0
jmp recv_bit1
jmp recv_bit2
jmp recv_bit3
jmp recv_bit4
jmp recv_bit5
jmp recv_bit6
jmp recv_bit7
jmp recv_parity0
jmp recv_stop0
jmp send_startbit0
jmp send_bit0
jmp send_bit1
jmp send_bit2
jmp send_bit3
jmp send_bit4
jmp send_bit5
jmp send_bit6
jmp send_bit7
jmp send_parity0
jmp send_stop0
jmp send_stop1
rise1:
rise0:
pop a
reti
capture_a_isr:
;here we service interrupts from ps2 port 0
;we must make it as short as possible...
push a ;[5]
iord port0 ;[5]
iord port0 ;[5]
rrc ;[4]
jc rise0 ;[4]
mov a,[status0] ;[5]
asl ;[4]
jacc snd_recv_tabl0 ;[7+5] - 44 ticks
;-------------------------------------------------------------------------------
recv_startbit0_:
inc [status1]
mov a,PS2_WD_TIMEOUT
mov [ps2_wd_b],a
pop a
reti
recv_bit0_:
recv_bit1_:
recv_bit2_:
recv_bit3_:
recv_bit4_:
recv_bit5_:
recv_bit6_:
recv_bit7_:
iord port1
rrc
rrc ;now our strobed bit in flag C
mov a,[sh_in_lo_reg_p1]
rrc
mov [sh_in_lo_reg_p1],a
inc [status1]
pop a
reti
recv_parity0_:
inc [status1]
pop a
reti
recv_stop0_:
mov a,[flag_wait_fa_1]
cmp a,1
jz filter_fa1
mov a,[sh_in_lo_reg_p1] ;[5]
push x ;[5]
mov x,[fifo_head_p1] ;[5]
mov [x+fifo_p1],a ;[6] store our byte to fifo
inc x ;[4] increment fifo head
mov a,x ;[4]
pop x ;[4]
and a,00fh ;[4] fifo size is 16 byte?
mov [fifo_head_p1],a ;[5] save new fifo ptr for future
filter_fa1:
mov a,0 ;[4]
mov [status1],a ;[5]
mov [flag_wait_fa_1],a
mov [ps2_wd_b],a
pop a ;[4]
reti ;[8] - 63+44=107 ticks
nop
Конечно, из памяти уходят многие детали, многих подробностей я уже просто не помню. Знаю только, что глубоко переработанная программа заработала успешно даже в Doom2. Вот что подсчет тактов животворящий делает.
И знаете, что? Я даже сейчас смог откомпилировать эту свою старую программу, просто запустил BAT файл:
Интересно, что у этой истории было еще и продолжение. Коды PS/2 ведь конвертировались в HID коды (PS/2 протокол был сам по себе довольно сложный, смотри marsohod.org/11-blog/57-ps2proto). А когда заказчик из Юго-Восточной страны, то некоторые клавиши там не совсем такие как у нас.
Вот при археологических раскопках в нашем офисе нашел типичную клавиатуру тех времен — ее прислали нам для испытаний. Были и другие экзотические варианты, но не все сохранились. Помню была клавиатура с дополнительными клавишами катакана и хирагана — и что бы это значило? И заказчик требует сделать, чтоб они работали. А как они должны работать? Что должно происходить при их нажатии?
Делали так: брали два одинаковых компьютера и параллельно устанавливали на один ПК — английскую windows 2000, а на второй ПК — чистую японскую Windows 2000, все ОС брались из MSDN подписки. Два компьютера нужны, чтобы правильно отвечать на вопросы в диалогах при установке Windows — прочитать-то мы не можем и перевести так же не можем. Вот параллельная установка на двух ПК как-то спасала. Уже потом клавиатуру подключали к ПК с установленной японской Windows и нажимали эти спорные клавиши пытаясь понять, что должно происходить при их нажатии. Вот как-то так и решались проблемы. Как давно это было…
Ну и что получилось: в результате, разобрать на полках и привести их в порядок не удалось. Наоборот, разворошил все ящики и коробки в поисках иных ценных и интересных для археолога артефактов… Столько интересного нашлось…
Комментарии (10)
BLINDCAT123
09.11.2016 08:46+4nice bit of kit, not sure if i quite understand some of the lanuage, im learning Russian so im always intreagued to know whats going on :)
ktod
09.11.2016 11:46+1Вы прям напомнили, как в самом конце 90х, будучи студеном, подрядился одному испанцу написать прошивку уж-не-помню-на-какой контроллер. Удаленная отладка в те времена была незабываемым приключением.
Особо запомнилось, что после всех оптимизаций свободного пзу осталось 1 байт. :)
roboter
09.11.2016 13:46+1одна микросхема обрабатывает и клаву и мышку?
а клок кто задаёт? клава? почему их 2 разных?
Alexeyslav
09.11.2016 15:27Ассемблер и время исполнения команд подозрительно похожи на Z-80… видимо с одной ветки пошли.
lzb_j77
09.11.2016 19:31А регистры говорят о 6502 или о 6800 :) или вообще о 8048.
Уверен, что после Спектрума можно программировать на любом железе любые задачи :)
FForth
09.11.2016 23:14Вряд ли т.к. растактовки команд ни о чём не могут сказать.
Впечатлило наличие двух указателей стеков в данном кристалле (один из моментов Forth CPU),
а как это «утилизировалось» в системе команд?
P.S. Больше похоже на 6502 систему команд.
pda0
Катакана — фонетический алфавит, для записи звуков, иностранных слов, а так же, емнип, для быстрого ввода иероглифов. Набираешь его звучание катаканой и наборная программа «сжимает» его в иероглиф.
Хигарана — собственно само иероглифическое письмо, которое обычно видят в Японии.
(А у китайцев такого нет, фонетику они записывают латиницей, системой под названием пиньин.)
Японка была забавной. Там символ «йена» разделителем пути работал. Помню месяца через три вынужденного использования понял, что начал понимать иероглифы. Не отдельные конечно, но мог почувствовать смысл надписи, даже без иконки, а иногда даже если не видел её ранее, а надпись была сложена из кусочков ранее виденных. При этом испытывал дискомфорт от немого ощущения, т.к. совершенно не представлял как оно звучит. :)
alexkunin
Напутали вы что-то. Катакана и хирагана — два начертания одной и той же слоговой азбуки, первое для «неродных» слов, второе — для «родных». Да, можно ими и кандзи записывать, т.е. сами иероглифы — это при наборе используется, либо для изучения языка (детьми и иностранцами). Но еще хираганой всякие частицы, связки и окончания пишутся. Но уж точно хирагана — не само иероглифическое письмо.
Dartess
Не совсем так, и катакана, и хирагана — фонетические алфавиты (кана), только катакана для записи слов иностранного происхождения («транслит» на японский). Иероглифы — это кандзи.
Только вот вопрос, как мне кажется, был риторическим :)