Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Проблеммы с прерываниями...

7.9K
24 января 2009 года
***Zebr@XXL***
47 / / 18.08.2005
Помогите пожалуйста. Такая проблема: устанавливаю свои обработчики прерываний, в том числе и IRQ1 для клавиатуры. Так вот: прерывание 0x21 вызывается почему-то только один раз. И больше почему-то не хочет.

Вот код установки новых обработчиков, и сами обработчике (установка происходит нормально, проверял в Bochs под отладчиком):
Код:
struct zosIntsTable
{
    u16 CallbackOffset0_15;
    u16 CallbackSeg;
    u8 NULLByte;
    u8 Flags;
    u16 CallbackOffset16_31;    
}__attribute__ ((packed));

struct zosIntsTableRegistor
{
    u16 Length;
    zptr Pointer;
}__attribute__ ((packed));

#define ZOS_IDT_FLAGS_MASK    0x80
#define ZOS_IDT_FLAGS_INT      0x0e
#define ZOS_IDT_FLAGS_TRAP    0x0f

void zosSetINT(u8 index, INTCallback Callback, zbool Interupt)
{
    IDT[index].CallbackOffset0_15 = ((zuint)Callback) & 0xffff;
    IDT[index].CallbackSeg = ZOS_SYSSEG_CODE;
    IDT[index].Flags = (Interupt?ZOS_IDT_FLAGS_INT:ZOS_IDT_FLAGS_TRAP) | ZOS_IDT_FLAGS_MASK;
    IDT[index].CallbackOffset16_31 = (((zuint)Callback) >> 16) & 0xffff;
}

void zosSetINTS()
{
    zos_memset(IDT, 0, sizeof(IDT));
   
    for (zuint i = 0; i < 0x20; i++)
        zosSetINT(i, zosINT_header, zfalse);
       
    zosSetINT(0x20, zosIRQ0_header, ztrue);        //Timer IRQ
    zosSetINT(0x21, zosIRQ1_header, ztrue);        //Keyboard IRQ
    for (zuint i = 0x22; i < 0x28; i++)
        zosSetINT(i, zosIRQ_dummy1, ztrue);
    for (zuint i = 0x28; i < 0x30; i++)
        zosSetINT(i, zosIRQ_dummy2, ztrue);
   
    for (zuint i = 0x30; i < 256; i++)
        zosSetINT(i, zosINT_header, zfalse);
   
    IDTReg.Length = sizeof(IDT) - 1;
    IDTReg.Pointer = IDT;
   
    asm("cli");
    asm("lidt %0":: "m"(IDTReg));
   
    portoutb(ZOS_PORT_8259M1, 0x11);
    portoutb(ZOS_PORT_8259S1, 0x11);
   
    portoutb(ZOS_PORT_8259M2, 0x20);
    portoutb(ZOS_PORT_8259S2, 0x28);
   
    portoutb(ZOS_PORT_8259M2, 0x04);
    portoutb(ZOS_PORT_8259S2, 0x02);
   
    portoutb(ZOS_PORT_8259M2, 0x01);
    portoutb(ZOS_PORT_8259S2, 0x01);
   
    portoutb(0x21, 0);
    portoutb(0xa1, 0);
   
    portoutb(0x70, 0x0d);
    asm("sti");
}

_zosIRQ0_header:
    pushad
    ;call zosIRQ0
    mov al, 020h
    out 020h, al
    popad
    iret
   
_zosIRQ1_header:
    pushad
    lea eax, [zosIRQ1]
    call eax
    mov al, 020h
    out 020h, al
    popad
    iret
   
_zosINT_header:
    pushad
    popad
    iret
   
_zosIRQ_dummy1:
    pushad
    mov al, 020h
    out 020h, al
    popad
    iret
   
_zosIRQ_dummy2:
    pushad
    mov al, 020h
    out 020h, al
    out 0a0h, al
    popad
    iret

void zosIRQ1()
{
    portinb(ZOS_KEYBOARD_PORT1);
    zosPrintString("Key\n");
   
    u8 s = portinb(ZOS_KEYBOARD_PORT2);
    s |= 1;
    portoutb(ZOS_KEYBOARD_PORT2, s);
}


Сообщение "Key\n" почему-то вылезает только один раз. Хотя по идее дожно при нажатии и отпускании клавиши...
1.6K
24 января 2009 года
Vov4ick
476 / / 01.02.2007
Прерывние 21 выполняет функции ввода-вывода для файлов, клавиатуры и экрана. Также осуществляет смену обработчиков прерываний. Очевидно, что твой новый обработчик ничего этого делать не умеет.
На ассемблере написать религия не позволяет? Строчек будет в два раза меньше и код будет понятным.
349
25 января 2009 года
Phantom-84
656 / / 27.10.2005
У меня отличаются значения для мастера и слэйва вот тут:
 
Код:
portoutb(ZOS_PORT_8259M2, 0x01);
  portoutb(ZOS_PORT_8259S2, 0x01);

 
Код:
mov al, 00001101b
  out 21h, al
  mov al, 00001001b
  out 0A1h, al

Потом лучше маскировать неиспользуемые прерывания.
И еще я бы добавил команду чтения значения из порта 0x71 к вот этому:
 
Код:
portoutb(0x70, 0x0d);

А перед перепрограммированием логики 8259 немаскируемые прерывания соответственно нужно запрещать, чего я вообще не увидел. То есть:
 
Код:
cli
  mov al, 8Fh
  out 70h, al
  in al, 71h

На инициализацию IDT не смотрел. Может, там что-то не так.
349
25 января 2009 года
Phantom-84
656 / / 27.10.2005
 
Код:
zosIRQ1_header:
    pushad
    lea eax, [zosIRQ1]
    call eax
    mov al, 020h
    out 020h, al
    popad
    iret
Эй, сиспрограммер, сегментные регистры не вариант сохранить и перенастроить?
349
25 января 2009 года
Phantom-84
656 / / 27.10.2005
 
Код:
u8 s = portinb(ZOS_KEYBOARD_PORT2);
    s |= 1;
    portoutb(ZOS_KEYBOARD_PORT2, s);
???
399
27 января 2009 года
KIV
432 / / 20.01.2009
Цитата: Vov4ick
Прерывние 21 выполняет функции ввода-вывода для файлов, клавиатуры и экрана. Также осуществляет смену обработчиков прерываний.



Прерывание 0x21 имеет данную функцию только в реальном режиме DOS.

261
27 января 2009 года
ahilles
1.5K / / 03.11.2005
***Zebr@XXL***, поясните пожалуйста, что вы вообще делаете? а то тут непонятки DOS, не DOS
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог