diff --git a/CLAUDE.md b/CLAUDE.md index d15f039..acdfcfa 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -171,15 +171,13 @@ kernel_api 已暴露能力:log, rsdp_address, fb_address/width/height/pitch/bp 当前 manifest 中 14 个外部 `.drv` 均已替换为真实 DKM 驱动并可加载执行。 -下一阶段优先路线: -1. **内存与 MMIO 基础设施**: 实现物理页分配器、页表映射接口、低位/高位 PCI MMIO 映射,解决 NVMe 4G 以上 BAR 和后续 DMA 映射问题。 -2. **DMA 与块设备数据路径**: 建立 contiguous DMA buffer、cache/屏障约定、PRDT/队列内存管理,然后推进 AHCI IDENTIFY/READ 与 NVMe admin queue/identify。 -3. **IRQ 后端升级**: ~~APIC EOI/IOAPIC redirection~~(B7 已完成:UTSM EOI 钩子 + legacy IRQ1/12/11 持续投递,QEMU 全链路验证;tick 2x 定论 = PIT mode3 IOAPIC edge 双触发 ~200Hz)。剩余:vector allocator 规范化、设备 IRQ 从 PIC 默认全面迁移、MSI/MSI-X(e1000/NVMe)。 -4. **网络数据路径**: 在 DMA/IRQ 完成后推进 e1000 RX/TX ring 与 virtio-net feature negotiation/virtqueue/RX-TX。 -5. **VFS 与真实块设备接入**: 将 FAT32 从测试镜像迁移到 AHCI/NVMe block provider,完善挂载、读取、目录遍历和错误路径。 -6. **DKM 工程化收尾**: 统一驱动本地 ABI 头、清理 warning、补充自动化 QEMU 场景(e1000/virtio-net/nvme/ahci)。 -7. **FirstInit 完善**: ~~修复按键崩溃(fb_text 优化问题)~~(B6 已验证未复现)、~~实现鼠标光标移动~~(M1 已完成)、~~user.conf 写盘~~(已完成)、网络配置界面。 -8. ~~**鼠标输入驱动**: 从 mouseInit stub 升级为完整 PS/2 鼠标 IRQ12 + 包解码 + 光标移动~~(M1 已完成)。 +下一阶段优先路线(活跃路线 = `docs/ROADMAP_INSANE.md` 五期填补计划,任务编号 F/U/D/R/E;状态唯一来源 = `docs/STATUS.md`): +1. **一期 F 系列剩余**: F2 统一帧缓冲控制台抽象、F3 跨平台构建(Make/CMake)。(F1 莲花 panic / F4 boot 分级自检 / F5 skip_firstinit 已完成) +2. **二期 U 系列**: UTRW Slow Path 真分支(slow_path.c 当前为 stub)、@sealed 段标记、密文页 dump、selftest 修 chacha20 KAT 间歇 FAIL。 +3. **三期 D 系列**: DKM 热卸载(引用计数)、裸机器码加载器、按名 API 导出表、彩色日志。 +4. **四期 R 系列收尾**: `drr_emergency_pool_kb`/`drr_recovery_log_size` 接线、segment/system 级回滚验证、PCQ per-cpu 多核。 +5. **五期 E 系列**: 启动莲花动画、假想时光键彩蛋、提交信息规范、风味 ISO。 +6. **工程债(Phase 存档遗留)**: vector allocator/MSI-X、NVMe 高位 BAR、virtio-net virtqueue、DKM 零 warning。 ## M1 里程碑完成状态(2026-07-29) diff --git a/CODE/UTSM/arch/x86_64/idt.c b/CODE/UTSM/arch/x86_64/idt.c index 255ce7a..b5c2448 100644 --- a/CODE/UTSM/arch/x86_64/idt.c +++ b/CODE/UTSM/arch/x86_64/idt.c @@ -2,6 +2,7 @@ #include #include #include +#include /* IDT gate descriptor (64-bit) */ typedef struct __attribute__((packed)) { @@ -628,29 +629,41 @@ void idt_handler(isr_frame *frame) { return; } /* CR2: #PF 的 fault 线性地址;CR3: 当前页表基址。 - * 寄存器 dump 用于定位 fault 指令的操作数来源。 */ + * 寄存器 dump 用于定位 fault 指令的操作数来源。 + * F1: 异常统一走莲花崩溃屏(panic_full 内部保留串口 dump + + * DRR 归档 + 帧缓冲直绘,最后 halt——不返回)。 */ u64 cr2, cr3; __asm__ volatile("mov %%cr2, %0" : "=r"(cr2)); __asm__ volatile("mov %%cr3, %0" : "=r"(cr3)); + (void)cr3; INSTR_PROBE(EXCP, frame->vector, frame->error_code, frame->rip, 0); - log_error("[IDT] exception"); - log_hex64("[IDT] vector=", frame->vector); - log_hex64("[IDT] err=", frame->error_code); - log_hex64("[IDT] rip=", frame->rip); - log_hex64("[IDT] cr2=", cr2); - log_hex64("[IDT] cr3=", cr3); - log_hex64("[IDT] rax=", frame->rax); - log_hex64("[IDT] rcx=", frame->rcx); - log_hex64("[IDT] rdx=", frame->rdx); - log_hex64("[IDT] rsi=", frame->rsi); - log_hex64("[IDT] rdi=", frame->rdi); - log_hex64("[IDT] r8=", frame->r8); - log_hex64("[IDT] r9=", frame->r9); - log_hex64("[IDT] r10=", frame->r10); - log_hex64("[IDT] r11=", frame->r11); - log_hex64("[IDT] cs=", frame->cs); - log_hex64("[IDT] rflags=", frame->rflags); - for (;;) { __asm__ volatile ("cli; hlt"); } + panic_regs pr; + pr.rip = frame->rip; + pr.rsp = 0; /* isr_frame 不含 rsp(stub 内使用),置 0 */ + pr.rflags = frame->rflags; + pr.cs = frame->cs; + pr.err = frame->error_code; + pr.vector = frame->vector; + pr.cr2 = cr2; + pr.rax = frame->rax; + pr.rcx = frame->rcx; + pr.rdx = frame->rdx; + pr.rsi = frame->rsi; + pr.rdi = frame->rdi; + pr.r8 = frame->r8; + pr.r9 = frame->r9; + pr.r10 = frame->r10; + pr.r11 = frame->r11; + char sym[16]; + sym[0] = 'U'; sym[1] = 'T'; sym[2] = 'S'; sym[3] = 'M'; sym[4] = '-'; + sym[5] = 'E'; sym[6] = 'X'; sym[7] = 'C'; + u32 v = frame->vector; + u32 hi = (v >> 4) & 0xF, lo = v & 0xF; + sym[8] = (char)(hi < 10 ? '0' + hi : 'A' + hi - 10); + sym[9] = (char)(lo < 10 ? '0' + lo : 'A' + lo - 10); + sym[10] = 0; + panic_full(sym, "cpu exception", &pr); + for (;;) { __asm__ volatile ("cli; hlt"); } /* 兜底(panic_full 不返回) */ } /* PIC IRQ: vectors 0x20-0x2F (32-47) diff --git a/CODE/UTSM/arch/x86_64/idt.d b/CODE/UTSM/arch/x86_64/idt.d new file mode 100644 index 0000000..3cb8d91 --- /dev/null +++ b/CODE/UTSM/arch/x86_64/idt.d @@ -0,0 +1,8 @@ +arch/x86_64/idt.o: arch\x86_64\idt.c include\utsm\idt.h \ + include\utsm\types.h include\utsm\log.h include\utsm\instr.h \ + include\utsm\panic.h +include\utsm\idt.h: +include\utsm\types.h: +include\utsm\log.h: +include\utsm\instr.h: +include\utsm\panic.h: diff --git a/CODE/UTSM/arch/x86_64/idt.o b/CODE/UTSM/arch/x86_64/idt.o index b87d121..fac639f 100644 Binary files a/CODE/UTSM/arch/x86_64/idt.o and b/CODE/UTSM/arch/x86_64/idt.o differ diff --git a/CODE/UTSM/dkm/kernel_api.c b/CODE/UTSM/dkm/kernel_api.c index 57363ec..9f1f14e 100644 --- a/CODE/UTSM/dkm/kernel_api.c +++ b/CODE/UTSM/dkm/kernel_api.c @@ -3,6 +3,7 @@ #include #include #include +#include static void dkm_api_info(const char *msg) { log_info(msg); @@ -17,7 +18,8 @@ static void dkm_api_error(const char *msg) { } static void dkm_api_panic(const char *msg) { - log_error(msg); + /* F1: 驱动 panic 统一走莲花崩溃屏(串口 dump + DRR 归档 + 帧缓冲) */ + panic_full("DKM-PANIC", msg, 0); for (;;) { __asm__ volatile("cli; hlt"); } diff --git a/CODE/UTSM/dkm/kernel_api.d b/CODE/UTSM/dkm/kernel_api.d new file mode 100644 index 0000000..13c9e2d --- /dev/null +++ b/CODE/UTSM/dkm/kernel_api.d @@ -0,0 +1,16 @@ +dkm/kernel_api.o: dkm\kernel_api.c include\utsm\dkm.h \ + include\utsm\types.h include\utsm\dma.h include\utsm\block.h \ + include\utsm\net.h include\utsm\paging.h include\utsm\log.h \ + include\utsm\idt.h include\utsm\mm.h include\utsm\panic.h \ + dkm\..\arch\x86_64\limine.h +include\utsm\dkm.h: +include\utsm\types.h: +include\utsm\dma.h: +include\utsm\block.h: +include\utsm\net.h: +include\utsm\paging.h: +include\utsm\log.h: +include\utsm\idt.h: +include\utsm\mm.h: +include\utsm\panic.h: +dkm\..\arch\x86_64\limine.h: diff --git a/CODE/UTSM/dkm/kernel_api.o b/CODE/UTSM/dkm/kernel_api.o index e869049..73c7eff 100644 Binary files a/CODE/UTSM/dkm/kernel_api.o and b/CODE/UTSM/dkm/kernel_api.o differ diff --git a/CODE/UTSM/drr/drr_stub.c b/CODE/UTSM/drr/drr_stub.c index c563ad1..12c49ee 100644 --- a/CODE/UTSM/drr/drr_stub.c +++ b/CODE/UTSM/drr/drr_stub.c @@ -316,6 +316,30 @@ void drr_report_fault(const char *reason) { g_drr.recovery_generation++; } +/* ---- F1: 崩溃归档(panic_full 调用;crash_buf 写 symbol+msg+rip 简表) ---- + * 返回 0=已归档;-1=DRR 未初始化(crash_buf 不可用)。 */ +int drr_crash_archive(const char *symbol, const char *msg, const void *regs) { + if (!g_drr.initialized || !g_drr.crash_buf || g_drr.crash_buf_size == 0) { + return -1; + } + u64 i = 0; + u8 *b = g_drr.crash_buf; + u64 cap = g_drr.crash_buf_size - 1; + /* 头部标记 */ + const char *magic = "CRASH1"; + for (const char *s = magic; *s && i < cap; s++) b[i++] = (u8)*s; + b[i++] = '|'; + for (const char *s = symbol ? symbol : "UNKNOWN"; *s && i < cap; s++) b[i++] = (u8)*s; + b[i++] = '|'; + for (const char *s = msg ? msg : "-"; *s && i < cap; s++) b[i++] = (u8)*s; + b[i] = 0; + /* recovery generation 前进(归档计数) */ + g_drr.recovery_generation++; + log_error("[DRR] crash archived"); + log_hex64("[DRR] generation=", g_drr.recovery_generation); + return 0; +} + /* ---- Recovery Log ---- */ void drr_log_write_intent(u32 segment_slot, u64 offset, u64 len) { if (!g_drr.initialized || !g_drr.log_base) return; diff --git a/CODE/UTSM/drr/drr_stub.o b/CODE/UTSM/drr/drr_stub.o index c421513..248a3ea 100644 Binary files a/CODE/UTSM/drr/drr_stub.o and b/CODE/UTSM/drr/drr_stub.o differ diff --git a/CODE/UTSM/include/utsm/assert.h b/CODE/UTSM/include/utsm/assert.h index 033f6a7..87333fe 100644 --- a/CODE/UTSM/include/utsm/assert.h +++ b/CODE/UTSM/include/utsm/assert.h @@ -2,6 +2,7 @@ #define UTSM_ASSERT_H #include +#include #define UTSM_ASSERT(cond) do { if (!(cond)) { panic("assertion failed: " #cond); } } while (0) diff --git a/CODE/UTSM/include/utsm/drr.h b/CODE/UTSM/include/utsm/drr.h index 0d3df35..ba3ebe1 100644 --- a/CODE/UTSM/include/utsm/drr.h +++ b/CODE/UTSM/include/utsm/drr.h @@ -105,6 +105,8 @@ void drr_init(void); const u64 *drr_get_root_key(void); u64 drr_recovery_generation(void); void drr_report_fault(const char *reason); +/* F1: 崩溃归档(crash_buf 写入;返回 0=已归档,-1=DRR 未初始化) */ +int drr_crash_archive(const char *symbol, const char *msg, const void *regs); void drr_log_write_intent(u32 segment_slot, u64 offset, u64 len); void drr_log_write_commit(u32 segment_slot, u64 offset, u64 len); diff --git a/CODE/UTSM/include/utsm/panic.h b/CODE/UTSM/include/utsm/panic.h new file mode 100644 index 0000000..25d5886 --- /dev/null +++ b/CODE/UTSM/include/utsm/panic.h @@ -0,0 +1,36 @@ +#ifndef UTSM_PANIC_H +#define UTSM_PANIC_H + +#include + +/* =================================================================== + * F1: 内核 panic 统一兜底(莲花崩溃屏) + * + * 崩了也得崩出莲花: + * - 帧缓冲直接绘制(不走 console_fb 驱动——崩溃时驱动可能已挂) + * - 淡金莲花 + panic_symbol + 消息 + 寄存器简表 + * - DRR 归档(crash_buf)后 halt + * + * 本路径只依赖:Limine framebuffer(Limine 常驻映射)+ serial + DRR + * Emergency Pool(静态区),不依赖堆/驱动/中断。 + * =================================================================== */ + +/* 寄存器简表(可传 0:无异常帧的普通 panic) */ +typedef struct panic_regs { + u64 rip; + u64 rsp; + u64 rflags; + u64 cs; + u64 err; + u64 vector; + u64 cr2; + u64 rax, rcx, rdx, rsi, rdi, r8, r9, r10, r11; +} panic_regs; + +/* 统一 panic 入口:画莲花崩溃屏 + 串口日志 + DRR 归档 + halt(不返回) */ +void panic_full(const char *symbol, const char *msg, const panic_regs *regs); + +/* 兼容旧接口:panic("msg") = panic_full("UTSM-PANIC", msg, 0) */ +void panic(const char *msg); + +#endif /* UTSM_PANIC_H */ diff --git a/CODE/UTSM/kernel/boot_selftest.c b/CODE/UTSM/kernel/boot_selftest.c new file mode 100644 index 0000000..764cd0a --- /dev/null +++ b/CODE/UTSM/kernel/boot_selftest.c @@ -0,0 +1,136 @@ +#include +#include +#include +#include +#include +#include +#include "ini_parser.h" + +/* =================================================================== + * F4: boot_ok 分级启动自检 + * + * "知道自己是几成疯。" + * FUCK [boot] selftest=0|1|2: + * 0 = 关闭(仅打一行 skip) + * 1 = 快速:结构健全性检查(IDT/GDT/配置/DRR/调度器服务表) + * 2 = 全量:快速 + 功能探针(DMA alloc/write/free、段分配) + * + * 失败语义:致命项(IDT/CS)→ 莲花 panic;非致命项 → WARN 继续。 + * 输出:串口 + 每项一行 [boot] 明细。 + * =================================================================== */ + +/* 致命项返回 -1(调用方 halt / panic),非致命返回计数。 */ +typedef struct { + int level; + int pass; + int warn; + int fail; +} bself_ctx; + +static void bself_line(bself_ctx *c, const char *name, int fatal, int ok) { + if (ok) { + c->pass++; + log_info("[boot] selftest [OK] "); + log_info(name); + } else if (fatal) { + c->fail++; + log_error("[boot] selftest [FATAL]"); + log_error(name); + } else { + c->warn++; + log_warn("[boot] selftest [WARN]"); + log_warn(name); + } +} + +/* IDTR 健全性:limit==4095(256 项)且 base 非零 */ +static int check_idt(u64 *base_out) { + /* sidt 写 10 字节:limit(2) + base(8) */ + u8 buf[10] __attribute__((aligned(2))); + __asm__ volatile("sidt %0" : "=m"(buf)); + u16 limit = *(u16 *)&buf[0]; + u64 base = *(u64 *)&buf[2]; + *base_out = base; + return (limit == 4095) && (base != 0); +} + +static int check_cs_valid(void) { + u64 cs; + __asm__ volatile("mov %%cs, %0" : "=r"(cs)); + return cs != 0; +} + +int boot_selftest_run(int level) { + bself_ctx c = { level, 0, 0, 0 }; + + log_info("[boot] selftest begin"); + log_info("[boot] level:"); + log_hex64("[boot] ", (u64)level); + + if (level <= 0) { + log_info("[boot] selftest skipped (selftest=0)"); + return 0; + } + + /* ---- 致命项 1: IDT 覆盖 ---- */ + u64 idt_base = 0; + int idt_ok = check_idt(&idt_base); + bself_line(&c, "IDT: limit/base", 1, idt_ok); + if (!idt_ok) { + panic_full("UTSM-BST", "IDT malformed at boot selftest", 0); + } + + /* ---- 致命项 2: CS 有效 ---- */ + int cs_ok = check_cs_valid(); + bself_line(&c, "CS: ring0 selector", 1, cs_ok); + if (!cs_ok) { + panic_full("UTSM-BST", "CS invalid at boot selftest", 0); + } + + /* ---- 非致命: DRR 初始化 ---- */ + int drr_ok = drr_recovery_generation() >= 1; + bself_line(&c, "DRR: emergency pool + ckpt slots", 0, drr_ok); + + /* ---- 非致命: 内核服务表(调度器) ---- */ + int sched_ok = utsm_sched_get_api() != 0; + bself_line(&c, "SCHED: service table", 0, sched_ok); + + /* ---- 非致命: kernel_api 平台信息 ---- */ + const dkm_kernel_api *api = dkm_get_kernel_api(); + bself_line(&c, "KAPI: kernel_api present", 0, api != 0); + + if (level >= 2) { + /* ---- 功能探针: DMA 页分配 + 写读回 ---- */ + dkm_dma_buffer buf; + int dma_ok = 0; + if (dma_alloc_pages(1, 4096, 0xFFFFFFFFULL, &buf) == 0 && buf.virt) { + volatile u64 *p = (volatile u64 *)buf.virt; + p[0] = 0x4C4F545553533FULL; /* "LOTUSS" 探针值 */ + dma_ok = (p[0] == 0x4C4F545553533FULL); + if (dma_ok) { + /* 注意:当前 DMA 分配器无 free 接口,1 页探针为一次性成本 */ + log_info("[boot] selftest dma probe page kept (no free API)"); + } + } + bself_line(&c, "DMA: alloc+rw probe", 0, dma_ok); + } + + log_info("[boot] selftest summary:"); + log_hex64("[boot] pass=", (u64)c.pass); + log_hex64("[boot] warn=", (u64)c.warn); + log_hex64("[boot] fail=", (u64)c.fail); + log_info(c.fail ? "[boot] BOOT-OK: FATAL-FAIL" : "[boot] BOOT-OK"); + + return c.fail ? -1 : 0; +} + +/* F1 验证钩子:FUCK [boot] panic_test=1 时触发莲花崩溃屏(默认 0)。 + * 用于 QEMU 演示/回归:panic_full → 串口 dump + DRR 归档 + 帧缓冲 + halt。 */ +void boot_panic_test(const ini_config *cfg); +void boot_panic_test(const ini_config *cfg) { + extern int ini_get_bool(const ini_config *cfg, const char *section, const char *key, int defval); + if (ini_get_bool(cfg, "boot", "panic_test", 0)) { + log_warn("[boot] panic_test=1 -> triggering lotus panic screen"); + panic_full("UTSM-E42", "lotus panic selftest", 0); + } +} diff --git a/CODE/UTSM/kernel/boot_selftest.d b/CODE/UTSM/kernel/boot_selftest.d new file mode 100644 index 0000000..d876121 --- /dev/null +++ b/CODE/UTSM/kernel/boot_selftest.d @@ -0,0 +1,16 @@ +kernel/boot_selftest.o: kernel\boot_selftest.c include\utsm\log.h \ + include\utsm\types.h include\utsm\panic.h include\utsm\drr.h \ + include\utsm\config.h include\utsm\dkm.h include\utsm\dma.h \ + include\utsm\block.h include\utsm\net.h include\utsm\paging.h \ + kernel\ini_parser.h +include\utsm\log.h: +include\utsm\types.h: +include\utsm\panic.h: +include\utsm\drr.h: +include\utsm\config.h: +include\utsm\dkm.h: +include\utsm\dma.h: +include\utsm\block.h: +include\utsm\net.h: +include\utsm\paging.h: +kernel\ini_parser.h: diff --git a/CODE/UTSM/kernel/main.c b/CODE/UTSM/kernel/main.c index 9eda890..e88fb5a 100644 --- a/CODE/UTSM/kernel/main.c +++ b/CODE/UTSM/kernel/main.c @@ -472,21 +472,26 @@ void kernel_main(void) { dsm_load_by_manifest_ex(cfg); INSTR_TS_END(ts_dsm, "dsm_load_manifest"); - /* === selftest — 可通过 FUCK [boot] selftest=0 跳过 === */ - int run_selftest = ini_get_bool(cfg, "boot", "selftest", 1); - if (run_selftest) { - INSTR_TS_DECL(ts_self); - INSTR_TS_BEGIN(ts_self); - int result = utsm_selftest_run(); - INSTR_TS_END(ts_self, "selftest"); - if (result == 0) { - log_info("[UTSM] SELFTEST PASS"); - } else { - log_error("[UTSM] SELFTEST FAIL"); - arch_halt_forever(); + /* === F4: 分级启动自检 — FUCK [boot] selftest=0|1|2 === + * 0=关 / 1=快速(结构健全性) / 2=全量(+DMA 探针 + UTSM selftest) */ + { + int self_level = ini_get_int(cfg, "boot", "selftest", 1); + extern int boot_selftest_run(int level); + extern void boot_panic_test(const ini_config *cfg); + boot_selftest_run(self_level); + boot_panic_test(cfg); + if (self_level >= 2) { + INSTR_TS_DECL(ts_self); + INSTR_TS_BEGIN(ts_self); + int result = utsm_selftest_run(); + INSTR_TS_END(ts_self, "selftest"); + if (result == 0) { + log_info("[UTSM] SELFTEST PASS"); + } else { + log_error("[UTSM] SELFTEST FAIL"); + arch_halt_forever(); + } } - } else { - log_info("[UTSM] selftest skipped by FUCK config"); } /* === SAS-R0-PCQ 调度器:demo 任务 + LAPIC tick 抢占启用(Phase 7) === diff --git a/CODE/UTSM/kernel/main.o b/CODE/UTSM/kernel/main.o index 921f267..6012a26 100644 Binary files a/CODE/UTSM/kernel/main.o and b/CODE/UTSM/kernel/main.o differ diff --git a/CODE/UTSM/kernel/panic.c b/CODE/UTSM/kernel/panic.c index 0b03bfc..af0b3dd 100644 --- a/CODE/UTSM/kernel/panic.c +++ b/CODE/UTSM/kernel/panic.c @@ -1,9 +1,250 @@ #include +#include +#include +#include +#include "../arch/x86_64/limine.h" + +/* =================================================================== + * F1: 莲花崩溃屏(panic_full) + * + * "崩了也得崩出莲花。" + * 帧缓冲直绘:淡金莲花 + panic_symbol + 消息 + 寄存器简表, + * DRR crash_buf 归档后 halt。不依赖驱动/堆/中断。 + * =================================================================== */ void arch_halt_forever(void); -void panic(const char *msg) { - log_error("[PANIC]"); - log_error(msg); +extern volatile struct limine_framebuffer_request g_fb_request; + +/* 11x18 Consolas 灰度字库(同 firstInit/ascii_bitmaps.c,自动生成) */ +#include "panic_font.inc" + +/* ---- 最小绘制原语(32bpp XRGB,带边界检查) ---- */ + +typedef struct { + u32 *fb; + u64 w, h, pitch; +} pfb; + +static int pfb_init(pfb *p) { + if (!g_fb_request.response || g_fb_request.response->framebuffer_count == 0) + return -1; + struct limine_framebuffer *fb = g_fb_request.response->framebuffers[0]; + if (fb->bpp < 32 || !fb->address) return -1; + p->fb = (u32 *)fb->address; + p->w = fb->width; + p->h = fb->height; + p->pitch = fb->pitch; + return 0; +} + +static inline void ppx(pfb *p, i64 x, i64 y, u32 c) { + if (x < 0 || (u64)x >= p->w || y < 0 || (u64)y >= p->h) return; + *(u32 *)((u8 *)p->fb + (u64)y * p->pitch + (u64)x * 4) = c; +} + +static void prect(pfb *p, i64 x, i64 y, i64 w, i64 h, u32 c) { + for (i64 r = 0; r < h; r++) + for (i64 c2 = 0; c2 < w; c2++) + ppx(p, x + c2, y + r, c); +} + +static u32 pgrad(u32 top, u32 bot, i64 y, i64 h) { + if (h <= 1) return top; + if (y < 0) y = 0; + if (y >= h) y = h - 1; + u32 a = (u32)(((u64)y * 255ULL) / (u64)(h - 1)); + u32 na = 256 - a; + u32 r = (((top >> 16) & 0xFF) * na + ((bot >> 16) & 0xFF) * a) >> 8; + u32 g = (((top >> 8) & 0xFF) * na + ((bot >> 8) & 0xFF) * a) >> 8; + u32 b = ((top & 0xFF) * na + (bot & 0xFF) * a) >> 8; + return 0xFF000000u | (r << 16) | (g << 8) | b; +} + +/* 11x18 灰度字符(g_ascii: ASCII 32..126) */ +static void pchar(pfb *p, char ch, i64 x, i64 y, u32 fg) { + u32 idx = (u32)ch - 32; + if (idx > 94) idx = 0; + const u8 *g = g_ascii[idx]; + for (i64 r = 0; r < g_ascii_h; r++) { + for (i64 c = 0; c < g_ascii_w; c++) { + u8 a = g[r * g_ascii_w + c]; + if (a < 24) continue; + ppx(p, x + c, y + r, fg); + } + } +} + +static void pstr(pfb *p, const char *s, i64 x, i64 y, u32 fg) { + i64 cx = x; + while (*s) { + pchar(p, *s, cx, y, fg); + cx += g_ascii_w; + s++; + } +} + +static void pstr_center(pfb *p, const char *s, i64 y, u32 fg) { + i64 w = 0; + for (const char *q = s; *q; q++) w += g_ascii_w; + pstr(p, s, ((i64)p->w - w) / 2, y, fg); +} + +/* ---- 莲花:8 瓣椭圆花瓣 + 金芯(淡金 on 暗底) ---- */ + +/* sin 表:33 项覆盖 [0, π/2],步长 (π/2)/32,值×1000。 + * cos(i) = SIN33[32-i]。视觉用途精度足够。 */ +static const i16 SIN33[33] = { + 0, 49, 98, 146, 195, 242, 290, 336, + 383, 428, 471, 513, 556, 597, 635, 671, + 707, 740, 773, 803, 831, 857, 882, 905, + 924, 941, 958, 972, 984, 993, 999, 1000, 1000 +}; + +/* a: q12 角度(0..3071,3072=整圈),输出 sin/cos ×1000 */ +static void sincos_q12(i64 a, i64 *so, i64 *co) { + a %= 3072; + if (a < 0) a += 3072; + i32 qs = (i32)(a / 768); + i32 idx = (i32)((a % 768) / 24); + i64 s = 0, c = 0; + switch (qs) { + case 0: s = SIN33[idx]; c = SIN33[32 - idx]; break; + case 1: s = SIN33[32 - idx]; c = -SIN33[idx]; break; + case 2: s = -SIN33[idx]; c = -SIN33[32 - idx]; break; + default: s = -SIN33[32 - idx]; c = SIN33[idx]; break; + } + *so = s; + *co = c; +} + +static void petal(pfb *p, i64 cx, i64 cy, i64 angle_q12, i64 len, i64 wid, u32 color) { + /* 花瓣局部坐标系:u 沿长轴(尖端收窄),v 沿短轴;旋转到屏幕坐标 */ + i64 s, c; + sincos_q12(angle_q12, &s, &c); + i64 len1000 = len ? len * 1000 : 1; + i64 wid1000 = wid ? wid * 1000 : 1; + for (i64 u = -len; u <= len; u++) { + for (i64 v = -wid; v <= wid; v++) { + i64 eu = (u * 1000 * 1000) / len1000; /* -1000..1000 */ + i64 ev = (v * 1000 * 1000) / wid1000; + if (eu > 200) ev = (ev * (1000 - (eu - 200) * 2)) / 1000; /* 收尖 */ + if (eu * eu + ev * ev > 1000 * 1000) continue; + i64 dx = (u * c - v * s) / 1000; + i64 dy = (u * s + v * c) / 1000; + ppx(p, cx + dx, cy + dy, color); + } + } +} + +static void lotus(pfb *p, i64 cx, i64 cy) { + const u32 petal_c = 0xFFD8B4E8; /* 淡粉金 */ + const u32 petal_c2 = 0xFFC498D8; /* 深一档 */ + const u32 core_c = 0xFFF0D080; /* 金芯 */ + for (i64 k = 0; k < 8; k++) { + i64 ang = k * 384; /* 3072/8 */ + petal(p, cx, cy, ang, 46, 15, (k & 1) ? petal_c : petal_c2); + } + /* 金芯圆 */ + for (i64 dy = -12; dy <= 12; dy++) + for (i64 dx = -12; dx <= 12; dx++) + if (dx * dx + dy * dy <= 144) + ppx(p, cx + dx, cy + dy, core_c); + /* 芯内小点 */ + for (i64 dy = -4; dy <= 4; dy++) + for (i64 dx = -4; dx <= 4; dx++) + if (dx * dx + dy * dy <= 16) + ppx(p, cx + dx, cy + dy, 0xFF7050A0); +} + +/* ---- hex 输出 ---- */ + +static void phex64(pfb *p, u64 v, i64 x, i64 y, u32 fg) { + char buf[19]; + buf[0] = '0'; buf[1] = 'x'; + for (i32 i = 0; i < 16; i++) { + u32 nib = (u32)((v >> ((15 - i) * 4)) & 0xF); + buf[2 + i] = (char)(nib < 10 ? '0' + nib : 'A' + nib - 10); + } + buf[18] = 0; + pstr(p, buf, x, y, fg); +} + +static void pregline(pfb *p, const char *name, u64 v, i64 x, i64 y, u32 fg) { + pstr(p, name, x, y, fg); + phex64(p, v, x + 5 * g_ascii_w, y, fg); +} + +/* ---- DRR 归档(drr.h 声明,drr_stub.c 提供;未初始化时返回 -1) ---- */ + +void panic_full(const char *symbol, const char *msg, const panic_regs *regs) { + log_error("[PANIC] =========================================="); + log_error("[PANIC] panic_full: 莲花崩溃屏"); + if (symbol) { log_error("[PANIC] symbol:"); log_error(symbol); } + if (msg) { log_error("[PANIC] msg:"); log_error(msg); } + if (regs) { + log_hex64("[PANIC] vector=", regs->vector); + log_hex64("[PANIC] err=", regs->err); + log_hex64("[PANIC] rip=", regs->rip); + log_hex64("[PANIC] rsp=", regs->rsp); + log_hex64("[PANIC] rflags=", regs->rflags); + log_hex64("[PANIC] cr2=", regs->cr2); + log_hex64("[PANIC] rax=", regs->rax); + log_hex64("[PANIC] rcx=", regs->rcx); + log_hex64("[PANIC] rdx=", regs->rdx); + } + + int archived = drr_crash_archive(symbol, msg, regs); + if (archived == 0) { + log_error("[PANIC] 本次崩溃已归档至 DRR"); + } else { + log_warn("[PANIC] DRR 归档不可用(未初始化),仅留串口日志"); + } + + /* 屏幕绘制放在归档之后:绘制循环中再出异常也不丢归档 */ + pfb P, *p = &P; + if (pfb_init(p) == 0) { + /* 暗夜渐变:深蓝 → 暗紫 */ + const u32 top = 0xFF101830, bot = 0xFF241430; + for (u64 y = 0; y < p->h; y++) { + u32 c = pgrad(top, bot, (i64)y, (i64)p->h); + u32 *line = (u32 *)((u8 *)p->fb + y * p->pitch); + for (u64 x = 0; x < p->w; x++) line[x] = c; + } + + lotus(p, (i64)p->w / 2, (i64)p->h / 2 - 120); + + const u32 fg = 0xFFF0E8D8, dim = 0xFFB0A8C0, acc = 0xFFF0D080; + pstr_center(p, "DESHAB PANIC", (i64)p->h / 2 + 10, acc); + + i64 y = (i64)p->h / 2 + 60; + if (symbol) pstr_center(p, symbol, y, fg), y += g_ascii_h + 8; + if (msg) { + /* 单行截断 60 字符 */ + char line[61]; + u32 i = 0; + while (msg[i] && i < 60) { line[i] = msg[i]; i++; } + line[i] = 0; + pstr_center(p, line, y, fg), y += g_ascii_h + 8; + } + if (regs) { + if (y + g_ascii_h * 6 < (i64)p->h) { + pregline(p, "RIP ", regs->rip, (i64)p->w / 2 - 14 * g_ascii_w / 2, y, dim); y += g_ascii_h + 2; + pregline(p, "RSP ", regs->rsp, (i64)p->w / 2 - 14 * g_ascii_w / 2, y, dim); y += g_ascii_h + 2; + pregline(p, "FLG ", regs->rflags, (i64)p->w / 2 - 14 * g_ascii_w / 2, y, dim); y += g_ascii_h + 2; + if (regs->vector == 14) { + pregline(p, "CR2 ", regs->cr2, (i64)p->w / 2 - 14 * g_ascii_w / 2, y, dim); y += g_ascii_h + 2; + } + } + } + pstr_center(p, archived == 0 ? "crash archived to DRR" : "DRR archive unavailable", + (i64)p->h - g_ascii_h - 24, dim); + } + + log_error("[PANIC] halt"); arch_halt_forever(); } + +void panic(const char *msg) { + panic_full("UTSM-PANIC", msg, 0); +} diff --git a/CODE/UTSM/kernel/panic.d b/CODE/UTSM/kernel/panic.d new file mode 100644 index 0000000..40f91cb --- /dev/null +++ b/CODE/UTSM/kernel/panic.d @@ -0,0 +1,10 @@ +kernel/panic.o: kernel\panic.c include\utsm\log.h include\utsm\types.h \ + include\utsm\panic.h include\utsm\drr.h include\utsm\config.h \ + kernel\..\arch\x86_64\limine.h kernel\panic_font.inc +include\utsm\log.h: +include\utsm\types.h: +include\utsm\panic.h: +include\utsm\drr.h: +include\utsm\config.h: +kernel\..\arch\x86_64\limine.h: +kernel\panic_font.inc: diff --git a/CODE/UTSM/kernel/panic.o b/CODE/UTSM/kernel/panic.o index 3ebb291..4bf2461 100644 Binary files a/CODE/UTSM/kernel/panic.o and b/CODE/UTSM/kernel/panic.o differ diff --git a/CODE/UTSM/kernel/panic_font.inc b/CODE/UTSM/kernel/panic_font.inc new file mode 100644 index 0000000..c004060 --- /dev/null +++ b/CODE/UTSM/kernel/panic_font.inc @@ -0,0 +1,1908 @@ +/* Auto-generated by render_ascii.py - Consolas 18px grayscale */ +/* 95 glyphs: ASCII 32 (space) .. 126 (~), cell 11x18 */ +/* Do not edit - regenerate via: py render_ascii.py */ + +static const int g_ascii_w = 11; +static const int g_ascii_h = 18; +static const unsigned char g_ascii[95][11*18] = { + /* 'space' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* '0x21' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 253, 216, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 246, 210, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 239, 204, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 232, 198, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 226, 192, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 219, 186, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 212, 180, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 205, 174, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 198, 168, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 191, 162, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 21, 223, 202, 3, 0, 0, 0, 0, + 0, 0, 0, 22, 224, 204, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* '0x22' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 181, 255, 43, 73, 255, 151, 0, 0, 0, + 0, 0, 165, 255, 27, 57, 255, 135, 0, 0, 0, + 0, 0, 149, 255, 11, 41, 255, 119, 0, 0, 0, + 0, 0, 132, 251, 0, 24, 255, 103, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* '0x23' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 245, 83, 0, 105, 226, 0, 0, 0, + 0, 0, 14, 255, 59, 0, 130, 199, 0, 0, 0, + 0, 0, 39, 255, 35, 0, 155, 173, 0, 0, 0, + 44, 255, 255, 255, 255, 255, 255, 255, 255, 132, 0, + 0, 0, 95, 234, 0, 0, 213, 118, 0, 0, 0, + 0, 0, 123, 209, 0, 0, 238, 91, 0, 0, 0, + 0, 0, 150, 184, 0, 7, 255, 65, 0, 0, 0, + 160, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, + 0, 0, 207, 125, 0, 67, 255, 9, 0, 0, 0, + 0, 0, 235, 97, 0, 95, 237, 0, 0, 0, 0, + 0, 7, 254, 69, 0, 122, 209, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* '0x24' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 219, 108, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 246, 78, 0, 0, 0, 0, + 0, 0, 72, 192, 242, 255, 255, 255, 8, 0, 0, + 0, 99, 254, 109, 83, 253, 5, 0, 0, 0, 0, + 0, 215, 196, 0, 99, 226, 0, 0, 0, 0, 0, + 0, 217, 230, 20, 133, 193, 0, 0, 0, 0, 0, + 0, 75, 249, 235, 220, 164, 0, 0, 0, 0, 0, + 0, 0, 40, 164, 251, 254, 184, 49, 0, 0, 0, + 0, 0, 0, 0, 236, 166, 226, 249, 67, 0, 0, + 0, 0, 0, 11, 255, 55, 19, 240, 193, 0, 0, + 0, 0, 0, 44, 255, 23, 1, 229, 191, 0, 0, + 0, 0, 0, 76, 247, 29, 144, 251, 72, 0, 0, + 8, 255, 255, 255, 254, 227, 173, 58, 0, 0, 0, + 0, 0, 0, 159, 169, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 194, 133, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* '0x25' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 7, 158, 240, 216, 60, 0, 0, 26, 241, 103, 0, + 114, 221, 23, 137, 214, 0, 0, 171, 199, 1, 0, + 162, 166, 0, 71, 251, 1, 74, 251, 46, 0, 0, + 127, 217, 19, 143, 203, 10, 223, 137, 0, 0, 0, + 15, 179, 244, 205, 47, 137, 224, 10, 0, 0, 0, + 0, 0, 0, 0, 45, 251, 75, 0, 0, 0, 0, + 0, 0, 0, 1, 198, 171, 0, 0, 0, 0, 0, + 0, 0, 0, 104, 241, 26, 0, 0, 0, 0, 0, + 0, 0, 23, 239, 108, 62, 212, 242, 164, 5, 0, + 0, 0, 166, 203, 5, 231, 120, 27, 234, 98, 0, + 0, 70, 252, 49, 26, 255, 46, 0, 191, 136, 0, + 8, 220, 142, 0, 4, 242, 112, 30, 237, 87, 0, + 132, 227, 12, 0, 0, 82, 225, 238, 144, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* '0x26' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 54, 198, 243, 208, 72, 0, 0, 0, 0, + 0, 19, 239, 143, 14, 140, 246, 28, 0, 0, 0, + 0, 96, 255, 33, 0, 38, 255, 94, 0, 0, 0, + 0, 116, 255, 44, 0, 65, 255, 83, 0, 0, 0, + 0, 74, 255, 126, 8, 195, 241, 20, 0, 0, 0, + 0, 3, 215, 240, 202, 248, 81, 0, 0, 0, 0, + 0, 2, 161, 255, 248, 49, 0, 0, 0, 0, 0, + 0, 165, 252, 188, 255, 125, 0, 147, 240, 0, 0, + 62, 255, 122, 3, 191, 253, 66, 168, 211, 0, 0, + 115, 255, 35, 0, 23, 230, 232, 231, 150, 0, 0, + 96, 255, 56, 0, 0, 62, 252, 255, 64, 0, 0, + 21, 235, 199, 40, 16, 94, 243, 254, 185, 2, 0, + 0, 44, 180, 235, 246, 197, 71, 128, 255, 129, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* '0x27' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 4, 255, 235, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 245, 219, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 229, 203, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 212, 187, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* '0x28' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 8, 177, 60, 0, 0, 0, + 0, 0, 0, 0, 0, 170, 241, 43, 0, 0, 0, + 0, 0, 0, 0, 108, 254, 72, 0, 0, 0, 0, + 0, 0, 0, 22, 243, 163, 0, 0, 0, 0, 0, + 0, 0, 0, 130, 251, 27, 0, 0, 0, 0, 0, + 0, 0, 0, 215, 186, 0, 0, 0, 0, 0, 0, + 0, 0, 31, 255, 110, 0, 0, 0, 0, 0, 0, + 0, 0, 64, 255, 77, 0, 0, 0, 0, 0, 0, + 0, 0, 85, 255, 58, 0, 0, 0, 0, 0, 0, + 0, 0, 67, 255, 79, 0, 0, 0, 0, 0, 0, + 0, 0, 37, 255, 113, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 224, 190, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 134, 252, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 25, 241, 170, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 109, 255, 79, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 171, 244, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 7, 176, 56, 0, 0, 0, + }, + /* '0x29' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 76, 167, 4, 0, 0, 0, 0, 0, 0, + 0, 0, 69, 251, 153, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 106, 255, 90, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 196, 233, 13, 0, 0, 0, 0, + 0, 0, 0, 0, 56, 255, 115, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 219, 207, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 143, 255, 16, 0, 0, 0, + 0, 0, 0, 0, 0, 109, 255, 52, 0, 0, 0, + 0, 0, 0, 0, 0, 87, 255, 62, 0, 0, 0, + 0, 0, 0, 0, 0, 105, 255, 40, 0, 0, 0, + 0, 0, 0, 0, 0, 137, 253, 11, 0, 0, 0, + 0, 0, 0, 0, 0, 212, 201, 0, 0, 0, 0, + 0, 0, 0, 0, 48, 255, 108, 0, 0, 0, 0, + 0, 0, 0, 0, 189, 229, 9, 0, 0, 0, 0, + 0, 0, 0, 98, 255, 82, 0, 0, 0, 0, 0, + 0, 0, 63, 249, 145, 0, 0, 0, 0, 0, 0, + 0, 0, 82, 162, 2, 0, 0, 0, 0, 0, 0, + }, + /* '0x2a' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 163, 137, 0, 0, 0, 0, 0, + 0, 58, 169, 17, 144, 117, 27, 184, 36, 0, 0, + 0, 34, 167, 226, 182, 173, 235, 165, 30, 0, 0, + 0, 0, 0, 89, 253, 247, 69, 0, 0, 0, 0, + 0, 31, 161, 228, 189, 180, 233, 146, 23, 0, 0, + 0, 67, 169, 18, 146, 118, 30, 186, 37, 0, 0, + 0, 0, 0, 0, 163, 138, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* '0x2b' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 208, 180, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 208, 180, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 208, 180, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 208, 180, 0, 0, 0, 0, 0, + 68, 255, 255, 255, 255, 255, 255, 255, 255, 40, 0, + 0, 0, 0, 0, 208, 180, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 208, 180, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 208, 180, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 208, 180, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* '0x2c' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 42, 231, 182, 2, 0, 0, 0, 0, + 0, 0, 0, 86, 255, 255, 62, 0, 0, 0, 0, + 0, 0, 0, 7, 221, 255, 79, 0, 0, 0, 0, + 0, 0, 0, 0, 168, 252, 27, 0, 0, 0, 0, + 0, 0, 9, 83, 243, 138, 0, 0, 0, 0, 0, + 0, 0, 223, 207, 101, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* '0x2d' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 172, 255, 255, 255, 255, 148, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* '0x2e' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 48, 227, 200, 13, 0, 0, 0, 0, + 0, 0, 0, 136, 255, 255, 73, 0, 0, 0, 0, + 0, 0, 0, 51, 230, 204, 14, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* '0x2f' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 40, 255, 76, 0, 0, + 0, 0, 0, 0, 0, 0, 142, 226, 3, 0, 0, + 0, 0, 0, 0, 0, 8, 237, 126, 0, 0, 0, + 0, 0, 0, 0, 0, 92, 252, 27, 0, 0, 0, + 0, 0, 0, 0, 0, 195, 176, 0, 0, 0, 0, + 0, 0, 0, 0, 42, 255, 73, 0, 0, 0, 0, + 0, 0, 0, 0, 145, 224, 2, 0, 0, 0, 0, + 0, 0, 0, 9, 238, 123, 0, 0, 0, 0, 0, + 0, 0, 0, 95, 251, 25, 0, 0, 0, 0, 0, + 0, 0, 0, 198, 173, 0, 0, 0, 0, 0, 0, + 0, 0, 45, 255, 70, 0, 0, 0, 0, 0, 0, + 0, 0, 148, 222, 1, 0, 0, 0, 0, 0, 0, + 0, 10, 240, 120, 0, 0, 0, 0, 0, 0, 0, + 0, 98, 250, 23, 0, 0, 0, 0, 0, 0, 0, + 0, 201, 171, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* '0' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 44, 179, 241, 244, 186, 49, 0, 0, 0, + 0, 38, 240, 156, 20, 30, 178, 242, 35, 0, 0, + 0, 172, 220, 3, 0, 0, 13, 241, 160, 0, 0, + 5, 248, 138, 0, 0, 0, 104, 250, 234, 0, 0, + 39, 255, 97, 0, 4, 149, 202, 147, 255, 16, 0, + 52, 255, 85, 19, 190, 164, 8, 112, 255, 28, 0, + 42, 255, 129, 218, 120, 0, 0, 131, 255, 15, 0, + 9, 252, 242, 77, 0, 0, 0, 162, 230, 0, 0, + 0, 189, 214, 2, 0, 0, 10, 235, 148, 0, 0, + 0, 58, 250, 150, 20, 25, 173, 231, 25, 0, 0, + 0, 0, 65, 198, 247, 239, 173, 35, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* '1' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 67, 206, 255, 52, 0, 0, 0, 0, + 0, 45, 183, 184, 151, 255, 52, 0, 0, 0, 0, + 0, 130, 117, 1, 128, 255, 52, 0, 0, 0, 0, + 0, 0, 0, 0, 128, 255, 52, 0, 0, 0, 0, + 0, 0, 0, 0, 128, 255, 52, 0, 0, 0, 0, + 0, 0, 0, 0, 128, 255, 52, 0, 0, 0, 0, + 0, 0, 0, 0, 128, 255, 52, 0, 0, 0, 0, + 0, 0, 0, 0, 128, 255, 52, 0, 0, 0, 0, + 0, 0, 0, 0, 128, 255, 52, 0, 0, 0, 0, + 0, 0, 0, 0, 128, 255, 52, 0, 0, 0, 0, + 0, 116, 255, 255, 255, 255, 255, 255, 196, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* '2' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 6, 119, 215, 248, 225, 148, 16, 0, 0, 0, + 0, 77, 196, 56, 8, 65, 237, 182, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 139, 255, 27, 0, 0, + 0, 0, 0, 0, 0, 0, 113, 255, 51, 0, 0, + 0, 0, 0, 0, 0, 0, 179, 246, 13, 0, 0, + 0, 0, 0, 0, 0, 94, 255, 140, 0, 0, 0, + 0, 0, 0, 0, 74, 250, 201, 7, 0, 0, 0, + 0, 0, 0, 67, 247, 204, 17, 0, 0, 0, 0, + 0, 0, 59, 244, 198, 15, 0, 0, 0, 0, 0, + 0, 52, 241, 192, 12, 0, 0, 0, 0, 0, 0, + 0, 179, 255, 255, 255, 255, 255, 255, 220, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* '3' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 64, 255, 255, 250, 222, 146, 19, 0, 0, 0, + 0, 0, 0, 0, 8, 66, 238, 185, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 148, 253, 10, 0, 0, + 0, 0, 0, 0, 0, 0, 165, 242, 2, 0, 0, + 0, 0, 0, 0, 12, 94, 250, 103, 0, 0, 0, + 0, 0, 40, 255, 255, 255, 187, 36, 0, 0, 0, + 0, 0, 0, 0, 8, 49, 179, 246, 49, 0, 0, + 0, 0, 0, 0, 0, 0, 13, 253, 146, 0, 0, + 0, 0, 0, 0, 0, 0, 31, 255, 127, 0, 0, + 0, 0, 0, 0, 10, 64, 202, 221, 20, 0, 0, + 0, 144, 255, 255, 244, 208, 131, 17, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* '4' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 23, 239, 255, 120, 0, 0, 0, + 0, 0, 0, 0, 164, 234, 255, 120, 0, 0, 0, + 0, 0, 0, 65, 255, 96, 255, 120, 0, 0, 0, + 0, 0, 6, 215, 170, 24, 255, 120, 0, 0, 0, + 0, 0, 123, 242, 27, 24, 255, 120, 0, 0, 0, + 0, 33, 246, 112, 0, 24, 255, 120, 0, 0, 0, + 0, 180, 207, 3, 0, 24, 255, 120, 0, 0, 0, + 82, 254, 56, 0, 0, 24, 255, 120, 0, 0, 0, + 160, 255, 255, 255, 255, 255, 255, 255, 255, 112, 0, + 0, 0, 0, 0, 0, 24, 255, 120, 0, 0, 0, + 0, 0, 0, 0, 0, 24, 255, 120, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* '5' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 60, 255, 255, 255, 255, 255, 244, 0, 0, 0, + 0, 60, 255, 52, 0, 0, 0, 0, 0, 0, 0, + 0, 60, 255, 52, 0, 0, 0, 0, 0, 0, 0, + 0, 60, 255, 52, 0, 0, 0, 0, 0, 0, 0, + 0, 60, 255, 255, 247, 222, 150, 36, 0, 0, 0, + 0, 0, 0, 0, 16, 68, 215, 238, 28, 0, 0, + 0, 0, 0, 0, 0, 0, 63, 255, 118, 0, 0, + 0, 0, 0, 0, 0, 0, 34, 255, 133, 0, 0, + 0, 0, 0, 0, 0, 0, 102, 255, 71, 0, 0, + 0, 0, 0, 0, 23, 100, 241, 158, 0, 0, 0, + 0, 112, 255, 255, 241, 189, 75, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* '6' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 42, 151, 223, 249, 255, 28, 0, 0, + 0, 0, 88, 245, 148, 40, 6, 0, 0, 0, 0, + 0, 32, 248, 112, 0, 0, 0, 0, 0, 0, 0, + 0, 137, 236, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 198, 190, 121, 222, 247, 214, 116, 3, 0, 0, + 0, 224, 245, 121, 27, 15, 105, 255, 122, 0, 0, + 0, 231, 172, 0, 0, 0, 0, 191, 221, 0, 0, + 0, 210, 193, 0, 0, 0, 0, 161, 247, 0, 0, + 0, 153, 243, 10, 0, 0, 0, 208, 198, 0, 0, + 0, 40, 247, 168, 27, 18, 134, 251, 53, 0, 0, + 0, 0, 59, 194, 246, 244, 186, 49, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* '7' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 248, 255, 255, 255, 255, 255, 255, 204, 0, 0, + 0, 0, 0, 0, 0, 0, 18, 242, 141, 0, 0, + 0, 0, 0, 0, 0, 0, 133, 248, 26, 0, 0, + 0, 0, 0, 0, 0, 18, 242, 151, 0, 0, 0, + 0, 0, 0, 0, 0, 133, 251, 33, 0, 0, 0, + 0, 0, 0, 0, 18, 242, 161, 0, 0, 0, 0, + 0, 0, 0, 0, 133, 253, 40, 0, 0, 0, 0, + 0, 0, 0, 18, 242, 170, 0, 0, 0, 0, 0, + 0, 0, 0, 133, 255, 48, 0, 0, 0, 0, 0, + 0, 0, 18, 242, 180, 0, 0, 0, 0, 0, 0, + 0, 0, 132, 255, 57, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* '8' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 74, 194, 237, 240, 201, 89, 0, 0, 0, + 0, 71, 254, 113, 14, 18, 136, 255, 72, 0, 0, + 0, 162, 232, 0, 0, 0, 5, 252, 142, 0, 0, + 0, 143, 251, 35, 0, 0, 46, 255, 107, 0, 0, + 0, 27, 223, 229, 79, 63, 225, 189, 8, 0, 0, + 0, 0, 26, 225, 255, 255, 212, 17, 0, 0, 0, + 0, 38, 221, 205, 51, 88, 230, 224, 36, 0, 0, + 0, 188, 231, 12, 0, 0, 31, 246, 173, 0, 0, + 0, 231, 196, 0, 0, 0, 0, 219, 209, 0, 0, + 0, 158, 252, 100, 14, 16, 114, 254, 113, 0, 0, + 0, 8, 127, 214, 244, 239, 199, 93, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* '9' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 64, 196, 247, 239, 170, 31, 0, 0, 0, + 0, 83, 254, 111, 15, 39, 191, 223, 12, 0, 0, + 2, 230, 180, 0, 0, 0, 37, 255, 106, 0, 0, + 24, 255, 133, 0, 0, 0, 0, 228, 171, 0, 0, + 4, 249, 160, 0, 0, 0, 0, 205, 196, 0, 0, + 0, 154, 247, 81, 11, 34, 136, 251, 194, 0, 0, + 0, 9, 135, 220, 249, 216, 106, 216, 169, 0, 0, + 0, 0, 0, 0, 0, 0, 11, 248, 108, 0, 0, + 0, 0, 0, 0, 0, 0, 125, 236, 15, 0, 0, + 0, 0, 0, 12, 54, 154, 238, 64, 0, 0, 0, + 0, 108, 254, 241, 207, 138, 28, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* '0x3a' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 23, 216, 200, 10, 0, 0, 0, 0, + 0, 0, 0, 89, 255, 255, 63, 0, 0, 0, 0, + 0, 0, 0, 25, 218, 203, 11, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 23, 216, 200, 10, 0, 0, 0, 0, + 0, 0, 0, 89, 255, 255, 63, 0, 0, 0, 0, + 0, 0, 0, 25, 218, 203, 11, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* '0x3b' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 23, 216, 200, 10, 0, 0, 0, 0, + 0, 0, 0, 89, 255, 255, 63, 0, 0, 0, 0, + 0, 0, 0, 25, 218, 203, 11, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 26, 224, 198, 10, 0, 0, 0, 0, + 0, 0, 0, 62, 255, 255, 86, 0, 0, 0, 0, + 0, 0, 0, 1, 199, 255, 103, 0, 0, 0, 0, + 0, 0, 0, 0, 141, 255, 47, 0, 0, 0, 0, + 0, 0, 7, 70, 234, 162, 0, 0, 0, 0, 0, + 0, 0, 197, 213, 115, 3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* '0x3c' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 123, 149, 0, 0, 0, + 0, 0, 0, 0, 6, 162, 253, 117, 0, 0, 0, + 0, 0, 0, 20, 195, 243, 77, 0, 0, 0, 0, + 0, 0, 41, 221, 224, 45, 0, 0, 0, 0, 0, + 0, 68, 239, 198, 22, 0, 0, 0, 0, 0, 0, + 0, 69, 240, 202, 25, 0, 0, 0, 0, 0, 0, + 0, 0, 41, 221, 227, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 20, 195, 244, 79, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 162, 253, 117, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 124, 150, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* '0x3d' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 212, 255, 255, 255, 255, 255, 255, 188, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 212, 255, 255, 255, 255, 255, 255, 188, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* '0x3e' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 167, 102, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 138, 255, 141, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 98, 250, 177, 11, 0, 0, 0, 0, + 0, 0, 0, 0, 63, 237, 206, 27, 0, 0, 0, + 0, 0, 0, 0, 0, 36, 216, 229, 51, 0, 0, + 0, 0, 0, 0, 0, 32, 211, 229, 51, 0, 0, + 0, 0, 0, 0, 59, 234, 207, 28, 0, 0, 0, + 0, 0, 0, 95, 249, 178, 11, 0, 0, 0, 0, + 0, 2, 136, 255, 142, 2, 0, 0, 0, 0, 0, + 0, 3, 167, 103, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* '0x3f' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 87, 239, 204, 120, 11, 0, 0, 0, 0, + 0, 0, 0, 25, 90, 226, 219, 26, 0, 0, 0, + 0, 0, 0, 0, 0, 40, 245, 181, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 170, 254, 10, 0, 0, + 0, 0, 0, 0, 0, 0, 153, 253, 8, 0, 0, + 0, 0, 0, 0, 2, 47, 229, 185, 0, 0, 0, + 0, 0, 0, 117, 255, 231, 159, 22, 0, 0, 0, + 0, 0, 0, 110, 255, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 103, 251, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 96, 246, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 157, 239, 57, 0, 0, 0, 0, 0, + 0, 0, 0, 160, 239, 59, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* '0x40' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 63, 195, 247, 227, 126, 3, 0, 0, + 0, 0, 88, 239, 93, 10, 50, 216, 146, 0, 0, + 0, 35, 246, 79, 0, 0, 0, 52, 252, 30, 0, + 0, 156, 179, 0, 0, 0, 0, 0, 215, 106, 0, + 16, 245, 71, 0, 0, 0, 0, 0, 163, 155, 0, + 85, 236, 3, 25, 188, 244, 214, 118, 136, 184, 0, + 142, 183, 0, 182, 168, 43, 255, 87, 124, 196, 0, + 189, 135, 31, 255, 55, 53, 255, 51, 122, 193, 0, + 208, 112, 93, 252, 5, 87, 255, 15, 132, 179, 0, + 224, 96, 126, 231, 0, 121, 234, 0, 156, 150, 0, + 226, 92, 130, 226, 0, 159, 205, 0, 199, 99, 0, + 212, 105, 101, 245, 38, 229, 217, 45, 243, 21, 0, + 180, 139, 18, 205, 232, 70, 210, 237, 92, 0, 0, + 126, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 41, 254, 55, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 152, 226, 66, 8, 39, 125, 102, 0, 0, 0, + 0, 4, 124, 222, 249, 225, 161, 41, 0, 0, 0, + }, + /* 'A' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 69, 246, 255, 55, 0, 0, 0, 0, + 0, 0, 0, 157, 165, 214, 143, 0, 0, 0, 0, + 0, 0, 6, 239, 87, 135, 228, 1, 0, 0, 0, + 0, 0, 79, 250, 15, 56, 255, 62, 0, 0, 0, + 0, 0, 167, 187, 0, 1, 231, 150, 0, 0, 0, + 0, 11, 244, 109, 0, 0, 154, 234, 3, 0, 0, + 0, 89, 255, 31, 0, 0, 75, 255, 69, 0, 0, + 0, 178, 255, 255, 255, 255, 255, 255, 157, 0, 0, + 16, 249, 97, 0, 0, 0, 0, 146, 238, 5, 0, + 99, 255, 29, 0, 0, 0, 0, 76, 255, 76, 0, + 188, 217, 0, 0, 0, 0, 0, 12, 250, 164, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'B' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 156, 255, 255, 254, 233, 189, 69, 0, 0, 0, + 0, 156, 244, 0, 3, 37, 178, 250, 46, 0, 0, + 0, 156, 244, 0, 0, 0, 44, 255, 115, 0, 0, + 0, 156, 244, 0, 0, 0, 59, 255, 102, 0, 0, + 0, 156, 244, 0, 3, 45, 201, 214, 14, 0, 0, + 0, 156, 255, 255, 255, 255, 241, 90, 0, 0, 0, + 0, 156, 244, 0, 3, 34, 146, 255, 123, 0, 0, + 0, 156, 244, 0, 0, 0, 0, 213, 222, 0, 0, + 0, 156, 244, 0, 0, 0, 0, 216, 213, 0, 0, + 0, 156, 244, 0, 1, 26, 132, 254, 93, 0, 0, + 0, 156, 255, 255, 251, 226, 175, 63, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'C' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 110, 205, 245, 231, 177, 49, 0, 0, + 0, 3, 183, 236, 92, 14, 12, 82, 151, 0, 0, + 0, 116, 255, 69, 0, 0, 0, 0, 0, 0, 0, + 0, 222, 203, 0, 0, 0, 0, 0, 0, 0, 0, + 23, 255, 153, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 255, 125, 0, 0, 0, 0, 0, 0, 0, 0, + 34, 255, 136, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 243, 186, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 160, 251, 42, 0, 0, 0, 0, 0, 0, 0, + 0, 23, 223, 225, 79, 12, 12, 83, 151, 0, 0, + 0, 0, 20, 141, 219, 249, 228, 165, 38, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'D' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 12, 255, 255, 255, 245, 214, 141, 23, 0, 0, 0, + 12, 255, 132, 0, 24, 69, 204, 230, 31, 0, 0, + 12, 255, 132, 0, 0, 0, 19, 238, 175, 0, 0, + 12, 255, 132, 0, 0, 0, 0, 158, 252, 10, 0, + 12, 255, 132, 0, 0, 0, 0, 115, 255, 48, 0, + 12, 255, 132, 0, 0, 0, 0, 103, 255, 58, 0, + 12, 255, 132, 0, 0, 0, 0, 118, 255, 39, 0, + 12, 255, 132, 0, 0, 0, 0, 171, 237, 3, 0, + 12, 255, 132, 0, 0, 0, 40, 249, 137, 0, 0, + 12, 255, 132, 0, 19, 90, 229, 190, 10, 0, 0, + 12, 255, 255, 251, 230, 191, 99, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'E' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 60, 255, 255, 255, 255, 255, 255, 76, 0, 0, + 0, 60, 255, 84, 0, 0, 0, 0, 0, 0, 0, + 0, 60, 255, 84, 0, 0, 0, 0, 0, 0, 0, + 0, 60, 255, 84, 0, 0, 0, 0, 0, 0, 0, + 0, 60, 255, 84, 0, 0, 0, 0, 0, 0, 0, + 0, 60, 255, 255, 255, 255, 255, 255, 28, 0, 0, + 0, 60, 255, 84, 0, 0, 0, 0, 0, 0, 0, + 0, 60, 255, 84, 0, 0, 0, 0, 0, 0, 0, + 0, 60, 255, 84, 0, 0, 0, 0, 0, 0, 0, + 0, 60, 255, 84, 0, 0, 0, 0, 0, 0, 0, + 0, 60, 255, 255, 255, 255, 255, 255, 76, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'F' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 52, 255, 255, 255, 255, 255, 255, 72, 0, 0, + 0, 52, 255, 104, 0, 0, 0, 0, 0, 0, 0, + 0, 52, 255, 104, 0, 0, 0, 0, 0, 0, 0, + 0, 52, 255, 104, 0, 0, 0, 0, 0, 0, 0, + 0, 52, 255, 104, 0, 0, 0, 0, 0, 0, 0, + 0, 52, 255, 255, 255, 255, 255, 255, 8, 0, 0, + 0, 52, 255, 104, 0, 0, 0, 0, 0, 0, 0, + 0, 52, 255, 104, 0, 0, 0, 0, 0, 0, 0, + 0, 52, 255, 104, 0, 0, 0, 0, 0, 0, 0, + 0, 52, 255, 104, 0, 0, 0, 0, 0, 0, 0, + 0, 52, 255, 104, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'G' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 9, 116, 204, 244, 235, 183, 60, 0, 0, + 0, 16, 205, 225, 84, 14, 11, 75, 165, 0, 0, + 0, 163, 241, 31, 0, 0, 0, 0, 0, 0, 0, + 24, 253, 141, 0, 0, 0, 0, 0, 0, 0, 0, + 82, 255, 90, 0, 0, 0, 0, 0, 0, 0, 0, + 103, 255, 63, 0, 0, 255, 255, 255, 228, 0, 0, + 91, 255, 82, 0, 0, 0, 0, 168, 228, 0, 0, + 44, 255, 126, 0, 0, 0, 0, 168, 228, 0, 0, + 0, 205, 230, 9, 0, 0, 0, 168, 228, 0, 0, + 0, 47, 239, 196, 58, 8, 13, 184, 228, 0, 0, + 0, 0, 33, 156, 225, 251, 243, 203, 119, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'H' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 255, 140, 0, 0, 0, 0, 164, 240, 0, 0, + 8, 255, 140, 0, 0, 0, 0, 164, 240, 0, 0, + 8, 255, 140, 0, 0, 0, 0, 164, 240, 0, 0, + 8, 255, 140, 0, 0, 0, 0, 164, 240, 0, 0, + 8, 255, 140, 0, 0, 0, 0, 164, 240, 0, 0, + 8, 255, 255, 255, 255, 255, 255, 255, 240, 0, 0, + 8, 255, 140, 0, 0, 0, 0, 164, 240, 0, 0, + 8, 255, 140, 0, 0, 0, 0, 164, 240, 0, 0, + 8, 255, 140, 0, 0, 0, 0, 164, 240, 0, 0, + 8, 255, 140, 0, 0, 0, 0, 164, 240, 0, 0, + 8, 255, 140, 0, 0, 0, 0, 164, 240, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'I' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 124, 255, 255, 255, 255, 255, 255, 100, 0, 0, + 0, 0, 0, 0, 216, 188, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 216, 188, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 216, 188, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 216, 188, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 216, 188, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 216, 188, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 216, 188, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 216, 188, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 216, 188, 0, 0, 0, 0, 0, + 0, 124, 255, 255, 255, 255, 255, 255, 100, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'J' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 64, 255, 255, 255, 255, 255, 180, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 224, 180, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 224, 180, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 224, 180, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 224, 180, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 224, 180, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 224, 180, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 225, 175, 0, 0, 0, + 0, 0, 0, 0, 0, 7, 249, 139, 0, 0, 0, + 0, 90, 115, 21, 17, 150, 247, 36, 0, 0, 0, + 0, 17, 153, 235, 247, 196, 52, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'K' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 160, 240, 0, 0, 0, 63, 252, 149, 0, 0, + 0, 160, 240, 0, 0, 21, 229, 188, 4, 0, 0, + 0, 160, 240, 0, 1, 185, 219, 18, 0, 0, 0, + 0, 160, 240, 0, 124, 240, 40, 0, 0, 0, 0, + 0, 160, 240, 63, 249, 72, 0, 0, 0, 0, 0, + 0, 160, 241, 219, 174, 0, 0, 0, 0, 0, 0, + 0, 160, 240, 91, 254, 90, 0, 0, 0, 0, 0, + 0, 160, 240, 0, 143, 248, 60, 0, 0, 0, 0, + 0, 160, 240, 0, 4, 190, 235, 35, 0, 0, 0, + 0, 160, 240, 0, 0, 21, 225, 216, 17, 0, 0, + 0, 160, 240, 0, 0, 0, 51, 247, 191, 6, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'L' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 244, 164, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 244, 164, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 244, 164, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 244, 164, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 244, 164, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 244, 164, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 244, 164, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 244, 164, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 244, 164, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 244, 164, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 244, 255, 255, 255, 255, 255, 168, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'M' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 6, 255, 246, 13, 0, 0, 47, 255, 238, 0, 0, + 20, 255, 236, 95, 0, 0, 143, 232, 251, 0, 0, + 33, 255, 132, 186, 0, 4, 229, 110, 255, 8, 0, + 46, 255, 38, 242, 23, 77, 178, 72, 255, 21, 0, + 59, 255, 18, 164, 110, 170, 81, 64, 255, 34, 0, + 72, 255, 11, 68, 204, 223, 5, 57, 255, 47, 0, + 85, 255, 5, 2, 225, 144, 0, 50, 255, 60, 0, + 98, 254, 0, 0, 0, 0, 0, 42, 255, 73, 0, + 111, 248, 0, 0, 0, 0, 0, 35, 255, 86, 0, + 124, 241, 0, 0, 0, 0, 0, 27, 255, 99, 0, + 137, 235, 0, 0, 0, 0, 0, 20, 255, 113, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'N' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 244, 255, 72, 0, 0, 0, 152, 220, 0, 0, + 0, 244, 206, 185, 0, 0, 0, 152, 220, 0, 0, + 0, 244, 131, 227, 43, 0, 0, 152, 220, 0, 0, + 0, 244, 128, 128, 156, 0, 0, 152, 220, 0, 0, + 0, 244, 128, 23, 240, 21, 0, 152, 220, 0, 0, + 0, 244, 128, 0, 158, 126, 0, 152, 220, 0, 0, + 0, 244, 128, 0, 44, 231, 7, 152, 220, 0, 0, + 0, 244, 128, 0, 0, 186, 95, 152, 220, 0, 0, + 0, 244, 128, 0, 0, 73, 201, 152, 220, 0, 0, + 0, 244, 128, 0, 0, 1, 213, 202, 220, 0, 0, + 0, 244, 128, 0, 0, 0, 101, 255, 220, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'O' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 58, 185, 243, 244, 196, 72, 0, 0, 0, + 0, 71, 250, 136, 17, 21, 145, 254, 82, 0, 0, + 3, 222, 190, 0, 0, 0, 0, 205, 226, 2, 0, + 61, 255, 96, 0, 0, 0, 0, 117, 255, 50, 0, + 109, 255, 53, 0, 0, 0, 0, 79, 255, 89, 0, + 124, 255, 37, 0, 0, 0, 0, 62, 255, 99, 0, + 113, 255, 54, 0, 0, 0, 0, 81, 255, 83, 0, + 75, 255, 91, 0, 0, 0, 0, 124, 255, 33, 0, + 11, 242, 180, 0, 0, 0, 5, 216, 197, 0, 0, + 0, 109, 255, 124, 15, 22, 166, 243, 47, 0, 0, + 0, 0, 92, 205, 247, 239, 175, 44, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'P' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 156, 255, 255, 253, 230, 179, 66, 0, 0, 0, + 0, 156, 244, 0, 3, 37, 167, 252, 78, 0, 0, + 0, 156, 244, 0, 0, 0, 4, 227, 207, 0, 0, + 0, 156, 244, 0, 0, 0, 0, 191, 232, 0, 0, + 0, 156, 244, 0, 0, 0, 7, 231, 181, 0, 0, + 0, 156, 244, 0, 5, 42, 173, 242, 46, 0, 0, + 0, 156, 255, 255, 252, 230, 162, 37, 0, 0, 0, + 0, 156, 244, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 156, 244, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 156, 244, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 156, 244, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'Q' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 54, 182, 242, 244, 196, 72, 0, 0, 0, + 0, 65, 249, 136, 17, 22, 148, 254, 82, 0, 0, + 1, 218, 190, 0, 0, 0, 0, 206, 226, 2, 0, + 57, 255, 94, 0, 0, 0, 0, 117, 255, 51, 0, + 106, 255, 53, 0, 0, 0, 0, 79, 255, 90, 0, + 122, 255, 37, 0, 0, 0, 0, 62, 255, 99, 0, + 105, 255, 54, 0, 0, 0, 0, 80, 255, 84, 0, + 75, 255, 92, 0, 0, 0, 0, 123, 255, 37, 0, + 9, 238, 180, 0, 0, 0, 4, 215, 203, 0, 0, + 0, 121, 255, 124, 15, 22, 165, 247, 55, 0, 0, + 0, 0, 105, 218, 255, 250, 186, 52, 0, 0, 0, + 0, 0, 0, 0, 198, 178, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 106, 253, 88, 13, 92, 133, 0, + 0, 0, 0, 0, 0, 116, 220, 245, 204, 77, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'R' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 128, 255, 255, 254, 237, 178, 46, 0, 0, 0, + 0, 128, 255, 16, 3, 47, 209, 231, 18, 0, 0, + 0, 128, 255, 16, 0, 0, 87, 255, 77, 0, 0, + 0, 128, 255, 16, 0, 0, 98, 255, 68, 0, 0, + 0, 128, 255, 16, 7, 62, 225, 203, 3, 0, 0, + 0, 128, 255, 255, 255, 254, 138, 12, 0, 0, 0, + 0, 128, 255, 16, 36, 210, 226, 27, 0, 0, 0, + 0, 128, 255, 16, 0, 55, 255, 165, 0, 0, 0, + 0, 128, 255, 16, 0, 0, 186, 251, 29, 0, 0, + 0, 128, 255, 16, 0, 0, 64, 255, 141, 0, 0, + 0, 128, 255, 16, 0, 0, 0, 197, 242, 15, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'S' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 78, 189, 240, 248, 194, 77, 0, 0, 0, + 0, 97, 255, 123, 24, 7, 58, 183, 7, 0, 0, + 0, 201, 211, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 196, 243, 31, 0, 0, 0, 0, 0, 0, 0, + 0, 68, 248, 239, 133, 33, 0, 0, 0, 0, 0, + 0, 0, 38, 162, 248, 254, 181, 46, 0, 0, 0, + 0, 0, 0, 0, 16, 110, 232, 249, 59, 0, 0, + 0, 0, 0, 0, 0, 0, 28, 246, 178, 0, 0, + 0, 0, 0, 0, 0, 0, 3, 244, 174, 0, 0, + 7, 187, 70, 15, 6, 35, 160, 251, 66, 0, 0, + 0, 77, 182, 238, 247, 223, 164, 54, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'T' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 64, 255, 255, 255, 255, 255, 255, 255, 255, 36, 0, + 0, 0, 0, 0, 216, 188, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 216, 188, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 216, 188, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 216, 188, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 216, 188, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 216, 188, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 216, 188, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 216, 188, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 216, 188, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 216, 188, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'U' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 12, 255, 132, 0, 0, 0, 0, 156, 244, 0, 0, + 12, 255, 132, 0, 0, 0, 0, 156, 244, 0, 0, + 12, 255, 132, 0, 0, 0, 0, 156, 244, 0, 0, + 12, 255, 132, 0, 0, 0, 0, 156, 244, 0, 0, + 12, 255, 132, 0, 0, 0, 0, 156, 244, 0, 0, + 12, 255, 132, 0, 0, 0, 0, 156, 244, 0, 0, + 12, 255, 132, 0, 0, 0, 0, 156, 244, 0, 0, + 5, 253, 137, 0, 0, 0, 0, 163, 235, 0, 0, + 0, 222, 175, 0, 0, 0, 0, 209, 186, 0, 0, + 0, 109, 253, 100, 17, 21, 130, 251, 62, 0, 0, + 0, 1, 111, 213, 249, 243, 186, 49, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'V' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 204, 239, 6, 0, 0, 0, 0, 8, 242, 174, 0, + 115, 255, 76, 0, 0, 0, 0, 81, 255, 83, 0, + 28, 254, 162, 0, 0, 0, 0, 167, 240, 8, 0, + 0, 194, 240, 6, 0, 0, 8, 243, 157, 0, 0, + 0, 105, 255, 77, 0, 0, 82, 255, 66, 0, 0, + 0, 20, 251, 163, 0, 0, 168, 229, 2, 0, 0, + 0, 0, 183, 241, 7, 9, 243, 140, 0, 0, 0, + 0, 0, 95, 255, 77, 82, 255, 49, 0, 0, 0, + 0, 0, 14, 247, 160, 167, 214, 0, 0, 0, 0, + 0, 0, 0, 173, 238, 243, 123, 0, 0, 0, 0, + 0, 0, 0, 84, 255, 255, 33, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'W' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 147, 230, 0, 0, 0, 0, 0, 0, 235, 118, 0, + 128, 245, 0, 0, 0, 0, 0, 0, 248, 101, 0, + 110, 255, 3, 0, 0, 0, 0, 5, 255, 83, 0, + 91, 255, 17, 0, 0, 0, 0, 19, 255, 65, 0, + 73, 255, 31, 0, 197, 163, 0, 33, 255, 47, 0, + 54, 255, 45, 23, 237, 242, 8, 46, 255, 29, 0, + 36, 255, 59, 102, 153, 215, 82, 60, 255, 12, 0, + 17, 255, 73, 182, 75, 131, 170, 73, 249, 0, 0, + 1, 253, 109, 233, 6, 42, 245, 101, 232, 0, 0, + 0, 236, 230, 162, 0, 0, 209, 227, 214, 0, 0, + 0, 217, 255, 78, 0, 0, 120, 255, 196, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'X' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 55, 252, 175, 0, 0, 0, 1, 189, 241, 29, 0, + 0, 140, 255, 104, 0, 0, 108, 255, 101, 0, 0, + 0, 9, 218, 246, 43, 35, 245, 187, 0, 0, 0, + 0, 0, 60, 254, 210, 196, 242, 31, 0, 0, 0, + 0, 0, 0, 146, 255, 255, 104, 0, 0, 0, 0, + 0, 0, 0, 51, 255, 255, 45, 0, 0, 0, 0, + 0, 0, 3, 200, 247, 254, 200, 2, 0, 0, 0, + 0, 0, 122, 255, 111, 153, 255, 112, 0, 0, 0, + 0, 45, 249, 195, 2, 14, 226, 244, 32, 0, 0, + 5, 206, 246, 36, 0, 0, 72, 255, 184, 0, 0, + 129, 255, 113, 0, 0, 0, 0, 160, 255, 93, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'Y' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 180, 253, 47, 0, 0, 0, 0, 46, 253, 151, 0, + 36, 248, 190, 0, 0, 0, 0, 185, 237, 19, 0, + 0, 133, 255, 80, 0, 0, 72, 255, 105, 0, 0, + 0, 10, 226, 219, 6, 3, 211, 207, 2, 0, 0, + 0, 0, 85, 255, 110, 99, 255, 59, 0, 0, 0, + 0, 0, 0, 188, 233, 228, 163, 0, 0, 0, 0, + 0, 0, 0, 41, 250, 242, 25, 0, 0, 0, 0, + 0, 0, 0, 0, 216, 188, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 216, 188, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 216, 188, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 216, 188, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'Z' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 220, 255, 255, 255, 255, 255, 255, 167, 0, 0, + 0, 0, 0, 0, 0, 0, 110, 245, 30, 0, 0, + 0, 0, 0, 0, 0, 23, 240, 120, 0, 0, 0, + 0, 0, 0, 0, 0, 163, 216, 6, 0, 0, 0, + 0, 0, 0, 0, 62, 254, 67, 0, 0, 0, 0, + 0, 0, 0, 4, 211, 168, 0, 0, 0, 0, 0, + 0, 0, 0, 114, 243, 27, 0, 0, 0, 0, 0, + 0, 0, 26, 242, 114, 0, 0, 0, 0, 0, 0, + 0, 0, 168, 211, 4, 0, 0, 0, 0, 0, 0, + 0, 66, 254, 61, 0, 0, 0, 0, 0, 0, 0, + 1, 215, 255, 255, 255, 255, 255, 255, 232, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* '0x5b' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 248, 255, 255, 255, 92, 0, 0, 0, + 0, 0, 0, 248, 124, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 248, 124, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 248, 124, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 248, 124, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 248, 124, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 248, 124, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 248, 124, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 248, 124, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 248, 124, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 248, 124, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 248, 124, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 248, 124, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 248, 124, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 248, 124, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 248, 124, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 248, 255, 255, 255, 92, 0, 0, 0, + }, + /* '0x5c' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 101, 249, 21, 0, 0, 0, 0, 0, 0, 0, + 0, 12, 242, 117, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 151, 219, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 48, 255, 67, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 201, 170, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 98, 250, 23, 0, 0, 0, 0, 0, + 0, 0, 0, 10, 240, 120, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 148, 221, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 45, 255, 70, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 198, 173, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 95, 251, 25, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 239, 123, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 145, 224, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 42, 255, 73, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 195, 176, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* '0x5d' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 120, 255, 255, 255, 220, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 156, 220, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 156, 220, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 156, 220, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 156, 220, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 156, 220, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 156, 220, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 156, 220, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 156, 220, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 156, 220, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 156, 220, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 156, 220, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 156, 220, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 156, 220, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 156, 220, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 156, 220, 0, 0, 0, 0, + 0, 0, 120, 255, 255, 255, 220, 0, 0, 0, 0, + }, + /* '0x5e' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 15, 237, 205, 1, 0, 0, 0, 0, + 0, 0, 0, 134, 201, 244, 95, 0, 0, 0, 0, + 0, 0, 25, 245, 59, 129, 228, 10, 0, 0, 0, + 0, 0, 153, 185, 0, 13, 233, 127, 0, 0, 0, + 0, 38, 251, 55, 0, 0, 108, 244, 26, 0, 0, + 0, 171, 181, 0, 0, 0, 5, 220, 159, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* '0x5f' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 228, 0, + }, + /* '0x60' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 20, 176, 248, 78, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 103, 240, 91, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'a' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 81, 187, 241, 239, 191, 63, 0, 0, 0, + 0, 23, 181, 64, 9, 28, 182, 244, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 48, 255, 96, 0, 0, + 0, 0, 0, 0, 0, 0, 24, 255, 116, 0, 0, + 0, 1, 111, 208, 240, 255, 255, 255, 116, 0, 0, + 0, 122, 254, 100, 15, 0, 24, 255, 116, 0, 0, + 0, 197, 212, 0, 0, 0, 45, 255, 116, 0, 0, + 0, 163, 244, 52, 12, 95, 229, 253, 116, 0, 0, + 0, 24, 175, 239, 244, 184, 56, 239, 116, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'b' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 152, 240, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 152, 240, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 152, 240, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 152, 239, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 152, 231, 37, 179, 244, 233, 118, 0, 0, 0, + 0, 152, 239, 225, 102, 15, 114, 255, 73, 0, 0, + 0, 152, 255, 87, 0, 0, 0, 223, 176, 0, 0, + 0, 152, 240, 0, 0, 0, 0, 174, 218, 0, 0, + 0, 152, 240, 0, 0, 0, 0, 160, 237, 0, 0, + 0, 152, 240, 0, 0, 0, 0, 181, 213, 0, 0, + 0, 152, 240, 0, 0, 0, 13, 241, 139, 0, 0, + 0, 152, 246, 57, 9, 37, 186, 226, 21, 0, 0, + 0, 70, 180, 231, 250, 233, 159, 27, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'c' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 97, 205, 247, 224, 141, 7, 0, 0, + 0, 0, 128, 250, 117, 22, 33, 121, 61, 0, 0, + 0, 40, 250, 133, 0, 0, 0, 0, 0, 0, 0, + 0, 124, 255, 35, 0, 0, 0, 0, 0, 0, 0, + 0, 151, 255, 5, 0, 0, 0, 0, 0, 0, 0, + 0, 136, 255, 26, 0, 0, 0, 0, 0, 0, 0, + 0, 76, 255, 106, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 193, 241, 95, 19, 30, 127, 62, 0, 0, + 0, 0, 10, 135, 220, 249, 221, 132, 6, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'd' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 24, 255, 116, 0, 0, + 0, 0, 0, 0, 0, 0, 24, 255, 116, 0, 0, + 0, 0, 0, 0, 0, 0, 24, 255, 116, 0, 0, + 0, 0, 0, 0, 0, 0, 24, 255, 116, 0, 0, + 0, 0, 37, 168, 236, 249, 225, 255, 116, 0, 0, + 0, 35, 238, 169, 34, 11, 79, 255, 116, 0, 0, + 0, 166, 229, 6, 0, 0, 24, 255, 116, 0, 0, + 0, 239, 162, 0, 0, 0, 24, 255, 116, 0, 0, + 6, 255, 138, 0, 0, 0, 24, 255, 116, 0, 0, + 0, 245, 150, 0, 0, 0, 27, 255, 116, 0, 0, + 0, 205, 196, 0, 0, 0, 156, 255, 116, 0, 0, + 0, 102, 254, 90, 17, 142, 192, 247, 116, 0, 0, + 0, 0, 126, 238, 239, 153, 12, 239, 116, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'e' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 32, 169, 240, 245, 187, 43, 0, 0, 0, + 0, 17, 230, 177, 28, 31, 171, 246, 33, 0, 0, + 0, 138, 240, 15, 0, 0, 12, 240, 152, 0, 0, + 0, 221, 183, 0, 0, 0, 0, 200, 198, 0, 0, + 0, 241, 255, 255, 255, 255, 255, 255, 216, 0, 0, + 0, 215, 178, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 169, 233, 11, 0, 0, 0, 0, 0, 0, 0, + 0, 50, 249, 183, 46, 5, 0, 0, 0, 0, 0, + 0, 0, 54, 182, 238, 254, 255, 255, 100, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'f' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 43, 178, 231, 255, 255, 60, 0, + 0, 0, 0, 16, 230, 189, 32, 0, 0, 0, 0, + 0, 0, 0, 82, 255, 55, 0, 0, 0, 0, 0, + 0, 0, 0, 113, 255, 25, 0, 0, 0, 0, 0, + 0, 0, 0, 116, 255, 24, 0, 0, 0, 0, 0, + 76, 255, 255, 255, 255, 255, 255, 255, 248, 0, 0, + 0, 0, 0, 116, 255, 24, 0, 0, 0, 0, 0, + 0, 0, 0, 116, 255, 24, 0, 0, 0, 0, 0, + 0, 0, 0, 116, 255, 24, 0, 0, 0, 0, 0, + 0, 0, 0, 116, 255, 24, 0, 0, 0, 0, 0, + 0, 0, 0, 116, 255, 24, 0, 0, 0, 0, 0, + 0, 0, 0, 116, 255, 24, 0, 0, 0, 0, 0, + 0, 0, 0, 116, 255, 24, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'g' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 62, 194, 242, 255, 255, 255, 255, 44, 0, + 0, 44, 248, 153, 19, 42, 214, 238, 10, 0, 0, + 0, 132, 251, 9, 0, 0, 92, 255, 55, 0, 0, + 0, 146, 251, 8, 0, 0, 93, 255, 44, 0, 0, + 0, 54, 253, 150, 17, 42, 215, 203, 2, 0, 0, + 0, 82, 247, 197, 246, 230, 159, 24, 0, 0, 0, + 0, 194, 174, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 181, 222, 48, 20, 10, 0, 0, 0, 0, 0, + 0, 68, 255, 236, 234, 243, 244, 191, 55, 0, 0, + 4, 222, 206, 9, 0, 0, 24, 198, 238, 4, 0, + 34, 255, 126, 0, 0, 0, 0, 147, 255, 22, 0, + 3, 232, 212, 52, 8, 19, 90, 244, 175, 0, 0, + 0, 41, 170, 232, 252, 246, 210, 122, 7, 0, 0, + }, + /* 'h' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 152, 240, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 152, 240, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 152, 240, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 152, 240, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 152, 235, 36, 184, 247, 221, 94, 0, 0, 0, + 0, 152, 243, 222, 88, 12, 138, 252, 39, 0, 0, + 0, 152, 253, 75, 0, 0, 26, 255, 103, 0, 0, + 0, 152, 240, 0, 0, 0, 8, 255, 127, 0, 0, + 0, 152, 240, 0, 0, 0, 8, 255, 128, 0, 0, + 0, 152, 240, 0, 0, 0, 8, 255, 128, 0, 0, + 0, 152, 240, 0, 0, 0, 8, 255, 128, 0, 0, + 0, 152, 240, 0, 0, 0, 8, 255, 128, 0, 0, + 0, 152, 240, 0, 0, 0, 8, 255, 128, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'i' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 24, 223, 211, 11, 0, 0, 0, 0, + 0, 0, 0, 24, 224, 211, 11, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 52, 255, 255, 255, 244, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 152, 244, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 152, 244, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 152, 244, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 152, 244, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 152, 244, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 152, 244, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 152, 244, 0, 0, 0, 0, 0, + 0, 124, 255, 255, 255, 255, 255, 255, 152, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'j' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 123, 245, 104, 0, 0, 0, + 0, 0, 0, 0, 0, 124, 245, 105, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 124, 255, 255, 255, 255, 255, 100, 0, 0, 0, + 0, 0, 0, 0, 0, 40, 255, 100, 0, 0, 0, + 0, 0, 0, 0, 0, 40, 255, 100, 0, 0, 0, + 0, 0, 0, 0, 0, 40, 255, 100, 0, 0, 0, + 0, 0, 0, 0, 0, 40, 255, 100, 0, 0, 0, + 0, 0, 0, 0, 0, 40, 255, 100, 0, 0, 0, + 0, 0, 0, 0, 0, 40, 255, 100, 0, 0, 0, + 0, 0, 0, 0, 0, 40, 255, 100, 0, 0, 0, + 0, 0, 0, 0, 0, 40, 255, 100, 0, 0, 0, + 0, 0, 0, 0, 0, 58, 255, 89, 0, 0, 0, + 0, 0, 0, 0, 0, 120, 255, 41, 0, 0, 0, + 0, 151, 59, 8, 66, 238, 164, 0, 0, 0, 0, + 0, 60, 203, 250, 228, 131, 7, 0, 0, 0, 0, + }, + /* 'k' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 104, 255, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 104, 255, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 104, 255, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 104, 255, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 104, 255, 32, 0, 0, 104, 254, 150, 1, 0, + 0, 104, 255, 32, 0, 103, 254, 143, 0, 0, 0, + 0, 104, 255, 32, 102, 254, 135, 0, 0, 0, 0, + 0, 104, 255, 133, 254, 128, 0, 0, 0, 0, 0, + 0, 104, 255, 159, 255, 100, 0, 0, 0, 0, 0, + 0, 104, 255, 33, 169, 251, 73, 0, 0, 0, 0, + 0, 104, 255, 32, 9, 203, 243, 50, 0, 0, 0, + 0, 104, 255, 32, 0, 26, 229, 230, 31, 0, 0, + 0, 104, 255, 32, 0, 0, 52, 246, 214, 17, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'l' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 52, 255, 255, 255, 244, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 152, 244, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 152, 244, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 152, 244, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 152, 244, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 152, 244, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 152, 244, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 152, 244, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 152, 244, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 152, 244, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 152, 244, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 152, 244, 0, 0, 0, 0, 0, + 0, 124, 255, 255, 255, 255, 255, 255, 152, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'm' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 52, 252, 53, 226, 222, 32, 164, 242, 124, 0, 0, + 52, 255, 202, 37, 219, 204, 137, 106, 246, 4, 0, + 52, 255, 127, 0, 193, 231, 9, 77, 255, 24, 0, + 52, 255, 52, 0, 192, 164, 0, 76, 255, 28, 0, + 52, 255, 52, 0, 192, 164, 0, 76, 255, 28, 0, + 52, 255, 52, 0, 192, 164, 0, 76, 255, 28, 0, + 52, 255, 52, 0, 192, 164, 0, 76, 255, 28, 0, + 52, 255, 52, 0, 192, 164, 0, 76, 255, 28, 0, + 52, 255, 52, 0, 192, 164, 0, 76, 255, 28, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'n' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 152, 201, 49, 191, 247, 222, 97, 0, 0, 0, + 0, 152, 238, 231, 80, 12, 136, 253, 41, 0, 0, + 0, 152, 253, 70, 0, 0, 26, 255, 104, 0, 0, + 0, 152, 240, 0, 0, 0, 8, 255, 127, 0, 0, + 0, 152, 240, 0, 0, 0, 8, 255, 128, 0, 0, + 0, 152, 240, 0, 0, 0, 8, 255, 128, 0, 0, + 0, 152, 240, 0, 0, 0, 8, 255, 128, 0, 0, + 0, 152, 240, 0, 0, 0, 8, 255, 128, 0, 0, + 0, 152, 240, 0, 0, 0, 8, 255, 128, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'o' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 54, 183, 242, 246, 194, 69, 0, 0, 0, + 0, 51, 248, 148, 17, 29, 157, 253, 71, 0, 0, + 0, 196, 204, 0, 0, 0, 3, 221, 198, 0, 0, + 21, 255, 124, 0, 0, 0, 0, 152, 252, 6, 0, + 43, 255, 102, 0, 0, 0, 0, 127, 255, 18, 0, + 28, 255, 124, 0, 0, 0, 0, 150, 247, 3, 0, + 0, 225, 196, 0, 0, 0, 3, 225, 177, 0, 0, + 0, 96, 255, 135, 23, 21, 163, 240, 43, 0, 0, + 0, 0, 87, 206, 248, 240, 176, 31, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'p' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 152, 203, 45, 185, 245, 232, 118, 0, 0, 0, + 0, 152, 238, 233, 102, 15, 114, 255, 73, 0, 0, + 0, 152, 255, 87, 0, 0, 0, 223, 176, 0, 0, + 0, 152, 240, 0, 0, 0, 0, 174, 218, 0, 0, + 0, 152, 240, 0, 0, 0, 0, 163, 237, 0, 0, + 0, 152, 240, 0, 0, 0, 0, 187, 215, 0, 0, + 0, 152, 240, 0, 0, 0, 19, 244, 143, 0, 0, + 0, 152, 246, 56, 9, 40, 187, 228, 23, 0, 0, + 0, 152, 254, 245, 254, 233, 159, 27, 0, 0, 0, + 0, 152, 240, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 152, 240, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 152, 240, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 152, 240, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'q' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 38, 171, 236, 248, 214, 202, 110, 0, 0, + 0, 36, 238, 169, 34, 11, 79, 255, 116, 0, 0, + 0, 165, 230, 6, 0, 0, 24, 255, 116, 0, 0, + 0, 227, 162, 0, 0, 0, 24, 255, 116, 0, 0, + 4, 254, 138, 0, 0, 0, 24, 255, 116, 0, 0, + 0, 245, 149, 0, 0, 0, 27, 255, 116, 0, 0, + 0, 205, 196, 0, 0, 0, 156, 255, 116, 0, 0, + 0, 105, 254, 91, 17, 142, 211, 255, 116, 0, 0, + 0, 2, 140, 239, 240, 158, 34, 255, 116, 0, 0, + 0, 0, 0, 0, 0, 0, 23, 255, 116, 0, 0, + 0, 0, 0, 0, 0, 0, 24, 255, 116, 0, 0, + 0, 0, 0, 0, 0, 0, 24, 255, 116, 0, 0, + 0, 0, 0, 0, 0, 0, 24, 255, 116, 0, 0, + }, + /* 'r' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 60, 255, 51, 129, 226, 244, 189, 36, 0, 0, + 0, 60, 255, 224, 169, 33, 30, 222, 191, 0, 0, + 0, 60, 255, 159, 0, 0, 0, 146, 246, 0, 0, + 0, 60, 255, 80, 0, 0, 0, 0, 0, 0, 0, + 0, 60, 255, 80, 0, 0, 0, 0, 0, 0, 0, + 0, 60, 255, 80, 0, 0, 0, 0, 0, 0, 0, + 0, 60, 255, 80, 0, 0, 0, 0, 0, 0, 0, + 0, 60, 255, 80, 0, 0, 0, 0, 0, 0, 0, + 0, 60, 255, 80, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 's' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 43, 176, 238, 243, 186, 57, 0, 0, 0, + 0, 14, 230, 174, 29, 14, 77, 154, 0, 0, 0, + 0, 58, 255, 89, 0, 0, 0, 0, 0, 0, 0, + 0, 14, 232, 234, 115, 29, 0, 0, 0, 0, 0, + 0, 0, 39, 175, 250, 254, 195, 60, 0, 0, 0, + 0, 0, 0, 0, 17, 99, 222, 249, 36, 0, 0, + 0, 0, 0, 0, 0, 0, 65, 255, 87, 0, 0, + 0, 93, 143, 49, 10, 26, 162, 244, 30, 0, 0, + 0, 13, 133, 211, 245, 237, 176, 49, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 't' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 176, 129, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 248, 140, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 248, 140, 0, 0, 0, 0, 0, 0, + 116, 255, 255, 255, 255, 255, 255, 255, 132, 0, 0, + 0, 0, 0, 248, 140, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 248, 140, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 248, 140, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 248, 140, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 247, 140, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 223, 161, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 150, 243, 67, 5, 0, 0, 0, 0, + 0, 0, 0, 14, 151, 228, 254, 255, 132, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'u' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 152, 240, 0, 0, 0, 8, 255, 128, 0, 0, + 0, 152, 240, 0, 0, 0, 8, 255, 128, 0, 0, + 0, 152, 240, 0, 0, 0, 8, 255, 128, 0, 0, + 0, 152, 240, 0, 0, 0, 8, 255, 128, 0, 0, + 0, 152, 240, 0, 0, 0, 8, 255, 128, 0, 0, + 0, 151, 240, 0, 0, 0, 8, 255, 128, 0, 0, + 0, 130, 252, 4, 0, 0, 92, 255, 128, 0, 0, + 0, 66, 255, 114, 10, 97, 229, 247, 128, 0, 0, + 0, 0, 122, 228, 247, 183, 38, 228, 128, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'v' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 59, 255, 125, 0, 0, 0, 0, 151, 249, 20, 0, + 0, 216, 210, 0, 0, 0, 2, 232, 172, 0, 0, + 0, 119, 255, 38, 0, 0, 63, 255, 74, 0, 0, + 0, 24, 251, 122, 0, 0, 147, 229, 3, 0, 0, + 0, 0, 178, 206, 0, 1, 229, 133, 0, 0, 0, + 0, 0, 80, 255, 34, 59, 255, 36, 0, 0, 0, + 0, 0, 4, 232, 117, 141, 193, 0, 0, 0, 0, + 0, 0, 0, 140, 194, 218, 95, 0, 0, 0, 0, + 0, 0, 0, 41, 253, 242, 10, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'w' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 155, 222, 0, 0, 0, 0, 0, 2, 251, 129, 0, + 119, 249, 1, 0, 0, 0, 0, 24, 255, 93, 0, + 83, 255, 25, 0, 195, 157, 0, 50, 255, 56, 0, + 47, 255, 54, 13, 243, 232, 1, 76, 255, 20, 0, + 11, 255, 84, 79, 176, 224, 55, 102, 239, 0, 0, + 0, 231, 113, 149, 105, 152, 132, 129, 203, 0, 0, + 0, 195, 146, 220, 32, 77, 213, 157, 166, 0, 0, + 0, 159, 240, 214, 0, 10, 247, 244, 130, 0, 0, + 0, 122, 255, 140, 0, 0, 182, 255, 94, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'x' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 210, 241, 29, 0, 0, 21, 235, 209, 8, 0, + 0, 42, 246, 183, 0, 0, 171, 244, 40, 0, 0, + 0, 0, 102, 255, 96, 87, 255, 95, 0, 0, 0, + 0, 0, 0, 171, 239, 235, 163, 0, 0, 0, 0, + 0, 0, 0, 44, 255, 255, 41, 0, 0, 0, 0, + 0, 0, 3, 195, 206, 218, 194, 3, 0, 0, 0, + 0, 0, 134, 252, 50, 65, 255, 131, 0, 0, 0, + 0, 70, 254, 139, 0, 0, 159, 253, 66, 0, 0, + 25, 234, 222, 10, 0, 0, 18, 234, 230, 22, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'y' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 58, 255, 127, 0, 0, 0, 0, 153, 248, 19, 0, + 0, 213, 215, 0, 0, 0, 5, 236, 165, 0, 0, + 0, 113, 255, 48, 0, 0, 76, 255, 62, 0, 0, + 0, 19, 249, 136, 0, 0, 165, 215, 0, 0, 0, + 0, 0, 168, 223, 0, 10, 244, 112, 0, 0, 0, + 0, 0, 68, 255, 56, 87, 247, 18, 0, 0, 0, + 0, 0, 1, 221, 150, 179, 163, 0, 0, 0, 0, + 0, 0, 0, 123, 248, 250, 62, 0, 0, 0, 0, + 0, 0, 0, 26, 252, 226, 1, 0, 0, 0, 0, + 0, 0, 0, 29, 252, 127, 0, 0, 0, 0, 0, + 0, 0, 0, 144, 242, 20, 0, 0, 0, 0, 0, + 0, 8, 101, 253, 99, 0, 0, 0, 0, 0, 0, + 124, 251, 214, 93, 0, 0, 0, 0, 0, 0, 0, + }, + /* 'z' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 112, 255, 255, 255, 255, 255, 253, 42, 0, 0, + 0, 0, 0, 0, 0, 10, 221, 145, 0, 0, 0, + 0, 0, 0, 0, 0, 141, 223, 11, 0, 0, 0, + 0, 0, 0, 0, 53, 252, 70, 0, 0, 0, 0, + 0, 0, 0, 5, 210, 159, 0, 0, 0, 0, 0, + 0, 0, 0, 126, 232, 18, 0, 0, 0, 0, 0, + 0, 0, 41, 249, 84, 0, 0, 0, 0, 0, 0, + 0, 2, 198, 174, 0, 0, 0, 0, 0, 0, 0, + 0, 103, 255, 255, 255, 255, 255, 255, 140, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + /* '0x7b' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 12, 151, 237, 227, 0, 0, 0, + 0, 0, 0, 0, 159, 223, 51, 2, 0, 0, 0, + 0, 0, 0, 1, 248, 113, 0, 0, 0, 0, 0, + 0, 0, 0, 22, 255, 85, 0, 0, 0, 0, 0, + 0, 0, 0, 28, 255, 84, 0, 0, 0, 0, 0, + 0, 0, 0, 28, 255, 82, 0, 0, 0, 0, 0, + 0, 0, 0, 42, 255, 60, 0, 0, 0, 0, 0, + 0, 0, 20, 157, 220, 5, 0, 0, 0, 0, 0, + 0, 148, 255, 233, 59, 0, 0, 0, 0, 0, 0, + 0, 0, 24, 160, 238, 17, 0, 0, 0, 0, 0, + 0, 0, 0, 38, 255, 74, 0, 0, 0, 0, 0, + 0, 0, 0, 28, 255, 88, 0, 0, 0, 0, 0, + 0, 0, 0, 28, 255, 88, 0, 0, 0, 0, 0, + 0, 0, 0, 27, 255, 88, 0, 0, 0, 0, 0, + 0, 0, 0, 5, 252, 108, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 183, 216, 45, 2, 0, 0, 0, + 0, 0, 0, 0, 25, 165, 232, 227, 0, 0, 0, + }, + /* '0x7c' */ { + 0, 0, 0, 0, 196, 172, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 196, 172, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 196, 172, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 196, 172, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 196, 172, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 196, 172, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 196, 172, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 196, 172, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 196, 172, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 196, 172, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 196, 172, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 196, 172, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 196, 172, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 196, 172, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 196, 172, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 196, 172, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 196, 172, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 196, 172, 0, 0, 0, 0, 0, + }, + /* '0x7d' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 249, 223, 137, 8, 0, 0, 0, 0, 0, + 0, 0, 4, 64, 239, 131, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 147, 221, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 117, 251, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 116, 255, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 114, 255, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 93, 255, 20, 0, 0, 0, 0, + 0, 0, 0, 0, 22, 240, 151, 21, 0, 0, 0, + 0, 0, 0, 0, 0, 78, 241, 255, 124, 0, 0, + 0, 0, 0, 0, 27, 244, 121, 16, 0, 0, 0, + 0, 0, 0, 0, 94, 255, 11, 0, 0, 0, 0, + 0, 0, 0, 0, 108, 255, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 108, 255, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 108, 255, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 128, 235, 0, 0, 0, 0, 0, + 0, 0, 3, 52, 227, 159, 0, 0, 0, 0, 0, + 0, 0, 251, 237, 155, 16, 0, 0, 0, 0, 0, + }, + /* '0x7e' */ { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 98, 224, 226, 82, 0, 0, 0, 0, 0, 0, + 34, 252, 81, 66, 240, 65, 0, 28, 255, 66, 0, + 93, 255, 5, 0, 90, 232, 48, 100, 244, 17, 0, + 0, 0, 0, 0, 0, 105, 233, 222, 83, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, +}; diff --git a/CODE/dsk/main.c b/CODE/dsk/main.c index ecba347..119d6cf 100644 --- a/CODE/dsk/main.c +++ b/CODE/dsk/main.c @@ -1798,6 +1798,8 @@ static void dsk_spinner_and_check(const void *boot_ctx_ptr) { /* === 应用 DSK 配置 === */ int show_logo = dsk_cfg_ok ? dsk_ini_get_bool(&dsk_cfg, "dsk", "show_logo", 1) : 1; int skip_login = dsk_cfg_ok ? dsk_ini_get_bool(&dsk_cfg, "dsk", "skip_login", 0) : 0; + /* F5: skip_firstinit=1 → 跳过首次启动向导与登录,直达 desktop */ + int skip_firstinit = dsk_cfg_ok ? dsk_ini_get_bool(&dsk_cfg, "dsk", "skip_firstinit", 0) : 0; int load_mouse = dsk_cfg_ok ? dsk_ini_get_bool(&dsk_cfg, "dsk", "mouse_init", 1) : 1; int load_netman = dsk_cfg_ok ? dsk_ini_get_bool(&dsk_cfg, "dsk", "netman", 1) : 1; int dev_mode = dsk_cfg_ok ? dsk_ini_get_bool(&dsk_cfg, "boot", "dev_mode", 0) : 0; @@ -1880,6 +1882,14 @@ static void dsk_spinner_and_check(const void *boot_ctx_ptr) { /* 合并 FUCK dev_mode 和 firstInit.txt dev_mode */ if (firstinit_dev_mode) dev_mode = 1; + /* F5: skip_firstinit=1 → 直达 desktop(跳过向导与登录)。 + * 优先级最高:即便 firstInit.txt 为 0(首次)也视作已完成。 */ + if (skip_firstinit) { + logl("[DSK] skip_firstinit=1: direct to desktop (wizard+login skipped)"); + is_first = 0; + firstinit_dev_mode = 0; + } + /* 开发者模式:加载 shell.elf 自动测试命令序列(cp/mv/echo/ls/cat/rm) */ if (dev_mode) { logl("[DSK:SCHED] decision: dev_mode -> shell.elf"); @@ -1903,8 +1913,8 @@ static void dsk_spinner_and_check(const void *boot_ctx_ptr) { dsk_schedule_netman(ctx, load_netman); milestone_write(7, "netman loaded"); - /* login — 可通过 skip_login=1 跳过 */ - if (skip_login) { + /* login — 可通过 skip_login=1 跳过;skip_firstinit=1 时一并跳过(F5) */ + if (skip_login || skip_firstinit) { logl("[DSK:SCHED] login skipped by FUCK config"); } else { DSK_TS_DECL(login_phase); diff --git a/CODE/dsk/main.o b/CODE/dsk/main.o index 1975762..e05c89d 100644 Binary files a/CODE/dsk/main.o and b/CODE/dsk/main.o differ diff --git a/Logo.png b/Logo.png deleted file mode 100644 index bc1468c..0000000 Binary files a/Logo.png and /dev/null differ diff --git a/README.md b/README.md index 3f1ef9e..6562fdc 100644 --- a/README.md +++ b/README.md @@ -1,53 +1,67 @@ -# Deshab-OS - -Deshab-OS 是一个从零编写的独立 64 位操作系统,基于 x86_64 long mode,采用单地址空间 Ring0(SAS-R0)内核架构,配套封缄内存(UTSM)、专用恢复根(DRR)与可加载驱动模块系统(DKM)。 - -## 项目状态 - -当前已完成可启动的实验内核闭环:Limine 引导 → UTSM 首阶段内核 → 14 个 DKM 驱动加载 → DSK 主内核 → 首次启动用户设置向导。 - -| 子系统 | 状态 | -|--------|------| -| 早期启动 / IDT / PIC | ✅ | -| UTSM 封缄内存(selftest) | 🔶 | -| DKM 驱动系统(14/14 驱动) | ✅ | -| DMA 物理页分配器 | ✅ | -| AHCI / NVMe 块设备 | 🔶 | -| FAT32 只读文件系统 | 🔶 | -| e1000 RX/TX 网络 | 🔶 | -| 字体系统(DBF,GB2312 全覆盖) | ✅ | -| FirstInit 用户设置向导 | 🔶 | -| SAS-R0-PCQ 调度器 | ⬜ | -| DRR 恢复系统 | ⬜ | - -## 核心架构 - -```text -SAS-R0-PCQ 单地址空间 Ring0 + Per-CPU O(1) 位图调度器 -UTSM UUID 调谐封缄内存(所有内存存密文,明文须经 UTRW 读写器) -UTRW 带标记读写器(Fast Path / Slow Path) -DRR 专用恢复根(看门狗 / checkpoint / A-B 回滚 / 独立 Emergency Pool) -DKM 驱动模块系统(ELF64 .drv ABI,4 stage 分阶段加载) -``` - -## 文档 - -| 文档 | 内容 | -|------|------| -| [架构设计文档](docs/ARCHITECTURE.md) | 系统整体架构、五大核心子系统、内存模型、驱动系统 | -| [启动路线设计](docs/BOOT_SEQUENCE.md) | B0-B4 五阶段启动序列、启动契约、回退链、视觉体验 | -| [开发路线图](docs/ROADMAP.md) | 分阶段开发路线、里程碑、验收标准 | -| [贡献与协作规范](CONTRIBUTING.md) | 开发环境、代码规范、Git 工作流、PR 流程 | -| [CLAUDE.md](CLAUDE.md) | 项目当前状态与下一阶段路线 | -| [UTSM 模块设计](CODE/UTSM/README.md) | 封缄内存模块完整设计 | -| [DKM 驱动系统](CODE/DKM/README.md) | 驱动模块系统说明 | -| [DSK 主内核](CODE/dsk/README) | 主内核说明与 boot context | -| [开发经验记录](LESSONS_LEARNED.md) | 开发过程中的经验与教训 | - -## 构建 - -```powershell -# 需求:LLVM Clang + ld.lld + Python/Pillow + QEMU -.\build.bat # 构建 utsm.elf + deshab.elf + 14 个 .drv + ISO/deshab.img -.\ISO\run_qemu.bat # QEMU UEFI 启动验证 -``` +# Deshab-OS + +> 实验内核 · QEMU 可启动演示 · 非生产系统 + +Deshab-OS 是一个从零编写的独立 64 位操作系统,基于 x86_64 long mode,采用单地址空间 Ring0(SAS-R0)内核架构,配套封缄内存(UTSM)、专用恢复根(DRR)与可加载驱动模块系统(DKM)。 + +当前已完成可启动的实验内核闭环:Limine 引导 → UTSM 首阶段内核 → 14 个 DKM 驱动加载 → DSK 主内核 → 桌面/登录/向导。 + +## 核心架构 + +```text +SAS-R0-PCQ 单地址空间 Ring0 + Per-CPU O(1) 位图调度器(当前 BSP-only) +UTSM UUID 调谐封缄内存(明文须经 UTRW 读写器) +UTRW 带标记读写器(Fast Path ✅ / Slow Path ⬜) +DRR 专用恢复根(看门狗 / checkpoint / A-B 回滚 / 独立 Emergency Pool) +DKM 驱动模块系统(ELF64 .drv ABI,4 stage 分阶段加载) +``` + +## 项目状态 + +**唯一状态源见 [docs/STATUS.md](docs/STATUS.md)**,本表只是引用摘要。 + +| 子系统 | 状态 | +|--------|------| +| 早期启动 / IRQ / DMA / DKM 14 驱动 | ✅ | +| UTSM 封缄(Fast path + selftest) | 🔶 | +| AHCI / e1000 / FAT32 写盘 | ✅ | +| NVMe / virtio-net / FAT32 完整路径 | 🔶 | +| PCQ 调度器 / DRR 恢复根 | ✅(BSP-only / 演示级) | +| Five-Phase 填补计划 | 见 [docs/ROADMAP_INSANE.md](docs/ROADMAP_INSANE.md) | + +### 已知边界(Non-Goals) + +1. **无进程隔离**:SAS-R0 单地址空间 Ring0,驱动 bug = 内核全盘崩。这不是安全 OS,是敞开工坊。 +2. **UTSM 仅 selftest 覆盖**:封缄是"设计意图 + 演示级实现",不是机密计算。 +3. **驱动为演示级**:QEMU 能演示 ≠ 真机可依赖;NVMe/virtio-net 尚未走完数据路径。 + +## 文档 + +| 文档 | 内容 | +|------|------| +| [STATUS.md](docs/STATUS.md) | **单一状态源**(全子系统三色表 + 证据) | +| [ROADMAP_INSANE.md](docs/ROADMAP_INSANE.md) | 五期填补计划(F/U/D/R/E 唯一任务编号) | +| [TASKBOARD.md](docs/TASKBOARD.md) | 可勾选任务表 | +| [PHILOSOPHY.md](docs/PHILOSOPHY.md) | 疯圣典:矛盾美学与「疯但好使」物理学 | +| [ARCHITECTURE.md](docs/ARCHITECTURE.md) | 架构设计 + 非目标章 | +| [BOOT_SEQUENCE.md](docs/BOOT_SEQUENCE.md) | B0-B4 五阶段启动序列(演示版) | +| [ROADMAP.md](docs/ROADMAP.md) | Phase 0-9 历史存档 + 用户态主线 | +| [CONTRIBUTING.md](CONTRIBUTING.md) | 开发环境、代码规范、Git 工作流 | +| [CLAUDE.md](CLAUDE.md) | 项目当前状态与下一阶段路线 | +| [LESSONS_LEARNED.md](LESSONS_LEARNED.md) | 开发经验与教训 | + +## 构建 + +> ⚠ 当前构建仅支持 **Windows**(build.ps1 + WSL mkfs.vfat/mkfs.ext4),跨平台构建见 ROADMAP_INSANE F3。 + +```powershell +# 需求:LLVM Clang + ld.lld + Python/Pillow + QEMU + WSL(mkfs) +.\build.bat # 构建 utsm.elf + deshab.elf + 14 个 .drv + ISO/deshab.img +.\build.bat -Variant dev # 开发者模式(自动跑 shell 测试,调试全开) +.\build.bat -Variant release # 发布版(进桌面+登录) +.\ISO\run_qemu.bat # QEMU UEFI 启动验证(串口输出到 stdio) +``` + +--- + +> "Deshab 不假装安全,只声明边界;不假装完成,只标⬜。" 🪷 diff --git a/SYSTEM/boot/utsm.elf b/SYSTEM/boot/utsm.elf index 6469ea7..adaea7d 100755 Binary files a/SYSTEM/boot/utsm.elf and b/SYSTEM/boot/utsm.elf differ diff --git a/SYSTEM/system/deshab64/FUCK b/SYSTEM/system/deshab64/FUCK index 7399bc8..3fb35e0 100644 --- a/SYSTEM/system/deshab64/FUCK +++ b/SYSTEM/system/deshab64/FUCK @@ -1,27 +1,19 @@ -# Deshab Kernel Configuration (REALTEST - 实机开发测试) -# 基于 dev 配置, 启用磁盘日志持久化 -# 启动时把完整日志写入磁盘 LBA 2-1000 扇区, 事后用 WinHex/dd 读取 -# 路径: SYSTEM/system/deshab64/FUCK -# UTSM 通过 Limine boot module 预加载读取(cmdline="fuck:config") -# DSK 通过 FAT32 子目录遍历读取(路径 "SYSTEM /DESHAB64 /FUCK ") -# 缺失或空的键使用硬编码默认值,行为与无配置文件时一致 +# Deshab Kernel Configuration — dev 变体(build/configs/dev/FUCK) +# build.ps1 -Variant dev 打包前注入 SYSTEM/system/deshab64/FUCK +# 开发者模式:selftest 开、dev_mode 自动跑 shell.elf 测试、日志持久化、跳过向导直达桌面 [boot] vmm=1 linux_guest=1 -# OpenXJ380 第二 guest:Phase 0 不需要,保持关闭 xj380_guest=0 -# 2026-09-20: 并行会话新增的 chacha20 KAT 间歇性 FAIL 会 arch_halt_forever -# 挡死整条启动链(chacha20 本体运行路径不受影响),先跳过自测解锁桌面。 -selftest=0 -dev_mode=0 -# 真机安全检查全部放宽(和 dev 一样),排除安全检查导致黑屏 +# F4: 分级自检 0=关 1=快速 2=全量(含 UTSM selftest;注意 chacha20 KAT 间歇 FAIL 会挡启动) +selftest=1 +# F1 验证钩子: 1=启动自检后触发莲花崩溃屏(演示/回归用,日常保持 0) +panic_test=0 +dev_mode=1 la57_guard=0 mcfg_check=0 max_phys_addr_bits=0 -# 实机启动日志持久化: 启用, 把启动日志写入 FAT32 文件 -# SYSTEM/DESHAB64/DEV/BOOTLOG.TXT (DEV 缺失时回退根目录 BOOTLOG.TXT) -# 主机直接读取该文件即可, 不覆盖 GPT, 可反复烧录测试 disk_log=1 [drivers] @@ -33,7 +25,6 @@ console_fb=1 ahci=1 nvme=1 ehci=1 -# xhci=1: xhci 驱动已修复无控制器时不再 halt,恢复启用 xhci=1 bootfs=1 vfs=1 @@ -61,27 +52,22 @@ drr_recovery_log_size=4096 drr_heartbeat_interval=0 [sched] -# SAS-R0-PCQ 调度器(Phase 7):tick=LAPIC timer(宿主自持) enable=1 tick_hz=100 timeslice_ms=10 -# demo 窗口忙等已加 tick 失速兜底(sched.c: 心跳无进展自动中止窗口), -# tick 不投递时不再卡死 bootstrap,窗口结束照常交接 DSK -# demo_fault=1 为看门狗负向测试(已验证通过),默认保持 0 demo_ms=1000 demo_fault=0 [drr] -# 恢复根(Phase 8):快照区/看门狗默认启用,ckpt_max_pages 编译期 128 watchdog_enabled=1 [dsk] show_logo=0 skip_login=1 +# F5: dev 直达桌面(跳过向导与登录) +skip_firstinit=1 mouse_init=1 netman=1 -# session=native|kde|ask (ask: 8s chooser, keyboard or serial '1'/'2') -# native: boot Deshab desktop; KDE icon in user/desktop launches Plasma session=native [debug] diff --git a/SYSTEM/system/deshab64/deshab.elf b/SYSTEM/system/deshab64/deshab.elf index 1206e47..8f655cf 100644 Binary files a/SYSTEM/system/deshab64/deshab.elf and b/SYSTEM/system/deshab64/deshab.elf differ diff --git a/SYSTEM/system/deshab64/desktop.elf b/SYSTEM/system/deshab64/desktop.elf index 0123b6e..b72805d 100755 Binary files a/SYSTEM/system/deshab64/desktop.elf and b/SYSTEM/system/deshab64/desktop.elf differ diff --git a/SYSTEM/system/user/use/firstInit.txt b/SYSTEM/system/user/use/firstInit.txt index 0d66ea1..6ed281c 100644 --- a/SYSTEM/system/user/use/firstInit.txt +++ b/SYSTEM/system/user/use/firstInit.txt @@ -1,2 +1,2 @@ -0 +1 1 diff --git a/build/configs/dev/FUCK b/build/configs/dev/FUCK new file mode 100644 index 0000000..3fb35e0 --- /dev/null +++ b/build/configs/dev/FUCK @@ -0,0 +1,91 @@ +# Deshab Kernel Configuration — dev 变体(build/configs/dev/FUCK) +# build.ps1 -Variant dev 打包前注入 SYSTEM/system/deshab64/FUCK +# 开发者模式:selftest 开、dev_mode 自动跑 shell.elf 测试、日志持久化、跳过向导直达桌面 + +[boot] +vmm=1 +linux_guest=1 +xj380_guest=0 +# F4: 分级自检 0=关 1=快速 2=全量(含 UTSM selftest;注意 chacha20 KAT 间歇 FAIL 会挡启动) +selftest=1 +# F1 验证钩子: 1=启动自检后触发莲花崩溃屏(演示/回归用,日常保持 0) +panic_test=0 +dev_mode=1 +la57_guard=0 +mcfg_check=0 +max_phys_addr_bits=0 +disk_log=1 + +[drivers] +timer=1 +apic=1 +acpi=1 +pci=1 +console_fb=1 +ahci=1 +nvme=1 +ehci=1 +xhci=1 +bootfs=1 +vfs=1 +fat32=1 +devfs=1 +e1000=1 +virtio_net=1 +ath9k=0 +ps2kbd=1 +ioapic_init=1 +lapic_enable=1 +apic_route=1 +apic_route_legacy=1 +nvme_msi=1 +apic_diag=0 + +[utsm] +max_segments=1024 +max_capabilities=256 +max_pckc_keys=8 +dirty_shard_pages=1024 +arena_size_mb=64 +drr_emergency_pool_kb=64 +drr_recovery_log_size=4096 +drr_heartbeat_interval=0 + +[sched] +enable=1 +tick_hz=100 +timeslice_ms=10 +demo_ms=1000 +demo_fault=0 + +[drr] +watchdog_enabled=1 + +[dsk] +show_logo=0 +skip_login=1 +# F5: dev 直达桌面(跳过向导与登录) +skip_firstinit=1 +mouse_init=1 +netman=1 +session=native + +[debug] +enabled=1 +log_level=1 +probe_enable=1 +probe_capacity=4096 +stat_summary_interval=256 +utsm_trace=1 +vmm_trace=1 +dkm_trace=1 +dsk_trace=1 +block_trace=1 +net_trace=0 +input_trace=1 + +[compat] +lib_path=lib +linux_lib_guest_path=/usr/lib/deshab +linux_lib_sync=1 +pe_dll_search=1 diff --git a/build/configs/dev/firstInit.txt b/build/configs/dev/firstInit.txt new file mode 100644 index 0000000..6ed281c --- /dev/null +++ b/build/configs/dev/firstInit.txt @@ -0,0 +1,2 @@ +1 +1 diff --git a/build/configs/release/FUCK b/build/configs/release/FUCK new file mode 100644 index 0000000..e127cdc --- /dev/null +++ b/build/configs/release/FUCK @@ -0,0 +1,89 @@ +# Deshab Kernel Configuration — release 变体(build/configs/release/FUCK) +# build.ps1 -Variant release 打包前注入 SYSTEM/system/deshab64/FUCK +# 发布版:调试零开销、进登录+向导正常路径、真机安全选项 + +[boot] +vmm=0 +linux_guest=0 +xj380_guest=0 +# F4: 分级自检(快速档,不含 UTSM selftest) +selftest=1 +dev_mode=0 +la57_guard=0 +mcfg_check=0 +max_phys_addr_bits=0 +disk_log=0 + +[drivers] +timer=1 +apic=1 +acpi=1 +pci=1 +console_fb=1 +ahci=1 +nvme=1 +ehci=1 +xhci=1 +bootfs=1 +vfs=1 +fat32=1 +devfs=1 +e1000=1 +virtio_net=1 +ath9k=0 +ps2kbd=1 +ioapic_init=1 +lapic_enable=1 +apic_route=1 +apic_route_legacy=1 +nvme_msi=1 +apic_diag=0 + +[utsm] +max_segments=1024 +max_capabilities=256 +max_pckc_keys=8 +dirty_shard_pages=1024 +arena_size_mb=64 +drr_emergency_pool_kb=64 +drr_recovery_log_size=4096 +drr_heartbeat_interval=0 + +[sched] +enable=1 +tick_hz=100 +timeslice_ms=10 +demo_ms=0 +demo_fault=0 + +[drr] +watchdog_enabled=1 + +[dsk] +show_logo=1 +skip_login=0 +# F5: release 走正常路径(向导/登录生效) +skip_firstinit=0 +mouse_init=1 +netman=1 +session=native + +[debug] +enabled=0 +log_level=0 +probe_enable=0 +probe_capacity=4096 +stat_summary_interval=0 +utsm_trace=0 +vmm_trace=0 +dkm_trace=0 +dsk_trace=0 +block_trace=0 +net_trace=0 +input_trace=0 + +[compat] +lib_path=lib +linux_lib_guest_path=/usr/lib/deshab +linux_lib_sync=0 +pe_dll_search=1 diff --git a/build/configs/release/firstInit.txt b/build/configs/release/firstInit.txt new file mode 100644 index 0000000..b261da1 --- /dev/null +++ b/build/configs/release/firstInit.txt @@ -0,0 +1,2 @@ +1 +0 diff --git a/dcplogo.png b/dcplogo.png deleted file mode 100644 index c788790..0000000 Binary files a/dcplogo.png and /dev/null differ diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 5e0f245..4e88713 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -1,6 +1,7 @@ # Deshab-OS 架构设计文档 > 系统整体架构、核心子系统与关键技术约束。模块文档索引:[UTSM](../CODE/UTSM/README.md)、[DKM](../CODE/DKM/README.md)、[DSK](../CODE/dsk/README)。 +> 子系统实现状态唯一来源:[STATUS.md](./STATUS.md)。 --- @@ -49,6 +50,8 @@ kernel_main() → serial_init → idt_init → arena_init(16MB) → dma_init(Lim ## 3. 五大核心架构支柱 +> 每根支柱的**当前实现边界**:SAS-R0-PCQ — 调度器 BSP-only,per-cpu runqueue 结构就位未启用;任务加密上下文为结构预留。UTSM — 封缄段表/UUID ✅,加密原语 chacha20/KDF/BLAKE2b 已落,PCKC schedule 待接;全内存密文为设计意图,当前仅 selftest 路径覆盖。UTRW — Fast Path 真实现,Slow Path 为 stub。DRR — checkpoint/看门狗/Emergency Pool ✅(演示级),Emergency Pool 为编译期 64KB 静态池。DKM — 14 驱动能加载 ✅,无热卸载/无 capability/无符号版本协商。 + ### 3.1 SAS-R0-PCQ — 单地址空间Ring0调度模型 - 单地址空间,Ring0,Per-CPU独立runqueue,调度热路径O(1) @@ -183,10 +186,11 @@ DBF格式8bpp灰度:simhei_16/24/32.dbf(GB2312 6763汉字+ASCII 32-126), ### 9.2 首次启动流程 ```text -DSK → 读FUCK配置(show_logo/skip_login/mouse_init/netman/dev_mode) - → 渐变背景+旋转加载环(comet-tail弧+TSC计时+show_logo=0可跳过) +DSK → 读FUCK配置(show_logo/skip_login/skip_firstinit/mouse_init/netman/dev_mode) + → 静态Logo(渐变背景+Logo.png居中alpha混合,show_logo=0可跳过) → 读firstInit.txt("0|1\n0|1",第二行dev_mode) → dev_mode=1: 加载shell.elf自动命令测试 + → skip_firstinit=1: 直接跳 desktop(跳过向导与登录) → firstInit==0(首次): mouseInit→netman→FirstInit(偏好/账户/网络)→写USER.CONF+翻转firstInit.txt→desktop → firstInit!=0(正常): login.elf(USER.CONF+skip_login可跳)→desktop ``` @@ -211,10 +215,12 @@ DSK → 读FUCK配置(show_logo/skip_login/mouse_init/netman/dev_mode) | DSK | FAT32子目录遍历(`SYSTEM /DESHAB64 /FUCK `),block provider可用后 | ```ini -[boot] vmm=1 linux_guest=1 selftest=1 dev_mode=0 +[boot] vmm=1 linux_guest=1 selftest=0|1|2 dev_mode=0 # selftest: 0=关 1=快速 2=全量 [drivers] timer=1 apic=1 nvme=0 # 0=跳过 [utsm] max_segments=1024 max_pckc_keys=8 dirty_shard_pages=1024 arena_size_mb=16 -[dsk] show_logo=1 skip_login=0 default_shell=desktop mouse_init=1 netman=1 +[sched] enable=1 tick_hz=100 timeslice_ms=10 demo_ms=0 demo_fault=0 +[drr] watchdog_enabled=1 +[dsk] show_logo=1 skip_login=0 skip_firstinit=0 default_shell=desktop mouse_init=1 netman=1 ``` 缺失或空时用硬编码默认值。算法参数通过运行期全局变量覆盖编译期宏,静态数组大小仍用编译期上限。 @@ -223,13 +229,22 @@ DSK → 读FUCK配置(show_logo/skip_login/mouse_init/netman/dev_mode) --- -## 11. 开放设计点 +## 11. 非目标(Non-Goals) -1. **加密原语未指定**——KDF/hash/stream/MAC待定,当前占位XOR stream -2. **kernel_api设计态vs实现态**——RE定义typed sub-struct指针,实现为const void*占位 -3. **block未作为独立子API**——走provider注册 -4. **log API签名分歧**——定参vs变参,统一方向待定 -5. **v1不追求**——RAM原地回滚/强安全隔离/设备副作用回滚 +Deshab 不假装是它不是的东西。以下为**明确不做**的目标(v1): + +1. **不提供进程隔离** — SAS-R0 单地址空间 Ring0,无 per-process 页表、无 ring3。驱动 bug 即内核崩溃,这是接受的代价。 +2. **不是 TEE / 机密计算** — UTSM 无硬件信任根(无 IOMMU/MPK/TEE 撑腰),封缄防的是"自己手滑",不是攻击者(本环境假设无攻击者)。 +3. **非形式化验证** — 0bug 靠 QEMU 演示证据 + DRR 回滚兜底,不靠证明。 +4. **DKM 不做故障隔离** — 同地址空间插件,"能加载"≠"能安全卸载";热卸载为 ROADMAP_INSANE D1 待办。 +5. **不追求多用户强安全** — 见 CLAUDE.md 设计约束 3。 +6. **v1 不追求** — RAM 原地回滚 / 设备副作用回滚 / 生产级真机部署。 + +## 11.5 开放设计点 + +1. **kernel_api设计态vs实现态**——RE定义typed sub-struct指针,实现为const void*占位 +2. **block未作为独立子API**——走provider注册 +3. **log API签名分歧**——定参vs变参,统一方向待定 --- @@ -262,7 +277,9 @@ docs/ (本文档所在) | [RE/UTSM_算法记录.md](../RE/UTSM_算法记录.md) | UTSM核心算法 | | [RE/驱动模块ABI设计.md](../RE/驱动模块ABI设计.md) | DKM ABI详细设计 | | [docs/BOOT_SEQUENCE.md](./BOOT_SEQUENCE.md) | 启动路线设计 | -| [docs/ROADMAP.md](./ROADMAP.md) | 开发路线图 | -| [docs/系统开发策划.md](./系统开发策划.md) | 实现矩阵与里程碑策划 | +| [docs/ROADMAP.md](./ROADMAP.md) | Phase 0-9 历史存档 | +| [docs/ROADMAP_INSANE.md](./ROADMAP_INSANE.md) | 五期填补计划(当前活跃) | +| [docs/STATUS.md](./STATUS.md) | 单一状态源 | +| [docs/PHILOSOPHY.md](./PHILOSOPHY.md) | 疯圣典 | | [docs/兼容层设计.md](./兼容层设计.md) | Linux/PE兼容层 | | [docs/桌面设计.md](./桌面设计.md) | 桌面环境设计 | diff --git a/docs/BOOT_SEQUENCE.md b/docs/BOOT_SEQUENCE.md index ccc8387..81d9f92 100644 --- a/docs/BOOT_SEQUENCE.md +++ b/docs/BOOT_SEQUENCE.md @@ -1,6 +1,7 @@ -# Deshab 启动路线设计 +# Deshab 启动路线设计(B0–B4 演示版) > 从上电到用户可交互的完整启动序列,带契约的分阶段唤醒过程。 +> 说明:本文为 QEMU 演示版——"契约/锚点/回退链"描述的是 QEMU 下的实际行为,非生产级承诺。状态见 [STATUS.md](./STATUS.md)。 --- @@ -29,7 +30,7 @@ B0 Ignis: UEFI/BIOS → Limine(读limine.conf, 加载utsm.elf, 预加载17个boot module) B1 Sigillum: serial/IDT/arena/DMA → UTSM init+PCKC → DKM 4-stage 14驱动 → selftest锚点 B2 Transitus: FAT32 block provider读deshab.elf(失败→Limine module) → ELF校验+PT_LOAD → 填充dsk_boot_context → 跳转DSK -B3 Origo: 渐变背景+旋转环 → FAT32读firstInit.txt → 首次/正常分支 +B3 Origo: 渐变背景+静态Logo → FAT32读firstInit.txt → 首次/正常分支 B4 Excitas(首次): mouseInit → netman → FirstInit → 写USER.CONF+firstInit.txt → desktop B4 Excitas(正常): login → desktop ``` @@ -119,13 +120,13 @@ dsk_entry(ctx): ③ 取block_read(api+0xA8) ④ 读FUCK配置(FAT32子目录) ⑤ 渐变背景(BG_TOP淡蓝→BG_BOTTOM深紫) - ⑥ 旋转加载环(show_logo=1时): comet-tail弧+双缓冲save/restore+TSC计时+33ms帧pacing + ⑥ 静态Logo(show_logo=1时): Logo.png居中alpha混合绘制于渐变背景(旋转加载环已移除) ⑦ 首次启动检测: FAT32读firstInit.txt("0|1\n0|1"),firstInit=='0'→首次 ⑧ dev_mode=1→加载shell.elf自动命令测试 - ⑨ 按首次/正常分支调度 + ⑨ skip_firstinit=1→直达desktop;否则按首次/正常分支调度 ``` -旋转环参数:SPIN_R=64, SPIN_THICK=3, SPIN_ARC=110/256≈155°, head_color=0xFFE8F2FC, 256项sin×127查表, base+=6顺时针。 +Logo绘制:居中 + alpha混合(B3 静态画面,取代原 comet-tail 旋转环)。 **B3锚点**:`[DSK] FUCK config loaded` + `[DSK] firstInit=0`(或"!=0"/"not found") diff --git a/docs/PHILOSOPHY.md b/docs/PHILOSOPHY.md new file mode 100644 index 0000000..c09d11e --- /dev/null +++ b/docs/PHILOSOPHY.md @@ -0,0 +1,47 @@ +# Deshab-OS 疯圣典(PHILOSOPHY) + +> "Deshab 不假装安全,只声明边界;不假装完成,只标⬜。" + +--- + +## 三条箴言 + +> 🕯️ 最自由的系统,需要最隆重的仪式来证明它本不需要仪式。 + +> 🕯️ 单地址空间里,隔离是一种修辞,不是一种机制。 + +> 🕯️ 0bug 不是没有错,是错也错得有 B0–B4 的章法。 + +--- + +## 「疯但好使」物理学 + +Deshab 的风格是自相矛盾:一边封圣一边爆粗,一边敞开门一边焊死锁。 + +| 疯的部分 | 为什么居然没翻车 | +|---------|----------------| +| 骂街式提交历史 | commit message 只是历史涂鸦,二进制照常 build,QEMU 不读 git log | +| Logo 叫 FUCKYOU | 渲染时只认像素,不认羞耻心 | +| 全内存封缄 UTSM | 加解密纯耗时钟,不改语义——"慢但对的" | +| DKM 4-stage 填表 | Ring0 里没别人抢地址,乱序也能落进空地 | +| FirstInit 半完成 | 跳过键全部有效,向导"未完但已退",体验反而干净 | + +疯的是姿态,稳的是时序。 + +--- + +## 矛盾美学宣言 + +1. **我们不承诺安全。** 环境假设为绝对安全(无攻击者),用户行为无限自由不受限制。UTSM 存在不是因为有人窥探,是因为我们喜欢咔哒声。 +2. **我们不承诺完成。** 状态表里的 ⬜ 是坦白,不是路线装饰。没写的东西不写进"核心架构"。 +3. **我们承诺可演示。** 每个里程碑必须有 QEMU 证据。莲花确实开了,这比任何架构图都硬。 +4. **我们承诺边界。** 已实现(✅)、演示级(🔶)、仅设计(⬜)三层分离,状态唯一来源是 [STATUS.md](./STATUS.md)。 + +--- + +## 气质定位 + +> Deshab-OS:一个把锁焊在敞开的门上、用莲花崩溃屏收殓每一次 panic 的毛坯神殿。 +> 敞开工坊,不是赛博保险柜:一把扳手走天下,卡了按时光键。 + +体面不靠装完成,靠标边界。🪷 diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index 437d26e..baa76dc 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -1,6 +1,9 @@ -# Deshab-OS 开发路线图 +# Deshab-OS 开发路线图(Phase 0–9 历史存档) -> 分阶段开发路线。✅已完成 · 🔶部分完成 · ⬜待实现 +> 本文档为**历史存档**:Phase 0–9 内核主线的任务清单与完成记录。 +> 当前活跃路线见 [ROADMAP_INSANE.md](./ROADMAP_INSANE.md)(五期填补计划,唯一任务编号 F/U/D/R/E); +> 子系统状态唯一来源见 [STATUS.md](./STATUS.md)。 +> ✅已完成 · 🔶部分完成 · ⬜待实现 --- @@ -23,10 +26,10 @@ Limine → utsm.elf → DKM 14驱动 → DSK(deshab.elf) | FAT32 | 🔶 | DKM只读;DSK读写(根目录) | | e1000 | ✅ | RX/TX+DHCP/ARP/UDP/DNS,polling | | 字体系统 | ✅ | DBF 16/24/32px,GB2312全覆盖 | -| FirstInit | 🔶 | UI+输入+SHA256密码+写盘;B6按键崩溃修复中 | +| FirstInit | 🔶 | UI+输入+SHA256密码+写盘;B6按键崩溃QEMU未复现;可跳过(skip_firstinit) ✅ | | 正常启动路径 | ✅ | login→desktop | | SAS-R0-PCQ | ✅ | O(1)位图调度+LAPIC tick+xv6式切换,selftest闭环 | -| DRR | 🔶 | 看门狗/快照/回滚闭环(CRC64+AB双槽),MAC仍为占位 | +| DRR | 🔶 | 看门狗/快照/回滚闭环;页MAC已升级BLAKE2b keyed MAC;segment/system级回滚待验证 | --- @@ -111,8 +114,8 @@ Limine → utsm.elf → DKM 14驱动 → DSK(deshab.elf) | 任务 | 状态 | 验收标准 | |------|------|---------| -| 按键崩溃修复(B6) | 🔶 | fb_text在-O2下稳定 | -| 鼠标光标移动 | ⬜ | PS/2 IRQ12+包解码+光标 | +| 按键崩溃修复(B6) | ✅ | QEMU复现测试未复现,全流程PASS | +| 鼠标光标移动 | ✅ | PS/2 IRQ12+包解码+光标(M1完成) | | user.conf写盘 | ✅ | 重启后login可读取 | | 网络配置界面+时区/语言 | ⬜ | — | | 设置完成后跳转+正常启动路径 | ✅ | FirstInit返回→持久化→desktop | @@ -146,8 +149,8 @@ selftest含runqueue O(1)、block/wake、看门狗负向测试(demo_fault=1检 | Page/Segment/System Rollback | 🔶 | page级回滚+verify PASS;segment/system级待真实加密后验证 | | 驱动recovery ops | ⬜ | quiesce/reset/reinit | -注:快照区为静态区域(UTSM arena 内),页快照容量编译期 128 页; -MAC 当前为 CRC64 占位(Phase 9 替换真实 MAC)。 +注:快照区经 dma_alloc_pages 分配,页快照容量编译期 129 页; +页 MAC 已为 BLAKE2b keyed MAC + mac_root 链(Phase 9 早期成果)。 风险:恢复路径禁用普通堆;Emergency Pool耗尽→system rollback。 --- @@ -211,5 +214,5 @@ MAC 当前为 CRC64 占位(Phase 9 替换真实 MAC)。 - [BOOT_SEQUENCE.md](./BOOT_SEQUENCE.md) - [兼容层设计.md](./兼容层设计.md) - [桌面设计.md](./桌面设计.md) -- [系统开发策划.md](./系统开发策划.md) +- [ROADMAP_INSANE.md](./ROADMAP_INSANE.md)(当前活跃路线) - [CLAUDE.md](../CLAUDE.md) diff --git a/docs/ROADMAP_INSANE.md b/docs/ROADMAP_INSANE.md new file mode 100644 index 0000000..c9bfeca --- /dev/null +++ b/docs/ROADMAP_INSANE.md @@ -0,0 +1,108 @@ +# Deshab-OS「疯起来」填补计划 v1.0 + +> 总原则:先让"疯"有可演示的实体,再让疯自洽不翻车。 +> 状态规范:✅ 已实现(附 QEMU 证据) · 🔶 演示级(注明边界) · ⬜ 仅设计(不承诺) +> +> **编号体系(唯一任务编号)**:F=骨架 / U=仪式 / D=自由 / R=落款 / E=品牌。 +> Phase 0–9 仅作历史存档(见 [ROADMAP.md](./ROADMAP.md));M 编号仅指 CLAUDE.md 里程碑记录。 + +--- + +## 分期总览 + +```text +一期 骨架 → 让"疯"站得住(基础设施) +二期 仪式 → 让 UTSM/UTRW 成型 +三期 自由 → 让 DKM/用户态有入口 +四期 落款 → 让 DRR/PCQ 可演示 +五期 品牌 → 让疯变成说明书 +``` + +--- + +## 🔩 一期:让「疯」站得住 + +没有这层,"无限自由"只是内核随便崩。 + +| 编号 | 功能 | 疯的意义 | 状态 | 验收标准 | +|------|------|---------|------|---------| +| F1 | 内核 panic 统一兜底 | 崩了也得崩出莲花 | ✅ | panic_symbol + 莲花崩溃屏 + 寄存器简表 + DRR 归档后 halt | +| F2 | UEFI 帧缓冲控制台 | 疯要有画面 | 🔶 | console_fb 已可出字;统一控制台抽象(无 VGA 回退也出宋体)⬜ | +| F3 | 构建跨平台(Make/CMake) | 疯不应绑 Windows | ⬜ | 当前 build.ps1 + WSL mkfs;Linux/macOS make iso 待做 | +| F4 | 状态机自检 boot_ok | 知道自己是几成疯 | ✅ | 启动分级自检(IDT/UTSM/DKM/调度器/DRR),输出 ✅/🔶 明细 | +| F5 | 可跳过 FirstInit | 自由的第一步 | ✅ | FUCK `[dsk] skip_firstinit=1` 直达 desktop;build/configs 模板注入生效 | + +一期不做任何"安全/加密",只让系统稳定地发疯。 + +--- + +## 🗝️ 二期:让「仪式」成型(UTSM / UTRW 落地) + +Deshab 最标志性的疯点——给空气上锁。 + +| 编号 | 功能 | 疯的意义 | 状态 | 实现要点 / 验收标准 | +|------|------|---------|------|-------------------| +| U1 | UTSM 元数据区(UUID 表) | 每页都有"身份" | ✅ | 封缄段表 + UUID 调谐已就位(`CODE/UTSM/core/segment.c`),可查询页归属 | +| U2 | UTRW Fast/Slow Path 真分支 | 快慢路不是画出来的 | 🔶 | Fast path ✅(capability 校验→PCKC→line 解密→seqlock);Slow path ⬜(当前 `utrw/slow_path.c` 为 stub) | +| U3 | `@sealed` 段可选标记 | 用户能选锁不锁 | ⬜ | 链接脚本支持 `__sealed` section;未标记段 0 开销 | +| U4 | 密文页 dump 工具 | 发疯也要可调试 | 🔶 | shell 可读内存;专用 dump 命令 + 明文/密文对照待做 | +| U5 | UTSM selftest 全覆盖 | 把🔶刷成✅ | 🔶 | chacha20 KAT/段表/越界已覆盖,KAT 间歇 FAIL 待修;覆盖率目标 ≥70% | + +二期做完:UTSM 从"设计"变"可开关的特性",疯得有旋钮。 + +--- + +## 🔌 三期:让「自由」有入口(DKM / 用户态雏形) + +无限自由的兑现层。 + +| 编号 | 功能 | 疯的意义 | 状态 | 实现要点 / 验收标准 | +|------|------|---------|------|-------------------| +| D1 | DKM 热卸载(基础) | 从"焊死"到"可拔" | ⬜ | 仅有 `DKM_F_NO_UNLOAD` 标志与状态机文档;需引用计数+资源回收,load/unload 循环 100 次不崩 | +| D2 | 裸机器码加载器 | 真·无限自由 | ⬜ | 任意 elf/裸码塞地址即执行;能打印、能崩内核 | +| D3 | 内核 API 导出表 | 自由也要有地图 | ⬜ | 当前为固定偏移 struct ABI(`CODE/sdk/include/deshab/kernel_api.h`);需按名导出表 kapi() | +| D4 | DKM 彩色日志前缀 | 每个驱动有自己的脾气 | ⬜ | 加载时自选颜色;日志一眼看出是谁在骂 | +| D5 | 最小 REPL/shell | 自由的交互面 | ✅ | shell.elf:ls/cat/cp/mv/rm/run/probe/test/pci 等 25+ 命令 | + +三期做完:用户能真在系统里"为所欲为",疯得可上手。 + +--- + +## ⏪ 四期:让「疯但有落款」落地(DRR / PCQ) + +把"未实现"的⬜变成"能演示"。 + +| 编号 | 功能 | 疯的意义 | 状态 | 实现要点 / 验收标准 | +|------|------|---------|------|-------------------| +| R1 | checkpoint 快照 | 时光键雏形 | ✅ | dirty shard 位图收集 → dma 页快照 + A/B 双槽 + CRC64 + 原子切换(`CODE/UTSM/drr/drr_core.c`) | +| R2 | 看门狗计时器 | 卡死也能体面 | ✅ | register/kick/timeout → fault 路径 → 回滚/复位;负向测试 PASS(demo_fault=1) | +| R3 | Emergency Pool | 崩溃后有地方喘气 | ✅ | 编译期 64KB 独立静态池(独立于堆)+ bump 分配器;`drr_emergency_pool_kb` 键未接线 ⬜ | +| R4 | A/B 镜像回滚 | 时光机第 1 台 | 🔶 | 页级回滚 + CRC verify + BLAKE2b keyed 页 MAC ✅;segment/system 级回滚待真实加密验证 | +| R5 | PCQ 位图调度器(单核→多核) | 让"凭感觉"变 O(1) | 🔶 | O(1) 位图 + LAPIC tick + xv6 式切换 ✅;BSP-only,per-cpu 多核负载均衡 ⬜ | + +四期做完:DRR/PCQ 从⬜变🔶,疯得有章法。 + +--- + +## 🪷 五期:让「疯」变成品牌(体验/文档/仪式) + +不是功能,是"Deshab 味"。 + +| 编号 | 功能 | 疯的意义 | 状态 | 验收标准 | +|------|------|---------|------|---------| +| E1 | 启动莲花动画 | 每次开机都有仪式 | ⬜ | Limine→UTSM 间莲花淡入(当前为 DSK 静态 Logo) | +| E2 | "假想时光键"彩蛋 | 未实现的浪漫 | ⬜ | 按键弹出"假设已回滚至假设态" | +| E3 | 提交信息规范(疯洁版) | 把脏历史变规矩 | ⬜ | 禁非描述性提交;保留疯味措辞 | +| E4 | deshab-fuckyou-edition 风味 ISO | 官方下场整活 | ⬜ | 独立分支,README 带莲花 slogan | +| E5 | 疯圣典进 docs/ | 疯得有文档 | ✅ | [PHILOSOPHY.md](./PHILOSOPHY.md) 已合并 | + +--- + +## ⚠ 保命守则 + +1. UTSM 二期必须做成可关闭,否则三期 DKM 乱摸内存会成调试地狱。 +2. DRR 先"单核+内存快照",QEMU 里验证,别一上真机。 +3. PCQ 别和 UTRW 缓存同时改,一次只动一个子系统。 +4. 每个里程碑必须有 QEMU 证据(串口日志/截图),疯要有画面证据。 + +> 一句话:先让 Deshab 稳稳地疯,再让它疯得能演示,最后让它疯得有说明书。🪷 diff --git a/docs/STATUS.md b/docs/STATUS.md new file mode 100644 index 0000000..9e7afe6 --- /dev/null +++ b/docs/STATUS.md @@ -0,0 +1,85 @@ +# Deshab-OS 状态总表(单一事实源) + +> 本文件是全项目唯一的子系统状态来源。其他文档(README/ROADMAP/ARCHITECTURE/CLAUDE.md)只引用本表,不得自抄状态。 +> 状态规范:✅ 已实现 · 🔶 演示级(注明边界) · ⬜ 仅设计/未实现。 +> 更新规则:状态变更必须同步本表,并附证据(串口日志路径 / QEMU 现象)。 + +## 内核底座 + +| 子系统 | 状态 | 边界/说明 | 证据 | +|--------|------|----------|------| +| 早期启动(Limine→long mode→C) | ✅ | cli/cld 纪律、early serial 非阻塞 | QEMU 启动日志 | +| IDT/异常 | ✅ | 0–255 stub 全覆盖;异常路径走 F1 莲花崩溃屏 | `arch/x86_64/idt.c` | +| PIC remap + IRQ 分发 | ✅ | remap 0x20–0x2f,handler 注册 + EOI | — | +| IOAPIC→LAPIC 路由(B7) | ✅ | apic_route=1 接管;失败自动降级 PIC | `.build_tmp/qemu_serial_*.log` | +| LAPIC timer | ✅ | TSC 校准 + 周期模式,[sched] 配置 | M4 QEMU 日志 | +| DMA 物理页分配器 | ✅ | bitmap,低 4G 钳位 | e1000 DMA 根治记录 | +| 页表映射接口(map/unmap) | ⬜ | mmio 通用映射待做 | — | +| panic 统一兜底(F1) | ✅ | 莲花崩溃屏 + panic_symbol + DRR 归档;CPU 异常/驱动 panic 统一入口 | `.build_tmp/qemu_serial_f1panic.log` | +| boot 分级自检(F4) | ✅ | `[boot] selftest=0\|1\|2`,5 项全过 BOOT-OK | `.build_tmp/qemu_serial_f1f4f5.log` | +| 构建系统 | 🔶 | Windows build.ps1 + WSL mkfs;跨平台 ⬜ | build.ps1 | + +## UTSM / UTRW + +| 子系统 | 状态 | 边界/说明 | 证据 | +|--------|------|----------|------| +| 封缄段表 / UUID 调谐(U1) | ✅ | 段创建/查询闭环 | `CODE/UTSM/core/segment.c` | +| UTRW Fast Path | ✅ | capability→PCKC→line 解密→seqlock | `utrw/read.c` | +| UTRW Slow Path(U2) | ⬜ | `utrw/slow_path.c` 当前为 stub | — | +| `@sealed` 段标记(U3) | ⬜ | 未实现 | — | +| selftest(U5) | 🔶 | KAT/段表/越界已覆盖;chacha20 KAT 间歇 FAIL 待修 | `test/utsm_selftest.c` | +| 真实加密原语 | 🔶 | chacha20/KDF/MAC 已落(Phase 9 早期),PCKC schedule 待接 | `crypto/` | + +## DKM 驱动系统 + +| 子系统 | 状态 | 边界/说明 | 证据 | +|--------|------|----------|------| +| ELF64 .drv 加载(4 stage) | ✅ | 14/14 驱动装载 + driver_init | QEMU 启动日志 | +| 驱动列表(timer/acpi/pci/ahci/nvme/bootfs/vfs/devfs/fat32/ps2kbd/e1000/virtio_net/console_fb/apic) | ✅ | 能力各异,见下行分项 | manifest.json | +| AHCI | ✅ | IDENTIFY/READ/WRITE DMA + ahci0 provider | — | +| NVMe | 🔶 | PCI discovery only,BAR0>4G 待映射 | — | +| FAT32(DKM 侧) | 🔶 | 只读,子目录路径待完善 | — | +| e1000 | ✅ | RX/TX + DHCP/ARP/UDP/DNS(polling) | — | +| virtio_net | 🔶 | PCI/capability 枚举,无 virtqueue | — | +| 热卸载(D1) | ⬜ | 仅有 NO_UNLOAD 标志与状态机文档 | — | +| 按名 API 导出表(D3) | ⬜ | 固定偏移 struct ABI | `CODE/sdk/include/deshab/kernel_api.h` | +| 彩色日志(D4) | ⬜ | 仅 info/warn/error/panic | — | + +## DSK 主内核 / 用户态 + +| 子系统 | 状态 | 边界/说明 | 证据 | +|--------|------|----------|------| +| 启动 Logo(静态莲花) | ✅ | 旋转加载环已移除 | QEMU 现象 | +| FirstInit 向导 | 🔶 | 输入+SHA256+写盘闭环;按键崩溃未复现(B6) | `.build_tmp/qemu_serial_b6.log` | +| 可跳过 FirstInit(F5) | ✅ | `[dsk] skip_firstinit=1` 直达 desktop,跳过向导与登录 | `.build_tmp/qemu_serial_f1f4f5.log` | +| mouseInit(PS/2 鼠标) | ✅ | IRQ12 + 包解码 + 光标(M1) | `.build_tmp/qemu_serial_mouse.log` | +| desktop.elf | ✅ | 三页面+窗口+任务栏+双缓冲 | — | +| shell.elf | ✅ | 25+ 命令(ls/cat/cp/mv/run/probe/test/pci…) | — | +| login.elf | ✅ | USER.CONF + skip_login | — | +| PE/EXE 兼容层 | ✅ | PE32+ 原生 / PE32 走 x86emu32 | — | +| Linux 兼容层 | 🔶 | VMM+park-and-resume;VMX 实机验证待 VT-x/KVM | — | +| Pacman | ⬜ | 五阶段方案 | — | + +## 调度 / 恢复 + +| 子系统 | 状态 | 边界/说明 | 证据 | +|--------|------|----------|------| +| SAS-R0-PCQ 调度器 | 🔶 | O(1) 位图 + LAPIC tick + xv6 式切换 ✅;BSP-only,per-cpu 多核 ⬜ | `.build_tmp/qemu_serial_sched_m4.log` | +| task_kill crypto erase | ⬜ | key_epoch++ 待做 | — | +| DRR checkpoint(R1) | ✅ | dirty shard → dma 页快照 + A/B 双槽 + CRC64 原子切换 | M4 QEMU 日志 | +| DRR 回滚(R4) | 🔶 | page 级 + BLAKE2b keyed 页 MAC ✅;segment/system 级待验证 | M4 QEMU 日志 | +| DRR 看门狗(R2) | ✅ | timeout 检出→回滚/复位;负向测试 PASS | M4 QEMU 日志 | +| Emergency Pool(R3) | ✅ | 64KB 编译期独立池;`drr_emergency_pool_kb` 键未接线 ⬜ | `include/utsm/drr.h` | + +## 文档体系 + +| 文档 | 状态 | 说明 | +|------|------|------| +| [STATUS.md](./STATUS.md) | ✅ | 单一状态源(本文件) | +| [ROADMAP_INSANE.md](./ROADMAP_INSANE.md) | ✅ | 五期填补计划(唯一任务编号 F/U/D/R/E) | +| [TASKBOARD.md](./TASKBOARD.md) | ✅ | 可勾选任务表 | +| [PHILOSOPHY.md](./PHILOSOPHY.md) | ✅ | 疯圣典 | +| [ROADMAP.md](./ROADMAP.md) | ✅ | Phase 0–9 历史存档 + 用户态主线 | +| [ARCHITECTURE.md](./ARCHITECTURE.md) | ✅ | 架构 + 非目标章 | +| [BOOT_SEQUENCE.md](./BOOT_SEQUENCE.md) | ✅ | B0–B4 演示版 | +| ~~系统开发策划.md~~ | 已删除 | 状态与本表矛盾,收编于此 | diff --git a/docs/TASKBOARD.md b/docs/TASKBOARD.md new file mode 100644 index 0000000..26afc52 --- /dev/null +++ b/docs/TASKBOARD.md @@ -0,0 +1,55 @@ +# Deshab-OS 任务板 + +> 按 [ROADMAP_INSANE.md](./ROADMAP_INSANE.md) 五期编号的可勾选任务表。 +> 状态:✅ 已实现 · 🔶 演示级 · ⬜ 仅设计。唯一状态源见 [STATUS.md](./STATUS.md)。 + +## 🔩 一期:骨架 + +- [x] F1 内核 panic 统一兜底(莲花崩溃屏 + panic_symbol + DRR 归档) +- [x] F4 boot_ok 分级启动自检(`[boot] selftest=0|1|2`) +- [x] F5 可跳过 FirstInit(`[dsk] skip_firstinit` + build/configs 模板) +- [ ] F2 统一帧缓冲控制台抽象(console_fb 雏形 🔶) +- [ ] F3 跨平台构建(Make/CMake) + +## 🗝️ 二期:仪式(UTSM/UTRW) + +- [x] U1 UTSM 元数据区 / UUID 调谐表 +- [ ] U2 UTRW Slow Path 真分支(Fast path ✅;slow_path.c 现为 stub) +- [ ] U3 `@sealed` 段可选标记(链接脚本 `__sealed` section) +- [ ] U4 密文页 dump 工具(明文/密文对照命令) +- [ ] U5 UTSM selftest 全覆盖(修 chacha20 KAT 间歇 FAIL,覆盖率 ≥70%) + +## 🔌 三期:自由(DKM/用户态) + +- [x] D5 最小 REPL/shell(shell.elf 25+ 命令) +- [ ] D1 DKM 热卸载(引用计数 + 资源回收,循环 100 次不崩) +- [ ] D2 裸机器码加载器 +- [ ] D3 内核 API 按名导出表(kapi()) +- [ ] D4 DKM 彩色日志前缀 + +## ⏪ 四期:落款(DRR/PCQ) + +- [x] R1 checkpoint 快照(A/B 双槽 + CRC64 + 原子切换) +- [x] R2 看门狗(timeout 检出 + 回滚/复位,负向测试 PASS) +- [x] R3 Emergency Pool(64KB 编译期独立池) +- [ ] R3b `drr_emergency_pool_kb` / `drr_recovery_log_size` FUCK 键接线 +- [ ] R4 A/B 回滚收尾(segment/system 级验证,依赖真实加密) +- [ ] R5 PCQ 多核(per-cpu runqueue 负载均衡;BSP-only 🔶) + +## 🪷 五期:品牌 + +- [x] E5 疯圣典进 docs/(PHILOSOPHY.md) +- [ ] E1 启动莲花动画 +- [ ] E2 "假想时光键"彩蛋 +- [ ] E3 提交信息规范(疯洁版) +- [ ] E4 deshab-fuckyou-edition 风味 ISO + +--- + +## 遗留工程债(Phase 存档,非五期编号) + +- [ ] Vector allocator / MSI-X +- [ ] NVMe 高位 BAR MMIO(BAR0>4G) +- [ ] virtio-net virtqueue RX/TX +- [ ] FAT32 完整子目录路径解析(DKM 侧) +- [ ] DKM 零 warning + 统一 ABI 头 diff --git a/docs/系统开发策划.md b/docs/系统开发策划.md deleted file mode 100644 index 4cdc9fd..0000000 --- a/docs/系统开发策划.md +++ /dev/null @@ -1,233 +0,0 @@ -# Deshab 系统开发策划 - -> 文档盘点、实现矩阵、阻塞风险、里程碑策划。ROADMAP的补充(补上兼容层/桌面/包管理等用户态生态主线)。 - ---- - -## 一、文档整理 - -### 1.1 文档地图 - -```text -docs/ARCHITECTURE.md 五大支柱+子系统现状 -docs/BOOT_SEQUENCE.md 五阶段启动模型 -docs/ROADMAP.md Phase 0–9路线图 -docs/系统开发策划.md ← 本文档 -docs/兼容层设计.md Linux/PE兼容层 -docs/桌面设计.md 桌面环境 -docs/RE/ UTSM_设计架构/算法记录/驱动模块ABI设计/Bug记录(12条)/test-cases(8份)/docs/ -docs/上下文/ 开发对话记录(待提炼为正式设计文档) -``` - -### 1.2 文档同步状态 - -2026-07-29已同步:ROADMAP/ARCHITECTURE/BOOT_SEQUENCE/Bug记录。关键偏差均已修正(如§9.2旋转环描述、console_fb圆弧已移除、B4正常路径已实现login→desktop)。 - -**关键发现**:`docs/上下文/`下四份开发记录(双内核/Linux EXE/桌面UI/Pacman)构成ROADMAP未收录的**用户态与生态主线**。 - ---- - -## 二、实现盘点 - -### 2.1 子系统实现状态矩阵 - -| 子系统 | 状态 | 主要缺口 | -|--------|------|---------| -| 早期启动(serial/IDT/PIC) | ✅ | — | -| DKM驱动加载(14驱动) | ✅ | ABI头未统一、warning未清零 | -| DMA分配器 | ✅ | — | -| UTSM封缄内存 | 🔶 | 真实加密原语未选型 | -| AHCI块设备 | ✅ | 单扇区偶发超时 | -| NVMe | ✅ | 写路径+PRP list+读回校验已完成 | -| FAT32 | 🔶 | DKM只读;DSK读写(根目录),子目录写待补 | -| e1000网络 | ✅ | 中断驱动收发(仍polling) | -| virtio_net | ✅ | virtqueue RX/TX+netdev注册+DHCP自测已完成 | -| 字体系统 | ✅ | — | -| FirstInit | 🔶 | B6按键崩溃修复中;鼠标仍轮询 | -| 正常启动路径 | ✅ | — | -| desktop.elf | ✅ | 脏矩形未做 | -| shell.elf / cmd.elf | ✅ | — | -| Linux兼容层 | 🔶 | VMX实机验证待做(需嵌套虚拟化环境) | -| PE/EXE兼容层 | ✅ | Win32 API覆盖少 | -| virtio-mmio模拟 | 🔶 | blk已支撑guest rootfs;net后端未在guest验证 | -| SAS-R0-PCQ调度器 | ⬜ | 未实现 | -| DRR恢复系统 | ⬜ | 未实现 | -| 真实加密 | ⬜ | 原语未选型 | -| Pacman包管理 | 🔶 | 依赖VMX验证+virtio-net后端 | - -### 2.2 关键能力清单 - -- **kernel_api**:log/rsdp/fb_*/boot_modules/irq_register/hhdm/dma.alloc_pages/block(read@+0xA8,write@+0x18)/net -- **dsk_boot_context**:magic `0x44534B31424F4F54`,reserved[4]=pe_service,reserved[5]=linux_compat_service -- **PE service**:load/run/unload(PE32+原生Ring0,PE32走x86emu32) -- **Linux compat service**:exec(path,argv)→IPC EXEC_REQUEST(16)→daemon fork+exec→STDOUT/STDERR/EXIT -- **IPC**:1MB共享内存@GPA 0x04000000,9+5 hypercall,VMCALL RAX=`0x5554534D48430000|op` -- **FAT32**:f32_read_root_file / f32_write_root_file - ---- - -## 三、阻塞与风险 - -### 3.1 关键阻塞点 - -| # | 阻塞点 | 严重度 | 缓解 | -|---|--------|--------|------| -| B1 | ~~block write~~ ✅已解决 | — | AHCI WRITE DMA+block_api.write已落地 | -| B2 | ~~高位PCI MMIO映射缺失~~ ✅已解决 | — | NVMe BAR0可读,写路径+PRP list+读回校验通过 | -| B3 | ~~WSL构建阻塞~~ ✅已解决 | — | bzImage/initrd/rootfs已产出 | -| **B4** | QEMU TCG不支持VMX | P0 | 真机VT-x/KVM/云VM验证;WHPX检测已落地 | -| B5 | ~~fileman QEMU exit~~ ✅已解决 | — | linker.ld BSS NOBITS分离+g_elf_image扩至1MB | -| **B6** | FirstInit按键崩溃 | P1 | fb_text边界检查+编译优化降级调试中 | -| **B7** | APIC/IOAPIC stage1+2 已落地 + NVMe MSI-X 完成 | P2 | UTSM LAPIC EOI 钩子已落地;vector allocator 已落地;NVMe MSI-X 已完成;剩余:virtio_net/e1000 MSI-X、真机冒烟 | - -### 3.2 风险登记 - -| 风险 | 概率 | 影响 | 应对 | -|------|------|------|------| -| VMX实机验证长期受阻 | 中 | 高 | 构建产物已就位;窗口期内争取验证,失败则冻结运行时 | -| ROADMAP与实现态偏离 | 高 | 中 | 本次整理后同步 | -| docs/上下文/对话膨胀 | 高 | 中 | 提炼为正式设计文档 | -| UTSM真实加密原语选型拖延 | 中 | 高 | Phase 9前完成PoC | -| PE32+原生执行安全风险 | 中 | 中 | PE shim白名单+IAT拦截审计 | - ---- - -## 四、开发策划 - -### 4.1 策划原则 - -先闭环再扩展;解阻塞优先于新功能;内核主线与生态主线并行;不破坏SAS-R0/O(1)热路径;文档与代码同步。 - -### 4.2 里程碑总览 - -```text -M1 持久化闭环+桌面稳定 (2–4周) B1→FAT32 write→FirstInit写盘→桌面bug -M2 存储升级+中断后端 (4–8周) B2高位MMIO→NVMe→B7 APIC/IOAPIC/MSI-X→e1000中断驱动 -M3 兼容层验证 (与M2并行) B3/B4→Linux guest→IPC→Arch rootfs -M4 调度器+恢复+加密 (8–16周) SAS-R0-PCQ→DRR→真实加密 -M5 软件生态 (依赖M3) Pacman→AUR→desktop集成 -``` - -### 4.3 M1 — 持久化闭环+桌面稳定 - -| 任务 | 验收标准 | -|------|---------| -| AHCI WRITE DMA | dkm_block_api.write注册 | -| FAT32文件覆写/创建 | f32_write_root_file可写user.conf/firstInit.txt | -| FAT32 FAT链分配 | 新文件可创建、可追加 | -| FirstInit user.conf写盘 | 重启后login可读取 | -| FirstInit鼠标光标 | PS/2 IRQ12+包解码+24×24光标 | -| 桌面fileman崩溃修复(B5) | fileman可正常使用 | -| FirstInit按键崩溃修复(B6) | -O2下fb_text稳定 | - -### 4.4 M2 — 存储升级+中断后端 - -| 任务 | 验收标准 | 进度 | -|------|---------|------| -| 页表映射接口 | mmio_map/unmap通用接口 | ✅ | -| 高位PCI MMIO映射(B2) | NVMe BAR0可读register | ✅(NVMe 数据路径已验证) | -| 替换arena为真实页分配 | 移除16MB arena上限 | | -| NVMe admin queue/identify+block provider | 注册nvme0 | ✅ 写路径+PRP list+读回校验完成 | -| IDT扩展256 vectors+vector allocator | 动态分配中断向量 | ✅ bitmap+ctzll,0x40-0xDF池,O(1)(commit 019585f) | -| APIC EOI→IOAPIC redirection→LAPIC timer | 替代PIC | ✅ stage1+2 完成(LAPIC接管/MADT/IOREDTBL/apic_route开关/tick链路验证/LAPIC EOI钩子/legacy IRQ1/12/11持续投递验证) | -| MSI/MSI-X | NVMe/e1000使用MSI-X | 🔶 NVMe MSI-X 完成(nvme_msi开关+幽灵CQE防御);virtio_net MSI-X 未完成(W6-B丢失);e1000 仍 legacy IRQ11 | -| e1000中断驱动收发 | 替代polling | ⬜ 仍 polling(走 legacy IRQ11 已通,MSI 切换待做) | -| virtio-net virtqueue RX/TX | 收发包成功 | ✅ virtqueue RX/TX+netdev注册+DHCP自测完成(纯轮询,MSI-X 待做) | -| DKM工程化收尾 | 统一ABI头、零warning | | -| QEMU测试套件脚本化 | Run-All 全用例自动化 | ✅ 9 用例(8+deaicup-e2e)全自动化 PASS | - -### 4.5 M3 — 兼容层验证 - -| 任务 | 验收标准 | -|------|---------| -| Linux 6.6 LTS构建+VMX运行环境 | bzImage+initramfs生成,真机VT-x或KVM可用 | -| VMX自测→Linux guest跑到shell | initramfs busybox shell可交互 | -| utsm_exec_daemon运行 | EXEC_READY(20)发送,park生效 | -| virtio-blk/net后端验证 | guest内可读写块/DHCP/ping | -| IPC exec全链路 | `linux ls`→stdout回显 | -| Arch rootfs bootstrap | pacman可用 | - -### 4.6 M4 — 调度器+恢复+加密 - -| 任务 | 验收标准 | -|------|---------| -| SAS-R0-PCQ: TCB+task_create, Per-CPU runqueue, O(1)位图调度, context_switch(只加载crypto指针), task_kill crypto erase | 多任务调度运行 | -| DRR: Emergency Pool, Watchdog, Recovery log, Dirty Shard+Bitmap, A/B Checkpoint双槽, 三级Rollback, 驱动recovery ops | checkpoint/rollback演示 | -| 真实加密: 原语选型PoC(HKDF+AES-CTR+Poly1305), KDF, Stream cipher(64B line), MAC(4KB page), PCKC真实key schedule | UTSM真实加密selftest通过 | - -### 4.7 M5 — 软件生态 - -| 任务 | 验收标准 | -|------|---------| -| FILE_TRANSFER+EXEC_FORWARD hypercall | 跨内核文件传输+命令委托 | -| shell path_search_and_run扩展 | PATH命中stub→IPC委托 | -| pacman装包+AUR helper | `pacman -S `成功 | -| desktop动态Linux命令图标 | 点击图标运行Linux应用 | - -### 4.8 依赖关系 - -```text -B1(block write)→FAT32 write→user.conf写盘→M1闭环 -B2(高位MMIO)→NVMe; B7(IRQ后端)→APIC/IOAPIC/MSI-X→e1000中断驱动+virtio-net -B3(Linux构建)+B4(VMX环境)→VMX验证→guest shell→daemon→IPC→Arch rootfs -M1→M4调度器→DRR→真实加密; Arch rootfs→M5 Pacman→AUR→desktop集成 -``` - ---- - -## 五、文档治理建议 - -**立即**:同步ROADMAP状态标记;结构化Bug记录(BUG-YYYYMMDD-NNN模板)。 - -**中期**:`docs/上下文/双内核+Linux_EXE`→`docs/兼容层设计.md`;`docs/上下文/桌面UI`→`docs/桌面设计.md`;Pacman→合并进兼容层设计§生态。 - -**长期**:PR必须同步ROADMAP+设计文档;test-cases关联可执行脚本;CLAUDE.md季度回顾。 - ---- - -## 六、附录:关键技术参考速查 - -### 6.1 关键地址与魔数 - -| 项 | 值 | -|----|-----| -| dsk_boot_context.magic | `0x44534B31424F4F54` "DSK1BOOT" | -| dkm_driver_desc.magic | `0x444B4D31` "DKM1" | -| VMCALL RAX | `0x5554534D48430000|op` "UTSMHC\0\0" | -| IPC共享内存GPA | `0x04000000`(1MB) | -| Linux guest RAM GPA | `0x05000000+`(64MB) | -| block_read偏移 | `kernel_api + 0xA8`(read@+0x10, write@+0x18) | -| pe_service槽 | `reserved[4]` | -| linux_compat_service槽 | `reserved[5]` | -| IPC exec消息号 | 16–20 | -| ipc_exec_request约束 | ≤240字节 | -| virtio-blk/net IRQ | 5/6(向量0x35/0x36) | - -### 6.2 关键约束清单 - -- 进入C前cli/cld;早期serial不无限等待ready位 -- 未启用SSE前-mno-sse -mno-sse2 -mno-mmx -msoft-float -- DATA/BSS用PF_R|PF_W|PF_X -- DSK ibuf 1MB;g_dsk_fat32_filedata 2MB;g_fdata 1MB -- FAT32批量读≥8扇区(推荐256);DSK linker.ld BSS分离NOBITS -- mkfat32.ps1 Name83正好11字符;Linux guest cmdline含nohlt idle=poll -- VMCS不保存guest GPR,vmexit_asm.S保存16个GPR到g_guest_regs -- 调度热路径禁止扫描capability/计算MAC/写checkpoint/重加密 -- DRR recovery路径禁止依赖普通堆;PE32+用__attribute__((ms_abi)) shim - -### 6.3 关键文件索引 - -| 模块 | 文件 | -|------|------| -| UTSM入口 | `CODE/UTSM/kernel/main.c` | -| DSK加载 | `CODE/UTSM/kernel/dsk_loader.c` | -| boot context | `CODE/UTSM/include/utsm/dsk.h` | -| VMM | `CODE/UTSM/vmm/vmm.c/vmexit.c/linux_boot.c/linux_resume.c/vmexit_asm.S` | -| PE兼容层 | `CODE/UTSM/pe/pe_service.c/pe_loader.c/pe_shim.c/x86emu32.c` | -| Linux compat | `CODE/UTSM/vmm/linux_compat.c` | -| IPC | `CODE/utsm-ipc/ipc_proto.h` | -| exec daemon | `CODE/linux/initramfs/bin/utsm_exec_daemon.c` | -| DSK | `CODE/dsk/main.c` | -| 桌面 | `CODE/desktop/main.c` | -| shell/cmd | `CODE/shell/main.c`, `CODE/cmd/main.c` | -| FAT32镜像 | `.build_tmp/mkfat32.ps1` | diff --git a/ohMyLogo.png b/ohMyLogo.png new file mode 100644 index 0000000..98c5bfc Binary files /dev/null and b/ohMyLogo.png differ