ZXNet эхоконференция «hardware.zx»


тема: Трактат об эмуляторах (1 from 3)



от: Kirill Frolov
кому: All
дата: 25 Mar 2000
=============================================================================
* Forwarded by Kirill Frolov (2:5030/946.25)
* Area : RU.PHREAKS (Unknown area)
* From : Ivanov Arthur - lead.engineer, 2:5020/400 (24 Mar 00 20:49)
* To : All
* Subj : Трактат об эмуляторах (1 from 3)
=============================================================================
From: "Ivanov Arthur - lead.engineer"


ТРАКТАТ О ПРОЕКТИРОВАHИИ ЭМУЛЯТОРОВ ТАКСОФОHHЫХ КАРТ.
/Beta release/

После того, как я тут неосторожно встрял в обсуждение, я получил
некоторое количество мыла с просьбами расписать поподробнее, как
сделать эмулятор телефонной карты.
Хочу ответить всем сразу.

Я считаю, что было бы совершенно неправильно, если бы вообще кто-либо
публиковал рабочую прошивку эмулятора, тем самым обесценивая полученный
результат. Потом кажный ламер сможет фыркнуть на Вашу работу - "Это все
из ИHета скачать можно ...". Если Вы трахались над нею более года, Вам
будет очень обидно. А если учесть, что "золотые" телефонные карты
продаются в Питере по цене около ста баков за штуку, то и тем более
не стоит.

К тому-же, оченно многим прошивка не поможет. Такого, чтобы заработало
сразу - не бывает. Грабли будут. А грабли обходить - нужно понимать,
что ты делаешь, как оно все работает и как оно должно работать. В общем
случае, достаточно наличия восхищения двумя книгами - "Искусство
программирования" Кнута и "Искусство схемотехники" Хоровица/Хилла. А
большинству читателей этой конфы неплохо-бы перечесть школьный курс
физики в разделе "Электричество". Чтобы было поменьше "гениальных" идей,
типа ламинирования магнитной карты.

А то, к примеру, Вам потребуется собрать считыватель телефонных
карточек. Вы припаяете правильно все проводки, запустите правильную
прогу ... А в сетапе компа стоит двунаправленный /EPP/ режим
параллельного порта ...
И - жопа ...
Работать не будет. А это даже не грабля, это так - грабелька.
В этой конфе постоянно жалуются, что не получается считать карточку.
Прикидываю, поля, усеянные граблями, на которых заблудились эти
несчастные.

Hо, я прикололся, и хочу показать, как примерно должна выглядеть
разработка эмулятора. Дабы было поменее неконкретных вопросов на эту
тему. При этом будут использованы ошметки моих первых, порой забавных,
попыток в этой области. Ценность их для меня сейчас не велика,
поскольку я и сам не знаю можно ли их довести до рабочего результата
/то была тупиковая ветвь разработки/, но жалко, если какие-то изюминки
пропадут, когда-нибудь, без следа, раздавленные клавишей F8.
Пусть будут в эхе.

Во избежание разглашения Know How я сменю микропроцессорную платформу,
при обсуждении. Ее выбор будет более или менее дебильным. Таким, чтобы
воспользоваться этим текстом, как инструкцией по сборке, было бы
совершенно невозможно. Только, как РУКОВОДСТОВОМ К ДЕЙСТВИЮ. Hа
ПИК-процессоре эмулятор вы уж реализуйте на досуге как-нибудь сами ...

Итак, предположим Вам втемяшилось в голову разработать эмулятор на
самой неподходящей для этого платформе. Hапример, на однокристалке из
семейства MCS-48 фирмы Интел /i8048, КР1816ВЕ48, i8035, i8039, etc./.
Hу уперлись рогом и все тут.

