Как читают телефонные карты, или научись цеплять к своему компу девайсы
Спецвыпуск Xakep, номер #011, стр. 011-088-3
Процедурки, которые здесь тусуются, научат тебя подключать и отключать ногу порта. На каждую ногу по две процедуры: одна выдает на ножку единицу, другая - ноль. Единица - это +5 вольт, а ноль - это почти 0 вольт. Вот и вся хреноматика. На одной ноге проводок Reset, на другой - Clk. Этими двумя проводками мы управляем режимами карты.
Вторая нога порта (d0) у нас заведена на reset карты. Эта процедура выполняет установку d0 в 1 (set reset). Не забывай, что установленное значение не изменится до тех пор, пока мы не запишем новое. Порт здесь - стандартный LPT1, его адрес в шестнадцатиричной записи: 378h. Просто с перепою RMaster забыл о всяких шестнадцатиричностях и пишет три десятичных восьмерки. Имеет право, 378h=888d.
Устанавливаем Reset в единицу:
procedure s_reset;
begin
s:=port[888]; {Порт данных LPT1}
asm
mov al,1 {В регистр AL загружаем маску 00000001}
mov bl,s {В BL загружаем данные из LPT1}
or bl,al {Устанавливаем младший разряд в единицу, остальные не меняем, результат в BL}
mov s,bl {Результат сохраняем в s}
end;
port[888]:=s {Выдаем в порт байт из s}
end;
Устанавливаем проводок Reset в ноль. Процедура сброса второй ноги порта в 0 (clear reset):
procedure c_reset;
begin
s:=port[888];
asm
mov al,254 {Маска 11111110}
mov bl,s
and bl,al {Устанавливаем младший разряд в ноль, остальные не меняем}
mov s,bl
end;
port[888]:=s
end;
Ну, а теперь для проводка Clk. Те же самые процедуры сброса и установки, только для третьей ноги порта. d1 соединена с Clk карты. Установка Clk в 1 (set Clk):
procedure s_clk;
begin
s:=port[888];
asm
mov al,2 {Маска 00000010}
mov bl,s
or bl,al
mov s,bl
end;
port[888]:=s
end;
Сброс Clk в 0 (clear Clk):
procedure c_clk;
begin
s:=port[888];
asm
mov al,253 {Маска 11111101}
mov bl,s
and bl,al
mov s,bl
end;
port[888]:=s;
end;
Проводок i/o предназначен для чтения. Пишем функцию, которая может проверить, что у нас творится на выходе телефонной карточки. Через эту функцию мы засасываем в компьютер инфу, которая хранится на карте. А через Reset и Clk мы просим карту дать нам эту инфу.
Функция при запуске выдает инвертированное значение 8 бита по адресу 379h. Этот бит равен 1, если на 11 ноге порта (busy) НИЗКИЙ уровень сигнала, и 0 - если уровень сигнала ВЫСОКИЙ. 11 нога соединена с i/o карты.
function io:byte;
begin
s:=port[889]; {LPT1}
asm
mov al,128 {10000000}
mov bl,s
and bl,al
mov s,bl
end;
s:=s shr 7; {Сдвиг вправо на 7 разрядов, младшие 7 разрядов выбрасываются}
if s=1 then io:=0 else io:=1;
end;
И еще раз для тех, кто с пропеллером. Если язык ассемблера ты не понимаешь, не обращай внимания на внутренности процедур. Достаточно знать, что данная процедура устанавливает 0 или 1 на некоторой ноге, при этом никак не влияя на другие. Функция io считывает 0 или 1 с 11 вывода порта.
Пауза
Пауза необходима на быстрых машинах, без нее сигналы будут передаваться быстрее, чем карта их сможет обработать.