VBE高分辨率显示模式开启

This commit is contained in:
xiaoyi1212 2024-05-21 21:09:04 +08:00
parent d6476d0509
commit 2b207128ff
20 changed files with 1419 additions and 200 deletions

View File

@ -1,17 +1,36 @@
.set ALIGN, 1<<0 .set MAGIC, 0x1badb002
.set MEMINFO, 1<<1 .set FLAGS, 7
.set FLAGS, ALIGN | MEMINFO /*.set FLAGS, 3 */
.set MAGIC, 0x1BADB002
.set CHECKSUM, -(MAGIC + FLAGS) .set CHECKSUM, -(MAGIC + FLAGS)
.set MODE_TYPE, 0
.set WIDTH, 1280 /* requested width */
.set HEIGHT, 720 /* requested height */
/* .set WIDTH, 640
.set HEIGHT, 480 */
.set DEPTH, 32 /* requested bits per pixel BPP */
.set HEADER_ADDR, 0
.set LOAD_ADDR, 0
.set LOAD_END_ADDR, 0
.set BSS_END_ADDR, 0
.set ENTRY_ADDR, 0
.section .multiboot .section .multiboot
.long MAGIC .long MAGIC
.long FLAGS .long FLAGS
.long CHECKSUM .long CHECKSUM
.long 0, 0, 0, 0, 0 .long HEADER_ADDR
.long 0 .long LOAD_ADDR
.long 1024, 768, 32 .long LOAD_END_ADDR
.long BSS_END_ADDR
.long ENTRY_ADDR
.long MODE_TYPE
.long WIDTH
.long HEIGHT
.long DEPTH
/* enough space for the returned header */
.space 4 * 13
.section .bss .section .bss
.align 16 .align 16
@ -25,6 +44,7 @@ stack_top:
_start: _start:
mov $stack_top, %esp mov $stack_top, %esp
push %ebx
call kernel_main call kernel_main
cli cli

View File

@ -1,30 +1,54 @@
import os import os
import sys import sys
gcc = '/i686_elf_tools/bin/i686-elf-gcc.exe -w -std=gnu99 -I include/ -std=gnu99 -ffreestanding -O0 -c -Wincompatible-pointer-types'
def check_os():
if sys.platform.startswith('darwin'):
return "Mac OS X"
elif sys.platform.startswith('win'):
return "Windows"
elif sys.platform.startswith('linux'):
return "Linux"
else:
return "Unknown"
if check_os() == "Windows":
gcc = '/i686_elf_tools/bin/i686-elf-gcc.exe -w -std=gnu99 -I include/ -std=gnu99 -ffreestanding -O2 -c -Wincompatible-pointer-types'
asm = '/i686_elf_tools/bin/i686-elf-as.exe' asm = '/i686_elf_tools/bin/i686-elf-as.exe'
nasm = "nasm -f elf32" nasm = "nasm -f elf32"
ld = '/i686_elf_tools/bin/i686-elf-ld.exe' ld = '/i686_elf_tools/bin/i686-elf-g++.exe'
cd = os.getcwd() # 获取当前执行目录 'D:\CrashPowerDOS-main\' cd = os.getcwd() # 获取当前执行目录 'D:\CrashPowerDOS-main\'
out = "target" out = "target"
dir_ = "\\"
elif check_os() == "Linux":
gcc = 'gcc.exe -w -std=gnu99 -I include/ -std=gnu99 -ffreestanding -O0 -c -Wincompatible-pointer-types'
asm = 'gcc.exe'
nasm = "nasm -f elf32"
ld = 'g++.exe'
cd = os.getcwd() # 获取当前执行目录 '\mnt\d\CrashPowerDOS-main\'
out = "target"
dir_ = "/"
def clean(): def clean():
print("Clean target folder") print("Clean target folder")
for file in os.listdir(cd + "\\target"): # 遍历指定文件夹下所有文件 for file in os.listdir(cd + dir_ + "target"): # 遍历指定文件夹下所有文件
os.remove(cd + "\\target\\" + file) os.remove(cd + dir_ + "target" + dir_ + file)
return 0 return 0
def build_boot(): # 构建引导程序 def build_boot(): # 构建引导程序
print("Building boot source code...") print("Building boot source code...")
status = True status = True
for file in os.listdir(cd + '\\boot'): for file in os.listdir(cd + dir_ + 'boot'):
if status and file == 'boot.asm': if status and file == 'boot.asm':
cmd = cd + asm + " " + cd + "\\boot\\" + file + " -o " + cd + "\\target\\" + file.split(".")[0] + ".o" cmd = cd + asm + " " + cd + dir_ + "boot" + dir_ + file + " -o " + cd + dir_ + "target" + dir_ + \
file.split(".")[0] + ".o"
status = False status = False
else: else:
cmd = nasm + " " + cd + "\\boot\\" + file + " -o " + cd + "\\target\\" + file.split(".")[0] + ".o" cmd = nasm + " " + cd + dir_ + "boot" + dir_ + file + " -o " + cd + dir_ + "target" + dir_ + \
file.split(".")[0] + ".o"
e = os.system(cmd) # os.system 执行命令 e为返回值(非0即不正常退出,可做判断终止构建流程) e = os.system(cmd) # os.system 执行命令 e为返回值(非0即不正常退出,可做判断终止构建流程)
if e != 0: if e != 0:
return -1 return -1
@ -33,8 +57,8 @@ def build_boot(): # 构建引导程序
def build_driver(): # 构建内置驱动程序 def build_driver(): # 构建内置驱动程序
print("Building driver source code...") print("Building driver source code...")
for file in os.listdir(cd + '\\driver'): for file in os.listdir(cd + dir_ + 'driver'):
cmd = cd + gcc + " " + "driver\\" + file + " -o " + "target\\" + file.split(".")[0] + ".o" cmd = cd + gcc + " " + "driver" + dir_ + file + " -o " + "target" + dir_ + file.split(".")[0] + ".o"
e = os.system(cmd) e = os.system(cmd)
if e != 0: if e != 0:
return -1 return -1
@ -43,8 +67,8 @@ def build_driver(): # 构建内置驱动程序
def build_kernel(): # 构建内核本体 def build_kernel(): # 构建内核本体
print("Building kernel source code...") print("Building kernel source code...")
for file in os.listdir(cd + '\\kernel'): for file in os.listdir(cd + dir_ + 'kernel'):
cmd = cd + gcc + " " + "kernel\\" + file + " -o " + "target\\" + file.split(".")[0] + ".o" cmd = cd + gcc + " " + "kernel" + dir_ + file + " -o " + "target" + dir_ + file.split(".")[0] + ".o"
e = os.system(cmd) e = os.system(cmd)
if e != 0: if e != 0:
return -1 return -1
@ -53,8 +77,8 @@ def build_kernel(): # 构建内核本体
def build_data(): # 构建数据结构实现 def build_data(): # 构建数据结构实现
print("Building util source code...") print("Building util source code...")
for file in os.listdir(cd + '\\util'): for file in os.listdir(cd + dir_ + 'util'):
cmd = cd + gcc + " " + "util\\" + file + " -o " + "target\\" + file.split(".")[0] + ".o" cmd = cd + gcc + " " + "util" + dir_ + file + " -o " + "target" + dir_ + file.split(".")[0] + ".o"
e = os.system(cmd) e = os.system(cmd)
if e != 0: if e != 0:
return -1 return -1
@ -63,8 +87,8 @@ def build_data(): # 构建数据结构实现
def build_sysapp(): # 构建内置系统应用 def build_sysapp(): # 构建内置系统应用
print("Building sysapp source code...") print("Building sysapp source code...")
for file in os.listdir(cd + '\\sysapp'): for file in os.listdir(cd + dir_ + 'sysapp'):
cmd = cd + gcc + " " + "sysapp\\" + file + " -o " + "target\\" + file.split(".")[0] + ".o" cmd = cd + gcc + " " + "sysapp" + dir_ + file + " -o " + "target" + dir_ + file.split(".")[0] + ".o"
e = os.system(cmd) e = os.system(cmd)
if e != 0: if e != 0:
return -1 return -1
@ -73,31 +97,45 @@ def build_sysapp(): # 构建内置系统应用
def build_network(): # 构建网络系统 def build_network(): # 构建网络系统
print("Building network source code...") print("Building network source code...")
for file in os.listdir(cd + '\\network'): for file in os.listdir(cd + dir_ + 'network'):
cmd = cd + gcc + " " + "network\\" + file + " -o " + "target\\" + file.split(".")[0] + ".o" cmd = cd + gcc + " " + "network" + dir_ + file + " -o " + "target" + dir_ + file.split(".")[0] + ".o"
e = os.system(cmd) e = os.system(cmd)
if e != 0: if e != 0:
return -1 return -1
return 0 return 0
def build_fs(): # 构建文件系统 def build_fs(): # 构建文件系统
print("Building fs source code...") print("Building fs source code...")
for file in os.listdir(cd + '\\fs'): for file in os.listdir(cd + dir_ + 'fs'):
cmd = cd + gcc + " " + "fs\\" + file + " -o " + "target\\" + file.split(".")[0] + ".o" cmd = cd + gcc + " " + "fs" + dir_ + file + " -o " + "target" + dir_ + file.split(".")[0] + ".o"
e = os.system(cmd) e = os.system(cmd)
if e != 0: if e != 0:
return -1 return -1
return 0 return 0
def linker(): # 交叉编译链接 def linker(): # 交叉编译链接
print("Linking object files...") print("Linking object files...")
source_file = "" source_file = ""
for file in os.listdir(cd + '\\target'): for file in os.listdir(cd + dir_ + 'target'):
source_file = source_file + " target\\" + file source_file = source_file + " target" + dir_ + file
return os.system( return os.system(
cd + "/i686_elf_tools/bin/i686-elf-gcc.exe -T linker.ld -o isodir\\sys\\kernel.elf -ffreestanding -O2 -nostdlib " + source_file + " -lgcc") cd + "/i686_elf_tools/bin/i686-elf-g++.exe -T linker.ld -o isodir" + dir_ + "sys" + dir_ + "kernel.elf -ffreestanding -O2 -nostdlib " + source_file + " -lgcc")
def launch():
if check_os() == "Windows":
if len(sys.argv) == 0 or sys.argv[1] == 'vga':
print("Graphics MODE [VGA]")
os.system("qemu-system-i386 -net nic,model=pcnet -net user -kernel isodir\\sys\\kernel.elf -hda diskx.img")
elif sys.argv[1] == 'vbe':
print("Graphics MODE [VBE]")
os.system("qemu-system-i386 -vga std -net nic,model=pcnet -net user -kernel isodir\\sys\\kernel.elf -hda diskx.img")
elif check_os() == "Linux":
os.system("grub-mkrescue -o cpos.iso isodir")
os.system("qemu-system-i386 -vga std -cdrom cpos.iso")
clean() clean()
a = build_boot() a = build_boot()
if a != 0: if a != 0:
@ -124,10 +162,3 @@ a = linker()
if a != 0: if a != 0:
exit(-1) exit(-1)
print("Launching i386 vm...") print("Launching i386 vm...")
if len(sys.argv) == 0 or sys.argv[1] == 'vga':
print("Graphics MODE [VGA]")
os.system("qemu-system-i386 -net nic,model=pcnet -net user -kernel isodir\\sys\\kernel.elf -hda diskx.img")
elif sys.argv[1] == 'vbe':
print("Graphics MODE [VBE]")
os.system("qemu-system-i386 -vga vmware -net nic,model=pcnet -net user -kernel isodir\\sys\\kernel.elf -hda diskx.img")