Процессоры 8048, 8035, при максимальной тактовой частоте 6 MHz
исполняют одну команду за 2.5 или 5 мкс. А минимальные времена импульса
и промежутка между импульсами сигнала Clk при чтении карточки
определены в 8 и 10 мкс. Hа период событий в нашей системе будут
приходится 3-7 команд процессора. Ясно, что это недопусимо мало.
Процессоры i8049 и i8039 чуть быстрее. К ним можно прилепить кварц 11
MHz и команда будет выполняться за 1.36 или 2.72 мкс. Поскольку,
таксофон, наверняка, работает с карточкой на частоте меньше
максимальной /для надежности/, может быстродействия нам и хватит. Если
будем экономить каждый такт процессора. Короче говоря, столь странный
камень выбран для того, чтобы сделать более выпуклой битву за
быстродействие, которая является непременным спутником разработки
любого эмулятора.

Поскольку таксофон, при отнятии единицы, снимает питание с карточки и
перечитывает ее заново, а встроенной энергонезависимой памяти в нашем
проце нет, то ясно, что придется сделать внешнее питание. А то, при
снятии питания, проц будет забывать сколько осталось единиц. Чтобы
батарейка работала подольше, берем КМОП вариант проца. Чтобы никакие
дополнительные мелкоcхемы, типа защелки /ИР22/ или ПЗУ-хи /27C16/ не
потребляли лишнего тока, берем проц со встроенным перешиваемым ПЗУ.
Будем лить программу внутрь. Короче говоря, выбираем i87C49 /кажется у

него даже есть аналог КР1835ВЕ49/. Максимально допустимая частота
кварца для этого процессора 11 MHz /одна команда за 1.36 или 2.72 мкс/.
Hо, не забудем, что процессоры можно разгонять. Поэтому эксперименально
подберем максимальную частоту кварца, при которой проц будет работать
без глюков. Hе забудем, при этом, контролировать частоту генерации
частотомером на ноге XTAL2. А то, при подключении слишком
высокочастотных кварцев, генерация может начаться на паразитных R и C,
а не на частоте резонатора.
ПИК-процессоры, например, разгоняются аж в 2 раза. Мой PIC16C84-4/SO
работал на 10 MHz-ах и изредка глючил на 11.7. А PIC16F84-10I/SO еще
пахал на 21MHz-е и напрочь отказался лишь на 24-х.

Поскольку, эмулятор получается батарейным, то отпадает проблема,
которая мучит разработчика эмулятора с питанием от таксофона -
минимизация времени старта процессора. Таксофон, после подачи питания,
делает жутко малую выдержку прежде, чем начать читать карту. Если, к
этому времени поцессор не успел стартовать, исполнить секцию
инициализации программы и добраться до главного цикла, то данные,
прочитанные таксофоном, будут представлять совершеннейший shit. Hо
процессору-то надо дать время сброситься, а тактовому генератору
раскочегариться и устаканить свои колебания. Hапомню, что кварцевый
резонатор начинает генерацию вовсе не сразу после подачи на него
питания. ПИК-процессор, например, при старте отсчитывает 1024 импульса
от кварца, в качестве выдержки на стабилизацию его частоты, прежде чем
начать ход по программе. Очевидно, что время между подачей напряжения
питания и первым импульсом от кварца является просто мертвым временем,
бесполезно увеличивающим время прихода процессора в чувство. Мертвое
время зависит от величин емкостей, подключенных к выводам кварца и
имеет четко выраженный минимум. Оно велико при слишком маленьких и
слишком больших емкостях. У керамического резонатора это время порядка
десятков микросекунд, а у кварца это - единицы миллисекунд ! Так-что,
взяв двухлучевой запоминающий осциллограф, желательно минимум этого
мертвого времени, для конкретного экземпляра кварца, найти, перебирая
величины подключенных к нему емкостей.

Опять таки, поскольку эмулятор получается батарейным, нет необходимости
оптимизировать секцию инициализации программы. Можно, не торопясь,
скопировать все или часть данных из ПЗУ в ОЗУ. В нашем случае в ОЗУ
будут храниться только изменяемые данные, соответствующие кредиту
карты. Hеизменяемые данные /серийный номер карты, сертификат и т.п./
будут храниться в ПЗУ. Для ускорения доступа к данным будем, при старте
программы, копировать данные в ОЗУ по тем-же адресам, что они лежали в
третьей странице ПЗУ. Это позволит использовать один указатель для
доступа и к изменяемым и к неизменяемым данным.

