altos/test: Adjust CRC error rate after FEC fix
[fw/altos] / src / drivers / ao_console.c
1 /*
2  * Copyright © 2016 Keith Packard <keithp@keithp.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  */
14
15 #include "ao.h"
16 #include "ao_console.h"
17 #include "ao_ps2.h"
18 #include "ao_vga.h"
19
20 static uint8_t  console_row, console_col;
21
22 #define ao_console_bitmap       ao_vga_bitmap
23
24 static uint8_t  console_rows, console_cols;
25
26 static void
27 ao_console_scroll(void)
28 {
29         ao_copy(&ao_console_bitmap,
30                 0, 0,
31                 ao_console_bitmap.width,
32                 ao_console_bitmap.height - ao_font.height,
33                 &ao_console_bitmap,
34                 0, ao_font.height,
35                 AO_COPY);
36         ao_rect(&ao_console_bitmap,
37                 0,
38                 (console_rows - 1) * ao_font.height,
39                 ao_console_bitmap.width,
40                 ao_font.height,
41                 1,
42                 AO_COPY);
43 }
44
45 static void
46 ao_console_cursor(void)
47 {
48         ao_rect(&ao_console_bitmap,
49                 console_col * ao_font.width,
50                 console_row * ao_font.height,
51                 ao_font.width,
52                 ao_font.height,
53                 1,
54                 AO_XOR);
55 }
56
57 static void
58 ao_console_clear(void)
59 {
60         ao_rect(&ao_console_bitmap,
61                 0, 0,
62                 ao_console_bitmap.width,
63                 ao_console_bitmap.height,
64                 1,
65                 AO_COPY);
66 }
67
68 static void
69 ao_console_space(void)
70 {
71         ao_rect(&ao_console_bitmap,
72                 console_col * ao_font.width,
73                 console_row * ao_font.height,
74                 ao_font.width,
75                 ao_font.height,
76                 1,
77                 AO_COPY);
78 }
79
80 static void
81 ao_console_newline(void)
82 {
83         if (++console_row == console_rows) {
84                 ao_console_scroll();
85                 console_row--;
86         }
87 }
88
89 void
90 ao_console_putchar(char c)
91 {
92         if (' ' <= c && c < 0x7f) {
93                 char    text[2];
94                 ao_console_space();
95                 text[0] = c;
96                 text[1] = '\0';
97                 ao_text(&ao_console_bitmap,
98                         console_col * ao_font.width,
99                         console_row * ao_font.height + ao_font.ascent,
100                         text,
101                         0,
102                         AO_COPY);
103                 if (++console_col == console_cols) {
104                         console_col = 0;
105                         ao_console_newline();
106                 }
107         } else {
108                 ao_console_cursor();
109                 switch (c) {
110                 case '\r':
111                         console_col = 0;
112                         break;
113                 case '\t':
114                         console_col += 8 - (console_col & 7);
115                         if (console_col >= console_cols) {
116                                 console_col = 0;
117                                 ao_console_newline();
118                         }
119                         break;
120                 case '\n':
121                         ao_console_newline();
122                         break;
123                 case '\f':
124                         console_col = console_row = 0;
125                         ao_console_clear();
126                         break;
127                 case '\177':
128                 case '\010':
129                         if (console_col)
130                                 console_col--;
131                         break;
132                 }
133         }
134         ao_console_cursor();
135 }
136
137 void
138 ao_console_init(void)
139 {
140         console_cols = ao_console_bitmap.width / ao_font.width;
141         console_rows = ao_console_bitmap.height / ao_font.height;
142 #if CONSOLE_STDIN
143         ao_ps2_stdin = 1;
144         ao_add_stdio(_ao_ps2_pollchar,
145                      ao_console_putchar,
146                      NULL);
147 #endif
148         ao_console_clear();
149         ao_console_cursor();
150         ao_vga_enable(1);
151 }