Initial checkin.
[people/mcb30/legacybios.git] / src / output.c
1 // Raw screen writing code.
2 //
3 // Copyright (C) 2008  Kevin O'Connor <kevin@koconnor.net>
4 //
5 // This file may be distributed under the terms of the GNU GPLv3 license.
6
7 #include <stdarg.h> // va_list
8
9 #include "farptr.h" // GET_VAR
10 #include "util.h" // bprintf
11 #include "biosvar.h" // struct bregs
12
13 static void
14 screenc(char c)
15 {
16     // XXX
17 }
18
19 // XXX
20 #define PORT_DEBUG  0x403
21
22 // Write a charcter to the framebuffer.
23 static void
24 putc(u16 action, char c)
25 {
26     screenc(c);
27     outb(c, PORT_DEBUG);
28 }
29
30 // Write a string to the framebuffer.
31 static void
32 puts(u16 action, const char *s)
33 {
34     for (; *s; s++)
35         putc(action, *s);
36 }
37
38 // Write a string to the framebuffer.
39 static void
40 puts_cs(u16 action, const char *s)
41 {
42     for (;; s++) {
43         char c = GET_VAR(CS, (u8)*s);
44         if (!c)
45             break;
46         putc(action, c);
47     }
48 }
49
50 // Write an unsigned integer to the screen.
51 static void
52 putuint(u16 action, u32 val)
53 {
54     char buf[12];
55     char *d = &buf[sizeof(buf) - 1];
56     *d-- = '\0';
57     for (;;) {
58         *d = val % 10;
59         val /= 10;
60         if (!val)
61             break;
62         d--;
63     }
64     puts(action, d);
65 }
66
67 // Write a single digit hex character to the screen.
68 static inline void
69 putsinglehex(u16 action, u32 val)
70 {
71     if (val <= 9)
72         val = '0' + val;
73     else
74         val = 'a' + val - 10;
75     putc(action, val);
76 }
77
78 // Write an integer in hexadecimal to the screen.
79 static void
80 puthex(u16 action, u32 val)
81 {
82     putsinglehex(action, (val >> 28) & 0xf);
83     putsinglehex(action, (val >> 24) & 0xf);
84     putsinglehex(action, (val >> 20) & 0xf);
85     putsinglehex(action, (val >> 16) & 0xf);
86     putsinglehex(action, (val >> 12) & 0xf);
87     putsinglehex(action, (val >> 8) & 0xf);
88     putsinglehex(action, (val >> 4) & 0xf);
89     putsinglehex(action, (val >> 0) & 0xf);
90 }
91
92 void
93 bprintf(u16 action, const char *fmt, ...)
94 {
95     va_list args;
96     va_start(args, fmt);
97     const char *s = fmt;
98     for (;; s++) {
99         char c = GET_VAR(CS, (u8)*s);
100         if (!c)
101             break;
102         if (c != '%') {
103             putc(action, c);
104             continue;
105         }
106         const char *n = s+1;
107         c = GET_VAR(CS, (u8)*n);
108         s32 val;
109         const char *sarg;
110         switch (c) {
111         case '%':
112             putc(action, '%');
113             break;
114         case 'd':
115             val = va_arg(args, s32);
116             if (val < 0) {
117                 putc(action, '-');
118                 val = -val;
119             }
120             putuint(action, val);
121             break;
122         case 'u':
123             val = va_arg(args, s32);
124             putuint(action, val);
125             break;
126         case 'x':
127             val = va_arg(args, s32);
128             puthex(action, val);
129             break;
130         case 's':
131             sarg = va_arg(args, const char *);
132             puts_cs(action, sarg);
133             break;
134         default:
135             putc(action, *s);
136             n = s;
137         }
138         s = n;
139     }
140     va_end(args);
141 }
142
143 // Function called on handler startup.
144 void
145 __debug_enter(const char *fname, struct bregs *regs)
146 {
147     bprintf(0, "enter %s: a=%x b=%x c=%x d=%x si=%x di=%x\n"
148             , fname, regs->eax, regs->ebx, regs->ecx, regs->edx
149             , regs->esi, regs->edi);
150     bprintf(0, "&=%x ds=%x es=%x bp=%x sp=%x ip=%x cs=%x f=%x\n"
151             , (u32)regs, regs->ds, regs->es, regs->ebp, regs->esp
152             , regs->ip, regs->cs, regs->flags);
153 }
154
155 void
156 __debug_exit(const char *fname, struct bregs *regs)
157 {
158     bprintf(0, "exit %s: a=%x b=%x c=%x d=%x s=%x i=%x\n"
159             , fname, regs->eax, regs->ebx, regs->ecx, regs->edx
160             , regs->esi, regs->edi);
161 }