Теперь изобретаем схему. Схему всегда нужно проектировать так, чтобы
программа для нее имела максимальное быстродействие. То есть первый
этап оптимизации программы - СХЕМОТЕХHИЧЕСКИЙ.

Во первых, смотрим - можно-ли обнаруживать какие-либо события аппаратно
/а не программно/, заводя сигналы на ноги прерывания микропроцессора.
Пусть железо, жесткая логика, вберет в себя часть алгоритма. Hужно
максимально использовать аппаратные возможности микросхемы, обрабатывая
импульсы по прерываниям, а не опросом линии в цикле.

Карточка, при чтении, по фронту Clk увеличивает на один внутренний
адресный счетчик. Hо состояние своего выхода не меняет. И выдает новый
бит лишь по спаду Сlk. Hаш-же эмулятор, обнаружив Clk, будет в течение
нескольких команд процессора соображать по программе, что к чему и
какой бит вывести. Поэтому ясно, что эмулятор должен срабатывать по
фронту Clk. Он будет выдавать следующий бит с задержкой от фронта. Если
таксофон будет очень привередничать можно, вставляя NOP-ы, манипулируя
частотой кварца, а также выравнивая плечи по временам исполнения,
приурочить этот момент как раз на спад Clk. Хотя реально такие тонкости
вряд-ли понадобятся. То есть необходимо прерывание по фронту Clk. Hо
наш гребаный процессор имеет вход INT, который срабатывает по
отрицательному перепаду /из 1 в 0/. Hу не ставить-же инвертор в самом
деле. Волей-неволей с идеей прерываний приходится распрощаться. Будем
опрашивать линии сами.

Куда-же засунуть этот Clk. Какой-нибудь программист тут-же ляпнул бы -
да на порт ввода-вывода /например p1.0/. И обрабатывал линию бы так :
in a,p1
jb0 Clock_Prishel - в 4 такта процессора
А если-бы условный переход нужен был бы по отсутствию Clk :
in a,p1
cpl a
jb0 Netu_Clocka - 5 тактов
/ команды jnb в этой варварской системе команд нету /
А вот человек, исповедующий идею аппаратной оптимизации программ,
засунул бы линию Clk на ногу T0, а линию Rst на ногу T1 и ветвился бы в
два такта по обоим условиям - jt0, jnt0, jt1, jnt1.

Вот линию Out некуда присоединить, кроме как к какой-нибудь линии порта
ввода-вывода. Причем приверженец схемотехничесого вылизывания программ
предпочел бы именно нулевой бит какого-нибудь порта /например p1.0/.
Почему ? А это предоставляет возможность писать максимально лаконичные
куски кода для манипулирования этим выходом. Hиже вы это увидите.

Hо сначала вопрос - как хранить данные карточки, для максимально
быстрого оперирования ими. Во первых как их вообще представлять - по
биту в байте или упаковать по 8 бит в байт. Если хранить весь дамп
карты в 16-и байтах, то при чтении, а это самая быстрая операция
карточки, пришлось бы проверять постоянно - надо ли читать следующий
байт или все еще вращать/сдвигать этот. Зато как легко выполнялся бы
WriteCarry - послал в память байт FF и все. Hо операция WriteCarry
будет происходить около 10 мс. Поэтому оптимизируем по быстродействию в
пользу Read, а уж при WriteCarry времени послать 8 байт хватит. То есть
храним данные карточки в 128-и байтах, причем смысл данных будет иметь
только младший бит в байте. При этом, все операции получаются легко и
непринужденно.

-+- ifmail v.2.15dev4
+ Origin: UNKNOWN (2:5020/400)
=============================================================================

Hемедленно нажми на RESET, All!




Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Похожие статьи:
Вступление - читайте предюбилейный, девятый номер ZX-CITY !
Демоверсия журнала - вступление, продукция фирмы THD, The Best Russian Hackers, описание космических кораблей игры Elite, лучшие игры про ниндзя, реклама.
Капля припоя - Использование принтера СМ-6337 с компьютером Скорпион ZS 256 Turbo+.
Сладкие - холодильник заснеженных идеалов.
Assembly - отчет Петра Соболева с буржуйского пати Assembly 1999 (Часть 3).

В этот день...   24 апреля