diff --git a/GNUmakefile b/GNUmakefile index d63a681..5064596 100755 --- a/GNUmakefile +++ b/GNUmakefile @@ -266,3 +266,8 @@ clean: distclean: $(MAKE) -C kernel distclean rm -rf iso_root *.iso *.hdd kernel-deps limine ovmf + +# Make some function to run clang-format all over the kernel +.PHONY: format +format: + clang-format -i -style=file $(shell find kernel/src -name '*.c' -or -name '*.h') \ No newline at end of file diff --git a/compile_commands.json b/compile_commands.json old mode 100755 new mode 100644 index f556a44..cf2888f --- a/compile_commands.json +++ b/compile_commands.json @@ -33,8 +33,46 @@ "obj-x86_64/main.c.o", "src/main.c" ], - "directory": "/home/raphm/Projets/sild/kernel", - "file": "/home/raphm/Projets/sild/kernel/src/main.c", - "output": "/home/raphm/Projets/sild/kernel/obj-x86_64/main.c.o" + "directory": "/home/raphm/Projets/sild/soaplin/kernel", + "file": "/home/raphm/Projets/sild/soaplin/kernel/src/main.c", + "output": "/home/raphm/Projets/sild/soaplin/kernel/obj-x86_64/main.c.o" + }, + { + "arguments": [ + "/usr/bin/cc", + "-g", + "-O2", + "-pipe", + "-Wall", + "-Wextra", + "-std=gnu11", + "-nostdinc", + "-ffreestanding", + "-fno-stack-protector", + "-fno-stack-check", + "-fno-PIC", + "-ffunction-sections", + "-fdata-sections", + "-m64", + "-march=x86-64", + "-mno-80387", + "-mno-mmx", + "-mno-sse", + "-mno-sse2", + "-mno-red-zone", + "-mcmodel=kernel", + "-I", + "src", + "-isystem", + "freestnd-c-hdrs", + "-DLIMINE_API_REVISION=3", + "-c", + "-o", + "obj-x86_64/mm/vmm.c.o", + "src/mm/vmm.c" + ], + "directory": "/home/raphm/Projets/sild/soaplin/kernel", + "file": "/home/raphm/Projets/sild/soaplin/kernel/src/mm/vmm.c", + "output": "/home/raphm/Projets/sild/soaplin/kernel/obj-x86_64/mm/vmm.c.o" } ] diff --git a/kernel/src/exec/elf.c b/kernel/src/exec/elf.c index 24d9e5d..5cd8d9c 100644 --- a/kernel/src/exec/elf.c +++ b/kernel/src/exec/elf.c @@ -2,125 +2,126 @@ #include "mm/memop.h" #include "mm/pmm.h" #include "mm/vmm.h" -#include #include +#include #include #include -program_t *elf_load(char *data) { - Elf64_Ehdr *ehdr = (Elf64_Ehdr*)data; - if ( ehdr->e_ident[EI_MAG0] != ELFMAG0 - || ehdr->e_ident[EI_MAG1] != ELFMAG1 - || ehdr->e_ident[EI_MAG2] != ELFMAG2 - || ehdr->e_ident[EI_MAG3] != ELFMAG3) - { - log("elf - loading failed: magic is incorrect\n"); - return NULL; - } +program_t *elf_load(char *data, int user) { + Elf64_Ehdr *ehdr = (Elf64_Ehdr *)data; + if (ehdr->e_ident[EI_MAG0] != ELFMAG0 || ehdr->e_ident[EI_MAG1] != ELFMAG1 || + ehdr->e_ident[EI_MAG2] != ELFMAG2 || ehdr->e_ident[EI_MAG3] != ELFMAG3) { + log("elf - loading failed: magic is incorrect\n"); + return NULL; + } - log("elf - e_ident[EI_DATA]: %d\n", ehdr->e_ident[EI_DATA]); - log("elf - e_ident[EI_CLASS]: %d\n", ehdr->e_ident[EI_CLASS]); - log("elf - e_ident[EI_OSABI]: %d\n", ehdr->e_ident[EI_OSABI]); - log("elf - e_machine: %d\n", ehdr->e_machine); - log("elf - e_entry: %p\n", ehdr->e_entry); - log("elf - e_type: %p\n", ehdr->e_type); - log("elf - e_phnum: %p\n", ehdr->e_phnum); + log("elf - e_ident[EI_DATA]: %d\n", ehdr->e_ident[EI_DATA]); + log("elf - e_ident[EI_CLASS]: %d\n", ehdr->e_ident[EI_CLASS]); + log("elf - e_ident[EI_OSABI]: %d\n", ehdr->e_ident[EI_OSABI]); + log("elf - e_machine: %d\n", ehdr->e_machine); + log("elf - e_entry: %p\n", ehdr->e_entry); + log("elf - e_type: %p\n", ehdr->e_type); + log("elf - e_phnum: %p\n", ehdr->e_phnum); - if ( ehdr->e_ident[EI_CLASS] != ELFCLASS64 - || ehdr->e_machine != EM_X86_64) - { - log("elf - loading failed: is the file built for amd64?\n"); - return NULL; - } + if (ehdr->e_ident[EI_CLASS] != ELFCLASS64 || ehdr->e_machine != EM_X86_64) { + log("elf - loading failed: is the file built for amd64?\n"); + return NULL; + } - if (ehdr->e_type != ET_EXEC) - { - log("elf - loading failed: ELF type isn't ET_EXEC\n"); - return NULL; - } + if (ehdr->e_type != ET_EXEC) { + log("elf - loading failed: ELF type isn't ET_EXEC\n"); + return NULL; + } - // There's the interesing part - elf_program_t *ret = malloc(sizeof(elf_program_t)); // Allocate memory for the program. + // There's the interesing part + elf_program_t *ret = + malloc(sizeof(elf_program_t)); // Allocate memory for the program. - pagemap_t *pm = vmm_alloc_pm(); // Allocate a pagemap, so that we can map the program inside. - ret->program.pm = pm; - ret->program.entry = ehdr->e_entry; - ret->ehdr = ehdr; + pagemap_t *pm = vmm_alloc_pm(); // Allocate a pagemap, so that we can map the + // program inside. + ret->program.pm = pm; + ret->program.entry = ehdr->e_entry; + ret->ehdr = ehdr; - Elf64_Phdr *phdr = (Elf64_Phdr *)((uint8_t *)data + ehdr->e_phoff); + Elf64_Phdr *phdr = (Elf64_Phdr *)((uint8_t *)data + ehdr->e_phoff); - for (uint16_t i = 0; i <= ehdr->e_phnum; i++) - { - log("elf - ELF segment type: %d\n", phdr[i].p_type); - if (phdr[i].p_type != PT_LOAD) - continue; + for (uint16_t i = 0; i < ehdr->e_phnum; i++) { + log("elf - ELF segment type: %d\n", phdr[i].p_type); + if (phdr[i].p_type != PT_LOAD) + continue; - uint64_t vaddr_start = ALIGN_DOWN(phdr[i].p_vaddr, PMM_PAGE_SIZE); - uint64_t vaddr_end = ALIGN_UP(phdr[i].p_vaddr + phdr[i].p_memsz, PMM_PAGE_SIZE); - uint64_t offset = phdr[i].p_offset; + uint64_t vaddr_start = ALIGN_DOWN(phdr[i].p_vaddr, PMM_PAGE_SIZE); + uint64_t vaddr_end = + ALIGN_UP(phdr[i].p_vaddr + phdr[i].p_memsz, PMM_PAGE_SIZE); + uint64_t offset = phdr[i].p_offset; - uint64_t flags = VMM_PRESENT; - //if (phdr[i].p_flags & PF_W) - flags |= VMM_WRITABLE; - //if (!(phdr[i].p_flags & PF_X)) - // flags |= VMM_NX; + uint64_t flags = VMM_PRESENT; + if (phdr[i].p_flags & PF_W) + flags |= VMM_WRITABLE; + if (!(phdr[i].p_flags & PF_X)) + flags |= VMM_NX; - flags |= VMM_USER; + if (user) + flags |= VMM_USER; - log("elf - loading ELF program header %u: vaddr 0x%llx - 0x%llx, offset 0x%llx, filesz 0x%llx, size 0x%llx, flags 0x%llx\n", - i, vaddr_start, vaddr_end, offset, phdr[i].p_filesz, phdr[i].p_memsz, flags); + log("elf - loading ELF program header %u: vaddr 0x%llx - 0x%llx, offset " + "0x%llx, filesz 0x%llx, size 0x%llx, flags 0x%llx\n", + i, vaddr_start, vaddr_end, offset, phdr[i].p_filesz, phdr[i].p_memsz, + flags); - uint64_t page_offset = phdr[i].p_vaddr & (PMM_PAGE_SIZE - 1); + uint64_t page_offset = phdr[i].p_vaddr & (PMM_PAGE_SIZE - 1); - for (uint64_t vaddr = vaddr_start; vaddr < vaddr_end; vaddr += PMM_PAGE_SIZE) - { - uint64_t phys = (uint64_t)pmm_request_page(); - if (!phys) - { - log("elf - pmm page alloc failed. out of memory?\n"); - return 0; - } + for (uint64_t vaddr = vaddr_start; vaddr < vaddr_end; + vaddr += PMM_PAGE_SIZE) { + uint64_t phys = (uint64_t)pmm_request_page(); + if (!phys) { + log("elf - pmm page alloc failed. out of memory?\n"); + return 0; + } - log("elf - vmm_map(%p, %p, %p, %d)\n", pm, vaddr, phys, flags); - vmm_map(pm, vaddr, phys, flags); - log("elf - memset(%p, 0, 0x1000)\n", HIGHER_HALF(phys)); - memset((void *)HIGHER_HALF(phys), 0, PMM_PAGE_SIZE); + if (user) { + log("elf - vmm_map_user(%p, %p, %p, %d)\n", pm, vaddr, phys, flags); + vmm_map_user(pm, vaddr, phys, flags); + } else { + log("elf - vmm_map(%p, %p, %p, %d)\n", pm, vaddr, phys, flags); + vmm_map(pm, vaddr, phys, flags); + } + log("elf - memset(%p, 0, 0x1000)\n", HIGHER_HALF(phys)); + memset((void *)HIGHER_HALF(phys), 0, PMM_PAGE_SIZE); - uint64_t file_page_offset = offset + (vaddr - vaddr_start); - uint64_t file_data_end = offset + phdr[i].p_filesz; + uint64_t file_page_offset = offset + (vaddr - vaddr_start); + uint64_t file_data_end = offset + phdr[i].p_filesz; - if (file_page_offset < file_data_end) - { - uint64_t bytes_from_start = vaddr - vaddr_start; - uint64_t page_data_offset = 0; + if (file_page_offset < file_data_end) { + uint64_t bytes_from_start = vaddr - vaddr_start; + uint64_t page_data_offset = 0; - if (bytes_from_start == 0 && page_offset > 0) - { - page_data_offset = page_offset; - } - - uint64_t copy_offset = file_page_offset; - uint64_t copy_size = PMM_PAGE_SIZE - page_data_offset; - - if (copy_offset + copy_size > file_data_end) - { - copy_size = file_data_end - copy_offset; - } - - if (copy_size > 0) - { - void *dest = (void *)(HIGHER_HALF(phys) + page_data_offset); - void *src = (uint8_t *)data + copy_offset; - log("elf - memcpy(%p, %p, %d)\n", dest, src, copy_size); - memcpy(dest, src, copy_size); - - //log("elf - copied 0x%llx bytes from ELF file offset 0x%llx to vaddr 0x%llx (phys 0x%llx)\n", - // copy_size, copy_offset, vaddr + page_data_offset, phys + page_data_offset); - } - } + if (bytes_from_start == 0 && page_offset > 0) { + page_data_offset = page_offset; } - } - log("elf - loaded ELF program in memory.\n"); - return (program_t*)ret; + uint64_t copy_offset = file_page_offset; + uint64_t copy_size = PMM_PAGE_SIZE - page_data_offset; + + if (copy_offset + copy_size > file_data_end) { + copy_size = file_data_end - copy_offset; + } + + if (copy_size > 0) { + void *dest = (void *)(HIGHER_HALF(phys) + page_data_offset); + void *src = (uint8_t *)data + copy_offset; + log("elf - memcpy(%p, %p, %d)\n", dest, src, copy_size); + memcpy(dest, src, copy_size); + + // log("elf - copied 0x%llx bytes from ELF file offset 0x%llx to vaddr + // 0x%llx (phys 0x%llx)\n", + // copy_size, copy_offset, vaddr + page_data_offset, phys + + // page_data_offset); + } + } + } + } + + log("elf - loaded ELF program in memory.\n"); + return (program_t *)ret; } \ No newline at end of file diff --git a/kernel/src/exec/elf.h b/kernel/src/exec/elf.h index 89e02a5..8180a8e 100644 --- a/kernel/src/exec/elf.h +++ b/kernel/src/exec/elf.h @@ -4,48 +4,48 @@ #include // ELF magic. -#define EI_MAG0 0 -#define ELFMAG0 0x7f +#define EI_MAG0 0 +#define ELFMAG0 0x7f -#define EI_MAG1 1 -#define ELFMAG1 'E' +#define EI_MAG1 1 +#define ELFMAG1 'E' -#define EI_MAG2 2 -#define ELFMAG2 'L' +#define EI_MAG2 2 +#define ELFMAG2 'L' -#define EI_MAG3 3 -#define ELFMAG3 'F' +#define EI_MAG3 3 +#define ELFMAG3 'F' // ELF class -#define EI_CLASS 4 +#define EI_CLASS 4 #define ELFCLASSNONE 0 -#define ELFCLASS32 1 -#define ELFCLASS64 2 +#define ELFCLASS32 1 +#define ELFCLASS64 2 // Is processor-specific data little-endian or big-endian? -#define EI_DATA 5 -#define ELFDATANONE 0 -#define ELFDATA2LSB 1 -#define ELFDATA2MSB 2 +#define EI_DATA 5 +#define ELFDATANONE 0 +#define ELFDATA2LSB 1 +#define ELFDATA2MSB 2 // ELF version -#define EI_VERSION 6 -#define EV_NONE 0 -#define EV_CURRENT 1 +#define EI_VERSION 6 +#define EV_NONE 0 +#define EV_CURRENT 1 // ELF ABI -#define EI_OSABI 7 -#define ELFOSABI_NONE 0 -#define ELFOSABI_SYSV 0 -#define ELFOSABI_HPUX 1 -#define ELFOSABI_NETBSD 2 -#define ELFOSABI_LINUX 3 -#define ELFOSABI_SOLARIS 6 -#define ELFOSABI_IRIX 8 -#define ELFOSABI_FREEBSD 9 -#define ELFOSABI_TRU64 10 -#define ELFOSABI_ARM 97 -#define ELFOSABI_STANDALONE 255 +#define EI_OSABI 7 +#define ELFOSABI_NONE 0 +#define ELFOSABI_SYSV 0 +#define ELFOSABI_HPUX 1 +#define ELFOSABI_NETBSD 2 +#define ELFOSABI_LINUX 3 +#define ELFOSABI_SOLARIS 6 +#define ELFOSABI_IRIX 8 +#define ELFOSABI_FREEBSD 9 +#define ELFOSABI_TRU64 10 +#define ELFOSABI_ARM 97 +#define ELFOSABI_STANDALONE 255 // ABI version #define EI_ABIVERSION 8 @@ -57,69 +57,69 @@ #define EI_NIDENT 16 // e_type -#define ET_NONE 0 -#define ET_REL 1 -#define ET_EXEC 2 -#define ET_DYN 3 -#define ET_CORE 4 +#define ET_NONE 0 +#define ET_REL 1 +#define ET_EXEC 2 +#define ET_DYN 3 +#define ET_CORE 4 // e_machine (we only included machines supported by Soaplin.) -#define EM_X86_64 62 +#define EM_X86_64 62 typedef uint64_t Elf64_Addr; typedef uint64_t Elf64_Off; typedef uint16_t Elf64_Section; typedef uint16_t Elf64_Versym; typedef uint8_t Elf_Byte; -typedef uint16_t Elf64_Half; -typedef int32_t Elf64_Sword; -typedef uint32_t Elf64_Word; -typedef int64_t Elf64_Sxword; +typedef uint16_t Elf64_Half; +typedef int32_t Elf64_Sword; +typedef uint32_t Elf64_Word; +typedef int64_t Elf64_Sxword; typedef uint64_t Elf64_Xword; typedef struct { - unsigned char e_ident[EI_NIDENT]; - uint16_t e_type; - uint16_t e_machine; - uint32_t e_version; - Elf64_Addr e_entry; - Elf64_Off e_phoff; - Elf64_Off e_shoff; - uint32_t e_flags; - uint16_t e_ehsize; - uint16_t e_phentsize; - uint16_t e_phnum; - uint16_t e_shentsize; - uint16_t e_shnum; - uint16_t e_shstrndx; + unsigned char e_ident[EI_NIDENT]; + uint16_t e_type; + uint16_t e_machine; + uint32_t e_version; + Elf64_Addr e_entry; + Elf64_Off e_phoff; + Elf64_Off e_shoff; + uint32_t e_flags; + uint16_t e_ehsize; + uint16_t e_phentsize; + uint16_t e_phnum; + uint16_t e_shentsize; + uint16_t e_shnum; + uint16_t e_shstrndx; } Elf64_Ehdr; -#define PT_NULL 0 -#define PT_LOAD 1 -#define PT_DYNAMIC 2 -#define PT_INTERP 3 -#define PT_NOTE 4 -#define PT_SHLIB 5 +#define PT_NULL 0 +#define PT_LOAD 1 +#define PT_DYNAMIC 2 +#define PT_INTERP 3 +#define PT_NOTE 4 +#define PT_SHLIB 5 -#define PF_X (1 << 0) -#define PF_W (1 << 1) -#define PF_R (1 << 2) +#define PF_X (1 << 0) +#define PF_W (1 << 1) +#define PF_R (1 << 2) typedef struct { - uint32_t p_type; - uint32_t p_flags; - Elf64_Off p_offset; - Elf64_Addr p_vaddr; - Elf64_Addr p_paddr; - uint64_t p_filesz; - uint64_t p_memsz; - uint64_t p_align; + uint32_t p_type; + uint32_t p_flags; + Elf64_Off p_offset; + Elf64_Addr p_vaddr; + Elf64_Addr p_paddr; + uint64_t p_filesz; + uint64_t p_memsz; + uint64_t p_align; } Elf64_Phdr; typedef struct { - program_t program; + program_t program; - Elf64_Ehdr *ehdr; + Elf64_Ehdr *ehdr; } elf_program_t; -program_t *elf_load(char *data); \ No newline at end of file +program_t *elf_load(char *data, int user); \ No newline at end of file diff --git a/kernel/src/exec/exec.h b/kernel/src/exec/exec.h index f0bb547..2ac1776 100644 --- a/kernel/src/exec/exec.h +++ b/kernel/src/exec/exec.h @@ -8,18 +8,21 @@ #define EXEC_TYPE_ELF 0 typedef struct { - // The path to the program/script that will be executed. - char *path; + // The path to the program/script that will be executed. + char *path; - // The pagemap where the program's code is loaded. - pagemap_t *pm; + // The pagemap where the program's code is loaded. + pagemap_t *pm; - // The path to the first instruction. This will be passed to the new process's rip register. - uint64_t entry; + // The path to the first instruction. This will be passed to the new process's + // rip register. + uint64_t entry; - // The program type. Used to get additional, unneeded information out of a program - int type; + // The program type. Used to get additional, unneeded information out of a + // program + int type; - // That is what Soaplin needs to know. Executable file loaders are encouraged to extend this structure - // to include info such as the EHDR for the ELF loader... + // That is what Soaplin needs to know. Executable file loaders are encouraged + // to extend this structure to include info such as the EHDR for the ELF + // loader... } program_t; \ No newline at end of file diff --git a/kernel/src/font.c b/kernel/src/font.c index 801878d..0c8c3ba 100644 --- a/kernel/src/font.c +++ b/kernel/src/font.c @@ -1,258 +1,343 @@ -unsigned char VGA8[] = { - 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, 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, 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, 0x38, 0x6c, 0xc6, 0xc6, 0xd6, 0xd6, 0xc6, 0xc6, 0x6c, 0x38, 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, 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, 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, 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, 0xd6, 0xd6, 0xd6, 0xfe, 0xee, 0x6c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x7c, 0x38, 0x38, 0x7c, 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, 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, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xd6, 0xc6, 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, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xd6, 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, 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, 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, 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, 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, 0xdc, 0x86, 0x0c, 0x18, 0x3e, 0x00, 0x00, - 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xce, 0x9e, 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 - }; \ No newline at end of file +unsigned char VGA8[] = { + 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, 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, 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, 0x38, 0x6c, 0xc6, 0xc6, 0xd6, 0xd6, 0xc6, 0xc6, 0x6c, 0x38, + 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, 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, 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, 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, 0xd6, 0xd6, 0xd6, 0xfe, 0xee, 0x6c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x7c, 0x38, 0x38, + 0x7c, 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, 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, 0xec, 0xfe, 0xd6, + 0xd6, 0xd6, 0xd6, 0xc6, 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, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc6, 0xc6, 0xd6, 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, 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, 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, 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, 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, 0xdc, 0x86, 0x0c, + 0x18, 0x3e, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, + 0x66, 0xce, 0x9e, 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}; \ No newline at end of file diff --git a/kernel/src/fs/vfs.h b/kernel/src/fs/vfs.h index 300f42d..bbaa364 100644 --- a/kernel/src/fs/vfs.h +++ b/kernel/src/fs/vfs.h @@ -5,24 +5,24 @@ #include #define VNODE_TYPE_FILE 0 -#define VNODE_TYPE_DIR 1 -#define VNODE_TYPE_DEV 2 +#define VNODE_TYPE_DIR 1 +#define VNODE_TYPE_DEV 2 typedef struct __vnode { - char name[128]; - int type; + char name[128]; + int type; - struct __vnode *children; - struct __vnode *next; - struct __vnode *parent; + struct __vnode *children; + struct __vnode *next; + struct __vnode *parent; - void(*write)(void *buffer, uint64_t off, uint64_t size); - void(*read)(void *buffer, uint64_t off, uint64_t size); + void (*write)(void *buffer, uint64_t off, uint64_t size); + void (*read)(void *buffer, uint64_t off, uint64_t size); } vnode; typedef struct __vfs_mount { - struct vfs_node *mount_point; // The directory in the main VFS where this is mounted - struct vfs_node *mounted_root; // The root node of the mounted filesystem - struct vfs_mount *next; // Pointer to next mount point + struct vfs_node + *mount_point; // The directory in the main VFS where this is mounted + struct vfs_node *mounted_root; // The root node of the mounted filesystem + struct vfs_mount *next; // Pointer to next mount point } vfs_mount; - diff --git a/kernel/src/lib/spinlock.h b/kernel/src/lib/spinlock.h index c94de1d..894ff5b 100644 --- a/kernel/src/lib/spinlock.h +++ b/kernel/src/lib/spinlock.h @@ -2,17 +2,16 @@ #include -typedef struct spinlock -{ - volatile int locked; +typedef struct spinlock { + volatile int locked; } spinlock_t; inline void spinlock_acquire(spinlock_t *lock) { - while (__sync_lock_test_and_set(&(lock)->locked, 1)) - while ((lock)->locked) - __asm__ volatile("pause"); + while (__sync_lock_test_and_set(&(lock)->locked, 1)) + while ((lock)->locked) + __asm__ volatile("pause"); } inline void spinlock_release(spinlock_t *lock) { - __sync_lock_release(&(lock)->locked); + __sync_lock_release(&(lock)->locked); } \ No newline at end of file diff --git a/kernel/src/main.c b/kernel/src/main.c old mode 100755 new mode 100644 index a833e13..9c27252 --- a/kernel/src/main.c +++ b/kernel/src/main.c @@ -1,49 +1,49 @@ #include "exec/elf.h" #include "exec/exec.h" +#include "mm/liballoc/liballoc.h" #include "mm/pmm.h" #include "mm/vma.h" #include "mm/vmm.h" -#include "mm/liballoc/liballoc.h" #include "sched/sched.h" +#include "sys/acpi.h" #include "sys/arch/x86_64/pit.h" #include "sys/arch/x86_64/sse.h" #include "sys/syscall.h" -#include -#include -#include -#include +#include #include -#include +#include +#include +#include +#include #include #include -#include -#include #include -#include +#include +#include +#include // Set the base revision to 3, this is recommended as this is the latest // base revision described by the Limine boot protocol specification. // See specification for further info. -__attribute__((used, section(".limine_requests"))) -static volatile LIMINE_BASE_REVISION(3); +__attribute__(( + used, section(".limine_requests"))) static volatile LIMINE_BASE_REVISION(3); // The Limine requests can be placed anywhere, but it is important that // the compiler does not optimise them away, so, usually, they should // be made volatile or equivalent, _and_ they should be accessed at least // once or marked as used with the "used" attribute as done here. -__attribute__((used, section(".limine_requests"))) -static volatile struct limine_framebuffer_request framebuffer_request = { - .id = LIMINE_FRAMEBUFFER_REQUEST, - .revision = 0 -}; +__attribute__(( + used, + section( + ".limine_requests"))) static volatile struct limine_framebuffer_request + framebuffer_request = {.id = LIMINE_FRAMEBUFFER_REQUEST, .revision = 0}; -__attribute__((used, section(".limine_requests"))) -static volatile struct limine_module_request module_request = { - .id = LIMINE_MODULE_REQUEST, - .revision = 0 -}; +__attribute__(( + used, + section(".limine_requests"))) static volatile struct limine_module_request + module_request = {.id = LIMINE_MODULE_REQUEST, .revision = 0}; /*__attribute__((used, section(".limine_requests"))) static volatile struct limine_entry_point_request entrypoint_request = { @@ -53,24 +53,26 @@ static volatile struct limine_entry_point_request entrypoint_request = { // Finally, define the start and end markers for the Limine requests. // These can also be moved anywhere, to any .c file, as seen fit. -__attribute__((used, section(".limine_requests_start"))) -static volatile LIMINE_REQUESTS_START_MARKER; - -__attribute__((used, section(".limine_requests_end"))) -static volatile LIMINE_REQUESTS_END_MARKER; +__attribute__((used, + section(".limine_requests_" + "start"))) static volatile LIMINE_REQUESTS_START_MARKER; +__attribute__(( + used, + section( + ".limine_requests_end"))) static volatile LIMINE_REQUESTS_END_MARKER; // Halt and catch fire function. static void hcf(void) { - for (;;) { -#if defined (__x86_64__) - asm ("hlt"); -#elif defined (__aarch64__) || defined (__riscv) - asm ("wfi"); -#elif defined (__loongarch64) - asm ("idle 0"); + for (;;) { +#if defined(__x86_64__) + asm("hlt"); +#elif defined(__aarch64__) || defined(__riscv) + asm("wfi"); +#elif defined(__loongarch64) + asm("idle 0"); #endif - } + } } struct limine_framebuffer *fb; @@ -83,66 +85,61 @@ char kstack[8192]; // If renaming kmain() to something else, make sure to change the // linker script accordingly. void kmain(void) { - // Ensure the bootloader actually understands our base revision (see spec). - /*if (LIMINE_BASE_REVISION_SUPPORTED == false) { - hcf(); - }*/ + // Ensure the bootloader actually understands our base revision (see spec). + /*if (LIMINE_BASE_REVISION_SUPPORTED == false) { + hcf(); + }*/ - // Ensure we got a framebuffer. - if (framebuffer_request.response != NULL) { - - // Fetch the first framebuffer. - struct limine_framebuffer *framebuffer = framebuffer_request.response->framebuffers[0]; - fb = framebuffer; + // Ensure we got a framebuffer. + if (framebuffer_request.response != NULL) { - ft_ctx = flanterm_fb_init( - NULL, - NULL, - framebuffer->address, framebuffer->width, framebuffer->height, framebuffer->pitch, - framebuffer->red_mask_size, framebuffer->red_mask_shift, - framebuffer->green_mask_size, framebuffer->green_mask_shift, - framebuffer->blue_mask_size, framebuffer->blue_mask_shift, - NULL, - NULL, NULL, - NULL, &fg, - NULL, NULL, - VGA8, 8, 16, 0, - 0, 0, - 0 - ); - } + // Fetch the first framebuffer. + struct limine_framebuffer *framebuffer = + framebuffer_request.response->framebuffers[0]; + fb = framebuffer; - printf("\n Soaplin 1.0-sild is booting up your computer...\n\n"); - //printf("Physical kernel EP: %p", entrypoint_request.entry); - - gdt_init(&kstack[8192]); - idt_init(); - fpu_activate(); - sse_init(); + ft_ctx = flanterm_fb_init( + NULL, NULL, framebuffer->address, framebuffer->width, + framebuffer->height, framebuffer->pitch, framebuffer->red_mask_size, + framebuffer->red_mask_shift, framebuffer->green_mask_size, + framebuffer->green_mask_shift, framebuffer->blue_mask_size, + framebuffer->blue_mask_shift, NULL, NULL, NULL, NULL, &fg, NULL, NULL, + VGA8, 8, 16, 0, 0, 0, 0); + } - pmm_init(); - vmm_init(); - kernel_vma_context = vma_create_context(vmm_kernel_pm); - if (!kernel_vma_context) { - log("kernel - vma ctx creation failed. halting\n"); - asm("cli"); - while (1) - asm("hlt"); - } + printf("\n Soaplin 1.0-sild is booting up your computer...\n\n"); + // printf("Physical kernel EP: %p", entrypoint_request.entry); - syscall_init(); - pit_init(1000); - sched_init(); - //user_init(); + gdt_init(&kstack[8192]); + idt_init(); + fpu_activate(); + sse_init(); - struct limine_file *f = module_request.response->modules[0]; - log("kmain - %s\n", f->path); - - program_t *prog = elf_load((char*)f->address); - - sched_create("Init", prog->entry, prog->pm, SCHED_USER_PROCESS); - - log("kernel - Soaplin initialized sucessfully.\n"); + pmm_init(); + vmm_init(); + kernel_vma_context = vma_create_context(vmm_kernel_pm); + if (!kernel_vma_context) { + log("kernel - vma ctx creation failed. halting\n"); + asm("cli"); while (1) - ;;//__asm__ volatile ("hlt"); + asm("hlt"); + } + + // acpi_init(); + syscall_init(); + pit_init(1000); + sched_init(); + // user_init(); + + struct limine_file *f = module_request.response->modules[0]; + log("kmain - %s\n", f->path); + + program_t *prog = elf_load((char *)f->address, 1); + + sched_create("Init", prog->entry, prog->pm, SCHED_USER_PROCESS); + + log("kernel - Soaplin initialized sucessfully.\n"); + while (1) + ; + ; //__asm__ volatile ("hlt"); } diff --git a/kernel/src/mm/liballoc/liballoc.c b/kernel/src/mm/liballoc/liballoc.c index 567196f..00d961a 100644 --- a/kernel/src/mm/liballoc/liballoc.c +++ b/kernel/src/mm/liballoc/liballoc.c @@ -16,52 +16,45 @@ #define USE_CASE4 #define USE_CASE5 -#define ALIGN(ptr) \ - if (ALIGNMENT > 1) \ - { \ - uintptr_t diff; \ - ptr = (void *)((uintptr_t)ptr + ALIGN_INFO); \ - diff = (uintptr_t)ptr & (ALIGNMENT - 1); \ - if (diff != 0) \ - { \ - diff = ALIGNMENT - diff; \ - ptr = (void *)((uintptr_t)ptr + diff); \ - } \ - *((ALIGN_TYPE *)((uintptr_t)ptr - ALIGN_INFO)) = \ - diff + ALIGN_INFO; \ - } +#define ALIGN(ptr) \ + if (ALIGNMENT > 1) { \ + uintptr_t diff; \ + ptr = (void *)((uintptr_t)ptr + ALIGN_INFO); \ + diff = (uintptr_t)ptr & (ALIGNMENT - 1); \ + if (diff != 0) { \ + diff = ALIGNMENT - diff; \ + ptr = (void *)((uintptr_t)ptr + diff); \ + } \ + *((ALIGN_TYPE *)((uintptr_t)ptr - ALIGN_INFO)) = diff + ALIGN_INFO; \ + } -#define UNALIGN(ptr) \ - if (ALIGNMENT > 1) \ - { \ - uintptr_t diff = *((ALIGN_TYPE *)((uintptr_t)ptr - ALIGN_INFO)); \ - if (diff < (ALIGNMENT + ALIGN_INFO)) \ - { \ - ptr = (void *)((uintptr_t)ptr - diff); \ - } \ - } +#define UNALIGN(ptr) \ + if (ALIGNMENT > 1) { \ + uintptr_t diff = *((ALIGN_TYPE *)((uintptr_t)ptr - ALIGN_INFO)); \ + if (diff < (ALIGNMENT + ALIGN_INFO)) { \ + ptr = (void *)((uintptr_t)ptr - diff); \ + } \ + } #define LIBALLOC_MAGIC 0xc001c0de #define LIBALLOC_DEAD 0xdeaddead -struct liballoc_major -{ - struct liballoc_major *prev; - struct liballoc_major *next; - unsigned int pages; - unsigned int size; - unsigned int usage; - struct liballoc_minor *first; +struct liballoc_major { + struct liballoc_major *prev; + struct liballoc_major *next; + unsigned int pages; + unsigned int size; + unsigned int usage; + struct liballoc_minor *first; }; -struct liballoc_minor -{ - struct liballoc_minor *prev; - struct liballoc_minor *next; - struct liballoc_major *block; - unsigned int magic; - unsigned int size; - unsigned int req_size; +struct liballoc_minor { + struct liballoc_minor *prev; + struct liballoc_minor *next; + struct liballoc_major *block; + unsigned int magic; + unsigned int size; + unsigned int req_size; }; static struct liballoc_major *l_memRoot = NULL; @@ -76,577 +69,518 @@ static long long l_warningCount = 0; static long long l_errorCount = 0; static long long l_possibleOverruns = 0; -static void *liballoc_memset(void *s, int c, size_t n) -{ - unsigned int i; - for (i = 0; i < n; i++) - ((char *)s)[i] = c; +static void *liballoc_memset(void *s, int c, size_t n) { + unsigned int i; + for (i = 0; i < n; i++) + ((char *)s)[i] = c; - return s; + return s; } -static void *liballoc_memcpy(void *s1, const void *s2, size_t n) -{ - char *cdest; - char *csrc; - unsigned int *ldest = (unsigned int *)s1; - unsigned int *lsrc = (unsigned int *)s2; +static void *liballoc_memcpy(void *s1, const void *s2, size_t n) { + char *cdest; + char *csrc; + unsigned int *ldest = (unsigned int *)s1; + unsigned int *lsrc = (unsigned int *)s2; - while (n >= sizeof(unsigned int)) - { - *ldest++ = *lsrc++; - n -= sizeof(unsigned int); - } + while (n >= sizeof(unsigned int)) { + *ldest++ = *lsrc++; + n -= sizeof(unsigned int); + } - cdest = (char *)ldest; - csrc = (char *)lsrc; + cdest = (char *)ldest; + csrc = (char *)lsrc; - while (n > 0) - { - *cdest++ = *csrc++; - n -= 1; - } + while (n > 0) { + *cdest++ = *csrc++; + n -= 1; + } - return s1; + return s1; } #if _DEBUG -void liballoc_dump() -{ +void liballoc_dump() { #ifdef _DEBUG - struct liballoc_major *maj = l_memRoot; - struct liballoc_minor *min = NULL; + struct liballoc_major *maj = l_memRoot; + struct liballoc_minor *min = NULL; #endif - info("------ Memory data ---------------"); - info("System memory allocated: %i bytes", l_allocated); - info("Memory in used (malloc'ed): %i bytes", l_inuse); - info("Warning count: %i", l_warningCount); - info("Error count: %i", l_errorCount); - info("Possible overruns: %i", l_possibleOverruns); + info("------ Memory data ---------------"); + info("System memory allocated: %i bytes", l_allocated); + info("Memory in used (malloc'ed): %i bytes", l_inuse); + info("Warning count: %i", l_warningCount); + info("Error count: %i", l_errorCount); + info("Possible overruns: %i", l_possibleOverruns); #ifdef _DEBUG - while (maj != NULL) - { - info("%x: total = %i, used = %i", - maj, - maj->size, - maj->usage); + while (maj != NULL) { + info("%x: total = %i, used = %i", maj, maj->size, maj->usage); - min = maj->first; - while (min != NULL) - { - info(" %x: %i bytes", - min, - min->size); - min = min->next; - } - - maj = maj->next; + min = maj->first; + while (min != NULL) { + info(" %x: %i bytes", min, min->size); + min = min->next; } + + maj = maj->next; + } #endif } #else -void liballoc_dump() -{ - return; -} +void liballoc_dump() { return; } #endif -static struct liballoc_major *allocate_new_page(unsigned int size) -{ - unsigned int st; - struct liballoc_major *maj; +static struct liballoc_major *allocate_new_page(unsigned int size) { + unsigned int st; + struct liballoc_major *maj; - st = size + sizeof(struct liballoc_major); - st += sizeof(struct liballoc_minor); + st = size + sizeof(struct liballoc_major); + st += sizeof(struct liballoc_minor); - if ((st % l_pageSize) == 0) - st = st / (l_pageSize); - else - st = st / (l_pageSize) + 1; + if ((st % l_pageSize) == 0) + st = st / (l_pageSize); + else + st = st / (l_pageSize) + 1; - if (st < l_pageCount) - st = l_pageCount; + if (st < l_pageCount) + st = l_pageCount; - maj = (struct liballoc_major *)liballoc_alloc(st); + maj = (struct liballoc_major *)liballoc_alloc(st); - if (maj == NULL) - { - l_warningCount += 1; - log("liballoc - (warning) liballoc_alloc( %i ) return NULL", st); - return NULL; - } + if (maj == NULL) { + l_warningCount += 1; + log("liballoc - (warning) liballoc_alloc( %i ) return NULL", st); + return NULL; + } - maj->prev = NULL; - maj->next = NULL; - maj->pages = st; - maj->size = st * l_pageSize; - maj->usage = sizeof(struct liballoc_major); - maj->first = NULL; + maj->prev = NULL; + maj->next = NULL; + maj->pages = st; + maj->size = st * l_pageSize; + maj->usage = sizeof(struct liballoc_major); + maj->first = NULL; - l_allocated += maj->size; + l_allocated += maj->size; - log("liballoc - Resource allocated %x of %i pages (%i bytes) for %i size.", maj, st, maj->size, size); - log("liballoc - Total memory usage = %i KB", (int)((l_allocated / (1024)))); + log("liballoc - Resource allocated %x of %i pages (%i bytes) for %i size.", + maj, st, maj->size, size); + log("liballoc - Total memory usage = %i KB", (int)((l_allocated / (1024)))); - return maj; + return maj; } -void *PREFIX(malloc)(size_t req_size) -{ - int startedBet = 0; - unsigned long long bestSize = 0; - void *p = NULL; - uintptr_t diff; - struct liballoc_major *maj; - struct liballoc_minor *min; - struct liballoc_minor *new_min; - unsigned long size = req_size; +void *PREFIX(malloc)(size_t req_size) { + int startedBet = 0; + unsigned long long bestSize = 0; + void *p = NULL; + uintptr_t diff; + struct liballoc_major *maj; + struct liballoc_minor *min; + struct liballoc_minor *new_min; + unsigned long size = req_size; - if (ALIGNMENT > 1) - { - size += ALIGNMENT + ALIGN_INFO; + if (ALIGNMENT > 1) { + size += ALIGNMENT + ALIGN_INFO; + } + + liballoc_lock(); + + if (size == 0) { + l_warningCount += 1; + log("liballoc - (warning) alloc( 0 ) called from %x", + __builtin_return_address(0)); + + liballoc_unlock(); + return PREFIX(malloc)(1); + } + + if (l_memRoot == NULL) { + log("liballoc - initialization of liballoc " VERSION ""); + l_memRoot = allocate_new_page(size); + if (l_memRoot == NULL) { + liballoc_unlock(); + log("liballoc - initial l_memRoot initialization failed", p); + return NULL; } - liballoc_lock(); + log("liballoc - set up first memory major %x", l_memRoot); + } - if (size == 0) - { - l_warningCount += 1; - log("liballoc - (warning) alloc( 0 ) called from %x", - __builtin_return_address(0)); + log("liballoc - %x PREFIX(malloc)( %i ): ", __builtin_return_address(0), + size); - liballoc_unlock(); - return PREFIX(malloc)(1); + maj = l_memRoot; + startedBet = 0; + + if (l_bestBet != NULL) { + bestSize = l_bestBet->size - l_bestBet->usage; + + if (bestSize > (size + sizeof(struct liballoc_minor))) { + maj = l_bestBet; + startedBet = 1; } + } - if (l_memRoot == NULL) - { - log("liballoc - initialization of liballoc " VERSION ""); - l_memRoot = allocate_new_page(size); - if (l_memRoot == NULL) - { - liballoc_unlock(); - log("liballoc - initial l_memRoot initialization failed", p); - return NULL; - } + while (maj != NULL) { + diff = maj->size - maj->usage; - log("liballoc - set up first memory major %x", l_memRoot); + if (bestSize < diff) { + + l_bestBet = maj; + bestSize = diff; } - log("liballoc - %x PREFIX(malloc)( %i ): ", - __builtin_return_address(0), - size); - - maj = l_memRoot; - startedBet = 0; - - if (l_bestBet != NULL) - { - bestSize = l_bestBet->size - l_bestBet->usage; - - if (bestSize > (size + sizeof(struct liballoc_minor))) - { - maj = l_bestBet; - startedBet = 1; - } - } - - while (maj != NULL) - { - diff = maj->size - maj->usage; - - if (bestSize < diff) - { - - l_bestBet = maj; - bestSize = diff; - } - #ifdef USE_CASE1 - if (diff < (size + sizeof(struct liballoc_minor))) - { - log("liballoc - (warning) CASE 1: Insufficient space in block %x", maj); + if (diff < (size + sizeof(struct liballoc_minor))) { + log("liballoc - (warning) CASE 1: Insufficient space in block %x", maj); - if (maj->next != NULL) - { - maj = maj->next; - continue; - } + if (maj->next != NULL) { + maj = maj->next; + continue; + } - if (startedBet == 1) - { - maj = l_memRoot; - startedBet = 0; - continue; - } + if (startedBet == 1) { + maj = l_memRoot; + startedBet = 0; + continue; + } - maj->next = allocate_new_page(size); - if (maj->next == NULL) - break; - maj->next->prev = maj; - maj = maj->next; - } + maj->next = allocate_new_page(size); + if (maj->next == NULL) + break; + maj->next->prev = maj; + maj = maj->next; + } #endif #ifdef USE_CASE2 - if (maj->first == NULL) - { - maj->first = (struct liballoc_minor *)((uintptr_t)maj + sizeof(struct liballoc_major)); + if (maj->first == NULL) { + maj->first = (struct liballoc_minor *)((uintptr_t)maj + + sizeof(struct liballoc_major)); - maj->first->magic = LIBALLOC_MAGIC; - maj->first->prev = NULL; - maj->first->next = NULL; - maj->first->block = maj; - maj->first->size = size; - maj->first->req_size = req_size; - maj->usage += size + sizeof(struct liballoc_minor); + maj->first->magic = LIBALLOC_MAGIC; + maj->first->prev = NULL; + maj->first->next = NULL; + maj->first->block = maj; + maj->first->size = size; + maj->first->req_size = req_size; + maj->usage += size + sizeof(struct liballoc_minor); - l_inuse += size; + l_inuse += size; - p = (void *)((uintptr_t)(maj->first) + sizeof(struct liballoc_minor)); + p = (void *)((uintptr_t)(maj->first) + sizeof(struct liballoc_minor)); - ALIGN(p); + ALIGN(p); - log("liballoc - (warning) CASE 2: returning %x", p); - liballoc_unlock(); - return p; - } + log("liballoc - (warning) CASE 2: returning %x", p); + liballoc_unlock(); + return p; + } #endif #ifdef USE_CASE3 - diff = (uintptr_t)(maj->first); - diff -= (uintptr_t)maj; - diff -= sizeof(struct liballoc_major); + diff = (uintptr_t)(maj->first); + diff -= (uintptr_t)maj; + diff -= sizeof(struct liballoc_major); - if (diff >= (size + sizeof(struct liballoc_minor))) - { + if (diff >= (size + sizeof(struct liballoc_minor))) { - maj->first->prev = (struct liballoc_minor *)((uintptr_t)maj + sizeof(struct liballoc_major)); - maj->first->prev->next = maj->first; - maj->first = maj->first->prev; + maj->first->prev = + (struct liballoc_minor *)((uintptr_t)maj + + sizeof(struct liballoc_major)); + maj->first->prev->next = maj->first; + maj->first = maj->first->prev; - maj->first->magic = LIBALLOC_MAGIC; - maj->first->prev = NULL; - maj->first->block = maj; - maj->first->size = size; - maj->first->req_size = req_size; - maj->usage += size + sizeof(struct liballoc_minor); + maj->first->magic = LIBALLOC_MAGIC; + maj->first->prev = NULL; + maj->first->block = maj; + maj->first->size = size; + maj->first->req_size = req_size; + maj->usage += size + sizeof(struct liballoc_minor); - l_inuse += size; + l_inuse += size; - p = (void *)((uintptr_t)(maj->first) + sizeof(struct liballoc_minor)); - ALIGN(p); + p = (void *)((uintptr_t)(maj->first) + sizeof(struct liballoc_minor)); + ALIGN(p); - log("liballoc - (warning) CASE 3: returning %x", p); - liballoc_unlock(); - return p; - } + log("liballoc - (warning) CASE 3: returning %x", p); + liballoc_unlock(); + return p; + } #endif #ifdef USE_CASE4 - min = maj->first; + min = maj->first; - while (min != NULL) - { + while (min != NULL) { - if (min->next == NULL) - { + if (min->next == NULL) { - diff = (uintptr_t)(maj) + maj->size; - diff -= (uintptr_t)min; - diff -= sizeof(struct liballoc_minor); - diff -= min->size; + diff = (uintptr_t)(maj) + maj->size; + diff -= (uintptr_t)min; + diff -= sizeof(struct liballoc_minor); + diff -= min->size; - if (diff >= (size + sizeof(struct liballoc_minor))) - { + if (diff >= (size + sizeof(struct liballoc_minor))) { - min->next = (struct liballoc_minor *)((uintptr_t)min + sizeof(struct liballoc_minor) + min->size); - min->next->prev = min; - min = min->next; - min->next = NULL; - min->magic = LIBALLOC_MAGIC; - min->block = maj; - min->size = size; - min->req_size = req_size; - maj->usage += size + sizeof(struct liballoc_minor); + min->next = (struct liballoc_minor *)((uintptr_t)min + + sizeof(struct liballoc_minor) + + min->size); + min->next->prev = min; + min = min->next; + min->next = NULL; + min->magic = LIBALLOC_MAGIC; + min->block = maj; + min->size = size; + min->req_size = req_size; + maj->usage += size + sizeof(struct liballoc_minor); - l_inuse += size; + l_inuse += size; - p = (void *)((uintptr_t)min + sizeof(struct liballoc_minor)); - ALIGN(p); + p = (void *)((uintptr_t)min + sizeof(struct liballoc_minor)); + ALIGN(p); - log("liballoc - (warning) CASE 4.1: returning %x", p); - liballoc_unlock(); - return p; - } - } - - if (min->next != NULL) - { - - diff = (uintptr_t)(min->next); - diff -= (uintptr_t)min; - diff -= sizeof(struct liballoc_minor); - diff -= min->size; - - if (diff >= (size + sizeof(struct liballoc_minor))) - { - - new_min = (struct liballoc_minor *)((uintptr_t)min + sizeof(struct liballoc_minor) + min->size); - - new_min->magic = LIBALLOC_MAGIC; - new_min->next = min->next; - new_min->prev = min; - new_min->size = size; - new_min->req_size = req_size; - new_min->block = maj; - min->next->prev = new_min; - min->next = new_min; - maj->usage += size + sizeof(struct liballoc_minor); - - l_inuse += size; - - p = (void *)((uintptr_t)new_min + sizeof(struct liballoc_minor)); - ALIGN(p); - - log("liballoc - (warning) CASE 4.2: returning %x", p); - liballoc_unlock(); - return p; - } - } - - min = min->next; + log("liballoc - (warning) CASE 4.1: returning %x", p); + liballoc_unlock(); + return p; } + } + + if (min->next != NULL) { + + diff = (uintptr_t)(min->next); + diff -= (uintptr_t)min; + diff -= sizeof(struct liballoc_minor); + diff -= min->size; + + if (diff >= (size + sizeof(struct liballoc_minor))) { + + new_min = (struct liballoc_minor *)((uintptr_t)min + + sizeof(struct liballoc_minor) + + min->size); + + new_min->magic = LIBALLOC_MAGIC; + new_min->next = min->next; + new_min->prev = min; + new_min->size = size; + new_min->req_size = req_size; + new_min->block = maj; + min->next->prev = new_min; + min->next = new_min; + maj->usage += size + sizeof(struct liballoc_minor); + + l_inuse += size; + + p = (void *)((uintptr_t)new_min + sizeof(struct liballoc_minor)); + ALIGN(p); + + log("liballoc - (warning) CASE 4.2: returning %x", p); + liballoc_unlock(); + return p; + } + } + + min = min->next; + } #endif #ifdef USE_CASE5 - if (maj->next == NULL) - { - log("liballoc - (warning) CASE 5: block full"); + if (maj->next == NULL) { + log("liballoc - (warning) CASE 5: block full"); - if (startedBet == 1) - { - maj = l_memRoot; - startedBet = 0; - continue; - } + if (startedBet == 1) { + maj = l_memRoot; + startedBet = 0; + continue; + } - maj->next = allocate_new_page(size); - if (maj->next == NULL) - break; - maj->next->prev = maj; - } + maj->next = allocate_new_page(size); + if (maj->next == NULL) + break; + maj->next->prev = maj; + } #endif - maj = maj->next; + maj = maj->next; + } + + liballoc_unlock(); + + log("liballoc - (warning) All cases exhausted. No memory available."); + log("liballoc - (warning) PREFIX(malloc)( %i ) returning NULL.", size); + liballoc_dump(); + + return NULL; +} + +void PREFIX(free)(void *ptr) { + struct liballoc_minor *min; + struct liballoc_major *maj; + + if (ptr == NULL) { + l_warningCount += 1; + log("liballoc - (warning) PREFIX(free)( NULL ) called from %x", + __builtin_return_address(0)); + + return; + } + + UNALIGN(ptr); + + liballoc_lock(); + + min = + (struct liballoc_minor *)((uintptr_t)ptr - sizeof(struct liballoc_minor)); + + if (min->magic != LIBALLOC_MAGIC) { + l_errorCount += 1; + + if (((min->magic & 0xFFFFFF) == (LIBALLOC_MAGIC & 0xFFFFFF)) || + ((min->magic & 0xFFFF) == (LIBALLOC_MAGIC & 0xFFFF)) || + ((min->magic & 0xFF) == (LIBALLOC_MAGIC & 0xFF))) { + l_possibleOverruns += 1; + log("liballoc - (warning) Possible 1-3 byte overrun for magic %x != %x", + min->magic, LIBALLOC_MAGIC); + } + + if (min->magic == LIBALLOC_DEAD) { + log("liballoc - multiple PREFIX(free)() attempt on %x from %x.", ptr, + __builtin_return_address(0)); + } else { + log("liballoc - Bad PREFIX(free)( %x ) called from %x", ptr, + __builtin_return_address(0)); } liballoc_unlock(); + return; + } - log("liballoc - (warning) All cases exhausted. No memory available."); - log("liballoc - (warning) PREFIX(malloc)( %i ) returning NULL.", size); - liballoc_dump(); + log("liballoc - %x PREFIX(free)( %x ): ", __builtin_return_address(0), ptr); - return NULL; + maj = min->block; + + l_inuse -= min->size; + + maj->usage -= (min->size + sizeof(struct liballoc_minor)); + min->magic = LIBALLOC_DEAD; + + if (min->next != NULL) + min->next->prev = min->prev; + if (min->prev != NULL) + min->prev->next = min->next; + + if (min->prev == NULL) + maj->first = min->next; + + if (maj->first == NULL) { + if (l_memRoot == maj) + l_memRoot = maj->next; + if (l_bestBet == maj) + l_bestBet = NULL; + if (maj->prev != NULL) + maj->prev->next = maj->next; + if (maj->next != NULL) + maj->next->prev = maj->prev; + l_allocated -= maj->size; + + liballoc_free(maj, maj->pages); + } else { + if (l_bestBet != NULL) { + int bestSize = l_bestBet->size - l_bestBet->usage; + int majSize = maj->size - maj->usage; + + if (majSize > bestSize) + l_bestBet = maj; + } + } + + log("liballoc - (warning) OK"); + + liballoc_unlock(); } -void PREFIX(free)(void *ptr) -{ - struct liballoc_minor *min; - struct liballoc_major *maj; +void *PREFIX(calloc)(size_t nobj, size_t size) { + int real_size; + void *p; - if (ptr == NULL) - { - l_warningCount += 1; - log("liballoc - (warning) PREFIX(free)( NULL ) called from %x", - __builtin_return_address(0)); + real_size = nobj * size; - return; - } + p = PREFIX(malloc)(real_size); - UNALIGN(ptr); + liballoc_memset(p, 0, real_size); - liballoc_lock(); - - min = (struct liballoc_minor *)((uintptr_t)ptr - sizeof(struct liballoc_minor)); - - if (min->magic != LIBALLOC_MAGIC) - { - l_errorCount += 1; - - if ( - ((min->magic & 0xFFFFFF) == (LIBALLOC_MAGIC & 0xFFFFFF)) || - ((min->magic & 0xFFFF) == (LIBALLOC_MAGIC & 0xFFFF)) || - ((min->magic & 0xFF) == (LIBALLOC_MAGIC & 0xFF))) - { - l_possibleOverruns += 1; - log("liballoc - (warning) Possible 1-3 byte overrun for magic %x != %x", - min->magic, - LIBALLOC_MAGIC); - } - - if (min->magic == LIBALLOC_DEAD) - { - log("liballoc - multiple PREFIX(free)() attempt on %x from %x.", - ptr, - __builtin_return_address(0)); - } - else - { - log("liballoc - Bad PREFIX(free)( %x ) called from %x", - ptr, - __builtin_return_address(0)); - } - - liballoc_unlock(); - return; - } - - log("liballoc - %x PREFIX(free)( %x ): ", - __builtin_return_address(0), - ptr); - - maj = min->block; - - l_inuse -= min->size; - - maj->usage -= (min->size + sizeof(struct liballoc_minor)); - min->magic = LIBALLOC_DEAD; - - if (min->next != NULL) - min->next->prev = min->prev; - if (min->prev != NULL) - min->prev->next = min->next; - - if (min->prev == NULL) - maj->first = min->next; - - if (maj->first == NULL) - { - if (l_memRoot == maj) - l_memRoot = maj->next; - if (l_bestBet == maj) - l_bestBet = NULL; - if (maj->prev != NULL) - maj->prev->next = maj->next; - if (maj->next != NULL) - maj->next->prev = maj->prev; - l_allocated -= maj->size; - - liballoc_free(maj, maj->pages); - } - else - { - if (l_bestBet != NULL) - { - int bestSize = l_bestBet->size - l_bestBet->usage; - int majSize = maj->size - maj->usage; - - if (majSize > bestSize) - l_bestBet = maj; - } - } - - log("liballoc - (warning) OK"); - - liballoc_unlock(); + return p; } -void *PREFIX(calloc)(size_t nobj, size_t size) -{ - int real_size; - void *p; +void *PREFIX(realloc)(void *p, size_t size) { + void *ptr; + struct liballoc_minor *min; + unsigned int real_size; - real_size = nobj * size; - - p = PREFIX(malloc)(real_size); - - liballoc_memset(p, 0, real_size); - - return p; -} - -void *PREFIX(realloc)(void *p, size_t size) -{ - void *ptr; - struct liballoc_minor *min; - unsigned int real_size; - - if (size == 0) - { - PREFIX(free) - (p); - return NULL; - } - - if (p == NULL) - return PREFIX(malloc)(size); - - ptr = p; - UNALIGN(ptr); - - liballoc_lock(); - - min = (struct liballoc_minor *)((uintptr_t)ptr - sizeof(struct liballoc_minor)); - - if (min->magic != LIBALLOC_MAGIC) - { - l_errorCount += 1; - - if ( - ((min->magic & 0xFFFFFF) == (LIBALLOC_MAGIC & 0xFFFFFF)) || - ((min->magic & 0xFFFF) == (LIBALLOC_MAGIC & 0xFFFF)) || - ((min->magic & 0xFF) == (LIBALLOC_MAGIC & 0xFF))) - { - l_possibleOverruns += 1; - log("liballoc - Possible 1-3 byte overrun for magic %x != %x", - min->magic, - LIBALLOC_MAGIC); - } - - if (min->magic == LIBALLOC_DEAD) - { - log("liballoc - liballoc: multiple PREFIX(free)() attempt on %x from %x.", - ptr, - __builtin_return_address(0)); - } - else - { - log("liballoc - liballoc: Bad PREFIX(free)( %x ) called from %x", - ptr, - __builtin_return_address(0)); - } - - liballoc_unlock(); - return NULL; - } - - real_size = min->req_size; - - if (real_size >= size) - { - min->req_size = size; - liballoc_unlock(); - return p; - } - - liballoc_unlock(); - - ptr = PREFIX(malloc)(size); - liballoc_memcpy(ptr, p, real_size); + if (size == 0) { PREFIX(free) (p); + return NULL; + } - return ptr; + if (p == NULL) + return PREFIX(malloc)(size); + + ptr = p; + UNALIGN(ptr); + + liballoc_lock(); + + min = + (struct liballoc_minor *)((uintptr_t)ptr - sizeof(struct liballoc_minor)); + + if (min->magic != LIBALLOC_MAGIC) { + l_errorCount += 1; + + if (((min->magic & 0xFFFFFF) == (LIBALLOC_MAGIC & 0xFFFFFF)) || + ((min->magic & 0xFFFF) == (LIBALLOC_MAGIC & 0xFFFF)) || + ((min->magic & 0xFF) == (LIBALLOC_MAGIC & 0xFF))) { + l_possibleOverruns += 1; + log("liballoc - Possible 1-3 byte overrun for magic %x != %x", min->magic, + LIBALLOC_MAGIC); + } + + if (min->magic == LIBALLOC_DEAD) { + log("liballoc - liballoc: multiple PREFIX(free)() attempt on %x from %x.", + ptr, __builtin_return_address(0)); + } else { + log("liballoc - liballoc: Bad PREFIX(free)( %x ) called from %x", ptr, + __builtin_return_address(0)); + } + + liballoc_unlock(); + return NULL; + } + + real_size = min->req_size; + + if (real_size >= size) { + min->req_size = size; + liballoc_unlock(); + return p; + } + + liballoc_unlock(); + + ptr = PREFIX(malloc)(size); + liballoc_memcpy(ptr, p, real_size); + PREFIX(free) + (p); + + return ptr; } \ No newline at end of file diff --git a/kernel/src/mm/liballoc/liballoc_soaplin.c b/kernel/src/mm/liballoc/liballoc_soaplin.c index 7befb10..97a94a4 100644 --- a/kernel/src/mm/liballoc/liballoc_soaplin.c +++ b/kernel/src/mm/liballoc/liballoc_soaplin.c @@ -1,40 +1,34 @@ #include "mm/liballoc/liballoc.h" #include "mm/vmm.h" -#include #include +#include #include extern vma_context_t *kernel_vma_context; -static spinlock_t liballoc_lock_var = { 0 }; +static spinlock_t liballoc_lock_var = {0}; -int liballoc_lock() -{ - spinlock_acquire(&liballoc_lock_var); - return 0; +int liballoc_lock() { + spinlock_acquire(&liballoc_lock_var); + return 0; } -int liballoc_unlock() -{ - spinlock_release(&liballoc_lock_var); - return 0; +int liballoc_unlock() { + spinlock_release(&liballoc_lock_var); + return 0; } -void *liballoc_alloc(size_t pages) -{ - return vma_alloc(kernel_vma_context, pages, VMM_PRESENT | VMM_WRITABLE); +void *liballoc_alloc(size_t pages) { + return vma_alloc(kernel_vma_context, pages, VMM_PRESENT | VMM_WRITABLE); } -int liballoc_free(void *ptr, size_t pages) -{ - (void)pages; - vma_free(kernel_vma_context, ptr); - return 0; +int liballoc_free(void *ptr, size_t pages) { + (void)pages; + vma_free(kernel_vma_context, ptr); + return 0; } - - - //void *malloc(size_t s) { return PREFIX(malloc)(s); } - //void *realloc(void *v, size_t s) { return PREFIX(realloc)(v, s); } - //void *calloc(size_t s1, size_t s) { return PREFIX(calloc)(s1, s); } - //void free(void *v) { return PREFIX(free)(v); } \ No newline at end of file +// void *malloc(size_t s) { return PREFIX(malloc)(s); } +// void *realloc(void *v, size_t s) { return PREFIX(realloc)(v, s); } +// void *calloc(size_t s1, size_t s) { return PREFIX(calloc)(s1, s); } +// void free(void *v) { return PREFIX(free)(v); } \ No newline at end of file diff --git a/kernel/src/mm/memop.c b/kernel/src/mm/memop.c old mode 100755 new mode 100644 index dca421b..0fdff0e --- a/kernel/src/mm/memop.c +++ b/kernel/src/mm/memop.c @@ -10,7 +10,6 @@ void *memcpy(void *dest, const void *src, size_t n) { uint8_t *pdest = (uint8_t *)dest; const uint8_t *psrc = (const uint8_t *)src; - for (size_t i = 0; i < n; i++) { pdest[i] = psrc[i]; } diff --git a/kernel/src/mm/pmm.c b/kernel/src/mm/pmm.c old mode 100755 new mode 100644 index ebccb22..8dcf73a --- a/kernel/src/mm/pmm.c +++ b/kernel/src/mm/pmm.c @@ -1,7 +1,7 @@ #include "limine.h" -#include #include #include +#include #include #include @@ -10,105 +10,88 @@ struct limine_memmap_response *_memmap; uint64_t hhdm_offset = 0x0; -__attribute__((used, section(".limine_requests"))) -struct limine_memmap_request mm_req = { - .id = LIMINE_MEMMAP_REQUEST, - .revision = 3 -}; +__attribute__(( + used, section(".limine_requests"))) struct limine_memmap_request mm_req = { + .id = LIMINE_MEMMAP_REQUEST, .revision = 3}; +__attribute__(( + used, section(".limine_requests"))) struct limine_hhdm_request hhdm_req = { + .id = LIMINE_HHDM_REQUEST, .revision = 3}; -__attribute__((used, section(".limine_requests"))) -struct limine_hhdm_request hhdm_req = { - .id = LIMINE_HHDM_REQUEST, - .revision = 3 -}; +int pmm_init() { + uint64_t free_pages = 0; + hhdm_offset = hhdm_req.response->offset; -int pmm_init() -{ - uint64_t free_pages = 0; - hhdm_offset = hhdm_req.response->offset; + struct limine_memmap_response *memmap = mm_req.response; + _memmap = memmap; - struct limine_memmap_response *memmap = mm_req.response; - _memmap = memmap; - - //DEBUG("mm", "----- PMM //INFO -----"); - int freemem = 0; - for (uint64_t i = 0; i < memmap->entry_count; i++) - { - if (memmap->entries[i]->type == LIMINE_MEMMAP_USABLE) - { - //DEBUG("mm", " - USABLE ENTRY\t\t@ 0x%.16llx, size: 0x%.16llx", memmap->entries[i]->base, memmap->entries[i]->length); - free_pages += DIV_ROUND_UP(memmap->entries[i]->length, PMM_PAGE_SIZE); - freemem += memmap->entries[i]->length; - } + // DEBUG("mm", "----- PMM //INFO -----"); + int freemem = 0; + for (uint64_t i = 0; i < memmap->entry_count; i++) { + if (memmap->entries[i]->type == LIMINE_MEMMAP_USABLE) { + // DEBUG("mm", " - USABLE ENTRY\t\t@ 0x%.16llx, size: 0x%.16llx", + // memmap->entries[i]->base, memmap->entries[i]->length); + free_pages += DIV_ROUND_UP(memmap->entries[i]->length, PMM_PAGE_SIZE); + freemem += memmap->entries[i]->length; } + } - uint64_t array_size = ALIGN_UP(free_pages * 8, PMM_PAGE_SIZE); + uint64_t array_size = ALIGN_UP(free_pages * 8, PMM_PAGE_SIZE); - for (uint64_t i = 0; i < memmap->entry_count; i++) - { - struct limine_memmap_entry *entry = memmap->entries[i]; - if (entry->length >= array_size && entry->type == LIMINE_MEMMAP_USABLE) - { - stack.pages = (uintptr_t*)HIGHER_HALF(entry->base); - entry->length -= array_size; - entry->base += array_size; - //DEBUG("mm", " - STACK START\t\t@ 0x%.16llx", stack.pages); - break; - } + for (uint64_t i = 0; i < memmap->entry_count; i++) { + struct limine_memmap_entry *entry = memmap->entries[i]; + if (entry->length >= array_size && entry->type == LIMINE_MEMMAP_USABLE) { + stack.pages = (uintptr_t *)HIGHER_HALF(entry->base); + entry->length -= array_size; + entry->base += array_size; + // DEBUG("mm", " - STACK START\t\t@ 0x%.16llx", stack.pages); + break; } + } - for (uint64_t i = 0; i < memmap->entry_count; i++) - { - struct limine_memmap_entry *entry = memmap->entries[i]; - if (entry->type == LIMINE_MEMMAP_USABLE) - { - for (uint64_t j = 0; j < entry->length; j += PMM_PAGE_SIZE) - { - stack.pages[stack.idx++] = entry->base + j; - } - } + for (uint64_t i = 0; i < memmap->entry_count; i++) { + struct limine_memmap_entry *entry = memmap->entries[i]; + if (entry->type == LIMINE_MEMMAP_USABLE) { + for (uint64_t j = 0; j < entry->length; j += PMM_PAGE_SIZE) { + stack.pages[stack.idx++] = entry->base + j; + } } + } - stack.max = stack.idx; - //DEBUG("mm", " - MAX INDEX:\t\t%d", stack.max); - //DEBUG("mm", " - CURRENT INDEX:\t%d", stack.idx); - //DEBUG("mm", "--------------------"); + stack.max = stack.idx; + // DEBUG("mm", " - MAX INDEX:\t\t%d", stack.max); + // DEBUG("mm", " - CURRENT INDEX:\t%d", stack.idx); + // DEBUG("mm", "--------------------"); - - log("pmm - %dmb is available to us.\n", freemem / (1024 * 1024)); - return 0; + log("pmm - %dmb is available to us.\n", freemem / (1024 * 1024)); + return 0; } -void *pmm_request_page() -{ - if (stack.idx == 0) - { - //ERROR("mm", "No more pages available."); - log("pmm - out of memory.\n"); - asm("cli"); - while (1) { - asm("hlt"); - } - return NULL; +void *pmm_request_page() { + if (stack.idx == 0) { + // ERROR("mm", "No more pages available."); + log("pmm - out of memory.\n"); + asm("cli"); + while (1) { + asm("hlt"); } + return NULL; + } - uint64_t page_addr = stack.pages[--stack.idx]; - memset(HIGHER_HALF(page_addr), 0, PMM_PAGE_SIZE); - return (void *)page_addr; + uint64_t page_addr = stack.pages[--stack.idx]; + memset(HIGHER_HALF(page_addr), 0, PMM_PAGE_SIZE); + return (void *)page_addr; } -void pmm_free_page(void *ptr) -{ - if (ptr == NULL) - return; +void pmm_free_page(void *ptr) { + if (ptr == NULL) + return; - if (stack.idx >= stack.max) - { - //ERROR("mm", "Stack overflow attempt while freeing a page."); - log("pmm - could not free the page: stack overflow.\n"); - return; - } + if (stack.idx >= stack.max) { + // ERROR("mm", "Stack overflow attempt while freeing a page."); + log("pmm - could not free the page: stack overflow.\n"); + return; + } - stack.pages[stack.idx++] = (uint64_t)ptr; + stack.pages[stack.idx++] = (uint64_t)ptr; } \ No newline at end of file diff --git a/kernel/src/mm/pmm.h b/kernel/src/mm/pmm.h old mode 100755 new mode 100644 index f39a988..533a457 --- a/kernel/src/mm/pmm.h +++ b/kernel/src/mm/pmm.h @@ -4,16 +4,16 @@ #include #define PMM_PAGE_SIZE 4096 -typedef struct pmm_stack -{ - uintptr_t *pages; - uint64_t idx; - uint64_t max; +typedef struct pmm_stack { + uintptr_t *pages; + uint64_t idx; + uint64_t max; } pmm_stack_t; extern uint64_t hhdm_offset; -#define DIV_ROUND_UP(x, y) (((uint64_t)(x) + ((uint64_t)(y) - 1)) / (uint64_t)(y)) +#define DIV_ROUND_UP(x, y) \ + (((uint64_t)(x) + ((uint64_t)(y) - 1)) / (uint64_t)(y)) #define ALIGN_UP(x, y) (DIV_ROUND_UP(x, y) * (uint64_t)(y)) #define ALIGN_DOWN(x, y) (((uint64_t)(x) / (uint64_t)(y)) * (uint64_t)(y)) diff --git a/kernel/src/mm/vma.c b/kernel/src/mm/vma.c index 606dd2b..3412e92 100644 --- a/kernel/src/mm/vma.c +++ b/kernel/src/mm/vma.c @@ -3,199 +3,179 @@ #include "mm/pmm.h" #include "mm/vmm.h" -#include #include +#include #include vma_context_t *kernel_vma_context; -vma_context_t *vma_create_context(pagemap_t *pagemap) -{ - log("vma - creating VMA context with pagemap: 0x%.16llx\n", (uint64_t)pagemap); +vma_context_t *vma_create_context(pagemap_t *pagemap) { + log("vma - creating VMA context with pagemap: 0x%.16llx\n", + (uint64_t)pagemap); - vma_context_t *ctx = (vma_context_t *)HIGHER_HALF(pmm_request_page()); - if (ctx == NULL) - { - log("vma - failed to allocate VMA context\n"); - return NULL; - } - log("vma - allocated VMA context at 0x%.16llx\n", (uint64_t)ctx); - memset(ctx, 0, sizeof(vma_context_t)); - log("vma - zeroed out VMA context at 0x%.16llx\n", (uint64_t)ctx); - - ctx->root = (vma_region_t *)HIGHER_HALF(pmm_request_page()); - if (ctx->root == NULL) - { - log("vma - failed to allocate root region\n"); - pmm_free_page((void *)PHYSICAL(ctx)); - return NULL; - } - log("vma - allocated root region at 0x%.16llx\n", (uint64_t)ctx->root); - - ctx->pagemap = pagemap; - ctx->root->start = PMM_PAGE_SIZE; - ctx->root->size = 0; - - log("vma - VMA context created at 0x%.16llx with root region at 0x%.16llx\n", (uint64_t)ctx, (uint64_t)ctx->root); - return ctx; -} - -void vma_destroy_context(vma_context_t *ctx) -{ - log("vma - destroying VMA context at 0x%.16llx\n", (uint64_t)ctx); - - if (ctx->root == NULL || ctx->pagemap == NULL) - { - log("vma - invalid context or root passed to vma_destroy_context\n"); - return; - } - - vma_region_t *region = ctx->root; - while (region != NULL) - { - log("vma - freeing region at 0x%.16llx\n", (uint64_t)region); - vma_region_t *next = region->next; - pmm_free_page((void *)PHYSICAL(region)); - region = next; - } + vma_context_t *ctx = (vma_context_t *)HIGHER_HALF(pmm_request_page()); + if (ctx == NULL) { + log("vma - failed to allocate VMA context\n"); + return NULL; + } + log("vma - allocated VMA context at 0x%.16llx\n", (uint64_t)ctx); + memset(ctx, 0, sizeof(vma_context_t)); + log("vma - zeroed out VMA context at 0x%.16llx\n", (uint64_t)ctx); + ctx->root = (vma_region_t *)HIGHER_HALF(pmm_request_page()); + if (ctx->root == NULL) { + log("vma - failed to allocate root region\n"); pmm_free_page((void *)PHYSICAL(ctx)); - log("vma - destroyed VMA context at 0x%.16llx\n", (uint64_t)ctx); + return NULL; + } + log("vma - allocated root region at 0x%.16llx\n", (uint64_t)ctx->root); + + ctx->pagemap = pagemap; + ctx->root->start = PMM_PAGE_SIZE; + ctx->root->size = 0; + + log("vma - VMA context created at 0x%.16llx with root region at 0x%.16llx\n", + (uint64_t)ctx, (uint64_t)ctx->root); + return ctx; } -void *vma_alloc(vma_context_t *ctx, uint64_t size, uint64_t flags) -{ - if (ctx == NULL || ctx->root == NULL || ctx->pagemap == NULL) - { - log("vma - invalid context or root passed to vma_alloc\n"); - return NULL; - } +void vma_destroy_context(vma_context_t *ctx) { + log("vma - destroying VMA context at 0x%.16llx\n", (uint64_t)ctx); - vma_region_t *region = ctx->root; - vma_region_t *new_region; - vma_region_t *last_region = ctx->root; + if (ctx->root == NULL || ctx->pagemap == NULL) { + log("vma - invalid context or root passed to vma_destroy_context\n"); + return; + } - while (region != NULL) - { - if (region->next == NULL || region->start + region->size < region->next->start) - { - new_region = (vma_region_t *)HIGHER_HALF(pmm_request_page()); - if (new_region == NULL) - { - log("vma - failed to allocate new VMA region\n"); - return NULL; - } + vma_region_t *region = ctx->root; + while (region != NULL) { + log("vma - freeing region at 0x%.16llx\n", (uint64_t)region); + vma_region_t *next = region->next; + pmm_free_page((void *)PHYSICAL(region)); + region = next; + } - memset(new_region, 0, sizeof(vma_region_t)); - new_region->size = size; - new_region->flags = flags; - new_region->start = region->start + region->size; - new_region->next = region->next; - new_region->prev = region; - region->next = new_region; + pmm_free_page((void *)PHYSICAL(ctx)); + log("vma - destroyed VMA context at 0x%.16llx\n", (uint64_t)ctx); +} - for (uint64_t i = 0; i < size; i++) - { - uint64_t page = (uint64_t)pmm_request_page(); - if (page == 0) - { - log("vma - failed to allocate physical memory for VMA region\n"); - return NULL; - } +void *vma_alloc(vma_context_t *ctx, uint64_t size, uint64_t flags) { + if (ctx == NULL || ctx->root == NULL || ctx->pagemap == NULL) { + log("vma - invalid context or root passed to vma_alloc\n"); + return NULL; + } - vmm_map(ctx->pagemap, new_region->start + i * PMM_PAGE_SIZE, page, new_region->flags); - } + vma_region_t *region = ctx->root; + vma_region_t *new_region; + vma_region_t *last_region = ctx->root; - return (void *)new_region->start; - } - region = region->next; - } - - new_region = (vma_region_t *)HIGHER_HALF(pmm_request_page()); - if (new_region == NULL) - { + while (region != NULL) { + if (region->next == NULL || + region->start + region->size < region->next->start) { + new_region = (vma_region_t *)HIGHER_HALF(pmm_request_page()); + if (new_region == NULL) { log("vma - failed to allocate new VMA region\n"); return NULL; - } + } - memset(new_region, 0, sizeof(vma_region_t)); + memset(new_region, 0, sizeof(vma_region_t)); + new_region->size = size; + new_region->flags = flags; + new_region->start = region->start + region->size; + new_region->next = region->next; + new_region->prev = region; + region->next = new_region; - last_region->next = new_region; - new_region->prev = last_region; - new_region->start = last_region->start + last_region->size; - new_region->size = size; - new_region->flags = flags; - new_region->next = NULL; - - for (uint64_t i = 0; i < size; i++) - { + for (uint64_t i = 0; i < size; i++) { uint64_t page = (uint64_t)pmm_request_page(); - if (page == 0) - { - log("vma - failed to allocate physical memory for VMA region\n"); - return NULL; + if (page == 0) { + log("vma - failed to allocate physical memory for VMA region\n"); + return NULL; } - vmm_map(ctx->pagemap, new_region->start + i * PMM_PAGE_SIZE, page, new_region->flags); + vmm_map(ctx->pagemap, new_region->start + i * PMM_PAGE_SIZE, page, + new_region->flags); + } + + return (void *)new_region->start; + } + region = region->next; + } + + new_region = (vma_region_t *)HIGHER_HALF(pmm_request_page()); + if (new_region == NULL) { + log("vma - failed to allocate new VMA region\n"); + return NULL; + } + + memset(new_region, 0, sizeof(vma_region_t)); + + last_region->next = new_region; + new_region->prev = last_region; + new_region->start = last_region->start + last_region->size; + new_region->size = size; + new_region->flags = flags; + new_region->next = NULL; + + for (uint64_t i = 0; i < size; i++) { + uint64_t page = (uint64_t)pmm_request_page(); + if (page == 0) { + log("vma - failed to allocate physical memory for VMA region\n"); + return NULL; } - return (void *)new_region->start; + vmm_map(ctx->pagemap, new_region->start + i * PMM_PAGE_SIZE, page, + new_region->flags); + } + + return (void *)new_region->start; } -void vma_free(vma_context_t *ctx, void *ptr) -{ - if (ctx == NULL) - { - log("vma - invalid context passed to vma_free\n"); - return; +void vma_free(vma_context_t *ctx, void *ptr) { + if (ctx == NULL) { + log("vma - invalid context passed to vma_free\n"); + return; + } + + vma_region_t *region = ctx->root; + while (region != NULL) { + if (region->start == (uint64_t)ptr) { + log("vma - found region to free at 0x%.16llx\n", (uint64_t)region); + break; } + region = region->next; + } - vma_region_t *region = ctx->root; - while (region != NULL) - { - if (region->start == (uint64_t)ptr) - { - log("vma - found region to free at 0x%.16llx\n", (uint64_t)region); - break; - } - region = region->next; + if (region == NULL) { + log("vma - unable to find region to free at address 0x%.16llx\n", + (uint64_t)ptr); + return; + } + + vma_region_t *prev = region->prev; + vma_region_t *next = region->next; + + for (uint64_t i = 0; i < region->size; i++) { + uint64_t virt = region->start + i * PMM_PAGE_SIZE; + uint64_t phys = virt_to_phys(vmm_kernel_pm, virt); + + if (phys != 0) { + pmm_free_page((void *)phys); + vmm_unmap(ctx->pagemap, virt); } + } - if (region == NULL) - { - log("vma - unable to find region to free at address 0x%.16llx\n", (uint64_t)ptr); - return; - } + if (prev != NULL) { + prev->next = next; + } - vma_region_t *prev = region->prev; - vma_region_t *next = region->next; + if (next != NULL) { + next->prev = prev; + } - for (uint64_t i = 0; i < region->size; i++) - { - uint64_t virt = region->start + i * PMM_PAGE_SIZE; - uint64_t phys = virt_to_phys(vmm_kernel_pm, virt); + if (region == ctx->root) { + ctx->root = next; + } - if (phys != 0) - { - pmm_free_page((void *)phys); - vmm_unmap(ctx->pagemap, virt); - } - } - - if (prev != NULL) - { - prev->next = next; - } - - if (next != NULL) - { - next->prev = prev; - } - - if (region == ctx->root) - { - ctx->root = next; - } - - pmm_free_page((void *)PHYSICAL(region)); + pmm_free_page((void *)PHYSICAL(region)); } diff --git a/kernel/src/mm/vma.h b/kernel/src/mm/vma.h index df6d225..d77d22e 100644 --- a/kernel/src/mm/vma.h +++ b/kernel/src/mm/vma.h @@ -3,23 +3,21 @@ #pragma once -#include #include +#include #include -typedef struct vma_region -{ - uint64_t start; - uint64_t size; - uint64_t flags; - struct vma_region *next; - struct vma_region *prev; +typedef struct vma_region { + uint64_t start; + uint64_t size; + uint64_t flags; + struct vma_region *next; + struct vma_region *prev; } vma_region_t; -typedef struct vma_context -{ - pagemap_t *pagemap; - vma_region_t *root; +typedef struct vma_context { + pagemap_t *pagemap; + vma_region_t *root; } vma_context_t; extern vma_context_t *kernel_vma_context; diff --git a/kernel/src/mm/vmm.c b/kernel/src/mm/vmm.c old mode 100755 new mode 100644 index ab04966..d6f8fc0 --- a/kernel/src/mm/vmm.c +++ b/kernel/src/mm/vmm.c @@ -4,6 +4,7 @@ #include "mm/pmm.h" #include "sys/log.h" #include "vmm.h" +#include #include __attribute__(( @@ -150,15 +151,16 @@ void vmm_load_pagemap(pagemap_t *pm) { } static uint64_t *__vmm_get_next_lvl(uint64_t *level, uint64_t entry, - uint64_t flags) { - if (!(level[entry] & 1)) { - uint64_t *pml = HIGHER_HALF(pmm_request_page()); + uint64_t flags, bool alloc) { + if (level[entry] & VMM_PRESENT) + return HIGHER_HALF(PTE_GET_ADDR(level[entry])); + if (alloc) { + uint64_t *pml = (uint64_t *)HIGHER_HALF(pmm_request_page()); memset(pml, 0, PMM_PAGE_SIZE); - level[entry] = (uint64_t)PHYSICAL(pml); - + level[entry] = (uint64_t)PHYSICAL(pml) | flags; + return pml; } - level[entry] |= (flags & 0xFFF); - return HIGHER_HALF(PTE_GET_ADDR(level[entry])); + return NULL; } uint64_t vmm_get_flags(pagemap_t *pm, uint64_t vaddr) { @@ -167,9 +169,15 @@ uint64_t vmm_get_flags(pagemap_t *pm, uint64_t vaddr) { uint64_t pml2_entry = (vaddr >> 21) & 0x1ff; uint64_t pml1_entry = (vaddr >> 12) & 0x1ff; - uint64_t *pml3 = __vmm_get_next_lvl(pm->toplevel, pml4_entry, 0); - uint64_t *pml2 = __vmm_get_next_lvl(pml3, pml3_entry, 0); - uint64_t *pml1 = __vmm_get_next_lvl(pml2, pml2_entry, 0); + uint64_t *pml3 = __vmm_get_next_lvl(pm->toplevel, pml4_entry, 0, false); + if (!pml3) + return 0; + uint64_t *pml2 = __vmm_get_next_lvl(pml3, pml3_entry, 0, false); + if (!pml2) + return 0; + uint64_t *pml1 = __vmm_get_next_lvl(pml2, pml2_entry, 0, false); + if (!pml1) + return 0; return pml1[pml1_entry] & 0x7000000000000FFF; } @@ -180,14 +188,17 @@ uint64_t virt_to_phys(pagemap_t *pagemap, uint64_t virt) { uint64_t pml2_idx = (virt >> 21) & 0x1FF; uint64_t pml1_idx = (virt >> 12) & 0x1FF; - uint64_t *pml3 = __vmm_get_next_lvl(pagemap->toplevel, pml4_idx, 0); - uint64_t *pml2 = __vmm_get_next_lvl(pml3, pml3_idx, 0); - uint64_t *pml1 = __vmm_get_next_lvl(pml2, pml2_idx, 0); + uint64_t *pml3 = __vmm_get_next_lvl(pagemap->toplevel, pml4_idx, 0, false); + if (!pml3) + return 0; + uint64_t *pml2 = __vmm_get_next_lvl(pml3, pml3_idx, 0, false); + if (!pml2) + return 0; + uint64_t *pml1 = __vmm_get_next_lvl(pml2, pml2_idx, 0, false); + if (!pml1) + return 0; - uint64_t phys_addr = - pml1[pml1_idx] & - 0x000FFFFFFFFFF000; // Masque pour obtenir l'adresse physique (en retirant - // les bits de flags) + uint64_t phys_addr = pml1[pml1_idx] & 0x000FFFFFFFFFF000; return phys_addr; } @@ -198,9 +209,30 @@ void vmm_map(pagemap_t *pm, uint64_t vaddr, uint64_t paddr, uint64_t flags) { uint64_t pml2_entry = (vaddr >> 21) & 0x1ff; uint64_t pml1_entry = (vaddr >> 12) & 0x1ff; - uint64_t *pml3 = __vmm_get_next_lvl(pm->toplevel, pml4_entry, flags); - uint64_t *pml2 = __vmm_get_next_lvl(pml3, pml3_entry, flags); - uint64_t *pml1 = __vmm_get_next_lvl(pml2, pml2_entry, flags); + uint64_t *pml3 = __vmm_get_next_lvl(pm->toplevel, pml4_entry, + VMM_PRESENT | VMM_WRITABLE, true); + uint64_t *pml2 = + __vmm_get_next_lvl(pml3, pml3_entry, VMM_PRESENT | VMM_WRITABLE, true); + uint64_t *pml1 = + __vmm_get_next_lvl(pml2, pml2_entry, VMM_PRESENT | VMM_WRITABLE, true); + + pml1[pml1_entry] = paddr | flags; +} + +void vmm_map_user(pagemap_t *pm, uint64_t vaddr, uint64_t paddr, + uint64_t flags) { + uint64_t pml4_entry = (vaddr >> 39) & 0x1ff; + uint64_t pml3_entry = (vaddr >> 30) & 0x1ff; + uint64_t pml2_entry = (vaddr >> 21) & 0x1ff; + uint64_t pml1_entry = (vaddr >> 12) & 0x1ff; + + uint64_t *pml3 = + __vmm_get_next_lvl(pm->toplevel, pml4_entry, flags, + true); // PML3 / Page Directory Pointer Entry + uint64_t *pml2 = __vmm_get_next_lvl(pml3, pml3_entry, flags, + true); // PML2 / Page Directory Entry + uint64_t *pml1 = __vmm_get_next_lvl(pml2, pml2_entry, flags, + true); // PML1 / Page Table Entry pml1[pml1_entry] = paddr | flags; } @@ -211,13 +243,13 @@ void vmm_unmap(pagemap_t *pm, uint64_t vaddr) { uint64_t pml3_entry = (vaddr >> 30) & 0x1ff; uint64_t pml4_entry = (vaddr >> 39) & 0x1ff; - uint64_t *pml3 = __vmm_get_next_lvl(pm->toplevel, pml4_entry, 0); + uint64_t *pml3 = __vmm_get_next_lvl(pm->toplevel, pml4_entry, 0, false); if (pml3 == NULL) return; - uint64_t *pml2 = __vmm_get_next_lvl(pml3, pml3_entry, 0); + uint64_t *pml2 = __vmm_get_next_lvl(pml3, pml3_entry, 0, false); if (pml2 == NULL) return; - uint64_t *pml1 = __vmm_get_next_lvl(pml2, pml2_entry, 0); + uint64_t *pml1 = __vmm_get_next_lvl(pml2, pml2_entry, 0, false); if (pml1 == NULL) return; diff --git a/kernel/src/mm/vmm.h b/kernel/src/mm/vmm.h old mode 100755 new mode 100644 index 5469653..12566bc --- a/kernel/src/mm/vmm.h +++ b/kernel/src/mm/vmm.h @@ -6,10 +6,10 @@ #define PTE_GET_ADDR(VALUE) ((VALUE) & PTE_ADDR_MASK) #define PTE_GET_FLAGS(VALUE) ((VALUE) & ~PTE_ADDR_MASK) -#define VMM_PRESENT (1 << 0) +#define VMM_PRESENT (1 << 0) #define VMM_WRITABLE (1 << 1) -#define VMM_USER (1 << 2) -#define VMM_NX (1ULL << 63) +#define VMM_USER (1 << 2) +#define VMM_NX (1ULL << 63) typedef char sym[]; @@ -25,9 +25,8 @@ extern sym rodata_end_ld; extern sym data_start_ld; extern sym data_end_ld; - typedef struct pagemap { - uint64_t *toplevel; + uint64_t *toplevel; } pagemap_t; extern pagemap_t *vmm_kernel_pm; @@ -37,7 +36,11 @@ pagemap_t *vmm_alloc_pm(); void vmm_init(); void vmm_release_pm(pagemap_t *pm); void vmm_load_pagemap(pagemap_t *pm); -uint64_t vmm_get_flags(pagemap_t* pm, uint64_t vaddr); +uint64_t vmm_get_flags(pagemap_t *pm, uint64_t vaddr); uint64_t virt_to_phys(pagemap_t *pagemap, uint64_t virt); + +// NOTE: for user mode, please use vmm_map_user instead. void vmm_map(pagemap_t *pm, uint64_t vaddr, uint64_t paddr, uint64_t flags); -void vmm_unmap(pagemap_t *pm, uint64_t vaddr) ; \ No newline at end of file +void vmm_map_user(pagemap_t *pm, uint64_t vaddr, uint64_t paddr, + uint64_t flags); +void vmm_unmap(pagemap_t *pm, uint64_t vaddr); \ No newline at end of file diff --git a/kernel/src/sched/sched.c b/kernel/src/sched/sched.c old mode 100755 new mode 100644 index 10d1614..fe94da7 --- a/kernel/src/sched/sched.c +++ b/kernel/src/sched/sched.c @@ -1,6 +1,6 @@ #include "sched/sched.h" -#include "mm/pmm.h" #include "mm/memop.h" +#include "mm/pmm.h" #include "mm/vmm.h" #include "sys/arch/x86_64/idt.h" #include "sys/log.h" @@ -11,148 +11,155 @@ sched_process *curr_proc; int current_pid = 0; int standby = 0; -void map_range_to_pagemap(pagemap_t *dest_pagemap, pagemap_t *src_pagemap, uint64_t start, uint64_t size, uint64_t flags) -{ - for (uint64_t offset = 0; offset < size; offset += PMM_PAGE_SIZE) - { - uint64_t phys = virt_to_phys(src_pagemap, start + offset); - if (phys) - { - vmm_map(dest_pagemap, start + offset, phys, flags); - } +void map_range_to_pagemap(pagemap_t *dest_pagemap, pagemap_t *src_pagemap, + uint64_t start, uint64_t size, int user, + uint64_t flags) { + for (uint64_t offset = 0; offset < size; offset += PMM_PAGE_SIZE) { + uint64_t phys = virt_to_phys(src_pagemap, start + offset); + if (phys) { + if (user) + vmm_map_user(dest_pagemap, start + offset, phys, flags); + else + vmm_map(dest_pagemap, start + offset, phys, flags); } + } } void sched_init() { - // TODO: It may be good to implement heap memory to save space. - - // We must initialize the process list. - // By default, sched_create will append to this list. - proc_list = pmm_request_page(); - memcpy(proc_list->name, "System\0", 7); - proc_list->pid = -1; - proc_list->type = SCHED_EMPTY; + // TODO: It may be good to implement heap memory to save space. - curr_proc = proc_list; + // We must initialize the process list. + // By default, sched_create will append to this list. + proc_list = pmm_request_page(); + memcpy(proc_list->name, "System\0", 7); + proc_list->pid = -1; + proc_list->type = SCHED_EMPTY; - standby = 1; - log("sched - As there's nothing " - "to schedule, the scheduler entered standby" - "mode.\n"); + curr_proc = proc_list; + + standby = 1; + log("sched - As there's nothing " + "to schedule, the scheduler entered standby" + "mode.\n"); } -sched_process *sched_create(char *name, uint64_t entry_point, pagemap_t* pm, uint32_t flags) -{ - // TODO: implement a separate strlen function - // as there's like 4 strlen impls in the kernel. - int i = 0; - while (name[i] != 0) - i++; +sched_process *sched_create(char *name, uint64_t entry_point, pagemap_t *pm, + uint32_t flags) { + // TODO: implement a separate strlen function + // as there's like 4 strlen impls in the kernel. + int i = 0; + while (name[i] != 0) + i++; - sched_process *proc = pmm_request_page(); - memset(proc, 0, sizeof(sched_process)); + sched_process *proc = pmm_request_page(); + memset(proc, 0, sizeof(sched_process)); - memcpy(proc->name, name, i); - proc->pid = current_pid; - proc->type = SCHED_RUNNING; - proc->flags = flags; + memcpy(proc->name, name, i); + proc->pid = current_pid; + proc->type = SCHED_RUNNING; + proc->flags = flags; - // We are about to setup the registers ourself. - // If it's broken, it's a boom in the ass of your computer - // (and a CPU exception) + // We are about to setup the registers ourself. + // If it's broken, it's a boom in the ass of your computer + // (and a CPU exception) - proc->pm = pm; + proc->pm = pm; - uint64_t *stack_phys = pmm_request_page(); - uint64_t *stack_virt = (uint64_t*)0x40000000; + uint64_t *stack_phys = pmm_request_page(); + uint64_t *stack_virt = (uint64_t *)0x40000000; - if (flags == SCHED_KERNEL_PROCESS) { - proc->stack_base = stack_phys; - proc->stack_base_physical = stack_phys; - proc->stack_end = proc_list->stack_base + PMM_PAGE_SIZE; - } else if (flags == SCHED_USER_PROCESS) { - vmm_map(proc->pm, (uint64_t)stack_virt, (uint64_t)stack_phys, VMM_PRESENT | VMM_WRITABLE | VMM_USER); - proc->stack_base = stack_virt; - proc->stack_base_physical = stack_phys; - proc->stack_end = proc_list->stack_base + PMM_PAGE_SIZE; - } - proc->regs.rip = (uint64_t)entry_point; + if (flags == SCHED_KERNEL_PROCESS) { + proc->stack_base = stack_phys; + proc->stack_base_physical = stack_phys; + proc->stack_end = proc_list->stack_base + PMM_PAGE_SIZE; + } else if (flags == SCHED_USER_PROCESS) { + vmm_map_user(proc->pm, (uint64_t)stack_virt, (uint64_t)stack_phys, + VMM_PRESENT | VMM_WRITABLE | VMM_USER); + proc->stack_base = stack_virt; + proc->stack_base_physical = stack_phys; + proc->stack_end = proc_list->stack_base + PMM_PAGE_SIZE; + } + proc->regs.rip = (uint64_t)entry_point; - if (flags == SCHED_KERNEL_PROCESS) { - proc->regs.cs = 0x28; // Run in kernel mode - proc->regs.ss = 0x30; - } - else if (flags == SCHED_USER_PROCESS) { - proc->regs.cs = 0x43; // Run in user mode - proc->regs.ss = 0x3B; - } - proc->regs.rflags = 0x202; // Enable interrupts - proc->regs.rsp = (uint64_t)proc->stack_end; - proc->regs.rbp = 0; + if (flags == SCHED_KERNEL_PROCESS) { + proc->regs.cs = 0x28; // Run in kernel mode + proc->regs.ss = 0x30; + } else if (flags == SCHED_USER_PROCESS) { + proc->regs.cs = 0x43; // Run in user mode + proc->regs.ss = 0x3B; + } + proc->regs.rflags = 0x202; // Enable interrupts + proc->regs.rsp = (uint64_t)proc->stack_end; + proc->regs.rbp = 0; - proc->next = curr_proc->next; - curr_proc->next = proc; + proc->next = curr_proc->next; + curr_proc->next = proc; - current_pid++; + current_pid++; - map_range_to_pagemap(pm, vmm_kernel_pm, 0x1000, 0x10000, VMM_PRESENT | VMM_WRITABLE | VMM_USER); + if (flags == SCHED_USER_PROCESS) + map_range_to_pagemap(pm, vmm_kernel_pm, 0x1000, 0x10000, 1, + VMM_PRESENT | VMM_WRITABLE | VMM_USER); + else + map_range_to_pagemap(pm, vmm_kernel_pm, 0x1000, 0x10000, 0, + VMM_PRESENT | VMM_WRITABLE); - if (standby) { - // Disable standby mode as there's actually something to - // run, now. - standby = 0; - log("sched - Standby mode has been" + if (standby) { + // Disable standby mode as there's actually something to + // run, now. + standby = 0; + log("sched - Standby mode has been" "disabled.\n"); - } + } - log("sched - created process '%s' (pid: %d, rip: %p)\n", proc->name, proc->pid, proc->regs.rip); - return proc; + log("sched - created process '%s' (pid: %d, rip: %p)\n", proc->name, + proc->pid, proc->regs.rip); + return proc; } void sched_exit(int exit_code) { - log("sched - Process %d exited with code %d!", curr_proc->pid, exit_code); - curr_proc->type = SCHED_DIED; - schedule(&curr_proc->regs); + log("sched - Process %d exited with code %d!", curr_proc->pid, exit_code); + curr_proc->type = SCHED_DIED; + schedule(&curr_proc->regs); } -void schedule(registers_t *regs) -{ - if (standby) { - //log("sched - Sched is in standby.\n"); - return; +void schedule(registers_t *regs) { + if (standby) { + // log("sched - Sched is in standby.\n"); + return; + } + + memcpy(&curr_proc->regs, regs, sizeof(registers_t)); + + if (curr_proc->type == SCHED_DIED) { + sched_process *prev_proc = proc_list; + while (prev_proc->next != curr_proc) { + prev_proc = prev_proc->next; } - memcpy(&curr_proc->regs, regs, sizeof(registers_t)); + prev_proc->next = curr_proc->next; - if (curr_proc->type == SCHED_DIED) { - sched_process *prev_proc = proc_list; - while (prev_proc->next != curr_proc) { - prev_proc = prev_proc->next; - } + // Now, it is safe to free the process's memory. + vmm_release_pm(curr_proc->pm); + pmm_free_page(curr_proc->stack_base_physical); - prev_proc->next = curr_proc->next; + // R.I.P. process + pmm_free_page(curr_proc); - // Now, it is safe to free the process's memory. - vmm_release_pm(curr_proc->pm); - pmm_free_page(curr_proc->stack_base_physical); + return; + } - // R.I.P. process - pmm_free_page(curr_proc); + curr_proc = curr_proc->next; + if (curr_proc == NULL) + curr_proc = proc_list; - return; - } + // log("sched - I choosed process %d\n", curr_proc->pid); + memcpy(regs, &curr_proc->regs, sizeof(registers_t)); - curr_proc = curr_proc->next; - if (curr_proc == NULL) - curr_proc = proc_list; - - //log("sched - I choosed process %d\n", curr_proc->pid); - memcpy(regs, &curr_proc->regs, sizeof(registers_t)); - - // Finally, load our pagemap - //if (memcmp(curr_proc->name, "Init", 4)== 0) { - vmm_load_pagemap(curr_proc->pm); - //asm("cli"); - //while (1) - // asm("hlt");} + // Finally, load our pagemap + // if (memcmp(curr_proc->name, "Init", 4)== 0) { + vmm_load_pagemap(curr_proc->pm); + // asm("cli"); + // while (1) + // asm("hlt");} } \ No newline at end of file diff --git a/kernel/src/sched/sched.h b/kernel/src/sched/sched.h old mode 100755 new mode 100644 index bb2db88..f328d7a --- a/kernel/src/sched/sched.h +++ b/kernel/src/sched/sched.h @@ -4,28 +4,26 @@ #include "sys/arch/x86_64/idt.h" #define SCHED_KERNEL_PROCESS 0 // A process that runs in kernel mode. -#define SCHED_USER_PROCESS 1 // A process that runs in userspace. The code MUST be mapped directly after creating the process. +#define SCHED_USER_PROCESS \ + 1 // A process that runs in userspace. The code MUST be mapped directly after + // creating the process. -typedef enum { - SCHED_RUNNING, - SCHED_DIED, - SCHED_EMPTY -} sched_proc_type; +typedef enum { SCHED_RUNNING, SCHED_DIED, SCHED_EMPTY } sched_proc_type; typedef struct _sched_process { - char name[128]; - int pid; - int type; - int flags; + char name[128]; + int pid; + int type; + int flags; - registers_t regs; - pagemap_t *pm; + registers_t regs; + pagemap_t *pm; - uint64_t *stack_end; - uint64_t *stack_base; - uint64_t *stack_base_physical; + uint64_t *stack_end; + uint64_t *stack_base; + uint64_t *stack_base_physical; - struct _sched_process *next; + struct _sched_process *next; } sched_process; extern sched_process *curr_proc; @@ -33,9 +31,10 @@ extern sched_process *proc_list; // The idle process is ditched in favor of standby mode, // which activates when there's nothing to run. -//extern sched_process *idle_process; +// extern sched_process *idle_process; void sched_init(); -sched_process *sched_create(char *name, uint64_t entry_point, pagemap_t *pm, uint32_t flags); +sched_process *sched_create(char *name, uint64_t entry_point, pagemap_t *pm, + uint32_t flags); void sched_exit(int exit_code); void schedule(registers_t *regs); \ No newline at end of file diff --git a/kernel/src/sys/acpi.c b/kernel/src/sys/acpi.c new file mode 100644 index 0000000..6c056ae --- /dev/null +++ b/kernel/src/sys/acpi.c @@ -0,0 +1,95 @@ +#include "limine.h" +#include "mm/pmm.h" +#include "sys/log.h" +#include +#include +#include + +__attribute__(( + used, + section(".limine_requests"))) static volatile struct limine_rsdp_request + rsdp_req = {.revision = 0, .id = LIMINE_RSDP_REQUEST}; + +rsdp_t *rsdp; +int acpi_available = 0; + +int is_xsdt = 0; +xsdt_t *xsdt; +rsdt_t *rsdt; +int item_count = 0; + +static int acpi_validate_rsdp(char *byte_array, size_t size) { + uint32_t sum = 0; + for (int i = 0; i < size; i++) { + sum += byte_array[i]; + } + return (sum & 0xFF) == 0; +} + +void *acpi_find_table(char *sign, int sign_size) { + if (!acpi_available) + return NULL; + + if (is_xsdt) { + for (int i = 0; i < item_count; i++) { + uint64_t *lst = + (uint64_t *)HIGHER_HALF((uint64_t)xsdt->PointerToOtherSDT); + acpi_table_header_t *ptr = (acpi_table_header_t *)HIGHER_HALF(lst[i]); + + if (!memcmp(ptr->Signature, sign, sign_size)) + return (void *)ptr; + } + } else { + for (int i = 0; i < item_count; i++) { + acpi_table_header_t *ptr = (acpi_table_header_t *)HIGHER_HALF( + (uint64_t)rsdt->PointerToOtherSDT[i]); + if (!memcmp(ptr->Signature, sign, sign_size)) + return (void *)ptr; + } + } + + return NULL; +} + +void acpi_init() { + rsdp_t *rsdp = (rsdp_t *)HIGHER_HALF(rsdp_req.response->address); + + if (!rsdp) { + log("acpi - not available: RSDP is NULL!\n"); + return; + } + + if (rsdp->rev < 2) { + if (!acpi_validate_rsdp((char *)rsdp, sizeof(rsdp_t))) { + log("acpi - not available: Was the RSDP hijacked?\n"); + return; + } + rsdt = (rsdt_t *)HIGHER_HALF((uint64_t)rsdp->rsdt_addr); + log("acpi - RSDT found at %p\n", rsdt); + item_count = (rsdt->h.Length - sizeof(acpi_table_header_t)) / 4; + log("acpi - RSDT contains %d entries\n", item_count); + } else { + is_xsdt = 1; + if (!acpi_validate_rsdp((char *)rsdp, sizeof(xsdp_t))) { + log("acpi - not available: Was the XSDP hijacked?\n"); + return; + } + + xsdt = (xsdt_t *)HIGHER_HALF((uint64_t)((xsdp_t *)rsdp)->xsdt_addr); + log("acpi - XSDT found at %p\n", xsdt); + item_count = (xsdt->h.Length - sizeof(acpi_table_header_t)) / 8; + log("acpi - XSDT contains %d entries\n", item_count); + } + + acpi_available = 1; + + void *fadt = acpi_find_table("FACP", 4); + if (!fadt) { + log("acpi - FADT not found\n"); + acpi_available = 0; + return; + } else { + log("acpi - FADT found at %p\n", fadt); + log("acpi - ACPI initialized successfully\n"); + } +} \ No newline at end of file diff --git a/kernel/src/sys/acpi.h b/kernel/src/sys/acpi.h new file mode 100644 index 0000000..da28bd6 --- /dev/null +++ b/kernel/src/sys/acpi.h @@ -0,0 +1,51 @@ +#pragma once + +#include + +#define ACPI_RSDP_SIGNATURE "RSD PTR " +#define ACPI_RSDP_SIGNATURE_LEN 7 + +typedef struct __acpi_table_header { + char Signature[4]; + uint32_t Length; + uint8_t Revision; + uint8_t Checksum; + char OEMID[6]; + char OEMTableID[8]; + uint32_t OEMRevision; + uint32_t CreatorID; + uint32_t CreatorRevision; +} acpi_table_header_t; + +typedef struct __rsdp { + char signature[8]; + uint8_t chksum; + char oemid[6]; + uint8_t rev; + uint32_t rsdt_addr; +} __attribute__((packed)) rsdp_t; + +typedef struct __xsdp { + char signature[8]; + uint8_t chksum; + char oemid[6]; + uint8_t rev; + uint32_t rsdt_addr; // deprecated since version 2.0 + + uint32_t len; + uint64_t xsdt_addr; + uint8_t chksum_ex; + uint8_t reserved[3]; +} __attribute__((packed)) xsdp_t; + +typedef struct __rsdt { + acpi_table_header_t h; + uint32_t *PointerToOtherSDT; +} rsdt_t; + +typedef struct __xsdt { + acpi_table_header_t h; + uint64_t *PointerToOtherSDT; +} xsdt_t; + +void acpi_init(); \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/cpuid.h b/kernel/src/sys/arch/x86_64/cpuid.h old mode 100755 new mode 100644 index 021f89e..45a8d5f --- a/kernel/src/sys/arch/x86_64/cpuid.h +++ b/kernel/src/sys/arch/x86_64/cpuid.h @@ -4,90 +4,90 @@ #include //=================CPUID_VENDOR================= -#define CPUID_VENDOR_INTEL "GenuineIntel" -#define CPUID_VENDOR_AMD "AuthenticAMD" +#define CPUID_VENDOR_INTEL "GenuineIntel" +#define CPUID_VENDOR_AMD "AuthenticAMD" //================CPUID_CPU_INFO================ -#define CPUID_CPU_INFO_EAX_STEPPING_MASK 0xF -#define CPUID_CPU_INFO_EAX_MODEL_MASK 0xF << 4 -#define CPUID_CPU_INFO_EAX_FAMILY_MASK 0xF << 8 -#define CPUID_CPU_INFO_EAX_TYPE_MASK 0x3 << 12 -#define CPUID_CPU_INFO_EAX_EXT_MODEL_MASK 0xF << 16 -#define CPUID_CPU_INFO_EAX_EXT_FAMILY_MASK 0xFF << 20 +#define CPUID_CPU_INFO_EAX_STEPPING_MASK 0xF +#define CPUID_CPU_INFO_EAX_MODEL_MASK 0xF << 4 +#define CPUID_CPU_INFO_EAX_FAMILY_MASK 0xF << 8 +#define CPUID_CPU_INFO_EAX_TYPE_MASK 0x3 << 12 +#define CPUID_CPU_INFO_EAX_EXT_MODEL_MASK 0xF << 16 +#define CPUID_CPU_INFO_EAX_EXT_FAMILY_MASK 0xFF << 20 -#define CPUID_CPU_INFO_EBX_BRAND_INDEX 0xFF -#define CPUID_CPU_INFO_EBX_CFLUSH_SIZE 0xFF << 8 -#define CPUID_CPU_INFO_EBX_MAX_LOGPROC 0xFF << 16 +#define CPUID_CPU_INFO_EBX_BRAND_INDEX 0xFF +#define CPUID_CPU_INFO_EBX_CFLUSH_SIZE 0xFF << 8 +#define CPUID_CPU_INFO_EBX_MAX_LOGPROC 0xFF << 16 #define CPUID_CPU_INFO_EBX_INIT_APIC_ID 0xFF << 25 -#define CPUID_CPU_INFO_ECX_SSE3 1 << 0 -#define CPUID_CPU_INFO_ECX_PCLMULQDQ 1 << 1 -#define CPUID_CPU_INFO_ECX_DTES64 1 << 2 -#define CPUID_CPU_INFO_ECX_MONITOR 1 << 3 -#define CPUID_CPU_INFO_ECX_DS_CPL 1 << 4 -#define CPUID_CPU_INFO_ECX_VMX 1 << 5 -#define CPUID_CPU_INFO_ECX_SMX 1 << 6 -#define CPUID_CPU_INFO_ECX_EIST 1 << 7 -#define CPUID_CPU_INFO_ECX_TM2 1 << 8 -#define CPUID_CPU_INFO_ECX_SSSE3 1 << 9 -#define CPUID_CPU_INFO_ECX_CNXT_ID 1 << 10 -#define CPUID_CPU_INFO_ECX_SDBG 1 << 11 -#define CPUID_CPU_INFO_ECX_FMA 1 << 12 -#define CPUID_CPU_INFO_ECX_CMPXCHG16B 1 << 13 -#define CPUID_CPU_INFO_ECX_XTPR_UC 1 << 14 -#define CPUID_CPU_INFO_ECX_PDCM 1 << 15 -//bit 16 is reserved -#define CPUID_CPU_INFO_ECX_PCID 1 << 17 -#define CPUID_CPU_INFO_ECX_DCA 1 << 18 -#define CPUID_CPU_INFO_ECX_SSE4_1 1 << 19 -#define CPUID_CPU_INFO_ECX_SSE4_2 1 << 20 -#define CPUID_CPU_INFO_ECX_X2APIC 1 << 21 -#define CPUID_CPU_INFO_ECX_MOVBE 1 << 22 -#define CPUID_CPU_INFO_ECX_POPCNT 1 << 23 -#define CPUID_CPU_INFO_ECX_TSC_DEADLINE 1 << 24 -#define CPUID_CPU_INFO_ECX_AESNI 1 << 25 -#define CPUID_CPU_INFO_ECX_XSAVE 1 << 26 -#define CPUID_CPU_INFO_ECX_OSXSAVE 1 << 27 -#define CPUID_CPU_INFO_ECX_AVX 1 << 28 -#define CPUID_CPU_INFO_ECX_F16C 1 << 29 -#define CPUID_CPU_INFO_ECX_RDRAND 1 << 30 -//bit 31 is unused +#define CPUID_CPU_INFO_ECX_SSE3 1 << 0 +#define CPUID_CPU_INFO_ECX_PCLMULQDQ 1 << 1 +#define CPUID_CPU_INFO_ECX_DTES64 1 << 2 +#define CPUID_CPU_INFO_ECX_MONITOR 1 << 3 +#define CPUID_CPU_INFO_ECX_DS_CPL 1 << 4 +#define CPUID_CPU_INFO_ECX_VMX 1 << 5 +#define CPUID_CPU_INFO_ECX_SMX 1 << 6 +#define CPUID_CPU_INFO_ECX_EIST 1 << 7 +#define CPUID_CPU_INFO_ECX_TM2 1 << 8 +#define CPUID_CPU_INFO_ECX_SSSE3 1 << 9 +#define CPUID_CPU_INFO_ECX_CNXT_ID 1 << 10 +#define CPUID_CPU_INFO_ECX_SDBG 1 << 11 +#define CPUID_CPU_INFO_ECX_FMA 1 << 12 +#define CPUID_CPU_INFO_ECX_CMPXCHG16B 1 << 13 +#define CPUID_CPU_INFO_ECX_XTPR_UC 1 << 14 +#define CPUID_CPU_INFO_ECX_PDCM 1 << 15 +// bit 16 is reserved +#define CPUID_CPU_INFO_ECX_PCID 1 << 17 +#define CPUID_CPU_INFO_ECX_DCA 1 << 18 +#define CPUID_CPU_INFO_ECX_SSE4_1 1 << 19 +#define CPUID_CPU_INFO_ECX_SSE4_2 1 << 20 +#define CPUID_CPU_INFO_ECX_X2APIC 1 << 21 +#define CPUID_CPU_INFO_ECX_MOVBE 1 << 22 +#define CPUID_CPU_INFO_ECX_POPCNT 1 << 23 +#define CPUID_CPU_INFO_ECX_TSC_DEADLINE 1 << 24 +#define CPUID_CPU_INFO_ECX_AESNI 1 << 25 +#define CPUID_CPU_INFO_ECX_XSAVE 1 << 26 +#define CPUID_CPU_INFO_ECX_OSXSAVE 1 << 27 +#define CPUID_CPU_INFO_ECX_AVX 1 << 28 +#define CPUID_CPU_INFO_ECX_F16C 1 << 29 +#define CPUID_CPU_INFO_ECX_RDRAND 1 << 30 +// bit 31 is unused -#define CPUID_CPU_INFO_EDX_FPU 1 << 0 -#define CPUID_CPU_INFO_EDX_VME 1 << 1 -#define CPUID_CPU_INFO_EDX_DE 1 << 2 -#define CPUID_CPU_INFO_EDX_PSE 1 << 3 -#define CPUID_CPU_INFO_EDX_TSC 1 << 4 -#define CPUID_CPU_INFO_EDX_MSR 1 << 5 -#define CPUID_CPU_INFO_EDX_PAE 1 << 6 -#define CPUID_CPU_INFO_EDX_MCE 1 << 7 -#define CPUID_CPU_INFO_EDX_CX8 1 << 8 -#define CPUID_CPU_INFO_EDX_APIC 1 << 9 -//bit 10 is reserved -#define CPUID_CPU_INFO_EDX_SEP 1 << 11 -#define CPUID_CPU_INFO_EDX_MTRR 1 << 12 -#define CPUID_CPU_INFO_EDX_PGE 1 << 13 -#define CPUID_CPU_INFO_EDX_MCA 1 << 14 -#define CPUID_CPU_INFO_EDX_CMOV 1 << 15 -#define CPUID_CPU_INFO_EDX_PAT 1 << 16 -#define CPUID_CPU_INFO_EDX_PSE_36 1 << 17 -#define CPUID_CPU_INFO_EDX_PSN 1 << 18 -#define CPUID_CPU_INFO_EDX_CLFSH 1 << 19 -//bit 20 is reserved -#define CPUID_CPU_INFO_EDX_DS 1 << 21 -#define CPUID_CPU_INFO_EDX_ACPI 1 << 22 -#define CPUID_CPU_INFO_EDX_MMX 1 << 23 -#define CPUID_CPU_INFO_EDX_FXSR 1 << 24 -#define CPUID_CPU_INFO_EDX_SSE 1 << 25 -#define CPUID_CPU_INFO_EDX_SSE2 1 << 26 -#define CPUID_CPU_INFO_EDX_SS 1 << 27 -#define CPUID_CPU_INFO_EDX_HTT 1 << 28 -#define CPUID_CPU_INFO_EDX_TM 1 << 29 -//bit 30 is reserved -#define CPUID_CPU_INFO_EDX_PBE 1 << 31 +#define CPUID_CPU_INFO_EDX_FPU 1 << 0 +#define CPUID_CPU_INFO_EDX_VME 1 << 1 +#define CPUID_CPU_INFO_EDX_DE 1 << 2 +#define CPUID_CPU_INFO_EDX_PSE 1 << 3 +#define CPUID_CPU_INFO_EDX_TSC 1 << 4 +#define CPUID_CPU_INFO_EDX_MSR 1 << 5 +#define CPUID_CPU_INFO_EDX_PAE 1 << 6 +#define CPUID_CPU_INFO_EDX_MCE 1 << 7 +#define CPUID_CPU_INFO_EDX_CX8 1 << 8 +#define CPUID_CPU_INFO_EDX_APIC 1 << 9 +// bit 10 is reserved +#define CPUID_CPU_INFO_EDX_SEP 1 << 11 +#define CPUID_CPU_INFO_EDX_MTRR 1 << 12 +#define CPUID_CPU_INFO_EDX_PGE 1 << 13 +#define CPUID_CPU_INFO_EDX_MCA 1 << 14 +#define CPUID_CPU_INFO_EDX_CMOV 1 << 15 +#define CPUID_CPU_INFO_EDX_PAT 1 << 16 +#define CPUID_CPU_INFO_EDX_PSE_36 1 << 17 +#define CPUID_CPU_INFO_EDX_PSN 1 << 18 +#define CPUID_CPU_INFO_EDX_CLFSH 1 << 19 +// bit 20 is reserved +#define CPUID_CPU_INFO_EDX_DS 1 << 21 +#define CPUID_CPU_INFO_EDX_ACPI 1 << 22 +#define CPUID_CPU_INFO_EDX_MMX 1 << 23 +#define CPUID_CPU_INFO_EDX_FXSR 1 << 24 +#define CPUID_CPU_INFO_EDX_SSE 1 << 25 +#define CPUID_CPU_INFO_EDX_SSE2 1 << 26 +#define CPUID_CPU_INFO_EDX_SS 1 << 27 +#define CPUID_CPU_INFO_EDX_HTT 1 << 28 +#define CPUID_CPU_INFO_EDX_TM 1 << 29 +// bit 30 is reserved +#define CPUID_CPU_INFO_EDX_PBE 1 << 31 //===============CPUID_CACHE_TLB=============== -//WARNING: I gave up and used ChatGPT for these +// WARNING: I gave up and used ChatGPT for these #define CPUID_CACHE_TLB_DESC_NULL 0x00 #define CPUID_CACHE_TLB_DESC_TLB_4_KBYTE_4WAY_32E 0x01 #define CPUID_CACHE_TLB_DESC_TLB_4_MBYTE_FULLY_2E 0x02 @@ -203,435 +203,445 @@ #define CPUID_CACHE_TLB_DESC_NO_CACHE_INFO_CPUID_LEAF_4 0xFF //=============CPUID_SERIAL_NUMBER============= -#define CPUID_SERIAL_NUMBER_STITCH(ECX,EDX) (uint64_t)((EDX << 32) | ECX) +#define CPUID_SERIAL_NUMBER_STITCH(ECX, EDX) (uint64_t)((EDX << 32) | ECX) //=============CPUID_CACHE_PARAMS============== -#define CPUID_CACHE_PARAMS_EAX_CACHE_TYPE 0xF -#define CPUID_CACHE_PARAMS_EAX_CACHE_LEVEL 0x7 << 4 -#define CPUID_CACHE_PARAMS_EAX_IS_SELF_INIT 1 << 8 -#define CPUID_CACHE_PARAMS_EAX_IS_FULLY_ASSOCIATIVE 1 << 9 +#define CPUID_CACHE_PARAMS_EAX_CACHE_TYPE 0xF +#define CPUID_CACHE_PARAMS_EAX_CACHE_LEVEL 0x7 << 4 +#define CPUID_CACHE_PARAMS_EAX_IS_SELF_INIT 1 << 8 +#define CPUID_CACHE_PARAMS_EAX_IS_FULLY_ASSOCIATIVE 1 << 9 // bits 10-13 are reserved -#define CPUID_CACHE_PARAMS_EAX_MAX_PROC_SHARING 0xFFF << 14 +#define CPUID_CACHE_PARAMS_EAX_MAX_PROC_SHARING 0xFFF << 14 -#define CPUID_CACHE_PARAMS_EAX_CACHE_TYPE_NULL 0x0 -#define CPUID_CACHE_PARAMS_EAX_CACHE_TYPE_DATA 0x1 +#define CPUID_CACHE_PARAMS_EAX_CACHE_TYPE_NULL 0x0 +#define CPUID_CACHE_PARAMS_EAX_CACHE_TYPE_DATA 0x1 #define CPUID_CACHE_PARAMS_EAX_CACHE_TYPE_INSTRUCTION 0x2 -#define CPUID_CACHE_PARAMS_EAX_CACHE_TYPE_UNIFIED 0x3 +#define CPUID_CACHE_PARAMS_EAX_CACHE_TYPE_UNIFIED 0x3 -#define CPUID_CACHE_PARAMS_EBX_COHERENCY_LINE_SIZE 0xFFF -#define CPUID_CACHE_PARAMS_EBX_PHYS_LINE_PARTITIONS 0x3FF << 12 -#define CPUID_CACHE_PARAMS_EBX_WAYS_OF_ASSOCIVITY 0x3FF +#define CPUID_CACHE_PARAMS_EBX_COHERENCY_LINE_SIZE 0xFFF +#define CPUID_CACHE_PARAMS_EBX_PHYS_LINE_PARTITIONS 0x3FF << 12 +#define CPUID_CACHE_PARAMS_EBX_WAYS_OF_ASSOCIVITY 0x3FF -#define CPUID_CACHE_PARAMS_EDX_CACHE_INCLUSIVENESS 1 +#define CPUID_CACHE_PARAMS_EDX_CACHE_INCLUSIVENESS 1 #define CPUID_CACHE_PARAMS_EDX_COMPLEX_CACHE_INDEXING 1 << 1 //=============CPUID_MONITOR_MWAIT============= -#define CPUID_MONITOR_MWAIT_ECX_ENUM_EXTENSIONS 1 -#define CPUID_MONITOR_MWAIT_ECX_BREAK_EVENTS 1 << 1 +#define CPUID_MONITOR_MWAIT_ECX_ENUM_EXTENSIONS 1 +#define CPUID_MONITOR_MWAIT_ECX_BREAK_EVENTS 1 << 1 -#define CPUID_MONITOR_MWAIT_EDX_C0_SUBC_STATES 0xF -#define CPUID_MONITOR_MWAIT_EDX_C1_SUBC_STATES 0xF << 4 -#define CPUID_MONITOR_MWAIT_EDX_C2_SUBC_STATES 0xF << 8 -#define CPUID_MONITOR_MWAIT_EDX_C3_SUBC_STATES 0xF << 12 -#define CPUID_MONITOR_MWAIT_EDX_C4_SUBC_STATES 0xF << 16 -#define CPUID_MONITOR_MWAIT_EDX_C5_SUBC_STATES 0xF << 20 -#define CPUID_MONITOR_MWAIT_EDX_C6_SUBC_STATES 0xF << 24 -#define CPUID_MONITOR_MWAIT_EDX_C7_SUBC_STATES 0xF << 28 +#define CPUID_MONITOR_MWAIT_EDX_C0_SUBC_STATES 0xF +#define CPUID_MONITOR_MWAIT_EDX_C1_SUBC_STATES 0xF << 4 +#define CPUID_MONITOR_MWAIT_EDX_C2_SUBC_STATES 0xF << 8 +#define CPUID_MONITOR_MWAIT_EDX_C3_SUBC_STATES 0xF << 12 +#define CPUID_MONITOR_MWAIT_EDX_C4_SUBC_STATES 0xF << 16 +#define CPUID_MONITOR_MWAIT_EDX_C5_SUBC_STATES 0xF << 20 +#define CPUID_MONITOR_MWAIT_EDX_C6_SUBC_STATES 0xF << 24 +#define CPUID_MONITOR_MWAIT_EDX_C7_SUBC_STATES 0xF << 28 //===========CPUID_THERMAL_AND_POWER=========== -#define CPUID_THERMAL_AND_POWER_EAX_TEMP_SENSOR 1 -#define CPUID_THERMAL_AND_POWER_EAX_TURBO_BOOST 1 << 1 -#define CPUID_THERMAL_AND_POWER_EAX_ARAT 1 << 2 -//Bit 3 is reserved -#define CPUID_THERMAL_AND_POWER_EAX_PLN 1 << 3 -#define CPUID_THERMAL_AND_POWER_EAX_ECMD 1 << 5 -#define CPUID_THERMAL_AND_POWER_EAX_PTM 1 << 6 -#define CPUID_THERMAL_AND_POWER_EAX_HWP 1 << 7 -#define CPUID_THERMAL_AND_POWER_EAX_HWP_NOTIFICATION 1 << 8 -#define CPUID_THERMAL_AND_POWER_EAX_HWP_ACT_WINDOW 1 << 9 -#define CPUID_THERMAL_AND_POWER_EAX_HWP_PERF_PREF 1 << 10 -#define CPUID_THERMAL_AND_POWER_EAX_HWP_PKG_LVL_REQ 1 << 11 -//Bit 12 is reserved -#define CPUID_THERMAL_AND_POWER_EAX_HDC 1 << 13 -#define CPUID_THERMAL_AND_POWER_EAX_TURBO_BOOST_MAX 1 << 14 -#define CPUID_THERMAL_AND_POWER_EAX_HWP_CAPABILITIES 1 << 15 -#define CPUID_THERMAL_AND_POWER_EAX_HWP_PECI 1 << 16 -#define CPUID_THERMAL_AND_POWER_EAX_FLEXIBLE_HWP 1 << 17 -#define CPUID_THERMAL_AND_POWER_EAX_FAST_HWP_REQUEST 1 << 18 -#define CPUID_THERMAL_AND_POWER_EAX_HW_FEEDBACK 1 << 19 -#define CPUID_THERMAL_AND_POWER_EAX_IGNORE_HWP_IDLE 1 << 20 -//Bits 21 and 22 are reserved -#define CPUID_THERMAL_AND_POWER_EAX_THREAD_DIRECTOR 1 << 23 -#define CPUID_THERMAL_AND_POWER_EAX_THERM_INTERRUPT 1 << 24 +#define CPUID_THERMAL_AND_POWER_EAX_TEMP_SENSOR 1 +#define CPUID_THERMAL_AND_POWER_EAX_TURBO_BOOST 1 << 1 +#define CPUID_THERMAL_AND_POWER_EAX_ARAT 1 << 2 +// Bit 3 is reserved +#define CPUID_THERMAL_AND_POWER_EAX_PLN 1 << 3 +#define CPUID_THERMAL_AND_POWER_EAX_ECMD 1 << 5 +#define CPUID_THERMAL_AND_POWER_EAX_PTM 1 << 6 +#define CPUID_THERMAL_AND_POWER_EAX_HWP 1 << 7 +#define CPUID_THERMAL_AND_POWER_EAX_HWP_NOTIFICATION 1 << 8 +#define CPUID_THERMAL_AND_POWER_EAX_HWP_ACT_WINDOW 1 << 9 +#define CPUID_THERMAL_AND_POWER_EAX_HWP_PERF_PREF 1 << 10 +#define CPUID_THERMAL_AND_POWER_EAX_HWP_PKG_LVL_REQ 1 << 11 +// Bit 12 is reserved +#define CPUID_THERMAL_AND_POWER_EAX_HDC 1 << 13 +#define CPUID_THERMAL_AND_POWER_EAX_TURBO_BOOST_MAX 1 << 14 +#define CPUID_THERMAL_AND_POWER_EAX_HWP_CAPABILITIES 1 << 15 +#define CPUID_THERMAL_AND_POWER_EAX_HWP_PECI 1 << 16 +#define CPUID_THERMAL_AND_POWER_EAX_FLEXIBLE_HWP 1 << 17 +#define CPUID_THERMAL_AND_POWER_EAX_FAST_HWP_REQUEST 1 << 18 +#define CPUID_THERMAL_AND_POWER_EAX_HW_FEEDBACK 1 << 19 +#define CPUID_THERMAL_AND_POWER_EAX_IGNORE_HWP_IDLE 1 << 20 +// Bits 21 and 22 are reserved +#define CPUID_THERMAL_AND_POWER_EAX_THREAD_DIRECTOR 1 << 23 +#define CPUID_THERMAL_AND_POWER_EAX_THERM_INTERRUPT 1 << 24 -#define CPUID_THERMAL_AND_POWER_EBX_INT_TRESHOLD 0xf +#define CPUID_THERMAL_AND_POWER_EBX_INT_TRESHOLD 0xf #define CPUID_THERMAL_AND_POWER_ECX_HW_COORD_FEEDBACK 1 -#define CPUID_THERMAL_AND_POWER_ECX_ENERGY_PERF_BIAS 1 << 3 -#define CPUID_THERMAL_AND_POWER_ECX_TD_CLASSES 0xff << 8 +#define CPUID_THERMAL_AND_POWER_ECX_ENERGY_PERF_BIAS 1 << 3 +#define CPUID_THERMAL_AND_POWER_ECX_TD_CLASSES 0xff << 8 -#define CPUID_THERMAL_AND_POWER_EDX_PERF_REPORT 1 -#define CPUID_THERMAL_AND_POWER_EDX_EFFICIENCY_REPORT 1 << 1 -#define CPUID_THERMAL_AND_POWER_EDX_HW_FEEDBACK_SIZE 0xf << 8 -#define CPUID_THERMAL_AND_POWER_EDX_THIS_PROC_HW_FB 0xffff << 16 +#define CPUID_THERMAL_AND_POWER_EDX_PERF_REPORT 1 +#define CPUID_THERMAL_AND_POWER_EDX_EFFICIENCY_REPORT 1 << 1 +#define CPUID_THERMAL_AND_POWER_EDX_HW_FEEDBACK_SIZE 0xf << 8 +#define CPUID_THERMAL_AND_POWER_EDX_THIS_PROC_HW_FB 0xffff << 16 //===========CPUID_EXTENDED_FEATURES=========== -#define CPUID_EXTENDED_FEATURES_EBX_FSGSBASE 1 -#define CPUID_EXTENDED_FEATURES_EBX_TSC_ADJUST 1 << 1 -#define CPUID_EXTENDED_FEATURES_EBX_SGX 1 << 2 -#define CPUID_EXTENDED_FEATURES_EBX_BMI1 1 << 3 -#define CPUID_EXTENDED_FEATURES_EBX_HLE 1 << 4 -#define CPUID_EXTENDED_FEATURES_EBX_AVX2 1 << 5 -#define CPUID_EXTENDED_FEATURES_EBX_FDP_EXCPTN_ONLY 1 << 6 -#define CPUID_EXTENDED_FEATURES_EBX_SMEP 1 << 7 -#define CPUID_EXTENDED_FEATURES_EBX_BMI2 1 << 8 -#define CPUID_EXTENDED_FEATURES_EBX_ENHANCED_REP 1 << 9 -#define CPUID_EXTENDED_FEATURES_EBX_INVCIP 1 << 10 -#define CPUID_EXTENDED_FEATURES_EBX_RTM 1 << 11 -#define CPUID_EXTENDED_FEATURES_EBX_RDT_M 1 << 12 -#define CPUID_EXTENDED_FEATURES_EBX_NO_FPU_CS 1 << 13 -#define CPUID_EXTENDED_FEATURES_EBX_MPX 1 << 14 -#define CPUID_EXTENDED_FEATURES_EBX_RDT_A 1 << 15 -#define CPUID_EXTENDED_FEATURES_EBX_AVX512F 1 << 16 -#define CPUID_EXTENDED_FEATURES_EBX_AVX512DQ 1 << 17 -#define CPUID_EXTENDED_FEATURES_EBX_RDSEED 1 << 18 -#define CPUID_EXTENDED_FEATURES_EBX_ADX 1 << 19 -#define CPUID_EXTENDED_FEATURES_EBX_SMAP 1 << 20 -#define CPUID_EXTENDED_FEATURES_EBX_AVX512_IFMA 1 << 21 +#define CPUID_EXTENDED_FEATURES_EBX_FSGSBASE 1 +#define CPUID_EXTENDED_FEATURES_EBX_TSC_ADJUST 1 << 1 +#define CPUID_EXTENDED_FEATURES_EBX_SGX 1 << 2 +#define CPUID_EXTENDED_FEATURES_EBX_BMI1 1 << 3 +#define CPUID_EXTENDED_FEATURES_EBX_HLE 1 << 4 +#define CPUID_EXTENDED_FEATURES_EBX_AVX2 1 << 5 +#define CPUID_EXTENDED_FEATURES_EBX_FDP_EXCPTN_ONLY 1 << 6 +#define CPUID_EXTENDED_FEATURES_EBX_SMEP 1 << 7 +#define CPUID_EXTENDED_FEATURES_EBX_BMI2 1 << 8 +#define CPUID_EXTENDED_FEATURES_EBX_ENHANCED_REP 1 << 9 +#define CPUID_EXTENDED_FEATURES_EBX_INVCIP 1 << 10 +#define CPUID_EXTENDED_FEATURES_EBX_RTM 1 << 11 +#define CPUID_EXTENDED_FEATURES_EBX_RDT_M 1 << 12 +#define CPUID_EXTENDED_FEATURES_EBX_NO_FPU_CS 1 << 13 +#define CPUID_EXTENDED_FEATURES_EBX_MPX 1 << 14 +#define CPUID_EXTENDED_FEATURES_EBX_RDT_A 1 << 15 +#define CPUID_EXTENDED_FEATURES_EBX_AVX512F 1 << 16 +#define CPUID_EXTENDED_FEATURES_EBX_AVX512DQ 1 << 17 +#define CPUID_EXTENDED_FEATURES_EBX_RDSEED 1 << 18 +#define CPUID_EXTENDED_FEATURES_EBX_ADX 1 << 19 +#define CPUID_EXTENDED_FEATURES_EBX_SMAP 1 << 20 +#define CPUID_EXTENDED_FEATURES_EBX_AVX512_IFMA 1 << 21 // Bit 22 is reserved -#define CPUID_EXTENDED_FEATURES_EBX_CLFLUSHOPT 1 << 23 -#define CPUID_EXTENDED_FEATURES_EBX_CLWB 1 << 24 -#define CPUID_EXTENDED_FEATURES_EBX_TRACE 1 << 25 -#define CPUID_EXTENDED_FEATURES_EBX_AVX512PF 1 << 26 -#define CPUID_EXTENDED_FEATURES_EBX_AVX512ER 1 << 27 -#define CPUID_EXTENDED_FEATURES_EBX_AVX512CD 1 << 28 -#define CPUID_EXTENDED_FEATURES_EBX_SHA 1 << 29 -#define CPUID_EXTENDED_FEATURES_EBX_AVX512BW 1 << 30 -#define CPUID_EXTENDED_FEATURES_EBX_AVX512VL 1 << 31 +#define CPUID_EXTENDED_FEATURES_EBX_CLFLUSHOPT 1 << 23 +#define CPUID_EXTENDED_FEATURES_EBX_CLWB 1 << 24 +#define CPUID_EXTENDED_FEATURES_EBX_TRACE 1 << 25 +#define CPUID_EXTENDED_FEATURES_EBX_AVX512PF 1 << 26 +#define CPUID_EXTENDED_FEATURES_EBX_AVX512ER 1 << 27 +#define CPUID_EXTENDED_FEATURES_EBX_AVX512CD 1 << 28 +#define CPUID_EXTENDED_FEATURES_EBX_SHA 1 << 29 +#define CPUID_EXTENDED_FEATURES_EBX_AVX512BW 1 << 30 +#define CPUID_EXTENDED_FEATURES_EBX_AVX512VL 1 << 31 -#define CPUID_EXTENDED_FEATURES_ECX_PREFETCHWT1 1 -#define CPUID_EXTENDED_FEATURES_ECX_AFX512_VBMI 1 << 1 -#define CPUID_EXTENDED_FEATURES_ECX_UMIP 1 << 2 -#define CPUID_EXTENDED_FEATURES_ECX_PKU 1 << 3 -#define CPUID_EXTENDED_FEATURES_ECX_OSPKE 1 << 4 -#define CPUID_EXTENDED_FEATURES_ECX_WAITPKG 1 << 5 -#define CPUID_EXTENDED_FEATURES_ECX_AVX512_VBMI2 1 << 6 -#define CPUID_EXTENDED_FEATURES_ECX_CET_SS 1 << 7 -#define CPUID_EXTENDED_FEATURES_ECX_GFNI 1 << 8 -#define CPUID_EXTENDED_FEATURES_ECX_VAES 1 << 9 -#define CPUID_EXTENDED_FEATURES_ECX_VPCLMULQDQ 1 << 10 -#define CPUID_EXTENDED_FEATURES_ECX_AVX512_VNNI 1 << 11 -#define CPUID_EXTENDED_FEATURES_ECX_AVX512_BITLANG 1 << 12 -#define CPUID_EXTENDED_FEATURES_ECX_TME_EN 1 << 13 -#define CPUID_EXTENDED_FEATURES_ECX_AVX512_VPOPVNZDQ 1 << 14 -//bit 15 is reserved -#define CPUID_EXTENDED_FEATURES_ECX_LA57 1 << 16 -#define CPUID_EXTENDED_FEATURES_ECX_MAWAU_VAL 0x1F << 17 -#define CPUID_EXTENDED_FEATURES_ECX_RDPID 1 << 22 -#define CPUID_EXTENDED_FEATURES_ECX_KL 1 << 23 -#define CPUID_EXTENDED_FEATURES_ECX_BUS_LOCK_DETECT 1 << 24 -#define CPUID_EXTENDED_FEATURES_ECX_CLDEMOTE 1 << 25 -//bit 26 is reserved -#define CPUID_EXTENDED_FEATURES_ECX_MOVDIRI 1 << 27 -#define CPUID_EXTENDED_FEATURES_ECX_MOVDIR64B 1 << 28 -#define CPUID_EXTENDED_FEATURES_ECX_ENQCMD 1 << 29 -#define CPUID_EXTENDED_FEATURES_ECX_SGX_LC 1 << 30 -#define CPUID_EXTENDED_FEATURES_ECX_PKS 1 << 31 +#define CPUID_EXTENDED_FEATURES_ECX_PREFETCHWT1 1 +#define CPUID_EXTENDED_FEATURES_ECX_AFX512_VBMI 1 << 1 +#define CPUID_EXTENDED_FEATURES_ECX_UMIP 1 << 2 +#define CPUID_EXTENDED_FEATURES_ECX_PKU 1 << 3 +#define CPUID_EXTENDED_FEATURES_ECX_OSPKE 1 << 4 +#define CPUID_EXTENDED_FEATURES_ECX_WAITPKG 1 << 5 +#define CPUID_EXTENDED_FEATURES_ECX_AVX512_VBMI2 1 << 6 +#define CPUID_EXTENDED_FEATURES_ECX_CET_SS 1 << 7 +#define CPUID_EXTENDED_FEATURES_ECX_GFNI 1 << 8 +#define CPUID_EXTENDED_FEATURES_ECX_VAES 1 << 9 +#define CPUID_EXTENDED_FEATURES_ECX_VPCLMULQDQ 1 << 10 +#define CPUID_EXTENDED_FEATURES_ECX_AVX512_VNNI 1 << 11 +#define CPUID_EXTENDED_FEATURES_ECX_AVX512_BITLANG 1 << 12 +#define CPUID_EXTENDED_FEATURES_ECX_TME_EN 1 << 13 +#define CPUID_EXTENDED_FEATURES_ECX_AVX512_VPOPVNZDQ 1 << 14 +// bit 15 is reserved +#define CPUID_EXTENDED_FEATURES_ECX_LA57 1 << 16 +#define CPUID_EXTENDED_FEATURES_ECX_MAWAU_VAL 0x1F << 17 +#define CPUID_EXTENDED_FEATURES_ECX_RDPID 1 << 22 +#define CPUID_EXTENDED_FEATURES_ECX_KL 1 << 23 +#define CPUID_EXTENDED_FEATURES_ECX_BUS_LOCK_DETECT 1 << 24 +#define CPUID_EXTENDED_FEATURES_ECX_CLDEMOTE 1 << 25 +// bit 26 is reserved +#define CPUID_EXTENDED_FEATURES_ECX_MOVDIRI 1 << 27 +#define CPUID_EXTENDED_FEATURES_ECX_MOVDIR64B 1 << 28 +#define CPUID_EXTENDED_FEATURES_ECX_ENQCMD 1 << 29 +#define CPUID_EXTENDED_FEATURES_ECX_SGX_LC 1 << 30 +#define CPUID_EXTENDED_FEATURES_ECX_PKS 1 << 31 -//bit 0 is reserved -#define CPUID_EXTENDED_FEATURES_EDX_SGX_KEYS 1 << 1 -#define CPUID_EXTENDED_FEATURES_EDX_AVX512_4VNNIW 1 << 2 -#define CPUID_EXTENDED_FEATURES_EDX_AVX512_4FMAPS 1 << 3 -#define CPUID_EXTENDED_FEATURES_EDX_FAST_REP_MOV 1 << 4 -#define CPUID_EXTENDED_FEATURES_EDX_UINTR 1 << 5 -//bits 6 and 7 are reserved -#define CPUID_EXTENDED_FEATURES_EDX_AVX512_VPINTERSECT 1 << 8 // intel you son of a bitch -#define CPUID_EXTENDED_FEATURES_EDX_SRBDS_CTRL 1 << 9 -#define CPUID_EXTENDED_FEATURES_EDX_MD_CLEAR 1 << 10 -#define CPUID_EXTENDED_FEATURES_EDX_RTM_ALWAYS_ABORT 1 << 11 -//bit 12 is reserved -#define CPUID_EXTENDED_FEATURES_EDX_RTM_FORCE_ABORT 1 << 13 -#define CPUID_EXTENDED_FEATURES_EDX_SERIALIZE 1 << 14 -#define CPUID_EXTENDED_FEATURES_EDX_HYBRID 1 << 15 -#define CPUID_EXTENDED_FEATURES_EDX_TSXLDTRK 1 << 16 -//bit 17 is reserved -#define CPUID_EXTENDED_FEATURES_EDX_PCONFIG 1 << 18 +// bit 0 is reserved +#define CPUID_EXTENDED_FEATURES_EDX_SGX_KEYS 1 << 1 +#define CPUID_EXTENDED_FEATURES_EDX_AVX512_4VNNIW 1 << 2 +#define CPUID_EXTENDED_FEATURES_EDX_AVX512_4FMAPS 1 << 3 +#define CPUID_EXTENDED_FEATURES_EDX_FAST_REP_MOV 1 << 4 +#define CPUID_EXTENDED_FEATURES_EDX_UINTR 1 << 5 +// bits 6 and 7 are reserved +#define CPUID_EXTENDED_FEATURES_EDX_AVX512_VPINTERSECT \ + 1 << 8 // intel you son of a bitch +#define CPUID_EXTENDED_FEATURES_EDX_SRBDS_CTRL 1 << 9 +#define CPUID_EXTENDED_FEATURES_EDX_MD_CLEAR 1 << 10 +#define CPUID_EXTENDED_FEATURES_EDX_RTM_ALWAYS_ABORT 1 << 11 +// bit 12 is reserved +#define CPUID_EXTENDED_FEATURES_EDX_RTM_FORCE_ABORT 1 << 13 +#define CPUID_EXTENDED_FEATURES_EDX_SERIALIZE 1 << 14 +#define CPUID_EXTENDED_FEATURES_EDX_HYBRID 1 << 15 +#define CPUID_EXTENDED_FEATURES_EDX_TSXLDTRK 1 << 16 +// bit 17 is reserved +#define CPUID_EXTENDED_FEATURES_EDX_PCONFIG 1 << 18 #define CPUID_EXTENDED_FEATURES_EDX_ARCHITECTURAL_LBR 1 << 19 -#define CPUID_EXTENDED_FEATURES_EDX_CET_IBT 1 << 20 -//bit 21 is reserved -#define CPUID_EXTENDED_FEATURES_EDX_AMX_BF16 1 << 22 -#define CPUID_EXTENDED_FEATURES_EDX_AVX512_FP16 1 << 23 -#define CPUID_EXTENDED_FEATURES_EDX_AMX_TILE 1 << 24 -#define CPUID_EXTENDED_FEATURES_EDX_AMX_INT8 1 << 25 -#define CPUID_EXTENDED_FEATURES_EDX_IBRS 1 << 26 -#define CPUID_EXTENDED_FEATURES_EDX_STIBP 1 << 27 -#define CPUID_EXTENDED_FEATURES_EDX_L1D_FLUSH 1 << 28 -#define CPUID_EXTENDED_FEATURES_EDX_ARCH_CAPABS_MSR 1 << 29 -#define CPUID_EXTENDED_FEATURES_EDX_CORE_CAPABS_MSR 1 << 30 -#define CPUID_EXTENDED_FEATURES_EDX_SSBD 1 << 31 +#define CPUID_EXTENDED_FEATURES_EDX_CET_IBT 1 << 20 +// bit 21 is reserved +#define CPUID_EXTENDED_FEATURES_EDX_AMX_BF16 1 << 22 +#define CPUID_EXTENDED_FEATURES_EDX_AVX512_FP16 1 << 23 +#define CPUID_EXTENDED_FEATURES_EDX_AMX_TILE 1 << 24 +#define CPUID_EXTENDED_FEATURES_EDX_AMX_INT8 1 << 25 +#define CPUID_EXTENDED_FEATURES_EDX_IBRS 1 << 26 +#define CPUID_EXTENDED_FEATURES_EDX_STIBP 1 << 27 +#define CPUID_EXTENDED_FEATURES_EDX_L1D_FLUSH 1 << 28 +#define CPUID_EXTENDED_FEATURES_EDX_ARCH_CAPABS_MSR 1 << 29 +#define CPUID_EXTENDED_FEATURES_EDX_CORE_CAPABS_MSR 1 << 30 +#define CPUID_EXTENDED_FEATURES_EDX_SSBD 1 << 31 //=========CPUID_EXTENDED_FEATURES_SL1========= -//bits 0-3 are reserved -#define CPUID_EXTENDED_FEATURES_SL1_EAX_AVX_VNNI 1 << 4 -#define CPUID_EXTENDED_FEATURES_SL1_EAX_AVX512_BF16 1 << 5 -//bits 6-9 are reserved -#define CPUID_EXTENDED_FEATURES_SL1_EAX_0_REP_MOVSB 1 << 10 -#define CPUID_EXTENDED_FEATURES_SL1_EAX_FAST_STOSB 1 << 11 -#define CPUID_EXTENDED_FEATURES_SL1_EAX_FAST_CMPSB 1 << 12 -//bits 13-21 are reserved -#define CPUID_EXTENDED_FEATURES_SL1_EAX_HRESET 1 << 22 -//bits 23-19 are reserved +// bits 0-3 are reserved +#define CPUID_EXTENDED_FEATURES_SL1_EAX_AVX_VNNI 1 << 4 +#define CPUID_EXTENDED_FEATURES_SL1_EAX_AVX512_BF16 1 << 5 +// bits 6-9 are reserved +#define CPUID_EXTENDED_FEATURES_SL1_EAX_0_REP_MOVSB 1 << 10 +#define CPUID_EXTENDED_FEATURES_SL1_EAX_FAST_STOSB 1 << 11 +#define CPUID_EXTENDED_FEATURES_SL1_EAX_FAST_CMPSB 1 << 12 +// bits 13-21 are reserved +#define CPUID_EXTENDED_FEATURES_SL1_EAX_HRESET 1 << 22 +// bits 23-19 are reserved #define CPUID_EXTENDED_FEATURES_SL1_EAX_INVD_POSTPOST 1 << 30 -//bit 31 is reserved +// bit 31 is reserved -#define CPUID_EXTENDED_FEATURES_SL1_EBX_PPIN 1 +#define CPUID_EXTENDED_FEATURES_SL1_EBX_PPIN 1 -#define CPUID_EXTENDED_FEATURES_SL1_EDX_CET_SSS 1 << 18 +#define CPUID_EXTENDED_FEATURES_SL1_EDX_CET_SSS 1 << 18 //=========CPUID_EXTENDED_FEATURES_SL2========= -#define CPUID_EXTENDED_FEATURES_SL2_EDX_PSFD 1 -#define CPUID_EXTENDED_FEATURES_SL2_EDX_IPRED_CTRL 1 << 1 -#define CPUID_EXTENDED_FEATURES_SL2_EDX_RRSBA_CTRL 1 << 2 -#define CPUID_EXTENDED_FEATURES_SL2_EDX_DDPD_U 1 << 3 -#define CPUID_EXTENDED_FEATURES_SL2_EDX_BHI_CTRL 1 << 4 -//The rest of the bits are reserved - +#define CPUID_EXTENDED_FEATURES_SL2_EDX_PSFD 1 +#define CPUID_EXTENDED_FEATURES_SL2_EDX_IPRED_CTRL 1 << 1 +#define CPUID_EXTENDED_FEATURES_SL2_EDX_RRSBA_CTRL 1 << 2 +#define CPUID_EXTENDED_FEATURES_SL2_EDX_DDPD_U 1 << 3 +#define CPUID_EXTENDED_FEATURES_SL2_EDX_BHI_CTRL 1 << 4 +// The rest of the bits are reserved enum leaves { - /* @ Basic CPU info - * @ Returned EAX: Highest basic CPUID leaf present - * @ Returned EBX: First 4 letters of the vendor identifier string - * @ Returned ECX: Third 4 letters of the vendor identifier string - * @ Retruned EDX: Second 4 letters of the vendor identifier string - */ - CPUID_VENDOR = 0x00000000, - /* @ CPU Version information - * @ Returned EAX: Family,Model,Stepping - * @ Returned EBX: Brand Index,CLFLUSH line size, Max number of logical processors - * @ Returned ECX: Featrue information - * @ Retruned EDX: More feature information - */ - CPUID_CPU_INFO = 0x00000001, - /* @ CPU Cache and TLB information - * @ Returned EAX: 4 Cache, prefetch or TLB descriptors - * @ Returned EBX: 4 Cache, prefetch or TLB descriptors - * @ Returned ECX: 4 Cache, prefetch or TLB descriptors - * @ Retruned EDX: 4 Cache, prefetch or TLB descriptors - */ - CPUID_CACHE_TLB = 0x00000002, - /* @ CPU Serial Number !!! PENTIUM 3 ONLY !!! - * @ Returned EAX: Reserved - * @ Returned EBX: Reserved - * @ Returned ECX: bits 0-31 of the serial number - * @ Retruned EDX: bits 32-63 of the serial number - */ - CPUID_SERIAL_NUMBER = 0x00000003, - /* @ CPU Deterministic cache parameters !!! Initial ECX = Cache level !!! - * @ Returned EAX: Cache level,Is self init,Is fully associative,Maximum number of addressable IDs for logical processors sharing this cache - * @ Returned EBX: L, P and W - * @ Returned ECX: S - * @ Retruned EDX: Cache inclusiveness and Complex Cache indexing - */ - CPUID_CACHE_PARAMS = 0x00000004, - /* @ MONITOR/MWAIT params - * @ Returned EAX: Smallest monitor-line size - * @ Returned EBX: Largest monitor-line size - * @ Returned ECX: Enumeration of Monitor-Mwait extensions,Supports treating interrupts as break-event for MWAIT - * @ Retruned EDX: Number of sub C-states supported using MWAIT for each C number thingy IDK - */ - CPUID_MONITOR_MWAIT = 0x00000005, - /* @ Thermal and power managment - * @ Returned EAX: Thermal and power info - * @ Returned EBX: Thermal and power info - * @ Returned ECX: Thermal and power info - * @ Retruned EDX: Thermal and power info - */ - CPUID_THERMAL_AND_POWER = 0x00000006, - /* @ Extended features - * @ Returned EAX: Number of subleaves supported - * @ Returned EBX: Features - * @ Returned ECX: Features - * @ Retruned EDX: Features - */ - CPUID_EXTENDED_FEATURES = 0x00000007, - /* @ Direct Cache Access Information - * @ Returned EAX: Value of the MSR "IA32_PLATFORM_DCA_CAP" - * @ Returned EBX: Reserved - * @ Returned ECX: Reserved - * @ Retruned EDX: Reserved - */ - CPUID_CACHE_ACCESS_INFO = 0x00000009, - CPUID_PERFORMANCE_MONITORING = 0x0000000A, - CPUID_EXTENDENDED_TOPOLOGY = 0x0000000B, - CPUID_EXTENDENDED_TOPOLOGY2 = 0x0000000D, - CPUID_INTEL_RDT = 0x0000000F, - CPUID_INTEL_RDT2 = 0x00000010, - CPUID_INTEL_SGX = 0x00000012, - CPUID_CPU_TRACE_ENUM = 0x00000014, - CPUID_TSC = 0x00000015, - CPUID_CPU_FREQ_INFO = 0x00000016, - CPUID_SOC_VENDOR = 0x00000017, - CPUID_DETERMINISTIC_ADRESS_TRANSLATION_PARAMS = 0x00000018, - CPUID_KEY_LOCKER = 0x000000019, - CPUID_NATIVE_MODEL_ID = 0x0000001A, - CPUID_PCONFIG_INFO = 0x0000001B, - CPUID_LAST_BRACH = 0x00000001C, - CPUID_TILE_INFO = 0x00000001D, - CPUID_TMUL_INFO = 0x00000001E, - CPUID_V2_EXTENDED_TOPOLOGY = 0x00000001F, - CPUID_V2_EXTENDED_TOPOLOGY2 = 0x000000020, - //TODO: add the bitmasks for these Microsoft ones - /* @ Hypervisor CPUID Leaf Range - * @ Returned EAX: Highest hypervisor CPUID leaf present - * @ Returned EBX: Largest monitor-line size - * @ Returned ECX: Enumeration of Monitor-Mwait extensions,Supports treating interrupts as break-event for MWAIT - * @ Retruned EDX: Number of sub C-states supported using MWAIT for each C number thingy IDK - */ - CPUID_HYPERV_IDENT = 0x40000000, - /* @ Hypervisor Vendor-Neutral Interface Identification - * @ Returned EAX: Hypervisor interface signature - * @ Returned EBX: Reserved - * @ Returned ECX: Reserved - * @ Retruned EDX: Reserved - */ - CPUID_MS_HYPERV_INTERFCE_IDENT = 0x40000001, - /* @ Hypervisor System Identity - * @ Returned EAX: Build number - * @ Returned EBX: Major and minor version - * @ Returned ECX: Reserved - * @ Retruned EDX: Reserved - */ - CPUID_MS_HYPERV_SYSTEM_IDENT = 0x40000002, - /* @ Hypervisor Feature Identification - * @ Returned EAX: bits 0-31 of HV_PARTITION_PRIVILEGE_MASK - * @ Returned EBX: bits 31-63 of HV_PARTITION_PRIVILEGE_MASK - * @ Returned ECX: Hyper-V features - * @ Retruned EDX: Hyper-V features - */ - CPUID_MS_HYPERV_FEATURE_IDENT = 0x40000003, - /* @ Implementation Recommendations - * @ Returned EAX: Hyper-V feature recommendations - * @ Returned EBX: Hyper-V feature recommendations - * @ Returned ECX: Hyper-V feature recommendations - * @ Retruned EDX: Reserved - */ - CPUID_MS_HYPERV_RECOMMENDATIONS = 0x40000004, - /* @ Hypervisor Implementation Limits - * @ Returned EAX: The maximum number of virtual processors supported - * @ Returned EBX: The maximum number of logical processors supported - * @ Returned ECX: The maximum number of physical interrupt vectors available for interrupt remapping. - * @ Retruned EDX: Reserved - */ - CPUID_MS_HYPERV_IMPL_LIMITS = 0x40000005, - /* @ Implementation Hardware Features - * @ Returned EAX: Hardware features - * @ Returned EBX: Reserved - * @ Returned ECX: Reserved - * @ Retruned EDX: Reserved - */ - CPUID_MS_HYPERV_HARDWARE_FEATURES = 0x40000006, - /* @ Nested Hypervisor Feature Identification - * @ Returned EAX: Nested Hypervisor features - * @ Returned EBX: Reserved - * @ Returned ECX: Reserved - * @ Retruned EDX: Nested Hypervisor features - */ - CPUID_MS_HYPERV_NESTED_FEATURES = 0x40000009, - /* @ Nested Hypervisor Nested Virtualization Features - * @ Returned EAX: Nested Hypervisor features - * @ Returned EBX: Nested Hypervisor features - * @ Returned ECX: Reserved - * @ Retruned EDX: Reserved - */ - CPUID_MS_HYPERV_NESTED_OPTIMISATIONS = 0x4000000A, - /* @ Extended processor signature - * @ Returned EAX: Reserved - * @ Returned EBX: Reserved - * @ Returned ECX: Extended feature bits - * @ Retruned EDX: Extended feature bits - */ - CPUID_EXTENDED_SIGNATURE = 0x800000001, - /* @ Full CPU name - * @ Returned EAX: First 4 characters of the full CPU name - * @ Returned EBX: Second 4 characters of the full CPU name - * @ Returned ECX: Third 4 characters of the full CPU name - * @ Retruned EDX: Fourth 4 characters of the full CPU name - */ - CPUID_BRAND_STRING1 = 0x800000002, - /* @ Full CPU name 2 - * @ Returned EAX: Fifth 4 characters of the full CPU name - * @ Returned EBX: Sexth 4 characters of the full CPU name - * @ Returned ECX: Seventh 4 characters of the full CPU name - * @ Retruned EDX: Eightth 4 characters of the full CPU name - */ - CPUID_BRAND_STRING2 = 0x800000003, - /* @ Full CPU name 3 - * @ Returned EAX: Nineth 4 characters of the full CPU name - * @ Returned EBX: Tenth 4 characters of the full CPU name - * @ Returned ECX: Eleventh 4 characters of the full CPU name - * @ Retruned EDX: Twelveth 4 characters of the full CPU name - */ - CPUID_BRAND_STRING3 = 0x800000004, - /* @ Cache line size and associativity - * @ Returned EAX: Reserved - * @ Returned EBX: Reserved - * @ Returned ECX: Bits 0-7 = Cache line size in bytes, Bits 12-15 = L2 Associativity, Bits 16-31 = Cache size in 1K blocks - * @ Retruned EDX: Reserved - */ - CPUID_MORE_CACHE = 0x800000006, - /* @ Invariant TSC available - * @ Returned EAX: Reserved - * @ Returned EBX: Reserved - * @ Returned ECX: Bit 8 = Invariant TSC available - * @ Retruned EDX: Reserved - */ - CPUID_INVARIANT_TSC_AVAILABLE = 0x800000007, - /* @ Physical adress size - * @ Returned EAX: Bits 0-7 = Physical Adress bits, Bits 8-15 = Linear Address bits - * @ Returned EBX: Bit 9 = WBNOINVD available - * @ Returned ECX: Reserved - * @ Retruned EDX: Reserved - */ - CPUID_PHYS_ADDR_SIZE = 0x800000008, + /* @ Basic CPU info + * @ Returned EAX: Highest basic CPUID leaf present + * @ Returned EBX: First 4 letters of the vendor identifier string + * @ Returned ECX: Third 4 letters of the vendor identifier string + * @ Retruned EDX: Second 4 letters of the vendor identifier string + */ + CPUID_VENDOR = 0x00000000, + /* @ CPU Version information + * @ Returned EAX: Family,Model,Stepping + * @ Returned EBX: Brand Index,CLFLUSH line size, Max number of logical + * processors + * @ Returned ECX: Featrue information + * @ Retruned EDX: More feature information + */ + CPUID_CPU_INFO = 0x00000001, + /* @ CPU Cache and TLB information + * @ Returned EAX: 4 Cache, prefetch or TLB descriptors + * @ Returned EBX: 4 Cache, prefetch or TLB descriptors + * @ Returned ECX: 4 Cache, prefetch or TLB descriptors + * @ Retruned EDX: 4 Cache, prefetch or TLB descriptors + */ + CPUID_CACHE_TLB = 0x00000002, + /* @ CPU Serial Number !!! PENTIUM 3 ONLY !!! + * @ Returned EAX: Reserved + * @ Returned EBX: Reserved + * @ Returned ECX: bits 0-31 of the serial number + * @ Retruned EDX: bits 32-63 of the serial number + */ + CPUID_SERIAL_NUMBER = 0x00000003, + /* @ CPU Deterministic cache parameters !!! Initial ECX = Cache level !!! + * @ Returned EAX: Cache level,Is self init,Is fully associative,Maximum + * number of addressable IDs for logical processors sharing this cache + * @ Returned EBX: L, P and W + * @ Returned ECX: S + * @ Retruned EDX: Cache inclusiveness and Complex Cache indexing + */ + CPUID_CACHE_PARAMS = 0x00000004, + /* @ MONITOR/MWAIT params + * @ Returned EAX: Smallest monitor-line size + * @ Returned EBX: Largest monitor-line size + * @ Returned ECX: Enumeration of Monitor-Mwait extensions,Supports treating + * interrupts as break-event for MWAIT + * @ Retruned EDX: Number of sub C-states supported using MWAIT for each C + * number thingy IDK + */ + CPUID_MONITOR_MWAIT = 0x00000005, + /* @ Thermal and power managment + * @ Returned EAX: Thermal and power info + * @ Returned EBX: Thermal and power info + * @ Returned ECX: Thermal and power info + * @ Retruned EDX: Thermal and power info + */ + CPUID_THERMAL_AND_POWER = 0x00000006, + /* @ Extended features + * @ Returned EAX: Number of subleaves supported + * @ Returned EBX: Features + * @ Returned ECX: Features + * @ Retruned EDX: Features + */ + CPUID_EXTENDED_FEATURES = 0x00000007, + /* @ Direct Cache Access Information + * @ Returned EAX: Value of the MSR "IA32_PLATFORM_DCA_CAP" + * @ Returned EBX: Reserved + * @ Returned ECX: Reserved + * @ Retruned EDX: Reserved + */ + CPUID_CACHE_ACCESS_INFO = 0x00000009, + CPUID_PERFORMANCE_MONITORING = 0x0000000A, + CPUID_EXTENDENDED_TOPOLOGY = 0x0000000B, + CPUID_EXTENDENDED_TOPOLOGY2 = 0x0000000D, + CPUID_INTEL_RDT = 0x0000000F, + CPUID_INTEL_RDT2 = 0x00000010, + CPUID_INTEL_SGX = 0x00000012, + CPUID_CPU_TRACE_ENUM = 0x00000014, + CPUID_TSC = 0x00000015, + CPUID_CPU_FREQ_INFO = 0x00000016, + CPUID_SOC_VENDOR = 0x00000017, + CPUID_DETERMINISTIC_ADRESS_TRANSLATION_PARAMS = 0x00000018, + CPUID_KEY_LOCKER = 0x000000019, + CPUID_NATIVE_MODEL_ID = 0x0000001A, + CPUID_PCONFIG_INFO = 0x0000001B, + CPUID_LAST_BRACH = 0x00000001C, + CPUID_TILE_INFO = 0x00000001D, + CPUID_TMUL_INFO = 0x00000001E, + CPUID_V2_EXTENDED_TOPOLOGY = 0x00000001F, + CPUID_V2_EXTENDED_TOPOLOGY2 = 0x000000020, + // TODO: add the bitmasks for these Microsoft ones + /* @ Hypervisor CPUID Leaf Range + * @ Returned EAX: Highest hypervisor CPUID leaf present + * @ Returned EBX: Largest monitor-line size + * @ Returned ECX: Enumeration of Monitor-Mwait extensions,Supports treating + * interrupts as break-event for MWAIT + * @ Retruned EDX: Number of sub C-states supported using MWAIT for each C + * number thingy IDK + */ + CPUID_HYPERV_IDENT = 0x40000000, + /* @ Hypervisor Vendor-Neutral Interface Identification + * @ Returned EAX: Hypervisor interface signature + * @ Returned EBX: Reserved + * @ Returned ECX: Reserved + * @ Retruned EDX: Reserved + */ + CPUID_MS_HYPERV_INTERFCE_IDENT = 0x40000001, + /* @ Hypervisor System Identity + * @ Returned EAX: Build number + * @ Returned EBX: Major and minor version + * @ Returned ECX: Reserved + * @ Retruned EDX: Reserved + */ + CPUID_MS_HYPERV_SYSTEM_IDENT = 0x40000002, + /* @ Hypervisor Feature Identification + * @ Returned EAX: bits 0-31 of HV_PARTITION_PRIVILEGE_MASK + * @ Returned EBX: bits 31-63 of HV_PARTITION_PRIVILEGE_MASK + * @ Returned ECX: Hyper-V features + * @ Retruned EDX: Hyper-V features + */ + CPUID_MS_HYPERV_FEATURE_IDENT = 0x40000003, + /* @ Implementation Recommendations + * @ Returned EAX: Hyper-V feature recommendations + * @ Returned EBX: Hyper-V feature recommendations + * @ Returned ECX: Hyper-V feature recommendations + * @ Retruned EDX: Reserved + */ + CPUID_MS_HYPERV_RECOMMENDATIONS = 0x40000004, + /* @ Hypervisor Implementation Limits + * @ Returned EAX: The maximum number of virtual processors supported + * @ Returned EBX: The maximum number of logical processors supported + * @ Returned ECX: The maximum number of physical interrupt vectors available + * for interrupt remapping. + * @ Retruned EDX: Reserved + */ + CPUID_MS_HYPERV_IMPL_LIMITS = 0x40000005, + /* @ Implementation Hardware Features + * @ Returned EAX: Hardware features + * @ Returned EBX: Reserved + * @ Returned ECX: Reserved + * @ Retruned EDX: Reserved + */ + CPUID_MS_HYPERV_HARDWARE_FEATURES = 0x40000006, + /* @ Nested Hypervisor Feature Identification + * @ Returned EAX: Nested Hypervisor features + * @ Returned EBX: Reserved + * @ Returned ECX: Reserved + * @ Retruned EDX: Nested Hypervisor features + */ + CPUID_MS_HYPERV_NESTED_FEATURES = 0x40000009, + /* @ Nested Hypervisor Nested Virtualization Features + * @ Returned EAX: Nested Hypervisor features + * @ Returned EBX: Nested Hypervisor features + * @ Returned ECX: Reserved + * @ Retruned EDX: Reserved + */ + CPUID_MS_HYPERV_NESTED_OPTIMISATIONS = 0x4000000A, + /* @ Extended processor signature + * @ Returned EAX: Reserved + * @ Returned EBX: Reserved + * @ Returned ECX: Extended feature bits + * @ Retruned EDX: Extended feature bits + */ + CPUID_EXTENDED_SIGNATURE = 0x800000001, + /* @ Full CPU name + * @ Returned EAX: First 4 characters of the full CPU name + * @ Returned EBX: Second 4 characters of the full CPU name + * @ Returned ECX: Third 4 characters of the full CPU name + * @ Retruned EDX: Fourth 4 characters of the full CPU name + */ + CPUID_BRAND_STRING1 = 0x800000002, + /* @ Full CPU name 2 + * @ Returned EAX: Fifth 4 characters of the full CPU name + * @ Returned EBX: Sexth 4 characters of the full CPU name + * @ Returned ECX: Seventh 4 characters of the full CPU name + * @ Retruned EDX: Eightth 4 characters of the full CPU name + */ + CPUID_BRAND_STRING2 = 0x800000003, + /* @ Full CPU name 3 + * @ Returned EAX: Nineth 4 characters of the full CPU name + * @ Returned EBX: Tenth 4 characters of the full CPU name + * @ Returned ECX: Eleventh 4 characters of the full CPU name + * @ Retruned EDX: Twelveth 4 characters of the full CPU name + */ + CPUID_BRAND_STRING3 = 0x800000004, + /* @ Cache line size and associativity + * @ Returned EAX: Reserved + * @ Returned EBX: Reserved + * @ Returned ECX: Bits 0-7 = Cache line size in bytes, Bits 12-15 = L2 + * Associativity, Bits 16-31 = Cache size in 1K blocks + * @ Retruned EDX: Reserved + */ + CPUID_MORE_CACHE = 0x800000006, + /* @ Invariant TSC available + * @ Returned EAX: Reserved + * @ Returned EBX: Reserved + * @ Returned ECX: Bit 8 = Invariant TSC available + * @ Retruned EDX: Reserved + */ + CPUID_INVARIANT_TSC_AVAILABLE = 0x800000007, + /* @ Physical adress size + * @ Returned EAX: Bits 0-7 = Physical Adress bits, Bits 8-15 = Linear + * Address bits + * @ Returned EBX: Bit 9 = WBNOINVD available + * @ Returned ECX: Reserved + * @ Retruned EDX: Reserved + */ + CPUID_PHYS_ADDR_SIZE = 0x800000008, }; -enum sub_leaves{ - /* @ Extended features available subleaf 1 !!! All fields return 0 is info not available !!! - * @ Returned EAX: Features - * @ Returned EBX: PPIN - * @ Returned ECX: Reserved - * @ Retruned EDX: CET_SSS - */ - CPUID_EXTENDED_FEATURES_SL1 = 0x00000001, - /* @ Extended features available subleaf 2 !!! All fields return 0 is info not available !!! - * @ Returned EAX: Reserved - * @ Returned EBX: Reserved - * @ Returned ECX: Reserved - * @ Retruned EDX: Features - */ - CPUID_EXTENDED_FEATURES_SL2 = 0x00000002, - CPUID_INTEL_RDT_CAPABILITY = 0x00000001, - CPUID_INTEL_RDT2_ALLOCATION = 0x00000000, - CPUID_INTEL_RDT2_RESID1 = 0x00000001, - CPUID_INTEL_RDT2_RESID2 = 0x00000002, - CPUID_INTEL_RDT2_RESID3 = 0x00000003, - CPUID_INTEL_SGX_SL1 = 0x00000001, - CPUID_INTEL_SGX_SL2 = 0x00000002, - CPUID_CPU_TRACE_ENUM_SL = 0x00000001, - CPUID_SOC_VENDOR_SL1 = 0x00000001, - CPUID_SOC_VENDOR_SL2 = 0x00000002, - CPUID_SOC_VENDOR_SL3 = 0x00000003, - //NOTE: goes higher than 1 - CPUID_DETERMINISTIC_ADRESS_TRANSLATION_PARAMS_SL = 0x00000001, - CPUID_TILE_INFO_PALETTE1 = 0x000000001, +enum sub_leaves { + /* @ Extended features available subleaf 1 !!! All fields return 0 is info not + * available !!! + * @ Returned EAX: Features + * @ Returned EBX: PPIN + * @ Returned ECX: Reserved + * @ Retruned EDX: CET_SSS + */ + CPUID_EXTENDED_FEATURES_SL1 = 0x00000001, + /* @ Extended features available subleaf 2 !!! All fields return 0 is info not + * available !!! + * @ Returned EAX: Reserved + * @ Returned EBX: Reserved + * @ Returned ECX: Reserved + * @ Retruned EDX: Features + */ + CPUID_EXTENDED_FEATURES_SL2 = 0x00000002, + CPUID_INTEL_RDT_CAPABILITY = 0x00000001, + CPUID_INTEL_RDT2_ALLOCATION = 0x00000000, + CPUID_INTEL_RDT2_RESID1 = 0x00000001, + CPUID_INTEL_RDT2_RESID2 = 0x00000002, + CPUID_INTEL_RDT2_RESID3 = 0x00000003, + CPUID_INTEL_SGX_SL1 = 0x00000001, + CPUID_INTEL_SGX_SL2 = 0x00000002, + CPUID_CPU_TRACE_ENUM_SL = 0x00000001, + CPUID_SOC_VENDOR_SL1 = 0x00000001, + CPUID_SOC_VENDOR_SL2 = 0x00000002, + CPUID_SOC_VENDOR_SL3 = 0x00000003, + // NOTE: goes higher than 1 + CPUID_DETERMINISTIC_ADRESS_TRANSLATION_PARAMS_SL = 0x00000001, + CPUID_TILE_INFO_PALETTE1 = 0x000000001, }; -static inline void cpuid(int leaf, int subleaf, int* a, int* b, int* c, int* d) { - __asm__ __volatile__ ( - "cpuid" - : "=a" (*a), "=b" (*b), "=c" (*c), "=d" (*d) - : "a" (leaf), "c" (subleaf) - ); +static inline void cpuid(int leaf, int subleaf, int *a, int *b, int *c, + int *d) { + __asm__ __volatile__("cpuid" + : "=a"(*a), "=b"(*b), "=c"(*c), "=d"(*d) + : "a"(leaf), "c"(subleaf)); } #endif // __CPUID_H__ \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/fpu.c b/kernel/src/sys/arch/x86_64/fpu.c index 5a71aec..b569c2c 100644 --- a/kernel/src/sys/arch/x86_64/fpu.c +++ b/kernel/src/sys/arch/x86_64/fpu.c @@ -1,14 +1,12 @@ #include #include -void fpu_set_cw(const uint16_t cw) { - asm volatile("fldcw %0" :: "m"(cw)); -} +void fpu_set_cw(const uint16_t cw) { asm volatile("fldcw %0" ::"m"(cw)); } void fpu_activate() { - size_t cr4; - asm volatile ("mov %%cr4, %0" : "=r"(cr4)); - cr4 |= 0x200; - asm volatile ("mov %0, %%cr4" :: "r"(cr4)); - fpu_set_cw(0x37F); + size_t cr4; + asm volatile("mov %%cr4, %0" : "=r"(cr4)); + cr4 |= 0x200; + asm volatile("mov %0, %%cr4" ::"r"(cr4)); + fpu_set_cw(0x37F); } \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/gdt.c b/kernel/src/sys/arch/x86_64/gdt.c old mode 100755 new mode 100644 index d6d712a..e528eff --- a/kernel/src/sys/arch/x86_64/gdt.c +++ b/kernel/src/sys/arch/x86_64/gdt.c @@ -1,32 +1,29 @@ -//#include "sys/log.h" +// #include "sys/log.h" +#include #include #include #include -#include -gdt_table def_table = { - { - 0x0000000000000000, // 0x00 +gdt_table def_table = {{ + 0x0000000000000000, // 0x00 - 0x00009a000000ffff, // 0x08 16 bit code - 0x000093000000ffff, // 0x10 16 bit data + 0x00009a000000ffff, // 0x08 16 bit code + 0x000093000000ffff, // 0x10 16 bit data - 0x00cf9a000000ffff, // 0x18 32 bit code - 0x00cf93000000ffff, // 0x20 32 bit data + 0x00cf9a000000ffff, // 0x18 32 bit code + 0x00cf93000000ffff, // 0x20 32 bit data - 0x00af9b000000ffff, // 0x28 64 bit code cs - 0x00af93000000ffff, // 0x30 64 bit data ss + 0x00af9b000000ffff, // 0x28 64 bit code cs + 0x00af93000000ffff, // 0x30 64 bit data ss - 0x00aff3000000ffff, // 0x38 data ss - 0x00affb000000ffff, // 0x40 user mode code cs - }, - { - } -}; + 0x00aff3000000ffff, // 0x38 data ss + 0x00affb000000ffff, // 0x40 user mode code cs + }, + {}}; tssr tss_list[256]; // One tssr per CPU -void gdt_init( char* kstack ) { +void gdt_init(char *kstack) { // TODO: adapt for multiprocessor kernel tss_list[0].rsp[0] = (uint64_t)kstack; @@ -40,15 +37,13 @@ void gdt_init( char* kstack ) { def_table.tss_entry.base2 = (uint8_t)((tss >> 24) & 0xff); def_table.tss_entry.base3 = (uint32_t)(tss >> 32); def_table.tss_entry.resv = 0; - - gdtr gdt = (gdtr){ - .size = (sizeof(gdt_table)) - 1, - .address = (uint64_t)&def_table - }; - __asm__ volatile ("lgdt %0\n\t" : : "m"(gdt) : "memory"); - __asm__ volatile ("ltr %0\n\t" : : "r"((uint16_t)0x48)); + gdtr gdt = + (gdtr){.size = (sizeof(gdt_table)) - 1, .address = (uint64_t)&def_table}; - //logln(progress, "kinit stage 1", "GDT initialized\n"); + __asm__ volatile("lgdt %0\n\t" : : "m"(gdt) : "memory"); + __asm__ volatile("ltr %0\n\t" : : "r"((uint16_t)0x48)); + + // logln(progress, "kinit stage 1", "GDT initialized\n"); log("gdt - initialized.\n"); } \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/gdt.h b/kernel/src/sys/arch/x86_64/gdt.h old mode 100755 new mode 100644 index 6004d06..be55cd9 --- a/kernel/src/sys/arch/x86_64/gdt.h +++ b/kernel/src/sys/arch/x86_64/gdt.h @@ -5,10 +5,10 @@ typedef struct { uint16_t length; uint16_t base; - uint8_t base1; - uint8_t flags; - uint8_t flags1; - uint8_t base2; + uint8_t base1; + uint8_t flags; + uint8_t flags1; + uint8_t base2; uint32_t base3; uint32_t resv; } __attribute__((packed)) tss_entry; @@ -23,7 +23,6 @@ typedef struct { uint64_t address; } __attribute__((packed)) gdtr; - typedef struct { uint32_t resv; uint64_t rsp[4]; @@ -34,4 +33,4 @@ typedef struct { uint16_t iopb; } __attribute__((packed)) tssr; // Per CPU -void gdt_init(char* kstack); \ No newline at end of file +void gdt_init(char *kstack); \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/idt.c b/kernel/src/sys/arch/x86_64/idt.c old mode 100755 new mode 100644 index e556eb4..f82700c --- a/kernel/src/sys/arch/x86_64/idt.c +++ b/kernel/src/sys/arch/x86_64/idt.c @@ -1,50 +1,51 @@ -//#include "sys/log.h" +// #include "sys/log.h" #include "sys/arch/x86_64/pic.h" #include #include -__attribute__((aligned(0x10))) -static idt_entry_t idt[256]; +__attribute__((aligned(0x10))) static idt_entry_t idt[256]; static idtr_t idtr; -void idt_set_descriptor(uint8_t vector, void* isr, uint8_t flags) { - idt_entry_t* descriptor = &idt[vector]; +void idt_set_descriptor(uint8_t vector, void *isr, uint8_t flags) { + idt_entry_t *descriptor = &idt[vector]; - descriptor->isr_low = (uint64_t)isr & 0xFFFF; - descriptor->kernel_cs = 0x28; - descriptor->ist = 0; - descriptor->attributes = flags; - descriptor->isr_mid = ((uint64_t)isr >> 16) & 0xFFFF; - descriptor->isr_high = ((uint64_t)isr >> 32) & 0xFFFFFFFF; - descriptor->reserved = 0; + descriptor->isr_low = (uint64_t)isr & 0xFFFF; + descriptor->kernel_cs = 0x28; + descriptor->ist = 0; + descriptor->attributes = flags; + descriptor->isr_mid = ((uint64_t)isr >> 16) & 0xFFFF; + descriptor->isr_high = ((uint64_t)isr >> 32) & 0xFFFFFFFF; + descriptor->reserved = 0; } static int vectors[256]; -extern void* isr_stub_table[]; +extern void *isr_stub_table[]; void idt_init() { - idtr.base = (uintptr_t)&idt[0]; - idtr.limit = (uint16_t)sizeof(idt_entry_t) * 256 - 1; + idtr.base = (uintptr_t)&idt[0]; + idtr.limit = (uint16_t)sizeof(idt_entry_t) * 256 - 1; - for (uint16_t vector = 0; vector <= 256; vector++) { - if (vector == 0x80) - continue; // We skip the syscall handler, since it should be called from user space. - idt_set_descriptor(vector, isr_stub_table[vector], 0x8E); - vectors[vector] = 1; - } - - uint16_t vector = 0x80; - idt_set_descriptor(vector, isr_stub_table[vector], 0xEE); + for (uint16_t vector = 0; vector <= 256; vector++) { + if (vector == 0x80) + continue; // We skip the syscall handler, since it should be called from + // user space. + idt_set_descriptor(vector, isr_stub_table[vector], 0x8E); vectors[vector] = 1; + } - pic_init(); - pic_unmask_irq(1); - - __asm__ volatile ("lidt %0" : : "m"(idtr)); // load the new IDT - __asm__ volatile ("sti"); // set the interrupt flag + uint16_t vector = 0x80; + idt_set_descriptor(vector, isr_stub_table[vector], 0xEE); + vectors[vector] = 1; - //logln(progress, "kinit stage 1", "IDT initialized! Time to receive interrupts!\n"); - log("idt - initialized\n"); + pic_init(); + pic_unmask_irq(1); + + __asm__ volatile("lidt %0" : : "m"(idtr)); // load the new IDT + __asm__ volatile("sti"); // set the interrupt flag + + // logln(progress, "kinit stage 1", "IDT initialized! Time to receive + // interrupts!\n"); + log("idt - initialized\n"); } \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/idt.h b/kernel/src/sys/arch/x86_64/idt.h old mode 100755 new mode 100644 index 8416f5e..015a379 --- a/kernel/src/sys/arch/x86_64/idt.h +++ b/kernel/src/sys/arch/x86_64/idt.h @@ -28,24 +28,27 @@ typedef struct { } __attribute__((packed)) registers_t; typedef struct stackframe { - struct stackframe* rbp; + struct stackframe *rbp; uint64_t rip; } stackframe_t; typedef struct { - uint16_t isr_low; // The lower 16 bits of the ISR's address - uint16_t kernel_cs; // The GDT segment selector that the CPU will load into CS before calling the ISR - uint8_t ist; // The IST in the TSS that the CPU will load into RSP; set to zero for now - uint8_t attributes; // Type and attributes; see the IDT page - uint16_t isr_mid; // The higher 16 bits of the lower 32 bits of the ISR's address - uint32_t isr_high; // The higher 32 bits of the ISR's address - uint32_t reserved; // Set to zero + uint16_t isr_low; // The lower 16 bits of the ISR's address + uint16_t kernel_cs; // The GDT segment selector that the CPU will load into CS + // before calling the ISR + uint8_t ist; // The IST in the TSS that the CPU will load into RSP; set to + // zero for now + uint8_t attributes; // Type and attributes; see the IDT page + uint16_t + isr_mid; // The higher 16 bits of the lower 32 bits of the ISR's address + uint32_t isr_high; // The higher 32 bits of the ISR's address + uint32_t reserved; // Set to zero } __attribute__((packed)) idt_entry_t; typedef struct { - uint16_t limit; - uint64_t base; + uint16_t limit; + uint64_t base; } __attribute__((packed)) idtr_t; -void idt_set_descriptor(uint8_t vector, void* isr, uint8_t flags); +void idt_set_descriptor(uint8_t vector, void *isr, uint8_t flags); void idt_init(void); \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/interrupts.c b/kernel/src/sys/arch/x86_64/interrupts.c old mode 100755 new mode 100644 index 15b7773..bbec1c2 --- a/kernel/src/sys/arch/x86_64/interrupts.c +++ b/kernel/src/sys/arch/x86_64/interrupts.c @@ -1,5 +1,5 @@ -//#include "mm/pmm.h" -//#include "mm/vmm.h" +// #include "mm/pmm.h" +// #include "mm/vmm.h" #include "mm/pmm.h" #include "mm/vmm.h" #include "sched/sched.h" @@ -7,75 +7,72 @@ #include "sys/arch/x86_64/rtc.h" #include "sys/log.h" #include "sys/syscall.h" -//#include "sys/sched.h" +// #include "sys/sched.h" #include #include #include -//#include +// #include int pit_millis = 0; int pit_secs = 0; +extern int vmm_kernel_pm_exists; struct Idt_StackFrame { - struct Idt_StackFrame* rbp; - uint64_t rip; -}__attribute__((packed)); + struct Idt_StackFrame *rbp; + uint64_t rip; +} __attribute__((packed)); -void dump_backtrace(registers_t *r) -{ - log("ints - backtrace : \n"); - struct Idt_StackFrame* frame = (struct Idt_StackFrame*)r->rbp; +void dump_backtrace(registers_t *r) { + log("ints - backtrace : \n"); + struct Idt_StackFrame *frame = (struct Idt_StackFrame *)r->rbp; - while (frame) { - log("ints - %s (ip: %p)\n", frame->rip); - frame = frame->rbp; - } - log("ints - \n"); + while (frame) { + log("ints - %s (ip: %p)\n", frame->rip); + frame = frame->rbp; + } + log("ints - \n"); } void pit_handler(registers_t *regs); void exception_handler(registers_t *regs) { - vmm_load_pagemap(vmm_kernel_pm); - - if (regs->int_no < 32) { - //panic(kmode_cpu_exception, regs); - log("ints - %d (RIP: %p, ERR: %d)\n", regs->int_no, regs->rip, regs->err_code); + vmm_load_pagemap(vmm_kernel_pm); - if(regs->int_no == 0xe) { - uint64_t cr2; - asm ("mov %%cr2, %0" : "=r"(cr2)); - log("ints - PF: Faulting location: %p (%p)\n", cr2, virt_to_phys(vmm_current_pm, cr2)); - log("ints - PF: Faulting page flags: %p\n", vmm_get_flags(vmm_current_pm, cr2)); - log("ints - PF: Faulting page map: %p\n", PHYSICAL(vmm_current_pm)); - } + if (regs->int_no < 32) { + // panic(kmode_cpu_exception, regs); + log("ints - %d (RIP: %p, ERR: %d)\n", regs->int_no, regs->rip, + regs->err_code); - // dump_backtrace(regs); - asm ("cli"); - while (1) - asm ("hlt"); + if (regs->int_no == 0xe && vmm_kernel_pm_exists) { + uint64_t cr2; + asm("mov %%cr2, %0" : "=r"(cr2)); + log("ints - PF: Faulting location: %p (%p)\n", cr2, + virt_to_phys(vmm_current_pm, cr2)); + log("ints - PF: Faulting page flags: %p\n", + vmm_get_flags(vmm_current_pm, cr2)); + log("ints - PF: Faulting page map: %p\n", PHYSICAL(vmm_current_pm)); } - if (regs->int_no == 1 + 32) - { - if (inb(0x60) & 0x80) - { - pic_ack(regs->int_no - 32); - return; - } + // dump_backtrace(regs); + asm("cli"); + while (1) + asm("hlt"); + } - log("ints - keyboard\n"); + if (regs->int_no == 1 + 32) { + if (inb(0x60) & 0x80) { + pic_ack(regs->int_no - 32); + return; } - else if (regs->int_no == 32 + 8) { - rtc_handle_interrupt(regs); - } - else if (regs->int_no == 0x80 - 32 || regs->int_no == 32) { - pit_handler(regs); - } - else if (regs->int_no == 0x80) - { - syscall_handle(regs); - } - //logln(info, "arch/ints", "Received interrupt %d\n", regs->int_no); - pic_ack(regs->int_no - 32); + + log("ints - keyboard\n"); + } else if (regs->int_no == 32 + 8) { + rtc_handle_interrupt(regs); + } else if (regs->int_no == 0x80 - 32 || regs->int_no == 32) { + pit_handler(regs); + } else if (regs->int_no == 0x80) { + syscall_handle(regs); + } + // logln(info, "arch/ints", "Received interrupt %d\n", regs->int_no); + pic_ack(regs->int_no - 32); } \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/pic.c b/kernel/src/sys/arch/x86_64/pic.c old mode 100755 new mode 100644 index d36cdf9..53ce230 --- a/kernel/src/sys/arch/x86_64/pic.c +++ b/kernel/src/sys/arch/x86_64/pic.c @@ -1,11 +1,11 @@ -//#include "sys/log.h" +// #include "sys/log.h" #include -//#include +// #include #include void pic_init() { - //if (acpi_available) - // return; + // if (acpi_available) + // return; uint8_t a1, a2; diff --git a/kernel/src/sys/arch/x86_64/pit.c b/kernel/src/sys/arch/x86_64/pit.c old mode 100755 new mode 100644 index cadfebb..32b60c3 --- a/kernel/src/sys/arch/x86_64/pit.c +++ b/kernel/src/sys/arch/x86_64/pit.c @@ -1,60 +1,52 @@ #include "sched/sched.h" #include "sys/arch/x86_64/idt.h" #include "sys/arch/x86_64/pic.h" -#include #include +#include #ifdef __x86_64__ -#include #include -//#include +#include +// #include uint32_t tick = 0; -void pit_handler(registers_t *regs) -{ - tick++; +void pit_handler(registers_t *regs) { + tick++; - schedule(regs); - //Scheduler_Schedule(regs); + schedule(regs); + // Scheduler_Schedule(regs); } -void pit_init(uint32_t frequency) -{ - uint32_t divisor = PIT_FREQUENCY / frequency; - outb(0x43, 0x34); - outb(0x40, (uint8_t)(divisor & 0xFF)); - outb(0x40, (uint8_t)((divisor >> 8) & 0xFF)); +void pit_init(uint32_t frequency) { + uint32_t divisor = PIT_FREQUENCY / frequency; + outb(0x43, 0x34); + outb(0x40, (uint8_t)(divisor & 0xFF)); + outb(0x40, (uint8_t)((divisor >> 8) & 0xFF)); - pic_unmask_irq(0); + pic_unmask_irq(0); } -void sleep(uint32_t seconds) -{ - uint32_t eticks = tick + seconds * HZ; - while (tick < eticks) - { - __asm__ __volatile__("hlt"); - } +void sleep(uint32_t seconds) { + uint32_t eticks = tick + seconds * HZ; + while (tick < eticks) { + __asm__ __volatile__("hlt"); + } } -void sleep_ms(uint32_t milliseconds) -{ - uint32_t eticks = tick + (milliseconds * HZ) / 1000; - while (tick < eticks) - { - __asm__ __volatile__("hlt"); - } +void sleep_ms(uint32_t milliseconds) { + uint32_t eticks = tick + (milliseconds * HZ) / 1000; + while (tick < eticks) { + __asm__ __volatile__("hlt"); + } } // todo: unistd: add usleep function -void usleep(uint32_t usecs) -{ - uint32_t eticks = tick + (usecs * HZ); - while (tick < eticks) - { - __asm__ __volatile__("hlt"); - } +void usleep(uint32_t usecs) { + uint32_t eticks = tick + (usecs * HZ); + while (tick < eticks) { + __asm__ __volatile__("hlt"); + } } #endif \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/rtc.c b/kernel/src/sys/arch/x86_64/rtc.c old mode 100755 new mode 100644 index df77a2e..9b277ef --- a/kernel/src/sys/arch/x86_64/rtc.c +++ b/kernel/src/sys/arch/x86_64/rtc.c @@ -1,26 +1,28 @@ #include "sys/arch/x86_64/idt.h" #include "sys/arch/x86_64/io.h" -#include #include +#include #include void rtc_init() { - asm("cli"); - outb(0x70, 0x8A); - outb(0x71, 0x20); - asm("sti"); + asm("cli"); + outb(0x70, 0x8A); + outb(0x71, 0x20); + asm("sti"); - asm("cli"); // disable interrupts - outb(0x70, 0x8B); // select register B, and disable NMI - char prev=inb(0x71); // read the current value of register B - outb(0x70, 0x8B); // set the index again (a read will reset the index to register D) - outb(0x71, prev | 0x40); // write the previous value ORed with 0x40. This turns on bit 6 of register B - asm("sti"); + asm("cli"); // disable interrupts + outb(0x70, 0x8B); // select register B, and disable NMI + char prev = inb(0x71); // read the current value of register B + outb(0x70, + 0x8B); // set the index again (a read will reset the index to register D) + outb(0x71, prev | 0x40); // write the previous value ORed with 0x40. This + // turns on bit 6 of register B + asm("sti"); - //pic_unmask_irq(8); + // pic_unmask_irq(8); } void rtc_handle_interrupt(registers_t *regs) { - (void)regs; - printf("RTC!\n"); + (void)regs; + printf("RTC!\n"); } \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/smp.c b/kernel/src/sys/arch/x86_64/smp.c index bf0a8c2..33183b6 100644 --- a/kernel/src/sys/arch/x86_64/smp.c +++ b/kernel/src/sys/arch/x86_64/smp.c @@ -1,6 +1,4 @@ #include "sys/arch/x86_64/smp.h" #include "limine.h" -void smp_init() { - -} \ No newline at end of file +void smp_init() {} \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/sse.c b/kernel/src/sys/arch/x86_64/sse.c old mode 100755 new mode 100644 index 570d903..2f3f021 --- a/kernel/src/sys/arch/x86_64/sse.c +++ b/kernel/src/sys/arch/x86_64/sse.c @@ -1,59 +1,59 @@ #include -#include #include +#include int cpuid_check_bit(int reg, int bit) { - int eax, ebx, ecx, edx; + int eax, ebx, ecx, edx; - // Minimal inline assembly to execute CPUID - __asm__ volatile ( - "cpuid" // Execute CPUID instruction - : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) // Output registers - : "a"(0x1) // Input: EAX = 0x1 (query feature flags) - : // No clobbered registers - ); + // Minimal inline assembly to execute CPUID + __asm__ volatile("cpuid" // Execute CPUID instruction + : "=a"(eax), "=b"(ebx), "=c"(ecx), + "=d"(edx) // Output registers + : "a"(0x1) // Input: EAX = 0x1 (query feature flags) + : // No clobbered registers + ); - // Check bit 25 of EDX (SSE support) in plain C - if (reg == 0) { - if (edx & (1 << bit)) { - return 1; // SSE is supported - } else { - return 0; // SSE is not supported - } - }else if (reg == 1) { - if (ecx & (1 << bit)) { - return 1; // SSE is supported - } else { - return 0; // SSE is not supported - } + // Check bit 25 of EDX (SSE support) in plain C + if (reg == 0) { + if (edx & (1 << bit)) { + return 1; // SSE is supported + } else { + return 0; // SSE is not supported } + } else if (reg == 1) { + if (ecx & (1 << bit)) { + return 1; // SSE is supported + } else { + return 0; // SSE is not supported + } + } - return 0; + return 0; } void sse_init() { - int sse = cpuid_check_bit(0, 25); - int sse2 = cpuid_check_bit(0, 26); - int sse3 = cpuid_check_bit(1, 0); - int ssse3 = cpuid_check_bit(1, 9); + int sse = cpuid_check_bit(0, 25); + int sse2 = cpuid_check_bit(0, 26); + int sse3 = cpuid_check_bit(1, 0); + int ssse3 = cpuid_check_bit(1, 9); - if (sse) - log("sse - sse is supported!\n"); - else - log("sse - sse isn't supported!\n"); + if (sse) + log("sse - sse is supported!\n"); + else + log("sse - sse isn't supported!\n"); - if (sse2) - log("sse - sse2 is supported!\n"); - else - log("sse - sse2 isn't supported!\n"); + if (sse2) + log("sse - sse2 is supported!\n"); + else + log("sse - sse2 isn't supported!\n"); - if (sse3) - log("sse - sse3 is supported!\n"); - else - log("sse - sse3 isn't supported!\n"); + if (sse3) + log("sse - sse3 is supported!\n"); + else + log("sse - sse3 isn't supported!\n"); - if (ssse3) - log("sse - ssse3 is supported!\n"); - else - log("sse - ssse3 isn't supported!\n"); + if (ssse3) + log("sse - ssse3 is supported!\n"); + else + log("sse - ssse3 isn't supported!\n"); } \ No newline at end of file diff --git a/kernel/src/sys/error_handling/panic.c b/kernel/src/sys/error_handling/panic.c index cb59d77..c867ff3 100644 --- a/kernel/src/sys/error_handling/panic.c +++ b/kernel/src/sys/error_handling/panic.c @@ -1,3 +1 @@ -void panic_ctx() { - -} \ No newline at end of file +void panic_ctx() {} \ No newline at end of file diff --git a/kernel/src/sys/gfx/flanterm/backends/fb.c b/kernel/src/sys/gfx/flanterm/backends/fb.c index 2ad1494..e3bac67 100644 --- a/kernel/src/sys/gfx/flanterm/backends/fb.c +++ b/kernel/src/sys/gfx/flanterm/backends/fb.c @@ -24,7 +24,8 @@ */ #ifdef __cplusplus -#error "Please do not compile Flanterm as C++ code! Flanterm should be compiled as C99 or newer." +#error \ + "Please do not compile Flanterm as C++ code! Flanterm should be compiled as C99 or newer." #endif #ifndef __STDC_VERSION__ @@ -39,9 +40,9 @@ #define ALWAYS_INLINE inline #endif -#include -#include #include +#include +#include #define FLANTERM_IN_FLANTERM @@ -64,26 +65,26 @@ static uint8_t bump_alloc_pool[FLANTERM_FB_BUMP_ALLOC_POOL_SIZE]; static size_t bump_alloc_ptr = 0; static void *bump_alloc(size_t s) { - static bool base_offset_added = false; - if (!base_offset_added) { - if ((uintptr_t)bump_alloc_pool & 0xf) { - bump_alloc_ptr += 0x10 - ((uintptr_t)bump_alloc_pool & 0xf); - } - base_offset_added = true; + static bool base_offset_added = false; + if (!base_offset_added) { + if ((uintptr_t)bump_alloc_pool & 0xf) { + bump_alloc_ptr += 0x10 - ((uintptr_t)bump_alloc_pool & 0xf); } + base_offset_added = true; + } - if ((s & 0xf) != 0) { - s += 0x10; - s &= ~(size_t)0xf; - } + if ((s & 0xf) != 0) { + s += 0x10; + s &= ~(size_t)0xf; + } - size_t next_ptr = bump_alloc_ptr + s; - if (next_ptr > FLANTERM_FB_BUMP_ALLOC_POOL_SIZE) { - return NULL; - } - void *ret = &bump_alloc_pool[bump_alloc_ptr]; - bump_alloc_ptr = next_ptr; - return ret; + size_t next_ptr = bump_alloc_ptr + s; + if (next_ptr > FLANTERM_FB_BUMP_ALLOC_POOL_SIZE) { + return NULL; + } + void *ret = &bump_alloc_pool[bump_alloc_ptr]; + bump_alloc_ptr = next_ptr; + return ret; } static bool bump_allocated_instance = false; @@ -93,1160 +94,1203 @@ static bool bump_allocated_instance = false; // Builtin font originally taken from: // https://github.com/viler-int10h/vga-text-mode-fonts/raw/master/FONTS/PC-OTHER/TOSH-SAT.F16 static const uint8_t builtin_font[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x81, 0x81, 0xa5, 0xa5, 0x81, - 0x81, 0xa5, 0x99, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x3c, 0x7e, 0xff, - 0xff, 0xdb, 0xdb, 0xff, 0xff, 0xdb, 0xe7, 0xff, 0x7e, 0x3c, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, - 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, - 0x3c, 0x3c, 0xdb, 0xff, 0xff, 0xdb, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0xff, 0x66, 0x18, 0x18, - 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x78, - 0x78, 0x30, 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, 0x78, 0xcc, 0x84, 0x84, 0xcc, 0x78, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, - 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1e, - 0x0e, 0x1e, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0xfc, 0x30, 0x30, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x18, 0x1c, 0x1e, 0x16, 0x12, - 0x10, 0x10, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x30, 0x38, 0x2c, - 0x26, 0x32, 0x3a, 0x2e, 0x26, 0x22, 0x62, 0xe2, 0xc6, 0x0e, 0x0c, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf8, 0xfe, - 0xf8, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x06, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x78, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x78, - 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, - 0xcc, 0xcc, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xdb, - 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, 0x00, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x78, - 0xfc, 0x30, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x78, 0x30, 0xfc, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x78, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0xfc, 0x78, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x0c, 0xfe, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 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, 0x24, 0x66, 0xff, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, - 0x38, 0x38, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x78, 0x78, 0x78, 0x78, 0x30, 0x30, 0x30, 0x00, 0x30, - 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, - 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x18, 0x7c, 0xc6, 0xc0, 0xc0, 0x7c, 0x06, 0x06, 0xc6, 0x7c, - 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x0c, 0x0c, 0x18, 0x38, - 0x30, 0x60, 0x60, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, - 0x6c, 0x38, 0x30, 0x76, 0xde, 0xcc, 0xcc, 0xde, 0x76, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x60, 0x60, 0x60, - 0x60, 0x60, 0x60, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x38, 0xfe, 0x38, 0x6c, 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, 0x00, 0x00, 0x18, 0x18, 0x30, 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, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, - 0x0c, 0x0c, 0x18, 0x38, 0x30, 0x60, 0x60, 0xc0, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xc6, 0xc6, 0xc6, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, - 0x06, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0x06, 0xc6, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, - 0xfe, 0x0c, 0x0c, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, - 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, - 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, - 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, - 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, - 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x0c, - 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, - 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x60, - 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x00, 0x30, - 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xde, 0xde, - 0xde, 0xde, 0xc0, 0xc0, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, - 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfc, 0xc6, 0xc6, 0xc6, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, - 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xcc, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xcc, 0xf8, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, - 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0xc0, - 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, - 0xc0, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c, - 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xcc, 0xd8, 0xf0, 0xe0, 0xf0, 0xd8, 0xcc, 0xc6, - 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, - 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, - 0xee, 0xfe, 0xd6, 0xd6, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xe6, 0xe6, 0xf6, 0xde, 0xce, 0xce, 0xc6, 0xc6, - 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xc6, - 0xc6, 0xc6, 0xc6, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xf6, 0xda, - 0x6c, 0x06, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xfc, - 0xd8, 0xcc, 0xcc, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, - 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, - 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x38, - 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, - 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc0, 0xc0, - 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, - 0x60, 0x60, 0x60, 0x60, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, - 0x60, 0x60, 0x30, 0x38, 0x18, 0x0c, 0x0c, 0x06, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x78, 0x00, 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, 0xff, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x06, 0x06, - 0x7e, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, - 0xc0, 0xdc, 0xe6, 0xc6, 0xc6, 0xc6, 0xc6, 0xe6, 0xdc, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc6, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x76, 0xce, 0xc6, - 0xc6, 0xc6, 0xc6, 0xce, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc0, 0xc0, 0xc0, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1c, 0x36, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xce, 0xc6, - 0xc6, 0xc6, 0xce, 0x76, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0xc0, 0xc0, - 0xc0, 0xdc, 0xe6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x1e, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0xc0, 0xc0, - 0xc0, 0xc6, 0xcc, 0xd8, 0xf0, 0xf0, 0xd8, 0xcc, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, - 0xd6, 0xd6, 0xd6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xdc, 0xe6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0xe6, 0xc6, - 0xc6, 0xc6, 0xe6, 0xdc, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x76, 0xce, 0xc6, 0xc6, 0xc6, 0xce, 0x76, 0x06, 0x06, 0x06, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0xe6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, - 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, - 0x70, 0x1c, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, - 0x30, 0xfe, 0x30, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x6c, 0xc6, - 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xce, 0x76, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xfe, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1c, 0x30, 0x30, 0x30, 0x30, 0xe0, 0x30, 0x30, 0x30, 0x30, - 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x30, - 0x30, 0x30, 0x30, 0x1c, 0x30, 0x30, 0x30, 0x30, 0xe0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x38, 0x38, 0x6c, - 0x6c, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, - 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x66, 0x3c, 0x18, 0xcc, 0x78, 0x00, - 0x00, 0x00, 0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xc6, - 0xfe, 0xc0, 0xc0, 0xc0, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, - 0x00, 0x7c, 0x06, 0x06, 0x7e, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x6c, 0x6c, 0x00, 0x7c, 0x06, 0x06, 0x7e, 0xc6, 0xc6, 0xc6, - 0x7e, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0x06, 0x06, - 0x7e, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, - 0x00, 0x7c, 0x06, 0x06, 0x7e, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc6, - 0x7c, 0x18, 0x0c, 0x38, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, - 0xfe, 0xc0, 0xc0, 0xc0, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, - 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc0, 0xc0, 0xc0, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc0, 0xc0, 0xc0, - 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, 0x00, 0x38, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, - 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x3c, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, - 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 0x00, - 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x18, 0x30, 0x60, 0x00, 0xfe, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, - 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0x36, 0x36, - 0x76, 0xde, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x3c, - 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, - 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x38, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, - 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xce, 0x76, 0x06, 0xc6, 0x7c, 0x00, - 0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0x7c, 0x00, 0x00, 0x00, 0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, - 0x30, 0x78, 0xcc, 0xc0, 0xc0, 0xcc, 0x78, 0x30, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0x60, 0x60, 0x60, 0xf8, 0x60, 0x60, 0x60, 0xe6, - 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0xfc, - 0x30, 0xfc, 0x30, 0x30, 0x30, 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, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0x06, 0x06, - 0x7e, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, - 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, - 0x00, 0xdc, 0xe6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x76, 0xdc, 0x00, 0xc6, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, - 0xc6, 0x00, 0x00, 0x00, 0x00, 0x78, 0xd8, 0xd8, 0x6c, 0x00, 0xfc, 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, 0x18, 0x18, 0x00, 0x18, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xc6, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xfe, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc0, 0xc2, 0xc6, 0xcc, 0xd8, 0x30, 0x60, 0xdc, 0x86, 0x0c, - 0x18, 0x3e, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc2, 0xc6, 0xcc, 0xd8, 0x30, - 0x66, 0xce, 0x9e, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, - 0x00, 0x30, 0x30, 0x30, 0x78, 0x78, 0x78, 0x78, 0x30, 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, 0x22, 0x88, 0x22, 0x88, - 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, - 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, 0xf8, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0xf8, 0x18, - 0x18, 0xf8, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0xf6, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xf8, 0x18, - 0x18, 0xf8, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, - 0x36, 0xf6, 0xf6, 0x06, 0x06, 0xf6, 0xf6, 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, 0xfe, 0x06, - 0x06, 0xf6, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0xf6, 0xf6, 0x06, 0x06, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0xf8, 0x18, - 0x18, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xf8, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, - 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xff, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, - 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x18, 0x18, 0x1f, 0x1f, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, - 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x37, 0x37, 0x30, 0x30, 0x3f, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x3f, 0x30, 0x30, 0x37, 0x37, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0xf7, 0x00, - 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xff, 0xff, 0x00, 0x00, 0xf7, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x37, 0x30, 0x30, 0x37, 0x37, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, - 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, - 0x36, 0xf7, 0xf7, 0x00, 0x00, 0xf7, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, - 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, - 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x1f, 0x1f, 0x18, 0x18, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x18, 0x18, 0x1f, 0x1f, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, - 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0xff, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0xff, 0xff, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, - 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x1f, 0x1f, 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, 0x00, - 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, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x76, 0xd6, 0xdc, 0xc8, 0xc8, 0xdc, 0xd6, 0x76, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, - 0xd8, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, - 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x7e, 0xfe, 0x24, 0x24, 0x24, 0x24, 0x66, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xfe, 0xc2, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc2, 0xfe, - 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xc8, 0xcc, - 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x76, 0x6c, 0x60, 0xc0, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0xfc, 0x98, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x30, 0x30, 0x78, 0xcc, 0xcc, - 0xcc, 0x78, 0x30, 0x30, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, - 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, - 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xcc, 0x60, 0x30, 0x78, 0xcc, - 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x76, 0xbb, 0x99, 0x99, 0xdd, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x02, 0x06, 0x3c, 0x6c, 0xce, 0xd6, 0xd6, 0xe6, 0x6c, 0x78, - 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x60, 0xc0, 0xc0, 0xfe, - 0xc0, 0xc0, 0x60, 0x30, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0xfc, - 0x30, 0x30, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00, 0xfc, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x00, - 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x36, 0x36, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0xfc, 0x00, 0x30, 0x30, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, - 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xcc, 0xcc, - 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c, - 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0x6c, 0x3c, 0x1c, 0x0c, 0x00, 0x00, - 0x00, 0xd8, 0xec, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x0c, 0x18, 0x30, 0x60, 0x7c, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x81, 0x81, 0xa5, 0xa5, 0x81, + 0x81, 0xa5, 0x99, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x3c, 0x7e, 0xff, + 0xff, 0xdb, 0xdb, 0xff, 0xff, 0xdb, 0xe7, 0xff, 0x7e, 0x3c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, + 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, + 0x3c, 0x3c, 0xdb, 0xff, 0xff, 0xdb, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0xff, 0x66, 0x18, 0x18, + 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x78, + 0x78, 0x30, 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, 0x78, 0xcc, 0x84, 0x84, 0xcc, 0x78, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, + 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1e, + 0x0e, 0x1e, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0xfc, 0x30, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x18, 0x1c, 0x1e, 0x16, 0x12, + 0x10, 0x10, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x30, 0x38, 0x2c, + 0x26, 0x32, 0x3a, 0x2e, 0x26, 0x22, 0x62, 0xe2, 0xc6, 0x0e, 0x0c, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf8, 0xfe, + 0xf8, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x06, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x78, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x78, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, + 0xcc, 0xcc, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xdb, + 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, 0x00, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x78, + 0xfc, 0x30, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x78, 0x30, 0xfc, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x78, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0xfc, 0x78, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x0c, 0xfe, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 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, 0x24, 0x66, 0xff, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, + 0x38, 0x38, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x78, 0x78, 0x78, 0x78, 0x30, 0x30, 0x30, 0x00, 0x30, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, + 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x18, 0x7c, 0xc6, 0xc0, 0xc0, 0x7c, 0x06, 0x06, 0xc6, 0x7c, + 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x0c, 0x0c, 0x18, 0x38, + 0x30, 0x60, 0x60, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, + 0x6c, 0x38, 0x30, 0x76, 0xde, 0xcc, 0xcc, 0xde, 0x76, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x60, 0x60, 0x60, + 0x60, 0x60, 0x60, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x38, 0xfe, 0x38, 0x6c, 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, 0x00, 0x00, 0x18, 0x18, 0x30, 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, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, + 0x0c, 0x0c, 0x18, 0x38, 0x30, 0x60, 0x60, 0xc0, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xc6, 0xc6, 0xc6, + 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, + 0x06, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0x06, 0xc6, + 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, + 0xfe, 0x0c, 0x0c, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, + 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, + 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, + 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, + 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, + 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x0c, + 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, + 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x60, + 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x00, 0x30, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xde, 0xde, + 0xde, 0xde, 0xc0, 0xc0, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, + 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0xc6, 0xc6, 0xc6, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, + 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, + 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xcc, + 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xcc, 0xf8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, + 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0xc0, + 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, + 0xc0, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, + 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0xcc, 0xd8, 0xf0, 0xe0, 0xf0, 0xd8, 0xcc, 0xc6, + 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, + 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, + 0xee, 0xfe, 0xd6, 0xd6, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0xe6, 0xe6, 0xf6, 0xde, 0xce, 0xce, 0xc6, 0xc6, + 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xc6, + 0xc6, 0xc6, 0xc6, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xf6, 0xda, + 0x6c, 0x06, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xfc, + 0xd8, 0xcc, 0xcc, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, + 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, + 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x38, + 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, + 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc0, 0xc0, + 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, + 0x60, 0x60, 0x60, 0x60, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, + 0x60, 0x60, 0x30, 0x38, 0x18, 0x0c, 0x0c, 0x06, 0x06, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x78, 0x00, 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, 0xff, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x06, 0x06, + 0x7e, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, + 0xc0, 0xdc, 0xe6, 0xc6, 0xc6, 0xc6, 0xc6, 0xe6, 0xdc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc6, + 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x76, 0xce, 0xc6, + 0xc6, 0xc6, 0xc6, 0xce, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc0, 0xc0, 0xc0, 0x7e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1c, 0x36, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xce, 0xc6, + 0xc6, 0xc6, 0xce, 0x76, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0xc0, 0xc0, + 0xc0, 0xdc, 0xe6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x1e, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0xc0, 0xc0, + 0xc0, 0xc6, 0xcc, 0xd8, 0xf0, 0xf0, 0xd8, 0xcc, 0xc6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, + 0xd6, 0xd6, 0xd6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xdc, 0xe6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, + 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0xe6, 0xc6, + 0xc6, 0xc6, 0xe6, 0xdc, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x76, 0xce, 0xc6, 0xc6, 0xc6, 0xce, 0x76, 0x06, 0x06, 0x06, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0xe6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, + 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, + 0x70, 0x1c, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, + 0x30, 0xfe, 0x30, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, + 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, + 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x6c, 0xc6, + 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, + 0xc6, 0xc6, 0xce, 0x76, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xfe, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xfe, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1c, 0x30, 0x30, 0x30, 0x30, 0xe0, 0x30, 0x30, 0x30, 0x30, + 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x30, + 0x30, 0x30, 0x30, 0x1c, 0x30, 0x30, 0x30, 0x30, 0xe0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x38, 0x38, 0x6c, + 0x6c, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, + 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x66, 0x3c, 0x18, 0xcc, 0x78, 0x00, + 0x00, 0x00, 0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, + 0x7c, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xc6, + 0xfe, 0xc0, 0xc0, 0xc0, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, + 0x00, 0x7c, 0x06, 0x06, 0x7e, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x6c, 0x6c, 0x00, 0x7c, 0x06, 0x06, 0x7e, 0xc6, 0xc6, 0xc6, + 0x7e, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0x06, 0x06, + 0x7e, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, + 0x00, 0x7c, 0x06, 0x06, 0x7e, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc6, + 0x7c, 0x18, 0x0c, 0x38, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, + 0xfe, 0xc0, 0xc0, 0xc0, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, + 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc0, 0xc0, 0xc0, 0x7e, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc0, 0xc0, 0xc0, + 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, 0x00, 0x38, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, + 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x3c, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, + 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 0x00, + 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, + 0x18, 0x30, 0x60, 0x00, 0xfe, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, + 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0x36, 0x36, + 0x76, 0xde, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x3c, + 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, + 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, + 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, + 0x7c, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0xc6, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, + 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xce, 0x76, 0x06, 0xc6, 0x7c, 0x00, + 0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, + 0x7c, 0x00, 0x00, 0x00, 0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, + 0x30, 0x78, 0xcc, 0xc0, 0xc0, 0xcc, 0x78, 0x30, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0x60, 0x60, 0x60, 0xf8, 0x60, 0x60, 0x60, 0xe6, + 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0xfc, + 0x30, 0xfc, 0x30, 0x30, 0x30, 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, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0x06, 0x06, + 0x7e, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, + 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, + 0x7c, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0xc6, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, + 0x00, 0xdc, 0xe6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, + 0x76, 0xdc, 0x00, 0xc6, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, + 0xc6, 0x00, 0x00, 0x00, 0x00, 0x78, 0xd8, 0xd8, 0x6c, 0x00, 0xfc, 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, 0x18, 0x18, 0x00, 0x18, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xc6, + 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfe, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc0, 0xc2, 0xc6, 0xcc, 0xd8, 0x30, 0x60, 0xdc, 0x86, 0x0c, + 0x18, 0x3e, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc2, 0xc6, 0xcc, 0xd8, 0x30, + 0x66, 0xce, 0x9e, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, + 0x00, 0x30, 0x30, 0x30, 0x78, 0x78, 0x78, 0x78, 0x30, 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, 0x22, 0x88, 0x22, 0x88, + 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, + 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, 0xf8, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0xf8, 0x18, + 0x18, 0xf8, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0xf6, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xf8, 0x18, + 0x18, 0xf8, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, + 0x36, 0xf6, 0xf6, 0x06, 0x06, 0xf6, 0xf6, 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, 0xfe, 0x06, + 0x06, 0xf6, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0xf6, 0xf6, 0x06, 0x06, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0xfe, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0xf8, 0x18, + 0x18, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xf8, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x18, 0x18, 0x1f, 0x1f, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, + 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x37, 0x37, 0x30, 0x30, 0x3f, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x3f, 0x30, 0x30, 0x37, 0x37, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0xf7, 0x00, + 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x00, 0x00, 0xf7, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x37, 0x30, 0x30, 0x37, 0x37, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, + 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, + 0x36, 0xf7, 0xf7, 0x00, 0x00, 0xf7, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, + 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x1f, 0x1f, 0x18, 0x18, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x18, 0x18, 0x1f, 0x1f, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, + 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0xff, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0xff, 0xff, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, + 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1f, 0x1f, 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, 0x00, + 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, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x76, 0xd6, 0xdc, 0xc8, 0xc8, 0xdc, 0xd6, 0x76, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, + 0xd8, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, + 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7e, 0xfe, 0x24, 0x24, 0x24, 0x24, 0x66, 0xc6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xfe, 0xc2, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc2, 0xfe, + 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xc8, 0xcc, + 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x76, 0x6c, 0x60, 0xc0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0xfc, 0x98, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x30, 0x30, 0x78, 0xcc, 0xcc, + 0xcc, 0x78, 0x30, 0x30, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, + 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, + 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xcc, 0x60, 0x30, 0x78, 0xcc, + 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x76, 0xbb, 0x99, 0x99, 0xdd, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x06, 0x3c, 0x6c, 0xce, 0xd6, 0xd6, 0xe6, 0x6c, 0x78, + 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x60, 0xc0, 0xc0, 0xfe, + 0xc0, 0xc0, 0x60, 0x30, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, + 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0xfc, + 0x30, 0x30, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00, 0xfc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x00, + 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x36, 0x36, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0xfc, 0x00, 0x30, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, + 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xcc, 0xcc, + 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0x6c, 0x3c, 0x1c, 0x0c, 0x00, 0x00, + 0x00, 0xd8, 0xec, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x0c, 0x18, 0x30, 0x60, 0x7c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}; -static ALWAYS_INLINE uint32_t convert_colour(struct flanterm_context *_ctx, uint32_t colour) { - struct flanterm_fb_context *ctx = (void *)_ctx; - uint32_t r = (colour >> 16) & 0xff; - uint32_t g = (colour >> 8) & 0xff; - uint32_t b = colour & 0xff; - return (r << ctx->red_mask_shift) | (g << ctx->green_mask_shift) | (b << ctx->blue_mask_shift); +static ALWAYS_INLINE uint32_t convert_colour(struct flanterm_context *_ctx, + uint32_t colour) { + struct flanterm_fb_context *ctx = (void *)_ctx; + uint32_t r = (colour >> 16) & 0xff; + uint32_t g = (colour >> 8) & 0xff; + uint32_t b = colour & 0xff; + return (r << ctx->red_mask_shift) | (g << ctx->green_mask_shift) | + (b << ctx->blue_mask_shift); } static void flanterm_fb_save_state(struct flanterm_context *_ctx) { - struct flanterm_fb_context *ctx = (void *)_ctx; - ctx->saved_state_text_fg = ctx->text_fg; - ctx->saved_state_text_bg = ctx->text_bg; - ctx->saved_state_cursor_x = ctx->cursor_x; - ctx->saved_state_cursor_y = ctx->cursor_y; + struct flanterm_fb_context *ctx = (void *)_ctx; + ctx->saved_state_text_fg = ctx->text_fg; + ctx->saved_state_text_bg = ctx->text_bg; + ctx->saved_state_cursor_x = ctx->cursor_x; + ctx->saved_state_cursor_y = ctx->cursor_y; } static void flanterm_fb_restore_state(struct flanterm_context *_ctx) { - struct flanterm_fb_context *ctx = (void *)_ctx; - ctx->text_fg = ctx->saved_state_text_fg; - ctx->text_bg = ctx->saved_state_text_bg; - ctx->cursor_x = ctx->saved_state_cursor_x; - ctx->cursor_y = ctx->saved_state_cursor_y; + struct flanterm_fb_context *ctx = (void *)_ctx; + ctx->text_fg = ctx->saved_state_text_fg; + ctx->text_bg = ctx->saved_state_text_bg; + ctx->cursor_x = ctx->saved_state_cursor_x; + ctx->cursor_y = ctx->saved_state_cursor_y; } static void flanterm_fb_swap_palette(struct flanterm_context *_ctx) { - struct flanterm_fb_context *ctx = (void *)_ctx; - uint32_t tmp = ctx->text_bg; - ctx->text_bg = ctx->text_fg; - ctx->text_fg = tmp; + struct flanterm_fb_context *ctx = (void *)_ctx; + uint32_t tmp = ctx->text_bg; + ctx->text_bg = ctx->text_fg; + ctx->text_fg = tmp; } -static void plot_char_scaled_canvas(struct flanterm_context *_ctx, struct flanterm_fb_char *c, size_t x, size_t y) { - struct flanterm_fb_context *ctx = (void *)_ctx; +static void plot_char_scaled_canvas(struct flanterm_context *_ctx, + struct flanterm_fb_char *c, size_t x, + size_t y) { + struct flanterm_fb_context *ctx = (void *)_ctx; - if (x >= _ctx->cols || y >= _ctx->rows) { - return; - } - - x = ctx->offset_x + x * ctx->glyph_width; - y = ctx->offset_y + y * ctx->glyph_height; - - bool *glyph = &ctx->font_bool[c->c * ctx->font_height * ctx->font_width]; - // naming: fx,fy for font coordinates, gx,gy for glyph coordinates - for (size_t gy = 0; gy < ctx->glyph_height; gy++) { - uint8_t fy = gy / ctx->font_scale_y; - volatile uint32_t *fb_line = ctx->framebuffer + x + (y + gy) * (ctx->pitch / 4); - uint32_t *canvas_line = ctx->canvas + x + (y + gy) * ctx->width; - bool *glyph_pointer = glyph + (fy * ctx->font_width); - for (size_t fx = 0; fx < ctx->font_width; fx++) { - for (size_t i = 0; i < ctx->font_scale_x; i++) { - size_t gx = ctx->font_scale_x * fx + i; - uint32_t bg = c->bg == 0xffffffff ? canvas_line[gx] : c->bg; - uint32_t fg = c->fg == 0xffffffff ? canvas_line[gx] : c->fg; - fb_line[gx] = *glyph_pointer ? fg : bg; - } - glyph_pointer++; - } + if (x >= _ctx->cols || y >= _ctx->rows) { + return; + } + + x = ctx->offset_x + x * ctx->glyph_width; + y = ctx->offset_y + y * ctx->glyph_height; + + bool *glyph = &ctx->font_bool[c->c * ctx->font_height * ctx->font_width]; + // naming: fx,fy for font coordinates, gx,gy for glyph coordinates + for (size_t gy = 0; gy < ctx->glyph_height; gy++) { + uint8_t fy = gy / ctx->font_scale_y; + volatile uint32_t *fb_line = + ctx->framebuffer + x + (y + gy) * (ctx->pitch / 4); + uint32_t *canvas_line = ctx->canvas + x + (y + gy) * ctx->width; + bool *glyph_pointer = glyph + (fy * ctx->font_width); + for (size_t fx = 0; fx < ctx->font_width; fx++) { + for (size_t i = 0; i < ctx->font_scale_x; i++) { + size_t gx = ctx->font_scale_x * fx + i; + uint32_t bg = c->bg == 0xffffffff ? canvas_line[gx] : c->bg; + uint32_t fg = c->fg == 0xffffffff ? canvas_line[gx] : c->fg; + fb_line[gx] = *glyph_pointer ? fg : bg; + } + glyph_pointer++; } + } } -static void plot_char_scaled_uncanvas(struct flanterm_context *_ctx, struct flanterm_fb_char *c, size_t x, size_t y) { - struct flanterm_fb_context *ctx = (void *)_ctx; +static void plot_char_scaled_uncanvas(struct flanterm_context *_ctx, + struct flanterm_fb_char *c, size_t x, + size_t y) { + struct flanterm_fb_context *ctx = (void *)_ctx; - if (x >= _ctx->cols || y >= _ctx->rows) { - return; - } - - uint32_t default_bg = ctx->default_bg; - - uint32_t bg = c->bg == 0xffffffff ? default_bg : c->bg; - uint32_t fg = c->fg == 0xffffffff ? default_bg : c->fg; - - x = ctx->offset_x + x * ctx->glyph_width; - y = ctx->offset_y + y * ctx->glyph_height; - - bool *glyph = &ctx->font_bool[c->c * ctx->font_height * ctx->font_width]; - // naming: fx,fy for font coordinates, gx,gy for glyph coordinates - for (size_t gy = 0; gy < ctx->glyph_height; gy++) { - uint8_t fy = gy / ctx->font_scale_y; - volatile uint32_t *fb_line = ctx->framebuffer + x + (y + gy) * (ctx->pitch / 4); - bool *glyph_pointer = glyph + (fy * ctx->font_width); - for (size_t fx = 0; fx < ctx->font_width; fx++) { - for (size_t i = 0; i < ctx->font_scale_x; i++) { - size_t gx = ctx->font_scale_x * fx + i; - fb_line[gx] = *glyph_pointer ? fg : bg; - } - glyph_pointer++; - } + if (x >= _ctx->cols || y >= _ctx->rows) { + return; + } + + uint32_t default_bg = ctx->default_bg; + + uint32_t bg = c->bg == 0xffffffff ? default_bg : c->bg; + uint32_t fg = c->fg == 0xffffffff ? default_bg : c->fg; + + x = ctx->offset_x + x * ctx->glyph_width; + y = ctx->offset_y + y * ctx->glyph_height; + + bool *glyph = &ctx->font_bool[c->c * ctx->font_height * ctx->font_width]; + // naming: fx,fy for font coordinates, gx,gy for glyph coordinates + for (size_t gy = 0; gy < ctx->glyph_height; gy++) { + uint8_t fy = gy / ctx->font_scale_y; + volatile uint32_t *fb_line = + ctx->framebuffer + x + (y + gy) * (ctx->pitch / 4); + bool *glyph_pointer = glyph + (fy * ctx->font_width); + for (size_t fx = 0; fx < ctx->font_width; fx++) { + for (size_t i = 0; i < ctx->font_scale_x; i++) { + size_t gx = ctx->font_scale_x * fx + i; + fb_line[gx] = *glyph_pointer ? fg : bg; + } + glyph_pointer++; } + } } -static void plot_char_unscaled_canvas(struct flanterm_context *_ctx, struct flanterm_fb_char *c, size_t x, size_t y) { - struct flanterm_fb_context *ctx = (void *)_ctx; +static void plot_char_unscaled_canvas(struct flanterm_context *_ctx, + struct flanterm_fb_char *c, size_t x, + size_t y) { + struct flanterm_fb_context *ctx = (void *)_ctx; - if (x >= _ctx->cols || y >= _ctx->rows) { - return; - } - - x = ctx->offset_x + x * ctx->glyph_width; - y = ctx->offset_y + y * ctx->glyph_height; - - bool *glyph = &ctx->font_bool[c->c * ctx->font_height * ctx->font_width]; - // naming: fx,fy for font coordinates, gx,gy for glyph coordinates - for (size_t gy = 0; gy < ctx->glyph_height; gy++) { - volatile uint32_t *fb_line = ctx->framebuffer + x + (y + gy) * (ctx->pitch / 4); - uint32_t *canvas_line = ctx->canvas + x + (y + gy) * ctx->width; - bool *glyph_pointer = glyph + (gy * ctx->font_width); - for (size_t fx = 0; fx < ctx->font_width; fx++) { - uint32_t bg = c->bg == 0xffffffff ? canvas_line[fx] : c->bg; - uint32_t fg = c->fg == 0xffffffff ? canvas_line[fx] : c->fg; - fb_line[fx] = *(glyph_pointer++) ? fg : bg; - } + if (x >= _ctx->cols || y >= _ctx->rows) { + return; + } + + x = ctx->offset_x + x * ctx->glyph_width; + y = ctx->offset_y + y * ctx->glyph_height; + + bool *glyph = &ctx->font_bool[c->c * ctx->font_height * ctx->font_width]; + // naming: fx,fy for font coordinates, gx,gy for glyph coordinates + for (size_t gy = 0; gy < ctx->glyph_height; gy++) { + volatile uint32_t *fb_line = + ctx->framebuffer + x + (y + gy) * (ctx->pitch / 4); + uint32_t *canvas_line = ctx->canvas + x + (y + gy) * ctx->width; + bool *glyph_pointer = glyph + (gy * ctx->font_width); + for (size_t fx = 0; fx < ctx->font_width; fx++) { + uint32_t bg = c->bg == 0xffffffff ? canvas_line[fx] : c->bg; + uint32_t fg = c->fg == 0xffffffff ? canvas_line[fx] : c->fg; + fb_line[fx] = *(glyph_pointer++) ? fg : bg; } + } } -static void plot_char_unscaled_uncanvas(struct flanterm_context *_ctx, struct flanterm_fb_char *c, size_t x, size_t y) { - struct flanterm_fb_context *ctx = (void *)_ctx; +static void plot_char_unscaled_uncanvas(struct flanterm_context *_ctx, + struct flanterm_fb_char *c, size_t x, + size_t y) { + struct flanterm_fb_context *ctx = (void *)_ctx; - if (x >= _ctx->cols || y >= _ctx->rows) { - return; - } - - uint32_t default_bg = ctx->default_bg; - - uint32_t bg = c->bg == 0xffffffff ? default_bg : c->bg; - uint32_t fg = c->fg == 0xffffffff ? default_bg : c->fg; - - x = ctx->offset_x + x * ctx->glyph_width; - y = ctx->offset_y + y * ctx->glyph_height; - - bool *glyph = &ctx->font_bool[c->c * ctx->font_height * ctx->font_width]; - // naming: fx,fy for font coordinates, gx,gy for glyph coordinates - for (size_t gy = 0; gy < ctx->glyph_height; gy++) { - volatile uint32_t *fb_line = ctx->framebuffer + x + (y + gy) * (ctx->pitch / 4); - bool *glyph_pointer = glyph + (gy * ctx->font_width); - for (size_t fx = 0; fx < ctx->font_width; fx++) { - fb_line[fx] = *(glyph_pointer++) ? fg : bg; - } + if (x >= _ctx->cols || y >= _ctx->rows) { + return; + } + + uint32_t default_bg = ctx->default_bg; + + uint32_t bg = c->bg == 0xffffffff ? default_bg : c->bg; + uint32_t fg = c->fg == 0xffffffff ? default_bg : c->fg; + + x = ctx->offset_x + x * ctx->glyph_width; + y = ctx->offset_y + y * ctx->glyph_height; + + bool *glyph = &ctx->font_bool[c->c * ctx->font_height * ctx->font_width]; + // naming: fx,fy for font coordinates, gx,gy for glyph coordinates + for (size_t gy = 0; gy < ctx->glyph_height; gy++) { + volatile uint32_t *fb_line = + ctx->framebuffer + x + (y + gy) * (ctx->pitch / 4); + bool *glyph_pointer = glyph + (gy * ctx->font_width); + for (size_t fx = 0; fx < ctx->font_width; fx++) { + fb_line[fx] = *(glyph_pointer++) ? fg : bg; } + } } -static inline bool compare_char(struct flanterm_fb_char *a, struct flanterm_fb_char *b) { - return !(a->c != b->c || a->bg != b->bg || a->fg != b->fg); +static inline bool compare_char(struct flanterm_fb_char *a, + struct flanterm_fb_char *b) { + return !(a->c != b->c || a->bg != b->bg || a->fg != b->fg); } -static void push_to_queue(struct flanterm_context *_ctx, struct flanterm_fb_char *c, size_t x, size_t y) { - struct flanterm_fb_context *ctx = (void *)_ctx; +static void push_to_queue(struct flanterm_context *_ctx, + struct flanterm_fb_char *c, size_t x, size_t y) { + struct flanterm_fb_context *ctx = (void *)_ctx; - if (x >= _ctx->cols || y >= _ctx->rows) { - return; + if (x >= _ctx->cols || y >= _ctx->rows) { + return; + } + + size_t i = y * _ctx->cols + x; + + struct flanterm_fb_queue_item *q = ctx->map[i]; + + if (q == NULL) { + if (compare_char(&ctx->grid[i], c)) { + return; } + q = &ctx->queue[ctx->queue_i++]; + q->x = x; + q->y = y; + ctx->map[i] = q; + } - size_t i = y * _ctx->cols + x; - - struct flanterm_fb_queue_item *q = ctx->map[i]; - - if (q == NULL) { - if (compare_char(&ctx->grid[i], c)) { - return; - } - q = &ctx->queue[ctx->queue_i++]; - q->x = x; - q->y = y; - ctx->map[i] = q; - } - - q->c = *c; + q->c = *c; } static void flanterm_fb_revscroll(struct flanterm_context *_ctx) { - struct flanterm_fb_context *ctx = (void *)_ctx; + struct flanterm_fb_context *ctx = (void *)_ctx; - for (size_t i = (_ctx->scroll_bottom_margin - 1) * _ctx->cols - 1; - i >= _ctx->scroll_top_margin * _ctx->cols; i--) { - if (i == (size_t)-1) { - break; - } - struct flanterm_fb_char *c; - struct flanterm_fb_queue_item *q = ctx->map[i]; - if (q != NULL) { - c = &q->c; - } else { - c = &ctx->grid[i]; - } - push_to_queue(_ctx, c, (i + _ctx->cols) % _ctx->cols, (i + _ctx->cols) / _ctx->cols); + for (size_t i = (_ctx->scroll_bottom_margin - 1) * _ctx->cols - 1; + i >= _ctx->scroll_top_margin * _ctx->cols; i--) { + if (i == (size_t)-1) { + break; } - - // Clear the first line of the screen. - struct flanterm_fb_char empty; - empty.c = ' '; - empty.fg = ctx->text_fg; - empty.bg = ctx->text_bg; - for (size_t i = 0; i < _ctx->cols; i++) { - push_to_queue(_ctx, &empty, i, _ctx->scroll_top_margin); - } -} - -static void flanterm_fb_scroll(struct flanterm_context *_ctx) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - for (size_t i = (_ctx->scroll_top_margin + 1) * _ctx->cols; - i < _ctx->scroll_bottom_margin * _ctx->cols; i++) { - struct flanterm_fb_char *c; - struct flanterm_fb_queue_item *q = ctx->map[i]; - if (q != NULL) { - c = &q->c; - } else { - c = &ctx->grid[i]; - } - push_to_queue(_ctx, c, (i - _ctx->cols) % _ctx->cols, (i - _ctx->cols) / _ctx->cols); - } - - // Clear the last line of the screen. - struct flanterm_fb_char empty; - empty.c = ' '; - empty.fg = ctx->text_fg; - empty.bg = ctx->text_bg; - for (size_t i = 0; i < _ctx->cols; i++) { - push_to_queue(_ctx, &empty, i, _ctx->scroll_bottom_margin - 1); - } -} - -static void flanterm_fb_clear(struct flanterm_context *_ctx, bool move) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - struct flanterm_fb_char empty; - empty.c = ' '; - empty.fg = ctx->text_fg; - empty.bg = ctx->text_bg; - for (size_t i = 0; i < _ctx->rows * _ctx->cols; i++) { - push_to_queue(_ctx, &empty, i % _ctx->cols, i / _ctx->cols); - } - - if (move) { - ctx->cursor_x = 0; - ctx->cursor_y = 0; - } -} - -static void flanterm_fb_set_cursor_pos(struct flanterm_context *_ctx, size_t x, size_t y) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - if (x >= _ctx->cols) { - if ((int)x < 0) { - x = 0; - } else { - x = _ctx->cols - 1; - } - } - if (y >= _ctx->rows) { - if ((int)y < 0) { - y = 0; - } else { - y = _ctx->rows - 1; - } - } - ctx->cursor_x = x; - ctx->cursor_y = y; -} - -static void flanterm_fb_get_cursor_pos(struct flanterm_context *_ctx, size_t *x, size_t *y) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - *x = ctx->cursor_x >= _ctx->cols ? _ctx->cols - 1 : ctx->cursor_x; - *y = ctx->cursor_y >= _ctx->rows ? _ctx->rows - 1 : ctx->cursor_y; -} - -static void flanterm_fb_move_character(struct flanterm_context *_ctx, size_t new_x, size_t new_y, size_t old_x, size_t old_y) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - if (old_x >= _ctx->cols || old_y >= _ctx->rows - || new_x >= _ctx->cols || new_y >= _ctx->rows) { - return; - } - - size_t i = old_x + old_y * _ctx->cols; - struct flanterm_fb_char *c; struct flanterm_fb_queue_item *q = ctx->map[i]; if (q != NULL) { - c = &q->c; + c = &q->c; } else { - c = &ctx->grid[i]; + c = &ctx->grid[i]; } + push_to_queue(_ctx, c, (i + _ctx->cols) % _ctx->cols, + (i + _ctx->cols) / _ctx->cols); + } - push_to_queue(_ctx, c, new_x, new_y); + // Clear the first line of the screen. + struct flanterm_fb_char empty; + empty.c = ' '; + empty.fg = ctx->text_fg; + empty.bg = ctx->text_bg; + for (size_t i = 0; i < _ctx->cols; i++) { + push_to_queue(_ctx, &empty, i, _ctx->scroll_top_margin); + } +} + +static void flanterm_fb_scroll(struct flanterm_context *_ctx) { + struct flanterm_fb_context *ctx = (void *)_ctx; + + for (size_t i = (_ctx->scroll_top_margin + 1) * _ctx->cols; + i < _ctx->scroll_bottom_margin * _ctx->cols; i++) { + struct flanterm_fb_char *c; + struct flanterm_fb_queue_item *q = ctx->map[i]; + if (q != NULL) { + c = &q->c; + } else { + c = &ctx->grid[i]; + } + push_to_queue(_ctx, c, (i - _ctx->cols) % _ctx->cols, + (i - _ctx->cols) / _ctx->cols); + } + + // Clear the last line of the screen. + struct flanterm_fb_char empty; + empty.c = ' '; + empty.fg = ctx->text_fg; + empty.bg = ctx->text_bg; + for (size_t i = 0; i < _ctx->cols; i++) { + push_to_queue(_ctx, &empty, i, _ctx->scroll_bottom_margin - 1); + } +} + +static void flanterm_fb_clear(struct flanterm_context *_ctx, bool move) { + struct flanterm_fb_context *ctx = (void *)_ctx; + + struct flanterm_fb_char empty; + empty.c = ' '; + empty.fg = ctx->text_fg; + empty.bg = ctx->text_bg; + for (size_t i = 0; i < _ctx->rows * _ctx->cols; i++) { + push_to_queue(_ctx, &empty, i % _ctx->cols, i / _ctx->cols); + } + + if (move) { + ctx->cursor_x = 0; + ctx->cursor_y = 0; + } +} + +static void flanterm_fb_set_cursor_pos(struct flanterm_context *_ctx, size_t x, + size_t y) { + struct flanterm_fb_context *ctx = (void *)_ctx; + + if (x >= _ctx->cols) { + if ((int)x < 0) { + x = 0; + } else { + x = _ctx->cols - 1; + } + } + if (y >= _ctx->rows) { + if ((int)y < 0) { + y = 0; + } else { + y = _ctx->rows - 1; + } + } + ctx->cursor_x = x; + ctx->cursor_y = y; +} + +static void flanterm_fb_get_cursor_pos(struct flanterm_context *_ctx, size_t *x, + size_t *y) { + struct flanterm_fb_context *ctx = (void *)_ctx; + + *x = ctx->cursor_x >= _ctx->cols ? _ctx->cols - 1 : ctx->cursor_x; + *y = ctx->cursor_y >= _ctx->rows ? _ctx->rows - 1 : ctx->cursor_y; +} + +static void flanterm_fb_move_character(struct flanterm_context *_ctx, + size_t new_x, size_t new_y, size_t old_x, + size_t old_y) { + struct flanterm_fb_context *ctx = (void *)_ctx; + + if (old_x >= _ctx->cols || old_y >= _ctx->rows || new_x >= _ctx->cols || + new_y >= _ctx->rows) { + return; + } + + size_t i = old_x + old_y * _ctx->cols; + + struct flanterm_fb_char *c; + struct flanterm_fb_queue_item *q = ctx->map[i]; + if (q != NULL) { + c = &q->c; + } else { + c = &ctx->grid[i]; + } + + push_to_queue(_ctx, c, new_x, new_y); } static void flanterm_fb_set_text_fg(struct flanterm_context *_ctx, size_t fg) { - struct flanterm_fb_context *ctx = (void *)_ctx; + struct flanterm_fb_context *ctx = (void *)_ctx; - ctx->text_fg = ctx->ansi_colours[fg]; + ctx->text_fg = ctx->ansi_colours[fg]; } static void flanterm_fb_set_text_bg(struct flanterm_context *_ctx, size_t bg) { - struct flanterm_fb_context *ctx = (void *)_ctx; + struct flanterm_fb_context *ctx = (void *)_ctx; - ctx->text_bg = ctx->ansi_colours[bg]; + ctx->text_bg = ctx->ansi_colours[bg]; } -static void flanterm_fb_set_text_fg_bright(struct flanterm_context *_ctx, size_t fg) { - struct flanterm_fb_context *ctx = (void *)_ctx; +static void flanterm_fb_set_text_fg_bright(struct flanterm_context *_ctx, + size_t fg) { + struct flanterm_fb_context *ctx = (void *)_ctx; - ctx->text_fg = ctx->ansi_bright_colours[fg]; + ctx->text_fg = ctx->ansi_bright_colours[fg]; } -static void flanterm_fb_set_text_bg_bright(struct flanterm_context *_ctx, size_t bg) { - struct flanterm_fb_context *ctx = (void *)_ctx; +static void flanterm_fb_set_text_bg_bright(struct flanterm_context *_ctx, + size_t bg) { + struct flanterm_fb_context *ctx = (void *)_ctx; - ctx->text_bg = ctx->ansi_bright_colours[bg]; + ctx->text_bg = ctx->ansi_bright_colours[bg]; } -static void flanterm_fb_set_text_fg_rgb(struct flanterm_context *_ctx, uint32_t fg) { - struct flanterm_fb_context *ctx = (void *)_ctx; +static void flanterm_fb_set_text_fg_rgb(struct flanterm_context *_ctx, + uint32_t fg) { + struct flanterm_fb_context *ctx = (void *)_ctx; - ctx->text_fg = convert_colour(_ctx, fg); + ctx->text_fg = convert_colour(_ctx, fg); } -static void flanterm_fb_set_text_bg_rgb(struct flanterm_context *_ctx, uint32_t bg) { - struct flanterm_fb_context *ctx = (void *)_ctx; +static void flanterm_fb_set_text_bg_rgb(struct flanterm_context *_ctx, + uint32_t bg) { + struct flanterm_fb_context *ctx = (void *)_ctx; - ctx->text_bg = convert_colour(_ctx, bg); + ctx->text_bg = convert_colour(_ctx, bg); } static void flanterm_fb_set_text_fg_default(struct flanterm_context *_ctx) { - struct flanterm_fb_context *ctx = (void *)_ctx; + struct flanterm_fb_context *ctx = (void *)_ctx; - ctx->text_fg = ctx->default_fg; + ctx->text_fg = ctx->default_fg; } static void flanterm_fb_set_text_bg_default(struct flanterm_context *_ctx) { - struct flanterm_fb_context *ctx = (void *)_ctx; + struct flanterm_fb_context *ctx = (void *)_ctx; - ctx->text_bg = 0xffffffff; + ctx->text_bg = 0xffffffff; } -static void flanterm_fb_set_text_fg_default_bright(struct flanterm_context *_ctx) { - struct flanterm_fb_context *ctx = (void *)_ctx; +static void +flanterm_fb_set_text_fg_default_bright(struct flanterm_context *_ctx) { + struct flanterm_fb_context *ctx = (void *)_ctx; - ctx->text_fg = ctx->default_fg_bright; + ctx->text_fg = ctx->default_fg_bright; } -static void flanterm_fb_set_text_bg_default_bright(struct flanterm_context *_ctx) { - struct flanterm_fb_context *ctx = (void *)_ctx; +static void +flanterm_fb_set_text_bg_default_bright(struct flanterm_context *_ctx) { + struct flanterm_fb_context *ctx = (void *)_ctx; - ctx->text_bg = ctx->default_bg_bright; + ctx->text_bg = ctx->default_bg_bright; } static void draw_cursor(struct flanterm_context *_ctx) { - struct flanterm_fb_context *ctx = (void *)_ctx; + struct flanterm_fb_context *ctx = (void *)_ctx; - if (ctx->cursor_x >= _ctx->cols || ctx->cursor_y >= _ctx->rows) { - return; - } + if (ctx->cursor_x >= _ctx->cols || ctx->cursor_y >= _ctx->rows) { + return; + } - size_t i = ctx->cursor_x + ctx->cursor_y * _ctx->cols; + size_t i = ctx->cursor_x + ctx->cursor_y * _ctx->cols; - struct flanterm_fb_char c; - struct flanterm_fb_queue_item *q = ctx->map[i]; - if (q != NULL) { - c = q->c; - } else { - c = ctx->grid[i]; - } - uint32_t tmp = c.fg; - c.fg = c.bg; - c.bg = tmp; - ctx->plot_char(_ctx, &c, ctx->cursor_x, ctx->cursor_y); - if (q != NULL) { - ctx->grid[i] = q->c; - ctx->map[i] = NULL; - } + struct flanterm_fb_char c; + struct flanterm_fb_queue_item *q = ctx->map[i]; + if (q != NULL) { + c = q->c; + } else { + c = ctx->grid[i]; + } + uint32_t tmp = c.fg; + c.fg = c.bg; + c.bg = tmp; + ctx->plot_char(_ctx, &c, ctx->cursor_x, ctx->cursor_y); + if (q != NULL) { + ctx->grid[i] = q->c; + ctx->map[i] = NULL; + } } static void flanterm_fb_double_buffer_flush(struct flanterm_context *_ctx) { - struct flanterm_fb_context *ctx = (void *)_ctx; + struct flanterm_fb_context *ctx = (void *)_ctx; - if (_ctx->cursor_enabled) { - draw_cursor(_ctx); + if (_ctx->cursor_enabled) { + draw_cursor(_ctx); + } + + for (size_t i = 0; i < ctx->queue_i; i++) { + struct flanterm_fb_queue_item *q = &ctx->queue[i]; + size_t offset = q->y * _ctx->cols + q->x; + if (ctx->map[offset] == NULL) { + continue; } + ctx->plot_char(_ctx, &q->c, q->x, q->y); + ctx->grid[offset] = q->c; + ctx->map[offset] = NULL; + } - for (size_t i = 0; i < ctx->queue_i; i++) { - struct flanterm_fb_queue_item *q = &ctx->queue[i]; - size_t offset = q->y * _ctx->cols + q->x; - if (ctx->map[offset] == NULL) { - continue; - } - ctx->plot_char(_ctx, &q->c, q->x, q->y); - ctx->grid[offset] = q->c; - ctx->map[offset] = NULL; + if ((ctx->old_cursor_x != ctx->cursor_x || + ctx->old_cursor_y != ctx->cursor_y) || + _ctx->cursor_enabled == false) { + if (ctx->old_cursor_x < _ctx->cols && ctx->old_cursor_y < _ctx->rows) { + ctx->plot_char( + _ctx, &ctx->grid[ctx->old_cursor_x + ctx->old_cursor_y * _ctx->cols], + ctx->old_cursor_x, ctx->old_cursor_y); } + } - if ((ctx->old_cursor_x != ctx->cursor_x || ctx->old_cursor_y != ctx->cursor_y) || _ctx->cursor_enabled == false) { - if (ctx->old_cursor_x < _ctx->cols && ctx->old_cursor_y < _ctx->rows) { - ctx->plot_char(_ctx, &ctx->grid[ctx->old_cursor_x + ctx->old_cursor_y * _ctx->cols], ctx->old_cursor_x, ctx->old_cursor_y); - } - } + ctx->old_cursor_x = ctx->cursor_x; + ctx->old_cursor_y = ctx->cursor_y; - ctx->old_cursor_x = ctx->cursor_x; - ctx->old_cursor_y = ctx->cursor_y; - - ctx->queue_i = 0; + ctx->queue_i = 0; } static void flanterm_fb_raw_putchar(struct flanterm_context *_ctx, uint8_t c) { - struct flanterm_fb_context *ctx = (void *)_ctx; + struct flanterm_fb_context *ctx = (void *)_ctx; - if (ctx->cursor_x >= _ctx->cols && (ctx->cursor_y < _ctx->scroll_bottom_margin - 1 || _ctx->scroll_enabled)) { - ctx->cursor_x = 0; - ctx->cursor_y++; - if (ctx->cursor_y == _ctx->scroll_bottom_margin) { - ctx->cursor_y--; - flanterm_fb_scroll(_ctx); - } - if (ctx->cursor_y >= _ctx->cols) { - ctx->cursor_y = _ctx->cols - 1; - } + if (ctx->cursor_x >= _ctx->cols && + (ctx->cursor_y < _ctx->scroll_bottom_margin - 1 || + _ctx->scroll_enabled)) { + ctx->cursor_x = 0; + ctx->cursor_y++; + if (ctx->cursor_y == _ctx->scroll_bottom_margin) { + ctx->cursor_y--; + flanterm_fb_scroll(_ctx); } + if (ctx->cursor_y >= _ctx->cols) { + ctx->cursor_y = _ctx->cols - 1; + } + } - struct flanterm_fb_char ch; - ch.c = c; - ch.fg = ctx->text_fg; - ch.bg = ctx->text_bg; - push_to_queue(_ctx, &ch, ctx->cursor_x++, ctx->cursor_y); + struct flanterm_fb_char ch; + ch.c = c; + ch.fg = ctx->text_fg; + ch.bg = ctx->text_bg; + push_to_queue(_ctx, &ch, ctx->cursor_x++, ctx->cursor_y); } static void flanterm_fb_full_refresh(struct flanterm_context *_ctx) { - struct flanterm_fb_context *ctx = (void *)_ctx; + struct flanterm_fb_context *ctx = (void *)_ctx; - uint32_t default_bg = ctx->default_bg; + uint32_t default_bg = ctx->default_bg; - for (size_t y = 0; y < ctx->height; y++) { - for (size_t x = 0; x < ctx->width; x++) { - if (ctx->canvas != NULL) { - ctx->framebuffer[y * (ctx->pitch / sizeof(uint32_t)) + x] = ctx->canvas[y * ctx->width + x]; - } else { - ctx->framebuffer[y * (ctx->pitch / sizeof(uint32_t)) + x] = default_bg; - } - } + for (size_t y = 0; y < ctx->height; y++) { + for (size_t x = 0; x < ctx->width; x++) { + if (ctx->canvas != NULL) { + ctx->framebuffer[y * (ctx->pitch / sizeof(uint32_t)) + x] = + ctx->canvas[y * ctx->width + x]; + } else { + ctx->framebuffer[y * (ctx->pitch / sizeof(uint32_t)) + x] = default_bg; + } } + } - for (size_t i = 0; i < (size_t)_ctx->rows * _ctx->cols; i++) { - size_t x = i % _ctx->cols; - size_t y = i / _ctx->cols; + for (size_t i = 0; i < (size_t)_ctx->rows * _ctx->cols; i++) { + size_t x = i % _ctx->cols; + size_t y = i / _ctx->cols; - ctx->plot_char(_ctx, &ctx->grid[i], x, y); - } + ctx->plot_char(_ctx, &ctx->grid[i], x, y); + } - if (_ctx->cursor_enabled) { - draw_cursor(_ctx); - } + if (_ctx->cursor_enabled) { + draw_cursor(_ctx); + } } -static void flanterm_fb_deinit(struct flanterm_context *_ctx, void (*_free)(void *, size_t)) { - struct flanterm_fb_context *ctx = (void *)_ctx; +static void flanterm_fb_deinit(struct flanterm_context *_ctx, + void (*_free)(void *, size_t)) { + struct flanterm_fb_context *ctx = (void *)_ctx; - if (_free == NULL) { + if (_free == NULL) { #ifndef FLANTERM_FB_DISABLE_BUMP_ALLOC - if (bump_allocated_instance == true) { - bump_alloc_ptr = 0; - bump_allocated_instance = false; - } + if (bump_allocated_instance == true) { + bump_alloc_ptr = 0; + bump_allocated_instance = false; + } #endif - return; - } + return; + } - _free(ctx->font_bits, ctx->font_bits_size); - _free(ctx->font_bool, ctx->font_bool_size); - _free(ctx->grid, ctx->grid_size); - _free(ctx->queue, ctx->queue_size); - _free(ctx->map, ctx->map_size); + _free(ctx->font_bits, ctx->font_bits_size); + _free(ctx->font_bool, ctx->font_bool_size); + _free(ctx->grid, ctx->grid_size); + _free(ctx->queue, ctx->queue_size); + _free(ctx->map, ctx->map_size); - if (ctx->canvas != NULL) { - _free(ctx->canvas, ctx->canvas_size); - } + if (ctx->canvas != NULL) { + _free(ctx->canvas, ctx->canvas_size); + } - _free(ctx, sizeof(struct flanterm_fb_context)); + _free(ctx, sizeof(struct flanterm_fb_context)); } struct flanterm_context *flanterm_fb_init( - void *(*_malloc)(size_t), - void (*_free)(void *, size_t), + void *(*_malloc)(size_t), void (*_free)(void *, size_t), uint32_t *framebuffer, size_t width, size_t height, size_t pitch, - uint8_t red_mask_size, uint8_t red_mask_shift, - uint8_t green_mask_size, uint8_t green_mask_shift, - uint8_t blue_mask_size, uint8_t blue_mask_shift, - uint32_t *canvas, - uint32_t *ansi_colours, uint32_t *ansi_bright_colours, - uint32_t *default_bg, uint32_t *default_fg, - uint32_t *default_bg_bright, uint32_t *default_fg_bright, - void *font, size_t font_width, size_t font_height, size_t font_spacing, - size_t font_scale_x, size_t font_scale_y, - size_t margin -) { - if (font_scale_x == 0 || font_scale_y == 0) { - font_scale_x = 1; - font_scale_y = 1; - if (width >= (1920 + 1920 / 3) && height >= (1080 + 1080 / 3)) { - font_scale_x = 2; - font_scale_y = 2; - } - if (width >= (3840 + 3840 / 3) && height >= (2160 + 2160 / 3)) { - font_scale_x = 4; - font_scale_y = 4; - } + uint8_t red_mask_size, uint8_t red_mask_shift, uint8_t green_mask_size, + uint8_t green_mask_shift, uint8_t blue_mask_size, uint8_t blue_mask_shift, + uint32_t *canvas, uint32_t *ansi_colours, uint32_t *ansi_bright_colours, + uint32_t *default_bg, uint32_t *default_fg, uint32_t *default_bg_bright, + uint32_t *default_fg_bright, void *font, size_t font_width, + size_t font_height, size_t font_spacing, size_t font_scale_x, + size_t font_scale_y, size_t margin) { + if (font_scale_x == 0 || font_scale_y == 0) { + font_scale_x = 1; + font_scale_y = 1; + if (width >= (1920 + 1920 / 3) && height >= (1080 + 1080 / 3)) { + font_scale_x = 2; + font_scale_y = 2; } + if (width >= (3840 + 3840 / 3) && height >= (2160 + 2160 / 3)) { + font_scale_x = 4; + font_scale_y = 4; + } + } - /*if (red_mask_size < 8 || red_mask_size != green_mask_size || red_mask_size != blue_mask_size) { - return NULL; - }*/ + /*if (red_mask_size < 8 || red_mask_size != green_mask_size || red_mask_size + != blue_mask_size) { return NULL; + }*/ - if (_malloc == NULL) { + if (_malloc == NULL) { #ifndef FLANTERM_FB_DISABLE_BUMP_ALLOC - if (bump_allocated_instance == true) { - return NULL; - } - _malloc = bump_alloc; - // Limit terminal size if needed - if (width > FLANTERM_FB_WIDTH_LIMIT || height > FLANTERM_FB_HEIGHT_LIMIT) { - size_t width_limit = width > FLANTERM_FB_WIDTH_LIMIT ? FLANTERM_FB_WIDTH_LIMIT : width; - size_t height_limit = height > FLANTERM_FB_HEIGHT_LIMIT ? FLANTERM_FB_HEIGHT_LIMIT : height; + if (bump_allocated_instance == true) { + return NULL; + } + _malloc = bump_alloc; + // Limit terminal size if needed + if (width > FLANTERM_FB_WIDTH_LIMIT || height > FLANTERM_FB_HEIGHT_LIMIT) { + size_t width_limit = + width > FLANTERM_FB_WIDTH_LIMIT ? FLANTERM_FB_WIDTH_LIMIT : width; + size_t height_limit = + height > FLANTERM_FB_HEIGHT_LIMIT ? FLANTERM_FB_HEIGHT_LIMIT : height; - framebuffer = (uint32_t *)((uintptr_t)framebuffer + ((((height / 2) - (height_limit / 2)) * pitch) + (((width / 2) - (width_limit / 2)) * 4))); + framebuffer = + (uint32_t *)((uintptr_t)framebuffer + + ((((height / 2) - (height_limit / 2)) * pitch) + + (((width / 2) - (width_limit / 2)) * 4))); - width = width_limit; - height = height_limit; - } + width = width_limit; + height = height_limit; + } - // Force disable canvas - canvas = NULL; + // Force disable canvas + canvas = NULL; #else - return NULL; + return NULL; #endif + } + + struct flanterm_fb_context *ctx = NULL; + ctx = _malloc(sizeof(struct flanterm_fb_context)); + if (ctx == NULL) { + goto fail; + } + + struct flanterm_context *_ctx = (void *)ctx; + memset(ctx, 0, sizeof(struct flanterm_fb_context)); + + ctx->red_mask_size = red_mask_size; + ctx->red_mask_shift = red_mask_shift + (red_mask_size - 8); + ctx->green_mask_size = green_mask_size; + ctx->green_mask_shift = green_mask_shift + (green_mask_size - 8); + ctx->blue_mask_size = blue_mask_size; + ctx->blue_mask_shift = blue_mask_shift + (blue_mask_size - 8); + + if (ansi_colours != NULL) { + for (size_t i = 0; i < 8; i++) { + ctx->ansi_colours[i] = convert_colour(_ctx, ansi_colours[i]); } + } else { + ctx->ansi_colours[0] = convert_colour(_ctx, 0x00000000); // black + ctx->ansi_colours[1] = convert_colour(_ctx, 0x00aa0000); // red + ctx->ansi_colours[2] = convert_colour(_ctx, 0x0000aa00); // green + ctx->ansi_colours[3] = convert_colour(_ctx, 0x00aa5500); // brown + ctx->ansi_colours[4] = convert_colour(_ctx, 0x000000aa); // blue + ctx->ansi_colours[5] = convert_colour(_ctx, 0x00aa00aa); // magenta + ctx->ansi_colours[6] = convert_colour(_ctx, 0x0000aaaa); // cyan + ctx->ansi_colours[7] = convert_colour(_ctx, 0x00aaaaaa); // grey + } - struct flanterm_fb_context *ctx = NULL; - ctx = _malloc(sizeof(struct flanterm_fb_context)); - if (ctx == NULL) { - goto fail; + if (ansi_bright_colours != NULL) { + for (size_t i = 0; i < 8; i++) { + ctx->ansi_bright_colours[i] = + convert_colour(_ctx, ansi_bright_colours[i]); } + } else { + ctx->ansi_bright_colours[0] = convert_colour(_ctx, 0x00555555); // black + ctx->ansi_bright_colours[1] = convert_colour(_ctx, 0x00ff5555); // red + ctx->ansi_bright_colours[2] = convert_colour(_ctx, 0x0055ff55); // green + ctx->ansi_bright_colours[3] = convert_colour(_ctx, 0x00ffff55); // brown + ctx->ansi_bright_colours[4] = convert_colour(_ctx, 0x005555ff); // blue + ctx->ansi_bright_colours[5] = convert_colour(_ctx, 0x00ff55ff); // magenta + ctx->ansi_bright_colours[6] = convert_colour(_ctx, 0x0055ffff); // cyan + ctx->ansi_bright_colours[7] = convert_colour(_ctx, 0x00ffffff); // grey + } - struct flanterm_context *_ctx = (void *)ctx; - memset(ctx, 0, sizeof(struct flanterm_fb_context)); + if (default_bg != NULL) { + ctx->default_bg = convert_colour(_ctx, *default_bg); + } else { + ctx->default_bg = 0x00000000; // background (black) + } - ctx->red_mask_size = red_mask_size; - ctx->red_mask_shift = red_mask_shift + (red_mask_size - 8); - ctx->green_mask_size = green_mask_size; - ctx->green_mask_shift = green_mask_shift + (green_mask_size - 8); - ctx->blue_mask_size = blue_mask_size; - ctx->blue_mask_shift = blue_mask_shift + (blue_mask_size - 8); + if (default_fg != NULL) { + ctx->default_fg = convert_colour(_ctx, *default_fg); + } else { + ctx->default_fg = convert_colour(_ctx, 0x00aaaaaa); // foreground (grey) + } - if (ansi_colours != NULL) { - for (size_t i = 0; i < 8; i++) { - ctx->ansi_colours[i] = convert_colour(_ctx, ansi_colours[i]); - } - } else { - ctx->ansi_colours[0] = convert_colour(_ctx, 0x00000000); // black - ctx->ansi_colours[1] = convert_colour(_ctx, 0x00aa0000); // red - ctx->ansi_colours[2] = convert_colour(_ctx, 0x0000aa00); // green - ctx->ansi_colours[3] = convert_colour(_ctx, 0x00aa5500); // brown - ctx->ansi_colours[4] = convert_colour(_ctx, 0x000000aa); // blue - ctx->ansi_colours[5] = convert_colour(_ctx, 0x00aa00aa); // magenta - ctx->ansi_colours[6] = convert_colour(_ctx, 0x0000aaaa); // cyan - ctx->ansi_colours[7] = convert_colour(_ctx, 0x00aaaaaa); // grey - } + if (default_bg_bright != NULL) { + ctx->default_bg_bright = convert_colour(_ctx, *default_bg_bright); + } else { + ctx->default_bg_bright = + convert_colour(_ctx, 0x00555555); // background (black) + } - if (ansi_bright_colours != NULL) { - for (size_t i = 0; i < 8; i++) { - ctx->ansi_bright_colours[i] = convert_colour(_ctx, ansi_bright_colours[i]); - } - } else { - ctx->ansi_bright_colours[0] = convert_colour(_ctx, 0x00555555); // black - ctx->ansi_bright_colours[1] = convert_colour(_ctx, 0x00ff5555); // red - ctx->ansi_bright_colours[2] = convert_colour(_ctx, 0x0055ff55); // green - ctx->ansi_bright_colours[3] = convert_colour(_ctx, 0x00ffff55); // brown - ctx->ansi_bright_colours[4] = convert_colour(_ctx, 0x005555ff); // blue - ctx->ansi_bright_colours[5] = convert_colour(_ctx, 0x00ff55ff); // magenta - ctx->ansi_bright_colours[6] = convert_colour(_ctx, 0x0055ffff); // cyan - ctx->ansi_bright_colours[7] = convert_colour(_ctx, 0x00ffffff); // grey - } + if (default_fg_bright != NULL) { + ctx->default_fg_bright = convert_colour(_ctx, *default_fg_bright); + } else { + ctx->default_fg_bright = + convert_colour(_ctx, 0x00ffffff); // foreground (grey) + } - if (default_bg != NULL) { - ctx->default_bg = convert_colour(_ctx, *default_bg); - } else { - ctx->default_bg = 0x00000000; // background (black) - } + ctx->text_fg = ctx->default_fg; + ctx->text_bg = 0xffffffff; - if (default_fg != NULL) { - ctx->default_fg = convert_colour(_ctx, *default_fg); - } else { - ctx->default_fg = convert_colour(_ctx, 0x00aaaaaa); // foreground (grey) - } - - if (default_bg_bright != NULL) { - ctx->default_bg_bright = convert_colour(_ctx, *default_bg_bright); - } else { - ctx->default_bg_bright = convert_colour(_ctx, 0x00555555); // background (black) - } - - if (default_fg_bright != NULL) { - ctx->default_fg_bright = convert_colour(_ctx, *default_fg_bright); - } else { - ctx->default_fg_bright = convert_colour(_ctx, 0x00ffffff); // foreground (grey) - } - - ctx->text_fg = ctx->default_fg; - ctx->text_bg = 0xffffffff; - - ctx->framebuffer = (void *)framebuffer; - ctx->width = width; - ctx->height = height; - ctx->pitch = pitch; + ctx->framebuffer = (void *)framebuffer; + ctx->width = width; + ctx->height = height; + ctx->pitch = pitch; #define FONT_BYTES ((font_width * font_height * FLANTERM_FB_FONT_GLYPHS) / 8) - if (font != NULL) { - ctx->font_width = font_width; - ctx->font_height = font_height; - ctx->font_bits_size = FONT_BYTES; - ctx->font_bits = _malloc(ctx->font_bits_size); - if (ctx->font_bits == NULL) { - goto fail; - } - memcpy(ctx->font_bits, font, ctx->font_bits_size); - } else { - ctx->font_width = font_width = 8; - ctx->font_height = font_height = 16; - ctx->font_bits_size = FONT_BYTES; - font_spacing = 1; - ctx->font_bits = _malloc(ctx->font_bits_size); - if (ctx->font_bits == NULL) { - goto fail; - } - memcpy(ctx->font_bits, builtin_font, ctx->font_bits_size); + if (font != NULL) { + ctx->font_width = font_width; + ctx->font_height = font_height; + ctx->font_bits_size = FONT_BYTES; + ctx->font_bits = _malloc(ctx->font_bits_size); + if (ctx->font_bits == NULL) { + goto fail; } + memcpy(ctx->font_bits, font, ctx->font_bits_size); + } else { + ctx->font_width = font_width = 8; + ctx->font_height = font_height = 16; + ctx->font_bits_size = FONT_BYTES; + font_spacing = 1; + ctx->font_bits = _malloc(ctx->font_bits_size); + if (ctx->font_bits == NULL) { + goto fail; + } + memcpy(ctx->font_bits, builtin_font, ctx->font_bits_size); + } #undef FONT_BYTES - ctx->font_width += font_spacing; + ctx->font_width += font_spacing; - ctx->font_bool_size = FLANTERM_FB_FONT_GLYPHS * font_height * ctx->font_width * sizeof(bool); - ctx->font_bool = _malloc(ctx->font_bool_size); - if (ctx->font_bool == NULL) { - goto fail; - } + ctx->font_bool_size = + FLANTERM_FB_FONT_GLYPHS * font_height * ctx->font_width * sizeof(bool); + ctx->font_bool = _malloc(ctx->font_bool_size); + if (ctx->font_bool == NULL) { + goto fail; + } - for (size_t i = 0; i < FLANTERM_FB_FONT_GLYPHS; i++) { - uint8_t *glyph = &ctx->font_bits[i * font_height]; + for (size_t i = 0; i < FLANTERM_FB_FONT_GLYPHS; i++) { + uint8_t *glyph = &ctx->font_bits[i * font_height]; - for (size_t y = 0; y < font_height; y++) { - // NOTE: the characters in VGA fonts are always one byte wide. - // 9 dot wide fonts have 8 dots and one empty column, except - // characters 0xC0-0xDF replicate column 9. - for (size_t x = 0; x < 8; x++) { - size_t offset = i * font_height * ctx->font_width + y * ctx->font_width + x; + for (size_t y = 0; y < font_height; y++) { + // NOTE: the characters in VGA fonts are always one byte wide. + // 9 dot wide fonts have 8 dots and one empty column, except + // characters 0xC0-0xDF replicate column 9. + for (size_t x = 0; x < 8; x++) { + size_t offset = + i * font_height * ctx->font_width + y * ctx->font_width + x; - if ((glyph[y] & (0x80 >> x))) { - ctx->font_bool[offset] = true; - } else { - ctx->font_bool[offset] = false; - } - } - // fill columns above 8 like VGA Line Graphics Mode does - for (size_t x = 8; x < ctx->font_width; x++) { - size_t offset = i * font_height * ctx->font_width + y * ctx->font_width + x; - - if (i >= 0xc0 && i <= 0xdf) { - ctx->font_bool[offset] = (glyph[y] & 1); - } else { - ctx->font_bool[offset] = false; - } - } - } - } - - ctx->font_scale_x = font_scale_x; - ctx->font_scale_y = font_scale_y; - - ctx->glyph_width = ctx->font_width * font_scale_x; - ctx->glyph_height = font_height * font_scale_y; - - _ctx->cols = (ctx->width - margin * 2) / ctx->glyph_width; - _ctx->rows = (ctx->height - margin * 2) / ctx->glyph_height; - - ctx->offset_x = margin + ((ctx->width - margin * 2) % ctx->glyph_width) / 2; - ctx->offset_y = margin + ((ctx->height - margin * 2) % ctx->glyph_height) / 2; - - ctx->grid_size = _ctx->rows * _ctx->cols * sizeof(struct flanterm_fb_char); - ctx->grid = _malloc(ctx->grid_size); - if (ctx->grid == NULL) { - goto fail; - } - for (size_t i = 0; i < _ctx->rows * _ctx->cols; i++) { - ctx->grid[i].c = ' '; - ctx->grid[i].fg = ctx->text_fg; - ctx->grid[i].bg = ctx->text_bg; - } - - ctx->queue_size = _ctx->rows * _ctx->cols * sizeof(struct flanterm_fb_queue_item); - ctx->queue = _malloc(ctx->queue_size); - if (ctx->queue == NULL) { - goto fail; - } - ctx->queue_i = 0; - memset(ctx->queue, 0, ctx->queue_size); - - ctx->map_size = _ctx->rows * _ctx->cols * sizeof(struct flanterm_fb_queue_item *); - ctx->map = _malloc(ctx->map_size); - if (ctx->map == NULL) { - goto fail; - } - memset(ctx->map, 0, ctx->map_size); - - if (canvas != NULL) { - ctx->canvas_size = ctx->width * ctx->height * sizeof(uint32_t); - ctx->canvas = _malloc(ctx->canvas_size); - if (ctx->canvas == NULL) { - goto fail; - } - for (size_t i = 0; i < ctx->width * ctx->height; i++) { - ctx->canvas[i] = convert_colour(_ctx, canvas[i]); - } - } - - if (font_scale_x == 1 && font_scale_y == 1) { - if (canvas == NULL) { - ctx->plot_char = plot_char_unscaled_uncanvas; + if ((glyph[y] & (0x80 >> x))) { + ctx->font_bool[offset] = true; } else { - ctx->plot_char = plot_char_unscaled_canvas; + ctx->font_bool[offset] = false; } + } + // fill columns above 8 like VGA Line Graphics Mode does + for (size_t x = 8; x < ctx->font_width; x++) { + size_t offset = + i * font_height * ctx->font_width + y * ctx->font_width + x; + + if (i >= 0xc0 && i <= 0xdf) { + ctx->font_bool[offset] = (glyph[y] & 1); + } else { + ctx->font_bool[offset] = false; + } + } + } + } + + ctx->font_scale_x = font_scale_x; + ctx->font_scale_y = font_scale_y; + + ctx->glyph_width = ctx->font_width * font_scale_x; + ctx->glyph_height = font_height * font_scale_y; + + _ctx->cols = (ctx->width - margin * 2) / ctx->glyph_width; + _ctx->rows = (ctx->height - margin * 2) / ctx->glyph_height; + + ctx->offset_x = margin + ((ctx->width - margin * 2) % ctx->glyph_width) / 2; + ctx->offset_y = margin + ((ctx->height - margin * 2) % ctx->glyph_height) / 2; + + ctx->grid_size = _ctx->rows * _ctx->cols * sizeof(struct flanterm_fb_char); + ctx->grid = _malloc(ctx->grid_size); + if (ctx->grid == NULL) { + goto fail; + } + for (size_t i = 0; i < _ctx->rows * _ctx->cols; i++) { + ctx->grid[i].c = ' '; + ctx->grid[i].fg = ctx->text_fg; + ctx->grid[i].bg = ctx->text_bg; + } + + ctx->queue_size = + _ctx->rows * _ctx->cols * sizeof(struct flanterm_fb_queue_item); + ctx->queue = _malloc(ctx->queue_size); + if (ctx->queue == NULL) { + goto fail; + } + ctx->queue_i = 0; + memset(ctx->queue, 0, ctx->queue_size); + + ctx->map_size = + _ctx->rows * _ctx->cols * sizeof(struct flanterm_fb_queue_item *); + ctx->map = _malloc(ctx->map_size); + if (ctx->map == NULL) { + goto fail; + } + memset(ctx->map, 0, ctx->map_size); + + if (canvas != NULL) { + ctx->canvas_size = ctx->width * ctx->height * sizeof(uint32_t); + ctx->canvas = _malloc(ctx->canvas_size); + if (ctx->canvas == NULL) { + goto fail; + } + for (size_t i = 0; i < ctx->width * ctx->height; i++) { + ctx->canvas[i] = convert_colour(_ctx, canvas[i]); + } + } + + if (font_scale_x == 1 && font_scale_y == 1) { + if (canvas == NULL) { + ctx->plot_char = plot_char_unscaled_uncanvas; } else { - if (canvas == NULL) { - ctx->plot_char = plot_char_scaled_uncanvas; - } else { - ctx->plot_char = plot_char_scaled_canvas; - } + ctx->plot_char = plot_char_unscaled_canvas; } + } else { + if (canvas == NULL) { + ctx->plot_char = plot_char_scaled_uncanvas; + } else { + ctx->plot_char = plot_char_scaled_canvas; + } + } - _ctx->raw_putchar = flanterm_fb_raw_putchar; - _ctx->clear = flanterm_fb_clear; - _ctx->set_cursor_pos = flanterm_fb_set_cursor_pos; - _ctx->get_cursor_pos = flanterm_fb_get_cursor_pos; - _ctx->set_text_fg = flanterm_fb_set_text_fg; - _ctx->set_text_bg = flanterm_fb_set_text_bg; - _ctx->set_text_fg_bright = flanterm_fb_set_text_fg_bright; - _ctx->set_text_bg_bright = flanterm_fb_set_text_bg_bright; - _ctx->set_text_fg_rgb = flanterm_fb_set_text_fg_rgb; - _ctx->set_text_bg_rgb = flanterm_fb_set_text_bg_rgb; - _ctx->set_text_fg_default = flanterm_fb_set_text_fg_default; - _ctx->set_text_bg_default = flanterm_fb_set_text_bg_default; - _ctx->set_text_fg_default_bright = flanterm_fb_set_text_fg_default_bright; - _ctx->set_text_bg_default_bright = flanterm_fb_set_text_bg_default_bright; - _ctx->move_character = flanterm_fb_move_character; - _ctx->scroll = flanterm_fb_scroll; - _ctx->revscroll = flanterm_fb_revscroll; - _ctx->swap_palette = flanterm_fb_swap_palette; - _ctx->save_state = flanterm_fb_save_state; - _ctx->restore_state = flanterm_fb_restore_state; - _ctx->double_buffer_flush = flanterm_fb_double_buffer_flush; - _ctx->full_refresh = flanterm_fb_full_refresh; - _ctx->deinit = flanterm_fb_deinit; + _ctx->raw_putchar = flanterm_fb_raw_putchar; + _ctx->clear = flanterm_fb_clear; + _ctx->set_cursor_pos = flanterm_fb_set_cursor_pos; + _ctx->get_cursor_pos = flanterm_fb_get_cursor_pos; + _ctx->set_text_fg = flanterm_fb_set_text_fg; + _ctx->set_text_bg = flanterm_fb_set_text_bg; + _ctx->set_text_fg_bright = flanterm_fb_set_text_fg_bright; + _ctx->set_text_bg_bright = flanterm_fb_set_text_bg_bright; + _ctx->set_text_fg_rgb = flanterm_fb_set_text_fg_rgb; + _ctx->set_text_bg_rgb = flanterm_fb_set_text_bg_rgb; + _ctx->set_text_fg_default = flanterm_fb_set_text_fg_default; + _ctx->set_text_bg_default = flanterm_fb_set_text_bg_default; + _ctx->set_text_fg_default_bright = flanterm_fb_set_text_fg_default_bright; + _ctx->set_text_bg_default_bright = flanterm_fb_set_text_bg_default_bright; + _ctx->move_character = flanterm_fb_move_character; + _ctx->scroll = flanterm_fb_scroll; + _ctx->revscroll = flanterm_fb_revscroll; + _ctx->swap_palette = flanterm_fb_swap_palette; + _ctx->save_state = flanterm_fb_save_state; + _ctx->restore_state = flanterm_fb_restore_state; + _ctx->double_buffer_flush = flanterm_fb_double_buffer_flush; + _ctx->full_refresh = flanterm_fb_full_refresh; + _ctx->deinit = flanterm_fb_deinit; - flanterm_context_reinit(_ctx); - flanterm_fb_full_refresh(_ctx); + flanterm_context_reinit(_ctx); + flanterm_fb_full_refresh(_ctx); #ifndef FLANTERM_FB_DISABLE_BUMP_ALLOC - if (_malloc == bump_alloc) { - bump_allocated_instance = true; - } + if (_malloc == bump_alloc) { + bump_allocated_instance = true; + } #endif - return _ctx; + return _ctx; fail: - if (ctx == NULL) { - return NULL; - } + if (ctx == NULL) { + return NULL; + } #ifndef FLANTERM_FB_DISABLE_BUMP_ALLOC - if (_malloc == bump_alloc) { - bump_alloc_ptr = 0; - return NULL; - } + if (_malloc == bump_alloc) { + bump_alloc_ptr = 0; + return NULL; + } #endif - if (_free == NULL) { - return NULL; - } - - if (ctx->canvas != NULL) { - _free(ctx->canvas, ctx->canvas_size); - } - if (ctx->map != NULL) { - _free(ctx->map, ctx->map_size); - } - if (ctx->queue != NULL) { - _free(ctx->queue, ctx->queue_size); - } - if (ctx->grid != NULL) { - _free(ctx->grid, ctx->grid_size); - } - if (ctx->font_bool != NULL) { - _free(ctx->font_bool, ctx->font_bool_size); - } - if (ctx->font_bits != NULL) { - _free(ctx->font_bits, ctx->font_bits_size); - } - if (ctx != NULL) { - _free(ctx, sizeof(struct flanterm_fb_context)); - } - + if (_free == NULL) { return NULL; + } + + if (ctx->canvas != NULL) { + _free(ctx->canvas, ctx->canvas_size); + } + if (ctx->map != NULL) { + _free(ctx->map, ctx->map_size); + } + if (ctx->queue != NULL) { + _free(ctx->queue, ctx->queue_size); + } + if (ctx->grid != NULL) { + _free(ctx->grid, ctx->grid_size); + } + if (ctx->font_bool != NULL) { + _free(ctx->font_bool, ctx->font_bool_size); + } + if (ctx->font_bits != NULL) { + _free(ctx->font_bits, ctx->font_bits_size); + } + if (ctx != NULL) { + _free(ctx, sizeof(struct flanterm_fb_context)); + } + + return NULL; } diff --git a/kernel/src/sys/gfx/flanterm/backends/fb.h b/kernel/src/sys/gfx/flanterm/backends/fb.h index f4e5e4a..b6a2152 100644 --- a/kernel/src/sys/gfx/flanterm/backends/fb.h +++ b/kernel/src/sys/gfx/flanterm/backends/fb.h @@ -26,9 +26,9 @@ #ifndef FLANTERM_FB_H #define FLANTERM_FB_H 1 -#include -#include #include +#include +#include #ifdef __cplusplus extern "C" { @@ -43,23 +43,24 @@ extern "C" { #endif struct flanterm_context *flanterm_fb_init( - /* If _malloc and _free are nulled, use the bump allocated instance (1 use only). */ + /* If _malloc and _free are nulled, use the bump allocated instance (1 use + only). */ void *(*_malloc)(size_t size), - void (*_free)(void *ptr, size_t size), - uint32_t *framebuffer, size_t width, size_t height, size_t pitch, - uint8_t red_mask_size, uint8_t red_mask_shift, - uint8_t green_mask_size, uint8_t green_mask_shift, - uint8_t blue_mask_size, uint8_t blue_mask_shift, - uint32_t *canvas, /* If nulled, no canvas. */ - uint32_t *ansi_colours, uint32_t *ansi_bright_colours, /* If nulled, default. */ + void (*_free)(void *ptr, size_t size), uint32_t *framebuffer, size_t width, + size_t height, size_t pitch, uint8_t red_mask_size, uint8_t red_mask_shift, + uint8_t green_mask_size, uint8_t green_mask_shift, uint8_t blue_mask_size, + uint8_t blue_mask_shift, uint32_t *canvas, /* If nulled, no canvas. */ + uint32_t *ansi_colours, + uint32_t *ansi_bright_colours, /* If nulled, default. */ uint32_t *default_bg, uint32_t *default_fg, /* If nulled, default. */ - uint32_t *default_bg_bright, uint32_t *default_fg_bright, /* If nulled, default. */ - /* If font is null, use default font and font_width and font_height ignored. */ + uint32_t *default_bg_bright, + uint32_t *default_fg_bright, /* If nulled, default. */ + /* If font is null, use default font and font_width and font_height ignored. + */ void *font, size_t font_width, size_t font_height, size_t font_spacing, - /* If scale_x and scale_y are 0, automatically scale font based on resolution. */ - size_t font_scale_x, size_t font_scale_y, - size_t margin -); + /* If scale_x and scale_y are 0, automatically scale font based on + resolution. */ + size_t font_scale_x, size_t font_scale_y, size_t margin); #ifdef __cplusplus } diff --git a/kernel/src/sys/gfx/flanterm/backends/fb_private.h b/kernel/src/sys/gfx/flanterm/backends/fb_private.h index 532e1ab..5985a6a 100644 --- a/kernel/src/sys/gfx/flanterm/backends/fb_private.h +++ b/kernel/src/sys/gfx/flanterm/backends/fb_private.h @@ -30,9 +30,9 @@ #error "Do not use fb_private.h. Use interfaces defined in fb.h only." #endif -#include -#include #include +#include +#include #ifdef __cplusplus extern "C" { @@ -41,77 +41,78 @@ extern "C" { #define FLANTERM_FB_FONT_GLYPHS 256 struct flanterm_fb_char { - uint32_t c; - uint32_t fg; - uint32_t bg; + uint32_t c; + uint32_t fg; + uint32_t bg; }; struct flanterm_fb_queue_item { - size_t x, y; - struct flanterm_fb_char c; + size_t x, y; + struct flanterm_fb_char c; }; struct flanterm_fb_context { - struct flanterm_context term; + struct flanterm_context term; - void (*plot_char)(struct flanterm_context *ctx, struct flanterm_fb_char *c, size_t x, size_t y); + void (*plot_char)(struct flanterm_context *ctx, struct flanterm_fb_char *c, + size_t x, size_t y); - size_t font_width; - size_t font_height; - size_t glyph_width; - size_t glyph_height; + size_t font_width; + size_t font_height; + size_t glyph_width; + size_t glyph_height; - size_t font_scale_x; - size_t font_scale_y; + size_t font_scale_x; + size_t font_scale_y; - size_t offset_x, offset_y; + size_t offset_x, offset_y; - volatile uint32_t *framebuffer; - size_t pitch; - size_t width; - size_t height; - size_t bpp; + volatile uint32_t *framebuffer; + size_t pitch; + size_t width; + size_t height; + size_t bpp; - uint8_t red_mask_size, red_mask_shift; - uint8_t green_mask_size, green_mask_shift; - uint8_t blue_mask_size, blue_mask_shift; + uint8_t red_mask_size, red_mask_shift; + uint8_t green_mask_size, green_mask_shift; + uint8_t blue_mask_size, blue_mask_shift; - size_t font_bits_size; - uint8_t *font_bits; - size_t font_bool_size; - bool *font_bool; + size_t font_bits_size; + uint8_t *font_bits; + size_t font_bool_size; + bool *font_bool; - uint32_t ansi_colours[8]; - uint32_t ansi_bright_colours[8]; - uint32_t default_fg, default_bg; - uint32_t default_fg_bright, default_bg_bright; + uint32_t ansi_colours[8]; + uint32_t ansi_bright_colours[8]; + uint32_t default_fg, default_bg; + uint32_t default_fg_bright, default_bg_bright; - size_t canvas_size; - uint32_t *canvas; + size_t canvas_size; + uint32_t *canvas; - size_t grid_size; - size_t queue_size; - size_t map_size; + size_t grid_size; + size_t queue_size; + size_t map_size; - struct flanterm_fb_char *grid; + struct flanterm_fb_char *grid; - struct flanterm_fb_queue_item *queue; - size_t queue_i; + struct flanterm_fb_queue_item *queue; + size_t queue_i; - struct flanterm_fb_queue_item **map; + struct flanterm_fb_queue_item **map; - uint32_t text_fg; - uint32_t text_bg; - size_t cursor_x; - size_t cursor_y; + uint32_t text_fg; + uint32_t text_bg; + size_t cursor_x; + size_t cursor_y; - uint32_t saved_state_text_fg; - uint32_t saved_state_text_bg; - size_t saved_state_cursor_x; - size_t saved_state_cursor_y; + uint32_t saved_state_text_fg; + uint32_t saved_state_text_bg; + size_t saved_state_cursor_x; + size_t saved_state_cursor_y; - size_t old_cursor_x; - size_t old_cursor_y; + size_t old_cursor_x; + size_t old_cursor_y; }; #ifdef __cplusplus diff --git a/kernel/src/sys/gfx/flanterm/flanterm.c b/kernel/src/sys/gfx/flanterm/flanterm.c index 89e0f0a..ae77986 100644 --- a/kernel/src/sys/gfx/flanterm/flanterm.c +++ b/kernel/src/sys/gfx/flanterm/flanterm.c @@ -24,16 +24,17 @@ */ #ifdef __cplusplus -#error "Please do not compile Flanterm as C++ code! Flanterm should be compiled as C99 or newer." +#error \ + "Please do not compile Flanterm as C++ code! Flanterm should be compiled as C99 or newer." #endif #ifndef __STDC_VERSION__ #error "Flanterm must be compiled as C99 or newer." #endif -#include -#include #include +#include +#include #define FLANTERM_IN_FLANTERM @@ -43,894 +44,950 @@ // https://man7.org/linux/man-pages/man4/console_codes.4.html static const uint32_t col256[] = { - 0x000000, 0x00005f, 0x000087, 0x0000af, 0x0000d7, 0x0000ff, 0x005f00, 0x005f5f, - 0x005f87, 0x005faf, 0x005fd7, 0x005fff, 0x008700, 0x00875f, 0x008787, 0x0087af, - 0x0087d7, 0x0087ff, 0x00af00, 0x00af5f, 0x00af87, 0x00afaf, 0x00afd7, 0x00afff, - 0x00d700, 0x00d75f, 0x00d787, 0x00d7af, 0x00d7d7, 0x00d7ff, 0x00ff00, 0x00ff5f, - 0x00ff87, 0x00ffaf, 0x00ffd7, 0x00ffff, 0x5f0000, 0x5f005f, 0x5f0087, 0x5f00af, - 0x5f00d7, 0x5f00ff, 0x5f5f00, 0x5f5f5f, 0x5f5f87, 0x5f5faf, 0x5f5fd7, 0x5f5fff, - 0x5f8700, 0x5f875f, 0x5f8787, 0x5f87af, 0x5f87d7, 0x5f87ff, 0x5faf00, 0x5faf5f, - 0x5faf87, 0x5fafaf, 0x5fafd7, 0x5fafff, 0x5fd700, 0x5fd75f, 0x5fd787, 0x5fd7af, - 0x5fd7d7, 0x5fd7ff, 0x5fff00, 0x5fff5f, 0x5fff87, 0x5fffaf, 0x5fffd7, 0x5fffff, - 0x870000, 0x87005f, 0x870087, 0x8700af, 0x8700d7, 0x8700ff, 0x875f00, 0x875f5f, - 0x875f87, 0x875faf, 0x875fd7, 0x875fff, 0x878700, 0x87875f, 0x878787, 0x8787af, - 0x8787d7, 0x8787ff, 0x87af00, 0x87af5f, 0x87af87, 0x87afaf, 0x87afd7, 0x87afff, - 0x87d700, 0x87d75f, 0x87d787, 0x87d7af, 0x87d7d7, 0x87d7ff, 0x87ff00, 0x87ff5f, - 0x87ff87, 0x87ffaf, 0x87ffd7, 0x87ffff, 0xaf0000, 0xaf005f, 0xaf0087, 0xaf00af, - 0xaf00d7, 0xaf00ff, 0xaf5f00, 0xaf5f5f, 0xaf5f87, 0xaf5faf, 0xaf5fd7, 0xaf5fff, - 0xaf8700, 0xaf875f, 0xaf8787, 0xaf87af, 0xaf87d7, 0xaf87ff, 0xafaf00, 0xafaf5f, - 0xafaf87, 0xafafaf, 0xafafd7, 0xafafff, 0xafd700, 0xafd75f, 0xafd787, 0xafd7af, - 0xafd7d7, 0xafd7ff, 0xafff00, 0xafff5f, 0xafff87, 0xafffaf, 0xafffd7, 0xafffff, - 0xd70000, 0xd7005f, 0xd70087, 0xd700af, 0xd700d7, 0xd700ff, 0xd75f00, 0xd75f5f, - 0xd75f87, 0xd75faf, 0xd75fd7, 0xd75fff, 0xd78700, 0xd7875f, 0xd78787, 0xd787af, - 0xd787d7, 0xd787ff, 0xd7af00, 0xd7af5f, 0xd7af87, 0xd7afaf, 0xd7afd7, 0xd7afff, - 0xd7d700, 0xd7d75f, 0xd7d787, 0xd7d7af, 0xd7d7d7, 0xd7d7ff, 0xd7ff00, 0xd7ff5f, - 0xd7ff87, 0xd7ffaf, 0xd7ffd7, 0xd7ffff, 0xff0000, 0xff005f, 0xff0087, 0xff00af, - 0xff00d7, 0xff00ff, 0xff5f00, 0xff5f5f, 0xff5f87, 0xff5faf, 0xff5fd7, 0xff5fff, - 0xff8700, 0xff875f, 0xff8787, 0xff87af, 0xff87d7, 0xff87ff, 0xffaf00, 0xffaf5f, - 0xffaf87, 0xffafaf, 0xffafd7, 0xffafff, 0xffd700, 0xffd75f, 0xffd787, 0xffd7af, - 0xffd7d7, 0xffd7ff, 0xffff00, 0xffff5f, 0xffff87, 0xffffaf, 0xffffd7, 0xffffff, - 0x080808, 0x121212, 0x1c1c1c, 0x262626, 0x303030, 0x3a3a3a, 0x444444, 0x4e4e4e, - 0x585858, 0x626262, 0x6c6c6c, 0x767676, 0x808080, 0x8a8a8a, 0x949494, 0x9e9e9e, - 0xa8a8a8, 0xb2b2b2, 0xbcbcbc, 0xc6c6c6, 0xd0d0d0, 0xdadada, 0xe4e4e4, 0xeeeeee -}; + 0x000000, 0x00005f, 0x000087, 0x0000af, 0x0000d7, 0x0000ff, 0x005f00, + 0x005f5f, 0x005f87, 0x005faf, 0x005fd7, 0x005fff, 0x008700, 0x00875f, + 0x008787, 0x0087af, 0x0087d7, 0x0087ff, 0x00af00, 0x00af5f, 0x00af87, + 0x00afaf, 0x00afd7, 0x00afff, 0x00d700, 0x00d75f, 0x00d787, 0x00d7af, + 0x00d7d7, 0x00d7ff, 0x00ff00, 0x00ff5f, 0x00ff87, 0x00ffaf, 0x00ffd7, + 0x00ffff, 0x5f0000, 0x5f005f, 0x5f0087, 0x5f00af, 0x5f00d7, 0x5f00ff, + 0x5f5f00, 0x5f5f5f, 0x5f5f87, 0x5f5faf, 0x5f5fd7, 0x5f5fff, 0x5f8700, + 0x5f875f, 0x5f8787, 0x5f87af, 0x5f87d7, 0x5f87ff, 0x5faf00, 0x5faf5f, + 0x5faf87, 0x5fafaf, 0x5fafd7, 0x5fafff, 0x5fd700, 0x5fd75f, 0x5fd787, + 0x5fd7af, 0x5fd7d7, 0x5fd7ff, 0x5fff00, 0x5fff5f, 0x5fff87, 0x5fffaf, + 0x5fffd7, 0x5fffff, 0x870000, 0x87005f, 0x870087, 0x8700af, 0x8700d7, + 0x8700ff, 0x875f00, 0x875f5f, 0x875f87, 0x875faf, 0x875fd7, 0x875fff, + 0x878700, 0x87875f, 0x878787, 0x8787af, 0x8787d7, 0x8787ff, 0x87af00, + 0x87af5f, 0x87af87, 0x87afaf, 0x87afd7, 0x87afff, 0x87d700, 0x87d75f, + 0x87d787, 0x87d7af, 0x87d7d7, 0x87d7ff, 0x87ff00, 0x87ff5f, 0x87ff87, + 0x87ffaf, 0x87ffd7, 0x87ffff, 0xaf0000, 0xaf005f, 0xaf0087, 0xaf00af, + 0xaf00d7, 0xaf00ff, 0xaf5f00, 0xaf5f5f, 0xaf5f87, 0xaf5faf, 0xaf5fd7, + 0xaf5fff, 0xaf8700, 0xaf875f, 0xaf8787, 0xaf87af, 0xaf87d7, 0xaf87ff, + 0xafaf00, 0xafaf5f, 0xafaf87, 0xafafaf, 0xafafd7, 0xafafff, 0xafd700, + 0xafd75f, 0xafd787, 0xafd7af, 0xafd7d7, 0xafd7ff, 0xafff00, 0xafff5f, + 0xafff87, 0xafffaf, 0xafffd7, 0xafffff, 0xd70000, 0xd7005f, 0xd70087, + 0xd700af, 0xd700d7, 0xd700ff, 0xd75f00, 0xd75f5f, 0xd75f87, 0xd75faf, + 0xd75fd7, 0xd75fff, 0xd78700, 0xd7875f, 0xd78787, 0xd787af, 0xd787d7, + 0xd787ff, 0xd7af00, 0xd7af5f, 0xd7af87, 0xd7afaf, 0xd7afd7, 0xd7afff, + 0xd7d700, 0xd7d75f, 0xd7d787, 0xd7d7af, 0xd7d7d7, 0xd7d7ff, 0xd7ff00, + 0xd7ff5f, 0xd7ff87, 0xd7ffaf, 0xd7ffd7, 0xd7ffff, 0xff0000, 0xff005f, + 0xff0087, 0xff00af, 0xff00d7, 0xff00ff, 0xff5f00, 0xff5f5f, 0xff5f87, + 0xff5faf, 0xff5fd7, 0xff5fff, 0xff8700, 0xff875f, 0xff8787, 0xff87af, + 0xff87d7, 0xff87ff, 0xffaf00, 0xffaf5f, 0xffaf87, 0xffafaf, 0xffafd7, + 0xffafff, 0xffd700, 0xffd75f, 0xffd787, 0xffd7af, 0xffd7d7, 0xffd7ff, + 0xffff00, 0xffff5f, 0xffff87, 0xffffaf, 0xffffd7, 0xffffff, 0x080808, + 0x121212, 0x1c1c1c, 0x262626, 0x303030, 0x3a3a3a, 0x444444, 0x4e4e4e, + 0x585858, 0x626262, 0x6c6c6c, 0x767676, 0x808080, 0x8a8a8a, 0x949494, + 0x9e9e9e, 0xa8a8a8, 0xb2b2b2, 0xbcbcbc, 0xc6c6c6, 0xd0d0d0, 0xdadada, + 0xe4e4e4, 0xeeeeee}; #define CHARSET_DEFAULT 0 #define CHARSET_DEC_SPECIAL 1 void flanterm_context_reinit(struct flanterm_context *ctx) { - ctx->tab_size = 8; - ctx->autoflush = true; - ctx->cursor_enabled = true; - ctx->scroll_enabled = true; - ctx->control_sequence = false; - ctx->escape = false; - ctx->osc = false; - ctx->osc_escape = false; - ctx->rrr = false; - ctx->discard_next = false; - ctx->bold = false; - ctx->bg_bold = false; - ctx->reverse_video = false; - ctx->dec_private = false; - ctx->insert_mode = false; - ctx->unicode_remaining = 0; - ctx->g_select = 0; - ctx->charsets[0] = CHARSET_DEFAULT; - ctx->charsets[1] = CHARSET_DEC_SPECIAL; - ctx->current_charset = 0; - ctx->escape_offset = 0; - ctx->esc_values_i = 0; - ctx->saved_cursor_x = 0; - ctx->saved_cursor_y = 0; - ctx->current_primary = (size_t)-1; - ctx->current_bg = (size_t)-1; - ctx->scroll_top_margin = 0; - ctx->scroll_bottom_margin = ctx->rows; - ctx->oob_output = FLANTERM_OOB_OUTPUT_ONLCR; + ctx->tab_size = 8; + ctx->autoflush = true; + ctx->cursor_enabled = true; + ctx->scroll_enabled = true; + ctx->control_sequence = false; + ctx->escape = false; + ctx->osc = false; + ctx->osc_escape = false; + ctx->rrr = false; + ctx->discard_next = false; + ctx->bold = false; + ctx->bg_bold = false; + ctx->reverse_video = false; + ctx->dec_private = false; + ctx->insert_mode = false; + ctx->unicode_remaining = 0; + ctx->g_select = 0; + ctx->charsets[0] = CHARSET_DEFAULT; + ctx->charsets[1] = CHARSET_DEC_SPECIAL; + ctx->current_charset = 0; + ctx->escape_offset = 0; + ctx->esc_values_i = 0; + ctx->saved_cursor_x = 0; + ctx->saved_cursor_y = 0; + ctx->current_primary = (size_t)-1; + ctx->current_bg = (size_t)-1; + ctx->scroll_top_margin = 0; + ctx->scroll_bottom_margin = ctx->rows; + ctx->oob_output = FLANTERM_OOB_OUTPUT_ONLCR; } static void flanterm_putchar(struct flanterm_context *ctx, uint8_t c); -void flanterm_write(struct flanterm_context *ctx, const char *buf, size_t count) { - for (size_t i = 0; i < count; i++) { - flanterm_putchar(ctx, buf[i]); - } +void flanterm_write(struct flanterm_context *ctx, const char *buf, + size_t count) { + for (size_t i = 0; i < count; i++) { + flanterm_putchar(ctx, buf[i]); + } - if (ctx->autoflush) { - ctx->double_buffer_flush(ctx); - } + if (ctx->autoflush) { + ctx->double_buffer_flush(ctx); + } } static void sgr(struct flanterm_context *ctx) { - size_t i = 0; + size_t i = 0; - if (!ctx->esc_values_i) - goto def; + if (!ctx->esc_values_i) + goto def; - for (; i < ctx->esc_values_i; i++) { - size_t offset; + for (; i < ctx->esc_values_i; i++) { + size_t offset; - if (ctx->esc_values[i] == 0) { -def: - if (ctx->reverse_video) { - ctx->reverse_video = false; - ctx->swap_palette(ctx); - } - ctx->bold = false; - ctx->bg_bold = false; - ctx->current_primary = (size_t)-1; - ctx->current_bg = (size_t)-1; - ctx->set_text_bg_default(ctx); - ctx->set_text_fg_default(ctx); - continue; - } - - else if (ctx->esc_values[i] == 1) { - ctx->bold = true; - if (ctx->current_primary != (size_t)-1) { - if (!ctx->reverse_video) { - ctx->set_text_fg_bright(ctx, ctx->current_primary); - } else { - ctx->set_text_bg_bright(ctx, ctx->current_primary); - } - } else { - if (!ctx->reverse_video) { - ctx->set_text_fg_default_bright(ctx); - } else { - ctx->set_text_bg_default_bright(ctx); - } - } - continue; - } - - else if (ctx->esc_values[i] == 5) { - ctx->bg_bold = true; - if (ctx->current_bg != (size_t)-1) { - if (!ctx->reverse_video) { - ctx->set_text_bg_bright(ctx, ctx->current_bg); - } else { - ctx->set_text_fg_bright(ctx, ctx->current_bg); - } - } else { - if (!ctx->reverse_video) { - ctx->set_text_bg_default_bright(ctx); - } else { - ctx->set_text_fg_default_bright(ctx); - } - } - continue; - } - - else if (ctx->esc_values[i] == 22) { - ctx->bold = false; - if (ctx->current_primary != (size_t)-1) { - if (!ctx->reverse_video) { - ctx->set_text_fg(ctx, ctx->current_primary); - } else { - ctx->set_text_bg(ctx, ctx->current_primary); - } - } else { - if (!ctx->reverse_video) { - ctx->set_text_fg_default(ctx); - } else { - ctx->set_text_bg_default(ctx); - } - } - continue; - } - - else if (ctx->esc_values[i] == 25) { - ctx->bg_bold = false; - if (ctx->current_bg != (size_t)-1) { - if (!ctx->reverse_video) { - ctx->set_text_bg(ctx, ctx->current_bg); - } else { - ctx->set_text_fg(ctx, ctx->current_bg); - } - } else { - if (!ctx->reverse_video) { - ctx->set_text_bg_default(ctx); - } else { - ctx->set_text_fg_default(ctx); - } - } - continue; - } - - else if (ctx->esc_values[i] >= 30 && ctx->esc_values[i] <= 37) { - offset = 30; - ctx->current_primary = ctx->esc_values[i] - offset; - - if (ctx->reverse_video) { - goto set_bg; - } - -set_fg: - if ((ctx->bold && !ctx->reverse_video) - || (ctx->bg_bold && ctx->reverse_video)) { - ctx->set_text_fg_bright(ctx, ctx->esc_values[i] - offset); - } else { - ctx->set_text_fg(ctx, ctx->esc_values[i] - offset); - } - continue; - } - - else if (ctx->esc_values[i] >= 40 && ctx->esc_values[i] <= 47) { - offset = 40; - ctx->current_bg = ctx->esc_values[i] - offset; - - if (ctx->reverse_video) { - goto set_fg; - } - -set_bg: - if ((ctx->bold && ctx->reverse_video) - || (ctx->bg_bold && !ctx->reverse_video)) { - ctx->set_text_bg_bright(ctx, ctx->esc_values[i] - offset); - } else { - ctx->set_text_bg(ctx, ctx->esc_values[i] - offset); - } - continue; - } - - else if (ctx->esc_values[i] >= 90 && ctx->esc_values[i] <= 97) { - offset = 90; - ctx->current_primary = ctx->esc_values[i] - offset; - - if (ctx->reverse_video) { - goto set_bg_bright; - } - -set_fg_bright: - ctx->set_text_fg_bright(ctx, ctx->esc_values[i] - offset); - continue; - } - - else if (ctx->esc_values[i] >= 100 && ctx->esc_values[i] <= 107) { - offset = 100; - ctx->current_bg = ctx->esc_values[i] - offset; - - if (ctx->reverse_video) { - goto set_fg_bright; - } - -set_bg_bright: - ctx->set_text_bg_bright(ctx, ctx->esc_values[i] - offset); - continue; - } - - else if (ctx->esc_values[i] == 39) { - ctx->current_primary = (size_t)-1; - - if (ctx->reverse_video) { - ctx->swap_palette(ctx); - } - - if (!ctx->bold) { - ctx->set_text_fg_default(ctx); - } else { - ctx->set_text_fg_default_bright(ctx); - } - - if (ctx->reverse_video) { - ctx->swap_palette(ctx); - } - - continue; - } - - else if (ctx->esc_values[i] == 49) { - ctx->current_bg = (size_t)-1; - - if (ctx->reverse_video) { - ctx->swap_palette(ctx); - } - - if (!ctx->bg_bold) { - ctx->set_text_bg_default(ctx); - } else { - ctx->set_text_bg_default_bright(ctx); - } - - if (ctx->reverse_video) { - ctx->swap_palette(ctx); - } - - continue; - } - - else if (ctx->esc_values[i] == 7) { - if (!ctx->reverse_video) { - ctx->reverse_video = true; - ctx->swap_palette(ctx); - } - continue; - } - - else if (ctx->esc_values[i] == 27) { - if (ctx->reverse_video) { - ctx->reverse_video = false; - ctx->swap_palette(ctx); - } - continue; - } - - // 256/RGB - else if (ctx->esc_values[i] == 38 || ctx->esc_values[i] == 48) { - bool fg = ctx->esc_values[i] == 38; - - i++; - if (i >= ctx->esc_values_i) { - break; - } - - switch (ctx->esc_values[i]) { - case 2: { // RGB - if (i + 3 >= ctx->esc_values_i) { - goto out; - } - - uint32_t rgb_value = 0; - - rgb_value |= ctx->esc_values[i + 1] << 16; - rgb_value |= ctx->esc_values[i + 2] << 8; - rgb_value |= ctx->esc_values[i + 3]; - - i += 3; - - (fg ? ctx->set_text_fg_rgb : ctx->set_text_bg_rgb)(ctx, rgb_value); - - break; - } - case 5: { // 256 colors - if (i + 1 >= ctx->esc_values_i) { - goto out; - } - - uint32_t col = ctx->esc_values[i + 1]; - - i++; - - if (col < 8) { - (fg ? ctx->set_text_fg : ctx->set_text_bg)(ctx, col); - } else if (col < 16) { - (fg ? ctx->set_text_fg_bright : ctx->set_text_bg_bright)(ctx, col - 8); - } else if (col < 256) { - uint32_t rgb_value = col256[col - 16]; - (fg ? ctx->set_text_fg_rgb : ctx->set_text_bg_rgb)(ctx, rgb_value); - } - - break; - } - default: continue; - } - } + if (ctx->esc_values[i] == 0) { + def: + if (ctx->reverse_video) { + ctx->reverse_video = false; + ctx->swap_palette(ctx); + } + ctx->bold = false; + ctx->bg_bold = false; + ctx->current_primary = (size_t)-1; + ctx->current_bg = (size_t)-1; + ctx->set_text_bg_default(ctx); + ctx->set_text_fg_default(ctx); + continue; } + else if (ctx->esc_values[i] == 1) { + ctx->bold = true; + if (ctx->current_primary != (size_t)-1) { + if (!ctx->reverse_video) { + ctx->set_text_fg_bright(ctx, ctx->current_primary); + } else { + ctx->set_text_bg_bright(ctx, ctx->current_primary); + } + } else { + if (!ctx->reverse_video) { + ctx->set_text_fg_default_bright(ctx); + } else { + ctx->set_text_bg_default_bright(ctx); + } + } + continue; + } + + else if (ctx->esc_values[i] == 5) { + ctx->bg_bold = true; + if (ctx->current_bg != (size_t)-1) { + if (!ctx->reverse_video) { + ctx->set_text_bg_bright(ctx, ctx->current_bg); + } else { + ctx->set_text_fg_bright(ctx, ctx->current_bg); + } + } else { + if (!ctx->reverse_video) { + ctx->set_text_bg_default_bright(ctx); + } else { + ctx->set_text_fg_default_bright(ctx); + } + } + continue; + } + + else if (ctx->esc_values[i] == 22) { + ctx->bold = false; + if (ctx->current_primary != (size_t)-1) { + if (!ctx->reverse_video) { + ctx->set_text_fg(ctx, ctx->current_primary); + } else { + ctx->set_text_bg(ctx, ctx->current_primary); + } + } else { + if (!ctx->reverse_video) { + ctx->set_text_fg_default(ctx); + } else { + ctx->set_text_bg_default(ctx); + } + } + continue; + } + + else if (ctx->esc_values[i] == 25) { + ctx->bg_bold = false; + if (ctx->current_bg != (size_t)-1) { + if (!ctx->reverse_video) { + ctx->set_text_bg(ctx, ctx->current_bg); + } else { + ctx->set_text_fg(ctx, ctx->current_bg); + } + } else { + if (!ctx->reverse_video) { + ctx->set_text_bg_default(ctx); + } else { + ctx->set_text_fg_default(ctx); + } + } + continue; + } + + else if (ctx->esc_values[i] >= 30 && ctx->esc_values[i] <= 37) { + offset = 30; + ctx->current_primary = ctx->esc_values[i] - offset; + + if (ctx->reverse_video) { + goto set_bg; + } + + set_fg: + if ((ctx->bold && !ctx->reverse_video) || + (ctx->bg_bold && ctx->reverse_video)) { + ctx->set_text_fg_bright(ctx, ctx->esc_values[i] - offset); + } else { + ctx->set_text_fg(ctx, ctx->esc_values[i] - offset); + } + continue; + } + + else if (ctx->esc_values[i] >= 40 && ctx->esc_values[i] <= 47) { + offset = 40; + ctx->current_bg = ctx->esc_values[i] - offset; + + if (ctx->reverse_video) { + goto set_fg; + } + + set_bg: + if ((ctx->bold && ctx->reverse_video) || + (ctx->bg_bold && !ctx->reverse_video)) { + ctx->set_text_bg_bright(ctx, ctx->esc_values[i] - offset); + } else { + ctx->set_text_bg(ctx, ctx->esc_values[i] - offset); + } + continue; + } + + else if (ctx->esc_values[i] >= 90 && ctx->esc_values[i] <= 97) { + offset = 90; + ctx->current_primary = ctx->esc_values[i] - offset; + + if (ctx->reverse_video) { + goto set_bg_bright; + } + + set_fg_bright: + ctx->set_text_fg_bright(ctx, ctx->esc_values[i] - offset); + continue; + } + + else if (ctx->esc_values[i] >= 100 && ctx->esc_values[i] <= 107) { + offset = 100; + ctx->current_bg = ctx->esc_values[i] - offset; + + if (ctx->reverse_video) { + goto set_fg_bright; + } + + set_bg_bright: + ctx->set_text_bg_bright(ctx, ctx->esc_values[i] - offset); + continue; + } + + else if (ctx->esc_values[i] == 39) { + ctx->current_primary = (size_t)-1; + + if (ctx->reverse_video) { + ctx->swap_palette(ctx); + } + + if (!ctx->bold) { + ctx->set_text_fg_default(ctx); + } else { + ctx->set_text_fg_default_bright(ctx); + } + + if (ctx->reverse_video) { + ctx->swap_palette(ctx); + } + + continue; + } + + else if (ctx->esc_values[i] == 49) { + ctx->current_bg = (size_t)-1; + + if (ctx->reverse_video) { + ctx->swap_palette(ctx); + } + + if (!ctx->bg_bold) { + ctx->set_text_bg_default(ctx); + } else { + ctx->set_text_bg_default_bright(ctx); + } + + if (ctx->reverse_video) { + ctx->swap_palette(ctx); + } + + continue; + } + + else if (ctx->esc_values[i] == 7) { + if (!ctx->reverse_video) { + ctx->reverse_video = true; + ctx->swap_palette(ctx); + } + continue; + } + + else if (ctx->esc_values[i] == 27) { + if (ctx->reverse_video) { + ctx->reverse_video = false; + ctx->swap_palette(ctx); + } + continue; + } + + // 256/RGB + else if (ctx->esc_values[i] == 38 || ctx->esc_values[i] == 48) { + bool fg = ctx->esc_values[i] == 38; + + i++; + if (i >= ctx->esc_values_i) { + break; + } + + switch (ctx->esc_values[i]) { + case 2: { // RGB + if (i + 3 >= ctx->esc_values_i) { + goto out; + } + + uint32_t rgb_value = 0; + + rgb_value |= ctx->esc_values[i + 1] << 16; + rgb_value |= ctx->esc_values[i + 2] << 8; + rgb_value |= ctx->esc_values[i + 3]; + + i += 3; + + (fg ? ctx->set_text_fg_rgb : ctx->set_text_bg_rgb)(ctx, rgb_value); + + break; + } + case 5: { // 256 colors + if (i + 1 >= ctx->esc_values_i) { + goto out; + } + + uint32_t col = ctx->esc_values[i + 1]; + + i++; + + if (col < 8) { + (fg ? ctx->set_text_fg : ctx->set_text_bg)(ctx, col); + } else if (col < 16) { + (fg ? ctx->set_text_fg_bright : ctx->set_text_bg_bright)(ctx, + col - 8); + } else if (col < 256) { + uint32_t rgb_value = col256[col - 16]; + (fg ? ctx->set_text_fg_rgb : ctx->set_text_bg_rgb)(ctx, rgb_value); + } + + break; + } + default: + continue; + } + } + } + out:; } static void dec_private_parse(struct flanterm_context *ctx, uint8_t c) { - ctx->dec_private = false; + ctx->dec_private = false; - if (ctx->esc_values_i == 0) { - return; + if (ctx->esc_values_i == 0) { + return; + } + + bool set; + + switch (c) { + case 'h': + set = true; + break; + case 'l': + set = false; + break; + default: + return; + } + + switch (ctx->esc_values[0]) { + case 25: { + if (set) { + ctx->cursor_enabled = true; + } else { + ctx->cursor_enabled = false; } + return; + } + } - bool set; - - switch (c) { - case 'h': - set = true; break; - case 'l': - set = false; break; - default: - return; - } - - switch (ctx->esc_values[0]) { - case 25: { - if (set) { - ctx->cursor_enabled = true; - } else { - ctx->cursor_enabled = false; - } - return; - } - } - - if (ctx->callback != NULL) { - ctx->callback(ctx, FLANTERM_CB_DEC, ctx->esc_values_i, (uintptr_t)ctx->esc_values, c); - } + if (ctx->callback != NULL) { + ctx->callback(ctx, FLANTERM_CB_DEC, ctx->esc_values_i, + (uintptr_t)ctx->esc_values, c); + } } static void linux_private_parse(struct flanterm_context *ctx) { - if (ctx->esc_values_i == 0) { - return; - } + if (ctx->esc_values_i == 0) { + return; + } - if (ctx->callback != NULL) { - ctx->callback(ctx, FLANTERM_CB_LINUX, ctx->esc_values_i, (uintptr_t)ctx->esc_values, 0); - } + if (ctx->callback != NULL) { + ctx->callback(ctx, FLANTERM_CB_LINUX, ctx->esc_values_i, + (uintptr_t)ctx->esc_values, 0); + } } static void mode_toggle(struct flanterm_context *ctx, uint8_t c) { - if (ctx->esc_values_i == 0) { - return; - } + if (ctx->esc_values_i == 0) { + return; + } - bool set; + bool set; - switch (c) { - case 'h': - set = true; break; - case 'l': - set = false; break; - default: - return; - } + switch (c) { + case 'h': + set = true; + break; + case 'l': + set = false; + break; + default: + return; + } - switch (ctx->esc_values[0]) { - case 4: - ctx->insert_mode = set; return; - } + switch (ctx->esc_values[0]) { + case 4: + ctx->insert_mode = set; + return; + } - if (ctx->callback != NULL) { - ctx->callback(ctx, FLANTERM_CB_MODE, ctx->esc_values_i, (uintptr_t)ctx->esc_values, c); - } + if (ctx->callback != NULL) { + ctx->callback(ctx, FLANTERM_CB_MODE, ctx->esc_values_i, + (uintptr_t)ctx->esc_values, c); + } } static void osc_parse(struct flanterm_context *ctx, uint8_t c) { - if (ctx->osc_escape && c == '\\') { - goto cleanup; - } + if (ctx->osc_escape && c == '\\') { + goto cleanup; + } - ctx->osc_escape = false; + ctx->osc_escape = false; - switch (c) { - case 0x1b: - ctx->osc_escape = true; - return; - case '\a': - default: - break; - } + switch (c) { + case 0x1b: + ctx->osc_escape = true; + return; + case '\a': + default: + break; + } cleanup: - ctx->osc_escape = false; - ctx->osc = false; - ctx->escape = false; + ctx->osc_escape = false; + ctx->osc = false; + ctx->escape = false; } static void control_sequence_parse(struct flanterm_context *ctx, uint8_t c) { - if (ctx->escape_offset == 2) { - switch (c) { - case '[': - ctx->discard_next = true; - goto cleanup; - case '?': - ctx->dec_private = true; - return; - } - } - - if (c >= '0' && c <= '9') { - if (ctx->esc_values_i == FLANTERM_MAX_ESC_VALUES) { - return; - } - ctx->rrr = true; - ctx->esc_values[ctx->esc_values_i] *= 10; - ctx->esc_values[ctx->esc_values_i] += c - '0'; - return; - } - - if (ctx->rrr == true) { - ctx->esc_values_i++; - ctx->rrr = false; - if (c == ';') - return; - } else if (c == ';') { - if (ctx->esc_values_i == FLANTERM_MAX_ESC_VALUES) { - return; - } - ctx->esc_values[ctx->esc_values_i] = 0; - ctx->esc_values_i++; - return; - } - - size_t esc_default; + if (ctx->escape_offset == 2) { switch (c) { - case 'J': case 'K': case 'q': - esc_default = 0; break; - default: - esc_default = 1; break; + case '[': + ctx->discard_next = true; + goto cleanup; + case '?': + ctx->dec_private = true; + return; } + } - for (size_t i = ctx->esc_values_i; i < FLANTERM_MAX_ESC_VALUES; i++) { - ctx->esc_values[i] = esc_default; + if (c >= '0' && c <= '9') { + if (ctx->esc_values_i == FLANTERM_MAX_ESC_VALUES) { + return; } + ctx->rrr = true; + ctx->esc_values[ctx->esc_values_i] *= 10; + ctx->esc_values[ctx->esc_values_i] += c - '0'; + return; + } - if (ctx->dec_private == true) { - dec_private_parse(ctx, c); - goto cleanup; + if (ctx->rrr == true) { + ctx->esc_values_i++; + ctx->rrr = false; + if (c == ';') + return; + } else if (c == ';') { + if (ctx->esc_values_i == FLANTERM_MAX_ESC_VALUES) { + return; } + ctx->esc_values[ctx->esc_values_i] = 0; + ctx->esc_values_i++; + return; + } - bool r = ctx->scroll_enabled; - ctx->scroll_enabled = false; - size_t x, y; - ctx->get_cursor_pos(ctx, &x, &y); + size_t esc_default; + switch (c) { + case 'J': + case 'K': + case 'q': + esc_default = 0; + break; + default: + esc_default = 1; + break; + } - switch (c) { - case 'F': - x = 0; - // FALLTHRU - case 'A': { - if (ctx->esc_values[0] > y) - ctx->esc_values[0] = y; - size_t orig_y = y; - size_t dest_y = y - ctx->esc_values[0]; - bool will_be_in_scroll_region = false; - if ((ctx->scroll_top_margin >= dest_y && ctx->scroll_top_margin <= orig_y) - || (ctx->scroll_bottom_margin >= dest_y && ctx->scroll_bottom_margin <= orig_y)) { - will_be_in_scroll_region = true; - } - if (will_be_in_scroll_region && dest_y < ctx->scroll_top_margin) { - dest_y = ctx->scroll_top_margin; - } - ctx->set_cursor_pos(ctx, x, dest_y); - break; - } - case 'E': - x = 0; - // FALLTHRU - case 'e': - case 'B': { - if (y + ctx->esc_values[0] > ctx->rows - 1) - ctx->esc_values[0] = (ctx->rows - 1) - y; - size_t orig_y = y; - size_t dest_y = y + ctx->esc_values[0]; - bool will_be_in_scroll_region = false; - if ((ctx->scroll_top_margin >= orig_y && ctx->scroll_top_margin <= dest_y) - || (ctx->scroll_bottom_margin >= orig_y && ctx->scroll_bottom_margin <= dest_y)) { - will_be_in_scroll_region = true; - } - if (will_be_in_scroll_region && dest_y >= ctx->scroll_bottom_margin) { - dest_y = ctx->scroll_bottom_margin - 1; - } - ctx->set_cursor_pos(ctx, x, dest_y); - break; - } - case 'a': - case 'C': - if (x + ctx->esc_values[0] > ctx->cols - 1) - ctx->esc_values[0] = (ctx->cols - 1) - x; - ctx->set_cursor_pos(ctx, x + ctx->esc_values[0], y); - break; - case 'D': - if (ctx->esc_values[0] > x) - ctx->esc_values[0] = x; - ctx->set_cursor_pos(ctx, x - ctx->esc_values[0], y); - break; - case 'c': - if (ctx->callback != NULL) { - ctx->callback(ctx, FLANTERM_CB_PRIVATE_ID, 0, 0, 0); - } - break; - case 'd': - ctx->esc_values[0] -= 1; - if (ctx->esc_values[0] >= ctx->rows) - ctx->esc_values[0] = ctx->rows - 1; - ctx->set_cursor_pos(ctx, x, ctx->esc_values[0]); - break; - case 'G': - case '`': - ctx->esc_values[0] -= 1; - if (ctx->esc_values[0] >= ctx->cols) - ctx->esc_values[0] = ctx->cols - 1; - ctx->set_cursor_pos(ctx, ctx->esc_values[0], y); - break; - case 'H': - case 'f': - if (ctx->esc_values[0] != 0) { - ctx->esc_values[0]--; - } - if (ctx->esc_values[1] != 0) { - ctx->esc_values[1]--; - } - if (ctx->esc_values[1] >= ctx->cols) - ctx->esc_values[1] = ctx->cols - 1; - if (ctx->esc_values[0] >= ctx->rows) - ctx->esc_values[0] = ctx->rows - 1; - ctx->set_cursor_pos(ctx, ctx->esc_values[1], ctx->esc_values[0]); - break; - case 'M': { - size_t count = ctx->esc_values[0] > ctx->rows ? ctx->rows : ctx->esc_values[0]; - for (size_t i = 0; i < count; i++) { - ctx->scroll(ctx); - } - break; - } - case 'L': { - size_t old_scroll_top_margin = ctx->scroll_top_margin; - ctx->scroll_top_margin = y; - size_t count = ctx->esc_values[0] > ctx->rows ? ctx->rows : ctx->esc_values[0]; - for (size_t i = 0; i < count; i++) { - ctx->revscroll(ctx); - } - ctx->scroll_top_margin = old_scroll_top_margin; - break; - } - case 'n': - switch (ctx->esc_values[0]) { - case 5: - if (ctx->callback != NULL) { - ctx->callback(ctx, FLANTERM_CB_STATUS_REPORT, 0, 0, 0); - } - break; - case 6: - if (ctx->callback != NULL) { - ctx->callback(ctx, FLANTERM_CB_POS_REPORT, x + 1, y + 1, 0); - } - break; - } - break; - case 'q': - if (ctx->callback != NULL) { - ctx->callback(ctx, FLANTERM_CB_KBD_LEDS, ctx->esc_values[0], 0, 0); - } - break; - case 'J': - switch (ctx->esc_values[0]) { - case 0: { - size_t rows_remaining = ctx->rows - (y + 1); - size_t cols_diff = ctx->cols - (x + 1); - size_t to_clear = rows_remaining * ctx->cols + cols_diff + 1; - for (size_t i = 0; i < to_clear; i++) { - ctx->raw_putchar(ctx, ' '); - } - ctx->set_cursor_pos(ctx, x, y); - break; - } - case 1: { - ctx->set_cursor_pos(ctx, 0, 0); - bool b = false; - for (size_t yc = 0; yc < ctx->rows; yc++) { - for (size_t xc = 0; xc < ctx->cols; xc++) { - ctx->raw_putchar(ctx, ' '); - if (xc == x && yc == y) { - ctx->set_cursor_pos(ctx, x, y); - b = true; - break; - } - } - if (b == true) - break; - } - break; - } - case 2: - case 3: - ctx->clear(ctx, false); - break; - } - break; - case '@': - for (size_t i = ctx->cols - 1; ; i--) { - ctx->move_character(ctx, i + ctx->esc_values[0], y, i, y); - ctx->set_cursor_pos(ctx, i, y); - ctx->raw_putchar(ctx, ' '); - if (i == x) { - break; - } - } - ctx->set_cursor_pos(ctx, x, y); - break; - case 'P': - for (size_t i = x + ctx->esc_values[0]; i < ctx->cols; i++) - ctx->move_character(ctx, i - ctx->esc_values[0], y, i, y); - ctx->set_cursor_pos(ctx, ctx->cols - ctx->esc_values[0], y); - // FALLTHRU - case 'X': { - size_t count = ctx->esc_values[0] > ctx->cols ? ctx->cols : ctx->esc_values[0]; - for (size_t i = 0; i < count; i++) - ctx->raw_putchar(ctx, ' '); + for (size_t i = ctx->esc_values_i; i < FLANTERM_MAX_ESC_VALUES; i++) { + ctx->esc_values[i] = esc_default; + } + + if (ctx->dec_private == true) { + dec_private_parse(ctx, c); + goto cleanup; + } + + bool r = ctx->scroll_enabled; + ctx->scroll_enabled = false; + size_t x, y; + ctx->get_cursor_pos(ctx, &x, &y); + + switch (c) { + case 'F': + x = 0; + // FALLTHRU + case 'A': { + if (ctx->esc_values[0] > y) + ctx->esc_values[0] = y; + size_t orig_y = y; + size_t dest_y = y - ctx->esc_values[0]; + bool will_be_in_scroll_region = false; + if ((ctx->scroll_top_margin >= dest_y && + ctx->scroll_top_margin <= orig_y) || + (ctx->scroll_bottom_margin >= dest_y && + ctx->scroll_bottom_margin <= orig_y)) { + will_be_in_scroll_region = true; + } + if (will_be_in_scroll_region && dest_y < ctx->scroll_top_margin) { + dest_y = ctx->scroll_top_margin; + } + ctx->set_cursor_pos(ctx, x, dest_y); + break; + } + case 'E': + x = 0; + // FALLTHRU + case 'e': + case 'B': { + if (y + ctx->esc_values[0] > ctx->rows - 1) + ctx->esc_values[0] = (ctx->rows - 1) - y; + size_t orig_y = y; + size_t dest_y = y + ctx->esc_values[0]; + bool will_be_in_scroll_region = false; + if ((ctx->scroll_top_margin >= orig_y && + ctx->scroll_top_margin <= dest_y) || + (ctx->scroll_bottom_margin >= orig_y && + ctx->scroll_bottom_margin <= dest_y)) { + will_be_in_scroll_region = true; + } + if (will_be_in_scroll_region && dest_y >= ctx->scroll_bottom_margin) { + dest_y = ctx->scroll_bottom_margin - 1; + } + ctx->set_cursor_pos(ctx, x, dest_y); + break; + } + case 'a': + case 'C': + if (x + ctx->esc_values[0] > ctx->cols - 1) + ctx->esc_values[0] = (ctx->cols - 1) - x; + ctx->set_cursor_pos(ctx, x + ctx->esc_values[0], y); + break; + case 'D': + if (ctx->esc_values[0] > x) + ctx->esc_values[0] = x; + ctx->set_cursor_pos(ctx, x - ctx->esc_values[0], y); + break; + case 'c': + if (ctx->callback != NULL) { + ctx->callback(ctx, FLANTERM_CB_PRIVATE_ID, 0, 0, 0); + } + break; + case 'd': + ctx->esc_values[0] -= 1; + if (ctx->esc_values[0] >= ctx->rows) + ctx->esc_values[0] = ctx->rows - 1; + ctx->set_cursor_pos(ctx, x, ctx->esc_values[0]); + break; + case 'G': + case '`': + ctx->esc_values[0] -= 1; + if (ctx->esc_values[0] >= ctx->cols) + ctx->esc_values[0] = ctx->cols - 1; + ctx->set_cursor_pos(ctx, ctx->esc_values[0], y); + break; + case 'H': + case 'f': + if (ctx->esc_values[0] != 0) { + ctx->esc_values[0]--; + } + if (ctx->esc_values[1] != 0) { + ctx->esc_values[1]--; + } + if (ctx->esc_values[1] >= ctx->cols) + ctx->esc_values[1] = ctx->cols - 1; + if (ctx->esc_values[0] >= ctx->rows) + ctx->esc_values[0] = ctx->rows - 1; + ctx->set_cursor_pos(ctx, ctx->esc_values[1], ctx->esc_values[0]); + break; + case 'M': { + size_t count = + ctx->esc_values[0] > ctx->rows ? ctx->rows : ctx->esc_values[0]; + for (size_t i = 0; i < count; i++) { + ctx->scroll(ctx); + } + break; + } + case 'L': { + size_t old_scroll_top_margin = ctx->scroll_top_margin; + ctx->scroll_top_margin = y; + size_t count = + ctx->esc_values[0] > ctx->rows ? ctx->rows : ctx->esc_values[0]; + for (size_t i = 0; i < count; i++) { + ctx->revscroll(ctx); + } + ctx->scroll_top_margin = old_scroll_top_margin; + break; + } + case 'n': + switch (ctx->esc_values[0]) { + case 5: + if (ctx->callback != NULL) { + ctx->callback(ctx, FLANTERM_CB_STATUS_REPORT, 0, 0, 0); + } + break; + case 6: + if (ctx->callback != NULL) { + ctx->callback(ctx, FLANTERM_CB_POS_REPORT, x + 1, y + 1, 0); + } + break; + } + break; + case 'q': + if (ctx->callback != NULL) { + ctx->callback(ctx, FLANTERM_CB_KBD_LEDS, ctx->esc_values[0], 0, 0); + } + break; + case 'J': + switch (ctx->esc_values[0]) { + case 0: { + size_t rows_remaining = ctx->rows - (y + 1); + size_t cols_diff = ctx->cols - (x + 1); + size_t to_clear = rows_remaining * ctx->cols + cols_diff + 1; + for (size_t i = 0; i < to_clear; i++) { + ctx->raw_putchar(ctx, ' '); + } + ctx->set_cursor_pos(ctx, x, y); + break; + } + case 1: { + ctx->set_cursor_pos(ctx, 0, 0); + bool b = false; + for (size_t yc = 0; yc < ctx->rows; yc++) { + for (size_t xc = 0; xc < ctx->cols; xc++) { + ctx->raw_putchar(ctx, ' '); + if (xc == x && yc == y) { ctx->set_cursor_pos(ctx, x, y); + b = true; break; + } } - case 'm': - sgr(ctx); - break; - case 's': - ctx->get_cursor_pos(ctx, &ctx->saved_cursor_x, &ctx->saved_cursor_y); - break; - case 'u': - ctx->set_cursor_pos(ctx, ctx->saved_cursor_x, ctx->saved_cursor_y); - break; - case 'K': - switch (ctx->esc_values[0]) { - case 0: { - for (size_t i = x; i < ctx->cols; i++) - ctx->raw_putchar(ctx, ' '); - ctx->set_cursor_pos(ctx, x, y); - break; - } - case 1: { - ctx->set_cursor_pos(ctx, 0, y); - for (size_t i = 0; i < x; i++) - ctx->raw_putchar(ctx, ' '); - break; - } - case 2: { - ctx->set_cursor_pos(ctx, 0, y); - for (size_t i = 0; i < ctx->cols; i++) - ctx->raw_putchar(ctx, ' '); - ctx->set_cursor_pos(ctx, x, y); - break; - } - } - break; - case 'r': - if (ctx->esc_values[0] == 0) { - ctx->esc_values[0] = 1; - } - if (ctx->esc_values[1] == 0) { - ctx->esc_values[1] = 1; - } - ctx->scroll_top_margin = 0; - ctx->scroll_bottom_margin = ctx->rows; - if (ctx->esc_values_i > 0) { - ctx->scroll_top_margin = ctx->esc_values[0] - 1; - } - if (ctx->esc_values_i > 1) { - ctx->scroll_bottom_margin = ctx->esc_values[1]; - } - if (ctx->scroll_top_margin >= ctx->rows - || ctx->scroll_bottom_margin > ctx->rows - || ctx->scroll_top_margin >= (ctx->scroll_bottom_margin - 1)) { - ctx->scroll_top_margin = 0; - ctx->scroll_bottom_margin = ctx->rows; - } - ctx->set_cursor_pos(ctx, 0, 0); - break; - case 'l': - case 'h': - mode_toggle(ctx, c); - break; - case ']': - linux_private_parse(ctx); - break; + if (b == true) + break; + } + break; } + case 2: + case 3: + ctx->clear(ctx, false); + break; + } + break; + case '@': + for (size_t i = ctx->cols - 1;; i--) { + ctx->move_character(ctx, i + ctx->esc_values[0], y, i, y); + ctx->set_cursor_pos(ctx, i, y); + ctx->raw_putchar(ctx, ' '); + if (i == x) { + break; + } + } + ctx->set_cursor_pos(ctx, x, y); + break; + case 'P': + for (size_t i = x + ctx->esc_values[0]; i < ctx->cols; i++) + ctx->move_character(ctx, i - ctx->esc_values[0], y, i, y); + ctx->set_cursor_pos(ctx, ctx->cols - ctx->esc_values[0], y); + // FALLTHRU + case 'X': { + size_t count = + ctx->esc_values[0] > ctx->cols ? ctx->cols : ctx->esc_values[0]; + for (size_t i = 0; i < count; i++) + ctx->raw_putchar(ctx, ' '); + ctx->set_cursor_pos(ctx, x, y); + break; + } + case 'm': + sgr(ctx); + break; + case 's': + ctx->get_cursor_pos(ctx, &ctx->saved_cursor_x, &ctx->saved_cursor_y); + break; + case 'u': + ctx->set_cursor_pos(ctx, ctx->saved_cursor_x, ctx->saved_cursor_y); + break; + case 'K': + switch (ctx->esc_values[0]) { + case 0: { + for (size_t i = x; i < ctx->cols; i++) + ctx->raw_putchar(ctx, ' '); + ctx->set_cursor_pos(ctx, x, y); + break; + } + case 1: { + ctx->set_cursor_pos(ctx, 0, y); + for (size_t i = 0; i < x; i++) + ctx->raw_putchar(ctx, ' '); + break; + } + case 2: { + ctx->set_cursor_pos(ctx, 0, y); + for (size_t i = 0; i < ctx->cols; i++) + ctx->raw_putchar(ctx, ' '); + ctx->set_cursor_pos(ctx, x, y); + break; + } + } + break; + case 'r': + if (ctx->esc_values[0] == 0) { + ctx->esc_values[0] = 1; + } + if (ctx->esc_values[1] == 0) { + ctx->esc_values[1] = 1; + } + ctx->scroll_top_margin = 0; + ctx->scroll_bottom_margin = ctx->rows; + if (ctx->esc_values_i > 0) { + ctx->scroll_top_margin = ctx->esc_values[0] - 1; + } + if (ctx->esc_values_i > 1) { + ctx->scroll_bottom_margin = ctx->esc_values[1]; + } + if (ctx->scroll_top_margin >= ctx->rows || + ctx->scroll_bottom_margin > ctx->rows || + ctx->scroll_top_margin >= (ctx->scroll_bottom_margin - 1)) { + ctx->scroll_top_margin = 0; + ctx->scroll_bottom_margin = ctx->rows; + } + ctx->set_cursor_pos(ctx, 0, 0); + break; + case 'l': + case 'h': + mode_toggle(ctx, c); + break; + case ']': + linux_private_parse(ctx); + break; + } - ctx->scroll_enabled = r; + ctx->scroll_enabled = r; cleanup: - ctx->control_sequence = false; - ctx->escape = false; + ctx->control_sequence = false; + ctx->escape = false; } static void restore_state(struct flanterm_context *ctx) { - ctx->bold = ctx->saved_state_bold; - ctx->bg_bold = ctx->saved_state_bg_bold; - ctx->reverse_video = ctx->saved_state_reverse_video; - ctx->current_charset = ctx->saved_state_current_charset; - ctx->current_primary = ctx->saved_state_current_primary; - ctx->current_bg = ctx->saved_state_current_bg; + ctx->bold = ctx->saved_state_bold; + ctx->bg_bold = ctx->saved_state_bg_bold; + ctx->reverse_video = ctx->saved_state_reverse_video; + ctx->current_charset = ctx->saved_state_current_charset; + ctx->current_primary = ctx->saved_state_current_primary; + ctx->current_bg = ctx->saved_state_current_bg; - ctx->restore_state(ctx); + ctx->restore_state(ctx); } static void save_state(struct flanterm_context *ctx) { - ctx->save_state(ctx); + ctx->save_state(ctx); - ctx->saved_state_bold = ctx->bold; - ctx->saved_state_bg_bold = ctx->bg_bold; - ctx->saved_state_reverse_video = ctx->reverse_video; - ctx->saved_state_current_charset = ctx->current_charset; - ctx->saved_state_current_primary = ctx->current_primary; - ctx->saved_state_current_bg = ctx->current_bg; + ctx->saved_state_bold = ctx->bold; + ctx->saved_state_bg_bold = ctx->bg_bold; + ctx->saved_state_reverse_video = ctx->reverse_video; + ctx->saved_state_current_charset = ctx->current_charset; + ctx->saved_state_current_primary = ctx->current_primary; + ctx->saved_state_current_bg = ctx->current_bg; } static void escape_parse(struct flanterm_context *ctx, uint8_t c) { - ctx->escape_offset++; + ctx->escape_offset++; - if (ctx->osc == true) { - osc_parse(ctx, c); - return; + if (ctx->osc == true) { + osc_parse(ctx, c); + return; + } + + if (ctx->control_sequence == true) { + control_sequence_parse(ctx, c); + return; + } + + size_t x, y; + ctx->get_cursor_pos(ctx, &x, &y); + + switch (c) { + case ']': + ctx->osc_escape = false; + ctx->osc = true; + return; + case '[': + for (size_t i = 0; i < FLANTERM_MAX_ESC_VALUES; i++) + ctx->esc_values[i] = 0; + ctx->esc_values_i = 0; + ctx->rrr = false; + ctx->control_sequence = true; + return; + case '7': + save_state(ctx); + break; + case '8': + restore_state(ctx); + break; + case 'c': + flanterm_context_reinit(ctx); + ctx->clear(ctx, true); + break; + case 'D': + if (y == ctx->scroll_bottom_margin - 1) { + ctx->scroll(ctx); + ctx->set_cursor_pos(ctx, x, y); + } else { + ctx->set_cursor_pos(ctx, x, y + 1); } - - if (ctx->control_sequence == true) { - control_sequence_parse(ctx, c); - return; + break; + case 'E': + if (y == ctx->scroll_bottom_margin - 1) { + ctx->scroll(ctx); + ctx->set_cursor_pos(ctx, 0, y); + } else { + ctx->set_cursor_pos(ctx, 0, y + 1); } - - size_t x, y; - ctx->get_cursor_pos(ctx, &x, &y); - - switch (c) { - case ']': - ctx->osc_escape = false; - ctx->osc = true; - return; - case '[': - for (size_t i = 0; i < FLANTERM_MAX_ESC_VALUES; i++) - ctx->esc_values[i] = 0; - ctx->esc_values_i = 0; - ctx->rrr = false; - ctx->control_sequence = true; - return; - case '7': - save_state(ctx); - break; - case '8': - restore_state(ctx); - break; - case 'c': - flanterm_context_reinit(ctx); - ctx->clear(ctx, true); - break; - case 'D': - if (y == ctx->scroll_bottom_margin - 1) { - ctx->scroll(ctx); - ctx->set_cursor_pos(ctx, x, y); - } else { - ctx->set_cursor_pos(ctx, x, y + 1); - } - break; - case 'E': - if (y == ctx->scroll_bottom_margin - 1) { - ctx->scroll(ctx); - ctx->set_cursor_pos(ctx, 0, y); - } else { - ctx->set_cursor_pos(ctx, 0, y + 1); - } - break; - case 'M': - // "Reverse linefeed" - if (y == ctx->scroll_top_margin) { - ctx->revscroll(ctx); - ctx->set_cursor_pos(ctx, 0, y); - } else { - ctx->set_cursor_pos(ctx, 0, y - 1); - } - break; - case 'Z': - if (ctx->callback != NULL) { - ctx->callback(ctx, FLANTERM_CB_PRIVATE_ID, 0, 0, 0); - } - break; - case '(': - case ')': - ctx->g_select = c - '\''; - break; + break; + case 'M': + // "Reverse linefeed" + if (y == ctx->scroll_top_margin) { + ctx->revscroll(ctx); + ctx->set_cursor_pos(ctx, 0, y); + } else { + ctx->set_cursor_pos(ctx, 0, y - 1); } + break; + case 'Z': + if (ctx->callback != NULL) { + ctx->callback(ctx, FLANTERM_CB_PRIVATE_ID, 0, 0, 0); + } + break; + case '(': + case ')': + ctx->g_select = c - '\''; + break; + } - ctx->escape = false; + ctx->escape = false; } static bool dec_special_print(struct flanterm_context *ctx, uint8_t c) { -#define FLANTERM_DEC_SPCL_PRN(C) ctx->raw_putchar(ctx, (C)); return true; - switch (c) { - case '`': FLANTERM_DEC_SPCL_PRN(0x04) - case '0': FLANTERM_DEC_SPCL_PRN(0xdb) - case '-': FLANTERM_DEC_SPCL_PRN(0x18) - case ',': FLANTERM_DEC_SPCL_PRN(0x1b) - case '.': FLANTERM_DEC_SPCL_PRN(0x19) - case 'a': FLANTERM_DEC_SPCL_PRN(0xb1) - case 'f': FLANTERM_DEC_SPCL_PRN(0xf8) - case 'g': FLANTERM_DEC_SPCL_PRN(0xf1) - case 'h': FLANTERM_DEC_SPCL_PRN(0xb0) - case 'j': FLANTERM_DEC_SPCL_PRN(0xd9) - case 'k': FLANTERM_DEC_SPCL_PRN(0xbf) - case 'l': FLANTERM_DEC_SPCL_PRN(0xda) - case 'm': FLANTERM_DEC_SPCL_PRN(0xc0) - case 'n': FLANTERM_DEC_SPCL_PRN(0xc5) - case 'q': FLANTERM_DEC_SPCL_PRN(0xc4) - case 's': FLANTERM_DEC_SPCL_PRN(0x5f) - case 't': FLANTERM_DEC_SPCL_PRN(0xc3) - case 'u': FLANTERM_DEC_SPCL_PRN(0xb4) - case 'v': FLANTERM_DEC_SPCL_PRN(0xc1) - case 'w': FLANTERM_DEC_SPCL_PRN(0xc2) - case 'x': FLANTERM_DEC_SPCL_PRN(0xb3) - case 'y': FLANTERM_DEC_SPCL_PRN(0xf3) - case 'z': FLANTERM_DEC_SPCL_PRN(0xf2) - case '~': FLANTERM_DEC_SPCL_PRN(0xfa) - case '_': FLANTERM_DEC_SPCL_PRN(0xff) - case '+': FLANTERM_DEC_SPCL_PRN(0x1a) - case '{': FLANTERM_DEC_SPCL_PRN(0xe3) - case '}': FLANTERM_DEC_SPCL_PRN(0x9c) - } +#define FLANTERM_DEC_SPCL_PRN(C) \ + ctx->raw_putchar(ctx, (C)); \ + return true; + switch (c) { + case '`': + FLANTERM_DEC_SPCL_PRN(0x04) + case '0': + FLANTERM_DEC_SPCL_PRN(0xdb) + case '-': + FLANTERM_DEC_SPCL_PRN(0x18) + case ',': + FLANTERM_DEC_SPCL_PRN(0x1b) + case '.': + FLANTERM_DEC_SPCL_PRN(0x19) + case 'a': + FLANTERM_DEC_SPCL_PRN(0xb1) + case 'f': + FLANTERM_DEC_SPCL_PRN(0xf8) + case 'g': + FLANTERM_DEC_SPCL_PRN(0xf1) + case 'h': + FLANTERM_DEC_SPCL_PRN(0xb0) + case 'j': + FLANTERM_DEC_SPCL_PRN(0xd9) + case 'k': + FLANTERM_DEC_SPCL_PRN(0xbf) + case 'l': + FLANTERM_DEC_SPCL_PRN(0xda) + case 'm': + FLANTERM_DEC_SPCL_PRN(0xc0) + case 'n': + FLANTERM_DEC_SPCL_PRN(0xc5) + case 'q': + FLANTERM_DEC_SPCL_PRN(0xc4) + case 's': + FLANTERM_DEC_SPCL_PRN(0x5f) + case 't': + FLANTERM_DEC_SPCL_PRN(0xc3) + case 'u': + FLANTERM_DEC_SPCL_PRN(0xb4) + case 'v': + FLANTERM_DEC_SPCL_PRN(0xc1) + case 'w': + FLANTERM_DEC_SPCL_PRN(0xc2) + case 'x': + FLANTERM_DEC_SPCL_PRN(0xb3) + case 'y': + FLANTERM_DEC_SPCL_PRN(0xf3) + case 'z': + FLANTERM_DEC_SPCL_PRN(0xf2) + case '~': + FLANTERM_DEC_SPCL_PRN(0xfa) + case '_': + FLANTERM_DEC_SPCL_PRN(0xff) + case '+': + FLANTERM_DEC_SPCL_PRN(0x1a) + case '{': + FLANTERM_DEC_SPCL_PRN(0xe3) + case '}': + FLANTERM_DEC_SPCL_PRN(0x9c) + } #undef FLANTERM_DEC_SPCL_PRN - return false; + return false; } // Following wcwidth related code inherited from: // https://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c struct interval { - uint32_t first; - uint32_t last; + uint32_t first; + uint32_t last; }; /* auxiliary function for binary search in interval table */ @@ -957,55 +1014,54 @@ int mk_wcwidth(uint32_t ucs) { /* sorted list of non-overlapping intervals of non-spacing characters */ /* generated by "uniset +cat=Me +cat=Mn +cat=Cf -00AD +1160-11FF +200B c" */ static const struct interval combining[] = { - { 0x0300, 0x036F }, { 0x0483, 0x0486 }, { 0x0488, 0x0489 }, - { 0x0591, 0x05BD }, { 0x05BF, 0x05BF }, { 0x05C1, 0x05C2 }, - { 0x05C4, 0x05C5 }, { 0x05C7, 0x05C7 }, { 0x0600, 0x0603 }, - { 0x0610, 0x0615 }, { 0x064B, 0x065E }, { 0x0670, 0x0670 }, - { 0x06D6, 0x06E4 }, { 0x06E7, 0x06E8 }, { 0x06EA, 0x06ED }, - { 0x070F, 0x070F }, { 0x0711, 0x0711 }, { 0x0730, 0x074A }, - { 0x07A6, 0x07B0 }, { 0x07EB, 0x07F3 }, { 0x0901, 0x0902 }, - { 0x093C, 0x093C }, { 0x0941, 0x0948 }, { 0x094D, 0x094D }, - { 0x0951, 0x0954 }, { 0x0962, 0x0963 }, { 0x0981, 0x0981 }, - { 0x09BC, 0x09BC }, { 0x09C1, 0x09C4 }, { 0x09CD, 0x09CD }, - { 0x09E2, 0x09E3 }, { 0x0A01, 0x0A02 }, { 0x0A3C, 0x0A3C }, - { 0x0A41, 0x0A42 }, { 0x0A47, 0x0A48 }, { 0x0A4B, 0x0A4D }, - { 0x0A70, 0x0A71 }, { 0x0A81, 0x0A82 }, { 0x0ABC, 0x0ABC }, - { 0x0AC1, 0x0AC5 }, { 0x0AC7, 0x0AC8 }, { 0x0ACD, 0x0ACD }, - { 0x0AE2, 0x0AE3 }, { 0x0B01, 0x0B01 }, { 0x0B3C, 0x0B3C }, - { 0x0B3F, 0x0B3F }, { 0x0B41, 0x0B43 }, { 0x0B4D, 0x0B4D }, - { 0x0B56, 0x0B56 }, { 0x0B82, 0x0B82 }, { 0x0BC0, 0x0BC0 }, - { 0x0BCD, 0x0BCD }, { 0x0C3E, 0x0C40 }, { 0x0C46, 0x0C48 }, - { 0x0C4A, 0x0C4D }, { 0x0C55, 0x0C56 }, { 0x0CBC, 0x0CBC }, - { 0x0CBF, 0x0CBF }, { 0x0CC6, 0x0CC6 }, { 0x0CCC, 0x0CCD }, - { 0x0CE2, 0x0CE3 }, { 0x0D41, 0x0D43 }, { 0x0D4D, 0x0D4D }, - { 0x0DCA, 0x0DCA }, { 0x0DD2, 0x0DD4 }, { 0x0DD6, 0x0DD6 }, - { 0x0E31, 0x0E31 }, { 0x0E34, 0x0E3A }, { 0x0E47, 0x0E4E }, - { 0x0EB1, 0x0EB1 }, { 0x0EB4, 0x0EB9 }, { 0x0EBB, 0x0EBC }, - { 0x0EC8, 0x0ECD }, { 0x0F18, 0x0F19 }, { 0x0F35, 0x0F35 }, - { 0x0F37, 0x0F37 }, { 0x0F39, 0x0F39 }, { 0x0F71, 0x0F7E }, - { 0x0F80, 0x0F84 }, { 0x0F86, 0x0F87 }, { 0x0F90, 0x0F97 }, - { 0x0F99, 0x0FBC }, { 0x0FC6, 0x0FC6 }, { 0x102D, 0x1030 }, - { 0x1032, 0x1032 }, { 0x1036, 0x1037 }, { 0x1039, 0x1039 }, - { 0x1058, 0x1059 }, { 0x1160, 0x11FF }, { 0x135F, 0x135F }, - { 0x1712, 0x1714 }, { 0x1732, 0x1734 }, { 0x1752, 0x1753 }, - { 0x1772, 0x1773 }, { 0x17B4, 0x17B5 }, { 0x17B7, 0x17BD }, - { 0x17C6, 0x17C6 }, { 0x17C9, 0x17D3 }, { 0x17DD, 0x17DD }, - { 0x180B, 0x180D }, { 0x18A9, 0x18A9 }, { 0x1920, 0x1922 }, - { 0x1927, 0x1928 }, { 0x1932, 0x1932 }, { 0x1939, 0x193B }, - { 0x1A17, 0x1A18 }, { 0x1B00, 0x1B03 }, { 0x1B34, 0x1B34 }, - { 0x1B36, 0x1B3A }, { 0x1B3C, 0x1B3C }, { 0x1B42, 0x1B42 }, - { 0x1B6B, 0x1B73 }, { 0x1DC0, 0x1DCA }, { 0x1DFE, 0x1DFF }, - { 0x200B, 0x200F }, { 0x202A, 0x202E }, { 0x2060, 0x2063 }, - { 0x206A, 0x206F }, { 0x20D0, 0x20EF }, { 0x302A, 0x302F }, - { 0x3099, 0x309A }, { 0xA806, 0xA806 }, { 0xA80B, 0xA80B }, - { 0xA825, 0xA826 }, { 0xFB1E, 0xFB1E }, { 0xFE00, 0xFE0F }, - { 0xFE20, 0xFE23 }, { 0xFEFF, 0xFEFF }, { 0xFFF9, 0xFFFB }, - { 0x10A01, 0x10A03 }, { 0x10A05, 0x10A06 }, { 0x10A0C, 0x10A0F }, - { 0x10A38, 0x10A3A }, { 0x10A3F, 0x10A3F }, { 0x1D167, 0x1D169 }, - { 0x1D173, 0x1D182 }, { 0x1D185, 0x1D18B }, { 0x1D1AA, 0x1D1AD }, - { 0x1D242, 0x1D244 }, { 0xE0001, 0xE0001 }, { 0xE0020, 0xE007F }, - { 0xE0100, 0xE01EF } - }; + {0x0300, 0x036F}, {0x0483, 0x0486}, {0x0488, 0x0489}, + {0x0591, 0x05BD}, {0x05BF, 0x05BF}, {0x05C1, 0x05C2}, + {0x05C4, 0x05C5}, {0x05C7, 0x05C7}, {0x0600, 0x0603}, + {0x0610, 0x0615}, {0x064B, 0x065E}, {0x0670, 0x0670}, + {0x06D6, 0x06E4}, {0x06E7, 0x06E8}, {0x06EA, 0x06ED}, + {0x070F, 0x070F}, {0x0711, 0x0711}, {0x0730, 0x074A}, + {0x07A6, 0x07B0}, {0x07EB, 0x07F3}, {0x0901, 0x0902}, + {0x093C, 0x093C}, {0x0941, 0x0948}, {0x094D, 0x094D}, + {0x0951, 0x0954}, {0x0962, 0x0963}, {0x0981, 0x0981}, + {0x09BC, 0x09BC}, {0x09C1, 0x09C4}, {0x09CD, 0x09CD}, + {0x09E2, 0x09E3}, {0x0A01, 0x0A02}, {0x0A3C, 0x0A3C}, + {0x0A41, 0x0A42}, {0x0A47, 0x0A48}, {0x0A4B, 0x0A4D}, + {0x0A70, 0x0A71}, {0x0A81, 0x0A82}, {0x0ABC, 0x0ABC}, + {0x0AC1, 0x0AC5}, {0x0AC7, 0x0AC8}, {0x0ACD, 0x0ACD}, + {0x0AE2, 0x0AE3}, {0x0B01, 0x0B01}, {0x0B3C, 0x0B3C}, + {0x0B3F, 0x0B3F}, {0x0B41, 0x0B43}, {0x0B4D, 0x0B4D}, + {0x0B56, 0x0B56}, {0x0B82, 0x0B82}, {0x0BC0, 0x0BC0}, + {0x0BCD, 0x0BCD}, {0x0C3E, 0x0C40}, {0x0C46, 0x0C48}, + {0x0C4A, 0x0C4D}, {0x0C55, 0x0C56}, {0x0CBC, 0x0CBC}, + {0x0CBF, 0x0CBF}, {0x0CC6, 0x0CC6}, {0x0CCC, 0x0CCD}, + {0x0CE2, 0x0CE3}, {0x0D41, 0x0D43}, {0x0D4D, 0x0D4D}, + {0x0DCA, 0x0DCA}, {0x0DD2, 0x0DD4}, {0x0DD6, 0x0DD6}, + {0x0E31, 0x0E31}, {0x0E34, 0x0E3A}, {0x0E47, 0x0E4E}, + {0x0EB1, 0x0EB1}, {0x0EB4, 0x0EB9}, {0x0EBB, 0x0EBC}, + {0x0EC8, 0x0ECD}, {0x0F18, 0x0F19}, {0x0F35, 0x0F35}, + {0x0F37, 0x0F37}, {0x0F39, 0x0F39}, {0x0F71, 0x0F7E}, + {0x0F80, 0x0F84}, {0x0F86, 0x0F87}, {0x0F90, 0x0F97}, + {0x0F99, 0x0FBC}, {0x0FC6, 0x0FC6}, {0x102D, 0x1030}, + {0x1032, 0x1032}, {0x1036, 0x1037}, {0x1039, 0x1039}, + {0x1058, 0x1059}, {0x1160, 0x11FF}, {0x135F, 0x135F}, + {0x1712, 0x1714}, {0x1732, 0x1734}, {0x1752, 0x1753}, + {0x1772, 0x1773}, {0x17B4, 0x17B5}, {0x17B7, 0x17BD}, + {0x17C6, 0x17C6}, {0x17C9, 0x17D3}, {0x17DD, 0x17DD}, + {0x180B, 0x180D}, {0x18A9, 0x18A9}, {0x1920, 0x1922}, + {0x1927, 0x1928}, {0x1932, 0x1932}, {0x1939, 0x193B}, + {0x1A17, 0x1A18}, {0x1B00, 0x1B03}, {0x1B34, 0x1B34}, + {0x1B36, 0x1B3A}, {0x1B3C, 0x1B3C}, {0x1B42, 0x1B42}, + {0x1B6B, 0x1B73}, {0x1DC0, 0x1DCA}, {0x1DFE, 0x1DFF}, + {0x200B, 0x200F}, {0x202A, 0x202E}, {0x2060, 0x2063}, + {0x206A, 0x206F}, {0x20D0, 0x20EF}, {0x302A, 0x302F}, + {0x3099, 0x309A}, {0xA806, 0xA806}, {0xA80B, 0xA80B}, + {0xA825, 0xA826}, {0xFB1E, 0xFB1E}, {0xFE00, 0xFE0F}, + {0xFE20, 0xFE23}, {0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFB}, + {0x10A01, 0x10A03}, {0x10A05, 0x10A06}, {0x10A0C, 0x10A0F}, + {0x10A38, 0x10A3A}, {0x10A3F, 0x10A3F}, {0x1D167, 0x1D169}, + {0x1D173, 0x1D182}, {0x1D185, 0x1D18B}, {0x1D1AA, 0x1D1AD}, + {0x1D242, 0x1D244}, {0xE0001, 0xE0001}, {0xE0020, 0xE007F}, + {0xE0100, 0xE01EF}}; /* test for 8-bit control characters */ if (ucs == 0) @@ -1014,375 +1070,542 @@ int mk_wcwidth(uint32_t ucs) { return 1; /* binary search in table of non-spacing characters */ - if (bisearch(ucs, combining, - sizeof(combining) / sizeof(struct interval) - 1)) + if (bisearch(ucs, combining, sizeof(combining) / sizeof(struct interval) - 1)) return 0; /* if we arrive here, ucs is not a combining or C0/C1 control character */ return 1 + - (ucs >= 0x1100 && - (ucs <= 0x115f || /* Hangul Jamo init. consonants */ - ucs == 0x2329 || ucs == 0x232a || - (ucs >= 0x2e80 && ucs <= 0xa4cf && - ucs != 0x303f) || /* CJK ... Yi */ - (ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */ - (ucs >= 0xf900 && ucs <= 0xfaff) || /* CJK Compatibility Ideographs */ - (ucs >= 0xfe10 && ucs <= 0xfe19) || /* Vertical forms */ - (ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */ - (ucs >= 0xff00 && ucs <= 0xff60) || /* Fullwidth Forms */ - (ucs >= 0xffe0 && ucs <= 0xffe6) || - (ucs >= 0x20000 && ucs <= 0x2fffd) || - (ucs >= 0x30000 && ucs <= 0x3fffd))); + (ucs >= 0x1100 && + (ucs <= 0x115f || /* Hangul Jamo init. consonants */ + ucs == 0x2329 || ucs == 0x232a || + (ucs >= 0x2e80 && ucs <= 0xa4cf && ucs != 0x303f) || /* CJK ... Yi */ + (ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */ + (ucs >= 0xf900 && + ucs <= 0xfaff) || /* CJK Compatibility Ideographs */ + (ucs >= 0xfe10 && ucs <= 0xfe19) || /* Vertical forms */ + (ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */ + (ucs >= 0xff00 && ucs <= 0xff60) || /* Fullwidth Forms */ + (ucs >= 0xffe0 && ucs <= 0xffe6) || + (ucs >= 0x20000 && ucs <= 0x2fffd) || + (ucs >= 0x30000 && ucs <= 0x3fffd))); } // End of https://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c inherited code static int unicode_to_cp437(uint64_t code_point) { - switch (code_point) { - case 0x263a: return 1; - case 0x263b: return 2; - case 0x2665: return 3; - case 0x2666: return 4; - case 0x2663: return 5; - case 0x2660: return 6; - case 0x2022: return 7; - case 0x25d8: return 8; - case 0x25cb: return 9; - case 0x25d9: return 10; - case 0x2642: return 11; - case 0x2640: return 12; - case 0x266a: return 13; - case 0x266b: return 14; - case 0x263c: return 15; - case 0x25ba: return 16; - case 0x25c4: return 17; - case 0x2195: return 18; - case 0x203c: return 19; - case 0x00b6: return 20; - case 0x00a7: return 21; - case 0x25ac: return 22; - case 0x21a8: return 23; - case 0x2191: return 24; - case 0x2193: return 25; - case 0x2192: return 26; - case 0x2190: return 27; - case 0x221f: return 28; - case 0x2194: return 29; - case 0x25b2: return 30; - case 0x25bc: return 31; + switch (code_point) { + case 0x263a: + return 1; + case 0x263b: + return 2; + case 0x2665: + return 3; + case 0x2666: + return 4; + case 0x2663: + return 5; + case 0x2660: + return 6; + case 0x2022: + return 7; + case 0x25d8: + return 8; + case 0x25cb: + return 9; + case 0x25d9: + return 10; + case 0x2642: + return 11; + case 0x2640: + return 12; + case 0x266a: + return 13; + case 0x266b: + return 14; + case 0x263c: + return 15; + case 0x25ba: + return 16; + case 0x25c4: + return 17; + case 0x2195: + return 18; + case 0x203c: + return 19; + case 0x00b6: + return 20; + case 0x00a7: + return 21; + case 0x25ac: + return 22; + case 0x21a8: + return 23; + case 0x2191: + return 24; + case 0x2193: + return 25; + case 0x2192: + return 26; + case 0x2190: + return 27; + case 0x221f: + return 28; + case 0x2194: + return 29; + case 0x25b2: + return 30; + case 0x25bc: + return 31; - case 0x2302: return 127; - case 0x00c7: return 128; - case 0x00fc: return 129; - case 0x00e9: return 130; - case 0x00e2: return 131; - case 0x00e4: return 132; - case 0x00e0: return 133; - case 0x00e5: return 134; - case 0x00e7: return 135; - case 0x00ea: return 136; - case 0x00eb: return 137; - case 0x00e8: return 138; - case 0x00ef: return 139; - case 0x00ee: return 140; - case 0x00ec: return 141; - case 0x00c4: return 142; - case 0x00c5: return 143; - case 0x00c9: return 144; - case 0x00e6: return 145; - case 0x00c6: return 146; - case 0x00f4: return 147; - case 0x00f6: return 148; - case 0x00f2: return 149; - case 0x00fb: return 150; - case 0x00f9: return 151; - case 0x00ff: return 152; - case 0x00d6: return 153; - case 0x00dc: return 154; - case 0x00a2: return 155; - case 0x00a3: return 156; - case 0x00a5: return 157; - case 0x20a7: return 158; - case 0x0192: return 159; - case 0x00e1: return 160; - case 0x00ed: return 161; - case 0x00f3: return 162; - case 0x00fa: return 163; - case 0x00f1: return 164; - case 0x00d1: return 165; - case 0x00aa: return 166; - case 0x00ba: return 167; - case 0x00bf: return 168; - case 0x2310: return 169; - case 0x00ac: return 170; - case 0x00bd: return 171; - case 0x00bc: return 172; - case 0x00a1: return 173; - case 0x00ab: return 174; - case 0x00bb: return 175; - case 0x2591: return 176; - case 0x2592: return 177; - case 0x2593: return 178; - case 0x2502: return 179; - case 0x2524: return 180; - case 0x2561: return 181; - case 0x2562: return 182; - case 0x2556: return 183; - case 0x2555: return 184; - case 0x2563: return 185; - case 0x2551: return 186; - case 0x2557: return 187; - case 0x255d: return 188; - case 0x255c: return 189; - case 0x255b: return 190; - case 0x2510: return 191; - case 0x2514: return 192; - case 0x2534: return 193; - case 0x252c: return 194; - case 0x251c: return 195; - case 0x2500: return 196; - case 0x253c: return 197; - case 0x255e: return 198; - case 0x255f: return 199; - case 0x255a: return 200; - case 0x2554: return 201; - case 0x2569: return 202; - case 0x2566: return 203; - case 0x2560: return 204; - case 0x2550: return 205; - case 0x256c: return 206; - case 0x2567: return 207; - case 0x2568: return 208; - case 0x2564: return 209; - case 0x2565: return 210; - case 0x2559: return 211; - case 0x2558: return 212; - case 0x2552: return 213; - case 0x2553: return 214; - case 0x256b: return 215; - case 0x256a: return 216; - case 0x2518: return 217; - case 0x250c: return 218; - case 0x2588: return 219; - case 0x2584: return 220; - case 0x258c: return 221; - case 0x2590: return 222; - case 0x2580: return 223; - case 0x03b1: return 224; - case 0x00df: return 225; - case 0x0393: return 226; - case 0x03c0: return 227; - case 0x03a3: return 228; - case 0x03c3: return 229; - case 0x00b5: return 230; - case 0x03c4: return 231; - case 0x03a6: return 232; - case 0x0398: return 233; - case 0x03a9: return 234; - case 0x03b4: return 235; - case 0x221e: return 236; - case 0x03c6: return 237; - case 0x03b5: return 238; - case 0x2229: return 239; - case 0x2261: return 240; - case 0x00b1: return 241; - case 0x2265: return 242; - case 0x2264: return 243; - case 0x2320: return 244; - case 0x2321: return 245; - case 0x00f7: return 246; - case 0x2248: return 247; - case 0x00b0: return 248; - case 0x2219: return 249; - case 0x00b7: return 250; - case 0x221a: return 251; - case 0x207f: return 252; - case 0x00b2: return 253; - case 0x25a0: return 254; - } + case 0x2302: + return 127; + case 0x00c7: + return 128; + case 0x00fc: + return 129; + case 0x00e9: + return 130; + case 0x00e2: + return 131; + case 0x00e4: + return 132; + case 0x00e0: + return 133; + case 0x00e5: + return 134; + case 0x00e7: + return 135; + case 0x00ea: + return 136; + case 0x00eb: + return 137; + case 0x00e8: + return 138; + case 0x00ef: + return 139; + case 0x00ee: + return 140; + case 0x00ec: + return 141; + case 0x00c4: + return 142; + case 0x00c5: + return 143; + case 0x00c9: + return 144; + case 0x00e6: + return 145; + case 0x00c6: + return 146; + case 0x00f4: + return 147; + case 0x00f6: + return 148; + case 0x00f2: + return 149; + case 0x00fb: + return 150; + case 0x00f9: + return 151; + case 0x00ff: + return 152; + case 0x00d6: + return 153; + case 0x00dc: + return 154; + case 0x00a2: + return 155; + case 0x00a3: + return 156; + case 0x00a5: + return 157; + case 0x20a7: + return 158; + case 0x0192: + return 159; + case 0x00e1: + return 160; + case 0x00ed: + return 161; + case 0x00f3: + return 162; + case 0x00fa: + return 163; + case 0x00f1: + return 164; + case 0x00d1: + return 165; + case 0x00aa: + return 166; + case 0x00ba: + return 167; + case 0x00bf: + return 168; + case 0x2310: + return 169; + case 0x00ac: + return 170; + case 0x00bd: + return 171; + case 0x00bc: + return 172; + case 0x00a1: + return 173; + case 0x00ab: + return 174; + case 0x00bb: + return 175; + case 0x2591: + return 176; + case 0x2592: + return 177; + case 0x2593: + return 178; + case 0x2502: + return 179; + case 0x2524: + return 180; + case 0x2561: + return 181; + case 0x2562: + return 182; + case 0x2556: + return 183; + case 0x2555: + return 184; + case 0x2563: + return 185; + case 0x2551: + return 186; + case 0x2557: + return 187; + case 0x255d: + return 188; + case 0x255c: + return 189; + case 0x255b: + return 190; + case 0x2510: + return 191; + case 0x2514: + return 192; + case 0x2534: + return 193; + case 0x252c: + return 194; + case 0x251c: + return 195; + case 0x2500: + return 196; + case 0x253c: + return 197; + case 0x255e: + return 198; + case 0x255f: + return 199; + case 0x255a: + return 200; + case 0x2554: + return 201; + case 0x2569: + return 202; + case 0x2566: + return 203; + case 0x2560: + return 204; + case 0x2550: + return 205; + case 0x256c: + return 206; + case 0x2567: + return 207; + case 0x2568: + return 208; + case 0x2564: + return 209; + case 0x2565: + return 210; + case 0x2559: + return 211; + case 0x2558: + return 212; + case 0x2552: + return 213; + case 0x2553: + return 214; + case 0x256b: + return 215; + case 0x256a: + return 216; + case 0x2518: + return 217; + case 0x250c: + return 218; + case 0x2588: + return 219; + case 0x2584: + return 220; + case 0x258c: + return 221; + case 0x2590: + return 222; + case 0x2580: + return 223; + case 0x03b1: + return 224; + case 0x00df: + return 225; + case 0x0393: + return 226; + case 0x03c0: + return 227; + case 0x03a3: + return 228; + case 0x03c3: + return 229; + case 0x00b5: + return 230; + case 0x03c4: + return 231; + case 0x03a6: + return 232; + case 0x0398: + return 233; + case 0x03a9: + return 234; + case 0x03b4: + return 235; + case 0x221e: + return 236; + case 0x03c6: + return 237; + case 0x03b5: + return 238; + case 0x2229: + return 239; + case 0x2261: + return 240; + case 0x00b1: + return 241; + case 0x2265: + return 242; + case 0x2264: + return 243; + case 0x2320: + return 244; + case 0x2321: + return 245; + case 0x00f7: + return 246; + case 0x2248: + return 247; + case 0x00b0: + return 248; + case 0x2219: + return 249; + case 0x00b7: + return 250; + case 0x221a: + return 251; + case 0x207f: + return 252; + case 0x00b2: + return 253; + case 0x25a0: + return 254; + } - return -1; + return -1; } static void flanterm_putchar(struct flanterm_context *ctx, uint8_t c) { - if (ctx->discard_next || (c == 0x18 || c == 0x1a)) { - ctx->discard_next = false; - ctx->escape = false; - ctx->control_sequence = false; - ctx->unicode_remaining = 0; - ctx->osc = false; - ctx->osc_escape = false; - ctx->g_select = 0; - return; + if (ctx->discard_next || (c == 0x18 || c == 0x1a)) { + ctx->discard_next = false; + ctx->escape = false; + ctx->control_sequence = false; + ctx->unicode_remaining = 0; + ctx->osc = false; + ctx->osc_escape = false; + ctx->g_select = 0; + return; + } + + if (ctx->unicode_remaining != 0) { + if ((c & 0xc0) != 0x80) { + ctx->unicode_remaining = 0; + goto unicode_error; } + ctx->unicode_remaining--; + ctx->code_point |= (uint64_t)(c & 0x3f) << (6 * ctx->unicode_remaining); if (ctx->unicode_remaining != 0) { - if ((c & 0xc0) != 0x80) { - ctx->unicode_remaining = 0; - goto unicode_error; - } - - ctx->unicode_remaining--; - ctx->code_point |= (uint64_t)(c & 0x3f) << (6 * ctx->unicode_remaining); - if (ctx->unicode_remaining != 0) { - return; - } - - int cc = unicode_to_cp437(ctx->code_point); - - if (cc == -1) { - size_t replacement_width = (size_t)mk_wcwidth(ctx->code_point); - if (replacement_width > 0) { - ctx->raw_putchar(ctx, 0xfe); - } - for (size_t i = 1; i < replacement_width; i++) { - ctx->raw_putchar(ctx, ' '); - } - } else { - ctx->raw_putchar(ctx, cc); - } - return; + return; } + int cc = unicode_to_cp437(ctx->code_point); + + if (cc == -1) { + size_t replacement_width = (size_t)mk_wcwidth(ctx->code_point); + if (replacement_width > 0) { + ctx->raw_putchar(ctx, 0xfe); + } + for (size_t i = 1; i < replacement_width; i++) { + ctx->raw_putchar(ctx, ' '); + } + } else { + ctx->raw_putchar(ctx, cc); + } + return; + } + unicode_error: - if (c >= 0xc0 && c <= 0xf7) { - if (c >= 0xc0 && c <= 0xdf) { - ctx->unicode_remaining = 1; - ctx->code_point = (uint64_t)(c & 0x1f) << 6; - } else if (c >= 0xe0 && c <= 0xef) { - ctx->unicode_remaining = 2; - ctx->code_point = (uint64_t)(c & 0x0f) << (6 * 2); - } else if (c >= 0xf0 && c <= 0xf7) { - ctx->unicode_remaining = 3; - ctx->code_point = (uint64_t)(c & 0x07) << (6 * 3); - } - return; + if (c >= 0xc0 && c <= 0xf7) { + if (c >= 0xc0 && c <= 0xdf) { + ctx->unicode_remaining = 1; + ctx->code_point = (uint64_t)(c & 0x1f) << 6; + } else if (c >= 0xe0 && c <= 0xef) { + ctx->unicode_remaining = 2; + ctx->code_point = (uint64_t)(c & 0x0f) << (6 * 2); + } else if (c >= 0xf0 && c <= 0xf7) { + ctx->unicode_remaining = 3; + ctx->code_point = (uint64_t)(c & 0x07) << (6 * 3); } + return; + } - if (ctx->escape == true) { - escape_parse(ctx, c); - return; - } - - if (ctx->g_select) { - ctx->g_select--; - switch (c) { - case 'B': - ctx->charsets[ctx->g_select] = CHARSET_DEFAULT; break; - case '0': - ctx->charsets[ctx->g_select] = CHARSET_DEC_SPECIAL; break; - } - ctx->g_select = 0; - return; - } - - size_t x, y; - ctx->get_cursor_pos(ctx, &x, &y); + if (ctx->escape == true) { + escape_parse(ctx, c); + return; + } + if (ctx->g_select) { + ctx->g_select--; switch (c) { - case 0x00: - case 0x7f: - return; - case 0x1b: - ctx->escape_offset = 0; - ctx->escape = true; - return; - case '\t': - if ((x / ctx->tab_size + 1) >= ctx->cols) { - ctx->set_cursor_pos(ctx, ctx->cols - 1, y); - return; - } - ctx->set_cursor_pos(ctx, (x / ctx->tab_size + 1) * ctx->tab_size, y); - return; - case 0x0b: - case 0x0c: - case '\n': - if (y == ctx->scroll_bottom_margin - 1) { - ctx->scroll(ctx); - ctx->set_cursor_pos(ctx, (ctx->oob_output & FLANTERM_OOB_OUTPUT_ONLCR) ? 0 : x, y); - } else { - ctx->set_cursor_pos(ctx, (ctx->oob_output & FLANTERM_OOB_OUTPUT_ONLCR) ? 0 : x, y + 1); - } - return; - case '\b': - ctx->set_cursor_pos(ctx, x - 1, y); - return; - case '\r': - ctx->set_cursor_pos(ctx, 0, y); - return; - case '\a': - // The bell is handled by the kernel - if (ctx->callback != NULL) { - ctx->callback(ctx, FLANTERM_CB_BELL, 0, 0, 0); - } - return; - case 14: - // Move to G1 set - ctx->current_charset = 1; - return; - case 15: - // Move to G0 set - ctx->current_charset = 0; - return; + case 'B': + ctx->charsets[ctx->g_select] = CHARSET_DEFAULT; + break; + case '0': + ctx->charsets[ctx->g_select] = CHARSET_DEC_SPECIAL; + break; } + ctx->g_select = 0; + return; + } - if (ctx->insert_mode == true) { - for (size_t i = ctx->cols - 1; ; i--) { - ctx->move_character(ctx, i + 1, y, i, y); - if (i == x) { - break; - } - } + size_t x, y; + ctx->get_cursor_pos(ctx, &x, &y); + + switch (c) { + case 0x00: + case 0x7f: + return; + case 0x1b: + ctx->escape_offset = 0; + ctx->escape = true; + return; + case '\t': + if ((x / ctx->tab_size + 1) >= ctx->cols) { + ctx->set_cursor_pos(ctx, ctx->cols - 1, y); + return; } - - // Translate character set - switch (ctx->charsets[ctx->current_charset]) { - case CHARSET_DEFAULT: - break; - case CHARSET_DEC_SPECIAL: - if (dec_special_print(ctx, c)) { - return; - } - break; - } - - if (c >= 0x20 && c <= 0x7e) { - ctx->raw_putchar(ctx, c); + ctx->set_cursor_pos(ctx, (x / ctx->tab_size + 1) * ctx->tab_size, y); + return; + case 0x0b: + case 0x0c: + case '\n': + if (y == ctx->scroll_bottom_margin - 1) { + ctx->scroll(ctx); + ctx->set_cursor_pos( + ctx, (ctx->oob_output & FLANTERM_OOB_OUTPUT_ONLCR) ? 0 : x, y); } else { - ctx->raw_putchar(ctx, 0xfe); + ctx->set_cursor_pos( + ctx, (ctx->oob_output & FLANTERM_OOB_OUTPUT_ONLCR) ? 0 : x, y + 1); } + return; + case '\b': + ctx->set_cursor_pos(ctx, x - 1, y); + return; + case '\r': + ctx->set_cursor_pos(ctx, 0, y); + return; + case '\a': + // The bell is handled by the kernel + if (ctx->callback != NULL) { + ctx->callback(ctx, FLANTERM_CB_BELL, 0, 0, 0); + } + return; + case 14: + // Move to G1 set + ctx->current_charset = 1; + return; + case 15: + // Move to G0 set + ctx->current_charset = 0; + return; + } + + if (ctx->insert_mode == true) { + for (size_t i = ctx->cols - 1;; i--) { + ctx->move_character(ctx, i + 1, y, i, y); + if (i == x) { + break; + } + } + } + + // Translate character set + switch (ctx->charsets[ctx->current_charset]) { + case CHARSET_DEFAULT: + break; + case CHARSET_DEC_SPECIAL: + if (dec_special_print(ctx, c)) { + return; + } + break; + } + + if (c >= 0x20 && c <= 0x7e) { + ctx->raw_putchar(ctx, c); + } else { + ctx->raw_putchar(ctx, 0xfe); + } } void flanterm_flush(struct flanterm_context *ctx) { - ctx->double_buffer_flush(ctx); + ctx->double_buffer_flush(ctx); } void flanterm_full_refresh(struct flanterm_context *ctx) { - ctx->full_refresh(ctx); + ctx->full_refresh(ctx); } -void flanterm_deinit(struct flanterm_context *ctx, void (*_free)(void *, size_t)) { - ctx->deinit(ctx, _free); +void flanterm_deinit(struct flanterm_context *ctx, + void (*_free)(void *, size_t)) { + ctx->deinit(ctx, _free); } -void flanterm_get_dimensions(struct flanterm_context *ctx, size_t *cols, size_t *rows) { - *cols = ctx->cols; - *rows = ctx->rows; +void flanterm_get_dimensions(struct flanterm_context *ctx, size_t *cols, + size_t *rows) { + *cols = ctx->cols; + *rows = ctx->rows; } void flanterm_set_autoflush(struct flanterm_context *ctx, bool state) { - ctx->autoflush = state; + ctx->autoflush = state; } -void flanterm_set_callback(struct flanterm_context *ctx, void (*callback)(struct flanterm_context *, uint64_t, uint64_t, uint64_t, uint64_t)) { - ctx->callback = callback; +void flanterm_set_callback(struct flanterm_context *ctx, + void (*callback)(struct flanterm_context *, uint64_t, + uint64_t, uint64_t, uint64_t)) { + ctx->callback = callback; } uint64_t flanterm_get_oob_output(struct flanterm_context *ctx) { - return ctx->oob_output; + return ctx->oob_output; } -void flanterm_set_oob_output(struct flanterm_context *ctx, uint64_t oob_output) { - ctx->oob_output = oob_output; +void flanterm_set_oob_output(struct flanterm_context *ctx, + uint64_t oob_output) { + ctx->oob_output = oob_output; } diff --git a/kernel/src/sys/gfx/flanterm/flanterm.h b/kernel/src/sys/gfx/flanterm/flanterm.h index 9e23cb5..a4d5b78 100644 --- a/kernel/src/sys/gfx/flanterm/flanterm.h +++ b/kernel/src/sys/gfx/flanterm/flanterm.h @@ -26,9 +26,9 @@ #ifndef FLANTERM_H #define FLANTERM_H 1 +#include #include #include -#include #ifdef __cplusplus extern "C" { @@ -62,14 +62,19 @@ struct flanterm_context; #endif -void flanterm_write(struct flanterm_context *ctx, const char *buf, size_t count); +void flanterm_write(struct flanterm_context *ctx, const char *buf, + size_t count); void flanterm_flush(struct flanterm_context *ctx); void flanterm_full_refresh(struct flanterm_context *ctx); -void flanterm_deinit(struct flanterm_context *ctx, void (*_free)(void *ptr, size_t size)); +void flanterm_deinit(struct flanterm_context *ctx, + void (*_free)(void *ptr, size_t size)); -void flanterm_get_dimensions(struct flanterm_context *ctx, size_t *cols, size_t *rows); +void flanterm_get_dimensions(struct flanterm_context *ctx, size_t *cols, + size_t *rows); void flanterm_set_autoflush(struct flanterm_context *ctx, bool state); -void flanterm_set_callback(struct flanterm_context *ctx, void (*callback)(struct flanterm_context *, uint64_t, uint64_t, uint64_t, uint64_t)); +void flanterm_set_callback(struct flanterm_context *ctx, + void (*callback)(struct flanterm_context *, uint64_t, + uint64_t, uint64_t, uint64_t)); uint64_t flanterm_get_oob_output(struct flanterm_context *ctx); void flanterm_set_oob_output(struct flanterm_context *ctx, uint64_t oob_output); diff --git a/kernel/src/sys/gfx/flanterm/flanterm_private.h b/kernel/src/sys/gfx/flanterm/flanterm_private.h index c7b8b18..9b049af 100644 --- a/kernel/src/sys/gfx/flanterm/flanterm_private.h +++ b/kernel/src/sys/gfx/flanterm/flanterm_private.h @@ -27,12 +27,13 @@ #define FLANTERM_PRIVATE_H 1 #ifndef FLANTERM_IN_FLANTERM -#error "Do not use flanterm_private.h. Use interfaces defined in flanterm.h only." +#error \ + "Do not use flanterm_private.h. Use interfaces defined in flanterm.h only." #endif +#include #include #include -#include #ifdef __cplusplus extern "C" { @@ -41,76 +42,78 @@ extern "C" { #define FLANTERM_MAX_ESC_VALUES 16 struct flanterm_context { - /* internal use */ + /* internal use */ - size_t tab_size; - bool autoflush; - bool cursor_enabled; - bool scroll_enabled; - bool control_sequence; - bool escape; - bool osc; - bool osc_escape; - bool rrr; - bool discard_next; - bool bold; - bool bg_bold; - bool reverse_video; - bool dec_private; - bool insert_mode; - uint64_t code_point; - size_t unicode_remaining; - uint8_t g_select; - uint8_t charsets[2]; - size_t current_charset; - size_t escape_offset; - size_t esc_values_i; - size_t saved_cursor_x; - size_t saved_cursor_y; - size_t current_primary; - size_t current_bg; - size_t scroll_top_margin; - size_t scroll_bottom_margin; - uint32_t esc_values[FLANTERM_MAX_ESC_VALUES]; - uint64_t oob_output; - bool saved_state_bold; - bool saved_state_bg_bold; - bool saved_state_reverse_video; - size_t saved_state_current_charset; - size_t saved_state_current_primary; - size_t saved_state_current_bg; + size_t tab_size; + bool autoflush; + bool cursor_enabled; + bool scroll_enabled; + bool control_sequence; + bool escape; + bool osc; + bool osc_escape; + bool rrr; + bool discard_next; + bool bold; + bool bg_bold; + bool reverse_video; + bool dec_private; + bool insert_mode; + uint64_t code_point; + size_t unicode_remaining; + uint8_t g_select; + uint8_t charsets[2]; + size_t current_charset; + size_t escape_offset; + size_t esc_values_i; + size_t saved_cursor_x; + size_t saved_cursor_y; + size_t current_primary; + size_t current_bg; + size_t scroll_top_margin; + size_t scroll_bottom_margin; + uint32_t esc_values[FLANTERM_MAX_ESC_VALUES]; + uint64_t oob_output; + bool saved_state_bold; + bool saved_state_bg_bold; + bool saved_state_reverse_video; + size_t saved_state_current_charset; + size_t saved_state_current_primary; + size_t saved_state_current_bg; - /* to be set by backend */ + /* to be set by backend */ - size_t rows, cols; + size_t rows, cols; - void (*raw_putchar)(struct flanterm_context *, uint8_t c); - void (*clear)(struct flanterm_context *, bool move); - void (*set_cursor_pos)(struct flanterm_context *, size_t x, size_t y); - void (*get_cursor_pos)(struct flanterm_context *, size_t *x, size_t *y); - void (*set_text_fg)(struct flanterm_context *, size_t fg); - void (*set_text_bg)(struct flanterm_context *, size_t bg); - void (*set_text_fg_bright)(struct flanterm_context *, size_t fg); - void (*set_text_bg_bright)(struct flanterm_context *, size_t bg); - void (*set_text_fg_rgb)(struct flanterm_context *, uint32_t fg); - void (*set_text_bg_rgb)(struct flanterm_context *, uint32_t bg); - void (*set_text_fg_default)(struct flanterm_context *); - void (*set_text_bg_default)(struct flanterm_context *); - void (*set_text_fg_default_bright)(struct flanterm_context *); - void (*set_text_bg_default_bright)(struct flanterm_context *); - void (*move_character)(struct flanterm_context *, size_t new_x, size_t new_y, size_t old_x, size_t old_y); - void (*scroll)(struct flanterm_context *); - void (*revscroll)(struct flanterm_context *); - void (*swap_palette)(struct flanterm_context *); - void (*save_state)(struct flanterm_context *); - void (*restore_state)(struct flanterm_context *); - void (*double_buffer_flush)(struct flanterm_context *); - void (*full_refresh)(struct flanterm_context *); - void (*deinit)(struct flanterm_context *, void (*)(void *, size_t)); + void (*raw_putchar)(struct flanterm_context *, uint8_t c); + void (*clear)(struct flanterm_context *, bool move); + void (*set_cursor_pos)(struct flanterm_context *, size_t x, size_t y); + void (*get_cursor_pos)(struct flanterm_context *, size_t *x, size_t *y); + void (*set_text_fg)(struct flanterm_context *, size_t fg); + void (*set_text_bg)(struct flanterm_context *, size_t bg); + void (*set_text_fg_bright)(struct flanterm_context *, size_t fg); + void (*set_text_bg_bright)(struct flanterm_context *, size_t bg); + void (*set_text_fg_rgb)(struct flanterm_context *, uint32_t fg); + void (*set_text_bg_rgb)(struct flanterm_context *, uint32_t bg); + void (*set_text_fg_default)(struct flanterm_context *); + void (*set_text_bg_default)(struct flanterm_context *); + void (*set_text_fg_default_bright)(struct flanterm_context *); + void (*set_text_bg_default_bright)(struct flanterm_context *); + void (*move_character)(struct flanterm_context *, size_t new_x, size_t new_y, + size_t old_x, size_t old_y); + void (*scroll)(struct flanterm_context *); + void (*revscroll)(struct flanterm_context *); + void (*swap_palette)(struct flanterm_context *); + void (*save_state)(struct flanterm_context *); + void (*restore_state)(struct flanterm_context *); + void (*double_buffer_flush)(struct flanterm_context *); + void (*full_refresh)(struct flanterm_context *); + void (*deinit)(struct flanterm_context *, void (*)(void *, size_t)); - /* to be set by client */ + /* to be set by client */ - void (*callback)(struct flanterm_context *, uint64_t, uint64_t, uint64_t, uint64_t); + void (*callback)(struct flanterm_context *, uint64_t, uint64_t, uint64_t, + uint64_t); }; void flanterm_context_reinit(struct flanterm_context *ctx); diff --git a/kernel/src/sys/log.c b/kernel/src/sys/log.c old mode 100755 new mode 100644 index d458fba..548ff29 --- a/kernel/src/sys/log.c +++ b/kernel/src/sys/log.c @@ -1,45 +1,52 @@ #include "sys/arch/x86_64/io.h" #include "sys/gfx/flanterm/flanterm.h" +#include #include #include -#include extern struct flanterm_context *ft_ctx; static spinlock_t log_lock = {0}; void log(char *format, ...) { - //spinlock_acquire(&log_lock); + // spinlock_acquire(&log_lock); - // TODO: replace this call with a call to printf() when the RTC is implemented. - char *date = "1970-01-01 00:00:00 | "; - int i2 = 0; for (i2; date[i2] != 0; i2++);; - if (ft_ctx) - flanterm_write(ft_ctx, date, i2); + // TODO: replace this call with a call to printf() when the RTC is + // implemented. + char *date = "1970-01-01 00:00:00 | "; + int i2 = 0; + for (i2; date[i2] != 0; i2++) + ; + ; + if (ft_ctx) + flanterm_write(ft_ctx, date, i2); - char buf[2048]; - va_list l; - va_start(l, format); - npf_vsnprintf(buf, 2048, format, l); - va_end(l); + char buf[2048]; + va_list l; + va_start(l, format); + npf_vsnprintf(buf, 2048, format, l); + va_end(l); - int i = 0; for (i; buf[i] != 0; i++);; - if (ft_ctx) - flanterm_write(ft_ctx, buf, i); + int i = 0; + for (i; buf[i] != 0; i++) + ; + ; + if (ft_ctx) + flanterm_write(ft_ctx, buf, i); - for (int i=0;;i++) { - if (date[i] == '\0') - break; - - outb(0xE9, date[i]); - } + for (int i = 0;; i++) { + if (date[i] == '\0') + break; - for (int i=0;;i++) { - if (buf[i] == '\0') - break; - - outb(0xE9, buf[i]); - } + outb(0xE9, date[i]); + } - //spinlock_release(&log_lock); + for (int i = 0;; i++) { + if (buf[i] == '\0') + break; + + outb(0xE9, buf[i]); + } + + // spinlock_release(&log_lock); } \ No newline at end of file diff --git a/kernel/src/sys/printf.c b/kernel/src/sys/printf.c old mode 100755 new mode 100644 index cd56343..9097ac6 --- a/kernel/src/sys/printf.c +++ b/kernel/src/sys/printf.c @@ -18,15 +18,18 @@ extern struct flanterm_context *ft_ctx; void printf(char *format, ...) { - char buf[2048]; - va_list lst; - va_start(lst, format); - npf_vsnprintf(buf, 2048, format, lst); - va_end(lst); + char buf[2048]; + va_list lst; + va_start(lst, format); + npf_vsnprintf(buf, 2048, format, lst); + va_end(lst); - //rt_print(buf); - int i = 0; for (i; buf[i] != 0; i++);; + // rt_print(buf); + int i = 0; + for (i; buf[i] != 0; i++) + ; + ; - if (ft_ctx) - flanterm_write(ft_ctx, buf, i); + if (ft_ctx) + flanterm_write(ft_ctx, buf, i); } \ No newline at end of file diff --git a/kernel/src/sys/syscall.c b/kernel/src/sys/syscall.c index 7d3eb52..c87134e 100644 --- a/kernel/src/sys/syscall.c +++ b/kernel/src/sys/syscall.c @@ -1,6 +1,6 @@ #include "sched/sched.h" -#include #include +#include #include #include @@ -12,41 +12,45 @@ static int syscall_initialized = 0; static uint64_t __syscall_undefined() { return 0; } void syscall_handle(registers_t *regs) { - if (regs->rax > 1024) { - log("syscall - syscall_handle was called with rax better than what Soaplin supports (1024). did you forget to set rax?\n"); - return; - } - - if (curr_proc == NULL || curr_proc->regs.cs != 0x43) { - log("syscall - syscall_handle was called by the kernel. is this wanted?\n"); - return; - } - - if (syscall_table[regs->rax] == (syscall)__syscall_undefined) { - log("syscall - syscall_handle was called with an undefined system call. (%d)\n", regs->rax); - return; - } - - regs->rax = syscall_table[regs->rax](regs->rdi, regs->rsi, regs->rdx, regs->rcx, regs->r8, regs->r9); + if (regs->rax > 1024) { + log("syscall - syscall_handle was called with rax better than what Soaplin " + "supports (1024). did you forget to set rax?\n"); return; + } + + if (curr_proc == NULL || curr_proc->regs.cs != 0x43) { + log("syscall - syscall_handle was called by the kernel. is this wanted?\n"); + return; + } + + if (syscall_table[regs->rax] == (syscall)__syscall_undefined) { + log("syscall - syscall_handle was called with an undefined system call. " + "(%d)\n", + regs->rax); + return; + } + + regs->rax = syscall_table[regs->rax](regs->rdi, regs->rsi, regs->rdx, + regs->rcx, regs->r8, regs->r9); + return; } void syscall_register(int id, syscall handler) { - if (syscall_table[id] != (syscall)__syscall_undefined) - { - log("syscall - warning: syscall_register has been called to try replacing an existing syscall.\n"); - return; - } + if (syscall_table[id] != (syscall)__syscall_undefined) { + log("syscall - warning: syscall_register has been called to try replacing " + "an existing syscall.\n"); + return; + } - syscall_table[id] = handler; - log("syscall - System call %d has been set to %p\n", id, handler); + syscall_table[id] = handler; + log("syscall - System call %d has been set to %p\n", id, handler); } extern void syscall_exit(int exit_code); void syscall_init() { - for (int i = 0; i < 1024; i++) - syscall_table[i] = (syscall)__syscall_undefined; + for (int i = 0; i < 1024; i++) + syscall_table[i] = (syscall)__syscall_undefined; - syscall_register(0, (syscall)syscall_exit); + syscall_register(0, (syscall)syscall_exit); } \ No newline at end of file diff --git a/kernel/src/sys/syscall.h b/kernel/src/sys/syscall.h index 7dc962c..5fce348 100644 --- a/kernel/src/sys/syscall.h +++ b/kernel/src/sys/syscall.h @@ -4,15 +4,17 @@ #include /// A function that defines a system call. -/// NOTE: Arguments are defined as uint64_t, but you can simply put your own type, and then cast your function to syscall. -typedef uint64_t(*syscall)(uint64_t rdi, uint64_t rsi, uint64_t rdx, uint64_t rcx, uint64_t r8, uint64_t r9); +/// NOTE: Arguments are defined as uint64_t, but you can simply put your own +/// type, and then cast your function to syscall. +typedef uint64_t (*syscall)(uint64_t rdi, uint64_t rsi, uint64_t rdx, + uint64_t rcx, uint64_t r8, uint64_t r9); /// Registers a system call. /// NOTE: an existing system call cannot be replaced by another. void syscall_register(int id, syscall handler); /// Called by the interupt handler, or the "syscall" instruction handler -void syscall_handle(registers_t*); +void syscall_handle(registers_t *); /// Initialize the system calls. void syscall_init(); \ No newline at end of file diff --git a/kernel/src/sys/syscalls/syscalls_proc.c b/kernel/src/sys/syscalls/syscalls_proc.c index fc23e56..13bca78 100644 --- a/kernel/src/sys/syscalls/syscalls_proc.c +++ b/kernel/src/sys/syscalls/syscalls_proc.c @@ -1,6 +1,6 @@ #include int syscall_exit(int exit_code) { - //sched_exit(exit_code); - return 0; + // sched_exit(exit_code); + return 0; } \ No newline at end of file diff --git a/kernel/src/sys/uname.h b/kernel/src/sys/uname.h index b667962..516d1f4 100644 --- a/kernel/src/sys/uname.h +++ b/kernel/src/sys/uname.h @@ -1,13 +1,13 @@ #pragma once typedef struct __uname { - char sysname[128]; /* Operating system name */ - char nodename[128]; /* Name within communications network - to which the node is attached, if any */ - char release[128]; /* Operating system release */ - char version[128]; /* Operating system version */ - char machine[128]; /* Hardware type identifier */ + char sysname[128]; /* Operating system name */ + char nodename[128]; /* Name within communications network + to which the node is attached, if any */ + char release[128]; /* Operating system release */ + char version[128]; /* Operating system version */ + char machine[128]; /* Hardware type identifier */ #ifdef _GNU_SOURCE - char domainname[]; /* NIS or YP domain name */ + char domainname[]; /* NIS or YP domain name */ #endif } uname_t; \ No newline at end of file