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



У минулу суботу вирішив провести «суботник» і нарешті навести порядок на полицях і в шафах.

У старих коробках, серед всякого різного обладнання, різних плат, девелопер китів і пачок старих дисків виявив кілька цікавих екземплярів пристроїв, просто справжні артефакти давнини. З цими артефактами пов'язана ціла історія, яку й хотів би розповісти.

Діло було так. В далекому-далекому році ми отримали замовлення на розробку прошивки для мікросхеми 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] our store 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 і натискали ці спірні клавіші намагаючись зрозуміти, що повинне відбуватися при їх натисканні. Ось як-то так і вирішувалися проблеми. Як давно це було…

Ну і що вийшло в результаті, розібрати на полицях і привести їх до ладу не вдалося. Навпаки, розкуйовдив всі ящики і коробки в пошуках інших цінних і цікавих для археолога артефактів… Стільки цікавого знайшлося…
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.