diff --git a/.gitmodules b/.gitmodules index 1f53219e..2c5ce1fb 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ -[submodule "riscv-pk"] - path = riscv-pk - url = https://github.com/rcore-os/riscv-pk.git [submodule "user"] path = user url = https://github.com/rcore-os/rcore-user.git diff --git a/crate/memory/src/memory_set/mod.rs b/crate/memory/src/memory_set/mod.rs index 77eddc19..94d87650 100644 --- a/crate/memory/src/memory_set/mod.rs +++ b/crate/memory/src/memory_set/mod.rs @@ -56,7 +56,9 @@ impl MemoryArea { } /// Check the array is within the readable memory fn check_read_array(&self, ptr: *const S, count: usize) -> bool { - ptr as usize >= self.start_addr && unsafe { ptr.add(count) as usize } <= self.end_addr + // page align + ptr as usize >= Page::of_addr(self.start_addr).start_address() + && unsafe { ptr.add(count) as usize } < Page::of_addr(self.end_addr + PAGE_SIZE - 1).start_address() } /// Check the array is within the writable memory fn check_write_array(&self, ptr: *mut S, count: usize) -> bool { diff --git a/kernel/Cargo.lock b/kernel/Cargo.lock index a4eacbc0..4848e5e3 100644 --- a/kernel/Cargo.lock +++ b/kernel/Cargo.lock @@ -393,21 +393,21 @@ dependencies = [ "riscv 0.5.0 (git+https://github.com/rcore-os/riscv)", "smoltcp 0.5.0 (git+https://github.com/rcore-os/smoltcp)", "spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "uart_16550 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "uart_16550 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "volatile 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "x86_64 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "x86_64 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "xmas-elf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rcore-fs" version = "0.1.0" -source = "git+https://github.com/rcore-os/rcore-fs#d7a2006cc316c98b7050aec63a2770dd690a4a80" +source = "git+https://github.com/rcore-os/rcore-fs#64d399fe664927f14853c22943a4bdeb34095f99" [[package]] name = "rcore-fs-sfs" version = "0.1.0" -source = "git+https://github.com/rcore-os/rcore-fs#d7a2006cc316c98b7050aec63a2770dd690a4a80" +source = "git+https://github.com/rcore-os/rcore-fs#64d399fe664927f14853c22943a4bdeb34095f99" dependencies = [ "bitvec 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -555,11 +555,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "uart_16550" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "x86_64 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", + "x86_64 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -615,18 +615,6 @@ dependencies = [ "raw-cpuid 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "x86_64" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "os_bootinfo 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "usize_conversions 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ux 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "x86_64" version = "0.3.6" @@ -642,7 +630,7 @@ dependencies = [ [[package]] name = "x86_64" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "array-init 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -734,7 +722,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" "checksum tock-registers 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3a385d94f3f62e60445a0adb9ff8d9621faa272234530d4c0f848ec98f88e316" "checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" -"checksum uart_16550 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "269f953d8de3226f7c065c589c7b4a3e83d10a419c7c3b5e2e0f197e6acc966e" +"checksum uart_16550 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b9392f60931fe3bf8f24e0a15ee4f51528770f1d64c48768ab66571334d95b0" "checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum usize_conversions 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f70329e2cbe45d6c97a5112daad40c34cd9a4e18edb5a2a18fefeb584d8d25e5" @@ -744,8 +732,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" "checksum x86 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "841e1ca5a87068718a2a26f2473c6f93cf3b8119f9778fa0ae4b39b664d9e66a" -"checksum x86_64 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "2bd647af1614659e1febec1d681231aea4ebda4818bf55a578aff02f3e4db4b4" "checksum x86_64 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f9258d7e2dd25008d69e8c9e9ee37865887a5e1e3d06a62f1cb3f6c209e6f177" -"checksum x86_64 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8f7e92e985f4052118fd69f2b366c67e91288c0f01f4ae52610dce236425dfa0" +"checksum x86_64 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1d0a8201f52d2c7b373c7243dcdfb27c0dd5012f221ef6a126f507ee82005204" "checksum xmas-elf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "22678df5df766e8d1e5d609da69f0c3132d794edf6ab5e75e7abcd2270d4cf58" "checksum zero 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5f1bc8a6b2005884962297587045002d8cfb8dcec9db332f4ca216ddc5de82c5" diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index 5d95f9c6..c4ce68cb 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -19,6 +19,7 @@ authors = [ ] [features] +default = ["sv39"] # Page table sv39 or sv48 (for riscv64) sv39 = [] board_u540 = ["sv39", "link_user"] @@ -31,6 +32,8 @@ board_malta = ["link_user"] board_mipssim = ["link_user"] # for thinpad board_thinpad = ["link_user"] +# for x86 PC +board_pc = ["link_user"] # Hard link user program link_user = [] # Run cmdline instead of user shell, useful for automatic testing @@ -68,7 +71,7 @@ bootloader = { git = "https://github.com/rcore-os/bootloader" } apic = { git = "https://github.com/rcore-os/apic-rs" } x86_64 = "0.5" raw-cpuid = "6.0" -uart_16550 = "0.1" +uart_16550 = "0.2" pc-keyboard = "0.5" [target.'cfg(any(target_arch = "riscv32", target_arch = "riscv64"))'.dependencies] diff --git a/kernel/Makefile b/kernel/Makefile index 41f4e42f..af393e3e 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -33,8 +33,8 @@ arch ?= riscv64 board ?= none -mode ?= debug -LOG ?= debug +mode ?= release +LOG ?= graphic ?= off smp ?= 4 pci_passthru ?= @@ -58,16 +58,13 @@ ifeq ($(arch), $(filter $(arch), aarch64 mipsel)) #link user img, so use original image export SFSIMG = $(user_dir)/build/$(arch).img else -ifeq ($(arch), x86_64) # board is pc or qemu? ifeq ($(board), pc) #link user img, so use original image export SFSIMG = $(user_dir)/build/$(arch).img -features += link_user else export SFSIMG = $(user_dir)/build/$(arch).qcow2 endif # pc or qemu -endif # x86_64 endif # aarch64 mipsel ifeq ($(arch), aarch64) @@ -98,17 +95,16 @@ qemu_net_opts := ifeq ($(arch), x86_64) qemu_opts += \ - -drive format=raw,file=$(bootimage) + -drive format=raw,file=$(bootimage) \ + -serial mon:stdio \ + -m 4G \ + -device isa-debug-exit ifeq ($(board), none) qemu_opts += \ -drive format=qcow2,file=$(SFSIMG),media=disk,cache=writeback,id=sfsimg,if=none \ -device ahci,id=ahci0 \ -device ide-drive,drive=sfsimg,bus=ahci0.0 endif -qemu_opts += \ - -serial mon:stdio \ - -m 4G \ - -device isa-debug-exit ifeq ($(pci_passthru), ) qemu_net_opts += \ -netdev type=tap,id=net0,script=no,downscript=no \ @@ -128,7 +124,8 @@ endif else ifeq ($(arch), riscv32) qemu_opts += \ -machine virt \ - -kernel $(kernel_img) \ + -kernel ../tools/opensbi/virt_rv32.elf \ + -device loader,addr=0x80400000,file=$(kernel_img) \ -drive file=$(SFSIMG),format=qcow2,id=sfs \ -device virtio-blk-device,drive=sfs qemu_net_opts += \ @@ -136,11 +133,19 @@ qemu_net_opts += \ -device virtio-net-device,netdev=net0 else ifeq ($(arch), riscv64) +ifeq ($(board), u540) qemu_opts += \ -machine virt \ - -kernel $(kernel_img) \ + -kernel ../tools/opensbi/fu540.elf \ + -device loader,addr=0x80200000,file=$(kernel_img) +else +qemu_opts += \ + -machine virt \ + -kernel ../tools/opensbi/virt_rv64.elf \ + -device loader,addr=0x80200000,file=$(kernel_img) \ -drive file=$(SFSIMG),format=qcow2,id=sfs \ -device virtio-blk-device,drive=sfs +endif qemu_net_opts += \ -netdev type=tap,id=net0,script=no,downscript=no \ -device virtio-net-device,netdev=net0 @@ -201,11 +206,9 @@ features += sv39 riscv_pk_args += --enable-sv39 endif -ifneq ($(arch), x86_64) ifneq ($(board), none) features += board_$(board) endif -endif build_args := --target targets/$(target).json --features "$(features)" @@ -303,28 +306,8 @@ ifeq ($(need_bootloader), true) endif $(kernel_img): kernel $(bootloader) -ifeq ($(arch), riscv32) - @mkdir -p target/$(target)/bbl && \ - cd target/$(target)/bbl && \ - $(bbl_path)/configure \ - $(riscv_pk_args) \ - --with-arch=rv32imac \ - --disable-fp-emulation \ - --host=riscv64-unknown-elf \ - --with-payload=$(abspath $(kernel)) && \ - make -j && \ - cp bbl $(abspath $@) -else ifeq ($(arch), riscv64) - @mkdir -p target/$(target)/bbl && \ - cd target/$(target)/bbl && \ - $(bbl_path)/configure \ - $(riscv_pk_args) \ - --with-arch=rv64imac \ - --disable-fp-emulation \ - --host=riscv64-unknown-elf \ - --with-payload=$(abspath $(kernel)) && \ - make -j && \ - cp bbl $(abspath $@) +ifeq ($(arch), $(filter $(arch), riscv32 riscv64)) + @$(objcopy) $(kernel) --strip-all -O binary $@ else ifeq ($(arch), aarch64) ifneq ($(u_boot), ) @cp $(u_boot) $@ @@ -341,13 +324,7 @@ kernel: $(dtb) ifeq ($(arch), x86_64) @bootimage build $(build_args) @mv target/x86_64/bootimage.bin $(bootimage) -else ifeq ($(arch), riscv32) - @-patch -p0 -N -b \ - $(shell rustc --print sysroot)/lib/rustlib/src/rust/src/libcore/sync/atomic.rs \ - src/arch/riscv32/atomic.patch - @cargo xbuild $(build_args) -else ifeq ($(arch), riscv64) - @cp src/arch/riscv32/board/u540/linker.ld src/arch/riscv32/boot/linker64.ld +else ifeq ($(arch), $(filter $(arch), riscv32 riscv64)) @-patch -p0 -N -b \ $(shell rustc --print sysroot)/lib/rustlib/src/rust/src/libcore/sync/atomic.rs \ src/arch/riscv32/atomic.patch @@ -389,7 +366,8 @@ endif ifeq ($(board), u540) .PHONY: install: $(kernel_img) - @$(objcopy) -S -O binary --change-addresses -0x80000000 $< $(build_path)/bin + @$(objcopy) -S -O binary ../tools/opensbi/fu540.elf $(build_path)/bin + @dd if=$< of=$(build_path)/bin bs=131072 seek=16 @../tools/u540/mkimg.sh $(build_path)/bin $(build_path)/sd.img endif diff --git a/kernel/events b/kernel/events deleted file mode 100644 index d99bc242..00000000 --- a/kernel/events +++ /dev/null @@ -1,62 +0,0 @@ -virtqueue_pop -virtio_blk_req_complete -virtio_blk_rw_complete -virtio_blk_submit_multireq -virtio_blk_handle_write -virtio_blk_handle_read -e1000e_link_status -e1000e_mac_set_sw -e1000e_irq_itr_set -e1000e_irq_eitr_set -e1000e_tx_disabled -e1000e_tx_descr -e1000e_rx_descr -#e1000e_rx_has_buffers -e1000e_rx_start_recv -#e1000e_rx_can_recv -e1000e_rx_can_recv_rings_full -e1000_receiver_overrun -#e1000e_rx_receive_iov -e1000e_core_ctrl_sw_reset -e1000e_core_ctrl_phy_reset -e1000e_rx_desc_buff_sizes -e1000e_rx_set_rctl -e1000e_rx_desc_len -e1000e_core_ctrl_write -e1000e_link_status_changed -e1000e_rx_rss_dispatched_to_queue -e1000e_rx_desc_buff_write -e1000e_rx_null_descriptor -e1000e_rx_set_rdt -e1000e_msix_use_vector_fail -e1000e_msix_init_fail -e1000e_msi_init_fail -e1000e_cb_pci_uninit -e1000e_cfg_support_virtio -e1000e_irq_msi_notify_postponed -e1000e_irq_msix_notify_postponed_vec -e1000e_irq_throttling_no_pending_vec -e1000e_irq_msix_notify_vec -e1000e_wrn_msix_vec_wrong -e1000e_wrn_msix_invalid -e1000e_irq_iam_clear_eiame -e1000e_irq_icr_clear_eiac -e1000e_irq_msi_notify -pci_update_mappings_del -pci_update_mappings_add -e1000e_irq_icr_write -e1000e_irq_icr_read_entry -e1000e_irq_legacy_notify -e1000e_irq_add_msi_other -e1000e_irq_pending_interrupts -e1000e_irq_icr_write -e1000e_irq_msix_notify_vec -e1000e_wrn_msix_vec_wrong -e1000e_wrn_msix_invalid -e1000e_irq_iam_clear_eiame -e1000e_irq_icr_clear_eiac -e1000e_irq_postponed_by_xitr -e1000e_intrmgr_rearm_timer -msix_* -#ahci_* -ide_* \ No newline at end of file diff --git a/kernel/src/arch/mipsel/boot/context.S b/kernel/src/arch/mipsel/boot/context.S index 534ede54..d81e9612 100644 --- a/kernel/src/arch/mipsel/boot/context.S +++ b/kernel/src/arch/mipsel/boot/context.S @@ -7,22 +7,23 @@ .globl switch_context .extern _root_page_table_ptr .extern _cur_kstack_ptr +.extern _cur_tls switch_context: // save from's registers addi sp, sp, (-4*14) sw sp, 0(a0) sw ra, 0(sp) - sw s0, 2*4(sp) - sw s1, 3*4(sp) - sw s2, 4*4(sp) - sw s3, 5*4(sp) - sw s4, 6*4(sp) - sw s5, 7*4(sp) - sw s6, 8*4(sp) - sw s7, 9*4(sp) - sw s8, 10*4(sp) - sw gp, 11*4(sp) + sw s0, 4*4(sp) + sw s1, 5*4(sp) + sw s2, 6*4(sp) + sw s3, 7*4(sp) + sw s4, 8*4(sp) + sw s5, 9*4(sp) + sw s6, 10*4(sp) + sw s7, 11*4(sp) + sw s8, 12*4(sp) + sw gp, 13*4(sp) // sw ra, 12*4(sp) // sw sp, 13*4(sp) @@ -31,27 +32,34 @@ switch_context: lw s1, 0(s0) sw s1, 4(sp) + // save TLS + la s2, _cur_tls + lw s1, 0(s2) + sw s1, 2*4(sp) + // restore to's registers lw sp, 0(a1) + + // restore page table address lw s1, 4(sp) sw s1, 0(s0) - // restore kstack ptr - // la s0, _cur_kstack_ptr - // addi s1, sp, 4 * 14 - // sw s1, 0(s0) + // restore TLS + lw s1, 2*4(sp) + sw s1, 0(s2) + mtc0 s1, $4, 2 // cp0.user_local lw ra, 0(sp) - lw s0, 2*4(sp) - lw s1, 3*4(sp) - lw s2, 4*4(sp) - lw s3, 5*4(sp) - lw s4, 6*4(sp) - lw s5, 7*4(sp) - lw s6, 8*4(sp) - lw s7, 9*4(sp) - lw s8, 10*4(sp) - lw gp, 11*4(sp) + lw s0, 4*4(sp) + lw s1, 5*4(sp) + lw s2, 6*4(sp) + lw s3, 7*4(sp) + lw s4, 8*4(sp) + lw s5, 9*4(sp) + lw s6, 10*4(sp) + lw s7, 11*4(sp) + lw s8, 12*4(sp) + lw gp, 13*4(sp) addi sp, sp, (4*14) sw zero, 0(a1) diff --git a/kernel/src/arch/mipsel/boot/trap.S b/kernel/src/arch/mipsel/boot/trap.S index 2d403436..44d48d25 100644 --- a/kernel/src/arch/mipsel/boot/trap.S +++ b/kernel/src/arch/mipsel/boot/trap.S @@ -177,3 +177,6 @@ _root_page_table_ptr: .global _cur_kstack_ptr _cur_kstack_ptr: .space 4 # 4bytes + .global _cur_tls +_cur_tls: + .space 4 # 4bytes diff --git a/kernel/src/arch/mipsel/compiler_rt.rs b/kernel/src/arch/mipsel/compiler_rt.rs deleted file mode 100644 index 04ed3c3e..00000000 --- a/kernel/src/arch/mipsel/compiler_rt.rs +++ /dev/null @@ -1,8 +0,0 @@ -//! Workaround for missing compiler-builtin symbols -//! -//! [atomic](http://llvm.org/docs/Atomics.html#libcalls-atomic) - -#[no_mangle] -pub extern "C" fn abort() { - panic!("abort"); -} diff --git a/kernel/src/arch/mipsel/consts.rs b/kernel/src/arch/mipsel/consts.rs index 48b1b82b..84ae103e 100644 --- a/kernel/src/arch/mipsel/consts.rs +++ b/kernel/src/arch/mipsel/consts.rs @@ -6,7 +6,8 @@ pub const KERNEL_OFFSET: usize = 0x80100000; pub const MEMORY_OFFSET: usize = 0x8000_0000; -pub const USER_STACK_OFFSET: usize = 0x80000000 - USER_STACK_SIZE; +pub const USER_STACK_OFFSET: usize = 0x70000000 - USER_STACK_SIZE; pub const USER_STACK_SIZE: usize = 0x10000; +pub const USER32_STACK_OFFSET: usize = 0x70000000 - USER_STACK_SIZE; pub const MAX_DTB_SIZE: usize = 0x2000; diff --git a/kernel/src/arch/mipsel/context.rs b/kernel/src/arch/mipsel/context.rs index 69f90164..ab4e5aa0 100644 --- a/kernel/src/arch/mipsel/context.rs +++ b/kernel/src/arch/mipsel/context.rs @@ -50,8 +50,8 @@ pub struct TrapFrame { pub sp: usize, pub fp: usize, pub ra: usize, - /// Reserve space for hartid - pub _hartid: usize, + /// Reserved + pub reserved: usize, } impl TrapFrame { @@ -120,6 +120,7 @@ impl InitStack { extern "C" { fn trap_return(); + fn _cur_tls(); } /// Saved registers for kernel context switches. @@ -130,17 +131,21 @@ struct ContextData { ra: usize, /// Page table token satp: usize, - /// Callee-saved registers + /// s[0] = TLS + /// s[1] = reserved + /// s[2..11] = Callee-saved registers s: [usize; 12], } impl ContextData { - fn new(satp: usize) -> Self { - ContextData { + fn new(satp: usize, tls: usize) -> Self { + let mut context = ContextData { ra: trap_return as usize, - satp, + satp: satp, ..ContextData::default() - } + }; + context.s[0] = tls; + context } } @@ -191,7 +196,7 @@ impl Context { ); InitStack { - context: ContextData::new(satp), + context: ContextData::new(satp, 0), tf: TrapFrame::new_kernel_thread(entry, arg, kstack_top), } .push_at(kstack_top) @@ -214,7 +219,7 @@ impl Context { ); InitStack { - context: ContextData::new(satp), + context: ContextData::new(satp, 0), tf: TrapFrame::new_user_thread(entry_addr, ustack_top), } .push_at(kstack_top) @@ -226,8 +231,9 @@ impl Context { /// The SATP register will be set to `satp`. /// All the other registers are same as the original. pub unsafe fn new_fork(tf: &TrapFrame, kstack_top: usize, satp: usize) -> Self { + let tls = unsafe { *(_cur_tls as *const usize) }; InitStack { - context: ContextData::new(satp), + context: ContextData::new(satp, tls), tf: { let mut tf = tf.clone(); // fork function's ret value, the new process is 0 @@ -253,11 +259,10 @@ impl Context { tls: usize, ) -> Self { InitStack { - context: ContextData::new(satp), + context: ContextData::new(satp, tls), tf: { let mut tf = tf.clone(); tf.sp = ustack_top; // sp - tf.v1 = tls; tf.v0 = 0; // return value tf }, diff --git a/kernel/src/arch/mipsel/cpu.rs b/kernel/src/arch/mipsel/cpu.rs index 932744a0..764d4721 100644 --- a/kernel/src/arch/mipsel/cpu.rs +++ b/kernel/src/arch/mipsel/cpu.rs @@ -1,6 +1,7 @@ +use mips::registers::cp0; +use mips::instructions; use crate::consts::MAX_CPU_NUM; use core::ptr::{read_volatile, write_volatile}; -use mips::registers::cp0; static mut STARTED: [bool; MAX_CPU_NUM] = [false; MAX_CPU_NUM]; @@ -21,7 +22,7 @@ pub unsafe fn start_others(hart_mask: usize) { } pub fn halt() { - /* nothing to do */ + unsafe { instructions::wait(); } } pub unsafe fn exit_in_qemu(error_code: u8) -> ! { diff --git a/kernel/src/arch/mipsel/interrupt.rs b/kernel/src/arch/mipsel/interrupt.rs index bc605472..1036ffb2 100644 --- a/kernel/src/arch/mipsel/interrupt.rs +++ b/kernel/src/arch/mipsel/interrupt.rs @@ -70,6 +70,17 @@ pub extern "C" fn rust_trap(tf: &mut TrapFrame) { E::TLBModification => page_fault(tf), E::TLBLoadMiss => page_fault(tf), E::TLBStoreMiss => page_fault(tf), + E::ReservedInstruction => { + if !reserved_inst(tf) { + error!("Unhandled Exception @ CPU{}: {:?} ", 0, tf.cause.cause()); + crate::trap::error(tf) + } else { + tf.epc = tf.epc + 4; + } + } + E::CoprocessorUnusable => { + tf.epc = tf.epc + 4; + } _ => { error!("Unhandled Exception @ CPU{}: {:?} ", 0, tf.cause.cause()); crate::trap::error(tf) @@ -149,6 +160,79 @@ fn syscall(tf: &mut TrapFrame) { } } +fn set_trapframe_register(rt: usize, val: usize, tf: &mut TrapFrame) { + match rt { + 1 => tf.at = val, + 2 => tf.v0 = val, + 3 => tf.v1 = val, + 4 => tf.a0 = val, + 5 => tf.a1 = val, + 6 => tf.a2 = val, + 7 => tf.a3 = val, + 8 => tf.t0 = val, + 9 => tf.t1 = val, + 10 => tf.t2 = val, + 11 => tf.t3 = val, + 12 => tf.t4 = val, + 13 => tf.t5 = val, + 14 => tf.t6 = val, + 15 => tf.t7 = val, + 16 => tf.s0 = val, + 17 => tf.s1 = val, + 18 => tf.s2 = val, + 19 => tf.s3 = val, + 20 => tf.s4 = val, + 21 => tf.s5 = val, + 22 => tf.s6 = val, + 23 => tf.s7 = val, + 24 => tf.t8 = val, + 25 => tf.t9 = val, + 26 => tf.k0 = val, + 27 => tf.k1 = val, + 28 => tf.gp = val, + 29 => tf.sp = val, + 30 => tf.fp = val, + 31 => tf.ra = val, + _ => { + error!("Unknown register {:?} ", rt); + crate::trap::error(tf) + } + } +} + +fn reserved_inst(tf: &mut TrapFrame) -> bool { + let inst = unsafe { + *(tf.epc as *const usize) + }; + + let opcode = inst >> 26; + let rt = (inst >> 16) & 0b11111; + let rd = (inst >> 11) & 0b11111; + let sel = (inst >> 6) & 0b111; + let format = inst & 0b111111; + + if opcode == 0b011111 && format == 0b111011 { + // RDHWR + if rd == 29 && sel == 0 { + extern "C" { + fn _cur_tls(); + } + + let tls = unsafe { + *(_cur_tls as *const usize) + }; + + set_trapframe_register(rt, tls, tf); + info!("Read TLS by rdhdr {:x} to register {:?}", tls, rt); + return true; + } else { + return false; + } + } + + false +} + fn page_fault(tf: &mut TrapFrame) { // TODO: set access/dirty bit let addr = tf.vaddr; @@ -164,6 +248,19 @@ fn page_fault(tf: &mut TrapFrame) { tlb_entry.entry_lo0.get_pfn() << 12, tlb_entry.entry_lo1.get_pfn() << 12 ); + + let tlb_valid = if virt_addr.page_number() & 1 == 0 { + tlb_entry.entry_lo0.valid() + } else { + tlb_entry.entry_lo1.valid() + }; + + if !tlb_valid { + if !crate::memory::handle_page_fault(addr) { + crate::trap::error(tf); + } + } + tlb::write_tlb_random(tlb_entry) } Err(()) => { diff --git a/kernel/src/arch/mipsel/mod.rs b/kernel/src/arch/mipsel/mod.rs index 74103db0..cf139427 100644 --- a/kernel/src/arch/mipsel/mod.rs +++ b/kernel/src/arch/mipsel/mod.rs @@ -1,4 +1,3 @@ -pub mod compiler_rt; pub mod consts; pub mod cpu; pub mod driver; diff --git a/kernel/src/arch/riscv32/board/u540/linker.ld b/kernel/src/arch/riscv32/board/u540/linker.ld deleted file mode 100644 index 6bbe85b1..00000000 --- a/kernel/src/arch/riscv32/board/u540/linker.ld +++ /dev/null @@ -1,49 +0,0 @@ -/* Copy from bbl-ucore : https://ring00.github.io/bbl-ucore */ - -/* Simple linker script for the ucore kernel. - See the GNU ld 'info' manual ("info ld") to learn the syntax. */ - -OUTPUT_ARCH(riscv) -ENTRY(_start) - -BASE_ADDRESS = 0xffffffffc0020000; - -SECTIONS -{ - /* Load the kernel at this address: "." means the current address */ - . = BASE_ADDRESS; - start = .; - - .text : { - stext = .; - *(.text.entry) - *(.text .text.*) - . = ALIGN(4K); - etext = .; - } - - .rodata : { - srodata = .; - *(.rodata .rodata.*) - . = ALIGN(4K); - erodata = .; - } - - .data : { - sdata = .; - *(.data .data.*) - edata = .; - } - - .stack : { - *(.bss.stack) - } - - .bss : { - sbss = .; - *(.bss .bss.*) - ebss = .; - } - - PROVIDE(end = .); -} diff --git a/kernel/src/arch/riscv32/board/u540/mod.rs b/kernel/src/arch/riscv32/board/u540/mod.rs index 2e9f7a62..816632da 100644 --- a/kernel/src/arch/riscv32/board/u540/mod.rs +++ b/kernel/src/arch/riscv32/board/u540/mod.rs @@ -4,7 +4,7 @@ use super::consts::KERNEL_OFFSET; pub unsafe fn init_external_interrupt() { const HART1_S_MODE_INTERRUPT_ENABLES: *mut u64 = (KERNEL_OFFSET + 0x0C00_2100) as *mut u64; const SERIAL: u64 = 4; - HART1_S_MODE_INTERRUPT_ENABLES.write(1 << SERIAL); + HART1_S_MODE_INTERRUPT_ENABLES.write_volatile(1 << SERIAL); } /// Claim and complete external interrupt by reading and writing to @@ -13,7 +13,14 @@ pub unsafe fn handle_external_interrupt() { const HART1_S_MODE_INTERRUPT_CLAIM_COMPLETE: *mut u32 = (KERNEL_OFFSET + 0x0C20_2004) as *mut u32; // claim - let source = HART1_S_MODE_INTERRUPT_CLAIM_COMPLETE.read(); + let source = HART1_S_MODE_INTERRUPT_CLAIM_COMPLETE.read_volatile(); // complete - HART1_S_MODE_INTERRUPT_CLAIM_COMPLETE.write(source); + HART1_S_MODE_INTERRUPT_CLAIM_COMPLETE.write_volatile(source); +} + +pub unsafe fn enable_serial_interrupt() { + const SERIAL_BASE: *mut u8 = (KERNEL_OFFSET + 0x10010000) as *mut u8; + const UART_REG_IE: usize = 4; + const UART_RXWM: u8 = 0x2; + SERIAL_BASE.add(UART_REG_IE).write_volatile(UART_RXWM); } diff --git a/kernel/src/arch/riscv32/board/virt/mod.rs b/kernel/src/arch/riscv32/board/virt/mod.rs new file mode 100644 index 00000000..52df8727 --- /dev/null +++ b/kernel/src/arch/riscv32/board/virt/mod.rs @@ -0,0 +1,18 @@ +use super::consts::KERNEL_OFFSET; + +/// Mask all external interrupt except serial. +pub unsafe fn init_external_interrupt() { + // By default: + // riscv-pk (bbl) enables all S-Mode IRQs (ref: machine/minit.c) + // OpenSBI v0.3 disables all IRQs (ref: platform/common/irqchip/plic.c) + + const HART0_S_MODE_INTERRUPT_ENABLES: *mut u32 = (KERNEL_OFFSET + 0x0C00_2080) as *mut u32; + const SERIAL: u32 = 0xa; + HART0_S_MODE_INTERRUPT_ENABLES.write_volatile(1 << SERIAL); +} + +pub unsafe fn enable_serial_interrupt() { + const UART16550: *mut u8 = (KERNEL_OFFSET + 0x10000000) as *mut u8; + UART16550.add(4).write_volatile(0x0B); + UART16550.add(1).write_volatile(0x01); +} diff --git a/kernel/src/arch/riscv32/boot/entry.asm b/kernel/src/arch/riscv32/boot/entry.asm deleted file mode 100644 index 3cee2fd3..00000000 --- a/kernel/src/arch/riscv32/boot/entry.asm +++ /dev/null @@ -1,19 +0,0 @@ - .section .text.entry - .globl _start -_start: - add t0, a0, 1 - slli t0, t0, 16 - - lui sp, %hi(bootstack) - addi sp, sp, %lo(bootstack) - add sp, sp, t0 - - call rust_main - - .section .bss.stack - .align 12 #PGSHIFT - .global bootstack -bootstack: - .space 4096 * 16 * 8 - .global bootstacktop -bootstacktop: diff --git a/kernel/src/arch/riscv32/boot/entry32.asm b/kernel/src/arch/riscv32/boot/entry32.asm new file mode 100644 index 00000000..22cc0eed --- /dev/null +++ b/kernel/src/arch/riscv32/boot/entry32.asm @@ -0,0 +1,55 @@ + .section .text.entry + .globl _start +_start: + # a0 == hartid + # pc == 0x80200000 + # sp == 0x800xxxxx + + # 1. set sp + # sp = bootstack + (hartid + 1) * 0x10000 + add t0, a0, 1 + slli t0, t0, 16 + lui sp, %hi(bootstack) + add sp, sp, t0 + + # 2. enable paging + # satp = (1 << 31) | PPN(boot_page_table_sv32) + lui t0, %hi(boot_page_table_sv32) + li t1, 0xc0000000 - 0x80000000 + sub t0, t0, t1 + srli t0, t0, 12 + li t1, 1 << 31 + or t0, t0, t1 + csrw satp, t0 + sfence.vma + + # 3. jump to rust_main (absolute address) + lui t0, %hi(rust_main) + addi t0, t0, %lo(rust_main) + jr t0 + + .section .bss.stack + .align 12 # page align + .global bootstack +bootstack: + .space 4096 * 16 * 8 + .global bootstacktop +bootstacktop: + + .section .data + .align 12 # page align +boot_page_table_sv32: + # NOTE: assume kernel image < 16M + # 0x80000000 -> 0x80000000 (4M * 4) + # 0xc0000000 -> 0x80000000 (4M * 4) + .zero 4 * 512 + .word (0x80000 << 10) | 0xcf # VRWXAD + .word (0x80400 << 10) | 0xcf # VRWXAD + .word (0x80800 << 10) | 0xcf # VRWXAD + .word (0x80c00 << 10) | 0xcf # VRWXAD + .zero 4 * 252 + .word (0x80000 << 10) | 0xcf # VRWXAD + .word (0x80400 << 10) | 0xcf # VRWXAD + .word (0x80800 << 10) | 0xcf # VRWXAD + .word (0x80c00 << 10) | 0xcf # VRWXAD + .zero 4 * 252 diff --git a/kernel/src/arch/riscv32/boot/entry64.asm b/kernel/src/arch/riscv32/boot/entry64.asm new file mode 100644 index 00000000..69727d5a --- /dev/null +++ b/kernel/src/arch/riscv32/boot/entry64.asm @@ -0,0 +1,48 @@ + .section .text.entry + .globl _start +_start: + # a0 == hartid + # pc == 0x80200000 + # sp == 0x800xxxxx + + # 1. set sp + # sp = bootstack + (hartid + 1) * 0x10000 + add t0, a0, 1 + slli t0, t0, 16 + lui sp, %hi(bootstack) + add sp, sp, t0 + + # 2. enable paging + # satp = (8 << 60) | PPN(boot_page_table_sv39) + lui t0, %hi(boot_page_table_sv39) + li t1, 0xffffffffc0000000 - 0x80000000 + sub t0, t0, t1 + srli t0, t0, 12 + li t1, 8 << 60 + or t0, t0, t1 + csrw satp, t0 + sfence.vma + + # 3. jump to rust_main (absolute address) + lui t0, %hi(rust_main) + addi t0, t0, %lo(rust_main) + jr t0 + + .section .bss.stack + .align 12 # page align + .global bootstack +bootstack: + .space 4096 * 16 * 8 + .global bootstacktop +bootstacktop: + + .section .data + .align 12 # page align +boot_page_table_sv39: + # 0x00000000_80000000 -> 0x80000000 (1G) + # 0xffffffff_c0000000 -> 0x80000000 (1G) + .quad 0 + .quad 0 + .quad (0x80000 << 10) | 0xcf # VRWXAD + .zero 8 * 508 + .quad (0x80000 << 10) | 0xcf # VRWXAD diff --git a/kernel/src/arch/riscv32/boot/linker.ld b/kernel/src/arch/riscv32/boot/linker.ld index bc3ba7f4..b9efafa5 100644 --- a/kernel/src/arch/riscv32/boot/linker.ld +++ b/kernel/src/arch/riscv32/boot/linker.ld @@ -6,7 +6,7 @@ OUTPUT_ARCH(riscv) ENTRY(_start) -BASE_ADDRESS = 0xC0020000; +BASE_ADDRESS = 0xC0400000; SECTIONS { diff --git a/kernel/src/arch/riscv32/boot/linker64.ld b/kernel/src/arch/riscv32/boot/linker64.ld index 6bbe85b1..87ca826c 100644 --- a/kernel/src/arch/riscv32/boot/linker64.ld +++ b/kernel/src/arch/riscv32/boot/linker64.ld @@ -6,7 +6,7 @@ OUTPUT_ARCH(riscv) ENTRY(_start) -BASE_ADDRESS = 0xffffffffc0020000; +BASE_ADDRESS = 0xffffffffc0200000; SECTIONS { diff --git a/kernel/src/arch/riscv32/consts.rs b/kernel/src/arch/riscv32/consts.rs index 45fa9985..30420545 100644 --- a/kernel/src/arch/riscv32/consts.rs +++ b/kernel/src/arch/riscv32/consts.rs @@ -22,17 +22,11 @@ pub const KERNEL_P2_INDEX: usize = (KERNEL_OFFSET >> 12 >> 10) & 0x3ff; #[cfg(target_arch = "riscv64")] pub const KERNEL_P4_INDEX: usize = (KERNEL_OFFSET >> 12 >> 9 >> 9 >> 9) & 0o777; -pub const KERNEL_HEAP_SIZE: usize = 0x00a0_0000; +pub const KERNEL_HEAP_SIZE: usize = 0x0080_0000; -#[cfg(target_arch = "riscv32")] pub const MEMORY_OFFSET: usize = 0x8000_0000; -#[cfg(target_arch = "riscv64")] -pub const MEMORY_OFFSET: usize = 0x8000_0000; - -#[cfg(target_arch = "riscv32")] -pub const MEMORY_END: usize = 0x8100_0000; -#[cfg(target_arch = "riscv64")] -pub const MEMORY_END: usize = 0x8100_0000; +// TODO: get memory end from device tree +pub const MEMORY_END: usize = 0x8800_0000; // FIXME: rv64 `sh` and `ls` will crash if stack top > 0x80000000 ??? pub const USER_STACK_OFFSET: usize = 0x80000000 - USER_STACK_SIZE; diff --git a/kernel/src/arch/riscv32/cpu.rs b/kernel/src/arch/riscv32/cpu.rs index b0a4836b..7e146da6 100644 --- a/kernel/src/arch/riscv32/cpu.rs +++ b/kernel/src/arch/riscv32/cpu.rs @@ -1,8 +1,3 @@ -use crate::consts::MAX_CPU_NUM; -use core::ptr::{read_volatile, write_volatile}; - -static mut STARTED: [bool; MAX_CPU_NUM] = [false; MAX_CPU_NUM]; - pub unsafe fn set_cpu_id(cpu_id: usize) { asm!("mv gp, $0" : : "r"(cpu_id)); } @@ -19,18 +14,6 @@ pub fn send_ipi(cpu_id: usize) { super::sbi::send_ipi(1 << cpu_id); } -pub unsafe fn has_started(cpu_id: usize) -> bool { - read_volatile(&STARTED[cpu_id]) -} - -pub unsafe fn start_others(hart_mask: usize) { - for cpu_id in 0..MAX_CPU_NUM { - if (hart_mask >> cpu_id) & 1 != 0 { - write_volatile(&mut STARTED[cpu_id], true); - } - } -} - pub fn halt() { unsafe { riscv::asm::wfi() } } diff --git a/kernel/src/arch/riscv32/io.rs b/kernel/src/arch/riscv32/io.rs index 161dfd1a..ea1e74aa 100644 --- a/kernel/src/arch/riscv32/io.rs +++ b/kernel/src/arch/riscv32/io.rs @@ -47,6 +47,3 @@ pub fn getchar_option() -> Option { pub fn putfmt(fmt: Arguments) { SerialPort.write_fmt(fmt).unwrap(); } - -const TXDATA: *mut u32 = 0x38000000 as *mut u32; -const RXDATA: *mut u32 = 0x38000004 as *mut u32; diff --git a/kernel/src/arch/riscv32/memory.rs b/kernel/src/arch/riscv32/memory.rs index a846c114..af7333b2 100644 --- a/kernel/src/arch/riscv32/memory.rs +++ b/kernel/src/arch/riscv32/memory.rs @@ -8,13 +8,17 @@ use riscv::{addr::*, register::sstatus}; /// Initialize the memory management module pub fn init(dtb: usize) { + // allow user memory access unsafe { sstatus::set_sum(); - } // Allow user memory access - // initialize heap and Frame allocator + } + // initialize heap and Frame allocator init_frame_allocator(); init_heap(); // remap the kernel use 4K page + unsafe { + super::paging::setup_recursive_mapping(); + } remap_the_kernel(dtb); } @@ -93,7 +97,7 @@ fn remap_the_kernel(dtb: usize) { Linear::new(offset), "dts", ); - // map PLIC for HiFiveU + // map PLIC for HiFiveU & VirtIO let offset = -(KERNEL_OFFSET as isize); ms.push( KERNEL_OFFSET + 0x0C00_2000, @@ -109,6 +113,22 @@ fn remap_the_kernel(dtb: usize) { Linear::new(offset), "plic1", ); + // map UART for HiFiveU + ms.push( + KERNEL_OFFSET + 0x10010000, + KERNEL_OFFSET + 0x10010000 + PAGE_SIZE, + MemoryAttr::default(), + Linear::new(offset), + "uart", + ); + // map UART for VirtIO + ms.push( + KERNEL_OFFSET + 0x10000000, + KERNEL_OFFSET + 0x10000000 + PAGE_SIZE, + MemoryAttr::default(), + Linear::new(offset), + "uart16550", + ); unsafe { ms.activate(); } diff --git a/kernel/src/arch/riscv32/mod.rs b/kernel/src/arch/riscv32/mod.rs index 650e881c..1b30ad30 100644 --- a/kernel/src/arch/riscv32/mod.rs +++ b/kernel/src/arch/riscv32/mod.rs @@ -1,6 +1,10 @@ #[cfg(feature = "board_u540")] #[path = "board/u540/mod.rs"] mod board; +#[cfg(not(feature = "board_u540"))] +#[path = "board/virt/mod.rs"] +mod board; + pub mod compiler_rt; pub mod consts; pub mod cpu; @@ -13,19 +17,24 @@ mod sbi; pub mod syscall; pub mod timer; +use self::consts::{KERNEL_OFFSET, MEMORY_OFFSET}; +use core::sync::atomic::{AtomicBool, Ordering}; use log::*; #[no_mangle] -pub extern "C" fn rust_main(hartid: usize, dtb: usize, hart_mask: usize) -> ! { - // An initial recursive page table has been set by BBL (shared by all cores) +pub extern "C" fn rust_main(hartid: usize, device_tree_paddr: usize) -> ! { + let device_tree_vaddr = device_tree_paddr - MEMORY_OFFSET + KERNEL_OFFSET; unsafe { cpu::set_cpu_id(hartid); } if hartid != BOOT_HART_ID { - while unsafe { !cpu::has_started(hartid) } {} - println!("Hello RISCV! in hart {}, dtb @ {:#x}", hartid, dtb); + while !AP_CAN_INIT.load(Ordering::Relaxed) {} + println!( + "Hello RISCV! in hart {}, device tree @ {:#x}", + hartid, device_tree_vaddr + ); others_main(); //other_main -> ! } @@ -34,24 +43,25 @@ pub extern "C" fn rust_main(hartid: usize, dtb: usize, hart_mask: usize) -> ! { memory::clear_bss(); } - println!("Hello RISCV! in hart {}, dtb @ {:#x}", hartid, dtb); + println!( + "Hello RISCV! in hart {}, device tree @ {:#x}", + hartid, device_tree_vaddr + ); crate::logging::init(); interrupt::init(); - memory::init(dtb); + memory::init(device_tree_vaddr); timer::init(); // FIXME: init driver on u540 #[cfg(not(feature = "board_u540"))] - crate::drivers::init(dtb); - #[cfg(feature = "board_u540")] + crate::drivers::init(device_tree_vaddr); unsafe { + board::enable_serial_interrupt(); board::init_external_interrupt(); } crate::process::init(); - unsafe { - cpu::start_others(hart_mask); - } + AP_CAN_INIT.store(true, Ordering::Relaxed); crate::kmain(); } @@ -62,6 +72,8 @@ fn others_main() -> ! { crate::kmain(); } +static AP_CAN_INIT: AtomicBool = AtomicBool::new(false); + #[cfg(not(feature = "board_u540"))] const BOOT_HART_ID: usize = 0; #[cfg(feature = "board_u540")] @@ -94,6 +106,8 @@ global_asm!( .endm " ); - -global_asm!(include_str!("boot/entry.asm")); +#[cfg(target_arch = "riscv32")] +global_asm!(include_str!("boot/entry32.asm")); +#[cfg(target_arch = "riscv64")] +global_asm!(include_str!("boot/entry64.asm")); global_asm!(include_str!("boot/trap.asm")); diff --git a/kernel/src/arch/riscv32/paging.rs b/kernel/src/arch/riscv32/paging.rs index 12e61ecf..d501d6f2 100644 --- a/kernel/src/arch/riscv32/paging.rs +++ b/kernel/src/arch/riscv32/paging.rs @@ -198,7 +198,7 @@ impl InactivePageTable for InactivePageTable0 { fn start(); fn end(); } - let mut entrys: [PageTableEntry; 16] = unsafe { core::mem::uninitialized() }; + let mut entrys: [PageTableEntry; 256] = unsafe { core::mem::uninitialized() }; let entry_start = start as usize >> 22; let entry_end = (end as usize >> 22) + 1; let entry_count = entry_end - entry_start; @@ -299,3 +299,13 @@ impl FrameDeallocator for FrameAllocatorForRiscv { dealloc_frame(frame.start_address().as_usize()); } } + +pub unsafe fn setup_recursive_mapping() { + let frame = satp::read().frame(); + let root_page_table = unsafe { &mut *(frame.start_address().as_usize() as *mut RvPageTable) }; + root_page_table.set_recursive(RECURSIVE_INDEX, frame); + unsafe { + sfence_vma_all(); + } + info!("setup recursive mapping end"); +} diff --git a/kernel/src/arch/riscv32/sbi.rs b/kernel/src/arch/riscv32/sbi.rs index 6a56ff18..babfa796 100644 --- a/kernel/src/arch/riscv32/sbi.rs +++ b/kernel/src/arch/riscv32/sbi.rs @@ -1,4 +1,5 @@ //! Port from sbi.h +#![allow(dead_code)] #[inline(always)] fn sbi_call(which: usize, arg0: usize, arg1: usize, arg2: usize) -> usize { diff --git a/kernel/src/arch/x86_64/consts.rs b/kernel/src/arch/x86_64/consts.rs index 2095e395..0b3a4f97 100644 --- a/kernel/src/arch/x86_64/consts.rs +++ b/kernel/src/arch/x86_64/consts.rs @@ -55,7 +55,7 @@ pub const USER_GRANT_PML4: usize = (USER_GRANT_OFFSET & PML4_MASK) / PML4_SIZE; pub const USER_STACK_OFFSET: usize = USER_GRANT_OFFSET + PML4_SIZE; pub const USER_STACK_PML4: usize = (USER_STACK_OFFSET & PML4_MASK) / PML4_SIZE; /// Size of user stack -pub const USER_STACK_SIZE: usize = 1024 * 1024; // 1 MB +pub const USER_STACK_SIZE: usize = 8 * 1024 * 1024; // 8 MB, the default config of Linux /// Offset to user sigstack pub const USER_SIGSTACK_OFFSET: usize = USER_STACK_OFFSET + PML4_SIZE; diff --git a/kernel/src/arch/x86_64/driver/serial.rs b/kernel/src/arch/x86_64/driver/serial.rs index ce84af55..68655e2c 100644 --- a/kernel/src/arch/x86_64/driver/serial.rs +++ b/kernel/src/arch/x86_64/driver/serial.rs @@ -1,5 +1,3 @@ -// Copy from Redox - use once::*; use spin::Mutex; use uart_16550::SerialPort; @@ -7,8 +5,8 @@ use x86_64::instructions::port::Port; use crate::arch::interrupt::{consts, enable_irq}; -pub static COM1: Mutex = Mutex::new(SerialPort::new(0x3F8)); -pub static COM2: Mutex = Mutex::new(SerialPort::new(0x2F8)); +pub static COM1: Mutex = Mutex::new(unsafe { SerialPort::new(0x3F8) }); +pub static COM2: Mutex = Mutex::new(unsafe { SerialPort::new(0x2F8) }); pub fn init() { assert_has_not_been_called!("serial::init must be called only once"); @@ -27,7 +25,6 @@ impl SerialRead for SerialPort { fn receive(&mut self) -> u8 { unsafe { let ports = self as *mut _ as *mut [Port; 6]; - let _line_sts = &(*ports)[5]; let data = &(*ports)[0]; data.read() } diff --git a/kernel/src/arch/x86_64/driver/vga.rs b/kernel/src/arch/x86_64/driver/vga.rs index 70556614..41f6b9f7 100644 --- a/kernel/src/arch/x86_64/driver/vga.rs +++ b/kernel/src/arch/x86_64/driver/vga.rs @@ -206,11 +206,11 @@ impl AsciiConsole for VgaWriter { CSI::CursorMove(dx, dy) => { let x = (self.pos.row.0 as i8 + dx).max(0) as u8; let y = (self.pos.col.0 as i8 + dy).max(0) as u8; - self.set_pos(Position::new(Row(x), Col(y))); + self.set_pos(Position::new(Row(x), Col(y))).unwrap(); } CSI::CursorMoveLine(dx) => { let x = (self.pos.row.0 as i8 + dx).max(0) as u8; - self.set_pos(Position::new(Row(x), Col(0))); + self.set_pos(Position::new(Row(x), Col(0))).unwrap(); } _ => {} } diff --git a/kernel/src/arch/x86_64/gdt.rs b/kernel/src/arch/x86_64/gdt.rs index 90e50375..ed648e34 100644 --- a/kernel/src/arch/x86_64/gdt.rs +++ b/kernel/src/arch/x86_64/gdt.rs @@ -17,22 +17,19 @@ pub fn init() { static mut CPUS: [Option; MAX_CPU_NUM] = [ // TODO: More elegant ? - None, None, None, None, None, None, None, None, - None, None, None, None, None, None, None, None, - None, None, None, None, None, None, None, None, - None, None, None, None, None, None, None, None, - None, None, None, None, None, None, None, None, - None, None, None, None, None, None, None, None, - None, None, None, None, None, None, None, None, - None, None, None, None, None, None, None, None, -// None, None, None, None, None, None, None, None, -// None, None, None, None, None, None, None, None, -// None, None, None, None, None, None, None, None, -// None, None, None, None, None, None, None, None, -// None, None, None, None, None, None, None, None, -// None, None, None, None, None, None, None, None, -// None, None, None, None, None, None, None, None, -// None, None, None, None, None, None, None, None, + None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, + None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, + None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, + None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, + None, + // None, None, None, None, None, None, None, None, + // None, None, None, None, None, None, None, None, + // None, None, None, None, None, None, None, None, + // None, None, None, None, None, None, None, None, + // None, None, None, None, None, None, None, None, + // None, None, None, None, None, None, None, None, + // None, None, None, None, None, None, None, None, + // None, None, None, None, None, None, None, None, ]; pub struct Cpu { diff --git a/kernel/src/drivers/console/fonts/font8x16.rs b/kernel/src/drivers/console/fonts/font8x16.rs index 7513e857..abea5bfc 100644 --- a/kernel/src/drivers/console/fonts/font8x16.rs +++ b/kernel/src/drivers/console/fonts/font8x16.rs @@ -4,4364 +4,8 @@ use super::Font; pub enum Font8x16 {} -impl Font8x16 { - /// font data - /// copied from `linux/lib/fonts/font_8x16.c` - const DATA: [u8; 256 * 16] = [ - /* 0 0x00 '^@' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 1 0x01 '^A' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x81, /* 10000001 */ - 0xa5, /* 10100101 */ - 0x81, /* 10000001 */ - 0x81, /* 10000001 */ - 0xbd, /* 10111101 */ - 0x99, /* 10011001 */ - 0x81, /* 10000001 */ - 0x81, /* 10000001 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 2 0x02 '^B' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0xff, /* 11111111 */ - 0xdb, /* 11011011 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xc3, /* 11000011 */ - 0xe7, /* 11100111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 3 0x03 '^C' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x6c, /* 01101100 */ - 0xfe, /* 11111110 */ - 0xfe, /* 11111110 */ - 0xfe, /* 11111110 */ - 0xfe, /* 11111110 */ - 0x7c, /* 01111100 */ - 0x38, /* 00111000 */ - 0x10, /* 00010000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 4 0x04 '^D' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x10, /* 00010000 */ - 0x38, /* 00111000 */ - 0x7c, /* 01111100 */ - 0xfe, /* 11111110 */ - 0x7c, /* 01111100 */ - 0x38, /* 00111000 */ - 0x10, /* 00010000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 5 0x05 '^E' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x3c, /* 00111100 */ - 0xe7, /* 11100111 */ - 0xe7, /* 11100111 */ - 0xe7, /* 11100111 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 6 0x06 '^F' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x7e, /* 01111110 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0x7e, /* 01111110 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 7 0x07 '^G' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 8 0x08 '^H' */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xe7, /* 11100111 */ - 0xc3, /* 11000011 */ - 0xc3, /* 11000011 */ - 0xe7, /* 11100111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - /* 9 0x09 '^I' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3c, /* 00111100 */ - 0x66, /* 01100110 */ - 0x42, /* 01000010 */ - 0x42, /* 01000010 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 10 0x0a '^J' */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xc3, /* 11000011 */ - 0x99, /* 10011001 */ - 0xbd, /* 10111101 */ - 0xbd, /* 10111101 */ - 0x99, /* 10011001 */ - 0xc3, /* 11000011 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - /* 11 0x0b '^K' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x1e, /* 00011110 */ - 0x0e, /* 00001110 */ - 0x1a, /* 00011010 */ - 0x32, /* 00110010 */ - 0x78, /* 01111000 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x78, /* 01111000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 12 0x0c '^L' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3c, /* 00111100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 13 0x0d '^M' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3f, /* 00111111 */ - 0x33, /* 00110011 */ - 0x3f, /* 00111111 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x70, /* 01110000 */ - 0xf0, /* 11110000 */ - 0xe0, /* 11100000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 14 0x0e '^N' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7f, /* 01111111 */ - 0x63, /* 01100011 */ - 0x7f, /* 01111111 */ - 0x63, /* 01100011 */ - 0x63, /* 01100011 */ - 0x63, /* 01100011 */ - 0x63, /* 01100011 */ - 0x67, /* 01100111 */ - 0xe7, /* 11100111 */ - 0xe6, /* 11100110 */ - 0xc0, /* 11000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 15 0x0f '^O' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0xdb, /* 11011011 */ - 0x3c, /* 00111100 */ - 0xe7, /* 11100111 */ - 0x3c, /* 00111100 */ - 0xdb, /* 11011011 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 16 0x10 '^P' */ - 0x00, /* 00000000 */ - 0x80, /* 10000000 */ - 0xc0, /* 11000000 */ - 0xe0, /* 11100000 */ - 0xf0, /* 11110000 */ - 0xf8, /* 11111000 */ - 0xfe, /* 11111110 */ - 0xf8, /* 11111000 */ - 0xf0, /* 11110000 */ - 0xe0, /* 11100000 */ - 0xc0, /* 11000000 */ - 0x80, /* 10000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 17 0x11 '^Q' */ - 0x00, /* 00000000 */ - 0x02, /* 00000010 */ - 0x06, /* 00000110 */ - 0x0e, /* 00001110 */ - 0x1e, /* 00011110 */ - 0x3e, /* 00111110 */ - 0xfe, /* 11111110 */ - 0x3e, /* 00111110 */ - 0x1e, /* 00011110 */ - 0x0e, /* 00001110 */ - 0x06, /* 00000110 */ - 0x02, /* 00000010 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 18 0x12 '^R' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x7e, /* 01111110 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 19 0x13 '^S' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x00, /* 00000000 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 20 0x14 '^T' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7f, /* 01111111 */ - 0xdb, /* 11011011 */ - 0xdb, /* 11011011 */ - 0xdb, /* 11011011 */ - 0x7b, /* 01111011 */ - 0x1b, /* 00011011 */ - 0x1b, /* 00011011 */ - 0x1b, /* 00011011 */ - 0x1b, /* 00011011 */ - 0x1b, /* 00011011 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 21 0x15 '^U' */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0x60, /* 01100000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x0c, /* 00001100 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 22 0x16 '^V' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0xfe, /* 11111110 */ - 0xfe, /* 11111110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 23 0x17 '^W' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x7e, /* 01111110 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 24 0x18 '^X' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x7e, /* 01111110 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 25 0x19 '^Y' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 26 0x1a '^Z' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x0c, /* 00001100 */ - 0xfe, /* 11111110 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 27 0x1b '^[' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0xfe, /* 11111110 */ - 0x60, /* 01100000 */ - 0x30, /* 00110000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 28 0x1c '^\' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 29 0x1d '^]' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x28, /* 00101000 */ - 0x6c, /* 01101100 */ - 0xfe, /* 11111110 */ - 0x6c, /* 01101100 */ - 0x28, /* 00101000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 30 0x1e '^^' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x10, /* 00010000 */ - 0x38, /* 00111000 */ - 0x38, /* 00111000 */ - 0x7c, /* 01111100 */ - 0x7c, /* 01111100 */ - 0xfe, /* 11111110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 31 0x1f '^_' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0xfe, /* 11111110 */ - 0x7c, /* 01111100 */ - 0x7c, /* 01111100 */ - 0x38, /* 00111000 */ - 0x38, /* 00111000 */ - 0x10, /* 00010000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 32 0x20 ' ' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 33 0x21 '!' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x3c, /* 00111100 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 34 0x22 '"' */ - 0x00, /* 00000000 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x24, /* 00100100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 35 0x23 '#' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0xfe, /* 11111110 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0xfe, /* 11111110 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 36 0x24 '$' */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc2, /* 11000010 */ - 0xc0, /* 11000000 */ - 0x7c, /* 01111100 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x86, /* 10000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 37 0x25 '%' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc2, /* 11000010 */ - 0xc6, /* 11000110 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0xc6, /* 11000110 */ - 0x86, /* 10000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 38 0x26 '&' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x76, /* 01110110 */ - 0xdc, /* 11011100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 39 0x27 ''' */ - 0x00, /* 00000000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 40 0x28 '(' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x0c, /* 00001100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 41 0x29 ')' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 42 0x2a '*' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - 0xff, /* 11111111 */ - 0x3c, /* 00111100 */ - 0x66, /* 01100110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 43 0x2b '+' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 44 0x2c ',' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 45 0x2d '-' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 46 0x2e '.' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 47 0x2f '/' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x02, /* 00000010 */ - 0x06, /* 00000110 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0xc0, /* 11000000 */ - 0x80, /* 10000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 48 0x30 '0' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xd6, /* 11010110 */ - 0xd6, /* 11010110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 49 0x31 '1' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x38, /* 00111000 */ - 0x78, /* 01111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 50 0x32 '2' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0x06, /* 00000110 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0xc0, /* 11000000 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 51 0x33 '3' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x3c, /* 00111100 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 52 0x34 '4' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x0c, /* 00001100 */ - 0x1c, /* 00011100 */ - 0x3c, /* 00111100 */ - 0x6c, /* 01101100 */ - 0xcc, /* 11001100 */ - 0xfe, /* 11111110 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x1e, /* 00011110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 53 0x35 '5' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xfc, /* 11111100 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 54 0x36 '6' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x60, /* 01100000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xfc, /* 11111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 55 0x37 '7' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0xc6, /* 11000110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 56 0x38 '8' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 57 0x39 '9' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7e, /* 01111110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x0c, /* 00001100 */ - 0x78, /* 01111000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 58 0x3a ':' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 59 0x3b ';' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 60 0x3c '<' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x06, /* 00000110 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x0c, /* 00001100 */ - 0x06, /* 00000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 61 0x3d '=' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 62 0x3e '>' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x60, /* 01100000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x0c, /* 00001100 */ - 0x06, /* 00000110 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 63 0x3f '?' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 64 0x40 '@' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xde, /* 11011110 */ - 0xde, /* 11011110 */ - 0xde, /* 11011110 */ - 0xdc, /* 11011100 */ - 0xc0, /* 11000000 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 65 0x41 'A' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x10, /* 00010000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 66 0x42 'B' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfc, /* 11111100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x7c, /* 01111100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0xfc, /* 11111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 67 0x43 'C' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3c, /* 00111100 */ - 0x66, /* 01100110 */ - 0xc2, /* 11000010 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc2, /* 11000010 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 68 0x44 'D' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xf8, /* 11111000 */ - 0x6c, /* 01101100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x6c, /* 01101100 */ - 0xf8, /* 11111000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 69 0x45 'E' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0x66, /* 01100110 */ - 0x62, /* 01100010 */ - 0x68, /* 01101000 */ - 0x78, /* 01111000 */ - 0x68, /* 01101000 */ - 0x60, /* 01100000 */ - 0x62, /* 01100010 */ - 0x66, /* 01100110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 70 0x46 'F' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0x66, /* 01100110 */ - 0x62, /* 01100010 */ - 0x68, /* 01101000 */ - 0x78, /* 01111000 */ - 0x68, /* 01101000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0xf0, /* 11110000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 71 0x47 'G' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3c, /* 00111100 */ - 0x66, /* 01100110 */ - 0xc2, /* 11000010 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xde, /* 11011110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x66, /* 01100110 */ - 0x3a, /* 00111010 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 72 0x48 'H' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 73 0x49 'I' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 74 0x4a 'J' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x1e, /* 00011110 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x78, /* 01111000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 75 0x4b 'K' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xe6, /* 11100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x6c, /* 01101100 */ - 0x78, /* 01111000 */ - 0x78, /* 01111000 */ - 0x6c, /* 01101100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0xe6, /* 11100110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 76 0x4c 'L' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xf0, /* 11110000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x62, /* 01100010 */ - 0x66, /* 01100110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 77 0x4d 'M' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xee, /* 11101110 */ - 0xfe, /* 11111110 */ - 0xfe, /* 11111110 */ - 0xd6, /* 11010110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 78 0x4e 'N' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xe6, /* 11100110 */ - 0xf6, /* 11110110 */ - 0xfe, /* 11111110 */ - 0xde, /* 11011110 */ - 0xce, /* 11001110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 79 0x4f 'O' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 80 0x50 'P' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfc, /* 11111100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x7c, /* 01111100 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0xf0, /* 11110000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 81 0x51 'Q' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xd6, /* 11010110 */ - 0xde, /* 11011110 */ - 0x7c, /* 01111100 */ - 0x0c, /* 00001100 */ - 0x0e, /* 00001110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 82 0x52 'R' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfc, /* 11111100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x7c, /* 01111100 */ - 0x6c, /* 01101100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0xe6, /* 11100110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 83 0x53 'S' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x60, /* 01100000 */ - 0x38, /* 00111000 */ - 0x0c, /* 00001100 */ - 0x06, /* 00000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 84 0x54 'T' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x7e, /* 01111110 */ - 0x5a, /* 01011010 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 85 0x55 'U' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 86 0x56 'V' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x10, /* 00010000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 87 0x57 'W' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xd6, /* 11010110 */ - 0xd6, /* 11010110 */ - 0xd6, /* 11010110 */ - 0xfe, /* 11111110 */ - 0xee, /* 11101110 */ - 0x6c, /* 01101100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 88 0x58 'X' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x6c, /* 01101100 */ - 0x7c, /* 01111100 */ - 0x38, /* 00111000 */ - 0x38, /* 00111000 */ - 0x7c, /* 01111100 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 89 0x59 'Y' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 90 0x5a 'Z' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0xc6, /* 11000110 */ - 0x86, /* 10000110 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0xc2, /* 11000010 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 91 0x5b '[' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3c, /* 00111100 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 92 0x5c '\' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x80, /* 10000000 */ - 0xc0, /* 11000000 */ - 0xe0, /* 11100000 */ - 0x70, /* 01110000 */ - 0x38, /* 00111000 */ - 0x1c, /* 00011100 */ - 0x0e, /* 00001110 */ - 0x06, /* 00000110 */ - 0x02, /* 00000010 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 93 0x5d ']' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3c, /* 00111100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 94 0x5e '^' */ - 0x10, /* 00010000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 95 0x5f '_' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 96 0x60 '`' */ - 0x00, /* 00000000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x0c, /* 00001100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 97 0x61 'a' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x78, /* 01111000 */ - 0x0c, /* 00001100 */ - 0x7c, /* 01111100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 98 0x62 'b' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xe0, /* 11100000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x78, /* 01111000 */ - 0x6c, /* 01101100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 99 0x63 'c' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 100 0x64 'd' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x1c, /* 00011100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x3c, /* 00111100 */ - 0x6c, /* 01101100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 101 0x65 'e' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 102 0x66 'f' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x1c, /* 00011100 */ - 0x36, /* 00110110 */ - 0x32, /* 00110010 */ - 0x30, /* 00110000 */ - 0x78, /* 01111000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x78, /* 01111000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 103 0x67 'g' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x76, /* 01110110 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x7c, /* 01111100 */ - 0x0c, /* 00001100 */ - 0xcc, /* 11001100 */ - 0x78, /* 01111000 */ - 0x00, /* 00000000 */ - /* 104 0x68 'h' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xe0, /* 11100000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x6c, /* 01101100 */ - 0x76, /* 01110110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0xe6, /* 11100110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 105 0x69 'i' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 106 0x6a 'j' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x00, /* 00000000 */ - 0x0e, /* 00001110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - /* 107 0x6b 'k' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xe0, /* 11100000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x66, /* 01100110 */ - 0x6c, /* 01101100 */ - 0x78, /* 01111000 */ - 0x78, /* 01111000 */ - 0x6c, /* 01101100 */ - 0x66, /* 01100110 */ - 0xe6, /* 11100110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 108 0x6c 'l' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 109 0x6d 'm' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xec, /* 11101100 */ - 0xfe, /* 11111110 */ - 0xd6, /* 11010110 */ - 0xd6, /* 11010110 */ - 0xd6, /* 11010110 */ - 0xd6, /* 11010110 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 110 0x6e 'n' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xdc, /* 11011100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 111 0x6f 'o' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 112 0x70 'p' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xdc, /* 11011100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x7c, /* 01111100 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0xf0, /* 11110000 */ - 0x00, /* 00000000 */ - /* 113 0x71 'q' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x76, /* 01110110 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x7c, /* 01111100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x1e, /* 00011110 */ - 0x00, /* 00000000 */ - /* 114 0x72 'r' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xdc, /* 11011100 */ - 0x76, /* 01110110 */ - 0x66, /* 01100110 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0xf0, /* 11110000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 115 0x73 's' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0x60, /* 01100000 */ - 0x38, /* 00111000 */ - 0x0c, /* 00001100 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 116 0x74 't' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x10, /* 00010000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0xfc, /* 11111100 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x36, /* 00110110 */ - 0x1c, /* 00011100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 117 0x75 'u' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 118 0x76 'v' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 119 0x77 'w' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xd6, /* 11010110 */ - 0xd6, /* 11010110 */ - 0xd6, /* 11010110 */ - 0xfe, /* 11111110 */ - 0x6c, /* 01101100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 120 0x78 'x' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x38, /* 00111000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 121 0x79 'y' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7e, /* 01111110 */ - 0x06, /* 00000110 */ - 0x0c, /* 00001100 */ - 0xf8, /* 11111000 */ - 0x00, /* 00000000 */ - /* 122 0x7a 'z' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0xcc, /* 11001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 123 0x7b '{' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x0e, /* 00001110 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x70, /* 01110000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x0e, /* 00001110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 124 0x7c '|' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 125 0x7d '}' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x70, /* 01110000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x0e, /* 00001110 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x70, /* 01110000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 126 0x7e '~' */ - 0x00, /* 00000000 */ - 0x76, /* 01110110 */ - 0xdc, /* 11011100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 127 0x7f '' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x10, /* 00010000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 128 0x80 'Ç' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3c, /* 00111100 */ - 0x66, /* 01100110 */ - 0xc2, /* 11000010 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc2, /* 11000010 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x70, /* 01110000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 129 0x81 'ü' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xcc, /* 11001100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 130 0x82 'é' */ - 0x00, /* 00000000 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 131 0x83 'â' */ - 0x00, /* 00000000 */ - 0x10, /* 00010000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0x00, /* 00000000 */ - 0x78, /* 01111000 */ - 0x0c, /* 00001100 */ - 0x7c, /* 01111100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 132 0x84 'ä' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xcc, /* 11001100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x78, /* 01111000 */ - 0x0c, /* 00001100 */ - 0x7c, /* 01111100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 133 0x85 'à' */ - 0x00, /* 00000000 */ - 0x60, /* 01100000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x78, /* 01111000 */ - 0x0c, /* 00001100 */ - 0x7c, /* 01111100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 134 0x86 'å' */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x00, /* 00000000 */ - 0x78, /* 01111000 */ - 0x0c, /* 00001100 */ - 0x7c, /* 01111100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 135 0x87 'ç' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x18, /* 00011000 */ - 0x70, /* 01110000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 136 0x88 'ê' */ - 0x00, /* 00000000 */ - 0x10, /* 00010000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 137 0x89 'ë' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 138 0x8a 'è' */ - 0x00, /* 00000000 */ - 0x60, /* 01100000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 139 0x8b 'ï' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x66, /* 01100110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 140 0x8c 'î' */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x66, /* 01100110 */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 141 0x8d 'ì' */ - 0x00, /* 00000000 */ - 0x60, /* 01100000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 142 0x8e 'Ä' */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x10, /* 00010000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 143 0x8f 'Å' */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x10, /* 00010000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 144 0x90 'É' */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0x66, /* 01100110 */ - 0x62, /* 01100010 */ - 0x68, /* 01101000 */ - 0x78, /* 01111000 */ - 0x68, /* 01101000 */ - 0x62, /* 01100010 */ - 0x66, /* 01100110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 145 0x91 'æ' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xec, /* 11101100 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x7e, /* 01111110 */ - 0xd8, /* 11011000 */ - 0xd8, /* 11011000 */ - 0x6e, /* 01101110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 146 0x92 'Æ' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3e, /* 00111110 */ - 0x6c, /* 01101100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xfe, /* 11111110 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xce, /* 11001110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 147 0x93 'ô' */ - 0x00, /* 00000000 */ - 0x10, /* 00010000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 148 0x94 'ö' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 149 0x95 'ò' */ - 0x00, /* 00000000 */ - 0x60, /* 01100000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 150 0x96 'û' */ - 0x00, /* 00000000 */ - 0x30, /* 00110000 */ - 0x78, /* 01111000 */ - 0xcc, /* 11001100 */ - 0x00, /* 00000000 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 151 0x97 'ù' */ - 0x00, /* 00000000 */ - 0x60, /* 01100000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 152 0x98 'ÿ' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7e, /* 01111110 */ - 0x06, /* 00000110 */ - 0x0c, /* 00001100 */ - 0x78, /* 01111000 */ - 0x00, /* 00000000 */ - /* 153 0x99 'Ö' */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 154 0x9a 'Ü' */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 155 0x9b '¢' */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 156 0x9c '£' */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0x64, /* 01100100 */ - 0x60, /* 01100000 */ - 0xf0, /* 11110000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0xe6, /* 11100110 */ - 0xfc, /* 11111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 157 0x9d '¥' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 158 0x9e '₧' */ - 0x00, /* 00000000 */ - 0xf8, /* 11111000 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xf8, /* 11111000 */ - 0xc4, /* 11000100 */ - 0xcc, /* 11001100 */ - 0xde, /* 11011110 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 159 0x9f 'ƒ' */ - 0x00, /* 00000000 */ - 0x0e, /* 00001110 */ - 0x1b, /* 00011011 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0xd8, /* 11011000 */ - 0x70, /* 01110000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 160 0xa0 'á' */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0x00, /* 00000000 */ - 0x78, /* 01111000 */ - 0x0c, /* 00001100 */ - 0x7c, /* 01111100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 161 0xa1 'í' */ - 0x00, /* 00000000 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 162 0xa2 'ó' */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 163 0xa3 'ú' */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0x00, /* 00000000 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 164 0xa4 'ñ' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x76, /* 01110110 */ - 0xdc, /* 11011100 */ - 0x00, /* 00000000 */ - 0xdc, /* 11011100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 165 0xa5 'Ñ' */ - 0x76, /* 01110110 */ - 0xdc, /* 11011100 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xe6, /* 11100110 */ - 0xf6, /* 11110110 */ - 0xfe, /* 11111110 */ - 0xde, /* 11011110 */ - 0xce, /* 11001110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 166 0xa6 'ª' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3c, /* 00111100 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x3e, /* 00111110 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 167 0xa7 'º' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 168 0xa8 '¿' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x00, /* 00000000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0xc0, /* 11000000 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 169 0xa9 '⌐' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 170 0xaa '¬' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 171 0xab '½' */ - 0x00, /* 00000000 */ - 0x60, /* 01100000 */ - 0xe0, /* 11100000 */ - 0x62, /* 01100010 */ - 0x66, /* 01100110 */ - 0x6c, /* 01101100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0xdc, /* 11011100 */ - 0x86, /* 10000110 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x3e, /* 00111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 172 0xac '¼' */ - 0x00, /* 00000000 */ - 0x60, /* 01100000 */ - 0xe0, /* 11100000 */ - 0x62, /* 01100010 */ - 0x66, /* 01100110 */ - 0x6c, /* 01101100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x66, /* 01100110 */ - 0xce, /* 11001110 */ - 0x9a, /* 10011010 */ - 0x3f, /* 00111111 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 173 0xad '¡' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x3c, /* 00111100 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 174 0xae '«' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x36, /* 00110110 */ - 0x6c, /* 01101100 */ - 0xd8, /* 11011000 */ - 0x6c, /* 01101100 */ - 0x36, /* 00110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 175 0xaf '»' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xd8, /* 11011000 */ - 0x6c, /* 01101100 */ - 0x36, /* 00110110 */ - 0x6c, /* 01101100 */ - 0xd8, /* 11011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 176 0xb0 '░' */ - 0x11, /* 00010001 */ - 0x44, /* 01000100 */ - 0x11, /* 00010001 */ - 0x44, /* 01000100 */ - 0x11, /* 00010001 */ - 0x44, /* 01000100 */ - 0x11, /* 00010001 */ - 0x44, /* 01000100 */ - 0x11, /* 00010001 */ - 0x44, /* 01000100 */ - 0x11, /* 00010001 */ - 0x44, /* 01000100 */ - 0x11, /* 00010001 */ - 0x44, /* 01000100 */ - 0x11, /* 00010001 */ - 0x44, /* 01000100 */ - /* 177 0xb1 '▒' */ - 0x55, /* 01010101 */ - 0xaa, /* 10101010 */ - 0x55, /* 01010101 */ - 0xaa, /* 10101010 */ - 0x55, /* 01010101 */ - 0xaa, /* 10101010 */ - 0x55, /* 01010101 */ - 0xaa, /* 10101010 */ - 0x55, /* 01010101 */ - 0xaa, /* 10101010 */ - 0x55, /* 01010101 */ - 0xaa, /* 10101010 */ - 0x55, /* 01010101 */ - 0xaa, /* 10101010 */ - 0x55, /* 01010101 */ - 0xaa, /* 10101010 */ - /* 178 0xb2 '▓' */ - 0xdd, /* 11011101 */ - 0x77, /* 01110111 */ - 0xdd, /* 11011101 */ - 0x77, /* 01110111 */ - 0xdd, /* 11011101 */ - 0x77, /* 01110111 */ - 0xdd, /* 11011101 */ - 0x77, /* 01110111 */ - 0xdd, /* 11011101 */ - 0x77, /* 01110111 */ - 0xdd, /* 11011101 */ - 0x77, /* 01110111 */ - 0xdd, /* 11011101 */ - 0x77, /* 01110111 */ - 0xdd, /* 11011101 */ - 0x77, /* 01110111 */ - /* 179 0xb3 '│' */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - /* 180 0xb4 '┤' */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0xf8, /* 11111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - /* 181 0xb5 '╡' */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0xf8, /* 11111000 */ - 0x18, /* 00011000 */ - 0xf8, /* 11111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - /* 182 0xb6 '╢' */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0xf6, /* 11110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - /* 183 0xb7 '╖' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - /* 184 0xb8 '╕' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xf8, /* 11111000 */ - 0x18, /* 00011000 */ - 0xf8, /* 11111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - /* 185 0xb9 '╣' */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0xf6, /* 11110110 */ - 0x06, /* 00000110 */ - 0xf6, /* 11110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - /* 186 0xba '║' */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - /* 187 0xbb '╗' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0x06, /* 00000110 */ - 0xf6, /* 11110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - /* 188 0xbc '╝' */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0xf6, /* 11110110 */ - 0x06, /* 00000110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 189 0xbd '╜' */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 190 0xbe '╛' */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0xf8, /* 11111000 */ - 0x18, /* 00011000 */ - 0xf8, /* 11111000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 191 0xbf '┐' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xf8, /* 11111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - /* 192 0xc0 '└' */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x1f, /* 00011111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 193 0xc1 '┴' */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 194 0xc2 '┬' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - /* 195 0xc3 '├' */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x1f, /* 00011111 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - /* 196 0xc4 '─' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 197 0xc5 '┼' */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0xff, /* 11111111 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - /* 198 0xc6 '╞' */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x1f, /* 00011111 */ - 0x18, /* 00011000 */ - 0x1f, /* 00011111 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - /* 199 0xc7 '╟' */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x37, /* 00110111 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - /* 200 0xc8 '╚' */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x37, /* 00110111 */ - 0x30, /* 00110000 */ - 0x3f, /* 00111111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 201 0xc9 '╔' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3f, /* 00111111 */ - 0x30, /* 00110000 */ - 0x37, /* 00110111 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - /* 202 0xca '╩' */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0xf7, /* 11110111 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 203 0xcb '╦' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0xf7, /* 11110111 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - /* 204 0xcc '╠' */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x37, /* 00110111 */ - 0x30, /* 00110000 */ - 0x37, /* 00110111 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - /* 205 0xcd '═' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 206 0xce '╬' */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0xf7, /* 11110111 */ - 0x00, /* 00000000 */ - 0xf7, /* 11110111 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - /* 207 0xcf '╧' */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 208 0xd0 '╨' */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 209 0xd1 '╤' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - /* 210 0xd2 '╥' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - /* 211 0xd3 '╙' */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x3f, /* 00111111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 212 0xd4 '╘' */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x1f, /* 00011111 */ - 0x18, /* 00011000 */ - 0x1f, /* 00011111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 213 0xd5 '╒' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x1f, /* 00011111 */ - 0x18, /* 00011000 */ - 0x1f, /* 00011111 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - /* 214 0xd6 '╓' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3f, /* 00111111 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - /* 215 0xd7 '╫' */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0xff, /* 11111111 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - /* 216 0xd8 '╪' */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0xff, /* 11111111 */ - 0x18, /* 00011000 */ - 0xff, /* 11111111 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - /* 217 0xd9 '┘' */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0xf8, /* 11111000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 218 0xda '┌' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x1f, /* 00011111 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - /* 219 0xdb '█' */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - /* 220 0xdc '▄' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - /* 221 0xdd '▌' */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - /* 222 0xde '▐' */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - /* 223 0xdf '▀' */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 224 0xe0 'α' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x76, /* 01110110 */ - 0xdc, /* 11011100 */ - 0xd8, /* 11011000 */ - 0xd8, /* 11011000 */ - 0xd8, /* 11011000 */ - 0xdc, /* 11011100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 225 0xe1 'ß' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x78, /* 01111000 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xd8, /* 11011000 */ - 0xcc, /* 11001100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xcc, /* 11001100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 226 0xe2 'Γ' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 227 0xe3 'π' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 228 0xe4 'Σ' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0xc6, /* 11000110 */ - 0x60, /* 01100000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 229 0xe5 'σ' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0xd8, /* 11011000 */ - 0xd8, /* 11011000 */ - 0xd8, /* 11011000 */ - 0xd8, /* 11011000 */ - 0xd8, /* 11011000 */ - 0x70, /* 01110000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 230 0xe6 'µ' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x7c, /* 01111100 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0xc0, /* 11000000 */ - 0x00, /* 00000000 */ - /* 231 0xe7 'τ' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x76, /* 01110110 */ - 0xdc, /* 11011100 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 232 0xe8 'Φ' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 233 0xe9 'Θ' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 234 0xea 'Ω' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0xee, /* 11101110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 235 0xeb 'δ' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x1e, /* 00011110 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x0c, /* 00001100 */ - 0x3e, /* 00111110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 236 0xec '∞' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0xdb, /* 11011011 */ - 0xdb, /* 11011011 */ - 0xdb, /* 11011011 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 237 0xed 'φ' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x03, /* 00000011 */ - 0x06, /* 00000110 */ - 0x7e, /* 01111110 */ - 0xdb, /* 11011011 */ - 0xdb, /* 11011011 */ - 0xf3, /* 11110011 */ - 0x7e, /* 01111110 */ - 0x60, /* 01100000 */ - 0xc0, /* 11000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 238 0xee 'ε' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x1c, /* 00011100 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x7c, /* 01111100 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x30, /* 00110000 */ - 0x1c, /* 00011100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 239 0xef '∩' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 240 0xf0 '≡' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 241 0xf1 '±' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 242 0xf2 '≥' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x0c, /* 00001100 */ - 0x06, /* 00000110 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 243 0xf3 '≤' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x0c, /* 00001100 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 244 0xf4 '⌠' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x0e, /* 00001110 */ - 0x1b, /* 00011011 */ - 0x1b, /* 00011011 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - /* 245 0xf5 '⌡' */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0xd8, /* 11011000 */ - 0xd8, /* 11011000 */ - 0xd8, /* 11011000 */ - 0x70, /* 01110000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 246 0xf6 '÷' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 247 0xf7 '≈' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x76, /* 01110110 */ - 0xdc, /* 11011100 */ - 0x00, /* 00000000 */ - 0x76, /* 01110110 */ - 0xdc, /* 11011100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 248 0xf8 '°' */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 249 0xf9 '·' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 250 0xfa '•' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 251 0xfb '√' */ - 0x00, /* 00000000 */ - 0x0f, /* 00001111 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0xec, /* 11101100 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x3c, /* 00111100 */ - 0x1c, /* 00011100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 252 0xfc 'ⁿ' */ - 0x00, /* 00000000 */ - 0x6c, /* 01101100 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 253 0xfd '²' */ - 0x00, /* 00000000 */ - 0x3c, /* 00111100 */ - 0x66, /* 01100110 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x32, /* 00110010 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 254 0xfe '■' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x7e, /* 01111110 */ - 0x7e, /* 01111110 */ - 0x7e, /* 01111110 */ - 0x7e, /* 01111110 */ - 0x7e, /* 01111110 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 255 0xff ' ' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - ]; -} +// https://github.com/jamwaffles/embedded-graphics/blob/0ec4fc09c55aee733fb9d9cd6525749b8e15766e/embedded-graphics/data/font8x16_1bpp.raw +const FONT_IMAGE: &'static [u8] = include_bytes!("font8x16_1bpp.raw"); impl Font for Font8x16 { const HEIGHT: usize = 16; @@ -4372,6 +16,43 @@ impl Font for Font8x16 { #[inline] fn get(byte: u8, x: usize, y: usize) -> bool { - Self::DATA[byte as usize * 16 + y] & (1 << (7 - x)) != 0 + const FONT_IMAGE_WIDTH: usize = 240; + let char_per_row = FONT_IMAGE_WIDTH / Self::WIDTH; + + // Char _code_ offset from first char, most often a space + // E.g. first char = ' ' (32), target char = '!' (33), offset = 33 - 32 = 1 + let char_offset = char_offset(byte as char) as usize; + let row = char_offset / char_per_row; + + // Top left corner of character, in pixels + let char_x = (char_offset - (row * char_per_row)) * Self::WIDTH; + let char_y = row * Self::HEIGHT; + + // Bit index + // = X pixel offset for char + // + Character row offset (row 0 = 0, row 1 = (192 * 8) = 1536) + // + X offset for the pixel block that comprises this char + // + Y offset for pixel block + let bitmap_bit_index = char_x + x + + (FONT_IMAGE_WIDTH * (char_y + y)); + + let bitmap_byte = bitmap_bit_index / 8; + let bitmap_bit = 7 - (bitmap_bit_index % 8); + + FONT_IMAGE[bitmap_byte] & ((1 << bitmap_bit) as u8) != 0 } } + +fn char_offset(c: char) -> u32 { + let fallback = '?' as u32 - ' ' as u32; + if c < ' ' { + return fallback; + } + if c <= '~' { + return c as u32 - ' ' as u32; + } + if c < '¡' || c > 'ÿ' { + return fallback; + } + c as u32 - ' ' as u32 - 34 +} diff --git a/kernel/src/drivers/console/fonts/font8x16_1bpp.raw b/kernel/src/drivers/console/fonts/font8x16_1bpp.raw new file mode 100644 index 00000000..372f9945 Binary files /dev/null and b/kernel/src/drivers/console/fonts/font8x16_1bpp.raw differ diff --git a/kernel/src/fs/file.rs b/kernel/src/fs/file.rs index dfb291fa..5e1b84f2 100644 --- a/kernel/src/fs/file.rs +++ b/kernel/src/fs/file.rs @@ -113,7 +113,7 @@ impl FileHandle { self.inode.poll() } - pub fn io_control(&self, cmd: u32, arg: u32) -> Result<()> { + pub fn io_control(&self, cmd: u32, arg: usize) -> Result<()> { self.inode.io_control(cmd, arg) } } diff --git a/kernel/src/fs/file_like.rs b/kernel/src/fs/file_like.rs index 47a3cc69..32c5cdcc 100644 --- a/kernel/src/fs/file_like.rs +++ b/kernel/src/fs/file_like.rs @@ -31,7 +31,7 @@ impl FileLike { } pub fn ioctl(&mut self, request: usize, arg1: usize, arg2: usize, arg3: usize) -> SysResult { match self { - FileLike::File(file) => file.io_control(request as u32, arg1 as u32)?, + FileLike::File(file) => file.io_control(request as u32, arg1)?, FileLike::Socket(socket) => { socket.ioctl(request, arg1, arg2, arg3)?; } diff --git a/kernel/src/fs/pipe.rs b/kernel/src/fs/pipe.rs index c0c50eac..88073807 100644 --- a/kernel/src/fs/pipe.rs +++ b/kernel/src/fs/pipe.rs @@ -69,7 +69,7 @@ macro_rules! impl_inode { fn move_(&self, _old_name: &str, _target: &Arc, _new_name: &str) -> Result<()> { Err(FsError::NotDir) } fn find(&self, _name: &str) -> Result> { Err(FsError::NotDir) } fn get_entry(&self, _id: usize) -> Result { Err(FsError::NotDir) } - fn io_control(&self, _cmd: u32, _data: u32) -> Result<()> { Err(FsError::NotSupported) } + fn io_control(&self, _cmd: u32, _data: usize) -> Result<()> { Err(FsError::NotSupported) } fn fs(&self) -> Arc { unimplemented!() } fn as_any_ref(&self) -> &Any { self } }; diff --git a/kernel/src/fs/stdio.rs b/kernel/src/fs/stdio.rs index d2ceda2a..14e8c317 100644 --- a/kernel/src/fs/stdio.rs +++ b/kernel/src/fs/stdio.rs @@ -20,8 +20,6 @@ impl Stdin { self.pushed.notify_one(); } pub fn pop(&self) -> char { - // QEMU v3.0 don't support M-mode external interrupt (bug?) - // So we have to use polling. loop { let ret = self.buf.lock().pop_front(); match ret { @@ -43,6 +41,11 @@ lazy_static! { pub static ref STDOUT: Arc = Arc::new(Stdout::default()); } +const TCGETS: u32 = 0x5401; +const TIOCGPGRP: u32 = 0x540F; +const TIOCSPGRP: u32 = 0x5410; +const TIOCGWINSZ: u32 = 0x5413; + // TODO: better way to provide default impl? macro_rules! impl_inode { () => { @@ -57,7 +60,23 @@ macro_rules! impl_inode { fn move_(&self, _old_name: &str, _target: &Arc, _new_name: &str) -> Result<()> { Err(FsError::NotDir) } fn find(&self, _name: &str) -> Result> { Err(FsError::NotDir) } fn get_entry(&self, _id: usize) -> Result { Err(FsError::NotDir) } - fn io_control(&self, _cmd: u32, _data: u32) -> Result<()> { Err(FsError::NotSupported) } + fn io_control(&self, cmd: u32, data: usize) -> Result<()> { + match cmd { + TCGETS | TIOCGWINSZ | TIOCSPGRP => { + // pretend to be tty + Ok(()) + }, + TIOCGPGRP => { + // pretend to be have a tty process group + // TODO: verify pointer + unsafe { + *(data as *mut u32) = 0 + }; + Ok(()) + } + _ => Err(FsError::NotSupported) + } + } fn fs(&self) -> Arc { unimplemented!() } fn as_any_ref(&self) -> &Any { self } }; diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs index 779b75f4..fa5f0a65 100644 --- a/kernel/src/lib.rs +++ b/kernel/src/lib.rs @@ -6,6 +6,7 @@ #![feature(optin_builtin_traits)] #![feature(panic_info_message)] #![feature(global_asm)] +#![deny(unused_must_use)] #![no_std] // just keep it ... diff --git a/kernel/src/logging.rs b/kernel/src/logging.rs index b832d50c..838abe5c 100644 --- a/kernel/src/logging.rs +++ b/kernel/src/logging.rs @@ -14,13 +14,12 @@ pub fn init() { static LOGGER: SimpleLogger = SimpleLogger; log::set_logger(&LOGGER).unwrap(); log::set_max_level(match option_env!("LOG") { - Some("off") => LevelFilter::Off, Some("error") => LevelFilter::Error, Some("warn") => LevelFilter::Warn, Some("info") => LevelFilter::Info, Some("debug") => LevelFilter::Debug, Some("trace") => LevelFilter::Trace, - _ => LevelFilter::Warn, + _ => LevelFilter::Off, }); } diff --git a/kernel/src/memory.rs b/kernel/src/memory.rs index a6314372..f98f1ad5 100644 --- a/kernel/src/memory.rs +++ b/kernel/src/memory.rs @@ -16,9 +16,9 @@ pub type MemorySet = rcore_memory::memory_set::MemorySet; #[cfg(target_arch = "x86_64")] pub type FrameAlloc = bitmap_allocator::BitAlloc16M; -// RISCV has 8M memory +// RISCV has 1G memory #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] -pub type FrameAlloc = bitmap_allocator::BitAlloc4K; +pub type FrameAlloc = bitmap_allocator::BitAlloc1M; // Raspberry Pi 3 has 1G memory #[cfg(any(target_arch = "aarch64", target_arch = "mips"))] diff --git a/kernel/src/process/abi.rs b/kernel/src/process/abi.rs index 913fb1ac..dcaa428d 100644 --- a/kernel/src/process/abi.rs +++ b/kernel/src/process/abi.rs @@ -5,7 +5,7 @@ use core::ptr::null; pub struct ProcInitInfo { pub args: Vec, - pub envs: BTreeMap, + pub envs: Vec, pub auxv: BTreeMap, } @@ -19,10 +19,8 @@ impl ProcInitInfo { let envs: Vec<_> = self .envs .iter() - .map(|(key, value)| { - writer.push_str(value.as_str()); - writer.push_slice(&[b"="]); - writer.push_slice(key.as_bytes()); + .map(|arg| { + writer.push_str(arg.as_str()); writer.sp }) .collect(); diff --git a/kernel/src/process/mod.rs b/kernel/src/process/mod.rs index fca611da..516d29e2 100644 --- a/kernel/src/process/mod.rs +++ b/kernel/src/process/mod.rs @@ -27,38 +27,86 @@ pub fn init() { static PROCESSORS: [Processor; MAX_CPU_NUM] = [ // TODO: More elegant ? - Processor::new(), Processor::new(), Processor::new(), Processor::new(), - Processor::new(), Processor::new(), Processor::new(), Processor::new(), - Processor::new(), Processor::new(), Processor::new(), Processor::new(), - Processor::new(), Processor::new(), Processor::new(), Processor::new(), - Processor::new(), Processor::new(), Processor::new(), Processor::new(), - Processor::new(), Processor::new(), Processor::new(), Processor::new(), - Processor::new(), Processor::new(), Processor::new(), Processor::new(), - Processor::new(), Processor::new(), Processor::new(), Processor::new(), - Processor::new(), Processor::new(), Processor::new(), Processor::new(), - Processor::new(), Processor::new(), Processor::new(), Processor::new(), - Processor::new(), Processor::new(), Processor::new(), Processor::new(), - Processor::new(), Processor::new(), Processor::new(), Processor::new(), - Processor::new(), Processor::new(), Processor::new(), Processor::new(), - Processor::new(), Processor::new(), Processor::new(), Processor::new(), - Processor::new(), Processor::new(), Processor::new(), Processor::new(), - Processor::new(), Processor::new(), Processor::new(), Processor::new(), -// Processor::new(), Processor::new(), Processor::new(), Processor::new(), -// Processor::new(), Processor::new(), Processor::new(), Processor::new(), -// Processor::new(), Processor::new(), Processor::new(), Processor::new(), -// Processor::new(), Processor::new(), Processor::new(), Processor::new(), -// Processor::new(), Processor::new(), Processor::new(), Processor::new(), -// Processor::new(), Processor::new(), Processor::new(), Processor::new(), -// Processor::new(), Processor::new(), Processor::new(), Processor::new(), -// Processor::new(), Processor::new(), Processor::new(), Processor::new(), -// Processor::new(), Processor::new(), Processor::new(), Processor::new(), -// Processor::new(), Processor::new(), Processor::new(), Processor::new(), -// Processor::new(), Processor::new(), Processor::new(), Processor::new(), -// Processor::new(), Processor::new(), Processor::new(), Processor::new(), -// Processor::new(), Processor::new(), Processor::new(), Processor::new(), -// Processor::new(), Processor::new(), Processor::new(), Processor::new(), -// Processor::new(), Processor::new(), Processor::new(), Processor::new(), -// Processor::new(), Processor::new(), Processor::new(), Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + // Processor::new(), Processor::new(), Processor::new(), Processor::new(), + // Processor::new(), Processor::new(), Processor::new(), Processor::new(), + // Processor::new(), Processor::new(), Processor::new(), Processor::new(), + // Processor::new(), Processor::new(), Processor::new(), Processor::new(), + // Processor::new(), Processor::new(), Processor::new(), Processor::new(), + // Processor::new(), Processor::new(), Processor::new(), Processor::new(), + // Processor::new(), Processor::new(), Processor::new(), Processor::new(), + // Processor::new(), Processor::new(), Processor::new(), Processor::new(), + // Processor::new(), Processor::new(), Processor::new(), Processor::new(), + // Processor::new(), Processor::new(), Processor::new(), Processor::new(), + // Processor::new(), Processor::new(), Processor::new(), Processor::new(), + // Processor::new(), Processor::new(), Processor::new(), Processor::new(), + // Processor::new(), Processor::new(), Processor::new(), Processor::new(), + // Processor::new(), Processor::new(), Processor::new(), Processor::new(), + // Processor::new(), Processor::new(), Processor::new(), Processor::new(), + // Processor::new(), Processor::new(), Processor::new(), Processor::new(), ]; /// Get current process diff --git a/kernel/src/process/structs.rs b/kernel/src/process/structs.rs index 700d4c22..a9982ee8 100644 --- a/kernel/src/process/structs.rs +++ b/kernel/src/process/structs.rs @@ -158,10 +158,12 @@ impl Thread { } /// Make a new user process from ELF `data` - pub fn new_user<'a, Iter>(data: &[u8], args: Iter) -> Box - where - Iter: Iterator, - { + pub fn new_user( + data: &[u8], + exec_path: &str, + mut args: Vec, + envs: Vec, + ) -> Box { // Parse ELF let elf = ElfFile::new(data).expect("failed to read elf"); @@ -172,17 +174,31 @@ impl Thread { _ => panic!("ELF is not executable or shared object"), } - // Check interpreter + // Check ELF arch + match elf.header.pt2.machine().as_machine() { + #[cfg(target_arch = "x86_64")] + header::Machine::X86_64 => {} + #[cfg(target_arch = "aarch64")] + header::Machine::AArch64 => {} + #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] + header::Machine::Other(243) => {} + #[cfg(target_arch = "mips")] + header::Machine::Mips => {} + machine @ _ => panic!("invalid elf arch: {:?}", machine), + } + + // Check interpreter (for dynamic link) if let Ok(loader_path) = elf.get_interpreter() { // assuming absolute path if let Ok(inode) = crate::fs::ROOT_INODE.lookup_follow(loader_path, FOLLOW_MAX_DEPTH) { if let Ok(buf) = inode.read_as_vec() { - debug!("using loader {}", &loader_path); // Elf loader should not have INTERP // No infinite loop - let mut new_args: Vec<&str> = args.collect(); - new_args.insert(0, loader_path); - return Thread::new_user(buf.as_slice(), new_args.into_iter()); + args.insert(0, loader_path.into()); + args.insert(1, exec_path.into()); + args.remove(2); + info!("loader args: {:?}", args); + return Thread::new_user(buf.as_slice(), exec_path, args, envs); } else { warn!("loader specified as {} but failed to read", &loader_path); } @@ -211,8 +227,8 @@ impl Thread { // Make init info let init_info = ProcInitInfo { - args: args.map(|s| String::from(s)).collect(), - envs: BTreeMap::new(), + args, + envs, auxv: { let mut map = BTreeMap::new(); if let Some(phdr_vaddr) = elf.get_phdr_vaddr() { @@ -418,7 +434,7 @@ impl ElfExt for ElfFile<'_> { virt_addr + mem_size, ph.flags().to_attr(), ByFrame::new(GlobalFrameAlloc), - "", + "elf", ); unsafe { ::core::slice::from_raw_parts_mut(virt_addr as *mut u8, mem_size) } }; diff --git a/kernel/src/shell.rs b/kernel/src/shell.rs index ce0f1561..000ad633 100644 --- a/kernel/src/shell.rs +++ b/kernel/src/shell.rs @@ -8,11 +8,14 @@ use alloc::vec::Vec; #[cfg(not(feature = "run_cmdline"))] pub fn run_user_shell() { - if let Ok(inode) = ROOT_INODE.lookup("rust/sh") { + if let Ok(inode) = ROOT_INODE.lookup("busybox") { let data = inode.read_as_vec().unwrap(); - processor() - .manager() - .add(Thread::new_user(data.as_slice(), "sh".split(' '))); + processor().manager().add(Thread::new_user( + data.as_slice(), + "busybox", + vec!["busybox".into(), "sh".into()], + Vec::new(), + )); } else { processor().manager().add(Thread::new_kernel(shell, 0)); } @@ -23,9 +26,11 @@ pub fn run_user_shell() { let cmdline = CMDLINE.read(); let inode = ROOT_INODE.lookup(&cmdline).unwrap(); let data = inode.read_as_vec().unwrap(); - processor() - .manager() - .add(Thread::new_user(data.as_slice(), cmdline.split(' '))); + processor().manager().add(Thread::new_user( + data.as_slice(), + cmdline.split(' ').map(|s| s.into()).collect(), + Vec::new(), + )); } pub extern "C" fn shell(_arg: usize) -> ! { @@ -42,9 +47,12 @@ pub extern "C" fn shell(_arg: usize) -> ! { let name = cmd.trim().split(' ').next().unwrap(); if let Ok(file) = ROOT_INODE.lookup(name) { let data = file.read_as_vec().unwrap(); - let _pid = processor() - .manager() - .add(Thread::new_user(data.as_slice(), cmd.split(' '))); + let _pid = processor().manager().add(Thread::new_user( + data.as_slice(), + &cmd, + cmd.split(' ').map(|s| s.into()).collect(), + Vec::new(), + )); // TODO: wait until process exits, or use user land shell completely //unsafe { thread::JoinHandle::<()>::_of(pid) }.join().unwrap(); } else { diff --git a/kernel/src/syscall/fs.rs b/kernel/src/syscall/fs.rs index 1ef806e4..3c79da0c 100644 --- a/kernel/src/syscall/fs.rs +++ b/kernel/src/syscall/fs.rs @@ -3,6 +3,7 @@ use core::cell::UnsafeCell; use core::cmp::min; use core::mem::size_of; +#[cfg(not(target_arch = "mips"))] use rcore_fs::vfs::Timespec; use crate::drivers::SOCKET_ACTIVITY; @@ -66,12 +67,28 @@ pub fn sys_pwrite(fd: usize, base: *const u8, len: usize, offset: usize) -> SysR Ok(len) } -pub fn sys_poll(ufds: *mut PollFd, nfds: usize, timeout_msecs: usize) -> SysResult { - info!( - "poll: ufds: {:?}, nfds: {}, timeout_msecs: {:#x}", - ufds, nfds, timeout_msecs - ); +pub fn sys_ppoll(ufds: *mut PollFd, nfds: usize, timeout: *const TimeSpec) -> SysResult { let proc = process(); + let timeout_msecs = if timeout.is_null() { + 1 << 31 // infinity + } else { + proc.vm.check_read_ptr(timeout)?; + unsafe { (*timeout).to_msec() } + }; + drop(proc); + + sys_poll(ufds, nfds, timeout_msecs as usize) +} + +pub fn sys_poll(ufds: *mut PollFd, nfds: usize, timeout_msecs: usize) -> SysResult { + let proc = process(); + if !proc.pid.is_init() { + // we trust pid 0 process + info!( + "poll: ufds: {:?}, nfds: {}, timeout_msecs: {:#x}", + ufds, nfds, timeout_msecs + ); + } proc.vm.check_write_array(ufds, nfds)?; let polls = unsafe { slice::from_raw_parts_mut(ufds, nfds) }; @@ -209,11 +226,14 @@ pub fn sys_readv(fd: usize, iov_ptr: *const IoVec, iov_count: usize) -> SysResul } pub fn sys_writev(fd: usize, iov_ptr: *const IoVec, iov_count: usize) -> SysResult { - info!( - "writev: fd: {}, iov: {:?}, count: {}", - fd, iov_ptr, iov_count - ); let mut proc = process(); + if !proc.pid.is_init() { + // we trust pid 0 process + info!( + "writev: fd: {}, iov: {:?}, count: {}", + fd, iov_ptr, iov_count + ); + } let iovs = IoVecs::check_and_new(iov_ptr, iov_count, &proc.vm, false)?; let buf = iovs.read_all_to_vec(); @@ -240,7 +260,7 @@ pub fn sys_openat(dir_fd: usize, path: *const u8, flags: usize, mode: usize) -> let inode = if flags.contains(OpenFlags::CREATE) { let (dir_path, file_name) = split_path(&path); // relative to cwd - let dir_inode = proc.lookup_inode_at(dir_fd, dir_path)?; + let dir_inode = proc.lookup_inode_at(dir_fd, dir_path, true)?; match dir_inode.find(file_name) { Ok(file_inode) => { if flags.contains(OpenFlags::EXCLUSIVE) { @@ -254,7 +274,7 @@ pub fn sys_openat(dir_fd: usize, path: *const u8, flags: usize, mode: usize) -> Err(e) => return Err(SysError::from(e)), } } else { - proc.lookup_inode_at(dir_fd, &path)? + proc.lookup_inode_at(dir_fd, &path, true)? }; let fd = proc.get_free_fd(); @@ -284,10 +304,10 @@ pub fn sys_faccessat(dirfd: usize, path: *const u8, mode: usize, flags: usize) - // we trust pid 0 process info!( "faccessat: dirfd: {}, path: {:?}, mode: {:#o}, flags: {:?}", - dirfd, path, mode, flags + dirfd as isize, path, mode, flags ); } - let inode = proc.lookup_inode_at(dirfd, &path)?; + let inode = proc.lookup_inode_at(dirfd, &path, !flags.contains(AtFlags::SYMLINK_NOFOLLOW))?; Ok(0) } @@ -306,8 +326,7 @@ pub fn sys_getcwd(buf: *mut u8, len: usize) -> SysResult { } pub fn sys_lstat(path: *const u8, stat_ptr: *mut Stat) -> SysResult { - warn!("lstat is partial implemented as stat"); - sys_stat(path, stat_ptr) + sys_fstatat(AT_FDCWD, path, stat_ptr, AtFlags::SYMLINK_NOFOLLOW.bits()) } pub fn sys_fstat(fd: usize, stat_ptr: *mut Stat) -> SysResult { @@ -329,10 +348,10 @@ pub fn sys_fstatat(dirfd: usize, path: *const u8, stat_ptr: *mut Stat, flags: us let flags = AtFlags::from_bits_truncate(flags); info!( "fstatat: dirfd: {}, path: {:?}, stat_ptr: {:?}, flags: {:?}", - dirfd, path, stat_ptr, flags + dirfd as isize, path, stat_ptr, flags ); - let inode = proc.lookup_inode_at(dirfd, &path)?; + let inode = proc.lookup_inode_at(dirfd, &path, !flags.contains(AtFlags::SYMLINK_NOFOLLOW))?; let stat = Stat::from(inode.metadata()?); unsafe { stat_ptr.write(stat); @@ -354,7 +373,7 @@ pub fn sys_readlinkat(dirfd: usize, path: *const u8, base: *mut u8, len: usize) proc.vm.check_write_array(base, len)?; info!("readlink: path: {:?}, base: {:?}, len: {}", path, base, len); - let inode = proc.lookup_inode_at(dirfd, &path)?; + let inode = proc.lookup_inode_at(dirfd, &path, false)?; if inode.metadata()?.type_ == FileType::SymLink { // TODO: recursive link resolution and loop detection let mut slice = unsafe { slice::from_raw_parts_mut(base, len) }; @@ -472,12 +491,9 @@ pub fn sys_chdir(path: *const u8) -> SysResult { if path.len() > 0 { let cwd = match path.as_bytes()[0] { b'/' => String::from("/"), - _ => proc.cwd.clone() + _ => proc.cwd.clone(), }; - let mut cwd_vec:Vec<_> = - cwd.split("/") - .filter(|&x| x != "") - .collect(); + let mut cwd_vec: Vec<_> = cwd.split("/").filter(|&x| x != "").collect(); let path_split = path.split("/").filter(|&x| x != ""); for seg in path_split { if seg == ".." { @@ -515,13 +531,13 @@ pub fn sys_renameat( let newpath = unsafe { proc.vm.check_and_clone_cstr(newpath)? }; info!( "renameat: olddirfd: {}, oldpath: {:?}, newdirfd: {}, newpath: {:?}", - olddirfd, oldpath, newdirfd, newpath + olddirfd as isize, oldpath, newdirfd as isize, newpath ); let (old_dir_path, old_file_name) = split_path(&oldpath); let (new_dir_path, new_file_name) = split_path(&newpath); - let old_dir_inode = proc.lookup_inode_at(olddirfd, old_dir_path)?; - let new_dir_inode = proc.lookup_inode_at(newdirfd, new_dir_path)?; + let old_dir_inode = proc.lookup_inode_at(olddirfd, old_dir_path, false)?; + let new_dir_inode = proc.lookup_inode_at(newdirfd, new_dir_path, false)?; old_dir_inode.move_(old_file_name, &new_dir_inode, new_file_name)?; Ok(0) } @@ -536,11 +552,11 @@ pub fn sys_mkdirat(dirfd: usize, path: *const u8, mode: usize) -> SysResult { // TODO: check pathname info!( "mkdirat: dirfd: {}, path: {:?}, mode: {:#o}", - dirfd, path, mode + dirfd as isize, path, mode ); let (dir_path, file_name) = split_path(&path); - let inode = proc.lookup_inode_at(dirfd, dir_path)?; + let inode = proc.lookup_inode_at(dirfd, dir_path, true)?; if inode.find(file_name).is_ok() { return Err(SysError::EEXIST); } @@ -580,12 +596,12 @@ pub fn sys_linkat( let flags = AtFlags::from_bits_truncate(flags); info!( "linkat: olddirfd: {}, oldpath: {:?}, newdirfd: {}, newpath: {:?}, flags: {:?}", - olddirfd, oldpath, newdirfd, newpath, flags + olddirfd as isize, oldpath, newdirfd as isize, newpath, flags ); let (new_dir_path, new_file_name) = split_path(&newpath); - let inode = proc.lookup_inode_at(olddirfd, &oldpath)?; - let new_dir_inode = proc.lookup_inode_at(newdirfd, new_dir_path)?; + let inode = proc.lookup_inode_at(olddirfd, &oldpath, true)?; + let new_dir_inode = proc.lookup_inode_at(newdirfd, new_dir_path, true)?; new_dir_inode.link(new_file_name, &inode)?; Ok(0) } @@ -600,11 +616,11 @@ pub fn sys_unlinkat(dirfd: usize, path: *const u8, flags: usize) -> SysResult { let flags = AtFlags::from_bits_truncate(flags); info!( "unlinkat: dirfd: {}, path: {:?}, flags: {:?}", - dirfd, path, flags + dirfd as isize, path, flags ); let (dir_path, file_name) = split_path(&path); - let dir_inode = proc.lookup_inode_at(dirfd, dir_path)?; + let dir_inode = proc.lookup_inode_at(dirfd, dir_path, true)?; let file_inode = dir_inode.find(file_name)?; if file_inode.metadata()?.type_ == FileType::Dir { return Err(SysError::EISDIR); @@ -647,8 +663,8 @@ pub fn sys_pipe(fds: *mut u32) -> SysResult { ); unsafe { - *fds = read_fd as u32; - *(fds.add(1)) = write_fd as u32; + fds.write(read_fd as u32); + fds.add(1).write(write_fd as u32); } info!("pipe: created rfd: {} wfd: {}", read_fd, write_fd); @@ -661,69 +677,60 @@ pub fn sys_sync() -> SysResult { Ok(0) } -pub fn sys_sendfile(out_fd: usize, in_fd: usize, offset: *mut usize, count: usize) -> SysResult { +pub fn sys_sendfile( + out_fd: usize, + in_fd: usize, + offset_ptr: *mut usize, + count: usize, +) -> SysResult { info!( - "sendfile: out: {}, in: {}, offset: {:?}, count: {}", - out_fd, in_fd, offset, count + "sendfile: out: {}, in: {}, offset_ptr: {:?}, count: {}", + out_fd, in_fd, offset_ptr, count ); let proc = process(); // We know it's save, pacify the borrow checker let proc_cell = UnsafeCell::new(proc); - let proc_in = unsafe { &mut *proc_cell.get() }; - let proc_out = unsafe { &mut *proc_cell.get() }; - //let in_file: &mut FileHandle = unsafe { &mut *UnsafeCell::new(proc.get_file(in_fd)?).get() }; - //let out_file: &mut FileHandle = unsafe { &mut *UnsafeCell::new(proc.get_file(out_fd)?).get() }; - let in_file = proc_in.get_file(in_fd)?; - let out_file = proc_out.get_file(out_fd)?; + let in_file = unsafe { (*proc_cell.get()).get_file(in_fd)? }; + let out_file = unsafe { (*proc_cell.get()).get_file(out_fd)? }; let mut buffer = [0u8; 1024]; - if offset.is_null() { - // read from current file offset - let mut bytes_read = 0; - while bytes_read < count { - let len = min(buffer.len(), count - bytes_read); - let read_len = in_file.read(&mut buffer[..len])?; - if read_len == 0 { - break; - } - bytes_read += read_len; - let mut bytes_written = 0; - while bytes_written < read_len { - let write_len = out_file.write(&buffer[bytes_written..])?; - if write_len == 0 { - return Err(SysError::EBADF); - } - bytes_written += write_len; - } - } - return Ok(bytes_read); - } else { - let proc_mem = unsafe { &mut *proc_cell.get() }; - proc_mem.vm.check_read_ptr(offset)?; - let mut read_offset = unsafe { *offset }; - // read from specified offset and write new offset back - let mut bytes_read = 0; - while bytes_read < count { - let len = min(buffer.len(), count - bytes_read); - let read_len = in_file.read_at(read_offset, &mut buffer[..len])?; - if read_len == 0 { - break; - } - bytes_read += read_len; - read_offset += read_len; - let mut bytes_written = 0; - while bytes_written < read_len { - let write_len = out_file.write(&buffer[bytes_written..])?; - if write_len == 0 { - return Err(SysError::EBADF); - } - bytes_written += write_len; - } - } + + let mut read_offset = if !offset_ptr.is_null() { unsafe { - *offset = read_offset; + (*proc_cell.get()).vm.check_read_ptr(offset_ptr)?; + offset_ptr.read() + } + } else { + in_file.seek(SeekFrom::Current(0))? as usize + }; + + // read from specified offset and write new offset back + let mut bytes_read = 0; + while bytes_read < count { + let len = min(buffer.len(), count - bytes_read); + let read_len = in_file.read_at(read_offset, &mut buffer[..len])?; + if read_len == 0 { + break; + } + bytes_read += read_len; + read_offset += read_len; + let mut bytes_written = 0; + while bytes_written < read_len { + let write_len = out_file.write(&buffer[bytes_written..])?; + if write_len == 0 { + return Err(SysError::EBADF); + } + bytes_written += write_len; } - return Ok(bytes_read); } + + if !offset_ptr.is_null() { + unsafe { + offset_ptr.write(read_offset); + } + } else { + in_file.seek(SeekFrom::Current(bytes_read as i64))?; + } + return Ok(bytes_read); } impl Process { @@ -751,12 +758,11 @@ impl Process { &self, dirfd: usize, path: &str, - // follow: bool, + follow: bool, ) -> Result, SysError> { - let follow = true; debug!( - "lookup_inode_at: fd: {:?}, cwd: {:?}, path: {:?}, follow: {:?}", - dirfd, self.cwd, path, follow + "lookup_inode_at: dirfd: {:?}, cwd: {:?}, path: {:?}, follow: {:?}", + dirfd as isize, self.cwd, path, follow ); let follow_max_depth = if follow { FOLLOW_MAX_DEPTH } else { 0 }; if dirfd == AT_FDCWD { @@ -773,7 +779,7 @@ impl Process { } pub fn lookup_inode(&self, path: &str) -> Result, SysError> { - self.lookup_inode_at(AT_FDCWD, path) + self.lookup_inode_at(AT_FDCWD, path, true) } } @@ -978,7 +984,55 @@ pub struct Stat { ctime: Timespec, } -#[cfg(not(target_arch = "x86_64"))] +#[cfg(target_arch = "mips")] +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] +pub struct Timespec { + pub sec: i32, + pub nsec: i32, +} + +#[cfg(target_arch = "mips")] +#[repr(C)] +#[derive(Debug)] +pub struct Stat { + /// ID of device containing file + dev: u64, + /// padding + __pad1: u64, + /// inode number + ino: u64, + /// file type and mode + mode: StatMode, + /// number of hard links + nlink: u32, + + /// user ID of owner + uid: u32, + /// group ID of owner + gid: u32, + /// device ID (if special file) + rdev: u64, + /// padding + __pad2: u64, + /// total size, in bytes + size: u64, + + /// last access time + atime: Timespec, + /// last modification time + mtime: Timespec, + /// last status change time + ctime: Timespec, + + /// blocksize for filesystem I/O + blksize: u32, + /// padding + __pad3: u32, + /// number of 512B blocks allocated + blocks: u64, +} + +#[cfg(not(any(target_arch = "x86_64", target_arch = "mips"))] #[repr(C)] #[derive(Debug)] pub struct Stat { @@ -1107,7 +1161,29 @@ impl From for Stat { } } - #[cfg(not(target_arch = "x86_64"))] + #[cfg(target_arch = "mips")] + fn from(info: Metadata) -> Self { + Stat { + dev: info.dev as u64, + ino: info.inode as u64, + mode: StatMode::from_type_mode(info.type_, info.mode as u16), + nlink: info.nlinks as u32, + uid: info.uid as u32, + gid: info.gid as u32, + rdev: 0, + size: info.size as u64, + blksize: info.blk_size as u32, + blocks: info.blocks as u64, + atime: Timespec { sec: info.atime.sec as i32, nsec: info.atime.nsec }, + mtime: Timespec { sec: info.mtime.sec as i32, nsec: info.mtime.nsec }, + ctime: Timespec { sec: info.ctime.sec as i32, nsec: info.ctime.nsec }, + __pad1: 0, + __pad2: 0, + __pad3: 0, + } + } + + #[cfg(not(any(target_arch = "x86_64", target_arch="mips")))] fn from(info: Metadata) -> Self { Stat { dev: info.dev as u64, @@ -1139,7 +1215,7 @@ pub struct IoVec { /// Starting address base: *mut u8, /// Number of bytes to transfer - len: u64, + len: usize, } /// A valid IoVecs request from user @@ -1160,15 +1236,15 @@ impl IoVecs { if iov.len > 0 { // skip empty iov if readv { - vm.check_write_array(iov.base, iov.len as usize)?; + vm.check_write_array(iov.base, iov.len)?; } else { - vm.check_read_array(iov.base, iov.len as usize)?; + vm.check_read_array(iov.base, iov.len)?; } } } let slices = iovs .iter() - .map(|iov| unsafe { slice::from_raw_parts_mut(iov.base, iov.len as usize) }) + .map(|iov| unsafe { slice::from_raw_parts_mut(iov.base, iov.len) }) .collect(); Ok(IoVecs(slices)) } diff --git a/kernel/src/syscall/mem.rs b/kernel/src/syscall/mem.rs index 1c5bee92..0b471c25 100644 --- a/kernel/src/syscall/mem.rs +++ b/kernel/src/syscall/mem.rs @@ -123,6 +123,21 @@ bitflags! { } } +#[cfg(target_arch = "mips")] +bitflags! { + pub struct MmapFlags: usize { + /// Changes are shared. + const SHARED = 1 << 0; + /// Changes are private. + const PRIVATE = 1 << 1; + /// Place the mapping at the exact address + const FIXED = 1 << 4; + /// The mapping is not backed by any file. (non-POSIX) + const ANONYMOUS = 0x800; + } +} + +#[cfg(not(target_arch = "mips"))] bitflags! { pub struct MmapFlags: usize { /// Changes are shared. diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index ef120523..15498e26 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -88,7 +88,7 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { } SYS_GETPID => sys_getpid(), // 40 - SYS_SENDFILE => sys_sendfile(args[0], args[1], args[3] as *mut usize, args[4]), + SYS_SENDFILE => sys_sendfile(args[0], args[1], args[2] as *mut usize, args[3]), SYS_SOCKET => sys_socket(args[0], args[1], args[2]), SYS_CONNECT => sys_connect(args[0], args[1] as *const SockAddr, args[2]), SYS_ACCEPT => sys_accept(args[0], args[1] as *mut SockAddr, args[2] as *mut u32), @@ -194,12 +194,28 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { warn!("sys_getegid is unimplemented"); Ok(0) } + SYS_SETPGID => { + warn!("sys_setpgid is unimplemented"); + Ok(0) + } // 110 SYS_GETPPID => sys_getppid(), SYS_SETSID => { warn!("sys_setsid is unimplemented"); Ok(0) } + SYS_GETPGID => { + warn!("sys_getpgid is unimplemented"); + Ok(0) + } + SYS_GETGROUPS => { + warn!("sys_getgroups is unimplemented"); + Ok(0) + } + SYS_SETGROUPS => { + warn!("sys_setgroups is unimplemented"); + Ok(0) + } SYS_SIGALTSTACK => { warn!("sys_sigaltstack is unimplemented"); Ok(0) @@ -213,6 +229,10 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { Err(SysError::EACCES) } SYS_SETPRIORITY => sys_set_priority(args[0]), + SYS_PRCTL => { + warn!("prctl is unimplemented"); + Ok(0) + } // SYS_SETRLIMIT => sys_setrlimit(), SYS_SYNC => sys_sync(), SYS_MOUNT => { @@ -254,11 +274,24 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { } SYS_NEWFSTATAT => sys_fstatat(args[0], args[1] as *const u8, args[2] as *mut Stat, args[3]), SYS_UNLINKAT => sys_unlinkat(args[0], args[1] as *const u8, args[2]), - SYS_READLINKAT => sys_readlinkat(args[0], args[1] as *const u8, args[2] as *mut u8, args[3]), SYS_RENAMEAT => sys_renameat(args[0], args[1] as *const u8, args[2], args[3] as *const u8), - SYS_LINKAT => sys_linkat(args[0], args[1] as *const u8, args[2], args[3] as *const u8, args[4]), + SYS_LINKAT => sys_linkat( + args[0], + args[1] as *const u8, + args[2], + args[3] as *const u8, + args[4], + ), SYS_SYMLINKAT => Err(SysError::EACCES), + SYS_READLINKAT => { + sys_readlinkat(args[0], args[1] as *const u8, args[2] as *mut u8, args[3]) + } + SYS_FCHMODAT => { + warn!("sys_fchmodat is unimplemented"); + Ok(0) + } SYS_FACCESSAT => sys_faccessat(args[0], args[1] as *const u8, args[2], args[3]), + SYS_PPOLL => sys_ppoll(args[0] as *mut PollFd, args[1], args[2] as *const TimeSpec), // ignore sigmask // 280 SYS_UTIMENSAT => { warn!("sys_utimensat is unimplemented"); @@ -286,8 +319,15 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { let x86_64_ret = x86_64_syscall(id, args, tf); #[cfg(not(target_arch = "x86_64"))] let x86_64_ret = None; + + #[cfg(target_arch = "mips")] + let mips_ret = mips_syscall(id, args, tf); + #[cfg(not(target_arch = "mips"))] + let mips_ret = None; if let Some(ret) = x86_64_ret { ret + } else if let Some(ret) = mips_ret { + ret } else { error!("unknown syscall id: {}, args: {:x?}", id, args); crate::trap::error(tf); @@ -307,6 +347,60 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { } } +#[cfg(target_arch = "mips")] +fn mips_syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> Option { + let ret = match id { + SYS_FORK => sys_fork(tf), + SYS_OPEN => sys_open(args[0] as *const u8, args[1], args[2]), + SYS_DUP2 => sys_dup2(args[0], args[1]), + SYS_MMAP2 => sys_mmap(args[0], args[1], args[2], args[3], args[4], args[5] * 4096), + SYS_FSTAT64 => sys_fstat(args[0], args[1] as *mut Stat), + SYS_LSTAT64 => sys_lstat(args[0] as *const u8, args[1] as *mut Stat), + SYS_STAT64 => sys_stat(args[0] as *const u8, args[1] as *mut Stat), + SYS_PIPE => { + let fd_ptr = args[0] as *mut u32; + match sys_pipe(fd_ptr) { + Ok(code) => { + unsafe { + tf.v0 = *fd_ptr as usize; + tf.v1 = *(fd_ptr.add(1)) as usize; + } + Ok(tf.v0) + }, + Err(err) => Err(err) + } + }, + SYS_GETPGID => { + warn!("sys_getpgid is unimplemented"); + Ok(0) + } + SYS_SETPGID => { + warn!("sys_setpgid is unimplemented"); + Ok(0) + } + SYS_FCNTL64 => { + warn!("sys_fcntl64 is unimplemented"); + Ok(0) + }, + SYS_SET_THREAD_AREA => { + info!("set_thread_area: tls: 0x{:x}", args[0]); + extern "C" { + fn _cur_tls(); + } + + unsafe { + asm!("mtc0 $0, $$4, 2": :"r"(args[0])); + *(_cur_tls as *mut usize) = args[0]; + } + Ok(0) + } + _ => { + return None; + } + }; + Some(ret) +} + #[cfg(target_arch = "x86_64")] fn x86_64_syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> Option { let ret = match id { @@ -324,7 +418,10 @@ fn x86_64_syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> Option sys_dup2(args[0], args[1]), - // SYS_PAUSE => sys_pause(), + SYS_ALARM => { + warn!("sys_alarm is unimplemented"); + Ok(0) + } SYS_FORK => sys_fork(tf), // use fork for vfork SYS_VFORK => sys_fork(tf), @@ -339,16 +436,12 @@ fn x86_64_syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> Option sys_arch_prctl(args[0] as i32, args[1], tf), - SYS_TIME => sys_time(args[0] as *mut u64), - SYS_ALARM => { - warn!("sys_alarm is unimplemented"); - Ok(0) - } SYS_CHOWN => { warn!("sys_chown is unimplemented"); Ok(0) } + SYS_ARCH_PRCTL => sys_arch_prctl(args[0] as i32, args[1], tf), + SYS_TIME => sys_time(args[0] as *mut u64), SYS_EPOLL_CREATE => { warn!("sys_epoll_create is unimplemented"); Err(SysError::ENOSYS) diff --git a/kernel/src/syscall/proc.rs b/kernel/src/syscall/proc.rs index c6cc4ece..89b77657 100644 --- a/kernel/src/syscall/proc.rs +++ b/kernel/src/syscall/proc.rs @@ -13,7 +13,7 @@ pub fn sys_fork(tf: &TrapFrame) -> SysResult { /// Create a new thread in the current process. /// The new thread's stack pointer will be set to `newsp`, -/// and thread pointer will be set to `newtls`. +/// and thread pointer will be set to `newtls`. /// The child tid will be stored at both `parent_tid` and `child_tid`. /// This is partially implemented for musl only. pub fn sys_clone( @@ -24,17 +24,19 @@ pub fn sys_clone( newtls: usize, tf: &TrapFrame, ) -> SysResult { + let clone_flags = CloneFlags::from_bits_truncate(flags); info!( - "clone: flags: {:#x}, newsp: {:#x}, parent_tid: {:?}, child_tid: {:?}, newtls: {:#x}", - flags, newsp, parent_tid, child_tid, newtls + "clone: flags: {:?} == {:#x}, newsp: {:#x}, parent_tid: {:?}, child_tid: {:?}, newtls: {:#x}", + clone_flags, flags, newsp, parent_tid, child_tid, newtls ); - if flags == 0x4111 { + if flags == 0x4111 || flags == 0x11 { warn!("sys_clone is calling sys_fork instead, ignoring other args"); return sys_fork(tf); } - if flags != 0x7d0f00 { - warn!("sys_clone only support musl pthread_create"); - return Err(SysError::ENOSYS); + if (flags != 0x7d0f00) && (flags!= 0x5d0f00) { //0x5d0f00 is the args from gcc of alpine linux + //warn!("sys_clone only support musl pthread_create"); + panic!("sys_clone only support sys_fork OR musl pthread_create without flags{:x}", flags); + //return Err(SysError::ENOSYS); } { let proc = process(); @@ -123,9 +125,9 @@ pub fn sys_exec( envp: *const *const u8, tf: &mut TrapFrame, ) -> SysResult { - info!("exec: name: {:?}, argv: {:?} envp: {:?}", name, argv, envp); + info!("exec: name: {:?}, argv: {:?}, envp: {:?}", name, argv, envp); let proc = process(); - let _name = if name.is_null() { + let exec_name = if name.is_null() { String::from("") } else { unsafe { proc.vm.check_and_clone_cstr(name)? } @@ -145,19 +147,37 @@ pub fn sys_exec( current_argv = current_argv.add(1); } } - info!("exec: args {:?}", args); + // Check and copy envs to kernel + let mut envs = Vec::new(); + unsafe { + let mut current_env = envp as *const *const u8; + if !current_env.is_null() { + proc.vm.check_read_ptr(current_env)?; + while !(*current_env).is_null() { + let env = proc.vm.check_and_clone_cstr(*current_env)?; + envs.push(env); + current_env = current_env.add(1); + } + } + } + if args.is_empty() { return Err(SysError::EINVAL); } + info!( + "exec: name: {:?}, args: {:?}, envp: {:?}", + exec_name, args, envs + ); + // Read program file - let path = args[0].as_str(); - let inode = proc.lookup_inode(path)?; + //let path = args[0].as_str(); + let exec_path = exec_name.as_str(); + let inode = proc.lookup_inode(exec_path)?; let buf = inode.read_as_vec()?; // Make new Thread - let iter = args.iter().map(|s| s.as_str()); - let mut thread = Thread::new_user(buf.as_slice(), iter); + let mut thread = Thread::new_user(buf.as_slice(), exec_path, args, envs); thread.proc.lock().clone_for_exec(&proc); // Activate new page table @@ -231,7 +251,11 @@ pub fn sys_gettid() -> SysResult { /// Get the parent process id pub fn sys_getppid() -> SysResult { - Ok(process().parent.as_ref().unwrap().lock().pid.get()) + if let Some(ref parent) = process().parent.as_ref() { + Ok(parent.lock().pid.get()) + } else { + Ok(0) + } } /// Exit the current thread @@ -313,3 +337,30 @@ pub fn sys_set_priority(priority: usize) -> SysResult { processor().manager().set_priority(pid, priority as u8); Ok(0) } + +bitflags! { + pub struct CloneFlags: usize { + const CSIGNAL = 0x000000ff; + const VM = 0x0000100; + const FS = 0x0000200; + const FILES = 0x0000400; + const SIGHAND = 0x0000800; + const PTRACE = 0x0002000; + const VFORK = 0x0004000; + const PARENT = 0x0008000; + const SYSVSEM = 0x0008000; + const SETTLS = 0x0008000; + const PARENT_SETTID = 0x0010000; + const CHILD_CLEARTID = 0x0020000; + const DETACHED = 0x0040000; + const UNTRACED = 0x0080000; + const CHILD_SETTID = 0x0100000; + const NEWCGROUP = 0x0200000; + const NEWUTS = 0x0400000; + const NEWIPC = 0x0800000; + const NEWUSER = 0x1000000; + const NEWPID = 0x2000000; + const NEWNET = 0x4000000; + const IO = 0x8000000; + } +} diff --git a/kernel/src/syscall/time.rs b/kernel/src/syscall/time.rs index 2ae76d46..faae93e2 100644 --- a/kernel/src/syscall/time.rs +++ b/kernel/src/syscall/time.rs @@ -19,6 +19,7 @@ const USEC_PER_SEC: u64 = 1_000_000; const MSEC_PER_SEC: u64 = 1_000; const USEC_PER_MSEC: u64 = 1_000; const NSEC_PER_USEC: u64 = 1_000; +const NSEC_PER_MSEC: u64 = 1_000_000; /// Get time since epoch in usec fn get_epoch_usec() -> u64 { @@ -32,20 +33,20 @@ fn get_epoch_usec() -> u64 { #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct TimeVal { - sec: u64, - usec: u64, + sec: usize, + usec: usize, } impl TimeVal { pub fn to_msec(&self) -> u64 { - self.sec * MSEC_PER_SEC + self.usec / USEC_PER_MSEC + (self.sec as u64) * MSEC_PER_SEC + (self.usec as u64) / USEC_PER_MSEC } pub fn get_epoch() -> Self { let usec = get_epoch_usec(); TimeVal { - sec: usec / USEC_PER_SEC, - usec: usec % USEC_PER_SEC, + sec: (usec / USEC_PER_SEC) as usize, + usec: (usec % USEC_PER_SEC) as usize, } } } @@ -53,20 +54,24 @@ impl TimeVal { #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct TimeSpec { - sec: u64, - nsec: u64, + sec: usize, + nsec: usize, } impl TimeSpec { + pub fn to_msec(&self) -> u64 { + (self.sec as u64) * MSEC_PER_SEC + (self.nsec as u64) / NSEC_PER_MSEC + } + pub fn to_duration(&self) -> Duration { - Duration::new(self.sec, self.nsec as u32) + Duration::new(self.sec as u64, self.nsec as u32) } pub fn get_epoch() -> Self { let usec = get_epoch_usec(); TimeSpec { - sec: usec / USEC_PER_SEC, - nsec: usec % USEC_PER_SEC * NSEC_PER_USEC, + sec: (usec / USEC_PER_SEC) as usize, + nsec: (usec % USEC_PER_SEC * NSEC_PER_USEC) as usize, } } } @@ -130,12 +135,12 @@ pub fn sys_getrusage(who: usize, rusage: *mut RUsage) -> SysResult { let usec = (tick - tick_base) * USEC_PER_TICK as u64; let new_rusage = RUsage { utime: TimeVal { - sec: usec / USEC_PER_SEC, - usec: usec % USEC_PER_SEC, + sec: (usec / USEC_PER_SEC) as usize, + usec: (usec % USEC_PER_SEC) as usize, }, stime: TimeVal { - sec: usec / USEC_PER_SEC, - usec: usec % USEC_PER_SEC, + sec: (usec / USEC_PER_SEC) as usize, + usec: (usec % USEC_PER_SEC) as usize, }, }; unsafe { *rusage = new_rusage }; diff --git a/kernel/src/util/mod.rs b/kernel/src/util/mod.rs index ee7eb609..e1ecb670 100644 --- a/kernel/src/util/mod.rs +++ b/kernel/src/util/mod.rs @@ -83,4 +83,4 @@ pub fn write(addr: usize, content: T) { pub fn read(addr: usize) -> T { let cell = (addr) as *const T; unsafe { read_volatile(cell) } -} \ No newline at end of file +} diff --git a/riscv-pk b/riscv-pk deleted file mode 160000 index 405ea59d..00000000 --- a/riscv-pk +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 405ea59dd7dd2762c5883822f21d9995bea32b0c diff --git a/tools/addr2line.py b/tools/addr2line.py index a7a1e79d..f02b415b 100644 --- a/tools/addr2line.py +++ b/tools/addr2line.py @@ -10,11 +10,11 @@ arch = sys.argv[2] mode = sys.argv[3] print('--------------------------------------') for line in lines: - match = re.search('(#[0-9]+ )(0x[0-9A-F]+)( fp 0x[0-9A-F]+)', line) + match = re.search('#([0-9]+) PC: (0x[0-9A-F]+) FP: (0x[0-9A-F]+)', line) if match: addr = match.group(2) process = subprocess.run([addrline, '-e', 'target/{0}/{1}/rcore'.format(arch, mode), '-f', '-C', addr], capture_output=True) res = process.stdout.decode('utf-8') - print('{0}{1}{3} {2}'.format(match.group(1), match.group(2), res.strip(), match.group(3))) + print('#{0} PC: {1} FP: {3} {2}'.format(match.group(1), match.group(2), res.strip(), match.group(3))) else: print(line, end='') diff --git a/tools/opensbi/README.md b/tools/opensbi/README.md new file mode 100644 index 00000000..79ad945a --- /dev/null +++ b/tools/opensbi/README.md @@ -0,0 +1,9 @@ +# OpenSBI + +These are binary release of OpenSBI on this [commit](https://github.com/riscv/opensbi/tree/194dbbe5a13dff2255411c26d249f3ad4ef42c0b) at 2019.04.15. + +- fu540.elf: opensbi-0.3-rv64-bin/platform/sifive/fu540/firmware/fw_jump.elf +- virt_rv32.elf: opensbi-0.3-rv32-bin/platform/qemu/virt/firmware/fw_jump.elf +- virt_rv64.elf: opensbi-0.3-rv64-bin/platform/qemu/virt/firmware/fw_jump.elf + +NOTE: The [official v0.3 release](https://github.com/riscv/opensbi/releases/tag/v0.3) has bug on serial interrupt. diff --git a/tools/opensbi/fu540.elf b/tools/opensbi/fu540.elf new file mode 100755 index 00000000..4b76fae3 Binary files /dev/null and b/tools/opensbi/fu540.elf differ diff --git a/tools/opensbi/virt_rv32.elf b/tools/opensbi/virt_rv32.elf new file mode 100755 index 00000000..1bebfb05 Binary files /dev/null and b/tools/opensbi/virt_rv32.elf differ diff --git a/tools/opensbi/virt_rv64.elf b/tools/opensbi/virt_rv64.elf new file mode 100755 index 00000000..6e941c0c Binary files /dev/null and b/tools/opensbi/virt_rv64.elf differ diff --git a/user b/user index fdaa1be8..8dbc0edb 160000 --- a/user +++ b/user @@ -1 +1 @@ -Subproject commit fdaa1be8635944d88ff128da13bf0464f7ce2eb6 +Subproject commit 8dbc0edb935a62d748aaac39258d4a985de0ae17