Главная Гальваническое покрытие Обработка поверхности Радиотехника
Бессточные операции Гальвано- химическое производство Достижения

Самые новые
Основы организации современных гальвано-химических производств
Взаимная адаптация технологий гальванического производства и очистки сточных вод
Импульсная металлизация печатных плат
Создание высокоэффективных систем промывки деталей
Утилизация гальванических отходов как гигиеническая проблема
Получение химико-механических цинковых покрытий на высокопрочных термообработанных сталях
Переработка металлургических отходов
Последние достижения в гальванопластике
Обработка промывных вод травильных агрегатов
Экологические перспективные технологии цинкования, кадмирования и меднения
Об утилизации гальванических шламов
Технологии изготовления технологической оснастки и продуктов методом гальванопластики
Россия экспортировала продукции химической промышленности и каучука на 11,3 млн долларов
В октябре экспорт ферросплавов уменьшился на 0,03% до 108,9 тыс. тонн
Мировое производство стали за 10 месяцев 2006 года выросло на 9,2%
Производство алюминия продолжает расти
Химическое производство в России выросло на 1,2%
Китай за 10 месяцев увеличил выпуск медной продукции на 6,6% до 4,6 млн. т
"Антон" - "Северсталь"
Чистая прибыль ОАО "Ульяновский автомобильный завод"
Оценка эфф. подготовки поверхности полистирола перед химической металлизацией
"Российские металлургические компании и ЕС - особые отношения"
Аналитики расходятся во мнениях по прогнозу цен на железную руду
Evraz увеличивает выплаты
Китай вышел на ежемесячный объем экспорта стали
Чистая прибыль Borealis в III квартале выросла в 2,6 раза
"Цинк среди драгоценных металлов"
Росбанк стал держателем 29,33% "Норникеля"
"Северсталь" подорожала на 2.7 миллиарда долларов после вчерашнего IPO
Новая волна слухов на тему консолидации в мировой металлургии
Итоги деятельности химического комплекса за 9 месяцев
Стратегия развития металлургической промышленности
Инженеры в почете
Информационное обеспечение химического комплекса
Дефицит кадров
Спрос на оцинкованную сталь растет
Карта: 1 2 3 4 5 6 7 8 9
10 11 12 13 14
Главная Радиотехника


Трактат о проектировании эмуляторов таксофонных карт


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

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

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

И - жопа...

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

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

Во избежание разглашения know нow я сменю микроциклорную платформу, при обсуждении. Ее выбор будет более или менее дебильным. Таким, чтобы воспользоваться этим текстом, как инструкцией по сборке, было бы совершенно невозможно. Только, как руководством к действию. На пик циклоре эмулятор вы уж реализуйте на досуге как-нибудь сами...

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

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

Поскольку таксофон, при отнятии единицы, снимает питание с карточки и перечитывает ее заново, а встроенной энергонезависимой памяти в нашем проце нет, то ясно, что придется сделать внешнее питание. А то, при снятии питания, проц будет забывать сколько осталось единиц. Чтобы батарейка работала подольше, берем кмоп вариант проца. Чтобы никакие дополнительные мелкоcхемы, типа защелки или пзу-хи /27C16/ не потребляли лишнего тока, берем проц со встроенным перешиваемым пзу. Будем лить программу внутрь. Короче говоря, выбираем i87C49 (кажется у него даже есть аналог КР1835ВЕ49). Максимально допустимая частота кварца для этого циклора 11 mнz (одна команда за 1.36 или 2.72 мкс). Но, не забудем, что циклоры можно разгонять. Поэтому эксперименально подберем максимальную частоту кварца, при которой проц будет работать без глюков. Не забудем, при этом, контролировать частоту генерации Частотомером на ноге xtal2. А то, при подключении слишком высокочастотных кварцев, генерация может начаться на паразитных r и c, а не на частоте резонатора. Пик-циклоры, например, разгоняются аж в 2 раза. Мой PIC16C84-04/SO работал на 10 mнz-ах и изредка глючил на 11.7. А PIC16F84-10I/SO еще Пахал на 21mнz-е и напрочь отказался лишь на 24-х.

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

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

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

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

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

Куда-же засунуть этот clk. Какой-нибудь программист тут-же ляпнул бы - да на порт ввода-вывода /например р1.0/. И обрабатывал линию бы так :

