diff options
| author | Nic Gaffney <gaffney_nic@protonmail.com> | 2024-02-06 04:58:35 -0600 |
|---|---|---|
| committer | Nic Gaffney <gaffney_nic@protonmail.com> | 2024-02-06 04:58:35 -0600 |
| commit | ecf636f2797647d5dfc38a4562cae53fe275217d (patch) | |
| tree | c71d113c553821c2b949eb6a6cd67de5f2fce068 /src/kernel/keyboard | |
| parent | f1dee4bc58e4bfb97a1b41831c5d4fc327882991 (diff) | |
| download | gftos-ecf636f2797647d5dfc38a4562cae53fe275217d.tar.gz | |
Interrupts + basic keyboard driver
Diffstat (limited to 'src/kernel/keyboard')
| -rw-r--r-- | src/kernel/keyboard/compile_flags.txt | 1 | ||||
| -rw-r--r-- | src/kernel/keyboard/isr.c | 49 | ||||
| -rw-r--r-- | src/kernel/keyboard/isr_wrap.s | 8 | ||||
| -rw-r--r-- | src/kernel/keyboard/pic.c | 65 |
4 files changed, 123 insertions, 0 deletions
diff --git a/src/kernel/keyboard/compile_flags.txt b/src/kernel/keyboard/compile_flags.txt new file mode 100644 index 0000000..2af49c7 --- /dev/null +++ b/src/kernel/keyboard/compile_flags.txt @@ -0,0 +1 @@ +-I../../include/ diff --git a/src/kernel/keyboard/isr.c b/src/kernel/keyboard/isr.c new file mode 100644 index 0000000..223bf9f --- /dev/null +++ b/src/kernel/keyboard/isr.c @@ -0,0 +1,49 @@ +#include "asm.h" +#include "print.h" +#include "str.h" +#include <stdint.h> +static uint8_t shift_held = 0; +static uint8_t capslock = 0; + +void keyboard_handler() { + const char *scancodes = + "??1234567890-=?\tqwertyuiop[]\n?asdfghjkl;'`?\\zxcvbnm,./?*? "; + const char *SCANCODES = + "\?\?!@#$%^&*()_+?\tQWERTYUIOP{}\n?ASDFGHJKL:\"~?|ZXCVBNM<>??*? "; + + unsigned char sc = inb(0x60); + + uint8_t isheld = shift_held != 0; + char c = ((isheld | capslock) & !(isheld & capslock)) ? SCANCODES[sc] + : scancodes[sc]; + + if (capslock & (!isheld) && !isalpha(c)) + c = scancodes[sc]; + if (isheld && !isalpha(c)) + c = SCANCODES[sc]; + + if (sc < 0x59 && scancodes[sc] != '?') + printf("%c", c); + + switch (sc) { + case 0x2A: + shift_held |= 0b10; + break; + case 0x36: + shift_held |= 0b01; + break; + case 0xAA: + shift_held &= 0b01; + break; + case 0xB6: + shift_held &= 0b10; + break; + case 0x0E: + delete_char(); + break; + case 0x3A: + capslock = !capslock; + break; + } + outb(0x20, 0x20); +} diff --git a/src/kernel/keyboard/isr_wrap.s b/src/kernel/keyboard/isr_wrap.s new file mode 100644 index 0000000..6f6c58b --- /dev/null +++ b/src/kernel/keyboard/isr_wrap.s @@ -0,0 +1,8 @@ +extern keyboard_handler +extern wrap_keyboard_handler +wrap_keyboard_handler: + pushad + cld + call keyboard_handler + popad + iret diff --git a/src/kernel/keyboard/pic.c b/src/kernel/keyboard/pic.c index 0c81629..e1b4fb3 100644 --- a/src/kernel/keyboard/pic.c +++ b/src/kernel/keyboard/pic.c @@ -1 +1,66 @@ #include "asm.h" +#include <stdint.h> +#define PIC1 0x20 +#define PIC2 0xA0 +#define PIC1_COMMAND PIC1 +#define PIC1_DATA (PIC1 + 1) +#define PIC2_COMMAND PIC2 +#define PIC2_DATA (PIC2 + 1) + +void PIC_init(int offset1, int offset2) { + uint8_t a1, a2; + + a1 = inb(PIC1_DATA); + a2 = inb(PIC2_DATA); + + outb(PIC1_COMMAND, 0x11); // Init PIC1 + io_wait(); + outb(PIC2_COMMAND, 0x11); // Init PIC2 + io_wait(); + outb(PIC1_DATA, offset1); // ICW2: Master PIC vector offset + io_wait(); + outb(PIC2_DATA, offset2); // ICW2: Slave PIC vector offset + io_wait(); + outb(PIC1_DATA, 4); + io_wait(); + outb(PIC2_DATA, 2); + io_wait(); + outb(PIC1_DATA, 0x01); + io_wait(); + outb(PIC2_DATA, 0x01); + io_wait(); + + outb(PIC1_DATA, a1); // restore saved masks. + outb(PIC2_DATA, a2); +} + +void IRQ_mask(uint8_t line) { + uint16_t port = line < 8 ? PIC1_DATA : PIC2_DATA; + line = line > 8 ? line - 8 : line; + uint8_t val = inb(port) | (1 << line); + outb(port, val); +} + +void IRQ_unmask(uint8_t line) { + uint16_t port = line < 8 ? PIC1_DATA : PIC2_DATA; + line = line > 8 ? line - 8 : line; + uint8_t val = inb(port) & ~(1 << line); + outb(port, val); +} + +void PIC_disable(void) { + outb(PIC1_DATA, 0xff); + outb(PIC2_DATA, 0xff); +} + +uint16_t PIC_irr(void) { + outb(PIC1_COMMAND, 0x0a); + outb(PIC2_COMMAND, 0x0a); + return (inb(PIC2_COMMAND) << 8) | inb(PIC1_COMMAND); +} + +uint16_t PIC_isr(void) { + outb(PIC1_COMMAND, 0x0b); + outb(PIC2_COMMAND, 0x0b); + return (inb(PIC2_COMMAND) << 8) | inb(PIC1_COMMAND); +} |
