Add initial port of the "open source vga bios" project.
authorKevin O'Connor <kevin@koconnor.net>
Thu, 7 May 2009 03:35:59 +0000 (23:35 -0400)
committerKevin O'Connor <kevin@koconnor.net>
Thu, 7 May 2009 03:35:59 +0000 (23:35 -0400)
This is an initial import of the code from:
    http://www.nongnu.org/vgabios/
The code has been ported from bcc to gcc and gas.
This is an initial import - many functions have not been ported; many
    bugs are present.

Makefile
vgasrc/clext.c [new file with mode: 0644]
vgasrc/vga.c [new file with mode: 0644]
vgasrc/vgaentry.S [new file with mode: 0644]
vgasrc/vgafonts.c [new file with mode: 0644]
vgasrc/vgalayout.lds.S [new file with mode: 0644]
vgasrc/vgatables.c [new file with mode: 0644]
vgasrc/vgatables.h [new file with mode: 0644]

index e079f12f104feddf17c232147b682258d1ed5fe5..5890fa555f2384118295bd6b7449895561d29cda 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -52,8 +52,8 @@ STRIP=strip
 
 .PHONY : all FORCE
 
-vpath %.c src
-vpath %.S src
+vpath %.c src vgasrc
+vpath %.S src vgasrc
 
 ################ Build rules
 
@@ -132,6 +132,30 @@ $(OUT)bios.bin: $(OUT)bios.bin.elf
        $(Q)$(OBJCOPY) -O binary $< $@
 
 
+################ VGA build rules
+
+# VGA src files
+SRCVGA=src/output.c src/util.c vgasrc/vga.c vgasrc/vgatables.c \
+       vgasrc/vgafonts.c vgasrc/clext.c
+
+$(OUT)vgaccode.16.s: ; $(call whole-compile, $(CFLAGS16) -S -Isrc, $(SRCVGA),$@)
+
+$(OUT)vgalayout16.o: vgaentry.S $(OUT)vgaccode.16.s $(OUT)asm-offsets.h
+       @echo "  Compiling (16bit) $@"
+       $(Q)$(CC) $(CFLAGS16INC) -c -D__ASSEMBLY__ -Isrc $< -o $@
+
+$(OUT)vgarom.o: $(OUT)vgalayout16.o $(OUT)vgalayout.lds
+       @echo "  Linking $@"
+       $(Q)$(LD) -T $(OUT)vgalayout.lds $(OUT)vgalayout16.o -o $@
+
+$(OUT)vgabios.bin.raw: $(OUT)vgarom.o
+       @echo "  Extracting binary $@"
+       $(Q)$(OBJCOPY) -O binary $< $@
+
+$(OUT)vgabios.bin: $(OUT)vgabios.bin.raw
+       @echo "  Finalizing rom $@"
+       $(Q)./tools/buildrom.py $< $@
+
 ####### Generic rules
 clean:
        $(Q)rm -rf $(OUT)
