actually lemme post the code.There are only three files right now so its not to cumbersome
Code: Select all
kb_int:
pusha
#movw $0x0f74, (0xb8000)
#movw $0x0f65, (0xb8002)
#movw $0x0f73, (0xb8004)
#movw $0x0f74, (0xb8006)
#for some reason causing a reboot when not using grub
#breakpont
#xchgw %bx, %bx 158
in $0x60, %al
nop
mov %al, (scancode)
cmp $0x9E, %al
mov (ticks), %ebx
jne store_sc
sub (last_keypress), %ebx #normal keypress takes 3 or 4, initial repeat is B subsequent 0
#xchgw %bx, %bx
#movw $0x0f58, (0xb8000)
store_sc:
movl %ebx, (last_keypress)
mov $0x20, %al
out %al, $0x20
call keypress
popa
iret
clock_int:
incl (ticks)
#xchgw %bx, %bx
mov $0x20, %al
out %al, $0x20
iret
dummy_exc:
movw $0x0f46, (0xb8006)
cli
hlt
dummy_int:
#pusha
#add $0x0f00, %eax
movw $0x0f21, (0xb8006)
mov $0x20, %al
out %al, $0x20
#popa
iret
.size _start, . - _start
.section .data
msg:
.string "message 1\n"
msg2:
.string "Leftover data found in keyboard buffer, disposing\n"
idt_info:
.word 0x800 - 1
.int 0x0
ticks:
.int 0x0 #supplies 4,294,967,295 or apx 2761 days of uptime, good enough for now
last_keypress:
.int 0x0
Code: Select all
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#if defined(__linux__)
#error "you are not using the cross compiler"
#endif
#if !defined(__i386__)
#error "this needs to be compiles with an i686-elf compiler"
#endif
enum vga_color {
VGA_COLOR_BLACK = 0,
VGA_COLOR_BLUE = 1,
VGA_COLOR_GREEN = 2,
VGA_COLOR_CYAN = 3,
VGA_COLOR_RED = 4,
VGA_COLOR_MAGENTA = 5,
VGA_COLOR_BROWN = 6,
VGA_COLOR_LIGHT_GREY = 7,
VGA_COLOR_DARK_GREY = 8,
VGA_COLOR_LIGHT_BLUE = 9,
VGA_COLOR_LIGHT_GREEN = 10,
VGA_COLOR_LIGHT_CYAN = 11,
VGA_COLOR_LIGHT_RED = 12,
VGA_COLOR_LIGHT_MAGENTA = 13,
VGA_COLOR_LIGHT_BROWN = 14,
VGA_COLOR_WHITE = 15,
};
static inline uint8_t vga_entry_color(enum vga_color fg, enum vga_color bg) {
return fg | bg << 4;
}
static inline uint16_t vga_entry(unsigned char uc, uint8_t color) {
return (uint16_t) uc | (uint16_t) color << 8;
}
size_t strlen(const char* str) {
size_t len = 0;
while(str[len]) {
len++;
}
return len;
}
static const size_t VGA_WIDTH = 80;
static const size_t VGA_HEIGHT = 26;
size_t terminal_row;
size_t terminal_column;
uint8_t terminal_color;
uint16_t* terminal_buffer;
uint16_t* columns;
uint8_t* video_ram;
void terminal_initialize(void) {
terminal_row = 0;
terminal_column = 0;
terminal_color = vga_entry_color(VGA_COLOR_LIGHT_GREY, VGA_COLOR_BLACK);
terminal_buffer = (uint16_t*) 0xb8000;
columns = (uint16_t*) 0x044A;
for (size_t y = 0; y < VGA_HEIGHT; y++) {
for (size_t x = 0; x < VGA_WIDTH; x++) {
const size_t index = (y * VGA_WIDTH) + x;
terminal_buffer[index] = vga_entry(' ', terminal_color);
}
}
}
void terminal_setcolor(uint8_t color) {
terminal_color = color;
}
void terminal_putentryat(char c, uint8_t color, size_t x, size_t y) {
const size_t index = y * VGA_WIDTH + x;
terminal_buffer[index] = vga_entry(c, color);
}
void terminal_scroll(void) {
// no buffer needed
terminal_row = 0;
terminal_column = 0;
for (size_t y = 0; y < VGA_HEIGHT; y++) {
for (size_t x = 0; x < VGA_WIDTH; x++) {
const size_t index = (y * VGA_WIDTH) + x;
if (y < VGA_HEIGHT - 1) {
terminal_buffer[index] = terminal_buffer[index + VGA_WIDTH];
} else {
terminal_buffer[index] = vga_entry(' ', terminal_color);
}
}
}
terminal_row = VGA_HEIGHT - 1;
terminal_column = 0;
}
void terminal_putchar(char c) {
if (c == '\n') {
// what about \r
terminal_column = VGA_WIDTH - 1;
} else {
terminal_putentryat(c, terminal_color, terminal_column, terminal_row);
}
if (++terminal_column == VGA_WIDTH) {
terminal_column = 0;
if (++terminal_row == VGA_HEIGHT) {
terminal_scroll();
}
}
}
void terminal_write(const char* data, size_t size) {
for (size_t i = 0; i < size; i++) {
terminal_putchar(data[i]);
}
}
void terminal_writestring(const char* data) {
terminal_write(data, strlen(data));
}
char* int_to_string(int number) {
char* tmp = NULL;
int count = 0;
while (number > 0) {
int remain = number % 10;
tmp[count] = remain + 48;
number = (number - remain) / 10;
count++;
}
char* retvalue = tmp + count;
for (int newcount = 0; newcount < count; newcount++) {
retvalue[newcount] = tmp[count - (newcount + 1)];
}
retvalue[count] = '\0';
return retvalue;
}
static inline uint8_t inb(uint16_t port) {
uint8_t ret;
asm volatile ("inb %1, %0" : "=a"(ret): "Nd" (port));
return ret;
}
static inline void outb(uint16_t port, uint8_t val) {
asm volatile ("outb %0, %1" : : "a"(val), "Nd"(port));
}
static inline void io_wait(void) {
asm volatile ( "jmp 1f\n\t"
"1:jmp 2f\n\t"
"2:" );
}
char getScancode() {
char c = 0;
do {
if (inb(0x60) != c) {
c = inb(0x60);
if (c > 0) {
return c;
}
}
} while (1);
}
void update_cursor(void) {
unsigned short pos = (terminal_row * VGA_WIDTH) + terminal_column;
outb(0x3d4, 0x0f);
outb(0x3D5, (unsigned char)(pos & 0xFF));
outb(0x3D4, 0x0E);
outb(0x3D5, (unsigned char )((pos >> 8) & 0xFF));
}
uint8_t scancode = 0x00;
uint8_t km_no_keys[256] = {
0x0,
0x0 /*escape*/, '1', '2', '3', '4', '5', '6', '7' , '8', '9', '0', '-', '=', 0x0, /*backspace*/
0x0 /*tab*/, 'q', 'w', 'e', 'r', 't', 'y', 'u' , 'i', 'o', 'p', '[', ']', '\n', /*enter*/
0x0 /*l-ctl*/, 'a', 's', 'd', 'f', 'g', 'h', 'j' , 'k', 'l', ';', '\'', '`',
0x0 /*l-shift*/, '\\', 'z', 'x', 'c', 'v', 'b', 'n' , 'm', ',', '.', '/', 0x0, /*r-shift*/
'*' /*keypad-multiply*/, 0x0 /*l-alt*/, ' ', 0x0 /*caps-lock*/, 'c', 'v', 'b', 'n' , 'm', ',', '.', '/', 0x0, /*r-shift*/
};
uint8_t *keymaps[1] = {km_no_keys};
void keypress(void) {
uint8_t keyboard_state = 0x00;
uint8_t old_col = terminal_column;
uint8_t old_row = terminal_row;
terminal_row = (size_t) 20;
if (scancode < 0x80) {
terminal_column = (size_t) 1;
} else {
terminal_column = (size_t) 5;
}
char *thesc = int_to_string(scancode);
if (strlen(thesc) == 2) {
terminal_putchar('0');
}
terminal_writestring(thesc);
if (scancode < 0x80) {
terminal_writestring(" ");;
}
terminal_row = old_row;
terminal_column = old_col;
if (scancode < 0x80) {
switch (scancode) {
case 0x01: //escape
break;
case 0x0E: //backspace
break;
case 0x0F: //tab
break;
//case 0x1c: //enter
//break;
case 0x1d: //left ctl
break;
case 0x2a: //left shift
break;
case 0x36: //right shift
break;
case 0x38: //left alt
break;
case 0x3A: //caps lock
break;
//default:
//terminal_putchar(keymaps[keyboard_state][scancode]);
//update_cursor();
}
}
terminal_writestring(int_to_string(scancode));
terminal_putchar(' ');
}
void ps2_wait_write() {
while((inb(0x64) & 2) != 0) {
// do nothing
}
}
void ps2_wait_read() {
while((inb(0x64) & 1) == 0) {
// do nothing
// geting no response on till a keypress
}
}
void byte_to_bin_string(uint8_t data) {
for (int x = 0; x < 8; x++) {
if (((data >> x) & 1) == 0) {
terminal_putchar('0');
} else {
terminal_putchar('1');
}
}
}
unsigned char ps2_send(unsigned char data) {
terminal_writestring("waiting for write\n");
ps2_wait_write();
terminal_writestring("writing\n");
outb(0x64, data);
terminal_writestring("waiting for read\n");
terminal_writestring("current keyboard status: ");
terminal_writestring(int_to_string((int)inb(0x64)));
terminal_putchar('\n');
ps2_wait_read();
terminal_writestring("returning\n");
return inb(0x60);
}
void kernel_main(void) {
terminal_writestring("Welcome to TestOS\n");
terminal_writestring("this is a second string\n");
terminal_putchar('\n');
update_cursor();
}