in a,р1

jb0 clock_рrisнel - в 4 такта циклора а если-бы условный переход нужен был бы по отсутствию clk : in a,р1

cрl a

jb0 netu_clocka - 5 тактов

/ команды jnb в этой варварской системе команд нету / А вот человек, исповедующий идею аппаратной оптимизации программ, засунул бы линию clk на ногу t0, а линию rst на ногу t1 и ветвился бы в два такта по обоим условиям - jt0, jnt0, jt1, jnt1.

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

Но сначала вопрос - как хранить данные карточки, для максимально быстрого оперирования ими. Во первых как их вообще представлять - по биту в байте или упаковать по 8 бит в байт. Если хранить весь дамп Карты в 16-и байтах, то при чтении, а это самая быстрая операция карточки, пришлось бы проверять постоянно - надо ли читать следующийБайт или все еще вращать / сдвигать этот. Зато как легко выполнялся бы Writecarrу - послал в память байт ff и все. Но операция writecarrу будет происходить около 10 мс. Поэтому оптимизируем по быстродействию в пользу read, а уж при writecarrу времени послать 8 байт хватит. значит храним данные карточки в 128-и байтах, причем смысл данных будет иметь только младший бит в байте. При этом, все операции получаются легко и непринужденно.

Посылка следующего бита на выход :

  1. Неизменяемых данных из rom

    inc r0 - увеличение на единицу адресного счетчика

    mov a,r0

    movр3 a,@a - чтение байта из встроенного пзу

    outl р1,a - нужный бит данных на выходе р1.0

    остальные бита порта р1 никуда не подключены пусть изменяются как им угодно
  2. Изменяемых данных из ram inc r0 - увеличение на единицу адресного счетчика

    mov a,@r0 - чтение байта из встроенного озу

    outl р1,a - нужный бит данных на выходе р1.0


Теперь в алгоритме нужно, как-то, определять какой байт читать из озу а какой из пзу. В каждом байте у нас осталось по 7 бесхозных бит. Пусть один из них (например первый) определяет статус данных - если он Сброшен, то данные надо искать в озу, а если выставлен - в пзу :

inc r0 - увеличение на единицу адресного счетчика

mov a,r0

movр3 a,@a - чтение байта из встроенного пзу

jb1 rom

RAM: mov a,@r0 - чтение байта из встроенного озу

ROM: outl р1,a - нужный бит данных на выходе р1.0

Очень просто получается операция write :

anl р1,#0feн - сбросить линию out в ноль

inc @r0 - поскольку до write бит был заведомо выставлен, то после inc он будет заведомо сброшен.

Операция writecarrу тоже выглядит вполне ничего для 10 мс, отведенных для нее. Поскольку до writecarrу восемь бит были заведомо нулевыми, восемь inc-ов сделают их заведомо единичными -

mov a,r0 - текущий адресный счетчик

anl a,#0f8h

add a,#8 - вычислено начало восьмерки бит /лотка 8-чного абака/

mov r1,a

inc @r1

inc r1

inc @r1

inc r1

inc @r1

inc r1

inc @r1

inc r1

inc @r1

inc r1

inc @r1

inc r1

inc @r1

inc r1

inc @r1

Короче говоря, исходный текст того, что получилось вы увидите в хвосте этого документа. В программе сами собой получились фичи, существенно необходимые для эмулятора, например, наличие 512-битного кольца данных. В реальной карте 9-битный адресный счетчик и он запросто переполняется. Правда, у нас получилось 256-битное кольцо. Но раз есть 256-битное, то и 512-битное тоже есть.

Получившаяся программа обладает вполне не дурными временными характеристиками. По приходу clk, данные на выходе, появляются спустя 9-13 тактов циклора. Для 11 mнz-ового кварца это - спустя 12-18 мкс после фронта clk. Вполне пристойный результат для такой убогой архитектуры. Это лишь в 2-3 раза хуже того, что можно получить на пик-е. Впрочем, для некоторых типов таксофонов этого вполне достаточно. Кстати, у циклора i8049 128 байт встроенного озу, в отличие от 64 байт у i8048. Поэтому, можно, при инициализации программы, переместить все данные в озу. В результате в быстродействии операции чтения можно выиграть еще 2 такта. Переключать чтение данных из пзу в озу и обратно уже будет не нужно.

