1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

wslで、最小のカーネルをコンパイル その7

Posted at

概要

wslで、kernel.elfのコンパイル、やってみた。
cで、書いたカーネルで、キーボード読み込みでじゃんけんを、実行してみた。

写真

image.png

サンプルコード

#include "kernel3.h"

uint32 vga_index;
static uint32 next_line_index = 1;
uint8 g_fore_color = WHITE, 
	g_back_color = BLUE;
int digit_ascii_codes[10] = {
	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39
};
uint32 strlen(const char * str) {
	uint32 length = 0;
	while(str[length])
		length++;
	return length;
}
uint32 digit_count(int num) {
	uint32 count = 0;
	if (num == 0)
		return 1;
	while(num > 0)
	{
		count++;
		num = num / 10;
	}
	return count;
}
void itoa(int num, char * number) {
	int dgcount = digit_count(num);
	int index = dgcount - 1;
	char x;
	if (num == 0 && dgcount == 1)
	{
		number[0] = '0';
		number[1] = '\0';
	}
	else
	{
		while(num != 0)
		{
			x = num % 10;
			number[index] = x + '0';
			index--;
			num = num / 10;
		}
		number[dgcount] = '\0';
	}
}
char get_ascii_char(uint8 key_code) {
	switch(key_code)
	{
	case KEY_A: return 'A';
	case KEY_B: return 'B';
	case KEY_C: return 'C';
	case KEY_D: return 'D';
	case KEY_E: return 'E';
	case KEY_F: return 'F';
	case KEY_G: return 'G';
	case KEY_H: return 'H';
	case KEY_I: return 'I';
	case KEY_J: return 'J';
	case KEY_K: return 'K';
	case KEY_L: return 'L';
	case KEY_M: return 'M';
	case KEY_N: return 'N';
	case KEY_O: return 'O';
	case KEY_P: return 'P';
	case KEY_Q: return 'Q';
	case KEY_R: return 'R';
	case KEY_S: return 'S';
	case KEY_T: return 'T';
	case KEY_U: return 'U';
	case KEY_V: return 'V';
	case KEY_W: return 'W';
	case KEY_X: return 'X';
	case KEY_Y: return 'Y';
	case KEY_Z: return 'Z';
	case KEY_1: return '1';
	case KEY_2: return '2';
	case KEY_3: return '3';
	case KEY_4: return '4';
	case KEY_5: return '5';
	case KEY_6: return '6';
	case KEY_7: return '7';
	case KEY_8: return '8';
	case KEY_9: return '9';
	case KEY_0: return '0';
	case KEY_MINUS: return '-';
	case KEY_EQUAL: return '=';
	case KEY_SQUARE_OPEN_BRACKET: return '[';
	case KEY_SQUARE_CLOSE_BRACKET: return ']';
	case KEY_SEMICOLON: return ';';
	case KEY_BACKSLASH: return '\\';
	case KEY_COMMA: return ',';
	case KEY_DOT: return '.';
	case KEY_FORESLHASH: return '/';
	case KEY_SPACE: return ' ';
	default: return 0;
	}
}
uint16 vga_entry(unsigned char ch, uint8 fore_color, uint8 back_color) {
	uint16 ax = 0;
	uint8 ah = 0,
		al = 0;
	ah = back_color;
	ah <<= 4;
	ah |= fore_color;
	ax = ah;
	ax <<= 8;
	al = ch;
	ax |= al;
	return ax;
}
void clear_vga_buffer(uint16 ** buffer, uint8 fore_color, uint8 back_color) {
	uint32 i;
	for(i = 0; i < BUFSIZE; i++)
	{
		(* buffer) [i] = vga_entry(NULL, fore_color, back_color);
	}
	next_line_index = 1;
	vga_index = 0;
}
void init_vga(uint8 fore_color, uint8 back_color) {
	vga_buffer = (uint16 *) VGA_ADDRESS;
	clear_vga_buffer(&vga_buffer, fore_color, back_color);
	g_fore_color = fore_color;
	g_back_color = back_color;
}
void print_new_line() {
	if (next_line_index >= 55)
	{
		next_line_index = 0;
		clear_vga_buffer(&vga_buffer, g_fore_color, g_back_color);
	}
	vga_index = 80 * next_line_index;
	next_line_index++;
}
void print_char(char ch) {
	vga_buffer[vga_index] = vga_entry(ch, g_fore_color, g_back_color);
	vga_index++;
}
void print_string(char * str) {
	uint32 index = 0;
	while(str[index])
	{
		print_char(str[index]);
		index++;
	}
}
void print_int(int num) {
	char str_num[digit_count(num) + 1];
	itoa(num, str_num);
	print_string(str_num);
}
uint8 inb(uint16 port) {
	uint8 ret;
	asm volatile("inb %1, %0": "=a"(ret): "d"(port));
	return ret;
}
void outb(uint16 port, uint8 data) {
	asm volatile("outb %0, %1": "=a"(data): "d"(port));
}
char get_input_keycode() {
	char ch = 0;
	while ((ch = inb(KEYBOARD_PORT)) != 0)
	{
		if (ch > 0)
			return ch;
	}
	return ch;
}
void wait_for_io(uint32 timer_count) {
	while (1)
	{
		asm volatile("nop");
		timer_count--;
		if (timer_count <= 0)
			break;
	}
}
void sleep(uint32 timer_count) {
	wait_for_io(timer_count);
}
char kinput() {
	char ch = 0;
	char keycode = 0;
	do
	{
		//sleep(0x4FFFFFF);
		keycode = get_input_keycode();
		ch = get_ascii_char(keycode);
		print_char(ch);
		print_char(0x39);
	} while(ch < 1);
	return ch;
}

void kernel_entry() {
	uint8 r = 243;
	char ch = 0;
	int user_input;
	int com_input;
	int i;
	init_vga(WHITE, BLUE);
	for (i = 0; i < 3; i++)
	{
		print_int(i);
		sleep(0x9FFFFFF);
		print_string(" jyanken pon (goo:1 choki:2 par:3) : ");
		ch = kinput();
		user_input = ch - 0x30;
		r = r * 5;
		r = r - 1;
		com_input = r % 3 + 1;
		switch (user_input)
		{
		case 1:
			if (com_input == 1)
			{
				print_string(" com : goo -- aiko");
			}
			else if (com_input == 2)
			{
				print_string(" com : choki -- kati");
			}
			else if (com_input == 3)
			{
				print_string(" com : par -- make");
			}
		break;
		case 2:
			if (com_input == 1)
			{
				print_string(" com : goo -- make");
			}
			else if (com_input == 2)
			{
				print_string(" com : choki -- aiko");
			}
			else if (com_input == 3)
			{
				print_string(" com : par -- kati");
			}
		break;
		case 3:
			if (com_input == 1)
			{
				print_string(" com : goo -- kati");
			}
			else if (com_input == 2)
			{
				print_string(" com : choki -- make");
			}
			else if (com_input == 3)
			{
				print_string(" com : par -- aiko");
			}
		break;
		default:
			print_string("(1 2 3)");
			print_new_line();
		continue;
		}
		print_new_line();
	}
}





以上。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?