xref: /haiku/src/system/boot/platform/next_m68k/console.cpp (revision 4c8e85b316c35a9161f5a1c50ad70bc91c83a76f)
1 /*
2  * Copyright 2007-2010, Haiku, Inc. All Rights Reserved.
3  * Distributed under the terms of the MIT license.
4  *
5  * Author:
6  *		François Revol, revol@free.fr.
7  */
8 
9 #include <SupportDefs.h>
10 #include <string.h>
11 #include "nextrom.h"
12 #include <util/kernel_cpp.h>
13 
14 #include "console.h"
15 #include "keyboard.h"
16 
17 
18 static bool sForceBW = false;	// force black & white for Milan
19 
20 // bootrom has more console info but we don't know the structure
21 // so we just use getc & putc for now.
22 
23 class Console : public ConsoleNode {
24 	public:
25 		Console();
26 
27 		virtual ssize_t ReadAt(void *cookie, off_t pos, void *buffer,
28 			size_t bufferSize);
29 		virtual ssize_t WriteAt(void *cookie, off_t pos, const void *buffer,
30 			size_t bufferSize);
31 
32 		virtual void	ClearScreen();
33 		virtual int32	Width();
34 		virtual int32	Height();
35 		virtual void	SetCursor(int32 x, int32 y);
36 		virtual void	SetCursorVisible(bool visible);
37 		virtual void	SetColors(int32 foreground, int32 background);
38 };
39 
40 
41 extern ConsoleNode* gConsoleNode;
42 static Console sConsole;
43 FILE *stdin, *stdout, *stderr;
44 
45 
46 Console::Console()
47 	: ConsoleNode()
48 {
49 }
50 
51 
52 ssize_t
53 Console::ReadAt(void */*cookie*/, off_t /*pos*/, void *_buffer,
54 	size_t bufferSize)
55 {
56 	char *buffer = (char*)_buffer;
57 	int c;
58 	ssize_t bytesTotal = 0;
59 
60 	while (bytesTotal < bufferSize && (c = mg->mg_try_getc())) {
61 		*buffer++ = (char)c;
62 		bytesTotal++;
63 	}
64 
65 	return bytesTotal;
66 }
67 
68 
69 ssize_t
70 Console::WriteAt(void */*cookie*/, off_t /*pos*/, const void *buffer,
71 	size_t bufferSize)
72 {
73 	const char *string = (const char *)buffer;
74 	size_t i;
75 
76 	for (i = 0; i < bufferSize; i++) {
77 		if (string[i] == '\0')
78 			break;
79 		mg->mg_putc(string[i]);
80 	}
81 
82 	return bufferSize;
83 }
84 
85 
86 void
87 Console::ClearScreen()
88 {
89 	sConsole.WriteAt(NULL, 0LL, "\033E", 2);
90 }
91 
92 
93 int32
94 Console::Width()
95 {
96 	int columnCount = 80; //XXX: check video mode
97 	return columnCount;
98 }
99 
100 
101 int32
102 Console::Height()
103 {
104 	int lineCount = 25; //XXX: check video mode
105 	return lineCount;
106 }
107 
108 
109 void
110 Console::SetCursor(int32 x, int32 y)
111 {
112 	char buff[] = "\033Y  ";
113 	x = MIN(79,MAX(0,x));
114 	y = MIN(24,MAX(0,y));
115 	buff[3] += (char)x;
116 	buff[2] += (char)y;
117 	sConsole.WriteAt(NULL, 0LL, buff, 4);
118 }
119 
120 
121 static int
122 translate_color(int32 color)
123 {
124 	/*
125 			r	g	b
126 		0:	0	0	0		// black
127 		1:	0	0	aa		// dark blue
128 		2:	0	aa	0		// dark green
129 		3:	0	aa	aa		// cyan
130 		4:	aa	0	0		// dark red
131 		5:	aa	0	aa		// purple
132 		6:	aa	55	0		// brown
133 		7:	aa	aa	aa		// light gray
134 		8:	55	55	55		// dark gray
135 		9:	55	55	ff		// light blue
136 		a:	55	ff	55		// light green
137 		b:	55	ff	ff		// light cyan
138 		c:	ff	55	55		// light red
139 		d:	ff	55	ff		// magenta
140 		e:	ff	ff	55		// yellow
141 		f:	ff	ff	ff		// white
142 	*/
143 	// cf. http://www.fortunecity.com/skyscraper/apple/308/html/chap4.htm
144 	static const char cmap[] = {
145 		15, 4, 2, 6, 1, 5, 3, 7,
146 		8, 12, 10, 14, 9, 13, 11, 0 };
147 
148 	if (color < 0 || color >= 16)
149 		return 0;
150 	return cmap[color];
151 	//return color;
152 }
153 
154 
155 void
156 Console::SetColors(int32 foreground, int32 background)
157 {
158 	char buff[] = "\033b \033c ";
159 	if (sForceBW) {
160 		if (background == 0) {
161 			foreground = 15;
162 		} else {
163 			background = 15;
164 			foreground = 0;
165 		}
166 	}
167 	buff[2] += (char)translate_color(foreground);
168 	buff[5] += (char)translate_color(background);
169 	sConsole.WriteAt(NULL, 0LL, buff, 6);
170 }
171 
172 
173 void
174 Console::SetCursorVisible(bool)
175 {
176 	// TODO?
177 }
178 
179 
180 //	#pragma mark -
181 
182 
183 static void
184 dump_colors()
185 {
186 	int bg, fg;
187 	dprintf("colors:\n");
188 	for (bg = 0; bg < 16; bg++) {
189 		for (fg = 0; fg < 16; fg++) {
190 			console_set_color(fg, bg);
191 			dprintf("#");
192 		}
193 		console_set_color(0, 15);
194 		dprintf("\n");
195 	}
196 }
197 
198 
199 status_t
200 console_init(void)
201 {
202 	gConsoleNode = &sConsole;
203 
204 	// now that we're initialized, enable stdio functionality
205 	stdin = (FILE *)&sConsole;
206 	stdout = stderr = (FILE *)&sConsole;
207 
208 	//dump_colors();
209 
210 	return B_OK;
211 }
212 
213 
214 // #pragma mark -
215 
216 
217 int
218 console_wait_for_key(void)
219 {
220 #if 0
221 	// XXX: do this way and remove keyboard.cpp ?
222 	// wait for a key
223 	char buffer[3];
224 	ssize_t bytesRead;
225 	do {
226 		bytesRead = sConsole.ReadAt(NULL, 0, buffer, 3);
227 		if (bytesRead < 0)
228 			return 0;
229 	} while (bytesRead == 0);
230 #endif
231 	union key key = wait_for_key();
232 
233 	if (key.code.ascii == 0) {
234 		switch (key.code.bios) {
235 			case BIOS_KEY_UP:
236 				return TEXT_CONSOLE_KEY_UP;
237 			case BIOS_KEY_DOWN:
238 				return TEXT_CONSOLE_KEY_DOWN;
239 			case BIOS_KEY_PAGE_UP:
240 				return TEXT_CONSOLE_KEY_PAGE_UP;
241 			case BIOS_KEY_PAGE_DOWN:
242 				return TEXT_CONSOLE_KEY_PAGE_DOWN;
243 			case BIOS_KEY_HOME:
244 				return TEXT_CONSOLE_KEY_HOME;
245 			case BIOS_KEY_END:
246 				return TEXT_CONSOLE_KEY_END;
247 			default:
248 				return 0;
249 		}
250 	} else
251 		return key.code.ascii;
252 }
253