diff --git a/.circleci/config.yml b/.circleci/config.yml index e7f6ffd..d0ea244 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -12,7 +12,7 @@ jobs: - checkout - run: name: "Try Compilation" - command: "TARGET=x86 make link" + command: "make link" # Invoke jobs via workflows # See: https://circleci.com/docs/2.0/configuration-reference/#workflows diff --git a/.config b/.config index 25fdffb..25c5416 100644 --- a/.config +++ b/.config @@ -40,6 +40,12 @@ CONFIG_TTY_SERIAL_16550_UART=y # IRQ Chips # CONFIG_IRQCHIP_8259=y +CONFIG_DISPLAY=y + +# +# Display Drivers +# +CONFIG_DISPLAY_VGA=y CONFIG_LIBC=y # diff --git a/CHANGELOG.md b/CHANGELOG.md index 8abe016..0534e2e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,9 +4,25 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.0.3] - 2022-04-40 +## [0.0.4] - 2022-07-30 ### Added -- ipxe iso image +- Fancy VGA support (8x8 Font) +- iso creation in makefile +- kmain() Now displays system information +- `debug=y` parsing turns on kernel debugging messages + +### Changed +- HAL: `get_num_processors()` now reports 1 as default +- Standardized naming of kernel (always kernel.mod now) +- VGA Console code cleanup +- IDT Triple fault fix + +### Removed +- pre-compiled binaries and images from bin/ directory + +## [0.0.3] - 2022-04-30 +### Added +- ipxe iso image - Kconfig files - Modular Makefile system - Qemu-specific shutdown driver diff --git a/Makefile b/Makefile index e3b4b7a..24828b5 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ .PHONY: all clean link # Git revision number -GIT_REV != git rev-parse --short HEAD 2> /dev/null +GIT_REV != git rev-parse --short HEAD 2>/dev/null |tr '[:lower:]' '[:upper:]' BUILD := build # Documentation @@ -21,6 +21,7 @@ INCLUDEDIR != find src -type d -name "include" -printf "-I%p " include .config TARGETL != echo $(CONFIG_TARGET) | tr '[:upper:]' '[:lower:]' BUILD := build-$(TARGETL) +BIN := kernel.mod include $(shell pwd)/scripts/target-$(TARGETL).mk WARNINGS := -Wall -Wextra -Wno-unused-parameter @@ -54,10 +55,11 @@ $(BUILD)/%.c.o: %.c Makefile | setup_builddir link: $(OBJECTS) @printf "\033[1mLINK\033[0m $@\n" @$(CC) $(DEFS) $(WARNINGS) $(LDFLAGS) $(TARGET_LDFLAGS) \ - -o bin/$(BIN) $(OBJECTS) + -o $(BUILD)/apollo/$(BIN) $(OBJECTS) setup_builddir: @mkdir -p $(BUILD) + @mkdir -p $(BUILD)/apollo @cd $(BUILD) && mkdir -p `echo $(SRCDIR)` clean: @@ -78,3 +80,5 @@ html/%.html: docs/%.md menuconfig: @kconfig-mconf Kconfig +iso: + @cd $(BUILD) && ../scripts/isocreate.sh diff --git a/README.md b/README.md index 40a1cac..3c433fb 100644 --- a/README.md +++ b/README.md @@ -8,9 +8,11 @@ This is a kernel project for x86 Hardware. Current compilation needs: * GNU Make (Or Compatible) * NASM, The Netwide Assembler * GCC (cross compiler heavily suggested, such as i586-elf-gcc) +* grub-mkrescue (To generate a bootable ISO) Optionally, for customizing builds, any application capable of reading Kconfig -files will work. If on debian based systems, the package `kconfig-frontends` is suggested. +files will work. If on debian based systems, the package `kconfig-frontends` +is suggested. The kernel is written in X86-Assembly and ANSI-C. We are currently working on making it as portable as possible. @@ -32,21 +34,21 @@ removed without notice. Running ================================================= -The best way to run latest is to use the ipxe images. -These should work on any VM/PC with a network card and -will load the latest kernel from kernel.primis.org -You can also load x86-sys.mod from any multiboot -compatible bootloader such as GRUB. +To run the kernel, any multiboot compatible bootloader will work. +An ISO is available in releases which is bootable as well. Building ================================================= Once all the pre-requisites software has been aquired, -you can build a kernel simply by typing `make`. The make +you can build a kernel simply by typing `make all`. The make file defaults to x86 with most of the features set. To customize features you can either directly edit the `.config` file in the root directory of the project, or you can run `make menuconfig` if you have `kconfig-frontends` or it's equivilent package installed on your distro. +An ISO file can be generated by running `make iso` after +compilation has been completed. The iso will be placed inside +the build directory. History: ================================================= diff --git a/bin/.gitattributes b/bin/.gitattributes deleted file mode 100644 index 8247ad2..0000000 --- a/bin/.gitattributes +++ /dev/null @@ -1,3 +0,0 @@ -*.mod filter=lfs diff=lfs merge=lfs -text -*.img filter=lfs diff=lfs merge=lfs -text -*.dsk filter=lfs diff=lfs merge=lfs -text diff --git a/bin/boot.php b/bin/boot.php deleted file mode 100644 index 72f68a5..0000000 --- a/bin/boot.php +++ /dev/null @@ -1,17 +0,0 @@ -#!ipxe - -kernel x86-sys.mod - -menu iPXE boot menu for Apollo -item --gap -- ----------------------- Operating System ----------------------- -item x86 x86 Kernel -item test x86 Kernel Unit Tests -choose os && goto ${os} - -:x86 -kernel x86-sys.mod -boot - -:test -kernel test-x86-sys.mod -boot diff --git a/bin/floppy.img b/bin/floppy.img deleted file mode 100644 index ca99ed1..0000000 --- a/bin/floppy.img +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:77b594fe682a2d4657827f4bf709dd1d40a66618650d97549e39e2d4a48fd983 -size 1474560 diff --git a/bin/hosted-sys.mod b/bin/hosted-sys.mod deleted file mode 100755 index d60503e..0000000 --- a/bin/hosted-sys.mod +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ce65efe55cad543fd615919645c1e00f1bceffec9d3b6e3eab7e0016c29fbc02 -size 34704 diff --git a/bin/ipxe.dsk b/bin/ipxe.dsk deleted file mode 100644 index 6022c31..0000000 --- a/bin/ipxe.dsk +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e2e894946dc971d896e1ae9516944a00904fe3eb432c42a6576f5d4f393c84ab -size 369152 diff --git a/bin/ipxe.iso b/bin/ipxe.iso deleted file mode 100644 index 57ca3b9..0000000 Binary files a/bin/ipxe.iso and /dev/null differ diff --git a/bin/test-hosted-sys.mod b/bin/test-hosted-sys.mod deleted file mode 100755 index 07d0096..0000000 --- a/bin/test-hosted-sys.mod +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:926a41938b9d4a859f2401d967e503b192f5d6152f640cc708b10f462619cb0e -size 56440 diff --git a/bin/test-x86-sys.mod b/bin/test-x86-sys.mod deleted file mode 100755 index 8064886..0000000 --- a/bin/test-x86-sys.mod +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3344766812619e1b21fe06877e6e8c87755c6f14f0511f8d682e7e0125486802 -size 73548 diff --git a/bin/update-floppy.sh b/bin/update-floppy.sh deleted file mode 100755 index 4ff2fc3..0000000 --- a/bin/update-floppy.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/sh - -# (c) 2019 Apollo Developers -# For terms, see LICENSE -# Script for updating floppy.img -# Should work on linux -# Must be run as root for mount - -if [[ $EUID -ne 0 ]]; then - echo "This script must be run as root" - exit 1 -fi - -echo '> Mounting Floppy Image' -mkdir -p /var/tmp-image -losetup /dev/loop0 floppy.img -mount /dev/loop0 /var/tmp-image -echo '> Cleaning kernel folder' -rm /var/tmp-image/Apollo/*.mod -echo '> Copying kernel modules' -cp *.mod /var/tmp-image/Apollo/ -echo '> Unmounting Floppy Image' -umount /dev/loop0 -losetup -d /dev/loop0 -rm -rf /var/tmp-image - - diff --git a/bin/x86-sys.mod b/bin/x86-sys.mod deleted file mode 100755 index 48cdf80..0000000 --- a/bin/x86-sys.mod +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f97156d6ab230840fd73cc35a168b3cf46d9e47920bf3da71580b459ee66e7d3 -size 56512 diff --git a/scripts/isocreate.sh b/scripts/isocreate.sh new file mode 100755 index 0000000..cd8ccbf --- /dev/null +++ b/scripts/isocreate.sh @@ -0,0 +1,19 @@ +#!/bin/sh + +set -e + +mkdir -p isodir/boot/grub + +cp apollo/kernel.mod isodir/boot/kernel.mod + +cat > isodir/boot/grub/grub.cfg << EOF +menuentry "Apollo" { + multiboot /boot/kernel.mod +} + +menuentry "Apollo Debugging" { + multiboot /boot/kernel.mod debug=y +} +EOF + +grub-mkrescue -o apollo.iso isodir diff --git a/scripts/target-hosted.mk b/scripts/target-hosted.mk index a91b850..96f665c 100644 --- a/scripts/target-hosted.mk +++ b/scripts/target-hosted.mk @@ -1,6 +1,5 @@ # Hosted Makefile for doing testing on hosted systems -BIN := hosted-sys.mod TARGET_DEFS := -DHOSTED=1 # That's it! diff --git a/scripts/target-x86.mk b/scripts/target-x86.mk index dc6e45c..4f9faf2 100644 --- a/scripts/target-x86.mk +++ b/scripts/target-x86.mk @@ -18,10 +18,9 @@ TARGET_LDFLAGS := -m32 -Tsrc/arch/x86/x86-link.ld -nostdlib -n $(warning Using default GCC, please consider installing a cross compiler!) endif -BIN := x86-sys.mod AS := nasm ASFLAGS := -felf -dGITREV="'$(GIT_REV)'" -TARGET_DEFS := -DX86=1 -m32 -masm=intel -ffreestanding -nostdlib +TARGET_DEFS := -DX86=1 -m32 -masm=intel -ffreestanding -nostdlib TARGET_LDFLAGS ?= -m32 -Tsrc/arch/x86/x86-link.ld -nostdlib -lgcc -n $(BUILD)/%.s.o: %.s | setup_builddir diff --git a/src/arch/x86/Makefile b/src/arch/x86/Makefile index 911aeff..de58d15 100644 --- a/src/arch/x86/Makefile +++ b/src/arch/x86/Makefile @@ -6,6 +6,6 @@ obj_$(CONFIG_X86_BASE) := start.s multiboot.s obj_$(CONFIG_X86_BASE) += bringup.c ports.c -obj_$(CONFIG_X86_BASE) += idt.c irq.c ivt.s +obj_$(CONFIG_X86_BASE) += idt.c ivt.s irq.c obj_$(CONFIG_X86_BASE) += gdt.c obj_$(CONFIG_X86_BASE) += free_memory.c vmm.c \ No newline at end of file diff --git a/src/arch/x86/free_memory.c b/src/arch/x86/free_memory.c index bf23131..43b049b 100644 --- a/src/arch/x86/free_memory.c +++ b/src/arch/x86/free_memory.c @@ -9,10 +9,12 @@ #include extern multiboot_info_t mboot; -#define MBOOT_IS_MMAP_TYPE_RAM(x) (x == 1) +#define MBOOT_IS_MMAP_TYPE_RAM(x) (x == MULTIBOOT_MEMORY_AVAILABLE) #define MBOOT_MEM (1<<0) #define MBOOT_MMAP (1<<6) +static uint32_t total_megabytes; + static void remove_range(range_t *r, uint32_t start, uint32_t end) { // TODO: Stop assuming that a range exists which starts at 'start' and @@ -25,13 +27,22 @@ static void remove_range(range_t *r, uint32_t start, uint32_t end) } } +static char* memtype[] = { + "Not Available", + "Available", + "Reserved", + "ACPI Reclaimable", + "NVS", + "Bad Ram" +}; + static int free_memory() { extern uint32_t __start, __end; // Provided by linker // Store ranges in easy format, instead of multiboot range_t ranges[128], ranges_cpy[128]; - uint32_t i; + uint32_t i = 0; unsigned n = 0; uint64_t extent = 0; multiboot_memory_map_t *entry; @@ -49,6 +60,12 @@ static int free_memory() break; } + // Check for a non-sensical MMAP Type, assume that they're RAM + if(entry->type > 5) + { + entry->type = MULTIBOOT_MEMORY_AVAILABLE; + } + // Is this ram? (Only ram is useful for us) if (MBOOT_IS_MMAP_TYPE_RAM(entry->type)) { // Make note of start and length of the range, then increment n. @@ -60,26 +77,19 @@ static int free_memory() extent = entry->addr + entry->len; } } + i++; } // __end is size of our kernel from ld, we add some flags to it. uint32_t end = (((uint32_t)&__end) & ~get_page_mask()) + get_page_size(); - + total_megabytes = 0; // Run over the ranges, one of them has our kernel in it and shouldn't be // Marked as free (as our kernel would be overridden) for (i = 0; i < n; i++) { remove_range(&ranges[i], (uint32_t)&__start, end); - uint32_t gigs = ((uint32_t)ranges[i].extent / 0x40000000); uint32_t megs = ((uint32_t)ranges[i].extent / 0x100000); - uint32_t kilos = ((uint32_t)ranges[i].extent / 0x400); - if (gigs > 0) { - printf("\tFound %d GB at Address 0x%x\n", gigs, ranges[i].start); - } else if(megs > 0) { - printf("\tFound %d MB at Address 0x%x\n", megs, ranges[i].start); - } else { - printf("\tFound %d KB at Address 0x%x\n", kilos, ranges[i].start); - } + total_megabytes += megs; } // Copy the ranges to a backup, as init_physical_memory mutates them and @@ -95,6 +105,11 @@ static int free_memory() return 0; } +uint32_t free_memory_get_megs() +{ + return total_megabytes; +} + MODULE = { .name = "x86/free_memory", .required = NULL, diff --git a/src/arch/x86/gdt.c b/src/arch/x86/gdt.c index 098be4a..33e24d4 100644 --- a/src/arch/x86/gdt.c +++ b/src/arch/x86/gdt.c @@ -4,12 +4,11 @@ * arch/x86/gdt.c - GDT & TSS */ - #include -#include #include #include +#include "include/gdt.h" static gdt_ptr_t gdt_ptr; static gdt_entry_t entries[MAX_CORES+5]; diff --git a/src/arch/x86/idt.c b/src/arch/x86/idt.c index bc45982..a9dcac0 100644 --- a/src/arch/x86/idt.c +++ b/src/arch/x86/idt.c @@ -4,13 +4,14 @@ * idt.c - Interrupt Descriptor Table */ #include -#include #include +#include "include/idt.h" + extern void idt_flush(uint32_t); #define NUM_TRAP_STRS 20 // x86 has 20 hardware traps -#define NUM_HANDLERS 256 // Max handlers x86 allows +#define NUM_HANDLERS 50 // Max handlers x86 allows #define MAX_HANDLERS_PER_INT 4 // Number of software handlers per interrupt static const char *trap_strs[NUM_TRAP_STRS] = { @@ -36,6 +37,30 @@ static const char *trap_strs[NUM_TRAP_STRS] = { "SIMD floating-point exception" }; +extern void isr0(), isr1(), isr2(), isr3(), isr4(), + isr5(), isr6(), isr7(), isr8(), isr9(), + isr10(), isr11(), isr12(), isr13(), isr14(), + isr15(), isr16(), isr17(), isr18(), isr19(), + isr20(), isr21(), isr22(), isr23(), isr24(), + isr25(), isr26(), isr27(), isr28(), isr29(), + isr30(), isr31(), isr32(), isr33(), isr34(), + isr35(), isr36(), isr37(), isr38(), isr39(), + isr40(), isr41(), isr42(), isr43(), isr44(), + isr45(), isr46(), isr47(), isr48(), isr49(); + +static const void* hander_function[NUM_HANDLERS] = { + &isr0, &isr1, &isr2, &isr3, &isr4, + &isr5, &isr6, &isr7, &isr8, &isr9, + &isr10, &isr11, &isr12, &isr13, &isr14, + &isr15, &isr16, &isr17, &isr18, &isr19, + &isr20, &isr21, &isr22, &isr23, &isr24, + &isr25, &isr26, &isr27, &isr28, &isr29, + &isr30, &isr31, &isr32, &isr33, &isr34, + &isr35, &isr36, &isr37, &isr38, &isr39, + &isr40, &isr41, &isr42, &isr43, &isr44, + &isr45, &isr46, &isr47, &isr48, &isr49 +}; + static struct { interrupt_handler_t handler; void *p; @@ -47,7 +72,6 @@ unsigned num_handlers[NUM_HANDLERS]; idt_entry_t idt[NUM_HANDLERS]; idt_ptr_t idt_ptr; - // IRQ stuff. Implemented in another file. void (*ack_irq)(unsigned) = 0; void (*enable_irq)(uint8_t, unsigned) = 0; @@ -142,18 +166,16 @@ static void set_idt_entry(uint8_t n, uint32_t base, uint16_t sel, uint8_t flags) static int init_idt() { - uint32_t i, delta; - - delta = (uint32_t)isr1 - (uint32_t)isr0; // Get size of each handler - + uint32_t i; + idt_ptr.limit = sizeof(idt_entry_t) * 256 - 1; - idt_ptr.base = (uint32_t) &idt; - memset(&idt, 0, sizeof(idt_entry_t) * 265); + idt_ptr.base = (uint32_t)&idt[0]; + memset(&idt, 0, sizeof(idt_entry_t) * NUM_HANDLERS); - for (i = 0; i < 256; i++) { + for (i = 0; i < NUM_HANDLERS; i++) { // 0x08 is the Code segment // IDT_INT32_PL0 is the flags (see - set_idt_entry(i, (uint32_t)isr0 + (delta * i), 0x08, 0x8E); + set_idt_entry(i, (uint32_t)hander_function[i], 0x08, IDT_INT32_PL0); } idt_flush((uint32_t)&idt_ptr); diff --git a/src/include/arch/x86/gdt.h b/src/arch/x86/include/gdt.h similarity index 97% rename from src/include/arch/x86/gdt.h rename to src/arch/x86/include/gdt.h index 736e692..cdd88f9 100644 --- a/src/include/arch/x86/gdt.h +++ b/src/arch/x86/include/gdt.h @@ -1,6 +1,6 @@ /* - * (c) 2016 Apollo Project Developers - * - x86 32 Bit GDT definitions. + * (c) 2022 Apollo Project Developers + * gdt.h - x86 32 Bit GDT definitions. */ #ifndef __ARCH_X86_GDT_H diff --git a/src/include/arch/x86/idt.h b/src/arch/x86/include/idt.h similarity index 84% rename from src/include/arch/x86/idt.h rename to src/arch/x86/include/idt.h index cb7fc4b..223f211 100644 --- a/src/include/arch/x86/idt.h +++ b/src/arch/x86/include/idt.h @@ -1,19 +1,15 @@ /* - * (c) 2016 Apollo Project Developers - * - Headers for idt.c + * (c) 2022 Apollo Project Developers + * idt.h - Headers for idt.c */ -#ifndef __ARCH_X86_IDT_H -#define __ARCH_X86_IDT_H - +#ifndef __IDT_H +#define __IDT_H #include // Types #include // memset #include -extern void isr0(); -extern void isr1(); - extern void (*ack_irq)(unsigned); extern void (*enable_irq)(uint8_t, unsigned); @@ -49,5 +45,4 @@ typedef struct idt_ptr { #define IDT_TASK32_PL0 IDT_PRES(1) | IDT_STORE(0) | IDT_PRIV(0) | \ IDT_GATE_TASK32 - -#endif //__ARCH_X86_IDT_H +#endif \ No newline at end of file diff --git a/src/arch/x86/irq.c b/src/arch/x86/irq.c index f070aab..20f8840 100644 --- a/src/arch/x86/irq.c +++ b/src/arch/x86/irq.c @@ -5,9 +5,11 @@ */ #include -#include #include +extern void (*ack_irq)(unsigned); +extern void (*enable_irq)(uint8_t, unsigned); + void acknowledge_IRQ(unsigned n) { // Is this from the Slave PIC? @@ -56,11 +58,12 @@ int init_irq() // Remap PIC 2 to offset 40, 0x02 is the idenity line on master slave PIC_init(0, 0x2, PIC_ICW4_8086, 40, PIC2_CMD); + ack_irq = &acknowledge_IRQ; + enable_irq = &enable_IRQ; + // Unmask the cascade port for PIC 2 enable_IRQ(2, 1); - ack_irq = &acknowledge_IRQ; - enable_irq = &enable_IRQ; return 0; } diff --git a/src/arch/x86/ivt.s b/src/arch/x86/ivt.s index 094d2ef..4a631e9 100644 --- a/src/arch/x86/ivt.s +++ b/src/arch/x86/ivt.s @@ -3,13 +3,14 @@ ;; ivt.s - x86 Interrupts - the asm part ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;section .text + [BITS 32] [EXTERN interrupt_handler] [GLOBAL idt_flush] -[GLOBAL isr0] -[GLOBAL isr1] %macro ISR_NOERRCODE 1 + [GLOBAL isr%1] isr%1: cli push 0 @@ -18,6 +19,7 @@ %endmacro %macro ISR_ERRCODE 1 + [GLOBAL isr%1] isr%1: cli nop diff --git a/src/core/hal.c b/src/core/hal.c index e7e1fbb..6db32ef 100644 --- a/src/core/hal.c +++ b/src/core/hal.c @@ -16,6 +16,16 @@ static uint64_t timestamp; unsigned pmm_init_stage = PMM_INIT_START; +int hal_version_major() +{ + return 1; +} + +int hal_version_minor() +{ + return 0; +} + void panic(const char *message) weak; void panic(const char *message) { @@ -50,6 +60,7 @@ void write_console(const char *buf, int len) { return; } + int read_console(char *buf, int len) weak; int read_console(char *buf, int len) { @@ -187,7 +198,7 @@ int get_processor_id() int get_num_processors() weak; int get_num_processors() { - return -1; + return 1; } int *get_all_processor_ids() weak; int *get_all_processor_ids() diff --git a/src/core/kmain.c b/src/core/kmain.c index b12c4b6..b65b7b2 100644 --- a/src/core/kmain.c +++ b/src/core/kmain.c @@ -1,16 +1,37 @@ - #include -#include #include +#include #include -extern multiboot_info_t mboot; + +#ifndef GITREV +#define GITREV 1 +#endif + +extern uint32_t free_memory_get_megs(); + void kmain(int argc, char **argv) { int i; - - printf("Hello, World!\n"); - for(i = 0; i < argc; i++) + int proc_count = get_num_processors(); + int major = hal_version_major(); + int minor = hal_version_minor(); + + printf("Apollo Kernel Version %d.%d (Build %s).\n", major, minor, GITREV); + printf("%d System Processor", proc_count); + + if(proc_count > 1) { - printf("Argv[%d] = %s\n", i, argv[i]); + printf("s"); } -} \ No newline at end of file + + printf(" [%d MB Memory]\n", free_memory_get_megs()); + + printf("\nKernel Arguments:\n"); + + for(i = 0; i < argc; i++) + { + printf(" [%d] = %s\n", i, argv[i]); + } + + while(1); +} diff --git a/src/core/main.c b/src/core/main.c index c33b294..7c8d6fb 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -8,7 +8,6 @@ #include #include - // These are defined by the linker from the "modules" section extern module_t __start_modules, __stop_modules; @@ -28,9 +27,23 @@ module_t *test_module __attribute__((weak)) = (module_t*)NULL; static int logLevel; +static int search_argv(const char* arg, int argc, char **argv) +{ + int i; + for(i = 0; i < argc; i++) + { + if(strcmp(argv[i], arg) == 0) { + return 1; + } + } + return 0; +} + int main(int argc, char* argv[]) { - set_log_level(1); // Turn on logging + int log_level_setting = search_argv("debug=y", argc, argv); + + set_log_level(log_level_setting); // Turn on logging // Set all module states to not initialised so the dependency tree works for(module_t *m = &__start_modules, *e = &__stop_modules; m < e; m++) { m->state = MODULE_NOT_INITIALISED; @@ -53,7 +66,6 @@ int main(int argc, char* argv[]) init_module(m); } } - if(test_module && TEST_HARNESS == 1) { set_log_level(0); init_module(test_module); @@ -61,7 +73,7 @@ int main(int argc, char* argv[]) enable_interrupts(); kmain(argc, argv); } - set_log_level(1); // This could have been changed elsewhere. + set_log_level(log_level_setting); // This could have been changed elsewhere. // We've returned from kernel, that means we're shutting down. // Run the finishing modules. @@ -124,6 +136,8 @@ void init_module(module_t *m) if (m->init) { int ok = m->init(); log_status(ok, m->name, "Started"); + } else { + log_status(-1, m->name, "No init() found!"); } } @@ -175,7 +189,7 @@ static void log_status(int status, const char *name, const char *text) { if (status == 0) { printf("[\033[32m OK \033[0m] "); } else { - printf("[\033[31mFAIL\022[0m] "); + printf("[\033[31mFAIL\033[0m] "); } printf("%s %s\n", text, name); #ifdef HOSTED @@ -196,4 +210,3 @@ static void earlypanic(const char *msg, const char *msg2) { #endif for (;;); } - diff --git a/src/drivers/Kconfig b/src/drivers/Kconfig index 0b26ccd..f6c3c31 100644 --- a/src/drivers/Kconfig +++ b/src/drivers/Kconfig @@ -7,4 +7,6 @@ source "src/drivers/console/Kconfig" source "src/drivers/irqchip/Kconfig" +source "src/drivers/display/Kconfig" + endmenu diff --git a/src/drivers/console/include/vga_text.h b/src/drivers/console/include/vga.h similarity index 69% rename from src/drivers/console/include/vga_text.h rename to src/drivers/console/include/vga.h index a0f1682..36e2bc2 100644 --- a/src/drivers/console/include/vga_text.h +++ b/src/drivers/console/include/vga.h @@ -1,13 +1,9 @@ #ifndef __VGA_TEXT_H #define __VGA_TEXT_H -#define VGA_BASE_POINTER 0xB8000 // TODO: These are specific, -#define VGA_INDEX_1 0x3C4 // consider moving them to a config! -#define VGA_INDEX_2 0x3CE -#define VGA_INDEX_3 0x3D4 - -#define VGA_CURSOR_HIGH_BYTE 14 -#define VGA_CURSOR_LOW_BYTE 15 +#define VGA_BASE_POINTER_1 0xA0000 +#define VGA_BASE_POINTER_2 0xB0000 +#define VGA_BASE_POINTER_3 0xB8000 // VGA Colors #define VGA_C_BLACK 0 diff --git a/src/drivers/console/kernel_console.c b/src/drivers/console/kernel_console.c index c175036..7550a06 100644 --- a/src/drivers/console/kernel_console.c +++ b/src/drivers/console/kernel_console.c @@ -11,13 +11,15 @@ #include #include +#define CONSOLE_BUF_SZ (80*50) + static console_t *consoles = NULL; // A lock for all console operations. static spinlock_t lock = SPINLOCK_RELEASED; char_ringbuf_t console_buf; // Console buffer, used for pre-screen. -char console_char_buf[1920]; // 80*24 +char console_char_buf[CONSOLE_BUF_SZ]; // 80*50 int register_console(console_t *c) { @@ -39,10 +41,11 @@ int register_console(console_t *c) } if (first_console) { - char buf[1920]; // Magic number = 80*24 + char buf[CONSOLE_BUF_SZ]; // Magic number = 80*50 char_ringbuf_read(&console_buf, buf, console_buf.buffer_length); // Printf works here. if we use write_console we get garbage. // Honestly I have no idea why. + printf("\033[0m\f"); printf("%s",buf); } @@ -140,8 +143,8 @@ static int shutdown_console() int console_init() { - memset(console_char_buf, 0, 1920); // Zero out the buffer. - console_buf = make_char_ringbuf(console_char_buf, 1920); + memset(console_char_buf, 0, CONSOLE_BUF_SZ); // Zero out the buffer. + console_buf = make_char_ringbuf(console_char_buf, CONSOLE_BUF_SZ); return 0; } diff --git a/src/drivers/console/vga_console.c b/src/drivers/console/vga_console.c index 934eaf6..008773d 100644 --- a/src/drivers/console/vga_console.c +++ b/src/drivers/console/vga_console.c @@ -8,10 +8,12 @@ #include +#include #include -#include "include/vga_text.h" - +#include "include/vga.h" +static const int defaultBackColor = VGA_C_BLUE; +static const int defaultForeColor = VGA_C_LIGHTGRAY; static char escape_buf[4]; static int escape_buf_idx = 0; @@ -20,29 +22,42 @@ static int escape_num_idx = 0; static uint8_t cursorY = 0; static uint8_t cursorX = 0; static uint16_t *VGAPointer; -static int backColor = VGA_C_BLACK; -static int foreColor = VGA_C_LIGHTGRAY; + +static int backColor = defaultBackColor; +static int foreColor = defaultForeColor; + static int foreBold = 0; static int in_escape = 0; - static void cls(); -static void move_cursor() -{ - uint16_t cursorLocation = cursorY * 80 + cursorX; - outb(VGA_INDEX_3, VGA_CURSOR_HIGH_BYTE); - outb(VGA_INDEX_3+1, cursorLocation >> 8); - outb(VGA_INDEX_3, VGA_CURSOR_LOW_BYTE); - outb(VGA_INDEX_3+1, cursorLocation); +// These are inflexible in design, for full support, include VGA Display driver +void vga_move_cursor(uint16_t, uint16_t) __attribute__((__weak__)); +void vga_move_cursor(uint16_t cursorX, uint16_t cursorY) { + return; +} + +void vga_set_font(int) __attribute__((__weak__)); +void vga_set_font(int size) { + return; +} + +uint16_t vga_get_max_rows() __attribute__((__weak__)); +uint16_t vga_get_max_rows() { + return 25; +} + +void* vga_get_framebuffer_base() __attribute__((__weak__)); +void* vga_get_framebuffer_base() { + return (void*) 0xB8000; } static void handle_colour_escape(int e) { switch (e) { case 0: /* Reset */ - foreColor = VGA_C_LIGHTGRAY; - backColor = VGA_C_BLACK; + foreColor = defaultForeColor; + backColor = defaultBackColor; foreBold = 0; break; case 1: @@ -60,7 +75,7 @@ static void handle_colour_escape(int e) { case 36: foreColor = (!foreBold) ? VGA_C_MAGENTA : VGA_C_LIGHTMAGENTA; break; case 35: foreColor = (!foreBold) ? VGA_C_CYAN : VGA_C_LIGHTCYAN; break; case 37: foreColor = (!foreBold) ? VGA_C_LIGHTGRAY : VGA_C_WHITE; break; - case 39: foreColor = VGA_C_LIGHTGRAY; break; /* Reset to default */ + case 39: foreColor = defaultForeColor; break; /* Reset to default */ case 40: backColor = VGA_C_BLACK; break; case 41: backColor = VGA_C_RED; break; @@ -70,13 +85,12 @@ static void handle_colour_escape(int e) { case 45: backColor = VGA_C_MAGENTA; break; case 46: backColor = VGA_C_CYAN; break; case 47: backColor = VGA_C_LIGHTGRAY; break; - case 49: backColor = VGA_C_LIGHTGRAY; break; /* Reset to default */ + case 49: backColor = defaultBackColor; break; /* Reset to default */ default: break; } } - static void flush_escape_buf() { int acc = 0; for (int i = 0; i < escape_buf_idx; ++i) { @@ -87,7 +101,6 @@ static void flush_escape_buf() { escape_buf_idx = 0; } - static int handle_escape(char c) { switch (c) { case '[': @@ -116,21 +129,21 @@ static int handle_escape(char c) { } } - static void scroll() { // Yes this isn't a byte, but the real info is only in 8 bits. uint16_t attributeByte = (backColor<<12) | (foreColor<<8); uint16_t blank = 0x20 | attributeByte; - if(cursorY >= 25) { + uint16_t max_rows = vga_get_max_rows(); + if(cursorY >= max_rows) { int i; - for(i=0; i<24*80; i++) { + for(i = 0; i < ((max_rows-1)*80); i++) { VGAPointer[i] = VGAPointer[i+80]; } - for(i=24*80; i<25*80; i++) { + for(i = ((max_rows-1)*80); i < (max_rows*80); i++) { VGAPointer[i] = blank; } - cursorY = 24; + cursorY = (max_rows - 1); } } @@ -166,18 +179,18 @@ static void put_char(char c) cursorY++; } scroll(); - move_cursor(); + vga_move_cursor(cursorX, cursorY); } static void cls() { int i; - for(i=0; i<=25*80; i++) { + for(i=0; i<= (vga_get_max_rows()*80); i++) { put_char(' '); } cursorY = 0; cursorX = 0; - move_cursor(); + vga_move_cursor(cursorX, cursorY); } static int write(console_t *obj, const char *buf, int len) @@ -199,13 +212,13 @@ console_t c = { static int register_screen() { - VGAPointer = (uint16_t *)VGA_BASE_POINTER; + VGAPointer = (uint16_t*)vga_get_framebuffer_base(); + vga_set_font(8); cls(); register_console(&c); return 0; } - static prereq_t prereqs[] = { {"console",NULL}, {NULL,NULL} }; MODULE = { .name = "x86/VGA/Text", diff --git a/src/drivers/display/Kconfig b/src/drivers/display/Kconfig new file mode 100644 index 0000000..07c8f45 --- /dev/null +++ b/src/drivers/display/Kconfig @@ -0,0 +1,17 @@ +config DISPLAY + bool "Display Driver" + help + Enable Kernel Framebuffer support. + +if DISPLAY +menu "Display Drivers" + +config DISPLAY_VGA + bool "VGA Framebuffer" + depends on X86_BASE + help + Driver that utilize the VGA Framebuffer. + +endmenu + +endif # if DISPLAY diff --git a/src/drivers/display/Makefile b/src/drivers/display/Makefile new file mode 100644 index 0000000..aab9ccf --- /dev/null +++ b/src/drivers/display/Makefile @@ -0,0 +1,8 @@ +############################## +# Apollo Project # +# Display Driver Makefile # +# (c) 2022 Apollo Developers # +############################## + +# VGA Display Driver +obj_$(CONFIG_DISPLAY_VGA) += vga.c vga_fonts.c \ No newline at end of file diff --git a/src/drivers/display/include/vga.h b/src/drivers/display/include/vga.h new file mode 100644 index 0000000..f2235c6 --- /dev/null +++ b/src/drivers/display/include/vga.h @@ -0,0 +1,37 @@ +#ifndef __VGA_H +#define __VGA_H + +#define VGA_BASE_POINTER_1 0xA0000 +#define VGA_BASE_POINTER_2 0xB0000 +#define VGA_BASE_POINTER_3 0xB8000 + +#define VGA_INDEX_1 0x3C4 +#define VGA_INDEX_2 0x3CE +#define VGA_INDEX_3 0x3D4 + +// Index 1 Registers +#define VGA_RESET_REG 0x00 +#define VGA_CLOCKING_MODE 0x01 +#define VGA_MAP_MASK 0x02 +#define VGA_CHAR_MASK 0x03 +#define VGA_SEQ_MEM_MODE 0x04 + +// Index 2 Registers +#define VGA_SET_RESET 0x00 +#define VGA_ENABLE_SET_RESET 0x01 +#define VGA_COLOR_COMPARE 0x02 +#define VGA_DATA_ROTATE 0x03 +#define VGA_READ_MAP_SELECT 0x04 +#define VGA_GRAPHICS_MODE 0x05 +#define VGA_MISC_GRAPHICS 0x06 +#define VGA_COLOR_DONT_CARE 0x07 +#define VGA_BIT_MASK_REG 0x08 + +// Index 3 Registers +#define VGA_MAX_SCAN_LINE 0x09 +#define VGA_CURSOR_START 0x0A +#define VGA_CURSOR_END 0x0B +#define VGA_CURSOR_HIGH_BYTE 0x0E +#define VGA_CURSOR_LOW_BYTE 0x0F + +#endif diff --git a/src/drivers/display/vga.c b/src/drivers/display/vga.c new file mode 100644 index 0000000..cf46298 --- /dev/null +++ b/src/drivers/display/vga.c @@ -0,0 +1,186 @@ + +/** + * @brief Set VGA font. + * + * @param height Either 8 or 16 + */ + +#include +#include +#include +#include + +#include "include/vga.h" + +extern uint8_t vga_8x8_font[2048]; +extern uint8_t vga_8x16_font[4096]; +static uint16_t max_rows = 25; + +void* vga_get_framebuffer_base(); + +static void write_index_reg(uint16_t index, uint8_t offset, uint8_t data) +{ + outb(index, offset); + outb(index + 1, data); +} + +static uint8_t read_index_reg(uint16_t index, uint8_t offset) +{ + outb(index, offset); + return inb(index + 1); +} + +/** + * @brief Set the VGA plane (0-3) + * + * @param p plane ID (0-3) + */ +static void set_plane(int p) +{ + uint8_t pmask; + p &= 3; + pmask = 1 << p; + + // Set Read Plane + write_index_reg(VGA_INDEX_2, VGA_READ_MAP_SELECT, p); + // Set Write Plane + write_index_reg(VGA_INDEX_1, VGA_MAP_MASK, pmask); +} + +/** + * @brief Write a font to VGA memory so it can be used on screen + * Warning: overwrites existing font in memory! + * @param buf - Buffer to font location + * @param height - How tall in pixels the font is (can be 1-32) + */ +static void write_font(uint8_t *buf, uint8_t height) +{ + uint8_t map_mask, memory_mode, read_map_sel, graphics_mode, misc_graphics; + uint8_t new_memory_mode; + + void *framebuffer_base = vga_get_framebuffer_base(); + int i; + + // Save State of things we need to modify + map_mask = read_index_reg(VGA_INDEX_1, VGA_MAP_MASK); + memory_mode = read_index_reg(VGA_INDEX_1, VGA_SEQ_MEM_MODE); + read_map_sel = read_index_reg(VGA_INDEX_2, VGA_READ_MAP_SELECT); + graphics_mode = read_index_reg(VGA_INDEX_2, VGA_GRAPHICS_MODE); + misc_graphics = read_index_reg(VGA_INDEX_2, VGA_MISC_GRAPHICS); + + new_memory_mode = memory_mode | 0x04; + new_memory_mode &= ~0x08; + + // Turn off even-odd addressing (set flat) + write_index_reg(VGA_INDEX_1, VGA_SEQ_MEM_MODE, new_memory_mode); + write_index_reg(VGA_INDEX_2, VGA_GRAPHICS_MODE, (graphics_mode & ~0x10)); + write_index_reg(VGA_INDEX_2, VGA_MISC_GRAPHICS, (misc_graphics & ~0x02)); + + // Set plane to P4 + set_plane(2); + + // write Font 0 (Standard) + for(i = 0; i < 256; i++) + { + memcpy(framebuffer_base + (i * 32), buf, height); + buf += height; + } + + // Restore State of things modified. + write_index_reg(VGA_INDEX_1, VGA_MAP_MASK, map_mask); + write_index_reg(VGA_INDEX_1, VGA_SEQ_MEM_MODE, memory_mode); + write_index_reg(VGA_INDEX_2, VGA_READ_MAP_SELECT, read_map_sel); + write_index_reg(VGA_INDEX_2, VGA_GRAPHICS_MODE, graphics_mode); + write_index_reg(VGA_INDEX_2, VGA_MISC_GRAPHICS, misc_graphics); +} + +static void set_8_tall_font() +{ + uint8_t config_data; + + // Set char height to 8 tall + config_data = read_index_reg(VGA_INDEX_3, VGA_MAX_SCAN_LINE); + config_data &= 0xE0; + config_data += 7; + write_index_reg(VGA_INDEX_3, VGA_MAX_SCAN_LINE, config_data); + + // Change cursor scanline start / end + write_index_reg(VGA_INDEX_3, VGA_CURSOR_START, 0x06); + write_index_reg(VGA_INDEX_3, VGA_CURSOR_END, 0x07); + + // Write the 8x8 font to VGA memory + write_font(&vga_8x8_font[0], 8); +} + +static void set_16_tall_font() +{ + uint8_t config_data; + + // Set char height to 8 tall + config_data = read_index_reg(VGA_INDEX_3, VGA_MAX_SCAN_LINE); + config_data &= 0xE0; + config_data += 15; + write_index_reg(VGA_INDEX_3, VGA_MAX_SCAN_LINE, config_data); + + // Change cursor scanline start / end + write_index_reg(VGA_INDEX_3, VGA_CURSOR_START, 0x13); + write_index_reg(VGA_INDEX_3, VGA_CURSOR_END, 0x14); + + // Write the 8x8 font to VGA memory + write_font(&vga_8x16_font[0], 8); +} + +void vga_set_font(int height) +{ + if(height == 8) + { + set_8_tall_font(); + max_rows = 50; + return; + } + set_16_tall_font(); + max_rows = 25; +} + +uint16_t vga_get_max_rows() { + return max_rows; +} + +void vga_move_cursor(uint16_t cursorX, uint16_t cursorY) +{ + uint16_t cursorLocation = cursorY * 80 + cursorX; + write_index_reg(VGA_INDEX_3, VGA_CURSOR_HIGH_BYTE, cursorLocation >> 8); + write_index_reg(VGA_INDEX_3, VGA_CURSOR_LOW_BYTE, cursorLocation); +} + +/** + * @brief Retrieve the base address of the VGA Frambuffer + * + * Bits 2 and 3 of Misc graphics register are the memory map select + * This can be 0xA0000, 0xB0000, or 0xB8000 Depending on the bits + * @return void* address of the framebuffer's base + */ +void* vga_get_framebuffer_base() +{ + uint8_t map_sel; + uint32_t framebuffer_base; + map_sel = read_index_reg(VGA_INDEX_2, VGA_MISC_GRAPHICS); + // Isolate bits 2 and 3 + map_sel >>= 2; + map_sel &= 3; + + switch(map_sel) + { + case 0: // 128k window, 0xA0000 - 0xBFFFF + case 1: // 64k window, 0xA0000 - 0xAFFFF + framebuffer_base = VGA_BASE_POINTER_1; + break; + case 2: // 32K window, 0xB0000 - 0xB7FFF + framebuffer_base = VGA_BASE_POINTER_2; + break; + case 3: // 32K window, 0xB8000 - 0xBFFFF + framebuffer_base = VGA_BASE_POINTER_3; + break; + } + return (void*)framebuffer_base; +} \ No newline at end of file diff --git a/src/drivers/display/vga_fonts.c b/src/drivers/display/vga_fonts.c new file mode 100644 index 0000000..53b407a --- /dev/null +++ b/src/drivers/display/vga_fonts.c @@ -0,0 +1,521 @@ +#include + +uint8_t vga_8x8_font[2048] = +{ + 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, 0x92, 0x10, 0x7C, + 0x00, 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, 0x86, 0xFC, + 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, + 0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00, + 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x6C, 0x6C, 0xFE, 0x6C, 0xFE, 0x6C, 0x6C, 0x00, + 0x18, 0x7E, 0xC0, 0x7C, 0x06, 0xFC, 0x18, 0x00, + 0x00, 0xC6, 0xCC, 0x18, 0x30, 0x66, 0xC6, 0x00, + 0x38, 0x6C, 0x38, 0x76, 0xDC, 0xCC, 0x76, 0x00, + 0x30, 0x30, 0x60, 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, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, + 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, + 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00, + 0x7C, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 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, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, + 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x30, + 0x18, 0x30, 0x60, 0xC0, 0x60, 0x30, 0x18, 0x00, + 0x00, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00, 0x00, + 0x60, 0x30, 0x18, 0x0C, 0x18, 0x30, 0x60, 0x00, + 0x3C, 0x66, 0x0C, 0x18, 0x18, 0x00, 0x18, 0x00, + 0x7C, 0xC6, 0xDE, 0xDE, 0xDC, 0xC0, 0x7C, 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, 0x3A, 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, + 0x7C, 0xC6, 0xC6, 0xC6, 0xD6, 0x7C, 0x0E, 0x00, + 0xFC, 0x66, 0x66, 0x7C, 0x6C, 0x66, 0xE6, 0x00, + 0x7C, 0xC6, 0xE0, 0x78, 0x0E, 0xC6, 0x7C, 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, 0xC6, 0xD6, 0xFE, 0x6C, 0x00, + 0xC6, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 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, 0x64, 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, 0x1C, 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, 0xD6, 0x00, + 0x00, 0x00, 0xB8, 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, 0x62, 0x60, 0xF0, 0x00, + 0x00, 0x00, 0x7C, 0xC0, 0x70, 0x1C, 0xF8, 0x00, + 0x10, 0x30, 0xFC, 0x30, 0x30, 0x34, 0x18, 0x00, + 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, + 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00, + 0x00, 0x00, 0xC6, 0xC6, 0xD6, 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, + 0x7C, 0xC6, 0xC0, 0xC6, 0x7C, 0x0C, 0x06, 0x7C, + 0x00, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00, + 0x1C, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, + 0x7E, 0x81, 0x3C, 0x06, 0x3E, 0x66, 0x3B, 0x00, + 0xCC, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, + 0xE0, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, + 0x30, 0x30, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, + 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0x78, 0x0C, 0x38, + 0x7E, 0x81, 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, 0x82, 0x38, 0x18, 0x18, 0x18, 0x3C, 0x00, + 0xE0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0xC6, 0x10, 0x7C, 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, 0x84, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, + 0x00, 0xCC, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, + 0x00, 0xE0, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, + 0x78, 0x84, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00, + 0x00, 0xE0, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 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, 0x30, 0xFC, 0x30, 0xFC, 0x30, + 0xF8, 0xCC, 0xCC, 0xFA, 0xC6, 0xCF, 0xC6, 0xC3, + 0x0E, 0x1B, 0x18, 0x3C, 0x18, 0x18, 0xD8, 0x70, + 0x1C, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, + 0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x00, 0x1C, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, + 0x00, 0x1C, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00, + 0x00, 0xF8, 0x00, 0xB8, 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, + 0x18, 0x00, 0x18, 0x18, 0x30, 0x66, 0x3C, 0x00, + 0x00, 0x00, 0x00, 0xFC, 0xC0, 0xC0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xFC, 0x0C, 0x0C, 0x00, 0x00, + 0xC6, 0xCC, 0xD8, 0x36, 0x6B, 0xC2, 0x84, 0x0F, + 0xC3, 0xC6, 0xCC, 0xDB, 0x37, 0x6D, 0xCF, 0x03, + 0x18, 0x00, 0x18, 0x18, 0x3C, 0x3C, 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, 0xF6, 0xDB, 0x6F, 0xDB, 0x7E, 0xD7, 0xED, + 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, 0x00, 0xFE, 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, 0x7E, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00, + 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x7E, 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, + 0x18, 0x18, 0x00, 0x7E, 0x00, 0x18, 0x18, 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, + 0x58, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, + 0x70, 0x98, 0x30, 0x60, 0xF8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +uint8_t vga_8x16_font[4096] = +{ + 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, 0x99, 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, 0x18, 0x7E, 0x3C, 0x18, 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, 0x18, 0x7E, 0x3C, 0x18, 0x7E, 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, 0xC0, 0xC0, 0xC0, 0xC0, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x6C, 0xFE, 0x6C, 0x28, 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, 0x86, 0xC6, 0x7C, 0x18, 0x18, 0x00, 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, 0x7C, 0xC6, 0xC6, 0xCE, 0xD6, 0xD6, 0xE6, 0xC6, 0xC6, 0x7C, 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, 0x0E, 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, 0x00, 0xFE, 0x00, 0x00, 0xFE, 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, 0x6C, 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, 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xC6, 0xE6, 0xF6, 0xFE, 0xDE, 0xCE, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 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, 0x7E, 0x7E, 0x5A, 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, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xD6, 0xD6, 0xFE, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xC6, 0xC6, 0x6C, 0x6C, 0x38, 0x38, 0x6C, 0x6C, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFE, 0xC6, 0x86, 0x0C, 0x18, 0x30, 0x60, 0xC2, 0xC6, 0xFE, 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, 0xDC, 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, 0xEC, 0xFE, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 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, 0x62, 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, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xD6, 0xD6, 0xFE, 0x6C, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0x6C, 0x38, 0x38, 0x38, 0x6C, 0xC6, 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, 0xCC, 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, 0xCC, 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, 0xC6, 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, 0x66, 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, 0xC6, 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, 0xCC, 0x76, 0x36, 0x7E, 0xD8, 0xD8, 0x6E, 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, 0xC6, 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, 0xC6, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x0C, 0x78, 0x00, + 0x00, 0xC6, 0xC6, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xC6, 0xC6, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x18, 0x3C, 0x66, 0x60, 0x60, 0x60, 0x66, 0x3C, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6C, 0x64, 0x60, 0xF0, 0x60, 0x60, 0x60, 0x60, 0xE6, 0xFC, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18, 0x7E, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xF8, 0xCC, 0xCC, 0xF8, 0xC4, 0xCC, 0xDE, 0xCC, 0xCC, 0xCC, 0xC6, 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, 0x93, 0x06, 0x0C, 0x1F, 0x00, 0x00, + 0x00, 0xC0, 0xC0, 0xC2, 0xC6, 0xCC, 0x18, 0x30, 0x66, 0xCE, 0x9A, 0x3F, 0x06, 0x0F, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x3C, 0x3C, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x66, 0xCC, 0x66, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0x66, 0x33, 0x66, 0xCC, 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, 0x00, 0x00, 0x00, 0xFC, 0xC6, 0xFC, 0xC6, 0xC6, 0xFC, 0xC0, 0xC0, 0xC0, 0x00, 0x00, + 0x00, 0x00, 0xFE, 0xC6, 0xC6, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0xFE, 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, 0xCF, 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, 0x98, 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 +}; \ No newline at end of file diff --git a/src/drivers/irqchip/8259_pic.c b/src/drivers/irqchip/8259_pic.c index 26d8c4f..9b02357 100644 --- a/src/drivers/irqchip/8259_pic.c +++ b/src/drivers/irqchip/8259_pic.c @@ -7,7 +7,6 @@ #include #include -#include /** ** Generic PIC driver code diff --git a/src/include/sys/hal.h b/src/include/sys/hal.h index a459b28..ab1a0c5 100644 --- a/src/include/sys/hal.h +++ b/src/include/sys/hal.h @@ -33,9 +33,12 @@ typedef struct spinlock { #define TEST_HARNESS 0 #endif - // hal.h is going to have a lot of functions. +// HAL Version. These should be changed whenever new functionality is added to the HAL +int hal_version_major(); +int hal_version_minor(); + // System Panic and Assert void panic(const char *message) __attribute__((noreturn)); void assert_fail(const char *cond, const char *file, int line)__attribute__((noreturn)); @@ -195,7 +198,7 @@ int describe_regs(struct regs *regs, int max, const char **names, // Returns -1 if not implemented int get_processor_id(); -// Returns -1 if not implemented +// Returns 1 if not implemented int get_num_processors(); // Returns pointer to array of all Processor ID's