#include "keyboard.h" #include "portio.h" #include "irq.h" #include "types.h" #include "fileobj.h" #define BUFFER_SIZE 32 char kbd_buffer[BUFFER_SIZE]; char *buf_head, *buf_tail, *buf_start, *buf_end; int keyboard_read(struct file_object *fo, void *buf, size_t n); struct fops keyboard_fops = { .read = &keyboard_read, }; struct file_object keyboard_fo; unsigned char scancode; unsigned char e0; void keyb_out_wait() { while (inportb(KEYB_STATUS) & KEYB_STATUS_OBF) ; } void keyb_send_byte(unsigned char b) { outportb(KEYB_DATA, b); keyb_out_wait(); } void keyb_set_leds(unsigned char leds) { keyb_send_byte(KEYB_COMMAND_LEDS); keyb_send_byte(leds); } void keyboard_init() { e0 = 0; buf_start = (char *)&kbd_buffer; buf_end = (char *)((char *)(&kbd_buffer) + BUFFER_SIZE - 1); buf_head = buf_start; buf_tail = buf_end; fileobj_init(&keyboard_fo); keyboard_fo.fops = &keyboard_fops; devfs_register_device("kbd", &keyboard_fo); } int keyboard_read(struct file_object *fo, void *buf, size_t n) { char *p = buf; for (; n; n--, p++) { while ( (buf_head == buf_start && buf_tail == buf_end) || (buf_tail == buf_head - 1) ) { kernel_yield(); } *p = *buf_tail++; if (buf_tail > buf_end) { buf_tail = buf_start; } } } // Keyboard ISR void interrupt_33() { unsigned char b = inportb(KEYB_DATA); if (!( (buf_head == buf_end && buf_tail == buf_start) || (buf_head == buf_tail - 1) )) { if (e0) { // printf(" KBD: e0 %x\n", b); e0 = 0; } else if (b == 0xE0) { e0 = 1; } else { // printf(" KBD: %x\n", b); } *buf_head++ = b; if (buf_head > buf_end) { buf_head = buf_start; } } else { printf(" KBD: Keyboard buffer full\n"); } ACK_MASTER_IRQ; }