summaryrefslogtreecommitdiffstats
path: root/system/kernel.c
blob: e8ad3a9b7b19685569826d309e5b906494cefb15 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/* kernel.c - kernel functions */

#include <system.h>
#include <console.h>


extern unsigned char console_std_attr;
extern unsigned short console_cur_pos;
extern unsigned char console_flags;

unsigned char numprint = 0;

#define PRINT_ON if(numprint == 0) { \
		asm("cli");\
		console_cursor_off();\
	}\
	numprint++

#define PRINT_OFF numprint--;\
	if(numprint == 0) {\
		console_cursor_on();\
		asm("sti");\
	}


void print(unsigned char * text) {
	print_attr(text, console_std_attr);
}

void print_attr(unsigned char * text, unsigned char attr) {
	PRINT_ON;
	while(*text) {
		print_char_attr(*text, attr);
		text++;
	}
	PRINT_OFF;
}

void print_char(unsigned char text) {
	print_char_attr(text, console_std_attr);
}

void print_char_attr(unsigned char text, unsigned char attr) {
	PRINT_ON;
	switch(text) {
		case 0x08:		// backspace
			if(console_cur_pos) console_cur_pos--;
			break;
		case 0x09:		// tab
			console_cur_pos += (8 - (console_cur_pos % 8));
			break;
		case 0x0A:		// new line
			console_cur_pos += (80 - (console_cur_pos % 80));
			break;
		case 0x0B:		// home
		case 0x0C:		// form feed
			console_cur_pos = 0;
			asm(
				"cld\n"
				"mov $32,%%ax\n"
				"mov %%ax,%%es\n"
				"xor %%edi,%%edi\n"
				"mov %0,%%ah\n"
				"mov $0x20,%%al\n"
				"mov $2000,%%ecx\n"
				"rep stosw"
				: : "m" (attr)
			);
			break;
		case 0x0D:		// carriage return
			console_cur_pos -= (console_cur_pos % 80);
			break;
		default:
			ANSI2ASCII(text);
			asm(
				"cld\n"
				"mov $32,%%ax\n"
				"mov %%ax,%%es\n"
				"xor %%eax,%%eax\n"
				"mov %0,%%ax\n"
				"shl $1,%%eax\n"
				"mov %%eax,%%edi\n"
				"mov %1,%%al\n"
				"mov %2,%%ah\n"
				"stosw"
				: : "m" (console_cur_pos), "m" (text), "m" (attr)
			);
			console_cur_pos++;
	}
	// scroll
	if(console_cur_pos >= 2000) {
		console_cur_pos -= 80;
		asm(
			"cld\n"
			"push %%ds\n"
			
			"mov $32,%%ax\n"
			"mov %%ax,%%ds\n"
			"mov %%ax,%%es\n"
			"mov $1920,%%ecx\n"
			"mov $160,%%esi\n"
			"xor %%edi,%%edi\n"
			"rep movsw\n"
			
			"mov $80,%%cx\n"
			"mov %%cs:%0,%%ah\n"
			"mov $0x20,%%al\n"
			"rep stosw\n"
			
			"pop %%ds"
			: : "m" (console_std_attr)
		);
	}
	PRINT_OFF;
}