Kaynağa Gözat

Add basic ANSI escape sequence support to BIOS console

tags/v0.9.3
Michael Brown 18 yıl önce
ebeveyn
işleme
8b3a4c9862

+ 139
- 1
src/arch/i386/firmware/pcbios/bios_console.c Dosyayı Görüntüle

@@ -16,8 +16,131 @@
16 16
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 17
  */
18 18
 
19
+#include <assert.h>
19 20
 #include <realmode.h>
20 21
 #include <console.h>
22
+#include <gpxe/ansiesc.h>
23
+
24
+#define ATTR_BOLD		0x08
25
+
26
+#define ATTR_FCOL_MASK		0x07
27
+#define ATTR_FCOL_BLACK		0x00
28
+#define ATTR_FCOL_BLUE		0x01
29
+#define ATTR_FCOL_GREEN		0x02
30
+#define ATTR_FCOL_CYAN		0x03
31
+#define ATTR_FCOL_RED		0x04
32
+#define ATTR_FCOL_MAGENTA	0x05
33
+#define ATTR_FCOL_YELLOW	0x06
34
+#define ATTR_FCOL_WHITE		0x07
35
+
36
+#define ATTR_BCOL_MASK		0x70
37
+#define ATTR_BCOL_BLACK		0x00
38
+#define ATTR_BCOL_BLUE		0x10
39
+#define ATTR_BCOL_GREEN		0x20
40
+#define ATTR_BCOL_CYAN		0x30
41
+#define ATTR_BCOL_RED		0x40
42
+#define ATTR_BCOL_MAGENTA	0x50
43
+#define ATTR_BCOL_YELLOW	0x60
44
+#define ATTR_BCOL_WHITE		0x70
45
+
46
+#define ATTR_DEFAULT		ATTR_FCOL_WHITE
47
+
48
+/** Current character attribute */
49
+static unsigned int bios_attr = ATTR_DEFAULT;
50
+
51
+/**
52
+ * Handle ANSI CUP (cursor position)
53
+ *
54
+ * @v count		Parameter count
55
+ * @v params[0]		Row (1 is top)
56
+ * @v params[1]		Column (1 is left)
57
+ */
58
+static void bios_handle_cup ( unsigned int count __unused, int params[] ) {
59
+	int cx = ( params[1] - 1 );
60
+	int cy = ( params[0] - 1 );
61
+
62
+	if ( cx < 0 )
63
+		cx = 0;
64
+	if ( cy < 0 )
65
+		cy = 0;
66
+
67
+	__asm__ __volatile__ ( REAL_CODE ( "sti\n\t"
68
+					   "int $0x10\n\t"
69
+					   "cli\n\t" )
70
+			       : : "a" ( 0x0200 ), "b" ( 1 ),
71
+			           "d" ( ( cy << 8 ) | cx ) );
72
+}
73
+
74
+/**
75
+ * Handle ANSI ED (erase in page)
76
+ *
77
+ * @v count		Parameter count
78
+ * @v params[0]		Region to erase
79
+ */
80
+static void bios_handle_ed ( unsigned int count __unused,
81
+			     int params[] __unused ) {
82
+	/* We assume that we always clear the whole screen */
83
+	assert ( params[0] == ANSIESC_ED_ALL );
84
+
85
+	__asm__ __volatile__ ( REAL_CODE ( "sti\n\t"
86
+					   "int $0x10\n\t"
87
+					   "cli\n\t" )
88
+			       : : "a" ( 0x0600 ), "b" ( bios_attr << 8 ),
89
+			           "c" ( 0 ), "d" ( 0xffff ) );
90
+}
91
+
92
+/**
93
+ * Handle ANSI SGR (set graphics rendition)
94
+ *
95
+ * @v count		Parameter count
96
+ * @v params		List of graphic rendition aspects
97
+ */
98
+static void bios_handle_sgr ( unsigned int count, int params[] ) {
99
+	static const uint8_t bios_attr_fcols[10] = {
100
+		ATTR_FCOL_BLACK, ATTR_FCOL_RED, ATTR_FCOL_GREEN,
101
+		ATTR_FCOL_YELLOW, ATTR_FCOL_BLUE, ATTR_FCOL_MAGENTA,
102
+		ATTR_FCOL_CYAN, ATTR_FCOL_WHITE,
103
+		ATTR_FCOL_WHITE, ATTR_FCOL_WHITE /* defaults */
104
+	};
105
+	static const uint8_t bios_attr_bcols[10] = {
106
+		ATTR_BCOL_BLACK, ATTR_BCOL_RED, ATTR_BCOL_GREEN,
107
+		ATTR_BCOL_YELLOW, ATTR_BCOL_BLUE, ATTR_BCOL_MAGENTA,
108
+		ATTR_BCOL_CYAN, ATTR_BCOL_WHITE,
109
+		ATTR_BCOL_BLACK, ATTR_BCOL_BLACK /* defaults */
110
+	};
111
+	unsigned int i;
112
+	int aspect;
113
+
114
+	for ( i = 0 ; i < count ; i++ ) {
115
+		aspect = params[i];
116
+		if ( aspect == 0 ) {
117
+			bios_attr = ATTR_DEFAULT;
118
+		} else if ( aspect == 1 ) {
119
+			bios_attr |= ATTR_BOLD;
120
+		} else if ( aspect == 22 ) {
121
+			bios_attr &= ~ATTR_BOLD;
122
+		} else if ( ( aspect >= 30 ) && ( aspect <= 39 ) ) {
123
+			bios_attr &= ~ATTR_FCOL_MASK;
124
+			bios_attr |= bios_attr_fcols[ aspect - 30 ];
125
+		} else if ( ( aspect >= 40 ) && ( aspect <= 49 ) ) {
126
+			bios_attr &= ~ATTR_BCOL_MASK;
127
+			bios_attr |= bios_attr_bcols[ aspect - 40 ];
128
+		}
129
+	}
130
+}
131
+
132
+/** BIOS console ANSI escape sequence handlers */
133
+static struct ansiesc_handler bios_ansiesc_handlers[] = {
134
+	{ ANSIESC_CUP, bios_handle_cup },
135
+	{ ANSIESC_ED, bios_handle_ed },
136
+	{ ANSIESC_SGR, bios_handle_sgr },
137
+	{ 0, NULL }
138
+};
139
+
140
+/** BIOS console ANSI escape sequence context */
141
+static struct ansiesc_context bios_ansiesc_ctx = {
142
+	.handlers = bios_ansiesc_handlers,
143
+};
21 144
 
