diff options
Diffstat (limited to 'src/keyboard.c')
| -rw-r--r-- | src/keyboard.c | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/src/keyboard.c b/src/keyboard.c new file mode 100644 index 0000000..987c7a2 --- /dev/null +++ b/src/keyboard.c @@ -0,0 +1,78 @@ +#include<stdbool.h> +#include<stddef.h> +#include<stdint.h> +#include"keyboard.h" + +#define BUFFER_SIZE 200 +char buffer[BUFFER_SIZE]; +size_t buffer_index=0; + +#define PIC1_COMMAND_PORT 0x20 +#define PIC1_DATA_PORT 0x21 +#define PIC2_COMMAND_PORT 0xA0 +#define PIC2_DATA_PORT 0xA1 +// IO Ports for Keyboard +#define KEYBOARD_DATA_PORT 0x60 +#define KEYBOARD_STATUS_PORT 0x64 + +extern char ioport_in(uint8_t port); +extern void ioport_out(uint8_t port, char data); + +void previous_field(); +void terminal_putchar(char c); +void tty(char *buffer); +void prompt(); + +void init_keyboard() +{ + // 0xFD = 1111 1101 in binary. enables only IRQ1 + // Why IRQ1? Remember, IRQ0 exists, it's 0-based + ioport_out(PIC1_DATA_PORT, 0xFD); +} + +void backspace() +{ + if(buffer_index<=0) return; + + previous_field(); + terminal_putchar(' '); + previous_field(); + buffer[--buffer_index]='\0'; + return; +} + +void enter() +{ + terminal_putchar('\n'); + if(buffer_index>0) + { + tty(buffer); + for(int i=0;i<BUFFER_SIZE;i++) buffer[i]='\0'; + buffer_index=0; + } + prompt(); + return; +} + +void handle_keyboard_interrupt() +{ + // Write end of interrupt (EOI) + ioport_out(PIC1_COMMAND_PORT, 0x20); + unsigned char status = ioport_in(KEYBOARD_STATUS_PORT); + + // Lowest bit of status will be set if buffer not empty + if (status & 0x1) + { + int16_t keycode = ioport_in(KEYBOARD_DATA_PORT); + if (keycode < 0 || keycode >= 128) return; + + if(keycode==14) backspace(); + else if(keycode==28) enter(); + else + { + buffer[buffer_index++]=keyboard[keycode]; + terminal_putchar(keyboard[keycode]); + } + + } +} |
