-
Notifications
You must be signed in to change notification settings - Fork 0
Completing the IDT (with IRQ)
randcode-generator edited this page Sep 14, 2014
·
4 revisions
To complete the IDT, we need to have handler for all interrupts. Interrupts from 0-31 are exceptions. Interrupts 32-47 are interrupt requests (IRQ) from hardware. For example, IRQ1 (interrupt 33) is triggered when a key is pressed.
- Remap the PIC so that the hardware interrupt requests (IRQ) starts at 32.
Reference (http://en.wikibooks.org/wiki/X86_Assembly/Programmable_Interrupt_Controller#Remapping)
mov al, 0x11
out 0x20, al
out 0xA0, al
mov al, 0x20
out 0x21, al
mov al, 0x28
out 0xA1, al
mov al, 0x04
out 0x21, al
mov al, 0x02
out 0xA1, al
mov al, 0x01
out 0x21, al
out 0xA1, al
mov al, 0x0
out 0x21, al
out 0xA1, al
- Create default exception interrupts. This is for interrupts 0-31
interrupt_default:
iret
- Create default interrupt requests for 32-39. Note that we have to send "End of Interrupt" (EOI) to the master PIC.
IRQ_32_39_interrupt_default:
mov al, 0x20 ; EOI command
out 0x20, al ; send to master
iret
- Create default interrupt requests for 40-47. Note that we have to send EOI to both master and slave PIC.
IRQ_40_47_interrupt_default:
mov al, 0x20 ; EOI command
out 0x20, al ; send to master
out 0xA0, al ; send to slave
iret
- Handle the keyboard interrupt (IRQ 1 or interrupt 33)
Create a table of keyscan. This is incomplete I only mapped a-z and space. Note that 0x90 represents keyup 'q'.
keyscan:
times 0x90 db 0
db 'q','w','e','r','t','y','u','i','o','p'
times 4 db 0
db 'a','s','d','f','g','h','j','k','l'
times 5 db 0
db 'z','x','c','v','b','n','m'
times 6 db 0
db ' '
Here is the interrupt handler (function) for interrupt 33. First, poll the status of the keyboard buffer. If the buffer is full, read the buffer, otherwise, keep polling. Anything less then 0x80 is keydown. Anything above 0x80 is keyup. So we only care about keyup, so we check if the value from the keyboard is greater than 0x80. If it is greater, output the character to screen. And finally send EOI.
interrupt33:
poll_status:
; bit 0 is the output buffer status
; 1 means buffer is full, can be read
; 0 means buffer is empty, don't read
mov eax, 0 ; set eax to 0
in al, 0x64 ; read status from keyboard
and al, 1 ; zero out all bits except first
cmp al, 1 ; compare bits
jne poll_status ; jump if not equal
in al, 0x60 ; read from buffer
mov cx, ax
cmp cx, 0x80 ; compare cx to 0x80
jl cont ; if cx is less then 0x80 go to cont
mov ebx, [VIDEO_MEMEORY] ; copy video memory to ebx
and eax, 0x00FF ; zero all bytes except the first
mov cl, [keyscan+eax] ; map the keyscan to ascii
mov byte[ebx], cl ; copy to video memory
mov cl, 15 ; set the character color to white
mov byte[ebx+1], cl ; copy to second byte of video memory
add word[VIDEO_MEMEORY], 2 ; add 2 to video memory variable
cont:
mov al, 0x20 ; EOI command
out 0x20, al ; send EOI command to master
iret
- Completed IDT
idt_info:
interrupt interrupt_default-starting+org
interrupt interrupt_default-starting+org
interrupt interrupt_default-starting+org
interrupt interrupt_default-starting+org
interrupt interrupt_default-starting+org
interrupt interrupt_default-starting+org
interrupt interrupt_default-starting+org
interrupt interrupt_default-starting+org
interrupt interrupt_default-starting+org
interrupt interrupt_default-starting+org
interrupt interrupt_default-starting+org
interrupt interrupt_default-starting+org
interrupt interrupt_default-starting+org
interrupt interrupt_default-starting+org
interrupt interrupt_default-starting+org
interrupt interrupt_default-starting+org
interrupt interrupt_default-starting+org
interrupt interrupt_default-starting+org
interrupt interrupt_default-starting+org
interrupt interrupt_default-starting+org
interrupt interrupt_default-starting+org
interrupt interrupt_default-starting+org
interrupt interrupt_default-starting+org
interrupt interrupt_default-starting+org
interrupt interrupt_default-starting+org
interrupt interrupt_default-starting+org
interrupt interrupt_default-starting+org
interrupt interrupt_default-starting+org
interrupt interrupt_default-starting+org
interrupt interrupt_default-starting+org
interrupt interrupt_default-starting+org
interrupt interrupt_default-starting+org
interrupt IRQ_32_39_interrupt_default-starting+org
interrupt interrupt33-starting+org
interrupt IRQ_32_39_interrupt_default-starting+org
interrupt IRQ_32_39_interrupt_default-starting+org
interrupt IRQ_32_39_interrupt_default-starting+org
interrupt IRQ_32_39_interrupt_default-starting+org
interrupt IRQ_32_39_interrupt_default-starting+org
interrupt IRQ_32_39_interrupt_default-starting+org
interrupt IRQ_40_47_interrupt_default-starting+org
interrupt IRQ_40_47_interrupt_default-starting+org
interrupt IRQ_40_47_interrupt_default-starting+org
interrupt IRQ_40_47_interrupt_default-starting+org
interrupt IRQ_40_47_interrupt_default-starting+org
interrupt IRQ_40_47_interrupt_default-starting+org
interrupt IRQ_40_47_interrupt_default-starting+org
idt_info_end:
Reference
https://github.com/randcode-generator/RandCodeOS/commit/f81eafb430572e43680fe1b3eb83fd713aa5ed84