blob: 1c10b5333e92e6fd0f8f9795e445413ef8071e08 [file] [log] [blame]
#include "io.h"
#include "kbd.h"
#include "log.h"
#include "pic.h"
bool pressed_keys[LAST_KBD_KEY];
char special_key_mappings[LAST_KBD_KEY - FIRST_KBD_KEY] = {
[KBD_ENTER - FIRST_KBD_KEY] = '\n',
[KBD_SPACEBAR - FIRST_KBD_KEY] = ' ',
[KBD_TAB - FIRST_KBD_KEY] = '\t',
[KBD_BACKSPACE - FIRST_KBD_KEY] = '\b',
};
void outb(ushort port, uchar val)
{
asm volatile("outb %1, %0" : : "dN"(port), "a"(val));
}
uchar inb(ushort port)
{
uchar ret;
asm volatile("inb %1, %0" : "=a"(ret) : "dN"(port));
return ret;
}
ushort inw(ushort port)
{
ushort ret;
asm("inw %1, %0" : "=a"(ret) : "dN"(port));
return ret;
}
struct ext2_dir_contains_data
{
char *name;
uint len;
bool found;
};
void outl(ushort port, uint val)
{
asm("outl %1, %0" : : "dN"(port), "a"(val));
}
uint inl(ushort port)
{
uint ret;
asm("inl %1, %0" : "=a"(ret) : "dN"(port));
return ret;
}
void outw(ushort port, ushort val)
{
asm("outw %1, %0" :: "dN"(port), "a"(val));
}
void __attribute__((noinline)) nop()
{
asm("nop");
}
void *memset(void *s, int c, size_t n)
{
for (size_t i = 0; i < n; i++)
{
((uchar *)s)[i] = c;
}
return s;
}
void *memcpy(void *dest, const void *src, size_t n)
{
for (size_t i = 0; i < n; i++)
{
((uchar *)dest)[i] = ((uchar *)src)[i];
}
return dest;
}
void strcpy(char *dest, char *src)
{
memcpy(dest, src, strlen(src) + 1);
}
uint strlen(char *a)
{
uint i = 0;
for (; a[i]; i++)
{
}
return i;
}
uint strnlen(char *s, size_t len)
{
int i;
for (i = 0; s[i] && i < len; i++)
{
}
return i;
}
int strncmp(char *a, char *b, size_t len)
{
int al = strnlen(a, len), bl = strnlen(b, len);
if (al != bl)
return bl - al;
for (int i = 0; i < al; i++)
{
if (a[i] != b[i])
return -1;
}
return 0;
}
int strcmp(char *a, char *b)
{
int al = strlen(a), bl = strlen(b);
if (al != bl)
return bl - al;
for (int i = 0; i < al; i++)
{
if (a[i] != b[i])
return -1;
}
return 0;
}
uchar kbd_scan_code()
{
return inb(KBD_DATA_PORT);
}
static bool kbd_shift_pressed()
{
return pressed_keys[KBD_LEFT_SHIFT] || pressed_keys[KBD_RIGHT_SHIFT] ||
pressed_keys[KBD_CAPS_LOCK];
}
void kbd_handle_input(struct registers *registers)
{
uchar byte = kbd_scan_code();
struct kbd_scan_codes code = scan_code_set_1[byte];
if (code.ascii && !code.brk)
{
kprintf("%c", kbd_shift_pressed() && code.up_symbol ? code.up_symbol
: code.symbol);
}
else if (!code.brk && special_key_mappings[code.symbol - FIRST_KBD_KEY])
{
kprintf("%c", special_key_mappings[code.symbol - FIRST_KBD_KEY]);
}
pressed_keys[code.symbol] = !code.brk;
}
void init_kbd()
{
memset(pressed_keys, 0, LAST_KBD_KEY);
add_interrupt_handler(33, kbd_handle_input);
}
bool isdigit(char c)
{
return c >= '0' && c <= '9';
}
uint parse_int(char *string)
{
uint number = 0;
for (; isdigit(*string); string++)
{
number *= 10;
number += *string - '0';
}
return number;
}