From 6e5a09981a6b6fb482aa58ee1bfe5dcfb75e601a Mon Sep 17 00:00:00 2001 From: Carlos Date: Fri, 20 Mar 2015 11:39:30 +0100 Subject: [PATCH] lesson 20, keyboard --- 20-interrupts-timer/README.md | 18 +- 20-interrupts-timer/cpu/idt.c | 18 +- 20-interrupts-timer/cpu/idt.h | 40 +-- 20-interrupts-timer/cpu/interrupt.asm | 426 +------------------------ 20-interrupts-timer/cpu/isr.c | 141 +------- 20-interrupts-timer/cpu/isr.h | 89 +----- 20-interrupts-timer/cpu/types.h | 17 +- 20-interrupts-timer/drivers/keyboard.c | 208 ++++++++++++ 20-interrupts-timer/drivers/keyboard.h | 3 + 20-interrupts-timer/kernel/kernel.c | 6 +- 10 files changed, 239 insertions(+), 727 deletions(-) mode change 100644 => 120000 20-interrupts-timer/cpu/idt.c mode change 100644 => 120000 20-interrupts-timer/cpu/idt.h mode change 100644 => 120000 20-interrupts-timer/cpu/interrupt.asm mode change 100644 => 120000 20-interrupts-timer/cpu/isr.c mode change 100644 => 120000 20-interrupts-timer/cpu/isr.h mode change 100644 => 120000 20-interrupts-timer/cpu/types.h create mode 100644 20-interrupts-timer/drivers/keyboard.c create mode 100644 20-interrupts-timer/drivers/keyboard.h diff --git a/20-interrupts-timer/README.md b/20-interrupts-timer/README.md index ec77e8a..fbc05e9 100644 --- a/20-interrupts-timer/README.md +++ b/20-interrupts-timer/README.md @@ -1,4 +1,4 @@ -*Concepts you may want to Google beforehand: CPU timer, keyboard interrupts* +*Concepts you may want to Google beforehand: CPU timer, keyboard interrupts, scancode* **Goal: Implement our first IRQ handlers: the CPU timer and the keyboard** @@ -18,3 +18,19 @@ Finally, go back to the `kernel/kernel.c` and do two things. Enable interrupts a (very important!) and then initialize the timer interrupt. Go `make run` and you'll see the clock ticking! + + +Keyboard +-------- + +The keyboard is even easier, with a drawback. The PIC does not send us the ASCII code +for the pressed key, but the scancode for the key-down and the key-up events, so we +will need to translate those. + +Check out `drivers/keyboard.c` where there are two functions: the callback and +the initialization which configures the interrupt callback. A new `keyboard.h` was +created with the definitions. + +`keyboard.c` also has a long table to translate scancodes to ASCII keys. For the time +being, we will only implement a simple subset of the US keyboard. You can read +more [about scancodes here](http://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html) diff --git a/20-interrupts-timer/cpu/idt.c b/20-interrupts-timer/cpu/idt.c deleted file mode 100644 index 999d0c9..0000000 --- a/20-interrupts-timer/cpu/idt.c +++ /dev/null @@ -1,17 +0,0 @@ -#include "idt.h" -#include "../kernel/util.h" - -void set_idt_gate(int n, u32 handler) { - idt[n].low_offset = low_16(handler); - idt[n].sel = KERNEL_CS; - idt[n].always0 = 0; - idt[n].flags = 0x8E; - idt[n].high_offset = high_16(handler); -} - -void set_idt() { - idt_reg.base = (u32) &idt; - idt_reg.limit = IDT_ENTRIES * sizeof(idt_gate_t) - 1; - /* Don't make the mistake of loading &idt -- always load &idt_reg */ - __asm__ __volatile__("lidtl (%0)" : : "r" (&idt_reg)); -} diff --git a/20-interrupts-timer/cpu/idt.c b/20-interrupts-timer/cpu/idt.c new file mode 120000 index 0000000..df3be06 --- /dev/null +++ b/20-interrupts-timer/cpu/idt.c @@ -0,0 +1 @@ +../../19-interrupts-irqs/cpu/idt.c \ No newline at end of file diff --git a/20-interrupts-timer/cpu/idt.h b/20-interrupts-timer/cpu/idt.h deleted file mode 100644 index 27bfac5..0000000 --- a/20-interrupts-timer/cpu/idt.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef IDT_H -#define IDT_H - -#include "types.h" - -/* Segment selectors */ -#define KERNEL_CS 0x08 - -/* How every interrupt gate (handler) is defined */ -typedef struct { - u16 low_offset; /* Lower 16 bits of handler function address */ - u16 sel; /* Kernel segment selector */ - u8 always0; - /* First byte - * Bit 7: "Interrupt is present" - * Bits 6-5: Privilege level of caller (0=kernel..3=user) - * Bit 4: Set to 0 for interrupt gates - * Bits 3-0: bits 1110 = decimal 14 = "32 bit interrupt gate" */ - u8 flags; - u16 high_offset; /* Higher 16 bits of handler function address */ -} __attribute__((packed)) idt_gate_t ; - -/* A pointer to the array of interrupt handlers. - * Assembly instruction 'lidt' will read it */ -typedef struct { - u16 limit; - u32 base; -} __attribute__((packed)) idt_register_t; - -#define IDT_ENTRIES 256 -idt_gate_t idt[IDT_ENTRIES]; -idt_register_t idt_reg; - - -/* Functions implemented in idt.c */ -void set_idt_gate(int n, u32 handler); -void set_idt(); - -#endif diff --git a/20-interrupts-timer/cpu/idt.h b/20-interrupts-timer/cpu/idt.h new file mode 120000 index 0000000..c828d84 --- /dev/null +++ b/20-interrupts-timer/cpu/idt.h @@ -0,0 +1 @@ +../../19-interrupts-irqs/cpu/idt.h \ No newline at end of file diff --git a/20-interrupts-timer/cpu/interrupt.asm b/20-interrupts-timer/cpu/interrupt.asm deleted file mode 100644 index bf83b7a..0000000 --- a/20-interrupts-timer/cpu/interrupt.asm +++ /dev/null @@ -1,425 +0,0 @@ -; Defined in isr.c -[extern isr_handler] -[extern irq_handler] - -; Common ISR code -isr_common_stub: - ; 1. Save CPU state - pusha ; Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax - mov ax, ds ; Lower 16-bits of eax = ds. - push eax ; save the data segment descriptor - mov ax, 0x10 ; kernel data segment descriptor - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - - ; 2. Call C handler - call isr_handler - - ; 3. Restore state - pop eax - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - popa - add esp, 8 ; Cleans up the pushed error code and pushed ISR number - sti - iret ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP - -; Common IRQ code. Identical to ISR code except for the 'call' -; and the 'pop ebx' -irq_common_stub: - pusha - mov ax, ds - push eax - mov ax, 0x10 - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - call irq_handler ; Different than the ISR code - pop ebx ; Different than the ISR code - mov ds, bx - mov es, bx - mov fs, bx - mov gs, bx - popa - add esp, 8 - sti - iret - -; We don't get information about which interrupt was caller -; when the handler is run, so we will need to have a different handler -; for every interrupt. -; Furthermore, some interrupts push an error code onto the stack but others -; don't, so we will push a dummy error code for those which don't, so that -; we have a consistent stack for all of them. - -; First make the ISRs global -global isr0 -global isr1 -global isr2 -global isr3 -global isr4 -global isr5 -global isr6 -global isr7 -global isr8 -global isr9 -global isr10 -global isr11 -global isr12 -global isr13 -global isr14 -global isr15 -global isr16 -global isr17 -global isr18 -global isr19 -global isr20 -global isr21 -global isr22 -global isr23 -global isr24 -global isr25 -global isr26 -global isr27 -global isr28 -global isr29 -global isr30 -global isr31 -; IRQs -global irq0 -global irq1 -global irq2 -global irq3 -global irq4 -global irq5 -global irq6 -global irq7 -global irq8 -global irq9 -global irq10 -global irq11 -global irq12 -global irq13 -global irq14 -global irq15 - -; 0: Divide By Zero Exception -isr0: - cli - push byte 0 - push byte 0 - jmp isr_common_stub - -; 1: Debug Exception -isr1: - cli - push byte 0 - push byte 1 - jmp isr_common_stub - -; 2: Non Maskable Interrupt Exception -isr2: - cli - push byte 0 - push byte 2 - jmp isr_common_stub - -; 3: Int 3 Exception -isr3: - cli - push byte 0 - push byte 3 - jmp isr_common_stub - -; 4: INTO Exception -isr4: - cli - push byte 0 - push byte 4 - jmp isr_common_stub - -; 5: Out of Bounds Exception -isr5: - cli - push byte 0 - push byte 5 - jmp isr_common_stub - -; 6: Invalid Opcode Exception -isr6: - cli - push byte 0 - push byte 6 - jmp isr_common_stub - -; 7: Coprocessor Not Available Exception -isr7: - cli - push byte 0 - push byte 7 - jmp isr_common_stub - -; 8: Double Fault Exception (With Error Code!) -isr8: - cli - push byte 8 - jmp isr_common_stub - -; 9: Coprocessor Segment Overrun Exception -isr9: - cli - push byte 0 - push byte 9 - jmp isr_common_stub - -; 10: Bad TSS Exception (With Error Code!) -isr10: - cli - push byte 10 - jmp isr_common_stub - -; 11: Segment Not Present Exception (With Error Code!) -isr11: - cli - push byte 11 - jmp isr_common_stub - -; 12: Stack Fault Exception (With Error Code!) -isr12: - cli - push byte 12 - jmp isr_common_stub - -; 13: General Protection Fault Exception (With Error Code!) -isr13: - cli - push byte 13 - jmp isr_common_stub - -; 14: Page Fault Exception (With Error Code!) -isr14: - cli - push byte 14 - jmp isr_common_stub - -; 15: Reserved Exception -isr15: - cli - push byte 0 - push byte 15 - jmp isr_common_stub - -; 16: Floating Point Exception -isr16: - cli - push byte 0 - push byte 16 - jmp isr_common_stub - -; 17: Alignment Check Exception -isr17: - cli - push byte 0 - push byte 17 - jmp isr_common_stub - -; 18: Machine Check Exception -isr18: - cli - push byte 0 - push byte 18 - jmp isr_common_stub - -; 19: Reserved -isr19: - cli - push byte 0 - push byte 19 - jmp isr_common_stub - -; 20: Reserved -isr20: - cli - push byte 0 - push byte 20 - jmp isr_common_stub - -; 21: Reserved -isr21: - cli - push byte 0 - push byte 21 - jmp isr_common_stub - -; 22: Reserved -isr22: - cli - push byte 0 - push byte 22 - jmp isr_common_stub - -; 23: Reserved -isr23: - cli - push byte 0 - push byte 23 - jmp isr_common_stub - -; 24: Reserved -isr24: - cli - push byte 0 - push byte 24 - jmp isr_common_stub - -; 25: Reserved -isr25: - cli - push byte 0 - push byte 25 - jmp isr_common_stub - -; 26: Reserved -isr26: - cli - push byte 0 - push byte 26 - jmp isr_common_stub - -; 27: Reserved -isr27: - cli - push byte 0 - push byte 27 - jmp isr_common_stub - -; 28: Reserved -isr28: - cli - push byte 0 - push byte 28 - jmp isr_common_stub - -; 29: Reserved -isr29: - cli - push byte 0 - push byte 29 - jmp isr_common_stub - -; 30: Reserved -isr30: - cli - push byte 0 - push byte 30 - jmp isr_common_stub - -; 31: Reserved -isr31: - cli - push byte 0 - push byte 31 - jmp isr_common_stub - -; IRQ handlers -irq0: - cli - push byte 0 - push byte 32 - jmp irq_common_stub - -irq1: - cli - push byte 1 - push byte 33 - jmp irq_common_stub - -irq2: - cli - push byte 2 - push byte 34 - jmp irq_common_stub - -irq3: - cli - push byte 3 - push byte 35 - jmp irq_common_stub - -irq4: - cli - push byte 4 - push byte 36 - jmp irq_common_stub - -irq5: - cli - push byte 5 - push byte 37 - jmp irq_common_stub - -irq6: - cli - push byte 6 - push byte 38 - jmp irq_common_stub - -irq7: - cli - push byte 7 - push byte 39 - jmp irq_common_stub - -irq8: - cli - push byte 8 - push byte 40 - jmp irq_common_stub - -irq9: - cli - push byte 9 - push byte 41 - jmp irq_common_stub - -irq10: - cli - push byte 10 - push byte 42 - jmp irq_common_stub - -irq11: - cli - push byte 11 - push byte 43 - jmp irq_common_stub - -irq12: - cli - push byte 12 - push byte 44 - jmp irq_common_stub - -irq13: - cli - push byte 13 - push byte 45 - jmp irq_common_stub - -irq14: - cli - push byte 14 - push byte 46 - jmp irq_common_stub - -irq15: - cli - push byte 15 - push byte 47 - jmp irq_common_stub - diff --git a/20-interrupts-timer/cpu/interrupt.asm b/20-interrupts-timer/cpu/interrupt.asm new file mode 120000 index 0000000..2ed6b8a --- /dev/null +++ b/20-interrupts-timer/cpu/interrupt.asm @@ -0,0 +1 @@ +../../19-interrupts-irqs/cpu/interrupt.asm \ No newline at end of file diff --git a/20-interrupts-timer/cpu/isr.c b/20-interrupts-timer/cpu/isr.c deleted file mode 100644 index 4687c24..0000000 --- a/20-interrupts-timer/cpu/isr.c +++ /dev/null @@ -1,140 +0,0 @@ -#include "isr.h" -#include "idt.h" -#include "../drivers/screen.h" -#include "../kernel/util.h" -#include "../drivers/ports.h" - -isr_t interrupt_handlers[256]; - -/* Can't do this with a loop because we need the address - * of the function names */ -void isr_install() { - set_idt_gate(0, (u32)isr0); - set_idt_gate(1, (u32)isr1); - set_idt_gate(2, (u32)isr2); - set_idt_gate(3, (u32)isr3); - set_idt_gate(4, (u32)isr4); - set_idt_gate(5, (u32)isr5); - set_idt_gate(6, (u32)isr6); - set_idt_gate(7, (u32)isr7); - set_idt_gate(8, (u32)isr8); - set_idt_gate(9, (u32)isr9); - set_idt_gate(10, (u32)isr10); - set_idt_gate(11, (u32)isr11); - set_idt_gate(12, (u32)isr12); - set_idt_gate(13, (u32)isr13); - set_idt_gate(14, (u32)isr14); - set_idt_gate(15, (u32)isr15); - set_idt_gate(16, (u32)isr16); - set_idt_gate(17, (u32)isr17); - set_idt_gate(18, (u32)isr18); - set_idt_gate(19, (u32)isr19); - set_idt_gate(20, (u32)isr20); - set_idt_gate(21, (u32)isr21); - set_idt_gate(22, (u32)isr22); - set_idt_gate(23, (u32)isr23); - set_idt_gate(24, (u32)isr24); - set_idt_gate(25, (u32)isr25); - set_idt_gate(26, (u32)isr26); - set_idt_gate(27, (u32)isr27); - set_idt_gate(28, (u32)isr28); - set_idt_gate(29, (u32)isr29); - set_idt_gate(30, (u32)isr30); - set_idt_gate(31, (u32)isr31); - - // Remap the PIC - port_byte_out(0x20, 0x11); - port_byte_out(0xA0, 0x11); - port_byte_out(0x21, 0x20); - port_byte_out(0xA1, 0x28); - port_byte_out(0x21, 0x04); - port_byte_out(0xA1, 0x02); - port_byte_out(0x21, 0x01); - port_byte_out(0xA1, 0x01); - port_byte_out(0x21, 0x0); - port_byte_out(0xA1, 0x0); - - // Install the IRQs - set_idt_gate(32, (u32)irq0); - set_idt_gate(33, (u32)irq1); - set_idt_gate(34, (u32)irq2); - set_idt_gate(35, (u32)irq3); - set_idt_gate(36, (u32)irq4); - set_idt_gate(37, (u32)irq5); - set_idt_gate(38, (u32)irq6); - set_idt_gate(39, (u32)irq7); - set_idt_gate(40, (u32)irq8); - set_idt_gate(41, (u32)irq9); - set_idt_gate(42, (u32)irq10); - set_idt_gate(43, (u32)irq11); - set_idt_gate(44, (u32)irq12); - set_idt_gate(45, (u32)irq13); - set_idt_gate(46, (u32)irq14); - set_idt_gate(47, (u32)irq15); - - set_idt(); // Load with ASM -} - -/* To print the message which defines every exception */ -char *exception_messages[] = { - "Division By Zero", - "Debug", - "Non Maskable Interrupt", - "Breakpoint", - "Into Detected Overflow", - "Out of Bounds", - "Invalid Opcode", - "No Coprocessor", - - "Double Fault", - "Coprocessor Segment Overrun", - "Bad TSS", - "Segment Not Present", - "Stack Fault", - "General Protection Fault", - "Page Fault", - "Unknown Interrupt", - - "Coprocessor Fault", - "Alignment Check", - "Machine Check", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved" -}; - -void isr_handler(registers_t r) { - kprint("received interrupt: "); - char s[3]; - int_to_ascii(r.int_no, s); - kprint(s); - kprint("\n"); - kprint(exception_messages[r.int_no]); - kprint("\n"); -} - -void register_interrupt_handler(u8 n, isr_t handler) { - interrupt_handlers[n] = handler; -} - -void irq_handler(registers_t r) { - /* If the irq involves the slave (IRQ > 7), send an EOI to it */ - if (r.int_no >= 40) port_byte_out(0xA0, 0x20); - port_byte_out(0x20, 0x20); /* Send EOI to master */ - /* Handle the interrupt in a more modular way */ - if (interrupt_handlers[r.int_no] != 0) { - isr_t handler = interrupt_handlers[r.int_no]; - handler(r); - } -} diff --git a/20-interrupts-timer/cpu/isr.c b/20-interrupts-timer/cpu/isr.c new file mode 120000 index 0000000..348fd8e --- /dev/null +++ b/20-interrupts-timer/cpu/isr.c @@ -0,0 +1 @@ +../../19-interrupts-irqs/cpu/isr.c \ No newline at end of file diff --git a/20-interrupts-timer/cpu/isr.h b/20-interrupts-timer/cpu/isr.h deleted file mode 100644 index 6673ca7..0000000 --- a/20-interrupts-timer/cpu/isr.h +++ /dev/null @@ -1,88 +0,0 @@ -#ifndef ISR_H -#define ISR_H - -#include "types.h" - -/* ISRs reserved for CPU exceptions */ -extern void isr0(); -extern void isr1(); -extern void isr2(); -extern void isr3(); -extern void isr4(); -extern void isr5(); -extern void isr6(); -extern void isr7(); -extern void isr8(); -extern void isr9(); -extern void isr10(); -extern void isr11(); -extern void isr12(); -extern void isr13(); -extern void isr14(); -extern void isr15(); -extern void isr16(); -extern void isr17(); -extern void isr18(); -extern void isr19(); -extern void isr20(); -extern void isr21(); -extern void isr22(); -extern void isr23(); -extern void isr24(); -extern void isr25(); -extern void isr26(); -extern void isr27(); -extern void isr28(); -extern void isr29(); -extern void isr30(); -extern void isr31(); -/* IRQ definitions */ -extern void irq0(); -extern void irq1(); -extern void irq2(); -extern void irq3(); -extern void irq4(); -extern void irq5(); -extern void irq6(); -extern void irq7(); -extern void irq8(); -extern void irq9(); -extern void irq10(); -extern void irq11(); -extern void irq12(); -extern void irq13(); -extern void irq14(); -extern void irq15(); - -#define IRQ0 32 -#define IRQ1 33 -#define IRQ2 34 -#define IRQ3 35 -#define IRQ4 36 -#define IRQ5 37 -#define IRQ6 38 -#define IRQ7 39 -#define IRQ8 40 -#define IRQ9 41 -#define IRQ10 42 -#define IRQ11 43 -#define IRQ12 44 -#define IRQ13 45 -#define IRQ14 46 -#define IRQ15 47 - -/* Struct which aggregates many registers */ -typedef struct { - u32 ds; /* Data segment selector */ - u32 edi, esi, ebp, esp, ebx, edx, ecx, eax; /* Pushed by pusha. */ - u32 int_no, err_code; /* Interrupt number and error code (if applicable) */ - u32 eip, cs, eflags, useresp, ss; /* Pushed by the processor automatically */ -} registers_t; - -void isr_install(); -void isr_handler(registers_t r); - -typedef void (*isr_t)(registers_t); -void register_interrupt_handler(u8 n, isr_t handler); - -#endif diff --git a/20-interrupts-timer/cpu/isr.h b/20-interrupts-timer/cpu/isr.h new file mode 120000 index 0000000..4d037d6 --- /dev/null +++ b/20-interrupts-timer/cpu/isr.h @@ -0,0 +1 @@ +../../19-interrupts-irqs/cpu/isr.h \ No newline at end of file diff --git a/20-interrupts-timer/cpu/types.h b/20-interrupts-timer/cpu/types.h deleted file mode 100644 index 992a502..0000000 --- a/20-interrupts-timer/cpu/types.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef TYPES_H -#define TYPES_H - -/* Instead of using 'chars' to allocate non-character bytes, - * we will use these new type with no semantic meaning */ -typedef unsigned int u32; -typedef int s32; -typedef unsigned short u16; -typedef short s16; -typedef unsigned char u8; -typedef char s8; - -#define low_16(address) (u16)((address) & 0xFFFF) -#define high_16(address) (u16)(((address) >> 16) & 0xFFFF) - -#endif diff --git a/20-interrupts-timer/cpu/types.h b/20-interrupts-timer/cpu/types.h new file mode 120000 index 0000000..2a539c0 --- /dev/null +++ b/20-interrupts-timer/cpu/types.h @@ -0,0 +1 @@ +../../19-interrupts-irqs/cpu/types.h \ No newline at end of file diff --git a/20-interrupts-timer/drivers/keyboard.c b/20-interrupts-timer/drivers/keyboard.c new file mode 100644 index 0000000..c8fd3a3 --- /dev/null +++ b/20-interrupts-timer/drivers/keyboard.c @@ -0,0 +1,208 @@ +#include "keyboard.h" +#include "ports.h" +#include "../cpu/isr.h" +#include "screen.h" + +static void keyboard_callback(registers_t regs) { + /* The PIC leaves us the scancode in port 0x60 */ + u8 scancode = port_byte_in(0x60); + char *sc_ascii; + int_to_ascii(scancode, sc_ascii); + kprint("Keyboard scancode: "); + kprint(sc_ascii); + kprint(", "); + print_letter(scancode); + kprint("\n"); +} + +void init_keyboard() { + register_interrupt_handler(IRQ1, keyboard_callback); +} + +void print_letter(u8 scancode) { + switch (scancode) { + case 0x0: + kprint("ERROR"); + break; + case 0x1: + kprint("ESC"); + break; + case 0x2: + kprint("1"); + break; + case 0x3: + kprint("2"); + break; + case 0x4: + kprint("3"); + break; + case 0x5: + kprint("4"); + break; + case 0x6: + kprint("5"); + break; + case 0x7: + kprint("6"); + break; + case 0x8: + kprint("7"); + break; + case 0x9: + kprint("8"); + break; + case 0x0A: + kprint("9"); + break; + case 0x0B: + kprint("0"); + break; + case 0x0C: + kprint("-"); + break; + case 0x0D: + kprint("+"); + break; + case 0x0E: + kprint("Backspace"); + break; + case 0x0F: + kprint("Tab"); + break; + case 0x10: + kprint("Q"); + break; + case 0x11: + kprint("W"); + break; + case 0x12: + kprint("E"); + break; + case 0x13: + kprint("R"); + break; + case 0x14: + kprint("T"); + break; + case 0x15: + kprint("Y"); + break; + case 0x16: + kprint("U"); + break; + case 0x17: + kprint("I"); + break; + case 0x18: + kprint("O"); + break; + case 0x19: + kprint("P"); + break; + case 0x1A: + kprint("["); + break; + case 0x1B: + kprint("]"); + break; + case 0x1C: + kprint("ENTER"); + break; + case 0x1D: + kprint("LCtrl"); + break; + case 0x1E: + kprint("A"); + break; + case 0x1F: + kprint("S"); + break; + case 0x20: + kprint("D"); + break; + case 0x21: + kprint("F"); + break; + case 0x22: + kprint("G"); + break; + case 0x23: + kprint("H"); + break; + case 0x24: + kprint("J"); + break; + case 0x25: + kprint("K"); + break; + case 0x26: + kprint("L"); + break; + case 0x27: + kprint(";"); + break; + case 0x28: + kprint("'"); + break; + case 0x29: + kprint("`"); + break; + case 0x2A: + kprint("LShift"); + break; + case 0x2B: + kprint("\\"); + break; + case 0x2C: + kprint("Z"); + break; + case 0x2D: + kprint("X"); + break; + case 0x2E: + kprint("C"); + break; + case 0x2F: + kprint("V"); + break; + case 0x30: + kprint("B"); + break; + case 0x31: + kprint("N"); + break; + case 0x32: + kprint("M"); + break; + case 0x33: + kprint(","); + break; + case 0x34: + kprint("."); + break; + case 0x35: + kprint("/"); + break; + case 0x36: + kprint("Rshift"); + break; + case 0x37: + kprint("Keypad *"); + break; + case 0x38: + kprint("LAlt"); + break; + case 0x39: + kprint("Spc"); + break; + default: + /* 'keuyp' event corresponds to the 'keydown' + 0x80 + * it may still be a scancode we haven't implemented yet */ + if (scancode - 0x80 <= 0x39) { + kprint("key up "); + print_letter(scancode - 0x80); + } else kprint("Unknown"); + break; + } +} + diff --git a/20-interrupts-timer/drivers/keyboard.h b/20-interrupts-timer/drivers/keyboard.h new file mode 100644 index 0000000..ad4fc66 --- /dev/null +++ b/20-interrupts-timer/drivers/keyboard.h @@ -0,0 +1,3 @@ +#include "../cpu/types.h" + +void init_keyboard(); diff --git a/20-interrupts-timer/kernel/kernel.c b/20-interrupts-timer/kernel/kernel.c index fba228a..70a1d13 100644 --- a/20-interrupts-timer/kernel/kernel.c +++ b/20-interrupts-timer/kernel/kernel.c @@ -1,9 +1,13 @@ #include "../cpu/isr.h" #include "../cpu/timer.h" +#include "../drivers/keyboard.h" void main() { isr_install(); asm volatile("sti"); - init_timer(50); +// init_timer(50); + /* Comment out the timer IRQ handler to read + * the keyboard IRQs easier */ + init_keyboard(); }