• Viernes 19 de Abril de 2024, 13:01

Autor Tema:  Cambiar el estado de los LEDs del teclado.  (Leído 3669 veces)

Sporeman

  • Nuevo Miembro
  • *
  • Mensajes: 3
  • Nacionalidad: es
    • Ver Perfil
    • http://sporeland.blog.com
Cambiar el estado de los LEDs del teclado.
« en: Jueves 18 de Septiembre de 2008, 18:54 »
0
Hola,

Soy un estudiante de ingeniería eléctrica aficionado a la informática. Hace tiempo que uso Linux, y en este SO hay una utilidad, setleds, para fijar el estado del bloque de mayúsculas, numérico y el scroll.

Quiero hacer algo similar para Windows, con Turbo C y ASM.

De momento, toqueteando la interrupción 16h no he conseguido nada. He rebuscado por Internet, y sí, hay información, pero no hay nada que se ajuste a lo que yo quiero. He bajado el código fuente del programa setleds, y éste fija el estado por llamadas a ioctl (). Yo lo quiero en ASM.

¿Alguien me puede ayudar? No pido que me escribais el código, sólo un poco de ayuda, por que no sé por dónde seguir.  :hitcomp:

Un saludo.

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Cambiar el estado de los LEDs del teclado.
« Respuesta #1 en: Jueves 18 de Septiembre de 2008, 19:29 »
0
Depura el codigo y fijate que hacen esos IOCTLs.

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

posman

  • Miembro MUY activo
  • ***
  • Mensajes: 119
    • Ver Perfil
Re: Cambiar el estado de los LEDs del teclado.
« Respuesta #2 en: Jueves 18 de Septiembre de 2008, 20:42 »
0
Consultando la RBIL, en la direccion de memoria 0040h:0097h (en modo real) indica el estado de los 3 leds (Caps Lock, Num Lock y Scroll Lock). Aunque no se si desde Turbo C se puede acceder a esa parte de la memoria

Consigue la Ralf Brown Interrupr List. Cuando lo descomprimes, debe estar un archivo memory.lst (o archivos .A, .B, etc para unirlos)

Pero aqui esta lo que te menciono:
Citar
MEM 0040h:0097h - KEYBOARD STATUS BYTE 2
Size:   BYTE
SeeAlso: MEM 0040h:0096h,INT 16/AH=11h

Bitfields for keyboard status byte 2:
Bit(s)   Description   (Table M0034)
 7   =1 keyboard transmit error flag
 6   =1 LED update in progress
 5   =1 RESEND received from keyboard
 4   =1 ACK received from keyboard
 3   reserved, must be zero
 2   Caps Lock LED
 1   Num Lock LED
 0   Scroll Lock LED
SeeAlso: #M0033,#M0010

posman

  • Miembro MUY activo
  • ***
  • Mensajes: 119
    • Ver Perfil
Re: Cambiar el estado de los LEDs del teclado.
« Respuesta #3 en: Jueves 18 de Septiembre de 2008, 21:48 »
0
Para cambiar el estado de los LEDS se utiliza el puerto 60h. Hay que enviar un EDh y despues un byte con el estado que quieres poner

Citar
PORT 0060-006F - KEYBOARD CONTROLLER 804x (8041, 8042) (or PPI (8255) on PC,XT)
Note:   XT uses ports 60h-63h, AT uses ports 60h-64h

0060  RW  KB controller data port or keyboard input buffer (ISA, EISA)
      should only be read from after status port bit0 = 1
      should only be written to if status port bit1 = 0
