xref: /haiku/src/system/boot/platform/atari_m68k/console.cpp (revision e1c4049fed1047bdb957b0529e1921e97ef94770)
1 /*
2  * Copyright 2007-2023, 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 "toscalls.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 
21 // TOS emulates a VT52
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 		void ClearScreen();
33 		int32 Width();
34 		int32 Height();
35 		void SetCursor(int32 x, int32 y);
36 		void SetCursorVisible(bool visible);
37 		void SetColors(int32 foreground, int32 background);
38 	private:
39 		int16 fHandle;
40 };
41 
42 
43 extern ConsoleNode* gConsoleNode;
44 static Console sConsole;
45 FILE *stdin, *stdout, *stderr;
46 
47 
48 Console::Console()
49 	: ConsoleNode(), fHandle(DEV_CONSOLE)
50 {
51 }
52 
53 
54 ssize_t
55 Console::ReadAt(void */*cookie*/, off_t /*pos*/, void *buffer,
56 	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,
66 	size_t bufferSize)
67 {
68 	const char *string = (const char *)buffer;
69 	size_t i;
70 
71 	// be nice to our audience and replace single "\n" with "\r\n"
72 
73 	for (i = 0; i < bufferSize; i++) {
74 		if (string[i] == '\0')
75 			break;
76 		if (string[i] == '\n')
77 			Bconout(fHandle, '\r');
78 		Bconout(fHandle, string[i]);
79 	}
80 
81 	return bufferSize;
82 }
83 
84 
85 void
86 Console::ClearScreen()
87 {
88 	Write("\033E", 2);
89 }
90 
91 
92 int32
93 Console::Width()
94 {
95 	return 80;
96 }
97 
98 
99 int32
100 Console::Height()
101 {
102 	return 25;
103 }
104 
105 
106 void
107 Console::SetCursor(int32 x, int32 y)
108 {
109 	char buff[] = "\033Y  ";
110 	x = MIN(79,MAX(0,x));
111 	y = MIN(24,MAX(0,y));
112 	buff[3] += (char)x;
113 	buff[2] += (char)y;
114 	Write(buff, 4);
115 }
116 
117 
118 void
119 Console::SetCursorVisible(bool visible)
120 {
121 	// TODO
122 }
123 
124 static int
125 translate_color(int32 color)
126 {
127 	/*
128 			r	g	b
129 		0:	0	0	0		// black
130 		1:	0	0	aa		// dark blue
131 		2:	0	aa	0		// dark green
132 		3:	0	aa	aa		// cyan
133 		4:	aa	0	0		// dark red
134 		5:	aa	0	aa		// purple
135 		6:	aa	55	0		// brown
136 		7:	aa	aa	aa		// light gray
137 		8:	55	55	55		// dark gray
138 		9:	55	55	ff		// light blue
139 		a:	55	ff	55		// light green
140 		b:	55	ff	ff		// light cyan
141 		c:	ff	55	55		// light red
142 		d:	ff	55	ff		// magenta
143 		e:	ff	ff	55		// yellow
144 		f:	ff	ff	ff		// white
145 	*/
146 	// cf. http://www.fortunecity.com/skyscraper/apple/308/html/chap4.htm
147 	static const char cmap[] = {
148 		15, 4, 2, 6, 1, 5, 3, 7,
149 		8, 12, 10, 14, 9, 13, 11, 0 };
150 
151 	if (color < 0 || color >= 16)
152 		return 0;
153 	return cmap[color];
154 }
155 
156 
157 void
158 Console::SetColors(int32 foreground, int32 background)
159 {
160 	char buff[] = "\033b \033c ";
161 	if (sForceBW) {
162 		if (background == 0)
163 			foreground = 15;
164 		else {
165 			background = 15;
166 			foreground = 0;
167 		}
168 
169 	}
170 	buff[2] += (char)translate_color(foreground);
171 	buff[5] += (char)translate_color(background);
172 	Write(buff, 6);
173 }
174 
175 
176 //	#pragma mark -
177 
178 
179 constexpr bool kDumpColors = false;
180 constexpr bool kDumpMilanModes = false;
181 
182 static void
183 dump_colors()
184 {
185 	int bg, fg;
186 	dprintf("colors:\n");
187 	for (bg = 0; bg < 16; bg++) {
188 		for (fg = 0; fg < 16; fg++) {
189 			console_set_color(fg, bg);
190 			dprintf("#");
191 		}
192 		console_set_color(0, 15);
193 		dprintf("\n");
194 	}
195 }
196 
197 
198 static int32
199 dump_milan_modes(SCREENINFO *info, uint32 flags)
200 {
201 	dprintf("mode: %d '%s':\n flags %08" B_PRIx32 " @%08" B_PRIx32 " %dx%d (%dx%d)\n%d planes %d colors fmt %08" B_PRIx32 "\n",
202 		info->devID, info->name, info->scrFlags, info->frameadr,
203 		info->scrWidth, info->scrHeight,
204 		info->virtWidth, info->virtHeight,
205 		info->scrPlanes, info->scrColors, info->scrFormat);
206 	return ENUMMODE_CONT;
207 }
208 
209 status_t
210 console_init(void)
211 {
212 	gConsoleNode = &sConsole;
213 
214 	console_clear_screen();
215 
216 	// enable stdio functionality
217 	stdin = (FILE *)&sConsole;
218 	stdout = stderr = (FILE *)&sConsole;
219 
220 	if (tos_find_cookie('_MIL')) {
221 		dprintf("Milan detected... forcing black & white\n");
222 		if (kDumpMilanModes) {
223 			dprintf("Getrez() = %d\n", Getrez());
224 			Setscreen(-1, &dump_milan_modes, MI_MAGIC, CMD_ENUMMODES);
225 			Setscreen((void*)-1, (void*)-1, 0, 0);
226 		}
227 		sForceBW = true;
228 	}
229 
230 	if (kDumpColors)
231 		dump_colors();
232 
233 	return B_OK;
234 }
235 
236 
237 // #pragma mark -
238 
239 
240 int
241 console_wait_for_key(void)
242 {
243 #if 0
244 	// XXX: do this way and remove keyboard.cpp ?
245 	// wait for a key
246 	char buffer[3];
247 	ssize_t bytesRead;
248 	do {
249 		bytesRead = sInput.ReadAt(NULL, 0, buffer, 3);
250 		if (bytesRead < 0)
251 			return 0;
252 	} while (bytesRead == 0);
253 #endif
254 	union key key = wait_for_key();
255 
256 	if (key.code.ascii == 0) {
257 		switch (key.code.bios) {
258 			case BIOS_KEY_UP:
259 				return TEXT_CONSOLE_KEY_UP;
260 			case BIOS_KEY_DOWN:
261 				return TEXT_CONSOLE_KEY_DOWN;
262 			case BIOS_KEY_PAGE_UP:
263 				return TEXT_CONSOLE_KEY_PAGE_UP;
264 			case BIOS_KEY_PAGE_DOWN:
265 				return TEXT_CONSOLE_KEY_PAGE_DOWN;
266 			case BIOS_KEY_HOME:
267 				return TEXT_CONSOLE_KEY_HOME;
268 			case BIOS_KEY_END:
269 				return TEXT_CONSOLE_KEY_END;
270 			default:
271 				return 0;
272 		}
273 	} else
274 		return key.code.ascii;
275 }
276 
277