22 145
 /**
23 146
  * Print a character to BIOS console
@@ -26,10 +149,25 @@
26 149
  */
27 150
 static void bios_putchar ( int character ) {
28 151
 
152
+	/* Intercept ANSI escape sequences */
153
+	character = ansiesc_process ( &bios_ansiesc_ctx, character );
154
+	if ( character < 0 )
155
+		return;
156
+
157
+	/* Set attribute for printable characters */
158
+	if ( character >= 0x20 ) {
159
+		__asm__ __volatile__ ( REAL_CODE ( "sti\n\t"
160
+						   "int $0x10\n\t"
161
+						   "cli\n\t" )
162
+				       : : "a" ( 0x0920 ), "b" ( bios_attr ),
163
+				           "c" ( 1 ) );
164
+	}
165
+
166
+	/* Print the character */
29 167
 	__asm__ __volatile__ ( REAL_CODE ( "sti\n\t"
30 168
 					   "int $0x10\n\t"
31 169
 					   "cli\n\t" )
32
-			       : : "a" ( character | 0x0e00 ), "b" ( 1 )
170
+			       : : "a" ( character | 0x0e00 ), "b" ( 0 )
33 171
 			       : "ebp" );
34 172
 }
35 173
 

+ 17
- 2
src/include/gpxe/ansiesc.h Dosyayı Görüntüle

@@ -93,8 +93,23 @@ struct ansiesc_context {
93 93
  * @{
94 94
  */
95 95
 
96
-/** Character and line position */
97
-#define ANSIESC_HVP 'f'
96
+/** Cursor position */
97
+#define ANSIESC_CUP 'H'
98
+
99
+/** Erase in page */
100
+#define ANSIESC_ED 'J'
101
+
102
+/** Erase from cursor to end of page */
103
+#define ANSIESC_ED_TO_END 0
104
+
105
+/** Erase from start of page to cursor */
106
+#define ANSIESC_ED_FROM_START 1
107
+
108
+/** Erase whole page */
109
+#define ANSIESC_ED_ALL 2
110
+
111
+/** Select graphic rendition */
112
+#define ANSIESC_SGR 'm'
98 113
 
99 114
 /** @} */
100 115
 

Loading…
İptal
Kaydet