Я пытаюсь настроить аппаратный прерыватель в защищенном режиме, используя djgpp-2 для компиляции в dosbox-0.74. Вот наименьший код возможно (прерывание от таймера), я думаю:Защищенное устройство Прерывание обработчика? (DJGPP)
#include <dpmi.h>
#include <go32.h>
#include <stdio.h>
unsigned int counter = 0;
void handler(void) {
++counter;
}
void endHandler(void) {}
int main(void) {
_go32_dpmi_seginfo oldInfo, newInfo;
_go32_dpmi_lock_data(&counter, sizeof(counter));
_go32_dpmi_lock_code(handler, endHandler - handler);
_go32_dpmi_get_protected_mode_interrupt_vector(8, &oldInfo);
newInfo.pm_offset = (int) handler;
newInfo.pm_selector = _go32_my_cs();
_go32_dpmi_allocate_iret_wrapper(&newInfo);
_go32_dpmi_set_protected_mode_interrupt_vector(8, &newInfo);
while (counter < 3) {
printf("%u\n", counter);
}
_go32_dpmi_set_protected_mode_interrupt_vector(8, &oldInfo);
_go32_dpmi_free_iret_wrapper(&newInfo);
return 0;
}
Обратите внимание, что я не мой обработчик формирования цепочки, но заменяющий его. Счетчик не будет увеличиваться за пределами 1
(поэтому никогда не останавливает основной цикл), заставляя меня угадать, что обработчик не возвращается правильно или вызывается только один раз. Цепь с другой стороны отлично работает (удалите оберточные линии и замените set_protected_mode
на chain_protected_mode
). Я пропустил линию?
'counter' должен быть помечен' volatile'. –
Кроме того, избавляйтесь от ненужных бросков в вызовах '_go32_dpmi_lock_code' и' ... data'. Они берут 'void *' (который примет указатель любого типа) и 'size_t' (что является результатом' sizeof'). –
Кроме того, ваше использование 'endHandler', чтобы попытаться вычислить размер' handler', является сомнительным. Ничто не гарантирует, что 'endHandler' придет сразу после' handler', как вы, кажется, ожидаете. В GCC лучшим решением является установка 'handler' в пользовательский раздел и использование переменной скрипта компоновщика для получения его размера. Однако я не уверен в DJGPP. –