assembler 16 bit keyboard input interrupt handler (int 9h) code has an invalid instruction

68 views Asked by At

I'm writing a 2 dimensional game for training an AI to play the game (kind of reinforcement learning). Before training the neural network I want to let the user generate the needed input patterns by capturing all key events when playing the game. It is important that both the keys pressed and the keys released are detected and also when pressing multiple keys (for example right arrow and Ctrl at the same time). I found some piece of code from Leo Ono on YouTube that seemed usefull to me at first. Unfortunately the assembler code has errors when running the game for more than 5 minutes. When I turn the keyboard input interrupt handler off the game works fine. The video memory is corrupted and the game halts after 5 minutes. Maybe the title of this site is appropriate for the problem because I suspect that the stack memory is overflowing but I have no idea how to increase the stack memory in the assembler code (NASM 16 bit).

I tried the following code (NASM 16 bit):

    
        bits 16

        global _install_key_handler
        global _uninstall_key_handler
        global _is_key_pressed
        
segment _TEXT public class=CODE

  _install_key_handler:
        PUSH ES
        CLI
        MOV AX,0
        MOV ES,AX
        MOV AX,[ES:4*9+2]
        MOV [DS:int9_original_segment],AX
        MOV AX,[ES:4*9]
        MOV [DS:int9_original_offset],AX
        MOV AX,CS
        MOV WORD [ES:4*9+2],AX
        MOV WORD [ES:4*9],key_handler
        STI
        POP ES
        RETF

  _uninstall_key_handler:
        PUSH ES
        MOV AX,0
        MOV ES,AX
        CLI
        MOV AX,[int9_original_offset]
        MOV [ES:4*9],AX
        MOV AX,[int9_original_segment]
        MOV [ES:4*9+2],AX
        STI
        POP ES
        RETF

  _is_key_pressed:
        PUSH BP
        MOV BP,SP
        MOV BX,[BP+6]
        MOV AL,[key_pressed+BX]
        MOV AH,0
        POP BP
        RETF

  key_handler:
        PUSH ES
        PUSH AX
        PUSH BX
        MOV AX,_DATA
        MOV ES,AX
        IN AL,60h
        CMP AL,0E0h
        JZ .ignore
        MOV AH,0
        MOV BX,AX
        AND BL,01111111b
        AND AL,10000000b
        CMP AL,10000000b
        JZ .key_released
    .key_pressed:
        MOV BYTE [ES:key_pressed+BX],1
        JMP .ignore
    .key_released:
        MOV BYTE [ES:key_pressed+BX],0
    .ignore:
        MOV AL,20h
        OUT 20h,al
        POP BX
        POP AX
        POP ES
        IRET

section _DATA public class=DATA
  int9_original_offset DW 0
  int9_original_segment DW 0

  key_pressed times 256 DB 0

I tried to push and pop additional registers (AX and BX) at _is_key_pressed and install/uninstall but that didn't help. I tried to increase the stack memory in Turbo Pascal 16 bit which contains the main source code but this didn't help either. I tried the i8086 cross compiler of free pascal instead of Turbo Pascal but the game only runs without the keyboard input interupt handler code (with the NASM code I get an 'invalid instruction' error.) Is there someone who knows alternative low level keyboard input interrupt handler code with the INT 09h instruction on the 60h keyboard port? I searched extensively on Google but couldn't find anything.

0

There are 0 answers