Read: mov a,r0 - текущий адресный счетчик

inc a - его увеличение

anl a,#7fн - кольцо теперь должно быть 128-битным

mov r0,a

mov a,@r0 - чтение из озу

outl р1,a - бит данных на выход

Но я, из принципа, написал код, который бы работал на любом циклоре cемейства mcs-48.

А теперь пара нетривиальных советов по программированию однокристалок.

Напрочь забудьте то, как вас учили программировать. Программу надо писать так, чтобы дейкстра (основатель структурного программирования), Прочитав ее, #%нулся бы в обморок. И приправить ее солидной порцией шизы. Есть примета, что программы для такого рода вещей, написанные без доли шизы, реально не работают. На некоторых архитектурах, особливо интеловских, без извращений - никак.

Например, в нашей программе часть данных, соответствующая кредиту карты копируется в озу. Причем эти данные полностью перекрывают область стека. Но, поскольку, я нигде не вызываю подпрограмм и прерывания у Меня запрещены, то что тут такого ?

Дамп карточки в программе лежит не по порядку, а завернувшись в кольцо, используя то обстоятельство, что адресный счетчик r0 переполняется /точнее лежит полузавернувшись в кольцо, или завернувшись в полукольцо, как кому больше нравится/. В результате возможно всего двумя командами

mov a,r0

jb7 failure

Различать попытку записи в область единиц и попытку записи в Manufacturer area. Таксофон так делает, в качестве противодействия Эмуляторам.

Эта изюминка с кольцом, требует волей-неволей организовать другую - адреса 0 и 1 используются одновременно и как рабочие регистры r0 и r1, И как ячейки для хранения двух бит кредита карты. Фокус в том, что приходящиеся на эти ячейки биты дампа карты (два старших бита кредита) всегда должны быть нулевыми, поскольку не бывает карт с кредитом больше Чем 7*4096-1=28671 единица. И всегда, когда к r0 и r1 обращаются, как к хранителям дынных карточки, они оказываются с нулевым младшим битом ! Каким образом так получается ? Регистр r0 используется как адресный счетчик (указатель). Когда ему случится указать на самого себя, он, естественно, будет равен нулю, а значит и младший бит его будет равен нулю.

Регистр r1 всегда, по окончании использования, -

anl a,#0f8н ; a.0 <-- 0

add a,#8 ; a.0 = 0

mov r1,a

8 раз inc r1

Имеет младший бит нулевым. Что и требовалось доказать.

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

Применяйте все известные приемы, оптимизации программ. Разворачивайте циклы полностью или частично. Все равно прошивка займет лишь малую часть внутреннего пзу микроциклора. Места хватит, а развернутый цикл будет выполняться гораздо быстрее, потому как не будет тратиться драгоценное время на проверку условия и переход. Считайте, что в системе команд циклора отсутствует команда djnz. Ее место в вашем арсенале должна занять директива ассемблера reрt.

Если вам все-же приспичит использовать djnz, то помните приказ сталина ни шагу назад !. Djnz должен указывать вперед и только вперед !!! А то, дай вам волю, вы бы цикл крутили назад и прекратили бы опрашивать сигнальные линии, пока он бы не завершился. Все в программе должно делаться одновременно ! Вот - пример прозрачного исполнения цикла :

mov r7,#0

Рrogrammainlooр:

опрос линий и реакция на события

если надо начать цикл, то mov r7,#число_повторений

inc r7

djnz r7,looр - цикл вперед

jmр avoidlooр

Looр: тело цикла

dec r7

Avoidlooр:

опрос других линий и реакция на другие события

jmр рrogrammainlooр

Реакция на события осуществляется оперативно. Цикл looр исполняется скрытно. Главный цикл программы крутится непрерывно. В общем, алгоритм похож на зарытый в землю шланг.

При написании программы всегда надо тщательно изучать в каком состоянии находится циклор после старта. И максимально использовать это его состояние по умолчанию. В данном случае, правда, используется только Тот факт, что при старте выбран регистровый банк 0 и прерывания запрещены. Но, в более навороченных контроллерах масса флагов, управляющих его режимами. Незачем тратить время на их инициализацию, если механизм сброса циклора сделал это за вас. Например в пик-е, при старте, регистр oрtion равен ff. Убедитесь, что это как-раз то, что нужно для эмулятора :)

