From 1f2c307bc3ed23625c1a2842ff8f92a44917aebf Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Wed, 6 May 2009 23:35:59 -0400 Subject: [PATCH] Add initial port of the "open source vga bios" project. 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 | 28 +- vgasrc/clext.c | 388 ++++++ vgasrc/vga.c | 2818 ++++++++++++++++++++++++++++++++++++++++ vgasrc/vgaentry.S | 43 + vgasrc/vgafonts.c | 785 +++++++++++ vgasrc/vgalayout.lds.S | 24 + vgasrc/vgatables.c | 353 +++++ vgasrc/vgatables.h | 134 ++ 8 files changed, 4571 insertions(+), 2 deletions(-) create mode 100644 vgasrc/clext.c create mode 100644 vgasrc/vga.c create mode 100644 vgasrc/vgaentry.S create mode 100644 vgasrc/vgafonts.c create mode 100644 vgasrc/vgalayout.lds.S create mode 100644 vgasrc/vgatables.c create mode 100644 vgasrc/vgatables.h diff --git a/Makefile b/Makefile index e079f12..5890fa5 100644 --- 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 index 0000000..4be70c1 --- /dev/null +++ b/vgasrc/clext.c @@ -0,0 +1,388 @@ +// QEMU Cirrus CLGD 54xx VGABIOS Extension. +// +// Copyright (C) 2009 Kevin O'Connor +// 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 index 0000000..e9deea0 --- /dev/null +++ b/vgasrc/vga.c @@ -0,0 +1,2818 @@ +// VGA bios implementation +// +// Copyright (C) 2009 Kevin O'Connor +// 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, ®s->cx, ®s->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, ®s->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, ®s->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, ®s->es, 0 // ®s->bp + , ®s->cx, ®s->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 index 0000000..48264cf --- /dev/null +++ b/vgasrc/vgaentry.S @@ -0,0 +1,43 @@ +// Rom layout and bios assembler to C interface. +// +// Copyright (C) 2009 Kevin O'Connor +// +// 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 index 0000000..8c1752c --- /dev/null +++ b/vgasrc/vgafonts.c @@ -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 index 0000000..b5f0319 --- /dev/null +++ b/vgasrc/vgalayout.lds.S @@ -0,0 +1,24 @@ +// Linker definitions for an option rom +// +// Copyright (C) 2009 Kevin O'Connor +// +// 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 index 0000000..c0aea04 --- /dev/null +++ b/vgasrc/vgatables.c @@ -0,0 +1,353 @@ +// Tables used by VGA bios +// +// Copyright (C) 2009 Kevin O'Connor +// 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 index 0000000..82b1302 --- /dev/null +++ b/vgasrc/vgatables.h @@ -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(); -- 2.25.1