Page 1 of 1
I was wondering if you can answer a few questions...
Posted: Wed Jul 28, 2004 11:00 pm
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...
RE:I was wondering if you can answer a few questions...
Posted: Wed Jul 28, 2004 11:00 pm
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
RE:I was wondering if you can answer a few questions...
Posted: Wed Jul 28, 2004 11:00 pm
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.
RE:I was wondering if you can answer a few questions...
Posted: Wed Jul 28, 2004 11:00 pm
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?
RE:I was wondering if you can answer a few questions...
Posted: Wed Jul 28, 2004 11:00 pm
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.
RE:I was wondering if you can answer a few questions...
Posted: Thu Jul 29, 2004 11:00 pm
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?
RE:I was wondering if you can answer a few questions...
Posted: Thu Jul 29, 2004 11:00 pm
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.