View File

@ -382,6 +382,9 @@ void hpet_initialize() {
if (!hpet) { if (!hpet) {
printf("can not found acpi hpet table\n"); printf("can not found acpi hpet table\n");
} }
printf("[acpi-hpet]: OEM: %s | Version: %d\n",hpet->oem,hpet->oemVersion);
hpetInfo = (HpetInfo *) hpet->hpetAddress.address; hpetInfo = (HpetInfo *) hpet->hpetAddress.address;
uint32_t counterClockPeriod = hpetInfo->generalCapabilities >> 32; uint32_t counterClockPeriod = hpetInfo->generalCapabilities >> 32;

View File

@ -1,68 +1,157 @@
#include "../include/graphics.h" #include "../include/graphics.h"
#include "../include/memory.h" #include "../include/memory.h"
#include "../include/io.h" #include "../include/io.h"
#include "../include/common.h"
#include "../include/multiboot2.h"
#include "../include/timer.h"
extern page_directory_t *kernel_directory; uint32_t width, height;
uint32_t video_base, video_size; uint32_t c_width, c_height; // 字符绘制总宽高
int32_t x, y;
int32_t cx, cy; // 字符坐标
uint32_t color, back_color;
uint32_t *screen;
uint32_t *char_buffer;
extern uint8_t ascfont[];
extern uint8_t plfont[];
svga_mode_info_t* svga_mode_get_info(multiboot_t *sys_multiboot_info,uint16_t mode) { bool vbe_status;
return (svga_mode_info_t *) sys_multiboot_info->vbe_mode_info;
void vbe_scroll() {
if (cx > c_width) {
cx = 0;
cy++;
} else cx++;
if (cy >= c_height) {
cy = c_height - 1;
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
screen[j + i * width] = screen[j + (i + 16) * width];
} }
/*
uint32_t svga_map_fb(uint32_t real_addr, uint32_t fb_length) {
int i = 0;
uint32_t fb_addr;
// Align framebuffer length to page boundaries
fb_length += 0x1000;
fb_length &= 0x0FFFF000;
// Map enough framebuffer
for(i = 0xD0000000; i < 0xD0000000 + fb_length; i += 0x1000) {
page_t* page = paging_get_page(i, true, kernel_directory);
fb_addr = (i & 0x0FFFF000) + real_addr;
page->present = 1;
page->rw = 1;
page->user = 1;
page->frame = fb_addr >> 12;
} }
}
// Convert the kernel directory addresses to physical if needed if (y == height - height % 16) {
for(i = 0x340; i < 0x340 + (fb_length / 0x400000); i++) { cy = c_height - 1;
uint32_t physAddr = kernel_directory->tablesPhysical[i]; for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
if((physAddr & 0xC0000000) == 0xC0000000) { (screen)[j + i * width] = (screen)[j + (i + 16 - height % 16) * width];
physAddr &= 0x0FFFFFFF; // get rid of high nybble }
}
kernel_directory->tablesPhysical[i] = physAddr; }
for (int i = 0; i < width; i++) {
for (int j = 0; j < 28; j++) {
screen[height * (width + j) + i] = back_color;
}
} }
} }
return 0xD0000000; void vbe_draw_char(char c, int32_t x, int32_t y) {
if (c == ' ') {
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 9; j++) {
screen[(y + i) * width + x + j] = back_color;
}
}
return;
} }
*/
int isVBEDisplayMode(uint16_t vbe_mode_info) { unsigned char *font;
if (vbe_mode_info & (1 << 12)) { font = plfont;
return 1; font += c * 16;
} else { for (int i = 0; i < 16; i++) {
for (int j = 0; j < 9; j++) {
if (font[i] & (0x80 >> j)) {
screen[(y + i) * width + x + j] = color;
} else screen[(y + i) * width + x + j] = back_color;
}
}
}
int cur_task() {
return 0; return 0;
while (1) {
vbe_draw_char('_', x, y);
clock_sleep(5);
vbe_draw_char(' ', x, y);
clock_sleep(5);
} }
} }
void initVBE(multiboot_t *mboot) { void draw_rect(int x0, int y0, int x1, int y1, int c) {
svga_mode_info_t *vbe_info = svga_mode_get_info(mboot,SVGA_DEFAULT_MODE); int x, y;
if(vbe_info->bpp == 32 || vbe_info->bpp == 16){ for (y = y0; y <= y1; y++) {
printf("VBE LOAD SUCCESS!"); for (x = x0; x <= x1; x++) {
(screen)[y * width + x] = c;
}
}
} }
printf("[VBE]: Bass: %08x | PITCH: %d | HEIGHT: %d\n",vbe_info->physbase, void vbe_putchar(char ch) {
vbe_info->pitch,
vbe_info->screen_height);
//video_base = svga_map_fb(svga_mode_info->physbase, svga_mode_info->pitch * svga_mode_info->screen_height); if (ch == '\n') {
cx = 0;
cy++;
return;
} else if (ch == '\r') {
cx = 0;
} else if (ch == '\b' && cx > 0) {
cx -= 1;
if (cx == 0) {
cx = c_width - 1;
if (cy != 0) cy -= 1;
if (cy == 0) cx = 0, cy = 0;
}
draw_rect(x, y, x + 9, y + 16, 0);
return;
}
vbe_scroll();
vbe_draw_char(ch, cx * 9 - 7, cy * 16);
}
void vbe_write(const char *data, size_t size) {
for (size_t i = 0; i < size; i++)
vbe_putchar(data[i]);
}
void vbe_writestring(const char *data) {
vbe_write(data, strlen(data));
}
void vbe_clear() {
for (uint32_t i = 0; i < (width * (height)); i++) {
screen[i] = back_color;
}
x = 2;
y = 0;
cx = cy = 0;
}
void initVBE(multiboot_t *info) {
printf("Loading VBE...\n");
vbe_status = true;
x = 2;
y = cx = cy = 0;
screen = (uint32_t) info->framebuffer_addr;
width = info->framebuffer_width;
height = info->framebuffer_height;
color = 0xFFFFFF;
back_color = 0x310924;
c_width = width / 9;
c_height = height / 16;
vbe_clear();
/*
for (int i = 0; i < c_height; i++){
vbe_putchar('A');
vbe_putchar('\n');
}
while (1) io_hlt(); while (1) io_hlt();
*/
} }

View File

