01/10/2004

Enviar Bytes para porta de teclado AT

Ola pessoal,

Será que alguem teria uma ideia de como enviar Bytes para a porta At de teclado sem usar assembler, ou pelo menos que seja compatível com Win NT/2000 e Linux

A finalidade é exibir msg em Teclados reduzidos e com Display
Exemplo do teclado em: www.gertec.com.br (Tec 44 Dis)

O Código abaixo funciona em Win9x mas gera exceção em NT/2000 e Linux

const
   PortAddr = 96 ;

procedure TACBrDISGertecTeclado.LimparDisplay;
begin
  TxKeyboard( 231 );  // Liga display
  TxKeyboard( 12 );    // Comando para Limpar
  TxKeyboard( 232 );  // DesLiga display
end;

procedure TACBrDISGertecTeclado.TxKeyboard(B: Byte);
begin
  asm
     mov al, B
     mov dx,PortAddr
     out dx,al
  end;
end;



Dopi

Respostas

02/10/2004

Tatuweb

Olá,

O correto não seria o pessoal da gertec fornecer os drivers? Eu uso um driver aqui para porta paralela que funciona perfeitamente. Teoricamente funciona para qualquer porta. Dentro do zip tem um ´passo-a-passo´ em português para instalar o driver.

Clique aqui para baixar


Responder Citar

02/10/2004

Rodc

Pelo que sei a plataforma NT não deixa você fazer acesso direto na porta usando o código assembler. Você tem de usar alguma função API para que o SO faça o acesso. Caso consiga, por favor, poste aqui no site porque tem muitas pessoas procurando como fazer isto, inclusive eu.
Grato,

Rodrigo Cesar


Responder Citar

02/10/2004

Tatuweb

Olá Rodc,

Acho que não fui muito claro no tópico anterior. No link que eu mencionei acima tem um pequeno driver (UserPort.sys) de apenas 4,5 KB dentro do zip. Basta copiá-lo para a pasta C:\WINNT\System32\Drivers. Esse driver vai permitir a você ter acesso a direto as portas nos sistemas 2k e XP via assembly. Na rotina que o colega Dopi escreveu sempre gera um erro na linha
[b:d3bb81f193]out dx, al[/b:d3bb81f193]
pois você está tentando acessar a porta diretamente. Quando você instalar o driver esse problema vai acabar e nenhum erro será gerado.

Junto com o zip do link existe um executável e um pequeno manual. O executável só é preciso rodá-lo uma única vez. Ele apenas vai te poupar do trabalho de reiniciar a máquina e vai carregar o driver. Quando o Windows for reiniciado ele vai automaticamente carregar o driver sem a necessidade de rodar o programa.


Responder Citar

04/10/2004

Dopi

Ola TatuWeb,

Muito obrigado pela dica....

Será que vc pode mandar o endereço de download ou o ZIP no meu Hotmail ?

Isso já resolve parte do problema que é rodar em Win2000/NT....

Quanto ao Linux, ainda não consegui... Todos os códigos que achei se baseiam na antiga função [b:a88cd810c0]outport[/b:a88cd810c0] do C.... e que o código em assembler acima, faz praticamente a mesma coisa, mas gera exceção....

Talvez usar os algum diretório do /dev/ .... mas estou pesquisando.... Assim que concluir, vou inserir o código no componente ACBrDIS para Display´s em geral... O Display Serial Gertec já está funcionando bem em Linux/Windows


Responder Citar

04/11/2004

Dopi

Ola pessoal estou reativando esse tópico porque achei uma solução para enviar comando para a porta AT compatível com LINUX. Estarei atualizando o ACBrDIS em breve na versão 0.08a....

{ Envia bytes para uma porta de Hardware }
procedure OutPort(PortAddr: word; Databyte: byte);
{$IFDEF LINUX}
var Buffer : Pointer ;
    FDevice : String ;
    N : Integer ;
    FHandle : Integer ;
{$ENDIF}
begin
{$IFDEF MSWINDOWS}
  asm
     mov al, Databyte
     mov dx,PortAddr
     out dx,al
  end;
{$ELSE}
  Buffer := @Databyte ;
  FDevice := ´/dev/port´ ;

  FHandle := FileOpen(FDevice, fmOpenWrite);
//FHandle := THandle(Libc.open(pchar(FDevice), O_RDWR or O_SYNC));
  if FHandle <= 0 then
     raise Exception.Create(´Erro abrindo:  /dev/port´+#10+10+
                            ´Você deve ter direito de Escrita nesse diretório.´);

  N := FileSeek( FHandle, PortAddr, 0 )  ;
  if N <= 0 then
     raise Exception.Create(´Erro ao acessar a porta: ´+IntToStr(PortAddr));

  N := FileWrite(Fhandle, Buffer^, 1) ;
  if N <= 0 then
     raise Exception.Create(´Erro ao escrever na porta: ´+IntToStr(PortAddr));

  FileClose( FHandle );
  sleep(1) ;
{$ENDIF}
end ;


Ainda estou tentando otimizar a rotina, percebi que ela gera um bocado de acesso a disco... apesar de não degradar o sistema... nao entendi bem porque... algum tem alguma dica ?

- A funçao acima roda bem em Win9x.
- No XP/NT/2000 é necessário usar o drive indicado pelo TatuWeb....
- No Linux é necessário ter previlégios de ROOT para acessar: /dev/port
Mesmo alterando os privilégios de /dev/port para todos poderem ler e escrever, ainda sim nao funciona a nao ser como SuperUsuário. Alguem sabe como contornar isso ?


Responder Citar