Page 1 of 1

help with turbo c++ and IVT (Keyboard)

Posted: Fri Oct 05, 2007 6:59 pm
by matias_beretta
Hello, I am doing a 16 Bit OS with Alexei Frounze Bootloader (That Runs An EXE FILE) and TURBO C++.

I decided to make a keyboard driver in c++, so I must set up an interrupt (int 9). I did it in C++ but it doesn't work and i don't know why. Here is my code:

Code: Select all

#include "VGA.H";

void keyboard()
{
   putc('M', 7);
   asm mov al, 0x20;
   asm out 0x20, al;
   asm iret;
}

void main()
{
   asm cli;
   asm mov ax, 0;
   asm mov es, ax;
   asm mov word ptr es:[36], offset keyboard;
   asm mov es:[38], cs;
   asm sti;
}
Thanks...

Posted: Sat Oct 06, 2007 7:48 am
by Combuster
All the TC3 inline assembly code I have seen preserves the segment registers. That's probably for a reason...

Posted: Sat Oct 06, 2007 8:01 am
by frank
What's going wrong are you not getting the M on the screen when you press a key?

reply

Posted: Sat Oct 06, 2007 8:21 am
by matias_beretta
yes, but only one time, after this nothing happens...

Posted: Sat Oct 06, 2007 8:36 am
by frank
Thats because you have to read the keyboard scancode from the keyboard. Try adding in al, 0x60 to your keyboard ISR.

test

Posted: Sat Oct 06, 2007 8:54 am
by matias_beretta
I tested writing in al, 60h but it doesn't work, really, it is the same...

My keyboard handler only works one time...

Posted: Sat Oct 06, 2007 9:56 am
by Combuster
from the list of frequently asked questions:

Send an EOI to the PIC

Posted: Sat Oct 06, 2007 12:21 pm
by frank
Combuster wrote:from the list of frequently asked questions:

Send an EOI to the PIC
But he seems to have that:
asm mov al, 0x20;
asm out 0x20, al;

Posted: Sat Oct 06, 2007 12:37 pm
by XCHG
frank is correct, you do have to read the byte-long scan code from the VT82C42 Keyboard Controller. Your IRQ handler will not be called more than once if you don't do that. Checklist:

1) Read the scan-code from the VT82C42 Keyboard Controller at port 0x60.
2) Send the End of Interrupt (EOI) signal to the Master PIC (at port 0x20). Send 0x20 to port 0x20 where the first 0x20 is the EOI signal and the latter 0x20 is the port number of the master PIC.

I hope that helps. However, below is the code that I have written for my IRQ1 handler. It might be able to help you:

Code: Select all

  __IRQ1Handler:
    ; void Interrupt __IRQ1Handler (void); StdCall;
                                              ; *EAX = The pressed key
                                              ; *EBX = value of the keyboard handler
                                              ; *EDX = Offset of the KeyInformation variable
    IRQPROLOGUE
    XOR     EAX , EAX                         ; Clear the value of the EAX, temporarily
    MOV     EBX , DWORD PTR [KeyboardHandler] ; EBX now holds the value of [KeyboardHandler]
    MOV     EDX , OFFSET KeyInformation       ; EDX holds the offset of the [KeyInformation] variable
    MOV     EAX , DWORD PTR [EDX]             ; EAX is the value of [KeyInformation] variable now
    IN      AL , 0x60                         ; Read the current scan code sent through this IRQ
    TEST    EBX , EBX                         ; See if any keyboard handlers are defined
    JZ      .SendEOI                          ; Jump to ... if not
                                              ; At this point, We are sure that a keyboard handler is registered
    CMP     AL , EXTENDEDKEY_PREFIX1          ; See if the current key is an extended key
    JE      .ExtendedKeyPressed               ; Jump to ... if yes
    CMP     AH , EXTENDEDKEY_PREFIX1          ; See if the previously entered key was an extended key
    JE      .InvokeHandlerForExtendedKey      ; Jump to ... if yes
                                              ; If it is proved not to be an extended key
    .InvokeHandlerForNonExtendedKey:          ; At this point, we are sure that the pressed key is not extended
      AND     EAX , 0x000000FF                ; Clear all bytes except for the scan code now
                                              ;
    .InvokeHandlerForExtendedKey:             ; We should now invoke the Keyboard Handler Procedure (KHP)
      PUSH    EDX                             ; Preserve the value of the data register
      INVOKE  EBX , EAX                       ; Invoke the KHP with EAX as the PressedKey parameter
      POP     EDX                             ; Restore the offset of the [KeyInformation] variable
      XOR     EAX , EAX                       ; Set the value of the EAX register to zero
      MOV     DWORD PTR [EDX] , EAX           ; KeyInformation is renewed and awaits to save new keys' information
      JMP     .SendEOI                        ; Jump to ... now, after we are done invoking the KHP
                                              ;
    .ExtendedKeyPressed:                      ; At this moment, an extended key is proven to have been pressed
      SHL     EAX , 0x08                      ; Move the extended key code to AH, AL = 0
      MOV     DWORD PTR [EDX] , EAX           ; Put this value in the [KeyInformation] variable
                                              ;
    .SendEOI:                                 ; End of the IRQ handler
     IRQEPILOGUE