@ -529,6 +529,11 @@ int mkdir(char *dictname, int last_clust, vfs_t *vfs) {
dictname: dictname:
last_clust: last_clust:
*/ */
struct FAT_FILEINFO *check_info = dict_search(
dictname, get_now_dir(vfs), get_directory_max(get_now_dir(vfs), vfs));
if(check_info != 0) return 0;
int r = mkfile(dictname, vfs); int r = mkfile(dictname, vfs);
if (!r) if (!r)
return 0; return 0;
@ -737,6 +742,7 @@ int mkfile(char *name, vfs_t *vfs) {
// logk("mkfile : %s\n", name); // logk("mkfile : %s\n", name);
char s[12]; char s[12];
int i, j; int i, j;
struct FAT_FILEINFO *finfo = Get_dictaddr(name, vfs); struct FAT_FILEINFO *finfo = Get_dictaddr(name, vfs);
// logk("finfo = %08x\n", finfo); // logk("finfo = %08x\n", finfo);
if (finfo == NULL) { if (finfo == NULL) {
@ -841,7 +847,6 @@ int mkfile(char *name, vfs_t *vfs) {
int changedict(char *dictname, vfs_t *vfs) { int changedict(char *dictname, vfs_t *vfs) {
// cd命令的依赖函数 // cd命令的依赖函数
strtoupper(dictname); strtoupper(dictname);
printf("%s\n",dictname);
if (strcmp(dictname, "/") == 0) { if (strcmp(dictname, "/") == 0) {
while (vfs->path->ctl->all != 0) { while (vfs->path->ctl->all != 0) {
kfree((FindForCount(vfs->path->ctl->all, vfs->path)->val)); kfree((FindForCount(vfs->path->ctl->all, vfs->path)->val));

View File

@ -55,4 +55,6 @@ void reset_kernel();
void shutdown_kernel(); void shutdown_kernel();
uint32_t memory_all(); uint32_t memory_all();
uint32_t ALIGN_F(const uint32_t addr, const uint32_t _align);
#endif //CRASHPOWEROS_COMMON_H #endif //CRASHPOWEROS_COMMON_H

View File

@ -43,7 +43,6 @@
#define BUF_SIZE 4096 #define BUF_SIZE 4096
#define SVGA_DEFAULT_MODE 0x117
// RRRRR GGGGGG BBBBB // RRRRR GGGGGG BBBBB
#define SVGA_24TO16BPP(x) ((x & 0xF80000) >> 8) | ((x & 0xFC00) >> 5) | ((x & 0xF8) >> 3) #define SVGA_24TO16BPP(x) ((x & 0xF80000) >> 8) | ((x & 0xFC00) >> 5) | ((x & 0xF8) >> 3)
@ -73,35 +72,6 @@ struct color_rgba {
uint8_t a; uint8_t a;
}; };
typedef struct svga_mode_info {
uint16_t attributes;
uint8_t windowA, windowB;
uint16_t granularity;
uint16_t windowSize;
uint16_t segmentA, segmentB;
uint32_t winFuncPtr; // ptr to INT 0x10 Function 0x4F05
uint16_t pitch; // bytes per scan line
uint16_t screen_width, screen_height; // resolution
uint8_t wChar, yChar, planes, bpp, banks; // number of banks
uint8_t memoryModel, bankSize, imagePages;
uint8_t reserved0;
// color masks
uint8_t readMask, redPosition;
uint8_t greenMask, greenPosition;
uint8_t blueMask, bluePosition;
uint8_t reservedMask, reservedPosition;
uint8_t directColorAttributes;
uint32_t physbase; //pointer to LFB in LFB modes
uint32_t offScreenMemOff;
uint16_t offScreenMemSize;
uint8_t reserved1[206];
} __attribute__((packed)) svga_mode_info_t;
svga_mode_info_t* svga_mode_get_info(multiboot_t *sys_multiboot_info,uint16_t mode);
typedef struct color_rgba color_rgba; typedef struct color_rgba color_rgba;
uint8_t vga_entry_color(enum vga_color fg, enum vga_color bg); uint8_t vga_entry_color(enum vga_color fg, enum vga_color bg);
@ -126,6 +96,14 @@ void vga_clear();
void move_cursor(); void move_cursor();
void initVBE(multiboot_t *mboot); void vbe_putchar(char c);
void vbe_clear();
void vbe_write(const char *data, size_t size);
void vbe_writestring(const char *data);
void vbe_scroll();
int cur_task();
void vbe_draw_char(char c,int32_t x,int32_t y);
void initVBE(multiboot_t *multiboot);
#endif #endif

View File

@ -14,6 +14,8 @@
typedef char ALIGN[16]; typedef char ALIGN[16];
#include "multiboot.h"
typedef struct page { typedef struct page {
uint32_t present: 1; uint32_t present: 1;
uint32_t rw: 1; uint32_t rw: 1;
@ -81,10 +83,12 @@ uint32_t kmalloc(size_t size);
uint32_t kmalloc_ap(uint32_t size, uint32_t *phys); uint32_t kmalloc_ap(uint32_t size, uint32_t *phys);
void init_page(); void init_page(multiboot_t *mboot);
void memclean(char *s, int len); void memclean(char *s, int len);
void *realloc(void *ptr, uint32_t size); void *realloc(void *ptr, uint32_t size);
page_t *get_phy_page(uint32_t address, int make, page_directory_t *dir);
#endif //CRASHPOWEROS_MEMORY_H #endif //CRASHPOWEROS_MEMORY_H

View File

@ -60,6 +60,8 @@ typedef struct multiboot_t {
uint32_t framebuffer_width; uint32_t framebuffer_width;
uint32_t framebuffer_height; uint32_t framebuffer_height;
char framebuffer_bpp; char framebuffer_bpp;
uint8_t type;
uint8_t color_info[5];
} __attribute__((packed)) multiboot_t; } __attribute__((packed)) multiboot_t;
/** /**

439
include/multiboot2.h Normal file
View File

@ -0,0 +1,439 @@
/**
* @file multiboot2.h
* @brief multiboot2
*/
#pragma once
#include "stdint.h"
#include "common.h"
/// @see Multiboot2 Specification version 2.0.pdf
// 启动后,在 32 位内核进入点,机器状态如下:
// 1. CS 指向基地址为 0x00000000限长为4G 1的代码段描述符。
// 2. DSSSESFS 和 GS 指向基地址为0x00000000限长为4G
// 1的数据段描述符。
// 3. A20 地址线已经打开。
// 4. 页机制被禁止。
// 5. 中断被禁止。
// 6. EAX = 0x2BADB002
// 7. 系统信息和启动信息块的线性地址保存在 EBX中相当于一个指针
// 以下即为这个信息块的结构
/**
* @brief MULTIBOOT2
*/
extern uint32_t multiboot2_magic;
extern uintptr_t multiboot2_boot_info_addr;
/* How many bytes from the start of the file we search for the header. */
static const uint32_t MULTIBOOT_SEARCH = 32768;
static const uint32_t MULTIBOOT_HEADER_ALIGN = 8;
/* The magic field should contain this. */
static const uint32_t MULTIBOOT2_HEADER_MAGIC = 0xe85250d6;
/* This should be in %eax. */
static const uint32_t MULTIBOOT2_BOOTLOADER_MAGIC = 0x36d76289;
/* Alignment of multiboot modules. */
static const uint32_t MULTIBOOT_MOD_ALIGN = 0x00001000;
/* Alignment of the multiboot info structure. */
static const uint32_t MULTIBOOT_INFO_ALIGN = 0x00000008;
/* Flags set in the 'flags' member of the multiboot header. */
static const uint32_t MULTIBOOT_TAG_ALIGN = 8;
static const uint32_t MULTIBOOT_TAG_TYPE_END = 0;
static const uint32_t MULTIBOOT_TAG_TYPE_CMDLINE = 1;
static const uint32_t MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME = 2;
static const uint32_t MULTIBOOT_TAG_TYPE_MODULE = 3;
static const uint32_t MULTIBOOT_TAG_TYPE_BASIC_MEMINFO = 4;
static const uint32_t MULTIBOOT_TAG_TYPE_BOOTDEV = 5;
static const uint32_t MULTIBOOT_TAG_TYPE_MMAP = 6;
static const uint32_t MULTIBOOT_TAG_TYPE_VBE = 7;
static const uint32_t MULTIBOOT_TAG_TYPE_FRAMEBUFFER = 8;
static const uint32_t MULTIBOOT_TAG_TYPE_ELF_SECTIONS = 9;
static const uint32_t MULTIBOOT_TAG_TYPE_APM = 10;
static const uint32_t MULTIBOOT_TAG_TYPE_EFI32 = 11;
static const uint32_t MULTIBOOT_TAG_TYPE_EFI64 = 12;
static const uint32_t MULTIBOOT_TAG_TYPE_SMBIOS = 13;
static const uint32_t MULTIBOOT_TAG_TYPE_ACPI_OLD = 14;
static const uint32_t MULTIBOOT_TAG_TYPE_ACPI_NEW = 15;
static const uint32_t MULTIBOOT_TAG_TYPE_NETWORK = 16;
static const uint32_t MULTIBOOT_TAG_TYPE_EFI_MMAP = 17;
static const uint32_t MULTIBOOT_TAG_TYPE_EFI_BS = 18;
static const uint32_t MULTIBOOT_TAG_TYPE_EFI32_IH = 19;
static const uint32_t MULTIBOOT_TAG_TYPE_EFI64_IH = 20;
static const uint32_t MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR = 21;
static const uint32_t MULTIBOOT_HEADER_TAG_END = 0;
static const uint32_t MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST =
1;
static const uint32_t MULTIBOOT_HEADER_TAG_ADDRESS = 2;
static const uint32_t MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS = 3;
static const uint32_t MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS = 4;
static const uint32_t MULTIBOOT_HEADER_TAG_FRAMEBUFFER = 5;
static const uint32_t MULTIBOOT_HEADER_TAG_MODULE_ALIGN = 6;
static const uint32_t MULTIBOOT_HEADER_TAG_EFI_BS = 7;
static const uint32_t MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI32 =
8;
static const uint32_t MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64 =
9;
static const uint32_t MULTIBOOT_HEADER_TAG_RELOCATABLE = 10;
static const uint32_t MULTIBOOT_ARCHITECTURE_I386 = 0;
static const uint32_t MULTIBOOT_ARCHITECTURE_MIPS32 = 4;
static const uint32_t MULTIBOOT_HEADER_TAG_OPTIONAL = 1;
static const uint32_t MULTIBOOT_LOAD_PREFERENCE_NONE = 0;
static const uint32_t MULTIBOOT_LOAD_PREFERENCE_LOW = 1;
static const uint32_t MULTIBOOT_LOAD_PREFERENCE_HIGH = 2;
static const uint32_t MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED =
1;
static const uint32_t MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED =
2;
static const uint32_t MULTIBOOT_MEMORY_AVAILABLE = 1;
static const uint32_t MULTIBOOT_MEMORY_RESERVED = 2;
static const uint32_t MULTIBOOT_MEMORY_ACPI_RECLAIMABLE = 3;
static const uint32_t MULTIBOOT_MEMORY_NVS = 4;
static const uint32_t MULTIBOOT_MEMORY_BADRAM = 5;
struct multiboot_header_t
{
// Must be MULTIBOOT_MAGIC - see above.
uint32_t magic;
// ISA
uint32_t architecture;
// Total header length.
uint32_t header_length;
// The above fields plus this one must equal 0 mod 2^32.
uint32_t checksum;
};
struct multiboot_header_tag_t
{
uint16_t type;
uint16_t flags;
uint32_t size;
};
struct multiboot_header_tag_information_request_t
{
uint16_t type;
uint16_t flags;
uint32_t size;
uint32_t requests[0];
};
struct multiboot_header_tag_address_t
{
uint16_t type;
uint16_t flags;
uint32_t size;
uint32_t header_addr;
uint32_t load_addr;
uint32_t load_end_addr;
uint32_t bss_end_addr;
};
struct multiboot_header_tag_entry_address_t
{
uint16_t type;
uint16_t flags;
uint32_t size;
uint32_t entry_addr;
};
struct multiboot_header_tag_console_flags_t
{
uint16_t type;
uint16_t flags;
uint32_t size;
uint32_t console_flags;
};
struct multiboot_header_tag_framebuffer_t
{
uint16_t type;
uint16_t flags;
uint32_t size;
uint32_t width;
uint32_t height;
uint32_t depth;
};
struct multiboot_header_tag_module_align_t
{
uint16_t type;
uint16_t flags;
uint32_t size;
};
struct multiboot_header_tag_relocatable_t
{
uint16_t type;
uint16_t flags;
uint32_t size;
uint32_t min_addr;
uint32_t max_addr;
uint32_t align;
uint32_t preference;
};
struct multiboot_color_t
{
uint8_t red;
uint8_t green;
uint8_t blue;
};
// multiboot2协议的内存区域信息
struct multiboot_mmap_entry_t
{
uint64_t addr;
uint64_t len;
uint32_t type;
uint32_t reserved;
};
struct multiboot_tag_t
{
uint32_t type;
uint32_t size;
};
struct multiboot_tag_string_t
{
struct multiboot_tag_t tag_t;
char string[0];
};
struct multiboot_tag_module_t
{
struct multiboot_tag_t tag_t;
uint32_t mod_start;
uint32_t mod_end;
char cmdline[0];
};
struct multiboot_tag_basic_meminfo_t
{
struct multiboot_tag_t tag_t;
uint32_t mem_lower;
uint32_t mem_upper;
};
struct multiboot_tag_bootdev_t
{
struct multiboot_tag_t tag_t;
uint32_t biosdev;
uint32_t slice;
uint32_t part;
};
struct multiboot_tag_mmap_t
{
struct multiboot_tag_t tag_t;
uint32_t entry_size;
uint32_t entry_version;
struct multiboot_mmap_entry_t entries[0];
};
struct multiboot_vbe_info_block_t
{
uint8_t external_specification[512];
};
struct multiboot_vbe_mode_info_block_t
{
uint8_t external_specification[256];
};
// bootloader传递的VBE信息的结构体
struct multiboot_tag_vbe_t
{
struct multiboot_tag_t tag_t;
uint16_t vbe_mode;
uint16_t vbe_interface_seg;
uint16_t vbe_interface_off;
uint16_t vbe_interface_len;
// The fields vbe_control_info and vbe_mode_info contain VBE control information returned by the VBE Function 00h and VBE mode information
// returned by the VBE Function 01h, respectively.
struct multiboot_vbe_info_block_t vbe_control_info;
struct multiboot_vbe_mode_info_block_t vbe_mode_info;
};
struct multiboot_tag_framebuffer_info_t
{
struct multiboot_tag_t tag_t;
uint64_t framebuffer_addr;
uint32_t framebuffer_pitch; // 帧缓存上界
// width and height expressed in pixels except type=2
// when type=2, they are expressed in characters
uint32_t framebuffer_width;
uint32_t framebuffer_height;
// number of bits per pixel.
uint8_t framebuffer_bpp;
// 帧缓存的类型
uint8_t framebuffer_type;
uint8_t reserved;
};
// indexed color
struct multiboot_tag_framebuffer_info_type0_t
{
struct multiboot_tag_framebuffer_info_t header;
uint32_t framebuffer_palette_num_colors;
struct multiboot_color_t color_desc;
};
// direct RGB color
struct multiboot_tag_framebuffer_info_type1_t
{
struct multiboot_tag_framebuffer_info_t header;
uint8_t framebuffer_red_field_position;
uint8_t framebuffer_red_mask_size;
uint8_t framebuffer_green_field_position;
uint8_t framebuffer_green_mask_size;
uint8_t framebuffer_blue_field_position;
uint8_t framebuffer_blue_mask_size;
};
struct multiboot_tag_elf_sections_t
{
struct multiboot_tag_t tag_t;
uint32_t num;
uint32_t entsize;
// 段字符串表索引
uint32_t shndx;
char sections[0];
};
struct multiboot_tag_apm_t
{
struct multiboot_tag_t tag_t;
uint16_t version;
uint16_t cseg;
uint32_t offset;
uint16_t cseg_16;
uint16_t dseg;
uint16_t flags;
uint16_t cseg_len;
uint16_t cseg_16_len;
uint16_t dseg_len;
};
struct multiboot_tag_efi32_t
{
struct multiboot_tag_t tag_t;
uint32_t pointer;
};
struct multiboot_tag_efi64_t
{
struct multiboot_tag_t tag_t;
uint64_t pointer;
};
struct multiboot_tag_smbios_t
{
struct multiboot_tag_t tag_t;
uint8_t major;
uint8_t minor;
uint8_t reserved[6];
uint8_t tables[0];
};
struct multiboot_tag_network_t
{
struct multiboot_tag_t tag_t;
uint8_t dhcpack[0];
};
struct multiboot_tag_efi_mmap_t
{
struct multiboot_tag_t tag_t;
uint32_t descr_size;
uint32_t descr_vers;
uint8_t efi_mmap[0];
};
struct multiboot_tag_efi32_ih_t
{
struct multiboot_tag_t tag_t;
uint32_t pointer;
};
struct multiboot_tag_efi64_ih_t
{
struct multiboot_tag_t tag_t;
uint64_t pointer;
};
struct multiboot_tag_load_base_addr_t
{
struct multiboot_tag_t tag_t;
uint32_t load_base_addr;
};
// 迭代变量
// 与 multiboot_tag_t 相同
struct iter_data_t
{
uint32_t type;
uint32_t size;
};
/**
* @brief
* @return true
* @return false
*/
bool multiboot2_init(uint32_t info_addr);
/**
* @brief
* @param _fun
* @param _data
*/
void multiboot2_iter(bool (*_fun)(const struct iter_data_t *, void *, uint32_t *),
void *_data, uint32_t *count);
/**
* @brief multiboot2协议提供的内存区域信息
*
* @param _iter_data
* @param _data
* @param count
* @return true
* @return false
*/
bool multiboot2_get_memory(const struct iter_data_t *_iter_data, void *_data, uint32_t *count);
/**
* @brief VBE信息
*
* @param _iter_data
* @param _data
*/
bool multiboot2_get_VBE_info(const struct iter_data_t *_iter_data, void *_data, uint32_t *reserved);
/**
* @brief
*
* @param _iter_data
* @param _data
*/
bool multiboot2_get_Framebuffer_info(const struct iter_data_t *_iter_data, void *_data, uint32_t *reserved);

View File

@ -10,5 +10,7 @@ int sprintf(char *buf, const char *fmt, ...);
void printf(const char *formet, ...); void printf(const char *formet, ...);
void print(char *message); void print(char *message);
void printk(const char *formet, ...); void printk(const char *formet, ...);
void putchar(char c);
void screen_clear();
#endif //CRASHPOWEROS_PRINTF_H #endif //CRASHPOWEROS_PRINTF_H

View File

@ -23,8 +23,6 @@
extern uint32_t end; extern uint32_t end;
extern int status; extern int status;
uint32_t placement_address = (uint32_t) & end; uint32_t placement_address = (uint32_t) & end;
multiboot_t *multiboot_all;
void reset_kernel(){ void reset_kernel(){
printf("Restart %s for x86...\n",OS_NAME); printf("Restart %s for x86...\n",OS_NAME);
@ -41,7 +39,7 @@ void shutdown_kernel(){
} }
uint32_t memory_all(){ uint32_t memory_all(){
return (multiboot_all->mem_upper + multiboot_all->mem_lower); return 0;
} }
int check_task(int *pid){ int check_task(int *pid){
@ -59,30 +57,36 @@ int check_task(int *pid){
} }
void kernel_main(multiboot_t *multiboot) { void kernel_main(multiboot_t *multiboot) {
io_cli(); io_cli();
vga_install(); vga_install();
if ((multiboot->mem_upper + multiboot->mem_lower) / 1024 + 1 < 16) { if ((multiboot->mem_upper + multiboot->mem_lower) / 1024 + 1 < 16) {
printf("[kernel] Minimal RAM amount for CPOS is 16 MB, but you have only %d MB.\n", printf("[kernel] Minimal RAM amount for CPOS is 16 MB, but you have only %d MB.\n",
(multiboot->mem_upper + multiboot->mem_lower) / 1024 + 1); (multiboot->mem_upper + multiboot->mem_lower) / 1024 + 1);
while (1) io_hlt(); while (1) io_hlt();
} }
//initVBE(multiboot);
printf("[\035kernel\036]: VGA driver load success!\n"); initVBE(multiboot);
printf("[kernel]: VGA driver load success!\n");
gdt_install(); gdt_install();
idt_install(); idt_install();
printf("[\035kernel\036]: description table config success!\n"); printf("[kernel]: description table config success!\n");
init_timer(1); init_timer(1);
acpi_install(); acpi_install();
printf("[\035kernel\036]: ACPI enable success!\n"); printf("[kernel]: ACPI enable success!\n");
init_page(); init_page(multiboot);
printf("[\035kernel\036]: page set success!\n");
printf("[kernel]: page set success!\n");
init_sched(); init_sched();
printf("[\035kernel\036]: task load success!\n"); printf("[kernel]: task load success!\n");
init_keyboard(); init_keyboard();
printf("[\035kernel\036]: Keyboard driver load success!\n"); printf("[kernel]: Keyboard driver load success!\n");
multiboot_all = multiboot;
io_sti(); io_sti();
kernel_thread(cur_task,NULL,"CPOS-VBE-SERVICE");
init_pit(); init_pit();
init_pci(); init_pci();
init_vdisk(); init_vdisk();
@ -100,11 +104,11 @@ void kernel_main(multiboot_t *multiboot) {
} }
if(pcnet_find_card()){ if(pcnet_find_card()){
//init_pcnet_card(); //init_pcnet_card();
} else printf("[\035kernel\036]: \033Cannot found pcnet.\036\n"); } else printf("[kernel]: Cannot found pcnet.\n");
print_cpu_id(); print_cpu_id();
printf("Memory: %dMB.",(multiboot->mem_upper + multiboot->mem_lower)/1024/1024); //printf("Memory: %dMB.",(multiboot->mem_upper + multiboot->mem_lower)/1024/1024);
clock_sleep(25); clock_sleep(25);

95
kernel/multiboot2.c Normal file
View File

@ -0,0 +1,95 @@
#include "../include/multiboot2.h"
uintptr_t multiboot2_boot_info_addr;
uint32_t multiboot2_magic;
uint32_t multiboot2_boot_info_size;
bool multiboot2_init(uint32_t info_addr) {
multiboot2_boot_info_addr = info_addr;
uintptr_t *addr = (uintptr_t *) multiboot2_boot_info_addr;
if (multiboot2_magic != MULTIBOOT2_BOOTLOADER_MAGIC)
return false;
// addr+0 处保存了大小
multiboot2_boot_info_size = *(uint32_t *) addr;
return true;
}
void multiboot2_iter(bool (*_fun)(const struct iter_data_t *, void *, uint32_t *),
void *data, uint32_t *count) {
uintptr_t addr = multiboot2_boot_info_addr;
// 接下来的第8字节开始为 tag 信息
struct iter_data_t *tag = (struct iter_data_t *) ((void *) addr + 8);
for (; tag->type != MULTIBOOT_TAG_TYPE_END;
tag = (struct iter_data_t *) ((uint8_t *) tag + ALIGN_F(tag->size, 8))) {
if (_fun(tag, data, count) == true) {
return;
}
}
return;
}
// 读取 grub2 传递的物理内存信息,保存到 e820map_t 结构体中
// 一般而言是这样的
// 地址(长度) 类型
// 0x00(0x9F000) 0x1
// 0x9F000(0x1000) 0x2
// 0xE8000(0x18000) 0x2
// 0x100000(0x7EF0000) 0x1
// 0x7FF0000(0x10000) 0x3
// 0xFFFC0000(0x40000) 0x2
/**
* @brief multiboot2协议提供的内存区域信息
*
* @param _iter_data
* @param _data
* @param count
* @return true
* @return false
*/
bool multiboot2_get_memory(const struct iter_data_t *_iter_data, void *data, uint32_t *count) {
if (_iter_data->type != MULTIBOOT_TAG_TYPE_MMAP)
return false;
struct multiboot_mmap_entry_t *resource = (struct multiboot_mmap_entry_t *) data;
struct multiboot_mmap_entry_t *mmap = ((struct multiboot_tag_mmap_t *) _iter_data)->entries;
*count = 0;
for (; (uint8_t *) mmap < (uint8_t *) _iter_data + _iter_data->size;
mmap = (struct multiboot_mmap_entry_t *) ((uint8_t *) mmap +
((struct multiboot_tag_mmap_t *) _iter_data)->entry_size)) {
*resource = *mmap;
// 将指针进行增加
resource = (struct multiboot_mmap_entry_t *) ((uint8_t *) resource +
((struct multiboot_tag_mmap_t *) _iter_data)->entry_size);
++(*count);
}
return true;
}
/**
* @brief VBE信息
*
* @param _iter_data
* @param _data
*/
bool multiboot2_get_VBE_info(const struct iter_data_t *_iter_data, void *data, uint32_t *reserved) {
if (_iter_data->type != MULTIBOOT_TAG_TYPE_VBE)
return false;
*(struct multiboot_tag_vbe_t *) data = *(struct multiboot_tag_vbe_t *) _iter_data;
return true;
}
/**
* @brief
*
* @param _iter_data
* @param _data
*/
bool multiboot2_get_Framebuffer_info(const struct iter_data_t *_iter_data, void *data, uint32_t *reserved) {
if (_iter_data->type != MULTIBOOT_TAG_TYPE_FRAMEBUFFER)
return false;
*(struct multiboot_tag_framebuffer_info_t *) data = *(struct multiboot_tag_framebuffer_info_t *) _iter_data;
return true;
}

View File

@ -59,6 +59,7 @@ void alloc_frame(page_t *page, int is_kernel, int is_writable) {
asm("cli"); asm("cli");
for (;;)io_hlt(); for (;;)io_hlt();
} }
set_frame(idx * 0x1000); set_frame(idx * 0x1000);
page->present = 1; // 现在这个页存在了 page->present = 1; // 现在这个页存在了
page->rw = is_writable ? 1 : 0; // 是否可写由is_writable决定 page->rw = is_writable ? 1 : 0; // 是否可写由is_writable决定
@ -66,7 +67,15 @@ void alloc_frame(page_t *page, int is_kernel, int is_writable) {
page->frame = idx; page->frame = idx;
} }
} }
void alloc_frame_line(page_t *page, unsigned line,int is_kernel, int is_writable) {
// logk("%08x\n",line);
set_frame(line);
page->present = 1; // 现在这个页存在了
page->rw = is_writable ? 1 : 0; // 是否可写由is_writable决定
page->user = is_kernel ? 0 : 1; // 是否为用户态由is_kernel决定
page->frame = line / 0x1000;
}
void free_frame(page_t *page) { void free_frame(page_t *page) {
uint32_t frame = page->frame; uint32_t frame = page->frame;
if (!frame) return; if (!frame) return;
@ -86,6 +95,7 @@ void switch_page_directory(page_directory_t *dir) {
} }
page_t *get_page(uint32_t address, int make, page_directory_t *dir) { page_t *get_page(uint32_t address, int make, page_directory_t *dir) {
address /= 0x1000; address /= 0x1000;
uint32_t table_idx = address / 1024; uint32_t table_idx = address / 1024;
if (dir->tables[table_idx]) return &dir->tables[table_idx]->pages[address % 1024]; if (dir->tables[table_idx]) return &dir->tables[table_idx]->pages[address % 1024];
@ -98,6 +108,7 @@ page_t *get_page(uint32_t address, int make, page_directory_t *dir) {
} else return 0; } else return 0;
} }
void page_fault(registers_t *regs) { void page_fault(registers_t *regs) {
asm("cli"); asm("cli");
uint32_t faulting_address; uint32_t faulting_address;
@ -175,7 +186,7 @@ page_directory_t *clone_directory(page_directory_t *src) {
return dir; return dir;
} }
void init_page() { void init_page(multiboot_t *mboot) {
uint32_t mem_end_page = 0xFFFFFFFF; // 4GB Page uint32_t mem_end_page = 0xFFFFFFFF; // 4GB Page
nframes = mem_end_page / 0x1000; nframes = mem_end_page / 0x1000;
@ -187,12 +198,19 @@ void init_page() {
memset(kernel_directory, 0, sizeof(page_directory_t)); memset(kernel_directory, 0, sizeof(page_directory_t));
current_directory = kernel_directory; current_directory = kernel_directory;
int i = 0; int i = 0;
while (i < placement_address) { while (i < placement_address) {
// 内核部分对ring3而言可读不可写 | 无偏移页表映射 // 内核部分对ring3而言可读不可写 | 无偏移页表映射
alloc_frame(get_page(i, 1, kernel_directory), 0, 0); alloc_frame(get_page(i, 1, kernel_directory), 0, 0);
i += 0x1000; i += 0x1000;
} }
unsigned int j = mboot->framebuffer_addr,size = mboot->framebuffer_height * mboot->framebuffer_width*mboot->framebuffer_bpp;
while (j <= mboot->framebuffer_addr + size){
alloc_frame_line(get_page(j,1,kernel_directory),j,0,0);
j += 0x1000;
}
for (int i = KHEAP_START; i < KHEAP_START + KHEAP_INITIAL_SIZE; i++) { for (int i = KHEAP_START; i < KHEAP_START + KHEAP_INITIAL_SIZE; i++) {
alloc_frame(get_page(i, 1, kernel_directory), 0, 0); alloc_frame(get_page(i, 1, kernel_directory), 0, 0);
} }

View File

@ -2,13 +2,16 @@
#include "../include/cmos.h" #include "../include/cmos.h"
#include "../include/graphics.h" #include "../include/graphics.h"
#include "../include/timer.h" #include "../include/timer.h"
#include "../include/common.h"
extern uint16_t *terminal_buffer; extern uint16_t *terminal_buffer;
extern uint8_t terminal_color; extern uint8_t terminal_color;
extern bool vbe_status;
int date_pid; int date_pid;
void launch_date(){ void launch_date(){
if(!vbe_status)
date_pid = kernel_thread(setup_date, NULL, "CPOS-Date"); date_pid = kernel_thread(setup_date, NULL, "CPOS-Date");
} }

View File

@ -102,7 +102,7 @@ static int check_exit(){
} }
void pcat_launch(struct File *file){ void pcat_launch(struct File *file){
vga_clear(); task_kill(date_pid); vga_clear(); screen_clear(); task_kill(date_pid); vga_clear();
this_process = (struct pcat_process*) kmalloc(sizeof(struct pcat_process)); this_process = (struct pcat_process*) kmalloc(sizeof(struct pcat_process));
this_process->buf_x = this_process->buf_y = 0; this_process->buf_x = this_process->buf_y = 0;
this_process->line = 1; this_process->line = 1;
@ -121,6 +121,6 @@ void pcat_launch(struct File *file){
input_handler(); input_handler();
} }
task_kill(pid); task_kill(pid);
vga_clear(); screen_clear();
date_pid = kernel_thread(setup_date, NULL, "CPOS-Date"); date_pid = kernel_thread(setup_date, NULL, "CPOS-Date");
} }

View File

@ -24,15 +24,15 @@ int gets(char *buf, int buf_size) {
if (c == '\b') { if (c == '\b') {
if (index > 0) { if (index > 0) {
index--; index--;
vga_writestring("\b \b"); print("\b \b");
} }
} else { } else {
buf[index++] = c; buf[index++] = c;
vga_putchar(c); putchar(c);
} }
} }
buf[index] = '\0'; buf[index] = '\0';
vga_putchar(c); putchar(c);
return index; return index;
} }
@ -60,16 +60,16 @@ int cmd_parse(char *cmd_str, char **argv, char token) {
void cmd_echo(int argc, char **argv) { void cmd_echo(int argc, char **argv) {
for (int i = 1; i < argc; i++) { for (int i = 1; i < argc; i++) {
if (i == 1) vga_writestring(""); if (i == 1) print("");
else vga_writestring(" "); else print(" ");
vga_writestring(argv[i]); print(argv[i]);
} }
vga_putchar('\n'); print("\n");
} }
void cmd_proc(int argc, char **argv) { void cmd_proc(int argc, char **argv) {
if (argc <= 1) { if (argc <= 1) {
printf("\033[Shell-PROC]: If there are too few parameters.\036\n"); printf("[Shell-PROC]: If there are too few parameters.\n");
return; return;
} }
@ -77,13 +77,13 @@ void cmd_proc(int argc, char **argv) {
print_proc(); print_proc();
} else if (!strcmp("kill", argv[1])) { } else if (!strcmp("kill", argv[1])) {
if (argc <= 2) { if (argc <= 2) {
printf("\033[Shell-PROC-kill]: If there are too few parameters.\036\n"); printf("[Shell-PROC-kill]: If there are too few parameters.\n");
return; return;
} }
int pid = strtol(argv[2], NULL, 10); int pid = strtol(argv[2], NULL, 10);
task_kill(pid); task_kill(pid);
} else { } else {
printf("\033[Shell-[PROC]]: Unknown parameter\036\n"); printf("[Shell-[PROC]]: Unknown parameter\n");
return; return;
} }
} }
@ -94,7 +94,7 @@ void cmd_date() {
(KHEAP_START + KHEAP_INITIAL_SIZE) / 1024 / 1024); (KHEAP_START + KHEAP_INITIAL_SIZE) / 1024 / 1024);
print_cpu_id(); print_cpu_id();
vga_writestring("\n"); print("\n");
} }
void cmd_ls() { void cmd_ls() {
@ -127,7 +127,7 @@ void cmd_ls() {
void cmd_mkdir(int argc, char **argv) { void cmd_mkdir(int argc, char **argv) {
if (argc == 1) { if (argc == 1) {
printf("\033[Shell-MKDIR]: If there are too few parameters, please specify the directory name.\036\n"); printf("[Shell-MKDIR]: If there are too few parameters, please specify the directory name.\n");
return; return;
} }
@ -145,7 +145,7 @@ void cmd_mkdir(int argc, char **argv) {
void cmd_del(int argc, char **argv) { void cmd_del(int argc, char **argv) {
if (argc == 1) { if (argc == 1) {
vga_writestring("\033[Shell-DEL]: If there are too few parameters, please specify the folder name.\036\n"); print("[Shell-DEL]: If there are too few parameters, please specify the folder name.\n");
return; return;
} }
@ -174,19 +174,13 @@ void cmd_shutdown() {
} }
void cmd_debug() { void cmd_debug() {
vga_clear(); screen_clear();
/*
extern multiboot_t *multiboot_all;
svga_mode_info_t *vbe_info = multiboot_all->vbe_mode_info;
printf("%08x\n",vbe_info->screen_height);
*/
printf("%s for x86 [Version %s] \n", OS_NAME, OS_VERSION); printf("%s for x86 [Version %s] \n", OS_NAME, OS_VERSION);
printf("\032Copyright 2024 XIAOYI12 (Build by GCC i686-elf-tools)\036\n"); printf("Copyright 2024 XIAOYI12 (Build by GCC i686-elf-tools)\n");
extern int acpi_enable_flag; extern int acpi_enable_flag;
extern uint8_t *rsdp_address; extern uint8_t *rsdp_address;
printf("ACPI: Enable: %s | RSDP Address: 0x%08x\n", acpi_enable_flag ? "\035ENABLE\036" : "\033DISABLE\036", printf("ACPI: Enable: %s | RSDP Address: 0x%08x\n", acpi_enable_flag ? "ENABLE" : "DISABLE",
rsdp_address); rsdp_address);
int index = 0; int index = 0;
print_proc_t(&index, get_current(), get_current()->next, 0); print_proc_t(&index, get_current(), get_current()->next, 0);
@ -213,7 +207,7 @@ void cmd_debug() {
void cmd_cd(int argc, char **argv) { void cmd_cd(int argc, char **argv) {
if (argc == 1) { if (argc == 1) {
vga_writestring("\033[Shell-CD]: If there are too few parameters, please specify the path.\036\n"); print("[Shell-CD]: If there are too few parameters, please specify the path.\n");
return; return;
} }
if (vfs_change_path(argv[1]) == 0) printf("Invalid path.\n"); if (vfs_change_path(argv[1]) == 0) printf("Invalid path.\n");
@ -235,7 +229,7 @@ void cmd_disk(int argc, char **argv) {
} }
if (strlen(argv[1]) > 1) { if (strlen(argv[1]) > 1) {
printf("\033[DISK]: Cannot found disk.\036\n"); printf("[DISK]: Cannot found disk.\n");
return; return;
} }
@ -253,7 +247,7 @@ void cmd_disk(int argc, char **argv) {
} }
} }
} }
printf("\033[DISK]: Cannot found disk.\036\n"); printf("[DISK]: Cannot found disk.\n");
return; return;
} }
printf("[Disk]: Loaded disk - "); printf("[Disk]: Loaded disk - ");
@ -291,9 +285,9 @@ char *user() {
void setup_shell() { void setup_shell() {
char *user1 = "default";//user(); char *user1 = "default";//user();
vga_clear(); screen_clear();
printf("%s for x86 [Version %s] \n", OS_NAME, OS_VERSION); printf("%s for x86 [Version %s] \n", OS_NAME, OS_VERSION);
printf("\032Copyright 2024 XIAOYI12 (Build by GCC i686-elf-tools)\036\n"); printf("Copyright 2024 XIAOYI12 (Build by GCC i686-elf-tools)\n");
char com[MAX_COMMAND_LEN]; char com[MAX_COMMAND_LEN];
char *argv[MAX_ARG_NR]; char *argv[MAX_ARG_NR];
@ -302,12 +296,12 @@ void setup_shell() {
while (1) { while (1) {
vfs_getPath(buffer); vfs_getPath(buffer);
printf("\035%s %s\\>\036 ", user1, buffer); printf("%s %s\\> ", user1, buffer);
if (gets(com, MAX_COMMAND_LEN) <= 0) continue; if (gets(com, MAX_COMMAND_LEN) <= 0) continue;
argc = cmd_parse(com, argv, ' '); argc = cmd_parse(com, argv, ' ');
if (argc == -1) { if (argc == -1) {
vga_writestring("[Shell]: Error: out of arguments buffer\n"); print("[Shell]: Error: out of arguments buffer\n");
continue; continue;
} }
@ -316,7 +310,7 @@ void setup_shell() {
else if (!strcmp("echo", argv[0])) else if (!strcmp("echo", argv[0]))
cmd_echo(argc, argv); cmd_echo(argc, argv);
else if (!strcmp("clear", argv[0])) else if (!strcmp("clear", argv[0]))
vga_clear(); screen_clear();
else if (!strcmp("proc", argv[0])) else if (!strcmp("proc", argv[0]))
cmd_proc(argc, argv); cmd_proc(argc, argv);
else if (!strcmp("sysinfo", argv[0])) else if (!strcmp("sysinfo", argv[0]))
@ -338,20 +332,20 @@ void setup_shell() {
else if (!strcmp("cd", argv[0])) else if (!strcmp("cd", argv[0]))
cmd_cd(argc, argv); cmd_cd(argc, argv);
else if (!strcmp("help", argv[0]) || !strcmp("?", argv[0]) || !strcmp("h", argv[0])) { else if (!strcmp("help", argv[0]) || !strcmp("?", argv[0]) || !strcmp("h", argv[0])) {
vga_writestring("-=[\037CoolPotShell Helper\036]=-\n"); print("-=[CoolPotShell Helper]=-\n");
vga_writestring("help ? h \032Print shell help info.\036\n"); print("help ? h Print shell help info.\n");
vga_writestring("version \032Print os version.\036\n"); print("version Print os version.\n");
vga_writestring("echo <msg> \032Print message.\036\n"); print("echo <msg> Print message.\n");
vga_writestring("ls \032List all files.\036\n"); print("ls List all files.\n");
vga_writestring("mkdir <name> \032Make a directory.\036\n"); print("mkdir <name> Make a directory.\n");
vga_writestring("del rm <name> \032Delete a file.\036\n"); print("del rm <name> Delete a file.\n");
vga_writestring("sysinfo \032Print system info.\036\n"); print("sysinfo Print system info.\n");
vga_writestring("proc [kill<pid>|list] \032Lists all running processes.\036\n"); print("proc [kill<pid>|list] Lists all running processes.\n");
vga_writestring("reset \032Reset OS.\036\n"); print("reset Reset OS.\n");
vga_writestring("shutdown exit \032Shutdown OS.\036\n"); print("shutdown exit Shutdown OS.\n");
vga_writestring("debug \032Print os debug info.\036\n"); print("debug Print os debug info.\n");
vga_writestring("disk [list|<ID>] \032List or view disks.\036\n"); print("disk [list|<ID>] List or view disks.\n");
vga_writestring("cd <path> \032Change shell top directory.\036\n"); print("cd <path> Change shell top directory.\n");
} else printf("\033[Shell]: Unknown command '%s'.\036\n", argv[0]); } else printf("\033[Shell]: Unknown command '%s'.\n", argv[0]);
} }
} }

View File

@ -5,6 +5,10 @@
static char num_str_buf[BUF_SIZE]; static char num_str_buf[BUF_SIZE];
uint32_t ALIGN_F(const uint32_t addr, const uint32_t _align) {
return (uint32_t)((addr + _align - 1) & (~(_align - 1)));
}
void insert_char(char *str, int pos, char ch) { void insert_char(char *str, int pos, char ch) {
int i; int i;
for (i = strlen(str); i >= pos; i--) { for (i = strlen(str); i >= pos; i--) {
@ -12,6 +16,7 @@ void insert_char(char* str, int pos, char ch) {
} }
str[pos] = ch; str[pos] = ch;
} }
void delete_char(char *str, int pos) { void delete_char(char *str, int pos) {
int i; int i;
for (i = pos; i < strlen(str); i++) { for (i = pos; i < strlen(str); i++) {

509
util/font.c Normal file
View File

@ -0,0 +1,509 @@
#include "../include/common.h"
uint8_t ascfont[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,
0x00, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00,
0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3c, 0x66, 0xc3, 0xc3, 0xdb, 0xdb, 0xc3, 0xc3, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xc3, 0xe7, 0xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00,
0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00,
0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00,
0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00,
0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00,
0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06, 0x3c, 0x00, 0x00, 0x00,
0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b, 0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00,
0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xc6, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00,
0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x18, 0x18, 0x7e, 0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0xfc, 0x66, 0x66, 0x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00, 0x00,
0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06, 0x0c, 0x1f, 0x00, 0x00,
0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00,
0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,
0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 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,
};
const uint8_t plfont[] =
{
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x10,0x10,0x00,0x00,
0x00,0x12,0x24,0x24,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x12,0x12,0x12,0x7e,0x24,0x24,0x24,0x7e,0x24,0x24,0x24,0x00,0x00,
0x00,0x00,0x08,0x3c,0x4a,0x4a,0x48,0x38,0x0c,0x0a,0x0a,0x4a,0x4a,0x3c,0x08,0x08,
0x00,0x00,0x00,0x44,0xa4,0xa8,0xa8,0xb0,0x54,0x1a,0x2a,0x2a,0x4a,0x44,0x00,0x00,
0x00,0x00,0x00,0x30,0x48,0x48,0x48,0x50,0x6e,0xa4,0x94,0x98,0x89,0x76,0x00,0x00,
0x00,0x60,0x20,0x20,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x02,0x04,0x08,0x08,0x10,0x10,0x10,0x10,0x10,0x10,0x08,0x08,0x04,0x02,0x00,
0x00,0x40,0x20,0x10,0x10,0x08,0x08,0x08,0x08,0x08,0x08,0x10,0x10,0x20,0x40,0x00,
0x00,0x00,0x00,0x00,0x10,0x10,0xd6,0x38,0x38,0xd6,0x10,0x10,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x08,0x08,0x08,0x7f,0x08,0x08,0x08,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x20,0x20,0x40,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,
0x00,0x00,0x02,0x04,0x04,0x04,0x08,0x08,0x10,0x10,0x10,0x20,0x20,0x40,0x40,0x00,
0x00,0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x24,0x18,0x00,0x00,
0x00,0x00,0x00,0x08,0x38,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x3e,0x00,0x00,
0x00,0x00,0x00,0x3c,0x42,0x42,0x42,0x02,0x04,0x08,0x10,0x20,0x42,0x7e,0x00,0x00,
0x00,0x00,0x00,0x3c,0x42,0x42,0x02,0x04,0x18,0x04,0x02,0x42,0x42,0x3c,0x00,0x00,
0x00,0x00,0x00,0x04,0x0c,0x0c,0x14,0x24,0x24,0x44,0x7f,0x04,0x04,0x1f,0x00,0x00,
0x00,0x00,0x00,0x7e,0x40,0x40,0x40,0x78,0x44,0x02,0x02,0x42,0x44,0x38,0x00,0x00,
0x00,0x00,0x00,0x18,0x24,0x40,0x40,0x5c,0x62,0x42,0x42,0x42,0x22,0x1c,0x00,0x00,
0x00,0x00,0x00,0x7e,0x42,0x04,0x04,0x08,0x08,0x10,0x10,0x10,0x10,0x10,0x00,0x00,
0x00,0x00,0x00,0x3c,0x42,0x42,0x42,0x24,0x18,0x24,0x42,0x42,0x42,0x3c,0x00,0x00,
0x00,0x00,0x00,0x38,0x44,0x42,0x42,0x42,0x46,0x3a,0x02,0x02,0x24,0x18,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x10,
0x00,0x00,0x00,0x02,0x04,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x04,0x02,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x7e,0x00,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x40,0x20,0x10,0x08,0x04,0x02,0x04,0x08,0x10,0x20,0x40,0x00,0x00,
0x00,0x00,0x00,0x3c,0x42,0x42,0x62,0x04,0x08,0x08,0x08,0x00,0x18,0x18,0x00,0x00,
0x00,0x00,0x00,0x38,0x44,0x5a,0xaa,0xaa,0xaa,0xaa,0xaa,0x5c,0x42,0x3c,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0xf8,0x44,0x44,0x44,0x78,0x44,0x42,0x42,0x42,0x44,0xf8,0x00,0x00,
0x00,0x00,0x00,0x3e,0x42,0x42,0x80,0x80,0x80,0x80,0x80,0x42,0x44,0x38,0x00,0x00,
0x00,0x00,0x00,0xf8,0x44,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x44,0xf8,0x00,0x00,
0x00,0x00,0x00,0xfc,0x42,0x48,0x48,0x78,0x48,0x48,0x40,0x42,0x42,0xfc,0x00,0x00,
0x00,0x00,0x00,0xfc,0x42,0x48,0x48,0x78,0x48,0x48,0x40,0x40,0x40,0xe0,0x00,0x00,
0x00,0x00,0x00,0x3c,0x44,0x44,0x80,0x80,0x80,0x8e,0x84,0x44,0x44,0x38,0x00,0x00,
0x00,0x00,0x00,0xe7,0x42,0x42,0x42,0x42,0x7e,0x42,0x42,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x7c,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x7c,0x00,0x00,
0x00,0x00,0x00,0x3e,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x88,0xf0,
0x00,0x00,0x00,0xee,0x44,0x48,0x50,0x70,0x50,0x48,0x48,0x44,0x44,0xee,0x00,0x00,
0x00,0x00,0x00,0xe0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x42,0xfe,0x00,0x00,
0x00,0x00,0x00,0xee,0x6c,0x6c,0x6c,0x6c,0x6c,0x54,0x54,0x54,0x54,0xd6,0x00,0x00,
0x00,0x00,0x00,0xc7,0x62,0x62,0x52,0x52,0x4a,0x4a,0x4a,0x46,0x46,0xe2,0x00,0x00,
0x00,0x00,0x00,0x38,0x44,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x44,0x38,0x00,0x00,
0x00,0x00,0x00,0xfc,0x42,0x42,0x42,0x42,0x7c,0x40,0x40,0x40,0x40,0xe0,0x00,0x00,
0x00,0x00,0x00,0x38,0x44,0x82,0x82,0x82,0x82,0x82,0x82,0xb2,0x4c,0x38,0x06,0x00,
0x00,0x00,0x00,0xfc,0x42,0x42,0x42,0x7c,0x48,0x48,0x44,0x44,0x42,0xe3,0x00,0x00,
0x00,0x00,0x00,0x3e,0x42,0x42,0x40,0x20,0x18,0x04,0x02,0x42,0x42,0x7c,0x00,0x00,
0x00,0x00,0x00,0xfe,0x92,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00,
0x00,0x00,0x00,0xe7,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x3c,0x00,0x00,
0x00,0x00,0x00,0xe7,0x42,0x42,0x44,0x24,0x24,0x28,0x28,0x18,0x10,0x10,0x00,0x00,
0x00,0x00,0x00,0xd6,0x54,0x54,0x54,0x54,0x54,0x6c,0x28,0x28,0x28,0x28,0x00,0x00,
0x00,0x00,0x00,0xe7,0x42,0x24,0x24,0x18,0x18,0x18,0x24,0x24,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0xee,0x44,0x44,0x28,0x28,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00,
0x00,0x00,0x00,0x7e,0x84,0x04,0x08,0x08,0x10,0x20,0x20,0x42,0x42,0xfc,0x00,0x00,
0x00,0x1e,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x1e,0x00,
0x00,0x00,0x40,0x20,0x20,0x20,0x10,0x10,0x10,0x08,0x08,0x04,0x04,0x04,0x02,0x02,
0x00,0x78,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x78,0x00,
0x00,0x18,0x24,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,0xff,
0x00,0x60,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x44,0x0c,0x34,0x44,0x4c,0x36,0x00,0x00,
0x00,0x00,0x00,0x00,0xc0,0x40,0x40,0x58,0x64,0x42,0x42,0x42,0x64,0x58,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1c,0x22,0x40,0x40,0x40,0x22,0x1c,0x00,0x00,
0x00,0x00,0x00,0x00,0x06,0x02,0x02,0x3e,0x42,0x42,0x42,0x42,0x46,0x3b,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x42,0x42,0x7e,0x40,0x42,0x3c,0x00,0x00,
0x00,0x00,0x00,0x00,0x0c,0x12,0x10,0x7c,0x10,0x10,0x10,0x10,0x10,0x7c,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x44,0x44,0x38,0x40,0x3c,0x42,0x42,0x3c,
0x00,0x00,0x00,0x00,0xc0,0x40,0x40,0x5c,0x62,0x42,0x42,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x7c,0x00,0x00,
0x00,0x00,0x00,0x0c,0x0c,0x00,0x00,0x1c,0x04,0x04,0x04,0x04,0x04,0x04,0x44,0x78,
0x00,0x00,0x00,0x00,0xc0,0x40,0x40,0x4e,0x48,0x50,0x70,0x48,0x44,0xee,0x00,0x00,
0x00,0x00,0x00,0x10,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x7c,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0x49,0x49,0x49,0x49,0x49,0xed,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xdc,0x62,0x42,0x42,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x42,0x42,0x42,0x42,0x42,0x3c,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd8,0x64,0x42,0x42,0x42,0x64,0x58,0x40,0xe0,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1a,0x26,0x42,0x42,0x42,0x26,0x1a,0x02,0x07,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xee,0x32,0x20,0x20,0x20,0x20,0xf8,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x42,0x40,0x3c,0x02,0x42,0x7c,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x7c,0x10,0x10,0x10,0x10,0x12,0x0c,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc6,0x42,0x42,0x42,0x42,0x46,0x3b,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xee,0x44,0x44,0x28,0x28,0x10,0x10,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xdb,0x89,0x4a,0x5a,0x54,0x24,0x24,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x76,0x24,0x18,0x18,0x18,0x24,0x6e,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe7,0x42,0x24,0x24,0x18,0x18,0x10,0x10,0x60,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7e,0x44,0x08,0x10,0x10,0x22,0x7e,0x00,0x00,
0x00,0x03,0x04,0x04,0x04,0x04,0x04,0x04,0x08,0x04,0x04,0x04,0x04,0x04,0x03,0x00,
0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
0x00,0xc0,0x20,0x20,0x20,0x20,0x20,0x20,0x10,0x20,0x20,0x20,0x20,0x20,0xc0,0x00,
0x20,0x5a,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3c,0x44,0x42,0x42,0xe7,0x00,0x00,
};

View File

@ -281,6 +281,8 @@ int sprintf(char *buf, const char *fmt, ...) {
return i; return i;
} }
extern bool vbe_status;
void printk(const char *formet, ...) { void printk(const char *formet, ...) {
int len; int len;
va_list ap; va_list ap;
@ -301,6 +303,20 @@ void printf(const char *formet, ...) {
va_end(ap); va_end(ap);
} }
void print(char *message) { void screen_clear(){
vga_writestring(message); if(vbe_status){
vbe_clear();
} else vga_clear();
}
void putchar(char c){
if(vbe_status){
vbe_putchar(c);
} else vga_putchar(c);
}
void print(char *message) {
if(vbe_status){
vbe_writestring(message);
} else vga_writestring(message);
} }