Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 914cb4e409 | |||
| 43b1db41ca | |||
| c763f512f1 | |||
| 5dc73e7000 | |||
| ca906767db | |||
| ef8d028211 | |||
| 2886fe5ecf | |||
| c2c552ef25 | |||
| e722874cee | |||
| 27b0ed634c |
+13
-2
@@ -9,5 +9,16 @@ build-std-features = ["compiler-builtins-mem"]
|
||||
[env]
|
||||
RUST_TARGET_PATH = { value = "kernel", relative = true }
|
||||
|
||||
[target.x86_64-kernel]
|
||||
runner = "scripts/run.sh"
|
||||
# Run in debug mode.
|
||||
[target.'cfg(all(target_arch = "x86_64", target_os = "none", debug_assertions))']
|
||||
runner = "scripts/run_debug.sh"
|
||||
|
||||
# Otherwise we run in release mode.
|
||||
[target.'cfg(all(target_arch = "x86_64", target_os = "none", not(debug_assertions)))']
|
||||
runner = "scripts/run_release.sh"
|
||||
|
||||
# [registry]
|
||||
# default = "gitea"
|
||||
|
||||
[registries.gitea]
|
||||
index = "sparse+https://git.zxq5.dev/api/packages/OsDev/cargo/" # Sparse index
|
||||
|
||||
-15
@@ -1,15 +0,0 @@
|
||||
[submodule "lib/lib_application"]
|
||||
path = lib/lib_application
|
||||
url = https://git.zxq5.dev/OsDev/FoundryOS-lib_application.git
|
||||
[submodule "lib/lib_ascii"]
|
||||
path = lib/lib_ascii
|
||||
url = https://git.zxq5.dev/OsDev/FoundryOS-lib_ascii.git
|
||||
[submodule "lib/lib_framebuffer"]
|
||||
path = lib/lib_framebuffer
|
||||
url = https://git.zxq5.dev/OsDev/FoundryOS-lib_framebuffer.git
|
||||
[submodule "lib/lib_serial"]
|
||||
path = lib/lib_serial
|
||||
url = https://git.zxq5.dev/OsDev/FoundryOS-lib_serial.git
|
||||
[submodule "lib/lib_alloc"]
|
||||
path = lib/lib_alloc
|
||||
url = https://git.zxq5.dev/OsDev/FoundryOS-lib_alloc.git
|
||||
Generated
+74
-44
@@ -22,22 +22,54 @@ checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.14"
|
||||
version = "1.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c3d1b2e905a3a7b00a6141adb0e4c0bb941d11caf55349d863942a1cc44e3c9"
|
||||
checksum = "c736e259eea577f443d5c86c304f9f4ae0295c43f3ba05c21f1d66b5f06001af"
|
||||
dependencies = [
|
||||
"shlex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1137cd7e7fc0fb5d3c5a8678be38ec56e819125d8d7907411fe24ccb943faca8"
|
||||
dependencies = [
|
||||
"crossbeam-epoch",
|
||||
"crossbeam-queue",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-queue"
|
||||
version = "0.3.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
|
||||
|
||||
[[package]]
|
||||
name = "foundry_os"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"lib_alloc",
|
||||
"lib_ascii",
|
||||
"lib_framebuffer",
|
||||
"lib_serial",
|
||||
"libk",
|
||||
"limine",
|
||||
"pc-keyboard",
|
||||
"pic8259",
|
||||
@@ -46,52 +78,38 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.5.0"
|
||||
name = "futures-core"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
|
||||
dependencies = [
|
||||
"spin",
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
"pin-project-lite",
|
||||
"pin-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lib_alloc"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"linked_list_allocator",
|
||||
"x86_64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lib_application"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"lib_ascii",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lib_ascii"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"lib_framebuffer",
|
||||
"spin",
|
||||
"x86_64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lib_framebuffer"
|
||||
name = "libk"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"crossbeam",
|
||||
"futures-util",
|
||||
"limine",
|
||||
"spin",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lib_serial"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"linked_list_allocator",
|
||||
"pc-keyboard",
|
||||
"spin",
|
||||
"x86_64",
|
||||
]
|
||||
@@ -139,6 +157,18 @@ dependencies = [
|
||||
"x86_64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
|
||||
|
||||
[[package]]
|
||||
name = "pin-utils"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.19"
|
||||
|
||||
+2
-8
@@ -1,17 +1,11 @@
|
||||
[workspace]
|
||||
members = [
|
||||
"lib/lib_framebuffer",
|
||||
"lib/lib_serial",
|
||||
"lib/lib_ascii",
|
||||
"kernel",
|
||||
"lib/lib_application",
|
||||
"lib/lib_alloc",
|
||||
]
|
||||
members = ["kernel", "libk"]
|
||||
resolver = "2"
|
||||
|
||||
[workspace.package]
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
authors = ["The Foundry OS contributors"]
|
||||
|
||||
[profile.dev]
|
||||
opt-level = "z"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#usage
|
||||
# Usage
|
||||
### Requirements
|
||||
- Latest rust nightly release
|
||||
> rustup update
|
||||
|
||||
+1
-4
@@ -5,10 +5,7 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
limine = "0.3.1"
|
||||
lib_framebuffer = { path = "../lib/lib_framebuffer" }
|
||||
lib_serial = { path = "../lib/lib_serial" }
|
||||
lib_ascii = { path = "../lib/lib_ascii" }
|
||||
lib_alloc = { path = "../lib/lib_alloc" }
|
||||
libk = { path = "../libk" }
|
||||
x86_64 = "0.15.2"
|
||||
spin = "0.9.8"
|
||||
pic8259 = "0.11.0"
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
use cc;
|
||||
use std::process::Command;
|
||||
use std::{env, path::Path};
|
||||
|
||||
fn main() {
|
||||
// Tell cargo to rerun if these files change
|
||||
println!("cargo:rerun-if-changed=src");
|
||||
|
||||
@@ -19,8 +19,8 @@ static TSS: Lazy<TaskStateSegment> = Lazy::new(|| {
|
||||
static mut STACK: [u8; STACK_SIZE] = [0; STACK_SIZE];
|
||||
|
||||
let stack_start = VirtAddr::from_ptr(&raw const STACK);
|
||||
let stack_end = stack_start + STACK_SIZE.try_into().unwrap();
|
||||
stack_end
|
||||
|
||||
stack_start + STACK_SIZE.try_into().unwrap()
|
||||
};
|
||||
tss
|
||||
});
|
||||
@@ -40,8 +40,8 @@ static GDT: Lazy<(GlobalDescriptorTable, Selectors)> = Lazy::new(|| {
|
||||
Selectors {
|
||||
code_selector,
|
||||
data_selector,
|
||||
user_code_selector,
|
||||
user_data_selector,
|
||||
_user_code_selector: user_code_selector,
|
||||
_user_data_selector: user_data_selector,
|
||||
tss_selector,
|
||||
},
|
||||
)
|
||||
@@ -50,8 +50,8 @@ static GDT: Lazy<(GlobalDescriptorTable, Selectors)> = Lazy::new(|| {
|
||||
struct Selectors {
|
||||
code_selector: SegmentSelector,
|
||||
data_selector: SegmentSelector,
|
||||
user_code_selector: SegmentSelector,
|
||||
user_data_selector: SegmentSelector,
|
||||
_user_code_selector: SegmentSelector,
|
||||
_user_data_selector: SegmentSelector,
|
||||
tss_selector: SegmentSelector,
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
use lib_ascii::{print, println_log};
|
||||
use lib_serial::serial_println;
|
||||
use x86_64::instructions::port::Port;
|
||||
use libk::prelude::*;
|
||||
use x86_64::registers::control::Cr2;
|
||||
use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame, PageFaultErrorCode};
|
||||
|
||||
@@ -81,30 +79,24 @@ extern "x86-interrupt" fn double_fault_handler(
|
||||
}
|
||||
|
||||
extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: InterruptStackFrame) {
|
||||
use pc_keyboard::{layouts, DecodedKey, HandleControl, Keyboard, ScancodeSet1};
|
||||
use pc_keyboard::{layouts, HandleControl, Keyboard, ScancodeSet1};
|
||||
// use pc_keyboard::DecodedKey;
|
||||
use spin::Mutex;
|
||||
use x86_64::instructions::port::Port;
|
||||
|
||||
static KEYBOARD: Lazy<Mutex<Keyboard<layouts::Us104Key, ScancodeSet1>>> = Lazy::new(|| {
|
||||
static KEYBOARD: Lazy<Mutex<Keyboard<layouts::Uk105Key, ScancodeSet1>>> = Lazy::new(|| {
|
||||
Mutex::new(Keyboard::new(
|
||||
ScancodeSet1::new(),
|
||||
layouts::Us104Key,
|
||||
layouts::Uk105Key,
|
||||
HandleControl::Ignore,
|
||||
))
|
||||
});
|
||||
|
||||
let mut keyboard = KEYBOARD.lock();
|
||||
let _keyboard = KEYBOARD.lock();
|
||||
let mut port = Port::new(0x60);
|
||||
|
||||
let scancode: u8 = unsafe { port.read() };
|
||||
if let Ok(Some(key_event)) = keyboard.add_byte(scancode) {
|
||||
if let Some(key) = keyboard.process_keyevent(key_event) {
|
||||
match key {
|
||||
DecodedKey::Unicode(character) => print!("{}", character),
|
||||
DecodedKey::RawKey(key) => print!("{:?}", key),
|
||||
}
|
||||
}
|
||||
}
|
||||
libk::io::keyboard::add_scancode(scancode);
|
||||
|
||||
unsafe {
|
||||
PICS.lock()
|
||||
|
||||
@@ -35,7 +35,7 @@ static KERNEL_ADDRESS_REQUEST: KernelAddressRequest = KernelAddressRequest::new(
|
||||
/// ```
|
||||
///
|
||||
/// Returns (virtual_base, physical_base)
|
||||
pub static KERNEL_PHYSICAL_MEMORY_OFFSET: Lazy<(u64, u64)> = Lazy::new(|| {
|
||||
pub static _KERNEL_PHYSICAL_MEMORY_OFFSET: Lazy<(u64, u64)> = Lazy::new(|| {
|
||||
let resp = KERNEL_ADDRESS_REQUEST.get_response().unwrap();
|
||||
|
||||
// These are base addresses, using Limine's built in page table.
|
||||
@@ -49,7 +49,7 @@ pub static KERNEL_PHYSICAL_MEMORY_OFFSET: Lazy<(u64, u64)> = Lazy::new(|| {
|
||||
/// Panics if the memory map was not found in MEMORY_MAP_REQUEST.
|
||||
pub fn get_memory_map() -> &'static MemoryMapResponse {
|
||||
if let Some(memory_map) = MEMORY_MAP_REQUEST.get_response() {
|
||||
return memory_map;
|
||||
memory_map
|
||||
} else {
|
||||
unreachable!("Could not fetch memory map from Limine.")
|
||||
}
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
use lib_alloc::allocator::FoundryAllocator;
|
||||
// use lib_alloc::allocator::FoundryAllocator;
|
||||
use limine::{memory_map::EntryType, response::MemoryMapResponse};
|
||||
use x86_64::{
|
||||
addr,
|
||||
// addr,
|
||||
registers::control::Cr3,
|
||||
structures::paging::{
|
||||
page_table::FrameError, FrameAllocator, OffsetPageTable, PageTable, PhysFrame, Size4KiB,
|
||||
// page_table::FrameError,
|
||||
FrameAllocator,
|
||||
OffsetPageTable,
|
||||
PageTable,
|
||||
PhysFrame,
|
||||
Size4KiB,
|
||||
},
|
||||
PhysAddr, VirtAddr,
|
||||
PhysAddr,
|
||||
VirtAddr,
|
||||
};
|
||||
|
||||
/// Returns a mutable reference to the current level 4 page table.
|
||||
@@ -93,7 +99,6 @@ unsafe impl FrameAllocator<Size4KiB> for FoundryOSFrameAllocator {
|
||||
///
|
||||
/// - `Some(PhysFrame)`: If a usable frame is available.
|
||||
/// - `None`: If there are no more usable frames to allocate.
|
||||
|
||||
fn allocate_frame(&mut self) -> Option<PhysFrame> {
|
||||
let frame = self.usable_frames().nth(self.next);
|
||||
self.next += 1;
|
||||
|
||||
+7
-17
@@ -4,14 +4,12 @@
|
||||
extern crate alloc;
|
||||
|
||||
use core::arch::asm;
|
||||
use lib_alloc::allocator::init_heap;
|
||||
use limine::request::{RequestsEndMarker, RequestsStartMarker};
|
||||
use limine::BaseRevision;
|
||||
|
||||
pub use lib_ascii::{print, print_log, println, println_log, WRITER};
|
||||
pub use lib_serial::{serial_print, serial_println, serial_read};
|
||||
use x86_64::structures::paging::Translate;
|
||||
use x86_64::{PhysAddr, VirtAddr};
|
||||
use libk::alloc::init_heap;
|
||||
use libk::prelude::*;
|
||||
|
||||
use x86_64::VirtAddr;
|
||||
|
||||
mod arch;
|
||||
|
||||
@@ -23,14 +21,6 @@ mod arch;
|
||||
#[link_section = ".requests"]
|
||||
static BASE_REVISION: BaseRevision = BaseRevision::new();
|
||||
|
||||
/// Define the stand and end markers for Limine requests.
|
||||
#[used]
|
||||
#[link_section = ".requests_start_marker"]
|
||||
static _START_MARKER: RequestsStartMarker = RequestsStartMarker::new();
|
||||
#[used]
|
||||
#[link_section = ".requests_end_marker"]
|
||||
static _END_MARKER: RequestsEndMarker = RequestsEndMarker::new();
|
||||
|
||||
#[panic_handler]
|
||||
fn rust_panic(_info: &core::panic::PanicInfo) -> ! {
|
||||
println!("Kernel panic: {}", _info);
|
||||
@@ -61,7 +51,7 @@ pub fn boot() -> Result<(), &'static str> {
|
||||
let memory_map = memmap::get_memory_map();
|
||||
|
||||
print_log!(" Initialising Serial... ");
|
||||
lib_serial::init()?;
|
||||
libk::io::serial::init()?;
|
||||
println_log!("[Success]");
|
||||
|
||||
print_log!(" Setting Up Global Descriptor Table... ");
|
||||
@@ -82,8 +72,8 @@ pub fn boot() -> Result<(), &'static str> {
|
||||
println_log!("[Success]");
|
||||
|
||||
print_log!(" Initialising Heap... ");
|
||||
if let Err(e) = init_heap(&mut l4_table, &mut frame_allocator) {
|
||||
return Err("Failed to initialise heap");
|
||||
if init_heap(&mut l4_table, &mut frame_allocator).is_err() {
|
||||
return Err("Failed to initialise heap: error");
|
||||
}
|
||||
println_log!("[Success]");
|
||||
|
||||
|
||||
+12
-9
@@ -3,15 +3,14 @@
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
use alloc::vec::Vec;
|
||||
|
||||
use foundry_os::{println, println_log};
|
||||
use libk::{
|
||||
io,
|
||||
prelude::*,
|
||||
scheduling::task::{Executor, Task},
|
||||
};
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn kmain() -> ! {
|
||||
// All limine requests must also be referenced in a called function, otherwise they may be
|
||||
// removed by the linker.
|
||||
|
||||
extern "C" fn kmain() -> ! {
|
||||
println_log!(" [ Initialising Kernel Systems ] ");
|
||||
if let Err(err) = foundry_os::boot() {
|
||||
panic!("{}", err);
|
||||
@@ -19,8 +18,8 @@ unsafe extern "C" fn kmain() -> ! {
|
||||
|
||||
println_log!("[ Kernel Initialised Successfully ] ");
|
||||
|
||||
let dimensions = lib_ascii::screensize_chars();
|
||||
let dimensions2 = lib_framebuffer::screensize_px();
|
||||
let dimensions = io::ascii::screensize_chars();
|
||||
let dimensions2 = io::ascii::screensize_px();
|
||||
|
||||
println!("Dimensions: {}x{} (px)", dimensions2.0, dimensions2.1);
|
||||
println!("Dimensions: {}x{} (chars)", dimensions.0, dimensions.1);
|
||||
@@ -46,5 +45,9 @@ unsafe extern "C" fn kmain() -> ! {
|
||||
"
|
||||
);
|
||||
|
||||
let mut executor = Executor::new();
|
||||
executor.spawn(Task::new(io::keyboard::print_keypresses()));
|
||||
executor.try_run();
|
||||
|
||||
loop {}
|
||||
}
|
||||
|
||||
Submodule lib/lib_alloc deleted from af814bf2ab
Submodule lib/lib_application deleted from 4b1c60676a
Submodule lib/lib_ascii deleted from 70d528b2e8
Submodule lib/lib_framebuffer deleted from 53553278d1
Submodule lib/lib_serial deleted from ed2fa6b501
@@ -0,0 +1,21 @@
|
||||
[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 = "0.10.5"
|
||||
@@ -0,0 +1,24 @@
|
||||
# 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)
|
||||
@@ -0,0 +1,3 @@
|
||||
pub mod allocator;
|
||||
|
||||
pub use self::allocator::init_heap;
|
||||
@@ -0,0 +1,45 @@
|
||||
use linked_list_allocator::LockedHeap;
|
||||
use x86_64::{
|
||||
structures::paging::{
|
||||
mapper::MapToError, FrameAllocator, Mapper, Page, PageTableFlags, Size4KiB,
|
||||
},
|
||||
VirtAddr,
|
||||
};
|
||||
|
||||
/// We are currently using a linked list heap allocator which uses our underlying page allocator.
|
||||
pub type FoundryAllocator = LockedHeap;
|
||||
|
||||
#[global_allocator]
|
||||
/// This is now Rust's global allocator, so we can use stuff requiring heap allocations.
|
||||
static ALLOCATOR: FoundryAllocator = FoundryAllocator::empty();
|
||||
|
||||
pub const HEAP_START: usize = 0x4444_4444_0000;
|
||||
pub const HEAP_SIZE: usize = 1000 * 1024;
|
||||
|
||||
/// Sets up the heap using the backing page frame allocator.
|
||||
pub fn init_heap(
|
||||
mapper: &mut impl Mapper<Size4KiB>,
|
||||
frame_allocator: &mut impl FrameAllocator<Size4KiB>,
|
||||
) -> Result<(), MapToError<Size4KiB>> {
|
||||
let range = {
|
||||
let heap_start = VirtAddr::new(HEAP_START as u64);
|
||||
let heap_end = heap_start + HEAP_SIZE as u64 - 1u64;
|
||||
let heap_start_page = Page::<Size4KiB>::containing_address(heap_start);
|
||||
let heap_end_page = Page::<Size4KiB>::containing_address(heap_end);
|
||||
Page::range_inclusive(heap_start_page, heap_end_page)
|
||||
};
|
||||
|
||||
for page in range {
|
||||
let frame = frame_allocator
|
||||
.allocate_frame()
|
||||
.ok_or(MapToError::FrameAllocationFailed)?;
|
||||
let flags = PageTableFlags::PRESENT | PageTableFlags::WRITABLE;
|
||||
unsafe { mapper.map_to(page, frame, flags, frame_allocator)?.flush() };
|
||||
}
|
||||
|
||||
unsafe {
|
||||
ALLOCATOR.lock().init(HEAP_START as *mut u8, HEAP_SIZE);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
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;
|
||||
@@ -0,0 +1,210 @@
|
||||
use core::fmt;
|
||||
use spin::{Lazy, Mutex};
|
||||
use x86_64::instructions::interrupts;
|
||||
|
||||
pub use super::framebuffer::screensize_px;
|
||||
use super::framebuffer::{Color, FRAMEBUFFER_WRITER};
|
||||
|
||||
mod font;
|
||||
use font::FONT;
|
||||
|
||||
static FONT_WIDTH: u32 = 8;
|
||||
static FONT_HEIGHT: u32 = 16;
|
||||
|
||||
pub static WRITER: Lazy<Mutex<Writer>> = Lazy::new(|| Mutex::new(Writer::new()));
|
||||
|
||||
pub fn screensize_chars() -> (u32, u32) {
|
||||
let writer = WRITER.lock();
|
||||
(writer.screen_width, writer.screen_height)
|
||||
}
|
||||
|
||||
pub struct Writer {
|
||||
/// Measured in chars not pixels.
|
||||
screen_width: u32,
|
||||
/// Measured in chars not pixels.
|
||||
screen_height: u32,
|
||||
/// 16 pixels tall.
|
||||
text_line: u32,
|
||||
/// 8 pixels wide.
|
||||
text_col: u32,
|
||||
|
||||
fg_color: Color,
|
||||
bg_color: Color,
|
||||
|
||||
offset1: usize,
|
||||
offset2: usize,
|
||||
}
|
||||
|
||||
impl Writer {
|
||||
pub fn new() -> Self {
|
||||
if let Some(writer) = FRAMEBUFFER_WRITER.lock().as_mut() {
|
||||
Self {
|
||||
screen_width: writer.width() as u32 / 8,
|
||||
screen_height: writer.height() as u32 / 16,
|
||||
text_line: 0,
|
||||
text_col: 0,
|
||||
fg_color: Color::White,
|
||||
bg_color: Color::Black,
|
||||
offset1: 16,
|
||||
offset2: 0,
|
||||
}
|
||||
} else {
|
||||
panic!("Framebuffer writer not initialized");
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_char(&mut self, c: u16) {
|
||||
if c as u8 == b'\n' {
|
||||
self.newline();
|
||||
return;
|
||||
}
|
||||
|
||||
// get the character data from the font array. -- each byte is a row of pixels
|
||||
let data: &[u8] = &FONT[c as usize * 16..(c as usize + 1) * 16];
|
||||
|
||||
if let Some(writer) = FRAMEBUFFER_WRITER.lock().as_mut() {
|
||||
for row in 0..16 {
|
||||
let line: u8 = data[row];
|
||||
for col in 0..8 {
|
||||
let pixel_x: u32 = self.text_col * FONT_WIDTH + col;
|
||||
let pixel_y: u32 = self.text_line * FONT_HEIGHT + row as u32;
|
||||
|
||||
if line & (0x80 >> col) != 0 {
|
||||
// write the foreground color
|
||||
writer.write_pixel(pixel_x as usize, pixel_y as usize, self.fg_color);
|
||||
} else {
|
||||
// write the background color
|
||||
writer.write_pixel(pixel_x as usize, pixel_y as usize, self.bg_color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// go to next position
|
||||
if self.text_col + 1 >= self.screen_width {
|
||||
self.newline();
|
||||
} else {
|
||||
self.text_col += 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_offset(&mut self, offset1: usize, offset2: usize) {
|
||||
self.offset1 = offset1;
|
||||
self.offset2 = offset2;
|
||||
}
|
||||
|
||||
pub fn dimensions(&self) -> (u32, u32) {
|
||||
(self.screen_width, self.screen_height)
|
||||
}
|
||||
|
||||
pub fn next_char(&mut self) {
|
||||
self.text_col += 1;
|
||||
}
|
||||
|
||||
pub fn newline(&mut self) {
|
||||
self.text_col = 0;
|
||||
|
||||
if self.text_line + 1 >= self.screen_height {
|
||||
self.text_line = 0;
|
||||
} else {
|
||||
self.text_line += 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_string(&mut self, s: &str) {
|
||||
for c in s.chars() {
|
||||
self.write_char(c as u16);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_colour(&mut self, fg: Color, bg: Color) {
|
||||
self.fg_color = fg;
|
||||
self.bg_color = bg;
|
||||
}
|
||||
|
||||
pub fn reset_colour(&mut self) {
|
||||
self.fg_color = Color::White;
|
||||
self.bg_color = Color::Black;
|
||||
}
|
||||
}
|
||||
|
||||
impl core::fmt::Write for Writer {
|
||||
fn write_str(&mut self, s: &str) -> core::fmt::Result {
|
||||
self.write_string(s);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn write(args: fmt::Arguments, fg: Color, bg: Color) {
|
||||
use core::fmt::Write;
|
||||
|
||||
interrupts::without_interrupts(|| {
|
||||
let mut writer = WRITER.lock();
|
||||
writer.set_colour(fg, bg);
|
||||
writer.write_fmt(args).unwrap();
|
||||
writer.reset_colour();
|
||||
});
|
||||
}
|
||||
|
||||
pub fn _print(args: fmt::Arguments) {
|
||||
x86_64::instructions::interrupts::without_interrupts(|| {
|
||||
write(args, Color::White, Color::Black);
|
||||
})
|
||||
}
|
||||
|
||||
pub fn _print_err(args: fmt::Arguments) {
|
||||
x86_64::instructions::interrupts::without_interrupts(|| {
|
||||
write(args, Color::Red, Color::Black);
|
||||
})
|
||||
}
|
||||
|
||||
pub fn _print_log(args: fmt::Arguments) {
|
||||
x86_64::instructions::interrupts::without_interrupts(|| {
|
||||
write(args, Color::Yellow, Color::Black);
|
||||
})
|
||||
}
|
||||
|
||||
pub fn clear_screen() {
|
||||
interrupts::without_interrupts(|| {
|
||||
let mut writer = WRITER.lock();
|
||||
writer.text_line = 0;
|
||||
writer.text_col = 0;
|
||||
|
||||
if let Some(writer) = FRAMEBUFFER_WRITER.lock().as_mut() {
|
||||
writer.clear();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! println_log {
|
||||
() => ($crate::print_log!("\n"));
|
||||
($($arg:tt)*) => ($crate::print_log!("{}\n", format_args!($($arg)*)));
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! print_log {
|
||||
($($arg:tt)*) => ($crate::io::ascii::_print_log(format_args!($($arg)*)));
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! println {
|
||||
() => ($crate::print!("\n"));
|
||||
($($arg:tt)*) => ($crate::print!("{}\n", format_args!($($arg)*)));
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! print {
|
||||
($($arg:tt)*) => ($crate::io::ascii::_print(format_args!($($arg)*)));
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! printlnerr {
|
||||
() => ($crate::printerr!("\n"));
|
||||
($($arg:tt)*) => ($crate::printerr!("{}\n", format_args!($($arg)*)));
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! printerr {
|
||||
($($arg:tt)*) => ($crate::_print_err(format_args!($($arg)*)));
|
||||
}
|
||||
@@ -0,0 +1,578 @@
|
||||
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
|
||||
];
|
||||
@@ -0,0 +1,83 @@
|
||||
use limine::request::FramebufferRequest;
|
||||
|
||||
#[used]
|
||||
#[link_section = ".requests"]
|
||||
static FRAMEBUFFER_REQUEST: FramebufferRequest = FramebufferRequest::new();
|
||||
|
||||
mod colour;
|
||||
|
||||
pub use colour::Color;
|
||||
use core::panic;
|
||||
|
||||
use limine::framebuffer::Framebuffer;
|
||||
use spin::{Lazy, Mutex};
|
||||
|
||||
// use crate::{colour::Color, FRAMEBUFFER_REQUEST};
|
||||
|
||||
pub static FRAMEBUFFER_WRITER: Lazy<Mutex<Option<FramebufferWriter>>> = Lazy::new(|| {
|
||||
Mutex::new(
|
||||
if let Some(framebuffer_response) = FRAMEBUFFER_REQUEST.get_response() {
|
||||
let framebuffer = framebuffer_response.framebuffers().next().unwrap();
|
||||
Some(FramebufferWriter::new(framebuffer))
|
||||
} else {
|
||||
panic!("Framebuffer request failed");
|
||||
},
|
||||
)
|
||||
});
|
||||
|
||||
pub struct FramebufferWriter<'a> {
|
||||
framebuffer: Framebuffer<'a>,
|
||||
}
|
||||
|
||||
unsafe impl<'a> Send for FramebufferWriter<'a> {}
|
||||
unsafe impl<'a> Sync for FramebufferWriter<'a> {}
|
||||
impl<'a> FramebufferWriter<'a> {
|
||||
pub fn new(framebuffer: Framebuffer<'a>) -> Self {
|
||||
Self { framebuffer }
|
||||
}
|
||||
|
||||
pub fn write_pixel(&self, x: usize, y: usize, color: Color) {
|
||||
let pitch = self.framebuffer.pitch() as usize;
|
||||
let bpp = (self.framebuffer.bpp() / 8) as usize;
|
||||
let pixel_offset = y * pitch + x * bpp;
|
||||
|
||||
unsafe {
|
||||
*(self.framebuffer.addr().add(pixel_offset) as *mut u32) = color.into();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn render_frame(&self, buffer: &[Color; 1280 * 800]) {
|
||||
for (y, row) in buffer.chunks(1280).enumerate() {
|
||||
for (x, pixel) in row.iter().enumerate() {
|
||||
self.write_pixel(x, y, *pixel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn width(&self) -> u32 {
|
||||
self.framebuffer.width() as u32
|
||||
}
|
||||
|
||||
pub fn height(&self) -> u32 {
|
||||
self.framebuffer.height() as u32
|
||||
}
|
||||
|
||||
pub fn clear(&self) {
|
||||
let width = self.framebuffer.width() as usize;
|
||||
let height = self.framebuffer.height() as usize;
|
||||
|
||||
for y in 0..height {
|
||||
for x in 0..width {
|
||||
self.write_pixel(x, y, Color::Black);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn screensize_px() -> (u32, u32) {
|
||||
if let Some(writer) = FRAMEBUFFER_WRITER.lock().as_mut() {
|
||||
(writer.width(), writer.height())
|
||||
} else {
|
||||
(0, 0)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
#[repr(u32)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||
pub enum Color {
|
||||
ARGB(u8, u8, u8, u8),
|
||||
RGB(u8, u8, u8),
|
||||
HexARGB(u32),
|
||||
Black = 0x000000FF,
|
||||
Blue = 0x0000FFFF,
|
||||
Green = 0x00FF00FF,
|
||||
Cyan = 0x00FFFFFF,
|
||||
Red = 0xFF0000FF,
|
||||
Magenta = 0xFF00FFFF,
|
||||
Yellow = 0xFFFF00FF,
|
||||
White = 0xFFFFFFFF,
|
||||
}
|
||||
|
||||
impl Into<u32> for Color {
|
||||
fn into(self) -> u32 {
|
||||
match self {
|
||||
Color::ARGB(a, r, g, b) => {
|
||||
(a as u32) << 24 | (r as u32) << 16 | (g as u32) << 8 | (b as u32)
|
||||
}
|
||||
Color::RGB(r, g, b) => (0u32) << 24 | (r as u32) << 16 | (g as u32) << 8 | (b as u32),
|
||||
Color::HexARGB(hex) => hex,
|
||||
Color::Black => 0xFF000000,
|
||||
Color::Blue => 0xFF0000FF,
|
||||
Color::Green => 0xFF00FF00,
|
||||
Color::Cyan => 0xFF00FFFF,
|
||||
Color::Red => 0xFFFF0000,
|
||||
Color::Magenta => 0xFFFF00FF,
|
||||
Color::Yellow => 0xFFFFFF00,
|
||||
Color::White => 0xFFFFFFFF,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl core::fmt::Display for Color {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
match self {
|
||||
Color::ARGB(r, g, b, a) => write!(f, "RGBA(#{:x}{:x}{:x}{:x})", r, g, b, a),
|
||||
Color::RGB(r, g, b) => write!(f, "RGB(#{:x}{:x}{:x})", r, g, b),
|
||||
Color::HexARGB(hex) => write!(f, "Hex(#{:x})", hex),
|
||||
Color::Black => write!(f, "Black"),
|
||||
Color::Blue => write!(f, "Blue"),
|
||||
Color::Green => write!(f, "Green"),
|
||||
Color::Cyan => write!(f, "Cyan"),
|
||||
Color::Red => write!(f, "Red"),
|
||||
Color::Magenta => write!(f, "Magenta"),
|
||||
Color::Yellow => write!(f, "Yellow"),
|
||||
Color::White => write!(f, "White"),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
extern crate alloc;
|
||||
|
||||
use core::{
|
||||
pin::Pin,
|
||||
task::{Context, Poll},
|
||||
};
|
||||
|
||||
use super::{print, println};
|
||||
use crossbeam::queue::ArrayQueue;
|
||||
use futures_util::{task::AtomicWaker, Stream};
|
||||
use spin::Once;
|
||||
|
||||
static KBD_QUEUE: Once<ArrayQueue<u8>> = Once::new();
|
||||
static WAKER: AtomicWaker = AtomicWaker::new();
|
||||
|
||||
pub fn add_scancode(scancode: u8) {
|
||||
if let Some(queue) = KBD_QUEUE.get() {
|
||||
if let Err(_) = queue.push(scancode) {
|
||||
println!("WARNING: scancode queue full; dropping keyboard input");
|
||||
} else {
|
||||
println!("waking waker");
|
||||
WAKER.wake();
|
||||
}
|
||||
} else {
|
||||
println!("WARNING: scancode queue not initialised");
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ScanCodeStream {
|
||||
_private: (),
|
||||
}
|
||||
|
||||
impl ScanCodeStream {
|
||||
pub fn new() -> Self {
|
||||
KBD_QUEUE.call_once(|| ArrayQueue::new(5));
|
||||
ScanCodeStream { _private: () }
|
||||
}
|
||||
}
|
||||
|
||||
impl Stream for ScanCodeStream {
|
||||
type Item = u8;
|
||||
|
||||
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
|
||||
let queue = KBD_QUEUE.get().expect("scancode queue not initialized");
|
||||
print!("polling or smth");
|
||||
|
||||
// fast path
|
||||
if let Some(scancode) = queue.pop() {
|
||||
return Poll::Ready(Some(scancode));
|
||||
}
|
||||
|
||||
WAKER.register(&cx.waker());
|
||||
match queue.pop() {
|
||||
Some(scancode) => {
|
||||
print!("scancode found");
|
||||
WAKER.take();
|
||||
Poll::Ready(Some(scancode))
|
||||
}
|
||||
None => {
|
||||
print!("returning");
|
||||
Poll::Pending
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
use futures_util::stream::StreamExt;
|
||||
use pc_keyboard::{layouts, DecodedKey, HandleControl, Keyboard, ScancodeSet1};
|
||||
|
||||
pub async fn print_keypresses() {
|
||||
let mut scancodes = ScanCodeStream::new();
|
||||
let mut keyboard = Keyboard::new(
|
||||
ScancodeSet1::new(),
|
||||
layouts::Us104Key,
|
||||
HandleControl::Ignore,
|
||||
);
|
||||
|
||||
println!("OK!!!");
|
||||
|
||||
while let Some(scancode) = scancodes.next().await {
|
||||
if let Ok(Some(key_event)) = keyboard.add_byte(scancode) {
|
||||
if let Some(key) = keyboard.process_keyevent(key_event) {
|
||||
match key {
|
||||
DecodedKey::Unicode(character) => print!("{}", character),
|
||||
DecodedKey::RawKey(key) => print!("{:?}", key),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
//! Functions for IO using ports.
|
||||
|
||||
use core::arch::asm;
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn inb(port: u16) -> u8 {
|
||||
let value: u8;
|
||||
asm!(
|
||||
"in al, dx",
|
||||
out("al") value,
|
||||
in("dx") port,
|
||||
options(nomem, nostack, preserves_flags)
|
||||
);
|
||||
value
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn outb(port: u16, value: u8) {
|
||||
asm!(
|
||||
"out dx, al",
|
||||
in("dx") port,
|
||||
in("al") value,
|
||||
options(nomem, nostack, preserves_flags)
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
use core::{
|
||||
fmt,
|
||||
sync::atomic::{AtomicUsize, Ordering},
|
||||
};
|
||||
use spin::{Lazy, Mutex};
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! serial_println {
|
||||
() => ($crate::serial_print!("\n"));
|
||||
($($arg:tt)*) => ($crate::io::serial_print!("{}\n", format_args!($($arg)*)));
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! serial_print {
|
||||
($($arg:tt)*) => ($crate::io::serial::_serial_write(format_args!($($arg)*)));
|
||||
}
|
||||
|
||||
use super::port::{inb, outb};
|
||||
|
||||
use x86_64::instructions::interrupts;
|
||||
|
||||
pub fn _serial_write(args: fmt::Arguments) {
|
||||
use core::fmt::Write;
|
||||
|
||||
interrupts::without_interrupts(|| {
|
||||
if let Some(writer) = WRITER.lock().as_mut() {
|
||||
writer.write_fmt(args).unwrap();
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn serial_read() -> &'static str {
|
||||
serial_println!("getting value!");
|
||||
|
||||
interrupts::without_interrupts(|| {
|
||||
if let Some(reader) = READER.lock().as_mut() {
|
||||
serial_println!("stuff happnin.");
|
||||
reader.read_str_to_buffer();
|
||||
} else {
|
||||
serial_println!("failed to get writer");
|
||||
}
|
||||
});
|
||||
|
||||
serial_println!("eee");
|
||||
|
||||
let i = BUFFER_LEN.load(Ordering::SeqCst);
|
||||
|
||||
return unsafe {
|
||||
if i != 0 {
|
||||
core::str::from_utf8(&BUFFER[..i - 1]).unwrap()
|
||||
} else {
|
||||
serial_println!("empty string");
|
||||
""
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static PORT: u16 = 0x3f8;
|
||||
static mut BUFFER: [u8; 256] = [0; 256];
|
||||
static BUFFER_LEN: AtomicUsize = AtomicUsize::new(0);
|
||||
|
||||
static READER: Lazy<Mutex<Option<Reader>>> = Lazy::new(|| Mutex::new(None));
|
||||
static WRITER: Lazy<Mutex<Option<Writer>>> = Lazy::new(|| Mutex::new(None));
|
||||
|
||||
struct Reader;
|
||||
|
||||
struct Writer;
|
||||
|
||||
impl fmt::Write for Writer {
|
||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||
for c in s.chars() {
|
||||
self.write_byte(c as u8);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Writer {
|
||||
unsafe fn write_success(&self) -> bool {
|
||||
inb(PORT + 5) & 0x20 != 0
|
||||
}
|
||||
|
||||
pub fn write_byte(&self, data: u8) {
|
||||
unsafe {
|
||||
while !self.write_success() {}
|
||||
outb(PORT + 0, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init() -> Result<(), &'static str> {
|
||||
if let Err(e) = test() {
|
||||
return Err(e);
|
||||
}
|
||||
|
||||
if READER.lock().is_none() {
|
||||
*READER.lock() = Some(Reader);
|
||||
}
|
||||
|
||||
if WRITER.lock().is_none() {
|
||||
*WRITER.lock() = Some(Writer);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn test() -> Result<(), &'static str> {
|
||||
unsafe {
|
||||
outb(PORT + 1, 0x00); // Disable all interrupts
|
||||
outb(PORT + 3, 0x80); // Enable DLAB (set baud rate divisor)
|
||||
outb(PORT + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud
|
||||
outb(PORT + 1, 0x00); // (hi byte)
|
||||
outb(PORT + 3, 0x03); // 8 bits, no parity, one stop bit
|
||||
outb(PORT + 2, 0xC7); // Enable FIFO, clear them, with 14-bytethreshold
|
||||
outb(PORT + 4, 0x0B); // IRQs enabled, RTS/DSR set
|
||||
outb(PORT + 4, 0x1E); // Set in loopback mode, test the serial chip
|
||||
outb(PORT + 0, 0xAE); // Test serial chip (send byte 0xAE and check if serial returns same byte)
|
||||
|
||||
if inb(PORT + 0) != 0xAE {
|
||||
return Err("serial test failed");
|
||||
}
|
||||
|
||||
outb(PORT + 4, 0x0F);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
impl Reader {
|
||||
pub fn read_str_to_buffer(&mut self) {
|
||||
unsafe {
|
||||
while !self.read_ready() {}
|
||||
|
||||
BUFFER_LEN.store(0, Ordering::SeqCst);
|
||||
|
||||
while BUFFER_LEN.load(Ordering::SeqCst) < 256 {
|
||||
let c = self.read();
|
||||
BUFFER[BUFFER_LEN.load(Ordering::SeqCst)] = c;
|
||||
if c as char == '\r' {
|
||||
break;
|
||||
}
|
||||
BUFFER_LEN.fetch_add(1, Ordering::SeqCst);
|
||||
}
|
||||
|
||||
serial_println!("returning")
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn read_ready(&self) -> bool {
|
||||
inb(PORT + 5) & 1 != 0
|
||||
}
|
||||
|
||||
pub fn read(&self) -> u8 {
|
||||
unsafe {
|
||||
while !self.read_ready() {}
|
||||
return inb(PORT + 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#![no_std]
|
||||
|
||||
// alloc
|
||||
// io : serial, framebuffer, ascii(?), keyboard
|
||||
// ?????
|
||||
// scheduling / tasks : async
|
||||
|
||||
pub mod alloc;
|
||||
pub mod io;
|
||||
pub mod scheduling;
|
||||
|
||||
/// Re-exports most of the IO macros.
|
||||
pub mod prelude {
|
||||
pub use crate::{print_log, println, println_log, serial_print, serial_println};
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
pub mod task;
|
||||
@@ -0,0 +1,133 @@
|
||||
extern crate alloc;
|
||||
use alloc::{boxed::Box, collections::BTreeMap, sync::Arc, task::Wake};
|
||||
use core::{
|
||||
future::Future,
|
||||
pin::Pin,
|
||||
sync::atomic::{AtomicU64, Ordering},
|
||||
task::{Context, Poll, Waker},
|
||||
};
|
||||
use crossbeam::queue::ArrayQueue;
|
||||
|
||||
pub struct Task {
|
||||
id: TaskId,
|
||||
future: Pin<Box<dyn Future<Output = ()>>>,
|
||||
}
|
||||
|
||||
impl Task {
|
||||
pub fn new(future: impl Future<Output = ()> + 'static) -> Task {
|
||||
Task {
|
||||
id: TaskId::new(),
|
||||
future: Box::pin(future),
|
||||
}
|
||||
}
|
||||
|
||||
fn poll(&mut self, context: &mut Context) -> Poll<()> {
|
||||
self.future.as_mut().poll(context)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Executor {
|
||||
tasks: BTreeMap<TaskId, Task>,
|
||||
task_queue: Arc<ArrayQueue<TaskId>>,
|
||||
waker_cache: BTreeMap<TaskId, Waker>,
|
||||
}
|
||||
|
||||
impl Executor {
|
||||
pub fn new() -> Self {
|
||||
Executor {
|
||||
tasks: BTreeMap::new(),
|
||||
task_queue: Arc::new(ArrayQueue::new(100)),
|
||||
waker_cache: BTreeMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn spawn(&mut self, task: Task) {
|
||||
let task_id = task.id;
|
||||
if self.tasks.insert(task.id, task).is_some() {
|
||||
panic!("a task with this id has already been allocated");
|
||||
}
|
||||
self.task_queue.push(task_id).expect("task queue is full");
|
||||
}
|
||||
|
||||
fn run_ready_tasks(&mut self) {
|
||||
let Self {
|
||||
tasks,
|
||||
task_queue,
|
||||
waker_cache,
|
||||
} = self;
|
||||
|
||||
while let Some(task_id) = task_queue.pop() {
|
||||
let task = match tasks.get_mut(&task_id) {
|
||||
Some(task) => task,
|
||||
None => continue,
|
||||
};
|
||||
let waker = waker_cache
|
||||
.entry(task_id)
|
||||
.or_insert_with(|| TaskWaker::new(task_id, task_queue.clone()));
|
||||
let mut context = Context::from_waker(waker);
|
||||
match task.poll(&mut context) {
|
||||
Poll::Ready(()) => {
|
||||
tasks.remove(&task_id);
|
||||
waker_cache.remove(&task_id);
|
||||
}
|
||||
Poll::Pending => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn try_run(&mut self) {
|
||||
self.run_ready_tasks();
|
||||
self.sleep_if_idle();
|
||||
}
|
||||
|
||||
fn sleep_if_idle(&self) {
|
||||
use x86_64::instructions::interrupts::{self, enable_and_hlt};
|
||||
|
||||
interrupts::disable();
|
||||
if self.task_queue.is_empty() {
|
||||
enable_and_hlt();
|
||||
} else {
|
||||
interrupts::enable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct TaskWaker {
|
||||
task_id: TaskId,
|
||||
task_queue: Arc<ArrayQueue<TaskId>>,
|
||||
}
|
||||
|
||||
impl TaskWaker {
|
||||
fn new(task_id: TaskId, task_queue: Arc<ArrayQueue<TaskId>>) -> Waker {
|
||||
Waker::from(Arc::new(TaskWaker {
|
||||
task_id,
|
||||
task_queue,
|
||||
}))
|
||||
}
|
||||
|
||||
fn wake_task(&self) {
|
||||
self.task_queue
|
||||
.push(self.task_id)
|
||||
.expect("task queue is full!");
|
||||
}
|
||||
}
|
||||
|
||||
impl Wake for TaskWaker {
|
||||
fn wake(self: Arc<Self>) {
|
||||
self.wake_task();
|
||||
}
|
||||
|
||||
fn wake_by_ref(self: &Arc<Self>) {
|
||||
self.wake_task();
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
struct TaskId(u64);
|
||||
|
||||
impl TaskId {
|
||||
fn new() -> Self {
|
||||
static NEXT: AtomicU64 = AtomicU64::new(0);
|
||||
TaskId(NEXT.fetch_add(1, Ordering::Relaxed))
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Script originally written by zxq5, I added separate scripts to remove `jq` dependency.
|
||||
|
||||
# Colors
|
||||
GREEN='\033[0;32m'
|
||||
BLUE='\033[0;34m'
|
||||
@@ -16,6 +18,8 @@ trap 'echo -e "${RED}${BOLD}error${NC}: build failed" >&2' ERR
|
||||
script_dir=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)
|
||||
project_root=$(cd "$script_dir/.." &>/dev/null && pwd)
|
||||
|
||||
echo -e "${GREEN}${BOLD} Running kernel in debug mode."
|
||||
|
||||
# Logging functions
|
||||
info() {
|
||||
echo -e "${BLUE}${BOLD}info${NC}: $1"
|
||||
@@ -124,8 +128,8 @@ else
|
||||
kvm_flag=""
|
||||
fi
|
||||
|
||||
# Check if we're running in debug mode
|
||||
if [[ "$(cargo metadata --format-version=1 | jq -r '.workspace_members[0]' | cut -d' ' -f2)" == "(debug)" ]]; then
|
||||
# Enable using GDB with $USE_GDB.
|
||||
if [ $USE_GDB ]; then
|
||||
debug_flags="-s -S"
|
||||
else
|
||||
debug_flags=""
|
||||
Executable
+186
@@ -0,0 +1,186 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Script originally written by zxq5, I added separate scripts to remove `jq` dependency.
|
||||
|
||||
# Colors
|
||||
GREEN='\033[0;32m'
|
||||
BLUE='\033[0;34m'
|
||||
YELLOW='\033[0;33m'
|
||||
RED='\033[0;31m'
|
||||
BOLD='\033[1m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Error handling
|
||||
set -e
|
||||
trap 'echo -e "${RED}${BOLD}error${NC}: build failed" >&2' ERR
|
||||
|
||||
# Get absolute path to project root
|
||||
script_dir=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)
|
||||
project_root=$(cd "$script_dir/.." &>/dev/null && pwd)
|
||||
|
||||
echo -e "${GREEN}${BOLD} Running kernel in release mode."
|
||||
|
||||
# Logging functions
|
||||
info() {
|
||||
echo -e "${BLUE}${BOLD}info${NC}: $1"
|
||||
}
|
||||
|
||||
compiling() {
|
||||
echo -e "${GREEN}${BOLD}Compiling${NC}: $1"
|
||||
}
|
||||
|
||||
warning() {
|
||||
echo -e "${YELLOW}${BOLD}warning${NC}: $1" >&2
|
||||
}
|
||||
|
||||
building() {
|
||||
echo -e "${GREEN}${BOLD}Building${NC}: $1"
|
||||
}
|
||||
|
||||
copying() {
|
||||
echo -e "${GREEN}${BOLD} Copying${NC}: $1 to $2"
|
||||
}
|
||||
|
||||
error() {
|
||||
echo -e "${RED}${BOLD}error${NC}: $1" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
copy_file() {
|
||||
copying $1 $2
|
||||
cp "$1" "$2" || error $3
|
||||
}
|
||||
|
||||
build_dir="$project_root/build"
|
||||
iso_root="$build_dir/iso_root"
|
||||
|
||||
# Check if we're running tests
|
||||
is_test=0
|
||||
if [[ $1 == *"deps"* ]]; then
|
||||
is_test=1
|
||||
kernel_path="$1"
|
||||
else
|
||||
# Build the kernel normally
|
||||
cd "$project_root"
|
||||
# cargo build
|
||||
kernel_path="$build_dir/target/x86_64-kernel/release/kernel"
|
||||
fi
|
||||
|
||||
# Check for required tools
|
||||
check_tools() {
|
||||
local missing=0
|
||||
for tool in xorriso git qemu-system-x86_64; do
|
||||
if ! command -v $tool >/dev/null 2>&1; then
|
||||
error "required tool '$tool' is not installed"
|
||||
missing=1
|
||||
fi
|
||||
done
|
||||
if [ $missing -eq 1 ]; then
|
||||
error "missing required tools"
|
||||
fi
|
||||
}
|
||||
|
||||
# Create build directory structure
|
||||
info "Creating build directory structure"
|
||||
mkdir -p "$iso_root/boot/limine"
|
||||
mkdir -p "$iso_root/EFI/BOOT"
|
||||
|
||||
# Clone Limine if needed
|
||||
if [ ! -d "$build_dir/limine" ]; then
|
||||
compiling "limine bootloader"
|
||||
cd "$build_dir"
|
||||
git clone https://github.com/limine-bootloader/limine.git --branch=v9.x-binary --depth=1 "$build_dir/limine" || error "failed to clone limine"
|
||||
make -C "$build_dir/limine" || error "failed to build limine"
|
||||
cd "$project_root"
|
||||
fi
|
||||
|
||||
# Copy files
|
||||
info "Copying files to ISO root"
|
||||
copy_file "$kernel_path" "$iso_root/boot/kernel" "failed to copy kernel"
|
||||
copy_file "$project_root/config/limine.conf" "$iso_root/boot/limine/limine.conf" "failed to copy limine config"
|
||||
copy_file "$build_dir/limine/limine-bios-cd.bin" "$iso_root/boot/limine/" "failed to copy limine-bios-cd.bin"
|
||||
copy_file "$build_dir/limine/limine-uefi-cd.bin" "$iso_root/boot/limine/" "failed to copy limine-uefi-cd.bin"
|
||||
copy_file "$build_dir/limine/limine-bios.sys" "$iso_root/boot/limine/" "failed to copy limine-bios.sys"
|
||||
copy_file "$build_dir/limine/BOOTX64.EFI" "$iso_root/EFI/BOOT/" "failed to copy BOOTX64.EFI"
|
||||
copy_file "$build_dir/limine/BOOTIA32.EFI" "$iso_root/EFI/BOOT/" "failed to copy BOOTIA32.EFI"
|
||||
|
||||
# Create ISO
|
||||
building "bootable ISO image"
|
||||
xorriso -as mkisofs -R -r -J -b boot/limine/limine-bios-cd.bin \
|
||||
-no-emul-boot -boot-load-size 4 -boot-info-table -hfsplus \
|
||||
-apm-block-size 2048 --efi-boot boot/limine/limine-uefi-cd.bin \
|
||||
-efi-boot-part --efi-boot-image --protective-msdos-label \
|
||||
"$iso_root" -o "$build_dir/image.iso" || error "failed to create ISO"
|
||||
|
||||
# Install Limine
|
||||
info "Installing Limine bootloader"
|
||||
"$build_dir/limine/limine" bios-install "$build_dir/image.iso" || error "failed to install limine"
|
||||
|
||||
# Check if KVM is available
|
||||
if [ "${KVM_FLAG:-enable}" = "disable" ]; then
|
||||
warning "KVM acceleration disabled by user"
|
||||
kvm_flag=""
|
||||
elif [ -c "/dev/kvm" ] && [ -w "/dev/kvm" ]; then
|
||||
info "KVM acceleration enabled"
|
||||
kvm_flag="-enable-kvm"
|
||||
else
|
||||
warning "KVM acceleration not available (is kvm module loaded?)"
|
||||
kvm_flag=""
|
||||
fi
|
||||
|
||||
# I'm lazy but I just remove GDB flags when running this script.
|
||||
debug_flags=""
|
||||
|
||||
# Set up test-specific flags
|
||||
if [ $is_test -eq 1 ]; then
|
||||
test_flags="-device isa-debug-exit,iobase=0xf4,iosize=0x04 -display none"
|
||||
serial_flags="-serial stdio"
|
||||
else
|
||||
test_flags=""
|
||||
# serial_flags="-serial tcp:127.0.0.1:1234,server -monitor telnet:127.0.0.1:1235,server"
|
||||
serial_flags="-serial stdio"
|
||||
fi
|
||||
|
||||
# Run in QEMU
|
||||
if [[ ${QEMU_FLAGS} == *-S* ]]; then
|
||||
info "Running OS in QEMU with GDB debugging enabled"
|
||||
info "To connect GDB, run: gdb"
|
||||
info "At the GDB prompt, type: target remote localhost:1234"
|
||||
else
|
||||
info "Running OS in QEMU..."
|
||||
fi
|
||||
|
||||
check_test_res() {
|
||||
qemu_exit_code=$?
|
||||
if [ $qemu_exit_code -eq 33 ]; then
|
||||
# Success case (0x10 << 1) | 1 = 33
|
||||
info "All tests passed"
|
||||
exit 0
|
||||
elif [ $qemu_exit_code -eq 35 ]; then
|
||||
# Failure case (0x11 << 1) | 1 = 35
|
||||
warning "Some tests failed"
|
||||
exit 1
|
||||
else
|
||||
# Any other exit code is treated as a failure
|
||||
warning "Some tests failed"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
kvm_flag=""
|
||||
|
||||
trap 'check_test_res "tests completed"' ERR
|
||||
|
||||
cd "$project_root"
|
||||
qemu-system-x86_64 -M q35 \
|
||||
${kvm_flag} \
|
||||
-cdrom "$build_dir/image.iso" \
|
||||
-boot d \
|
||||
-m 2G \
|
||||
${serial_flags} \
|
||||
-no-reboot \
|
||||
${test_flags} \
|
||||
${debug_flags} \
|
||||
${QEMU_FLAGS:-}
|
||||
|
||||
Reference in New Issue
Block a user