0060  R-  KeyBoard or KB controller data output buffer (via PPI on XT)
      PC: input from port A of 8255, if bit7 in 61h set (see #P0396)
      get scancodes, special codes (in PC: with bit7 in 61h cleared)
        (see #P0390)
.
.
.
Values for keyboard commands (data also goes to PORT 0060h):
Value   Count   Description
 EDh   double   set/reset mode indicators Caps Num Scrl
      bit 2 = CapsLk, bit 1 = NumLk, bit 0 = ScrlLk
      all other bits must be zero.

Sporeman

  • Nuevo Miembro
  • *
  • Mensajes: 3
  • Nacionalidad: es
    • Ver Perfil
    • http://sporeland.blog.com
Re: Cambiar el estado de los LEDs del teclado.
« Respuesta #4 en: Viernes 19 de Septiembre de 2008, 10:14 »
0
Mandando EDh al puerto 60 cambio el estado de las CAPS, NUM, y SCROLL, pero los LEDs no hacen nada. Por lo menos ya tengo algo hecho, muchas gracias  :beer:

No sé si turbo C me deja acceder directamente a la memoria, supongo que al estar ejecutando la aplicación bajo windows, ésta se cerrará y dirá que ha efectuado una operación no válida.

Ahora viene la pregunta tonta: ¿Como voy a esa dirección? ¿Con un mov? Mis conocimientos de Ensamblador son un poco limitados, sorry  :unsure:

De momento parece que vamos bien.  :good:

posman

  • Miembro MUY activo
  • ***
  • Mensajes: 119
    • Ver Perfil
Re: Cambiar el estado de los LEDs del teclado.
« Respuesta #5 en: Viernes 19 de Septiembre de 2008, 15:56 »
0
Para enviar datos a algun puerto en ensamblador, se utiliza in y out

out 60h, 0EDh

En C creo que se utilizan inport/inportb/outport/outportb, pero no estoy seguro

Sporeman

  • Nuevo Miembro
  • *
  • Mensajes: 3
  • Nacionalidad: es
    • Ver Perfil
    • http://sporeland.blog.com
Re: Cambiar el estado de los LEDs del teclado.
« Respuesta #6 en: Viernes 19 de Septiembre de 2008, 23:34 »
0
Pues sí, Windows (XP SP3) me cierra inmediatamente cualquier programa que intente hacer nada con el puerto 60h. En el mejor de los casos, no hace nada.

Como parece que bajo windows no voy a conseguir mucho, he instalado el MS-Dos en una máquina virtual. En MS-Dos y con el debug he creado tres programas muy similares entre sí. Ahí va el código del "nums":

Código: Text
  1.  
  2. 16D2:0100   mov ax,ed
  3. 16D2:0103   out 60,ax
  4. 16D2:0105   mov ax,2
  5. 16D2:0108   out 60,ax
  6. 16D2:010A   mov ax,4c
  7. 16D2:010D   int 21
  8.  

Así funciona exactamente como yo quiero. El 2 es, como os imaginareis, el segundo bit, 2^(n-1)

He probado también con turbo C,
Código: Text
  1.  
  2. void main () {
  3.       asm mov ax,0xED;
  4.       asm out 0x60,ax;
  5.       asm mov ax,7; //Todos los leds encendidos
  6.       asm out 0x60,ax;
  7. }
  8.  
  9.  

E igual, funciona en MS-Dos puro (el virtual PC), pero no en Windows. Me parece que con el modo protegido hemos topado.  :argh:  :hitcomp:

m0skit0

  • Miembro de PLATA
  • *****
  • Mensajes: 2337
  • Nacionalidad: ma
    • Ver Perfil
    • http://fr33kk0mpu73r.blogspot.com/
Re: Cambiar el estado de los LEDs del teclado.
« Respuesta #7 en: Miércoles 24 de Septiembre de 2008, 11:22 »
0
En Windows (y en Linux) un programa no puede acceder a direcciones de memoria que no le pertenezcan. Lo que sí puede hacer (que es lo que tú haces en Linux con ioctl) es pedirle al SO que ejecute ciertas acciones. Lo que tú buscas es la API de Windows que modifique esos LEDs: SetKeyboardState() y GetKeyBoardState(). Suerte programando estas llamadas en ensamblador...

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Cambiar el estado de los LEDs del teclado.
« Respuesta #8 en: Miércoles 24 de Septiembre de 2008, 12:29 »
0
http://en.wikipedia.org/wiki/IOPL

Hilo muy relacionado.

En sintesis no deberias intentar acceso directo al hardware (o memoria fisica) bajo Windows (o cualquier S.O. moderno, 32/64 bits) sino usar la API como bien te indico m0skit0. Usar la API de Windows desde assembly es muy simple, empujas los parametros a la pila (push) y llamas a la funcion (call), incluso hay una directiva en MASM (y creo que otros ensambladores la soportan) llamada invoke que simplifica esto a una linea tipo C:

Código: Text
  1. push param3
  2. push param2
  3. push param1
  4. call Funcion
  5.  

Código: Text
  1. invoke Funcion, param1, param2, param3
  2.  

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

m0skit0

  • Miembro de PLATA
  • *****
  • Mensajes: 2337
  • Nacionalidad: ma
    • Ver Perfil
    • http://fr33kk0mpu73r.blogspot.com/
Re: Cambiar el estado de los LEDs del teclado.
« Respuesta #9 en: Miércoles 24 de Septiembre de 2008, 14:26 »
0
Una nota: si vas a pasar los parámetros por ensamblador, fíjate bien (como pone Eternal Idol) que tienes que meter los parámetros en la pila en orden inverso a cómo los pide la API (o cualquier función).