VirtualBox

source: vbox/trunk/src/VBox/Devices/PC/BIOS/print.c@ 87766

Last change on this file since 87766 was 82968, checked in by vboxsync, 5 years ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.3 KB
Line 
1/* $Id: print.c 82968 2020-02-04 10:35:17Z vboxsync $ */
2/** @file
3 * PC BIOS - ???
4 */
5
6/*
7 * Copyright (C) 2006-2020 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 * --------------------------------------------------------------------
17 *
18 * This code is based on:
19 *
20 * ROM BIOS for use with Bochs/Plex86/QEMU emulation environment
21 *
22 * Copyright (C) 2002 MandrakeSoft S.A.
23 *
24 * MandrakeSoft S.A.
25 * 43, rue d'Aboukir
26 * 75002 Paris - France
27 * http://www.linux-mandrake.com/
28 * http://www.mandrakesoft.com/
29 *
30 * This library is free software; you can redistribute it and/or
31 * modify it under the terms of the GNU Lesser General Public
32 * License as published by the Free Software Foundation; either
33 * version 2 of the License, or (at your option) any later version.
34 *
35 * This library is distributed in the hope that it will be useful,
36 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
38 * Lesser General Public License for more details.
39 *
40 * You should have received a copy of the GNU Lesser General Public
41 * License along with this library; if not, write to the Free Software
42 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
43 *
44 */
45
46/*
47 * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
48 * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
49 * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
50 * a choice of LGPL license versions is made available with the language indicating
51 * that LGPLv2 or any later version may be used, or where a choice of which version
52 * of the LGPL is applied is otherwise unspecified.
53 */
54
55
56#include <stdint.h>
57#include <stdarg.h>
58#include "inlines.h"
59#include "biosint.h"
60
61// Debug printf support
62
63/* Redirect INFO output to backdoor logging port. */
64#define INFO_PORT 0x504
65#define DEBUG_PORT 0x403
66
67const char bios_prefix_string[] = "BIOS: ";
68
69void wrch(uint8_t c);
70#pragma aux wrch = "mov ah, 0eh" "int 10h" parm [al] modify exact [ax bx];
71
72void send(uint16_t action, uint8_t c)
73{
74#if BX_DEBUG_SERIAL
75 if (c == '\n')
76 uart_tx_byte(BX_DEBUG_PORT, '\r');
77 uart_tx_byte(BX_DEBUG_PORT, c);
78#endif
79#if BX_VIRTUAL_PORTS
80 if (action & BIOS_PRINTF_DEBUG)
81 outb(DEBUG_PORT, c);
82 if (action & BIOS_PRINTF_INFO)
83 outb(INFO_PORT, c);
84#endif
85 if (action & BIOS_PRINTF_SCREEN) {
86 if (c == '\n')
87 wrch('\r');
88 wrch(c);
89 }
90}
91
92void put_int(uint16_t action, short val, short width, bx_bool neg)
93{
94 short nval = val / 10;
95 if (nval)
96 put_int(action, nval, width - 1, neg);
97 else {
98 while (--width > 0)
99 send(action, ' ');
100 if (neg)
101 send(action, '-');
102 }
103 send(action, val - (nval * 10) + '0');
104}
105
106void put_uint(uint16_t action, unsigned short val, short width, bx_bool neg)
107{
108 unsigned short nval = val / 10;
109 if (nval)
110 put_uint(action, nval, width - 1, neg);
111 else {
112 while (--width > 0)
113 send(action, ' ');
114 if (neg)
115 send(action, '-');
116 }
117 send(action, val - (nval * 10) + '0');
118}
119
120void put_luint(uint16_t action, unsigned long val, short width, bx_bool neg)
121{
122 unsigned long nval = val / 10;
123 if (nval)
124 put_luint(action, nval, width - 1, neg);
125 else {
126 while (--width > 0)
127 send(action, ' ');
128 if (neg)
129 send(action, '-');
130 }
131 send(action, val - (nval * 10) + '0');
132}
133
134void put_str(uint16_t action, const char __far *s)
135{
136 uint8_t c;
137
138 while (c = *s) {
139 send(action, c);
140 s++;
141 }
142}
143
144void put_str_near(uint16_t action, const char __near *s)
145{
146 uint8_t c;
147
148 while (c = *s) {
149 send(action, c);
150 s++;
151 }
152}
153
154
155//--------------------------------------------------------------------------
156// bios_printf()
157// A compact variable argument printf function.
158//
159// Supports %[format_width][length]format
160// where format can be x,X,u,d,s,S,c
161// and the optional length modifier is l (ell, long 32-bit) or ll
162// (long long, 64-bit).
163// Only x,X work with ll
164//--------------------------------------------------------------------------
165void bios_printf(uint16_t action, const char *s, ...)
166{
167 uint8_t c;
168 bx_bool in_format;
169 int i;
170 uint16_t arg, nibble, hibyte, format_width, hexadd;
171 va_list args;
172
173 va_start( args, s );
174
175 in_format = 0;
176 format_width = 0;
177
178 if ((action & BIOS_PRINTF_DEBHALT) == BIOS_PRINTF_DEBHALT) {
179 bios_printf (BIOS_PRINTF_SCREEN, "FATAL: ");
180 }
181
182 while (c = *s) {
183 if ( c == '%' ) {
184 in_format = 1;
185 format_width = 0;
186 }
187 else if (in_format) {
188 if ( (c>='0') && (c<='9') ) {
189 format_width = (format_width * 10) + (c - '0');
190 }
191 else {
192 arg = va_arg( args, uint16_t );
193 if (c == 'x' || c == 'X') {
194 if (format_width == 0)
195 format_width = 4;
196 if (c == 'x')
197 hexadd = 'a';
198 else
199 hexadd = 'A';
200 for (i=format_width-1; i>=0; i--) {
201 nibble = (arg >> (4 * i)) & 0x000f;
202 send (action, (nibble<=9)? (nibble+'0') : (nibble-10+hexadd));
203 }
204 }
205 else if (c == 'u') {
206 put_uint(action, arg, format_width, 0);
207 }
208 else if (c == 'l' && s[1] == 'l') {
209 uint64_t llval;
210 uint16_t __far *cp16;
211
212 s += 2;
213 c = *s;
214 cp16 = (uint16_t __far *)&llval;
215 cp16[0] = arg;
216 cp16[1] = va_arg( args, uint16_t );
217 cp16[2] = va_arg( args, uint16_t );
218 cp16[3] = va_arg( args, uint16_t );
219 if (c == 'x' || c == 'X') {
220 if (format_width == 0)
221 format_width = 16;
222 if (c == 'x')
223 hexadd = 'a';
224 else
225 hexadd = 'A';
226 for (i=format_width-1; i>=0; i--) {
227 nibble = (llval >> (i * 4)) & 0x000f;
228 send (action, (nibble<=9)? (nibble+'0') : (nibble-10+hexadd));
229 }
230 } else {
231 BX_PANIC("bios_printf: unknown %ll format\n");
232 }
233 }
234 else if (c == 'l') {
235 s++;
236 c = *s; /* is it ld,lx,lu? */
237 hibyte = va_arg( args, uint16_t );
238 if (c == 'd') {
239 if (hibyte & 0x8000)
240 put_luint(action, 0L-(((uint32_t) hibyte << 16) | arg), format_width-1, 1);
241 else
242 put_luint(action, ((uint32_t) hibyte << 16) | arg, format_width, 0);
243 }
244 else if (c == 'u') {
245 put_luint(action, ((uint32_t) hibyte << 16) | arg, format_width, 0);
246 }
247 else if (c == 'x' || c == 'X')
248 {
249 if (format_width == 0)
250 format_width = 8;
251 if (c == 'x')
252 hexadd = 'a';
253 else
254 hexadd = 'A';
255 for (i=format_width-1; i>=0; i--) {
256 nibble = ((((uint32_t)hibyte << 16) | arg) >> (4 * i)) & 0x000f;
257 send (action, (nibble<=9)? (nibble+'0') : (nibble-10+hexadd));
258 }
259 }
260 }
261 else if (c == 'd') {
262 if (arg & 0x8000)
263 put_int(action, -arg, format_width - 1, 1);
264 else
265 put_int(action, arg, format_width, 0);
266 }
267 else if (c == 's') {
268 put_str(action, (char *)arg);
269 }
270 else if (c == 'S') {
271 hibyte = arg;
272 arg = va_arg( args, uint16_t );
273 put_str(action, hibyte :> (char *)arg);
274 }
275 else if (c == 'c') {
276 send(action, arg);
277 }
278 else
279 BX_PANIC("bios_printf: unknown format\n");
280 in_format = 0;
281 }
282 }
283 else {
284 send(action, c);
285 }
286 ++s;
287 }
288 va_end( args );
289 if (action & BIOS_PRINTF_HALT) {
290 // freeze in a busy loop.
291 int_disable();
292 halt_forever();
293 }
294}
295
296// End of printf support
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette