I was wondering if you can answer a few questions...

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
ComputerPsi

I was wondering if you can answer a few questions...

Post by ComputerPsi »

Hi. At the moment I am trying to build an operating system, that is very simple (for now). It work on x86 real mode, and uses many bios interrupts to do anything. Right now, I'm try to learn how to make a hardware interrupt/driver for the keyboard. I can already access it with ports 60,61, and 64 but I am not sure how to create an interrupt or driver for it, without using DOS interrupt vector. Anybody know how to do this? Or suggest a way to get any key from the keyboard without having to keep on checking if a key has been pushed...
Lont

RE:I was wondering if you can answer a few questions...

Post by Lont »

Hi,

Do not poll the keyboard it is damn slow. You should use the int as you already pointed out your self.

The keyboard has hardware IRQ 1, which corresponds to INT 9. So you should write a int handler for the keyboard and point the int vector to the handler. The int vector table starts at 0x0000:0x0000 and every int has an 4-byte entry. Describing the segment:offset of the handler. So the int vector of int 9 sits at: 0x0000:0x0024.

Don't forget to put an EOI in your handler and to store the ints in it (sti in asm).

Lont
ComputerPsi

RE:I was wondering if you can answer a few questions...

Post by ComputerPsi »

Oh, I am such an idiot! I already knew how to set software interrupts and that INT 9 is the hardware interrupt for the keyboard, but I thought that hardware and software interrupts are addressed a bit differentely. Well, thanks anyway. (As a test, I set the interrupt code of int 9 to be nothing... And, as you have guessed, the keyboard didn't work at all, because as soon as the keyboard sent to message to the computer, my code stopped it from doing anything :) NO MORE ANNOYING BEEPS IF I PUSH THE KEYS TOO LONG!!!! lol.
ComputerPsi

RE:I was wondering if you can answer a few questions...

Post by ComputerPsi »

Question - What would happen if I didn't put an EOI? Would the system stop the keyboard from working or something?
Another Question - What do you mean by store the ints in it (sti in asm)? I didn't understand that... What I do:
Take the scan code and translate it to its correct ascii, and send it to my hardware interrupt handler I created for the OS. Then, I enable and disable the keyboard quickly (Some tutorials said to do that). Then, I send a EOI to port 20.
Am I missing something?
ASHLEY4

RE:I was wondering if you can answer a few questions...

Post by ASHLEY4 »

This is some code,that may help you hook up your keyboard driver with out dos.
[code]
; set interrupt vector
_func25:
         cli
        xor ah, ah
        shl ax, 2

        push si
        push bx
        push es

        mov si, ax
        xor bx, bx
        mov es, bx

        mov word [es:si], dx            ; offset
        mov bx, ds
        mov word [es:si+2], bx          ; segment

        pop es
        pop bx
        pop si
        sti

        jmp int21_exit

;----------------------------------------------------------------------------
; get interrupt vector
_func35:
        push ds
        push si

        xor ah, ah
        shl ax, 2
        mov si, ax

        xor bx, bx
        mov ds, bx              ; DS = 0

        mov bx, word [ds:si+2]  ; segment
        push bx
        mov bx, word [ds:si]    ; offset

        pop es                  ; get segment

        pop si
        pop ds


        jmp int21_exit

;--------------------------------------------------------------------------
       int21_exit:
        ret

[/code]
Let me know if you want some code for your keyboard driver.
ASHLEY4.
ComputerPsi

RE:I was wondering if you can answer a few questions...

Post by ComputerPsi »

Nice code you have got there... But I already can set an interrupt without using dos services... Question - What is the difference between the interrupt and the driver? When interrupt 9 is called, the code would translate the information from port 60 and sent it to the right places of the OS, isn't that called a driver... and an interrupt?
ASHLEY4

RE:I was wondering if you can answer a few questions...

Post by ASHLEY4 »

Keyboard Basics

Your pressing a key - any key triggers a lot of events. A electrical switch is closed and electrons rush to the chip on your keyboard to inform it of the key press. The chip then sends a signal to the keyboard controller on your motherboard. The keyboard controller generates an IRQ 1, and urges the CPU to drop whatever its doing and take note of the keystroke. The CPU obliges immediately after processing any pending IRQ 0. When the CPU decides to process the IRQ 1, it causes an INT 9h. This is usually handled by the BIOS. The handler then reads I/O port 60h to retrieve the scancode of the pressed key. Then, it analyzes the keystroke and decides what to do with it. Once the BIOS is done with its task, it lets the CPU do whatever it was doing when it was interrupted. But wait... this is only for the key press... all these events have probably occurred so fast that your finger is still on the keyboard. In time which seems like forever in computer terms, you will release the key. This causes a similar sequence of events, and the BIOS now knows that the key's been released.


Now, the general idea is, that instead of letting the BIOS analyze the keystroke, your program gets to it first. You do this simply by replacing the BIOS INT 9h vector with your own! When it gets called, simply read the keyboard port 60h to get the keystroke!

Handling IRQs

An interrupt handler is like any other function, but for the following points:

It must terminate with an iret instruction instead of ret. This is taken care of by the compiler if you include the interrupt keyword in the function declaration.
It can't accept or return parameters, i.e. it must be declared like void interrupt fname (void)
An interrupt handler handling a hardware interrupt (i.e. and IRQ handler) must tell the PIC (Programmable Interrupt Controller) when if finished handling the interrupt, usually just before the handler function returns. You do this by writing 0x20 to port 0x20. In Borland C/C++ you do this with outportb (0x20, 0x20); Other compilers include similar functions.
;*************************************************************************************************************
Say you want to replace, the bios int 9h, for one you made,(as i thort you wanted to do )you would put its address in the IVT  and when a key was pressed that bit of code,would be run.
This is a example of one i made for a dos game.
Newint9                 PROC

                        PUSH     AX                        ; Push registers
                        PUSH     BX
                        PUSH     DS
                        ; CLI
                        MOV      AX,CS
                        MOV      DS,AX
                        IN       AL,60h
                        MOV      BX,AX
                        AND      BX,007Fh                  ; switch high bit of BX to zero
                        AND      AL,80h                    ; check high bit of port value
                        JZ       Press
Release:                                                   ; high bit = 1: "release" code
                        MOV      KeyDown[bx],00h           ; write 00 to "down" array element
                        JMP      Done
Press:                                                     ; high bit = 0: "press" code
                        MOV      KeyDown[bx],01h           ; write 01 to "down" array element
Done:
                        IN       AL,61h                    ; read port 61h, system ctrl port
                        MOV      AH,AL                     ; save value to AH
                        OR       AL,80h                    ; set top bit to "1" - reset kbd
                        OUT      61h,AL                    ; write out value to port
                        XCHG     AH,AL                     ; put original value back into AL
                        OUT      61h,AL                    ; rewrite original value in AL
                        MOV      AL,20h                    ; generate End of Interrupt
                        OUT      20h,AL
                        ;STI
                        POP      DS                        ; pop registers
                        POP      BX
                        POP      AX
            
                        IRET

Newint9                 ENDP

Note:  You do not after put your own in,you can stick with the bios in real-mode ,to start with .

ASHLEY4.
Post Reply