From 706c58b9b9fa74c63180f490a1f48652d0408944 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Thu, 18 Apr 2024 10:55:51 +0200 Subject: MHR-3: Start working on drivers now. Signed-off-by: Amlal El Mahrouss --- Private/Drivers/SampleDriver/SampleDriver.c | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 Private/Drivers/SampleDriver/SampleDriver.c (limited to 'Private/Drivers/SampleDriver/SampleDriver.c') diff --git a/Private/Drivers/SampleDriver/SampleDriver.c b/Private/Drivers/SampleDriver/SampleDriver.c new file mode 100644 index 00000000..79b19bf3 --- /dev/null +++ b/Private/Drivers/SampleDriver/SampleDriver.c @@ -0,0 +1,9 @@ +/* ------------------------------------------- + + Copyright Mahrouss Logic + +------------------------------------------- */ + +int __ImageStart(void) { + return 0; +} -- cgit v1.2.3 From 0ae4062bfe9936cc9fd2c7bb924442480b067d93 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Thu, 18 Apr 2024 23:10:15 +0200 Subject: MHR-5: initial commit. Signed-off-by: Amlal El Mahrouss --- Private/DriverKit/KernelPrint.c | 19 ++++ Private/DriverKit/KernelPrint.h | 45 +++++++++ Private/Drivers/SampleDriver/SampleDriver.c | 8 ++ Private/Drivers/SampleDriver/makefile | 2 +- Private/FirmwareKit/EFI/EFI.hxx | 2 - Private/HALKit/AMD64/HalHardwareMP.cpp | 10 +- Private/HALKit/PowerPC/HalHart.cxx | 19 ++++ Private/HALKit/PowerPC/HalSMPManager.cxx | 18 ---- Private/HALKit/PowerPC/HalStartSequence.s | 10 +- Private/HALKit/PowerPC/Hart.hxx | 9 +- Private/HALKit/PowerPC/MBCI/.gitkeep | 0 Private/HALKit/PowerPC/MBCI/HalMBCIHost.cxx | 8 ++ Private/HALKit/PowerPC/PCI/.gitkeep | 0 Private/HALKit/PowerPC/PCI/HalDevice.cxx | 1 - Private/HALKit/PowerPC/Processor.hpp | 4 +- Private/NewBoot/BootKit/BootKit.hxx | 11 ++- Private/NewBoot/BootKit/Rsrc/Driver.rsrc | 70 +++++++++++++ Private/NewBoot/Source/HEL/AMD64/BootEPM.cxx | 119 ----------------------- Private/NewBoot/Source/HEL/AMD64/BootMain.cxx | 119 +++++++++-------------- Private/NewBoot/Source/HEL/PowerPC/BootEPM.cxx | 10 +- Private/NewBoot/Source/HEL/PowerPC/BootPowerPC.S | 14 ++- Private/Root/Boot/Icons/boot-logo.ico | Bin 2238 -> 3638 bytes Private/Root/Boot/Icons/driver-logo.ico | Bin 2238 -> 3638 bytes Private/Root/Boot/Icons/kernel-logo.ico | Bin 2238 -> 3638 bytes 24 files changed, 261 insertions(+), 237 deletions(-) create mode 100644 Private/DriverKit/KernelPrint.c create mode 100644 Private/DriverKit/KernelPrint.h create mode 100644 Private/HALKit/PowerPC/HalHart.cxx delete mode 100644 Private/HALKit/PowerPC/HalSMPManager.cxx create mode 100644 Private/HALKit/PowerPC/MBCI/.gitkeep create mode 100644 Private/HALKit/PowerPC/MBCI/HalMBCIHost.cxx delete mode 100644 Private/HALKit/PowerPC/PCI/.gitkeep delete mode 100644 Private/HALKit/PowerPC/PCI/HalDevice.cxx create mode 100644 Private/NewBoot/BootKit/Rsrc/Driver.rsrc delete mode 100644 Private/NewBoot/Source/HEL/AMD64/BootEPM.cxx (limited to 'Private/Drivers/SampleDriver/SampleDriver.c') diff --git a/Private/DriverKit/KernelPrint.c b/Private/DriverKit/KernelPrint.c new file mode 100644 index 00000000..32e20f4f --- /dev/null +++ b/Private/DriverKit/KernelPrint.c @@ -0,0 +1,19 @@ +/* ------------------------------------------- + + Copyright Mahrouss Logic + + Purpose: Kernel Text I/O. + +------------------------------------------- */ + +#include "DriverKit/KernelPrint.h" + +#ifdef __x86_64__ +static void kernelPrintCharAMD64(const char ch) { + __asm__ volatile("outb %%al, %1" : : "a"(ch), "Nd"(0x3F8) : "memory"); +} +#endif // if __x86_64__ + +DK_EXTERN void kernelPrintChar(const char ch) { + kernelPrintChar(ch); +} diff --git a/Private/DriverKit/KernelPrint.h b/Private/DriverKit/KernelPrint.h new file mode 100644 index 00000000..7e25e304 --- /dev/null +++ b/Private/DriverKit/KernelPrint.h @@ -0,0 +1,45 @@ +/* ------------------------------------------- + + Copyright Mahrouss Logic + + Purpose: Kernel Text I/O. + +------------------------------------------- */ + +#pragma once + +#if defined(__cplusplus) +#define DK_EXTERN extern "C" +#else +#define DK_EXTERN extern +#endif // defined(__cplusplus) + +#include +#include + +/// @brief print character into UART. +DK_EXTERN void kernelPrintChar(const char ch); + +static inline size_t kernelStringLength(const char* str) { + size_t index = 0; + + while (str[index] != 0) { + ++index; + } + + return index; +} + +/// @brief print string to UART. +static inline void kernelPrintStr(const char* message) { + if (!message) return; + if (*message == 0) return; + + size_t index = 0; + size_t len = kernelStringLength(message); + + while (index < len) { + kernelPrintChar(message[index]); + ++index; + } +} diff --git a/Private/Drivers/SampleDriver/SampleDriver.c b/Private/Drivers/SampleDriver/SampleDriver.c index 79b19bf3..04d40516 100644 --- a/Private/Drivers/SampleDriver/SampleDriver.c +++ b/Private/Drivers/SampleDriver/SampleDriver.c @@ -4,6 +4,14 @@ ------------------------------------------- */ +#include + int __ImageStart(void) { + kernelPrintStr("SampleDriver: Starting up.\n"); + return 0; +} + +int __ImageEnd(void) { + kernelPrintStr("SampleDriver: Shutting down.\n"); return 0; } diff --git a/Private/Drivers/SampleDriver/makefile b/Private/Drivers/SampleDriver/makefile index 7d58b611..899b1491 100644 --- a/Private/Drivers/SampleDriver/makefile +++ b/Private/Drivers/SampleDriver/makefile @@ -49,7 +49,7 @@ endif .PHONY: compile-amd64 compile-amd64: $(WINDRES) DriverRsrc.rsrc -O coff -o DriverRsrc.o - $(CC_GNU) $(FLAG_GNU) $(DEBUG) $(wildcard *.c) + $(CC_GNU) $(FLAG_GNU) $(DEBUG) $(wildcard *.c) $(wildcard ../../DriverKit/*.c) .PHONY: clean clean: diff --git a/Private/FirmwareKit/EFI/EFI.hxx b/Private/FirmwareKit/EFI/EFI.hxx index 1d56f757..7f8223cf 100644 --- a/Private/FirmwareKit/EFI/EFI.hxx +++ b/Private/FirmwareKit/EFI/EFI.hxx @@ -571,8 +571,6 @@ typedef struct EfiSystemTable { } *ConfigurationTable; } EfiSystemTable; -#define EfiMain efi_main - #define kEfiOk 0 #define kEfiFail -1 diff --git a/Private/HALKit/AMD64/HalHardwareMP.cpp b/Private/HALKit/AMD64/HalHardwareMP.cpp index 0e9f3022..135222b9 100644 --- a/Private/HALKit/AMD64/HalHardwareMP.cpp +++ b/Private/HALKit/AMD64/HalHardwareMP.cpp @@ -19,20 +19,12 @@ void rt_wakeup_thread(HAL::StackFrame* stack) { HAL::rt_sti(); } -/// @brief Hangs until RCX register is cleared. -/// @param stack -static void __rt_hang_proc(HAL::StackFrame* stack) { - while (stack->Rcx == 1) { - ; - } -} - /// @brief makes thread sleep. /// hooks and hangs thread to prevent code from executing. void rt_hang_thread(HAL::StackFrame* stack) { HAL::rt_cli(); - __rt_hang_proc(stack); + stack->Rcx = 1; HAL::rt_sti(); } diff --git a/Private/HALKit/PowerPC/HalHart.cxx b/Private/HALKit/PowerPC/HalHart.cxx new file mode 100644 index 00000000..102bab7d --- /dev/null +++ b/Private/HALKit/PowerPC/HalHart.cxx @@ -0,0 +1,19 @@ +/* ------------------------------------------- + + Copyright Mahrouss Logic + +------------------------------------------- */ + +#include +#include +#include + +using namespace NewOS; + +/// @brief wakes up thread. +/// wakes up thread from hang. +void rt_wakeup_thread(HAL::StackFramePtr stack) {} + +/// @brief makes thread sleep. +/// hooks and hangs thread to prevent code from executing. +void rt_hang_thread(HAL::StackFramePtr stack) {} diff --git a/Private/HALKit/PowerPC/HalSMPManager.cxx b/Private/HALKit/PowerPC/HalSMPManager.cxx deleted file mode 100644 index 26ebc399..00000000 --- a/Private/HALKit/PowerPC/HalSMPManager.cxx +++ /dev/null @@ -1,18 +0,0 @@ -/* ------------------------------------------- - - Copyright Mahrouss Logic - -------------------------------------------- */ - -#include -#include - -using namespace NewOS; - -/// @brief wakes up thread. -/// wakes up thread from hang. -void rt_wakeup_thread(HAL::StackFramePtr stack) {} - -/// @brief makes thread sleep. -/// hooks and hangs thread to prevent code from executing. -void rt_hang_thread(HAL::StackFramePtr stack) {} \ No newline at end of file diff --git a/Private/HALKit/PowerPC/HalStartSequence.s b/Private/HALKit/PowerPC/HalStartSequence.s index 112ac73f..f50a4d4f 100644 --- a/Private/HALKit/PowerPC/HalStartSequence.s +++ b/Private/HALKit/PowerPC/HalStartSequence.s @@ -1,6 +1,14 @@ +/* ------------------------------------------- + + Copyright Mahrouss Logic + +------------------------------------------- */ + .globl Main +.extern HalKernelMain .align 4 .text Main: - b Main + bl HalKernelMain + blr diff --git a/Private/HALKit/PowerPC/Hart.hxx b/Private/HALKit/PowerPC/Hart.hxx index 618cbd97..56d51243 100644 --- a/Private/HALKit/PowerPC/Hart.hxx +++ b/Private/HALKit/PowerPC/Hart.hxx @@ -15,6 +15,13 @@ #include +/// @brief hardware thread indentification type. typedef NewOS::Int32 PPCHartType; - +/// @brief Hardware thread information structure. +typedef struct HalHardwareThread { + NewOS::UIntPtr fStartAddress; + NewOS::UInt8 fPrivleged : 1; + NewOS::UInt32 fPageFlags; + PPCHartType fIdentNumber; +} HalHardwareThread; diff --git a/Private/HALKit/PowerPC/MBCI/.gitkeep b/Private/HALKit/PowerPC/MBCI/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/Private/HALKit/PowerPC/MBCI/HalMBCIHost.cxx b/Private/HALKit/PowerPC/MBCI/HalMBCIHost.cxx new file mode 100644 index 00000000..98371c43 --- /dev/null +++ b/Private/HALKit/PowerPC/MBCI/HalMBCIHost.cxx @@ -0,0 +1,8 @@ +/* ------------------------------------------- + + Copyright Mahrouss Logic + +------------------------------------------- */ + +#include +#include diff --git a/Private/HALKit/PowerPC/PCI/.gitkeep b/Private/HALKit/PowerPC/PCI/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/Private/HALKit/PowerPC/PCI/HalDevice.cxx b/Private/HALKit/PowerPC/PCI/HalDevice.cxx deleted file mode 100644 index 8b137891..00000000 --- a/Private/HALKit/PowerPC/PCI/HalDevice.cxx +++ /dev/null @@ -1 +0,0 @@ - diff --git a/Private/HALKit/PowerPC/Processor.hpp b/Private/HALKit/PowerPC/Processor.hpp index 19f8e799..12a5bd26 100644 --- a/Private/HALKit/PowerPC/Processor.hpp +++ b/Private/HALKit/PowerPC/Processor.hpp @@ -11,12 +11,12 @@ #include #include -#define __PPC_ALIGN __attribute__((aligned(4))) +#define kHalPPCAlignment __attribute__((aligned(4))) namespace NewOS::HAL { typedef UIntPtr Reg; -struct __PPC_ALIGN StackFrame { +struct kHalPPCAlignment StackFrame { Reg R0; Reg R1; Reg R2; diff --git a/Private/NewBoot/BootKit/BootKit.hxx b/Private/NewBoot/BootKit/BootKit.hxx index 1fbd0aef..be16c2c5 100644 --- a/Private/NewBoot/BootKit/BootKit.hxx +++ b/Private/NewBoot/BootKit/BootKit.hxx @@ -18,9 +18,12 @@ class BVersionString; #include #include + #ifdef __EFI_x86_64__ +#define kBootVirtualAddress (0xffffff80000000) #include #endif // ifdef __EFI_x86_64__ + #include #include @@ -68,8 +71,10 @@ NewOS::SizeT BSetMem(CharacterTypeUTF8 *src, const CharacterTypeUTF8 byte, /// String length functions. +/// @brief get string length. NewOS::SizeT BStrLen(const CharacterTypeUTF16 *ptr); +/// @brief set memory with custom value. NewOS::SizeT BSetMem(CharacterTypeUTF16 *src, const CharacterTypeUTF16 byte, const NewOS::SizeT len); @@ -169,7 +174,7 @@ inline UInt32 In32(UInt16 port) { /*** * Common processor instructions. -*/ + */ EXTERN_C void rt_hlt(); EXTERN_C void rt_cli(); @@ -221,8 +226,10 @@ class BVersionString final { /// @param namePart the partition's name /// @param namePartLength the partition name's length /// @param bootDev the disk interface. -/// @return +/// @return EXTERN_C Boolean boot_write_epm_partition(const Char *namePart, SizeT namePartLength, BootDevice *bootDev); +/// @brief Bootloader main type. +typedef void (*BootMainKind)(HEL::HandoverInformationHeader* handoverInfo); diff --git a/Private/NewBoot/BootKit/Rsrc/Driver.rsrc b/Private/NewBoot/BootKit/Rsrc/Driver.rsrc new file mode 100644 index 00000000..c9fdc812 --- /dev/null +++ b/Private/NewBoot/BootKit/Rsrc/Driver.rsrc @@ -0,0 +1,70 @@ +#define DRIVER_LOGO_HEIGHT 64 +#define DRIVER_LOGO_WIDTH 64 + +// array size is 12288 +static const unsigned int driver_logo[] = { + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x242424, 0x3b3b3b, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x404040, 0x3e3e3e, 0x393939, 0x333333, 0x202020, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x3b3b3b, 0x999999, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xb9b9b9, 0xacacac, 0x848484, 0x333333, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x404040, 0xbfbfbf, 0xfbfbfb, 0xf2f2f2, 0xeeeeee, 0xeeeeee, 0xeeeeee, 0xeeeeee, 0xf0f0f0, 0xf4f4f4, 0xf6f6f6, 0xf6f6f6, 0xf6f6f6, 0xf6f6f6, 0xf6f6f6, 0xf6f6f6, 0xf4f4f4, 0xf0f0f0, 0xeeeeee, 0xeeeeee, 0xeeeeee, 0xeeeeee, 0xeeeeee, 0xeeeeee, 0xf0f0f0, 0xf4f4f4, 0xf6f6f6, 0xf6f6f6, 0xf6f6f6, 0xf6f6f6, 0xf6f6f6, 0xf6f6f6, 0xf4f4f4, 0xf0f0f0, 0xeeeeee, 0xeeeeee, 0xeeeeee, 0xeeeeee, 0xeeeeee, 0xeeeeee, 0xf0f0f0, 0xf4f4f4, 0xf6f6f6, 0xf6f6f6, 0xf6f6f6, 0xf6f6f6, 0xf6f6f6, 0xf6f6f6, 0xf4f4f4, 0xf0f0f0, 0xeeeeee, 0xeeeeee, 0xe4e4e4, 0xd1d1d1, 0x969696, 0x323232, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x404040, 0xbfbfbf, 0xf2f2f2, 0xd9d9d9, 0xcccccc, 0xcccccc, 0xcccccc, 0xcccccc, 0xd2d2d2, 0xdfdfdf, 0xe5e5e5, 0xe5e5e5, 0xe5e5e5, 0xe5e5e5, 0xe5e5e5, 0xe5e5e5, 0xdfdfdf, 0xd2d2d2, 0xcccccc, 0xcccccc, 0xcccccc, 0xcccccc, 0xcccccc, 0xcccccc, 0xd2d2d2, 0xdfdfdf, 0xe5e5e5, 0xe5e5e5, 0xe5e5e5, 0xe5e5e5, 0xe5e5e5, 0xe5e5e5, 0xdfdfdf, 0xd2d2d2, 0xcccccc, 0xcccccc, 0xcccccc, 0xcccccc, 0xcccccc, 0xcccccc, 0xd2d2d2, 0xdfdfdf, 0xe5e5e5, 0xe5e5e5, 0xe5e5e5, 0xe5e5e5, 0xe5e5e5, 0xe5e5e5, 0xdfdfdf, 0xd2d2d2, 0xcccccc, 0xcccccc, 0xc0c0c0, 0xa9a9a9, 0x767676, 0x272727, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x404040, 0xbfbfbf, 0xeeeeee, 0xcccccc, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xaeaeae, 0x959595, 0x666666, 0x222222, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x404040, 0xbfbfbf, 0xeeeeee, 0xcccccc, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xaeaeae, 0x959595, 0x666666, 0x222222, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x404040, 0xbfbfbf, 0xeeeeee, 0xcccccc, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xaeaeae, 0x959595, 0x666666, 0x222222, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x404040, 0xbfbfbf, 0xeeeeee, 0xcccccc, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xaeaeae, 0x959595, 0x666666, 0x222222, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x404040, 0xbfbfbf, 0xf0f0f0, 0xd2d2d2, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xb5b5b5, 0x979797, 0x666666, 0x222222, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x404040, 0xbfbfbf, 0xf4f4f4, 0xdfdfdf, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xc1c1c1, 0x9b9b9b, 0x666666, 0x222222, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x404040, 0xbfbfbf, 0xf6f6f6, 0xe5e5e5, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xc8c8c8, 0x9d9d9d, 0x666666, 0x222222, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x404040, 0xbfbfbf, 0xf6f6f6, 0xe5e5e5, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xc8c8c8, 0x9d9d9d, 0x666666, 0x222222, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x404040, 0xbfbfbf, 0xf6f6f6, 0xe5e5e5, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xc8c8c8, 0x9d9d9d, 0x666666, 0x222222, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x404040, 0xbfbfbf, 0xf6f6f6, 0xe5e5e5, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xc8c8c8, 0x9d9d9d, 0x666666, 0x222222, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x404040, 0xbfbfbf, 0xf1f1f1, 0xd6d6d6, 0xcbcbcb, 0xd1d1d1, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xc8c8c8, 0x9d9d9d, 0x666666, 0x222222, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x404040, 0xbfbfbf, 0xe7e7e7, 0xb6b6b6, 0xa7a7a7, 0xbababa, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xc8c8c8, 0x9d9d9d, 0x666666, 0x222222, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x404040, 0xbfbfbf, 0xd9d9d9, 0x8c8c8c, 0x787878, 0x9c9c9c, 0xb1b1b1, 0xb8b8b8, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xc1c1c1, 0x9b9b9b, 0x666666, 0x222222, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x404040, 0xbfbfbf, 0xc8c8c8, 0x595959, 0x3f3f3f, 0x787878, 0x9e9e9e, 0xb1b1b1, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xb5b5b5, 0x979797, 0x666666, 0x222222, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x303030, 0x8f8f8f, 0x999999, 0x3b3b3b, 0x202020, 0x525252, 0x808080, 0xb2b2b2, 0xcacaca, 0xc6c6c6, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xaeaeae, 0x959595, 0x666666, 0x222222, 0x000000, 0x000000, 0x242424, 0x3b3b3b, 0x3b3b3b, 0x242424, 0x000000, + 0x000000, 0x101010, 0x303030, 0x3b3b3b, 0x242424, 0x141414, 0x202020, 0x555555, 0xbbbbbb, 0xe8e8e8, 0xdbdbdb, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xaeaeae, 0x959595, 0x666666, 0x222222, 0x000000, 0x000000, 0x3b3b3b, 0x999999, 0x999999, 0x3b3b3b, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x404040, 0xbfbfbf, 0xf6f6f6, 0xe5e5e5, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xaeaeae, 0x959595, 0x666666, 0x222222, 0x101010, 0x303030, 0x686868, 0xb9b9b9, 0xa9a9a9, 0x383838, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x404040, 0xbfbfbf, 0xf6f6f6, 0xe5e5e5, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xaeaeae, 0x959595, 0x666666, 0x222222, 0x303030, 0x8f8f8f, 0xb9b9b9, 0xacacac, 0x7c7c7c, 0x292929, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x404040, 0xbfbfbf, 0xf6f6f6, 0xe5e5e5, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xb4b4b4, 0xa5a5a5, 0x848484, 0x515151, 0x676767, 0xc7c7c7, 0xdbdbdb, 0xa4a4a4, 0x666666, 0x222222, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x404040, 0xbfbfbf, 0xf6f6f6, 0xe5e5e5, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbebebe, 0xc5c5c5, 0xbfbfbf, 0xaeaeae, 0xb6b6b6, 0xd6d6d6, 0xcecece, 0x9f9f9f, 0x666666, 0x222222, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x404040, 0xbfbfbf, 0xf6f6f6, 0xe5e5e5, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xc8c8c8, 0x9d9d9d, 0x666666, 0x222222, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x404040, 0xbfbfbf, 0xf6f6f6, 0xe5e5e5, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xc8c8c8, 0x9d9d9d, 0x666666, 0x222222, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x404040, 0xbfbfbf, 0xf4f4f4, 0xdfdfdf, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xc1c1c1, 0x9b9b9b, 0x666666, 0x222222, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x404040, 0xbfbfbf, 0xf0f0f0, 0xd2d2d2, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xb5b5b5, 0x979797, 0x666666, 0x222222, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x404040, 0xbfbfbf, 0xeeeeee, 0xcccccc, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xaeaeae, 0x959595, 0x666666, 0x222222, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x404040, 0xbfbfbf, 0xeeeeee, 0xcccccc, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xaeaeae, 0x959595, 0x666666, 0x222222, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x404040, 0xbfbfbf, 0xeeeeee, 0xcccccc, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xaeaeae, 0x959595, 0x666666, 0x222222, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x404040, 0xbfbfbf, 0xeeeeee, 0xcccccc, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xaeaeae, 0x959595, 0x666666, 0x222222, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x404040, 0xbfbfbf, 0xeeeeee, 0xcccccc, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xaeaeae, 0x959595, 0x666666, 0x222222, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x404040, 0xbfbfbf, 0xeeeeee, 0xcccccc, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xaeaeae, 0x959595, 0x666666, 0x222222, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x404040, 0xbfbfbf, 0xf0f0f0, 0xd2d2d2, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xb5b5b5, 0x979797, 0x666666, 0x222222, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x404040, 0xbfbfbf, 0xf4f4f4, 0xdfdfdf, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xc1c1c1, 0x9b9b9b, 0x666666, 0x222222, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x404040, 0xbfbfbf, 0xf6f6f6, 0xe5e5e5, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xb8b8b8, 0xb1b1b1, 0xbababa, 0xd1d1d1, 0xc8c8c8, 0x9d9d9d, 0x666666, 0x222222, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x404040, 0xbfbfbf, 0xf6f6f6, 0xe5e5e5, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xb1b1b1, 0x9e9e9e, 0xa7a7a7, 0xcbcbcb, 0xc8c8c8, 0x9d9d9d, 0x666666, 0x222222, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x404040, 0xbfbfbf, 0xf6f6f6, 0xe5e5e5, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xb8b8b8, 0xb1b1b1, 0x9c9c9c, 0x787878, 0x7e7e7e, 0xafafaf, 0xb8b8b8, 0x989898, 0x666666, 0x222222, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x404040, 0xbfbfbf, 0xf6f6f6, 0xe5e5e5, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xb1b1b1, 0x9e9e9e, 0x787878, 0x3f3f3f, 0x414141, 0x7e7e7e, 0x989898, 0x8d8d8d, 0x666666, 0x222222, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x404040, 0xbfbfbf, 0xf6f6f6, 0xe5e5e5, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xb5b5b5, 0x979797, 0x666666, 0x222222, 0x1a1a1a, 0x4d4d4d, 0x6f6f6f, 0x808080, 0x666666, 0x222222, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x404040, 0xbfbfbf, 0xf6f6f6, 0xe5e5e5, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xc1c1c1, 0x9b9b9b, 0x666666, 0x222222, 0x090909, 0x1a1a1a, 0x3c3c3c, 0x6f6f6f, 0x666666, 0x222222, 0x000000, + 0x000000, 0x101010, 0x303030, 0x3b3b3b, 0x242424, 0x242424, 0x3b3b3b, 0x707070, 0xcfcfcf, 0xf4f4f4, 0xdfdfdf, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xc8c8c8, 0x9d9d9d, 0x666666, 0x222222, 0x000000, 0x000000, 0x202020, 0x525252, 0x525252, 0x202020, 0x000000, + 0x000000, 0x303030, 0x8f8f8f, 0x999999, 0x3b3b3b, 0x3b3b3b, 0x999999, 0xcfcfcf, 0xefefef, 0xf0f0f0, 0xd2d2d2, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xc8c8c8, 0x9d9d9d, 0x666666, 0x222222, 0x000000, 0x000000, 0x141414, 0x202020, 0x202020, 0x141414, 0x000000, + 0x000000, 0x404040, 0xbfbfbf, 0xcfcfcf, 0x707070, 0x707070, 0xcfcfcf, 0xfdfdfd, 0xf9f9f9, 0xe8e8e8, 0xcacaca, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xc8c8c8, 0x9d9d9d, 0x666666, 0x222222, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x404040, 0xbfbfbf, 0xefefef, 0xcfcfcf, 0xcfcfcf, 0xefefef, 0xf9f9f9, 0xececec, 0xdbdbdb, 0xc6c6c6, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xc8c8c8, 0x9d9d9d, 0x666666, 0x222222, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x404040, 0xbfbfbf, 0xfdfdfd, 0xf9f9f9, 0xf4f4f4, 0xf0f0f0, 0xe8e8e8, 0xdbdbdb, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xc8c8c8, 0x9d9d9d, 0x666666, 0x222222, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x404040, 0xbfbfbf, 0xf9f9f9, 0xececec, 0xdfdfdf, 0xd2d2d2, 0xcacaca, 0xc6c6c6, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xc8c8c8, 0x9d9d9d, 0x666666, 0x222222, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x404040, 0xbfbfbf, 0xf4f4f4, 0xdfdfdf, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xc1c1c1, 0x9b9b9b, 0x666666, 0x222222, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x404040, 0xbfbfbf, 0xf0f0f0, 0xd2d2d2, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xb5b5b5, 0x979797, 0x666666, 0x222222, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x404040, 0xbfbfbf, 0xeeeeee, 0xcccccc, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xaeaeae, 0x959595, 0x666666, 0x222222, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x404040, 0xbfbfbf, 0xeeeeee, 0xcccccc, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xaeaeae, 0x959595, 0x666666, 0x222222, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x404040, 0xbfbfbf, 0xeeeeee, 0xcccccc, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xaeaeae, 0x959595, 0x666666, 0x222222, 0x101010, 0x575757, 0xcbcbcb, 0xcbcbcb, 0xcacaca, 0xcfcfcf, 0x000000, + 0x000000, 0x404040, 0xbfbfbf, 0xeeeeee, 0xcccccc, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xaeaeae, 0x959595, 0x666666, 0x222222, 0x292929, 0x8e8e8e, 0xcccccc, 0xcccccc, 0xcdcdcd, 0xcacaca, 0x000000, + 0x000000, 0x404040, 0xbfbfbf, 0xeeeeee, 0xcccccc, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xaeaeae, 0x959595, 0x666666, 0x222222, 0x313131, 0x939393, 0xc6c6c6, 0xcacaca, 0xcccccc, 0xcbcbcb, 0xcbcbcb, + 0x000000, 0x404040, 0xbfbfbf, 0xeeeeee, 0xcccccc, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xaeaeae, 0x959595, 0x666666, 0x222222, 0x2d2d2d, 0x868686, 0xb9b9b9, 0xc6c6c6, 0xcccccc, 0xcccccc, 0xcccccc, + 0x000000, 0x404040, 0xbfbfbf, 0xf0f0f0, 0xd2d2d2, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xcacaca, 0xd7d7d7, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xdbdbdb, 0xd7d7d7, 0xcecece, 0xc1c1c1, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbdbdbd, 0xc1c1c1, 0xb5b5b5, 0x979797, 0x666666, 0x222222, 0x282828, 0x797979, 0xaaaaaa, 0xbbbbbb, 0xc6c6c6, 0xcacaca, 0xcccccc, + 0x000000, 0x404040, 0xbfbfbf, 0xf4f4f4, 0xdfdfdf, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xd7d7d7, 0xdbdbdb, 0xdddddd, 0xdddddd, 0xdddddd, 0xdddddd, 0xd7d7d7, 0xcacaca, 0xc1c1c1, 0xbdbdbd, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xc1c1c1, 0xcecece, 0xc1c1c1, 0x9b9b9b, 0x666666, 0x222222, 0x242424, 0x6c6c6c, 0x999999, 0xaaaaaa, 0xb9b9b9, 0xc6c6c6, 0xcccccc, + 0x000000, 0x3e3e3e, 0xb9b9b9, 0xebebeb, 0xd3d3d3, 0xc8c8c8, 0xc8c8c8, 0xc8c8c8, 0xc8c8c8, 0xc8c8c8, 0xc8c8c8, 0xc1c1c1, 0xb5b5b5, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xb5b5b5, 0xc1c1c1, 0xc8c8c8, 0xc8c8c8, 0xc8c8c8, 0xc8c8c8, 0xc8c8c8, 0xc8c8c8, 0xc1c1c1, 0xb5b5b5, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xb5b5b5, 0xc1c1c1, 0xc8c8c8, 0xc8c8c8, 0xc8c8c8, 0xc8c8c8, 0xc8c8c8, 0xc8c8c8, 0xc1c1c1, 0xb5b5b5, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xb5b5b5, 0xc1c1c1, 0xb8b8b8, 0x989898, 0x666666, 0x222222, 0x222222, 0x666666, 0x939393, 0xa8a8a8, 0xb8b8b8, 0xc4c4c4, 0xcccccc, + 0x000000, 0x393939, 0xacacac, 0xd3d3d3, 0xafafaf, 0x9d9d9d, 0x9d9d9d, 0x9d9d9d, 0x9d9d9d, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x979797, 0x959595, 0x959595, 0x959595, 0x959595, 0x959595, 0x959595, 0x979797, 0x9b9b9b, 0x9d9d9d, 0x9d9d9d, 0x9d9d9d, 0x9d9d9d, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x979797, 0x959595, 0x959595, 0x959595, 0x959595, 0x959595, 0x959595, 0x979797, 0x9b9b9b, 0x9d9d9d, 0x9d9d9d, 0x9d9d9d, 0x9d9d9d, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x979797, 0x959595, 0x959595, 0x959595, 0x959595, 0x959595, 0x959595, 0x979797, 0x9b9b9b, 0x989898, 0x8d8d8d, 0x666666, 0x222222, 0x222222, 0x666666, 0x979797, 0xb5b5b5, 0xc4c4c4, 0xc6c6c6, 0xcbcbcb, + 0x000000, 0x333333, 0x848484, 0x969696, 0x767676, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x666666, 0x555555, 0x333333, 0x3c3c3c, 0x6f6f6f, 0x959595, 0xb8b8b8, 0xcdcdcd, 0xcacaca, 0x000000, + 0x000000, 0x202020, 0x333333, 0x323232, 0x272727, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x222222, 0x333333, 0x555555, 0x6f6f6f, 0x808080, 0x8e8e8e, 0xa4a4a4, 0xcacaca, 0xcfcfcf, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x222222, 0x666666, 0x888888, 0x888888, 0x888888, 0x878787, 0x000000, 0x000000, 0x000000 +}; diff --git a/Private/NewBoot/Source/HEL/AMD64/BootEPM.cxx b/Private/NewBoot/Source/HEL/AMD64/BootEPM.cxx deleted file mode 100644 index 0d678dc1..00000000 --- a/Private/NewBoot/Source/HEL/AMD64/BootEPM.cxx +++ /dev/null @@ -1,119 +0,0 @@ -/* ------------------------------------------- - - Copyright Mahrouss Logic - -------------------------------------------- */ - -#include -#include - -#define kEPMSectorSize kATASectorSize -#define kEPMSwapSize MIB(16) -#define kEPMGPTStartLba (30) - -// {310E1FC7-2060-425D-BE7B-75A37CC679BC} -STATIC const BlockGUID kEPMGuid = { - 0x310e1fc7, - 0x2060, - 0x425d, - {0xbe, 0x7b, 0x75, 0xa3, 0x7c, 0xc6, 0x79, 0xbc}}; - -/// @brief Write epm partition to disk. -/// @param namePart partition name -/// @param namePartLength length of name -/// @param bootDev disk interface. -/// @return -EXTERN_C Boolean boot_write_epm_partition(const Char* namePart, SizeT namePartLength, - BootDevice* bootDev) { - if (namePartLength > kEPMNameLength || !namePart) return No; - if (!bootDev) return No; - - bootDev->Leak().mBase = kEPMGPTStartLba; - bootDev->Leak().mSize = kEPMSectorSize; - - Char buf[kEPMSectorSize] = {0}; - - bootDev->Read(buf, 1); - - BTextWriter writer; - - writer.Write(L"NewOS: Checking for a EPM partition...\r\n"); - - for (SizeT index = 0; index < kEPMMagicLength; ++index) { - if (buf[index] != kEPMMagic[index]) { - writer.Write(L"NewOS: Writing a EPM partition...\r\n"); - - BootBlockType* bootBlock = (BootBlockType*)buf; - - bootBlock->Version = kEPMRevision; - bootBlock->NumBlocks = 2; - - for (SizeT i = 0; i < kEPMNameLength; ++i) { - bootBlock->Magic[i] = kEPMMagic[i]; - } - - for (SizeT i = 0; i < namePartLength; ++i) { - bootBlock->Name[i] = namePart[i]; - } - - bootBlock->LbaStart = - sizeof(BootBlockType) + (sizeof(PartitionBlockType) * kEPMMaxBlks); - - bootBlock->SectorSz = kEPMSectorSize; - - bootBlock->Uuid = kEPMGuid; - - PartitionBlock* partBlock = (PartitionBlock*)(buf + sizeof(BootBlock)); - - const char* fsName = "NewFS"; - int fsNameLength = 6; - - for (SizeT i = 0; i < fsNameLength; ++i) { - partBlock->Fs[i] = fsName[i]; - } - - partBlock->Version = kEPMNewOS; - - const char* partNameSystem = "System HD"; - int partNameLength = 10; - - for (SizeT i = 0; i < partNameLength; ++i) { - partBlock->Name[i] = partNameSystem[i]; - } - - partBlock->SectorSz = kEPMSectorSize; - partBlock->LbaStart = kEPMStartPartitionBlk + kEPMSwapSize; - partBlock->Version = kNewFSVersionInteger; - partBlock->Kind = kNewFSPartitionTypeStandard; - partBlock->LbaEnd = 0UL; ///! grows on the disk. - - PartitionBlock* swapBlock = (PartitionBlock*)(buf + sizeof(BootBlock) + sizeof(PartitionBlock)); - - for (SizeT i = 0; i < fsNameLength; ++i) { - swapBlock->Fs[i] = fsName[i]; - } - - swapBlock->Version = kEPMNewOS; - - const char *partNameSwap = "Swap HD"; - partNameLength = 8; - - for (SizeT i = 0; i < partNameLength; ++i) { - swapBlock->Name[i] = partNameSwap[i]; - } - - swapBlock->SectorSz = kEPMSectorSize; - swapBlock->LbaStart = kEPMStartPartitionBlk; - swapBlock->Version = kNewFSVersionInteger; - swapBlock->Kind = kNewFSPartitionTypePage; - swapBlock->LbaEnd = kEPMSwapSize; /// 4 MIB swap partition. - - bootDev->Write(buf, 1); - - return No; - } - } - - writer.Write(L"NewOS: Partition found, everything's OK.\r\n"); - return Yes; -} \ No newline at end of file diff --git a/Private/NewBoot/Source/HEL/AMD64/BootMain.cxx b/Private/NewBoot/Source/HEL/AMD64/BootMain.cxx index f5bb3ce8..a5014f92 100644 --- a/Private/NewBoot/Source/HEL/AMD64/BootMain.cxx +++ b/Private/NewBoot/Source/HEL/AMD64/BootMain.cxx @@ -5,53 +5,41 @@ ------------------------------------------- */ #include +#include +#include #include #include #include -#ifdef __x86_64__ -#include -#else -#error This CPU is unknown. -#endif // ifdef __x86_64__ - #define kMaxBufSize 256 -/// @brief Bootloader main type. -typedef void (*bt_main_type)(HEL::HandoverInformationHeader* handoverInfo); +/// @brief check the BootDevice if suitable. +STATIC Bool CheckBootDevice(BootDeviceATA& ataDev) { + if (ataDev.Leak().mErr) return false; + return true; +} /// @brief Main EFI entrypoint. /// @param ImageHandle Handle of this image. /// @param SystemTable The system table of it. /// @return -EFI_EXTERN_C EFI_API Int EfiMain(EfiHandlePtr ImageHandle, - EfiSystemTable* SystemTable) { - InitEFI(SystemTable); // Init the EFI library. - InitGOP(); // Init the GOP. +EFI_EXTERN_C EFI_API Int efi_main(EfiHandlePtr ImageHandle, + EfiSystemTable* SystemTable) { + InitEFI(SystemTable); ///! Init the EFI library. + InitGOP(); ///! Init the GOP. BTextWriter writer; /// Splash screen stuff - writer.Write(L"Mahrouss-Logic (R) NewOS: ").Write(BVersionString::Shared()); + writer.Write(L"Mahrouss-Logic (R) NewBoot: ").Write(BVersionString::Shared()); - writer.Write(L"\r\nNewOS: Firmware Vendor: ") + writer.Write(L"\r\nNewBoot: Firmware Vendor: ") .Write(SystemTable->FirmwareVendor) .Write(L"\r\n"); BootDeviceATA ataDev; Boolean isEpmFound = No; - /// if ATA drive is initialized and EFI vendor supports an EPM scheme. - /// @EDK tells our OS that it supports EPM scheme as well. - if (ataDev) { - Char namePart[kEPMNameLength] = {"NewBoot"}; - /// tries to read an EPM block, or writes one if it fails. - isEpmFound = boot_write_epm_partition(namePart, kEPMNameLength, &ataDev); - } else { - writer.Write(L"NewOS: This computer can't work with NewOS.\r\n"); - return kEfiFail; - } - UInt32 MapKey = 0; UInt32* SizePtr = nullptr; EfiMemoryDescriptor* Descriptor = nullptr; @@ -76,46 +64,8 @@ EFI_EXTERN_C EFI_API Int EfiMain(EfiHandlePtr ImageHandle, EFI::RaiseHardError(L"__bad_alloc", L"NewBoot ran out of memory!"); } - /**** - * - * Get machine memory map. - * - */ - - while (BS->GetMemoryMap(SizePtr, Descriptor, &MapKey, &SzDesc, &RevDesc) != - kEfiOk) - ; - HEL::HandoverInformationHeader* handoverHdrPtr = nullptr; - BS->AllocatePool(EfiLoaderData, sizeof(HEL::HandoverInformationHeader), - (VoidPtr*)&handoverHdrPtr); - - handoverHdrPtr->f_GOP.f_The = kGop->Mode->FrameBufferBase; - handoverHdrPtr->f_GOP.f_Width = kGop->Mode->Info->VerticalResolution; - handoverHdrPtr->f_GOP.f_Height = kGop->Mode->Info->HorizontalResolution; - handoverHdrPtr->f_GOP.f_PixelPerLine = kGop->Mode->Info->PixelsPerScanLine; - handoverHdrPtr->f_GOP.f_PixelFormat = kGop->Mode->Info->PixelFormat; - handoverHdrPtr->f_GOP.f_Size = kGop->Mode->FrameBufferSize; - - handoverHdrPtr->f_PhysicalStart = - reinterpret_cast(Descriptor->PhysicalStart); - handoverHdrPtr->f_PhysicalSize = Descriptor->NumberOfPages; - - handoverHdrPtr->f_VirtualStart = - reinterpret_cast(Descriptor->VirtualStart); - - handoverHdrPtr->f_VirtualSize = Descriptor->NumberOfPages; /* # of pages */ - - handoverHdrPtr->f_FirmwareVendorLen = BStrLen(SystemTable->FirmwareVendor); - - BCopyMem(handoverHdrPtr->f_FirmwareVendorName, SystemTable->FirmwareVendor, - handoverHdrPtr->f_FirmwareVendorLen); - -#ifdef __DEBUG__ - writer.Write(L"NewOS: Fetching ACPI's 'RSD PTR'...").Write(L"\r\n"); -#endif - for (SizeT indexVT = 0; indexVT < SystemTable->NumberOfTableEntries; ++indexVT) { volatile Char* vendorTable = reinterpret_cast( @@ -127,29 +77,48 @@ EFI_EXTERN_C EFI_API Int EfiMain(EfiHandlePtr ImageHandle, vendorTable[6] == 'R' && vendorTable[7] == ' ') { handoverHdrPtr->f_HardwareTables.f_RsdPtr = (VoidPtr)vendorTable; -#ifdef __DEBUG__ - writer.Write(L"NewOS: Found ACPI's 'RSD PTR' table on this machine.") - .Write(L"\r\n"); -#endif + writer.Write(L"NewBoot: Found RSDP for kernel.\r\n"); break; } } - if (!isEpmFound) { - writer.Write(L"NewOS: No partition found for NewOS. (HCR-1000)\r\n"); - } - handoverHdrPtr->f_Magic = kHandoverMagic; handoverHdrPtr->f_Version = kHandoverVersion; - writer.Write(L"Running NewOS...\r\n"); + BCopyMem(handoverHdrPtr->f_FirmwareVendorName, SystemTable->FirmwareVendor, + handoverHdrPtr->f_FirmwareVendorLen); + + handoverHdrPtr->f_GOP.f_The = kGop->Mode->FrameBufferBase; + handoverHdrPtr->f_GOP.f_Width = kGop->Mode->Info->VerticalResolution; + handoverHdrPtr->f_GOP.f_Height = kGop->Mode->Info->HorizontalResolution; + handoverHdrPtr->f_GOP.f_PixelPerLine = kGop->Mode->Info->PixelsPerScanLine; + handoverHdrPtr->f_GOP.f_PixelFormat = kGop->Mode->Info->PixelFormat; + handoverHdrPtr->f_GOP.f_Size = kGop->Mode->FrameBufferSize; + + BS->AllocatePool(EfiLoaderData, sizeof(HEL::HandoverInformationHeader), + (VoidPtr*)&handoverHdrPtr); + + handoverHdrPtr->f_PhysicalStart = 0; + handoverHdrPtr->f_PhysicalSize = 0; + + EfiPhysicalAddress* whereAddress = + reinterpret_cast(kBootVirtualAddress); + + BS->AllocatePages(EfiAllocateType::AllocateAnyPages, + EfiMemoryType::EfiConventionalMemory, 1, whereAddress); + + handoverHdrPtr->f_VirtualStart = reinterpret_cast(whereAddress); + + handoverHdrPtr->f_VirtualSize = Descriptor->NumberOfPages; /* # of pages */ + + handoverHdrPtr->f_FirmwareVendorLen = BStrLen(SystemTable->FirmwareVendor); - EFI::ExitBootServices(MapKey, ImageHandle); + // EFI::ExitBootServices(MapKey, ImageHandle); /// TODO: Read catalog and read NewKernel.exe - EFI::Stop(); + // EFI::Stop(); - return kEfiFail; + CANT_REACH(); } diff --git a/Private/NewBoot/Source/HEL/PowerPC/BootEPM.cxx b/Private/NewBoot/Source/HEL/PowerPC/BootEPM.cxx index f088d73c..72276ef9 100644 --- a/Private/NewBoot/Source/HEL/PowerPC/BootEPM.cxx +++ b/Private/NewBoot/Source/HEL/PowerPC/BootEPM.cxx @@ -21,7 +21,7 @@ STATIC const BlockGUID kEPMGuid = { /// @param namePart partition name /// @param namePartLength length of name /// @param bootDev disk interface. -/// @return +/// @return EXTERN_C Boolean boot_write_epm_partition(const Char* namePart, SizeT namePartLength, BootDevice* bootDev) { if (namePartLength > kEPMNameLength || !namePart) return No; @@ -36,11 +36,11 @@ EXTERN_C Boolean boot_write_epm_partition(const Char* namePart, SizeT namePartLe BTextWriter writer; - writer.Write(L"NewOS: Checking for a EPM partition...\r\n"); + writer.Write(L"NewBoot: Checking for an EPM partition...\r\n"); for (SizeT index = 0; index < kEPMMagicLength; ++index) { if (buf[index] != kEPMMagic[index]) { - writer.Write(L"NewOS: Writing a EPM partition...\r\n"); + writer.Write(L"NewBoot: Writing an EPM partition...\r\n"); BootBlockType* bootBlock = (BootBlockType*)buf; @@ -113,6 +113,6 @@ EXTERN_C Boolean boot_write_epm_partition(const Char* namePart, SizeT namePartLe } } - writer.Write(L"NewOS: Partition found, everything's OK.\r\n"); + writer.Write(L"NewBoot: Partition found, everything's OK.\r\n"); return Yes; -} \ No newline at end of file +} diff --git a/Private/NewBoot/Source/HEL/PowerPC/BootPowerPC.S b/Private/NewBoot/Source/HEL/PowerPC/BootPowerPC.S index 0b3cd493..53d9d4f2 100644 --- a/Private/NewBoot/Source/HEL/PowerPC/BootPowerPC.S +++ b/Private/NewBoot/Source/HEL/PowerPC/BootPowerPC.S @@ -19,4 +19,16 @@ boot_hdr_ver: boot_hdr_proc: .long bootloader_start -/* NewOS kernel header end */ \ No newline at end of file +/* NewOS kernel header end */ + +.extern bootloader_main +.extern bootloader_stack + +.globl bootloader_start +bootloader_start: + mflr 4 /* real address of .Laddr */ + lwz 0,(bootloader_stack-bootloader_start)(4) /* stack address location */ + mr 1,0 /* use user defined stack */ + + bl bootloader_main + blr diff --git a/Private/Root/Boot/Icons/boot-logo.ico b/Private/Root/Boot/Icons/boot-logo.ico index a9c250ed..9be8328f 100644 Binary files a/Private/Root/Boot/Icons/boot-logo.ico and b/Private/Root/Boot/Icons/boot-logo.ico differ diff --git a/Private/Root/Boot/Icons/driver-logo.ico b/Private/Root/Boot/Icons/driver-logo.ico index 9ee1b954..9394ab64 100644 Binary files a/Private/Root/Boot/Icons/driver-logo.ico and b/Private/Root/Boot/Icons/driver-logo.ico differ diff --git a/Private/Root/Boot/Icons/kernel-logo.ico b/Private/Root/Boot/Icons/kernel-logo.ico index d5ea0310..0512b65e 100644 Binary files a/Private/Root/Boot/Icons/kernel-logo.ico and b/Private/Root/Boot/Icons/kernel-logo.ico differ -- cgit v1.2.3 From 155971914073bedfa585a0be4d14a40bd23e3b8f Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Sat, 20 Apr 2024 23:13:11 +0200 Subject: MHR-9: Driver toolkit, initial commit. Signed-off-by: Amlal El Mahrouss --- Private/DriverKit/KernelDev.c | 31 ++++++++++++++ Private/DriverKit/KernelDev.h | 28 +++++++++++++ Private/DriverKit/KernelDispatchCall.s | 13 ++++++ Private/DriverKit/KernelPrint.c | 23 +++++++---- Private/DriverKit/KernelPrint.h | 33 ++------------- Private/DriverKit/KernelStd.c | 24 +++++++++++ Private/DriverKit/KernelStd.h | 22 ++++++++++ Private/DriverKit/KernelString.c | 19 +++++++++ Private/DriverKit/KernelString.h | 13 ++++++ Private/Drivers/Bonjour/DriverRsrc.rsrc | 25 +++++++++++ Private/Drivers/Bonjour/SampleDriver.c | 18 ++++++++ Private/Drivers/Bonjour/makefile | 62 ++++++++++++++++++++++++++++ Private/Drivers/SampleDriver/SampleDriver.c | 5 ++- Private/Drivers/SampleDriver/makefile | 2 +- Private/NewKit/Application.hxx | 10 ++--- Private/Root/Boot/Icons/bonjour-logo.ico | Bin 0 -> 87830 bytes Private/Root/Boot/Icons/boot-logo.ico | Bin 3638 -> 87830 bytes Private/Root/Boot/Icons/driver-logo.ico | Bin 3638 -> 87830 bytes Private/Root/Boot/Icons/kernel-logo.ico | Bin 3638 -> 87830 bytes Private/Root/Users/Shared/.gitkeep | 0 Private/Root/Users/User.script | 3 -- Public/Developer/SystemLib/Sources/App.c | 4 +- 22 files changed, 285 insertions(+), 50 deletions(-) create mode 100644 Private/DriverKit/KernelDev.c create mode 100644 Private/DriverKit/KernelDev.h create mode 100644 Private/DriverKit/KernelDispatchCall.s create mode 100644 Private/DriverKit/KernelStd.c create mode 100644 Private/DriverKit/KernelStd.h create mode 100644 Private/DriverKit/KernelString.c create mode 100644 Private/DriverKit/KernelString.h create mode 100644 Private/Drivers/Bonjour/DriverRsrc.rsrc create mode 100644 Private/Drivers/Bonjour/SampleDriver.c create mode 100644 Private/Drivers/Bonjour/makefile create mode 100644 Private/Root/Boot/Icons/bonjour-logo.ico create mode 100644 Private/Root/Users/Shared/.gitkeep delete mode 100644 Private/Root/Users/User.script (limited to 'Private/Drivers/SampleDriver/SampleDriver.c') diff --git a/Private/DriverKit/KernelDev.c b/Private/DriverKit/KernelDev.c new file mode 100644 index 00000000..e8c041af --- /dev/null +++ b/Private/DriverKit/KernelDev.c @@ -0,0 +1,31 @@ +/* ------------------------------------------- + + Copyright Mahrouss Logic + + Purpose: Kernel Text I/O. + +------------------------------------------- */ + +#include + +/// @brief Open a new binary device from path. +DK_EXTERN kernelDeviceRef kernelOpenBinaryDevice(const char* devicePath) { + if (!devicePath) return NIL; + + return kernelCall("OpenBinaryDevice", 1, devicePath); +} + +/// @brief Open a new character device from path. +DK_EXTERN kernelDeviceRef kernelOpenCharDevice(const char* devicePath) { + if (!devicePath) return NIL; + + return kernelCall("OpenCharDevice", 1, devicePath); +} + +/// @brief Close any device. +/// @param device valid device. +DK_EXTERN void kernelCloseDevice(kernelDeviceRef device) { + if (!device) return; + + kernelCall("CloseDevice", 1, device); +} diff --git a/Private/DriverKit/KernelDev.h b/Private/DriverKit/KernelDev.h new file mode 100644 index 00000000..daa60a7c --- /dev/null +++ b/Private/DriverKit/KernelDev.h @@ -0,0 +1,28 @@ +/* ------------------------------------------- + + Copyright Mahrouss Logic + + Purpose: Kernel Devices. + +------------------------------------------- */ + +#pragma once + +#include + +typedef struct _kernelDevice { + int32_t(*read)(); // read from device. + int32_t(*write)(); // write to device. + struct _kernelDevice* (*open)(const char* path); // open device. + void (*close)(struct _kernelDevice* dev); // close device. +} kernelDevice,* kernelDeviceRef; + +/// @brief Open a new binary device from path. +DK_EXTERN kernelDeviceRef kernelOpenBinaryDevice(const char* devicePath); + +/// @brief Open a new character device from path. +DK_EXTERN kernelDeviceRef kernelOpenCharDevice(const char* devicePath); + +/// @brief Close any device. +/// @param device valid device. +DK_EXTERN void kernelCloseDevice(kernelDeviceRef device); diff --git a/Private/DriverKit/KernelDispatchCall.s b/Private/DriverKit/KernelDispatchCall.s new file mode 100644 index 00000000..2919f6ec --- /dev/null +++ b/Private/DriverKit/KernelDispatchCall.s @@ -0,0 +1,13 @@ +.globl __kernelDispatchCall + +.section .text + +#ifdef __x86_64__ + +/* Really simple function, takes our va-list, + and brings it to the trap handler in the kernel. */ +__kernelDispatchCall: + int $0x33 + ret + +#endif diff --git a/Private/DriverKit/KernelPrint.c b/Private/DriverKit/KernelPrint.c index 32e20f4f..5ca09ccf 100644 --- a/Private/DriverKit/KernelPrint.c +++ b/Private/DriverKit/KernelPrint.c @@ -6,14 +6,23 @@ ------------------------------------------- */ -#include "DriverKit/KernelPrint.h" +#include -#ifdef __x86_64__ -static void kernelPrintCharAMD64(const char ch) { - __asm__ volatile("outb %%al, %1" : : "a"(ch), "Nd"(0x3F8) : "memory"); +DK_EXTERN void kernelPrintChar(const char ch) { + kernelCall("WriteCharacter", 1, ch); } -#endif // if __x86_64__ -DK_EXTERN void kernelPrintChar(const char ch) { - kernelPrintChar(ch); +/// @brief print string to UART. +/// @param message UART to transmit. +DK_EXTERN void kernelPrintStr(const char* message) { + if (!message) return; + if (*message == 0) return; + + size_t index = 0; + size_t len = kernelStringLength(message); + + while (index < len) { + kernelPrintChar(message[index]); + ++index; + } } diff --git a/Private/DriverKit/KernelPrint.h b/Private/DriverKit/KernelPrint.h index 7e25e304..36e55442 100644 --- a/Private/DriverKit/KernelPrint.h +++ b/Private/DriverKit/KernelPrint.h @@ -8,38 +8,11 @@ #pragma once -#if defined(__cplusplus) -#define DK_EXTERN extern "C" -#else -#define DK_EXTERN extern -#endif // defined(__cplusplus) - -#include -#include +#include /// @brief print character into UART. DK_EXTERN void kernelPrintChar(const char ch); -static inline size_t kernelStringLength(const char* str) { - size_t index = 0; - - while (str[index] != 0) { - ++index; - } - - return index; -} - /// @brief print string to UART. -static inline void kernelPrintStr(const char* message) { - if (!message) return; - if (*message == 0) return; - - size_t index = 0; - size_t len = kernelStringLength(message); - - while (index < len) { - kernelPrintChar(message[index]); - ++index; - } -} +/// @param message UART to transmit. +DK_EXTERN void kernelPrintStr(const char* message); diff --git a/Private/DriverKit/KernelStd.c b/Private/DriverKit/KernelStd.c new file mode 100644 index 00000000..494ac0bc --- /dev/null +++ b/Private/DriverKit/KernelStd.c @@ -0,0 +1,24 @@ +/* ------------------------------------------- + + Copyright Mahrouss Logic + + Purpose: Kernel Definitions. + +------------------------------------------- */ + +#include +#include + +DK_EXTERN __attribute__((naked)) void __kernelDispatchCall(int32_t cnt, ...); + +DK_EXTERN void* kernelCall(const char* kernelRpcName, int32_t cnt, ...) { + if (!kernelRpcName || cnt == 0) return NIL; + + va_list arg; + va_start(arg, cnt); + + __kernelDispatchCall(cnt, arg); + + va_end(arg); + +} diff --git a/Private/DriverKit/KernelStd.h b/Private/DriverKit/KernelStd.h new file mode 100644 index 00000000..3344630e --- /dev/null +++ b/Private/DriverKit/KernelStd.h @@ -0,0 +1,22 @@ +/* ------------------------------------------- + + Copyright Mahrouss Logic + + Purpose: Kernel Definitions. + +------------------------------------------- */ + +#pragma once + +#if defined(__cplusplus) +#define DK_EXTERN extern "C" +#define NIL nullptr +#else +#define DK_EXTERN extern +#define NIL NULL +#endif // defined(__cplusplus) + +#include +#include + +DK_EXTERN void* kernelCall(const char* kernelRpcName, int32_t cnt, ...); diff --git a/Private/DriverKit/KernelString.c b/Private/DriverKit/KernelString.c new file mode 100644 index 00000000..7c129dd4 --- /dev/null +++ b/Private/DriverKit/KernelString.c @@ -0,0 +1,19 @@ +/* ------------------------------------------- + + Copyright Mahrouss Logic + + Purpose: Kernel Strings. + +------------------------------------------- */ + +#include + +DK_EXTERN size_t kernelStringLength(const char* str) { + size_t index = 0; + + while (str[index] != 0) { + ++index; + } + + return index; +} diff --git a/Private/DriverKit/KernelString.h b/Private/DriverKit/KernelString.h new file mode 100644 index 00000000..d1b8ac93 --- /dev/null +++ b/Private/DriverKit/KernelString.h @@ -0,0 +1,13 @@ +/* ------------------------------------------- + + Copyright Mahrouss Logic + + Purpose: Kernel Strings. + +------------------------------------------- */ + +#pragma once + +#include + +DK_EXTERN size_t kernelStringLength(const char* str); diff --git a/Private/Drivers/Bonjour/DriverRsrc.rsrc b/Private/Drivers/Bonjour/DriverRsrc.rsrc new file mode 100644 index 00000000..62347b80 --- /dev/null +++ b/Private/Drivers/Bonjour/DriverRsrc.rsrc @@ -0,0 +1,25 @@ +1 ICON "../../Root/Boot/Icons/bonjour-logo.ico" + +1 VERSIONINFO +FILEVERSION 1,0,0,0 +PRODUCTVERSION 1,0,0,0 +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "080904E4" + BEGIN + VALUE "CompanyName", "Mahrouss-Logic" + VALUE "FileDescription", "NewOS Bonjour driver." + VALUE "FileVersion", "1.00" + VALUE "InternalName", "Bonjour." + VALUE "LegalCopyright", "Copyright Mahrouss-Logic, all rights reserved." + VALUE "OriginalFilename", "Bonjour.exe" + VALUE "ProductName", "Bonjour." + VALUE "ProductVersion", "1.00" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x809, 1252 + END +END diff --git a/Private/Drivers/Bonjour/SampleDriver.c b/Private/Drivers/Bonjour/SampleDriver.c new file mode 100644 index 00000000..8289fcbc --- /dev/null +++ b/Private/Drivers/Bonjour/SampleDriver.c @@ -0,0 +1,18 @@ +/* ------------------------------------------- + + Copyright Mahrouss Logic + +------------------------------------------- */ + +#include +#include + +int __ImageStart(void) { + kernelPrintStr("SampleDriver: Starting up...\r\n"); + return 0; +} + +int __ImageEnd(void) { + kernelPrintStr("SampleDriver: Shutting down...\r\n"); + return 0; +} diff --git a/Private/Drivers/Bonjour/makefile b/Private/Drivers/Bonjour/makefile new file mode 100644 index 00000000..e1cdba67 --- /dev/null +++ b/Private/Drivers/Bonjour/makefile @@ -0,0 +1,62 @@ +################################################## +# (C) Mahrouss Logic, all rights reserved. +# This is the sample driver makefile. +################################################## + +CC_GNU=x86_64-w64-mingw32-gcc +LD_GNU=x86_64-w64-mingw32-ld + +WINDRES=x86_64-w64-mingw32-windres + +ADD_FILE=touch +COPY=cp +HTTP_GET=wget + +ifeq ($(shell uname), Windows_NT) +EMU=qemu-system-x86_64w +else +EMU=qemu-system-x86_64 +endif + +IMG=epm.img +IMG_2=epm-slave.img +EMU_FLAGS=-net none -smp 4 -m 4G -M q35 -bios OVMF.fd -device piix3-ide,id=ide -drive id=disk,file=$(IMG),format=raw,if=none -device ide-hd,drive=disk,bus=ide.0 -drive file=fat:rw:CDROM,index=2,format=raw -d int -hdd epm-slave.img + +LD_FLAGS=-e __ImageStart --subsystem=17 + +OBJ=$(wildcard *.o) $(wildcard HEL/AMD64/*.obj) + + +REM=rm +REM_FLAG=-f + +FLAG_ASM=-f win64 +FLAG_GNU=-fshort-wchar -D__EFI_x86_64__ -mgeneral-regs-only -mno-red-zone -D__KERNEL__ -DEFI_FUNCTION_WRAPPER -I../ -I../../ -I./ -c -ffreestanding -std=c17 -D__HAVE_MAHROUSS_APIS__ -D__MAHROUSS__ -D__BOOTLOADER__ -I./ + +.PHONY: invalid-recipe +invalid-recipe: + @echo "invalid-recipe: Use make all instead." + +.PHONY: all +all: compile-amd64 + $(LD_GNU) $(OBJ) $(LD_FLAGS) -o Bonjour.exe + cp Bonjour.exe ../../Root/Boot/Bonjour.exe + +ifneq ($(DEBUG_SUPPORT), ) +DEBUG = -D__DEBUG__ +endif + +.PHONY: compile-amd64 +compile-amd64: + $(WINDRES) DriverRsrc.rsrc -O coff -o DriverRsrc.o + $(CC_GNU) $(FLAG_GNU) $(DEBUG) $(wildcard *.c) $(wildcard ../../DriverKit/*.c) $(wildcard ../../DriverKit/*.s) + +.PHONY: clean +clean: + $(REM) $(REM_FLAG) $(OBJ) Bonjour.exe + +.PHONY: help +help: + @echo "=== HELP ===" + @echo "clean: Clean driver." + @echo "compile-amd64: Build driver." diff --git a/Private/Drivers/SampleDriver/SampleDriver.c b/Private/Drivers/SampleDriver/SampleDriver.c index 04d40516..8289fcbc 100644 --- a/Private/Drivers/SampleDriver/SampleDriver.c +++ b/Private/Drivers/SampleDriver/SampleDriver.c @@ -4,14 +4,15 @@ ------------------------------------------- */ +#include #include int __ImageStart(void) { - kernelPrintStr("SampleDriver: Starting up.\n"); + kernelPrintStr("SampleDriver: Starting up...\r\n"); return 0; } int __ImageEnd(void) { - kernelPrintStr("SampleDriver: Shutting down.\n"); + kernelPrintStr("SampleDriver: Shutting down...\r\n"); return 0; } diff --git a/Private/Drivers/SampleDriver/makefile b/Private/Drivers/SampleDriver/makefile index 19e88f8f..637be18d 100644 --- a/Private/Drivers/SampleDriver/makefile +++ b/Private/Drivers/SampleDriver/makefile @@ -49,7 +49,7 @@ endif .PHONY: compile-amd64 compile-amd64: $(WINDRES) DriverRsrc.rsrc -O coff -o DriverRsrc.o - $(CC_GNU) $(FLAG_GNU) $(DEBUG) $(wildcard *.c) $(wildcard ../../DriverKit/*.c) + $(CC_GNU) $(FLAG_GNU) $(DEBUG) $(wildcard *.c) $(wildcard ../../DriverKit/*.c) $(wildcard ../../DriverKit/*.s) .PHONY: clean clean: diff --git a/Private/NewKit/Application.hxx b/Private/NewKit/Application.hxx index f19dbd97..15ffd073 100644 --- a/Private/NewKit/Application.hxx +++ b/Private/NewKit/Application.hxx @@ -7,7 +7,7 @@ #pragma once /// -/// @brief Main application object, given by the OS to interact with the OS. +/// @brief Application object, given by the OS to the process. interact with the OS. /// @file Application.hxx /// @author Amlal EL Mahrouss /// @@ -17,14 +17,14 @@ /// \brief Application Interface. /// \author Amlal El Mahrouss -typedef struct Application final { +typedef struct _Application final { /// @brief Releases the object exit the process on main object. - NewOS::Void(*Release)(struct Application* Self, NewOS::Int32 ExitCode); + NewOS::Void(*Release)(struct _Application* Self, NewOS::Int32 ExitCode); /// @brief Invoke a function from the application object. - NewOS::IntPtr(*Invoke)(struct Application* Self, NewOS::Int32 Sel, ...); + NewOS::IntPtr(*Invoke)(struct _Application* Self, NewOS::Int32 Sel, ...); /// @brief Query a new application object from a GUID. /// @note this doesn't query a process, it query a registered object withtin that app. - NewOS::Void(*Query)(struct Application* Self, NewOS::VoidPtr* Dst, NewOS::SizeT SzDst, NewOS::XRN::GUIDSequence GuidOf); + NewOS::Void(*Query)(struct _Application* Self, NewOS::VoidPtr* Dst, NewOS::SizeT SzDst, NewOS::XRN::GUIDSequence GuidOf); } Application, *ApplicationRef; #define app_cast reinterpret_cast diff --git a/Private/Root/Boot/Icons/bonjour-logo.ico b/Private/Root/Boot/Icons/bonjour-logo.ico new file mode 100644 index 00000000..5424b46f Binary files /dev/null and b/Private/Root/Boot/Icons/bonjour-logo.ico differ diff --git a/Private/Root/Boot/Icons/boot-logo.ico b/Private/Root/Boot/Icons/boot-logo.ico index 9be8328f..3a0258b8 100644 Binary files a/Private/Root/Boot/Icons/boot-logo.ico and b/Private/Root/Boot/Icons/boot-logo.ico differ diff --git a/Private/Root/Boot/Icons/driver-logo.ico b/Private/Root/Boot/Icons/driver-logo.ico index 9394ab64..5cf8e397 100644 Binary files a/Private/Root/Boot/Icons/driver-logo.ico and b/Private/Root/Boot/Icons/driver-logo.ico differ diff --git a/Private/Root/Boot/Icons/kernel-logo.ico b/Private/Root/Boot/Icons/kernel-logo.ico index 0512b65e..0866aa2d 100644 Binary files a/Private/Root/Boot/Icons/kernel-logo.ico and b/Private/Root/Boot/Icons/kernel-logo.ico differ diff --git a/Private/Root/Users/Shared/.gitkeep b/Private/Root/Users/Shared/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/Private/Root/Users/User.script b/Private/Root/Users/User.script deleted file mode 100644 index 09cecb8b..00000000 --- a/Private/Root/Users/User.script +++ /dev/null @@ -1,3 +0,0 @@ -# User script - -Guest: true; diff --git a/Public/Developer/SystemLib/Sources/App.c b/Public/Developer/SystemLib/Sources/App.c index 9d390795..36e53c7e 100644 --- a/Public/Developer/SystemLib/Sources/App.c +++ b/Public/Developer/SystemLib/Sources/App.c @@ -11,7 +11,7 @@ ApplicationRef kSharedApplication = NullPtr; /// @brief Gets the app arguments count. /// @param void no arguments. -/// @return +/// @return The number of arguments given to the application. CA_EXTERN_C SizeType RtGetAppArgumentsCount(VoidType) { CA_MUST_PASS(kSharedApplication); @@ -23,7 +23,7 @@ CA_EXTERN_C SizeType RtGetAppArgumentsCount(VoidType) { /// @return CA_EXTERN_C CharacterTypeUTF8** RtGetAppArgumentsPtr(VoidType) { CA_MUST_PASS(kSharedApplication); - + return (CharacterTypeUTF8**)kSharedApplication->Invoke(kSharedApplication, kCallGetArgsPtr); } -- cgit v1.2.3 From b4dc4ad11804ae9b2113f61b7055b506cebd5c6d Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Sun, 21 Apr 2024 12:25:15 +0200 Subject: MHR-5: Worked on DriverKit to bring C++ support for it, as some drivers may need it. Signed-off-by: Amlal El Mahrouss --- Private/DriverKit/KernelStdCxx.cc | 24 ++++++++++ Private/DriverKit/KernelString.c | 11 +++++ Private/DriverKit/KernelString.h | 3 ++ Private/Drivers/Bonjour/makefile | 10 ---- Private/Drivers/MahroussUpdate/DriverRsrc.rsrc | 25 ++++++++++ Private/Drivers/MahroussUpdate/MahroussUpdate.cc | 24 ++++++++++ Private/Drivers/MahroussUpdate/MahroussUpdate.hxx | 33 ++++++++++++++ Private/Drivers/MahroussUpdate/makefile | 53 ++++++++++++++++++++++ Private/Drivers/SampleDriver/SampleDriver.c | 3 ++ Private/Drivers/SampleDriver/makefile | 10 ---- Private/Root/Boot/Icons/boot-logo.ico | Bin 87830 -> 78998 bytes Private/Root/Boot/Icons/update-logo.ico | Bin 0 -> 87830 bytes 12 files changed, 176 insertions(+), 20 deletions(-) create mode 100644 Private/DriverKit/KernelStdCxx.cc create mode 100644 Private/Drivers/MahroussUpdate/DriverRsrc.rsrc create mode 100644 Private/Drivers/MahroussUpdate/MahroussUpdate.cc create mode 100644 Private/Drivers/MahroussUpdate/MahroussUpdate.hxx create mode 100644 Private/Drivers/MahroussUpdate/makefile create mode 100644 Private/Root/Boot/Icons/update-logo.ico (limited to 'Private/Drivers/SampleDriver/SampleDriver.c') diff --git a/Private/DriverKit/KernelStdCxx.cc b/Private/DriverKit/KernelStdCxx.cc new file mode 100644 index 00000000..79d41a72 --- /dev/null +++ b/Private/DriverKit/KernelStdCxx.cc @@ -0,0 +1,24 @@ +/* ------------------------------------------- + + Copyright Mahrouss Logic + + Purpose: Driver C++ Definitions. + +------------------------------------------- */ + +#include + +void* operator new(size_t sz) { + if (!sz) ++sz; + + auto ptr = kernelCall("NewKernelHeap", 1, sz); + kernelCall("KernelHeapProtect", 1, ptr); + + return ptr; +} + +void operator delete(void* ptr) noexcept { + if (!ptr) return; + + kernelCall("DeleteKernelHeap", 1,ptr); +} diff --git a/Private/DriverKit/KernelString.c b/Private/DriverKit/KernelString.c index 7c129dd4..0bb45b16 100644 --- a/Private/DriverKit/KernelString.c +++ b/Private/DriverKit/KernelString.c @@ -17,3 +17,14 @@ DK_EXTERN size_t kernelStringLength(const char* str) { return index; } + +DK_EXTERN int kernelStringCopy(char* dst, const char* src, size_t len) { + size_t index = 0; + + while (index != len) { + dst[index] = src[index]; + ++index; + } + + return index; +} diff --git a/Private/DriverKit/KernelString.h b/Private/DriverKit/KernelString.h index d1b8ac93..8e189d26 100644 --- a/Private/DriverKit/KernelString.h +++ b/Private/DriverKit/KernelString.h @@ -10,4 +10,7 @@ #include +/// @brief DriverKit equivalent of POSIX's string.h. + DK_EXTERN size_t kernelStringLength(const char* str); +DK_EXTERN int kernelStringCopy(char* dst, const char* src, size_t len); diff --git a/Private/Drivers/Bonjour/makefile b/Private/Drivers/Bonjour/makefile index b98d9ff9..46edfd2e 100644 --- a/Private/Drivers/Bonjour/makefile +++ b/Private/Drivers/Bonjour/makefile @@ -12,16 +12,6 @@ ADD_FILE=touch COPY=cp HTTP_GET=wget -ifeq ($(shell uname), Windows_NT) -EMU=qemu-system-x86_64w -else -EMU=qemu-system-x86_64 -endif - -IMG=epm.img -IMG_2=epm-slave.img -EMU_FLAGS=-net none -smp 4 -m 4G -M q35 -bios OVMF.fd -device piix3-ide,id=ide -drive id=disk,file=$(IMG),format=raw,if=none -device ide-hd,drive=disk,bus=ide.0 -drive file=fat:rw:CDROM,index=2,format=raw -d int -hdd epm-slave.img - LD_FLAGS=-e __ImageStart --subsystem=17 OBJ=*.o diff --git a/Private/Drivers/MahroussUpdate/DriverRsrc.rsrc b/Private/Drivers/MahroussUpdate/DriverRsrc.rsrc new file mode 100644 index 00000000..359a0875 --- /dev/null +++ b/Private/Drivers/MahroussUpdate/DriverRsrc.rsrc @@ -0,0 +1,25 @@ +1 ICON "../../Root/Boot/Icons/update-logo.ico" + +1 VERSIONINFO +FILEVERSION 1,0,0,0 +PRODUCTVERSION 1,0,0,0 +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "080904E4" + BEGIN + VALUE "CompanyName", "Mahrouss-Logic" + VALUE "FileDescription", "New OS Mahrouss Update driver." + VALUE "FileVersion", "1.00" + VALUE "InternalName", "Mahrouss Update." + VALUE "LegalCopyright", "Copyright Mahrouss-Logic, all rights reserved." + VALUE "OriginalFilename", "MahroussUpdate.exe" + VALUE "ProductName", "MahroussUpdate." + VALUE "ProductVersion", "1.00" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x809, 1252 + END +END diff --git a/Private/Drivers/MahroussUpdate/MahroussUpdate.cc b/Private/Drivers/MahroussUpdate/MahroussUpdate.cc new file mode 100644 index 00000000..c8741ed0 --- /dev/null +++ b/Private/Drivers/MahroussUpdate/MahroussUpdate.cc @@ -0,0 +1,24 @@ +/* ------------------------------------------- + + Copyright Mahrouss Logic + +------------------------------------------- */ + +#include +#include + +#include + +DK_EXTERN int __ImageStart(void) { + kernelPrintStr("Mahrouss Update: Looking for updates...\r\n"); + UpdateRequest req("mup://release-mahrouss.logic/newos/"); + + return 0; +} + +DK_EXTERN int __ImageEnd(void) { + return 0; +} + +///! @brief Use this to check your stack, if using MinGW/MSVC. +DK_EXTERN void ___chkstk_ms(void) {} diff --git a/Private/Drivers/MahroussUpdate/MahroussUpdate.hxx b/Private/Drivers/MahroussUpdate/MahroussUpdate.hxx new file mode 100644 index 00000000..a4f219be --- /dev/null +++ b/Private/Drivers/MahroussUpdate/MahroussUpdate.hxx @@ -0,0 +1,33 @@ +/* ------------------------------------------- + + Copyright Mahrouss Logic + +------------------------------------------- */ + +#pragma once + +#include + +#include "DriverKit/KernelPrint.h" + +/// @file Software update job driver. + +class UpdateRequest; +class UpdateRequestObserver; + +class UpdateRequest { + public: + explicit UpdateRequest(const char* patchUrl = "mup://invalid-url-scheme/") { + kernelStringCopy(this->fPatchUrl, patchUrl, kernelStringLength(patchUrl)); + + kernelPrintStr("Mahrouss Update, Looking at: "); + kernelPrintStr(patchUrl); + kernelPrintChar('\r'); + kernelPrintChar('\n'); + } + + ~UpdateRequest() {} + + private: + char fPatchUrl[4096] = {0}; +}; diff --git a/Private/Drivers/MahroussUpdate/makefile b/Private/Drivers/MahroussUpdate/makefile new file mode 100644 index 00000000..a0673a23 --- /dev/null +++ b/Private/Drivers/MahroussUpdate/makefile @@ -0,0 +1,53 @@ +################################################## +# (C) Mahrouss Logic, all rights reserved. +# This is the sample driver makefile. +################################################## + +CC_GNU=x86_64-w64-mingw32-gcc +LD_GNU=x86_64-w64-mingw32-ld + +WINDRES=x86_64-w64-mingw32-windres + +ADD_FILE=touch +COPY=cp +HTTP_GET=wget + +LD_FLAGS=-e __ImageStart --subsystem=17 + +OBJ=*.o + + +REM=rm +REM_FLAG=-f + +FLAG_ASM=-f win64 +FLAG_GNU=-fshort-wchar -D__EFI_x86_64__ -mgeneral-regs-only -mno-red-zone -D__KERNEL__ -DEFI_FUNCTION_WRAPPER -I../ -I../../ -I./ -c -ffreestanding -D__HAVE_MAHROUSS_APIS__ -D__MAHROUSS__ -D__BOOTLOADER__ -I./ + +.PHONY: invalid-recipe +invalid-recipe: + @echo "invalid-recipe: Use make all instead." + +.PHONY: all +all: compile-amd64 + $(LD_GNU) $(OBJ) $(LD_FLAGS) -o MahroussUpdate.exe + cp MahroussUpdate.exe ../../Root/Boot/MahroussUpdate.exe + +ifneq ($(DEBUG_SUPPORT), ) +DEBUG = -D__DEBUG__ +endif + +.PHONY: compile-amd64 +compile-amd64: + $(WINDRES) DriverRsrc.rsrc -O coff -o DriverRsrc.o + $(CC_GNU) $(FLAG_GNU) -std=c17 $(DEBUG) $(wildcard *.c) $(wildcard ../../DriverKit/*.c) $(wildcard ../../DriverKit/*.s) + $(CC_GNU) $(FLAG_GNU) -std=c++17 -fno-rtti -fno-exceptions $(DEBUG) $(wildcard *.cc) $(wildcard ../../DriverKit/*.cc) + +.PHONY: clean +clean: + $(REM) $(REM_FLAG) $(OBJ) MahroussUpdate.exe + +.PHONY: help +help: + @echo "=== HELP ===" + @echo "clean: Clean driver." + @echo "compile-amd64: Build driver." diff --git a/Private/Drivers/SampleDriver/SampleDriver.c b/Private/Drivers/SampleDriver/SampleDriver.c index 8289fcbc..4481d480 100644 --- a/Private/Drivers/SampleDriver/SampleDriver.c +++ b/Private/Drivers/SampleDriver/SampleDriver.c @@ -16,3 +16,6 @@ int __ImageEnd(void) { kernelPrintStr("SampleDriver: Shutting down...\r\n"); return 0; } + +///! @brief Use this to check your stack, if using MinGW/MSVC. +void ___chkstk_ms(void) {} diff --git a/Private/Drivers/SampleDriver/makefile b/Private/Drivers/SampleDriver/makefile index 2433aa51..cc96c022 100644 --- a/Private/Drivers/SampleDriver/makefile +++ b/Private/Drivers/SampleDriver/makefile @@ -12,16 +12,6 @@ ADD_FILE=touch COPY=cp HTTP_GET=wget -ifeq ($(shell uname), Windows_NT) -EMU=qemu-system-x86_64w -else -EMU=qemu-system-x86_64 -endif - -IMG=epm.img -IMG_2=epm-slave.img -EMU_FLAGS=-net none -smp 4 -m 4G -M q35 -bios OVMF.fd -device piix3-ide,id=ide -drive id=disk,file=$(IMG),format=raw,if=none -device ide-hd,drive=disk,bus=ide.0 -drive file=fat:rw:CDROM,index=2,format=raw -d int -hdd epm-slave.img - LD_FLAGS=-e __ImageStart --subsystem=17 OBJ=*.o diff --git a/Private/Root/Boot/Icons/boot-logo.ico b/Private/Root/Boot/Icons/boot-logo.ico index 3a0258b8..b7a2eba2 100644 Binary files a/Private/Root/Boot/Icons/boot-logo.ico and b/Private/Root/Boot/Icons/boot-logo.ico differ diff --git a/Private/Root/Boot/Icons/update-logo.ico b/Private/Root/Boot/Icons/update-logo.ico new file mode 100644 index 00000000..860194db Binary files /dev/null and b/Private/Root/Boot/Icons/update-logo.ico differ -- cgit v1.2.3