refactor mega-commit.

- reorganised the entire project so that the entire kernel is a single codebase rather than a kernel and a libk.
This commit is contained in:
2025-03-03 02:49:56 +00:00
parent 53d325749d
commit 3966e697da
57 changed files with 331 additions and 997 deletions
+1 -1
View File
@@ -5,5 +5,5 @@
"editor.defaultFormatter": "rust-lang.rust-analyzer", "editor.defaultFormatter": "rust-lang.rust-analyzer",
"editor.formatOnSave": true "editor.formatOnSave": true
}, },
"rust-analyzer.check.command": "clippy", "rust-analyzer.check.command": "clippy"
} }
Generated
+4 -15
View File
@@ -110,8 +110,11 @@ name = "foundry_os"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"cc", "cc",
"libk", "crossbeam",
"futures-util",
"libm",
"limine", "limine",
"linked_list_allocator",
"pc-keyboard", "pc-keyboard",
"pic8259", "pic8259",
"spin", "spin",
@@ -148,20 +151,6 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
[[package]]
name = "libk"
version = "0.1.0"
dependencies = [
"crossbeam",
"futures-util",
"libm",
"limine",
"linked_list_allocator",
"pc-keyboard",
"spin",
"x86_64",
]
[[package]] [[package]]
name = "libm" name = "libm"
version = "0.1.0" version = "0.1.0"
+1 -1
View File
@@ -1,5 +1,5 @@
[workspace] [workspace]
members = ["kernel", "libk", "libm"] members = ["kernel", "libm"]
resolver = "2" resolver = "2"
[workspace.package] [workspace.package]
+9 -1
View File
@@ -6,11 +6,19 @@ authors.workspace = true
[dependencies] [dependencies]
limine = "0.3.1" limine = "0.3.1"
libk = { path = "../libk" }
x86_64 = "0.15.2" x86_64 = "0.15.2"
spin = "0.9.8" spin = "0.9.8"
pic8259 = "0.11.0" pic8259 = "0.11.0"
pc-keyboard = "0.8.0" pc-keyboard = "0.8.0"
libm = { path = "../libm" }
crossbeam = { version = "0.8.4", default-features = false, features = [
"alloc",
"crossbeam-queue",
] }
futures-util = { version = "0.3.31", default-features = false, features = [
"alloc",
] }
linked_list_allocator = { version = "0.10.5", features = ["use_spin"] }
[build-dependencies] [build-dependencies]
cc = "1.2.14" cc = "1.2.14"
-26
View File
@@ -1,26 +0,0 @@
pub mod model_specific_registers {
use core::arch::x86_64::__cpuid;
use spin::Lazy;
use x86_64::registers::model_specific::Msr;
const CPUID_FLAG_MSR: u32 = 1 << 5;
static EDX: Lazy<u32> = Lazy::new(|| unsafe { __cpuid(1).edx });
pub fn cpu_has_msr() -> bool {
*EDX & CPUID_FLAG_MSR != 0
}
pub fn cpu_get_msr(msr: u32, value: &mut u64) {
let msr = Msr::new(msr);
unsafe {
*value = msr.read();
}
}
pub fn cpu_set_msr(msr: u32, value: u64) {
let mut msr = Msr::new(msr);
unsafe {
msr.write(value);
}
}
}
@@ -1,19 +1,14 @@
use core::arch::x86_64::__cpuid; use core::arch::x86_64::__cpuid;
use libk::drivers::memory::{FoundryOSFrameAllocator, FRAME_ALLOCATOR, OFFSET_PAGE_TABLE}; use crate::arch::x86_64::memory::memory_map::PHYSICAL_MEMORY_OFFSET;
use spin::Lazy; use crate::serial_print;
use x86_64::{ use x86_64::{
PhysAddr, VirtAddr, PhysAddr, VirtAddr,
instructions::port::Port, structures::paging::{Mapper, Page, PageTableFlags, PhysFrame, Size4KiB},
registers::model_specific::Msr,
structures::paging::{
FrameAllocator, Mapper, Page, PageTableFlags, PhysFrame, Size4KiB, Translate,
},
}; };
use crate::serial_print; use crate::arch::x86_64::cpu::msr::*;
use crate::arch::x86_64::memory::memory::{FRAME_ALLOCATOR, OFFSET_PAGE_TABLE};
use super::{cpu::model_specific_registers::*, memmap::PHYSICAL_MEMORY_OFFSET};
const IA32_APIC_BASE_MSR: u32 = 0x1b; const IA32_APIC_BASE_MSR: u32 = 0x1b;
const IA32_APIC_BASE_MSR_BSP: u64 = 0x100; const IA32_APIC_BASE_MSR_BSP: u64 = 0x100;
@@ -68,7 +63,8 @@ pub fn check_apic() -> bool {
#[inline(always)] #[inline(always)]
unsafe fn phys_to_virt(phys: PhysAddr) -> VirtAddr { unsafe fn phys_to_virt(phys: PhysAddr) -> VirtAddr {
let phys = phys.as_u64(); let phys = phys.as_u64();
phys.checked_add(*PHYSICAL_MEMORY_OFFSET).map_or_else(|| panic!(" overflow"), VirtAddr::new) phys.checked_add(*PHYSICAL_MEMORY_OFFSET)
.map_or_else(|| panic!(" overflow"), VirtAddr::new)
} }
pub fn enable_apic() { pub fn enable_apic() {
@@ -92,7 +88,7 @@ pub fn enable_apic() {
} }
// // FIXME: this causes a page fault // // FIXME: this causes a page fault
// // TODO: map to virtual memor // // TODO: map to virtual memory
let reg = read_apic_register(&apic_virt, 0xF0); let reg = read_apic_register(&apic_virt, 0xF0);
+3
View File
@@ -0,0 +1,3 @@
pub mod apic;
mod msr;
pub mod pic;
+24
View File
@@ -0,0 +1,24 @@
use core::arch::x86_64::__cpuid;
use spin::Lazy;
use x86_64::registers::model_specific::Msr;
const CPUID_FLAG_MSR: u32 = 1 << 5;
static EDX: Lazy<u32> = Lazy::new(|| unsafe { __cpuid(1).edx });
pub fn cpu_has_msr() -> bool {
*EDX & CPUID_FLAG_MSR != 0
}
pub fn cpu_get_msr(msr: u32, value: &mut u64) {
let msr = Msr::new(msr);
unsafe {
*value = msr.read();
}
}
pub fn cpu_set_msr(msr: u32, value: u64) {
let mut msr = Msr::new(msr);
unsafe {
msr.write(value);
}
}
@@ -40,6 +40,14 @@ pub struct ChainedPics {
} }
impl ChainedPics { impl ChainedPics {
/// Construct a new `ChainedPics` given the base offsets of the two PICs.
///
/// # Safety
///
/// This function is unsafe because it requires you to pass valid offsets.
/// If you pass offsets that are out of range, or if you pass offsets that
/// conflict with one another, the resulting object will be useless and
/// will likely cause problems for your system.
pub const unsafe fn new(offset1: u8, offset2: u8) -> Self { pub const unsafe fn new(offset1: u8, offset2: u8) -> Self {
ChainedPics { ChainedPics {
pics: [ pics: [
@@ -66,11 +74,11 @@ impl ChainedPics {
unsafe { Self::new(primary_offset, primary_offset + 8) } unsafe { Self::new(primary_offset, primary_offset + 8) }
} }
/// Returns the initialize of this [`ChainedPics`]. /// Returns a new instance of [`ChainedPics`].
/// ///
/// # Safety /// # Safety
/// ///
/// . /// this is unsafe because it required writing to CPU I/O ports.
pub unsafe fn initialize(&mut self) { pub unsafe fn initialize(&mut self) {
unsafe { unsafe {
let mut wait_port: Port<u8> = Port::new(0x80); let mut wait_port: Port<u8> = Port::new(0x80);
@@ -2,7 +2,7 @@ use core::fmt;
use spin::{Lazy, Mutex}; use spin::{Lazy, Mutex};
use x86_64::instructions::interrupts; use x86_64::instructions::interrupts;
use super::framebuffer::{colour::Colour, display::FRAMEBUFFER_WRITER}; use crate::arch::x86_64::drivers::framebuffer::{colour::Colour, display::FRAMEBUFFER_WRITER};
use crate::resources::font::{FONT_SPLEEN_8X16, Font}; use crate::resources::font::{FONT_SPLEEN_8X16, Font};
@@ -145,7 +145,7 @@ impl Writer {
} }
} }
impl core::fmt::Write for Writer { impl fmt::Write for Writer {
fn write_str(&mut self, s: &str) -> core::fmt::Result { fn write_str(&mut self, s: &str) -> core::fmt::Result {
self.write_string(s); self.write_string(s);
Ok(()) Ok(())
@@ -164,19 +164,19 @@ fn write(args: fmt::Arguments, fg: Colour, bg: Colour) {
} }
pub fn _print(args: fmt::Arguments) { pub fn _print(args: fmt::Arguments) {
x86_64::instructions::interrupts::without_interrupts(|| { interrupts::without_interrupts(|| {
write(args, Colour::White, Colour::Black); write(args, Colour::White, Colour::Black);
}) })
} }
pub fn _print_err(args: fmt::Arguments) { pub fn _print_err(args: fmt::Arguments) {
x86_64::instructions::interrupts::without_interrupts(|| { interrupts::without_interrupts(|| {
write(args, Colour::Red, Colour::Black); write(args, Colour::Red, Colour::Black);
}) })
} }
pub fn _print_log(args: fmt::Arguments) { pub fn _print_log(args: fmt::Arguments) {
x86_64::instructions::interrupts::without_interrupts(|| { interrupts::without_interrupts(|| {
write(args, Colour::Yellow, Colour::Black); write(args, Colour::Yellow, Colour::Black);
}) })
} }
@@ -209,7 +209,7 @@ macro_rules! println_log {
#[macro_export] #[macro_export]
macro_rules! print_log { macro_rules! print_log {
($($arg:tt)*) => ($crate::_print_log(format_args!($($arg)*))); ($($arg:tt)*) => ($crate::prelude::_print_log(format_args!($($arg)*)));
} }
#[macro_export] #[macro_export]
@@ -220,7 +220,7 @@ macro_rules! println {
#[macro_export] #[macro_export]
macro_rules! print { macro_rules! print {
($($arg:tt)*) => ($crate::_print(format_args!($($arg)*))); ($($arg:tt)*) => ($crate::prelude::_print(format_args!($($arg)*)));
} }
#[macro_export] #[macro_export]
@@ -231,5 +231,5 @@ macro_rules! printlnerr {
#[macro_export] #[macro_export]
macro_rules! printerr { macro_rules! printerr {
($($arg:tt)*) => ($crate::_print_err(format_args!($($arg)*))); ($($arg:tt)*) => ($crate::prelude::_print_err(format_args!($($arg)*)));
} }
@@ -3,16 +3,12 @@ use core::{
task::{Context, Poll}, task::{Context, Poll},
}; };
use crate::println;
use crossbeam::queue::ArrayQueue; use crossbeam::queue::ArrayQueue;
use futures_util::{Stream, StreamExt, task::AtomicWaker}; use futures_util::{Stream, StreamExt, task::AtomicWaker};
use pc_keyboard::{ use pc_keyboard::{DecodedKey, HandleControl, KeyCode, Keyboard, ScancodeSet1, layouts::Uk105Key};
DecodedKey, HandleControl, KeyCode, Keyboard, ScancodeSet1,
layouts::{self, Uk105Key},
};
use spin::{Lazy, Mutex, Once}; use spin::{Lazy, Mutex, Once};
use crate::prelude::*;
static KBD_QUEUE: Once<ArrayQueue<u8>> = Once::new(); static KBD_QUEUE: Once<ArrayQueue<u8>> = Once::new();
static WAKER: AtomicWaker = AtomicWaker::new(); static WAKER: AtomicWaker = AtomicWaker::new();
@@ -20,7 +16,7 @@ pub static KEYBOARD: Lazy<Mutex<Keyboard<Uk105Key, ScancodeSet1>>> = Lazy::new(|
Mutex::new(Keyboard::new( Mutex::new(Keyboard::new(
ScancodeSet1::new(), ScancodeSet1::new(),
// TODO: Expose an API to change the default KB layout. // TODO: Expose an API to change the default KB layout.
layouts::Uk105Key, Uk105Key,
HandleControl::Ignore, HandleControl::Ignore,
)) ))
}); });
+5
View File
@@ -0,0 +1,5 @@
pub mod ascii;
pub mod framebuffer;
pub mod keyboard;
pub mod port;
pub mod serial;
@@ -15,7 +15,7 @@ macro_rules! serial_println {
($($arg:tt)*) => (serial_print!("{}\n", format_args!($($arg)*))); ($($arg:tt)*) => (serial_print!("{}\n", format_args!($($arg)*)));
} }
use super::port::{inb, outb}; use crate::arch::x86_64::drivers::port::{inb, outb};
use x86_64::instructions::interrupts; use x86_64::instructions::interrupts;
+2 -2
View File
@@ -1,11 +1,11 @@
use x86_64::{ use x86_64::{
VirtAddr,
instructions::tables::load_tss, instructions::tables::load_tss,
registers::segmentation::{Segment, CS, DS, ES, SS}, registers::segmentation::{CS, DS, ES, SS, Segment},
structures::{ structures::{
gdt::{Descriptor, GlobalDescriptorTable, SegmentSelector}, gdt::{Descriptor, GlobalDescriptorTable, SegmentSelector},
tss::TaskStateSegment, tss::TaskStateSegment,
}, },
VirtAddr,
}; };
use spin::Lazy; use spin::Lazy;
+6 -6
View File
@@ -1,14 +1,14 @@
use libk::drivers::memory::{FRAME_ALLOCATOR, OFFSET_PAGE_TABLE}; use crate::serial_print;
use libk::prelude::*;
use pic8259::ChainedPics; use pic8259::ChainedPics;
use x86_64::registers::control::Cr2; use x86_64::registers::control::Cr2;
use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame, PageFaultErrorCode}; use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame, PageFaultErrorCode};
use x86_64::structures::paging::mapper::MapperFlushAll; use x86_64::structures::paging::mapper::MapperFlushAll;
use x86_64::structures::paging::{FrameAllocator, Mapper, Page, PageTableFlags, Size4KiB}; use x86_64::structures::paging::{FrameAllocator, Mapper, Page, PageTableFlags, Size4KiB};
use spin::{Lazy, Mutex};
use super::gdt; use super::gdt;
use crate::arch::x86_64::memory::memory::{FRAME_ALLOCATOR, OFFSET_PAGE_TABLE};
use crate::{println_log, serial_println};
use spin::{Lazy, Mutex};
static IDT: Lazy<InterruptDescriptorTable> = Lazy::new(|| { static IDT: Lazy<InterruptDescriptorTable> = Lazy::new(|| {
let mut idt = InterruptDescriptorTable::new(); let mut idt = InterruptDescriptorTable::new();
@@ -91,7 +91,7 @@ extern "x86-interrupt" fn double_fault_handler(
} }
extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: InterruptStackFrame) { extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: InterruptStackFrame) {
use pc_keyboard::{layouts, HandleControl, Keyboard, ScancodeSet1}; use pc_keyboard::{HandleControl, Keyboard, ScancodeSet1, layouts};
// use pc_keyboard::DecodedKey; // use pc_keyboard::DecodedKey;
use spin::Mutex; use spin::Mutex;
use x86_64::instructions::port::Port; use x86_64::instructions::port::Port;
@@ -108,7 +108,7 @@ extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: InterruptStac
let mut port = Port::new(0x60); let mut port = Port::new(0x60);
let scancode: u8 = unsafe { port.read() }; let scancode: u8 = unsafe { port.read() };
libk::drivers::io::keyboard::add_scancode(scancode); crate::arch::x86_64::drivers::keyboard::add_scancode(scancode);
unsafe { unsafe {
PICS.lock() PICS.lock()
@@ -1,8 +1,41 @@
use alloc::collections::LinkedList;
use core::alloc::{GlobalAlloc, Layout}; use core::alloc::{GlobalAlloc, Layout};
use core::{mem, ptr}; use core::ptr;
use core::ptr::NonNull; use spin::{Mutex, MutexGuard};
use crate::drivers::kalloc::allocator::Locked; use x86_64::structures::paging::{Size4KiB, mapper::MapToError};
/// We are currently using a linked list heap allocator which uses our underlying page allocator.
#[global_allocator]
/// This is now Rust's global allocator, so we can use stuff requiring heap allocations.
static ALLOCATOR: Locked<FoundryAllocator> = Locked::new(FoundryAllocator::new());
pub const HEAP_START: usize = 0x4444_4444_0000;
pub const HEAP_SIZE: usize = 1024 * 1024 * 1024;
/// Sets up the heap using the backing page frame allocator.
pub unsafe fn init_heap() -> Result<(), MapToError<Size4KiB>> {
unsafe {
// code to allocate frames is now done in the page fault interrupt handler!
ALLOCATOR.lock().init(HEAP_START, HEAP_SIZE);
Ok(())
}
}
pub struct Locked<T> {
inner: Mutex<T>,
}
impl<T> Locked<T> {
pub const fn new(inner: T) -> Self {
Locked {
inner: Mutex::new(inner),
}
}
pub fn lock(&self) -> MutexGuard<T> {
self.inner.lock()
}
}
const BLOCK_SIZES: &[usize] = &[8, 16, 32, 64, 128, 256, 512, 1024, 2048]; const BLOCK_SIZES: &[usize] = &[8, 16, 32, 64, 128, 256, 512, 1024, 2048];
struct ListNode { struct ListNode {
@@ -28,13 +61,15 @@ impl FoundryAllocator {
fallback: Locked::new(FoundryFallbackAllocator::new()), fallback: Locked::new(FoundryFallbackAllocator::new()),
} }
} }
pub unsafe fn init(&mut self, heap_start: usize, heap_size: usize) { unsafe { pub unsafe fn init(&mut self, heap_start: usize, heap_size: usize) {
self.fallback.lock().init(heap_start, heap_size); unsafe {
}} self.fallback.lock().init(heap_start, heap_size);
}
}
unsafe fn fallback_alloc(&mut self, layout: Layout) -> *mut u8 { unsafe { unsafe fn fallback_alloc(&mut self, layout: Layout) -> *mut u8 {
self.fallback.alloc(layout) unsafe { self.fallback.alloc(layout) }
}} }
fn block_size(&self, layout: &Layout) -> Option<usize> { fn block_size(&self, layout: &Layout) -> Option<usize> {
let required_block_size = layout.size().max(layout.align()); let required_block_size = layout.size().max(layout.align());
@@ -58,8 +93,7 @@ unsafe impl GlobalAlloc for Locked<FoundryAllocator> {
let block_size = BLOCK_SIZES[index]; let block_size = BLOCK_SIZES[index];
// only works if all block sizes are a power of 2 // only works if all block sizes are a power of 2
let block_align = block_size; let block_align = block_size;
let layout = Layout::from_size_align(block_size, block_align) let layout = Layout::from_size_align(block_size, block_align).unwrap();
.unwrap();
unsafe { allocator.fallback_alloc(layout) } unsafe { allocator.fallback_alloc(layout) }
} }
} }
@@ -68,7 +102,6 @@ unsafe impl GlobalAlloc for Locked<FoundryAllocator> {
} }
} }
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
let mut allocator = self.lock(); let mut allocator = self.lock();
match allocator.block_size(&layout) { match allocator.block_size(&layout) {
@@ -79,9 +112,9 @@ unsafe impl GlobalAlloc for Locked<FoundryAllocator> {
let new_ptr = ptr as *mut ListNode; let new_ptr = ptr as *mut ListNode;
unsafe { new_ptr.write(new_node) }; unsafe { new_ptr.write(new_node) };
allocator.list_heads[idx] = Some( unsafe { &mut *new_ptr }); allocator.list_heads[idx] = Some(unsafe { &mut *new_ptr });
} }
None => {; None => {
unsafe { allocator.fallback.dealloc(ptr, layout) }; unsafe { allocator.fallback.dealloc(ptr, layout) };
} }
} }
@@ -95,10 +128,7 @@ struct FallbackListNode {
impl FallbackListNode { impl FallbackListNode {
const fn new(size: usize) -> Self { const fn new(size: usize) -> Self {
Self { Self { size, next: None }
size,
next: None,
}
} }
fn start_addr(&self) -> usize { fn start_addr(&self) -> usize {
@@ -125,15 +155,21 @@ impl FoundryFallbackAllocator {
unsafe { self.add_region(heap_start, heap_size) }; unsafe { self.add_region(heap_start, heap_size) };
} }
unsafe fn add_region(&mut self, addr: usize, size: usize) { unsafe { unsafe fn add_region(&mut self, addr: usize, size: usize) {
let mut node = FallbackListNode::new(size); unsafe {
node.next = self.head.next.take(); let mut node = FallbackListNode::new(size);
let node_ptr = addr as *mut FallbackListNode; node.next = self.head.next.take();
node_ptr.write(node); let node_ptr = addr as *mut FallbackListNode;
self.head.next = Some(&mut *node_ptr); node_ptr.write(node);
}} self.head.next = Some(&mut *node_ptr);
}
}
fn find_region(&mut self, size: usize, align: usize) -> Option<(&'static mut FallbackListNode, usize)> { fn find_region(
&mut self,
size: usize,
align: usize,
) -> Option<(&'static mut FallbackListNode, usize)> {
let mut current = &mut self.head; let mut current = &mut self.head;
// look for a large enough memory region in linked list // look for a large enough memory region in linked list
while let Some(ref mut region) = current.next { while let Some(ref mut region) = current.next {
@@ -163,8 +199,11 @@ impl FoundryFallbackAllocator {
(size, layout.align()) (size, layout.align())
} }
fn alloc_from_region(region: &FallbackListNode, size: usize, align: usize) -> Result<usize, ()> fn alloc_from_region(
{ region: &FallbackListNode,
size: usize,
align: usize,
) -> Result<usize, ()> {
let alloc_start = Self::align_up(region.start_addr(), align); let alloc_start = Self::align_up(region.start_addr(), align);
let alloc_end = alloc_start.checked_add(size).ok_or(())?; let alloc_end = alloc_start.checked_add(size).ok_or(())?;
@@ -205,27 +244,6 @@ unsafe impl GlobalAlloc for Locked<FoundryFallbackAllocator> {
// perform layout adjustments // perform layout adjustments
let (size, _) = FoundryFallbackAllocator::size_align(layout); let (size, _) = FoundryFallbackAllocator::size_align(layout);
unsafe { unsafe { allocator.add_region(ptr as usize, size) }
allocator.add_region(ptr as usize, size)
}
} }
} }
@@ -0,0 +1 @@
@@ -2,12 +2,9 @@
use limine::{memory_map::EntryType, response::MemoryMapResponse}; use limine::{memory_map::EntryType, response::MemoryMapResponse};
use spin::{Mutex, Once}; use spin::{Mutex, Once};
use x86_64::{ use x86_64::{
registers::control::Cr3, structures::paging::{ PhysAddr, VirtAddr,
FrameAllocator, OffsetPageTable, PageTable, PhysFrame, Size4KiB registers::control::Cr3,
, structures::paging::{FrameAllocator, OffsetPageTable, PageTable, PhysFrame, Size4KiB},
},
PhysAddr,
VirtAddr,
}; };
pub static FRAME_ALLOCATOR: Once<Mutex<FoundryOSFrameAllocator>> = Once::new(); pub static FRAME_ALLOCATOR: Once<Mutex<FoundryOSFrameAllocator>> = Once::new();
+3
View File
@@ -0,0 +1,3 @@
pub mod allocation;
pub mod memory;
pub mod memory_map;
+5 -8
View File
@@ -1,9 +1,6 @@
pub mod gdt;
pub mod interrupts;
pub mod memmap;
pub mod apic;
pub mod cpu; pub mod cpu;
pub mod drivers;
pub mod gdt;
pub mod interrupts;
pub mod memory;
pub mod processing;
@@ -3,7 +3,8 @@
//! Written by @zxq5 for the most part with code from //! Written by @zxq5 for the most part with code from
//! [here](https://github.com/phil-opp/blog_os/). //! [here](https://github.com/phil-opp/blog_os/).
//! //!
use crate::prelude::*;
use alloc::boxed::Box;
use alloc::collections::BTreeMap; use alloc::collections::BTreeMap;
use alloc::sync::Arc; use alloc::sync::Arc;
use alloc::task::Wake; use alloc::task::Wake;
+2
View File
@@ -0,0 +1,2 @@
pub mod async_io;
pub mod threading;
@@ -1,3 +1,6 @@
mod switch;
mod deprecated;
use core::arch::asm; use core::arch::asm;
#[repr(C)] #[repr(C)]
@@ -68,43 +71,43 @@ impl ThreadContext {
let mut context = Self::default(); let mut context = Self::default();
unsafe { unsafe {
asm!( asm!(
"mov {0}, rax", "mov {0}, rax",
"mov {1}, rbx", "mov {1}, rbx",
"mov {2}, rcx", "mov {2}, rcx",
"mov {3}, rdx", "mov {3}, rdx",
"mov {4}, rsi", "mov {4}, rsi",
"mov {5}, rdi", "mov {5}, rdi",
"mov {6}, rbp", "mov {6}, rbp",
"mov {7}, rsp", "mov {7}, rsp",
"mov {8}, r8", "mov {8}, r8",
"mov {9}, r9", "mov {9}, r9",
"mov {10}, r10", "mov {10}, r10",
"mov {11}, r11", "mov {11}, r11",
"mov {12}, r12", "mov {12}, r12",
"mov {13}, r13", "mov {13}, r13",
"mov {14}, r14", "mov {14}, r14",
"mov {15}, r15", "mov {15}, r15",
"lea {16}, [rip]", "lea {16}, [rip]",
"pushf", "pushf",
"pop {17}", "pop {17}",
out(reg) context.rax, out(reg) context.rax,
out(reg) context.rbx, out(reg) context.rbx,
out(reg) context.rcx, out(reg) context.rcx,
out(reg) context.rdx, out(reg) context.rdx,
out(reg) context.rsi, out(reg) context.rsi,
out(reg) context.rdi, out(reg) context.rdi,
out(reg) context.rbp, out(reg) context.rbp,
out(reg) context.rsp, out(reg) context.rsp,
out(reg) context.r8, out(reg) context.r8,
out(reg) context.r9, out(reg) context.r9,
out(reg) context.r10, out(reg) context.r10,
out(reg) context.r11, out(reg) context.r11,
out(reg) context.r12, out(reg) context.r12,
out(reg) context.r13, out(reg) context.r13,
out(reg) context.r14, out(reg) context.r14,
out(reg) context.r15, out(reg) context.r15,
out(reg) context.rip, out(reg) context.rip,
out(reg) context.rflags, out(reg) context.rflags,
); );
} }
@@ -0,0 +1,45 @@
use x86_64::VirtAddr;
mod switch;
#[derive(Debug)]
pub struct Thread {
id: ThreadId,
stack_ptr: Option<VirtAddr>,
stack_bounds: Option<StackBounds>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct StackBounds {
start: VirtAddr,
end: VirtAddr,
}
impl StackBounds {
pub fn new(start: VirtAddr, end: VirtAddr) -> Self {
Self { start, end }
}
pub fn start(&self) -> VirtAddr {
self.start
}
pub fn end(&self) -> VirtAddr {
self.end
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct ThreadId(u64);
impl ThreadId {
pub fn as_u64(&self) -> u64 {
self.0
}
fn new() -> Self {
use core::sync::atomic::{AtomicU64, Ordering};
static NEXT_THREAD_ID: AtomicU64 = AtomicU64::new(1);
ThreadId(NEXT_THREAD_ID.fetch_add(1, Ordering::Relaxed))
}
}
@@ -0,0 +1 @@
+23 -19
View File
@@ -12,18 +12,26 @@
)] )]
extern crate alloc; extern crate alloc;
use crate::prelude::*;
use arch::x86_64::apic::enable_apic; use crate::arch::x86_64::memory::memory::{init_frame_allocator, init_page_table};
use arch::x86_64::memory::allocation::allocator::init_heap;
use arch::x86_64::memory::memory_map;
use core::arch::asm; use core::arch::asm;
use libk::drivers::memory;
use limine::BaseRevision; use limine::BaseRevision;
use libk::drivers::kalloc::allocator::init_heap;
use libk::prelude::*;
use x86_64::VirtAddr; use x86_64::VirtAddr;
mod arch; pub mod arch;
pub mod resources;
#[allow(unused)] // We aren't using much of this right now.
pub mod std;
pub mod util;
pub mod prelude {
pub use crate::std::io::{
_print, _print_log, _serial_write
};
pub use crate::{print, println, print_log, println_log, printerr, printlnerr, serial_print, serial_println};
}
/// Sets the base revision to the latest revision supported by the crate. /// Sets the base revision to the latest revision supported by the crate.
/// See specification for further info. /// See specification for further info.
@@ -45,10 +53,6 @@ pub fn hcf() -> ! {
unsafe { unsafe {
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
asm!("hlt"); asm!("hlt");
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
asm!("wfi");
#[cfg(target_arch = "loongarch64")]
asm!("idle 0");
} }
} }
} }
@@ -58,12 +62,12 @@ pub fn boot() -> Result<(), &'static str> {
return Err("base revision not supported"); return Err("base revision not supported");
} }
use arch::x86_64::{gdt, interrupts, memmap}; use arch::x86_64::{gdt, interrupts};
let memory_map = memmap::get_memory_map(); let memory_map = memory_map::get_memory_map();
print_log!(" Initialising Serial... "); print_log!(" Initialising Serial... ");
if libk::drivers::io::serial::init().is_err() { if arch::x86_64::drivers::serial::init().is_err() {
println_log!("[Not Detected]") println_log!("[Not Detected]")
} else { } else {
println_log!("[Success]"); println_log!("[Success]");
@@ -78,16 +82,16 @@ pub fn boot() -> Result<(), &'static str> {
println_log!("[Success]"); println_log!("[Success]");
print_log!(" Initialising Memory Subsystem... "); print_log!(" Initialising Memory Subsystem... ");
let physical_memory_offset = VirtAddr::new(*memmap::PHYSICAL_MEMORY_OFFSET); let physical_memory_offset = VirtAddr::new(*memory_map::PHYSICAL_MEMORY_OFFSET);
memory::init_page_table(physical_memory_offset); init_page_table(physical_memory_offset);
println_log!("[Success]"); println_log!("[Success]");
print_log!(" Setting Up Page Table... "); print_log!(" Setting Up Page Table... ");
memory::init_frame_allocator(memory_map); init_frame_allocator(memory_map);
println_log!("[Success]"); println_log!("[Success]");
print_log!(" Initialising Heap... "); print_log!(" Initialising Heap... ");
if init_heap().is_err() { if unsafe { init_heap() }.is_err() {
return Err("Failed to initialise heap: error"); return Err("Failed to initialise heap: error");
} }
println_log!("[Success]"); println_log!("[Success]");
+7 -13
View File
@@ -2,16 +2,11 @@
#![no_main] #![no_main]
extern crate alloc; extern crate alloc;
use foundry_os::arch::x86_64::drivers::ascii::screensize_chars;
use alloc::vec; use foundry_os::arch::x86_64::drivers::framebuffer::display::screensize_px;
use libk::{ use foundry_os::arch::x86_64::processing::async_io::task::{Executor, Task};
drivers::{ use foundry_os::util::shell::shell;
async_io::task::{Executor, Task}, use foundry_os::{println, println_log};
io::{self, framebuffer::colour::Colour},
},
prelude::*,
util::shell::shell,
};
#[unsafe(no_mangle)] #[unsafe(no_mangle)]
extern "C" fn kmain() -> ! { extern "C" fn kmain() -> ! {
@@ -22,8 +17,8 @@ extern "C" fn kmain() -> ! {
println_log!("[ Kernel Initialised Successfully ] "); println_log!("[ Kernel Initialised Successfully ] ");
let dimensions = io::ascii::screensize_chars(); let dimensions = screensize_chars();
let dimensions2 = io::framebuffer::display::screensize_px(); let dimensions2 = screensize_px();
println!("Dimensions: {}x{} (px)", dimensions2.0, dimensions2.1); println!("Dimensions: {}x{} (px)", dimensions2.0, dimensions2.1);
println!("Dimensions: {}x{} (chars)", dimensions.0, dimensions.1); println!("Dimensions: {}x{} (chars)", dimensions.0, dimensions.1);
@@ -34,7 +29,6 @@ extern "C" fn kmain() -> ! {
// println!("{}", somevec.len()); // println!("{}", somevec.len());
// println!("PASSED!"); // println!("PASSED!");
let mut executor = Executor::new(); let mut executor = Executor::new();
executor.spawn(Task::new(shell())); executor.spawn(Task::new(shell()));
executor.run(); executor.run();
@@ -1,11 +1,9 @@
use libm::include_font; use libm::include_font;
pub mod ibm_vga_8x16;
pub static FONT_SPLEEN_8X16: Font = pub static FONT_SPLEEN_8X16: Font =
Font::new(include_font!("./libk/resources/font/spleen-8x16.psf")); Font::new(include_font!("./kernel/resources/font/spleen-8x16.psf"));
pub static FONT_CP850_8X16: Font = Font::new(include_font!("./libk/resources/font/cp850-8x16.psf")); pub static FONT_CP850_8X16: Font =
Font::new(include_font!("./kernel/resources/font/cp850-8x16.psf"));
// pub struct Font(pub [[u8; 16]; 512]); // pub struct Font(pub [[u8; 16]; 512]);
@@ -42,7 +40,7 @@ impl Font {
self.height self.height
} }
pub const fn default() -> &'static Font { pub fn default() -> &'static Font {
&FONT_CP850_8X16 &FONT_CP850_8X16
} }
} }
@@ -1,4 +1,5 @@
use crate::prelude::*; use alloc::string::String;
use alloc::vec::Vec;
pub mod frame; pub mod frame;
pub mod render; pub mod render;
@@ -7,10 +8,7 @@ pub mod window;
pub trait Application { pub trait Application {
type Output; type Output;
fn run( async fn run(&mut self, args: Vec<String>) -> Result<Self::Output, Error>;
&mut self,
args: Vec<String>,
) -> impl core::future::Future<Output = Result<Self::Output, Error>> + Send;
} }
#[derive(Debug)] #[derive(Debug)]
@@ -1,9 +1,6 @@
use crate::{drivers::io::framebuffer::colour::Colour, std::maths::geometry::Vec2}; use super::{render::RenderError, window::Window};
use crate::arch::x86_64::drivers::framebuffer::colour::Colour;
use super::{ use crate::std::maths::geometry::Vec2;
render::{ColouredChar, RenderError},
window::{self, Window},
};
use alloc::{vec, vec::Vec}; use alloc::{vec, vec::Vec};
pub struct Frame<'f> { pub struct Frame<'f> {
@@ -1,7 +1,6 @@
use crate::arch::x86_64::drivers::framebuffer::colour::Colour;
use core::fmt::Display; use core::fmt::Display;
use crate::drivers::io::framebuffer::colour::Colour;
#[derive(Clone, Copy, Debug, PartialEq, Eq)] #[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum RenderError { pub enum RenderError {
Generic, Generic,
@@ -1,12 +1,8 @@
use limine::framebuffer;
use crate::{
drivers::io::framebuffer::{colour::Colour, display::FRAMEBUFFER_WRITER},
prelude::*,
std::maths::geometry::Vec2,
};
use super::render::RenderError; use super::render::RenderError;
use crate::arch::x86_64::drivers::framebuffer::colour::Colour;
use crate::arch::x86_64::drivers::framebuffer::display::FRAMEBUFFER_WRITER;
use crate::std::maths::geometry::Vec2;
use alloc::string::String;
pub struct Window { pub struct Window {
dimensions: Vec2<usize>, dimensions: Vec2<usize>,
@@ -1,9 +1,9 @@
use crate::{drivers::io::framebuffer::colour::Colour, resources::font::Font};
use super::{ use super::{
application::{frame::Frame, render::RenderError}, application::{frame::Frame, render::RenderError},
maths::geometry::Vec2, maths::geometry::Vec2,
}; };
use crate::arch::x86_64::drivers::framebuffer::colour::Colour;
use crate::resources::font::Font;
pub struct Writer<'a> { pub struct Writer<'a> {
font: &'a Font, font: &'a Font,
+6 -7
View File
@@ -1,17 +1,16 @@
pub use crate::drivers::io::{ pub use crate::arch::x86_64::drivers::{
ascii::{_print, _print_err, _print_log}, ascii::{_print, _print_err, _print_log},
print, print_log, printerr, println, println_log, printlnerr,
serial::_serial_write, serial::_serial_write,
serial_print, serial_println,
}; };
pub mod stdin { pub mod stdin {
use alloc::string::String; use crate::arch::x86_64::drivers::{
use crate::drivers::io::{
ascii::WRITER, ascii::WRITER,
keyboard::{KeyStroke, get_keystroke_async, get_keystroke_optional}, keyboard::{
get_keystroke_async, get_keystroke_optional, KeyStroke,
}
}; };
use alloc::string::String;
/// Reads a line of input from standard input asynchronously, returning a `String` containing /// Reads a line of input from standard input asynchronously, returning a `String` containing
/// the input line. Does not include the newline character at the end of the line. /// the input line. Does not include the newline character at the end of the line.
@@ -1,13 +1,16 @@
use crate::drivers::io::keyboard::{KeyStroke, get_keystroke_async}; use crate::serial_print;
use crate::arch::x86_64::drivers::keyboard::{KeyStroke, get_keystroke_async};
use crate::prelude::*; use crate::prelude::*;
use crate::resources::font::{FONT_CP850_8X16, FONT_SPLEEN_8X16, Font}; use crate::resources::font::Font;
use crate::std::application::frame::Frame; use crate::std::application::frame::Frame;
use crate::std::application::render::RenderError; use crate::std::application::render::RenderError;
use crate::std::application::window::Window; use crate::std::application::window::Window;
use crate::std::application::{Application, Error}; use crate::std::application::{Application, Error};
use crate::std::ascii::Writer; use crate::std::ascii::Writer;
use crate::std::maths::geometry::Vec2; use crate::std::maths::geometry::Vec2;
use alloc::string::ToString; use alloc::string::{String, ToString};
use alloc::vec::Vec;
use crate::serial_println;
pub struct Editor { pub struct Editor {
cursor_line: usize, cursor_line: usize,
@@ -70,15 +73,17 @@ impl<'a> Editor {
col += scale; col += scale;
} }
writer.render_glyph( writer
&mut frame, .render_glyph(
Vec2::new( &mut frame,
self.cursor_col * width + Self::PADDING, Vec2::new(
self.cursor_line * height + Self::PADDING, self.cursor_col * width + Self::PADDING,
), self.cursor_line * height + Self::PADDING,
b'_', ),
scale, b'_',
); scale,
)
.expect("TODO: panic message");
Ok(frame) Ok(frame)
} }
@@ -1,12 +1,12 @@
// use x86_64::registers::rflags::read; // use x86_64::registers::rflags::read;
use crate::arch::x86_64::drivers::ascii::clear_screen;
use crate::prelude::*;
use crate::std::application::Application;
use crate::std::io::stdin::read_line;
use crate::util::editor::Editor;
use alloc::vec::Vec; use alloc::vec::Vec;
use crate::{
drivers::io::ascii::clear_screen, prelude::stdin::read_line, print, println,
std::application::Application, util::editor::Editor,
};
static FETCH: &str = " static FETCH: &str = "
$$$$$$$$\\ $$\\ $$$$$$$$\\ $$\\
$$ _____| $$ | $$ _____| $$ |
-22
View File
@@ -1,22 +0,0 @@
[package]
name = "libk"
publish = ["gitea"]
version.workspace = true
edition.workspace = true
authors.workspace = true
description = "A library crate used to write the kernel for Foundry OS."
[dependencies]
limine = "0.3.1"
x86_64 = "0.15.2"
crossbeam = { version = "0.8.4", default-features = false, features = [
"alloc",
"crossbeam-queue",
] }
pc-keyboard = "0.8.0"
spin = "0.9.8"
futures-util = { version = "0.3.31", default-features = false, features = [
"alloc",
] }
linked_list_allocator = { version = "0.10.5", features = ["use_spin"] }
libm = { path = "../libm" }
-24
View File
@@ -1,24 +0,0 @@
# libk is for the code that did not make the kernel*
\*crate, lol.
libk is an attempt to move away from the godforsaken git submodules that plagued our forefathers. Now we have a crate containing a bunch of code that didn't quite make the core kernel crate, which should be:
* simpler to maintain
* has a catchier name
* less fighting with Cargo.toml manifests
## TODO:
A lot of things must be improved and worked on, feel free to add extra TODOs below.
- [] Create a kernel logging abstraction similar to Linux. (this should probably just use the serial drivers)
The rationale behind this is that we want some sort of debug log/tracing support so we aren't just printf debugging forever.
## Authors
Again, write your name below if you like:
* @zxq5 (wrote most of the libraries as of 23/02/25)
* @nullndvoid (made this lushious library crate)
-17
View File
@@ -1,17 +0,0 @@
pub mod ascii;
pub mod framebuffer;
pub mod keyboard;
pub mod port;
pub mod serial;
// Re-exported macro definitions.
pub use crate::print;
pub use crate::print_log;
pub use crate::printerr;
pub use crate::println;
pub use crate::println_log;
pub use crate::printlnerr;
pub use crate::serial_print;
pub use crate::serial_println;
-42
View File
@@ -1,42 +0,0 @@
use linked_list_allocator::LockedHeap;
use spin::{Mutex, MutexGuard};
use x86_64::structures::paging::{
mapper::MapToError,
Size4KiB,
};
use crate::drivers::kalloc::foundry_kalloc::FoundryAllocator;
/// We are currently using a linked list heap allocator which uses our underlying page allocator.
#[global_allocator]
/// This is now Rust's global allocator, so we can use stuff requiring heap allocations.
static ALLOCATOR: Locked<FoundryAllocator> = Locked::new(FoundryAllocator::new());
pub const HEAP_START: usize = 0x4444_4444_0000;
pub const HEAP_SIZE: usize = 1024 * 1024 * 1024;
/// Sets up the heap using the backing page frame allocator.
pub fn init_heap() -> Result<(), MapToError<Size4KiB>> {
// code to allocate frames is now done in the page fault interrupt handler!
unsafe {
ALLOCATOR.lock().init(HEAP_START, HEAP_SIZE);
}
Ok(())
}
pub struct Locked<T> {
inner: Mutex<T>,
}
impl<T> Locked<T> {
pub const fn new(inner: T) -> Self {
Locked {
inner: Mutex::new(inner)
}
}
pub fn lock(&self) -> MutexGuard<T> {
self.inner.lock()
}
}
-6
View File
@@ -1,6 +0,0 @@
pub mod io;
pub mod kalloc;
pub mod async_io;
pub mod memory;
pub mod pic;
-38
View File
@@ -1,38 +0,0 @@
#![no_std]
#![warn(
clippy::correctness,
clippy::nursery,
clippy::unnecessary_cast,
clippy::all,
clippy::suspicious,
clippy::perf,
rustdoc::missing_errors_doc,
rustdoc::missing_panics_doc,
tail_expr_drop_order
)]
extern crate alloc;
pub mod drivers;
pub mod resources;
pub mod threads;
pub mod util;
#[allow(unused)] // We aren't using much of this right now.
pub mod std;
/// Re-exports most of the IO macros as well as standard allocation stuff
#[allow(unused)]
pub mod prelude {
pub use crate::std::io::*;
pub use alloc::{
boxed::Box,
string::{String, ToString},
vec::Vec,
};
}
pub use crate::drivers::io::{
ascii::{_print, _print_log},
serial::_serial_write,
};
-578
View File
@@ -1,578 +0,0 @@
pub static FONT: [u8; 288 * 16] = [
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 0
0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00,
0x00, // 1
0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00,
0x00, // 2
0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00,
0x00, // 3
0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00,
0x00, // 4
0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
0x00, // 5
0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
0x00, // 6
0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
0x00, // 7
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 8
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, // 9
0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00,
0x00, // 10
0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff,
0xff, // 11
0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00,
0x00, // 12
0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00,
0x00, // 13
0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00,
0x00, // 14
0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00,
0x00, // 15
0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00,
0x00, // 16
0x00, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00,
0x00, // 17
0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, // 18
0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00,
0x00, // 19
0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00,
0x00, // 20
0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00,
0x00, // 21
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00,
0x00, // 22
0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00,
0x00, // 23
0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00,
0x00, // 24
0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00,
0x00, // 25
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 26
0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 27
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 28
0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x6c, 0xfe, 0x6c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 29
0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00,
0x00, // 30
0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
0x00, // 31
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 32
0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
0x00, // 33
0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 34
0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00,
0x00, // 35
0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00,
0x00, // 36
0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00,
0x00, // 37
0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
0x00, // 38
0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 39
0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00,
0x00, // 40
0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00,
0x00, // 41
0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 42
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 43
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00,
0x00, // 44
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 45
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
0x00, // 46
0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00,
0x00, // 47
0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xd6, 0xd6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00,
0x00, // 48
0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00,
0x00, // 49
0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00,
0x00, // 50
0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00,
0x00, // 51
0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00,
0x00, // 52
0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00,
0x00, // 53
0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
0x00, // 54
0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00,
0x00, // 55
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
0x00, // 56
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00,
0x00, // 57
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, // 58
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00,
0x00, // 59
0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00,
0x00, // 60
0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 61
0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00,
0x00, // 62
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
0x00, // 63
0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00,
0x00, // 64
0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00,
0x00, // 65
0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00,
0x00, // 66
0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00,
0x00, // 67
0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00,
0x00, // 68
0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00,
0x00, // 69
0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00,
0x00, // 70
0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00,
0x00, // 71
0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00,
0x00, // 72
0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
0x00, // 73
0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00,
0x00, // 74
0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00,
0x00, // 75
0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00,
0x00, // 76
0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00,
0x00, // 77
0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00,
0x00, // 78
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
0x00, // 79
0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00,
0x00, // 80
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00,
0x00, // 81
0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00,
0x00, // 82
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
0x00, // 83
0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
0x00, // 84
0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
0x00, // 85
0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00,
0x00, // 86
0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0xee, 0x6c, 0x00, 0x00, 0x00,
0x00, // 87
0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x7c, 0x38, 0x38, 0x7c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00,
0x00, // 88
0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
0x00, // 89
0x00, 0x00, 0xfe, 0xc6, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00,
0x00, // 90
0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00,
0x00, // 91
0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00,
0x00, // 92
0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00,
0x00, // 93
0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 94
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
0x00, // 95
0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 96
0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
0x00, // 97
0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00,
0x00, // 98
0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00,
0x00, // 99
0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
0x00, // 100
0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00,
0x00, // 101
0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00,
0x00, // 102
0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78,
0x00, // 103
0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00,
0x00, // 104
0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
0x00, // 105
0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c,
0x00, // 106
0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00,
0x00, // 107
0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
0x00, // 108
0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xd6, 0xc6, 0x00, 0x00, 0x00,
0x00, // 109
0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00,
0x00, // 110
0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
0x00, // 111
0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0,
0x00, // 112
0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e,
0x00, // 113
0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00,
0x00, // 114
0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00,
0x00, // 115
0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00,
0x00, // 116
0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
0x00, // 117
0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00,
0x00, // 118
0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00,
0x00, // 119
0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00,
0x00, // 120
0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8,
0x00, // 121
0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00,
0x00, // 122
0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00,
0x00, // 123
0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00,
0x00, // 124
0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00,
0x00, // 125
0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 126
0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
0x00, // 127
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 128
0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00,
0x00, // 129
0x00, 0x18, 0x18, 0x3c, 0x66, 0x60, 0x60, 0x60, 0x66, 0x3c, 0x18, 0x18, 0x00, 0x00, 0x00,
0x00, // 130
0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00,
0x00, // 131
0x00, 0x00, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00,
0x00, // 132
0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00,
0x00, // 133
0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 134
0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 135
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00,
0x00, // 136
0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 137
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
0x00, // 138
0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 139
0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00,
0x00, // 140
0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00,
0x00, // 141
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 142
0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 143
0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 144
0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xce, 0x9e, 0x3e, 0x06, 0x06, 0x00,
0x00, // 145
0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xdc, 0x86, 0x0c, 0x18, 0x3e, 0x00,
0x00, // 146
0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
0x00, // 147
0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00,
0x00, // 148
0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00,
0x00, // 149
0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00,
0x00, // 150
0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00,
0x00, // 151
0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00,
0x00, // 152
0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00,
0x00, // 153
0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
0x00, // 154
0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
0x00, // 155
0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, 0x00, 0x00, 0x00,
0x00, // 156
0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
0x00, // 157
0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
0x00, // 158
0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
0x00, // 159
0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
0x00, // 160
0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
0x00, // 161
0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x76, 0x36, 0x7e, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00,
0x00, // 162
0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06, 0x3c, 0x00, 0x00,
0x00, // 163
0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00,
0x00, // 164
0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00,
0x00, // 165
0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00,
0x00, // 166
0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00,
0x00, // 167
0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
0x00, // 168
0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
0x00, // 169
0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
0x00, // 170
0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
0x00, // 171
0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00,
0x00, // 172
0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
0x00, // 173
0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
0x00, // 174
0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
0x00, // 175
0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
0x00, // 176
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, // 177
0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
0x00, // 178
0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
0x00, // 179
0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
0x00, // 180
0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
0x00, // 181
0x00, 0x00, 0xc6, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78,
0x00, // 182
0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00,
0x00, // 183
0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00,
0x00, // 184
0x00, 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00,
0x00, // 185
0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00,
0x00, // 186
0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00,
0x00, // 187
0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00,
0x00, // 188
0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00,
0x00, // 189
0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00,
0x00, // 190
0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00,
0x00, // 191
0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00,
0x00, // 192
0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00,
0x00, // 193
0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00,
0x00, // 194
0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, 0x00, 0x00, 0x00,
0x00, // 195
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 196
0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00,
0x00, // 197
0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 198
0x00, 0xf8, 0xcc, 0xcc, 0xf8, 0xc4, 0xcc, 0xde, 0xcc, 0xcc, 0xcc, 0xc6, 0x00, 0x00, 0x00,
0x00, // 199
0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 200
0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00,
0x00, // 201
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 202
0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00,
0x00, // 203
0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x6c, 0xfe, 0x6c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 204
0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, // 205
0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00,
0x00, // 206
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 207
0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00,
0x00, // 208
0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 209
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 210
0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00,
0x00, // 211
0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 212
0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00,
0x00, // 213
0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00,
0x00, // 214
0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00,
0x00, // 215
0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
0x00, // 216
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00,
0x00, // 217
0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, // 218
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00,
0x00, // 219
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 220
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, // 221
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, // 222
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, // 223
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 224
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 225
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, // 226
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, // 227
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, // 228
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 229
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, // 230
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 231
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, // 232
0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, // 233
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, // 234
0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, // 235
0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, // 236
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, // 237
0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, // 238
0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 239
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 240
0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 241
0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 242
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 243
0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 244
0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, // 245
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, // 246
0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, // 247
0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, // 248
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, // 249
0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, // 250
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, // 251
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, // 252
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, // 253
0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 254
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 255
0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 256
0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, // 257
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, // 258
0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, // 259
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // 260
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, // 261
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, // 262
0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
0xf0, // 263
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
0x0f, // 264
0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11,
0x44, // 265
0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55,
0xaa, // 266
0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd,
0x77, // 267
0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, // 268
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00,
0x00, // 269
0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00,
0x00, // 270
0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00,
0x00, // 271
0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
0x00, // 272
0x00, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00,
0x00, // 273
0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00,
0x00, // 274
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, // 275
0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff,
0xff, // 276
0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00,
0x00, // 277
0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00,
0x00, // 278
0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00,
0x00, // 279
0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00,
0x00, // 280
0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00,
0x00, // 281
0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
0x00, // 282
0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
0x00, // 283
0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00,
0x00, // 284
0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
0x00, // 285
0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00,
0x00, // 286
0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00,
0x00, // 287
];