【发布时间】:2017-01-02 23:43:26
【问题描述】:
我正在尝试制作一个简单的游戏引擎/库来创建我自己的 DOS 游戏。我目前正在努力让输入正常工作。我遇到的问题是我处理 int 9(键盘输入)的自定义 ISR 锁定了我的程序。
注意:我通过使用我的编译器的 _dos_getvect() 和 _dos_setvect() 让它工作;但是,我不知道为什么我自己的自定义 getInterruptVector() 和 setInterruptVector() 不起作用。如果有人能解释原因,我将不胜感激。
查看“interrupt_hooker.c”中的相关代码。
main.c
#include "input.h"
#include "stdio.h"
int main(int argc, char *argv[])
{
hookKeyboardISR();
unsigned char i = 0;
while(1)
{
printf("%i", 1);
//i = getKey(SCAN_ESC);
//printf("%i", i);
}
unhookKeyboardISR();
return 0;
}
输入.h
#ifndef INPUT_H_INCLUDED
#define INPUT_H_INCLUDED
#include "scan_codes.h"
void hookKeyboardISR();
void unhookKeyboardISR();
unsigned char getKey(unsigned char scan_code);
unsigned char isExtended();
#endif // INPUT_H_INCLUDED
输入.c
#include "input.h"
#include "interrupt_hooker.h"
#ifndef NULL
#define NULL ((void*)0)
#endif // NULL
unsigned char key_array[MAX_SCAN_CODES] = {0};
unsigned char extended_key = 0;
void __interrupt (*oldKeyboardISR)() = NULL;
unsigned char getKey(unsigned char scan_code)
{
return key_array[scan_code];
}
unsigned char isExtended()
{
return extended_key;
}
void __interrupt keyboardISR()
{
unsigned char scan_code = 0;
unsigned char temp = 0;
scan_code = inp(0x60);
outp(0x61,(temp = inp(0x61)) | 0x80);
outp(0x61,temp);
/*asm
{
in al, 60h //get scan code from keyboard controller
mov scan_code, al //put it in scan_code
in al, 61h
or al, 80h
out 61h, al
xor al, 80h
out 61h, al
}*/
switch(scan_code)
{
//if extended code
case 0xe0:
extended_key = 1;
break;
case 0xe1:
break;
default:
//check if break code
if(scan_code & 0x80){
scan_code &= 0x7f;
//set key to released
key_array[scan_code] = 0;
}
else{
//set key to pressed
key_array[scan_code] = 1;
}
extended_key = 0;
break;
}
//send EOI
outp(0x20, 0x20);
/*asm
{
sti
mov al, 20h
out 20h, al
}*/
}
void hookKeyboardISR()
{
if(oldKeyboardISR == NULL){
getInterruptVector(0x09, oldKeyboardISR);
setInterruptVector(0x09, keyboardISR);
}
}
void unhookKeyboardISR()
{
if(oldKeyboardISR != NULL){
setInterruptVector(0x09, oldKeyboardISR);
oldKeyboardISR = NULL;
}
}
interrupt_hooker.h
#ifndef INTERRUPT_HOOKER_H_INCLUDED
#define INTERRUPT_HOOKER_H_INCLUDED
void getInterruptVector(unsigned char int_number, void __interrupt (*isr)());
void setInterruptVector(unsigned char int_number, void __interrupt (*isr)());
#endif // INTERRUPT_HOOKER_H_INCLUDED
interrupt_hooker.c
void getInterruptVector(unsigned char int_number, void __interrupt (*isr)())
{
asm
{
cli
mov al, int_number
mov ah, 35h
int 21h
mov word ptr [isr], bx
mov word ptr [isr+2], es
sti
}
}
void setInterruptVector(unsigned char int_number, void __interrupt (*isr)())
{
asm
{
cli
mov dx, word ptr [isr+2]
mov ds, dx
mov dx, word ptr [isr]
mov al, int_number
mov ah, 25h
int 21h
sti
}
}
【问题讨论】:
标签: c assembly game-engine dos