Initial checkin.
diff --git a/src/boot.c b/src/boot.c
new file mode 100644
index 0000000..828be14
--- /dev/null
+++ b/src/boot.c
@@ -0,0 +1,118 @@
+// 16bit code to load disk image and start system boot.
+//
+// Copyright (C) 2008  Kevin O'Connor <kevin@koconnor.net>
+// Copyright (C) 2002  MandrakeSoft S.A.
+//
+// This file may be distributed under the terms of the GNU GPLv3 license.
+
+#include "types.h" // VISIBLE
+#include "util.h" // irq_enable
+#include "biosvar.h" // struct bregs
+#include "farptr.h" // SET_SEG
+
+static inline void
+__call_irq(u8 nr)
+{
+    asm volatile("int %0" : : "N" (nr));
+}
+
+static inline u32
+call_irq(u8 nr, struct bregs *callregs)
+{
+    u32 flags;
+    asm volatile(
+        // Save current registers
+        "pushal\n"
+        // Pull in calling registers.
+        "movl 0x04(%%eax), %%edi\n"
+        "movl 0x08(%%eax), %%esi\n"
+        "movl 0x0c(%%eax), %%ebp\n"
+        "movl 0x14(%%eax), %%ebx\n"
+        "movl 0x18(%%eax), %%edx\n"
+        "movl 0x1c(%%eax), %%ecx\n"
+        "movl 0x20(%%eax), %%eax\n"
+        // Invoke interrupt
+        "int %1\n"
+        // Restore registers
+        "popal\n"
+        // Exract flags
+        "pushfw\n"
+        "popl %%eax\n"
+        : "=a" (flags): "N" (nr), "a" (callregs), "m" (*callregs));
+    return flags;
+}
+
+static void
+print_boot_failure()
+{
+    bprintf(0, "Boot failed\n");
+}
+
+static void
+try_boot()
+{
+    // XXX - assume floppy
+    u16 bootseg = 0x07c0;
+    u8 bootdrv = 0;
+
+    // Read sector
+    struct bregs cr;
+    memset(&cr, 0, sizeof(cr));
+    cr.dl = bootdrv;
+    SET_SEG(ES, bootseg);
+    cr.bx = 0;
+    cr.ah = 2;
+    cr.al = 1;
+    cr.ch = 0;
+    cr.cl = 1;
+    cr.dh = 0;
+    u32 status = call_irq(0x13, &cr);
+
+    if (status & F_CF) {
+        print_boot_failure();
+        return;
+    }
+
+    u16 bootip = (bootseg & 0x0fff) << 4;
+    bootseg &= 0xf000;
+
+    u32 segoff = (bootseg << 16) | bootip;
+    asm volatile (
+        "pushf\n"
+        "pushl %0\n"
+        "movb %b1, %%dl\n"
+        // Set the magic number in ax and the boot drive in dl.
+        "movw $0xaa55, %%ax\n"
+        // Zero some of the other registers.
+        "xorw %%bx, %%bx\n"
+        "movw %%bx, %%ds\n"
+        "movw %%bx, %%es\n"
+        "movw %%bx, %%bp\n"
+        // Go!
+        "iretw\n"
+        : : "r" (segoff), "ri" (bootdrv));
+}
+
+// Boot Failure recovery: try the next device.
+void VISIBLE
+handle_18(struct bregs *regs)
+{
+    debug_enter(regs);
+    try_boot();
+}
+
+// INT 19h Boot Load Service Entry Point
+void VISIBLE
+handle_19(struct bregs *regs)
+{
+    debug_enter(regs);
+    try_boot();
+}
+
+// Callback from 32bit entry - start boot process
+void VISIBLE
+begin_boot()
+{
+    irq_enable();
+    __call_irq(0x19);
+}