omg pog
This commit is contained in:
parent
86a2d5370d
commit
74c403595d
2
Makefile
2
Makefile
|
@ -22,7 +22,7 @@ ARCHDIR = arch/$(ARCH)/
|
|||
all: $(BIN)
|
||||
|
||||
run: $(ISO)
|
||||
$(QEMU) -cdrom $(ISO)
|
||||
$(QEMU) -d int -cdrom $(ISO)
|
||||
|
||||
$(ISO): $(BIN)
|
||||
grub-mkrescue -o $(ISO) sysroot
|
||||
|
|
|
@ -32,28 +32,30 @@ stack_bottom:
|
|||
resb 16384 ; 16 KiB
|
||||
stack_top:
|
||||
|
||||
section .data
|
||||
section .rodata
|
||||
gdt:
|
||||
gdt_null:
|
||||
dq 0
|
||||
gdt_code:
|
||||
dw 0FFFFh
|
||||
dw 0
|
||||
db 0
|
||||
.null:
|
||||
dq 0x0
|
||||
.code:
|
||||
dw 0xffff
|
||||
dw 0x0000
|
||||
db 0x00
|
||||
db 10011010b
|
||||
db 11001111b
|
||||
db 0
|
||||
gdt_data:
|
||||
dw 0FFFFh
|
||||
dw 0
|
||||
db 0
|
||||
db 0x00
|
||||
.data:
|
||||
dw 0xffff
|
||||
dw 0x0000
|
||||
db 0x00
|
||||
db 10010010b
|
||||
db 11001111b
|
||||
db 0
|
||||
gdt_size: equ $ - gdt
|
||||
gdt_desc:
|
||||
dw gdt_size - 1
|
||||
db 0x00
|
||||
.end:
|
||||
.descriptor:
|
||||
dw .end - gdt - 1
|
||||
dd gdt
|
||||
code_segment equ gdt.code - gdt
|
||||
data_segment equ gdt.data - gdt
|
||||
|
||||
; The linker script specifies _start as the entry point to the kernel and the
|
||||
; bootloader will jump to this position once the kernel has been loaded. It
|
||||
|
@ -63,11 +65,19 @@ section .text
|
|||
global _start:function (_start.end - _start)
|
||||
global load_idt
|
||||
|
||||
load_idt:
|
||||
mov edx, [esp + 4]
|
||||
lidt [edx]
|
||||
sti
|
||||
ret
|
||||
gdt_load:
|
||||
push eax
|
||||
lgdt [gdt.descriptor]
|
||||
jmp 0x08:.loaded_cs
|
||||
.loaded_cs:
|
||||
mov ax, 0x10
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
mov ss, ax
|
||||
pop eax
|
||||
ret
|
||||
|
||||
_start:
|
||||
; The bootloader has loaded us into 32-bit protected mode on a x86
|
||||
|
@ -93,7 +103,7 @@ _start:
|
|||
; yet. The GDT should be loaded here. Paging should be enabled here.
|
||||
; C++ features such as global constructors and exceptions will require
|
||||
; runtime support to work as well.
|
||||
lgdt [gdt_desc]
|
||||
call gdt_load
|
||||
|
||||
; Enter the high-level kernel. The ABI requires the stack is 16-byte
|
||||
; aligned at the time of the call instruction (which afterwards pushes
|
||||
|
@ -115,6 +125,7 @@ _start:
|
|||
; Since they are disabled, this will lock up the computer.
|
||||
; 3) Jump to the hlt instruction if it ever wakes up due to a
|
||||
; non-maskable interrupt occurring or due to system management mode.
|
||||
|
||||
cli
|
||||
.hang: hlt
|
||||
jmp .hang
|
||||
|
|
|
@ -10,7 +10,10 @@ void idt_init() {
|
|||
idt_ptr[0] = (sizeof (struct idt_entry) * 256) + ((idt_address & 0xffff) << 16);
|
||||
idt_ptr[1] = idt_address >> 16;
|
||||
|
||||
load_idt(idt_ptr);
|
||||
__asm__ __volatile__(
|
||||
"lidt %0\n\t"
|
||||
"sti\n\t" : : "m"(idt_ptr)
|
||||
);
|
||||
}
|
||||
|
||||
void idt_register_handler(uint8_t interrupt, unsigned long address) {
|
||||
|
|
|
@ -1,162 +1,172 @@
|
|||
#include <isr.h>
|
||||
#include <terminal.h>
|
||||
|
||||
__attribute__((interrupt)) void isr0(void* butterdog) {
|
||||
__attribute__((interrupt)) void isr0(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Division By Zero");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) void isr1(void* butterdog) {
|
||||
__attribute__((interrupt)) void isr1(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Debug");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) void isr2(void* butterdog) {
|
||||
__attribute__((interrupt)) void isr2(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Non Maskable Interrupt");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) void isr3(void* butterdog) {
|
||||
__attribute__((interrupt)) void isr3(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Breakpoint");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) void isr4(void* butterdog) {
|
||||
__attribute__((interrupt)) void isr4(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Into Detected Overflow");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) void isr5(void* butterdog) {
|
||||
__attribute__((interrupt)) void isr5(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Out of Bounds");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) void isr6(void* butterdog) {
|
||||
__attribute__((interrupt)) void isr6(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Invalid Opcode");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) void isr7(void* butterdog) {
|
||||
__attribute__((interrupt)) void isr7(struct interrupt_frame* frame) {
|
||||
terminal_writeline("No Coprocessor");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) void isr8(void* butterdog) {
|
||||
__attribute__((interrupt)) void isr8(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Double Fault");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) void isr9(void* butterdog) {
|
||||
__attribute__((interrupt)) void isr9(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Coprocessor Segment Overrun");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) void isr10(void* butterdog) {
|
||||
__attribute__((interrupt)) void isr10(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Bad TSS");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) void isr11(void* butterdog) {
|
||||
__attribute__((interrupt)) void isr11(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Segment Not Present");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) void isr12(void* butterdog) {
|
||||
__attribute__((interrupt)) void isr12(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Stack Fault");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) void isr13(void* butterdog) {
|
||||
__attribute__((interrupt)) void isr13(struct interrupt_frame* frame) {
|
||||
terminal_writeline("General Protection Fault");
|
||||
|
||||
terminal_writeline("heres some info:");
|
||||
|
||||
terminal_writestring("ip: ");
|
||||
terminal_writeline(itoa(frame->ip));
|
||||
terminal_writestring("sp: ");
|
||||
terminal_writeline(itoa(frame->sp));
|
||||
terminal_writestring("cs: ");
|
||||
terminal_writeline(itoa(frame->cs));
|
||||
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) void isr14(void* butterdog) {
|
||||
__attribute__((interrupt)) void isr14(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Page Fault");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) void isr15(void* butterdog) {
|
||||
__attribute__((interrupt)) void isr15(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Unknown Interrupt");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) void isr16(void* butterdog) {
|
||||
__attribute__((interrupt)) void isr16(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Coprocessor Fault");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) void isr17(void* butterdog) {
|
||||
__attribute__((interrupt)) void isr17(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Alignment Check");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) void isr18(void* butterdog) {
|
||||
__attribute__((interrupt)) void isr18(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Machine Check");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) void isr19(void* butterdog) {
|
||||
__attribute__((interrupt)) void isr19(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Reserved");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) void isr20(void* butterdog) {
|
||||
__attribute__((interrupt)) void isr20(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Reserved");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) void isr21(void* butterdog) {
|
||||
__attribute__((interrupt)) void isr21(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Reserved");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) void isr22(void* butterdog) {
|
||||
__attribute__((interrupt)) void isr22(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Reserved");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) void isr23(void* butterdog) {
|
||||
__attribute__((interrupt)) void isr23(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Reserved");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) void isr24(void* butterdog) {
|
||||
__attribute__((interrupt)) void isr24(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Reserved");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) void isr25(void* butterdog) {
|
||||
__attribute__((interrupt)) void isr25(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Reserved");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) void isr26(void* butterdog) {
|
||||
__attribute__((interrupt)) void isr26(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Reserved");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) void isr27(void* butterdog) {
|
||||
__attribute__((interrupt)) void isr27(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Reserved");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) void isr28(void* butterdog) {
|
||||
__attribute__((interrupt)) void isr28(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Reserved");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) void isr29(void* butterdog) {
|
||||
__attribute__((interrupt)) void isr29(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Reserved");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) void isr30(void* butterdog) {
|
||||
__attribute__((interrupt)) void isr30(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Reserved");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) void isr31(void* butterdog) {
|
||||
__attribute__((interrupt)) void isr31(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Reserved");
|
||||
asm("hlt");
|
||||
}
|
||||
|
@ -194,6 +204,7 @@ void isr_install(void) {
|
|||
idt_register_handler(29, (unsigned long)isr29);
|
||||
idt_register_handler(30, (unsigned long)isr30);
|
||||
idt_register_handler(31, (unsigned long)isr31);
|
||||
//idt_register_handler(32, (unsigned long)isr32);
|
||||
|
||||
idt_init();
|
||||
}
|
|
@ -18,7 +18,7 @@ void kernel_main() {
|
|||
terminal_initialize();
|
||||
terminal_writeline("Initializing terminal... done");
|
||||
terminal_writestring("Preparing interrupts... ");
|
||||
remap_pic(0x20, 0x28);
|
||||
i686_pic_init();
|
||||
isr_install();
|
||||
terminal_writeline("done");
|
||||
terminal_writestring("Preparing keyboard... ");
|
||||
|
@ -30,14 +30,20 @@ void kernel_main() {
|
|||
} else {
|
||||
terminal_writeline("no");
|
||||
}
|
||||
terminal_writestring("Is keyboard enabled? ");
|
||||
if (are_interrupts_enabled() == 1) {
|
||||
terminal_writeline("yes");
|
||||
} else {
|
||||
terminal_writeline("no");
|
||||
}
|
||||
|
||||
terminal_writeline("----------");
|
||||
|
||||
terminal_writeline("hello yes");
|
||||
terminal_writestring("> ");
|
||||
|
||||
while (true);
|
||||
|
||||
while (true);
|
||||
|
||||
//while (true) {
|
||||
// if (inportb(0x64) & 1) {
|
||||
// const char key = keyboard_to_ascii(parse_keycode(inportb(0x60)));
|
||||
|
|
|
@ -1,406 +1,71 @@
|
|||
#include <keyboard.h>
|
||||
|
||||
unsigned char kbdus[128] =
|
||||
{
|
||||
0, 27, '1', '2', '3', '4', '5', '6', '7', '8', /* 9 */
|
||||
'9', '0', '-', '=', '\b', /* Backspace */
|
||||
'\t', /* Tab */
|
||||
'q', 'w', 'e', 'r', /* 19 */
|
||||
't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', /* Enter key */
|
||||
0, /* 29 - Control */
|
||||
'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', /* 39 */
|
||||
'\'', '`', 0, /* Left shift */
|
||||
'\\', 'z', 'x', 'c', 'v', 'b', 'n', /* 49 */
|
||||
'm', ',', '.', '/', 0, /* Right shift */
|
||||
'*',
|
||||
0, /* Alt */
|
||||
' ', /* Space bar */
|
||||
0, /* Caps lock */
|
||||
0, /* 59 - F1 key ... > */
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, /* < ... F10 */
|
||||
0, /* 69 - Num lock*/
|
||||
0, /* Scroll Lock */
|
||||
0, /* Home key */
|
||||
0, /* Up Arrow */
|
||||
0, /* Page Up */
|
||||
'-',
|
||||
0, /* Left Arrow */
|
||||
0,
|
||||
0, /* Right Arrow */
|
||||
'+',
|
||||
0, /* 79 - End key*/
|
||||
0, /* Down Arrow */
|
||||
0, /* Page Down */
|
||||
0, /* Insert Key */
|
||||
0, /* Delete Key */
|
||||
0, 0, 0,
|
||||
0, /* F11 Key */
|
||||
0, /* F12 Key */
|
||||
0, /* All other keys are undefined */
|
||||
};
|
||||
|
||||
uint8_t lastkey = 0;
|
||||
char* keycache = 0;
|
||||
uint16_t key_loc = 0;
|
||||
uint8_t __kbd_enabled = 0;
|
||||
|
||||
enum KEYCODE {
|
||||
|
||||
// Alphanumeric keys ////////////////
|
||||
|
||||
KEY_SPACE = ' ',
|
||||
KEY_0 = '0',
|
||||
KEY_1 = '1',
|
||||
KEY_2 = '2',
|
||||
KEY_3 = '3',
|
||||
KEY_4 = '4',
|
||||
KEY_5 = '5',
|
||||
KEY_6 = '6',
|
||||
KEY_7 = '7',
|
||||
KEY_8 = '8',
|
||||
KEY_9 = '9',
|
||||
|
||||
KEY_A = 'a',
|
||||
KEY_B = 'b',
|
||||
KEY_C = 'c',
|
||||
KEY_D = 'd',
|
||||
KEY_E = 'e',
|
||||
KEY_F = 'f',
|
||||
KEY_G = 'g',
|
||||
KEY_H = 'h',
|
||||
KEY_I = 'i',
|
||||
KEY_J = 'j',
|
||||
KEY_K = 'k',
|
||||
KEY_L = 'l',
|
||||
KEY_M = 'm',
|
||||
KEY_N = 'n',
|
||||
KEY_O = 'o',
|
||||
KEY_P = 'p',
|
||||
KEY_Q = 'q',
|
||||
KEY_R = 'r',
|
||||
KEY_S = 's',
|
||||
KEY_T = 't',
|
||||
KEY_U = 'u',
|
||||
KEY_V = 'v',
|
||||
KEY_W = 'w',
|
||||
KEY_X = 'x',
|
||||
KEY_Y = 'y',
|
||||
KEY_Z = 'z',
|
||||
|
||||
KEY_RETURN = '\n',
|
||||
KEY_ESCAPE = 0x1b,
|
||||
KEY_BACKSPACE = 0x7f,
|
||||
|
||||
// Arrow keys ////////////////////////
|
||||
|
||||
KEY_UP = 0x1100,
|
||||
KEY_DOWN = 0x1101,
|
||||
KEY_LEFT = 0x1102,
|
||||
KEY_RIGHT = 0x1103,
|
||||
|
||||
// Function keys /////////////////////
|
||||
|
||||
KEY_F1 = 0x1201,
|
||||
KEY_F2 = 0x1202,
|
||||
KEY_F3 = 0x1203,
|
||||
KEY_F4 = 0x1204,
|
||||
KEY_F5 = 0x1205,
|
||||
KEY_F6 = 0x1206,
|
||||
KEY_F7 = 0x1207,
|
||||
KEY_F8 = 0x1208,
|
||||
KEY_F9 = 0x1209,
|
||||
KEY_F10 = 0x120a,
|
||||
KEY_F11 = 0x120b,
|
||||
KEY_F12 = 0x120b,
|
||||
KEY_F13 = 0x120c,
|
||||
KEY_F14 = 0x120d,
|
||||
KEY_F15 = 0x120e,
|
||||
|
||||
KEY_DOT = '.',
|
||||
KEY_COMMA = ',',
|
||||
KEY_COLON = ':',
|
||||
KEY_SEMICOLON = ';',
|
||||
KEY_SLASH = '/',
|
||||
KEY_BACKSLASH = '\\',
|
||||
KEY_PLUS = '+',
|
||||
KEY_MINUS = '-',
|
||||
KEY_ASTERISK = '*',
|
||||
KEY_EXCLAMATION = '!',
|
||||
KEY_QUESTION = '?',
|
||||
KEY_QUOTEDOUBLE = '\"',
|
||||
KEY_QUOTE = '\'',
|
||||
KEY_EQUAL = '=',
|
||||
KEY_HASH = '#',
|
||||
KEY_PERCENT = '%',
|
||||
KEY_AMPERSAND = '&',
|
||||
KEY_UNDERSCORE = '_',
|
||||
KEY_LEFTPARENTHESIS = '(',
|
||||
KEY_RIGHTPARENTHESIS = ')',
|
||||
KEY_LEFTBRACKET = '[',
|
||||
KEY_RIGHTBRACKET = ']',
|
||||
KEY_LEFTCURL = '{',
|
||||
KEY_RIGHTCURL = '}',
|
||||
KEY_DOLLAR = '$',
|
||||
KEY_POUND = '$',
|
||||
KEY_EURO = '$',
|
||||
KEY_LESS = '<',
|
||||
KEY_GREATER = '>',
|
||||
KEY_BAR = '|',
|
||||
KEY_GRAVE = '`',
|
||||
KEY_TILDE = '~',
|
||||
KEY_AT = '@',
|
||||
KEY_CARRET = '^',
|
||||
|
||||
// Numeric keypad //////////////////////
|
||||
|
||||
KEY_KP_0 = '0',
|
||||
KEY_KP_1 = '1',
|
||||
KEY_KP_2 = '2',
|
||||
KEY_KP_3 = '3',
|
||||
KEY_KP_4 = '4',
|
||||
KEY_KP_5 = '5',
|
||||
KEY_KP_6 = '6',
|
||||
KEY_KP_7 = '7',
|
||||
KEY_KP_8 = '8',
|
||||
KEY_KP_9 = '9',
|
||||
KEY_KP_PLUS = '+',
|
||||
KEY_KP_MINUS = '-',
|
||||
KEY_KP_DECIMAL = '.',
|
||||
KEY_KP_DIVIDE = '/',
|
||||
KEY_KP_ASTERISK = '*',
|
||||
KEY_KP_NUMLOCK = 0x300f,
|
||||
KEY_KP_ENTER = 0x3010,
|
||||
|
||||
KEY_TAB = 0x4000,
|
||||
KEY_CAPSLOCK = 0x4001,
|
||||
|
||||
// Modify keys ////////////////////////////
|
||||
|
||||
KEY_LSHIFT = 0x4002,
|
||||
KEY_LCTRL = 0x4003,
|
||||
KEY_LALT = 0x4004,
|
||||
KEY_LWIN = 0x4005,
|
||||
KEY_RSHIFT = 0x4006,
|
||||
KEY_RCTRL = 0x4007,
|
||||
KEY_RALT = 0x4008,
|
||||
KEY_RWIN = 0x4009,
|
||||
|
||||
KEY_INSERT = 0x400a,
|
||||
KEY_DELETE = 0x400b,
|
||||
KEY_HOME = 0x400c,
|
||||
KEY_END = 0x400d,
|
||||
KEY_PAGEUP = 0x400e,
|
||||
KEY_PAGEDOWN = 0x400f,
|
||||
KEY_SCROLLLOCK = 0x4010,
|
||||
KEY_PAUSE = 0x4011,
|
||||
|
||||
KEY_UNKNOWN,
|
||||
KEY_NUMKEYCODES
|
||||
};
|
||||
|
||||
static int scancode_std [] = {
|
||||
// key scancode
|
||||
KEY_UNKNOWN, //0
|
||||
KEY_ESCAPE, //1
|
||||
KEY_1, //2
|
||||
KEY_2, //3
|
||||
KEY_3, //4
|
||||
KEY_4, //5
|
||||
KEY_5, //6
|
||||
KEY_6, //7
|
||||
KEY_7, //8
|
||||
KEY_8, //9
|
||||
KEY_9, //0xa
|
||||
KEY_0, //0xb
|
||||
KEY_MINUS, //0xc
|
||||
KEY_EQUAL, //0xd
|
||||
KEY_BACKSPACE, //0xe
|
||||
KEY_TAB, //0xf
|
||||
KEY_Q, //0x10
|
||||
KEY_W, //0x11
|
||||
KEY_E, //0x12
|
||||
KEY_R, //0x13
|
||||
KEY_T, //0x14
|
||||
KEY_Y, //0x15
|
||||
KEY_U, //0x16
|
||||
KEY_I, //0x17
|
||||
KEY_O, //0x18
|
||||
KEY_P, //0x19
|
||||
KEY_LEFTBRACKET,//0x1a
|
||||
KEY_RIGHTBRACKET,//0x1b
|
||||
KEY_RETURN, //0x1c
|
||||
KEY_LCTRL, //0x1d
|
||||
KEY_A, //0x1e
|
||||
KEY_S, //0x1f
|
||||
KEY_D, //0x20
|
||||
KEY_F, //0x21
|
||||
KEY_G, //0x22
|
||||
KEY_H, //0x23
|
||||
KEY_J, //0x24
|
||||
KEY_K, //0x25
|
||||
KEY_L, //0x26
|
||||
KEY_SEMICOLON, //0x27
|
||||
KEY_QUOTE, //0x28
|
||||
KEY_GRAVE, //0x29
|
||||
KEY_LSHIFT, //0x2a
|
||||
KEY_BACKSLASH, //0x2b
|
||||
KEY_Z, //0x2c
|
||||
KEY_X, //0x2d
|
||||
KEY_C, //0x2e
|
||||
KEY_V, //0x2f
|
||||
KEY_B, //0x30
|
||||
KEY_N, //0x31
|
||||
KEY_M, //0x32
|
||||
KEY_COMMA, //0x33
|
||||
KEY_DOT, //0x34
|
||||
KEY_SLASH, //0x35
|
||||
KEY_RSHIFT, //0x36
|
||||
KEY_KP_ASTERISK,//0x37
|
||||
KEY_RALT, //0x38
|
||||
KEY_SPACE, //0x39
|
||||
KEY_CAPSLOCK, //0x3a
|
||||
KEY_F1, //0x3b
|
||||
KEY_F2, //0x3c
|
||||
KEY_F3, //0x3d
|
||||
KEY_F4, //0x3e
|
||||
KEY_F5, //0x3f
|
||||
KEY_F6, //0x40
|
||||
KEY_F7, //0x41
|
||||
KEY_F8, //0x42
|
||||
KEY_F9, //0x43
|
||||
KEY_F10, //0x44
|
||||
KEY_KP_NUMLOCK, //0x45
|
||||
KEY_SCROLLLOCK, //0x46
|
||||
KEY_HOME, //0x47
|
||||
KEY_KP_8, //0x48 //keypad up arrow
|
||||
KEY_PAGEUP, //0x49
|
||||
KEY_KP_2, //0x50 //keypad down arrow
|
||||
KEY_KP_3, //0x51 //keypad page down
|
||||
KEY_KP_0, //0x52 //keypad insert key
|
||||
KEY_KP_DECIMAL, //0x53 //keypad delete key
|
||||
KEY_UNKNOWN, //0x54
|
||||
KEY_UNKNOWN, //0x55
|
||||
KEY_UNKNOWN, //0x56
|
||||
KEY_F11, //0x57
|
||||
KEY_F12 //0x58
|
||||
};
|
||||
|
||||
static uint8_t _shift = 0;
|
||||
static uint8_t _alt = 0;
|
||||
static uint8_t _ctrl = 0;
|
||||
static uint8_t _capslock = 0;
|
||||
|
||||
uint8_t keyboard_to_ascii(uint8_t key) {
|
||||
if(!key) return 0;
|
||||
// if shift key is down or caps lock is on, make the key uppercase
|
||||
if (_shift || _capslock)
|
||||
if (key >= 'a' && key <= 'z')
|
||||
key -= 32;
|
||||
|
||||
if (_shift && !_capslock) {
|
||||
if (key >= '0' && key <= '9') {
|
||||
switch (key) {
|
||||
case '0':
|
||||
key = KEY_RIGHTPARENTHESIS;
|
||||
break;
|
||||
case '1':
|
||||
key = KEY_EXCLAMATION;
|
||||
break;
|
||||
case '2':
|
||||
key = KEY_AT;
|
||||
break;
|
||||
case '3':
|
||||
key = KEY_HASH;
|
||||
break;
|
||||
case '4':
|
||||
key = KEY_DOLLAR;
|
||||
break;
|
||||
case '5':
|
||||
key = KEY_PERCENT;
|
||||
break;
|
||||
case '6':
|
||||
key = KEY_CARRET;
|
||||
break;
|
||||
case '7':
|
||||
key = KEY_AMPERSAND;
|
||||
break;
|
||||
case '8':
|
||||
key = KEY_ASTERISK;
|
||||
break;
|
||||
case '9':
|
||||
key = KEY_LEFTPARENTHESIS;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (key) {
|
||||
case KEY_COMMA:
|
||||
key = KEY_LESS;
|
||||
break;
|
||||
case KEY_DOT:
|
||||
key = KEY_GREATER;
|
||||
break;
|
||||
case KEY_SLASH:
|
||||
key = KEY_QUESTION;
|
||||
break;
|
||||
case KEY_SEMICOLON:
|
||||
key = KEY_COLON;
|
||||
break;
|
||||
case KEY_QUOTE:
|
||||
key = KEY_QUOTEDOUBLE;
|
||||
break;
|
||||
case KEY_LEFTBRACKET:
|
||||
key = KEY_LEFTCURL;
|
||||
break;
|
||||
case KEY_RIGHTBRACKET:
|
||||
key = KEY_RIGHTCURL;
|
||||
break;
|
||||
case KEY_GRAVE:
|
||||
key = KEY_TILDE;
|
||||
break;
|
||||
case KEY_MINUS:
|
||||
key = KEY_UNDERSCORE;
|
||||
break;
|
||||
case KEY_PLUS:
|
||||
key = KEY_EQUAL;
|
||||
break;
|
||||
case KEY_BACKSLASH:
|
||||
key = KEY_BAR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if (_ctrl && key >= 'a' && key <= 'z')
|
||||
// return __CONTROL(key - 32);
|
||||
|
||||
// return the key
|
||||
return key;
|
||||
}
|
||||
|
||||
uint8_t _extended = 0;
|
||||
uint8_t parse_keycode(uint8_t code) {
|
||||
if (code == 0xE0 || code == 0xE1) {
|
||||
_extended = 1;
|
||||
} else {
|
||||
_extended = 0;
|
||||
if (code & 0x80) {
|
||||
code -= 0x80;
|
||||
int key = scancode_std[code];
|
||||
switch (key) {
|
||||
case KEY_LCTRL:
|
||||
case KEY_RCTRL:
|
||||
_ctrl = 0;
|
||||
break;
|
||||
case KEY_LSHIFT:
|
||||
case KEY_RSHIFT:
|
||||
_shift = 0;
|
||||
break;
|
||||
case KEY_LALT:
|
||||
case KEY_RALT:
|
||||
_alt = 0;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
int key = scancode_std[code];
|
||||
switch (key) {
|
||||
case KEY_LCTRL:
|
||||
case KEY_RCTRL:
|
||||
_ctrl = 1;
|
||||
return 0;
|
||||
case KEY_LSHIFT:
|
||||
case KEY_RSHIFT:
|
||||
_shift = 1;
|
||||
return 0;
|
||||
case KEY_LALT:
|
||||
case KEY_RALT:
|
||||
_alt = 1;
|
||||
return 0;
|
||||
case KEY_CAPSLOCK:
|
||||
_capslock = (_capslock) ? 0 : 1;
|
||||
return 0;
|
||||
}
|
||||
return key;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) void keyboard_irq(struct interrupt_frame* frame) {
|
||||
terminal_writeline("called");
|
||||
char key = keyboard_to_ascii(inportb(0x60));
|
||||
keycache[key_loc++] = key;
|
||||
unsigned char scancode = inportb(0x60);
|
||||
|
||||
const char key = kbdus[scancode];
|
||||
|
||||
if (scancode & 128) {
|
||||
// This is a release scancode, just ignore it
|
||||
i686_pic_irq_notify_on_term(1);
|
||||
return;
|
||||
}
|
||||
|
||||
terminal_putchar(key);
|
||||
send_eoi(33);
|
||||
|
||||
i686_pic_irq_notify_on_term(1);
|
||||
}
|
||||
|
||||
void keyboard_init(void) {
|
||||
terminal_writeline("haha keyboard go brr");
|
||||
keycache = (char*)malloc(256);
|
||||
memset(keycache, 0, 256);
|
||||
i686_pic_irq_enable(1);
|
||||
idt_register_handler(33, (uint32_t)keyboard_irq);
|
||||
|
||||
__kbd_enabled = 1;
|
||||
|
||||
terminal_writeline("haha keyboard go brr");
|
||||
}
|
||||
|
||||
uint8_t keyboard_enabled(void) {
|
||||
|
|
|
@ -1,42 +1,71 @@
|
|||
#include <pic.h>
|
||||
|
||||
/*
|
||||
arguments:
|
||||
offset1 - vector offset for master PIC
|
||||
vectors on the master become offset1..offset1+7
|
||||
offset2 - same for slave PIC: offset2..offset2+7
|
||||
*/
|
||||
void remap_pic(int offset1, int offset2) {
|
||||
unsigned char a1, a2;
|
||||
|
||||
a1 = inportb(PIC1_DATA); // save masks
|
||||
a2 = inportb(PIC2_DATA);
|
||||
|
||||
outportb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4); // starts the initialization sequence (in cascade mode)
|
||||
io_wait();
|
||||
outportb(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4);
|
||||
io_wait();
|
||||
outportb(PIC1_DATA, offset1); // ICW2: Master PIC vector offset
|
||||
io_wait();
|
||||
outportb(PIC2_DATA, offset2); // ICW2: Slave PIC vector offset
|
||||
io_wait();
|
||||
outportb(PIC1_DATA, 4); // ICW3: tell Master PIC that there is a slave PIC at IRQ2 (0000 0100)
|
||||
io_wait();
|
||||
outportb(PIC2_DATA, 2); // ICW3: tell Slave PIC its cascade identity (0000 0010)
|
||||
io_wait();
|
||||
|
||||
outportb(PIC1_DATA, ICW4_8086);
|
||||
io_wait();
|
||||
outportb(PIC2_DATA, ICW4_8086);
|
||||
io_wait();
|
||||
|
||||
outportb(PIC1_DATA, a1); // restore saved masks.
|
||||
outportb(PIC2_DATA, a2);
|
||||
#define PIC1 0x20
|
||||
#define PIC2 0xA0
|
||||
#define PIC1_COMMAND PIC1
|
||||
#define PIC1_DATA (PIC1 + 1)
|
||||
#define PIC2_COMMAND PIC2
|
||||
#define PIC2_DATA (PIC2 + 1)
|
||||
#define PIC_EOI 0x20
|
||||
|
||||
#define ICW1_ICW4 0x01
|
||||
#define ICW1_INIT 0x10
|
||||
#define ICW4_8086 0x01
|
||||
|
||||
static uint8_t pic1_mask = 0xff;
|
||||
static uint8_t pic2_mask = 0xff;
|
||||
|
||||
static inline void i686_cpu_io_wait() {
|
||||
asm volatile("outb %%al, $0x80" : : "a"(0));
|
||||
}
|
||||
|
||||
void send_eoi(uint8_t irq) {
|
||||
if (irq >= 8)
|
||||
void i686_pic_init() {
|
||||
outportb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4);
|
||||
i686_cpu_io_wait();
|
||||
outportb(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4);
|
||||
i686_cpu_io_wait();
|
||||
outportb(PIC1_DATA, 0x20);
|
||||
i686_cpu_io_wait();
|
||||
outportb(PIC2_DATA, 0x28);
|
||||
i686_cpu_io_wait();
|
||||
outportb(PIC1_DATA, 4);
|
||||
i686_cpu_io_wait();
|
||||
outportb(PIC2_DATA, 2);
|
||||
i686_cpu_io_wait();
|
||||
outportb(PIC1_DATA, ICW4_8086);
|
||||
i686_cpu_io_wait();
|
||||
outportb(PIC2_DATA, ICW4_8086);
|
||||
i686_cpu_io_wait();
|
||||
outportb(PIC1_DATA, pic1_mask);
|
||||
outportb(PIC2_DATA, pic2_mask);
|
||||
i686_pic_irq_enable(2);
|
||||
}
|
||||
|
||||
void i686_pic_irq_notify_on_term(uint8_t no) {
|
||||
if (no >= 8) {
|
||||
outportb(PIC2_COMMAND, PIC_EOI);
|
||||
|
||||
}
|
||||
outportb(PIC1_COMMAND, PIC_EOI);
|
||||
}
|
||||
|
||||
void i686_pic_irq_enable(uint8_t no) {
|
||||
if (no >= 8) {
|
||||
no -= 8;
|
||||
pic2_mask &= ~(1 << no);
|
||||
outportb(PIC2_DATA, pic2_mask);
|
||||
} else {
|
||||
pic1_mask &= ~(1 << no);
|
||||
outportb(PIC1_DATA, pic1_mask);
|
||||
}
|
||||
}
|
||||
|
||||
void i686_pic_irq_disable(uint8_t no) {
|
||||
if (no >= 8) {
|
||||
no -= 8;
|
||||
pic2_mask |= (1 << no);
|
||||
outportb(PIC2_DATA, pic2_mask);
|
||||
} else {
|
||||
pic1_mask |= (1 << no);
|
||||
outportb(PIC1_DATA, pic1_mask);
|
||||
}
|
||||
}
|
|
@ -14,4 +14,26 @@ int rand(void) {
|
|||
|
||||
void srand(size_t seed) {
|
||||
rand_next = seed;
|
||||
}
|
||||
|
||||
char* itoa(int res) {
|
||||
int size = 0;
|
||||
int t = res;
|
||||
|
||||
while(t / 10 != 0) {
|
||||
t = t/10;
|
||||
size++;
|
||||
}
|
||||
static char ret[64];
|
||||
size++;
|
||||
ret[size] = '\0';
|
||||
t = res;
|
||||
int i = size - 1;
|
||||
while(i >= 0) {
|
||||
ret[i] = (t % 10) + '0';
|
||||
t = t/10;
|
||||
i--;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -19,6 +19,15 @@ struct idt_entry {
|
|||
unsigned short int offset_higherbits;
|
||||
};
|
||||
|
||||
struct interrupt_frame
|
||||
{
|
||||
uintptr_t ip;
|
||||
uintptr_t cs;
|
||||
uintptr_t flags;
|
||||
uintptr_t sp;
|
||||
uintptr_t ss;
|
||||
};
|
||||
|
||||
void idt_init();
|
||||
void idt_register_handler(uint8_t interrupt, unsigned long address);
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@ extern uint16_t key_loc;
|
|||
|
||||
void keyboard_init(void);
|
||||
uint8_t keyboard_enabled(void);
|
||||
uint8_t keyboard_to_ascii(uint8_t key);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -7,29 +7,10 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#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 PIC_EOI 0x20 /* End-of-interrupt command code */
|
||||
|
||||
#define ICW1_ICW4 0x01 /* ICW4 (not) needed */
|
||||
#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 remap_pic(int offset1, int offset2);
|
||||
void send_eoi(uint8_t irq);
|
||||
void i686_pic_init();
|
||||
void i686_pic_irq_notify_on_term(uint8_t no);
|
||||
void i686_pic_irq_enable(uint8_t no);
|
||||
void i686_pic_irq_disable(uint8_t no);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ static size_t rand_next;
|
|||
|
||||
int rand(void);
|
||||
void srand(size_t seed);
|
||||
char* itoa(int res);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue