From 610f91d87152cbe48d3054fcf437d8239da6ef35 Mon Sep 17 00:00:00 2001 From: Amlal Date: Sat, 21 Dec 2024 21:59:13 +0100 Subject: IMP: :boom: Breaking changes some checks are needed to be done. Signed-off-by: Amlal --- dev/BootLoader/BootKit/BitManip.h | 20 + dev/BootLoader/BootKit/BootKit.h | 393 ++++++++ dev/BootLoader/BootKit/Device.h | 37 + dev/BootLoader/BootKit/EPM.h | 9 + dev/BootLoader/BootKit/HW/ATA.h | 58 ++ dev/BootLoader/BootKit/HW/SATA.h | 46 + dev/BootLoader/BootKit/Platform.h | 32 + dev/BootLoader/BootKit/Protocol.h | 10 + dev/BootLoader/BootKit/Rsrc/zka_disk.rsrc | 116 +++ dev/BootLoader/BootKit/Rsrc/zka_has_disk.rsrc | 116 +++ dev/BootLoader/BootKit/Rsrc/zka_no_disk.rsrc | 116 +++ dev/BootLoader/BootKit/Support.h | 167 ++++ dev/BootLoader/BootKit/Thread.h | 44 + dev/BootLoader/DownloadOVMF.ps1 | 4 + dev/BootLoader/Modules/.keep | 0 dev/BootLoader/Modules/NetBoot/.hgkeep | 0 dev/BootLoader/Modules/NetBoot/Boot.S | 28 + dev/BootLoader/Modules/NetBoot/Module.cc | 16 + dev/BootLoader/Modules/NetBoot/NetBoot.h | 26 + dev/BootLoader/Modules/NetBoot/build.json | 24 + dev/BootLoader/Modules/SysChk/.hgkeep | 0 dev/BootLoader/Modules/SysChk/Boot.S | 20 + dev/BootLoader/Modules/SysChk/Module.cc | 22 + dev/BootLoader/Modules/SysChk/build.json | 24 + dev/BootLoader/ReadMe.md | 20 + dev/BootLoader/amd64-efi.make | 119 +++ dev/BootLoader/arm64-efi.make | 112 +++ dev/BootLoader/src/.gitkeep | 0 dev/BootLoader/src/BootFileReader.cc | 203 ++++ dev/BootLoader/src/BootString.cc | 92 ++ dev/BootLoader/src/BootSupport.cc | 82 ++ dev/BootLoader/src/BootTextWriter.cc | 169 ++++ dev/BootLoader/src/BootThread.cc | 207 ++++ dev/BootLoader/src/BootloaderRsrc.rsrc | 25 + dev/BootLoader/src/HEL/64X000/.gitkeep | 0 dev/BootLoader/src/HEL/64X000/Boot64x0.S | 35 + dev/BootLoader/src/HEL/AMD64/.gitkeep | 0 dev/BootLoader/src/HEL/AMD64/BootAPI.S | 60 ++ dev/BootLoader/src/HEL/AMD64/BootATA.cc | 278 ++++++ dev/BootLoader/src/HEL/AMD64/BootMain.cc | 326 ++++++ dev/BootLoader/src/HEL/AMD64/BootPlatform.cc | 106 ++ dev/BootLoader/src/HEL/AMD64/BootSATA.cc | 20 + dev/BootLoader/src/HEL/ARM64/.gitkeep | 0 dev/BootLoader/src/HEL/ARM64/BootAPI.S | 12 + dev/BootLoader/src/HEL/ARM64/BootMain.cc | 76 ++ dev/BootLoader/src/HEL/ARM64/BootPlatform.cc | 37 + dev/BootLoader/src/HEL/POWER/.gitkeep | 0 dev/BootLoader/src/HEL/POWER/CoreBootStartup.S | 34 + dev/BootLoader/src/New+Delete.cc | 60 ++ dev/BootLoader/src/Root/EFI/STARTUP.NSH | 2 + dev/BootLoader/src/Root/zka/fntkrnl.ttf | Bin 0 -> 42752 bytes dev/CompressKit/API.h | 2 +- dev/CompressKit/CKCompress.s | 2 +- dev/CompressKit/CKDecompress.s | 2 +- dev/HintKit/CompilerHint.h | 2 +- dev/Kernel/ArchKit/ArchKit.h | 90 ++ dev/Kernel/CFKit/GUIDWizard.h | 24 + dev/Kernel/CFKit/GUIDWrapper.h | 60 ++ dev/Kernel/CFKit/Property.h | 54 + dev/Kernel/CFKit/Utils.h | 55 + dev/Kernel/CompilerKit/CompilerKit.h | 13 + dev/Kernel/CompilerKit/Detail.h | 27 + dev/Kernel/CompilerKit/Version.h | 7 + dev/Kernel/FSKit/Defines.h | 12 + dev/Kernel/FSKit/HPFS.h | 30 + dev/Kernel/FSKit/IndexableProperty.h | 63 ++ dev/Kernel/FSKit/NeFS.h | 402 ++++++++ dev/Kernel/FirmwareKit/.gitkeep | 0 dev/Kernel/FirmwareKit/CoreBoot/CoreBoot.h | 31 + dev/Kernel/FirmwareKit/CoreBoot/NetBoot.h | 9 + dev/Kernel/FirmwareKit/EFI.h | 11 + dev/Kernel/FirmwareKit/EFI/API.h | 114 +++ dev/Kernel/FirmwareKit/EFI/EFI.h | 884 ++++++++++++++++ dev/Kernel/FirmwareKit/EFI/NS.h | 15 + dev/Kernel/FirmwareKit/EPM.h | 112 +++ dev/Kernel/FirmwareKit/GPT.h | 48 + dev/Kernel/FirmwareKit/Handover.h | 110 ++ dev/Kernel/HALKit/.gitkeep | 0 dev/Kernel/HALKit/64x0/.hgkeep | 0 dev/Kernel/HALKit/64x0/APM/.hgkeep | 0 dev/Kernel/HALKit/64x0/HalVirtualMemory.cc | 17 + dev/Kernel/HALKit/64x0/MBCI/.gitkeep | 0 dev/Kernel/HALKit/64x0/ReadMe.md | 4 + dev/Kernel/HALKit/AMD64/CPUID.h | 86 ++ dev/Kernel/HALKit/AMD64/HalACPIFactoryInterface.cc | 126 +++ dev/Kernel/HALKit/AMD64/HalAP.cc | 51 + dev/Kernel/HALKit/AMD64/HalAPICController.cc | 39 + dev/Kernel/HALKit/AMD64/HalBoot.asm | 28 + dev/Kernel/HALKit/AMD64/HalCPUAMD64.cc | 101 ++ dev/Kernel/HALKit/AMD64/HalCommonAPI.asm | 53 + dev/Kernel/HALKit/AMD64/HalControlRegister.s | 45 + .../HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc | 232 +++++ dev/Kernel/HALKit/AMD64/HalCoreScheduler.cc | 240 +++++ dev/Kernel/HALKit/AMD64/HalDebugOutput.cc | 146 +++ dev/Kernel/HALKit/AMD64/HalDebugPort.cc | 40 + dev/Kernel/HALKit/AMD64/HalDescriptorLoader.cc | 126 +++ dev/Kernel/HALKit/AMD64/HalInterruptAPI.asm | 406 ++++++++ dev/Kernel/HALKit/AMD64/HalKernelMain.cc | 103 ++ dev/Kernel/HALKit/AMD64/HalPagingMgrAMD64.cc | 168 ++++ dev/Kernel/HALKit/AMD64/HalRoutineWait.s | 11 + dev/Kernel/HALKit/AMD64/HalTimerAMD64.cc | 86 ++ dev/Kernel/HALKit/AMD64/HalUtils.asm | 27 + dev/Kernel/HALKit/AMD64/Hypervisor.h | 25 + dev/Kernel/HALKit/AMD64/MBCI/HalMBCI.cc | 7 + dev/Kernel/HALKit/AMD64/PCI/DMA.cc | 82 ++ dev/Kernel/HALKit/AMD64/PCI/Database.cc | 11 + dev/Kernel/HALKit/AMD64/PCI/Device.cc | 139 +++ dev/Kernel/HALKit/AMD64/PCI/Express.cc | 11 + dev/Kernel/HALKit/AMD64/PCI/IO.cc | 7 + dev/Kernel/HALKit/AMD64/PCI/Iterator.cc | 41 + dev/Kernel/HALKit/AMD64/PCI/PCI.cc | 7 + dev/Kernel/HALKit/AMD64/Paging.h | 99 ++ dev/Kernel/HALKit/AMD64/Processor.h | 331 ++++++ dev/Kernel/HALKit/AMD64/ReadMe.md | 8 + dev/Kernel/HALKit/AMD64/Storage/AHCI-DMA.cc | 319 ++++++ dev/Kernel/HALKit/AMD64/Storage/ATA-DMA.cc | 38 + dev/Kernel/HALKit/AMD64/Storage/ATA-PIO.cc | 197 ++++ dev/Kernel/HALKit/ARM64/.gitkeep | 0 dev/Kernel/HALKit/ARM64/AP.h | 36 + dev/Kernel/HALKit/ARM64/APM/.gitkeep | 0 dev/Kernel/HALKit/ARM64/APM/APM.cc | 37 + dev/Kernel/HALKit/ARM64/HalACPIFactoryInterface.cc | 31 + dev/Kernel/HALKit/ARM64/HalAP.cc | 40 + dev/Kernel/HALKit/ARM64/HalCoreMPScheduler.cc | 28 + dev/Kernel/HALKit/ARM64/HalDebugOutput.cc | 83 ++ dev/Kernel/HALKit/ARM64/HalKernelMain.cc | 57 ++ dev/Kernel/HALKit/ARM64/HalPageInternal.S | 5 + dev/Kernel/HALKit/ARM64/HalPagingMgrARM64.cc | 86 ++ dev/Kernel/HALKit/ARM64/HalSchedulerCore.cc | 34 + dev/Kernel/HALKit/ARM64/HalSchedulerCoreARM64.cc | 40 + dev/Kernel/HALKit/ARM64/HalTimerARM64.cc | 14 + dev/Kernel/HALKit/ARM64/MBCI/.keepme | 0 dev/Kernel/HALKit/ARM64/Paging.h | 120 +++ dev/Kernel/HALKit/ARM64/Processor.h | 75 ++ dev/Kernel/HALKit/ARM64/ReadMe.md | 3 + dev/Kernel/HALKit/ARM64/Storage/.gitkeep | 0 dev/Kernel/HALKit/ARM64/Storage/HalFlash.cc | 66 ++ dev/Kernel/HALKit/AXP/CR.s | 11 + dev/Kernel/HALKit/AXP/CoreInterruptHandlerDEC.cpp | 0 dev/Kernel/HALKit/AXP/CoreSyscallHandlerDEC.cpp | 24 + dev/Kernel/HALKit/AXP/HAL.s | 13 + dev/Kernel/HALKit/AXP/Processor.h | 7 + dev/Kernel/HALKit/AXP/README | 1 + dev/Kernel/HALKit/AXP/README.TXT | 1 + dev/Kernel/HALKit/AXP/SYSCALL.s | 10 + dev/Kernel/HALKit/AXP/VM.s | 5 + dev/Kernel/HALKit/POWER/.gitkeep | 0 dev/Kernel/HALKit/POWER/AP.h | 39 + dev/Kernel/HALKit/POWER/APM/.gitkeep | 0 dev/Kernel/HALKit/POWER/HalAP.cc | 40 + dev/Kernel/HALKit/POWER/HalDebugOutput.cc | 27 + dev/Kernel/HALKit/POWER/HalStartSequence.s | 14 + dev/Kernel/HALKit/POWER/HalThread.cc | 8 + dev/Kernel/HALKit/POWER/HalVirtualMemory.cc | 49 + dev/Kernel/HALKit/POWER/MBCI/.gitkeep | 0 dev/Kernel/HALKit/POWER/MBCI/HalMBCIHost.cc | 8 + dev/Kernel/HALKit/POWER/Processor.h | 62 ++ dev/Kernel/HALKit/POWER/ReadMe.md | 4 + dev/Kernel/HALKit/RISCV/.keep | 0 dev/Kernel/HALKit/RISCV/AP.h | 36 + dev/Kernel/HALKit/RISCV/APM/.gitkeep | 0 dev/Kernel/HALKit/RISCV/HalAP.cc | 40 + dev/Kernel/HALKit/RISCV/ReadMe.md | 4 + dev/Kernel/HALKit/RISCV/Storage/.gitkeep | 0 dev/Kernel/HALKit/X86S/.gitkeep | 0 dev/Kernel/HALKit/X86S/ACPI/.gitkeep | 0 dev/Kernel/HALKit/X86S/Storage/.gitkeep | 0 dev/Kernel/KernelKit/CodeMgr.h | 37 + dev/Kernel/KernelKit/DebugOutput.h | 198 ++++ dev/Kernel/KernelKit/Defines.h | 15 + dev/Kernel/KernelKit/DeviceMgr.h | 140 +++ dev/Kernel/KernelKit/DriveMgr.h | 169 ++++ dev/Kernel/KernelKit/FileMgr.h | 427 ++++++++ dev/Kernel/KernelKit/HardwareThreadScheduler.h | 149 +++ dev/Kernel/KernelKit/Heap.h | 86 ++ dev/Kernel/KernelKit/IDLLObject.h | 48 + dev/Kernel/KernelKit/IPEFDLLObject.h | 106 ++ dev/Kernel/KernelKit/LPC.h | 69 ++ dev/Kernel/KernelKit/LoaderInterface.h | 34 + dev/Kernel/KernelKit/LockDelegate.h | 69 ++ dev/Kernel/KernelKit/MSDOS.h | 52 + dev/Kernel/KernelKit/PCI/DMA.h | 81 ++ dev/Kernel/KernelKit/PCI/DMA.inl | 20 + dev/Kernel/KernelKit/PCI/Database.h | 38 + dev/Kernel/KernelKit/PCI/Device.h | 80 ++ dev/Kernel/KernelKit/PCI/Express.h | 11 + dev/Kernel/KernelKit/PCI/IO-Impl-AMD64.inl | 54 + dev/Kernel/KernelKit/PCI/IO.h | 59 ++ dev/Kernel/KernelKit/PCI/Iterator.h | 43 + dev/Kernel/KernelKit/PCI/PCI.h | 59 ++ dev/Kernel/KernelKit/PE.h | 143 +++ dev/Kernel/KernelKit/PECodeMgr.h | 24 + dev/Kernel/KernelKit/PEF.h | 117 +++ dev/Kernel/KernelKit/PEFCodeMgr.h | 72 ++ dev/Kernel/KernelKit/Semaphore.h | 43 + dev/Kernel/KernelKit/ThreadLocalStorage.h | 65 ++ dev/Kernel/KernelKit/ThreadLocalStorage.inl | 99 ++ dev/Kernel/KernelKit/Timer.h | 82 ++ dev/Kernel/KernelKit/User.h | 83 ++ dev/Kernel/KernelKit/UserProcessScheduler.h | 338 +++++++ dev/Kernel/KernelKit/UserProcessScheduler.inl | 40 + dev/Kernel/KernelKit/XCOFF.h | 51 + dev/Kernel/KernelRsrc.rsrc | 25 + dev/Kernel/MoveAll.ARM64.sh | 7 + dev/Kernel/MoveAll.X64.sh | 7 + dev/Kernel/NetworkKit/IP.h | 83 ++ dev/Kernel/NetworkKit/IPC.h | 107 ++ dev/Kernel/NetworkKit/LTE.h | 16 + dev/Kernel/NetworkKit/MAC.h | 29 + dev/Kernel/NetworkKit/NetworkDevice.h | 83 ++ dev/Kernel/NetworkKit/NetworkDevice.inl | 32 + dev/Kernel/NewKit/Array.h | 72 ++ dev/Kernel/NewKit/ArrayList.h | 58 ++ dev/Kernel/NewKit/Atom.h | 46 + dev/Kernel/NewKit/Crc32.h | 23 + dev/Kernel/NewKit/CxxAbi.h | 28 + dev/Kernel/NewKit/Defines.h | 186 ++++ dev/Kernel/NewKit/ErrorOr.h | 77 ++ dev/Kernel/NewKit/Function.h | 53 + dev/Kernel/NewKit/Json.h | 151 +++ dev/Kernel/NewKit/KString.h | 94 ++ dev/Kernel/NewKit/Macros.h | 149 +++ dev/Kernel/NewKit/MutableArray.h | 239 +++++ dev/Kernel/NewKit/New.h | 18 + dev/Kernel/NewKit/NewKit.h | 20 + dev/Kernel/NewKit/OwnPtr.h | 94 ++ dev/Kernel/NewKit/PageMgr.h | 81 ++ dev/Kernel/NewKit/Pair.h | 14 + dev/Kernel/NewKit/Pmm.h | 44 + dev/Kernel/NewKit/Ref.h | 108 ++ dev/Kernel/NewKit/Stop.h | 71 ++ dev/Kernel/NewKit/Stream.h | 58 ++ dev/Kernel/NewKit/Utils.h | 29 + dev/Kernel/NewKit/Variant.h | 70 ++ dev/Kernel/POSIXKit/signal.h | 20 + dev/Kernel/POSIXKit/unix_layer.h | 11 + dev/Kernel/ReadMe.md | 3 + dev/Kernel/StorageKit/AHCI.h | 33 + dev/Kernel/StorageKit/ATA.h | 39 + dev/Kernel/StorageKit/NVME.h | 34 + dev/Kernel/StorageKit/PRDT.h | 36 + dev/Kernel/StorageKit/SCSI.h | 11 + dev/Kernel/StorageKit/StorageKit.h | 22 + dev/Kernel/amd64-efi.make | 85 ++ dev/Kernel/arm64-efi.make | 64 ++ dev/Kernel/doc/Explicit Partition Map.pdf | Bin 0 -> 12364 bytes dev/Kernel/doc/SPECIFICATION.md | 63 ++ dev/Kernel/doc/TODO-LIST.md | 25 + dev/Kernel/obj/.hgkeep | 0 dev/Kernel/power64-cb.make | 4 + dev/Kernel/riscv64-cb.make | 0 dev/Kernel/src/ACPIFactoryInterface.cc | 96 ++ dev/Kernel/src/Array.cc | 7 + dev/Kernel/src/ArrayList.cc | 7 + dev/Kernel/src/Atom.cc | 10 + dev/Kernel/src/BitMapMgr.cc | 185 ++++ dev/Kernel/src/CodeMgr.cc | 38 + dev/Kernel/src/Crc32.cc | 83 ++ dev/Kernel/src/CxxAbi-AMD64.cc | 90 ++ dev/Kernel/src/CxxAbi-ARM64.cc | 107 ++ dev/Kernel/src/Defines.cc | 7 + dev/Kernel/src/DeviceMgr.cc | 7 + dev/Kernel/src/DriveMgr.cc | 221 ++++ dev/Kernel/src/ErrorOr.cc | 12 + dev/Kernel/src/FS/HPFS.cc | 22 + dev/Kernel/src/FS/NeFS.cc | 1054 ++++++++++++++++++++ dev/Kernel/src/FileMgr.cc | 52 + dev/Kernel/src/GUIDWizard.cc | 72 ++ dev/Kernel/src/GUIDWrapper.cc | 11 + dev/Kernel/src/HardwareThreadScheduler.cc | 238 +++++ dev/Kernel/src/Heap.cc | 307 ++++++ dev/Kernel/src/IDLLObject.cc | 15 + dev/Kernel/src/IPEFDLLObject.cc | 103 ++ dev/Kernel/src/IndexableProperty.cc | 57 ++ dev/Kernel/src/Json.cc | 10 + dev/Kernel/src/KString.cc | 217 ++++ dev/Kernel/src/KernelMain.cc | 126 +++ dev/Kernel/src/LPC.cc | 34 + dev/Kernel/src/LockDelegate.cc | 12 + dev/Kernel/src/MutableArray.cc | 7 + dev/Kernel/src/NeFS+FileMgr.cc | 249 +++++ dev/Kernel/src/NeFS+IO.cc | 101 ++ dev/Kernel/src/Network/IP.cc | 126 +++ dev/Kernel/src/Network/IPC.cc | 111 +++ dev/Kernel/src/Network/NetworkDevice.cc | 35 + dev/Kernel/src/New+Delete.cc | 50 + dev/Kernel/src/OwnPtr.cc | 7 + dev/Kernel/src/PEFCodeMgr.cc | 284 ++++++ dev/Kernel/src/PRDT.cc | 24 + dev/Kernel/src/PageMgr.cc | 110 ++ dev/Kernel/src/Pmm.cc | 98 ++ dev/Kernel/src/Property.cc | 45 + dev/Kernel/src/Ref.cc | 7 + dev/Kernel/src/Semaphore.cc | 72 ++ dev/Kernel/src/Stop.cc | 130 +++ dev/Kernel/src/Storage/AHCIDeviceInterface.cc | 35 + dev/Kernel/src/Storage/ATADeviceInterface.cc | 88 ++ dev/Kernel/src/Storage/NVMEDeviceInterface.cc | 28 + dev/Kernel/src/Storage/SCSIDeviceInterface.cc | 11 + dev/Kernel/src/Stream.cc | 12 + dev/Kernel/src/ThreadLocalStorage.cc | 67 ++ dev/Kernel/src/Timer.cc | 47 + dev/Kernel/src/User.cc | 178 ++++ dev/Kernel/src/UserProcessScheduler.cc | 582 +++++++++++ dev/Kernel/src/UserProcessTeam.cc | 55 + dev/Kernel/src/Utils.cc | 223 +++++ dev/Kernel/src/Variant.cc | 33 + dev/Modules/ACPI/ACPI.h | 2 +- dev/Modules/ACPI/ACPIFactoryInterface.h | 2 +- dev/Modules/AHCI/AHCI.h | 2 +- dev/Modules/APM/APM.h | 2 +- dev/Modules/ATA/ATA.h | 2 +- dev/Modules/FB/FB.h | 2 +- dev/Modules/FB/Text.h | 2 +- dev/Modules/Flash/Flash.h | 2 +- dev/Modules/HPET/Defines.h | 2 +- dev/Modules/LTE/LTE.h | 2 +- dev/Modules/MBCI/Interface.h | 2 +- dev/Modules/MBCI/MBCI.h | 2 +- dev/Modules/NVME/NVME.h | 2 +- dev/Modules/ReadMe.md | 2 +- dev/Modules/SCSI/SCSI.h | 2 +- dev/Modules/XHCI/Defines.h | 2 +- dev/SCIKit/CompilerHint.h | 2 +- dev/SCIKit/GPU.h | 2 +- dev/SCIKit/LPC.h | 2 +- dev/SCIKit/Macros.h | 2 +- dev/SCIKit/SCI.h | 2 +- dev/SCIKit/SysCalls.h | 2 +- dev/SCIKit/src/GPU.cc | 2 +- dev/SCIKit/src/LPC.cc | 2 +- dev/SCIKit/src/Makefile | 13 +- dev/SCIKit/src/SCI+IO.asm | 50 + dev/SCIKit/src/SCI.cc | 2 +- dev/SCIKit/src/SysCallDispatcher.asm | 50 - dev/ZBAKit/BootKit/BitManip.h | 20 - dev/ZBAKit/BootKit/BootKit.h | 393 -------- dev/ZBAKit/BootKit/Device.h | 37 - dev/ZBAKit/BootKit/EPM.h | 9 - dev/ZBAKit/BootKit/HW/ATA.h | 58 -- dev/ZBAKit/BootKit/HW/SATA.h | 46 - dev/ZBAKit/BootKit/Platform.h | 32 - dev/ZBAKit/BootKit/Protocol.h | 10 - dev/ZBAKit/BootKit/Rsrc/zka_disk.rsrc | 116 --- dev/ZBAKit/BootKit/Rsrc/zka_has_disk.rsrc | 116 --- dev/ZBAKit/BootKit/Rsrc/zka_no_disk.rsrc | 116 --- dev/ZBAKit/BootKit/Support.h | 167 ---- dev/ZBAKit/BootKit/Thread.h | 44 - dev/ZBAKit/DownloadOVMF.ps1 | 4 - dev/ZBAKit/Modules/.keep | 0 dev/ZBAKit/Modules/NetBoot/.hgkeep | 0 dev/ZBAKit/Modules/NetBoot/Boot.S | 28 - dev/ZBAKit/Modules/NetBoot/Module.cc | 16 - dev/ZBAKit/Modules/NetBoot/NetBoot.h | 26 - dev/ZBAKit/Modules/NetBoot/build.json | 24 - dev/ZBAKit/Modules/SysChk/.hgkeep | 0 dev/ZBAKit/Modules/SysChk/Boot.S | 20 - dev/ZBAKit/Modules/SysChk/Module.cc | 22 - dev/ZBAKit/Modules/SysChk/build.json | 24 - dev/ZBAKit/ReadMe.md | 20 - dev/ZBAKit/amd64-efi.make | 119 --- dev/ZBAKit/arm64-efi.make | 112 --- dev/ZBAKit/src/.gitkeep | 0 dev/ZBAKit/src/BootFileReader.cc | 203 ---- dev/ZBAKit/src/BootString.cc | 92 -- dev/ZBAKit/src/BootSupport.cc | 82 -- dev/ZBAKit/src/BootTextWriter.cc | 169 ---- dev/ZBAKit/src/BootThread.cc | 207 ---- dev/ZBAKit/src/BootloaderRsrc.rsrc | 25 - dev/ZBAKit/src/HEL/64X000/.gitkeep | 0 dev/ZBAKit/src/HEL/64X000/Boot64x0.S | 35 - dev/ZBAKit/src/HEL/AMD64/.gitkeep | 0 dev/ZBAKit/src/HEL/AMD64/BootAPI.S | 60 -- dev/ZBAKit/src/HEL/AMD64/BootATA.cc | 278 ------ dev/ZBAKit/src/HEL/AMD64/BootMain.cc | 337 ------- dev/ZBAKit/src/HEL/AMD64/BootPlatform.cc | 106 -- dev/ZBAKit/src/HEL/AMD64/BootSATA.cc | 20 - dev/ZBAKit/src/HEL/ARM64/.gitkeep | 0 dev/ZBAKit/src/HEL/ARM64/BootAPI.S | 12 - dev/ZBAKit/src/HEL/ARM64/BootMain.cc | 76 -- dev/ZBAKit/src/HEL/ARM64/BootPlatform.cc | 37 - dev/ZBAKit/src/HEL/POWER/.gitkeep | 0 dev/ZBAKit/src/HEL/POWER/CoreBootStartup.S | 34 - dev/ZBAKit/src/New+Delete.cc | 60 -- dev/ZBAKit/src/Root/EFI/STARTUP.NSH | 2 - dev/ZBAKit/src/Root/zka/startup.wav | Bin 1045048 -> 0 bytes dev/ZBAKit/src/Root/zka/urbanist.ttf | Bin 42752 -> 0 bytes dev/ZKAKit/ArchKit/ArchKit.h | 90 -- dev/ZKAKit/CFKit/GUIDWizard.h | 24 - dev/ZKAKit/CFKit/GUIDWrapper.h | 60 -- dev/ZKAKit/CFKit/Property.h | 54 - dev/ZKAKit/CFKit/Utils.h | 55 - dev/ZKAKit/CompilerKit/CompilerKit.h | 13 - dev/ZKAKit/CompilerKit/Detail.h | 27 - dev/ZKAKit/CompilerKit/Version.h | 7 - dev/ZKAKit/FSKit/Defines.h | 12 - dev/ZKAKit/FSKit/HPFS.h | 30 - dev/ZKAKit/FSKit/IndexableProperty.h | 63 -- dev/ZKAKit/FSKit/NeFS.h | 402 -------- dev/ZKAKit/FirmwareKit/.gitkeep | 0 dev/ZKAKit/FirmwareKit/CoreBoot/CoreBoot.h | 31 - dev/ZKAKit/FirmwareKit/CoreBoot/NetBoot.h | 9 - dev/ZKAKit/FirmwareKit/EFI.h | 11 - dev/ZKAKit/FirmwareKit/EFI/API.h | 114 --- dev/ZKAKit/FirmwareKit/EFI/EFI.h | 884 ---------------- dev/ZKAKit/FirmwareKit/EFI/NS.h | 15 - dev/ZKAKit/FirmwareKit/EPM.h | 122 --- dev/ZKAKit/FirmwareKit/GPT.h | 48 - dev/ZKAKit/FirmwareKit/Handover.h | 112 --- dev/ZKAKit/HALKit/.gitkeep | 0 dev/ZKAKit/HALKit/64x0/.hgkeep | 0 dev/ZKAKit/HALKit/64x0/APM/.hgkeep | 0 dev/ZKAKit/HALKit/64x0/HalVirtualMemory.cc | 17 - dev/ZKAKit/HALKit/64x0/MBCI/.gitkeep | 0 dev/ZKAKit/HALKit/64x0/ReadMe.md | 4 - dev/ZKAKit/HALKit/AMD64/CPUID.h | 86 -- dev/ZKAKit/HALKit/AMD64/HalACPIFactoryInterface.cc | 126 --- dev/ZKAKit/HALKit/AMD64/HalAP.cc | 51 - dev/ZKAKit/HALKit/AMD64/HalAPICController.cc | 39 - dev/ZKAKit/HALKit/AMD64/HalBoot.asm | 28 - dev/ZKAKit/HALKit/AMD64/HalCPUAMD64.cc | 101 -- dev/ZKAKit/HALKit/AMD64/HalCommonAPI.asm | 53 - dev/ZKAKit/HALKit/AMD64/HalControlRegister.s | 45 - .../HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc | 232 ----- dev/ZKAKit/HALKit/AMD64/HalCoreScheduler.cc | 240 ----- dev/ZKAKit/HALKit/AMD64/HalDebugOutput.cc | 146 --- dev/ZKAKit/HALKit/AMD64/HalDebugPort.cc | 40 - dev/ZKAKit/HALKit/AMD64/HalDescriptorLoader.cc | 126 --- dev/ZKAKit/HALKit/AMD64/HalInterruptAPI.asm | 406 -------- dev/ZKAKit/HALKit/AMD64/HalKernelMain.cc | 103 -- dev/ZKAKit/HALKit/AMD64/HalPagingMgrAMD64.cc | 168 ---- dev/ZKAKit/HALKit/AMD64/HalRoutineWait.s | 11 - dev/ZKAKit/HALKit/AMD64/HalTimerAMD64.cc | 86 -- dev/ZKAKit/HALKit/AMD64/HalUtils.asm | 27 - dev/ZKAKit/HALKit/AMD64/Hypervisor.h | 25 - dev/ZKAKit/HALKit/AMD64/MBCI/HalMBCI.cc | 7 - dev/ZKAKit/HALKit/AMD64/PCI/DMA.cc | 82 -- dev/ZKAKit/HALKit/AMD64/PCI/Database.cc | 11 - dev/ZKAKit/HALKit/AMD64/PCI/Device.cc | 139 --- dev/ZKAKit/HALKit/AMD64/PCI/Express.cc | 11 - dev/ZKAKit/HALKit/AMD64/PCI/IO.cc | 7 - dev/ZKAKit/HALKit/AMD64/PCI/Iterator.cc | 41 - dev/ZKAKit/HALKit/AMD64/PCI/PCI.cc | 7 - dev/ZKAKit/HALKit/AMD64/Paging.h | 99 -- dev/ZKAKit/HALKit/AMD64/Processor.h | 331 ------ dev/ZKAKit/HALKit/AMD64/ReadMe.md | 8 - dev/ZKAKit/HALKit/AMD64/Storage/AHCI-DMA.cc | 319 ------ dev/ZKAKit/HALKit/AMD64/Storage/ATA-DMA.cc | 38 - dev/ZKAKit/HALKit/AMD64/Storage/ATA-PIO.cc | 197 ---- dev/ZKAKit/HALKit/ARM64/.gitkeep | 0 dev/ZKAKit/HALKit/ARM64/AP.h | 36 - dev/ZKAKit/HALKit/ARM64/APM/.gitkeep | 0 dev/ZKAKit/HALKit/ARM64/APM/APM.cc | 37 - dev/ZKAKit/HALKit/ARM64/HalACPIFactoryInterface.cc | 31 - dev/ZKAKit/HALKit/ARM64/HalAP.cc | 40 - dev/ZKAKit/HALKit/ARM64/HalCoreMPScheduler.cc | 28 - dev/ZKAKit/HALKit/ARM64/HalDebugOutput.cc | 83 -- dev/ZKAKit/HALKit/ARM64/HalKernelMain.cc | 57 -- dev/ZKAKit/HALKit/ARM64/HalPageInternal.S | 5 - dev/ZKAKit/HALKit/ARM64/HalPagingMgrARM64.cc | 86 -- dev/ZKAKit/HALKit/ARM64/HalSchedulerCore.cc | 34 - dev/ZKAKit/HALKit/ARM64/HalSchedulerCoreARM64.cc | 40 - dev/ZKAKit/HALKit/ARM64/HalTimerARM64.cc | 14 - dev/ZKAKit/HALKit/ARM64/MBCI/.keepme | 0 dev/ZKAKit/HALKit/ARM64/Paging.h | 120 --- dev/ZKAKit/HALKit/ARM64/Processor.h | 75 -- dev/ZKAKit/HALKit/ARM64/ReadMe.md | 3 - dev/ZKAKit/HALKit/ARM64/Storage/.gitkeep | 0 dev/ZKAKit/HALKit/ARM64/Storage/HalFlash.cc | 66 -- dev/ZKAKit/HALKit/AXP/CR.s | 11 - dev/ZKAKit/HALKit/AXP/CoreInterruptHandlerDEC.cpp | 0 dev/ZKAKit/HALKit/AXP/CoreSyscallHandlerDEC.cpp | 24 - dev/ZKAKit/HALKit/AXP/HAL.s | 13 - dev/ZKAKit/HALKit/AXP/Processor.h | 7 - dev/ZKAKit/HALKit/AXP/README | 1 - dev/ZKAKit/HALKit/AXP/README.TXT | 1 - dev/ZKAKit/HALKit/AXP/SYSCALL.s | 10 - dev/ZKAKit/HALKit/AXP/VM.s | 5 - dev/ZKAKit/HALKit/POWER/.gitkeep | 0 dev/ZKAKit/HALKit/POWER/AP.h | 39 - dev/ZKAKit/HALKit/POWER/APM/.gitkeep | 0 dev/ZKAKit/HALKit/POWER/HalAP.cc | 40 - dev/ZKAKit/HALKit/POWER/HalDebugOutput.cc | 27 - dev/ZKAKit/HALKit/POWER/HalStartSequence.s | 14 - dev/ZKAKit/HALKit/POWER/HalThread.cc | 8 - dev/ZKAKit/HALKit/POWER/HalVirtualMemory.cc | 49 - dev/ZKAKit/HALKit/POWER/MBCI/.gitkeep | 0 dev/ZKAKit/HALKit/POWER/MBCI/HalMBCIHost.cc | 8 - dev/ZKAKit/HALKit/POWER/Processor.h | 62 -- dev/ZKAKit/HALKit/POWER/ReadMe.md | 4 - dev/ZKAKit/HALKit/RISCV/.keep | 0 dev/ZKAKit/HALKit/RISCV/AP.h | 36 - dev/ZKAKit/HALKit/RISCV/APM/.gitkeep | 0 dev/ZKAKit/HALKit/RISCV/HalAP.cc | 40 - dev/ZKAKit/HALKit/RISCV/ReadMe.md | 4 - dev/ZKAKit/HALKit/RISCV/Storage/.gitkeep | 0 dev/ZKAKit/HALKit/X86S/.gitkeep | 0 dev/ZKAKit/HALKit/X86S/ACPI/.gitkeep | 0 dev/ZKAKit/HALKit/X86S/Storage/.gitkeep | 0 dev/ZKAKit/KernelKit/CodeMgr.h | 37 - dev/ZKAKit/KernelKit/DebugOutput.h | 198 ---- dev/ZKAKit/KernelKit/Defines.h | 15 - dev/ZKAKit/KernelKit/DeviceMgr.h | 140 --- dev/ZKAKit/KernelKit/DriveMgr.h | 169 ---- dev/ZKAKit/KernelKit/FileMgr.h | 427 -------- dev/ZKAKit/KernelKit/HardwareThreadScheduler.h | 149 --- dev/ZKAKit/KernelKit/Heap.h | 86 -- dev/ZKAKit/KernelKit/IDLLObject.h | 48 - dev/ZKAKit/KernelKit/IPEFDLLObject.h | 106 -- dev/ZKAKit/KernelKit/LPC.h | 69 -- dev/ZKAKit/KernelKit/LoaderInterface.h | 34 - dev/ZKAKit/KernelKit/LockDelegate.h | 69 -- dev/ZKAKit/KernelKit/MSDOS.h | 52 - dev/ZKAKit/KernelKit/PCI/DMA.h | 81 -- dev/ZKAKit/KernelKit/PCI/DMA.inl | 20 - dev/ZKAKit/KernelKit/PCI/Database.h | 38 - dev/ZKAKit/KernelKit/PCI/Device.h | 80 -- dev/ZKAKit/KernelKit/PCI/Express.h | 11 - dev/ZKAKit/KernelKit/PCI/IO-Impl-AMD64.inl | 54 - dev/ZKAKit/KernelKit/PCI/IO.h | 59 -- dev/ZKAKit/KernelKit/PCI/Iterator.h | 43 - dev/ZKAKit/KernelKit/PCI/PCI.h | 59 -- dev/ZKAKit/KernelKit/PE.h | 143 --- dev/ZKAKit/KernelKit/PECodeMgr.h | 24 - dev/ZKAKit/KernelKit/PEF.h | 117 --- dev/ZKAKit/KernelKit/PEFCodeMgr.h | 72 -- dev/ZKAKit/KernelKit/Semaphore.h | 43 - dev/ZKAKit/KernelKit/ThreadLocalStorage.h | 65 -- dev/ZKAKit/KernelKit/ThreadLocalStorage.inl | 99 -- dev/ZKAKit/KernelKit/Timer.h | 82 -- dev/ZKAKit/KernelKit/User.h | 83 -- dev/ZKAKit/KernelKit/UserProcessScheduler.h | 338 ------- dev/ZKAKit/KernelKit/UserProcessScheduler.inl | 40 - dev/ZKAKit/KernelKit/XCOFF.h | 51 - dev/ZKAKit/KernelRsrc.rsrc | 25 - dev/ZKAKit/MoveAll.ARM64.sh | 7 - dev/ZKAKit/MoveAll.X64.sh | 7 - dev/ZKAKit/NetworkKit/IP.h | 83 -- dev/ZKAKit/NetworkKit/IPC.h | 107 -- dev/ZKAKit/NetworkKit/LTE.h | 16 - dev/ZKAKit/NetworkKit/MAC.h | 29 - dev/ZKAKit/NetworkKit/NetworkDevice.h | 83 -- dev/ZKAKit/NetworkKit/NetworkDevice.inl | 32 - dev/ZKAKit/NewKit/Array.h | 72 -- dev/ZKAKit/NewKit/ArrayList.h | 58 -- dev/ZKAKit/NewKit/Atom.h | 46 - dev/ZKAKit/NewKit/Crc32.h | 23 - dev/ZKAKit/NewKit/CxxAbi.h | 28 - dev/ZKAKit/NewKit/Defines.h | 186 ---- dev/ZKAKit/NewKit/ErrorOr.h | 77 -- dev/ZKAKit/NewKit/Function.h | 53 - dev/ZKAKit/NewKit/Json.h | 151 --- dev/ZKAKit/NewKit/KString.h | 94 -- dev/ZKAKit/NewKit/Macros.h | 149 --- dev/ZKAKit/NewKit/MutableArray.h | 239 ----- dev/ZKAKit/NewKit/New.h | 18 - dev/ZKAKit/NewKit/NewKit.h | 20 - dev/ZKAKit/NewKit/OwnPtr.h | 94 -- dev/ZKAKit/NewKit/PageMgr.h | 81 -- dev/ZKAKit/NewKit/Pair.h | 14 - dev/ZKAKit/NewKit/Pmm.h | 44 - dev/ZKAKit/NewKit/Ref.h | 108 -- dev/ZKAKit/NewKit/Stop.h | 71 -- dev/ZKAKit/NewKit/Stream.h | 58 -- dev/ZKAKit/NewKit/Utils.h | 29 - dev/ZKAKit/NewKit/Variant.h | 70 -- dev/ZKAKit/POSIXKit/signal.h | 20 - dev/ZKAKit/POSIXKit/unix_layer.h | 11 - dev/ZKAKit/ReadMe.md | 3 - dev/ZKAKit/StorageKit/AHCI.h | 33 - dev/ZKAKit/StorageKit/ATA.h | 39 - dev/ZKAKit/StorageKit/NVME.h | 34 - dev/ZKAKit/StorageKit/PRDT.h | 36 - dev/ZKAKit/StorageKit/SCSI.h | 11 - dev/ZKAKit/StorageKit/StorageKit.h | 22 - dev/ZKAKit/amd64-efi.make | 85 -- dev/ZKAKit/arm64-efi.make | 64 -- dev/ZKAKit/doc/Explicit Partition Map.pdf | Bin 12364 -> 0 bytes dev/ZKAKit/doc/SPECIFICATION.md | 63 -- dev/ZKAKit/doc/TODO-LIST.md | 25 - dev/ZKAKit/obj/.hgkeep | 0 dev/ZKAKit/power64-cb.make | 4 - dev/ZKAKit/riscv64-cb.make | 0 dev/ZKAKit/src/ACPIFactoryInterface.cc | 96 -- dev/ZKAKit/src/Array.cc | 7 - dev/ZKAKit/src/ArrayList.cc | 7 - dev/ZKAKit/src/Atom.cc | 10 - dev/ZKAKit/src/BitMapMgr.cc | 185 ---- dev/ZKAKit/src/CodeMgr.cc | 38 - dev/ZKAKit/src/Crc32.cc | 83 -- dev/ZKAKit/src/CxxAbi-AMD64.cc | 90 -- dev/ZKAKit/src/CxxAbi-ARM64.cc | 107 -- dev/ZKAKit/src/Defines.cc | 7 - dev/ZKAKit/src/DeviceMgr.cc | 7 - dev/ZKAKit/src/DriveMgr.cc | 219 ---- dev/ZKAKit/src/ErrorOr.cc | 12 - dev/ZKAKit/src/FS/HPFS.cc | 22 - dev/ZKAKit/src/FS/NeFS.cc | 1054 -------------------- dev/ZKAKit/src/FileMgr.cc | 52 - dev/ZKAKit/src/GUIDWizard.cc | 72 -- dev/ZKAKit/src/GUIDWrapper.cc | 11 - dev/ZKAKit/src/HardwareThreadScheduler.cc | 238 ----- dev/ZKAKit/src/Heap.cc | 307 ------ dev/ZKAKit/src/IDLLObject.cc | 15 - dev/ZKAKit/src/IPEFDLLObject.cc | 103 -- dev/ZKAKit/src/IndexableProperty.cc | 57 -- dev/ZKAKit/src/Json.cc | 10 - dev/ZKAKit/src/KString.cc | 217 ---- dev/ZKAKit/src/KernelMain.cc | 140 --- dev/ZKAKit/src/LPC.cc | 34 - dev/ZKAKit/src/LockDelegate.cc | 12 - dev/ZKAKit/src/MutableArray.cc | 7 - dev/ZKAKit/src/NeFS+FileMgr.cc | 249 ----- dev/ZKAKit/src/NeFS+IO.cc | 101 -- dev/ZKAKit/src/Network/IP.cc | 126 --- dev/ZKAKit/src/Network/IPC.cc | 111 --- dev/ZKAKit/src/Network/NetworkDevice.cc | 35 - dev/ZKAKit/src/New+Delete.cc | 50 - dev/ZKAKit/src/OwnPtr.cc | 7 - dev/ZKAKit/src/PEFCodeMgr.cc | 284 ------ dev/ZKAKit/src/PRDT.cc | 24 - dev/ZKAKit/src/PageMgr.cc | 110 -- dev/ZKAKit/src/Pmm.cc | 98 -- dev/ZKAKit/src/Property.cc | 45 - dev/ZKAKit/src/Ref.cc | 7 - dev/ZKAKit/src/Semaphore.cc | 72 -- dev/ZKAKit/src/Stop.cc | 130 --- dev/ZKAKit/src/Storage/AHCIDeviceInterface.cc | 35 - dev/ZKAKit/src/Storage/ATADeviceInterface.cc | 88 -- dev/ZKAKit/src/Storage/NVMEDeviceInterface.cc | 28 - dev/ZKAKit/src/Storage/SCSIDeviceInterface.cc | 11 - dev/ZKAKit/src/Stream.cc | 12 - dev/ZKAKit/src/ThreadLocalStorage.cc | 67 -- dev/ZKAKit/src/Timer.cc | 47 - dev/ZKAKit/src/User.cc | 178 ---- dev/ZKAKit/src/UserProcessScheduler.cc | 582 ----------- dev/ZKAKit/src/UserProcessTeam.cc | 55 - dev/ZKAKit/src/Utils.cc | 223 ----- dev/ZKAKit/src/Variant.cc | 33 - 639 files changed, 22115 insertions(+), 22145 deletions(-) create mode 100644 dev/BootLoader/BootKit/BitManip.h create mode 100644 dev/BootLoader/BootKit/BootKit.h create mode 100644 dev/BootLoader/BootKit/Device.h create mode 100644 dev/BootLoader/BootKit/EPM.h create mode 100644 dev/BootLoader/BootKit/HW/ATA.h create mode 100644 dev/BootLoader/BootKit/HW/SATA.h create mode 100644 dev/BootLoader/BootKit/Platform.h create mode 100644 dev/BootLoader/BootKit/Protocol.h create mode 100644 dev/BootLoader/BootKit/Rsrc/zka_disk.rsrc create mode 100644 dev/BootLoader/BootKit/Rsrc/zka_has_disk.rsrc create mode 100644 dev/BootLoader/BootKit/Rsrc/zka_no_disk.rsrc create mode 100644 dev/BootLoader/BootKit/Support.h create mode 100644 dev/BootLoader/BootKit/Thread.h create mode 100644 dev/BootLoader/DownloadOVMF.ps1 create mode 100644 dev/BootLoader/Modules/.keep create mode 100644 dev/BootLoader/Modules/NetBoot/.hgkeep create mode 100644 dev/BootLoader/Modules/NetBoot/Boot.S create mode 100644 dev/BootLoader/Modules/NetBoot/Module.cc create mode 100644 dev/BootLoader/Modules/NetBoot/NetBoot.h create mode 100644 dev/BootLoader/Modules/NetBoot/build.json create mode 100644 dev/BootLoader/Modules/SysChk/.hgkeep create mode 100644 dev/BootLoader/Modules/SysChk/Boot.S create mode 100644 dev/BootLoader/Modules/SysChk/Module.cc create mode 100644 dev/BootLoader/Modules/SysChk/build.json create mode 100644 dev/BootLoader/ReadMe.md create mode 100644 dev/BootLoader/amd64-efi.make create mode 100644 dev/BootLoader/arm64-efi.make create mode 100644 dev/BootLoader/src/.gitkeep create mode 100644 dev/BootLoader/src/BootFileReader.cc create mode 100644 dev/BootLoader/src/BootString.cc create mode 100644 dev/BootLoader/src/BootSupport.cc create mode 100644 dev/BootLoader/src/BootTextWriter.cc create mode 100644 dev/BootLoader/src/BootThread.cc create mode 100644 dev/BootLoader/src/BootloaderRsrc.rsrc create mode 100644 dev/BootLoader/src/HEL/64X000/.gitkeep create mode 100644 dev/BootLoader/src/HEL/64X000/Boot64x0.S create mode 100644 dev/BootLoader/src/HEL/AMD64/.gitkeep create mode 100644 dev/BootLoader/src/HEL/AMD64/BootAPI.S create mode 100644 dev/BootLoader/src/HEL/AMD64/BootATA.cc create mode 100644 dev/BootLoader/src/HEL/AMD64/BootMain.cc create mode 100644 dev/BootLoader/src/HEL/AMD64/BootPlatform.cc create mode 100644 dev/BootLoader/src/HEL/AMD64/BootSATA.cc create mode 100644 dev/BootLoader/src/HEL/ARM64/.gitkeep create mode 100644 dev/BootLoader/src/HEL/ARM64/BootAPI.S create mode 100644 dev/BootLoader/src/HEL/ARM64/BootMain.cc create mode 100644 dev/BootLoader/src/HEL/ARM64/BootPlatform.cc create mode 100644 dev/BootLoader/src/HEL/POWER/.gitkeep create mode 100644 dev/BootLoader/src/HEL/POWER/CoreBootStartup.S create mode 100644 dev/BootLoader/src/New+Delete.cc create mode 100644 dev/BootLoader/src/Root/EFI/STARTUP.NSH create mode 100644 dev/BootLoader/src/Root/zka/fntkrnl.ttf create mode 100644 dev/Kernel/ArchKit/ArchKit.h create mode 100644 dev/Kernel/CFKit/GUIDWizard.h create mode 100644 dev/Kernel/CFKit/GUIDWrapper.h create mode 100644 dev/Kernel/CFKit/Property.h create mode 100644 dev/Kernel/CFKit/Utils.h create mode 100644 dev/Kernel/CompilerKit/CompilerKit.h create mode 100644 dev/Kernel/CompilerKit/Detail.h create mode 100644 dev/Kernel/CompilerKit/Version.h create mode 100644 dev/Kernel/FSKit/Defines.h create mode 100644 dev/Kernel/FSKit/HPFS.h create mode 100644 dev/Kernel/FSKit/IndexableProperty.h create mode 100644 dev/Kernel/FSKit/NeFS.h create mode 100644 dev/Kernel/FirmwareKit/.gitkeep create mode 100644 dev/Kernel/FirmwareKit/CoreBoot/CoreBoot.h create mode 100644 dev/Kernel/FirmwareKit/CoreBoot/NetBoot.h create mode 100644 dev/Kernel/FirmwareKit/EFI.h create mode 100644 dev/Kernel/FirmwareKit/EFI/API.h create mode 100644 dev/Kernel/FirmwareKit/EFI/EFI.h create mode 100644 dev/Kernel/FirmwareKit/EFI/NS.h create mode 100644 dev/Kernel/FirmwareKit/EPM.h create mode 100644 dev/Kernel/FirmwareKit/GPT.h create mode 100644 dev/Kernel/FirmwareKit/Handover.h create mode 100644 dev/Kernel/HALKit/.gitkeep create mode 100644 dev/Kernel/HALKit/64x0/.hgkeep create mode 100644 dev/Kernel/HALKit/64x0/APM/.hgkeep create mode 100644 dev/Kernel/HALKit/64x0/HalVirtualMemory.cc create mode 100644 dev/Kernel/HALKit/64x0/MBCI/.gitkeep create mode 100644 dev/Kernel/HALKit/64x0/ReadMe.md create mode 100644 dev/Kernel/HALKit/AMD64/CPUID.h create mode 100644 dev/Kernel/HALKit/AMD64/HalACPIFactoryInterface.cc create mode 100644 dev/Kernel/HALKit/AMD64/HalAP.cc create mode 100644 dev/Kernel/HALKit/AMD64/HalAPICController.cc create mode 100644 dev/Kernel/HALKit/AMD64/HalBoot.asm create mode 100644 dev/Kernel/HALKit/AMD64/HalCPUAMD64.cc create mode 100644 dev/Kernel/HALKit/AMD64/HalCommonAPI.asm create mode 100644 dev/Kernel/HALKit/AMD64/HalControlRegister.s create mode 100644 dev/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc create mode 100644 dev/Kernel/HALKit/AMD64/HalCoreScheduler.cc create mode 100644 dev/Kernel/HALKit/AMD64/HalDebugOutput.cc create mode 100644 dev/Kernel/HALKit/AMD64/HalDebugPort.cc create mode 100644 dev/Kernel/HALKit/AMD64/HalDescriptorLoader.cc create mode 100644 dev/Kernel/HALKit/AMD64/HalInterruptAPI.asm create mode 100644 dev/Kernel/HALKit/AMD64/HalKernelMain.cc create mode 100644 dev/Kernel/HALKit/AMD64/HalPagingMgrAMD64.cc create mode 100644 dev/Kernel/HALKit/AMD64/HalRoutineWait.s create mode 100644 dev/Kernel/HALKit/AMD64/HalTimerAMD64.cc create mode 100644 dev/Kernel/HALKit/AMD64/HalUtils.asm create mode 100644 dev/Kernel/HALKit/AMD64/Hypervisor.h create mode 100644 dev/Kernel/HALKit/AMD64/MBCI/HalMBCI.cc create mode 100644 dev/Kernel/HALKit/AMD64/PCI/DMA.cc create mode 100644 dev/Kernel/HALKit/AMD64/PCI/Database.cc create mode 100644 dev/Kernel/HALKit/AMD64/PCI/Device.cc create mode 100644 dev/Kernel/HALKit/AMD64/PCI/Express.cc create mode 100644 dev/Kernel/HALKit/AMD64/PCI/IO.cc create mode 100644 dev/Kernel/HALKit/AMD64/PCI/Iterator.cc create mode 100644 dev/Kernel/HALKit/AMD64/PCI/PCI.cc create mode 100644 dev/Kernel/HALKit/AMD64/Paging.h create mode 100644 dev/Kernel/HALKit/AMD64/Processor.h create mode 100644 dev/Kernel/HALKit/AMD64/ReadMe.md create mode 100644 dev/Kernel/HALKit/AMD64/Storage/AHCI-DMA.cc create mode 100644 dev/Kernel/HALKit/AMD64/Storage/ATA-DMA.cc create mode 100644 dev/Kernel/HALKit/AMD64/Storage/ATA-PIO.cc create mode 100644 dev/Kernel/HALKit/ARM64/.gitkeep create mode 100644 dev/Kernel/HALKit/ARM64/AP.h create mode 100644 dev/Kernel/HALKit/ARM64/APM/.gitkeep create mode 100644 dev/Kernel/HALKit/ARM64/APM/APM.cc create mode 100644 dev/Kernel/HALKit/ARM64/HalACPIFactoryInterface.cc create mode 100644 dev/Kernel/HALKit/ARM64/HalAP.cc create mode 100644 dev/Kernel/HALKit/ARM64/HalCoreMPScheduler.cc create mode 100644 dev/Kernel/HALKit/ARM64/HalDebugOutput.cc create mode 100644 dev/Kernel/HALKit/ARM64/HalKernelMain.cc create mode 100644 dev/Kernel/HALKit/ARM64/HalPageInternal.S create mode 100644 dev/Kernel/HALKit/ARM64/HalPagingMgrARM64.cc create mode 100644 dev/Kernel/HALKit/ARM64/HalSchedulerCore.cc create mode 100644 dev/Kernel/HALKit/ARM64/HalSchedulerCoreARM64.cc create mode 100644 dev/Kernel/HALKit/ARM64/HalTimerARM64.cc create mode 100644 dev/Kernel/HALKit/ARM64/MBCI/.keepme create mode 100644 dev/Kernel/HALKit/ARM64/Paging.h create mode 100644 dev/Kernel/HALKit/ARM64/Processor.h create mode 100644 dev/Kernel/HALKit/ARM64/ReadMe.md create mode 100644 dev/Kernel/HALKit/ARM64/Storage/.gitkeep create mode 100644 dev/Kernel/HALKit/ARM64/Storage/HalFlash.cc create mode 100644 dev/Kernel/HALKit/AXP/CR.s create mode 100644 dev/Kernel/HALKit/AXP/CoreInterruptHandlerDEC.cpp create mode 100644 dev/Kernel/HALKit/AXP/CoreSyscallHandlerDEC.cpp create mode 100644 dev/Kernel/HALKit/AXP/HAL.s create mode 100644 dev/Kernel/HALKit/AXP/Processor.h create mode 100644 dev/Kernel/HALKit/AXP/README create mode 100644 dev/Kernel/HALKit/AXP/README.TXT create mode 100644 dev/Kernel/HALKit/AXP/SYSCALL.s create mode 100644 dev/Kernel/HALKit/AXP/VM.s create mode 100644 dev/Kernel/HALKit/POWER/.gitkeep create mode 100644 dev/Kernel/HALKit/POWER/AP.h create mode 100644 dev/Kernel/HALKit/POWER/APM/.gitkeep create mode 100644 dev/Kernel/HALKit/POWER/HalAP.cc create mode 100644 dev/Kernel/HALKit/POWER/HalDebugOutput.cc create mode 100644 dev/Kernel/HALKit/POWER/HalStartSequence.s create mode 100644 dev/Kernel/HALKit/POWER/HalThread.cc create mode 100644 dev/Kernel/HALKit/POWER/HalVirtualMemory.cc create mode 100644 dev/Kernel/HALKit/POWER/MBCI/.gitkeep create mode 100644 dev/Kernel/HALKit/POWER/MBCI/HalMBCIHost.cc create mode 100644 dev/Kernel/HALKit/POWER/Processor.h create mode 100644 dev/Kernel/HALKit/POWER/ReadMe.md create mode 100644 dev/Kernel/HALKit/RISCV/.keep create mode 100644 dev/Kernel/HALKit/RISCV/AP.h create mode 100644 dev/Kernel/HALKit/RISCV/APM/.gitkeep create mode 100644 dev/Kernel/HALKit/RISCV/HalAP.cc create mode 100644 dev/Kernel/HALKit/RISCV/ReadMe.md create mode 100644 dev/Kernel/HALKit/RISCV/Storage/.gitkeep create mode 100644 dev/Kernel/HALKit/X86S/.gitkeep create mode 100644 dev/Kernel/HALKit/X86S/ACPI/.gitkeep create mode 100644 dev/Kernel/HALKit/X86S/Storage/.gitkeep create mode 100644 dev/Kernel/KernelKit/CodeMgr.h create mode 100644 dev/Kernel/KernelKit/DebugOutput.h create mode 100644 dev/Kernel/KernelKit/Defines.h create mode 100644 dev/Kernel/KernelKit/DeviceMgr.h create mode 100644 dev/Kernel/KernelKit/DriveMgr.h create mode 100644 dev/Kernel/KernelKit/FileMgr.h create mode 100644 dev/Kernel/KernelKit/HardwareThreadScheduler.h create mode 100644 dev/Kernel/KernelKit/Heap.h create mode 100644 dev/Kernel/KernelKit/IDLLObject.h create mode 100644 dev/Kernel/KernelKit/IPEFDLLObject.h create mode 100644 dev/Kernel/KernelKit/LPC.h create mode 100644 dev/Kernel/KernelKit/LoaderInterface.h create mode 100644 dev/Kernel/KernelKit/LockDelegate.h create mode 100644 dev/Kernel/KernelKit/MSDOS.h create mode 100644 dev/Kernel/KernelKit/PCI/DMA.h create mode 100644 dev/Kernel/KernelKit/PCI/DMA.inl create mode 100644 dev/Kernel/KernelKit/PCI/Database.h create mode 100644 dev/Kernel/KernelKit/PCI/Device.h create mode 100644 dev/Kernel/KernelKit/PCI/Express.h create mode 100644 dev/Kernel/KernelKit/PCI/IO-Impl-AMD64.inl create mode 100644 dev/Kernel/KernelKit/PCI/IO.h create mode 100644 dev/Kernel/KernelKit/PCI/Iterator.h create mode 100644 dev/Kernel/KernelKit/PCI/PCI.h create mode 100644 dev/Kernel/KernelKit/PE.h create mode 100644 dev/Kernel/KernelKit/PECodeMgr.h create mode 100644 dev/Kernel/KernelKit/PEF.h create mode 100644 dev/Kernel/KernelKit/PEFCodeMgr.h create mode 100644 dev/Kernel/KernelKit/Semaphore.h create mode 100644 dev/Kernel/KernelKit/ThreadLocalStorage.h create mode 100644 dev/Kernel/KernelKit/ThreadLocalStorage.inl create mode 100644 dev/Kernel/KernelKit/Timer.h create mode 100644 dev/Kernel/KernelKit/User.h create mode 100644 dev/Kernel/KernelKit/UserProcessScheduler.h create mode 100644 dev/Kernel/KernelKit/UserProcessScheduler.inl create mode 100644 dev/Kernel/KernelKit/XCOFF.h create mode 100644 dev/Kernel/KernelRsrc.rsrc create mode 100644 dev/Kernel/MoveAll.ARM64.sh create mode 100644 dev/Kernel/MoveAll.X64.sh create mode 100644 dev/Kernel/NetworkKit/IP.h create mode 100644 dev/Kernel/NetworkKit/IPC.h create mode 100644 dev/Kernel/NetworkKit/LTE.h create mode 100644 dev/Kernel/NetworkKit/MAC.h create mode 100644 dev/Kernel/NetworkKit/NetworkDevice.h create mode 100644 dev/Kernel/NetworkKit/NetworkDevice.inl create mode 100644 dev/Kernel/NewKit/Array.h create mode 100644 dev/Kernel/NewKit/ArrayList.h create mode 100644 dev/Kernel/NewKit/Atom.h create mode 100644 dev/Kernel/NewKit/Crc32.h create mode 100644 dev/Kernel/NewKit/CxxAbi.h create mode 100644 dev/Kernel/NewKit/Defines.h create mode 100644 dev/Kernel/NewKit/ErrorOr.h create mode 100644 dev/Kernel/NewKit/Function.h create mode 100644 dev/Kernel/NewKit/Json.h create mode 100644 dev/Kernel/NewKit/KString.h create mode 100644 dev/Kernel/NewKit/Macros.h create mode 100644 dev/Kernel/NewKit/MutableArray.h create mode 100644 dev/Kernel/NewKit/New.h create mode 100644 dev/Kernel/NewKit/NewKit.h create mode 100644 dev/Kernel/NewKit/OwnPtr.h create mode 100644 dev/Kernel/NewKit/PageMgr.h create mode 100644 dev/Kernel/NewKit/Pair.h create mode 100644 dev/Kernel/NewKit/Pmm.h create mode 100644 dev/Kernel/NewKit/Ref.h create mode 100644 dev/Kernel/NewKit/Stop.h create mode 100644 dev/Kernel/NewKit/Stream.h create mode 100644 dev/Kernel/NewKit/Utils.h create mode 100644 dev/Kernel/NewKit/Variant.h create mode 100644 dev/Kernel/POSIXKit/signal.h create mode 100644 dev/Kernel/POSIXKit/unix_layer.h create mode 100644 dev/Kernel/ReadMe.md create mode 100644 dev/Kernel/StorageKit/AHCI.h create mode 100644 dev/Kernel/StorageKit/ATA.h create mode 100644 dev/Kernel/StorageKit/NVME.h create mode 100644 dev/Kernel/StorageKit/PRDT.h create mode 100644 dev/Kernel/StorageKit/SCSI.h create mode 100644 dev/Kernel/StorageKit/StorageKit.h create mode 100644 dev/Kernel/amd64-efi.make create mode 100644 dev/Kernel/arm64-efi.make create mode 100644 dev/Kernel/doc/Explicit Partition Map.pdf create mode 100644 dev/Kernel/doc/SPECIFICATION.md create mode 100644 dev/Kernel/doc/TODO-LIST.md create mode 100644 dev/Kernel/obj/.hgkeep create mode 100644 dev/Kernel/power64-cb.make create mode 100644 dev/Kernel/riscv64-cb.make create mode 100644 dev/Kernel/src/ACPIFactoryInterface.cc create mode 100644 dev/Kernel/src/Array.cc create mode 100644 dev/Kernel/src/ArrayList.cc create mode 100644 dev/Kernel/src/Atom.cc create mode 100644 dev/Kernel/src/BitMapMgr.cc create mode 100644 dev/Kernel/src/CodeMgr.cc create mode 100644 dev/Kernel/src/Crc32.cc create mode 100644 dev/Kernel/src/CxxAbi-AMD64.cc create mode 100644 dev/Kernel/src/CxxAbi-ARM64.cc create mode 100644 dev/Kernel/src/Defines.cc create mode 100644 dev/Kernel/src/DeviceMgr.cc create mode 100644 dev/Kernel/src/DriveMgr.cc create mode 100644 dev/Kernel/src/ErrorOr.cc create mode 100644 dev/Kernel/src/FS/HPFS.cc create mode 100644 dev/Kernel/src/FS/NeFS.cc create mode 100644 dev/Kernel/src/FileMgr.cc create mode 100644 dev/Kernel/src/GUIDWizard.cc create mode 100644 dev/Kernel/src/GUIDWrapper.cc create mode 100644 dev/Kernel/src/HardwareThreadScheduler.cc create mode 100644 dev/Kernel/src/Heap.cc create mode 100644 dev/Kernel/src/IDLLObject.cc create mode 100644 dev/Kernel/src/IPEFDLLObject.cc create mode 100644 dev/Kernel/src/IndexableProperty.cc create mode 100644 dev/Kernel/src/Json.cc create mode 100644 dev/Kernel/src/KString.cc create mode 100644 dev/Kernel/src/KernelMain.cc create mode 100644 dev/Kernel/src/LPC.cc create mode 100644 dev/Kernel/src/LockDelegate.cc create mode 100644 dev/Kernel/src/MutableArray.cc create mode 100644 dev/Kernel/src/NeFS+FileMgr.cc create mode 100644 dev/Kernel/src/NeFS+IO.cc create mode 100644 dev/Kernel/src/Network/IP.cc create mode 100644 dev/Kernel/src/Network/IPC.cc create mode 100644 dev/Kernel/src/Network/NetworkDevice.cc create mode 100644 dev/Kernel/src/New+Delete.cc create mode 100644 dev/Kernel/src/OwnPtr.cc create mode 100644 dev/Kernel/src/PEFCodeMgr.cc create mode 100644 dev/Kernel/src/PRDT.cc create mode 100644 dev/Kernel/src/PageMgr.cc create mode 100644 dev/Kernel/src/Pmm.cc create mode 100644 dev/Kernel/src/Property.cc create mode 100644 dev/Kernel/src/Ref.cc create mode 100644 dev/Kernel/src/Semaphore.cc create mode 100644 dev/Kernel/src/Stop.cc create mode 100644 dev/Kernel/src/Storage/AHCIDeviceInterface.cc create mode 100644 dev/Kernel/src/Storage/ATADeviceInterface.cc create mode 100644 dev/Kernel/src/Storage/NVMEDeviceInterface.cc create mode 100644 dev/Kernel/src/Storage/SCSIDeviceInterface.cc create mode 100644 dev/Kernel/src/Stream.cc create mode 100644 dev/Kernel/src/ThreadLocalStorage.cc create mode 100644 dev/Kernel/src/Timer.cc create mode 100644 dev/Kernel/src/User.cc create mode 100644 dev/Kernel/src/UserProcessScheduler.cc create mode 100644 dev/Kernel/src/UserProcessTeam.cc create mode 100644 dev/Kernel/src/Utils.cc create mode 100644 dev/Kernel/src/Variant.cc create mode 100644 dev/SCIKit/src/SCI+IO.asm delete mode 100644 dev/SCIKit/src/SysCallDispatcher.asm delete mode 100644 dev/ZBAKit/BootKit/BitManip.h delete mode 100644 dev/ZBAKit/BootKit/BootKit.h delete mode 100644 dev/ZBAKit/BootKit/Device.h delete mode 100644 dev/ZBAKit/BootKit/EPM.h delete mode 100644 dev/ZBAKit/BootKit/HW/ATA.h delete mode 100644 dev/ZBAKit/BootKit/HW/SATA.h delete mode 100644 dev/ZBAKit/BootKit/Platform.h delete mode 100644 dev/ZBAKit/BootKit/Protocol.h delete mode 100644 dev/ZBAKit/BootKit/Rsrc/zka_disk.rsrc delete mode 100644 dev/ZBAKit/BootKit/Rsrc/zka_has_disk.rsrc delete mode 100644 dev/ZBAKit/BootKit/Rsrc/zka_no_disk.rsrc delete mode 100644 dev/ZBAKit/BootKit/Support.h delete mode 100644 dev/ZBAKit/BootKit/Thread.h delete mode 100644 dev/ZBAKit/DownloadOVMF.ps1 delete mode 100644 dev/ZBAKit/Modules/.keep delete mode 100644 dev/ZBAKit/Modules/NetBoot/.hgkeep delete mode 100644 dev/ZBAKit/Modules/NetBoot/Boot.S delete mode 100644 dev/ZBAKit/Modules/NetBoot/Module.cc delete mode 100644 dev/ZBAKit/Modules/NetBoot/NetBoot.h delete mode 100644 dev/ZBAKit/Modules/NetBoot/build.json delete mode 100644 dev/ZBAKit/Modules/SysChk/.hgkeep delete mode 100644 dev/ZBAKit/Modules/SysChk/Boot.S delete mode 100644 dev/ZBAKit/Modules/SysChk/Module.cc delete mode 100644 dev/ZBAKit/Modules/SysChk/build.json delete mode 100644 dev/ZBAKit/ReadMe.md delete mode 100644 dev/ZBAKit/amd64-efi.make delete mode 100644 dev/ZBAKit/arm64-efi.make delete mode 100644 dev/ZBAKit/src/.gitkeep delete mode 100644 dev/ZBAKit/src/BootFileReader.cc delete mode 100644 dev/ZBAKit/src/BootString.cc delete mode 100644 dev/ZBAKit/src/BootSupport.cc delete mode 100644 dev/ZBAKit/src/BootTextWriter.cc delete mode 100644 dev/ZBAKit/src/BootThread.cc delete mode 100644 dev/ZBAKit/src/BootloaderRsrc.rsrc delete mode 100644 dev/ZBAKit/src/HEL/64X000/.gitkeep delete mode 100644 dev/ZBAKit/src/HEL/64X000/Boot64x0.S delete mode 100644 dev/ZBAKit/src/HEL/AMD64/.gitkeep delete mode 100644 dev/ZBAKit/src/HEL/AMD64/BootAPI.S delete mode 100644 dev/ZBAKit/src/HEL/AMD64/BootATA.cc delete mode 100644 dev/ZBAKit/src/HEL/AMD64/BootMain.cc delete mode 100644 dev/ZBAKit/src/HEL/AMD64/BootPlatform.cc delete mode 100644 dev/ZBAKit/src/HEL/AMD64/BootSATA.cc delete mode 100644 dev/ZBAKit/src/HEL/ARM64/.gitkeep delete mode 100644 dev/ZBAKit/src/HEL/ARM64/BootAPI.S delete mode 100644 dev/ZBAKit/src/HEL/ARM64/BootMain.cc delete mode 100644 dev/ZBAKit/src/HEL/ARM64/BootPlatform.cc delete mode 100644 dev/ZBAKit/src/HEL/POWER/.gitkeep delete mode 100644 dev/ZBAKit/src/HEL/POWER/CoreBootStartup.S delete mode 100644 dev/ZBAKit/src/New+Delete.cc delete mode 100644 dev/ZBAKit/src/Root/EFI/STARTUP.NSH delete mode 100644 dev/ZBAKit/src/Root/zka/startup.wav delete mode 100644 dev/ZBAKit/src/Root/zka/urbanist.ttf delete mode 100644 dev/ZKAKit/ArchKit/ArchKit.h delete mode 100644 dev/ZKAKit/CFKit/GUIDWizard.h delete mode 100644 dev/ZKAKit/CFKit/GUIDWrapper.h delete mode 100644 dev/ZKAKit/CFKit/Property.h delete mode 100644 dev/ZKAKit/CFKit/Utils.h delete mode 100644 dev/ZKAKit/CompilerKit/CompilerKit.h delete mode 100644 dev/ZKAKit/CompilerKit/Detail.h delete mode 100644 dev/ZKAKit/CompilerKit/Version.h delete mode 100644 dev/ZKAKit/FSKit/Defines.h delete mode 100644 dev/ZKAKit/FSKit/HPFS.h delete mode 100644 dev/ZKAKit/FSKit/IndexableProperty.h delete mode 100644 dev/ZKAKit/FSKit/NeFS.h delete mode 100644 dev/ZKAKit/FirmwareKit/.gitkeep delete mode 100644 dev/ZKAKit/FirmwareKit/CoreBoot/CoreBoot.h delete mode 100644 dev/ZKAKit/FirmwareKit/CoreBoot/NetBoot.h delete mode 100644 dev/ZKAKit/FirmwareKit/EFI.h delete mode 100644 dev/ZKAKit/FirmwareKit/EFI/API.h delete mode 100644 dev/ZKAKit/FirmwareKit/EFI/EFI.h delete mode 100644 dev/ZKAKit/FirmwareKit/EFI/NS.h delete mode 100644 dev/ZKAKit/FirmwareKit/EPM.h delete mode 100644 dev/ZKAKit/FirmwareKit/GPT.h delete mode 100644 dev/ZKAKit/FirmwareKit/Handover.h delete mode 100644 dev/ZKAKit/HALKit/.gitkeep delete mode 100644 dev/ZKAKit/HALKit/64x0/.hgkeep delete mode 100644 dev/ZKAKit/HALKit/64x0/APM/.hgkeep delete mode 100644 dev/ZKAKit/HALKit/64x0/HalVirtualMemory.cc delete mode 100644 dev/ZKAKit/HALKit/64x0/MBCI/.gitkeep delete mode 100644 dev/ZKAKit/HALKit/64x0/ReadMe.md delete mode 100644 dev/ZKAKit/HALKit/AMD64/CPUID.h delete mode 100644 dev/ZKAKit/HALKit/AMD64/HalACPIFactoryInterface.cc delete mode 100644 dev/ZKAKit/HALKit/AMD64/HalAP.cc delete mode 100644 dev/ZKAKit/HALKit/AMD64/HalAPICController.cc delete mode 100644 dev/ZKAKit/HALKit/AMD64/HalBoot.asm delete mode 100644 dev/ZKAKit/HALKit/AMD64/HalCPUAMD64.cc delete mode 100644 dev/ZKAKit/HALKit/AMD64/HalCommonAPI.asm delete mode 100644 dev/ZKAKit/HALKit/AMD64/HalControlRegister.s delete mode 100644 dev/ZKAKit/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc delete mode 100644 dev/ZKAKit/HALKit/AMD64/HalCoreScheduler.cc delete mode 100644 dev/ZKAKit/HALKit/AMD64/HalDebugOutput.cc delete mode 100644 dev/ZKAKit/HALKit/AMD64/HalDebugPort.cc delete mode 100644 dev/ZKAKit/HALKit/AMD64/HalDescriptorLoader.cc delete mode 100644 dev/ZKAKit/HALKit/AMD64/HalInterruptAPI.asm delete mode 100644 dev/ZKAKit/HALKit/AMD64/HalKernelMain.cc delete mode 100644 dev/ZKAKit/HALKit/AMD64/HalPagingMgrAMD64.cc delete mode 100644 dev/ZKAKit/HALKit/AMD64/HalRoutineWait.s delete mode 100644 dev/ZKAKit/HALKit/AMD64/HalTimerAMD64.cc delete mode 100644 dev/ZKAKit/HALKit/AMD64/HalUtils.asm delete mode 100644 dev/ZKAKit/HALKit/AMD64/Hypervisor.h delete mode 100644 dev/ZKAKit/HALKit/AMD64/MBCI/HalMBCI.cc delete mode 100644 dev/ZKAKit/HALKit/AMD64/PCI/DMA.cc delete mode 100644 dev/ZKAKit/HALKit/AMD64/PCI/Database.cc delete mode 100644 dev/ZKAKit/HALKit/AMD64/PCI/Device.cc delete mode 100644 dev/ZKAKit/HALKit/AMD64/PCI/Express.cc delete mode 100644 dev/ZKAKit/HALKit/AMD64/PCI/IO.cc delete mode 100644 dev/ZKAKit/HALKit/AMD64/PCI/Iterator.cc delete mode 100644 dev/ZKAKit/HALKit/AMD64/PCI/PCI.cc delete mode 100644 dev/ZKAKit/HALKit/AMD64/Paging.h delete mode 100644 dev/ZKAKit/HALKit/AMD64/Processor.h delete mode 100644 dev/ZKAKit/HALKit/AMD64/ReadMe.md delete mode 100644 dev/ZKAKit/HALKit/AMD64/Storage/AHCI-DMA.cc delete mode 100644 dev/ZKAKit/HALKit/AMD64/Storage/ATA-DMA.cc delete mode 100644 dev/ZKAKit/HALKit/AMD64/Storage/ATA-PIO.cc delete mode 100644 dev/ZKAKit/HALKit/ARM64/.gitkeep delete mode 100644 dev/ZKAKit/HALKit/ARM64/AP.h delete mode 100644 dev/ZKAKit/HALKit/ARM64/APM/.gitkeep delete mode 100644 dev/ZKAKit/HALKit/ARM64/APM/APM.cc delete mode 100644 dev/ZKAKit/HALKit/ARM64/HalACPIFactoryInterface.cc delete mode 100644 dev/ZKAKit/HALKit/ARM64/HalAP.cc delete mode 100644 dev/ZKAKit/HALKit/ARM64/HalCoreMPScheduler.cc delete mode 100644 dev/ZKAKit/HALKit/ARM64/HalDebugOutput.cc delete mode 100644 dev/ZKAKit/HALKit/ARM64/HalKernelMain.cc delete mode 100644 dev/ZKAKit/HALKit/ARM64/HalPageInternal.S delete mode 100644 dev/ZKAKit/HALKit/ARM64/HalPagingMgrARM64.cc delete mode 100644 dev/ZKAKit/HALKit/ARM64/HalSchedulerCore.cc delete mode 100644 dev/ZKAKit/HALKit/ARM64/HalSchedulerCoreARM64.cc delete mode 100644 dev/ZKAKit/HALKit/ARM64/HalTimerARM64.cc delete mode 100644 dev/ZKAKit/HALKit/ARM64/MBCI/.keepme delete mode 100644 dev/ZKAKit/HALKit/ARM64/Paging.h delete mode 100644 dev/ZKAKit/HALKit/ARM64/Processor.h delete mode 100644 dev/ZKAKit/HALKit/ARM64/ReadMe.md delete mode 100644 dev/ZKAKit/HALKit/ARM64/Storage/.gitkeep delete mode 100644 dev/ZKAKit/HALKit/ARM64/Storage/HalFlash.cc delete mode 100644 dev/ZKAKit/HALKit/AXP/CR.s delete mode 100644 dev/ZKAKit/HALKit/AXP/CoreInterruptHandlerDEC.cpp delete mode 100644 dev/ZKAKit/HALKit/AXP/CoreSyscallHandlerDEC.cpp delete mode 100644 dev/ZKAKit/HALKit/AXP/HAL.s delete mode 100644 dev/ZKAKit/HALKit/AXP/Processor.h delete mode 100644 dev/ZKAKit/HALKit/AXP/README delete mode 100644 dev/ZKAKit/HALKit/AXP/README.TXT delete mode 100644 dev/ZKAKit/HALKit/AXP/SYSCALL.s delete mode 100644 dev/ZKAKit/HALKit/AXP/VM.s delete mode 100644 dev/ZKAKit/HALKit/POWER/.gitkeep delete mode 100644 dev/ZKAKit/HALKit/POWER/AP.h delete mode 100644 dev/ZKAKit/HALKit/POWER/APM/.gitkeep delete mode 100644 dev/ZKAKit/HALKit/POWER/HalAP.cc delete mode 100644 dev/ZKAKit/HALKit/POWER/HalDebugOutput.cc delete mode 100644 dev/ZKAKit/HALKit/POWER/HalStartSequence.s delete mode 100644 dev/ZKAKit/HALKit/POWER/HalThread.cc delete mode 100644 dev/ZKAKit/HALKit/POWER/HalVirtualMemory.cc delete mode 100644 dev/ZKAKit/HALKit/POWER/MBCI/.gitkeep delete mode 100644 dev/ZKAKit/HALKit/POWER/MBCI/HalMBCIHost.cc delete mode 100644 dev/ZKAKit/HALKit/POWER/Processor.h delete mode 100644 dev/ZKAKit/HALKit/POWER/ReadMe.md delete mode 100644 dev/ZKAKit/HALKit/RISCV/.keep delete mode 100644 dev/ZKAKit/HALKit/RISCV/AP.h delete mode 100644 dev/ZKAKit/HALKit/RISCV/APM/.gitkeep delete mode 100644 dev/ZKAKit/HALKit/RISCV/HalAP.cc delete mode 100644 dev/ZKAKit/HALKit/RISCV/ReadMe.md delete mode 100644 dev/ZKAKit/HALKit/RISCV/Storage/.gitkeep delete mode 100644 dev/ZKAKit/HALKit/X86S/.gitkeep delete mode 100644 dev/ZKAKit/HALKit/X86S/ACPI/.gitkeep delete mode 100644 dev/ZKAKit/HALKit/X86S/Storage/.gitkeep delete mode 100644 dev/ZKAKit/KernelKit/CodeMgr.h delete mode 100644 dev/ZKAKit/KernelKit/DebugOutput.h delete mode 100644 dev/ZKAKit/KernelKit/Defines.h delete mode 100644 dev/ZKAKit/KernelKit/DeviceMgr.h delete mode 100644 dev/ZKAKit/KernelKit/DriveMgr.h delete mode 100644 dev/ZKAKit/KernelKit/FileMgr.h delete mode 100644 dev/ZKAKit/KernelKit/HardwareThreadScheduler.h delete mode 100644 dev/ZKAKit/KernelKit/Heap.h delete mode 100644 dev/ZKAKit/KernelKit/IDLLObject.h delete mode 100644 dev/ZKAKit/KernelKit/IPEFDLLObject.h delete mode 100644 dev/ZKAKit/KernelKit/LPC.h delete mode 100644 dev/ZKAKit/KernelKit/LoaderInterface.h delete mode 100644 dev/ZKAKit/KernelKit/LockDelegate.h delete mode 100644 dev/ZKAKit/KernelKit/MSDOS.h delete mode 100644 dev/ZKAKit/KernelKit/PCI/DMA.h delete mode 100644 dev/ZKAKit/KernelKit/PCI/DMA.inl delete mode 100644 dev/ZKAKit/KernelKit/PCI/Database.h delete mode 100644 dev/ZKAKit/KernelKit/PCI/Device.h delete mode 100644 dev/ZKAKit/KernelKit/PCI/Express.h delete mode 100644 dev/ZKAKit/KernelKit/PCI/IO-Impl-AMD64.inl delete mode 100644 dev/ZKAKit/KernelKit/PCI/IO.h delete mode 100644 dev/ZKAKit/KernelKit/PCI/Iterator.h delete mode 100644 dev/ZKAKit/KernelKit/PCI/PCI.h delete mode 100644 dev/ZKAKit/KernelKit/PE.h delete mode 100644 dev/ZKAKit/KernelKit/PECodeMgr.h delete mode 100644 dev/ZKAKit/KernelKit/PEF.h delete mode 100644 dev/ZKAKit/KernelKit/PEFCodeMgr.h delete mode 100644 dev/ZKAKit/KernelKit/Semaphore.h delete mode 100644 dev/ZKAKit/KernelKit/ThreadLocalStorage.h delete mode 100644 dev/ZKAKit/KernelKit/ThreadLocalStorage.inl delete mode 100644 dev/ZKAKit/KernelKit/Timer.h delete mode 100644 dev/ZKAKit/KernelKit/User.h delete mode 100644 dev/ZKAKit/KernelKit/UserProcessScheduler.h delete mode 100644 dev/ZKAKit/KernelKit/UserProcessScheduler.inl delete mode 100644 dev/ZKAKit/KernelKit/XCOFF.h delete mode 100644 dev/ZKAKit/KernelRsrc.rsrc delete mode 100755 dev/ZKAKit/MoveAll.ARM64.sh delete mode 100755 dev/ZKAKit/MoveAll.X64.sh delete mode 100644 dev/ZKAKit/NetworkKit/IP.h delete mode 100644 dev/ZKAKit/NetworkKit/IPC.h delete mode 100644 dev/ZKAKit/NetworkKit/LTE.h delete mode 100644 dev/ZKAKit/NetworkKit/MAC.h delete mode 100644 dev/ZKAKit/NetworkKit/NetworkDevice.h delete mode 100644 dev/ZKAKit/NetworkKit/NetworkDevice.inl delete mode 100644 dev/ZKAKit/NewKit/Array.h delete mode 100644 dev/ZKAKit/NewKit/ArrayList.h delete mode 100644 dev/ZKAKit/NewKit/Atom.h delete mode 100644 dev/ZKAKit/NewKit/Crc32.h delete mode 100644 dev/ZKAKit/NewKit/CxxAbi.h delete mode 100644 dev/ZKAKit/NewKit/Defines.h delete mode 100644 dev/ZKAKit/NewKit/ErrorOr.h delete mode 100644 dev/ZKAKit/NewKit/Function.h delete mode 100644 dev/ZKAKit/NewKit/Json.h delete mode 100644 dev/ZKAKit/NewKit/KString.h delete mode 100644 dev/ZKAKit/NewKit/Macros.h delete mode 100644 dev/ZKAKit/NewKit/MutableArray.h delete mode 100644 dev/ZKAKit/NewKit/New.h delete mode 100644 dev/ZKAKit/NewKit/NewKit.h delete mode 100644 dev/ZKAKit/NewKit/OwnPtr.h delete mode 100644 dev/ZKAKit/NewKit/PageMgr.h delete mode 100644 dev/ZKAKit/NewKit/Pair.h delete mode 100644 dev/ZKAKit/NewKit/Pmm.h delete mode 100644 dev/ZKAKit/NewKit/Ref.h delete mode 100644 dev/ZKAKit/NewKit/Stop.h delete mode 100644 dev/ZKAKit/NewKit/Stream.h delete mode 100644 dev/ZKAKit/NewKit/Utils.h delete mode 100644 dev/ZKAKit/NewKit/Variant.h delete mode 100644 dev/ZKAKit/POSIXKit/signal.h delete mode 100644 dev/ZKAKit/POSIXKit/unix_layer.h delete mode 100644 dev/ZKAKit/ReadMe.md delete mode 100644 dev/ZKAKit/StorageKit/AHCI.h delete mode 100644 dev/ZKAKit/StorageKit/ATA.h delete mode 100644 dev/ZKAKit/StorageKit/NVME.h delete mode 100644 dev/ZKAKit/StorageKit/PRDT.h delete mode 100644 dev/ZKAKit/StorageKit/SCSI.h delete mode 100644 dev/ZKAKit/StorageKit/StorageKit.h delete mode 100644 dev/ZKAKit/amd64-efi.make delete mode 100644 dev/ZKAKit/arm64-efi.make delete mode 100644 dev/ZKAKit/doc/Explicit Partition Map.pdf delete mode 100644 dev/ZKAKit/doc/SPECIFICATION.md delete mode 100644 dev/ZKAKit/doc/TODO-LIST.md delete mode 100644 dev/ZKAKit/obj/.hgkeep delete mode 100644 dev/ZKAKit/power64-cb.make delete mode 100644 dev/ZKAKit/riscv64-cb.make delete mode 100644 dev/ZKAKit/src/ACPIFactoryInterface.cc delete mode 100644 dev/ZKAKit/src/Array.cc delete mode 100644 dev/ZKAKit/src/ArrayList.cc delete mode 100644 dev/ZKAKit/src/Atom.cc delete mode 100644 dev/ZKAKit/src/BitMapMgr.cc delete mode 100644 dev/ZKAKit/src/CodeMgr.cc delete mode 100644 dev/ZKAKit/src/Crc32.cc delete mode 100644 dev/ZKAKit/src/CxxAbi-AMD64.cc delete mode 100644 dev/ZKAKit/src/CxxAbi-ARM64.cc delete mode 100644 dev/ZKAKit/src/Defines.cc delete mode 100644 dev/ZKAKit/src/DeviceMgr.cc delete mode 100644 dev/ZKAKit/src/DriveMgr.cc delete mode 100644 dev/ZKAKit/src/ErrorOr.cc delete mode 100644 dev/ZKAKit/src/FS/HPFS.cc delete mode 100644 dev/ZKAKit/src/FS/NeFS.cc delete mode 100644 dev/ZKAKit/src/FileMgr.cc delete mode 100644 dev/ZKAKit/src/GUIDWizard.cc delete mode 100644 dev/ZKAKit/src/GUIDWrapper.cc delete mode 100644 dev/ZKAKit/src/HardwareThreadScheduler.cc delete mode 100644 dev/ZKAKit/src/Heap.cc delete mode 100644 dev/ZKAKit/src/IDLLObject.cc delete mode 100644 dev/ZKAKit/src/IPEFDLLObject.cc delete mode 100644 dev/ZKAKit/src/IndexableProperty.cc delete mode 100644 dev/ZKAKit/src/Json.cc delete mode 100644 dev/ZKAKit/src/KString.cc delete mode 100644 dev/ZKAKit/src/KernelMain.cc delete mode 100644 dev/ZKAKit/src/LPC.cc delete mode 100644 dev/ZKAKit/src/LockDelegate.cc delete mode 100644 dev/ZKAKit/src/MutableArray.cc delete mode 100644 dev/ZKAKit/src/NeFS+FileMgr.cc delete mode 100644 dev/ZKAKit/src/NeFS+IO.cc delete mode 100644 dev/ZKAKit/src/Network/IP.cc delete mode 100644 dev/ZKAKit/src/Network/IPC.cc delete mode 100644 dev/ZKAKit/src/Network/NetworkDevice.cc delete mode 100644 dev/ZKAKit/src/New+Delete.cc delete mode 100644 dev/ZKAKit/src/OwnPtr.cc delete mode 100644 dev/ZKAKit/src/PEFCodeMgr.cc delete mode 100644 dev/ZKAKit/src/PRDT.cc delete mode 100644 dev/ZKAKit/src/PageMgr.cc delete mode 100644 dev/ZKAKit/src/Pmm.cc delete mode 100644 dev/ZKAKit/src/Property.cc delete mode 100644 dev/ZKAKit/src/Ref.cc delete mode 100644 dev/ZKAKit/src/Semaphore.cc delete mode 100644 dev/ZKAKit/src/Stop.cc delete mode 100644 dev/ZKAKit/src/Storage/AHCIDeviceInterface.cc delete mode 100644 dev/ZKAKit/src/Storage/ATADeviceInterface.cc delete mode 100644 dev/ZKAKit/src/Storage/NVMEDeviceInterface.cc delete mode 100644 dev/ZKAKit/src/Storage/SCSIDeviceInterface.cc delete mode 100644 dev/ZKAKit/src/Stream.cc delete mode 100644 dev/ZKAKit/src/ThreadLocalStorage.cc delete mode 100644 dev/ZKAKit/src/Timer.cc delete mode 100644 dev/ZKAKit/src/User.cc delete mode 100644 dev/ZKAKit/src/UserProcessScheduler.cc delete mode 100644 dev/ZKAKit/src/UserProcessTeam.cc delete mode 100644 dev/ZKAKit/src/Utils.cc delete mode 100644 dev/ZKAKit/src/Variant.cc (limited to 'dev') diff --git a/dev/BootLoader/BootKit/BitManip.h b/dev/BootLoader/BootKit/BitManip.h new file mode 100644 index 00000000..7146d266 --- /dev/null +++ b/dev/BootLoader/BootKit/BitManip.h @@ -0,0 +1,20 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#ifndef __BITMANIP_H__ +#define __BITMANIP_H__ + +/// File: BitManip.h +/// Purpose: Bit manipulation helpers, based on coreboot-dev. + +#define bk_set_bit(X, O) X = (1 << O) | X +#define bk_clear_bit(X, O) X = ~(1 << O) & X +#define bk_toogle(X, O) X = (1 << O) ^ X +#define bk_lsb(X) X = X & -X +#define bk_msb(X) X = -(mp_lsb(X)) & X +#define bk_look_for_bit(X, O) (1 << O) | X + +#endif // ifndef __BITMANIP_H__ diff --git a/dev/BootLoader/BootKit/BootKit.h b/dev/BootLoader/BootKit/BootKit.h new file mode 100644 index 00000000..c489262d --- /dev/null +++ b/dev/BootLoader/BootKit/BootKit.h @@ -0,0 +1,393 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +/***********************************************************************************/ +/// @file BootKit.h +/// @brief Bootloader Application Programming Interface. +/***********************************************************************************/ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +/// include NeFS header and Support header as well. + +#include +#include + +/***********************************************************************************/ +/// Include other APIs. +/***********************************************************************************/ + +#include +#include + +#include + +/***********************************************************************************/ +/// Framebuffer helpers. +/***********************************************************************************/ + +namespace EFI +{ + EXTERN void ThrowError(const WideChar* errorCode, + const WideChar* reason) noexcept; +} // namespace EFI + +namespace Boot +{ + class BTextWriter; + class BFileReader; + class BThread; + class BVersionString; + + typedef Char* PEFImagePtr; + typedef Char* PEImagePtr; + + typedef WideChar CharacterTypeUTF16; + typedef Char CharacterTypeUTF8; + + using namespace Kernel; + + /** + * @brief BootKit Text Writer class + * Writes to UEFI StdOut. + */ + class BTextWriter final + { + BTextWriter& _Write(const Long& num); + + public: + BTextWriter& Write(const Long& num); + BTextWriter& Write(const Char* str); + BTextWriter& Write(const CharacterTypeUTF16* str); + BTextWriter& WriteCharacter(CharacterTypeUTF16 c); + BTextWriter& Write(const UChar* str); + + public: + explicit BTextWriter() = default; + ~BTextWriter() = default; + + public: + BTextWriter& operator=(const BTextWriter&) = default; + BTextWriter(const BTextWriter&) = default; + }; + + Kernel::SizeT BCopyMem(CharacterTypeUTF16* dest, CharacterTypeUTF16* src, const Kernel::SizeT len); + + Kernel::SizeT BSetMem(CharacterTypeUTF8* src, const CharacterTypeUTF8 byte, const Kernel::SizeT len); + + /// String length functions. + + /// @brief get string length. + Kernel::SizeT BStrLen(const CharacterTypeUTF16* ptr); + + /// @brief set memory with custom value. + Kernel::SizeT BSetMem(CharacterTypeUTF16* src, const CharacterTypeUTF16 byte, const Kernel::SizeT len); + + /** + * @brief BootKit File Reader class + * Reads the Firmware Boot partition and filesystem. + */ + class BFileReader final + { + public: + explicit BFileReader(const CharacterTypeUTF16* path, + EfiHandlePtr ImageHandle); + ~BFileReader(); + + public: + Void ReadAll(SizeT until, SizeT chunk = kib_cast(4), UIntPtr out_address = 0UL); + + enum + { + kOperationOkay, + kNotSupported, + kEmptyDirectory, + kNoSuchEntry, + kIsDirectory, + kTooSmall, + kCount, + }; + + /// @brief error code getter. + /// @return the error code. + Int32& Error(); + + /// @brief blob getter. + /// @return the blob. + VoidPtr Blob(); + + /// @breif Size getter. + /// @return the size of the file. + UInt64& Size(); + + public: + BFileReader& operator=(const BFileReader&) = default; + BFileReader(const BFileReader&) = default; + + private: + Int32 mErrorCode{kOperationOkay}; + VoidPtr mBlob{nullptr}; + CharacterTypeUTF16 mPath[kPathLen]; + BTextWriter mWriter; + EfiFileProtocol* mFile{nullptr}; + UInt64 mSizeFile{0}; + EfiFileProtocol* mRootFs; + }; + + typedef UInt8* BlobType; + + class BVersionString final + { + public: + static const CharacterTypeUTF8* The() + { + return BOOTLOADER_VERSION; + } + }; + + /***********************************************************************************/ + /// Provide some useful processor features. + /***********************************************************************************/ + +#ifdef __EFI_x86_64__ + + /*** + * Common processor instructions. + */ + + EXTERN_C void rt_out8(UInt16 port, UInt8 value); + EXTERN_C void rt_out16(UInt16 port, UInt16 value); + EXTERN_C void rt_out32(UInt16 port, UInt32 value); + EXTERN_C UInt8 rt_in8(UInt16 port); + EXTERN_C UInt16 In16(UInt16 port); + EXTERN_C UInt32 rt_in32(UInt16 port); + + EXTERN_C void rt_hlt(); + EXTERN_C void rt_cli(); + EXTERN_C void rt_sti(); + EXTERN_C void rt_cld(); + EXTERN_C void rt_std(); + +#endif // __EFI_x86_64__ + + static inline const UInt32 kRgbRed = 0x000000FF; + static inline const UInt32 kRgbGreen = 0x0000FF00; + static inline const UInt32 kRgbBlue = 0x00FF0000; + static inline const UInt32 kRgbBlack = 0x00000000; + static inline const UInt32 kRgbWhite = 0x00FFFFFF; + +#define kBKBootFileMime "boot-x/file" +#define kBKBootDirMime "boot-x/dir" + + /// @brief BootKit Drive Formatter. + template + class BDiskFormatFactory final + { + public: + /// @brief File entry for **BDiskFormatFactory**. + struct BFileDescriptor final + { + Char fFileName[kNeFSNodeNameLen]; + Int32 fKind; + }; + + public: + explicit BDiskFormatFactory() = default; + explicit BDiskFormatFactory(BootDev dev) + : fDiskDev(dev) + { + } + + ~BDiskFormatFactory() = default; + + ZKA_COPY_DELETE(BDiskFormatFactory); + + /// @brief Format disk using partition name and fileBlobs. + /// @param Partition partName the target partition name. + /// @param fileBlobs blobs array. + /// @param blobCount blobs array count. + /// @retval True disk has been formatted. + /// @retval False failed to format. + Boolean Format(const Char* partName, BFileDescriptor* fileBlobs, SizeT blobCount); + + /// @brief check if partition is good. + Bool IsPartitionValid() noexcept + { + fDiskDev.Leak().mBase = (kNeFSRootCatalogStartAddress); + fDiskDev.Leak().mSize = BootDev::kSectorSize; + + Char buf[BootDev::kSectorSize] = {0}; + + fDiskDev.Read(buf, BootDev::kSectorSize); + + NFS_ROOT_PARTITION_BLOCK* blockPart = reinterpret_cast(buf); + + BTextWriter writer; + + for (SizeT indexMag = 0UL; indexMag < kNeFSIdentLen; ++indexMag) + { + if (blockPart->Ident[indexMag] != kNeFSIdent[indexMag]) + return false; + } + + if (blockPart->DiskSize != this->fDiskDev.GetDiskSize() || + blockPart->DiskSize < 1 || + blockPart->SectorSize != BootDev::kSectorSize || + blockPart->Version != kNeFSVersionInteger || + blockPart->StartCatalog == 0) + { + return false; + } + else if (blockPart->PartitionName[0] == 0) + { + return false; + } + + writer.Write(L"BootZ: Partition: ").Write(blockPart->PartitionName).Write(L" is healthy.\r"); + + return true; + } + + private: + /// @brief Write all of the requested catalogs into the filesystem. + /// @param fileBlobs the blobs. + /// @param blobCount the number of blobs to write. + /// @param partBlock the NeFS partition block. + Boolean WriteRootCatalog(BFileDescriptor* fileBlobs, SizeT blobCount, NFS_ROOT_PARTITION_BLOCK& partBlock) + { + BFileDescriptor* blob = fileBlobs; + Lba startLba = partBlock.StartCatalog; + BTextWriter writer; + + NFS_CATALOG_STRUCT catalogKind{0}; + + constexpr auto cNeFSCatalogPadding = 4; + + catalogKind.PrevSibling = startLba; + catalogKind.NextSibling = (startLba + sizeof(NFS_CATALOG_STRUCT) * cNeFSCatalogPadding); + + /// Fill catalog kind. + catalogKind.Kind = blob->fKind; + catalogKind.Flags = kNeFSFlagCreated; + + --partBlock.FreeCatalog; + --partBlock.FreeSectors; + + CopyMem(catalogKind.Name, blob->fFileName, StrLen(blob->fFileName)); + + fDiskDev.Leak().mBase = startLba; + fDiskDev.Leak().mSize = sizeof(NFS_CATALOG_STRUCT); + + fDiskDev.Write((Char*)&catalogKind, sizeof(NFS_CATALOG_STRUCT)); + + writer.Write(L"BootZ: Wrote directory: ").Write(blob->fFileName).Write(L"\r"); + + return true; + } + + private: + BootDev fDiskDev; + }; + + /// @brief Format disk. + /// @param Partition Name + /// @param Blobs. + /// @param Number of blobs. + /// @retval True disk has been formatted. + /// @retval False failed to format. + template + inline Boolean BDiskFormatFactory::Format(const Char* partName, + BDiskFormatFactory::BFileDescriptor* fileBlobs, + SizeT blobCount) + { + if (!fileBlobs || !blobCount) + return false; /// sanity check + + /// convert the sector into something that the disk understands. + SizeT sectorSz = sizeof(NFS_ROOT_PARTITION_BLOCK); + + /// @note A catalog roughly equal to a sector. + + constexpr auto kMinimumDiskSize = kNeFSMinimumDiskSize; // at minimum. + + /// @note also look at EPM headers, for free part blocks. + + if (fDiskDev.GetDiskSize() < kMinimumDiskSize) + { + cg_init(); + + CGDrawBitMapInRegion(zka_no_disk, ZKA_NO_DISK_HEIGHT, ZKA_NO_DISK_WIDTH, (kHandoverHeader->f_GOP.f_Width - ZKA_NO_DISK_WIDTH) / 2, (kHandoverHeader->f_GOP.f_Height - ZKA_NO_DISK_HEIGHT) / 2); + EFI::ThrowError(L"Drive-Too-Tiny", L"Can't format a New Filesystem partition here."); + return false; + } + + NFS_ROOT_PARTITION_BLOCK partBlock{0}; + + CopyMem(partBlock.Ident, kNeFSIdent, kNeFSIdentLen - 1); + CopyMem(partBlock.PartitionName, partName, StrLen(partName)); + + partBlock.Version = kNeFSVersionInteger; + partBlock.CatalogCount = blobCount; + partBlock.Kind = kNeFSHardDrive; + partBlock.SectorSize = sectorSz; + partBlock.FreeCatalog = fDiskDev.GetSectorsCount() / sizeof(NFS_CATALOG_STRUCT); + partBlock.SectorCount = fDiskDev.GetSectorsCount(); + partBlock.FreeSectors = fDiskDev.GetSectorsCount(); + partBlock.StartCatalog = kNeFSCatalogStartAddress; + partBlock.DiskSize = fDiskDev.GetDiskSize(); + partBlock.Flags = kNeFSPartitionTypeBoot | kNeFSPartitionTypeStandard; + + fDiskDev.Leak().mBase = kNeFSRootCatalogStartAddress; + fDiskDev.Leak().mSize = sectorSz; + + fDiskDev.Write((Char*)&partBlock, sectorSz); + + BOOT_BLOCK_STRUCT epm_boot{0}; + + constexpr auto cFsName = "NeFS"; + constexpr auto cBlockName = "ZKA:"; + + CopyMem(epm_boot.Fs, reinterpret_cast(const_cast(cFsName)), StrLen(cFsName)); + + epm_boot.FsVersion = kNeFSVersionInteger; + epm_boot.LbaStart = kNeFSRootCatalogStartAddress; + epm_boot.SectorSz = partBlock.SectorSize; + epm_boot.Kind = kEPMZkaOS; + epm_boot.NumBlocks = partBlock.CatalogCount; + + CopyMem(epm_boot.Name, reinterpret_cast(const_cast(cBlockName)), StrLen(cBlockName)); + CopyMem(epm_boot.Magic, reinterpret_cast(const_cast(kEPMMagic)), StrLen(kEPMMagic)); + + fDiskDev.Leak().mBase = 1; // always always resies at zero block. + fDiskDev.Leak().mSize = BootDev::kSectorSize; + + fDiskDev.Write((Char*)&epm_boot, sectorSz); + + /// if we can write a root catalog, then write the partition block. + if (this->WriteRootCatalog(fileBlobs, blobCount, partBlock)) + { + BTextWriter writer; + writer.Write(L"BootZ: Drive formatted.\r"); + + return true; + } + else + { + EFI::ThrowError(L"Filesystem-Failure-Part", L"Filesystem couldn't be partitioned, this drive cannot be formatted as an explicit partition map."); + } + + return false; + } +} // namespace Boot diff --git a/dev/BootLoader/BootKit/Device.h b/dev/BootLoader/BootKit/Device.h new file mode 100644 index 00000000..cbe08ab8 --- /dev/null +++ b/dev/BootLoader/BootKit/Device.h @@ -0,0 +1,37 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include +#include + +using namespace Kernel; + +/// @brief Device type. +class Device +{ +public: + explicit Device() = default; + virtual ~Device() = default; + + ZKA_MOVE_DEFAULT(Device); + + struct Trait + { + SizeT mBase{1024}; + SizeT mSize{1024}; + }; + + virtual Trait& Leak() = 0; + + virtual Device& Read(Char* Buf, const SizeT& SecCount) = 0; + virtual Device& Write(Char* Buf, const SizeT& SecCount) = 0; +}; + +typedef Device BootDevice; +typedef Device NetworkDevice; +typedef Device DiskDevice; diff --git a/dev/BootLoader/BootKit/EPM.h b/dev/BootLoader/BootKit/EPM.h new file mode 100644 index 00000000..24ebbab9 --- /dev/null +++ b/dev/BootLoader/BootKit/EPM.h @@ -0,0 +1,9 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include diff --git a/dev/BootLoader/BootKit/HW/ATA.h b/dev/BootLoader/BootKit/HW/ATA.h new file mode 100644 index 00000000..e1a0b672 --- /dev/null +++ b/dev/BootLoader/BootKit/HW/ATA.h @@ -0,0 +1,58 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include +#include + +using namespace Kernel; + +class BootDeviceATA final : public Device +{ +public: + enum + { + kPrimary = ATA_PRIMARY_IO, + kSecondary = ATA_SECONDARY_IO, + }; + + explicit BootDeviceATA() noexcept; + ~BootDeviceATA() = default; + + ZKA_COPY_DELETE(BootDeviceATA); + + enum + { + kSectorSize = kATASectorSize + }; + + struct ATATrait final : public Device::Trait + { + UInt16 mBus{kPrimary}; + UInt8 mMaster{0}; + Boolean mErr{false}; + + operator bool() + { + return !mErr; + } + }; + +public: + operator bool(); + + SizeT GetSectorsCount() noexcept; + SizeT GetDiskSize() noexcept; + + BootDeviceATA& Read(Char* Buf, const SizeT& SecCount) override; + BootDeviceATA& Write(Char* Buf, const SizeT& SecCount) override; + + ATATrait& Leak() override; + +private: + ATATrait mTrait; +}; diff --git a/dev/BootLoader/BootKit/HW/SATA.h b/dev/BootLoader/BootKit/HW/SATA.h new file mode 100644 index 00000000..ffb903f4 --- /dev/null +++ b/dev/BootLoader/BootKit/HW/SATA.h @@ -0,0 +1,46 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include +#include + +class BootDeviceSATA final +{ +public: + explicit BootDeviceSATA() noexcept; + ~BootDeviceSATA() = default; + + ZKA_COPY_DEFAULT(BootDeviceSATA); + + struct SATATrait final + { + Kernel::SizeT mBase{1024}; + Kernel::Boolean mErr{false}; + Kernel::Boolean mDetected{false}; + + operator bool() + { + return !this->mErr; + } + }; + + operator bool() + { + return this->Leak().mDetected; + } + + BootDeviceSATA& Read(Kernel::WideChar* Buf, const Kernel::SizeT& SecCount); + BootDeviceSATA& Write(Kernel::WideChar* Buf, const Kernel::SizeT& SecCount); + + SATATrait& Leak(); + +private: + SATATrait mTrait; +}; + +#define kAHCISectorSz 4096 diff --git a/dev/BootLoader/BootKit/Platform.h b/dev/BootLoader/BootKit/Platform.h new file mode 100644 index 00000000..886c340a --- /dev/null +++ b/dev/BootLoader/BootKit/Platform.h @@ -0,0 +1,32 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +/** + @file Platform.h + @brief Platform specific code. +*/ + +#ifdef __x86_64__ + +#ifdef __cplusplus +#ifndef EXTERN_C +#define EXTERN_C extern "C" +#endif +#else +#ifndef EXTERN_C +#define EXTERN_C extern +#endif +#endif // __cplusplus + +EXTERN_C void rt_halt(); +EXTERN_C void rt_cli(); +EXTERN_C void rt_sti(); +EXTERN_C void rt_cld(); +EXTERN_C void rt_std(); + +#endif /* ifdef __x86_64__ */ diff --git a/dev/BootLoader/BootKit/Protocol.h b/dev/BootLoader/BootKit/Protocol.h new file mode 100644 index 00000000..07b381a7 --- /dev/null +++ b/dev/BootLoader/BootKit/Protocol.h @@ -0,0 +1,10 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include +#include diff --git a/dev/BootLoader/BootKit/Rsrc/zka_disk.rsrc b/dev/BootLoader/BootKit/Rsrc/zka_disk.rsrc new file mode 100644 index 00000000..ce980b7b --- /dev/null +++ b/dev/BootLoader/BootKit/Rsrc/zka_disk.rsrc @@ -0,0 +1,116 @@ +#define ZKA_DISK_HEIGHT 110 +#define ZKA_DISK_WIDTH 110 + +// array size is 36300 +static const unsigned int zka_disk[] = { + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x333333, 0x565656, 0x636363, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6a6a6a, 0x5f5f5f, 0x4d4d4d, 0x2b2b2b, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x464646, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x6a6a6a, 0x3b3b3b, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x3d3d3d, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x393939, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x252525, 0x676767, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x606060, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4c4c4c, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x3d3d3d, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x616161, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x525252, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x242424, 0x767676, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x676767, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x393939, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7e7e7e, 0x292929, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4e4e4e, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x3f3f3f, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x666666, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x555555, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x222222, 0x7c7c7c, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x6d6d6d, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x393939, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x868686, 0x292929, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x515151, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x404040, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x6a6a6a, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x828282, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x727272, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x383838, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x8e8e8e, 0x2a2a2a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x525252, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x414141, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x6e6e6e, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x5c5c5c, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x868686, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x787878, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x373737, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x959595, 0x2a2a2a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x545454, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0x444444, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x707070, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0x5e5e5e, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x8b8b8b, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0x7c7c7c, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x363636, 0xa7a7a7, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0x9c9c9c, 0x2a2a2a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x545454, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0x464646, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x717171, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0x636363, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x8e8e8e, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0x818181, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x343434, 0xacacac, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xa3a3a3, 0x2a2a2a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x545454, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0x484848, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x727272, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0x676767, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x909090, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0x868686, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x313131, 0xb0b0b0, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xa9a9a9, 0x2a2a2a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x525252, 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, 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, 0x494949, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x727272, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0x6a6a6a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x929292, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0x8c8c8c, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x2e2e2e, 0xb4b4b4, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xafafaf, 0x292929, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x505050, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0x4b4b4b, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x717171, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0x6e6e6e, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x939393, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0x929292, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x2a2a2a, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0x292929, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4c4c4c, 0x4c4c4c, 0x4c4c4c, 0x4c4c4c, 0x4b4b4b, 0x4b4b4b, 0x4b4b4b, 0x4b4b4b, 0x4a4a4a, 0x4a4a4a, 0x4a4a4a, 0x4a4a4a, 0x494949, 0x494949, 0x494949, 0x494949, 0x484848, 0x484848, 0x484848, 0x484848, 0x474747, 0x474747, 0x474747, 0x464646, 0x464646, 0x464646, 0x464646, 0x454545, 0x454545, 0x454545, 0x454545, 0x444444, 0x444444, 0x444444, 0x444444, 0x434343, 0x434343, 0x434343, 0x434343, 0x424242, 0x424242, 0x424242, 0x414141, 0x414141, 0x414141, 0x414141, 0x404040, 0x404040, 0x404040, 0x404040, 0x3f3f3f, 0x3f3f3f, 0x3f3f3f, 0x3f3f3f, 0x3e3e3e, 0x3e3e3e, 0x3e3e3e, 0x3e3e3e, 0x3d3d3d, 0x3d3d3d, 0x3d3d3d, 0x3d3d3d, 0x3c3c3c, 0x3c3c3c, 0x3c3c3c, 0x3c3c3c, 0x3b3b3b, 0x3b3b3b, 0x3b3b3b, 0x3a3a3a, 0x3a3a3a, 0x3a3a3a, 0x3a3a3a, 0x393939, 0x393939, 0x393939, 0x393939, 0x383838, 0x383838, 0x383838, 0x383838, 0x373737, 0x373737, 0x373737, 0x373737, 0x363636, 0x363636, 0x363636, 0x353535, 0x353535, 0x353535, 0x353535, 0x343434, 0x343434, 0x343434, 0x343434, 0x333333, 0x333333, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc2c2c2, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xababab, 0xababab, 0xa9a9a9, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x949494, 0x949494, 0x929292, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7b7b7b, 0x7b7b7b, 0x797979, 0x797979, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xcfcfcf, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0x9f9f9f, 0x9f9f9f, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x9b9b9b, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x888888, 0x888888, 0x868686, 0x868686, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x6f6f6f, 0x6f6f6f, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbebebe, 0xbcbcbc, 0xbcbcbc, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xa9a9a9, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa5a5a5, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcbcbcb, 0xc9c9c9, 0xc9c9c9, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb2b2b2, 0xb0b0b0, 0xb0b0b0, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x9b9b9b, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x848484, 0x848484, 0x828282, 0x828282, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x5a5a5a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc2c2c2, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xa9a9a9, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x929292, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7b7b7b, 0x7b7b7b, 0x797979, 0x797979, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xcfcfcf, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x9b9b9b, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x868686, 0x868686, 0x848484, 0x848484, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x6f6f6f, 0x6f6f6f, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbebebe, 0xbebebe, 0xbcbcbc, 0xbcbcbc, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa5a5a5, 0xa3a3a3, 0xa3a3a3, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcbcbcb, 0xcbcbcb, 0xc9c9c9, 0xc9c9c9, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb2b2b2, 0xb0b0b0, 0xb0b0b0, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x9b9b9b, 0x999999, 0x999999, 0x979797, 0x979797, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x848484, 0x848484, 0x828282, 0x828282, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x5a5a5a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc2c2c2, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xababab, 0xababab, 0xa9a9a9, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x949494, 0x949494, 0x929292, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7b7b7b, 0x7b7b7b, 0x797979, 0x797979, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xcfcfcf, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0x9f9f9f, 0x9f9f9f, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x9b9b9b, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x888888, 0x888888, 0x868686, 0x393939, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4d4d4d, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x6f6f6f, 0x6f6f6f, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbebebe, 0xbcbcbc, 0xbcbcbc, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xa9a9a9, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa5a5a5, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x393939, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4c4c4c, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcbcbcb, 0xc9c9c9, 0xc9c9c9, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb2b2b2, 0xb0b0b0, 0xb0b0b0, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x9b9b9b, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x393939, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4d4d4d, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x5a5a5a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc2c2c2, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xa9a9a9, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x929292, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x393939, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4c4c4c, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xcfcfcf, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x9b9b9b, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x868686, 0x393939, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4d4d4d, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x6f6f6f, 0x6f6f6f, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbebebe, 0xbebebe, 0xbcbcbc, 0xbcbcbc, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa5a5a5, 0xa3a3a3, 0xa3a3a3, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x393939, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4c4c4c, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcbcbcb, 0xcbcbcb, 0xc9c9c9, 0xc9c9c9, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb2b2b2, 0xb0b0b0, 0xb0b0b0, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x9b9b9b, 0x999999, 0x999999, 0x979797, 0x979797, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x848484, 0x848484, 0x828282, 0x828282, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x5a5a5a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc2c2c2, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xababab, 0xababab, 0xa9a9a9, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x949494, 0x949494, 0x929292, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7b7b7b, 0x7b7b7b, 0x797979, 0x797979, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xcfcfcf, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0x9f9f9f, 0x9f9f9f, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x9b9b9b, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x888888, 0x888888, 0x868686, 0x868686, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x6f6f6f, 0x6f6f6f, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbebebe, 0xbcbcbc, 0xbcbcbc, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xa9a9a9, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa5a5a5, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcbcbcb, 0xc9c9c9, 0xc9c9c9, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb2b2b2, 0xb0b0b0, 0xb0b0b0, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x9b9b9b, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x848484, 0x848484, 0x828282, 0x828282, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x5a5a5a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc2c2c2, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xa9a9a9, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x929292, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7b7b7b, 0x7b7b7b, 0x797979, 0x797979, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xc6c6c6, 0xd1d1d1, 0xcfcfcf, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x9b9b9b, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x868686, 0x868686, 0x848484, 0x848484, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x6f6f6f, 0x6f6f6f, 0x6d6d6d, 0x565656, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x9a9a9a, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbebebe, 0xbebebe, 0xbcbcbc, 0xbcbcbc, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa5a5a5, 0xa3a3a3, 0xa3a3a3, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x464646, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x797979, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcbcbcb, 0xcbcbcb, 0xc9c9c9, 0xc9c9c9, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb2b2b2, 0xb0b0b0, 0xb0b0b0, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x9b9b9b, 0x999999, 0x999999, 0x979797, 0x979797, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x848484, 0x848484, 0x828282, 0x828282, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x353535, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xbfbfbf, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc2c2c2, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xababab, 0xababab, 0xa9a9a9, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x949494, 0x949494, 0x929292, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7b7b7b, 0x7b7b7b, 0x797979, 0x797979, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x464646, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x464646, 0xcfcfcf, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0x9f9f9f, 0x9f9f9f, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x9b9b9b, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x888888, 0x888888, 0x868686, 0x868686, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x6f6f6f, 0x676767, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x7f7f7f, 0xbababa, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbebebe, 0xbcbcbc, 0xbcbcbc, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xa9a9a9, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa5a5a5, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x626262, 0x484848, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x3a3a3a, 0x4b4b4b, 0x4b4b4b, 0x4a4a4a, 0x4a4a4a, 0x4a4a4a, 0x4a4a4a, 0x494949, 0x494949, 0x494949, 0x494949, 0x484848, 0x484848, 0x484848, 0x484848, 0x474747, 0x474747, 0x474747, 0x464646, 0x464646, 0x464646, 0x464646, 0x454545, 0x454545, 0x454545, 0x454545, 0x444444, 0x444444, 0x444444, 0x444444, 0x434343, 0x434343, 0x434343, 0x424242, 0x424242, 0x424242, 0x424242, 0x414141, 0x414141, 0x414141, 0x414141, 0x404040, 0x404040, 0x404040, 0x404040, 0x3f3f3f, 0x3f3f3f, 0x3f3f3f, 0x3f3f3f, 0x3e3e3e, 0x3e3e3e, 0x3e3e3e, 0x3e3e3e, 0x3d3d3d, 0x3d3d3d, 0x3d3d3d, 0x3d3d3d, 0x3c3c3c, 0x3c3c3c, 0x3c3c3c, 0x3c3c3c, 0x3b3b3b, 0x3b3b3b, 0x3b3b3b, 0x3a3a3a, 0x3a3a3a, 0x3a3a3a, 0x3a3a3a, 0x393939, 0x393939, 0x393939, 0x393939, 0x383838, 0x383838, 0x383838, 0x383838, 0x373737, 0x373737, 0x373737, 0x373737, 0x363636, 0x363636, 0x363636, 0x353535, 0x353535, 0x353535, 0x353535, 0x272727, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020 +}; \ No newline at end of file diff --git a/dev/BootLoader/BootKit/Rsrc/zka_has_disk.rsrc b/dev/BootLoader/BootKit/Rsrc/zka_has_disk.rsrc new file mode 100644 index 00000000..bdc0bb99 --- /dev/null +++ b/dev/BootLoader/BootKit/Rsrc/zka_has_disk.rsrc @@ -0,0 +1,116 @@ +#define ZKA_HAS_DISK_HEIGHT 110 +#define ZKA_HAS_DISK_WIDTH 110 + +// array size is 36300 +static const unsigned int zka_has_disk[] = { + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x333333, 0x565656, 0x636363, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6a6a6a, 0x5f5f5f, 0x4d4d4d, 0x2b2b2b, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x464646, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x6a6a6a, 0x3b3b3b, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x3d3d3d, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x393939, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x252525, 0x676767, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x606060, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4c4c4c, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x3d3d3d, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x616161, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x525252, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x242424, 0x767676, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x676767, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x393939, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7e7e7e, 0x292929, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4e4e4e, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x3f3f3f, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x666666, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x555555, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x222222, 0x7c7c7c, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x6d6d6d, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x393939, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x868686, 0x292929, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x515151, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x404040, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x6a6a6a, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x89948e, 0x7ba08a, 0x6eaa87, 0x6cab87, 0x6cab87, 0x6caa87, 0x6caa87, 0x6da888, 0x799f8a, 0x89938e, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x828282, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x8c9590, 0x72ab88, 0x61b883, 0x52c37f, 0x4bc87e, 0x4ac77e, 0x4ac67e, 0x49c57e, 0x48c47f, 0x47c37f, 0x47c37f, 0x46c17f, 0x46c180, 0x45c07f, 0x4cba82, 0x5cb085, 0x6fa58a, 0x8c9490, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x727272, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x383838, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x899d90, 0x69b686, 0x4ecb7e, 0x4dca7e, 0x4cc97e, 0x4bc87e, 0x4bc77f, 0x4ac67f, 0x4ac67f, 0x49c57f, 0x48c47f, 0x47c37f, 0x47c280, 0x46c180, 0x46c080, 0x45bf80, 0x44bf81, 0x43be81, 0x43bd81, 0x42bc81, 0x62ac89, 0x869a91, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x8e8e8e, 0x2a2a2a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x525252, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x86a390, 0x61be83, 0x4ecb7d, 0x4dca7d, 0x4cca7e, 0x4bc87e, 0x4bc87e, 0x4ac77e, 0x4ac67e, 0x49c57e, 0x48c47f, 0x48c37f, 0x47c37f, 0x46c17f, 0x46c180, 0x45c080, 0x45bf80, 0x44be80, 0x43bd80, 0x42bc80, 0x42bc81, 0x41ba81, 0x41ba81, 0x40b981, 0x57af87, 0x839d92, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x414141, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x6e6e6e, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x929e96, 0x68bb87, 0x4fcd7e, 0x4ecc7d, 0x4ecb7e, 0x4dca7e, 0x4cc97e, 0x4bc87e, 0x4bc77f, 0x4ac67f, 0x4ac67f, 0x49c57f, 0x48c480, 0x47c380, 0x47c280, 0x46c180, 0x46c080, 0x45bf80, 0x44bf81, 0x43be81, 0x43bd81, 0x42bc81, 0x42bb82, 0x41ba82, 0x40b982, 0x40b882, 0x3fb882, 0x3eb782, 0x5fab8b, 0x919b97, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x5c5c5c, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x868686, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x88a893, 0x55c97f, 0x4ecc7d, 0x4ecb7d, 0x4dca7d, 0x4cc97e, 0x4bc87e, 0x4bc87e, 0x4ac77e, 0x4ac67e, 0x49c57e, 0x48c47f, 0x47c37f, 0x47c27f, 0x46c17f, 0x46c180, 0x45c080, 0x44bf80, 0x44be80, 0x43bd80, 0x42bc80, 0x42bb81, 0x41ba81, 0x41ba81, 0x40b981, 0x3fb882, 0x3eb782, 0x3eb682, 0x3db582, 0x3db482, 0x45b185, 0x83a195, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x787878, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x373737, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x7bb48f, 0x4fcd7d, 0x4fcc7d, 0x4ecb7d, 0x4dcb7e, 0x4cca7e, 0x4cc97e, 0x4bc87e, 0x4bc77f, 0x4ac67f, 0x49c57f, 0x49c47f, 0x48c480, 0x47c37f, 0x47c280, 0x46c180, 0x46c080, 0x45bf80, 0x44bf81, 0x43bd81, 0x43bd81, 0x42bc81, 0x42bb82, 0x41ba82, 0x40b982, 0x3fb882, 0x3fb882, 0x3eb682, 0x3eb683, 0x3db583, 0x3cb483, 0x3cb383, 0x3bb284, 0x74a693, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x959595, 0x2a2a2a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x545454, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0x76b88e, 0x4fcd7d, 0x4ecc7d, 0x4ecb7d, 0x4dca7d, 0x4cca7e, 0x4bc87e, 0x4bc87e, 0x4ac77e, 0x4ac67f, 0x49c57e, 0x48c47f, 0x48c37f, 0x47c37f, 0x46c17f, 0x46c180, 0x45c080, 0x45bf80, 0x44be80, 0x43bd81, 0x42bc81, 0x42bc81, 0x41ba81, 0x41ba81, 0x40b981, 0x3fb882, 0x3eb782, 0x3eb682, 0x3db582, 0x3db583, 0x3cb383, 0x3bb383, 0x3ab283, 0x3ab183, 0x39b083, 0x6fa893, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0x444444, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x707070, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0x79ba90, 0x4fcd7d, 0x4fcd7e, 0x4ecb7e, 0x4dcb7e, 0x4dca7e, 0x4cc97e, 0x4bc87e, 0x4bc77f, 0x4ac67f, 0x4ac67f, 0x49c47f, 0x48c480, 0x47c380, 0x47c280, 0x46c180, 0x46c080, 0x45bf80, 0x44bf81, 0x43bd81, 0x43bd81, 0x42bc81, 0x42bb82, 0x41ba82, 0x40b982, 0x40b882, 0x3fb883, 0x3eb682, 0x3eb683, 0x3db583, 0x3cb483, 0x3cb383, 0x3bb284, 0x3ab184, 0x3ab184, 0x39af84, 0x38af85, 0x6da894, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0x5e5e5e, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x8b8b8b, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0x7db892, 0x4fcd7d, 0x4ecc7d, 0x4ecb7d, 0x4dca7d, 0x4cc97e, 0x4bc87e, 0x4bc87e, 0x4ac67e, 0x4ac67e, 0x49c57e, 0x48c47f, 0x47c37f, 0x47c27f, 0x46c17f, 0x46c180, 0x45bf80, 0x44bf80, 0x43be80, 0x43bd80, 0x42bc80, 0x42bb81, 0x41ba81, 0x40ba81, 0x3fb881, 0x3fb882, 0x3eb782, 0x3eb682, 0x3db582, 0x3cb482, 0x3cb382, 0x3bb383, 0x3ab183, 0x3ab183, 0x39b083, 0x39af84, 0x38ae84, 0x37ad84, 0x36ac84, 0x74a897, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0x7c7c7c, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x363636, 0xa7a7a7, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0x90b39d, 0x4fcd7d, 0x4fcc7d, 0x4ecb7d, 0x4dcb7e, 0x4cc97e, 0x4cc97e, 0x4bc87e, 0x4bc77f, 0x4ac67f, 0x49c57f, 0x48c47f, 0x48c480, 0x47c27f, 0x47c280, 0x46c180, 0x45c080, 0x44bf80, 0x44be81, 0x43bd81, 0x43bd81, 0x42bb81, 0x41bb82, 0x41ba82, 0x40b982, 0x3fb882, 0x3fb782, 0x3eb682, 0x3eb683, 0x3db483, 0x3cb483, 0x3bb383, 0x3bb284, 0x3ab184, 0x3ab084, 0x39af84, 0x38af84, 0x37ad84, 0x37ad85, 0x36ac85, 0x36ab85, 0x8aa99f, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0x9c9c9c, 0x2a2a2a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x545454, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xa2afa6, 0x56ca80, 0x4ecc7d, 0x4ecb7d, 0x4dca7d, 0x4cc97e, 0x4bc87e, 0x4bc87e, 0x4ac67e, 0x4ac67f, 0x49c57e, 0x48c47f, 0x47c37f, 0x47c27f, 0x46c17f, 0x46c180, 0x45bf80, 0x44bf80, 0x43be80, 0x43bd81, 0x42bc81, 0x42bb81, 0x41ba81, 0x40ba81, 0x40b881, 0x3fb882, 0x3eb782, 0x3eb682, 0x3db582, 0x3db483, 0x3cb383, 0x3bb383, 0x3ab183, 0x3ab183, 0x39b083, 0x39af84, 0x38ae84, 0x37ad84, 0x36ac84, 0x36ac85, 0x35ab85, 0x35aa85, 0x3ea988, 0xa2aba8, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0x464646, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x717171, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0x70c28e, 0x4fcc7e, 0x4ecb7e, 0x4dcb7e, 0x4cca7e, 0x4cc97e, 0x4bc87e, 0x4bc77f, 0x4ac67f, 0x49c57f, 0x48c47f, 0x48c480, 0x47c380, 0x47c280, 0x46c180, 0x45c080, 0x45bf80, 0x44be81, 0x43bd81, 0x43bd81, 0x42bc81, 0x42bb82, 0x41ba82, 0x40b982, 0x3fb882, 0x3fb783, 0x3eb682, 0x3eb683, 0x3db583, 0x3cb483, 0x3bb383, 0x3bb284, 0x3ab184, 0x3ab084, 0x39af84, 0x38af85, 0x38ae85, 0x37ad85, 0x36ac85, 0x36ab85, 0x35aa85, 0x34a986, 0x34a886, 0x63aa96, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0x636363, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x8e8e8e, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0x9bb6a5, 0x4ecc7d, 0x4dcb7d, 0x4cca7d, 0x4cc97e, 0x4bc87e, 0x4bc77e, 0x4ac67e, 0x49c67e, 0x49c57e, 0x48c47f, 0x47c37f, 0x47c27f, 0x46c17f, 0x46c080, 0x45bf80, 0x44bf80, 0x43be80, 0x43bd81, 0x42bc80, 0x42bb81, 0x41ba81, 0x40b981, 0x3fb881, 0x3fb882, 0x3eb782, 0x3eb682, 0x3db582, 0x3cb483, 0x3bb383, 0x3bb283, 0x3ab183, 0x3ab183, 0x39b083, 0x38af84, 0x37ae84, 0x37ad84, 0x36ac84, 0x36ab85, 0x35aa85, 0x34aa85, 0x34a985, 0x33a885, 0x32a785, 0x32a686, 0x9baea9, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0x818181, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x343434, 0xacacac, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0x68c68b, 0x4ecb7d, 0x4dcb7e, 0x4cc97e, 0x4cc97e, 0x4bc87e, 0x4bc77f, 0x4ac67f, 0x49c57f, 0x48c47f, 0x48c480, 0x47c27f, 0x47c280, 0x46c180, 0x45c080, 0x44bf80, 0x44be81, 0x43bd81, 0x43bd81, 0x42bb81, 0x41bb82, 0x41ba82, 0x40b982, 0x3fb882, 0x3fb782, 0x3eb682, 0x3eb683, 0x3db483, 0x3cb483, 0x3bb383, 0x3bb284, 0x3ab184, 0x3ab084, 0x39af84, 0x38af85, 0x37ad84, 0x37ad85, 0x36ac85, 0x36ab85, 0x35aa85, 0x34a986, 0x33a886, 0x33a886, 0x32a686, 0x32a687, 0x57a993, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xa3a3a3, 0x2a2a2a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x545454, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xa0baaa, 0x4dcb7d, 0x4dca7d, 0x4cc97e, 0x4bc87e, 0x4bc77e, 0x4ac67e, 0x4ac67f, 0x49c57e, 0x48c47f, 0x47c37f, 0x47c27f, 0x46c17f, 0x46c080, 0x45bf80, 0x44bf80, 0x43be80, 0x43bd81, 0x42bc81, 0x42bb81, 0x41ba81, 0x40b981, 0x3fb881, 0x3fb882, 0x3eb782, 0x3eb682, 0x3db582, 0x3cb483, 0x3bb383, 0x3bb283, 0x3ab183, 0x3ab184, 0x39b083, 0x38af84, 0x38ae84, 0x37ad84, 0x36ac84, 0x36ab85, 0x35aa85, 0x35aa85, 0x34a985, 0x33a886, 0x32a786, 0x32a686, 0x31a586, 0x31a486, 0x30a386, 0x9eb2ad, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0x484848, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x727272, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0x72c592, 0x4dcb7e, 0x4cc97e, 0x4cc97e, 0x4bc87e, 0x4bc77f, 0x4ac67f, 0x49c57f, 0x48c47f, 0x48c480, 0x47c280, 0x47c280, 0x46c180, 0x45c080, 0x45bf81, 0x44be81, 0x43bd81, 0x43bd81, 0x42bb81, 0x42bb82, 0x41ba82, 0x40b982, 0x3fb882, 0x3fb783, 0x3eb682, 0x3eb683, 0x3db483, 0x3cb483, 0x3bb383, 0x3bb284, 0x3ab184, 0x3ab084, 0x39af84, 0x38af85, 0x37ad85, 0x37ad85, 0x36ac85, 0x36ab85, 0x35aa85, 0x34a986, 0x33a886, 0x33a886, 0x32a686, 0x32a687, 0x31a587, 0x30a487, 0x30a387, 0x60aa99, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0x676767, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x909090, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xb3bbb6, 0x50c97f, 0x4cc97e, 0x4bc87e, 0x4bc77e, 0x4ac67e, 0x49c57e, 0x48c47e, 0x48c47f, 0x47c37f, 0x47c27f, 0x46c17f, 0x45c080, 0x44bf80, 0x44be80, 0x43bd80, 0x43bd81, 0x42bc80, 0x41bb81, 0x41ba81, 0x40b981, 0x3fb881, 0x3fb782, 0x3eb682, 0x3eb682, 0x3db582, 0x3cb482, 0x3bb383, 0x3bb283, 0x3ab183, 0x3ab083, 0x39af83, 0x38af84, 0x37ae84, 0x51b894, 0x8ed1b9, 0x50b694, 0x35aa85, 0x34a985, 0x33a885, 0x33a885, 0x32a785, 0x32a686, 0x31a586, 0x30a486, 0x2fa386, 0x2fa387, 0x2ea187, 0x32a289, 0xb4b9b8, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0x868686, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x313131, 0xb0b0b0, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0x92c2a5, 0x4cc97e, 0x4cc97e, 0x4bc77e, 0x4ac77f, 0x4ac67f, 0x49c57f, 0x48c47f, 0x48c380, 0x47c27f, 0x46c280, 0x46c080, 0x45c080, 0x44bf80, 0x44be81, 0x43bd81, 0x43bc81, 0x42bb81, 0x41bb82, 0x40ba82, 0x40b982, 0x3fb882, 0x3fb782, 0x3eb682, 0x3db583, 0x3cb483, 0x3cb483, 0x3bb383, 0x3bb284, 0x3ab184, 0x39b084, 0x39af84, 0x38ae85, 0x6bc3a4, 0xf4fcf6, 0xfbfffa, 0xf3fbf5, 0x54b797, 0x34a986, 0x33a886, 0x33a786, 0x32a686, 0x31a686, 0x31a587, 0x30a487, 0x2fa387, 0x2fa287, 0x2ea187, 0x2ea088, 0x86b2a9, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xa9a9a9, 0x2a2a2a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x525252, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0x74c695, 0x4bc87e, 0x4bc77e, 0x4ac67e, 0x49c67f, 0x48c47f, 0x48c47f, 0x47c37f, 0x47c27f, 0x46c17f, 0x45c080, 0x45bf80, 0x44bf80, 0x43bd80, 0x43bd81, 0x42bc81, 0x42bb81, 0x41ba81, 0x40b981, 0x3fb881, 0x3fb882, 0x3eb682, 0x3eb682, 0x3db582, 0x3cb483, 0x3bb383, 0x3bb283, 0x3ab183, 0x3ab184, 0x39af83, 0x38af84, 0x37ae84, 0x6ac3a3, 0xf4fcf5, 0xfafff8, 0xfafff8, 0xfafff8, 0x9ed7c3, 0x33a886, 0x32a786, 0x32a686, 0x31a586, 0x30a486, 0x30a386, 0x2fa387, 0x2ea187, 0x2ea187, 0x2da087, 0x2d9f88, 0x61aa9c, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0x494949, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x727272, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0x57c885, 0x4bc77e, 0x4ac77f, 0x4ac67f, 0x49c57f, 0x48c47f, 0x48c380, 0x47c280, 0x47c280, 0x46c080, 0x45c080, 0x44bf80, 0x44be81, 0x43bd81, 0x43bc81, 0x42bb81, 0x41bb82, 0x40b982, 0x40b982, 0x3fb882, 0x3fb783, 0x3eb683, 0x3db583, 0x3db483, 0x3cb483, 0x3bb383, 0x3bb284, 0x3ab184, 0x3ab084, 0x39af84, 0x38ae85, 0x6ac3a3, 0xf5fdf5, 0xf9fff7, 0xf9fff7, 0xf9fff7, 0xf9fff6, 0x83cbb4, 0x33a786, 0x32a686, 0x32a687, 0x31a587, 0x30a487, 0x2fa387, 0x2fa288, 0x2ea187, 0x2ea088, 0x2d9f88, 0x2c9f88, 0x3ea28f, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0x6a6a6a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x929292, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xb9c4be, 0x4bc77e, 0x4ac67e, 0x49c57e, 0x48c47e, 0x48c47f, 0x47c37f, 0x47c27f, 0x46c17f, 0x45c080, 0x44bf80, 0x44be80, 0x43bd80, 0x43bd81, 0x42bc80, 0x41bb81, 0x41ba81, 0x40b981, 0x3fb881, 0x3fb782, 0x3eb682, 0x3db682, 0x3db582, 0x3cb483, 0x3bb383, 0x3bb283, 0x3ab183, 0x39b083, 0x39af83, 0x38af84, 0x37ae84, 0x6ac2a2, 0xf1fcf2, 0xf8fff5, 0xf7fff5, 0xf7fff5, 0xf7fff4, 0xc3e8d7, 0x36a987, 0x32a686, 0x31a586, 0x30a486, 0x2fa386, 0x2fa287, 0x2ea187, 0x2ea187, 0x2da087, 0x2c9f87, 0x2c9e88, 0x2b9d88, 0x2a9c88, 0xbcc2c1, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0x8c8c8c, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x2e2e2e, 0xb4b4b4, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xa9c7b6, 0x4ac77f, 0x49c67f, 0x49c57f, 0x48c47f, 0x48c380, 0x47c280, 0x46c180, 0x46c080, 0x45c080, 0x44bf80, 0x44be81, 0x43bd81, 0x43bc81, 0x42bb81, 0x41ba82, 0x40b982, 0x40b982, 0x3fb882, 0x3fb782, 0x3eb682, 0x3db583, 0x3cb483, 0x3cb383, 0x3bb283, 0x3bb284, 0x3ab184, 0x39b084, 0x38af84, 0x38ae85, 0x69c2a1, 0xf2fcf1, 0xf7fff4, 0xf7fff4, 0xf7fff3, 0xf7fff3, 0xc4e8d7, 0x39aa89, 0x32a686, 0x31a587, 0x31a487, 0x30a487, 0x2fa387, 0x2fa287, 0x2ea187, 0x2ea088, 0x2d9f88, 0x2c9e88, 0x2b9d88, 0x2b9d89, 0x2a9c89, 0xa6beba, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xafafaf, 0x292929, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x505050, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0x99c8ad, 0x49c57f, 0x48c47f, 0x48c47f, 0x47c37f, 0x47c27f, 0x46c17f, 0x45c080, 0x45bf80, 0x44bf80, 0x43bd80, 0x43bd81, 0x42bc81, 0x41bb81, 0x4cbe88, 0x6dca9e, 0x40b882, 0x3fb882, 0x3eb682, 0x3db682, 0x3db582, 0x3cb483, 0x3bb383, 0x3bb283, 0x3ab183, 0x3ab184, 0x39af83, 0x38af84, 0x37ae84, 0x69c2a1, 0xeffcef, 0xf6fff3, 0xf5fff2, 0xf5fff2, 0xf5fff1, 0xc3e8d5, 0x39aa8a, 0x32a686, 0x31a586, 0x30a486, 0x30a386, 0x2fa387, 0x2ea187, 0x2ea187, 0x2da087, 0x2d9f88, 0x2c9e88, 0x2b9d88, 0x2a9c88, 0x2a9c89, 0x299a88, 0x93bab4, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0x4b4b4b, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x717171, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0x93caab, 0x49c57f, 0x48c47f, 0x48c380, 0x47c280, 0x47c280, 0x46c080, 0x45c081, 0x44bf81, 0x44be81, 0x43bd81, 0x43bc81, 0x42bb81, 0x63c898, 0xe7f8ec, 0xf9fff7, 0xcdeedb, 0x4bbc8b, 0x3eb683, 0x3db583, 0x3cb483, 0x3cb483, 0x3bb283, 0x3bb284, 0x3ab184, 0x39b084, 0x38af84, 0x38ae85, 0x65c1a0, 0xeffcee, 0xf5fff1, 0xf5fff1, 0xf5fff1, 0xf5fff1, 0xc2e8d5, 0x3aaa8a, 0x32a686, 0x32a687, 0x31a487, 0x30a487, 0x2fa387, 0x2fa288, 0x2ea187, 0x2ea088, 0x2d9f88, 0x2c9f88, 0x2b9d88, 0x2b9d89, 0x2a9c89, 0x2a9b89, 0x299a89, 0x89b8b1, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0x6e6e6e, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x939393, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0x8cc9a7, 0x48c47f, 0x47c27f, 0x46c27f, 0x46c17f, 0x45c080, 0x44bf80, 0x44be80, 0x43bd80, 0x43bd81, 0x42bb80, 0x41bb81, 0x40ba81, 0xb8e6cd, 0xf7fff5, 0xf7fff5, 0xf7fff4, 0xd2f1de, 0x48b989, 0x3cb483, 0x3bb383, 0x3bb283, 0x3ab183, 0x39b083, 0x39af83, 0x38af84, 0x37ad84, 0x64c19e, 0xecfbec, 0xf4fff0, 0xf3ffef, 0xf3ffef, 0xf3ffee, 0xc5ead5, 0x3aa989, 0x31a686, 0x31a586, 0x30a486, 0x2fa386, 0x2fa287, 0x2ea187, 0x2ea187, 0x2d9f87, 0x2c9f87, 0x2b9e87, 0x2b9d88, 0x2a9c88, 0x2a9b88, 0x299a88, 0x289a89, 0x279889, 0x81b5ae, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0x929292, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x2a2a2a, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0x79b493, 0x48c380, 0x47c280, 0x46c180, 0x45c080, 0x45c080, 0x44be80, 0x44be81, 0x43bd81, 0x42bc81, 0x41bb81, 0x41ba82, 0x40b982, 0xb9e7cd, 0xf7fff3, 0xf7fff3, 0xf6fff3, 0xf6fff3, 0xd0f0db, 0x47b78a, 0x3bb283, 0x3bb284, 0x3ab084, 0x39b084, 0x38af84, 0x38ae85, 0x65c19e, 0xedfceb, 0xf3ffee, 0xf3ffee, 0xf2ffee, 0xf2ffee, 0xc3ead4, 0x3aaa8a, 0x32a686, 0x31a587, 0x30a487, 0x30a487, 0x2fa287, 0x2fa287, 0x2ea187, 0x2da088, 0x2c9f88, 0x2c9e88, 0x2b9d88, 0x2b9d89, 0x2a9b89, 0x299b89, 0x299a89, 0x289989, 0x279889, 0x699f98, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0x292929, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x316749, 0x47c280, 0x46c17f, 0x45c080, 0x44bf80, 0x44be80, 0x43bd80, 0x43bd81, 0x42bb81, 0x41bb81, 0x40ba81, 0x40b981, 0x3fb881, 0x59c192, 0xebfbeb, 0xf5fff1, 0xf4fff1, 0xf4fff1, 0xf4fff0, 0xcceed8, 0x43b588, 0x39b084, 0x39af83, 0x38af84, 0x37ad84, 0x65c19e, 0xebfce9, 0xf2ffed, 0xf1ffec, 0xf1ffec, 0xf1ffec, 0xc2ead3, 0x39a98a, 0x32a686, 0x31a586, 0x30a486, 0x2fa386, 0x2fa287, 0x2ea187, 0x2ea187, 0x2d9f87, 0x2c9f88, 0x2b9e88, 0x2b9d88, 0x2a9c88, 0x2a9b89, 0x299a88, 0x289a89, 0x289889, 0x279889, 0x269789, 0x22524d, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x2f5d44, 0x46c180, 0x45c080, 0x45c081, 0x44bf81, 0x44be81, 0x43bd81, 0x42bc81, 0x42bb81, 0x41ba82, 0x40b982, 0x40b982, 0x3fb882, 0x3fb783, 0x62c498, 0xe9fbe9, 0xf4ffef, 0xf3ffef, 0xf3ffef, 0xf3ffee, 0xcbeed7, 0x42b489, 0x38af84, 0x38ae85, 0x63c09d, 0xeafce8, 0xf1ffec, 0xf1ffec, 0xf0ffeb, 0xf0ffeb, 0xc3ebd3, 0x3aaa8a, 0x32a686, 0x31a587, 0x30a487, 0x30a487, 0x2fa387, 0x2fa288, 0x2ea187, 0x2da088, 0x2d9f88, 0x2c9e88, 0x2b9d88, 0x2b9d89, 0x2a9c89, 0x2a9b89, 0x299a89, 0x28998a, 0x27988a, 0x27978a, 0x26968a, 0x224a46, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x294838, 0x45c080, 0x44bf80, 0x44be80, 0x43bd80, 0x43bc81, 0x42bb81, 0x41bb81, 0x40ba81, 0x40b981, 0x3fb881, 0x3fb782, 0x3eb682, 0x3db582, 0x3cb482, 0x60c398, 0xe7fae7, 0xf2ffed, 0xf1ffec, 0xf1ffec, 0xf1ffeb, 0xc9edd5, 0x3eb088, 0x63c09c, 0xe8fbe6, 0xefffea, 0xefffe9, 0xefffe9, 0xeeffe9, 0xc2ead1, 0x39a989, 0x31a686, 0x31a586, 0x30a486, 0x2fa386, 0x2fa287, 0x2ea187, 0x2ea087, 0x2d9f87, 0x2c9f88, 0x2b9e88, 0x2b9d88, 0x2a9c88, 0x2a9b88, 0x299a88, 0x289989, 0x279889, 0x279889, 0x269789, 0x26968a, 0x25958a, 0x213a38, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x24302a, 0x45c081, 0x44be80, 0x44be81, 0x43bd81, 0x42bc81, 0x41bb81, 0x41ba82, 0x40b982, 0x40b982, 0x3fb782, 0x3eb783, 0x3db683, 0x3db583, 0x3cb483, 0x3cb383, 0x61c299, 0xe9fce7, 0xf0ffeb, 0xf0ffeb, 0xf0ffea, 0xf0ffea, 0xc9eed5, 0xe9fce6, 0xefffe9, 0xefffe9, 0xeeffe8, 0xeeffe8, 0xc1ead0, 0x3aaa8a, 0x32a686, 0x31a587, 0x30a487, 0x30a487, 0x2fa287, 0x2fa287, 0x2ea187, 0x2da088, 0x2c9f88, 0x2c9e88, 0x2b9d88, 0x2b9d89, 0x2a9b89, 0x299b89, 0x299a89, 0x28998a, 0x279889, 0x27978a, 0x26968a, 0x25968a, 0x25948a, 0x202928, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x41b279, 0x43bd80, 0x43bc81, 0x42bb81, 0x41bb81, 0x40ba81, 0x40b982, 0x3fb882, 0x3fb782, 0x3eb682, 0x3db582, 0x3cb482, 0x3cb483, 0x3bb383, 0x3bb283, 0x3ab183, 0x60c19a, 0xe6fbe4, 0xeeffe9, 0xeeffe8, 0xeeffe8, 0xedffe7, 0xedffe7, 0xedffe7, 0xedffe6, 0xecffe6, 0xc1eacf, 0x39a98a, 0x32a686, 0x31a586, 0x30a486, 0x2fa386, 0x2fa287, 0x2ea187, 0x2ea087, 0x2d9f87, 0x2c9f88, 0x2b9e88, 0x2b9d88, 0x2a9c88, 0x2a9b89, 0x299a88, 0x289989, 0x279889, 0x279889, 0x269789, 0x26968a, 0x25958a, 0x24948a, 0x238880, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4c4c4c, 0x4c4c4c, 0x4c4c4c, 0x4c4c4c, 0x4b4b4b, 0x4b4b4b, 0x4b4b4b, 0x4b4b4b, 0x4a4a4a, 0x4a4a4a, 0x4a4a4a, 0x4a4a4a, 0x494949, 0x494949, 0x494949, 0x494949, 0x484848, 0x484848, 0x484848, 0x484848, 0x474747, 0x474747, 0x474747, 0x464646, 0x464646, 0x44976e, 0x43bd81, 0x42bc81, 0x42bb81, 0x41ba82, 0x40b982, 0x40b982, 0x3fb782, 0x3eb783, 0x3eb683, 0x3db583, 0x3cb483, 0x3cb384, 0x3bb283, 0x3ab284, 0x3ab084, 0x39b084, 0x5fc099, 0xe5fbe3, 0xedffe7, 0xedffe7, 0xedffe6, 0xedffe6, 0xecffe5, 0xecffe5, 0xc0ebce, 0x3aaa8a, 0x32a686, 0x31a587, 0x30a487, 0x30a487, 0x2fa287, 0x2fa288, 0x2ea188, 0x2da088, 0x2d9f88, 0x2c9e88, 0x2b9d88, 0x2b9d89, 0x2a9b89, 0x2a9b89, 0x299a89, 0x28998a, 0x27988a, 0x27978a, 0x26968a, 0x26968a, 0x25948a, 0x24948b, 0x2b726d, 0x393939, 0x393939, 0x383838, 0x383838, 0x383838, 0x383838, 0x373737, 0x373737, 0x373737, 0x373737, 0x363636, 0x363636, 0x363636, 0x353535, 0x353535, 0x353535, 0x353535, 0x343434, 0x343434, 0x343434, 0x343434, 0x333333, 0x333333, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc2c2c2, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0x86b9a0, 0x41bb81, 0x41ba81, 0x40b981, 0x40b981, 0x3fb881, 0x3eb782, 0x3eb682, 0x3db582, 0x3cb482, 0x3cb383, 0x3bb283, 0x3bb283, 0x3ab183, 0x39b083, 0x38af83, 0x38ae84, 0x37ad84, 0x5ebe99, 0xe3fbe0, 0xebffe4, 0xebffe3, 0xebffe3, 0xeaffe3, 0xc3eccf, 0x39a989, 0x31a586, 0x30a486, 0x30a486, 0x2fa386, 0x2fa287, 0x2ea187, 0x2da087, 0x2c9f87, 0x2c9e88, 0x2b9d88, 0x2b9d88, 0x2a9c88, 0x299b88, 0x299a88, 0x289989, 0x279889, 0x279789, 0x269689, 0x26968a, 0x25958a, 0x24948a, 0x23938a, 0x23928a, 0x5f8986, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7b7b7b, 0x7b7b7b, 0x797979, 0x797979, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xcfcfcf, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xaeb8b3, 0x43bb82, 0x41ba82, 0x40b982, 0x40b882, 0x3fb782, 0x3eb783, 0x3db583, 0x3db583, 0x3cb483, 0x3cb383, 0x3bb283, 0x3ab184, 0x39b084, 0x39b084, 0x38ae84, 0x38ae85, 0x37ad85, 0x36ac85, 0x5cbd99, 0xe3fcdf, 0xeaffe2, 0xeaffe2, 0xc2ecce, 0x3bab8a, 0x31a686, 0x31a587, 0x30a487, 0x30a387, 0x2fa287, 0x2ea287, 0x2ea087, 0x2da088, 0x2c9f88, 0x2c9e88, 0x2b9d88, 0x2b9c89, 0x2a9b89, 0x299b89, 0x289989, 0x28998a, 0x279889, 0x27978a, 0x26968a, 0x25958a, 0x24948a, 0x24948b, 0x23928b, 0x26928b, 0x808584, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x6f6f6f, 0x6f6f6f, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbebebe, 0xbcbcbc, 0xbcbcbc, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0x64b891, 0x40b982, 0x3fb882, 0x3fb782, 0x3eb682, 0x3db582, 0x3cb482, 0x3cb483, 0x3bb283, 0x3bb283, 0x3ab183, 0x39b084, 0x38af84, 0x38ae84, 0x37ad84, 0x37ad84, 0x36ab84, 0x35ab85, 0x34aa85, 0x55b996, 0x8ed3b3, 0x85cfaf, 0x38a989, 0x31a686, 0x30a486, 0x30a486, 0x2fa386, 0x2fa287, 0x2ea187, 0x2da087, 0x2d9f87, 0x2c9f88, 0x2b9d88, 0x2b9d88, 0x2a9c88, 0x2a9b89, 0x299a88, 0x289989, 0x279889, 0x279889, 0x269689, 0x26968a, 0x25958a, 0x24948a, 0x23938a, 0x23928b, 0x22918b, 0x468d89, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcbcbcb, 0xc9c9c9, 0xc9c9c9, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0x98b7a9, 0x40b882, 0x3fb782, 0x3eb783, 0x3db583, 0x3db583, 0x3cb483, 0x3cb384, 0x3bb283, 0x3ab184, 0x3ab084, 0x39b084, 0x38ae84, 0x38ae85, 0x37ad85, 0x36ac85, 0x36ab85, 0x35aa86, 0x34a986, 0x34a986, 0x33a786, 0x32a786, 0x32a686, 0x31a587, 0x30a487, 0x30a387, 0x2fa287, 0x2fa288, 0x2ea088, 0x2da088, 0x2c9f88, 0x2c9e88, 0x2b9d88, 0x2b9c89, 0x2a9b89, 0x299b89, 0x289989, 0x28998a, 0x27988a, 0x27978a, 0x26968a, 0x25958a, 0x25948a, 0x24948b, 0x23928b, 0x23928b, 0x22918b, 0x758887, 0x848484, 0x848484, 0x828282, 0x828282, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x5a5a5a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc2c2c2, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0x57b68c, 0x3db682, 0x3db582, 0x3cb482, 0x3cb383, 0x3bb283, 0x3ab283, 0x39b083, 0x39b084, 0x38af84, 0x38ae84, 0x37ad84, 0x36ac84, 0x36ab84, 0x35ab85, 0x34a985, 0x34a985, 0x33a885, 0x33a786, 0x32a686, 0x31a586, 0x30a486, 0x30a486, 0x2fa286, 0x2fa287, 0x2ea187, 0x2da087, 0x2c9f87, 0x2c9e88, 0x2b9d88, 0x2b9d88, 0x2a9b88, 0x299b88, 0x289a88, 0x289989, 0x279889, 0x279789, 0x269689, 0x25968a, 0x24948a, 0x24948a, 0x23938a, 0x23928b, 0x22918a, 0x22918b, 0x3f8e89, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7b7b7b, 0x7b7b7b, 0x797979, 0x797979, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xcfcfcf, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0x98b6a9, 0x3db583, 0x3db583, 0x3cb483, 0x3cb383, 0x3bb283, 0x3ab184, 0x39b084, 0x39af84, 0x38ae84, 0x38ae85, 0x37ad85, 0x36ac85, 0x35ab85, 0x35aa86, 0x34a985, 0x34a886, 0x33a786, 0x32a786, 0x31a686, 0x31a587, 0x30a487, 0x30a387, 0x2fa287, 0x2ea187, 0x2ea088, 0x2da088, 0x2c9f88, 0x2c9e88, 0x2b9d88, 0x2b9c89, 0x2a9b89, 0x299a89, 0x289989, 0x28998a, 0x27988a, 0x27978a, 0x26968a, 0x25958a, 0x24948a, 0x24938b, 0x23928b, 0x23928b, 0x22918b, 0x23918b, 0x738887, 0x868686, 0x848484, 0x848484, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x6f6f6f, 0x6f6f6f, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbebebe, 0xbebebe, 0xbcbcbc, 0xbcbcbc, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0x5fb491, 0x3cb383, 0x3bb283, 0x3ab283, 0x3ab183, 0x39b084, 0x38af84, 0x38ae84, 0x37ad84, 0x37ac85, 0x36ab84, 0x35ab85, 0x34aa85, 0x34a985, 0x33a885, 0x33a786, 0x32a686, 0x31a586, 0x30a486, 0x30a487, 0x2fa387, 0x2fa287, 0x2ea187, 0x2da087, 0x2c9f87, 0x2c9e88, 0x2b9d88, 0x2b9d88, 0x2a9c88, 0x299b89, 0x299a89, 0x289989, 0x279889, 0x279789, 0x269689, 0x25968a, 0x25958a, 0x24948a, 0x23938a, 0x23928b, 0x22918b, 0x22918b, 0x22918b, 0x498d89, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcbcbcb, 0xcbcbcb, 0xc9c9c9, 0xc9c9c9, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xa4b4ad, 0x40b385, 0x3bb284, 0x3ab184, 0x39b084, 0x39b084, 0x38ae84, 0x38ae85, 0x37ad85, 0x36ac85, 0x35ab85, 0x35aa86, 0x34a986, 0x34a986, 0x33a786, 0x32a786, 0x32a686, 0x31a587, 0x30a487, 0x30a387, 0x2fa287, 0x2fa288, 0x2ea088, 0x2da088, 0x2c9f88, 0x2c9e89, 0x2b9d88, 0x2b9c89, 0x2a9b89, 0x299b89, 0x289989, 0x28998a, 0x27988a, 0x27978a, 0x26968a, 0x25958b, 0x24948b, 0x24948b, 0x23928b, 0x23928b, 0x22918b, 0x22918b, 0x29918b, 0x7f8988, 0x878787, 0x868686, 0x848484, 0x848484, 0x828282, 0x828282, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x5a5a5a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc2c2c2, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0x89b2a2, 0x39b083, 0x39b084, 0x38af84, 0x38ae84, 0x37ad84, 0x36ac84, 0x35ab84, 0x35aa85, 0x34a985, 0x34a985, 0x33a885, 0x32a786, 0x31a686, 0x31a586, 0x30a486, 0x30a386, 0x2fa286, 0x2ea287, 0x2ea187, 0x2da087, 0x2c9f87, 0x2c9e88, 0x2b9d88, 0x2b9c88, 0x2a9b88, 0x299b88, 0x289a88, 0x289989, 0x279889, 0x279789, 0x269689, 0x25958a, 0x24948a, 0x24948a, 0x23938a, 0x23928b, 0x22918a, 0x22918b, 0x22918b, 0x22918b, 0x6e8a89, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7b7b7b, 0x7b7b7b, 0x797979, 0x797979, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xcfcfcf, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0x72b19a, 0x39af84, 0x38ae84, 0x38ae85, 0x37ac85, 0x36ac85, 0x35ab85, 0x35aa86, 0x34a985, 0x34a886, 0x33a786, 0x32a786, 0x31a586, 0x31a587, 0x30a487, 0x30a387, 0x2fa287, 0x2ea188, 0x2da088, 0x2da088, 0x2c9e88, 0x2c9e88, 0x2b9d88, 0x2a9c89, 0x299b89, 0x299a89, 0x289989, 0x28998a, 0x27978a, 0x26978a, 0x26968a, 0x25958a, 0x24948a, 0x24938b, 0x23928b, 0x23928b, 0x22918b, 0x22918b, 0x22918b, 0x5d8d8b, 0x888888, 0x888888, 0x868686, 0x393939, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4d4d4d, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x6f6f6f, 0x6f6f6f, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbebebe, 0xbcbcbc, 0xbcbcbc, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0x6daf98, 0x37ad84, 0x36ac85, 0x35ab84, 0x35aa85, 0x34a985, 0x34a985, 0x33a885, 0x32a786, 0x32a686, 0x31a586, 0x30a486, 0x30a387, 0x2fa287, 0x2fa287, 0x2ea187, 0x2da087, 0x2c9f87, 0x2c9e88, 0x2b9d88, 0x2b9c88, 0x2a9b88, 0x299b89, 0x289a89, 0x289989, 0x279889, 0x279789, 0x269689, 0x25958a, 0x24948a, 0x24948a, 0x23938a, 0x23928b, 0x22918b, 0x22918b, 0x22918b, 0x22918b, 0x568d8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x393939, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4c4c4c, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcbcbcb, 0xc9c9c9, 0xc9c9c9, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb2b2b2, 0x73ae9a, 0x36ac85, 0x35ab85, 0x35aa86, 0x34a986, 0x34a886, 0x33a786, 0x32a786, 0x31a686, 0x31a587, 0x30a487, 0x30a387, 0x2fa287, 0x2ea188, 0x2da088, 0x2da088, 0x2c9f88, 0x2c9e89, 0x2b9d88, 0x2a9c89, 0x2a9b89, 0x299a89, 0x289989, 0x28998a, 0x27988a, 0x27978a, 0x26968a, 0x25958b, 0x24948b, 0x24938b, 0x23928b, 0x23928b, 0x22918b, 0x22918b, 0x22918b, 0x588f8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x393939, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4d4d4d, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x5a5a5a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc2c2c2, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0x7aad9d, 0x34a985, 0x34a985, 0x33a785, 0x32a786, 0x31a686, 0x31a586, 0x30a486, 0x30a387, 0x2fa286, 0x2ea287, 0x2ea187, 0x2da087, 0x2c9f87, 0x2c9e88, 0x2b9d88, 0x2b9c88, 0x2a9b88, 0x299b88, 0x289a89, 0x289989, 0x279889, 0x279789, 0x269689, 0x25958a, 0x24948a, 0x24948a, 0x23938a, 0x23928b, 0x22918b, 0x22918b, 0x22918b, 0x22918b, 0x608e8b, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x393939, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4c4c4c, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xcfcfcf, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0x90ada4, 0x3da989, 0x33a786, 0x32a686, 0x31a586, 0x31a587, 0x30a487, 0x30a387, 0x2fa287, 0x2ea188, 0x2da088, 0x2d9f88, 0x2c9e88, 0x2c9e88, 0x2b9d88, 0x2a9c89, 0x299b89, 0x299a89, 0x289989, 0x28988a, 0x27978a, 0x26978a, 0x25968a, 0x25958b, 0x24948a, 0x24938b, 0x23928b, 0x22918b, 0x22918b, 0x22918b, 0x2c918b, 0x758f8d, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x868686, 0x393939, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4d4d4d, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x6f6f6f, 0x6f6f6f, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbebebe, 0xbebebe, 0xbcbcbc, 0xbcbcbc, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xa2acaa, 0x5fa894, 0x31a586, 0x30a486, 0x30a387, 0x2fa287, 0x2fa287, 0x2ea087, 0x2da087, 0x2c9f87, 0x2c9e88, 0x2b9d88, 0x2b9c88, 0x2a9b88, 0x299b89, 0x289a89, 0x289989, 0x279889, 0x27978a, 0x269689, 0x25958a, 0x24948a, 0x24948a, 0x23938a, 0x23928b, 0x22918b, 0x22918b, 0x22918b, 0x4c918d, 0x868e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x393939, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4c4c4c, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcbcbcb, 0xcbcbcb, 0xc9c9c9, 0xc9c9c9, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb2b2b2, 0xb0b0b0, 0xb0b0b0, 0xaeaeae, 0xadadad, 0xacacac, 0x8eaaa3, 0x4fa590, 0x30a387, 0x2fa287, 0x2ea188, 0x2da088, 0x2d9f88, 0x2c9e88, 0x2c9e89, 0x2b9d88, 0x2a9c89, 0x2a9b89, 0x299a89, 0x289989, 0x28988a, 0x27978a, 0x26978a, 0x26968a, 0x25958b, 0x24948b, 0x24938b, 0x23928b, 0x22918b, 0x22918b, 0x43928d, 0x7b9190, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x848484, 0x848484, 0x828282, 0x828282, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x5a5a5a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc2c2c2, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xababab, 0xababab, 0xa9a9a9, 0x93a8a3, 0x5ea394, 0x36a08a, 0x2c9f87, 0x2c9e88, 0x2b9d88, 0x2a9c88, 0x299b88, 0x299a89, 0x289989, 0x289989, 0x279889, 0x269789, 0x269689, 0x25958a, 0x24948a, 0x24938a, 0x23928a, 0x23928b, 0x2d918b, 0x53928f, 0x819291, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7b7b7b, 0x7b7b7b, 0x797979, 0x797979, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xcfcfcf, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0x89a49f, 0x62a195, 0x389d8b, 0x2a9c89, 0x299b89, 0x299a89, 0x289989, 0x28988a, 0x27978a, 0x26968a, 0x25958a, 0x25958a, 0x24948a, 0x36948d, 0x599491, 0x7d9594, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x888888, 0x888888, 0x868686, 0x868686, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x6f6f6f, 0x6f6f6f, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbebebe, 0xbcbcbc, 0xbcbcbc, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xa9a9a9, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa5a5a5, 0xa3a3a3, 0x9ba2a1, 0x8ea09d, 0x809e9a, 0x749c97, 0x689b95, 0x679a94, 0x729a96, 0x7e9997, 0x889998, 0x949998, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcbcbcb, 0xc9c9c9, 0xc9c9c9, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb2b2b2, 0xb0b0b0, 0xb0b0b0, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x9b9b9b, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x848484, 0x848484, 0x828282, 0x828282, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x5a5a5a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc2c2c2, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xa9a9a9, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x929292, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7b7b7b, 0x7b7b7b, 0x797979, 0x797979, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xc6c6c6, 0xd1d1d1, 0xcfcfcf, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x9b9b9b, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x868686, 0x868686, 0x848484, 0x848484, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x6f6f6f, 0x6f6f6f, 0x6d6d6d, 0x565656, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x9a9a9a, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbebebe, 0xbebebe, 0xbcbcbc, 0xbcbcbc, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa5a5a5, 0xa3a3a3, 0xa3a3a3, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x464646, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x797979, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcbcbcb, 0xcbcbcb, 0xc9c9c9, 0xc9c9c9, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb2b2b2, 0xb0b0b0, 0xb0b0b0, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x9b9b9b, 0x999999, 0x999999, 0x979797, 0x979797, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x848484, 0x848484, 0x828282, 0x828282, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x353535, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xbfbfbf, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc2c2c2, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xababab, 0xababab, 0xa9a9a9, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x949494, 0x949494, 0x929292, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7b7b7b, 0x7b7b7b, 0x797979, 0x797979, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x464646, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x464646, 0xcfcfcf, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0x9f9f9f, 0x9f9f9f, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x9b9b9b, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x888888, 0x888888, 0x868686, 0x868686, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x6f6f6f, 0x676767, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x7f7f7f, 0xbababa, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbebebe, 0xbcbcbc, 0xbcbcbc, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xa9a9a9, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa5a5a5, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x626262, 0x484848, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x3a3a3a, 0x4b4b4b, 0x4b4b4b, 0x4a4a4a, 0x4a4a4a, 0x4a4a4a, 0x4a4a4a, 0x494949, 0x494949, 0x494949, 0x494949, 0x484848, 0x484848, 0x484848, 0x484848, 0x474747, 0x474747, 0x474747, 0x464646, 0x464646, 0x464646, 0x464646, 0x454545, 0x454545, 0x454545, 0x454545, 0x444444, 0x444444, 0x444444, 0x444444, 0x434343, 0x434343, 0x434343, 0x424242, 0x424242, 0x424242, 0x424242, 0x414141, 0x414141, 0x414141, 0x414141, 0x404040, 0x404040, 0x404040, 0x404040, 0x3f3f3f, 0x3f3f3f, 0x3f3f3f, 0x3f3f3f, 0x3e3e3e, 0x3e3e3e, 0x3e3e3e, 0x3e3e3e, 0x3d3d3d, 0x3d3d3d, 0x3d3d3d, 0x3d3d3d, 0x3c3c3c, 0x3c3c3c, 0x3c3c3c, 0x3c3c3c, 0x3b3b3b, 0x3b3b3b, 0x3b3b3b, 0x3a3a3a, 0x3a3a3a, 0x3a3a3a, 0x3a3a3a, 0x393939, 0x393939, 0x393939, 0x393939, 0x383838, 0x383838, 0x383838, 0x383838, 0x373737, 0x373737, 0x373737, 0x373737, 0x363636, 0x363636, 0x363636, 0x353535, 0x353535, 0x353535, 0x353535, 0x272727, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020 +}; \ No newline at end of file diff --git a/dev/BootLoader/BootKit/Rsrc/zka_no_disk.rsrc b/dev/BootLoader/BootKit/Rsrc/zka_no_disk.rsrc new file mode 100644 index 00000000..31689e63 --- /dev/null +++ b/dev/BootLoader/BootKit/Rsrc/zka_no_disk.rsrc @@ -0,0 +1,116 @@ +#define ZKA_NO_DISK_HEIGHT 110 +#define ZKA_NO_DISK_WIDTH 110 + +// array size is 36300 +static const unsigned int zka_no_disk[] = { + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x333333, 0x565656, 0x636363, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6a6a6a, 0x5f5f5f, 0x4d4d4d, 0x2b2b2b, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x464646, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x6a6a6a, 0x3b3b3b, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x3d3d3d, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x393939, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x252525, 0x676767, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x606060, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4c4c4c, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x3d3d3d, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x616161, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x525252, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x242424, 0x767676, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x676767, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x393939, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7e7e7e, 0x292929, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4e4e4e, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x3f3f3f, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x666666, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x555555, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x222222, 0x7c7c7c, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x6d6d6d, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x393939, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x868686, 0x292929, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x515151, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x404040, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x6a6a6a, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x828282, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0xa69a77, 0xbea35a, 0xc0a458, 0xa69a77, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x727272, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x383838, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0xab9d77, 0xebb626, 0xffbe0c, 0xffbd0c, 0xffbd0c, 0xffbc0c, 0xecb524, 0xaa9c78, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x8e8e8e, 0x2a2a2a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x525252, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0xa49b83, 0xfcbc0f, 0xfebc0c, 0xffbc0c, 0xfebc0b, 0xffbb0c, 0xfebb0b, 0xffba0b, 0xfcb90e, 0xa49b83, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x414141, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x6e6e6e, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0xe8b52c, 0xffbd0c, 0xffbc0c, 0xffbc0c, 0xffbb0c, 0xffbb0c, 0xffba0b, 0xffba0c, 0xffb90b, 0xe8b22c, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x5c5c5c, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x868686, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0xbca66b, 0xfebb0b, 0xffbb0b, 0xfeba0b, 0xffba0b, 0xfeba0b, 0xffb90b, 0xfeb80b, 0xffb80b, 0xfeb80b, 0xffb70b, 0xbda46a, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x787878, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x373737, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0xa09f9b, 0xf3b81e, 0xffbb0c, 0xffbb0c, 0xffba0b, 0xffba0c, 0xffb90b, 0xffb90b, 0xffb80b, 0xffb80b, 0xffb70b, 0xffb70b, 0xf3b31d, 0xa09e9b, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x959595, 0x2a2a2a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x545454, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xcbac5c, 0xffba0b, 0xfeba0b, 0xffb90b, 0xfeb90b, 0xffb80b, 0xfeb80b, 0xffb70b, 0xfeb70a, 0xffb60b, 0xfeb60a, 0xffb60a, 0xfeb50a, 0xccaa5b, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0x444444, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x707070, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xaaa699, 0xfab914, 0xffba0c, 0xffb90b, 0xffb90c, 0xffb80b, 0xffb80b, 0xffb70b, 0xffb70b, 0xffb60b, 0xffb60b, 0xffb50b, 0xffb50b, 0xffb40a, 0xfab313, 0xa9a498, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0x5e5e5e, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x8b8b8b, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xd9b14c, 0xfeb80b, 0xfeb80b, 0xfeb70b, 0xffb70b, 0xfeb60a, 0xfeb60a, 0xfeb60a, 0xffb50a, 0xfeb50a, 0xfeb40a, 0xfeb40a, 0xfeb30a, 0xfeb30a, 0xfeb20a, 0xd9ac4a, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0x7c7c7c, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x363636, 0xa7a7a7, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xb5aa91, 0xfeb80d, 0xffb80b, 0xffb80b, 0xffb70b, 0xffb70b, 0xffb60b, 0xffb60b, 0xffb50a, 0xffb50b, 0xffb40a, 0xffb40a, 0xffb30a, 0xffb30a, 0xffb20a, 0xffb20a, 0xfeb10c, 0xb5aa92, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0x9c9c9c, 0x2a2a2a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x545454, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xe6b43a, 0xffb70b, 0xfeb60a, 0xffb60b, 0xfeb60a, 0xffb50a, 0xfeb50a, 0xffb40a, 0xfeb40a, 0xffb40a, 0xfeb30a, 0xffb20a, 0xfeb20a, 0xffb20a, 0xfeb109, 0xffb109, 0xfeb009, 0xe6ae39, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0x464646, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x717171, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xc2b085, 0xffb70b, 0xffb70b, 0xffb60b, 0xffb60b, 0xffb50b, 0xffb50b, 0xffb40a, 0xffb40b, 0xffb30a, 0xffb30a, 0xffb20a, 0xffb20a, 0xffb10a, 0xffb10a, 0xffb00a, 0xffb00a, 0xffaf0a, 0xffaf0a, 0xc2ae85, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0x636363, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x8e8e8e, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb1b0af, 0xf1b526, 0xfeb50a, 0xffb50a, 0xfeb40a, 0xfeb40a, 0xfeb40a, 0xffb30a, 0xfeb30a, 0xfeb20a, 0xfeb209, 0xfeb10a, 0xfeb109, 0xfeb009, 0xfeb009, 0xfeb009, 0xfeaf09, 0xfeaf09, 0xfeae09, 0xfeae09, 0xf1ad25, 0xb1b0af, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0x818181, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x343434, 0xacacac, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xd0b472, 0xffb60b, 0xffb50a, 0xffb50b, 0xffb40a, 0xffb40a, 0xffb30a, 0xffb30a, 0xffb20a, 0xdc9e15, 0x90712e, 0x91712e, 0xdd9c15, 0xffb00a, 0xffaf09, 0xffaf0a, 0xffae09, 0xffae09, 0xffad09, 0xffad09, 0xffac09, 0xd0b071, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xa3a3a3, 0x2a2a2a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x545454, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb8b5ae, 0xf8b519, 0xffb40a, 0xfeb40a, 0xffb30a, 0xfeb30a, 0xffb20a, 0xfeb20a, 0xffb10a, 0xfeb109, 0x564f40, 0x444444, 0x444444, 0x564e3e, 0xfeaf09, 0xfeae09, 0xffae09, 0xfead09, 0xfead09, 0xfeac08, 0xffac09, 0xfeab08, 0xf8ac17, 0xb8b5ae, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0x484848, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x727272, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xdcb660, 0xffb40a, 0xffb40b, 0xffb30a, 0xffb30a, 0xffb20a, 0xffb20a, 0xffb10a, 0xffb10a, 0xeba510, 0x444444, 0x434343, 0x434343, 0x424242, 0xeca30f, 0xffad09, 0xffad09, 0xffac09, 0xffac09, 0xffac09, 0xffab09, 0xffab09, 0xffaa09, 0xdcb15e, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0x676767, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x909090, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xc1b9a8, 0xfcb30f, 0xfeb20a, 0xfeb20a, 0xfeb109, 0xfeb10a, 0xfeb009, 0xfeb009, 0xfeb009, 0xfeaf09, 0xe6a110, 0x424242, 0x424242, 0x414141, 0x414141, 0xe69e10, 0xfeac08, 0xfeac08, 0xfeab08, 0xfeab08, 0xfeaa08, 0xfeaa08, 0xfea908, 0xfea908, 0xfca90d, 0xc1b8a8, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0x868686, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x313131, 0xb0b0b0, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xe6b74c, 0xffb30a, 0xffb20a, 0xffb20a, 0xffb10a, 0xffb10a, 0xffb009, 0xffb00a, 0xffaf09, 0xffaf09, 0xe7a010, 0x414141, 0x414141, 0x414141, 0x404040, 0xe79e10, 0xffab09, 0xffab09, 0xffaa08, 0xffaa09, 0xffa908, 0xffa908, 0xffa808, 0xffa808, 0xffa808, 0xe7af4b, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xa9a9a9, 0x2a2a2a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x525252, 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, 0xcbbc9b, 0xfeb209, 0xffb10a, 0xfeb109, 0xffb009, 0xfeb009, 0xffaf09, 0xfeaf09, 0xfeae09, 0xfeae09, 0xffae09, 0xe69f10, 0x404040, 0x3f3f3f, 0x3f3f3f, 0x3e3e3e, 0xe69d0f, 0xfeaa08, 0xfeaa08, 0xfea908, 0xfea908, 0xfea808, 0xfea808, 0xfea707, 0xfea708, 0xfea607, 0xfea607, 0xcbba9b, 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, 0x494949, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x727272, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xf1b533, 0xffb10a, 0xffb10a, 0xffb00a, 0xffb00a, 0xffaf09, 0xffaf0a, 0xffae09, 0xffae09, 0xffad09, 0xffad09, 0xe79e10, 0x3f3f3f, 0x3e3e3e, 0x3e3e3e, 0x3d3d3d, 0xe79c10, 0xffaa08, 0xffa909, 0xffa908, 0xffa808, 0xffa808, 0xffa708, 0xffa708, 0xffa608, 0xffa608, 0xffa608, 0xf1ab31, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0x6a6a6a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x929292, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xd6be89, 0xfeb009, 0xfeaf09, 0xfeaf09, 0xfeae09, 0xfeae09, 0xfeae09, 0xfead09, 0xfead08, 0xfeac09, 0xfeac08, 0xfeab08, 0xe69d0f, 0x3d3d3d, 0x3c3c3c, 0x3c3c3c, 0x3b3b3b, 0xe69b0e, 0xfea808, 0xfea808, 0xfea707, 0xfea708, 0xfea607, 0xfea607, 0xfea507, 0xfea507, 0xfea407, 0xfea407, 0xfea307, 0xd6ba89, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0x8c8c8c, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x2e2e2e, 0xb4b4b4, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc9c8c6, 0xf8b321, 0xffb00a, 0xffaf09, 0xffaf09, 0xffae09, 0xffae09, 0xffad09, 0xffad09, 0xffac09, 0xffac09, 0xffab09, 0xffab09, 0xe79c0f, 0x3c3c3c, 0x3c3c3c, 0x3b3b3b, 0x3b3b3b, 0xe69a0e, 0xffa708, 0xffa708, 0xffa608, 0xffa608, 0xffa608, 0xffa508, 0xfea507, 0xffa407, 0xffa407, 0xffa307, 0xfea307, 0xf8a71f, 0xc8c7c5, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xafafaf, 0x292929, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x505050, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xe1be76, 0xfeaf09, 0xfeae09, 0xfeae09, 0xffad09, 0xfead09, 0xfeac09, 0xfeac08, 0xffac09, 0xfeab08, 0xfeab08, 0xfeaa08, 0xfeaa08, 0xe69b0e, 0x3b3b3b, 0x3a3a3a, 0x3a3a3a, 0x393939, 0xe5990e, 0xfea607, 0xfea607, 0xfea507, 0xfea507, 0xfea407, 0xfea407, 0xfea307, 0xfea307, 0xfea207, 0xfea207, 0xfea106, 0xfea107, 0xe0b774, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0x4b4b4b, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x717171, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xd0cbc2, 0xfbb117, 0xffae09, 0xffae09, 0xffad09, 0xffad09, 0xffac09, 0xffac09, 0xffab09, 0xffab09, 0xffaa08, 0xffaa09, 0xffa908, 0xffa909, 0xe69a0e, 0x3a3a3a, 0x393939, 0x393939, 0x383838, 0xe6980e, 0xffa608, 0xffa508, 0xffa507, 0xffa408, 0xffa407, 0xffa407, 0xffa307, 0xffa307, 0xffa207, 0xffa207, 0xffa107, 0xffa107, 0xfba315, 0xd0cbc2, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0x6e6e6e, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x939393, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xe9bc60, 0xfead09, 0xfeac08, 0xfeac09, 0xfeac08, 0xfeab08, 0xfeab08, 0xfeaa08, 0xfeaa08, 0xfea908, 0xfea908, 0xfea808, 0xfea808, 0xfea808, 0xe5990d, 0x383838, 0x373737, 0x373737, 0x363636, 0xe5970d, 0xfea407, 0xfea407, 0xfea307, 0xfea307, 0xfea206, 0xfea207, 0xfea106, 0xfea106, 0xfea006, 0xfea006, 0xfe9f06, 0xfe9f06, 0xfe9e06, 0xe9b45f, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0x929292, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x2a2a2a, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xb0a691, 0xfdad0c, 0xffad09, 0xffac09, 0xffac09, 0xffab09, 0xffab09, 0xffaa08, 0xffaa08, 0xffa908, 0xffa908, 0xfea808, 0xffa808, 0xffa708, 0xffa708, 0xe5980e, 0x373737, 0x363636, 0x363636, 0x353535, 0xe6960d, 0xfea407, 0xffa307, 0xfea307, 0xffa207, 0xfea207, 0xffa107, 0xfea106, 0xffa007, 0xfea006, 0xffa007, 0xfe9f06, 0xff9f06, 0xfe9e06, 0xfd9e09, 0xb0a491, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0x292929, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xb88010, 0xfeac08, 0xffab09, 0xfeab08, 0xfeaa08, 0xfeaa08, 0xfea908, 0xfea908, 0xfea808, 0xfea808, 0xfea808, 0xfea707, 0xfea708, 0xfea607, 0xfea607, 0xf8a208, 0x3a3834, 0x353535, 0x353535, 0x393733, 0xf89f08, 0xfea207, 0xfea207, 0xfea106, 0xfea106, 0xfea006, 0xfea006, 0xfe9f06, 0xfe9f06, 0xfe9e06, 0xfe9e06, 0xfe9d06, 0xfe9d06, 0xfe9d05, 0xfe9c06, 0xb7740e, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x523f1b, 0xffac09, 0xffab09, 0xffab09, 0xffaa08, 0xffaa09, 0xffa908, 0xffa908, 0xffa808, 0xffa808, 0xffa708, 0xffa708, 0xffa608, 0xffa608, 0xffa508, 0xffa508, 0xffa407, 0xa9751b, 0x353434, 0x353533, 0xab7519, 0xffa207, 0xffa207, 0xffa107, 0xffa107, 0xffa007, 0xffa007, 0xffa007, 0xfe9f06, 0xff9f06, 0xff9e06, 0xff9e06, 0xfe9d06, 0xff9d06, 0xff9c06, 0xff9c06, 0xfe9b06, 0x523b1a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd38f0d, 0xfeaa08, 0xfeaa08, 0xfea908, 0xfea908, 0xfea808, 0xfea808, 0xfea708, 0xfea707, 0xfea607, 0xfea607, 0xfea607, 0xfea507, 0xfea507, 0xfea407, 0xfea407, 0xfea307, 0xfea307, 0xe9970a, 0xea970b, 0xfea106, 0xfea106, 0xfea006, 0xfea006, 0xfe9f06, 0xfe9f06, 0xfe9e06, 0xfe9e06, 0xfe9d05, 0xfe9d06, 0xfe9c05, 0xfe9c06, 0xfe9b05, 0xfe9b05, 0xfe9a05, 0xfe9a05, 0xfe9905, 0xd3810a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x715318, 0xffaa08, 0xffaa08, 0xffa908, 0xffa908, 0xffa808, 0xffa808, 0xffa708, 0xffa708, 0xffa608, 0xffa608, 0xffa507, 0xffa508, 0xfea407, 0xffa407, 0xffa307, 0xffa307, 0xfea207, 0xffa207, 0xffa207, 0xffa107, 0xfea106, 0xffa007, 0xfea006, 0xff9f07, 0xfe9f06, 0xff9e06, 0xfe9e06, 0xff9e06, 0xfe9d06, 0xff9d06, 0xfe9c06, 0xff9c06, 0xfe9b05, 0xff9b06, 0xfe9a05, 0xff9a05, 0xfe9905, 0xff9905, 0x704b16, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x27241f, 0xe89b0b, 0xfea908, 0xfea808, 0xfea808, 0xfea708, 0xfea707, 0xfea608, 0xfea607, 0xfea607, 0xfea507, 0xfea507, 0xfea407, 0xfea407, 0xfea307, 0xfea307, 0xfea207, 0xfea207, 0xfea106, 0xfea106, 0xfea006, 0xfea006, 0xfe9f06, 0xfe9f06, 0xfe9e06, 0xfe9e06, 0xfe9d06, 0xfe9d06, 0xfe9c05, 0xfe9c06, 0xfe9b05, 0xfe9b05, 0xfe9b05, 0xfe9a05, 0xfe9a05, 0xfe9905, 0xfe9905, 0xfe9805, 0xfe9804, 0xfe9705, 0xe78b07, 0x27241f, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4c4c4c, 0x4c4c4c, 0x4c4c4c, 0x4c4c4c, 0x4b4b4b, 0x4b4b4b, 0x4b4b4b, 0x4b4b4b, 0x4a4a4a, 0x4a4a4a, 0x4a4a4a, 0x4a4a4a, 0x494949, 0x494949, 0x494949, 0x494949, 0x484848, 0x484848, 0x484848, 0x484848, 0x474747, 0x474747, 0x474747, 0x464646, 0x464646, 0x464646, 0x464646, 0x454545, 0x9f7627, 0xffa908, 0xffa808, 0xffa808, 0xffa708, 0xffa708, 0xffa608, 0xffa608, 0xffa508, 0xffa508, 0xffa407, 0xffa408, 0xffa307, 0xffa307, 0xffa207, 0xffa207, 0xffa207, 0xffa107, 0xffa107, 0xffa007, 0xffa007, 0xff9f07, 0xff9f06, 0xff9e06, 0xff9e06, 0xff9e06, 0xff9d06, 0xff9d06, 0xff9c06, 0xff9c06, 0xfe9b06, 0xff9b06, 0xff9a05, 0xff9a06, 0xfe9905, 0xff9905, 0xff9805, 0xff9805, 0xfe9705, 0xff9705, 0xfe9605, 0x996620, 0x3a3a3a, 0x3a3a3a, 0x3a3a3a, 0x393939, 0x393939, 0x393939, 0x393939, 0x383838, 0x383838, 0x383838, 0x383838, 0x373737, 0x373737, 0x373737, 0x373737, 0x363636, 0x363636, 0x363636, 0x353535, 0x353535, 0x353535, 0x353535, 0x343434, 0x343434, 0x343434, 0x343434, 0x333333, 0x333333, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc2c2c2, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xbbb4a6, 0xfba80e, 0xfea708, 0xfea607, 0xfea607, 0xfea607, 0xfea507, 0xfea507, 0xfea407, 0xfea407, 0xfea307, 0xfea307, 0xfea207, 0xfea206, 0xfea207, 0xfea106, 0xfea106, 0xfea006, 0xfea006, 0xfe9f06, 0xe4910b, 0xa97016, 0xa97016, 0xe69009, 0xfe9d06, 0xfe9c05, 0xfe9c05, 0xfe9b05, 0xfe9b05, 0xfe9a05, 0xfe9a05, 0xfe9905, 0xfe9905, 0xfe9805, 0xfe9805, 0xfe9704, 0xfe9704, 0xfe9704, 0xfe9604, 0xfe9604, 0xfe9504, 0xfe9504, 0xf99409, 0x92897d, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7b7b7b, 0x7b7b7b, 0x797979, 0x797979, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xcfcfcf, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0xe2ad4c, 0xffa708, 0xffa708, 0xfea608, 0xffa608, 0xffa507, 0xffa508, 0xfea407, 0xffa407, 0xfea307, 0xffa307, 0xfea207, 0xffa207, 0xfea107, 0xffa107, 0xfea006, 0xffa007, 0xfe9f06, 0xff9f06, 0xab7115, 0x2f2e2d, 0x2c2c2c, 0x2c2c2c, 0x2d2c2b, 0xac7014, 0xfe9c06, 0xff9b06, 0xfe9b05, 0xff9a06, 0xfe9a05, 0xff9a05, 0xfe9905, 0xff9905, 0xfe9805, 0xff9805, 0xfe9705, 0xff9705, 0xfe9605, 0xff9605, 0xfe9504, 0xfe9504, 0xfe9404, 0xff9404, 0xcf8f38, 0x888888, 0x868686, 0x868686, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x6f6f6f, 0x6f6f6f, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbebebe, 0xbcbcbc, 0xbcbcbc, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xc2b399, 0xfea609, 0xfea607, 0xfea507, 0xfea507, 0xfea407, 0xfea407, 0xfea407, 0xfea307, 0xfea307, 0xfea206, 0xfea207, 0xfea106, 0xfea106, 0xfea006, 0xfea006, 0xfe9f06, 0xfe9f06, 0xfe9e06, 0xf99b07, 0x322f2a, 0x2b2b2b, 0x2b2b2b, 0x2a2a2a, 0x292929, 0x332f28, 0xfc9905, 0xfe9a05, 0xfe9905, 0xfe9905, 0xfe9805, 0xfe9805, 0xfe9704, 0xfe9705, 0xfe9704, 0xfe9604, 0xfe9604, 0xfe9504, 0xfe9504, 0xfe9404, 0xfe9404, 0xfe9304, 0xfe9304, 0xfe9304, 0xfd9204, 0x9b8971, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcbcbcb, 0xc9c9c9, 0xc9c9c9, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xecaa33, 0xffa608, 0xffa508, 0xffa508, 0xffa407, 0xffa407, 0xffa307, 0xffa307, 0xffa207, 0xffa207, 0xffa107, 0xffa107, 0xffa007, 0xffa007, 0xffa006, 0xff9f07, 0xfe9e06, 0xff9e06, 0xff9e06, 0xe18d0b, 0x2b2b2b, 0x2a2a2a, 0x2a2a2a, 0x292929, 0x292929, 0x282828, 0xe18b0a, 0xff9a06, 0xfe9905, 0xff9905, 0xfe9805, 0xff9805, 0xfe9705, 0xff9705, 0xfe9605, 0xff9605, 0xfe9504, 0xff9505, 0xfe9404, 0xff9404, 0xfe9304, 0xff9304, 0xfe9204, 0xff9204, 0xfe9104, 0xe18f25, 0x878787, 0x868686, 0x848484, 0x848484, 0x828282, 0x828282, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x5a5a5a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc2c2c2, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xccb284, 0xfea407, 0xfea407, 0xfea407, 0xfea307, 0xfea307, 0xfea207, 0xfea206, 0xfea107, 0xfea106, 0xfea006, 0xfea006, 0xfea006, 0xfe9f06, 0xfe9f06, 0xfe9e06, 0xfe9e06, 0xfe9d05, 0xfe9d06, 0xfe9c05, 0xfb9a06, 0x2f2c28, 0x292929, 0x282828, 0x282828, 0x272727, 0x302c25, 0xfb9705, 0xfe9805, 0xfe9704, 0xfe9704, 0xfe9604, 0xfe9604, 0xfe9504, 0xfe9504, 0xfe9504, 0xfe9404, 0xfe9404, 0xfe9304, 0xfe9303, 0xfe9204, 0xfe9203, 0xfe9103, 0xfe9103, 0xfe9103, 0xfe9003, 0xfe9003, 0xa88960, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7b7b7b, 0x7b7b7b, 0x797979, 0x797979, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xcfcfcf, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xbab9b7, 0xf5a821, 0xfea407, 0xffa407, 0xffa307, 0xffa307, 0xfea207, 0xffa207, 0xffa107, 0xffa107, 0xfea006, 0xffa007, 0xfe9f06, 0xff9f06, 0xfe9e06, 0xff9e06, 0xfe9d06, 0xff9d06, 0xfe9c06, 0xff9c06, 0xfe9c06, 0xff9b06, 0xa66c13, 0x282828, 0x272727, 0x272727, 0x262626, 0xa96b12, 0xfe9805, 0xff9805, 0xfe9705, 0xff9705, 0xfe9605, 0xff9605, 0xfe9504, 0xff9504, 0xfe9404, 0xff9404, 0xfe9304, 0xff9304, 0xfe9204, 0xff9204, 0xfe9104, 0xfe9104, 0xfe9003, 0xff9004, 0xfe8f03, 0xfe8f03, 0xed8d16, 0x878684, 0x848484, 0x848484, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x6f6f6f, 0x6f6f6f, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbebebe, 0xbebebe, 0xbcbcbc, 0xbcbcbc, 0xbababa, 0xb9b9b9, 0xd5b06e, 0xfea307, 0xfea307, 0xfea207, 0xfea206, 0xfea207, 0xfea106, 0xfea106, 0xfea006, 0xfea006, 0xfe9f06, 0xfe9f06, 0xfe9e06, 0xfe9e06, 0xfe9d06, 0xfe9d06, 0xfe9c05, 0xfe9c06, 0xfe9b05, 0xfe9b05, 0xfe9a05, 0xfe9a05, 0xfe9905, 0xc0780e, 0x6e4c1b, 0x714d1a, 0xc2780d, 0xfe9705, 0xfe9604, 0xfe9604, 0xfe9504, 0xfe9504, 0xfe9504, 0xfe9404, 0xfe9404, 0xfe9304, 0xfe9304, 0xfe9204, 0xfe9203, 0xfe9104, 0xfe9103, 0xfe9103, 0xfe9003, 0xfe9003, 0xfe8f03, 0xfe8f03, 0xfe8e03, 0xfe8e03, 0xfe8d03, 0xb68850, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcbcbcb, 0xcbcbcb, 0xc9c9c9, 0xc9c9c9, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xf8a517, 0xffa307, 0xffa207, 0xffa207, 0xffa107, 0xffa107, 0xffa007, 0xffa007, 0xff9f06, 0xff9f07, 0xff9e06, 0xff9e06, 0xff9d06, 0xff9d06, 0xff9d06, 0xff9c06, 0xff9c06, 0xff9b06, 0xfe9b05, 0xff9a06, 0xff9a05, 0xff9a06, 0xfe9905, 0xff9905, 0xff9805, 0xff9805, 0xfe9705, 0xff9705, 0xfe9605, 0xff9605, 0xfe9504, 0xff9505, 0xfe9404, 0xff9404, 0xfe9304, 0xff9304, 0xfe9204, 0xff9204, 0xfe9104, 0xff9104, 0xfe9004, 0xff9004, 0xfe8f03, 0xff8f03, 0xfe8e03, 0xff8e03, 0xfe8d03, 0xff8d03, 0xfe8d03, 0xf38c0f, 0x848484, 0x848484, 0x828282, 0x828282, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x5a5a5a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc2c2c2, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xceb282, 0xfea206, 0xfea106, 0xfea106, 0xfea006, 0xfea006, 0xfe9f06, 0xfe9f06, 0xfe9e06, 0xfe9e06, 0xfe9e06, 0xfe9d05, 0xfe9d06, 0xfe9c05, 0xfe9c05, 0xfe9b05, 0xfe9b05, 0xfe9a05, 0xfe9a05, 0xfe9905, 0xfe9905, 0xfe9805, 0xfe9805, 0xfe9704, 0xfe9704, 0xfe9604, 0xfe9604, 0xfe9504, 0xfe9504, 0xfe9404, 0xfe9404, 0xfe9304, 0xfe9304, 0xfe9203, 0xfe9204, 0xfe9103, 0xfe9103, 0xfe9103, 0xfe9003, 0xfe9003, 0xfe8f03, 0xfe8f03, 0xfe8e03, 0xfe8e02, 0xfe8d03, 0xfe8d02, 0xfe8d02, 0xfe8c02, 0xfe8c02, 0xfe8b02, 0xfe8b02, 0xa7865e, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7b7b7b, 0x7b7b7b, 0x797979, 0x797979, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xcfcfcf, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xd9af69, 0xfea107, 0xffa107, 0xfea006, 0xffa007, 0xfe9f06, 0xff9f06, 0xfe9e06, 0xff9e06, 0xfe9d06, 0xff9d06, 0xfe9c06, 0xff9c06, 0xfe9b06, 0xff9b06, 0xfe9a05, 0xff9a05, 0xfe9a05, 0xff9905, 0xfe9805, 0xff9805, 0xfe9805, 0xff9705, 0xfe9705, 0xff9605, 0xfe9604, 0xff9605, 0xfe9504, 0xfe9504, 0xfe9404, 0xff9404, 0xfe9304, 0xfe9304, 0xfe9204, 0xff9204, 0xfe9103, 0xfe9104, 0xfe9003, 0xfe9004, 0xfe8f03, 0xfe8f03, 0xfe8e03, 0xfe8e03, 0xfe8d03, 0xfe8d03, 0xfe8c03, 0xfe8c03, 0xfe8b02, 0xfe8b03, 0xfe8a02, 0xfe8a02, 0x824f13, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4d4d4d, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x6f6f6f, 0x6f6f6f, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbebebe, 0xbcbcbc, 0xbcbcbc, 0xbababa, 0xd7ae6c, 0xfea006, 0xfe9f06, 0xfe9f06, 0xfe9e06, 0xfe9e06, 0xfe9e06, 0xfe9d05, 0xfe9d06, 0xfe9c05, 0xfe9c06, 0xfe9b05, 0xfe9b05, 0xfe9a05, 0xfe9a05, 0xfe9905, 0xfe9905, 0xfe9805, 0xfe9805, 0xfe9704, 0xfe9705, 0xfe9604, 0xfe9604, 0xfe9504, 0xfe9504, 0xfe9404, 0xfe9404, 0xfe9304, 0xfe9304, 0xfe9204, 0xfe9204, 0xfe9203, 0xfe9103, 0xfe9103, 0xfe9003, 0xfe9003, 0xfe8f03, 0xfe8f03, 0xfe8f03, 0xfe8e03, 0xfe8e03, 0xfe8d02, 0xfe8d03, 0xfe8c02, 0xfe8c02, 0xfe8b02, 0xfe8b02, 0xfe8a02, 0xfe8a02, 0xfe8902, 0xfe8902, 0x7e4c13, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4c4c4c, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcbcbcb, 0xc9c9c9, 0xc9c9c9, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xc8b596, 0xff9f06, 0xff9f07, 0xfe9e06, 0xff9e06, 0xff9d06, 0xff9d06, 0xfe9c06, 0xff9c06, 0xff9b06, 0xff9b06, 0xfe9a05, 0xff9a06, 0xfe9a05, 0xff9905, 0xfe9905, 0xff9805, 0xfe9805, 0xff9705, 0xfe9705, 0xff9605, 0xfe9605, 0xff9605, 0xfe9504, 0xff9504, 0xfe9404, 0xff9404, 0xfe9304, 0xff9304, 0xfe9204, 0xff9204, 0xfe9104, 0xff9104, 0xfe9003, 0xff9004, 0xfe8f03, 0xff8f03, 0xfe8e03, 0xff8e03, 0xfe8d03, 0xff8d03, 0xfe8c03, 0xff8c03, 0xfe8b03, 0xfe8b03, 0xfe8a02, 0xff8a03, 0xfe8902, 0xfe8902, 0xfe8902, 0xff8802, 0x4c351a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4d4d4d, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x5a5a5a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc2c2c2, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xeca433, 0xfe9d06, 0xfe9d05, 0xfe9c06, 0xfe9c05, 0xfe9c05, 0xfe9b05, 0xfe9b05, 0xfe9a05, 0xfe9a05, 0xfe9905, 0xfe9905, 0xfe9805, 0xfe9805, 0xfe9704, 0xfe9704, 0xfe9604, 0xfe9604, 0xfe9504, 0xfe9504, 0xfe9404, 0xfe9404, 0xfe9304, 0xfe9304, 0xfe9203, 0xfe9204, 0xfe9103, 0xfe9103, 0xfe9003, 0xfe9003, 0xfe8f03, 0xfe8f03, 0xfe8f03, 0xfe8e03, 0xfe8e02, 0xfe8d03, 0xfe8d02, 0xfe8c03, 0xfe8c02, 0xfe8b02, 0xfe8b02, 0xfe8b02, 0xfe8a02, 0xfe8a02, 0xfe8902, 0xfe8902, 0xfe8801, 0xfe8802, 0xfe8701, 0xe17b0a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4c4c4c, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xcfcfcf, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xbeb7ad, 0xf3a224, 0xfe9c06, 0xff9c06, 0xfe9b06, 0xff9b06, 0xfe9a05, 0xff9a05, 0xfe9905, 0xff9905, 0xfe9805, 0xff9805, 0xfe9705, 0xff9705, 0xfe9705, 0xff9605, 0xfe9604, 0xff9505, 0xfe9504, 0xff9404, 0xfe9404, 0xff9404, 0xfe9304, 0xfe9304, 0xfe9204, 0xff9204, 0xfe9103, 0xfe9104, 0xfe9003, 0xff9004, 0xfe8f03, 0xfe8f03, 0xfe8e03, 0xfe8e03, 0xfe8d03, 0xfe8d03, 0xfe8c03, 0xfe8c03, 0xfe8b02, 0xfe8b03, 0xfe8a02, 0xfe8a02, 0xfe8902, 0xfe8902, 0xfe8802, 0xfe8802, 0xfe8702, 0xfe8702, 0xf6870a, 0x5d472f, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4d4d4d, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x6f6f6f, 0x6f6f6f, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbebebe, 0xbebebe, 0xbcbcbc, 0xbcbcbc, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xbbb5ac, 0xe2a549, 0xfe9b05, 0xfe9a05, 0xfe9a05, 0xfe9905, 0xfe9905, 0xfe9805, 0xfe9805, 0xfe9704, 0xfe9705, 0xfe9604, 0xfe9604, 0xfe9504, 0xfe9504, 0xfe9404, 0xfe9404, 0xfe9304, 0xfe9304, 0xfe9204, 0xfe9204, 0xfe9103, 0xfe9103, 0xfe9103, 0xfe9003, 0xfe8f03, 0xfe8f03, 0xfe8f03, 0xfe8e03, 0xfe8e03, 0xfe8d03, 0xfe8d02, 0xfe8d03, 0xfe8c02, 0xfe8b02, 0xfe8b02, 0xfe8b02, 0xfe8a02, 0xfe8a02, 0xfe8902, 0xfe8902, 0xfe8801, 0xfe8802, 0xfe8701, 0xfe8702, 0xfa8605, 0xd08635, 0x91867a, 0x393939, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4c4c4c, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcbcbcb, 0xcbcbcb, 0xc9c9c9, 0xc9c9c9, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xc3af90, 0xc7ad88, 0xc5ac87, 0xc5ac87, 0xc4aa85, 0xc4aa85, 0xc2a884, 0xc1a783, 0xc1a682, 0xc0a681, 0xbfa580, 0xbea480, 0xbea37f, 0xbda27e, 0xbca17d, 0xbba07d, 0xbb9f7c, 0xba9f7b, 0xb99e7a, 0xb89d7a, 0xb89c79, 0xb79b78, 0xb59976, 0xb59976, 0xb49875, 0xb49875, 0xb29673, 0xb29673, 0xb19472, 0xb19472, 0xaf9370, 0xaf9270, 0xae916f, 0xad906e, 0xac8f6d, 0xac8e6c, 0xab8d6c, 0xaa8d6b, 0xa98c6a, 0xa98b69, 0xa88a69, 0xa2896e, 0x898989, 0x888888, 0x878787, 0x868686, 0x848484, 0x848484, 0x828282, 0x828282, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x5a5a5a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc2c2c2, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xababab, 0xababab, 0xa9a9a9, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x949494, 0x949494, 0x929292, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7b7b7b, 0x7b7b7b, 0x797979, 0x797979, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xcfcfcf, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0x9f9f9f, 0x9f9f9f, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x9b9b9b, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x888888, 0x888888, 0x868686, 0x868686, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x6f6f6f, 0x6f6f6f, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbebebe, 0xbcbcbc, 0xbcbcbc, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xa9a9a9, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa5a5a5, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcbcbcb, 0xc9c9c9, 0xc9c9c9, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb2b2b2, 0xb0b0b0, 0xb0b0b0, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x9b9b9b, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x848484, 0x848484, 0x828282, 0x828282, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x5a5a5a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc2c2c2, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xa9a9a9, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x929292, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7b7b7b, 0x7b7b7b, 0x797979, 0x797979, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xc6c6c6, 0xd1d1d1, 0xcfcfcf, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x9b9b9b, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x868686, 0x868686, 0x848484, 0x848484, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x6f6f6f, 0x6f6f6f, 0x6d6d6d, 0x565656, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x9a9a9a, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbebebe, 0xbebebe, 0xbcbcbc, 0xbcbcbc, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa5a5a5, 0xa3a3a3, 0xa3a3a3, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x464646, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x797979, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcbcbcb, 0xcbcbcb, 0xc9c9c9, 0xc9c9c9, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb2b2b2, 0xb0b0b0, 0xb0b0b0, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x9b9b9b, 0x999999, 0x999999, 0x979797, 0x979797, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x848484, 0x848484, 0x828282, 0x828282, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x353535, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xbfbfbf, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc2c2c2, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xababab, 0xababab, 0xa9a9a9, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x949494, 0x949494, 0x929292, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7b7b7b, 0x7b7b7b, 0x797979, 0x797979, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x464646, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x464646, 0xcfcfcf, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0x9f9f9f, 0x9f9f9f, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x9b9b9b, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x888888, 0x888888, 0x868686, 0x868686, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x6f6f6f, 0x676767, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x7f7f7f, 0xbababa, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbebebe, 0xbcbcbc, 0xbcbcbc, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xa9a9a9, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa5a5a5, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x626262, 0x484848, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x3a3a3a, 0x4b4b4b, 0x4b4b4b, 0x4a4a4a, 0x4a4a4a, 0x4a4a4a, 0x4a4a4a, 0x494949, 0x494949, 0x494949, 0x494949, 0x484848, 0x484848, 0x484848, 0x484848, 0x474747, 0x474747, 0x474747, 0x464646, 0x464646, 0x464646, 0x464646, 0x454545, 0x454545, 0x454545, 0x454545, 0x444444, 0x444444, 0x444444, 0x444444, 0x434343, 0x434343, 0x434343, 0x424242, 0x424242, 0x424242, 0x424242, 0x414141, 0x414141, 0x414141, 0x414141, 0x404040, 0x404040, 0x404040, 0x404040, 0x3f3f3f, 0x3f3f3f, 0x3f3f3f, 0x3f3f3f, 0x3e3e3e, 0x3e3e3e, 0x3e3e3e, 0x3e3e3e, 0x3d3d3d, 0x3d3d3d, 0x3d3d3d, 0x3d3d3d, 0x3c3c3c, 0x3c3c3c, 0x3c3c3c, 0x3c3c3c, 0x3b3b3b, 0x3b3b3b, 0x3b3b3b, 0x3a3a3a, 0x3a3a3a, 0x3a3a3a, 0x3a3a3a, 0x393939, 0x393939, 0x393939, 0x393939, 0x383838, 0x383838, 0x383838, 0x383838, 0x373737, 0x373737, 0x373737, 0x373737, 0x363636, 0x363636, 0x363636, 0x353535, 0x353535, 0x353535, 0x353535, 0x272727, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, + 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020 +}; \ No newline at end of file diff --git a/dev/BootLoader/BootKit/Support.h b/dev/BootLoader/BootKit/Support.h new file mode 100644 index 00000000..ee783c08 --- /dev/null +++ b/dev/BootLoader/BootKit/Support.h @@ -0,0 +1,167 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +/// @file Support.h +/// @brief Purpose of this file is to help port libs into the bootloader. + +#include + +#define kLongMax ((long)(~0UL >> 1)) +#define kLongMin (~kLongMax) + +#ifdef __ZBAOSLDR__ + +/// @brief memset definition in C++. +/// @param dst destination pointer. +/// @param byte value to fill in. +/// @param len length of of src. +EXTERN_C void* memset(void* dst, int byte, long long unsigned int len); + +/// @brief memcpy definition in C++. +/// @param dst destination pointer. +/// @param src source pointer. +/// @param len length of of src. +EXTERN_C void* memcpy(void* dst, const void* src, long long unsigned int len); + +/// @brief strlen definition in C++. +EXTERN_C size_t strlen(const char* whatToCheck); + +/// @brief strcmp definition in C++. +EXTERN_C int strcmp(const char* whatToCheck, const char* whatToCheckRight); + +#define SetMem(dst, c, sz) memset(dst, c, sz) +#define MoveMem(dst, src, sz) memcpy(dst, src, sz) +#define CopyMem(dst, src, sz) memcpy(dst, src, sz) +#define StrLen(src) strlen(src) +#define StrCmp(dst, src) strcmp(dst, src) + +#endif // __ZBAOSLDR__ + +inline int IsSpace(int c) +{ + return c == ' '; +} + +inline int StringNCompare(const char* destination, const char* source, long length) +{ + long err = 0; + + for (long i = 0UL; i < length; ++i) + { + if (source[i] != destination[i]) + ++err; + } + + return err; +} + +inline long StringToLong(const char* nptr, char** endptr, int base) +{ + const char *p = nptr, *endp; + bool is_neg = 0, overflow = 0; + + /* Need unsigned so (-kLongMin) can fit in these: */ + unsigned long n = 0UL, cutoff; + int cutlim; + + if (base < 0 || base == 1 || base > 36) + { + return 0L; + } + + endp = nptr; + + while (IsSpace(*p)) + p++; + + if (*p == '+') + { + p++; + } + else if (*p == '-') + { + is_neg = 1, p++; + } + if (*p == '0') + { + p++; + /* For strtol(" 0xZ", &endptr, 16), endptr should point to 'x'; + * pointing to ' ' or '0' is non-compliant. + * (Many implementations do this wrong.) */ + endp = p; + if (base == 16 && (*p == 'X' || *p == 'x')) + { + p++; + } + else if (base == 2 && (*p == 'B' || *p == 'b')) + { + /* C23 standard supports "0B" and "0b" prefixes. */ + p++; + } + else if (base == 0) + { + if (*p == 'X' || *p == 'x') + { + base = 16, p++; + } + else if (*p == 'B' || *p == 'b') + { + base = 2, p++; + } + else + { + base = 8; + } + } + } + else if (base == 0) + { + base = 10; + } + + cutoff = (is_neg) ? -(kLongMin / base) : kLongMax / base; + cutlim = (is_neg) ? -(kLongMin % base) : kLongMax % base; + + while (1) + { + int c; + if (*p >= 'A') + c = ((*p - 'A') & (~('a' ^ 'A'))) + 10; + else if (*p <= '9') + c = *p - '0'; + else + break; + if (c < 0 || c >= base) + break; + endp = ++p; + if (overflow) + { + /* endptr should go forward and point to the non-digit character + * (of the given base); required by ANSI standard. */ + if (endptr) + continue; + break; + } + if (n > cutoff || (n == cutoff && c > cutlim)) + { + overflow = 1; + continue; + } + n = n * base + c; + } + + if (endptr) + *endptr = (char*)endp; + + if (overflow) + { + return ((is_neg) ? kLongMin : kLongMax); + } + + return (long)((is_neg) ? -n : n); +} diff --git a/dev/BootLoader/BootKit/Thread.h b/dev/BootLoader/BootKit/Thread.h new file mode 100644 index 00000000..691c9b97 --- /dev/null +++ b/dev/BootLoader/BootKit/Thread.h @@ -0,0 +1,44 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include +#include +#include + +namespace Boot +{ + using namespace Kernel; + + class BThread; + + /// @brief Program loader class + /// @package nl.zeta.boot.api + class BThread final + { + public: + explicit BThread() = delete; + ~BThread() = default; + + explicit BThread(Kernel::VoidPtr blob); + + BThread& operator=(const BThread&) = default; + BThread(const BThread&) = default; + + void Start(HEL::BootInfoHeader* handover, BOOL is_own_stack); + void SetName(const char* name); + const char* GetName(); + bool IsValid(); + + private: + Char fBlobName[255] = {"BootThread"}; + VoidPtr fStartAddress{nullptr}; + VoidPtr fBlob{nullptr}; + UInt8* fStack{nullptr}; + HEL::BootInfoHeader* fHandover{nullptr}; + }; +} // namespace Boot diff --git a/dev/BootLoader/DownloadOVMF.ps1 b/dev/BootLoader/DownloadOVMF.ps1 new file mode 100644 index 00000000..5a2c5f0e --- /dev/null +++ b/dev/BootLoader/DownloadOVMF.ps1 @@ -0,0 +1,4 @@ +$client = new-object System.Net.WebClient +$output = "$PSScriptRoot\OVMF.fd" + +$client.DownloadFile("https://retrage.github.io/edk2-nightly/bin/DEBUGX64_OVMF.fd", $output) diff --git a/dev/BootLoader/Modules/.keep b/dev/BootLoader/Modules/.keep new file mode 100644 index 00000000..e69de29b diff --git a/dev/BootLoader/Modules/NetBoot/.hgkeep b/dev/BootLoader/Modules/NetBoot/.hgkeep new file mode 100644 index 00000000..e69de29b diff --git a/dev/BootLoader/Modules/NetBoot/Boot.S b/dev/BootLoader/Modules/NetBoot/Boot.S new file mode 100644 index 00000000..090b3050 --- /dev/null +++ b/dev/BootLoader/Modules/NetBoot/Boot.S @@ -0,0 +1,28 @@ +;; /* +;; * ======================================================== +;; * +;; * BootZ +;; * Copyright (C) 2024, TQ B.V, all rights reserved., all rights reserved. +;; * +;; * ======================================================== +;; */ + +.code64 +.intel_syntax noprefix + +#define kTypeDriver 101 +#define kArchAmd64 122 +#define kHandoverMagic 0xBADCC + +.section .ldr + +.quad kHandoverMagic +.word kTypeDriver + +.text + +.extern main +.global __main + +__main: + ret diff --git a/dev/BootLoader/Modules/NetBoot/Module.cc b/dev/BootLoader/Modules/NetBoot/Module.cc new file mode 100644 index 00000000..a7c20e06 --- /dev/null +++ b/dev/BootLoader/Modules/NetBoot/Module.cc @@ -0,0 +1,16 @@ +/* + * ======================================================== + * + * NetBoot + * Copyright (C) 2024, TQ B.V, all rights reserved., all rights reserved. + * + * ======================================================== + */ + +#include +#include + +EXTERN_C Int32 main(Kernel::HEL::BootInfoHeader* Handover) +{ + return kEfiOk; +} diff --git a/dev/BootLoader/Modules/NetBoot/NetBoot.h b/dev/BootLoader/Modules/NetBoot/NetBoot.h new file mode 100644 index 00000000..79e9951c --- /dev/null +++ b/dev/BootLoader/Modules/NetBoot/NetBoot.h @@ -0,0 +1,26 @@ +/* + * ======================================================== + * + * NetBoot + * Copyright (C) 2024, TQ B.V, all rights reserved., all rights reserved. + * + * ======================================================== + */ + +#pragma once + +#include + +/// @brief the internet header is used to download updates OTA. +typedef struct NetBootInternetHeader +{ + Kernel::Char NB1; /// magic char 1 'N' + Kernel::Char NB2; /// magic char 2 'E' + Kernel::Char NB3; /// magic char 3 'T' + Kernel::Char NB4; /// magic char 4 'B' + + Kernel::Char PatchName[255]; /// example: ColdChoco + Kernel::Int32 PatchLength; /// the patch length. + Kernel::Char PatchTarget[255]; /// the target file. + Kernel::Boolean ImpliesROM; /// does it imply an EEPROM reprogram? +} NetBootInternetHeader; diff --git a/dev/BootLoader/Modules/NetBoot/build.json b/dev/BootLoader/Modules/NetBoot/build.json new file mode 100644 index 00000000..3844f9cb --- /dev/null +++ b/dev/BootLoader/Modules/NetBoot/build.json @@ -0,0 +1,24 @@ +{ + "compiler_path": "x86_64-w64-mingw32-g++", + "compiler_std": "c++20", + "headers_path": ["../", "../../", "../../../Kernel", "../../../", "./"], + "sources_path": [".cc", "*.S"], + "output_name": "netboot.sys", + "compiler_flags": [ + "-ffreestanding", + "-nostdlib", + "-std=c++20", + "-fPIC", + "-fno-rtti", + "-fno-exceptions", + "-Wl,--subsystem=17,--image-base,0x1000000" + ], + "cpp_macros": [ + "__MINOSKRNL__", + "__ZBAOSLDR__", + "__ZKA_AMD64__", + "kNetBootVersionHighest=0x0100", + "kNetBootVersionLowest=0x0100", + "kNetBootVersion=0x0100" + ] +} diff --git a/dev/BootLoader/Modules/SysChk/.hgkeep b/dev/BootLoader/Modules/SysChk/.hgkeep new file mode 100644 index 00000000..e69de29b diff --git a/dev/BootLoader/Modules/SysChk/Boot.S b/dev/BootLoader/Modules/SysChk/Boot.S new file mode 100644 index 00000000..ad1dc1d0 --- /dev/null +++ b/dev/BootLoader/Modules/SysChk/Boot.S @@ -0,0 +1,20 @@ +;; /* +;; * ======================================================== +;; * +;; * BootZ +;; * Copyright (C) 2024, TQ B.V, all rights reserved., all rights reserved. +;; * +;; * ======================================================== +;; */ + +.code64 +.intel_syntax noprefix + +#define kTypeDriver 101 +#define kArchAmd64 122 +#define kHandoverMagic 0xBADCC + +.section .ldr + +.quad kHandoverMagic +.word kTypeDriver diff --git a/dev/BootLoader/Modules/SysChk/Module.cc b/dev/BootLoader/Modules/SysChk/Module.cc new file mode 100644 index 00000000..2ae5023e --- /dev/null +++ b/dev/BootLoader/Modules/SysChk/Module.cc @@ -0,0 +1,22 @@ +/* + * ======================================================== + * + * NetBoot + * Copyright (C) 2024, TQ B.V, all rights reserved., all rights reserved. + * + * ======================================================== + */ + +#include + +EXTERN_C Int32 ModuleMain(Kernel::HEL::BootInfoHeader* Handover) +{ + EfiSystemTable* system_table = (EfiSystemTable*)Handover->f_FirmwareCustomTables[1]; + + system_table->ConOut->ClearScreen(system_table->ConOut); + + system_table->ConOut->OutputString(system_table->ConOut, L"SYSCHK: CHECKING FOR VALID NEFS OR HPFS PARTITIONS...\r\n"); + system_table->ConOut->OutputString(system_table->ConOut, L"SYSCHK: GOOD TO GO!\r\n"); + + return kEfiOk; +} diff --git a/dev/BootLoader/Modules/SysChk/build.json b/dev/BootLoader/Modules/SysChk/build.json new file mode 100644 index 00000000..cd21e269 --- /dev/null +++ b/dev/BootLoader/Modules/SysChk/build.json @@ -0,0 +1,24 @@ +{ + "compiler_path": "x86_64-w64-mingw32-g++", + "compiler_std": "c++20", + "headers_path": ["../", "../../", "../../../Kernel", "../../../", "./"], + "sources_path": ["*.cc", "*.S"], + "output_name": "syschk.sys", + "compiler_flags": [ + "-ffreestanding", + "-nostdlib", + "-std=c++20", + "-fPIC", + "-fno-rtti", + "-fno-exceptions", + "-Wl,--subsystem=17,--image-base,0x10000000,-e,ModuleMain" + ], + "cpp_macros": [ + "__MINOSKRNL__", + "__ZBAOSLDR__", + "__ZKA_AMD64__", + "kChkVersionHighest=0x0100", + "kChkVersionLowest=0x0100", + "kChkVersion=0x0100" + ] +} diff --git a/dev/BootLoader/ReadMe.md b/dev/BootLoader/ReadMe.md new file mode 100644 index 00000000..8a9de0f6 --- /dev/null +++ b/dev/BootLoader/ReadMe.md @@ -0,0 +1,20 @@ +# BootZ (Zeta Bootloader Architecture) + +You need: + +- MinGW for the Kernel and bootloader. +- Netwide Assembler to output COFF object code. + +Start by cloning the repo: + +``` +git clone git@github.com:amlel-el-mahrouss/zka-dev.git +``` + +And then execute: + +``` +make all +``` + +##### Copyright, TQ B.V, all rights reserved. diff --git a/dev/BootLoader/amd64-efi.make b/dev/BootLoader/amd64-efi.make new file mode 100644 index 00000000..e83a833b --- /dev/null +++ b/dev/BootLoader/amd64-efi.make @@ -0,0 +1,119 @@ +################################################## +# (c) TQ B.V, all rights reserved. +# This is the bootloader makefile. +################################################## + +CC_GNU=x86_64-w64-mingw32-g++ +LD_GNU=x86_64-w64-mingw32-ld + +WINDRES=x86_64-w64-mingw32-windres + +ADD_FILE=touch +COPY=cp +HTTP_GET=wget + +# Select this for Windows. +ifneq ($(findstring CYGWIN_NT-10.0,$(shell uname)), ) +EMU=qemu-system-x86_64w.exe +else +# this for NT distributions +EMU=qemu-system-x86_64 +endif + +ifeq ($(NEWS_MODEL), ) +ZKA_MODEL=-DkMachineModel="\"ZKA\"" +endif + +BIOS=OVMF.fd +IMG=epm-master-1.img +IMG_2=epm-slave.img +IMG_3=epm-master-2.img + +EMU_FLAGS=-net none -smp 1 -m 8G -M q35 \ + -bios $(BIOS) -drive \ + file=fat:rw:src/Root/,index=2,format=raw \ + -monitor stdio + +LD_FLAGS=-e Main --subsystem=10 + +STANDALONE_MACRO=-D__STANDALONE__ +OBJ=*.o + +REM=rm +REM_FLAG=-f + +FLAG_ASM=-f win64 +FLAG_GNU=-fshort-wchar -D__EFI_x86_64__ -mno-red-zone -D__MINOSKRNL__ -D__ZBAOSLDR__ \ + -DEFI_FUNCTION_WRAPPER -I./ -I../Kernel -I../ -c -nostdlib -fno-rtti -fno-exceptions \ + -std=c++20 -D__HAVE_ZKA_APIS__ -DZBA_USE_FB -D__ZKA_AMD64__ -D__ZKA__ -DZKA_AUTO_FORMAT + +BOOTLOADER=zbaosldr.exe +KERNEL=minoskrnl.exe +SYSCHK=syschk.sys +STARTUP=startup.sys +SCIKIT=SCIKit.dylib + +.PHONY: invalid-recipe +invalid-recipe: + @echo "=== ERROR ===" + @echo "=> Use make compile- instead." + +.PHONY: all +all: compile-amd64 + mkdir -p src/Root/EFI/BOOT + $(LD_GNU) $(OBJ) $(LD_FLAGS) -o src/$(BOOTLOADER) + $(COPY) src/$(BOOTLOADER) src/Root/EFI/BOOT/BOOTX64.EFI + $(COPY) src/$(BOOTLOADER) src/Root/EFI/BOOT/ZBAOSLDR.EFI + $(COPY) ../Kernel/$(KERNEL) src/Root/$(KERNEL) + $(COPY) ./Modules/SysChk/$(SYSCHK) src/Root/$(SYSCHK) + $(COPY) ../SCIKit/$(SCIKIT) src/Root/$(SCIKIT) + $(COPY) src/$(BOOTLOADER) src/Root/$(BOOTLOADER) + +ifneq ($(DEBUG_SUPPORT), ) +DEBUG = -D__DEBUG__ +endif + +.PHONY: compile-amd64 +compile-amd64: + $(WINDRES) src/BootloaderRsrc.rsrc -O coff -o BootloaderRsrc.o + $(CC_GNU) $(ZKA_MODEL) $(STANDALONE_MACRO) $(FLAG_GNU) $(DEBUG) \ + $(wildcard src/HEL/AMD64/*.cc) \ + $(wildcard src/HEL/AMD64/*.S) \ + $(wildcard src/*.cc) + +.PHONY: run-efi-amd64-ahci +run-efi-amd64-ahci: + $(EMU) $(EMU_FLAGS) -hdd $(IMG) + +.PHONY: run-efi-amd64-ata +run-efi-amd64-ata: + $(EMU) $(EMU_FLAGS) -device piix3-ide,id=ide -drive id=disk,file=$(IMG),format=raw,if=none -device ide-hd,drive=disk,bus=ide.0 + +# img_2 is the rescue disk. img is the bootable disk, as provided by the Zeta specs. +.PHONY: epm-img +epm-img: + qemu-img create -f raw $(IMG) 10G + qemu-img create -f raw $(IMG_2) 4G + qemu-img create -f raw $(IMG_3) 4G + +.PHONY: download-edk +download-edk: + $(HTTP_GET) https://retrage.github.io/edk2-nightly/bin/DEBUGX64_OVMF.fd -O OVMF.fd + +BINS=*.bin +EXECUTABLES=zbaosldr.exe minoskrnl.exe OVMF.fd + +TARGETS=$(REM_FLAG) $(OBJ) $(BIN) $(IMG) $(IMG_2) $(EXECUTABLES) + +.PHONY: clean +clean: + $(REM) $(TARGETS) + +.PHONY: help +help: + @echo "=== HELP ===" + @echo "epm-img: Format a disk using the Explicit Partition Map." + @echo "gpt-img: Format a disk using the Explicit Partition Map." + @echo "clean: clean bootloader." + @echo "bootloader-amd64: Build bootloader. (PC AMD64)" + @echo "run-efi-amd64-: Run bootloader. (PC AMD64)" diff --git a/dev/BootLoader/arm64-efi.make b/dev/BootLoader/arm64-efi.make new file mode 100644 index 00000000..ccf60605 --- /dev/null +++ b/dev/BootLoader/arm64-efi.make @@ -0,0 +1,112 @@ +################################################## +# (c) TQ B.V, all rights reserved. +# This is the bootloader makefile. +################################################## + +CC_GNU = clang++ +LD_GNU = lld-link + +ADD_FILE=touch +COPY=cp +HTTP_GET=wget + +# Select this for Windows. +ifneq ($(findstring CYGWIN_NT-10.0,$(shell uname)), ) +EMU=qemu-system-aarch64w.exe +else +# this for NT distributions +EMU=qemu-system-aarch64 +endif + +ifeq ($(NEWS_MODEL), ) +ZKA_MODEL=-DkMachineModel="\"ZKA\"" +endif + +BIOS=OVMF.fd +IMG=epm-master-1.img +IMG_2=epm-slave.img +IMG_3=epm-master-2.img + +EMU_FLAGS=-net none -smp 4 -m 8G -cpu max -M virt-9.1 \ + -bios $(BIOS) \ + -drive id=disk,file=$(IMG),format=raw,if=none \ + -drive \ + file=fat:rw:src/Root/,index=1,format=raw \ + -device virtio-tablet-pci \ + -d int -no-shutdown -no-reboot -device virtio-gpu-pci,xres=844,yres=390 -serial stdio + +LD_FLAGS=-subsystem:efi_application -entry:Main /nodefaultlib + +STANDALONE_MACRO=-D__STANDALONE__ +OBJ=*.o + +REM=rm +REM_FLAG=-f + +FLAG_ASM=-f win64 +FLAG_GNU=-fshort-wchar -c -ffreestanding -MMD -mno-red-zone -D__ZKA_ARM64__ -fno-rtti -fno-exceptions -I./ \ + -target aarch64-unknown-windows \ + -std=c++20 -D__FSKIT_USE_NEFS__ -D__STANDALONE__ -D__MINOSKRNL__ -D__ZBAOSLDR__ -D__HAVE_ZKA_APIS__ -D__ZKA__ -I../ -I../Kernel + +BOOT_LOADER=zbaosldr.exe +KERNEL=minoskrnl.exe +SYS_CHK=syschk.sys +STARTUP=startup.sys + +.PHONY: invalid-recipe +invalid-recipe: + @echo "invalid-recipe: Use make compile- instead." + +.PHONY: all +all: compile-amd64 + mkdir -p src/Root/EFI/BOOT + $(LD_GNU) $(OBJ) $(LD_FLAGS) /out:src/$(BOOT_LOADER) + $(COPY) src/$(BOOT_LOADER) src/Root/EFI/BOOT/BOOTAA64.EFI + $(COPY) src/$(BOOT_LOADER) src/Root/EFI/BOOT/BootZ.EFI + $(COPY) ../Kernel/$(KERNEL) src/Root/$(KERNEL) + $(COPY) src/$(BOOT_LOADER) src/Root/$(BOOT_LOADER) + +ifneq ($(DEBUG_SUPPORT), ) +DEBUG = -D__DEBUG__ +endif + +.PHONY: compile-amd64 +compile-amd64: + $(RESCMD) + $(CC_GNU) $(ZKA_MODEL) $(STANDALONE_MACRO) $(FLAG_GNU) $(DEBUG) \ + $(wildcard src/HEL/ARM64/*.cc) \ + $(wildcard src/HEL/ARM64/*.S) \ + $(wildcard src/*.cc) + +.PHONY: run-efi-amd64 +run-efi-amd64: + $(EMU) $(EMU_FLAGS) + +# img_2 is the rescue disk. img is the bootable disk, as provided by the Zeta. +.PHONY: epm-img +epm-img: + qemu-img create -f raw $(IMG) 10G + qemu-img create -f raw $(IMG_2) 4G + qemu-img create -f raw $(IMG_3) 4G + +.PHONY: download-edk +download-edk: + $(HTTP_GET) https://retrage.github.io/edk2-nightly/bin/DEBUGAARCH64_QEMU_EFI.fd -O OVMF.fd + +BINS=*.bin +EXECUTABLES=zbaosldr.exe minoskrnl.exe OVMF.fd + +TARGETS=$(REM_FLAG) $(OBJ) $(BIN) $(IMG) $(IMG_2) $(EXECUTABLES) + +.PHONY: clean +clean: + $(REM) $(TARGETS) + +.PHONY: help +help: + @echo "=== HELP ===" + @echo "epm-img: Format a disk using the Explicit Partition Map." + @echo "gpt-img: Format a disk using the Explicit Partition Map." + @echo "clean: clean bootloader." + @echo "bootloader-amd64: Build bootloader. (PC AMD64)" + @echo "run-efi-amd64: Run bootloader. (PC AMD64)" diff --git a/dev/BootLoader/src/.gitkeep b/dev/BootLoader/src/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/dev/BootLoader/src/BootFileReader.cc b/dev/BootLoader/src/BootFileReader.cc new file mode 100644 index 00000000..d5976464 --- /dev/null +++ b/dev/BootLoader/src/BootFileReader.cc @@ -0,0 +1,203 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + + File: FileReader.cc + Purpose: New Boot FileReader, + Read complete file and store it in a buffer. + +------------------------------------------- */ + +#include +#include +#include +#include +#include +#include + +/// @file BootFileReader +/// @brief Bootloader File reader. +/// BUGS: 0 + +//////////////////////////////////////////////////////////////////////////////////////////////////// +/// +/// +/// @name BFileReader class +/// @brief Reads the file as a blob. +/// +/// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*** + @brief File Reader constructor. +*/ +Boot::BFileReader::BFileReader(const CharacterTypeUTF16* path, + EfiHandlePtr ImageHandle) +{ + if (path != nullptr) + { + SizeT index = 0UL; + for (; path[index] != L'\0'; ++index) + { + mPath[index] = path[index]; + } + + mPath[index] = 0; + } + + /// Load protocols with their GUIDs. + + EfiGUID guidEfp = EfiGUID(EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID); + + EfiSimpleFilesystemProtocol* efp = nullptr; + + EfiLoadImageProtocol* img = nullptr; + EfiGUID guidImg = EfiGUID(EFI_LOADED_IMAGE_PROTOCOL_GUID); + + if (BS->HandleProtocol(ImageHandle, &guidImg, (void**)&img) != kEfiOk) + { + mWriter.Write(L"BootZ: Handle-Protocol: No-Such-Protocol").Write(L"\r"); + this->mErrorCode = kNotSupported; + } + + if (BS->HandleProtocol(img->DeviceHandle, &guidEfp, (void**)&efp) != kEfiOk) + { + mWriter.Write(L"BootZ: Handle-Protocol: No-Such-Protocol").Write(L"\r"); + this->mErrorCode = kNotSupported; + return; + } + + /// Start doing disk I/O + + if (efp->OpenVolume(efp, &mRootFs) != kEfiOk) + { + mWriter.Write(L"BootZ: Fetch-Protocol: No-Such-Volume").Write(L"\r"); + this->mErrorCode = kNotSupported; + return; + } + + EfiFileProtocol* fileFs = nullptr; + + if (mRootFs->Open(mRootFs, &fileFs, mPath, kEFIFileRead, kEFIReadOnly) != + kEfiOk) + { + mWriter.Write(L"BootZ: Fetch-Protocol: No-Such-Path: ") + .Write(mPath) + .Write(L"\r"); + this->mErrorCode = kNotSupported; + + CGDrawString("BootZ: PLEASE RECOVER YOUR MINKRNL INSTALL.", 40, 10, RGB(0xFF, 0xFF, 0xFF)); + + mRootFs->Close(mRootFs); + + return; + } + + mSizeFile = 0; + mFile = fileFs; + mErrorCode = kOperationOkay; +} + +Boot::BFileReader::~BFileReader() +{ + if (this->mFile) + { + this->mFile->Close(this->mFile); + this->mFile = nullptr; + } + + if (this->mRootFs) + { + this->mRootFs->Close(this->mRootFs); + this->mRootFs = nullptr; + } + + if (this->mBlob) + { + BS->FreePool(this->mBlob); + this->mBlob = nullptr; + } + + BSetMem(this->mPath, 0, kPathLen); +} + +/** + @brief Reads all of the file into a buffer. + @param **readUntil** size of file + @param **chunkToRead** chunk to read each time. +*/ +Void Boot::BFileReader::ReadAll(SizeT readUntil, SizeT chunkToRead, UIntPtr out_address) +{ + if (mBlob == nullptr) + { + EfiFileInfo newPtrInfo{}; + UInt32 szInfo = 0U; + + EfiGUID kFileInfoGUID = EFI_FILE_INFO_GUID; + + if (mFile->GetInfo(mFile, &kFileInfoGUID, &szInfo, &newPtrInfo) == kEfiOk) + { + if (newPtrInfo.FileSize < readUntil) + readUntil = newPtrInfo.FileSize; + else if (readUntil < 1) + readUntil = newPtrInfo.FileSize; + + mWriter.Write(L"BootZ: File size: ").Write(readUntil).Write("\r"); + } + + if (!out_address) + { + if (auto err = BS->AllocatePool(EfiLoaderCode, readUntil, (VoidPtr*)&mBlob) != + kEfiOk) + { + mWriter.Write(L"*** error: ").Write(err).Write(L" ***\r"); + EFI::ThrowError(L"OutOfMemory", L"Out of memory."); + } + } + else + { + mBlob = (VoidPtr)out_address; + } + } + + mErrorCode = kNotSupported; + + UInt64 bufSize = chunkToRead; + UInt64 szCnt = 0UL; + + while (szCnt < readUntil) + { + auto res = mFile->Read(mFile, &bufSize, (VoidPtr)(&((Char*)mBlob)[szCnt])); + + szCnt += bufSize; + + if (res == kBufferTooSmall) + { + bufSize = chunkToRead; + } + } + + mSizeFile = szCnt; + mErrorCode = kOperationOkay; +} + +/// @brief error code getter. +/// @return the error code. +Int32& Boot::BFileReader::Error() +{ + return mErrorCode; +} + +/// @brief blob getter. +/// @return the blob. +VoidPtr Boot::BFileReader::Blob() +{ + return mBlob; +} + +/// @breif Size getter. +/// @return the size of the file. +UInt64& Boot::BFileReader::Size() +{ + return mSizeFile; +} diff --git a/dev/BootLoader/src/BootString.cc b/dev/BootLoader/src/BootString.cc new file mode 100644 index 00000000..6ea95173 --- /dev/null +++ b/dev/BootLoader/src/BootString.cc @@ -0,0 +1,92 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + + File: BootString.cc + Purpose: BootZ string library + + Revision History: + + + +------------------------------------------- */ + +#include +#include +#include + +/// BUGS: 0 + +///////////////////////////////////////////////////////////////////////////////////////////////////////// + +Kernel::SizeT Boot::BCopyMem(CharacterTypeUTF16* dest, CharacterTypeUTF16* src, const Kernel::SizeT len) +{ + if (!dest || !src) + return 0; + + SizeT index = 0UL; + for (; index < len; ++index) + { + dest[index] = src[index]; + } + + return index; +} + +Kernel::SizeT Boot::BStrLen(const CharacterTypeUTF16* ptr) +{ + if (!ptr) + return 0; + + Kernel::SizeT cnt = 0; + + while (*ptr != (CharacterTypeUTF16)0) + { + ++ptr; + ++cnt; + } + + return cnt; +} + +Kernel::SizeT Boot::BSetMem(CharacterTypeUTF16* src, const CharacterTypeUTF16 byte, const Kernel::SizeT len) +{ + if (!src) + return 0; + + Kernel::SizeT cnt = 0UL; + + while (*src != 0) + { + if (cnt > len) + break; + + *src = byte; + ++src; + + ++cnt; + } + + return cnt; +} + +Kernel::SizeT Boot::BSetMem(CharacterTypeUTF8* src, const CharacterTypeUTF8 byte, const Kernel::SizeT len) +{ + if (!src) + return 0; + + Kernel::SizeT cnt = 0UL; + + while (*src != 0) + { + if (cnt > len) + break; + + *src = byte; + ++src; + + ++cnt; + } + + return cnt; +} diff --git a/dev/BootLoader/src/BootSupport.cc b/dev/BootLoader/src/BootSupport.cc new file mode 100644 index 00000000..521fcd8f --- /dev/null +++ b/dev/BootLoader/src/BootSupport.cc @@ -0,0 +1,82 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include +#include +#include +#include +#include +#include + +#ifdef __STANDALONE__ + +/// @brief memset definition in C++. +/// @param dst destination pointer. +/// @param byte value to fill in. +/// @param len length of of src. +EXTERN_C VoidPtr memset(void* dst, int byte, long long unsigned int len) +{ + for (size_t i = 0UL; i < len; ++i) + { + ((int*)dst)[i] = byte; + } + + return dst; +} + +/// @brief memcpy definition in C++. +/// @param dst destination pointer. +/// @param src source pointer. +/// @param len length of of src. +EXTERN_C VoidPtr memcpy(void* dst, const void* src, long long unsigned int len) +{ + for (size_t i = 0UL; i < len; ++i) + { + ((int*)dst)[i] = ((int*)src)[i]; + } + + return dst; +} + +/// @brief strlen definition in C++. +EXTERN_C size_t strlen(const char* whatToCheck) +{ + SizeT len = 0; + + while (whatToCheck[len] != 0) + { + ++len; + } + + return len; +} + +/// @brief strcmp definition in C++. +EXTERN_C int strcmp(const char* whatToCheck, const char* whatToCheckRight) +{ + if (!whatToCheck || *whatToCheck == 0) + return 0; + + SizeT len = 0; + + while (whatToCheck[len] == whatToCheckRight[len]) + { + if (whatToCheck[len] == 0) + return 0; + + ++len; + } + + return len; +} + +/// @brief something specific to the Microsoft's ABI, When the stack grows too big. +EXTERN_C void ___chkstk_ms(void) +{ +} + +#endif diff --git a/dev/BootLoader/src/BootTextWriter.cc b/dev/BootLoader/src/BootTextWriter.cc new file mode 100644 index 00000000..69a2ad47 --- /dev/null +++ b/dev/BootLoader/src/BootTextWriter.cc @@ -0,0 +1,169 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + + File: BootTextWriter.cc + Purpose: BootZ string library + + Revision History: + + + +------------------------------------------- */ + +#include +#include +#include +#include + +///////////////////////////////////////////////////////////////////////////////////////////////////////// +/// BUGS: 0 /// +///////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** +@brief puts wrapper over EFI ConOut. +*/ +Boot::BTextWriter& Boot::BTextWriter::Write(const CharacterTypeUTF16* str) +{ +#ifdef __DEBUG__ + if (!str || *str == 0) + return *this; + + CharacterTypeUTF16 strTmp[2]; + strTmp[1] = 0; + + for (size_t i = 0; str[i] != 0; i++) + { + if (str[i] == '\r') + { + strTmp[0] = str[i]; + ST->ConOut->OutputString(ST->ConOut, strTmp); + + strTmp[0] = '\n'; + ST->ConOut->OutputString(ST->ConOut, strTmp); + } + else + { + strTmp[0] = str[i]; + ST->ConOut->OutputString(ST->ConOut, strTmp); + } + } +#endif // ifdef __DEBUG__ + + return *this; +} + +/// @brief UTF-8 equivalent of Write (UTF-16). +/// @param str the input string. +Boot::BTextWriter& Boot::BTextWriter::Write(const Char* str) +{ +#ifdef __DEBUG__ + if (!str || *str == 0) + return *this; + + CharacterTypeUTF16 strTmp[2]; + strTmp[1] = 0; + + for (size_t i = 0; str[i] != 0; i++) + { + if (str[i] == '\r') + { + strTmp[0] = str[i]; + ST->ConOut->OutputString(ST->ConOut, strTmp); + + strTmp[0] = '\n'; + ST->ConOut->OutputString(ST->ConOut, strTmp); + } + else + { + strTmp[0] = str[i]; + ST->ConOut->OutputString(ST->ConOut, strTmp); + } + } +#endif // ifdef __DEBUG__ + + return *this; +} + +Boot::BTextWriter& Boot::BTextWriter::Write(const UChar* str) +{ +#ifdef __DEBUG__ + if (!str || *str == 0) + return *this; + + CharacterTypeUTF16 strTmp[2]; + strTmp[1] = 0; + + for (size_t i = 0; str[i] != 0; i++) + { + if (str[i] == '\r') + { + strTmp[0] = str[i]; + ST->ConOut->OutputString(ST->ConOut, strTmp); + + strTmp[0] = '\n'; + ST->ConOut->OutputString(ST->ConOut, strTmp); + } + else + { + strTmp[0] = str[i]; + ST->ConOut->OutputString(ST->ConOut, strTmp); + } + } +#endif // ifdef __DEBUG__ + + return *this; +} + +/** +@brief putc wrapper over EFI ConOut. +*/ +Boot::BTextWriter& Boot::BTextWriter::WriteCharacter(CharacterTypeUTF16 c) +{ +#ifdef __DEBUG__ + EfiCharType str[2]; + + str[0] = c; + str[1] = 0; + ST->ConOut->OutputString(ST->ConOut, str); +#endif // ifdef __DEBUG__ + + return *this; +} + +Boot::BTextWriter& Boot::BTextWriter::Write(const Long& x) +{ +#ifdef __DEBUG__ + this->_Write(x); + this->Write("h"); +#endif // ifdef __DEBUG__ + + return *this; +} + +Boot::BTextWriter& Boot::BTextWriter::_Write(const Long& x) +{ +#ifdef __DEBUG__ + UInt64 y = (x > 0 ? x : -x) / 16; + UInt64 h = (x > 0 ? x : -x) % 16; + + if (y) + this->_Write(y); + + /* fail if the hex number is not base-16 */ + if (h > 16) + { + this->WriteCharacter('?'); + return *this; + } + + if (y < 0) + y = -y; + + const char cNumbers[] = "0123456789ABCDEF"; + + this->WriteCharacter(cNumbers[h]); +#endif // ifdef __DEBUG__ + + return *this; +} diff --git a/dev/BootLoader/src/BootThread.cc b/dev/BootLoader/src/BootThread.cc new file mode 100644 index 00000000..33b058df --- /dev/null +++ b/dev/BootLoader/src/BootThread.cc @@ -0,0 +1,207 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/// @brief External boot services symbol. +EXTERN EfiBootServices* BS; + +/// @note BThread doesn't parse the symbols so doesn't nullify them, .bss is though. + +namespace Boot +{ + EXTERN_C Void rt_jump_to_address(VoidPtr code, HEL::BootInfoHeader* handover, UInt8* stack); + + BThread::BThread(VoidPtr blob) + : fBlob(blob), fStartAddress(nullptr) + { + // detect the format. + const Char* blob_bytes = reinterpret_cast(fBlob); + + BTextWriter writer; + + if (!blob_bytes) + { + // failed to provide a valid pointer. + return; + } + + if (blob_bytes[0] == kMagMz0 && + blob_bytes[1] == kMagMz1) + { + LDR_EXEC_HEADER_PTR header_ptr = CFKit::ldr_find_exec_header(blob_bytes); + LDR_OPTIONAL_HEADER_PTR opt_header_ptr = CFKit::ldr_find_opt_exec_header(blob_bytes); + + if (!header_ptr || !opt_header_ptr) + return; + +#ifdef __ZKA_AMD64__ + if (header_ptr->mMachine != kPeMachineAMD64 || + header_ptr->mSignature != kPeSignature) + { + writer.Write("BootZ: Not a PE32+ executable.\r"); + return; + } +#elif defined(__ZKA_ARM64__) + if (header_ptr->mMachine != kPeMachineAMD64 || + header_ptr->mSignature != kPeSignature) + { + writer.Write("BootZ: Not a PE32+ executable.\r"); + return; + } +#endif // __ZKA_AMD64__ || __ZKA_ARM64__ + + if (opt_header_ptr->mSubsystem != kZKASubsystem) + { + writer.Write("BootZ: Not a ZKA Subsystem executable.\r"); + return; + } + + writer.Write("BootZ: PE32+ executable detected (ZKA Subsystem).\r"); + + auto numSecs = header_ptr->mNumberOfSections; + + writer.Write("BootZ: Major Linker Ver: ").Write(opt_header_ptr->mMajorLinkerVersion).Write("\r"); + writer.Write("BootZ: Minor Linker Ver: ").Write(opt_header_ptr->mMinorLinkerVersion).Write("\r"); + writer.Write("BootZ: Major Subsystem Ver: ").Write(opt_header_ptr->mMajorSubsystemVersion).Write("\r"); + writer.Write("BootZ: Minor Subsystem Ver: ").Write(opt_header_ptr->mMinorSubsystemVersion).Write("\r"); + writer.Write("BootZ: Magic: ").Write(header_ptr->mSignature).Write("\r"); + + constexpr auto cPageSize = 512; + + EfiPhysicalAddress loadStartAddress = opt_header_ptr->mImageBase; + loadStartAddress += opt_header_ptr->mBaseOfData; + + writer.Write("BootZ: ImageBase: ").Write(loadStartAddress).Write("\r"); + + auto numPages = opt_header_ptr->mSizeOfImage / cPageSize; + BS->AllocatePages(AllocateAddress, EfiLoaderData, numPages, &loadStartAddress); + + LDR_SECTION_HEADER_PTR sectPtr = (LDR_SECTION_HEADER_PTR)(((Char*)opt_header_ptr) + header_ptr->mSizeOfOptionalHeader); + + constexpr auto sectionForCode = ".text"; + constexpr auto sectionForNewLdr = ".ldr"; + constexpr auto sectionForBSS = ".bss"; + + for (SizeT sectIndex = 0; sectIndex < numSecs; ++sectIndex) + { + LDR_SECTION_HEADER_PTR sect = §Ptr[sectIndex]; + + SetMem((VoidPtr)(loadStartAddress + sect->mVirtualAddress), 0, sect->mSizeOfRawData); + + if (StrCmp(sectionForCode, sect->mName) == 0) + { + fStartAddress = (VoidPtr)((UIntPtr)loadStartAddress + opt_header_ptr->mAddressOfEntryPoint); + writer.Write("BootZ: Executable entry address: ").Write((UIntPtr)fStartAddress).Write("\r"); + } + else if (StrCmp(sectionForNewLdr, sect->mName) == 0) + { + struct HANDOVER_INFORMATION_STUB + { + UInt64 HandoverMagic; + UInt32 HandoverType; + UInt32 HandoverPad; + UInt32 HandoverArch; + }* handover_struc = (struct HANDOVER_INFORMATION_STUB*)((UIntPtr)fBlob + sect->mPointerToRawData); + + if (handover_struc->HandoverMagic != kHandoverMagic && + handover_struc->HandoverType != HEL::kTypeKernel) + { +#ifdef __ZKA_AMD64__ + if (handover_struc->HandoverArch != HEL::kArchAMD64) + { + CGDrawString("BootZ: NOT AN HANDOVER IMAGE, BAD ARCHITECTURE...", 40, 10, RGB(0xFF, 0xFF, 0xFF)); + ::EFI::Stop(); + } +#endif + +#ifdef __ZKA_ARM64__ + if (handover_struc->HandoverArch != HEL::kArchARM64) + { + CGDrawString("BootZ: NOT AN HANDOVER IMAGE, BAD ARCHITECTURE...", 40, 10, RGB(0xFF, 0xFF, 0xFF)); + ::EFI::Stop(); + } +#endif + CGDrawString("BootZ: NOT AN HANDOVER IMAGE...", 40, 10, RGB(0xFF, 0xFF, 0xFF)); + + ::EFI::Stop(); + } + } + + writer.Write("BootZ: Raw offset: ").Write(sect->mPointerToRawData).Write(" of ").Write(sect->mName).Write("\r"); + + CopyMem((VoidPtr)(loadStartAddress + sect->mVirtualAddress), (VoidPtr)((UIntPtr)fBlob + sect->mPointerToRawData), sect->mSizeOfRawData); + } + } + else if (blob_bytes[0] == kPefMagic[0] && + blob_bytes[1] == kPefMagic[1] && + blob_bytes[2] == kPefMagic[2] && + blob_bytes[3] == kPefMagic[3]) + { + // ========================================= // + // PEF executable detected. + // ========================================= // + + fStartAddress = nullptr; + writer.Write("BootZ: PEF executable detected, won't load it.\r"); + writer.Write("BootZ: note: PEF executables aren't loadable by default.\r"); + } + else + { + writer.Write("BootZ: INVALID EXECUTABLE.\r"); + } + + fStack = new UInt8[mib_cast(8)]; + } + + /// @note handover header has to be valid! + Void BThread::Start(HEL::BootInfoHeader* handover, Bool own_stack) + { + HEL::HandoverProc err_fn = [](HEL::BootInfoHeader* rcx) -> void { + CGDrawString("BootZ: INVALID IMAGE! ABORTING...", 50, 10, RGB(0xFF, 0xFF, 0xFF)); + ::EFI::Stop(); + }; + + if (!fStartAddress) + { + err_fn(handover); + } + + fHandover = handover; + + if (own_stack) + rt_jump_to_address(fStartAddress, fHandover, &fStack[mib_cast(8) - 1]); + else + { + delete[] fStack; + reinterpret_cast(fStartAddress)(fHandover); + } + } + + const Char* BThread::GetName() + { + return fBlobName; + } + + Void BThread::SetName(const Char* name) + { + CopyMem(fBlobName, name, StrLen(name)); + } + + bool BThread::IsValid() + { + return fStartAddress != nullptr; + } +} // namespace Boot diff --git a/dev/BootLoader/src/BootloaderRsrc.rsrc b/dev/BootLoader/src/BootloaderRsrc.rsrc new file mode 100644 index 00000000..dd20a78c --- /dev/null +++ b/dev/BootLoader/src/BootloaderRsrc.rsrc @@ -0,0 +1,25 @@ +#include "../../Kernel/CompilerKit/Version.h" + +1 VERSIONINFO +FILEVERSION 1,0,0,0 +PRODUCTVERSION 1,0,0,0 +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "080904E4" + BEGIN + VALUE "CompanyName", "TQ B.V" + VALUE "FileDescription", "ZKA OS Loader." + VALUE "FileVersion", BOOTLOADER_VERSION + VALUE "InternalName", "zbaosldr" + VALUE "LegalCopyright", "Copyright (C) 2024, TQ B.V all rights reserved." + VALUE "OriginalFilename", "zbaosldr.exe" + VALUE "ProductName", "zbaosldr" + VALUE "ProductVersion", BOOTLOADER_VERSION + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x809, 1252 + END +END diff --git a/dev/BootLoader/src/HEL/64X000/.gitkeep b/dev/BootLoader/src/HEL/64X000/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/dev/BootLoader/src/HEL/64X000/Boot64x0.S b/dev/BootLoader/src/HEL/64X000/Boot64x0.S new file mode 100644 index 00000000..e79f97ef --- /dev/null +++ b/dev/BootLoader/src/HEL/64X000/Boot64x0.S @@ -0,0 +1,35 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +.section .boot_hdr +.align 4 + +/* BootZ boot header begin for a 64x000 Kernel. */ + +boot_hdr_mag: + .ascii "CB" +boot_hdr_name: + // it has to match ten bytes. + .asciz "zbaosldr\0\0" +boot_hdr_ver: + .word 0x104 +boot_hdr_proc: + .long bootloader_start + +/* BootZ boot header end */ + +.extern bootloader_main +.extern bootloader_stack + +.globl bootloader_start +bootloader_start: + psh 4 /* real address of .Laddr */ + ldi 0,(bootloader_stack-bootloader_start)(4) /* stack address location */ + mv 19,0 /* use user defined stack */ + jrl + + bl bootloader_main + blr diff --git a/dev/BootLoader/src/HEL/AMD64/.gitkeep b/dev/BootLoader/src/HEL/AMD64/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/dev/BootLoader/src/HEL/AMD64/BootAPI.S b/dev/BootLoader/src/HEL/AMD64/BootAPI.S new file mode 100644 index 00000000..963ef46a --- /dev/null +++ b/dev/BootLoader/src/HEL/AMD64/BootAPI.S @@ -0,0 +1,60 @@ +.global rt_jump_to_address +.global rt_reset_hardware + +.text + +.intel_syntax noprefix + +/** + @brief this function setups a stack and then jumps to + a function */ +rt_jump_to_address: + mov rbx, rcx + mov rcx, rdx + push rbx + push rdx + mov rsp, r8 + push rax + jmp rbx + + pop rdx + pop rbx + pop rax + + ret + +rt_reset_hardware: + /* dont raise any interrupts. (except ofc NMIs.) */ + cli + /* remap PIC */ +wait_gate1: + in al,0x64 + and al,2 + jnz wait_gate1 + mov al,0x0D1 + out 0x64,al +wait_gate2: + in al,0x64 + and al,2 + jnz wait_gate2 + mov al,0x0FE + out 0x60,al + + /* trigger triple fault, by writing to cr4 */ + + mov rax, 0 + lidt [rax] + +reset_wait: + jmp reset_wait + +.global boot_write_cr3 +.global boot_read_cr3 + +boot_read_cr3: + mov rax, rax + ret + +boot_write_cr3: + mov cr3, rcx + ret diff --git a/dev/BootLoader/src/HEL/AMD64/BootATA.cc b/dev/BootLoader/src/HEL/AMD64/BootATA.cc new file mode 100644 index 00000000..52df1b2b --- /dev/null +++ b/dev/BootLoader/src/HEL/AMD64/BootATA.cc @@ -0,0 +1,278 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +/** + * @file BootATA.cc + * @author TQ B.V (amlalelmahrouss@icloud.com) + * @brief ATA driver. + * @version 0.1 + * @date 2024-02-02 + * + * @copyright Copyright (c) TQ B.V + * + */ + +#include +#include +#include + +/// bugs: 0 + +using namespace Boot; + +#define kATADataLen 256 + +static Boolean kATADetected = false; +static Int32 kATADeviceType = kATADeviceCount; +static UInt16 kATAData[kATADataLen] = {0}; + +Boolean boot_ata_detected(Void); + +STATIC Boolean boot_ata_wait_io(UInt16 IO) +{ + for (int i = 0; i < 400; i++) + rt_in8(IO + ATA_REG_STATUS); + +ATAWaitForIO_Retry: + auto statRdy = rt_in8(IO + ATA_REG_STATUS); + + if ((statRdy & ATA_SR_BSY)) + goto ATAWaitForIO_Retry; + +ATAWaitForIO_Retry2: + statRdy = rt_in8(IO + ATA_REG_STATUS); + + if (statRdy & ATA_SR_ERR) + return false; + + if (!(statRdy & ATA_SR_DRDY)) + goto ATAWaitForIO_Retry2; + + return true; +} + +Void boot_ata_select(UInt16 Bus) +{ + if (Bus == ATA_PRIMARY_IO) + rt_out8(Bus + ATA_REG_HDDEVSEL, ATA_PRIMARY_SEL); + else + rt_out8(Bus + ATA_REG_HDDEVSEL, ATA_SECONDARY_SEL); +} + +Boolean boot_ata_init(UInt16 Bus, UInt8 Drive, UInt16& OutBus, UInt8& OutMaster) +{ + if (boot_ata_detected()) + return true; + + BTextWriter writer; + + UInt16 IO = Bus; + + boot_ata_select(IO); + + // Bus init, NEIN bit. + rt_out8(IO + ATA_REG_NEIN, 1); + + // identify until it's good. +ATAInit_Retry: + auto statRdy = rt_in8(IO + ATA_REG_STATUS); + + if (statRdy & ATA_SR_ERR) + { + writer.Write( + L"BootZ: ATA: Not an IDE based drive.\r"); + + return false; + } + + if ((statRdy & ATA_SR_BSY)) + goto ATAInit_Retry; + + rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_IDENTIFY); + + /// fetch serial info + /// model, speed, number of sectors... + + boot_ata_wait_io(IO); + + for (SizeT indexData = 0ul; indexData < kATADataLen; ++indexData) + { + kATAData[indexData] = Kernel::HAL::rt_in16(IO + ATA_REG_DATA); + } + + OutBus = + (Bus == ATA_PRIMARY_IO) ? BootDeviceATA::kPrimary : BootDeviceATA::kSecondary; + + OutMaster = (Bus == ATA_PRIMARY_IO) ? ATA_MASTER : ATA_SLAVE; + + return true; +} + +Void boot_ata_read(UInt64 Lba, UInt16 IO, UInt8 Master, CharacterTypeUTF8* Buf, SizeT SectorSz, SizeT Size) +{ + Lba /= SectorSz; + + UInt8 Command = ((!Master) ? 0xE0 : 0xF0); + + boot_ata_wait_io(IO); + boot_ata_select(IO); + + rt_out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F)); + + rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + SectorSz) / SectorSz)); + + rt_out8(IO + ATA_REG_LBA0, (Lba)&0xFF); + rt_out8(IO + ATA_REG_LBA1, (Lba) >> 8); + rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16); + rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24); + + rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_READ_PIO); + + boot_ata_wait_io(IO); + + for (SizeT IndexOff = 0; IndexOff < Size; ++IndexOff) + { + boot_ata_wait_io(IO); + Buf[IndexOff] = Kernel::HAL::rt_in16(IO + ATA_REG_DATA); + boot_ata_wait_io(IO); + } +} + +Void boot_ata_write(UInt64 Lba, UInt16 IO, UInt8 Master, CharacterTypeUTF8* Buf, SizeT SectorSz, SizeT Size) +{ + Lba /= SectorSz; + + UInt8 Command = ((!Master) ? 0xE0 : 0xF0); + + boot_ata_wait_io(IO); + boot_ata_select(IO); + + rt_out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F)); + + rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + (SectorSz)) / SectorSz)); + + rt_out8(IO + ATA_REG_LBA0, (Lba)&0xFF); + rt_out8(IO + ATA_REG_LBA1, (Lba) >> 8); + rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16); + rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24); + + rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_WRITE_PIO); + + boot_ata_wait_io(IO); + + for (SizeT IndexOff = 0; IndexOff < Size; ++IndexOff) + { + boot_ata_wait_io(IO); + rt_out16(IO + ATA_REG_DATA, Buf[IndexOff]); + boot_ata_wait_io(IO); + } +} + +/// @check is ATA detected? +Boolean boot_ata_detected(Void) +{ + return kATADetected; +} + +/*** + * + * + * @brief ATA Device class. + * + * + */ + +/** + * @brief ATA Device constructor. + * @param void none. + */ +BootDeviceATA::BootDeviceATA() noexcept +{ + if (boot_ata_init(ATA_PRIMARY_IO, true, this->Leak().mBus, + this->Leak().mMaster) || + boot_ata_init(ATA_SECONDARY_IO, true, this->Leak().mBus, + this->Leak().mMaster)) + { + kATADetected = true; + } +} +/** + * @brief Is ATA detected? + */ +BootDeviceATA::operator bool() +{ + return boot_ata_detected(); +} + +/** + @brief Read Buf from disk + @param Sz Sector size + @param Buf buffer +*/ +BootDeviceATA& BootDeviceATA::Read(CharacterTypeUTF8* Buf, const SizeT& SectorSz) +{ + if (!boot_ata_detected()) + { + Leak().mErr = true; + return *this; + } + + this->Leak().mErr = false; + + if (!Buf || SectorSz < 1) + return *this; + + boot_ata_read(this->Leak().mBase, this->Leak().mBus, this->Leak().mMaster, + Buf, SectorSz, this->Leak().mSize); + + return *this; +} + +/** + @brief Write Buf into disk + @param Sz Sector size + @param Buf buffer +*/ +BootDeviceATA& BootDeviceATA::Write(CharacterTypeUTF8* Buf, const SizeT& SectorSz) +{ + if (!boot_ata_detected()) + { + Leak().mErr = true; + return *this; + } + + Leak().mErr = false; + + if (!Buf || SectorSz < 1) + return *this; + + boot_ata_write(this->Leak().mBase, this->Leak().mBus, this->Leak().mMaster, + Buf, SectorSz, this->Leak().mSize); + + return *this; +} + +/** + * @brief ATA trait getter. + * @return BootDeviceATA::ATATrait& the drive config. + */ +BootDeviceATA::ATATrait& BootDeviceATA::Leak() +{ + return mTrait; +} + +/*** + @brief Getter, gets the number of sectors inside the drive. +*/ +SizeT BootDeviceATA::GetSectorsCount() noexcept +{ + return (kATAData[61] << 16) | kATAData[60]; +} + +SizeT BootDeviceATA::GetDiskSize() noexcept +{ + return this->GetSectorsCount() * BootDeviceATA::kSectorSize; +} diff --git a/dev/BootLoader/src/HEL/AMD64/BootMain.cc b/dev/BootLoader/src/HEL/AMD64/BootMain.cc new file mode 100644 index 00000000..4d0190c0 --- /dev/null +++ b/dev/BootLoader/src/HEL/AMD64/BootMain.cc @@ -0,0 +1,326 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Makes the compiler shut up. +#ifndef kMachineModel +#define kMachineModel "ZkaOS" +#endif // !kMachineModel + +#ifndef kExpectedWidth +#define kExpectedWidth 1920 +#endif + +#ifndef kExpectedHeight +#define kExpectedHeight 1080 +#endif + +/** Graphics related. */ + +STATIC EfiGraphicsOutputProtocol* kGop = nullptr; +STATIC UInt16 kGopStride = 0U; +STATIC EfiGUID kGopGuid; + +EXTERN_C Void rt_reset_hardware(); + +EXTERN EfiBootServices* BS; + +/** + @brief Finds and stores the GOP object. +*/ +STATIC Bool boot_init_fb() noexcept +{ + kGopGuid = EfiGUID(EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID); + kGop = nullptr; + + if (BS->LocateProtocol(&kGopGuid, nullptr, (VoidPtr*)&kGop) != kEfiOk) + return No; + + kGopStride = 4; + + for (SizeT i = 0; i < kGop->Mode->MaxMode; ++i) + { + EfiGraphicsOutputProtocolModeInformation* infoPtr = nullptr; + UInt32 sz = 0U; + + kGop->QueryMode(kGop, i, &sz, &infoPtr); + + if (infoPtr->HorizontalResolution == kExpectedWidth && + infoPtr->VerticalResolution == kExpectedHeight) + { + kGop->SetMode(kGop, i); + return Yes; + } + } + + return No; +} + +EXTERN_C VoidPtr boot_read_cr3(); +EXTERN_C Void boot_write_cr3(VoidPtr new_cr3); + +EXTERN EfiBootServices* BS; + +/// @brief Main EFI entrypoint. +/// @param ImageHandle Handle of this image. +/// @param SystemTable The system table of it. +/// @return nothing, never returns. +EFI_EXTERN_C EFI_API Int32 Main(EfiHandlePtr ImageHandle, + EfiSystemTable* SystemTable) +{ + InitEFI(SystemTable); ///! Init the EFI library. + + HEL::BootInfoHeader* handover_hdr = + new HEL::BootInfoHeader(); + + UInt32 map_key = 0; + UInt32 size_struct_ptr = sizeof(EfiMemoryDescriptor); + EfiMemoryDescriptor* struct_ptr = nullptr; + UInt32 sz_desc = sizeof(EfiMemoryDescriptor); + UInt32 rev_desc = 0; + +#ifdef ZBA_USE_FB + if (!boot_init_fb()) + return 1; ///! Init the GOP. + + for (SizeT index_vt = 0; index_vt < SystemTable->NumberOfTableEntries; + ++index_vt) + { + Char* vendor_table = reinterpret_cast( + SystemTable->ConfigurationTable[index_vt].VendorTable); + + // ACPI's 'RSD PTR', which contains the ACPI SDT (MADT, FACP...) + if (vendor_table[0] == 'R' && vendor_table[1] == 'S' && + vendor_table[2] == 'D' && vendor_table[3] == ' ' && + vendor_table[4] == 'P' && vendor_table[5] == 'T' && + vendor_table[6] == 'R' && vendor_table[7] == ' ') + { + handover_hdr->f_HardwareTables.f_VendorPtr = (VoidPtr)vendor_table; + break; + } + } + + // ------------------------------------------ // + // draw background color. + // ------------------------------------------ // + + handover_hdr->f_GOP.f_The = kGop->Mode->FrameBufferBase; + handover_hdr->f_GOP.f_Width = kGop->Mode->Info->VerticalResolution; + handover_hdr->f_GOP.f_Height = kGop->Mode->Info->HorizontalResolution; + handover_hdr->f_GOP.f_PixelPerLine = kGop->Mode->Info->PixelsPerScanLine; + handover_hdr->f_GOP.f_PixelFormat = kGop->Mode->Info->PixelFormat; + handover_hdr->f_GOP.f_Size = kGop->Mode->FrameBufferSize; +#endif // ZBA_USE_FB + + // ------------------------------------------- // + // Grab MP services, extended to runtime. // + // ------------------------------------------- // + + auto guid_mp = EfiGUID(EFI_MP_SERVICES_PROTOCOL_GUID); + EfiMpServicesProtocol* mp = nullptr; + + BS->LocateProtocol(&guid_mp, nullptr, reinterpret_cast(&mp)); + + handover_hdr->f_HardwareTables.f_MpPtr = reinterpret_cast(mp); + + kHandoverHeader = handover_hdr; + + cg_init(); + + CG::CGDrawBackground(); + + CGDrawBitMapInRegion(zka_disk, ZKA_DISK_HEIGHT, ZKA_DISK_WIDTH, (kHandoverHeader->f_GOP.f_Width - ZKA_DISK_WIDTH) / 2, (kHandoverHeader->f_GOP.f_Height - ZKA_DISK_HEIGHT) / 2); + + cg_fini(); + + UInt32 cnt_enabled = 0; + UInt32 cnt_disabled = 0; + + mp->GetNumberOfProcessors(mp, &cnt_disabled, &cnt_enabled); + + handover_hdr->f_HardwareTables.f_MultiProcessingEnabled = cnt_enabled > 1; + // Fill handover header now. + + Boot::BDiskFormatFactory partition_factory; + + // ---------------------------------------------------- // + // The following checks for an exisiting partition + // inside the disk, if it doesn't have one, + // format the disk. + // ---------------------------------------------------- // + +#ifdef ZKA_AUTO_FORMAT + if (!partition_factory.IsPartitionValid()) + { + CG::CGDrawBackground(); + + CGDrawBitMapInRegion(zka_no_disk, ZKA_NO_DISK_HEIGHT, ZKA_NO_DISK_WIDTH, (kHandoverHeader->f_GOP.f_Width - ZKA_NO_DISK_WIDTH) / 2, (kHandoverHeader->f_GOP.f_Height - ZKA_NO_DISK_HEIGHT) / 2); + + cg_fini(); + + CGDrawString("Formatting EPM disk...", 30, 10, RGB(0xFF, 0xFF, 0xFF)); + + Boot::BDiskFormatFactory::BFileDescriptor root; + + root.fFileName[0] = kNeFSRoot[0]; + root.fFileName[1] = 0; + + root.fKind = kNeFSCatalogKindDir; + + partition_factory.Format("FileSystem (A:)\0", &root, 1); + + CG::CGDrawBackground(); + + CGDrawBitMapInRegion(zka_has_disk, ZKA_HAS_DISK_HEIGHT, ZKA_HAS_DISK_WIDTH, (kHandoverHeader->f_GOP.f_Width - ZKA_HAS_DISK_WIDTH) / 2, (kHandoverHeader->f_GOP.f_Height - ZKA_HAS_DISK_HEIGHT) / 2); + + cg_fini(); + } +#endif // ZKA_AUTO_FORMAT + + BS->GetMemoryMap(&size_struct_ptr, struct_ptr, &map_key, &sz_desc, &rev_desc); + + struct_ptr = new EfiMemoryDescriptor[sz_desc]; + + BS->GetMemoryMap(&size_struct_ptr, struct_ptr, &map_key, &sz_desc, &rev_desc); + + auto kDefaultMemoryMap = 0; // Grab any usable entries. + + //-----------------------------------------------------------// + // A simple loop which finds a usable memory region for us. + //-----------------------------------------------------------// + + SizeT lookup_index = 0UL; + + for (; struct_ptr[lookup_index].Kind != EfiMemoryType::EfiConventionalMemory; ++lookup_index) + { + ZKA_UNUSED(0); + } + + kDefaultMemoryMap = lookup_index; + + //-------------------------------------------------------------// + // Update handover file specific table and phyiscal start field. + //-------------------------------------------------------------// + + handover_hdr->f_BitMapStart = nullptr; /* Start of bitmap. */ + handover_hdr->f_BitMapSize = kHandoverBitMapSz; /* Size of bitmap. */ + + while (BS->AllocatePool(EfiLoaderData, handover_hdr->f_BitMapSize, &handover_hdr->f_BitMapStart) != kEfiOk) + { + if (handover_hdr->f_BitMapStart) + { + BS->FreePool(handover_hdr->f_BitMapStart); + handover_hdr->f_BitMapStart = nullptr; + } + } + + handover_hdr->f_FirmwareCustomTables[0] = (VoidPtr)BS; + handover_hdr->f_FirmwareCustomTables[1] = (VoidPtr)ST; + + Boot::BFileReader reader_syschk(L"syschk.sys", ImageHandle); + reader_syschk.ReadAll(0); + + Boot::BThread* syschk_thread = nullptr; + + // ------------------------------------------ // + // If we succeed in reading the blob, then execute it. + // ------------------------------------------ // + + if (reader_syschk.Blob()) + { + syschk_thread = new Boot::BThread(reader_syschk.Blob()); + syschk_thread->SetName("BootZ: System Check"); + } + + syschk_thread->Start(handover_hdr, NO); + + // nullify these fields, to avoid being reused later. + + handover_hdr->f_FirmwareCustomTables[0] = nullptr; + handover_hdr->f_FirmwareCustomTables[1] = nullptr; + + handover_hdr->f_FirmwareVendorLen = Boot::BStrLen(SystemTable->FirmwareVendor); + + handover_hdr->f_Magic = kHandoverMagic; + handover_hdr->f_Version = kHandoverVersion; + + // Provide fimware vendor name. + + Boot::BCopyMem(handover_hdr->f_FirmwareVendorName, SystemTable->FirmwareVendor, + handover_hdr->f_FirmwareVendorLen); + + handover_hdr->f_FirmwareVendorLen = Boot::BStrLen(SystemTable->FirmwareVendor); + + // Assign to global 'kHandoverHeader'. + + Boot::BFileReader reader_kernel(L"minoskrnl.exe", ImageHandle); + + reader_kernel.ReadAll(0); + + Boot::BThread* kernel_thread = nullptr; + + // ------------------------------------------ // + // If we succeed in reading the blob, then execute it. + // ------------------------------------------ // + + if (reader_kernel.Blob()) + { + kernel_thread = new Boot::BThread(reader_kernel.Blob()); + kernel_thread->SetName("BootZ: ZkaOS Kernel."); + + handover_hdr->f_KernelImage = reader_kernel.Blob(); + } + else + { +#ifdef ZBA_USE_FB + CGDrawString("BootZ: Please recover your kernel image.", 30, 10, RGB(0xFF, 0xFF, 0xFF)); +#endif // ZBA_USE_FB + + EFI::Stop(); + } + + Boot::BFileReader ttf_font(L"zka\\fntkrnl.ttf", ImageHandle); + + ttf_font.ReadAll(0); + + if (ttf_font.Blob()) + { + handover_hdr->f_KernelImage = reader_kernel.Blob(); + handover_hdr->f_KernelSz = reader_kernel.Size(); + handover_hdr->f_FontImage = ttf_font.Blob(); + handover_hdr->f_FontSz = ttf_font.Size(); + } + else + { + cg_init(); + CGDrawBitMapInRegion(zka_no_disk, ZKA_NO_DISK_HEIGHT, ZKA_NO_DISK_WIDTH, (kHandoverHeader->f_GOP.f_Width - ZKA_NO_DISK_WIDTH) / 2, (kHandoverHeader->f_GOP.f_Height - ZKA_NO_DISK_HEIGHT) / 2); + + EFI::Stop(); + } + + EFI::ExitBootServices(map_key, ImageHandle); + + // ---------------------------------------------------- // + // Finally load the OS kernel. + // ---------------------------------------------------- // + + kernel_thread->Start(handover_hdr, YES); + + CANT_REACH(); +} diff --git a/dev/BootLoader/src/HEL/AMD64/BootPlatform.cc b/dev/BootLoader/src/HEL/AMD64/BootPlatform.cc new file mode 100644 index 00000000..83e37a02 --- /dev/null +++ b/dev/BootLoader/src/HEL/AMD64/BootPlatform.cc @@ -0,0 +1,106 @@ + +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include +#include + +#ifdef __STANDALONE__ + +using namespace Boot; + +EXTERN_C void rt_hlt() +{ + asm volatile("hlt"); +} + +EXTERN_C void rt_cli() +{ + asm volatile("cli"); +} + +EXTERN_C void rt_sti() +{ + asm volatile("sti"); +} + +EXTERN_C void rt_cld() +{ + asm volatile("cld"); +} + +EXTERN_C void rt_std() +{ + asm volatile("std"); +} + +EXTERN_C void rt_out8(UInt16 port, UInt8 value) +{ + asm volatile("outb %%al, %1" + : + : "a"(value), "Nd"(port) + : "memory"); +} + +EXTERN_C void rt_out16(UInt16 port, UInt16 value) +{ + asm volatile("outw %%ax, %1" + : + : "a"(value), "Nd"(port) + : "memory"); +} + +EXTERN_C void rt_out32(UInt16 port, UInt32 value) +{ + asm volatile("outl %%eax, %1" + : + : "a"(value), "Nd"(port) + : "memory"); +} + +EXTERN_C UInt8 rt_in8(UInt16 port) +{ + UInt8 value; + asm volatile("inb %1, %%al" + : "=a"(value) + : "Nd"(port) + : "memory"); + + return value; +} + +EXTERN_C UInt16 rt_in16(UInt16 port) +{ + UInt16 value; + asm volatile("inw %%dx, %%ax" + : "=a"(value) + : "d"(port)); + + return value; +} + +EXTERN_C UInt32 rt_in32(UInt16 port) +{ + UInt32 value; + asm volatile("inl %1, %%eax" + : "=a"(value) + : "Nd"(port) + : "memory"); + + return value; +} + +#else + +#include + +void rt_hlt() +{ + Kernel::HAL::rt_halt(); +} + +#endif // __STANDALONE__ diff --git a/dev/BootLoader/src/HEL/AMD64/BootSATA.cc b/dev/BootLoader/src/HEL/AMD64/BootSATA.cc new file mode 100644 index 00000000..5118d865 --- /dev/null +++ b/dev/BootLoader/src/HEL/AMD64/BootSATA.cc @@ -0,0 +1,20 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +/** + * @file BootAHCI.cc + * @author TQ B.V (amlalelmahrouss@icloud.com) + * @brief AHCI support for BootZ. + * @version 0.1 + * @date 2024-02-02 + * + * @copyright Copyright (c) TQ B.V + * + */ + +#include +#include +#include diff --git a/dev/BootLoader/src/HEL/ARM64/.gitkeep b/dev/BootLoader/src/HEL/ARM64/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/dev/BootLoader/src/HEL/ARM64/BootAPI.S b/dev/BootLoader/src/HEL/ARM64/BootAPI.S new file mode 100644 index 00000000..a60ad218 --- /dev/null +++ b/dev/BootLoader/src/HEL/ARM64/BootAPI.S @@ -0,0 +1,12 @@ +.global rt_jump_to_address + +.text + +/** + @brief this function setups a stack and then jumps to + a function */ +rt_jump_to_address: + mov x19, x0 + mov sp, x2 + blr x19 + diff --git a/dev/BootLoader/src/HEL/ARM64/BootMain.cc b/dev/BootLoader/src/HEL/ARM64/BootMain.cc new file mode 100644 index 00000000..7f3ba6cf --- /dev/null +++ b/dev/BootLoader/src/HEL/ARM64/BootMain.cc @@ -0,0 +1,76 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include +#include +#include + +#ifndef kExpectedWidth +#define kExpectedWidth 844 +#endif + +#ifndef kExpectedHeight +#define kExpectedHeight 390 +#endif + +EXTERN EfiBootServices* BS; + +STATIC EfiGraphicsOutputProtocol* kGop = nullptr; +STATIC UInt16 kGopStride = 0U; +STATIC EfiGUID kGopGuid; + +/// @brief Main EFI entrypoint. +/// @param ImageHandle Handle of this image. +/// @param SystemTable The system table of it. +/// @return nothing, never returns. +EFI_EXTERN_C EFI_API Int32 Main(EfiHandlePtr ImageHandle, + EfiSystemTable* SystemTable) +{ + InitEFI(SystemTable); + + kGopGuid = EfiGUID(EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID); + kGop = nullptr; + + BS->LocateProtocol(&kGopGuid, nullptr, (VoidPtr*)&kGop); + + kGopStride = 4; + + Boot::BTextWriter writer; + + for (SizeT i = 0; i < kGop->Mode->MaxMode; ++i) + { + EfiGraphicsOutputProtocolModeInformation* infoPtr = nullptr; + UInt32 sz = 0U; + + kGop->QueryMode(kGop, i, &sz, &infoPtr); + + writer.Write(infoPtr->HorizontalResolution); + writer.Write(infoPtr->VerticalResolution); + writer.Write("\r"); + + if (infoPtr->HorizontalResolution == kExpectedWidth && + infoPtr->VerticalResolution == kExpectedHeight) + { + kGop->SetMode(kGop, i); + break; + } + } + + Boot::BFileReader reader_kernel(L"minoskrnl.exe", ImageHandle); + + reader_kernel.ReadAll(0); + + if (reader_kernel.Blob()) + { + auto kernel_thread = Boot::BThread(reader_kernel.Blob()); + + if (kernel_thread.IsValid()) + kernel_thread.Start(nullptr, YES); + } + + CANT_REACH(); +} diff --git a/dev/BootLoader/src/HEL/ARM64/BootPlatform.cc b/dev/BootLoader/src/HEL/ARM64/BootPlatform.cc new file mode 100644 index 00000000..75a69998 --- /dev/null +++ b/dev/BootLoader/src/HEL/ARM64/BootPlatform.cc @@ -0,0 +1,37 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include +#include + +#ifdef __STANDALONE__ + +using namespace Boot; + +EXTERN_C void rt_hlt() +{ + while (Yes) + ; +} + +EXTERN_C void rt_cli() +{ +} + +EXTERN_C void rt_sti() +{ +} + +EXTERN_C void rt_cld() +{ +} + +EXTERN_C void rt_std() +{ +} + +#endif // __STANDALONE__ diff --git a/dev/BootLoader/src/HEL/POWER/.gitkeep b/dev/BootLoader/src/HEL/POWER/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/dev/BootLoader/src/HEL/POWER/CoreBootStartup.S b/dev/BootLoader/src/HEL/POWER/CoreBootStartup.S new file mode 100644 index 00000000..0948711d --- /dev/null +++ b/dev/BootLoader/src/HEL/POWER/CoreBootStartup.S @@ -0,0 +1,34 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +.section .boot_hdr +.align 4 + +/* BootZ boot header begin */ + +boot_hdr_mag: + .ascii "CB" +boot_hdr_name: + // it has to match ten bytes. + .asciz "zbaosldr\0\0" +boot_hdr_ver: + .word 0x104 +boot_hdr_proc: + .long bootloader_start + +/* BootZ boot 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/dev/BootLoader/src/New+Delete.cc b/dev/BootLoader/src/New+Delete.cc new file mode 100644 index 00000000..b654621e --- /dev/null +++ b/dev/BootLoader/src/New+Delete.cc @@ -0,0 +1,60 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include +#include + +#ifdef __STANDALONE__ +EXTERN EfiBootServices* BS; + +/// @brief Allocates a new object. +/// @param sz the size. +/// @return +void* operator new(size_t sz) +{ + void* buf = nullptr; + + while (BS->AllocatePool(EfiMemoryType::EfiLoaderData, sz, &buf) == kBufferTooSmall) + BS->FreePool(buf); + + return buf; +} + +/// @brief Allocates a new object. +/// @param sz the size. +/// @return +void* operator new[](size_t sz) +{ + void* buf = nullptr; + BS->AllocatePool(EfiMemoryType::EfiLoaderData, sz, &buf); + + return buf; +} + +/// @brief Deletes the object. +/// @param buf the object. +void operator delete(void* buf) +{ + BS->FreePool(buf); +} + +/// @brief Deletes the object. +/// @param buf the object. +void operator delete[](void* buf) +{ + BS->FreePool(buf); +} + +/// @brief Deletes the object (array specific). +/// @param buf the object. +/// @param size it's size. +void operator delete(void* buf, size_t size) +{ + BS->FreePool(buf); +} + +#endif // __STANDALONE__ diff --git a/dev/BootLoader/src/Root/EFI/STARTUP.NSH b/dev/BootLoader/src/Root/EFI/STARTUP.NSH new file mode 100644 index 00000000..d29ba8fd --- /dev/null +++ b/dev/BootLoader/src/Root/EFI/STARTUP.NSH @@ -0,0 +1,2 @@ +fs0: +BOOT\BOOTX64.EFI diff --git a/dev/BootLoader/src/Root/zka/fntkrnl.ttf b/dev/BootLoader/src/Root/zka/fntkrnl.ttf new file mode 100644 index 00000000..e9a6dbb0 Binary files /dev/null and b/dev/BootLoader/src/Root/zka/fntkrnl.ttf differ diff --git a/dev/CompressKit/API.h b/dev/CompressKit/API.h index 47e568db..1040ff6c 100644 --- a/dev/CompressKit/API.h +++ b/dev/CompressKit/API.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024, Theater Quality Inc, all rights reserved. + Copyright (C) 2024, TQ B.V, all rights reserved. ------------------------------------------- */ diff --git a/dev/CompressKit/CKCompress.s b/dev/CompressKit/CKCompress.s index 2f12bf22..62bc26f9 100644 --- a/dev/CompressKit/CKCompress.s +++ b/dev/CompressKit/CKCompress.s @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024 Theater Quality Inc, all rights reserved. + Copyright (C) 2024 TQ B.V, all rights reserved. ------------------------------------------- */ diff --git a/dev/CompressKit/CKDecompress.s b/dev/CompressKit/CKDecompress.s index 2f12bf22..62bc26f9 100644 --- a/dev/CompressKit/CKDecompress.s +++ b/dev/CompressKit/CKDecompress.s @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024 Theater Quality Inc, all rights reserved. + Copyright (C) 2024 TQ B.V, all rights reserved. ------------------------------------------- */ diff --git a/dev/HintKit/CompilerHint.h b/dev/HintKit/CompilerHint.h index 851b143f..0dc4c707 100644 --- a/dev/HintKit/CompilerHint.h +++ b/dev/HintKit/CompilerHint.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024, Theater Quality Inc, all rights reserved. + Copyright (C) 2024, TQ B.V, all rights reserved. ------------------------------------------- */ diff --git a/dev/Kernel/ArchKit/ArchKit.h b/dev/Kernel/ArchKit/ArchKit.h new file mode 100644 index 00000000..296c896f --- /dev/null +++ b/dev/Kernel/ArchKit/ArchKit.h @@ -0,0 +1,90 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include +#include +#include + +#include + +#ifdef __ZKA_AMD64__ +#include +#include +#include +#elif defined(__ZKA_POWER64__) +#include +#elif defined(__ZKA_ARM64__) +#include +#else +#error !!! unknown architecture !!! +#endif + +namespace Kernel +{ + inline SSizeT rt_hash_seed(const Char* seed, int mul) + { + SSizeT hash = 0; + + for (SSizeT idx = 0; seed[idx] != 0; ++idx) + { + hash += seed[idx]; + hash ^= mul; + } + + return hash; + } + + /// @brief write to mapped memory register + /// @param base the base address. + /// @param reg the register. + /// @param value the write to write on it. + inline Void ke_dma_write(UInt32 base, UInt32 reg, UInt32 value) noexcept + { + *(volatile UInt32*)((UInt64)base + reg) = value; + } + + /// @brief read from mapped memory register. + /// @param base base address + /// @param reg the register. + /// @return the value inside the register. + inline UInt32 ke_dma_read(UInt32 base, UInt32 reg) noexcept + { + return *(volatile UInt32*)((UInt64)base + reg); + } + + namespace HAL + { + auto mm_is_bitmap(VoidPtr ptr) -> Bool; + } +} // namespace Kernel + +#define kKernelMaxSystemCalls (256) + +typedef Kernel::Void (*rt_syscall_proc)(Kernel::VoidPtr); + +struct HAL_SYSCALL_RECORD final +{ + Kernel::Int64 fHash; + Kernel::Bool fHooked; + rt_syscall_proc fProc; + + operator bool() + { + return fHooked; + } +}; + +inline Kernel::Array + kSyscalls; + +inline Kernel::Array + kKerncalls; + +EXTERN_C Kernel::HAL::StackFramePtr mp_get_current_context(Kernel::Int64 pid); diff --git a/dev/Kernel/CFKit/GUIDWizard.h b/dev/Kernel/CFKit/GUIDWizard.h new file mode 100644 index 00000000..a9ab57be --- /dev/null +++ b/dev/Kernel/CFKit/GUIDWizard.h @@ -0,0 +1,24 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace CFKit::XRN::Version1 +{ + using namespace Kernel; + + Ref cf_make_sequence(const ArrayList& seq); + ErrorOr> cf_try_guid_to_string(Ref& guid); +} // namespace CFKit::XRN::Version1 diff --git a/dev/Kernel/CFKit/GUIDWrapper.h b/dev/Kernel/CFKit/GUIDWrapper.h new file mode 100644 index 00000000..4e34a9c4 --- /dev/null +++ b/dev/Kernel/CFKit/GUIDWrapper.h @@ -0,0 +1,60 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include +#include +#include + +/* GUID for C++ Components */ + +#define kXRNNil "@{........-....-M...-N...-............}" + +// eXtensible Resource Information +namespace CFKit::XRN +{ + using namespace Kernel; + + union GUIDSequence { + alignas(8) UShort u8[16]; + alignas(8) UShort u16[8]; + alignas(8) UInt u32[4]; + alignas(8) ULong u64[2]; + + struct + { + alignas(8) UInt fMs1; + UShort fMs2; + UShort fMs3; + UChar fMs4[8]; + }; + }; + + class GUID final + { + public: + explicit GUID() = default; + ~GUID() = default; + + public: + GUID& operator=(const GUID&) = default; + GUID(const GUID&) = default; + + public: + GUIDSequence& operator->() noexcept + { + return fUUID; + } + GUIDSequence& Leak() noexcept + { + return fUUID; + } + + private: + GUIDSequence fUUID; + }; +} // namespace CFKit::XRN diff --git a/dev/Kernel/CFKit/Property.h b/dev/Kernel/CFKit/Property.h new file mode 100644 index 00000000..b7b22536 --- /dev/null +++ b/dev/Kernel/CFKit/Property.h @@ -0,0 +1,54 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#ifndef CFKIT_PROPS_H +#define CFKIT_PROPS_H + +#include +#include +#include +#include + +#define kMaxPropLen 255 + +namespace CFKit +{ + using namespace Kernel; + + /// @brief handle to anything (number, ptr, string...) + using PropertyId = UIntPtr; + + /// @brief Kernel property class. + /// @example \Properties\SmpCores or \Properties\KernelVersion + class Property + { + public: + Property(); + virtual ~Property(); + + public: + Property& operator=(const Property&) = default; + Property(const Property&) = default; + + bool StringEquals(KString& name); + PropertyId& GetValue(); + KString& GetKey(); + + private: + KString fName{kMaxPropLen}; + PropertyId fValue{0UL}; + }; + + template + using PropertyArray = Array; +} // namespace CFKit + +namespace Kernel +{ + using namespace CFKit; +} + +#endif // !CFKIT_PROPS_H diff --git a/dev/Kernel/CFKit/Utils.h b/dev/Kernel/CFKit/Utils.h new file mode 100644 index 00000000..370eca45 --- /dev/null +++ b/dev/Kernel/CFKit/Utils.h @@ -0,0 +1,55 @@ +#ifndef CFKIT_UTILS_H +#define CFKIT_UTILS_H + +#include +#include + +namespace CFKit +{ + using namespace Kernel; + + /// @brief Finds the PE header inside the blob. + inline auto ldr_find_exec_header(DosHeaderPtr ptrDos) -> LDR_EXEC_HEADER_PTR + { + if (!ptrDos) + return nullptr; + + if (ptrDos->eMagic[0] != kMagMz0) + return nullptr; + + if (ptrDos->eMagic[1] != kMagMz1) + return nullptr; + + return (LDR_EXEC_HEADER_PTR)(VoidPtr)(&ptrDos->eLfanew + 1); + } + + /// @brief Finds the PE optional header inside the blob. + inline auto ldr_find_opt_exec_header(DosHeaderPtr ptrDos) -> LDR_OPTIONAL_HEADER_PTR + { + if (!ptrDos) + return nullptr; + + auto exec = ldr_find_exec_header(ptrDos); + + if (!exec) + return nullptr; + + return (LDR_OPTIONAL_HEADER_PTR)(VoidPtr)(&exec->mCharacteristics + 1); + } + + /// @brief Finds the PE header inside the blob. + /// @note overloaded function. + inline auto ldr_find_exec_header(const Char* ptrDos) -> LDR_EXEC_HEADER_PTR + { + return ldr_find_exec_header((DosHeaderPtr)ptrDos); + } + + /// @brief Finds the PE header inside the blob. + /// @note overloaded function. + inline auto ldr_find_opt_exec_header(const Char* ptrDos) -> LDR_OPTIONAL_HEADER_PTR + { + return ldr_find_opt_exec_header((DosHeaderPtr)ptrDos); + } +} // namespace CFKit + +#endif // ifndef CFKIT_UTILS_H diff --git a/dev/Kernel/CompilerKit/CompilerKit.h b/dev/Kernel/CompilerKit/CompilerKit.h new file mode 100644 index 00000000..843652e4 --- /dev/null +++ b/dev/Kernel/CompilerKit/CompilerKit.h @@ -0,0 +1,13 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#ifndef _INC_CL_H +#define _INC_CL_H + +#include +#include + +#endif /* ifndef _INC_CL_H */ diff --git a/dev/Kernel/CompilerKit/Detail.h b/dev/Kernel/CompilerKit/Detail.h new file mode 100644 index 00000000..08d40304 --- /dev/null +++ b/dev/Kernel/CompilerKit/Detail.h @@ -0,0 +1,27 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#ifdef __MINOSKRNL__ +#include +#endif // ifdef __MINOSKRNL__ + +#define ZKA_COPY_DELETE(KLASS) \ + KLASS& operator=(const KLASS&) = delete; \ + KLASS(const KLASS&) = delete; + +#define ZKA_COPY_DEFAULT(KLASS) \ + KLASS& operator=(const KLASS&) = default; \ + KLASS(const KLASS&) = default; + +#define ZKA_MOVE_DELETE(KLASS) \ + KLASS& operator=(KLASS&&) = delete; \ + KLASS(KLASS&&) = delete; + +#define ZKA_MOVE_DEFAULT(KLASS) \ + KLASS& operator=(KLASS&&) = default; \ + KLASS(KLASS&&) = default; diff --git a/dev/Kernel/CompilerKit/Version.h b/dev/Kernel/CompilerKit/Version.h new file mode 100644 index 00000000..b8c7f1a9 --- /dev/null +++ b/dev/Kernel/CompilerKit/Version.h @@ -0,0 +1,7 @@ +// (c) TQ B.V + +#pragma once + +/// .. +#define BOOTLOADER_VERSION "1104.2024.110" +#define KERNEL_VERSION "1104.2024.110" diff --git a/dev/Kernel/FSKit/Defines.h b/dev/Kernel/FSKit/Defines.h new file mode 100644 index 00000000..9176e3dd --- /dev/null +++ b/dev/Kernel/FSKit/Defines.h @@ -0,0 +1,12 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include + +#define FSKIT_VERSION "1.0.0" +#define FSKIT_VERSION_BCD 0x0100 diff --git a/dev/Kernel/FSKit/HPFS.h b/dev/Kernel/FSKit/HPFS.h new file mode 100644 index 00000000..f6aec5be --- /dev/null +++ b/dev/Kernel/FSKit/HPFS.h @@ -0,0 +1,30 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include + +/// @file HPFS.h +/// @brief HPFS filesystem support. + +#define kHPFSVersion 0x0100 +#define kHPFSMagic " HPFS" +#define kHPFSMagicLen 8 + +#define kHPFSMinimumDiskSize (gib_cast(64)) + +enum +{ + kHPFSInvalidDrive, + kHPFSHDDDrive, + kHPFSSSDDrive, + kHPFSMassStorageDrive, + kHPFSSCSIDrive, + kHPFSDriveCount, +}; + +struct HPFS_EXPLICIT_BOOT_SECTOR; diff --git a/dev/Kernel/FSKit/IndexableProperty.h b/dev/Kernel/FSKit/IndexableProperty.h new file mode 100644 index 00000000..412a1205 --- /dev/null +++ b/dev/Kernel/FSKit/IndexableProperty.h @@ -0,0 +1,63 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include +#include +#include + +#define kIndexerNodeNameLength 255 +#define kIndexerClaimed 0xCF + +namespace Kernel +{ + namespace Indexer + { + struct IndexProperty final + { + public: + Char Drive[kDriveNameLen]; + Char Path[kIndexerNodeNameLength]; + }; + + class IndexableProperty final : public Property + { + public: + explicit IndexableProperty() + : Property() + { + Kernel::KString strProp(kMaxPropLen); + strProp += "/Properties/Indexable"; + + this->GetKey() = strProp; + } + + ~IndexableProperty() override = default; + + ZKA_COPY_DEFAULT(IndexableProperty); + + public: + IndexProperty& Leak() noexcept; + + public: + void AddFlag(Int16 flag); + void RemoveFlag(Int16 flag); + Int16 HasFlag(Int16 flag); + + private: + IndexProperty fIndex; + UInt32 fFlags; + }; + + /// @brief Index a file into the indexer instance. + /// @param filename path + /// @param filenameLen used bytes in path. + /// @param indexer the filesystem indexer. + /// @return none. + Void fs_index_file(const Char* filename, SizeT filenameLen, IndexableProperty& indexer); + } // namespace Indexer +} // namespace Kernel diff --git a/dev/Kernel/FSKit/NeFS.h b/dev/Kernel/FSKit/NeFS.h new file mode 100644 index 00000000..42857df9 --- /dev/null +++ b/dev/Kernel/FSKit/NeFS.h @@ -0,0 +1,402 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + + FILE: NeFS.h + PURPOSE: NeFS (New FileSystem) support. + + Revision History: + + ?/?/?: Added file (amlel) + 12/02/24: Add UUID macro for EPM and GPT partition schemes. + 3/16/24: Add mandatory sector size, kNeFSSectorSz is set to 2048 by +default. + +------------------------------------------- */ + +#pragma once + +#include +#include +#include +#include + +/** + @brief New File System specification. + @author TQ B.V (TQ B.V, amlalelmahrouss at icloud dot com) +*/ + +#define kNeFSInvalidFork (-1) +#define kNeFSInvalidCatalog (-1) +#define kNeFSNodeNameLen (256) + +#define kNeFSMinimumDiskSize (gib_cast(4)) + +#define kNeFSSectorSz (512) +#define kNeFSForkDataSz (mib_cast(16)) + +#define kNeFSIdentLen (8) +#define kNeFSIdent " NeFS" +#define kNeFSPadLen (392) + +#define kNeFSMetaFilePrefix '$' + +#define kNeFSVersionInteger (0x0129) +#define kNeFSVerionString "1.2.9" + +/// @brief Standard fork types. +#define kNeFSDataFork "main_data" +#define kNeFSResourceFork "main_rsrc" + +#define kNeFSForkSize (sizeof(NFS_FORK_STRUCT)) + +#define kNeFSPartitionTypeStandard (7) +#define kNeFSPartitionTypePage (8) +#define kNeFSPartitionTypeBoot (9) + +#define kNeFSCatalogKindFile (1) +#define kNeFSCatalogKindDir (2) +#define kNeFSCatalogKindAlias (3) + +//! Shared between network and/or partitions. Export forks as .zip when copying. +#define kNeFSCatalogKindShared (4) + +#define kNeFSCatalogKindResource (5) +#define kNeFSCatalogKindExecutable (6) + +#define kNeFSCatalogKindPage (8) + +#define kNeFSCatalogKindDevice (9) +#define kNeFSCatalogKindLock (10) + +#define kNeFSCatalogKindRLE (11) +#define kNeFSCatalogKindMetaFile (12) + +#define kNeFSCatalogKindTTF (13) +#define kNeFSCatalogKindRIFF (14) +#define kNeFSCatalogKindMPEG (15) +#define kNeFSCatalogKindDVX (16) + +#define kNeFSSeparator '/' +#define kNeFSSeparatorAlt '/' + +#define kNeFSUpDir ".." +#define kNeFSRoot "/" +#define kNeFSRootAlt "/" + +#define kNeFSLF '\r' +#define kNeFSEOF (-1) + +#define kNeFSBitWidth (sizeof(Kernel::Char)) +#define kNeFSLbaType (Kernel::Lba) + +/// @note Start after the partition map header. (Virtual addressing) +#define kNeFSRootCatalogStartAddress (1024) +#define kNeFSCatalogStartAddress ((2048) + sizeof(NFS_ROOT_PARTITION_BLOCK)) + +#define kResourceTypeDialog (10) +#define kResourceTypeString (11) +#define kResourceTypeMenu (12) +#define kResourceTypeSound (13) +#define kResourceTypeFont (14) + +#define kConfigLen (64) +#define kPartLen (32) + +#define kNeFSFlagDeleted (70) +#define kNeFSFlagUnallocated (0) +#define kNeFSFlagCreated (71) + +#define kNeFSMimeNameLen (200) +#define kNeFSForkNameLen (200) + +#define kNeFSFrameworkExt ".fwrk" +#define kNeFSApplicationExt ".app" +#define kNeFSJournalExt ".jrnl" + +struct NFS_CATALOG_STRUCT; +struct NFS_FORK_STRUCT; +struct NFS_ROOT_PARTITION_BLOCK; + +enum +{ + kNeFSHardDrive = 0xC0, // Hard Drive + kNeFSSolidStateDrive = 0xC1, // Solid State Drive + kNeFSOpticalDrive = 0x0C, // Blu-Ray/DVD + kNeFSMassStorageDevice = 0xCC, // USB + kNeFSScsiDrive = 0xC4, // SCSI Hard Drive + kNeFSFlashDrive = 0xC6, + kNeFSUnknown = 0xFF, // Unknown device. + kNeFSDriveCount = 7, +}; + +/// @brief Catalog type. +struct PACKED NFS_CATALOG_STRUCT final +{ + Kernel::Char Name[kNeFSNodeNameLen]; + Kernel::Char Mime[kNeFSMimeNameLen]; + + /// Catalog status flag. + Kernel::UInt16 Flags; + /// Custom catalog flags. + Kernel::UInt16 FilkMMFlags; + /// Catalog kind. + Kernel::Int32 Kind; + + /// Size of the data fork. + Kernel::Lba DataForkSize; + + /// Size of all resource forks. + Kernel::Lba ResourceForkSize; + + Kernel::Lba DataFork; + Kernel::Lba ResourceFork; + + Kernel::Lba NextSibling; + Kernel::Lba PrevSibling; +}; + +/// @brief Fork type, contains a data page. +/// @note The way we store is way different than how other filesystems do, specific chunk of code are +/// written into either the data fork or resource fork, the resource fork is reserved for file metadata. +/// whereas the data fork is reserved for file data. +struct PACKED NFS_FORK_STRUCT final +{ + Kernel::Char ForkName[kNeFSForkNameLen]; + Kernel::Char CatalogName[kNeFSNodeNameLen]; + + Kernel::Int32 Flags; + Kernel::Int32 Kind; + + Kernel::Int64 ResourceId; + Kernel::Int32 ResourceKind; + Kernel::Int32 ResourckMMFlags; + + Kernel::Lba DataOffset; // 8 Where to look for this data? + Kernel::SizeT DataSize; /// Data size according using sector count. + + Kernel::Lba NextSibling; + Kernel::Lba PreviousSibling; +}; + +/// @brief Partition block type +struct PACKED NFS_ROOT_PARTITION_BLOCK final +{ + Kernel::Char Ident[kNeFSIdentLen]; + Kernel::Char PartitionName[kPartLen]; + + Kernel::Int32 Flags; + Kernel::Int32 Kind; + + Kernel::Lba StartCatalog; + Kernel::SizeT CatalogCount; + + Kernel::SizeT DiskSize; + + Kernel::SizeT FreeCatalog; + Kernel::SizeT FreeSectors; + + Kernel::SizeT SectorCount; + Kernel::SizeT SectorSize; + + Kernel::UInt64 Version; + + Kernel::Lba EpmBlock; + + Kernel::Char Pad[kNeFSPadLen]; +}; + +namespace Kernel +{ + class NeFileSystemParser; + class NeFileSystemJournal; + class NeFileSystemHelper; + + enum + { + kNeFSSubDriveA, + kNeFSSubDriveB, + kNeFSSubDriveC, + kNeFSSubDriveD, + kNeFSSubDriveInvalid, + kNeFSSubDriveCount, + }; + + /// \brief Resource fork kind. + enum + { + kNeFSRsrcForkKind = 0, + kNeFSDataForkKind = 1 + }; + + /// + /// \name NeFileSystemParser + /// \brief NeFS parser class. (catalog creation, remove removal, root, + /// forks...) Designed like the DOM, detects the filesystem automatically. + /// + class NeFileSystemParser final + { + public: + explicit NeFileSystemParser() = default; + ~NeFileSystemParser() = default; + + public: + ZKA_COPY_DEFAULT(NeFileSystemParser); + + public: + /// @brief Creates a new fork inside the New filesystem partition. + /// @param catalog it's catalog + /// @param theFork the fork itself. + /// @return the fork + _Output NFS_FORK_STRUCT* CreateFork(_Input NFS_CATALOG_STRUCT* catalog, + _Input NFS_FORK_STRUCT& theFork); + + /// @brief Find fork inside New filesystem. + /// @param catalog the catalog. + /// @param name the fork name. + /// @return the fork. + _Output NFS_FORK_STRUCT* FindFork(_Input NFS_CATALOG_STRUCT* catalog, + _Input const Char* name, + Boolean dataOrRsrc); + + _Output Void RemoveFork(_Input NFS_FORK_STRUCT* fork); + + _Output Void CloseFork(_Input NFS_FORK_STRUCT* fork); + + _Output NFS_CATALOG_STRUCT* FindCatalog(_Input const Char* catalogName, Lba& outLba); + + _Output NFS_CATALOG_STRUCT* GetCatalog(_Input const Char* name); + + _Output NFS_CATALOG_STRUCT* CreateCatalog(_Input const Char* name, + _Input const Int32& flags, + _Input const Int32& kind); + + _Output NFS_CATALOG_STRUCT* CreateCatalog(_Input const Char* name); + + Bool WriteCatalog(_Input _Output NFS_CATALOG_STRUCT* catalog, + _Input Bool isRsrcFork, + _Input VoidPtr data, + _Input SizeT sizeOfData, + _Input const Char* forkName); + + VoidPtr ReadCatalog(_Input _Output NFS_CATALOG_STRUCT* catalog, + _Input Bool isRsrcFork, + _Input SizeT dataSz, + _Input const Char* forkName); + + bool Seek(_Input _Output NFS_CATALOG_STRUCT* catalog, SizeT off); + + SizeT Tell(_Input _Output NFS_CATALOG_STRUCT* catalog); + + bool RemoveCatalog(_Input const Char* catalog); + + bool CloseCatalog(_InOut NFS_CATALOG_STRUCT* catalog); + + /// @brief Make a EPM+NeFS drive out of the disk. + /// @param drive The drive to write on. + /// @return If it was sucessful, see err_local_get(). + bool Format(_Input _Output DriveTrait* drive, _Input const Lba endLba, _Input const Int32 flags, const Char* part_name); + + public: + Int32 mDriveIndex{kNeFSSubDriveA}; + }; + + /// + /// \name NeFileSystemHelper + /// \brief Filesystem helper and utils. + /// + + class NeFileSystemHelper final + { + public: + STATIC const Char* Root(); + STATIC const Char* UpDir(); + STATIC const Char Separator(); + STATIC const Char MetaFile(); + }; + + /// @brief Journal class for NeFS. + class NeFileSystemJournal final + { + public: + explicit NeFileSystemJournal(const char* stamp) + { + if (!stamp) + { + kcout << "Invalid: Journal Stamp, using default name.\r"; + return; + } + + kcout << "Info: Journal stamp: " << stamp << endl; + rt_copy_memory((VoidPtr)stamp, this->mStamp, rt_string_len(stamp)); + } + + ~NeFileSystemJournal() = default; + + ZKA_COPY_DEFAULT(NeFileSystemJournal); + + Bool CreateJournal(NeFileSystemParser* parser) + { + if (!parser) + return NO; + + auto node = parser->CreateCatalog(mStamp); + + if (!node) + return NO; + + delete node; + node = nullptr; + + return YES; + } + + Bool IsJournalValid(NeFileSystemParser* parser) + { + if (!parser) + return NO; + + if (auto node = parser->GetCatalog(mStamp); + node) + { + delete node; + node = nullptr; + + return YES; + } + + return NO; + } + + Void Commit() {} + + Void Start() {} + + private: + Char mStamp[255] = { "/System/FileSystemStamp.jrnl" }; + + }; + + namespace Detail + { + Boolean fs_init_newfs(Void) noexcept; + } // namespace Detail +} // namespace Kernel + +/// @brief Write to newfs disk. +/// @param drv_mnt mounted interface. +/// @param drv_trait drive info +/// @param drv_indx drive index. +/// @return status code. +Kernel::Int32 fs_newfs_write(Kernel::MountpointInterface* drv_mnt, + Kernel::DriveTrait& drv_trait, + Kernel::Int32 drv_indx); + +/// @brief Read from newfs disk. +/// @param drv_mnt mounted interface. +/// @param drv_trait drive info +/// @param drv_indx drive index. +/// @return status code. +Kernel::Int32 fs_newfs_read(Kernel::MountpointInterface* drv_mnt, + Kernel::DriveTrait& drv_trait, + Kernel::Int32 drv_indx); diff --git a/dev/Kernel/FirmwareKit/.gitkeep b/dev/Kernel/FirmwareKit/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/dev/Kernel/FirmwareKit/CoreBoot/CoreBoot.h b/dev/Kernel/FirmwareKit/CoreBoot/CoreBoot.h new file mode 100644 index 00000000..eda3a396 --- /dev/null +++ b/dev/Kernel/FirmwareKit/CoreBoot/CoreBoot.h @@ -0,0 +1,31 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include + +namespace Firmware::Detail::CoreBoot +{ + using namespace Kernel; + + struct LEHeader; + + /// @brief Linear Executable Header + /// @author TQ B.V + struct ATTRIBUTE(aligned(4)) LEHeader + { + const Char fMagic[2]; // magic number + const Char fName[10]; // operating system name + const UInt32 fRevision; // firmware revision + const UInt32 fStartAddress; // start address (master/slave(s) thread) + +#ifdef ZKA_IS_EXTENDED_COREBOOT + const UIntPtr fMasterStructure; // master structure for MP/PM and device tree and such (ARM) + const UIntPtr fMasterStructureVersion; // master structure version. +#endif + }; +} // namespace Firmware::Detail::CoreBoot diff --git a/dev/Kernel/FirmwareKit/CoreBoot/NetBoot.h b/dev/Kernel/FirmwareKit/CoreBoot/NetBoot.h new file mode 100644 index 00000000..6fbe0993 --- /dev/null +++ b/dev/Kernel/FirmwareKit/CoreBoot/NetBoot.h @@ -0,0 +1,9 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include diff --git a/dev/Kernel/FirmwareKit/EFI.h b/dev/Kernel/FirmwareKit/EFI.h new file mode 100644 index 00000000..044c28e9 --- /dev/null +++ b/dev/Kernel/FirmwareKit/EFI.h @@ -0,0 +1,11 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include + +/// @note this header is used to reference the EFI/EFI.h diff --git a/dev/Kernel/FirmwareKit/EFI/API.h b/dev/Kernel/FirmwareKit/EFI/API.h new file mode 100644 index 00000000..096a3157 --- /dev/null +++ b/dev/Kernel/FirmwareKit/EFI/API.h @@ -0,0 +1,114 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#ifndef __EFI_API__ +#define __EFI_API__ + +#include +#include +#include +#include + +#define kZKASubsystem 17 + +#ifdef __ZBAOSLDR__ +// forward decl. +class BTextWriter; + +#define __BOOTKIT_NO_INCLUDE__ 1 + +#include +#include +#endif // ifdef __ZBAOSLDR__ + +inline EfiSystemTable* ST = nullptr; +inline EfiBootServices* BS = nullptr; + +EXTERN_C void rt_cli(); +EXTERN_C void rt_hlt(); + +namespace EFI +{ + /// @brief Halt and clear interrupts. + /// @return + inline Void Stop() noexcept + { + while (1) + { + rt_hlt(); + rt_cli(); + } + } + + /** +@brief Exit EFI API to let the OS load correctly. +Bascially frees everything we have in the EFI side. +*/ + inline void ExitBootServices(UInt64 MapKey, EfiHandlePtr ImageHandle) noexcept + { + if (!ST) + return; + + ST->BootServices->ExitBootServices(ImageHandle, MapKey); + } + + enum + { + kPartEPM, + kPartGPT, + kPartMBR, + kPartCnt, + }; + + inline UInt32 Platform() noexcept + { + return kPeMachineAMD64; + } + + /*** + * @brief Throw an error, stop execution as well. + * @param ErrorCode error code to be print. + * @param Reason reason to be print. + */ + inline void ThrowError(const EfiCharType* ErrorCode, + const EfiCharType* Reason) noexcept + { + ST->ConOut->OutputString(ST->ConOut, L"\r*** STOP ***\r"); + + ST->ConOut->OutputString(ST->ConOut, L"*** Error: "); + ST->ConOut->OutputString(ST->ConOut, ErrorCode); + + ST->ConOut->OutputString(ST->ConOut, L", Reason: "); + ST->ConOut->OutputString(ST->ConOut, Reason); + + ST->ConOut->OutputString(ST->ConOut, L" ***\r"); + + EFI::Stop(); + } +} // namespace EFI + +inline void InitEFI(EfiSystemTable* SystemTable) noexcept +{ + if (!SystemTable) + return; + + ST = SystemTable; + BS = ST->BootServices; + + ST->ConOut->ClearScreen(SystemTable->ConOut); + ST->ConOut->SetAttribute(SystemTable->ConOut, kEFIYellow); + + ST->BootServices->SetWatchdogTimer(0, 0, 0, nullptr); + ST->ConOut->EnableCursor(ST->ConOut, false); +} + +#ifdef __ZBAOSLDR__ + +#include + +#endif // ifdef __ZBAOSLDR__ + +#endif /* ifndef __EFI_API__ */ diff --git a/dev/Kernel/FirmwareKit/EFI/EFI.h b/dev/Kernel/FirmwareKit/EFI/EFI.h new file mode 100644 index 00000000..4e8a4af4 --- /dev/null +++ b/dev/Kernel/FirmwareKit/EFI/EFI.h @@ -0,0 +1,884 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#ifndef FIRMWARE_KIT_EFI_H +#define FIRMWARE_KIT_EFI_H + +/** +@brief Implementation of the main EFI protocols. +*/ + +#include + +using namespace Kernel; + +/* we always use stdcall in EFI, the pascal way of calling functions. */ + +#ifndef EPI_API +#define EFI_API __attribute__((ms_abi)) +#endif // ifndef EPI_API + +#define IN +#define OUT +#define OPTIONAL + +#define EFI_FINAL final + +// Forward decls + +struct EfiTableHeader; +struct EfiLoadFileProtocol; +struct EfiSimpleTextOutputProtocol; +struct EfiDevicePathProtocol; +struct EfiBootServices; +struct EfiMemoryDescriptor; +struct EfiSystemTable; +struct EfiGUID; +struct EfiFileDevicePathProtocol; +struct EfiHandle; +struct EfiGraphicsOutputProtocol; +struct EfiBitmask; +struct EfiFileProtocol; + +typedef UInt64 EfiStatusType; + +/// @brief Core Handle Kind +/// Self is like NT's Win32 HANDLE type. +typedef struct EfiHandle +{ +} * EfiHandlePtr; + +/* UEFI uses wide characters by default. */ +typedef WideChar EfiCharType; + +typedef UInt64 EfiPhysicalAddress; +typedef UIntPtr EfiVirtualAddress; + +/// What's BootBolicy? +/// If TRUE, indicates that the request originates from the boot manager, and +/// that the boot manager is attempting to load FilePath as a boot selection. If +/// FALSE, then FilePath must match an exact file to be loaded. + +typedef UInt64(EFI_API* EfiTextString)(struct EfiSimpleTextOutputProtocol* Self, + const WideChar* OutputString); + +typedef UInt64(EFI_API* EfiTextAttrib)(struct EfiSimpleTextOutputProtocol* Self, + const WideChar Attribute); + +typedef UInt64(EFI_API* EfiTextClear)(struct EfiSimpleTextOutputProtocol* Self); + +typedef UInt64(EFI_API* EfiLoadFile)(EfiLoadFileProtocol* Self, + EfiFileDevicePathProtocol* FilePath, + Boolean BootPolicy, + UInt32* BufferSize, + VoidPtr Buffer); + +typedef UInt64(EFI_API* EfiCopyMem)(VoidPtr DstBuf, VoidPtr SrcBuf, SizeT Length); + +typedef UInt64(EFI_API* EfiSetMem)(VoidPtr DstBuf, Char Byte, SizeT Length); + +typedef UInt64(EFI_API* EfiHandleProtocol)(EfiHandlePtr Handle, EfiGUID* Guid, VoidPtr* Device); + +typedef UInt64(EFI_API* EfiLocateDevicePath)(EfiGUID* Protocol, + EfiDevicePathProtocol** DevicePath, + EfiHandlePtr Device); + +typedef UInt64(EFI_API* EfiStartImage)(EfiHandlePtr Handle, VoidPtr ArgsSize, VoidPtr ArgsPtr); + +typedef UInt64(EFI_API* EfiLoadImage)(Boolean BootPolicy, + EfiHandlePtr ParentHandle, + EfiFileDevicePathProtocol* DeviceFile, + VoidPtr buffer, + SizeT size, + EfiHandlePtr* ppHandle); + +/// EFI pool helpers, taken from iPXE. + +typedef enum EfiMemoryType +{ + /// + /// Not used. + /// + EfiReservedMemoryType, + /// + /// The code portions of a loaded application. + /// (Note that UEFI OS loaders are UEFI applications.) + /// + EfiLoaderCode, + /// + /// The data portions of a loaded application and the default data allocation + /// type used by an application to allocate pool memory. + /// + EfiLoaderData, + /// + /// The code portions of a loaded Boot Services Driver. + /// + EfiBootServicesCode, + /// + /// The data portions of a loaded Boot Serves Driver, and the default data + /// allocation type used by a Boot Services Driver to allocate pool memory. + /// + EfiBootServicesData, + /// + /// The code portions of a loaded Runtime Services Driver. + /// + EfiRuntimeServicesCode, + /// + /// The data portions of a loaded Runtime Services Driver and the default + /// data allocation type used by a Runtime Services Driver to allocate pool + /// memory. + /// + EfiRuntimeServicesData, + /// + /// Free (unallocated) memory. + /// + EfiConventionalMemory, + /// + /// Memory in which errors have been detected. + /// + EfiUnusableMemory, + /// + /// Memory that holds the ACPI tables. + /// + EfiACPIReclaimMemory, + /// + /// Address space reserved for use by the firmware. + /// + EfiACPIMemoryNVS, + /// + /// Used by system firmware to request that a memory-mapped IO region + /// be mapped by the OS to a virtual address so it can be accessed by EFI + /// runtime services. + /// + EfiMemoryMappedIO, + /// + /// System memory-mapped IO region that is used to translate memory + /// cycles to IO cycles by the processor. + /// + EfiMemoryMappedIOPortSpace, + /// + /// Address space reserved by the firmware for code that is part of the + /// processor. + /// + EfiPalCode, + /// + /// A memory region that operates as EfiConventionalMemory, + /// however it happens to also support byte-addressable non-volatility. + /// + EfiPersistentMemory, + /// + /// A memory region that describes system memory that has not been accepted + /// by a corresponding call to the underlying isolation architecture. + /// + EfiUnacceptedMemoryType, + /// + /// The last type of memory. + /// Not a real type. + /// + EfiMaxMemoryType, +} EfiMemoryType; + +typedef enum EfiAllocateType +{ + /// Anything that satisfy the request. + AllocateAnyPages, + AllocateMaxAddress, + /// + /// Allocate pages at a specified address. + /// + AllocateAddress, + /// + /// Maximum enumeration value that may be used for bounds checking. + /// + MaxAllocateType +} EfiAllocateType; + +typedef struct EfiMemoryDescriptor +{ + /// + /// Kind of the memory region. + /// Kind EFI_MEMORY_TYPE is defined in the + /// AllocatePages() function description. + /// + UInt32 Kind; + /// + /// Physical address of the first byte in the memory region. PhysicalStart + /// must be aligned on a 4 KiB boundary, and must not be above + /// 0xfffffffffffff000. Kind EFI_PHYSICAL_ADDRESS is defined in the + /// AllocatePages() function description + /// + EfiPhysicalAddress PhysicalStart; + /// + /// Virtual address of the first byte in the memory region. + /// VirtualStart must be aligned on a 4 KiB boundary, + /// and must not be above 0xfffffffffffff000. + /// + EfiVirtualAddress VirtualStart; + /// + /// NumberOfPagesNumber of 4 KiB pages in the memory region. + /// NumberOfPages must not be 0, and must not be any value + /// that would represent a memory page with a start address, + /// either physical or virtual, above 0xfffffffffffff000. + /// + UInt64 NumberOfPages; + /// + /// Attributes of the memory region that describe the bit mask of capabilities + /// for that memory region, and not necessarily the current settings for that + /// memory region. + /// + UInt64 Attribute; +} EfiMemoryDescriptor; + +typedef UInt64(EFI_API* EfiAllocatePool)(EfiMemoryType PoolType, UInt32 Size, VoidPtr* Buffer); + +typedef UInt64(EFI_API* EfiFreePool)(VoidPtr Buffer); + +typedef UInt64(EFI_API* EfiCalculateCrc32)(VoidPtr Data, UInt32 DataSize, UInt32* CrcOut); + +/** +@brief Present in every header, used to identify a UEFI structure. +*/ +typedef struct EfiTableHeader +{ + UInt64 Signature; + UInt32 Revision; + UInt32 HeaderSize; + UInt32 Crc32; + UInt32 Reserved; +} EfiTableHeader; + +#define EFI_ACPI_TABLE_PROTOCOL_GUID \ + { \ + 0xffe06bdd, 0x6107, 0x46a6, \ + { \ + 0x7b, 0xb2, 0x5a, 0x9c, 0x7e, 0xc5, 0x27, 0x5c \ + } \ + } + +#define EFI_LOAD_FILE_PROTOCOL_GUID \ + { \ + 0x56EC3091, 0x954C, 0x11d2, \ + { \ + 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b \ + } \ + } + +#define EFI_LOAD_FILE2_PROTOCOL_GUID \ + { \ + 0x4006c0c1, 0xfcb3, 0x403e, \ + { \ + 0x99, 0x6d, 0x4a, 0x6c, 0x87, 0x24, 0xe0, 0x6d \ + } \ + } + +#define EFI_LOADED_IMAGE_PROTOCOL_GUID \ + { \ + 0x5B1B31A1, 0x9562, 0x11d2, \ + { \ + 0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B \ + } \ + } + +#define EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID \ + { \ + 0x9042a9de, 0x23dc, 0x4a38, \ + { \ + 0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a \ + } \ + } + +#define EFI_LOADED_IMAGE_PROTOCOL_REVISION 0x1000 + +#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID \ + { \ + 0x0964e5b22, 0x6459, 0x11d2, \ + { \ + 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b \ + } \ + } + +#define EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL_GUID \ + { \ + 0xbc62157e, 0x3e33, 0x4fec, \ + { \ + 0x99, 0x20, 0x2d, 0x3b, 0x36, 0xd7, 0x50, 0xdf \ + } \ + } + +#define EFI_DEVICE_PATH_PROTOCOL_GUID \ + { \ + 0x9576e91, 0x6d3f, 0x11d2, \ + { \ + 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b \ + } \ + } + +#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID \ + { \ + 0x0964e5b22, 0x6459, 0x11d2, \ + { \ + 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b \ + } \ + } + +typedef UInt64(EfiImageUnload)(EfiHandlePtr ImageHandle); + +enum +{ + kPixelRedGreenBlueReserved8BitPerColor, + kPixelBlueGreenRedReserved8BitPerColor, + kPixelBitMask, + kPixelBltOnly, + kPixelFormatMax +}; + +typedef struct EfiBitmask +{ + UInt32 RedMask; + UInt32 GreenMask; + UInt32 BlueMask; + UInt32 ReservedMask; +} EfiBitmask; + +typedef struct +{ + UInt8 Blue; + UInt8 Green; + UInt8 Red; + UInt8 Reserved; +} EfiGraphicsOutputBltPixel; + +typedef enum EfiGraphicsOutputProtocolBltOperation +{ + EfiBltVideoFill, + EfiBltVideoToBltBuffer, + EfiBltBufferToVideo, + EfiBltVideoToVideo, + EfiGraphicsOutputBltOperationMax +} EfiGraphicsOutputProtocolBltOperation; + +typedef struct EfiGraphicsOutputProtocolModeInformation +{ + UInt32 Version; + UInt32 HorizontalResolution; + UInt32 VerticalResolution; + UInt32 PixelFormat; + EfiBitmask PixelInformation; + UInt32 PixelsPerScanLine; +} EfiGraphicsOutputProtocolModeInformation; + +typedef UInt64(EFI_API* EfiGraphicsOutputProtocolQueryMode)( + EfiGraphicsOutputProtocol* Self, UInt32 ModeNumber, UInt32* SizeOfInfo, EfiGraphicsOutputProtocolModeInformation** Info); + +typedef UInt64(EFI_API* EfiGraphicsOutputProtocolSetMode)( + EfiGraphicsOutputProtocol* Self, UInt32 ModeNumber); + +typedef UInt64(EFI_API* EfiGraphicsOutputProtocolBlt)( + EfiGraphicsOutputProtocol* Self, EfiGraphicsOutputBltPixel* BltBuffer, EfiGraphicsOutputProtocolBltOperation BltOperation, UInt32 SourceX, UInt32 SourceY, UInt32 DestinationX, UInt32 DestinationY, UInt32 Width, UInt32 Height, UInt32 Delta); + +typedef struct +{ + UInt32 MaxMode; + UInt32 Mode; + EfiGraphicsOutputProtocolModeInformation* Info; + UInt32 SizeOfInfo; + UIntPtr FrameBufferBase; + UInt32 FrameBufferSize; +} EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE; + +typedef struct EfiGraphicsOutputProtocol +{ + EfiGraphicsOutputProtocolQueryMode QueryMode; + EfiGraphicsOutputProtocolSetMode SetMode; + EfiGraphicsOutputProtocolBlt Blt; + EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE* Mode; +} EfiGraphicsOutputProtocol; + +typedef struct EfiLoadImageProtocol +{ + UInt32 Revision; + EfiHandlePtr ParentHandle; + EfiSystemTable* SystemTable; + + // Source location of the image + EfiHandlePtr DeviceHandle; + EfiDevicePathProtocol* FilePath; + Void* Reserved; + + // Image’s load options + UInt32 LoadOptionsSize; + Void* LoadOptions; + + // Location where image was loaded + Void* ImageBase; + UInt64 ImageSize; + EfiMemoryType ImageCodeType; + EfiMemoryType ImageDataType; + EfiImageUnload Unload; +} EfiLoadImageProtocol; + +typedef struct EfiLoadFileProtocol +{ + EfiLoadFile LoadFile; +} EfiLoadFileProtocol; + +typedef struct EfiDevicePathProtocol +{ + UInt8 Kind; + UInt8 SubType; + UInt8 Length[2]; +} EfiDevicePathProtocol; + +typedef struct EfiFileDevicePathProtocol +{ + EfiDevicePathProtocol Proto; + + /// + /// File Path of this struct + /// + WideChar Path[kPathLen]; +} EfiFileDevicePathProtocol; + +typedef UInt64(EFI_API* EfiExitBootServices)(VoidPtr ImageHandle, + UInt32 MapKey); + +typedef UInt64(EFI_API* EfiAllocatePages)(EfiAllocateType AllocType, + EfiMemoryType MemType, + UInt32 Count, + EfiPhysicalAddress* Memory); + +typedef UInt64(EFI_API* EfiFreePages)(EfiPhysicalAddress* Memory, UInt32 Pages); + +typedef UInt64(EFI_API* EfiGetMemoryMap)(UInt32* MapSize, + EfiMemoryDescriptor* DescPtr, + UInt32* MapKey, + UInt32* DescSize, + UInt32* DescVersion); + +/** + * @brief GUID type, something you can also find in CFKit. + */ +typedef struct EfiGUID EFI_FINAL +{ + UInt32 Data1; + UInt16 Data2; + UInt16 Data3; + UInt8 Data4[8]; +} EfiGUID; + +/*** + * Protocol stuff... + */ + +/** some helpers */ +#define EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL 0x00000001 +#define EFI_OPEN_PROTOCOL_GET_PROTOCOL 0x00000002 +#define EFI_OPEN_PROTOCOL_TEST_PROTOCOL 0x00000004 +#define EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER 0x00000008 +#define EFI_OPEN_PROTOCOL_BY_DRIVER 0x00000010 +#define EFI_OPEN_PROTOCOL_EXCLUSIVE 0x00000020 + +typedef UInt64(EFI_API* EfiLocateProtocol)(EfiGUID* Protocol, + VoidPtr Registration, + VoidPtr* Interface); + +typedef UInt64(EFI_API* EfiOpenProtocol)(EfiHandlePtr Handle, EfiGUID* Guid, VoidPtr* Interface, EfiHandlePtr AgentHandle, EfiHandlePtr ControllerHandle, UInt32 Attributes); + +typedef UInt64(EFI_API* EfiEnableCursor)(EfiSimpleTextOutputProtocol* Self, Boolean Visible); + +/** +@name EfiBootServices +@brief UEFI Boot Services record, it contains functions necessary to a +firmware level application. +*/ +typedef struct EfiBootServices +{ + EfiTableHeader SystemTable; + VoidPtr RaiseTPL; + VoidPtr RestoreTPL; + EfiAllocatePages AllocatePages; + EfiFreePages FreePages; + EfiGetMemoryMap GetMemoryMap; + EfiAllocatePool AllocatePool; + EfiFreePool FreePool; + VoidPtr CreateEvent; + VoidPtr SetTimer; + VoidPtr WaitForEvent; + VoidPtr SignalEvent; + VoidPtr CloseEvent; + VoidPtr CheckEvent; + VoidPtr InstallProtocolInterface; + VoidPtr ReinstallProtocolInterface; + VoidPtr UninstallProtocolInterface; + EfiHandleProtocol HandleProtocol; + VoidPtr Reserved; + VoidPtr RegisterProtocolNotify; + VoidPtr LocateHandle; + EfiLocateDevicePath LocateDevicePath; + VoidPtr InstallConfigurationTable; + EfiLoadImage LoadImage; + EfiStartImage StartImage; + VoidPtr Exit; + VoidPtr UnloadImage; + EfiExitBootServices ExitBootServices; + VoidPtr GetNextMonotonicCount; + VoidPtr Stall; + EfiStatusType(EFI_API* SetWatchdogTimer)(UInt32 Timeout, UInt64 WatchdogCode, UInt32 DataSize, EfiCharType* Data); + VoidPtr ConnectController; + VoidPtr DisconnectController; + EfiOpenProtocol OpenProtocol; + VoidPtr CloseProtocol; + VoidPtr OpenProtocolInformation; + VoidPtr ProtocolsPerHandle; + VoidPtr LocateHandleBuffer; + EfiLocateProtocol LocateProtocol; + VoidPtr InstallMultipleProtocolInterfaces; + VoidPtr UninstallMultipleProtocolInterfaces; + EfiCalculateCrc32 CalculateCrc32; + EfiCopyMem CopyMem; + EfiSetMem SetMem; + VoidPtr CreateEventEx; +} EfiBootServices; + +#define kEntireDevPath 0xFF +#define kThisInstancePath 0x01 + +/** +@brief PrintF like protocol. +*/ +typedef struct EfiSimpleTextOutputProtocol +{ + VoidPtr Reset; + EfiTextString OutputString; + VoidPtr TestString; + VoidPtr QueryMode; + VoidPtr SetMode; + EfiTextAttrib SetAttribute; + EfiTextClear ClearScreen; + VoidPtr SetCursorPosition; + EfiEnableCursor EnableCursor; + VoidPtr Mode; +} EfiSimpleTextOutputProtocol; + +typedef UInt64(EFI_API* EfiOpenVolume)(struct EfiSimpleFilesystemProtocol*, + struct EfiFileProtocol**); + +struct EfiSimpleFilesystemProtocol +{ + UInt64 Revision; + EfiOpenVolume OpenVolume; +}; + +/** +@brief The Structure that they give you when booting. +*/ +typedef struct EfiSystemTable +{ + EfiTableHeader SystemHeader; + WideChar* FirmwareVendor; + UInt32 FirmwareRevision; + EfiHandlePtr ConsoleInHandle; + VoidPtr ConIn; + EfiHandlePtr ConsoleOutHandle; + EfiSimpleTextOutputProtocol* ConOut; + EfiHandlePtr StandardErrorHandle; + VoidPtr StdErr; + VoidPtr RuntimeServices; + EfiBootServices* BootServices; + UInt64 NumberOfTableEntries; + /// The configuration table (contains the RSD PTR entry.) + struct + { + EfiGUID VendorGUID; + VoidPtr VendorTable; + } * ConfigurationTable; +} EfiSystemTable; + +#define kEfiOk 0 +#define kEfiFail -1 +#define kBufferTooSmall 5 + +#define EFI_EXTERN_C extern "C" + +typedef struct EfiIPV4 +{ + UInt8 Addr[4]; +} EfiIPV4; + +/// +/// 16-byte buffer. An IPv6 internet protocol address. +/// +typedef struct EfiIPV6 +{ + UInt8 Addr[16]; +} EfiIPV6; + +#define kEFIYellow (0x01 | 0x02 | 0x04 | 0x08) + +#ifdef __x86_64 +#define __EFI_x86_64__ 1 +#endif // __x86_64 + +enum +{ + kEFIHwDevicePath = 0x01, + kEFIAcpiDevicePath = 0x02, + kEFIMessaingDevicePath = 0x03, + kEFIMediaDevicePath = 0x04, + kEFIBiosBootPath = 0x05, + kEFIEndOfPath = 0x06, + kEFICount = 6, +}; + +#define END_DEVICE_PATH_TYPE 0x7f +#define END_ENTIRE_DEVICE_PATH_SUBTYPE 0xFF +#define END_INSTANCE_DEVICE_PATH_SUBTYPE 0x01 + +#define kEfiOffsetOf(T, F) __builtin_offsetof(T, F) + +/// File I/O macros + +#define kEFIFileRead 0x0000000000000001 +#define kEFIFileWrite 0x0000000000000002 +#define kEFIFileCreate 0x0000000000000000 + +#define kEFIReadOnly 0x01 +#define kEFIHidden 0x02 +#define kEFISystem 0x04 +#define kEFIReserved 0x08 +#define kEFIDirectory 0x10 +#define kEFIArchive 0x20 + +#define EFI_FILE_PROTOCOL_REVISION 0x00010000 +#define EFI_FILE_PROTOCOL_REVISION2 0x00020000 +#define EFI_FILE_PROTOCOL_LATEST_REVISION EFI_FILE_PROTOCOL_REVISION2 + +#define EFI_EXTRA_DESCRIPTOR_SIZE 8 + +#define EFI_MP_SERVICES_PROTOCOL_GUID \ + { \ + 0x3fdda605, 0xa76e, 0x4f46, \ + { \ + 0xad, 0x29, 0x12, 0xf4, \ + 0x53, 0x1b, 0x3d, 0x08 \ + } \ + } + +#define PROCESSOR_AS_BSP_BIT 0x00000001 +#define PROCESSOR_ENABLED_BIT 0x00000002 +#define PROCESSOR_HEALTH_STATUS_BIT 0x00000004 + +#define END_OF_CPU_LIST 0xffffffff + +typedef struct EfiIOToken +{ + // + // If Event is NULL, then blocking I/O is performed. + // If Event is not NULL and non-blocking I/O is supported, then non-blocking + // I/O is performed, and Event will be signaled when the read request is + // completed. The caller must be prepared to handle the case where the + // callback associated with Event occurs before the original asynchronous I/O + // request call returns. + // + UInt64 Event; + + // + // Defines whether or not the signaled event encountered an error. + // + UInt64 Status; + + // + // For OpenEx(): Not Used, ignored. + // For ReadEx(): On input, the size of the Buffer. On output, the amount of + // data returned in Buffer. + // In both cases, the size is measured in bytes. + // For WriteEx(): On input, the size of the Buffer. On output, the amount of + // data actually written. + // In both cases, the size is measured in bytes. + // For FlushEx(): Not used, ignored. + // + UInt32 BufferSize; + + // + // For OpenEx(): Not Used, ignored. + // For ReadEx(): The buffer into which the data is read. + // For WriteEx(): The buffer of data to write. + // For FlushEx(): Not Used, ignored. + // + Void* Buffer; +} EfiIOToken; + +typedef struct EfiFileProtocol +{ + UInt64 Revision; + + EfiStatusType(EFI_API* Open)(struct EfiFileProtocol* Self, + struct EfiFileProtocol** Out, + EfiCharType* CharType, + UInt64 OpenMode, + UInt64 Attrib); + + EfiStatusType(EFI_API* Close)(struct EfiFileProtocol* Self); + + EfiStatusType(EFI_API* Delete)(struct EfiFileProtocol* Self); + + EfiStatusType(EFI_API* Read)(struct EfiFileProtocol* Self, UInt64* BufSize, VoidPtr BufOut); + + EfiStatusType(EFI_API* Write)(struct EfiFileProtocol* Self, UInt64* BufSize, VoidPtr BufOut); + + EfiStatusType(EFI_API* GetPosition)(EfiFileProtocol* Self, UInt64* Position); + + EfiStatusType(EFI_API* SetPosition)(EfiFileProtocol* Self, UInt64* Position); + + EfiStatusType(EFI_API* GetInfo)(struct EfiFileProtocol*, struct EfiGUID*, UInt32*, void*); + + EfiStatusType(EFI_API* SetInfo)(struct EfiFileProtocol*, struct EfiGUID*, UInt32*, void*); + + EfiStatusType(EFI_API* Flush)(EfiFileProtocol*); + + EfiStatusType(EFI_API* OpenEx)(EfiFileProtocol* Self, + EfiFileProtocol** OutHandle, + EfiCharType* Path, + UInt64 Mode, + UInt64 Attrib, + struct EfiIOToken* Token); + + EfiStatusType(EFI_API* ReadEx)(EfiFileProtocol* Self, + struct EfiIOToken* Token); + + EfiStatusType(EFI_API* WriteEx)(EfiFileProtocol* Self, + struct EfiIOToken* Token); + + EfiStatusType(EFI_API* FlushEx)(EfiFileProtocol* Self, + struct EfiIOToken* Token); +} EfiFileProtocol, *EfiFileProtocolPtr; + +typedef UInt64 EfiCursorType; + +typedef struct EfiTime +{ + UInt16 Year; + UInt8 Month; + UInt8 Day; + UInt8 Hour; + UInt8 Minute; + UInt8 Second; + UInt8 Pad1; + UInt32 Nanosecond; + Int16 TimeZone; + UInt8 Daylight; + UInt8 Pad2; +} EfiTime; + +#define EFI_FILE_INFO_GUID \ + { \ + 0x09576e92, 0x6d3f, 0x11d2, \ + { \ + 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b \ + } \ + } + +struct EfiFileInfo EFI_FINAL +{ + /// @brief Structure size. + UInt64 Size; + /// @brief File size. + UInt64 FileSize; + /// @brief Physical size on disk. + UInt64 PhysicalSize; + /// @brief Create time. + EfiTime CreateTime; + /// @brief Last access time. + EfiTime LastAccessTime; + /// @brief Edit time. + EfiTime EditTime; + /// @brief Attributes. + UInt64 Attribute; + /// @brief VLA file name. + WideChar FileName[1]; +}; + +//******************************************************* +// EFI_CPU_PHYSICAL_LOCATION +// @note As in the EFI specs. +//******************************************************* +typedef struct _EfiCPUPhyiscalLocation +{ + UInt32 Package; + UInt32 Core; + UInt32 Thread; +} EfiCPUPhyiscalLocation; + +typedef union _EfiExtendedProcessorInformation { + EfiCPUPhyiscalLocation Location2; +} EfiExtendedProcessorInformation; + +typedef struct _EfiProcessorInformation +{ + UInt64 ProcessorId; + UInt32 StatusFlag; + EfiCPUPhyiscalLocation Location; + EfiExtendedProcessorInformation ExtendedInformation; +} EfiProcessorInformation; + +typedef EfiStatusType EFI_API (*EfiMpServicesGetNumberOfProcessors)( + IN struct _EfiMpServicesProtocol* Self, + OUT UInt32* NumberOfProcessors, + OUT UInt32* NumberOfEnabledProcessors); + +typedef EfiStatusType EFI_API (*EfiMpServicesGetProcessorInfo)( + IN struct _EfiMpServicesProtocol* Self, + IN UInt32* ProcessorNumber, + OUT struct _EfiProcessorInformation* NumberOfEnabledProcessors); + +typedef void EFI_API (*EFI_AP_PROCEDURE)( + IN VoidPtr ProcedureArgument); + +typedef EfiStatusType EFI_API (*EfiMpServicesStartupAllAPS)( + IN struct _EfiMpServicesProtocol* Self, + IN EFI_AP_PROCEDURE Procedure, + IN Boolean SingleThread, + IN VoidPtr WaitEvent OPTIONAL, // EFI_EVENT first, but unused here. + IN UInt32 TimeoutInMicroSeconds, + IN Void* ProcedureArgument OPTIONAL, + OUT UInt32** FailedCpuList OPTIONAL); + +typedef EfiStatusType EFI_API (*EfiMpServicesSwitchBSP)( + IN struct _EfiMpServicesProtocol* Self, + IN UInt32 ProcessorNumber, + IN Boolean EnableOldBSP); + +typedef EfiStatusType EFI_API (*EfiMpServicesStartupThisAP)( + IN struct _EfiMpServicesProtocol* Self, + IN EFI_AP_PROCEDURE Procedure, + IN UInt32 ProcessorNumber, + IN VoidPtr WaitEvent OPTIONAL, + IN UInt32 TimeoutInMicroseconds, + IN Void* ProcedureArgument OPTIONAL, + OUT Boolean* Finished OPTIONAL); + +typedef EfiStatusType EFI_API (*EfiMpServicesDisableThisAP)( + IN struct _EfiMpServicesProtocol* Self, + IN UInt32 ProcessorNumber, + IN Boolean EnableAP, + IN UInt32* HealthFlag OPTIONAL); + +typedef EfiStatusType EFI_API (*EfiMpServicesWhoAmI)( + IN struct _EfiMpServicesProtocol* Self, + OUT UInt32* ProcessorNumber); + +typedef struct _EfiMpServicesProtocol +{ + EfiMpServicesGetNumberOfProcessors GetNumberOfProcessors; + EfiMpServicesGetProcessorInfo GetProcessorInfo; + EfiMpServicesStartupAllAPS StartupAllAPs; + EfiMpServicesStartupThisAP StartupThisAP; + EfiMpServicesSwitchBSP SwitchBSP; + EfiMpServicesDisableThisAP EnableDisableAP; + EfiMpServicesWhoAmI WhoAmI; +} EfiMpServicesProtocol; + +#endif // ifndef FIRMWARE_KIT_EFI_H diff --git a/dev/Kernel/FirmwareKit/EFI/NS.h b/dev/Kernel/FirmwareKit/EFI/NS.h new file mode 100644 index 00000000..07b301f0 --- /dev/null +++ b/dev/Kernel/FirmwareKit/EFI/NS.h @@ -0,0 +1,15 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include + +namespace Firmware::Detail::EFI +{ + using namespace Kernel; +#include +} // namespace Firmware::Detail::EFI diff --git a/dev/Kernel/FirmwareKit/EPM.h b/dev/Kernel/FirmwareKit/EPM.h new file mode 100644 index 00000000..3178c2b0 --- /dev/null +++ b/dev/Kernel/FirmwareKit/EPM.h @@ -0,0 +1,112 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +/** + @brief The Explicit Partition Map scheme. +*/ + +#ifndef FIRMWAREKIT_EPM_H +#define FIRMWAREKIT_EPM_H + +#include + +#define kEPMNameLength (32) +#define kEPMFilesystemLength (16) +#define kEPMMagicLength (5) + +/* @brief AMD64 magic for EPM */ +#define kEPMMagic86 "EPMAM" + +/* @brief RISC-V magic for EPM */ +#define kEPMMagicRISCV "EPMRV" + +/* @brief ARM magic for EPM */ +#define kEPMMagicARM "EPMAR" + +/* @brief 64x0 magic for EPM */ +#define kEPMMagic64k "EPM64" + +/* @brief 32x0 magic for EPM */ +#define kEPMMagic32k "EPM32" + +/* @brief POWER magic for EPM */ +#define kEPMMagicPPC "EPMPC" + +/* @brief Invalid magic for EPM */ +#define kEPMMagicError "EPM??" + +#ifdef __ZKA_AMD64__ +#define kEPMMagic kEPMMagic86 +#else +#ifdef __ZKA_ARM64__ +#define kEPMMagic kEPMMagicARM +#else +#define kEPMMagic kEPMMagicError +#endif +#endif + +///! @brief partition must start at this address. +///! Anything below is reserved for Data backup by the Main OS. +#define kEPMPartBlockLba (sizeof(EPM_BOOT_BLOCK)) + +///! @brief Current EPM revision. +#define kEPMRevisionBcd (0x0100) + +/// !@brief EPM boot block address. +#define kEPMBootBlockLba (0U) + +#define kEPMReserveLen (401) + +struct EPM_GUID; +struct EPM_BOOT_BLOCK; + +/* The first 0 > 128 addresses of a disk contains these headers. */ + +/// @brief EPM GUID structure. +typedef struct EPM_GUID +{ + Kernel::UInt32 Data1; + Kernel::UInt16 Data2; + Kernel::UInt16 Data3; + Kernel::UInt8 Data4[8]; +} EPM_GUID; + +/** + * @brief The EPM boot block. + * @note NumBlock and LbaStart are ignored on some platforms. + */ +struct PACKED EPM_BOOT_BLOCK +{ + Kernel::Char Magic[kEPMMagicLength]; + Kernel::Char Name[kEPMNameLength]; + EPM_GUID Guid; + Kernel::Int32 Version; + Kernel::Int64 NumBlocks; + Kernel::Int64 SectorSz; + Kernel::Int64 LbaStart; // base offset + Kernel::Int64 LbaEnd; // addition of lba_start to get the end of partition. + Kernel::Int16 Kind; + Kernel::Int32 FsVersion; + Kernel::Char Fs[kEPMFilesystemLength]; /* NeFS, ffs2... */ + Kernel::Char Reserved[kEPMReserveLen]; // to fill a full sector. +}; + +///! @brief Version kind enum. +///! @brief Use in boot block version field. + +enum +{ + kEPMInvalid = 0x00, + kEPMGenericOS = 0xcf, // Generic OS + kEPMLinux = 0x8f, // Linux on EPM + kEPMBSD = 0x9f, // Berkeley Soft. Distribution + kEPMZkaOS = 0x1f, // This OS. + kEPMInvalidOS = 0xff, +}; + +typedef struct EPM_BOOT_BLOCK BOOT_BLOCK_STRUCT; + +#endif // ifndef FIRMWAREKIT_EPM_H diff --git a/dev/Kernel/FirmwareKit/GPT.h b/dev/Kernel/FirmwareKit/GPT.h new file mode 100644 index 00000000..61d29281 --- /dev/null +++ b/dev/Kernel/FirmwareKit/GPT.h @@ -0,0 +1,48 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include +#include + +#define kSectorSizeGPT 512 + +namespace Kernel +{ + typedef EfiGUID GPT_GUID; + struct GPT_PARTITION_TABLE; + struct GPT_PARTITION_ENTRY; + + struct PACKED GPT_PARTITION_TABLE final + { + Char PartitionName[8]; + UInt32 Revision; + UInt32 HeaderSize; + UInt32 ChecksumCRC32; + UInt32 Reserved1; + UInt64 LBAHeader; + UInt64 LBAAltHeader; + UInt64 FirstGPTEntry; + UInt64 LastGPTEntry; + GPT_GUID Guid; + UInt64 StartingLBA; + UInt32 NumPartitionEntries; + UInt32 SizeOfEntries; + UInt32 CRC32PartEntry; + UInt8 Reserved2[kSectorSizeGPT]; + }; + + struct PACKED GPT_PARTITION_ENTRY + { + GPT_GUID PartitionTypeGUID; + GPT_GUID UniquePartitionGUID; + UInt64 StartLBA; + UInt64 EndLBA; + UInt64 Attributes; + UInt8 Name[72]; + }; +} // namespace Kernel diff --git a/dev/Kernel/FirmwareKit/Handover.h b/dev/Kernel/FirmwareKit/Handover.h new file mode 100644 index 00000000..a4f086ea --- /dev/null +++ b/dev/Kernel/FirmwareKit/Handover.h @@ -0,0 +1,110 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +/** + * @file Handover.h + * @author TQ B.V (amlalelmahrouss@icloud.com) + * @brief The handover boot protocol. + * @version 1.15 + * @date 2024-02-23 + * + * @copyright Copyright (c) 2024, TQ B.V + * + */ + +#pragma once + +#include + +#define kHandoverMagic 0xBADCC +#define kHandoverVersion 0x0117 + +/* Initial bitmap pointer location and size. */ +#define kHandoverBitMapSz (gib_cast(4)) +#define kHandoverStructSz sizeof(HEL::BootInfoHeader) + +namespace Kernel::HEL +{ + /** + @brief The executable type enum. + */ + enum + { + kTypeKernel = 100, + kTypeKernelDriver = 101, + kTypeRsrc = 102, + kTypeInvalid = 103, + kTypeCount = 4, + }; + + /** + @brief The executable architecture enum. + */ + + enum + { + kArchAMD64 = 122, + kArchARM64 = 123, + kArchRISCV = 124, + kArchCount = 3, + }; + + struct BootInfoHeader final + { + UInt64 f_Magic; + UInt64 f_Version; + + VoidPtr f_BitMapStart; + SizeT f_BitMapSize; + + VoidPtr f_PageStart; + + VoidPtr f_KernelImage; + SizeT f_KernelSz; + VoidPtr f_StartupImage; + SizeT f_StartupSz; + VoidPtr f_FontImage; + SizeT f_FontSz; + + WideChar f_FirmwareVendorName[32]; + SizeT f_FirmwareVendorLen; + + VoidPtr f_FirmwareCustomTables[2]; // On EFI 0: BS 1: ST + + struct + { + VoidPtr f_SmBios; + VoidPtr f_VendorPtr; + VoidPtr f_MpPtr; + Bool f_MultiProcessingEnabled; + } f_HardwareTables; + + struct + { + UIntPtr f_The; + SizeT f_Size; + UInt32 f_Width; + UInt32 f_Height; + UInt32 f_PixelFormat; + UInt32 f_PixelPerLine; + } f_GOP; + + UInt64 f_FirmwareSpecific[8]; + }; + + enum + { + kHandoverSpecificKind, + kHandoverSpecificAttrib, + kHandoverSpecificMemoryEfi, + }; + + /// @brief Alias of bootloader main type. + typedef void (*HandoverProc)(BootInfoHeader* boot_info); +} // namespace Kernel::HEL + +/// @brief Bootloader information header global variable. +inline Kernel::HEL::BootInfoHeader* kHandoverHeader = nullptr; diff --git a/dev/Kernel/HALKit/.gitkeep b/dev/Kernel/HALKit/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/dev/Kernel/HALKit/64x0/.hgkeep b/dev/Kernel/HALKit/64x0/.hgkeep new file mode 100644 index 00000000..e69de29b diff --git a/dev/Kernel/HALKit/64x0/APM/.hgkeep b/dev/Kernel/HALKit/64x0/APM/.hgkeep new file mode 100644 index 00000000..e69de29b diff --git a/dev/Kernel/HALKit/64x0/HalVirtualMemory.cc b/dev/Kernel/HALKit/64x0/HalVirtualMemory.cc new file mode 100644 index 00000000..6dd40325 --- /dev/null +++ b/dev/Kernel/HALKit/64x0/HalVirtualMemory.cc @@ -0,0 +1,17 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include + +using namespace Kernel; + +/// @brief Flush system TLB, looks like the POWER version, as it acts the same, no specific instruction for that. +/// @note The 88K MMU should be present as well. +EXTERN_C void hal_flush_tlb() +{ + asm volatile("invltlb"); +} diff --git a/dev/Kernel/HALKit/64x0/MBCI/.gitkeep b/dev/Kernel/HALKit/64x0/MBCI/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/dev/Kernel/HALKit/64x0/ReadMe.md b/dev/Kernel/HALKit/64x0/ReadMe.md new file mode 100644 index 00000000..c131541e --- /dev/null +++ b/dev/Kernel/HALKit/64x0/ReadMe.md @@ -0,0 +1,4 @@ +64x0 Hardware Abstraction Layer + +- Supported CPU: TQ B.V 64x0 +- Supported Firmware: CoreBoot diff --git a/dev/Kernel/HALKit/AMD64/CPUID.h b/dev/Kernel/HALKit/AMD64/CPUID.h new file mode 100644 index 00000000..44e1d842 --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/CPUID.h @@ -0,0 +1,86 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + + File: CPUID.h + Purpose: CPUID flags. + + Revision History: + + 30/01/24: Added file (amlel) + +------------------------------------------- */ + +#pragma once + +#include + +enum CPUFeatureEnum +{ + kCPUFeatureSSE3 = 1 << 0, + kCPUFeaturePCLMUL = 1 << 1, + kCPUFeatureDTES64 = 1 << 2, + kCPUFeatureMONITOR = 1 << 3, + kCPUFeatureDS_CPL = 1 << 4, + kCPUFeatureVMX = 1 << 5, + kCPUFeatureSMX = 1 << 6, + kCPUFeatureEST = 1 << 7, + kCPUFeatureTM2 = 1 << 8, + kCPUFeatureSSSE3 = 1 << 9, + kCPUFeatureCID = 1 << 10, + kCPUFeatureSDBG = 1 << 11, + kCPUFeatureFMA = 1 << 12, + kCPUFeatureCX16 = 1 << 13, + kCPUFeatureXTPR = 1 << 14, + kCPUFeaturePDCM = 1 << 15, + kCPUFeaturePCID = 1 << 17, + kCPUFeatureDCA = 1 << 18, + kCPUFeatureSSE4_1 = 1 << 19, + kCPUFeatureSSE4_2 = 1 << 20, + kCPUFeatureX2APIC = 1 << 21, + kCPUFeatureMOVBE = 1 << 22, + kCPUFeaturePOP3C = 1 << 23, + kCPUFeatureECXTSC = 1 << 24, + kCPUFeatureAES = 1 << 25, + kCPUFeatureXSAVE = 1 << 26, + kCPUFeatureOSXSAVE = 1 << 27, + kCPUFeatureAVX = 1 << 28, + kCPUFeatureF16C = 1 << 29, + kCPUFeatureRDRAND = 1 << 30, + kCPUFeatureHYPERVISOR = 1 << 31, + kCPUFeatureFPU = 1 << 0, + kCPUFeatureVME = 1 << 1, + kCPUFeatureDE = 1 << 2, + kCPUFeaturePSE = 1 << 3, + kCPUFeatureEDXTSC = 1 << 4, + kCPUFeatureMSR = 1 << 5, + kCPUFeaturePAE = 1 << 6, + kCPUFeatureMCE = 1 << 7, + kCPUFeatureCX8 = 1 << 8, + kCPUFeatureAPIC = 1 << 9, + kCPUFeatureSEP = 1 << 11, + kCPUFeatureMTRR = 1 << 12, + kCPUFeaturePGE = 1 << 13, + kCPUFeatureMCA = 1 << 14, + kCPUFeatureCMOV = 1 << 15, + kCPUFeaturePAT = 1 << 16, + kCPUFeaturePSE36 = 1 << 17, + kCPUFeaturePSN = 1 << 18, + kCPUFeatureCLFLUSH = 1 << 19, + kCPUFeatureDS = 1 << 21, + kCPUFeatureACPI = 1 << 22, + kCPUFeatureMMX = 1 << 23, + kCPUFeatureFXSR = 1 << 24, + kCPUFeatureSSE = 1 << 25, + kCPUFeatureSSE2 = 1 << 26, + kCPUFeatureSS = 1 << 27, + kCPUFeatureHTT = 1 << 28, + kCPUFeatureTM = 1 << 29, + kCPUFeatureIA64 = 1 << 30, + kCPUFeaturePBE = 1 << 31 +}; + +namespace Kernel +{ + typedef Int64 CPUID; +} // namespace Kernel diff --git a/dev/Kernel/HALKit/AMD64/HalACPIFactoryInterface.cc b/dev/Kernel/HALKit/AMD64/HalACPIFactoryInterface.cc new file mode 100644 index 00000000..f742c3d7 --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/HalACPIFactoryInterface.cc @@ -0,0 +1,126 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include +#include +#include +#include + +namespace Kernel +{ + namespace Detail + { + struct FADT final : public SDT + { + UInt32 FirmwareCtrl; + UInt32 Dsdt; + + // field used in ACPI 1.0; no longer in use, for compatibility only + UInt8 Reserved; + + UInt8 PreferredPowerManagementProfile; + UInt16 SCI_Interrupt; + UInt32 SMI_CommandPort; + UInt8 AcpiEnable; + UInt8 AcpiDisable; + UInt8 S4BIOS_REQ; + UInt8 PSTATE_Control; + UInt32 PM1aEventBlock; + UInt32 PM1bEventBlock; + UInt32 PM1aControlBlock; + UInt32 PM1bControlBlock; + UInt32 PM2ControlBlock; + UInt32 PMTimerBlock; + UInt32 GPE0Block; + UInt32 GPE1Block; + UInt8 PM1EventLength; + UInt8 PM1ControlLength; + UInt8 PM2ControlLength; + UInt8 PMTimerLength; + UInt8 GPE0Length; + UInt8 GPE1Length; + UInt8 GPE1Base; + UInt8 CStateControl; + UInt16 WorstC2Latency; + UInt16 WorstC3Latency; + UInt16 FlushSize; + UInt16 FlushStride; + UInt8 DutyOffset; + UInt8 DutyWidth; + UInt8 DayAlarm; + UInt8 MonthAlarm; + UInt8 Century; + + // reserved in ACPI 1.0; used since ACPI 2.0+ + UInt16 BootArchitecturkMMFlags; + + UInt8 Reserved2; + UInt32 Flags; + + // 12 byte structure; see below for details + ACPI_ADDRESS ResetReg; + + UInt8 ResetValue; + UInt8 Reserved3[3]; + + // 64bit pointers - Available on ACPI 2.0+ + UInt64 X_FirmwareControl; + UInt64 X_Dsdt; + + ACPI_ADDRESS X_PM1aEventBlock; + ACPI_ADDRESS X_PM1bEventBlock; + ACPI_ADDRESS X_PM1aControlBlock; + ACPI_ADDRESS X_PM1bControlBlock; + ACPI_ADDRESS X_PM2ControlBlock; + ACPI_ADDRESS X_PMTimerBlock; + ACPI_ADDRESS X_GPE0Block; + ACPI_ADDRESS X_GPE1Block; + }; + } // namespace Detail + + ACPIFactoryInterface::ACPIFactoryInterface(VoidPtr rsp_ptr) + : fRsdp(rsp_ptr), fEntries(0) + { + } + + Void ACPIFactoryInterface::Shutdown() + { + failed_to_shutdown: + // in case no acpi mode, or it's not available. + while (Yes) + { + asm volatile("cli; hlt"); + } + } + + /// @brief Reboot machine in either ACPI or by triple faulting. + /// @return nothing it's a reboot. + Void ACPIFactoryInterface::Reboot() + { + failed_to_reboot: + asm volatile(".intel_syntax noprefix; " + "rt_reset_hardware:; " + "cli; " + "wait_gate1: ; " + "in al,0x64 ; " + "and al,2 ; " + "jnz wait_gate1 ; " + "mov al,0x0D1 ; " + "out 0x64,al ; " + "wait_gate2: ; " + "in al,0x64 ; " + "and al,2 ; " + "jnz wait_gate2 ; " + "mov al,0x0FE ; " + "out 0x60,al ; " + "xor rax,rax ; " + "lidt [rax] ; " + "reset_wait: ; " + "jmp reset_wait ; " + ".att_syntax; "); + } +} // namespace Kernel diff --git a/dev/Kernel/HALKit/AMD64/HalAP.cc b/dev/Kernel/HALKit/AMD64/HalAP.cc new file mode 100644 index 00000000..aefe570c --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/HalAP.cc @@ -0,0 +1,51 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include + +namespace Kernel +{ + /***********************************************************************************/ + /// @brief Unimplemented function (crashes by default) + /// @param + /***********************************************************************************/ + + EXTERN_C Void __zka_pure_call(void) + { + UserProcessScheduler::The().GetCurrentProcess().Leak().Crash(); + } + + /***********************************************************************************/ + /// @brief Validate user stack. + /// @param stack_ptr the frame pointer. + /***********************************************************************************/ + + Bool hal_check_stack(HAL::StackFramePtr stack_ptr) + { + if (!stack_ptr) + return No; + + return stack_ptr->SP != 0 && stack_ptr->BP != 0; + } + + /// @brief Wakes up thread. + /// Wakes up thread from the hang state. + Void mp_wakeup_thread(HAL::StackFrame* stack) + { + Kernel::UserProcessHelper::StartScheduling(); + } + + /// @brief makes the thread sleep on a loop. + /// hooks and hangs thread to prevent code from executing. + Void mp_hang_thread(HAL::StackFrame* stack) + { + while (Yes) + { + /* Nothing to do, code is spinning */ + } + } +} // namespace Kernel diff --git a/dev/Kernel/HALKit/AMD64/HalAPICController.cc b/dev/Kernel/HALKit/AMD64/HalAPICController.cc new file mode 100644 index 00000000..e29bea67 --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/HalAPICController.cc @@ -0,0 +1,39 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include + +#define cIOAPICRegVal (4) +#define cIOAPICRegReg (0) + +namespace Kernel::HAL +{ + /// @brief Read from APIC controller. + /// @param reg register. + UInt32 APICController::Read(UInt32 reg) noexcept + { + MUST_PASS(this->fApic); + + UInt32 volatile* io_apic = (UInt32 volatile*)this->fApic; + io_apic[cIOAPICRegReg] = (reg & 0xFF); + + return io_apic[cIOAPICRegVal]; + } + + /// @brief Write to APIC controller. + /// @param reg register. + /// @param value value. + Void APICController::Write(UInt32 reg, UInt32 value) noexcept + { + MUST_PASS(this->fApic); + + UInt32 volatile* io_apic = (UInt32 volatile*)this->fApic; + + io_apic[cIOAPICRegReg] = (reg & 0xFF); + io_apic[cIOAPICRegVal] = value; + } +} // namespace Kernel::HAL diff --git a/dev/Kernel/HALKit/AMD64/HalBoot.asm b/dev/Kernel/HALKit/AMD64/HalBoot.asm new file mode 100644 index 00000000..8830f786 --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/HalBoot.asm @@ -0,0 +1,28 @@ +;; /* +;; * ======================================================== +;; * +;; * ZKA +;; * Copyright (C) 2024, TQ B.V, all rights reserved., all rights reserved. +;; * +;; * ======================================================== +;; */ + +[bits 64] + +;; Global symbol of this unit +[extern hal_init_platform] + +%define kTypeKernel 100 +%define kArchAmd64 122 +%define kHandoverMagic 0xBADCC + +section .ldr + +HandoverMagic: + dq kHandoverMagic +HandoverType: + dw kTypeKernel +HandoverPad: + dw 0 +HandoverArch: + dw kArchAmd64 diff --git a/dev/Kernel/HALKit/AMD64/HalCPUAMD64.cc b/dev/Kernel/HALKit/AMD64/HalCPUAMD64.cc new file mode 100644 index 00000000..9af3ce37 --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/HalCPUAMD64.cc @@ -0,0 +1,101 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + + File: HalCPU.cc + Purpose: Platform processor routines. + +------------------------------------------- */ + +#include +#include + +/** + * @file HalCPU.cc + * @brief Common CPU API. + */ + +namespace Kernel::HAL +{ + Void lrt_out8(UInt16 port, UInt8 value) + { + asm volatile("outb %%al, %1" + : + : "a"(value), "Nd"(port) + : "memory"); + } + + Void lrt_out16(UInt16 port, UInt16 value) + { + asm volatile("outw %%ax, %1" + : + : "a"(value), "Nd"(port) + : "memory"); + } + + Void lrt_out32(UInt16 port, UInt32 value) + { + asm volatile("outl %%eax, %1" + : + : "a"(value), "Nd"(port) + : "memory"); + } + + UInt8 lrt_in8(UInt16 port) + { + UInt8 value = 0UL; + asm volatile("inb %1, %%al" + : "=a"(value) + : "Nd"(port) + : "memory"); + + return value; + } + + UInt16 lrt_in16(UInt16 port) + { + UInt16 value = 0UL; + asm volatile("inw %1, %%ax" + : "=a"(value) + : "Nd"(port) + : "memory"); + + return value; + } + + UInt32 lrt_in32(UInt16 port) + { + UInt32 value = 0UL; + asm volatile("inl %1, %%eax" + : "=a"(value) + : "Nd"(port) + : "memory"); + + return value; + } + + Void rt_halt() + { + asm volatile("hlt"); + } + + Void rt_cli() + { + asm volatile("cli"); + } + + Void rt_sti() + { + asm volatile("sti"); + } + + Void rt_cld() + { + asm volatile("cld"); + } + + Void rt_std() + { + asm volatile("std"); + } +} // namespace Kernel::HAL diff --git a/dev/Kernel/HALKit/AMD64/HalCommonAPI.asm b/dev/Kernel/HALKit/AMD64/HalCommonAPI.asm new file mode 100644 index 00000000..fae0753b --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/HalCommonAPI.asm @@ -0,0 +1,53 @@ +;; /* +;; * ======================================================== +;; * +;; * ZKA +;; * Copyright (C) 2024, TQ B.V, all rights reserved., all rights reserved. +;; * +;; * ======================================================== +;; */ + +section .text + +extern rt_wait_400ns + +global rt_out8 +global rt_out16 +global rt_out32 + +global rt_in8 +global rt_in16 +global rt_in32 + +rt_out8: + mov al, dl + mov dx, cx + out dx, al + ret + +rt_out16: + mov ax, dx + mov dx, cx + out dx, ax + ret + +rt_out32: + mov eax, edx + mov edx, ecx + out dx, eax + ret + +rt_in8: + mov dx, cx + in al, dx + ret + +rt_in16: + mov edx, ecx + in ax, dx + ret + +rt_in32: + mov rdx, rcx + in eax, dx + ret diff --git a/dev/Kernel/HALKit/AMD64/HalControlRegister.s b/dev/Kernel/HALKit/AMD64/HalControlRegister.s new file mode 100644 index 00000000..3ff54d15 --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/HalControlRegister.s @@ -0,0 +1,45 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +.globl hal_write_cr3 +.globl hal_write_cr0 +.globl hal_read_cr2 +.globl hal_read_cr3 +.globl hal_read_cr0 +.globl hal_flush_tlb +.globl hal_invl_tlb + +.text + +hal_invl_tlb: + invlpg (%rcx) + retq + +hal_flush_tlb: + call hal_read_cr3 + mov %rax, %rcx + call hal_write_cr3 + retq + +hal_read_cr3: + movq %cr3, %rax + retq + +hal_read_cr0: + movq %cr0, %rax + retq + +hal_read_cr2: + movq %cr2, %rax + retq + +hal_write_cr3: + movq %rcx, %cr3 + retq + +hal_write_cr0: + movq %rcx, %cr0 + retq diff --git a/dev/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc b/dev/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc new file mode 100644 index 00000000..a5125e68 --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc @@ -0,0 +1,232 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include +#include +#include + +/// @brief Handle GPF fault. +/// @param rsp +EXTERN_C void idt_handle_gpf(Kernel::UIntPtr rsp) +{ + kcout << "Kernel: GPF.\r"; + + auto process = Kernel::UserProcessScheduler::The().GetCurrentProcess(); + + if (!process) + Kernel::ke_stop(RUNTIME_CHECK_PAGE); + + process.Leak().ProcessSignal.SignalIP = 0UL; + process.Leak().ProcessSignal.SignalID = SIGKILL; + process.Leak().ProcessSignal.PreviousStatus = process.Leak().Status; + + kcout << "Kernel: PRCFROZE status set..\r"; + + process.Leak().Status = Kernel::ProcessStatusKind::kFrozen; + + process.Leak().Crash(); + + Kernel::ke_stop(RUNTIME_CHECK_POINTER); +} + +/// @brief Handle page fault. +/// @param rsp +EXTERN_C void idt_handle_pf(Kernel::UIntPtr rsp) +{ + kcout << "Kernel: Page Fault.\r"; + kcout << "Kernel: SIGKILL set.\r"; + + auto process = Kernel::UserProcessScheduler::The().GetCurrentProcess(); + + if (!process) + Kernel::ke_stop(RUNTIME_CHECK_PAGE); + + process.Leak().ProcessSignal.SignalIP = 0UL; + process.Leak().ProcessSignal.SignalID = SIGKILL; + process.Leak().ProcessSignal.PreviousStatus = process.Leak().Status; + + kcout << "Kernel: PRCFROZE status set..\r"; + + process.Leak().Status = Kernel::ProcessStatusKind::kFrozen; + + process.Leak().Crash(); + + Kernel::ke_stop(RUNTIME_CHECK_PAGE); +} + +/// @brief Handle scheduler interrupt. +EXTERN_C void idt_handle_scheduler(Kernel::UIntPtr rsp) +{ + static BOOL is_scheduling = NO; + static Kernel::Int64 try_count_before_brute = 100000UL; + + while (is_scheduling) + { + --try_count_before_brute; + + if (try_count_before_brute < 1) + break; + } + + try_count_before_brute = 100000UL; + is_scheduling = YES; + + kcout << "Kernel: Timer IRQ (Scheduler Notification).\r"; + Kernel::UserProcessHelper::StartScheduling(); + + is_scheduling = NO; +} + +/// @brief Handle math fault. +/// @param rsp +EXTERN_C void idt_handle_math(Kernel::UIntPtr rsp) +{ + kcout << "Kernel: Math error (division by zero?).\r"; + + auto process = Kernel::UserProcessScheduler::The().GetCurrentProcess(); + + if (!process) + Kernel::ke_stop(RUNTIME_CHECK_PAGE); + + process.Leak().ProcessSignal.SignalIP = 0UL; + process.Leak().ProcessSignal.SignalID = SIGKILL; + process.Leak().ProcessSignal.PreviousStatus = process.Leak().Status; + + kcout << "Kernel: PRCFROZE status set..\r"; + + process.Leak().Status = Kernel::ProcessStatusKind::kFrozen; + + process.Leak().Crash(); + + Kernel::ke_stop(RUNTIME_CHECK_UNEXCPECTED); +} + +/// @brief Handle any generic fault. +/// @param rsp +EXTERN_C void idt_handle_generic(Kernel::UIntPtr rsp) +{ + kcout << "Kernel: Generic Process Fault.\r"; + + auto process = Kernel::UserProcessScheduler::The().GetCurrentProcess(); + + if (!process) + Kernel::ke_stop(RUNTIME_CHECK_PAGE); + + process.Leak().ProcessSignal.SignalIP = 0UL; + process.Leak().ProcessSignal.SignalID = SIGKILL; + process.Leak().ProcessSignal.PreviousStatus = process.Leak().Status; + + kcout << "Kernel: PRCFROZE status set..\r"; + + process.Leak().Status = Kernel::ProcessStatusKind::kFrozen; + + process.Leak().Crash(); + + Kernel::ke_stop(RUNTIME_CHECK_UNEXCPECTED); +} + +EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip) +{ + auto process = Kernel::UserProcessScheduler::The().GetCurrentProcess(); + + if (!process) + Kernel::ke_stop(RUNTIME_CHECK_PAGE); + + kcout << "Kernel: Process RIP: " << Kernel::hex_number(rip) << endl; + kcout << "Kernel: SIGTRAP set.\r"; + + process.Leak().ProcessSignal.SignalIP = rip; + process.Leak().ProcessSignal.SignalID = SIGTRAP; + + process.Leak().ProcessSignal.PreviousStatus = process.Leak().Status; + + kcout << "Kernel: PRCFROZE status set..\r"; + + process.Leak().Status = Kernel::ProcessStatusKind::kFrozen; +} + +/// @brief Handle #UD fault. +/// @param rsp +EXTERN_C void idt_handle_ud(Kernel::UIntPtr rsp) +{ + kcout << "Kernel: Undefined Opcode.\r"; + + auto process = Kernel::UserProcessScheduler::The().GetCurrentProcess(); + + if (!process) + Kernel::ke_stop(RUNTIME_CHECK_PAGE); + + process.Leak().ProcessSignal.SignalIP = 0UL; + process.Leak().ProcessSignal.SignalID = SIGKILL; + process.Leak().ProcessSignal.PreviousStatus = process.Leak().Status; + + kcout << "Kernel: PRCFROZE status set..\r"; + + process.Leak().Status = Kernel::ProcessStatusKind::kFrozen; + + process.Leak().Crash(); + + Kernel::ke_stop(RUNTIME_CHECK_UNEXCPECTED); +} + +/// @brief Enter syscall from assembly. +/// @param stack the stack pushed from assembly routine. +/// @return nothing. +EXTERN_C Kernel::Void hal_system_call_enter(Kernel::UIntPtr rcx_syscall_index, Kernel::UIntPtr rdx_syscall_struct) +{ + if (rcx_syscall_index < kSyscalls.Count()) + { + kcout << "syscall: Enter Syscall.\r"; + + if (kSyscalls[rcx_syscall_index].fHooked) + { + if (kSyscalls[rcx_syscall_index].fProc) + { + (kSyscalls[rcx_syscall_index].fProc)((Kernel::VoidPtr)rdx_syscall_struct); + } + else + { + kcout << "syscall: syscall isn't valid at all! (is nullptr)\r"; + } + } + else + { + kcout << "syscall: syscall isn't hooked at all! (is set to false)\r"; + } + + kcout << "syscall: Exit Syscall.\r"; + } +} + +/// @brief Enter Kernel call from assembly (DDK only). +/// @param stack the stack pushed from assembly routine. +/// @return nothing. +EXTERN_C Kernel::Void hal_kernel_call_enter(Kernel::UIntPtr rcx_kerncall_index, Kernel::UIntPtr rdx_kerncall_struct) +{ + if (rcx_kerncall_index < kKerncalls.Count()) + { + kcout << "kerncall: Enter Kernel Call List.\r"; + + if (kKerncalls[rcx_kerncall_index].fHooked) + { + if (kKerncalls[rcx_kerncall_index].fProc) + { + (kKerncalls[rcx_kerncall_index].fProc)((Kernel::VoidPtr)rdx_kerncall_struct); + } + else + { + kcout << "kerncall: Kernel call isn't valid at all! (is nullptr)\r"; + } + } + else + { + kcout << "kerncall: Kernel call isn't hooked at all! (is set to false)\r"; + } + + kcout << "kerncall: Exit Kernel Call List.\r"; + } +} diff --git a/dev/Kernel/HALKit/AMD64/HalCoreScheduler.cc b/dev/Kernel/HALKit/AMD64/HalCoreScheduler.cc new file mode 100644 index 00000000..f6835b8f --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/HalCoreScheduler.cc @@ -0,0 +1,240 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Needed for SMP. +#include + +#define kApicSignature "APIC" + +#define kAPIC_ICR_Low 0x300 +#define kAPIC_ICR_High 0x310 +#define kAPIC_SIPI_Vector 0x00500 +#define kAPIC_EIPI_Vector 0x00400 + +#define kAPIC_BASE_MSR 0x1B +#define kAPIC_BASE_MSR_BSP 0x100 +#define kAPIC_BASE_MSR_ENABLE 0x800 + +#define cSMPMax (32U) + +/// @note: _hal_switch_context is internal + +/////////////////////////////////////////////////////////////////////////////////////// + +//! NOTE: fGSI stands 'Field Global System Interrupt' + +/////////////////////////////////////////////////////////////////////////////////////// + +namespace Kernel::HAL +{ + struct MADT_TABLE; + + EXTERN_C Void _hal_spin_core(Void); + + STATIC struct MADT_TABLE* kMADTBlock = nullptr; + STATIC Bool kSMPAware = false; + STATIC Int64 kSMPCount = 0; + + STATIC Int32 cSMPInterrupt = 0; + STATIC UInt64 kAPICLocales[cSMPMax] = {0}; + STATIC VoidPtr kRawMADT = nullptr; + + /// @brief Multiple APIC Descriptor Table. + struct MADT_TABLE final : public SDT + { + UInt32 Address; // Madt address + UInt8 Flags; // Madt flags + + struct + { + UInt8 Type; + UInt8 Len; + + union { + struct + { + UInt8 IoID; + UInt8 Resv; + UInt32 IoAddress; + UInt32 GISBase; + } IOAPIC; + + struct + { + UInt8 Source; + UInt8 IRQSource; + UInt32 GSI; + UInt16 Flags; + } IOAPIC_NMI; + + struct + { + UInt8 ProcessorID; + UInt16 Flags; + UInt8 LINT; + } LAPIC; + + struct + { + UInt16 Reserved; + UInt64 Address; + } LAPIC_ADDRESS_OVERRIDE; + + struct + { + UInt16 Reserved; + UInt32 x2APICID; + UInt32 Flags; + UInt32 AcpiID; + } LAPIC_ADDRESS; + }; + } List[]; // Records List + }; + + /////////////////////////////////////////////////////////////////////////////////////// + + /***********************************************************************************/ + /// @brief Send IPI command to APIC. + /// @param apicId programmable interrupt controller id. + /// @param vector vector interrupt. + /// @param targetAddress target APIC adress. + /// @return + /***********************************************************************************/ + + Void hal_send_start_ipi(UInt32 apicId, UInt8 vector, UInt32 targetAddress) + { + Kernel::ke_dma_write(targetAddress, kAPIC_ICR_High, (apicId << 24)); + Kernel::ke_dma_write(targetAddress, kAPIC_ICR_Low, kAPIC_SIPI_Vector | vector); + } + + /***********************************************************************************/ + /// @brief Send end IPI for CPU. + /// @param apicId + /// @param vector + /// @param targetAddress + /// @return + /***********************************************************************************/ + Void hal_send_end_ipi(UInt32 apicId, UInt8 vector, UInt32 targetAddress) + { + Kernel::ke_dma_write(targetAddress, kAPIC_ICR_High, (apicId << 24)); + Kernel::ke_dma_write(targetAddress, kAPIC_ICR_Low, kAPIC_EIPI_Vector | vector); + } + + STATIC struct PROCESS_CONTROL_BLOCK final + { + HAL::StackFramePtr f_Frame; + UInt8* f_Stack; + VoidPtr f_Image; + } kProcessBlocks[kSchedProcessLimitPerTeam] = {0}; + + EXTERN_C HAL::StackFramePtr mp_get_current_context(Int64 pid) + { + const auto process_index = pid % kSchedProcessLimitPerTeam; + return kProcessBlocks[process_index].f_Frame; + } + + EXTERN_C Bool mp_register_process(VoidPtr image, UInt8* stack_ptr, HAL::StackFramePtr stack_frame, ProcessID pid) + { + MUST_PASS(image && stack_ptr && stack_frame); + + const auto process_index = pid % kSchedProcessLimitPerTeam; + + kProcessBlocks[process_index].f_Frame = stack_frame; + kProcessBlocks[process_index].f_Stack = stack_ptr; + kProcessBlocks[process_index].f_Image = image; + + if (!mp_is_smp()) + { + /// TODO: Switch from process_index in hash list. + } + + return Yes; + } + + /***********************************************************************************/ + /// @brief Is the current config SMP aware? + /// @return True if YES, False if not. + /***********************************************************************************/ + Bool mp_is_smp(Void) noexcept + { + return kSMPAware; + } + + /***********************************************************************************/ + /// @brief Fetch and enable SMP scheduler. + /// @param vendor_ptr SMP containing structure. + /***********************************************************************************/ + Void mp_get_cores(VoidPtr vendor_ptr) noexcept + { + if (!vendor_ptr) + return; + + auto hw_and_pow_int = PowerFactoryInterface(vendor_ptr); + kRawMADT = hw_and_pow_int.Find(kApicSignature).Leak().Leak(); + + kMADTBlock = reinterpret_cast(kRawMADT); + kSMPAware = NO; + + if (kMADTBlock) + { + SizeT index = 0; + + // reset values. + + cSMPInterrupt = 0; + kSMPCount = 0; + + kcout << "SMP: Probing Local APICs...\r"; + + UIntPtr madt_address = kMADTBlock->Address; + + while (Yes) + { + if (kMADTBlock->List[index].Type > 9 || + kSMPCount > cSMPMax) + break; + + switch (kMADTBlock->List[index].Type) + { + case 0x00: { + kAPICLocales[index] = kMADTBlock->List[index].LAPIC.ProcessorID; + kcout << "SMP: APIC ID: " << number(kAPICLocales[index]) << endl; + ++kSMPCount; + break; + } + case 0x05: { + madt_address = kMADTBlock->List[index].LAPIC_ADDRESS_OVERRIDE.Address; + kcout << "SMP: APIC address: " << number(madt_address) << endl; + break; + } + } + + ++index; + } + + kcout << "SMP: number of cores: " << number(kSMPCount) << endl; + + // Kernel is now SMP aware. + // That means that the scheduler is now available (on MP Kernels) + + kSMPAware = true; + + /// TODO: Notify Boot AP that it must start. + } + } +} // namespace Kernel::HAL + +/////////////////////////////////////////////////////////////////////////////////////// diff --git a/dev/Kernel/HALKit/AMD64/HalDebugOutput.cc b/dev/Kernel/HALKit/AMD64/HalDebugOutput.cc new file mode 100644 index 00000000..41279d27 --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/HalDebugOutput.cc @@ -0,0 +1,146 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include +#include +#include + +namespace Kernel +{ + enum CommStatus + { + kStateInvalid, + kStateReady = 0xCF, + kStateTransmit = 0xFC, + kStateCnt = 3 + }; + + namespace Detail + { + constexpr short PORT = 0x3F8; + + static int kState = kStateInvalid; + + /// @brief Init COM1. + /// @return + bool hal_serial_init() noexcept + { +#ifdef __DEBUG__ + if (kState == kStateReady || kState == kStateTransmit) + return true; + + HAL::rt_out8(PORT + 1, 0x00); // Disable all interrupts + HAL::rt_out8(PORT + 3, 0x80); // Enable DLAB (set baud rate divisor) + HAL::rt_out8(PORT + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud + HAL::rt_out8(PORT + 1, 0x00); // (hi byte) + HAL::rt_out8(PORT + 3, 0x03); // 8 bits, no parity, one stop bit + HAL::rt_out8(PORT + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold + HAL::rt_out8(PORT + 4, 0x0B); // IRQs enabled, RTS/DSR set + HAL::rt_out8(PORT + 4, 0x1E); // Set in loopback mode, test the serial chip + HAL::rt_out8(PORT + 0, 0xAE); // Test serial chip (send byte 0xAE and check if + // serial returns same byte) + + // Check if serial is faulty (i.e: not same byte as sent) + if (HAL::rt_in8(PORT) != 0xAE) + { + ke_stop(RUNTIME_CHECK_HANDSHAKE); + } + + kState = kStateReady; + + // If serial is not faulty set it in normal operation mode + // (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled) + HAL::rt_out8(Detail::PORT + 4, 0x0F); +#endif // __DEBUG__ + + return true; + } + } // namespace Detail + + TerminalDevice::~TerminalDevice() = default; + + EXTERN_C void ke_io_write(const Char* bytes) + { +#ifdef __DEBUG__ + Detail::hal_serial_init(); + + if (!bytes || Detail::kState != kStateReady) + return; + if (*bytes == 0) + return; + + Detail::kState = kStateTransmit; + + SizeT index = 0; + SizeT len = 0; + + index = 0; + len = rt_string_len(bytes, 255); + + while (index < len) + { + if (bytes[index] == '\r') + HAL::rt_out8(Detail::PORT, '\r'); + + HAL::rt_out8(Detail::PORT, bytes[index] == '\r' ? '\n' : bytes[index]); + ++index; + } + + Detail::kState = kStateReady; +#endif // __DEBUG__ + } + + EXTERN_C void ke_io_read(const Char* bytes) + { +#ifdef __DEBUG__ + Detail::hal_serial_init(); + + if (!bytes || Detail::kState != kStateReady) + return; + + Detail::kState = kStateTransmit; + + SizeT index = 0; + + ///! TODO: Look on how to wait for the UART to complete. + while (true) + { + auto in = HAL::rt_in8(Detail::PORT); + + ///! If enter pressed then break. + if (in == 0xD) + { + break; + } + + if (in < '0' || in < 'A' || in < 'a') + { + if (in != '@' || in != '!' || in != '?' || in != '.' || in != '/' || + in != ':') + { + continue; + } + } + + ((char*)bytes)[index] = in; + + ++index; + } + + ((char*)bytes)[index] = 0; + + Detail::kState = kStateReady; +#endif // __DEBUG__ + } + + TerminalDevice TerminalDevice::The() noexcept + { + TerminalDevice out(Kernel::ke_io_write, Kernel::ke_io_read); + return out; + } + +} // namespace Kernel diff --git a/dev/Kernel/HALKit/AMD64/HalDebugPort.cc b/dev/Kernel/HALKit/AMD64/HalDebugPort.cc new file mode 100644 index 00000000..e9b2e3b5 --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/HalDebugPort.cc @@ -0,0 +1,40 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +//! @file DebuggerPort.cc +//! @brief UART debug via packets. + +#include +#include + +// after that we have start of additional data. + +namespace Kernel +{ + void rt_debug_listen(DebuggerPortHeader* theHook) noexcept + { + if (theHook == nullptr) + return; + + for (UInt32 i = 0U; i < kDebugMaxPorts; ++i) + { + HAL::rt_out16(theHook->fPort[i], kDebugMag0); + HAL::rt_wait_400ns(); + + HAL::rt_out16(theHook->fPort[i], kDebugMag1); + HAL::rt_wait_400ns(); + + HAL::rt_out16(theHook->fPort[i], kDebugMag2); + HAL::rt_wait_400ns(); + + HAL::rt_out16(theHook->fPort[i], kDebugMag3); + HAL::rt_wait_400ns(); + + if (HAL::rt_in16(theHook->fPort[i] != kDebugUnboundPort)) + ++theHook->fBoundCnt; + } + } +} // namespace Kernel diff --git a/dev/Kernel/HALKit/AMD64/HalDescriptorLoader.cc b/dev/Kernel/HALKit/AMD64/HalDescriptorLoader.cc new file mode 100644 index 00000000..e5a3700b --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/HalDescriptorLoader.cc @@ -0,0 +1,126 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include + +#define kPITDefaultTicks (100U) + +namespace Kernel::HAL +{ + namespace Detail + { + STATIC ::Kernel::Detail::AMD64::InterruptDescriptorAMD64 + kInterruptVectorTable[kKernelIdtSize] = {}; + + STATIC void hal_set_irq_mask(UInt8 irql); + STATIC void hal_clear_irq_mask(UInt8 irql); + + STATIC Void hal_enable_pit(UInt16 ticks) noexcept + { + if (ticks == 0) + ticks = kPITDefaultTicks; + + // Configure PIT to receieve scheduler interrupts. + + UInt16 cCommonDivisor = kPITFrequency / ticks; // 100 Hz. + + HAL::rt_out8(kPITControlPort, 0x36); // Command to PIT + HAL::rt_out8(kPITChannel0Port, cCommonDivisor & 0xFF); // Send low byte + HAL::rt_out8(kPITChannel0Port, (cCommonDivisor >> 8) & 0xFF); // Send high byte + + hal_clear_irq_mask(32); + } + + STATIC void hal_set_irq_mask(UInt8 irql) + { + UInt16 port; + UInt8 value; + + if (irql < 8) + { + port = kPICData; + } + else + { + port = kPIC2Data; + irql -= 8; + } + + value = rt_in8(port) | (1 << irql); + rt_out8(port, value); + } + + STATIC void hal_clear_irq_mask(UInt8 irql) + { + UInt16 port; + UInt8 value; + + if (irql < 8) + { + port = kPICData; + } + else + { + port = kPIC2Data; + irql -= 8; + } + + value = rt_in8(port) & ~(1 << irql); + rt_out8(port, value); + } + } // namespace Detail + + /// @brief Loads the provided Global Descriptor Table. + /// @param gdt + /// @return + Void GDTLoader::Load(RegisterGDT& gdt) + { + hal_load_gdt(gdt); + } + + Void IDTLoader::Load(Register64& idt) + { + rt_cli(); + + const Int16 kPITTickForScheduler = kPITDefaultTicks; + + volatile ::Kernel::UIntPtr** ptr_ivt = (volatile ::Kernel::UIntPtr**)idt.Base; + + for (SizeT idt_indx = 0; idt_indx < kKernelIdtSize; ++idt_indx) + { + Detail::kInterruptVectorTable[idt_indx].Selector = kIDTSelector; + Detail::kInterruptVectorTable[idt_indx].Ist = 0; + Detail::kInterruptVectorTable[idt_indx].TypeAttributes = kInterruptGate; + Detail::kInterruptVectorTable[idt_indx].OffsetLow = ((UIntPtr)ptr_ivt[idt_indx] & 0xFFFF); + Detail::kInterruptVectorTable[idt_indx].OffsetMid = (((UIntPtr)ptr_ivt[idt_indx] >> 16) & 0xFFFF); + Detail::kInterruptVectorTable[idt_indx].OffsetHigh = + (((UIntPtr)ptr_ivt[idt_indx] >> 32) & 0xFFFFFFFF); + + Detail::kInterruptVectorTable[idt_indx].Zero = 0; + } + + idt.Base = (UIntPtr)&Detail::kInterruptVectorTable[0]; + idt.Limit = sizeof(::Kernel::Detail::AMD64::InterruptDescriptorAMD64) * + (kKernelIdtSize); + + hal_load_idt(idt); + + Detail::hal_enable_pit(kPITTickForScheduler); + + rt_sti(); + } + + void GDTLoader::Load(Ref& gdt) + { + GDTLoader::Load(gdt.Leak()); + } + + void IDTLoader::Load(Ref& idt) + { + IDTLoader::Load(idt.Leak()); + } +} // namespace Kernel::HAL diff --git a/dev/Kernel/HALKit/AMD64/HalInterruptAPI.asm b/dev/Kernel/HALKit/AMD64/HalInterruptAPI.asm new file mode 100644 index 00000000..9d1bf367 --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/HalInterruptAPI.asm @@ -0,0 +1,406 @@ +;; /* +;; * --------------------------------------------------- +;; * +;; * Copyright (C) 2024, TQ B.V, all rights reserved. +;; * +;; * File: HalInterruptAPI.asm +;; * Purpose: Interrupt API, redirect raw interrupts into their handlers. +;; * +;; * --------------------------------------------------- +;; */ + +[bits 64] + +%define kInterruptId 0x21 + +%macro IntExp 1 +global __ZKA_INT_%1 +__ZKA_INT_%1: + cli + + mov al, 0x20 + out 0x20, al + out 0xA0, al + + sti + o64 iret +%endmacro + +%macro IntNormal 1 +global __ZKA_INT_%1 +__ZKA_INT_%1: + cli + + mov al, 0x20 + out 0x20, al + out 0xA0, al + + sti + o64 iret +%endmacro + +; This file handles the core interrupt table +; Last edited 31/01/24 + +global ke_handle_irq +global kInterruptVectorTable + +extern idt_handle_gpf +extern idt_handle_pf +extern ke_io_write +extern idt_handle_ud +extern idt_handle_generic +extern idt_handle_breakpoint + +section .text + +IntNormal 0 +IntNormal 1 +IntNormal 2 + +section .data + +__ZKA_INT_3_GET_RIP: + dq 0 +__ZKA_INT_3_GET_RIP_END: + +section .text + +;; @brief Triggers a breakpoint and freeze the process. RIP is also fetched. +__ZKA_INT_3: + cli + + mov al, 0x20 + out 0x20, al + out 0xA0, al + + push rax + mov rax, idt_handle_breakpoint + + lea rcx, [rel __ZKA_INT_3_GET_RIP] + sub rcx, 16 + mov [rcx], rcx + + call rax + pop rax + + sti + o64 iret + +IntNormal 4 +IntNormal 5 + +;; Invalid opcode interrupt +__ZKA_INT_6: + cli + + mov al, 0x20 + out 0x20, al + out 0xA0, al + + push rax + mov rax, idt_handle_ud + + mov rcx, rsp + + call rax + pop rax + + sti + o64 iret + +IntNormal 7 + +;; Invalid opcode interrupt +__ZKA_INT_8: + cli + + mov al, 0x20 + out 0x20, al + out 0xA0, al + + push rax + mov rax, idt_handle_generic + + mov rcx, rsp + + call rax + pop rax + + sti + o64 iret + +IntNormal 9 +IntExp 10 +IntExp 11 + +IntExp 12 + +__ZKA_INT_13: + cli + + mov al, 0x20 + out 0x20, al + out 0xA0, al + + push rax + mov rax, idt_handle_gpf + + mov rcx, rsp + + call rax + pop rax + + sti + o64 iret + +__ZKA_INT_14: + cli + + mov al, 0x20 + out 0x20, al + out 0xA0, al + push rax + mov rax, idt_handle_pf + + mov rcx, rsp + + call rax + pop rax + + sti + o64 iret + +IntNormal 15 +IntNormal 16 +IntExp 17 +IntNormal 18 +IntNormal 19 +IntNormal 20 +IntNormal 21 + +IntNormal 22 + +IntNormal 23 +IntNormal 24 +IntNormal 25 +IntNormal 26 +IntNormal 27 +IntNormal 28 +IntNormal 29 +IntExp 30 +IntNormal 31 + +[extern idt_handle_scheduler] + +__ZKA_INT_32: + cli + + mov al, 0x20 + out 0x20, al + out 0xA0, al + + push rax + mov rcx, rsp + call idt_handle_scheduler + pop rax + + sti + o64 iret + +IntNormal 33 + +IntNormal 34 +IntNormal 35 +IntNormal 36 +IntNormal 37 +IntNormal 38 +IntNormal 39 +IntNormal 40 + +IntNormal 41 + +IntNormal 42 +IntNormal 43 +IntNormal 44 +IntNormal 45 +IntNormal 46 +IntNormal 47 +IntNormal 48 +IntNormal 49 + +[extern hal_system_call_enter] +[extern hal_kernel_call_enter] + +__ZKA_INT_50: + cli + + mov al, 0x20 + out 0x20, al + out 0xA0, al + + push rax + mov rax, hal_system_call_enter + + mov rcx, r8 + mov rdx, r9 + + call rax + pop rax + + sti + + o64 iret + +__ZKA_INT_51: + cli + + mov al, 0x20 + out 0x20, al + out 0xA0, al + + push rax + mov rax, hal_kernel_call_enter + + mov rcx, r8 + mov rdx, r9 + + call rax + pop rax + + sti + + o64 iret + +IntNormal 52 + +IntNormal 53 +IntNormal 54 +IntNormal 55 +IntNormal 56 +IntNormal 57 +IntNormal 58 +IntNormal 59 +IntNormal 60 + +%assign i 61 +%rep 195 + IntNormal i +%assign i i+1 +%endrep + +section .text + +[global hal_load_gdt] + +hal_load_gdt: + cld + + lgdt [rcx] + + mov ax, 0x10 + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov ss, ax + + mov rax, 0x08 + push rax + push hal_reload_segments + + o64 retf + +extern hal_real_init + +hal_reload_segments: + std + ;; Write address of syscall handler. + mov rdx, [mp_system_call_handler] + shr rdx, 32 + mov rcx, 0xC0000082 + wrmsr + + ;; Set segments of syscall handler. + + xor rax, rax + mov rdx, 0x230008 + mov rcx, 0xC0000081 + wrmsr + + mov ecx, 0xC0000080 + rdmsr + or eax, 1 + wrmsr + + jmp hal_real_init + ret + +global hal_load_idt +global hal_user_code_start + +extern hal_system_call_enter +global mp_system_call_handler + +mp_system_call_handler: + + push r8 + push r9 + push r10 + push r11 + push r12 + push r13 + push r14 + push r15 + + jmp hal_system_call_enter + + pop r15 + pop r14 + pop r13 + pop r12 + pop r11 + pop r10 + pop r9 + pop r8 + + o64 sysret + +hal_load_idt: + lidt [rcx] + + ; Master PIC initialization + mov al, 0x11 ; Start initialization in cascade mode + out 0x20, al ; Send initialization command to Master PIC + out 0xA0, al ; Send initialization command to Slave PIC + + ; Remap the PIC to use vectors 32-39 for Master and 40-47 for Slave + mov al, 0x20 ; Set Master PIC offset to 32 + out 0x21, al ; Send offset to Master PIC + + mov al, 0x28 ; Set Slave PIC offset to 40 + out 0xA1, al ; Send offset to Slave PIC + + ; Configure Master PIC to inform Slave PIC at IRQ2 + mov al, 0x04 ; Tell Master PIC there is a Slave PIC at IRQ2 + out 0x21, al + + ; Configure Slave PIC identity + mov al, 0x02 ; Tell Slave PIC its cascade identity + out 0xA1, al + + ; Set both PICs to 8086 mode + mov al, 0x01 ; 8086 mode + out 0x21, al + out 0xA1, al + + ret + +section .data + +kInterruptVectorTable: + %assign i 0 + %rep 256 + dq __ZKA_INT_%+i + %assign i i+1 + %endrep diff --git a/dev/Kernel/HALKit/AMD64/HalKernelMain.cc b/dev/Kernel/HALKit/AMD64/HalKernelMain.cc new file mode 100644 index 00000000..a831cbc2 --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/HalKernelMain.cc @@ -0,0 +1,103 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +EXTERN_C Kernel::VoidPtr kInterruptVectorTable[]; +EXTERN_C Kernel::VoidPtr mp_user_switch_proc; +EXTERN_C Kernel::Char mp_user_switch_proc_stack_begin[]; + +EXTERN_C Kernel::rtl_ctor_kind __CTOR_LIST__[]; +EXTERN_C Kernel::VoidPtr __DTOR_LIST__; + +EXTERN_C Kernel::Void rtl_kernel_main(Kernel::SizeT argc, char** argv, char** envp, Kernel::SizeT envp_len); + +STATIC Kernel::Void hal_init_cxx_ctors() +{ + for (Kernel::SizeT index = 0UL; __CTOR_LIST__[index] != __DTOR_LIST__; ++index) + { + Kernel::rtl_ctor_kind constructor_cxx = (Kernel::rtl_ctor_kind)__CTOR_LIST__[index]; + constructor_cxx(); + } +} + +/// @brief Kernel init procedure. +EXTERN_C void hal_init_platform( + Kernel::HEL::BootInfoHeader* handover_hdr) +{ + kHandoverHeader = handover_hdr; + + if (kHandoverHeader->f_Magic != kHandoverMagic && + kHandoverHeader->f_Version != kHandoverVersion) + { + return; + } + + hal_init_cxx_ctors(); + + /************************************** */ + /* INITIALIZE BIT MAP. */ + /************************************** */ + + kKernelBitMpSize = kHandoverHeader->f_BitMapSize; + kKernelBitMpStart = reinterpret_cast( + reinterpret_cast(kHandoverHeader->f_BitMapStart)); + + /************************************** */ + /* INITIALIZE GDT AND SEGMENTS. */ + /************************************** */ + + STATIC CONST auto kGDTEntriesCount = 6; + + /* GDT, mostly descriptors for user and kernel segments. */ + STATIC Kernel::HAL::Detail::ZKA_GDT_ENTRY ALIGN(0x08) kGDTArray[kGDTEntriesCount] = { + {.fLimitLow = 0, .fBaseLow = 0, .fBaseMid = 0, .fAccessByte = 0x00, .fFlags = 0x00, .fBaseHigh = 0}, // Null entry + {.fLimitLow = 0xFFFF, .fBaseLow = 0, .fBaseMid = 0, .fAccessByte = 0x9A, .fFlags = 0xAF, .fBaseHigh = 0}, // Kernel code + {.fLimitLow = 0xFFFF, .fBaseLow = 0, .fBaseMid = 0, .fAccessByte = 0x92, .fFlags = 0xCF, .fBaseHigh = 0}, // Kernel data + {.fLimitLow = 0xFFFF, .fBaseLow = 0, .fBaseMid = 0, .fAccessByte = 0xF2, .fFlags = 0xCF, .fBaseHigh = 0}, // User data + {.fLimitLow = 0xFFFF, .fBaseLow = 0, .fBaseMid = 0, .fAccessByte = 0xFA, .fFlags = 0xAF, .fBaseHigh = 0}, // User code + }; + + // Load memory descriptors. + Kernel::HAL::RegisterGDT gdt_reg; + + gdt_reg.Base = reinterpret_cast(kGDTArray); + gdt_reg.Limit = (sizeof(Kernel::HAL::Detail::ZKA_GDT_ENTRY) * kGDTEntriesCount) - 1; + + //! GDT will load hal_read_init after it successfully loads the segments. + Kernel::HAL::GDTLoader gdt_loader; + gdt_loader.Load(gdt_reg); + + Kernel::ke_stop(RUNTIME_CHECK_BOOTSTRAP); +} + +EXTERN_C Kernel::Void hal_real_init(Kernel::Void) noexcept +{ + CG::CGDrawBackground(); + + rtl_kernel_main(0, nullptr, nullptr, 0); + + if (kHandoverHeader->f_HardwareTables.f_MultiProcessingEnabled) + Kernel::HAL::mp_get_cores(kHandoverHeader->f_HardwareTables.f_VendorPtr); + + Kernel::HAL::Register64 idt_reg; + idt_reg.Base = (Kernel::UIntPtr)kInterruptVectorTable; + + Kernel::HAL::IDTLoader idt_loader; + idt_loader.Load(idt_reg); + + while (YES) + { + } +} diff --git a/dev/Kernel/HALKit/AMD64/HalPagingMgrAMD64.cc b/dev/Kernel/HALKit/AMD64/HalPagingMgrAMD64.cc new file mode 100644 index 00000000..b87aed5c --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/HalPagingMgrAMD64.cc @@ -0,0 +1,168 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + + File: HalPagingMgr.cc + Purpose: Platform Paging Manager.. + +------------------------------------------- */ + +#include +#include + +namespace Kernel::HAL +{ + typedef UInt32 PageTableIndex; + + /***********************************************************************************/ + /// \brief Page store type. + /***********************************************************************************/ + struct ZKA_PAGE_STORE final + { + struct + { + PDE* fPde{nullptr}; + PTE* fPte{nullptr}; + VoidPtr fVAddr{nullptr}; + } fInternalStore; + + Bool fStoreOp{No}; // Store operation is in progress. + + bool IsValidPage(PTE* pte) + { + return pte && pte->Present; + } + + bool IsWRPage(PTE* pte) + { + return pte && pte->Wr; + } + + bool IsUserPage(PTE* pte) + { + return pte && pte->User; + } + + static ZKA_PAGE_STORE& The() + { + static ZKA_PAGE_STORE the; + return the; + } + }; + + /***********************************************************************************/ + /// \brief Retrieve the page status of a PTE. + /// \param pte Page Table Entry pointer. + /***********************************************************************************/ + STATIC Void mmi_page_status(PTE* pte) + { + kcout << (pte->Present ? "Present" : "Not Present") << endl; + kcout << (pte->Wr ? "W/R" : "Not W/R") << endl; + kcout << (pte->ExecDisable ? "NX" : "Not NX") << endl; + kcout << (pte->User ? "User" : "Not User") << endl; + } + + STATIC Int32 mmi_map_page_table_entry(VoidPtr virtual_address, UInt32 flags, ZKA_PTE* pt_entry, ZKA_PDE* pd_entry); + + /***********************************************************************************/ + /// @brief Maps or allocates a page from virtual_address. + /// @param virtual_address a valid virtual address. + /// @param phys_addr point to physical address. + /// @param flags the flags to put on the page. + /// @return Status code of page manipulation process. + /***********************************************************************************/ + EXTERN_C Int32 mm_map_page(VoidPtr virtual_address, UInt32 flags) + { + if (!virtual_address || + !flags) + return 0; + + // Constants for table index bits + const UInt64 cPmlIndexMask = 0x1FFULL; // Mask for PML4, PDPT, PD, PT index (9 bits) + const UInt64 cPtIndexMask = 0xFFFULL; // Mask for page table index (12 bits) + + UInt64 cr3 = (UInt64)hal_read_cr3(); + + ZKA_PAGE_STORE& page_store = ZKA_PAGE_STORE::The(); + + // Extract the indices from the virtual address + UInt64 pml4_index = ((UIntPtr)virtual_address >> 39) & cPmlIndexMask; + UInt64 pdpt_index = ((UIntPtr)virtual_address >> 30) & cPmlIndexMask; + UInt64 pd_index = ((UIntPtr)virtual_address >> 21) & cPmlIndexMask; + UInt64 pt_index = ((UIntPtr)virtual_address >> 12) & cPmlIndexMask; + + page_store.fStoreOp = Yes; + + if (page_store.fInternalStore.fVAddr == virtual_address) + { + page_store.fStoreOp = No; + return mmi_map_page_table_entry(page_store.fInternalStore.fVAddr, flags, page_store.fInternalStore.fPte, page_store.fInternalStore.fPde); + } + + const auto cPmlEntrySize = 8; + + // Read the PML4 entry from memory + UInt64 pml4_base = cr3 & ~cPtIndexMask; // CR3 points to the PML4 table base, mask off lower bits + UInt64 pml4_entry = (pml4_base + pml4_index * cPmlEntrySize); // Each entry is 8 bytes + + // Read the PDPT entry + UInt64 pdpt_base = pml4_entry & ~cPtIndexMask; // Get the PDPT base physical address + UInt64 pdpt_entry = (pdpt_base + pdpt_index * cPmlEntrySize); + + // Read the PD entry + UInt64 pd_base = pdpt_entry & ~cPtIndexMask; // Get the Page Directory base physical address + UInt64 pd_entry = (pd_base + pd_index * cPmlEntrySize); + + // Read the PT entry + UInt64 pt_base = pd_entry & ~cPtIndexMask; // Get the Page Table base physical address + UInt64 pt_entry = (pt_base + pt_index * cPmlEntrySize); + + // Lastly, grab the pte entry. + ZKA_PDE* pde_struct = reinterpret_cast(pt_base); + + return mmi_map_page_table_entry(virtual_address, flags, pde_struct->fEntries[pt_entry], pde_struct); + } + + /***********************************************************************************/ + /// @brief Maps flags for a specific pte. + /// @internal Internal function. + /***********************************************************************************/ + STATIC Int32 mmi_map_page_table_entry(VoidPtr virtual_address, UInt32 flags, ZKA_PTE* pt_entry, ZKA_PDE* pd_entry) + { + if (!pt_entry) + return 1; + + pt_entry->Present = true; + + if (flags & kMMFlagsWr) + pt_entry->Wr = true; + else if (flags & ~kMMFlagsWr) + pt_entry->Wr = false; + + if (flags & kMMFlagsNX) + pt_entry->ExecDisable = true; + else if (flags & ~kMMFlagsNX) + pt_entry->ExecDisable = false; + + if (flags & kMMFlagsUser) + pt_entry->User = true; + else if (flags & ~kMMFlagsUser) + pt_entry->User = false; + + hal_invl_tlb(reinterpret_cast(pt_entry)); + + mmi_page_status(pt_entry); + + ZKA_PAGE_STORE& page_store = ZKA_PAGE_STORE::The(); + + // Update Internal store. + + page_store.fInternalStore.fPde = pd_entry; + page_store.fInternalStore.fPte = pt_entry; + page_store.fInternalStore.fVAddr = virtual_address; + + page_store.fStoreOp = No; + + return 0; + } +} // namespace Kernel::HAL diff --git a/dev/Kernel/HALKit/AMD64/HalRoutineWait.s b/dev/Kernel/HALKit/AMD64/HalRoutineWait.s new file mode 100644 index 00000000..89051ba4 --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/HalRoutineWait.s @@ -0,0 +1,11 @@ +.globl rt_wait_400ns + +.section .text +rt_wait_400ns: + jmp .loop + pause + .loop: + jmp .loop2 + pause + .loop2: + ret diff --git a/dev/Kernel/HALKit/AMD64/HalTimerAMD64.cc b/dev/Kernel/HALKit/AMD64/HalTimerAMD64.cc new file mode 100644 index 00000000..ade45ebb --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/HalTimerAMD64.cc @@ -0,0 +1,86 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + + File: HalTimer.cc + Purpose: HAL timer + + Revision History: + + 07/07/24: Added file (amlel) + +------------------------------------------- */ + +#include +#include +#include + +// timer slot 0 + +#define cHPETCounterRegValue (0x00) +#define cHPETConfigRegValue (0x20) +#define cHPETCompRegValue (0x24) +#define cHPETInterruptRegValue (0x2C) + +///! BUGS: 0 +///! @file HalTimer.cc +///! @brief Hardware Timer (HPET) + +namespace Kernel::Detail +{ + struct HPET_BLOCK : public Kernel::SDT + { + Kernel::UInt8 hardware_rev_id; + Kernel::UInt8 comparator_count : 5; + Kernel::UInt8 counter_size : 1; + Kernel::UInt8 reserved : 1; + Kernel::UInt8 legacy_replacement : 1; + Kernel::UInt16 pci_vendor_id; + ACPI_ADDRESS address; + Kernel::UInt8 hpet_number; + Kernel::UInt16 minimum_tick; + Kernel::UInt8 page_protection; + } PACKED; +} // namespace Kernel::Detail + +using namespace Kernel; + +HardwareTimer::HardwareTimer(Int64 ms) + : fWaitFor(ms) +{ + auto power = PowerFactoryInterface(kHandoverHeader->f_HardwareTables.f_VendorPtr); + + auto hpet = (Detail::HPET_BLOCK*)power.Find("HPET").Leak().Leak(); + MUST_PASS(hpet); + + fDigitalTimer = (IntPtr*)hpet->address.Address; +} + +HardwareTimer::~HardwareTimer() +{ + fDigitalTimer = nullptr; + fWaitFor = 0; +} + +Int32 HardwareTimer::Wait() noexcept +{ + if (fWaitFor < 1) + return 1; + + // if not enabled yet. + if (!(*(fDigitalTimer + cHPETConfigRegValue) & (1 << 0))) + { + *(fDigitalTimer + cHPETConfigRegValue) |= (1 << 0); // enable it + *(fDigitalTimer + cHPETConfigRegValue) |= (1 << 3); // one shot conf + } + + UInt64 ticks = fWaitFor / ((*(fDigitalTimer) >> 32) & __UINT32_MAX__); + UInt64 prev = *(fDigitalTimer + cHPETCounterRegValue); + + prev += ticks; + + while (*(fDigitalTimer + cHPETCounterRegValue) < (ticks)) + ; + + return 0; +} diff --git a/dev/Kernel/HALKit/AMD64/HalUtils.asm b/dev/Kernel/HALKit/AMD64/HalUtils.asm new file mode 100644 index 00000000..2f141352 --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/HalUtils.asm @@ -0,0 +1,27 @@ +;; /* +;; * ======================================================== +;; * +;; * ZKA +;; * Copyright (C) 2024, TQ B.V, all rights reserved., all rights reserved. +;; * +;; * ======================================================== +;; */ + +[bits 64] + +[global rt_install_tib] + +section .text + +;; changed: rs, fs +;; expected: rcx, rdx + +rt_install_tib: + mov rcx, gs ;; TIB -> Thread Information Block + mov rdx, fs ;; PIB -> Process Information Block + ret + +;; //////////////////////////////////////////////////// ;; + +[extern cBspDone] +[extern kApicMadtAddressesCount] diff --git a/dev/Kernel/HALKit/AMD64/Hypervisor.h b/dev/Kernel/HALKit/AMD64/Hypervisor.h new file mode 100644 index 00000000..f1c56205 --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/Hypervisor.h @@ -0,0 +1,25 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include + +namespace Kernel +{ + MAKE_STRING_ENUM(HYPERVISOR) + ENUM_STRING(Qemu, "TCGTCGTCGTCG"); + ENUM_STRING(KVM, " KVMKVMKVM "); + ENUM_STRING(VMWare, "VMwareVMware"); + ENUM_STRING(VirtualBox, "VBoxVBoxVBox"); + ENUM_STRING(Xen, "XenVMMXenVMM"); + ENUM_STRING(Microsoft, "Microsoft Hv"); + ENUM_STRING(Parallels, " prl hyperv "); + ENUM_STRING(ParallelsAlt, " lrpepyh vr "); + ENUM_STRING(Bhyve, "bhyve bhyve "); + ENUM_STRING(Qnx, " QNXQVMBSQG "); + END_STRING_ENUM() +} // namespace Kernel diff --git a/dev/Kernel/HALKit/AMD64/MBCI/HalMBCI.cc b/dev/Kernel/HALKit/AMD64/MBCI/HalMBCI.cc new file mode 100644 index 00000000..4faa5365 --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/MBCI/HalMBCI.cc @@ -0,0 +1,7 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include diff --git a/dev/Kernel/HALKit/AMD64/PCI/DMA.cc b/dev/Kernel/HALKit/AMD64/PCI/DMA.cc new file mode 100644 index 00000000..192b37ba --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/PCI/DMA.cc @@ -0,0 +1,82 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include + +namespace Kernel +{ + DMAWrapper::operator bool() + { + return fAddress; + } + + bool DMAWrapper::operator!() + { + return !fAddress; + } + + Boolean DMAWrapper::Check(UIntPtr offset) const + { + if (!fAddress) + return false; + if (offset == 0) + return true; + + kcout << "[DMAWrapper::IsIn] Checking offset..\n"; + return reinterpret_cast(fAddress) >= offset; + } + + bool DMAWrapper::Write(const UIntPtr& bit, const UIntPtr& offset) + { + if (!fAddress) + return false; + + kcout << "[DMAWrapper::Write] Writing at address..\n"; + + auto addr = + (volatile UIntPtr*)(reinterpret_cast(fAddress) + offset); + *addr = bit; + + return true; + } + + UIntPtr DMAWrapper::Read(const UIntPtr& offset) + { + kcout << "[DMAWrapper::Read] checking fAddress..\n"; + if (!fAddress) + return 0; + + kcout << "[DMAWrapper::Read] Reading fAddress..\n"; + return *(volatile UIntPtr*)(reinterpret_cast(fAddress) + offset); + ; + } + + UIntPtr DMAWrapper::operator[](const UIntPtr& offset) + { + return this->Read(offset); + } + + OwnPtr> DMAFactory::Construct(OwnPtr& dma) + { + if (!dma) + return {}; + + OwnPtr> dmaOwnPtr = + make_ptr, char*>(reinterpret_cast(dma->fAddress)); + + if (!dmaOwnPtr) + return {}; + + kcout << "Returning the new OwnPtr>!\r"; + return dmaOwnPtr; + } + + DMAWrapper& DMAWrapper::operator=(voidPtr Ptr) + { + fAddress = Ptr; + return *this; + } +} // namespace Kernel diff --git a/dev/Kernel/HALKit/AMD64/PCI/Database.cc b/dev/Kernel/HALKit/AMD64/PCI/Database.cc new file mode 100644 index 00000000..381b63c4 --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/PCI/Database.cc @@ -0,0 +1,11 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include + +namespace Kernel +{ +} diff --git a/dev/Kernel/HALKit/AMD64/PCI/Device.cc b/dev/Kernel/HALKit/AMD64/PCI/Device.cc new file mode 100644 index 00000000..46286a03 --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/PCI/Device.cc @@ -0,0 +1,139 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include + +Kernel::UInt ZKA_PCIReadRaw(Kernel::UInt bar, Kernel::UShort bus, Kernel::UShort dev, Kernel::UShort fun) +{ + Kernel::UInt target = 0x80000000 | ((Kernel::UInt)bus << 16) | + ((Kernel::UInt)dev << 11) | ((Kernel::UInt)fun << 8) | + (bar & 0xFC); + + Kernel::HAL::rt_out32((Kernel::UShort)Kernel::PCI::PciConfigKind::ConfigAddress, + target); + + return Kernel::HAL::rt_in32((Kernel::UShort)Kernel::PCI::PciConfigKind::ConfigData); +} + +void ZKA_PCISetCfgTarget(Kernel::UInt bar, Kernel::UShort bus, Kernel::UShort dev, Kernel::UShort fun) +{ + Kernel::UInt target = 0x80000000 | ((Kernel::UInt)bus << 16) | + ((Kernel::UInt)dev << 11) | ((Kernel::UInt)fun << 8) | + (bar & ~3); + + Kernel::HAL::rt_out32((Kernel::UShort)Kernel::PCI::PciConfigKind::ConfigAddress, + target); +} + +#define PCI_BAR_IO 0x01 +#define PCI_BAR_LOWMEM 0x02 +#define PCI_BAR_64 0x04 +#define PCI_BAR_PREFETCH 0x08 + +namespace Kernel::PCI +{ + Device::Device(UShort bus, UShort device, UShort func, UInt32 bar) + : fBus(bus), fDevice(device), fFunction(func), fBar(bar) + { + } + + Device::~Device() = default; + + UInt Device::Read(UInt bar, Size sz) + { + ZKA_PCISetCfgTarget(bar, fBus, fDevice, fFunction); + + if (sz == 4) + return HAL::rt_in32((UShort)PciConfigKind::ConfigData + (bar & 3)); + if (sz == 2) + return HAL::rt_in16((UShort)PciConfigKind::ConfigData + (bar & 3)); + if (sz == 1) + return HAL::rt_in8((UShort)PciConfigKind::ConfigData + (bar & 3)); + + return 0xFFFF; + } + + void Device::Write(UInt bar, UIntPtr data, Size sz) + { + ZKA_PCISetCfgTarget(bar, fBus, fDevice, fFunction); + + if (sz == 4) + HAL::rt_out32((UShort)PciConfigKind::ConfigData + (fBar & 3), (UInt)data); + if (sz == 2) + HAL::rt_out16((UShort)PciConfigKind::ConfigData + (fBar & 3), (UShort)data); + if (sz == 1) + HAL::rt_out8((UShort)PciConfigKind::ConfigData + (fBar & 3), (UChar)data); + } + + UShort Device::DeviceId() + { + return (UShort)(ZKA_PCIReadRaw(0x0 >> 16, fBus, fDevice, fFunction)); + } + + UShort Device::VendorId() + { + return (UShort)(ZKA_PCIReadRaw(0x0, fBus, fDevice, fFunction) >> 16); + } + + UShort Device::InterfaceId() + { + return (UShort)(ZKA_PCIReadRaw(0x0, fBus, fDevice, fFunction) >> 16); + } + + UChar Device::Class() + { + return (UChar)(ZKA_PCIReadRaw(0x08, fBus, fDevice, fFunction) >> 24); + } + + UChar Device::Subclass() + { + return (UChar)(ZKA_PCIReadRaw(0x08, fBus, fDevice, fFunction) >> 16); + } + + UChar Device::ProgIf() + { + return (UChar)(ZKA_PCIReadRaw(0x08, fBus, fDevice, fFunction) >> 8); + } + + UChar Device::HeaderType() + { + return (UChar)(ZKA_PCIReadRaw(0xC, fBus, fDevice, fFunction) >> 16); + } + + void Device::EnableMmio(UInt32 bar_in) + { + bool enable = Read(bar_in, sizeof(UChar)) | (1 << 1); + Write(bar_in, enable, sizeof(UShort)); + } + + void Device::BecomeBusMaster(UInt32 bar_in) + { + bool enable = Read(bar_in, sizeof(UShort)) | (1 << 2); + Write(bar_in, enable, sizeof(UShort)); + } + + UIntPtr Device::Bar(UInt32 bar_in) + { + UInt32 bar = ZKA_PCIReadRaw(bar_in, fBus, fDevice, fFunction); + return bar; + } + + UShort Device::Vendor() + { + UShort vendor = VendorId(); + + if (vendor != (UShort)PciConfigKind::Invalid) + fDevice = (UShort)Read(0x0, sizeof(UShort)); + + return fDevice; + } + + Device::operator bool() + { + return VendorId() != (UShort)PciConfigKind::Invalid; + } +} // namespace Kernel::PCI diff --git a/dev/Kernel/HALKit/AMD64/PCI/Express.cc b/dev/Kernel/HALKit/AMD64/PCI/Express.cc new file mode 100644 index 00000000..f24c5536 --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/PCI/Express.cc @@ -0,0 +1,11 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include + +namespace Kernel +{ +} diff --git a/dev/Kernel/HALKit/AMD64/PCI/IO.cc b/dev/Kernel/HALKit/AMD64/PCI/IO.cc new file mode 100644 index 00000000..da81d38b --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/PCI/IO.cc @@ -0,0 +1,7 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include diff --git a/dev/Kernel/HALKit/AMD64/PCI/Iterator.cc b/dev/Kernel/HALKit/AMD64/PCI/Iterator.cc new file mode 100644 index 00000000..d87482ab --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/PCI/Iterator.cc @@ -0,0 +1,41 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include + +namespace Kernel::PCI +{ + Iterator::Iterator(const Types::PciDeviceKind& type) + { + // probe devices. + for (int bus = 0; bus < ZKA_BUS_COUNT; ++bus) + { + for (int device = 0; device < ZKA_DEVICE_COUNT; ++device) + { + for (int function = 0; function < ZKA_FUNCTION_COUNT; ++function) + { + auto bar = 0x00; + + Device dev(bus, device, function, bar); + + if (dev.Class() == (UChar)type) + { + fDevices[bus] = dev; + } + } + } + } + } + + Iterator::~Iterator() + { + } + + Ref Iterator::operator[](const Size& at) + { + return fDevices[at]; + } +} // namespace Kernel::PCI diff --git a/dev/Kernel/HALKit/AMD64/PCI/PCI.cc b/dev/Kernel/HALKit/AMD64/PCI/PCI.cc new file mode 100644 index 00000000..47a56e53 --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/PCI/PCI.cc @@ -0,0 +1,7 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include diff --git a/dev/Kernel/HALKit/AMD64/Paging.h b/dev/Kernel/HALKit/AMD64/Paging.h new file mode 100644 index 00000000..4e8c8c65 --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/Paging.h @@ -0,0 +1,99 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +/** --------------------------------------------------- + + * THIS FILE CONTAINS CODE FOR X86_64 PAGING. + +------------------------------------------------------- */ + +#include + +#ifndef kPageMax +#define kPageMax (0x200) +#endif //! kPageMax + +#ifndef kPageAlign +#define kPageAlign (0x08) +#endif //! kPageAlign + +#ifndef kPageSize +#define kPageSize (0x100) +#endif // !kPageSize + +#ifndef kAlign +#define kAlign __BIGGEST_ALIGNMENT__ +#endif // !kAlign + +EXTERN_C void hal_flush_tlb(); +EXTERN_C void hal_invl_tlb(Kernel::VoidPtr addr); +EXTERN_C void hal_write_cr3(Kernel::VoidPtr cr3); +EXTERN_C void hal_write_cr0(Kernel::VoidPtr bit); + +EXTERN_C Kernel::VoidPtr hal_read_cr0(); // @brief CPU control register. +EXTERN_C Kernel::VoidPtr hal_read_cr2(); // @brief Fault address. +EXTERN_C Kernel::VoidPtr hal_read_cr3(); // @brief Page table. + +namespace Kernel::HAL +{ + /// @brief Final page entry (Not PML, PDPT) + struct PACKED ZKA_PTE final + { + UInt64 Present : 1; + UInt64 Wr : 1; + UInt64 User : 1; + UInt64 Wt : 1; + UInt64 Cache : 1; + UInt64 Accessed : 1; + UInt64 Dirty : 1; + UInt64 MemoryType : 1; + UInt64 Global : 1; + UInt64 Resvered1 : 3; + UInt64 PhysicalAddress : 36; + UInt64 Reserved2 : 10; + UInt64 ProtectionKey : 5; + UInt64 ExecDisable : 1; + }; + + namespace Detail + { + enum class ControlRegisterBits + { + ProtectedModeEnable = 0, + MonitorCoProcessor = 1, + Emulation = 2, + TaskSwitched = 3, + ExtensionType = 4, + NumericError = 5, + WriteProtect = 16, + AlignementMask = 18, + NotWriteThrough = 29, + CacheDisable = 30, + PageEnable = 31, + }; + + inline UInt8 control_register_cast(ControlRegisterBits reg) + { + return static_cast(reg); + } + } // namespace Detail + + struct ZKA_PDE final + { + ZKA_PTE* ALIGN(kPageAlign) fEntries[kPageMax]; + }; + + auto mm_alloc_bitmap(Boolean wr, Boolean user, SizeT size, Bool is_page) -> VoidPtr; + auto mm_free_bitmap(VoidPtr page_ptr) -> Bool; +} // namespace Kernel::HAL + +namespace Kernel +{ + typedef HAL::ZKA_PTE PTE; + typedef HAL::ZKA_PDE PDE; +} // namespace Kernel diff --git a/dev/Kernel/HALKit/AMD64/Processor.h b/dev/Kernel/HALKit/AMD64/Processor.h new file mode 100644 index 00000000..ce7d53f9 --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/Processor.h @@ -0,0 +1,331 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + + File: Prcoessor.h + Purpose: AMD64 processor abstraction. + + Revision History: + + 30/01/24: Added file (amlel) + +------------------------------------------- */ + +#pragma once + +#include +#include +#include +#include +#include + +#define kPITControlPort 0x43 +#define kPITChannel0Port 0x40 +#define kPITFrequency 1193180 + +#define kPICCommand 0x20 +#define kPICData 0x21 +#define kPIC2Command 0xA0 +#define kPIC2Data 0xA1 + +EXTERN_C +{ +#include +} + +#include + +/// @brief Maximum entries of the interrupt descriptor table. +#define kKernelIdtSize (0x100) + +/// @brief interrupt for system call. +#define kKernelInterruptId (0x32) + +#define IsActiveLow(FLG) (FLG & 2) +#define IsLevelTriggered(FLG) (FLG & 8) + +#define kInterruptGate (0x8E) +#define kTrapGate (0xEF) +#define kTaskGate (0b10001100) +#define kIDTSelector (0x08) + +namespace Kernel +{ + namespace Detail::AMD64 + { + struct PACKED InterruptDescriptorAMD64 final + { + UInt16 OffsetLow; // offset bits 0..15 + UInt16 Selector; // a code segment selector in GDT or LDT + UInt8 Ist; + UInt8 TypeAttributes; + UInt16 OffsetMid; + UInt32 OffsetHigh; + UInt32 Zero; // reserved + }; + } // namespace Detail::AMD64 +} // namespace Kernel + +namespace Kernel::HAL +{ + /// @brief Memory Manager mapping flags. + enum + { + kMMFlagsInvalid = 0 << 0, + kMMFlagsPresent = 1 << 0, + kMMFlagsWr = 1 << 1, + kMMFlagsUser = 1 << 2, + kMMFlagsNX = 1 << 3, + kMMFlagsCount = 4, + }; + + struct PACKED Register64 final + { + UShort Limit; + UIntPtr Base; + }; + + struct PACKED RegisterGDT final + { + UShort Limit; + UIntPtr Base; + }; + + using RawRegister = UInt64; + using Reg = RawRegister; + using InterruptId = UInt16; /* For each element in the IVT */ + + /// @brief Stack frame (as retrieved from assembly.) + struct PACKED StackFrame final + { + RawRegister R8{0}; + RawRegister R9{0}; + RawRegister R10{0}; + RawRegister FS{0}; + RawRegister R12{0}; + RawRegister R13{0}; + RawRegister R14{0}; + RawRegister R15{0}; + RawRegister GS{0}; + RawRegister SP{0}; + RawRegister BP{0}; + }; + + typedef StackFrame* StackFramePtr; + + class InterruptDescriptor final + { + public: + UShort Offset; + UShort Selector; + UChar Ist; + UChar Atrributes; + + UShort SecondOffset; + UInt ThirdOffset; + UInt Zero; + + operator bool() + { + return Offset != 0xFFFF; + } + }; + + using InterruptDescriptorArray = Array; + + class SegmentDescriptor final + { + public: + UInt16 Base; + UInt8 BaseMiddle; + UInt8 BaseHigh; + + UShort Limit; + UChar Gran; + UChar AccessByte; + }; + + /*** + * @brief Segment Boolean operations + */ + class SegmentDescriptorComparator final + { + public: + Bool IsValid(SegmentDescriptor& seg) + { + return seg.Base > seg.Limit; + } + + Bool Equals(SegmentDescriptor& seg, SegmentDescriptor& segRight) + { + return seg.Base == segRight.Base && seg.Limit == segRight.Limit; + } + }; + + using SegmentArray = Array; + + class GDTLoader final + { + public: + static Void Load(RegisterGDT& gdt); + static Void Load(Ref& gdt); + }; + + class IDTLoader final + { + public: + static Void Load(Register64& idt); + static Void Load(Ref& idt); + }; + /***********************************************************************************/ + /// @brief Is the current config SMP aware? + /// @return True if YES, False if not. + /***********************************************************************************/ + Bool mp_is_smp(Void) noexcept; + + /***********************************************************************************/ + /// @brief Fetch and enable SMP scheduler. + /// @param vendor_ptr SMP containing structure. + /***********************************************************************************/ + Void mp_get_cores(VoidPtr vendor_ptr) noexcept; + + /***********************************************************************************/ + + Void hal_send_start_ipi(UInt32 apicId, UInt8 vector, UInt32 targetAddress); + Void hal_send_end_ipi(UInt32 apicId, UInt8 vector, UInt32 targetAddress); + + /***********************************************************************************/ + + /***********************************************************************************/ + /// @brief Do a cpuid to check if MSR exists on CPU. + /// @retval true it does exists. + /// @retval false it doesn't. + /***********************************************************************************/ + inline Bool hal_has_msr() noexcept + { + static UInt32 eax, unused, edx; // eax, edx + + __get_cpuid(1, &eax, &unused, &unused, &edx); + + // edx returns the flag for MSR (which is 1 shifted to 5.) + return edx & (1 << 5); + } + + /***********************************************************************************/ + /// @brief Get Model specific register inside core. + /// @param msr MSR + /// @param lo low byte + /// @param hi high byte + /***********************************************************************************/ + inline Void hal_get_msr(UInt32 msr, UInt32* lo, UInt32* hi) noexcept + { + if (!lo || !hi) + return; + + asm volatile("rdmsr" + : "=a"(*lo), "=d"(*hi) + : "c"(msr)); + } + + /// @brief Set Model-specific register. + /// @param msr MSR + /// @param lo low byte + /// @param hi high byte + inline Void hal_set_msr(UInt32 msr, UInt32 lo, UInt32 hi) noexcept + { + asm volatile("wrmsr" + : + : "a"(lo), "d"(hi), "c"(msr)); + } + + /// @brief Processor specific namespace. + namespace Detail + { + /* @brief TSS struct. */ + struct ZKA_TSS final + { + UInt32 fReserved1; + UInt64 fRsp0; + UInt64 fRsp1; + UInt64 fRsp2; + UInt64 fReserved2; + UInt64 fIst1; + UInt64 fIst2; + UInt64 fIst3; + UInt64 fIst4; + UInt64 fIst5; + UInt64 fIst6; + UInt64 fIst7; + UInt64 fReserved3; + UInt16 fReserved4; + UInt16 fIopb; + }; + + /** + @brief Global descriptor table entry, either null, code or data. + */ + + struct PACKED ZKA_GDT_ENTRY final + { + UInt16 fLimitLow; + UInt16 fBaseLow; + UInt8 fBaseMid; + UInt8 fAccessByte; + UInt8 fFlags; + UInt8 fBaseHigh; + }; + } // namespace Detail + + class APICController + { + public: + explicit APICController(VoidPtr base) + : fApic(base) + { + } + + ~APICController() = default; + + ZKA_COPY_DEFAULT(APICController); + + public: + UInt32 Read(UInt32 reg) noexcept; + Void Write(UInt32 reg, UInt32 value) noexcept; + + private: + VoidPtr fApic{nullptr}; + }; + + /// @brief Set a PTE from pd_base. + /// @param virt_addr a valid virtual address. + /// @param phys_addr point to physical address. + /// @param flags the flags to put on the page. + /// @return Status code of page manip. + EXTERN_C Int32 mm_map_page(VoidPtr virt_addr, UInt32 flags); + + EXTERN_C UInt8 rt_in8(UInt16 port); + EXTERN_C UInt16 rt_in16(UInt16 port); + EXTERN_C UInt32 rt_in32(UInt16 port); + + EXTERN_C void rt_out16(UShort port, UShort byte); + EXTERN_C void rt_out8(UShort port, UChar byte); + EXTERN_C void rt_out32(UShort port, UInt byte); + + EXTERN_C void rt_wait_400ns(); + EXTERN_C void rt_halt(); + EXTERN_C void rt_cli(); + EXTERN_C void rt_sti(); + EXTERN_C void rt_cld(); + EXTERN_C void rt_std(); +} // namespace Kernel::HAL + +EXTERN_C Kernel::Void idt_handle_generic(Kernel::UIntPtr rsp); +EXTERN_C Kernel::Void idt_handle_gpf(Kernel::UIntPtr rsp); +EXTERN_C Kernel::Void idt_handle_math(Kernel::UIntPtr rsp); +EXTERN_C Kernel::Void idt_handle_pf(Kernel::UIntPtr rsp); + +EXTERN_C ATTRIBUTE(naked) Kernel::Void hal_load_idt(Kernel::HAL::Register64 ptr); +EXTERN_C ATTRIBUTE(naked) Kernel::Void hal_load_gdt(Kernel::HAL::RegisterGDT ptr); + +inline Kernel::VoidPtr kKernelBitMpStart = nullptr; +inline Kernel::UIntPtr kKernelBitMpSize = 0UL; diff --git a/dev/Kernel/HALKit/AMD64/ReadMe.md b/dev/Kernel/HALKit/AMD64/ReadMe.md new file mode 100644 index 00000000..9570b33e --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/ReadMe.md @@ -0,0 +1,8 @@ +# AMD64 Hardware Abstraction Layer + +## Brief + +- Supported CPU: AMD64 BASED CPUs. +- Supported Firmware: EDK 2. + +###### Copyright (C) 2024, TQ B.V, all rights reserved. All rights reserved. diff --git a/dev/Kernel/HALKit/AMD64/Storage/AHCI-DMA.cc b/dev/Kernel/HALKit/AMD64/Storage/AHCI-DMA.cc new file mode 100644 index 00000000..e86bfde7 --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/Storage/AHCI-DMA.cc @@ -0,0 +1,319 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +/** + * @file AHCI.cc + * @author TQ B.V (amlalelmahrouss@icloud.com) + * @brief AHCI driver. + * @version 0.1 + * @date 2024-02-02 + * + * @Copyright (C) 2024, TQ B.V, all rights reserved. + * + */ + +#include +#include + +#include +#include +#include +#include +#include + +#ifdef __AHCI__ + +#define HBA_ERR_TFE (1 << 30) +#define HBA_PxCMD_ST 0x0001 +#define HBA_PxCMD_FRE 0x0010 +#define HBA_PxCMD_FR 0x4000 +#define HBA_PxCMD_CR 0x8000 + +#define kAhciStartAddress mib_cast(4) + +#define kAhciLBAMode (1 << 6) + +#define kAhciMaxPoll (100000U) + +#define kCmdOrCtrlCmd 1 +#define kCmdOrCtrlCtrl 0 + +#define kAhciSRBsy 0x80 +#define kAhciSRDrq 0x08 + +enum +{ + kSATAProgIfAHCI = 0x01, + kSATASubClass = 0x06, + kSATABar5 = 0x24, +}; + +STATIC Kernel::PCI::Device kAhciDevice; +STATIC HbaPort* kAhciPort = nullptr; +STATIC Kernel::Lba kCurrentDiskSectorCount = 0UL; + +Kernel::Void drv_calculate_disk_geometry() +{ + kCurrentDiskSectorCount = 0UL; + kcout << "Highest AHCI LBA (48-bit): " << Kernel::number(kCurrentDiskSectorCount) << endl; +} + +/// @brief Initializes an AHCI disk. +/// @param PortsImplemented the amount of kAhciPort that have been detected. +/// @return if the disk was successfully initialized or not. +Kernel::Boolean drv_std_init(Kernel::UInt16& PortsImplemented) +{ + using namespace Kernel; + + PCI::Iterator iterator(Types::PciDeviceKind::MassStorageController); + + for (SizeT device_index = 0; device_index < ZKA_BUS_COUNT; ++device_index) + { + kAhciDevice = iterator[device_index].Leak(); // And then leak the reference. + + // if SATA and then interface is AHCI... + if (kAhciDevice.Subclass() == kSATASubClass && + kAhciDevice.ProgIf() == kSATAProgIfAHCI) + { + kAhciDevice.EnableMmio(0x24); // Enable the memory index_byte/o for this ahci device. + kAhciDevice.BecomeBusMaster(0x24); // Become bus master for this ahci device, so that we can control it. + + HbaMem* mem_ahci = (HbaMem*)kAhciDevice.Bar(0x24); + + Kernel::UInt32 ports_implemented = mem_ahci->Pi; + Kernel::UInt16 ahci_index = 0; + + const Kernel::UInt16 kMaxPortsImplemented = 32; + const Kernel::UInt32 kSATASignature = 0x00000101; + const Kernel::UInt8 kAhciPresent = 0x03; + const Kernel::UInt8 kAhciIPMActive = 0x01; + + Kernel::Boolean detected = false; + + while (ahci_index < kMaxPortsImplemented) + { + if (ports_implemented) + { + kcout << "Port is implemented by host.\r"; + + Kernel::UInt8 ipm = (mem_ahci->Ports[ahci_index].Ssts >> 8) & 0x0F; + Kernel::UInt8 det = mem_ahci->Ports[ahci_index].Ssts & 0x0F; + + if (mem_ahci->Ports[ahci_index].Sig == kSATASignature) + { + kcout << "Port is AHCI controller.\r"; + + detected = true; + + kAhciPort = &mem_ahci->Ports[ahci_index]; + + kAhciPort->Cmd &= ~HBA_PxCMD_FRE; + + // Clear FRE (bit4) + kAhciPort->Cmd &= ~HBA_PxCMD_ST; + + // Wait until FR (bit14), CR (bit15) are cleared + while (YES) + { + if (kAhciPort->Cmd & HBA_PxCMD_CR) + continue; + + if (kAhciPort->Cmd & HBA_PxCMD_FR) + continue; + break; + } + + // when it's stopped. + + // do in-between + + kAhciPort->Clb = kAhciStartAddress + (ahci_index << 10); + kAhciPort->Clbu = 0; + rt_set_memory((Kernel::VoidPtr)((Kernel::UIntPtr)kAhciPort->Clb + kAhciPort->Clbu), 0, 1024); + + // FIS offset: 32K+256*ahci_index + // FIS entry size = 256 bytes per port + kAhciPort->Fb = kAhciStartAddress + (32 << 10) + (ahci_index << 8); + kAhciPort->Fbu = 0; + rt_set_memory((Kernel::VoidPtr)((Kernel::UIntPtr)kAhciPort->Fb + kAhciPort->Fbu), 0, 256); + + // Command table offset: 40K + 8K*ahci_index + // Command table size = 256*32 = 8K per port + HbaCmdHeader* cmd_header = (HbaCmdHeader*)((Kernel::UIntPtr)kAhciPort->Clb + kAhciPort->Clbu); + + for (SizeT i = 0; i < 32; i++) + { + cmd_header[i].Prdtl = 8; // 8 prdt entries per command table + // 256 bytes per command table, 64+16+48+16*8 + // Command table offset: 40K + 8K*ahci_index + cmdheader_index*256 + cmd_header[i].Ctba = kAhciStartAddress + (40 << 10) + (ahci_index << 13) + (i << 8); + cmd_header[i].Ctbau = 0; + + rt_set_memory((VoidPtr)((Kernel::UIntPtr)cmd_header[i].Ctba + cmd_header[i].Ctbau), 0, 256); + } + + // when it's starting + + // check for bits again, to start it again. + while (YES) + { + if (kAhciPort->Cmd & HBA_PxCMD_FR) + continue; + + break; + } + + kAhciPort->Cmd |= HBA_PxCMD_FRE; + kAhciPort->Cmd |= HBA_PxCMD_ST; + + drv_calculate_disk_geometry(); + + break; + } + } + + ports_implemented >>= 1; + ++ahci_index; + } + + return detected; + } + } + + return No; +} + +Kernel::Boolean drv_std_detected(Kernel::Void) +{ + return kAhciDevice.DeviceId() != 0xFFFF; +} + +Kernel::Void drv_std_write(Kernel::UInt64 lba, Kernel::Char* buffer, Kernel::SizeT sector_cnt, Kernel::SizeT size_buffer) +{ +} + +Kernel::Void drv_std_read(Kernel::UInt64 lba, Kernel::Char* buffer, Kernel::SizeT sector_cnt, Kernel::SizeT size_buffer) +{ + kAhciPort->Is = -1; + + Kernel::SizeT port = 0; + Kernel::UInt32 slots = (kAhciPort->Sact | kAhciPort->Ci); + + for (; port < slots; ++port) + { + if ((slots & 1) == 0) + break; + + slots >>= 1; + } + + HbaCmdHeader* cmd_hdr = (HbaCmdHeader*)((Kernel::UIntPtr)kAhciPort->Clb + kAhciPort->Clbu); + + cmd_hdr += port; + cmd_hdr->Cfl = sizeof(FisRegH2D) / sizeof(Kernel::UInt32); + cmd_hdr->Write = NO; + cmd_hdr->Prdtl = (Kernel::UInt16)((sector_cnt - 1) >> 4) + 1; + + HbaCmdTbl* cmd_tbl = (HbaCmdTbl*)((Kernel::UIntPtr)cmd_hdr->Ctba + cmd_hdr->Ctbau); + Kernel::rt_set_memory(cmd_tbl, 0, (cmd_hdr->Prdtl - 1) * sizeof(HbaPrdtEntry)); + + Kernel::SizeT i = 0; + + for (Kernel::SizeT i = 0; i < cmd_hdr->Prdtl - 1; i++) + { + cmd_tbl->PrdtEntries[i].Dba = (Kernel::UInt32)(Kernel::UInt64)buffer; + cmd_tbl->PrdtEntries[i].Dbau = (Kernel::UInt32)((Kernel::UInt64)(buffer) >> 32); + cmd_tbl->PrdtEntries[i].Dbc = size_buffer - 1; // 8K bytes (this value should always be set to 1 less than the actual value) + cmd_tbl->PrdtEntries[i].InterruptBit = 1; + } + + cmd_tbl->PrdtEntries[i].Dba = (Kernel::UInt32)(Kernel::UInt64)buffer; + cmd_tbl->PrdtEntries[i].Dbau = (Kernel::UInt32)((Kernel::UInt64)(buffer) >> 32); + cmd_tbl->PrdtEntries[i].Dbc = size_buffer - 1; // 8K bytes (this value should always be set to 1 less than the actual value) + cmd_tbl->PrdtEntries[i].InterruptBit = 1; + + FisRegH2D* cmd_fis = (FisRegH2D*)(&cmd_tbl->Cfis); + + cmd_fis->FisType = kFISTypeRegH2D; + cmd_fis->CmdOrCtrl = YES; // Command + cmd_fis->Command = kAHCICmdReadDmaEx; + + cmd_fis->Lba0 = (Kernel::UInt8)(Kernel::UInt32)lba & 0xFF; + cmd_fis->Lba1 = (Kernel::UInt8)((Kernel::UInt32)lba >> 8); + cmd_fis->Lba2 = (Kernel::UInt8)((Kernel::UInt32)lba >> 16); + cmd_fis->Device = kAhciLBAMode; // LBA mode + + cmd_fis->Lba3 = (Kernel::UInt8)((Kernel::UInt32)lba >> 24); + cmd_fis->Lba4 = (Kernel::UInt8)(lba >> 32); + cmd_fis->Lba5 = (Kernel::UInt8)((lba >> 32) >> 8); + + cmd_fis->CountLow = sector_cnt & 0xFF; + cmd_fis->CountHigh = (sector_cnt >> 8) & 0xFF; + + Kernel::UInt64 spin = 0UL; + + // The below loop waits until the port is no longer busy before issuing a new command + while ((kAhciPort->Tfd & (kAhciSRBsy | kAhciSRDrq)) && spin < kAhciMaxPoll) + { + spin++; + } + if (spin == 1000000) + { + kcout << "AHCI: Port is hung.\r"; + return; + } + + kAhciPort->Ci = 1 << port; // Issue command + + // Wait for completion + while (YES) + { + // In some longer duration reads, it may be helpful to spin on the DPS bit + // in the PxIS port field as well (1 << 5) + if ((kAhciPort->Ci & (1 << port)) == 0) + break; + if (kAhciPort->Is & HBA_ERR_TFE) // Task file error + { + using namespace Kernel; + kcout << ("AHCI: Read disk error.\r"); + + err_global_get() = kErrorUnrecoverableDisk; + + return; + } + } + + // Check again for the last time. + if (kAhciPort->Is & HBA_ERR_TFE) // task file error status + { + using namespace Kernel; + + kcout << ("AHCI: Read disk error.\r"); + *buffer = 0; + + err_global_get() = kErrorUnrecoverableDisk; + + return; + } +} + +/*** + @brief Gets the number of sectors inside the drive. + @return Sector size in bytes. + */ +Kernel::SizeT drv_get_sector_count() +{ + return kCurrentDiskSectorCount; +} + +/// @brief Get the drive size. +/// @return Disk size in bytes. +Kernel::SizeT drv_get_size() +{ + return drv_get_sector_count() * kAHCISectorSize; +} + +#endif // ifdef __AHCI__ diff --git a/dev/Kernel/HALKit/AMD64/Storage/ATA-DMA.cc b/dev/Kernel/HALKit/AMD64/Storage/ATA-DMA.cc new file mode 100644 index 00000000..d1751105 --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/Storage/ATA-DMA.cc @@ -0,0 +1,38 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +/** + * @file ATA-DMA.cc + * @author TQ B.V (amlalelmahrouss@icloud.com) + * @brief ATA driver (DMA mode). + * @version 0.1 + * @date 2024-02-02 + * + * @copyright Copyright (c) TQ B.V + * + */ + +#include + +#include +#include + +using namespace Kernel; + +EXTERN_C Int32 kPRDTTransferStatus; +STATIC PRDT kPRDT; + +#ifdef __ATA_DMA__ + +#ifdef __ATA_PIO__ +#error !!! You cant have both PIO and DMA enabled! !!! +#endif /* ifdef __ATA_PIO__ */ + +#ifdef __AHCI__ +#error !!! You cant have both ATA and AHCI enabled! !!! +#endif /* ifdef __AHCI__ */ + +#endif /* ifdef __ATA_DMA__ */ diff --git a/dev/Kernel/HALKit/AMD64/Storage/ATA-PIO.cc b/dev/Kernel/HALKit/AMD64/Storage/ATA-PIO.cc new file mode 100644 index 00000000..678d65b7 --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/Storage/ATA-PIO.cc @@ -0,0 +1,197 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +/** + * @file ATA-PIO.cc + * @author TQ B.V (amlalelmahrouss@icloud.com) + * @brief ATA driver (PIO mode). + * @version 0.1 + * @date 2024-02-02 + * + * @copyright Copyright (c) TQ B.V + * + */ + +#include +#include + +#ifdef __ATA_PIO__ + +using namespace Kernel; +using namespace Kernel::HAL; + +/// bugs: 0 + +#define kATADataLen 256 + +STATIC Boolean kATADetected = false; +STATIC Int32 kATADeviceType = kATADeviceCount; +STATIC Char kATAData[kATADataLen] = {0}; + +Boolean drv_std_wait_io(UInt16 IO) +{ + for (int i = 0; i < 400; i++) + rt_in8(IO + ATA_REG_STATUS); + +ATAWaitForIO_Retry: + auto statRdy = rt_in8(IO + ATA_REG_STATUS); + + if ((statRdy & ATA_SR_BSY)) + goto ATAWaitForIO_Retry; + +ATAWaitForIO_Retry2: + statRdy = rt_in8(IO + ATA_REG_STATUS); + + if (statRdy & ATA_SR_ERR) + return false; + + if (!(statRdy & ATA_SR_DRDY)) + goto ATAWaitForIO_Retry2; + + return true; +} + +Void drv_std_select(UInt16 Bus) +{ + if (Bus == ATA_PRIMARY_IO) + rt_out8(Bus + ATA_REG_HDDEVSEL, ATA_PRIMARY_SEL); + else + rt_out8(Bus + ATA_REG_HDDEVSEL, ATA_SECONDARY_SEL); +} + +Boolean drv_std_init(UInt16 Bus, UInt8 Drive, UInt16& OutBus, UInt8& OutMaster) +{ + UInt16 IO = Bus; + + drv_std_select(IO); + +ATAInit_Retry: + // Bus init, NEIN bit. + rt_out8(IO + ATA_REG_NEIN, 1); + + // identify until it's good + + auto statRdy = rt_in8(IO + ATA_REG_STATUS); + + if (statRdy & ATA_SR_ERR) + { + kcout << "ERROR: ATA DRIVE RETURNED ERROR BIT! ABORTING...\r"; + + return false; + } + + if ((statRdy & ATA_SR_BSY)) + { + kcout << "Retrying..."; + goto ATAInit_Retry; + } + + rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_IDENTIFY); + + /// fetch serial info + /// model, speed, number of sectors... + + drv_std_wait_io(IO); + + for (SizeT indexData = 0ul; indexData < kATADataLen; ++indexData) + { + kATAData[indexData] = rt_in16(IO + ATA_REG_DATA); + } + + OutBus = (Bus == ATA_PRIMARY_IO) ? ATA_PRIMARY_IO : ATA_SECONDARY_IO; + + OutMaster = (Bus == ATA_PRIMARY_IO) ? ATA_MASTER : ATA_SLAVE; + + kcout << "INFO: INITIALIZED ATA DRIVE!\r"; + + return true; +} + +Void drv_std_read(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size) +{ + Lba /= SectorSz; + + UInt8 Command = ((!Master) ? 0xE0 : 0xF0); + + drv_std_wait_io(IO); + drv_std_select(IO); + + rt_out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F)); + + rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + SectorSz) / SectorSz)); + + rt_out8(IO + ATA_REG_LBA0, (Lba)&0xFF); + rt_out8(IO + ATA_REG_LBA1, (Lba) >> 8); + rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16); + rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24); + + rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_READ_PIO); + + drv_std_wait_io(IO); + + for (SizeT IndexOff = 0; IndexOff < Size; ++IndexOff) + { + drv_std_wait_io(IO); + Buf[IndexOff] = rt_in16(IO + ATA_REG_DATA); + drv_std_wait_io(IO); + } + + drv_std_wait_io(IO); +} + +Void drv_std_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size) +{ + Lba /= SectorSz; + + UInt8 Command = ((!Master) ? 0xE0 : 0xF0); + + drv_std_wait_io(IO); + drv_std_select(IO); + + rt_out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F)); + + rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + (SectorSz)) / SectorSz)); + + rt_out8(IO + ATA_REG_LBA0, (Lba)&0xFF); + rt_out8(IO + ATA_REG_LBA1, (Lba) >> 8); + rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16); + rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24); + + rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_WRITE_PIO); + + drv_std_wait_io(IO); + + for (SizeT IndexOff = 0; IndexOff < Size; ++IndexOff) + { + drv_std_wait_io(IO); + rt_out16(IO + ATA_REG_DATA, Buf[IndexOff]); + drv_std_wait_io(IO); + } + + drv_std_wait_io(IO); +} + +/// @brief is ATA detected? +Boolean drv_std_detected(Void) +{ + return kATADetected; +} + +/*** + @brief Getter, gets the number of sectors inside the drive. +*/ +Kernel::SizeT drv_get_sector_count() +{ + return (kATAData[61] << 16) | kATAData[60]; +} + +/// @brief Get the drive size. +Kernel::SizeT drv_get_size() +{ + return drv_get_sector_count() * kATASectorSize; +} + +#endif /* ifdef __ATA_PIO__ */ diff --git a/dev/Kernel/HALKit/ARM64/.gitkeep b/dev/Kernel/HALKit/ARM64/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/dev/Kernel/HALKit/ARM64/AP.h b/dev/Kernel/HALKit/ARM64/AP.h new file mode 100644 index 00000000..ba09e8ab --- /dev/null +++ b/dev/Kernel/HALKit/ARM64/AP.h @@ -0,0 +1,36 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + + File: AP.h + Purpose: RISC-V hardware threads. + + Revision History: + + 30/01/24: Added file (amlel) + +------------------------------------------- */ + +#pragma once + +#include + +namespace Kernel +{ + typedef Int64 hal_ap_kind; + + typedef struct HAL_HARDWARE_THREAD + { + Kernel::UIntPtr fStartAddress; + Kernel::UInt8 fPrivleged : 1; + Kernel::UInt32 fPageMemoryFlags; + hal_ap_kind fIdentNumber; + } HAL_HARDWARE_THREAD; + + /// @brief Set PC to specific hart. + /// @param hart the hart + /// @param epc the pc. + /// @return + EXTERN_C Kernel::Void hal_set_pc_to_hart(HAL_HARDWARE_THREAD* hart, Kernel::VoidPtr epc); + +} // namespace Kernel diff --git a/dev/Kernel/HALKit/ARM64/APM/.gitkeep b/dev/Kernel/HALKit/ARM64/APM/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/dev/Kernel/HALKit/ARM64/APM/APM.cc b/dev/Kernel/HALKit/ARM64/APM/APM.cc new file mode 100644 index 00000000..d861420b --- /dev/null +++ b/dev/Kernel/HALKit/ARM64/APM/APM.cc @@ -0,0 +1,37 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include + +using namespace Kernel; + +/// @brief Send a APM command into it's own IO space. +/// @param base_dma the IO base port. +/// @param cmd the command. +/// @return status code. +EXTERN_C Int32 apm_send_io_command(UInt16 cmd, APMPowerCmd value) +{ + switch (cmd) + { + case kAPMPowerCommandReboot: { + asm volatile( + "ldr x0, =0x84000009\n" + "hvc #0\n"); + + return kErrorSuccess; + } + case kAPMPowerCommandShutdown: { + asm volatile( + "ldr x0, =0x84000008\n" + "hvc #0\n"); + + return kErrorSuccess; + } + default: + return kErrorInvalidData; + } +} diff --git a/dev/Kernel/HALKit/ARM64/HalACPIFactoryInterface.cc b/dev/Kernel/HALKit/ARM64/HalACPIFactoryInterface.cc new file mode 100644 index 00000000..b43612cc --- /dev/null +++ b/dev/Kernel/HALKit/ARM64/HalACPIFactoryInterface.cc @@ -0,0 +1,31 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include +#include +#include +#include + +namespace Kernel +{ + ACPIFactoryInterface::ACPIFactoryInterface(VoidPtr rsp_ptr) + : fRsdp(rsp_ptr), fEntries(0) + { + } + + Void ACPIFactoryInterface::Shutdown() + { + apm_send_io_command(kAPMPowerCommandShutdown, 0); + } + + /// @brief Reboot machine in either ACPI or by triple faulting. + /// @return nothing it's a reboot. + Void ACPIFactoryInterface::Reboot() + { + apm_send_io_command(kAPMPowerCommandReboot, 0); + } +} // namespace Kernel diff --git a/dev/Kernel/HALKit/ARM64/HalAP.cc b/dev/Kernel/HALKit/ARM64/HalAP.cc new file mode 100644 index 00000000..24ac5126 --- /dev/null +++ b/dev/Kernel/HALKit/ARM64/HalAP.cc @@ -0,0 +1,40 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include +#include + +using namespace Kernel; + +namespace Kernel::Detail +{ + STATIC void mp_hang_fn(void) + { + while (YES) + ; + } +} // namespace Kernel::Detail + +/// @brief wakes up thread. +/// wakes up thread from hang. +void mp_wakeup_thread(HAL::StackFramePtr stack) +{ + if (!stack) + return; + + hal_set_pc_to_hart(reinterpret_cast(stack->R15), reinterpret_cast(stack->BP)); +} + +/// @brief makes thread sleep. +/// hooks and hangs thread to prevent code from executing. +void mp_hang_thread(HAL::StackFramePtr stack) +{ + if (!stack) + return; + + hal_set_pc_to_hart(reinterpret_cast(stack->R15), reinterpret_cast(Kernel::Detail::mp_hang_fn)); +} diff --git a/dev/Kernel/HALKit/ARM64/HalCoreMPScheduler.cc b/dev/Kernel/HALKit/ARM64/HalCoreMPScheduler.cc new file mode 100644 index 00000000..78eead11 --- /dev/null +++ b/dev/Kernel/HALKit/ARM64/HalCoreMPScheduler.cc @@ -0,0 +1,28 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include + +using namespace Kernel; + +STATIC struct PROCESS_CONTROL_BLOCK final +{ + HAL::StackFramePtr f_Frame; + UInt8* f_Stack; + VoidPtr f_Image; +} kProcessBlocks[kSchedProcessLimitPerTeam] = {0}; + +EXTERN_C HAL::StackFramePtr mp_get_current_context(ProcessID pid) +{ + return kProcessBlocks[pid % kSchedProcessLimitPerTeam].f_Frame; +} + +EXTERN_C Bool mp_register_process(VoidPtr image, UInt8* stack_ptr, HAL::StackFramePtr stack_frame, ProcessID pid) +{ + MUST_PASS(image && stack_ptr && stack_frame); + return No; +} diff --git a/dev/Kernel/HALKit/ARM64/HalDebugOutput.cc b/dev/Kernel/HALKit/ARM64/HalDebugOutput.cc new file mode 100644 index 00000000..9718ec7f --- /dev/null +++ b/dev/Kernel/HALKit/ARM64/HalDebugOutput.cc @@ -0,0 +1,83 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include +#include +#include + +namespace Kernel +{ + EXTERN_C void ke_io_write(const Char* bytes) + { +#ifdef __DEBUG__ + if (*bytes == 0) + return; + + SizeT index = 0; + SizeT len = 0; + + index = 0; + len = rt_string_len(bytes, 255); + + volatile UInt8* uart_ptr = (UInt8*)0x09000000; + + while (index < len) + { + if (bytes[index] == '\r') + *uart_ptr = '\r'; + + *uart_ptr = bytes[index] == '\r' ? '\n' : bytes[index]; + ++index; + } +#endif // __DEBUG__ + } + + TerminalDevice::~TerminalDevice() = default; + + EXTERN_C void ke_io_read(const Char* bytes) + { +#ifdef __DEBUG__ + SizeT index = 0; + + volatile UInt8* uart_ptr = (UInt8*)0x09000000; + + ///! TODO: Look on how to wait for the UART to complete. + while (Yes) + { + auto in = *uart_ptr; + + ///! If enter pressed then break. + if (in == 0xD) + { + break; + } + + if (in < '0' || in < 'A' || in < 'a') + { + if (in != '@' || in != '!' || in != '?' || in != '.' || in != '/' || + in != ':') + { + continue; + } + } + + ((char*)bytes)[index] = in; + + ++index; + } + + ((char*)bytes)[index] = 0; +#endif // __DEBUG__ + } + + TerminalDevice TerminalDevice::The() noexcept + { + TerminalDevice out(Kernel::ke_io_write, Kernel::ke_io_read); + return out; + } + +} // namespace Kernel diff --git a/dev/Kernel/HALKit/ARM64/HalKernelMain.cc b/dev/Kernel/HALKit/ARM64/HalKernelMain.cc new file mode 100644 index 00000000..57526aa0 --- /dev/null +++ b/dev/Kernel/HALKit/ARM64/HalKernelMain.cc @@ -0,0 +1,57 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +Kernel::Void hal_real_init(Kernel::Void) noexcept; +EXTERN_C Kernel::Void rtl_kernel_main(Kernel::SizeT argc, char** argv, char** envp, Kernel::SizeT envp_len); + +EXTERN_C void hal_init_platform( + Kernel::HEL::BootInfoHeader* handover_hdr) +{ + + /************************************************** */ + /* INITIALIZE AND VALIDATE HEADER. */ + /************************************************** */ + + kHandoverHeader = handover_hdr; + + if (kHandoverHeader->f_Magic != kHandoverMagic && + kHandoverHeader->f_Version != kHandoverVersion) + { + return; + } + + /************************************** */ + /* INITIALIZE BIT MAP. */ + /************************************** */ + + kKernelBitMpSize = kHandoverHeader->f_BitMapSize; + kKernelBitMpStart = reinterpret_cast( + reinterpret_cast(kHandoverHeader->f_BitMapStart)); + + /// @note do initialize the interrupts after it. + + CG::CGDrawBackground(); + + rtl_kernel_main(0, nullptr, nullptr, 0); + + while (YES) + { + } +} diff --git a/dev/Kernel/HALKit/ARM64/HalPageInternal.S b/dev/Kernel/HALKit/ARM64/HalPageInternal.S new file mode 100644 index 00000000..8fcf40ff --- /dev/null +++ b/dev/Kernel/HALKit/ARM64/HalPageInternal.S @@ -0,0 +1,5 @@ +.text + +hal_flush_tlb: + tlbi + ret diff --git a/dev/Kernel/HALKit/ARM64/HalPagingMgrARM64.cc b/dev/Kernel/HALKit/ARM64/HalPagingMgrARM64.cc new file mode 100644 index 00000000..603ef301 --- /dev/null +++ b/dev/Kernel/HALKit/ARM64/HalPagingMgrARM64.cc @@ -0,0 +1,86 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + + File: HalPagingMgr.cc + Purpose: Platform Paging Manager.. + +------------------------------------------- */ + +#include +#include + +namespace Kernel::HAL +{ + typedef UInt32 PageTableIndex; + + /// \brief Page store type. + struct ZKA_PAGE_STORE final + { + struct + { + PDE* fPde{nullptr}; + PTE* fPte{nullptr}; + VoidPtr fVAddr{nullptr}; + } fInternalStore; + + Bool fStoreOp{No}; // Store operation in progress. + + static ZKA_PAGE_STORE& The() + { + static ZKA_PAGE_STORE the; + return the; + } + }; + + /// \brief Retrieve the page status of a PTE. + STATIC Void mmi_page_status(PTE* pte) + { + } + + STATIC Int32 mmi_map_page_table_entry(VoidPtr virtual_address, UInt32 flags, PTE* pt_entry); + + /// @brief Maps or allocates a page from virtual_address. + /// @param virtual_address a valid virtual address. + /// @param phys_addr point to physical address. + /// @param flags the flags to put on the page. + /// @return Status code of page manipulation process. + EXTERN_C Int32 mm_map_page(VoidPtr virtual_address, UInt32 flags) + { + if (!virtual_address || + !flags) + return 0; + + ZKA_PAGE_STORE& page_store = ZKA_PAGE_STORE::The(); + + while (page_store.fStoreOp) + ; + + page_store.fStoreOp = Yes; + + if (page_store.fInternalStore.fVAddr == virtual_address) + { + page_store.fStoreOp = No; + return mmi_map_page_table_entry(page_store.fInternalStore.fVAddr, flags, page_store.fInternalStore.fPte); + } + + return 1; + } + + /// @brief Maps flags for a specific pte. + /// @internal Internal function. + STATIC Int32 mmi_map_page_table_entry(VoidPtr virtual_address, UInt32 flags, PTE* pt_entry) + { + ZKA_PAGE_STORE& page_store = ZKA_PAGE_STORE::The(); + + // Update Internal store. + + page_store.fInternalStore.fPde = nullptr; + page_store.fInternalStore.fPte = pt_entry; + page_store.fInternalStore.fVAddr = virtual_address; + + page_store.fStoreOp = No; + + return 0; + } +} // namespace Kernel::HAL diff --git a/dev/Kernel/HALKit/ARM64/HalSchedulerCore.cc b/dev/Kernel/HALKit/ARM64/HalSchedulerCore.cc new file mode 100644 index 00000000..c0b6d871 --- /dev/null +++ b/dev/Kernel/HALKit/ARM64/HalSchedulerCore.cc @@ -0,0 +1,34 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include + +namespace Kernel +{ + /***********************************************************************************/ + /// @brief Unimplemented function (crashes by default) + /// @param void + /***********************************************************************************/ + + EXTERN_C Void __zka_pure_call(void) + { + UserProcessScheduler::The().GetCurrentProcess().Leak().Crash(); + } + + /***********************************************************************************/ + /// @brief Validate user stack. + /// @param stack_ptr the frame pointer. + /***********************************************************************************/ + + Bool hal_check_stack(HAL::StackFramePtr stack_ptr) + { + if (!stack_ptr) + return No; + + return stack_ptr->SP != 0 && stack_ptr->BP != 0; + } +} // namespace Kernel diff --git a/dev/Kernel/HALKit/ARM64/HalSchedulerCoreARM64.cc b/dev/Kernel/HALKit/ARM64/HalSchedulerCoreARM64.cc new file mode 100644 index 00000000..d45b47e3 --- /dev/null +++ b/dev/Kernel/HALKit/ARM64/HalSchedulerCoreARM64.cc @@ -0,0 +1,40 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include + +namespace Kernel +{ + EXTERN_C Void __zka_pure_call(void) + { + UserProcessScheduler::The().GetCurrentProcess().Leak().Crash(); + } + + bool hal_check_stack(HAL::StackFramePtr stackPtr) + { + if (!stackPtr) + return No; + + if (stackPtr->BP == 0 || stackPtr->SP == 0) + return No; + + return Yes; + } + + /// @brief Wakes up thread. + /// Wakes up thread from the hang state. + Void mp_wakeup_thread(HAL::StackFrame* stack) + { + ZKA_UNUSED(stack); + } + + /// @brief makes the thread sleep on a loop. + /// hooks and hangs thread to prevent code from executing. + Void mp_hang_thread(HAL::StackFrame* stack) + { + ZKA_UNUSED(stack); + } +} // namespace Kernel diff --git a/dev/Kernel/HALKit/ARM64/HalTimerARM64.cc b/dev/Kernel/HALKit/ARM64/HalTimerARM64.cc new file mode 100644 index 00000000..f4c9ef01 --- /dev/null +++ b/dev/Kernel/HALKit/ARM64/HalTimerARM64.cc @@ -0,0 +1,14 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + + File: HalTimer.cc + Purpose: HAL timer + + Revision History: + + 07/07/24: Added file (amlel) + +------------------------------------------- */ + +#include diff --git a/dev/Kernel/HALKit/ARM64/MBCI/.keepme b/dev/Kernel/HALKit/ARM64/MBCI/.keepme new file mode 100644 index 00000000..e69de29b diff --git a/dev/Kernel/HALKit/ARM64/Paging.h b/dev/Kernel/HALKit/ARM64/Paging.h new file mode 100644 index 00000000..430235de --- /dev/null +++ b/dev/Kernel/HALKit/ARM64/Paging.h @@ -0,0 +1,120 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +/** --------------------------------------------------- + + * THIS FILE CONTAINS CODE FOR ARMV8 PAGING. + +------------------------------------------------------- */ + +#include + +#ifndef kPageMax +#define kPageMax (0x200) +#endif //! kPageMax + +#ifndef kPageAlign +#define kPageAlign (0x1000) +#endif //! kPageAlign + +#ifndef kPageSize +#define kPageSize (0x1000) +#endif // !kPageSize + +//! short format address range + +#define c16KBPage 0b000 +#define c8KBPage 0b001 +#define c4KBPage 0b010 +#define c2KBPage 0b011 +#define c1KBPage 0b100 +#define c512BPage 0b101 +#define c256BPage 0b110 +#define c128BPage 0b111 + +/// Long format address range + +#define cPageMAll \ + { \ + 0b000, 0b000 \ + } +#define cPageMToMax(M) \ + { \ + M, 0b000 \ + } +#define cPageMaxToM(M) \ + { \ + 0b000, M \ + } +#define cPageMToN(M, N) \ + { \ + M, N \ + } + +namespace Kernel::HAL +{ + struct PACKED PTE_4KB final + { + UInt64 Valid : 1; + UInt64 Table : 1; + UInt64 AttrIndex : 3; + UInt64 NS : 1; + UInt64 AP : 2; + UInt64 SH : 2; + UInt64 AF : 1; + UInt64 NG : 1; + UInt64 Reserved1 : 1; + UInt64 Contiguous : 1; + UInt64 Dirty : 1; + UInt64 Reserved : 2; + UInt64 PhysicalAddress : 36; + UInt64 Reserved3 : 4; + UInt64 PXN : 1; + UInt64 XN : 1; + UInt64 Reserved4 : 9; + }; + + namespace Detail + { + enum class ControlRegisterBits + { + ProtectedModeEnable = 0, + MonitorCoProcessor = 1, + Emulation = 2, + TaskSwitched = 3, + ExtensionType = 4, + NumericError = 5, + WriteProtect = 16, + AlignementMask = 18, + NotWriteThrough = 29, + CacheDisable = 30, + PageEnable = 31, + }; + + inline UInt8 control_register_cast(ControlRegisterBits reg) + { + return static_cast(reg); + } + } // namespace Detail + + struct PDE_4KB final + { + PTE_4KB ALIGN(kPageAlign) fEntries[kPageMax]; + }; + + auto mm_alloc_bitmap(Boolean wr, Boolean user, SizeT size, Bool is_page) -> VoidPtr; + auto mm_free_bitmap(VoidPtr page_ptr) -> Bool; +} // namespace Kernel::HAL + +namespace Kernel +{ + typedef HAL::PTE_4KB PTE; + typedef HAL::PDE_4KB PDE; +} // namespace Kernel + +EXTERN_C void hal_flush_tlb(); diff --git a/dev/Kernel/HALKit/ARM64/Processor.h b/dev/Kernel/HALKit/ARM64/Processor.h new file mode 100644 index 00000000..2fe9e31a --- /dev/null +++ b/dev/Kernel/HALKit/ARM64/Processor.h @@ -0,0 +1,75 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include +#include +#include +#include + +#define kCPUBackendName "ARMv8" + +namespace Kernel::HAL +{ + struct PACKED Register64 final + { + UShort Limit; + UIntPtr Base; + }; + + /// @brief Memory Manager mapping flags. + enum + { + kMMFlagsPresent = 1 << 0, + kMMFlagsWr = 1 << 1, + kMMFlagsUser = 1 << 2, + kMMFlagsNX = 1 << 3, + kMMFlagsCount = 3, + }; + + /// @brief Set a PTE from pd_base. + /// @param virt_addr a valid virtual address. + /// @param phys_addr point to physical address. + /// @param flags the flags to put on the page. + /// @return Status code of page manip. + EXTERN_C Int32 mm_map_page(VoidPtr virt_addr, UInt32 flags); + + typedef UIntPtr Reg; + typedef Register64 Register; + + /// @note let's keep the same name as AMD64 HAL. + struct PACKED StackFrame final + { + Reg R8{0}; + Reg R9{0}; + Reg R10{0}; + Reg R11{0}; + Reg R12{0}; + Reg R13{0}; + Reg R14{0}; + Reg R15{0}; + Reg SP{0}; + Reg BP{0}; + }; + + typedef StackFrame* StackFramePtr; + + inline Void rt_halt() + { + while (Yes) + { + } + } + +} // namespace Kernel::HAL + +inline Kernel::VoidPtr kKernelBitMpStart = nullptr; +inline Kernel::UIntPtr kKernelBitMpSize = 0UL; + +inline Kernel::VoidPtr kKernelPhysicalStart = nullptr; + +#include diff --git a/dev/Kernel/HALKit/ARM64/ReadMe.md b/dev/Kernel/HALKit/ARM64/ReadMe.md new file mode 100644 index 00000000..c51229f2 --- /dev/null +++ b/dev/Kernel/HALKit/ARM64/ReadMe.md @@ -0,0 +1,3 @@ +# ARM64 Hardware Abstraction Layer + +- Supported Firmware: CoreBoot/EDK/OpenMobileBoot diff --git a/dev/Kernel/HALKit/ARM64/Storage/.gitkeep b/dev/Kernel/HALKit/ARM64/Storage/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/dev/Kernel/HALKit/ARM64/Storage/HalFlash.cc b/dev/Kernel/HALKit/ARM64/Storage/HalFlash.cc new file mode 100644 index 00000000..c3fe73e1 --- /dev/null +++ b/dev/Kernel/HALKit/ARM64/Storage/HalFlash.cc @@ -0,0 +1,66 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include + +/// @file Flash.cc +/// @brief Flash memory builtin. + +#ifdef __USE_MBCI_FLASH__ + +#define kMaxFlash (4U) + +namespace Kernel +{ + /// /:/BRIDGE/FLSH/1 + constexpr auto kFlashBridgeMagic = "FLSH"; + constexpr auto kFlashBridgeRevision = 1; + + STATIC const Boolean kFlashEnabled = No; + STATIC SizeT kFlashSize[kMaxFlash] = {}; + STATIC SizeT kFlashSectorSz[kMaxFlash] = {}; + + /// @brief Enable flash memory builtin. + STATIC Void drv_enable_flash(Int32 slot); + + /// @brief Disable flash memory builtin. + STATIC Void drv_disable_flash(Int32 slot); + + /// @brief get sector count. + /// @return drive sector count. + SizeT drv_get_sector_count(Int32 slot) + { + if (slot > kMaxFlash) + return 0; + + return kFlashSectorSz[slot]; + } + + /// @brief get device size. + /// @return drive size + SizeT drv_get_size(Int32 slot) + { + if (slot > kMaxFlash) + return 0; + + return kFlashSize[slot]; + } + + /// @brief Enable flash memory at slot. + STATIC Void drv_enable_flash(Int32 arg) + { + kcout << "Enabled FLSH hardware.\r"; + } + + /// @brief Disable flash memory at slot. + STATIC Void drv_disable_flash(Int32 arg) + { + kcout << "Disabled FLSH hardware.\r"; + } +} // namespace Kernel + +#endif // if __USE_MBCI_FLASH__ (Bridge) diff --git a/dev/Kernel/HALKit/AXP/CR.s b/dev/Kernel/HALKit/AXP/CR.s new file mode 100644 index 00000000..4d68257d --- /dev/null +++ b/dev/Kernel/HALKit/AXP/CR.s @@ -0,0 +1,11 @@ +.globl read_lr1 +.globl read_lr0 + +.section .text + read_lr0: + movq %r30, %cr3 + ret + + hal_read_cr0: + movq %r30, %cr0 + ret \ No newline at end of file diff --git a/dev/Kernel/HALKit/AXP/CoreInterruptHandlerDEC.cpp b/dev/Kernel/HALKit/AXP/CoreInterruptHandlerDEC.cpp new file mode 100644 index 00000000..e69de29b diff --git a/dev/Kernel/HALKit/AXP/CoreSyscallHandlerDEC.cpp b/dev/Kernel/HALKit/AXP/CoreSyscallHandlerDEC.cpp new file mode 100644 index 00000000..16184673 --- /dev/null +++ b/dev/Kernel/HALKit/AXP/CoreSyscallHandlerDEC.cpp @@ -0,0 +1,24 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include + +/// @brief Internal call for syscall, to work with C++. +/// @param stack +/// @return nothing. +EXTERN_C void rt_syscall_handle(Kernel::HAL::StackFrame* stack) +{ + if (stack->Rcx <= (kSyscalls.Count() - 1)) + { + kcout << "syscall: enter.\r"; + + if (kSyscalls[stack->Rcx].Leak().Leak().fHooked) + (kSyscalls[stack->Rcx].Leak().Leak().fProc)(stack); + + kcout << "syscall: exit.\r"; + } +} diff --git a/dev/Kernel/HALKit/AXP/HAL.s b/dev/Kernel/HALKit/AXP/HAL.s new file mode 100644 index 00000000..0178527f --- /dev/null +++ b/dev/Kernel/HALKit/AXP/HAL.s @@ -0,0 +1,13 @@ +.globl rt_wait_400ns + +.section .text +rt_wait_400ns: + jmp .L +.L: + jmp .L2 + wtint ;; wait for interrupt +.L2: + + ret + + diff --git a/dev/Kernel/HALKit/AXP/Processor.h b/dev/Kernel/HALKit/AXP/Processor.h new file mode 100644 index 00000000..ec986d79 --- /dev/null +++ b/dev/Kernel/HALKit/AXP/Processor.h @@ -0,0 +1,7 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once diff --git a/dev/Kernel/HALKit/AXP/README b/dev/Kernel/HALKit/AXP/README new file mode 100644 index 00000000..91e7b134 --- /dev/null +++ b/dev/Kernel/HALKit/AXP/README @@ -0,0 +1 @@ +This is for DEC Alpha. diff --git a/dev/Kernel/HALKit/AXP/README.TXT b/dev/Kernel/HALKit/AXP/README.TXT new file mode 100644 index 00000000..11e138f9 --- /dev/null +++ b/dev/Kernel/HALKit/AXP/README.TXT @@ -0,0 +1 @@ +An toy HAL to test the Kernel portability. diff --git a/dev/Kernel/HALKit/AXP/SYSCALL.s b/dev/Kernel/HALKit/AXP/SYSCALL.s new file mode 100644 index 00000000..19cab808 --- /dev/null +++ b/dev/Kernel/HALKit/AXP/SYSCALL.s @@ -0,0 +1,10 @@ +.section .text +system_handle_user_call: + .cfi_startproc + + push %r0 + jmp %r1 + mov %r30, %r2 + + .cfi_endproc + retsys \ No newline at end of file diff --git a/dev/Kernel/HALKit/AXP/VM.s b/dev/Kernel/HALKit/AXP/VM.s new file mode 100644 index 00000000..7024086b --- /dev/null +++ b/dev/Kernel/HALKit/AXP/VM.s @@ -0,0 +1,5 @@ +.global hal_flush_tlb + +.section .text +hal_flush_tlb: + swppal \ No newline at end of file diff --git a/dev/Kernel/HALKit/POWER/.gitkeep b/dev/Kernel/HALKit/POWER/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/dev/Kernel/HALKit/POWER/AP.h b/dev/Kernel/HALKit/POWER/AP.h new file mode 100644 index 00000000..6965f27c --- /dev/null +++ b/dev/Kernel/HALKit/POWER/AP.h @@ -0,0 +1,39 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + + File: AP.h + Purpose: POWER hardware threads. + + Revision History: + + 14/04/24: Added file (amlel) + +------------------------------------------- */ + +#pragma once + +#include + +namespace Kernel +{ + struct HAL_HARDWARE_THREAD; + + /// @brief hardware thread indentification type. + typedef Kernel::Int32 hal_ap_kind; + + /// @brief Hardware thread information structure. + typedef struct HAL_HARDWARE_THREAD + { + Kernel::UIntPtr fStartAddress; + Kernel::UInt8 fPrivleged : 1; + Kernel::UInt32 fPageMemoryFlags; + hal_ap_kind fIdentNumber; + } HAL_HARDWARE_THREAD; + + /// @brief Set PC to specific hart. + /// @param hart the hart + /// @param epc the pc. + /// @return + EXTERN_C Kernel::Void hal_set_pc_to_hart(HAL_HARDWARE_THREAD* hart, Kernel::VoidPtr epc); +} // namespace Kernel diff --git a/dev/Kernel/HALKit/POWER/APM/.gitkeep b/dev/Kernel/HALKit/POWER/APM/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/dev/Kernel/HALKit/POWER/HalAP.cc b/dev/Kernel/HALKit/POWER/HalAP.cc new file mode 100644 index 00000000..e354c915 --- /dev/null +++ b/dev/Kernel/HALKit/POWER/HalAP.cc @@ -0,0 +1,40 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include +#include + +using namespace Kernel; + +namespace Kernel::Detail +{ + STATIC void mp_hang_fn(void) + { + while (YES) + ; + } +} // namespace Kernel::Detail + +/// @brief wakes up thread. +/// wakes up thread from hang. +void mp_wakeup_thread(HAL::StackFramePtr stack) +{ + if (!stack) + return; + + hal_set_pc_to_hart(reinterpret_cast(stack->R15), reinterpret_cast(stack->BP)); +} + +/// @brief makes thread sleep. +/// hooks and hangs thread to prevent code from executing. +void mp_hang_thread(HAL::StackFramePtr stack) +{ + if (!stack) + return; + + hal_set_pc_to_hart(reinterpret_cast(stack->R15), reinterpret_cast(Kernel::Detail::mp_hang_fn)); +} diff --git a/dev/Kernel/HALKit/POWER/HalDebugOutput.cc b/dev/Kernel/HALKit/POWER/HalDebugOutput.cc new file mode 100644 index 00000000..409ae3a0 --- /dev/null +++ b/dev/Kernel/HALKit/POWER/HalDebugOutput.cc @@ -0,0 +1,27 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include + +using namespace Kernel; + +/// @brief Writes to COM1. +/// @param bytes +void ke_io_write(const Char* bytes) +{ + if (!bytes) + return; + + SizeT index = 0; + SizeT len = rt_string_len(bytes, 255); + + while (index < len) + { + // TODO + ++index; + } +} diff --git a/dev/Kernel/HALKit/POWER/HalStartSequence.s b/dev/Kernel/HALKit/POWER/HalStartSequence.s new file mode 100644 index 00000000..e99375a8 --- /dev/null +++ b/dev/Kernel/HALKit/POWER/HalStartSequence.s @@ -0,0 +1,14 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +.globl __ImageStart +.extern hal_init_platform +.align 4 +.text + +__ImageStart: + bl hal_init_platform + blr diff --git a/dev/Kernel/HALKit/POWER/HalThread.cc b/dev/Kernel/HALKit/POWER/HalThread.cc new file mode 100644 index 00000000..fbd694ff --- /dev/null +++ b/dev/Kernel/HALKit/POWER/HalThread.cc @@ -0,0 +1,8 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include diff --git a/dev/Kernel/HALKit/POWER/HalVirtualMemory.cc b/dev/Kernel/HALKit/POWER/HalVirtualMemory.cc new file mode 100644 index 00000000..b5fefcfa --- /dev/null +++ b/dev/Kernel/HALKit/POWER/HalVirtualMemory.cc @@ -0,0 +1,49 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include +#include + +/// @note Refer to SoC documentation. + +using namespace Kernel; + +EXTERN_C Void hal_write_tlb(UInt32 mas0, UInt32 mas1, UInt32 mas2, UInt32 mas3, UInt32 mas7) +{ + hal_mtspr(MAS0, mas0); + hal_mtspr(MAS1, mas1); + hal_mtspr(MAS2, mas2); + hal_mtspr(MAS3, mas3); + hal_mtspr(MAS7, mas7); + + hal_flush_tlb(); +} + +EXTERN_C Bool hal_set_tlb(UInt8 tlb, UInt32 epn, UInt64 rpn, UInt8 perms, UInt8 wimge, UInt8 ts, UInt8 esel, UInt8 tsize, UInt8 iprot) +{ + if ((hal_mfspr(SPRN_MMUCFG) & MMUCFG_MAVN) == MMUCFG_MAVN_V1 && (tsize & 1)) + { + // this MMU does not allow odd tsize values + return false; + } + + UInt32 mas0 = FSL_BOOKE_MAS0(tlb, esel, 0); + UInt32 mas1 = FSL_BOOKE_MAS1(1, iprot, 0, ts, tsize); + UInt32 mas2 = FSL_BOOKE_MAS2(epn, wimge); + UInt32 mas3 = FSL_BOOKE_MAS3(rpn, 0, perms); + UInt32 mas7 = FSL_BOOKE_MAS7(rpn); + + hal_write_tlb(mas0, mas1, mas2, mas3, mas7); + + return true; +} + +/// @brief Flush TLB +EXTERN_C void hal_flush_tlb() +{ + asm volatile("isync;tlbwe;msync;isync"); +} diff --git a/dev/Kernel/HALKit/POWER/MBCI/.gitkeep b/dev/Kernel/HALKit/POWER/MBCI/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/dev/Kernel/HALKit/POWER/MBCI/HalMBCIHost.cc b/dev/Kernel/HALKit/POWER/MBCI/HalMBCIHost.cc new file mode 100644 index 00000000..fbd694ff --- /dev/null +++ b/dev/Kernel/HALKit/POWER/MBCI/HalMBCIHost.cc @@ -0,0 +1,8 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include diff --git a/dev/Kernel/HALKit/POWER/Processor.h b/dev/Kernel/HALKit/POWER/Processor.h new file mode 100644 index 00000000..e230b4a7 --- /dev/null +++ b/dev/Kernel/HALKit/POWER/Processor.h @@ -0,0 +1,62 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + + Purpose: POWER processor header. + +------------------------------------------- */ + +#pragma once + +#include +#include + +#define NoOp() asm volatile("mr 0, 0") +#define kHalPPCAlignment __attribute__((aligned(4))) + +namespace Kernel::HAL +{ + typedef UIntPtr Reg; + + /// @brief Stack frame (as retrieved from assembly.) + struct PACKED StackFrame final + { + Reg R8{0}; + Reg R9{0}; + Reg R10{0}; + Reg R11{0}; + Reg R12{0}; + Reg R13{0}; + Reg R14{0}; + Reg R15{0}; + Reg SP{0}; + Reg BP{0}; + }; + + typedef StackFrame* StackFramePtr; + + inline void rt_halt() + { + while (true) + { + NoOp(); // no oop. + } + } + + inline void rt_cli() + { + NoOp(); // no oop + } +} // namespace Kernel::HAL + +EXTERN_C Kernel::Void int_handle_math(Kernel::UIntPtr sp); +EXTERN_C Kernel::Void int_handle_pf(Kernel::UIntPtr sp); + +/// @brief Set TLB. +Kernel::Bool hal_set_tlb(Kernel::UInt8 tlb, Kernel::UInt32 epn, Kernel::UInt64 rpn, Kernel::UInt8 perms, Kernel::UInt8 wimge, Kernel::UInt8 ts, Kernel::UInt8 esel, Kernel::UInt8 tsize, Kernel::UInt8 iprot); + +/// @brief Write TLB. +Kernel::Void hal_write_tlb(Kernel::UInt32 mas0, Kernel::UInt32 mas1, Kernel::UInt32 mas2, Kernel::UInt32 mas3, Kernel::UInt32 mas7); + +/// @brief Flush TLB. +EXTERN_C Kernel::Void hal_flush_tlb(); diff --git a/dev/Kernel/HALKit/POWER/ReadMe.md b/dev/Kernel/HALKit/POWER/ReadMe.md new file mode 100644 index 00000000..a9751581 --- /dev/null +++ b/dev/Kernel/HALKit/POWER/ReadMe.md @@ -0,0 +1,4 @@ +POWER Hardware Abstraction Layer + +- Supported CPU: POWER +- Supported Firmware: CoreBoot \ No newline at end of file diff --git a/dev/Kernel/HALKit/RISCV/.keep b/dev/Kernel/HALKit/RISCV/.keep new file mode 100644 index 00000000..e69de29b diff --git a/dev/Kernel/HALKit/RISCV/AP.h b/dev/Kernel/HALKit/RISCV/AP.h new file mode 100644 index 00000000..ba09e8ab --- /dev/null +++ b/dev/Kernel/HALKit/RISCV/AP.h @@ -0,0 +1,36 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + + File: AP.h + Purpose: RISC-V hardware threads. + + Revision History: + + 30/01/24: Added file (amlel) + +------------------------------------------- */ + +#pragma once + +#include + +namespace Kernel +{ + typedef Int64 hal_ap_kind; + + typedef struct HAL_HARDWARE_THREAD + { + Kernel::UIntPtr fStartAddress; + Kernel::UInt8 fPrivleged : 1; + Kernel::UInt32 fPageMemoryFlags; + hal_ap_kind fIdentNumber; + } HAL_HARDWARE_THREAD; + + /// @brief Set PC to specific hart. + /// @param hart the hart + /// @param epc the pc. + /// @return + EXTERN_C Kernel::Void hal_set_pc_to_hart(HAL_HARDWARE_THREAD* hart, Kernel::VoidPtr epc); + +} // namespace Kernel diff --git a/dev/Kernel/HALKit/RISCV/APM/.gitkeep b/dev/Kernel/HALKit/RISCV/APM/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/dev/Kernel/HALKit/RISCV/HalAP.cc b/dev/Kernel/HALKit/RISCV/HalAP.cc new file mode 100644 index 00000000..7b168e4c --- /dev/null +++ b/dev/Kernel/HALKit/RISCV/HalAP.cc @@ -0,0 +1,40 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include +#include + +using namespace Kernel; + +namespace Kernel::Detail +{ + STATIC void mp_hang_fn(void) + { + while (YES) + ; + } +} // namespace Kernel::Detail + +/// @brief wakes up thread. +/// wakes up thread from hang. +void mp_wakeup_thread(HAL::StackFramePtr stack) +{ + if (!stack) + return; + + hal_set_pc_to_hart(reinterpret_cast(stack->R15), reinterpret_cast(stack->BP)); +} + +/// @brief makes thread sleep. +/// hooks and hangs thread to prevent code from executing. +void mp_hang_thread(HAL::StackFramePtr stack) +{ + if (!stack) + return; + + hal_set_pc_to_hart(reinterpret_cast(stack->R15), reinterpret_cast(Kernel::Detail::mp_hang_fn)); +} diff --git a/dev/Kernel/HALKit/RISCV/ReadMe.md b/dev/Kernel/HALKit/RISCV/ReadMe.md new file mode 100644 index 00000000..b099aa31 --- /dev/null +++ b/dev/Kernel/HALKit/RISCV/ReadMe.md @@ -0,0 +1,4 @@ +RISCV64 Hardware Abstraction Layer + +- Supported CPU: RISCV64 +- Supported Firmware: CoreBoot \ No newline at end of file diff --git a/dev/Kernel/HALKit/RISCV/Storage/.gitkeep b/dev/Kernel/HALKit/RISCV/Storage/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/dev/Kernel/HALKit/X86S/.gitkeep b/dev/Kernel/HALKit/X86S/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/dev/Kernel/HALKit/X86S/ACPI/.gitkeep b/dev/Kernel/HALKit/X86S/ACPI/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/dev/Kernel/HALKit/X86S/Storage/.gitkeep b/dev/Kernel/HALKit/X86S/Storage/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/dev/Kernel/KernelKit/CodeMgr.h b/dev/Kernel/KernelKit/CodeMgr.h new file mode 100644 index 00000000..c0409f9c --- /dev/null +++ b/dev/Kernel/KernelKit/CodeMgr.h @@ -0,0 +1,37 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + + File: CodeMgr.hpp + Purpose: Code Mgr. + + Revision History: + + 30/01/24: Added file (amlel) + 3/8/24: Add UPP struct. + +------------------------------------------- */ + +#pragma once + +#include +#include +#include + +namespace Kernel +{ + /// @brief Main process entrypoint. + typedef void (*rtl_main_kind)(SizeT argc, char** argv, char** envp, SizeT envp_len); + + /// @brief C++ Constructor entrypoint. + typedef void(*rtl_ctor_kind)(void); + + /// @brief C++ Destructor entrypoint. + typedef void(*rtl_dtor_kind)(void); + + /// @brief Executes a new process from a function. Kernel code only. + /// @note This sets up a new stack, anything on the main function that calls the Kernel will not be accessible. + /// @param main the start of the process. + /// @return The team's process id. + ProcessID rtl_create_process(rtl_main_kind main, const Char* process_name) noexcept; +} // namespace Kernel diff --git a/dev/Kernel/KernelKit/DebugOutput.h b/dev/Kernel/KernelKit/DebugOutput.h new file mode 100644 index 00000000..2481da96 --- /dev/null +++ b/dev/Kernel/KernelKit/DebugOutput.h @@ -0,0 +1,198 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include +#include +#include +#include + +#define kDebugMaxPorts 56 + +#define kDebugUnboundPort 0x0FEED + +#define kDebugMag0 'Z' +#define kDebugMag1 'D' +#define kDebugMag2 'B' +#define kDebugMag3 'G' + +#define kDebugSourceFile 0 +#define kDebugLine 33 +#define kDebugTeam 43 +#define kDebugEOP 49 + +namespace Kernel +{ + class TerminalDevice; + class DTraceDevice; + + inline TerminalDevice end_line(); + inline TerminalDevice number(const Long& x); + inline TerminalDevice hex_number(const Long& x); + + // @brief Emulates a VT100 terminal. + class TerminalDevice final ZKA_DEVICE + { + public: + TerminalDevice(void (*print)(const Char*), void (*get)(const Char*)) + : IDeviceObject(print, get) + { + } + + ~TerminalDevice() override; + + /// @brief returns device name (terminal name) + /// @return string type (const Char*) + virtual const Char* Name() const override + { + return ("TerminalDevice"); + } + + ZKA_COPY_DEFAULT(TerminalDevice); + + STATIC TerminalDevice The() noexcept; + }; + + inline TerminalDevice end_line() + { + TerminalDevice selfTerm = TerminalDevice::The(); + + selfTerm.operator<<("\r"); + return selfTerm; + } + + inline TerminalDevice carriage_return() + { + TerminalDevice selfTerm = TerminalDevice::The(); + + selfTerm.operator<<("\r"); + return selfTerm; + } + + inline TerminalDevice tabulate() + { + TerminalDevice selfTerm = TerminalDevice::The(); + + selfTerm.operator<<("\t"); + return selfTerm; + } + + /// @brief emulate a terminal bell, like the VT100 does. + inline TerminalDevice bell() + { + TerminalDevice selfTerm = TerminalDevice::The(); + + selfTerm.operator<<("\a"); + return selfTerm; + } + + namespace Detail + { + inline TerminalDevice _write_number(const Long& x, TerminalDevice& term) + { + UInt64 y = (x > 0 ? x : -x) / 10; + UInt64 h = (x > 0 ? x : -x) % 10; + + if (y) + _write_number(y, term); + + /* fail if the number is not base-10 */ + if (h > 10) + { + _write_number('?', term); + return term; + } + + if (y < 0) + y = -y; + + const Char kNumbers[11] = "0123456789"; + + Char buf[2]; + buf[0] = kNumbers[h]; + buf[1] = 0; + + term.operator<<(buf); + return term; + } + + inline TerminalDevice _write_number_hex(const Long& x, TerminalDevice& term) + { + UInt64 y = (x > 0 ? x : -x) / 16; + UInt64 h = (x > 0 ? x : -x) % 16; + + if (y) + _write_number_hex(y, term); + + /* fail if the hex number is not base-16 */ + if (h > 16) + { + _write_number_hex('?', term); + return term; + } + + if (y < 0) + y = -y; + + const Char kNumbers[17] = "0123456789ABCDEF"; + + Char buf[2]; + buf[0] = kNumbers[h]; + buf[1] = 0; + + term.operator<<(buf); + return term; + } + } // namespace Detail + + inline TerminalDevice hex_number(const Long& x) + { + TerminalDevice selfTerm = TerminalDevice::The(); + + Detail::_write_number_hex(x, selfTerm); + selfTerm.operator<<("h"); + + return selfTerm; + } + + inline TerminalDevice number(const Long& x) + { + TerminalDevice selfTerm = TerminalDevice::The(); + + Detail::_write_number(x, selfTerm); + + return selfTerm; + } + + inline TerminalDevice get_console_in(Char* buf) + { + TerminalDevice selfTerm = TerminalDevice::The(); + + selfTerm >> buf; + + return selfTerm; + } + + typedef Char rt_debug_type[255]; + + class DebuggerPortHeader final + { + public: + Int16 fPort[kDebugMaxPorts]; + Int16 fBoundCnt; + }; +} // namespace Kernel + +#ifdef kcout +#undef kcout +#endif // ifdef kcout + +#define kcout \ + (Kernel::TerminalDevice::The() << "\e[0;31m [ " << __FILE__ << ": LINE: " << Kernel::number(__LINE__)); \ + (Kernel::TerminalDevice::The() << " ] \e[0m" \ + << ": ") +#define endl Kernel::TerminalDevice::The() << Kernel::end_line() diff --git a/dev/Kernel/KernelKit/Defines.h b/dev/Kernel/KernelKit/Defines.h new file mode 100644 index 00000000..c95604b3 --- /dev/null +++ b/dev/Kernel/KernelKit/Defines.h @@ -0,0 +1,15 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include + +#define KERNELKIT_VERSION "1.0.2" +#define KERNELKIT_VERSION_BCD 0x01020 + +class UserProcessScheduler; +class UserProcess; diff --git a/dev/Kernel/KernelKit/DeviceMgr.h b/dev/Kernel/KernelKit/DeviceMgr.h new file mode 100644 index 00000000..52e8f8b0 --- /dev/null +++ b/dev/Kernel/KernelKit/DeviceMgr.h @@ -0,0 +1,140 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +/* ------------------------------------------- + + Revision History: + + 31/01/24: Add kDeviceCnt (amlel) + 15/11/24: Add ZKA_DEVICE macro, to inherit from device object. + + ------------------------------------------- */ + +#pragma once + +/* @note Device Mgr. */ +/* @file KernelKit/DeviceMgr.h */ +/* @brief Device abstraction and I/O buffer. */ + +#include +#include + +#define kDeviceMgrRootDirPath "/Devices/" + +#define ZKA_DEVICE : public ::Kernel::IDeviceObject + +// Last Rev: Wed, Apr 3, 2024 9:09:41 AM + +namespace Kernel +{ + template + class IDeviceObject; + + /***********************************************************************************/ + /// @brief Device contract interface, represents an HW device. + /***********************************************************************************/ + template + class IDeviceObject + { + public: + explicit IDeviceObject(void (*Out)(T), void (*In)(T)) + : fOut(Out), fIn(In) + { + } + + virtual ~IDeviceObject() = default; + + public: + IDeviceObject& operator=(const IDeviceObject&) = default; + IDeviceObject(const IDeviceObject&) = default; + + public: + virtual IDeviceObject& operator<<(T Data) + { + fOut(Data); + return *this; + } + + virtual IDeviceObject& operator>>(T Data) + { + fIn(Data); + return *this; + } + + virtual const char* Name() const + { + return "IDeviceObject"; + } + + operator bool() + { + return fOut && fIn; + } + + Bool operator!() + { + return !fOut || !fIn; + } + + private: + Void (*fOut)(T Data) = {nullptr}; + Void (*fIn)(T Data) = {nullptr}; + }; + + /// + /// @brief Input Output abstract class. + /// Used mainly to communicate between OS to hardware. + /// + template + class IOBuf final + { + public: + explicit IOBuf(T dma_addr) + : fData(dma_addr) + { + // At least pass something valid when instancating this struct. + MUST_PASS(fData); + } + + IOBuf& operator=(const IOBuf&) = default; + IOBuf(const IOBuf&) = default; + + ~IOBuf() = default; + + public: + template + R operator->() const + { + return fData; + } + + template + R& operator[](Size index) const + { + return fData[index]; + } + + private: + T fData; + }; + + ///! @brief Device enum types. + enum + { + kDeviceTypeIDE, + kDeviceTypeEthernet, + kDeviceTypeWiFi, + kDeviceTypeFW, + kDeviceTypeBT, + kDeviceTypeRS232, + kDeviceTypeSCSI, + kDeviceTypeAHCI, + kDeviceTypeMBCI, + kDeviceTypeUSB, + kDeviceTypeMediaCtrl, // MM controller + kDeviceTypeCount, + }; +} // namespace Kernel diff --git a/dev/Kernel/KernelKit/DriveMgr.h b/dev/Kernel/KernelKit/DriveMgr.h new file mode 100644 index 00000000..b719e48c --- /dev/null +++ b/dev/Kernel/KernelKit/DriveMgr.h @@ -0,0 +1,169 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#ifndef INC_DRIVE_MANAGER_H +#define INC_DRIVE_MANAGER_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#define kDriveMaxCount (4U) +#define kDriveSectorSz (512U) +#define kDriveInvalidID (-1) +#define kDriveNameLen (32) + +#define drv_sector_cnt(SIZE, SECTOR_SZ) (((SIZE) + (SECTOR_SZ)) / (SECTOR_SZ)) + +namespace Kernel +{ + enum + { + kInvalidDisc = -1, + + /// Storage types, combine with flags. + kBlockDevice = 0xAD, + kMassStorageDisc = 0xDA, + kFloppyDisc = 0xCD, + kOpticalDisc = 0xDC, // CD-ROM/DVD-ROM/Blu-Ray + kTapeDisc = 0xD7, + + /// Storage flags, combine with types. + kReadOnlyDrive = 0x10, // Read only drive + kEPMDrive = 0x11, // Explicit Partition Map. + kEPTDrive = 0x12, // ESP w/ EPM partition. + kMBRDrive = 0x13, // PC classic partition scheme + kGPTDrive = 0x14, // PC new partition scheme + kUnformattedDrive = 0x15, + kStorageCount = 9, + }; + + /// @brief Media drive trait type. + struct DriveTrait final + { + Char fName[kDriveNameLen]; // /System, /Boot, //./Devices/USB... + Int32 fKind; // fMassStorage, fFloppy, fOpticalDisc. + Int32 fFlags; // fReadOnly, fXPMDrive, fXPTDrive + + /// @brief Packet drive (StorageKit compilant.) + struct DrivePacket final + { + VoidPtr fPacketContent{nullptr}; //! packet body. + Char fPacketMime[kDriveNameLen] = "*/*"; //! identify what we're sending. + SizeT fPacketSize{0UL}; //! packet size + UInt32 fPacketCRC32{0UL}; //! sanity crc, in case if good is set to false + Boolean fPacketGood{YES}; + Lba fPacketLba{0UL}; + Boolean fPacketReadOnly{NO}; + } fPacket; + + Void (*fInput)(DrivePacket* packet_ptr); + Void (*fOutput)(DrivePacket* packet_ptr); + Void (*fVerify)(DrivePacket* packet_ptr); + Void (*fInit)(DrivePacket* packet_ptr); + const Char* (*fDriveKind)(Void); + }; + + ///! drive as a device. + typedef DriveTrait* DriveTraitPtr; + + /** + * @brief Mounted drives interface. + * @note This class has all of it's drive set to nullptr, allocate them using + * GetAddressOf(index). + */ + class MountpointInterface final + { + public: + explicit MountpointInterface() = default; + ~MountpointInterface() = default; + + ZKA_COPY_DEFAULT(MountpointInterface); + + public: + DriveTrait& A() + { + return mA; + } + + DriveTrait& B() + { + return mB; + } + + DriveTrait& C() + { + return mC; + } + + DriveTrait& D() + { + return mD; + } + + enum + { + kDriveIndexA = 0, + kDriveIndexB, + kDriveIndexC, + kDriveIndexD, + kDriveIndexInvalid, + }; + + DriveTraitPtr GetAddressOf(const Int32& index) + { + err_local_get() = kErrorSuccess; + + switch (index) + { + case kDriveIndexA: + return &mA; + case kDriveIndexB: + return &mB; + case kDriveIndexC: + return &mC; + case kDriveIndexD: + return &mD; + default: { + err_local_get() = kErrorNoSuchDisk; + kcout << "No such disk index.\n"; + + break; + } + } + + return nullptr; + } + + private: + DriveTrait mA, mB, mC, mD; + }; + + /// @brief Unimplemented drive. + /// @param pckt the packet to read. + /// @return + Void io_drv_unimplemented(DriveTrait::DrivePacket* pckt); + + /// @brief Gets the drive kind (ATA, SCSI, AHCI...) + /// @param void none. + /// @return the drive kind (ATA, Flash, NVM) + const Char* io_drv_kind(Void); + + /// @brief Makes a new drive. + /// @return the new drive as a trait. + DriveTrait io_construct_blank_drive(Void) noexcept; + + /// @brief Fetches the main drive. + /// @return the new drive as a trait. + DriveTrait io_construct_main_drive(Void) noexcept; +} // namespace Kernel + +#endif /* ifndef INC_DRIVE_MANAGER_H */ diff --git a/dev/Kernel/KernelKit/FileMgr.h b/dev/Kernel/KernelKit/FileMgr.h new file mode 100644 index 00000000..b85828f2 --- /dev/null +++ b/dev/Kernel/KernelKit/FileMgr.h @@ -0,0 +1,427 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + + File: FileMgr.h + Purpose: Kernel file manager. + +------------------------------------------- */ + +/* ------------------------------------------- + + Revision History: + + 31/01/24: Update documentation (amlel) + 05/07/24: NeFS support, and fork support, updated constants and specs + as well. + + ------------------------------------------- */ + +#ifndef INC_FILEMGR_H +#define INC_FILEMGR_H + +#ifdef __FSKIT_INCLUDES_NEFS__ +#include +#endif // __FSKIT_INCLUDES_NEFS__ + +#ifdef __FSKIT_INCLUDES_HPFS__ +#include +#endif // __FSKIT_INCLUDES_HPFS__ + +#include +#include +#include +#include +#include +#include +#include +#include + +/// @brief Filesystem manager, abstraction over mounted filesystem. +/// Works like the VFS or IFS. + +#define kRestrictR "r" +#define kRestrictRB "rb" +#define kRestrictW "w" +#define kRestrictWB "rw" +#define kRestrictRWB "rwb" + +#define kRestrictMax (5U) + +#define node_cast(PTR) reinterpret_cast(PTR) + +/** + @note Refer to first enum. +*/ +#define kFileOpsCount (4U) +#define kFileMimeGeneric "n-application-kind/all" + +/** @brief invalid position. (n-pos) */ +#define kNPos (SizeT)(-1); + +namespace Kernel +{ + enum + { + kFileWriteAll = 100, + kFileReadAll = 101, + kFileReadChunk = 102, + kFileWriteChunk = 103, + kFileIOCnt = (kFileWriteChunk - kFileWriteAll) + 1, + // file flags + kFileFlagRsrc = 104, + kFileFlagData = 105, + }; + + typedef VoidPtr NodePtr; + + /** + @brief Filesystem Mgr Interface class + @brief Used to provide common I/O for a specific filesystem. +*/ + class IFilesystemMgr + { + public: + explicit IFilesystemMgr() = default; + virtual ~IFilesystemMgr() = default; + + public: + ZKA_COPY_DEFAULT(IFilesystemMgr); + + public: + /// @brief Mounts a new filesystem into an active state. + /// @param interface the filesystem interface + /// @return + static bool Mount(IFilesystemMgr* interface); + + /// @brief Unmounts the active filesystem + /// @return + static IFilesystemMgr* Unmount(); + + /// @brief Getter, gets the active filesystem. + /// @return + static IFilesystemMgr* GetMounted(); + + public: + virtual NodePtr Create(_Input const Char* path) = 0; + virtual NodePtr CreateAlias(_Input const Char* path) = 0; + virtual NodePtr CreateDirectory(_Input const Char* path) = 0; + virtual NodePtr CreateSwapFile(const Char* path) = 0; + + public: + virtual bool Remove(_Input const Char* path) = 0; + + public: + virtual NodePtr Open(_Input const Char* path, _Input const Char* r) = 0; + + public: + virtual Void Write(_Input NodePtr node, _Input VoidPtr data, _Input Int32 flags, _Input SizeT size) = 0; + + virtual _Output VoidPtr Read(_Input NodePtr node, + _Input Int32 flags, + _Input SizeT sz) = 0; + + virtual Void Write(_Input const Char* name, + _Input NodePtr node, + _Input VoidPtr data, + _Input Int32 flags, + _Input SizeT size) = 0; + + virtual _Output VoidPtr Read(_Input const Char* name, + _Input NodePtr node, + _Input Int32 flags, + _Input SizeT sz) = 0; + + public: + virtual bool Seek(_Input NodePtr node, _Input SizeT off) = 0; + + public: + virtual SizeT Tell(_Input NodePtr node) = 0; + virtual bool Rewind(_Input NodePtr node) = 0; + }; + +#ifdef __FSKIT_INCLUDES_NEFS__ + /** + * @brief Based of IFilesystemMgr, takes care of managing NeFS + * disks. + */ + class NeFileSystemMgr final : public IFilesystemMgr + { + public: + explicit NeFileSystemMgr(); + ~NeFileSystemMgr() override; + + public: + ZKA_COPY_DEFAULT(NeFileSystemMgr); + + public: + NodePtr Create(const Char* path) override; + NodePtr CreateAlias(const Char* path) override; + NodePtr CreateDirectory(const Char* path) override; + NodePtr CreateSwapFile(const Char* path) override; + + public: + bool Remove(_Input const Char* path) override; + NodePtr Open(_Input const Char* path, _Input const Char* r) override; + Void Write(_Input NodePtr node, _Input VoidPtr data, _Input Int32 flags, _Input SizeT sz) override; + VoidPtr Read(_Input NodePtr node, _Input Int32 flags, _Input SizeT sz) override; + bool Seek(_Input NodePtr node, _Input SizeT off) override; + SizeT Tell(_Input NodePtr node) override; + bool Rewind(_Input NodePtr node) override; + + Void Write(_Input const Char* name, + _Input NodePtr node, + _Input VoidPtr data, + _Input Int32 flags, + _Input SizeT size) override; + + _Output VoidPtr Read(_Input const Char* name, + _Input NodePtr node, + _Input Int32 flags, + _Input SizeT sz) override; + + public: + /// @brief Get NeFS parser class. + /// @return The filesystem parser class. + NeFileSystemParser* GetParser() noexcept; + + private: + NeFileSystemParser* fImpl{nullptr}; + }; + +#endif // ifdef __FSKIT_INCLUDES_NEFS__ + + /** + * Usable FileStream + * @tparam Encoding file encoding (char, wchar_t...) + * @tparam FSClass Filesystem contract who takes care of it. + */ + template + class FileStream final + { + public: + explicit FileStream(const Encoding* path, const Encoding* restrict_type); + ~FileStream(); + + public: + FileStream& operator=(const FileStream&); + FileStream(const FileStream&); + + public: + ErrorOr WriteAll(const VoidPtr data) noexcept + { + if (this->fFileRestrict != kFileMgrRestrictReadWrite && + this->fFileRestrict != kFileMgrRestrictReadWriteBinary && + this->fFileRestrict != kFileMgrRestrictWrite && + this->fFileRestrict != kFileMgrRestrictWriteBinary) + return ErrorOr(kErrorInvalidData); + + if (data == nullptr) + return ErrorOr(kErrorInvalidData); + + auto man = FSClass::GetMounted(); + + if (man) + { + man->Write(fFile, data, kFileWriteAll); + return ErrorOr(0); + } + + return ErrorOr(kErrorInvalidData); + } + + VoidPtr ReadAll() noexcept + { + if (this->fFileRestrict != kFileMgrRestrictReadWrite && + this->fFileRestrict != kFileMgrRestrictReadWriteBinary && + this->fFileRestrict != kFileMgrRestrictRead && + this->fFileRestrict != kFileMgrRestrictReadBinary) + return nullptr; + + auto man = FSClass::GetMounted(); + + if (man) + { + VoidPtr ret = man->Read(fFile, kFileReadAll, 0); + return ret; + } + + return nullptr; + } + + ErrorOr WriteAll(const Char* fName, const VoidPtr data) noexcept + { + if (this->fFileRestrict != kFileMgrRestrictReadWrite && + this->fFileRestrict != kFileMgrRestrictReadWriteBinary && + this->fFileRestrict != kFileMgrRestrictWrite && + this->fFileRestrict != kFileMgrRestrictWriteBinary) + return ErrorOr(kErrorInvalidData); + + if (data == nullptr) + return ErrorOr(kErrorInvalidData); + + auto man = FSClass::GetMounted(); + + if (man) + { + man->Write(fName, fFile, data, kFileWriteAll); + return ErrorOr(0); + } + + return ErrorOr(kErrorInvalidData); + } + + VoidPtr Read(const Char* fName) noexcept + { + if (this->fFileRestrict != kFileMgrRestrictReadWrite && + this->fFileRestrict != kFileMgrRestrictReadWriteBinary && + this->fFileRestrict != kFileMgrRestrictRead && + this->fFileRestrict != kFileMgrRestrictReadBinary) + return nullptr; + + auto man = FSClass::GetMounted(); + + if (man) + { + VoidPtr ret = man->Read(fName, fFile, kFileReadAll, 0); + return ret; + } + + return nullptr; + } + + VoidPtr Read(SizeT offset, SizeT sz) + { + if (this->fFileRestrict != kFileMgrRestrictReadWrite && + this->fFileRestrict != kFileMgrRestrictReadWriteBinary && + this->fFileRestrict != kFileMgrRestrictRead && + this->fFileRestrict != kFileMgrRestrictReadBinary) + return nullptr; + + auto man = FSClass::GetMounted(); + + if (man) + { + man->Seek(fFile, offset); + auto ret = man->Read(fFile, kFileReadChunk, sz); + + return ret; + } + + return nullptr; + } + + Void Write(SizeT offset, voidPtr data, SizeT sz) + { + if (this->fFileRestrict != kFileMgrRestrictReadWrite && + this->fFileRestrict != kFileMgrRestrictReadWriteBinary && + this->fFileRestrict != kFileMgrRestrictWrite && + this->fFileRestrict != kFileMgrRestrictWriteBinary) + return; + + auto man = FSClass::GetMounted(); + + if (man) + { + man->Seek(fFile, offset); + man->Write(fFile, data, sz, kFileReadChunk); + } + } + + public: + /// @brief Leak node pointer. + /// @return The node pointer. + NodePtr Leak() + { + return fFile; + } + + /// @brief Leak MIME. + /// @return The MIME. + Char* MIME() noexcept + { + return const_cast(fMime); + } + + enum + { + kFileMgrRestrictRead, + kFileMgrRestrictReadBinary, + kFileMgrRestrictWrite, + kFileMgrRestrictWriteBinary, + kFileMgrRestrictReadWrite, + kFileMgrRestrictReadWriteBinary, + }; + + private: + NodePtr fFile{nullptr}; + Int32 fFileRestrict{kFileMgrRestrictReadBinary}; + const Char* fMime{kFileMimeGeneric}; + }; + + using FileStreamUTF8 = FileStream; + using FileStreamUTF16 = FileStream; + + typedef UInt64 CursorType; + + inline static const auto kRestrictStrLen = 8U; + + /// @brief restrict information about the file descriptor. + struct FileRestrictKind final + { + Char fRestrict[kRestrictStrLen]; + Int32 fMappedTo; + }; + + /// @brief constructor + template + inline FileStream::FileStream(const Encoding* path, + const Encoding* restrict_type) + : fFile(Class::GetMounted()->Open(path, restrict_type)) + { + const SizeT kRestrictCount = kRestrictMax; + const FileRestrictKind kRestrictList[] = { + { + .fRestrict = kRestrictR, + .fMappedTo = kFileMgrRestrictRead, + }, + { + .fRestrict = kRestrictRB, + .fMappedTo = kFileMgrRestrictReadBinary, + }, + { + .fRestrict = kRestrictRWB, + .fMappedTo = kFileMgrRestrictReadWriteBinary, + }, + { + .fRestrict = kRestrictW, + .fMappedTo = kFileMgrRestrictWrite, + }, + { + .fRestrict = kRestrictWB, + .fMappedTo = kFileMgrRestrictReadWrite, + }}; + + for (SizeT index = 0; index < kRestrictCount; ++index) + { + if (rt_string_cmp(restrict_type, kRestrictList[index].fRestrict, + rt_string_len(kRestrictList[index].fRestrict)) == 0) + { + fFileRestrict = kRestrictList[index].fMappedTo; + break; + } + } + + kcout << "new file: " << path << ".\r"; + } + + /// @brief destructor of the file stream. + template + inline FileStream::~FileStream() + { + mm_delete_heap(fFile); + } +} // namespace Kernel + +#endif // ifndef INC_FILEMGR_H diff --git a/dev/Kernel/KernelKit/HardwareThreadScheduler.h b/dev/Kernel/KernelKit/HardwareThreadScheduler.h new file mode 100644 index 00000000..05cc9987 --- /dev/null +++ b/dev/Kernel/KernelKit/HardwareThreadScheduler.h @@ -0,0 +1,149 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#ifndef __INC_MP_MANAGER_H__ +#define __INC_MP_MANAGER_H__ + +#include +#include +#include + +/// @note Last Rev Sun 28 Jul CET 2024 +/// @note Last Rev Thu, Aug 1, 2024 9:07:38 AM + +#define kMaxAPInsideSched (8U) + +namespace Kernel +{ + class HardwareThread; + class HardwareThreadScheduler; + + using ThreadID = UInt32; + + enum ThreadKind + { + kAPSystemReserved, // System reserved thread, well user can't use it + kAPStandard, // user thread, cannot be used by Kernel + kAPFallback, // fallback thread, cannot be used by user if not clear or + // used by Kernel. + kAPBoot, // The core we booted from, the mama. + kInvalidAP, + kAPCount, + }; + + typedef enum ThreadKind ThreadKind; + typedef ThreadID ThreadID; + + /***********************************************************************************/ + /// + /// \name HardwareThread + /// \brief Abstraction over the CPU's core, used to run processes or threads. + /// + /***********************************************************************************/ + + class HardwareThread final + { + public: + explicit HardwareThread(); + ~HardwareThread(); + + public: + ZKA_COPY_DEFAULT(HardwareThread) + + public: + operator bool(); + + public: + void Wake(const bool wakeup = false) noexcept; + void Busy(const bool busy = false) noexcept; + + public: + bool Switch(VoidPtr image, Ptr8 stack_ptr, HAL::StackFramePtr frame, const ProcessID& pid); + bool IsWakeup() noexcept; + + public: + HAL::StackFramePtr StackFrame() noexcept; + const ThreadKind& Kind() noexcept; + bool IsBusy() noexcept; + const ThreadID& ID() noexcept; + + private: + HAL::StackFramePtr fStack{nullptr}; + ThreadKind fKind{ThreadKind::kAPStandard}; + ThreadID fID{0}; + ProcessID fSourcePID{-1}; + Bool fWakeup{false}; + Bool fBusy{false}; + UInt64 fPTime{0}; + + private: + friend class HardwareThreadScheduler; + friend class UserProcessHelper; + }; + + /// + /// \name HardwareThreadScheduler + /// \brief Class to manage the thread scheduling. + /// + + class HardwareThreadScheduler final : public ISchedulable + { + private: + friend class UserProcessHelper; + + public: + explicit HardwareThreadScheduler(); + ~HardwareThreadScheduler(); + ZKA_COPY_DEFAULT(HardwareThreadScheduler); + + public: + HAL::StackFramePtr Leak() noexcept; + + public: + Ref operator[](const SizeT& idx); + bool operator!() noexcept; + operator bool() noexcept; + + const Bool IsUser() override + { + return Yes; + } + + const Bool IsKernel() override + { + return No; + } + + const Bool HasMP() override + { + return kHandoverHeader->f_HardwareTables.f_MultiProcessingEnabled; + } + + public: + /// @brief Shared instance of the MP Mgr. + /// @return the reference to the mp manager class. + STATIC HardwareThreadScheduler& The(); + + public: + /// @brief Returns the amount of threads present in the system. + /// @returns SizeT the amount of cores present. + SizeT Capacity() noexcept; + + private: + Array fThreadList; + ThreadID fCurrentThread{0}; + }; + + /// @brief wakes up thread. + /// wakes up thread from hang. + Void mp_wakeup_thread(HAL::StackFramePtr stack); + + /// @brief makes thread sleep. + /// hooks and hangs thread to prevent code from executing. + Void mp_hang_thread(HAL::StackFramePtr stack); +} // namespace Kernel + +#endif // !__INC_MP_MANAGER_H__ diff --git a/dev/Kernel/KernelKit/Heap.h b/dev/Kernel/KernelKit/Heap.h new file mode 100644 index 00000000..4a3afff4 --- /dev/null +++ b/dev/Kernel/KernelKit/Heap.h @@ -0,0 +1,86 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#ifndef INC_KERNEL_HEAP_H +#define INC_KERNEL_HEAP_H + +// last-rev 30/01/24 +// file: Heap.h +// description: heap allocation support. + +#include +#include +#include + +namespace Kernel +{ + /// @brief Declare pointer as free. + /// @param heap_ptr the pointer. + /// @return a status code regarding the deallocation. + Int32 mm_delete_heap(VoidPtr heap_ptr); + + /// @brief Declare a new size for heap_ptr. + /// @param heap_ptr the pointer. + /// @return unsupported always returns nullptr. + VoidPtr mm_realloc_heap(VoidPtr heap_ptr, SizeT new_sz); + + /// @brief Check if pointer is a valid Kernel pointer. + /// @param heap_ptr the pointer + /// @return if it exists it returns true. + Boolean mm_is_valid_heap(VoidPtr heap_ptr); + + /// @brief Allocate chunk of memory. + /// @param sz Size of pointer + /// @param wr Read Write bit. + /// @param user User enable bit. + /// @return The newly allocated pointer, or nullptr. + VoidPtr mm_new_heap(const SizeT sz, const Bool wr, const Bool user); + + /// @brief Protect the heap with a CRC value. + /// @param heap_ptr pointer. + /// @return if it valid: point has crc now., otherwise fail. + Boolean mm_protect_heap(VoidPtr heap_ptr); + + /// @brief Makes a Kernel page. + /// @param heap_ptr the page pointer. + /// @return status code + Int32 mm_make_page(VoidPtr heap_ptr); + + /// @brief Overwrites and set the flags of a heap header. + /// @param heap_ptr the pointer to update. + /// @param flags the flags to set. + Int32 mm_make_flags(VoidPtr heap_ptr, UInt64 flags); + + /// @brief Gets the flags of a heap header. + /// @param heap_ptr the pointer to get. + UInt64 mm_get_flags(VoidPtr heap_ptr); + + /// @brief Allocate C++ class. + /// @param cls The class to allocate. + /// @param args The args to pass. + template + inline Void mm_new_class(_Input _Output T** cls, _Input Args&&... args) + { + if (*cls) + { + err_global_get() = Kernel::kErrorInvalidData; + return; + } + + *cls = new T(move(args)...); + } + + /// @brief Delete and nullify C++ class. + /// @param cls The class to delete. + template + inline Void mm_delete_class(_Input _Output T** cls) + { + delete *cls; + *cls = nullptr; + } +} // namespace Kernel + +#endif // !INC_KERNEL_HEAP_H diff --git a/dev/Kernel/KernelKit/IDLLObject.h b/dev/Kernel/KernelKit/IDLLObject.h new file mode 100644 index 00000000..3a8c20cb --- /dev/null +++ b/dev/Kernel/KernelKit/IDLLObject.h @@ -0,0 +1,48 @@ +/* + * ======================================================== + * + * Kernel + * Copyright (C) 2024, TQ B.V, all rights reserved., all rights reserved. + * + * ======================================================== + */ + +#pragma once + +#include +#include + +#define ZKA_DLL_OBJECT : public IDLLObject + +namespace Kernel +{ + /// @brief DLL class object. A handle to a shared library. + class IDLLObject + { + public: + explicit IDLLObject() = default; + virtual ~IDLLObject() = default; + + struct DLL_TRAITS final + { + VoidPtr ImageObject{nullptr}; + VoidPtr ImageEntrypointOffset{nullptr}; + + Bool IsValid() + { + return ImageObject && ImageEntrypointOffset; + } + }; + + ZKA_COPY_DEFAULT(IDLLObject); + + virtual DLL_TRAITS** GetAddressOf() = 0; + virtual DLL_TRAITS* Get() = 0; + + virtual Void Mount(DLL_TRAITS* to_mount) = 0; + virtual Void Unmount() = 0; + }; + + /// @brief Pure implementation, missing method/function handler. + EXTERN_C void __zka_pure_call(void); +} // namespace Kernel diff --git a/dev/Kernel/KernelKit/IPEFDLLObject.h b/dev/Kernel/KernelKit/IPEFDLLObject.h new file mode 100644 index 00000000..fb3f0bc2 --- /dev/null +++ b/dev/Kernel/KernelKit/IPEFDLLObject.h @@ -0,0 +1,106 @@ +/* + * ======================================================== + * + * Kernel + * Copyright (C) 2024, TQ B.V, all rights reserved., all rights reserved. + * + * ======================================================== + */ + +#ifndef __KERNELKIT_SHARED_OBJECT_H__ +#define __KERNELKIT_SHARED_OBJECT_H__ + +#include +#include +#include +#include +#include + +namespace Kernel +{ + /** + * @brief Shared Library class + * Load library from this class + */ + class IPEFDLLObject final ZKA_DLL_OBJECT + { + public: + explicit IPEFDLLObject() = default; + ~IPEFDLLObject() = default; + + public: + ZKA_COPY_DEFAULT(IPEFDLLObject); + + private: + DLL_TRAITS* fMounted{nullptr}; + + public: + DLL_TRAITS** GetAddressOf() + { + return &fMounted; + } + + DLL_TRAITS* Get() + { + return fMounted; + } + + public: + void Mount(DLL_TRAITS* to_mount) + { + if (!to_mount || !to_mount->ImageObject) + return; + + fMounted = to_mount; + + if (fLoader && to_mount) + { + delete fLoader; + fLoader = nullptr; + } + + if (!fLoader) + { + fLoader = new PEFLoader(fMounted->ImageObject); + } + } + + void Unmount() + { + if (fMounted) + fMounted = nullptr; + }; + + template + SymbolType Load(const Char* symbol_name, SizeT len, Int32 kind) + { + if (symbol_name == nullptr || *symbol_name == 0) + return nullptr; + if (len > kPathLen || len < 1) + return nullptr; + + auto ret = + reinterpret_cast(fLoader->FindSymbol(symbol_name, kind)); + + if (!ret) + { + if (kind == kPefCode) + return (VoidPtr)&__zka_pure_call; + + return nullptr; + } + + return ret; + } + + private: + PEFLoader* fLoader{nullptr}; + }; + + typedef IPEFDLLObject* IDLL; + + EXTERN_C IDLL rtl_init_dylib(UserProcess* header); + EXTERN_C Void rtl_fini_dylib(UserProcess* header, IDLL lib, Bool* successful); +} // namespace Kernel + +#endif /* ifndef __KERNELKIT_SHARED_OBJECT_H__ */ diff --git a/dev/Kernel/KernelKit/LPC.h b/dev/Kernel/KernelKit/LPC.h new file mode 100644 index 00000000..bb35aa81 --- /dev/null +++ b/dev/Kernel/KernelKit/LPC.h @@ -0,0 +1,69 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include + +/// @file LPC.h +/// @brief Local Process Codes. + +#define err_local_ok() (Kernel::UserProcessScheduler::The().GetCurrentProcess().Leak().GetLocalCode() == Kernel::kErrorSuccess) +#define err_local_fail() (Kernel::UserProcessScheduler::The().GetCurrentProcess().Leak().GetLocalCode() != Kernel::kErrorSuccess) +#define err_local_get() (Kernel::UserProcessScheduler::The().GetCurrentProcess().Leak().GetLocalCode()) + +#define err_global_ok() (Kernel::kErrorLocalNumber == Kernel::kErrorSuccess) +#define err_global_fail() (Kernel::kErrorLocalNumber != Kernel::kErrorSuccess) +#define err_global_get() (Kernel::kErrorLocalNumber) + +namespace Kernel +{ + typedef Int32 HError; + + inline HError kErrorLocalNumber = 0UL; + + inline constexpr HError kErrorSuccess = 0; + inline constexpr HError kErrorExecutable = 33; + inline constexpr HError kErrorExecutableLib = 34; + inline constexpr HError kErrorFileNotFound = 35; + inline constexpr HError kErrorDirectoryNotFound = 36; + inline constexpr HError kErrorDiskReadOnly = 37; + inline constexpr HError kErrorDiskIsFull = 38; + inline constexpr HError kErrorProcessFault = 39; + inline constexpr HError kErrorSocketHangUp = 40; + inline constexpr HError kErrorThreadLocalStorage = 41; + inline constexpr HError kErrorMath = 42; + inline constexpr HError kErrorNoNetwork = 43; + inline constexpr HError kErrorHeapOutOfMemory = 44; + inline constexpr HError kErrorNoSuchDisk = 45; + inline constexpr HError kErrorFileExists = 46; + inline constexpr HError kErrorFormatFailed = 47; + inline constexpr HError kErrorNetworkTimeout = 48; + inline constexpr HError kErrorInternal = 49; + inline constexpr HError kErrorForkAlreadyExists = 50; + inline constexpr HError kErrorOutOfTeamSlot = 51; + inline constexpr HError kErrorHeapNotPresent = 52; + inline constexpr HError kErrorNoEntrypoint = 53; + inline constexpr HError kErrorDiskIsCorrupted = 54; + inline constexpr HError kErrorDisk = 55; + inline constexpr HError kErrorInvalidData = 56; + inline constexpr HError kErrorAsync = 57; + inline constexpr HError kErrorNonBlocking = 58; + inline constexpr HError kErrorIPC = 59; + inline constexpr HError kErrorSign = 60; + inline constexpr HError kErrorInvalidCreds = 61; + inline constexpr HError kErrorCDTrayBroken = 62; + inline constexpr HError kErrorUnrecoverableDisk = 63; + inline constexpr HError kErrorUnimplemented = 0; + + /// @brief Raises a bug check stop code. + Void err_bug_check_raise(Void) noexcept; + + /// @brief Does a system wide bug check. + /// @param void no params are needed. + /// @return if error-free: false, otherwise true. + Boolean err_bug_check(Void) noexcept; +} // namespace Kernel diff --git a/dev/Kernel/KernelKit/LoaderInterface.h b/dev/Kernel/KernelKit/LoaderInterface.h new file mode 100644 index 00000000..985873f4 --- /dev/null +++ b/dev/Kernel/KernelKit/LoaderInterface.h @@ -0,0 +1,34 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include +#include +#include +#include + +namespace Kernel +{ + /// @brief This interface is used to make loader contracts (MSCOFF, PEF). + /// @author @Amlal-El-Mahrouss + class LoaderInterface + { + public: + explicit LoaderInterface() = default; + virtual ~LoaderInterface() = default; + + ZKA_COPY_DEFAULT(LoaderInterface); + + public: + virtual _Output ErrorOr GetBlob() = 0; + virtual _Output const Char* AsString() = 0; + virtual _Output const Char* MIME() = 0; + virtual _Output const Char* Path() = 0; + virtual _Output ErrorOr FindStart() = 0; + virtual _Output VoidPtr FindSymbol(_Input const Char* name, _Input Int32 kind) = 0; + }; +} // namespace Kernel diff --git a/dev/Kernel/KernelKit/LockDelegate.h b/dev/Kernel/KernelKit/LockDelegate.h new file mode 100644 index 00000000..86b9dcdf --- /dev/null +++ b/dev/Kernel/KernelKit/LockDelegate.h @@ -0,0 +1,69 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include +#include + +namespace Kernel +{ + enum + { + kLockDone = 200, + kLockTimedOut, + }; + + /// @brief Lock condition pointer. + typedef Boolean* LockPtr; + + /// @brief Locking delegate class, hangs until limit. + /// @tparam N the amount of cycles to wait. + template + class LockDelegate final + { + public: + LockDelegate() = delete; + + public: + explicit LockDelegate(LockPtr expr) + { + auto spin = 0U; + + while (spin < N) + { + if (*expr) + { + fLockStatus | kLockDone; + break; + } + + ++spin; + } + + if (spin > N) + fLockStatus | kLockTimedOut; + } + + ~LockDelegate() = default; + + LockDelegate& operator=(const LockDelegate&) = delete; + LockDelegate(const LockDelegate&) = delete; + + bool Done() + { + return fLockStatus[kLockDone] == kLockDone; + } + + bool HasTimedOut() + { + return fLockStatus[kLockTimedOut] != kLockTimedOut; + } + + private: + Atom fLockStatus; + }; +} // namespace Kernel diff --git a/dev/Kernel/KernelKit/MSDOS.h b/dev/Kernel/KernelKit/MSDOS.h new file mode 100644 index 00000000..8ef7e0d6 --- /dev/null +++ b/dev/Kernel/KernelKit/MSDOS.h @@ -0,0 +1,52 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + + File: MSDOS.hpp + Purpose: MS-DOS header for Kernel. + + Revision History: + + 30/01/24: Added file (amlel) + +------------------------------------------- */ + +#ifndef __MSDOS_EXEC__ +#define __MSDOS_EXEC__ + +#include +#include + +// Last Rev +// Sat Feb 24 CET 2024 + +#define kMagMz0 'M' +#define kMagMz1 'Z' + +typedef Kernel::UInt32 DosWord; +typedef Kernel::Long DosLong; + +typedef struct _DosHeader +{ + Kernel::UInt8 eMagic[2]; + DosWord eMagLen; + DosWord ePagesCount; + DosWord eCrlc; + DosWord eCParHdr; + DosWord eMinAlloc; + DosWord eMaxAlloc; + DosWord eStackSeg; + DosWord eStackPtr; + DosWord eChksum; + DosWord eIp; + DosWord eCs; + DosWord eLfarlc; + DosWord eOvno; + DosWord eRes[4]; + DosWord eOemid; + DosWord eOeminfo; + DosWord eRes2[10]; + DosLong eLfanew; +} DosHeader, *DosHeaderPtr; + +#endif /* ifndef __MSDOS_EXEC__ */ diff --git a/dev/Kernel/KernelKit/PCI/DMA.h b/dev/Kernel/KernelKit/PCI/DMA.h new file mode 100644 index 00000000..ab2adaa8 --- /dev/null +++ b/dev/Kernel/KernelKit/PCI/DMA.h @@ -0,0 +1,81 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace Kernel +{ + enum class DmaKind + { + PCI, // Bus mastering is required to be turned on. Basiaclly a request + // control system. 64-Bit access depends on the PAE bit and the device + // (if Double Address Cycle is available) + ISA, // Four DMA channels 0-3; 8 bit transfers and only a megabyte of RAM. + Invalid, + }; + + class DMAWrapper final + { + public: + explicit DMAWrapper() = delete; + + public: + explicit DMAWrapper(nullPtr) = delete; + explicit DMAWrapper(voidPtr Ptr, DmaKind Kind = DmaKind::PCI) + : fAddress(Ptr), fKind(Kind) + { + } + + public: + DMAWrapper& operator=(voidPtr Ptr); + + public: + DMAWrapper& operator=(const DMAWrapper&) = default; + DMAWrapper(const DMAWrapper&) = default; + + public: + ~DMAWrapper() = default; + + template + T* operator->(); + + template + T* Get(const UIntPtr off = 0); + + public: + operator bool(); + bool operator!(); + + public: + bool Write(const UIntPtr& bit, const UIntPtr& offset); + UIntPtr Read(const UIntPtr& offset); + Boolean Check(UIntPtr offset) const; + + public: + UIntPtr operator[](const UIntPtr& offset); + + private: + voidPtr fAddress{nullptr}; + DmaKind fKind{DmaKind::Invalid}; + + private: + friend class DMAFactory; + }; + + class DMAFactory final + { + public: + static OwnPtr> Construct(OwnPtr& dma); + }; +} // namespace Kernel + +#include diff --git a/dev/Kernel/KernelKit/PCI/DMA.inl b/dev/Kernel/KernelKit/PCI/DMA.inl new file mode 100644 index 00000000..78e099a5 --- /dev/null +++ b/dev/Kernel/KernelKit/PCI/DMA.inl @@ -0,0 +1,20 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +namespace Kernel +{ + template + T* DMAWrapper::operator->() + { + return fAddress; + } + + template + T* DMAWrapper::Get(const UIntPtr offset) + { + return reinterpret_cast((UIntPtr)fAddress + offset); + } +} // namespace Kernel diff --git a/dev/Kernel/KernelKit/PCI/Database.h b/dev/Kernel/KernelKit/PCI/Database.h new file mode 100644 index 00000000..d3a4817d --- /dev/null +++ b/dev/Kernel/KernelKit/PCI/Database.h @@ -0,0 +1,38 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ +#pragma once + +#include +#include + +namespace Kernel +{ + namespace Types + { + // https://wiki.osdev.org/PCI + enum class PciDeviceKind : UChar + { + MassStorageController = 0x1, + NetworkController = 0x2, + DisplayController = 0x3, + MultimediaController = 0x4, + MemoryController = 0x5, + Bridge = 0x6, + CommunicationController = 0x7, + GenericSystemPeripheral = 0x8, + InputDeviceController = 0x9, + DockingStation = 0xa, + Processor = 0xb, + SerialBusController = 0xc, + WirelessController = 0xd, + IntelligentController = 0xe, + SatelliteCommunicationsController = 0xf, + CoProcessor = 0x40, + Unassgined = 0xf, + Invalid = Unassgined, + }; + } // namespace Types +} // namespace Kernel diff --git a/dev/Kernel/KernelKit/PCI/Device.h b/dev/Kernel/KernelKit/PCI/Device.h new file mode 100644 index 00000000..249c8ecd --- /dev/null +++ b/dev/Kernel/KernelKit/PCI/Device.h @@ -0,0 +1,80 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ +#pragma once + +#include + +namespace Kernel::PCI +{ + enum class PciConfigKind : UShort + { + ConfigAddress = 0xCF8, + ConfigData = 0xCFC, + Invalid = 0xFFF + }; + + class Device final + { + public: + Device() = default; + + public: + explicit Device(UShort bus, UShort device, UShort function, UInt32 bar); + + Device& operator=(const Device&) = default; + + Device(const Device&) = default; + + ~Device(); + + public: + UInt Read(UInt bar, Size szData); + void Write(UInt bar, UIntPtr data, Size szData); + + public: + operator bool(); + + public: + template + UInt Read(UInt bar) + { + static_assert(sizeof(T) <= 4, "64-bit PCI addressing is unsupported"); + return Read(bar, sizeof(T)); + } + + template + void Write(UInt bar, UIntPtr data) + { + static_assert(sizeof(T) <= 4, "64-bit PCI addressing is unsupported"); + Write(bar, data, sizeof(T)); + } + + public: + UShort DeviceId(); + UShort VendorId(); + UShort InterfaceId(); + UChar Class(); + UChar Subclass(); + UChar ProgIf(); + UChar HeaderType(); + UIntPtr Bar(UInt32 bar_in); + + public: + void EnableMmio(UInt32 bar_in); + void BecomeBusMaster(UInt32 bar_in); // for PCI-DMA, PC-DMA does not need that. + + UShort Vendor(); + + private: + UShort fBus; + UShort fDevice; + UShort fFunction; + UInt32 fBar; + }; +} // namespace Kernel::PCI + +EXTERN_C void NewOSPCISetCfgTarget(Kernel::UInt bar); +EXTERN_C Kernel::UInt NewOSPCIReadRaw(Kernel::UInt bar); diff --git a/dev/Kernel/KernelKit/PCI/Express.h b/dev/Kernel/KernelKit/PCI/Express.h new file mode 100644 index 00000000..b3118063 --- /dev/null +++ b/dev/Kernel/KernelKit/PCI/Express.h @@ -0,0 +1,11 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include + +#define PCI_EXPRESS_BUS_COUNT (4096) diff --git a/dev/Kernel/KernelKit/PCI/IO-Impl-AMD64.inl b/dev/Kernel/KernelKit/PCI/IO-Impl-AMD64.inl new file mode 100644 index 00000000..fd155bed --- /dev/null +++ b/dev/Kernel/KernelKit/PCI/IO-Impl-AMD64.inl @@ -0,0 +1,54 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + + File: IO-Impl-AMD64.hpp + Purpose: I/O for AMD64. + + Revision History: + + 30/01/24: Add file. (amlel) + 02/02/24: Update I/O routines. (amlel) + +------------------------------------------- */ + +namespace Kernel +{ + template + template + T IOArray::In(SizeT index) + { + switch (sizeof(T)) + { +#ifdef __ZKA_AMD64__ + case 4: + return HAL::rt_in32(fPorts[index].Leak()); + case 2: + return HAL::rt_in16(fPorts[index].Leak()); + case 1: + return HAL::rt_in8(fPorts[index].Leak()); +#endif + default: + return 0xFFFF; + } + } + + template + template + void IOArray::Out(SizeT index, T value) + { + switch (sizeof(T)) + { +#ifdef __ZKA_AMD64__ + case 4: + HAL::rt_out32(fPorts[index].Leak(), value); + case 2: + HAL::rt_out16(fPorts[index].Leak(), value); + case 1: + HAL::rt_out8(fPorts[index].Leak(), value); +#endif + default: + break; + } + } +} // namespace Kernel diff --git a/dev/Kernel/KernelKit/PCI/IO.h b/dev/Kernel/KernelKit/PCI/IO.h new file mode 100644 index 00000000..847856f7 --- /dev/null +++ b/dev/Kernel/KernelKit/PCI/IO.h @@ -0,0 +1,59 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include +#include +#include +#include + +namespace Kernel +{ + template + class IOArray final + { + public: + IOArray() = delete; + + IOArray(nullPtr) = delete; + + explicit IOArray(Array& ports) + : fPorts(ports) + { + } + ~IOArray() + { + } + + IOArray& operator=(const IOArray&) = default; + + IOArray(const IOArray&) = default; + + operator bool() + { + return !fPorts.Empty(); + } + + public: + template + T In(SizeT index); + + template + void Out(SizeT index, T value); + + private: + Array fPorts; + }; + + using IOArray16 = IOArray<16>; +} // namespace Kernel + +#ifdef __x86_64__ +#include +#else +#error Please provide platform specific code for the I/O +#endif // ifdef __x86_64__ diff --git a/dev/Kernel/KernelKit/PCI/Iterator.h b/dev/Kernel/KernelKit/PCI/Iterator.h new file mode 100644 index 00000000..f5ea7ecd --- /dev/null +++ b/dev/Kernel/KernelKit/PCI/Iterator.h @@ -0,0 +1,43 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#ifndef __PCI_ITERATOR_H__ +#define __PCI_ITERATOR_H__ + +#include +#include +#include +#include +#include + +#define ZKA_BUS_COUNT (256) +#define ZKA_DEVICE_COUNT (33) +#define ZKA_FUNCTION_COUNT (8) + +namespace Kernel::PCI +{ + class Iterator final + { + public: + Iterator() = delete; + + public: + explicit Iterator(const Types::PciDeviceKind& deviceType); + + Iterator& operator=(const Iterator&) = default; + Iterator(const Iterator&) = default; + + ~Iterator(); + + public: + Ref operator[](const Size& sz); + + private: + Array fDevices; + }; +} // namespace Kernel::PCI + +#endif // __PCI_ITERATOR_H__ diff --git a/dev/Kernel/KernelKit/PCI/PCI.h b/dev/Kernel/KernelKit/PCI/PCI.h new file mode 100644 index 00000000..62b2aa1b --- /dev/null +++ b/dev/Kernel/KernelKit/PCI/PCI.h @@ -0,0 +1,59 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include + +#define cPCIConfigAddressPort (0xCF8) +#define cPCIConfigDataPort (0xCFC) + +#define cPCIDeviceCount (32) +#define cPCIFuncCount (8) +#define cPCIBusCount (255) + +namespace Kernel::PCI +{ + // model + struct DeviceHeader + { + UInt16 VendorId; + UInt16 DeviceId; + UInt8 Command; + UInt8 Status; + UInt8 RevisionId; + UInt8 ProgIf; + UInt8 SubClass; + UInt8 Class; + UInt8 CacheLineSz; + UInt8 LatencyTimer; + UInt8 HeaderType; + UInt8 Bist; + UInt8 Bus; + UInt8 Device; + UInt8 Function; + }; + + namespace Detail + { + class BAR + { + public: + UIntPtr BAR; + SizeT Size; + }; + } // namespace Detail + + class BAR + { + public: + Detail::BAR BAR1; + Detail::BAR BAR2; + Detail::BAR BAR3; + Detail::BAR BAR4; + Detail::BAR BAR5; + }; +} // namespace Kernel::PCI diff --git a/dev/Kernel/KernelKit/PE.h b/dev/Kernel/KernelKit/PE.h new file mode 100644 index 00000000..086f6d40 --- /dev/null +++ b/dev/Kernel/KernelKit/PE.h @@ -0,0 +1,143 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + + File: PE.h + Purpose: Portable Executable for Kernel. + + Revision History: + + 30/01/24: Added file (amlel) + +------------------------------------------- */ + +#ifndef __KERNELKIT_INC_PE_H__ +#define __KERNELKIT_INC_PE_H__ + +#include + +#define kPeSignature 0x00004550 + +#define kPeDLLBase 0x4000000 +#define kPeEXEBase 0x1000000 + +#define kPeMagic32 0x010b +#define kPeMagic64 0x020b + +#define kPeMachineAMD64 0x8664 +#define kPeMachineARM64 0xaa64 + +typedef struct LDR_EXEC_HEADER final +{ + Kernel::UInt32 mSignature; + Kernel::UInt16 mMachine; + Kernel::UInt16 mNumberOfSections; + Kernel::UInt32 mTimeDateStamp; + Kernel::UInt32 mPointerToSymbolTable; + Kernel::UInt32 mNumberOfSymbols; + Kernel::UInt16 mSizeOfOptionalHeader; + Kernel::UInt16 mCharacteristics; +} LDR_EXEC_HEADER, *LDR_EXEC_HEADER_PTR; + +typedef struct LDR_OPTIONAL_HEADER final +{ + Kernel::UInt16 mMagic; // 0x010b - PE32, 0x020b - PE32+ (64 bit) + Kernel::UInt8 mMajorLinkerVersion; + Kernel::UInt8 mMinorLinkerVersion; + Kernel::UInt32 mSizeOfCode; + Kernel::UInt32 mSizeOfInitializedData; + Kernel::UInt32 mSizeOfUninitializedData; + Kernel::UInt32 mAddressOfEntryPoint; + Kernel::UInt32 mBaseOfCode; + Kernel::UInt32 mBaseOfData; + Kernel::UInt32 mImageBase; + Kernel::UInt32 mSectionAlignment; + Kernel::UInt32 mFileAlignment; + Kernel::UInt16 mMajorOperatingSystemVersion; + Kernel::UInt16 mMinorOperatingSystemVersion; + Kernel::UInt16 mMajorImageVersion; + Kernel::UInt16 mMinorImageVersion; + Kernel::UInt16 mMajorSubsystemVersion; + Kernel::UInt16 mMinorSubsystemVersion; + Kernel::UInt32 mWin32VersionValue; + Kernel::UInt32 mSizeOfImage; + Kernel::UInt32 mSizeOfHeaders; + Kernel::UInt32 mCheckSum; + Kernel::UInt16 mSubsystem; + Kernel::UInt16 mDllCharacteristics; + Kernel::UInt32 mSizeOfStackReserve; + Kernel::UInt32 mSizeOfStackCommit; + Kernel::UInt32 mSizeOfHeapReserve; + Kernel::UInt32 mSizeOfHeapCommit; + Kernel::UInt32 mLoaderFlags; + Kernel::UInt32 mNumberOfRvaAndSizes; +} LDR_OPTIONAL_HEADER, *LDR_OPTIONAL_HEADER_PTR; + +typedef struct LDR_SECTION_HEADER final +{ + Kernel::Char mName[8]; + Kernel::UInt32 mVirtualSize; + Kernel::UInt32 mVirtualAddress; + Kernel::UInt32 mSizeOfRawData; + Kernel::UInt32 mPointerToRawData; + Kernel::UInt32 mPointerToRelocations; + Kernel::UInt32 mPointerToLineNumbers; + Kernel::UInt16 mNumberOfRelocations; + Kernel::UInt16 mNumberOfLinenumbers; + Kernel::UInt32 mCharacteristics; +} LDR_SECTION_HEADER, *LDR_SECTION_HEADER_PTR; + +enum kExecDataDirParams +{ + kExecExport, + kExecImport, + kExecInvalid, + kExecCount, +}; + +typedef struct LDR_EXPORT_DIRECTORY +{ + Kernel::UInt32 mCharacteristics; + Kernel::UInt32 mTimeDateStamp; + Kernel::UInt16 mMajorVersion; + Kernel::UInt16 mMinorVersion; + Kernel::UInt32 mName; + Kernel::UInt32 mBase; + Kernel::UInt32 mNumberOfFunctions; + Kernel::UInt32 mNumberOfNames; + Kernel::UInt32 mAddressOfFunctions; // export table rva + Kernel::UInt32 mAddressOfNames; + Kernel::UInt32 mAddressOfNameOrdinal; // ordinal table rva +} LDR_EXPORT_DIRECTORY, *LDR_EXPORT_DIRECTORY_PTR; + +typedef struct LDR_IMPORT_DIRECTORY +{ + union { + Kernel::UInt32 mCharacteristics; + Kernel::UInt32 mOriginalFirstThunk; + }; + Kernel::UInt32 mTimeDateStamp; + Kernel::UInt32 mForwarderChain; + Kernel::UInt32 mNameRva; + Kernel::UInt32 mThunkTableRva; +} LDR_IMPORT_DIRECTORY, *LDR_IMPORT_DIRECTORY_PTR; + +typedef struct LDR_DATA_DIRECTORY +{ + Kernel::UInt32 VirtualAddress; + Kernel::UInt32 Size; +} LDR_DATA_DIRECTORY, *LDR_DATA_DIRECTORY_PTR; + +typedef struct LDR_IMAGE_HEADER +{ + LDR_EXEC_HEADER mHeader; + LDR_OPTIONAL_HEADER mOptHdr; +} LDR_IMAGE_HEADER, *LDR_IMAGE_HEADER_PTR; + +enum +{ + eUserSection = 0x00000020, + cPEResourceId = 0xFFaadd00, +}; + +#endif /* ifndef __KERNELKIT_INC_PE_H__ */ diff --git a/dev/Kernel/KernelKit/PECodeMgr.h b/dev/Kernel/KernelKit/PECodeMgr.h new file mode 100644 index 00000000..cf5273d9 --- /dev/null +++ b/dev/Kernel/KernelKit/PECodeMgr.h @@ -0,0 +1,24 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + + File: PECodeMgr.h + Purpose: PE32+ Code Mgr and DLL mgr. + + Revision History: + + 12/02/24: Added file (amlel) + +------------------------------------------- */ + +#pragma once + +//////////////////////////////////////////////////// + +// LAST REV: Mon Feb 12 13:52:01 CET 2024 + +//////////////////////////////////////////////////// + +#include +#include +#include diff --git a/dev/Kernel/KernelKit/PEF.h b/dev/Kernel/KernelKit/PEF.h new file mode 100644 index 00000000..51fac4c2 --- /dev/null +++ b/dev/Kernel/KernelKit/PEF.h @@ -0,0 +1,117 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + + File: PEF.h + Purpose: Preferred Executable Format for Kernel. + + Revision History: + + ?/?/23: Added file (amlel) + +------------------------------------------- */ + +#ifndef KERNELKIT_PEF_H +#define KERNELKIT_PEF_H + +#include +#include +#include + +#define kPefMagic "Joy!" +#define kPefMagicFat "yoJ!" + +#define kPefMagicLen 5 + +#define kPefVersion 3 +#define kPefNameLen 255 + +/* not mandatory, only for non fork based filesystems. */ +#define kPefExt ".o" +#define kPefDylibExt ".dylib" +#define kPefLibExt ".lib" +#define kPefObjectExt ".obj" +#define kPefDebugExt ".dbg" +#define kPefDriverExt ".sys" + +// Kernel System Binary Interface. +#define kPefAbi (0x5046) + +#define kPefBaseOrigin (0x40000000) + +#define kPefStart "__ImageStart" + +#define kPefForkKind kPefMagic +#define kPefForkKindFAT kPefMagicFat + +namespace Kernel +{ + enum + { + kPefArchIntel86S, + kPefArchAMD64, + kPefArchRISCV, + kPefArch64x0, /* 64x0. ISA */ + kPefArch32x0, /* 32x0. ISA */ + kPefArchPowerPC, + kPefArchARM64, + kPefArchCount = (kPefArchPowerPC - kPefArchIntel86S) + 1, + kPefArchInvalid = 0xFF, + }; + + enum + { + kPefSubArchAMD, + kPefSubArchIntel, + kPefSubArchARM, + kPefSubArchGeneric, + kPefSubArchIBM, + }; + + enum + { + kPefKindExec = 1, /* .exe */ + kPefKindDylib = 2, /* .dylib */ + kPefKindObject = 4, /* .obj */ + kPefKindDebug = 5, /* .dbg */ + kPefKindDriver = 6, + kPefKindCount, + }; + + typedef struct PEFContainer final + { + Char Magic[kPefMagicLen]; + UInt32 Linker; + UInt32 Version; + UInt32 Kind; + UInt32 Abi; + UInt32 Cpu; + UInt32 SubCpu; /* Cpu specific information */ + UIntPtr Start; + SizeT HdrSz; /* Size of header */ + SizeT Count; /* container header count */ + } PACKED PEFContainer; + + /* First PEFCommandHeader starts after PEFContainer */ + + typedef struct PEFCommandHeader final + { + Char Name[kPefNameLen]; /* container name */ + UInt32 Cpu; /* container cpu */ + UInt32 SubCpu; /* container sub-cpu */ + UInt32 Flags; /* container flags */ + UInt16 Kind; /* container kind */ + UIntPtr Offset; /* content offset */ + SizeT Size; /* content Size */ + } PACKED PEFCommandHeader; + + enum + { + kPefCode = 0xC, + kPefData = 0xD, + kPefZero = 0xE, + kPefLinkerID = 0x1, + }; +} // namespace Kernel + +#endif /* ifndef KERNELKIT_PEF_H */ diff --git a/dev/Kernel/KernelKit/PEFCodeMgr.h b/dev/Kernel/KernelKit/PEFCodeMgr.h new file mode 100644 index 00000000..1d895ee5 --- /dev/null +++ b/dev/Kernel/KernelKit/PEFCodeMgr.h @@ -0,0 +1,72 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#ifndef _INC_CODE_MANAGER_PEF_H_ +#define _INC_CODE_MANAGER_PEF_H_ + +#include +#include +#include +#include + +#ifndef INC_PROCESS_SCHEDULER_H +#include +#endif + +#define kPefApplicationMime "application/vnd-zka-executable" + +namespace Kernel +{ + /// + /// \name PEFLoader + /// \brief PEF loader class. + /// + class PEFLoader : public LoaderInterface + { + private: + explicit PEFLoader() = delete; + + public: + explicit PEFLoader(const VoidPtr blob); + explicit PEFLoader(const Char* path); + ~PEFLoader() override; + + public: + ZKA_COPY_DEFAULT(PEFLoader); + + public: + const Char* Path() override; + const Char* AsString() override; + const Char* MIME() override; + + public: + ErrorOr FindStart() override; + VoidPtr FindSymbol(const Char* name, Int32 kind) override; + ErrorOr GetBlob() override; + + public: + bool IsLoaded() noexcept; + + private: +#ifdef __FSKIT_INCLUDES_NEFS__ + OwnPtr> fFile; +#else + OwnPtr> fFile; +#endif // __FSKIT_INCLUDES_NEFS__ + + Ref fPath; + VoidPtr fCachedBlob; + bool fFatBinary; + bool fBad; + }; + + namespace Utils + { + ProcessID rtl_create_process(PEFLoader& exec, const Int32& procKind) noexcept; + } // namespace Utils +} // namespace Kernel + +#endif // ifndef _INC_CODE_MANAGER_PEF_H_ diff --git a/dev/Kernel/KernelKit/Semaphore.h b/dev/Kernel/KernelKit/Semaphore.h new file mode 100644 index 00000000..a5727d5e --- /dev/null +++ b/dev/Kernel/KernelKit/Semaphore.h @@ -0,0 +1,43 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include +#include +#include + +namespace Kernel +{ + class UserProcess; + + typedef UserProcess* UserProcessPtr; + + /// @brief Access control class, which locks a task until one is done. + class Semaphore final + { + public: + explicit Semaphore() = default; + ~Semaphore() = default; + + public: + bool IsLocked() const; + bool Unlock() noexcept; + + public: + void WaitForProcess() noexcept; + + public: + bool Lock(UserProcess* process); + bool LockOrWait(UserProcess* process, TimerInterface* timer); + + public: + ZKA_COPY_DEFAULT(Semaphore); + + private: + UserProcessPtr fLockingProcess{nullptr}; + }; +} // namespace Kernel diff --git a/dev/Kernel/KernelKit/ThreadLocalStorage.h b/dev/Kernel/KernelKit/ThreadLocalStorage.h new file mode 100644 index 00000000..646032d8 --- /dev/null +++ b/dev/Kernel/KernelKit/ThreadLocalStorage.h @@ -0,0 +1,65 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#ifndef KERNELKIT_TLS_H +#define KERNELKIT_TLS_H + +#include +#include + +///! @brief Thread Local Storage for minoskrnl. + +#define kCookieMag0 'Z' +#define kCookieMag1 'K' +#define kCookieMag2 'A' + +#define kTLSCookieLen (3U) + +struct THREAD_INFORMATION_BLOCK; + +/// @brief Thread Information Block. +/// Located in GS on AMD64, other architectures have their own stuff. (64x0, 32x0, ARM64) +struct PACKED THREAD_INFORMATION_BLOCK final +{ + Kernel::Char Cookie[kTLSCookieLen]{0}; //! Thread magic number. + Kernel::VoidPtr Record{nullptr}; //! Thread information record. +}; + +///! @brief Cookie Sanity check. +Kernel::Boolean tls_check_tib(THREAD_INFORMATION_BLOCK* the_tib); + +///! @brief new ptr syscall. +template +T* tls_new_ptr(void) noexcept; + +///! @brief delete ptr syscall. +template +Kernel::Boolean tls_delete_ptr(T* ptr) noexcept; + +//! @brief Delete process pointer. +//! @param obj The pointer to delete. +template +inline Kernel::Bool tls_delete_ptr(Kernel::ErrorOr obj) noexcept; + +//! @brief Delete process pointer. +//! @param obj The pointer to delete. +template +inline Kernel::Bool tls_delete_ptr(Kernel::ErrorOr obj) noexcept; + +template +T* tls_new_class(Args&&... args); + +/// @brief TLS install TIB and PIB. (syscall) +EXTERN_C Kernel::Void rt_install_tib(THREAD_INFORMATION_BLOCK* TIB, THREAD_INFORMATION_BLOCK* PIB); + +/// @brief TLS check (syscall) +EXTERN_C Kernel::Bool tls_check_syscall_impl(Kernel::VoidPtr TIB) noexcept; + +#include + +// last rev 7/7/24 + +#endif /* ifndef KERNELKIT_TLS_H */ diff --git a/dev/Kernel/KernelKit/ThreadLocalStorage.inl b/dev/Kernel/KernelKit/ThreadLocalStorage.inl new file mode 100644 index 00000000..e145ade5 --- /dev/null +++ b/dev/Kernel/KernelKit/ThreadLocalStorage.inl @@ -0,0 +1,99 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +//! @file ThreadLocalStorage.inl +//! @brief Allocate resources from the process's heap storage. + +#ifndef INC_PROCESS_SCHEDULER_H +#include +#endif + +template +inline T* tls_new_ptr(void) noexcept +{ + using namespace Kernel; + + auto ref_process = UserProcessScheduler::The().GetCurrentProcess(); + MUST_PASS(ref_process); + + auto pointer = ref_process.Leak().New(sizeof(T)); + + if (pointer.Error()) + return nullptr; + + return reinterpret_cast(pointer.Leak().Leak()); +} + +//! @brief Delete process pointer. +//! @param obj The pointer to delete. +template +inline Kernel::Bool tls_delete_ptr(T* obj) noexcept +{ + using namespace Kernel; + + if (!obj) + return No; + + auto ref_process = UserProcessScheduler::The().GetCurrentProcess(); + MUST_PASS(ref_process); + + ErrorOr obj_wrapped{obj}; + + return ref_process.Leak().Delete(obj_wrapped, sizeof(T)); +} + +//! @brief Delete process pointer. +//! @param obj The pointer to delete. +template +inline Kernel::Bool tls_delete_ptr(Kernel::ErrorOr obj) noexcept +{ + return tls_delete_ptr(obj.Leak()); +} + +//! @brief Delete process pointer. +//! @param obj The pointer to delete. +template +inline Kernel::Bool tls_delete_ptr(Kernel::ErrorOr obj) noexcept +{ + return tls_delete_ptr(obj->Leak()); +} + +/// @brief Allocate a C++ class, and then call the constructor of it. +/// @tparam T class type. +/// @tparam ...Args varg class type. +/// @param args arguments list. +/// @return Class instance. +template +T* tls_new_class(Args&&... args) +{ + using namespace Kernel; + + T* obj = tls_new_ptr(); + + if (obj) + { + *obj = T(forward(args)...); + return obj; + } + + return nullptr; +} + +/// @brief Delete a C++ class (call constructor first.) +/// @tparam T +/// @param obj +/// @return +template +inline Kernel::Bool tls_delete_class(T* obj) +{ + using namespace Kernel; + + if (!obj) + return No; + + obj->~T(); + return tls_delete_ptr(obj); +} diff --git a/dev/Kernel/KernelKit/Timer.h b/dev/Kernel/KernelKit/Timer.h new file mode 100644 index 00000000..bbeb1ab6 --- /dev/null +++ b/dev/Kernel/KernelKit/Timer.h @@ -0,0 +1,82 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include +#include +#include + +namespace Kernel +{ + class SoftwareTimer; + class TimerInterface; + + class TimerInterface + { + public: + /// @brief Default constructor + explicit TimerInterface() = default; + virtual ~TimerInterface() = default; + + public: + ZKA_COPY_DEFAULT(TimerInterface); + + public: + virtual Int32 Wait() noexcept; + }; + + class SoftwareTimer final : public TimerInterface + { + public: + explicit SoftwareTimer(Int64 seconds); + ~SoftwareTimer() override; + + public: + ZKA_COPY_DEFAULT(SoftwareTimer); + + public: + Int32 Wait() noexcept override; + + private: + IntPtr* fDigitalTimer{nullptr}; + Int64 fWaitFor{0}; + }; + + class HardwareTimer final : public TimerInterface + { + public: + explicit HardwareTimer(Int64 seconds); + ~HardwareTimer() override; + + public: + ZKA_COPY_DEFAULT(HardwareTimer); + + public: + Int32 Wait() noexcept override; + + private: + IntPtr* fDigitalTimer{nullptr}; + Int64 fWaitFor{0}; + }; + + inline Int64 Milliseconds(Int64 time) + { + if (time < 0) + return 0; + + // TODO: nanoseconds maybe? + return 1000 * 1000 * time; + } + + inline Int64 Seconds(Int64 time) + { + if (time < 0) + return 0; + + return 1000 * Milliseconds(time); + } +} // namespace Kernel diff --git a/dev/Kernel/KernelKit/User.h b/dev/Kernel/KernelKit/User.h new file mode 100644 index 00000000..be911830 --- /dev/null +++ b/dev/Kernel/KernelKit/User.h @@ -0,0 +1,83 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#ifndef INC_USER_H +#define INC_USER_H + +#include +#include +#include +#include + +///! We got the Super and guest user, both used to make authorization operations on the OS. +#define kSuperUser "OS AUTHORITY/SUPER" +#define kGuestUser "OS AUTHORITY/GUEST" + +#define kUsersDir "/Users/" + +#define kMaxUserNameLen (255U) +#define kMaxUserTokenLen (255U) + +namespace Kernel +{ + class User; + + enum class UserRingKind + { + kRingInvalid = 0, + kRingStdUser = 1, + kRingSuperUser = 2, + kRingGuestUser = 5, + kRingCount = 3, + }; + + typedef Char* usr_public_key_kind; + + class User final + { + public: + explicit User() = delete; + + User(const Int32& sel, const Char* userName); + User(const UserRingKind& kind, const Char* userName); + + ~User(); + + public: + ZKA_COPY_DEFAULT(User) + + public: + bool operator==(const User& lhs); + bool operator!=(const User& lhs); + + public: + /// @brief Get software ring + const UserRingKind& Ring() noexcept; + + /// @brief Get user name + Char* Name() noexcept; + + /// @brief Is he a standard user? + Bool IsStdUser() noexcept; + + /// @brief Is she a super user? + Bool IsSuperUser() noexcept; + + /// @brief Saves a password from the public key. + Bool Save(const usr_public_key_kind password) noexcept; + + /// @brief Checks if a password matches the **password**. + /// @param password the password to check. + Bool Matches(const usr_public_key_kind password) noexcept; + + private: + UserRingKind mUserRing{UserRingKind::kRingStdUser}; + Char mUserName[kMaxUserNameLen] = {0}; + Char mUserToken[kMaxUserTokenLen] = {0}; + }; +} // namespace Kernel + +#endif /* ifndef INC_USER_H */ diff --git a/dev/Kernel/KernelKit/UserProcessScheduler.h b/dev/Kernel/KernelKit/UserProcessScheduler.h new file mode 100644 index 00000000..073eb7d4 --- /dev/null +++ b/dev/Kernel/KernelKit/UserProcessScheduler.h @@ -0,0 +1,338 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#ifndef INC_PROCESS_SCHEDULER_H +#define INC_PROCESS_SCHEDULER_H + +#include +#include +#include +#include + +#define kSchedMinMicroTime (AffinityKind::kStandard) +#define kSchedInvalidPID (-1) +#define kSchedProcessLimitPerTeam (32U) + +#define kSchedMaxMemoryLimit gib_cast(128) +#define kSchedMaxStackSz mib_cast(8) + +#define kProcessInvalidID (-1) +#define kProcessNameLen (128U) + +//////////////////////////////////////////////////// +// The current date is: Thu 11/28/2024 // +//////////////////////////////////////////////////// + +namespace Kernel +{ + //! @note Forward class declarations. + + class UserProcess; + class IDLLObject; + class UserProcessTeam; + class UserProcessScheduler; + class UserProcessHelper; + + //! @brief Local Process identifier. + typedef Int64 ProcessID; + + //! @brief Local Process status enum. + enum class ProcessStatusKind : Int32 + { + kInvalid, + kStarting, + kRunning, + kKilled, + kFrozen, + kFinished, + kCount, + }; + + //! @brief Affinity is the amount of nano-seconds this process is going + //! to run. + enum class AffinityKind : Int32 + { + kRealTime = 500, + kVeryHigh = 250, + kHigh = 200, + kStandard = 1000, + kLowUsage = 1500, + kVeryLowUsage = 2000, + }; + + // operator overloading. + + inline bool operator<(AffinityKind lhs, AffinityKind rhs) + { + Int32 lhs_int = static_cast(lhs); + Int32 rhs_int = static_cast(rhs); + + return lhs_int < rhs_int; + } + + inline bool operator>(AffinityKind lhs, AffinityKind rhs) + { + Int32 lhs_int = static_cast(lhs); + Int32 rhs_int = static_cast(rhs); + + return lhs_int > rhs_int; + } + + inline bool operator<=(AffinityKind lhs, AffinityKind rhs) + { + Int32 lhs_int = static_cast(lhs); + Int32 rhs_int = static_cast(rhs); + + return lhs_int <= rhs_int; + } + + inline bool operator>=(AffinityKind lhs, AffinityKind rhs) + { + Int32 lhs_int = static_cast(lhs); + Int32 rhs_int = static_cast(rhs); + + return lhs_int >= rhs_int; + } + + // end of operator overloading. + + enum class ProcessSubsystem : Int32 + { + kProcessSubsystemSecurity = 100, + kProcessSubsystemApplication, + kProcessSubsystemService, + kProcessSubsystemDriver, + kProcessSubsystemInvalid = 255, + kProcessSubsystemCount = 4, + }; + + using ProcessTime = UInt64; + using PID = Int64; + + // for permission manager, tells where we run the code. + enum class ProcessLevelRing : Int32 + { + kRingStdUser = 1, + kRingSuperUser = 2, + kRingGuestUser = 5, + kRingCount = 5, + }; + + /// @brief Helper type to describe a code image. + using ImagePtr = VoidPtr; + + struct UserProcessImage final + { + explicit UserProcessImage() = default; + + ImagePtr fCode; + ImagePtr fBlob; + + operator bool() + { + return this->fCode; + } + + Bool HasImage() + { + return this->fBlob != nullptr; + } + }; + + /// @name UserProcess + /// @brief User process class, holds information about the running process/thread. + class UserProcess final + { + public: + explicit UserProcess(); + ~UserProcess(); + + public: + ZKA_COPY_DEFAULT(UserProcess); + + public: + Char Name[kProcessNameLen] = {"Process (Unnamed)"}; + ProcessSubsystem SubSystem{ProcessSubsystem::kProcessSubsystemInvalid}; + User* Owner{nullptr}; + HAL::StackFramePtr StackFrame{nullptr}; + AffinityKind Affinity{AffinityKind::kStandard}; + ProcessStatusKind Status{ProcessStatusKind::kFinished}; + UInt8* StackReserve{nullptr}; + UserProcessImage Image; + SizeT StackSize{kSchedMaxStackSz}; + IDLLObject* DylibDelegate{nullptr}; + SizeT MemoryCursor{0}; + SizeT MemoryLimit{kSchedMaxMemoryLimit}; + + struct UserProcessHeapList final + { + VoidPtr MemoryEntry{nullptr}; + SizeT MemoryEntrySize{0UL}; + SizeT MemoryEntryPad{0UL}; + + struct UserProcessHeapList* MemoryPrev{nullptr}; + struct UserProcessHeapList* MemoryNext{nullptr}; + }; + + struct UserProcessSignal final + { + UIntPtr SignalIP; + ProcessStatusKind PreviousStatus; + UIntPtr SignalID; + }; + + UserProcessSignal ProcessSignal; + UserProcessHeapList* ProcessMemoryHeap{nullptr}; + UserProcessTeam* ProcessParentTeam; + + VoidPtr VMRegister{0UL}; + + enum + { + kInvalidExecutableKind, + kExectuableKind, + kExectuableDLLKind, + kExectuableKindCount, + }; + + ProcessTime PTime{0}; //! @brief Process allocated tine. + + PID ProcessId{kSchedInvalidPID}; + Int32 Kind{kExectuableKind}; + + public: + //! @brief boolean operator, check status. + operator bool(); + + ///! @brief Crashes the app, exits with code ~0. + Void Crash(); + + ///! @brief Exits the app. + Void Exit(const Int32& exit_code = 0); + + ///! @brief TLS allocate. + ///! @param sz size of new ptr. + ErrorOr New(const SizeT& sz, const SizeT& pad_amount = 0); + + ///! @brief TLS free. + ///! @param ptr the pointer to free. + ///! @param sz the size of it. + template + Boolean Delete(ErrorOr ptr, const SizeT& sz); + + ///! @brief Wakes up threads. + Void Wake(const Bool wakeup = false); + + public: + //! @brief Gets the local exit code. + const UInt32& GetExitCode() noexcept; + + ///! @brief Get the process's name + ///! @example 'C Runtime Library' + const Char* GetName() noexcept; + + //! @brief return local error code of process. + //! @return Int32 local error code. + Int32& GetLocalCode() noexcept; + + const User* GetOwner() noexcept; + const ProcessStatusKind& GetStatus() noexcept; + const AffinityKind& GetAffinity() noexcept; + + private: + UInt32 fLastExitCode{0}; + Int32 fLocalCode{0}; + + friend UserProcessScheduler; + friend UserProcessHelper; + }; + + /// \brief Processs Team (contains multiple processes inside it.) + /// Equivalent to a process batch + class UserProcessTeam final + { + public: + explicit UserProcessTeam(); + ~UserProcessTeam() = default; + + ZKA_COPY_DEFAULT(UserProcessTeam); + + Array& AsArray(); + Ref& AsRef(); + ProcessID& Id() noexcept; + + public: + Array mProcessList; + Ref mCurrentProcess; + ProcessID mTeamId{0}; + ProcessID mProcessCount{0}; + }; + + using UserProcessPtr = UserProcess*; + + /// @brief Process scheduler class. + /// The main class which you call to schedule user processes. + class UserProcessScheduler final : public ISchedulable + { + friend class UserProcessHelper; + + public: + explicit UserProcessScheduler() = default; + ~UserProcessScheduler() override = default; + + ZKA_COPY_DEFAULT(UserProcessScheduler) + + operator bool(); + bool operator!(); + + public: + UserProcessTeam& CurrentTeam(); + + public: + ProcessID Spawn(UserProcess* process); + const Bool Remove(ProcessID process_id); + + const Bool IsUser() override; + const Bool IsKernel() override; + const Bool HasMP() override; + + public: + Ref& GetCurrentProcess(); + const SizeT Run() noexcept; + + public: + STATIC UserProcessScheduler& The(); + + private: + UserProcessTeam mTeam{}; + }; + + /* + * \brief UserProcess helper class, which contains needed utilities for the scheduler. + */ + + class UserProcessHelper final + { + public: + STATIC Bool Switch(VoidPtr image_ptr, UInt8* stack_ptr, HAL::StackFramePtr frame_ptr, const PID& new_pid); + STATIC Bool CanBeScheduled(const UserProcess* process); + STATIC ErrorOr TheCurrentPID(); + STATIC SizeT StartScheduling(); + }; + + const UInt32& sched_get_exit_code(void) noexcept; +} // namespace Kernel + +#include +#include + +//////////////////////////////////////////////////// + +// END + +//////////////////////////////////////////////////// + +#endif /* ifndef INC_PROCESS_SCHEDULER_H */ diff --git a/dev/Kernel/KernelKit/UserProcessScheduler.inl b/dev/Kernel/KernelKit/UserProcessScheduler.inl new file mode 100644 index 00000000..2973d6a4 --- /dev/null +++ b/dev/Kernel/KernelKit/UserProcessScheduler.inl @@ -0,0 +1,40 @@ +namespace Kernel +{ + /***********************************************************************************/ + /** @brief Free pointer from usage. */ + /***********************************************************************************/ + + template + Boolean UserProcess::Delete(ErrorOr ptr, const SizeT& sz) + { + if (!ptr || + sz == 0) + return No; + + UserProcessHeapList* entry = this->ProcessMemoryHeap; + + while (entry != nullptr) + { + if (entry->MemoryEntry == ptr.Leak().Leak()) + { +#ifdef __ZKA_AMD64__ + auto pd = hal_read_cr3(); + hal_write_cr3(this->VMRegister); + + auto ret = mm_delete_heap(entry->MemoryEntry); + + hal_write_cr3(pd); + + return ret; +#else + Bool ret = mm_delete_heap(ptr.Leak().Leak()); + return ret; +#endif + } + + entry = entry->MemoryNext; + } + + return No; + } +} // namespace Kernel diff --git a/dev/Kernel/KernelKit/XCOFF.h b/dev/Kernel/KernelKit/XCOFF.h new file mode 100644 index 00000000..386ee190 --- /dev/null +++ b/dev/Kernel/KernelKit/XCOFF.h @@ -0,0 +1,51 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + + File: XCOFF.hpp + Purpose: XCOFF for Kernel. + + Revision History: + + 04/07/24: Added file (amlel) + +------------------------------------------- */ + +#ifndef INC_XOCFF_H +#define INC_XOCFF_H + +#include + +#define kXCOFF64Magic (0x01F7) + +#define kXCOFFRelFlg (0x0001) +#define kXCOFFExecutable (0x0002) +#define kXCOFFLnno (0x0004) +#define kXCOFFLSyms (0x0008) + +struct XCoffFileHeader; +struct XCoffForkHeader; + +/// @brief XCoff file header, meant for POWER apps. +typedef struct XCoffFileHeader +{ + Kernel::UInt16 fMagic; + Kernel::UInt16 fTarget; + Kernel::UInt16 fNumSecs; + Kernel::UInt32 fTimeDat; + Kernel::UIntPtr fSymPtr; + Kernel::UInt32 fNumSyms; + Kernel::UInt16 fOptHdr; // ?: Number of bytes in optional header +} XCoffFileHeader64; + +#define cForkNameLen (255) + +/// @brief This the executable manifest fork. +typedef struct XCoffForkHeader +{ + Kernel::Char fPropertiesXMLFork[cForkNameLen]; + Kernel::Char fDynamicLoaderFork[cForkNameLen]; + Kernel::Char fCodeSignFork[cForkNameLen]; +} XCoffForkHeader; + +#endif // ifndef INC_XOCFF_H diff --git a/dev/Kernel/KernelRsrc.rsrc b/dev/Kernel/KernelRsrc.rsrc new file mode 100644 index 00000000..478d5208 --- /dev/null +++ b/dev/Kernel/KernelRsrc.rsrc @@ -0,0 +1,25 @@ +#include "CompilerKit/Version.h" + +1 VERSIONINFO +FILEVERSION 1,0,0,0 +PRODUCTVERSION 1,0,0,0 +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "080904E4" + BEGIN + VALUE "CompanyName", "TQ B.V." + VALUE "FileDescription", "ZKA Minimal Kernel." + VALUE "FileVersion", KERNEL_VERSION + VALUE "InternalName", "minoskrnl" + VALUE "LegalCopyright", "(c) 2024 TQ B.V, all rights reserved." + VALUE "OriginalFilename", "minoskrnl.exe" + VALUE "ProductName", "ZKA Minimal Kernel." + VALUE "ProductVersion", KERNEL_VERSION + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x809, 1252 + END +END diff --git a/dev/Kernel/MoveAll.ARM64.sh b/dev/Kernel/MoveAll.ARM64.sh new file mode 100644 index 00000000..35e0909e --- /dev/null +++ b/dev/Kernel/MoveAll.ARM64.sh @@ -0,0 +1,7 @@ +#! /bin/sh + +for file in *.o; do + mv -- "$file" "${file%.o}.obj" +done + +mv *.obj obj/ diff --git a/dev/Kernel/MoveAll.X64.sh b/dev/Kernel/MoveAll.X64.sh new file mode 100644 index 00000000..1c135d06 --- /dev/null +++ b/dev/Kernel/MoveAll.X64.sh @@ -0,0 +1,7 @@ +#! /bin/sh + +for file in *.o; do + mv -- "$file" "${file%.o}.obj" +done + +mv *.obj HALKit/AMD64/*.obj obj/ diff --git a/dev/Kernel/NetworkKit/IP.h b/dev/Kernel/NetworkKit/IP.h new file mode 100644 index 00000000..c8a12d7c --- /dev/null +++ b/dev/Kernel/NetworkKit/IP.h @@ -0,0 +1,83 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include +#include +#include +#include + +namespace Kernel +{ + class RawIPAddress6; + class RawIPAddress; + class IPFactory; + + class RawIPAddress final + { + private: + explicit RawIPAddress(char bytes[4]); + ~RawIPAddress() = default; + + RawIPAddress& operator=(const RawIPAddress&) = delete; + RawIPAddress(const RawIPAddress&) = default; + + public: + char* Address(); + + char& operator[](const Size& index); + + bool operator==(const RawIPAddress& ipv6); + bool operator!=(const RawIPAddress& ipv6); + + private: + char fAddr[4]; + + friend IPFactory; // it is the one creating these addresses, thus this + // is why the constructors are private. + }; + + /** + * @brief IPv6 address. + */ + class RawIPAddress6 final + { + private: + explicit RawIPAddress6(char Bytes[8]); + ~RawIPAddress6() = default; + + RawIPAddress6& operator=(const RawIPAddress6&) = delete; + RawIPAddress6(const RawIPAddress6&) = default; + + public: + char* Address() + { + return fAddr; + } + + char& operator[](const Size& index); + + bool operator==(const RawIPAddress6& ipv6); + bool operator!=(const RawIPAddress6& ipv6); + + private: + char fAddr[8]; + + friend IPFactory; + }; + + /** + * @brief IP Creation helpers + */ + class IPFactory final + { + public: + static ErrorOr ToKString(Ref& ipv6); + static ErrorOr ToKString(Ref& ipv4); + static bool IpCheckVersion4(const Char* ip); + }; +} // namespace Kernel diff --git a/dev/Kernel/NetworkKit/IPC.h b/dev/Kernel/NetworkKit/IPC.h new file mode 100644 index 00000000..8496282c --- /dev/null +++ b/dev/Kernel/NetworkKit/IPC.h @@ -0,0 +1,107 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved.. + + File: IPC.h. + Purpose: IPC protocol. + +------------------------------------------- */ + +#ifndef INC_IPC_H +#define INC_IPC_H + +#include +#include +#include +#include + +/// @file IPC.h +/// @brief IPC comm. protocol. + +/// IA separator. +#define kIPCRemoteSeparator ":" + +/// Interchange address, consists of PID:TEAM. +#define kIPCRemoteInvalid "00:00" + +#define kIPCHeaderMagic (0x4950434) + +namespace Kernel +{ + struct IPCAddress; + struct IPCMessage; + + /// @brief 128-bit IPC address. + struct PACKED IPCAddress final + { + UInt64 UserProcessID; + UInt64 UserProcessTeam; + + //////////////////////////////////// + // some operators. + //////////////////////////////////// + + bool operator==(const IPCAddress& addr) noexcept + { + return addr.UserProcessID == this->UserProcessID && addr.UserProcessTeam == this->UserProcessTeam; + } + + bool operator==(IPCAddress& addr) noexcept + { + return addr.UserProcessID == this->UserProcessID && addr.UserProcessTeam == this->UserProcessTeam; + } + }; + + typedef struct IPCAddress IPCEPAddressKind; + + enum + { + kIPCLittleEndian = 0, + kIPCBigEndian = 1, + kIPCMixedEndian = 2, + }; + + constexpr inline auto kIPCMsgSize = 6094U; + + /// @brief IPC connection header, message cannot be greater than 6K. + typedef struct IPCMessage final + { + UInt32 IpcHeaderMagic; // cRemoteHeaderMagic + UInt8 IpcEndianess; // 0 : LE, 1 : BE + SizeT IpcPacketSize; + IPCEPAddressKind IpcFrom; + IPCEPAddressKind IpcTo; + UInt32 IpcCRC32; + UInt32 IpcMsg; + UInt32 IpcMsgSz; + UInt8 IpcData[kIPCMsgSize]; + + /// @brief Passes the message to target, could be anything, HTTP packet, JSON or whatever. + Bool Pass(IPCMessage* target) noexcept + { + if (target && target->IpcFrom == this->IpcTo) + { + if (this->IpcMsgSz > target->IpcMsgSz) + return No; + + rt_copy_memory(this->IpcData, target->IpcData, this->IpcMsgSz); + + return Yes; + } + + return No; + } + } PACKED IPCMessage; + + /// @brief Sanitize packet function + /// @retval true packet is correct. + /// @retval false packet is incorrect and process has crashed. + Bool ipc_sanitize_packet(_Input IPCMessage* pckt_in); + + /// @brief Construct packet function + /// @retval true packet is correct. + /// @retval false packet is incorrect and process has crashed. + Bool ipc_construct_packet(_Output _Input IPCMessage** pckt_in); +} // namespace Kernel + +#endif // INC_IPC_H diff --git a/dev/Kernel/NetworkKit/LTE.h b/dev/Kernel/NetworkKit/LTE.h new file mode 100644 index 00000000..5d10a7d7 --- /dev/null +++ b/dev/Kernel/NetworkKit/LTE.h @@ -0,0 +1,16 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved.. + + File: LTE.h. + Purpose: LTE protocol classes. + +------------------------------------------- */ + +#ifndef _INC_NETWORK_LTE_H_ +#define _INC_NETWORK_LTE_H_ + +#include +#include + +#endif // ifndef _INC_NETWORK_LTE_H_ diff --git a/dev/Kernel/NetworkKit/MAC.h b/dev/Kernel/NetworkKit/MAC.h new file mode 100644 index 00000000..9119bc5c --- /dev/null +++ b/dev/Kernel/NetworkKit/MAC.h @@ -0,0 +1,29 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include +#include +#include + +namespace Kernel +{ + class MacAddressGetter; + + /// \brief This retrieves the MAC address of the device. + /// \note Listens for the current NIC. + class MacAddressGetter final + { + public: + explicit MacAddressGetter() = default; + + public: + KString& AsString(); + Array& AsBytes(); + }; + +} // namespace Kernel diff --git a/dev/Kernel/NetworkKit/NetworkDevice.h b/dev/Kernel/NetworkKit/NetworkDevice.h new file mode 100644 index 00000000..9511f89c --- /dev/null +++ b/dev/Kernel/NetworkKit/NetworkDevice.h @@ -0,0 +1,83 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#ifndef __INC_NETWORK_DEVICE_H__ +#define __INC_NETWORK_DEVICE_H__ + +#include +#include + +/// @note Can either work with: Ethernet, GPRS, WiFi + +namespace Kernel +{ + struct NetworkDeviceCommand; + class NetworkDevice; + + /** + * \brief Network device interface, establishes a connection to the NIC. + */ + class NetworkDevice final : public IDeviceObject + { + public: + NetworkDevice(void (*out)(NetworkDeviceCommand), + void (*in)(NetworkDeviceCommand), + void (*onCleanup)(void) = nullptr); + + ~NetworkDevice() override; + + public: + NetworkDevice& operator=(const NetworkDevice&) = default; + NetworkDevice(const NetworkDevice&) = default; + + public: + const Char* Name() const override; + Boolean Name(const Char* newStr); + + private: + static constexpr auto cNetworkNameLen = 512; + + Void (*fCleanup)(void); + Char fNetworkName[cNetworkNameLen]; + }; + + struct NetworkDeviceCommand final + { + UInt32 CommandName; + UInt32 CommandType; + UInt32 CommandFlags; + VoidPtr CommandBuffer; + SizeT CommandSizeBuffer; + }; + + /// @brief TCP device. + using TCPNetworkDevice = NetworkDevice; + + /// @brief UDP device. + using UDPNetworkDevice = NetworkDevice; + + /// @brief PPP device. + using PPPNetworkDevice = NetworkDevice; + + /// @brief IPC device. + using IPCEPNetworkDevice = NetworkDevice; + + /// @brief GRPS device. + using GPRSNetworkDevice = NetworkDevice; + + /// @brief GSM device. + using GSMNetworkDevice = NetworkDevice; + + /// @brief Bluetooth device. + using BTNetworkDevice = NetworkDevice; + + /// @brief LTE device. + using LTENetworkDevice = NetworkDevice; +} // namespace Kernel + +#include + +#endif // !__INC_NETWORK_DEVICE_H__ diff --git a/dev/Kernel/NetworkKit/NetworkDevice.inl b/dev/Kernel/NetworkKit/NetworkDevice.inl new file mode 100644 index 00000000..ce0fadd3 --- /dev/null +++ b/dev/Kernel/NetworkKit/NetworkDevice.inl @@ -0,0 +1,32 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +/*** + Dtor and ctors. +*/ + +namespace Kernel +{ + NetworkDevice::NetworkDevice(void (*out)(NetworkDeviceCommand), + void (*in)(NetworkDeviceCommand), + void (*on_cleanup)(void)) + : IDeviceObject(out, in), fCleanup(on_cleanup) + { + kcout << "NetworkDevice initialized.\r"; + + MUST_PASS(out && in && on_cleanup); + } + + NetworkDevice::~NetworkDevice() + { + MUST_PASS(fCleanup); + + kcout << "NetworkDevice cleanup.\r"; + + if (fCleanup) + fCleanup(); + } +} // namespace Kernel diff --git a/dev/Kernel/NewKit/Array.h b/dev/Kernel/NewKit/Array.h new file mode 100644 index 00000000..6c69536e --- /dev/null +++ b/dev/Kernel/NewKit/Array.h @@ -0,0 +1,72 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include +#include +#include + +namespace Kernel +{ + template + class Array final + { + public: + explicit Array() = default; + ~Array() = default; + + Array& operator=(const Array&) = default; + Array(const Array&) = default; + + T& operator[](const SizeT& At) + { + return fArray[At]; + } + + T Assign(const SizeT& At, T NewVal) + { + fArray[At] = NewVal; + return fArray[At]; + } + + Boolean Empty() + { + return this->Count() > 0; + } + + const SizeT Capacity() + { + return N; + } + + const SizeT Count() + { + SizeT count = 0; + + for (SizeT i = 0; i < N; i++) + { + if (fArray[i]) + ++count; + } + + return count; + } + + const T* CData() + { + return fArray; + } + + operator bool() + { + return !Empty(); + } + + private: + T fArray[N]; + }; +} // namespace Kernel diff --git a/dev/Kernel/NewKit/ArrayList.h b/dev/Kernel/NewKit/ArrayList.h new file mode 100644 index 00000000..822ecab4 --- /dev/null +++ b/dev/Kernel/NewKit/ArrayList.h @@ -0,0 +1,58 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include + +namespace Kernel +{ + template + class ArrayList final + { + public: + explicit ArrayList(T* list) + : fList(reinterpret_cast(list)) + { + } + + ~ArrayList() = default; + + ArrayList& operator=(const ArrayList&) = default; + ArrayList(const ArrayList&) = default; + + T* Data() + { + return fList; + } + + const T* CData() + { + return fList; + } + + T& operator[](int index) const + { + return fList[index]; + } + + operator bool() + { + return fList; + } + + private: + T* fList; + + friend class InitHelpers; + }; + + template + ArrayList make_list(ValueType val) + { + return ArrayList{val}; + } +} // namespace Kernel diff --git a/dev/Kernel/NewKit/Atom.h b/dev/Kernel/NewKit/Atom.h new file mode 100644 index 00000000..b858abe8 --- /dev/null +++ b/dev/Kernel/NewKit/Atom.h @@ -0,0 +1,46 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ +#pragma once + +#include + +namespace Kernel +{ + template + class Atom final + { + public: + explicit Atom() = default; + ~Atom() = default; + + public: + Atom& operator=(const Atom&) = delete; + Atom(const Atom&) = delete; + + public: + T operator[](Size sz) + { + return (fArrayOfAtoms & sz); + } + void operator|(Size sz) + { + fArrayOfAtoms |= sz; + } + + friend Boolean operator==(Atom& atomic, const T& idx) + { + return atomic[idx] == idx; + } + + friend Boolean operator!=(Atom& atomic, const T& idx) + { + return atomic[idx] == idx; + } + + private: + T fArrayOfAtoms; + }; +} // namespace Kernel diff --git a/dev/Kernel/NewKit/Crc32.h b/dev/Kernel/NewKit/Crc32.h new file mode 100644 index 00000000..9bd4ac26 --- /dev/null +++ b/dev/Kernel/NewKit/Crc32.h @@ -0,0 +1,23 @@ +/* + * ======================================================== + * + * ZKA + * Date Added: 13/02/2023 + * Copyright (C) 2024, TQ B.V, all rights reserved., all rights reserved. + * + * ======================================================== + */ + +#ifndef CRC32_H +#define CRC32_H + +#include + +#define kCrcCnt (256) + +namespace Kernel +{ + UInt ke_calculate_crc32(const Char* crc, UInt len) noexcept; +} // namespace Kernel + +#endif // !CRC32_H diff --git a/dev/Kernel/NewKit/CxxAbi.h b/dev/Kernel/NewKit/CxxAbi.h new file mode 100644 index 00000000..c987bd6f --- /dev/null +++ b/dev/Kernel/NewKit/CxxAbi.h @@ -0,0 +1,28 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ +#pragma once + +#include + +#ifndef __TOOLCHAINKIT__ + +#define kAtExitMacDestructors (128) + +struct atexit_func_entry_t +{ + void (*destructor_func)(void*); + void* obj_ptr; + void* dso_handle; +}; + +typedef unsigned uarch_t; + +namespace cxxabiv1 +{ + typedef void* __guard; +} + +#endif // __GNUC__ diff --git a/dev/Kernel/NewKit/Defines.h b/dev/Kernel/NewKit/Defines.h new file mode 100644 index 00000000..ddf971b1 --- /dev/null +++ b/dev/Kernel/NewKit/Defines.h @@ -0,0 +1,186 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include + +#define NEWKIT_VERSION_STR "1.1.0" +#define NEWKIT_VERSION_BCD 0x01100 + +#ifdef __has_feature +#if !__has_feature(cxx_nullptr) +#if !__has_nullptr +#error !!! You must at least have nullptr featured on your C++ compiler. !!! +#endif +#endif +#endif + +/// @brief The **Kernel** namespace where it's API resides. +namespace Kernel +{ + using voidPtr = void*; + using VoidPtr = void*; + using nullPtr = decltype(nullptr); + using NullPtr = decltype(nullptr); + + using Int = int; + using Int32 = int; + using UShort = unsigned short; + using UInt16 = unsigned short; + using Short = short; + using Int16 = short; + using UInt = unsigned int; + using UInt32 = unsigned int; + using Long = __INT64_TYPE__; + using Int64 = __INT64_TYPE__; + using ULong = __UINT64_TYPE__; + using UInt64 = __UINT64_TYPE__; + using Boolean = bool; + using Bool = bool; + using Char = char; + using UChar = unsigned char; + using UInt8 = unsigned char; + + using SSize = Int64; + using SSizeT = Int64; + using Size = __SIZE_TYPE__; + using SizeT = __SIZE_TYPE__; + using IntPtr = __INTPTR_TYPE__; + using UIntPtr = __UINTPTR_TYPE__; + using IntFast = __INT_FAST32_TYPE__; + using IntFast64 = __INT_FAST64_TYPE__; + using PtrDiff = __PTRDIFF_TYPE__; + + using SInt16 = Int16; + using SInt32 = Int32; + using SInt64 = Int64; + + typedef UIntPtr* Ptr64; + typedef UInt32* Ptr32; + typedef UInt8* Ptr8; + + using Utf8Char = char8_t; + using Utf16Char = char16_t; + using WideChar = wchar_t; + using Utf32Char = char32_t; + + typedef UInt32 PhysicalAddressKind; + typedef UIntPtr VirtualAddressKind; + + using Void = void; + + using Lba = UInt64; + + enum class Endian : UInt8 + { + kEndianInvalid, + kEndianBig, + kEndianLittle, + kEndianMixed, + kEndianCount + }; + + /// @brief Forward object. + /// @tparam Args the object type. + /// @param arg the object. + /// @return object's rvalue + template + inline Args&& forward(Args& arg) + { + return static_cast(arg); + } + + /// @brief Move object. + /// @tparam Args the object type. + /// @param arg the object. + /// @return object's rvalue + template + inline Args&& move(Args&& arg) + { + return static_cast(arg); + } + + /// @brief Encoding interface, used as a proxy to convert T to Char* + /// Used to cast A to B or B to A. + class ICodec + { + public: + explicit ICodec() = default; + virtual ~ICodec() = default; + + ICodec& operator=(const ICodec&) = default; + ICodec(const ICodec&) = default; + + public: + /// @brief Convert type to bytes. + /// @tparam T the type. + /// @param type (a1) the data. + /// @return a1 as Char* + template + Char* AsBytes(T type) noexcept + { + return nullptr; + } + + /// @brief Construct from type to class. + /// @tparam T the type to convert. + /// @param type (a1) the data. + /// @return a1 as Char* + template + OutputClass* Construct(Char* type) noexcept + { + FactoryClass class_fac; + return class_fac.template From(type); + } + + /// @brief Convert T class to Y class. + /// @tparam T the class type of type. + /// @tparam Y the result class. + /// @param type the class to cast. + /// @return the class as Y. + template + Y As(T type) noexcept + { + if (type.template IsSerializable()) + { + return reinterpret_cast(type); + } + + return type.template As(); + } + }; + + /// \brief Scheduler interface, represents a scheduler object. + /// @note This is used to schedule tasks, such as threads, drivers, user threads, etc. + class ISchedulable + { + public: + explicit ISchedulable() = default; + virtual ~ISchedulable() = default; + + ISchedulable& operator=(const ISchedulable&) = default; + ISchedulable(const ISchedulable&) = default; + + /// @brief Is this object only accepting user tasks? + virtual const Bool IsUser() + { + return NO; + } + + /// @brief Is this object only accepting kernel tasks? + virtual const Bool IsKernel() + { + return NO; + } + + /// @brief Is this object offloading to another CPU? + virtual const Bool HasMP() + { + return NO; + } + }; +} // namespace Kernel diff --git a/dev/Kernel/NewKit/ErrorOr.h b/dev/Kernel/NewKit/ErrorOr.h new file mode 100644 index 00000000..c33e6f2b --- /dev/null +++ b/dev/Kernel/NewKit/ErrorOr.h @@ -0,0 +1,77 @@ +/* + * ======================================================== + * + * ZKA + * Copyright (C) 2024, TQ B.V, all rights reserved., all rights reserved. + * + * ======================================================== + */ + +#pragma once + +#include +#include + +namespace Kernel +{ + using ErrorT = UInt; + + template + class ErrorOr final + { + public: + ErrorOr() = default; + ~ErrorOr() = default; + + public: + explicit ErrorOr(Int32 err) + : mId(err) + { + } + + explicit ErrorOr(nullPtr Null) + { + } + + explicit ErrorOr(T* Class) + : mRef(Class) + { + } + + explicit ErrorOr(T Class) + : mRef(Class) + { + } + + ErrorOr& operator=(const ErrorOr&) = default; + ErrorOr(const ErrorOr&) = default; + + ErrorOr& operator=(const Ref& refErr) + { + mRef = refErr; + return *this; + } + + Ref& Leak() + { + return mRef; + } + + Int32 Error() + { + return mId; + } + + operator bool() + { + return mRef; + } + + private: + Ref mRef; + Int32 mId{0}; + }; + + using ErrorOrAny = ErrorOr; + +} // namespace Kernel diff --git a/dev/Kernel/NewKit/Function.h b/dev/Kernel/NewKit/Function.h new file mode 100644 index 00000000..9fa218af --- /dev/null +++ b/dev/Kernel/NewKit/Function.h @@ -0,0 +1,53 @@ +#ifndef _INC_FUNCTION_H__ +#define _INC_FUNCTION_H__ + +#include + +namespace Kernel +{ + template + class Function final + { + public: + Function() = default; + + public: + explicit Function(T (*Fn)(Args... args)) + : fFn(Fn) + { + } + + ~Function() = default; + + Function& operator=(const Function&) = default; + Function(const Function&) = default; + + template + T operator()(Args... args) + { + return fFn(args...); + } + + template + T Call(Args... args) + { + return fFn(args...); + } + + operator bool() + { + return fFn; + } + + bool operator!() + { + return !fFn; + } + + private: + T(*fFn) + (Args... args); + }; +} // namespace Kernel + +#endif // !_INC_FUNCTION_H__ diff --git a/dev/Kernel/NewKit/Json.h b/dev/Kernel/NewKit/Json.h new file mode 100644 index 00000000..88c7b29b --- /dev/null +++ b/dev/Kernel/NewKit/Json.h @@ -0,0 +1,151 @@ + +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +// last-rev: 30/01/24 + +#include +#include +#include +#include +#include + +#define kMaxJsonPath 4096 +#define kJSONLen 32 +#define kJSONNull "null" + +namespace Kernel +{ + /// @brief Json class + class JSON final + { + public: + explicit JSON() + { + auto len = kJSONLen; + KString key = KString(len); + key += kJSONNull; + + this->AsKey() = key; + this->AsValue() = key; + } + + explicit JSON(SizeT lhsLen, SizeT rhsLen) + : fKey(lhsLen), fValue(rhsLen) + { + } + + ~JSON() = default; + + ZKA_COPY_DEFAULT(JSON); + + const Bool& IsUndefined() + { + return fUndefined; + } + + private: + Bool fUndefined; // is this instance undefined? + KString fKey; + KString fValue; + + public: + /// @brief returns the key of the json + /// @return the key as string view. + KString& AsKey() + { + return fKey; + } + + /// @brief returns the value of the json. + /// @return the key as string view. + KString& AsValue() + { + return fValue; + } + + static JSON kNull; + }; + + /// @brief Json stream reader helper. + struct JsonStreamReader final + { + STATIC JSON In(const Char* full_array) + { + auto start_val = '{'; + auto end_val = '}'; + Boolean probe_value = false; + + if (full_array[0] != start_val) + { + if (full_array[0] != '[') + return JSON::kNull; + + start_val = '['; + end_val = ']'; + + probe_value = true; + } + + SizeT len = rt_string_len(full_array); + + SizeT key_len = 0; + SizeT value_len = 0; + + JSON type(kMaxJsonPath, kMaxJsonPath); + + for (SizeT i = 1; i < len; ++i) + { + if (full_array[i] == '\r' || + full_array[i] == '\n') + continue; + + if (probe_value) + { + if (full_array[i] == end_val || + full_array[i] == ',') + { + probe_value = false; + + ++value_len; + } + else + { + type.AsValue().Data()[value_len] = full_array[i]; + + ++value_len; + } + } + else + { + if (start_val == '[') + continue; + + if (full_array[i] == ':') + { + probe_value = true; + type.AsKey().Data()[key_len] = 0; + ++key_len; + } + else + { + type.AsKey().Data()[key_len] = full_array[i]; + + ++key_len; + } + } + } + + type.AsValue().Data()[value_len] = 0; + + return type; + } + }; + + using JsonStream = Stream; +} // namespace Kernel diff --git a/dev/Kernel/NewKit/KString.h b/dev/Kernel/NewKit/KString.h new file mode 100644 index 00000000..aadd2128 --- /dev/null +++ b/dev/Kernel/NewKit/KString.h @@ -0,0 +1,94 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include +#include +#include +#include +#include + +#define cMinimumStringSize 8196 + +namespace Kernel +{ + /// @brief KString static string class. + class KString final + { + public: + explicit KString() + { + fDataSz = cMinimumStringSize; + + fData = new Char[fDataSz]; + MUST_PASS(fData); + + rt_set_memory(fData, 0, fDataSz); + } + + explicit KString(const SizeT& Sz) + : fDataSz(Sz) + { + MUST_PASS(Sz > 1); + + fData = new Char[Sz]; + MUST_PASS(fData); + + rt_set_memory(fData, 0, Sz); + } + + ~KString() + { + if (fData) + { + delete[] fData; + fData = nullptr; + } + } + + ZKA_COPY_DEFAULT(KString); + + Char* Data(); + const Char* CData() const; + Size Length() const; + + bool operator==(const Char* rhs) const; + bool operator!=(const Char* rhs) const; + + bool operator==(const KString& rhs) const; + bool operator!=(const KString& rhs) const; + + KString& operator+=(const Char* rhs); + KString& operator+=(const KString& rhs); + + operator bool() + { + return fData; + } + + bool operator!() + { + return fData; + } + + private: + Char* fData{nullptr}; + Size fDataSz{0}; + Size fCur{0}; + + friend class StringBuilder; + }; + + struct StringBuilder final + { + static ErrorOr Construct(const Char* data); + static const Char* FromBool(const Char* fmt, bool n); + static const Char* Format(const Char* fmt, const Char* from); + static bool Equals(const Char* lhs, const Char* rhs); + static bool Equals(const WideChar* lhs, const WideChar* rhs); + }; +} // namespace Kernel diff --git a/dev/Kernel/NewKit/Macros.h b/dev/Kernel/NewKit/Macros.h new file mode 100644 index 00000000..a337a60d --- /dev/null +++ b/dev/Kernel/NewKit/Macros.h @@ -0,0 +1,149 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#ifndef KIB +#define KIB(X) (Kernel::UInt64)((X) / 1024) +#endif + +#ifndef kib_cast +#define kib_cast(X) (Kernel::UInt64)((X)*1024) +#endif + +#ifndef MIB +#define MIB(X) (Kernel::UInt64)((Kernel::UInt64)KIB(X) / 1024) +#endif + +#ifndef mib_cast +#define mib_cast(X) (Kernel::UInt64)((Kernel::UInt64)kib_cast(X) * 1024) +#endif + +#ifndef GIB +#define GIB(X) (Kernel::UInt64)((Kernel::UInt64)MIB(X) / 1024) +#endif + +#ifndef gib_cast +#define gib_cast(X) (Kernel::UInt64)((Kernel::UInt64)mib_cast(X) * 1024) +#endif + +#ifndef TIB +#define TIB(X) (Kernel::UInt64)((Kernel::UInt64)GIB(X) / 1024) +#endif + +#ifndef tib_cast +#define tib_cast(X) ((Kernel::UInt64)gib_cast(X) * 1024) +#endif + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(a) \ + (((sizeof(a) / sizeof(*(a))) / \ + (static_cast(!(sizeof(a) % sizeof(*(a))))))) +#endif + +#define DEPRECATED ATTRIBUTE(deprecated) + +#ifndef ALIGN +#define ALIGN(X) __attribute__((aligned(X))) +#endif // #ifndef ALIGN + +#ifndef ATTRIBUTE +#define ATTRIBUTE(X) __attribute__((X)) +#endif // #ifndef ATTRIBUTE + +#ifndef __ZKA_VER__ +#define __ZKA_VER__ (2024) +#endif // !__ZKA_VER__ + +#ifndef EXTERN +#define EXTERN extern +#endif + +#ifndef EXTERN_C +#define EXTERN_C extern "C" +#endif + +#ifndef MAKE_ENUM +#define MAKE_ENUM(NAME) \ + enum NAME \ + { +#endif + +#ifndef END_ENUM +#define END_ENUM() \ + } \ + ; +#endif + +#ifndef MAKE_STRING_ENUM +#define MAKE_STRING_ENUM(NAME) \ + namespace NAME \ + { +#endif + +#ifndef ENUM_STRING +#define ENUM_STRING(NAME, VAL) inline constexpr const char* e##NAME = VAL +#endif + +#ifndef END_STRING_ENUM +#define END_STRING_ENUM() } +#endif + +#ifndef rtl_alloca +#define rtl_alloca(sz) __builtin_alloca(sz) +#endif // #ifndef rtl_alloca + +#ifndef CANT_REACH +#define CANT_REACH() __builtin_unreachable() +#endif + +#define kInvalidAddress 0xFBFBFBFBFBFBFBFB +#define kBadAddress 0x0000000000000000 +#define kMaxAddr 0xFFFFFFFFFFFFFFFF +#define kPathLen 0x100 + +#define PACKED ATTRIBUTE(packed) +#define NO_EXEC ATTRIBUTE(noexec) + +#define EXTERN extern +#define STATIC static + +#define CONST const + +#define STRINGIFY(X) #X +#define ZKA_UNUSED(X) ((Kernel::Void)X) + +#ifndef RGB +#define RGB(R, G, B) (Kernel::UInt32)(R | G << 0x8 | B << 0x10) +#endif // !RGB + +#ifdef __ZKA_AMD64__ +#define dbg_break_point() asm volatile("int $3") +#else +#define dbg_break_point() ((void)0) +#endif + +#define rtl_deduce_endianess(address, value) \ + (((reinterpret_cast(address)[0]) == (value)) \ + ? (Kernel::Endian::kEndianBig) \ + : (Kernel::Endian::kEndianLittle)) + +#define Yes true +#define No false + +#define YES true +#define NO false + +#define TRUE true +#define FALSE false + +#define BOOL Kernel::Boolean + +#ifdef INIT_OBJECT +#undef INIT_OBJECT +#endif // ifdef INIT_OBJECT + +#define INIT_OBJECT(OBJ, TYPE, ...) TYPE OBJ = TYPE(__VA_ARGS__) diff --git a/dev/Kernel/NewKit/MutableArray.h b/dev/Kernel/NewKit/MutableArray.h new file mode 100644 index 00000000..b3fbd2ac --- /dev/null +++ b/dev/Kernel/NewKit/MutableArray.h @@ -0,0 +1,239 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ +#pragma once + +#include +#include +#include + +#define TRY_FIND_NODE(NAME, NODE) \ + auto* NAME = NODE; \ + while (NAME) \ + { \ + if (NAME->fIndex == Index) \ + return NAME->fVal; \ + NAME = NAME->fNext; \ + } + +#define TRY_FIND_NODE2(NAME, NODE) \ + auto* NAME = NODE; \ + while (NAME) \ + { \ + if (NAME->fIndex == Index) \ + return Ref{NAME->fVal}; \ + NAME = NAME->fNext; \ + } + +#define TRY_REMOVE_NODE(NODE) \ + if (NODE && NODE->fIndex == Index) \ + { \ + NODE->fUsed = false; \ + NODE->fIndex = 0; \ + \ + return true; \ + } + +// FIXME: this is a shitty algorithm, which is consumer hungry. +// Remove and occurences of that, and remove that class. +namespace Kernel +{ + template + class MutableArray; + + template + class NullableMutableArray; + + template + class MutableLinkedList + { + public: + T fVal; + SizeT fIndex{0}; + Boolean fUsed{false}; + + MutableLinkedList* fPrev{nullptr}; + MutableLinkedList* fNext{nullptr}; + }; + + template + class NullableMutableArray + { + public: + // explicit this. + explicit NullableMutableArray() + : fFirstNode(new MutableLinkedList()) + { + } + + /* + * We free all the nodes allocated by the array + * and store the next one inside "NextIt" + */ + + virtual ~NullableMutableArray() + { + auto* It = fFirstNode; + MutableLinkedList* NextIt = nullptr; + + while (It) + { + NextIt = It->fNext; + delete It; + + It = NextIt; + } + } + + NullableMutableArray& operator=(const NullableMutableArray&) = default; + NullableMutableArray(const NullableMutableArray&) = default; + + operator bool() + { + return Count() > 1; + } + + public: + T operator[](const SizeT& Index) const + { + TRY_FIND_NODE(first, fFirstNode); + TRY_FIND_NODE(last, fLastNode); + + return _PlaceHolderValue; + } + + SizeT Count() const + { + return fNodeCount; + } + + public: + Boolean Remove(const SizeT& Index) + { + TRY_REMOVE_NODE(fFirstNode); + TRY_REMOVE_NODE(fLastNode); + + return false; + } + + Boolean Add(const T val) + { + auto* iterationNode = fFirstNode; + MUST_PASS(iterationNode); + + while (iterationNode) + { + if (!iterationNode->fUsed) + { + iterationNode->fVal = val; + iterationNode->fIndex = 0; + + iterationNode->fUsed = true; + + ++fNodeCount; + + return true; + } + + iterationNode = iterationNode->fNext; + } + + return false; + } + + private: + /* Avoid useless lookups */ + MutableLinkedList* fLastNode{nullptr}; + MutableLinkedList* fFirstNode{nullptr}; + + /* Number of nodes inside of this dynamic array. */ + Kernel::SizeT fNodeCount{0}; + + private: + // don't remove that + friend MutableArray; + }; + + template + class MutableArray : public NullableMutableArray + { + public: + // explicit this. + explicit MutableArray() = default; + virtual ~MutableArray() = default; + + ZKA_COPY_DEFAULT(MutableArray) + + public: + Boolean Add(const T val) + { + auto* iterationNode = fFirstNode; + + if (!iterationNode) + { + fFirstNode = new MutableLinkedList(); + iterationNode = fFirstNode; + } + + MUST_PASS(iterationNode); + + while (iterationNode) + { + if (!iterationNode->fUsed) + { + iterationNode->fVal = val; + iterationNode->fIndex = 0; + + iterationNode->fUsed = true; + + ++fNodeCount; + + return true; + } + + iterationNode = iterationNode->fNext; + } + + return false; + } + + public: + Ref operator[](const SizeT& Index) const + { + TRY_FIND_NODE2(first, fFirstNode); + TRY_FIND_NODE2(last, fLastNode); + + return {}; + } + + SizeT Count() const + { + return fNodeCount; + } + + bool Contains(T& value) noexcept + { + MutableLinkedList* first = fFirstNode; + + while (first) + { + if (first->fVal == value && first->fUsed) + return true; + + first = first->fNext; + } + + return false; + } + + private: + /* Avoid useless lookups */ + MutableLinkedList* fLastNode{nullptr}; + MutableLinkedList* fFirstNode{nullptr}; + + /* Number of nodes inside of this dynamic array. */ + Kernel::SizeT fNodeCount{0}; + }; +} // namespace Kernel diff --git a/dev/Kernel/NewKit/New.h b/dev/Kernel/NewKit/New.h new file mode 100644 index 00000000..5285eaa7 --- /dev/null +++ b/dev/Kernel/NewKit/New.h @@ -0,0 +1,18 @@ + +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ +#pragma once + +#include + +typedef __SIZE_TYPE__ size_t; // gcc will complain about that + +void* operator new(size_t ptr); +void* operator new[](size_t ptr); + +void operator delete(void* ptr); +void operator delete(void* ptr, unsigned long); +void operator delete[](void* ptr); diff --git a/dev/Kernel/NewKit/NewKit.h b/dev/Kernel/NewKit/NewKit.h new file mode 100644 index 00000000..11f6c7cd --- /dev/null +++ b/dev/Kernel/NewKit/NewKit.h @@ -0,0 +1,20 @@ + +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/dev/Kernel/NewKit/OwnPtr.h b/dev/Kernel/NewKit/OwnPtr.h new file mode 100644 index 00000000..6aadbfc3 --- /dev/null +++ b/dev/Kernel/NewKit/OwnPtr.h @@ -0,0 +1,94 @@ + +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include +#include +#include + +namespace Kernel +{ + template + class OwnPtr; + + template + class NonNullRefPtr; + + template + class OwnPtr final + { + public: + OwnPtr() + { + } + ~OwnPtr() + { + this->Delete(); + } + + OwnPtr& operator=(const OwnPtr&) = default; + OwnPtr(const OwnPtr&) = default; + + public: + template + bool New(Args&&... arg) + { + if (fCls) + { + return false; + } + + fCls = new T(arg...); + return fCls; + } + + void Delete() + { + if (fCls) + delete fCls; + + fCls = nullptr; + } + + T* operator->() const + { + return fCls; + }; + T* Raw() + { + return fCls; + } + + Ref AsRef() + { + return Ref(fCls); + } + + operator bool() + { + return fCls; + } + bool operator!() + { + return !fCls; + } + + private: + T* fCls; + }; + + template + OwnPtr make_ptr(Args... args) + { + OwnPtr ret; + ret.template New(forward(args)...); + MUST_PASS(ret); + + return ret; + } +} // namespace Kernel diff --git a/dev/Kernel/NewKit/PageMgr.h b/dev/Kernel/NewKit/PageMgr.h new file mode 100644 index 00000000..b8d14e87 --- /dev/null +++ b/dev/Kernel/NewKit/PageMgr.h @@ -0,0 +1,81 @@ +// a way to create and find our pages. +// I'm thinking about a separate way of getting a paged area. + +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include +#include + +namespace Kernel +{ + class PageMgr; + + class PTEWrapper final + { + public: + explicit PTEWrapper(Boolean Rw = false, Boolean User = false, Boolean ExecDisable = false, UIntPtr Address = 0); + + ~PTEWrapper(); + + PTEWrapper& operator=(const PTEWrapper&) = default; + PTEWrapper(const PTEWrapper&) = default; + + public: + const UIntPtr VirtualAddress(); + + Void NoExecute(const bool enable = false); + Bool NoExecute(); + + operator bool() + { + return fVirtAddr; + } + + bool Reclaim(); + bool Shareable(); + bool Present(); + bool Access(); + + private: + Boolean fRw; + Boolean fUser; + Boolean fExecDisable; + UIntPtr fVirtAddr; + Boolean fCache; + Boolean fShareable; + Boolean fWt; + Boolean fPresent; + Boolean fAccessed; + + private: + friend class PageMgr; + friend class Pmm; + }; + + struct PageMgr final + { + public: + PageMgr() = default; + ~PageMgr() = default; + + PageMgr& operator=(const PageMgr&) = default; + PageMgr(const PageMgr&) = default; + + public: + PTEWrapper Request(Boolean Rw, Boolean User, Boolean ExecDisable, SizeT Sz); + bool Free(Ref& wrapper); + + private: + void FlushTLB(); + + private: + friend PTEWrapper; + friend class Pmm; + }; +} // namespace Kernel diff --git a/dev/Kernel/NewKit/Pair.h b/dev/Kernel/NewKit/Pair.h new file mode 100644 index 00000000..65c06dda --- /dev/null +++ b/dev/Kernel/NewKit/Pair.h @@ -0,0 +1,14 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include + +namespace Kernel +{ + class Pair; +} // namespace Kernel diff --git a/dev/Kernel/NewKit/Pmm.h b/dev/Kernel/NewKit/Pmm.h new file mode 100644 index 00000000..7990a75f --- /dev/null +++ b/dev/Kernel/NewKit/Pmm.h @@ -0,0 +1,44 @@ + +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include +#include + +namespace Kernel +{ + class Pmm; + class PTEWrapper; + + class Pmm final + { + public: + explicit Pmm(); + ~Pmm(); + + Pmm& operator=(const Pmm&) = delete; + Pmm(const Pmm&) = default; + + Ref RequestPage(Boolean user = false, Boolean readWrite = false); + Boolean FreePage(Ref refPage); + + Boolean ToggleRw(Ref refPage, Boolean enable = true); + Boolean TogglePresent(Ref refPage, Boolean enable = true); + Boolean ToggleUser(Ref refPage, Boolean enable = true); + Boolean ToggleShare(Ref refPage, Boolean enable = true); + + /// @brief Get the page manager of this. + Ref& Leak() + { + return fPageMgr; + } + + private: + Ref fPageMgr; + }; +} // namespace Kernel diff --git a/dev/Kernel/NewKit/Ref.h b/dev/Kernel/NewKit/Ref.h new file mode 100644 index 00000000..4af94494 --- /dev/null +++ b/dev/Kernel/NewKit/Ref.h @@ -0,0 +1,108 @@ + +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#ifndef _NEWKIT_REF_H_ +#define _NEWKIT_REF_H_ + +#include +#include +#include + +namespace Kernel +{ + template + class Ref final + { + public: + Ref() = default; + + ~Ref() + { + if (mm_is_valid_heap(fClass)) + delete fClass; + } + + public: + Ref(T* cls) + : fClass(cls) + { + } + + Ref(T cls) + : fClass(&cls) + { + } + + Ref& operator=(T ref) + { + if (!fClass) + return *this; + + fClass = &ref; + return *this; + } + + public: + T operator->() const + { + MUST_PASS(*fClass); + return *fClass; + } + + T& Leak() noexcept + { + return *fClass; + } + + T& TryLeak() const noexcept + { + MUST_PASS(*fClass); + return *fClass; + } + + T operator*() + { + return *fClass; + } + + operator bool() noexcept + { + return fClass; + } + + private: + T* fClass{nullptr}; + }; + + template + class NonNullRef final + { + public: + NonNullRef() = delete; + NonNullRef(nullPtr) = delete; + + NonNullRef(T* ref) + : fRef(ref) + { + MUST_PASS(ref); + } + + Ref& operator->() + { + MUST_PASS(fRef); + return fRef; + } + + NonNullRef& operator=(const NonNullRef& ref) = delete; + NonNullRef(const NonNullRef& ref) = default; + + private: + Ref fRef{nullptr}; + }; +} // namespace Kernel + +#endif // ifndef _NEWKIT_REF_H_ diff --git a/dev/Kernel/NewKit/Stop.h b/dev/Kernel/NewKit/Stop.h new file mode 100644 index 00000000..8f3064c7 --- /dev/null +++ b/dev/Kernel/NewKit/Stop.h @@ -0,0 +1,71 @@ + +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include + +namespace Kernel +{ + void ke_runtime_check(bool bExpression, const Char* file, const Char* line); +} + +#define MUST_PASS_COMPILER(EXPR, MSG) static_assert(EXPR, MSG) + +#define __MUST_PASS(EXPR, FILE, LINE) \ + Kernel::ke_runtime_check(EXPR, FILE, STRINGIFY(LINE)) + +#ifdef __DEBUG__ +#define MUST_PASS(EXPR) __MUST_PASS((EXPR), __FILE__, __LINE__) +#define assert(EXPR) MUST_PASS(EXPR, RUNTIME_CHECK_EXPRESSION) +#else +#define MUST_PASS(EXPR) (Kernel::Void)(EXPR) +#define assert(EXPR) (Kernel::Void)(EXPR) +#endif + +enum RUNTIME_CHECK +{ + RUNTIME_CHECK_FAILED = -1, + RUNTIME_CHECK_POINTER = 0, + RUNTIME_CHECK_EXPRESSION, + RUNTIME_CHECK_FILE, + RUNTIME_CHECK_IPC, + RUNTIME_CHECK_TLS, + RUNTIME_CHECK_HANDSHAKE, + RUNTIME_CHECK_ACPI, + RUNTIME_CHECK_INVALID_PRIVILEGE, + RUNTIME_CHECK_PROCESS, + RUNTIME_CHECK_BAD_BEHAVIOR, + RUNTIME_CHECK_BOOTSTRAP, + RUNTIME_CHECK_UNEXCPECTED, + RUNTIME_CHECK_FILESYSTEM, + RUNTIME_CHECK_VIRTUAL_OUT_OF_MEM, + RUNTIME_CHECK_PAGE, + RUNTIME_CHECK_COUNT, +}; + +namespace Kernel +{ + /// @brief Dumping factory class. + class RecoveryFactory final + { + public: + STATIC Void Recover() noexcept; + }; + + void ke_stop(const Int32& id); +} // namespace Kernel + +#ifdef TRY +#undef TRY +#endif + +#define TRY(FN) \ + if (!FN()) \ + { \ + MUST_PASS(false); \ + } diff --git a/dev/Kernel/NewKit/Stream.h b/dev/Kernel/NewKit/Stream.h new file mode 100644 index 00000000..2fe0d306 --- /dev/null +++ b/dev/Kernel/NewKit/Stream.h @@ -0,0 +1,58 @@ + +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include +#include + +namespace Kernel +{ + template + class Stream final + { + public: + explicit Stream(Ref ref) + : fStream(ref) + { + } + + ~Stream() = default; + + Stream& operator=(const Stream&) = default; + Stream(const Stream&) = default; + + template + friend Stream& operator>>(Stream& Ks, Ref& Buf) + { + Ks.fKind = Ks.fStream->In(Buf); + return *Ks; + } + + template + friend Stream& operator<<(Stream& Ks, Ref& Buf) + { + Ks.fKind = Buf; + Ks.fStream->Out(Buf.Leak()); + return *Ks; + } + + Ref& AsStreamTrait() + { + return fStream; + } + + Ref& AsType() + { + return fKind; + } + + private: + Ref fStream; + Ref fKind; + }; +} // namespace Kernel diff --git a/dev/Kernel/NewKit/Utils.h b/dev/Kernel/NewKit/Utils.h new file mode 100644 index 00000000..ae6350ec --- /dev/null +++ b/dev/Kernel/NewKit/Utils.h @@ -0,0 +1,29 @@ + +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include + +namespace Kernel +{ + Int rt_copy_memory(const voidPtr src, voidPtr dst, Size len); + Int rt_move_memory(const voidPtr src, voidPtr dst, Size len); + voidPtr rt_set_memory(voidPtr dst, UInt32 val, Size len); + void rt_zero_memory(voidPtr pointer, Size len); + Int rt_string_cmp(const Char* src, const Char* cmp, Size len); + const Char* alloc_string(const Char* text); + Size rt_string_len(const Char* str); + Size rt_string_len(const Char* str, SizeT _len); + Boolean rt_to_string(Char* buf, Int limit, Int base); + Boolean is_newln(Char chr); + Boolean is_space(Char chr); + Int rt_to_uppercase(Int c); + Int rt_to_lower(Int c); + voidPtr rt_string_in_string(const Char* in, const Char* needle); + char* rt_string_has_char(Char* str, const Char chr); +} // namespace Kernel diff --git a/dev/Kernel/NewKit/Variant.h b/dev/Kernel/NewKit/Variant.h new file mode 100644 index 00000000..95718fae --- /dev/null +++ b/dev/Kernel/NewKit/Variant.h @@ -0,0 +1,70 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include +#include +#include + +namespace Kernel +{ + class Variant final + { + public: + enum class VariantKind + { + kString, + kBlob, + kNull, + kJson, + kXML, + }; + + public: + explicit Variant() = delete; + + public: + ZKA_COPY_DEFAULT(Variant); + + ~Variant() = default; + + public: + explicit Variant(KString* stringView) + : fPtr((VoidPtr)stringView), fKind(VariantKind::kString) + { + } + + explicit Variant(JSON* json) + : fPtr((VoidPtr)json), fKind(VariantKind::kJson) + { + } + + explicit Variant(nullPtr) + : fPtr(nullptr), fKind(VariantKind::kNull) + { + } + + explicit Variant(VoidPtr ptr) + : fPtr(ptr), fKind(VariantKind::kBlob) + { + } + + public: + const Char* ToString(); + VoidPtr Leak(); + + template + T* As() + { + return reinterpret_cast(fPtr); + } + + private: + voidPtr fPtr{nullptr}; + VariantKind fKind{VariantKind::kNull}; + }; +} // namespace Kernel diff --git a/dev/Kernel/POSIXKit/signal.h b/dev/Kernel/POSIXKit/signal.h new file mode 100644 index 00000000..7bfec0dd --- /dev/null +++ b/dev/Kernel/POSIXKit/signal.h @@ -0,0 +1,20 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +/** https://pubs.opengroup.org/onlinepubs/009695399/basedefs/signal.h.html */ + +#include + +typedef Kernel::UInt32 signal_t; + +#define SIGKILL 0 +#define SIGPAUS 1 +#define SIGEXEC 2 +#define SIGTRAP 3 +#define SIGABRT 4 +#define SIGCONT 5 diff --git a/dev/Kernel/POSIXKit/unix_layer.h b/dev/Kernel/POSIXKit/unix_layer.h new file mode 100644 index 00000000..74a5defa --- /dev/null +++ b/dev/Kernel/POSIXKit/unix_layer.h @@ -0,0 +1,11 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include +#include +#include diff --git a/dev/Kernel/ReadMe.md b/dev/Kernel/ReadMe.md new file mode 100644 index 00000000..f90bc5e5 --- /dev/null +++ b/dev/Kernel/ReadMe.md @@ -0,0 +1,3 @@ +# ZkaOS Minimal Kernel DLL. + +An EXE which takes the role of the Minimal Kernel Image. diff --git a/dev/Kernel/StorageKit/AHCI.h b/dev/Kernel/StorageKit/AHCI.h new file mode 100644 index 00000000..88fcfdc8 --- /dev/null +++ b/dev/Kernel/StorageKit/AHCI.h @@ -0,0 +1,33 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include +#include +#include + +namespace Kernel +{ + class AHCIDeviceInterface ZKA_DEVICE + { + public: + explicit AHCIDeviceInterface(void (*Out)(MountpointInterface* outpacket), + void (*In)(MountpointInterface* inpacket), + void (*Cleanup)(void)); + + virtual ~AHCIDeviceInterface(); + + public: + AHCIDeviceInterface& operator=(const AHCIDeviceInterface&) = default; + AHCIDeviceInterface(const AHCIDeviceInterface&) = default; + + const Char* Name() const override; + + private: + void (*fCleanup)(void) = {nullptr}; + }; +} // namespace Kernel diff --git a/dev/Kernel/StorageKit/ATA.h b/dev/Kernel/StorageKit/ATA.h new file mode 100644 index 00000000..d45bc164 --- /dev/null +++ b/dev/Kernel/StorageKit/ATA.h @@ -0,0 +1,39 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include +#include +#include +#include + +namespace Kernel +{ + /// @brief ATA device interface type. + class ATADeviceInterface : public IDeviceObject + { + public: + explicit ATADeviceInterface(void (*Out)(MountpointInterface* outpacket), + void (*In)(MountpointInterface* inpacket), + void (*Cleanup)(void)); + + virtual ~ATADeviceInterface(); + + public: + ATADeviceInterface& operator<<(MountpointInterface* Data) override; + ATADeviceInterface& operator>>(MountpointInterface* Data) override; + + public: + ATADeviceInterface& operator=(const ATADeviceInterface&) = default; + ATADeviceInterface(const ATADeviceInterface&) = default; + + const Char* Name() const override; + + private: + void (*fCleanup)(void) = {nullptr}; + }; +} // namespace Kernel diff --git a/dev/Kernel/StorageKit/NVME.h b/dev/Kernel/StorageKit/NVME.h new file mode 100644 index 00000000..db6e2f2a --- /dev/null +++ b/dev/Kernel/StorageKit/NVME.h @@ -0,0 +1,34 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include +#include + +namespace Kernel +{ + class NVMEDeviceInterface final ZKA_DEVICE + { + public: + explicit NVMEDeviceInterface(Void (*out)(MountpointInterface* out_packet), + Void (*in)(MountpointInterface* in_packet), + Void (*cleanup)(Void)); + + ~NVMEDeviceInterface() override; + + public: + ZKA_COPY_DEFAULT(NVMEDeviceInterface); + + const Char* Name() const override; + + public: + OwnPtr operator()(UInt32 dma_low, UInt32 dma_high, SizeT dma_sz); + + private: + Void (*fCleanup)(Void) = {nullptr}; + }; +} // namespace Kernel diff --git a/dev/Kernel/StorageKit/PRDT.h b/dev/Kernel/StorageKit/PRDT.h new file mode 100644 index 00000000..85e89e61 --- /dev/null +++ b/dev/Kernel/StorageKit/PRDT.h @@ -0,0 +1,36 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include +#include +#include + +#define kPrdtTransferSize (sizeof(Kernel::UShort)) + +namespace Kernel +{ + /// @brief Tranfer information about PRD. + enum kPRDTTransfer + { + kPRDTTransferInProgress, + kPRDTTransferIsDone, + kPRDTTransferCount, + }; + + /// @brief Physical Region Descriptor Table. + struct PRDT + { + UInt32 fPhysAddress; + UInt32 fSectorCount; + UInt8 fEndBit; + }; + + void construct_prdt(Ref& prd); + + EXTERN_C Int32 kPRDTTransferStatus; +} // namespace Kernel diff --git a/dev/Kernel/StorageKit/SCSI.h b/dev/Kernel/StorageKit/SCSI.h new file mode 100644 index 00000000..ffe8e9d2 --- /dev/null +++ b/dev/Kernel/StorageKit/SCSI.h @@ -0,0 +1,11 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include + +extern const scsi_packet_type<12> kCDRomPacketTemplate; diff --git a/dev/Kernel/StorageKit/StorageKit.h b/dev/Kernel/StorageKit/StorageKit.h new file mode 100644 index 00000000..0f241e9c --- /dev/null +++ b/dev/Kernel/StorageKit/StorageKit.h @@ -0,0 +1,22 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#define kDriveSectorSizeHDD (512U) +#define kDriveSectorSizeSSD (512U) +#define kDriveSectorSizeOptical (2048) + +namespace Kernel +{ + template + class IDeviceObject; + + class NVMEDeviceInterface; + class AHCIDeviceInterface; + class ATADeviceInterface; + class SCSIDeviceInterface; +} // namespace Kernel diff --git a/dev/Kernel/amd64-efi.make b/dev/Kernel/amd64-efi.make new file mode 100644 index 00000000..52b1ff5f --- /dev/null +++ b/dev/Kernel/amd64-efi.make @@ -0,0 +1,85 @@ +################################################## +# (c) TQ B.V, all rights reserved. +# This is the minoskrnl's makefile. +################################################## + +CC = x86_64-w64-mingw32-g++ +LD = x86_64-w64-mingw32-ld +CCFLAGS = -fshort-wchar -c -D__ZKA_AMD64__ -mno-red-zone -fno-rtti -fno-exceptions \ + -std=c++20 -D__ZKA_SUPPORT_NX__ -O0 -I../Vendor -D__FSKIT_INCLUDES_NEFS__ \ + -D__MINOSKRNL__ -D__HAVE_ZKA_APIS__ -D__FREESTANDING__ -D__ZKA__ -I./ -I../ -I../zba + +ASM = nasm + +DISK_DRV = + +ifneq ($(ATA_PIO_SUPPORT), ) +DISK_DRV = -D__ATA_PIO__ +endif + +ifneq ($(ATA_DMA_SUPPORT), ) +DISK_DRV = -D__ATA_DMA__ +endif + +ifneq ($(AHCI_SUPPORT), ) +DISK_DRV = -D__AHCI__ +endif + +ifneq ($(DEBUG_SUPPORT), ) +DEBUG_MACRO = -D__DEBUG__ +endif + +COPY = cp + +# Add assembler, linker, and object files variables. +ASMFLAGS = -f win64 + +# Kernel subsystem is 17 and entrypoint is hal_init_platform +LDFLAGS = -e hal_init_platform --subsystem=17 --image-base 0x4000000 +LDOBJ = obj/*.obj + +# This file is the Kernel, responsible of task, memory, driver, sci, disk and device management. +KERNEL_IMG = minoskrnl.exe + +.PHONY: error +error: + @echo "=== ERROR ===" + @echo "=> Use a specific target." + +MOVEALL=./MoveAll.X64.sh +WINDRES=x86_64-w64-mingw32-windres + +.PHONY: newos-amd64-epm +newos-amd64-epm: clean + $(WINDRES) KernelRsrc.rsrc -O coff -o KernelRsrc.obj + $(CC) $(CCFLAGS) $(DISK_DRV) $(DEBUG_MACRO) $(wildcard src/*.cc) \ + $(wildcard src/FS/*.cc) $(wildcard HALKit/AMD64/Storage/*.cc) \ + $(wildcard HALKit/AMD64/PCI/*.cc) $(wildcard src/Network/*.cc) $(wildcard src/Storage/*.cc) \ + $(wildcard HALKit/AMD64/*.cc) $(wildcard src/WS/*.cc) \ + $(wildcard HALKit/AMD64/*.s) + $(ASM) $(ASMFLAGS) HALKit/AMD64/HalInterruptAPI.asm + $(ASM) $(ASMFLAGS) HALKit/AMD64/HalCommonAPI.asm + $(ASM) $(ASMFLAGS) HALKit/AMD64/HalBoot.asm + $(ASM) $(ASMFLAGS) HALKit/AMD64/HalUtils.asm + $(MOVEALL) + +OBJCOPY=x86_64-w64-mingw32-objcopy + +.PHONY: link-amd64-epm +link-amd64-epm: + $(LD) $(LDFLAGS) $(LDOBJ) -o $(KERNEL_IMG) + +.PHONY: all +all: newos-amd64-epm link-amd64-epm + @echo "Kernel => OK." + +.PHONY: help +help: + @echo "=== HELP ===" + @echo "all: Build Kernel and link it." + @echo "link-amd64-epm: Link Kernel for EPM based disks." + @echo "newos-amd64-epm: Build Kernel for EPM based disks." + +.PHONY: clean +clean: + rm -f $(LDOBJ) $(wildcard *.o) $(KERNEL_IMG) diff --git a/dev/Kernel/arm64-efi.make b/dev/Kernel/arm64-efi.make new file mode 100644 index 00000000..9deebe0a --- /dev/null +++ b/dev/Kernel/arm64-efi.make @@ -0,0 +1,64 @@ +################################################## +# (c) TQ B.V, all rights reserved. +# This is the microKernel makefile. +################################################## + +CC = clang++ +LD = lld-link +CCFLAGS = -fshort-wchar -c -ffreestanding -MMD -mno-red-zone -D__ZKA_ARM64__ -fno-rtti -fno-exceptions -I./ \ + -target aarch64-unknown-windows \ + -std=c++20 -O3 -D__MINOSKRNL__ -D__ZKA_MINIMAL_OS__ -D__ZKA_NO_BUILTIN__ -D__HAVE_ZKA_APIS__ -D__ZKA__ -I../ + +ASM = clang++ + +DISKDRIVER = -D__USE_FLASH_MEM__ -D__USE_SAS__ -D__USE_SATA__ + +ifneq ($(DEBUG_SUPPORT), ) +DEBUG = -D__DEBUG__ +endif + +COPY = cp + +LDFLAGS = -subsystem:efi_application -entry:hal_init_platform /nodefaultlib +LDOBJ = obj/*.obj + +# This file is the Kernel, responsible of task management and memory. +KERNEL = minoskrnl.exe + +.PHONY: error +error: + @echo "=== ERROR ===" + @echo "=> Use a specific target." + +MOVEALL=./MoveAll.ARM64.sh + +.PHONY: newos-arm64-epm +newos-arm64-epm: clean + $(CC) $(CCFLAGS) $(DISKDRIVER) $(DEBUG) $(wildcard src/*.cc) \ + $(wildcard src/FS/*.cc) $(wildcard HALKit/ARM64/Storage/*.cc) \ + $(wildcard HALKit/ARM64/PCI/*.cc) $(wildcard src/Network/*.cc) $(wildcard src/Storage/*.cc) \ + $(wildcard HALKit/ARM64/*.cc) $(wildcard HALKit/ARM64/*.cpp) \ + $(wildcard HALKit/ARM64/*.s) $(wildcard HALKit/ARM64/APM/*.cc) + + $(MOVEALL) + +OBJCOPY=x86_64-w64-mingw32-objcopy + +.PHONY: link-arm64-epm +link-arm64-epm: + $(LD) $(LDFLAGS) $(LDOBJ) /out:$(KERNEL) + +.PHONY: all +all: newos-arm64-epm link-arm64-epm + @echo "Kernel => OK." + +.PHONY: help +help: + @echo "=== HELP ===" + @echo "all: Build Kernel and link it." + @echo "link-arm64-epm: Link Kernel for EPM based disks." + @echo "newos-arm64-epm: Build Kernel for EPM based disks." + +.PHONY: clean +clean: + rm -f $(LDOBJ) $(wildcard *.o) $(KERNEL) diff --git a/dev/Kernel/doc/Explicit Partition Map.pdf b/dev/Kernel/doc/Explicit Partition Map.pdf new file mode 100644 index 00000000..a73834cd Binary files /dev/null and b/dev/Kernel/doc/Explicit Partition Map.pdf differ diff --git a/dev/Kernel/doc/SPECIFICATION.md b/dev/Kernel/doc/SPECIFICATION.md new file mode 100644 index 00000000..0233643a --- /dev/null +++ b/dev/Kernel/doc/SPECIFICATION.md @@ -0,0 +1,63 @@ +=================================== + +# 0: General Information + +=================================== + +- ABI and Format: PEF/PE32+. +- Kernel architecture: Portable hybrid Kernel. +- Language: C++/(Assembly (AMD64, X64000, X86S, ARM64, POWER, RISCV)) + +=================================== + +# 1: The Kernel + +=================================== + +- Drive/Device Abstraction. +- SMP, Preemptive Multi Threading. +- Separation of Files/Devices. +- Networking. +- Hardware Abstraction Layer. +- Native Filesystem support (NeFS, FAT32 and ffs2). +- Program Loaders interfaces. +- TLS (Thread Local Storage) support. +- Semaphore, Locks, Timers. +- Canary mechanisms. +- Dynamic Sys. +- Cross Platform. +- Permission Selectors. + +=================================== + +# 2: The Filesystem + +=================================== + +- Catalog object with associated forks. +- Large storage support. +- Long file names. +- UNIX path style. + +================================== + +# 3: Common naming conventions: + +================================== + +- Kernel -> ke_init_x +- RunTime -> rt_copy_mem +- Hal -> hal_foo_bar +- Class methods -> Class::FooBar + +=================================== + +# 4: The zbaosldr + +=================================== + +- Capable of booting from a network drive. +- Loads a PE file which is the Kernel. +- Sanity checks, based on the number of sections. +- Handover compliant. +- Does check for a valid partition (useful in the case of recovering) diff --git a/dev/Kernel/doc/TODO-LIST.md b/dev/Kernel/doc/TODO-LIST.md new file mode 100644 index 00000000..6e8e4b4d --- /dev/null +++ b/dev/Kernel/doc/TODO-LIST.md @@ -0,0 +1,25 @@ +# TODO list + +- We need preemptive multi-threading. [ X ] +- We then need sync primitives. [ X ] +- We also need a system library for the OS. [ X ] +- We need a bootloader for AMD64 [ X ] + - Implement Boot Services [ X ] + - Design Handover [ X ] + - Load Kernel into memory [ X ] + - Fix bug in Kernel loader, which causes a 06 #UD. [ X ] + - Load Kernel [ X ] + - Add IDT [ X ] + - AHCI driver [ WiP ] +- Context switch x87/SSE/AVX registers [ X ] +- Framebuffer [ X ] +- ATA support [ X ] +- Make installer [ X ] + +Status: + +BootZ: Need to boot from EPM partition. [ X ] +
+minoskrnl: New Filesystem is done. [ X ] + +**Refer to Jira please!** diff --git a/dev/Kernel/obj/.hgkeep b/dev/Kernel/obj/.hgkeep new file mode 100644 index 00000000..e69de29b diff --git a/dev/Kernel/power64-cb.make b/dev/Kernel/power64-cb.make new file mode 100644 index 00000000..53c5bc77 --- /dev/null +++ b/dev/Kernel/power64-cb.make @@ -0,0 +1,4 @@ +################################################## +# (c) TQ B.V, all rights reserved. +# This is the microKernel makefile. +################################################## diff --git a/dev/Kernel/riscv64-cb.make b/dev/Kernel/riscv64-cb.make new file mode 100644 index 00000000..e69de29b diff --git a/dev/Kernel/src/ACPIFactoryInterface.cc b/dev/Kernel/src/ACPIFactoryInterface.cc new file mode 100644 index 00000000..4128d8bf --- /dev/null +++ b/dev/Kernel/src/ACPIFactoryInterface.cc @@ -0,0 +1,96 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include +#include +#include + +namespace Kernel +{ + /// @brief Finds a descriptor table inside ACPI XSDT. + ErrorOr ACPIFactoryInterface::Find(const Char* signature) + { + MUST_PASS(fRsdp); + + if (!signature) + return ErrorOr{-1}; + + if (*signature == 0) + return ErrorOr{-1}; + + RSDP* rsp_ptr = reinterpret_cast(this->fRsdp); + + if (rsp_ptr->Revision <= 1) + return ErrorOr{-1}; + + RSDT* xsdt = reinterpret_cast(rsp_ptr->RsdtAddress); + + Int64 num = (xsdt->Length - sizeof(SDT)) / sizeof(Int64); + + /*** + crucial to avoid underflows. + */ + if (num < 1) + { + /// stop here, we should have entries... + ke_stop(RUNTIME_CHECK_ACPI); + return ErrorOr{-1}; + } + + this->fEntries = num; + + kcout << "ACPI: Number of entries: " << number(this->fEntries) << endl; + kcout << "ACPI: Revision: " << number(xsdt->Revision) << endl; + kcout << "ACPI: Signature: " << xsdt->Signature << endl; + kcout << "ACPI: Address of XSDT: " << hex_number((UIntPtr)xsdt) << endl; + + const short cAcpiSignatureLength = 4; + + for (Size index = 0; index < this->fEntries; ++index) + { + SDT* sdt = reinterpret_cast(xsdt->AddressArr[index]); + + kcout << "ACPI: Checksum: " << number(sdt->Checksum) << endl; + kcout << "ACPI: Revision: " << number(sdt->Revision) << endl; + + for (short signature_index = 0; signature_index < cAcpiSignatureLength; ++signature_index) + { + if (sdt->Signature[signature_index] != signature[signature_index]) + break; + + if (signature_index == (cAcpiSignatureLength - 1)) + { + kcout << "ACPI: SDT Signature: " << sdt->Signature << endl; + kcout << "ACPI: SDT OEM ID: " << sdt->OemId << endl; + return ErrorOr(reinterpret_cast(xsdt->AddressArr[index])); + } + } + } + + return ErrorOr{-1}; + } + + /*** + @brief Checksum on SDT header. + @param checksum the header to checksum + @param len the length of it. + */ + bool ACPIFactoryInterface::Checksum(const Char* checksum, SSizeT len) + { + if (len == 0) + return 1; + + char chr = 0; + + for (int index = 0; index < len; ++index) + { + chr += checksum[index]; + } + + return chr == 0; + } +} // namespace Kernel diff --git a/dev/Kernel/src/Array.cc b/dev/Kernel/src/Array.cc new file mode 100644 index 00000000..2dc49e5a --- /dev/null +++ b/dev/Kernel/src/Array.cc @@ -0,0 +1,7 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include diff --git a/dev/Kernel/src/ArrayList.cc b/dev/Kernel/src/ArrayList.cc new file mode 100644 index 00000000..24e1375d --- /dev/null +++ b/dev/Kernel/src/ArrayList.cc @@ -0,0 +1,7 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include diff --git a/dev/Kernel/src/Atom.cc b/dev/Kernel/src/Atom.cc new file mode 100644 index 00000000..fa903985 --- /dev/null +++ b/dev/Kernel/src/Atom.cc @@ -0,0 +1,10 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include + +// @file Atom.cpp +// @brief Atomic primitives diff --git a/dev/Kernel/src/BitMapMgr.cc b/dev/Kernel/src/BitMapMgr.cc new file mode 100644 index 00000000..68e42e35 --- /dev/null +++ b/dev/Kernel/src/BitMapMgr.cc @@ -0,0 +1,185 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include + +#ifdef __ZKA_AMD64__ +#include +#elif defined(__ZKA_ARM64__) +#include +#endif + +#include +#include + +#define kBitMapMagic (0x10210U) + +#define kBitMapMagIdx (0U) +#define kBitMapSizeIdx (1U) +#define kBitMapUsedIdx (2U) + +namespace Kernel +{ + namespace HAL + { + namespace Detail + { + /// \brief Proxy Interface to allocate a bitmap. + class IBitMapAllocator final + { + public: + explicit IBitMapAllocator() = default; + ~IBitMapAllocator() = default; + + ZKA_COPY_DELETE(IBitMapAllocator); + + auto IsBitMap(VoidPtr page_ptr) -> Bool + { + if (!page_ptr) + return No; + + UIntPtr* ptr_bit_set = reinterpret_cast(page_ptr); + + if (!ptr_bit_set[kBitMapMagIdx] || + ptr_bit_set[kBitMapMagIdx] != kBitMapMagic) + return No; + + return Yes; + } + + auto FreeBitMap(VoidPtr page_ptr) -> Bool + { + if (this->IsBitMap(page_ptr) == No) + return No; + + UIntPtr* ptr_bit_set = reinterpret_cast(page_ptr); + + ptr_bit_set[kBitMapMagIdx] = kBitMapMagic; + ptr_bit_set[kBitMapUsedIdx] = No; + + this->GetBitMapStatus(ptr_bit_set); + + return Yes; + } + + UInt32 MakeMMFlags(Bool wr, Bool user) + { + UInt32 flags = kMMFlagsPresent; + + if (wr) + flags |= kMMFlagsWr; + + if (user) + flags |= kMMFlagsUser; + + return flags; + } + + /// @brief Iterate over availables pages for a free one. + /// @return The new address which was found. + auto FindBitMap(VoidPtr base_ptr, SizeT size, Bool wr, Bool user) -> VoidPtr + { + VoidPtr base = reinterpret_cast(((UIntPtr)base_ptr) + kPageSize); + + while (base && size) + { + UIntPtr* ptr_bit_set = reinterpret_cast(base); + + if (ptr_bit_set[kBitMapMagIdx] == kBitMapMagic && + ptr_bit_set[kBitMapSizeIdx] <= size) + { + if (ptr_bit_set[kBitMapUsedIdx] == No) + { + ptr_bit_set[kBitMapSizeIdx] = size; + ptr_bit_set[kBitMapUsedIdx] = Yes; + + this->GetBitMapStatus(ptr_bit_set); + + UInt32 flags = this->MakeMMFlags(wr, user); + mm_map_page(ptr_bit_set, flags); + + return (VoidPtr)ptr_bit_set; + } + } + else if (ptr_bit_set[kBitMapMagIdx] != kBitMapMagic) + { + UIntPtr* ptr_bit_set = reinterpret_cast(base_ptr); + + ptr_bit_set[kBitMapMagIdx] = kBitMapMagic; + ptr_bit_set[kBitMapSizeIdx] = size; + ptr_bit_set[kBitMapUsedIdx] = Yes; + + this->GetBitMapStatus(ptr_bit_set); + + UInt32 flags = this->MakeMMFlags(wr, user); + mm_map_page(ptr_bit_set, flags); + + return (VoidPtr)ptr_bit_set; + } + + base = reinterpret_cast(reinterpret_cast(base_ptr) + (ptr_bit_set[0] != kBitMapMagic ? size : ptr_bit_set[1])); + + if ((UIntPtr)base_ptr < (reinterpret_cast(base) + kHandoverHeader->f_BitMapSize)) + return nullptr; + } + + return nullptr; + } + + /// @brief Print Bitmap status + auto GetBitMapStatus(UIntPtr* ptr_bit_set) -> Void + { + if (!this->IsBitMap(ptr_bit_set)) + { + kcout << "Not a BitMap: " << hex_number((UIntPtr)ptr_bit_set) << endl; + return; + } + + kcout << "Magic Number: " << hex_number(ptr_bit_set[kBitMapMagIdx]) << endl; + kcout << "Is Allocated: " << (ptr_bit_set[kBitMapUsedIdx] ? "Yes" : "No") << endl; + kcout << "Size of BitMap (B): " << number(ptr_bit_set[kBitMapSizeIdx]) << endl; + kcout << "Size of BitMap (KIB): " << number(KIB(ptr_bit_set[kBitMapSizeIdx])) << endl; + kcout << "Size of BitMap (MIB): " << number(MIB(ptr_bit_set[kBitMapSizeIdx])) << endl; + kcout << "Size of BitMap (GIB): " << number(GIB(ptr_bit_set[kBitMapSizeIdx])) << endl; + kcout << "Size of BitMap (TIB): " << number(TIB(ptr_bit_set[kBitMapSizeIdx])) << endl; + kcout << "Address Of BitMap: " << hex_number((UIntPtr)ptr_bit_set) << endl; + } + }; + } // namespace Detail + + auto mm_is_bitmap(VoidPtr ptr) -> Bool + { + Detail::IBitMapAllocator traits; + return traits.IsBitMap(ptr); + } + + /// @brief Allocate a new page to be used by the OS. + /// @param wr read/write bit. + /// @param user user bit. + /// @return a new bitmap allocated pointer. + auto mm_alloc_bitmap(Boolean wr, Boolean user, SizeT size, Bool is_page) -> VoidPtr + { + VoidPtr ptr_new = nullptr; + Detail::IBitMapAllocator traits; + + ptr_new = traits.FindBitMap(kKernelBitMpStart, size, wr, user); + + return (UIntPtr*)ptr_new; + } + + /// @brief Free Bitmap, and mark it a absent in page terms. + auto mm_free_bitmap(VoidPtr page_ptr) -> Bool + { + if (!page_ptr) + return No; + + Detail::IBitMapAllocator traits; + Bool ret = traits.FreeBitMap(page_ptr); + + return ret; + } + } // namespace HAL +} // namespace Kernel diff --git a/dev/Kernel/src/CodeMgr.cc b/dev/Kernel/src/CodeMgr.cc new file mode 100644 index 00000000..4a3fdcf1 --- /dev/null +++ b/dev/Kernel/src/CodeMgr.cc @@ -0,0 +1,38 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include +#include + +namespace Kernel +{ + /// @brief Executes a new process from a function. Kernel code only. + /// @note This sets up a new stack, anything on the main function that calls the Kernel will not be accessible. + /// @param main the start of the process. + /// @return if the process was started or not. + ProcessID rtl_create_process(rtl_main_kind main, const Char* process_name) noexcept + { + if (*process_name == 0) + return kProcessInvalidID; + + UserProcess* process_hdr = new UserProcess(); + + process_hdr->Image.fCode = reinterpret_cast(main); + process_hdr->Kind = UserProcess::kExectuableKind; + process_hdr->StackSize = kib_cast(8); + + rt_set_memory(process_hdr->Name, 0, kProcessNameLen); + rt_copy_memory((VoidPtr)process_name, process_hdr->Name, rt_string_len(process_name)); + + ProcessID id = UserProcessScheduler::The().Spawn(process_hdr); + + if (id == kProcessInvalidID) + delete process_hdr; + + return id; + } +} // namespace Kernel diff --git a/dev/Kernel/src/Crc32.cc b/dev/Kernel/src/Crc32.cc new file mode 100644 index 00000000..6ac44b30 --- /dev/null +++ b/dev/Kernel/src/Crc32.cc @@ -0,0 +1,83 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include + +// @file CRC32.cpp +// @brief Check sequence implementation. + +namespace Kernel +{ + /// @brief The CRC32 seed table. + UInt32 kCrcTbl[kCrcCnt] = { + 0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L, 0xC79A971FL, + 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL, 0x8AD958CFL, 0x78B2DBCCL, + 0x6BE22838L, 0x9989AB3BL, 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, + 0x5E133C24L, 0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL, + 0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L, 0x9A879FA0L, + 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L, 0x5D1D08BFL, 0xAF768BBCL, + 0xBC267848L, 0x4E4DFB4BL, 0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, + 0x33ED7D2AL, 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L, + 0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L, 0x6DFE410EL, + 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL, 0x30E349B1L, 0xC288CAB2L, + 0xD1D83946L, 0x23B3BA45L, 0xF779DEAEL, 0x05125DADL, 0x1642AE59L, + 0xE4292D5AL, 0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL, + 0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L, 0x417B1DBCL, + 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L, 0x86E18AA3L, 0x748A09A0L, + 0x67DAFA54L, 0x95B17957L, 0xCBA24573L, 0x39C9C670L, 0x2A993584L, + 0xD8F2B687L, 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L, + 0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L, 0x96BF4DCCL, + 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L, 0xDBFC821CL, 0x2997011FL, + 0x3AC7F2EBL, 0xC8AC71E8L, 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, + 0x0F36E6F7L, 0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L, + 0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L, 0xEB1FCBADL, + 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L, 0x2C855CB2L, 0xDEEEDFB1L, + 0xCDBE2C45L, 0x3FD5AF46L, 0x7198540DL, 0x83F3D70EL, 0x90A324FAL, + 0x62C8A7F9L, 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L, + 0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L, 0x3CDB9BDDL, + 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L, 0x82F63B78L, 0x709DB87BL, + 0x63CD4B8FL, 0x91A6C88CL, 0x456CAC67L, 0xB7072F64L, 0xA457DC90L, + 0x563C5F93L, 0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L, + 0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL, 0x92A8FC17L, + 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L, 0x55326B08L, 0xA759E80BL, + 0xB4091BFFL, 0x466298FCL, 0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, + 0x0B21572CL, 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L, + 0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L, 0x65D122B9L, + 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL, 0x2892ED69L, 0xDAF96E6AL, + 0xC9A99D9EL, 0x3BC21E9DL, 0xEF087A76L, 0x1D63F975L, 0x0E330A81L, + 0xFC588982L, 0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL, + 0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L, 0x38CC2A06L, + 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L, 0xFF56BD19L, 0x0D3D3E1AL, + 0x1E6DCDEEL, 0xEC064EEDL, 0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, + 0xD0DDD530L, 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL, + 0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL, 0x8ECEE914L, + 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L, 0xD3D3E1ABL, 0x21B862A8L, + 0x32E8915CL, 0xC083125FL, 0x144976B4L, 0xE622F5B7L, 0xF5720643L, + 0x07198540L, 0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L, + 0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL, 0xE330A81AL, + 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL, 0x24AA3F05L, 0xD6C1BC06L, + 0xC5914FF2L, 0x37FACCF1L, 0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, + 0x7AB90321L, 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL, + 0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L, 0x34F4F86AL, + 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL, 0x79B737BAL, 0x8BDCB4B9L, + 0x988C474DL, 0x6AE7C44EL, 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, + 0xAD7D5351L}; + + /// @brief Calculate CRC32 of p + /// @param p the data to compute. + /// @param len the length of the data. + /// @return the CRC32. + UInt ke_calculate_crc32(const Char* p, UInt len) noexcept + { + UInt crc = 0xffffffff; + + while (len-- != 0) + crc = kCrcTbl[((UInt8)crc ^ *(p++))] ^ (crc >> 8); + + // return (~crc); also works, does the same thing. + return (crc ^ 0xffffffff); + } +} // namespace Kernel diff --git a/dev/Kernel/src/CxxAbi-AMD64.cc b/dev/Kernel/src/CxxAbi-AMD64.cc new file mode 100644 index 00000000..3f862b23 --- /dev/null +++ b/dev/Kernel/src/CxxAbi-AMD64.cc @@ -0,0 +1,90 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#ifdef __ZKA_AMD64__ + +#include +#include +#include + +atexit_func_entry_t __atexit_funcs[kAtExitMacDestructors]; + +uarch_t __atexit_func_count; + +/// @brief dynamic shared object Handle. +Kernel::UIntPtr __dso_handle; + +EXTERN_C Kernel::Void __cxa_pure_virtual(void* self) +{ + kcout << "object: " << Kernel::number(reinterpret_cast(self)); + kcout << ", has unimplemented virtual functions.\r"; +} + +EXTERN_C void ___chkstk_ms(void) +{ +} + +EXTERN_C int atexit(void (*f)(void*), void* arg, void* dso) +{ + if (__atexit_func_count >= kAtExitMacDestructors) + return 1; + + __atexit_funcs[__atexit_func_count].destructor_func = f; + __atexit_funcs[__atexit_func_count].obj_ptr = arg; + __atexit_funcs[__atexit_func_count].dso_handle = dso; + + __atexit_func_count++; + + return 0; +} + +EXTERN_C void __cxa_finalize(void* f) +{ + uarch_t i = __atexit_func_count; + if (!f) + { + while (i--) + { + if (__atexit_funcs[i].destructor_func) + { + (*__atexit_funcs[i].destructor_func)(__atexit_funcs[i].obj_ptr); + }; + } + + return; + } + + while (i--) + { + if (__atexit_funcs[i].destructor_func) + { + (*__atexit_funcs[i].destructor_func)(__atexit_funcs[i].obj_ptr); + __atexit_funcs[i].destructor_func = 0; + }; + } +} + +namespace cxxabiv1 +{ + EXTERN_C int __cxa_guard_acquire(__guard* g) + { + (void)g; + return 0; + } + + EXTERN_C int __cxa_guard_release(__guard* g) + { + *(char*)g = 1; + return 0; + } + + EXTERN_C void __cxa_guard_abort(__guard* g) + { + (void)g; + } +} // namespace cxxabiv1 + +#endif // ifdef __ZKA_AMD64__ diff --git a/dev/Kernel/src/CxxAbi-ARM64.cc b/dev/Kernel/src/CxxAbi-ARM64.cc new file mode 100644 index 00000000..59731dc6 --- /dev/null +++ b/dev/Kernel/src/CxxAbi-ARM64.cc @@ -0,0 +1,107 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#ifdef __ZKA_ARM64__ + +#include +#include +#include + +atexit_func_entry_t __atexit_funcs[kAtExitMacDestructors]; + +uarch_t __atexit_func_count; + +/// @brief dynamic shared object Handle. +Kernel::UIntPtr __dso_handle; + +EXTERN_C void __chkstk(void) +{ +} + +EXTERN_C int atexit(void (*f)(void*), void* arg, void* dso) +{ + if (__atexit_func_count >= kAtExitMacDestructors) + return 1; + + __atexit_funcs[__atexit_func_count].destructor_func = f; + __atexit_funcs[__atexit_func_count].obj_ptr = arg; + __atexit_funcs[__atexit_func_count].dso_handle = dso; + + __atexit_func_count++; + + return 0; +} + +EXTERN_C void __cxa_finalize(void* f) +{ + uarch_t i = __atexit_func_count; + if (!f) + { + while (i--) + { + if (__atexit_funcs[i].destructor_func) + { + (*__atexit_funcs[i].destructor_func)(__atexit_funcs[i].obj_ptr); + }; + } + + return; + } + + while (i--) + { + if (__atexit_funcs[i].destructor_func) + { + (*__atexit_funcs[i].destructor_func)(__atexit_funcs[i].obj_ptr); + __atexit_funcs[i].destructor_func = 0; + }; + } +} + +namespace cxxabiv1 +{ + EXTERN_C int __cxa_guard_acquire(__guard* g) + { + (void)g; + return 0; + } + + EXTERN_C int __cxa_guard_release(__guard* g) + { + *(char*)g = 1; + return 0; + } + + EXTERN_C void __cxa_guard_abort(__guard* g) + { + (void)g; + } +} // namespace cxxabiv1 + +EXTERN_C Kernel::Void _purecall(void* self) +{ + kcout << "object: " << Kernel::number(reinterpret_cast(self)); + kcout << ", has unimplemented virtual functions.\r"; +} + +EXTERN_C Kernel::Void _Init_thread_footer(Kernel::Int* thread_obj) +{ + ZKA_UNUSED(thread_obj); +} + +EXTERN_C Kernel::Void _Init_thread_epoch(Kernel::Void) +{ + ZKA_UNUSED(0); +} + +EXTERN_C Kernel::Void _Init_thread_header(Kernel::Int* thread_obj) +{ + ZKA_UNUSED(0); +} + +EXTERN_C Kernel::Int _tls_index = 0UL; + +#endif // ifdef __ZKA_ARM64__ diff --git a/dev/Kernel/src/Defines.cc b/dev/Kernel/src/Defines.cc new file mode 100644 index 00000000..a5a24f0e --- /dev/null +++ b/dev/Kernel/src/Defines.cc @@ -0,0 +1,7 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include diff --git a/dev/Kernel/src/DeviceMgr.cc b/dev/Kernel/src/DeviceMgr.cc new file mode 100644 index 00000000..192a491f --- /dev/null +++ b/dev/Kernel/src/DeviceMgr.cc @@ -0,0 +1,7 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include diff --git a/dev/Kernel/src/DriveMgr.cc b/dev/Kernel/src/DriveMgr.cc new file mode 100644 index 00000000..1b601ff4 --- /dev/null +++ b/dev/Kernel/src/DriveMgr.cc @@ -0,0 +1,221 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include +#include +#include +#include +#include +#include + +/***********************************************************************************/ +/// @file DriveMgr.cc +/// @brief Drive Manager of minoskrnl. +/***********************************************************************************/ + +namespace Kernel +{ + STATIC UInt16 kATAIO = 0U; + STATIC UInt8 kATAMaster = 0U; + + /// @brief reads from an ATA drive. + /// @param pckt Packet structure (fPacketContent must be non null) + /// @return + Void io_drv_input(DriveTrait::DrivePacket* pckt) + { + if (!pckt) + { + return; + } + +#ifdef __AHCI__ + drv_std_read(pckt->fPacketLba, (Char*)pckt->fPacketContent, kAHCISectorSize, pckt->fPacketSize); +#elif defined(__ATA_PIO__) || defined(__ATA_DMA__) + drv_std_read(pckt->fPacketLba, kATAIO, kATAMaster, (Char*)pckt->fPacketContent, kATASectorSize, pckt->fPacketSize); +#endif + } + + /// @brief Writes to an ATA drive. + /// @param pckt the packet to write. + /// @return + Void io_drv_output(DriveTrait::DrivePacket* pckt) + { + if (!pckt) + { + return; + } + +#ifdef __AHCI__ + drv_std_write(pckt->fPacketLba, (Char*)pckt->fPacketContent, kAHCISectorSize, pckt->fPacketSize); +#elif defined(__ATA_PIO__) || defined(__ATA_DMA__) + drv_std_write(pckt->fPacketLba, kATAIO, kATAMaster, (Char*)pckt->fPacketContent, kATASectorSize, pckt->fPacketSize); +#endif + } + + /// @brief Executes a disk check on the ATA drive. + /// @param pckt the packet to read. + /// @return + Void io_drv_init(DriveTrait::DrivePacket* pckt) + { + if (!pckt) + { + return; + } + + kATAMaster = 0; + kATAIO = 0; + +#if defined(__ATA_PIO__) || defined(__ATA_DMA__) + kATAMaster = true; + kATAIO = ATA_PRIMARY_IO; + + if (drv_std_init(kATAIO, kATAMaster, kATAIO, kATAMaster)) + { + pckt->fPacketGood = YES; + return; + } + + kATAMaster = false; + kATAIO = ATA_SECONDARY_IO; + + if (!drv_std_init(kATAIO, kATAMaster, kATAIO, kATAMaster)) + { + return; + } + + pckt->fPacketGood = YES; +#elif defined(__AHCI__) + UInt16 pi = 0; + + if (!drv_std_init(pi)) + { + return; + } +#endif // if defined(__ATA_PIO__) || defined (__ATA_DMA__) + } + +/// @brief Gets the drive kind (ATA, SCSI, AHCI...) +/// @param no arguments. +/// @return no arguments. +#ifdef __ATA_PIO__ + const Char* io_drv_kind(Void) + { + return "ATA-PIO"; + } +#endif +#ifdef __ATA_DMA__ + const Char* io_drv_kind(Void) + { + return "ATA-DMA"; + } +#endif +#ifdef __AHCI__ + const Char* io_drv_kind(Void) + { + return "AHCI"; + } +#endif +#ifdef __ZKA_MINIMAL_OS__ + const Char* io_drv_kind(Void) + { + return "Not Loaded"; + } +#endif + + /// @brief Unimplemented drive function. + /// @param pckt the packet to read. + /// @return + Void io_drv_unimplemented(DriveTrait::DrivePacket* pckt) + { + ZKA_UNUSED(pckt); + } + + /// @brief Makes a new drive. + /// @return the new blank drive. + DriveTrait io_construct_blank_drive() noexcept + { + DriveTrait trait; + + rt_copy_memory((VoidPtr) "/Disks/NUL:", trait.fName, rt_string_len("/Disks/NUL:")); + trait.fKind = kInvalidDisc; + + trait.fInput = io_drv_unimplemented; + trait.fOutput = io_drv_unimplemented; + trait.fVerify = io_drv_unimplemented; + trait.fInit = io_drv_unimplemented; + trait.fDriveKind = io_drv_kind; + + kcout << "Construct: " << trait.fName << "\r"; + + return trait; + } + + namespace Detail + { + Void ioi_detect_drive(DriveTrait* trait) + { + static EPM_BOOT_BLOCK block_struct; + + trait->fPacket.fPacketLba = kEPMBootBlockLba; + trait->fPacket.fPacketSize = sizeof(EPM_BOOT_BLOCK); + trait->fPacket.fPacketContent = &block_struct; + + rt_copy_memory((VoidPtr) "fs/detect-packet", trait->fPacket.fPacketMime, + rt_string_len("fs/detect-packet")); + + trait->fInit(&trait->fPacket); + + trait->fInput(&trait->fPacket); + + if (rt_string_cmp(((BOOT_BLOCK_STRUCT*)trait->fPacket.fPacketContent)->Magic, kEPMMagic, kEPMMagicLength) == 0) + { + trait->fPacket.fPacketReadOnly = NO; + trait->fKind = kMassStorageDisc | kEPMDrive; + + kcout << "Formatted Disc is EPM (and Mass Storage too.)\r"; + } + else + { + trait->fPacket.fPacketReadOnly = YES; + trait->fKind = kMassStorageDisc | kUnformattedDrive | kReadOnlyDrive; + + kcout << "Scheme Found: " << block_struct.Name << endl; + + if (block_struct.Name[0] == 0) + kcout << "Disc partition is unknown (Was set to Read Only.)\r"; + } + + rt_copy_memory((VoidPtr) "*/*", trait->fPacket.fPacketMime, + rt_string_len("*/*")); + + trait->fPacket.fPacketLba = 0; + trait->fPacket.fPacketSize = 0UL; + trait->fPacket.fPacketContent = nullptr; + } + } // namespace Detail + + /// @brief Fetches the main drive. + /// @return the new drive. (returns kEPMDrive if EPM formatted) + DriveTrait io_construct_main_drive() noexcept + { + DriveTrait trait{}; + + rt_copy_memory((VoidPtr) "/Disks/OS:", trait.fName, rt_string_len("/Disks/OS:")); + + trait.fVerify = io_drv_unimplemented; + trait.fOutput = io_drv_output; + trait.fInput = io_drv_input; + trait.fInit = io_drv_init; + trait.fDriveKind = io_drv_kind; + + kcout << "Detecting partition scheme of: " << trait.fName << ".\r"; + + Detail::ioi_detect_drive(&trait); + + return trait; + } +} // namespace Kernel diff --git a/dev/Kernel/src/ErrorOr.cc b/dev/Kernel/src/ErrorOr.cc new file mode 100644 index 00000000..e1bb055a --- /dev/null +++ b/dev/Kernel/src/ErrorOr.cc @@ -0,0 +1,12 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include + +/***********************************************************************************/ +/// @file ErrorOr.cc /// +/// @brief ErrorOr container class. /// +/***********************************************************************************/ diff --git a/dev/Kernel/src/FS/HPFS.cc b/dev/Kernel/src/FS/HPFS.cc new file mode 100644 index 00000000..01bbb859 --- /dev/null +++ b/dev/Kernel/src/FS/HPFS.cc @@ -0,0 +1,22 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#ifdef __FSKIT_INCLUDES_HPFS__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif // ifdef __FSKIT_INCLUDES_HPFS__ diff --git a/dev/Kernel/src/FS/NeFS.cc b/dev/Kernel/src/FS/NeFS.cc new file mode 100644 index 00000000..4cf0a838 --- /dev/null +++ b/dev/Kernel/src/FS/NeFS.cc @@ -0,0 +1,1054 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#ifdef __FSKIT_INCLUDES_NEFS__ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace Kernel; + +#ifdef __ZKA_NO_BUILTIN__ +/***********************************************************************************/ +/** + Define those external symbols, to make the editor shutup +*/ +/***********************************************************************************/ + +/***********************************************************************************/ +/// @brief get sector count. +/***********************************************************************************/ +Kernel::SizeT drv_get_sector_count(); + +/***********************************************************************************/ +/// @brief get device size. +/***********************************************************************************/ +Kernel::SizeT drv_get_size(); + +#endif + +///! BUGS: 0 + +/***********************************************************************************/ +/// This file implements the New File System. +/// New File System implements a B-Tree based algortihm. +/// / +/// /Path1/ /ath2/ +/// /readme.rtf /ListContents.pef /readme.lnk <-- symlink. +/// /Path1/readme.rtf +/***********************************************************************************/ + +STATIC MountpointInterface kDiskMountpoint; + +/***********************************************************************************/ +/// @brief Creates a new fork inside the New filesystem partition. +/// @param catalog it's catalog +/// @param the_fork the fork itself. +/// @return the fork +/***********************************************************************************/ +_Output NFS_FORK_STRUCT* NeFileSystemParser::CreateFork(_Input NFS_CATALOG_STRUCT* catalog, + _Input NFS_FORK_STRUCT& the_fork) +{ + if (catalog && the_fork.ForkName[0] != 0 && + the_fork.DataSize <= kNeFSForkDataSz) + { + Lba lba = (the_fork.Kind == kNeFSDataForkKind) ? catalog->DataFork + : catalog->ResourceFork; + + kcout << "Fork LBA: " << hex_number(lba) << endl; + + if (lba <= kNeFSCatalogStartAddress) + return nullptr; + + auto drv = kDiskMountpoint.A(); + + /// special treatment. + rt_copy_memory((VoidPtr) "fs/nefs-packet", drv.fPacket.fPacketMime, + rt_string_len("fs/nefs-packet")); + + NFS_FORK_STRUCT curFork{0}; + NFS_FORK_STRUCT prevFork{0}; + Lba lbaOfPreviousFork = lba; + + /// do not check for anything. Loop until we get what we want, that is a free fork zone. + while (true) + { + if (lba <= kNeFSCatalogStartAddress) + break; + + drv.fPacket.fPacketLba = lba; + drv.fPacket.fPacketSize = sizeof(NFS_FORK_STRUCT); + drv.fPacket.fPacketContent = &curFork; + + drv.fInput(&drv.fPacket); + + if (curFork.NextSibling > kBadAddress) + { + kcout << "Bad fork: " << hex_number(curFork.NextSibling) << endl; + break; + } + + kcout << "Next fork: " << hex_number(curFork.NextSibling) << endl; + + if (curFork.Flags & kNeFSFlagCreated) + { + kcout << "Fork already exists.\r"; + + /// sanity check. + if (StringBuilder::Equals(curFork.ForkName, the_fork.ForkName) && + StringBuilder::Equals(curFork.CatalogName, catalog->Name)) + return nullptr; + + kcout << "Next fork: " << hex_number(curFork.NextSibling) << endl; + + lbaOfPreviousFork = lba; + lba = curFork.NextSibling; + + prevFork = curFork; + } + else + { + /// This is a check that we have, in order to link the previous fork + /// entry. + if (lba >= kNeFSCatalogStartAddress) + { + drv.fPacket.fPacketLba = lbaOfPreviousFork; + drv.fPacket.fPacketSize = sizeof(NFS_FORK_STRUCT); + drv.fPacket.fPacketContent = &prevFork; + + prevFork.NextSibling = lba; + + /// write to disk. + drv.fOutput(&drv.fPacket); + } + + break; + } + } + + the_fork.Flags |= kNeFSFlagCreated; + the_fork.DataOffset = lba - sizeof(NFS_FORK_STRUCT); + the_fork.PreviousSibling = lbaOfPreviousFork; + the_fork.NextSibling = the_fork.DataOffset - the_fork.DataSize - sizeof(NFS_FORK_STRUCT); + + drv.fPacket.fPacketLba = lba; + drv.fPacket.fPacketSize = sizeof(NFS_FORK_STRUCT); + drv.fPacket.fPacketContent = &the_fork; + + drv.fOutput(&drv.fPacket); + + /// log what we have now. + kcout << "Wrote fork data at: " << hex_number(the_fork.DataOffset) + << endl; + + kcout << "Wrote fork at: " << hex_number(lba) << endl; + + return &the_fork; + } + + return nullptr; +} + +/***********************************************************************************/ +/// @brief Find fork inside New filesystem. +/// @param catalog the catalog. +/// @param name the fork name. +/// @return the fork. +/***********************************************************************************/ +_Output NFS_FORK_STRUCT* NeFileSystemParser::FindFork(_Input NFS_CATALOG_STRUCT* catalog, + _Input const Char* name, + Boolean isDataFork) +{ + auto drv = kDiskMountpoint.A(); + NFS_FORK_STRUCT* the_fork = nullptr; + + Lba lba = isDataFork ? catalog->DataFork : catalog->ResourceFork; + + while (lba != 0) + { + drv.fPacket.fPacketLba = lba; + drv.fPacket.fPacketSize = sizeof(NFS_FORK_STRUCT); + drv.fPacket.fPacketContent = (VoidPtr)the_fork; + + rt_copy_memory((VoidPtr) "fs/nefs-packet", drv.fPacket.fPacketMime, 16); + + if (auto res = + fs_newfs_read(&kDiskMountpoint, drv, this->mDriveIndex); + res) + { + switch (res) + { + case 1: + err_local_get() = kErrorDiskReadOnly; + break; + case 2: + err_local_get() = kErrorDiskIsFull; + break; + err_local_get() = kErrorNoSuchDisk; + break; + + default: + break; + } + return nullptr; + } + + if (StringBuilder::Equals(the_fork->ForkName, name)) + { + break; + } + + lba = the_fork->NextSibling; + } + + return the_fork; +} + +/***********************************************************************************/ +/// @brief Simpler factory to create a catalog (assumes you want to create a +/// file.) +/// @param name +/// @return catalog pointer. +/***********************************************************************************/ +_Output NFS_CATALOG_STRUCT* NeFileSystemParser::CreateCatalog(_Input const Char* name) +{ + return this->CreateCatalog(name, 0, kNeFSCatalogKindFile); +} + +/***********************************************************************************/ +/// @brief Creates a new catalog into the disk. +/// @param name the catalog name. +/// @param flags the flags of the catalog. +/// @param kind the catalog kind. +/// @return catalog pointer. +/***********************************************************************************/ +_Output NFS_CATALOG_STRUCT* NeFileSystemParser::CreateCatalog(_Input const Char* name, + _Input const Int32& flags, + _Input const Int32& kind) +{ + kcout << "CreateCatalog(...)\r"; + + Lba out_lba = 0UL; + + kcout << "Checking for path separator...\r"; + + /// a directory should have a slash in the end. + if (kind == kNeFSCatalogKindDir && + name[rt_string_len(name) - 1] != NeFileSystemHelper::Separator()) + return nullptr; + + /// a file shouldn't have a slash in the end. + if (kind != kNeFSCatalogKindDir && + name[rt_string_len(name) - 1] == NeFileSystemHelper::Separator()) + return nullptr; + + NFS_CATALOG_STRUCT* catalog_copy = this->FindCatalog(name, out_lba); + + if (catalog_copy) + { + kcout << "Catalog already exists: " << name << ".\r"; + err_local_get() = kErrorFileExists; + + return catalog_copy; + } + + Char parentName[kNeFSNodeNameLen] = {0}; + + for (SizeT indexName = 0UL; indexName < rt_string_len(name); ++indexName) + { + parentName[indexName] = name[indexName]; + } + + if (*parentName == 0) + { + kcout << "Parent name is NUL.\r"; + err_local_get() = kErrorFileNotFound; + return nullptr; + } + + /// Locate parent catalog, to then allocate right after it. + + for (SizeT indexFill = 0; indexFill < rt_string_len(name); ++indexFill) + { + parentName[indexFill] = name[indexFill]; + } + + SizeT indexReverseCopy = rt_string_len(parentName); + + // zero character it. + parentName[--indexReverseCopy] = 0; + + // mandatory / character, zero it. + parentName[--indexReverseCopy] = 0; + + while (parentName[indexReverseCopy] != NeFileSystemHelper::Separator()) + { + parentName[indexReverseCopy] = 0; + --indexReverseCopy; + } + + NFS_CATALOG_STRUCT* catalog = this->FindCatalog(parentName, out_lba); + + auto drive = kDiskMountpoint.A(); + + if (catalog && catalog->Kind == kNeFSCatalogKindFile) + { + kcout << "Parent name is file.\r"; + delete catalog; + return nullptr; + } + else if (!catalog) + { + Char sectorBufPartBlock[kNeFSSectorSz] = {0}; + + drive.fPacket.fPacketContent = sectorBufPartBlock; + drive.fPacket.fPacketSize = kNeFSSectorSz; + drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress; + + drive.fInput(&drive.fPacket); + + constexpr auto cNeFSCatalogPadding = 4; + + NFS_ROOT_PARTITION_BLOCK* part_block = (NFS_ROOT_PARTITION_BLOCK*)sectorBufPartBlock; + out_lba = part_block->StartCatalog; + } + + constexpr SizeT kDefaultForkSize = kNeFSForkSize; + + NFS_CATALOG_STRUCT* child_catalog = new NFS_CATALOG_STRUCT(); + + Int32 flagsList = flags; + + child_catalog->ResourceForkSize = kDefaultForkSize; + child_catalog->DataForkSize = kDefaultForkSize; + + child_catalog->NextSibling = out_lba; + child_catalog->PrevSibling = out_lba; + child_catalog->Kind = kind; + child_catalog->Flags = kNeFSFlagCreated | flagsList; + + rt_copy_memory((VoidPtr)name, (VoidPtr)child_catalog->Name, + rt_string_len(name)); + + NFS_CATALOG_STRUCT temporary_catalog; + + Lba start_free = out_lba; + + rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, + rt_string_len("fs/nefs-packet")); + + drive.fPacket.fPacketContent = &temporary_catalog; + drive.fPacket.fPacketSize = kNeFSSectorSz; + drive.fPacket.fPacketLba = start_free; + + drive.fInput(&drive.fPacket); + + NFS_CATALOG_STRUCT* next_sibling = reinterpret_cast(&temporary_catalog); + + start_free = next_sibling->NextSibling; + + child_catalog->PrevSibling = out_lba; + + drive.fPacket.fPacketLba = start_free; + drive.fInput(&drive.fPacket); + + while (drive.fPacket.fPacketGood) + { + next_sibling = reinterpret_cast(&temporary_catalog); + + if (start_free <= kNeFSRootCatalogStartAddress) + { + delete child_catalog; + delete catalog; + + return nullptr; + } + + // ========================== // + // Allocate catalog now... + // ========================== // + if ((next_sibling->Flags & kNeFSFlagCreated) == 0) + { + Char sectorBufPartBlock[kNeFSSectorSz] = {0}; + + drive.fPacket.fPacketContent = sectorBufPartBlock; + drive.fPacket.fPacketSize = kNeFSSectorSz; + drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress; + + drive.fInput(&drive.fPacket); + + constexpr auto cNeFSCatalogPadding = 4; + + NFS_ROOT_PARTITION_BLOCK* part_block = (NFS_ROOT_PARTITION_BLOCK*)sectorBufPartBlock; + + if (part_block->FreeCatalog < 1) + { + delete child_catalog; + return nullptr; + } + + child_catalog->DataFork = part_block->DiskSize - start_free; + child_catalog->ResourceFork = child_catalog->DataFork; + + // Write the new catalog next sibling, if we don't know this parent. // + // This is necessary, so that we don't have to get another lba to allocate. // + if (!StringBuilder::Equals(parentName, next_sibling->Name)) + { + child_catalog->NextSibling = + start_free + (sizeof(NFS_CATALOG_STRUCT) * cNeFSCatalogPadding); + } + + drive.fPacket.fPacketContent = child_catalog; + drive.fPacket.fPacketSize = sizeof(NFS_CATALOG_STRUCT); + drive.fPacket.fPacketLba = start_free; + + drive.fOutput(&drive.fPacket); + + // Get NeFS partition's block. + + drive.fPacket.fPacketContent = sectorBufPartBlock; + drive.fPacket.fPacketSize = kNeFSSectorSz; + drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress; + + drive.fInput(&drive.fPacket); + + part_block->FreeSectors -= 1; + part_block->CatalogCount += 1; + part_block->FreeCatalog -= 1; + + drive.fOutput(&drive.fPacket); + + kcout << "Create new catalog, status: " + << hex_number(child_catalog->Flags) << endl; + kcout << "Create new catalog, name: " << child_catalog->Name + << endl; + + delete catalog; + return child_catalog; + } + else if ((next_sibling->Flags & kNeFSFlagCreated) && + StringBuilder::Equals(next_sibling->Name, name)) + { + return next_sibling; + } + + constexpr auto cNeFSCatalogPadding = 4; + + //// @note that's how we find the next catalog in the partition block. + start_free = start_free + (sizeof(NFS_CATALOG_STRUCT) * cNeFSCatalogPadding); + + drive.fPacket.fPacketContent = &temporary_catalog; + drive.fPacket.fPacketSize = kNeFSSectorSz; + drive.fPacket.fPacketLba = start_free; + + drive.fInput(&drive.fPacket); + } + + delete catalog; + return nullptr; +} + +/// @brief Make a EPM+NeFS drive out of the disk. +/// @param drive The drive to write on. +/// @return If it was sucessful, see err_local_get(). +bool NeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input const Lba endLba, _Input const Int32 flags, const Char* part_name) +{ + if (*part_name == 0 || + endLba == 0) + return false; + + // verify disk. + drive->fVerify(&drive->fPacket); + + rt_copy_memory((VoidPtr) "fs/nefs-packet", drive->fPacket.fPacketMime, + rt_string_len("fs/nefs-packet")); + + // if disk isn't good, then error out. + if (false == drive->fPacket.fPacketGood) + { + err_local_get() = kErrorDiskIsCorrupted; + return false; + } + + Char fs_buf[kNeFSSectorSz] = {0}; + + Lba start = kNeFSRootCatalogStartAddress; + + drive->fPacket.fPacketContent = fs_buf; + drive->fPacket.fPacketSize = kNeFSSectorSz; + drive->fPacket.fPacketLba = start; + + drive->fInput(&drive->fPacket); + + if (flags & kNeFSPartitionTypeBoot) + { + // make it bootable when needed. + Char bufEpmHdr[kNeFSSectorSz] = {0}; + + BOOT_BLOCK_STRUCT* epm_boot = (BOOT_BLOCK_STRUCT*)bufEpmHdr; + + // Write a new EPM entry. + + constexpr auto kFsName = "NeFS"; + constexpr auto kBlockName = "ZKA:"; + + rt_copy_memory(reinterpret_cast(const_cast(kFsName)), epm_boot->Fs, rt_string_len(kFsName)); + + epm_boot->FsVersion = kNeFSVersionInteger; + epm_boot->LbaStart = start; + epm_boot->SectorSz = kNeFSSectorSz; + + rt_copy_memory(reinterpret_cast(const_cast(kBlockName)), epm_boot->Name, rt_string_len(kBlockName)); + rt_copy_memory(reinterpret_cast(const_cast(kEPMMagic)), epm_boot->Magic, rt_string_len(kEPMMagic)); + + Lba outEpmLba = kEPMBootBlockLba; + + Char buf[kNeFSSectorSz]; + + Lba prevStart = 0; + SizeT cnt = 0; + + while (drive->fPacket.fPacketGood) + { + drive->fPacket.fPacketContent = buf; + drive->fPacket.fPacketSize = kNeFSSectorSz; + drive->fPacket.fPacketLba = outEpmLba; + + drive->fInput(&drive->fPacket); + + if (buf[0] == 0) + { + epm_boot->LbaStart = prevStart; + + if (epm_boot->LbaStart) + epm_boot->LbaStart = outEpmLba; + + epm_boot->LbaEnd = endLba; + epm_boot->NumBlocks = cnt; + + drive->fPacket.fPacketContent = bufEpmHdr; + drive->fPacket.fPacketSize = kNeFSSectorSz; + drive->fPacket.fPacketLba = outEpmLba; + + drive->fOutput(&drive->fPacket); + + break; + } + else + { + prevStart = ((BOOT_BLOCK_STRUCT*)buf)->LbaStart + ((BOOT_BLOCK_STRUCT*)buf)->LbaEnd; + } + + outEpmLba += sizeof(BOOT_BLOCK_STRUCT); + ++cnt; + } + } + + // disk isnt faulty and data has been fetched. + while (drive->fPacket.fPacketGood) + { + NFS_ROOT_PARTITION_BLOCK* part_block = (NFS_ROOT_PARTITION_BLOCK*)fs_buf; + + // check for an empty partition here. + if (part_block->PartitionName[0] == 0 && + rt_string_cmp(part_block->Ident, kNeFSIdent, kNeFSIdentLen)) + { + // partition is free and valid. + + part_block->Version = kNeFSVersionInteger; + + const auto cUntitledHD = part_name; + + rt_copy_memory((VoidPtr)kNeFSIdent, (VoidPtr)part_block->Ident, + kNeFSIdentLen); + + rt_copy_memory((VoidPtr)cUntitledHD, (VoidPtr)part_block->PartitionName, + rt_string_len(cUntitledHD)); + + SizeT catalogCount = 0UL; + + SizeT sectorCount = drv_get_sector_count(); + SizeT diskSize = drv_get_size(); + + part_block->Kind = kNeFSPartitionTypeStandard; + part_block->StartCatalog = kNeFSCatalogStartAddress; + part_block->Flags = kNeFSPartitionTypeStandard; + part_block->CatalogCount = sectorCount / sizeof(NFS_CATALOG_STRUCT); + part_block->SectorCount = sectorCount; + part_block->DiskSize = diskSize; + part_block->FreeCatalog = sectorCount / sizeof(NFS_CATALOG_STRUCT); + + drive->fPacket.fPacketContent = fs_buf; + drive->fPacket.fPacketSize = kNeFSSectorSz; + drive->fPacket.fPacketLba = kNeFSRootCatalogStartAddress; + + drive->fOutput(&drive->fPacket); + + kcout << "drive kind: " << drive->fDriveKind() << endl; + + kcout << "partition name: " << part_block->PartitionName << endl; + kcout << "start: " << hex_number(part_block->StartCatalog) << endl; + kcout << "number of catalogs: " << hex_number(part_block->CatalogCount) << endl; + kcout << "free catalog: " << hex_number(part_block->FreeCatalog) << endl; + kcout << "free sectors: " << hex_number(part_block->FreeSectors) << endl; + kcout << "sector size: " << hex_number(part_block->SectorSize) << endl; + + // write the root catalog. + this->CreateCatalog(kNeFSRoot, 0, kNeFSCatalogKindDir); + + return true; + } + + kcout << "partition block already exists.\r"; + + start += part_block->DiskSize; + + drive->fPacket.fPacketContent = fs_buf; + drive->fPacket.fPacketSize = kNeFSSectorSz; + drive->fPacket.fPacketLba = start; + + drive->fInput(&drive->fPacket); + } + + return false; +} + +/// @brief Writes the data fork into a specific catalog. +/// @param catalog the catalog itself +/// @param data the data. +/// @return if the catalog w rote the contents successfully. +bool NeFileSystemParser::WriteCatalog(_Input _Output NFS_CATALOG_STRUCT* catalog, Bool is_rsrc_fork, _Input VoidPtr data, _Input SizeT size_of_data, _Input const Char* forkName) +{ + if (size_of_data > kNeFSForkDataSz || + size_of_data == 0) + return No; + + auto buf = new UInt8[kNeFSForkDataSz]; + rt_set_memory(buf, 0, kNeFSForkDataSz); + + rt_copy_memory(data, buf, size_of_data); + + auto drive = kDiskMountpoint.A(); + + rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, + rt_string_len("fs/nefs-packet")); + + auto startFork = (!is_rsrc_fork) ? catalog->DataFork + : catalog->ResourceFork; + + NFS_FORK_STRUCT* fork_data_input = new NFS_FORK_STRUCT(); + NFS_FORK_STRUCT prevFork{}; + + // sanity check of the fork position as the condition to run the loop. + while (startFork >= kNeFSCatalogStartAddress) + { + drive.fPacket.fPacketContent = fork_data_input; + drive.fPacket.fPacketSize = sizeof(NFS_FORK_STRUCT); + drive.fPacket.fPacketLba = startFork; + + drive.fInput(&drive.fPacket); + + // check the fork, if it's position is valid. + if (fork_data_input->DataOffset <= kNeFSCatalogStartAddress) + { + err_local_get() = kErrorDiskIsCorrupted; + + kcout << "Invalid fork offset.\r"; + + return false; + } + + if (fork_data_input->Flags != kNeFSFlagUnallocated && + fork_data_input->Flags != kNeFSFlagDeleted && + StringBuilder::Equals(fork_data_input->ForkName, forkName) && + StringBuilder::Equals(fork_data_input->CatalogName, catalog->Name) && + fork_data_input->DataSize == size_of_data) + { + // ===================================================== // + // Store the blob now. + // ===================================================== // + + fork_data_input->Flags |= kNeFSFlagCreated; + + drive.fPacket.fPacketContent = buf; + drive.fPacket.fPacketSize = kNeFSForkDataSz; + drive.fPacket.fPacketLba = fork_data_input->DataOffset; + + kcout << "data offset: " << hex_number(fork_data_input->DataOffset) << endl; + + drive.fOutput(&drive.fPacket); + + drive.fPacket.fPacketContent = fork_data_input; + drive.fPacket.fPacketSize = sizeof(NFS_FORK_STRUCT); + drive.fPacket.fPacketLba = startFork - sizeof(NFS_FORK_STRUCT); + + drive.fOutput(&drive.fPacket); + + kcout << "wrote fork at offset: " << hex_number(fork_data_input->DataOffset) << endl; + kcout << "wrote fork at offset: " << hex_number(startFork - sizeof(NFS_FORK_STRUCT)) << endl; + + delete catalog; + + return true; + } + + // stumble upon a fork, store it. + + prevFork = *fork_data_input; + + startFork = fork_data_input->NextSibling; + } + + return false; +} + +/// @brief +/// @param catalog_name the catalog name. +/// @return the newly found catalog. +_Output NFS_CATALOG_STRUCT* NeFileSystemParser::FindCatalog(_Input const Char* catalog_name, + Lba& out_lba) +{ + if (!catalog_name || + *catalog_name == 0) + return nullptr; + + kcout << "Start finding catalog...\r"; + + NFS_ROOT_PARTITION_BLOCK fs_buf{0}; + auto drive = kDiskMountpoint.A(); + + rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, + rt_string_len("fs/nefs-packet")); + + drive.fPacket.fPacketContent = &fs_buf; + drive.fPacket.fPacketSize = sizeof(NFS_ROOT_PARTITION_BLOCK); + drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress; + + drive.fInput(&drive.fPacket); + + NFS_ROOT_PARTITION_BLOCK* part = (NFS_ROOT_PARTITION_BLOCK*)&fs_buf; + + auto startCatalogList = part->StartCatalog; + const auto cCtartCatalogList = startCatalogList; + + auto localSearchFirst = false; + + NFS_CATALOG_STRUCT temporary_catalog{0}; + + drive.fPacket.fPacketLba = startCatalogList; + drive.fPacket.fPacketContent = &temporary_catalog; + drive.fPacket.fPacketSize = sizeof(NFS_CATALOG_STRUCT); + + drive.fInput(&drive.fPacket); + + if (!StringBuilder::Equals(catalog_name, NeFileSystemHelper::Root())) + { + Char parentName[kNeFSNodeNameLen] = {0}; + + for (SizeT indexFill = 0; indexFill < rt_string_len(catalog_name); ++indexFill) + { + parentName[indexFill] = catalog_name[indexFill]; + } + + SizeT indexReverseCopy = rt_string_len(parentName); + + // zero character. + parentName[--indexReverseCopy] = 0; + + // mandatory '/' character. + parentName[--indexReverseCopy] = 0; + + while (parentName[indexReverseCopy] != NeFileSystemHelper::Separator()) + { + parentName[indexReverseCopy] = 0; + --indexReverseCopy; + } + + NFS_CATALOG_STRUCT* parentCatalog = this->FindCatalog(parentName, out_lba); + + if (parentCatalog && + !StringBuilder::Equals(parentName, NeFileSystemHelper::Root())) + { + startCatalogList = parentCatalog->NextSibling; + delete parentCatalog; + + localSearchFirst = true; + } + else if (parentCatalog) + { + delete parentCatalog; + } + else + { + return nullptr; + } + } + + kcout << "Fetching catalog...\r"; + +NeFSSearchThroughCatalogList: + while (drive.fPacket.fPacketGood) + { + drive.fPacket.fPacketLba = startCatalogList; + drive.fPacket.fPacketContent = &temporary_catalog; + drive.fPacket.fPacketSize = sizeof(NFS_CATALOG_STRUCT); + + drive.fInput(&drive.fPacket); + + NFS_CATALOG_STRUCT* catalog = (NFS_CATALOG_STRUCT*)&temporary_catalog; + + if (StringBuilder::Equals(catalog_name, catalog->Name)) + { + /// ignore unallocated catalog, break + if (!(catalog->Flags & kNeFSFlagCreated)) + { + goto NeFSContinueSearch; + } + + NFS_CATALOG_STRUCT* catalogPtr = new NFS_CATALOG_STRUCT(); + rt_copy_memory(catalog, catalogPtr, sizeof(NFS_CATALOG_STRUCT)); + + kcout << "Found catalog at: " << hex_number(startCatalogList) << endl; + kcout << "Found catalog at: " << catalog->Name << endl; + + out_lba = startCatalogList; + return catalogPtr; + } + + NeFSContinueSearch: + startCatalogList = catalog->NextSibling; + + if (startCatalogList <= kNeFSRootCatalogStartAddress) + break; + } + + if (localSearchFirst) + { + localSearchFirst = false; + startCatalogList = cCtartCatalogList; + + goto NeFSSearchThroughCatalogList; + } + + out_lba = 0UL; + return nullptr; +} + +/// @brief Get catalog from filesystem. +/// @param name the catalog's name/ +/// @return +_Output NFS_CATALOG_STRUCT* NeFileSystemParser::GetCatalog(_Input const Char* name) +{ + Lba unused = 0; + return this->FindCatalog(name, unused); +} + +/// @brief Closes a catalog, (frees it). +/// @param catalog the catalog to close. +/// @return +Boolean NeFileSystemParser::CloseCatalog(_Input _Output NFS_CATALOG_STRUCT* catalog) +{ + if (!catalog) + return false; + + delete catalog; + catalog = nullptr; + + return true; +} + +/// @brief Mark catalog as removed. +/// @param catalog The catalog structure. +/// @return if the catalog was removed or not. +Boolean NeFileSystemParser::RemoveCatalog(_Input const Char* catalog_name) +{ + if (!catalog_name || + StringBuilder::Equals(catalog_name, NeFileSystemHelper::Root())) + { + err_local_get() = kErrorInternal; + return false; + } + + Lba out_lba = 0; + auto catalog = this->FindCatalog(catalog_name, out_lba); + + if (out_lba >= kNeFSCatalogStartAddress || + catalog->Flags & kNeFSFlagCreated) + { + catalog->Flags |= kNeFSFlagDeleted; + + auto drive = kDiskMountpoint.A(); + + rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, + rt_string_len("fs/nefs-packet")); + + drive.fPacket.fPacketLba = out_lba; // the catalog position. + drive.fPacket.fPacketSize = + sizeof(NFS_CATALOG_STRUCT); // size of catalog. roughly the sector size. + drive.fPacket.fPacketContent = catalog; // the catalog itself. + + drive.fOutput(&drive.fPacket); // send packet. + + Char partitionBlockBuf[sizeof(NFS_ROOT_PARTITION_BLOCK)] = {0}; + + drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress; + drive.fPacket.fPacketContent = partitionBlockBuf; + drive.fPacket.fPacketSize = sizeof(NFS_ROOT_PARTITION_BLOCK); + + drive.fInput(&drive.fPacket); + + NFS_ROOT_PARTITION_BLOCK* part_block = + reinterpret_cast(partitionBlockBuf); + + --part_block->CatalogCount; + ++part_block->FreeSectors; + + drive.fOutput(&drive.fPacket); + + return true; + } + + delete catalog; + return false; +} + +/// ***************************************************************** /// +/// Reading,Seek,Tell are unimplemented on catalogs, refer to forks I/O instead. +/// ***************************************************************** /// + +/***********************************************************************************/ +/// @brief Read the catalog data fork. +/// @param catalog +/// @param dataSz +/// @return +/***********************************************************************************/ + +VoidPtr NeFileSystemParser::ReadCatalog(_Input _Output NFS_CATALOG_STRUCT* catalog, + _Input Bool is_rsrc_fork, + _Input SizeT dataSz, + _Input const Char* forkName) +{ + if (!catalog) + { + err_local_get() = kErrorFileNotFound; + return nullptr; + } + + constexpr auto cNeFSCatalogPadding = 4; + + Lba dataForkLba = (!is_rsrc_fork) ? catalog->DataFork : catalog->ResourceFork; + Size dataForkSize = (!is_rsrc_fork) ? catalog->DataForkSize : catalog->ResourceForkSize; + + kcout << "catalog " << catalog->Name + << ", fork: " << hex_number(dataForkLba) << endl; + + NFS_FORK_STRUCT* fs_buf = new NFS_FORK_STRUCT(); + auto drive = kDiskMountpoint.A(); + + rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, + rt_string_len("fs/nefs-packet")); + + NFS_FORK_STRUCT* fs_fork_data = nullptr; + + while (dataForkLba > kNeFSCatalogStartAddress) + { + drive.fPacket.fPacketLba = dataForkLba; + drive.fPacket.fPacketSize = sizeof(NFS_FORK_STRUCT); + drive.fPacket.fPacketContent = fs_buf; + + drive.fInput(&drive.fPacket); + + fs_fork_data = fs_buf; + + kcout << "ForkName: " << fs_fork_data->ForkName << endl; + kcout << "CatalogName: " << fs_fork_data->CatalogName << endl; + + if (StringBuilder::Equals(forkName, fs_fork_data->ForkName) && + StringBuilder::Equals(catalog->Name, fs_fork_data->CatalogName)) + break; + + dataForkLba = fs_fork_data->NextSibling; + } + + if (dataForkLba < kNeFSCatalogStartAddress) + { + delete fs_buf; + return nullptr; + } + + return fs_fork_data; +} + +/***********************************************************************************/ +/// @brief Seek in the data fork. +/// @param catalog the catalog offset. +/// @param off where to seek. +/// @return if the seeking was successful. +/***********************************************************************************/ + +bool NeFileSystemParser::Seek(_Input _Output NFS_CATALOG_STRUCT* catalog, SizeT off) +{ + if (!catalog) + { + err_local_get() = kErrorFileNotFound; + return false; + } + + err_local_get() = kErrorUnimplemented; + return false; +} + +/***********************************************************************************/ +/// @brief Tell where we are inside the data fork. +/// @param catalog +/// @return The position on the file. +/***********************************************************************************/ + +SizeT NeFileSystemParser::Tell(_Input _Output NFS_CATALOG_STRUCT* catalog) +{ + if (!catalog) + { + err_local_get() = kErrorFileNotFound; + return 0; + } + + err_local_get() = kErrorUnimplemented; + return 0; +} + +namespace Kernel::Detail +{ + /***********************************************************************************/ + /// @brief Construct NeFS drives. + /***********************************************************************************/ + Boolean fs_init_newfs(Void) noexcept + { + kcout << "Creating A: drive...\r"; + kcout << "Creating A:\r"; + + kDiskMountpoint.A() = io_construct_main_drive(); + kDiskMountpoint.B() = io_construct_blank_drive(); + kDiskMountpoint.C() = io_construct_blank_drive(); + kDiskMountpoint.D() = io_construct_blank_drive(); + + kcout << "Creating A: [ OK ]\r"; + + return true; + } +} // namespace Kernel::Detail + +#endif // ifdef __FSKIT_INCLUDES_NEFS__ diff --git a/dev/Kernel/src/FileMgr.cc b/dev/Kernel/src/FileMgr.cc new file mode 100644 index 00000000..b522a858 --- /dev/null +++ b/dev/Kernel/src/FileMgr.cc @@ -0,0 +1,52 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include + +/// BUGS: 0 +//! @brief File System Manager API. + +namespace Kernel +{ + STATIC IFilesystemMgr* kMountedFilesystem = nullptr; + + /// @brief FilesystemMgr getter. + /// @return The mounted filesystem. + _Output IFilesystemMgr* IFilesystemMgr::GetMounted() + { + return kMountedFilesystem; + } + + /// @brief Unmount filesystem. + /// @return The unmounted filesystem. + _Output IFilesystemMgr* IFilesystemMgr::Unmount() + { + if (kMountedFilesystem) + { + auto mount = kMountedFilesystem; + kMountedFilesystem = nullptr; + + return mount; + } + + return nullptr; + } + + /// @brief Mount filesystem. + /// @param mount_ptr The filesystem to mount. + /// @return if it succeeded true, otherwise false. + _Output Bool IFilesystemMgr::Mount(_Input IFilesystemMgr* mount_ptr) + { + if (mount_ptr != nullptr) + { + kMountedFilesystem = mount_ptr; + return Yes; + } + + return No; + } +} // namespace Kernel diff --git a/dev/Kernel/src/GUIDWizard.cc b/dev/Kernel/src/GUIDWizard.cc new file mode 100644 index 00000000..fb58556b --- /dev/null +++ b/dev/Kernel/src/GUIDWizard.cc @@ -0,0 +1,72 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + + File: GUIDWizard.cc + Purpose: GUID helper code + + Revision History: + +------------------------------------------- */ + +#include +#include + +// begin of ascii 'readable' characters. (A, C, C, 1, 2) +#define kUUIDAsciiBegin 47 +// @brief Size of UUID. +#define kUUIDSize 37 + +namespace CFKit::XRN::Version1 +{ + auto cf_make_sequence(const ArrayList& uuidSeq) -> Ref + { + GUIDSequence* seq = new GUIDSequence(); + MUST_PASS(seq); + + Ref seq_ref{seq}; + + seq_ref.Leak()->fMs1 = uuidSeq[0]; + seq_ref.Leak()->fMs2 = uuidSeq[1]; + seq_ref.Leak()->fMs3 = uuidSeq[2]; + seq_ref.Leak()->fMs4[0] = uuidSeq[3]; + seq_ref.Leak()->fMs4[1] = uuidSeq[4]; + seq_ref.Leak()->fMs4[2] = uuidSeq[5]; + seq_ref.Leak()->fMs4[3] = uuidSeq[6]; + seq_ref.Leak()->fMs4[4] = uuidSeq[7]; + seq_ref.Leak()->fMs4[5] = uuidSeq[8]; + seq_ref.Leak()->fMs4[6] = uuidSeq[9]; + seq_ref.Leak()->fMs4[7] = uuidSeq[10]; + + return seq_ref; + } + + // @brief Tries to make a guid out of a string. + // This function is not complete for now + auto cf_try_guid_to_string(Ref& seq) -> ErrorOr> + { + Char buf[kUUIDSize]; + + for (SizeT index = 0; index < 16; ++index) + { + buf[index] = seq.Leak()->u8[index] + kUUIDAsciiBegin; + } + + for (SizeT index = 16; index < 24; ++index) + { + buf[index] = seq.Leak()->u16[index] + kUUIDAsciiBegin; + } + + for (SizeT index = 24; index < 28; ++index) + { + buf[index] = seq.Leak()->u32[index] + kUUIDAsciiBegin; + } + + auto view = StringBuilder::Construct(buf); + + if (view) + return ErrorOr>{view.Leak()}; + + return ErrorOr>{-1}; + } +} // namespace CFKit::XRN::Version1 diff --git a/dev/Kernel/src/GUIDWrapper.cc b/dev/Kernel/src/GUIDWrapper.cc new file mode 100644 index 00000000..b3a08b64 --- /dev/null +++ b/dev/Kernel/src/GUIDWrapper.cc @@ -0,0 +1,11 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include + +namespace CFKit::XRN +{ +} diff --git a/dev/Kernel/src/HardwareThreadScheduler.cc b/dev/Kernel/src/HardwareThreadScheduler.cc new file mode 100644 index 00000000..b71537b5 --- /dev/null +++ b/dev/Kernel/src/HardwareThreadScheduler.cc @@ -0,0 +1,238 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include +#include +#include + +/***********************************************************************************/ +///! @file HardwareThreadScheduler.cc +///! @brief This file handles multi processing in the Kernel. +///! @brief Multi processing is needed for multi-tasking operations. +/***********************************************************************************/ + +namespace Kernel +{ + /***********************************************************************************/ + /// @note Those symbols are needed in order to switch and validate the stack. + /***********************************************************************************/ + + EXTERN Bool hal_check_stack(HAL::StackFramePtr frame_ptr); + EXTERN_C Bool mp_register_process(VoidPtr image, Ptr8 stack_ptr, HAL::StackFramePtr frame, ProcessID pid); + + STATIC HardwareThreadScheduler kHardwareThreadScheduler; + + ///! A HardwareThread class takes care of it's owned hardware thread. + ///! It has a stack for it's core. + + /***********************************************************************************/ + ///! @brief C++ constructor. + /***********************************************************************************/ + HardwareThread::HardwareThread() = default; + + /***********************************************************************************/ + ///! @brief C++ destructor. + /***********************************************************************************/ + HardwareThread::~HardwareThread() = default; + + /***********************************************************************************/ + //! @brief returns the id of the thread. + /***********************************************************************************/ + const ThreadID& HardwareThread::ID() noexcept + { + return fID; + } + + /***********************************************************************************/ + //! @brief returns the kind of thread we have. + /***********************************************************************************/ + const ThreadKind& HardwareThread::Kind() noexcept + { + return fKind; + } + + /***********************************************************************************/ + //! @brief is the thread busy? + //! @return whether the thread is busy or not. + /***********************************************************************************/ + Bool HardwareThread::IsBusy() noexcept + { + STATIC Int64 busy_timer = 0U; + + if (fBusy && busy_timer > this->fPTime) + { + busy_timer = 0U; + fBusy = No; + } + + ++busy_timer; + + return fBusy; + } + + /***********************************************************************************/ + /// @brief Get processor stack frame. + /***********************************************************************************/ + + HAL::StackFramePtr HardwareThread::StackFrame() noexcept + { + MUST_PASS(fStack); + return fStack; + } + + Void HardwareThread::Busy(const Bool busy) noexcept + { + fBusy = busy; + } + + HardwareThread::operator bool() + { + return this->fStack && !this->fBusy; + } + + /***********************************************************************************/ + /// @brief Wakeup the processor. + /***********************************************************************************/ + + Void HardwareThread::Wake(const bool wakeup) noexcept + { + fWakeup = wakeup; + + if (!fWakeup) + mp_hang_thread(fStack); + else + mp_wakeup_thread(fStack); + } + + /***********************************************************************************/ + /// @brief Switch to hardware thread. + /// @param stack the new hardware thread. + /// @retval true stack was changed, code is running. + /// @retval false stack is invalid, previous code is running. + /***********************************************************************************/ + Bool HardwareThread::Switch(VoidPtr image, Ptr8 stack_ptr, HAL::StackFramePtr frame, const ProcessID& pid) + { + if (!frame || + !image || + !stack_ptr) + return No; + + if (!this->IsWakeup()) + return No; + + if (this->IsBusy()) + return No; + + if (!hal_check_stack(frame)) + return No; + + this->fStack = frame; + this->fSourcePID = pid; + + Bool ret = mp_register_process(image, stack_ptr, fStack, this->fSourcePID); + + if (ret) + this->Busy(true); + + return ret; + } + + /***********************************************************************************/ + ///! @brief Tells if processor is waked up. + /***********************************************************************************/ + bool HardwareThread::IsWakeup() noexcept + { + return fWakeup; + } + + /***********************************************************************************/ + ///! @brief Constructor and destructors. + ///! @brief Default constructor. + /***********************************************************************************/ + + HardwareThreadScheduler::HardwareThreadScheduler() = default; + + /***********************************************************************************/ + ///! @brief Default destructor. + /***********************************************************************************/ + HardwareThreadScheduler::~HardwareThreadScheduler() = default; + + /***********************************************************************************/ + /// @brief Shared singleton function + /***********************************************************************************/ + HardwareThreadScheduler& HardwareThreadScheduler::The() + { + return kHardwareThreadScheduler; + } + + /***********************************************************************************/ + /// @brief Get Stack Frame of AP. + /***********************************************************************************/ + HAL::StackFramePtr HardwareThreadScheduler::Leak() noexcept + { + return fThreadList[fCurrentThread].fStack; + } + + /***********************************************************************************/ + /** + * Get Hardware thread at index. + * @param idx the index + * @return the reference to the hardware thread. + */ + /***********************************************************************************/ + Ref HardwareThreadScheduler::operator[](const SizeT& idx) + { + if (idx == 0) + { + if (fThreadList[idx].Kind() != kAPSystemReserved) + { + fThreadList[idx].fKind = kAPBoot; + } + } + else if (idx >= kMaxAPInsideSched) + { + static HardwareThread* fakeThread = nullptr; + return {fakeThread}; + } + + return &fThreadList[idx]; + } + + /***********************************************************************************/ + /** + * Check if thread pool isn't empty. + * @return + */ + /***********************************************************************************/ + HardwareThreadScheduler::operator bool() noexcept + { + return !fThreadList.Empty(); + } + + /***********************************************************************************/ + /** + * Reverse operator bool + * @return + */ + /***********************************************************************************/ + bool HardwareThreadScheduler::operator!() noexcept + { + return fThreadList.Empty(); + } + + /***********************************************************************************/ + /// @brief Returns the amount of core present. + /// @return the number of APs. + /***********************************************************************************/ + SizeT HardwareThreadScheduler::Capacity() noexcept + { + if (fThreadList.Empty()) + return 0UL; + + return fThreadList.Capacity(); + } +} // namespace Kernel diff --git a/dev/Kernel/src/Heap.cc b/dev/Kernel/src/Heap.cc new file mode 100644 index 00000000..2cf7e56a --- /dev/null +++ b/dev/Kernel/src/Heap.cc @@ -0,0 +1,307 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include +#include +#include +#include +#include +#include + +/* ------------------------------------------- + + Revision History: + 10/8/24: FIX: Fix useless long name, alongside a new WR (WriteRead) field. + 20/10/24: Fix mm_new_ and mm_delete_ APIs inside Heap.h header. (amlal) + + ------------------------------------------- */ + +//! @file Heap.cc +//! @brief This serves as the main memory manager. + +#define kKernelHeapMagic (0xD4D7D5) +#define kKernelHeapAlignSz (__BIGGEST_ALIGNMENT__) +#define kKernelHeapMaxSize (gib_cast(2)) + +namespace Kernel +{ + /// @brief Contains data structures and algorithms for the heap. + namespace Detail + { + struct PACKED HEAP_INFORMATION_BLOCK; + + /// @brief Kernel heap information block. + /// Located before the address bytes. + /// | HIB | CLASS/STRUCT/DATA TYPES... | + struct PACKED HEAP_INFORMATION_BLOCK final + { + ///! @brief 32-bit value which contains the magic number of the heap. + UInt32 fMagic : 24; + + ///! @brief Boolean value which tells if the heap is allocated. + Boolean fPresent : 1; + + /// @brief Is this valued owned by the user? + Boolean fWriteRead : 1; + + /// @brief Is this valued owned by the user? + Boolean fUser : 1; + + /// @brief Is this a page pointer? + Boolean fPagePtr : 1; + + /// @brief 32-bit CRC checksum. + UInt32 fCRC32; + + /// @brief 64-bit Allocation flags. + UInt64 fFlags; + + /// @brief 64-bit pointer size. + SizeT fHeapSize; + + /// @brief 64-bit target pointer. + UIntPtr fHeapPtr; + + /// @brief Padding bytes for header. + UInt8 fPadding[kKernelHeapAlignSz]; + }; + + /// @brief Check for heap address validity. + /// @param heap_ptr The address_ptr to check. + /// @return Bool if the pointer is valid or not. + _Output auto mm_check_heap_address(VoidPtr heap_ptr) -> Bool + { + if (!heap_ptr) + return false; + + /// Add that check in case we're having an integer underflow. /// + + auto base_heap = (IntPtr)(heap_ptr) - sizeof(Detail::HEAP_INFORMATION_BLOCK); + + if (base_heap < 0) + { + return false; + } + + return true; + } + + typedef HEAP_INFORMATION_BLOCK* HEAP_INFORMATION_BLOCK_PTR; + } // namespace Detail + + /// @brief Declare a new size for ptr_heap. + /// @param ptr_heap the pointer. + /// @return Newly allocated heap header. + _Output VoidPtr mm_realloc_heap(VoidPtr ptr_heap, SizeT new_sz) + { + if (Detail::mm_check_heap_address(ptr_heap) == No) + return nullptr; + + if (!ptr_heap || new_sz < 1) + return nullptr; + + kcout << "This function is not implemented by minOSKrnl, please use the BSD's realloc instead.\r"; + ke_stop(RUNTIME_CHECK_PROCESS); + + return nullptr; + } + + /// @brief Allocate chunk of memory. + /// @param sz Size of pointer + /// @param wr Read Write bit. + /// @param user User enable bit. + /// @return The newly allocated pointer. + _Output VoidPtr mm_new_heap(const SizeT sz, const bool wr, const bool user) + { + auto sz_fix = sz; + + if (sz_fix == 0) + return nullptr; + + // We can't allocate that big now. + MUST_PASS(sz < kKernelHeapMaxSize); + + sz_fix += sizeof(Detail::HEAP_INFORMATION_BLOCK); + + PageMgr heap_mgr; + auto wrapper = heap_mgr.Request(wr, user, No, sz_fix); + + Detail::HEAP_INFORMATION_BLOCK_PTR heap_info_ptr = + reinterpret_cast( + wrapper.VirtualAddress() + sizeof(Detail::HEAP_INFORMATION_BLOCK)); + + heap_info_ptr->fHeapSize = sz_fix; + heap_info_ptr->fMagic = kKernelHeapMagic; + heap_info_ptr->fCRC32 = No; // dont fill it for now. + heap_info_ptr->fHeapPtr = reinterpret_cast(heap_info_ptr) + sizeof(Detail::HEAP_INFORMATION_BLOCK); + heap_info_ptr->fPagePtr = No; + heap_info_ptr->fWriteRead = wr; + heap_info_ptr->fUser = user; + heap_info_ptr->fPresent = Yes; + + rt_set_memory(heap_info_ptr->fPadding, 0, kKernelHeapAlignSz); + + auto result = reinterpret_cast(heap_info_ptr->fHeapPtr); + + kcout << "Created Heap address: " << hex_number(reinterpret_cast(heap_info_ptr)) << endl; + + return result; + } + + /// @brief Makes a page heap. + /// @param heap_ptr the pointer to make a page heap. + /// @return kErrorSuccess if successful, otherwise an error code. + _Output Int32 mm_make_page(VoidPtr heap_ptr) + { + if (Detail::mm_check_heap_address(heap_ptr) == No) + return kErrorHeapNotPresent; + + Detail::HEAP_INFORMATION_BLOCK_PTR heap_info_ptr = + reinterpret_cast( + (UIntPtr)heap_ptr - sizeof(Detail::HEAP_INFORMATION_BLOCK)); + + if (!heap_info_ptr) + return kErrorHeapNotPresent; + + heap_info_ptr->fPagePtr = true; + + kcout << "Created page address: " << hex_number(reinterpret_cast(heap_info_ptr)) << endl; + + return kErrorSuccess; + } + + /// @brief Overwrites and set the flags of a heap header. + /// @param heap_ptr the pointer to update. + /// @param flags the flags to set. + _Output Int32 mm_make_flags(VoidPtr heap_ptr, UInt64 flags) + { + if (Detail::mm_check_heap_address(heap_ptr) == No) + return kErrorHeapNotPresent; + + Detail::HEAP_INFORMATION_BLOCK_PTR heap_info_ptr = + reinterpret_cast( + (UIntPtr)heap_ptr - sizeof(Detail::HEAP_INFORMATION_BLOCK)); + + if (!heap_info_ptr) + return kErrorHeapNotPresent; + + heap_info_ptr->fFlags = flags; + + return kErrorSuccess; + } + + /// @brief Gets the flags of a heap header. + /// @param heap_ptr the pointer to get. + _Output UInt64 mm_get_flags(VoidPtr heap_ptr) + { + Detail::HEAP_INFORMATION_BLOCK_PTR heap_info_ptr = + reinterpret_cast( + (UIntPtr)heap_ptr - sizeof(Detail::HEAP_INFORMATION_BLOCK)); + + if (!heap_info_ptr) + return kErrorHeapNotPresent; + + return heap_info_ptr->fFlags; + } + + /// @brief Declare pointer as free. + /// @param heap_ptr the pointer. + /// @return + _Output Int32 mm_delete_heap(VoidPtr heap_ptr) + { + if (Detail::mm_check_heap_address(heap_ptr) == No) + return kErrorHeapNotPresent; + + Detail::HEAP_INFORMATION_BLOCK_PTR heap_info_ptr = + reinterpret_cast( + (UIntPtr)(heap_ptr) - sizeof(Detail::HEAP_INFORMATION_BLOCK)); + + if (heap_info_ptr && heap_info_ptr->fMagic == kKernelHeapMagic) + { + if (!heap_info_ptr->fPresent) + { + return kErrorHeapNotPresent; + } + + if (heap_info_ptr->fCRC32 != 0) + { + if (heap_info_ptr->fCRC32 != + ke_calculate_crc32((Char*)heap_info_ptr->fHeapPtr, + heap_info_ptr->fHeapSize)) + { + if (!heap_info_ptr->fUser) + { + ke_stop(RUNTIME_CHECK_POINTER); + } + } + } + + heap_info_ptr->fHeapSize = 0UL; + heap_info_ptr->fPresent = No; + heap_info_ptr->fHeapPtr = 0; + heap_info_ptr->fCRC32 = 0; + heap_info_ptr->fWriteRead = No; + heap_info_ptr->fUser = No; + heap_info_ptr->fMagic = 0; + + PTEWrapper pageWrapper(No, No, No, reinterpret_cast(heap_info_ptr) - sizeof(Detail::HEAP_INFORMATION_BLOCK)); + Ref pteAddress{pageWrapper}; + + PageMgr heap_mgr; + heap_mgr.Free(pteAddress); + + kcout << "Freed Heap address successfully." << endl; + + return kErrorSuccess; + } + + return kErrorInternal; + } + + /// @brief Check if pointer is a valid Kernel pointer. + /// @param heap_ptr the pointer + /// @return if it exists. + _Output Boolean mm_is_valid_heap(VoidPtr heap_ptr) + { + if (heap_ptr && HAL::mm_is_bitmap(heap_ptr)) + { + Detail::HEAP_INFORMATION_BLOCK_PTR heap_info_ptr = + reinterpret_cast( + (UIntPtr)(heap_ptr) - sizeof(Detail::HEAP_INFORMATION_BLOCK)); + + if (heap_info_ptr && heap_info_ptr->fPresent && heap_info_ptr->fMagic == kKernelHeapMagic) + { + return Yes; + } + } + + return No; + } + + /// @brief Protect the heap with a CRC value. + /// @param heap_ptr HIB pointer. + /// @return if it valid: point has crc now., otherwise fail. + _Output Boolean mm_protect_heap(VoidPtr heap_ptr) + { + if (heap_ptr) + { + Detail::HEAP_INFORMATION_BLOCK_PTR heap_info_ptr = + reinterpret_cast( + (UIntPtr)heap_ptr - sizeof(Detail::HEAP_INFORMATION_BLOCK)); + + if (heap_info_ptr && heap_info_ptr->fPresent && kKernelHeapMagic == heap_info_ptr->fMagic) + { + heap_info_ptr->fCRC32 = + ke_calculate_crc32((Char*)heap_info_ptr->fHeapPtr, heap_info_ptr->fHeapSize); + + return Yes; + } + } + + return No; + } +} // namespace Kernel diff --git a/dev/Kernel/src/IDLLObject.cc b/dev/Kernel/src/IDLLObject.cc new file mode 100644 index 00000000..6355045e --- /dev/null +++ b/dev/Kernel/src/IDLLObject.cc @@ -0,0 +1,15 @@ +/* + * ======================================================== + * + * minoskrnl + * Copyright (C) 2024, TQ B.V, all rights reserved., all rights reserved. + * + * ======================================================== + */ + +#include +#include + +#include + +using namespace Kernel; diff --git a/dev/Kernel/src/IPEFDLLObject.cc b/dev/Kernel/src/IPEFDLLObject.cc new file mode 100644 index 00000000..0089b877 --- /dev/null +++ b/dev/Kernel/src/IPEFDLLObject.cc @@ -0,0 +1,103 @@ +/* + * ======================================================== + * + * minoskrnl + * Copyright (C) 2024, TQ B.V, all rights reserved., all rights reserved. + * + * ======================================================== + */ + +#include +#include +#include +#include +#include +#include + +/* ------------------------------------------- + + Revision History: + + 01/02/24: Reworked dll ABI, expect a rtl_init_dylib and + rtl_fini_dylib (amlel) 15/02/24: Breaking changes, changed the name of the + routines. (amlel) + + 07/28/24: Replace rt_library_free with rtl_fini_dylib + + 10/8/24: FIX: Fix log comment. + + ------------------------------------------- */ + +using namespace Kernel; + +/***********************************************************************************/ +/// @file IPEFDLLObject.cc +/// @brief PEF's DLL runtime. +/***********************************************************************************/ + +/***********************************************************************************/ +/** @brief Library initializer. */ +/***********************************************************************************/ + +EXTERN_C IDLL rtl_init_dylib(UserProcess* header) +{ + IDLL dll_obj = tls_new_class(); + + if (!dll_obj) + { + header->Crash(); + return nullptr; + } + + dll_obj->Mount(tls_new_class()); + + if (!dll_obj->Get()) + { + tls_delete_class(dll_obj); + header->Crash(); + + return nullptr; + } + + dll_obj->Get()->ImageObject = + header->Image.fBlob; + + if (!dll_obj->Get()->ImageObject) + { + tls_delete_class(dll_obj); + header->Crash(); + + return nullptr; + } + + dll_obj->Get()->ImageEntrypointOffset = + dll_obj->Load(kPefStart, rt_string_len(kPefStart, 0), kPefCode); + + return dll_obj; +} + +/***********************************************************************************/ +/** @brief Frees the dll_obj. */ +/** @note Please check if the dll_obj got freed! */ +/** @param dll_obj The dll_obj to free. */ +/** @param successful Reports if successful or not. */ +/***********************************************************************************/ + +EXTERN_C Void rtl_fini_dylib(UserProcess* header, IDLL dll_obj, Bool* successful) +{ + MUST_PASS(successful); + + // sanity check (will also trigger a bug check if this fails) + if (dll_obj == nullptr) + { + *successful = false; + header->Crash(); + } + + delete dll_obj->Get(); + delete dll_obj; + + dll_obj = nullptr; + + *successful = true; +} diff --git a/dev/Kernel/src/IndexableProperty.cc b/dev/Kernel/src/IndexableProperty.cc new file mode 100644 index 00000000..6d60ccc3 --- /dev/null +++ b/dev/Kernel/src/IndexableProperty.cc @@ -0,0 +1,57 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include +#include +#include + +/// @brief File indexer API for fast path access. +/// BUGS: 0 + +#define kMaxLenIndexer (256U) + +namespace Kernel +{ + namespace Indexer + { + IndexProperty& IndexableProperty::Leak() noexcept + { + return fIndex; + } + + Void IndexableProperty::AddFlag(Int16 flag) + { + fFlags |= flag; + } + + Void IndexableProperty::RemoveFlag(Int16 flag) + { + fFlags &= flag; + } + + Int16 IndexableProperty::HasFlag(Int16 flag) + { + return fFlags & flag; + } + + /// @brief Index a file into the indexer instance. + /// @param filename filesystem path to access. + /// @param filenameLen used bytes in path. + /// @param indexer the filesystem indexer. + /// @return none, check before if indexer can be claimed (using indexer.HasFlag(kIndexerClaimed)). + Void fs_index_file(const Char* filename, SizeT filenameLen, IndexableProperty& indexer) + { + if (!indexer.HasFlag(kIndexerClaimed)) + { + indexer.AddFlag(kIndexerClaimed); + rt_copy_memory((VoidPtr)indexer.Leak().Path, (VoidPtr)filename, filenameLen); + + kcout << "FSKit: Indexed new file: " << filename << endl; + } + } + } // namespace Indexer +} // namespace Kernel diff --git a/dev/Kernel/src/Json.cc b/dev/Kernel/src/Json.cc new file mode 100644 index 00000000..77ebb073 --- /dev/null +++ b/dev/Kernel/src/Json.cc @@ -0,0 +1,10 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include + +/// @brief Undefined object, is null in length. +INIT_OBJECT(Kernel::JSON::kNull, Kernel::JSON); diff --git a/dev/Kernel/src/KString.cc b/dev/Kernel/src/KString.cc new file mode 100644 index 00000000..2bcf8365 --- /dev/null +++ b/dev/Kernel/src/KString.cc @@ -0,0 +1,217 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include + +/// @file KString.cc +/// @brief Kernel String manipulation file. + +namespace Kernel +{ + Char* KString::Data() + { + return fData; + } + + const Char* KString::CData() const + { + return fData; + } + + Size KString::Length() const + { + return fDataSz; + } + + bool KString::operator==(const KString& rhs) const + { + if (rhs.Length() != this->Length()) + return false; + + for (Size index = 0; index < this->Length(); ++index) + { + if (rhs.fData[index] != fData[index]) + return false; + } + + return true; + } + + bool KString::operator==(const Char* rhs) const + { + if (rt_string_len(rhs) != this->Length()) + return false; + + for (Size index = 0; index < rt_string_len(rhs); ++index) + { + if (rhs[index] != fData[index]) + return false; + } + + return true; + } + + bool KString::operator!=(const KString& rhs) const + { + if (rhs.Length() != this->Length()) + return false; + + for (Size index = 0; index < rhs.Length(); ++index) + { + if (rhs.fData[index] == fData[index]) + return false; + } + + return true; + } + + bool KString::operator!=(const Char* rhs) const + { + if (rt_string_len(rhs) != this->Length()) + return false; + + for (Size index = 0; index < rt_string_len(rhs); ++index) + { + if (rhs[index] == fData[index]) + return false; + } + + return true; + } + + ErrorOr StringBuilder::Construct(const Char* data) + { + if (!data || *data == 0) + return {}; + + KString* view = new KString(rt_string_len(data)); + (*view) += data; + + return ErrorOr(*view); + } + + const Char* StringBuilder::FromBool(const Char* fmt, bool i) + { + if (!fmt) + return ("?"); + + const Char* boolean_expr = i ? "YES" : "NO"; + Char* ret = (Char*)rtl_alloca((sizeof(char) * i) ? 4 : 5 + rt_string_len(fmt)); + + if (!ret) + return ("?"); + + const auto fmt_len = rt_string_len(fmt); + const auto res_len = rt_string_len(boolean_expr); + + for (Size idx = 0; idx < fmt_len; ++idx) + { + if (fmt[idx] == '%') + { + SizeT result_cnt = idx; + + for (auto y_idx = idx; y_idx < res_len; ++y_idx) + { + ret[result_cnt] = boolean_expr[y_idx]; + ++result_cnt; + } + + break; + } + + ret[idx] = fmt[idx]; + } + + return ret; + } + + bool StringBuilder::Equals(const Char* lhs, const Char* rhs) + { + if (rt_string_len(rhs) != rt_string_len(lhs)) + return false; + + for (Size index = 0; index < rt_string_len(rhs); ++index) + { + if (rhs[index] != lhs[index]) + return false; + } + + return true; + } + + bool StringBuilder::Equals(const WideChar* lhs, const WideChar* rhs) + { + for (Size index = 0; rhs[index] != 0; ++index) + { + if (rhs[index] != lhs[index]) + return false; + } + + return true; + } + + const Char* StringBuilder::Format(const Char* fmt, const Char* fmt2) + { + if (!fmt || !fmt2) + return ("?"); + + Char* ret = + (Char*)rtl_alloca(sizeof(char) * rt_string_len(fmt2) + rt_string_len(fmt)); + + if (!ret) + return ("?"); + + for (Size idx = 0; idx < rt_string_len(fmt); ++idx) + { + if (fmt[idx] == '%') + { + Size result_cnt = idx; + for (Size y_idx = 0; y_idx < rt_string_len(fmt2); ++y_idx) + { + ret[result_cnt] = fmt2[y_idx]; + ++result_cnt; + } + + break; + } + + ret[idx] = fmt[idx]; + } + + return ret; + } + + STATIC void rt_string_append(Char* lhs, const Char* rhs, Int32 cur) + { + SizeT sz_rhs = rt_string_len(rhs); + SizeT rhs_i = 0; + + for (; rhs_i < sz_rhs; ++rhs_i) + { + lhs[rhs_i + cur] = rhs[rhs_i]; + } + } + + KString& KString::operator+=(const Char* rhs) + { + rt_string_append(this->fData, rhs, this->fCur); + this->fCur += rt_string_len(rhs); + + return *this; + } + + KString& KString::operator+=(const KString& rhs) + { + if (rt_string_len(rhs.fData) > this->Length()) + return *this; + + rt_string_append(this->fData, const_cast(rhs.fData), this->fCur); + this->fCur += rt_string_len(const_cast(rhs.fData)); + + return *this; + } +} // namespace Kernel diff --git a/dev/Kernel/src/KernelMain.cc b/dev/Kernel/src/KernelMain.cc new file mode 100644 index 00000000..6907deea --- /dev/null +++ b/dev/Kernel/src/KernelMain.cc @@ -0,0 +1,126 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies + + File: Main.cxx + Purpose: Main entrypoint of kernel. + +------------------------------------------- */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +STATIC CG::ML_WINDOW_STRUCT* kKernelWnd = nullptr; + +namespace Kernel::Detail +{ + /// @brief Filesystem auto formatter, additional checks are also done by the class. + class FilesystemInstaller final + { + Kernel::NeFileSystemMgr* fNeFS{nullptr}; + + public: + /// @brief wizard constructor. + FilesystemInstaller() + { + fNeFS = (Kernel::NeFileSystemMgr*)Kernel::IFilesystemMgr::GetMounted(); + + if (fNeFS && fNeFS->GetParser()) + { + constexpr auto kFolderInfo = "META-XML"; + const auto kFolderCount = 7; + const char* kFolderStr[kFolderCount] = { + "/Boot/", "/System/", "/Support/", "/Applications/", + "/Users/", "/Library/", "/Mount/"}; + + for (Kernel::SizeT dir_index = 0UL; dir_index < kFolderCount; ++dir_index) + { + auto catalog_folder = fNeFS->GetParser()->GetCatalog(kFolderStr[dir_index]); + + if (catalog_folder) + { + delete catalog_folder; + catalog_folder = nullptr; + + continue; + } + + catalog_folder = fNeFS->GetParser()->CreateCatalog(kFolderStr[dir_index], 0, + kNeFSCatalogKindDir); + + NFS_FORK_STRUCT fork_folder{0}; + + Kernel::rt_copy_memory((Kernel::VoidPtr)(kFolderInfo), fork_folder.ForkName, + Kernel::rt_string_len(kFolderInfo)); + + Kernel::rt_copy_memory((Kernel::VoidPtr)(catalog_folder->Name), + fork_folder.CatalogName, + Kernel::rt_string_len(catalog_folder->Name)); + + fork_folder.DataSize = kNeFSForkSize; + fork_folder.ResourceId = 0; + fork_folder.ResourceKind = Kernel::kNeFSRsrcForkKind; + fork_folder.Kind = Kernel::kNeFSDataForkKind; + + Kernel::KString folder_metadata(2048); + + folder_metadata += + "\r

Kind: folder

\r

Created by: system

\r

Edited by: " + "system

\r

Volume Type: Zeta

\r"; + + folder_metadata += "

Path: "; + folder_metadata += kFolderStr[dir_index]; + folder_metadata += "

\r"; + + const Kernel::SizeT kMetaDataSz = kNeFSSectorSz; + + fNeFS->GetParser()->CreateFork(catalog_folder, fork_folder); + + fNeFS->GetParser()->WriteCatalog( + catalog_folder, true, (Kernel::VoidPtr)(folder_metadata.CData()), + kMetaDataSz, kFolderInfo); + + delete catalog_folder; + catalog_folder = nullptr; + } + } + } + + ~FilesystemInstaller() = default; + + ZKA_COPY_DEFAULT(FilesystemInstaller); + + /// @brief Grab the disk's NewFS reference. + /// @return NeFileSystemMgr the filesystem interface + Kernel::NeFileSystemMgr* Leak() + { + return fNeFS; + } + }; +} // namespace Kernel::Detail + +/// @brief Application entrypoint. +/// @param Void +/// @return Void +EXTERN_C Kernel::Void rtl_kernel_main(Kernel::SizeT argc, char** argv, char** envp, Kernel::SizeT envp_len) +{ + Kernel::IFilesystemMgr::Mount(new Kernel::NeFileSystemMgr()); + Kernel::Detail::FilesystemInstaller installer; + + +} diff --git a/dev/Kernel/src/LPC.cc b/dev/Kernel/src/LPC.cc new file mode 100644 index 00000000..f1d7ed50 --- /dev/null +++ b/dev/Kernel/src/LPC.cc @@ -0,0 +1,34 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include + +namespace Kernel +{ + STATIC Bool kRaiseOnBugCheck = false; + + /// @brief Does a system wide bug check. + /// @param void no params. + /// @return if error-free: false, otherwise true. + Boolean err_bug_check(void) noexcept + { + if (kRaiseOnBugCheck) + { + ke_stop(RUNTIME_CHECK_BAD_BEHAVIOR); + } + + return No; + } + + /// @brief Tells if we should raise a bug check not. + /// @param void + /// @return void + Void err_bug_check_raise(Void) noexcept + { + kRaiseOnBugCheck = true; + } +} // namespace Kernel diff --git a/dev/Kernel/src/LockDelegate.cc b/dev/Kernel/src/LockDelegate.cc new file mode 100644 index 00000000..060637c2 --- /dev/null +++ b/dev/Kernel/src/LockDelegate.cc @@ -0,0 +1,12 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include + +namespace Kernel +{ + /// @note Leave it empty for now. +} // namespace Kernel diff --git a/dev/Kernel/src/MutableArray.cc b/dev/Kernel/src/MutableArray.cc new file mode 100644 index 00000000..15a2778c --- /dev/null +++ b/dev/Kernel/src/MutableArray.cc @@ -0,0 +1,7 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include diff --git a/dev/Kernel/src/NeFS+FileMgr.cc b/dev/Kernel/src/NeFS+FileMgr.cc new file mode 100644 index 00000000..513b9ab2 --- /dev/null +++ b/dev/Kernel/src/NeFS+FileMgr.cc @@ -0,0 +1,249 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include + +#ifndef __ZKA_MINIMAL_OS__ +#ifdef __FSKIT_INCLUDES_NEFS__ + +/// @brief NeFS File manager. +/// BUGS: 0 + +namespace Kernel +{ + /// @brief C++ constructor + NeFileSystemMgr::NeFileSystemMgr() + { + MUST_PASS(Detail::fs_init_newfs()); + + NeFileSystemParser* fImpl; + mm_new_class(&fImpl); + MUST_PASS(fImpl); + + kcout << "We are done allocating NeFileSystemParser...\r"; + } + + NeFileSystemMgr::~NeFileSystemMgr() + { + if (fImpl) + { + kcout << "Destroying NeFileSystemParser...\r"; + + mm_delete_class(&fImpl); + } + } + + /// @brief Removes a node from the filesystem. + /// @param path The filename + /// @return If it was deleted or not. + bool NeFileSystemMgr::Remove(_Input const Char* path) + { + if (path == nullptr || *path == 0) + return false; + + return fImpl->RemoveCatalog(path); + } + + /// @brief Creates a node with the specified. + /// @param path The filename path. + /// @return The Node pointer. + NodePtr NeFileSystemMgr::Create(_Input const Char* path) + { + return node_cast(fImpl->CreateCatalog(path)); + } + + /// @brief Creates a node with is a directory. + /// @param path The filename path. + /// @return The Node pointer. + NodePtr NeFileSystemMgr::CreateDirectory(const Char* path) + { + return node_cast(fImpl->CreateCatalog(path, 0, kNeFSCatalogKindDir)); + } + + /// @brief Creates a node with is a alias. + /// @param path The filename path. + /// @return The Node pointer. + NodePtr NeFileSystemMgr::CreateAlias(const Char* path) + { + return node_cast(fImpl->CreateCatalog(path, 0, kNeFSCatalogKindAlias)); + } + + /// @brief Creates a node with is a page file. + /// @param path The filename path. + /// @return The Node pointer. + NodePtr NeFileSystemMgr::CreateSwapFile(const Char* path) + { + return node_cast(fImpl->CreateCatalog(path, 0, kNeFSCatalogKindPage)); + } + + /// @brief Gets the root directory. + /// @return + const Char* NeFileSystemHelper::Root() + { + return kNeFSRoot; + } + + /// @brief Gets the up-dir directory. + /// @return + const Char* NeFileSystemHelper::UpDir() + { + return kNeFSUpDir; + } + + /// @brief Gets the separator character. + /// @return + const Char NeFileSystemHelper::Separator() + { + return kNeFSSeparator; + } + + /// @brief Gets the metafile character. + /// @return + const Char NeFileSystemHelper::MetaFile() + { + return kNeFSMetaFilePrefix; + } + + /// @brief Opens a new file. + /// @param path + /// @param r + /// @return + _Output NodePtr NeFileSystemMgr::Open(_Input const Char* path, _Input const Char* r) + { + if (!path || *path == 0) + return nullptr; + + if (!r || *r == 0) + return nullptr; + + auto catalog = fImpl->GetCatalog(path); + + return node_cast(catalog); + } + + /// @brief Writes to a catalog's fork. + /// @param node the node ptr. + /// @param data the data. + /// @param flags the size. + /// @return + Void NeFileSystemMgr::Write(_Input NodePtr node, _Input VoidPtr data, _Input Int32 flags, _Input SizeT size) + { + if (!node) + return; + if (!size) + return; + + constexpr auto cDataForkName = kNeFSDataFork; + this->Write(cDataForkName, node, data, flags, size); + } + + /// @brief Read from filesystem fork. + /// @param node the catalog node. + /// @param flags the flags with it. + /// @param sz the size to read. + /// @return + _Output VoidPtr NeFileSystemMgr::Read(_Input NodePtr node, _Input Int32 flags, _Input SizeT size) + { + if (!node) + return nullptr; + if (!size) + return nullptr; + + constexpr auto cDataForkName = kNeFSDataFork; + return this->Read(cDataForkName, node, flags, size); + } + + Void NeFileSystemMgr::Write(_Input const Char* name, + _Input NodePtr node, + _Input VoidPtr data, + _Input Int32 flags, + _Input SizeT size) + { + if (!size || + size > kNeFSForkSize) + return; + + if (!data) + return; + + ZKA_UNUSED(flags); + + if ((reinterpret_cast(node))->Kind == kNeFSCatalogKindFile) + fImpl->WriteCatalog(reinterpret_cast(node), (flags & kFileFlagRsrc ? true : false), data, size, + name); + } + + _Output VoidPtr NeFileSystemMgr::Read(_Input const Char* name, + _Input NodePtr node, + _Input Int32 flags, + _Input SizeT sz) + { + if (sz > kNeFSForkSize) + return nullptr; + + if (!sz) + return nullptr; + + ZKA_UNUSED(flags); + + if ((reinterpret_cast(node))->Kind == kNeFSCatalogKindFile) + return fImpl->ReadCatalog(reinterpret_cast(node), (flags & kFileFlagRsrc ? true : false), sz, + name); + + return nullptr; + } + + /// @brief Seek from Catalog. + /// @param node + /// @param off + /// @retval true always returns false, this is unimplemented. + /// @retval false always returns this, it is unimplemented. + + _Output Bool NeFileSystemMgr::Seek(NodePtr node, SizeT off) + { + if (!node || off == 0) + return false; + + return fImpl->Seek(reinterpret_cast(node), off); + } + + /// @brief Tell where the catalog is. + /// @param node + /// @retval true always returns false, this is unimplemented. + /// @retval false always returns this, it is unimplemented. + + _Output SizeT NeFileSystemMgr::Tell(NodePtr node) + { + if (!node) + return kNPos; + + return fImpl->Tell(reinterpret_cast(node)); + } + + /// @brief Rewinds the catalog. + /// @param node + /// @retval true always returns false, this is unimplemented. + /// @retval false always returns this, it is unimplemented. + + _Output Bool NeFileSystemMgr::Rewind(NodePtr node) + { + if (!node) + return false; + + return this->Seek(node, 0); + } + + /// @brief Returns the filesystem parser. + /// @return the Filesystem parser class. + _Output NeFileSystemParser* NeFileSystemMgr::GetParser() noexcept + { + return fImpl; + } +} // namespace Kernel + +#endif // ifdef __FSKIT_INCLUDES_NEFS__ +#endif // ifndef __ZKA_MINIMAL_OS__ diff --git a/dev/Kernel/src/NeFS+IO.cc b/dev/Kernel/src/NeFS+IO.cc new file mode 100644 index 00000000..912ef70e --- /dev/null +++ b/dev/Kernel/src/NeFS+IO.cc @@ -0,0 +1,101 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include + +/************************************************************* + * + * File: NeFS+IO.cc + * Purpose: Filesystem to mountpoint interface. + * Date: 3/26/24 + * + * Copyright (C) 2024, TQ B.V, all rights reserved., all rights reserved. + * + *************************************************************/ + +#ifdef __FSKIT_INCLUDES_NEFS__ + +#include + +/// Useful macros. + +#define NEFS_WRITE(DRV, TRAITS, MP) (MP->DRV()).fOutput(&TRAITS) +#define NEFS_READ(DRV, TRAITS, MP) (MP->DRV()).fInput(&TRAITS) + +using namespace Kernel; + +/// @brief Read from newfs disk. +/// @param Mnt mounted interface. +/// @param DrvTrait drive info +/// @param DrvIndex drive index. +/// @return +Int32 fs_newfs_read(MountpointInterface* Mnt, DriveTrait& DrvTrait, Int32 DrvIndex) +{ + if (!Mnt) + return 1; + + DrvTrait.fPacket.fPacketGood = false; + + switch (DrvIndex) + { + case kNeFSSubDriveA: { + NEFS_READ(A, DrvTrait.fPacket, Mnt); + break; + } + case kNeFSSubDriveB: { + NEFS_READ(B, DrvTrait.fPacket, Mnt); + break; + } + case kNeFSSubDriveC: { + NEFS_READ(C, DrvTrait.fPacket, Mnt); + break; + } + case kNeFSSubDriveD: { + NEFS_READ(D, DrvTrait.fPacket, Mnt); + break; + } + } + + return DrvTrait.fPacket.fPacketGood; +} + +/// @brief Write to newfs disk. +/// @param Mnt mounted interface. +/// @param DrvTrait drive info +/// @param DrvIndex drive index. +/// @return +Int32 fs_newfs_write(MountpointInterface* Mnt, DriveTrait& DrvTrait, Int32 DrvIndex) +{ + if (!Mnt) + return 1; + + DrvTrait.fPacket.fPacketGood = false; + + switch (DrvIndex) + { + case kNeFSSubDriveA: { + NEFS_WRITE(A, DrvTrait.fPacket, Mnt); + break; + } + case kNeFSSubDriveB: { + NEFS_WRITE(B, DrvTrait.fPacket, Mnt); + break; + } + case kNeFSSubDriveC: { + NEFS_WRITE(C, DrvTrait.fPacket, Mnt); + break; + } + case kNeFSSubDriveD: { + NEFS_WRITE(D, DrvTrait.fPacket, Mnt); + break; + } + } + + return DrvTrait.fPacket.fPacketGood; +} + +#endif // ifdef __FSKIT_INCLUDES_NEFS__ diff --git a/dev/Kernel/src/Network/IP.cc b/dev/Kernel/src/Network/IP.cc new file mode 100644 index 00000000..1b745f30 --- /dev/null +++ b/dev/Kernel/src/Network/IP.cc @@ -0,0 +1,126 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include + +namespace Kernel +{ + char* RawIPAddress::Address() + { + return fAddr; + } + + RawIPAddress::RawIPAddress(char bytes[4]) + { + rt_copy_memory(bytes, fAddr, 4); + } + + bool RawIPAddress::operator==(const RawIPAddress& ipv4) + { + for (Size index = 0; index < 4; ++index) + { + if (ipv4.fAddr[index] != fAddr[index]) + return false; + } + + return true; + } + + bool RawIPAddress::operator!=(const RawIPAddress& ipv4) + { + for (Size index = 0; index < 4; ++index) + { + if (ipv4.fAddr[index] == fAddr[index]) + return false; + } + + return true; + } + + char& RawIPAddress::operator[](const Size& index) + { + kcout << "[RawIPAddress::operator[]] Fetching Index...\r"; + + static char IP_PLACEHOLDER = '0'; + if (index > 4) + return IP_PLACEHOLDER; + + return fAddr[index]; + } + + RawIPAddress6::RawIPAddress6(char bytes[8]) + { + rt_copy_memory(bytes, fAddr, 8); + } + + char& RawIPAddress6::operator[](const Size& index) + { + kcout << "[RawIPAddress6::operator[]] Fetching Index...\r"; + + static char IP_PLACEHOLDER = '0'; + if (index > 8) + return IP_PLACEHOLDER; + + return fAddr[index]; + } + + bool RawIPAddress6::operator==(const RawIPAddress6& ipv6) + { + for (SizeT index = 0; index < 8; ++index) + { + if (ipv6.fAddr[index] != fAddr[index]) + return false; + } + + return true; + } + + bool RawIPAddress6::operator!=(const RawIPAddress6& ipv6) + { + for (SizeT index = 0; index < 8; ++index) + { + if (ipv6.fAddr[index] == fAddr[index]) + return false; + } + + return true; + } + + ErrorOr IPFactory::ToKString(Ref& ipv6) + { + auto str = StringBuilder::Construct(ipv6.Leak().Address()); + return str; + } + + ErrorOr IPFactory::ToKString(Ref& ipv4) + { + auto str = StringBuilder::Construct(ipv4.Leak().Address()); + return str; + } + + bool IPFactory::IpCheckVersion4(const Char* ip) + { + int cnter = 0; + + for (Size base = 0; base < rt_string_len(ip); ++base) + { + if (ip[base] == '.') + { + cnter = 0; + } + else + { + if (cnter == 3) + return false; + + ++cnter; + } + } + + return true; + } +} // namespace Kernel diff --git a/dev/Kernel/src/Network/IPC.cc b/dev/Kernel/src/Network/IPC.cc new file mode 100644 index 00000000..7ca796bd --- /dev/null +++ b/dev/Kernel/src/Network/IPC.cc @@ -0,0 +1,111 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include +#include + +using namespace Kernel; + +/// @internal +/// @brief The internal sanitize function. +Bool ipc_int_sanitize_packet(IPCMessage* pckt) +{ + auto endian = rtl_deduce_endianess(pckt, ((Char*)pckt)[0]); + + switch (endian) + { + case Endian::kEndianBig: { + if (pckt->IpcEndianess == kIPCLittleEndian) + goto ipc_check_failed; + + break; + } + case Endian::kEndianLittle: { + if (pckt->IpcEndianess == kIPCBigEndian) + goto ipc_check_failed; + + break; + } + case Endian::kEndianMixed: { + if (pckt->IpcEndianess == kIPCMixedEndian) + goto ipc_check_failed; + + break; + } + default: + goto ipc_check_failed; + } + + if (pckt->IpcFrom == pckt->IpcTo || + pckt->IpcPacketSize > kIPCMsgSize) + { + goto ipc_check_failed; + } + + return pckt->IpcPacketSize > 1 && pckt->IpcHeaderMagic == kIPCHeaderMagic; + +ipc_check_failed: + err_local_get() = kErrorIPC; + return false; +} + +namespace Kernel +{ + /// @brief Sanitize packet function + /// @retval true packet is correct. + /// @retval false packet is incorrect and process has crashed. + Bool ipc_sanitize_packet(IPCMessage* pckt) + { + if (!pckt || + !ipc_int_sanitize_packet(pckt)) + { + UserProcessScheduler::The().GetCurrentProcess().Leak().Crash(); + return false; + } + + return true; + } + + /// @brief Construct packet function + /// @retval true packet is correct. + /// @retval false packet is incorrect and process has crashed. + Bool ipc_construct_packet(_Output IPCMessage** pckt_in) + { + // don't do anything if it's valid already. + if (*pckt_in) + return true; + + // crash process if the packet pointer of pointer is NULL. + if (!pckt_in) + { + UserProcessScheduler::The().GetCurrentProcess().Leak().Crash(); + return false; + } + + *pckt_in = new IPCMessage(); + + if (*pckt_in) + { + auto endian = rtl_deduce_endianess((*pckt_in), ((Char*)(*pckt_in))[0]); + + (*pckt_in)->IpcHeaderMagic = kIPCHeaderMagic; + + (*pckt_in)->IpcEndianess = static_cast(endian); + (*pckt_in)->IpcPacketSize = sizeof(IPCMessage); + + (*pckt_in)->IpcTo.UserProcessID = 0; + (*pckt_in)->IpcTo.UserProcessTeam = 0; + + (*pckt_in)->IpcFrom.UserProcessID = Kernel::UserProcessScheduler::The().GetCurrentProcess().Leak().ProcessId; + (*pckt_in)->IpcFrom.UserProcessTeam = Kernel::UserProcessScheduler::The().CurrentTeam().mTeamId; + + return Yes; + } + + return No; + } +} // namespace Kernel diff --git a/dev/Kernel/src/Network/NetworkDevice.cc b/dev/Kernel/src/Network/NetworkDevice.cc new file mode 100644 index 00000000..49df121c --- /dev/null +++ b/dev/Kernel/src/Network/NetworkDevice.cc @@ -0,0 +1,35 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include + +namespace Kernel +{ + /// \brief Getter for fNetworkName. + const Char* NetworkDevice::Name() const + { + return this->fNetworkName; + } + + /// \brief Setter for fNetworkName. + Boolean NetworkDevice::Name(const Char* strView) + { + if (strView == nullptr) + return false; + + if (*strView == 0) + return false; + + if (rt_string_len(strView) > cNetworkNameLen) + return false; + + rt_copy_memory((VoidPtr)strView, + (VoidPtr)this->fNetworkName, rt_string_len(strView)); + + return true; + } +} // namespace Kernel diff --git a/dev/Kernel/src/New+Delete.cc b/dev/Kernel/src/New+Delete.cc new file mode 100644 index 00000000..d852f9dd --- /dev/null +++ b/dev/Kernel/src/New+Delete.cc @@ -0,0 +1,50 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include + +void* operator new[](size_t sz) +{ + if (sz == 0) + ++sz; + + return Kernel::mm_new_heap(sz, true, false); +} + +void* operator new(size_t sz) +{ + if (sz == 0) + ++sz; + + return Kernel::mm_new_heap(sz, true, false); +} + +void operator delete[](void* ptr) +{ + if (ptr == nullptr) + return; + + Kernel::mm_delete_heap(ptr); +} + +void operator delete(void* ptr) +{ + if (ptr == nullptr) + return; + + Kernel::mm_delete_heap(ptr); +} + +void operator delete(void* ptr, size_t sz) +{ + if (ptr == nullptr) + return; + + ZKA_UNUSED(sz); + + Kernel::mm_delete_heap(ptr); +} diff --git a/dev/Kernel/src/OwnPtr.cc b/dev/Kernel/src/OwnPtr.cc new file mode 100644 index 00000000..32fb5583 --- /dev/null +++ b/dev/Kernel/src/OwnPtr.cc @@ -0,0 +1,7 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include diff --git a/dev/Kernel/src/PEFCodeMgr.cc b/dev/Kernel/src/PEFCodeMgr.cc new file mode 100644 index 00000000..1d115f07 --- /dev/null +++ b/dev/Kernel/src/PEFCodeMgr.cc @@ -0,0 +1,284 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/// @brief PEF stack size symbol. +#define kPefStackSizeSymbol "SizeOfReserveStack" +#define kPefHeapSizeSymbol "SizeOfReserveHeap" +#define kPefNameSymbol "ProgramName" + +namespace Kernel +{ + namespace Detail + { + /***********************************************************************************/ + /// @brief Get the PEF platform signature according to the compiled architecture. + /***********************************************************************************/ + UInt32 ldr_get_platform(void) noexcept + { +#if defined(__ZKA_32X0__) + return kPefArch32x0; +#elif defined(__ZKA_64X0__) + return kPefArch64x0; +#elif defined(__ZKA_AMD64__) + return kPefArchAMD64; +#elif defined(__ZKA_PPC64__) + return kPefArchPowerPC; +#elif defined(__ZKA_ARM64__) + return kPefArchARM64; +#else + return kPefArchInvalid; +#endif // __32x0__ || __64x0__ || __x86_64__ + } + } // namespace Detail + + /***********************************************************************************/ + /// @brief PEF loader constructor w/ blob. + /// @param blob file blob. + /***********************************************************************************/ + PEFLoader::PEFLoader(const VoidPtr blob) + : fCachedBlob(blob) + { + MUST_PASS(fCachedBlob); + fBad = false; + } + + /***********************************************************************************/ + /// @brief PEF loader constructor. + /// @param path the filesystem path. + /***********************************************************************************/ + PEFLoader::PEFLoader(const Char* path) + : fCachedBlob(nullptr), fBad(false), fFatBinary(false) + { + fFile.New(const_cast(path), kRestrictRB); + fPath = StringBuilder::Construct(path).Leak(); + + auto kPefHeader = "PEF_CONTAINER"; + + fCachedBlob = fFile->Read(kPefHeader); + + PEFContainer* container = reinterpret_cast(fCachedBlob); + + if (container->Cpu == Detail::ldr_get_platform() && + container->Magic[0] == kPefMagic[0] && + container->Magic[1] == kPefMagic[1] && + container->Magic[2] == kPefMagic[2] && + container->Magic[3] == kPefMagic[3] && + container->Magic[4] == kPefMagic[4] && container->Abi == kPefAbi) + { + return; + } + else if (container->Magic[4] == kPefMagic[0] && + container->Magic[3] == kPefMagic[1] && + container->Magic[2] == kPefMagic[2] && + container->Magic[1] == kPefMagic[3] && + container->Magic[0] == kPefMagic[4] && container->Abi == kPefAbi) + { + /// This is a fat binary. + this->fFatBinary = true; + return; + } + + fBad = true; + + if (fCachedBlob) + mm_delete_heap(fCachedBlob); + + kcout << "PEFLoader: warn: Executable format error!\r"; + + fCachedBlob = nullptr; + } + + /***********************************************************************************/ + /// @brief PEF destructor. + /***********************************************************************************/ + PEFLoader::~PEFLoader() + { + if (fCachedBlob) + mm_delete_heap(fCachedBlob); + + fFile.Delete(); + } + + /***********************************************************************************/ + /// @brief Finds the symbol according to it's name. + /// @param name name of symbol. + /// @param kind kind of symbol we want. + /***********************************************************************************/ + VoidPtr PEFLoader::FindSymbol(const Char* name, Int32 kind) + { + if (!fCachedBlob || fBad || !name) + return nullptr; + + PEFContainer* container = reinterpret_cast(fCachedBlob); + + auto blob = fFile->Read(name); + + PEFCommandHeader* container_header = reinterpret_cast(blob); + + constexpr auto cMangleCharacter = '$'; + const Char* cContainerKinds[] = {".code64", ".data64", ".zero64", nullptr}; + + ErrorOr error_or_symbol; + + switch (kind) + { + case kPefCode: { + error_or_symbol = StringBuilder::Construct(cContainerKinds[0]); // code symbol. + break; + } + case kPefData: { + error_or_symbol = StringBuilder::Construct(cContainerKinds[1]); // data symbol. + break; + } + case kPefZero: { + error_or_symbol = StringBuilder::Construct(cContainerKinds[2]); // block starting symbol. + break; + } + default: + return nullptr; // prevent that from the kernel's mode perspective, let that happen if it were + // a user process. + } + + Char* unconst_symbol = const_cast(name); + + for (SizeT i = 0UL; i < rt_string_len(unconst_symbol, kPefNameLen); ++i) + { + if (unconst_symbol[i] == ' ') + { + unconst_symbol[i] = cMangleCharacter; + } + } + + error_or_symbol.Leak().Leak() += name; + + for (SizeT index = 0; index < container->Count; ++index) + { + if (StringBuilder::Equals(container_header->Name, + error_or_symbol.Leak().Leak().CData())) + { + if (container_header->Kind == kind) + { + if (container_header->Cpu != Detail::ldr_get_platform()) + { + if (!this->fFatBinary) + { + mm_delete_heap(blob); + return nullptr; + } + } + + Char* container_blob_value = new Char[container_header->Size]; + + rt_copy_memory((VoidPtr)((Char*)blob + sizeof(PEFCommandHeader)), container_blob_value, container_header->Size); + mm_delete_heap(blob); + + kcout << "PEFLoader: INFO: Load stub: " << container_header->Name << "!\r"; + + return container_blob_value; + } + } + } + + mm_delete_heap(blob); + return nullptr; + } + + /// @brief Finds the executable entrypoint. + /// @return + ErrorOr PEFLoader::FindStart() + { + if (auto sym = this->FindSymbol(kPefStart, kPefCode); sym) + return ErrorOr(sym); + + return ErrorOr(kErrorExecutable); + } + + /// @brief Tells if the executable is loaded or not. + /// @return + bool PEFLoader::IsLoaded() noexcept + { + return !fBad && fCachedBlob; + } + + const Char* PEFLoader::Path() + { + return fPath.Leak().CData(); + } + + const Char* PEFLoader::AsString() + { +#ifdef __32x0__ + return "32x0 PEF executable."; +#elif defined(__64x0__) + return "64x0 PEF executable."; +#elif defined(__x86_64__) + return "x86_64 PEF executable."; +#elif defined(__aarch64__) + return "AARCH64 PEF executable."; +#elif defined(__powerpc64__) + return "POWER64 PEF executable."; +#else + return "???? PEF executable."; +#endif // __32x0__ || __64x0__ || __x86_64__ || __powerpc64__ + } + + const Char* PEFLoader::MIME() + { + return kPefApplicationMime; + } + + ErrorOr PEFLoader::GetBlob() + { + return ErrorOr{this->fCachedBlob}; + } + + namespace Utils + { + ProcessID rtl_create_process(PEFLoader& exec, const Int32& procKind) noexcept + { + auto errOrStart = exec.FindStart(); + + if (errOrStart.Error() != kErrorSuccess) + return kProcessInvalidID; + + UserProcess* proc = new UserProcess(); + + proc->Kind = procKind; + proc->Image.fCode = errOrStart.Leak().Leak(); + proc->Image.fBlob = exec.GetBlob().Leak().Leak(); + proc->StackSize = *(UIntPtr*)exec.FindSymbol(kPefStackSizeSymbol, kPefData); + proc->MemoryLimit = *(UIntPtr*)exec.FindSymbol(kPefHeapSizeSymbol, kPefData); + proc->PTime = 0UL; + + rt_set_memory(proc->Name, 0, kProcessNameLen); + + if (exec.FindSymbol(kPefNameSymbol, kPefData)) + rt_copy_memory(exec.FindSymbol(kPefNameSymbol, kPefData), proc->Name, rt_string_len((Char*)exec.FindSymbol(kPefNameSymbol, kPefData))); + + if (!proc->StackSize) + { + const auto kDefaultStackSizeMib = 8; + proc->StackSize = mib_cast(kDefaultStackSizeMib); + } + + auto id = UserProcessScheduler::The().Spawn(proc); + + if (id == kProcessInvalidID) + delete proc; + + return id; + } + } // namespace Utils +} // namespace Kernel diff --git a/dev/Kernel/src/PRDT.cc b/dev/Kernel/src/PRDT.cc new file mode 100644 index 00000000..2bec9b1e --- /dev/null +++ b/dev/Kernel/src/PRDT.cc @@ -0,0 +1,24 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include +#include + +namespace Kernel +{ + /***********************************************************************************/ + /// @brief constructs a new PRD. + /// @param prd PRD reference. + /// @note This doesnt construct a valid, please fill it by yourself. + /***********************************************************************************/ + void construct_prdt(Ref& prd) + { + prd.Leak().fPhysAddress = 0x0; + prd.Leak().fSectorCount = 0x0; + prd.Leak().fEndBit = 0x0; + } +} // namespace Kernel diff --git a/dev/Kernel/src/PageMgr.cc b/dev/Kernel/src/PageMgr.cc new file mode 100644 index 00000000..4598be78 --- /dev/null +++ b/dev/Kernel/src/PageMgr.cc @@ -0,0 +1,110 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include + +#ifdef __ZKA_AMD64__ +#include +#elif defined(__ZKA_ARM64__) +#include +#endif // ifdef __ZKA_AMD64__ || defined(__ZKA_ARM64__) + +namespace Kernel +{ + PTEWrapper::PTEWrapper(Boolean Rw, Boolean User, Boolean ExecDisable, UIntPtr VirtAddr) + : fRw(Rw), + fUser(User), + fExecDisable(ExecDisable), + fVirtAddr(VirtAddr), + fCache(false), + fShareable(false), + fWt(false), + fPresent(true), + fAccessed(false) + { + } + + PTEWrapper::~PTEWrapper() = default; + + /// @brief Flush virtual address. + /// @param VirtAddr + Void PageMgr::FlushTLB() + { +#ifndef __ZKA_MINIMAL_OS__ + hal_flush_tlb(); +#endif // !__ZKA_MINIMAL_OS__ + } + + /// @brief Reclaim freed page. + /// @return + Bool PTEWrapper::Reclaim() + { + if (!this->fPresent) + { + this->fPresent = true; + return true; + } + + return false; + } + + /// @brief Request a PTE. + /// @param Rw r/w? + /// @param User user mode? + /// @param ExecDisable disable execution on page? + /// @return + PTEWrapper PageMgr::Request(Boolean Rw, Boolean User, Boolean ExecDisable, SizeT Sz) + { + // Store PTE wrapper right after PTE. + VoidPtr ptr = Kernel::HAL::mm_alloc_bitmap(Rw, User, Sz, false); + + return PTEWrapper{Rw, User, ExecDisable, reinterpret_cast(ptr)}; + } + + /// @brief Disable BitMap. + /// @param wrapper the wrapper. + /// @return If the page bitmap was cleared or not. + Bool PageMgr::Free(Ref& wrapper) + { + if (!Kernel::HAL::mm_free_bitmap((VoidPtr)wrapper.Leak().VirtualAddress())) + return false; + + return true; + } + + /// @brief Virtual PTE address. + /// @return The virtual address of the page. + const UIntPtr PTEWrapper::VirtualAddress() + { + return (fVirtAddr); + } + + Bool PTEWrapper::Shareable() + { + return fShareable; + } + + Bool PTEWrapper::Present() + { + return fPresent; + } + + Bool PTEWrapper::Access() + { + return fAccessed; + } + + Void PTEWrapper::NoExecute(const bool enable) + { + fExecDisable = enable; + } + + Bool PTEWrapper::NoExecute() + { + return fExecDisable; + } +} // namespace Kernel diff --git a/dev/Kernel/src/Pmm.cc b/dev/Kernel/src/Pmm.cc new file mode 100644 index 00000000..f83e6d6e --- /dev/null +++ b/dev/Kernel/src/Pmm.cc @@ -0,0 +1,98 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include + +#if defined(__ZKA_ARM64__) +#include +#endif // defined(__ZKA_ARM64__) + +#if defined(__ZKA_AMD64__) +#include +#endif // defined(__ZKA_AMD64__) + +namespace Kernel +{ + /***********************************************************************************/ + /// @brief Pmm constructor. + /***********************************************************************************/ + Pmm::Pmm() + : fPageMgr() + { + kcout << "[PMM] Allocate PageMemoryMgr"; + } + + Pmm::~Pmm() = default; + + /***********************************************************************************/ + /// @param If this returns Null pointer, enter emergency mode. + /// @param user is this a user page? + /// @param readWrite is it r/w? + /***********************************************************************************/ + Ref Pmm::RequestPage(Boolean user, Boolean readWrite) + { + PTEWrapper pt = fPageMgr.Leak().Request(user, readWrite, false, kPageSize); + + if (pt.fPresent) + { + kcout << "[PMM]: Allocation failed.\r"; + return {}; + } + + return Ref(pt); + } + + Boolean Pmm::FreePage(Ref PageRef) + { + if (!PageRef) + return false; + + PageRef.Leak().fPresent = false; + + return true; + } + + Boolean Pmm::TogglePresent(Ref PageRef, Boolean Enable) + { + if (!PageRef) + return false; + + PageRef.Leak().fPresent = Enable; + + return true; + } + + Boolean Pmm::ToggleUser(Ref PageRef, Boolean Enable) + { + if (!PageRef) + return false; + + PageRef.Leak().fRw = Enable; + + return true; + } + + Boolean Pmm::ToggleRw(Ref PageRef, Boolean Enable) + { + if (!PageRef) + return false; + + PageRef.Leak().fRw = Enable; + + return true; + } + + Boolean Pmm::ToggleShare(Ref PageRef, Boolean Enable) + { + if (!PageRef) + return false; + + PageRef.Leak().fShareable = Enable; + + return true; + } +} // namespace Kernel diff --git a/dev/Kernel/src/Property.cc b/dev/Kernel/src/Property.cc new file mode 100644 index 00000000..afbe9578 --- /dev/null +++ b/dev/Kernel/src/Property.cc @@ -0,0 +1,45 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include + +namespace CFKit +{ + /***********************************************************************************/ + /// @brief Destructor. + /***********************************************************************************/ + Property::~Property() = default; + + /***********************************************************************************/ + /// @brief Constructor. + /***********************************************************************************/ + Property::Property() = default; + + /***********************************************************************************/ + /// @brief Check if property's name equals to name. + /// @param name string to check. + /***********************************************************************************/ + Bool Property::StringEquals(KString& name) + { + return this->fName && this->fName == name; + } + + /***********************************************************************************/ + /// @brief Gets the key (name) of property. + /***********************************************************************************/ + KString& Property::GetKey() + { + return this->fName; + } + + /***********************************************************************************/ + /// @brief Gets the value of the property. + /***********************************************************************************/ + PropertyId& Property::GetValue() + { + return fValue; + } +} // namespace CFKit diff --git a/dev/Kernel/src/Ref.cc b/dev/Kernel/src/Ref.cc new file mode 100644 index 00000000..df9a2999 --- /dev/null +++ b/dev/Kernel/src/Ref.cc @@ -0,0 +1,7 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include diff --git a/dev/Kernel/src/Semaphore.cc b/dev/Kernel/src/Semaphore.cc new file mode 100644 index 00000000..804feaa8 --- /dev/null +++ b/dev/Kernel/src/Semaphore.cc @@ -0,0 +1,72 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include + +namespace Kernel +{ + /***********************************************************************************/ + /// @brief Unlocks process out of the semaphore. + /***********************************************************************************/ + Bool Semaphore::Unlock() noexcept + { + if (fLockingProcess) + fLockingProcess = nullptr; + else + return No; + + return Yes; + } + + /***********************************************************************************/ + /// @brief Locks process in the semaphore. + /***********************************************************************************/ + Bool Semaphore::Lock(UserProcess* process) + { + if (!process || fLockingProcess) + return No; + + fLockingProcess = process; + + return Yes; + } + + /***********************************************************************************/ + /// @brief Checks if process is locked. + /***********************************************************************************/ + Bool Semaphore::IsLocked() const + { + return fLockingProcess; + } + + /***********************************************************************************/ + /// @brief Try lock or wait. + /***********************************************************************************/ + Bool Semaphore::LockOrWait(UserProcess* process, TimerInterface* timer) + { + if (process == nullptr) + return No; + + if (timer == nullptr) + return No; + + this->Lock(process); + + timer->Wait(); + + return this->Lock(process); + } + + /***********************************************************************************/ + /// @brief Wait for process to be free. + /***********************************************************************************/ + Void Semaphore::WaitForProcess() noexcept + { + while (fLockingProcess) + ; + } +} // namespace Kernel diff --git a/dev/Kernel/src/Stop.cc b/dev/Kernel/src/Stop.cc new file mode 100644 index 00000000..01820208 --- /dev/null +++ b/dev/Kernel/src/Stop.cc @@ -0,0 +1,130 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define kWebsiteURL "https://el-mahrouss-logic.com/products/help/" + +/* Each error code is attributed with an ID, which will prompt a string onto the + * screen. Wait for debugger... */ + +namespace Kernel +{ + /***********************************************************************************/ + /// @brief Stops execution of the kernel. + /// @param id kernel stop ID. + /***********************************************************************************/ + Void ke_stop(const Kernel::Int32& id) + { + cg_init(); + + auto panic_text = RGB(0xff, 0xff, 0xff); + + auto start_y = 50; + auto x = 10; + + if (id != RUNTIME_CHECK_BOOTSTRAP) + CGDrawString("Kernel Panic!", start_y, x, panic_text); + else + CGDrawString("Kernel Bootstrap:", start_y, x, panic_text); + + start_y += 10; + + cg_fini(); + + // show text according to error id. + + switch (id) + { + case RUNTIME_CHECK_PROCESS: { + CGDrawString("0x00000008: Invalid process behavior.", start_y, x, panic_text); + break; + } + case RUNTIME_CHECK_ACPI: { + CGDrawString("0x00000006: ACPI configuration error.", start_y, x, panic_text); + break; + } + case RUNTIME_CHECK_PAGE: { + CGDrawString("0x0000000B: Write/Read in non paged area.", start_y, x, panic_text); + break; + } + case RUNTIME_CHECK_FILESYSTEM: { + CGDrawString("0x0000000A: Filesystem driver error.", start_y, x, panic_text); + break; + } + case RUNTIME_CHECK_POINTER: { + CGDrawString("0x00000000: Kernel heap is corrupted.", start_y, x, panic_text); + break; + } + case RUNTIME_CHECK_BAD_BEHAVIOR: { + CGDrawString("0x00000009: Bad behavior.", start_y, x, panic_text); + break; + } + case RUNTIME_CHECK_BOOTSTRAP: { + CGDrawString("0x0000000A: Kernel has finished running, running OSLdr...", start_y, x, panic_text); + return; + } + case RUNTIME_CHECK_HANDSHAKE: { + CGDrawString("0x00000005: Handshake fault.", start_y, x, panic_text); + break; + } + case RUNTIME_CHECK_IPC: { + CGDrawString("0x00000003: Bad LPC message.", start_y, x, panic_text); + break; + } + case RUNTIME_CHECK_INVALID_PRIVILEGE: { + CGDrawString("0x00000007: Privilege access violation.", start_y, x, panic_text); + break; + case RUNTIME_CHECK_UNEXCPECTED: { + CGDrawString("0x0000000B: Unexpected violation.", start_y, x, panic_text); + break; + } + case RUNTIME_CHECK_VIRTUAL_OUT_OF_MEM: { + CGDrawString("0x10000001: Out of virtual memory.", start_y, x, panic_text); + + break; + } + case RUNTIME_CHECK_FAILED: { + CGDrawString("0x10000001: Kernel Bug check appears to have failed, a dump has been written to the storage.", start_y, x, panic_text); + break; + } + default: { + CGDrawString("0xFFFFFFFC: Unknown Kernel Error code.", start_y, x, panic_text); + break; + } + } + }; + + RecoveryFactory::Recover(); + } + + Void RecoveryFactory::Recover() noexcept + { + while (YES) + { + HAL::rt_halt(); + } + } + + void ke_runtime_check(bool expr, const Char* file, const Char* line) + { + if (!expr) + { + kcout << "FAILED: FILE: " << file << endl; + kcout << "FAILED: LINE: " << line << endl; + + ke_stop(RUNTIME_CHECK_FAILED); // Runtime Check failed + } + } +} // namespace Kernel diff --git a/dev/Kernel/src/Storage/AHCIDeviceInterface.cc b/dev/Kernel/src/Storage/AHCIDeviceInterface.cc new file mode 100644 index 00000000..6d3f933e --- /dev/null +++ b/dev/Kernel/src/Storage/AHCIDeviceInterface.cc @@ -0,0 +1,35 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include + +using namespace Kernel; + +/// @brief Class constructor +/// @param Out Drive output +/// @param In Drive input +/// @param Cleanup Drive cleanup. +AHCIDeviceInterface::AHCIDeviceInterface(void (*Out)(MountpointInterface* outpacket), + void (*In)(MountpointInterface* inpacket), + void (*Cleanup)(void)) + : IDeviceObject(Out, In), fCleanup(Cleanup) +{ +} + +/// @brief Class desctructor +AHCIDeviceInterface::~AHCIDeviceInterface() +{ + MUST_PASS(fCleanup); + if (fCleanup) + fCleanup(); +} + +/// @brief Returns the name of the device interface. +/// @return it's name as a string. +const Char* AHCIDeviceInterface::Name() const +{ + return "AHCIDeviceInterface"; +} diff --git a/dev/Kernel/src/Storage/ATADeviceInterface.cc b/dev/Kernel/src/Storage/ATADeviceInterface.cc new file mode 100644 index 00000000..c9184909 --- /dev/null +++ b/dev/Kernel/src/Storage/ATADeviceInterface.cc @@ -0,0 +1,88 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include + +using namespace Kernel; + +/// @brief Class constructor +/// @param Out Drive output +/// @param In Drive input +/// @param Cleanup Drive cleanup. +ATADeviceInterface::ATADeviceInterface( + void (*Out)(MountpointInterface* outpacket), + void (*In)(MountpointInterface* inpacket), + void (*Cleanup)(void)) + : IDeviceObject(Out, In), fCleanup(Cleanup) +{ +} + +/// @brief Class desctructor +ATADeviceInterface::~ATADeviceInterface() +{ + MUST_PASS(fCleanup); + if (fCleanup) + fCleanup(); +} + +/// @brief Returns the name of the device interface. +/// @return it's name as a string. +const Char* ATADeviceInterface::Name() const +{ + return "ATADeviceInterface"; +} + +/// @brief Output operator. +/// @param Data +/// @return +ATADeviceInterface& ATADeviceInterface::operator<<(MountpointInterface* Data) +{ + if (!Data) + return *this; + + for (SizeT driveCount = 0; driveCount < kDriveMaxCount; ++driveCount) + { + auto interface = Data->GetAddressOf(driveCount); + if ((interface) && rt_string_cmp((interface)->fDriveKind(), "ATA-", 5) == 0) + { + continue; + } + else if ((interface) && + rt_string_cmp((interface)->fDriveKind(), "ATA-", 5) != 0) + { + return *this; + } + } + + return (ATADeviceInterface&)IDeviceObject::operator<<( + Data); +} + +/// @brief Input operator. +/// @param Data +/// @return +ATADeviceInterface& ATADeviceInterface::operator>>(MountpointInterface* Data) +{ + if (!Data) + return *this; + + for (SizeT driveCount = 0; driveCount < kDriveMaxCount; ++driveCount) + { + auto interface = Data->GetAddressOf(driveCount); + if ((interface) && rt_string_cmp((interface)->fDriveKind(), "ATA-", 5) == 0) + { + continue; + } + else if ((interface) && + rt_string_cmp((interface)->fDriveKind(), "ATA-", 5) != 0) + { + return *this; + } + } + + return (ATADeviceInterface&)IDeviceObject::operator>>( + Data); +} diff --git a/dev/Kernel/src/Storage/NVMEDeviceInterface.cc b/dev/Kernel/src/Storage/NVMEDeviceInterface.cc new file mode 100644 index 00000000..48849ad0 --- /dev/null +++ b/dev/Kernel/src/Storage/NVMEDeviceInterface.cc @@ -0,0 +1,28 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include + +namespace Kernel +{ + NVMEDeviceInterface::NVMEDeviceInterface(void (*out)(MountpointInterface* outpacket), + void (*in)(MountpointInterface* inpacket), + void (*cleanup)(void)) + : IDeviceObject(out, in), fCleanup(cleanup) + { + } + + NVMEDeviceInterface::~NVMEDeviceInterface() + { + if (fCleanup) + fCleanup(); + } + + const Char* NVMEDeviceInterface::Name() const + { + return ("NVMEDeviceInterface"); + } +} // namespace Kernel diff --git a/dev/Kernel/src/Storage/SCSIDeviceInterface.cc b/dev/Kernel/src/Storage/SCSIDeviceInterface.cc new file mode 100644 index 00000000..7704fc6b --- /dev/null +++ b/dev/Kernel/src/Storage/SCSIDeviceInterface.cc @@ -0,0 +1,11 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include + +///! @brief ATAPI SCSI packet. +const scsi_packet_type<12> kCDRomPacketTemplate = {0x43, 0, 1, 0, 0, 0, + 0, 12, 0x40, 0, 0}; diff --git a/dev/Kernel/src/Stream.cc b/dev/Kernel/src/Stream.cc new file mode 100644 index 00000000..c719e91f --- /dev/null +++ b/dev/Kernel/src/Stream.cc @@ -0,0 +1,12 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + + File: Stream.cc + Purpose: Stream object + + Revision History: + +------------------------------------------- */ + +#include diff --git a/dev/Kernel/src/ThreadLocalStorage.cc b/dev/Kernel/src/ThreadLocalStorage.cc new file mode 100644 index 00000000..e765f6a0 --- /dev/null +++ b/dev/Kernel/src/ThreadLocalStorage.cc @@ -0,0 +1,67 @@ +/* + * ======================================================== + * + * minoskrnl + * Copyright (C) 2024, TQ B.V, all rights reserved., all rights reserved. + * + * ======================================================== + */ + +#include +#include +#include +#include + +/***********************************************************************************/ +/// @bugs: 0 +/// @file ThreadLocalStorage.cc +/// @brief Process Thread Local Storage. +/***********************************************************************************/ + +using namespace Kernel; + +/** + * @brief Checks for cookie inside the TIB. + * @param tib_ptr the TIB to check. + * @return if the cookie is enabled, true; false otherwise + */ + +Boolean tls_check_tib(THREAD_INFORMATION_BLOCK* tib_ptr) +{ + if (!tib_ptr || + !tib_ptr->Record) + return false; + + ICodec encoder; + const Char* tib_as_bytes = encoder.AsBytes(tib_ptr); + + kcout << "TLS: Validating the TIB...\r"; + + return tib_as_bytes[0] == kCookieMag0 && tib_as_bytes[1] == kCookieMag1 && + tib_as_bytes[2] == kCookieMag2; +} + +/** + * @brief System call implementation of the TLS check. + * @param tib_ptr The TIB record. + * @return + */ +EXTERN_C Bool tls_check_syscall_impl(Kernel::VoidPtr tib_ptr) noexcept +{ + if (!tib_ptr) + { + kcout << "TLS: Failing because of an invalid TIB...\r"; + return false; + } + + THREAD_INFORMATION_BLOCK* tib = (THREAD_INFORMATION_BLOCK*)tib_ptr; + + if (!tls_check_tib(tib)) + { + kcout << "TLS: Failing because of an invalid TIB...\r"; + return false; + } + + kcout << "TLS Check pass.\r"; + return true; +} diff --git a/dev/Kernel/src/Timer.cc b/dev/Kernel/src/Timer.cc new file mode 100644 index 00000000..656efb55 --- /dev/null +++ b/dev/Kernel/src/Timer.cc @@ -0,0 +1,47 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include + +///! BUGS: 0 +///! @file Timer.cc +///! @brief Software Timer implementation + +using namespace Kernel; + +/// @brief Unimplemented as it is an interface. +Int32 TimerInterface::Wait() noexcept +{ + return kErrorUnimplemented; +} + +/// @brief SoftwareTimer class, meant to be generic. + +SoftwareTimer::SoftwareTimer(Int64 seconds) + : fWaitFor(seconds) +{ + fDigitalTimer = new IntPtr(); + MUST_PASS(fDigitalTimer); +} + +SoftwareTimer::~SoftwareTimer() +{ + delete fDigitalTimer; + fWaitFor = 0; +} + +Int32 SoftwareTimer::Wait() noexcept +{ + if (fWaitFor < 1) + return 1; + + while (*fDigitalTimer < (*fDigitalTimer + fWaitFor)) + { + ++(*fDigitalTimer); + } + + return 0; +} diff --git a/dev/Kernel/src/User.cc b/dev/Kernel/src/User.cc new file mode 100644 index 00000000..601eee15 --- /dev/null +++ b/dev/Kernel/src/User.cc @@ -0,0 +1,178 @@ +/* + * ======================================================== + * + * ZKA + * Copyright (C) 2024, TQ B.V, all rights reserved., all rights reserved. + * + * File: User.cc + * Purpose: User class, used to provide authentication and security. + * + * ======================================================== + */ + +#include +#include +#include +#include +#include +#include + +#define kStdUserType (0xCE) +#define kSuperUserType (0xEC) + +/// @file User.cc +/// @brief User support (or also called ) + +namespace Kernel +{ + namespace Detail + { + /// \brief Constructs a password by hashing the password. + /// \param password password to hash. + /// \return the hashed password + const Int32 cred_construct_token(Char* password, const Char* in_password, User* user, SizeT length) + { + if (!password || !user) + return 1; + + kcout << "cred_construct_token: Hashing user password...\r"; + + for (Size i_pass = 0; i_pass < length; ++i_pass) + { + const Char& cur_chr = in_password[i_pass]; + + if (cur_chr == 0) + break; + + password[i_pass] = cur_chr | (user->IsStdUser() ? kStdUserType : kSuperUserType); + } + + kcout << "cred_construct_token: Hashed user password.\r"; + + return 0; + } + } // namespace Detail + + /// @brief User ring constructor. + User::User(const Int32& sel, const Char* userName) + : mUserRing((UserRingKind)sel) + { + MUST_PASS(sel >= 0); + rt_copy_memory((VoidPtr)userName, this->mUserName, rt_string_len(userName)); + } + + /// @brief User ring constructor. + User::User(const UserRingKind& ringKind, const Char* userName) + : mUserRing(ringKind) + { + rt_copy_memory((VoidPtr)userName, this->mUserName, rt_string_len(userName)); + } + + /// @brief User destructor class. + User::~User() = default; + + Bool User::Save(const usr_public_key_kind password_to_fill) noexcept + { + if (!password_to_fill || + *password_to_fill == 0) + return No; + + SizeT len = rt_string_len(password_to_fill); + + Char* password = new Char[len]; + MUST_PASS(password); + + // fill data first, generate hash. + // return false on error. + + rt_copy_memory((VoidPtr)password_to_fill, password, len); + + if (!Detail::cred_construct_token(password, password_to_fill, this, len)) + { + delete[] password; + password = nullptr; + + return No; + } + + // then store password. + + rt_copy_memory(password, this->mUserToken, rt_string_len(password_to_fill)); + + delete[] password; + password = nullptr; + + kcout << "User::Save: Saved password successfully...\r"; + + return Yes; + } + + Bool User::Matches(const usr_public_key_kind password_to_fill) noexcept + { + if (!password_to_fill || + *password_to_fill) + return No; + + SizeT len = rt_string_len(password_to_fill); + + Char* password = new Char[len]; + MUST_PASS(password); + + // fill data first, generate hash. + // return false on error. + + rt_copy_memory((VoidPtr)password_to_fill, password, len); + + if (!Detail::cred_construct_token(password, password_to_fill, this, len)) + { + delete[] password; + password = nullptr; + + return No; + } + + kcout << "User::Matches: Validating hashed passwords...\r"; + + // now check if the password matches. + if (rt_string_cmp(password, this->mUserToken, rt_string_len(this->mUserToken)) == 0) + { + kcout << "User::Matches: Password is valid.\r"; + return Yes; + } + + kcout << "User::Matches: Password isn't valid.\r"; + return No; + } + + Bool User::operator==(const User& lhs) + { + return lhs.mUserRing == this->mUserRing; + } + + Bool User::operator!=(const User& lhs) + { + return lhs.mUserRing != this->mUserRing; + } + + Char* User::Name() noexcept + { + return this->mUserName; + } + + /// @brief Returns the user's ring. + /// @return The king of ring the user is attached to. + const UserRingKind& User::Ring() noexcept + { + return this->mUserRing; + } + + Bool User::IsStdUser() noexcept + { + return this->Ring() == UserRingKind::kRingStdUser; + } + + Bool User::IsSuperUser() noexcept + { + return this->Ring() == UserRingKind::kRingSuperUser; + } +} // namespace Kernel diff --git a/dev/Kernel/src/UserProcessScheduler.cc b/dev/Kernel/src/UserProcessScheduler.cc new file mode 100644 index 00000000..56703e7c --- /dev/null +++ b/dev/Kernel/src/UserProcessScheduler.cc @@ -0,0 +1,582 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + + FILE: UserProcessScheduler.cc + PURPOSE: EL0/Ring-3 Process scheduler. + +------------------------------------------- */ + +/***********************************************************************************/ +/// @file UserProcessScheduler.cc +/// @brief EL0/Ring-3 process scheduler. +/***********************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +///! BUGS: 0 + +/***********************************************************************************/ +/** TODO: Document the Kernel, SDK and kits. */ +/***********************************************************************************/ + +namespace Kernel +{ + /***********************************************************************************/ + /// @brief Exit Code global variable. + /***********************************************************************************/ + + STATIC UInt32 kLastExitCode = 0U; + + /***********************************************************************************/ + /// @brief User Process scheduler global and external reference of thread scheduler. + /***********************************************************************************/ + + STATIC UserProcessScheduler kProcessScheduler; + + UserProcess::UserProcess() = default; + UserProcess::~UserProcess() = default; + + /// @brief Gets the last exit code. + /// @note Not thread-safe. + /// @return Int32 the last exit code. + const UInt32& sched_get_exit_code(void) noexcept + { + return kLastExitCode; + } + + /***********************************************************************************/ + /// @brief Crashes the current process-> + /***********************************************************************************/ + + Void UserProcess::Crash() + { + if (this->Status != ProcessStatusKind::kRunning) + return; + + kcout << this->Name << ": crashed, error id: " << number(kErrorProcessFault) << endl; + this->Exit(kErrorProcessFault); + } + + /***********************************************************************************/ + //! @brief boolean operator, check status. + /***********************************************************************************/ + + UserProcess::operator bool() + { + return this->Status == ProcessStatusKind::kRunning; + } + + /***********************************************************************************/ + /// @brief Gets the local last exit code. + /// @note Not thread-safe. + /// @return Int32 the last exit code. + /***********************************************************************************/ + + const UInt32& UserProcess::GetExitCode() noexcept + { + return this->fLastExitCode; + } + + /***********************************************************************************/ + /// @brief Error code variable getter. + /***********************************************************************************/ + + Int32& UserProcess::GetLocalCode() noexcept + { + return this->fLocalCode; + } + + /***********************************************************************************/ + /// @brief Wake process-> + /***********************************************************************************/ + + Void UserProcess::Wake(const bool should_wakeup) + { + this->Status = + should_wakeup ? ProcessStatusKind::kRunning : ProcessStatusKind::kFrozen; + } + + /***********************************************************************************/ + /** @brief Add pointer to entry. */ + /***********************************************************************************/ + + ErrorOr UserProcess::New(const SizeT& sz, const SizeT& pad_amount) + { +#ifdef __ZKA_AMD64__ + auto vm_register = hal_read_cr3(); + hal_write_cr3(this->VMRegister); + + auto ptr = mm_new_heap(sz + pad_amount, Yes, Yes); + + hal_write_cr3(vm_register); +#else + auto ptr = mm_new_heap(sz + pad_amount, Yes, Yes); +#endif + + if (!this->ProcessMemoryHeap) + { + this->ProcessMemoryHeap = new UserProcess::UserProcessHeapList(); + + this->ProcessMemoryHeap->MemoryEntryPad = pad_amount; + this->ProcessMemoryHeap->MemoryEntrySize = sz; + + this->ProcessMemoryHeap->MemoryEntry = ptr; + + this->ProcessMemoryHeap->MemoryPrev = nullptr; + this->ProcessMemoryHeap->MemoryNext = nullptr; + + return ErrorOr(ptr); + } + else + { + UserProcessHeapList* entry = this->ProcessMemoryHeap; + UserProcessHeapList* prev_entry = nullptr; + + while (!entry) + { + if (entry->MemoryEntry == nullptr) + break; // chose to break here, when we get an already allocated memory entry for our needs. + + prev_entry = entry; + entry = entry->MemoryNext; + } + + entry->MemoryNext = new UserProcessHeapList(); + entry->MemoryNext->MemoryEntry = ptr; + + entry->MemoryNext->MemoryPrev = entry; + entry->MemoryNext->MemoryNext = nullptr; + } + + return ErrorOr(nullptr); + } + + /***********************************************************************************/ + /// @brief Gets the name of the current process-> + /***********************************************************************************/ + + const Char* UserProcess::GetName() noexcept + { + return this->Name; + } + + /***********************************************************************************/ + /// @brief Gets the owner of the process-> + /***********************************************************************************/ + + const User* UserProcess::GetOwner() noexcept + { + return this->Owner; + } + + /// @brief UserProcess status getter. + const ProcessStatusKind& UserProcess::GetStatus() noexcept + { + return this->Status; + } + + /***********************************************************************************/ + /** + @brief Affinity is the time slot allowed for the process-> + */ + /***********************************************************************************/ + + const AffinityKind& UserProcess::GetAffinity() noexcept + { + return this->Affinity; + } + + /***********************************************************************************/ + /** + @brief Exit process method. + @param exit_code The process's exit code. + */ + /***********************************************************************************/ + + Void UserProcess::Exit(const Int32& exit_code) + { + this->Status = exit_code > 0 ? ProcessStatusKind::kKilled : ProcessStatusKind::kFrozen; + this->fLastExitCode = exit_code; + + kLastExitCode = exit_code; + + auto memory_heap_list = this->ProcessMemoryHeap; + +#ifdef __ZKA_AMD64__ + auto pd = hal_read_cr3(); + hal_write_cr3(this->VMRegister); +#endif + + // Deleting memory lists. Make sure to free all of them. + while (memory_heap_list) + { + if (memory_heap_list->MemoryEntry) + { + MUST_PASS(mm_delete_heap(memory_heap_list->MemoryEntry)); + } + +#ifdef __ZKA_AMD64__ + hal_write_cr3(pd); +#endif + + auto next = memory_heap_list->MemoryNext; + + mm_delete_heap(memory_heap_list); + + memory_heap_list = nullptr; + memory_heap_list = next; + } + + //! Free the memory's page directory. + HAL::mm_free_bitmap(this->VMRegister); + + //! Delete image if not done already. + if (this->Image.fCode && mm_is_valid_heap(this->Image.fCode)) + mm_delete_heap(this->Image.fCode); + + if (this->Image.fBlob && mm_is_valid_heap(this->Image.fBlob)) + mm_delete_heap(this->Image.fBlob); + + if (this->StackFrame && mm_is_valid_heap(this->StackFrame)) + mm_delete_heap((VoidPtr)this->StackFrame); + + this->Image.fBlob = nullptr; + this->Image.fCode = nullptr; + this->StackFrame = nullptr; + + if (this->Kind == kExectuableDLLKind) + { + Bool success = false; + + rtl_fini_dylib(this, reinterpret_cast(this->DylibDelegate), &success); + + if (!success) + { + ke_stop(RUNTIME_CHECK_PROCESS); + } + + this->DylibDelegate = nullptr; + } + + if (this->StackReserve) + mm_delete_heap(reinterpret_cast(this->StackReserve)); + + this->ProcessId = 0; + this->Status = ProcessStatusKind::kFinished; + + --this->ProcessParentTeam->mProcessCount; + + delete this; + } + + /***********************************************************************************/ + /// @brief Add process to team. + /// @param process the process *Ref* class. + /// @return the process index inside the team. + /***********************************************************************************/ + + ProcessID UserProcessScheduler::Spawn(UserProcess* process) + { + if (!process) + { + return kProcessInvalidID; + } + +#ifdef __ZKA_AMD64__ + process->VMRegister = mm_new_heap(sizeof(PDE), No, Yes); + + if (!process->VMRegister) + { + process->Crash(); + return -kErrorProcessFault; + } +#endif // __ZKA_AMD64__ + + kcout << "Create page directory for: " << process->Name << endl; + + process->StackFrame = reinterpret_cast(mm_new_heap(sizeof(HAL::StackFrame), Yes, Yes)); + + if (!process->StackFrame) + { + process->Crash(); + return -kErrorProcessFault; + } + + kcout << "Create stack for: " << process->Name << endl; + + // Create heap according to type of process-> + if (process->Kind == UserProcess::kExectuableDLLKind) + { + process->DylibDelegate = rtl_init_dylib(process); + MUST_PASS(process->DylibDelegate); + + kcout << "Created Library Interface for process: " << process->Name << endl; + } + + process->StackReserve = new UInt8[process->StackSize]; + + UInt32 flags = HAL::kMMFlagsPresent; + flags |= HAL::kMMFlagsWr; + flags |= HAL::kMMFlagsUser; + + HAL::mm_map_page((VoidPtr)process->StackReserve, flags); + + if (!process->StackReserve) + { + process->Crash(); + return -kErrorProcessFault; + } + + kcout << "Created Reserved Stack for process: " << process->Name << endl; + + ProcessID pid = mTeam.mProcessCount; + + if (pid > kSchedProcessLimitPerTeam) + return kProcessInvalidID; + + ++mTeam.mProcessCount; + + process->ProcessParentTeam = &mTeam; + + process->ProcessId = pid; + process->Status = ProcessStatusKind::kStarting; + process->PTime = (UIntPtr)AffinityKind::kStandard; + + kcout << "Process Name: " << process->Name << endl; + kcout << "PID: " << number(process->ProcessId) << endl; + + mTeam.mProcessList.Assign(pid, process); + + return process->ProcessId; + } + + /***********************************************************************************/ + /// @brief Retrieves the singleton of the process scheduler. + /***********************************************************************************/ + + UserProcessScheduler& UserProcessScheduler::The() + { + return kProcessScheduler; + } + + /***********************************************************************************/ + + /// @brief Remove process from list. + /// @param process_id process slot inside team. + /// @retval true process was removed. + /// @retval false process doesn't exist in team. + + /***********************************************************************************/ + + const Bool UserProcessScheduler::Remove(ProcessID process_id) + { + // check if process is within range. + if (process_id > mTeam.mProcessList.Count()) + return No; + + mTeam.mProcessList[process_id]->Exit(0); + + return Yes; + } + + const Bool UserProcessScheduler::IsUser() + { + return Yes; + } + + const Bool UserProcessScheduler::IsKernel() + { + return No; + } + + const Bool UserProcessScheduler::HasMP() + { + MUST_PASS(kHandoverHeader); + return kHandoverHeader->f_HardwareTables.f_MultiProcessingEnabled; + } + + /***********************************************************************************/ + + /// @brief Run User scheduler object. + /// @return Process count executed within a team. + + /***********************************************************************************/ + + const SizeT UserProcessScheduler::Run() noexcept + { + SizeT process_index = 0; //! we store this guy to tell the scheduler how many + //! things we have scheduled. + + if (mTeam.mProcessList.Empty()) + { + kcout << "UserProcessScheduler::Run(): This team doesn't have any process!\r"; + return 0; + } + + kcout << "UserProcessScheduler::Run(): This team has a process capacity of: " << number(mTeam.mProcessList.Capacity()) << endl; + + for (; process_index < mTeam.AsArray().Capacity(); ++process_index) + { + auto process = mTeam.AsArray()[process_index]; + + //! check if process needs to be scheduled. + if (process && UserProcessHelper::CanBeScheduled(process)) + { + // Set current process header. + this->GetCurrentProcess() = process; + + process->PTime = static_cast(process->Affinity); + + kcout << "Switch to '" << process->Name << "'.\r"; + + // tell helper to find a core to schedule on. + if (!UserProcessHelper::Switch(process->Image.fCode, &process->StackReserve[process->StackSize - 1], process->StackFrame, + process->ProcessId)) + { + process->Crash(); + } + } + else + { + --process->PTime; + } + } + + return process_index; + } + + /// @brief Gets the current scheduled team. + /// @return + UserProcessTeam& UserProcessScheduler::CurrentTeam() + { + return mTeam; + } + + /// @internal + + /// @brief Gets current running process-> + /// @return + Ref& UserProcessScheduler::GetCurrentProcess() + { + return mTeam.AsRef(); + } + + /// @brief Current proccess id getter. + /// @return UserProcess ID integer. + ErrorOr UserProcessHelper::TheCurrentPID() + { + if (!kProcessScheduler.GetCurrentProcess()) + return ErrorOr{kErrorProcessFault}; + + kcout << "UserProcessHelper::TheCurrentPID: Leaking ProcessId...\r"; + return ErrorOr{kProcessScheduler.GetCurrentProcess().Leak().ProcessId}; + } + + /// @brief Check if process can be schedulded. + /// @param process the process reference. + /// @retval true can be schedulded. + /// @retval false cannot be schedulded. + Bool UserProcessHelper::CanBeScheduled(const UserProcess* process) + { + if (process->Status == ProcessStatusKind::kKilled || + process->Status == ProcessStatusKind::kFinished || + process->Status == ProcessStatusKind::kFrozen) + return No; + + if (process->Status == ProcessStatusKind::kInvalid) + return No; + + if (!process->Image.fCode) + return No; + + if (!process->Name[0]) + return No; + + return process->PTime < 1; + } + + /***********************************************************************************/ + /** + * @brief Start scheduling current AP. + */ + /***********************************************************************************/ + SizeT UserProcessHelper::StartScheduling() + { + return kProcessScheduler.Run(); + } + + /***********************************************************************************/ + /** + * \brief Does a context switch in a CPU. + * \param the_stack the stackframe of the running app. + * \param new_pid the process's PID. + */ + /***********************************************************************************/ + + Bool UserProcessHelper::Switch(VoidPtr image_ptr, UInt8* stack, HAL::StackFramePtr frame_ptr, const PID& new_pid) + { + if (!stack || !frame_ptr || !image_ptr || new_pid < 0) + return No; + + if (!mm_is_valid_heap(image_ptr)) + return No; + + for (SizeT index = 0UL; index < HardwareThreadScheduler::The().Capacity(); ++index) + { + if (!HardwareThreadScheduler::The()[index].Leak()) + continue; + + if (HardwareThreadScheduler::The()[index].Leak()->Kind() == kInvalidAP) + continue; + + if (HardwareThreadScheduler::The()[index].Leak()->Kind() != + ThreadKind::kAPBoot && + HardwareThreadScheduler::The()[index].Leak()->Kind() != + ThreadKind::kAPSystemReserved) + { + PID prev_pid = UserProcessHelper::TheCurrentPID(); + UserProcessHelper::TheCurrentPID().Leak().Leak() = new_pid; + + //////////////////////////////////////////////////////////// + /// Prepare task switch. /// + //////////////////////////////////////////////////////////// + + auto prev_ptime = HardwareThreadScheduler::The()[index].Leak()->fPTime; + HardwareThreadScheduler::The()[index].Leak()->fPTime = UserProcessScheduler::The().CurrentTeam().AsArray()[new_pid]->PTime; + Bool ret = HardwareThreadScheduler::The()[index].Leak()->Switch(image_ptr, stack, frame_ptr, new_pid); + + //////////////////////////////////////////////////////////// + /// Rollback on fail. /// + //////////////////////////////////////////////////////////// + if (!ret) + { + HardwareThreadScheduler::The()[index].Leak()->fPTime = prev_ptime; + UserProcessHelper::TheCurrentPID().Leak().Leak() = prev_pid; + + continue; + } + } + } + + return false; + } + + /// @brief this checks if any process is on the team. + UserProcessScheduler::operator bool() + { + return mTeam.AsArray().Count() > 0; + } + + /// @brief this checks if no process is on the team. + bool UserProcessScheduler::operator!() + { + return mTeam.AsArray().Count() == 0; + } +} // namespace Kernel diff --git a/dev/Kernel/src/UserProcessTeam.cc b/dev/Kernel/src/UserProcessTeam.cc new file mode 100644 index 00000000..2e65aebb --- /dev/null +++ b/dev/Kernel/src/UserProcessTeam.cc @@ -0,0 +1,55 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +/***********************************************************************************/ +/// @file UserProcessTeam.cc +/// @brief Process teams implementation. +/***********************************************************************************/ + +#include + +namespace Kernel +{ + UserProcessTeam::UserProcessTeam() + { + for (SizeT i = 0U; i < this->mProcessList.Count(); ++i) + { + this->mProcessList[i] = nullptr; + } + } + + /***********************************************************************************/ + /// @brief UserProcess list array getter. + /// @return The list of process to schedule. + /***********************************************************************************/ + + Array& UserProcessTeam::AsArray() + { + return this->mProcessList; + } + + /***********************************************************************************/ + /// @brief Get team ID. + /// @return The team's ID. + /***********************************************************************************/ + + ProcessID& UserProcessTeam::Id() noexcept + { + return this->mTeamId; + } + + /***********************************************************************************/ + /// @brief Get current process getter as Ref. + /// @return The current process header. + /***********************************************************************************/ + + Ref& UserProcessTeam::AsRef() + { + return this->mCurrentProcess; + } +} // namespace Kernel + +// last rev 05-03-24 diff --git a/dev/Kernel/src/Utils.cc b/dev/Kernel/src/Utils.cc new file mode 100644 index 00000000..0c3ac5f8 --- /dev/null +++ b/dev/Kernel/src/Utils.cc @@ -0,0 +1,223 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include + +namespace Kernel +{ + Int32 rt_string_cmp(const Char* src, const Char* cmp, Size size) + { + if (!cmp || + !src) + return 1; + + Int32 counter = 0; + + for (Size index = 0; index < size; ++index) + { + if (src[index] != cmp[index]) + ++counter; + } + + return counter; + } + + Void rt_zero_memory(voidPtr pointer, Size len) + { + rt_set_memory(pointer, 0, len); + } + + SizeT rt_string_len(const Char* str, SizeT _len) + { + SizeT len{0}; + + do + { + if (len > _len) + { + return _len; + } + + ++len; + } while (str[len] != '\0'); + + return len; + } + + Size rt_string_len(const Char* ptr) + { + SizeT cnt{0}; + + do + { + ++cnt; + } while (ptr[cnt] != 0); + + return cnt; + } + + voidPtr rt_set_memory(voidPtr src, UInt32 value, Size len) + { + if (!src || len < 1) + return nullptr; + + UInt32* start = reinterpret_cast(src); + + while (len) + { + *start = value; + ++start; + --len; + } + + return (voidPtr)start; + } + + Int rt_move_memory(const voidPtr src, voidPtr dst, Size len) + { + if (len < 1) + return 2; + + if (!src || !dst) + return 1; + + Char* srcChr = reinterpret_cast(src); + Char* dstChar = reinterpret_cast(dst); + SizeT index = 0; + + while (index < len) + { + dstChar[index] = srcChr[index]; + srcChr[index] = 0; + + ++index; + } + + return 0; + } + + Int rt_copy_memory(const voidPtr src, voidPtr dst, Size len) + { + if (len < 1) + return 0; + + char* srcChr = reinterpret_cast(src); + char* dstChar = reinterpret_cast(dst); + Size index = 0; + + while (index < len) + { + dstChar[index] = srcChr[index]; + ++index; + } + + return index; + } + + const Char* alloc_string(const Char* text) + { + if (!text) + return nullptr; + + const Char* string = new Char[rt_string_len(text)]; + + if (!string) + return nullptr; + + voidPtr vText = reinterpret_cast(const_cast(text)); + voidPtr vStr = reinterpret_cast(const_cast(string)); + + rt_copy_memory(vText, vStr, rt_string_len(text)); + + return string; + } + + Int32 rt_to_uppercase(Int32 character) + { + if (character >= 'a' && character <= 'z') + return character - 0x20; + + return character; + } + + Int32 rt_to_lower(Int32 character) + { + if (character >= 'A' && character <= 'Z') + return character + 0x20; + + return character; + } + + Bool rt_to_string(Char* str, Int32 limit, Int32 base) + { + if (limit == 0) + return false; + + Int copy_limit = limit; + Int cnt = 0; + Int ret = base; + + while (limit != 1) + { + ret = ret % 10; + str[cnt] = ret; + + ++cnt; + --limit; + --ret; + } + + str[copy_limit] = '\0'; + return true; + } + + Boolean is_space(Char chr) + { + return chr == ' '; + } + + Boolean is_newln(Char chr) + { + return chr == '\n'; + } + + voidPtr rt_string_in_string(const Char* in, const Char* needle) + { + for (SizeT i = 0; i < rt_string_len(in); ++i) + { + if (rt_string_cmp(in + i, needle, rt_string_len(needle)) == 0) + return reinterpret_cast(const_cast(in + i)); + } + + return nullptr; + } + + // @brief Checks for a string start at the character. + + Char* rt_string_has_char(Char* str, const Char chr) + { + while (*str != chr) + { + ++str; + + if (*str == 0) + return nullptr; + } + + return str; + } +} // namespace Kernel + +EXTERN_C void* memset(void* dst, int c, long long unsigned int len) +{ + return Kernel::rt_set_memory(dst, c, len); +} + +EXTERN_C void* memcpy(void* dst, const void* src, long long unsigned int len) +{ + Kernel::rt_copy_memory(const_cast(src), dst, len); + return dst; +} diff --git a/dev/Kernel/src/Variant.cc b/dev/Kernel/src/Variant.cc new file mode 100644 index 00000000..39235652 --- /dev/null +++ b/dev/Kernel/src/Variant.cc @@ -0,0 +1,33 @@ +/* ------------------------------------------- + + Copyright (C) 2024, TQ B.V, all rights reserved. + +------------------------------------------- */ + +#include + +namespace Kernel +{ + const Char* Variant::ToString() + { + switch (fKind) + { + case VariantKind::kXML: + return ("Class:{XML}"); + case VariantKind::kJson: + return ("Class:{Json}"); + case VariantKind::kString: + return ("Class:{String}"); + case VariantKind::kBlob: + return ("Class:{Blob}"); + default: + return ("Class:{Null}"); + } + } + + /// @brief Leak variant's instance. + VoidPtr Variant::Leak() + { + return fPtr; + } +} // namespace Kernel diff --git a/dev/Modules/ACPI/ACPI.h b/dev/Modules/ACPI/ACPI.h index d21c475e..8d04cd96 100644 --- a/dev/Modules/ACPI/ACPI.h +++ b/dev/Modules/ACPI/ACPI.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024, Theater Quality Inc, all rights reserved. + Copyright (C) 2024, TQ B.V, all rights reserved. ------------------------------------------- */ diff --git a/dev/Modules/ACPI/ACPIFactoryInterface.h b/dev/Modules/ACPI/ACPIFactoryInterface.h index d6a71316..815b97bb 100644 --- a/dev/Modules/ACPI/ACPIFactoryInterface.h +++ b/dev/Modules/ACPI/ACPIFactoryInterface.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024, Theater Quality Inc, all rights reserved. + Copyright (C) 2024, TQ B.V, all rights reserved. ------------------------------------------- */ diff --git a/dev/Modules/AHCI/AHCI.h b/dev/Modules/AHCI/AHCI.h index 4670c5c7..9fe4d84a 100644 --- a/dev/Modules/AHCI/AHCI.h +++ b/dev/Modules/AHCI/AHCI.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024, Theater Quality Inc, all rights reserved. + Copyright (C) 2024, TQ B.V, all rights reserved. File: AHCI.h Purpose: AHCI protocol defines. diff --git a/dev/Modules/APM/APM.h b/dev/Modules/APM/APM.h index 6c631802..6e31b7fc 100644 --- a/dev/Modules/APM/APM.h +++ b/dev/Modules/APM/APM.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024, Theater Quality Inc, all rights reserved. + Copyright (C) 2024, TQ B.V, all rights reserved. ------------------------------------------- */ diff --git a/dev/Modules/ATA/ATA.h b/dev/Modules/ATA/ATA.h index d79fdd52..145a1d00 100644 --- a/dev/Modules/ATA/ATA.h +++ b/dev/Modules/ATA/ATA.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024, Theater Quality Inc, all rights reserved. + Copyright (C) 2024, TQ B.V, all rights reserved. File: Defines.h Purpose: ATA header. diff --git a/dev/Modules/FB/FB.h b/dev/Modules/FB/FB.h index 6a609255..02fd1c6f 100644 --- a/dev/Modules/FB/FB.h +++ b/dev/Modules/FB/FB.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024, Theater Quality Inc, all rights reserved. + Copyright (C) 2024, TQ B.V, all rights reserved. ------------------------------------------- */ diff --git a/dev/Modules/FB/Text.h b/dev/Modules/FB/Text.h index 36e082c3..f8a255f7 100644 --- a/dev/Modules/FB/Text.h +++ b/dev/Modules/FB/Text.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024, Theater Quality Inc, all rights reserved. + Copyright (C) 2024, TQ B.V, all rights reserved. ------------------------------------------- */ diff --git a/dev/Modules/Flash/Flash.h b/dev/Modules/Flash/Flash.h index f549ef44..120675fb 100644 --- a/dev/Modules/Flash/Flash.h +++ b/dev/Modules/Flash/Flash.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024, Theater Quality Inc, all rights reserved. + Copyright (C) 2024, TQ B.V, all rights reserved. ------------------------------------------- */ diff --git a/dev/Modules/HPET/Defines.h b/dev/Modules/HPET/Defines.h index 813e6884..e8a0d3a6 100644 --- a/dev/Modules/HPET/Defines.h +++ b/dev/Modules/HPET/Defines.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024, Theater Quality Inc, all rights reserved. + Copyright (C) 2024, TQ B.V, all rights reserved. File: HPET.h Purpose: HPET builtin. diff --git a/dev/Modules/LTE/LTE.h b/dev/Modules/LTE/LTE.h index a5327df9..5209d937 100644 --- a/dev/Modules/LTE/LTE.h +++ b/dev/Modules/LTE/LTE.h @@ -1,6 +1,6 @@ /* ------------------------------------------- -Copyright (C) 2024, Theater Quality Inc, all rights reserved.. +Copyright (C) 2024, TQ B.V, all rights reserved.. File: LTE\LTE.h. Purpose: LTE Standard Library. diff --git a/dev/Modules/MBCI/Interface.h b/dev/Modules/MBCI/Interface.h index 9186ba24..efcfc0aa 100644 --- a/dev/Modules/MBCI/Interface.h +++ b/dev/Modules/MBCI/Interface.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024, Theater Quality Inc, all rights reserved. + Copyright (C) 2024, TQ B.V, all rights reserved. ------------------------------------------- */ diff --git a/dev/Modules/MBCI/MBCI.h b/dev/Modules/MBCI/MBCI.h index ac620972..2be77b58 100644 --- a/dev/Modules/MBCI/MBCI.h +++ b/dev/Modules/MBCI/MBCI.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024, Theater Quality Inc, all rights reserved. + Copyright (C) 2024, TQ B.V, all rights reserved. ------------------------------------------- */ diff --git a/dev/Modules/NVME/NVME.h b/dev/Modules/NVME/NVME.h index 2d77a769..f2f42fac 100644 --- a/dev/Modules/NVME/NVME.h +++ b/dev/Modules/NVME/NVME.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024, Theater Quality Inc, all rights reserved. + Copyright (C) 2024, TQ B.V, all rights reserved. Revision History: diff --git a/dev/Modules/ReadMe.md b/dev/Modules/ReadMe.md index bdb7fb69..f1bfc626 100644 --- a/dev/Modules/ReadMe.md +++ b/dev/Modules/ReadMe.md @@ -9,4 +9,4 @@ They are pluggable modules for builtin hardware support. - [X] AHCI kernel module. - [X] MBCI kernel module. -###### Copyright (C) 2024, Theater Quality Inc, all rights reserved. All rights reserved. +###### Copyright (C) 2024, TQ B.V, all rights reserved. All rights reserved. diff --git a/dev/Modules/SCSI/SCSI.h b/dev/Modules/SCSI/SCSI.h index 917c963e..27213ee7 100644 --- a/dev/Modules/SCSI/SCSI.h +++ b/dev/Modules/SCSI/SCSI.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024, Theater Quality Inc, all rights reserved. + Copyright (C) 2024, TQ B.V, all rights reserved. ------------------------------------------- */ diff --git a/dev/Modules/XHCI/Defines.h b/dev/Modules/XHCI/Defines.h index 6758cf33..ada55dfc 100644 --- a/dev/Modules/XHCI/Defines.h +++ b/dev/Modules/XHCI/Defines.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024, Theater Quality Inc, all rights reserved. + Copyright (C) 2024, TQ B.V, all rights reserved. File: Defines.h Purpose: XHCI (and backwards) header. diff --git a/dev/SCIKit/CompilerHint.h b/dev/SCIKit/CompilerHint.h index 3365bac2..0c84f8e4 100644 --- a/dev/SCIKit/CompilerHint.h +++ b/dev/SCIKit/CompilerHint.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024, Theater Quality Inc, all rights reserved. + Copyright (C) 2024, TQ B.V, all rights reserved. ------------------------------------------- */ diff --git a/dev/SCIKit/GPU.h b/dev/SCIKit/GPU.h index a7e3dd92..0606733a 100644 --- a/dev/SCIKit/GPU.h +++ b/dev/SCIKit/GPU.h @@ -1,6 +1,6 @@ /* ------------------------------------------- -Copyright (C) 2024, Theater Quality Inc, all rights reserved. +Copyright (C) 2024, TQ B.V, all rights reserved. File: GPU.h Purpose: GFX System Calls. diff --git a/dev/SCIKit/LPC.h b/dev/SCIKit/LPC.h index b0e9e456..8013c6df 100644 --- a/dev/SCIKit/LPC.h +++ b/dev/SCIKit/LPC.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024, Theater Quality Inc, all rights reserved. + Copyright (C) 2024, TQ B.V, all rights reserved. ------------------------------------------- */ diff --git a/dev/SCIKit/Macros.h b/dev/SCIKit/Macros.h index 9523725c..28e62075 100644 --- a/dev/SCIKit/Macros.h +++ b/dev/SCIKit/Macros.h @@ -1,6 +1,6 @@ /* ------------------------------------------- -Copyright (C) 2024, Theater Quality Inc, all rights reserved. +Copyright (C) 2024, TQ B.V, all rights reserved. File: Macros.h Purpose: SCIKit Macros header. diff --git a/dev/SCIKit/SCI.h b/dev/SCIKit/SCI.h index 0eea032a..146b469b 100644 --- a/dev/SCIKit/SCI.h +++ b/dev/SCIKit/SCI.h @@ -1,6 +1,6 @@ /* ------------------------------------------- -Copyright (C) 2024, Theater Quality Inc, all rights reserved. +Copyright (C) 2024, TQ B.V, all rights reserved. File: SCI.h Purpose: System Calls. diff --git a/dev/SCIKit/SysCalls.h b/dev/SCIKit/SysCalls.h index 1f87134a..ccb5433c 100644 --- a/dev/SCIKit/SysCalls.h +++ b/dev/SCIKit/SysCalls.h @@ -1,6 +1,6 @@ /* ------------------------------------------- -Copyright (C) 2024, Theater Quality Inc, all rights reserved. +Copyright (C) 2024, TQ B.V, all rights reserved. File: Macros.h Purpose: SCIKit Macros header. diff --git a/dev/SCIKit/src/GPU.cc b/dev/SCIKit/src/GPU.cc index cb21dae5..f0462c5c 100644 --- a/dev/SCIKit/src/GPU.cc +++ b/dev/SCIKit/src/GPU.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- -Copyright (C) 2024, Theater Quality Inc, all rights reserved. +Copyright (C) 2024, TQ B.V, all rights reserved. File: GPU.cc Purpose: GPU Interface. diff --git a/dev/SCIKit/src/LPC.cc b/dev/SCIKit/src/LPC.cc index 2dcfc415..bbc2004c 100644 --- a/dev/SCIKit/src/LPC.cc +++ b/dev/SCIKit/src/LPC.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- -Copyright (C) 2024, Theater Quality Inc, all rights reserved. +Copyright (C) 2024, TQ B.V, all rights reserved. File: LPC.cc Purpose: Local Procedure Codes. diff --git a/dev/SCIKit/src/Makefile b/dev/SCIKit/src/Makefile index b14cc60d..22f7a44d 100644 --- a/dev/SCIKit/src/Makefile +++ b/dev/SCIKit/src/Makefile @@ -1,11 +1,16 @@ ################################################## -# (c) Theater Quality Inc, all rights reserved. +# (c) TQ B.V, all rights reserved. # This is the bootloader makefile. ################################################## ASM=nasm FLAGS=-f win64 -.PHONY: syscall_unit -syscall_unit: - $(ASM) $(FLAGS) SysCallDispatcher.asm -o SysCallDispatcher.o +.PHONY: error +error: + @echo "==> Invalid rule." + @echo "==> Use sci_asm_io instead." + +.PHONY: sci_asm_io +sci_asm_io: + $(ASM) $(FLAGS) SCI+IO.asm -o SCI+IO.o diff --git a/dev/SCIKit/src/SCI+IO.asm b/dev/SCIKit/src/SCI+IO.asm new file mode 100644 index 00000000..3f5c39fa --- /dev/null +++ b/dev/SCIKit/src/SCI+IO.asm @@ -0,0 +1,50 @@ +;; /* +;; * ======================================================== +;; * +;; * SCI +;; * Copyright (C) 2024, TQ B.V, all rights reserved., all rights reserved. +;; * +;; * ======================================================== +;; */ + +[bits 64] + +section .text + +global sci_syscall_arg_1 +global sci_syscall_arg_2 +global sci_syscall_arg_3 +global sci_syscall_arg_4 + +sci_syscall_arg_1: + mov r8, rcx + syscall + ret + +sci_syscall_arg_2: + mov r8, rcx + mov r9, rdx + syscall + ret + +sci_syscall_arg_3: + mov rbx, r8 + + mov r8, rcx + mov r9, rdx + mov r10, rbx + + syscall + ret + +sci_syscall_arg_4: + mov rbx, r8 + mov rax, r9 + + mov r8, rcx + mov r9, rdx + mov r10, rbx + mov r11, rax + + syscall + ret diff --git a/dev/SCIKit/src/SCI.cc b/dev/SCIKit/src/SCI.cc index a5ccdc23..f61fcdd7 100644 --- a/dev/SCIKit/src/SCI.cc +++ b/dev/SCIKit/src/SCI.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024, Theater Quality Inc, all rights reserved. + Copyright (C) 2024, TQ B.V, all rights reserved. ------------------------------------------- */ diff --git a/dev/SCIKit/src/SysCallDispatcher.asm b/dev/SCIKit/src/SysCallDispatcher.asm deleted file mode 100644 index 2f52796b..00000000 --- a/dev/SCIKit/src/SysCallDispatcher.asm +++ /dev/null @@ -1,50 +0,0 @@ -;; /* -;; * ======================================================== -;; * -;; * SCI -;; * Copyright (C) 2024, Theater Quality Inc, all rights reserved., all rights reserved. -;; * -;; * ======================================================== -;; */ - -[bits 64] - -section .text - -global sci_syscall_arg_1 -global sci_syscall_arg_2 -global sci_syscall_arg_3 -global sci_syscall_arg_4 - -sci_syscall_arg_1: - mov r8, rcx - syscall - ret - -sci_syscall_arg_2: - mov r8, rcx - mov r9, rdx - syscall - ret - -sci_syscall_arg_3: - mov rbx, r8 - - mov r8, rcx - mov r9, rdx - mov r10, rbx - - syscall - ret - -sci_syscall_arg_4: - mov rbx, r8 - mov rax, r9 - - mov r8, rcx - mov r9, rdx - mov r10, rbx - mov r11, rax - - syscall - ret diff --git a/dev/ZBAKit/BootKit/BitManip.h b/dev/ZBAKit/BootKit/BitManip.h deleted file mode 100644 index 3b5ea540..00000000 --- a/dev/ZBAKit/BootKit/BitManip.h +++ /dev/null @@ -1,20 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#ifndef __BITMANIP_H__ -#define __BITMANIP_H__ - -/// File: BitManip.h -/// Purpose: Bit manipulation helpers, based on coreboot-dev. - -#define bk_set_bit(X, O) X = (1 << O) | X -#define bk_clear_bit(X, O) X = ~(1 << O) & X -#define bk_toogle(X, O) X = (1 << O) ^ X -#define bk_lsb(X) X = X & -X -#define bk_msb(X) X = -(mp_lsb(X)) & X -#define bk_look_for_bit(X, O) (1 << O) | X - -#endif // ifndef __BITMANIP_H__ diff --git a/dev/ZBAKit/BootKit/BootKit.h b/dev/ZBAKit/BootKit/BootKit.h deleted file mode 100644 index cbf9b725..00000000 --- a/dev/ZBAKit/BootKit/BootKit.h +++ /dev/null @@ -1,393 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -/***********************************************************************************/ -/// @file BootKit.h -/// @brief Bootloader Application Programming Interface. -/***********************************************************************************/ - -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include - -/// include NeFS header and Support header as well. - -#include -#include - -/***********************************************************************************/ -/// Include other APIs. -/***********************************************************************************/ - -#include -#include - -#include - -/***********************************************************************************/ -/// Framebuffer helpers. -/***********************************************************************************/ - -namespace EFI -{ - EXTERN void ThrowError(const WideChar* errorCode, - const WideChar* reason) noexcept; -} // namespace EFI - -namespace Boot -{ - class BTextWriter; - class BFileReader; - class BThread; - class BVersionString; - - typedef Char* PEFImagePtr; - typedef Char* PEImagePtr; - - typedef WideChar CharacterTypeUTF16; - typedef Char CharacterTypeUTF8; - - using namespace Kernel; - - /** - * @brief BootKit Text Writer class - * Writes to UEFI StdOut. - */ - class BTextWriter final - { - BTextWriter& _Write(const Long& num); - - public: - BTextWriter& Write(const Long& num); - BTextWriter& Write(const Char* str); - BTextWriter& Write(const CharacterTypeUTF16* str); - BTextWriter& WriteCharacter(CharacterTypeUTF16 c); - BTextWriter& Write(const UChar* str); - - public: - explicit BTextWriter() = default; - ~BTextWriter() = default; - - public: - BTextWriter& operator=(const BTextWriter&) = default; - BTextWriter(const BTextWriter&) = default; - }; - - Kernel::SizeT BCopyMem(CharacterTypeUTF16* dest, CharacterTypeUTF16* src, const Kernel::SizeT len); - - Kernel::SizeT BSetMem(CharacterTypeUTF8* src, const CharacterTypeUTF8 byte, const Kernel::SizeT len); - - /// String length functions. - - /// @brief get string length. - Kernel::SizeT BStrLen(const CharacterTypeUTF16* ptr); - - /// @brief set memory with custom value. - Kernel::SizeT BSetMem(CharacterTypeUTF16* src, const CharacterTypeUTF16 byte, const Kernel::SizeT len); - - /** - * @brief BootKit File Reader class - * Reads the Firmware Boot partition and filesystem. - */ - class BFileReader final - { - public: - explicit BFileReader(const CharacterTypeUTF16* path, - EfiHandlePtr ImageHandle); - ~BFileReader(); - - public: - Void ReadAll(SizeT until, SizeT chunk = kib_cast(4), UIntPtr out_address = 0UL); - - enum - { - kOperationOkay, - kNotSupported, - kEmptyDirectory, - kNoSuchEntry, - kIsDirectory, - kTooSmall, - kCount, - }; - - /// @brief error code getter. - /// @return the error code. - Int32& Error(); - - /// @brief blob getter. - /// @return the blob. - VoidPtr Blob(); - - /// @breif Size getter. - /// @return the size of the file. - UInt64& Size(); - - public: - BFileReader& operator=(const BFileReader&) = default; - BFileReader(const BFileReader&) = default; - - private: - Int32 mErrorCode{kOperationOkay}; - VoidPtr mBlob{nullptr}; - CharacterTypeUTF16 mPath[kPathLen]; - BTextWriter mWriter; - EfiFileProtocol* mFile{nullptr}; - UInt64 mSizeFile{0}; - EfiFileProtocol* mRootFs; - }; - - typedef UInt8* BlobType; - - class BVersionString final - { - public: - static const CharacterTypeUTF8* The() - { - return BOOTLOADER_VERSION; - } - }; - - /***********************************************************************************/ - /// Provide some useful processor features. - /***********************************************************************************/ - -#ifdef __EFI_x86_64__ - - /*** - * Common processor instructions. - */ - - EXTERN_C void rt_out8(UInt16 port, UInt8 value); - EXTERN_C void rt_out16(UInt16 port, UInt16 value); - EXTERN_C void rt_out32(UInt16 port, UInt32 value); - EXTERN_C UInt8 rt_in8(UInt16 port); - EXTERN_C UInt16 In16(UInt16 port); - EXTERN_C UInt32 rt_in32(UInt16 port); - - EXTERN_C void rt_hlt(); - EXTERN_C void rt_cli(); - EXTERN_C void rt_sti(); - EXTERN_C void rt_cld(); - EXTERN_C void rt_std(); - -#endif // __EFI_x86_64__ - - static inline const UInt32 kRgbRed = 0x000000FF; - static inline const UInt32 kRgbGreen = 0x0000FF00; - static inline const UInt32 kRgbBlue = 0x00FF0000; - static inline const UInt32 kRgbBlack = 0x00000000; - static inline const UInt32 kRgbWhite = 0x00FFFFFF; - -#define kBKBootFileMime "boot-x/file" -#define kBKBootDirMime "boot-x/dir" - - /// @brief BootKit Drive Formatter. - template - class BDiskFormatFactory final - { - public: - /// @brief File entry for **BDiskFormatFactory**. - struct BFileDescriptor final - { - Char fFileName[kNeFSNodeNameLen]; - Int32 fKind; - }; - - public: - explicit BDiskFormatFactory() = default; - explicit BDiskFormatFactory(BootDev dev) - : fDiskDev(dev) - { - } - - ~BDiskFormatFactory() = default; - - ZKA_COPY_DELETE(BDiskFormatFactory); - - /// @brief Format disk using partition name and fileBlobs. - /// @param Partition partName the target partition name. - /// @param fileBlobs blobs array. - /// @param blobCount blobs array count. - /// @retval True disk has been formatted. - /// @retval False failed to format. - Boolean Format(const Char* partName, BFileDescriptor* fileBlobs, SizeT blobCount); - - /// @brief check if partition is good. - Bool IsPartitionValid() noexcept - { - fDiskDev.Leak().mBase = (kNeFSRootCatalogStartAddress); - fDiskDev.Leak().mSize = BootDev::kSectorSize; - - Char buf[BootDev::kSectorSize] = {0}; - - fDiskDev.Read(buf, BootDev::kSectorSize); - - NFS_ROOT_PARTITION_BLOCK* blockPart = reinterpret_cast(buf); - - BTextWriter writer; - - for (SizeT indexMag = 0UL; indexMag < kNeFSIdentLen; ++indexMag) - { - if (blockPart->Ident[indexMag] != kNeFSIdent[indexMag]) - return false; - } - - if (blockPart->DiskSize != this->fDiskDev.GetDiskSize() || - blockPart->DiskSize < 1 || - blockPart->SectorSize != BootDev::kSectorSize || - blockPart->Version != kNeFSVersionInteger || - blockPart->StartCatalog == 0) - { - return false; - } - else if (blockPart->PartitionName[0] == 0) - { - return false; - } - - writer.Write(L"BootZ: Partition: ").Write(blockPart->PartitionName).Write(L" is healthy.\r"); - - return true; - } - - private: - /// @brief Write all of the requested catalogs into the filesystem. - /// @param fileBlobs the blobs. - /// @param blobCount the number of blobs to write. - /// @param partBlock the NeFS partition block. - Boolean WriteRootCatalog(BFileDescriptor* fileBlobs, SizeT blobCount, NFS_ROOT_PARTITION_BLOCK& partBlock) - { - BFileDescriptor* blob = fileBlobs; - Lba startLba = partBlock.StartCatalog; - BTextWriter writer; - - NFS_CATALOG_STRUCT catalogKind{0}; - - constexpr auto cNeFSCatalogPadding = 4; - - catalogKind.PrevSibling = startLba; - catalogKind.NextSibling = (startLba + sizeof(NFS_CATALOG_STRUCT) * cNeFSCatalogPadding); - - /// Fill catalog kind. - catalogKind.Kind = blob->fKind; - catalogKind.Flags = kNeFSFlagCreated; - - --partBlock.FreeCatalog; - --partBlock.FreeSectors; - - CopyMem(catalogKind.Name, blob->fFileName, StrLen(blob->fFileName)); - - fDiskDev.Leak().mBase = startLba; - fDiskDev.Leak().mSize = sizeof(NFS_CATALOG_STRUCT); - - fDiskDev.Write((Char*)&catalogKind, sizeof(NFS_CATALOG_STRUCT)); - - writer.Write(L"BootZ: Wrote directory: ").Write(blob->fFileName).Write(L"\r"); - - return true; - } - - private: - BootDev fDiskDev; - }; - - /// @brief Format disk. - /// @param Partition Name - /// @param Blobs. - /// @param Number of blobs. - /// @retval True disk has been formatted. - /// @retval False failed to format. - template - inline Boolean BDiskFormatFactory::Format(const Char* partName, - BDiskFormatFactory::BFileDescriptor* fileBlobs, - SizeT blobCount) - { - if (!fileBlobs || !blobCount) - return false; /// sanity check - - /// convert the sector into something that the disk understands. - SizeT sectorSz = sizeof(NFS_ROOT_PARTITION_BLOCK); - - /// @note A catalog roughly equal to a sector. - - constexpr auto kMinimumDiskSize = kNeFSMinimumDiskSize; // at minimum. - - /// @note also look at EPM headers, for free part blocks. - - if (fDiskDev.GetDiskSize() < kMinimumDiskSize) - { - cg_init(); - - CGDrawBitMapInRegion(zka_no_disk, ZKA_NO_DISK_HEIGHT, ZKA_NO_DISK_WIDTH, (kHandoverHeader->f_GOP.f_Width - ZKA_NO_DISK_WIDTH) / 2, (kHandoverHeader->f_GOP.f_Height - ZKA_NO_DISK_HEIGHT) / 2); - EFI::ThrowError(L"Drive-Too-Tiny", L"Can't format a New Filesystem partition here."); - return false; - } - - NFS_ROOT_PARTITION_BLOCK partBlock{0}; - - CopyMem(partBlock.Ident, kNeFSIdent, kNeFSIdentLen - 1); - CopyMem(partBlock.PartitionName, partName, StrLen(partName)); - - partBlock.Version = kNeFSVersionInteger; - partBlock.CatalogCount = blobCount; - partBlock.Kind = kNeFSHardDrive; - partBlock.SectorSize = sectorSz; - partBlock.FreeCatalog = fDiskDev.GetSectorsCount() / sizeof(NFS_CATALOG_STRUCT); - partBlock.SectorCount = fDiskDev.GetSectorsCount(); - partBlock.FreeSectors = fDiskDev.GetSectorsCount(); - partBlock.StartCatalog = kNeFSCatalogStartAddress; - partBlock.DiskSize = fDiskDev.GetDiskSize(); - partBlock.Flags = kNeFSPartitionTypeBoot | kNeFSPartitionTypeStandard; - - fDiskDev.Leak().mBase = kNeFSRootCatalogStartAddress; - fDiskDev.Leak().mSize = sectorSz; - - fDiskDev.Write((Char*)&partBlock, sectorSz); - - BOOT_BLOCK_STRUCT epmBoot{0}; - - constexpr auto cFsName = "NeFS"; - constexpr auto cBlockName = "ZKA:"; - - CopyMem(epmBoot.Fs, reinterpret_cast(const_cast(cFsName)), StrLen(cFsName)); - - epmBoot.FsVersion = kNeFSVersionInteger; - epmBoot.LbaStart = kNeFSRootCatalogStartAddress; - epmBoot.SectorSz = partBlock.SectorSize; - epmBoot.Kind = kEPMNewOS; - epmBoot.NumBlocks = partBlock.CatalogCount; - - CopyMem(epmBoot.Name, reinterpret_cast(const_cast(cBlockName)), StrLen(cBlockName)); - CopyMem(epmBoot.Magic, reinterpret_cast(const_cast(kEPMMagic)), StrLen(kEPMMagic)); - - fDiskDev.Leak().mBase = 1; // always always resies at zero block. - fDiskDev.Leak().mSize = BootDev::kSectorSize; - - fDiskDev.Write((Char*)&epmBoot, sectorSz); - - /// if we can write a root catalog, then write the partition block. - if (this->WriteRootCatalog(fileBlobs, blobCount, partBlock)) - { - BTextWriter writer; - writer.Write(L"BootZ: Drive formatted.\r"); - - return true; - } - else - { - EFI::ThrowError(L"Filesystem-Failure-Part", L"Filesystem couldn't be partitioned, this drive cannot be formatted as an explicit partition map."); - } - - return false; - } -} // namespace Boot diff --git a/dev/ZBAKit/BootKit/Device.h b/dev/ZBAKit/BootKit/Device.h deleted file mode 100644 index 03e913bd..00000000 --- a/dev/ZBAKit/BootKit/Device.h +++ /dev/null @@ -1,37 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include -#include - -using namespace Kernel; - -/// @brief Device type. -class Device -{ -public: - explicit Device() = default; - virtual ~Device() = default; - - ZKA_MOVE_DEFAULT(Device); - - struct Trait - { - SizeT mBase{1024}; - SizeT mSize{1024}; - }; - - virtual Trait& Leak() = 0; - - virtual Device& Read(Char* Buf, const SizeT& SecCount) = 0; - virtual Device& Write(Char* Buf, const SizeT& SecCount) = 0; -}; - -typedef Device BootDevice; -typedef Device NetworkDevice; -typedef Device DiskDevice; diff --git a/dev/ZBAKit/BootKit/EPM.h b/dev/ZBAKit/BootKit/EPM.h deleted file mode 100644 index 1956144e..00000000 --- a/dev/ZBAKit/BootKit/EPM.h +++ /dev/null @@ -1,9 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include diff --git a/dev/ZBAKit/BootKit/HW/ATA.h b/dev/ZBAKit/BootKit/HW/ATA.h deleted file mode 100644 index 79a19886..00000000 --- a/dev/ZBAKit/BootKit/HW/ATA.h +++ /dev/null @@ -1,58 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include -#include - -using namespace Kernel; - -class BootDeviceATA final : public Device -{ -public: - enum - { - kPrimary = ATA_PRIMARY_IO, - kSecondary = ATA_SECONDARY_IO, - }; - - explicit BootDeviceATA() noexcept; - ~BootDeviceATA() = default; - - ZKA_COPY_DELETE(BootDeviceATA); - - enum - { - kSectorSize = kATASectorSize - }; - - struct ATATrait final : public Device::Trait - { - UInt16 mBus{kPrimary}; - UInt8 mMaster{0}; - Boolean mErr{false}; - - operator bool() - { - return !mErr; - } - }; - -public: - operator bool(); - - SizeT GetSectorsCount() noexcept; - SizeT GetDiskSize() noexcept; - - BootDeviceATA& Read(Char* Buf, const SizeT& SecCount) override; - BootDeviceATA& Write(Char* Buf, const SizeT& SecCount) override; - - ATATrait& Leak() override; - -private: - ATATrait mTrait; -}; diff --git a/dev/ZBAKit/BootKit/HW/SATA.h b/dev/ZBAKit/BootKit/HW/SATA.h deleted file mode 100644 index 0b6dd92b..00000000 --- a/dev/ZBAKit/BootKit/HW/SATA.h +++ /dev/null @@ -1,46 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include -#include - -class BootDeviceSATA final -{ -public: - explicit BootDeviceSATA() noexcept; - ~BootDeviceSATA() = default; - - ZKA_COPY_DEFAULT(BootDeviceSATA); - - struct SATATrait final - { - Kernel::SizeT mBase{1024}; - Kernel::Boolean mErr{false}; - Kernel::Boolean mDetected{false}; - - operator bool() - { - return !this->mErr; - } - }; - - operator bool() - { - return this->Leak().mDetected; - } - - BootDeviceSATA& Read(Kernel::WideChar* Buf, const Kernel::SizeT& SecCount); - BootDeviceSATA& Write(Kernel::WideChar* Buf, const Kernel::SizeT& SecCount); - - SATATrait& Leak(); - -private: - SATATrait mTrait; -}; - -#define kAHCISectorSz 4096 diff --git a/dev/ZBAKit/BootKit/Platform.h b/dev/ZBAKit/BootKit/Platform.h deleted file mode 100644 index c8bb5058..00000000 --- a/dev/ZBAKit/BootKit/Platform.h +++ /dev/null @@ -1,32 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -/** - @file Platform.h - @brief Platform specific code. -*/ - -#ifdef __x86_64__ - -#ifdef __cplusplus -#ifndef EXTERN_C -#define EXTERN_C extern "C" -#endif -#else -#ifndef EXTERN_C -#define EXTERN_C extern -#endif -#endif // __cplusplus - -EXTERN_C void rt_halt(); -EXTERN_C void rt_cli(); -EXTERN_C void rt_sti(); -EXTERN_C void rt_cld(); -EXTERN_C void rt_std(); - -#endif /* ifdef __x86_64__ */ diff --git a/dev/ZBAKit/BootKit/Protocol.h b/dev/ZBAKit/BootKit/Protocol.h deleted file mode 100644 index 618885fe..00000000 --- a/dev/ZBAKit/BootKit/Protocol.h +++ /dev/null @@ -1,10 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include -#include diff --git a/dev/ZBAKit/BootKit/Rsrc/zka_disk.rsrc b/dev/ZBAKit/BootKit/Rsrc/zka_disk.rsrc deleted file mode 100644 index ce980b7b..00000000 --- a/dev/ZBAKit/BootKit/Rsrc/zka_disk.rsrc +++ /dev/null @@ -1,116 +0,0 @@ -#define ZKA_DISK_HEIGHT 110 -#define ZKA_DISK_WIDTH 110 - -// array size is 36300 -static const unsigned int zka_disk[] = { - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x333333, 0x565656, 0x636363, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6a6a6a, 0x5f5f5f, 0x4d4d4d, 0x2b2b2b, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x464646, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x6a6a6a, 0x3b3b3b, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x3d3d3d, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x393939, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x252525, 0x676767, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x606060, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4c4c4c, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x3d3d3d, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x616161, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x525252, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x242424, 0x767676, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x676767, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x393939, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7e7e7e, 0x292929, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4e4e4e, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x3f3f3f, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x666666, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x555555, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x222222, 0x7c7c7c, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x6d6d6d, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x393939, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x868686, 0x292929, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x515151, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x404040, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x6a6a6a, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x828282, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x727272, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x383838, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x8e8e8e, 0x2a2a2a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x525252, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x414141, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x6e6e6e, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x5c5c5c, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x868686, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x787878, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x373737, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x959595, 0x2a2a2a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x545454, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0x444444, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x707070, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0x5e5e5e, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x8b8b8b, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0x7c7c7c, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x363636, 0xa7a7a7, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0x9c9c9c, 0x2a2a2a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x545454, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0x464646, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x717171, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0x636363, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x8e8e8e, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0x818181, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x343434, 0xacacac, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xa3a3a3, 0x2a2a2a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x545454, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0x484848, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x727272, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0x676767, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x909090, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0x868686, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x313131, 0xb0b0b0, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xa9a9a9, 0x2a2a2a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x525252, 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, 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, 0x494949, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x727272, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0x6a6a6a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x929292, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0x8c8c8c, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x2e2e2e, 0xb4b4b4, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xafafaf, 0x292929, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x505050, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0x4b4b4b, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x717171, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0x6e6e6e, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x939393, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0x929292, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x2a2a2a, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0x292929, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4c4c4c, 0x4c4c4c, 0x4c4c4c, 0x4c4c4c, 0x4b4b4b, 0x4b4b4b, 0x4b4b4b, 0x4b4b4b, 0x4a4a4a, 0x4a4a4a, 0x4a4a4a, 0x4a4a4a, 0x494949, 0x494949, 0x494949, 0x494949, 0x484848, 0x484848, 0x484848, 0x484848, 0x474747, 0x474747, 0x474747, 0x464646, 0x464646, 0x464646, 0x464646, 0x454545, 0x454545, 0x454545, 0x454545, 0x444444, 0x444444, 0x444444, 0x444444, 0x434343, 0x434343, 0x434343, 0x434343, 0x424242, 0x424242, 0x424242, 0x414141, 0x414141, 0x414141, 0x414141, 0x404040, 0x404040, 0x404040, 0x404040, 0x3f3f3f, 0x3f3f3f, 0x3f3f3f, 0x3f3f3f, 0x3e3e3e, 0x3e3e3e, 0x3e3e3e, 0x3e3e3e, 0x3d3d3d, 0x3d3d3d, 0x3d3d3d, 0x3d3d3d, 0x3c3c3c, 0x3c3c3c, 0x3c3c3c, 0x3c3c3c, 0x3b3b3b, 0x3b3b3b, 0x3b3b3b, 0x3a3a3a, 0x3a3a3a, 0x3a3a3a, 0x3a3a3a, 0x393939, 0x393939, 0x393939, 0x393939, 0x383838, 0x383838, 0x383838, 0x383838, 0x373737, 0x373737, 0x373737, 0x373737, 0x363636, 0x363636, 0x363636, 0x353535, 0x353535, 0x353535, 0x353535, 0x343434, 0x343434, 0x343434, 0x343434, 0x333333, 0x333333, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc2c2c2, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xababab, 0xababab, 0xa9a9a9, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x949494, 0x949494, 0x929292, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7b7b7b, 0x7b7b7b, 0x797979, 0x797979, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xcfcfcf, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0x9f9f9f, 0x9f9f9f, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x9b9b9b, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x888888, 0x888888, 0x868686, 0x868686, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x6f6f6f, 0x6f6f6f, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbebebe, 0xbcbcbc, 0xbcbcbc, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xa9a9a9, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa5a5a5, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcbcbcb, 0xc9c9c9, 0xc9c9c9, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb2b2b2, 0xb0b0b0, 0xb0b0b0, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x9b9b9b, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x848484, 0x848484, 0x828282, 0x828282, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x5a5a5a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc2c2c2, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xa9a9a9, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x929292, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7b7b7b, 0x7b7b7b, 0x797979, 0x797979, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xcfcfcf, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x9b9b9b, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x868686, 0x868686, 0x848484, 0x848484, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x6f6f6f, 0x6f6f6f, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbebebe, 0xbebebe, 0xbcbcbc, 0xbcbcbc, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa5a5a5, 0xa3a3a3, 0xa3a3a3, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcbcbcb, 0xcbcbcb, 0xc9c9c9, 0xc9c9c9, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb2b2b2, 0xb0b0b0, 0xb0b0b0, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x9b9b9b, 0x999999, 0x999999, 0x979797, 0x979797, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x848484, 0x848484, 0x828282, 0x828282, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x5a5a5a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc2c2c2, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xababab, 0xababab, 0xa9a9a9, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x949494, 0x949494, 0x929292, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7b7b7b, 0x7b7b7b, 0x797979, 0x797979, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xcfcfcf, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0x9f9f9f, 0x9f9f9f, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x9b9b9b, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x888888, 0x888888, 0x868686, 0x393939, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4d4d4d, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x6f6f6f, 0x6f6f6f, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbebebe, 0xbcbcbc, 0xbcbcbc, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xa9a9a9, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa5a5a5, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x393939, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4c4c4c, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcbcbcb, 0xc9c9c9, 0xc9c9c9, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb2b2b2, 0xb0b0b0, 0xb0b0b0, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x9b9b9b, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x393939, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4d4d4d, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x5a5a5a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc2c2c2, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xa9a9a9, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x929292, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x393939, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4c4c4c, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xcfcfcf, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x9b9b9b, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x868686, 0x393939, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4d4d4d, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x6f6f6f, 0x6f6f6f, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbebebe, 0xbebebe, 0xbcbcbc, 0xbcbcbc, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa5a5a5, 0xa3a3a3, 0xa3a3a3, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x393939, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4c4c4c, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcbcbcb, 0xcbcbcb, 0xc9c9c9, 0xc9c9c9, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb2b2b2, 0xb0b0b0, 0xb0b0b0, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x9b9b9b, 0x999999, 0x999999, 0x979797, 0x979797, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x848484, 0x848484, 0x828282, 0x828282, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x5a5a5a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc2c2c2, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xababab, 0xababab, 0xa9a9a9, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x949494, 0x949494, 0x929292, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7b7b7b, 0x7b7b7b, 0x797979, 0x797979, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xcfcfcf, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0x9f9f9f, 0x9f9f9f, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x9b9b9b, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x888888, 0x888888, 0x868686, 0x868686, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x6f6f6f, 0x6f6f6f, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbebebe, 0xbcbcbc, 0xbcbcbc, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xa9a9a9, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa5a5a5, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcbcbcb, 0xc9c9c9, 0xc9c9c9, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb2b2b2, 0xb0b0b0, 0xb0b0b0, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x9b9b9b, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x848484, 0x848484, 0x828282, 0x828282, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x5a5a5a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc2c2c2, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xa9a9a9, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x929292, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7b7b7b, 0x7b7b7b, 0x797979, 0x797979, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xc6c6c6, 0xd1d1d1, 0xcfcfcf, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x9b9b9b, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x868686, 0x868686, 0x848484, 0x848484, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x6f6f6f, 0x6f6f6f, 0x6d6d6d, 0x565656, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x9a9a9a, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbebebe, 0xbebebe, 0xbcbcbc, 0xbcbcbc, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa5a5a5, 0xa3a3a3, 0xa3a3a3, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x464646, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x797979, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcbcbcb, 0xcbcbcb, 0xc9c9c9, 0xc9c9c9, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb2b2b2, 0xb0b0b0, 0xb0b0b0, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x9b9b9b, 0x999999, 0x999999, 0x979797, 0x979797, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x848484, 0x848484, 0x828282, 0x828282, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x353535, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xbfbfbf, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc2c2c2, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xababab, 0xababab, 0xa9a9a9, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x949494, 0x949494, 0x929292, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7b7b7b, 0x7b7b7b, 0x797979, 0x797979, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x464646, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x464646, 0xcfcfcf, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0x9f9f9f, 0x9f9f9f, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x9b9b9b, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x888888, 0x888888, 0x868686, 0x868686, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x6f6f6f, 0x676767, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x7f7f7f, 0xbababa, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbebebe, 0xbcbcbc, 0xbcbcbc, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xa9a9a9, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa5a5a5, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x626262, 0x484848, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x3a3a3a, 0x4b4b4b, 0x4b4b4b, 0x4a4a4a, 0x4a4a4a, 0x4a4a4a, 0x4a4a4a, 0x494949, 0x494949, 0x494949, 0x494949, 0x484848, 0x484848, 0x484848, 0x484848, 0x474747, 0x474747, 0x474747, 0x464646, 0x464646, 0x464646, 0x464646, 0x454545, 0x454545, 0x454545, 0x454545, 0x444444, 0x444444, 0x444444, 0x444444, 0x434343, 0x434343, 0x434343, 0x424242, 0x424242, 0x424242, 0x424242, 0x414141, 0x414141, 0x414141, 0x414141, 0x404040, 0x404040, 0x404040, 0x404040, 0x3f3f3f, 0x3f3f3f, 0x3f3f3f, 0x3f3f3f, 0x3e3e3e, 0x3e3e3e, 0x3e3e3e, 0x3e3e3e, 0x3d3d3d, 0x3d3d3d, 0x3d3d3d, 0x3d3d3d, 0x3c3c3c, 0x3c3c3c, 0x3c3c3c, 0x3c3c3c, 0x3b3b3b, 0x3b3b3b, 0x3b3b3b, 0x3a3a3a, 0x3a3a3a, 0x3a3a3a, 0x3a3a3a, 0x393939, 0x393939, 0x393939, 0x393939, 0x383838, 0x383838, 0x383838, 0x383838, 0x373737, 0x373737, 0x373737, 0x373737, 0x363636, 0x363636, 0x363636, 0x353535, 0x353535, 0x353535, 0x353535, 0x272727, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020 -}; \ No newline at end of file diff --git a/dev/ZBAKit/BootKit/Rsrc/zka_has_disk.rsrc b/dev/ZBAKit/BootKit/Rsrc/zka_has_disk.rsrc deleted file mode 100644 index bdc0bb99..00000000 --- a/dev/ZBAKit/BootKit/Rsrc/zka_has_disk.rsrc +++ /dev/null @@ -1,116 +0,0 @@ -#define ZKA_HAS_DISK_HEIGHT 110 -#define ZKA_HAS_DISK_WIDTH 110 - -// array size is 36300 -static const unsigned int zka_has_disk[] = { - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x333333, 0x565656, 0x636363, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6a6a6a, 0x5f5f5f, 0x4d4d4d, 0x2b2b2b, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x464646, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x6a6a6a, 0x3b3b3b, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x3d3d3d, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x393939, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x252525, 0x676767, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x606060, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4c4c4c, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x3d3d3d, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x616161, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x525252, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x242424, 0x767676, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x676767, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x393939, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7e7e7e, 0x292929, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4e4e4e, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x3f3f3f, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x666666, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x555555, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x222222, 0x7c7c7c, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x6d6d6d, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x393939, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x868686, 0x292929, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x515151, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x404040, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x6a6a6a, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x89948e, 0x7ba08a, 0x6eaa87, 0x6cab87, 0x6cab87, 0x6caa87, 0x6caa87, 0x6da888, 0x799f8a, 0x89938e, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x828282, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x8c9590, 0x72ab88, 0x61b883, 0x52c37f, 0x4bc87e, 0x4ac77e, 0x4ac67e, 0x49c57e, 0x48c47f, 0x47c37f, 0x47c37f, 0x46c17f, 0x46c180, 0x45c07f, 0x4cba82, 0x5cb085, 0x6fa58a, 0x8c9490, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x727272, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x383838, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x899d90, 0x69b686, 0x4ecb7e, 0x4dca7e, 0x4cc97e, 0x4bc87e, 0x4bc77f, 0x4ac67f, 0x4ac67f, 0x49c57f, 0x48c47f, 0x47c37f, 0x47c280, 0x46c180, 0x46c080, 0x45bf80, 0x44bf81, 0x43be81, 0x43bd81, 0x42bc81, 0x62ac89, 0x869a91, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x8e8e8e, 0x2a2a2a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x525252, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x86a390, 0x61be83, 0x4ecb7d, 0x4dca7d, 0x4cca7e, 0x4bc87e, 0x4bc87e, 0x4ac77e, 0x4ac67e, 0x49c57e, 0x48c47f, 0x48c37f, 0x47c37f, 0x46c17f, 0x46c180, 0x45c080, 0x45bf80, 0x44be80, 0x43bd80, 0x42bc80, 0x42bc81, 0x41ba81, 0x41ba81, 0x40b981, 0x57af87, 0x839d92, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x414141, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x6e6e6e, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x929e96, 0x68bb87, 0x4fcd7e, 0x4ecc7d, 0x4ecb7e, 0x4dca7e, 0x4cc97e, 0x4bc87e, 0x4bc77f, 0x4ac67f, 0x4ac67f, 0x49c57f, 0x48c480, 0x47c380, 0x47c280, 0x46c180, 0x46c080, 0x45bf80, 0x44bf81, 0x43be81, 0x43bd81, 0x42bc81, 0x42bb82, 0x41ba82, 0x40b982, 0x40b882, 0x3fb882, 0x3eb782, 0x5fab8b, 0x919b97, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x5c5c5c, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x868686, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x88a893, 0x55c97f, 0x4ecc7d, 0x4ecb7d, 0x4dca7d, 0x4cc97e, 0x4bc87e, 0x4bc87e, 0x4ac77e, 0x4ac67e, 0x49c57e, 0x48c47f, 0x47c37f, 0x47c27f, 0x46c17f, 0x46c180, 0x45c080, 0x44bf80, 0x44be80, 0x43bd80, 0x42bc80, 0x42bb81, 0x41ba81, 0x41ba81, 0x40b981, 0x3fb882, 0x3eb782, 0x3eb682, 0x3db582, 0x3db482, 0x45b185, 0x83a195, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x787878, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x373737, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x7bb48f, 0x4fcd7d, 0x4fcc7d, 0x4ecb7d, 0x4dcb7e, 0x4cca7e, 0x4cc97e, 0x4bc87e, 0x4bc77f, 0x4ac67f, 0x49c57f, 0x49c47f, 0x48c480, 0x47c37f, 0x47c280, 0x46c180, 0x46c080, 0x45bf80, 0x44bf81, 0x43bd81, 0x43bd81, 0x42bc81, 0x42bb82, 0x41ba82, 0x40b982, 0x3fb882, 0x3fb882, 0x3eb682, 0x3eb683, 0x3db583, 0x3cb483, 0x3cb383, 0x3bb284, 0x74a693, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x959595, 0x2a2a2a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x545454, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0x76b88e, 0x4fcd7d, 0x4ecc7d, 0x4ecb7d, 0x4dca7d, 0x4cca7e, 0x4bc87e, 0x4bc87e, 0x4ac77e, 0x4ac67f, 0x49c57e, 0x48c47f, 0x48c37f, 0x47c37f, 0x46c17f, 0x46c180, 0x45c080, 0x45bf80, 0x44be80, 0x43bd81, 0x42bc81, 0x42bc81, 0x41ba81, 0x41ba81, 0x40b981, 0x3fb882, 0x3eb782, 0x3eb682, 0x3db582, 0x3db583, 0x3cb383, 0x3bb383, 0x3ab283, 0x3ab183, 0x39b083, 0x6fa893, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0x444444, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x707070, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0x79ba90, 0x4fcd7d, 0x4fcd7e, 0x4ecb7e, 0x4dcb7e, 0x4dca7e, 0x4cc97e, 0x4bc87e, 0x4bc77f, 0x4ac67f, 0x4ac67f, 0x49c47f, 0x48c480, 0x47c380, 0x47c280, 0x46c180, 0x46c080, 0x45bf80, 0x44bf81, 0x43bd81, 0x43bd81, 0x42bc81, 0x42bb82, 0x41ba82, 0x40b982, 0x40b882, 0x3fb883, 0x3eb682, 0x3eb683, 0x3db583, 0x3cb483, 0x3cb383, 0x3bb284, 0x3ab184, 0x3ab184, 0x39af84, 0x38af85, 0x6da894, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0x5e5e5e, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x8b8b8b, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0x7db892, 0x4fcd7d, 0x4ecc7d, 0x4ecb7d, 0x4dca7d, 0x4cc97e, 0x4bc87e, 0x4bc87e, 0x4ac67e, 0x4ac67e, 0x49c57e, 0x48c47f, 0x47c37f, 0x47c27f, 0x46c17f, 0x46c180, 0x45bf80, 0x44bf80, 0x43be80, 0x43bd80, 0x42bc80, 0x42bb81, 0x41ba81, 0x40ba81, 0x3fb881, 0x3fb882, 0x3eb782, 0x3eb682, 0x3db582, 0x3cb482, 0x3cb382, 0x3bb383, 0x3ab183, 0x3ab183, 0x39b083, 0x39af84, 0x38ae84, 0x37ad84, 0x36ac84, 0x74a897, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0x7c7c7c, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x363636, 0xa7a7a7, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0x90b39d, 0x4fcd7d, 0x4fcc7d, 0x4ecb7d, 0x4dcb7e, 0x4cc97e, 0x4cc97e, 0x4bc87e, 0x4bc77f, 0x4ac67f, 0x49c57f, 0x48c47f, 0x48c480, 0x47c27f, 0x47c280, 0x46c180, 0x45c080, 0x44bf80, 0x44be81, 0x43bd81, 0x43bd81, 0x42bb81, 0x41bb82, 0x41ba82, 0x40b982, 0x3fb882, 0x3fb782, 0x3eb682, 0x3eb683, 0x3db483, 0x3cb483, 0x3bb383, 0x3bb284, 0x3ab184, 0x3ab084, 0x39af84, 0x38af84, 0x37ad84, 0x37ad85, 0x36ac85, 0x36ab85, 0x8aa99f, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0x9c9c9c, 0x2a2a2a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x545454, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xa2afa6, 0x56ca80, 0x4ecc7d, 0x4ecb7d, 0x4dca7d, 0x4cc97e, 0x4bc87e, 0x4bc87e, 0x4ac67e, 0x4ac67f, 0x49c57e, 0x48c47f, 0x47c37f, 0x47c27f, 0x46c17f, 0x46c180, 0x45bf80, 0x44bf80, 0x43be80, 0x43bd81, 0x42bc81, 0x42bb81, 0x41ba81, 0x40ba81, 0x40b881, 0x3fb882, 0x3eb782, 0x3eb682, 0x3db582, 0x3db483, 0x3cb383, 0x3bb383, 0x3ab183, 0x3ab183, 0x39b083, 0x39af84, 0x38ae84, 0x37ad84, 0x36ac84, 0x36ac85, 0x35ab85, 0x35aa85, 0x3ea988, 0xa2aba8, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0x464646, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x717171, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0x70c28e, 0x4fcc7e, 0x4ecb7e, 0x4dcb7e, 0x4cca7e, 0x4cc97e, 0x4bc87e, 0x4bc77f, 0x4ac67f, 0x49c57f, 0x48c47f, 0x48c480, 0x47c380, 0x47c280, 0x46c180, 0x45c080, 0x45bf80, 0x44be81, 0x43bd81, 0x43bd81, 0x42bc81, 0x42bb82, 0x41ba82, 0x40b982, 0x3fb882, 0x3fb783, 0x3eb682, 0x3eb683, 0x3db583, 0x3cb483, 0x3bb383, 0x3bb284, 0x3ab184, 0x3ab084, 0x39af84, 0x38af85, 0x38ae85, 0x37ad85, 0x36ac85, 0x36ab85, 0x35aa85, 0x34a986, 0x34a886, 0x63aa96, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0x636363, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x8e8e8e, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0x9bb6a5, 0x4ecc7d, 0x4dcb7d, 0x4cca7d, 0x4cc97e, 0x4bc87e, 0x4bc77e, 0x4ac67e, 0x49c67e, 0x49c57e, 0x48c47f, 0x47c37f, 0x47c27f, 0x46c17f, 0x46c080, 0x45bf80, 0x44bf80, 0x43be80, 0x43bd81, 0x42bc80, 0x42bb81, 0x41ba81, 0x40b981, 0x3fb881, 0x3fb882, 0x3eb782, 0x3eb682, 0x3db582, 0x3cb483, 0x3bb383, 0x3bb283, 0x3ab183, 0x3ab183, 0x39b083, 0x38af84, 0x37ae84, 0x37ad84, 0x36ac84, 0x36ab85, 0x35aa85, 0x34aa85, 0x34a985, 0x33a885, 0x32a785, 0x32a686, 0x9baea9, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0x818181, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x343434, 0xacacac, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0x68c68b, 0x4ecb7d, 0x4dcb7e, 0x4cc97e, 0x4cc97e, 0x4bc87e, 0x4bc77f, 0x4ac67f, 0x49c57f, 0x48c47f, 0x48c480, 0x47c27f, 0x47c280, 0x46c180, 0x45c080, 0x44bf80, 0x44be81, 0x43bd81, 0x43bd81, 0x42bb81, 0x41bb82, 0x41ba82, 0x40b982, 0x3fb882, 0x3fb782, 0x3eb682, 0x3eb683, 0x3db483, 0x3cb483, 0x3bb383, 0x3bb284, 0x3ab184, 0x3ab084, 0x39af84, 0x38af85, 0x37ad84, 0x37ad85, 0x36ac85, 0x36ab85, 0x35aa85, 0x34a986, 0x33a886, 0x33a886, 0x32a686, 0x32a687, 0x57a993, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xa3a3a3, 0x2a2a2a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x545454, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xa0baaa, 0x4dcb7d, 0x4dca7d, 0x4cc97e, 0x4bc87e, 0x4bc77e, 0x4ac67e, 0x4ac67f, 0x49c57e, 0x48c47f, 0x47c37f, 0x47c27f, 0x46c17f, 0x46c080, 0x45bf80, 0x44bf80, 0x43be80, 0x43bd81, 0x42bc81, 0x42bb81, 0x41ba81, 0x40b981, 0x3fb881, 0x3fb882, 0x3eb782, 0x3eb682, 0x3db582, 0x3cb483, 0x3bb383, 0x3bb283, 0x3ab183, 0x3ab184, 0x39b083, 0x38af84, 0x38ae84, 0x37ad84, 0x36ac84, 0x36ab85, 0x35aa85, 0x35aa85, 0x34a985, 0x33a886, 0x32a786, 0x32a686, 0x31a586, 0x31a486, 0x30a386, 0x9eb2ad, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0x484848, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x727272, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0x72c592, 0x4dcb7e, 0x4cc97e, 0x4cc97e, 0x4bc87e, 0x4bc77f, 0x4ac67f, 0x49c57f, 0x48c47f, 0x48c480, 0x47c280, 0x47c280, 0x46c180, 0x45c080, 0x45bf81, 0x44be81, 0x43bd81, 0x43bd81, 0x42bb81, 0x42bb82, 0x41ba82, 0x40b982, 0x3fb882, 0x3fb783, 0x3eb682, 0x3eb683, 0x3db483, 0x3cb483, 0x3bb383, 0x3bb284, 0x3ab184, 0x3ab084, 0x39af84, 0x38af85, 0x37ad85, 0x37ad85, 0x36ac85, 0x36ab85, 0x35aa85, 0x34a986, 0x33a886, 0x33a886, 0x32a686, 0x32a687, 0x31a587, 0x30a487, 0x30a387, 0x60aa99, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0x676767, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x909090, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xb3bbb6, 0x50c97f, 0x4cc97e, 0x4bc87e, 0x4bc77e, 0x4ac67e, 0x49c57e, 0x48c47e, 0x48c47f, 0x47c37f, 0x47c27f, 0x46c17f, 0x45c080, 0x44bf80, 0x44be80, 0x43bd80, 0x43bd81, 0x42bc80, 0x41bb81, 0x41ba81, 0x40b981, 0x3fb881, 0x3fb782, 0x3eb682, 0x3eb682, 0x3db582, 0x3cb482, 0x3bb383, 0x3bb283, 0x3ab183, 0x3ab083, 0x39af83, 0x38af84, 0x37ae84, 0x51b894, 0x8ed1b9, 0x50b694, 0x35aa85, 0x34a985, 0x33a885, 0x33a885, 0x32a785, 0x32a686, 0x31a586, 0x30a486, 0x2fa386, 0x2fa387, 0x2ea187, 0x32a289, 0xb4b9b8, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0x868686, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x313131, 0xb0b0b0, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0x92c2a5, 0x4cc97e, 0x4cc97e, 0x4bc77e, 0x4ac77f, 0x4ac67f, 0x49c57f, 0x48c47f, 0x48c380, 0x47c27f, 0x46c280, 0x46c080, 0x45c080, 0x44bf80, 0x44be81, 0x43bd81, 0x43bc81, 0x42bb81, 0x41bb82, 0x40ba82, 0x40b982, 0x3fb882, 0x3fb782, 0x3eb682, 0x3db583, 0x3cb483, 0x3cb483, 0x3bb383, 0x3bb284, 0x3ab184, 0x39b084, 0x39af84, 0x38ae85, 0x6bc3a4, 0xf4fcf6, 0xfbfffa, 0xf3fbf5, 0x54b797, 0x34a986, 0x33a886, 0x33a786, 0x32a686, 0x31a686, 0x31a587, 0x30a487, 0x2fa387, 0x2fa287, 0x2ea187, 0x2ea088, 0x86b2a9, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xa9a9a9, 0x2a2a2a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x525252, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0x74c695, 0x4bc87e, 0x4bc77e, 0x4ac67e, 0x49c67f, 0x48c47f, 0x48c47f, 0x47c37f, 0x47c27f, 0x46c17f, 0x45c080, 0x45bf80, 0x44bf80, 0x43bd80, 0x43bd81, 0x42bc81, 0x42bb81, 0x41ba81, 0x40b981, 0x3fb881, 0x3fb882, 0x3eb682, 0x3eb682, 0x3db582, 0x3cb483, 0x3bb383, 0x3bb283, 0x3ab183, 0x3ab184, 0x39af83, 0x38af84, 0x37ae84, 0x6ac3a3, 0xf4fcf5, 0xfafff8, 0xfafff8, 0xfafff8, 0x9ed7c3, 0x33a886, 0x32a786, 0x32a686, 0x31a586, 0x30a486, 0x30a386, 0x2fa387, 0x2ea187, 0x2ea187, 0x2da087, 0x2d9f88, 0x61aa9c, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0xbfbfbf, 0x494949, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x727272, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0x57c885, 0x4bc77e, 0x4ac77f, 0x4ac67f, 0x49c57f, 0x48c47f, 0x48c380, 0x47c280, 0x47c280, 0x46c080, 0x45c080, 0x44bf80, 0x44be81, 0x43bd81, 0x43bc81, 0x42bb81, 0x41bb82, 0x40b982, 0x40b982, 0x3fb882, 0x3fb783, 0x3eb683, 0x3db583, 0x3db483, 0x3cb483, 0x3bb383, 0x3bb284, 0x3ab184, 0x3ab084, 0x39af84, 0x38ae85, 0x6ac3a3, 0xf5fdf5, 0xf9fff7, 0xf9fff7, 0xf9fff7, 0xf9fff6, 0x83cbb4, 0x33a786, 0x32a686, 0x32a687, 0x31a587, 0x30a487, 0x2fa387, 0x2fa288, 0x2ea187, 0x2ea088, 0x2d9f88, 0x2c9f88, 0x3ea28f, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0x6a6a6a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x929292, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xb9c4be, 0x4bc77e, 0x4ac67e, 0x49c57e, 0x48c47e, 0x48c47f, 0x47c37f, 0x47c27f, 0x46c17f, 0x45c080, 0x44bf80, 0x44be80, 0x43bd80, 0x43bd81, 0x42bc80, 0x41bb81, 0x41ba81, 0x40b981, 0x3fb881, 0x3fb782, 0x3eb682, 0x3db682, 0x3db582, 0x3cb483, 0x3bb383, 0x3bb283, 0x3ab183, 0x39b083, 0x39af83, 0x38af84, 0x37ae84, 0x6ac2a2, 0xf1fcf2, 0xf8fff5, 0xf7fff5, 0xf7fff5, 0xf7fff4, 0xc3e8d7, 0x36a987, 0x32a686, 0x31a586, 0x30a486, 0x2fa386, 0x2fa287, 0x2ea187, 0x2ea187, 0x2da087, 0x2c9f87, 0x2c9e88, 0x2b9d88, 0x2a9c88, 0xbcc2c1, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0x8c8c8c, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x2e2e2e, 0xb4b4b4, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xa9c7b6, 0x4ac77f, 0x49c67f, 0x49c57f, 0x48c47f, 0x48c380, 0x47c280, 0x46c180, 0x46c080, 0x45c080, 0x44bf80, 0x44be81, 0x43bd81, 0x43bc81, 0x42bb81, 0x41ba82, 0x40b982, 0x40b982, 0x3fb882, 0x3fb782, 0x3eb682, 0x3db583, 0x3cb483, 0x3cb383, 0x3bb283, 0x3bb284, 0x3ab184, 0x39b084, 0x38af84, 0x38ae85, 0x69c2a1, 0xf2fcf1, 0xf7fff4, 0xf7fff4, 0xf7fff3, 0xf7fff3, 0xc4e8d7, 0x39aa89, 0x32a686, 0x31a587, 0x31a487, 0x30a487, 0x2fa387, 0x2fa287, 0x2ea187, 0x2ea088, 0x2d9f88, 0x2c9e88, 0x2b9d88, 0x2b9d89, 0x2a9c89, 0xa6beba, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xafafaf, 0x292929, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x505050, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0x99c8ad, 0x49c57f, 0x48c47f, 0x48c47f, 0x47c37f, 0x47c27f, 0x46c17f, 0x45c080, 0x45bf80, 0x44bf80, 0x43bd80, 0x43bd81, 0x42bc81, 0x41bb81, 0x4cbe88, 0x6dca9e, 0x40b882, 0x3fb882, 0x3eb682, 0x3db682, 0x3db582, 0x3cb483, 0x3bb383, 0x3bb283, 0x3ab183, 0x3ab184, 0x39af83, 0x38af84, 0x37ae84, 0x69c2a1, 0xeffcef, 0xf6fff3, 0xf5fff2, 0xf5fff2, 0xf5fff1, 0xc3e8d5, 0x39aa8a, 0x32a686, 0x31a586, 0x30a486, 0x30a386, 0x2fa387, 0x2ea187, 0x2ea187, 0x2da087, 0x2d9f88, 0x2c9e88, 0x2b9d88, 0x2a9c88, 0x2a9c89, 0x299a88, 0x93bab4, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0x4b4b4b, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x717171, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0x93caab, 0x49c57f, 0x48c47f, 0x48c380, 0x47c280, 0x47c280, 0x46c080, 0x45c081, 0x44bf81, 0x44be81, 0x43bd81, 0x43bc81, 0x42bb81, 0x63c898, 0xe7f8ec, 0xf9fff7, 0xcdeedb, 0x4bbc8b, 0x3eb683, 0x3db583, 0x3cb483, 0x3cb483, 0x3bb283, 0x3bb284, 0x3ab184, 0x39b084, 0x38af84, 0x38ae85, 0x65c1a0, 0xeffcee, 0xf5fff1, 0xf5fff1, 0xf5fff1, 0xf5fff1, 0xc2e8d5, 0x3aaa8a, 0x32a686, 0x32a687, 0x31a487, 0x30a487, 0x2fa387, 0x2fa288, 0x2ea187, 0x2ea088, 0x2d9f88, 0x2c9f88, 0x2b9d88, 0x2b9d89, 0x2a9c89, 0x2a9b89, 0x299a89, 0x89b8b1, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0x6e6e6e, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x939393, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0x8cc9a7, 0x48c47f, 0x47c27f, 0x46c27f, 0x46c17f, 0x45c080, 0x44bf80, 0x44be80, 0x43bd80, 0x43bd81, 0x42bb80, 0x41bb81, 0x40ba81, 0xb8e6cd, 0xf7fff5, 0xf7fff5, 0xf7fff4, 0xd2f1de, 0x48b989, 0x3cb483, 0x3bb383, 0x3bb283, 0x3ab183, 0x39b083, 0x39af83, 0x38af84, 0x37ad84, 0x64c19e, 0xecfbec, 0xf4fff0, 0xf3ffef, 0xf3ffef, 0xf3ffee, 0xc5ead5, 0x3aa989, 0x31a686, 0x31a586, 0x30a486, 0x2fa386, 0x2fa287, 0x2ea187, 0x2ea187, 0x2d9f87, 0x2c9f87, 0x2b9e87, 0x2b9d88, 0x2a9c88, 0x2a9b88, 0x299a88, 0x289a89, 0x279889, 0x81b5ae, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0x929292, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x2a2a2a, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0x79b493, 0x48c380, 0x47c280, 0x46c180, 0x45c080, 0x45c080, 0x44be80, 0x44be81, 0x43bd81, 0x42bc81, 0x41bb81, 0x41ba82, 0x40b982, 0xb9e7cd, 0xf7fff3, 0xf7fff3, 0xf6fff3, 0xf6fff3, 0xd0f0db, 0x47b78a, 0x3bb283, 0x3bb284, 0x3ab084, 0x39b084, 0x38af84, 0x38ae85, 0x65c19e, 0xedfceb, 0xf3ffee, 0xf3ffee, 0xf2ffee, 0xf2ffee, 0xc3ead4, 0x3aaa8a, 0x32a686, 0x31a587, 0x30a487, 0x30a487, 0x2fa287, 0x2fa287, 0x2ea187, 0x2da088, 0x2c9f88, 0x2c9e88, 0x2b9d88, 0x2b9d89, 0x2a9b89, 0x299b89, 0x299a89, 0x289989, 0x279889, 0x699f98, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0x292929, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x316749, 0x47c280, 0x46c17f, 0x45c080, 0x44bf80, 0x44be80, 0x43bd80, 0x43bd81, 0x42bb81, 0x41bb81, 0x40ba81, 0x40b981, 0x3fb881, 0x59c192, 0xebfbeb, 0xf5fff1, 0xf4fff1, 0xf4fff1, 0xf4fff0, 0xcceed8, 0x43b588, 0x39b084, 0x39af83, 0x38af84, 0x37ad84, 0x65c19e, 0xebfce9, 0xf2ffed, 0xf1ffec, 0xf1ffec, 0xf1ffec, 0xc2ead3, 0x39a98a, 0x32a686, 0x31a586, 0x30a486, 0x2fa386, 0x2fa287, 0x2ea187, 0x2ea187, 0x2d9f87, 0x2c9f88, 0x2b9e88, 0x2b9d88, 0x2a9c88, 0x2a9b89, 0x299a88, 0x289a89, 0x289889, 0x279889, 0x269789, 0x22524d, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x2f5d44, 0x46c180, 0x45c080, 0x45c081, 0x44bf81, 0x44be81, 0x43bd81, 0x42bc81, 0x42bb81, 0x41ba82, 0x40b982, 0x40b982, 0x3fb882, 0x3fb783, 0x62c498, 0xe9fbe9, 0xf4ffef, 0xf3ffef, 0xf3ffef, 0xf3ffee, 0xcbeed7, 0x42b489, 0x38af84, 0x38ae85, 0x63c09d, 0xeafce8, 0xf1ffec, 0xf1ffec, 0xf0ffeb, 0xf0ffeb, 0xc3ebd3, 0x3aaa8a, 0x32a686, 0x31a587, 0x30a487, 0x30a487, 0x2fa387, 0x2fa288, 0x2ea187, 0x2da088, 0x2d9f88, 0x2c9e88, 0x2b9d88, 0x2b9d89, 0x2a9c89, 0x2a9b89, 0x299a89, 0x28998a, 0x27988a, 0x27978a, 0x26968a, 0x224a46, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x294838, 0x45c080, 0x44bf80, 0x44be80, 0x43bd80, 0x43bc81, 0x42bb81, 0x41bb81, 0x40ba81, 0x40b981, 0x3fb881, 0x3fb782, 0x3eb682, 0x3db582, 0x3cb482, 0x60c398, 0xe7fae7, 0xf2ffed, 0xf1ffec, 0xf1ffec, 0xf1ffeb, 0xc9edd5, 0x3eb088, 0x63c09c, 0xe8fbe6, 0xefffea, 0xefffe9, 0xefffe9, 0xeeffe9, 0xc2ead1, 0x39a989, 0x31a686, 0x31a586, 0x30a486, 0x2fa386, 0x2fa287, 0x2ea187, 0x2ea087, 0x2d9f87, 0x2c9f88, 0x2b9e88, 0x2b9d88, 0x2a9c88, 0x2a9b88, 0x299a88, 0x289989, 0x279889, 0x279889, 0x269789, 0x26968a, 0x25958a, 0x213a38, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x24302a, 0x45c081, 0x44be80, 0x44be81, 0x43bd81, 0x42bc81, 0x41bb81, 0x41ba82, 0x40b982, 0x40b982, 0x3fb782, 0x3eb783, 0x3db683, 0x3db583, 0x3cb483, 0x3cb383, 0x61c299, 0xe9fce7, 0xf0ffeb, 0xf0ffeb, 0xf0ffea, 0xf0ffea, 0xc9eed5, 0xe9fce6, 0xefffe9, 0xefffe9, 0xeeffe8, 0xeeffe8, 0xc1ead0, 0x3aaa8a, 0x32a686, 0x31a587, 0x30a487, 0x30a487, 0x2fa287, 0x2fa287, 0x2ea187, 0x2da088, 0x2c9f88, 0x2c9e88, 0x2b9d88, 0x2b9d89, 0x2a9b89, 0x299b89, 0x299a89, 0x28998a, 0x279889, 0x27978a, 0x26968a, 0x25968a, 0x25948a, 0x202928, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x41b279, 0x43bd80, 0x43bc81, 0x42bb81, 0x41bb81, 0x40ba81, 0x40b982, 0x3fb882, 0x3fb782, 0x3eb682, 0x3db582, 0x3cb482, 0x3cb483, 0x3bb383, 0x3bb283, 0x3ab183, 0x60c19a, 0xe6fbe4, 0xeeffe9, 0xeeffe8, 0xeeffe8, 0xedffe7, 0xedffe7, 0xedffe7, 0xedffe6, 0xecffe6, 0xc1eacf, 0x39a98a, 0x32a686, 0x31a586, 0x30a486, 0x2fa386, 0x2fa287, 0x2ea187, 0x2ea087, 0x2d9f87, 0x2c9f88, 0x2b9e88, 0x2b9d88, 0x2a9c88, 0x2a9b89, 0x299a88, 0x289989, 0x279889, 0x279889, 0x269789, 0x26968a, 0x25958a, 0x24948a, 0x238880, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4c4c4c, 0x4c4c4c, 0x4c4c4c, 0x4c4c4c, 0x4b4b4b, 0x4b4b4b, 0x4b4b4b, 0x4b4b4b, 0x4a4a4a, 0x4a4a4a, 0x4a4a4a, 0x4a4a4a, 0x494949, 0x494949, 0x494949, 0x494949, 0x484848, 0x484848, 0x484848, 0x484848, 0x474747, 0x474747, 0x474747, 0x464646, 0x464646, 0x44976e, 0x43bd81, 0x42bc81, 0x42bb81, 0x41ba82, 0x40b982, 0x40b982, 0x3fb782, 0x3eb783, 0x3eb683, 0x3db583, 0x3cb483, 0x3cb384, 0x3bb283, 0x3ab284, 0x3ab084, 0x39b084, 0x5fc099, 0xe5fbe3, 0xedffe7, 0xedffe7, 0xedffe6, 0xedffe6, 0xecffe5, 0xecffe5, 0xc0ebce, 0x3aaa8a, 0x32a686, 0x31a587, 0x30a487, 0x30a487, 0x2fa287, 0x2fa288, 0x2ea188, 0x2da088, 0x2d9f88, 0x2c9e88, 0x2b9d88, 0x2b9d89, 0x2a9b89, 0x2a9b89, 0x299a89, 0x28998a, 0x27988a, 0x27978a, 0x26968a, 0x26968a, 0x25948a, 0x24948b, 0x2b726d, 0x393939, 0x393939, 0x383838, 0x383838, 0x383838, 0x383838, 0x373737, 0x373737, 0x373737, 0x373737, 0x363636, 0x363636, 0x363636, 0x353535, 0x353535, 0x353535, 0x353535, 0x343434, 0x343434, 0x343434, 0x343434, 0x333333, 0x333333, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc2c2c2, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0x86b9a0, 0x41bb81, 0x41ba81, 0x40b981, 0x40b981, 0x3fb881, 0x3eb782, 0x3eb682, 0x3db582, 0x3cb482, 0x3cb383, 0x3bb283, 0x3bb283, 0x3ab183, 0x39b083, 0x38af83, 0x38ae84, 0x37ad84, 0x5ebe99, 0xe3fbe0, 0xebffe4, 0xebffe3, 0xebffe3, 0xeaffe3, 0xc3eccf, 0x39a989, 0x31a586, 0x30a486, 0x30a486, 0x2fa386, 0x2fa287, 0x2ea187, 0x2da087, 0x2c9f87, 0x2c9e88, 0x2b9d88, 0x2b9d88, 0x2a9c88, 0x299b88, 0x299a88, 0x289989, 0x279889, 0x279789, 0x269689, 0x26968a, 0x25958a, 0x24948a, 0x23938a, 0x23928a, 0x5f8986, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7b7b7b, 0x7b7b7b, 0x797979, 0x797979, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xcfcfcf, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xaeb8b3, 0x43bb82, 0x41ba82, 0x40b982, 0x40b882, 0x3fb782, 0x3eb783, 0x3db583, 0x3db583, 0x3cb483, 0x3cb383, 0x3bb283, 0x3ab184, 0x39b084, 0x39b084, 0x38ae84, 0x38ae85, 0x37ad85, 0x36ac85, 0x5cbd99, 0xe3fcdf, 0xeaffe2, 0xeaffe2, 0xc2ecce, 0x3bab8a, 0x31a686, 0x31a587, 0x30a487, 0x30a387, 0x2fa287, 0x2ea287, 0x2ea087, 0x2da088, 0x2c9f88, 0x2c9e88, 0x2b9d88, 0x2b9c89, 0x2a9b89, 0x299b89, 0x289989, 0x28998a, 0x279889, 0x27978a, 0x26968a, 0x25958a, 0x24948a, 0x24948b, 0x23928b, 0x26928b, 0x808584, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x6f6f6f, 0x6f6f6f, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbebebe, 0xbcbcbc, 0xbcbcbc, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0x64b891, 0x40b982, 0x3fb882, 0x3fb782, 0x3eb682, 0x3db582, 0x3cb482, 0x3cb483, 0x3bb283, 0x3bb283, 0x3ab183, 0x39b084, 0x38af84, 0x38ae84, 0x37ad84, 0x37ad84, 0x36ab84, 0x35ab85, 0x34aa85, 0x55b996, 0x8ed3b3, 0x85cfaf, 0x38a989, 0x31a686, 0x30a486, 0x30a486, 0x2fa386, 0x2fa287, 0x2ea187, 0x2da087, 0x2d9f87, 0x2c9f88, 0x2b9d88, 0x2b9d88, 0x2a9c88, 0x2a9b89, 0x299a88, 0x289989, 0x279889, 0x279889, 0x269689, 0x26968a, 0x25958a, 0x24948a, 0x23938a, 0x23928b, 0x22918b, 0x468d89, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcbcbcb, 0xc9c9c9, 0xc9c9c9, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0x98b7a9, 0x40b882, 0x3fb782, 0x3eb783, 0x3db583, 0x3db583, 0x3cb483, 0x3cb384, 0x3bb283, 0x3ab184, 0x3ab084, 0x39b084, 0x38ae84, 0x38ae85, 0x37ad85, 0x36ac85, 0x36ab85, 0x35aa86, 0x34a986, 0x34a986, 0x33a786, 0x32a786, 0x32a686, 0x31a587, 0x30a487, 0x30a387, 0x2fa287, 0x2fa288, 0x2ea088, 0x2da088, 0x2c9f88, 0x2c9e88, 0x2b9d88, 0x2b9c89, 0x2a9b89, 0x299b89, 0x289989, 0x28998a, 0x27988a, 0x27978a, 0x26968a, 0x25958a, 0x25948a, 0x24948b, 0x23928b, 0x23928b, 0x22918b, 0x758887, 0x848484, 0x848484, 0x828282, 0x828282, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x5a5a5a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc2c2c2, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0x57b68c, 0x3db682, 0x3db582, 0x3cb482, 0x3cb383, 0x3bb283, 0x3ab283, 0x39b083, 0x39b084, 0x38af84, 0x38ae84, 0x37ad84, 0x36ac84, 0x36ab84, 0x35ab85, 0x34a985, 0x34a985, 0x33a885, 0x33a786, 0x32a686, 0x31a586, 0x30a486, 0x30a486, 0x2fa286, 0x2fa287, 0x2ea187, 0x2da087, 0x2c9f87, 0x2c9e88, 0x2b9d88, 0x2b9d88, 0x2a9b88, 0x299b88, 0x289a88, 0x289989, 0x279889, 0x279789, 0x269689, 0x25968a, 0x24948a, 0x24948a, 0x23938a, 0x23928b, 0x22918a, 0x22918b, 0x3f8e89, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7b7b7b, 0x7b7b7b, 0x797979, 0x797979, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xcfcfcf, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0x98b6a9, 0x3db583, 0x3db583, 0x3cb483, 0x3cb383, 0x3bb283, 0x3ab184, 0x39b084, 0x39af84, 0x38ae84, 0x38ae85, 0x37ad85, 0x36ac85, 0x35ab85, 0x35aa86, 0x34a985, 0x34a886, 0x33a786, 0x32a786, 0x31a686, 0x31a587, 0x30a487, 0x30a387, 0x2fa287, 0x2ea187, 0x2ea088, 0x2da088, 0x2c9f88, 0x2c9e88, 0x2b9d88, 0x2b9c89, 0x2a9b89, 0x299a89, 0x289989, 0x28998a, 0x27988a, 0x27978a, 0x26968a, 0x25958a, 0x24948a, 0x24938b, 0x23928b, 0x23928b, 0x22918b, 0x23918b, 0x738887, 0x868686, 0x848484, 0x848484, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x6f6f6f, 0x6f6f6f, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbebebe, 0xbebebe, 0xbcbcbc, 0xbcbcbc, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0x5fb491, 0x3cb383, 0x3bb283, 0x3ab283, 0x3ab183, 0x39b084, 0x38af84, 0x38ae84, 0x37ad84, 0x37ac85, 0x36ab84, 0x35ab85, 0x34aa85, 0x34a985, 0x33a885, 0x33a786, 0x32a686, 0x31a586, 0x30a486, 0x30a487, 0x2fa387, 0x2fa287, 0x2ea187, 0x2da087, 0x2c9f87, 0x2c9e88, 0x2b9d88, 0x2b9d88, 0x2a9c88, 0x299b89, 0x299a89, 0x289989, 0x279889, 0x279789, 0x269689, 0x25968a, 0x25958a, 0x24948a, 0x23938a, 0x23928b, 0x22918b, 0x22918b, 0x22918b, 0x498d89, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcbcbcb, 0xcbcbcb, 0xc9c9c9, 0xc9c9c9, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xa4b4ad, 0x40b385, 0x3bb284, 0x3ab184, 0x39b084, 0x39b084, 0x38ae84, 0x38ae85, 0x37ad85, 0x36ac85, 0x35ab85, 0x35aa86, 0x34a986, 0x34a986, 0x33a786, 0x32a786, 0x32a686, 0x31a587, 0x30a487, 0x30a387, 0x2fa287, 0x2fa288, 0x2ea088, 0x2da088, 0x2c9f88, 0x2c9e89, 0x2b9d88, 0x2b9c89, 0x2a9b89, 0x299b89, 0x289989, 0x28998a, 0x27988a, 0x27978a, 0x26968a, 0x25958b, 0x24948b, 0x24948b, 0x23928b, 0x23928b, 0x22918b, 0x22918b, 0x29918b, 0x7f8988, 0x878787, 0x868686, 0x848484, 0x848484, 0x828282, 0x828282, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x5a5a5a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc2c2c2, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0x89b2a2, 0x39b083, 0x39b084, 0x38af84, 0x38ae84, 0x37ad84, 0x36ac84, 0x35ab84, 0x35aa85, 0x34a985, 0x34a985, 0x33a885, 0x32a786, 0x31a686, 0x31a586, 0x30a486, 0x30a386, 0x2fa286, 0x2ea287, 0x2ea187, 0x2da087, 0x2c9f87, 0x2c9e88, 0x2b9d88, 0x2b9c88, 0x2a9b88, 0x299b88, 0x289a88, 0x289989, 0x279889, 0x279789, 0x269689, 0x25958a, 0x24948a, 0x24948a, 0x23938a, 0x23928b, 0x22918a, 0x22918b, 0x22918b, 0x22918b, 0x6e8a89, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7b7b7b, 0x7b7b7b, 0x797979, 0x797979, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xcfcfcf, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0x72b19a, 0x39af84, 0x38ae84, 0x38ae85, 0x37ac85, 0x36ac85, 0x35ab85, 0x35aa86, 0x34a985, 0x34a886, 0x33a786, 0x32a786, 0x31a586, 0x31a587, 0x30a487, 0x30a387, 0x2fa287, 0x2ea188, 0x2da088, 0x2da088, 0x2c9e88, 0x2c9e88, 0x2b9d88, 0x2a9c89, 0x299b89, 0x299a89, 0x289989, 0x28998a, 0x27978a, 0x26978a, 0x26968a, 0x25958a, 0x24948a, 0x24938b, 0x23928b, 0x23928b, 0x22918b, 0x22918b, 0x22918b, 0x5d8d8b, 0x888888, 0x888888, 0x868686, 0x393939, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4d4d4d, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x6f6f6f, 0x6f6f6f, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbebebe, 0xbcbcbc, 0xbcbcbc, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0x6daf98, 0x37ad84, 0x36ac85, 0x35ab84, 0x35aa85, 0x34a985, 0x34a985, 0x33a885, 0x32a786, 0x32a686, 0x31a586, 0x30a486, 0x30a387, 0x2fa287, 0x2fa287, 0x2ea187, 0x2da087, 0x2c9f87, 0x2c9e88, 0x2b9d88, 0x2b9c88, 0x2a9b88, 0x299b89, 0x289a89, 0x289989, 0x279889, 0x279789, 0x269689, 0x25958a, 0x24948a, 0x24948a, 0x23938a, 0x23928b, 0x22918b, 0x22918b, 0x22918b, 0x22918b, 0x568d8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x393939, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4c4c4c, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcbcbcb, 0xc9c9c9, 0xc9c9c9, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb2b2b2, 0x73ae9a, 0x36ac85, 0x35ab85, 0x35aa86, 0x34a986, 0x34a886, 0x33a786, 0x32a786, 0x31a686, 0x31a587, 0x30a487, 0x30a387, 0x2fa287, 0x2ea188, 0x2da088, 0x2da088, 0x2c9f88, 0x2c9e89, 0x2b9d88, 0x2a9c89, 0x2a9b89, 0x299a89, 0x289989, 0x28998a, 0x27988a, 0x27978a, 0x26968a, 0x25958b, 0x24948b, 0x24938b, 0x23928b, 0x23928b, 0x22918b, 0x22918b, 0x22918b, 0x588f8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x393939, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4d4d4d, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x5a5a5a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc2c2c2, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0x7aad9d, 0x34a985, 0x34a985, 0x33a785, 0x32a786, 0x31a686, 0x31a586, 0x30a486, 0x30a387, 0x2fa286, 0x2ea287, 0x2ea187, 0x2da087, 0x2c9f87, 0x2c9e88, 0x2b9d88, 0x2b9c88, 0x2a9b88, 0x299b88, 0x289a89, 0x289989, 0x279889, 0x279789, 0x269689, 0x25958a, 0x24948a, 0x24948a, 0x23938a, 0x23928b, 0x22918b, 0x22918b, 0x22918b, 0x22918b, 0x608e8b, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x393939, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4c4c4c, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xcfcfcf, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0x90ada4, 0x3da989, 0x33a786, 0x32a686, 0x31a586, 0x31a587, 0x30a487, 0x30a387, 0x2fa287, 0x2ea188, 0x2da088, 0x2d9f88, 0x2c9e88, 0x2c9e88, 0x2b9d88, 0x2a9c89, 0x299b89, 0x299a89, 0x289989, 0x28988a, 0x27978a, 0x26978a, 0x25968a, 0x25958b, 0x24948a, 0x24938b, 0x23928b, 0x22918b, 0x22918b, 0x22918b, 0x2c918b, 0x758f8d, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x868686, 0x393939, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4d4d4d, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x6f6f6f, 0x6f6f6f, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbebebe, 0xbebebe, 0xbcbcbc, 0xbcbcbc, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xa2acaa, 0x5fa894, 0x31a586, 0x30a486, 0x30a387, 0x2fa287, 0x2fa287, 0x2ea087, 0x2da087, 0x2c9f87, 0x2c9e88, 0x2b9d88, 0x2b9c88, 0x2a9b88, 0x299b89, 0x289a89, 0x289989, 0x279889, 0x27978a, 0x269689, 0x25958a, 0x24948a, 0x24948a, 0x23938a, 0x23928b, 0x22918b, 0x22918b, 0x22918b, 0x4c918d, 0x868e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x393939, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4c4c4c, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcbcbcb, 0xcbcbcb, 0xc9c9c9, 0xc9c9c9, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb2b2b2, 0xb0b0b0, 0xb0b0b0, 0xaeaeae, 0xadadad, 0xacacac, 0x8eaaa3, 0x4fa590, 0x30a387, 0x2fa287, 0x2ea188, 0x2da088, 0x2d9f88, 0x2c9e88, 0x2c9e89, 0x2b9d88, 0x2a9c89, 0x2a9b89, 0x299a89, 0x289989, 0x28988a, 0x27978a, 0x26978a, 0x26968a, 0x25958b, 0x24948b, 0x24938b, 0x23928b, 0x22918b, 0x22918b, 0x43928d, 0x7b9190, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x848484, 0x848484, 0x828282, 0x828282, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x5a5a5a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc2c2c2, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xababab, 0xababab, 0xa9a9a9, 0x93a8a3, 0x5ea394, 0x36a08a, 0x2c9f87, 0x2c9e88, 0x2b9d88, 0x2a9c88, 0x299b88, 0x299a89, 0x289989, 0x289989, 0x279889, 0x269789, 0x269689, 0x25958a, 0x24948a, 0x24938a, 0x23928a, 0x23928b, 0x2d918b, 0x53928f, 0x819291, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7b7b7b, 0x7b7b7b, 0x797979, 0x797979, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xcfcfcf, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0x89a49f, 0x62a195, 0x389d8b, 0x2a9c89, 0x299b89, 0x299a89, 0x289989, 0x28988a, 0x27978a, 0x26968a, 0x25958a, 0x25958a, 0x24948a, 0x36948d, 0x599491, 0x7d9594, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x888888, 0x888888, 0x868686, 0x868686, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x6f6f6f, 0x6f6f6f, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbebebe, 0xbcbcbc, 0xbcbcbc, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xa9a9a9, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa5a5a5, 0xa3a3a3, 0x9ba2a1, 0x8ea09d, 0x809e9a, 0x749c97, 0x689b95, 0x679a94, 0x729a96, 0x7e9997, 0x889998, 0x949998, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcbcbcb, 0xc9c9c9, 0xc9c9c9, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb2b2b2, 0xb0b0b0, 0xb0b0b0, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x9b9b9b, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x848484, 0x848484, 0x828282, 0x828282, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x5a5a5a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc2c2c2, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xa9a9a9, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x929292, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7b7b7b, 0x7b7b7b, 0x797979, 0x797979, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xc6c6c6, 0xd1d1d1, 0xcfcfcf, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x9b9b9b, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x868686, 0x868686, 0x848484, 0x848484, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x6f6f6f, 0x6f6f6f, 0x6d6d6d, 0x565656, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x9a9a9a, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbebebe, 0xbebebe, 0xbcbcbc, 0xbcbcbc, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa5a5a5, 0xa3a3a3, 0xa3a3a3, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x464646, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x797979, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcbcbcb, 0xcbcbcb, 0xc9c9c9, 0xc9c9c9, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb2b2b2, 0xb0b0b0, 0xb0b0b0, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x9b9b9b, 0x999999, 0x999999, 0x979797, 0x979797, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x848484, 0x848484, 0x828282, 0x828282, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x353535, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xbfbfbf, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc2c2c2, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xababab, 0xababab, 0xa9a9a9, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x949494, 0x949494, 0x929292, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7b7b7b, 0x7b7b7b, 0x797979, 0x797979, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x464646, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x464646, 0xcfcfcf, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0x9f9f9f, 0x9f9f9f, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x9b9b9b, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x888888, 0x888888, 0x868686, 0x868686, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x6f6f6f, 0x676767, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x7f7f7f, 0xbababa, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbebebe, 0xbcbcbc, 0xbcbcbc, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xa9a9a9, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa5a5a5, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x626262, 0x484848, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x3a3a3a, 0x4b4b4b, 0x4b4b4b, 0x4a4a4a, 0x4a4a4a, 0x4a4a4a, 0x4a4a4a, 0x494949, 0x494949, 0x494949, 0x494949, 0x484848, 0x484848, 0x484848, 0x484848, 0x474747, 0x474747, 0x474747, 0x464646, 0x464646, 0x464646, 0x464646, 0x454545, 0x454545, 0x454545, 0x454545, 0x444444, 0x444444, 0x444444, 0x444444, 0x434343, 0x434343, 0x434343, 0x424242, 0x424242, 0x424242, 0x424242, 0x414141, 0x414141, 0x414141, 0x414141, 0x404040, 0x404040, 0x404040, 0x404040, 0x3f3f3f, 0x3f3f3f, 0x3f3f3f, 0x3f3f3f, 0x3e3e3e, 0x3e3e3e, 0x3e3e3e, 0x3e3e3e, 0x3d3d3d, 0x3d3d3d, 0x3d3d3d, 0x3d3d3d, 0x3c3c3c, 0x3c3c3c, 0x3c3c3c, 0x3c3c3c, 0x3b3b3b, 0x3b3b3b, 0x3b3b3b, 0x3a3a3a, 0x3a3a3a, 0x3a3a3a, 0x3a3a3a, 0x393939, 0x393939, 0x393939, 0x393939, 0x383838, 0x383838, 0x383838, 0x383838, 0x373737, 0x373737, 0x373737, 0x373737, 0x363636, 0x363636, 0x363636, 0x353535, 0x353535, 0x353535, 0x353535, 0x272727, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020 -}; \ No newline at end of file diff --git a/dev/ZBAKit/BootKit/Rsrc/zka_no_disk.rsrc b/dev/ZBAKit/BootKit/Rsrc/zka_no_disk.rsrc deleted file mode 100644 index 31689e63..00000000 --- a/dev/ZBAKit/BootKit/Rsrc/zka_no_disk.rsrc +++ /dev/null @@ -1,116 +0,0 @@ -#define ZKA_NO_DISK_HEIGHT 110 -#define ZKA_NO_DISK_WIDTH 110 - -// array size is 36300 -static const unsigned int zka_no_disk[] = { - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x333333, 0x565656, 0x636363, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6d6d6d, 0x6a6a6a, 0x5f5f5f, 0x4d4d4d, 0x2b2b2b, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x464646, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x707070, 0x6a6a6a, 0x3b3b3b, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x3d3d3d, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x727272, 0x393939, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x252525, 0x676767, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x757575, 0x606060, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4c4c4c, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x777777, 0x787878, 0x777777, 0x777777, 0x3d3d3d, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x616161, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x7a7a7a, 0x7b7b7b, 0x525252, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x242424, 0x767676, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x7c7c7c, 0x7d7d7d, 0x7c7c7c, 0x7c7c7c, 0x676767, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x393939, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7f7f7f, 0x808080, 0x7e7e7e, 0x292929, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4e4e4e, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x828282, 0x818181, 0x828282, 0x828282, 0x3f3f3f, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x666666, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x858585, 0x555555, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x222222, 0x7c7c7c, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x868686, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x878787, 0x6d6d6d, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x393939, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x8a8a8a, 0x868686, 0x292929, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x515151, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x8c8c8c, 0x404040, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x6a6a6a, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x8f8f8f, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x828282, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0xa69a77, 0xbea35a, 0xc0a458, 0xa69a77, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x919191, 0x727272, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x383838, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0xab9d77, 0xebb626, 0xffbe0c, 0xffbd0c, 0xffbd0c, 0xffbc0c, 0xecb524, 0xaa9c78, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x949494, 0x8e8e8e, 0x2a2a2a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x525252, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0xa49b83, 0xfcbc0f, 0xfebc0c, 0xffbc0c, 0xfebc0b, 0xffbb0c, 0xfebb0b, 0xffba0b, 0xfcb90e, 0xa49b83, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x969696, 0x414141, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x6e6e6e, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0xe8b52c, 0xffbd0c, 0xffbc0c, 0xffbc0c, 0xffbb0c, 0xffbb0c, 0xffba0b, 0xffba0c, 0xffb90b, 0xe8b22c, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x999999, 0x5c5c5c, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x868686, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0xbca66b, 0xfebb0b, 0xffbb0b, 0xfeba0b, 0xffba0b, 0xfeba0b, 0xffb90b, 0xfeb80b, 0xffb80b, 0xfeb80b, 0xffb70b, 0xbda46a, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x9b9b9b, 0x787878, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x373737, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0xa09f9b, 0xf3b81e, 0xffbb0c, 0xffbb0c, 0xffba0b, 0xffba0c, 0xffb90b, 0xffb90b, 0xffb80b, 0xffb80b, 0xffb70b, 0xffb70b, 0xf3b31d, 0xa09e9b, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x9e9e9e, 0x959595, 0x2a2a2a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x545454, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xcbac5c, 0xffba0b, 0xfeba0b, 0xffb90b, 0xfeb90b, 0xffb80b, 0xfeb80b, 0xffb70b, 0xfeb70a, 0xffb60b, 0xfeb60a, 0xffb60a, 0xfeb50a, 0xccaa5b, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0xa0a0a0, 0xa1a1a1, 0x444444, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x707070, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xaaa699, 0xfab914, 0xffba0c, 0xffb90b, 0xffb90c, 0xffb80b, 0xffb80b, 0xffb70b, 0xffb70b, 0xffb60b, 0xffb60b, 0xffb50b, 0xffb50b, 0xffb40a, 0xfab313, 0xa9a498, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0xa3a3a3, 0xa4a4a4, 0x5e5e5e, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x8b8b8b, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xd9b14c, 0xfeb80b, 0xfeb80b, 0xfeb70b, 0xffb70b, 0xfeb60a, 0xfeb60a, 0xfeb60a, 0xffb50a, 0xfeb50a, 0xfeb40a, 0xfeb40a, 0xfeb30a, 0xfeb30a, 0xfeb20a, 0xd9ac4a, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0xa5a5a5, 0xa6a6a6, 0x7c7c7c, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x363636, 0xa7a7a7, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xb5aa91, 0xfeb80d, 0xffb80b, 0xffb80b, 0xffb70b, 0xffb70b, 0xffb60b, 0xffb60b, 0xffb50a, 0xffb50b, 0xffb40a, 0xffb40a, 0xffb30a, 0xffb30a, 0xffb20a, 0xffb20a, 0xfeb10c, 0xb5aa92, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0xa8a8a8, 0xa9a9a9, 0x9c9c9c, 0x2a2a2a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x545454, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xe6b43a, 0xffb70b, 0xfeb60a, 0xffb60b, 0xfeb60a, 0xffb50a, 0xfeb50a, 0xffb40a, 0xfeb40a, 0xffb40a, 0xfeb30a, 0xffb20a, 0xfeb20a, 0xffb20a, 0xfeb109, 0xffb109, 0xfeb009, 0xe6ae39, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0xababab, 0x464646, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x717171, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xc2b085, 0xffb70b, 0xffb70b, 0xffb60b, 0xffb60b, 0xffb50b, 0xffb50b, 0xffb40a, 0xffb40b, 0xffb30a, 0xffb30a, 0xffb20a, 0xffb20a, 0xffb10a, 0xffb10a, 0xffb00a, 0xffb00a, 0xffaf0a, 0xffaf0a, 0xc2ae85, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0xaeaeae, 0x636363, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x8e8e8e, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb1b0af, 0xf1b526, 0xfeb50a, 0xffb50a, 0xfeb40a, 0xfeb40a, 0xfeb40a, 0xffb30a, 0xfeb30a, 0xfeb20a, 0xfeb209, 0xfeb10a, 0xfeb109, 0xfeb009, 0xfeb009, 0xfeb009, 0xfeaf09, 0xfeaf09, 0xfeae09, 0xfeae09, 0xf1ad25, 0xb1b0af, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0xb0b0b0, 0x818181, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x343434, 0xacacac, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xd0b472, 0xffb60b, 0xffb50a, 0xffb50b, 0xffb40a, 0xffb40a, 0xffb30a, 0xffb30a, 0xffb20a, 0xdc9e15, 0x90712e, 0x91712e, 0xdd9c15, 0xffb00a, 0xffaf09, 0xffaf0a, 0xffae09, 0xffae09, 0xffad09, 0xffad09, 0xffac09, 0xd0b071, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xb3b3b3, 0xa3a3a3, 0x2a2a2a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x545454, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb8b5ae, 0xf8b519, 0xffb40a, 0xfeb40a, 0xffb30a, 0xfeb30a, 0xffb20a, 0xfeb20a, 0xffb10a, 0xfeb109, 0x564f40, 0x444444, 0x444444, 0x564e3e, 0xfeaf09, 0xfeae09, 0xffae09, 0xfead09, 0xfead09, 0xfeac08, 0xffac09, 0xfeab08, 0xf8ac17, 0xb8b5ae, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0xb5b5b5, 0x484848, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x727272, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xdcb660, 0xffb40a, 0xffb40b, 0xffb30a, 0xffb30a, 0xffb20a, 0xffb20a, 0xffb10a, 0xffb10a, 0xeba510, 0x444444, 0x434343, 0x434343, 0x424242, 0xeca30f, 0xffad09, 0xffad09, 0xffac09, 0xffac09, 0xffac09, 0xffab09, 0xffab09, 0xffaa09, 0xdcb15e, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0xb8b8b8, 0x676767, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x909090, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xc1b9a8, 0xfcb30f, 0xfeb20a, 0xfeb20a, 0xfeb109, 0xfeb10a, 0xfeb009, 0xfeb009, 0xfeb009, 0xfeaf09, 0xe6a110, 0x424242, 0x424242, 0x414141, 0x414141, 0xe69e10, 0xfeac08, 0xfeac08, 0xfeab08, 0xfeab08, 0xfeaa08, 0xfeaa08, 0xfea908, 0xfea908, 0xfca90d, 0xc1b8a8, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0xbababa, 0x868686, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x313131, 0xb0b0b0, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xe6b74c, 0xffb30a, 0xffb20a, 0xffb20a, 0xffb10a, 0xffb10a, 0xffb009, 0xffb00a, 0xffaf09, 0xffaf09, 0xe7a010, 0x414141, 0x414141, 0x414141, 0x404040, 0xe79e10, 0xffab09, 0xffab09, 0xffaa08, 0xffaa09, 0xffa908, 0xffa908, 0xffa808, 0xffa808, 0xffa808, 0xe7af4b, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xbdbdbd, 0xa9a9a9, 0x2a2a2a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x525252, 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, 0xcbbc9b, 0xfeb209, 0xffb10a, 0xfeb109, 0xffb009, 0xfeb009, 0xffaf09, 0xfeaf09, 0xfeae09, 0xfeae09, 0xffae09, 0xe69f10, 0x404040, 0x3f3f3f, 0x3f3f3f, 0x3e3e3e, 0xe69d0f, 0xfeaa08, 0xfeaa08, 0xfea908, 0xfea908, 0xfea808, 0xfea808, 0xfea707, 0xfea708, 0xfea607, 0xfea607, 0xcbba9b, 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, 0x494949, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x727272, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xf1b533, 0xffb10a, 0xffb10a, 0xffb00a, 0xffb00a, 0xffaf09, 0xffaf0a, 0xffae09, 0xffae09, 0xffad09, 0xffad09, 0xe79e10, 0x3f3f3f, 0x3e3e3e, 0x3e3e3e, 0x3d3d3d, 0xe79c10, 0xffaa08, 0xffa909, 0xffa908, 0xffa808, 0xffa808, 0xffa708, 0xffa708, 0xffa608, 0xffa608, 0xffa608, 0xf1ab31, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0xc2c2c2, 0x6a6a6a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x929292, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xd6be89, 0xfeb009, 0xfeaf09, 0xfeaf09, 0xfeae09, 0xfeae09, 0xfeae09, 0xfead09, 0xfead08, 0xfeac09, 0xfeac08, 0xfeab08, 0xe69d0f, 0x3d3d3d, 0x3c3c3c, 0x3c3c3c, 0x3b3b3b, 0xe69b0e, 0xfea808, 0xfea808, 0xfea707, 0xfea708, 0xfea607, 0xfea607, 0xfea507, 0xfea507, 0xfea407, 0xfea407, 0xfea307, 0xd6ba89, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0xc4c4c4, 0x8c8c8c, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x2e2e2e, 0xb4b4b4, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc9c8c6, 0xf8b321, 0xffb00a, 0xffaf09, 0xffaf09, 0xffae09, 0xffae09, 0xffad09, 0xffad09, 0xffac09, 0xffac09, 0xffab09, 0xffab09, 0xe79c0f, 0x3c3c3c, 0x3c3c3c, 0x3b3b3b, 0x3b3b3b, 0xe69a0e, 0xffa708, 0xffa708, 0xffa608, 0xffa608, 0xffa608, 0xffa508, 0xfea507, 0xffa407, 0xffa407, 0xffa307, 0xfea307, 0xf8a71f, 0xc8c7c5, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xc7c7c7, 0xc7c7c7, 0xc8c8c8, 0xc7c7c7, 0xafafaf, 0x292929, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x505050, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xe1be76, 0xfeaf09, 0xfeae09, 0xfeae09, 0xffad09, 0xfead09, 0xfeac09, 0xfeac08, 0xffac09, 0xfeab08, 0xfeab08, 0xfeaa08, 0xfeaa08, 0xe69b0e, 0x3b3b3b, 0x3a3a3a, 0x3a3a3a, 0x393939, 0xe5990e, 0xfea607, 0xfea607, 0xfea507, 0xfea507, 0xfea407, 0xfea407, 0xfea307, 0xfea307, 0xfea207, 0xfea207, 0xfea106, 0xfea107, 0xe0b774, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0xc9c9c9, 0xcacaca, 0x4b4b4b, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x717171, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xd0cbc2, 0xfbb117, 0xffae09, 0xffae09, 0xffad09, 0xffad09, 0xffac09, 0xffac09, 0xffab09, 0xffab09, 0xffaa08, 0xffaa09, 0xffa908, 0xffa909, 0xe69a0e, 0x3a3a3a, 0x393939, 0x393939, 0x383838, 0xe6980e, 0xffa608, 0xffa508, 0xffa507, 0xffa408, 0xffa407, 0xffa407, 0xffa307, 0xffa307, 0xffa207, 0xffa207, 0xffa107, 0xffa107, 0xfba315, 0xd0cbc2, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0xcdcdcd, 0xcdcdcd, 0xcccccc, 0xcdcdcd, 0x6e6e6e, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x939393, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xe9bc60, 0xfead09, 0xfeac08, 0xfeac09, 0xfeac08, 0xfeab08, 0xfeab08, 0xfeaa08, 0xfeaa08, 0xfea908, 0xfea908, 0xfea808, 0xfea808, 0xfea808, 0xe5990d, 0x383838, 0x373737, 0x373737, 0x363636, 0xe5970d, 0xfea407, 0xfea407, 0xfea307, 0xfea307, 0xfea206, 0xfea207, 0xfea106, 0xfea106, 0xfea006, 0xfea006, 0xfe9f06, 0xfe9f06, 0xfe9e06, 0xe9b45f, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0xcecece, 0xcfcfcf, 0x929292, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x2a2a2a, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xb0a691, 0xfdad0c, 0xffad09, 0xffac09, 0xffac09, 0xffab09, 0xffab09, 0xffaa08, 0xffaa08, 0xffa908, 0xffa908, 0xfea808, 0xffa808, 0xffa708, 0xffa708, 0xe5980e, 0x373737, 0x363636, 0x363636, 0x353535, 0xe6960d, 0xfea407, 0xffa307, 0xfea307, 0xffa207, 0xfea207, 0xffa107, 0xfea106, 0xffa007, 0xfea006, 0xffa007, 0xfe9f06, 0xff9f06, 0xfe9e06, 0xfd9e09, 0xb0a491, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0xa5a5a5, 0x292929, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xb88010, 0xfeac08, 0xffab09, 0xfeab08, 0xfeaa08, 0xfeaa08, 0xfea908, 0xfea908, 0xfea808, 0xfea808, 0xfea808, 0xfea707, 0xfea708, 0xfea607, 0xfea607, 0xf8a208, 0x3a3834, 0x353535, 0x353535, 0x393733, 0xf89f08, 0xfea207, 0xfea207, 0xfea106, 0xfea106, 0xfea006, 0xfea006, 0xfe9f06, 0xfe9f06, 0xfe9e06, 0xfe9e06, 0xfe9d06, 0xfe9d06, 0xfe9d05, 0xfe9c06, 0xb7740e, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x523f1b, 0xffac09, 0xffab09, 0xffab09, 0xffaa08, 0xffaa09, 0xffa908, 0xffa908, 0xffa808, 0xffa808, 0xffa708, 0xffa708, 0xffa608, 0xffa608, 0xffa508, 0xffa508, 0xffa407, 0xa9751b, 0x353434, 0x353533, 0xab7519, 0xffa207, 0xffa207, 0xffa107, 0xffa107, 0xffa007, 0xffa007, 0xffa007, 0xfe9f06, 0xff9f06, 0xff9e06, 0xff9e06, 0xfe9d06, 0xff9d06, 0xff9c06, 0xff9c06, 0xfe9b06, 0x523b1a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd38f0d, 0xfeaa08, 0xfeaa08, 0xfea908, 0xfea908, 0xfea808, 0xfea808, 0xfea708, 0xfea707, 0xfea607, 0xfea607, 0xfea607, 0xfea507, 0xfea507, 0xfea407, 0xfea407, 0xfea307, 0xfea307, 0xe9970a, 0xea970b, 0xfea106, 0xfea106, 0xfea006, 0xfea006, 0xfe9f06, 0xfe9f06, 0xfe9e06, 0xfe9e06, 0xfe9d05, 0xfe9d06, 0xfe9c05, 0xfe9c06, 0xfe9b05, 0xfe9b05, 0xfe9a05, 0xfe9a05, 0xfe9905, 0xd3810a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x715318, 0xffaa08, 0xffaa08, 0xffa908, 0xffa908, 0xffa808, 0xffa808, 0xffa708, 0xffa708, 0xffa608, 0xffa608, 0xffa507, 0xffa508, 0xfea407, 0xffa407, 0xffa307, 0xffa307, 0xfea207, 0xffa207, 0xffa207, 0xffa107, 0xfea106, 0xffa007, 0xfea006, 0xff9f07, 0xfe9f06, 0xff9e06, 0xfe9e06, 0xff9e06, 0xfe9d06, 0xff9d06, 0xfe9c06, 0xff9c06, 0xfe9b05, 0xff9b06, 0xfe9a05, 0xff9a05, 0xfe9905, 0xff9905, 0x704b16, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x27241f, 0xe89b0b, 0xfea908, 0xfea808, 0xfea808, 0xfea708, 0xfea707, 0xfea608, 0xfea607, 0xfea607, 0xfea507, 0xfea507, 0xfea407, 0xfea407, 0xfea307, 0xfea307, 0xfea207, 0xfea207, 0xfea106, 0xfea106, 0xfea006, 0xfea006, 0xfe9f06, 0xfe9f06, 0xfe9e06, 0xfe9e06, 0xfe9d06, 0xfe9d06, 0xfe9c05, 0xfe9c06, 0xfe9b05, 0xfe9b05, 0xfe9b05, 0xfe9a05, 0xfe9a05, 0xfe9905, 0xfe9905, 0xfe9805, 0xfe9804, 0xfe9705, 0xe78b07, 0x27241f, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4c4c4c, 0x4c4c4c, 0x4c4c4c, 0x4c4c4c, 0x4b4b4b, 0x4b4b4b, 0x4b4b4b, 0x4b4b4b, 0x4a4a4a, 0x4a4a4a, 0x4a4a4a, 0x4a4a4a, 0x494949, 0x494949, 0x494949, 0x494949, 0x484848, 0x484848, 0x484848, 0x484848, 0x474747, 0x474747, 0x474747, 0x464646, 0x464646, 0x464646, 0x464646, 0x454545, 0x9f7627, 0xffa908, 0xffa808, 0xffa808, 0xffa708, 0xffa708, 0xffa608, 0xffa608, 0xffa508, 0xffa508, 0xffa407, 0xffa408, 0xffa307, 0xffa307, 0xffa207, 0xffa207, 0xffa207, 0xffa107, 0xffa107, 0xffa007, 0xffa007, 0xff9f07, 0xff9f06, 0xff9e06, 0xff9e06, 0xff9e06, 0xff9d06, 0xff9d06, 0xff9c06, 0xff9c06, 0xfe9b06, 0xff9b06, 0xff9a05, 0xff9a06, 0xfe9905, 0xff9905, 0xff9805, 0xff9805, 0xfe9705, 0xff9705, 0xfe9605, 0x996620, 0x3a3a3a, 0x3a3a3a, 0x3a3a3a, 0x393939, 0x393939, 0x393939, 0x393939, 0x383838, 0x383838, 0x383838, 0x383838, 0x373737, 0x373737, 0x373737, 0x373737, 0x363636, 0x363636, 0x363636, 0x353535, 0x353535, 0x353535, 0x353535, 0x343434, 0x343434, 0x343434, 0x343434, 0x333333, 0x333333, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc2c2c2, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xbbb4a6, 0xfba80e, 0xfea708, 0xfea607, 0xfea607, 0xfea607, 0xfea507, 0xfea507, 0xfea407, 0xfea407, 0xfea307, 0xfea307, 0xfea207, 0xfea206, 0xfea207, 0xfea106, 0xfea106, 0xfea006, 0xfea006, 0xfe9f06, 0xe4910b, 0xa97016, 0xa97016, 0xe69009, 0xfe9d06, 0xfe9c05, 0xfe9c05, 0xfe9b05, 0xfe9b05, 0xfe9a05, 0xfe9a05, 0xfe9905, 0xfe9905, 0xfe9805, 0xfe9805, 0xfe9704, 0xfe9704, 0xfe9704, 0xfe9604, 0xfe9604, 0xfe9504, 0xfe9504, 0xf99409, 0x92897d, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7b7b7b, 0x7b7b7b, 0x797979, 0x797979, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xcfcfcf, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0xe2ad4c, 0xffa708, 0xffa708, 0xfea608, 0xffa608, 0xffa507, 0xffa508, 0xfea407, 0xffa407, 0xfea307, 0xffa307, 0xfea207, 0xffa207, 0xfea107, 0xffa107, 0xfea006, 0xffa007, 0xfe9f06, 0xff9f06, 0xab7115, 0x2f2e2d, 0x2c2c2c, 0x2c2c2c, 0x2d2c2b, 0xac7014, 0xfe9c06, 0xff9b06, 0xfe9b05, 0xff9a06, 0xfe9a05, 0xff9a05, 0xfe9905, 0xff9905, 0xfe9805, 0xff9805, 0xfe9705, 0xff9705, 0xfe9605, 0xff9605, 0xfe9504, 0xfe9504, 0xfe9404, 0xff9404, 0xcf8f38, 0x888888, 0x868686, 0x868686, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x6f6f6f, 0x6f6f6f, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbebebe, 0xbcbcbc, 0xbcbcbc, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xc2b399, 0xfea609, 0xfea607, 0xfea507, 0xfea507, 0xfea407, 0xfea407, 0xfea407, 0xfea307, 0xfea307, 0xfea206, 0xfea207, 0xfea106, 0xfea106, 0xfea006, 0xfea006, 0xfe9f06, 0xfe9f06, 0xfe9e06, 0xf99b07, 0x322f2a, 0x2b2b2b, 0x2b2b2b, 0x2a2a2a, 0x292929, 0x332f28, 0xfc9905, 0xfe9a05, 0xfe9905, 0xfe9905, 0xfe9805, 0xfe9805, 0xfe9704, 0xfe9705, 0xfe9704, 0xfe9604, 0xfe9604, 0xfe9504, 0xfe9504, 0xfe9404, 0xfe9404, 0xfe9304, 0xfe9304, 0xfe9304, 0xfd9204, 0x9b8971, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcbcbcb, 0xc9c9c9, 0xc9c9c9, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xecaa33, 0xffa608, 0xffa508, 0xffa508, 0xffa407, 0xffa407, 0xffa307, 0xffa307, 0xffa207, 0xffa207, 0xffa107, 0xffa107, 0xffa007, 0xffa007, 0xffa006, 0xff9f07, 0xfe9e06, 0xff9e06, 0xff9e06, 0xe18d0b, 0x2b2b2b, 0x2a2a2a, 0x2a2a2a, 0x292929, 0x292929, 0x282828, 0xe18b0a, 0xff9a06, 0xfe9905, 0xff9905, 0xfe9805, 0xff9805, 0xfe9705, 0xff9705, 0xfe9605, 0xff9605, 0xfe9504, 0xff9505, 0xfe9404, 0xff9404, 0xfe9304, 0xff9304, 0xfe9204, 0xff9204, 0xfe9104, 0xe18f25, 0x878787, 0x868686, 0x848484, 0x848484, 0x828282, 0x828282, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x5a5a5a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc2c2c2, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xccb284, 0xfea407, 0xfea407, 0xfea407, 0xfea307, 0xfea307, 0xfea207, 0xfea206, 0xfea107, 0xfea106, 0xfea006, 0xfea006, 0xfea006, 0xfe9f06, 0xfe9f06, 0xfe9e06, 0xfe9e06, 0xfe9d05, 0xfe9d06, 0xfe9c05, 0xfb9a06, 0x2f2c28, 0x292929, 0x282828, 0x282828, 0x272727, 0x302c25, 0xfb9705, 0xfe9805, 0xfe9704, 0xfe9704, 0xfe9604, 0xfe9604, 0xfe9504, 0xfe9504, 0xfe9504, 0xfe9404, 0xfe9404, 0xfe9304, 0xfe9303, 0xfe9204, 0xfe9203, 0xfe9103, 0xfe9103, 0xfe9103, 0xfe9003, 0xfe9003, 0xa88960, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7b7b7b, 0x7b7b7b, 0x797979, 0x797979, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xcfcfcf, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xbab9b7, 0xf5a821, 0xfea407, 0xffa407, 0xffa307, 0xffa307, 0xfea207, 0xffa207, 0xffa107, 0xffa107, 0xfea006, 0xffa007, 0xfe9f06, 0xff9f06, 0xfe9e06, 0xff9e06, 0xfe9d06, 0xff9d06, 0xfe9c06, 0xff9c06, 0xfe9c06, 0xff9b06, 0xa66c13, 0x282828, 0x272727, 0x272727, 0x262626, 0xa96b12, 0xfe9805, 0xff9805, 0xfe9705, 0xff9705, 0xfe9605, 0xff9605, 0xfe9504, 0xff9504, 0xfe9404, 0xff9404, 0xfe9304, 0xff9304, 0xfe9204, 0xff9204, 0xfe9104, 0xfe9104, 0xfe9003, 0xff9004, 0xfe8f03, 0xfe8f03, 0xed8d16, 0x878684, 0x848484, 0x848484, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x6f6f6f, 0x6f6f6f, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbebebe, 0xbebebe, 0xbcbcbc, 0xbcbcbc, 0xbababa, 0xb9b9b9, 0xd5b06e, 0xfea307, 0xfea307, 0xfea207, 0xfea206, 0xfea207, 0xfea106, 0xfea106, 0xfea006, 0xfea006, 0xfe9f06, 0xfe9f06, 0xfe9e06, 0xfe9e06, 0xfe9d06, 0xfe9d06, 0xfe9c05, 0xfe9c06, 0xfe9b05, 0xfe9b05, 0xfe9a05, 0xfe9a05, 0xfe9905, 0xc0780e, 0x6e4c1b, 0x714d1a, 0xc2780d, 0xfe9705, 0xfe9604, 0xfe9604, 0xfe9504, 0xfe9504, 0xfe9504, 0xfe9404, 0xfe9404, 0xfe9304, 0xfe9304, 0xfe9204, 0xfe9203, 0xfe9104, 0xfe9103, 0xfe9103, 0xfe9003, 0xfe9003, 0xfe8f03, 0xfe8f03, 0xfe8e03, 0xfe8e03, 0xfe8d03, 0xb68850, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcbcbcb, 0xcbcbcb, 0xc9c9c9, 0xc9c9c9, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xf8a517, 0xffa307, 0xffa207, 0xffa207, 0xffa107, 0xffa107, 0xffa007, 0xffa007, 0xff9f06, 0xff9f07, 0xff9e06, 0xff9e06, 0xff9d06, 0xff9d06, 0xff9d06, 0xff9c06, 0xff9c06, 0xff9b06, 0xfe9b05, 0xff9a06, 0xff9a05, 0xff9a06, 0xfe9905, 0xff9905, 0xff9805, 0xff9805, 0xfe9705, 0xff9705, 0xfe9605, 0xff9605, 0xfe9504, 0xff9505, 0xfe9404, 0xff9404, 0xfe9304, 0xff9304, 0xfe9204, 0xff9204, 0xfe9104, 0xff9104, 0xfe9004, 0xff9004, 0xfe8f03, 0xff8f03, 0xfe8e03, 0xff8e03, 0xfe8d03, 0xff8d03, 0xfe8d03, 0xf38c0f, 0x848484, 0x848484, 0x828282, 0x828282, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x5a5a5a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc2c2c2, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xceb282, 0xfea206, 0xfea106, 0xfea106, 0xfea006, 0xfea006, 0xfe9f06, 0xfe9f06, 0xfe9e06, 0xfe9e06, 0xfe9e06, 0xfe9d05, 0xfe9d06, 0xfe9c05, 0xfe9c05, 0xfe9b05, 0xfe9b05, 0xfe9a05, 0xfe9a05, 0xfe9905, 0xfe9905, 0xfe9805, 0xfe9805, 0xfe9704, 0xfe9704, 0xfe9604, 0xfe9604, 0xfe9504, 0xfe9504, 0xfe9404, 0xfe9404, 0xfe9304, 0xfe9304, 0xfe9203, 0xfe9204, 0xfe9103, 0xfe9103, 0xfe9103, 0xfe9003, 0xfe9003, 0xfe8f03, 0xfe8f03, 0xfe8e03, 0xfe8e02, 0xfe8d03, 0xfe8d02, 0xfe8d02, 0xfe8c02, 0xfe8c02, 0xfe8b02, 0xfe8b02, 0xa7865e, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7b7b7b, 0x7b7b7b, 0x797979, 0x797979, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xcfcfcf, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xd9af69, 0xfea107, 0xffa107, 0xfea006, 0xffa007, 0xfe9f06, 0xff9f06, 0xfe9e06, 0xff9e06, 0xfe9d06, 0xff9d06, 0xfe9c06, 0xff9c06, 0xfe9b06, 0xff9b06, 0xfe9a05, 0xff9a05, 0xfe9a05, 0xff9905, 0xfe9805, 0xff9805, 0xfe9805, 0xff9705, 0xfe9705, 0xff9605, 0xfe9604, 0xff9605, 0xfe9504, 0xfe9504, 0xfe9404, 0xff9404, 0xfe9304, 0xfe9304, 0xfe9204, 0xff9204, 0xfe9103, 0xfe9104, 0xfe9003, 0xfe9004, 0xfe8f03, 0xfe8f03, 0xfe8e03, 0xfe8e03, 0xfe8d03, 0xfe8d03, 0xfe8c03, 0xfe8c03, 0xfe8b02, 0xfe8b03, 0xfe8a02, 0xfe8a02, 0x824f13, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4d4d4d, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x6f6f6f, 0x6f6f6f, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbebebe, 0xbcbcbc, 0xbcbcbc, 0xbababa, 0xd7ae6c, 0xfea006, 0xfe9f06, 0xfe9f06, 0xfe9e06, 0xfe9e06, 0xfe9e06, 0xfe9d05, 0xfe9d06, 0xfe9c05, 0xfe9c06, 0xfe9b05, 0xfe9b05, 0xfe9a05, 0xfe9a05, 0xfe9905, 0xfe9905, 0xfe9805, 0xfe9805, 0xfe9704, 0xfe9705, 0xfe9604, 0xfe9604, 0xfe9504, 0xfe9504, 0xfe9404, 0xfe9404, 0xfe9304, 0xfe9304, 0xfe9204, 0xfe9204, 0xfe9203, 0xfe9103, 0xfe9103, 0xfe9003, 0xfe9003, 0xfe8f03, 0xfe8f03, 0xfe8f03, 0xfe8e03, 0xfe8e03, 0xfe8d02, 0xfe8d03, 0xfe8c02, 0xfe8c02, 0xfe8b02, 0xfe8b02, 0xfe8a02, 0xfe8a02, 0xfe8902, 0xfe8902, 0x7e4c13, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4c4c4c, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcbcbcb, 0xc9c9c9, 0xc9c9c9, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xc8b596, 0xff9f06, 0xff9f07, 0xfe9e06, 0xff9e06, 0xff9d06, 0xff9d06, 0xfe9c06, 0xff9c06, 0xff9b06, 0xff9b06, 0xfe9a05, 0xff9a06, 0xfe9a05, 0xff9905, 0xfe9905, 0xff9805, 0xfe9805, 0xff9705, 0xfe9705, 0xff9605, 0xfe9605, 0xff9605, 0xfe9504, 0xff9504, 0xfe9404, 0xff9404, 0xfe9304, 0xff9304, 0xfe9204, 0xff9204, 0xfe9104, 0xff9104, 0xfe9003, 0xff9004, 0xfe8f03, 0xff8f03, 0xfe8e03, 0xff8e03, 0xfe8d03, 0xff8d03, 0xfe8c03, 0xff8c03, 0xfe8b03, 0xfe8b03, 0xfe8a02, 0xff8a03, 0xfe8902, 0xfe8902, 0xfe8902, 0xff8802, 0x4c351a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4d4d4d, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x5a5a5a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc2c2c2, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xeca433, 0xfe9d06, 0xfe9d05, 0xfe9c06, 0xfe9c05, 0xfe9c05, 0xfe9b05, 0xfe9b05, 0xfe9a05, 0xfe9a05, 0xfe9905, 0xfe9905, 0xfe9805, 0xfe9805, 0xfe9704, 0xfe9704, 0xfe9604, 0xfe9604, 0xfe9504, 0xfe9504, 0xfe9404, 0xfe9404, 0xfe9304, 0xfe9304, 0xfe9203, 0xfe9204, 0xfe9103, 0xfe9103, 0xfe9003, 0xfe9003, 0xfe8f03, 0xfe8f03, 0xfe8f03, 0xfe8e03, 0xfe8e02, 0xfe8d03, 0xfe8d02, 0xfe8c03, 0xfe8c02, 0xfe8b02, 0xfe8b02, 0xfe8b02, 0xfe8a02, 0xfe8a02, 0xfe8902, 0xfe8902, 0xfe8801, 0xfe8802, 0xfe8701, 0xe17b0a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4c4c4c, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xcfcfcf, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xbeb7ad, 0xf3a224, 0xfe9c06, 0xff9c06, 0xfe9b06, 0xff9b06, 0xfe9a05, 0xff9a05, 0xfe9905, 0xff9905, 0xfe9805, 0xff9805, 0xfe9705, 0xff9705, 0xfe9705, 0xff9605, 0xfe9604, 0xff9505, 0xfe9504, 0xff9404, 0xfe9404, 0xff9404, 0xfe9304, 0xfe9304, 0xfe9204, 0xff9204, 0xfe9103, 0xfe9104, 0xfe9003, 0xff9004, 0xfe8f03, 0xfe8f03, 0xfe8e03, 0xfe8e03, 0xfe8d03, 0xfe8d03, 0xfe8c03, 0xfe8c03, 0xfe8b02, 0xfe8b03, 0xfe8a02, 0xfe8a02, 0xfe8902, 0xfe8902, 0xfe8802, 0xfe8802, 0xfe8702, 0xfe8702, 0xf6870a, 0x5d472f, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4d4d4d, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x6f6f6f, 0x6f6f6f, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbebebe, 0xbebebe, 0xbcbcbc, 0xbcbcbc, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xbbb5ac, 0xe2a549, 0xfe9b05, 0xfe9a05, 0xfe9a05, 0xfe9905, 0xfe9905, 0xfe9805, 0xfe9805, 0xfe9704, 0xfe9705, 0xfe9604, 0xfe9604, 0xfe9504, 0xfe9504, 0xfe9404, 0xfe9404, 0xfe9304, 0xfe9304, 0xfe9204, 0xfe9204, 0xfe9103, 0xfe9103, 0xfe9103, 0xfe9003, 0xfe8f03, 0xfe8f03, 0xfe8f03, 0xfe8e03, 0xfe8e03, 0xfe8d03, 0xfe8d02, 0xfe8d03, 0xfe8c02, 0xfe8b02, 0xfe8b02, 0xfe8b02, 0xfe8a02, 0xfe8a02, 0xfe8902, 0xfe8902, 0xfe8801, 0xfe8802, 0xfe8701, 0xfe8702, 0xfa8605, 0xd08635, 0x91867a, 0x393939, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x4c4c4c, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcbcbcb, 0xcbcbcb, 0xc9c9c9, 0xc9c9c9, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xc3af90, 0xc7ad88, 0xc5ac87, 0xc5ac87, 0xc4aa85, 0xc4aa85, 0xc2a884, 0xc1a783, 0xc1a682, 0xc0a681, 0xbfa580, 0xbea480, 0xbea37f, 0xbda27e, 0xbca17d, 0xbba07d, 0xbb9f7c, 0xba9f7b, 0xb99e7a, 0xb89d7a, 0xb89c79, 0xb79b78, 0xb59976, 0xb59976, 0xb49875, 0xb49875, 0xb29673, 0xb29673, 0xb19472, 0xb19472, 0xaf9370, 0xaf9270, 0xae916f, 0xad906e, 0xac8f6d, 0xac8e6c, 0xab8d6c, 0xaa8d6b, 0xa98c6a, 0xa98b69, 0xa88a69, 0xa2896e, 0x898989, 0x888888, 0x878787, 0x868686, 0x848484, 0x848484, 0x828282, 0x828282, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x5a5a5a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc2c2c2, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xababab, 0xababab, 0xa9a9a9, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x949494, 0x949494, 0x929292, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7b7b7b, 0x7b7b7b, 0x797979, 0x797979, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xcfcfcf, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0x9f9f9f, 0x9f9f9f, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x9b9b9b, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x888888, 0x888888, 0x868686, 0x868686, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x6f6f6f, 0x6f6f6f, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbebebe, 0xbcbcbc, 0xbcbcbc, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xa9a9a9, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa5a5a5, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd2d2d2, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcbcbcb, 0xc9c9c9, 0xc9c9c9, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb2b2b2, 0xb0b0b0, 0xb0b0b0, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x9b9b9b, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x848484, 0x848484, 0x828282, 0x828282, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x5a5a5a, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc2c2c2, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xa9a9a9, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x929292, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7b7b7b, 0x7b7b7b, 0x797979, 0x797979, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x595959, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xc6c6c6, 0xd1d1d1, 0xcfcfcf, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x9b9b9b, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x868686, 0x868686, 0x848484, 0x848484, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x6f6f6f, 0x6f6f6f, 0x6d6d6d, 0x565656, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x9a9a9a, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbebebe, 0xbebebe, 0xbcbcbc, 0xbcbcbc, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa5a5a5, 0xa3a3a3, 0xa3a3a3, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, 0x464646, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x797979, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcbcbcb, 0xcbcbcb, 0xc9c9c9, 0xc9c9c9, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb2b2b2, 0xb0b0b0, 0xb0b0b0, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x9b9b9b, 0x999999, 0x999999, 0x979797, 0x979797, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x848484, 0x848484, 0x828282, 0x828282, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x353535, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0xbfbfbf, 0xcfcfcf, 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc2c2c2, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xababab, 0xababab, 0xa9a9a9, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x949494, 0x949494, 0x929292, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7b7b7b, 0x7b7b7b, 0x797979, 0x797979, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x464646, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x464646, 0xcfcfcf, 0xcfcfcf, 0xcdcdcd, 0xcdcdcd, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb6b6b6, 0xb6b6b6, 0xb4b4b4, 0xb4b4b4, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0x9f9f9f, 0x9f9f9f, 0x9d9d9d, 0x9d9d9d, 0x9b9b9b, 0x9b9b9b, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x888888, 0x888888, 0x868686, 0x868686, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, 0x737373, 0x727272, 0x717171, 0x6f6f6f, 0x676767, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x7f7f7f, 0xbababa, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc0c0c0, 0xc0c0c0, 0xbebebe, 0xbebebe, 0xbcbcbc, 0xbcbcbc, 0xbababa, 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, 0xababab, 0xa9a9a9, 0xa9a9a9, 0xa7a7a7, 0xa7a7a7, 0xa5a5a5, 0xa5a5a5, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x909090, 0x909090, 0x8e8e8e, 0x8e8e8e, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, 0x7a7a7a, 0x797979, 0x777777, 0x777777, 0x757575, 0x757575, 0x737373, 0x727272, 0x717171, 0x626262, 0x484848, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x3a3a3a, 0x4b4b4b, 0x4b4b4b, 0x4a4a4a, 0x4a4a4a, 0x4a4a4a, 0x4a4a4a, 0x494949, 0x494949, 0x494949, 0x494949, 0x484848, 0x484848, 0x484848, 0x484848, 0x474747, 0x474747, 0x474747, 0x464646, 0x464646, 0x464646, 0x464646, 0x454545, 0x454545, 0x454545, 0x454545, 0x444444, 0x444444, 0x444444, 0x444444, 0x434343, 0x434343, 0x434343, 0x424242, 0x424242, 0x424242, 0x424242, 0x414141, 0x414141, 0x414141, 0x414141, 0x404040, 0x404040, 0x404040, 0x404040, 0x3f3f3f, 0x3f3f3f, 0x3f3f3f, 0x3f3f3f, 0x3e3e3e, 0x3e3e3e, 0x3e3e3e, 0x3e3e3e, 0x3d3d3d, 0x3d3d3d, 0x3d3d3d, 0x3d3d3d, 0x3c3c3c, 0x3c3c3c, 0x3c3c3c, 0x3c3c3c, 0x3b3b3b, 0x3b3b3b, 0x3b3b3b, 0x3a3a3a, 0x3a3a3a, 0x3a3a3a, 0x3a3a3a, 0x393939, 0x393939, 0x393939, 0x393939, 0x383838, 0x383838, 0x383838, 0x383838, 0x373737, 0x373737, 0x373737, 0x373737, 0x363636, 0x363636, 0x363636, 0x353535, 0x353535, 0x353535, 0x353535, 0x272727, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, - 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020, 0x202020 -}; \ No newline at end of file diff --git a/dev/ZBAKit/BootKit/Support.h b/dev/ZBAKit/BootKit/Support.h deleted file mode 100644 index a57782e3..00000000 --- a/dev/ZBAKit/BootKit/Support.h +++ /dev/null @@ -1,167 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -/// @file Support.h -/// @brief Purpose of this file is to help port libs into the bootloader. - -#include - -#define kLongMax ((long)(~0UL >> 1)) -#define kLongMin (~kLongMax) - -#ifdef __ZBAOSLDR__ - -/// @brief memset definition in C++. -/// @param dst destination pointer. -/// @param byte value to fill in. -/// @param len length of of src. -EXTERN_C void* memset(void* dst, int byte, long long unsigned int len); - -/// @brief memcpy definition in C++. -/// @param dst destination pointer. -/// @param src source pointer. -/// @param len length of of src. -EXTERN_C void* memcpy(void* dst, const void* src, long long unsigned int len); - -/// @brief strlen definition in C++. -EXTERN_C size_t strlen(const char* whatToCheck); - -/// @brief strcmp definition in C++. -EXTERN_C int strcmp(const char* whatToCheck, const char* whatToCheckRight); - -#define SetMem(dst, c, sz) memset(dst, c, sz) -#define MoveMem(dst, src, sz) memcpy(dst, src, sz) -#define CopyMem(dst, src, sz) memcpy(dst, src, sz) -#define StrLen(src) strlen(src) -#define StrCmp(dst, src) strcmp(dst, src) - -#endif // __ZBAOSLDR__ - -inline int IsSpace(int c) -{ - return c == ' '; -} - -inline int StringNCompare(const char* destination, const char* source, long length) -{ - long err = 0; - - for (long i = 0UL; i < length; ++i) - { - if (source[i] != destination[i]) - ++err; - } - - return err; -} - -inline long StringToLong(const char* nptr, char** endptr, int base) -{ - const char *p = nptr, *endp; - bool is_neg = 0, overflow = 0; - - /* Need unsigned so (-kLongMin) can fit in these: */ - unsigned long n = 0UL, cutoff; - int cutlim; - - if (base < 0 || base == 1 || base > 36) - { - return 0L; - } - - endp = nptr; - - while (IsSpace(*p)) - p++; - - if (*p == '+') - { - p++; - } - else if (*p == '-') - { - is_neg = 1, p++; - } - if (*p == '0') - { - p++; - /* For strtol(" 0xZ", &endptr, 16), endptr should point to 'x'; - * pointing to ' ' or '0' is non-compliant. - * (Many implementations do this wrong.) */ - endp = p; - if (base == 16 && (*p == 'X' || *p == 'x')) - { - p++; - } - else if (base == 2 && (*p == 'B' || *p == 'b')) - { - /* C23 standard supports "0B" and "0b" prefixes. */ - p++; - } - else if (base == 0) - { - if (*p == 'X' || *p == 'x') - { - base = 16, p++; - } - else if (*p == 'B' || *p == 'b') - { - base = 2, p++; - } - else - { - base = 8; - } - } - } - else if (base == 0) - { - base = 10; - } - - cutoff = (is_neg) ? -(kLongMin / base) : kLongMax / base; - cutlim = (is_neg) ? -(kLongMin % base) : kLongMax % base; - - while (1) - { - int c; - if (*p >= 'A') - c = ((*p - 'A') & (~('a' ^ 'A'))) + 10; - else if (*p <= '9') - c = *p - '0'; - else - break; - if (c < 0 || c >= base) - break; - endp = ++p; - if (overflow) - { - /* endptr should go forward and point to the non-digit character - * (of the given base); required by ANSI standard. */ - if (endptr) - continue; - break; - } - if (n > cutoff || (n == cutoff && c > cutlim)) - { - overflow = 1; - continue; - } - n = n * base + c; - } - - if (endptr) - *endptr = (char*)endp; - - if (overflow) - { - return ((is_neg) ? kLongMin : kLongMax); - } - - return (long)((is_neg) ? -n : n); -} diff --git a/dev/ZBAKit/BootKit/Thread.h b/dev/ZBAKit/BootKit/Thread.h deleted file mode 100644 index 06fd84a0..00000000 --- a/dev/ZBAKit/BootKit/Thread.h +++ /dev/null @@ -1,44 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include -#include -#include - -namespace Boot -{ - using namespace Kernel; - - class BThread; - - /// @brief Program loader class - /// @package nl.zeta.boot.api - class BThread final - { - public: - explicit BThread() = delete; - ~BThread() = default; - - explicit BThread(Kernel::VoidPtr blob); - - BThread& operator=(const BThread&) = default; - BThread(const BThread&) = default; - - void Start(HEL::BootInfoHeader* handover, BOOL is_own_stack); - void SetName(const char* name); - const char* GetName(); - bool IsValid(); - - private: - Char fBlobName[255] = {"BootThread"}; - VoidPtr fStartAddress{nullptr}; - VoidPtr fBlob{nullptr}; - UInt8* fStack{nullptr}; - HEL::BootInfoHeader* fHandover{nullptr}; - }; -} // namespace Boot diff --git a/dev/ZBAKit/DownloadOVMF.ps1 b/dev/ZBAKit/DownloadOVMF.ps1 deleted file mode 100644 index 5a2c5f0e..00000000 --- a/dev/ZBAKit/DownloadOVMF.ps1 +++ /dev/null @@ -1,4 +0,0 @@ -$client = new-object System.Net.WebClient -$output = "$PSScriptRoot\OVMF.fd" - -$client.DownloadFile("https://retrage.github.io/edk2-nightly/bin/DEBUGX64_OVMF.fd", $output) diff --git a/dev/ZBAKit/Modules/.keep b/dev/ZBAKit/Modules/.keep deleted file mode 100644 index e69de29b..00000000 diff --git a/dev/ZBAKit/Modules/NetBoot/.hgkeep b/dev/ZBAKit/Modules/NetBoot/.hgkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/dev/ZBAKit/Modules/NetBoot/Boot.S b/dev/ZBAKit/Modules/NetBoot/Boot.S deleted file mode 100644 index 0527e509..00000000 --- a/dev/ZBAKit/Modules/NetBoot/Boot.S +++ /dev/null @@ -1,28 +0,0 @@ -;; /* -;; * ======================================================== -;; * -;; * BootZ -;; * Copyright (C) 2024, Theater Quality Inc, all rights reserved., all rights reserved. -;; * -;; * ======================================================== -;; */ - -.code64 -.intel_syntax noprefix - -#define kTypeDriver 101 -#define kArchAmd64 122 -#define kHandoverMagic 0xBADCC - -.section .ldr - -.quad kHandoverMagic -.word kTypeDriver - -.text - -.extern main -.global __main - -__main: - ret diff --git a/dev/ZBAKit/Modules/NetBoot/Module.cc b/dev/ZBAKit/Modules/NetBoot/Module.cc deleted file mode 100644 index 1b4a4bb4..00000000 --- a/dev/ZBAKit/Modules/NetBoot/Module.cc +++ /dev/null @@ -1,16 +0,0 @@ -/* - * ======================================================== - * - * NetBoot - * Copyright (C) 2024, Theater Quality Inc, all rights reserved., all rights reserved. - * - * ======================================================== - */ - -#include -#include - -EXTERN_C Int32 main(Kernel::HEL::BootInfoHeader* Handover) -{ - return kEfiOk; -} diff --git a/dev/ZBAKit/Modules/NetBoot/NetBoot.h b/dev/ZBAKit/Modules/NetBoot/NetBoot.h deleted file mode 100644 index cdfe17f9..00000000 --- a/dev/ZBAKit/Modules/NetBoot/NetBoot.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * ======================================================== - * - * NetBoot - * Copyright (C) 2024, Theater Quality Inc, all rights reserved., all rights reserved. - * - * ======================================================== - */ - -#pragma once - -#include - -/// @brief the internet header is used to download updates OTA. -typedef struct NetBootInternetHeader -{ - Kernel::Char NB1; /// magic char 1 'N' - Kernel::Char NB2; /// magic char 2 'E' - Kernel::Char NB3; /// magic char 3 'T' - Kernel::Char NB4; /// magic char 4 'B' - - Kernel::Char PatchName[255]; /// example: ColdChoco - Kernel::Int32 PatchLength; /// the patch length. - Kernel::Char PatchTarget[255]; /// the target file. - Kernel::Boolean ImpliesROM; /// does it imply an EEPROM reprogram? -} NetBootInternetHeader; diff --git a/dev/ZBAKit/Modules/NetBoot/build.json b/dev/ZBAKit/Modules/NetBoot/build.json deleted file mode 100644 index 25f3dc2e..00000000 --- a/dev/ZBAKit/Modules/NetBoot/build.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "compiler_path": "x86_64-w64-mingw32-g++", - "compiler_std": "c++20", - "headers_path": ["../", "../../", "../../../ZKAKit", "../../../", "./"], - "sources_path": [".cc", "*.S"], - "output_name": "netboot.sys", - "compiler_flags": [ - "-ffreestanding", - "-nostdlib", - "-std=c++20", - "-fPIC", - "-fno-rtti", - "-fno-exceptions", - "-Wl,--subsystem=17,--image-base,0x1000000" - ], - "cpp_macros": [ - "__MINOSKRNL__", - "__ZBAOSLDR__", - "__ZKA_AMD64__", - "kNetBootVersionHighest=0x0100", - "kNetBootVersionLowest=0x0100", - "kNetBootVersion=0x0100" - ] -} diff --git a/dev/ZBAKit/Modules/SysChk/.hgkeep b/dev/ZBAKit/Modules/SysChk/.hgkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/dev/ZBAKit/Modules/SysChk/Boot.S b/dev/ZBAKit/Modules/SysChk/Boot.S deleted file mode 100644 index 9fdf4428..00000000 --- a/dev/ZBAKit/Modules/SysChk/Boot.S +++ /dev/null @@ -1,20 +0,0 @@ -;; /* -;; * ======================================================== -;; * -;; * BootZ -;; * Copyright (C) 2024, Theater Quality Inc, all rights reserved., all rights reserved. -;; * -;; * ======================================================== -;; */ - -.code64 -.intel_syntax noprefix - -#define kTypeDriver 101 -#define kArchAmd64 122 -#define kHandoverMagic 0xBADCC - -.section .ldr - -.quad kHandoverMagic -.word kTypeDriver diff --git a/dev/ZBAKit/Modules/SysChk/Module.cc b/dev/ZBAKit/Modules/SysChk/Module.cc deleted file mode 100644 index b0808fde..00000000 --- a/dev/ZBAKit/Modules/SysChk/Module.cc +++ /dev/null @@ -1,22 +0,0 @@ -/* - * ======================================================== - * - * NetBoot - * Copyright (C) 2024, Theater Quality Inc, all rights reserved., all rights reserved. - * - * ======================================================== - */ - -#include - -EXTERN_C Int32 ModuleMain(Kernel::HEL::BootInfoHeader* Handover) -{ - EfiSystemTable* system_table = (EfiSystemTable*)Handover->f_FirmwareCustomTables[1]; - - system_table->ConOut->ClearScreen(system_table->ConOut); - - system_table->ConOut->OutputString(system_table->ConOut, L"SYSCHK: CHECKING FOR VALID NEFS OR HPFS PARTITIONS...\r\n"); - system_table->ConOut->OutputString(system_table->ConOut, L"SYSCHK: GOOD TO GO!\r\n"); - - return kEfiOk; -} diff --git a/dev/ZBAKit/Modules/SysChk/build.json b/dev/ZBAKit/Modules/SysChk/build.json deleted file mode 100644 index e3fb3244..00000000 --- a/dev/ZBAKit/Modules/SysChk/build.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "compiler_path": "x86_64-w64-mingw32-g++", - "compiler_std": "c++20", - "headers_path": ["../", "../../", "../../../ZKAKit", "../../../", "./"], - "sources_path": ["*.cc", "*.S"], - "output_name": "syschk.sys", - "compiler_flags": [ - "-ffreestanding", - "-nostdlib", - "-std=c++20", - "-fPIC", - "-fno-rtti", - "-fno-exceptions", - "-Wl,--subsystem=17,--image-base,0x10000000,-e,ModuleMain" - ], - "cpp_macros": [ - "__MINOSKRNL__", - "__ZBAOSLDR__", - "__ZKA_AMD64__", - "kChkVersionHighest=0x0100", - "kChkVersionLowest=0x0100", - "kChkVersion=0x0100" - ] -} diff --git a/dev/ZBAKit/ReadMe.md b/dev/ZBAKit/ReadMe.md deleted file mode 100644 index 91f8fa2e..00000000 --- a/dev/ZBAKit/ReadMe.md +++ /dev/null @@ -1,20 +0,0 @@ -# BootZ (Zeta Bootloader Architecture) - -You need: - -- MinGW for the Kernel and bootloader. -- Netwide Assembler to output COFF object code. - -Start by cloning the repo: - -``` -git clone git@github.com:amlel-el-mahrouss/zka-dev.git -``` - -And then execute: - -``` -make all -``` - -##### Copyright, Theater Quality Inc, all rights reserved. diff --git a/dev/ZBAKit/amd64-efi.make b/dev/ZBAKit/amd64-efi.make deleted file mode 100644 index c63bd0b9..00000000 --- a/dev/ZBAKit/amd64-efi.make +++ /dev/null @@ -1,119 +0,0 @@ -################################################## -# (c) Theater Quality Inc, all rights reserved. -# This is the bootloader makefile. -################################################## - -CC_GNU=x86_64-w64-mingw32-g++ -LD_GNU=x86_64-w64-mingw32-ld - -WINDRES=x86_64-w64-mingw32-windres - -ADD_FILE=touch -COPY=cp -HTTP_GET=wget - -# Select this for Windows. -ifneq ($(findstring CYGWIN_NT-10.0,$(shell uname)), ) -EMU=qemu-system-x86_64w.exe -else -# this for NT distributions -EMU=qemu-system-x86_64 -endif - -ifeq ($(NEWS_MODEL), ) -ZKA_MODEL=-DkMachineModel="\"ZKA\"" -endif - -BIOS=OVMF.fd -IMG=epm-master-1.img -IMG_2=epm-slave.img -IMG_3=epm-master-2.img - -EMU_FLAGS=-net none -smp 1 -m 8G -M q35 \ - -bios $(BIOS) -drive \ - file=fat:rw:src/Root/,index=2,format=raw \ - -monitor stdio - -LD_FLAGS=-e Main --subsystem=10 - -STANDALONE_MACRO=-D__STANDALONE__ -OBJ=*.o - -REM=rm -REM_FLAG=-f - -FLAG_ASM=-f win64 -FLAG_GNU=-fshort-wchar -D__EFI_x86_64__ -mno-red-zone -D__MINOSKRNL__ -D__ZBAOSLDR__ \ - -DEFI_FUNCTION_WRAPPER -I./ -I../ZKAKit -I../ -c -nostdlib -fno-rtti -fno-exceptions \ - -std=c++20 -D__HAVE_ZKA_APIS__ -DZBA_USE_FB -D__ZKA_AMD64__ -D__ZKA__ -DZKA_AUTO_FORMAT - -BOOTLOADER=zbaosldr.exe -KERNEL=minoskrnl.exe -SYSCHK=syschk.sys -STARTUP=startup.sys -SCIKIT=SCIKit.dylib - -.PHONY: invalid-recipe -invalid-recipe: - @echo "=== ERROR ===" - @echo "=> Use make compile- instead." - -.PHONY: all -all: compile-amd64 - mkdir -p src/Root/EFI/BOOT - $(LD_GNU) $(OBJ) $(LD_FLAGS) -o src/$(BOOTLOADER) - $(COPY) src/$(BOOTLOADER) src/Root/EFI/BOOT/BOOTX64.EFI - $(COPY) src/$(BOOTLOADER) src/Root/EFI/BOOT/ZBAOSLDR.EFI - $(COPY) ../ZKAKit/$(KERNEL) src/Root/$(KERNEL) - $(COPY) ./Modules/SysChk/$(SYSCHK) src/Root/$(SYSCHK) - $(COPY) ../SCIKit/$(SCIKIT) src/Root/$(SCIKIT) - $(COPY) src/$(BOOTLOADER) src/Root/$(BOOTLOADER) - -ifneq ($(DEBUG_SUPPORT), ) -DEBUG = -D__DEBUG__ -endif - -.PHONY: compile-amd64 -compile-amd64: - $(WINDRES) src/BootloaderRsrc.rsrc -O coff -o BootloaderRsrc.o - $(CC_GNU) $(ZKA_MODEL) $(STANDALONE_MACRO) $(FLAG_GNU) $(DEBUG) \ - $(wildcard src/HEL/AMD64/*.cc) \ - $(wildcard src/HEL/AMD64/*.S) \ - $(wildcard src/*.cc) - -.PHONY: run-efi-amd64-ahci -run-efi-amd64-ahci: - $(EMU) $(EMU_FLAGS) -hdd $(IMG) - -.PHONY: run-efi-amd64-ata -run-efi-amd64-ata: - $(EMU) $(EMU_FLAGS) -device piix3-ide,id=ide -drive id=disk,file=$(IMG),format=raw,if=none -device ide-hd,drive=disk,bus=ide.0 - -# img_2 is the rescue disk. img is the bootable disk, as provided by the Zeta specs. -.PHONY: epm-img -epm-img: - qemu-img create -f raw $(IMG) 10G - qemu-img create -f raw $(IMG_2) 4G - qemu-img create -f raw $(IMG_3) 4G - -.PHONY: download-edk -download-edk: - $(HTTP_GET) https://retrage.github.io/edk2-nightly/bin/DEBUGX64_OVMF.fd -O OVMF.fd - -BINS=*.bin -EXECUTABLES=zbaosldr.exe minoskrnl.exe OVMF.fd - -TARGETS=$(REM_FLAG) $(OBJ) $(BIN) $(IMG) $(IMG_2) $(EXECUTABLES) - -.PHONY: clean -clean: - $(REM) $(TARGETS) - -.PHONY: help -help: - @echo "=== HELP ===" - @echo "epm-img: Format a disk using the Explicit Partition Map." - @echo "gpt-img: Format a disk using the Explicit Partition Map." - @echo "clean: clean bootloader." - @echo "bootloader-amd64: Build bootloader. (PC AMD64)" - @echo "run-efi-amd64-: Run bootloader. (PC AMD64)" diff --git a/dev/ZBAKit/arm64-efi.make b/dev/ZBAKit/arm64-efi.make deleted file mode 100644 index 37454941..00000000 --- a/dev/ZBAKit/arm64-efi.make +++ /dev/null @@ -1,112 +0,0 @@ -################################################## -# (c) Theater Quality Inc, all rights reserved. -# This is the bootloader makefile. -################################################## - -CC_GNU = clang++ -LD_GNU = lld-link - -ADD_FILE=touch -COPY=cp -HTTP_GET=wget - -# Select this for Windows. -ifneq ($(findstring CYGWIN_NT-10.0,$(shell uname)), ) -EMU=qemu-system-aarch64w.exe -else -# this for NT distributions -EMU=qemu-system-aarch64 -endif - -ifeq ($(NEWS_MODEL), ) -ZKA_MODEL=-DkMachineModel="\"ZKA\"" -endif - -BIOS=OVMF.fd -IMG=epm-master-1.img -IMG_2=epm-slave.img -IMG_3=epm-master-2.img - -EMU_FLAGS=-net none -smp 4 -m 8G -cpu max -M virt-9.1 \ - -bios $(BIOS) \ - -drive id=disk,file=$(IMG),format=raw,if=none \ - -drive \ - file=fat:rw:src/Root/,index=1,format=raw \ - -device virtio-tablet-pci \ - -d int -no-shutdown -no-reboot -device virtio-gpu-pci,xres=844,yres=390 -serial stdio - -LD_FLAGS=-subsystem:efi_application -entry:Main /nodefaultlib - -STANDALONE_MACRO=-D__STANDALONE__ -OBJ=*.o - -REM=rm -REM_FLAG=-f - -FLAG_ASM=-f win64 -FLAG_GNU=-fshort-wchar -c -ffreestanding -MMD -mno-red-zone -D__ZKA_ARM64__ -fno-rtti -fno-exceptions -I./ \ - -target aarch64-unknown-windows \ - -std=c++20 -D__FSKIT_USE_NEFS__ -D__STANDALONE__ -D__MINOSKRNL__ -D__ZBAOSLDR__ -D__HAVE_ZKA_APIS__ -D__ZKA__ -I../ -I../ZKAKit - -BOOT_LOADER=zbaosldr.exe -KERNEL=minoskrnl.exe -SYS_CHK=syschk.sys -STARTUP=startup.sys - -.PHONY: invalid-recipe -invalid-recipe: - @echo "invalid-recipe: Use make compile- instead." - -.PHONY: all -all: compile-amd64 - mkdir -p src/Root/EFI/BOOT - $(LD_GNU) $(OBJ) $(LD_FLAGS) /out:src/$(BOOT_LOADER) - $(COPY) src/$(BOOT_LOADER) src/Root/EFI/BOOT/BOOTAA64.EFI - $(COPY) src/$(BOOT_LOADER) src/Root/EFI/BOOT/BootZ.EFI - $(COPY) ../ZKAKit/$(KERNEL) src/Root/$(KERNEL) - $(COPY) src/$(BOOT_LOADER) src/Root/$(BOOT_LOADER) - -ifneq ($(DEBUG_SUPPORT), ) -DEBUG = -D__DEBUG__ -endif - -.PHONY: compile-amd64 -compile-amd64: - $(RESCMD) - $(CC_GNU) $(ZKA_MODEL) $(STANDALONE_MACRO) $(FLAG_GNU) $(DEBUG) \ - $(wildcard src/HEL/ARM64/*.cc) \ - $(wildcard src/HEL/ARM64/*.S) \ - $(wildcard src/*.cc) - -.PHONY: run-efi-amd64 -run-efi-amd64: - $(EMU) $(EMU_FLAGS) - -# img_2 is the rescue disk. img is the bootable disk, as provided by the Zeta. -.PHONY: epm-img -epm-img: - qemu-img create -f raw $(IMG) 10G - qemu-img create -f raw $(IMG_2) 4G - qemu-img create -f raw $(IMG_3) 4G - -.PHONY: download-edk -download-edk: - $(HTTP_GET) https://retrage.github.io/edk2-nightly/bin/DEBUGAARCH64_QEMU_EFI.fd -O OVMF.fd - -BINS=*.bin -EXECUTABLES=zbaosldr.exe minoskrnl.exe OVMF.fd - -TARGETS=$(REM_FLAG) $(OBJ) $(BIN) $(IMG) $(IMG_2) $(EXECUTABLES) - -.PHONY: clean -clean: - $(REM) $(TARGETS) - -.PHONY: help -help: - @echo "=== HELP ===" - @echo "epm-img: Format a disk using the Explicit Partition Map." - @echo "gpt-img: Format a disk using the Explicit Partition Map." - @echo "clean: clean bootloader." - @echo "bootloader-amd64: Build bootloader. (PC AMD64)" - @echo "run-efi-amd64: Run bootloader. (PC AMD64)" diff --git a/dev/ZBAKit/src/.gitkeep b/dev/ZBAKit/src/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/dev/ZBAKit/src/BootFileReader.cc b/dev/ZBAKit/src/BootFileReader.cc deleted file mode 100644 index 1edf1281..00000000 --- a/dev/ZBAKit/src/BootFileReader.cc +++ /dev/null @@ -1,203 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - - File: FileReader.cc - Purpose: New Boot FileReader, - Read complete file and store it in a buffer. - -------------------------------------------- */ - -#include -#include -#include -#include -#include -#include - -/// @file BootFileReader -/// @brief Bootloader File reader. -/// BUGS: 0 - -//////////////////////////////////////////////////////////////////////////////////////////////////// -/// -/// -/// @name BFileReader class -/// @brief Reads the file as a blob. -/// -/// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*** - @brief File Reader constructor. -*/ -Boot::BFileReader::BFileReader(const CharacterTypeUTF16* path, - EfiHandlePtr ImageHandle) -{ - if (path != nullptr) - { - SizeT index = 0UL; - for (; path[index] != L'\0'; ++index) - { - mPath[index] = path[index]; - } - - mPath[index] = 0; - } - - /// Load protocols with their GUIDs. - - EfiGUID guidEfp = EfiGUID(EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID); - - EfiSimpleFilesystemProtocol* efp = nullptr; - - EfiLoadImageProtocol* img = nullptr; - EfiGUID guidImg = EfiGUID(EFI_LOADED_IMAGE_PROTOCOL_GUID); - - if (BS->HandleProtocol(ImageHandle, &guidImg, (void**)&img) != kEfiOk) - { - mWriter.Write(L"BootZ: Handle-Protocol: No-Such-Protocol").Write(L"\r"); - this->mErrorCode = kNotSupported; - } - - if (BS->HandleProtocol(img->DeviceHandle, &guidEfp, (void**)&efp) != kEfiOk) - { - mWriter.Write(L"BootZ: Handle-Protocol: No-Such-Protocol").Write(L"\r"); - this->mErrorCode = kNotSupported; - return; - } - - /// Start doing disk I/O - - if (efp->OpenVolume(efp, &mRootFs) != kEfiOk) - { - mWriter.Write(L"BootZ: Fetch-Protocol: No-Such-Volume").Write(L"\r"); - this->mErrorCode = kNotSupported; - return; - } - - EfiFileProtocol* fileFs = nullptr; - - if (mRootFs->Open(mRootFs, &fileFs, mPath, kEFIFileRead, kEFIReadOnly) != - kEfiOk) - { - mWriter.Write(L"BootZ: Fetch-Protocol: No-Such-Path: ") - .Write(mPath) - .Write(L"\r"); - this->mErrorCode = kNotSupported; - - CGDrawString("BootZ: PLEASE RECOVER YOUR MINKRNL INSTALL.", 40, 10, RGB(0xFF, 0xFF, 0xFF)); - - mRootFs->Close(mRootFs); - - return; - } - - mSizeFile = 0; - mFile = fileFs; - mErrorCode = kOperationOkay; -} - -Boot::BFileReader::~BFileReader() -{ - if (this->mFile) - { - this->mFile->Close(this->mFile); - this->mFile = nullptr; - } - - if (this->mRootFs) - { - this->mRootFs->Close(this->mRootFs); - this->mRootFs = nullptr; - } - - if (this->mBlob) - { - BS->FreePool(this->mBlob); - this->mBlob = nullptr; - } - - BSetMem(this->mPath, 0, kPathLen); -} - -/** - @brief Reads all of the file into a buffer. - @param **readUntil** size of file - @param **chunkToRead** chunk to read each time. -*/ -Void Boot::BFileReader::ReadAll(SizeT readUntil, SizeT chunkToRead, UIntPtr out_address) -{ - if (mBlob == nullptr) - { - EfiFileInfo newPtrInfo{}; - UInt32 szInfo = 0U; - - EfiGUID kFileInfoGUID = EFI_FILE_INFO_GUID; - - if (mFile->GetInfo(mFile, &kFileInfoGUID, &szInfo, &newPtrInfo) == kEfiOk) - { - if (newPtrInfo.FileSize < readUntil) - readUntil = newPtrInfo.FileSize; - else if (readUntil < 1) - readUntil = newPtrInfo.FileSize; - - mWriter.Write(L"BootZ: File size: ").Write(readUntil).Write("\r"); - } - - if (!out_address) - { - if (auto err = BS->AllocatePool(EfiLoaderCode, readUntil, (VoidPtr*)&mBlob) != - kEfiOk) - { - mWriter.Write(L"*** error: ").Write(err).Write(L" ***\r"); - EFI::ThrowError(L"OutOfMemory", L"Out of memory."); - } - } - else - { - mBlob = (VoidPtr)out_address; - } - } - - mErrorCode = kNotSupported; - - UInt64 bufSize = chunkToRead; - UInt64 szCnt = 0UL; - - while (szCnt < readUntil) - { - auto res = mFile->Read(mFile, &bufSize, (VoidPtr)(&((Char*)mBlob)[szCnt])); - - szCnt += bufSize; - - if (res == kBufferTooSmall) - { - bufSize = chunkToRead; - } - } - - mSizeFile = szCnt; - mErrorCode = kOperationOkay; -} - -/// @brief error code getter. -/// @return the error code. -Int32& Boot::BFileReader::Error() -{ - return mErrorCode; -} - -/// @brief blob getter. -/// @return the blob. -VoidPtr Boot::BFileReader::Blob() -{ - return mBlob; -} - -/// @breif Size getter. -/// @return the size of the file. -UInt64& Boot::BFileReader::Size() -{ - return mSizeFile; -} diff --git a/dev/ZBAKit/src/BootString.cc b/dev/ZBAKit/src/BootString.cc deleted file mode 100644 index f511f2fc..00000000 --- a/dev/ZBAKit/src/BootString.cc +++ /dev/null @@ -1,92 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - - File: BootString.cc - Purpose: BootZ string library - - Revision History: - - - -------------------------------------------- */ - -#include -#include -#include - -/// BUGS: 0 - -///////////////////////////////////////////////////////////////////////////////////////////////////////// - -Kernel::SizeT Boot::BCopyMem(CharacterTypeUTF16* dest, CharacterTypeUTF16* src, const Kernel::SizeT len) -{ - if (!dest || !src) - return 0; - - SizeT index = 0UL; - for (; index < len; ++index) - { - dest[index] = src[index]; - } - - return index; -} - -Kernel::SizeT Boot::BStrLen(const CharacterTypeUTF16* ptr) -{ - if (!ptr) - return 0; - - Kernel::SizeT cnt = 0; - - while (*ptr != (CharacterTypeUTF16)0) - { - ++ptr; - ++cnt; - } - - return cnt; -} - -Kernel::SizeT Boot::BSetMem(CharacterTypeUTF16* src, const CharacterTypeUTF16 byte, const Kernel::SizeT len) -{ - if (!src) - return 0; - - Kernel::SizeT cnt = 0UL; - - while (*src != 0) - { - if (cnt > len) - break; - - *src = byte; - ++src; - - ++cnt; - } - - return cnt; -} - -Kernel::SizeT Boot::BSetMem(CharacterTypeUTF8* src, const CharacterTypeUTF8 byte, const Kernel::SizeT len) -{ - if (!src) - return 0; - - Kernel::SizeT cnt = 0UL; - - while (*src != 0) - { - if (cnt > len) - break; - - *src = byte; - ++src; - - ++cnt; - } - - return cnt; -} diff --git a/dev/ZBAKit/src/BootSupport.cc b/dev/ZBAKit/src/BootSupport.cc deleted file mode 100644 index 7e6d3479..00000000 --- a/dev/ZBAKit/src/BootSupport.cc +++ /dev/null @@ -1,82 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include -#include -#include -#include -#include -#include - -#ifdef __STANDALONE__ - -/// @brief memset definition in C++. -/// @param dst destination pointer. -/// @param byte value to fill in. -/// @param len length of of src. -EXTERN_C VoidPtr memset(void* dst, int byte, long long unsigned int len) -{ - for (size_t i = 0UL; i < len; ++i) - { - ((int*)dst)[i] = byte; - } - - return dst; -} - -/// @brief memcpy definition in C++. -/// @param dst destination pointer. -/// @param src source pointer. -/// @param len length of of src. -EXTERN_C VoidPtr memcpy(void* dst, const void* src, long long unsigned int len) -{ - for (size_t i = 0UL; i < len; ++i) - { - ((int*)dst)[i] = ((int*)src)[i]; - } - - return dst; -} - -/// @brief strlen definition in C++. -EXTERN_C size_t strlen(const char* whatToCheck) -{ - SizeT len = 0; - - while (whatToCheck[len] != 0) - { - ++len; - } - - return len; -} - -/// @brief strcmp definition in C++. -EXTERN_C int strcmp(const char* whatToCheck, const char* whatToCheckRight) -{ - if (!whatToCheck || *whatToCheck == 0) - return 0; - - SizeT len = 0; - - while (whatToCheck[len] == whatToCheckRight[len]) - { - if (whatToCheck[len] == 0) - return 0; - - ++len; - } - - return len; -} - -/// @brief something specific to the Microsoft's ABI, When the stack grows too big. -EXTERN_C void ___chkstk_ms(void) -{ -} - -#endif diff --git a/dev/ZBAKit/src/BootTextWriter.cc b/dev/ZBAKit/src/BootTextWriter.cc deleted file mode 100644 index bbb9a961..00000000 --- a/dev/ZBAKit/src/BootTextWriter.cc +++ /dev/null @@ -1,169 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - - File: BootTextWriter.cc - Purpose: BootZ string library - - Revision History: - - - -------------------------------------------- */ - -#include -#include -#include -#include - -///////////////////////////////////////////////////////////////////////////////////////////////////////// -/// BUGS: 0 /// -///////////////////////////////////////////////////////////////////////////////////////////////////////// - -/** -@brief puts wrapper over EFI ConOut. -*/ -Boot::BTextWriter& Boot::BTextWriter::Write(const CharacterTypeUTF16* str) -{ -#ifdef __DEBUG__ - if (!str || *str == 0) - return *this; - - CharacterTypeUTF16 strTmp[2]; - strTmp[1] = 0; - - for (size_t i = 0; str[i] != 0; i++) - { - if (str[i] == '\r') - { - strTmp[0] = str[i]; - ST->ConOut->OutputString(ST->ConOut, strTmp); - - strTmp[0] = '\n'; - ST->ConOut->OutputString(ST->ConOut, strTmp); - } - else - { - strTmp[0] = str[i]; - ST->ConOut->OutputString(ST->ConOut, strTmp); - } - } -#endif // ifdef __DEBUG__ - - return *this; -} - -/// @brief UTF-8 equivalent of Write (UTF-16). -/// @param str the input string. -Boot::BTextWriter& Boot::BTextWriter::Write(const Char* str) -{ -#ifdef __DEBUG__ - if (!str || *str == 0) - return *this; - - CharacterTypeUTF16 strTmp[2]; - strTmp[1] = 0; - - for (size_t i = 0; str[i] != 0; i++) - { - if (str[i] == '\r') - { - strTmp[0] = str[i]; - ST->ConOut->OutputString(ST->ConOut, strTmp); - - strTmp[0] = '\n'; - ST->ConOut->OutputString(ST->ConOut, strTmp); - } - else - { - strTmp[0] = str[i]; - ST->ConOut->OutputString(ST->ConOut, strTmp); - } - } -#endif // ifdef __DEBUG__ - - return *this; -} - -Boot::BTextWriter& Boot::BTextWriter::Write(const UChar* str) -{ -#ifdef __DEBUG__ - if (!str || *str == 0) - return *this; - - CharacterTypeUTF16 strTmp[2]; - strTmp[1] = 0; - - for (size_t i = 0; str[i] != 0; i++) - { - if (str[i] == '\r') - { - strTmp[0] = str[i]; - ST->ConOut->OutputString(ST->ConOut, strTmp); - - strTmp[0] = '\n'; - ST->ConOut->OutputString(ST->ConOut, strTmp); - } - else - { - strTmp[0] = str[i]; - ST->ConOut->OutputString(ST->ConOut, strTmp); - } - } -#endif // ifdef __DEBUG__ - - return *this; -} - -/** -@brief putc wrapper over EFI ConOut. -*/ -Boot::BTextWriter& Boot::BTextWriter::WriteCharacter(CharacterTypeUTF16 c) -{ -#ifdef __DEBUG__ - EfiCharType str[2]; - - str[0] = c; - str[1] = 0; - ST->ConOut->OutputString(ST->ConOut, str); -#endif // ifdef __DEBUG__ - - return *this; -} - -Boot::BTextWriter& Boot::BTextWriter::Write(const Long& x) -{ -#ifdef __DEBUG__ - this->_Write(x); - this->Write("h"); -#endif // ifdef __DEBUG__ - - return *this; -} - -Boot::BTextWriter& Boot::BTextWriter::_Write(const Long& x) -{ -#ifdef __DEBUG__ - UInt64 y = (x > 0 ? x : -x) / 16; - UInt64 h = (x > 0 ? x : -x) % 16; - - if (y) - this->_Write(y); - - /* fail if the hex number is not base-16 */ - if (h > 16) - { - this->WriteCharacter('?'); - return *this; - } - - if (y < 0) - y = -y; - - const char cNumbers[] = "0123456789ABCDEF"; - - this->WriteCharacter(cNumbers[h]); -#endif // ifdef __DEBUG__ - - return *this; -} diff --git a/dev/ZBAKit/src/BootThread.cc b/dev/ZBAKit/src/BootThread.cc deleted file mode 100644 index 32f8fd86..00000000 --- a/dev/ZBAKit/src/BootThread.cc +++ /dev/null @@ -1,207 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -/// @brief External boot services symbol. -EXTERN EfiBootServices* BS; - -/// @note BThread doesn't parse the symbols so doesn't nullify them, .bss is though. - -namespace Boot -{ - EXTERN_C Void rt_jump_to_address(VoidPtr code, HEL::BootInfoHeader* handover, UInt8* stack); - - BThread::BThread(VoidPtr blob) - : fBlob(blob), fStartAddress(nullptr) - { - // detect the format. - const Char* blob_bytes = reinterpret_cast(fBlob); - - BTextWriter writer; - - if (!blob_bytes) - { - // failed to provide a valid pointer. - return; - } - - if (blob_bytes[0] == kMagMz0 && - blob_bytes[1] == kMagMz1) - { - LDR_EXEC_HEADER_PTR header_ptr = CFKit::ldr_find_exec_header(blob_bytes); - LDR_OPTIONAL_HEADER_PTR opt_header_ptr = CFKit::ldr_find_opt_exec_header(blob_bytes); - - if (!header_ptr || !opt_header_ptr) - return; - -#ifdef __ZKA_AMD64__ - if (header_ptr->mMachine != kPeMachineAMD64 || - header_ptr->mSignature != kPeSignature) - { - writer.Write("BootZ: Not a PE32+ executable.\r"); - return; - } -#elif defined(__ZKA_ARM64__) - if (header_ptr->mMachine != kPeMachineAMD64 || - header_ptr->mSignature != kPeSignature) - { - writer.Write("BootZ: Not a PE32+ executable.\r"); - return; - } -#endif // __ZKA_AMD64__ || __ZKA_ARM64__ - - if (opt_header_ptr->mSubsystem != kZKASubsystem) - { - writer.Write("BootZ: Not a ZKA Subsystem executable.\r"); - return; - } - - writer.Write("BootZ: PE32+ executable detected (ZKA Subsystem).\r"); - - auto numSecs = header_ptr->mNumberOfSections; - - writer.Write("BootZ: Major Linker Ver: ").Write(opt_header_ptr->mMajorLinkerVersion).Write("\r"); - writer.Write("BootZ: Minor Linker Ver: ").Write(opt_header_ptr->mMinorLinkerVersion).Write("\r"); - writer.Write("BootZ: Major Subsystem Ver: ").Write(opt_header_ptr->mMajorSubsystemVersion).Write("\r"); - writer.Write("BootZ: Minor Subsystem Ver: ").Write(opt_header_ptr->mMinorSubsystemVersion).Write("\r"); - writer.Write("BootZ: Magic: ").Write(header_ptr->mSignature).Write("\r"); - - constexpr auto cPageSize = 512; - - EfiPhysicalAddress loadStartAddress = opt_header_ptr->mImageBase; - loadStartAddress += opt_header_ptr->mBaseOfData; - - writer.Write("BootZ: ImageBase: ").Write(loadStartAddress).Write("\r"); - - auto numPages = opt_header_ptr->mSizeOfImage / cPageSize; - BS->AllocatePages(AllocateAddress, EfiLoaderData, numPages, &loadStartAddress); - - LDR_SECTION_HEADER_PTR sectPtr = (LDR_SECTION_HEADER_PTR)(((Char*)opt_header_ptr) + header_ptr->mSizeOfOptionalHeader); - - constexpr auto sectionForCode = ".text"; - constexpr auto sectionForNewLdr = ".ldr"; - constexpr auto sectionForBSS = ".bss"; - - for (SizeT sectIndex = 0; sectIndex < numSecs; ++sectIndex) - { - LDR_SECTION_HEADER_PTR sect = §Ptr[sectIndex]; - - SetMem((VoidPtr)(loadStartAddress + sect->mVirtualAddress), 0, sect->mSizeOfRawData); - - if (StrCmp(sectionForCode, sect->mName) == 0) - { - fStartAddress = (VoidPtr)((UIntPtr)loadStartAddress + opt_header_ptr->mAddressOfEntryPoint); - writer.Write("BootZ: Executable entry address: ").Write((UIntPtr)fStartAddress).Write("\r"); - } - else if (StrCmp(sectionForNewLdr, sect->mName) == 0) - { - struct HANDOVER_INFORMATION_STUB - { - UInt64 HandoverMagic; - UInt32 HandoverType; - UInt32 HandoverPad; - UInt32 HandoverArch; - }* handover_struc = (struct HANDOVER_INFORMATION_STUB*)((UIntPtr)fBlob + sect->mPointerToRawData); - - if (handover_struc->HandoverMagic != kHandoverMagic && - handover_struc->HandoverType != HEL::kTypeKernel) - { -#ifdef __ZKA_AMD64__ - if (handover_struc->HandoverArch != HEL::kArchAMD64) - { - CGDrawString("BootZ: NOT AN HANDOVER IMAGE, BAD ARCHITECTURE...", 40, 10, RGB(0xFF, 0xFF, 0xFF)); - ::EFI::Stop(); - } -#endif - -#ifdef __ZKA_ARM64__ - if (handover_struc->HandoverArch != HEL::kArchARM64) - { - CGDrawString("BootZ: NOT AN HANDOVER IMAGE, BAD ARCHITECTURE...", 40, 10, RGB(0xFF, 0xFF, 0xFF)); - ::EFI::Stop(); - } -#endif - CGDrawString("BootZ: NOT AN HANDOVER IMAGE...", 40, 10, RGB(0xFF, 0xFF, 0xFF)); - - ::EFI::Stop(); - } - } - - writer.Write("BootZ: Raw offset: ").Write(sect->mPointerToRawData).Write(" of ").Write(sect->mName).Write("\r"); - - CopyMem((VoidPtr)(loadStartAddress + sect->mVirtualAddress), (VoidPtr)((UIntPtr)fBlob + sect->mPointerToRawData), sect->mSizeOfRawData); - } - } - else if (blob_bytes[0] == kPefMagic[0] && - blob_bytes[1] == kPefMagic[1] && - blob_bytes[2] == kPefMagic[2] && - blob_bytes[3] == kPefMagic[3]) - { - // ========================================= // - // PEF executable detected. - // ========================================= // - - fStartAddress = nullptr; - writer.Write("BootZ: PEF executable detected, won't load it.\r"); - writer.Write("BootZ: note: PEF executables aren't loadable by default.\r"); - } - else - { - writer.Write("BootZ: INVALID EXECUTABLE.\r"); - } - - fStack = new UInt8[mib_cast(8)]; - } - - /// @note handover header has to be valid! - Void BThread::Start(HEL::BootInfoHeader* handover, Bool own_stack) - { - HEL::HandoverProc err_fn = [](HEL::BootInfoHeader* rcx) -> void { - CGDrawString("BootZ: INVALID IMAGE! ABORTING...", 50, 10, RGB(0xFF, 0xFF, 0xFF)); - ::EFI::Stop(); - }; - - if (!fStartAddress) - { - err_fn(handover); - } - - fHandover = handover; - - if (own_stack) - rt_jump_to_address(fStartAddress, fHandover, &fStack[mib_cast(8) - 1]); - else - { - delete[] fStack; - reinterpret_cast(fStartAddress)(fHandover); - } - } - - const Char* BThread::GetName() - { - return fBlobName; - } - - Void BThread::SetName(const Char* name) - { - CopyMem(fBlobName, name, StrLen(name)); - } - - bool BThread::IsValid() - { - return fStartAddress != nullptr; - } -} // namespace Boot diff --git a/dev/ZBAKit/src/BootloaderRsrc.rsrc b/dev/ZBAKit/src/BootloaderRsrc.rsrc deleted file mode 100644 index eca9a4ec..00000000 --- a/dev/ZBAKit/src/BootloaderRsrc.rsrc +++ /dev/null @@ -1,25 +0,0 @@ -#include "../../ZKAKit/CompilerKit/Version.h" - -1 VERSIONINFO -FILEVERSION 1,0,0,0 -PRODUCTVERSION 1,0,0,0 -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "080904E4" - BEGIN - VALUE "CompanyName", "Theater Quality Inc" - VALUE "FileDescription", "ZKA OS Loader." - VALUE "FileVersion", BOOTLOADER_VERSION - VALUE "InternalName", "zbaosldr" - VALUE "LegalCopyright", "Copyright (C) 2024, Theater Quality Inc all rights reserved." - VALUE "OriginalFilename", "zbaosldr.exe" - VALUE "ProductName", "zbaosldr" - VALUE "ProductVersion", BOOTLOADER_VERSION - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x809, 1252 - END -END diff --git a/dev/ZBAKit/src/HEL/64X000/.gitkeep b/dev/ZBAKit/src/HEL/64X000/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/dev/ZBAKit/src/HEL/64X000/Boot64x0.S b/dev/ZBAKit/src/HEL/64X000/Boot64x0.S deleted file mode 100644 index a9ca1a2d..00000000 --- a/dev/ZBAKit/src/HEL/64X000/Boot64x0.S +++ /dev/null @@ -1,35 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -.section .boot_hdr -.align 4 - -/* BootZ boot header begin for a 64x000 Kernel. */ - -boot_hdr_mag: - .ascii "CB" -boot_hdr_name: - // it has to match ten bytes. - .asciz "zbaosldr\0\0" -boot_hdr_ver: - .word 0x104 -boot_hdr_proc: - .long bootloader_start - -/* BootZ boot header end */ - -.extern bootloader_main -.extern bootloader_stack - -.globl bootloader_start -bootloader_start: - psh 4 /* real address of .Laddr */ - ldi 0,(bootloader_stack-bootloader_start)(4) /* stack address location */ - mv 19,0 /* use user defined stack */ - jrl - - bl bootloader_main - blr diff --git a/dev/ZBAKit/src/HEL/AMD64/.gitkeep b/dev/ZBAKit/src/HEL/AMD64/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/dev/ZBAKit/src/HEL/AMD64/BootAPI.S b/dev/ZBAKit/src/HEL/AMD64/BootAPI.S deleted file mode 100644 index 963ef46a..00000000 --- a/dev/ZBAKit/src/HEL/AMD64/BootAPI.S +++ /dev/null @@ -1,60 +0,0 @@ -.global rt_jump_to_address -.global rt_reset_hardware - -.text - -.intel_syntax noprefix - -/** - @brief this function setups a stack and then jumps to - a function */ -rt_jump_to_address: - mov rbx, rcx - mov rcx, rdx - push rbx - push rdx - mov rsp, r8 - push rax - jmp rbx - - pop rdx - pop rbx - pop rax - - ret - -rt_reset_hardware: - /* dont raise any interrupts. (except ofc NMIs.) */ - cli - /* remap PIC */ -wait_gate1: - in al,0x64 - and al,2 - jnz wait_gate1 - mov al,0x0D1 - out 0x64,al -wait_gate2: - in al,0x64 - and al,2 - jnz wait_gate2 - mov al,0x0FE - out 0x60,al - - /* trigger triple fault, by writing to cr4 */ - - mov rax, 0 - lidt [rax] - -reset_wait: - jmp reset_wait - -.global boot_write_cr3 -.global boot_read_cr3 - -boot_read_cr3: - mov rax, rax - ret - -boot_write_cr3: - mov cr3, rcx - ret diff --git a/dev/ZBAKit/src/HEL/AMD64/BootATA.cc b/dev/ZBAKit/src/HEL/AMD64/BootATA.cc deleted file mode 100644 index 572a124d..00000000 --- a/dev/ZBAKit/src/HEL/AMD64/BootATA.cc +++ /dev/null @@ -1,278 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -/** - * @file BootATA.cc - * @author Theater Quality Inc (amlalelmahrouss@icloud.com) - * @brief ATA driver. - * @version 0.1 - * @date 2024-02-02 - * - * @copyright Copyright (c) Theater Quality Inc - * - */ - -#include -#include -#include - -/// bugs: 0 - -using namespace Boot; - -#define kATADataLen 256 - -static Boolean kATADetected = false; -static Int32 kATADeviceType = kATADeviceCount; -static UInt16 kATAData[kATADataLen] = {0}; - -Boolean boot_ata_detected(Void); - -STATIC Boolean boot_ata_wait_io(UInt16 IO) -{ - for (int i = 0; i < 400; i++) - rt_in8(IO + ATA_REG_STATUS); - -ATAWaitForIO_Retry: - auto statRdy = rt_in8(IO + ATA_REG_STATUS); - - if ((statRdy & ATA_SR_BSY)) - goto ATAWaitForIO_Retry; - -ATAWaitForIO_Retry2: - statRdy = rt_in8(IO + ATA_REG_STATUS); - - if (statRdy & ATA_SR_ERR) - return false; - - if (!(statRdy & ATA_SR_DRDY)) - goto ATAWaitForIO_Retry2; - - return true; -} - -Void boot_ata_select(UInt16 Bus) -{ - if (Bus == ATA_PRIMARY_IO) - rt_out8(Bus + ATA_REG_HDDEVSEL, ATA_PRIMARY_SEL); - else - rt_out8(Bus + ATA_REG_HDDEVSEL, ATA_SECONDARY_SEL); -} - -Boolean boot_ata_init(UInt16 Bus, UInt8 Drive, UInt16& OutBus, UInt8& OutMaster) -{ - if (boot_ata_detected()) - return true; - - BTextWriter writer; - - UInt16 IO = Bus; - - boot_ata_select(IO); - - // Bus init, NEIN bit. - rt_out8(IO + ATA_REG_NEIN, 1); - - // identify until it's good. -ATAInit_Retry: - auto statRdy = rt_in8(IO + ATA_REG_STATUS); - - if (statRdy & ATA_SR_ERR) - { - writer.Write( - L"BootZ: ATA: Not an IDE based drive.\r"); - - return false; - } - - if ((statRdy & ATA_SR_BSY)) - goto ATAInit_Retry; - - rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_IDENTIFY); - - /// fetch serial info - /// model, speed, number of sectors... - - boot_ata_wait_io(IO); - - for (SizeT indexData = 0ul; indexData < kATADataLen; ++indexData) - { - kATAData[indexData] = Kernel::HAL::rt_in16(IO + ATA_REG_DATA); - } - - OutBus = - (Bus == ATA_PRIMARY_IO) ? BootDeviceATA::kPrimary : BootDeviceATA::kSecondary; - - OutMaster = (Bus == ATA_PRIMARY_IO) ? ATA_MASTER : ATA_SLAVE; - - return true; -} - -Void boot_ata_read(UInt64 Lba, UInt16 IO, UInt8 Master, CharacterTypeUTF8* Buf, SizeT SectorSz, SizeT Size) -{ - Lba /= SectorSz; - - UInt8 Command = ((!Master) ? 0xE0 : 0xF0); - - boot_ata_wait_io(IO); - boot_ata_select(IO); - - rt_out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F)); - - rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + SectorSz) / SectorSz)); - - rt_out8(IO + ATA_REG_LBA0, (Lba)&0xFF); - rt_out8(IO + ATA_REG_LBA1, (Lba) >> 8); - rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16); - rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24); - - rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_READ_PIO); - - boot_ata_wait_io(IO); - - for (SizeT IndexOff = 0; IndexOff < Size; ++IndexOff) - { - boot_ata_wait_io(IO); - Buf[IndexOff] = Kernel::HAL::rt_in16(IO + ATA_REG_DATA); - boot_ata_wait_io(IO); - } -} - -Void boot_ata_write(UInt64 Lba, UInt16 IO, UInt8 Master, CharacterTypeUTF8* Buf, SizeT SectorSz, SizeT Size) -{ - Lba /= SectorSz; - - UInt8 Command = ((!Master) ? 0xE0 : 0xF0); - - boot_ata_wait_io(IO); - boot_ata_select(IO); - - rt_out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F)); - - rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + (SectorSz)) / SectorSz)); - - rt_out8(IO + ATA_REG_LBA0, (Lba)&0xFF); - rt_out8(IO + ATA_REG_LBA1, (Lba) >> 8); - rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16); - rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24); - - rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_WRITE_PIO); - - boot_ata_wait_io(IO); - - for (SizeT IndexOff = 0; IndexOff < Size; ++IndexOff) - { - boot_ata_wait_io(IO); - rt_out16(IO + ATA_REG_DATA, Buf[IndexOff]); - boot_ata_wait_io(IO); - } -} - -/// @check is ATA detected? -Boolean boot_ata_detected(Void) -{ - return kATADetected; -} - -/*** - * - * - * @brief ATA Device class. - * - * - */ - -/** - * @brief ATA Device constructor. - * @param void none. - */ -BootDeviceATA::BootDeviceATA() noexcept -{ - if (boot_ata_init(ATA_PRIMARY_IO, true, this->Leak().mBus, - this->Leak().mMaster) || - boot_ata_init(ATA_SECONDARY_IO, true, this->Leak().mBus, - this->Leak().mMaster)) - { - kATADetected = true; - } -} -/** - * @brief Is ATA detected? - */ -BootDeviceATA::operator bool() -{ - return boot_ata_detected(); -} - -/** - @brief Read Buf from disk - @param Sz Sector size - @param Buf buffer -*/ -BootDeviceATA& BootDeviceATA::Read(CharacterTypeUTF8* Buf, const SizeT& SectorSz) -{ - if (!boot_ata_detected()) - { - Leak().mErr = true; - return *this; - } - - this->Leak().mErr = false; - - if (!Buf || SectorSz < 1) - return *this; - - boot_ata_read(this->Leak().mBase, this->Leak().mBus, this->Leak().mMaster, - Buf, SectorSz, this->Leak().mSize); - - return *this; -} - -/** - @brief Write Buf into disk - @param Sz Sector size - @param Buf buffer -*/ -BootDeviceATA& BootDeviceATA::Write(CharacterTypeUTF8* Buf, const SizeT& SectorSz) -{ - if (!boot_ata_detected()) - { - Leak().mErr = true; - return *this; - } - - Leak().mErr = false; - - if (!Buf || SectorSz < 1) - return *this; - - boot_ata_write(this->Leak().mBase, this->Leak().mBus, this->Leak().mMaster, - Buf, SectorSz, this->Leak().mSize); - - return *this; -} - -/** - * @brief ATA trait getter. - * @return BootDeviceATA::ATATrait& the drive config. - */ -BootDeviceATA::ATATrait& BootDeviceATA::Leak() -{ - return mTrait; -} - -/*** - @brief Getter, gets the number of sectors inside the drive. -*/ -SizeT BootDeviceATA::GetSectorsCount() noexcept -{ - return (kATAData[61] << 16) | kATAData[60]; -} - -SizeT BootDeviceATA::GetDiskSize() noexcept -{ - return this->GetSectorsCount() * BootDeviceATA::kSectorSize; -} diff --git a/dev/ZBAKit/src/HEL/AMD64/BootMain.cc b/dev/ZBAKit/src/HEL/AMD64/BootMain.cc deleted file mode 100644 index dbe10366..00000000 --- a/dev/ZBAKit/src/HEL/AMD64/BootMain.cc +++ /dev/null @@ -1,337 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// Makes the compiler shut up. -#ifndef kMachineModel -#define kMachineModel "ZkaOS" -#endif // !kMachineModel - -#ifndef kExpectedWidth -#define kExpectedWidth 1920 -#endif - -#ifndef kExpectedHeight -#define kExpectedHeight 1080 -#endif - -/** Graphics related. */ - -STATIC EfiGraphicsOutputProtocol* kGop = nullptr; -STATIC UInt16 kGopStride = 0U; -STATIC EfiGUID kGopGuid; - -EXTERN_C Void rt_reset_hardware(); - -EXTERN EfiBootServices* BS; - -/** - @brief Finds and stores the GOP object. -*/ -STATIC Bool boot_init_fb() noexcept -{ - kGopGuid = EfiGUID(EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID); - kGop = nullptr; - - if (BS->LocateProtocol(&kGopGuid, nullptr, (VoidPtr*)&kGop) != kEfiOk) - return No; - - kGopStride = 4; - - for (SizeT i = 0; i < kGop->Mode->MaxMode; ++i) - { - EfiGraphicsOutputProtocolModeInformation* infoPtr = nullptr; - UInt32 sz = 0U; - - kGop->QueryMode(kGop, i, &sz, &infoPtr); - - if (infoPtr->HorizontalResolution == kExpectedWidth && - infoPtr->VerticalResolution == kExpectedHeight) - { - kGop->SetMode(kGop, i); - return Yes; - } - } - - return No; -} - -EXTERN_C VoidPtr boot_read_cr3(); -EXTERN_C Void boot_write_cr3(VoidPtr new_cr3); - -EXTERN EfiBootServices* BS; - -/// @brief Main EFI entrypoint. -/// @param ImageHandle Handle of this image. -/// @param SystemTable The system table of it. -/// @return nothing, never returns. -EFI_EXTERN_C EFI_API Int32 Main(EfiHandlePtr ImageHandle, - EfiSystemTable* SystemTable) -{ - InitEFI(SystemTable); ///! Init the EFI library. - - HEL::BootInfoHeader* handover_hdr = - new HEL::BootInfoHeader(); - - UInt32 map_key = 0; - UInt32 size_struct_ptr = sizeof(EfiMemoryDescriptor); - EfiMemoryDescriptor* struct_ptr = nullptr; - UInt32 sz_desc = sizeof(EfiMemoryDescriptor); - UInt32 rev_desc = 0; - -#ifdef ZBA_USE_FB - if (!boot_init_fb()) - return 1; ///! Init the GOP. - - for (SizeT index_vt = 0; index_vt < SystemTable->NumberOfTableEntries; - ++index_vt) - { - Char* vendor_table = reinterpret_cast( - SystemTable->ConfigurationTable[index_vt].VendorTable); - - // ACPI's 'RSD PTR', which contains the ACPI SDT (MADT, FACP...) - if (vendor_table[0] == 'R' && vendor_table[1] == 'S' && - vendor_table[2] == 'D' && vendor_table[3] == ' ' && - vendor_table[4] == 'P' && vendor_table[5] == 'T' && - vendor_table[6] == 'R' && vendor_table[7] == ' ') - { - handover_hdr->f_HardwareTables.f_VendorPtr = (VoidPtr)vendor_table; - break; - } - } - - // ------------------------------------------ // - // draw background color. - // ------------------------------------------ // - - handover_hdr->f_GOP.f_The = kGop->Mode->FrameBufferBase; - handover_hdr->f_GOP.f_Width = kGop->Mode->Info->VerticalResolution; - handover_hdr->f_GOP.f_Height = kGop->Mode->Info->HorizontalResolution; - handover_hdr->f_GOP.f_PixelPerLine = kGop->Mode->Info->PixelsPerScanLine; - handover_hdr->f_GOP.f_PixelFormat = kGop->Mode->Info->PixelFormat; - handover_hdr->f_GOP.f_Size = kGop->Mode->FrameBufferSize; -#endif // ZBA_USE_FB - - // ------------------------------------------- // - // Grab MP services, extended to runtime. // - // ------------------------------------------- // - - auto guid_mp = EfiGUID(EFI_MP_SERVICES_PROTOCOL_GUID); - EfiMpServicesProtocol* mp = nullptr; - - BS->LocateProtocol(&guid_mp, nullptr, reinterpret_cast(&mp)); - - handover_hdr->f_HardwareTables.f_MpPtr = reinterpret_cast(mp); - - kHandoverHeader = handover_hdr; - - cg_init(); - - CG::CGDrawBackground(); - - CGDrawBitMapInRegion(zka_disk, ZKA_DISK_HEIGHT, ZKA_DISK_WIDTH, (kHandoverHeader->f_GOP.f_Width - ZKA_DISK_WIDTH) / 2, (kHandoverHeader->f_GOP.f_Height - ZKA_DISK_HEIGHT) / 2); - - cg_fini(); - - UInt32 cnt_enabled = 0; - UInt32 cnt_disabled = 0; - - mp->GetNumberOfProcessors(mp, &cnt_disabled, &cnt_enabled); - -#ifdef ZBA_USE_FB - CGDrawString("BootZ (c) 2024 Theater Quality Inc.", 10, 10, RGB(0xFF, 0xFF, 0xFF)); - CGDrawString((cnt_enabled > 1) ? "Multi processor configuration detected." : "Single processor configuration detected.", 20, 10, RGB(0xFF, 0xFF, 0xFF)); -#endif // ZBA_USE_FB - - handover_hdr->f_HardwareTables.f_MultiProcessingEnabled = cnt_enabled > 1; - // Fill handover header now. - - Boot::BDiskFormatFactory partition_factory; - - // ---------------------------------------------------- // - // The following checks for an exisiting partition - // inside the disk, if it doesn't have one, - // format the disk. - // ---------------------------------------------------- // - -#ifdef ZKA_AUTO_FORMAT - if (!partition_factory.IsPartitionValid()) - { - CG::CGDrawBackground(); - - CGDrawBitMapInRegion(zka_no_disk, ZKA_NO_DISK_HEIGHT, ZKA_NO_DISK_WIDTH, (kHandoverHeader->f_GOP.f_Width - ZKA_NO_DISK_WIDTH) / 2, (kHandoverHeader->f_GOP.f_Height - ZKA_NO_DISK_HEIGHT) / 2); - - cg_fini(); - - CGDrawString("Formatting EPM disk...", 30, 10, RGB(0xFF, 0xFF, 0xFF)); - - Boot::BDiskFormatFactory::BFileDescriptor root; - - root.fFileName[0] = kNeFSRoot[0]; - root.fFileName[1] = 0; - - root.fKind = kNeFSCatalogKindDir; - - partition_factory.Format("FileSystem (A:)\0", &root, 1); - - CG::CGDrawBackground(); - - CGDrawBitMapInRegion(zka_has_disk, ZKA_HAS_DISK_HEIGHT, ZKA_HAS_DISK_WIDTH, (kHandoverHeader->f_GOP.f_Width - ZKA_HAS_DISK_WIDTH) / 2, (kHandoverHeader->f_GOP.f_Height - ZKA_HAS_DISK_HEIGHT) / 2); - - cg_fini(); - } -#endif // ZKA_AUTO_FORMAT - - BS->GetMemoryMap(&size_struct_ptr, struct_ptr, &map_key, &sz_desc, &rev_desc); - - struct_ptr = new EfiMemoryDescriptor[sz_desc]; - - BS->GetMemoryMap(&size_struct_ptr, struct_ptr, &map_key, &sz_desc, &rev_desc); - - auto kDefaultMemoryMap = 0; // Grab any usable entries. - - //-----------------------------------------------------------// - // A simple loop which finds a usable memory region for us. - //-----------------------------------------------------------// - - SizeT lookup_index = 0UL; - - for (; struct_ptr[lookup_index].Kind != EfiMemoryType::EfiConventionalMemory; ++lookup_index) - { - ZKA_UNUSED(0); - } - - kDefaultMemoryMap = lookup_index; - - //-----------------------------------------------------------// - // Update handover file specific table and phyiscal start field. - //-----------------------------------------------------------// - - handover_hdr->f_BitMapStart = nullptr; /* Start of bitmap. */ - handover_hdr->f_BitMapSize = kHandoverBitMapSz; /* Size of bitmap. */ - - while (BS->AllocatePool(EfiLoaderData, handover_hdr->f_BitMapSize, &handover_hdr->f_BitMapStart) != kEfiOk) - { - if (handover_hdr->f_BitMapStart) - { - BS->FreePool(handover_hdr->f_BitMapStart); - handover_hdr->f_BitMapStart = nullptr; - } - } - - handover_hdr->f_FirmwareCustomTables[0] = (VoidPtr)BS; - handover_hdr->f_FirmwareCustomTables[1] = (VoidPtr)ST; - - Boot::BFileReader reader_syschk(L"syschk.sys", ImageHandle); - reader_syschk.ReadAll(0); - - Boot::BThread* syschk_thread = nullptr; - - // ------------------------------------------ // - // If we succeed in reading the blob, then execute it. - // ------------------------------------------ // - - if (reader_syschk.Blob()) - { - syschk_thread = new Boot::BThread(reader_syschk.Blob()); - syschk_thread->SetName("System Check (BootZ EFI Driver)"); - } - - syschk_thread->Start(handover_hdr, NO); - - // nullify these fields, to avoid being reused later. - - handover_hdr->f_FirmwareCustomTables[0] = nullptr; - handover_hdr->f_FirmwareCustomTables[1] = nullptr; - - handover_hdr->f_FirmwareVendorLen = Boot::BStrLen(SystemTable->FirmwareVendor); - - handover_hdr->f_Magic = kHandoverMagic; - handover_hdr->f_Version = kHandoverVersion; - - // Provide fimware vendor name. - - Boot::BCopyMem(handover_hdr->f_FirmwareVendorName, SystemTable->FirmwareVendor, - handover_hdr->f_FirmwareVendorLen); - - handover_hdr->f_FirmwareVendorLen = Boot::BStrLen(SystemTable->FirmwareVendor); - - // Assign to global 'kHandoverHeader'. - - Boot::BFileReader reader_kernel(L"minoskrnl.exe", ImageHandle); - - reader_kernel.ReadAll(0); - - Boot::BThread* kernel_thread = nullptr; - - // ------------------------------------------ // - // If we succeed in reading the blob, then execute it. - // ------------------------------------------ // - - if (reader_kernel.Blob()) - { - kernel_thread = new Boot::BThread(reader_kernel.Blob()); - kernel_thread->SetName("Minimal OS Kernel."); - - handover_hdr->f_KernelImage = reader_kernel.Blob(); - } - else - { -#ifdef ZBA_USE_FB - CGDrawString("BootZ: Please recover your kernel image.", 30, 10, RGB(0xFF, 0xFF, 0xFF)); -#endif // ZBA_USE_FB - - EFI::Stop(); - } - - Boot::BFileReader chime_wav(L"zka\\startup.wav", ImageHandle); - Boot::BFileReader ttf_font(L"zka\\urbanist.ttf", ImageHandle); - - chime_wav.ReadAll(0); - ttf_font.ReadAll(0); - - if (chime_wav.Blob() && - ttf_font.Blob()) - { - handover_hdr->f_StartupChime = chime_wav.Blob(); - handover_hdr->f_ChimeSz = chime_wav.Size(); - handover_hdr->f_KernelImage = reader_kernel.Blob(); - handover_hdr->f_KernelSz = reader_kernel.Size(); - handover_hdr->f_TTFallbackFont = ttf_font.Blob(); - handover_hdr->f_FontSz = ttf_font.Size(); - } - else - { -#ifdef ZBA_USE_FB - CGDrawString("BootZ: OS resources are not present, please reinstall the OS.", 30, 10, RGB(0xFF, 0xFF, 0xFF)); -#endif // ZBA_USE_FB - - EFI::Stop(); - } - - EFI::ExitBootServices(map_key, ImageHandle); - - // ---------------------------------------------------- // - // Finally load the OS kernel. - // ---------------------------------------------------- // - - kernel_thread->Start(handover_hdr, YES); - - CANT_REACH(); -} diff --git a/dev/ZBAKit/src/HEL/AMD64/BootPlatform.cc b/dev/ZBAKit/src/HEL/AMD64/BootPlatform.cc deleted file mode 100644 index f2208f2e..00000000 --- a/dev/ZBAKit/src/HEL/AMD64/BootPlatform.cc +++ /dev/null @@ -1,106 +0,0 @@ - -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include -#include - -#ifdef __STANDALONE__ - -using namespace Boot; - -EXTERN_C void rt_hlt() -{ - asm volatile("hlt"); -} - -EXTERN_C void rt_cli() -{ - asm volatile("cli"); -} - -EXTERN_C void rt_sti() -{ - asm volatile("sti"); -} - -EXTERN_C void rt_cld() -{ - asm volatile("cld"); -} - -EXTERN_C void rt_std() -{ - asm volatile("std"); -} - -EXTERN_C void rt_out8(UInt16 port, UInt8 value) -{ - asm volatile("outb %%al, %1" - : - : "a"(value), "Nd"(port) - : "memory"); -} - -EXTERN_C void rt_out16(UInt16 port, UInt16 value) -{ - asm volatile("outw %%ax, %1" - : - : "a"(value), "Nd"(port) - : "memory"); -} - -EXTERN_C void rt_out32(UInt16 port, UInt32 value) -{ - asm volatile("outl %%eax, %1" - : - : "a"(value), "Nd"(port) - : "memory"); -} - -EXTERN_C UInt8 rt_in8(UInt16 port) -{ - UInt8 value; - asm volatile("inb %1, %%al" - : "=a"(value) - : "Nd"(port) - : "memory"); - - return value; -} - -EXTERN_C UInt16 rt_in16(UInt16 port) -{ - UInt16 value; - asm volatile("inw %%dx, %%ax" - : "=a"(value) - : "d"(port)); - - return value; -} - -EXTERN_C UInt32 rt_in32(UInt16 port) -{ - UInt32 value; - asm volatile("inl %1, %%eax" - : "=a"(value) - : "Nd"(port) - : "memory"); - - return value; -} - -#else - -#include - -void rt_hlt() -{ - Kernel::HAL::rt_halt(); -} - -#endif // __STANDALONE__ diff --git a/dev/ZBAKit/src/HEL/AMD64/BootSATA.cc b/dev/ZBAKit/src/HEL/AMD64/BootSATA.cc deleted file mode 100644 index 28516038..00000000 --- a/dev/ZBAKit/src/HEL/AMD64/BootSATA.cc +++ /dev/null @@ -1,20 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -/** - * @file BootAHCI.cc - * @author Theater Quality Inc (amlalelmahrouss@icloud.com) - * @brief AHCI support for BootZ. - * @version 0.1 - * @date 2024-02-02 - * - * @copyright Copyright (c) Theater Quality Inc - * - */ - -#include -#include -#include diff --git a/dev/ZBAKit/src/HEL/ARM64/.gitkeep b/dev/ZBAKit/src/HEL/ARM64/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/dev/ZBAKit/src/HEL/ARM64/BootAPI.S b/dev/ZBAKit/src/HEL/ARM64/BootAPI.S deleted file mode 100644 index a60ad218..00000000 --- a/dev/ZBAKit/src/HEL/ARM64/BootAPI.S +++ /dev/null @@ -1,12 +0,0 @@ -.global rt_jump_to_address - -.text - -/** - @brief this function setups a stack and then jumps to - a function */ -rt_jump_to_address: - mov x19, x0 - mov sp, x2 - blr x19 - diff --git a/dev/ZBAKit/src/HEL/ARM64/BootMain.cc b/dev/ZBAKit/src/HEL/ARM64/BootMain.cc deleted file mode 100644 index fe35ea1b..00000000 --- a/dev/ZBAKit/src/HEL/ARM64/BootMain.cc +++ /dev/null @@ -1,76 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include -#include -#include - -#ifndef kExpectedWidth -#define kExpectedWidth 844 -#endif - -#ifndef kExpectedHeight -#define kExpectedHeight 390 -#endif - -EXTERN EfiBootServices* BS; - -STATIC EfiGraphicsOutputProtocol* kGop = nullptr; -STATIC UInt16 kGopStride = 0U; -STATIC EfiGUID kGopGuid; - -/// @brief Main EFI entrypoint. -/// @param ImageHandle Handle of this image. -/// @param SystemTable The system table of it. -/// @return nothing, never returns. -EFI_EXTERN_C EFI_API Int32 Main(EfiHandlePtr ImageHandle, - EfiSystemTable* SystemTable) -{ - InitEFI(SystemTable); - - kGopGuid = EfiGUID(EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID); - kGop = nullptr; - - BS->LocateProtocol(&kGopGuid, nullptr, (VoidPtr*)&kGop); - - kGopStride = 4; - - Boot::BTextWriter writer; - - for (SizeT i = 0; i < kGop->Mode->MaxMode; ++i) - { - EfiGraphicsOutputProtocolModeInformation* infoPtr = nullptr; - UInt32 sz = 0U; - - kGop->QueryMode(kGop, i, &sz, &infoPtr); - - writer.Write(infoPtr->HorizontalResolution); - writer.Write(infoPtr->VerticalResolution); - writer.Write("\r"); - - if (infoPtr->HorizontalResolution == kExpectedWidth && - infoPtr->VerticalResolution == kExpectedHeight) - { - kGop->SetMode(kGop, i); - break; - } - } - - Boot::BFileReader reader_kernel(L"minoskrnl.exe", ImageHandle); - - reader_kernel.ReadAll(0); - - if (reader_kernel.Blob()) - { - auto kernel_thread = Boot::BThread(reader_kernel.Blob()); - - if (kernel_thread.IsValid()) - kernel_thread.Start(nullptr, YES); - } - - CANT_REACH(); -} diff --git a/dev/ZBAKit/src/HEL/ARM64/BootPlatform.cc b/dev/ZBAKit/src/HEL/ARM64/BootPlatform.cc deleted file mode 100644 index 22a0366e..00000000 --- a/dev/ZBAKit/src/HEL/ARM64/BootPlatform.cc +++ /dev/null @@ -1,37 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include -#include - -#ifdef __STANDALONE__ - -using namespace Boot; - -EXTERN_C void rt_hlt() -{ - while (Yes) - ; -} - -EXTERN_C void rt_cli() -{ -} - -EXTERN_C void rt_sti() -{ -} - -EXTERN_C void rt_cld() -{ -} - -EXTERN_C void rt_std() -{ -} - -#endif // __STANDALONE__ diff --git a/dev/ZBAKit/src/HEL/POWER/.gitkeep b/dev/ZBAKit/src/HEL/POWER/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/dev/ZBAKit/src/HEL/POWER/CoreBootStartup.S b/dev/ZBAKit/src/HEL/POWER/CoreBootStartup.S deleted file mode 100644 index e4964c59..00000000 --- a/dev/ZBAKit/src/HEL/POWER/CoreBootStartup.S +++ /dev/null @@ -1,34 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -.section .boot_hdr -.align 4 - -/* BootZ boot header begin */ - -boot_hdr_mag: - .ascii "CB" -boot_hdr_name: - // it has to match ten bytes. - .asciz "zbaosldr\0\0" -boot_hdr_ver: - .word 0x104 -boot_hdr_proc: - .long bootloader_start - -/* BootZ boot 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/dev/ZBAKit/src/New+Delete.cc b/dev/ZBAKit/src/New+Delete.cc deleted file mode 100644 index 04c6bc72..00000000 --- a/dev/ZBAKit/src/New+Delete.cc +++ /dev/null @@ -1,60 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include -#include - -#ifdef __STANDALONE__ -EXTERN EfiBootServices* BS; - -/// @brief Allocates a new object. -/// @param sz the size. -/// @return -void* operator new(size_t sz) -{ - void* buf = nullptr; - - while (BS->AllocatePool(EfiMemoryType::EfiLoaderData, sz, &buf) == kBufferTooSmall) - BS->FreePool(buf); - - return buf; -} - -/// @brief Allocates a new object. -/// @param sz the size. -/// @return -void* operator new[](size_t sz) -{ - void* buf = nullptr; - BS->AllocatePool(EfiMemoryType::EfiLoaderData, sz, &buf); - - return buf; -} - -/// @brief Deletes the object. -/// @param buf the object. -void operator delete(void* buf) -{ - BS->FreePool(buf); -} - -/// @brief Deletes the object. -/// @param buf the object. -void operator delete[](void* buf) -{ - BS->FreePool(buf); -} - -/// @brief Deletes the object (array specific). -/// @param buf the object. -/// @param size it's size. -void operator delete(void* buf, size_t size) -{ - BS->FreePool(buf); -} - -#endif // __STANDALONE__ diff --git a/dev/ZBAKit/src/Root/EFI/STARTUP.NSH b/dev/ZBAKit/src/Root/EFI/STARTUP.NSH deleted file mode 100644 index d29ba8fd..00000000 --- a/dev/ZBAKit/src/Root/EFI/STARTUP.NSH +++ /dev/null @@ -1,2 +0,0 @@ -fs0: -BOOT\BOOTX64.EFI diff --git a/dev/ZBAKit/src/Root/zka/startup.wav b/dev/ZBAKit/src/Root/zka/startup.wav deleted file mode 100644 index 524921f5..00000000 Binary files a/dev/ZBAKit/src/Root/zka/startup.wav and /dev/null differ diff --git a/dev/ZBAKit/src/Root/zka/urbanist.ttf b/dev/ZBAKit/src/Root/zka/urbanist.ttf deleted file mode 100644 index e9a6dbb0..00000000 Binary files a/dev/ZBAKit/src/Root/zka/urbanist.ttf and /dev/null differ diff --git a/dev/ZKAKit/ArchKit/ArchKit.h b/dev/ZKAKit/ArchKit/ArchKit.h deleted file mode 100644 index e8d32a9d..00000000 --- a/dev/ZKAKit/ArchKit/ArchKit.h +++ /dev/null @@ -1,90 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include -#include -#include - -#include - -#ifdef __ZKA_AMD64__ -#include -#include -#include -#elif defined(__ZKA_POWER64__) -#include -#elif defined(__ZKA_ARM64__) -#include -#else -#error !!! unknown architecture !!! -#endif - -namespace Kernel -{ - inline SSizeT rt_hash_seed(const Char* seed, int mul) - { - SSizeT hash = 0; - - for (SSizeT idx = 0; seed[idx] != 0; ++idx) - { - hash += seed[idx]; - hash ^= mul; - } - - return hash; - } - - /// @brief write to mapped memory register - /// @param base the base address. - /// @param reg the register. - /// @param value the write to write on it. - inline Void ke_dma_write(UInt32 base, UInt32 reg, UInt32 value) noexcept - { - *(volatile UInt32*)((UInt64)base + reg) = value; - } - - /// @brief read from mapped memory register. - /// @param base base address - /// @param reg the register. - /// @return the value inside the register. - inline UInt32 ke_dma_read(UInt32 base, UInt32 reg) noexcept - { - return *(volatile UInt32*)((UInt64)base + reg); - } - - namespace HAL - { - auto mm_is_bitmap(VoidPtr ptr) -> Bool; - } -} // namespace Kernel - -#define kKernelMaxSystemCalls (256) - -typedef Kernel::Void (*rt_syscall_proc)(Kernel::VoidPtr); - -struct HAL_SYSCALL_RECORD final -{ - Kernel::Int64 fHash; - Kernel::Bool fHooked; - rt_syscall_proc fProc; - - operator bool() - { - return fHooked; - } -}; - -inline Kernel::Array - kSyscalls; - -inline Kernel::Array - kKerncalls; - -EXTERN_C Kernel::HAL::StackFramePtr mp_get_current_context(Kernel::Int64 pid); diff --git a/dev/ZKAKit/CFKit/GUIDWizard.h b/dev/ZKAKit/CFKit/GUIDWizard.h deleted file mode 100644 index 825f3ad5..00000000 --- a/dev/ZKAKit/CFKit/GUIDWizard.h +++ /dev/null @@ -1,24 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace CFKit::XRN::Version1 -{ - using namespace Kernel; - - Ref cf_make_sequence(const ArrayList& seq); - ErrorOr> cf_try_guid_to_string(Ref& guid); -} // namespace CFKit::XRN::Version1 diff --git a/dev/ZKAKit/CFKit/GUIDWrapper.h b/dev/ZKAKit/CFKit/GUIDWrapper.h deleted file mode 100644 index 2a850099..00000000 --- a/dev/ZKAKit/CFKit/GUIDWrapper.h +++ /dev/null @@ -1,60 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include -#include -#include - -/* GUID for C++ Components */ - -#define kXRNNil "@{........-....-M...-N...-............}" - -// eXtensible Resource Information -namespace CFKit::XRN -{ - using namespace Kernel; - - union GUIDSequence { - alignas(8) UShort u8[16]; - alignas(8) UShort u16[8]; - alignas(8) UInt u32[4]; - alignas(8) ULong u64[2]; - - struct - { - alignas(8) UInt fMs1; - UShort fMs2; - UShort fMs3; - UChar fMs4[8]; - }; - }; - - class GUID final - { - public: - explicit GUID() = default; - ~GUID() = default; - - public: - GUID& operator=(const GUID&) = default; - GUID(const GUID&) = default; - - public: - GUIDSequence& operator->() noexcept - { - return fUUID; - } - GUIDSequence& Leak() noexcept - { - return fUUID; - } - - private: - GUIDSequence fUUID; - }; -} // namespace CFKit::XRN diff --git a/dev/ZKAKit/CFKit/Property.h b/dev/ZKAKit/CFKit/Property.h deleted file mode 100644 index cb91a5c3..00000000 --- a/dev/ZKAKit/CFKit/Property.h +++ /dev/null @@ -1,54 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#ifndef CFKIT_PROPS_H -#define CFKIT_PROPS_H - -#include -#include -#include -#include - -#define kMaxPropLen 255 - -namespace CFKit -{ - using namespace Kernel; - - /// @brief handle to anything (number, ptr, string...) - using PropertyId = UIntPtr; - - /// @brief Kernel property class. - /// @example \Properties\SmpCores or \Properties\KernelVersion - class Property - { - public: - Property(); - virtual ~Property(); - - public: - Property& operator=(const Property&) = default; - Property(const Property&) = default; - - bool StringEquals(KString& name); - PropertyId& GetValue(); - KString& GetKey(); - - private: - KString fName{kMaxPropLen}; - PropertyId fValue{0UL}; - }; - - template - using PropertyArray = Array; -} // namespace CFKit - -namespace Kernel -{ - using namespace CFKit; -} - -#endif // !CFKIT_PROPS_H diff --git a/dev/ZKAKit/CFKit/Utils.h b/dev/ZKAKit/CFKit/Utils.h deleted file mode 100644 index 370eca45..00000000 --- a/dev/ZKAKit/CFKit/Utils.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef CFKIT_UTILS_H -#define CFKIT_UTILS_H - -#include -#include - -namespace CFKit -{ - using namespace Kernel; - - /// @brief Finds the PE header inside the blob. - inline auto ldr_find_exec_header(DosHeaderPtr ptrDos) -> LDR_EXEC_HEADER_PTR - { - if (!ptrDos) - return nullptr; - - if (ptrDos->eMagic[0] != kMagMz0) - return nullptr; - - if (ptrDos->eMagic[1] != kMagMz1) - return nullptr; - - return (LDR_EXEC_HEADER_PTR)(VoidPtr)(&ptrDos->eLfanew + 1); - } - - /// @brief Finds the PE optional header inside the blob. - inline auto ldr_find_opt_exec_header(DosHeaderPtr ptrDos) -> LDR_OPTIONAL_HEADER_PTR - { - if (!ptrDos) - return nullptr; - - auto exec = ldr_find_exec_header(ptrDos); - - if (!exec) - return nullptr; - - return (LDR_OPTIONAL_HEADER_PTR)(VoidPtr)(&exec->mCharacteristics + 1); - } - - /// @brief Finds the PE header inside the blob. - /// @note overloaded function. - inline auto ldr_find_exec_header(const Char* ptrDos) -> LDR_EXEC_HEADER_PTR - { - return ldr_find_exec_header((DosHeaderPtr)ptrDos); - } - - /// @brief Finds the PE header inside the blob. - /// @note overloaded function. - inline auto ldr_find_opt_exec_header(const Char* ptrDos) -> LDR_OPTIONAL_HEADER_PTR - { - return ldr_find_opt_exec_header((DosHeaderPtr)ptrDos); - } -} // namespace CFKit - -#endif // ifndef CFKIT_UTILS_H diff --git a/dev/ZKAKit/CompilerKit/CompilerKit.h b/dev/ZKAKit/CompilerKit/CompilerKit.h deleted file mode 100644 index 3b3f15fa..00000000 --- a/dev/ZKAKit/CompilerKit/CompilerKit.h +++ /dev/null @@ -1,13 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#ifndef _INC_CL_H -#define _INC_CL_H - -#include -#include - -#endif /* ifndef _INC_CL_H */ diff --git a/dev/ZKAKit/CompilerKit/Detail.h b/dev/ZKAKit/CompilerKit/Detail.h deleted file mode 100644 index c44cccd6..00000000 --- a/dev/ZKAKit/CompilerKit/Detail.h +++ /dev/null @@ -1,27 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#ifdef __MINOSKRNL__ -#include -#endif // ifdef __MINOSKRNL__ - -#define ZKA_COPY_DELETE(KLASS) \ - KLASS& operator=(const KLASS&) = delete; \ - KLASS(const KLASS&) = delete; - -#define ZKA_COPY_DEFAULT(KLASS) \ - KLASS& operator=(const KLASS&) = default; \ - KLASS(const KLASS&) = default; - -#define ZKA_MOVE_DELETE(KLASS) \ - KLASS& operator=(KLASS&&) = delete; \ - KLASS(KLASS&&) = delete; - -#define ZKA_MOVE_DEFAULT(KLASS) \ - KLASS& operator=(KLASS&&) = default; \ - KLASS(KLASS&&) = default; diff --git a/dev/ZKAKit/CompilerKit/Version.h b/dev/ZKAKit/CompilerKit/Version.h deleted file mode 100644 index 10cf93d1..00000000 --- a/dev/ZKAKit/CompilerKit/Version.h +++ /dev/null @@ -1,7 +0,0 @@ -// (c) Theater Quality Inc - -#pragma once - -/// .. -#define BOOTLOADER_VERSION "1104.2024.110" -#define KERNEL_VERSION "1104.2024.110" diff --git a/dev/ZKAKit/FSKit/Defines.h b/dev/ZKAKit/FSKit/Defines.h deleted file mode 100644 index feb022ee..00000000 --- a/dev/ZKAKit/FSKit/Defines.h +++ /dev/null @@ -1,12 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include - -#define FSKIT_VERSION "1.0.0" -#define FSKIT_VERSION_BCD 0x0100 diff --git a/dev/ZKAKit/FSKit/HPFS.h b/dev/ZKAKit/FSKit/HPFS.h deleted file mode 100644 index 397bde5b..00000000 --- a/dev/ZKAKit/FSKit/HPFS.h +++ /dev/null @@ -1,30 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include - -/// @file HPFS.h -/// @brief HPFS filesystem support. - -#define kHPFSVersion 0x0100 -#define kHPFSMagic " HPFS" -#define kHPFSMagicLen 8 - -#define kHPFSMinimumDiskSize (gib_cast(64)) - -enum -{ - kHPFSInvalidDrive, - kHPFSHDDDrive, - kHPFSSSDDrive, - kHPFSMassStorageDrive, - kHPFSSCSIDrive, - kHPFSDriveCount, -}; - -struct HPFS_EXPLICIT_BOOT_SECTOR; diff --git a/dev/ZKAKit/FSKit/IndexableProperty.h b/dev/ZKAKit/FSKit/IndexableProperty.h deleted file mode 100644 index 585a25c5..00000000 --- a/dev/ZKAKit/FSKit/IndexableProperty.h +++ /dev/null @@ -1,63 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include -#include -#include - -#define kIndexerNodeNameLength 255 -#define kIndexerClaimed 0xCF - -namespace Kernel -{ - namespace Indexer - { - struct IndexProperty final - { - public: - Char Drive[kDriveNameLen]; - Char Path[kIndexerNodeNameLength]; - }; - - class IndexableProperty final : public Property - { - public: - explicit IndexableProperty() - : Property() - { - Kernel::KString strProp(kMaxPropLen); - strProp += "/Properties/Indexable"; - - this->GetKey() = strProp; - } - - ~IndexableProperty() override = default; - - ZKA_COPY_DEFAULT(IndexableProperty); - - public: - IndexProperty& Leak() noexcept; - - public: - void AddFlag(Int16 flag); - void RemoveFlag(Int16 flag); - Int16 HasFlag(Int16 flag); - - private: - IndexProperty fIndex; - UInt32 fFlags; - }; - - /// @brief Index a file into the indexer instance. - /// @param filename path - /// @param filenameLen used bytes in path. - /// @param indexer the filesystem indexer. - /// @return none. - Void fs_index_file(const Char* filename, SizeT filenameLen, IndexableProperty& indexer); - } // namespace Indexer -} // namespace Kernel diff --git a/dev/ZKAKit/FSKit/NeFS.h b/dev/ZKAKit/FSKit/NeFS.h deleted file mode 100644 index dacb2fcc..00000000 --- a/dev/ZKAKit/FSKit/NeFS.h +++ /dev/null @@ -1,402 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - - FILE: NeFS.h - PURPOSE: NeFS (New FileSystem) support. - - Revision History: - - ?/?/?: Added file (amlel) - 12/02/24: Add UUID macro for EPM and GPT partition schemes. - 3/16/24: Add mandatory sector size, kNeFSSectorSz is set to 2048 by -default. - -------------------------------------------- */ - -#pragma once - -#include -#include -#include -#include - -/** - @brief New File System specification. - @author Theater Quality Inc (Theater Quality Inc, amlalelmahrouss at icloud dot com) -*/ - -#define kNeFSInvalidFork (-1) -#define kNeFSInvalidCatalog (-1) -#define kNeFSNodeNameLen (256) - -#define kNeFSMinimumDiskSize (gib_cast(4)) - -#define kNeFSSectorSz (512) -#define kNeFSForkDataSz (mib_cast(16)) - -#define kNeFSIdentLen (8) -#define kNeFSIdent " NeFS" -#define kNeFSPadLen (392) - -#define kNeFSMetaFilePrefix '$' - -#define kNeFSVersionInteger (0x0129) -#define kNeFSVerionString "1.2.9" - -/// @brief Standard fork types. -#define kNeFSDataFork "main_data" -#define kNeFSResourceFork "main_rsrc" - -#define kNeFSForkSize (sizeof(NFS_FORK_STRUCT)) - -#define kNeFSPartitionTypeStandard (7) -#define kNeFSPartitionTypePage (8) -#define kNeFSPartitionTypeBoot (9) - -#define kNeFSCatalogKindFile (1) -#define kNeFSCatalogKindDir (2) -#define kNeFSCatalogKindAlias (3) - -//! Shared between network and/or partitions. Export forks as .zip when copying. -#define kNeFSCatalogKindShared (4) - -#define kNeFSCatalogKindResource (5) -#define kNeFSCatalogKindExecutable (6) - -#define kNeFSCatalogKindPage (8) - -#define kNeFSCatalogKindDevice (9) -#define kNeFSCatalogKindLock (10) - -#define kNeFSCatalogKindRLE (11) -#define kNeFSCatalogKindMetaFile (12) - -#define kNeFSCatalogKindTTF (13) -#define kNeFSCatalogKindRIFF (14) -#define kNeFSCatalogKindMPEG (15) -#define kNeFSCatalogKindDVX (16) - -#define kNeFSSeparator '/' -#define kNeFSSeparatorAlt '/' - -#define kNeFSUpDir ".." -#define kNeFSRoot "/" -#define kNeFSRootAlt "/" - -#define kNeFSLF '\r' -#define kNeFSEOF (-1) - -#define kNeFSBitWidth (sizeof(Kernel::Char)) -#define kNeFSLbaType (Kernel::Lba) - -/// @note Start after the partition map header. (Virtual addressing) -#define kNeFSRootCatalogStartAddress (1024) -#define kNeFSCatalogStartAddress ((2048) + sizeof(NFS_ROOT_PARTITION_BLOCK)) - -#define kResourceTypeDialog (10) -#define kResourceTypeString (11) -#define kResourceTypeMenu (12) -#define kResourceTypeSound (13) -#define kResourceTypeFont (14) - -#define kConfigLen (64) -#define kPartLen (32) - -#define kNeFSFlagDeleted (70) -#define kNeFSFlagUnallocated (0) -#define kNeFSFlagCreated (71) - -#define kNeFSMimeNameLen (200) -#define kNeFSForkNameLen (200) - -#define kNeFSFrameworkExt ".fwrk" -#define kNeFSApplicationExt ".app" -#define kNeFSJournalExt ".jrnl" - -struct NFS_CATALOG_STRUCT; -struct NFS_FORK_STRUCT; -struct NFS_ROOT_PARTITION_BLOCK; - -enum -{ - kNeFSHardDrive = 0xC0, // Hard Drive - kNeFSSolidStateDrive = 0xC1, // Solid State Drive - kNeFSOpticalDrive = 0x0C, // Blu-Ray/DVD - kNeFSMassStorageDevice = 0xCC, // USB - kNeFSScsiDrive = 0xC4, // SCSI Hard Drive - kNeFSFlashDrive = 0xC6, - kNeFSUnknown = 0xFF, // Unknown device. - kNeFSDriveCount = 7, -}; - -/// @brief Catalog type. -struct PACKED NFS_CATALOG_STRUCT final -{ - Kernel::Char Name[kNeFSNodeNameLen]; - Kernel::Char Mime[kNeFSMimeNameLen]; - - /// Catalog status flag. - Kernel::UInt16 Flags; - /// Custom catalog flags. - Kernel::UInt16 FilkMMFlags; - /// Catalog kind. - Kernel::Int32 Kind; - - /// Size of the data fork. - Kernel::Lba DataForkSize; - - /// Size of all resource forks. - Kernel::Lba ResourceForkSize; - - Kernel::Lba DataFork; - Kernel::Lba ResourceFork; - - Kernel::Lba NextSibling; - Kernel::Lba PrevSibling; -}; - -/// @brief Fork type, contains a data page. -/// @note The way we store is way different than how other filesystems do, specific chunk of code are -/// written into either the data fork or resource fork, the resource fork is reserved for file metadata. -/// whereas the data fork is reserved for file data. -struct PACKED NFS_FORK_STRUCT final -{ - Kernel::Char ForkName[kNeFSForkNameLen]; - Kernel::Char CatalogName[kNeFSNodeNameLen]; - - Kernel::Int32 Flags; - Kernel::Int32 Kind; - - Kernel::Int64 ResourceId; - Kernel::Int32 ResourceKind; - Kernel::Int32 ResourckMMFlags; - - Kernel::Lba DataOffset; // 8 Where to look for this data? - Kernel::SizeT DataSize; /// Data size according using sector count. - - Kernel::Lba NextSibling; - Kernel::Lba PreviousSibling; -}; - -/// @brief Partition block type -struct PACKED NFS_ROOT_PARTITION_BLOCK final -{ - Kernel::Char Ident[kNeFSIdentLen]; - Kernel::Char PartitionName[kPartLen]; - - Kernel::Int32 Flags; - Kernel::Int32 Kind; - - Kernel::Lba StartCatalog; - Kernel::SizeT CatalogCount; - - Kernel::SizeT DiskSize; - - Kernel::SizeT FreeCatalog; - Kernel::SizeT FreeSectors; - - Kernel::SizeT SectorCount; - Kernel::SizeT SectorSize; - - Kernel::UInt64 Version; - - Kernel::Lba EpmBlock; - - Kernel::Char Pad[kNeFSPadLen]; -}; - -namespace Kernel -{ - class NeFileSystemParser; - class NeFileSystemJournal; - class NeFileSystemHelper; - - enum - { - kNeFSSubDriveA, - kNeFSSubDriveB, - kNeFSSubDriveC, - kNeFSSubDriveD, - kNeFSSubDriveInvalid, - kNeFSSubDriveCount, - }; - - /// \brief Resource fork kind. - enum - { - kNeFSRsrcForkKind = 0, - kNeFSDataForkKind = 1 - }; - - /// - /// \name NeFileSystemParser - /// \brief NeFS parser class. (catalog creation, remove removal, root, - /// forks...) Designed like the DOM, detects the filesystem automatically. - /// - class NeFileSystemParser final - { - public: - explicit NeFileSystemParser() = default; - ~NeFileSystemParser() = default; - - public: - ZKA_COPY_DEFAULT(NeFileSystemParser); - - public: - /// @brief Creates a new fork inside the New filesystem partition. - /// @param catalog it's catalog - /// @param theFork the fork itself. - /// @return the fork - _Output NFS_FORK_STRUCT* CreateFork(_Input NFS_CATALOG_STRUCT* catalog, - _Input NFS_FORK_STRUCT& theFork); - - /// @brief Find fork inside New filesystem. - /// @param catalog the catalog. - /// @param name the fork name. - /// @return the fork. - _Output NFS_FORK_STRUCT* FindFork(_Input NFS_CATALOG_STRUCT* catalog, - _Input const Char* name, - Boolean dataOrRsrc); - - _Output Void RemoveFork(_Input NFS_FORK_STRUCT* fork); - - _Output Void CloseFork(_Input NFS_FORK_STRUCT* fork); - - _Output NFS_CATALOG_STRUCT* FindCatalog(_Input const Char* catalogName, Lba& outLba); - - _Output NFS_CATALOG_STRUCT* GetCatalog(_Input const Char* name); - - _Output NFS_CATALOG_STRUCT* CreateCatalog(_Input const Char* name, - _Input const Int32& flags, - _Input const Int32& kind); - - _Output NFS_CATALOG_STRUCT* CreateCatalog(_Input const Char* name); - - Bool WriteCatalog(_Input _Output NFS_CATALOG_STRUCT* catalog, - _Input Bool isRsrcFork, - _Input VoidPtr data, - _Input SizeT sizeOfData, - _Input const Char* forkName); - - VoidPtr ReadCatalog(_Input _Output NFS_CATALOG_STRUCT* catalog, - _Input Bool isRsrcFork, - _Input SizeT dataSz, - _Input const Char* forkName); - - bool Seek(_Input _Output NFS_CATALOG_STRUCT* catalog, SizeT off); - - SizeT Tell(_Input _Output NFS_CATALOG_STRUCT* catalog); - - bool RemoveCatalog(_Input const Char* catalog); - - bool CloseCatalog(_InOut NFS_CATALOG_STRUCT* catalog); - - /// @brief Make a EPM+NeFS drive out of the disk. - /// @param drive The drive to write on. - /// @return If it was sucessful, see err_local_get(). - bool Format(_Input _Output DriveTrait* drive, _Input const Lba endLba, _Input const Int32 flags, const Char* part_name); - - public: - Int32 mDriveIndex{kNeFSSubDriveA}; - }; - - /// - /// \name NeFileSystemHelper - /// \brief Filesystem helper and utils. - /// - - class NeFileSystemHelper final - { - public: - STATIC const Char* Root(); - STATIC const Char* UpDir(); - STATIC const Char Separator(); - STATIC const Char MetaFile(); - }; - - /// @brief Journal class for NeFS. - class NeFileSystemJournal final - { - public: - explicit NeFileSystemJournal(const char* stamp) - { - if (!stamp) - { - kcout << "Invalid: Journal Stamp, using default name.\r"; - return; - } - - kcout << "Info: Journal stamp: " << stamp << endl; - rt_copy_memory((VoidPtr)stamp, this->mStamp, rt_string_len(stamp)); - } - - ~NeFileSystemJournal() = default; - - ZKA_COPY_DEFAULT(NeFileSystemJournal); - - Bool CreateJournal(NeFileSystemParser* parser) - { - if (!parser) - return NO; - - auto node = parser->CreateCatalog(mStamp); - - if (!node) - return NO; - - delete node; - node = nullptr; - - return YES; - } - - Bool IsJournalValid(NeFileSystemParser* parser) - { - if (!parser) - return NO; - - if (auto node = parser->GetCatalog(mStamp); - node) - { - delete node; - node = nullptr; - - return YES; - } - - return NO; - } - - Void Commit() {} - - Void Start() {} - - private: - Char mStamp[255] = { "/System/FileSystemStamp.jrnl" }; - - }; - - namespace Detail - { - Boolean fs_init_newfs(Void) noexcept; - } // namespace Detail -} // namespace Kernel - -/// @brief Write to newfs disk. -/// @param drv_mnt mounted interface. -/// @param drv_trait drive info -/// @param drv_indx drive index. -/// @return status code. -Kernel::Int32 fs_newfs_write(Kernel::MountpointInterface* drv_mnt, - Kernel::DriveTrait& drv_trait, - Kernel::Int32 drv_indx); - -/// @brief Read from newfs disk. -/// @param drv_mnt mounted interface. -/// @param drv_trait drive info -/// @param drv_indx drive index. -/// @return status code. -Kernel::Int32 fs_newfs_read(Kernel::MountpointInterface* drv_mnt, - Kernel::DriveTrait& drv_trait, - Kernel::Int32 drv_indx); diff --git a/dev/ZKAKit/FirmwareKit/.gitkeep b/dev/ZKAKit/FirmwareKit/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/dev/ZKAKit/FirmwareKit/CoreBoot/CoreBoot.h b/dev/ZKAKit/FirmwareKit/CoreBoot/CoreBoot.h deleted file mode 100644 index 46a4eae8..00000000 --- a/dev/ZKAKit/FirmwareKit/CoreBoot/CoreBoot.h +++ /dev/null @@ -1,31 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include - -namespace Firmware::Detail::CoreBoot -{ - using namespace Kernel; - - struct LEHeader; - - /// @brief Linear Executable Header - /// @author Theater Quality Inc - struct ATTRIBUTE(aligned(4)) LEHeader - { - const Char fMagic[2]; // magic number - const Char fName[10]; // operating system name - const UInt32 fRevision; // firmware revision - const UInt32 fStartAddress; // start address (master/slave(s) thread) - -#ifdef ZKA_IS_EXTENDED_COREBOOT - const UIntPtr fMasterStructure; // master structure for MP/PM and device tree and such (ARM) - const UIntPtr fMasterStructureVersion; // master structure version. -#endif - }; -} // namespace Firmware::Detail::CoreBoot diff --git a/dev/ZKAKit/FirmwareKit/CoreBoot/NetBoot.h b/dev/ZKAKit/FirmwareKit/CoreBoot/NetBoot.h deleted file mode 100644 index da0b93a7..00000000 --- a/dev/ZKAKit/FirmwareKit/CoreBoot/NetBoot.h +++ /dev/null @@ -1,9 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include diff --git a/dev/ZKAKit/FirmwareKit/EFI.h b/dev/ZKAKit/FirmwareKit/EFI.h deleted file mode 100644 index 53ff3959..00000000 --- a/dev/ZKAKit/FirmwareKit/EFI.h +++ /dev/null @@ -1,11 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include - -/// @note this header is used to reference the EFI/EFI.h diff --git a/dev/ZKAKit/FirmwareKit/EFI/API.h b/dev/ZKAKit/FirmwareKit/EFI/API.h deleted file mode 100644 index 7bb83ebf..00000000 --- a/dev/ZKAKit/FirmwareKit/EFI/API.h +++ /dev/null @@ -1,114 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#ifndef __EFI_API__ -#define __EFI_API__ - -#include -#include -#include -#include - -#define kZKASubsystem 17 - -#ifdef __ZBAOSLDR__ -// forward decl. -class BTextWriter; - -#define __BOOTKIT_NO_INCLUDE__ 1 - -#include -#include -#endif // ifdef __ZBAOSLDR__ - -inline EfiSystemTable* ST = nullptr; -inline EfiBootServices* BS = nullptr; - -EXTERN_C void rt_cli(); -EXTERN_C void rt_hlt(); - -namespace EFI -{ - /// @brief Halt and clear interrupts. - /// @return - inline Void Stop() noexcept - { - while (1) - { - rt_hlt(); - rt_cli(); - } - } - - /** -@brief Exit EFI API to let the OS load correctly. -Bascially frees everything we have in the EFI side. -*/ - inline void ExitBootServices(UInt64 MapKey, EfiHandlePtr ImageHandle) noexcept - { - if (!ST) - return; - - ST->BootServices->ExitBootServices(ImageHandle, MapKey); - } - - enum - { - kPartEPM, - kPartGPT, - kPartMBR, - kPartCnt, - }; - - inline UInt32 Platform() noexcept - { - return kPeMachineAMD64; - } - - /*** - * @brief Throw an error, stop execution as well. - * @param ErrorCode error code to be print. - * @param Reason reason to be print. - */ - inline void ThrowError(const EfiCharType* ErrorCode, - const EfiCharType* Reason) noexcept - { - ST->ConOut->OutputString(ST->ConOut, L"\r*** STOP ***\r"); - - ST->ConOut->OutputString(ST->ConOut, L"*** Error: "); - ST->ConOut->OutputString(ST->ConOut, ErrorCode); - - ST->ConOut->OutputString(ST->ConOut, L", Reason: "); - ST->ConOut->OutputString(ST->ConOut, Reason); - - ST->ConOut->OutputString(ST->ConOut, L" ***\r"); - - EFI::Stop(); - } -} // namespace EFI - -inline void InitEFI(EfiSystemTable* SystemTable) noexcept -{ - if (!SystemTable) - return; - - ST = SystemTable; - BS = ST->BootServices; - - ST->ConOut->ClearScreen(SystemTable->ConOut); - ST->ConOut->SetAttribute(SystemTable->ConOut, kEFIYellow); - - ST->BootServices->SetWatchdogTimer(0, 0, 0, nullptr); - ST->ConOut->EnableCursor(ST->ConOut, false); -} - -#ifdef __ZBAOSLDR__ - -#include - -#endif // ifdef __ZBAOSLDR__ - -#endif /* ifndef __EFI_API__ */ diff --git a/dev/ZKAKit/FirmwareKit/EFI/EFI.h b/dev/ZKAKit/FirmwareKit/EFI/EFI.h deleted file mode 100644 index befa4e87..00000000 --- a/dev/ZKAKit/FirmwareKit/EFI/EFI.h +++ /dev/null @@ -1,884 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#ifndef FIRMWARE_KIT_EFI_H -#define FIRMWARE_KIT_EFI_H - -/** -@brief Implementation of the main EFI protocols. -*/ - -#include - -using namespace Kernel; - -/* we always use stdcall in EFI, the pascal way of calling functions. */ - -#ifndef EPI_API -#define EFI_API __attribute__((ms_abi)) -#endif // ifndef EPI_API - -#define IN -#define OUT -#define OPTIONAL - -#define EFI_FINAL final - -// Forward decls - -struct EfiTableHeader; -struct EfiLoadFileProtocol; -struct EfiSimpleTextOutputProtocol; -struct EfiDevicePathProtocol; -struct EfiBootServices; -struct EfiMemoryDescriptor; -struct EfiSystemTable; -struct EfiGUID; -struct EfiFileDevicePathProtocol; -struct EfiHandle; -struct EfiGraphicsOutputProtocol; -struct EfiBitmask; -struct EfiFileProtocol; - -typedef UInt64 EfiStatusType; - -/// @brief Core Handle Kind -/// Self is like NT's Win32 HANDLE type. -typedef struct EfiHandle -{ -} * EfiHandlePtr; - -/* UEFI uses wide characters by default. */ -typedef WideChar EfiCharType; - -typedef UInt64 EfiPhysicalAddress; -typedef UIntPtr EfiVirtualAddress; - -/// What's BootBolicy? -/// If TRUE, indicates that the request originates from the boot manager, and -/// that the boot manager is attempting to load FilePath as a boot selection. If -/// FALSE, then FilePath must match an exact file to be loaded. - -typedef UInt64(EFI_API* EfiTextString)(struct EfiSimpleTextOutputProtocol* Self, - const WideChar* OutputString); - -typedef UInt64(EFI_API* EfiTextAttrib)(struct EfiSimpleTextOutputProtocol* Self, - const WideChar Attribute); - -typedef UInt64(EFI_API* EfiTextClear)(struct EfiSimpleTextOutputProtocol* Self); - -typedef UInt64(EFI_API* EfiLoadFile)(EfiLoadFileProtocol* Self, - EfiFileDevicePathProtocol* FilePath, - Boolean BootPolicy, - UInt32* BufferSize, - VoidPtr Buffer); - -typedef UInt64(EFI_API* EfiCopyMem)(VoidPtr DstBuf, VoidPtr SrcBuf, SizeT Length); - -typedef UInt64(EFI_API* EfiSetMem)(VoidPtr DstBuf, Char Byte, SizeT Length); - -typedef UInt64(EFI_API* EfiHandleProtocol)(EfiHandlePtr Handle, EfiGUID* Guid, VoidPtr* Device); - -typedef UInt64(EFI_API* EfiLocateDevicePath)(EfiGUID* Protocol, - EfiDevicePathProtocol** DevicePath, - EfiHandlePtr Device); - -typedef UInt64(EFI_API* EfiStartImage)(EfiHandlePtr Handle, VoidPtr ArgsSize, VoidPtr ArgsPtr); - -typedef UInt64(EFI_API* EfiLoadImage)(Boolean BootPolicy, - EfiHandlePtr ParentHandle, - EfiFileDevicePathProtocol* DeviceFile, - VoidPtr buffer, - SizeT size, - EfiHandlePtr* ppHandle); - -/// EFI pool helpers, taken from iPXE. - -typedef enum EfiMemoryType -{ - /// - /// Not used. - /// - EfiReservedMemoryType, - /// - /// The code portions of a loaded application. - /// (Note that UEFI OS loaders are UEFI applications.) - /// - EfiLoaderCode, - /// - /// The data portions of a loaded application and the default data allocation - /// type used by an application to allocate pool memory. - /// - EfiLoaderData, - /// - /// The code portions of a loaded Boot Services Driver. - /// - EfiBootServicesCode, - /// - /// The data portions of a loaded Boot Serves Driver, and the default data - /// allocation type used by a Boot Services Driver to allocate pool memory. - /// - EfiBootServicesData, - /// - /// The code portions of a loaded Runtime Services Driver. - /// - EfiRuntimeServicesCode, - /// - /// The data portions of a loaded Runtime Services Driver and the default - /// data allocation type used by a Runtime Services Driver to allocate pool - /// memory. - /// - EfiRuntimeServicesData, - /// - /// Free (unallocated) memory. - /// - EfiConventionalMemory, - /// - /// Memory in which errors have been detected. - /// - EfiUnusableMemory, - /// - /// Memory that holds the ACPI tables. - /// - EfiACPIReclaimMemory, - /// - /// Address space reserved for use by the firmware. - /// - EfiACPIMemoryNVS, - /// - /// Used by system firmware to request that a memory-mapped IO region - /// be mapped by the OS to a virtual address so it can be accessed by EFI - /// runtime services. - /// - EfiMemoryMappedIO, - /// - /// System memory-mapped IO region that is used to translate memory - /// cycles to IO cycles by the processor. - /// - EfiMemoryMappedIOPortSpace, - /// - /// Address space reserved by the firmware for code that is part of the - /// processor. - /// - EfiPalCode, - /// - /// A memory region that operates as EfiConventionalMemory, - /// however it happens to also support byte-addressable non-volatility. - /// - EfiPersistentMemory, - /// - /// A memory region that describes system memory that has not been accepted - /// by a corresponding call to the underlying isolation architecture. - /// - EfiUnacceptedMemoryType, - /// - /// The last type of memory. - /// Not a real type. - /// - EfiMaxMemoryType, -} EfiMemoryType; - -typedef enum EfiAllocateType -{ - /// Anything that satisfy the request. - AllocateAnyPages, - AllocateMaxAddress, - /// - /// Allocate pages at a specified address. - /// - AllocateAddress, - /// - /// Maximum enumeration value that may be used for bounds checking. - /// - MaxAllocateType -} EfiAllocateType; - -typedef struct EfiMemoryDescriptor -{ - /// - /// Kind of the memory region. - /// Kind EFI_MEMORY_TYPE is defined in the - /// AllocatePages() function description. - /// - UInt32 Kind; - /// - /// Physical address of the first byte in the memory region. PhysicalStart - /// must be aligned on a 4 KiB boundary, and must not be above - /// 0xfffffffffffff000. Kind EFI_PHYSICAL_ADDRESS is defined in the - /// AllocatePages() function description - /// - EfiPhysicalAddress PhysicalStart; - /// - /// Virtual address of the first byte in the memory region. - /// VirtualStart must be aligned on a 4 KiB boundary, - /// and must not be above 0xfffffffffffff000. - /// - EfiVirtualAddress VirtualStart; - /// - /// NumberOfPagesNumber of 4 KiB pages in the memory region. - /// NumberOfPages must not be 0, and must not be any value - /// that would represent a memory page with a start address, - /// either physical or virtual, above 0xfffffffffffff000. - /// - UInt64 NumberOfPages; - /// - /// Attributes of the memory region that describe the bit mask of capabilities - /// for that memory region, and not necessarily the current settings for that - /// memory region. - /// - UInt64 Attribute; -} EfiMemoryDescriptor; - -typedef UInt64(EFI_API* EfiAllocatePool)(EfiMemoryType PoolType, UInt32 Size, VoidPtr* Buffer); - -typedef UInt64(EFI_API* EfiFreePool)(VoidPtr Buffer); - -typedef UInt64(EFI_API* EfiCalculateCrc32)(VoidPtr Data, UInt32 DataSize, UInt32* CrcOut); - -/** -@brief Present in every header, used to identify a UEFI structure. -*/ -typedef struct EfiTableHeader -{ - UInt64 Signature; - UInt32 Revision; - UInt32 HeaderSize; - UInt32 Crc32; - UInt32 Reserved; -} EfiTableHeader; - -#define EFI_ACPI_TABLE_PROTOCOL_GUID \ - { \ - 0xffe06bdd, 0x6107, 0x46a6, \ - { \ - 0x7b, 0xb2, 0x5a, 0x9c, 0x7e, 0xc5, 0x27, 0x5c \ - } \ - } - -#define EFI_LOAD_FILE_PROTOCOL_GUID \ - { \ - 0x56EC3091, 0x954C, 0x11d2, \ - { \ - 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b \ - } \ - } - -#define EFI_LOAD_FILE2_PROTOCOL_GUID \ - { \ - 0x4006c0c1, 0xfcb3, 0x403e, \ - { \ - 0x99, 0x6d, 0x4a, 0x6c, 0x87, 0x24, 0xe0, 0x6d \ - } \ - } - -#define EFI_LOADED_IMAGE_PROTOCOL_GUID \ - { \ - 0x5B1B31A1, 0x9562, 0x11d2, \ - { \ - 0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B \ - } \ - } - -#define EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID \ - { \ - 0x9042a9de, 0x23dc, 0x4a38, \ - { \ - 0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a \ - } \ - } - -#define EFI_LOADED_IMAGE_PROTOCOL_REVISION 0x1000 - -#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID \ - { \ - 0x0964e5b22, 0x6459, 0x11d2, \ - { \ - 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b \ - } \ - } - -#define EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL_GUID \ - { \ - 0xbc62157e, 0x3e33, 0x4fec, \ - { \ - 0x99, 0x20, 0x2d, 0x3b, 0x36, 0xd7, 0x50, 0xdf \ - } \ - } - -#define EFI_DEVICE_PATH_PROTOCOL_GUID \ - { \ - 0x9576e91, 0x6d3f, 0x11d2, \ - { \ - 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b \ - } \ - } - -#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID \ - { \ - 0x0964e5b22, 0x6459, 0x11d2, \ - { \ - 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b \ - } \ - } - -typedef UInt64(EfiImageUnload)(EfiHandlePtr ImageHandle); - -enum -{ - kPixelRedGreenBlueReserved8BitPerColor, - kPixelBlueGreenRedReserved8BitPerColor, - kPixelBitMask, - kPixelBltOnly, - kPixelFormatMax -}; - -typedef struct EfiBitmask -{ - UInt32 RedMask; - UInt32 GreenMask; - UInt32 BlueMask; - UInt32 ReservedMask; -} EfiBitmask; - -typedef struct -{ - UInt8 Blue; - UInt8 Green; - UInt8 Red; - UInt8 Reserved; -} EfiGraphicsOutputBltPixel; - -typedef enum EfiGraphicsOutputProtocolBltOperation -{ - EfiBltVideoFill, - EfiBltVideoToBltBuffer, - EfiBltBufferToVideo, - EfiBltVideoToVideo, - EfiGraphicsOutputBltOperationMax -} EfiGraphicsOutputProtocolBltOperation; - -typedef struct EfiGraphicsOutputProtocolModeInformation -{ - UInt32 Version; - UInt32 HorizontalResolution; - UInt32 VerticalResolution; - UInt32 PixelFormat; - EfiBitmask PixelInformation; - UInt32 PixelsPerScanLine; -} EfiGraphicsOutputProtocolModeInformation; - -typedef UInt64(EFI_API* EfiGraphicsOutputProtocolQueryMode)( - EfiGraphicsOutputProtocol* Self, UInt32 ModeNumber, UInt32* SizeOfInfo, EfiGraphicsOutputProtocolModeInformation** Info); - -typedef UInt64(EFI_API* EfiGraphicsOutputProtocolSetMode)( - EfiGraphicsOutputProtocol* Self, UInt32 ModeNumber); - -typedef UInt64(EFI_API* EfiGraphicsOutputProtocolBlt)( - EfiGraphicsOutputProtocol* Self, EfiGraphicsOutputBltPixel* BltBuffer, EfiGraphicsOutputProtocolBltOperation BltOperation, UInt32 SourceX, UInt32 SourceY, UInt32 DestinationX, UInt32 DestinationY, UInt32 Width, UInt32 Height, UInt32 Delta); - -typedef struct -{ - UInt32 MaxMode; - UInt32 Mode; - EfiGraphicsOutputProtocolModeInformation* Info; - UInt32 SizeOfInfo; - UIntPtr FrameBufferBase; - UInt32 FrameBufferSize; -} EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE; - -typedef struct EfiGraphicsOutputProtocol -{ - EfiGraphicsOutputProtocolQueryMode QueryMode; - EfiGraphicsOutputProtocolSetMode SetMode; - EfiGraphicsOutputProtocolBlt Blt; - EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE* Mode; -} EfiGraphicsOutputProtocol; - -typedef struct EfiLoadImageProtocol -{ - UInt32 Revision; - EfiHandlePtr ParentHandle; - EfiSystemTable* SystemTable; - - // Source location of the image - EfiHandlePtr DeviceHandle; - EfiDevicePathProtocol* FilePath; - Void* Reserved; - - // Image’s load options - UInt32 LoadOptionsSize; - Void* LoadOptions; - - // Location where image was loaded - Void* ImageBase; - UInt64 ImageSize; - EfiMemoryType ImageCodeType; - EfiMemoryType ImageDataType; - EfiImageUnload Unload; -} EfiLoadImageProtocol; - -typedef struct EfiLoadFileProtocol -{ - EfiLoadFile LoadFile; -} EfiLoadFileProtocol; - -typedef struct EfiDevicePathProtocol -{ - UInt8 Kind; - UInt8 SubType; - UInt8 Length[2]; -} EfiDevicePathProtocol; - -typedef struct EfiFileDevicePathProtocol -{ - EfiDevicePathProtocol Proto; - - /// - /// File Path of this struct - /// - WideChar Path[kPathLen]; -} EfiFileDevicePathProtocol; - -typedef UInt64(EFI_API* EfiExitBootServices)(VoidPtr ImageHandle, - UInt32 MapKey); - -typedef UInt64(EFI_API* EfiAllocatePages)(EfiAllocateType AllocType, - EfiMemoryType MemType, - UInt32 Count, - EfiPhysicalAddress* Memory); - -typedef UInt64(EFI_API* EfiFreePages)(EfiPhysicalAddress* Memory, UInt32 Pages); - -typedef UInt64(EFI_API* EfiGetMemoryMap)(UInt32* MapSize, - EfiMemoryDescriptor* DescPtr, - UInt32* MapKey, - UInt32* DescSize, - UInt32* DescVersion); - -/** - * @brief GUID type, something you can also find in CFKit. - */ -typedef struct EfiGUID EFI_FINAL -{ - UInt32 Data1; - UInt16 Data2; - UInt16 Data3; - UInt8 Data4[8]; -} EfiGUID; - -/*** - * Protocol stuff... - */ - -/** some helpers */ -#define EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL 0x00000001 -#define EFI_OPEN_PROTOCOL_GET_PROTOCOL 0x00000002 -#define EFI_OPEN_PROTOCOL_TEST_PROTOCOL 0x00000004 -#define EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER 0x00000008 -#define EFI_OPEN_PROTOCOL_BY_DRIVER 0x00000010 -#define EFI_OPEN_PROTOCOL_EXCLUSIVE 0x00000020 - -typedef UInt64(EFI_API* EfiLocateProtocol)(EfiGUID* Protocol, - VoidPtr Registration, - VoidPtr* Interface); - -typedef UInt64(EFI_API* EfiOpenProtocol)(EfiHandlePtr Handle, EfiGUID* Guid, VoidPtr* Interface, EfiHandlePtr AgentHandle, EfiHandlePtr ControllerHandle, UInt32 Attributes); - -typedef UInt64(EFI_API* EfiEnableCursor)(EfiSimpleTextOutputProtocol* Self, Boolean Visible); - -/** -@name EfiBootServices -@brief UEFI Boot Services record, it contains functions necessary to a -firmware level application. -*/ -typedef struct EfiBootServices -{ - EfiTableHeader SystemTable; - VoidPtr RaiseTPL; - VoidPtr RestoreTPL; - EfiAllocatePages AllocatePages; - EfiFreePages FreePages; - EfiGetMemoryMap GetMemoryMap; - EfiAllocatePool AllocatePool; - EfiFreePool FreePool; - VoidPtr CreateEvent; - VoidPtr SetTimer; - VoidPtr WaitForEvent; - VoidPtr SignalEvent; - VoidPtr CloseEvent; - VoidPtr CheckEvent; - VoidPtr InstallProtocolInterface; - VoidPtr ReinstallProtocolInterface; - VoidPtr UninstallProtocolInterface; - EfiHandleProtocol HandleProtocol; - VoidPtr Reserved; - VoidPtr RegisterProtocolNotify; - VoidPtr LocateHandle; - EfiLocateDevicePath LocateDevicePath; - VoidPtr InstallConfigurationTable; - EfiLoadImage LoadImage; - EfiStartImage StartImage; - VoidPtr Exit; - VoidPtr UnloadImage; - EfiExitBootServices ExitBootServices; - VoidPtr GetNextMonotonicCount; - VoidPtr Stall; - EfiStatusType(EFI_API* SetWatchdogTimer)(UInt32 Timeout, UInt64 WatchdogCode, UInt32 DataSize, EfiCharType* Data); - VoidPtr ConnectController; - VoidPtr DisconnectController; - EfiOpenProtocol OpenProtocol; - VoidPtr CloseProtocol; - VoidPtr OpenProtocolInformation; - VoidPtr ProtocolsPerHandle; - VoidPtr LocateHandleBuffer; - EfiLocateProtocol LocateProtocol; - VoidPtr InstallMultipleProtocolInterfaces; - VoidPtr UninstallMultipleProtocolInterfaces; - EfiCalculateCrc32 CalculateCrc32; - EfiCopyMem CopyMem; - EfiSetMem SetMem; - VoidPtr CreateEventEx; -} EfiBootServices; - -#define kEntireDevPath 0xFF -#define kThisInstancePath 0x01 - -/** -@brief PrintF like protocol. -*/ -typedef struct EfiSimpleTextOutputProtocol -{ - VoidPtr Reset; - EfiTextString OutputString; - VoidPtr TestString; - VoidPtr QueryMode; - VoidPtr SetMode; - EfiTextAttrib SetAttribute; - EfiTextClear ClearScreen; - VoidPtr SetCursorPosition; - EfiEnableCursor EnableCursor; - VoidPtr Mode; -} EfiSimpleTextOutputProtocol; - -typedef UInt64(EFI_API* EfiOpenVolume)(struct EfiSimpleFilesystemProtocol*, - struct EfiFileProtocol**); - -struct EfiSimpleFilesystemProtocol -{ - UInt64 Revision; - EfiOpenVolume OpenVolume; -}; - -/** -@brief The Structure that they give you when booting. -*/ -typedef struct EfiSystemTable -{ - EfiTableHeader SystemHeader; - WideChar* FirmwareVendor; - UInt32 FirmwareRevision; - EfiHandlePtr ConsoleInHandle; - VoidPtr ConIn; - EfiHandlePtr ConsoleOutHandle; - EfiSimpleTextOutputProtocol* ConOut; - EfiHandlePtr StandardErrorHandle; - VoidPtr StdErr; - VoidPtr RuntimeServices; - EfiBootServices* BootServices; - UInt64 NumberOfTableEntries; - /// The configuration table (contains the RSD PTR entry.) - struct - { - EfiGUID VendorGUID; - VoidPtr VendorTable; - } * ConfigurationTable; -} EfiSystemTable; - -#define kEfiOk 0 -#define kEfiFail -1 -#define kBufferTooSmall 5 - -#define EFI_EXTERN_C extern "C" - -typedef struct EfiIPV4 -{ - UInt8 Addr[4]; -} EfiIPV4; - -/// -/// 16-byte buffer. An IPv6 internet protocol address. -/// -typedef struct EfiIPV6 -{ - UInt8 Addr[16]; -} EfiIPV6; - -#define kEFIYellow (0x01 | 0x02 | 0x04 | 0x08) - -#ifdef __x86_64 -#define __EFI_x86_64__ 1 -#endif // __x86_64 - -enum -{ - kEFIHwDevicePath = 0x01, - kEFIAcpiDevicePath = 0x02, - kEFIMessaingDevicePath = 0x03, - kEFIMediaDevicePath = 0x04, - kEFIBiosBootPath = 0x05, - kEFIEndOfPath = 0x06, - kEFICount = 6, -}; - -#define END_DEVICE_PATH_TYPE 0x7f -#define END_ENTIRE_DEVICE_PATH_SUBTYPE 0xFF -#define END_INSTANCE_DEVICE_PATH_SUBTYPE 0x01 - -#define kEfiOffsetOf(T, F) __builtin_offsetof(T, F) - -/// File I/O macros - -#define kEFIFileRead 0x0000000000000001 -#define kEFIFileWrite 0x0000000000000002 -#define kEFIFileCreate 0x0000000000000000 - -#define kEFIReadOnly 0x01 -#define kEFIHidden 0x02 -#define kEFISystem 0x04 -#define kEFIReserved 0x08 -#define kEFIDirectory 0x10 -#define kEFIArchive 0x20 - -#define EFI_FILE_PROTOCOL_REVISION 0x00010000 -#define EFI_FILE_PROTOCOL_REVISION2 0x00020000 -#define EFI_FILE_PROTOCOL_LATEST_REVISION EFI_FILE_PROTOCOL_REVISION2 - -#define EFI_EXTRA_DESCRIPTOR_SIZE 8 - -#define EFI_MP_SERVICES_PROTOCOL_GUID \ - { \ - 0x3fdda605, 0xa76e, 0x4f46, \ - { \ - 0xad, 0x29, 0x12, 0xf4, \ - 0x53, 0x1b, 0x3d, 0x08 \ - } \ - } - -#define PROCESSOR_AS_BSP_BIT 0x00000001 -#define PROCESSOR_ENABLED_BIT 0x00000002 -#define PROCESSOR_HEALTH_STATUS_BIT 0x00000004 - -#define END_OF_CPU_LIST 0xffffffff - -typedef struct EfiIOToken -{ - // - // If Event is NULL, then blocking I/O is performed. - // If Event is not NULL and non-blocking I/O is supported, then non-blocking - // I/O is performed, and Event will be signaled when the read request is - // completed. The caller must be prepared to handle the case where the - // callback associated with Event occurs before the original asynchronous I/O - // request call returns. - // - UInt64 Event; - - // - // Defines whether or not the signaled event encountered an error. - // - UInt64 Status; - - // - // For OpenEx(): Not Used, ignored. - // For ReadEx(): On input, the size of the Buffer. On output, the amount of - // data returned in Buffer. - // In both cases, the size is measured in bytes. - // For WriteEx(): On input, the size of the Buffer. On output, the amount of - // data actually written. - // In both cases, the size is measured in bytes. - // For FlushEx(): Not used, ignored. - // - UInt32 BufferSize; - - // - // For OpenEx(): Not Used, ignored. - // For ReadEx(): The buffer into which the data is read. - // For WriteEx(): The buffer of data to write. - // For FlushEx(): Not Used, ignored. - // - Void* Buffer; -} EfiIOToken; - -typedef struct EfiFileProtocol -{ - UInt64 Revision; - - EfiStatusType(EFI_API* Open)(struct EfiFileProtocol* Self, - struct EfiFileProtocol** Out, - EfiCharType* CharType, - UInt64 OpenMode, - UInt64 Attrib); - - EfiStatusType(EFI_API* Close)(struct EfiFileProtocol* Self); - - EfiStatusType(EFI_API* Delete)(struct EfiFileProtocol* Self); - - EfiStatusType(EFI_API* Read)(struct EfiFileProtocol* Self, UInt64* BufSize, VoidPtr BufOut); - - EfiStatusType(EFI_API* Write)(struct EfiFileProtocol* Self, UInt64* BufSize, VoidPtr BufOut); - - EfiStatusType(EFI_API* GetPosition)(EfiFileProtocol* Self, UInt64* Position); - - EfiStatusType(EFI_API* SetPosition)(EfiFileProtocol* Self, UInt64* Position); - - EfiStatusType(EFI_API* GetInfo)(struct EfiFileProtocol*, struct EfiGUID*, UInt32*, void*); - - EfiStatusType(EFI_API* SetInfo)(struct EfiFileProtocol*, struct EfiGUID*, UInt32*, void*); - - EfiStatusType(EFI_API* Flush)(EfiFileProtocol*); - - EfiStatusType(EFI_API* OpenEx)(EfiFileProtocol* Self, - EfiFileProtocol** OutHandle, - EfiCharType* Path, - UInt64 Mode, - UInt64 Attrib, - struct EfiIOToken* Token); - - EfiStatusType(EFI_API* ReadEx)(EfiFileProtocol* Self, - struct EfiIOToken* Token); - - EfiStatusType(EFI_API* WriteEx)(EfiFileProtocol* Self, - struct EfiIOToken* Token); - - EfiStatusType(EFI_API* FlushEx)(EfiFileProtocol* Self, - struct EfiIOToken* Token); -} EfiFileProtocol, *EfiFileProtocolPtr; - -typedef UInt64 EfiCursorType; - -typedef struct EfiTime -{ - UInt16 Year; - UInt8 Month; - UInt8 Day; - UInt8 Hour; - UInt8 Minute; - UInt8 Second; - UInt8 Pad1; - UInt32 Nanosecond; - Int16 TimeZone; - UInt8 Daylight; - UInt8 Pad2; -} EfiTime; - -#define EFI_FILE_INFO_GUID \ - { \ - 0x09576e92, 0x6d3f, 0x11d2, \ - { \ - 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b \ - } \ - } - -struct EfiFileInfo EFI_FINAL -{ - /// @brief Structure size. - UInt64 Size; - /// @brief File size. - UInt64 FileSize; - /// @brief Physical size on disk. - UInt64 PhysicalSize; - /// @brief Create time. - EfiTime CreateTime; - /// @brief Last access time. - EfiTime LastAccessTime; - /// @brief Edit time. - EfiTime EditTime; - /// @brief Attributes. - UInt64 Attribute; - /// @brief VLA file name. - WideChar FileName[1]; -}; - -//******************************************************* -// EFI_CPU_PHYSICAL_LOCATION -// @note As in the EFI specs. -//******************************************************* -typedef struct _EfiCPUPhyiscalLocation -{ - UInt32 Package; - UInt32 Core; - UInt32 Thread; -} EfiCPUPhyiscalLocation; - -typedef union _EfiExtendedProcessorInformation { - EfiCPUPhyiscalLocation Location2; -} EfiExtendedProcessorInformation; - -typedef struct _EfiProcessorInformation -{ - UInt64 ProcessorId; - UInt32 StatusFlag; - EfiCPUPhyiscalLocation Location; - EfiExtendedProcessorInformation ExtendedInformation; -} EfiProcessorInformation; - -typedef EfiStatusType EFI_API (*EfiMpServicesGetNumberOfProcessors)( - IN struct _EfiMpServicesProtocol* Self, - OUT UInt32* NumberOfProcessors, - OUT UInt32* NumberOfEnabledProcessors); - -typedef EfiStatusType EFI_API (*EfiMpServicesGetProcessorInfo)( - IN struct _EfiMpServicesProtocol* Self, - IN UInt32* ProcessorNumber, - OUT struct _EfiProcessorInformation* NumberOfEnabledProcessors); - -typedef void EFI_API (*EFI_AP_PROCEDURE)( - IN VoidPtr ProcedureArgument); - -typedef EfiStatusType EFI_API (*EfiMpServicesStartupAllAPS)( - IN struct _EfiMpServicesProtocol* Self, - IN EFI_AP_PROCEDURE Procedure, - IN Boolean SingleThread, - IN VoidPtr WaitEvent OPTIONAL, // EFI_EVENT first, but unused here. - IN UInt32 TimeoutInMicroSeconds, - IN Void* ProcedureArgument OPTIONAL, - OUT UInt32** FailedCpuList OPTIONAL); - -typedef EfiStatusType EFI_API (*EfiMpServicesSwitchBSP)( - IN struct _EfiMpServicesProtocol* Self, - IN UInt32 ProcessorNumber, - IN Boolean EnableOldBSP); - -typedef EfiStatusType EFI_API (*EfiMpServicesStartupThisAP)( - IN struct _EfiMpServicesProtocol* Self, - IN EFI_AP_PROCEDURE Procedure, - IN UInt32 ProcessorNumber, - IN VoidPtr WaitEvent OPTIONAL, - IN UInt32 TimeoutInMicroseconds, - IN Void* ProcedureArgument OPTIONAL, - OUT Boolean* Finished OPTIONAL); - -typedef EfiStatusType EFI_API (*EfiMpServicesDisableThisAP)( - IN struct _EfiMpServicesProtocol* Self, - IN UInt32 ProcessorNumber, - IN Boolean EnableAP, - IN UInt32* HealthFlag OPTIONAL); - -typedef EfiStatusType EFI_API (*EfiMpServicesWhoAmI)( - IN struct _EfiMpServicesProtocol* Self, - OUT UInt32* ProcessorNumber); - -typedef struct _EfiMpServicesProtocol -{ - EfiMpServicesGetNumberOfProcessors GetNumberOfProcessors; - EfiMpServicesGetProcessorInfo GetProcessorInfo; - EfiMpServicesStartupAllAPS StartupAllAPs; - EfiMpServicesStartupThisAP StartupThisAP; - EfiMpServicesSwitchBSP SwitchBSP; - EfiMpServicesDisableThisAP EnableDisableAP; - EfiMpServicesWhoAmI WhoAmI; -} EfiMpServicesProtocol; - -#endif // ifndef FIRMWARE_KIT_EFI_H diff --git a/dev/ZKAKit/FirmwareKit/EFI/NS.h b/dev/ZKAKit/FirmwareKit/EFI/NS.h deleted file mode 100644 index cba490de..00000000 --- a/dev/ZKAKit/FirmwareKit/EFI/NS.h +++ /dev/null @@ -1,15 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include - -namespace Firmware::Detail::EFI -{ - using namespace Kernel; -#include -} // namespace Firmware::Detail::EFI diff --git a/dev/ZKAKit/FirmwareKit/EPM.h b/dev/ZKAKit/FirmwareKit/EPM.h deleted file mode 100644 index 7a721e4b..00000000 --- a/dev/ZKAKit/FirmwareKit/EPM.h +++ /dev/null @@ -1,122 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -/** - @brief The Explicit Partition Map scheme. -*/ - -#ifndef __FIRMWARE_EPM_H__ -#define __FIRMWARE_EPM_H__ - -#include - -#define kEPMNameLength (32) -#define kEPMFilesystemLength (16) -#define kEPMMagicLength (5) - -/* @brief AMD64 magic for EPM */ -#define kEPMMagic86 "EPMAM" - -/* @brief RISC-V magic for EPM */ -#define kEPMMagicRISCV "EPMRV" - -/* @brief ARM magic for EPM */ -#define kEPMMagicARM "EPMAR" - -/* @brief 64x0 magic for EPM */ -#define kEPMMagic64k "EPM64" - -/* @brief 32x0 magic for EPM */ - -#define kEPMMagic32k "EPM32" - -/* @brief POWER magic for EPM */ - -#define kEPMMagicPPC "EPMPC" - -/* @brief UEFI magic for EPM */ - -#define kEPMMagicUEFI "EPMUE" - -/* @brief CoreBoot magic for EPM */ - -#define kEPMMagicCoreBoot "EPMCB" - -/* @brief Invalid magic for EPM */ - -#define kEPMMagicError "EPM??" - -#ifdef __ZKA_AMD64__ -#define kEPMMagic kEPMMagic86 -#else -#ifdef __ZKA_ARM64__ -#define kEPMMagic kEPMMagicARM -#else -#define kEPMMagic kEPMMagicError -#endif -#endif - -///! @brief partition must start at this address. -///! Anything below is reserved for Data backup by the Main OS. -#define kEPMStartPartitionBlk (sizeof(_BOOT_BLOCK_STRUCT)) - -///! @brief Current EPM revision. -#define kEPMRevision (0xAD) - -///! @brief Current EPM revision. -#define kEPMRevisionUEFI (0xAF) - -/// !@brief EPM base address. -#define kEPMBaseLba (0U) - -struct _BLOCK_GUID_STRUCT; -struct _BOOT_BLOCK_STRUCT; - -/* The first 0 > 128 addresses of a disk contains these headers. */ - -/// @brief EPM GUID structure. -typedef struct _BLOCK_GUID_STRUCT -{ - Kernel::UInt32 Data1; - Kernel::UInt16 Data2; - Kernel::UInt16 Data3; - Kernel::UInt8 Data4[8]; -} BLOCK_GUID_STRUCT; - -/** - * @brief The EPM boot block. - * @note NumBlock and LbaStart are ignored on some platforms. - */ -struct PACKED _BOOT_BLOCK_STRUCT -{ - Kernel::Char Magic[kEPMMagicLength]; - Kernel::Char Name[kEPMNameLength]; - BLOCK_GUID_STRUCT Uuid; - Kernel::Int32 Version; - Kernel::Int64 NumBlocks; - Kernel::Int64 SectorSz; - Kernel::Int64 LbaStart; // base offset - Kernel::Int64 LbaEnd; // addition of lba_start to get the end of partition. - Kernel::Int16 Kind; - Kernel::Int32 FsVersion; - Kernel::Char Fs[kEPMFilesystemLength]; /* NeFS, ffs2... */ - Kernel::Char Reserved[401]; // to fill a full sector. -}; - -///! @brief Version kind enum. -///! @brief Use in boot block version field. - -enum -{ - kEPMEmbeddedOS = 0xcf, // Embedded OS - kEPMLinux = 0x8f, // Linux on EPM - kEPMBSD = 0x9f, // Berkeley Soft. Distribution - kEPMNewOS = 0x1f, // This OS. -}; - -typedef struct _BOOT_BLOCK_STRUCT BOOT_BLOCK_STRUCT; - -#endif // ifndef __FIRMWARE_EPM_H__ diff --git a/dev/ZKAKit/FirmwareKit/GPT.h b/dev/ZKAKit/FirmwareKit/GPT.h deleted file mode 100644 index 0ba8f222..00000000 --- a/dev/ZKAKit/FirmwareKit/GPT.h +++ /dev/null @@ -1,48 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include -#include - -#define kSectorSizeGPT 512 - -namespace Kernel -{ - typedef EfiGUID GPT_GUID; - struct GPT_PARTITION_TABLE; - struct GPT_PARTITION_ENTRY; - - struct PACKED GPT_PARTITION_TABLE final - { - Char PartitionName[8]; - UInt32 Revision; - UInt32 HeaderSize; - UInt32 ChecksumCRC32; - UInt32 Reserved1; - UInt64 LBAHeader; - UInt64 LBAAltHeader; - UInt64 FirstGPTEntry; - UInt64 LastGPTEntry; - GPT_GUID Guid; - UInt64 StartingLBA; - UInt32 NumPartitionEntries; - UInt32 SizeOfEntries; - UInt32 CRC32PartEntry; - UInt8 Reserved2[kSectorSizeGPT]; - }; - - struct PACKED GPT_PARTITION_ENTRY - { - GPT_GUID PartitionTypeGUID; - GPT_GUID UniquePartitionGUID; - UInt64 StartLBA; - UInt64 EndLBA; - UInt64 Attributes; - UInt8 Name[72]; - }; -} // namespace Kernel diff --git a/dev/ZKAKit/FirmwareKit/Handover.h b/dev/ZKAKit/FirmwareKit/Handover.h deleted file mode 100644 index 5ba32a04..00000000 --- a/dev/ZKAKit/FirmwareKit/Handover.h +++ /dev/null @@ -1,112 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -/** - * @file Handover.h - * @author Theater Quality Inc (amlalelmahrouss@icloud.com) - * @brief The handover boot protocol. - * @version 1.15 - * @date 2024-02-23 - * - * @copyright Copyright (c) 2024, Theater Quality Inc - * - */ - -#pragma once - -#include - -#define kHandoverMagic 0xBADCC -#define kHandoverVersion 0x0117 - -/* Initial bitmap pointer location and size. */ -#define kHandoverBitMapSz (gib_cast(4)) -#define kHandoverStructSz sizeof(HEL::BootInfoHeader) - -namespace Kernel::HEL -{ - /** - @brief The executable type enum. - */ - enum - { - kTypeKernel = 100, - kTypeKernelDriver = 101, - kTypeRsrc = 102, - kTypeInvalid = 103, - kTypeCount = 4, - }; - - /** - @brief The executable architecture enum. - */ - - enum - { - kArchAMD64 = 122, - kArchARM64 = 123, - kArchRISCV = 124, - kArchCount = 3, - }; - - struct BootInfoHeader final - { - UInt64 f_Magic; - UInt64 f_Version; - - VoidPtr f_BitMapStart; - SizeT f_BitMapSize; - - VoidPtr f_PageStart; - - VoidPtr f_KernelImage; - SizeT f_KernelSz; - VoidPtr f_StartupChime; - SizeT f_ChimeSz; - VoidPtr f_StartupImage; - SizeT f_StartupSz; - VoidPtr f_TTFallbackFont; - SizeT f_FontSz; - - WideChar f_FirmwareVendorName[32]; - SizeT f_FirmwareVendorLen; - - VoidPtr f_FirmwareCustomTables[2]; // On EFI 0: BS 1: ST - - struct - { - VoidPtr f_SmBios; - VoidPtr f_VendorPtr; - VoidPtr f_MpPtr; - Bool f_MultiProcessingEnabled; - } f_HardwareTables; - - struct - { - UIntPtr f_The; - SizeT f_Size; - UInt32 f_Width; - UInt32 f_Height; - UInt32 f_PixelFormat; - UInt32 f_PixelPerLine; - } f_GOP; - - UInt64 f_FirmwareSpecific[8]; - }; - - enum - { - kHandoverSpecificKind, - kHandoverSpecificAttrib, - kHandoverSpecificMemoryEfi, - }; - - /// @brief Alias of bootloader main type. - typedef void (*HandoverProc)(BootInfoHeader* boot_info); -} // namespace Kernel::HEL - -/// @brief Bootloader information header global variable. -inline Kernel::HEL::BootInfoHeader* kHandoverHeader = nullptr; diff --git a/dev/ZKAKit/HALKit/.gitkeep b/dev/ZKAKit/HALKit/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/dev/ZKAKit/HALKit/64x0/.hgkeep b/dev/ZKAKit/HALKit/64x0/.hgkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/dev/ZKAKit/HALKit/64x0/APM/.hgkeep b/dev/ZKAKit/HALKit/64x0/APM/.hgkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/dev/ZKAKit/HALKit/64x0/HalVirtualMemory.cc b/dev/ZKAKit/HALKit/64x0/HalVirtualMemory.cc deleted file mode 100644 index a8989ffc..00000000 --- a/dev/ZKAKit/HALKit/64x0/HalVirtualMemory.cc +++ /dev/null @@ -1,17 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include - -using namespace Kernel; - -/// @brief Flush system TLB, looks like the POWER version, as it acts the same, no specific instruction for that. -/// @note The 88K MMU should be present as well. -EXTERN_C void hal_flush_tlb() -{ - asm volatile("invltlb"); -} diff --git a/dev/ZKAKit/HALKit/64x0/MBCI/.gitkeep b/dev/ZKAKit/HALKit/64x0/MBCI/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/dev/ZKAKit/HALKit/64x0/ReadMe.md b/dev/ZKAKit/HALKit/64x0/ReadMe.md deleted file mode 100644 index 03ccd2d7..00000000 --- a/dev/ZKAKit/HALKit/64x0/ReadMe.md +++ /dev/null @@ -1,4 +0,0 @@ -64x0 Hardware Abstraction Layer - -- Supported CPU: Theater Quality Inc 64x0 -- Supported Firmware: CoreBoot diff --git a/dev/ZKAKit/HALKit/AMD64/CPUID.h b/dev/ZKAKit/HALKit/AMD64/CPUID.h deleted file mode 100644 index afcdc09f..00000000 --- a/dev/ZKAKit/HALKit/AMD64/CPUID.h +++ /dev/null @@ -1,86 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - - File: CPUID.h - Purpose: CPUID flags. - - Revision History: - - 30/01/24: Added file (amlel) - -------------------------------------------- */ - -#pragma once - -#include - -enum CPUFeatureEnum -{ - kCPUFeatureSSE3 = 1 << 0, - kCPUFeaturePCLMUL = 1 << 1, - kCPUFeatureDTES64 = 1 << 2, - kCPUFeatureMONITOR = 1 << 3, - kCPUFeatureDS_CPL = 1 << 4, - kCPUFeatureVMX = 1 << 5, - kCPUFeatureSMX = 1 << 6, - kCPUFeatureEST = 1 << 7, - kCPUFeatureTM2 = 1 << 8, - kCPUFeatureSSSE3 = 1 << 9, - kCPUFeatureCID = 1 << 10, - kCPUFeatureSDBG = 1 << 11, - kCPUFeatureFMA = 1 << 12, - kCPUFeatureCX16 = 1 << 13, - kCPUFeatureXTPR = 1 << 14, - kCPUFeaturePDCM = 1 << 15, - kCPUFeaturePCID = 1 << 17, - kCPUFeatureDCA = 1 << 18, - kCPUFeatureSSE4_1 = 1 << 19, - kCPUFeatureSSE4_2 = 1 << 20, - kCPUFeatureX2APIC = 1 << 21, - kCPUFeatureMOVBE = 1 << 22, - kCPUFeaturePOP3C = 1 << 23, - kCPUFeatureECXTSC = 1 << 24, - kCPUFeatureAES = 1 << 25, - kCPUFeatureXSAVE = 1 << 26, - kCPUFeatureOSXSAVE = 1 << 27, - kCPUFeatureAVX = 1 << 28, - kCPUFeatureF16C = 1 << 29, - kCPUFeatureRDRAND = 1 << 30, - kCPUFeatureHYPERVISOR = 1 << 31, - kCPUFeatureFPU = 1 << 0, - kCPUFeatureVME = 1 << 1, - kCPUFeatureDE = 1 << 2, - kCPUFeaturePSE = 1 << 3, - kCPUFeatureEDXTSC = 1 << 4, - kCPUFeatureMSR = 1 << 5, - kCPUFeaturePAE = 1 << 6, - kCPUFeatureMCE = 1 << 7, - kCPUFeatureCX8 = 1 << 8, - kCPUFeatureAPIC = 1 << 9, - kCPUFeatureSEP = 1 << 11, - kCPUFeatureMTRR = 1 << 12, - kCPUFeaturePGE = 1 << 13, - kCPUFeatureMCA = 1 << 14, - kCPUFeatureCMOV = 1 << 15, - kCPUFeaturePAT = 1 << 16, - kCPUFeaturePSE36 = 1 << 17, - kCPUFeaturePSN = 1 << 18, - kCPUFeatureCLFLUSH = 1 << 19, - kCPUFeatureDS = 1 << 21, - kCPUFeatureACPI = 1 << 22, - kCPUFeatureMMX = 1 << 23, - kCPUFeatureFXSR = 1 << 24, - kCPUFeatureSSE = 1 << 25, - kCPUFeatureSSE2 = 1 << 26, - kCPUFeatureSS = 1 << 27, - kCPUFeatureHTT = 1 << 28, - kCPUFeatureTM = 1 << 29, - kCPUFeatureIA64 = 1 << 30, - kCPUFeaturePBE = 1 << 31 -}; - -namespace Kernel -{ - typedef Int64 CPUID; -} // namespace Kernel diff --git a/dev/ZKAKit/HALKit/AMD64/HalACPIFactoryInterface.cc b/dev/ZKAKit/HALKit/AMD64/HalACPIFactoryInterface.cc deleted file mode 100644 index 1a1d50a3..00000000 --- a/dev/ZKAKit/HALKit/AMD64/HalACPIFactoryInterface.cc +++ /dev/null @@ -1,126 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include -#include -#include -#include - -namespace Kernel -{ - namespace Detail - { - struct FADT final : public SDT - { - UInt32 FirmwareCtrl; - UInt32 Dsdt; - - // field used in ACPI 1.0; no longer in use, for compatibility only - UInt8 Reserved; - - UInt8 PreferredPowerManagementProfile; - UInt16 SCI_Interrupt; - UInt32 SMI_CommandPort; - UInt8 AcpiEnable; - UInt8 AcpiDisable; - UInt8 S4BIOS_REQ; - UInt8 PSTATE_Control; - UInt32 PM1aEventBlock; - UInt32 PM1bEventBlock; - UInt32 PM1aControlBlock; - UInt32 PM1bControlBlock; - UInt32 PM2ControlBlock; - UInt32 PMTimerBlock; - UInt32 GPE0Block; - UInt32 GPE1Block; - UInt8 PM1EventLength; - UInt8 PM1ControlLength; - UInt8 PM2ControlLength; - UInt8 PMTimerLength; - UInt8 GPE0Length; - UInt8 GPE1Length; - UInt8 GPE1Base; - UInt8 CStateControl; - UInt16 WorstC2Latency; - UInt16 WorstC3Latency; - UInt16 FlushSize; - UInt16 FlushStride; - UInt8 DutyOffset; - UInt8 DutyWidth; - UInt8 DayAlarm; - UInt8 MonthAlarm; - UInt8 Century; - - // reserved in ACPI 1.0; used since ACPI 2.0+ - UInt16 BootArchitecturkMMFlags; - - UInt8 Reserved2; - UInt32 Flags; - - // 12 byte structure; see below for details - ACPI_ADDRESS ResetReg; - - UInt8 ResetValue; - UInt8 Reserved3[3]; - - // 64bit pointers - Available on ACPI 2.0+ - UInt64 X_FirmwareControl; - UInt64 X_Dsdt; - - ACPI_ADDRESS X_PM1aEventBlock; - ACPI_ADDRESS X_PM1bEventBlock; - ACPI_ADDRESS X_PM1aControlBlock; - ACPI_ADDRESS X_PM1bControlBlock; - ACPI_ADDRESS X_PM2ControlBlock; - ACPI_ADDRESS X_PMTimerBlock; - ACPI_ADDRESS X_GPE0Block; - ACPI_ADDRESS X_GPE1Block; - }; - } // namespace Detail - - ACPIFactoryInterface::ACPIFactoryInterface(VoidPtr rsp_ptr) - : fRsdp(rsp_ptr), fEntries(0) - { - } - - Void ACPIFactoryInterface::Shutdown() - { - failed_to_shutdown: - // in case no acpi mode, or it's not available. - while (Yes) - { - asm volatile("cli; hlt"); - } - } - - /// @brief Reboot machine in either ACPI or by triple faulting. - /// @return nothing it's a reboot. - Void ACPIFactoryInterface::Reboot() - { - failed_to_reboot: - asm volatile(".intel_syntax noprefix; " - "rt_reset_hardware:; " - "cli; " - "wait_gate1: ; " - "in al,0x64 ; " - "and al,2 ; " - "jnz wait_gate1 ; " - "mov al,0x0D1 ; " - "out 0x64,al ; " - "wait_gate2: ; " - "in al,0x64 ; " - "and al,2 ; " - "jnz wait_gate2 ; " - "mov al,0x0FE ; " - "out 0x60,al ; " - "xor rax,rax ; " - "lidt [rax] ; " - "reset_wait: ; " - "jmp reset_wait ; " - ".att_syntax; "); - } -} // namespace Kernel diff --git a/dev/ZKAKit/HALKit/AMD64/HalAP.cc b/dev/ZKAKit/HALKit/AMD64/HalAP.cc deleted file mode 100644 index 7240d210..00000000 --- a/dev/ZKAKit/HALKit/AMD64/HalAP.cc +++ /dev/null @@ -1,51 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include - -namespace Kernel -{ - /***********************************************************************************/ - /// @brief Unimplemented function (crashes by default) - /// @param - /***********************************************************************************/ - - EXTERN_C Void __zka_pure_call(void) - { - UserProcessScheduler::The().GetCurrentProcess().Leak().Crash(); - } - - /***********************************************************************************/ - /// @brief Validate user stack. - /// @param stack_ptr the frame pointer. - /***********************************************************************************/ - - Bool hal_check_stack(HAL::StackFramePtr stack_ptr) - { - if (!stack_ptr) - return No; - - return stack_ptr->SP != 0 && stack_ptr->BP != 0; - } - - /// @brief Wakes up thread. - /// Wakes up thread from the hang state. - Void mp_wakeup_thread(HAL::StackFrame* stack) - { - Kernel::UserProcessHelper::StartScheduling(); - } - - /// @brief makes the thread sleep on a loop. - /// hooks and hangs thread to prevent code from executing. - Void mp_hang_thread(HAL::StackFrame* stack) - { - while (Yes) - { - /* Nothing to do, code is spinning */ - } - } -} // namespace Kernel diff --git a/dev/ZKAKit/HALKit/AMD64/HalAPICController.cc b/dev/ZKAKit/HALKit/AMD64/HalAPICController.cc deleted file mode 100644 index cebbc41b..00000000 --- a/dev/ZKAKit/HALKit/AMD64/HalAPICController.cc +++ /dev/null @@ -1,39 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include - -#define cIOAPICRegVal (4) -#define cIOAPICRegReg (0) - -namespace Kernel::HAL -{ - /// @brief Read from APIC controller. - /// @param reg register. - UInt32 APICController::Read(UInt32 reg) noexcept - { - MUST_PASS(this->fApic); - - UInt32 volatile* io_apic = (UInt32 volatile*)this->fApic; - io_apic[cIOAPICRegReg] = (reg & 0xFF); - - return io_apic[cIOAPICRegVal]; - } - - /// @brief Write to APIC controller. - /// @param reg register. - /// @param value value. - Void APICController::Write(UInt32 reg, UInt32 value) noexcept - { - MUST_PASS(this->fApic); - - UInt32 volatile* io_apic = (UInt32 volatile*)this->fApic; - - io_apic[cIOAPICRegReg] = (reg & 0xFF); - io_apic[cIOAPICRegVal] = value; - } -} // namespace Kernel::HAL diff --git a/dev/ZKAKit/HALKit/AMD64/HalBoot.asm b/dev/ZKAKit/HALKit/AMD64/HalBoot.asm deleted file mode 100644 index e9207936..00000000 --- a/dev/ZKAKit/HALKit/AMD64/HalBoot.asm +++ /dev/null @@ -1,28 +0,0 @@ -;; /* -;; * ======================================================== -;; * -;; * ZKA -;; * Copyright (C) 2024, Theater Quality Inc, all rights reserved., all rights reserved. -;; * -;; * ======================================================== -;; */ - -[bits 64] - -;; Global symbol of this unit -[extern hal_init_platform] - -%define kTypeKernel 100 -%define kArchAmd64 122 -%define kHandoverMagic 0xBADCC - -section .ldr - -HandoverMagic: - dq kHandoverMagic -HandoverType: - dw kTypeKernel -HandoverPad: - dw 0 -HandoverArch: - dw kArchAmd64 diff --git a/dev/ZKAKit/HALKit/AMD64/HalCPUAMD64.cc b/dev/ZKAKit/HALKit/AMD64/HalCPUAMD64.cc deleted file mode 100644 index 127d5843..00000000 --- a/dev/ZKAKit/HALKit/AMD64/HalCPUAMD64.cc +++ /dev/null @@ -1,101 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - - File: HalCPU.cc - Purpose: Platform processor routines. - -------------------------------------------- */ - -#include -#include - -/** - * @file HalCPU.cc - * @brief Common CPU API. - */ - -namespace Kernel::HAL -{ - Void lrt_out8(UInt16 port, UInt8 value) - { - asm volatile("outb %%al, %1" - : - : "a"(value), "Nd"(port) - : "memory"); - } - - Void lrt_out16(UInt16 port, UInt16 value) - { - asm volatile("outw %%ax, %1" - : - : "a"(value), "Nd"(port) - : "memory"); - } - - Void lrt_out32(UInt16 port, UInt32 value) - { - asm volatile("outl %%eax, %1" - : - : "a"(value), "Nd"(port) - : "memory"); - } - - UInt8 lrt_in8(UInt16 port) - { - UInt8 value = 0UL; - asm volatile("inb %1, %%al" - : "=a"(value) - : "Nd"(port) - : "memory"); - - return value; - } - - UInt16 lrt_in16(UInt16 port) - { - UInt16 value = 0UL; - asm volatile("inw %1, %%ax" - : "=a"(value) - : "Nd"(port) - : "memory"); - - return value; - } - - UInt32 lrt_in32(UInt16 port) - { - UInt32 value = 0UL; - asm volatile("inl %1, %%eax" - : "=a"(value) - : "Nd"(port) - : "memory"); - - return value; - } - - Void rt_halt() - { - asm volatile("hlt"); - } - - Void rt_cli() - { - asm volatile("cli"); - } - - Void rt_sti() - { - asm volatile("sti"); - } - - Void rt_cld() - { - asm volatile("cld"); - } - - Void rt_std() - { - asm volatile("std"); - } -} // namespace Kernel::HAL diff --git a/dev/ZKAKit/HALKit/AMD64/HalCommonAPI.asm b/dev/ZKAKit/HALKit/AMD64/HalCommonAPI.asm deleted file mode 100644 index 6d0dd8b9..00000000 --- a/dev/ZKAKit/HALKit/AMD64/HalCommonAPI.asm +++ /dev/null @@ -1,53 +0,0 @@ -;; /* -;; * ======================================================== -;; * -;; * ZKA -;; * Copyright (C) 2024, Theater Quality Inc, all rights reserved., all rights reserved. -;; * -;; * ======================================================== -;; */ - -section .text - -extern rt_wait_400ns - -global rt_out8 -global rt_out16 -global rt_out32 - -global rt_in8 -global rt_in16 -global rt_in32 - -rt_out8: - mov al, dl - mov dx, cx - out dx, al - ret - -rt_out16: - mov ax, dx - mov dx, cx - out dx, ax - ret - -rt_out32: - mov eax, edx - mov edx, ecx - out dx, eax - ret - -rt_in8: - mov dx, cx - in al, dx - ret - -rt_in16: - mov edx, ecx - in ax, dx - ret - -rt_in32: - mov rdx, rcx - in eax, dx - ret diff --git a/dev/ZKAKit/HALKit/AMD64/HalControlRegister.s b/dev/ZKAKit/HALKit/AMD64/HalControlRegister.s deleted file mode 100644 index 1901886d..00000000 --- a/dev/ZKAKit/HALKit/AMD64/HalControlRegister.s +++ /dev/null @@ -1,45 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -.globl hal_write_cr3 -.globl hal_write_cr0 -.globl hal_read_cr2 -.globl hal_read_cr3 -.globl hal_read_cr0 -.globl hal_flush_tlb -.globl hal_invl_tlb - -.text - -hal_invl_tlb: - invlpg (%rcx) - retq - -hal_flush_tlb: - call hal_read_cr3 - mov %rax, %rcx - call hal_write_cr3 - retq - -hal_read_cr3: - movq %cr3, %rax - retq - -hal_read_cr0: - movq %cr0, %rax - retq - -hal_read_cr2: - movq %cr2, %rax - retq - -hal_write_cr3: - movq %rcx, %cr3 - retq - -hal_write_cr0: - movq %rcx, %cr0 - retq diff --git a/dev/ZKAKit/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc b/dev/ZKAKit/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc deleted file mode 100644 index 036593e5..00000000 --- a/dev/ZKAKit/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc +++ /dev/null @@ -1,232 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include -#include -#include - -/// @brief Handle GPF fault. -/// @param rsp -EXTERN_C void idt_handle_gpf(Kernel::UIntPtr rsp) -{ - kcout << "Kernel: GPF.\r"; - - auto process = Kernel::UserProcessScheduler::The().GetCurrentProcess(); - - if (!process) - Kernel::ke_stop(RUNTIME_CHECK_PAGE); - - process.Leak().ProcessSignal.SignalIP = 0UL; - process.Leak().ProcessSignal.SignalID = SIGKILL; - process.Leak().ProcessSignal.PreviousStatus = process.Leak().Status; - - kcout << "Kernel: PRCFROZE status set..\r"; - - process.Leak().Status = Kernel::ProcessStatusKind::kFrozen; - - process.Leak().Crash(); - - Kernel::ke_stop(RUNTIME_CHECK_POINTER); -} - -/// @brief Handle page fault. -/// @param rsp -EXTERN_C void idt_handle_pf(Kernel::UIntPtr rsp) -{ - kcout << "Kernel: Page Fault.\r"; - kcout << "Kernel: SIGKILL set.\r"; - - auto process = Kernel::UserProcessScheduler::The().GetCurrentProcess(); - - if (!process) - Kernel::ke_stop(RUNTIME_CHECK_PAGE); - - process.Leak().ProcessSignal.SignalIP = 0UL; - process.Leak().ProcessSignal.SignalID = SIGKILL; - process.Leak().ProcessSignal.PreviousStatus = process.Leak().Status; - - kcout << "Kernel: PRCFROZE status set..\r"; - - process.Leak().Status = Kernel::ProcessStatusKind::kFrozen; - - process.Leak().Crash(); - - Kernel::ke_stop(RUNTIME_CHECK_PAGE); -} - -/// @brief Handle scheduler interrupt. -EXTERN_C void idt_handle_scheduler(Kernel::UIntPtr rsp) -{ - static BOOL is_scheduling = NO; - static Kernel::Int64 try_count_before_brute = 100000UL; - - while (is_scheduling) - { - --try_count_before_brute; - - if (try_count_before_brute < 1) - break; - } - - try_count_before_brute = 100000UL; - is_scheduling = YES; - - kcout << "Kernel: Timer IRQ (Scheduler Notification).\r"; - Kernel::UserProcessHelper::StartScheduling(); - - is_scheduling = NO; -} - -/// @brief Handle math fault. -/// @param rsp -EXTERN_C void idt_handle_math(Kernel::UIntPtr rsp) -{ - kcout << "Kernel: Math error (division by zero?).\r"; - - auto process = Kernel::UserProcessScheduler::The().GetCurrentProcess(); - - if (!process) - Kernel::ke_stop(RUNTIME_CHECK_PAGE); - - process.Leak().ProcessSignal.SignalIP = 0UL; - process.Leak().ProcessSignal.SignalID = SIGKILL; - process.Leak().ProcessSignal.PreviousStatus = process.Leak().Status; - - kcout << "Kernel: PRCFROZE status set..\r"; - - process.Leak().Status = Kernel::ProcessStatusKind::kFrozen; - - process.Leak().Crash(); - - Kernel::ke_stop(RUNTIME_CHECK_UNEXCPECTED); -} - -/// @brief Handle any generic fault. -/// @param rsp -EXTERN_C void idt_handle_generic(Kernel::UIntPtr rsp) -{ - kcout << "Kernel: Generic Process Fault.\r"; - - auto process = Kernel::UserProcessScheduler::The().GetCurrentProcess(); - - if (!process) - Kernel::ke_stop(RUNTIME_CHECK_PAGE); - - process.Leak().ProcessSignal.SignalIP = 0UL; - process.Leak().ProcessSignal.SignalID = SIGKILL; - process.Leak().ProcessSignal.PreviousStatus = process.Leak().Status; - - kcout << "Kernel: PRCFROZE status set..\r"; - - process.Leak().Status = Kernel::ProcessStatusKind::kFrozen; - - process.Leak().Crash(); - - Kernel::ke_stop(RUNTIME_CHECK_UNEXCPECTED); -} - -EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip) -{ - auto process = Kernel::UserProcessScheduler::The().GetCurrentProcess(); - - if (!process) - Kernel::ke_stop(RUNTIME_CHECK_PAGE); - - kcout << "Kernel: Process RIP: " << Kernel::hex_number(rip) << endl; - kcout << "Kernel: SIGTRAP set.\r"; - - process.Leak().ProcessSignal.SignalIP = rip; - process.Leak().ProcessSignal.SignalID = SIGTRAP; - - process.Leak().ProcessSignal.PreviousStatus = process.Leak().Status; - - kcout << "Kernel: PRCFROZE status set..\r"; - - process.Leak().Status = Kernel::ProcessStatusKind::kFrozen; -} - -/// @brief Handle #UD fault. -/// @param rsp -EXTERN_C void idt_handle_ud(Kernel::UIntPtr rsp) -{ - kcout << "Kernel: Undefined Opcode.\r"; - - auto process = Kernel::UserProcessScheduler::The().GetCurrentProcess(); - - if (!process) - Kernel::ke_stop(RUNTIME_CHECK_PAGE); - - process.Leak().ProcessSignal.SignalIP = 0UL; - process.Leak().ProcessSignal.SignalID = SIGKILL; - process.Leak().ProcessSignal.PreviousStatus = process.Leak().Status; - - kcout << "Kernel: PRCFROZE status set..\r"; - - process.Leak().Status = Kernel::ProcessStatusKind::kFrozen; - - process.Leak().Crash(); - - Kernel::ke_stop(RUNTIME_CHECK_UNEXCPECTED); -} - -/// @brief Enter syscall from assembly. -/// @param stack the stack pushed from assembly routine. -/// @return nothing. -EXTERN_C Kernel::Void hal_system_call_enter(Kernel::UIntPtr rcx_syscall_index, Kernel::UIntPtr rdx_syscall_struct) -{ - if (rcx_syscall_index < kSyscalls.Count()) - { - kcout << "syscall: Enter Syscall.\r"; - - if (kSyscalls[rcx_syscall_index].fHooked) - { - if (kSyscalls[rcx_syscall_index].fProc) - { - (kSyscalls[rcx_syscall_index].fProc)((Kernel::VoidPtr)rdx_syscall_struct); - } - else - { - kcout << "syscall: syscall isn't valid at all! (is nullptr)\r"; - } - } - else - { - kcout << "syscall: syscall isn't hooked at all! (is set to false)\r"; - } - - kcout << "syscall: Exit Syscall.\r"; - } -} - -/// @brief Enter Kernel call from assembly (DDK only). -/// @param stack the stack pushed from assembly routine. -/// @return nothing. -EXTERN_C Kernel::Void hal_kernel_call_enter(Kernel::UIntPtr rcx_kerncall_index, Kernel::UIntPtr rdx_kerncall_struct) -{ - if (rcx_kerncall_index < kKerncalls.Count()) - { - kcout << "kerncall: Enter Kernel Call List.\r"; - - if (kKerncalls[rcx_kerncall_index].fHooked) - { - if (kKerncalls[rcx_kerncall_index].fProc) - { - (kKerncalls[rcx_kerncall_index].fProc)((Kernel::VoidPtr)rdx_kerncall_struct); - } - else - { - kcout << "kerncall: Kernel call isn't valid at all! (is nullptr)\r"; - } - } - else - { - kcout << "kerncall: Kernel call isn't hooked at all! (is set to false)\r"; - } - - kcout << "kerncall: Exit Kernel Call List.\r"; - } -} diff --git a/dev/ZKAKit/HALKit/AMD64/HalCoreScheduler.cc b/dev/ZKAKit/HALKit/AMD64/HalCoreScheduler.cc deleted file mode 100644 index 02150f6e..00000000 --- a/dev/ZKAKit/HALKit/AMD64/HalCoreScheduler.cc +++ /dev/null @@ -1,240 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// Needed for SMP. -#include - -#define kApicSignature "APIC" - -#define kAPIC_ICR_Low 0x300 -#define kAPIC_ICR_High 0x310 -#define kAPIC_SIPI_Vector 0x00500 -#define kAPIC_EIPI_Vector 0x00400 - -#define kAPIC_BASE_MSR 0x1B -#define kAPIC_BASE_MSR_BSP 0x100 -#define kAPIC_BASE_MSR_ENABLE 0x800 - -#define cSMPMax (32U) - -/// @note: _hal_switch_context is internal - -/////////////////////////////////////////////////////////////////////////////////////// - -//! NOTE: fGSI stands 'Field Global System Interrupt' - -/////////////////////////////////////////////////////////////////////////////////////// - -namespace Kernel::HAL -{ - struct MADT_TABLE; - - EXTERN_C Void _hal_spin_core(Void); - - STATIC struct MADT_TABLE* kMADTBlock = nullptr; - STATIC Bool kSMPAware = false; - STATIC Int64 kSMPCount = 0; - - STATIC Int32 cSMPInterrupt = 0; - STATIC UInt64 kAPICLocales[cSMPMax] = {0}; - STATIC VoidPtr kRawMADT = nullptr; - - /// @brief Multiple APIC Descriptor Table. - struct MADT_TABLE final : public SDT - { - UInt32 Address; // Madt address - UInt8 Flags; // Madt flags - - struct - { - UInt8 Type; - UInt8 Len; - - union { - struct - { - UInt8 IoID; - UInt8 Resv; - UInt32 IoAddress; - UInt32 GISBase; - } IOAPIC; - - struct - { - UInt8 Source; - UInt8 IRQSource; - UInt32 GSI; - UInt16 Flags; - } IOAPIC_NMI; - - struct - { - UInt8 ProcessorID; - UInt16 Flags; - UInt8 LINT; - } LAPIC; - - struct - { - UInt16 Reserved; - UInt64 Address; - } LAPIC_ADDRESS_OVERRIDE; - - struct - { - UInt16 Reserved; - UInt32 x2APICID; - UInt32 Flags; - UInt32 AcpiID; - } LAPIC_ADDRESS; - }; - } List[]; // Records List - }; - - /////////////////////////////////////////////////////////////////////////////////////// - - /***********************************************************************************/ - /// @brief Send IPI command to APIC. - /// @param apicId programmable interrupt controller id. - /// @param vector vector interrupt. - /// @param targetAddress target APIC adress. - /// @return - /***********************************************************************************/ - - Void hal_send_start_ipi(UInt32 apicId, UInt8 vector, UInt32 targetAddress) - { - Kernel::ke_dma_write(targetAddress, kAPIC_ICR_High, (apicId << 24)); - Kernel::ke_dma_write(targetAddress, kAPIC_ICR_Low, kAPIC_SIPI_Vector | vector); - } - - /***********************************************************************************/ - /// @brief Send end IPI for CPU. - /// @param apicId - /// @param vector - /// @param targetAddress - /// @return - /***********************************************************************************/ - Void hal_send_end_ipi(UInt32 apicId, UInt8 vector, UInt32 targetAddress) - { - Kernel::ke_dma_write(targetAddress, kAPIC_ICR_High, (apicId << 24)); - Kernel::ke_dma_write(targetAddress, kAPIC_ICR_Low, kAPIC_EIPI_Vector | vector); - } - - STATIC struct PROCESS_CONTROL_BLOCK final - { - HAL::StackFramePtr f_Frame; - UInt8* f_Stack; - VoidPtr f_Image; - } kProcessBlocks[kSchedProcessLimitPerTeam] = {0}; - - EXTERN_C HAL::StackFramePtr mp_get_current_context(Int64 pid) - { - const auto process_index = pid % kSchedProcessLimitPerTeam; - return kProcessBlocks[process_index].f_Frame; - } - - EXTERN_C Bool mp_register_process(VoidPtr image, UInt8* stack_ptr, HAL::StackFramePtr stack_frame, ProcessID pid) - { - MUST_PASS(image && stack_ptr && stack_frame); - - const auto process_index = pid % kSchedProcessLimitPerTeam; - - kProcessBlocks[process_index].f_Frame = stack_frame; - kProcessBlocks[process_index].f_Stack = stack_ptr; - kProcessBlocks[process_index].f_Image = image; - - if (!mp_is_smp()) - { - /// TODO: Switch from process_index in hash list. - } - - return Yes; - } - - /***********************************************************************************/ - /// @brief Is the current config SMP aware? - /// @return True if YES, False if not. - /***********************************************************************************/ - Bool mp_is_smp(Void) noexcept - { - return kSMPAware; - } - - /***********************************************************************************/ - /// @brief Fetch and enable SMP scheduler. - /// @param vendor_ptr SMP containing structure. - /***********************************************************************************/ - Void mp_get_cores(VoidPtr vendor_ptr) noexcept - { - if (!vendor_ptr) - return; - - auto hw_and_pow_int = PowerFactoryInterface(vendor_ptr); - kRawMADT = hw_and_pow_int.Find(kApicSignature).Leak().Leak(); - - kMADTBlock = reinterpret_cast(kRawMADT); - kSMPAware = NO; - - if (kMADTBlock) - { - SizeT index = 0; - - // reset values. - - cSMPInterrupt = 0; - kSMPCount = 0; - - kcout << "SMP: Probing Local APICs...\r"; - - UIntPtr madt_address = kMADTBlock->Address; - - while (Yes) - { - if (kMADTBlock->List[index].Type > 9 || - kSMPCount > cSMPMax) - break; - - switch (kMADTBlock->List[index].Type) - { - case 0x00: { - kAPICLocales[index] = kMADTBlock->List[index].LAPIC.ProcessorID; - kcout << "SMP: APIC ID: " << number(kAPICLocales[index]) << endl; - ++kSMPCount; - break; - } - case 0x05: { - madt_address = kMADTBlock->List[index].LAPIC_ADDRESS_OVERRIDE.Address; - kcout << "SMP: APIC address: " << number(madt_address) << endl; - break; - } - } - - ++index; - } - - kcout << "SMP: number of cores: " << number(kSMPCount) << endl; - - // Kernel is now SMP aware. - // That means that the scheduler is now available (on MP Kernels) - - kSMPAware = true; - - /// TODO: Notify Boot AP that it must start. - } - } -} // namespace Kernel::HAL - -/////////////////////////////////////////////////////////////////////////////////////// diff --git a/dev/ZKAKit/HALKit/AMD64/HalDebugOutput.cc b/dev/ZKAKit/HALKit/AMD64/HalDebugOutput.cc deleted file mode 100644 index 6ae5859d..00000000 --- a/dev/ZKAKit/HALKit/AMD64/HalDebugOutput.cc +++ /dev/null @@ -1,146 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include -#include -#include - -namespace Kernel -{ - enum CommStatus - { - kStateInvalid, - kStateReady = 0xCF, - kStateTransmit = 0xFC, - kStateCnt = 3 - }; - - namespace Detail - { - constexpr short PORT = 0x3F8; - - static int kState = kStateInvalid; - - /// @brief Init COM1. - /// @return - bool hal_serial_init() noexcept - { -#ifdef __DEBUG__ - if (kState == kStateReady || kState == kStateTransmit) - return true; - - HAL::rt_out8(PORT + 1, 0x00); // Disable all interrupts - HAL::rt_out8(PORT + 3, 0x80); // Enable DLAB (set baud rate divisor) - HAL::rt_out8(PORT + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud - HAL::rt_out8(PORT + 1, 0x00); // (hi byte) - HAL::rt_out8(PORT + 3, 0x03); // 8 bits, no parity, one stop bit - HAL::rt_out8(PORT + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold - HAL::rt_out8(PORT + 4, 0x0B); // IRQs enabled, RTS/DSR set - HAL::rt_out8(PORT + 4, 0x1E); // Set in loopback mode, test the serial chip - HAL::rt_out8(PORT + 0, 0xAE); // Test serial chip (send byte 0xAE and check if - // serial returns same byte) - - // Check if serial is faulty (i.e: not same byte as sent) - if (HAL::rt_in8(PORT) != 0xAE) - { - ke_stop(RUNTIME_CHECK_HANDSHAKE); - } - - kState = kStateReady; - - // If serial is not faulty set it in normal operation mode - // (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled) - HAL::rt_out8(Detail::PORT + 4, 0x0F); -#endif // __DEBUG__ - - return true; - } - } // namespace Detail - - TerminalDevice::~TerminalDevice() = default; - - EXTERN_C void ke_io_write(const Char* bytes) - { -#ifdef __DEBUG__ - Detail::hal_serial_init(); - - if (!bytes || Detail::kState != kStateReady) - return; - if (*bytes == 0) - return; - - Detail::kState = kStateTransmit; - - SizeT index = 0; - SizeT len = 0; - - index = 0; - len = rt_string_len(bytes, 255); - - while (index < len) - { - if (bytes[index] == '\r') - HAL::rt_out8(Detail::PORT, '\r'); - - HAL::rt_out8(Detail::PORT, bytes[index] == '\r' ? '\n' : bytes[index]); - ++index; - } - - Detail::kState = kStateReady; -#endif // __DEBUG__ - } - - EXTERN_C void ke_io_read(const Char* bytes) - { -#ifdef __DEBUG__ - Detail::hal_serial_init(); - - if (!bytes || Detail::kState != kStateReady) - return; - - Detail::kState = kStateTransmit; - - SizeT index = 0; - - ///! TODO: Look on how to wait for the UART to complete. - while (true) - { - auto in = HAL::rt_in8(Detail::PORT); - - ///! If enter pressed then break. - if (in == 0xD) - { - break; - } - - if (in < '0' || in < 'A' || in < 'a') - { - if (in != '@' || in != '!' || in != '?' || in != '.' || in != '/' || - in != ':') - { - continue; - } - } - - ((char*)bytes)[index] = in; - - ++index; - } - - ((char*)bytes)[index] = 0; - - Detail::kState = kStateReady; -#endif // __DEBUG__ - } - - TerminalDevice TerminalDevice::The() noexcept - { - TerminalDevice out(Kernel::ke_io_write, Kernel::ke_io_read); - return out; - } - -} // namespace Kernel diff --git a/dev/ZKAKit/HALKit/AMD64/HalDebugPort.cc b/dev/ZKAKit/HALKit/AMD64/HalDebugPort.cc deleted file mode 100644 index 583a6b52..00000000 --- a/dev/ZKAKit/HALKit/AMD64/HalDebugPort.cc +++ /dev/null @@ -1,40 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -//! @file DebuggerPort.cc -//! @brief UART debug via packets. - -#include -#include - -// after that we have start of additional data. - -namespace Kernel -{ - void rt_debug_listen(DebuggerPortHeader* theHook) noexcept - { - if (theHook == nullptr) - return; - - for (UInt32 i = 0U; i < kDebugMaxPorts; ++i) - { - HAL::rt_out16(theHook->fPort[i], kDebugMag0); - HAL::rt_wait_400ns(); - - HAL::rt_out16(theHook->fPort[i], kDebugMag1); - HAL::rt_wait_400ns(); - - HAL::rt_out16(theHook->fPort[i], kDebugMag2); - HAL::rt_wait_400ns(); - - HAL::rt_out16(theHook->fPort[i], kDebugMag3); - HAL::rt_wait_400ns(); - - if (HAL::rt_in16(theHook->fPort[i] != kDebugUnboundPort)) - ++theHook->fBoundCnt; - } - } -} // namespace Kernel diff --git a/dev/ZKAKit/HALKit/AMD64/HalDescriptorLoader.cc b/dev/ZKAKit/HALKit/AMD64/HalDescriptorLoader.cc deleted file mode 100644 index 372481f3..00000000 --- a/dev/ZKAKit/HALKit/AMD64/HalDescriptorLoader.cc +++ /dev/null @@ -1,126 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include - -#define kPITDefaultTicks (100U) - -namespace Kernel::HAL -{ - namespace Detail - { - STATIC ::Kernel::Detail::AMD64::InterruptDescriptorAMD64 - kInterruptVectorTable[kKernelIdtSize] = {}; - - STATIC void hal_set_irq_mask(UInt8 irql); - STATIC void hal_clear_irq_mask(UInt8 irql); - - STATIC Void hal_enable_pit(UInt16 ticks) noexcept - { - if (ticks == 0) - ticks = kPITDefaultTicks; - - // Configure PIT to receieve scheduler interrupts. - - UInt16 cCommonDivisor = kPITFrequency / ticks; // 100 Hz. - - HAL::rt_out8(kPITControlPort, 0x36); // Command to PIT - HAL::rt_out8(kPITChannel0Port, cCommonDivisor & 0xFF); // Send low byte - HAL::rt_out8(kPITChannel0Port, (cCommonDivisor >> 8) & 0xFF); // Send high byte - - hal_clear_irq_mask(32); - } - - STATIC void hal_set_irq_mask(UInt8 irql) - { - UInt16 port; - UInt8 value; - - if (irql < 8) - { - port = kPICData; - } - else - { - port = kPIC2Data; - irql -= 8; - } - - value = rt_in8(port) | (1 << irql); - rt_out8(port, value); - } - - STATIC void hal_clear_irq_mask(UInt8 irql) - { - UInt16 port; - UInt8 value; - - if (irql < 8) - { - port = kPICData; - } - else - { - port = kPIC2Data; - irql -= 8; - } - - value = rt_in8(port) & ~(1 << irql); - rt_out8(port, value); - } - } // namespace Detail - - /// @brief Loads the provided Global Descriptor Table. - /// @param gdt - /// @return - Void GDTLoader::Load(RegisterGDT& gdt) - { - hal_load_gdt(gdt); - } - - Void IDTLoader::Load(Register64& idt) - { - rt_cli(); - - const Int16 kPITTickForScheduler = kPITDefaultTicks; - - volatile ::Kernel::UIntPtr** ptr_ivt = (volatile ::Kernel::UIntPtr**)idt.Base; - - for (SizeT idt_indx = 0; idt_indx < kKernelIdtSize; ++idt_indx) - { - Detail::kInterruptVectorTable[idt_indx].Selector = kIDTSelector; - Detail::kInterruptVectorTable[idt_indx].Ist = 0; - Detail::kInterruptVectorTable[idt_indx].TypeAttributes = kInterruptGate; - Detail::kInterruptVectorTable[idt_indx].OffsetLow = ((UIntPtr)ptr_ivt[idt_indx] & 0xFFFF); - Detail::kInterruptVectorTable[idt_indx].OffsetMid = (((UIntPtr)ptr_ivt[idt_indx] >> 16) & 0xFFFF); - Detail::kInterruptVectorTable[idt_indx].OffsetHigh = - (((UIntPtr)ptr_ivt[idt_indx] >> 32) & 0xFFFFFFFF); - - Detail::kInterruptVectorTable[idt_indx].Zero = 0; - } - - idt.Base = (UIntPtr)&Detail::kInterruptVectorTable[0]; - idt.Limit = sizeof(::Kernel::Detail::AMD64::InterruptDescriptorAMD64) * - (kKernelIdtSize); - - hal_load_idt(idt); - - Detail::hal_enable_pit(kPITTickForScheduler); - - rt_sti(); - } - - void GDTLoader::Load(Ref& gdt) - { - GDTLoader::Load(gdt.Leak()); - } - - void IDTLoader::Load(Ref& idt) - { - IDTLoader::Load(idt.Leak()); - } -} // namespace Kernel::HAL diff --git a/dev/ZKAKit/HALKit/AMD64/HalInterruptAPI.asm b/dev/ZKAKit/HALKit/AMD64/HalInterruptAPI.asm deleted file mode 100644 index cb440418..00000000 --- a/dev/ZKAKit/HALKit/AMD64/HalInterruptAPI.asm +++ /dev/null @@ -1,406 +0,0 @@ -;; /* -;; * --------------------------------------------------- -;; * -;; * Copyright (C) 2024, Theater Quality Inc, all rights reserved. -;; * -;; * File: HalInterruptAPI.asm -;; * Purpose: Interrupt API, redirect raw interrupts into their handlers. -;; * -;; * --------------------------------------------------- -;; */ - -[bits 64] - -%define kInterruptId 0x21 - -%macro IntExp 1 -global __ZKA_INT_%1 -__ZKA_INT_%1: - cli - - mov al, 0x20 - out 0x20, al - out 0xA0, al - - sti - o64 iret -%endmacro - -%macro IntNormal 1 -global __ZKA_INT_%1 -__ZKA_INT_%1: - cli - - mov al, 0x20 - out 0x20, al - out 0xA0, al - - sti - o64 iret -%endmacro - -; This file handles the core interrupt table -; Last edited 31/01/24 - -global ke_handle_irq -global kInterruptVectorTable - -extern idt_handle_gpf -extern idt_handle_pf -extern ke_io_write -extern idt_handle_ud -extern idt_handle_generic -extern idt_handle_breakpoint - -section .text - -IntNormal 0 -IntNormal 1 -IntNormal 2 - -section .data - -__ZKA_INT_3_GET_RIP: - dq 0 -__ZKA_INT_3_GET_RIP_END: - -section .text - -;; @brief Triggers a breakpoint and freeze the process. RIP is also fetched. -__ZKA_INT_3: - cli - - mov al, 0x20 - out 0x20, al - out 0xA0, al - - push rax - mov rax, idt_handle_breakpoint - - lea rcx, [rel __ZKA_INT_3_GET_RIP] - sub rcx, 16 - mov [rcx], rcx - - call rax - pop rax - - sti - o64 iret - -IntNormal 4 -IntNormal 5 - -;; Invalid opcode interrupt -__ZKA_INT_6: - cli - - mov al, 0x20 - out 0x20, al - out 0xA0, al - - push rax - mov rax, idt_handle_ud - - mov rcx, rsp - - call rax - pop rax - - sti - o64 iret - -IntNormal 7 - -;; Invalid opcode interrupt -__ZKA_INT_8: - cli - - mov al, 0x20 - out 0x20, al - out 0xA0, al - - push rax - mov rax, idt_handle_generic - - mov rcx, rsp - - call rax - pop rax - - sti - o64 iret - -IntNormal 9 -IntExp 10 -IntExp 11 - -IntExp 12 - -__ZKA_INT_13: - cli - - mov al, 0x20 - out 0x20, al - out 0xA0, al - - push rax - mov rax, idt_handle_gpf - - mov rcx, rsp - - call rax - pop rax - - sti - o64 iret - -__ZKA_INT_14: - cli - - mov al, 0x20 - out 0x20, al - out 0xA0, al - push rax - mov rax, idt_handle_pf - - mov rcx, rsp - - call rax - pop rax - - sti - o64 iret - -IntNormal 15 -IntNormal 16 -IntExp 17 -IntNormal 18 -IntNormal 19 -IntNormal 20 -IntNormal 21 - -IntNormal 22 - -IntNormal 23 -IntNormal 24 -IntNormal 25 -IntNormal 26 -IntNormal 27 -IntNormal 28 -IntNormal 29 -IntExp 30 -IntNormal 31 - -[extern idt_handle_scheduler] - -__ZKA_INT_32: - cli - - mov al, 0x20 - out 0x20, al - out 0xA0, al - - push rax - mov rcx, rsp - call idt_handle_scheduler - pop rax - - sti - o64 iret - -IntNormal 33 - -IntNormal 34 -IntNormal 35 -IntNormal 36 -IntNormal 37 -IntNormal 38 -IntNormal 39 -IntNormal 40 - -IntNormal 41 - -IntNormal 42 -IntNormal 43 -IntNormal 44 -IntNormal 45 -IntNormal 46 -IntNormal 47 -IntNormal 48 -IntNormal 49 - -[extern hal_system_call_enter] -[extern hal_kernel_call_enter] - -__ZKA_INT_50: - cli - - mov al, 0x20 - out 0x20, al - out 0xA0, al - - push rax - mov rax, hal_system_call_enter - - mov rcx, r8 - mov rdx, r9 - - call rax - pop rax - - sti - - o64 iret - -__ZKA_INT_51: - cli - - mov al, 0x20 - out 0x20, al - out 0xA0, al - - push rax - mov rax, hal_kernel_call_enter - - mov rcx, r8 - mov rdx, r9 - - call rax - pop rax - - sti - - o64 iret - -IntNormal 52 - -IntNormal 53 -IntNormal 54 -IntNormal 55 -IntNormal 56 -IntNormal 57 -IntNormal 58 -IntNormal 59 -IntNormal 60 - -%assign i 61 -%rep 195 - IntNormal i -%assign i i+1 -%endrep - -section .text - -[global hal_load_gdt] - -hal_load_gdt: - cld - - lgdt [rcx] - - mov ax, 0x10 - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - mov ss, ax - - mov rax, 0x08 - push rax - push hal_reload_segments - - o64 retf - -extern hal_real_init - -hal_reload_segments: - std - ;; Write address of syscall handler. - mov rdx, [mp_system_call_handler] - shr rdx, 32 - mov rcx, 0xC0000082 - wrmsr - - ;; Set segments of syscall handler. - - xor rax, rax - mov rdx, 0x230008 - mov rcx, 0xC0000081 - wrmsr - - mov ecx, 0xC0000080 - rdmsr - or eax, 1 - wrmsr - - jmp hal_real_init - ret - -global hal_load_idt -global hal_user_code_start - -extern hal_system_call_enter -global mp_system_call_handler - -mp_system_call_handler: - - push r8 - push r9 - push r10 - push r11 - push r12 - push r13 - push r14 - push r15 - - jmp hal_system_call_enter - - pop r15 - pop r14 - pop r13 - pop r12 - pop r11 - pop r10 - pop r9 - pop r8 - - o64 sysret - -hal_load_idt: - lidt [rcx] - - ; Master PIC initialization - mov al, 0x11 ; Start initialization in cascade mode - out 0x20, al ; Send initialization command to Master PIC - out 0xA0, al ; Send initialization command to Slave PIC - - ; Remap the PIC to use vectors 32-39 for Master and 40-47 for Slave - mov al, 0x20 ; Set Master PIC offset to 32 - out 0x21, al ; Send offset to Master PIC - - mov al, 0x28 ; Set Slave PIC offset to 40 - out 0xA1, al ; Send offset to Slave PIC - - ; Configure Master PIC to inform Slave PIC at IRQ2 - mov al, 0x04 ; Tell Master PIC there is a Slave PIC at IRQ2 - out 0x21, al - - ; Configure Slave PIC identity - mov al, 0x02 ; Tell Slave PIC its cascade identity - out 0xA1, al - - ; Set both PICs to 8086 mode - mov al, 0x01 ; 8086 mode - out 0x21, al - out 0xA1, al - - ret - -section .data - -kInterruptVectorTable: - %assign i 0 - %rep 256 - dq __ZKA_INT_%+i - %assign i i+1 - %endrep diff --git a/dev/ZKAKit/HALKit/AMD64/HalKernelMain.cc b/dev/ZKAKit/HALKit/AMD64/HalKernelMain.cc deleted file mode 100644 index d6fe8a14..00000000 --- a/dev/ZKAKit/HALKit/AMD64/HalKernelMain.cc +++ /dev/null @@ -1,103 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -EXTERN_C Kernel::VoidPtr kInterruptVectorTable[]; -EXTERN_C Kernel::VoidPtr mp_user_switch_proc; -EXTERN_C Kernel::Char mp_user_switch_proc_stack_begin[]; - -EXTERN_C Kernel::rtl_ctor_kind __CTOR_LIST__[]; -EXTERN_C Kernel::VoidPtr __DTOR_LIST__; - -EXTERN_C Kernel::Void rtl_kernel_main(Kernel::SizeT argc, char** argv, char** envp, Kernel::SizeT envp_len); - -STATIC Kernel::Void hal_init_cxx_ctors() -{ - for (Kernel::SizeT index = 0UL; __CTOR_LIST__[index] != __DTOR_LIST__; ++index) - { - Kernel::rtl_ctor_kind constructor_cxx = (Kernel::rtl_ctor_kind)__CTOR_LIST__[index]; - constructor_cxx(); - } -} - -/// @brief Kernel init procedure. -EXTERN_C void hal_init_platform( - Kernel::HEL::BootInfoHeader* handover_hdr) -{ - kHandoverHeader = handover_hdr; - - if (kHandoverHeader->f_Magic != kHandoverMagic && - kHandoverHeader->f_Version != kHandoverVersion) - { - return; - } - - hal_init_cxx_ctors(); - - /************************************** */ - /* INITIALIZE BIT MAP. */ - /************************************** */ - - kKernelBitMpSize = kHandoverHeader->f_BitMapSize; - kKernelBitMpStart = reinterpret_cast( - reinterpret_cast(kHandoverHeader->f_BitMapStart)); - - /************************************** */ - /* INITIALIZE GDT AND SEGMENTS. */ - /************************************** */ - - STATIC CONST auto kGDTEntriesCount = 6; - - /* GDT, mostly descriptors for user and kernel segments. */ - STATIC Kernel::HAL::Detail::ZKA_GDT_ENTRY ALIGN(0x08) kGDTArray[kGDTEntriesCount] = { - {.fLimitLow = 0, .fBaseLow = 0, .fBaseMid = 0, .fAccessByte = 0x00, .fFlags = 0x00, .fBaseHigh = 0}, // Null entry - {.fLimitLow = 0xFFFF, .fBaseLow = 0, .fBaseMid = 0, .fAccessByte = 0x9A, .fFlags = 0xAF, .fBaseHigh = 0}, // Kernel code - {.fLimitLow = 0xFFFF, .fBaseLow = 0, .fBaseMid = 0, .fAccessByte = 0x92, .fFlags = 0xCF, .fBaseHigh = 0}, // Kernel data - {.fLimitLow = 0xFFFF, .fBaseLow = 0, .fBaseMid = 0, .fAccessByte = 0xF2, .fFlags = 0xCF, .fBaseHigh = 0}, // User data - {.fLimitLow = 0xFFFF, .fBaseLow = 0, .fBaseMid = 0, .fAccessByte = 0xFA, .fFlags = 0xAF, .fBaseHigh = 0}, // User code - }; - - // Load memory descriptors. - Kernel::HAL::RegisterGDT gdt_reg; - - gdt_reg.Base = reinterpret_cast(kGDTArray); - gdt_reg.Limit = (sizeof(Kernel::HAL::Detail::ZKA_GDT_ENTRY) * kGDTEntriesCount) - 1; - - //! GDT will load hal_read_init after it successfully loads the segments. - Kernel::HAL::GDTLoader gdt_loader; - gdt_loader.Load(gdt_reg); - - Kernel::ke_stop(RUNTIME_CHECK_BOOTSTRAP); -} - -EXTERN_C Kernel::Void hal_real_init(Kernel::Void) noexcept -{ - CG::CGDrawBackground(); - - rtl_kernel_main(0, nullptr, nullptr, 0); - - if (kHandoverHeader->f_HardwareTables.f_MultiProcessingEnabled) - Kernel::HAL::mp_get_cores(kHandoverHeader->f_HardwareTables.f_VendorPtr); - - Kernel::HAL::Register64 idt_reg; - idt_reg.Base = (Kernel::UIntPtr)kInterruptVectorTable; - - Kernel::HAL::IDTLoader idt_loader; - idt_loader.Load(idt_reg); - - while (YES) - { - } -} diff --git a/dev/ZKAKit/HALKit/AMD64/HalPagingMgrAMD64.cc b/dev/ZKAKit/HALKit/AMD64/HalPagingMgrAMD64.cc deleted file mode 100644 index 6d5923c7..00000000 --- a/dev/ZKAKit/HALKit/AMD64/HalPagingMgrAMD64.cc +++ /dev/null @@ -1,168 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - - File: HalPagingMgr.cc - Purpose: Platform Paging Manager.. - -------------------------------------------- */ - -#include -#include - -namespace Kernel::HAL -{ - typedef UInt32 PageTableIndex; - - /***********************************************************************************/ - /// \brief Page store type. - /***********************************************************************************/ - struct ZKA_PAGE_STORE final - { - struct - { - PDE* fPde{nullptr}; - PTE* fPte{nullptr}; - VoidPtr fVAddr{nullptr}; - } fInternalStore; - - Bool fStoreOp{No}; // Store operation is in progress. - - bool IsValidPage(PTE* pte) - { - return pte && pte->Present; - } - - bool IsWRPage(PTE* pte) - { - return pte && pte->Wr; - } - - bool IsUserPage(PTE* pte) - { - return pte && pte->User; - } - - static ZKA_PAGE_STORE& The() - { - static ZKA_PAGE_STORE the; - return the; - } - }; - - /***********************************************************************************/ - /// \brief Retrieve the page status of a PTE. - /// \param pte Page Table Entry pointer. - /***********************************************************************************/ - STATIC Void mmi_page_status(PTE* pte) - { - kcout << (pte->Present ? "Present" : "Not Present") << endl; - kcout << (pte->Wr ? "W/R" : "Not W/R") << endl; - kcout << (pte->ExecDisable ? "NX" : "Not NX") << endl; - kcout << (pte->User ? "User" : "Not User") << endl; - } - - STATIC Int32 mmi_map_page_table_entry(VoidPtr virtual_address, UInt32 flags, ZKA_PTE* pt_entry, ZKA_PDE* pd_entry); - - /***********************************************************************************/ - /// @brief Maps or allocates a page from virtual_address. - /// @param virtual_address a valid virtual address. - /// @param phys_addr point to physical address. - /// @param flags the flags to put on the page. - /// @return Status code of page manipulation process. - /***********************************************************************************/ - EXTERN_C Int32 mm_map_page(VoidPtr virtual_address, UInt32 flags) - { - if (!virtual_address || - !flags) - return 0; - - // Constants for table index bits - const UInt64 cPmlIndexMask = 0x1FFULL; // Mask for PML4, PDPT, PD, PT index (9 bits) - const UInt64 cPtIndexMask = 0xFFFULL; // Mask for page table index (12 bits) - - UInt64 cr3 = (UInt64)hal_read_cr3(); - - ZKA_PAGE_STORE& page_store = ZKA_PAGE_STORE::The(); - - // Extract the indices from the virtual address - UInt64 pml4_index = ((UIntPtr)virtual_address >> 39) & cPmlIndexMask; - UInt64 pdpt_index = ((UIntPtr)virtual_address >> 30) & cPmlIndexMask; - UInt64 pd_index = ((UIntPtr)virtual_address >> 21) & cPmlIndexMask; - UInt64 pt_index = ((UIntPtr)virtual_address >> 12) & cPmlIndexMask; - - page_store.fStoreOp = Yes; - - if (page_store.fInternalStore.fVAddr == virtual_address) - { - page_store.fStoreOp = No; - return mmi_map_page_table_entry(page_store.fInternalStore.fVAddr, flags, page_store.fInternalStore.fPte, page_store.fInternalStore.fPde); - } - - const auto cPmlEntrySize = 8; - - // Read the PML4 entry from memory - UInt64 pml4_base = cr3 & ~cPtIndexMask; // CR3 points to the PML4 table base, mask off lower bits - UInt64 pml4_entry = (pml4_base + pml4_index * cPmlEntrySize); // Each entry is 8 bytes - - // Read the PDPT entry - UInt64 pdpt_base = pml4_entry & ~cPtIndexMask; // Get the PDPT base physical address - UInt64 pdpt_entry = (pdpt_base + pdpt_index * cPmlEntrySize); - - // Read the PD entry - UInt64 pd_base = pdpt_entry & ~cPtIndexMask; // Get the Page Directory base physical address - UInt64 pd_entry = (pd_base + pd_index * cPmlEntrySize); - - // Read the PT entry - UInt64 pt_base = pd_entry & ~cPtIndexMask; // Get the Page Table base physical address - UInt64 pt_entry = (pt_base + pt_index * cPmlEntrySize); - - // Lastly, grab the pte entry. - ZKA_PDE* pde_struct = reinterpret_cast(pt_base); - - return mmi_map_page_table_entry(virtual_address, flags, pde_struct->fEntries[pt_entry], pde_struct); - } - - /***********************************************************************************/ - /// @brief Maps flags for a specific pte. - /// @internal Internal function. - /***********************************************************************************/ - STATIC Int32 mmi_map_page_table_entry(VoidPtr virtual_address, UInt32 flags, ZKA_PTE* pt_entry, ZKA_PDE* pd_entry) - { - if (!pt_entry) - return 1; - - pt_entry->Present = true; - - if (flags & kMMFlagsWr) - pt_entry->Wr = true; - else if (flags & ~kMMFlagsWr) - pt_entry->Wr = false; - - if (flags & kMMFlagsNX) - pt_entry->ExecDisable = true; - else if (flags & ~kMMFlagsNX) - pt_entry->ExecDisable = false; - - if (flags & kMMFlagsUser) - pt_entry->User = true; - else if (flags & ~kMMFlagsUser) - pt_entry->User = false; - - hal_invl_tlb(reinterpret_cast(pt_entry)); - - mmi_page_status(pt_entry); - - ZKA_PAGE_STORE& page_store = ZKA_PAGE_STORE::The(); - - // Update Internal store. - - page_store.fInternalStore.fPde = pd_entry; - page_store.fInternalStore.fPte = pt_entry; - page_store.fInternalStore.fVAddr = virtual_address; - - page_store.fStoreOp = No; - - return 0; - } -} // namespace Kernel::HAL diff --git a/dev/ZKAKit/HALKit/AMD64/HalRoutineWait.s b/dev/ZKAKit/HALKit/AMD64/HalRoutineWait.s deleted file mode 100644 index 89051ba4..00000000 --- a/dev/ZKAKit/HALKit/AMD64/HalRoutineWait.s +++ /dev/null @@ -1,11 +0,0 @@ -.globl rt_wait_400ns - -.section .text -rt_wait_400ns: - jmp .loop - pause - .loop: - jmp .loop2 - pause - .loop2: - ret diff --git a/dev/ZKAKit/HALKit/AMD64/HalTimerAMD64.cc b/dev/ZKAKit/HALKit/AMD64/HalTimerAMD64.cc deleted file mode 100644 index 97da8c48..00000000 --- a/dev/ZKAKit/HALKit/AMD64/HalTimerAMD64.cc +++ /dev/null @@ -1,86 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - - File: HalTimer.cc - Purpose: HAL timer - - Revision History: - - 07/07/24: Added file (amlel) - -------------------------------------------- */ - -#include -#include -#include - -// timer slot 0 - -#define cHPETCounterRegValue (0x00) -#define cHPETConfigRegValue (0x20) -#define cHPETCompRegValue (0x24) -#define cHPETInterruptRegValue (0x2C) - -///! BUGS: 0 -///! @file HalTimer.cc -///! @brief Hardware Timer (HPET) - -namespace Kernel::Detail -{ - struct HPET_BLOCK : public Kernel::SDT - { - Kernel::UInt8 hardware_rev_id; - Kernel::UInt8 comparator_count : 5; - Kernel::UInt8 counter_size : 1; - Kernel::UInt8 reserved : 1; - Kernel::UInt8 legacy_replacement : 1; - Kernel::UInt16 pci_vendor_id; - ACPI_ADDRESS address; - Kernel::UInt8 hpet_number; - Kernel::UInt16 minimum_tick; - Kernel::UInt8 page_protection; - } PACKED; -} // namespace Kernel::Detail - -using namespace Kernel; - -HardwareTimer::HardwareTimer(Int64 ms) - : fWaitFor(ms) -{ - auto power = PowerFactoryInterface(kHandoverHeader->f_HardwareTables.f_VendorPtr); - - auto hpet = (Detail::HPET_BLOCK*)power.Find("HPET").Leak().Leak(); - MUST_PASS(hpet); - - fDigitalTimer = (IntPtr*)hpet->address.Address; -} - -HardwareTimer::~HardwareTimer() -{ - fDigitalTimer = nullptr; - fWaitFor = 0; -} - -Int32 HardwareTimer::Wait() noexcept -{ - if (fWaitFor < 1) - return 1; - - // if not enabled yet. - if (!(*(fDigitalTimer + cHPETConfigRegValue) & (1 << 0))) - { - *(fDigitalTimer + cHPETConfigRegValue) |= (1 << 0); // enable it - *(fDigitalTimer + cHPETConfigRegValue) |= (1 << 3); // one shot conf - } - - UInt64 ticks = fWaitFor / ((*(fDigitalTimer) >> 32) & __UINT32_MAX__); - UInt64 prev = *(fDigitalTimer + cHPETCounterRegValue); - - prev += ticks; - - while (*(fDigitalTimer + cHPETCounterRegValue) < (ticks)) - ; - - return 0; -} diff --git a/dev/ZKAKit/HALKit/AMD64/HalUtils.asm b/dev/ZKAKit/HALKit/AMD64/HalUtils.asm deleted file mode 100644 index daec5f82..00000000 --- a/dev/ZKAKit/HALKit/AMD64/HalUtils.asm +++ /dev/null @@ -1,27 +0,0 @@ -;; /* -;; * ======================================================== -;; * -;; * ZKA -;; * Copyright (C) 2024, Theater Quality Inc, all rights reserved., all rights reserved. -;; * -;; * ======================================================== -;; */ - -[bits 64] - -[global rt_install_tib] - -section .text - -;; changed: rs, fs -;; expected: rcx, rdx - -rt_install_tib: - mov rcx, gs ;; TIB -> Thread Information Block - mov rdx, fs ;; PIB -> Process Information Block - ret - -;; //////////////////////////////////////////////////// ;; - -[extern cBspDone] -[extern kApicMadtAddressesCount] diff --git a/dev/ZKAKit/HALKit/AMD64/Hypervisor.h b/dev/ZKAKit/HALKit/AMD64/Hypervisor.h deleted file mode 100644 index 158ff396..00000000 --- a/dev/ZKAKit/HALKit/AMD64/Hypervisor.h +++ /dev/null @@ -1,25 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include - -namespace Kernel -{ - MAKE_STRING_ENUM(HYPERVISOR) - ENUM_STRING(Qemu, "TCGTCGTCGTCG"); - ENUM_STRING(KVM, " KVMKVMKVM "); - ENUM_STRING(VMWare, "VMwareVMware"); - ENUM_STRING(VirtualBox, "VBoxVBoxVBox"); - ENUM_STRING(Xen, "XenVMMXenVMM"); - ENUM_STRING(Microsoft, "Microsoft Hv"); - ENUM_STRING(Parallels, " prl hyperv "); - ENUM_STRING(ParallelsAlt, " lrpepyh vr "); - ENUM_STRING(Bhyve, "bhyve bhyve "); - ENUM_STRING(Qnx, " QNXQVMBSQG "); - END_STRING_ENUM() -} // namespace Kernel diff --git a/dev/ZKAKit/HALKit/AMD64/MBCI/HalMBCI.cc b/dev/ZKAKit/HALKit/AMD64/MBCI/HalMBCI.cc deleted file mode 100644 index b7948bcb..00000000 --- a/dev/ZKAKit/HALKit/AMD64/MBCI/HalMBCI.cc +++ /dev/null @@ -1,7 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include diff --git a/dev/ZKAKit/HALKit/AMD64/PCI/DMA.cc b/dev/ZKAKit/HALKit/AMD64/PCI/DMA.cc deleted file mode 100644 index 69544d22..00000000 --- a/dev/ZKAKit/HALKit/AMD64/PCI/DMA.cc +++ /dev/null @@ -1,82 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include - -namespace Kernel -{ - DMAWrapper::operator bool() - { - return fAddress; - } - - bool DMAWrapper::operator!() - { - return !fAddress; - } - - Boolean DMAWrapper::Check(UIntPtr offset) const - { - if (!fAddress) - return false; - if (offset == 0) - return true; - - kcout << "[DMAWrapper::IsIn] Checking offset..\n"; - return reinterpret_cast(fAddress) >= offset; - } - - bool DMAWrapper::Write(const UIntPtr& bit, const UIntPtr& offset) - { - if (!fAddress) - return false; - - kcout << "[DMAWrapper::Write] Writing at address..\n"; - - auto addr = - (volatile UIntPtr*)(reinterpret_cast(fAddress) + offset); - *addr = bit; - - return true; - } - - UIntPtr DMAWrapper::Read(const UIntPtr& offset) - { - kcout << "[DMAWrapper::Read] checking fAddress..\n"; - if (!fAddress) - return 0; - - kcout << "[DMAWrapper::Read] Reading fAddress..\n"; - return *(volatile UIntPtr*)(reinterpret_cast(fAddress) + offset); - ; - } - - UIntPtr DMAWrapper::operator[](const UIntPtr& offset) - { - return this->Read(offset); - } - - OwnPtr> DMAFactory::Construct(OwnPtr& dma) - { - if (!dma) - return {}; - - OwnPtr> dmaOwnPtr = - make_ptr, char*>(reinterpret_cast(dma->fAddress)); - - if (!dmaOwnPtr) - return {}; - - kcout << "Returning the new OwnPtr>!\r"; - return dmaOwnPtr; - } - - DMAWrapper& DMAWrapper::operator=(voidPtr Ptr) - { - fAddress = Ptr; - return *this; - } -} // namespace Kernel diff --git a/dev/ZKAKit/HALKit/AMD64/PCI/Database.cc b/dev/ZKAKit/HALKit/AMD64/PCI/Database.cc deleted file mode 100644 index 4a27e9a7..00000000 --- a/dev/ZKAKit/HALKit/AMD64/PCI/Database.cc +++ /dev/null @@ -1,11 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include - -namespace Kernel -{ -} diff --git a/dev/ZKAKit/HALKit/AMD64/PCI/Device.cc b/dev/ZKAKit/HALKit/AMD64/PCI/Device.cc deleted file mode 100644 index 57907b0f..00000000 --- a/dev/ZKAKit/HALKit/AMD64/PCI/Device.cc +++ /dev/null @@ -1,139 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include - -Kernel::UInt ZKA_PCIReadRaw(Kernel::UInt bar, Kernel::UShort bus, Kernel::UShort dev, Kernel::UShort fun) -{ - Kernel::UInt target = 0x80000000 | ((Kernel::UInt)bus << 16) | - ((Kernel::UInt)dev << 11) | ((Kernel::UInt)fun << 8) | - (bar & 0xFC); - - Kernel::HAL::rt_out32((Kernel::UShort)Kernel::PCI::PciConfigKind::ConfigAddress, - target); - - return Kernel::HAL::rt_in32((Kernel::UShort)Kernel::PCI::PciConfigKind::ConfigData); -} - -void ZKA_PCISetCfgTarget(Kernel::UInt bar, Kernel::UShort bus, Kernel::UShort dev, Kernel::UShort fun) -{ - Kernel::UInt target = 0x80000000 | ((Kernel::UInt)bus << 16) | - ((Kernel::UInt)dev << 11) | ((Kernel::UInt)fun << 8) | - (bar & ~3); - - Kernel::HAL::rt_out32((Kernel::UShort)Kernel::PCI::PciConfigKind::ConfigAddress, - target); -} - -#define PCI_BAR_IO 0x01 -#define PCI_BAR_LOWMEM 0x02 -#define PCI_BAR_64 0x04 -#define PCI_BAR_PREFETCH 0x08 - -namespace Kernel::PCI -{ - Device::Device(UShort bus, UShort device, UShort func, UInt32 bar) - : fBus(bus), fDevice(device), fFunction(func), fBar(bar) - { - } - - Device::~Device() = default; - - UInt Device::Read(UInt bar, Size sz) - { - ZKA_PCISetCfgTarget(bar, fBus, fDevice, fFunction); - - if (sz == 4) - return HAL::rt_in32((UShort)PciConfigKind::ConfigData + (bar & 3)); - if (sz == 2) - return HAL::rt_in16((UShort)PciConfigKind::ConfigData + (bar & 3)); - if (sz == 1) - return HAL::rt_in8((UShort)PciConfigKind::ConfigData + (bar & 3)); - - return 0xFFFF; - } - - void Device::Write(UInt bar, UIntPtr data, Size sz) - { - ZKA_PCISetCfgTarget(bar, fBus, fDevice, fFunction); - - if (sz == 4) - HAL::rt_out32((UShort)PciConfigKind::ConfigData + (fBar & 3), (UInt)data); - if (sz == 2) - HAL::rt_out16((UShort)PciConfigKind::ConfigData + (fBar & 3), (UShort)data); - if (sz == 1) - HAL::rt_out8((UShort)PciConfigKind::ConfigData + (fBar & 3), (UChar)data); - } - - UShort Device::DeviceId() - { - return (UShort)(ZKA_PCIReadRaw(0x0 >> 16, fBus, fDevice, fFunction)); - } - - UShort Device::VendorId() - { - return (UShort)(ZKA_PCIReadRaw(0x0, fBus, fDevice, fFunction) >> 16); - } - - UShort Device::InterfaceId() - { - return (UShort)(ZKA_PCIReadRaw(0x0, fBus, fDevice, fFunction) >> 16); - } - - UChar Device::Class() - { - return (UChar)(ZKA_PCIReadRaw(0x08, fBus, fDevice, fFunction) >> 24); - } - - UChar Device::Subclass() - { - return (UChar)(ZKA_PCIReadRaw(0x08, fBus, fDevice, fFunction) >> 16); - } - - UChar Device::ProgIf() - { - return (UChar)(ZKA_PCIReadRaw(0x08, fBus, fDevice, fFunction) >> 8); - } - - UChar Device::HeaderType() - { - return (UChar)(ZKA_PCIReadRaw(0xC, fBus, fDevice, fFunction) >> 16); - } - - void Device::EnableMmio(UInt32 bar_in) - { - bool enable = Read(bar_in, sizeof(UChar)) | (1 << 1); - Write(bar_in, enable, sizeof(UShort)); - } - - void Device::BecomeBusMaster(UInt32 bar_in) - { - bool enable = Read(bar_in, sizeof(UShort)) | (1 << 2); - Write(bar_in, enable, sizeof(UShort)); - } - - UIntPtr Device::Bar(UInt32 bar_in) - { - UInt32 bar = ZKA_PCIReadRaw(bar_in, fBus, fDevice, fFunction); - return bar; - } - - UShort Device::Vendor() - { - UShort vendor = VendorId(); - - if (vendor != (UShort)PciConfigKind::Invalid) - fDevice = (UShort)Read(0x0, sizeof(UShort)); - - return fDevice; - } - - Device::operator bool() - { - return VendorId() != (UShort)PciConfigKind::Invalid; - } -} // namespace Kernel::PCI diff --git a/dev/ZKAKit/HALKit/AMD64/PCI/Express.cc b/dev/ZKAKit/HALKit/AMD64/PCI/Express.cc deleted file mode 100644 index ee039138..00000000 --- a/dev/ZKAKit/HALKit/AMD64/PCI/Express.cc +++ /dev/null @@ -1,11 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include - -namespace Kernel -{ -} diff --git a/dev/ZKAKit/HALKit/AMD64/PCI/IO.cc b/dev/ZKAKit/HALKit/AMD64/PCI/IO.cc deleted file mode 100644 index 7c602900..00000000 --- a/dev/ZKAKit/HALKit/AMD64/PCI/IO.cc +++ /dev/null @@ -1,7 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include diff --git a/dev/ZKAKit/HALKit/AMD64/PCI/Iterator.cc b/dev/ZKAKit/HALKit/AMD64/PCI/Iterator.cc deleted file mode 100644 index a6f3b937..00000000 --- a/dev/ZKAKit/HALKit/AMD64/PCI/Iterator.cc +++ /dev/null @@ -1,41 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include - -namespace Kernel::PCI -{ - Iterator::Iterator(const Types::PciDeviceKind& type) - { - // probe devices. - for (int bus = 0; bus < ZKA_BUS_COUNT; ++bus) - { - for (int device = 0; device < ZKA_DEVICE_COUNT; ++device) - { - for (int function = 0; function < ZKA_FUNCTION_COUNT; ++function) - { - auto bar = 0x00; - - Device dev(bus, device, function, bar); - - if (dev.Class() == (UChar)type) - { - fDevices[bus] = dev; - } - } - } - } - } - - Iterator::~Iterator() - { - } - - Ref Iterator::operator[](const Size& at) - { - return fDevices[at]; - } -} // namespace Kernel::PCI diff --git a/dev/ZKAKit/HALKit/AMD64/PCI/PCI.cc b/dev/ZKAKit/HALKit/AMD64/PCI/PCI.cc deleted file mode 100644 index ebc61759..00000000 --- a/dev/ZKAKit/HALKit/AMD64/PCI/PCI.cc +++ /dev/null @@ -1,7 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include diff --git a/dev/ZKAKit/HALKit/AMD64/Paging.h b/dev/ZKAKit/HALKit/AMD64/Paging.h deleted file mode 100644 index 5cfeab4c..00000000 --- a/dev/ZKAKit/HALKit/AMD64/Paging.h +++ /dev/null @@ -1,99 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -/** --------------------------------------------------- - - * THIS FILE CONTAINS CODE FOR X86_64 PAGING. - -------------------------------------------------------- */ - -#include - -#ifndef kPageMax -#define kPageMax (0x200) -#endif //! kPageMax - -#ifndef kPageAlign -#define kPageAlign (0x08) -#endif //! kPageAlign - -#ifndef kPageSize -#define kPageSize (0x100) -#endif // !kPageSize - -#ifndef kAlign -#define kAlign __BIGGEST_ALIGNMENT__ -#endif // !kAlign - -EXTERN_C void hal_flush_tlb(); -EXTERN_C void hal_invl_tlb(Kernel::VoidPtr addr); -EXTERN_C void hal_write_cr3(Kernel::VoidPtr cr3); -EXTERN_C void hal_write_cr0(Kernel::VoidPtr bit); - -EXTERN_C Kernel::VoidPtr hal_read_cr0(); // @brief CPU control register. -EXTERN_C Kernel::VoidPtr hal_read_cr2(); // @brief Fault address. -EXTERN_C Kernel::VoidPtr hal_read_cr3(); // @brief Page table. - -namespace Kernel::HAL -{ - /// @brief Final page entry (Not PML, PDPT) - struct PACKED ZKA_PTE final - { - UInt64 Present : 1; - UInt64 Wr : 1; - UInt64 User : 1; - UInt64 Wt : 1; - UInt64 Cache : 1; - UInt64 Accessed : 1; - UInt64 Dirty : 1; - UInt64 MemoryType : 1; - UInt64 Global : 1; - UInt64 Resvered1 : 3; - UInt64 PhysicalAddress : 36; - UInt64 Reserved2 : 10; - UInt64 ProtectionKey : 5; - UInt64 ExecDisable : 1; - }; - - namespace Detail - { - enum class ControlRegisterBits - { - ProtectedModeEnable = 0, - MonitorCoProcessor = 1, - Emulation = 2, - TaskSwitched = 3, - ExtensionType = 4, - NumericError = 5, - WriteProtect = 16, - AlignementMask = 18, - NotWriteThrough = 29, - CacheDisable = 30, - PageEnable = 31, - }; - - inline UInt8 control_register_cast(ControlRegisterBits reg) - { - return static_cast(reg); - } - } // namespace Detail - - struct ZKA_PDE final - { - ZKA_PTE* ALIGN(kPageAlign) fEntries[kPageMax]; - }; - - auto mm_alloc_bitmap(Boolean wr, Boolean user, SizeT size, Bool is_page) -> VoidPtr; - auto mm_free_bitmap(VoidPtr page_ptr) -> Bool; -} // namespace Kernel::HAL - -namespace Kernel -{ - typedef HAL::ZKA_PTE PTE; - typedef HAL::ZKA_PDE PDE; -} // namespace Kernel diff --git a/dev/ZKAKit/HALKit/AMD64/Processor.h b/dev/ZKAKit/HALKit/AMD64/Processor.h deleted file mode 100644 index a5e7f7d5..00000000 --- a/dev/ZKAKit/HALKit/AMD64/Processor.h +++ /dev/null @@ -1,331 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - - File: Prcoessor.h - Purpose: AMD64 processor abstraction. - - Revision History: - - 30/01/24: Added file (amlel) - -------------------------------------------- */ - -#pragma once - -#include -#include -#include -#include -#include - -#define kPITControlPort 0x43 -#define kPITChannel0Port 0x40 -#define kPITFrequency 1193180 - -#define kPICCommand 0x20 -#define kPICData 0x21 -#define kPIC2Command 0xA0 -#define kPIC2Data 0xA1 - -EXTERN_C -{ -#include -} - -#include - -/// @brief Maximum entries of the interrupt descriptor table. -#define kKernelIdtSize (0x100) - -/// @brief interrupt for system call. -#define kKernelInterruptId (0x32) - -#define IsActiveLow(FLG) (FLG & 2) -#define IsLevelTriggered(FLG) (FLG & 8) - -#define kInterruptGate (0x8E) -#define kTrapGate (0xEF) -#define kTaskGate (0b10001100) -#define kIDTSelector (0x08) - -namespace Kernel -{ - namespace Detail::AMD64 - { - struct PACKED InterruptDescriptorAMD64 final - { - UInt16 OffsetLow; // offset bits 0..15 - UInt16 Selector; // a code segment selector in GDT or LDT - UInt8 Ist; - UInt8 TypeAttributes; - UInt16 OffsetMid; - UInt32 OffsetHigh; - UInt32 Zero; // reserved - }; - } // namespace Detail::AMD64 -} // namespace Kernel - -namespace Kernel::HAL -{ - /// @brief Memory Manager mapping flags. - enum - { - kMMFlagsInvalid = 0 << 0, - kMMFlagsPresent = 1 << 0, - kMMFlagsWr = 1 << 1, - kMMFlagsUser = 1 << 2, - kMMFlagsNX = 1 << 3, - kMMFlagsCount = 4, - }; - - struct PACKED Register64 final - { - UShort Limit; - UIntPtr Base; - }; - - struct PACKED RegisterGDT final - { - UShort Limit; - UIntPtr Base; - }; - - using RawRegister = UInt64; - using Reg = RawRegister; - using InterruptId = UInt16; /* For each element in the IVT */ - - /// @brief Stack frame (as retrieved from assembly.) - struct PACKED StackFrame final - { - RawRegister R8{0}; - RawRegister R9{0}; - RawRegister R10{0}; - RawRegister FS{0}; - RawRegister R12{0}; - RawRegister R13{0}; - RawRegister R14{0}; - RawRegister R15{0}; - RawRegister GS{0}; - RawRegister SP{0}; - RawRegister BP{0}; - }; - - typedef StackFrame* StackFramePtr; - - class InterruptDescriptor final - { - public: - UShort Offset; - UShort Selector; - UChar Ist; - UChar Atrributes; - - UShort SecondOffset; - UInt ThirdOffset; - UInt Zero; - - operator bool() - { - return Offset != 0xFFFF; - } - }; - - using InterruptDescriptorArray = Array; - - class SegmentDescriptor final - { - public: - UInt16 Base; - UInt8 BaseMiddle; - UInt8 BaseHigh; - - UShort Limit; - UChar Gran; - UChar AccessByte; - }; - - /*** - * @brief Segment Boolean operations - */ - class SegmentDescriptorComparator final - { - public: - Bool IsValid(SegmentDescriptor& seg) - { - return seg.Base > seg.Limit; - } - - Bool Equals(SegmentDescriptor& seg, SegmentDescriptor& segRight) - { - return seg.Base == segRight.Base && seg.Limit == segRight.Limit; - } - }; - - using SegmentArray = Array; - - class GDTLoader final - { - public: - static Void Load(RegisterGDT& gdt); - static Void Load(Ref& gdt); - }; - - class IDTLoader final - { - public: - static Void Load(Register64& idt); - static Void Load(Ref& idt); - }; - /***********************************************************************************/ - /// @brief Is the current config SMP aware? - /// @return True if YES, False if not. - /***********************************************************************************/ - Bool mp_is_smp(Void) noexcept; - - /***********************************************************************************/ - /// @brief Fetch and enable SMP scheduler. - /// @param vendor_ptr SMP containing structure. - /***********************************************************************************/ - Void mp_get_cores(VoidPtr vendor_ptr) noexcept; - - /***********************************************************************************/ - - Void hal_send_start_ipi(UInt32 apicId, UInt8 vector, UInt32 targetAddress); - Void hal_send_end_ipi(UInt32 apicId, UInt8 vector, UInt32 targetAddress); - - /***********************************************************************************/ - - /***********************************************************************************/ - /// @brief Do a cpuid to check if MSR exists on CPU. - /// @retval true it does exists. - /// @retval false it doesn't. - /***********************************************************************************/ - inline Bool hal_has_msr() noexcept - { - static UInt32 eax, unused, edx; // eax, edx - - __get_cpuid(1, &eax, &unused, &unused, &edx); - - // edx returns the flag for MSR (which is 1 shifted to 5.) - return edx & (1 << 5); - } - - /***********************************************************************************/ - /// @brief Get Model specific register inside core. - /// @param msr MSR - /// @param lo low byte - /// @param hi high byte - /***********************************************************************************/ - inline Void hal_get_msr(UInt32 msr, UInt32* lo, UInt32* hi) noexcept - { - if (!lo || !hi) - return; - - asm volatile("rdmsr" - : "=a"(*lo), "=d"(*hi) - : "c"(msr)); - } - - /// @brief Set Model-specific register. - /// @param msr MSR - /// @param lo low byte - /// @param hi high byte - inline Void hal_set_msr(UInt32 msr, UInt32 lo, UInt32 hi) noexcept - { - asm volatile("wrmsr" - : - : "a"(lo), "d"(hi), "c"(msr)); - } - - /// @brief Processor specific namespace. - namespace Detail - { - /* @brief TSS struct. */ - struct ZKA_TSS final - { - UInt32 fReserved1; - UInt64 fRsp0; - UInt64 fRsp1; - UInt64 fRsp2; - UInt64 fReserved2; - UInt64 fIst1; - UInt64 fIst2; - UInt64 fIst3; - UInt64 fIst4; - UInt64 fIst5; - UInt64 fIst6; - UInt64 fIst7; - UInt64 fReserved3; - UInt16 fReserved4; - UInt16 fIopb; - }; - - /** - @brief Global descriptor table entry, either null, code or data. - */ - - struct PACKED ZKA_GDT_ENTRY final - { - UInt16 fLimitLow; - UInt16 fBaseLow; - UInt8 fBaseMid; - UInt8 fAccessByte; - UInt8 fFlags; - UInt8 fBaseHigh; - }; - } // namespace Detail - - class APICController - { - public: - explicit APICController(VoidPtr base) - : fApic(base) - { - } - - ~APICController() = default; - - ZKA_COPY_DEFAULT(APICController); - - public: - UInt32 Read(UInt32 reg) noexcept; - Void Write(UInt32 reg, UInt32 value) noexcept; - - private: - VoidPtr fApic{nullptr}; - }; - - /// @brief Set a PTE from pd_base. - /// @param virt_addr a valid virtual address. - /// @param phys_addr point to physical address. - /// @param flags the flags to put on the page. - /// @return Status code of page manip. - EXTERN_C Int32 mm_map_page(VoidPtr virt_addr, UInt32 flags); - - EXTERN_C UInt8 rt_in8(UInt16 port); - EXTERN_C UInt16 rt_in16(UInt16 port); - EXTERN_C UInt32 rt_in32(UInt16 port); - - EXTERN_C void rt_out16(UShort port, UShort byte); - EXTERN_C void rt_out8(UShort port, UChar byte); - EXTERN_C void rt_out32(UShort port, UInt byte); - - EXTERN_C void rt_wait_400ns(); - EXTERN_C void rt_halt(); - EXTERN_C void rt_cli(); - EXTERN_C void rt_sti(); - EXTERN_C void rt_cld(); - EXTERN_C void rt_std(); -} // namespace Kernel::HAL - -EXTERN_C Kernel::Void idt_handle_generic(Kernel::UIntPtr rsp); -EXTERN_C Kernel::Void idt_handle_gpf(Kernel::UIntPtr rsp); -EXTERN_C Kernel::Void idt_handle_math(Kernel::UIntPtr rsp); -EXTERN_C Kernel::Void idt_handle_pf(Kernel::UIntPtr rsp); - -EXTERN_C ATTRIBUTE(naked) Kernel::Void hal_load_idt(Kernel::HAL::Register64 ptr); -EXTERN_C ATTRIBUTE(naked) Kernel::Void hal_load_gdt(Kernel::HAL::RegisterGDT ptr); - -inline Kernel::VoidPtr kKernelBitMpStart = nullptr; -inline Kernel::UIntPtr kKernelBitMpSize = 0UL; diff --git a/dev/ZKAKit/HALKit/AMD64/ReadMe.md b/dev/ZKAKit/HALKit/AMD64/ReadMe.md deleted file mode 100644 index 9fd0b980..00000000 --- a/dev/ZKAKit/HALKit/AMD64/ReadMe.md +++ /dev/null @@ -1,8 +0,0 @@ -# AMD64 Hardware Abstraction Layer - -## Brief - -- Supported CPU: AMD64 BASED CPUs. -- Supported Firmware: EDK 2. - -###### Copyright (C) 2024, Theater Quality Inc, all rights reserved. All rights reserved. diff --git a/dev/ZKAKit/HALKit/AMD64/Storage/AHCI-DMA.cc b/dev/ZKAKit/HALKit/AMD64/Storage/AHCI-DMA.cc deleted file mode 100644 index 44e72ec9..00000000 --- a/dev/ZKAKit/HALKit/AMD64/Storage/AHCI-DMA.cc +++ /dev/null @@ -1,319 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -/** - * @file AHCI.cc - * @author Theater Quality Inc (amlalelmahrouss@icloud.com) - * @brief AHCI driver. - * @version 0.1 - * @date 2024-02-02 - * - * @Copyright (C) 2024, Theater Quality Inc, all rights reserved. - * - */ - -#include -#include - -#include -#include -#include -#include -#include - -#ifdef __AHCI__ - -#define HBA_ERR_TFE (1 << 30) -#define HBA_PxCMD_ST 0x0001 -#define HBA_PxCMD_FRE 0x0010 -#define HBA_PxCMD_FR 0x4000 -#define HBA_PxCMD_CR 0x8000 - -#define kAhciStartAddress mib_cast(4) - -#define kAhciLBAMode (1 << 6) - -#define kAhciMaxPoll (100000U) - -#define kCmdOrCtrlCmd 1 -#define kCmdOrCtrlCtrl 0 - -#define kAhciSRBsy 0x80 -#define kAhciSRDrq 0x08 - -enum -{ - kSATAProgIfAHCI = 0x01, - kSATASubClass = 0x06, - kSATABar5 = 0x24, -}; - -STATIC Kernel::PCI::Device kAhciDevice; -STATIC HbaPort* kAhciPort = nullptr; -STATIC Kernel::Lba kCurrentDiskSectorCount = 0UL; - -Kernel::Void drv_calculate_disk_geometry() -{ - kCurrentDiskSectorCount = 0UL; - kcout << "Highest AHCI LBA (48-bit): " << Kernel::number(kCurrentDiskSectorCount) << endl; -} - -/// @brief Initializes an AHCI disk. -/// @param PortsImplemented the amount of kAhciPort that have been detected. -/// @return if the disk was successfully initialized or not. -Kernel::Boolean drv_std_init(Kernel::UInt16& PortsImplemented) -{ - using namespace Kernel; - - PCI::Iterator iterator(Types::PciDeviceKind::MassStorageController); - - for (SizeT device_index = 0; device_index < ZKA_BUS_COUNT; ++device_index) - { - kAhciDevice = iterator[device_index].Leak(); // And then leak the reference. - - // if SATA and then interface is AHCI... - if (kAhciDevice.Subclass() == kSATASubClass && - kAhciDevice.ProgIf() == kSATAProgIfAHCI) - { - kAhciDevice.EnableMmio(0x24); // Enable the memory index_byte/o for this ahci device. - kAhciDevice.BecomeBusMaster(0x24); // Become bus master for this ahci device, so that we can control it. - - HbaMem* mem_ahci = (HbaMem*)kAhciDevice.Bar(0x24); - - Kernel::UInt32 ports_implemented = mem_ahci->Pi; - Kernel::UInt16 ahci_index = 0; - - const Kernel::UInt16 kMaxPortsImplemented = 32; - const Kernel::UInt32 kSATASignature = 0x00000101; - const Kernel::UInt8 kAhciPresent = 0x03; - const Kernel::UInt8 kAhciIPMActive = 0x01; - - Kernel::Boolean detected = false; - - while (ahci_index < kMaxPortsImplemented) - { - if (ports_implemented) - { - kcout << "Port is implemented by host.\r"; - - Kernel::UInt8 ipm = (mem_ahci->Ports[ahci_index].Ssts >> 8) & 0x0F; - Kernel::UInt8 det = mem_ahci->Ports[ahci_index].Ssts & 0x0F; - - if (mem_ahci->Ports[ahci_index].Sig == kSATASignature) - { - kcout << "Port is AHCI controller.\r"; - - detected = true; - - kAhciPort = &mem_ahci->Ports[ahci_index]; - - kAhciPort->Cmd &= ~HBA_PxCMD_FRE; - - // Clear FRE (bit4) - kAhciPort->Cmd &= ~HBA_PxCMD_ST; - - // Wait until FR (bit14), CR (bit15) are cleared - while (YES) - { - if (kAhciPort->Cmd & HBA_PxCMD_CR) - continue; - - if (kAhciPort->Cmd & HBA_PxCMD_FR) - continue; - break; - } - - // when it's stopped. - - // do in-between - - kAhciPort->Clb = kAhciStartAddress + (ahci_index << 10); - kAhciPort->Clbu = 0; - rt_set_memory((Kernel::VoidPtr)((Kernel::UIntPtr)kAhciPort->Clb + kAhciPort->Clbu), 0, 1024); - - // FIS offset: 32K+256*ahci_index - // FIS entry size = 256 bytes per port - kAhciPort->Fb = kAhciStartAddress + (32 << 10) + (ahci_index << 8); - kAhciPort->Fbu = 0; - rt_set_memory((Kernel::VoidPtr)((Kernel::UIntPtr)kAhciPort->Fb + kAhciPort->Fbu), 0, 256); - - // Command table offset: 40K + 8K*ahci_index - // Command table size = 256*32 = 8K per port - HbaCmdHeader* cmd_header = (HbaCmdHeader*)((Kernel::UIntPtr)kAhciPort->Clb + kAhciPort->Clbu); - - for (SizeT i = 0; i < 32; i++) - { - cmd_header[i].Prdtl = 8; // 8 prdt entries per command table - // 256 bytes per command table, 64+16+48+16*8 - // Command table offset: 40K + 8K*ahci_index + cmdheader_index*256 - cmd_header[i].Ctba = kAhciStartAddress + (40 << 10) + (ahci_index << 13) + (i << 8); - cmd_header[i].Ctbau = 0; - - rt_set_memory((VoidPtr)((Kernel::UIntPtr)cmd_header[i].Ctba + cmd_header[i].Ctbau), 0, 256); - } - - // when it's starting - - // check for bits again, to start it again. - while (YES) - { - if (kAhciPort->Cmd & HBA_PxCMD_FR) - continue; - - break; - } - - kAhciPort->Cmd |= HBA_PxCMD_FRE; - kAhciPort->Cmd |= HBA_PxCMD_ST; - - drv_calculate_disk_geometry(); - - break; - } - } - - ports_implemented >>= 1; - ++ahci_index; - } - - return detected; - } - } - - return No; -} - -Kernel::Boolean drv_std_detected(Kernel::Void) -{ - return kAhciDevice.DeviceId() != 0xFFFF; -} - -Kernel::Void drv_std_write(Kernel::UInt64 lba, Kernel::Char* buffer, Kernel::SizeT sector_cnt, Kernel::SizeT size_buffer) -{ -} - -Kernel::Void drv_std_read(Kernel::UInt64 lba, Kernel::Char* buffer, Kernel::SizeT sector_cnt, Kernel::SizeT size_buffer) -{ - kAhciPort->Is = -1; - - Kernel::SizeT port = 0; - Kernel::UInt32 slots = (kAhciPort->Sact | kAhciPort->Ci); - - for (; port < slots; ++port) - { - if ((slots & 1) == 0) - break; - - slots >>= 1; - } - - HbaCmdHeader* cmd_hdr = (HbaCmdHeader*)((Kernel::UIntPtr)kAhciPort->Clb + kAhciPort->Clbu); - - cmd_hdr += port; - cmd_hdr->Cfl = sizeof(FisRegH2D) / sizeof(Kernel::UInt32); - cmd_hdr->Write = NO; - cmd_hdr->Prdtl = (Kernel::UInt16)((sector_cnt - 1) >> 4) + 1; - - HbaCmdTbl* cmd_tbl = (HbaCmdTbl*)((Kernel::UIntPtr)cmd_hdr->Ctba + cmd_hdr->Ctbau); - Kernel::rt_set_memory(cmd_tbl, 0, (cmd_hdr->Prdtl - 1) * sizeof(HbaPrdtEntry)); - - Kernel::SizeT i = 0; - - for (Kernel::SizeT i = 0; i < cmd_hdr->Prdtl - 1; i++) - { - cmd_tbl->PrdtEntries[i].Dba = (Kernel::UInt32)(Kernel::UInt64)buffer; - cmd_tbl->PrdtEntries[i].Dbau = (Kernel::UInt32)((Kernel::UInt64)(buffer) >> 32); - cmd_tbl->PrdtEntries[i].Dbc = size_buffer - 1; // 8K bytes (this value should always be set to 1 less than the actual value) - cmd_tbl->PrdtEntries[i].InterruptBit = 1; - } - - cmd_tbl->PrdtEntries[i].Dba = (Kernel::UInt32)(Kernel::UInt64)buffer; - cmd_tbl->PrdtEntries[i].Dbau = (Kernel::UInt32)((Kernel::UInt64)(buffer) >> 32); - cmd_tbl->PrdtEntries[i].Dbc = size_buffer - 1; // 8K bytes (this value should always be set to 1 less than the actual value) - cmd_tbl->PrdtEntries[i].InterruptBit = 1; - - FisRegH2D* cmd_fis = (FisRegH2D*)(&cmd_tbl->Cfis); - - cmd_fis->FisType = kFISTypeRegH2D; - cmd_fis->CmdOrCtrl = YES; // Command - cmd_fis->Command = kAHCICmdReadDmaEx; - - cmd_fis->Lba0 = (Kernel::UInt8)(Kernel::UInt32)lba & 0xFF; - cmd_fis->Lba1 = (Kernel::UInt8)((Kernel::UInt32)lba >> 8); - cmd_fis->Lba2 = (Kernel::UInt8)((Kernel::UInt32)lba >> 16); - cmd_fis->Device = kAhciLBAMode; // LBA mode - - cmd_fis->Lba3 = (Kernel::UInt8)((Kernel::UInt32)lba >> 24); - cmd_fis->Lba4 = (Kernel::UInt8)(lba >> 32); - cmd_fis->Lba5 = (Kernel::UInt8)((lba >> 32) >> 8); - - cmd_fis->CountLow = sector_cnt & 0xFF; - cmd_fis->CountHigh = (sector_cnt >> 8) & 0xFF; - - Kernel::UInt64 spin = 0UL; - - // The below loop waits until the port is no longer busy before issuing a new command - while ((kAhciPort->Tfd & (kAhciSRBsy | kAhciSRDrq)) && spin < kAhciMaxPoll) - { - spin++; - } - if (spin == 1000000) - { - kcout << "AHCI: Port is hung.\r"; - return; - } - - kAhciPort->Ci = 1 << port; // Issue command - - // Wait for completion - while (YES) - { - // In some longer duration reads, it may be helpful to spin on the DPS bit - // in the PxIS port field as well (1 << 5) - if ((kAhciPort->Ci & (1 << port)) == 0) - break; - if (kAhciPort->Is & HBA_ERR_TFE) // Task file error - { - using namespace Kernel; - kcout << ("AHCI: Read disk error.\r"); - - err_global_get() = kErrorUnrecoverableDisk; - - return; - } - } - - // Check again for the last time. - if (kAhciPort->Is & HBA_ERR_TFE) // task file error status - { - using namespace Kernel; - - kcout << ("AHCI: Read disk error.\r"); - *buffer = 0; - - err_global_get() = kErrorUnrecoverableDisk; - - return; - } -} - -/*** - @brief Gets the number of sectors inside the drive. - @return Sector size in bytes. - */ -Kernel::SizeT drv_get_sector_count() -{ - return kCurrentDiskSectorCount; -} - -/// @brief Get the drive size. -/// @return Disk size in bytes. -Kernel::SizeT drv_get_size() -{ - return drv_get_sector_count() * kAHCISectorSize; -} - -#endif // ifdef __AHCI__ diff --git a/dev/ZKAKit/HALKit/AMD64/Storage/ATA-DMA.cc b/dev/ZKAKit/HALKit/AMD64/Storage/ATA-DMA.cc deleted file mode 100644 index dcca84dc..00000000 --- a/dev/ZKAKit/HALKit/AMD64/Storage/ATA-DMA.cc +++ /dev/null @@ -1,38 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -/** - * @file ATA-DMA.cc - * @author Theater Quality Inc (amlalelmahrouss@icloud.com) - * @brief ATA driver (DMA mode). - * @version 0.1 - * @date 2024-02-02 - * - * @copyright Copyright (c) Theater Quality Inc - * - */ - -#include - -#include -#include - -using namespace Kernel; - -EXTERN_C Int32 kPRDTTransferStatus; -STATIC PRDT kPRDT; - -#ifdef __ATA_DMA__ - -#ifdef __ATA_PIO__ -#error !!! You cant have both PIO and DMA enabled! !!! -#endif /* ifdef __ATA_PIO__ */ - -#ifdef __AHCI__ -#error !!! You cant have both ATA and AHCI enabled! !!! -#endif /* ifdef __AHCI__ */ - -#endif /* ifdef __ATA_DMA__ */ diff --git a/dev/ZKAKit/HALKit/AMD64/Storage/ATA-PIO.cc b/dev/ZKAKit/HALKit/AMD64/Storage/ATA-PIO.cc deleted file mode 100644 index e117d89c..00000000 --- a/dev/ZKAKit/HALKit/AMD64/Storage/ATA-PIO.cc +++ /dev/null @@ -1,197 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -/** - * @file ATA-PIO.cc - * @author Theater Quality Inc (amlalelmahrouss@icloud.com) - * @brief ATA driver (PIO mode). - * @version 0.1 - * @date 2024-02-02 - * - * @copyright Copyright (c) Theater Quality Inc - * - */ - -#include -#include - -#ifdef __ATA_PIO__ - -using namespace Kernel; -using namespace Kernel::HAL; - -/// bugs: 0 - -#define kATADataLen 256 - -STATIC Boolean kATADetected = false; -STATIC Int32 kATADeviceType = kATADeviceCount; -STATIC Char kATAData[kATADataLen] = {0}; - -Boolean drv_std_wait_io(UInt16 IO) -{ - for (int i = 0; i < 400; i++) - rt_in8(IO + ATA_REG_STATUS); - -ATAWaitForIO_Retry: - auto statRdy = rt_in8(IO + ATA_REG_STATUS); - - if ((statRdy & ATA_SR_BSY)) - goto ATAWaitForIO_Retry; - -ATAWaitForIO_Retry2: - statRdy = rt_in8(IO + ATA_REG_STATUS); - - if (statRdy & ATA_SR_ERR) - return false; - - if (!(statRdy & ATA_SR_DRDY)) - goto ATAWaitForIO_Retry2; - - return true; -} - -Void drv_std_select(UInt16 Bus) -{ - if (Bus == ATA_PRIMARY_IO) - rt_out8(Bus + ATA_REG_HDDEVSEL, ATA_PRIMARY_SEL); - else - rt_out8(Bus + ATA_REG_HDDEVSEL, ATA_SECONDARY_SEL); -} - -Boolean drv_std_init(UInt16 Bus, UInt8 Drive, UInt16& OutBus, UInt8& OutMaster) -{ - UInt16 IO = Bus; - - drv_std_select(IO); - -ATAInit_Retry: - // Bus init, NEIN bit. - rt_out8(IO + ATA_REG_NEIN, 1); - - // identify until it's good - - auto statRdy = rt_in8(IO + ATA_REG_STATUS); - - if (statRdy & ATA_SR_ERR) - { - kcout << "ERROR: ATA DRIVE RETURNED ERROR BIT! ABORTING...\r"; - - return false; - } - - if ((statRdy & ATA_SR_BSY)) - { - kcout << "Retrying..."; - goto ATAInit_Retry; - } - - rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_IDENTIFY); - - /// fetch serial info - /// model, speed, number of sectors... - - drv_std_wait_io(IO); - - for (SizeT indexData = 0ul; indexData < kATADataLen; ++indexData) - { - kATAData[indexData] = rt_in16(IO + ATA_REG_DATA); - } - - OutBus = (Bus == ATA_PRIMARY_IO) ? ATA_PRIMARY_IO : ATA_SECONDARY_IO; - - OutMaster = (Bus == ATA_PRIMARY_IO) ? ATA_MASTER : ATA_SLAVE; - - kcout << "INFO: INITIALIZED ATA DRIVE!\r"; - - return true; -} - -Void drv_std_read(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size) -{ - Lba /= SectorSz; - - UInt8 Command = ((!Master) ? 0xE0 : 0xF0); - - drv_std_wait_io(IO); - drv_std_select(IO); - - rt_out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F)); - - rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + SectorSz) / SectorSz)); - - rt_out8(IO + ATA_REG_LBA0, (Lba)&0xFF); - rt_out8(IO + ATA_REG_LBA1, (Lba) >> 8); - rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16); - rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24); - - rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_READ_PIO); - - drv_std_wait_io(IO); - - for (SizeT IndexOff = 0; IndexOff < Size; ++IndexOff) - { - drv_std_wait_io(IO); - Buf[IndexOff] = rt_in16(IO + ATA_REG_DATA); - drv_std_wait_io(IO); - } - - drv_std_wait_io(IO); -} - -Void drv_std_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size) -{ - Lba /= SectorSz; - - UInt8 Command = ((!Master) ? 0xE0 : 0xF0); - - drv_std_wait_io(IO); - drv_std_select(IO); - - rt_out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F)); - - rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + (SectorSz)) / SectorSz)); - - rt_out8(IO + ATA_REG_LBA0, (Lba)&0xFF); - rt_out8(IO + ATA_REG_LBA1, (Lba) >> 8); - rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16); - rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24); - - rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_WRITE_PIO); - - drv_std_wait_io(IO); - - for (SizeT IndexOff = 0; IndexOff < Size; ++IndexOff) - { - drv_std_wait_io(IO); - rt_out16(IO + ATA_REG_DATA, Buf[IndexOff]); - drv_std_wait_io(IO); - } - - drv_std_wait_io(IO); -} - -/// @brief is ATA detected? -Boolean drv_std_detected(Void) -{ - return kATADetected; -} - -/*** - @brief Getter, gets the number of sectors inside the drive. -*/ -Kernel::SizeT drv_get_sector_count() -{ - return (kATAData[61] << 16) | kATAData[60]; -} - -/// @brief Get the drive size. -Kernel::SizeT drv_get_size() -{ - return drv_get_sector_count() * kATASectorSize; -} - -#endif /* ifdef __ATA_PIO__ */ diff --git a/dev/ZKAKit/HALKit/ARM64/.gitkeep b/dev/ZKAKit/HALKit/ARM64/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/dev/ZKAKit/HALKit/ARM64/AP.h b/dev/ZKAKit/HALKit/ARM64/AP.h deleted file mode 100644 index 9b018526..00000000 --- a/dev/ZKAKit/HALKit/ARM64/AP.h +++ /dev/null @@ -1,36 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - - File: AP.h - Purpose: RISC-V hardware threads. - - Revision History: - - 30/01/24: Added file (amlel) - -------------------------------------------- */ - -#pragma once - -#include - -namespace Kernel -{ - typedef Int64 hal_ap_kind; - - typedef struct HAL_HARDWARE_THREAD - { - Kernel::UIntPtr fStartAddress; - Kernel::UInt8 fPrivleged : 1; - Kernel::UInt32 fPageMemoryFlags; - hal_ap_kind fIdentNumber; - } HAL_HARDWARE_THREAD; - - /// @brief Set PC to specific hart. - /// @param hart the hart - /// @param epc the pc. - /// @return - EXTERN_C Kernel::Void hal_set_pc_to_hart(HAL_HARDWARE_THREAD* hart, Kernel::VoidPtr epc); - -} // namespace Kernel diff --git a/dev/ZKAKit/HALKit/ARM64/APM/.gitkeep b/dev/ZKAKit/HALKit/ARM64/APM/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/dev/ZKAKit/HALKit/ARM64/APM/APM.cc b/dev/ZKAKit/HALKit/ARM64/APM/APM.cc deleted file mode 100644 index 80cd4b8d..00000000 --- a/dev/ZKAKit/HALKit/ARM64/APM/APM.cc +++ /dev/null @@ -1,37 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include - -using namespace Kernel; - -/// @brief Send a APM command into it's own IO space. -/// @param base_dma the IO base port. -/// @param cmd the command. -/// @return status code. -EXTERN_C Int32 apm_send_io_command(UInt16 cmd, APMPowerCmd value) -{ - switch (cmd) - { - case kAPMPowerCommandReboot: { - asm volatile( - "ldr x0, =0x84000009\n" - "hvc #0\n"); - - return kErrorSuccess; - } - case kAPMPowerCommandShutdown: { - asm volatile( - "ldr x0, =0x84000008\n" - "hvc #0\n"); - - return kErrorSuccess; - } - default: - return kErrorInvalidData; - } -} diff --git a/dev/ZKAKit/HALKit/ARM64/HalACPIFactoryInterface.cc b/dev/ZKAKit/HALKit/ARM64/HalACPIFactoryInterface.cc deleted file mode 100644 index f8c8ffd8..00000000 --- a/dev/ZKAKit/HALKit/ARM64/HalACPIFactoryInterface.cc +++ /dev/null @@ -1,31 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include -#include -#include -#include - -namespace Kernel -{ - ACPIFactoryInterface::ACPIFactoryInterface(VoidPtr rsp_ptr) - : fRsdp(rsp_ptr), fEntries(0) - { - } - - Void ACPIFactoryInterface::Shutdown() - { - apm_send_io_command(kAPMPowerCommandShutdown, 0); - } - - /// @brief Reboot machine in either ACPI or by triple faulting. - /// @return nothing it's a reboot. - Void ACPIFactoryInterface::Reboot() - { - apm_send_io_command(kAPMPowerCommandReboot, 0); - } -} // namespace Kernel diff --git a/dev/ZKAKit/HALKit/ARM64/HalAP.cc b/dev/ZKAKit/HALKit/ARM64/HalAP.cc deleted file mode 100644 index e2fe69c2..00000000 --- a/dev/ZKAKit/HALKit/ARM64/HalAP.cc +++ /dev/null @@ -1,40 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include -#include - -using namespace Kernel; - -namespace Kernel::Detail -{ - STATIC void mp_hang_fn(void) - { - while (YES) - ; - } -} // namespace Kernel::Detail - -/// @brief wakes up thread. -/// wakes up thread from hang. -void mp_wakeup_thread(HAL::StackFramePtr stack) -{ - if (!stack) - return; - - hal_set_pc_to_hart(reinterpret_cast(stack->R15), reinterpret_cast(stack->BP)); -} - -/// @brief makes thread sleep. -/// hooks and hangs thread to prevent code from executing. -void mp_hang_thread(HAL::StackFramePtr stack) -{ - if (!stack) - return; - - hal_set_pc_to_hart(reinterpret_cast(stack->R15), reinterpret_cast(Kernel::Detail::mp_hang_fn)); -} diff --git a/dev/ZKAKit/HALKit/ARM64/HalCoreMPScheduler.cc b/dev/ZKAKit/HALKit/ARM64/HalCoreMPScheduler.cc deleted file mode 100644 index 75f8283c..00000000 --- a/dev/ZKAKit/HALKit/ARM64/HalCoreMPScheduler.cc +++ /dev/null @@ -1,28 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include - -using namespace Kernel; - -STATIC struct PROCESS_CONTROL_BLOCK final -{ - HAL::StackFramePtr f_Frame; - UInt8* f_Stack; - VoidPtr f_Image; -} kProcessBlocks[kSchedProcessLimitPerTeam] = {0}; - -EXTERN_C HAL::StackFramePtr mp_get_current_context(ProcessID pid) -{ - return kProcessBlocks[pid % kSchedProcessLimitPerTeam].f_Frame; -} - -EXTERN_C Bool mp_register_process(VoidPtr image, UInt8* stack_ptr, HAL::StackFramePtr stack_frame, ProcessID pid) -{ - MUST_PASS(image && stack_ptr && stack_frame); - return No; -} diff --git a/dev/ZKAKit/HALKit/ARM64/HalDebugOutput.cc b/dev/ZKAKit/HALKit/ARM64/HalDebugOutput.cc deleted file mode 100644 index c138480d..00000000 --- a/dev/ZKAKit/HALKit/ARM64/HalDebugOutput.cc +++ /dev/null @@ -1,83 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include -#include -#include - -namespace Kernel -{ - EXTERN_C void ke_io_write(const Char* bytes) - { -#ifdef __DEBUG__ - if (*bytes == 0) - return; - - SizeT index = 0; - SizeT len = 0; - - index = 0; - len = rt_string_len(bytes, 255); - - volatile UInt8* uart_ptr = (UInt8*)0x09000000; - - while (index < len) - { - if (bytes[index] == '\r') - *uart_ptr = '\r'; - - *uart_ptr = bytes[index] == '\r' ? '\n' : bytes[index]; - ++index; - } -#endif // __DEBUG__ - } - - TerminalDevice::~TerminalDevice() = default; - - EXTERN_C void ke_io_read(const Char* bytes) - { -#ifdef __DEBUG__ - SizeT index = 0; - - volatile UInt8* uart_ptr = (UInt8*)0x09000000; - - ///! TODO: Look on how to wait for the UART to complete. - while (Yes) - { - auto in = *uart_ptr; - - ///! If enter pressed then break. - if (in == 0xD) - { - break; - } - - if (in < '0' || in < 'A' || in < 'a') - { - if (in != '@' || in != '!' || in != '?' || in != '.' || in != '/' || - in != ':') - { - continue; - } - } - - ((char*)bytes)[index] = in; - - ++index; - } - - ((char*)bytes)[index] = 0; -#endif // __DEBUG__ - } - - TerminalDevice TerminalDevice::The() noexcept - { - TerminalDevice out(Kernel::ke_io_write, Kernel::ke_io_read); - return out; - } - -} // namespace Kernel diff --git a/dev/ZKAKit/HALKit/ARM64/HalKernelMain.cc b/dev/ZKAKit/HALKit/ARM64/HalKernelMain.cc deleted file mode 100644 index c7c642ff..00000000 --- a/dev/ZKAKit/HALKit/ARM64/HalKernelMain.cc +++ /dev/null @@ -1,57 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -Kernel::Void hal_real_init(Kernel::Void) noexcept; -EXTERN_C Kernel::Void rtl_kernel_main(Kernel::SizeT argc, char** argv, char** envp, Kernel::SizeT envp_len); - -EXTERN_C void hal_init_platform( - Kernel::HEL::BootInfoHeader* handover_hdr) -{ - - /************************************************** */ - /* INITIALIZE AND VALIDATE HEADER. */ - /************************************************** */ - - kHandoverHeader = handover_hdr; - - if (kHandoverHeader->f_Magic != kHandoverMagic && - kHandoverHeader->f_Version != kHandoverVersion) - { - return; - } - - /************************************** */ - /* INITIALIZE BIT MAP. */ - /************************************** */ - - kKernelBitMpSize = kHandoverHeader->f_BitMapSize; - kKernelBitMpStart = reinterpret_cast( - reinterpret_cast(kHandoverHeader->f_BitMapStart)); - - /// @note do initialize the interrupts after it. - - CG::CGDrawBackground(); - - rtl_kernel_main(0, nullptr, nullptr, 0); - - while (YES) - { - } -} diff --git a/dev/ZKAKit/HALKit/ARM64/HalPageInternal.S b/dev/ZKAKit/HALKit/ARM64/HalPageInternal.S deleted file mode 100644 index 8fcf40ff..00000000 --- a/dev/ZKAKit/HALKit/ARM64/HalPageInternal.S +++ /dev/null @@ -1,5 +0,0 @@ -.text - -hal_flush_tlb: - tlbi - ret diff --git a/dev/ZKAKit/HALKit/ARM64/HalPagingMgrARM64.cc b/dev/ZKAKit/HALKit/ARM64/HalPagingMgrARM64.cc deleted file mode 100644 index 6d160213..00000000 --- a/dev/ZKAKit/HALKit/ARM64/HalPagingMgrARM64.cc +++ /dev/null @@ -1,86 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - - File: HalPagingMgr.cc - Purpose: Platform Paging Manager.. - -------------------------------------------- */ - -#include -#include - -namespace Kernel::HAL -{ - typedef UInt32 PageTableIndex; - - /// \brief Page store type. - struct ZKA_PAGE_STORE final - { - struct - { - PDE* fPde{nullptr}; - PTE* fPte{nullptr}; - VoidPtr fVAddr{nullptr}; - } fInternalStore; - - Bool fStoreOp{No}; // Store operation in progress. - - static ZKA_PAGE_STORE& The() - { - static ZKA_PAGE_STORE the; - return the; - } - }; - - /// \brief Retrieve the page status of a PTE. - STATIC Void mmi_page_status(PTE* pte) - { - } - - STATIC Int32 mmi_map_page_table_entry(VoidPtr virtual_address, UInt32 flags, PTE* pt_entry); - - /// @brief Maps or allocates a page from virtual_address. - /// @param virtual_address a valid virtual address. - /// @param phys_addr point to physical address. - /// @param flags the flags to put on the page. - /// @return Status code of page manipulation process. - EXTERN_C Int32 mm_map_page(VoidPtr virtual_address, UInt32 flags) - { - if (!virtual_address || - !flags) - return 0; - - ZKA_PAGE_STORE& page_store = ZKA_PAGE_STORE::The(); - - while (page_store.fStoreOp) - ; - - page_store.fStoreOp = Yes; - - if (page_store.fInternalStore.fVAddr == virtual_address) - { - page_store.fStoreOp = No; - return mmi_map_page_table_entry(page_store.fInternalStore.fVAddr, flags, page_store.fInternalStore.fPte); - } - - return 1; - } - - /// @brief Maps flags for a specific pte. - /// @internal Internal function. - STATIC Int32 mmi_map_page_table_entry(VoidPtr virtual_address, UInt32 flags, PTE* pt_entry) - { - ZKA_PAGE_STORE& page_store = ZKA_PAGE_STORE::The(); - - // Update Internal store. - - page_store.fInternalStore.fPde = nullptr; - page_store.fInternalStore.fPte = pt_entry; - page_store.fInternalStore.fVAddr = virtual_address; - - page_store.fStoreOp = No; - - return 0; - } -} // namespace Kernel::HAL diff --git a/dev/ZKAKit/HALKit/ARM64/HalSchedulerCore.cc b/dev/ZKAKit/HALKit/ARM64/HalSchedulerCore.cc deleted file mode 100644 index 57475d8b..00000000 --- a/dev/ZKAKit/HALKit/ARM64/HalSchedulerCore.cc +++ /dev/null @@ -1,34 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include - -namespace Kernel -{ - /***********************************************************************************/ - /// @brief Unimplemented function (crashes by default) - /// @param void - /***********************************************************************************/ - - EXTERN_C Void __zka_pure_call(void) - { - UserProcessScheduler::The().GetCurrentProcess().Leak().Crash(); - } - - /***********************************************************************************/ - /// @brief Validate user stack. - /// @param stack_ptr the frame pointer. - /***********************************************************************************/ - - Bool hal_check_stack(HAL::StackFramePtr stack_ptr) - { - if (!stack_ptr) - return No; - - return stack_ptr->SP != 0 && stack_ptr->BP != 0; - } -} // namespace Kernel diff --git a/dev/ZKAKit/HALKit/ARM64/HalSchedulerCoreARM64.cc b/dev/ZKAKit/HALKit/ARM64/HalSchedulerCoreARM64.cc deleted file mode 100644 index 0536b5e8..00000000 --- a/dev/ZKAKit/HALKit/ARM64/HalSchedulerCoreARM64.cc +++ /dev/null @@ -1,40 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include - -namespace Kernel -{ - EXTERN_C Void __zka_pure_call(void) - { - UserProcessScheduler::The().GetCurrentProcess().Leak().Crash(); - } - - bool hal_check_stack(HAL::StackFramePtr stackPtr) - { - if (!stackPtr) - return No; - - if (stackPtr->BP == 0 || stackPtr->SP == 0) - return No; - - return Yes; - } - - /// @brief Wakes up thread. - /// Wakes up thread from the hang state. - Void mp_wakeup_thread(HAL::StackFrame* stack) - { - ZKA_UNUSED(stack); - } - - /// @brief makes the thread sleep on a loop. - /// hooks and hangs thread to prevent code from executing. - Void mp_hang_thread(HAL::StackFrame* stack) - { - ZKA_UNUSED(stack); - } -} // namespace Kernel diff --git a/dev/ZKAKit/HALKit/ARM64/HalTimerARM64.cc b/dev/ZKAKit/HALKit/ARM64/HalTimerARM64.cc deleted file mode 100644 index 5391fc0c..00000000 --- a/dev/ZKAKit/HALKit/ARM64/HalTimerARM64.cc +++ /dev/null @@ -1,14 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - - File: HalTimer.cc - Purpose: HAL timer - - Revision History: - - 07/07/24: Added file (amlel) - -------------------------------------------- */ - -#include diff --git a/dev/ZKAKit/HALKit/ARM64/MBCI/.keepme b/dev/ZKAKit/HALKit/ARM64/MBCI/.keepme deleted file mode 100644 index e69de29b..00000000 diff --git a/dev/ZKAKit/HALKit/ARM64/Paging.h b/dev/ZKAKit/HALKit/ARM64/Paging.h deleted file mode 100644 index 8456638c..00000000 --- a/dev/ZKAKit/HALKit/ARM64/Paging.h +++ /dev/null @@ -1,120 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -/** --------------------------------------------------- - - * THIS FILE CONTAINS CODE FOR ARMV8 PAGING. - -------------------------------------------------------- */ - -#include - -#ifndef kPageMax -#define kPageMax (0x200) -#endif //! kPageMax - -#ifndef kPageAlign -#define kPageAlign (0x1000) -#endif //! kPageAlign - -#ifndef kPageSize -#define kPageSize (0x1000) -#endif // !kPageSize - -//! short format address range - -#define c16KBPage 0b000 -#define c8KBPage 0b001 -#define c4KBPage 0b010 -#define c2KBPage 0b011 -#define c1KBPage 0b100 -#define c512BPage 0b101 -#define c256BPage 0b110 -#define c128BPage 0b111 - -/// Long format address range - -#define cPageMAll \ - { \ - 0b000, 0b000 \ - } -#define cPageMToMax(M) \ - { \ - M, 0b000 \ - } -#define cPageMaxToM(M) \ - { \ - 0b000, M \ - } -#define cPageMToN(M, N) \ - { \ - M, N \ - } - -namespace Kernel::HAL -{ - struct PACKED PTE_4KB final - { - UInt64 Valid : 1; - UInt64 Table : 1; - UInt64 AttrIndex : 3; - UInt64 NS : 1; - UInt64 AP : 2; - UInt64 SH : 2; - UInt64 AF : 1; - UInt64 NG : 1; - UInt64 Reserved1 : 1; - UInt64 Contiguous : 1; - UInt64 Dirty : 1; - UInt64 Reserved : 2; - UInt64 PhysicalAddress : 36; - UInt64 Reserved3 : 4; - UInt64 PXN : 1; - UInt64 XN : 1; - UInt64 Reserved4 : 9; - }; - - namespace Detail - { - enum class ControlRegisterBits - { - ProtectedModeEnable = 0, - MonitorCoProcessor = 1, - Emulation = 2, - TaskSwitched = 3, - ExtensionType = 4, - NumericError = 5, - WriteProtect = 16, - AlignementMask = 18, - NotWriteThrough = 29, - CacheDisable = 30, - PageEnable = 31, - }; - - inline UInt8 control_register_cast(ControlRegisterBits reg) - { - return static_cast(reg); - } - } // namespace Detail - - struct PDE_4KB final - { - PTE_4KB ALIGN(kPageAlign) fEntries[kPageMax]; - }; - - auto mm_alloc_bitmap(Boolean wr, Boolean user, SizeT size, Bool is_page) -> VoidPtr; - auto mm_free_bitmap(VoidPtr page_ptr) -> Bool; -} // namespace Kernel::HAL - -namespace Kernel -{ - typedef HAL::PTE_4KB PTE; - typedef HAL::PDE_4KB PDE; -} // namespace Kernel - -EXTERN_C void hal_flush_tlb(); diff --git a/dev/ZKAKit/HALKit/ARM64/Processor.h b/dev/ZKAKit/HALKit/ARM64/Processor.h deleted file mode 100644 index c6ae060d..00000000 --- a/dev/ZKAKit/HALKit/ARM64/Processor.h +++ /dev/null @@ -1,75 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include -#include -#include -#include - -#define kCPUBackendName "ARMv8" - -namespace Kernel::HAL -{ - struct PACKED Register64 final - { - UShort Limit; - UIntPtr Base; - }; - - /// @brief Memory Manager mapping flags. - enum - { - kMMFlagsPresent = 1 << 0, - kMMFlagsWr = 1 << 1, - kMMFlagsUser = 1 << 2, - kMMFlagsNX = 1 << 3, - kMMFlagsCount = 3, - }; - - /// @brief Set a PTE from pd_base. - /// @param virt_addr a valid virtual address. - /// @param phys_addr point to physical address. - /// @param flags the flags to put on the page. - /// @return Status code of page manip. - EXTERN_C Int32 mm_map_page(VoidPtr virt_addr, UInt32 flags); - - typedef UIntPtr Reg; - typedef Register64 Register; - - /// @note let's keep the same name as AMD64 HAL. - struct PACKED StackFrame final - { - Reg R8{0}; - Reg R9{0}; - Reg R10{0}; - Reg R11{0}; - Reg R12{0}; - Reg R13{0}; - Reg R14{0}; - Reg R15{0}; - Reg SP{0}; - Reg BP{0}; - }; - - typedef StackFrame* StackFramePtr; - - inline Void rt_halt() - { - while (Yes) - { - } - } - -} // namespace Kernel::HAL - -inline Kernel::VoidPtr kKernelBitMpStart = nullptr; -inline Kernel::UIntPtr kKernelBitMpSize = 0UL; - -inline Kernel::VoidPtr kKernelPhysicalStart = nullptr; - -#include diff --git a/dev/ZKAKit/HALKit/ARM64/ReadMe.md b/dev/ZKAKit/HALKit/ARM64/ReadMe.md deleted file mode 100644 index c51229f2..00000000 --- a/dev/ZKAKit/HALKit/ARM64/ReadMe.md +++ /dev/null @@ -1,3 +0,0 @@ -# ARM64 Hardware Abstraction Layer - -- Supported Firmware: CoreBoot/EDK/OpenMobileBoot diff --git a/dev/ZKAKit/HALKit/ARM64/Storage/.gitkeep b/dev/ZKAKit/HALKit/ARM64/Storage/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/dev/ZKAKit/HALKit/ARM64/Storage/HalFlash.cc b/dev/ZKAKit/HALKit/ARM64/Storage/HalFlash.cc deleted file mode 100644 index 9bd71b57..00000000 --- a/dev/ZKAKit/HALKit/ARM64/Storage/HalFlash.cc +++ /dev/null @@ -1,66 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include - -/// @file Flash.cc -/// @brief Flash memory builtin. - -#ifdef __USE_MBCI_FLASH__ - -#define kMaxFlash (4U) - -namespace Kernel -{ - /// /:/BRIDGE/FLSH/1 - constexpr auto kFlashBridgeMagic = "FLSH"; - constexpr auto kFlashBridgeRevision = 1; - - STATIC const Boolean kFlashEnabled = No; - STATIC SizeT kFlashSize[kMaxFlash] = {}; - STATIC SizeT kFlashSectorSz[kMaxFlash] = {}; - - /// @brief Enable flash memory builtin. - STATIC Void drv_enable_flash(Int32 slot); - - /// @brief Disable flash memory builtin. - STATIC Void drv_disable_flash(Int32 slot); - - /// @brief get sector count. - /// @return drive sector count. - SizeT drv_get_sector_count(Int32 slot) - { - if (slot > kMaxFlash) - return 0; - - return kFlashSectorSz[slot]; - } - - /// @brief get device size. - /// @return drive size - SizeT drv_get_size(Int32 slot) - { - if (slot > kMaxFlash) - return 0; - - return kFlashSize[slot]; - } - - /// @brief Enable flash memory at slot. - STATIC Void drv_enable_flash(Int32 arg) - { - kcout << "Enabled FLSH hardware.\r"; - } - - /// @brief Disable flash memory at slot. - STATIC Void drv_disable_flash(Int32 arg) - { - kcout << "Disabled FLSH hardware.\r"; - } -} // namespace Kernel - -#endif // if __USE_MBCI_FLASH__ (Bridge) diff --git a/dev/ZKAKit/HALKit/AXP/CR.s b/dev/ZKAKit/HALKit/AXP/CR.s deleted file mode 100644 index 4d68257d..00000000 --- a/dev/ZKAKit/HALKit/AXP/CR.s +++ /dev/null @@ -1,11 +0,0 @@ -.globl read_lr1 -.globl read_lr0 - -.section .text - read_lr0: - movq %r30, %cr3 - ret - - hal_read_cr0: - movq %r30, %cr0 - ret \ No newline at end of file diff --git a/dev/ZKAKit/HALKit/AXP/CoreInterruptHandlerDEC.cpp b/dev/ZKAKit/HALKit/AXP/CoreInterruptHandlerDEC.cpp deleted file mode 100644 index e69de29b..00000000 diff --git a/dev/ZKAKit/HALKit/AXP/CoreSyscallHandlerDEC.cpp b/dev/ZKAKit/HALKit/AXP/CoreSyscallHandlerDEC.cpp deleted file mode 100644 index 9d042635..00000000 --- a/dev/ZKAKit/HALKit/AXP/CoreSyscallHandlerDEC.cpp +++ /dev/null @@ -1,24 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include - -/// @brief Internal call for syscall, to work with C++. -/// @param stack -/// @return nothing. -EXTERN_C void rt_syscall_handle(Kernel::HAL::StackFrame* stack) -{ - if (stack->Rcx <= (kSyscalls.Count() - 1)) - { - kcout << "syscall: enter.\r"; - - if (kSyscalls[stack->Rcx].Leak().Leak().fHooked) - (kSyscalls[stack->Rcx].Leak().Leak().fProc)(stack); - - kcout << "syscall: exit.\r"; - } -} diff --git a/dev/ZKAKit/HALKit/AXP/HAL.s b/dev/ZKAKit/HALKit/AXP/HAL.s deleted file mode 100644 index 0178527f..00000000 --- a/dev/ZKAKit/HALKit/AXP/HAL.s +++ /dev/null @@ -1,13 +0,0 @@ -.globl rt_wait_400ns - -.section .text -rt_wait_400ns: - jmp .L -.L: - jmp .L2 - wtint ;; wait for interrupt -.L2: - - ret - - diff --git a/dev/ZKAKit/HALKit/AXP/Processor.h b/dev/ZKAKit/HALKit/AXP/Processor.h deleted file mode 100644 index 6d3e9337..00000000 --- a/dev/ZKAKit/HALKit/AXP/Processor.h +++ /dev/null @@ -1,7 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once diff --git a/dev/ZKAKit/HALKit/AXP/README b/dev/ZKAKit/HALKit/AXP/README deleted file mode 100644 index 91e7b134..00000000 --- a/dev/ZKAKit/HALKit/AXP/README +++ /dev/null @@ -1 +0,0 @@ -This is for DEC Alpha. diff --git a/dev/ZKAKit/HALKit/AXP/README.TXT b/dev/ZKAKit/HALKit/AXP/README.TXT deleted file mode 100644 index 11e138f9..00000000 --- a/dev/ZKAKit/HALKit/AXP/README.TXT +++ /dev/null @@ -1 +0,0 @@ -An toy HAL to test the Kernel portability. diff --git a/dev/ZKAKit/HALKit/AXP/SYSCALL.s b/dev/ZKAKit/HALKit/AXP/SYSCALL.s deleted file mode 100644 index 19cab808..00000000 --- a/dev/ZKAKit/HALKit/AXP/SYSCALL.s +++ /dev/null @@ -1,10 +0,0 @@ -.section .text -system_handle_user_call: - .cfi_startproc - - push %r0 - jmp %r1 - mov %r30, %r2 - - .cfi_endproc - retsys \ No newline at end of file diff --git a/dev/ZKAKit/HALKit/AXP/VM.s b/dev/ZKAKit/HALKit/AXP/VM.s deleted file mode 100644 index 7024086b..00000000 --- a/dev/ZKAKit/HALKit/AXP/VM.s +++ /dev/null @@ -1,5 +0,0 @@ -.global hal_flush_tlb - -.section .text -hal_flush_tlb: - swppal \ No newline at end of file diff --git a/dev/ZKAKit/HALKit/POWER/.gitkeep b/dev/ZKAKit/HALKit/POWER/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/dev/ZKAKit/HALKit/POWER/AP.h b/dev/ZKAKit/HALKit/POWER/AP.h deleted file mode 100644 index 8150a56d..00000000 --- a/dev/ZKAKit/HALKit/POWER/AP.h +++ /dev/null @@ -1,39 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - - File: AP.h - Purpose: POWER hardware threads. - - Revision History: - - 14/04/24: Added file (amlel) - -------------------------------------------- */ - -#pragma once - -#include - -namespace Kernel -{ - struct HAL_HARDWARE_THREAD; - - /// @brief hardware thread indentification type. - typedef Kernel::Int32 hal_ap_kind; - - /// @brief Hardware thread information structure. - typedef struct HAL_HARDWARE_THREAD - { - Kernel::UIntPtr fStartAddress; - Kernel::UInt8 fPrivleged : 1; - Kernel::UInt32 fPageMemoryFlags; - hal_ap_kind fIdentNumber; - } HAL_HARDWARE_THREAD; - - /// @brief Set PC to specific hart. - /// @param hart the hart - /// @param epc the pc. - /// @return - EXTERN_C Kernel::Void hal_set_pc_to_hart(HAL_HARDWARE_THREAD* hart, Kernel::VoidPtr epc); -} // namespace Kernel diff --git a/dev/ZKAKit/HALKit/POWER/APM/.gitkeep b/dev/ZKAKit/HALKit/POWER/APM/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/dev/ZKAKit/HALKit/POWER/HalAP.cc b/dev/ZKAKit/HALKit/POWER/HalAP.cc deleted file mode 100644 index 8939044c..00000000 --- a/dev/ZKAKit/HALKit/POWER/HalAP.cc +++ /dev/null @@ -1,40 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include -#include - -using namespace Kernel; - -namespace Kernel::Detail -{ - STATIC void mp_hang_fn(void) - { - while (YES) - ; - } -} // namespace Kernel::Detail - -/// @brief wakes up thread. -/// wakes up thread from hang. -void mp_wakeup_thread(HAL::StackFramePtr stack) -{ - if (!stack) - return; - - hal_set_pc_to_hart(reinterpret_cast(stack->R15), reinterpret_cast(stack->BP)); -} - -/// @brief makes thread sleep. -/// hooks and hangs thread to prevent code from executing. -void mp_hang_thread(HAL::StackFramePtr stack) -{ - if (!stack) - return; - - hal_set_pc_to_hart(reinterpret_cast(stack->R15), reinterpret_cast(Kernel::Detail::mp_hang_fn)); -} diff --git a/dev/ZKAKit/HALKit/POWER/HalDebugOutput.cc b/dev/ZKAKit/HALKit/POWER/HalDebugOutput.cc deleted file mode 100644 index 98a2a8f2..00000000 --- a/dev/ZKAKit/HALKit/POWER/HalDebugOutput.cc +++ /dev/null @@ -1,27 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include - -using namespace Kernel; - -/// @brief Writes to COM1. -/// @param bytes -void ke_io_write(const Char* bytes) -{ - if (!bytes) - return; - - SizeT index = 0; - SizeT len = rt_string_len(bytes, 255); - - while (index < len) - { - // TODO - ++index; - } -} diff --git a/dev/ZKAKit/HALKit/POWER/HalStartSequence.s b/dev/ZKAKit/HALKit/POWER/HalStartSequence.s deleted file mode 100644 index 1c4c7d21..00000000 --- a/dev/ZKAKit/HALKit/POWER/HalStartSequence.s +++ /dev/null @@ -1,14 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -.globl __ImageStart -.extern hal_init_platform -.align 4 -.text - -__ImageStart: - bl hal_init_platform - blr diff --git a/dev/ZKAKit/HALKit/POWER/HalThread.cc b/dev/ZKAKit/HALKit/POWER/HalThread.cc deleted file mode 100644 index efdf2b54..00000000 --- a/dev/ZKAKit/HALKit/POWER/HalThread.cc +++ /dev/null @@ -1,8 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include diff --git a/dev/ZKAKit/HALKit/POWER/HalVirtualMemory.cc b/dev/ZKAKit/HALKit/POWER/HalVirtualMemory.cc deleted file mode 100644 index c94370db..00000000 --- a/dev/ZKAKit/HALKit/POWER/HalVirtualMemory.cc +++ /dev/null @@ -1,49 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include -#include - -/// @note Refer to SoC documentation. - -using namespace Kernel; - -EXTERN_C Void hal_write_tlb(UInt32 mas0, UInt32 mas1, UInt32 mas2, UInt32 mas3, UInt32 mas7) -{ - hal_mtspr(MAS0, mas0); - hal_mtspr(MAS1, mas1); - hal_mtspr(MAS2, mas2); - hal_mtspr(MAS3, mas3); - hal_mtspr(MAS7, mas7); - - hal_flush_tlb(); -} - -EXTERN_C Bool hal_set_tlb(UInt8 tlb, UInt32 epn, UInt64 rpn, UInt8 perms, UInt8 wimge, UInt8 ts, UInt8 esel, UInt8 tsize, UInt8 iprot) -{ - if ((hal_mfspr(SPRN_MMUCFG) & MMUCFG_MAVN) == MMUCFG_MAVN_V1 && (tsize & 1)) - { - // this MMU does not allow odd tsize values - return false; - } - - UInt32 mas0 = FSL_BOOKE_MAS0(tlb, esel, 0); - UInt32 mas1 = FSL_BOOKE_MAS1(1, iprot, 0, ts, tsize); - UInt32 mas2 = FSL_BOOKE_MAS2(epn, wimge); - UInt32 mas3 = FSL_BOOKE_MAS3(rpn, 0, perms); - UInt32 mas7 = FSL_BOOKE_MAS7(rpn); - - hal_write_tlb(mas0, mas1, mas2, mas3, mas7); - - return true; -} - -/// @brief Flush TLB -EXTERN_C void hal_flush_tlb() -{ - asm volatile("isync;tlbwe;msync;isync"); -} diff --git a/dev/ZKAKit/HALKit/POWER/MBCI/.gitkeep b/dev/ZKAKit/HALKit/POWER/MBCI/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/dev/ZKAKit/HALKit/POWER/MBCI/HalMBCIHost.cc b/dev/ZKAKit/HALKit/POWER/MBCI/HalMBCIHost.cc deleted file mode 100644 index efdf2b54..00000000 --- a/dev/ZKAKit/HALKit/POWER/MBCI/HalMBCIHost.cc +++ /dev/null @@ -1,8 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include diff --git a/dev/ZKAKit/HALKit/POWER/Processor.h b/dev/ZKAKit/HALKit/POWER/Processor.h deleted file mode 100644 index d323daa6..00000000 --- a/dev/ZKAKit/HALKit/POWER/Processor.h +++ /dev/null @@ -1,62 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - - Purpose: POWER processor header. - -------------------------------------------- */ - -#pragma once - -#include -#include - -#define NoOp() asm volatile("mr 0, 0") -#define kHalPPCAlignment __attribute__((aligned(4))) - -namespace Kernel::HAL -{ - typedef UIntPtr Reg; - - /// @brief Stack frame (as retrieved from assembly.) - struct PACKED StackFrame final - { - Reg R8{0}; - Reg R9{0}; - Reg R10{0}; - Reg R11{0}; - Reg R12{0}; - Reg R13{0}; - Reg R14{0}; - Reg R15{0}; - Reg SP{0}; - Reg BP{0}; - }; - - typedef StackFrame* StackFramePtr; - - inline void rt_halt() - { - while (true) - { - NoOp(); // no oop. - } - } - - inline void rt_cli() - { - NoOp(); // no oop - } -} // namespace Kernel::HAL - -EXTERN_C Kernel::Void int_handle_math(Kernel::UIntPtr sp); -EXTERN_C Kernel::Void int_handle_pf(Kernel::UIntPtr sp); - -/// @brief Set TLB. -Kernel::Bool hal_set_tlb(Kernel::UInt8 tlb, Kernel::UInt32 epn, Kernel::UInt64 rpn, Kernel::UInt8 perms, Kernel::UInt8 wimge, Kernel::UInt8 ts, Kernel::UInt8 esel, Kernel::UInt8 tsize, Kernel::UInt8 iprot); - -/// @brief Write TLB. -Kernel::Void hal_write_tlb(Kernel::UInt32 mas0, Kernel::UInt32 mas1, Kernel::UInt32 mas2, Kernel::UInt32 mas3, Kernel::UInt32 mas7); - -/// @brief Flush TLB. -EXTERN_C Kernel::Void hal_flush_tlb(); diff --git a/dev/ZKAKit/HALKit/POWER/ReadMe.md b/dev/ZKAKit/HALKit/POWER/ReadMe.md deleted file mode 100644 index a9751581..00000000 --- a/dev/ZKAKit/HALKit/POWER/ReadMe.md +++ /dev/null @@ -1,4 +0,0 @@ -POWER Hardware Abstraction Layer - -- Supported CPU: POWER -- Supported Firmware: CoreBoot \ No newline at end of file diff --git a/dev/ZKAKit/HALKit/RISCV/.keep b/dev/ZKAKit/HALKit/RISCV/.keep deleted file mode 100644 index e69de29b..00000000 diff --git a/dev/ZKAKit/HALKit/RISCV/AP.h b/dev/ZKAKit/HALKit/RISCV/AP.h deleted file mode 100644 index 9b018526..00000000 --- a/dev/ZKAKit/HALKit/RISCV/AP.h +++ /dev/null @@ -1,36 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - - File: AP.h - Purpose: RISC-V hardware threads. - - Revision History: - - 30/01/24: Added file (amlel) - -------------------------------------------- */ - -#pragma once - -#include - -namespace Kernel -{ - typedef Int64 hal_ap_kind; - - typedef struct HAL_HARDWARE_THREAD - { - Kernel::UIntPtr fStartAddress; - Kernel::UInt8 fPrivleged : 1; - Kernel::UInt32 fPageMemoryFlags; - hal_ap_kind fIdentNumber; - } HAL_HARDWARE_THREAD; - - /// @brief Set PC to specific hart. - /// @param hart the hart - /// @param epc the pc. - /// @return - EXTERN_C Kernel::Void hal_set_pc_to_hart(HAL_HARDWARE_THREAD* hart, Kernel::VoidPtr epc); - -} // namespace Kernel diff --git a/dev/ZKAKit/HALKit/RISCV/APM/.gitkeep b/dev/ZKAKit/HALKit/RISCV/APM/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/dev/ZKAKit/HALKit/RISCV/HalAP.cc b/dev/ZKAKit/HALKit/RISCV/HalAP.cc deleted file mode 100644 index 70d66d94..00000000 --- a/dev/ZKAKit/HALKit/RISCV/HalAP.cc +++ /dev/null @@ -1,40 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include -#include - -using namespace Kernel; - -namespace Kernel::Detail -{ - STATIC void mp_hang_fn(void) - { - while (YES) - ; - } -} // namespace Kernel::Detail - -/// @brief wakes up thread. -/// wakes up thread from hang. -void mp_wakeup_thread(HAL::StackFramePtr stack) -{ - if (!stack) - return; - - hal_set_pc_to_hart(reinterpret_cast(stack->R15), reinterpret_cast(stack->BP)); -} - -/// @brief makes thread sleep. -/// hooks and hangs thread to prevent code from executing. -void mp_hang_thread(HAL::StackFramePtr stack) -{ - if (!stack) - return; - - hal_set_pc_to_hart(reinterpret_cast(stack->R15), reinterpret_cast(Kernel::Detail::mp_hang_fn)); -} diff --git a/dev/ZKAKit/HALKit/RISCV/ReadMe.md b/dev/ZKAKit/HALKit/RISCV/ReadMe.md deleted file mode 100644 index b099aa31..00000000 --- a/dev/ZKAKit/HALKit/RISCV/ReadMe.md +++ /dev/null @@ -1,4 +0,0 @@ -RISCV64 Hardware Abstraction Layer - -- Supported CPU: RISCV64 -- Supported Firmware: CoreBoot \ No newline at end of file diff --git a/dev/ZKAKit/HALKit/RISCV/Storage/.gitkeep b/dev/ZKAKit/HALKit/RISCV/Storage/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/dev/ZKAKit/HALKit/X86S/.gitkeep b/dev/ZKAKit/HALKit/X86S/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/dev/ZKAKit/HALKit/X86S/ACPI/.gitkeep b/dev/ZKAKit/HALKit/X86S/ACPI/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/dev/ZKAKit/HALKit/X86S/Storage/.gitkeep b/dev/ZKAKit/HALKit/X86S/Storage/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/dev/ZKAKit/KernelKit/CodeMgr.h b/dev/ZKAKit/KernelKit/CodeMgr.h deleted file mode 100644 index 1c157e93..00000000 --- a/dev/ZKAKit/KernelKit/CodeMgr.h +++ /dev/null @@ -1,37 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - - File: CodeMgr.hpp - Purpose: Code Mgr. - - Revision History: - - 30/01/24: Added file (amlel) - 3/8/24: Add UPP struct. - -------------------------------------------- */ - -#pragma once - -#include -#include -#include - -namespace Kernel -{ - /// @brief Main process entrypoint. - typedef void (*rtl_main_kind)(SizeT argc, char** argv, char** envp, SizeT envp_len); - - /// @brief C++ Constructor entrypoint. - typedef void(*rtl_ctor_kind)(void); - - /// @brief C++ Destructor entrypoint. - typedef void(*rtl_dtor_kind)(void); - - /// @brief Executes a new process from a function. Kernel code only. - /// @note This sets up a new stack, anything on the main function that calls the Kernel will not be accessible. - /// @param main the start of the process. - /// @return The team's process id. - ProcessID rtl_create_process(rtl_main_kind main, const Char* process_name) noexcept; -} // namespace Kernel diff --git a/dev/ZKAKit/KernelKit/DebugOutput.h b/dev/ZKAKit/KernelKit/DebugOutput.h deleted file mode 100644 index 42cd8748..00000000 --- a/dev/ZKAKit/KernelKit/DebugOutput.h +++ /dev/null @@ -1,198 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include -#include -#include -#include - -#define kDebugMaxPorts 56 - -#define kDebugUnboundPort 0x0FEED - -#define kDebugMag0 'Z' -#define kDebugMag1 'D' -#define kDebugMag2 'B' -#define kDebugMag3 'G' - -#define kDebugSourceFile 0 -#define kDebugLine 33 -#define kDebugTeam 43 -#define kDebugEOP 49 - -namespace Kernel -{ - class TerminalDevice; - class DTraceDevice; - - inline TerminalDevice end_line(); - inline TerminalDevice number(const Long& x); - inline TerminalDevice hex_number(const Long& x); - - // @brief Emulates a VT100 terminal. - class TerminalDevice final ZKA_DEVICE - { - public: - TerminalDevice(void (*print)(const Char*), void (*get)(const Char*)) - : IDeviceObject(print, get) - { - } - - ~TerminalDevice() override; - - /// @brief returns device name (terminal name) - /// @return string type (const Char*) - virtual const Char* Name() const override - { - return ("TerminalDevice"); - } - - ZKA_COPY_DEFAULT(TerminalDevice); - - STATIC TerminalDevice The() noexcept; - }; - - inline TerminalDevice end_line() - { - TerminalDevice selfTerm = TerminalDevice::The(); - - selfTerm.operator<<("\r"); - return selfTerm; - } - - inline TerminalDevice carriage_return() - { - TerminalDevice selfTerm = TerminalDevice::The(); - - selfTerm.operator<<("\r"); - return selfTerm; - } - - inline TerminalDevice tabulate() - { - TerminalDevice selfTerm = TerminalDevice::The(); - - selfTerm.operator<<("\t"); - return selfTerm; - } - - /// @brief emulate a terminal bell, like the VT100 does. - inline TerminalDevice bell() - { - TerminalDevice selfTerm = TerminalDevice::The(); - - selfTerm.operator<<("\a"); - return selfTerm; - } - - namespace Detail - { - inline TerminalDevice _write_number(const Long& x, TerminalDevice& term) - { - UInt64 y = (x > 0 ? x : -x) / 10; - UInt64 h = (x > 0 ? x : -x) % 10; - - if (y) - _write_number(y, term); - - /* fail if the number is not base-10 */ - if (h > 10) - { - _write_number('?', term); - return term; - } - - if (y < 0) - y = -y; - - const Char kNumbers[11] = "0123456789"; - - Char buf[2]; - buf[0] = kNumbers[h]; - buf[1] = 0; - - term.operator<<(buf); - return term; - } - - inline TerminalDevice _write_number_hex(const Long& x, TerminalDevice& term) - { - UInt64 y = (x > 0 ? x : -x) / 16; - UInt64 h = (x > 0 ? x : -x) % 16; - - if (y) - _write_number_hex(y, term); - - /* fail if the hex number is not base-16 */ - if (h > 16) - { - _write_number_hex('?', term); - return term; - } - - if (y < 0) - y = -y; - - const Char kNumbers[17] = "0123456789ABCDEF"; - - Char buf[2]; - buf[0] = kNumbers[h]; - buf[1] = 0; - - term.operator<<(buf); - return term; - } - } // namespace Detail - - inline TerminalDevice hex_number(const Long& x) - { - TerminalDevice selfTerm = TerminalDevice::The(); - - Detail::_write_number_hex(x, selfTerm); - selfTerm.operator<<("h"); - - return selfTerm; - } - - inline TerminalDevice number(const Long& x) - { - TerminalDevice selfTerm = TerminalDevice::The(); - - Detail::_write_number(x, selfTerm); - - return selfTerm; - } - - inline TerminalDevice get_console_in(Char* buf) - { - TerminalDevice selfTerm = TerminalDevice::The(); - - selfTerm >> buf; - - return selfTerm; - } - - typedef Char rt_debug_type[255]; - - class DebuggerPortHeader final - { - public: - Int16 fPort[kDebugMaxPorts]; - Int16 fBoundCnt; - }; -} // namespace Kernel - -#ifdef kcout -#undef kcout -#endif // ifdef kcout - -#define kcout \ - (Kernel::TerminalDevice::The() << "\e[0;31m [ " << __FILE__ << ": LINE: " << Kernel::number(__LINE__)); \ - (Kernel::TerminalDevice::The() << " ] \e[0m" \ - << ": ") -#define endl Kernel::TerminalDevice::The() << Kernel::end_line() diff --git a/dev/ZKAKit/KernelKit/Defines.h b/dev/ZKAKit/KernelKit/Defines.h deleted file mode 100644 index a4599d71..00000000 --- a/dev/ZKAKit/KernelKit/Defines.h +++ /dev/null @@ -1,15 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include - -#define KERNELKIT_VERSION "1.0.2" -#define KERNELKIT_VERSION_BCD 0x01020 - -class UserProcessScheduler; -class UserProcess; diff --git a/dev/ZKAKit/KernelKit/DeviceMgr.h b/dev/ZKAKit/KernelKit/DeviceMgr.h deleted file mode 100644 index 502e0604..00000000 --- a/dev/ZKAKit/KernelKit/DeviceMgr.h +++ /dev/null @@ -1,140 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -/* ------------------------------------------- - - Revision History: - - 31/01/24: Add kDeviceCnt (amlel) - 15/11/24: Add ZKA_DEVICE macro, to inherit from device object. - - ------------------------------------------- */ - -#pragma once - -/* @note Device Mgr. */ -/* @file KernelKit/DeviceMgr.h */ -/* @brief Device abstraction and I/O buffer. */ - -#include -#include - -#define kDeviceMgrRootDirPath "/Devices/" - -#define ZKA_DEVICE : public ::Kernel::IDeviceObject - -// Last Rev: Wed, Apr 3, 2024 9:09:41 AM - -namespace Kernel -{ - template - class IDeviceObject; - - /***********************************************************************************/ - /// @brief Device contract interface, represents an HW device. - /***********************************************************************************/ - template - class IDeviceObject - { - public: - explicit IDeviceObject(void (*Out)(T), void (*In)(T)) - : fOut(Out), fIn(In) - { - } - - virtual ~IDeviceObject() = default; - - public: - IDeviceObject& operator=(const IDeviceObject&) = default; - IDeviceObject(const IDeviceObject&) = default; - - public: - virtual IDeviceObject& operator<<(T Data) - { - fOut(Data); - return *this; - } - - virtual IDeviceObject& operator>>(T Data) - { - fIn(Data); - return *this; - } - - virtual const char* Name() const - { - return "IDeviceObject"; - } - - operator bool() - { - return fOut && fIn; - } - - Bool operator!() - { - return !fOut || !fIn; - } - - private: - Void (*fOut)(T Data) = {nullptr}; - Void (*fIn)(T Data) = {nullptr}; - }; - - /// - /// @brief Input Output abstract class. - /// Used mainly to communicate between OS to hardware. - /// - template - class IOBuf final - { - public: - explicit IOBuf(T dma_addr) - : fData(dma_addr) - { - // At least pass something valid when instancating this struct. - MUST_PASS(fData); - } - - IOBuf& operator=(const IOBuf&) = default; - IOBuf(const IOBuf&) = default; - - ~IOBuf() = default; - - public: - template - R operator->() const - { - return fData; - } - - template - R& operator[](Size index) const - { - return fData[index]; - } - - private: - T fData; - }; - - ///! @brief Device enum types. - enum - { - kDeviceTypeIDE, - kDeviceTypeEthernet, - kDeviceTypeWiFi, - kDeviceTypeFW, - kDeviceTypeBT, - kDeviceTypeRS232, - kDeviceTypeSCSI, - kDeviceTypeAHCI, - kDeviceTypeMBCI, - kDeviceTypeUSB, - kDeviceTypeMediaCtrl, // MM controller - kDeviceTypeCount, - }; -} // namespace Kernel diff --git a/dev/ZKAKit/KernelKit/DriveMgr.h b/dev/ZKAKit/KernelKit/DriveMgr.h deleted file mode 100644 index 811baeeb..00000000 --- a/dev/ZKAKit/KernelKit/DriveMgr.h +++ /dev/null @@ -1,169 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#ifndef INC_DRIVE_MANAGER_H -#define INC_DRIVE_MANAGER_H - -#include -#include -#include -#include -#include -#include -#include -#include - -#define kDriveMaxCount (4U) -#define kDriveSectorSz (512U) -#define kDriveInvalidID (-1) -#define kDriveNameLen (32) - -#define drv_sector_cnt(SIZE, SECTOR_SZ) (((SIZE) + (SECTOR_SZ)) / (SECTOR_SZ)) - -namespace Kernel -{ - enum - { - kInvalidDisc = -1, - - /// Storage types, combine with flags. - kBlockDevice = 0xAD, - kMassStorageDisc = 0xDA, - kFloppyDisc = 0xCD, - kOpticalDisc = 0xDC, // CD-ROM/DVD-ROM/Blu-Ray - kTapeDisc = 0xD7, - - /// Storage flags, combine with types. - kReadOnlyDrive = 0x10, // Read only drive - kEPMDrive = 0x11, // Explicit Partition Map. - kEPTDrive = 0x12, // ESP w/ EPM partition. - kMBRDrive = 0x13, // PC classic partition scheme - kGPTDrive = 0x14, // PC new partition scheme - kUnformattedDrive = 0x15, - kStorageCount = 9, - }; - - /// @brief Media drive trait type. - struct DriveTrait final - { - Char fName[kDriveNameLen]; // /System, /Boot, //./Devices/USB... - Int32 fKind; // fMassStorage, fFloppy, fOpticalDisc. - Int32 fFlags; // fReadOnly, fXPMDrive, fXPTDrive - - /// @brief Packet drive (StorageKit compilant.) - struct DrivePacket final - { - VoidPtr fPacketContent{nullptr}; //! packet body. - Char fPacketMime[kDriveNameLen] = "*/*"; //! identify what we're sending. - SizeT fPacketSize{0UL}; //! packet size - UInt32 fPacketCRC32{0UL}; //! sanity crc, in case if good is set to false - Boolean fPacketGood{YES}; - Lba fPacketLba{0UL}; - Boolean fPacketReadOnly{NO}; - } fPacket; - - Void (*fInput)(DrivePacket* packet_ptr); - Void (*fOutput)(DrivePacket* packet_ptr); - Void (*fVerify)(DrivePacket* packet_ptr); - Void (*fInit)(DrivePacket* packet_ptr); - const Char* (*fDriveKind)(Void); - }; - - ///! drive as a device. - typedef DriveTrait* DriveTraitPtr; - - /** - * @brief Mounted drives interface. - * @note This class has all of it's drive set to nullptr, allocate them using - * GetAddressOf(index). - */ - class MountpointInterface final - { - public: - explicit MountpointInterface() = default; - ~MountpointInterface() = default; - - ZKA_COPY_DEFAULT(MountpointInterface); - - public: - DriveTrait& A() - { - return mA; - } - - DriveTrait& B() - { - return mB; - } - - DriveTrait& C() - { - return mC; - } - - DriveTrait& D() - { - return mD; - } - - enum - { - kDriveIndexA = 0, - kDriveIndexB, - kDriveIndexC, - kDriveIndexD, - kDriveIndexInvalid, - }; - - DriveTraitPtr GetAddressOf(const Int32& index) - { - err_local_get() = kErrorSuccess; - - switch (index) - { - case kDriveIndexA: - return &mA; - case kDriveIndexB: - return &mB; - case kDriveIndexC: - return &mC; - case kDriveIndexD: - return &mD; - default: { - err_local_get() = kErrorNoSuchDisk; - kcout << "No such disk index.\n"; - - break; - } - } - - return nullptr; - } - - private: - DriveTrait mA, mB, mC, mD; - }; - - /// @brief Unimplemented drive. - /// @param pckt the packet to read. - /// @return - Void io_drv_unimplemented(DriveTrait::DrivePacket* pckt); - - /// @brief Gets the drive kind (ATA, SCSI, AHCI...) - /// @param void none. - /// @return the drive kind (ATA, Flash, NVM) - const Char* io_drv_kind(Void); - - /// @brief Makes a new drive. - /// @return the new drive as a trait. - DriveTrait io_construct_blank_drive(Void) noexcept; - - /// @brief Fetches the main drive. - /// @return the new drive as a trait. - DriveTrait io_construct_main_drive(Void) noexcept; -} // namespace Kernel - -#endif /* ifndef INC_DRIVE_MANAGER_H */ diff --git a/dev/ZKAKit/KernelKit/FileMgr.h b/dev/ZKAKit/KernelKit/FileMgr.h deleted file mode 100644 index ac94d86b..00000000 --- a/dev/ZKAKit/KernelKit/FileMgr.h +++ /dev/null @@ -1,427 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - - File: FileMgr.h - Purpose: Kernel file manager. - -------------------------------------------- */ - -/* ------------------------------------------- - - Revision History: - - 31/01/24: Update documentation (amlel) - 05/07/24: NeFS support, and fork support, updated constants and specs - as well. - - ------------------------------------------- */ - -#ifndef INC_FILEMGR_H -#define INC_FILEMGR_H - -#ifdef __FSKIT_INCLUDES_NEFS__ -#include -#endif // __FSKIT_INCLUDES_NEFS__ - -#ifdef __FSKIT_INCLUDES_HPFS__ -#include -#endif // __FSKIT_INCLUDES_HPFS__ - -#include -#include -#include -#include -#include -#include -#include -#include - -/// @brief Filesystem manager, abstraction over mounted filesystem. -/// Works like the VFS or IFS. - -#define kRestrictR "r" -#define kRestrictRB "rb" -#define kRestrictW "w" -#define kRestrictWB "rw" -#define kRestrictRWB "rwb" - -#define kRestrictMax (5U) - -#define node_cast(PTR) reinterpret_cast(PTR) - -/** - @note Refer to first enum. -*/ -#define kFileOpsCount (4U) -#define kFileMimeGeneric "n-application-kind/all" - -/** @brief invalid position. (n-pos) */ -#define kNPos (SizeT)(-1); - -namespace Kernel -{ - enum - { - kFileWriteAll = 100, - kFileReadAll = 101, - kFileReadChunk = 102, - kFileWriteChunk = 103, - kFileIOCnt = (kFileWriteChunk - kFileWriteAll) + 1, - // file flags - kFileFlagRsrc = 104, - kFileFlagData = 105, - }; - - typedef VoidPtr NodePtr; - - /** - @brief Filesystem Mgr Interface class - @brief Used to provide common I/O for a specific filesystem. -*/ - class IFilesystemMgr - { - public: - explicit IFilesystemMgr() = default; - virtual ~IFilesystemMgr() = default; - - public: - ZKA_COPY_DEFAULT(IFilesystemMgr); - - public: - /// @brief Mounts a new filesystem into an active state. - /// @param interface the filesystem interface - /// @return - static bool Mount(IFilesystemMgr* interface); - - /// @brief Unmounts the active filesystem - /// @return - static IFilesystemMgr* Unmount(); - - /// @brief Getter, gets the active filesystem. - /// @return - static IFilesystemMgr* GetMounted(); - - public: - virtual NodePtr Create(_Input const Char* path) = 0; - virtual NodePtr CreateAlias(_Input const Char* path) = 0; - virtual NodePtr CreateDirectory(_Input const Char* path) = 0; - virtual NodePtr CreateSwapFile(const Char* path) = 0; - - public: - virtual bool Remove(_Input const Char* path) = 0; - - public: - virtual NodePtr Open(_Input const Char* path, _Input const Char* r) = 0; - - public: - virtual Void Write(_Input NodePtr node, _Input VoidPtr data, _Input Int32 flags, _Input SizeT size) = 0; - - virtual _Output VoidPtr Read(_Input NodePtr node, - _Input Int32 flags, - _Input SizeT sz) = 0; - - virtual Void Write(_Input const Char* name, - _Input NodePtr node, - _Input VoidPtr data, - _Input Int32 flags, - _Input SizeT size) = 0; - - virtual _Output VoidPtr Read(_Input const Char* name, - _Input NodePtr node, - _Input Int32 flags, - _Input SizeT sz) = 0; - - public: - virtual bool Seek(_Input NodePtr node, _Input SizeT off) = 0; - - public: - virtual SizeT Tell(_Input NodePtr node) = 0; - virtual bool Rewind(_Input NodePtr node) = 0; - }; - -#ifdef __FSKIT_INCLUDES_NEFS__ - /** - * @brief Based of IFilesystemMgr, takes care of managing NeFS - * disks. - */ - class NeFileSystemMgr final : public IFilesystemMgr - { - public: - explicit NeFileSystemMgr(); - ~NeFileSystemMgr() override; - - public: - ZKA_COPY_DEFAULT(NeFileSystemMgr); - - public: - NodePtr Create(const Char* path) override; - NodePtr CreateAlias(const Char* path) override; - NodePtr CreateDirectory(const Char* path) override; - NodePtr CreateSwapFile(const Char* path) override; - - public: - bool Remove(_Input const Char* path) override; - NodePtr Open(_Input const Char* path, _Input const Char* r) override; - Void Write(_Input NodePtr node, _Input VoidPtr data, _Input Int32 flags, _Input SizeT sz) override; - VoidPtr Read(_Input NodePtr node, _Input Int32 flags, _Input SizeT sz) override; - bool Seek(_Input NodePtr node, _Input SizeT off) override; - SizeT Tell(_Input NodePtr node) override; - bool Rewind(_Input NodePtr node) override; - - Void Write(_Input const Char* name, - _Input NodePtr node, - _Input VoidPtr data, - _Input Int32 flags, - _Input SizeT size) override; - - _Output VoidPtr Read(_Input const Char* name, - _Input NodePtr node, - _Input Int32 flags, - _Input SizeT sz) override; - - public: - /// @brief Get NeFS parser class. - /// @return The filesystem parser class. - NeFileSystemParser* GetParser() noexcept; - - private: - NeFileSystemParser* fImpl{nullptr}; - }; - -#endif // ifdef __FSKIT_INCLUDES_NEFS__ - - /** - * Usable FileStream - * @tparam Encoding file encoding (char, wchar_t...) - * @tparam FSClass Filesystem contract who takes care of it. - */ - template - class FileStream final - { - public: - explicit FileStream(const Encoding* path, const Encoding* restrict_type); - ~FileStream(); - - public: - FileStream& operator=(const FileStream&); - FileStream(const FileStream&); - - public: - ErrorOr WriteAll(const VoidPtr data) noexcept - { - if (this->fFileRestrict != kFileMgrRestrictReadWrite && - this->fFileRestrict != kFileMgrRestrictReadWriteBinary && - this->fFileRestrict != kFileMgrRestrictWrite && - this->fFileRestrict != kFileMgrRestrictWriteBinary) - return ErrorOr(kErrorInvalidData); - - if (data == nullptr) - return ErrorOr(kErrorInvalidData); - - auto man = FSClass::GetMounted(); - - if (man) - { - man->Write(fFile, data, kFileWriteAll); - return ErrorOr(0); - } - - return ErrorOr(kErrorInvalidData); - } - - VoidPtr ReadAll() noexcept - { - if (this->fFileRestrict != kFileMgrRestrictReadWrite && - this->fFileRestrict != kFileMgrRestrictReadWriteBinary && - this->fFileRestrict != kFileMgrRestrictRead && - this->fFileRestrict != kFileMgrRestrictReadBinary) - return nullptr; - - auto man = FSClass::GetMounted(); - - if (man) - { - VoidPtr ret = man->Read(fFile, kFileReadAll, 0); - return ret; - } - - return nullptr; - } - - ErrorOr WriteAll(const Char* fName, const VoidPtr data) noexcept - { - if (this->fFileRestrict != kFileMgrRestrictReadWrite && - this->fFileRestrict != kFileMgrRestrictReadWriteBinary && - this->fFileRestrict != kFileMgrRestrictWrite && - this->fFileRestrict != kFileMgrRestrictWriteBinary) - return ErrorOr(kErrorInvalidData); - - if (data == nullptr) - return ErrorOr(kErrorInvalidData); - - auto man = FSClass::GetMounted(); - - if (man) - { - man->Write(fName, fFile, data, kFileWriteAll); - return ErrorOr(0); - } - - return ErrorOr(kErrorInvalidData); - } - - VoidPtr Read(const Char* fName) noexcept - { - if (this->fFileRestrict != kFileMgrRestrictReadWrite && - this->fFileRestrict != kFileMgrRestrictReadWriteBinary && - this->fFileRestrict != kFileMgrRestrictRead && - this->fFileRestrict != kFileMgrRestrictReadBinary) - return nullptr; - - auto man = FSClass::GetMounted(); - - if (man) - { - VoidPtr ret = man->Read(fName, fFile, kFileReadAll, 0); - return ret; - } - - return nullptr; - } - - VoidPtr Read(SizeT offset, SizeT sz) - { - if (this->fFileRestrict != kFileMgrRestrictReadWrite && - this->fFileRestrict != kFileMgrRestrictReadWriteBinary && - this->fFileRestrict != kFileMgrRestrictRead && - this->fFileRestrict != kFileMgrRestrictReadBinary) - return nullptr; - - auto man = FSClass::GetMounted(); - - if (man) - { - man->Seek(fFile, offset); - auto ret = man->Read(fFile, kFileReadChunk, sz); - - return ret; - } - - return nullptr; - } - - Void Write(SizeT offset, voidPtr data, SizeT sz) - { - if (this->fFileRestrict != kFileMgrRestrictReadWrite && - this->fFileRestrict != kFileMgrRestrictReadWriteBinary && - this->fFileRestrict != kFileMgrRestrictWrite && - this->fFileRestrict != kFileMgrRestrictWriteBinary) - return; - - auto man = FSClass::GetMounted(); - - if (man) - { - man->Seek(fFile, offset); - man->Write(fFile, data, sz, kFileReadChunk); - } - } - - public: - /// @brief Leak node pointer. - /// @return The node pointer. - NodePtr Leak() - { - return fFile; - } - - /// @brief Leak MIME. - /// @return The MIME. - Char* MIME() noexcept - { - return const_cast(fMime); - } - - enum - { - kFileMgrRestrictRead, - kFileMgrRestrictReadBinary, - kFileMgrRestrictWrite, - kFileMgrRestrictWriteBinary, - kFileMgrRestrictReadWrite, - kFileMgrRestrictReadWriteBinary, - }; - - private: - NodePtr fFile{nullptr}; - Int32 fFileRestrict{kFileMgrRestrictReadBinary}; - const Char* fMime{kFileMimeGeneric}; - }; - - using FileStreamUTF8 = FileStream; - using FileStreamUTF16 = FileStream; - - typedef UInt64 CursorType; - - inline static const auto kRestrictStrLen = 8U; - - /// @brief restrict information about the file descriptor. - struct FileRestrictKind final - { - Char fRestrict[kRestrictStrLen]; - Int32 fMappedTo; - }; - - /// @brief constructor - template - inline FileStream::FileStream(const Encoding* path, - const Encoding* restrict_type) - : fFile(Class::GetMounted()->Open(path, restrict_type)) - { - const SizeT kRestrictCount = kRestrictMax; - const FileRestrictKind kRestrictList[] = { - { - .fRestrict = kRestrictR, - .fMappedTo = kFileMgrRestrictRead, - }, - { - .fRestrict = kRestrictRB, - .fMappedTo = kFileMgrRestrictReadBinary, - }, - { - .fRestrict = kRestrictRWB, - .fMappedTo = kFileMgrRestrictReadWriteBinary, - }, - { - .fRestrict = kRestrictW, - .fMappedTo = kFileMgrRestrictWrite, - }, - { - .fRestrict = kRestrictWB, - .fMappedTo = kFileMgrRestrictReadWrite, - }}; - - for (SizeT index = 0; index < kRestrictCount; ++index) - { - if (rt_string_cmp(restrict_type, kRestrictList[index].fRestrict, - rt_string_len(kRestrictList[index].fRestrict)) == 0) - { - fFileRestrict = kRestrictList[index].fMappedTo; - break; - } - } - - kcout << "new file: " << path << ".\r"; - } - - /// @brief destructor of the file stream. - template - inline FileStream::~FileStream() - { - mm_delete_heap(fFile); - } -} // namespace Kernel - -#endif // ifndef INC_FILEMGR_H diff --git a/dev/ZKAKit/KernelKit/HardwareThreadScheduler.h b/dev/ZKAKit/KernelKit/HardwareThreadScheduler.h deleted file mode 100644 index 8b6c2a90..00000000 --- a/dev/ZKAKit/KernelKit/HardwareThreadScheduler.h +++ /dev/null @@ -1,149 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#ifndef __INC_MP_MANAGER_H__ -#define __INC_MP_MANAGER_H__ - -#include -#include -#include - -/// @note Last Rev Sun 28 Jul CET 2024 -/// @note Last Rev Thu, Aug 1, 2024 9:07:38 AM - -#define kMaxAPInsideSched (8U) - -namespace Kernel -{ - class HardwareThread; - class HardwareThreadScheduler; - - using ThreadID = UInt32; - - enum ThreadKind - { - kAPSystemReserved, // System reserved thread, well user can't use it - kAPStandard, // user thread, cannot be used by Kernel - kAPFallback, // fallback thread, cannot be used by user if not clear or - // used by Kernel. - kAPBoot, // The core we booted from, the mama. - kInvalidAP, - kAPCount, - }; - - typedef enum ThreadKind ThreadKind; - typedef ThreadID ThreadID; - - /***********************************************************************************/ - /// - /// \name HardwareThread - /// \brief Abstraction over the CPU's core, used to run processes or threads. - /// - /***********************************************************************************/ - - class HardwareThread final - { - public: - explicit HardwareThread(); - ~HardwareThread(); - - public: - ZKA_COPY_DEFAULT(HardwareThread) - - public: - operator bool(); - - public: - void Wake(const bool wakeup = false) noexcept; - void Busy(const bool busy = false) noexcept; - - public: - bool Switch(VoidPtr image, Ptr8 stack_ptr, HAL::StackFramePtr frame, const ProcessID& pid); - bool IsWakeup() noexcept; - - public: - HAL::StackFramePtr StackFrame() noexcept; - const ThreadKind& Kind() noexcept; - bool IsBusy() noexcept; - const ThreadID& ID() noexcept; - - private: - HAL::StackFramePtr fStack{nullptr}; - ThreadKind fKind{ThreadKind::kAPStandard}; - ThreadID fID{0}; - ProcessID fSourcePID{-1}; - Bool fWakeup{false}; - Bool fBusy{false}; - UInt64 fPTime{0}; - - private: - friend class HardwareThreadScheduler; - friend class UserProcessHelper; - }; - - /// - /// \name HardwareThreadScheduler - /// \brief Class to manage the thread scheduling. - /// - - class HardwareThreadScheduler final : public ISchedulable - { - private: - friend class UserProcessHelper; - - public: - explicit HardwareThreadScheduler(); - ~HardwareThreadScheduler(); - ZKA_COPY_DEFAULT(HardwareThreadScheduler); - - public: - HAL::StackFramePtr Leak() noexcept; - - public: - Ref operator[](const SizeT& idx); - bool operator!() noexcept; - operator bool() noexcept; - - const Bool IsUser() override - { - return Yes; - } - - const Bool IsKernel() override - { - return No; - } - - const Bool HasMP() override - { - return kHandoverHeader->f_HardwareTables.f_MultiProcessingEnabled; - } - - public: - /// @brief Shared instance of the MP Mgr. - /// @return the reference to the mp manager class. - STATIC HardwareThreadScheduler& The(); - - public: - /// @brief Returns the amount of threads present in the system. - /// @returns SizeT the amount of cores present. - SizeT Capacity() noexcept; - - private: - Array fThreadList; - ThreadID fCurrentThread{0}; - }; - - /// @brief wakes up thread. - /// wakes up thread from hang. - Void mp_wakeup_thread(HAL::StackFramePtr stack); - - /// @brief makes thread sleep. - /// hooks and hangs thread to prevent code from executing. - Void mp_hang_thread(HAL::StackFramePtr stack); -} // namespace Kernel - -#endif // !__INC_MP_MANAGER_H__ diff --git a/dev/ZKAKit/KernelKit/Heap.h b/dev/ZKAKit/KernelKit/Heap.h deleted file mode 100644 index 6c7e04bd..00000000 --- a/dev/ZKAKit/KernelKit/Heap.h +++ /dev/null @@ -1,86 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#ifndef INC_KERNEL_HEAP_H -#define INC_KERNEL_HEAP_H - -// last-rev 30/01/24 -// file: Heap.h -// description: heap allocation support. - -#include -#include -#include - -namespace Kernel -{ - /// @brief Declare pointer as free. - /// @param heap_ptr the pointer. - /// @return a status code regarding the deallocation. - Int32 mm_delete_heap(VoidPtr heap_ptr); - - /// @brief Declare a new size for heap_ptr. - /// @param heap_ptr the pointer. - /// @return unsupported always returns nullptr. - VoidPtr mm_realloc_heap(VoidPtr heap_ptr, SizeT new_sz); - - /// @brief Check if pointer is a valid Kernel pointer. - /// @param heap_ptr the pointer - /// @return if it exists it returns true. - Boolean mm_is_valid_heap(VoidPtr heap_ptr); - - /// @brief Allocate chunk of memory. - /// @param sz Size of pointer - /// @param wr Read Write bit. - /// @param user User enable bit. - /// @return The newly allocated pointer, or nullptr. - VoidPtr mm_new_heap(const SizeT sz, const Bool wr, const Bool user); - - /// @brief Protect the heap with a CRC value. - /// @param heap_ptr pointer. - /// @return if it valid: point has crc now., otherwise fail. - Boolean mm_protect_heap(VoidPtr heap_ptr); - - /// @brief Makes a Kernel page. - /// @param heap_ptr the page pointer. - /// @return status code - Int32 mm_make_page(VoidPtr heap_ptr); - - /// @brief Overwrites and set the flags of a heap header. - /// @param heap_ptr the pointer to update. - /// @param flags the flags to set. - Int32 mm_make_flags(VoidPtr heap_ptr, UInt64 flags); - - /// @brief Gets the flags of a heap header. - /// @param heap_ptr the pointer to get. - UInt64 mm_get_flags(VoidPtr heap_ptr); - - /// @brief Allocate C++ class. - /// @param cls The class to allocate. - /// @param args The args to pass. - template - inline Void mm_new_class(_Input _Output T** cls, _Input Args&&... args) - { - if (*cls) - { - err_global_get() = Kernel::kErrorInvalidData; - return; - } - - *cls = new T(move(args)...); - } - - /// @brief Delete and nullify C++ class. - /// @param cls The class to delete. - template - inline Void mm_delete_class(_Input _Output T** cls) - { - delete *cls; - *cls = nullptr; - } -} // namespace Kernel - -#endif // !INC_KERNEL_HEAP_H diff --git a/dev/ZKAKit/KernelKit/IDLLObject.h b/dev/ZKAKit/KernelKit/IDLLObject.h deleted file mode 100644 index b2ca53b8..00000000 --- a/dev/ZKAKit/KernelKit/IDLLObject.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * ======================================================== - * - * Kernel - * Copyright (C) 2024, Theater Quality Inc, all rights reserved., all rights reserved. - * - * ======================================================== - */ - -#pragma once - -#include -#include - -#define ZKA_DLL_OBJECT : public IDLLObject - -namespace Kernel -{ - /// @brief DLL class object. A handle to a shared library. - class IDLLObject - { - public: - explicit IDLLObject() = default; - virtual ~IDLLObject() = default; - - struct DLL_TRAITS final - { - VoidPtr ImageObject{nullptr}; - VoidPtr ImageEntrypointOffset{nullptr}; - - Bool IsValid() - { - return ImageObject && ImageEntrypointOffset; - } - }; - - ZKA_COPY_DEFAULT(IDLLObject); - - virtual DLL_TRAITS** GetAddressOf() = 0; - virtual DLL_TRAITS* Get() = 0; - - virtual Void Mount(DLL_TRAITS* to_mount) = 0; - virtual Void Unmount() = 0; - }; - - /// @brief Pure implementation, missing method/function handler. - EXTERN_C void __zka_pure_call(void); -} // namespace Kernel diff --git a/dev/ZKAKit/KernelKit/IPEFDLLObject.h b/dev/ZKAKit/KernelKit/IPEFDLLObject.h deleted file mode 100644 index f82cb0e5..00000000 --- a/dev/ZKAKit/KernelKit/IPEFDLLObject.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * ======================================================== - * - * Kernel - * Copyright (C) 2024, Theater Quality Inc, all rights reserved., all rights reserved. - * - * ======================================================== - */ - -#ifndef __KERNELKIT_SHARED_OBJECT_H__ -#define __KERNELKIT_SHARED_OBJECT_H__ - -#include -#include -#include -#include -#include - -namespace Kernel -{ - /** - * @brief Shared Library class - * Load library from this class - */ - class IPEFDLLObject final ZKA_DLL_OBJECT - { - public: - explicit IPEFDLLObject() = default; - ~IPEFDLLObject() = default; - - public: - ZKA_COPY_DEFAULT(IPEFDLLObject); - - private: - DLL_TRAITS* fMounted{nullptr}; - - public: - DLL_TRAITS** GetAddressOf() - { - return &fMounted; - } - - DLL_TRAITS* Get() - { - return fMounted; - } - - public: - void Mount(DLL_TRAITS* to_mount) - { - if (!to_mount || !to_mount->ImageObject) - return; - - fMounted = to_mount; - - if (fLoader && to_mount) - { - delete fLoader; - fLoader = nullptr; - } - - if (!fLoader) - { - fLoader = new PEFLoader(fMounted->ImageObject); - } - } - - void Unmount() - { - if (fMounted) - fMounted = nullptr; - }; - - template - SymbolType Load(const Char* symbol_name, SizeT len, Int32 kind) - { - if (symbol_name == nullptr || *symbol_name == 0) - return nullptr; - if (len > kPathLen || len < 1) - return nullptr; - - auto ret = - reinterpret_cast(fLoader->FindSymbol(symbol_name, kind)); - - if (!ret) - { - if (kind == kPefCode) - return (VoidPtr)&__zka_pure_call; - - return nullptr; - } - - return ret; - } - - private: - PEFLoader* fLoader{nullptr}; - }; - - typedef IPEFDLLObject* IDLL; - - EXTERN_C IDLL rtl_init_dylib(UserProcess* header); - EXTERN_C Void rtl_fini_dylib(UserProcess* header, IDLL lib, Bool* successful); -} // namespace Kernel - -#endif /* ifndef __KERNELKIT_SHARED_OBJECT_H__ */ diff --git a/dev/ZKAKit/KernelKit/LPC.h b/dev/ZKAKit/KernelKit/LPC.h deleted file mode 100644 index 8010420b..00000000 --- a/dev/ZKAKit/KernelKit/LPC.h +++ /dev/null @@ -1,69 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include - -/// @file LPC.h -/// @brief Local Process Codes. - -#define err_local_ok() (Kernel::UserProcessScheduler::The().GetCurrentProcess().Leak().GetLocalCode() == Kernel::kErrorSuccess) -#define err_local_fail() (Kernel::UserProcessScheduler::The().GetCurrentProcess().Leak().GetLocalCode() != Kernel::kErrorSuccess) -#define err_local_get() (Kernel::UserProcessScheduler::The().GetCurrentProcess().Leak().GetLocalCode()) - -#define err_global_ok() (Kernel::kErrorLocalNumber == Kernel::kErrorSuccess) -#define err_global_fail() (Kernel::kErrorLocalNumber != Kernel::kErrorSuccess) -#define err_global_get() (Kernel::kErrorLocalNumber) - -namespace Kernel -{ - typedef Int32 HError; - - inline HError kErrorLocalNumber = 0UL; - - inline constexpr HError kErrorSuccess = 0; - inline constexpr HError kErrorExecutable = 33; - inline constexpr HError kErrorExecutableLib = 34; - inline constexpr HError kErrorFileNotFound = 35; - inline constexpr HError kErrorDirectoryNotFound = 36; - inline constexpr HError kErrorDiskReadOnly = 37; - inline constexpr HError kErrorDiskIsFull = 38; - inline constexpr HError kErrorProcessFault = 39; - inline constexpr HError kErrorSocketHangUp = 40; - inline constexpr HError kErrorThreadLocalStorage = 41; - inline constexpr HError kErrorMath = 42; - inline constexpr HError kErrorNoNetwork = 43; - inline constexpr HError kErrorHeapOutOfMemory = 44; - inline constexpr HError kErrorNoSuchDisk = 45; - inline constexpr HError kErrorFileExists = 46; - inline constexpr HError kErrorFormatFailed = 47; - inline constexpr HError kErrorNetworkTimeout = 48; - inline constexpr HError kErrorInternal = 49; - inline constexpr HError kErrorForkAlreadyExists = 50; - inline constexpr HError kErrorOutOfTeamSlot = 51; - inline constexpr HError kErrorHeapNotPresent = 52; - inline constexpr HError kErrorNoEntrypoint = 53; - inline constexpr HError kErrorDiskIsCorrupted = 54; - inline constexpr HError kErrorDisk = 55; - inline constexpr HError kErrorInvalidData = 56; - inline constexpr HError kErrorAsync = 57; - inline constexpr HError kErrorNonBlocking = 58; - inline constexpr HError kErrorIPC = 59; - inline constexpr HError kErrorSign = 60; - inline constexpr HError kErrorInvalidCreds = 61; - inline constexpr HError kErrorCDTrayBroken = 62; - inline constexpr HError kErrorUnrecoverableDisk = 63; - inline constexpr HError kErrorUnimplemented = 0; - - /// @brief Raises a bug check stop code. - Void err_bug_check_raise(Void) noexcept; - - /// @brief Does a system wide bug check. - /// @param void no params are needed. - /// @return if error-free: false, otherwise true. - Boolean err_bug_check(Void) noexcept; -} // namespace Kernel diff --git a/dev/ZKAKit/KernelKit/LoaderInterface.h b/dev/ZKAKit/KernelKit/LoaderInterface.h deleted file mode 100644 index b9a624bb..00000000 --- a/dev/ZKAKit/KernelKit/LoaderInterface.h +++ /dev/null @@ -1,34 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include -#include -#include -#include - -namespace Kernel -{ - /// @brief This interface is used to make loader contracts (MSCOFF, PEF). - /// @author @Amlal-El-Mahrouss - class LoaderInterface - { - public: - explicit LoaderInterface() = default; - virtual ~LoaderInterface() = default; - - ZKA_COPY_DEFAULT(LoaderInterface); - - public: - virtual _Output ErrorOr GetBlob() = 0; - virtual _Output const Char* AsString() = 0; - virtual _Output const Char* MIME() = 0; - virtual _Output const Char* Path() = 0; - virtual _Output ErrorOr FindStart() = 0; - virtual _Output VoidPtr FindSymbol(_Input const Char* name, _Input Int32 kind) = 0; - }; -} // namespace Kernel diff --git a/dev/ZKAKit/KernelKit/LockDelegate.h b/dev/ZKAKit/KernelKit/LockDelegate.h deleted file mode 100644 index 7b533378..00000000 --- a/dev/ZKAKit/KernelKit/LockDelegate.h +++ /dev/null @@ -1,69 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include -#include - -namespace Kernel -{ - enum - { - kLockDone = 200, - kLockTimedOut, - }; - - /// @brief Lock condition pointer. - typedef Boolean* LockPtr; - - /// @brief Locking delegate class, hangs until limit. - /// @tparam N the amount of cycles to wait. - template - class LockDelegate final - { - public: - LockDelegate() = delete; - - public: - explicit LockDelegate(LockPtr expr) - { - auto spin = 0U; - - while (spin < N) - { - if (*expr) - { - fLockStatus | kLockDone; - break; - } - - ++spin; - } - - if (spin > N) - fLockStatus | kLockTimedOut; - } - - ~LockDelegate() = default; - - LockDelegate& operator=(const LockDelegate&) = delete; - LockDelegate(const LockDelegate&) = delete; - - bool Done() - { - return fLockStatus[kLockDone] == kLockDone; - } - - bool HasTimedOut() - { - return fLockStatus[kLockTimedOut] != kLockTimedOut; - } - - private: - Atom fLockStatus; - }; -} // namespace Kernel diff --git a/dev/ZKAKit/KernelKit/MSDOS.h b/dev/ZKAKit/KernelKit/MSDOS.h deleted file mode 100644 index 14575001..00000000 --- a/dev/ZKAKit/KernelKit/MSDOS.h +++ /dev/null @@ -1,52 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - - File: MSDOS.hpp - Purpose: MS-DOS header for Kernel. - - Revision History: - - 30/01/24: Added file (amlel) - -------------------------------------------- */ - -#ifndef __MSDOS_EXEC__ -#define __MSDOS_EXEC__ - -#include -#include - -// Last Rev -// Sat Feb 24 CET 2024 - -#define kMagMz0 'M' -#define kMagMz1 'Z' - -typedef Kernel::UInt32 DosWord; -typedef Kernel::Long DosLong; - -typedef struct _DosHeader -{ - Kernel::UInt8 eMagic[2]; - DosWord eMagLen; - DosWord ePagesCount; - DosWord eCrlc; - DosWord eCParHdr; - DosWord eMinAlloc; - DosWord eMaxAlloc; - DosWord eStackSeg; - DosWord eStackPtr; - DosWord eChksum; - DosWord eIp; - DosWord eCs; - DosWord eLfarlc; - DosWord eOvno; - DosWord eRes[4]; - DosWord eOemid; - DosWord eOeminfo; - DosWord eRes2[10]; - DosLong eLfanew; -} DosHeader, *DosHeaderPtr; - -#endif /* ifndef __MSDOS_EXEC__ */ diff --git a/dev/ZKAKit/KernelKit/PCI/DMA.h b/dev/ZKAKit/KernelKit/PCI/DMA.h deleted file mode 100644 index 1b17af8a..00000000 --- a/dev/ZKAKit/KernelKit/PCI/DMA.h +++ /dev/null @@ -1,81 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include -#include -#include -#include -#include - -namespace Kernel -{ - enum class DmaKind - { - PCI, // Bus mastering is required to be turned on. Basiaclly a request - // control system. 64-Bit access depends on the PAE bit and the device - // (if Double Address Cycle is available) - ISA, // Four DMA channels 0-3; 8 bit transfers and only a megabyte of RAM. - Invalid, - }; - - class DMAWrapper final - { - public: - explicit DMAWrapper() = delete; - - public: - explicit DMAWrapper(nullPtr) = delete; - explicit DMAWrapper(voidPtr Ptr, DmaKind Kind = DmaKind::PCI) - : fAddress(Ptr), fKind(Kind) - { - } - - public: - DMAWrapper& operator=(voidPtr Ptr); - - public: - DMAWrapper& operator=(const DMAWrapper&) = default; - DMAWrapper(const DMAWrapper&) = default; - - public: - ~DMAWrapper() = default; - - template - T* operator->(); - - template - T* Get(const UIntPtr off = 0); - - public: - operator bool(); - bool operator!(); - - public: - bool Write(const UIntPtr& bit, const UIntPtr& offset); - UIntPtr Read(const UIntPtr& offset); - Boolean Check(UIntPtr offset) const; - - public: - UIntPtr operator[](const UIntPtr& offset); - - private: - voidPtr fAddress{nullptr}; - DmaKind fKind{DmaKind::Invalid}; - - private: - friend class DMAFactory; - }; - - class DMAFactory final - { - public: - static OwnPtr> Construct(OwnPtr& dma); - }; -} // namespace Kernel - -#include diff --git a/dev/ZKAKit/KernelKit/PCI/DMA.inl b/dev/ZKAKit/KernelKit/PCI/DMA.inl deleted file mode 100644 index da2208cf..00000000 --- a/dev/ZKAKit/KernelKit/PCI/DMA.inl +++ /dev/null @@ -1,20 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -namespace Kernel -{ - template - T* DMAWrapper::operator->() - { - return fAddress; - } - - template - T* DMAWrapper::Get(const UIntPtr offset) - { - return reinterpret_cast((UIntPtr)fAddress + offset); - } -} // namespace Kernel diff --git a/dev/ZKAKit/KernelKit/PCI/Database.h b/dev/ZKAKit/KernelKit/PCI/Database.h deleted file mode 100644 index dcc5d9d8..00000000 --- a/dev/ZKAKit/KernelKit/PCI/Database.h +++ /dev/null @@ -1,38 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ -#pragma once - -#include -#include - -namespace Kernel -{ - namespace Types - { - // https://wiki.osdev.org/PCI - enum class PciDeviceKind : UChar - { - MassStorageController = 0x1, - NetworkController = 0x2, - DisplayController = 0x3, - MultimediaController = 0x4, - MemoryController = 0x5, - Bridge = 0x6, - CommunicationController = 0x7, - GenericSystemPeripheral = 0x8, - InputDeviceController = 0x9, - DockingStation = 0xa, - Processor = 0xb, - SerialBusController = 0xc, - WirelessController = 0xd, - IntelligentController = 0xe, - SatelliteCommunicationsController = 0xf, - CoProcessor = 0x40, - Unassgined = 0xf, - Invalid = Unassgined, - }; - } // namespace Types -} // namespace Kernel diff --git a/dev/ZKAKit/KernelKit/PCI/Device.h b/dev/ZKAKit/KernelKit/PCI/Device.h deleted file mode 100644 index 19a0832c..00000000 --- a/dev/ZKAKit/KernelKit/PCI/Device.h +++ /dev/null @@ -1,80 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ -#pragma once - -#include - -namespace Kernel::PCI -{ - enum class PciConfigKind : UShort - { - ConfigAddress = 0xCF8, - ConfigData = 0xCFC, - Invalid = 0xFFF - }; - - class Device final - { - public: - Device() = default; - - public: - explicit Device(UShort bus, UShort device, UShort function, UInt32 bar); - - Device& operator=(const Device&) = default; - - Device(const Device&) = default; - - ~Device(); - - public: - UInt Read(UInt bar, Size szData); - void Write(UInt bar, UIntPtr data, Size szData); - - public: - operator bool(); - - public: - template - UInt Read(UInt bar) - { - static_assert(sizeof(T) <= 4, "64-bit PCI addressing is unsupported"); - return Read(bar, sizeof(T)); - } - - template - void Write(UInt bar, UIntPtr data) - { - static_assert(sizeof(T) <= 4, "64-bit PCI addressing is unsupported"); - Write(bar, data, sizeof(T)); - } - - public: - UShort DeviceId(); - UShort VendorId(); - UShort InterfaceId(); - UChar Class(); - UChar Subclass(); - UChar ProgIf(); - UChar HeaderType(); - UIntPtr Bar(UInt32 bar_in); - - public: - void EnableMmio(UInt32 bar_in); - void BecomeBusMaster(UInt32 bar_in); // for PCI-DMA, PC-DMA does not need that. - - UShort Vendor(); - - private: - UShort fBus; - UShort fDevice; - UShort fFunction; - UInt32 fBar; - }; -} // namespace Kernel::PCI - -EXTERN_C void NewOSPCISetCfgTarget(Kernel::UInt bar); -EXTERN_C Kernel::UInt NewOSPCIReadRaw(Kernel::UInt bar); diff --git a/dev/ZKAKit/KernelKit/PCI/Express.h b/dev/ZKAKit/KernelKit/PCI/Express.h deleted file mode 100644 index 10eca955..00000000 --- a/dev/ZKAKit/KernelKit/PCI/Express.h +++ /dev/null @@ -1,11 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include - -#define PCI_EXPRESS_BUS_COUNT (4096) diff --git a/dev/ZKAKit/KernelKit/PCI/IO-Impl-AMD64.inl b/dev/ZKAKit/KernelKit/PCI/IO-Impl-AMD64.inl deleted file mode 100644 index 5bf047cd..00000000 --- a/dev/ZKAKit/KernelKit/PCI/IO-Impl-AMD64.inl +++ /dev/null @@ -1,54 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - - File: IO-Impl-AMD64.hpp - Purpose: I/O for AMD64. - - Revision History: - - 30/01/24: Add file. (amlel) - 02/02/24: Update I/O routines. (amlel) - -------------------------------------------- */ - -namespace Kernel -{ - template - template - T IOArray::In(SizeT index) - { - switch (sizeof(T)) - { -#ifdef __ZKA_AMD64__ - case 4: - return HAL::rt_in32(fPorts[index].Leak()); - case 2: - return HAL::rt_in16(fPorts[index].Leak()); - case 1: - return HAL::rt_in8(fPorts[index].Leak()); -#endif - default: - return 0xFFFF; - } - } - - template - template - void IOArray::Out(SizeT index, T value) - { - switch (sizeof(T)) - { -#ifdef __ZKA_AMD64__ - case 4: - HAL::rt_out32(fPorts[index].Leak(), value); - case 2: - HAL::rt_out16(fPorts[index].Leak(), value); - case 1: - HAL::rt_out8(fPorts[index].Leak(), value); -#endif - default: - break; - } - } -} // namespace Kernel diff --git a/dev/ZKAKit/KernelKit/PCI/IO.h b/dev/ZKAKit/KernelKit/PCI/IO.h deleted file mode 100644 index 41c720d1..00000000 --- a/dev/ZKAKit/KernelKit/PCI/IO.h +++ /dev/null @@ -1,59 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include -#include -#include -#include - -namespace Kernel -{ - template - class IOArray final - { - public: - IOArray() = delete; - - IOArray(nullPtr) = delete; - - explicit IOArray(Array& ports) - : fPorts(ports) - { - } - ~IOArray() - { - } - - IOArray& operator=(const IOArray&) = default; - - IOArray(const IOArray&) = default; - - operator bool() - { - return !fPorts.Empty(); - } - - public: - template - T In(SizeT index); - - template - void Out(SizeT index, T value); - - private: - Array fPorts; - }; - - using IOArray16 = IOArray<16>; -} // namespace Kernel - -#ifdef __x86_64__ -#include -#else -#error Please provide platform specific code for the I/O -#endif // ifdef __x86_64__ diff --git a/dev/ZKAKit/KernelKit/PCI/Iterator.h b/dev/ZKAKit/KernelKit/PCI/Iterator.h deleted file mode 100644 index fa054113..00000000 --- a/dev/ZKAKit/KernelKit/PCI/Iterator.h +++ /dev/null @@ -1,43 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#ifndef __PCI_ITERATOR_H__ -#define __PCI_ITERATOR_H__ - -#include -#include -#include -#include -#include - -#define ZKA_BUS_COUNT (256) -#define ZKA_DEVICE_COUNT (33) -#define ZKA_FUNCTION_COUNT (8) - -namespace Kernel::PCI -{ - class Iterator final - { - public: - Iterator() = delete; - - public: - explicit Iterator(const Types::PciDeviceKind& deviceType); - - Iterator& operator=(const Iterator&) = default; - Iterator(const Iterator&) = default; - - ~Iterator(); - - public: - Ref operator[](const Size& sz); - - private: - Array fDevices; - }; -} // namespace Kernel::PCI - -#endif // __PCI_ITERATOR_H__ diff --git a/dev/ZKAKit/KernelKit/PCI/PCI.h b/dev/ZKAKit/KernelKit/PCI/PCI.h deleted file mode 100644 index c8da391d..00000000 --- a/dev/ZKAKit/KernelKit/PCI/PCI.h +++ /dev/null @@ -1,59 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include - -#define cPCIConfigAddressPort (0xCF8) -#define cPCIConfigDataPort (0xCFC) - -#define cPCIDeviceCount (32) -#define cPCIFuncCount (8) -#define cPCIBusCount (255) - -namespace Kernel::PCI -{ - // model - struct DeviceHeader - { - UInt16 VendorId; - UInt16 DeviceId; - UInt8 Command; - UInt8 Status; - UInt8 RevisionId; - UInt8 ProgIf; - UInt8 SubClass; - UInt8 Class; - UInt8 CacheLineSz; - UInt8 LatencyTimer; - UInt8 HeaderType; - UInt8 Bist; - UInt8 Bus; - UInt8 Device; - UInt8 Function; - }; - - namespace Detail - { - class BAR - { - public: - UIntPtr BAR; - SizeT Size; - }; - } // namespace Detail - - class BAR - { - public: - Detail::BAR BAR1; - Detail::BAR BAR2; - Detail::BAR BAR3; - Detail::BAR BAR4; - Detail::BAR BAR5; - }; -} // namespace Kernel::PCI diff --git a/dev/ZKAKit/KernelKit/PE.h b/dev/ZKAKit/KernelKit/PE.h deleted file mode 100644 index 9a332642..00000000 --- a/dev/ZKAKit/KernelKit/PE.h +++ /dev/null @@ -1,143 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - - File: PE.h - Purpose: Portable Executable for Kernel. - - Revision History: - - 30/01/24: Added file (amlel) - -------------------------------------------- */ - -#ifndef __KERNELKIT_INC_PE_H__ -#define __KERNELKIT_INC_PE_H__ - -#include - -#define kPeSignature 0x00004550 - -#define kPeDLLBase 0x4000000 -#define kPeEXEBase 0x1000000 - -#define kPeMagic32 0x010b -#define kPeMagic64 0x020b - -#define kPeMachineAMD64 0x8664 -#define kPeMachineARM64 0xaa64 - -typedef struct LDR_EXEC_HEADER final -{ - Kernel::UInt32 mSignature; - Kernel::UInt16 mMachine; - Kernel::UInt16 mNumberOfSections; - Kernel::UInt32 mTimeDateStamp; - Kernel::UInt32 mPointerToSymbolTable; - Kernel::UInt32 mNumberOfSymbols; - Kernel::UInt16 mSizeOfOptionalHeader; - Kernel::UInt16 mCharacteristics; -} LDR_EXEC_HEADER, *LDR_EXEC_HEADER_PTR; - -typedef struct LDR_OPTIONAL_HEADER final -{ - Kernel::UInt16 mMagic; // 0x010b - PE32, 0x020b - PE32+ (64 bit) - Kernel::UInt8 mMajorLinkerVersion; - Kernel::UInt8 mMinorLinkerVersion; - Kernel::UInt32 mSizeOfCode; - Kernel::UInt32 mSizeOfInitializedData; - Kernel::UInt32 mSizeOfUninitializedData; - Kernel::UInt32 mAddressOfEntryPoint; - Kernel::UInt32 mBaseOfCode; - Kernel::UInt32 mBaseOfData; - Kernel::UInt32 mImageBase; - Kernel::UInt32 mSectionAlignment; - Kernel::UInt32 mFileAlignment; - Kernel::UInt16 mMajorOperatingSystemVersion; - Kernel::UInt16 mMinorOperatingSystemVersion; - Kernel::UInt16 mMajorImageVersion; - Kernel::UInt16 mMinorImageVersion; - Kernel::UInt16 mMajorSubsystemVersion; - Kernel::UInt16 mMinorSubsystemVersion; - Kernel::UInt32 mWin32VersionValue; - Kernel::UInt32 mSizeOfImage; - Kernel::UInt32 mSizeOfHeaders; - Kernel::UInt32 mCheckSum; - Kernel::UInt16 mSubsystem; - Kernel::UInt16 mDllCharacteristics; - Kernel::UInt32 mSizeOfStackReserve; - Kernel::UInt32 mSizeOfStackCommit; - Kernel::UInt32 mSizeOfHeapReserve; - Kernel::UInt32 mSizeOfHeapCommit; - Kernel::UInt32 mLoaderFlags; - Kernel::UInt32 mNumberOfRvaAndSizes; -} LDR_OPTIONAL_HEADER, *LDR_OPTIONAL_HEADER_PTR; - -typedef struct LDR_SECTION_HEADER final -{ - Kernel::Char mName[8]; - Kernel::UInt32 mVirtualSize; - Kernel::UInt32 mVirtualAddress; - Kernel::UInt32 mSizeOfRawData; - Kernel::UInt32 mPointerToRawData; - Kernel::UInt32 mPointerToRelocations; - Kernel::UInt32 mPointerToLineNumbers; - Kernel::UInt16 mNumberOfRelocations; - Kernel::UInt16 mNumberOfLinenumbers; - Kernel::UInt32 mCharacteristics; -} LDR_SECTION_HEADER, *LDR_SECTION_HEADER_PTR; - -enum kExecDataDirParams -{ - kExecExport, - kExecImport, - kExecInvalid, - kExecCount, -}; - -typedef struct LDR_EXPORT_DIRECTORY -{ - Kernel::UInt32 mCharacteristics; - Kernel::UInt32 mTimeDateStamp; - Kernel::UInt16 mMajorVersion; - Kernel::UInt16 mMinorVersion; - Kernel::UInt32 mName; - Kernel::UInt32 mBase; - Kernel::UInt32 mNumberOfFunctions; - Kernel::UInt32 mNumberOfNames; - Kernel::UInt32 mAddressOfFunctions; // export table rva - Kernel::UInt32 mAddressOfNames; - Kernel::UInt32 mAddressOfNameOrdinal; // ordinal table rva -} LDR_EXPORT_DIRECTORY, *LDR_EXPORT_DIRECTORY_PTR; - -typedef struct LDR_IMPORT_DIRECTORY -{ - union { - Kernel::UInt32 mCharacteristics; - Kernel::UInt32 mOriginalFirstThunk; - }; - Kernel::UInt32 mTimeDateStamp; - Kernel::UInt32 mForwarderChain; - Kernel::UInt32 mNameRva; - Kernel::UInt32 mThunkTableRva; -} LDR_IMPORT_DIRECTORY, *LDR_IMPORT_DIRECTORY_PTR; - -typedef struct LDR_DATA_DIRECTORY -{ - Kernel::UInt32 VirtualAddress; - Kernel::UInt32 Size; -} LDR_DATA_DIRECTORY, *LDR_DATA_DIRECTORY_PTR; - -typedef struct LDR_IMAGE_HEADER -{ - LDR_EXEC_HEADER mHeader; - LDR_OPTIONAL_HEADER mOptHdr; -} LDR_IMAGE_HEADER, *LDR_IMAGE_HEADER_PTR; - -enum -{ - eUserSection = 0x00000020, - cPEResourceId = 0xFFaadd00, -}; - -#endif /* ifndef __KERNELKIT_INC_PE_H__ */ diff --git a/dev/ZKAKit/KernelKit/PECodeMgr.h b/dev/ZKAKit/KernelKit/PECodeMgr.h deleted file mode 100644 index fc4dd09d..00000000 --- a/dev/ZKAKit/KernelKit/PECodeMgr.h +++ /dev/null @@ -1,24 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - - File: PECodeMgr.h - Purpose: PE32+ Code Mgr and DLL mgr. - - Revision History: - - 12/02/24: Added file (amlel) - -------------------------------------------- */ - -#pragma once - -//////////////////////////////////////////////////// - -// LAST REV: Mon Feb 12 13:52:01 CET 2024 - -//////////////////////////////////////////////////// - -#include -#include -#include diff --git a/dev/ZKAKit/KernelKit/PEF.h b/dev/ZKAKit/KernelKit/PEF.h deleted file mode 100644 index 73f41a4a..00000000 --- a/dev/ZKAKit/KernelKit/PEF.h +++ /dev/null @@ -1,117 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - - File: PEF.h - Purpose: Preferred Executable Format for Kernel. - - Revision History: - - ?/?/23: Added file (amlel) - -------------------------------------------- */ - -#ifndef KERNELKIT_PEF_H -#define KERNELKIT_PEF_H - -#include -#include -#include - -#define kPefMagic "Joy!" -#define kPefMagicFat "yoJ!" - -#define kPefMagicLen 5 - -#define kPefVersion 3 -#define kPefNameLen 255 - -/* not mandatory, only for non fork based filesystems. */ -#define kPefExt ".o" -#define kPefDylibExt ".dylib" -#define kPefLibExt ".lib" -#define kPefObjectExt ".obj" -#define kPefDebugExt ".dbg" -#define kPefDriverExt ".sys" - -// Kernel System Binary Interface. -#define kPefAbi (0x5046) - -#define kPefBaseOrigin (0x40000000) - -#define kPefStart "__ImageStart" - -#define kPefForkKind kPefMagic -#define kPefForkKindFAT kPefMagicFat - -namespace Kernel -{ - enum - { - kPefArchIntel86S, - kPefArchAMD64, - kPefArchRISCV, - kPefArch64x0, /* 64x0. ISA */ - kPefArch32x0, /* 32x0. ISA */ - kPefArchPowerPC, - kPefArchARM64, - kPefArchCount = (kPefArchPowerPC - kPefArchIntel86S) + 1, - kPefArchInvalid = 0xFF, - }; - - enum - { - kPefSubArchAMD, - kPefSubArchIntel, - kPefSubArchARM, - kPefSubArchGeneric, - kPefSubArchIBM, - }; - - enum - { - kPefKindExec = 1, /* .exe */ - kPefKindDylib = 2, /* .dylib */ - kPefKindObject = 4, /* .obj */ - kPefKindDebug = 5, /* .dbg */ - kPefKindDriver = 6, - kPefKindCount, - }; - - typedef struct PEFContainer final - { - Char Magic[kPefMagicLen]; - UInt32 Linker; - UInt32 Version; - UInt32 Kind; - UInt32 Abi; - UInt32 Cpu; - UInt32 SubCpu; /* Cpu specific information */ - UIntPtr Start; - SizeT HdrSz; /* Size of header */ - SizeT Count; /* container header count */ - } PACKED PEFContainer; - - /* First PEFCommandHeader starts after PEFContainer */ - - typedef struct PEFCommandHeader final - { - Char Name[kPefNameLen]; /* container name */ - UInt32 Cpu; /* container cpu */ - UInt32 SubCpu; /* container sub-cpu */ - UInt32 Flags; /* container flags */ - UInt16 Kind; /* container kind */ - UIntPtr Offset; /* content offset */ - SizeT Size; /* content Size */ - } PACKED PEFCommandHeader; - - enum - { - kPefCode = 0xC, - kPefData = 0xD, - kPefZero = 0xE, - kPefLinkerID = 0x1, - }; -} // namespace Kernel - -#endif /* ifndef KERNELKIT_PEF_H */ diff --git a/dev/ZKAKit/KernelKit/PEFCodeMgr.h b/dev/ZKAKit/KernelKit/PEFCodeMgr.h deleted file mode 100644 index d1a0bf80..00000000 --- a/dev/ZKAKit/KernelKit/PEFCodeMgr.h +++ /dev/null @@ -1,72 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#ifndef _INC_CODE_MANAGER_PEF_H_ -#define _INC_CODE_MANAGER_PEF_H_ - -#include -#include -#include -#include - -#ifndef INC_PROCESS_SCHEDULER_H -#include -#endif - -#define kPefApplicationMime "application/vnd-zka-executable" - -namespace Kernel -{ - /// - /// \name PEFLoader - /// \brief PEF loader class. - /// - class PEFLoader : public LoaderInterface - { - private: - explicit PEFLoader() = delete; - - public: - explicit PEFLoader(const VoidPtr blob); - explicit PEFLoader(const Char* path); - ~PEFLoader() override; - - public: - ZKA_COPY_DEFAULT(PEFLoader); - - public: - const Char* Path() override; - const Char* AsString() override; - const Char* MIME() override; - - public: - ErrorOr FindStart() override; - VoidPtr FindSymbol(const Char* name, Int32 kind) override; - ErrorOr GetBlob() override; - - public: - bool IsLoaded() noexcept; - - private: -#ifdef __FSKIT_INCLUDES_NEFS__ - OwnPtr> fFile; -#else - OwnPtr> fFile; -#endif // __FSKIT_INCLUDES_NEFS__ - - Ref fPath; - VoidPtr fCachedBlob; - bool fFatBinary; - bool fBad; - }; - - namespace Utils - { - ProcessID rtl_create_process(PEFLoader& exec, const Int32& procKind) noexcept; - } // namespace Utils -} // namespace Kernel - -#endif // ifndef _INC_CODE_MANAGER_PEF_H_ diff --git a/dev/ZKAKit/KernelKit/Semaphore.h b/dev/ZKAKit/KernelKit/Semaphore.h deleted file mode 100644 index fef44b15..00000000 --- a/dev/ZKAKit/KernelKit/Semaphore.h +++ /dev/null @@ -1,43 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include -#include -#include - -namespace Kernel -{ - class UserProcess; - - typedef UserProcess* UserProcessPtr; - - /// @brief Access control class, which locks a task until one is done. - class Semaphore final - { - public: - explicit Semaphore() = default; - ~Semaphore() = default; - - public: - bool IsLocked() const; - bool Unlock() noexcept; - - public: - void WaitForProcess() noexcept; - - public: - bool Lock(UserProcess* process); - bool LockOrWait(UserProcess* process, TimerInterface* timer); - - public: - ZKA_COPY_DEFAULT(Semaphore); - - private: - UserProcessPtr fLockingProcess{nullptr}; - }; -} // namespace Kernel diff --git a/dev/ZKAKit/KernelKit/ThreadLocalStorage.h b/dev/ZKAKit/KernelKit/ThreadLocalStorage.h deleted file mode 100644 index ce334b75..00000000 --- a/dev/ZKAKit/KernelKit/ThreadLocalStorage.h +++ /dev/null @@ -1,65 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#ifndef KERNELKIT_TLS_H -#define KERNELKIT_TLS_H - -#include -#include - -///! @brief Thread Local Storage for minoskrnl. - -#define kCookieMag0 'Z' -#define kCookieMag1 'K' -#define kCookieMag2 'A' - -#define kTLSCookieLen (3U) - -struct THREAD_INFORMATION_BLOCK; - -/// @brief Thread Information Block. -/// Located in GS on AMD64, other architectures have their own stuff. (64x0, 32x0, ARM64) -struct PACKED THREAD_INFORMATION_BLOCK final -{ - Kernel::Char Cookie[kTLSCookieLen]{0}; //! Thread magic number. - Kernel::VoidPtr Record{nullptr}; //! Thread information record. -}; - -///! @brief Cookie Sanity check. -Kernel::Boolean tls_check_tib(THREAD_INFORMATION_BLOCK* the_tib); - -///! @brief new ptr syscall. -template -T* tls_new_ptr(void) noexcept; - -///! @brief delete ptr syscall. -template -Kernel::Boolean tls_delete_ptr(T* ptr) noexcept; - -//! @brief Delete process pointer. -//! @param obj The pointer to delete. -template -inline Kernel::Bool tls_delete_ptr(Kernel::ErrorOr obj) noexcept; - -//! @brief Delete process pointer. -//! @param obj The pointer to delete. -template -inline Kernel::Bool tls_delete_ptr(Kernel::ErrorOr obj) noexcept; - -template -T* tls_new_class(Args&&... args); - -/// @brief TLS install TIB and PIB. (syscall) -EXTERN_C Kernel::Void rt_install_tib(THREAD_INFORMATION_BLOCK* TIB, THREAD_INFORMATION_BLOCK* PIB); - -/// @brief TLS check (syscall) -EXTERN_C Kernel::Bool tls_check_syscall_impl(Kernel::VoidPtr TIB) noexcept; - -#include - -// last rev 7/7/24 - -#endif /* ifndef KERNELKIT_TLS_H */ diff --git a/dev/ZKAKit/KernelKit/ThreadLocalStorage.inl b/dev/ZKAKit/KernelKit/ThreadLocalStorage.inl deleted file mode 100644 index 3b11cd86..00000000 --- a/dev/ZKAKit/KernelKit/ThreadLocalStorage.inl +++ /dev/null @@ -1,99 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -//! @file ThreadLocalStorage.inl -//! @brief Allocate resources from the process's heap storage. - -#ifndef INC_PROCESS_SCHEDULER_H -#include -#endif - -template -inline T* tls_new_ptr(void) noexcept -{ - using namespace Kernel; - - auto ref_process = UserProcessScheduler::The().GetCurrentProcess(); - MUST_PASS(ref_process); - - auto pointer = ref_process.Leak().New(sizeof(T)); - - if (pointer.Error()) - return nullptr; - - return reinterpret_cast(pointer.Leak().Leak()); -} - -//! @brief Delete process pointer. -//! @param obj The pointer to delete. -template -inline Kernel::Bool tls_delete_ptr(T* obj) noexcept -{ - using namespace Kernel; - - if (!obj) - return No; - - auto ref_process = UserProcessScheduler::The().GetCurrentProcess(); - MUST_PASS(ref_process); - - ErrorOr obj_wrapped{obj}; - - return ref_process.Leak().Delete(obj_wrapped, sizeof(T)); -} - -//! @brief Delete process pointer. -//! @param obj The pointer to delete. -template -inline Kernel::Bool tls_delete_ptr(Kernel::ErrorOr obj) noexcept -{ - return tls_delete_ptr(obj.Leak()); -} - -//! @brief Delete process pointer. -//! @param obj The pointer to delete. -template -inline Kernel::Bool tls_delete_ptr(Kernel::ErrorOr obj) noexcept -{ - return tls_delete_ptr(obj->Leak()); -} - -/// @brief Allocate a C++ class, and then call the constructor of it. -/// @tparam T class type. -/// @tparam ...Args varg class type. -/// @param args arguments list. -/// @return Class instance. -template -T* tls_new_class(Args&&... args) -{ - using namespace Kernel; - - T* obj = tls_new_ptr(); - - if (obj) - { - *obj = T(forward(args)...); - return obj; - } - - return nullptr; -} - -/// @brief Delete a C++ class (call constructor first.) -/// @tparam T -/// @param obj -/// @return -template -inline Kernel::Bool tls_delete_class(T* obj) -{ - using namespace Kernel; - - if (!obj) - return No; - - obj->~T(); - return tls_delete_ptr(obj); -} diff --git a/dev/ZKAKit/KernelKit/Timer.h b/dev/ZKAKit/KernelKit/Timer.h deleted file mode 100644 index a2dae8cd..00000000 --- a/dev/ZKAKit/KernelKit/Timer.h +++ /dev/null @@ -1,82 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include -#include -#include - -namespace Kernel -{ - class SoftwareTimer; - class TimerInterface; - - class TimerInterface - { - public: - /// @brief Default constructor - explicit TimerInterface() = default; - virtual ~TimerInterface() = default; - - public: - ZKA_COPY_DEFAULT(TimerInterface); - - public: - virtual Int32 Wait() noexcept; - }; - - class SoftwareTimer final : public TimerInterface - { - public: - explicit SoftwareTimer(Int64 seconds); - ~SoftwareTimer() override; - - public: - ZKA_COPY_DEFAULT(SoftwareTimer); - - public: - Int32 Wait() noexcept override; - - private: - IntPtr* fDigitalTimer{nullptr}; - Int64 fWaitFor{0}; - }; - - class HardwareTimer final : public TimerInterface - { - public: - explicit HardwareTimer(Int64 seconds); - ~HardwareTimer() override; - - public: - ZKA_COPY_DEFAULT(HardwareTimer); - - public: - Int32 Wait() noexcept override; - - private: - IntPtr* fDigitalTimer{nullptr}; - Int64 fWaitFor{0}; - }; - - inline Int64 Milliseconds(Int64 time) - { - if (time < 0) - return 0; - - // TODO: nanoseconds maybe? - return 1000 * 1000 * time; - } - - inline Int64 Seconds(Int64 time) - { - if (time < 0) - return 0; - - return 1000 * Milliseconds(time); - } -} // namespace Kernel diff --git a/dev/ZKAKit/KernelKit/User.h b/dev/ZKAKit/KernelKit/User.h deleted file mode 100644 index b74b08c1..00000000 --- a/dev/ZKAKit/KernelKit/User.h +++ /dev/null @@ -1,83 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#ifndef INC_USER_H -#define INC_USER_H - -#include -#include -#include -#include - -///! We got the Super and guest user, both used to make authorization operations on the OS. -#define kSuperUser "OS AUTHORITY/SUPER" -#define kGuestUser "OS AUTHORITY/GUEST" - -#define kUsersDir "/Users/" - -#define kMaxUserNameLen (255U) -#define kMaxUserTokenLen (255U) - -namespace Kernel -{ - class User; - - enum class UserRingKind - { - kRingInvalid = 0, - kRingStdUser = 1, - kRingSuperUser = 2, - kRingGuestUser = 5, - kRingCount = 3, - }; - - typedef Char* usr_public_key_kind; - - class User final - { - public: - explicit User() = delete; - - User(const Int32& sel, const Char* userName); - User(const UserRingKind& kind, const Char* userName); - - ~User(); - - public: - ZKA_COPY_DEFAULT(User) - - public: - bool operator==(const User& lhs); - bool operator!=(const User& lhs); - - public: - /// @brief Get software ring - const UserRingKind& Ring() noexcept; - - /// @brief Get user name - Char* Name() noexcept; - - /// @brief Is he a standard user? - Bool IsStdUser() noexcept; - - /// @brief Is she a super user? - Bool IsSuperUser() noexcept; - - /// @brief Saves a password from the public key. - Bool Save(const usr_public_key_kind password) noexcept; - - /// @brief Checks if a password matches the **password**. - /// @param password the password to check. - Bool Matches(const usr_public_key_kind password) noexcept; - - private: - UserRingKind mUserRing{UserRingKind::kRingStdUser}; - Char mUserName[kMaxUserNameLen] = {0}; - Char mUserToken[kMaxUserTokenLen] = {0}; - }; -} // namespace Kernel - -#endif /* ifndef INC_USER_H */ diff --git a/dev/ZKAKit/KernelKit/UserProcessScheduler.h b/dev/ZKAKit/KernelKit/UserProcessScheduler.h deleted file mode 100644 index ab4c4ff1..00000000 --- a/dev/ZKAKit/KernelKit/UserProcessScheduler.h +++ /dev/null @@ -1,338 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#ifndef INC_PROCESS_SCHEDULER_H -#define INC_PROCESS_SCHEDULER_H - -#include -#include -#include -#include - -#define kSchedMinMicroTime (AffinityKind::kStandard) -#define kSchedInvalidPID (-1) -#define kSchedProcessLimitPerTeam (32U) - -#define kSchedMaxMemoryLimit gib_cast(128) -#define kSchedMaxStackSz mib_cast(8) - -#define kProcessInvalidID (-1) -#define kProcessNameLen (128U) - -//////////////////////////////////////////////////// -// The current date is: Thu 11/28/2024 // -//////////////////////////////////////////////////// - -namespace Kernel -{ - //! @note Forward class declarations. - - class UserProcess; - class IDLLObject; - class UserProcessTeam; - class UserProcessScheduler; - class UserProcessHelper; - - //! @brief Local Process identifier. - typedef Int64 ProcessID; - - //! @brief Local Process status enum. - enum class ProcessStatusKind : Int32 - { - kInvalid, - kStarting, - kRunning, - kKilled, - kFrozen, - kFinished, - kCount, - }; - - //! @brief Affinity is the amount of nano-seconds this process is going - //! to run. - enum class AffinityKind : Int32 - { - kRealTime = 500, - kVeryHigh = 250, - kHigh = 200, - kStandard = 1000, - kLowUsage = 1500, - kVeryLowUsage = 2000, - }; - - // operator overloading. - - inline bool operator<(AffinityKind lhs, AffinityKind rhs) - { - Int32 lhs_int = static_cast(lhs); - Int32 rhs_int = static_cast(rhs); - - return lhs_int < rhs_int; - } - - inline bool operator>(AffinityKind lhs, AffinityKind rhs) - { - Int32 lhs_int = static_cast(lhs); - Int32 rhs_int = static_cast(rhs); - - return lhs_int > rhs_int; - } - - inline bool operator<=(AffinityKind lhs, AffinityKind rhs) - { - Int32 lhs_int = static_cast(lhs); - Int32 rhs_int = static_cast(rhs); - - return lhs_int <= rhs_int; - } - - inline bool operator>=(AffinityKind lhs, AffinityKind rhs) - { - Int32 lhs_int = static_cast(lhs); - Int32 rhs_int = static_cast(rhs); - - return lhs_int >= rhs_int; - } - - // end of operator overloading. - - enum class ProcessSubsystem : Int32 - { - kProcessSubsystemSecurity = 100, - kProcessSubsystemApplication, - kProcessSubsystemService, - kProcessSubsystemDriver, - kProcessSubsystemInvalid = 255, - kProcessSubsystemCount = 4, - }; - - using ProcessTime = UInt64; - using PID = Int64; - - // for permission manager, tells where we run the code. - enum class ProcessLevelRing : Int32 - { - kRingStdUser = 1, - kRingSuperUser = 2, - kRingGuestUser = 5, - kRingCount = 5, - }; - - /// @brief Helper type to describe a code image. - using ImagePtr = VoidPtr; - - struct UserProcessImage final - { - explicit UserProcessImage() = default; - - ImagePtr fCode; - ImagePtr fBlob; - - operator bool() - { - return this->fCode; - } - - Bool HasImage() - { - return this->fBlob != nullptr; - } - }; - - /// @name UserProcess - /// @brief User process class, holds information about the running process/thread. - class UserProcess final - { - public: - explicit UserProcess(); - ~UserProcess(); - - public: - ZKA_COPY_DEFAULT(UserProcess); - - public: - Char Name[kProcessNameLen] = {"Process (Unnamed)"}; - ProcessSubsystem SubSystem{ProcessSubsystem::kProcessSubsystemInvalid}; - User* Owner{nullptr}; - HAL::StackFramePtr StackFrame{nullptr}; - AffinityKind Affinity{AffinityKind::kStandard}; - ProcessStatusKind Status{ProcessStatusKind::kFinished}; - UInt8* StackReserve{nullptr}; - UserProcessImage Image; - SizeT StackSize{kSchedMaxStackSz}; - IDLLObject* DylibDelegate{nullptr}; - SizeT MemoryCursor{0}; - SizeT MemoryLimit{kSchedMaxMemoryLimit}; - - struct UserProcessHeapList final - { - VoidPtr MemoryEntry{nullptr}; - SizeT MemoryEntrySize{0UL}; - SizeT MemoryEntryPad{0UL}; - - struct UserProcessHeapList* MemoryPrev{nullptr}; - struct UserProcessHeapList* MemoryNext{nullptr}; - }; - - struct UserProcessSignal final - { - UIntPtr SignalIP; - ProcessStatusKind PreviousStatus; - UIntPtr SignalID; - }; - - UserProcessSignal ProcessSignal; - UserProcessHeapList* ProcessMemoryHeap{nullptr}; - UserProcessTeam* ProcessParentTeam; - - VoidPtr VMRegister{0UL}; - - enum - { - kInvalidExecutableKind, - kExectuableKind, - kExectuableDLLKind, - kExectuableKindCount, - }; - - ProcessTime PTime{0}; //! @brief Process allocated tine. - - PID ProcessId{kSchedInvalidPID}; - Int32 Kind{kExectuableKind}; - - public: - //! @brief boolean operator, check status. - operator bool(); - - ///! @brief Crashes the app, exits with code ~0. - Void Crash(); - - ///! @brief Exits the app. - Void Exit(const Int32& exit_code = 0); - - ///! @brief TLS allocate. - ///! @param sz size of new ptr. - ErrorOr New(const SizeT& sz, const SizeT& pad_amount = 0); - - ///! @brief TLS free. - ///! @param ptr the pointer to free. - ///! @param sz the size of it. - template - Boolean Delete(ErrorOr ptr, const SizeT& sz); - - ///! @brief Wakes up threads. - Void Wake(const Bool wakeup = false); - - public: - //! @brief Gets the local exit code. - const UInt32& GetExitCode() noexcept; - - ///! @brief Get the process's name - ///! @example 'C Runtime Library' - const Char* GetName() noexcept; - - //! @brief return local error code of process. - //! @return Int32 local error code. - Int32& GetLocalCode() noexcept; - - const User* GetOwner() noexcept; - const ProcessStatusKind& GetStatus() noexcept; - const AffinityKind& GetAffinity() noexcept; - - private: - UInt32 fLastExitCode{0}; - Int32 fLocalCode{0}; - - friend UserProcessScheduler; - friend UserProcessHelper; - }; - - /// \brief Processs Team (contains multiple processes inside it.) - /// Equivalent to a process batch - class UserProcessTeam final - { - public: - explicit UserProcessTeam(); - ~UserProcessTeam() = default; - - ZKA_COPY_DEFAULT(UserProcessTeam); - - Array& AsArray(); - Ref& AsRef(); - ProcessID& Id() noexcept; - - public: - Array mProcessList; - Ref mCurrentProcess; - ProcessID mTeamId{0}; - ProcessID mProcessCount{0}; - }; - - using UserProcessPtr = UserProcess*; - - /// @brief Process scheduler class. - /// The main class which you call to schedule user processes. - class UserProcessScheduler final : public ISchedulable - { - friend class UserProcessHelper; - - public: - explicit UserProcessScheduler() = default; - ~UserProcessScheduler() override = default; - - ZKA_COPY_DEFAULT(UserProcessScheduler) - - operator bool(); - bool operator!(); - - public: - UserProcessTeam& CurrentTeam(); - - public: - ProcessID Spawn(UserProcess* process); - const Bool Remove(ProcessID process_id); - - const Bool IsUser() override; - const Bool IsKernel() override; - const Bool HasMP() override; - - public: - Ref& GetCurrentProcess(); - const SizeT Run() noexcept; - - public: - STATIC UserProcessScheduler& The(); - - private: - UserProcessTeam mTeam{}; - }; - - /* - * \brief UserProcess helper class, which contains needed utilities for the scheduler. - */ - - class UserProcessHelper final - { - public: - STATIC Bool Switch(VoidPtr image_ptr, UInt8* stack_ptr, HAL::StackFramePtr frame_ptr, const PID& new_pid); - STATIC Bool CanBeScheduled(const UserProcess* process); - STATIC ErrorOr TheCurrentPID(); - STATIC SizeT StartScheduling(); - }; - - const UInt32& sched_get_exit_code(void) noexcept; -} // namespace Kernel - -#include -#include - -//////////////////////////////////////////////////// - -// END - -//////////////////////////////////////////////////// - -#endif /* ifndef INC_PROCESS_SCHEDULER_H */ diff --git a/dev/ZKAKit/KernelKit/UserProcessScheduler.inl b/dev/ZKAKit/KernelKit/UserProcessScheduler.inl deleted file mode 100644 index 2973d6a4..00000000 --- a/dev/ZKAKit/KernelKit/UserProcessScheduler.inl +++ /dev/null @@ -1,40 +0,0 @@ -namespace Kernel -{ - /***********************************************************************************/ - /** @brief Free pointer from usage. */ - /***********************************************************************************/ - - template - Boolean UserProcess::Delete(ErrorOr ptr, const SizeT& sz) - { - if (!ptr || - sz == 0) - return No; - - UserProcessHeapList* entry = this->ProcessMemoryHeap; - - while (entry != nullptr) - { - if (entry->MemoryEntry == ptr.Leak().Leak()) - { -#ifdef __ZKA_AMD64__ - auto pd = hal_read_cr3(); - hal_write_cr3(this->VMRegister); - - auto ret = mm_delete_heap(entry->MemoryEntry); - - hal_write_cr3(pd); - - return ret; -#else - Bool ret = mm_delete_heap(ptr.Leak().Leak()); - return ret; -#endif - } - - entry = entry->MemoryNext; - } - - return No; - } -} // namespace Kernel diff --git a/dev/ZKAKit/KernelKit/XCOFF.h b/dev/ZKAKit/KernelKit/XCOFF.h deleted file mode 100644 index d4ddcb46..00000000 --- a/dev/ZKAKit/KernelKit/XCOFF.h +++ /dev/null @@ -1,51 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - - File: XCOFF.hpp - Purpose: XCOFF for Kernel. - - Revision History: - - 04/07/24: Added file (amlel) - -------------------------------------------- */ - -#ifndef INC_XOCFF_H -#define INC_XOCFF_H - -#include - -#define kXCOFF64Magic (0x01F7) - -#define kXCOFFRelFlg (0x0001) -#define kXCOFFExecutable (0x0002) -#define kXCOFFLnno (0x0004) -#define kXCOFFLSyms (0x0008) - -struct XCoffFileHeader; -struct XCoffForkHeader; - -/// @brief XCoff file header, meant for POWER apps. -typedef struct XCoffFileHeader -{ - Kernel::UInt16 fMagic; - Kernel::UInt16 fTarget; - Kernel::UInt16 fNumSecs; - Kernel::UInt32 fTimeDat; - Kernel::UIntPtr fSymPtr; - Kernel::UInt32 fNumSyms; - Kernel::UInt16 fOptHdr; // ?: Number of bytes in optional header -} XCoffFileHeader64; - -#define cForkNameLen (255) - -/// @brief This the executable manifest fork. -typedef struct XCoffForkHeader -{ - Kernel::Char fPropertiesXMLFork[cForkNameLen]; - Kernel::Char fDynamicLoaderFork[cForkNameLen]; - Kernel::Char fCodeSignFork[cForkNameLen]; -} XCoffForkHeader; - -#endif // ifndef INC_XOCFF_H diff --git a/dev/ZKAKit/KernelRsrc.rsrc b/dev/ZKAKit/KernelRsrc.rsrc deleted file mode 100644 index 3bb869ee..00000000 --- a/dev/ZKAKit/KernelRsrc.rsrc +++ /dev/null @@ -1,25 +0,0 @@ -#include "CompilerKit/Version.h" - -1 VERSIONINFO -FILEVERSION 1,0,0,0 -PRODUCTVERSION 1,0,0,0 -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "080904E4" - BEGIN - VALUE "CompanyName", "Theater Quality Inc." - VALUE "FileDescription", "ZKA Minimal Kernel." - VALUE "FileVersion", KERNEL_VERSION - VALUE "InternalName", "minoskrnl" - VALUE "LegalCopyright", "(c) 2024 Theater Quality Inc, all rights reserved." - VALUE "OriginalFilename", "minoskrnl.exe" - VALUE "ProductName", "ZKA Minimal Kernel." - VALUE "ProductVersion", KERNEL_VERSION - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x809, 1252 - END -END diff --git a/dev/ZKAKit/MoveAll.ARM64.sh b/dev/ZKAKit/MoveAll.ARM64.sh deleted file mode 100755 index 35e0909e..00000000 --- a/dev/ZKAKit/MoveAll.ARM64.sh +++ /dev/null @@ -1,7 +0,0 @@ -#! /bin/sh - -for file in *.o; do - mv -- "$file" "${file%.o}.obj" -done - -mv *.obj obj/ diff --git a/dev/ZKAKit/MoveAll.X64.sh b/dev/ZKAKit/MoveAll.X64.sh deleted file mode 100755 index 1c135d06..00000000 --- a/dev/ZKAKit/MoveAll.X64.sh +++ /dev/null @@ -1,7 +0,0 @@ -#! /bin/sh - -for file in *.o; do - mv -- "$file" "${file%.o}.obj" -done - -mv *.obj HALKit/AMD64/*.obj obj/ diff --git a/dev/ZKAKit/NetworkKit/IP.h b/dev/ZKAKit/NetworkKit/IP.h deleted file mode 100644 index c30fa8d1..00000000 --- a/dev/ZKAKit/NetworkKit/IP.h +++ /dev/null @@ -1,83 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include -#include -#include -#include - -namespace Kernel -{ - class RawIPAddress6; - class RawIPAddress; - class IPFactory; - - class RawIPAddress final - { - private: - explicit RawIPAddress(char bytes[4]); - ~RawIPAddress() = default; - - RawIPAddress& operator=(const RawIPAddress&) = delete; - RawIPAddress(const RawIPAddress&) = default; - - public: - char* Address(); - - char& operator[](const Size& index); - - bool operator==(const RawIPAddress& ipv6); - bool operator!=(const RawIPAddress& ipv6); - - private: - char fAddr[4]; - - friend IPFactory; // it is the one creating these addresses, thus this - // is why the constructors are private. - }; - - /** - * @brief IPv6 address. - */ - class RawIPAddress6 final - { - private: - explicit RawIPAddress6(char Bytes[8]); - ~RawIPAddress6() = default; - - RawIPAddress6& operator=(const RawIPAddress6&) = delete; - RawIPAddress6(const RawIPAddress6&) = default; - - public: - char* Address() - { - return fAddr; - } - - char& operator[](const Size& index); - - bool operator==(const RawIPAddress6& ipv6); - bool operator!=(const RawIPAddress6& ipv6); - - private: - char fAddr[8]; - - friend IPFactory; - }; - - /** - * @brief IP Creation helpers - */ - class IPFactory final - { - public: - static ErrorOr ToKString(Ref& ipv6); - static ErrorOr ToKString(Ref& ipv4); - static bool IpCheckVersion4(const Char* ip); - }; -} // namespace Kernel diff --git a/dev/ZKAKit/NetworkKit/IPC.h b/dev/ZKAKit/NetworkKit/IPC.h deleted file mode 100644 index 0e50c266..00000000 --- a/dev/ZKAKit/NetworkKit/IPC.h +++ /dev/null @@ -1,107 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved.. - - File: IPC.h. - Purpose: IPC protocol. - -------------------------------------------- */ - -#ifndef INC_IPC_H -#define INC_IPC_H - -#include -#include -#include -#include - -/// @file IPC.h -/// @brief IPC comm. protocol. - -/// IA separator. -#define kIPCRemoteSeparator ":" - -/// Interchange address, consists of PID:TEAM. -#define kIPCRemoteInvalid "00:00" - -#define kIPCHeaderMagic (0x4950434) - -namespace Kernel -{ - struct IPCAddress; - struct IPCMessage; - - /// @brief 128-bit IPC address. - struct PACKED IPCAddress final - { - UInt64 UserProcessID; - UInt64 UserProcessTeam; - - //////////////////////////////////// - // some operators. - //////////////////////////////////// - - bool operator==(const IPCAddress& addr) noexcept - { - return addr.UserProcessID == this->UserProcessID && addr.UserProcessTeam == this->UserProcessTeam; - } - - bool operator==(IPCAddress& addr) noexcept - { - return addr.UserProcessID == this->UserProcessID && addr.UserProcessTeam == this->UserProcessTeam; - } - }; - - typedef struct IPCAddress IPCEPAddressKind; - - enum - { - kIPCLittleEndian = 0, - kIPCBigEndian = 1, - kIPCMixedEndian = 2, - }; - - constexpr inline auto kIPCMsgSize = 6094U; - - /// @brief IPC connection header, message cannot be greater than 6K. - typedef struct IPCMessage final - { - UInt32 IpcHeaderMagic; // cRemoteHeaderMagic - UInt8 IpcEndianess; // 0 : LE, 1 : BE - SizeT IpcPacketSize; - IPCEPAddressKind IpcFrom; - IPCEPAddressKind IpcTo; - UInt32 IpcCRC32; - UInt32 IpcMsg; - UInt32 IpcMsgSz; - UInt8 IpcData[kIPCMsgSize]; - - /// @brief Passes the message to target, could be anything, HTTP packet, JSON or whatever. - Bool Pass(IPCMessage* target) noexcept - { - if (target && target->IpcFrom == this->IpcTo) - { - if (this->IpcMsgSz > target->IpcMsgSz) - return No; - - rt_copy_memory(this->IpcData, target->IpcData, this->IpcMsgSz); - - return Yes; - } - - return No; - } - } PACKED IPCMessage; - - /// @brief Sanitize packet function - /// @retval true packet is correct. - /// @retval false packet is incorrect and process has crashed. - Bool ipc_sanitize_packet(_Input IPCMessage* pckt_in); - - /// @brief Construct packet function - /// @retval true packet is correct. - /// @retval false packet is incorrect and process has crashed. - Bool ipc_construct_packet(_Output _Input IPCMessage** pckt_in); -} // namespace Kernel - -#endif // INC_IPC_H diff --git a/dev/ZKAKit/NetworkKit/LTE.h b/dev/ZKAKit/NetworkKit/LTE.h deleted file mode 100644 index 9b113a1f..00000000 --- a/dev/ZKAKit/NetworkKit/LTE.h +++ /dev/null @@ -1,16 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved.. - - File: LTE.h. - Purpose: LTE protocol classes. - -------------------------------------------- */ - -#ifndef _INC_NETWORK_LTE_H_ -#define _INC_NETWORK_LTE_H_ - -#include -#include - -#endif // ifndef _INC_NETWORK_LTE_H_ diff --git a/dev/ZKAKit/NetworkKit/MAC.h b/dev/ZKAKit/NetworkKit/MAC.h deleted file mode 100644 index 7f1f6f09..00000000 --- a/dev/ZKAKit/NetworkKit/MAC.h +++ /dev/null @@ -1,29 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include -#include -#include - -namespace Kernel -{ - class MacAddressGetter; - - /// \brief This retrieves the MAC address of the device. - /// \note Listens for the current NIC. - class MacAddressGetter final - { - public: - explicit MacAddressGetter() = default; - - public: - KString& AsString(); - Array& AsBytes(); - }; - -} // namespace Kernel diff --git a/dev/ZKAKit/NetworkKit/NetworkDevice.h b/dev/ZKAKit/NetworkKit/NetworkDevice.h deleted file mode 100644 index 7e4241ce..00000000 --- a/dev/ZKAKit/NetworkKit/NetworkDevice.h +++ /dev/null @@ -1,83 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#ifndef __INC_NETWORK_DEVICE_H__ -#define __INC_NETWORK_DEVICE_H__ - -#include -#include - -/// @note Can either work with: Ethernet, GPRS, WiFi - -namespace Kernel -{ - struct NetworkDeviceCommand; - class NetworkDevice; - - /** - * \brief Network device interface, establishes a connection to the NIC. - */ - class NetworkDevice final : public IDeviceObject - { - public: - NetworkDevice(void (*out)(NetworkDeviceCommand), - void (*in)(NetworkDeviceCommand), - void (*onCleanup)(void) = nullptr); - - ~NetworkDevice() override; - - public: - NetworkDevice& operator=(const NetworkDevice&) = default; - NetworkDevice(const NetworkDevice&) = default; - - public: - const Char* Name() const override; - Boolean Name(const Char* newStr); - - private: - static constexpr auto cNetworkNameLen = 512; - - Void (*fCleanup)(void); - Char fNetworkName[cNetworkNameLen]; - }; - - struct NetworkDeviceCommand final - { - UInt32 CommandName; - UInt32 CommandType; - UInt32 CommandFlags; - VoidPtr CommandBuffer; - SizeT CommandSizeBuffer; - }; - - /// @brief TCP device. - using TCPNetworkDevice = NetworkDevice; - - /// @brief UDP device. - using UDPNetworkDevice = NetworkDevice; - - /// @brief PPP device. - using PPPNetworkDevice = NetworkDevice; - - /// @brief IPC device. - using IPCEPNetworkDevice = NetworkDevice; - - /// @brief GRPS device. - using GPRSNetworkDevice = NetworkDevice; - - /// @brief GSM device. - using GSMNetworkDevice = NetworkDevice; - - /// @brief Bluetooth device. - using BTNetworkDevice = NetworkDevice; - - /// @brief LTE device. - using LTENetworkDevice = NetworkDevice; -} // namespace Kernel - -#include - -#endif // !__INC_NETWORK_DEVICE_H__ diff --git a/dev/ZKAKit/NetworkKit/NetworkDevice.inl b/dev/ZKAKit/NetworkKit/NetworkDevice.inl deleted file mode 100644 index 3c8e8ef9..00000000 --- a/dev/ZKAKit/NetworkKit/NetworkDevice.inl +++ /dev/null @@ -1,32 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -/*** - Dtor and ctors. -*/ - -namespace Kernel -{ - NetworkDevice::NetworkDevice(void (*out)(NetworkDeviceCommand), - void (*in)(NetworkDeviceCommand), - void (*on_cleanup)(void)) - : IDeviceObject(out, in), fCleanup(on_cleanup) - { - kcout << "NetworkDevice initialized.\r"; - - MUST_PASS(out && in && on_cleanup); - } - - NetworkDevice::~NetworkDevice() - { - MUST_PASS(fCleanup); - - kcout << "NetworkDevice cleanup.\r"; - - if (fCleanup) - fCleanup(); - } -} // namespace Kernel diff --git a/dev/ZKAKit/NewKit/Array.h b/dev/ZKAKit/NewKit/Array.h deleted file mode 100644 index 496a115c..00000000 --- a/dev/ZKAKit/NewKit/Array.h +++ /dev/null @@ -1,72 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include -#include -#include - -namespace Kernel -{ - template - class Array final - { - public: - explicit Array() = default; - ~Array() = default; - - Array& operator=(const Array&) = default; - Array(const Array&) = default; - - T& operator[](const SizeT& At) - { - return fArray[At]; - } - - T Assign(const SizeT& At, T NewVal) - { - fArray[At] = NewVal; - return fArray[At]; - } - - Boolean Empty() - { - return this->Count() > 0; - } - - const SizeT Capacity() - { - return N; - } - - const SizeT Count() - { - SizeT count = 0; - - for (SizeT i = 0; i < N; i++) - { - if (fArray[i]) - ++count; - } - - return count; - } - - const T* CData() - { - return fArray; - } - - operator bool() - { - return !Empty(); - } - - private: - T fArray[N]; - }; -} // namespace Kernel diff --git a/dev/ZKAKit/NewKit/ArrayList.h b/dev/ZKAKit/NewKit/ArrayList.h deleted file mode 100644 index cda60c21..00000000 --- a/dev/ZKAKit/NewKit/ArrayList.h +++ /dev/null @@ -1,58 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include - -namespace Kernel -{ - template - class ArrayList final - { - public: - explicit ArrayList(T* list) - : fList(reinterpret_cast(list)) - { - } - - ~ArrayList() = default; - - ArrayList& operator=(const ArrayList&) = default; - ArrayList(const ArrayList&) = default; - - T* Data() - { - return fList; - } - - const T* CData() - { - return fList; - } - - T& operator[](int index) const - { - return fList[index]; - } - - operator bool() - { - return fList; - } - - private: - T* fList; - - friend class InitHelpers; - }; - - template - ArrayList make_list(ValueType val) - { - return ArrayList{val}; - } -} // namespace Kernel diff --git a/dev/ZKAKit/NewKit/Atom.h b/dev/ZKAKit/NewKit/Atom.h deleted file mode 100644 index 62eae414..00000000 --- a/dev/ZKAKit/NewKit/Atom.h +++ /dev/null @@ -1,46 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ -#pragma once - -#include - -namespace Kernel -{ - template - class Atom final - { - public: - explicit Atom() = default; - ~Atom() = default; - - public: - Atom& operator=(const Atom&) = delete; - Atom(const Atom&) = delete; - - public: - T operator[](Size sz) - { - return (fArrayOfAtoms & sz); - } - void operator|(Size sz) - { - fArrayOfAtoms |= sz; - } - - friend Boolean operator==(Atom& atomic, const T& idx) - { - return atomic[idx] == idx; - } - - friend Boolean operator!=(Atom& atomic, const T& idx) - { - return atomic[idx] == idx; - } - - private: - T fArrayOfAtoms; - }; -} // namespace Kernel diff --git a/dev/ZKAKit/NewKit/Crc32.h b/dev/ZKAKit/NewKit/Crc32.h deleted file mode 100644 index 1d36a2d9..00000000 --- a/dev/ZKAKit/NewKit/Crc32.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * ======================================================== - * - * ZKA - * Date Added: 13/02/2023 - * Copyright (C) 2024, Theater Quality Inc, all rights reserved., all rights reserved. - * - * ======================================================== - */ - -#ifndef CRC32_H -#define CRC32_H - -#include - -#define kCrcCnt (256) - -namespace Kernel -{ - UInt ke_calculate_crc32(const Char* crc, UInt len) noexcept; -} // namespace Kernel - -#endif // !CRC32_H diff --git a/dev/ZKAKit/NewKit/CxxAbi.h b/dev/ZKAKit/NewKit/CxxAbi.h deleted file mode 100644 index 5e8cdc8c..00000000 --- a/dev/ZKAKit/NewKit/CxxAbi.h +++ /dev/null @@ -1,28 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ -#pragma once - -#include - -#ifndef __TOOLCHAINKIT__ - -#define kAtExitMacDestructors (128) - -struct atexit_func_entry_t -{ - void (*destructor_func)(void*); - void* obj_ptr; - void* dso_handle; -}; - -typedef unsigned uarch_t; - -namespace cxxabiv1 -{ - typedef void* __guard; -} - -#endif // __GNUC__ diff --git a/dev/ZKAKit/NewKit/Defines.h b/dev/ZKAKit/NewKit/Defines.h deleted file mode 100644 index 4f0fa4bc..00000000 --- a/dev/ZKAKit/NewKit/Defines.h +++ /dev/null @@ -1,186 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include - -#define NEWKIT_VERSION_STR "1.1.0" -#define NEWKIT_VERSION_BCD 0x01100 - -#ifdef __has_feature -#if !__has_feature(cxx_nullptr) -#if !__has_nullptr -#error !!! You must at least have nullptr featured on your C++ compiler. !!! -#endif -#endif -#endif - -/// @brief The **Kernel** namespace where it's API resides. -namespace Kernel -{ - using voidPtr = void*; - using VoidPtr = void*; - using nullPtr = decltype(nullptr); - using NullPtr = decltype(nullptr); - - using Int = int; - using Int32 = int; - using UShort = unsigned short; - using UInt16 = unsigned short; - using Short = short; - using Int16 = short; - using UInt = unsigned int; - using UInt32 = unsigned int; - using Long = __INT64_TYPE__; - using Int64 = __INT64_TYPE__; - using ULong = __UINT64_TYPE__; - using UInt64 = __UINT64_TYPE__; - using Boolean = bool; - using Bool = bool; - using Char = char; - using UChar = unsigned char; - using UInt8 = unsigned char; - - using SSize = Int64; - using SSizeT = Int64; - using Size = __SIZE_TYPE__; - using SizeT = __SIZE_TYPE__; - using IntPtr = __INTPTR_TYPE__; - using UIntPtr = __UINTPTR_TYPE__; - using IntFast = __INT_FAST32_TYPE__; - using IntFast64 = __INT_FAST64_TYPE__; - using PtrDiff = __PTRDIFF_TYPE__; - - using SInt16 = Int16; - using SInt32 = Int32; - using SInt64 = Int64; - - typedef UIntPtr* Ptr64; - typedef UInt32* Ptr32; - typedef UInt8* Ptr8; - - using Utf8Char = char8_t; - using Utf16Char = char16_t; - using WideChar = wchar_t; - using Utf32Char = char32_t; - - typedef UInt32 PhysicalAddressKind; - typedef UIntPtr VirtualAddressKind; - - using Void = void; - - using Lba = UInt64; - - enum class Endian : UInt8 - { - kEndianInvalid, - kEndianBig, - kEndianLittle, - kEndianMixed, - kEndianCount - }; - - /// @brief Forward object. - /// @tparam Args the object type. - /// @param arg the object. - /// @return object's rvalue - template - inline Args&& forward(Args& arg) - { - return static_cast(arg); - } - - /// @brief Move object. - /// @tparam Args the object type. - /// @param arg the object. - /// @return object's rvalue - template - inline Args&& move(Args&& arg) - { - return static_cast(arg); - } - - /// @brief Encoding interface, used as a proxy to convert T to Char* - /// Used to cast A to B or B to A. - class ICodec - { - public: - explicit ICodec() = default; - virtual ~ICodec() = default; - - ICodec& operator=(const ICodec&) = default; - ICodec(const ICodec&) = default; - - public: - /// @brief Convert type to bytes. - /// @tparam T the type. - /// @param type (a1) the data. - /// @return a1 as Char* - template - Char* AsBytes(T type) noexcept - { - return nullptr; - } - - /// @brief Construct from type to class. - /// @tparam T the type to convert. - /// @param type (a1) the data. - /// @return a1 as Char* - template - OutputClass* Construct(Char* type) noexcept - { - FactoryClass class_fac; - return class_fac.template From(type); - } - - /// @brief Convert T class to Y class. - /// @tparam T the class type of type. - /// @tparam Y the result class. - /// @param type the class to cast. - /// @return the class as Y. - template - Y As(T type) noexcept - { - if (type.template IsSerializable()) - { - return reinterpret_cast(type); - } - - return type.template As(); - } - }; - - /// \brief Scheduler interface, represents a scheduler object. - /// @note This is used to schedule tasks, such as threads, drivers, user threads, etc. - class ISchedulable - { - public: - explicit ISchedulable() = default; - virtual ~ISchedulable() = default; - - ISchedulable& operator=(const ISchedulable&) = default; - ISchedulable(const ISchedulable&) = default; - - /// @brief Is this object only accepting user tasks? - virtual const Bool IsUser() - { - return NO; - } - - /// @brief Is this object only accepting kernel tasks? - virtual const Bool IsKernel() - { - return NO; - } - - /// @brief Is this object offloading to another CPU? - virtual const Bool HasMP() - { - return NO; - } - }; -} // namespace Kernel diff --git a/dev/ZKAKit/NewKit/ErrorOr.h b/dev/ZKAKit/NewKit/ErrorOr.h deleted file mode 100644 index 59717954..00000000 --- a/dev/ZKAKit/NewKit/ErrorOr.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * ======================================================== - * - * ZKA - * Copyright (C) 2024, Theater Quality Inc, all rights reserved., all rights reserved. - * - * ======================================================== - */ - -#pragma once - -#include -#include - -namespace Kernel -{ - using ErrorT = UInt; - - template - class ErrorOr final - { - public: - ErrorOr() = default; - ~ErrorOr() = default; - - public: - explicit ErrorOr(Int32 err) - : mId(err) - { - } - - explicit ErrorOr(nullPtr Null) - { - } - - explicit ErrorOr(T* Class) - : mRef(Class) - { - } - - explicit ErrorOr(T Class) - : mRef(Class) - { - } - - ErrorOr& operator=(const ErrorOr&) = default; - ErrorOr(const ErrorOr&) = default; - - ErrorOr& operator=(const Ref& refErr) - { - mRef = refErr; - return *this; - } - - Ref& Leak() - { - return mRef; - } - - Int32 Error() - { - return mId; - } - - operator bool() - { - return mRef; - } - - private: - Ref mRef; - Int32 mId{0}; - }; - - using ErrorOrAny = ErrorOr; - -} // namespace Kernel diff --git a/dev/ZKAKit/NewKit/Function.h b/dev/ZKAKit/NewKit/Function.h deleted file mode 100644 index 9fa218af..00000000 --- a/dev/ZKAKit/NewKit/Function.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef _INC_FUNCTION_H__ -#define _INC_FUNCTION_H__ - -#include - -namespace Kernel -{ - template - class Function final - { - public: - Function() = default; - - public: - explicit Function(T (*Fn)(Args... args)) - : fFn(Fn) - { - } - - ~Function() = default; - - Function& operator=(const Function&) = default; - Function(const Function&) = default; - - template - T operator()(Args... args) - { - return fFn(args...); - } - - template - T Call(Args... args) - { - return fFn(args...); - } - - operator bool() - { - return fFn; - } - - bool operator!() - { - return !fFn; - } - - private: - T(*fFn) - (Args... args); - }; -} // namespace Kernel - -#endif // !_INC_FUNCTION_H__ diff --git a/dev/ZKAKit/NewKit/Json.h b/dev/ZKAKit/NewKit/Json.h deleted file mode 100644 index 9e286e63..00000000 --- a/dev/ZKAKit/NewKit/Json.h +++ /dev/null @@ -1,151 +0,0 @@ - -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -// last-rev: 30/01/24 - -#include -#include -#include -#include -#include - -#define kMaxJsonPath 4096 -#define kJSONLen 32 -#define kJSONNull "null" - -namespace Kernel -{ - /// @brief Json class - class JSON final - { - public: - explicit JSON() - { - auto len = kJSONLen; - KString key = KString(len); - key += kJSONNull; - - this->AsKey() = key; - this->AsValue() = key; - } - - explicit JSON(SizeT lhsLen, SizeT rhsLen) - : fKey(lhsLen), fValue(rhsLen) - { - } - - ~JSON() = default; - - ZKA_COPY_DEFAULT(JSON); - - const Bool& IsUndefined() - { - return fUndefined; - } - - private: - Bool fUndefined; // is this instance undefined? - KString fKey; - KString fValue; - - public: - /// @brief returns the key of the json - /// @return the key as string view. - KString& AsKey() - { - return fKey; - } - - /// @brief returns the value of the json. - /// @return the key as string view. - KString& AsValue() - { - return fValue; - } - - static JSON kNull; - }; - - /// @brief Json stream reader helper. - struct JsonStreamReader final - { - STATIC JSON In(const Char* full_array) - { - auto start_val = '{'; - auto end_val = '}'; - Boolean probe_value = false; - - if (full_array[0] != start_val) - { - if (full_array[0] != '[') - return JSON::kNull; - - start_val = '['; - end_val = ']'; - - probe_value = true; - } - - SizeT len = rt_string_len(full_array); - - SizeT key_len = 0; - SizeT value_len = 0; - - JSON type(kMaxJsonPath, kMaxJsonPath); - - for (SizeT i = 1; i < len; ++i) - { - if (full_array[i] == '\r' || - full_array[i] == '\n') - continue; - - if (probe_value) - { - if (full_array[i] == end_val || - full_array[i] == ',') - { - probe_value = false; - - ++value_len; - } - else - { - type.AsValue().Data()[value_len] = full_array[i]; - - ++value_len; - } - } - else - { - if (start_val == '[') - continue; - - if (full_array[i] == ':') - { - probe_value = true; - type.AsKey().Data()[key_len] = 0; - ++key_len; - } - else - { - type.AsKey().Data()[key_len] = full_array[i]; - - ++key_len; - } - } - } - - type.AsValue().Data()[value_len] = 0; - - return type; - } - }; - - using JsonStream = Stream; -} // namespace Kernel diff --git a/dev/ZKAKit/NewKit/KString.h b/dev/ZKAKit/NewKit/KString.h deleted file mode 100644 index a7020a10..00000000 --- a/dev/ZKAKit/NewKit/KString.h +++ /dev/null @@ -1,94 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include -#include -#include -#include -#include - -#define cMinimumStringSize 8196 - -namespace Kernel -{ - /// @brief KString static string class. - class KString final - { - public: - explicit KString() - { - fDataSz = cMinimumStringSize; - - fData = new Char[fDataSz]; - MUST_PASS(fData); - - rt_set_memory(fData, 0, fDataSz); - } - - explicit KString(const SizeT& Sz) - : fDataSz(Sz) - { - MUST_PASS(Sz > 1); - - fData = new Char[Sz]; - MUST_PASS(fData); - - rt_set_memory(fData, 0, Sz); - } - - ~KString() - { - if (fData) - { - delete[] fData; - fData = nullptr; - } - } - - ZKA_COPY_DEFAULT(KString); - - Char* Data(); - const Char* CData() const; - Size Length() const; - - bool operator==(const Char* rhs) const; - bool operator!=(const Char* rhs) const; - - bool operator==(const KString& rhs) const; - bool operator!=(const KString& rhs) const; - - KString& operator+=(const Char* rhs); - KString& operator+=(const KString& rhs); - - operator bool() - { - return fData; - } - - bool operator!() - { - return fData; - } - - private: - Char* fData{nullptr}; - Size fDataSz{0}; - Size fCur{0}; - - friend class StringBuilder; - }; - - struct StringBuilder final - { - static ErrorOr Construct(const Char* data); - static const Char* FromBool(const Char* fmt, bool n); - static const Char* Format(const Char* fmt, const Char* from); - static bool Equals(const Char* lhs, const Char* rhs); - static bool Equals(const WideChar* lhs, const WideChar* rhs); - }; -} // namespace Kernel diff --git a/dev/ZKAKit/NewKit/Macros.h b/dev/ZKAKit/NewKit/Macros.h deleted file mode 100644 index 15f7fe26..00000000 --- a/dev/ZKAKit/NewKit/Macros.h +++ /dev/null @@ -1,149 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#ifndef KIB -#define KIB(X) (Kernel::UInt64)((X) / 1024) -#endif - -#ifndef kib_cast -#define kib_cast(X) (Kernel::UInt64)((X)*1024) -#endif - -#ifndef MIB -#define MIB(X) (Kernel::UInt64)((Kernel::UInt64)KIB(X) / 1024) -#endif - -#ifndef mib_cast -#define mib_cast(X) (Kernel::UInt64)((Kernel::UInt64)kib_cast(X) * 1024) -#endif - -#ifndef GIB -#define GIB(X) (Kernel::UInt64)((Kernel::UInt64)MIB(X) / 1024) -#endif - -#ifndef gib_cast -#define gib_cast(X) (Kernel::UInt64)((Kernel::UInt64)mib_cast(X) * 1024) -#endif - -#ifndef TIB -#define TIB(X) (Kernel::UInt64)((Kernel::UInt64)GIB(X) / 1024) -#endif - -#ifndef tib_cast -#define tib_cast(X) ((Kernel::UInt64)gib_cast(X) * 1024) -#endif - -#ifndef ARRAY_SIZE -#define ARRAY_SIZE(a) \ - (((sizeof(a) / sizeof(*(a))) / \ - (static_cast(!(sizeof(a) % sizeof(*(a))))))) -#endif - -#define DEPRECATED ATTRIBUTE(deprecated) - -#ifndef ALIGN -#define ALIGN(X) __attribute__((aligned(X))) -#endif // #ifndef ALIGN - -#ifndef ATTRIBUTE -#define ATTRIBUTE(X) __attribute__((X)) -#endif // #ifndef ATTRIBUTE - -#ifndef __ZKA_VER__ -#define __ZKA_VER__ (2024) -#endif // !__ZKA_VER__ - -#ifndef EXTERN -#define EXTERN extern -#endif - -#ifndef EXTERN_C -#define EXTERN_C extern "C" -#endif - -#ifndef MAKE_ENUM -#define MAKE_ENUM(NAME) \ - enum NAME \ - { -#endif - -#ifndef END_ENUM -#define END_ENUM() \ - } \ - ; -#endif - -#ifndef MAKE_STRING_ENUM -#define MAKE_STRING_ENUM(NAME) \ - namespace NAME \ - { -#endif - -#ifndef ENUM_STRING -#define ENUM_STRING(NAME, VAL) inline constexpr const char* e##NAME = VAL -#endif - -#ifndef END_STRING_ENUM -#define END_STRING_ENUM() } -#endif - -#ifndef rtl_alloca -#define rtl_alloca(sz) __builtin_alloca(sz) -#endif // #ifndef rtl_alloca - -#ifndef CANT_REACH -#define CANT_REACH() __builtin_unreachable() -#endif - -#define kInvalidAddress 0xFBFBFBFBFBFBFBFB -#define kBadAddress 0x0000000000000000 -#define kMaxAddr 0xFFFFFFFFFFFFFFFF -#define kPathLen 0x100 - -#define PACKED ATTRIBUTE(packed) -#define NO_EXEC ATTRIBUTE(noexec) - -#define EXTERN extern -#define STATIC static - -#define CONST const - -#define STRINGIFY(X) #X -#define ZKA_UNUSED(X) ((Kernel::Void)X) - -#ifndef RGB -#define RGB(R, G, B) (Kernel::UInt32)(R | G << 0x8 | B << 0x10) -#endif // !RGB - -#ifdef __ZKA_AMD64__ -#define dbg_break_point() asm volatile("int $3") -#else -#define dbg_break_point() ((void)0) -#endif - -#define rtl_deduce_endianess(address, value) \ - (((reinterpret_cast(address)[0]) == (value)) \ - ? (Kernel::Endian::kEndianBig) \ - : (Kernel::Endian::kEndianLittle)) - -#define Yes true -#define No false - -#define YES true -#define NO false - -#define TRUE true -#define FALSE false - -#define BOOL Kernel::Boolean - -#ifdef INIT_OBJECT -#undef INIT_OBJECT -#endif // ifdef INIT_OBJECT - -#define INIT_OBJECT(OBJ, TYPE, ...) TYPE OBJ = TYPE(__VA_ARGS__) diff --git a/dev/ZKAKit/NewKit/MutableArray.h b/dev/ZKAKit/NewKit/MutableArray.h deleted file mode 100644 index 53d79819..00000000 --- a/dev/ZKAKit/NewKit/MutableArray.h +++ /dev/null @@ -1,239 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ -#pragma once - -#include -#include -#include - -#define TRY_FIND_NODE(NAME, NODE) \ - auto* NAME = NODE; \ - while (NAME) \ - { \ - if (NAME->fIndex == Index) \ - return NAME->fVal; \ - NAME = NAME->fNext; \ - } - -#define TRY_FIND_NODE2(NAME, NODE) \ - auto* NAME = NODE; \ - while (NAME) \ - { \ - if (NAME->fIndex == Index) \ - return Ref{NAME->fVal}; \ - NAME = NAME->fNext; \ - } - -#define TRY_REMOVE_NODE(NODE) \ - if (NODE && NODE->fIndex == Index) \ - { \ - NODE->fUsed = false; \ - NODE->fIndex = 0; \ - \ - return true; \ - } - -// FIXME: this is a shitty algorithm, which is consumer hungry. -// Remove and occurences of that, and remove that class. -namespace Kernel -{ - template - class MutableArray; - - template - class NullableMutableArray; - - template - class MutableLinkedList - { - public: - T fVal; - SizeT fIndex{0}; - Boolean fUsed{false}; - - MutableLinkedList* fPrev{nullptr}; - MutableLinkedList* fNext{nullptr}; - }; - - template - class NullableMutableArray - { - public: - // explicit this. - explicit NullableMutableArray() - : fFirstNode(new MutableLinkedList()) - { - } - - /* - * We free all the nodes allocated by the array - * and store the next one inside "NextIt" - */ - - virtual ~NullableMutableArray() - { - auto* It = fFirstNode; - MutableLinkedList* NextIt = nullptr; - - while (It) - { - NextIt = It->fNext; - delete It; - - It = NextIt; - } - } - - NullableMutableArray& operator=(const NullableMutableArray&) = default; - NullableMutableArray(const NullableMutableArray&) = default; - - operator bool() - { - return Count() > 1; - } - - public: - T operator[](const SizeT& Index) const - { - TRY_FIND_NODE(first, fFirstNode); - TRY_FIND_NODE(last, fLastNode); - - return _PlaceHolderValue; - } - - SizeT Count() const - { - return fNodeCount; - } - - public: - Boolean Remove(const SizeT& Index) - { - TRY_REMOVE_NODE(fFirstNode); - TRY_REMOVE_NODE(fLastNode); - - return false; - } - - Boolean Add(const T val) - { - auto* iterationNode = fFirstNode; - MUST_PASS(iterationNode); - - while (iterationNode) - { - if (!iterationNode->fUsed) - { - iterationNode->fVal = val; - iterationNode->fIndex = 0; - - iterationNode->fUsed = true; - - ++fNodeCount; - - return true; - } - - iterationNode = iterationNode->fNext; - } - - return false; - } - - private: - /* Avoid useless lookups */ - MutableLinkedList* fLastNode{nullptr}; - MutableLinkedList* fFirstNode{nullptr}; - - /* Number of nodes inside of this dynamic array. */ - Kernel::SizeT fNodeCount{0}; - - private: - // don't remove that - friend MutableArray; - }; - - template - class MutableArray : public NullableMutableArray - { - public: - // explicit this. - explicit MutableArray() = default; - virtual ~MutableArray() = default; - - ZKA_COPY_DEFAULT(MutableArray) - - public: - Boolean Add(const T val) - { - auto* iterationNode = fFirstNode; - - if (!iterationNode) - { - fFirstNode = new MutableLinkedList(); - iterationNode = fFirstNode; - } - - MUST_PASS(iterationNode); - - while (iterationNode) - { - if (!iterationNode->fUsed) - { - iterationNode->fVal = val; - iterationNode->fIndex = 0; - - iterationNode->fUsed = true; - - ++fNodeCount; - - return true; - } - - iterationNode = iterationNode->fNext; - } - - return false; - } - - public: - Ref operator[](const SizeT& Index) const - { - TRY_FIND_NODE2(first, fFirstNode); - TRY_FIND_NODE2(last, fLastNode); - - return {}; - } - - SizeT Count() const - { - return fNodeCount; - } - - bool Contains(T& value) noexcept - { - MutableLinkedList* first = fFirstNode; - - while (first) - { - if (first->fVal == value && first->fUsed) - return true; - - first = first->fNext; - } - - return false; - } - - private: - /* Avoid useless lookups */ - MutableLinkedList* fLastNode{nullptr}; - MutableLinkedList* fFirstNode{nullptr}; - - /* Number of nodes inside of this dynamic array. */ - Kernel::SizeT fNodeCount{0}; - }; -} // namespace Kernel diff --git a/dev/ZKAKit/NewKit/New.h b/dev/ZKAKit/NewKit/New.h deleted file mode 100644 index eb6c33e4..00000000 --- a/dev/ZKAKit/NewKit/New.h +++ /dev/null @@ -1,18 +0,0 @@ - -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ -#pragma once - -#include - -typedef __SIZE_TYPE__ size_t; // gcc will complain about that - -void* operator new(size_t ptr); -void* operator new[](size_t ptr); - -void operator delete(void* ptr); -void operator delete(void* ptr, unsigned long); -void operator delete[](void* ptr); diff --git a/dev/ZKAKit/NewKit/NewKit.h b/dev/ZKAKit/NewKit/NewKit.h deleted file mode 100644 index e17c3465..00000000 --- a/dev/ZKAKit/NewKit/NewKit.h +++ /dev/null @@ -1,20 +0,0 @@ - -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include diff --git a/dev/ZKAKit/NewKit/OwnPtr.h b/dev/ZKAKit/NewKit/OwnPtr.h deleted file mode 100644 index 36d1cdea..00000000 --- a/dev/ZKAKit/NewKit/OwnPtr.h +++ /dev/null @@ -1,94 +0,0 @@ - -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include -#include -#include - -namespace Kernel -{ - template - class OwnPtr; - - template - class NonNullRefPtr; - - template - class OwnPtr final - { - public: - OwnPtr() - { - } - ~OwnPtr() - { - this->Delete(); - } - - OwnPtr& operator=(const OwnPtr&) = default; - OwnPtr(const OwnPtr&) = default; - - public: - template - bool New(Args&&... arg) - { - if (fCls) - { - return false; - } - - fCls = new T(arg...); - return fCls; - } - - void Delete() - { - if (fCls) - delete fCls; - - fCls = nullptr; - } - - T* operator->() const - { - return fCls; - }; - T* Raw() - { - return fCls; - } - - Ref AsRef() - { - return Ref(fCls); - } - - operator bool() - { - return fCls; - } - bool operator!() - { - return !fCls; - } - - private: - T* fCls; - }; - - template - OwnPtr make_ptr(Args... args) - { - OwnPtr ret; - ret.template New(forward(args)...); - MUST_PASS(ret); - - return ret; - } -} // namespace Kernel diff --git a/dev/ZKAKit/NewKit/PageMgr.h b/dev/ZKAKit/NewKit/PageMgr.h deleted file mode 100644 index 225842c9..00000000 --- a/dev/ZKAKit/NewKit/PageMgr.h +++ /dev/null @@ -1,81 +0,0 @@ -// a way to create and find our pages. -// I'm thinking about a separate way of getting a paged area. - -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include -#include - -namespace Kernel -{ - class PageMgr; - - class PTEWrapper final - { - public: - explicit PTEWrapper(Boolean Rw = false, Boolean User = false, Boolean ExecDisable = false, UIntPtr Address = 0); - - ~PTEWrapper(); - - PTEWrapper& operator=(const PTEWrapper&) = default; - PTEWrapper(const PTEWrapper&) = default; - - public: - const UIntPtr VirtualAddress(); - - Void NoExecute(const bool enable = false); - Bool NoExecute(); - - operator bool() - { - return fVirtAddr; - } - - bool Reclaim(); - bool Shareable(); - bool Present(); - bool Access(); - - private: - Boolean fRw; - Boolean fUser; - Boolean fExecDisable; - UIntPtr fVirtAddr; - Boolean fCache; - Boolean fShareable; - Boolean fWt; - Boolean fPresent; - Boolean fAccessed; - - private: - friend class PageMgr; - friend class Pmm; - }; - - struct PageMgr final - { - public: - PageMgr() = default; - ~PageMgr() = default; - - PageMgr& operator=(const PageMgr&) = default; - PageMgr(const PageMgr&) = default; - - public: - PTEWrapper Request(Boolean Rw, Boolean User, Boolean ExecDisable, SizeT Sz); - bool Free(Ref& wrapper); - - private: - void FlushTLB(); - - private: - friend PTEWrapper; - friend class Pmm; - }; -} // namespace Kernel diff --git a/dev/ZKAKit/NewKit/Pair.h b/dev/ZKAKit/NewKit/Pair.h deleted file mode 100644 index 117bc1ac..00000000 --- a/dev/ZKAKit/NewKit/Pair.h +++ /dev/null @@ -1,14 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include - -namespace Kernel -{ - class Pair; -} // namespace Kernel diff --git a/dev/ZKAKit/NewKit/Pmm.h b/dev/ZKAKit/NewKit/Pmm.h deleted file mode 100644 index 1852c429..00000000 --- a/dev/ZKAKit/NewKit/Pmm.h +++ /dev/null @@ -1,44 +0,0 @@ - -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include -#include - -namespace Kernel -{ - class Pmm; - class PTEWrapper; - - class Pmm final - { - public: - explicit Pmm(); - ~Pmm(); - - Pmm& operator=(const Pmm&) = delete; - Pmm(const Pmm&) = default; - - Ref RequestPage(Boolean user = false, Boolean readWrite = false); - Boolean FreePage(Ref refPage); - - Boolean ToggleRw(Ref refPage, Boolean enable = true); - Boolean TogglePresent(Ref refPage, Boolean enable = true); - Boolean ToggleUser(Ref refPage, Boolean enable = true); - Boolean ToggleShare(Ref refPage, Boolean enable = true); - - /// @brief Get the page manager of this. - Ref& Leak() - { - return fPageMgr; - } - - private: - Ref fPageMgr; - }; -} // namespace Kernel diff --git a/dev/ZKAKit/NewKit/Ref.h b/dev/ZKAKit/NewKit/Ref.h deleted file mode 100644 index 75500693..00000000 --- a/dev/ZKAKit/NewKit/Ref.h +++ /dev/null @@ -1,108 +0,0 @@ - -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#ifndef _NEWKIT_REF_H_ -#define _NEWKIT_REF_H_ - -#include -#include -#include - -namespace Kernel -{ - template - class Ref final - { - public: - Ref() = default; - - ~Ref() - { - if (mm_is_valid_heap(fClass)) - delete fClass; - } - - public: - Ref(T* cls) - : fClass(cls) - { - } - - Ref(T cls) - : fClass(&cls) - { - } - - Ref& operator=(T ref) - { - if (!fClass) - return *this; - - fClass = &ref; - return *this; - } - - public: - T operator->() const - { - MUST_PASS(*fClass); - return *fClass; - } - - T& Leak() noexcept - { - return *fClass; - } - - T& TryLeak() const noexcept - { - MUST_PASS(*fClass); - return *fClass; - } - - T operator*() - { - return *fClass; - } - - operator bool() noexcept - { - return fClass; - } - - private: - T* fClass{nullptr}; - }; - - template - class NonNullRef final - { - public: - NonNullRef() = delete; - NonNullRef(nullPtr) = delete; - - NonNullRef(T* ref) - : fRef(ref) - { - MUST_PASS(ref); - } - - Ref& operator->() - { - MUST_PASS(fRef); - return fRef; - } - - NonNullRef& operator=(const NonNullRef& ref) = delete; - NonNullRef(const NonNullRef& ref) = default; - - private: - Ref fRef{nullptr}; - }; -} // namespace Kernel - -#endif // ifndef _NEWKIT_REF_H_ diff --git a/dev/ZKAKit/NewKit/Stop.h b/dev/ZKAKit/NewKit/Stop.h deleted file mode 100644 index 0d7bf27b..00000000 --- a/dev/ZKAKit/NewKit/Stop.h +++ /dev/null @@ -1,71 +0,0 @@ - -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include - -namespace Kernel -{ - void ke_runtime_check(bool bExpression, const Char* file, const Char* line); -} - -#define MUST_PASS_COMPILER(EXPR, MSG) static_assert(EXPR, MSG) - -#define __MUST_PASS(EXPR, FILE, LINE) \ - Kernel::ke_runtime_check(EXPR, FILE, STRINGIFY(LINE)) - -#ifdef __DEBUG__ -#define MUST_PASS(EXPR) __MUST_PASS((EXPR), __FILE__, __LINE__) -#define assert(EXPR) MUST_PASS(EXPR, RUNTIME_CHECK_EXPRESSION) -#else -#define MUST_PASS(EXPR) (Kernel::Void)(EXPR) -#define assert(EXPR) (Kernel::Void)(EXPR) -#endif - -enum RUNTIME_CHECK -{ - RUNTIME_CHECK_FAILED = -1, - RUNTIME_CHECK_POINTER = 0, - RUNTIME_CHECK_EXPRESSION, - RUNTIME_CHECK_FILE, - RUNTIME_CHECK_IPC, - RUNTIME_CHECK_TLS, - RUNTIME_CHECK_HANDSHAKE, - RUNTIME_CHECK_ACPI, - RUNTIME_CHECK_INVALID_PRIVILEGE, - RUNTIME_CHECK_PROCESS, - RUNTIME_CHECK_BAD_BEHAVIOR, - RUNTIME_CHECK_BOOTSTRAP, - RUNTIME_CHECK_UNEXCPECTED, - RUNTIME_CHECK_FILESYSTEM, - RUNTIME_CHECK_VIRTUAL_OUT_OF_MEM, - RUNTIME_CHECK_PAGE, - RUNTIME_CHECK_COUNT, -}; - -namespace Kernel -{ - /// @brief Dumping factory class. - class RecoveryFactory final - { - public: - STATIC Void Recover() noexcept; - }; - - void ke_stop(const Int32& id); -} // namespace Kernel - -#ifdef TRY -#undef TRY -#endif - -#define TRY(FN) \ - if (!FN()) \ - { \ - MUST_PASS(false); \ - } diff --git a/dev/ZKAKit/NewKit/Stream.h b/dev/ZKAKit/NewKit/Stream.h deleted file mode 100644 index b0ebaa5a..00000000 --- a/dev/ZKAKit/NewKit/Stream.h +++ /dev/null @@ -1,58 +0,0 @@ - -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include -#include - -namespace Kernel -{ - template - class Stream final - { - public: - explicit Stream(Ref ref) - : fStream(ref) - { - } - - ~Stream() = default; - - Stream& operator=(const Stream&) = default; - Stream(const Stream&) = default; - - template - friend Stream& operator>>(Stream& Ks, Ref& Buf) - { - Ks.fKind = Ks.fStream->In(Buf); - return *Ks; - } - - template - friend Stream& operator<<(Stream& Ks, Ref& Buf) - { - Ks.fKind = Buf; - Ks.fStream->Out(Buf.Leak()); - return *Ks; - } - - Ref& AsStreamTrait() - { - return fStream; - } - - Ref& AsType() - { - return fKind; - } - - private: - Ref fStream; - Ref fKind; - }; -} // namespace Kernel diff --git a/dev/ZKAKit/NewKit/Utils.h b/dev/ZKAKit/NewKit/Utils.h deleted file mode 100644 index 3c72ba8e..00000000 --- a/dev/ZKAKit/NewKit/Utils.h +++ /dev/null @@ -1,29 +0,0 @@ - -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include - -namespace Kernel -{ - Int rt_copy_memory(const voidPtr src, voidPtr dst, Size len); - Int rt_move_memory(const voidPtr src, voidPtr dst, Size len); - voidPtr rt_set_memory(voidPtr dst, UInt32 val, Size len); - void rt_zero_memory(voidPtr pointer, Size len); - Int rt_string_cmp(const Char* src, const Char* cmp, Size len); - const Char* alloc_string(const Char* text); - Size rt_string_len(const Char* str); - Size rt_string_len(const Char* str, SizeT _len); - Boolean rt_to_string(Char* buf, Int limit, Int base); - Boolean is_newln(Char chr); - Boolean is_space(Char chr); - Int rt_to_uppercase(Int c); - Int rt_to_lower(Int c); - voidPtr rt_string_in_string(const Char* in, const Char* needle); - char* rt_string_has_char(Char* str, const Char chr); -} // namespace Kernel diff --git a/dev/ZKAKit/NewKit/Variant.h b/dev/ZKAKit/NewKit/Variant.h deleted file mode 100644 index b604e2c3..00000000 --- a/dev/ZKAKit/NewKit/Variant.h +++ /dev/null @@ -1,70 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include -#include -#include - -namespace Kernel -{ - class Variant final - { - public: - enum class VariantKind - { - kString, - kBlob, - kNull, - kJson, - kXML, - }; - - public: - explicit Variant() = delete; - - public: - ZKA_COPY_DEFAULT(Variant); - - ~Variant() = default; - - public: - explicit Variant(KString* stringView) - : fPtr((VoidPtr)stringView), fKind(VariantKind::kString) - { - } - - explicit Variant(JSON* json) - : fPtr((VoidPtr)json), fKind(VariantKind::kJson) - { - } - - explicit Variant(nullPtr) - : fPtr(nullptr), fKind(VariantKind::kNull) - { - } - - explicit Variant(VoidPtr ptr) - : fPtr(ptr), fKind(VariantKind::kBlob) - { - } - - public: - const Char* ToString(); - VoidPtr Leak(); - - template - T* As() - { - return reinterpret_cast(fPtr); - } - - private: - voidPtr fPtr{nullptr}; - VariantKind fKind{VariantKind::kNull}; - }; -} // namespace Kernel diff --git a/dev/ZKAKit/POSIXKit/signal.h b/dev/ZKAKit/POSIXKit/signal.h deleted file mode 100644 index c47fa392..00000000 --- a/dev/ZKAKit/POSIXKit/signal.h +++ /dev/null @@ -1,20 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -/** https://pubs.opengroup.org/onlinepubs/009695399/basedefs/signal.h.html */ - -#include - -typedef Kernel::UInt32 signal_t; - -#define SIGKILL 0 -#define SIGPAUS 1 -#define SIGEXEC 2 -#define SIGTRAP 3 -#define SIGABRT 4 -#define SIGCONT 5 diff --git a/dev/ZKAKit/POSIXKit/unix_layer.h b/dev/ZKAKit/POSIXKit/unix_layer.h deleted file mode 100644 index dbc576af..00000000 --- a/dev/ZKAKit/POSIXKit/unix_layer.h +++ /dev/null @@ -1,11 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include -#include -#include diff --git a/dev/ZKAKit/ReadMe.md b/dev/ZKAKit/ReadMe.md deleted file mode 100644 index a63661c9..00000000 --- a/dev/ZKAKit/ReadMe.md +++ /dev/null @@ -1,3 +0,0 @@ -# ZKA Minimal Kernel DLL. - -A dll which takes the role of the microKernel image. diff --git a/dev/ZKAKit/StorageKit/AHCI.h b/dev/ZKAKit/StorageKit/AHCI.h deleted file mode 100644 index ca4bcf31..00000000 --- a/dev/ZKAKit/StorageKit/AHCI.h +++ /dev/null @@ -1,33 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include -#include -#include - -namespace Kernel -{ - class AHCIDeviceInterface ZKA_DEVICE - { - public: - explicit AHCIDeviceInterface(void (*Out)(MountpointInterface* outpacket), - void (*In)(MountpointInterface* inpacket), - void (*Cleanup)(void)); - - virtual ~AHCIDeviceInterface(); - - public: - AHCIDeviceInterface& operator=(const AHCIDeviceInterface&) = default; - AHCIDeviceInterface(const AHCIDeviceInterface&) = default; - - const Char* Name() const override; - - private: - void (*fCleanup)(void) = {nullptr}; - }; -} // namespace Kernel diff --git a/dev/ZKAKit/StorageKit/ATA.h b/dev/ZKAKit/StorageKit/ATA.h deleted file mode 100644 index 0a3d2678..00000000 --- a/dev/ZKAKit/StorageKit/ATA.h +++ /dev/null @@ -1,39 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include -#include -#include -#include - -namespace Kernel -{ - /// @brief ATA device interface type. - class ATADeviceInterface : public IDeviceObject - { - public: - explicit ATADeviceInterface(void (*Out)(MountpointInterface* outpacket), - void (*In)(MountpointInterface* inpacket), - void (*Cleanup)(void)); - - virtual ~ATADeviceInterface(); - - public: - ATADeviceInterface& operator<<(MountpointInterface* Data) override; - ATADeviceInterface& operator>>(MountpointInterface* Data) override; - - public: - ATADeviceInterface& operator=(const ATADeviceInterface&) = default; - ATADeviceInterface(const ATADeviceInterface&) = default; - - const Char* Name() const override; - - private: - void (*fCleanup)(void) = {nullptr}; - }; -} // namespace Kernel diff --git a/dev/ZKAKit/StorageKit/NVME.h b/dev/ZKAKit/StorageKit/NVME.h deleted file mode 100644 index 49f4203b..00000000 --- a/dev/ZKAKit/StorageKit/NVME.h +++ /dev/null @@ -1,34 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include -#include - -namespace Kernel -{ - class NVMEDeviceInterface final ZKA_DEVICE - { - public: - explicit NVMEDeviceInterface(Void (*out)(MountpointInterface* out_packet), - Void (*in)(MountpointInterface* in_packet), - Void (*cleanup)(Void)); - - ~NVMEDeviceInterface() override; - - public: - ZKA_COPY_DEFAULT(NVMEDeviceInterface); - - const Char* Name() const override; - - public: - OwnPtr operator()(UInt32 dma_low, UInt32 dma_high, SizeT dma_sz); - - private: - Void (*fCleanup)(Void) = {nullptr}; - }; -} // namespace Kernel diff --git a/dev/ZKAKit/StorageKit/PRDT.h b/dev/ZKAKit/StorageKit/PRDT.h deleted file mode 100644 index 258ba338..00000000 --- a/dev/ZKAKit/StorageKit/PRDT.h +++ /dev/null @@ -1,36 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include -#include -#include - -#define kPrdtTransferSize (sizeof(Kernel::UShort)) - -namespace Kernel -{ - /// @brief Tranfer information about PRD. - enum kPRDTTransfer - { - kPRDTTransferInProgress, - kPRDTTransferIsDone, - kPRDTTransferCount, - }; - - /// @brief Physical Region Descriptor Table. - struct PRDT - { - UInt32 fPhysAddress; - UInt32 fSectorCount; - UInt8 fEndBit; - }; - - void construct_prdt(Ref& prd); - - EXTERN_C Int32 kPRDTTransferStatus; -} // namespace Kernel diff --git a/dev/ZKAKit/StorageKit/SCSI.h b/dev/ZKAKit/StorageKit/SCSI.h deleted file mode 100644 index 0cbb780a..00000000 --- a/dev/ZKAKit/StorageKit/SCSI.h +++ /dev/null @@ -1,11 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include - -extern const scsi_packet_type<12> kCDRomPacketTemplate; diff --git a/dev/ZKAKit/StorageKit/StorageKit.h b/dev/ZKAKit/StorageKit/StorageKit.h deleted file mode 100644 index 83cf4cd2..00000000 --- a/dev/ZKAKit/StorageKit/StorageKit.h +++ /dev/null @@ -1,22 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#define kDriveSectorSizeHDD (512U) -#define kDriveSectorSizeSSD (512U) -#define kDriveSectorSizeOptical (2048) - -namespace Kernel -{ - template - class IDeviceObject; - - class NVMEDeviceInterface; - class AHCIDeviceInterface; - class ATADeviceInterface; - class SCSIDeviceInterface; -} // namespace Kernel diff --git a/dev/ZKAKit/amd64-efi.make b/dev/ZKAKit/amd64-efi.make deleted file mode 100644 index 812bea24..00000000 --- a/dev/ZKAKit/amd64-efi.make +++ /dev/null @@ -1,85 +0,0 @@ -################################################## -# (c) Theater Quality Inc, all rights reserved. -# This is the minoskrnl's makefile. -################################################## - -CC = x86_64-w64-mingw32-g++ -LD = x86_64-w64-mingw32-ld -CCFLAGS = -fshort-wchar -c -D__ZKA_AMD64__ -mno-red-zone -fno-rtti -fno-exceptions \ - -std=c++20 -D__ZKA_SUPPORT_NX__ -O0 -I../Vendor -D__FSKIT_INCLUDES_NEFS__ \ - -D__MINOSKRNL__ -D__HAVE_ZKA_APIS__ -D__FREESTANDING__ -D__ZKA__ -I./ -I../ -I../zba - -ASM = nasm - -DISK_DRV = - -ifneq ($(ATA_PIO_SUPPORT), ) -DISK_DRV = -D__ATA_PIO__ -endif - -ifneq ($(ATA_DMA_SUPPORT), ) -DISK_DRV = -D__ATA_DMA__ -endif - -ifneq ($(AHCI_SUPPORT), ) -DISK_DRV = -D__AHCI__ -endif - -ifneq ($(DEBUG_SUPPORT), ) -DEBUG_MACRO = -D__DEBUG__ -endif - -COPY = cp - -# Add assembler, linker, and object files variables. -ASMFLAGS = -f win64 - -# Kernel subsystem is 17 and entrypoint is hal_init_platform -LDFLAGS = -e hal_init_platform --subsystem=17 --image-base 0x4000000 -LDOBJ = obj/*.obj - -# This file is the Kernel, responsible of task, memory, driver, sci, disk and device management. -KERNEL_IMG = minoskrnl.exe - -.PHONY: error -error: - @echo "=== ERROR ===" - @echo "=> Use a specific target." - -MOVEALL=./MoveAll.X64.sh -WINDRES=x86_64-w64-mingw32-windres - -.PHONY: newos-amd64-epm -newos-amd64-epm: clean - $(WINDRES) KernelRsrc.rsrc -O coff -o KernelRsrc.obj - $(CC) $(CCFLAGS) $(DISK_DRV) $(DEBUG_MACRO) $(wildcard src/*.cc) \ - $(wildcard src/FS/*.cc) $(wildcard HALKit/AMD64/Storage/*.cc) \ - $(wildcard HALKit/AMD64/PCI/*.cc) $(wildcard src/Network/*.cc) $(wildcard src/Storage/*.cc) \ - $(wildcard HALKit/AMD64/*.cc) $(wildcard src/WS/*.cc) \ - $(wildcard HALKit/AMD64/*.s) - $(ASM) $(ASMFLAGS) HALKit/AMD64/HalInterruptAPI.asm - $(ASM) $(ASMFLAGS) HALKit/AMD64/HalCommonAPI.asm - $(ASM) $(ASMFLAGS) HALKit/AMD64/HalBoot.asm - $(ASM) $(ASMFLAGS) HALKit/AMD64/HalUtils.asm - $(MOVEALL) - -OBJCOPY=x86_64-w64-mingw32-objcopy - -.PHONY: link-amd64-epm -link-amd64-epm: - $(LD) $(LDFLAGS) $(LDOBJ) -o $(KERNEL_IMG) - -.PHONY: all -all: newos-amd64-epm link-amd64-epm - @echo "Kernel => OK." - -.PHONY: help -help: - @echo "=== HELP ===" - @echo "all: Build Kernel and link it." - @echo "link-amd64-epm: Link Kernel for EPM based disks." - @echo "newos-amd64-epm: Build Kernel for EPM based disks." - -.PHONY: clean -clean: - rm -f $(LDOBJ) $(wildcard *.o) $(KERNEL_IMG) diff --git a/dev/ZKAKit/arm64-efi.make b/dev/ZKAKit/arm64-efi.make deleted file mode 100644 index 16bc73eb..00000000 --- a/dev/ZKAKit/arm64-efi.make +++ /dev/null @@ -1,64 +0,0 @@ -################################################## -# (c) Theater Quality Inc, all rights reserved. -# This is the microKernel makefile. -################################################## - -CC = clang++ -LD = lld-link -CCFLAGS = -fshort-wchar -c -ffreestanding -MMD -mno-red-zone -D__ZKA_ARM64__ -fno-rtti -fno-exceptions -I./ \ - -target aarch64-unknown-windows \ - -std=c++20 -O3 -D__MINOSKRNL__ -D__ZKA_MINIMAL_OS__ -D__ZKA_NO_BUILTIN__ -D__HAVE_ZKA_APIS__ -D__ZKA__ -I../ - -ASM = clang++ - -DISKDRIVER = -D__USE_FLASH_MEM__ -D__USE_SAS__ -D__USE_SATA__ - -ifneq ($(DEBUG_SUPPORT), ) -DEBUG = -D__DEBUG__ -endif - -COPY = cp - -LDFLAGS = -subsystem:efi_application -entry:hal_init_platform /nodefaultlib -LDOBJ = obj/*.obj - -# This file is the Kernel, responsible of task management and memory. -KERNEL = minoskrnl.exe - -.PHONY: error -error: - @echo "=== ERROR ===" - @echo "=> Use a specific target." - -MOVEALL=./MoveAll.ARM64.sh - -.PHONY: newos-arm64-epm -newos-arm64-epm: clean - $(CC) $(CCFLAGS) $(DISKDRIVER) $(DEBUG) $(wildcard src/*.cc) \ - $(wildcard src/FS/*.cc) $(wildcard HALKit/ARM64/Storage/*.cc) \ - $(wildcard HALKit/ARM64/PCI/*.cc) $(wildcard src/Network/*.cc) $(wildcard src/Storage/*.cc) \ - $(wildcard HALKit/ARM64/*.cc) $(wildcard HALKit/ARM64/*.cpp) \ - $(wildcard HALKit/ARM64/*.s) $(wildcard HALKit/ARM64/APM/*.cc) - - $(MOVEALL) - -OBJCOPY=x86_64-w64-mingw32-objcopy - -.PHONY: link-arm64-epm -link-arm64-epm: - $(LD) $(LDFLAGS) $(LDOBJ) /out:$(KERNEL) - -.PHONY: all -all: newos-arm64-epm link-arm64-epm - @echo "Kernel => OK." - -.PHONY: help -help: - @echo "=== HELP ===" - @echo "all: Build Kernel and link it." - @echo "link-arm64-epm: Link Kernel for EPM based disks." - @echo "newos-arm64-epm: Build Kernel for EPM based disks." - -.PHONY: clean -clean: - rm -f $(LDOBJ) $(wildcard *.o) $(KERNEL) diff --git a/dev/ZKAKit/doc/Explicit Partition Map.pdf b/dev/ZKAKit/doc/Explicit Partition Map.pdf deleted file mode 100644 index a73834cd..00000000 Binary files a/dev/ZKAKit/doc/Explicit Partition Map.pdf and /dev/null differ diff --git a/dev/ZKAKit/doc/SPECIFICATION.md b/dev/ZKAKit/doc/SPECIFICATION.md deleted file mode 100644 index 0233643a..00000000 --- a/dev/ZKAKit/doc/SPECIFICATION.md +++ /dev/null @@ -1,63 +0,0 @@ -=================================== - -# 0: General Information - -=================================== - -- ABI and Format: PEF/PE32+. -- Kernel architecture: Portable hybrid Kernel. -- Language: C++/(Assembly (AMD64, X64000, X86S, ARM64, POWER, RISCV)) - -=================================== - -# 1: The Kernel - -=================================== - -- Drive/Device Abstraction. -- SMP, Preemptive Multi Threading. -- Separation of Files/Devices. -- Networking. -- Hardware Abstraction Layer. -- Native Filesystem support (NeFS, FAT32 and ffs2). -- Program Loaders interfaces. -- TLS (Thread Local Storage) support. -- Semaphore, Locks, Timers. -- Canary mechanisms. -- Dynamic Sys. -- Cross Platform. -- Permission Selectors. - -=================================== - -# 2: The Filesystem - -=================================== - -- Catalog object with associated forks. -- Large storage support. -- Long file names. -- UNIX path style. - -================================== - -# 3: Common naming conventions: - -================================== - -- Kernel -> ke_init_x -- RunTime -> rt_copy_mem -- Hal -> hal_foo_bar -- Class methods -> Class::FooBar - -=================================== - -# 4: The zbaosldr - -=================================== - -- Capable of booting from a network drive. -- Loads a PE file which is the Kernel. -- Sanity checks, based on the number of sections. -- Handover compliant. -- Does check for a valid partition (useful in the case of recovering) diff --git a/dev/ZKAKit/doc/TODO-LIST.md b/dev/ZKAKit/doc/TODO-LIST.md deleted file mode 100644 index 6e8e4b4d..00000000 --- a/dev/ZKAKit/doc/TODO-LIST.md +++ /dev/null @@ -1,25 +0,0 @@ -# TODO list - -- We need preemptive multi-threading. [ X ] -- We then need sync primitives. [ X ] -- We also need a system library for the OS. [ X ] -- We need a bootloader for AMD64 [ X ] - - Implement Boot Services [ X ] - - Design Handover [ X ] - - Load Kernel into memory [ X ] - - Fix bug in Kernel loader, which causes a 06 #UD. [ X ] - - Load Kernel [ X ] - - Add IDT [ X ] - - AHCI driver [ WiP ] -- Context switch x87/SSE/AVX registers [ X ] -- Framebuffer [ X ] -- ATA support [ X ] -- Make installer [ X ] - -Status: - -BootZ: Need to boot from EPM partition. [ X ] -
-minoskrnl: New Filesystem is done. [ X ] - -**Refer to Jira please!** diff --git a/dev/ZKAKit/obj/.hgkeep b/dev/ZKAKit/obj/.hgkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/dev/ZKAKit/power64-cb.make b/dev/ZKAKit/power64-cb.make deleted file mode 100644 index 8d7b20ae..00000000 --- a/dev/ZKAKit/power64-cb.make +++ /dev/null @@ -1,4 +0,0 @@ -################################################## -# (c) Theater Quality Inc, all rights reserved. -# This is the microKernel makefile. -################################################## diff --git a/dev/ZKAKit/riscv64-cb.make b/dev/ZKAKit/riscv64-cb.make deleted file mode 100644 index e69de29b..00000000 diff --git a/dev/ZKAKit/src/ACPIFactoryInterface.cc b/dev/ZKAKit/src/ACPIFactoryInterface.cc deleted file mode 100644 index 424a951a..00000000 --- a/dev/ZKAKit/src/ACPIFactoryInterface.cc +++ /dev/null @@ -1,96 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include -#include -#include - -namespace Kernel -{ - /// @brief Finds a descriptor table inside ACPI XSDT. - ErrorOr ACPIFactoryInterface::Find(const Char* signature) - { - MUST_PASS(fRsdp); - - if (!signature) - return ErrorOr{-1}; - - if (*signature == 0) - return ErrorOr{-1}; - - RSDP* rsp_ptr = reinterpret_cast(this->fRsdp); - - if (rsp_ptr->Revision <= 1) - return ErrorOr{-1}; - - RSDT* xsdt = reinterpret_cast(rsp_ptr->RsdtAddress); - - Int64 num = (xsdt->Length - sizeof(SDT)) / sizeof(Int64); - - /*** - crucial to avoid underflows. - */ - if (num < 1) - { - /// stop here, we should have entries... - ke_stop(RUNTIME_CHECK_ACPI); - return ErrorOr{-1}; - } - - this->fEntries = num; - - kcout << "ACPI: Number of entries: " << number(this->fEntries) << endl; - kcout << "ACPI: Revision: " << number(xsdt->Revision) << endl; - kcout << "ACPI: Signature: " << xsdt->Signature << endl; - kcout << "ACPI: Address of XSDT: " << hex_number((UIntPtr)xsdt) << endl; - - const short cAcpiSignatureLength = 4; - - for (Size index = 0; index < this->fEntries; ++index) - { - SDT* sdt = reinterpret_cast(xsdt->AddressArr[index]); - - kcout << "ACPI: Checksum: " << number(sdt->Checksum) << endl; - kcout << "ACPI: Revision: " << number(sdt->Revision) << endl; - - for (short signature_index = 0; signature_index < cAcpiSignatureLength; ++signature_index) - { - if (sdt->Signature[signature_index] != signature[signature_index]) - break; - - if (signature_index == (cAcpiSignatureLength - 1)) - { - kcout << "ACPI: SDT Signature: " << sdt->Signature << endl; - kcout << "ACPI: SDT OEM ID: " << sdt->OemId << endl; - return ErrorOr(reinterpret_cast(xsdt->AddressArr[index])); - } - } - } - - return ErrorOr{-1}; - } - - /*** - @brief Checksum on SDT header. - @param checksum the header to checksum - @param len the length of it. - */ - bool ACPIFactoryInterface::Checksum(const Char* checksum, SSizeT len) - { - if (len == 0) - return 1; - - char chr = 0; - - for (int index = 0; index < len; ++index) - { - chr += checksum[index]; - } - - return chr == 0; - } -} // namespace Kernel diff --git a/dev/ZKAKit/src/Array.cc b/dev/ZKAKit/src/Array.cc deleted file mode 100644 index ec676682..00000000 --- a/dev/ZKAKit/src/Array.cc +++ /dev/null @@ -1,7 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include diff --git a/dev/ZKAKit/src/ArrayList.cc b/dev/ZKAKit/src/ArrayList.cc deleted file mode 100644 index 48bdd8a0..00000000 --- a/dev/ZKAKit/src/ArrayList.cc +++ /dev/null @@ -1,7 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include diff --git a/dev/ZKAKit/src/Atom.cc b/dev/ZKAKit/src/Atom.cc deleted file mode 100644 index 43814d34..00000000 --- a/dev/ZKAKit/src/Atom.cc +++ /dev/null @@ -1,10 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include - -// @file Atom.cpp -// @brief Atomic primitives diff --git a/dev/ZKAKit/src/BitMapMgr.cc b/dev/ZKAKit/src/BitMapMgr.cc deleted file mode 100644 index be9f73b8..00000000 --- a/dev/ZKAKit/src/BitMapMgr.cc +++ /dev/null @@ -1,185 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include - -#ifdef __ZKA_AMD64__ -#include -#elif defined(__ZKA_ARM64__) -#include -#endif - -#include -#include - -#define kBitMapMagic (0x10210U) - -#define kBitMapMagIdx (0U) -#define kBitMapSizeIdx (1U) -#define kBitMapUsedIdx (2U) - -namespace Kernel -{ - namespace HAL - { - namespace Detail - { - /// \brief Proxy Interface to allocate a bitmap. - class IBitMapAllocator final - { - public: - explicit IBitMapAllocator() = default; - ~IBitMapAllocator() = default; - - ZKA_COPY_DELETE(IBitMapAllocator); - - auto IsBitMap(VoidPtr page_ptr) -> Bool - { - if (!page_ptr) - return No; - - UIntPtr* ptr_bit_set = reinterpret_cast(page_ptr); - - if (!ptr_bit_set[kBitMapMagIdx] || - ptr_bit_set[kBitMapMagIdx] != kBitMapMagic) - return No; - - return Yes; - } - - auto FreeBitMap(VoidPtr page_ptr) -> Bool - { - if (this->IsBitMap(page_ptr) == No) - return No; - - UIntPtr* ptr_bit_set = reinterpret_cast(page_ptr); - - ptr_bit_set[kBitMapMagIdx] = kBitMapMagic; - ptr_bit_set[kBitMapUsedIdx] = No; - - this->GetBitMapStatus(ptr_bit_set); - - return Yes; - } - - UInt32 MakeMMFlags(Bool wr, Bool user) - { - UInt32 flags = kMMFlagsPresent; - - if (wr) - flags |= kMMFlagsWr; - - if (user) - flags |= kMMFlagsUser; - - return flags; - } - - /// @brief Iterate over availables pages for a free one. - /// @return The new address which was found. - auto FindBitMap(VoidPtr base_ptr, SizeT size, Bool wr, Bool user) -> VoidPtr - { - VoidPtr base = reinterpret_cast(((UIntPtr)base_ptr) + kPageSize); - - while (base && size) - { - UIntPtr* ptr_bit_set = reinterpret_cast(base); - - if (ptr_bit_set[kBitMapMagIdx] == kBitMapMagic && - ptr_bit_set[kBitMapSizeIdx] <= size) - { - if (ptr_bit_set[kBitMapUsedIdx] == No) - { - ptr_bit_set[kBitMapSizeIdx] = size; - ptr_bit_set[kBitMapUsedIdx] = Yes; - - this->GetBitMapStatus(ptr_bit_set); - - UInt32 flags = this->MakeMMFlags(wr, user); - mm_map_page(ptr_bit_set, flags); - - return (VoidPtr)ptr_bit_set; - } - } - else if (ptr_bit_set[kBitMapMagIdx] != kBitMapMagic) - { - UIntPtr* ptr_bit_set = reinterpret_cast(base_ptr); - - ptr_bit_set[kBitMapMagIdx] = kBitMapMagic; - ptr_bit_set[kBitMapSizeIdx] = size; - ptr_bit_set[kBitMapUsedIdx] = Yes; - - this->GetBitMapStatus(ptr_bit_set); - - UInt32 flags = this->MakeMMFlags(wr, user); - mm_map_page(ptr_bit_set, flags); - - return (VoidPtr)ptr_bit_set; - } - - base = reinterpret_cast(reinterpret_cast(base_ptr) + (ptr_bit_set[0] != kBitMapMagic ? size : ptr_bit_set[1])); - - if ((UIntPtr)base_ptr < (reinterpret_cast(base) + kHandoverHeader->f_BitMapSize)) - return nullptr; - } - - return nullptr; - } - - /// @brief Print Bitmap status - auto GetBitMapStatus(UIntPtr* ptr_bit_set) -> Void - { - if (!this->IsBitMap(ptr_bit_set)) - { - kcout << "Not a BitMap: " << hex_number((UIntPtr)ptr_bit_set) << endl; - return; - } - - kcout << "Magic Number: " << hex_number(ptr_bit_set[kBitMapMagIdx]) << endl; - kcout << "Is Allocated: " << (ptr_bit_set[kBitMapUsedIdx] ? "Yes" : "No") << endl; - kcout << "Size of BitMap (B): " << number(ptr_bit_set[kBitMapSizeIdx]) << endl; - kcout << "Size of BitMap (KIB): " << number(KIB(ptr_bit_set[kBitMapSizeIdx])) << endl; - kcout << "Size of BitMap (MIB): " << number(MIB(ptr_bit_set[kBitMapSizeIdx])) << endl; - kcout << "Size of BitMap (GIB): " << number(GIB(ptr_bit_set[kBitMapSizeIdx])) << endl; - kcout << "Size of BitMap (TIB): " << number(TIB(ptr_bit_set[kBitMapSizeIdx])) << endl; - kcout << "Address Of BitMap: " << hex_number((UIntPtr)ptr_bit_set) << endl; - } - }; - } // namespace Detail - - auto mm_is_bitmap(VoidPtr ptr) -> Bool - { - Detail::IBitMapAllocator traits; - return traits.IsBitMap(ptr); - } - - /// @brief Allocate a new page to be used by the OS. - /// @param wr read/write bit. - /// @param user user bit. - /// @return a new bitmap allocated pointer. - auto mm_alloc_bitmap(Boolean wr, Boolean user, SizeT size, Bool is_page) -> VoidPtr - { - VoidPtr ptr_new = nullptr; - Detail::IBitMapAllocator traits; - - ptr_new = traits.FindBitMap(kKernelBitMpStart, size, wr, user); - - return (UIntPtr*)ptr_new; - } - - /// @brief Free Bitmap, and mark it a absent in page terms. - auto mm_free_bitmap(VoidPtr page_ptr) -> Bool - { - if (!page_ptr) - return No; - - Detail::IBitMapAllocator traits; - Bool ret = traits.FreeBitMap(page_ptr); - - return ret; - } - } // namespace HAL -} // namespace Kernel diff --git a/dev/ZKAKit/src/CodeMgr.cc b/dev/ZKAKit/src/CodeMgr.cc deleted file mode 100644 index 0450f56a..00000000 --- a/dev/ZKAKit/src/CodeMgr.cc +++ /dev/null @@ -1,38 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include -#include - -namespace Kernel -{ - /// @brief Executes a new process from a function. Kernel code only. - /// @note This sets up a new stack, anything on the main function that calls the Kernel will not be accessible. - /// @param main the start of the process. - /// @return if the process was started or not. - ProcessID rtl_create_process(rtl_main_kind main, const Char* process_name) noexcept - { - if (*process_name == 0) - return kProcessInvalidID; - - UserProcess* process_hdr = new UserProcess(); - - process_hdr->Image.fCode = reinterpret_cast(main); - process_hdr->Kind = UserProcess::kExectuableKind; - process_hdr->StackSize = kib_cast(8); - - rt_set_memory(process_hdr->Name, 0, kProcessNameLen); - rt_copy_memory((VoidPtr)process_name, process_hdr->Name, rt_string_len(process_name)); - - ProcessID id = UserProcessScheduler::The().Spawn(process_hdr); - - if (id == kProcessInvalidID) - delete process_hdr; - - return id; - } -} // namespace Kernel diff --git a/dev/ZKAKit/src/Crc32.cc b/dev/ZKAKit/src/Crc32.cc deleted file mode 100644 index 3a8f9192..00000000 --- a/dev/ZKAKit/src/Crc32.cc +++ /dev/null @@ -1,83 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include - -// @file CRC32.cpp -// @brief Check sequence implementation. - -namespace Kernel -{ - /// @brief The CRC32 seed table. - UInt32 kCrcTbl[kCrcCnt] = { - 0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L, 0xC79A971FL, - 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL, 0x8AD958CFL, 0x78B2DBCCL, - 0x6BE22838L, 0x9989AB3BL, 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, - 0x5E133C24L, 0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL, - 0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L, 0x9A879FA0L, - 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L, 0x5D1D08BFL, 0xAF768BBCL, - 0xBC267848L, 0x4E4DFB4BL, 0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, - 0x33ED7D2AL, 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L, - 0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L, 0x6DFE410EL, - 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL, 0x30E349B1L, 0xC288CAB2L, - 0xD1D83946L, 0x23B3BA45L, 0xF779DEAEL, 0x05125DADL, 0x1642AE59L, - 0xE4292D5AL, 0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL, - 0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L, 0x417B1DBCL, - 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L, 0x86E18AA3L, 0x748A09A0L, - 0x67DAFA54L, 0x95B17957L, 0xCBA24573L, 0x39C9C670L, 0x2A993584L, - 0xD8F2B687L, 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L, - 0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L, 0x96BF4DCCL, - 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L, 0xDBFC821CL, 0x2997011FL, - 0x3AC7F2EBL, 0xC8AC71E8L, 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, - 0x0F36E6F7L, 0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L, - 0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L, 0xEB1FCBADL, - 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L, 0x2C855CB2L, 0xDEEEDFB1L, - 0xCDBE2C45L, 0x3FD5AF46L, 0x7198540DL, 0x83F3D70EL, 0x90A324FAL, - 0x62C8A7F9L, 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L, - 0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L, 0x3CDB9BDDL, - 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L, 0x82F63B78L, 0x709DB87BL, - 0x63CD4B8FL, 0x91A6C88CL, 0x456CAC67L, 0xB7072F64L, 0xA457DC90L, - 0x563C5F93L, 0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L, - 0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL, 0x92A8FC17L, - 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L, 0x55326B08L, 0xA759E80BL, - 0xB4091BFFL, 0x466298FCL, 0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, - 0x0B21572CL, 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L, - 0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L, 0x65D122B9L, - 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL, 0x2892ED69L, 0xDAF96E6AL, - 0xC9A99D9EL, 0x3BC21E9DL, 0xEF087A76L, 0x1D63F975L, 0x0E330A81L, - 0xFC588982L, 0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL, - 0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L, 0x38CC2A06L, - 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L, 0xFF56BD19L, 0x0D3D3E1AL, - 0x1E6DCDEEL, 0xEC064EEDL, 0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, - 0xD0DDD530L, 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL, - 0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL, 0x8ECEE914L, - 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L, 0xD3D3E1ABL, 0x21B862A8L, - 0x32E8915CL, 0xC083125FL, 0x144976B4L, 0xE622F5B7L, 0xF5720643L, - 0x07198540L, 0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L, - 0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL, 0xE330A81AL, - 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL, 0x24AA3F05L, 0xD6C1BC06L, - 0xC5914FF2L, 0x37FACCF1L, 0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, - 0x7AB90321L, 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL, - 0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L, 0x34F4F86AL, - 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL, 0x79B737BAL, 0x8BDCB4B9L, - 0x988C474DL, 0x6AE7C44EL, 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, - 0xAD7D5351L}; - - /// @brief Calculate CRC32 of p - /// @param p the data to compute. - /// @param len the length of the data. - /// @return the CRC32. - UInt ke_calculate_crc32(const Char* p, UInt len) noexcept - { - UInt crc = 0xffffffff; - - while (len-- != 0) - crc = kCrcTbl[((UInt8)crc ^ *(p++))] ^ (crc >> 8); - - // return (~crc); also works, does the same thing. - return (crc ^ 0xffffffff); - } -} // namespace Kernel diff --git a/dev/ZKAKit/src/CxxAbi-AMD64.cc b/dev/ZKAKit/src/CxxAbi-AMD64.cc deleted file mode 100644 index 83633955..00000000 --- a/dev/ZKAKit/src/CxxAbi-AMD64.cc +++ /dev/null @@ -1,90 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#ifdef __ZKA_AMD64__ - -#include -#include -#include - -atexit_func_entry_t __atexit_funcs[kAtExitMacDestructors]; - -uarch_t __atexit_func_count; - -/// @brief dynamic shared object Handle. -Kernel::UIntPtr __dso_handle; - -EXTERN_C Kernel::Void __cxa_pure_virtual(void* self) -{ - kcout << "object: " << Kernel::number(reinterpret_cast(self)); - kcout << ", has unimplemented virtual functions.\r"; -} - -EXTERN_C void ___chkstk_ms(void) -{ -} - -EXTERN_C int atexit(void (*f)(void*), void* arg, void* dso) -{ - if (__atexit_func_count >= kAtExitMacDestructors) - return 1; - - __atexit_funcs[__atexit_func_count].destructor_func = f; - __atexit_funcs[__atexit_func_count].obj_ptr = arg; - __atexit_funcs[__atexit_func_count].dso_handle = dso; - - __atexit_func_count++; - - return 0; -} - -EXTERN_C void __cxa_finalize(void* f) -{ - uarch_t i = __atexit_func_count; - if (!f) - { - while (i--) - { - if (__atexit_funcs[i].destructor_func) - { - (*__atexit_funcs[i].destructor_func)(__atexit_funcs[i].obj_ptr); - }; - } - - return; - } - - while (i--) - { - if (__atexit_funcs[i].destructor_func) - { - (*__atexit_funcs[i].destructor_func)(__atexit_funcs[i].obj_ptr); - __atexit_funcs[i].destructor_func = 0; - }; - } -} - -namespace cxxabiv1 -{ - EXTERN_C int __cxa_guard_acquire(__guard* g) - { - (void)g; - return 0; - } - - EXTERN_C int __cxa_guard_release(__guard* g) - { - *(char*)g = 1; - return 0; - } - - EXTERN_C void __cxa_guard_abort(__guard* g) - { - (void)g; - } -} // namespace cxxabiv1 - -#endif // ifdef __ZKA_AMD64__ diff --git a/dev/ZKAKit/src/CxxAbi-ARM64.cc b/dev/ZKAKit/src/CxxAbi-ARM64.cc deleted file mode 100644 index d46ea1e5..00000000 --- a/dev/ZKAKit/src/CxxAbi-ARM64.cc +++ /dev/null @@ -1,107 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#ifdef __ZKA_ARM64__ - -#include -#include -#include - -atexit_func_entry_t __atexit_funcs[kAtExitMacDestructors]; - -uarch_t __atexit_func_count; - -/// @brief dynamic shared object Handle. -Kernel::UIntPtr __dso_handle; - -EXTERN_C void __chkstk(void) -{ -} - -EXTERN_C int atexit(void (*f)(void*), void* arg, void* dso) -{ - if (__atexit_func_count >= kAtExitMacDestructors) - return 1; - - __atexit_funcs[__atexit_func_count].destructor_func = f; - __atexit_funcs[__atexit_func_count].obj_ptr = arg; - __atexit_funcs[__atexit_func_count].dso_handle = dso; - - __atexit_func_count++; - - return 0; -} - -EXTERN_C void __cxa_finalize(void* f) -{ - uarch_t i = __atexit_func_count; - if (!f) - { - while (i--) - { - if (__atexit_funcs[i].destructor_func) - { - (*__atexit_funcs[i].destructor_func)(__atexit_funcs[i].obj_ptr); - }; - } - - return; - } - - while (i--) - { - if (__atexit_funcs[i].destructor_func) - { - (*__atexit_funcs[i].destructor_func)(__atexit_funcs[i].obj_ptr); - __atexit_funcs[i].destructor_func = 0; - }; - } -} - -namespace cxxabiv1 -{ - EXTERN_C int __cxa_guard_acquire(__guard* g) - { - (void)g; - return 0; - } - - EXTERN_C int __cxa_guard_release(__guard* g) - { - *(char*)g = 1; - return 0; - } - - EXTERN_C void __cxa_guard_abort(__guard* g) - { - (void)g; - } -} // namespace cxxabiv1 - -EXTERN_C Kernel::Void _purecall(void* self) -{ - kcout << "object: " << Kernel::number(reinterpret_cast(self)); - kcout << ", has unimplemented virtual functions.\r"; -} - -EXTERN_C Kernel::Void _Init_thread_footer(Kernel::Int* thread_obj) -{ - ZKA_UNUSED(thread_obj); -} - -EXTERN_C Kernel::Void _Init_thread_epoch(Kernel::Void) -{ - ZKA_UNUSED(0); -} - -EXTERN_C Kernel::Void _Init_thread_header(Kernel::Int* thread_obj) -{ - ZKA_UNUSED(0); -} - -EXTERN_C Kernel::Int _tls_index = 0UL; - -#endif // ifdef __ZKA_ARM64__ diff --git a/dev/ZKAKit/src/Defines.cc b/dev/ZKAKit/src/Defines.cc deleted file mode 100644 index 10ef190d..00000000 --- a/dev/ZKAKit/src/Defines.cc +++ /dev/null @@ -1,7 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include diff --git a/dev/ZKAKit/src/DeviceMgr.cc b/dev/ZKAKit/src/DeviceMgr.cc deleted file mode 100644 index d5be833b..00000000 --- a/dev/ZKAKit/src/DeviceMgr.cc +++ /dev/null @@ -1,7 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include diff --git a/dev/ZKAKit/src/DriveMgr.cc b/dev/ZKAKit/src/DriveMgr.cc deleted file mode 100644 index 6dc2b770..00000000 --- a/dev/ZKAKit/src/DriveMgr.cc +++ /dev/null @@ -1,219 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include -#include -#include -#include -#include -#include - -/***********************************************************************************/ -/// @file DriveMgr.cc -/// @brief Drive Manager of minoskrnl. -/***********************************************************************************/ - -namespace Kernel -{ - STATIC UInt16 kATAIO = 0U; - STATIC UInt8 kATAMaster = 0U; - - /// @brief reads from an ATA drive. - /// @param pckt Packet structure (fPacketContent must be non null) - /// @return - Void io_drv_input(DriveTrait::DrivePacket* pckt) - { - if (!pckt) - { - return; - } - -#ifdef __AHCI__ - drv_std_read(pckt->fPacketLba, (Char*)pckt->fPacketContent, kAHCISectorSize, pckt->fPacketSize); -#elif defined(__ATA_PIO__) || defined(__ATA_DMA__) - drv_std_read(pckt->fPacketLba, kATAIO, kATAMaster, (Char*)pckt->fPacketContent, kATASectorSize, pckt->fPacketSize); -#endif - } - - /// @brief Writes to an ATA drive. - /// @param pckt the packet to write. - /// @return - Void io_drv_output(DriveTrait::DrivePacket* pckt) - { - if (!pckt) - { - return; - } - -#ifdef __AHCI__ - drv_std_write(pckt->fPacketLba, (Char*)pckt->fPacketContent, kAHCISectorSize, pckt->fPacketSize); -#elif defined(__ATA_PIO__) || defined(__ATA_DMA__) - drv_std_write(pckt->fPacketLba, kATAIO, kATAMaster, (Char*)pckt->fPacketContent, kATASectorSize, pckt->fPacketSize); -#endif - } - - /// @brief Executes a disk check on the ATA drive. - /// @param pckt the packet to read. - /// @return - Void io_drv_init(DriveTrait::DrivePacket* pckt) - { - if (!pckt) - { - return; - } - - kATAMaster = 0; - kATAIO = 0; - -#if defined(__ATA_PIO__) || defined(__ATA_DMA__) - kATAMaster = true; - kATAIO = ATA_PRIMARY_IO; - - if (drv_std_init(kATAIO, kATAMaster, kATAIO, kATAMaster)) - { - pckt->fPacketGood = YES; - return; - } - - kATAMaster = false; - kATAIO = ATA_SECONDARY_IO; - - if (!drv_std_init(kATAIO, kATAMaster, kATAIO, kATAMaster)) - { - return; - } - - pckt->fPacketGood = YES; -#elif defined(__AHCI__) - UInt16 pi = 0; - - if (!drv_std_init(pi)) - { - return; - } -#endif // if defined(__ATA_PIO__) || defined (__ATA_DMA__) - } - -/// @brief Gets the drive kind (ATA, SCSI, AHCI...) -/// @param no arguments. -/// @return no arguments. -#ifdef __ATA_PIO__ - const Char* io_drv_kind(Void) - { - return "ATA-PIO"; - } -#endif -#ifdef __ATA_DMA__ - const Char* io_drv_kind(Void) - { - return "ATA-DMA"; - } -#endif -#ifdef __AHCI__ - const Char* io_drv_kind(Void) - { - return "AHCI"; - } -#endif -#ifdef __ZKA_MINIMAL_OS__ - const Char* io_drv_kind(Void) - { - return "Not Loaded"; - } -#endif - - /// @brief Unimplemented drive function. - /// @param pckt the packet to read. - /// @return - Void io_drv_unimplemented(DriveTrait::DrivePacket* pckt) - { - ZKA_UNUSED(pckt); - } - - /// @brief Makes a new drive. - /// @return the new blank drive. - DriveTrait io_construct_blank_drive() noexcept - { - DriveTrait trait; - - rt_copy_memory((VoidPtr) "/Disks/NUL:", trait.fName, rt_string_len("/Disks/NUL:")); - trait.fKind = kInvalidDisc; - - trait.fInput = io_drv_unimplemented; - trait.fOutput = io_drv_unimplemented; - trait.fVerify = io_drv_unimplemented; - trait.fInit = io_drv_unimplemented; - trait.fDriveKind = io_drv_kind; - - kcout << "Construct: " << trait.fName << "\r"; - - return trait; - } - - namespace Detail - { - Void ioi_detect_drive(DriveTrait* trait) - { - static _BOOT_BLOCK_STRUCT block_struct; - - trait->fPacket.fPacketLba = kEPMBaseLba; - trait->fPacket.fPacketSize = sizeof(_BOOT_BLOCK_STRUCT); - trait->fPacket.fPacketContent = &block_struct; - - rt_copy_memory((VoidPtr) "fs/detect-packet", trait->fPacket.fPacketMime, - rt_string_len("fs/detect-packet")); - - trait->fInit(&trait->fPacket); - - trait->fInput(&trait->fPacket); - - if (rt_string_cmp(((BOOT_BLOCK_STRUCT*)trait->fPacket.fPacketContent)->Magic, kEPMMagic, kEPMMagicLength) == 0) - { - trait->fPacket.fPacketReadOnly = NO; - trait->fKind = kMassStorageDisc | kEPMDrive; - kcout << "Formatted Disc is EPM (Mass Storage).\r"; - } - else - { - trait->fPacket.fPacketReadOnly = YES; - trait->fKind = kMassStorageDisc | kUnformattedDrive | kReadOnlyDrive; - kcout << "Scheme Found: " << block_struct.Name << endl; - - if (block_struct.Name[0] == 0) - kcout << "Disc partition is unknown (set to Read Only).\r"; - } - - rt_copy_memory((VoidPtr) "*/*", trait->fPacket.fPacketMime, - rt_string_len("*/*")); - - trait->fPacket.fPacketLba = 0; - trait->fPacket.fPacketSize = 0UL; - trait->fPacket.fPacketContent = nullptr; - } - } // namespace Detail - - /// @brief Fetches the main drive. - /// @return the new drive. (returns kEPMDrive if EPM formatted) - DriveTrait io_construct_main_drive() noexcept - { - DriveTrait trait; - - rt_copy_memory((VoidPtr) "/Disks/OS:", trait.fName, rt_string_len("/Disks/OS:")); - - trait.fVerify = io_drv_unimplemented; - trait.fOutput = io_drv_output; - trait.fInput = io_drv_input; - trait.fInit = io_drv_init; - trait.fDriveKind = io_drv_kind; - - kcout << "Detect partition scheme of: " << trait.fName << ".\r"; - - Detail::ioi_detect_drive(&trait); - - return trait; - } -} // namespace Kernel diff --git a/dev/ZKAKit/src/ErrorOr.cc b/dev/ZKAKit/src/ErrorOr.cc deleted file mode 100644 index 4e92491c..00000000 --- a/dev/ZKAKit/src/ErrorOr.cc +++ /dev/null @@ -1,12 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include - -/***********************************************************************************/ -/// @file ErrorOr.cc /// -/// @brief ErrorOr container class. /// -/***********************************************************************************/ diff --git a/dev/ZKAKit/src/FS/HPFS.cc b/dev/ZKAKit/src/FS/HPFS.cc deleted file mode 100644 index 8aba73ac..00000000 --- a/dev/ZKAKit/src/FS/HPFS.cc +++ /dev/null @@ -1,22 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#ifdef __FSKIT_INCLUDES_HPFS__ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#endif // ifdef __FSKIT_INCLUDES_HPFS__ diff --git a/dev/ZKAKit/src/FS/NeFS.cc b/dev/ZKAKit/src/FS/NeFS.cc deleted file mode 100644 index c062d16a..00000000 --- a/dev/ZKAKit/src/FS/NeFS.cc +++ /dev/null @@ -1,1054 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#ifdef __FSKIT_INCLUDES_NEFS__ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace Kernel; - -#ifdef __ZKA_NO_BUILTIN__ -/***********************************************************************************/ -/** - Define those external symbols, to make the editor shutup -*/ -/***********************************************************************************/ - -/***********************************************************************************/ -/// @brief get sector count. -/***********************************************************************************/ -Kernel::SizeT drv_get_sector_count(); - -/***********************************************************************************/ -/// @brief get device size. -/***********************************************************************************/ -Kernel::SizeT drv_get_size(); - -#endif - -///! BUGS: 0 - -/***********************************************************************************/ -/// This file implements the New File System. -/// New File System implements a B-Tree based algortihm. -/// / -/// /Path1/ /ath2/ -/// /readme.rtf /ListContents.pef /readme.lnk <-- symlink. -/// /Path1/readme.rtf -/***********************************************************************************/ - -STATIC MountpointInterface kDiskMountpoint; - -/***********************************************************************************/ -/// @brief Creates a new fork inside the New filesystem partition. -/// @param catalog it's catalog -/// @param the_fork the fork itself. -/// @return the fork -/***********************************************************************************/ -_Output NFS_FORK_STRUCT* NeFileSystemParser::CreateFork(_Input NFS_CATALOG_STRUCT* catalog, - _Input NFS_FORK_STRUCT& the_fork) -{ - if (catalog && the_fork.ForkName[0] != 0 && - the_fork.DataSize <= kNeFSForkDataSz) - { - Lba lba = (the_fork.Kind == kNeFSDataForkKind) ? catalog->DataFork - : catalog->ResourceFork; - - kcout << "Fork LBA: " << hex_number(lba) << endl; - - if (lba <= kNeFSCatalogStartAddress) - return nullptr; - - auto drv = kDiskMountpoint.A(); - - /// special treatment. - rt_copy_memory((VoidPtr) "fs/nefs-packet", drv.fPacket.fPacketMime, - rt_string_len("fs/nefs-packet")); - - NFS_FORK_STRUCT curFork{0}; - NFS_FORK_STRUCT prevFork{0}; - Lba lbaOfPreviousFork = lba; - - /// do not check for anything. Loop until we get what we want, that is a free fork zone. - while (true) - { - if (lba <= kNeFSCatalogStartAddress) - break; - - drv.fPacket.fPacketLba = lba; - drv.fPacket.fPacketSize = sizeof(NFS_FORK_STRUCT); - drv.fPacket.fPacketContent = &curFork; - - drv.fInput(&drv.fPacket); - - if (curFork.NextSibling > kBadAddress) - { - kcout << "Bad fork: " << hex_number(curFork.NextSibling) << endl; - break; - } - - kcout << "Next fork: " << hex_number(curFork.NextSibling) << endl; - - if (curFork.Flags & kNeFSFlagCreated) - { - kcout << "Fork already exists.\r"; - - /// sanity check. - if (StringBuilder::Equals(curFork.ForkName, the_fork.ForkName) && - StringBuilder::Equals(curFork.CatalogName, catalog->Name)) - return nullptr; - - kcout << "Next fork: " << hex_number(curFork.NextSibling) << endl; - - lbaOfPreviousFork = lba; - lba = curFork.NextSibling; - - prevFork = curFork; - } - else - { - /// This is a check that we have, in order to link the previous fork - /// entry. - if (lba >= kNeFSCatalogStartAddress) - { - drv.fPacket.fPacketLba = lbaOfPreviousFork; - drv.fPacket.fPacketSize = sizeof(NFS_FORK_STRUCT); - drv.fPacket.fPacketContent = &prevFork; - - prevFork.NextSibling = lba; - - /// write to disk. - drv.fOutput(&drv.fPacket); - } - - break; - } - } - - the_fork.Flags |= kNeFSFlagCreated; - the_fork.DataOffset = lba - sizeof(NFS_FORK_STRUCT); - the_fork.PreviousSibling = lbaOfPreviousFork; - the_fork.NextSibling = the_fork.DataOffset - the_fork.DataSize - sizeof(NFS_FORK_STRUCT); - - drv.fPacket.fPacketLba = lba; - drv.fPacket.fPacketSize = sizeof(NFS_FORK_STRUCT); - drv.fPacket.fPacketContent = &the_fork; - - drv.fOutput(&drv.fPacket); - - /// log what we have now. - kcout << "Wrote fork data at: " << hex_number(the_fork.DataOffset) - << endl; - - kcout << "Wrote fork at: " << hex_number(lba) << endl; - - return &the_fork; - } - - return nullptr; -} - -/***********************************************************************************/ -/// @brief Find fork inside New filesystem. -/// @param catalog the catalog. -/// @param name the fork name. -/// @return the fork. -/***********************************************************************************/ -_Output NFS_FORK_STRUCT* NeFileSystemParser::FindFork(_Input NFS_CATALOG_STRUCT* catalog, - _Input const Char* name, - Boolean isDataFork) -{ - auto drv = kDiskMountpoint.A(); - NFS_FORK_STRUCT* the_fork = nullptr; - - Lba lba = isDataFork ? catalog->DataFork : catalog->ResourceFork; - - while (lba != 0) - { - drv.fPacket.fPacketLba = lba; - drv.fPacket.fPacketSize = sizeof(NFS_FORK_STRUCT); - drv.fPacket.fPacketContent = (VoidPtr)the_fork; - - rt_copy_memory((VoidPtr) "fs/nefs-packet", drv.fPacket.fPacketMime, 16); - - if (auto res = - fs_newfs_read(&kDiskMountpoint, drv, this->mDriveIndex); - res) - { - switch (res) - { - case 1: - err_local_get() = kErrorDiskReadOnly; - break; - case 2: - err_local_get() = kErrorDiskIsFull; - break; - err_local_get() = kErrorNoSuchDisk; - break; - - default: - break; - } - return nullptr; - } - - if (StringBuilder::Equals(the_fork->ForkName, name)) - { - break; - } - - lba = the_fork->NextSibling; - } - - return the_fork; -} - -/***********************************************************************************/ -/// @brief Simpler factory to create a catalog (assumes you want to create a -/// file.) -/// @param name -/// @return catalog pointer. -/***********************************************************************************/ -_Output NFS_CATALOG_STRUCT* NeFileSystemParser::CreateCatalog(_Input const Char* name) -{ - return this->CreateCatalog(name, 0, kNeFSCatalogKindFile); -} - -/***********************************************************************************/ -/// @brief Creates a new catalog into the disk. -/// @param name the catalog name. -/// @param flags the flags of the catalog. -/// @param kind the catalog kind. -/// @return catalog pointer. -/***********************************************************************************/ -_Output NFS_CATALOG_STRUCT* NeFileSystemParser::CreateCatalog(_Input const Char* name, - _Input const Int32& flags, - _Input const Int32& kind) -{ - kcout << "CreateCatalog(...)\r"; - - Lba out_lba = 0UL; - - kcout << "Checking for path separator...\r"; - - /// a directory should have a slash in the end. - if (kind == kNeFSCatalogKindDir && - name[rt_string_len(name) - 1] != NeFileSystemHelper::Separator()) - return nullptr; - - /// a file shouldn't have a slash in the end. - if (kind != kNeFSCatalogKindDir && - name[rt_string_len(name) - 1] == NeFileSystemHelper::Separator()) - return nullptr; - - NFS_CATALOG_STRUCT* catalog_copy = this->FindCatalog(name, out_lba); - - if (catalog_copy) - { - kcout << "Catalog already exists: " << name << ".\r"; - err_local_get() = kErrorFileExists; - - return catalog_copy; - } - - Char parentName[kNeFSNodeNameLen] = {0}; - - for (SizeT indexName = 0UL; indexName < rt_string_len(name); ++indexName) - { - parentName[indexName] = name[indexName]; - } - - if (*parentName == 0) - { - kcout << "Parent name is NUL.\r"; - err_local_get() = kErrorFileNotFound; - return nullptr; - } - - /// Locate parent catalog, to then allocate right after it. - - for (SizeT indexFill = 0; indexFill < rt_string_len(name); ++indexFill) - { - parentName[indexFill] = name[indexFill]; - } - - SizeT indexReverseCopy = rt_string_len(parentName); - - // zero character it. - parentName[--indexReverseCopy] = 0; - - // mandatory / character, zero it. - parentName[--indexReverseCopy] = 0; - - while (parentName[indexReverseCopy] != NeFileSystemHelper::Separator()) - { - parentName[indexReverseCopy] = 0; - --indexReverseCopy; - } - - NFS_CATALOG_STRUCT* catalog = this->FindCatalog(parentName, out_lba); - - auto drive = kDiskMountpoint.A(); - - if (catalog && catalog->Kind == kNeFSCatalogKindFile) - { - kcout << "Parent name is file.\r"; - delete catalog; - return nullptr; - } - else if (!catalog) - { - Char sectorBufPartBlock[kNeFSSectorSz] = {0}; - - drive.fPacket.fPacketContent = sectorBufPartBlock; - drive.fPacket.fPacketSize = kNeFSSectorSz; - drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress; - - drive.fInput(&drive.fPacket); - - constexpr auto cNeFSCatalogPadding = 4; - - NFS_ROOT_PARTITION_BLOCK* part_block = (NFS_ROOT_PARTITION_BLOCK*)sectorBufPartBlock; - out_lba = part_block->StartCatalog; - } - - constexpr SizeT kDefaultForkSize = kNeFSForkSize; - - NFS_CATALOG_STRUCT* child_catalog = new NFS_CATALOG_STRUCT(); - - Int32 flagsList = flags; - - child_catalog->ResourceForkSize = kDefaultForkSize; - child_catalog->DataForkSize = kDefaultForkSize; - - child_catalog->NextSibling = out_lba; - child_catalog->PrevSibling = out_lba; - child_catalog->Kind = kind; - child_catalog->Flags = kNeFSFlagCreated | flagsList; - - rt_copy_memory((VoidPtr)name, (VoidPtr)child_catalog->Name, - rt_string_len(name)); - - NFS_CATALOG_STRUCT temporary_catalog; - - Lba start_free = out_lba; - - rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, - rt_string_len("fs/nefs-packet")); - - drive.fPacket.fPacketContent = &temporary_catalog; - drive.fPacket.fPacketSize = kNeFSSectorSz; - drive.fPacket.fPacketLba = start_free; - - drive.fInput(&drive.fPacket); - - NFS_CATALOG_STRUCT* next_sibling = reinterpret_cast(&temporary_catalog); - - start_free = next_sibling->NextSibling; - - child_catalog->PrevSibling = out_lba; - - drive.fPacket.fPacketLba = start_free; - drive.fInput(&drive.fPacket); - - while (drive.fPacket.fPacketGood) - { - next_sibling = reinterpret_cast(&temporary_catalog); - - if (start_free <= kNeFSRootCatalogStartAddress) - { - delete child_catalog; - delete catalog; - - return nullptr; - } - - // ========================== // - // Allocate catalog now... - // ========================== // - if ((next_sibling->Flags & kNeFSFlagCreated) == 0) - { - Char sectorBufPartBlock[kNeFSSectorSz] = {0}; - - drive.fPacket.fPacketContent = sectorBufPartBlock; - drive.fPacket.fPacketSize = kNeFSSectorSz; - drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress; - - drive.fInput(&drive.fPacket); - - constexpr auto cNeFSCatalogPadding = 4; - - NFS_ROOT_PARTITION_BLOCK* part_block = (NFS_ROOT_PARTITION_BLOCK*)sectorBufPartBlock; - - if (part_block->FreeCatalog < 1) - { - delete child_catalog; - return nullptr; - } - - child_catalog->DataFork = part_block->DiskSize - start_free; - child_catalog->ResourceFork = child_catalog->DataFork; - - // Write the new catalog next sibling, if we don't know this parent. // - // This is necessary, so that we don't have to get another lba to allocate. // - if (!StringBuilder::Equals(parentName, next_sibling->Name)) - { - child_catalog->NextSibling = - start_free + (sizeof(NFS_CATALOG_STRUCT) * cNeFSCatalogPadding); - } - - drive.fPacket.fPacketContent = child_catalog; - drive.fPacket.fPacketSize = sizeof(NFS_CATALOG_STRUCT); - drive.fPacket.fPacketLba = start_free; - - drive.fOutput(&drive.fPacket); - - // Get NeFS partition's block. - - drive.fPacket.fPacketContent = sectorBufPartBlock; - drive.fPacket.fPacketSize = kNeFSSectorSz; - drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress; - - drive.fInput(&drive.fPacket); - - part_block->FreeSectors -= 1; - part_block->CatalogCount += 1; - part_block->FreeCatalog -= 1; - - drive.fOutput(&drive.fPacket); - - kcout << "Create new catalog, status: " - << hex_number(child_catalog->Flags) << endl; - kcout << "Create new catalog, name: " << child_catalog->Name - << endl; - - delete catalog; - return child_catalog; - } - else if ((next_sibling->Flags & kNeFSFlagCreated) && - StringBuilder::Equals(next_sibling->Name, name)) - { - return next_sibling; - } - - constexpr auto cNeFSCatalogPadding = 4; - - //// @note that's how we find the next catalog in the partition block. - start_free = start_free + (sizeof(NFS_CATALOG_STRUCT) * cNeFSCatalogPadding); - - drive.fPacket.fPacketContent = &temporary_catalog; - drive.fPacket.fPacketSize = kNeFSSectorSz; - drive.fPacket.fPacketLba = start_free; - - drive.fInput(&drive.fPacket); - } - - delete catalog; - return nullptr; -} - -/// @brief Make a EPM+NeFS drive out of the disk. -/// @param drive The drive to write on. -/// @return If it was sucessful, see err_local_get(). -bool NeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input const Lba endLba, _Input const Int32 flags, const Char* part_name) -{ - if (*part_name == 0 || - endLba == 0) - return false; - - // verify disk. - drive->fVerify(&drive->fPacket); - - rt_copy_memory((VoidPtr) "fs/nefs-packet", drive->fPacket.fPacketMime, - rt_string_len("fs/nefs-packet")); - - // if disk isn't good, then error out. - if (false == drive->fPacket.fPacketGood) - { - err_local_get() = kErrorDiskIsCorrupted; - return false; - } - - Char fs_buf[kNeFSSectorSz] = {0}; - - Lba start = kNeFSRootCatalogStartAddress; - - drive->fPacket.fPacketContent = fs_buf; - drive->fPacket.fPacketSize = kNeFSSectorSz; - drive->fPacket.fPacketLba = start; - - drive->fInput(&drive->fPacket); - - if (flags & kNeFSPartitionTypeBoot) - { - // make it bootable when needed. - Char bufEpmHdr[kNeFSSectorSz] = {0}; - - BOOT_BLOCK_STRUCT* epmBoot = (BOOT_BLOCK_STRUCT*)bufEpmHdr; - - // Write a new EPM entry. - - constexpr auto kFsName = "NeFS"; - constexpr auto kBlockName = "ZKA:"; - - rt_copy_memory(reinterpret_cast(const_cast(kFsName)), epmBoot->Fs, rt_string_len(kFsName)); - - epmBoot->FsVersion = kNeFSVersionInteger; - epmBoot->LbaStart = start; - epmBoot->SectorSz = kNeFSSectorSz; - - rt_copy_memory(reinterpret_cast(const_cast(kBlockName)), epmBoot->Name, rt_string_len(kBlockName)); - rt_copy_memory(reinterpret_cast(const_cast(kEPMMagic)), epmBoot->Magic, rt_string_len(kEPMMagic)); - - Lba outEpmLba = kEPMBaseLba; - - Char buf[kNeFSSectorSz]; - - Lba prevStart = 0; - SizeT cnt = 0; - - while (drive->fPacket.fPacketGood) - { - drive->fPacket.fPacketContent = buf; - drive->fPacket.fPacketSize = kNeFSSectorSz; - drive->fPacket.fPacketLba = outEpmLba; - - drive->fInput(&drive->fPacket); - - if (buf[0] == 0) - { - epmBoot->LbaStart = prevStart; - - if (epmBoot->LbaStart) - epmBoot->LbaStart = outEpmLba; - - epmBoot->LbaEnd = endLba; - epmBoot->NumBlocks = cnt; - - drive->fPacket.fPacketContent = bufEpmHdr; - drive->fPacket.fPacketSize = kNeFSSectorSz; - drive->fPacket.fPacketLba = outEpmLba; - - drive->fOutput(&drive->fPacket); - - break; - } - else - { - prevStart = ((BOOT_BLOCK_STRUCT*)buf)->LbaStart + ((BOOT_BLOCK_STRUCT*)buf)->LbaEnd; - } - - outEpmLba += sizeof(BOOT_BLOCK_STRUCT); - ++cnt; - } - } - - // disk isnt faulty and data has been fetched. - while (drive->fPacket.fPacketGood) - { - NFS_ROOT_PARTITION_BLOCK* part_block = (NFS_ROOT_PARTITION_BLOCK*)fs_buf; - - // check for an empty partition here. - if (part_block->PartitionName[0] == 0 && - rt_string_cmp(part_block->Ident, kNeFSIdent, kNeFSIdentLen)) - { - // partition is free and valid. - - part_block->Version = kNeFSVersionInteger; - - const auto cUntitledHD = part_name; - - rt_copy_memory((VoidPtr)kNeFSIdent, (VoidPtr)part_block->Ident, - kNeFSIdentLen); - - rt_copy_memory((VoidPtr)cUntitledHD, (VoidPtr)part_block->PartitionName, - rt_string_len(cUntitledHD)); - - SizeT catalogCount = 0UL; - - SizeT sectorCount = drv_get_sector_count(); - SizeT diskSize = drv_get_size(); - - part_block->Kind = kNeFSPartitionTypeStandard; - part_block->StartCatalog = kNeFSCatalogStartAddress; - part_block->Flags = kNeFSPartitionTypeStandard; - part_block->CatalogCount = sectorCount / sizeof(NFS_CATALOG_STRUCT); - part_block->SectorCount = sectorCount; - part_block->DiskSize = diskSize; - part_block->FreeCatalog = sectorCount / sizeof(NFS_CATALOG_STRUCT); - - drive->fPacket.fPacketContent = fs_buf; - drive->fPacket.fPacketSize = kNeFSSectorSz; - drive->fPacket.fPacketLba = kNeFSRootCatalogStartAddress; - - drive->fOutput(&drive->fPacket); - - kcout << "drive kind: " << drive->fDriveKind() << endl; - - kcout << "partition name: " << part_block->PartitionName << endl; - kcout << "start: " << hex_number(part_block->StartCatalog) << endl; - kcout << "number of catalogs: " << hex_number(part_block->CatalogCount) << endl; - kcout << "free catalog: " << hex_number(part_block->FreeCatalog) << endl; - kcout << "free sectors: " << hex_number(part_block->FreeSectors) << endl; - kcout << "sector size: " << hex_number(part_block->SectorSize) << endl; - - // write the root catalog. - this->CreateCatalog(kNeFSRoot, 0, kNeFSCatalogKindDir); - - return true; - } - - kcout << "partition block already exists.\r"; - - start += part_block->DiskSize; - - drive->fPacket.fPacketContent = fs_buf; - drive->fPacket.fPacketSize = kNeFSSectorSz; - drive->fPacket.fPacketLba = start; - - drive->fInput(&drive->fPacket); - } - - return false; -} - -/// @brief Writes the data fork into a specific catalog. -/// @param catalog the catalog itself -/// @param data the data. -/// @return if the catalog w rote the contents successfully. -bool NeFileSystemParser::WriteCatalog(_Input _Output NFS_CATALOG_STRUCT* catalog, Bool is_rsrc_fork, _Input VoidPtr data, _Input SizeT size_of_data, _Input const Char* forkName) -{ - if (size_of_data > kNeFSForkDataSz || - size_of_data == 0) - return No; - - auto buf = new UInt8[kNeFSForkDataSz]; - rt_set_memory(buf, 0, kNeFSForkDataSz); - - rt_copy_memory(data, buf, size_of_data); - - auto drive = kDiskMountpoint.A(); - - rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, - rt_string_len("fs/nefs-packet")); - - auto startFork = (!is_rsrc_fork) ? catalog->DataFork - : catalog->ResourceFork; - - NFS_FORK_STRUCT* fork_data_input = new NFS_FORK_STRUCT(); - NFS_FORK_STRUCT prevFork{}; - - // sanity check of the fork position as the condition to run the loop. - while (startFork >= kNeFSCatalogStartAddress) - { - drive.fPacket.fPacketContent = fork_data_input; - drive.fPacket.fPacketSize = sizeof(NFS_FORK_STRUCT); - drive.fPacket.fPacketLba = startFork; - - drive.fInput(&drive.fPacket); - - // check the fork, if it's position is valid. - if (fork_data_input->DataOffset <= kNeFSCatalogStartAddress) - { - err_local_get() = kErrorDiskIsCorrupted; - - kcout << "Invalid fork offset.\r"; - - return false; - } - - if (fork_data_input->Flags != kNeFSFlagUnallocated && - fork_data_input->Flags != kNeFSFlagDeleted && - StringBuilder::Equals(fork_data_input->ForkName, forkName) && - StringBuilder::Equals(fork_data_input->CatalogName, catalog->Name) && - fork_data_input->DataSize == size_of_data) - { - // ===================================================== // - // Store the blob now. - // ===================================================== // - - fork_data_input->Flags |= kNeFSFlagCreated; - - drive.fPacket.fPacketContent = buf; - drive.fPacket.fPacketSize = kNeFSForkDataSz; - drive.fPacket.fPacketLba = fork_data_input->DataOffset; - - kcout << "data offset: " << hex_number(fork_data_input->DataOffset) << endl; - - drive.fOutput(&drive.fPacket); - - drive.fPacket.fPacketContent = fork_data_input; - drive.fPacket.fPacketSize = sizeof(NFS_FORK_STRUCT); - drive.fPacket.fPacketLba = startFork - sizeof(NFS_FORK_STRUCT); - - drive.fOutput(&drive.fPacket); - - kcout << "wrote fork at offset: " << hex_number(fork_data_input->DataOffset) << endl; - kcout << "wrote fork at offset: " << hex_number(startFork - sizeof(NFS_FORK_STRUCT)) << endl; - - delete catalog; - - return true; - } - - // stumble upon a fork, store it. - - prevFork = *fork_data_input; - - startFork = fork_data_input->NextSibling; - } - - return false; -} - -/// @brief -/// @param catalog_name the catalog name. -/// @return the newly found catalog. -_Output NFS_CATALOG_STRUCT* NeFileSystemParser::FindCatalog(_Input const Char* catalog_name, - Lba& out_lba) -{ - if (!catalog_name || - *catalog_name == 0) - return nullptr; - - kcout << "Start finding catalog...\r"; - - NFS_ROOT_PARTITION_BLOCK fs_buf{0}; - auto drive = kDiskMountpoint.A(); - - rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, - rt_string_len("fs/nefs-packet")); - - drive.fPacket.fPacketContent = &fs_buf; - drive.fPacket.fPacketSize = sizeof(NFS_ROOT_PARTITION_BLOCK); - drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress; - - drive.fInput(&drive.fPacket); - - NFS_ROOT_PARTITION_BLOCK* part = (NFS_ROOT_PARTITION_BLOCK*)&fs_buf; - - auto startCatalogList = part->StartCatalog; - const auto cCtartCatalogList = startCatalogList; - - auto localSearchFirst = false; - - NFS_CATALOG_STRUCT temporary_catalog{0}; - - drive.fPacket.fPacketLba = startCatalogList; - drive.fPacket.fPacketContent = &temporary_catalog; - drive.fPacket.fPacketSize = sizeof(NFS_CATALOG_STRUCT); - - drive.fInput(&drive.fPacket); - - if (!StringBuilder::Equals(catalog_name, NeFileSystemHelper::Root())) - { - Char parentName[kNeFSNodeNameLen] = {0}; - - for (SizeT indexFill = 0; indexFill < rt_string_len(catalog_name); ++indexFill) - { - parentName[indexFill] = catalog_name[indexFill]; - } - - SizeT indexReverseCopy = rt_string_len(parentName); - - // zero character. - parentName[--indexReverseCopy] = 0; - - // mandatory '/' character. - parentName[--indexReverseCopy] = 0; - - while (parentName[indexReverseCopy] != NeFileSystemHelper::Separator()) - { - parentName[indexReverseCopy] = 0; - --indexReverseCopy; - } - - NFS_CATALOG_STRUCT* parentCatalog = this->FindCatalog(parentName, out_lba); - - if (parentCatalog && - !StringBuilder::Equals(parentName, NeFileSystemHelper::Root())) - { - startCatalogList = parentCatalog->NextSibling; - delete parentCatalog; - - localSearchFirst = true; - } - else if (parentCatalog) - { - delete parentCatalog; - } - else - { - return nullptr; - } - } - - kcout << "Fetching catalog...\r"; - -NeFSSearchThroughCatalogList: - while (drive.fPacket.fPacketGood) - { - drive.fPacket.fPacketLba = startCatalogList; - drive.fPacket.fPacketContent = &temporary_catalog; - drive.fPacket.fPacketSize = sizeof(NFS_CATALOG_STRUCT); - - drive.fInput(&drive.fPacket); - - NFS_CATALOG_STRUCT* catalog = (NFS_CATALOG_STRUCT*)&temporary_catalog; - - if (StringBuilder::Equals(catalog_name, catalog->Name)) - { - /// ignore unallocated catalog, break - if (!(catalog->Flags & kNeFSFlagCreated)) - { - goto NeFSContinueSearch; - } - - NFS_CATALOG_STRUCT* catalogPtr = new NFS_CATALOG_STRUCT(); - rt_copy_memory(catalog, catalogPtr, sizeof(NFS_CATALOG_STRUCT)); - - kcout << "Found catalog at: " << hex_number(startCatalogList) << endl; - kcout << "Found catalog at: " << catalog->Name << endl; - - out_lba = startCatalogList; - return catalogPtr; - } - - NeFSContinueSearch: - startCatalogList = catalog->NextSibling; - - if (startCatalogList <= kNeFSRootCatalogStartAddress) - break; - } - - if (localSearchFirst) - { - localSearchFirst = false; - startCatalogList = cCtartCatalogList; - - goto NeFSSearchThroughCatalogList; - } - - out_lba = 0UL; - return nullptr; -} - -/// @brief Get catalog from filesystem. -/// @param name the catalog's name/ -/// @return -_Output NFS_CATALOG_STRUCT* NeFileSystemParser::GetCatalog(_Input const Char* name) -{ - Lba unused = 0; - return this->FindCatalog(name, unused); -} - -/// @brief Closes a catalog, (frees it). -/// @param catalog the catalog to close. -/// @return -Boolean NeFileSystemParser::CloseCatalog(_Input _Output NFS_CATALOG_STRUCT* catalog) -{ - if (!catalog) - return false; - - delete catalog; - catalog = nullptr; - - return true; -} - -/// @brief Mark catalog as removed. -/// @param catalog The catalog structure. -/// @return if the catalog was removed or not. -Boolean NeFileSystemParser::RemoveCatalog(_Input const Char* catalog_name) -{ - if (!catalog_name || - StringBuilder::Equals(catalog_name, NeFileSystemHelper::Root())) - { - err_local_get() = kErrorInternal; - return false; - } - - Lba out_lba = 0; - auto catalog = this->FindCatalog(catalog_name, out_lba); - - if (out_lba >= kNeFSCatalogStartAddress || - catalog->Flags & kNeFSFlagCreated) - { - catalog->Flags |= kNeFSFlagDeleted; - - auto drive = kDiskMountpoint.A(); - - rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, - rt_string_len("fs/nefs-packet")); - - drive.fPacket.fPacketLba = out_lba; // the catalog position. - drive.fPacket.fPacketSize = - sizeof(NFS_CATALOG_STRUCT); // size of catalog. roughly the sector size. - drive.fPacket.fPacketContent = catalog; // the catalog itself. - - drive.fOutput(&drive.fPacket); // send packet. - - Char partitionBlockBuf[sizeof(NFS_ROOT_PARTITION_BLOCK)] = {0}; - - drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress; - drive.fPacket.fPacketContent = partitionBlockBuf; - drive.fPacket.fPacketSize = sizeof(NFS_ROOT_PARTITION_BLOCK); - - drive.fInput(&drive.fPacket); - - NFS_ROOT_PARTITION_BLOCK* part_block = - reinterpret_cast(partitionBlockBuf); - - --part_block->CatalogCount; - ++part_block->FreeSectors; - - drive.fOutput(&drive.fPacket); - - return true; - } - - delete catalog; - return false; -} - -/// ***************************************************************** /// -/// Reading,Seek,Tell are unimplemented on catalogs, refer to forks I/O instead. -/// ***************************************************************** /// - -/***********************************************************************************/ -/// @brief Read the catalog data fork. -/// @param catalog -/// @param dataSz -/// @return -/***********************************************************************************/ - -VoidPtr NeFileSystemParser::ReadCatalog(_Input _Output NFS_CATALOG_STRUCT* catalog, - _Input Bool is_rsrc_fork, - _Input SizeT dataSz, - _Input const Char* forkName) -{ - if (!catalog) - { - err_local_get() = kErrorFileNotFound; - return nullptr; - } - - constexpr auto cNeFSCatalogPadding = 4; - - Lba dataForkLba = (!is_rsrc_fork) ? catalog->DataFork : catalog->ResourceFork; - Size dataForkSize = (!is_rsrc_fork) ? catalog->DataForkSize : catalog->ResourceForkSize; - - kcout << "catalog " << catalog->Name - << ", fork: " << hex_number(dataForkLba) << endl; - - NFS_FORK_STRUCT* fs_buf = new NFS_FORK_STRUCT(); - auto drive = kDiskMountpoint.A(); - - rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, - rt_string_len("fs/nefs-packet")); - - NFS_FORK_STRUCT* fs_fork_data = nullptr; - - while (dataForkLba > kNeFSCatalogStartAddress) - { - drive.fPacket.fPacketLba = dataForkLba; - drive.fPacket.fPacketSize = sizeof(NFS_FORK_STRUCT); - drive.fPacket.fPacketContent = fs_buf; - - drive.fInput(&drive.fPacket); - - fs_fork_data = fs_buf; - - kcout << "ForkName: " << fs_fork_data->ForkName << endl; - kcout << "CatalogName: " << fs_fork_data->CatalogName << endl; - - if (StringBuilder::Equals(forkName, fs_fork_data->ForkName) && - StringBuilder::Equals(catalog->Name, fs_fork_data->CatalogName)) - break; - - dataForkLba = fs_fork_data->NextSibling; - } - - if (dataForkLba < kNeFSCatalogStartAddress) - { - delete fs_buf; - return nullptr; - } - - return fs_fork_data; -} - -/***********************************************************************************/ -/// @brief Seek in the data fork. -/// @param catalog the catalog offset. -/// @param off where to seek. -/// @return if the seeking was successful. -/***********************************************************************************/ - -bool NeFileSystemParser::Seek(_Input _Output NFS_CATALOG_STRUCT* catalog, SizeT off) -{ - if (!catalog) - { - err_local_get() = kErrorFileNotFound; - return false; - } - - err_local_get() = kErrorUnimplemented; - return false; -} - -/***********************************************************************************/ -/// @brief Tell where we are inside the data fork. -/// @param catalog -/// @return The position on the file. -/***********************************************************************************/ - -SizeT NeFileSystemParser::Tell(_Input _Output NFS_CATALOG_STRUCT* catalog) -{ - if (!catalog) - { - err_local_get() = kErrorFileNotFound; - return 0; - } - - err_local_get() = kErrorUnimplemented; - return 0; -} - -namespace Kernel::Detail -{ - /***********************************************************************************/ - /// @brief Construct NeFS drives. - /***********************************************************************************/ - Boolean fs_init_newfs(Void) noexcept - { - kcout << "Creating A: drive...\r"; - kcout << "Creating A:\r"; - - kDiskMountpoint.A() = io_construct_main_drive(); - kDiskMountpoint.B() = io_construct_blank_drive(); - kDiskMountpoint.C() = io_construct_blank_drive(); - kDiskMountpoint.D() = io_construct_blank_drive(); - - kcout << "Creating A: [ OK ]\r"; - - return true; - } -} // namespace Kernel::Detail - -#endif // ifdef __FSKIT_INCLUDES_NEFS__ diff --git a/dev/ZKAKit/src/FileMgr.cc b/dev/ZKAKit/src/FileMgr.cc deleted file mode 100644 index 20892c99..00000000 --- a/dev/ZKAKit/src/FileMgr.cc +++ /dev/null @@ -1,52 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include - -/// BUGS: 0 -//! @brief File System Manager API. - -namespace Kernel -{ - STATIC IFilesystemMgr* kMountedFilesystem = nullptr; - - /// @brief FilesystemMgr getter. - /// @return The mounted filesystem. - _Output IFilesystemMgr* IFilesystemMgr::GetMounted() - { - return kMountedFilesystem; - } - - /// @brief Unmount filesystem. - /// @return The unmounted filesystem. - _Output IFilesystemMgr* IFilesystemMgr::Unmount() - { - if (kMountedFilesystem) - { - auto mount = kMountedFilesystem; - kMountedFilesystem = nullptr; - - return mount; - } - - return nullptr; - } - - /// @brief Mount filesystem. - /// @param mount_ptr The filesystem to mount. - /// @return if it succeeded true, otherwise false. - _Output Bool IFilesystemMgr::Mount(_Input IFilesystemMgr* mount_ptr) - { - if (mount_ptr != nullptr) - { - kMountedFilesystem = mount_ptr; - return Yes; - } - - return No; - } -} // namespace Kernel diff --git a/dev/ZKAKit/src/GUIDWizard.cc b/dev/ZKAKit/src/GUIDWizard.cc deleted file mode 100644 index 7224951d..00000000 --- a/dev/ZKAKit/src/GUIDWizard.cc +++ /dev/null @@ -1,72 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - - File: GUIDWizard.cc - Purpose: GUID helper code - - Revision History: - -------------------------------------------- */ - -#include -#include - -// begin of ascii 'readable' characters. (A, C, C, 1, 2) -#define kUUIDAsciiBegin 47 -// @brief Size of UUID. -#define kUUIDSize 37 - -namespace CFKit::XRN::Version1 -{ - auto cf_make_sequence(const ArrayList& uuidSeq) -> Ref - { - GUIDSequence* seq = new GUIDSequence(); - MUST_PASS(seq); - - Ref seq_ref{seq}; - - seq_ref.Leak()->fMs1 = uuidSeq[0]; - seq_ref.Leak()->fMs2 = uuidSeq[1]; - seq_ref.Leak()->fMs3 = uuidSeq[2]; - seq_ref.Leak()->fMs4[0] = uuidSeq[3]; - seq_ref.Leak()->fMs4[1] = uuidSeq[4]; - seq_ref.Leak()->fMs4[2] = uuidSeq[5]; - seq_ref.Leak()->fMs4[3] = uuidSeq[6]; - seq_ref.Leak()->fMs4[4] = uuidSeq[7]; - seq_ref.Leak()->fMs4[5] = uuidSeq[8]; - seq_ref.Leak()->fMs4[6] = uuidSeq[9]; - seq_ref.Leak()->fMs4[7] = uuidSeq[10]; - - return seq_ref; - } - - // @brief Tries to make a guid out of a string. - // This function is not complete for now - auto cf_try_guid_to_string(Ref& seq) -> ErrorOr> - { - Char buf[kUUIDSize]; - - for (SizeT index = 0; index < 16; ++index) - { - buf[index] = seq.Leak()->u8[index] + kUUIDAsciiBegin; - } - - for (SizeT index = 16; index < 24; ++index) - { - buf[index] = seq.Leak()->u16[index] + kUUIDAsciiBegin; - } - - for (SizeT index = 24; index < 28; ++index) - { - buf[index] = seq.Leak()->u32[index] + kUUIDAsciiBegin; - } - - auto view = StringBuilder::Construct(buf); - - if (view) - return ErrorOr>{view.Leak()}; - - return ErrorOr>{-1}; - } -} // namespace CFKit::XRN::Version1 diff --git a/dev/ZKAKit/src/GUIDWrapper.cc b/dev/ZKAKit/src/GUIDWrapper.cc deleted file mode 100644 index a3b141ae..00000000 --- a/dev/ZKAKit/src/GUIDWrapper.cc +++ /dev/null @@ -1,11 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include - -namespace CFKit::XRN -{ -} diff --git a/dev/ZKAKit/src/HardwareThreadScheduler.cc b/dev/ZKAKit/src/HardwareThreadScheduler.cc deleted file mode 100644 index e93b2284..00000000 --- a/dev/ZKAKit/src/HardwareThreadScheduler.cc +++ /dev/null @@ -1,238 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include -#include -#include - -/***********************************************************************************/ -///! @file HardwareThreadScheduler.cc -///! @brief This file handles multi processing in the Kernel. -///! @brief Multi processing is needed for multi-tasking operations. -/***********************************************************************************/ - -namespace Kernel -{ - /***********************************************************************************/ - /// @note Those symbols are needed in order to switch and validate the stack. - /***********************************************************************************/ - - EXTERN Bool hal_check_stack(HAL::StackFramePtr frame_ptr); - EXTERN_C Bool mp_register_process(VoidPtr image, Ptr8 stack_ptr, HAL::StackFramePtr frame, ProcessID pid); - - STATIC HardwareThreadScheduler kHardwareThreadScheduler; - - ///! A HardwareThread class takes care of it's owned hardware thread. - ///! It has a stack for it's core. - - /***********************************************************************************/ - ///! @brief C++ constructor. - /***********************************************************************************/ - HardwareThread::HardwareThread() = default; - - /***********************************************************************************/ - ///! @brief C++ destructor. - /***********************************************************************************/ - HardwareThread::~HardwareThread() = default; - - /***********************************************************************************/ - //! @brief returns the id of the thread. - /***********************************************************************************/ - const ThreadID& HardwareThread::ID() noexcept - { - return fID; - } - - /***********************************************************************************/ - //! @brief returns the kind of thread we have. - /***********************************************************************************/ - const ThreadKind& HardwareThread::Kind() noexcept - { - return fKind; - } - - /***********************************************************************************/ - //! @brief is the thread busy? - //! @return whether the thread is busy or not. - /***********************************************************************************/ - Bool HardwareThread::IsBusy() noexcept - { - STATIC Int64 busy_timer = 0U; - - if (fBusy && busy_timer > this->fPTime) - { - busy_timer = 0U; - fBusy = No; - } - - ++busy_timer; - - return fBusy; - } - - /***********************************************************************************/ - /// @brief Get processor stack frame. - /***********************************************************************************/ - - HAL::StackFramePtr HardwareThread::StackFrame() noexcept - { - MUST_PASS(fStack); - return fStack; - } - - Void HardwareThread::Busy(const Bool busy) noexcept - { - fBusy = busy; - } - - HardwareThread::operator bool() - { - return this->fStack && !this->fBusy; - } - - /***********************************************************************************/ - /// @brief Wakeup the processor. - /***********************************************************************************/ - - Void HardwareThread::Wake(const bool wakeup) noexcept - { - fWakeup = wakeup; - - if (!fWakeup) - mp_hang_thread(fStack); - else - mp_wakeup_thread(fStack); - } - - /***********************************************************************************/ - /// @brief Switch to hardware thread. - /// @param stack the new hardware thread. - /// @retval true stack was changed, code is running. - /// @retval false stack is invalid, previous code is running. - /***********************************************************************************/ - Bool HardwareThread::Switch(VoidPtr image, Ptr8 stack_ptr, HAL::StackFramePtr frame, const ProcessID& pid) - { - if (!frame || - !image || - !stack_ptr) - return No; - - if (!this->IsWakeup()) - return No; - - if (this->IsBusy()) - return No; - - if (!hal_check_stack(frame)) - return No; - - this->fStack = frame; - this->fSourcePID = pid; - - Bool ret = mp_register_process(image, stack_ptr, fStack, this->fSourcePID); - - if (ret) - this->Busy(true); - - return ret; - } - - /***********************************************************************************/ - ///! @brief Tells if processor is waked up. - /***********************************************************************************/ - bool HardwareThread::IsWakeup() noexcept - { - return fWakeup; - } - - /***********************************************************************************/ - ///! @brief Constructor and destructors. - ///! @brief Default constructor. - /***********************************************************************************/ - - HardwareThreadScheduler::HardwareThreadScheduler() = default; - - /***********************************************************************************/ - ///! @brief Default destructor. - /***********************************************************************************/ - HardwareThreadScheduler::~HardwareThreadScheduler() = default; - - /***********************************************************************************/ - /// @brief Shared singleton function - /***********************************************************************************/ - HardwareThreadScheduler& HardwareThreadScheduler::The() - { - return kHardwareThreadScheduler; - } - - /***********************************************************************************/ - /// @brief Get Stack Frame of AP. - /***********************************************************************************/ - HAL::StackFramePtr HardwareThreadScheduler::Leak() noexcept - { - return fThreadList[fCurrentThread].fStack; - } - - /***********************************************************************************/ - /** - * Get Hardware thread at index. - * @param idx the index - * @return the reference to the hardware thread. - */ - /***********************************************************************************/ - Ref HardwareThreadScheduler::operator[](const SizeT& idx) - { - if (idx == 0) - { - if (fThreadList[idx].Kind() != kAPSystemReserved) - { - fThreadList[idx].fKind = kAPBoot; - } - } - else if (idx >= kMaxAPInsideSched) - { - static HardwareThread* fakeThread = nullptr; - return {fakeThread}; - } - - return &fThreadList[idx]; - } - - /***********************************************************************************/ - /** - * Check if thread pool isn't empty. - * @return - */ - /***********************************************************************************/ - HardwareThreadScheduler::operator bool() noexcept - { - return !fThreadList.Empty(); - } - - /***********************************************************************************/ - /** - * Reverse operator bool - * @return - */ - /***********************************************************************************/ - bool HardwareThreadScheduler::operator!() noexcept - { - return fThreadList.Empty(); - } - - /***********************************************************************************/ - /// @brief Returns the amount of core present. - /// @return the number of APs. - /***********************************************************************************/ - SizeT HardwareThreadScheduler::Capacity() noexcept - { - if (fThreadList.Empty()) - return 0UL; - - return fThreadList.Capacity(); - } -} // namespace Kernel diff --git a/dev/ZKAKit/src/Heap.cc b/dev/ZKAKit/src/Heap.cc deleted file mode 100644 index 77425670..00000000 --- a/dev/ZKAKit/src/Heap.cc +++ /dev/null @@ -1,307 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include -#include -#include -#include -#include -#include - -/* ------------------------------------------- - - Revision History: - 10/8/24: FIX: Fix useless long name, alongside a new WR (WriteRead) field. - 20/10/24: Fix mm_new_ and mm_delete_ APIs inside Heap.h header. (amlal) - - ------------------------------------------- */ - -//! @file Heap.cc -//! @brief This serves as the main memory manager. - -#define kKernelHeapMagic (0xD4D7D5) -#define kKernelHeapAlignSz (__BIGGEST_ALIGNMENT__) -#define kKernelHeapMaxSize (gib_cast(2)) - -namespace Kernel -{ - /// @brief Contains data structures and algorithms for the heap. - namespace Detail - { - struct PACKED HEAP_INFORMATION_BLOCK; - - /// @brief Kernel heap information block. - /// Located before the address bytes. - /// | HIB | CLASS/STRUCT/DATA TYPES... | - struct PACKED HEAP_INFORMATION_BLOCK final - { - ///! @brief 32-bit value which contains the magic number of the heap. - UInt32 fMagic : 24; - - ///! @brief Boolean value which tells if the heap is allocated. - Boolean fPresent : 1; - - /// @brief Is this valued owned by the user? - Boolean fWriteRead : 1; - - /// @brief Is this valued owned by the user? - Boolean fUser : 1; - - /// @brief Is this a page pointer? - Boolean fPagePtr : 1; - - /// @brief 32-bit CRC checksum. - UInt32 fCRC32; - - /// @brief 64-bit Allocation flags. - UInt64 fFlags; - - /// @brief 64-bit pointer size. - SizeT fHeapSize; - - /// @brief 64-bit target pointer. - UIntPtr fHeapPtr; - - /// @brief Padding bytes for header. - UInt8 fPadding[kKernelHeapAlignSz]; - }; - - /// @brief Check for heap address validity. - /// @param heap_ptr The address_ptr to check. - /// @return Bool if the pointer is valid or not. - _Output auto mm_check_heap_address(VoidPtr heap_ptr) -> Bool - { - if (!heap_ptr) - return false; - - /// Add that check in case we're having an integer underflow. /// - - auto base_heap = (IntPtr)(heap_ptr) - sizeof(Detail::HEAP_INFORMATION_BLOCK); - - if (base_heap < 0) - { - return false; - } - - return true; - } - - typedef HEAP_INFORMATION_BLOCK* HEAP_INFORMATION_BLOCK_PTR; - } // namespace Detail - - /// @brief Declare a new size for ptr_heap. - /// @param ptr_heap the pointer. - /// @return Newly allocated heap header. - _Output VoidPtr mm_realloc_heap(VoidPtr ptr_heap, SizeT new_sz) - { - if (Detail::mm_check_heap_address(ptr_heap) == No) - return nullptr; - - if (!ptr_heap || new_sz < 1) - return nullptr; - - kcout << "This function is not implemented by minOSKrnl, please use the BSD's realloc instead.\r"; - ke_stop(RUNTIME_CHECK_PROCESS); - - return nullptr; - } - - /// @brief Allocate chunk of memory. - /// @param sz Size of pointer - /// @param wr Read Write bit. - /// @param user User enable bit. - /// @return The newly allocated pointer. - _Output VoidPtr mm_new_heap(const SizeT sz, const bool wr, const bool user) - { - auto sz_fix = sz; - - if (sz_fix == 0) - return nullptr; - - // We can't allocate that big now. - MUST_PASS(sz < kKernelHeapMaxSize); - - sz_fix += sizeof(Detail::HEAP_INFORMATION_BLOCK); - - PageMgr heap_mgr; - auto wrapper = heap_mgr.Request(wr, user, No, sz_fix); - - Detail::HEAP_INFORMATION_BLOCK_PTR heap_info_ptr = - reinterpret_cast( - wrapper.VirtualAddress() + sizeof(Detail::HEAP_INFORMATION_BLOCK)); - - heap_info_ptr->fHeapSize = sz_fix; - heap_info_ptr->fMagic = kKernelHeapMagic; - heap_info_ptr->fCRC32 = No; // dont fill it for now. - heap_info_ptr->fHeapPtr = reinterpret_cast(heap_info_ptr) + sizeof(Detail::HEAP_INFORMATION_BLOCK); - heap_info_ptr->fPagePtr = No; - heap_info_ptr->fWriteRead = wr; - heap_info_ptr->fUser = user; - heap_info_ptr->fPresent = Yes; - - rt_set_memory(heap_info_ptr->fPadding, 0, kKernelHeapAlignSz); - - auto result = reinterpret_cast(heap_info_ptr->fHeapPtr); - - kcout << "Created Heap address: " << hex_number(reinterpret_cast(heap_info_ptr)) << endl; - - return result; - } - - /// @brief Makes a page heap. - /// @param heap_ptr the pointer to make a page heap. - /// @return kErrorSuccess if successful, otherwise an error code. - _Output Int32 mm_make_page(VoidPtr heap_ptr) - { - if (Detail::mm_check_heap_address(heap_ptr) == No) - return kErrorHeapNotPresent; - - Detail::HEAP_INFORMATION_BLOCK_PTR heap_info_ptr = - reinterpret_cast( - (UIntPtr)heap_ptr - sizeof(Detail::HEAP_INFORMATION_BLOCK)); - - if (!heap_info_ptr) - return kErrorHeapNotPresent; - - heap_info_ptr->fPagePtr = true; - - kcout << "Created page address: " << hex_number(reinterpret_cast(heap_info_ptr)) << endl; - - return kErrorSuccess; - } - - /// @brief Overwrites and set the flags of a heap header. - /// @param heap_ptr the pointer to update. - /// @param flags the flags to set. - _Output Int32 mm_make_flags(VoidPtr heap_ptr, UInt64 flags) - { - if (Detail::mm_check_heap_address(heap_ptr) == No) - return kErrorHeapNotPresent; - - Detail::HEAP_INFORMATION_BLOCK_PTR heap_info_ptr = - reinterpret_cast( - (UIntPtr)heap_ptr - sizeof(Detail::HEAP_INFORMATION_BLOCK)); - - if (!heap_info_ptr) - return kErrorHeapNotPresent; - - heap_info_ptr->fFlags = flags; - - return kErrorSuccess; - } - - /// @brief Gets the flags of a heap header. - /// @param heap_ptr the pointer to get. - _Output UInt64 mm_get_flags(VoidPtr heap_ptr) - { - Detail::HEAP_INFORMATION_BLOCK_PTR heap_info_ptr = - reinterpret_cast( - (UIntPtr)heap_ptr - sizeof(Detail::HEAP_INFORMATION_BLOCK)); - - if (!heap_info_ptr) - return kErrorHeapNotPresent; - - return heap_info_ptr->fFlags; - } - - /// @brief Declare pointer as free. - /// @param heap_ptr the pointer. - /// @return - _Output Int32 mm_delete_heap(VoidPtr heap_ptr) - { - if (Detail::mm_check_heap_address(heap_ptr) == No) - return kErrorHeapNotPresent; - - Detail::HEAP_INFORMATION_BLOCK_PTR heap_info_ptr = - reinterpret_cast( - (UIntPtr)(heap_ptr) - sizeof(Detail::HEAP_INFORMATION_BLOCK)); - - if (heap_info_ptr && heap_info_ptr->fMagic == kKernelHeapMagic) - { - if (!heap_info_ptr->fPresent) - { - return kErrorHeapNotPresent; - } - - if (heap_info_ptr->fCRC32 != 0) - { - if (heap_info_ptr->fCRC32 != - ke_calculate_crc32((Char*)heap_info_ptr->fHeapPtr, - heap_info_ptr->fHeapSize)) - { - if (!heap_info_ptr->fUser) - { - ke_stop(RUNTIME_CHECK_POINTER); - } - } - } - - heap_info_ptr->fHeapSize = 0UL; - heap_info_ptr->fPresent = No; - heap_info_ptr->fHeapPtr = 0; - heap_info_ptr->fCRC32 = 0; - heap_info_ptr->fWriteRead = No; - heap_info_ptr->fUser = No; - heap_info_ptr->fMagic = 0; - - PTEWrapper pageWrapper(No, No, No, reinterpret_cast(heap_info_ptr) - sizeof(Detail::HEAP_INFORMATION_BLOCK)); - Ref pteAddress{pageWrapper}; - - PageMgr heap_mgr; - heap_mgr.Free(pteAddress); - - kcout << "Freed Heap address successfully." << endl; - - return kErrorSuccess; - } - - return kErrorInternal; - } - - /// @brief Check if pointer is a valid Kernel pointer. - /// @param heap_ptr the pointer - /// @return if it exists. - _Output Boolean mm_is_valid_heap(VoidPtr heap_ptr) - { - if (heap_ptr && HAL::mm_is_bitmap(heap_ptr)) - { - Detail::HEAP_INFORMATION_BLOCK_PTR heap_info_ptr = - reinterpret_cast( - (UIntPtr)(heap_ptr) - sizeof(Detail::HEAP_INFORMATION_BLOCK)); - - if (heap_info_ptr && heap_info_ptr->fPresent && heap_info_ptr->fMagic == kKernelHeapMagic) - { - return Yes; - } - } - - return No; - } - - /// @brief Protect the heap with a CRC value. - /// @param heap_ptr HIB pointer. - /// @return if it valid: point has crc now., otherwise fail. - _Output Boolean mm_protect_heap(VoidPtr heap_ptr) - { - if (heap_ptr) - { - Detail::HEAP_INFORMATION_BLOCK_PTR heap_info_ptr = - reinterpret_cast( - (UIntPtr)heap_ptr - sizeof(Detail::HEAP_INFORMATION_BLOCK)); - - if (heap_info_ptr && heap_info_ptr->fPresent && kKernelHeapMagic == heap_info_ptr->fMagic) - { - heap_info_ptr->fCRC32 = - ke_calculate_crc32((Char*)heap_info_ptr->fHeapPtr, heap_info_ptr->fHeapSize); - - return Yes; - } - } - - return No; - } -} // namespace Kernel diff --git a/dev/ZKAKit/src/IDLLObject.cc b/dev/ZKAKit/src/IDLLObject.cc deleted file mode 100644 index 7067d1fa..00000000 --- a/dev/ZKAKit/src/IDLLObject.cc +++ /dev/null @@ -1,15 +0,0 @@ -/* - * ======================================================== - * - * minoskrnl - * Copyright (C) 2024, Theater Quality Inc, all rights reserved., all rights reserved. - * - * ======================================================== - */ - -#include -#include - -#include - -using namespace Kernel; diff --git a/dev/ZKAKit/src/IPEFDLLObject.cc b/dev/ZKAKit/src/IPEFDLLObject.cc deleted file mode 100644 index a7d80081..00000000 --- a/dev/ZKAKit/src/IPEFDLLObject.cc +++ /dev/null @@ -1,103 +0,0 @@ -/* - * ======================================================== - * - * minoskrnl - * Copyright (C) 2024, Theater Quality Inc, all rights reserved., all rights reserved. - * - * ======================================================== - */ - -#include -#include -#include -#include -#include -#include - -/* ------------------------------------------- - - Revision History: - - 01/02/24: Reworked dll ABI, expect a rtl_init_dylib and - rtl_fini_dylib (amlel) 15/02/24: Breaking changes, changed the name of the - routines. (amlel) - - 07/28/24: Replace rt_library_free with rtl_fini_dylib - - 10/8/24: FIX: Fix log comment. - - ------------------------------------------- */ - -using namespace Kernel; - -/***********************************************************************************/ -/// @file IPEFDLLObject.cc -/// @brief PEF's DLL runtime. -/***********************************************************************************/ - -/***********************************************************************************/ -/** @brief Library initializer. */ -/***********************************************************************************/ - -EXTERN_C IDLL rtl_init_dylib(UserProcess* header) -{ - IDLL dll_obj = tls_new_class(); - - if (!dll_obj) - { - header->Crash(); - return nullptr; - } - - dll_obj->Mount(tls_new_class()); - - if (!dll_obj->Get()) - { - tls_delete_class(dll_obj); - header->Crash(); - - return nullptr; - } - - dll_obj->Get()->ImageObject = - header->Image.fBlob; - - if (!dll_obj->Get()->ImageObject) - { - tls_delete_class(dll_obj); - header->Crash(); - - return nullptr; - } - - dll_obj->Get()->ImageEntrypointOffset = - dll_obj->Load(kPefStart, rt_string_len(kPefStart, 0), kPefCode); - - return dll_obj; -} - -/***********************************************************************************/ -/** @brief Frees the dll_obj. */ -/** @note Please check if the dll_obj got freed! */ -/** @param dll_obj The dll_obj to free. */ -/** @param successful Reports if successful or not. */ -/***********************************************************************************/ - -EXTERN_C Void rtl_fini_dylib(UserProcess* header, IDLL dll_obj, Bool* successful) -{ - MUST_PASS(successful); - - // sanity check (will also trigger a bug check if this fails) - if (dll_obj == nullptr) - { - *successful = false; - header->Crash(); - } - - delete dll_obj->Get(); - delete dll_obj; - - dll_obj = nullptr; - - *successful = true; -} diff --git a/dev/ZKAKit/src/IndexableProperty.cc b/dev/ZKAKit/src/IndexableProperty.cc deleted file mode 100644 index f5328870..00000000 --- a/dev/ZKAKit/src/IndexableProperty.cc +++ /dev/null @@ -1,57 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include -#include -#include - -/// @brief File indexer API for fast path access. -/// BUGS: 0 - -#define kMaxLenIndexer (256U) - -namespace Kernel -{ - namespace Indexer - { - IndexProperty& IndexableProperty::Leak() noexcept - { - return fIndex; - } - - Void IndexableProperty::AddFlag(Int16 flag) - { - fFlags |= flag; - } - - Void IndexableProperty::RemoveFlag(Int16 flag) - { - fFlags &= flag; - } - - Int16 IndexableProperty::HasFlag(Int16 flag) - { - return fFlags & flag; - } - - /// @brief Index a file into the indexer instance. - /// @param filename filesystem path to access. - /// @param filenameLen used bytes in path. - /// @param indexer the filesystem indexer. - /// @return none, check before if indexer can be claimed (using indexer.HasFlag(kIndexerClaimed)). - Void fs_index_file(const Char* filename, SizeT filenameLen, IndexableProperty& indexer) - { - if (!indexer.HasFlag(kIndexerClaimed)) - { - indexer.AddFlag(kIndexerClaimed); - rt_copy_memory((VoidPtr)indexer.Leak().Path, (VoidPtr)filename, filenameLen); - - kcout << "FSKit: Indexed new file: " << filename << endl; - } - } - } // namespace Indexer -} // namespace Kernel diff --git a/dev/ZKAKit/src/Json.cc b/dev/ZKAKit/src/Json.cc deleted file mode 100644 index f9fef7eb..00000000 --- a/dev/ZKAKit/src/Json.cc +++ /dev/null @@ -1,10 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include - -/// @brief Undefined object, is null in length. -INIT_OBJECT(Kernel::JSON::kNull, Kernel::JSON); diff --git a/dev/ZKAKit/src/KString.cc b/dev/ZKAKit/src/KString.cc deleted file mode 100644 index 8e40aa42..00000000 --- a/dev/ZKAKit/src/KString.cc +++ /dev/null @@ -1,217 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include - -/// @file KString.cc -/// @brief Kernel String manipulation file. - -namespace Kernel -{ - Char* KString::Data() - { - return fData; - } - - const Char* KString::CData() const - { - return fData; - } - - Size KString::Length() const - { - return fDataSz; - } - - bool KString::operator==(const KString& rhs) const - { - if (rhs.Length() != this->Length()) - return false; - - for (Size index = 0; index < this->Length(); ++index) - { - if (rhs.fData[index] != fData[index]) - return false; - } - - return true; - } - - bool KString::operator==(const Char* rhs) const - { - if (rt_string_len(rhs) != this->Length()) - return false; - - for (Size index = 0; index < rt_string_len(rhs); ++index) - { - if (rhs[index] != fData[index]) - return false; - } - - return true; - } - - bool KString::operator!=(const KString& rhs) const - { - if (rhs.Length() != this->Length()) - return false; - - for (Size index = 0; index < rhs.Length(); ++index) - { - if (rhs.fData[index] == fData[index]) - return false; - } - - return true; - } - - bool KString::operator!=(const Char* rhs) const - { - if (rt_string_len(rhs) != this->Length()) - return false; - - for (Size index = 0; index < rt_string_len(rhs); ++index) - { - if (rhs[index] == fData[index]) - return false; - } - - return true; - } - - ErrorOr StringBuilder::Construct(const Char* data) - { - if (!data || *data == 0) - return {}; - - KString* view = new KString(rt_string_len(data)); - (*view) += data; - - return ErrorOr(*view); - } - - const Char* StringBuilder::FromBool(const Char* fmt, bool i) - { - if (!fmt) - return ("?"); - - const Char* boolean_expr = i ? "YES" : "NO"; - Char* ret = (Char*)rtl_alloca((sizeof(char) * i) ? 4 : 5 + rt_string_len(fmt)); - - if (!ret) - return ("?"); - - const auto fmt_len = rt_string_len(fmt); - const auto res_len = rt_string_len(boolean_expr); - - for (Size idx = 0; idx < fmt_len; ++idx) - { - if (fmt[idx] == '%') - { - SizeT result_cnt = idx; - - for (auto y_idx = idx; y_idx < res_len; ++y_idx) - { - ret[result_cnt] = boolean_expr[y_idx]; - ++result_cnt; - } - - break; - } - - ret[idx] = fmt[idx]; - } - - return ret; - } - - bool StringBuilder::Equals(const Char* lhs, const Char* rhs) - { - if (rt_string_len(rhs) != rt_string_len(lhs)) - return false; - - for (Size index = 0; index < rt_string_len(rhs); ++index) - { - if (rhs[index] != lhs[index]) - return false; - } - - return true; - } - - bool StringBuilder::Equals(const WideChar* lhs, const WideChar* rhs) - { - for (Size index = 0; rhs[index] != 0; ++index) - { - if (rhs[index] != lhs[index]) - return false; - } - - return true; - } - - const Char* StringBuilder::Format(const Char* fmt, const Char* fmt2) - { - if (!fmt || !fmt2) - return ("?"); - - Char* ret = - (Char*)rtl_alloca(sizeof(char) * rt_string_len(fmt2) + rt_string_len(fmt)); - - if (!ret) - return ("?"); - - for (Size idx = 0; idx < rt_string_len(fmt); ++idx) - { - if (fmt[idx] == '%') - { - Size result_cnt = idx; - for (Size y_idx = 0; y_idx < rt_string_len(fmt2); ++y_idx) - { - ret[result_cnt] = fmt2[y_idx]; - ++result_cnt; - } - - break; - } - - ret[idx] = fmt[idx]; - } - - return ret; - } - - STATIC void rt_string_append(Char* lhs, const Char* rhs, Int32 cur) - { - SizeT sz_rhs = rt_string_len(rhs); - SizeT rhs_i = 0; - - for (; rhs_i < sz_rhs; ++rhs_i) - { - lhs[rhs_i + cur] = rhs[rhs_i]; - } - } - - KString& KString::operator+=(const Char* rhs) - { - rt_string_append(this->fData, rhs, this->fCur); - this->fCur += rt_string_len(rhs); - - return *this; - } - - KString& KString::operator+=(const KString& rhs) - { - if (rt_string_len(rhs.fData) > this->Length()) - return *this; - - rt_string_append(this->fData, const_cast(rhs.fData), this->fCur); - this->fCur += rt_string_len(const_cast(rhs.fData)); - - return *this; - } -} // namespace Kernel diff --git a/dev/ZKAKit/src/KernelMain.cc b/dev/ZKAKit/src/KernelMain.cc deleted file mode 100644 index 6bafd979..00000000 --- a/dev/ZKAKit/src/KernelMain.cc +++ /dev/null @@ -1,140 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Technologies - - File: Main.cxx - Purpose: Main entrypoint of kernel. - -------------------------------------------- */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -STATIC CG::ML_WINDOW_STRUCT* kKernelWnd = nullptr; - -namespace Kernel::Detail -{ - /// @brief Filesystem auto formatter, additional checks are also done by the class. - class FilesystemInstaller final - { - Kernel::NeFileSystemMgr* fNeFS{nullptr}; - - public: - /// @brief wizard constructor. - FilesystemInstaller() - { - fNeFS = (Kernel::NeFileSystemMgr*)Kernel::IFilesystemMgr::GetMounted(); - - if (fNeFS && fNeFS->GetParser()) - { - constexpr auto kFolderInfo = "META-XML"; - const auto kFolderCount = 7; - const char* kFolderStr[kFolderCount] = { - "/Boot/", "/System/", "/Support/", "/Applications/", - "/Users/", "/Library/", "/Mount/"}; - - for (Kernel::SizeT dir_index = 0UL; dir_index < kFolderCount; ++dir_index) - { - auto catalog_folder = fNeFS->GetParser()->GetCatalog(kFolderStr[dir_index]); - - if (catalog_folder) - { - delete catalog_folder; - catalog_folder = nullptr; - - continue; - } - - catalog_folder = fNeFS->GetParser()->CreateCatalog(kFolderStr[dir_index], 0, - kNeFSCatalogKindDir); - - NFS_FORK_STRUCT fork_folder{0}; - - Kernel::rt_copy_memory((Kernel::VoidPtr)(kFolderInfo), fork_folder.ForkName, - Kernel::rt_string_len(kFolderInfo)); - - Kernel::rt_copy_memory((Kernel::VoidPtr)(catalog_folder->Name), - fork_folder.CatalogName, - Kernel::rt_string_len(catalog_folder->Name)); - - fork_folder.DataSize = kNeFSForkSize; - fork_folder.ResourceId = 0; - fork_folder.ResourceKind = Kernel::kNeFSRsrcForkKind; - fork_folder.Kind = Kernel::kNeFSDataForkKind; - - Kernel::KString folder_metadata(2048); - - folder_metadata += - "\r

Kind: folder

\r

Created by: system

\r

Edited by: " - "system

\r

Volume Type: Zeta

\r"; - - folder_metadata += "

Path: "; - folder_metadata += kFolderStr[dir_index]; - folder_metadata += "

\r"; - - const Kernel::SizeT kMetaDataSz = kNeFSSectorSz; - - fNeFS->GetParser()->CreateFork(catalog_folder, fork_folder); - - fNeFS->GetParser()->WriteCatalog( - catalog_folder, true, (Kernel::VoidPtr)(folder_metadata.CData()), - kMetaDataSz, kFolderInfo); - - delete catalog_folder; - catalog_folder = nullptr; - } - } - } - - ~FilesystemInstaller() = default; - - ZKA_COPY_DEFAULT(FilesystemInstaller); - - /// @brief Grab the disk's NewFS reference. - /// @return NeFileSystemMgr the filesystem interface - Kernel::NeFileSystemMgr* Leak() - { - return fNeFS; - } - }; -} // namespace Kernel::Detail - -/// @brief Application entrypoint. -/// @param Void -/// @return Void -EXTERN_C Kernel::Void rtl_kernel_main(Kernel::SizeT argc, char** argv, char** envp, Kernel::SizeT envp_len) -{ - Kernel::IFilesystemMgr::Mount(new Kernel::NeFileSystemMgr()); - - kKernelWnd = CG::CGCreateWindow(CG::kWndFlagWindow, "ZkaOS | " KERNEL_VERSION, "ZkaWindow", 10, 10, 305, 114); - - if (kKernelWnd) - { - kKernelWnd->w_sub_type = CG::kWndFlagCloseControlSelect; - kKernelWnd->w_child_count = 0; - kKernelWnd->w_type = CG::kWndFlagWindow; - kKernelWnd->w_needs_repaint = Yes; - kKernelWnd->w_display_ptr = nullptr; - - CG::CGDrawWindow(kKernelWnd); - - CG::CGDrawStringToWnd(kKernelWnd, "Welcome to ZKA.", 10, 10, RGB(0, 0, 0)); - - Kernel::Detail::FilesystemInstaller installer; - } -} diff --git a/dev/ZKAKit/src/LPC.cc b/dev/ZKAKit/src/LPC.cc deleted file mode 100644 index 07a7b982..00000000 --- a/dev/ZKAKit/src/LPC.cc +++ /dev/null @@ -1,34 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include - -namespace Kernel -{ - STATIC Bool kRaiseOnBugCheck = false; - - /// @brief Does a system wide bug check. - /// @param void no params. - /// @return if error-free: false, otherwise true. - Boolean err_bug_check(void) noexcept - { - if (kRaiseOnBugCheck) - { - ke_stop(RUNTIME_CHECK_BAD_BEHAVIOR); - } - - return No; - } - - /// @brief Tells if we should raise a bug check not. - /// @param void - /// @return void - Void err_bug_check_raise(Void) noexcept - { - kRaiseOnBugCheck = true; - } -} // namespace Kernel diff --git a/dev/ZKAKit/src/LockDelegate.cc b/dev/ZKAKit/src/LockDelegate.cc deleted file mode 100644 index ebcbe45a..00000000 --- a/dev/ZKAKit/src/LockDelegate.cc +++ /dev/null @@ -1,12 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include - -namespace Kernel -{ - /// @note Leave it empty for now. -} // namespace Kernel diff --git a/dev/ZKAKit/src/MutableArray.cc b/dev/ZKAKit/src/MutableArray.cc deleted file mode 100644 index 4329a2ea..00000000 --- a/dev/ZKAKit/src/MutableArray.cc +++ /dev/null @@ -1,7 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include diff --git a/dev/ZKAKit/src/NeFS+FileMgr.cc b/dev/ZKAKit/src/NeFS+FileMgr.cc deleted file mode 100644 index c57785dc..00000000 --- a/dev/ZKAKit/src/NeFS+FileMgr.cc +++ /dev/null @@ -1,249 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include - -#ifndef __ZKA_MINIMAL_OS__ -#ifdef __FSKIT_INCLUDES_NEFS__ - -/// @brief NeFS File manager. -/// BUGS: 0 - -namespace Kernel -{ - /// @brief C++ constructor - NeFileSystemMgr::NeFileSystemMgr() - { - MUST_PASS(Detail::fs_init_newfs()); - - NeFileSystemParser* fImpl; - mm_new_class(&fImpl); - MUST_PASS(fImpl); - - kcout << "We are done allocating NeFileSystemParser...\r"; - } - - NeFileSystemMgr::~NeFileSystemMgr() - { - if (fImpl) - { - kcout << "Destroying NeFileSystemParser...\r"; - - mm_delete_class(&fImpl); - } - } - - /// @brief Removes a node from the filesystem. - /// @param path The filename - /// @return If it was deleted or not. - bool NeFileSystemMgr::Remove(_Input const Char* path) - { - if (path == nullptr || *path == 0) - return false; - - return fImpl->RemoveCatalog(path); - } - - /// @brief Creates a node with the specified. - /// @param path The filename path. - /// @return The Node pointer. - NodePtr NeFileSystemMgr::Create(_Input const Char* path) - { - return node_cast(fImpl->CreateCatalog(path)); - } - - /// @brief Creates a node with is a directory. - /// @param path The filename path. - /// @return The Node pointer. - NodePtr NeFileSystemMgr::CreateDirectory(const Char* path) - { - return node_cast(fImpl->CreateCatalog(path, 0, kNeFSCatalogKindDir)); - } - - /// @brief Creates a node with is a alias. - /// @param path The filename path. - /// @return The Node pointer. - NodePtr NeFileSystemMgr::CreateAlias(const Char* path) - { - return node_cast(fImpl->CreateCatalog(path, 0, kNeFSCatalogKindAlias)); - } - - /// @brief Creates a node with is a page file. - /// @param path The filename path. - /// @return The Node pointer. - NodePtr NeFileSystemMgr::CreateSwapFile(const Char* path) - { - return node_cast(fImpl->CreateCatalog(path, 0, kNeFSCatalogKindPage)); - } - - /// @brief Gets the root directory. - /// @return - const Char* NeFileSystemHelper::Root() - { - return kNeFSRoot; - } - - /// @brief Gets the up-dir directory. - /// @return - const Char* NeFileSystemHelper::UpDir() - { - return kNeFSUpDir; - } - - /// @brief Gets the separator character. - /// @return - const Char NeFileSystemHelper::Separator() - { - return kNeFSSeparator; - } - - /// @brief Gets the metafile character. - /// @return - const Char NeFileSystemHelper::MetaFile() - { - return kNeFSMetaFilePrefix; - } - - /// @brief Opens a new file. - /// @param path - /// @param r - /// @return - _Output NodePtr NeFileSystemMgr::Open(_Input const Char* path, _Input const Char* r) - { - if (!path || *path == 0) - return nullptr; - - if (!r || *r == 0) - return nullptr; - - auto catalog = fImpl->GetCatalog(path); - - return node_cast(catalog); - } - - /// @brief Writes to a catalog's fork. - /// @param node the node ptr. - /// @param data the data. - /// @param flags the size. - /// @return - Void NeFileSystemMgr::Write(_Input NodePtr node, _Input VoidPtr data, _Input Int32 flags, _Input SizeT size) - { - if (!node) - return; - if (!size) - return; - - constexpr auto cDataForkName = kNeFSDataFork; - this->Write(cDataForkName, node, data, flags, size); - } - - /// @brief Read from filesystem fork. - /// @param node the catalog node. - /// @param flags the flags with it. - /// @param sz the size to read. - /// @return - _Output VoidPtr NeFileSystemMgr::Read(_Input NodePtr node, _Input Int32 flags, _Input SizeT size) - { - if (!node) - return nullptr; - if (!size) - return nullptr; - - constexpr auto cDataForkName = kNeFSDataFork; - return this->Read(cDataForkName, node, flags, size); - } - - Void NeFileSystemMgr::Write(_Input const Char* name, - _Input NodePtr node, - _Input VoidPtr data, - _Input Int32 flags, - _Input SizeT size) - { - if (!size || - size > kNeFSForkSize) - return; - - if (!data) - return; - - ZKA_UNUSED(flags); - - if ((reinterpret_cast(node))->Kind == kNeFSCatalogKindFile) - fImpl->WriteCatalog(reinterpret_cast(node), (flags & kFileFlagRsrc ? true : false), data, size, - name); - } - - _Output VoidPtr NeFileSystemMgr::Read(_Input const Char* name, - _Input NodePtr node, - _Input Int32 flags, - _Input SizeT sz) - { - if (sz > kNeFSForkSize) - return nullptr; - - if (!sz) - return nullptr; - - ZKA_UNUSED(flags); - - if ((reinterpret_cast(node))->Kind == kNeFSCatalogKindFile) - return fImpl->ReadCatalog(reinterpret_cast(node), (flags & kFileFlagRsrc ? true : false), sz, - name); - - return nullptr; - } - - /// @brief Seek from Catalog. - /// @param node - /// @param off - /// @retval true always returns false, this is unimplemented. - /// @retval false always returns this, it is unimplemented. - - _Output Bool NeFileSystemMgr::Seek(NodePtr node, SizeT off) - { - if (!node || off == 0) - return false; - - return fImpl->Seek(reinterpret_cast(node), off); - } - - /// @brief Tell where the catalog is. - /// @param node - /// @retval true always returns false, this is unimplemented. - /// @retval false always returns this, it is unimplemented. - - _Output SizeT NeFileSystemMgr::Tell(NodePtr node) - { - if (!node) - return kNPos; - - return fImpl->Tell(reinterpret_cast(node)); - } - - /// @brief Rewinds the catalog. - /// @param node - /// @retval true always returns false, this is unimplemented. - /// @retval false always returns this, it is unimplemented. - - _Output Bool NeFileSystemMgr::Rewind(NodePtr node) - { - if (!node) - return false; - - return this->Seek(node, 0); - } - - /// @brief Returns the filesystem parser. - /// @return the Filesystem parser class. - _Output NeFileSystemParser* NeFileSystemMgr::GetParser() noexcept - { - return fImpl; - } -} // namespace Kernel - -#endif // ifdef __FSKIT_INCLUDES_NEFS__ -#endif // ifndef __ZKA_MINIMAL_OS__ diff --git a/dev/ZKAKit/src/NeFS+IO.cc b/dev/ZKAKit/src/NeFS+IO.cc deleted file mode 100644 index 902b2a5d..00000000 --- a/dev/ZKAKit/src/NeFS+IO.cc +++ /dev/null @@ -1,101 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include - -/************************************************************* - * - * File: NeFS+IO.cc - * Purpose: Filesystem to mountpoint interface. - * Date: 3/26/24 - * - * Copyright (C) 2024, Theater Quality Inc, all rights reserved., all rights reserved. - * - *************************************************************/ - -#ifdef __FSKIT_INCLUDES_NEFS__ - -#include - -/// Useful macros. - -#define NEFS_WRITE(DRV, TRAITS, MP) (MP->DRV()).fOutput(&TRAITS) -#define NEFS_READ(DRV, TRAITS, MP) (MP->DRV()).fInput(&TRAITS) - -using namespace Kernel; - -/// @brief Read from newfs disk. -/// @param Mnt mounted interface. -/// @param DrvTrait drive info -/// @param DrvIndex drive index. -/// @return -Int32 fs_newfs_read(MountpointInterface* Mnt, DriveTrait& DrvTrait, Int32 DrvIndex) -{ - if (!Mnt) - return 1; - - DrvTrait.fPacket.fPacketGood = false; - - switch (DrvIndex) - { - case kNeFSSubDriveA: { - NEFS_READ(A, DrvTrait.fPacket, Mnt); - break; - } - case kNeFSSubDriveB: { - NEFS_READ(B, DrvTrait.fPacket, Mnt); - break; - } - case kNeFSSubDriveC: { - NEFS_READ(C, DrvTrait.fPacket, Mnt); - break; - } - case kNeFSSubDriveD: { - NEFS_READ(D, DrvTrait.fPacket, Mnt); - break; - } - } - - return DrvTrait.fPacket.fPacketGood; -} - -/// @brief Write to newfs disk. -/// @param Mnt mounted interface. -/// @param DrvTrait drive info -/// @param DrvIndex drive index. -/// @return -Int32 fs_newfs_write(MountpointInterface* Mnt, DriveTrait& DrvTrait, Int32 DrvIndex) -{ - if (!Mnt) - return 1; - - DrvTrait.fPacket.fPacketGood = false; - - switch (DrvIndex) - { - case kNeFSSubDriveA: { - NEFS_WRITE(A, DrvTrait.fPacket, Mnt); - break; - } - case kNeFSSubDriveB: { - NEFS_WRITE(B, DrvTrait.fPacket, Mnt); - break; - } - case kNeFSSubDriveC: { - NEFS_WRITE(C, DrvTrait.fPacket, Mnt); - break; - } - case kNeFSSubDriveD: { - NEFS_WRITE(D, DrvTrait.fPacket, Mnt); - break; - } - } - - return DrvTrait.fPacket.fPacketGood; -} - -#endif // ifdef __FSKIT_INCLUDES_NEFS__ diff --git a/dev/ZKAKit/src/Network/IP.cc b/dev/ZKAKit/src/Network/IP.cc deleted file mode 100644 index 2a07bc62..00000000 --- a/dev/ZKAKit/src/Network/IP.cc +++ /dev/null @@ -1,126 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include - -namespace Kernel -{ - char* RawIPAddress::Address() - { - return fAddr; - } - - RawIPAddress::RawIPAddress(char bytes[4]) - { - rt_copy_memory(bytes, fAddr, 4); - } - - bool RawIPAddress::operator==(const RawIPAddress& ipv4) - { - for (Size index = 0; index < 4; ++index) - { - if (ipv4.fAddr[index] != fAddr[index]) - return false; - } - - return true; - } - - bool RawIPAddress::operator!=(const RawIPAddress& ipv4) - { - for (Size index = 0; index < 4; ++index) - { - if (ipv4.fAddr[index] == fAddr[index]) - return false; - } - - return true; - } - - char& RawIPAddress::operator[](const Size& index) - { - kcout << "[RawIPAddress::operator[]] Fetching Index...\r"; - - static char IP_PLACEHOLDER = '0'; - if (index > 4) - return IP_PLACEHOLDER; - - return fAddr[index]; - } - - RawIPAddress6::RawIPAddress6(char bytes[8]) - { - rt_copy_memory(bytes, fAddr, 8); - } - - char& RawIPAddress6::operator[](const Size& index) - { - kcout << "[RawIPAddress6::operator[]] Fetching Index...\r"; - - static char IP_PLACEHOLDER = '0'; - if (index > 8) - return IP_PLACEHOLDER; - - return fAddr[index]; - } - - bool RawIPAddress6::operator==(const RawIPAddress6& ipv6) - { - for (SizeT index = 0; index < 8; ++index) - { - if (ipv6.fAddr[index] != fAddr[index]) - return false; - } - - return true; - } - - bool RawIPAddress6::operator!=(const RawIPAddress6& ipv6) - { - for (SizeT index = 0; index < 8; ++index) - { - if (ipv6.fAddr[index] == fAddr[index]) - return false; - } - - return true; - } - - ErrorOr IPFactory::ToKString(Ref& ipv6) - { - auto str = StringBuilder::Construct(ipv6.Leak().Address()); - return str; - } - - ErrorOr IPFactory::ToKString(Ref& ipv4) - { - auto str = StringBuilder::Construct(ipv4.Leak().Address()); - return str; - } - - bool IPFactory::IpCheckVersion4(const Char* ip) - { - int cnter = 0; - - for (Size base = 0; base < rt_string_len(ip); ++base) - { - if (ip[base] == '.') - { - cnter = 0; - } - else - { - if (cnter == 3) - return false; - - ++cnter; - } - } - - return true; - } -} // namespace Kernel diff --git a/dev/ZKAKit/src/Network/IPC.cc b/dev/ZKAKit/src/Network/IPC.cc deleted file mode 100644 index 05d9d804..00000000 --- a/dev/ZKAKit/src/Network/IPC.cc +++ /dev/null @@ -1,111 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include -#include - -using namespace Kernel; - -/// @internal -/// @brief The internal sanitize function. -Bool ipc_int_sanitize_packet(IPCMessage* pckt) -{ - auto endian = rtl_deduce_endianess(pckt, ((Char*)pckt)[0]); - - switch (endian) - { - case Endian::kEndianBig: { - if (pckt->IpcEndianess == kIPCLittleEndian) - goto ipc_check_failed; - - break; - } - case Endian::kEndianLittle: { - if (pckt->IpcEndianess == kIPCBigEndian) - goto ipc_check_failed; - - break; - } - case Endian::kEndianMixed: { - if (pckt->IpcEndianess == kIPCMixedEndian) - goto ipc_check_failed; - - break; - } - default: - goto ipc_check_failed; - } - - if (pckt->IpcFrom == pckt->IpcTo || - pckt->IpcPacketSize > kIPCMsgSize) - { - goto ipc_check_failed; - } - - return pckt->IpcPacketSize > 1 && pckt->IpcHeaderMagic == kIPCHeaderMagic; - -ipc_check_failed: - err_local_get() = kErrorIPC; - return false; -} - -namespace Kernel -{ - /// @brief Sanitize packet function - /// @retval true packet is correct. - /// @retval false packet is incorrect and process has crashed. - Bool ipc_sanitize_packet(IPCMessage* pckt) - { - if (!pckt || - !ipc_int_sanitize_packet(pckt)) - { - UserProcessScheduler::The().GetCurrentProcess().Leak().Crash(); - return false; - } - - return true; - } - - /// @brief Construct packet function - /// @retval true packet is correct. - /// @retval false packet is incorrect and process has crashed. - Bool ipc_construct_packet(_Output IPCMessage** pckt_in) - { - // don't do anything if it's valid already. - if (*pckt_in) - return true; - - // crash process if the packet pointer of pointer is NULL. - if (!pckt_in) - { - UserProcessScheduler::The().GetCurrentProcess().Leak().Crash(); - return false; - } - - *pckt_in = new IPCMessage(); - - if (*pckt_in) - { - auto endian = rtl_deduce_endianess((*pckt_in), ((Char*)(*pckt_in))[0]); - - (*pckt_in)->IpcHeaderMagic = kIPCHeaderMagic; - - (*pckt_in)->IpcEndianess = static_cast(endian); - (*pckt_in)->IpcPacketSize = sizeof(IPCMessage); - - (*pckt_in)->IpcTo.UserProcessID = 0; - (*pckt_in)->IpcTo.UserProcessTeam = 0; - - (*pckt_in)->IpcFrom.UserProcessID = Kernel::UserProcessScheduler::The().GetCurrentProcess().Leak().ProcessId; - (*pckt_in)->IpcFrom.UserProcessTeam = Kernel::UserProcessScheduler::The().CurrentTeam().mTeamId; - - return Yes; - } - - return No; - } -} // namespace Kernel diff --git a/dev/ZKAKit/src/Network/NetworkDevice.cc b/dev/ZKAKit/src/Network/NetworkDevice.cc deleted file mode 100644 index 5a7ea487..00000000 --- a/dev/ZKAKit/src/Network/NetworkDevice.cc +++ /dev/null @@ -1,35 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include - -namespace Kernel -{ - /// \brief Getter for fNetworkName. - const Char* NetworkDevice::Name() const - { - return this->fNetworkName; - } - - /// \brief Setter for fNetworkName. - Boolean NetworkDevice::Name(const Char* strView) - { - if (strView == nullptr) - return false; - - if (*strView == 0) - return false; - - if (rt_string_len(strView) > cNetworkNameLen) - return false; - - rt_copy_memory((VoidPtr)strView, - (VoidPtr)this->fNetworkName, rt_string_len(strView)); - - return true; - } -} // namespace Kernel diff --git a/dev/ZKAKit/src/New+Delete.cc b/dev/ZKAKit/src/New+Delete.cc deleted file mode 100644 index 03afc117..00000000 --- a/dev/ZKAKit/src/New+Delete.cc +++ /dev/null @@ -1,50 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include - -void* operator new[](size_t sz) -{ - if (sz == 0) - ++sz; - - return Kernel::mm_new_heap(sz, true, false); -} - -void* operator new(size_t sz) -{ - if (sz == 0) - ++sz; - - return Kernel::mm_new_heap(sz, true, false); -} - -void operator delete[](void* ptr) -{ - if (ptr == nullptr) - return; - - Kernel::mm_delete_heap(ptr); -} - -void operator delete(void* ptr) -{ - if (ptr == nullptr) - return; - - Kernel::mm_delete_heap(ptr); -} - -void operator delete(void* ptr, size_t sz) -{ - if (ptr == nullptr) - return; - - ZKA_UNUSED(sz); - - Kernel::mm_delete_heap(ptr); -} diff --git a/dev/ZKAKit/src/OwnPtr.cc b/dev/ZKAKit/src/OwnPtr.cc deleted file mode 100644 index fa290c41..00000000 --- a/dev/ZKAKit/src/OwnPtr.cc +++ /dev/null @@ -1,7 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include diff --git a/dev/ZKAKit/src/PEFCodeMgr.cc b/dev/ZKAKit/src/PEFCodeMgr.cc deleted file mode 100644 index 5cde2da1..00000000 --- a/dev/ZKAKit/src/PEFCodeMgr.cc +++ /dev/null @@ -1,284 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include -#include -#include -#include -#include -#include -#include - -/// @brief PEF stack size symbol. -#define kPefStackSizeSymbol "SizeOfReserveStack" -#define kPefHeapSizeSymbol "SizeOfReserveHeap" -#define kPefNameSymbol "ProgramName" - -namespace Kernel -{ - namespace Detail - { - /***********************************************************************************/ - /// @brief Get the PEF platform signature according to the compiled architecture. - /***********************************************************************************/ - UInt32 ldr_get_platform(void) noexcept - { -#if defined(__ZKA_32X0__) - return kPefArch32x0; -#elif defined(__ZKA_64X0__) - return kPefArch64x0; -#elif defined(__ZKA_AMD64__) - return kPefArchAMD64; -#elif defined(__ZKA_PPC64__) - return kPefArchPowerPC; -#elif defined(__ZKA_ARM64__) - return kPefArchARM64; -#else - return kPefArchInvalid; -#endif // __32x0__ || __64x0__ || __x86_64__ - } - } // namespace Detail - - /***********************************************************************************/ - /// @brief PEF loader constructor w/ blob. - /// @param blob file blob. - /***********************************************************************************/ - PEFLoader::PEFLoader(const VoidPtr blob) - : fCachedBlob(blob) - { - MUST_PASS(fCachedBlob); - fBad = false; - } - - /***********************************************************************************/ - /// @brief PEF loader constructor. - /// @param path the filesystem path. - /***********************************************************************************/ - PEFLoader::PEFLoader(const Char* path) - : fCachedBlob(nullptr), fBad(false), fFatBinary(false) - { - fFile.New(const_cast(path), kRestrictRB); - fPath = StringBuilder::Construct(path).Leak(); - - auto kPefHeader = "PEF_CONTAINER"; - - fCachedBlob = fFile->Read(kPefHeader); - - PEFContainer* container = reinterpret_cast(fCachedBlob); - - if (container->Cpu == Detail::ldr_get_platform() && - container->Magic[0] == kPefMagic[0] && - container->Magic[1] == kPefMagic[1] && - container->Magic[2] == kPefMagic[2] && - container->Magic[3] == kPefMagic[3] && - container->Magic[4] == kPefMagic[4] && container->Abi == kPefAbi) - { - return; - } - else if (container->Magic[4] == kPefMagic[0] && - container->Magic[3] == kPefMagic[1] && - container->Magic[2] == kPefMagic[2] && - container->Magic[1] == kPefMagic[3] && - container->Magic[0] == kPefMagic[4] && container->Abi == kPefAbi) - { - /// This is a fat binary. - this->fFatBinary = true; - return; - } - - fBad = true; - - if (fCachedBlob) - mm_delete_heap(fCachedBlob); - - kcout << "PEFLoader: warn: Executable format error!\r"; - - fCachedBlob = nullptr; - } - - /***********************************************************************************/ - /// @brief PEF destructor. - /***********************************************************************************/ - PEFLoader::~PEFLoader() - { - if (fCachedBlob) - mm_delete_heap(fCachedBlob); - - fFile.Delete(); - } - - /***********************************************************************************/ - /// @brief Finds the symbol according to it's name. - /// @param name name of symbol. - /// @param kind kind of symbol we want. - /***********************************************************************************/ - VoidPtr PEFLoader::FindSymbol(const Char* name, Int32 kind) - { - if (!fCachedBlob || fBad || !name) - return nullptr; - - PEFContainer* container = reinterpret_cast(fCachedBlob); - - auto blob = fFile->Read(name); - - PEFCommandHeader* container_header = reinterpret_cast(blob); - - constexpr auto cMangleCharacter = '$'; - const Char* cContainerKinds[] = {".code64", ".data64", ".zero64", nullptr}; - - ErrorOr error_or_symbol; - - switch (kind) - { - case kPefCode: { - error_or_symbol = StringBuilder::Construct(cContainerKinds[0]); // code symbol. - break; - } - case kPefData: { - error_or_symbol = StringBuilder::Construct(cContainerKinds[1]); // data symbol. - break; - } - case kPefZero: { - error_or_symbol = StringBuilder::Construct(cContainerKinds[2]); // block starting symbol. - break; - } - default: - return nullptr; // prevent that from the kernel's mode perspective, let that happen if it were - // a user process. - } - - Char* unconst_symbol = const_cast(name); - - for (SizeT i = 0UL; i < rt_string_len(unconst_symbol, kPefNameLen); ++i) - { - if (unconst_symbol[i] == ' ') - { - unconst_symbol[i] = cMangleCharacter; - } - } - - error_or_symbol.Leak().Leak() += name; - - for (SizeT index = 0; index < container->Count; ++index) - { - if (StringBuilder::Equals(container_header->Name, - error_or_symbol.Leak().Leak().CData())) - { - if (container_header->Kind == kind) - { - if (container_header->Cpu != Detail::ldr_get_platform()) - { - if (!this->fFatBinary) - { - mm_delete_heap(blob); - return nullptr; - } - } - - Char* container_blob_value = new Char[container_header->Size]; - - rt_copy_memory((VoidPtr)((Char*)blob + sizeof(PEFCommandHeader)), container_blob_value, container_header->Size); - mm_delete_heap(blob); - - kcout << "PEFLoader: INFO: Load stub: " << container_header->Name << "!\r"; - - return container_blob_value; - } - } - } - - mm_delete_heap(blob); - return nullptr; - } - - /// @brief Finds the executable entrypoint. - /// @return - ErrorOr PEFLoader::FindStart() - { - if (auto sym = this->FindSymbol(kPefStart, kPefCode); sym) - return ErrorOr(sym); - - return ErrorOr(kErrorExecutable); - } - - /// @brief Tells if the executable is loaded or not. - /// @return - bool PEFLoader::IsLoaded() noexcept - { - return !fBad && fCachedBlob; - } - - const Char* PEFLoader::Path() - { - return fPath.Leak().CData(); - } - - const Char* PEFLoader::AsString() - { -#ifdef __32x0__ - return "32x0 PEF executable."; -#elif defined(__64x0__) - return "64x0 PEF executable."; -#elif defined(__x86_64__) - return "x86_64 PEF executable."; -#elif defined(__aarch64__) - return "AARCH64 PEF executable."; -#elif defined(__powerpc64__) - return "POWER64 PEF executable."; -#else - return "???? PEF executable."; -#endif // __32x0__ || __64x0__ || __x86_64__ || __powerpc64__ - } - - const Char* PEFLoader::MIME() - { - return kPefApplicationMime; - } - - ErrorOr PEFLoader::GetBlob() - { - return ErrorOr{this->fCachedBlob}; - } - - namespace Utils - { - ProcessID rtl_create_process(PEFLoader& exec, const Int32& procKind) noexcept - { - auto errOrStart = exec.FindStart(); - - if (errOrStart.Error() != kErrorSuccess) - return kProcessInvalidID; - - UserProcess* proc = new UserProcess(); - - proc->Kind = procKind; - proc->Image.fCode = errOrStart.Leak().Leak(); - proc->Image.fBlob = exec.GetBlob().Leak().Leak(); - proc->StackSize = *(UIntPtr*)exec.FindSymbol(kPefStackSizeSymbol, kPefData); - proc->MemoryLimit = *(UIntPtr*)exec.FindSymbol(kPefHeapSizeSymbol, kPefData); - proc->PTime = 0UL; - - rt_set_memory(proc->Name, 0, kProcessNameLen); - - if (exec.FindSymbol(kPefNameSymbol, kPefData)) - rt_copy_memory(exec.FindSymbol(kPefNameSymbol, kPefData), proc->Name, rt_string_len((Char*)exec.FindSymbol(kPefNameSymbol, kPefData))); - - if (!proc->StackSize) - { - const auto kDefaultStackSizeMib = 8; - proc->StackSize = mib_cast(kDefaultStackSizeMib); - } - - auto id = UserProcessScheduler::The().Spawn(proc); - - if (id == kProcessInvalidID) - delete proc; - - return id; - } - } // namespace Utils -} // namespace Kernel diff --git a/dev/ZKAKit/src/PRDT.cc b/dev/ZKAKit/src/PRDT.cc deleted file mode 100644 index 1c07fddf..00000000 --- a/dev/ZKAKit/src/PRDT.cc +++ /dev/null @@ -1,24 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include -#include - -namespace Kernel -{ - /***********************************************************************************/ - /// @brief constructs a new PRD. - /// @param prd PRD reference. - /// @note This doesnt construct a valid, please fill it by yourself. - /***********************************************************************************/ - void construct_prdt(Ref& prd) - { - prd.Leak().fPhysAddress = 0x0; - prd.Leak().fSectorCount = 0x0; - prd.Leak().fEndBit = 0x0; - } -} // namespace Kernel diff --git a/dev/ZKAKit/src/PageMgr.cc b/dev/ZKAKit/src/PageMgr.cc deleted file mode 100644 index a4d37a4d..00000000 --- a/dev/ZKAKit/src/PageMgr.cc +++ /dev/null @@ -1,110 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include - -#ifdef __ZKA_AMD64__ -#include -#elif defined(__ZKA_ARM64__) -#include -#endif // ifdef __ZKA_AMD64__ || defined(__ZKA_ARM64__) - -namespace Kernel -{ - PTEWrapper::PTEWrapper(Boolean Rw, Boolean User, Boolean ExecDisable, UIntPtr VirtAddr) - : fRw(Rw), - fUser(User), - fExecDisable(ExecDisable), - fVirtAddr(VirtAddr), - fCache(false), - fShareable(false), - fWt(false), - fPresent(true), - fAccessed(false) - { - } - - PTEWrapper::~PTEWrapper() = default; - - /// @brief Flush virtual address. - /// @param VirtAddr - Void PageMgr::FlushTLB() - { -#ifndef __ZKA_MINIMAL_OS__ - hal_flush_tlb(); -#endif // !__ZKA_MINIMAL_OS__ - } - - /// @brief Reclaim freed page. - /// @return - Bool PTEWrapper::Reclaim() - { - if (!this->fPresent) - { - this->fPresent = true; - return true; - } - - return false; - } - - /// @brief Request a PTE. - /// @param Rw r/w? - /// @param User user mode? - /// @param ExecDisable disable execution on page? - /// @return - PTEWrapper PageMgr::Request(Boolean Rw, Boolean User, Boolean ExecDisable, SizeT Sz) - { - // Store PTE wrapper right after PTE. - VoidPtr ptr = Kernel::HAL::mm_alloc_bitmap(Rw, User, Sz, false); - - return PTEWrapper{Rw, User, ExecDisable, reinterpret_cast(ptr)}; - } - - /// @brief Disable BitMap. - /// @param wrapper the wrapper. - /// @return If the page bitmap was cleared or not. - Bool PageMgr::Free(Ref& wrapper) - { - if (!Kernel::HAL::mm_free_bitmap((VoidPtr)wrapper.Leak().VirtualAddress())) - return false; - - return true; - } - - /// @brief Virtual PTE address. - /// @return The virtual address of the page. - const UIntPtr PTEWrapper::VirtualAddress() - { - return (fVirtAddr); - } - - Bool PTEWrapper::Shareable() - { - return fShareable; - } - - Bool PTEWrapper::Present() - { - return fPresent; - } - - Bool PTEWrapper::Access() - { - return fAccessed; - } - - Void PTEWrapper::NoExecute(const bool enable) - { - fExecDisable = enable; - } - - Bool PTEWrapper::NoExecute() - { - return fExecDisable; - } -} // namespace Kernel diff --git a/dev/ZKAKit/src/Pmm.cc b/dev/ZKAKit/src/Pmm.cc deleted file mode 100644 index fe7c8996..00000000 --- a/dev/ZKAKit/src/Pmm.cc +++ /dev/null @@ -1,98 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include - -#if defined(__ZKA_ARM64__) -#include -#endif // defined(__ZKA_ARM64__) - -#if defined(__ZKA_AMD64__) -#include -#endif // defined(__ZKA_AMD64__) - -namespace Kernel -{ - /***********************************************************************************/ - /// @brief Pmm constructor. - /***********************************************************************************/ - Pmm::Pmm() - : fPageMgr() - { - kcout << "[PMM] Allocate PageMemoryMgr"; - } - - Pmm::~Pmm() = default; - - /***********************************************************************************/ - /// @param If this returns Null pointer, enter emergency mode. - /// @param user is this a user page? - /// @param readWrite is it r/w? - /***********************************************************************************/ - Ref Pmm::RequestPage(Boolean user, Boolean readWrite) - { - PTEWrapper pt = fPageMgr.Leak().Request(user, readWrite, false, kPageSize); - - if (pt.fPresent) - { - kcout << "[PMM]: Allocation failed.\r"; - return {}; - } - - return Ref(pt); - } - - Boolean Pmm::FreePage(Ref PageRef) - { - if (!PageRef) - return false; - - PageRef.Leak().fPresent = false; - - return true; - } - - Boolean Pmm::TogglePresent(Ref PageRef, Boolean Enable) - { - if (!PageRef) - return false; - - PageRef.Leak().fPresent = Enable; - - return true; - } - - Boolean Pmm::ToggleUser(Ref PageRef, Boolean Enable) - { - if (!PageRef) - return false; - - PageRef.Leak().fRw = Enable; - - return true; - } - - Boolean Pmm::ToggleRw(Ref PageRef, Boolean Enable) - { - if (!PageRef) - return false; - - PageRef.Leak().fRw = Enable; - - return true; - } - - Boolean Pmm::ToggleShare(Ref PageRef, Boolean Enable) - { - if (!PageRef) - return false; - - PageRef.Leak().fShareable = Enable; - - return true; - } -} // namespace Kernel diff --git a/dev/ZKAKit/src/Property.cc b/dev/ZKAKit/src/Property.cc deleted file mode 100644 index 140205cc..00000000 --- a/dev/ZKAKit/src/Property.cc +++ /dev/null @@ -1,45 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include - -namespace CFKit -{ - /***********************************************************************************/ - /// @brief Destructor. - /***********************************************************************************/ - Property::~Property() = default; - - /***********************************************************************************/ - /// @brief Constructor. - /***********************************************************************************/ - Property::Property() = default; - - /***********************************************************************************/ - /// @brief Check if property's name equals to name. - /// @param name string to check. - /***********************************************************************************/ - Bool Property::StringEquals(KString& name) - { - return this->fName && this->fName == name; - } - - /***********************************************************************************/ - /// @brief Gets the key (name) of property. - /***********************************************************************************/ - KString& Property::GetKey() - { - return this->fName; - } - - /***********************************************************************************/ - /// @brief Gets the value of the property. - /***********************************************************************************/ - PropertyId& Property::GetValue() - { - return fValue; - } -} // namespace CFKit diff --git a/dev/ZKAKit/src/Ref.cc b/dev/ZKAKit/src/Ref.cc deleted file mode 100644 index 35b2df3b..00000000 --- a/dev/ZKAKit/src/Ref.cc +++ /dev/null @@ -1,7 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include diff --git a/dev/ZKAKit/src/Semaphore.cc b/dev/ZKAKit/src/Semaphore.cc deleted file mode 100644 index e957b0a3..00000000 --- a/dev/ZKAKit/src/Semaphore.cc +++ /dev/null @@ -1,72 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include - -namespace Kernel -{ - /***********************************************************************************/ - /// @brief Unlocks process out of the semaphore. - /***********************************************************************************/ - Bool Semaphore::Unlock() noexcept - { - if (fLockingProcess) - fLockingProcess = nullptr; - else - return No; - - return Yes; - } - - /***********************************************************************************/ - /// @brief Locks process in the semaphore. - /***********************************************************************************/ - Bool Semaphore::Lock(UserProcess* process) - { - if (!process || fLockingProcess) - return No; - - fLockingProcess = process; - - return Yes; - } - - /***********************************************************************************/ - /// @brief Checks if process is locked. - /***********************************************************************************/ - Bool Semaphore::IsLocked() const - { - return fLockingProcess; - } - - /***********************************************************************************/ - /// @brief Try lock or wait. - /***********************************************************************************/ - Bool Semaphore::LockOrWait(UserProcess* process, TimerInterface* timer) - { - if (process == nullptr) - return No; - - if (timer == nullptr) - return No; - - this->Lock(process); - - timer->Wait(); - - return this->Lock(process); - } - - /***********************************************************************************/ - /// @brief Wait for process to be free. - /***********************************************************************************/ - Void Semaphore::WaitForProcess() noexcept - { - while (fLockingProcess) - ; - } -} // namespace Kernel diff --git a/dev/ZKAKit/src/Stop.cc b/dev/ZKAKit/src/Stop.cc deleted file mode 100644 index b8bfdb1b..00000000 --- a/dev/ZKAKit/src/Stop.cc +++ /dev/null @@ -1,130 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define kWebsiteURL "https://el-mahrouss-logic.com/products/help/" - -/* Each error code is attributed with an ID, which will prompt a string onto the - * screen. Wait for debugger... */ - -namespace Kernel -{ - /***********************************************************************************/ - /// @brief Stops execution of the kernel. - /// @param id kernel stop ID. - /***********************************************************************************/ - Void ke_stop(const Kernel::Int32& id) - { - cg_init(); - - auto panic_text = RGB(0xff, 0xff, 0xff); - - auto start_y = 50; - auto x = 10; - - if (id != RUNTIME_CHECK_BOOTSTRAP) - CGDrawString("Kernel Panic!", start_y, x, panic_text); - else - CGDrawString("Kernel Bootstrap:", start_y, x, panic_text); - - start_y += 10; - - cg_fini(); - - // show text according to error id. - - switch (id) - { - case RUNTIME_CHECK_PROCESS: { - CGDrawString("0x00000008: Invalid process behavior.", start_y, x, panic_text); - break; - } - case RUNTIME_CHECK_ACPI: { - CGDrawString("0x00000006: ACPI configuration error.", start_y, x, panic_text); - break; - } - case RUNTIME_CHECK_PAGE: { - CGDrawString("0x0000000B: Write/Read in non paged area.", start_y, x, panic_text); - break; - } - case RUNTIME_CHECK_FILESYSTEM: { - CGDrawString("0x0000000A: Filesystem driver error.", start_y, x, panic_text); - break; - } - case RUNTIME_CHECK_POINTER: { - CGDrawString("0x00000000: Kernel heap is corrupted.", start_y, x, panic_text); - break; - } - case RUNTIME_CHECK_BAD_BEHAVIOR: { - CGDrawString("0x00000009: Bad behavior.", start_y, x, panic_text); - break; - } - case RUNTIME_CHECK_BOOTSTRAP: { - CGDrawString("0x0000000A: Kernel has finished running, running OSLdr...", start_y, x, panic_text); - return; - } - case RUNTIME_CHECK_HANDSHAKE: { - CGDrawString("0x00000005: Handshake fault.", start_y, x, panic_text); - break; - } - case RUNTIME_CHECK_IPC: { - CGDrawString("0x00000003: Bad LPC message.", start_y, x, panic_text); - break; - } - case RUNTIME_CHECK_INVALID_PRIVILEGE: { - CGDrawString("0x00000007: Privilege access violation.", start_y, x, panic_text); - break; - case RUNTIME_CHECK_UNEXCPECTED: { - CGDrawString("0x0000000B: Unexpected violation.", start_y, x, panic_text); - break; - } - case RUNTIME_CHECK_VIRTUAL_OUT_OF_MEM: { - CGDrawString("0x10000001: Out of virtual memory.", start_y, x, panic_text); - - break; - } - case RUNTIME_CHECK_FAILED: { - CGDrawString("0x10000001: Kernel Bug check appears to have failed, a dump has been written to the storage.", start_y, x, panic_text); - break; - } - default: { - CGDrawString("0xFFFFFFFC: Unknown Kernel Error code.", start_y, x, panic_text); - break; - } - } - }; - - RecoveryFactory::Recover(); - } - - Void RecoveryFactory::Recover() noexcept - { - while (YES) - { - HAL::rt_halt(); - } - } - - void ke_runtime_check(bool expr, const Char* file, const Char* line) - { - if (!expr) - { - kcout << "FAILED: FILE: " << file << endl; - kcout << "FAILED: LINE: " << line << endl; - - ke_stop(RUNTIME_CHECK_FAILED); // Runtime Check failed - } - } -} // namespace Kernel diff --git a/dev/ZKAKit/src/Storage/AHCIDeviceInterface.cc b/dev/ZKAKit/src/Storage/AHCIDeviceInterface.cc deleted file mode 100644 index 5a4b218f..00000000 --- a/dev/ZKAKit/src/Storage/AHCIDeviceInterface.cc +++ /dev/null @@ -1,35 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include - -using namespace Kernel; - -/// @brief Class constructor -/// @param Out Drive output -/// @param In Drive input -/// @param Cleanup Drive cleanup. -AHCIDeviceInterface::AHCIDeviceInterface(void (*Out)(MountpointInterface* outpacket), - void (*In)(MountpointInterface* inpacket), - void (*Cleanup)(void)) - : IDeviceObject(Out, In), fCleanup(Cleanup) -{ -} - -/// @brief Class desctructor -AHCIDeviceInterface::~AHCIDeviceInterface() -{ - MUST_PASS(fCleanup); - if (fCleanup) - fCleanup(); -} - -/// @brief Returns the name of the device interface. -/// @return it's name as a string. -const Char* AHCIDeviceInterface::Name() const -{ - return "AHCIDeviceInterface"; -} diff --git a/dev/ZKAKit/src/Storage/ATADeviceInterface.cc b/dev/ZKAKit/src/Storage/ATADeviceInterface.cc deleted file mode 100644 index 58564524..00000000 --- a/dev/ZKAKit/src/Storage/ATADeviceInterface.cc +++ /dev/null @@ -1,88 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include - -using namespace Kernel; - -/// @brief Class constructor -/// @param Out Drive output -/// @param In Drive input -/// @param Cleanup Drive cleanup. -ATADeviceInterface::ATADeviceInterface( - void (*Out)(MountpointInterface* outpacket), - void (*In)(MountpointInterface* inpacket), - void (*Cleanup)(void)) - : IDeviceObject(Out, In), fCleanup(Cleanup) -{ -} - -/// @brief Class desctructor -ATADeviceInterface::~ATADeviceInterface() -{ - MUST_PASS(fCleanup); - if (fCleanup) - fCleanup(); -} - -/// @brief Returns the name of the device interface. -/// @return it's name as a string. -const Char* ATADeviceInterface::Name() const -{ - return "ATADeviceInterface"; -} - -/// @brief Output operator. -/// @param Data -/// @return -ATADeviceInterface& ATADeviceInterface::operator<<(MountpointInterface* Data) -{ - if (!Data) - return *this; - - for (SizeT driveCount = 0; driveCount < kDriveMaxCount; ++driveCount) - { - auto interface = Data->GetAddressOf(driveCount); - if ((interface) && rt_string_cmp((interface)->fDriveKind(), "ATA-", 5) == 0) - { - continue; - } - else if ((interface) && - rt_string_cmp((interface)->fDriveKind(), "ATA-", 5) != 0) - { - return *this; - } - } - - return (ATADeviceInterface&)IDeviceObject::operator<<( - Data); -} - -/// @brief Input operator. -/// @param Data -/// @return -ATADeviceInterface& ATADeviceInterface::operator>>(MountpointInterface* Data) -{ - if (!Data) - return *this; - - for (SizeT driveCount = 0; driveCount < kDriveMaxCount; ++driveCount) - { - auto interface = Data->GetAddressOf(driveCount); - if ((interface) && rt_string_cmp((interface)->fDriveKind(), "ATA-", 5) == 0) - { - continue; - } - else if ((interface) && - rt_string_cmp((interface)->fDriveKind(), "ATA-", 5) != 0) - { - return *this; - } - } - - return (ATADeviceInterface&)IDeviceObject::operator>>( - Data); -} diff --git a/dev/ZKAKit/src/Storage/NVMEDeviceInterface.cc b/dev/ZKAKit/src/Storage/NVMEDeviceInterface.cc deleted file mode 100644 index ca957fe2..00000000 --- a/dev/ZKAKit/src/Storage/NVMEDeviceInterface.cc +++ /dev/null @@ -1,28 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include - -namespace Kernel -{ - NVMEDeviceInterface::NVMEDeviceInterface(void (*out)(MountpointInterface* outpacket), - void (*in)(MountpointInterface* inpacket), - void (*cleanup)(void)) - : IDeviceObject(out, in), fCleanup(cleanup) - { - } - - NVMEDeviceInterface::~NVMEDeviceInterface() - { - if (fCleanup) - fCleanup(); - } - - const Char* NVMEDeviceInterface::Name() const - { - return ("NVMEDeviceInterface"); - } -} // namespace Kernel diff --git a/dev/ZKAKit/src/Storage/SCSIDeviceInterface.cc b/dev/ZKAKit/src/Storage/SCSIDeviceInterface.cc deleted file mode 100644 index 92346e17..00000000 --- a/dev/ZKAKit/src/Storage/SCSIDeviceInterface.cc +++ /dev/null @@ -1,11 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include - -///! @brief ATAPI SCSI packet. -const scsi_packet_type<12> kCDRomPacketTemplate = {0x43, 0, 1, 0, 0, 0, - 0, 12, 0x40, 0, 0}; diff --git a/dev/ZKAKit/src/Stream.cc b/dev/ZKAKit/src/Stream.cc deleted file mode 100644 index 2d6a0034..00000000 --- a/dev/ZKAKit/src/Stream.cc +++ /dev/null @@ -1,12 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - - File: Stream.cc - Purpose: Stream object - - Revision History: - -------------------------------------------- */ - -#include diff --git a/dev/ZKAKit/src/ThreadLocalStorage.cc b/dev/ZKAKit/src/ThreadLocalStorage.cc deleted file mode 100644 index 3d318632..00000000 --- a/dev/ZKAKit/src/ThreadLocalStorage.cc +++ /dev/null @@ -1,67 +0,0 @@ -/* - * ======================================================== - * - * minoskrnl - * Copyright (C) 2024, Theater Quality Inc, all rights reserved., all rights reserved. - * - * ======================================================== - */ - -#include -#include -#include -#include - -/***********************************************************************************/ -/// @bugs: 0 -/// @file ThreadLocalStorage.cc -/// @brief Process Thread Local Storage. -/***********************************************************************************/ - -using namespace Kernel; - -/** - * @brief Checks for cookie inside the TIB. - * @param tib_ptr the TIB to check. - * @return if the cookie is enabled, true; false otherwise - */ - -Boolean tls_check_tib(THREAD_INFORMATION_BLOCK* tib_ptr) -{ - if (!tib_ptr || - !tib_ptr->Record) - return false; - - ICodec encoder; - const Char* tib_as_bytes = encoder.AsBytes(tib_ptr); - - kcout << "TLS: Validating the TIB...\r"; - - return tib_as_bytes[0] == kCookieMag0 && tib_as_bytes[1] == kCookieMag1 && - tib_as_bytes[2] == kCookieMag2; -} - -/** - * @brief System call implementation of the TLS check. - * @param tib_ptr The TIB record. - * @return - */ -EXTERN_C Bool tls_check_syscall_impl(Kernel::VoidPtr tib_ptr) noexcept -{ - if (!tib_ptr) - { - kcout << "TLS: Failing because of an invalid TIB...\r"; - return false; - } - - THREAD_INFORMATION_BLOCK* tib = (THREAD_INFORMATION_BLOCK*)tib_ptr; - - if (!tls_check_tib(tib)) - { - kcout << "TLS: Failing because of an invalid TIB...\r"; - return false; - } - - kcout << "TLS Check pass.\r"; - return true; -} diff --git a/dev/ZKAKit/src/Timer.cc b/dev/ZKAKit/src/Timer.cc deleted file mode 100644 index 8795dd66..00000000 --- a/dev/ZKAKit/src/Timer.cc +++ /dev/null @@ -1,47 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include - -///! BUGS: 0 -///! @file Timer.cc -///! @brief Software Timer implementation - -using namespace Kernel; - -/// @brief Unimplemented as it is an interface. -Int32 TimerInterface::Wait() noexcept -{ - return kErrorUnimplemented; -} - -/// @brief SoftwareTimer class, meant to be generic. - -SoftwareTimer::SoftwareTimer(Int64 seconds) - : fWaitFor(seconds) -{ - fDigitalTimer = new IntPtr(); - MUST_PASS(fDigitalTimer); -} - -SoftwareTimer::~SoftwareTimer() -{ - delete fDigitalTimer; - fWaitFor = 0; -} - -Int32 SoftwareTimer::Wait() noexcept -{ - if (fWaitFor < 1) - return 1; - - while (*fDigitalTimer < (*fDigitalTimer + fWaitFor)) - { - ++(*fDigitalTimer); - } - - return 0; -} diff --git a/dev/ZKAKit/src/User.cc b/dev/ZKAKit/src/User.cc deleted file mode 100644 index d45c8e1b..00000000 --- a/dev/ZKAKit/src/User.cc +++ /dev/null @@ -1,178 +0,0 @@ -/* - * ======================================================== - * - * ZKA - * Copyright (C) 2024, Theater Quality Inc, all rights reserved., all rights reserved. - * - * File: User.cc - * Purpose: User class, used to provide authentication and security. - * - * ======================================================== - */ - -#include -#include -#include -#include -#include -#include - -#define kStdUserType (0xCE) -#define kSuperUserType (0xEC) - -/// @file User.cc -/// @brief User support (or also called ) - -namespace Kernel -{ - namespace Detail - { - /// \brief Constructs a password by hashing the password. - /// \param password password to hash. - /// \return the hashed password - const Int32 cred_construct_token(Char* password, const Char* in_password, User* user, SizeT length) - { - if (!password || !user) - return 1; - - kcout << "cred_construct_token: Hashing user password...\r"; - - for (Size i_pass = 0; i_pass < length; ++i_pass) - { - const Char& cur_chr = in_password[i_pass]; - - if (cur_chr == 0) - break; - - password[i_pass] = cur_chr | (user->IsStdUser() ? kStdUserType : kSuperUserType); - } - - kcout << "cred_construct_token: Hashed user password.\r"; - - return 0; - } - } // namespace Detail - - /// @brief User ring constructor. - User::User(const Int32& sel, const Char* userName) - : mUserRing((UserRingKind)sel) - { - MUST_PASS(sel >= 0); - rt_copy_memory((VoidPtr)userName, this->mUserName, rt_string_len(userName)); - } - - /// @brief User ring constructor. - User::User(const UserRingKind& ringKind, const Char* userName) - : mUserRing(ringKind) - { - rt_copy_memory((VoidPtr)userName, this->mUserName, rt_string_len(userName)); - } - - /// @brief User destructor class. - User::~User() = default; - - Bool User::Save(const usr_public_key_kind password_to_fill) noexcept - { - if (!password_to_fill || - *password_to_fill == 0) - return No; - - SizeT len = rt_string_len(password_to_fill); - - Char* password = new Char[len]; - MUST_PASS(password); - - // fill data first, generate hash. - // return false on error. - - rt_copy_memory((VoidPtr)password_to_fill, password, len); - - if (!Detail::cred_construct_token(password, password_to_fill, this, len)) - { - delete[] password; - password = nullptr; - - return No; - } - - // then store password. - - rt_copy_memory(password, this->mUserToken, rt_string_len(password_to_fill)); - - delete[] password; - password = nullptr; - - kcout << "User::Save: Saved password successfully...\r"; - - return Yes; - } - - Bool User::Matches(const usr_public_key_kind password_to_fill) noexcept - { - if (!password_to_fill || - *password_to_fill) - return No; - - SizeT len = rt_string_len(password_to_fill); - - Char* password = new Char[len]; - MUST_PASS(password); - - // fill data first, generate hash. - // return false on error. - - rt_copy_memory((VoidPtr)password_to_fill, password, len); - - if (!Detail::cred_construct_token(password, password_to_fill, this, len)) - { - delete[] password; - password = nullptr; - - return No; - } - - kcout << "User::Matches: Validating hashed passwords...\r"; - - // now check if the password matches. - if (rt_string_cmp(password, this->mUserToken, rt_string_len(this->mUserToken)) == 0) - { - kcout << "User::Matches: Password is valid.\r"; - return Yes; - } - - kcout << "User::Matches: Password isn't valid.\r"; - return No; - } - - Bool User::operator==(const User& lhs) - { - return lhs.mUserRing == this->mUserRing; - } - - Bool User::operator!=(const User& lhs) - { - return lhs.mUserRing != this->mUserRing; - } - - Char* User::Name() noexcept - { - return this->mUserName; - } - - /// @brief Returns the user's ring. - /// @return The king of ring the user is attached to. - const UserRingKind& User::Ring() noexcept - { - return this->mUserRing; - } - - Bool User::IsStdUser() noexcept - { - return this->Ring() == UserRingKind::kRingStdUser; - } - - Bool User::IsSuperUser() noexcept - { - return this->Ring() == UserRingKind::kRingSuperUser; - } -} // namespace Kernel diff --git a/dev/ZKAKit/src/UserProcessScheduler.cc b/dev/ZKAKit/src/UserProcessScheduler.cc deleted file mode 100644 index 637eb151..00000000 --- a/dev/ZKAKit/src/UserProcessScheduler.cc +++ /dev/null @@ -1,582 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - - FILE: UserProcessScheduler.cc - PURPOSE: EL0/Ring-3 Process scheduler. - -------------------------------------------- */ - -/***********************************************************************************/ -/// @file UserProcessScheduler.cc -/// @brief EL0/Ring-3 process scheduler. -/***********************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include - -///! BUGS: 0 - -/***********************************************************************************/ -/** TODO: Document the Kernel, SDK and kits. */ -/***********************************************************************************/ - -namespace Kernel -{ - /***********************************************************************************/ - /// @brief Exit Code global variable. - /***********************************************************************************/ - - STATIC UInt32 kLastExitCode = 0U; - - /***********************************************************************************/ - /// @brief User Process scheduler global and external reference of thread scheduler. - /***********************************************************************************/ - - STATIC UserProcessScheduler kProcessScheduler; - - UserProcess::UserProcess() = default; - UserProcess::~UserProcess() = default; - - /// @brief Gets the last exit code. - /// @note Not thread-safe. - /// @return Int32 the last exit code. - const UInt32& sched_get_exit_code(void) noexcept - { - return kLastExitCode; - } - - /***********************************************************************************/ - /// @brief Crashes the current process-> - /***********************************************************************************/ - - Void UserProcess::Crash() - { - if (this->Status != ProcessStatusKind::kRunning) - return; - - kcout << this->Name << ": crashed, error id: " << number(kErrorProcessFault) << endl; - this->Exit(kErrorProcessFault); - } - - /***********************************************************************************/ - //! @brief boolean operator, check status. - /***********************************************************************************/ - - UserProcess::operator bool() - { - return this->Status == ProcessStatusKind::kRunning; - } - - /***********************************************************************************/ - /// @brief Gets the local last exit code. - /// @note Not thread-safe. - /// @return Int32 the last exit code. - /***********************************************************************************/ - - const UInt32& UserProcess::GetExitCode() noexcept - { - return this->fLastExitCode; - } - - /***********************************************************************************/ - /// @brief Error code variable getter. - /***********************************************************************************/ - - Int32& UserProcess::GetLocalCode() noexcept - { - return this->fLocalCode; - } - - /***********************************************************************************/ - /// @brief Wake process-> - /***********************************************************************************/ - - Void UserProcess::Wake(const bool should_wakeup) - { - this->Status = - should_wakeup ? ProcessStatusKind::kRunning : ProcessStatusKind::kFrozen; - } - - /***********************************************************************************/ - /** @brief Add pointer to entry. */ - /***********************************************************************************/ - - ErrorOr UserProcess::New(const SizeT& sz, const SizeT& pad_amount) - { -#ifdef __ZKA_AMD64__ - auto vm_register = hal_read_cr3(); - hal_write_cr3(this->VMRegister); - - auto ptr = mm_new_heap(sz + pad_amount, Yes, Yes); - - hal_write_cr3(vm_register); -#else - auto ptr = mm_new_heap(sz + pad_amount, Yes, Yes); -#endif - - if (!this->ProcessMemoryHeap) - { - this->ProcessMemoryHeap = new UserProcess::UserProcessHeapList(); - - this->ProcessMemoryHeap->MemoryEntryPad = pad_amount; - this->ProcessMemoryHeap->MemoryEntrySize = sz; - - this->ProcessMemoryHeap->MemoryEntry = ptr; - - this->ProcessMemoryHeap->MemoryPrev = nullptr; - this->ProcessMemoryHeap->MemoryNext = nullptr; - - return ErrorOr(ptr); - } - else - { - UserProcessHeapList* entry = this->ProcessMemoryHeap; - UserProcessHeapList* prev_entry = nullptr; - - while (!entry) - { - if (entry->MemoryEntry == nullptr) - break; // chose to break here, when we get an already allocated memory entry for our needs. - - prev_entry = entry; - entry = entry->MemoryNext; - } - - entry->MemoryNext = new UserProcessHeapList(); - entry->MemoryNext->MemoryEntry = ptr; - - entry->MemoryNext->MemoryPrev = entry; - entry->MemoryNext->MemoryNext = nullptr; - } - - return ErrorOr(nullptr); - } - - /***********************************************************************************/ - /// @brief Gets the name of the current process-> - /***********************************************************************************/ - - const Char* UserProcess::GetName() noexcept - { - return this->Name; - } - - /***********************************************************************************/ - /// @brief Gets the owner of the process-> - /***********************************************************************************/ - - const User* UserProcess::GetOwner() noexcept - { - return this->Owner; - } - - /// @brief UserProcess status getter. - const ProcessStatusKind& UserProcess::GetStatus() noexcept - { - return this->Status; - } - - /***********************************************************************************/ - /** - @brief Affinity is the time slot allowed for the process-> - */ - /***********************************************************************************/ - - const AffinityKind& UserProcess::GetAffinity() noexcept - { - return this->Affinity; - } - - /***********************************************************************************/ - /** - @brief Exit process method. - @param exit_code The process's exit code. - */ - /***********************************************************************************/ - - Void UserProcess::Exit(const Int32& exit_code) - { - this->Status = exit_code > 0 ? ProcessStatusKind::kKilled : ProcessStatusKind::kFrozen; - this->fLastExitCode = exit_code; - - kLastExitCode = exit_code; - - auto memory_heap_list = this->ProcessMemoryHeap; - -#ifdef __ZKA_AMD64__ - auto pd = hal_read_cr3(); - hal_write_cr3(this->VMRegister); -#endif - - // Deleting memory lists. Make sure to free all of them. - while (memory_heap_list) - { - if (memory_heap_list->MemoryEntry) - { - MUST_PASS(mm_delete_heap(memory_heap_list->MemoryEntry)); - } - -#ifdef __ZKA_AMD64__ - hal_write_cr3(pd); -#endif - - auto next = memory_heap_list->MemoryNext; - - mm_delete_heap(memory_heap_list); - - memory_heap_list = nullptr; - memory_heap_list = next; - } - - //! Free the memory's page directory. - HAL::mm_free_bitmap(this->VMRegister); - - //! Delete image if not done already. - if (this->Image.fCode && mm_is_valid_heap(this->Image.fCode)) - mm_delete_heap(this->Image.fCode); - - if (this->Image.fBlob && mm_is_valid_heap(this->Image.fBlob)) - mm_delete_heap(this->Image.fBlob); - - if (this->StackFrame && mm_is_valid_heap(this->StackFrame)) - mm_delete_heap((VoidPtr)this->StackFrame); - - this->Image.fBlob = nullptr; - this->Image.fCode = nullptr; - this->StackFrame = nullptr; - - if (this->Kind == kExectuableDLLKind) - { - Bool success = false; - - rtl_fini_dylib(this, reinterpret_cast(this->DylibDelegate), &success); - - if (!success) - { - ke_stop(RUNTIME_CHECK_PROCESS); - } - - this->DylibDelegate = nullptr; - } - - if (this->StackReserve) - mm_delete_heap(reinterpret_cast(this->StackReserve)); - - this->ProcessId = 0; - this->Status = ProcessStatusKind::kFinished; - - --this->ProcessParentTeam->mProcessCount; - - delete this; - } - - /***********************************************************************************/ - /// @brief Add process to team. - /// @param process the process *Ref* class. - /// @return the process index inside the team. - /***********************************************************************************/ - - ProcessID UserProcessScheduler::Spawn(UserProcess* process) - { - if (!process) - { - return kProcessInvalidID; - } - -#ifdef __ZKA_AMD64__ - process->VMRegister = mm_new_heap(sizeof(PDE), No, Yes); - - if (!process->VMRegister) - { - process->Crash(); - return -kErrorProcessFault; - } -#endif // __ZKA_AMD64__ - - kcout << "Create page directory for: " << process->Name << endl; - - process->StackFrame = reinterpret_cast(mm_new_heap(sizeof(HAL::StackFrame), Yes, Yes)); - - if (!process->StackFrame) - { - process->Crash(); - return -kErrorProcessFault; - } - - kcout << "Create stack for: " << process->Name << endl; - - // Create heap according to type of process-> - if (process->Kind == UserProcess::kExectuableDLLKind) - { - process->DylibDelegate = rtl_init_dylib(process); - MUST_PASS(process->DylibDelegate); - - kcout << "Created Library Interface for process: " << process->Name << endl; - } - - process->StackReserve = new UInt8[process->StackSize]; - - UInt32 flags = HAL::kMMFlagsPresent; - flags |= HAL::kMMFlagsWr; - flags |= HAL::kMMFlagsUser; - - HAL::mm_map_page((VoidPtr)process->StackReserve, flags); - - if (!process->StackReserve) - { - process->Crash(); - return -kErrorProcessFault; - } - - kcout << "Created Reserved Stack for process: " << process->Name << endl; - - ProcessID pid = mTeam.mProcessCount; - - if (pid > kSchedProcessLimitPerTeam) - return kProcessInvalidID; - - ++mTeam.mProcessCount; - - process->ProcessParentTeam = &mTeam; - - process->ProcessId = pid; - process->Status = ProcessStatusKind::kStarting; - process->PTime = (UIntPtr)AffinityKind::kStandard; - - kcout << "Process Name: " << process->Name << endl; - kcout << "PID: " << number(process->ProcessId) << endl; - - mTeam.mProcessList.Assign(pid, process); - - return process->ProcessId; - } - - /***********************************************************************************/ - /// @brief Retrieves the singleton of the process scheduler. - /***********************************************************************************/ - - UserProcessScheduler& UserProcessScheduler::The() - { - return kProcessScheduler; - } - - /***********************************************************************************/ - - /// @brief Remove process from list. - /// @param process_id process slot inside team. - /// @retval true process was removed. - /// @retval false process doesn't exist in team. - - /***********************************************************************************/ - - const Bool UserProcessScheduler::Remove(ProcessID process_id) - { - // check if process is within range. - if (process_id > mTeam.mProcessList.Count()) - return No; - - mTeam.mProcessList[process_id]->Exit(0); - - return Yes; - } - - const Bool UserProcessScheduler::IsUser() - { - return Yes; - } - - const Bool UserProcessScheduler::IsKernel() - { - return No; - } - - const Bool UserProcessScheduler::HasMP() - { - MUST_PASS(kHandoverHeader); - return kHandoverHeader->f_HardwareTables.f_MultiProcessingEnabled; - } - - /***********************************************************************************/ - - /// @brief Run User scheduler object. - /// @return Process count executed within a team. - - /***********************************************************************************/ - - const SizeT UserProcessScheduler::Run() noexcept - { - SizeT process_index = 0; //! we store this guy to tell the scheduler how many - //! things we have scheduled. - - if (mTeam.mProcessList.Empty()) - { - kcout << "UserProcessScheduler::Run(): This team doesn't have any process!\r"; - return 0; - } - - kcout << "UserProcessScheduler::Run(): This team has a process capacity of: " << number(mTeam.mProcessList.Capacity()) << endl; - - for (; process_index < mTeam.AsArray().Capacity(); ++process_index) - { - auto process = mTeam.AsArray()[process_index]; - - //! check if process needs to be scheduled. - if (process && UserProcessHelper::CanBeScheduled(process)) - { - // Set current process header. - this->GetCurrentProcess() = process; - - process->PTime = static_cast(process->Affinity); - - kcout << "Switch to '" << process->Name << "'.\r"; - - // tell helper to find a core to schedule on. - if (!UserProcessHelper::Switch(process->Image.fCode, &process->StackReserve[process->StackSize - 1], process->StackFrame, - process->ProcessId)) - { - process->Crash(); - } - } - else - { - --process->PTime; - } - } - - return process_index; - } - - /// @brief Gets the current scheduled team. - /// @return - UserProcessTeam& UserProcessScheduler::CurrentTeam() - { - return mTeam; - } - - /// @internal - - /// @brief Gets current running process-> - /// @return - Ref& UserProcessScheduler::GetCurrentProcess() - { - return mTeam.AsRef(); - } - - /// @brief Current proccess id getter. - /// @return UserProcess ID integer. - ErrorOr UserProcessHelper::TheCurrentPID() - { - if (!kProcessScheduler.GetCurrentProcess()) - return ErrorOr{kErrorProcessFault}; - - kcout << "UserProcessHelper::TheCurrentPID: Leaking ProcessId...\r"; - return ErrorOr{kProcessScheduler.GetCurrentProcess().Leak().ProcessId}; - } - - /// @brief Check if process can be schedulded. - /// @param process the process reference. - /// @retval true can be schedulded. - /// @retval false cannot be schedulded. - Bool UserProcessHelper::CanBeScheduled(const UserProcess* process) - { - if (process->Status == ProcessStatusKind::kKilled || - process->Status == ProcessStatusKind::kFinished || - process->Status == ProcessStatusKind::kFrozen) - return No; - - if (process->Status == ProcessStatusKind::kInvalid) - return No; - - if (!process->Image.fCode) - return No; - - if (!process->Name[0]) - return No; - - return process->PTime < 1; - } - - /***********************************************************************************/ - /** - * @brief Start scheduling current AP. - */ - /***********************************************************************************/ - SizeT UserProcessHelper::StartScheduling() - { - return kProcessScheduler.Run(); - } - - /***********************************************************************************/ - /** - * \brief Does a context switch in a CPU. - * \param the_stack the stackframe of the running app. - * \param new_pid the process's PID. - */ - /***********************************************************************************/ - - Bool UserProcessHelper::Switch(VoidPtr image_ptr, UInt8* stack, HAL::StackFramePtr frame_ptr, const PID& new_pid) - { - if (!stack || !frame_ptr || !image_ptr || new_pid < 0) - return No; - - if (!mm_is_valid_heap(image_ptr)) - return No; - - for (SizeT index = 0UL; index < HardwareThreadScheduler::The().Capacity(); ++index) - { - if (!HardwareThreadScheduler::The()[index].Leak()) - continue; - - if (HardwareThreadScheduler::The()[index].Leak()->Kind() == kInvalidAP) - continue; - - if (HardwareThreadScheduler::The()[index].Leak()->Kind() != - ThreadKind::kAPBoot && - HardwareThreadScheduler::The()[index].Leak()->Kind() != - ThreadKind::kAPSystemReserved) - { - PID prev_pid = UserProcessHelper::TheCurrentPID(); - UserProcessHelper::TheCurrentPID().Leak().Leak() = new_pid; - - //////////////////////////////////////////////////////////// - /// Prepare task switch. /// - //////////////////////////////////////////////////////////// - - auto prev_ptime = HardwareThreadScheduler::The()[index].Leak()->fPTime; - HardwareThreadScheduler::The()[index].Leak()->fPTime = UserProcessScheduler::The().CurrentTeam().AsArray()[new_pid]->PTime; - Bool ret = HardwareThreadScheduler::The()[index].Leak()->Switch(image_ptr, stack, frame_ptr, new_pid); - - //////////////////////////////////////////////////////////// - /// Rollback on fail. /// - //////////////////////////////////////////////////////////// - if (!ret) - { - HardwareThreadScheduler::The()[index].Leak()->fPTime = prev_ptime; - UserProcessHelper::TheCurrentPID().Leak().Leak() = prev_pid; - - continue; - } - } - } - - return false; - } - - /// @brief this checks if any process is on the team. - UserProcessScheduler::operator bool() - { - return mTeam.AsArray().Count() > 0; - } - - /// @brief this checks if no process is on the team. - bool UserProcessScheduler::operator!() - { - return mTeam.AsArray().Count() == 0; - } -} // namespace Kernel diff --git a/dev/ZKAKit/src/UserProcessTeam.cc b/dev/ZKAKit/src/UserProcessTeam.cc deleted file mode 100644 index 77497f3a..00000000 --- a/dev/ZKAKit/src/UserProcessTeam.cc +++ /dev/null @@ -1,55 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -/***********************************************************************************/ -/// @file UserProcessTeam.cc -/// @brief Process teams implementation. -/***********************************************************************************/ - -#include - -namespace Kernel -{ - UserProcessTeam::UserProcessTeam() - { - for (SizeT i = 0U; i < this->mProcessList.Count(); ++i) - { - this->mProcessList[i] = nullptr; - } - } - - /***********************************************************************************/ - /// @brief UserProcess list array getter. - /// @return The list of process to schedule. - /***********************************************************************************/ - - Array& UserProcessTeam::AsArray() - { - return this->mProcessList; - } - - /***********************************************************************************/ - /// @brief Get team ID. - /// @return The team's ID. - /***********************************************************************************/ - - ProcessID& UserProcessTeam::Id() noexcept - { - return this->mTeamId; - } - - /***********************************************************************************/ - /// @brief Get current process getter as Ref. - /// @return The current process header. - /***********************************************************************************/ - - Ref& UserProcessTeam::AsRef() - { - return this->mCurrentProcess; - } -} // namespace Kernel - -// last rev 05-03-24 diff --git a/dev/ZKAKit/src/Utils.cc b/dev/ZKAKit/src/Utils.cc deleted file mode 100644 index c0574dca..00000000 --- a/dev/ZKAKit/src/Utils.cc +++ /dev/null @@ -1,223 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include - -namespace Kernel -{ - Int32 rt_string_cmp(const Char* src, const Char* cmp, Size size) - { - if (!cmp || - !src) - return 1; - - Int32 counter = 0; - - for (Size index = 0; index < size; ++index) - { - if (src[index] != cmp[index]) - ++counter; - } - - return counter; - } - - Void rt_zero_memory(voidPtr pointer, Size len) - { - rt_set_memory(pointer, 0, len); - } - - SizeT rt_string_len(const Char* str, SizeT _len) - { - SizeT len{0}; - - do - { - if (len > _len) - { - return _len; - } - - ++len; - } while (str[len] != '\0'); - - return len; - } - - Size rt_string_len(const Char* ptr) - { - SizeT cnt{0}; - - do - { - ++cnt; - } while (ptr[cnt] != 0); - - return cnt; - } - - voidPtr rt_set_memory(voidPtr src, UInt32 value, Size len) - { - if (!src || len < 1) - return nullptr; - - UInt32* start = reinterpret_cast(src); - - while (len) - { - *start = value; - ++start; - --len; - } - - return (voidPtr)start; - } - - Int rt_move_memory(const voidPtr src, voidPtr dst, Size len) - { - if (len < 1) - return 2; - - if (!src || !dst) - return 1; - - Char* srcChr = reinterpret_cast(src); - Char* dstChar = reinterpret_cast(dst); - SizeT index = 0; - - while (index < len) - { - dstChar[index] = srcChr[index]; - srcChr[index] = 0; - - ++index; - } - - return 0; - } - - Int rt_copy_memory(const voidPtr src, voidPtr dst, Size len) - { - if (len < 1) - return 0; - - char* srcChr = reinterpret_cast(src); - char* dstChar = reinterpret_cast(dst); - Size index = 0; - - while (index < len) - { - dstChar[index] = srcChr[index]; - ++index; - } - - return index; - } - - const Char* alloc_string(const Char* text) - { - if (!text) - return nullptr; - - const Char* string = new Char[rt_string_len(text)]; - - if (!string) - return nullptr; - - voidPtr vText = reinterpret_cast(const_cast(text)); - voidPtr vStr = reinterpret_cast(const_cast(string)); - - rt_copy_memory(vText, vStr, rt_string_len(text)); - - return string; - } - - Int32 rt_to_uppercase(Int32 character) - { - if (character >= 'a' && character <= 'z') - return character - 0x20; - - return character; - } - - Int32 rt_to_lower(Int32 character) - { - if (character >= 'A' && character <= 'Z') - return character + 0x20; - - return character; - } - - Bool rt_to_string(Char* str, Int32 limit, Int32 base) - { - if (limit == 0) - return false; - - Int copy_limit = limit; - Int cnt = 0; - Int ret = base; - - while (limit != 1) - { - ret = ret % 10; - str[cnt] = ret; - - ++cnt; - --limit; - --ret; - } - - str[copy_limit] = '\0'; - return true; - } - - Boolean is_space(Char chr) - { - return chr == ' '; - } - - Boolean is_newln(Char chr) - { - return chr == '\n'; - } - - voidPtr rt_string_in_string(const Char* in, const Char* needle) - { - for (SizeT i = 0; i < rt_string_len(in); ++i) - { - if (rt_string_cmp(in + i, needle, rt_string_len(needle)) == 0) - return reinterpret_cast(const_cast(in + i)); - } - - return nullptr; - } - - // @brief Checks for a string start at the character. - - Char* rt_string_has_char(Char* str, const Char chr) - { - while (*str != chr) - { - ++str; - - if (*str == 0) - return nullptr; - } - - return str; - } -} // namespace Kernel - -EXTERN_C void* memset(void* dst, int c, long long unsigned int len) -{ - return Kernel::rt_set_memory(dst, c, len); -} - -EXTERN_C void* memcpy(void* dst, const void* src, long long unsigned int len) -{ - Kernel::rt_copy_memory(const_cast(src), dst, len); - return dst; -} diff --git a/dev/ZKAKit/src/Variant.cc b/dev/ZKAKit/src/Variant.cc deleted file mode 100644 index 0b91ae8d..00000000 --- a/dev/ZKAKit/src/Variant.cc +++ /dev/null @@ -1,33 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Theater Quality Inc, all rights reserved. - -------------------------------------------- */ - -#include - -namespace Kernel -{ - const Char* Variant::ToString() - { - switch (fKind) - { - case VariantKind::kXML: - return ("Class:{XML}"); - case VariantKind::kJson: - return ("Class:{Json}"); - case VariantKind::kString: - return ("Class:{String}"); - case VariantKind::kBlob: - return ("Class:{Blob}"); - default: - return ("Class:{Null}"); - } - } - - /// @brief Leak variant's instance. - VoidPtr Variant::Leak() - { - return fPtr; - } -} // namespace Kernel -- cgit v1.2.3