Как стать автором
Обновить

Археология программиста

Время на прочтение 6 мин
Количество просмотров 25K


В прошедшую субботу решил провести «субботник» и наконец-то навести порядок на полках и в шкафах.

В старых коробках, среди всякого разного оборудования, разных плат, девелопер китов и пачек старых дисков обнаружил несколько интересных экземпляров устройств, просто настоящие артефакты древности. С этими артефактами связана целая история, которую и хотел бы рассказать.

Дело было так. В далеком-далеком году мы получили заказ на разработку прошивки для микросхемы 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 и нажимали эти спорные клавиши пытаясь понять, что должно происходить при их нажатии. Вот как-то так и решались проблемы. Как давно это было…

Ну и что получилось: в результате, разобрать на полках и привести их в порядок не удалось. Наоборот, разворошил все ящики и коробки в поисках иных ценных и интересных для археолога артефактов… Столько интересного нашлось…
Теги:
Хабы:
+65
Комментарии 10
Комментарии Комментарии 10

Публикации

Истории

Ближайшие события

Московский туристический хакатон
Дата 23 марта – 7 апреля
Место
Москва Онлайн
Геймтон «DatsEdenSpace» от DatsTeam
Дата 5 – 6 апреля
Время 17:00 – 20:00
Место
Онлайн