source: trunk/hal/x86_64/core/x86_printf.c @ 90

Last change on this file since 90 was 90, checked in by max@…, 5 years ago

scroll for real, and add %c

File size: 5.5 KB
Line 
1/*
2 * x86_printf.c - A printf function for x86 (debug only).
3 *
4 * Copyright (c) [don't know exactly, found on the internet... anyway, this
5 *                file will be removed soon...]
6 *
7 * This file is part of ALMOS-MKH.
8 *
9 * ALMOS-MKH is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; version 2.0 of the License.
12 *
13 * ALMOS-MKH is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with ALMOS-MKH.; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23#include <hal_types.h>
24#include <hal_boot.h>
25#include <hal_internal.h>
26
27#include <memcpy.h>
28#include <thread.h>
29#include <string.h>
30#include <process.h>
31#include <printk.h>
32#include <vmm.h>
33#include <core.h>
34#include <cluster.h>
35
36#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
37#define CONS_X_SIZE     80
38#define CONS_Y_SIZE     26
39
40static char cons_buffer[CONS_X_SIZE * 2 * CONS_Y_SIZE] __in_kdata;
41extern intptr_t iom_base;
42size_t cons_ptr __in_kdata = 0;
43
44void x86_panic(char *msg)
45{
46        x86_printf("!!!!! PANIC !!!!!\n");
47        x86_printf("-> %s\n", msg);
48        x86_printf("!!!!!!!!!!!!!!!!!\n");
49        while (1);
50}
51
52static void check_scroll()
53{
54        char *base = (char *)iom_base + (0xB8000 - IOM_BEGIN);
55        char *src, *dst;
56        size_t i;
57
58        if (cons_ptr < (CONS_X_SIZE * 2) * CONS_Y_SIZE) {
59                return;
60        }
61
62        for (i = 0; i < CONS_Y_SIZE - 1; i++) {
63                dst = (char *)&cons_buffer[0] + i * (CONS_X_SIZE * 2);
64                src = (char *)&cons_buffer[0] + (i + 1) * (CONS_X_SIZE * 2);
65
66                memcpy(dst, src, (CONS_X_SIZE * 2));
67        }
68
69        memset(&cons_buffer[0] + (CONS_X_SIZE * 2) * (CONS_Y_SIZE - 1),
70            0, (CONS_X_SIZE * 2));
71
72        cons_ptr -= (CONS_X_SIZE * 2);
73        memcpy(base, &cons_buffer[0], (CONS_X_SIZE * 2) * (CONS_Y_SIZE - 1));
74}
75
76static void x86_putc(char c)
77{
78        if (c == '\n') {
79                cons_ptr = roundup(cons_ptr, CONS_X_SIZE * 2);
80                check_scroll();
81                return;
82        }
83
84        char *video = (char *)iom_base + (0xB8000 - IOM_BEGIN) + cons_ptr;
85        char *buf = &cons_buffer[cons_ptr];
86        *video = c;
87        *buf = c;
88        cons_ptr++, video++, buf++;
89        *video = 0x7;
90        *buf = 0x7;
91        cons_ptr++, video++, buf++;
92
93        check_scroll();
94}
95
96static void x86_itoa(char *buf, unsigned long int n, int base)
97{
98        unsigned long int tmp;
99        int i, j;
100
101        tmp = n;
102        i = 0;
103
104        do {
105                tmp = n % base;
106                buf[i++] = (tmp < 10) ? (tmp + '0') : (tmp + 'a' - 10);
107        } while (n /= base);
108        buf[i--] = 0;
109
110        for (j = 0; j < i; j++, i--) {
111                tmp = buf[j];
112                buf[j] = buf[i];
113                buf[i] = tmp;
114        }
115}
116
117static void x86_ztoa(char *buf, uint64_t n, uint64_t base)
118{
119        uint64_t tmp;
120        int i, j;
121
122        tmp = n;
123        i = 0;
124
125        do {
126                tmp = n % base;
127                buf[i++] = (tmp < 10) ? (tmp + '0') : (tmp + 'a' - 10);
128        } while (n /= base);
129        buf[i--] = 0;
130
131        for (j = 0; j < i; j++, i--) {
132                tmp = buf[j];
133                buf[j] = buf[i];
134                buf[i] = tmp;
135        }
136}
137
138static char alphabet[] = "abcdefghijklmnopqrstuvwxyz";
139
140void x86_printf(char *s, ...)
141{
142        va_list ap;
143
144        char buf[64];
145        int i, j, size, buflen, neg;
146
147        unsigned char c;
148        int ival;
149        unsigned int uival;
150        uint64_t zval;
151
152        va_start(ap, s);
153
154        while ((c = *s++)) {
155                size = 0;
156                neg = 0;
157
158                if (c == 0)
159                        break;
160                else if (c == '%') {
161                        c = *s++;
162                        if (c >= '0' && c <= '9') {
163                                size = c - '0';
164                                c = *s++;
165                        }
166
167                        if (c == 'c') {
168                                ival = va_arg(ap, int);
169                                if ((ival - 97) > sizeof(alphabet)) {
170                                        x86_printf("(unknown:%d)", ival);
171                                } else {
172                                        x86_putc(alphabet[ival - 97]);
173                                }
174                        } else if (c == 'z') {
175                                zval = va_arg(ap, uint64_t);
176                                x86_ztoa(buf, zval, 10);
177
178                                buflen = strlen(buf);
179                                if (buflen < size)
180                                        for (i = size, j = buflen; i >= 0; i--, j--)
181                                                buf[i] = (j >= 0) ? buf[j] : '0';
182
183                                x86_printf(buf);
184                        } else if (c == 'Z') {
185                                zval = va_arg(ap, uint64_t);
186                                x86_ztoa(buf, zval, 16);
187
188                                buflen = strlen(buf);
189                                if (buflen < size)
190                                        for (i = size, j = buflen; i >= 0; i--, j--)
191                                                buf[i] = (j >= 0) ? buf[j] : '0';
192
193                                x86_printf("0x%s", buf);
194                        } else if (c == 'd') {
195                                ival = va_arg(ap, int);
196                                if (ival < 0) {
197                                        uival = 0 - ival;
198                                        neg++;
199                                } else
200                                        uival = ival;
201                                x86_itoa(buf, uival, 10);
202
203                                buflen = strlen(buf);
204                                if (buflen < size)
205                                        for (i = size, j = buflen; i >= 0;
206                                             i--, j--)
207                                                buf[i] =
208                                                    (j >=
209                                                     0) ? buf[j] : '0';
210
211                                if (neg)
212                                        x86_printf("-%s", buf);
213                                else
214                                        x86_printf(buf);
215                        } else if (c == 'u') {
216                                uival = va_arg(ap, int);
217                                x86_itoa(buf, uival, 10);
218
219                                buflen = strlen(buf);
220                                if (buflen < size)
221                                        for (i = size, j = buflen; i >= 0;
222                                             i--, j--)
223                                                buf[i] =
224                                                    (j >=
225                                                     0) ? buf[j] : '0';
226
227                                x86_printf(buf);
228                        } else if (c == 'x' || c == 'X') {
229                                uival = va_arg(ap, int);
230                                x86_itoa(buf, uival, 16);
231
232                                buflen = strlen(buf);
233                                if (buflen < size)
234                                        for (i = size, j = buflen; i >= 0;
235                                             i--, j--)
236                                                buf[i] =
237                                                    (j >=
238                                                     0) ? buf[j] : '0';
239
240                                x86_printf("0x%s", buf);
241                        } else if (c == 'p') {
242                                uival = va_arg(ap, int);
243                                x86_itoa(buf, uival, 16);
244                                size = 8;
245
246                                buflen = strlen(buf);
247                                if (buflen < size)
248                                        for (i = size, j = buflen; i >= 0;
249                                             i--, j--)
250                                                buf[i] =
251                                                    (j >=
252                                                     0) ? buf[j] : '0';
253
254                                x86_printf("0x%s", buf);
255                        } else if (c == 's') {
256                                x86_printf((char *) va_arg(ap, uint64_t));
257                        } 
258                } else
259                        x86_putc(c);
260        }
261
262        return;
263}
Note: See TracBrowser for help on using the repository browser.