blob: 0dcd20d7c80e1dfe4baead9f65401c48a5684892 [file] [log] [blame]
Kevin O'Connorf076a3e2008-02-25 22:25:15 -05001// 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
13static void
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050014screenc(u8 c)
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050015{
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050016 struct bregs br;
17 memset(&br, 0, sizeof(br));
18 br.ah = 0x0e;
19 br.al = c;
20 call16_int(0x10, &br);
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050021}
22
23// XXX
24#define PORT_DEBUG 0x403
25
26// Write a charcter to the framebuffer.
27static void
28putc(u16 action, char c)
29{
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050030 outb(c, PORT_DEBUG);
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050031 if (action) {
32 if (c == '\n')
33 screenc('\r');
34 screenc(c);
35 }
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050036}
37
38// Write a string to the framebuffer.
39static void
40puts(u16 action, const char *s)
41{
42 for (; *s; s++)
43 putc(action, *s);
44}
45
46// Write a string to the framebuffer.
47static void
48puts_cs(u16 action, const char *s)
49{
50 for (;; s++) {
51 char c = GET_VAR(CS, (u8)*s);
52 if (!c)
53 break;
54 putc(action, c);
55 }
56}
57
58// Write an unsigned integer to the screen.
59static void
60putuint(u16 action, u32 val)
61{
62 char buf[12];
63 char *d = &buf[sizeof(buf) - 1];
64 *d-- = '\0';
65 for (;;) {
Kevin O'Connor4b60c002008-02-25 22:29:55 -050066 *d = (val % 10) + '0';
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050067 val /= 10;
68 if (!val)
69 break;
70 d--;
71 }
72 puts(action, d);
73}
74
75// Write a single digit hex character to the screen.
76static inline void
77putsinglehex(u16 action, u32 val)
78{
79 if (val <= 9)
80 val = '0' + val;
81 else
82 val = 'a' + val - 10;
83 putc(action, val);
84}
85
86// Write an integer in hexadecimal to the screen.
87static void
88puthex(u16 action, u32 val)
89{
90 putsinglehex(action, (val >> 28) & 0xf);
91 putsinglehex(action, (val >> 24) & 0xf);
92 putsinglehex(action, (val >> 20) & 0xf);
93 putsinglehex(action, (val >> 16) & 0xf);
94 putsinglehex(action, (val >> 12) & 0xf);
95 putsinglehex(action, (val >> 8) & 0xf);
96 putsinglehex(action, (val >> 4) & 0xf);
97 putsinglehex(action, (val >> 0) & 0xf);
98}
99
100void
101bprintf(u16 action, const char *fmt, ...)
102{
103 va_list args;
104 va_start(args, fmt);
105 const char *s = fmt;
106 for (;; s++) {
107 char c = GET_VAR(CS, (u8)*s);
108 if (!c)
109 break;
110 if (c != '%') {
111 putc(action, c);
112 continue;
113 }
114 const char *n = s+1;
115 c = GET_VAR(CS, (u8)*n);
116 s32 val;
117 const char *sarg;
118 switch (c) {
119 case '%':
120 putc(action, '%');
121 break;
122 case 'd':
123 val = va_arg(args, s32);
124 if (val < 0) {
125 putc(action, '-');
126 val = -val;
127 }
128 putuint(action, val);
129 break;
130 case 'u':
131 val = va_arg(args, s32);
132 putuint(action, val);
133 break;
134 case 'x':
135 val = va_arg(args, s32);
136 puthex(action, val);
137 break;
Kevin O'Connor12dade52008-03-01 13:35:17 -0500138 case 'c':
139 val = va_arg(args, int);
140 putc(action, val);
141 break;
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500142 case 's':
143 sarg = va_arg(args, const char *);
144 puts_cs(action, sarg);
145 break;
146 default:
Kevin O'Connor4ce6a492008-02-29 00:21:27 -0500147 putc(action, '%');
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500148 n = s;
149 }
150 s = n;
151 }
152 va_end(args);
153}
154
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500155static void
156dump_regs(const char *fname, const char *type, struct bregs *regs)
157{
158 if (!regs) {
159 bprintf(0, "%s %s: NULL\n", type, fname);
160 return;
161 }
162 bprintf(0, "%s %s: a=%x b=%x c=%x d=%x si=%x di=%x\n"
163 , type, fname, regs->eax, regs->ebx, regs->ecx, regs->edx
164 , regs->esi, regs->edi);
165 bprintf(0, " ds=%x es=%x bp=%x sp=%x ip=%x cs=%x f=%x\n"
166 , regs->ds, regs->es, regs->ebp, regs->esp
167 , regs->ip, regs->cs, regs->flags);
168}
169
Kevin O'Connorc65a3802008-03-02 13:58:23 -0500170void
171__debug_isr(const char *fname, struct bregs *regs)
172{
173 puts_cs(0, fname);
174 putc(0, '\n');
175}
176
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500177// Function called on handler startup.
178void
179__debug_enter(const char *fname, struct bregs *regs)
180{
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500181 // XXX - implement run time suppression test
182 dump_regs(fname, "enter", regs);
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500183}
184
185void
186__debug_exit(const char *fname, struct bregs *regs)
187{
Kevin O'Connor4b60c002008-02-25 22:29:55 -0500188 if (! (regs->flags & F_CF))
189 return;
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500190 dump_regs(fname, "exit", regs);
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500191}
Kevin O'Connor4ce6a492008-02-29 00:21:27 -0500192
193void
194__debug_stub(const char *fname, struct bregs *regs)
195{
196 dump_regs(fname, "stub", regs);
197}