xref: /haiku/src/system/kernel/debug/blue_screen.cpp (revision 0160c6fbdaf8acbc8814f244e606bc3dae6da5d8)
1f33c8020SAxel Dörfler /*
2f33c8020SAxel Dörfler  * Copyright 2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3f33c8020SAxel Dörfler  * Distributed under the terms of the MIT License.
4f33c8020SAxel Dörfler  */
5f33c8020SAxel Dörfler 
6f33c8020SAxel Dörfler 
7f33c8020SAxel Dörfler #include "blue_screen.h"
8f33c8020SAxel Dörfler 
9f33c8020SAxel Dörfler #include <frame_buffer_console.h>
10f33c8020SAxel Dörfler #include <console.h>
11f33c8020SAxel Dörfler #include <arch/debug_console.h>
12f33c8020SAxel Dörfler 
13f33c8020SAxel Dörfler #include <string.h>
14f33c8020SAxel Dörfler #include <stdio.h>
15f33c8020SAxel Dörfler 
16f33c8020SAxel Dörfler 
17f33c8020SAxel Dörfler #define USE_SCROLLING 0
18f33c8020SAxel Dörfler #define NO_CLEAR 1
19f33c8020SAxel Dörfler 
20f33c8020SAxel Dörfler struct screen_info {
21f33c8020SAxel Dörfler 	int32	columns;
22f33c8020SAxel Dörfler 	int32	rows;
23f33c8020SAxel Dörfler 	int32	x, y;
24f33c8020SAxel Dörfler 	uint8	attr;
25f33c8020SAxel Dörfler } sScreen;
26f33c8020SAxel Dörfler 
27f33c8020SAxel Dörfler console_module_info *sModule;
28f33c8020SAxel Dörfler 
29f33c8020SAxel Dörfler 
30f33c8020SAxel Dörfler static inline void
31f33c8020SAxel Dörfler hide_cursor(void)
32f33c8020SAxel Dörfler {
33f33c8020SAxel Dörfler 	sModule->move_cursor(-1, -1);
34f33c8020SAxel Dörfler }
35f33c8020SAxel Dörfler 
36f33c8020SAxel Dörfler 
37f33c8020SAxel Dörfler static inline void
38f33c8020SAxel Dörfler update_cursor(int32 x, int32 y)
39f33c8020SAxel Dörfler {
40f33c8020SAxel Dörfler 	sModule->move_cursor(x, y);
41f33c8020SAxel Dörfler }
42f33c8020SAxel Dörfler 
43f33c8020SAxel Dörfler 
44f33c8020SAxel Dörfler #if USE_SCROLLING
45f33c8020SAxel Dörfler 
46f33c8020SAxel Dörfler /** scroll from the cursor line up to the top of the scroll region up one line */
47f33c8020SAxel Dörfler 
48f33c8020SAxel Dörfler static void
49f33c8020SAxel Dörfler scroll_up(void)
50f33c8020SAxel Dörfler {
51f33c8020SAxel Dörfler 	// move the screen up one
52f33c8020SAxel Dörfler 	sModule->blit(0, 1, sScreen.columns, sScreen.rows - 1, 0, 0);
53f33c8020SAxel Dörfler 
54f33c8020SAxel Dörfler 	// clear the bottom line
55f33c8020SAxel Dörfler 	sModule->fill_glyph(0, 0, sScreen.columns, 1, ' ', sScreen.attr);
56f33c8020SAxel Dörfler }
57f33c8020SAxel Dörfler #endif
58f33c8020SAxel Dörfler 
59f33c8020SAxel Dörfler 
60f33c8020SAxel Dörfler static void
61f33c8020SAxel Dörfler next_line(void)
62f33c8020SAxel Dörfler {
63f33c8020SAxel Dörfler 	if (sScreen.y == sScreen.rows - 1) {
64f33c8020SAxel Dörfler #if USE_SCROLLING
65f33c8020SAxel Dörfler  		scroll_up();
66f33c8020SAxel Dörfler #else
67f33c8020SAxel Dörfler 		sScreen.y = 0;
68f33c8020SAxel Dörfler #endif
69f33c8020SAxel Dörfler 	} else if (sScreen.y < sScreen.rows - 1) {
70f33c8020SAxel Dörfler 		sScreen.y++;
71f33c8020SAxel Dörfler 	}
72f33c8020SAxel Dörfler 
73f33c8020SAxel Dörfler #if NO_CLEAR
74*0160c6fbSAxel Dörfler 	sModule->fill_glyph(0, (sScreen.y + 2) % sScreen.rows, sScreen.columns, 1, ' ', sScreen.attr);
75f33c8020SAxel Dörfler #endif
76f33c8020SAxel Dörfler 	sScreen.x = 0;
77f33c8020SAxel Dörfler }
78f33c8020SAxel Dörfler 
79f33c8020SAxel Dörfler 
80f33c8020SAxel Dörfler static void
81f33c8020SAxel Dörfler back_space(void)
82f33c8020SAxel Dörfler {
83f33c8020SAxel Dörfler 	if (sScreen.x <= 0)
84f33c8020SAxel Dörfler 		return;
85f33c8020SAxel Dörfler 
86f33c8020SAxel Dörfler 	sScreen.x--;
87f33c8020SAxel Dörfler 	sModule->put_glyph(sScreen.x, sScreen.y, ' ', sScreen.attr);
88f33c8020SAxel Dörfler }
89f33c8020SAxel Dörfler 
90f33c8020SAxel Dörfler 
91f33c8020SAxel Dörfler static void
92f33c8020SAxel Dörfler put_character(char c)
93f33c8020SAxel Dörfler {
94f33c8020SAxel Dörfler 	if (++sScreen.x >= sScreen.columns) {
95f33c8020SAxel Dörfler 		next_line();
96f33c8020SAxel Dörfler 		sScreen.x++;
97f33c8020SAxel Dörfler 	}
98f33c8020SAxel Dörfler 
99f33c8020SAxel Dörfler 	sModule->put_glyph(sScreen.x - 1, sScreen.y, c, sScreen.attr);
100f33c8020SAxel Dörfler }
101f33c8020SAxel Dörfler 
102f33c8020SAxel Dörfler 
103f33c8020SAxel Dörfler static void
104f33c8020SAxel Dörfler parse_character(char c)
105f33c8020SAxel Dörfler {
106f33c8020SAxel Dörfler 	// just output the stuff
107f33c8020SAxel Dörfler 	switch (c) {
108f33c8020SAxel Dörfler 		case '\n':
109f33c8020SAxel Dörfler 			next_line();
110f33c8020SAxel Dörfler 			break;
111f33c8020SAxel Dörfler 		case 0x8:
112f33c8020SAxel Dörfler 			back_space();
113f33c8020SAxel Dörfler 			break;
114f33c8020SAxel Dörfler 		case '\t':
115f33c8020SAxel Dörfler 			put_character(' ');
116f33c8020SAxel Dörfler 			break;
117f33c8020SAxel Dörfler 
118f33c8020SAxel Dörfler 		case '\r':
119f33c8020SAxel Dörfler 		case '\0':
120f33c8020SAxel Dörfler 			break;
121f33c8020SAxel Dörfler 
122f33c8020SAxel Dörfler 		default:
123f33c8020SAxel Dörfler 			put_character(c);
124f33c8020SAxel Dörfler 	}
125f33c8020SAxel Dörfler }
126f33c8020SAxel Dörfler 
127f33c8020SAxel Dörfler 
128f33c8020SAxel Dörfler //	#pragma mark -
129f33c8020SAxel Dörfler 
130f33c8020SAxel Dörfler 
131f33c8020SAxel Dörfler status_t
132f33c8020SAxel Dörfler blue_screen_init(void)
133f33c8020SAxel Dörfler {
134f33c8020SAxel Dörfler 	extern console_module_info gFrameBufferConsoleModule;
135f33c8020SAxel Dörfler 
136f33c8020SAxel Dörfler 	// we can't use get_module() here, since it's too early in the boot process
137f33c8020SAxel Dörfler 
138f33c8020SAxel Dörfler 	if (!frame_buffer_console_available())
139f33c8020SAxel Dörfler 		return B_ERROR;
140f33c8020SAxel Dörfler 
141f33c8020SAxel Dörfler 	sModule = &gFrameBufferConsoleModule;
142f33c8020SAxel Dörfler 	return B_OK;
143f33c8020SAxel Dörfler }
144f33c8020SAxel Dörfler 
145f33c8020SAxel Dörfler 
146f33c8020SAxel Dörfler void
147f33c8020SAxel Dörfler blue_screen_enter(void)
148f33c8020SAxel Dörfler {
149f33c8020SAxel Dörfler 	sScreen.attr = 0x0f;	// black on white
150f33c8020SAxel Dörfler 	sScreen.x = sScreen.y = 0;
151f33c8020SAxel Dörfler 
152f33c8020SAxel Dörfler 	sModule->get_size(&sScreen.columns, &sScreen.rows);
153f33c8020SAxel Dörfler #if !NO_CLEAR
154f33c8020SAxel Dörfler 	sModule->clear(sScreen.attr);
155f33c8020SAxel Dörfler #else
156f33c8020SAxel Dörfler 	sModule->fill_glyph(0, sScreen.y, sScreen.columns, 3, ' ', sScreen.attr);
157f33c8020SAxel Dörfler #endif
158f33c8020SAxel Dörfler }
159f33c8020SAxel Dörfler 
160f33c8020SAxel Dörfler 
161f33c8020SAxel Dörfler char
162f33c8020SAxel Dörfler blue_screen_getchar(void)
163f33c8020SAxel Dörfler {
164f33c8020SAxel Dörfler 	return arch_debug_blue_screen_getchar();
165f33c8020SAxel Dörfler }
166f33c8020SAxel Dörfler 
167f33c8020SAxel Dörfler 
168f33c8020SAxel Dörfler void
169f33c8020SAxel Dörfler blue_screen_putchar(char c)
170f33c8020SAxel Dörfler {
171f33c8020SAxel Dörfler 	hide_cursor();
172f33c8020SAxel Dörfler 
173f33c8020SAxel Dörfler 	parse_character(c);
174f33c8020SAxel Dörfler 
175f33c8020SAxel Dörfler 	update_cursor(sScreen.x, sScreen.y);
176f33c8020SAxel Dörfler }
177f33c8020SAxel Dörfler 
178f33c8020SAxel Dörfler 
179f33c8020SAxel Dörfler void
180f33c8020SAxel Dörfler blue_screen_puts(const char *text)
181f33c8020SAxel Dörfler {
182f33c8020SAxel Dörfler 	hide_cursor();
183f33c8020SAxel Dörfler 
184f33c8020SAxel Dörfler 	while (text[0] != '\0') {
185f33c8020SAxel Dörfler 		parse_character(text[0]);
186f33c8020SAxel Dörfler 		text++;
187f33c8020SAxel Dörfler 	}
188f33c8020SAxel Dörfler 
189f33c8020SAxel Dörfler 	update_cursor(sScreen.x, sScreen.y);
190f33c8020SAxel Dörfler }
191