Added IRQs and little refactor :3
This commit is contained in:
parent
cac521ded0
commit
ddb45b819b
9
Makefile
9
Makefile
|
@ -22,14 +22,17 @@ KERNEL_OBJS=\
|
|||
kernel/kernel.o \
|
||||
kernel/debugging.o \
|
||||
kernel/elf.o \
|
||||
kernel/keyboard.o \
|
||||
|
||||
LIB_OBJS=\
|
||||
$(ARCHDIR)/bootstrap.o \
|
||||
$(ARCHDIR)/tty.o \
|
||||
$(ARCHDIR)/strlib.o \
|
||||
$(ARCHDIR)/idt.o \
|
||||
$(ARCHDIR)/interrupt.o \
|
||||
$(ARCHDIR)/interrupts/idt.o \
|
||||
$(ARCHDIR)/interrupts/interrupt.o \
|
||||
$(ARCHDIR)/gdt.o \
|
||||
$(ARCHDIR)/userland.o \
|
||||
$(ARCHDIR)/interrupts/pic.o \
|
||||
|
||||
OBJS=$(KERNEL_OBJS) $(LIB_OBJS)
|
||||
|
||||
|
@ -50,7 +53,7 @@ clean:
|
|||
rm -f myos.iso
|
||||
rm -f isodir/boot/myos.kernel
|
||||
|
||||
$(ARCHDIR)/interrupt.o: CFLAGS += -mgeneral-regs-only
|
||||
$(ARCHDIR)/interrupts/interrupt.o: CFLAGS += -mgeneral-regs-only
|
||||
# kernel/elf.o: CFLAGS += -masm=intel
|
||||
|
||||
%.o : %.c
|
||||
|
|
|
@ -4,7 +4,16 @@
|
|||
#include "interrupt.h"
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "io.h"
|
||||
#include "../io.h"
|
||||
|
||||
#define IRQ0 0x20
|
||||
#define IRQ1 (IRQ0 + 1)
|
||||
#define IRQ2 (IRQ0 + 2)
|
||||
#define IRQ3 (IRQ0 + 3)
|
||||
#define IRQ4 (IRQ0 + 4)
|
||||
#define IRQ5 (IRQ0 + 5)
|
||||
#define IRQ6 (IRQ0 + 6)
|
||||
#define IRQ7 (IRQ0 + 7)
|
||||
|
||||
#define NUM_ENTRIES 0x100
|
||||
|
||||
|
@ -104,7 +113,6 @@ struct InterruptDescriptor generate_entry(bool present, void isr(struct interrup
|
|||
|
||||
void idt_init()
|
||||
{
|
||||
terminal_initialize();
|
||||
struct InterruptDescriptor entry;
|
||||
|
||||
entry = generate_entry(true, exception, 0xF, 0, 0x8);
|
||||
|
@ -122,18 +130,20 @@ void idt_init()
|
|||
entry = generate_entry(true, double_fault, 0xF, 0, 0x8);
|
||||
add_entry(entry, DoubleFault);
|
||||
|
||||
outb(0x21,0x20); // Tell the PIC to use interrupts 0x20 - 0x27
|
||||
entry = generate_entry(true, irq, 0xE, 0, 0x8);
|
||||
for (int i = 0x20; i < 0x28; i++)
|
||||
for (int i = IRQ0; i <= IRQ7; i++)
|
||||
{
|
||||
add_entry(entry, i);
|
||||
}
|
||||
|
||||
entry = generate_entry(true, keyboard_interrupt, 0xE, 0, 0x8);
|
||||
add_entry(entry, IRQ1);
|
||||
|
||||
struct InterruptDescriptor print_entry;
|
||||
print_entry.present = true;
|
||||
print_entry.offset = (uint32_t)print;
|
||||
print_entry.gate_type = 0xE;
|
||||
print_entry.ring = 0;
|
||||
print_entry.ring = 3;
|
||||
print_entry.selector = 0x8;
|
||||
|
||||
add_entry(print_entry, 0x80);
|
||||
|
@ -142,7 +152,7 @@ void idt_init()
|
|||
input_entry.present = true;
|
||||
input_entry.offset = (uint32_t)input;
|
||||
input_entry.gate_type = 0xE;
|
||||
input_entry.ring = 0;
|
||||
input_entry.ring = 3;
|
||||
input_entry.selector = 0x8;
|
||||
|
||||
add_entry(input_entry, 0x81);
|
|
@ -1,7 +1,8 @@
|
|||
#include <kernel/tty.h>
|
||||
#include <stddef.h>
|
||||
#include <debugging.h>
|
||||
#include "io.h"
|
||||
#include <kernel/keyboard.h>
|
||||
#include "../io.h"
|
||||
|
||||
struct interrupt_frame {
|
||||
uint32_t eflags;
|
||||
|
@ -45,38 +46,14 @@ __attribute__((interrupt)) void double_fault(struct interrupt_frame* frame)
|
|||
__attribute__((interrupt)) void exception(struct interrupt_frame* frame)
|
||||
{
|
||||
terminal_writestring("Some weird error code stuff\n");
|
||||
/* terminal_writestring("Error code:\n");
|
||||
print_hex_bytes(frame, sizeof(frame));
|
||||
terminal_putchar('\n'); */
|
||||
while (1) { }
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) void print(struct interrupt_frame* frame)
|
||||
{
|
||||
/* terminal_initialize();
|
||||
terminal_putchar(test);
|
||||
test++; */
|
||||
|
||||
char* start;
|
||||
asm("mov %%edx, %0" : "=r" (start));
|
||||
terminal_writestring(start);
|
||||
|
||||
/* uint8_t* stack;
|
||||
asm("mov %%esp, %0" : "=r" (stack));
|
||||
|
||||
terminal_writestring("\nSTACK:\n");
|
||||
print_hex_bytes(stack - 24, 4);
|
||||
terminal_putchar('\n');
|
||||
print_hex_bytes(stack - 20, 4);
|
||||
terminal_putchar('\n');
|
||||
print_hex_bytes(stack - 16, 4);
|
||||
terminal_putchar('\n');
|
||||
print_hex_bytes(stack - 12, 4);
|
||||
terminal_putchar('\n');
|
||||
print_hex_bytes(stack - 8, 4);
|
||||
terminal_putchar('\n');
|
||||
print_hex_bytes(stack - 4, 4);
|
||||
terminal_putchar('\n'); */
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) void input(struct interrupt_frame* frame)
|
||||
|
@ -84,7 +61,7 @@ __attribute__((interrupt)) void input(struct interrupt_frame* frame)
|
|||
char* buffer;
|
||||
asm("mov %%edx, %0" : "=r" (buffer));
|
||||
|
||||
size_t index = 0;
|
||||
/* size_t index = 0;
|
||||
|
||||
char current_character = get_last_key_pressed();
|
||||
while (current_character != '\n') {
|
||||
|
@ -96,12 +73,18 @@ __attribute__((interrupt)) void input(struct interrupt_frame* frame)
|
|||
}
|
||||
current_character = tmp;
|
||||
}
|
||||
buffer[index] = '\0';
|
||||
buffer[index] = '\0'; */
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) void keyboard_interrupt(struct interrupt_frame* frame)
|
||||
{
|
||||
uint8_t scancode = inb(0x60);
|
||||
handle_keyboard(scancode);
|
||||
outb(0x20, 0x20);
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) void irq(struct interrupt_frame* frame)
|
||||
{
|
||||
terminal_writestring("Test");
|
||||
outb(0x20, 0x20);
|
||||
}
|
||||
|
|
@ -9,4 +9,5 @@ __attribute__((interrupt)) void exception(struct interrupt_frame* frame);
|
|||
__attribute__((interrupt)) void print(struct interrupt_frame* frame);
|
||||
__attribute__((interrupt)) void input(struct interrupt_frame* frame);
|
||||
|
||||
__attribute__((interrupt)) void keyboard_interrupt(struct interrupt_frame* frame);
|
||||
__attribute__((interrupt)) void irq(struct interrupt_frame* frame);
|
49
arch/i686/interrupts/pic.c
Normal file
49
arch/i686/interrupts/pic.c
Normal file
|
@ -0,0 +1,49 @@
|
|||
#include "../io.h"
|
||||
|
||||
#define PIC1 0x20 /* IO base address for master PIC */
|
||||
#define PIC2 0xA0 /* IO base address for slave PIC */
|
||||
#define PIC1_COMMAND PIC1
|
||||
#define PIC1_DATA (PIC1+1)
|
||||
#define PIC2_COMMAND PIC2
|
||||
#define PIC2_DATA (PIC2+1)
|
||||
|
||||
#define ICW1_ICW4 0x01 /* Indicates that ICW4 will be present */
|
||||
#define ICW1_SINGLE 0x02 /* Single (cascade) mode */
|
||||
#define ICW1_INTERVAL4 0x04 /* Call address interval 4 (8) */
|
||||
#define ICW1_LEVEL 0x08 /* Level triggered (edge) mode */
|
||||
#define ICW1_INIT 0x10 /* Initialization - required! */
|
||||
|
||||
#define ICW4_8086 0x01 /* 8086/88 (MCS-80/85) mode */
|
||||
#define ICW4_AUTO 0x02 /* Auto (normal) EOI */
|
||||
#define ICW4_BUF_SLAVE 0x08 /* Buffered mode/slave */
|
||||
#define ICW4_BUF_MASTER 0x0C /* Buffered mode/master */
|
||||
#define ICW4_SFNM 0x10 /* Special fully nested (not) */
|
||||
|
||||
void init_pic() {
|
||||
uint8_t a1, a2;
|
||||
|
||||
a1 = inb(PIC1_DATA); // save masks
|
||||
a2 = inb(PIC2_DATA);
|
||||
|
||||
outb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4); // starts the initialization sequence (in cascade mode)
|
||||
io_wait();
|
||||
outb(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4);
|
||||
io_wait();
|
||||
outb(PIC1_DATA, 0x20); // ICW2: Master PIC vector offset
|
||||
io_wait();
|
||||
outb(PIC2_DATA, 0xFF); // ICW2: Slave PIC vector offset
|
||||
io_wait();
|
||||
outb(PIC1_DATA, 4); // ICW3: tell Master PIC that there is a slave PIC at IRQ2 (0000 0100)
|
||||
io_wait();
|
||||
outb(PIC2_DATA, 2); // ICW3: tell Slave PIC its cascade identity (0000 0010)
|
||||
io_wait();
|
||||
|
||||
outb(PIC1_DATA, ICW4_8086); // ICW4: have the PICs use 8086 mode (and not 8080 mode)
|
||||
io_wait();
|
||||
outb(PIC2_DATA, ICW4_8086);
|
||||
io_wait();
|
||||
|
||||
outb(PIC1_DATA, a1); // restore saved masks.
|
||||
// outb(PIC2_DATA, a2);
|
||||
outb(PIC2_DATA, 0xFF);
|
||||
}
|
|
@ -3,17 +3,19 @@
|
|||
static inline void outb(uint16_t port, uint8_t val)
|
||||
{
|
||||
__asm__ volatile ( "outb %b0, %w1" : : "a"(val), "Nd"(port) : "memory");
|
||||
/* There's an outb %al, $imm8 encoding, for compile-time constant port numbers that fit in 8b. (N constraint).
|
||||
* Wider immediate constants would be truncated at assemble-time (e.g. "i" constraint).
|
||||
* The outb %al, %dx encoding is the only option for all other cases.
|
||||
* %1 expands to %dx because port is a uint16_t. %w1 could be used if we had the port number a wider C type */
|
||||
}
|
||||
|
||||
static inline void inb(uint16_t port, uint8_t val)
|
||||
static inline uint8_t inb(uint16_t port)
|
||||
{
|
||||
__asm__ volatile ( "inb %b0, %w1" : : "a"(val), "Nd"(port) : "memory");
|
||||
/* There's an outb %al, $imm8 encoding, for compile-time constant port numbers that fit in 8b. (N constraint).
|
||||
* Wider immediate constants would be truncated at assemble-time (e.g. "i" constraint).
|
||||
* The outb %al, %dx encoding is the only option for all other cases.
|
||||
* %1 expands to %dx because port is a uint16_t. %w1 could be used if we had the port number a wider C type */
|
||||
uint8_t ret;
|
||||
__asm__ volatile ( "inb %w1, %b0"
|
||||
: "=a"(ret)
|
||||
: "Nd"(port)
|
||||
: "memory");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void io_wait(void)
|
||||
{
|
||||
outb(0x80, 0);
|
||||
}
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
#include "io.h"
|
||||
|
||||
#define ICW1_ICW4 0x01 /* Indicates that ICW4 will be present */
|
||||
#define ICW1_SINGLE 0x02 /* Single (cascade) mode */
|
||||
#define ICW1_INTERVAL4 0x04 /* Call address interval 4 (8) */
|
||||
#define ICW1_LEVEL 0x08 /* Level triggered (edge) mode */
|
||||
#define ICW1_INIT 0x10 /* Initialization - required! */
|
||||
|
||||
#define ICW4_8086 0x01 /* 8086/88 (MCS-80/85) mode */
|
||||
#define ICW4_AUTO 0x02 /* Auto (normal) EOI */
|
||||
#define ICW4_BUF_SLAVE 0x08 /* Buffered mode/slave */
|
||||
#define ICW4_BUF_MASTER 0x0C /* Buffered mode/master */
|
||||
#define ICW4_SFNM 0x10 /* Special fully nested (not) */
|
||||
|
||||
void init_pic() {
|
||||
|
||||
}
|
16
arch/i686/userland.s
Normal file
16
arch/i686/userland.s
Normal file
|
@ -0,0 +1,16 @@
|
|||
.global jump_to_userspace
|
||||
jump_to_userspace:
|
||||
mov $0x20 | 0x3, %ax
|
||||
movw %ax, %ds
|
||||
movw %ax, %es
|
||||
movw %ax, %fs
|
||||
movw %ax, %gs
|
||||
pushl $0x20 | 0x3 /* SS*/
|
||||
pushl $0x00c00100 /* ESP */
|
||||
pushf /* EFLAGS */
|
||||
popl %eax
|
||||
orl $0x200, %eax
|
||||
pushl %eax /* Set interrupts */
|
||||
pushl $0x18 | 0x3 /* CS */
|
||||
pushl $0x00800000 /* EIP */
|
||||
iret
|
3
include/kernel/keyboard.h
Normal file
3
include/kernel/keyboard.h
Normal file
|
@ -0,0 +1,3 @@
|
|||
#include <stdint.h>
|
||||
|
||||
void handle_keyboard(uint8_t scancode);
|
1
include/kernel/pic.h
Normal file
1
include/kernel/pic.h
Normal file
|
@ -0,0 +1 @@
|
|||
void init_pic();
|
|
@ -3,133 +3,6 @@
|
|||
#include <stdbool.h>
|
||||
#include <strlib.h>
|
||||
|
||||
static inline uint8_t inb(uint16_t port)
|
||||
{
|
||||
uint8_t ret;
|
||||
__asm__ volatile ( "inb %w1, %b0"
|
||||
: "=a"(ret)
|
||||
: "Nd"(port)
|
||||
: "memory");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool is_in_shift;
|
||||
|
||||
static unsigned char keyboard_char(unsigned char scancode)
|
||||
{
|
||||
if (0x01 < scancode && scancode < 0x0B) {
|
||||
return scancode - 2 + '1';
|
||||
}
|
||||
|
||||
if (scancode == 0x0B) {
|
||||
return '0';
|
||||
}
|
||||
|
||||
switch (scancode) {
|
||||
case 0x10:
|
||||
return 'Q';
|
||||
case 0x11:
|
||||
return 'W';
|
||||
case 0x12:
|
||||
return 'E';
|
||||
case 0x13:
|
||||
return 'R';
|
||||
case 0x14:
|
||||
return 'T';
|
||||
case 0x15:
|
||||
return 'Y';
|
||||
case 0x16:
|
||||
return 'U';
|
||||
case 0x17:
|
||||
return 'I';
|
||||
case 0x18:
|
||||
return 'O';
|
||||
case 0x19:
|
||||
return 'P';
|
||||
case 0x1a:
|
||||
return '[';
|
||||
case 0x1b:
|
||||
return ']';
|
||||
case 0x1c:
|
||||
return '\n';
|
||||
case 0x1d:
|
||||
return '\b';
|
||||
case 0x1e:
|
||||
return 'A';
|
||||
case 0x1f:
|
||||
return 'S';
|
||||
case 0x20:
|
||||
return 'D';
|
||||
case 0x21:
|
||||
return 'F';
|
||||
case 0x22:
|
||||
return 'G';
|
||||
case 0x23:
|
||||
return 'H';
|
||||
case 0x24:
|
||||
return 'J';
|
||||
case 0x25:
|
||||
return 'K';
|
||||
case 0x26:
|
||||
return 'L';
|
||||
case 0x27:
|
||||
return ';';
|
||||
case 0x28:
|
||||
return '\'';
|
||||
case 0x29:
|
||||
return '`';
|
||||
case 0x2a:
|
||||
is_in_shift = true;
|
||||
break;
|
||||
case 0x2b:
|
||||
return '\\';
|
||||
case 0x2c:
|
||||
return 'Z';
|
||||
case 0x2d:
|
||||
return 'X';
|
||||
case 0x2e:
|
||||
return 'C';
|
||||
case 0x2f:
|
||||
return 'V';
|
||||
case 0x30:
|
||||
return 'B';
|
||||
case 0x31:
|
||||
return 'N';
|
||||
case 0x32:
|
||||
return 'M';
|
||||
case 0x33:
|
||||
return ',';
|
||||
case 0x34:
|
||||
return '.';
|
||||
case 0x35:
|
||||
return '/';
|
||||
case 0x36:
|
||||
is_in_shift = true;
|
||||
break;
|
||||
case 0x39:
|
||||
return ' ';
|
||||
case 0xaa:
|
||||
is_in_shift = false;
|
||||
break;
|
||||
case 0xb6:
|
||||
is_in_shift = false;
|
||||
break;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
char get_last_key_pressed()
|
||||
{
|
||||
char scancode = inb(0x60);
|
||||
|
||||
if (is_in_shift) {
|
||||
return keyboard_char(scancode);
|
||||
}
|
||||
|
||||
return to_lower_char(keyboard_char(scancode));
|
||||
}
|
||||
|
||||
void print_hex_digit(uint8_t digit)
|
||||
{
|
||||
digit = digit & 0xf;
|
||||
|
|
21
kernel/elf.c
21
kernel/elf.c
|
@ -13,25 +13,12 @@ static void* memcpy(void* restrict dstptr, const void* restrict srcptr, size_t s
|
|||
return dstptr;
|
||||
}
|
||||
|
||||
extern void jump_to_userspace();
|
||||
|
||||
void run_program(uint8_t* program, size_t length)
|
||||
{
|
||||
uint8_t* userland_code = (uint8_t*) 0x0;
|
||||
uint8_t* userland_code = (uint8_t*) 0x00800000;
|
||||
memcpy(userland_code, program, length);
|
||||
|
||||
print_hex_bytes(userland_code, 1);
|
||||
terminal_putchar('\n');
|
||||
|
||||
asm ("\
|
||||
mov $0x20 | 0x3, %%ax;\
|
||||
movw %%ax, %%ds;\
|
||||
movw %%ax, %%es;\
|
||||
movw %%ax, %%fs;\
|
||||
movw %%ax, %%gs;\
|
||||
pushl $0x20 | 0x3; /* SS selector */ \
|
||||
pushl $0x00c00100; /* ESP */ \
|
||||
pushf; /* EFLAGS */ \
|
||||
popl %%eax; orl $0x200, %%eax; pushl %%eax; /* Set interrupts in USERPACE */\
|
||||
pushl $0x18 | 0x3; /* CS selector */\
|
||||
pushl $0x0; /* EIP */ \
|
||||
iret;":::"eax");
|
||||
jump_to_userspace();
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <kernel/idt.h>
|
||||
#include <debugging.h>
|
||||
#include <kernel/elf.h>
|
||||
#include <kernel/pic.h>
|
||||
|
||||
/* Check if the compiler thinks you are targeting the wrong operating system. */
|
||||
#if defined(__linux__)
|
||||
|
@ -9,34 +10,45 @@
|
|||
#endif
|
||||
|
||||
uint8_t program[] = {
|
||||
0xB8, 0x00, 0x00, 0x00, 0x00, // mov eax, 0x0 (Just a simple NOP-like instruction)
|
||||
0xF4 // hlt (halts the CPU, should trap to kernel if interrupts enabled)
|
||||
0xba, 0x09, 0x00, 0x80, 0x00, // mov $string, %edx
|
||||
0xcd, 0x80, // int 0x80
|
||||
0xeb, 0xfe, // jmp .
|
||||
'H',
|
||||
'e',
|
||||
'l',
|
||||
'l',
|
||||
'o',
|
||||
' ',
|
||||
'W',
|
||||
'o',
|
||||
'r',
|
||||
'l',
|
||||
'd',
|
||||
' ',
|
||||
'f',
|
||||
'r',
|
||||
'o',
|
||||
'm',
|
||||
' ',
|
||||
'r',
|
||||
'i',
|
||||
'n',
|
||||
'g',
|
||||
' ',
|
||||
'3',
|
||||
'!',
|
||||
0x00,
|
||||
};
|
||||
|
||||
void kernel_main(void)
|
||||
{
|
||||
/* Initialize terminal interface */
|
||||
// terminal_initialize();
|
||||
terminal_initialize();
|
||||
|
||||
init_pic();
|
||||
idt_init();
|
||||
|
||||
// asm("int $13");
|
||||
// asm("ljmp $0x18, $0x00c00100"); // Example: Far jump to user code segment with selector 0x18
|
||||
|
||||
print_hex_bytes(idt_init, 4);
|
||||
terminal_putchar('\n');
|
||||
|
||||
run_program(program, 15);
|
||||
|
||||
/*
|
||||
char buf[100];
|
||||
|
||||
// run_program(program, sizeof(program));
|
||||
while (true) {
|
||||
asm("mov %0, %%edx" :: "r" (buf));
|
||||
asm("int $0x81");
|
||||
terminal_writestring("newline");
|
||||
terminal_putchar('\n');
|
||||
}
|
||||
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
|
132
kernel/keyboard.c
Normal file
132
kernel/keyboard.c
Normal file
|
@ -0,0 +1,132 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <strlib.h>
|
||||
#include <kernel/tty.h>
|
||||
|
||||
static bool is_in_shift;
|
||||
|
||||
char buffer[100];
|
||||
static size_t i;
|
||||
|
||||
static unsigned char keyboard_char(unsigned char scancode)
|
||||
{
|
||||
if (0x01 < scancode && scancode < 0x0B) {
|
||||
return scancode - 2 + '1';
|
||||
}
|
||||
|
||||
if (scancode == 0x0B) {
|
||||
return '0';
|
||||
}
|
||||
|
||||
switch (scancode) {
|
||||
case 0x10:
|
||||
return 'Q';
|
||||
case 0x11:
|
||||
return 'W';
|
||||
case 0x12:
|
||||
return 'E';
|
||||
case 0x13:
|
||||
return 'R';
|
||||
case 0x14:
|
||||
return 'T';
|
||||
case 0x15:
|
||||
return 'Y';
|
||||
case 0x16:
|
||||
return 'U';
|
||||
case 0x17:
|
||||
return 'I';
|
||||
case 0x18:
|
||||
return 'O';
|
||||
case 0x19:
|
||||
return 'P';
|
||||
case 0x1a:
|
||||
return '[';
|
||||
case 0x1b:
|
||||
return ']';
|
||||
case 0x1c:
|
||||
return '\n';
|
||||
case 0x1d:
|
||||
return '\b';
|
||||
case 0x1e:
|
||||
return 'A';
|
||||
case 0x1f:
|
||||
return 'S';
|
||||
case 0x20:
|
||||
return 'D';
|
||||
case 0x21:
|
||||
return 'F';
|
||||
case 0x22:
|
||||
return 'G';
|
||||
case 0x23:
|
||||
return 'H';
|
||||
case 0x24:
|
||||
return 'J';
|
||||
case 0x25:
|
||||
return 'K';
|
||||
case 0x26:
|
||||
return 'L';
|
||||
case 0x27:
|
||||
return ';';
|
||||
case 0x28:
|
||||
return '\'';
|
||||
case 0x29:
|
||||
return '`';
|
||||
case 0x2a:
|
||||
is_in_shift = true;
|
||||
break;
|
||||
case 0x2b:
|
||||
return '\\';
|
||||
case 0x2c:
|
||||
return 'Z';
|
||||
case 0x2d:
|
||||
return 'X';
|
||||
case 0x2e:
|
||||
return 'C';
|
||||
case 0x2f:
|
||||
return 'V';
|
||||
case 0x30:
|
||||
return 'B';
|
||||
case 0x31:
|
||||
return 'N';
|
||||
case 0x32:
|
||||
return 'M';
|
||||
case 0x33:
|
||||
return ',';
|
||||
case 0x34:
|
||||
return '.';
|
||||
case 0x35:
|
||||
return '/';
|
||||
case 0x36:
|
||||
is_in_shift = true;
|
||||
break;
|
||||
case 0x39:
|
||||
return ' ';
|
||||
case 0xaa:
|
||||
is_in_shift = false;
|
||||
break;
|
||||
case 0xb6:
|
||||
is_in_shift = false;
|
||||
break;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void handle_keyboard(uint8_t scancode) {
|
||||
char character;
|
||||
|
||||
if (is_in_shift) {
|
||||
character = keyboard_char(scancode);
|
||||
} else {
|
||||
character = to_lower_char(keyboard_char(scancode));
|
||||
}
|
||||
|
||||
if (character == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
buffer[i] = character;
|
||||
i++;
|
||||
|
||||
terminal_putchar(character);
|
||||
}
|
Loading…
Reference in a new issue