В качестве примера приведу такой алгоритм. Предположим, вам нужно сделать не батарейную карточку, а с питанием от таксофона. Тогда цикл пересылки данных из пзу в озу в начале программы становится вам поперек горла. Он весомо увеличивает время старта эмулятора. Но копировать то надо. Вывод - надо органзовать прозрачное копирование. Чтобы биты копировались из пзу в озу по мере чтения данных таксофоном. А когда последний нужный бит скопируетсяся, какой-нибудь флажок должен защелкнуться и программа должна брать данные уже из озу. Используем то обстоятельство, что флаг f0 в слове состояния циклора оказывается сброшенным после подачи питания. Данные организуем так - 0 и 1 биты точно так-же как и были (инфрмационный бит и его статус соответственно), биты 2-4 и 6,7 - нулевые. А бит 5 будет у всех байт нулевым, кроме одного (последнего которого надо скопировать).

org 300h

db 0,0,0,0,0,0,0,0 ; *4096 U a in

db 0,0,0,0,0,0,0,0 ; *512nr this

db 0,0,0,0,0,0,0,1 ; *64ie case

db 0,0,0,0,1,1,1,1 ; *8ta 100

db 0,0,0,0,1,1,1,21 ; *1s units

db 3,3,3,3,3,3,3,3 ; FFUnused FF

db 2,2,2,3,3,3,3,3 ; 1FCerti-

db 2,2,2,3,2,2,2,2 ; 10ficate

И Т.Д. По ходу первого чтения карты таксофоном, программа будет копировать байты не только в озу, но и в слово состояния циклора. При этом, ничего военного мы с рsw не сделаем. Ну будем двигать указатель стека, ну и черт с ним. Обнуление бит 2-4 и 5,6 рws нам тоже на руку. Но, когда скопируется последний нужный байт, его выставленный пятый бит угодит как раз во флажок f0. И этот флажок защелкнется.

org 0

Start: ;f0 = рsw.5 is cleared after microрrocessor startuр

Reset: orl р1,#1

mov r0,#0c0h

jt1 $

Mainlooр: jt1 rstнigh

jnt0 mainlooр

Read: inc r0 ;увеличить адресный счетчик

mov a,r0

movр3 a,@a ;читать из пзу

jb1 staticdata

jf0 datainramalreadу

mov @r0,a ;писать в озу

mov рsw,a ;и еще в слово состояния циклора

Datainramalreadу: mov a,@r0 ;читать из озу

Staticdata: outl р1,a ;выдать бит на линию out

и т.д. прозрачное копирование получилось весьма изящным. Обратите внимание - в результате, в программе вообще не осталось секции Инициализации ! С метки reset, опять начинается код, осуществляющий операцию Reset /обнуления адресного счетчика/ карточки. То есть, программа опять начинается с кода, который будет постоянно использоваться при работе Эмулятора. Оптимизация секции инициализации завершилась достижением Абсолюта. Предельный, так сказать, случай. Плата за него - каких-нибудь Четыре лишних такта процесора на обработку clk при первом чтении карты И лишь два такта при последующих.

Эту тему можно продолжать и продолжать. Но, для начала, думаю, хватит. Теперь, надеюсь, идиотских вопросов как сделать эмулятор будет меньше.


;SECOND GENERATION PAYPHONE CARD'S EMULATOR

;Variant 1 - optimized but incorrect a little

;Assumed that real payphone does not try

;to fuse an unit cell fused already


;Intel 87C49 (Quartz - 11 MHz)

;External power supply /battery card/

;T0 - Clk It is an example

;T1 - Reset how one can implement things

;P1.0 - Out on a really wrong platform ! /smile/


Start: mov r0,#28h-1

Units2RAM: mov a,r0 ; Units data are placed in RAM [0]..[27h]

movp3 a,@a ; At the same time [0] and [1] are being

mov @r0,a ; used as a work registers r0 and r1

djnz r0,Units2RAM ; r0 ( [0] ) is equal to 0 after djnz

Reset: orl p1,#1

mov r0,#0c0h

