aboutsummaryrefslogtreecommitdiffstats
path: root/src/output.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/output.c')
-rw-r--r--src/output.c161
1 files changed, 161 insertions, 0 deletions
diff --git a/src/output.c b/src/output.c
new file mode 100644
index 00000000..9670163b
--- /dev/null
+++ b/src/output.c
@@ -0,0 +1,161 @@
+// Raw screen writing code.
+//
+// Copyright (C) 2008 Kevin O'Connor <kevin@koconnor.net>
+//
+// This file may be distributed under the terms of the GNU GPLv3 license.
+
+#include <stdarg.h> // va_list
+
+#include "farptr.h" // GET_VAR
+#include "util.h" // bprintf
+#include "biosvar.h" // struct bregs
+
+static void
+screenc(char c)
+{
+ // XXX
+}
+
+// XXX
+#define PORT_DEBUG 0x403
+
+// Write a charcter to the framebuffer.
+static void
+putc(u16 action, char c)
+{
+ screenc(c);
+ outb(c, PORT_DEBUG);
+}
+
+// Write a string to the framebuffer.
+static void
+puts(u16 action, const char *s)
+{
+ for (; *s; s++)
+ putc(action, *s);
+}
+
+// Write a string to the framebuffer.
+static void
+puts_cs(u16 action, const char *s)
+{
+ for (;; s++) {
+ char c = GET_VAR(CS, (u8)*s);
+ if (!c)
+ break;
+ putc(action, c);
+ }
+}
+
+// Write an unsigned integer to the screen.
+static void
+putuint(u16 action, u32 val)
+{
+ char buf[12];
+ char *d = &buf[sizeof(buf) - 1];
+ *d-- = '\0';
+ for (;;) {
+ *d = val % 10;
+ val /= 10;
+ if (!val)
+ break;
+ d--;
+ }
+ puts(action, d);
+}
+
+// Write a single digit hex character to the screen.
+static inline void
+putsinglehex(u16 action, u32 val)
+{
+ if (val <= 9)
+ val = '0' + val;
+ else
+ val = 'a' + val - 10;
+ putc(action, val);
+}
+
+// Write an integer in hexadecimal to the screen.
+static void
+puthex(u16 action, u32 val)
+{
+ putsinglehex(action, (val >> 28) & 0xf);
+ putsinglehex(action, (val >> 24) & 0xf);
+ putsinglehex(action, (val >> 20) & 0xf);
+ putsinglehex(action, (val >> 16) & 0xf);
+ putsinglehex(action, (val >> 12) & 0xf);
+ putsinglehex(action, (val >> 8) & 0xf);
+ putsinglehex(action, (val >> 4) & 0xf);
+ putsinglehex(action, (val >> 0) & 0xf);
+}
+
+void
+bprintf(u16 action, const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ const char *s = fmt;
+ for (;; s++) {
+ char c = GET_VAR(CS, (u8)*s);
+ if (!c)
+ break;
+ if (c != '%') {
+ putc(action, c);
+ continue;
+ }
+ const char *n = s+1;
+ c = GET_VAR(CS, (u8)*n);
+ s32 val;
+ const char *sarg;
+ switch (c) {
+ case '%':
+ putc(action, '%');
+ break;
+ case 'd':
+ val = va_arg(args, s32);
+ if (val < 0) {
+ putc(action, '-');
+ val = -val;
+ }
+ putuint(action, val);
+ break;
+ case 'u':
+ val = va_arg(args, s32);
+ putuint(action, val);
+ break;
+ case 'x':
+ val = va_arg(args, s32);
+ puthex(action, val);
+ break;
+ case 's':
+ sarg = va_arg(args, const char *);
+ puts_cs(action, sarg);
+ break;
+ default:
+ putc(action, *s);
+ n = s;
+ }
+ s = n;
+ }
+ va_end(args);
+}
+
+// Function called on handler startup.
+void
+__debug_enter(const char *fname, struct bregs *regs)
+{
+ bprintf(0, "enter %s: a=%x b=%x c=%x d=%x si=%x di=%x\n"
+ , fname, regs->eax, regs->ebx, regs->ecx, regs->edx
+ , regs->esi, regs->edi);
+ bprintf(0, "&=%x ds=%x es=%x bp=%x sp=%x ip=%x cs=%x f=%x\n"
+ , (u32)regs, regs->ds, regs->es, regs->ebp, regs->esp
+ , regs->ip, regs->cs, regs->flags);
+}
+
+void
+__debug_exit(const char *fname, struct bregs *regs)
+{
+ bprintf(0, "exit %s: a=%x b=%x c=%x d=%x s=%x i=%x\n"
+ , fname, regs->eax, regs->ebx, regs->ecx, regs->edx
+ , regs->esi, regs->edi);
+}