我試圖在保護模式下設置硬件中斷處理程序,使用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
(因此永遠不會停止主循環),使我猜測處理程序不能正確返回或僅被調用一次。另一方面鏈接工作正常(刪除包裝線,並用chain_protected_mode
替換set_protected_mode
)。 我錯過了一條線嗎?
'counter'應標記爲'volatile'。 –
另外,在'_go32_dpmi_lock_code'和'... data'調用中刪除不必要的強制轉換。他們把'void *'(它將接受任何類型的指針)和'size_t'(這是'sizeof'的結果)。 –
另外,使用'endHandler'來嘗試和計算'handler'的大小是可疑的。沒有什麼能保證'endHandler'會像''handler'一樣立即出現,就像你期待的那樣。在GCC中,更好的解決方案是將'handler'放入自定義部分並使用鏈接描述符變量來獲取其大小。但我不確定DJGPP。 –