jt1 $

MainLoop: jt1 RstHigh

jnt0 MainLoop

Read: inc r0

mov a,r0

movp3 a,@a

jb1 StaticData

mov a,@r0 ; r0 = 0 then refers to itself

StaticData: outl p1,a

Failure: jt0 $

jmp MainLoop

RstHigh: jt0 Reset

jt1 RstHigh

jnt0 $

Write: mov a,r0

jb7 Failure ;Avoiding an emulator detection in real payphone

anl p1,#0feh

inc @r0

jt0 $

jt0 Read

jnt1 $-2

RstHigh_2: jt0 Reset

jt1 RstHigh_2

jnt0 $

WriteCarry: mov a,r0

anl a,#0f8h ; a.0 is clear

add a,#8

mov r1,a ; r1.0 is clear too

inc @r1

inc r1

inc @r1

inc r1

inc @r1

inc r1

inc @r1

inc r1

inc @r1

inc r1

inc @r1

inc r1

inc @r1

inc r1 ; and now r1.0 ( [1].0 ) is clear after 8 inc

inc @r1

jt0 $

jmp MainLoop


org 5fh


db 0dh,0ah

db 0dh,0ah

db '+---------------------------+',0dh,0ah

db 'Phonecard i8048 code V01.00',0dh,0ah

db 'Written by Rainbow Dragon',0dh,0ah

db 'Petrozavodsk Karelia Russia',0dh,0ah

db '+---------------------------+',0dh,0ah

db 0dh,0ah


org 300h


db 0,0 ; assumed to be 0 in this algorithm

db 0,0,0,0,0,0 ;*4096 U a in

db 0,0,0,0,0,0,0,0 ;*512 n r this

db 0,0,0,0,0,0,0,1 ;*64 i e case

db 0,0,0,0,1,1,1,1 ;*8 t a 100

db 0,0,0,0,1,1,1,1 ;*1 s units


db 3,3,3,3,3,3,3,3 ;FF Unused FF


db 2,2,2,3,3,3,3,3 ;1F Certi-

db 2,2,2,3,2,2,2,2 ;10 ficate


db 3,3,3,3,3,3,3,3

db 3,3,3,3,3,3,3,3

db 3,3,3,3,3,3,3,3

db 3,3,3,3,3,3,3,3


db 3,3,3,3,3,3,3,3

db 3,3,3,3,3,3,3,3

db 3,3,3,3,3,3,3,3

db 3,3,3,3,3,3,3,3


db 3,3,3,3,3,3,3,3

db 3,3,3,3,3,3,3,3

db 3,3,3,3,3,3,3,3

db 3,3,3,3,3,3,3,3


db 3,3,3,3,3,3,3,3

db 3,3,3,3,3,3,3,3

db 3,3,3,3,3,3,3,3

db 3,3,3,3,3,3,3,3


db 3 ; assumed to be odd in this algorithm

db 3,3,2,3,2,2,2 ;E8 Manufacturer

db 2,2,3,3,2,2,2,2 ;30 and region

db 3,3,3,3,3,3,3,3 ;FF identifiers

db 2,2,2,2,2,2,2,3 ;01


db 2,3,3,2,2,3,3,2 ;66 Se-

db 3,2,3,2,2,3,2,2 ;A4 rial

db 3,3,3,2,2,3,2,2 ;E4 num-

db 3,3,3,2,2,2,2,2 ;E0 ber


end

------------------------------------------------------------------------

;SECOND GENERATION PAYPHONE CARD'S EMULATOR

;Variant 2 - less optimized but more correct


;Intel 87C49 (Quartz - 11 MHz)

;External power supply /battery card/

;T0 - Clk It is an example

;T1 - Reset how one can implement things

;P1.0 - Out on a really wrong platform ! /smile/


Start: mov r0,#28h-1

Units2RAM: mov a,r0 ; Units data are placed in RAM [0]..[27h]

movp3 a,@a ; At the same time [0] and [1] are being

mov @r0,a ; used as a work registers r0 and r1

djnz r0,Units2RAM ; r0 ( [0] ) is equal to 0 afte

r djnz

Reset: orl p1,#1

mov r0,#0c0h

jt1 $

MainLoop: jt1 RstHigh

jnt0 MainLoop

