Сборка клавиатуры IO Port - PullRequest
       17

Сборка клавиатуры IO Port

2 голосов
/ 08 августа 2010

Я видел следующую тему .

Мне интересно связываться с клавиатурой с помощью инструкций IN / OUT и устанавливать различные режимы, такие как включение светодиода заглушки.До сих пор я столкнулся с проблемами при этом.Следующая ссылка может помочь.

Я пробовал различные комбинации, такие как

mov al,0EDh           ;ED command - Send LED bits. The next byte written to port 60h updates the LEDs on the keyboard.
out 60h,al            ;out on port 60h
mov al,00000111b      ;led status - all leds on. bits 3-7 = reserved(zero)
out 60h,al            ;out on port 60h

Буду признателен за любую помощь.Спасибо.

РЕДАКТИРОВАТЬ: Как я уже сказал, использование порта 60h не работает, я искал по сети для использования 0040: 0017.Одна из сетей заявила, что биты 5,6,7 содержат данные о состоянии светодиодов

Я пытался использовать этот код:

mov al,es:[0017h]
or al,11100000b
mov es:[0017h],al

, и он тоже не работал.

Возможно, я ошибаюсь, поэтому кто-нибудь может мне помочь или выслать мне рабочий код для включения всех 3 светодиодов?

EDIT2: я запустил свое приложение на MS-DOS, установленном на виртуальной машинеи код работал отлично.

Мой вопрос: как я могу заставить его работать вне MS-DOS ??

Ответы [ 2 ]

1 голос
/ 12 августа 2010

Чтобы получить доступ к портам ввода / вывода из задачи, работающей в режиме VM86 или защищенном режиме, вам необходимы специальные привилегии.Эти привилегии можно получить с помощью:

  • IOPL (только для задач в защищенном режиме): если текущий уровень привилегий для задачи <= IOPL задачи, доступ разрешен. </li>
  • Битовая карта разрешения ввода / вывода (для задач VM86 и задач защищенного режима с недостаточным CPL): TSS может содержать битовую карту для разрешения / отклонения доступа к порту ввода / вывода.

Когда доступ отклонен, GPF

В Linux есть системные вызовы iopl () и ioperm (), которые позволяют процессам с CAP_SYS_RAWIO получить эти привилегии.Таким образом, получить доступ к светодиодным индикаторам клавиатуры в Linux можно следующим образом:

#include <stdio.h>
#include <sys/io.h>

int main()
{
    int ret;

    ret = ioperm(0x60, 0xf, 1);
    if (ret < 0) {
            perror("ioperm");
            return 1;
    }
    while (inb(0x64) & 0x2);
    outb(0xed, 0x60);
    while (inb(0x64) & 0x2);
    outb(0x07, 0x60);
    ioperm(0x60, 0xf, 0);

    return 0;
}

Windows NTVDM и Linux Dosemu используют режим VM86 для запуска программ реального режима DOS.При попытке доступа к порту I / O не разрешен, генерируется GPF, и эти системы могут эмулировать (или нет) доступ к порту I / O.Дозему имеет переключатель -k, который обходит обычный tty-слой и напрямую обращается к клавиатуре.Используя этот переключатель, ваш первый пример работает.

Теперь, чтобы сделать то же самое в Windows, вероятно, потребуется сделать это с драйвером, работающим на кольце 0. Альтернативой может быть использование драйвера, который разрешает процессам кольца 3 доступ кпорты ввода / вывода (очень небезопасные): см., например, ioperm для cygwin .

0 голосов
/ 08 августа 2010

Я никогда не писал на клавиатуру, используя 60 долларов, не знаю, что там.Попробуйте записать светодиодные биты в $ 0417.

Изменить:

procedure writekbd(kbdbyte:byte);
begin
   mem[$0000:$0417]:=kbdbyte;
end;

function readkbd:byte;
begin
   kbdbyte:=mem[$0000:$0417];

   rsh:=kbdbyte and $1;
   lsh:=kbdbyte and $2;
   ctl:=kbdbyte and $4;
   alt:=kbdbyte and $8;
   scr:=kbdbyte and $10;
   num:=kbdbyte and $20;
   cap:=kbdbyte and $40;
   ins:=kbdbyte and $80;

   readkbd:=kbdbyte;
end;

procedure numoff;
begin
   readkbd;
   writekbd(kbdbyte and $df);
end;

procedure numon;
begin
   readkbd;
   writekbd(kbdbyte or $20);
end;

procedure capoff;
begin
   readkbd;
   writekbd(kbdbyte and $bf);
end;

procedure capon;
begin
   readkbd;
   writekbd(kbdbyte or $40);
end;

procedure scroff;
begin
   readkbd;
   writekbd(kbdbyte and $ef);
end;

procedure scron;
begin
   readkbd;
   writekbd(kbdbyte or $10);
end;

Изменения в 0000: 0417 вступили в силу немедленно.

Редактировать 2:

Оказывается, моему коду нужны прерывания для обновления статуса клавиатуры в конце концов.

mov ax, 0100h
int 0016h
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...