diff --git a/vgasrc/clext.c b/vgasrc/clext.c
new file mode 100644 (file)
index 0000000..4be70c1
--- /dev/null
@@ -0,0 +1,388 @@
+//  QEMU Cirrus CLGD 54xx VGABIOS Extension.
+//
+// Copyright (C) 2009  Kevin O'Connor <kevin@koconnor.net>
+//  Copyright (c) 2004 Makoto Suzuki (suzu)
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+#include "vgatables.h" // cirrus_init
+#include "biosvar.h" // GET_GLOBAL
+#include "util.h" // dprintf
+
+struct cirrus_mode_s {
+    /* + 0 */
+    u16 mode;
+    u16 width;
+    u16 height;
+    u16 depth;
+    /* + 8 */
+    u16 hidden_dac; /* 0x3c6 */
+    u16 *seq; /* 0x3c4 */
+    u16 *graph; /* 0x3ce */
+    u16 *crtc; /* 0x3d4 */
+    /* +16 */
+    u8 bitsperpixel;
+    u8 vesacolortype;
+    u8 vesaredmask;
+    u8 vesaredpos;
+    u8 vesagreenmask;
+    u8 vesagreenpos;
+    u8 vesabluemask;
+    u8 vesabluepos;
+    /* +24 */
+    u8 vesareservedmask;
+    u8 vesareservedpos;
+};
+
+/* VGA */
+static u16 cseq_vga[] VAR16 = {0x0007,0xffff};
+static u16 cgraph_vga[] VAR16 = {0x0009,0x000a,0x000b,0xffff};
+static u16 ccrtc_vga[] VAR16 = {0x001a,0x001b,0x001d,0xffff};
+
+/* extensions */
+static u16 cgraph_svgacolor[] VAR16 = {
+    0x0000,0x0001,0x0002,0x0003,0x0004,0x4005,0x0506,0x0f07,0xff08,
+    0x0009,0x000a,0x000b,
+    0xffff
+};
+/* 640x480x8 */
+static u16 cseq_640x480x8[] VAR16 = {
+    0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107,
+    0x580b,0x580c,0x580d,0x580e,
+    0x0412,0x0013,0x2017,
+    0x331b,0x331c,0x331d,0x331e,
+    0xffff
+};
+static u16 ccrtc_640x480x8[] VAR16 = {
+    0x2c11,
+    0x5f00,0x4f01,0x4f02,0x8003,0x5204,0x1e05,0x0b06,0x3e07,
+    0x4009,0x000c,0x000d,
+    0xea10,0xdf12,0x5013,0x4014,0xdf15,0x0b16,0xc317,0xff18,
+    0x001a,0x221b,0x001d,
+    0xffff
+};
+/* 640x480x16 */
+static u16 cseq_640x480x16[] VAR16 = {
+    0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707,
+    0x580b,0x580c,0x580d,0x580e,
+    0x0412,0x0013,0x2017,
+    0x331b,0x331c,0x331d,0x331e,
+    0xffff
+};
+static u16 ccrtc_640x480x16[] VAR16 = {
+    0x2c11,
+    0x5f00,0x4f01,0x4f02,0x8003,0x5204,0x1e05,0x0b06,0x3e07,
+    0x4009,0x000c,0x000d,
+    0xea10,0xdf12,0xa013,0x4014,0xdf15,0x0b16,0xc317,0xff18,
+    0x001a,0x221b,0x001d,
+    0xffff
+};
+/* 640x480x24 */
+static u16 cseq_640x480x24[] VAR16 = {
+    0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1507,
+    0x580b,0x580c,0x580d,0x580e,
+    0x0412,0x0013,0x2017,
+    0x331b,0x331c,0x331d,0x331e,
+    0xffff
+};
+static u16 ccrtc_640x480x24[] VAR16 = {
+    0x2c11,
+    0x5f00,0x4f01,0x4f02,0x8003,0x5204,0x1e05,0x0b06,0x3e07,
+    0x4009,0x000c,0x000d,
+    0xea10,0xdf12,0x0013,0x4014,0xdf15,0x0b16,0xc317,0xff18,
+    0x001a,0x321b,0x001d,
+    0xffff
+};
+/* 800x600x8 */
+static u16 cseq_800x600x8[] VAR16 = {
+    0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107,
+    0x230b,0x230c,0x230d,0x230e,
+    0x0412,0x0013,0x2017,
+    0x141b,0x141c,0x141d,0x141e,
+    0xffff
+};
+static u16 ccrtc_800x600x8[] VAR16 = {
+    0x2311,0x7d00,0x6301,0x6302,0x8003,0x6b04,0x1a05,0x9806,0xf007,
+    0x6009,0x000c,0x000d,
+    0x7d10,0x5712,0x6413,0x4014,0x5715,0x9816,0xc317,0xff18,
+    0x001a,0x221b,0x001d,
+    0xffff
+};
+/* 800x600x16 */
+static u16 cseq_800x600x16[] VAR16 = {
+    0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707,
+    0x230b,0x230c,0x230d,0x230e,
+    0x0412,0x0013,0x2017,
+    0x141b,0x141c,0x141d,0x141e,
+    0xffff
+};
+static u16 ccrtc_800x600x16[] VAR16 = {
+    0x2311,0x7d00,0x6301,0x6302,0x8003,0x6b04,0x1a05,0x9806,0xf007,
+    0x6009,0x000c,0x000d,
+    0x7d10,0x5712,0xc813,0x4014,0x5715,0x9816,0xc317,0xff18,
+    0x001a,0x221b,0x001d,
+    0xffff
+};
+/* 800x600x24 */
+static u16 cseq_800x600x24[] VAR16 = {
+    0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1507,
+    0x230b,0x230c,0x230d,0x230e,
+    0x0412,0x0013,0x2017,
+    0x141b,0x141c,0x141d,0x141e,
+    0xffff
+};
+static u16 ccrtc_800x600x24[] VAR16 = {
+    0x2311,0x7d00,0x6301,0x6302,0x8003,0x6b04,0x1a05,0x9806,0xf007,
+    0x6009,0x000c,0x000d,
+    0x7d10,0x5712,0x2c13,0x4014,0x5715,0x9816,0xc317,0xff18,
+    0x001a,0x321b,0x001d,
+    0xffff
+};
+/* 1024x768x8 */
+static u16 cseq_1024x768x8[] VAR16 = {
+    0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107,
+    0x760b,0x760c,0x760d,0x760e,
+    0x0412,0x0013,0x2017,
+    0x341b,0x341c,0x341d,0x341e,
+    0xffff
+};
+static u16 ccrtc_1024x768x8[] VAR16 = {
+    0x2911,0xa300,0x7f01,0x7f02,0x8603,0x8304,0x9405,0x2406,0xf507,
+    0x6009,0x000c,0x000d,
+    0x0310,0xff12,0x8013,0x4014,0xff15,0x2416,0xc317,0xff18,
+    0x001a,0x221b,0x001d,
+    0xffff
+};
+/* 1024x768x16 */
+static u16 cseq_1024x768x16[] VAR16 = {
+    0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707,
+    0x760b,0x760c,0x760d,0x760e,
+    0x0412,0x0013,0x2017,
+    0x341b,0x341c,0x341d,0x341e,
+    0xffff
+};
+static u16 ccrtc_1024x768x16[] VAR16 = {
+    0x2911,0xa300,0x7f01,0x7f02,0x8603,0x8304,0x9405,0x2406,0xf507,
+    0x6009,0x000c,0x000d,
+    0x0310,0xff12,0x0013,0x4014,0xff15,0x2416,0xc317,0xff18,
+    0x001a,0x321b,0x001d,
+    0xffff
+};
+/* 1024x768x24 */
+static u16 cseq_1024x768x24[] VAR16 = {
+    0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1507,
+    0x760b,0x760c,0x760d,0x760e,
+    0x0412,0x0013,0x2017,
+    0x341b,0x341c,0x341d,0x341e,
+    0xffff
+};
+static u16 ccrtc_1024x768x24[] VAR16 = {
+    0x2911,0xa300,0x7f01,0x7f02,0x8603,0x8304,0x9405,0x2406,0xf507,
+    0x6009,0x000c,0x000d,
+    0x0310,0xff12,0x8013,0x4014,0xff15,0x2416,0xc317,0xff18,
+    0x001a,0x321b,0x001d,
+    0xffff
+};
+/* 1280x1024x8 */
+static u16 cseq_1280x1024x8[] VAR16 = {
+    0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107,
+    0x760b,0x760c,0x760d,0x760e,
+    0x0412,0x0013,0x2017,
+    0x341b,0x341c,0x341d,0x341e,
+    0xffff
+};
+static u16 ccrtc_1280x1024x8[] VAR16 = {
+    0x2911,0xc300,0x9f01,0x9f02,0x8603,0x8304,0x9405,0x2406,0xf707,
+    0x6009,0x000c,0x000d,
+    0x0310,0xff12,0xa013,0x4014,0xff15,0x2416,0xc317,0xff18,
+    0x001a,0x221b,0x001d,
+    0xffff
+};
+/* 1280x1024x16 */
+static u16 cseq_1280x1024x16[] VAR16 = {
+    0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707,
+    0x760b,0x760c,0x760d,0x760e,
+    0x0412,0x0013,0x2017,
+    0x341b,0x341c,0x341d,0x341e,
+    0xffff
+};
+static u16 ccrtc_1280x1024x16[] VAR16 = {
+    0x2911,0xc300,0x9f01,0x9f02,0x8603,0x8304,0x9405,0x2406,0xf707,
+    0x6009,0x000c,0x000d,
+    0x0310,0xff12,0x4013,0x4014,0xff15,0x2416,0xc317,0xff18,
+    0x001a,0x321b,0x001d,
+    0xffff
+};
+
+/* 1600x1200x8 */
+static u16 cseq_1600x1200x8[] VAR16 = {
+    0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107,
+    0x760b,0x760c,0x760d,0x760e,
+    0x0412,0x0013,0x2017,
+    0x341b,0x341c,0x341d,0x341e,
+    0xffff
+};
+static u16 ccrtc_1600x1200x8[] VAR16 = {
+    0x2911,0xc300,0x9f01,0x9f02,0x8603,0x8304,0x9405,0x2406,0xf707,
+    0x6009,0x000c,0x000d,
+    0x0310,0xff12,0xa013,0x4014,0xff15,0x2416,0xc317,0xff18,
+    0x001a,0x221b,0x001d,
+    0xffff
+};
+
+static struct cirrus_mode_s cirrus_modes[] VAR16 = {
+    {0x5f,640,480,8,0x00,
+     cseq_640x480x8,cgraph_svgacolor,ccrtc_640x480x8,8,
+     4,0,0,0,0,0,0,0,0},
+    {0x64,640,480,16,0xe1,
+     cseq_640x480x16,cgraph_svgacolor,ccrtc_640x480x16,16,
+     6,5,11,6,5,5,0,0,0},
+    {0x66,640,480,15,0xf0,
+     cseq_640x480x16,cgraph_svgacolor,ccrtc_640x480x16,16,
+     6,5,10,5,5,5,0,1,15},
+    {0x71,640,480,24,0xe5,
+     cseq_640x480x24,cgraph_svgacolor,ccrtc_640x480x24,24,
+     6,8,16,8,8,8,0,0,0},
+
+    {0x5c,800,600,8,0x00,
+     cseq_800x600x8,cgraph_svgacolor,ccrtc_800x600x8,8,
+     4,0,0,0,0,0,0,0,0},
+    {0x65,800,600,16,0xe1,
+     cseq_800x600x16,cgraph_svgacolor,ccrtc_800x600x16,16,
+     6,5,11,6,5,5,0,0,0},
+    {0x67,800,600,15,0xf0,
+     cseq_800x600x16,cgraph_svgacolor,ccrtc_800x600x16,16,
+     6,5,10,5,5,5,0,1,15},
+
+    {0x60,1024,768,8,0x00,
+     cseq_1024x768x8,cgraph_svgacolor,ccrtc_1024x768x8,8,
+     4,0,0,0,0,0,0,0,0},
+    {0x74,1024,768,16,0xe1,
+     cseq_1024x768x16,cgraph_svgacolor,ccrtc_1024x768x16,16,
+     6,5,11,6,5,5,0,0,0},
+    {0x68,1024,768,15,0xf0,
+     cseq_1024x768x16,cgraph_svgacolor,ccrtc_1024x768x16,16,
+     6,5,10,5,5,5,0,1,15},
+
+    {0x78,800,600,24,0xe5,
+     cseq_800x600x24,cgraph_svgacolor,ccrtc_800x600x24,24,
+     6,8,16,8,8,8,0,0,0},
+    {0x79,1024,768,24,0xe5,
+     cseq_1024x768x24,cgraph_svgacolor,ccrtc_1024x768x24,24,
+     6,8,16,8,8,8,0,0,0},
+
+    {0x6d,1280,1024,8,0x00,
+     cseq_1280x1024x8,cgraph_svgacolor,ccrtc_1280x1024x8,8,
+     4,0,0,0,0,0,0,0,0},
+    {0x69,1280,1024,15,0xf0,
+     cseq_1280x1024x16,cgraph_svgacolor,ccrtc_1280x1024x16,16,
+     6,5,10,5,5,5,0,1,15},
+    {0x75,1280,1024,16,0xe1,
+     cseq_1280x1024x16,cgraph_svgacolor,ccrtc_1280x1024x16,16,
+     6,5,11,6,5,5,0,0,0},
+
+    {0x7b,1600,1200,8,0x00,
+     cseq_1600x1200x8,cgraph_svgacolor,ccrtc_1600x1200x8,8,
+     4,0,0,0,0,0,0,0,0},
+
+    {0xfe,0,0,0,0,cseq_vga,cgraph_vga,ccrtc_vga,0,
+     0xff,0,0,0,0,0,0,0,0},
+};
+
+static struct cirrus_mode_s *
+cirrus_get_modeentry(u8 mode)
+{
+    struct cirrus_mode_s *table = cirrus_modes;
+    while (table < &cirrus_modes[ARRAY_SIZE(cirrus_modes)]) {
+        u16 tmode = GET_GLOBAL(table->mode);
+        if (tmode == mode)
+            return table;
+        table++;
+    }
+    return NULL;
+}
+
+static void
+cirrus_switch_mode_setregs(u16 *data, u16 port)
+{
+    for (;;) {
+        u16 val = GET_GLOBAL(*data);
+        if (val == 0xffff)
+            return;
+        outw(val, port);
+        data++;
+    }
+}
+
+static u16
+cirrus_get_crtc()
+{
+    return 0x3b4 + ((inb(0x3cc) & 1) << 5);
+}
+
+static void
+cirrus_switch_mode(struct cirrus_mode_s *table)
+{
+    // Unlock cirrus special
+    outw(0x1206, 0x3c4);
+    cirrus_switch_mode_setregs(GET_GLOBAL(table->seq), 0x3c4);
+    cirrus_switch_mode_setregs(GET_GLOBAL(table->graph), 0x3ce);
+    cirrus_switch_mode_setregs(GET_GLOBAL(table->crtc), cirrus_get_crtc());
+
+    outb(0x00, 0x3c6);
+    inb(0x3c6);
+    inb(0x3c6);
+    inb(0x3c6);
+    inb(0x3c6);
+    outb(GET_GLOBAL(table->hidden_dac), 0x3c6);
+    outb(0xff, 0x3c6);
+
+    u8 vesacolortype = GET_GLOBAL(table->vesacolortype);
+    u8 v = biosfn_get_single_palette_reg(0x10) & 0xfe;
+    if (vesacolortype == 3)
+        v |= 0x41;
+    else if (vesacolortype)
+        v |= 0x01;
+    biosfn_set_single_palette_reg(0x10, v);
+}
+
+void
+cirrus_set_video_mode(u8 mode)
+{
+    dprintf(1, "cirrus mode %d\n", mode);
+    SET_BDA(vbe_mode, 0);
+    struct cirrus_mode_s *table = cirrus_get_modeentry(mode & 0x7f);
+    if (table) {
+        //XXX - cirrus_set_video_mode_extended(table);
+        return;
+    }
+    table = cirrus_get_modeentry(0xfe);
+    cirrus_switch_mode(table);
+    dprintf(1, "cirrus mode switch regular\n");
+}
+
+static int
+cirrus_check()
+{
+    outw(0x9206, 0x3c4);
+    return inb(0x3c5) == 0x12;
+}
+
+void
+cirrus_init()
+{
+    dprintf(1, "cirrus init\n");
+    if (! cirrus_check())
+        return;
+    dprintf(1, "cirrus init 2\n");
+
+    // memory setup
+    outb(0x0f, 0x3c4);
+    u8 v = inb(0x3c5);
+    outb(((v & 0x18) << 8) | 0x0a, 0x3c4);
+    // set vga mode
+    outw(0x0007, 0x3c4);
+    // reset bitblt
+    outw(0x0431, 0x3ce);
+    outw(0x0031, 0x3ce);
+}
diff --git a/vgasrc/vga.c b/vgasrc/vga.c
new file mode 100644 (file)
index 0000000..e9deea0
--- /dev/null
@@ -0,0 +1,2818 @@
+// VGA bios implementation
+//
+// Copyright (C) 2009  Kevin O'Connor <kevin@koconnor.net>
+// Copyright (C) 2001-2008 the LGPL VGABios developers Team
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+
+// TODO:
+//  * commit to git
+//  * Send announcement emails
+//
+//  * introduce "struct vregs", or add ebp to struct bregs.
+//  * Integrate vga_modes/pallete?/line_to_vpti/dac_regs/video_param_table
+//  * define structs for save/restore state
+//  * review correctness of converted asm by comparing with RBIL
+//  * eliminate unimplemented() calls
+//  * eliminate DEBUG defs
+//  * more syntax cleanups
+//  * refactor redundant code into sub-functions
+//  * See if there is a method to the in/out stuff that can be encapsulated.
+//  * remove "biosfn" prefixes
+//  * don't hardcode 0xc000
+//  * add defs for 0xa000/0xb800
+//  * verify all funcs static
+//
+//  * separate code into separate files
+//  * extract hw code from bios interfaces
+//
+//  * convert vbe/clext code
+
+#include "bregs.h" // struct bregs
+#include "biosvar.h" // GET_BDA
+#include "util.h" // memset
+#include "vgatables.h" // vga_modes
+
+// XXX
+#define CONFIG_VBE 0
+#define CONFIG_CIRRUS 0
+
+// XXX
+#define DEBUG_VGA_POST 1
+#define DEBUG_VGA_10 3
+
+#define SET_VGA(var, val) SET_FARVAR(0xc000, (var), (val))
+
+
+// ===================================================================
+//
+// Video Utils
+//
+// ===================================================================
+
+// -------------------------------------------------------------------
+static u8
+find_vga_entry(u8 mode)
+{
+    u8 i;
+    for (i = 0; i <= MODE_MAX; i++)
+        if (GET_GLOBAL(vga_modes[i].svgamode) == mode)
+            return i;
+    return 0xFF;
+}
+
+inline void
+call16_vgaint(u32 eax, u32 ebx)
+{
+    asm volatile(
+        "int $0x10\n"
+        "cli\n"
+        "cld"
+        :
+        : "a"(eax), "b"(ebx)
+        : "cc", "memory");
+}
+
+// XXX
+inline void
+memcpy16_far(u16 d_seg, void *d_far, u16 s_seg, const void *s_far, size_t len)
+{
+    memcpy_far(d_seg, d_far, s_seg, s_far, len);
+}
+
+
+// ===================================================================
+//
+// BIOS functions
+//
+// ===================================================================
+
+// -------------------------------------------------------------------
+static void
+biosfn_perform_gray_scale_summing(u16 start, u16 count)
+{
+    u8 r, g, b;
+    u16 i;
+    u16 index;
+
+    inb(VGAREG_ACTL_RESET);
+    outb(0x00, VGAREG_ACTL_ADDRESS);
+
+    for (index = 0; index < count; index++) {
+        // set read address and switch to read mode
+        outb(start, VGAREG_DAC_READ_ADDRESS);
+        // get 6-bit wide RGB data values
+        r = inb(VGAREG_DAC_DATA);
+        g = inb(VGAREG_DAC_DATA);
+        b = inb(VGAREG_DAC_DATA);
+
+        // intensity = ( 0.3 * Red ) + ( 0.59 * Green ) + ( 0.11 * Blue )
+        i = ((77 * r + 151 * g + 28 * b) + 0x80) >> 8;
+
+        if (i > 0x3f)
+            i = 0x3f;
+
+        // set write address and switch to write mode
+        outb(start, VGAREG_DAC_WRITE_ADDRESS);
+        // write new intensity value
+        outb(i & 0xff, VGAREG_DAC_DATA);
+        outb(i & 0xff, VGAREG_DAC_DATA);
+        outb(i & 0xff, VGAREG_DAC_DATA);
+        start++;
+    }
+    inb(VGAREG_ACTL_RESET);
+    outb(0x20, VGAREG_ACTL_ADDRESS);
+}
+
+// -------------------------------------------------------------------
+static void
+biosfn_set_cursor_shape(u8 CH, u8 CL)
+{
+    u16 cheight, curs, crtc_addr;
+    u8 modeset_ctl;
+
+    CH &= 0x3f;
+    CL &= 0x1f;
+
+    curs = (CH << 8) + CL;
+    SET_BDA(cursor_type, curs);
+
+    modeset_ctl = GET_BDA(modeset_ctl);
+    cheight = GET_BDA(char_height);
+    if ((modeset_ctl & 0x01) && (cheight > 8) && (CL < 8) && (CH < 0x20)) {
+        if (CL != (CH + 1)) {
+            CH = ((CH + 1) * cheight / 8) - 1;
+        } else {
+            CH = ((CL + 1) * cheight / 8) - 2;
+        }
+        CL = ((CL + 1) * cheight / 8) - 1;
+    }
+    // CTRC regs 0x0a and 0x0b
+    crtc_addr = GET_BDA(crtc_address);
+    outb(0x0a, crtc_addr);
+    outb(CH, crtc_addr + 1);
+    outb(0x0b, crtc_addr);
+    outb(CL, crtc_addr + 1);
+}
+
+// -------------------------------------------------------------------
+static void
+biosfn_set_cursor_pos(u8 page, u16 cursor)
+{
+    u8 xcurs, ycurs, current;
+    u16 nbcols, nbrows, address, crtc_addr;
+
+    // Should not happen...
+    if (page > 7)
+        return;
+
+    // Bios cursor pos
+    SET_BDA(cursor_pos[page], cursor);
+
+    // Set the hardware cursor
+    current = GET_BDA(video_page);
+    if (page == current) {
+        // Get the dimensions
+        nbcols = GET_BDA(video_cols);
+        nbrows = GET_BDA(video_rows) + 1;
+
+        xcurs = cursor & 0x00ff;
+        ycurs = (cursor & 0xff00) >> 8;
+
+        // Calculate the address knowing nbcols nbrows and page num
+        address =
+            SCREEN_IO_START(nbcols, nbrows, page) + xcurs + ycurs * nbcols;
+
+        // CRTC regs 0x0e and 0x0f
+        crtc_addr = GET_BDA(crtc_address);
+        outb(0x0e, crtc_addr);
+        outb((address & 0xff00) >> 8, crtc_addr + 1);
+        outb(0x0f, crtc_addr);
+        outb(address & 0x00ff, crtc_addr + 1);
+    }
+}
+
+// -------------------------------------------------------------------
+static void
+biosfn_get_cursor_pos(u8 page, u16 *shape, u16 *pos)
+{
+    // Default
+    *shape = 0;
+    *pos = 0;
+    if (page > 7)
+        return;
+
+    // FIXME should handle VGA 14/16 lines
+    *shape = GET_BDA(cursor_type);
+    *pos = GET_BDA(cursor_pos[page]);
+}
+
+// -------------------------------------------------------------------
+static void
+biosfn_set_active_page(u8 page)
+{
+    u16 cursor, dummy, crtc_addr;
+    u16 nbcols, nbrows, address;
+    u8 mode, line;
+
+    if (page > 7)
+        return;
+
+    // Get the mode
+    mode = GET_BDA(video_mode);
+    line = find_vga_entry(mode);
+    if (line == 0xFF)
+        return;
+
+    // Get pos curs pos for the right page
+    biosfn_get_cursor_pos(page, &dummy, &cursor);
+
+    if (GET_GLOBAL(vga_modes[line].class) == TEXT) {
+        // Get the dimensions
+        nbcols = GET_BDA(video_cols);
+        nbrows = GET_BDA(video_rows) + 1;
+
+        // Calculate the address knowing nbcols nbrows and page num
+        address = SCREEN_MEM_START(nbcols, nbrows, page);
+        SET_BDA(video_pagestart, address);
+
+        // Start address
+        address = SCREEN_IO_START(nbcols, nbrows, page);
+    } else {
+        address = page * GET_GLOBAL(video_param_table[GET_GLOBAL(line_to_vpti[line])].slength);
+    }
+
+    // CRTC regs 0x0c and 0x0d
+    crtc_addr = GET_BDA(crtc_address);
+    outb(0x0c, crtc_addr);
+    outb((address & 0xff00) >> 8, crtc_addr + 1);
+    outb(0x0d, crtc_addr);
+    outb(address & 0x00ff, crtc_addr + 1);
+
+    // And change the BIOS page
+    SET_BDA(video_page, page);
+
+#ifdef DEBUG
+    printf("Set active page %02x address %04x\n", page, address);
+#endif
+
+    // Display the cursor, now the page is active
+    biosfn_set_cursor_pos(page, cursor);
+}
+
+static void
+biosfn_set_video_mode(u8 mode)
+{                               // mode: Bit 7 is 1 if no clear screen
+    // Should we clear the screen ?
+    u8 noclearmem = mode & 0x80;
+    u8 line, mmask, *palette, vpti;
+    u16 i, twidth, theightm1, cheight;
+    u8 modeset_ctl, video_ctl, vga_switches;
+
+    if (CONFIG_CIRRUS)
+        cirrus_set_video_mode(mode);
+
+#ifdef VBE
+    if (vbe_has_vbe_display())
+        dispi_set_enable(VBE_DISPI_DISABLED);
+#endif
+
+    // The real mode
+    mode = mode & 0x7f;
+
+    // find the entry in the video modes
+    line = find_vga_entry(mode);
+
+#ifdef DEBUG
+    printf("mode search %02x found line %02x\n", mode, line);
+#endif
+
+    if (line == 0xFF)
+        return;
+
+    vpti = GET_GLOBAL(line_to_vpti[line]);
+    twidth = GET_GLOBAL(video_param_table[vpti].twidth);
+    theightm1 = GET_GLOBAL(video_param_table[vpti].theightm1);
+    cheight = GET_GLOBAL(video_param_table[vpti].cheight);
+
+    // Read the bios vga control
+    video_ctl = GET_BDA(video_ctl);
+
+    // Read the bios vga switches
+    vga_switches = GET_BDA(video_switches);
+
+    // Read the bios mode set control
+    modeset_ctl = GET_BDA(modeset_ctl);
+
+    // Then we know the number of lines
+// FIXME
+
+    // if palette loading (bit 3 of modeset ctl = 0)
+    if ((modeset_ctl & 0x08) == 0) {    // Set the PEL mask
+        outb(GET_GLOBAL(vga_modes[line].pelmask), VGAREG_PEL_MASK);
+
+        // Set the whole dac always, from 0
+        outb(0x00, VGAREG_DAC_WRITE_ADDRESS);
+
+        // From which palette
+        switch (GET_GLOBAL(vga_modes[line].dacmodel)) {
+        default:
+        case 0:
+            palette = palette0;
+            break;
+        case 1:
+            palette = palette1;
+            break;
+        case 2:
+            palette = palette2;
+            break;
+        case 3:
+            palette = palette3;
+            break;
+        }
+        // Always 256*3 values
+        for (i = 0; i < 0x0100; i++) {
+            if (i <= GET_GLOBAL(dac_regs[GET_GLOBAL(vga_modes[line].dacmodel)])) {
+                outb(GET_GLOBAL(palette[(i * 3) + 0]), VGAREG_DAC_DATA);
+                outb(GET_GLOBAL(palette[(i * 3) + 1]), VGAREG_DAC_DATA);
+                outb(GET_GLOBAL(palette[(i * 3) + 2]), VGAREG_DAC_DATA);
+            } else {
+                outb(0, VGAREG_DAC_DATA);
+                outb(0, VGAREG_DAC_DATA);
+                outb(0, VGAREG_DAC_DATA);
+            }
+        }
+        if ((modeset_ctl & 0x02) == 0x02)
+            biosfn_perform_gray_scale_summing(0x00, 0x100);
+    }
+    // Reset Attribute Ctl flip-flop
+    inb(VGAREG_ACTL_RESET);
+
+    // Set Attribute Ctl
+    for (i = 0; i <= 0x13; i++) {
+        outb(i, VGAREG_ACTL_ADDRESS);
+        outb(GET_GLOBAL(video_param_table[vpti].actl_regs[i])
+             , VGAREG_ACTL_WRITE_DATA);
+    }
+    outb(0x14, VGAREG_ACTL_ADDRESS);
+    outb(0x00, VGAREG_ACTL_WRITE_DATA);
+
+    // Set Sequencer Ctl
+    outb(0, VGAREG_SEQU_ADDRESS);
+    outb(0x03, VGAREG_SEQU_DATA);
+    for (i = 1; i <= 4; i++) {
+        outb(i, VGAREG_SEQU_ADDRESS);
+        outb(GET_GLOBAL(video_param_table[vpti].sequ_regs[i - 1])
+             , VGAREG_SEQU_DATA);
+    }
+
+    // Set Grafx Ctl
+    for (i = 0; i <= 8; i++) {
+        outb(i, VGAREG_GRDC_ADDRESS);
+        outb(GET_GLOBAL(video_param_table[vpti].grdc_regs[i])
+             , VGAREG_GRDC_DATA);
+    }
+
+    // Set CRTC address VGA or MDA
+    u16 crtc_addr = VGAREG_VGA_CRTC_ADDRESS;
+    if (GET_GLOBAL(vga_modes[line].memmodel) == MTEXT)
+        crtc_addr = VGAREG_MDA_CRTC_ADDRESS;
+
+    // Disable CRTC write protection
+    outw(0x0011, crtc_addr);
+    // Set CRTC regs
+    for (i = 0; i <= 0x18; i++) {
+        outb(i, crtc_addr);
+        outb(GET_GLOBAL(video_param_table[vpti].crtc_regs[i]), crtc_addr + 1);
+    }
+
+    // Set the misc register
+    outb(GET_GLOBAL(video_param_table[vpti].miscreg), VGAREG_WRITE_MISC_OUTPUT);
+
+    // Enable video
+    outb(0x20, VGAREG_ACTL_ADDRESS);
+    inb(VGAREG_ACTL_RESET);
+
+    if (noclearmem == 0x00) {
+        if (GET_GLOBAL(vga_modes[line].class) == TEXT) {
+            memset16_far(GET_GLOBAL(vga_modes[line].sstart)
+                         , 0, 0x0720, 0x4000); // 32k
+        } else {
+            if (mode < 0x0d) {
+                memset16_far(GET_GLOBAL(vga_modes[line].sstart)
+                             , 0, 0x0000, 0x4000);     // 32k
+            } else {
+                outb(0x02, VGAREG_SEQU_ADDRESS);
+                mmask = inb(VGAREG_SEQU_DATA);
+                outb(0x0f, VGAREG_SEQU_DATA);   // all planes
+                memset16_far(GET_GLOBAL(vga_modes[line].sstart)
+                             , 0, 0x0000, 0x8000);     // 64k
+                outb(mmask, VGAREG_SEQU_DATA);
+            }
+        }
+    }
+    // Set the BIOS mem
+    SET_BDA(video_mode, mode);
+    SET_BDA(video_cols, twidth);
+    SET_BDA(video_pagesize, GET_GLOBAL(video_param_table[vpti].slength));
+    SET_BDA(crtc_address, crtc_addr);
+    SET_BDA(video_rows, theightm1);
+    SET_BDA(char_height, cheight);
+    SET_BDA(video_ctl, (0x60 | noclearmem));
+    SET_BDA(video_switches, 0xF9);
+    SET_BDA(modeset_ctl, GET_BDA(modeset_ctl) & 0x7f);
+
+    // FIXME We nearly have the good tables. to be reworked
+    SET_BDA(dcc_index, 0x08);   // 8 is VGA should be ok for now
+    SET_BDA(video_savetable_ptr, (u32)video_save_pointer_table);
+    SET_BDA(video_savetable_seg, 0xc000);
+
+    // FIXME
+    SET_BDA(video_msr, 0x00); // Unavailable on vanilla vga, but...
+    SET_BDA(video_pal, 0x00); // Unavailable on vanilla vga, but...
+
+    // Set cursor shape
+    if (GET_GLOBAL(vga_modes[line].class) == TEXT)
+        biosfn_set_cursor_shape(0x06, 0x07);
+    // Set cursor pos for page 0..7
+    for (i = 0; i < 8; i++)
+        biosfn_set_cursor_pos(i, 0x0000);
+
+    // Set active page 0
+    biosfn_set_active_page(0x00);
+
+    // Write the fonts in memory
+    if (GET_GLOBAL(vga_modes[line].class) == TEXT) {
+        call16_vgaint(0x1104, 0);
+        call16_vgaint(0x1103, 0);
+    }
+    // Set the ints 0x1F and 0x43
+    SET_IVT(0x1f, 0xC000, (u32)&vgafont8[128 * 8]);
+
+    switch (cheight) {
+    case 8:
+        SET_IVT(0x43, 0xC000, (u32)vgafont8);
+        break;
+    case 14:
+        SET_IVT(0x43, 0xC000, (u32)vgafont14);
+        break;
+    case 16:
+        SET_IVT(0x43, 0xC000, (u32)vgafont16);
+        break;
+    }
+}
+
+// -------------------------------------------------------------------
+static void
+vgamem_copy_pl4(u8 xstart, u8 ysrc, u8 ydest, u8 cols, u8 nbcols,
+                u8 cheight)
+{
+    u16 src = ysrc * cheight * nbcols + xstart;
+    u16 dest = ydest * cheight * nbcols + xstart;
+    outw(0x0105, VGAREG_GRDC_ADDRESS);
+    u8 i;
+    for (i = 0; i < cheight; i++)
+        memcpy_far(0xa000, (void*)(dest + i * nbcols)
+                   , 0xa000, (void*)(src + i * nbcols), cols);
+    outw(0x0005, VGAREG_GRDC_ADDRESS);
+}
+
+// -------------------------------------------------------------------
+static void
+vgamem_fill_pl4(u8 xstart, u8 ystart, u8 cols, u8 nbcols, u8 cheight,
+                u8 attr)
+{
+    u16 dest = ystart * cheight * nbcols + xstart;
+    outw(0x0205, VGAREG_GRDC_ADDRESS);
+    u8 i;
+    for (i = 0; i < cheight; i++)
+        memset_far(0xa000, (void*)(dest + i * nbcols), attr, cols);
+    outw(0x0005, VGAREG_GRDC_ADDRESS);
+}
+
+// -------------------------------------------------------------------
+static void
+vgamem_copy_cga(u8 xstart, u8 ysrc, u8 ydest, u8 cols, u8 nbcols,
+                u8 cheight)
+{
+    u16 src = ((ysrc * cheight * nbcols) >> 1) + xstart;
+    u16 dest = ((ydest * cheight * nbcols) >> 1) + xstart;
+    u8 i;
+    for (i = 0; i < cheight; i++)
+        if (i & 1)
+            memcpy_far(0xb800, (void*)(0x2000 + dest + (i >> 1) * nbcols)
+                       , 0xb800, (void*)(0x2000 + src + (i >> 1) * nbcols)
+                       , cols);
+        else
+            memcpy_far(0xb800, (void*)(dest + (i >> 1) * nbcols)
+                       , 0xb800, (void*)(src + (i >> 1) * nbcols), cols);
+}
+
+// -------------------------------------------------------------------
+static void
+vgamem_fill_cga(u8 xstart, u8 ystart, u8 cols, u8 nbcols, u8 cheight,
+                u8 attr)
+{
+    u16 dest = ((ystart * cheight * nbcols) >> 1) + xstart;
+    u8 i;
+    for (i = 0; i < cheight; i++)
+        if (i & 1)
+            memset_far(0xb800, (void*)(0x2000 + dest + (i >> 1) * nbcols)
+                       , attr, cols);
+        else
+            memset_far(0xb800, (void*)(dest + (i >> 1) * nbcols), attr, cols);
+}
+
+// -------------------------------------------------------------------
+static void
+biosfn_scroll(u8 nblines, u8 attr, u8 rul, u8 cul, u8 rlr, u8 clr, u8 page,
+              u8 dir)
+{
+    // page == 0xFF if current
+
+    u8 mode, line, cheight, bpp, cols;
+    u16 nbcols, nbrows, i;
+
+    if (rul > rlr)
+        return;
+    if (cul > clr)
+        return;
+
+    // Get the mode
+    mode = GET_BDA(video_mode);
+    line = find_vga_entry(mode);
+    if (line == 0xFF)
+        return;
+
+    // Get the dimensions
+    nbrows = GET_BDA(video_rows) + 1;
+    nbcols = GET_BDA(video_cols);
+
+    // Get the current page
+    if (page == 0xFF)
+        page = GET_BDA(video_page);
+
+    if (rlr >= nbrows)
+        rlr = nbrows - 1;
+    if (clr >= nbcols)
+        clr = nbcols - 1;
+    if (nblines > nbrows)
+        nblines = 0;
+    cols = clr - cul + 1;
+
+    if (GET_GLOBAL(vga_modes[line].class) == TEXT) {
+        // Compute the address
+        void *address = (void*)(SCREEN_MEM_START(nbcols, nbrows, page));
+#ifdef DEBUG
+        printf("Scroll, address %04x (%04x %04x %02x)\n", address, nbrows,
+               nbcols, page);
+#endif
+
+        if (nblines == 0 && rul == 0 && cul == 0 && rlr == nbrows - 1
+            && clr == nbcols - 1) {
+            memset16_far(GET_GLOBAL(vga_modes[line].sstart), address
+                         , (u16)attr * 0x100 + ' ', nbrows * nbcols);
+        } else {                // if Scroll up
+            if (dir == SCROLL_UP) {
+                for (i = rul; i <= rlr; i++) {
+                    if ((i + nblines > rlr) || (nblines == 0))
+                        memset16_far(GET_GLOBAL(vga_modes[line].sstart)
+                                     , address + (i * nbcols + cul) * 2
+                                     , (u16)attr * 0x100 + ' ', cols);
+                    else
+                        memcpy16_far(GET_GLOBAL(vga_modes[line].sstart)
+                                     , address + (i * nbcols + cul) * 2
+                                     , GET_GLOBAL(vga_modes[line].sstart)
+                                     , (void*)(((i + nblines) * nbcols + cul) * 2)
+                                     , cols);
+                }
+            } else {
+                for (i = rlr; i >= rul; i--) {
+                    if ((i < rul + nblines) || (nblines == 0))
+                        memset16_far(GET_GLOBAL(vga_modes[line].sstart)
+                                     , address + (i * nbcols + cul) * 2
+                                     , (u16)attr * 0x100 + ' ', cols);
+                    else
+                        memcpy16_far(GET_GLOBAL(vga_modes[line].sstart)
+                                     , address + (i * nbcols + cul) * 2
+                                     , GET_GLOBAL(vga_modes[line].sstart)
+                                     , (void*)(((i - nblines) * nbcols + cul) * 2)
+                                     , cols);
+                    if (i > rlr)
+                        break;
+                }
+            }
+        }
+    } else {
+        // FIXME gfx mode not complete
+        cheight = GET_GLOBAL(video_param_table[GET_GLOBAL(line_to_vpti[line])].cheight);
+        switch (GET_GLOBAL(vga_modes[line].memmodel)) {
+        case PLANAR4:
+        case PLANAR1:
+            if (nblines == 0 && rul == 0 && cul == 0 && rlr == nbrows - 1
+                && clr == nbcols - 1) {
+                outw(0x0205, VGAREG_GRDC_ADDRESS);
+                memset_far(GET_GLOBAL(vga_modes[line].sstart), 0, attr,
+                           nbrows * nbcols * cheight);
+                outw(0x0005, VGAREG_GRDC_ADDRESS);
+            } else {            // if Scroll up
+                if (dir == SCROLL_UP) {
+                    for (i = rul; i <= rlr; i++) {
+                        if ((i + nblines > rlr) || (nblines == 0))
+                            vgamem_fill_pl4(cul, i, cols, nbcols, cheight,
+                                            attr);
+                        else
+                            vgamem_copy_pl4(cul, i + nblines, i, cols,
+                                            nbcols, cheight);
+                    }
+                } else {
+                    for (i = rlr; i >= rul; i--) {
+                        if ((i < rul + nblines) || (nblines == 0))
+                            vgamem_fill_pl4(cul, i, cols, nbcols, cheight,
+                                            attr);
+                        else
+                            vgamem_copy_pl4(cul, i, i - nblines, cols,
+                                            nbcols, cheight);
+                        if (i > rlr)
+                            break;
+                    }
+                }
+            }
+            break;
+        case CGA:
+            bpp = GET_GLOBAL(vga_modes[line].pixbits);
+            if (nblines == 0 && rul == 0 && cul == 0 && rlr == nbrows - 1
+                && clr == nbcols - 1) {
+                memset_far(GET_GLOBAL(vga_modes[line].sstart), 0, attr,
+                           nbrows * nbcols * cheight * bpp);
+            } else {
+                if (bpp == 2) {
+                    cul <<= 1;
+                    cols <<= 1;
+                    nbcols <<= 1;
+                }
+                // if Scroll up
+                if (dir == SCROLL_UP) {
+                    for (i = rul; i <= rlr; i++) {
+                        if ((i + nblines > rlr) || (nblines == 0))
+                            vgamem_fill_cga(cul, i, cols, nbcols, cheight,
+                                            attr);
+                        else
+                            vgamem_copy_cga(cul, i + nblines, i, cols,
+                                            nbcols, cheight);
+                    }
+                } else {
+                    for (i = rlr; i >= rul; i--) {
+                        if ((i < rul + nblines) || (nblines == 0))
+                            vgamem_fill_cga(cul, i, cols, nbcols, cheight,
+                                            attr);
+                        else
+                            vgamem_copy_cga(cul, i, i - nblines, cols,
+                                            nbcols, cheight);
+                        if (i > rlr)
+                            break;
+                    }
+                }
+            }
+            break;
+#ifdef DEBUG
+        default:
+            printf("Scroll in graphics mode ");
+            unimplemented();
+#endif
+        }
+    }
+}
+
+// -------------------------------------------------------------------
+static void
+biosfn_read_char_attr(u8 page, u16 *car)
+{
+    u8 xcurs, ycurs, mode, line;
+    u16 nbcols, nbrows;
+    u16 cursor, dummy;
+
+    // Get the mode
+    mode = GET_BDA(video_mode);
+    line = find_vga_entry(mode);
+    if (line == 0xFF)
+        return;
+
+    // Get the cursor pos for the page
+    biosfn_get_cursor_pos(page, &dummy, &cursor);
+    xcurs = cursor & 0x00ff;
+    ycurs = (cursor & 0xff00) >> 8;
+
+    // Get the dimensions
+    nbrows = GET_BDA(video_rows) + 1;
+    nbcols = GET_BDA(video_cols);
+
+    if (GET_GLOBAL(vga_modes[line].class) == TEXT) {
+        // Compute the address
+        u16 *address = (void*)(SCREEN_MEM_START(nbcols, nbrows, page)
+                               + (xcurs + ycurs * nbcols) * 2);
+
+        *car = GET_FARVAR(GET_GLOBAL(vga_modes[line].sstart), *address);
+    } else {
+        // FIXME gfx mode
+#ifdef DEBUG
+        unimplemented();
+#endif
+    }
+}
+
+// -------------------------------------------------------------------
+static void
+write_gfx_char_pl4(u8 car, u8 attr, u8 xcurs, u8 ycurs, u8 nbcols,
+                   u8 cheight)
+{
+    u8 i, j, mask;
+    u8 *fdata;
+    u16 addr, src;
+
+    switch (cheight) {
+    case 14:
+        fdata = vgafont14;
+        break;
+    case 16:
+        fdata = vgafont16;
+        break;
+    default:
+        fdata = vgafont8;
+    }
+    addr = xcurs + ycurs * cheight * nbcols;
+    src = car * cheight;
+    outw(0x0f02, VGAREG_SEQU_ADDRESS);
+    outw(0x0205, VGAREG_GRDC_ADDRESS);
+    if (attr & 0x80)
+        outw(0x1803, VGAREG_GRDC_ADDRESS);
+    else
+        outw(0x0003, VGAREG_GRDC_ADDRESS);
+    for (i = 0; i < cheight; i++) {
+        u8 *dest = (void*)(addr + i * nbcols);
+        for (j = 0; j < 8; j++) {
+            mask = 0x80 >> j;
+            outw((mask << 8) | 0x08, VGAREG_GRDC_ADDRESS);
+            GET_FARVAR(0xa000, *dest);
+            if (GET_GLOBAL(fdata[src + i]) & mask)
+                SET_FARVAR(0xa000, *dest, attr & 0x0f);
+            else
+                SET_FARVAR(0xa000, *dest, 0x00);
+        }
+    }
+    outw(0xff08, VGAREG_GRDC_ADDRESS);
+    outw(0x0005, VGAREG_GRDC_ADDRESS);
+    outw(0x0003, VGAREG_GRDC_ADDRESS);
+}
+
+// -------------------------------------------------------------------
+static void
+write_gfx_char_cga(u8 car, u8 attr, u8 xcurs, u8 ycurs, u8 nbcols, u8 bpp)
+{
+    u8 *fdata = vgafont8;
+    u16 addr = (xcurs * bpp) + ycurs * 320;
+    u16 src = car * 8;
+    u8 i;
+    for (i = 0; i < 8; i++) {
+        u8 *dest = (void*)(addr + (i >> 1) * 80);
+        if (i & 1)
+            dest += 0x2000;
+        u8 mask = 0x80;
+        if (bpp == 1) {
+            u8 data = 0;
+            if (attr & 0x80)
+                data = GET_FARVAR(0xb800, *dest);
+            u8 j;
+            for (j = 0; j < 8; j++) {
+                if (GET_GLOBAL(fdata[src + i]) & mask) {
+                    if (attr & 0x80)
+                        data ^= (attr & 0x01) << (7 - j);
+                    else
+                        data |= (attr & 0x01) << (7 - j);
+                }
+                mask >>= 1;
+            }
+            SET_FARVAR(0xb800, *dest, data);
+        } else {
+            while (mask > 0) {
+                u8 data = 0;
+                if (attr & 0x80)
+                    data = GET_FARVAR(0xb800, *dest);
+                u8 j;
+                for (j = 0; j < 4; j++) {
+                    if (GET_GLOBAL(fdata[src + i]) & mask) {
+                        if (attr & 0x80)
+                            data ^= (attr & 0x03) << ((3 - j) * 2);
+                        else
+                            data |= (attr & 0x03) << ((3 - j) * 2);
+                    }
+                    mask >>= 1;
+                }
+                SET_FARVAR(0xb800, *dest, data);
+                dest += 1;
+            }
+        }
+    }
+}
+
+// -------------------------------------------------------------------
+static void
+write_gfx_char_lin(u8 car, u8 attr, u8 xcurs, u8 ycurs, u8 nbcols)
+{
+    u8 *fdata = vgafont8;
+    u16 addr = xcurs * 8 + ycurs * nbcols * 64;
+    u16 src = car * 8;
+    u8 i;
+    for (i = 0; i < 8; i++) {
+        u8 *dest = (void*)(addr + i * nbcols * 8);
+        u8 mask = 0x80;
+        u8 j;
+        for (j = 0; j < 8; j++) {
+            u8 data = 0x00;
+            if (GET_GLOBAL(fdata[src + i]) & mask)
+                data = attr;
+            SET_FARVAR(0xa000, dest[j], data);
+            mask >>= 1;
+        }
+    }
+}
+
+// -------------------------------------------------------------------
+static void
+biosfn_write_char_attr(u8 car, u8 page, u8 attr, u16 count)
+{
+    u8 cheight, xcurs, ycurs, mode, line, bpp;
+    u16 nbcols, nbrows;
+    u16 cursor, dummy;
+
+    // Get the mode
+    mode = GET_BDA(video_mode);
+    line = find_vga_entry(mode);
+    if (line == 0xFF)
+        return;
+
+    // Get the cursor pos for the page
+    biosfn_get_cursor_pos(page, &dummy, &cursor);
+    xcurs = cursor & 0x00ff;
+    ycurs = (cursor & 0xff00) >> 8;
+
+    // Get the dimensions
+    nbrows = GET_BDA(video_rows) + 1;
+    nbcols = GET_BDA(video_cols);
+
+    if (GET_GLOBAL(vga_modes[line].class) == TEXT) {
+        // Compute the address
+        void *address = (void*)(SCREEN_MEM_START(nbcols, nbrows, page)
+                                + (xcurs + ycurs * nbcols) * 2);
+
+        dummy = ((u16)attr << 8) + car;
+        memset16_far(GET_GLOBAL(vga_modes[line].sstart), address, dummy, count);
+    } else {
+        // FIXME gfx mode not complete
+        cheight = GET_GLOBAL(video_param_table[GET_GLOBAL(line_to_vpti[line])].cheight);
+        bpp = GET_GLOBAL(vga_modes[line].pixbits);
+        while ((count-- > 0) && (xcurs < nbcols)) {
+            switch (GET_GLOBAL(vga_modes[line].memmodel)) {
+            case PLANAR4:
+            case PLANAR1:
+                write_gfx_char_pl4(car, attr, xcurs, ycurs, nbcols,
+                                   cheight);
+                break;
+            case CGA:
+                write_gfx_char_cga(car, attr, xcurs, ycurs, nbcols, bpp);
+                break;
+            case LINEAR8:
+                write_gfx_char_lin(car, attr, xcurs, ycurs, nbcols);
+                break;
+#ifdef DEBUG
+            default:
+                unimplemented();
+#endif
+            }
+            xcurs++;
+        }
+    }
+}
+
+// -------------------------------------------------------------------
+static void
+biosfn_write_char_only(u8 car, u8 page, u8 attr, u16 count)
+{
+    u8 cheight, xcurs, ycurs, mode, line, bpp;
+    u16 nbcols, nbrows;
+    u16 cursor, dummy;
+
+    // Get the mode
+    mode = GET_BDA(video_mode);
+    line = find_vga_entry(mode);
+    if (line == 0xFF)
+        return;
+
+    // Get the cursor pos for the page
+    biosfn_get_cursor_pos(page, &dummy, &cursor);
+    xcurs = cursor & 0x00ff;
+    ycurs = (cursor & 0xff00) >> 8;
+
+    // Get the dimensions
+    nbrows = GET_BDA(video_rows) + 1;
+    nbcols = GET_BDA(video_cols);
+
+    if (GET_GLOBAL(vga_modes[line].class) == TEXT) {
+        // Compute the address
+        u8 *address = (void*)(SCREEN_MEM_START(nbcols, nbrows, page)
+                              + (xcurs + ycurs * nbcols) * 2);
+        while (count-- > 0) {
+            SET_FARVAR(GET_GLOBAL(vga_modes[line].sstart), *address, car);
+            address += 2;
+        }
+    } else {
+        // FIXME gfx mode not complete
+        cheight = GET_GLOBAL(video_param_table[GET_GLOBAL(line_to_vpti[line])].cheight);
+        bpp = GET_GLOBAL(vga_modes[line].pixbits);
+        while ((count-- > 0) && (xcurs < nbcols)) {
+            switch (GET_GLOBAL(vga_modes[line].memmodel)) {
+            case PLANAR4:
+            case PLANAR1:
+                write_gfx_char_pl4(car, attr, xcurs, ycurs, nbcols,
+                                   cheight);
+                break;
+            case CGA:
+                write_gfx_char_cga(car, attr, xcurs, ycurs, nbcols, bpp);
+                break;
+            case LINEAR8:
+                write_gfx_char_lin(car, attr, xcurs, ycurs, nbcols);
+                break;
+#ifdef DEBUG
+            default:
+                unimplemented();
+#endif
+            }
+            xcurs++;
+        }
+    }
+}
+
+
+
+// -------------------------------------------------------------------
+static void
+biosfn_set_border_color(struct bregs *regs)
+{
+    inb(VGAREG_ACTL_RESET);
+    outb(0x00, VGAREG_ACTL_ADDRESS);
+    u8 al = regs->bl & 0x0f;
+    if (al & 0x08)
+        al += 0x08;
+    outb(al, VGAREG_ACTL_ADDRESS);
+    u8 bl = regs->bl & 0x10;
+
+    int i;
+    for (i = 1; i < 4; i++) {
+        outb(i, VGAREG_ACTL_ADDRESS);
+
+        al = inb(VGAREG_ACTL_READ_DATA);
+        al &= 0xef;
+        al |= bl;
+        outb(al, VGAREG_ACTL_ADDRESS);
+    }
+    outb(0x20, VGAREG_ACTL_ADDRESS);
+}
+
+static void
+biosfn_set_palette(struct bregs *regs)
+{
+    inb(VGAREG_ACTL_RESET);
+    u8 bl = regs->bl & 0x01;
+    int i;
+    for (i = 1; i < 4; i++) {
+        outb(i, VGAREG_ACTL_ADDRESS);
+
+        u8 al = inb(VGAREG_ACTL_READ_DATA);
+        al &= 0xfe;
+        al |= bl;
+        outb(al, VGAREG_ACTL_ADDRESS);
+    }
+    outb(0x20, VGAREG_ACTL_ADDRESS);
+}
+
+// -------------------------------------------------------------------
+static void
+biosfn_write_pixel(u8 BH, u8 AL, u16 CX, u16 DX)
+{
+    u8 mask, attr, data;
+
+    // Get the mode
+    u8 mode = GET_BDA(video_mode);
+    u8 line = find_vga_entry(mode);
+    if (line == 0xFF)
+        return;
+    if (GET_GLOBAL(vga_modes[line].class) == TEXT)
+        return;
+
+    u8 *addr;
+    switch (GET_GLOBAL(vga_modes[line].memmodel)) {
+    case PLANAR4:
+    case PLANAR1:
+        addr = (void*)(CX / 8 + DX * GET_BDA(video_cols));
+        mask = 0x80 >> (CX & 0x07);
+        outw((mask << 8) | 0x08, VGAREG_GRDC_ADDRESS);
+        outw(0x0205, VGAREG_GRDC_ADDRESS);
+        data = GET_FARVAR(0xa000, *addr);
+        if (AL & 0x80)
+            outw(0x1803, VGAREG_GRDC_ADDRESS);
+        SET_FARVAR(0xa000, *addr, AL);
+        outw(0xff08, VGAREG_GRDC_ADDRESS);
+        outw(0x0005, VGAREG_GRDC_ADDRESS);
+        outw(0x0003, VGAREG_GRDC_ADDRESS);
+        break;
+    case CGA:
+        if (GET_GLOBAL(vga_modes[line].pixbits) == 2)
+            addr = (void*)((CX >> 2) + (DX >> 1) * 80);
+        else
+            addr = (void*)((CX >> 3) + (DX >> 1) * 80);
+        if (DX & 1)
+            addr += 0x2000;
+        data = GET_FARVAR(0xb800, *addr);
+        if (GET_GLOBAL(vga_modes[line].pixbits) == 2) {
+            attr = (AL & 0x03) << ((3 - (CX & 0x03)) * 2);
+            mask = 0x03 << ((3 - (CX & 0x03)) * 2);
+        } else {
+            attr = (AL & 0x01) << (7 - (CX & 0x07));
+            mask = 0x01 << (7 - (CX & 0x07));
+        }
+        if (AL & 0x80) {
+            data ^= attr;
+        } else {
+            data &= ~mask;
+            data |= attr;
+        }
+        SET_FARVAR(0xb800, *addr, data);
+        break;
+    case LINEAR8:
+        addr = (void*)(CX + DX * (GET_BDA(video_cols) * 8));
+        SET_FARVAR(0xa000, *addr, AL);
+        break;
+#ifdef DEBUG
+    default:
+        unimplemented();
+#endif
+    }
+}
+
+// -------------------------------------------------------------------
+static void
+biosfn_read_pixel(u8 BH, u16 CX, u16 DX, u16 *AX)
+{
+    u8 mode, line, mask, attr, data, i;
+
+    // Get the mode
+    mode = GET_BDA(video_mode);
+    line = find_vga_entry(mode);
+    if (line == 0xFF)
+        return;
+    if (GET_GLOBAL(vga_modes[line].class) == TEXT)
+        return;
+
+    u8 *addr;
+    switch (GET_GLOBAL(vga_modes[line].memmodel)) {
+    case PLANAR4:
+    case PLANAR1:
+        addr = (void*)(CX / 8 + DX * GET_BDA(video_cols));
+        mask = 0x80 >> (CX & 0x07);
+        attr = 0x00;
+        for (i = 0; i < 4; i++) {
+            outw((i << 8) | 0x04, VGAREG_GRDC_ADDRESS);
+            data = GET_FARVAR(0xa000, *addr) & mask;
+            if (data > 0)
+                attr |= (0x01 << i);
+        }
+        break;
+    case CGA:
+        addr = (void*)((CX >> 2) + (DX >> 1) * 80);
+        if (DX & 1)
+            addr += 0x2000;
+        data = GET_FARVAR(0xb800, *addr);
+        if (GET_GLOBAL(vga_modes[line].pixbits) == 2)
+            attr = (data >> ((3 - (CX & 0x03)) * 2)) & 0x03;
+        else
+            attr = (data >> (7 - (CX & 0x07))) & 0x01;
+        break;
+    case LINEAR8:
+        addr = (void*)(CX + DX * (GET_BDA(video_cols) * 8));
+        attr = GET_FARVAR(0xa000, *addr);
+        break;
+    default:
+#ifdef DEBUG
+        unimplemented();
+#endif
+        attr = 0;
+    }
+    *AX = (*AX & 0xff00) | attr;
+}
+
+// -------------------------------------------------------------------
+static void
+biosfn_write_teletype(u8 car, u8 page, u8 attr, u8 flag)
+{                               // flag = WITH_ATTR / NO_ATTR
+    u8 cheight, xcurs, ycurs, mode, line, bpp;
+    u16 nbcols, nbrows;
+    u16 cursor, dummy;
+
+    // special case if page is 0xff, use current page
+    if (page == 0xff)
+        page = GET_BDA(video_page);
+
+    // Get the mode
+    mode = GET_BDA(video_mode);
+    line = find_vga_entry(mode);
+    if (line == 0xFF)
+        return;
+
+    // Get the cursor pos for the page
+    biosfn_get_cursor_pos(page, &dummy, &cursor);
+    xcurs = cursor & 0x00ff;
+    ycurs = (cursor & 0xff00) >> 8;
+
+    // Get the dimensions
+    nbrows = GET_BDA(video_rows) + 1;
+    nbcols = GET_BDA(video_cols);
+
+    switch (car) {
+    case 7:
+        //FIXME should beep
+        break;
+
+    case 8:
+        if (xcurs > 0)
+            xcurs--;
+        break;
+
+    case '\r':
+        xcurs = 0;
+        break;
+
+    case '\n':
+        ycurs++;
+        break;
+
+    case '\t':
+        do {
+            biosfn_write_teletype(' ', page, attr, flag);
+            biosfn_get_cursor_pos(page, &dummy, &cursor);
+            xcurs = cursor & 0x00ff;
+            ycurs = (cursor & 0xff00) >> 8;
+        } while (xcurs % 8 == 0);
+        break;
+
+    default:
+
+        if (GET_GLOBAL(vga_modes[line].class) == TEXT) {
+            // Compute the address
+            u8 *address = (void*)(SCREEN_MEM_START(nbcols, nbrows, page)
+                                  + (xcurs + ycurs * nbcols) * 2);
+            // Write the char
+            SET_FARVAR(GET_GLOBAL(vga_modes[line].sstart), address[0], car);
+            if (flag == WITH_ATTR)
+                SET_FARVAR(GET_GLOBAL(vga_modes[line].sstart), address[1], attr);
+        } else {
+            // FIXME gfx mode not complete
+            cheight = GET_GLOBAL(video_param_table[GET_GLOBAL(line_to_vpti[line])].cheight);
+            bpp = GET_GLOBAL(vga_modes[line].pixbits);
+            switch (GET_GLOBAL(vga_modes[line].memmodel)) {
+            case PLANAR4:
+            case PLANAR1:
+                write_gfx_char_pl4(car, attr, xcurs, ycurs, nbcols,
+                                   cheight);
+                break;
+            case CGA:
+                write_gfx_char_cga(car, attr, xcurs, ycurs, nbcols, bpp);
+                break;
+            case LINEAR8:
+                write_gfx_char_lin(car, attr, xcurs, ycurs, nbcols);
+                break;
+#ifdef DEBUG
+            default:
+                unimplemented();
+#endif
+            }
+        }
+        xcurs++;
+    }
+
+    // Do we need to wrap ?
+    if (xcurs == nbcols) {
+        xcurs = 0;
+        ycurs++;
+    }
+    // Do we need to scroll ?
+    if (ycurs == nbrows) {
+        if (GET_GLOBAL(vga_modes[line].class) == TEXT)
+            biosfn_scroll(0x01, 0x07, 0, 0, nbrows - 1, nbcols - 1, page,
+                          SCROLL_UP);
+        else
+            biosfn_scroll(0x01, 0x00, 0, 0, nbrows - 1, nbcols - 1, page,
+                          SCROLL_UP);
+        ycurs -= 1;
+    }
+    // Set the cursor for the page
+    cursor = ycurs;
+    cursor <<= 8;
+    cursor += xcurs;
+    biosfn_set_cursor_pos(page, cursor);
+}
+
+// -------------------------------------------------------------------
+static void
+biosfn_get_video_mode(struct bregs *regs)
+{
+    regs->bh = GET_BDA(video_page);
+    regs->al = GET_BDA(video_mode) | (GET_BDA(video_ctl) & 0x80);
+    regs->ah = GET_BDA(video_cols);
+}
+
+// -------------------------------------------------------------------
+static void
+biosfn_set_overscan_border_color(struct bregs *regs)
+{
+    inb(VGAREG_ACTL_RESET);
+    outb(0x11, VGAREG_ACTL_ADDRESS);
+    outb(regs->bh, VGAREG_ACTL_ADDRESS);
+    outb(0x20, VGAREG_ACTL_ADDRESS);
+}
+
+// -------------------------------------------------------------------
+static void
+biosfn_set_all_palette_reg(struct bregs *regs)
+{
+    inb(VGAREG_ACTL_RESET);
+
+    u8 *data = (u8*)(regs->dx + 0);
+    int i;
+    for (i = 0; i < 0x10; i++) {
+        outb(i, VGAREG_ACTL_ADDRESS);
+        u8 val = GET_FARVAR(regs->es, *data);
+        outb(val, VGAREG_ACTL_ADDRESS);
+        data++;
+    }
+    outb(0x11, VGAREG_ACTL_ADDRESS);
+    outb(GET_FARVAR(regs->es, *data), VGAREG_ACTL_ADDRESS);
+    outb(0x20, VGAREG_ACTL_ADDRESS);
+}
+
+// -------------------------------------------------------------------
+static void
+biosfn_toggle_intensity(struct bregs *regs)
+{
+    inb(VGAREG_ACTL_RESET);
+    outb(0x10, VGAREG_ACTL_ADDRESS);
+    u8 val = (inb(VGAREG_ACTL_READ_DATA) & 0x7f) | ((regs->bl & 0x01) << 3);
+    outb(val, VGAREG_ACTL_ADDRESS);
+    outb(0x20, VGAREG_ACTL_ADDRESS);
+}
+
+// -------------------------------------------------------------------
+void
+biosfn_set_single_palette_reg(u8 reg, u8 val)
+{
+    inb(VGAREG_ACTL_RESET);
+    outb(reg, VGAREG_ACTL_ADDRESS);
+    outb(val, VGAREG_ACTL_ADDRESS);
+    outb(0x20, VGAREG_ACTL_ADDRESS);
+}
+
+// -------------------------------------------------------------------
+u8
+biosfn_get_single_palette_reg(u8 reg)
+{
+    inb(VGAREG_ACTL_RESET);
+    outb(reg, VGAREG_ACTL_ADDRESS);
+    u8 v = inb(VGAREG_ACTL_READ_DATA);
+    inb(VGAREG_ACTL_RESET);
+    outb(0x20, VGAREG_ACTL_ADDRESS);
+    return v;
+}
+
+// -------------------------------------------------------------------
+static void
+biosfn_read_overscan_border_color(struct bregs *regs)
+{
+    inb(VGAREG_ACTL_RESET);
+    outb(0x11, VGAREG_ACTL_ADDRESS);
+    regs->bh = inb(VGAREG_ACTL_READ_DATA);
+    inb(VGAREG_ACTL_RESET);
+    outb(0x20, VGAREG_ACTL_ADDRESS);
+}
+
+// -------------------------------------------------------------------
+static void
+biosfn_get_all_palette_reg(struct bregs *regs)
+{
+    u8 *data = (u8*)(regs->dx + 0);
+    int i;
+    for (i = 0; i < 0x10; i++) {
+        inb(VGAREG_ACTL_RESET);
+        outb(i, VGAREG_ACTL_ADDRESS);
+        SET_FARVAR(regs->es, *data, inb(VGAREG_ACTL_READ_DATA));
+        data++;
+    }
+    inb(VGAREG_ACTL_RESET);
+    outb(0x11, VGAREG_ACTL_ADDRESS);
+    SET_FARVAR(regs->es, *data, inb(VGAREG_ACTL_READ_DATA));
+    inb(VGAREG_ACTL_RESET);
+    outb(0x20, VGAREG_ACTL_ADDRESS);
+}
+
+// -------------------------------------------------------------------
+static void
+biosfn_set_single_dac_reg(struct bregs *regs)
+{
+    outb(regs->bl, VGAREG_DAC_WRITE_ADDRESS);
+    outb(regs->dh, VGAREG_DAC_DATA);
+    outb(regs->ch, VGAREG_DAC_DATA);
+    outb(regs->cl, VGAREG_DAC_DATA);
+}
+
+// -------------------------------------------------------------------
+static void
+biosfn_set_all_dac_reg(struct bregs *regs)
+{
+    outb(regs->bl, VGAREG_DAC_WRITE_ADDRESS);
+    u8 *data = (u8*)(regs->dx + 0);
+    int count = regs->cx;
+    while (count) {
+        outb(GET_FARVAR(regs->es, *data), VGAREG_DAC_DATA);
+        data++;
+        outb(GET_FARVAR(regs->es, *data), VGAREG_DAC_DATA);
+        data++;
+        outb(GET_FARVAR(regs->es, *data), VGAREG_DAC_DATA);
+        data++;
+        count--;
+    }
+}
+
+// -------------------------------------------------------------------
+static void
+biosfn_select_video_dac_color_page(struct bregs *regs)
+{
+    inb(VGAREG_ACTL_RESET);
+    outb(0x10, VGAREG_ACTL_ADDRESS);
+    u8 val = inb(VGAREG_ACTL_READ_DATA);
+    if (!(regs->bl & 0x01)) {
+        val = (val & 0x7f) | (regs->bh << 7);
+        outb(val, VGAREG_ACTL_ADDRESS);
+        outb(0x20, VGAREG_ACTL_ADDRESS);
+        return;
+    }
+    inb(VGAREG_ACTL_RESET);
+    outb(0x14, VGAREG_ACTL_ADDRESS);
+    u8 bh = regs->bh;
+    if (!(val & 0x80))
+        bh <<= 2;
+    bh &= 0x0f;
+    outb(bh, VGAREG_ACTL_ADDRESS);
+    outb(0x20, VGAREG_ACTL_ADDRESS);
+}
+
+// -------------------------------------------------------------------
+static void
+biosfn_read_single_dac_reg(struct bregs *regs)
+{
+    outb(regs->bl, VGAREG_DAC_READ_ADDRESS);
+    regs->dh = inb(VGAREG_DAC_DATA);
+    regs->ch = inb(VGAREG_DAC_DATA);
+    regs->cl = inb(VGAREG_DAC_DATA);
+}
+
+// -------------------------------------------------------------------
+static void
+biosfn_read_all_dac_reg(struct bregs *regs)
+{
+    outb(regs->bl, VGAREG_DAC_READ_ADDRESS);
+    u8 *data = (u8*)(regs->dx + 0);
+    int count = regs->cx;
+    while (count) {
+        SET_FARVAR(regs->es, *data, inb(VGAREG_DAC_DATA));
+        data++;
+        SET_FARVAR(regs->es, *data, inb(VGAREG_DAC_DATA));
+        data++;
+        SET_FARVAR(regs->es, *data, inb(VGAREG_DAC_DATA));
+        data++;
+        count--;
+    }
+}
+
+// -------------------------------------------------------------------
+static void
+biosfn_set_pel_mask(struct bregs *regs)
+{
+    outb(regs->bl, VGAREG_PEL_MASK);
+}
+
+// -------------------------------------------------------------------
+static void
+biosfn_read_pel_mask(struct bregs *regs)
+{
+    regs->bl = inb(VGAREG_PEL_MASK);
+}
+
+// -------------------------------------------------------------------
+static void
+biosfn_read_video_dac_state(struct bregs *regs)
+{
+    inb(VGAREG_ACTL_RESET);
+    outb(0x10, VGAREG_ACTL_ADDRESS);
+    u8 val1 = inb(VGAREG_ACTL_READ_DATA) >> 7;
+
+    inb(VGAREG_ACTL_RESET);
+    outb(0x14, VGAREG_ACTL_ADDRESS);
+    u8 val2 = inb(VGAREG_ACTL_READ_DATA) & 0x0f;
+    if (!(val1 & 0x01))
+        val2 >>= 2;
+
+    inb(VGAREG_ACTL_RESET);
+    outb(0x20, VGAREG_ACTL_ADDRESS);
+
+    regs->bl = val1;
+    regs->bh = val2;
+}
+
+// -------------------------------------------------------------------
+static void
+get_font_access()
+{
+    outw(0x0100, VGAREG_SEQU_ADDRESS);
+    outw(0x0402, VGAREG_SEQU_ADDRESS);
+    outw(0x0704, VGAREG_SEQU_ADDRESS);
+    outw(0x0300, VGAREG_SEQU_ADDRESS);
+    outw(0x0204, VGAREG_GRDC_ADDRESS);
+    outw(0x0005, VGAREG_GRDC_ADDRESS);
+    outw(0x0406, VGAREG_GRDC_ADDRESS);
+}
+
+static void
+release_font_access()
+{
+    outw(0x0100, VGAREG_SEQU_ADDRESS);
+    outw(0x0302, VGAREG_SEQU_ADDRESS);
+    outw(0x0304, VGAREG_SEQU_ADDRESS);
+    outw(0x0300, VGAREG_SEQU_ADDRESS);
+    u16 v = inw(VGAREG_READ_MISC_OUTPUT);
+    v = ((v & 0x01) << 10) | 0x0a06;
+    outw(v, VGAREG_GRDC_ADDRESS);
+    outw(0x0004, VGAREG_GRDC_ADDRESS);
+    outw(0x1005, VGAREG_GRDC_ADDRESS);
+}
+
+static void
+set_scan_lines(u8 lines)
+{
+    u16 crtc_addr, cols, vde;
+    u8 crtc_r9, ovl, rows;
+
+    crtc_addr = GET_BDA(crtc_address);
+    outb(0x09, crtc_addr);
+    crtc_r9 = inb(crtc_addr + 1);
+    crtc_r9 = (crtc_r9 & 0xe0) | (lines - 1);
+    outb(crtc_r9, crtc_addr + 1);
+    if (lines == 8)
+        biosfn_set_cursor_shape(0x06, 0x07);
+    else
+        biosfn_set_cursor_shape(lines - 4, lines - 3);
+    SET_BDA(char_height, lines);
+    outb(0x12, crtc_addr);
+    vde = inb(crtc_addr + 1);
+    outb(0x07, crtc_addr);
+    ovl = inb(crtc_addr + 1);
+    vde += (((ovl & 0x02) << 7) + ((ovl & 0x40) << 3) + 1);
+    rows = vde / lines;
+    SET_BDA(video_rows, rows - 1);
+    cols = GET_BDA(video_cols);
+    SET_BDA(video_pagesize, rows * cols * 2);
+}
+
+static void
+biosfn_load_text_user_pat(u8 AL, u16 ES, u16 BP, u16 CX, u16 DX, u8 BL,
+                          u8 BH)
+{
+    get_font_access();
+    u16 blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11);
+    u16 i;
+    for (i = 0; i < CX; i++) {
+        void *src = (void*)(BP + i * BH);
+        void *dest = (void*)(blockaddr + (DX + i) * 32);
+        memcpy_far(0xA000, dest, ES, src, BH);
+    }
+    release_font_access();
+    if (AL >= 0x10)
+        set_scan_lines(BH);
+}
+
+static void
+biosfn_load_text_8_14_pat(u8 AL, u8 BL)
+{
+    get_font_access();
+    u16 blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11);
+    u16 i;
+    for (i = 0; i < 0x100; i++) {
+        u16 src = i * 14;
+        void *dest = (void*)(blockaddr + i * 32);
+        memcpy_far(0xA000, dest, 0xC000, &vgafont14[src], 14);
+    }
+    release_font_access();
+    if (AL >= 0x10)
+        set_scan_lines(14);
+}
+
+static void
+biosfn_load_text_8_8_pat(u8 AL, u8 BL)
+{
+    get_font_access();
+    u16 blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11);
+    u16 i;
+    for (i = 0; i < 0x100; i++) {
+        u16 src = i * 8;
+        void *dest = (void*)(blockaddr + i * 32);
+        memcpy_far(0xA000, dest, 0xC000, &vgafont8[src], 8);
+    }
+    release_font_access();
+    if (AL >= 0x10)
+        set_scan_lines(8);
+}
+
+// -------------------------------------------------------------------
+static void
+biosfn_set_text_block_specifier(struct bregs *regs)
+{
+    outw((regs->bl << 8) | 0x03, VGAREG_SEQU_ADDRESS);
+}
+
+// -------------------------------------------------------------------
+static void
+biosfn_load_text_8_16_pat(u8 AL, u8 BL)
+{
+    get_font_access();
+    u16 blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11);
+    u16 i;
+    for (i = 0; i < 0x100; i++) {
+        u16 src = i * 16;
+        void *dest = (void*)(blockaddr + i * 32);
+        memcpy_far(0xA000, dest, 0xC000, &vgafont16[src], 16);
+    }
+    release_font_access();
+    if (AL >= 0x10)
+        set_scan_lines(16);
+}
+
+// -------------------------------------------------------------------
+static void
+biosfn_get_font_info(u8 BH, u16 *ES, u16 *BP, u16 *CX, u16 *DX)
+{
+    switch (BH) {
+    case 0x00: {
+        u32 segoff = GET_IVT(0x1f).segoff;
+        *ES = segoff >> 16;
+        *BP = segoff;
+        break;
+    }
+    case 0x01: {
+        u32 segoff = GET_IVT(0x43).segoff;
+        *ES = segoff >> 16;
+        *BP = segoff;
+        break;
+    }
+    case 0x02:
+        *ES = 0xC000;
+        *BP = (u32)vgafont14;
+        break;
+    case 0x03:
+        *ES = 0xC000;
+        *BP = (u32)vgafont8;
+        break;
+    case 0x04:
+        *ES = 0xC000;
+        *BP = (u32)vgafont8 + 128 * 8;
+        break;
+    case 0x05:
+        *ES = 0xC000;
+        *BP = (u32)vgafont14alt;
+        break;
+    case 0x06:
+        *ES = 0xC000;
+        *BP = (u32)vgafont16;
+        break;
+    case 0x07:
+        *ES = 0xC000;
+        *BP = (u32)vgafont16alt;
+        break;
+    default:
+#ifdef DEBUG
+        printf("Get font info BH(%02x) was discarded\n", BH);
+#endif
+        return;
+    }
+    // Set byte/char of on screen font
+    *CX = GET_BDA(char_height) & 0xff;
+
+    // Set Highest char row
+    *DX = GET_BDA(video_rows);
+}
+
+// -------------------------------------------------------------------
+static void
+biosfn_get_ega_info(struct bregs *regs)
+{
+    regs->cx = GET_BDA(video_switches) & 0x0f;
+    regs->ax = GET_BDA(crtc_address);
+    if (regs->ax == VGAREG_MDA_CRTC_ADDRESS)
+        regs->bx = 0x0103;
+    else
+        regs->bx = 0x0003;
+}
+
+// -------------------------------------------------------------------
+static void
+biosfn_select_vert_res(struct bregs *regs)
+{
+    u8 mctl = GET_BDA(modeset_ctl);
+    u8 vswt = GET_BDA(video_switches);
+
+    switch (regs->al) {
+    case 0x00:
+        // 200 lines
+        mctl = (mctl & ~0x10) | 0x80;
+        vswt = (vswt & ~0x0f) | 0x08;
+        break;
+    case 0x01:
+        // 350 lines
+        mctl &= ~0x90;
+        vswt = (vswt & ~0x0f) | 0x09;
+        break;
+    case 0x02:
+        // 400 lines
+        mctl = (mctl & ~0x80) | 0x10;
+        vswt = (vswt & ~0x0f) | 0x09;
+        break;
+    default:
+#ifdef DEBUG
+        printf("Select vert res (%02x) was discarded\n");
+#endif
+        break;
+    }
+    SET_BDA(modeset_ctl, mctl);
+    SET_BDA(video_switches, vswt);
+    regs->ax = 0x1212;
+}
+
+static void
+biosfn_enable_default_palette_loading(struct bregs *regs)
+{
+    u8 v = (regs->al & 0x01) << 3;
+    u8 mctl = GET_BDA(video_ctl) & ~0x08;
+    SET_BDA(video_ctl, mctl | v);
+    regs->ax = 0x1212;
+}
+
+static void
+biosfn_enable_video_addressing(struct bregs *regs)
+{
+    u8 v = ((regs->al << 1) & 0x02) ^ 0x02;
+    u8 v2 = inb(VGAREG_READ_MISC_OUTPUT) & ~0x02;
+    outb(v | v2, VGAREG_WRITE_MISC_OUTPUT);
+    regs->ax = 0x1212;
+}
+
+
+static void
+biosfn_enable_grayscale_summing(struct bregs *regs)
+{
+    u8 v = ((regs->al << 1) & 0x02) ^ 0x02;
+    u8 v2 = GET_BDA(modeset_ctl) & ~0x02;
+    SET_BDA(modeset_ctl, v | v2);
+    regs->ax = 0x1212;
+}
+
+static void
+biosfn_enable_cursor_emulation(struct bregs *regs)
+{
+    u8 v = (regs->al & 0x01) ^ 0x01;
+    u8 v2 = GET_BDA(modeset_ctl) & ~0x01;
+    SET_BDA(modeset_ctl, v | v2);
+    regs->ax = 0x1212;
+}
+
+// -------------------------------------------------------------------
+static void
+biosfn_write_string(u8 flag, u8 page, u8 attr, u16 count, u8 row, u8 col,
+                    u16 seg, u8 *offset)
+{
+    u16 newcurs, oldcurs, dummy;
+    u8 car;
+
+    // Read curs info for the page
+    biosfn_get_cursor_pos(page, &dummy, &oldcurs);
+
+    // if row=0xff special case : use current cursor position
+    if (row == 0xff) {
+        col = oldcurs & 0x00ff;
+        row = (oldcurs & 0xff00) >> 8;
+    }
+
+    newcurs = row;
+    newcurs <<= 8;
+    newcurs += col;
+    biosfn_set_cursor_pos(page, newcurs);
+
+    while (count-- != 0) {
+        car = GET_FARVAR(seg, *offset);
+        offset++;
+        if ((flag & 0x02) != 0) {
+            attr = GET_FARVAR(seg, *offset);
+            offset++;
+        }
+
+        biosfn_write_teletype(car, page, attr, WITH_ATTR);
+    }
+
+    // Set back curs pos
+    if ((flag & 0x01) == 0)
+        biosfn_set_cursor_pos(page, oldcurs);
+}
+
+// -------------------------------------------------------------------
+static void
+biosfn_read_display_code(struct bregs *regs)
+{
+    regs->bx = GET_BDA(dcc_index);
+    regs->al = 0x1a;
+}
+
+static void
+biosfn_set_display_code(struct bregs *regs)
+{
+    SET_BDA(dcc_index, regs->bl);
+#ifdef DEBUG
+    printf("Alternate Display code (%02x) was discarded", regs->bh);
+#endif
+    regs->al = 0x1a;
+}
+
+// -------------------------------------------------------------------
+static void
+biosfn_read_state_info(u16 BX, u16 ES, u16 DI)
+{
+    // Address of static functionality table
+    SET_FARVAR(ES, *(u16*)(DI + 0x00), (u32)static_functionality);
+    SET_FARVAR(ES, *(u16*)(DI + 0x02), 0xC000);
+
+    // Hard coded copy from BIOS area. Should it be cleaner ?
+    memcpy_far(ES, (void*)(DI + 0x04), SEG_BDA, (void*)0x49, 30);
+    memcpy_far(ES, (void*)(DI + 0x22), SEG_BDA, (void*)0x84, 3);
+
+    SET_FARVAR(ES, *(u8*)(DI + 0x25), GET_BDA(dcc_index));
+    SET_FARVAR(ES, *(u8*)(DI + 0x26), 0);
+    SET_FARVAR(ES, *(u8*)(DI + 0x27), 16);
+    SET_FARVAR(ES, *(u8*)(DI + 0x28), 0);
+    SET_FARVAR(ES, *(u8*)(DI + 0x29), 8);
+    SET_FARVAR(ES, *(u8*)(DI + 0x2a), 2);
+    SET_FARVAR(ES, *(u8*)(DI + 0x2b), 0);
+    SET_FARVAR(ES, *(u8*)(DI + 0x2c), 0);
+    SET_FARVAR(ES, *(u8*)(DI + 0x31), 3);
+    SET_FARVAR(ES, *(u8*)(DI + 0x32), 0);
+
+    memset_far(ES, (void*)(DI + 0x33), 0, 13);
+}
+
+// -------------------------------------------------------------------
+// -------------------------------------------------------------------
+static u16
+biosfn_read_video_state_size(u16 CX)
+{
+    u16 size = 0;
+    if (CX & 1)
+        size += 0x46;
+    if (CX & 2)
+        size += (5 + 8 + 5) * 2 + 6;
+    if (CX & 4)
+        size += 3 + 256 * 3 + 1;
+    return size;
+}
+
+static u16
+biosfn_save_video_state(u16 CX, u16 ES, u16 BX)
+{
+    u16 i, crtc_addr, ar_index;
+
+    crtc_addr = GET_BDA(crtc_address);
+    if (CX & 1) {
+        SET_FARVAR(ES, *(u8*)(BX+0), inb(VGAREG_SEQU_ADDRESS));
+        BX++;
+        SET_FARVAR(ES, *(u8*)(BX+0), inb(crtc_addr));
+        BX++;
+        SET_FARVAR(ES, *(u8*)(BX+0), inb(VGAREG_GRDC_ADDRESS));
+        BX++;
+        inb(VGAREG_ACTL_RESET);
+        ar_index = inb(VGAREG_ACTL_ADDRESS);
+        SET_FARVAR(ES, *(u8*)(BX+0), ar_index);
+        BX++;
+        SET_FARVAR(ES, *(u8*)(BX+0), inb(VGAREG_READ_FEATURE_CTL));
+        BX++;
+
+        for (i = 1; i <= 4; i++) {
+            outb(i, VGAREG_SEQU_ADDRESS);
+            SET_FARVAR(ES, *(u8*)(BX+0), inb(VGAREG_SEQU_DATA));
+            BX++;
+        }
+        outb(0, VGAREG_SEQU_ADDRESS);
+        SET_FARVAR(ES, *(u8*)(BX+0), inb(VGAREG_SEQU_DATA));
+        BX++;
+
+        for (i = 0; i <= 0x18; i++) {
+            outb(i, crtc_addr);
+            SET_FARVAR(ES, *(u8*)(BX+0), inb(crtc_addr + 1));
+            BX++;
+        }
+
+        for (i = 0; i <= 0x13; i++) {
+            inb(VGAREG_ACTL_RESET);
+            outb(i | (ar_index & 0x20), VGAREG_ACTL_ADDRESS);
+            SET_FARVAR(ES, *(u8*)(BX+0), inb(VGAREG_ACTL_READ_DATA));
+            BX++;
+        }
+        inb(VGAREG_ACTL_RESET);
+
+        for (i = 0; i <= 8; i++) {
+            outb(i, VGAREG_GRDC_ADDRESS);
+            SET_FARVAR(ES, *(u8*)(BX+0), inb(VGAREG_GRDC_DATA));
+            BX++;
+        }
+
+        SET_FARVAR(ES, *(u16*)(BX+0), crtc_addr);
+        BX += 2;
+
+        /* XXX: read plane latches */
+        SET_FARVAR(ES, *(u8*)(BX+0), 0);
+        BX++;
+        SET_FARVAR(ES, *(u8*)(BX+0), 0);
+        BX++;
+        SET_FARVAR(ES, *(u8*)(BX+0), 0);
+        BX++;
+        SET_FARVAR(ES, *(u8*)(BX+0), 0);
+        BX++;
+    }
+    if (CX & 2) {
+        SET_FARVAR(ES, *(u8*)(BX+0), GET_BDA(video_mode));
+        BX++;
+        SET_FARVAR(ES, *(u16*)(BX+0), GET_BDA(video_cols));
+        BX += 2;
+        SET_FARVAR(ES, *(u16*)(BX+0), GET_BDA(video_pagesize));
+        BX += 2;
+        SET_FARVAR(ES, *(u16*)(BX+0), GET_BDA(crtc_address));
+        BX += 2;
+        SET_FARVAR(ES, *(u8*)(BX+0), GET_BDA(video_rows));
+        BX++;
+        SET_FARVAR(ES, *(u16*)(BX+0), GET_BDA(char_height));
+        BX += 2;
+        SET_FARVAR(ES, *(u8*)(BX+0), GET_BDA(video_ctl));
+        BX++;
+        SET_FARVAR(ES, *(u8*)(BX+0), GET_BDA(video_switches));
+        BX++;
+        SET_FARVAR(ES, *(u8*)(BX+0), GET_BDA(modeset_ctl));
+        BX++;
+        SET_FARVAR(ES, *(u16*)(BX+0), GET_BDA(cursor_type));
+        BX += 2;
+        for (i = 0; i < 8; i++) {
+            SET_FARVAR(ES, *(u16*)(BX+0), GET_BDA(cursor_pos[i]));
+            BX += 2;
+        }
+        SET_FARVAR(ES, *(u16*)(BX+0), GET_BDA(video_pagestart));
+        BX += 2;
+        SET_FARVAR(ES, *(u8*)(BX+0), GET_BDA(video_page));
+        BX++;
+        /* current font */
+        SET_FARVAR(ES, *(u16*)(BX+0), GET_FARVAR(0, *(u16*)(0x1f * 4)));
+        BX += 2;
+        SET_FARVAR(ES, *(u16*)(BX+0), GET_FARVAR(0, *(u16*)(0x1f * 4 + 2)));
+        BX += 2;
+        SET_FARVAR(ES, *(u16*)(BX+0), GET_FARVAR(0, *(u16*)(0x43 * 4)));
+        BX += 2;
+        SET_FARVAR(ES, *(u16*)(BX+0), GET_FARVAR(0, *(u16*)(0x43 * 4 + 2)));
+        BX += 2;
+    }
+    if (CX & 4) {
+        /* XXX: check this */
+        SET_FARVAR(ES, *(u8*)(BX+0), inb(VGAREG_DAC_STATE));
+        BX++;                   /* read/write mode dac */
+        SET_FARVAR(ES, *(u8*)(BX+0), inb(VGAREG_DAC_WRITE_ADDRESS));
+        BX++;                   /* pix address */
+        SET_FARVAR(ES, *(u8*)(BX+0), inb(VGAREG_PEL_MASK));
+        BX++;
+        // Set the whole dac always, from 0
+        outb(0x00, VGAREG_DAC_WRITE_ADDRESS);
+        for (i = 0; i < 256 * 3; i++) {
+            SET_FARVAR(ES, *(u8*)(BX+0), inb(VGAREG_DAC_DATA));
+            BX++;
+        }
+        SET_FARVAR(ES, *(u8*)(BX+0), 0);
+        BX++;                   /* color select register */
+    }
+    return BX;
+}
+
+static u16
+biosfn_restore_video_state(u16 CX, u16 ES, u16 BX)
+{
+    u16 i, crtc_addr, v, addr1, ar_index;
+
+    if (CX & 1) {
+        // Reset Attribute Ctl flip-flop
+        inb(VGAREG_ACTL_RESET);
+
+        crtc_addr = GET_FARVAR(ES, *(u16*)(BX + 0x40));
+        addr1 = BX;
+        BX += 5;
+
+        for (i = 1; i <= 4; i++) {
+            outb(i, VGAREG_SEQU_ADDRESS);
+            outb(GET_FARVAR(ES, *(u8*)(BX+0)), VGAREG_SEQU_DATA);
+            BX++;
+        }
+        outb(0, VGAREG_SEQU_ADDRESS);
+        outb(GET_FARVAR(ES, *(u8*)(BX+0)), VGAREG_SEQU_DATA);
+        BX++;
+
+        // Disable CRTC write protection
+        outw(0x0011, crtc_addr);
+        // Set CRTC regs
+        for (i = 0; i <= 0x18; i++) {
+            if (i != 0x11) {
+                outb(i, crtc_addr);
+                outb(GET_FARVAR(ES, *(u8*)(BX+0)), crtc_addr + 1);
+            }
+            BX++;
+        }
+        // select crtc base address
+        v = inb(VGAREG_READ_MISC_OUTPUT) & ~0x01;
+        if (crtc_addr == 0x3d4)
+            v |= 0x01;
+        outb(v, VGAREG_WRITE_MISC_OUTPUT);
+
+        // enable write protection if needed
+        outb(0x11, crtc_addr);
+        outb(GET_FARVAR(ES, *(u8*)(BX - 0x18 + 0x11)), crtc_addr + 1);
+
+        // Set Attribute Ctl
+        ar_index = GET_FARVAR(ES, *(u8*)(addr1 + 0x03));
+        inb(VGAREG_ACTL_RESET);
+        for (i = 0; i <= 0x13; i++) {
+            outb(i | (ar_index & 0x20), VGAREG_ACTL_ADDRESS);
+            outb(GET_FARVAR(ES, *(u8*)(BX+0)), VGAREG_ACTL_WRITE_DATA);
+            BX++;
+        }
+        outb(ar_index, VGAREG_ACTL_ADDRESS);
+        inb(VGAREG_ACTL_RESET);
+
+        for (i = 0; i <= 8; i++) {
+            outb(i, VGAREG_GRDC_ADDRESS);
+            outb(GET_FARVAR(ES, *(u8*)(BX+0)), VGAREG_GRDC_DATA);
+            BX++;
+        }
+        BX += 2;                /* crtc_addr */
+        BX += 4;                /* plane latches */
+
+        outb(GET_FARVAR(ES, *(u8*)(addr1+0)), VGAREG_SEQU_ADDRESS);
+        addr1++;
+        outb(GET_FARVAR(ES, *(u8*)(addr1+0)), crtc_addr);
+        addr1++;
+        outb(GET_FARVAR(ES, *(u8*)(addr1+0)), VGAREG_GRDC_ADDRESS);
+        addr1++;
+        addr1++;
+        outb(GET_FARVAR(ES, *(u8*)(addr1+0)), crtc_addr - 0x4 + 0xa);
+        addr1++;
+    }
+    if (CX & 2) {
+        SET_BDA(video_mode, GET_FARVAR(ES, *(u8*)(BX+0)));
+        BX++;
+        SET_BDA(video_cols, GET_FARVAR(ES, *(u16*)(BX+0)));
+        BX += 2;
+        SET_BDA(video_pagesize, GET_FARVAR(ES, *(u16*)(BX+0)));
+        BX += 2;
+        SET_BDA(crtc_address, GET_FARVAR(ES, *(u16*)(BX+0)));
+        BX += 2;
+        SET_BDA(video_rows, GET_FARVAR(ES, *(u8*)(BX+0)));
+        BX++;
+        SET_BDA(char_height, GET_FARVAR(ES, *(u16*)(BX+0)));
+        BX += 2;
+        SET_BDA(video_ctl, GET_FARVAR(ES, *(u8*)(BX+0)));
+        BX++;
+        SET_BDA(video_switches, GET_FARVAR(ES, *(u8*)(BX+0)));
+        BX++;
+        SET_BDA(modeset_ctl, GET_FARVAR(ES, *(u8*)(BX+0)));
+        BX++;
+        SET_BDA(cursor_type, GET_FARVAR(ES, *(u16*)(BX+0)));
+        BX += 2;
+        for (i = 0; i < 8; i++) {
+            SET_BDA(cursor_pos[i], GET_FARVAR(ES, *(u16*)(BX+0)));
+            BX += 2;
+        }
+        SET_BDA(video_pagestart, GET_FARVAR(ES, *(u16*)(BX+0)));
+        BX += 2;
+        SET_BDA(video_page, GET_FARVAR(ES, *(u8*)(BX+0)));
+        BX++;
+        /* current font */
+        SET_IVT(0x1f, GET_FARVAR(ES, *(u16*)(BX+2)), GET_FARVAR(ES, *(u16*)(BX+0)));
+        BX += 4;
+        SET_IVT(0x43, GET_FARVAR(ES, *(u16*)(BX+2)), GET_FARVAR(ES, *(u16*)(BX+0)));
+        BX += 4;
+    }
+    if (CX & 4) {
+        BX++;
+        v = GET_FARVAR(ES, *(u8*)(BX+0));
+        BX++;
+        outb(GET_FARVAR(ES, *(u8*)(BX+0)), VGAREG_PEL_MASK);
+        BX++;
+        // Set the whole dac always, from 0
+        outb(0x00, VGAREG_DAC_WRITE_ADDRESS);
+        for (i = 0; i < 256 * 3; i++) {
+            outb(GET_FARVAR(ES, *(u8*)(BX+0)), VGAREG_DAC_DATA);
+            BX++;
+        }
+        BX++;
+        outb(v, VGAREG_DAC_WRITE_ADDRESS);
+    }
+    return BX;
+}
+
+
+/****************************************************************
+ * VGA int 10 handler
+ ****************************************************************/
+
+static void
+handle_1000(struct bregs *regs)
+{
+    // XXX - inline
+    biosfn_set_video_mode(regs->al);
+    switch(regs->al & 0x7F) {
+    case 6:
+        regs->al = 0x3F;
+        break;
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+    case 5:
+    case 7:
+        regs->al = 0x30;
+        break;
+    default:
+        regs->al = 0x20;
+    }
+}
+
+static void
+handle_1001(struct bregs *regs)
+{
+    biosfn_set_cursor_shape(regs->ch, regs->cl);
+}
+
+static void
+handle_1002(struct bregs *regs)
+{
+    biosfn_set_cursor_pos(regs->bh, regs->dx);
+}
+
+static void
+handle_1003(struct bregs *regs)
+{
+    biosfn_get_cursor_pos(regs->bh, &regs->cx, &regs->dx);
+}
+
+// Read light pen pos (unimplemented)
+static void
+handle_1004(struct bregs *regs)
+{
+    debug_stub(regs);
+    regs->ax = regs->bx = regs->cx = regs->dx = 0;
+}
+
+static void
+handle_1005(struct bregs *regs)
+{
+    biosfn_set_active_page(regs->al);
+}
+
+static void
+handle_1006(struct bregs *regs)
+{
+    biosfn_scroll(regs->al, regs->bh, regs->ch, regs->cl, regs->dh, regs->dl
+                  , 0xFF, SCROLL_UP);
+}
+
+static void
+handle_1007(struct bregs *regs)
+{
+    biosfn_scroll(regs->al, regs->bh, regs->ch, regs->cl, regs->dh, regs->dl
+                  , 0xFF, SCROLL_DOWN);
+}
+
+static void
+handle_1008(struct bregs *regs)
+{
+    // XXX - inline
+    biosfn_read_char_attr(regs->bh, &regs->ax);
+}
+
+static void
+handle_1009(struct bregs *regs)
+{
+    // XXX - inline
+    biosfn_write_char_attr(regs->al, regs->bh, regs->bl, regs->cx);
+}
+
+static void
+handle_100a(struct bregs *regs)
+{
+    // XXX - inline
+    biosfn_write_char_only(regs->al, regs->bh, regs->bl, regs->cx);
+}
+
+
+static void
+handle_100b00(struct bregs *regs)
+{
+    // XXX - inline
+    biosfn_set_border_color(regs);
+}
+
+static void
+handle_100b01(struct bregs *regs)
+{
+    // XXX - inline
+    biosfn_set_palette(regs);
+}
+
+static void
+handle_100bXX(struct bregs *regs)
+{
+    debug_stub(regs);
+}
+
+static void
+handle_100b(struct bregs *regs)
+{
+    switch (regs->bh) {
+    case 0x00: handle_100b00(regs); break;
+    case 0x01: handle_100b01(regs); break;
+    default:   handle_100bXX(regs); break;
+    }
+}
+
+
+static void
+handle_100c(struct bregs *regs)
+{
+    // XXX - inline
+    biosfn_write_pixel(regs->bh, regs->al, regs->cx, regs->dx);
+}
+
+static void
+handle_100d(struct bregs *regs)
+{
+    // XXX - inline
+    biosfn_read_pixel(regs->bh, regs->cx, regs->dx, &regs->ax);
+}
+
+static void
+handle_100e(struct bregs *regs)
+{
+    // Ralf Brown Interrupt list is WRONG on bh(page)
+    // We do output only on the current page !
+    biosfn_write_teletype(regs->al, 0xff, regs->bl, NO_ATTR);
+}
+
+static void
+handle_100f(struct bregs *regs)
+{
+    // XXX - inline
+    biosfn_get_video_mode(regs);
+}
+
+
+static void
+handle_101000(struct bregs *regs)
+{
+    if (regs->bl > 0x14)
+        return;
+    biosfn_set_single_palette_reg(regs->bl, regs->bh);
+}
+
+static void
+handle_101001(struct bregs *regs)
+{
+    // XXX - inline
+    biosfn_set_overscan_border_color(regs);
+}
+
+static void
+handle_101002(struct bregs *regs)
+{
+    // XXX - inline
+    biosfn_set_all_palette_reg(regs);
+}
+
+static void
+handle_101003(struct bregs *regs)
+{
+    // XXX - inline
+    biosfn_toggle_intensity(regs);
+}
+
+static void
+handle_101007(struct bregs *regs)
+{
+    if (regs->bl > 0x14)
+        return;
+    regs->bh = biosfn_get_single_palette_reg(regs->bl);
+}
+
+static void
+handle_101008(struct bregs *regs)
+{
+    // XXX - inline
+    biosfn_read_overscan_border_color(regs);
+}
+
+static void
+handle_101009(struct bregs *regs)
+{
+    // XXX - inline
+    biosfn_get_all_palette_reg(regs);
+}
+
+static void
+handle_101010(struct bregs *regs)
+{
+    // XXX - inline
+    biosfn_set_single_dac_reg(regs);
+}
+
+static void
+handle_101012(struct bregs *regs)
+{
+    // XXX - inline
+    biosfn_set_all_dac_reg(regs);
+}
+
+static void
+handle_101013(struct bregs *regs)
+{
+    // XXX - inline
+    biosfn_select_video_dac_color_page(regs);
+}
+
+static void
+handle_101015(struct bregs *regs)
+{
+    // XXX - inline
+    biosfn_read_single_dac_reg(regs);
+}
+
+static void
+handle_101017(struct bregs *regs)
+{
+    // XXX - inline
+    biosfn_read_all_dac_reg(regs);
+}
+
+static void
+handle_101018(struct bregs *regs)
+{
+    // XXX - inline
+    biosfn_set_pel_mask(regs);
+}
+
+static void
+handle_101019(struct bregs *regs)
+{
+    // XXX - inline
+    biosfn_read_pel_mask(regs);
+}
+
+static void
+handle_10101a(struct bregs *regs)
+{
+    // XXX - inline
+    biosfn_read_video_dac_state(regs);
+}
+
+static void
+handle_10101b(struct bregs *regs)
+{
+    biosfn_perform_gray_scale_summing(regs->bx, regs->cx);
+}
+
+static void
+handle_1010XX(struct bregs *regs)
+{
+    debug_stub(regs);
+}
+
+static void
+handle_1010(struct bregs *regs)
+{
+    switch (regs->al) {
+    case 0x00: handle_101000(regs); break;
+    case 0x01: handle_101001(regs); break;
+    case 0x02: handle_101002(regs); break;
+    case 0x03: handle_101003(regs); break;
+    case 0x07: handle_101007(regs); break;
+    case 0x08: handle_101008(regs); break;
+    case 0x09: handle_101009(regs); break;
+    case 0x10: handle_101010(regs); break;
+    case 0x12: handle_101012(regs); break;
+    case 0x13: handle_101013(regs); break;
+    case 0x15: handle_101015(regs); break;
+    case 0x17: handle_101017(regs); break;
+    case 0x18: handle_101018(regs); break;
+    case 0x19: handle_101019(regs); break;
+    case 0x1a: handle_10101a(regs); break;
+    case 0x1b: handle_10101b(regs); break;
+    default:   handle_1010XX(regs); break;
+    }
+}
+
+
+static void
+handle_101100(struct bregs *regs)
+{
+    // XXX - inline
+    biosfn_load_text_user_pat(regs->al, regs->es, 0 // XXX - regs->bp
+                              , regs->cx, regs->dx, regs->bl, regs->bh);
+}
+
+static void
+handle_101101(struct bregs *regs)
+{
+    // XXX - inline
+    biosfn_load_text_8_14_pat(regs->al, regs->bl);
+}
+
+static void
+handle_101102(struct bregs *regs)
+{
+    // XXX - inline
+    biosfn_load_text_8_8_pat(regs->al, regs->bl);
+}
+
+static void
+handle_101103(struct bregs *regs)
+{
+    // XXX - inline
+    biosfn_set_text_block_specifier(regs);
+}
+
+static void
+handle_101104(struct bregs *regs)
+{
+    // XXX - inline
+    biosfn_load_text_8_16_pat(regs->al, regs->bl);
+}
+
+static void
+handle_101110(struct bregs *regs)
+{
+    handle_101100(regs);
+}
+
+static void
+handle_101111(struct bregs *regs)
+{
+    handle_101101(regs);
+}
+
+static void
+handle_101112(struct bregs *regs)
+{
+    handle_101102(regs);
+}
+
+static void
+handle_101114(struct bregs *regs)
+{
+    handle_101104(regs);
+}
+
+static void
+handle_101130(struct bregs *regs)
+{
+    // XXX - inline
+    biosfn_get_font_info(regs->bh, &regs->es, 0 // &regs->bp
+                         , &regs->cx, &regs->dx);
+}
+
+static void
+handle_1011XX(struct bregs *regs)
+{
+    debug_stub(regs);
+}
+
+static void
+handle_1011(struct bregs *regs)
+{
+    switch (regs->al) {
+    case 0x00: handle_101100(regs); break;
+    case 0x01: handle_101101(regs); break;
+    case 0x02: handle_101102(regs); break;
+    case 0x03: handle_101103(regs); break;
+    case 0x04: handle_101104(regs); break;
+    case 0x10: handle_101110(regs); break;
+    case 0x11: handle_101111(regs); break;
+    case 0x12: handle_101112(regs); break;
+    case 0x14: handle_101114(regs); break;
+    case 0x30: handle_101130(regs); break;
+    default:   handle_1011XX(regs); break;
+    }
+}
+
+
+static void
+handle_101210(struct bregs *regs)
+{
+    // XXX - inline
+    biosfn_get_ega_info(regs);
+}
+
+static void
+handle_101230(struct bregs *regs)
+{
+    // XXX - inline
+    biosfn_select_vert_res(regs);
+}
+
+static void
+handle_101231(struct bregs *regs)
+{
+    // XXX - inline
+    biosfn_enable_default_palette_loading(regs);
+}
+
+static void
+handle_101232(struct bregs *regs)
+{
+    // XXX - inline
+    biosfn_enable_video_addressing(regs);
+}
+
+static void
+handle_101233(struct bregs *regs)
+{
+    // XXX - inline
+    biosfn_enable_grayscale_summing(regs);
+}
+
+static void
+handle_101234(struct bregs *regs)
+{
+    // XXX - inline
+    biosfn_enable_cursor_emulation(regs);
+}
+
+static void
+handle_101235(struct bregs *regs)
+{
+    debug_stub(regs);
+    regs->al = 0x12;
+}
+
+static void
+handle_101236(struct bregs *regs)
+{
+    debug_stub(regs);
+    regs->al = 0x12;
+}
+
+static void
+handle_1012XX(struct bregs *regs)
+{
+    debug_stub(regs);
+}
+
+static void
+handle_1012(struct bregs *regs)
+{
+    switch (regs->bl) {
+    case 0x10: handle_101210(regs); break;
+    case 0x30: handle_101230(regs); break;
+    case 0x31: handle_101231(regs); break;
+    case 0x32: handle_101232(regs); break;
+    case 0x33: handle_101233(regs); break;
+    case 0x34: handle_101234(regs); break;
+    case 0x35: handle_101235(regs); break;
+    case 0x36: handle_101236(regs); break;
+    default:   handle_1012XX(regs); break;
+    }
+
+    // XXX - cirrus has 1280, 1281, 1282, 1285, 129a, 12a0, 12a1, 12a2, 12ae
+}
+
+
+static void
+handle_1013(struct bregs *regs)
+{
+    // XXX - inline
+    biosfn_write_string(regs->al, regs->bh, regs->bl, regs->cx
+                        , regs->dh, regs->dl, regs->es, 0); // regs->bp);
+}
+
+
+static void
+handle_101a00(struct bregs *regs)
+{
+    // XXX - inline
+    biosfn_read_display_code(regs);
+}
+
+static void
+handle_101a01(struct bregs *regs)
+{
+    // XXX - inline
+    biosfn_set_display_code(regs);
+}
+
+static void
+handle_101aXX(struct bregs *regs)
+{
+    debug_stub(regs);
+}
+
+static void
+handle_101a(struct bregs *regs)
+{
+    switch (regs->al) {
+    case 0x00: handle_101a00(regs); break;
+    case 0x01: handle_101a01(regs); break;
+    default:   handle_101aXX(regs); break;
+    }
+}
+
+
+static void
+handle_101b(struct bregs *regs)
+{
+    // XXX - inline
+    biosfn_read_state_info(regs->bx, regs->es, regs->di);
+    regs->al = 0x1B;
+}
+
+
+static void
+handle_101c00(struct bregs *regs)
+{
+    // XXX - inline
+    regs->bx = biosfn_read_video_state_size(regs->cx);
+}
+
+static void
+handle_101c01(struct bregs *regs)
+{
+    // XXX - inline
+    biosfn_save_video_state(regs->cx, regs->es, regs->bx);
+}
+
+static void
+handle_101c02(struct bregs *regs)
+{
+    // XXX - inline
+    biosfn_restore_video_state(regs->cx, regs->es, regs->bx);
+}
+
+static void
+handle_101cXX(struct bregs *regs)
+{
+    debug_stub(regs);
+}
+
+static void
+handle_101c(struct bregs *regs)
+{
+    switch (regs->al) {
+    case 0x00: handle_101c00(regs); break;
+    case 0x01: handle_101c01(regs); break;
+    case 0x02: handle_101c02(regs); break;
+    default:   handle_101cXX(regs); break;
+    }
+}
+
+
+static void
+handle_104f00(struct bregs *regs)
+{
+    // XXX - vbe_biosfn_return_controller_information(&AX,ES,DI);
+    // XXX - OR cirrus_vesa_00h
+}
+
+static void
+handle_104f01(struct bregs *regs)
+{
+    // XXX - vbe_biosfn_return_mode_information(&AX,CX,ES,DI);
+    // XXX - OR cirrus_vesa_01h
+}
+
+static void
+handle_104f02(struct bregs *regs)
+{
+    // XXX - vbe_biosfn_set_mode(&AX,BX,ES,DI);
+    // XXX - OR cirrus_vesa_02h
+}
+
+static void
+handle_104f03(struct bregs *regs)
+{
+    // XXX - vbe_biosfn_return_current_mode
+    // XXX - OR cirrus_vesa_03h
+}
+
+static void
+handle_104f04(struct bregs *regs)
+{
+    // XXX - vbe_biosfn_save_restore_state(&AX, CX, DX, ES, &BX);
+}
+
+static void
+handle_104f05(struct bregs *regs)
+{
+    // XXX - vbe_biosfn_display_window_control
+    // XXX - OR cirrus_vesa_05h
+}
+
+static void
+handle_104f06(struct bregs *regs)
+{
+    // XXX - vbe_biosfn_set_get_logical_scan_line_length
+    // XXX - OR cirrus_vesa_06h
+}
+
+static void
+handle_104f07(struct bregs *regs)
+{
+    // XXX - vbe_biosfn_set_get_display_start
+    // XXX - OR cirrus_vesa_07h
+}
+
+static void
+handle_104f08(struct bregs *regs)
+{
+    // XXX - vbe_biosfn_set_get_dac_palette_format
+}
+
+static void
+handle_104f0a(struct bregs *regs)
+{
+    // XXX - vbe_biosfn_return_protected_mode_interface
+}
+
+static void
+handle_104fXX(struct bregs *regs)
+{
+    debug_stub(regs);
+    regs->ax = 0x0100;
+}
+
+static void
+handle_104f(struct bregs *regs)
+{
+    if (! CONFIG_VBE) {
+        handle_104fXX(regs);
+        return;
+    }
+
+    // XXX - check vbe_has_vbe_display()?
+
+    switch (regs->al) {
+    case 0x00: handle_104f00(regs); break;
+    case 0x01: handle_104f01(regs); break;
+    case 0x02: handle_104f02(regs); break;
+    case 0x03: handle_104f03(regs); break;
+    case 0x04: handle_104f04(regs); break;
+    case 0x05: handle_104f05(regs); break;
+    case 0x06: handle_104f06(regs); break;
+    case 0x07: handle_104f07(regs); break;
+    case 0x08: handle_104f08(regs); break;
+    case 0x0a: handle_104f0a(regs); break;
+    default:   handle_104fXX(regs); break;
+    }
+}
+
+
+static void
+handle_10XX(struct bregs *regs)
+{
+    debug_stub(regs);
+}
+
+// INT 10h Video Support Service Entry Point
+void VISIBLE16
+handle_10(struct bregs *regs)
+{
+    debug_enter(regs, DEBUG_VGA_10);
+    switch (regs->ah) {
+    case 0x00: handle_1000(regs); break;
+    case 0x01: handle_1001(regs); break;
+    case 0x02: handle_1002(regs); break;
+    case 0x03: handle_1003(regs); break;
+    case 0x04: handle_1004(regs); break;
+    case 0x05: handle_1005(regs); break;
+    case 0x06: handle_1006(regs); break;
+    case 0x07: handle_1007(regs); break;
+    case 0x08: handle_1008(regs); break;
+    case 0x09: handle_1009(regs); break;
+    case 0x0a: handle_100a(regs); break;
+    case 0x0b: handle_100b(regs); break;
+    case 0x0c: handle_100c(regs); break;
+    case 0x0d: handle_100d(regs); break;
+    case 0x0e: handle_100e(regs); break;
+    case 0x0f: handle_100f(regs); break;
+    case 0x10: handle_1010(regs); break;
+    case 0x11: handle_1011(regs); break;
+    case 0x12: handle_1012(regs); break;
+    case 0x13: handle_1013(regs); break;
+    case 0x1a: handle_101a(regs); break;
+    case 0x1b: handle_101b(regs); break;
+    case 0x1c: handle_101c(regs); break;
+    case 0x4f: handle_104f(regs); break;
+    default:   handle_10XX(regs); break;
+    }
+}
+
+
+/****************************************************************
+ * VGA post
+ ****************************************************************/
+
+static void
+init_bios_area()
+{
+    // init detected hardware BIOS Area
+    // set 80x25 color (not clear from RBIL but usual)
+    u16 eqf = GET_BDA(equipment_list_flags);
+    SET_BDA(equipment_list_flags, (eqf & 0xffcf) | 0x20);
+
+    // Just for the first int10 find its children
+
+    // the default char height
+    SET_BDA(char_height, 0x10);
+
+    // Clear the screen
+    SET_BDA(video_ctl, 0x60);
+
+    // Set the basic screen we have
+    SET_BDA(video_switches, 0xf9);
+
+    // Set the basic modeset options
+    SET_BDA(modeset_ctl, 0x51);
+
+    // Set the  default MSR
+    SET_BDA(video_msr, 0x09);
+}
+
+static void
+init_vga_card()
+{
+    // switch to color mode and enable CPU access 480 lines
+    outb(0xc3, VGAREG_WRITE_MISC_OUTPUT);
+    // more than 64k 3C4/04
+    outb(0x04, VGAREG_SEQU_ADDRESS);
+    outb(0x02, VGAREG_SEQU_DATA);
+}
+
+void VISIBLE16
+vga_post(struct bregs *regs)
+{
+    debug_enter(regs, DEBUG_VGA_POST);
+
+    init_vga_card();
+
+    init_bios_area();
+
+    // vbe_init();
+
+    extern void entry_10(void);
+    SET_IVT(0x10, 0xC000, (u32)entry_10);
+
+    if (CONFIG_CIRRUS)
+        cirrus_init();
+
+    // XXX - clear screen and display info
+
+    // XXX: fill it
+    SET_VGA(video_save_pointer_table[0], (u32)video_param_table);
+    SET_VGA(video_save_pointer_table[1], 0xC000);
+
+    // Fixup checksum
+    extern u8 _rom_header_size, _rom_header_checksum;
+    SET_VGA(_rom_header_checksum, 0);
+    u8 sum = -checksum_far(0xC000, 0, _rom_header_size * 512);
+    SET_VGA(_rom_header_checksum, sum);
+}
diff --git a/vgasrc/vgaentry.S b/vgasrc/vgaentry.S
new file mode 100644 (file)
index 0000000..48264cf
--- /dev/null
@@ -0,0 +1,43 @@
+// Rom layout and bios assembler to C interface.
+//
+// Copyright (C) 2009  Kevin O'Connor <kevin@koconnor.net>
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+
+/****************************************************************
+ * Include of 16bit C code
+ ****************************************************************/
+
+        .code16gcc
+.include "out/vgaccode.16.s"
+
+#include "entryfuncs.S" // ENTRY_*
+
+
+/****************************************************************
+ * Rom Header
+ ****************************************************************/
+
+        .section .rom.header
+        .global _rom_header, _rom_header_size, _rom_header_checksum
+_rom_header:
+        .word 0xaa55
+_rom_header_size:
+        .byte 0
+_rom_header_entry:
+        jmp _optionrom_entry
+_rom_header_checksum:
+        .space 22
+
+
+/****************************************************************
+ * Entry points
+ ****************************************************************/
+
+        DECLFUNC _optionrom_entry
+_optionrom_entry:
+        ENTRY_ARG vga_post
+        lretw
+
+        DECL_IRQ_ENTRY_ARG 10
diff --git a/vgasrc/vgafonts.c b/vgasrc/vgafonts.c
new file mode 100644 (file)
index 0000000..8c1752c
--- /dev/null
@@ -0,0 +1,785 @@
+#include "vgatables.h" // vgafont8
+
+/*
+ * These fonts come from ftp://ftp.simtel.net/pub/simtelnet/msdos/screen/fntcol16.zip
+ * The package is (c) by Joseph Gil
+ * The individual fonts are public domain
+ */
+u8 vgafont8[256 * 8] VAR16 = {
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e,
+    0x7e, 0xff, 0xdb, 0xff, 0xc3, 0xe7, 0xff, 0x7e,
+    0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00,
+    0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00,
+    0x38, 0x7c, 0x38, 0xfe, 0xfe, 0x7c, 0x38, 0x7c,
+    0x10, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x7c,
+    0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00,
+    0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff,
+    0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00,
+    0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff,
+    0x0f, 0x07, 0x0f, 0x7d, 0xcc, 0xcc, 0xcc, 0x78,
+    0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18,
+    0x3f, 0x33, 0x3f, 0x30, 0x30, 0x70, 0xf0, 0xe0,
+    0x7f, 0x63, 0x7f, 0x63, 0x63, 0x67, 0xe6, 0xc0,
+    0x99, 0x5a, 0x3c, 0xe7, 0xe7, 0x3c, 0x5a, 0x99,
+    0x80, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0x80, 0x00,
+    0x02, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x02, 0x00,
+    0x18, 0x3c, 0x7e, 0x18, 0x18, 0x7e, 0x3c, 0x18,
+    0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00,
+    0x7f, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x00,
+    0x3e, 0x63, 0x38, 0x6c, 0x6c, 0x38, 0xcc, 0x78,
+    0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x00,
+    0x18, 0x3c, 0x7e, 0x18, 0x7e, 0x3c, 0x18, 0xff,
+    0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x00,
+    0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00,
+    0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00,
+    0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00,
+    0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00,
+    0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00,
+    0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x00, 0x00,
+    0x00, 0xff, 0xff, 0x7e, 0x3c, 0x18, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x30, 0x78, 0x78, 0x30, 0x30, 0x00, 0x30, 0x00,
+    0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00,
+    0x30, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x30, 0x00,
+    0x00, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xc6, 0x00,
+    0x38, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0x76, 0x00,
+    0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00,
+    0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00,
+    0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00,
+    0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x60,
+    0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00,
+    0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00,
+    0x7c, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0x7c, 0x00,
+    0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x00,
+    0x78, 0xcc, 0x0c, 0x38, 0x60, 0xcc, 0xfc, 0x00,
+    0x78, 0xcc, 0x0c, 0x38, 0x0c, 0xcc, 0x78, 0x00,
+    0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x1e, 0x00,
+    0xfc, 0xc0, 0xf8, 0x0c, 0x0c, 0xcc, 0x78, 0x00,
+    0x38, 0x60, 0xc0, 0xf8, 0xcc, 0xcc, 0x78, 0x00,
+    0xfc, 0xcc, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x00,
+    0x78, 0xcc, 0xcc, 0x78, 0xcc, 0xcc, 0x78, 0x00,
+    0x78, 0xcc, 0xcc, 0x7c, 0x0c, 0x18, 0x70, 0x00,
+    0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00,
+    0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x60,
+    0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x00,
+    0x00, 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00,
+    0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00,
+    0x78, 0xcc, 0x0c, 0x18, 0x30, 0x00, 0x30, 0x00,
+    0x7c, 0xc6, 0xde, 0xde, 0xde, 0xc0, 0x78, 0x00,
+    0x30, 0x78, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0x00,
+    0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xfc, 0x00,
+    0x3c, 0x66, 0xc0, 0xc0, 0xc0, 0x66, 0x3c, 0x00,
+    0xf8, 0x6c, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00,
+    0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00,
+    0xfe, 0x62, 0x68, 0x78, 0x68, 0x60, 0xf0, 0x00,
+    0x3c, 0x66, 0xc0, 0xc0, 0xce, 0x66, 0x3e, 0x00,
+    0xcc, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0xcc, 0x00,
+    0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
+    0x1e, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00,
+    0xe6, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00,
+    0xf0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00,
+    0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0x00,
+    0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0x00,
+    0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00,
+    0xfc, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00,
+    0x78, 0xcc, 0xcc, 0xcc, 0xdc, 0x78, 0x1c, 0x00,
+    0xfc, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0xe6, 0x00,
+    0x78, 0xcc, 0xe0, 0x70, 0x1c, 0xcc, 0x78, 0x00,
+    0xfc, 0xb4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
+    0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xfc, 0x00,
+    0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00,
+    0xc6, 0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x00,
+    0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x6c, 0xc6, 0x00,
+    0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x30, 0x78, 0x00,
+    0xfe, 0xc6, 0x8c, 0x18, 0x32, 0x66, 0xfe, 0x00,
+    0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00,
+    0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02, 0x00,
+    0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00,
+    0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+    0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00,
+    0xe0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0xdc, 0x00,
+    0x00, 0x00, 0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x00,
+    0x1c, 0x0c, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00,
+    0x00, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00,
+    0x38, 0x6c, 0x60, 0xf0, 0x60, 0x60, 0xf0, 0x00,
+    0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8,
+    0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0xe6, 0x00,
+    0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
+    0x0c, 0x00, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78,
+    0xe0, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0xe6, 0x00,
+    0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
+    0x00, 0x00, 0xcc, 0xfe, 0xfe, 0xd6, 0xc6, 0x00,
+    0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0xcc, 0x00,
+    0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00,
+    0x00, 0x00, 0xdc, 0x66, 0x66, 0x7c, 0x60, 0xf0,
+    0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0x1e,
+    0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0xf0, 0x00,
+    0x00, 0x00, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x00,
+    0x10, 0x30, 0x7c, 0x30, 0x30, 0x34, 0x18, 0x00,
+    0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00,
+    0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00,
+    0x00, 0x00, 0xc6, 0xd6, 0xfe, 0xfe, 0x6c, 0x00,
+    0x00, 0x00, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0x00,
+    0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8,
+    0x00, 0x00, 0xfc, 0x98, 0x30, 0x64, 0xfc, 0x00,
+    0x1c, 0x30, 0x30, 0xe0, 0x30, 0x30, 0x1c, 0x00,
+    0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00,
+    0xe0, 0x30, 0x30, 0x1c, 0x30, 0x30, 0xe0, 0x00,
+    0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00,
+    0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x18, 0x0c, 0x78,
+    0x00, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00,
+    0x1c, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00,
+    0x7e, 0xc3, 0x3c, 0x06, 0x3e, 0x66, 0x3f, 0x00,
+    0xcc, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00,
+    0xe0, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00,
+    0x30, 0x30, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00,
+    0x00, 0x00, 0x78, 0xc0, 0xc0, 0x78, 0x0c, 0x38,
+    0x7e, 0xc3, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
+    0xcc, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00,
+    0xe0, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00,
+    0xcc, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
+    0x7c, 0xc6, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00,
+    0xe0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
+    0xc6, 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0xc6, 0x00,
+    0x30, 0x30, 0x00, 0x78, 0xcc, 0xfc, 0xcc, 0x00,
+    0x1c, 0x00, 0xfc, 0x60, 0x78, 0x60, 0xfc, 0x00,
+    0x00, 0x00, 0x7f, 0x0c, 0x7f, 0xcc, 0x7f, 0x00,
+    0x3e, 0x6c, 0xcc, 0xfe, 0xcc, 0xcc, 0xce, 0x00,
+    0x78, 0xcc, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00,
+    0x00, 0xcc, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00,
+    0x00, 0xe0, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00,
+    0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00,
+    0x00, 0xe0, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00,
+    0x00, 0xcc, 0x00, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8,
+    0xc3, 0x18, 0x3c, 0x66, 0x66, 0x3c, 0x18, 0x00,
+    0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00,
+    0x18, 0x18, 0x7e, 0xc0, 0xc0, 0x7e, 0x18, 0x18,
+    0x38, 0x6c, 0x64, 0xf0, 0x60, 0xe6, 0xfc, 0x00,
+    0xcc, 0xcc, 0x78, 0xfc, 0x30, 0xfc, 0x30, 0x30,
+    0xf8, 0xcc, 0xcc, 0xfa, 0xc6, 0xcf, 0xc6, 0xc7,
+    0x0e, 0x1b, 0x18, 0x3c, 0x18, 0x18, 0xd8, 0x70,
+    0x1c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00,
+    0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
+    0x00, 0x1c, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00,
+    0x00, 0x1c, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00,
+    0x00, 0xf8, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0x00,
+    0xfc, 0x00, 0xcc, 0xec, 0xfc, 0xdc, 0xcc, 0x00,
+    0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00,
+    0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00,
+    0x30, 0x00, 0x30, 0x60, 0xc0, 0xcc, 0x78, 0x00,
+    0x00, 0x00, 0x00, 0xfc, 0xc0, 0xc0, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0c, 0x00, 0x00,
+    0xc3, 0xc6, 0xcc, 0xde, 0x33, 0x66, 0xcc, 0x0f,
+    0xc3, 0xc6, 0xcc, 0xdb, 0x37, 0x6f, 0xcf, 0x03,
+    0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00,
+    0x00, 0x33, 0x66, 0xcc, 0x66, 0x33, 0x00, 0x00,
+    0x00, 0xcc, 0x66, 0x33, 0x66, 0xcc, 0x00, 0x00,
+    0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88,
+    0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
+    0xdb, 0x77, 0xdb, 0xee, 0xdb, 0x77, 0xdb, 0xee,
+    0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+    0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18,
+    0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18,
+    0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36,
+    0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36,
+    0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18,
+    0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00,
+    0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00,
+    0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18,
+    0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00,
+    0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18,
+    0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18,
+    0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
+    0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18,
+    0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18,
+    0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36,
+    0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00,
+    0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36,
+    0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00,
+    0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18,
+    0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00,
+    0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18,
+    0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36,
+    0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18,
+    0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+    0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
+    0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
+    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x76, 0xdc, 0xc8, 0xdc, 0x76, 0x00,
+    0x00, 0x78, 0xcc, 0xf8, 0xcc, 0xf8, 0xc0, 0xc0,
+    0x00, 0xfc, 0xcc, 0xc0, 0xc0, 0xc0, 0xc0, 0x00,
+    0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00,
+    0xfc, 0xcc, 0x60, 0x30, 0x60, 0xcc, 0xfc, 0x00,
+    0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0x70, 0x00,
+    0x00, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0xc0,
+    0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x00,
+    0xfc, 0x30, 0x78, 0xcc, 0xcc, 0x78, 0x30, 0xfc,
+    0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0x6c, 0x38, 0x00,
+    0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x6c, 0xee, 0x00,
+    0x1c, 0x30, 0x18, 0x7c, 0xcc, 0xcc, 0x78, 0x00,
+    0x00, 0x00, 0x7e, 0xdb, 0xdb, 0x7e, 0x00, 0x00,
+    0x06, 0x0c, 0x7e, 0xdb, 0xdb, 0x7e, 0x60, 0xc0,
+    0x38, 0x60, 0xc0, 0xf8, 0xc0, 0x60, 0x38, 0x00,
+    0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x00,
+    0x00, 0xfc, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0x00,
+    0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0xfc, 0x00,
+    0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0xfc, 0x00,
+    0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0xfc, 0x00,
+    0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18,
+    0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70,
+    0x30, 0x30, 0x00, 0xfc, 0x00, 0x30, 0x30, 0x00,
+    0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00,
+    0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
+    0x0f, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x3c, 0x1c,
+    0x78, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00,
+    0x70, 0x18, 0x30, 0x60, 0x78, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+u8 vgafont14[256 * 14] VAR16 = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x7e, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0x7e, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x02, 0x06, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00,
+ 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x28, 0x6c, 0xfe, 0x6c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
+ 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x66, 0xc6, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
+ 0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xe6, 0x66, 0x6c, 0x6c, 0x78, 0x6c, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00,
+ 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xfe, 0x7c, 0x6c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfe, 0xc6, 0x8c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00,
+ 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
+ 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00,
+ 0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00,
+ 0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xc6, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x70, 0x1c, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x66, 0xfe, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00,
+ 0x00, 0x00, 0xcc, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
+ 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
+ 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
+ 0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x66, 0x3c, 0x0c, 0x06, 0x3c, 0x00, 0x00,
+ 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x66, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
+ 0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
+ 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
+ 0x00, 0xc6, 0xc6, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00,
+ 0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00,
+ 0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xcc, 0x76, 0x36, 0x7e, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00,
+ 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc6, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
+ 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc6, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00,
+ 0x00, 0xc6, 0xc6, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00,
+ 0x00, 0xc6, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x18, 0x18, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x18, 0x18, 0x00, 0x00, 0x00,
+ 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00,
+ 0x00, 0xf8, 0xcc, 0xcc, 0xf8, 0xc4, 0xcc, 0xde, 0xcc, 0xcc, 0xc6, 0x00, 0x00, 0x00,
+ 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00,
+ 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
+ 0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
+ 0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00,
+ 0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0x00, 0x00, 0x00,
+ 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xc0, 0xc0, 0xc6, 0xcc, 0xd8, 0x30, 0x60, 0xdc, 0x86, 0x0c, 0x18, 0x3e, 0x00,
+ 0x00, 0xc0, 0xc0, 0xc6, 0xcc, 0xd8, 0x30, 0x66, 0xce, 0x9e, 0x3e, 0x06, 0x06, 0x00,
+ 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,
+ 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
+ 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfc, 0xc6, 0xc6, 0xfc, 0xc0, 0xc0, 0x40, 0x00,
+ 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00,
+ 0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+u8 vgafont16[256 * 16] VAR16 = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x66, 0xc3, 0xc3, 0xdb, 0xdb, 0xc3, 0xc3, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc3, 0xe7, 0xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00,
+ 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
+ 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00,
+ 0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00,
+ 0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06, 0x3c, 0x00, 0x00, 0x00,
+ 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+ 0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b, 0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc6, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00,
+ 0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x18, 0x18, 0x7e, 0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xfc, 0x66, 0x66, 0x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00, 0x00,
+ 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
+ 0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06, 0x0c, 0x1f, 0x00, 0x00,
+ 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,
+ 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
+ 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+u8 vgafont14alt[1] VAR16;
+u8 vgafont16alt[1] VAR16;
diff --git a/vgasrc/vgalayout.lds.S b/vgasrc/vgalayout.lds.S
new file mode 100644 (file)
index 0000000..b5f0319
--- /dev/null
@@ -0,0 +1,24 @@
+// Linker definitions for an option rom
+//
+// Copyright (C) 2009  Kevin O'Connor <kevin@koconnor.net>
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
+OUTPUT_ARCH("i386")
+ENTRY(_optionrom_entry)
+SECTIONS
+{
+        .text 0 : {
+                *(.rom.header)
+                *(.text.*)
+                _rodata = . ;
+                *(.rodata.__func__.*)
+                *(.rodata.str1.1)
+                *(.data16.*)
+                }
+
+        // Discard regular data sections to force a link error if
+        // 16bit code attempts to access data not marked with VAR16.
+        /DISCARD/ : { *(.text*) *(.rodata*) *(.data*) *(.bss*) *(COMMON) }
+}
diff --git a/vgasrc/vgatables.c b/vgasrc/vgatables.c
new file mode 100644 (file)
index 0000000..c0aea04
--- /dev/null
@@ -0,0 +1,353 @@
+// Tables used by VGA bios
+//
+// Copyright (C) 2009  Kevin O'Connor <kevin@koconnor.net>
+// Copyright (C) 2001-2008 the LGPL VGABios developers Team
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+#include "vgatables.h"
+
+u16 video_save_pointer_table[14] VAR16;
+
+struct vgamodes_s vga_modes[MODE_MAX + 1] VAR16 = {   //mode  class  model bits sstart  pelm  dac
+    {0x00, TEXT, CTEXT, 4, 0xB800, 0xFF, 0x02},
+    {0x01, TEXT, CTEXT, 4, 0xB800, 0xFF, 0x02},
+    {0x02, TEXT, CTEXT, 4, 0xB800, 0xFF, 0x02},
+    {0x03, TEXT, CTEXT, 4, 0xB800, 0xFF, 0x02},
+    {0x04, GRAPH, CGA, 2, 0xB800, 0xFF, 0x01},
+    {0x05, GRAPH, CGA, 2, 0xB800, 0xFF, 0x01},
+    {0x06, GRAPH, CGA, 1, 0xB800, 0xFF, 0x01},
+    {0x07, TEXT, MTEXT, 4, 0xB000, 0xFF, 0x00},
+    {0x0D, GRAPH, PLANAR4, 4, 0xA000, 0xFF, 0x01},
+    {0x0E, GRAPH, PLANAR4, 4, 0xA000, 0xFF, 0x01},
+    {0x0F, GRAPH, PLANAR1, 1, 0xA000, 0xFF, 0x00},
+    {0x10, GRAPH, PLANAR4, 4, 0xA000, 0xFF, 0x02},
+    {0x11, GRAPH, PLANAR1, 1, 0xA000, 0xFF, 0x02},
+    {0x12, GRAPH, PLANAR4, 4, 0xA000, 0xFF, 0x02},
+    {0x13, GRAPH, LINEAR8, 8, 0xA000, 0xFF, 0x03},
+    {0x6A, GRAPH, PLANAR4, 4, 0xA000, 0xFF, 0x02}
+};
+
+/* convert index in vga_modes[] to index in video_param_table[] */
+u8 line_to_vpti[MODE_MAX + 1] VAR16 = {
+    0x17, 0x17, 0x18, 0x18, 0x04, 0x05, 0x06, 0x07,
+    0x0d, 0x0e, 0x11, 0x12, 0x1a, 0x1b, 0x1c, 0x1d,
+};
+
+u8 dac_regs[DAC_MAX_MODEL + 1] VAR16 = { 0x3f, 0x3f, 0x3f, 0xff };
+
+struct VideoParamTableEntry_s video_param_table[30] VAR16 = {
+    // index=0x00 no mode defined
+    {},
+    // index=0x01 no mode defined
+    {},
+    // index=0x02 no mode defined
+    {},
+    // index=0x03 no mode defined
+    {},
+    // index=0x04 vga mode 0x04
+    { 40, 24, 8, 0x0800,      /* tw, th-1, ch, slength */
+      { 0x09, 0x03, 0x00, 0x02 },    /* sequ_regs */
+      0x63,                      /* miscreg */
+      { 0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f,
+        0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xa2,
+        0xff },                      /* crtc_regs */
+      { 0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07,
+        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+        0x01, 0x00, 0x03, 0x00 },    /* actl_regs */
+      { 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0f, 0x0f, 0xff }, /* grdc_regs */
+    },
+    /* index=0x05 vga mode 0x05 */
+    { 40, 24, 8, 0x0800,     /* tw, th-1, ch, slength */
+      { 0x09, 0x03, 0x00, 0x02 },    /* sequ_regs */
+      0x63,                      /* miscreg */
+      { 0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f,
+        0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xa2,
+        0xff },                      /* crtc_regs */
+      { 0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07,
+        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+        0x01, 0x00, 0x03, 0x00 },    /* actl_regs */
+      { 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0f, 0x0f, 0xff }, /* grdc_regs */
+    },
+    /* index=0x06 vga mode 0x06 */
+    { 80, 24, 8, 0x1000,     /* tw, th-1, ch, slength */
+      { 0x01, 0x01, 0x00, 0x06 },    /* sequ_regs */
+      0x63,                      /* miscreg */
+      { 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f,
+        0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, 0xb9, 0xc2,
+        0xff },                      /* crtc_regs */
+      { 0x00, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
+        0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
+        0x01, 0x00, 0x01, 0x00 },    /* actl_regs */
+      { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x0f, 0xff }, /* grdc_regs */
+     },
+    /* index=0x07 vga mode 0x07 */
+    { 80, 24, 16, 0x1000,    /* tw, th-1, ch, slength */
+      { 0x00, 0x03, 0x00, 0x02 },    /* sequ_regs */
+      0x66,                      /* miscreg */
+      { 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
+        0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
+        0x9c, 0x8e, 0x8f, 0x28, 0x0f, 0x96, 0xb9, 0xa3,
+        0xff },                      /* crtc_regs */
+      { 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+        0x10, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+        0x0e, 0x00, 0x0f, 0x08 },    /* actl_regs */
+      { 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0a, 0x0f, 0xff }, /* grdc_regs */
+     },
+    /* index=0x08 no mode defined */
+    {},
+    /* index=0x09 no mode defined */
+    {},
+    /* index=0x0a no mode defined */
+    {},
+    /* index=0x0b no mode defined */
+    {},
+    /* index=0x0c no mode defined */
+    {},
+    /* index=0x0d vga mode 0x0d */
+    { 40, 24, 8, 0x2000,     /* tw, th-1, ch, slength */
+      { 0x09, 0x0f, 0x00, 0x06 },    /* sequ_regs */
+      0x63,                      /* miscreg */
+      { 0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f,
+        0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xe3,
+        0xff },                      /* crtc_regs */
+      { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+        0x01, 0x00, 0x0f, 0x00 },    /* actl_regs */
+      { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff }, /* grdc_regs */
+     },
+    /* index=0x0e vga mode 0x0e */
+    { 80, 24, 8, 0x4000,     /* tw, th-1, ch, slength */
+      { 0x01, 0x0f, 0x00, 0x06 },    /* sequ_regs */
+      0x63,                      /* miscreg */
+      { 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f,
+        0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, 0xb9, 0xe3,
+        0xff },                      /* crtc_regs */
+      { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+        0x01, 0x00, 0x0f, 0x00 },    /* actl_regs */
+      { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff }, /* grdc_regs */
+     },
+    /* index=0x0f no mode defined */
+    {},
+    /* index=0x10 no mode defined */
+    {},
+    /* index=0x11 vga mode 0x0f */
+    { 80, 24, 14, 0x8000,    /* tw, th-1, ch, slength */
+      { 0x01, 0x0f, 0x00, 0x06 },    /* sequ_regs */
+      0xa3,                      /* miscreg */
+      { 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f,
+        0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x83, 0x85, 0x5d, 0x28, 0x0f, 0x63, 0xba, 0xe3,
+        0xff },                      /* crtc_regs */
+      { 0x00, 0x08, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
+        0x00, 0x08, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00,
+        0x01, 0x00, 0x01, 0x00 },    /* actl_regs */
+      { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff }, /* grdc_regs */
+     },
+    /* index=0x12 vga mode 0x10 */
+    { 80, 24, 14, 0x8000,    /* tw, th-1, ch, slength */
+      { 0x01, 0x0f, 0x00, 0x06 },    /* sequ_regs */
+      0xa3,                      /* miscreg */
+      { 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f,
+        0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x83, 0x85, 0x5d, 0x28, 0x0f, 0x63, 0xba, 0xe3,
+        0xff },                      /* crtc_regs */
+      { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
+        0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+        0x01, 0x00, 0x0f, 0x00 },    /* actl_regs */
+      { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff }, /* grdc_regs */
+     },
+    /* index=0x13 no mode defined */
+    {},
+    /* index=0x14 no mode defined */
+    {},
+    /* index=0x15 no mode defined */
+    {},
+    /* index=0x16 no mode defined */
+    {},
+    /* index=0x17 vga mode 0x01 */
+    { 40, 24, 16, 0x0800,    /* tw, th-1, ch, slength */
+      { 0x08, 0x03, 0x00, 0x02 },    /* sequ_regs */
+      0x67,                      /* miscreg */
+      { 0x2d, 0x27, 0x28, 0x90, 0x2b, 0xa0, 0xbf, 0x1f,
+        0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
+        0x9c, 0x8e, 0x8f, 0x14, 0x1f, 0x96, 0xb9, 0xa3,
+        0xff },                      /* crtc_regs */
+      { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
+        0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+        0x0c, 0x00, 0x0f, 0x08 },    /* actl_regs */
+      { 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x0f, 0xff }, /* grdc_regs */
+    },
+    /* index=0x18 vga mode 0x03 */
+    { 80, 24, 16, 0x1000,    /* tw, th-1, ch, slength */
+      { 0x00, 0x03, 0x00, 0x02 },    /* sequ_regs */
+      0x67,                      /* miscreg */
+      { 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
+        0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
+        0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3,
+        0xff },                      /* crtc_regs */
+      { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
+        0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+        0x0c, 0x00, 0x0f, 0x08 },    /* actl_regs */
+      { 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x0f, 0xff }, /* grdc_regs */
+     },
+    /* index=0x19 vga mode 0x07 */
+    { 80, 24, 16, 0x1000,    /* tw, th-1, ch, slength */
+      { 0x00, 0x03, 0x00, 0x02 },    /* sequ_regs */
+      0x66,                      /* miscreg */
+      { 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
+        0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
+        0x9c, 0x8e, 0x8f, 0x28, 0x0f, 0x96, 0xb9, 0xa3,
+        0xff },                      /* crtc_regs */
+      { 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+        0x10, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+        0x0e, 0x00, 0x0f, 0x08 },    /* actl_regs */
+      { 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0a, 0x0f, 0xff }, /* grdc_regs */
+    },
+    /* index=0x1a vga mode 0x11 */
+    { 80, 29, 16, 0x0000,    /* tw, th-1, ch, slength */
+      { 0x01, 0x0f, 0x00, 0x06 },    /* sequ_regs */
+      0xe3,                      /* miscreg */
+      { 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e,
+        0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0xea, 0x8c, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xe3,
+        0xff },                      /* crtc_regs */
+      { 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f,
+        0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f,
+        0x01, 0x00, 0x0f, 0x00 },    /* actl_regs */
+      { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff }, /* grdc_regs */
+    },
+    /* index=0x1b vga mode 0x12 */
+    { 80, 29, 16, 0x0000,    /* tw, th-1, ch, slength */
+      { 0x01, 0x0f, 0x00, 0x06 },    /* sequ_regs */
+      0xe3,                      /* miscreg */
+      { 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e,
+        0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0xea, 0x8c, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xe3,
+        0xff },                      /* crtc_regs */
+      { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
+        0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+        0x01, 0x00, 0x0f, 0x00 },    /* actl_regs */
+      { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff }, /* grdc_regs */
+     },
+    /* index=0x1c vga mode 0x13 */
+    { 40, 24, 8, 0x0000,     /* tw, th-1, ch, slength */
+      { 0x01, 0x0f, 0x00, 0x0e },    /* sequ_regs */
+      0x63,                      /* miscreg */
+      { 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f,
+        0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x9c, 0x8e, 0x8f, 0x28, 0x40, 0x96, 0xb9, 0xa3,
+        0xff },                      /* crtc_regs */
+      { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+        0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+        0x41, 0x00, 0x0f, 0x00 },    /* actl_regs */
+      { 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0f, 0xff }, /* grdc_regs */
+     },
+    /* index=0x1d vga mode 0x6a */
+    { 100, 36, 16, 0x0000,   /* tw, th-1, ch, slength */
+      { 0x01, 0x0f, 0x00, 0x06 },    /* sequ_regs */
+      0xe3,                      /* miscreg */
+      { 0x7f, 0x63, 0x63, 0x83, 0x6b, 0x1b, 0x72, 0xf0,
+        0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x59, 0x8d, 0x57, 0x32, 0x00, 0x57, 0x73, 0xe3,
+        0xff },                      /* crtc_regs */
+      { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
+        0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+        0x01, 0x00, 0x0f, 0x00 },    /* actl_regs */
+      { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff }, /* grdc_regs */
+     },
+};
+
+/* Mono */
+u8 palette0[] VAR16 = {
+  0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00,
+  0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a,
+  0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a,
+  0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f,
+  0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00,
+  0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a,
+  0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a,
+  0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f 
+};
+
+u8 palette1[] VAR16 = {
+  0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a,
+  0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a,
+  0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f,
+  0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f,
+  0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a,
+  0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a,
+  0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f,
+  0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f 
+};
+
+u8 palette2[] VAR16 = {
+  0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x2a,0x00, 0x2a,0x2a,0x2a,
+  0x00,0x00,0x15, 0x00,0x00,0x3f, 0x00,0x2a,0x15, 0x00,0x2a,0x3f, 0x2a,0x00,0x15, 0x2a,0x00,0x3f, 0x2a,0x2a,0x15, 0x2a,0x2a,0x3f,
+  0x00,0x15,0x00, 0x00,0x15,0x2a, 0x00,0x3f,0x00, 0x00,0x3f,0x2a, 0x2a,0x15,0x00, 0x2a,0x15,0x2a, 0x2a,0x3f,0x00, 0x2a,0x3f,0x2a,
+  0x00,0x15,0x15, 0x00,0x15,0x3f, 0x00,0x3f,0x15, 0x00,0x3f,0x3f, 0x2a,0x15,0x15, 0x2a,0x15,0x3f, 0x2a,0x3f,0x15, 0x2a,0x3f,0x3f,
+  0x15,0x00,0x00, 0x15,0x00,0x2a, 0x15,0x2a,0x00, 0x15,0x2a,0x2a, 0x3f,0x00,0x00, 0x3f,0x00,0x2a, 0x3f,0x2a,0x00, 0x3f,0x2a,0x2a,
+  0x15,0x00,0x15, 0x15,0x00,0x3f, 0x15,0x2a,0x15, 0x15,0x2a,0x3f, 0x3f,0x00,0x15, 0x3f,0x00,0x3f, 0x3f,0x2a,0x15, 0x3f,0x2a,0x3f,
+  0x15,0x15,0x00, 0x15,0x15,0x2a, 0x15,0x3f,0x00, 0x15,0x3f,0x2a, 0x3f,0x15,0x00, 0x3f,0x15,0x2a, 0x3f,0x3f,0x00, 0x3f,0x3f,0x2a,
+  0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f 
+};
+
+u8 palette3[] VAR16 = {
+  0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a,
+  0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f,
+  0x00,0x00,0x00, 0x05,0x05,0x05, 0x08,0x08,0x08, 0x0b,0x0b,0x0b, 0x0e,0x0e,0x0e, 0x11,0x11,0x11, 0x14,0x14,0x14, 0x18,0x18,0x18,
+  0x1c,0x1c,0x1c, 0x20,0x20,0x20, 0x24,0x24,0x24, 0x28,0x28,0x28, 0x2d,0x2d,0x2d, 0x32,0x32,0x32, 0x38,0x38,0x38, 0x3f,0x3f,0x3f,
+  0x00,0x00,0x3f, 0x10,0x00,0x3f, 0x1f,0x00,0x3f, 0x2f,0x00,0x3f, 0x3f,0x00,0x3f, 0x3f,0x00,0x2f, 0x3f,0x00,0x1f, 0x3f,0x00,0x10,
+  0x3f,0x00,0x00, 0x3f,0x10,0x00, 0x3f,0x1f,0x00, 0x3f,0x2f,0x00, 0x3f,0x3f,0x00, 0x2f,0x3f,0x00, 0x1f,0x3f,0x00, 0x10,0x3f,0x00,
+  0x00,0x3f,0x00, 0x00,0x3f,0x10, 0x00,0x3f,0x1f, 0x00,0x3f,0x2f, 0x00,0x3f,0x3f, 0x00,0x2f,0x3f, 0x00,0x1f,0x3f, 0x00,0x10,0x3f,
+  0x1f,0x1f,0x3f, 0x27,0x1f,0x3f, 0x2f,0x1f,0x3f, 0x37,0x1f,0x3f, 0x3f,0x1f,0x3f, 0x3f,0x1f,0x37, 0x3f,0x1f,0x2f, 0x3f,0x1f,0x27,
+
+  0x3f,0x1f,0x1f, 0x3f,0x27,0x1f, 0x3f,0x2f,0x1f, 0x3f,0x37,0x1f, 0x3f,0x3f,0x1f, 0x37,0x3f,0x1f, 0x2f,0x3f,0x1f, 0x27,0x3f,0x1f,
+  0x1f,0x3f,0x1f, 0x1f,0x3f,0x27, 0x1f,0x3f,0x2f, 0x1f,0x3f,0x37, 0x1f,0x3f,0x3f, 0x1f,0x37,0x3f, 0x1f,0x2f,0x3f, 0x1f,0x27,0x3f,
+  0x2d,0x2d,0x3f, 0x31,0x2d,0x3f, 0x36,0x2d,0x3f, 0x3a,0x2d,0x3f, 0x3f,0x2d,0x3f, 0x3f,0x2d,0x3a, 0x3f,0x2d,0x36, 0x3f,0x2d,0x31,
+  0x3f,0x2d,0x2d, 0x3f,0x31,0x2d, 0x3f,0x36,0x2d, 0x3f,0x3a,0x2d, 0x3f,0x3f,0x2d, 0x3a,0x3f,0x2d, 0x36,0x3f,0x2d, 0x31,0x3f,0x2d,
+  0x2d,0x3f,0x2d, 0x2d,0x3f,0x31, 0x2d,0x3f,0x36, 0x2d,0x3f,0x3a, 0x2d,0x3f,0x3f, 0x2d,0x3a,0x3f, 0x2d,0x36,0x3f, 0x2d,0x31,0x3f,
+  0x00,0x00,0x1c, 0x07,0x00,0x1c, 0x0e,0x00,0x1c, 0x15,0x00,0x1c, 0x1c,0x00,0x1c, 0x1c,0x00,0x15, 0x1c,0x00,0x0e, 0x1c,0x00,0x07,
+  0x1c,0x00,0x00, 0x1c,0x07,0x00, 0x1c,0x0e,0x00, 0x1c,0x15,0x00, 0x1c,0x1c,0x00, 0x15,0x1c,0x00, 0x0e,0x1c,0x00, 0x07,0x1c,0x00,
+  0x00,0x1c,0x00, 0x00,0x1c,0x07, 0x00,0x1c,0x0e, 0x00,0x1c,0x15, 0x00,0x1c,0x1c, 0x00,0x15,0x1c, 0x00,0x0e,0x1c, 0x00,0x07,0x1c,
+
+  0x0e,0x0e,0x1c, 0x11,0x0e,0x1c, 0x15,0x0e,0x1c, 0x18,0x0e,0x1c, 0x1c,0x0e,0x1c, 0x1c,0x0e,0x18, 0x1c,0x0e,0x15, 0x1c,0x0e,0x11,
+  0x1c,0x0e,0x0e, 0x1c,0x11,0x0e, 0x1c,0x15,0x0e, 0x1c,0x18,0x0e, 0x1c,0x1c,0x0e, 0x18,0x1c,0x0e, 0x15,0x1c,0x0e, 0x11,0x1c,0x0e,
+  0x0e,0x1c,0x0e, 0x0e,0x1c,0x11, 0x0e,0x1c,0x15, 0x0e,0x1c,0x18, 0x0e,0x1c,0x1c, 0x0e,0x18,0x1c, 0x0e,0x15,0x1c, 0x0e,0x11,0x1c,
+  0x14,0x14,0x1c, 0x16,0x14,0x1c, 0x18,0x14,0x1c, 0x1a,0x14,0x1c, 0x1c,0x14,0x1c, 0x1c,0x14,0x1a, 0x1c,0x14,0x18, 0x1c,0x14,0x16,
+  0x1c,0x14,0x14, 0x1c,0x16,0x14, 0x1c,0x18,0x14, 0x1c,0x1a,0x14, 0x1c,0x1c,0x14, 0x1a,0x1c,0x14, 0x18,0x1c,0x14, 0x16,0x1c,0x14,
+  0x14,0x1c,0x14, 0x14,0x1c,0x16, 0x14,0x1c,0x18, 0x14,0x1c,0x1a, 0x14,0x1c,0x1c, 0x14,0x1a,0x1c, 0x14,0x18,0x1c, 0x14,0x16,0x1c,
+  0x00,0x00,0x10, 0x04,0x00,0x10, 0x08,0x00,0x10, 0x0c,0x00,0x10, 0x10,0x00,0x10, 0x10,0x00,0x0c, 0x10,0x00,0x08, 0x10,0x00,0x04,
+  0x10,0x00,0x00, 0x10,0x04,0x00, 0x10,0x08,0x00, 0x10,0x0c,0x00, 0x10,0x10,0x00, 0x0c,0x10,0x00, 0x08,0x10,0x00, 0x04,0x10,0x00,
+
+  0x00,0x10,0x00, 0x00,0x10,0x04, 0x00,0x10,0x08, 0x00,0x10,0x0c, 0x00,0x10,0x10, 0x00,0x0c,0x10, 0x00,0x08,0x10, 0x00,0x04,0x10,
+  0x08,0x08,0x10, 0x0a,0x08,0x10, 0x0c,0x08,0x10, 0x0e,0x08,0x10, 0x10,0x08,0x10, 0x10,0x08,0x0e, 0x10,0x08,0x0c, 0x10,0x08,0x0a,
+  0x10,0x08,0x08, 0x10,0x0a,0x08, 0x10,0x0c,0x08, 0x10,0x0e,0x08, 0x10,0x10,0x08, 0x0e,0x10,0x08, 0x0c,0x10,0x08, 0x0a,0x10,0x08,
+  0x08,0x10,0x08, 0x08,0x10,0x0a, 0x08,0x10,0x0c, 0x08,0x10,0x0e, 0x08,0x10,0x10, 0x08,0x0e,0x10, 0x08,0x0c,0x10, 0x08,0x0a,0x10,
+  0x0b,0x0b,0x10, 0x0c,0x0b,0x10, 0x0d,0x0b,0x10, 0x0f,0x0b,0x10, 0x10,0x0b,0x10, 0x10,0x0b,0x0f, 0x10,0x0b,0x0d, 0x10,0x0b,0x0c,
+  0x10,0x0b,0x0b, 0x10,0x0c,0x0b, 0x10,0x0d,0x0b, 0x10,0x0f,0x0b, 0x10,0x10,0x0b, 0x0f,0x10,0x0b, 0x0d,0x10,0x0b, 0x0c,0x10,0x0b,
+  0x0b,0x10,0x0b, 0x0b,0x10,0x0c, 0x0b,0x10,0x0d, 0x0b,0x10,0x0f, 0x0b,0x10,0x10, 0x0b,0x0f,0x10, 0x0b,0x0d,0x10, 0x0b,0x0c,0x10,
+  0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00
+};
+
+u8 static_functionality[0x10] VAR16 = {
+ /* 0 */ 0xff,  // All modes supported #1
+ /* 1 */ 0xe0,  // All modes supported #2
+ /* 2 */ 0x0f,  // All modes supported #3
+ /* 3 */ 0x00, 0x00, 0x00, 0x00,  // reserved
+ /* 7 */ 0x07,  // 200, 350, 400 scan lines
+ /* 8 */ 0x02,  // mamimum number of visible charsets in text mode
+ /* 9 */ 0x08,  // total number of charset blocks in text mode
+ /* a */ 0xe7,  // Change to add new functions
+ /* b */ 0x0c,  // Change to add new functions
+ /* c */ 0x00,  // reserved
+ /* d */ 0x00,  // reserved
+ /* e */ 0x00,  // Change to add new functions
+ /* f */ 0x00   // reserved
+};
diff --git a/vgasrc/vgatables.h b/vgasrc/vgatables.h
new file mode 100644 (file)
index 0000000..82b1302
--- /dev/null
@@ -0,0 +1,134 @@
+
+#include "types.h" // u8
+
+/*
+ *
+ * VGA registers
+ *
+ */
+#define VGAREG_ACTL_ADDRESS            0x3c0
+#define VGAREG_ACTL_WRITE_DATA         0x3c0
+#define VGAREG_ACTL_READ_DATA          0x3c1
+
+#define VGAREG_INPUT_STATUS            0x3c2
+#define VGAREG_WRITE_MISC_OUTPUT       0x3c2
+#define VGAREG_VIDEO_ENABLE            0x3c3
+#define VGAREG_SEQU_ADDRESS            0x3c4
+#define VGAREG_SEQU_DATA               0x3c5
+
+#define VGAREG_PEL_MASK                0x3c6
+#define VGAREG_DAC_STATE               0x3c7
+#define VGAREG_DAC_READ_ADDRESS        0x3c7
+#define VGAREG_DAC_WRITE_ADDRESS       0x3c8
+#define VGAREG_DAC_DATA                0x3c9
+
+#define VGAREG_READ_FEATURE_CTL        0x3ca
+#define VGAREG_READ_MISC_OUTPUT        0x3cc
+
+#define VGAREG_GRDC_ADDRESS            0x3ce
+#define VGAREG_GRDC_DATA               0x3cf
+
+#define VGAREG_MDA_CRTC_ADDRESS        0x3b4
+#define VGAREG_MDA_CRTC_DATA           0x3b5
+#define VGAREG_VGA_CRTC_ADDRESS        0x3d4
+#define VGAREG_VGA_CRTC_DATA           0x3d5
+
+#define VGAREG_MDA_WRITE_FEATURE_CTL   0x3ba
+#define VGAREG_VGA_WRITE_FEATURE_CTL   0x3da
+#define VGAREG_ACTL_RESET              0x3da
+
+#define VGAREG_MDA_MODECTL             0x3b8
+#define VGAREG_CGA_MODECTL             0x3d8
+#define VGAREG_CGA_PALETTE             0x3d9
+
+/* Video memory */
+#define VGAMEM_GRAPH 0xA000
+#define VGAMEM_CTEXT 0xB800
+#define VGAMEM_MTEXT 0xB000
+
+/*
+ *
+ * Tables of default values for each mode
+ *
+ */
+#define MODE_MAX   15
+#define TEXT       0x00
+#define GRAPH      0x01
+
+#define CTEXT      0x00
+#define MTEXT      0x01
+#define CGA        0x02
+#define PLANAR1    0x03
+#define PLANAR4    0x04
+#define LINEAR8    0x05
+
+// for SVGA
+#define LINEAR15   0x10
+#define LINEAR16   0x11
+#define LINEAR24   0x12
+#define LINEAR32   0x13
+
+#define SCROLL_DOWN 0
+#define SCROLL_UP   1
+#define NO_ATTR     2
+#define WITH_ATTR   3
+
+#define SCREEN_SIZE(x,y) (((x*y*2)|0x00ff)+1)
+#define SCREEN_MEM_START(x,y,p) ((((x*y*2)|0x00ff)+1)*p)
+#define SCREEN_IO_START(x,y,p) ((((x*y)|0x00ff)+1)*p)
+
+
+extern u16 video_save_pointer_table[];
+
+struct vgamodes_s {
+    u8 svgamode;
+    u8 class;                   /* TEXT, GRAPH */
+    u8 memmodel;                /* CTEXT,MTEXT,CGA,PL1,PL2,PL4,P8,P15,P16,P24,P32 */
+    u8 pixbits;
+    u16 sstart;
+    u8 pelmask;
+    u8 dacmodel;                /* 0 1 2 3 */
+} PACKED;
+
+extern struct vgamodes_s vga_modes[];
+
+/* Default Palette */
+#define DAC_MAX_MODEL 3
+
+extern u8 line_to_vpti[];
+extern u8 dac_regs[];
+
+/* standard BIOS Video Parameter Table */
+struct VideoParamTableEntry_s {
+    u8 twidth;
+    u8 theightm1;
+    u8 cheight;
+    u16 slength;
+    u8 sequ_regs[4];
+    u8 miscreg;
+    u8 crtc_regs[25];
+    u8 actl_regs[20];
+    u8 grdc_regs[9];
+} PACKED;
+
+extern struct VideoParamTableEntry_s video_param_table[];
+extern u8 palette0[];
+extern u8 palette1[];
+extern u8 palette2[];
+extern u8 palette3[];
+extern u8 static_functionality[];
+
+// vgafonts.c
+extern u8 vgafont8[];
+extern u8 vgafont14[];
+extern u8 vgafont16[];
+extern u8 vgafont14alt[];
+extern u8 vgafont16alt[];
+
+// vga.c
+void biosfn_set_single_palette_reg(u8 reg, u8 val);
+u8 biosfn_get_single_palette_reg(u8 reg);
+
+// clext.c
+void cirrus_set_video_mode(u8 mode);
+void cirrus_init();