console: Initial commit of simple framebuffer console output
This commit is contained in:
		
							
								
								
									
										131
									
								
								kernel/console.c
									
									
									
									
									
								
							
							
						
						
									
										131
									
								
								kernel/console.c
									
									
									
									
									
								
							| @@ -20,19 +20,23 @@ | ||||
|  | ||||
| #include <font.h> | ||||
| #include <framebuffer.h> | ||||
| #include <kmalloc.h> | ||||
| #include <print.h> | ||||
|  | ||||
| #define CONSOLE_BUFFER_SIZE 16384 | ||||
| char console_buffer[CONSOLE_BUFFER_SIZE]; | ||||
| char console_output_buffer[CONSOLE_BUFFER_SIZE]; | ||||
| char *console_buffer_p = console_buffer; | ||||
| struct fb *console_framebuffer = 0; | ||||
| struct font *console_font = 0; | ||||
| unsigned int chars_per_line = 0, lines = 0; | ||||
| char *console_buffer, *cb_first_line; | ||||
| struct fb *console_framebuffer; | ||||
| struct font *console_font; | ||||
| unsigned int chars_per_line, lines; | ||||
| unsigned int curr_char, curr_line; | ||||
|  | ||||
| void console_char_to_fb(char c, unsigned int x, unsigned int y) { | ||||
| void console_char_to_fb(char c, unsigned int chr, unsigned int line) { | ||||
| 	unsigned int x, y; | ||||
| 	unsigned int cx, cy, bit = 0; | ||||
| 	char *font_char = &console_font->data[console_font->bytes_per_char * (c - console_font->ascii_offset)]; | ||||
|  | ||||
| 	x = chr * console_font->width; | ||||
| 	y = line * console_font->height; | ||||
|  | ||||
| 	for (cy = 0; cy < console_font->height; cy++) { | ||||
| 		for (cx = 0; cx < console_font->width; cx++) { | ||||
| 			unsigned char on = font_char[bit / 8] & (1 << (bit % 8)); | ||||
| @@ -45,36 +49,103 @@ void console_char_to_fb(char c, unsigned int x, unsigned int y) { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void console_refresh_fb() { | ||||
| void console_redraw_fb() { | ||||
| 	unsigned int cc, cl = 0; | ||||
| 	char *c; | ||||
|  | ||||
| 	if (!console_framebuffer) | ||||
| 		return; | ||||
| } | ||||
|  | ||||
| void console_clear() { | ||||
| 	int i; | ||||
| 	for (i = 0; i < CONSOLE_BUFFER_SIZE; i++) { | ||||
| 		console_buffer[i] = 0; | ||||
| 	for (c = cb_first_line; c < console_buffer + chars_per_line * lines; c += chars_per_line) { | ||||
| 		char *d; | ||||
| 		cc = 0; | ||||
| 		for (d = c; d < c + chars_per_line; d++) | ||||
| 			console_char_to_fb(*d, cc++, cl); | ||||
| 		cl++; | ||||
| 	} | ||||
|  | ||||
| 	for (c = console_buffer; c < cb_first_line; c += chars_per_line) { | ||||
| 		char *d; | ||||
| 		cc = 0; | ||||
| 		for (d = c; d < c + chars_per_line; d++) | ||||
| 			console_char_to_fb(*d, cc++, cl); | ||||
| 		cl++; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void console_init(struct fb *f) { | ||||
| 	console_clear(); | ||||
| 	console_refresh_fb(); | ||||
| 	console_font = font_get(); | ||||
| 	console_framebuffer = f; | ||||
| 	chars_per_line = console_framebuffer->width / console_font->width; | ||||
| 	lines = console_framebuffer->height / console_font->height; | ||||
| void console_buffer_clear() { | ||||
| 	char *c; | ||||
| 	for (c = console_buffer; c < console_buffer + chars_per_line * lines; c++) | ||||
| 		*c = ' '; | ||||
| 	curr_char = 0; | ||||
| 	curr_line = 0; | ||||
| } | ||||
|  | ||||
| 	console_char_to_fb('A', 100, 100); | ||||
| 	console_char_to_fb('E', 111, 100); | ||||
| 	console_char_to_fb('D', 122, 100); | ||||
| 	console_char_to_fb('R', 133, 100); | ||||
| 	console_char_to_fb('I', 144, 100); | ||||
| 	console_char_to_fb('X', 155, 100); | ||||
| int console_init(struct fb *f) { | ||||
| 	console_framebuffer = f; | ||||
| 	console_font = font_get(); | ||||
| 	lines = console_framebuffer->height / console_font->height; | ||||
| 	chars_per_line = console_framebuffer->width / console_font->width; | ||||
| 	curr_line = 0; | ||||
| 	curr_char = 0; | ||||
|  | ||||
| 	if (!(console_buffer = kmalloc(sizeof(char) * chars_per_line * lines))) { | ||||
| 		print("Error: Failed to allocate memory for console buffer\n"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	cb_first_line = console_buffer; | ||||
| 	 | ||||
| 	console_buffer_clear(); | ||||
| 	console_redraw_fb(); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| void console_newline() { | ||||
| 	char *c; | ||||
|  | ||||
| 	curr_line++; | ||||
| 	curr_char = 0; | ||||
| 	if (curr_line == lines) { | ||||
| 		char *console_buffer_end = console_buffer + chars_per_line * lines; | ||||
|  | ||||
| 		//empty the current first line, since it will wrap around to the bottom | ||||
| 		for (c = cb_first_line; c < cb_first_line + chars_per_line; c++) | ||||
| 			*c = ' '; | ||||
|  | ||||
| 		cb_first_line += chars_per_line; | ||||
| 		if (cb_first_line >= console_buffer_end) | ||||
| 			cb_first_line = console_buffer; | ||||
|  | ||||
| 		curr_line = lines - 1; | ||||
|  | ||||
| 		console_redraw_fb(); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void console_putc(char c) { | ||||
| 	*console_buffer_p = c; | ||||
| 	if (++console_buffer_p > console_buffer + CONSOLE_BUFFER_SIZE) | ||||
| 		console_buffer_p = console_buffer; | ||||
| 	char *console_buffer_end = console_buffer + chars_per_line * lines; | ||||
| 	char *write_char_at; | ||||
|  | ||||
| 	switch (c) { | ||||
| 		case '\n': | ||||
| 			console_newline(); | ||||
| 			return; | ||||
| 		case '\r': | ||||
| 			curr_char = 0; | ||||
| 			return; | ||||
| 		default: | ||||
| 			break; | ||||
| 	} | ||||
|  | ||||
| 	if (curr_char + 1 > chars_per_line) | ||||
| 		console_newline(); | ||||
|  | ||||
| 	write_char_at = cb_first_line + chars_per_line * curr_line + curr_char; | ||||
| 	if (write_char_at >= console_buffer_end) | ||||
| 		write_char_at -= chars_per_line * lines; | ||||
|  | ||||
| 	*write_char_at = c; | ||||
|  | ||||
| 	console_char_to_fb(c, curr_char++, curr_line); | ||||
| } | ||||
|   | ||||
| @@ -31,15 +31,17 @@ | ||||
|  | ||||
| struct fb myfb; | ||||
|  | ||||
| void video(void) { | ||||
| 	unsigned int x, y; | ||||
| void print_console_logo() { | ||||
| 	print_func(&console_putc, "                            _            _      _\n"); | ||||
| 	print_func(&console_putc, "                           / \\   ___  __| |_ __(_)_  __\n"); | ||||
| 	print_func(&console_putc, "                          / _ \\ / _ \\/ _` | '__| \\ \\/ /\n"); | ||||
| 	print_func(&console_putc, "                         / ___ \\  __/ (_| | |  | |>  <\n"); | ||||
| 	print_func(&console_putc, "                        /_/   \\_\\___|\\__,_|_|  |_/_/\\_\\\n\n"); | ||||
| 	print_func(&console_putc, "                        Copyright (C) 2012 - Aaron Lindsay\n"); | ||||
| } | ||||
|  | ||||
| void video_init(void) { | ||||
| 	bcm2835_videocore_init(&myfb, 16); | ||||
|  | ||||
| 	for (y = 0; y < myfb.height; y++) | ||||
| 		for (x = 0; x < myfb.width; x++) | ||||
| 			fb_write_pixel(&myfb, x, y, 0x3f, 0x0, 0x6f); | ||||
|  | ||||
| 	console_init(&myfb); | ||||
| } | ||||
|  | ||||
| void test_mm() { | ||||
| @@ -142,7 +144,9 @@ int main(void) { | ||||
|  | ||||
| 	test_memory(); | ||||
|  | ||||
| 	video(); | ||||
| 	video_init(); | ||||
| 	console_init(&myfb); | ||||
| 	print_console_logo(); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user