aboutsummaryrefslogtreecommitdiff
path: root/screen/console.c
blob: 00e9ebb3997de79a9a50ba4b027d52cb431364d2 (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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301, USA.
 *
 */

#ifndef CONSOLE_C
#define CONSOLE_C

#include <toast.h>

/*********************************************************
 * Set up the console buffer and pointer
 ********************************************************/
void console_init()
{
	console_buffer = (char*)0xB8000;
	console_pointer = 0;
}


/*********************************************************
 * Update cursor position to x,y co-ord for next char
 ********************************************************/
void console_set_cursor_xy(uint8_t x,uint8_t y)
{
	console_pointer = (160*y) + (2*x);
}

/*********************************************************
 * Update flashing cursor to match console_position
 * Note: Does _NOT_ dictate the pos for next printed byte
 ********************************************************/
void console_update_cursor()
{
	outb(0x3D4, 0x0F);
	outb(0x3D5, ((console_pointer/2) & 0xFF));
	outb(0x3D4, 0x0E);
	outb(0x3D5, (((console_pointer/2)>>8)&0xFF));
}

/*********************************************************
 * Clear the console with the current colour scheme
 ********************************************************/
void console_clear()
{
	for (console_pointer = 0; console_pointer < 4000; console_pointer+=2)
	{
		console_buffer[console_pointer] = 0;
		console_buffer[console_pointer+1] = console_color;
	}
	console_pointer = 0;
	console_update_cursor();
}


/*********************************************************
 * Set the console foreground AND background colours
 ********************************************************/
void console_set_colors(uint8_t fg, uint8_t bg)
{
	console_color = (bg << 4) | fg;
}


/*********************************************************
 * Set ONLY the console foreground colour
 ********************************************************/
void console_set_color(uint8_t fg)
{
	console_color &= 0xF0;				// Zero-out foreground color
	console_color |= fg;				// Apply foreground color
}


/*********************************************************
 * Print a single character
 ********************************************************/
void console_print_char(const char c)
{
	// Scroll the screen up a line if the pointer is out of bounds
	if (console_pointer >= 4000)
		console_scroll();
	switch (c)
	{
		case 8:
			console_buffer[console_pointer-=2] = 0;
			break;

		case 10:
			console_pointer += 160-(console_pointer%160);
			break;

		default:
			console_buffer[console_pointer++] = c;
			console_buffer[console_pointer++] = console_color;
	}
}


/*********************************************************
 * Print an integer of a certain base
 ********************************************************/
void console_print_num(const uint32_t num, const uint8_t base)
{
	char buffer[32];
	uint32_t i = 0;
	if (num == 0)
	{
		console_print_char('0');
	} else {
		itoa(num,buffer,base);
		// Find the first digit which isn't a trailing digit
		while(buffer[i++] == '0');
		console_print_string(buffer+i-1);
	}
}

/*********************************************************
 * Print a single null-terminated string
 ********************************************************/
void console_print_string(const char *string)
{
	uint16_t i = 0;
	while(string[i] != 0)
		console_print_char(string[i++]);
	console_update_cursor();
}

/*********************************************************
 * Print a single null-terminated string
 ********************************************************/
void console_scroll(/*uint8_t lines*/)
{
	//memcpy(console_buffer, console_buffer+160, 3840);
	memcpy(console_buffer, console_buffer+160, 3840);
	memset(console_buffer+3840, 0, 160);
	console_pointer = 3840;
}


/*********************************************************
 * Print a formatted string
 ********************************************************/
void console_print(const char* format, ...)
{
	va_list strings;
	va_start(strings,format);
	uint16_t i;
	uint64_t length = strlen(format);

	for (i = 0; i < length; i++)
	{
		if (format[i] == '%')
		{
			switch (format[++i])
			{
				case 's':
					console_print_string(va_arg(strings, char*));
					break;
				case 'c':
					console_print_char(va_arg(strings, uint64_t));
					break;
				case 'd':
					console_print_num(va_arg(strings, uint64_t),10);
					break;
				case 'x':
					console_print_num(va_arg(strings, uint64_t),16);
					break;
				case 'o':
					console_print_num(va_arg(strings, uint64_t),8);
					break;
				case 'b':
					console_print_num(va_arg(strings, uint64_t),2);
					break;
			}
		} else {
			console_print_char(format[i]);
		}
	}
	va_end(strings);
}

#endif