xref: /haiku/src/system/boot/platform/bios_ia32/console.cpp (revision 93aeb8c3bc3f13cb1f282e3e749258a23790d947)
1 /*
2  * Copyright 2004-2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include "console.h"
8 
9 #include <SupportDefs.h>
10 #include <util/kernel_cpp.h>
11 #include <boot/stage2.h>
12 
13 #include <string.h>
14 
15 
16 class Console : public ConsoleNode {
17 	public:
18 		Console();
19 
20 		virtual ssize_t ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize);
21 		virtual ssize_t WriteAt(void *cookie, off_t pos, const void *buffer, size_t bufferSize);
22 };
23 
24 static uint16 *sScreenBase = (uint16 *)0xb8000;
25 static uint32 sScreenWidth = 80;
26 static uint32 sScreenHeight = 25;
27 static uint32 sScreenOffset = 0;
28 static uint16 sColor = 0x0f00;
29 
30 static Console sInput, sOutput;
31 FILE *stdin, *stdout, *stderr;
32 
33 
34 static void
35 scroll_up()
36 {
37 	memcpy(sScreenBase, sScreenBase + sScreenWidth,
38 		sScreenWidth * sScreenHeight * 2 - sScreenWidth * 2);
39 	sScreenOffset = (sScreenHeight - 1) * sScreenWidth;
40 
41 	for (uint32 i = 0; i < sScreenWidth; i++)
42 		sScreenBase[sScreenOffset + i] = sColor | ' ';
43 }
44 
45 
46 //	#pragma mark -
47 
48 
49 Console::Console()
50 	: ConsoleNode()
51 {
52 }
53 
54 
55 ssize_t
56 Console::ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize)
57 {
58 	// don't seek in character devices
59 	// not implemented (and not yet? needed)
60 	return B_ERROR;
61 }
62 
63 
64 ssize_t
65 Console::WriteAt(void *cookie, off_t /*pos*/, const void *buffer, size_t bufferSize)
66 {
67 	const char *string = (const char *)buffer;
68 
69 	if (gKernelArgs.frame_buffer.enabled)
70 		return bufferSize;
71 
72 	for (uint32 i = 0; i < bufferSize; i++) {
73 		if (string[0] == '\n')
74 			sScreenOffset += sScreenWidth - (sScreenOffset % sScreenWidth);
75 		else
76 			sScreenBase[sScreenOffset++] = sColor | string[0];
77 
78 		if (sScreenOffset >= sScreenWidth * sScreenHeight)
79 			scroll_up();
80 
81 		string++;
82 	}
83 	return bufferSize;
84 }
85 
86 
87 //	#pragma mark -
88 
89 
90 void
91 console_clear_screen(void)
92 {
93 	if (gKernelArgs.frame_buffer.enabled)
94 		return;
95 
96 	for (uint32 i = 0; i < sScreenWidth * sScreenHeight; i++)
97 		sScreenBase[i] = sColor;
98 
99 	// reset cursor position as well
100 	sScreenOffset = 0;
101 }
102 
103 
104 int32
105 console_width(void)
106 {
107 	return sScreenWidth;
108 }
109 
110 
111 int32
112 console_height(void)
113 {
114 	return sScreenHeight;
115 }
116 
117 
118 void
119 console_set_cursor(int32 x, int32 y)
120 {
121 	if (y >= (int32)sScreenHeight)
122 		y = sScreenHeight - 1;
123 	else if (y < 0)
124 		y = 0;
125 	if (x >= (int32)sScreenWidth)
126 		x = sScreenWidth - 1;
127 	else if (x < 0)
128 		x = 0;
129 
130 	sScreenOffset = x + y * sScreenWidth;
131 }
132 
133 
134 void
135 console_set_color(int32 foreground, int32 background)
136 {
137 	sColor = (background & 0xf) << 12 | (foreground & 0xf) << 8;
138 }
139 
140 
141 status_t
142 console_init(void)
143 {
144 	// ToDo: make screen size changeable via stage2_args
145 
146 	console_clear_screen();
147 
148 	// enable stdio functionality
149 	stdin = (FILE *)&sInput;
150 	stdout = stderr = (FILE *)&sOutput;
151 
152 	return B_OK;
153 }
154 
155 
156