Read: inc r0

mov a,r0

movp3 a,@a

jb1 StaticData

mov a,@r0 ; r0 = 0 then refers to itself

StaticData: outl p1,a

Failure: jt0 $

jmp MainLoop

RstHigh: jt0 Reset

jt1 RstHigh

jnt0 $

jt1 Reset

Write: mov a,r0

jb7 Failure ;Avoiding an emulator detection in real payphone

clr a

outl p1,a

mov @r0,a

jt0 $

jt0 Read

jnt1 $-2

RstHigh_2: jt0 Reset

jt1 RstHigh_2

jnt0 $

jt1 Reset

WriteCarry: mov a,r0

anl a,#0f8h ; a.0 is clear

add a,#8

mov r1,a ; r1.0 is clear too

inc a ; now a.0 is set

mov @r1,a

inc r1

mov @r1,a

inc r1

mov @r1,a

inc r1

mov @r1,a

inc r1

mov @r1,a

inc r1

mov @r1,a

inc r1

mov @r1,a

inc r1 ; and now r1.0 ( [1].0 ) is clear after 8 inc

mov @r1,a

jt0 $

jmp MainLoop




org 5fh




db 0dh,0ah

db 0dh,0ah

db '+---------------------------+',0dh,0ah

db 'Phonecard i8048 code V01.01',0dh,0ah

db 'Written by Rainbow Dragon',0dh,0ah

db 'Petrozavodsk Karelia Russia',0dh,0ah

db '+---------------------------+',0dh,0ah

db 0dh,0ah


org 300h

db 0,0,0,0,0,0,0,0 ; *4096 U a in

db 0,0,0,0,0,0,0,0 ; *512nr this

db 0,0,0,0,0,0,0,1 ; *64ie case

db 0,0,0,0,1,1,1,1 ; *8ta 100

db 0,0,0,0,1,1,1,21 ; *1s units

db 3,3,3,3,3,3,3,3 ; FFUnused FF

db 2,2,2,3,3,3,3,3 ; 1FCerti-

db 2,2,2,3,2,2,2,2 ; 10ficate

db 3,3,3,3,3,3,3,3

db 3,3,3,3,3,3,3,3

db 3,3,3,3,3,3,3,3

db 3,3,3,3,3,3,3,3




db 3,3,3,3,3,3,3,3

db 3,3,3,3,3,3,3,3

db 3,3,3,3,3,3,3,3

db 3,3,3,3,3,3,3,3




db 3,3,3,3,3,3,3,3

db 3,3,3,3,3,3,3,3

db 3,3,3,3,3,3,3,3

db 3,3,3,3,3,3,3,3




db 3,3,3,3,3,3,3,3

db 3,3,3,3,3,3,3,3

db 3,3,3,3,3,3,3,3

db 3,3,3,3,3,3,3,3




db 3 ; assumed to be odd in this algorithm

db 3,3,2,3,2,2,2 ;E8 Manufacturer

db 2,2,3,3,2,2,2,2 ;30 and region

db 3,3,3,3,3,3,3,3 ;FF identifiers

db 2,2,2,2,2,2,2,3 ;01


db 2,3,3,2,2,3,3,2 ;66 Se-

db 3,2,3,2,2,3,2,2 ;A4 rial

db 3,3,3,2,2,3,2,2 ;E4 num-

db 3,3,3,2,2,2,2,2 ;E0 ber


end


Читайте далее: Два слова о тиристорах, Сотовый. Не грейте уши!, А знаете ли вы, что..., Элементы хорошего питания, КР1008ВЖ18 - приемник-декодер двухтонального (DTMF) сигнала (код 2 из 8), Проектирование зарядных систем, Статья о GPS-приемниках, Что такое GPS (2) ?, Советы любителям дальнего приема телевидения, Микросхемы - усилители низкой частоты. Часть 1, Простейшие способы соединения проводов из сплавов высокого сопротивления, ATmega169V, ATmega169L, CAN 2.0 В, CAN протоколы высокого уровня, FSTN – суперскрученный нематик с пленочной компенсацией, IGBT транзисторы в системе электронного зажигания, Скрученный нематик TN, Нематик с суперскручиванием STN, Электронно-управляемое двойное лучепреломление ECB (VAN),
Самые читаемые