diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..a82d3f0 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.14) + +project(ChUrlOS) + +add_subdirectory(cmake) + +set(CMAKE_VERBOSE_MAKEFILE ON) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) \ No newline at end of file diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt new file mode 100644 index 0000000..1bee493 --- /dev/null +++ b/cmake/CMakeLists.txt @@ -0,0 +1,36 @@ +cmake_minimum_required(VERSION 3.14) + +# Set source directory variables +set(CHURLOS_ROOT_DIR "${CMAKE_CURRENT_LIST_DIR}/..") +set(CHURLOS_SRC_DIR "${CHURLOS_ROOT_DIR}/src") +set(CHURLOS_TOOL_DIR "${CHURLOS_ROOT_DIR}/tools") + +# Set output directory variables +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/static) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/shared) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) + +# Force out of source build +message(STATUS "Force out of source build check...") +string(COMPARE EQUAL "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}" insource) +if (insource) + message(FATAL_ERROR "Please do not build in your source dir. Use a dedicated build folder!") +endif () + +# Set compiler-flags +ENABLE_LANGUAGE(ASM_NASM) +set(CMAKE_ASM_NASM_OBJECT_FORMAT "elf32") +set(CMAKE_ASM_NASM_INCLUDES "${CHURLOS_SRC_DIR}/") +set(CMAKE_ASM_NASM_COMPILE_OBJECT " -I${CMAKE_ASM_NASM_INCLUDES} -f ${CMAKE_ASM_NASM_OBJECT_FORMAT} -o ") +set(CMAKE_C_FLAGS "-m32 -march=i386 -mfpmath=387 -mno-mmx -mno-sse -mno-avx -Wall -fno-stack-protector -nostdlib -fno-pic -no-pie -ffreestanding") +if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 9) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mmanual-endbr") +endif() +set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -Wl,--build-id=none -Wno-non-virtual-dtor -fno-threadsafe-statics -Wplacement-new=0 -fno-use-cxa-atexit -fno-rtti -fno-exceptions -std=c++20 -T ${CHURLOS_SRC_DIR}/link.ld") + +# Add subdirectories +add_subdirectory(bootdisk) +add_subdirectory(device) +add_subdirectory(kernel) +add_subdirectory(lib) +add_subdirectory(system) diff --git a/cmake/bootdisk/CMakeLists.txt b/cmake/bootdisk/CMakeLists.txt new file mode 100644 index 0000000..736c658 --- /dev/null +++ b/cmake/bootdisk/CMakeLists.txt @@ -0,0 +1,30 @@ +cmake_minimum_required(VERSION 3.14) + +project(bootdisk) +message(STATUS "Project " ${PROJECT_NAME}) + +# BIOS-dev.code:total-tracks:-heads:-sectors:start-track:-head:-sector +# Default-Werte fuer Boot von Floppy (USB/HD erkennt bootsect.asm selbst): +set(BOOTDEVICE "0:80:2:18:0:0:1") + +add_custom_command(OUTPUT "${CHURLOS_ROOT_DIR}/bootdisk.vmi" + BYPRODUCTS "${CMAKE_BINARY_DIR}/bootsect" "${CMAKE_BINARY_DIR}/setup" "${CMAKE_BINARY_DIR}/build" "${CMAKE_BINARY_DIR}/system.img" "${CMAKE_BINARY_DIR}/bootdisk.img" "${CMAKE_BINARY_DIR}/bootdisk.vmi" + + # Compile bootsect and setup code + COMMAND nasm -f bin -o "${CMAKE_BINARY_DIR}/bootsect" "${CHURLOS_SRC_DIR}/bootdisk/bootsect.asm" + COMMAND nasm -f bin -o "${CMAKE_BINARY_DIR}/setup" "${CHURLOS_SRC_DIR}/bootdisk/setup.asm" + + # Compile build code + COMMAND gcc -o "${CMAKE_BINARY_DIR}/build" "${CHURLOS_SRC_DIR}/bootdisk/build.c" + + # Build system.img + COMMAND objcopy -O binary "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/system" "${CMAKE_BINARY_DIR}/system.img" + + # Build bootdisk + COMMAND "${CMAKE_BINARY_DIR}/build" "${CMAKE_BINARY_DIR}/bootsect" "${CMAKE_BINARY_DIR}/setup" "${CMAKE_BINARY_DIR}/system.img" ${BOOTDEVICE} "${CMAKE_BINARY_DIR}/bootdisk.img" + COMMAND dd if="${CMAKE_BINARY_DIR}/bootdisk.img" of="${CMAKE_BINARY_DIR}/bootdisk.vmi" bs=1474560 conv=sync + COMMAND /run/current-system/sw/bin/cp "${CMAKE_BINARY_DIR}/bootdisk.vmi" "${CHURLOS_ROOT_DIR}/bootdisk.vmi" + DEPENDS system + ) + +add_custom_target(${PROJECT_NAME} DEPENDS ${CHURLOS_ROOT_DIR}/bootdisk.vmi) diff --git a/cmake/device/CMakeLists.txt b/cmake/device/CMakeLists.txt new file mode 100644 index 0000000..168a062 --- /dev/null +++ b/cmake/device/CMakeLists.txt @@ -0,0 +1,18 @@ +cmake_minimum_required(VERSION 3.14) + +project(device) +message(STATUS "Project " ${PROJECT_NAME}) + +include_directories(${CHURLOS_SRC_DIR}) + +add_library(${PROJECT_NAME} STATIC ${SOURCE_FILES}) + +# Add subdirectories +add_subdirectory(bios) +add_subdirectory(cpu) +add_subdirectory(graphics) +add_subdirectory(hid) +add_subdirectory(interrupt) +add_subdirectory(port) +add_subdirectory(sound) +add_subdirectory(time) diff --git a/cmake/device/bios/CMakeLists.txt b/cmake/device/bios/CMakeLists.txt new file mode 100644 index 0000000..8e4b6f1 --- /dev/null +++ b/cmake/device/bios/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.14) + +target_sources(device PUBLIC + ${CHURLOS_SRC_DIR}/device/bios/BIOS.cc + ) diff --git a/cmake/device/cpu/CMakeLists.txt b/cmake/device/cpu/CMakeLists.txt new file mode 100644 index 0000000..95a0d9b --- /dev/null +++ b/cmake/device/cpu/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.14) + +# target_sources(device PUBLIC +# ${CHURLOS_SRC_DIR}/ +# ) diff --git a/cmake/device/graphics/CMakeLists.txt b/cmake/device/graphics/CMakeLists.txt new file mode 100644 index 0000000..92e2222 --- /dev/null +++ b/cmake/device/graphics/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 3.14) + +target_sources(device PUBLIC + ${CHURLOS_SRC_DIR}/device/graphics/CGA.cc + ${CHURLOS_SRC_DIR}/device/graphics/CGA_Stream.cc + ${CHURLOS_SRC_DIR}/device/graphics/Fonts.cc + ${CHURLOS_SRC_DIR}/device/graphics/LFBgraphics.cc + ${CHURLOS_SRC_DIR}/device/graphics/VESA.cc + ) diff --git a/cmake/device/hid/CMakeLists.txt b/cmake/device/hid/CMakeLists.txt new file mode 100644 index 0000000..6101496 --- /dev/null +++ b/cmake/device/hid/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.14) + +target_sources(device PUBLIC + ${CHURLOS_SRC_DIR}/device/hid/Keyboard.cc + ) diff --git a/cmake/device/interrupt/CMakeLists.txt b/cmake/device/interrupt/CMakeLists.txt new file mode 100644 index 0000000..ee682e3 --- /dev/null +++ b/cmake/device/interrupt/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.14) + +target_sources(device PUBLIC + ${CHURLOS_SRC_DIR}/device/interrupt/PIC.cc + ) diff --git a/cmake/device/port/CMakeLists.txt b/cmake/device/port/CMakeLists.txt new file mode 100644 index 0000000..93a2a30 --- /dev/null +++ b/cmake/device/port/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.14) + +target_sources(device PUBLIC + ${CHURLOS_SRC_DIR}/device/port/SerialOut.cc + ) diff --git a/cmake/device/sound/CMakeLists.txt b/cmake/device/sound/CMakeLists.txt new file mode 100644 index 0000000..1968ef7 --- /dev/null +++ b/cmake/device/sound/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.14) + +target_sources(device PUBLIC + ${CHURLOS_SRC_DIR}/device/sound/PCSPK.cc + ) diff --git a/cmake/device/time/CMakeLists.txt b/cmake/device/time/CMakeLists.txt new file mode 100644 index 0000000..8d7f918 --- /dev/null +++ b/cmake/device/time/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.14) + +target_sources(device PUBLIC + ${CHURLOS_SRC_DIR}/device/time/PIT.cc + ) diff --git a/cmake/kernel/CMakeLists.txt b/cmake/kernel/CMakeLists.txt new file mode 100644 index 0000000..b4f3216 --- /dev/null +++ b/cmake/kernel/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 3.14) + +project(kernel) +message(STATUS "Project " ${PROJECT_NAME}) + +include_directories(${CHURLOS_SRC_DIR}) + +add_library(${PROJECT_NAME} STATIC ${SOURCE_FILES}) + +# Add subdirectories +add_subdirectory(demo) +add_subdirectory(event) +add_subdirectory(interrupt) +add_subdirectory(log) +add_subdirectory(memory) +add_subdirectory(process) +add_subdirectory(system) diff --git a/cmake/kernel/demo/CMakeLists.txt b/cmake/kernel/demo/CMakeLists.txt new file mode 100644 index 0000000..b6de868 --- /dev/null +++ b/cmake/kernel/demo/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 3.14) + +target_sources(kernel PUBLIC + ${CHURLOS_SRC_DIR}/kernel/demo/ArrayDemo.cc + ${CHURLOS_SRC_DIR}/kernel/demo/bmp_hhu.cc + ${CHURLOS_SRC_DIR}/kernel/demo/HeapDemo.cc + ${CHURLOS_SRC_DIR}/kernel/demo/KeyboardDemo.cc + ${CHURLOS_SRC_DIR}/kernel/demo/MainMenu.cc + ${CHURLOS_SRC_DIR}/kernel/demo/PagingDemo.cc + ${CHURLOS_SRC_DIR}/kernel/demo/PCSPKdemo.cc + ${CHURLOS_SRC_DIR}/kernel/demo/PreemptiveThreadDemo.cc + ${CHURLOS_SRC_DIR}/kernel/demo/SmartPointerDemo.cc + ${CHURLOS_SRC_DIR}/kernel/demo/StringDemo.cc + ${CHURLOS_SRC_DIR}/kernel/demo/TextDemo.cc + ${CHURLOS_SRC_DIR}/kernel/demo/VBEdemo.cc + ${CHURLOS_SRC_DIR}/kernel/demo/VectorDemo.cc + ) diff --git a/cmake/kernel/event/CMakeLists.txt b/cmake/kernel/event/CMakeLists.txt new file mode 100644 index 0000000..86ec4b5 --- /dev/null +++ b/cmake/kernel/event/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.14) + +target_sources(kernel PUBLIC + ${CHURLOS_SRC_DIR}/kernel/event/KeyEventListener.cc + ${CHURLOS_SRC_DIR}/kernel/event/KeyEventManager.cc + ) diff --git a/cmake/kernel/interrupt/CMakeLists.txt b/cmake/kernel/interrupt/CMakeLists.txt new file mode 100644 index 0000000..6bd219e --- /dev/null +++ b/cmake/kernel/interrupt/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.14) + +target_sources(kernel PUBLIC + ${CHURLOS_SRC_DIR}/kernel/interrupt/Bluescreen.cc + ${CHURLOS_SRC_DIR}/kernel/interrupt/IntDispatcher.cc + ) diff --git a/cmake/kernel/log/CMakeLists.txt b/cmake/kernel/log/CMakeLists.txt new file mode 100644 index 0000000..f1207c3 --- /dev/null +++ b/cmake/kernel/log/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.14) + +target_sources(kernel PUBLIC + ${CHURLOS_SRC_DIR}/kernel/log/Logger.cc + ) diff --git a/cmake/kernel/memory/CMakeLists.txt b/cmake/kernel/memory/CMakeLists.txt new file mode 100644 index 0000000..10db582 --- /dev/null +++ b/cmake/kernel/memory/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.14) + +target_sources(kernel PUBLIC + ${CHURLOS_SRC_DIR}/kernel/memory/Allocator.cc + ${CHURLOS_SRC_DIR}/kernel/memory/BumpAllocator.cc + ${CHURLOS_SRC_DIR}/kernel/memory/LinkedListAllocator.cc + ${CHURLOS_SRC_DIR}/kernel/memory/Paging.cc + ) diff --git a/cmake/kernel/process/CMakeLists.txt b/cmake/kernel/process/CMakeLists.txt new file mode 100644 index 0000000..d8b6eec --- /dev/null +++ b/cmake/kernel/process/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 3.14) + +target_sources(kernel PUBLIC + ${CHURLOS_SRC_DIR}/kernel/process/Scheduler.cc + ${CHURLOS_SRC_DIR}/kernel/process/Thread.cc + ${CHURLOS_SRC_DIR}/kernel/process/Thread.asm + ) diff --git a/cmake/kernel/system/CMakeLists.txt b/cmake/kernel/system/CMakeLists.txt new file mode 100644 index 0000000..19f20f3 --- /dev/null +++ b/cmake/kernel/system/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.14) + +target_sources(kernel PUBLIC + ${CHURLOS_SRC_DIR}/kernel/system/Globals.cc + ) diff --git a/cmake/lib/CMakeLists.txt b/cmake/lib/CMakeLists.txt new file mode 100644 index 0000000..bec97ec --- /dev/null +++ b/cmake/lib/CMakeLists.txt @@ -0,0 +1,14 @@ +cmake_minimum_required(VERSION 3.14) + +project(lib) +message(STATUS "Project " ${PROJECT_NAME}) + +include_directories(${CHURLOS_SRC_DIR}) + +add_library(${PROJECT_NAME} STATIC ${SOURCE_FILES}) + +# Add subdirectories +add_subdirectory(async) +add_subdirectory(mem) +add_subdirectory(stream) +add_subdirectory(util) diff --git a/cmake/lib/async/CMakeLists.txt b/cmake/lib/async/CMakeLists.txt new file mode 100644 index 0000000..99b25b3 --- /dev/null +++ b/cmake/lib/async/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.14) + +target_sources(lib PUBLIC + ${CHURLOS_SRC_DIR}/lib/async/Semaphore.cc + ${CHURLOS_SRC_DIR}/lib/async/SpinLock.cc + ) diff --git a/cmake/lib/mem/CMakeLists.txt b/cmake/lib/mem/CMakeLists.txt new file mode 100644 index 0000000..264fc50 --- /dev/null +++ b/cmake/lib/mem/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.14) + +target_sources(lib PUBLIC + ${CHURLOS_SRC_DIR}/lib/mem/Memory.cc + ) diff --git a/cmake/lib/stream/CMakeLists.txt b/cmake/lib/stream/CMakeLists.txt new file mode 100644 index 0000000..0d85897 --- /dev/null +++ b/cmake/lib/stream/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.14) + +target_sources(lib PUBLIC + ${CHURLOS_SRC_DIR}/lib/stream/OutStream.cc + ) diff --git a/cmake/lib/util/CMakeLists.txt b/cmake/lib/util/CMakeLists.txt new file mode 100644 index 0000000..e7a802f --- /dev/null +++ b/cmake/lib/util/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 3.14) + +target_sources(lib PUBLIC + ${CHURLOS_SRC_DIR}/lib/util/String.cc + ${CHURLOS_SRC_DIR}/lib/util/StringBuffer.cc + ${CHURLOS_SRC_DIR}/lib/util/StringView.cc + ) diff --git a/cmake/system/CMakeLists.txt b/cmake/system/CMakeLists.txt new file mode 100644 index 0000000..1bd99c8 --- /dev/null +++ b/cmake/system/CMakeLists.txt @@ -0,0 +1,16 @@ +cmake_minimum_required(VERSION 3.14) + +project(system) +message(STATUS "Project " ${PROJECT_NAME}) + +include_directories(${CHURLOS_SRC_DIR}) + +# Set source files +set(SOURCE_FILES + ${CHURLOS_SRC_DIR}/startup.asm + ${CHURLOS_SRC_DIR}/main.cc + ) + +add_executable(${PROJECT_NAME} ${SOURCE_FILES}) + +target_link_libraries(${PROJECT_NAME} device kernel lib) diff --git a/src/bootdisk/bootsect.asm b/src/bootdisk/bootsect.asm new file mode 100644 index 0000000..4b3b7df --- /dev/null +++ b/src/bootdisk/bootsect.asm @@ -0,0 +1,324 @@ +; $Id: bootsect.asm 5001 2012-10-12 11:34:05Z os $ + +;****************************************************************************** +;* Betriebssysteme * +;*----------------------------------------------------------------------------* +;* * +;* B O O T S E C T * +;* * +;*----------------------------------------------------------------------------* +;* Code fuer den Disketten-Bootblock des System-Images. Das BIOS laedt den * +;* ersten Block einer Diskette (den Bootblock) beim Starten des Rechner in * +;* den Hauptspeicher und fuehrt ihn aus. Der Programmcode des Bootblocks * +;* laedt nun das restliche System und fuehrt es aus. * +;****************************************************************************** + +; +; Konstanten +; + BIOSSEG equ 0x07c0 ; Hierher wird der Bootsector + ; vom BIOS geladen + BOOTSEG equ 0x0060 ; Hierher verschiebt sich der + ; Boot-Code + SETUPSEG equ 0x9000 ; Hierher laedt der Boot-Code den + ; Setup-Code (max. 64K inkl. Stack) + SYSTEMSEG equ 0x1000 ; System-Code (max. 512K) + SECTORSZ equ 512 ; Groesse eines Sektors in Bytes + +[SECTION .text] + +; +; Boot-Code +; +bootsector: + jmp skip_data + +;------------------------------------------------------------------------------ +; +; Datenbereich, der von 'build' beim Erzeugen der Boot-Diskette +; gefuellt wird. +; +pad: + times 4+bootsector-$ db 0 ; Bytes zum Auffuellen, damit 'total_tracks' an einer + ; geraden und tools/build.c bekannten Adresse liegt +total_tracks: + dw 0 ; Anzahl der Tracks der Diskette +total_heads: + dw 0 ; Anzahl der Seiten der Diskette +total_sectors: + dw 0 ; Anzahl der Sektoren pro Track +setup_sectors: + dw 0 ; Anzahl der Sektoren, die der Setup-Code einnimmt +system_sectors: + dw 0 ; Anzahl der Sektoren, die das System einnimmt +bootdevice: + db 0 ; BIOS Geraetecode: 00: Disk A, 01: Disk B, ..., 0x80 HD0, ... +curr_track: + db 0 ; Track, bei dem die Diskette/Partition beginnt +curr_head: + db 0 ; Head, bei dem die Diskette/Partition beginnt +curr_sector: + db 0 ; Sector, bei dem die Diskette/Partition beginnt + +;----------------------------------------------------------------------- + +; +; Kopieren des Bootsectors +; +skip_data: + mov bl,dl ; vom BIOS uebergebenes Boot-Device sichern + + mov ax,BIOSSEG + mov ds,ax + xor si,si + mov ax,BOOTSEG + mov es,ax + xor di,di + mov cx,SECTORSZ/2 + rep movsw +; +; Ausfuehrung durch die Kopie fortsetzen +; + jmp BOOTSEG:start +; +; Segmentregister initialisieren und Platz fuer den Stack schaffen +; +start: + mov ax,cs ; Daten-, Stack- und Codesegment sollen + mov ds,ax ; hierher zeigen. + mov ss,ax + mov sp,4*SECTORSZ ; Drei Sektoren als Stack freilassen + + mov [bootdevice],bl ; zuvor gesichertes Boot-Device permanent ablegen + +; +; Ausgabe einer Meldung mit Hilfe eines BIOS-Aufrufs +; + mov ah,0x03 ; Feststellen der Cursor-Position + xor bh,bh + int 0x10 + + mov cx,13 + mov bx,0x0007 ; page 0, attribute 7 (normal) + mov ax,ds + mov es,ax + mov bp,bootmessage + mov ax,0x1301 ; Ausgabe des Textes, Cursor bewegen + int 0x10 +; +; Nachladen des Setup-Codes und des Systems selbst. +; + xor ah,ah ; Reset des Disketten-/Plattencontrollers + mov dl,[bootdevice] + int 0x13 +; +; Informationen ueber die Laufwerksgeometrie holen +; +hdd_probe: + mov dl,[bootdevice] + test dl,0x80 + jz load_setup ; Floppy mit den Standardparametern laden + mov ah,0x8 + int 0x13 + jc load_setup ; CF bei Fehler gesetzt + mov [total_heads],dh + mov ax,cx ; CX sichern + and ax,0x3f + mov [total_sectors],ax + mov ax,cx + shr ax,6 + mov [total_tracks],ax + +; +; Weiterstellen der Disketten-/Plattenposition um 1 (Bootblock) +; +load_setup: + call step_disk + +; +; Laden des Setup-Codes +; + mov word [curr_segment],SETUPSEG + mov word [curr_offset],0 + mov ax,[setup_sectors] + call load +; +; Laden des Kernels +; + mov word [curr_segment],SYSTEMSEG + mov word [curr_offset],0 + mov ax,[system_sectors] + call load +; +; Floppy wieder abschalten +; + call stop_floppy_motor +; +; Start des Setup-Codes +; + mov ax, [system_sectors] ; Speichere Anzahl an System-Sektoren in AX. + jmp SETUPSEG:0 + +; +; load +; +; Die 'ax' Sektoren von der Diskette in den Hauptspeicher. Die Position auf +; der Diskette muss vorher in curr_head/curr_track/curr_sector und die +; Position im Hauptspeicher in curr_segment/curr_offset stehen. Die Positionen +; werden entsprechend der geladenen Sektoren weitergestellt. +; +load: + mov [to_load],ax +l_next_part: + mov al,[curr_head] + mov [last_head],al + mov al,[curr_track] + mov [last_track],al + mov al,[curr_sector] + mov [last_sector],al + mov ax,[curr_segment] + mov [last_segment],ax + mov ax,[curr_offset] + mov [last_offset],ax + + mov al,0 + +l_loop: call step + + cmp byte [curr_sector],0x01 + je l_now + cmp word [curr_offset],0x0000 + je l_now + cmp al,[to_load] + jne l_loop + +l_now: + push ax + mov dl,[bootdevice] + mov dh,[last_head] + mov ch,[last_track] + mov cl,[last_sector] + mov bx,[last_segment] + mov es,bx + mov bx,[last_offset] + mov ah,0x02 ; Funktionscode fuer 'Lesen' + int 0x13 + pop ax + + push ax + call print_dot + pop ax + + mov ah,0 + sub [to_load],ax + jne l_next_part + ret + +; +; step +; +; Stellt die aktuelle Position im Hauptspeicher und auf der Diskette +; um einen Sektor (512 Byte) weiter. +; +step: add al,1 + call step_disk + call step_memory + ret + +step_disk: + mov bl,[curr_sector] + add bl,1 + mov [curr_sector],bl + cmp bl,[total_sectors] + jle l_1 + mov byte [curr_sector],1 + + mov bl,[curr_head] + add bl,1 + mov [curr_head],bl + cmp bl,[total_heads] + jne l_1 + mov byte [curr_head],0 + + mov bl,[curr_track] + add bl,1 + mov [curr_track],bl + +l_1: ret + +step_memory: + mov bx,[curr_offset] + add bx,SECTORSZ + mov [curr_offset],bx + test bx,0xffff + jne l_2 + mov bx,[curr_segment] + add bx,0x1000 ; 64 KByte weiterstellen + mov [curr_segment],bx + +l_2 ret + +; +; Ausgabe eines Stern ('*') mit Hilfe eines BIOS-Aufrufs +; +print_dot: + mov ah,0x03 ; Feststellen der Cursor-Position + xor bh,bh + int 0x10 + + mov cx,1 + mov bx,0x0007 ; page 0, attribute 7 (normal) + mov ax,ds + mov es,ax + mov bp,dot + mov ax,0x1301 ; Ausgabe des Textes, Cursor bewegen + int 0x10 + + ret + +; +; stop_floppy_motor +; +; Stopt den Motor der Floppy, da das BIOS dazu in Kuerze nicht mehr in +; der Lage sein wird. Egal, ob von Floppy oder Platte gebootet wurde. +; +stop_floppy_motor: + mov dx,0x3f2 + xor al,al + out dx,al + ret + +; +; Datenbereich +; + +bootmessage: + db 13,10 + db 'booting ... ' + +dot: + db '*' + +to_load: + dw 0 +curr_segment: + dw 0 +curr_offset: + dw 0 + +last_head: + db 0 +last_track: + db 0 +last_sector: + db 0 +last_segment: + dw 0 +last_offset: + dw 0 + +unused: + times bootsector+510-$ db 0 + +mark: + dw 0xaa55 diff --git a/src/bootdisk/build.c b/src/bootdisk/build.c new file mode 100755 index 0000000..55c9feb --- /dev/null +++ b/src/bootdisk/build.c @@ -0,0 +1,149 @@ +#include /* fprintf */ +#include +#include /* contains exit */ +#include /* contains read/write */ +#include +#include + +#if !defined(DOS) && !defined(Win32) +#define O_BINARY 0 +#endif + +#define SECTOR 512 + +void die(const char *str) { + fprintf(stderr, "%s\n", str); + exit(1); +} + +int main(int argc, char **argv) { + int fd, fd_out; + char bootsector[SECTOR]; + char setupsector[SECTOR]; + struct stat info; + unsigned short setup_size; + int bytes_read, to_read; + unsigned int dc, st, sh, ss, tt, th, ts; + unsigned char bios_device_code, start_track, start_head, start_sector; + unsigned short total_tracks, total_heads, total_sectors; + unsigned short system_sectors; + + if (argc != 6) + die("usage: build bootsector setup-code system-image dev.info bootdisk-image\n\n" + "dev.info: BIOS-dev.code:total-tracks:-heads:-sectors:start-track:-head:-sector\n" + "BIOS-devicecode: 0=fd0, 1=fd1, ..., 128=hd0, 129=hd1, ...\n" + "Example: to boot from a 3.5\" floppy disk use \"0:80:2:18:0:0:1\"\n"); + + sscanf(argv[4], "%u:%u:%u:%u:%u:%u:%u", &dc, &tt, &th, &ts, &st, &sh, &ss); + bios_device_code = (unsigned char) dc; + total_tracks = (unsigned short) tt; + total_sectors = (unsigned short) ts; + total_heads = (unsigned short) th; + start_track = (unsigned char) st; + start_head = (unsigned char) sh; + start_sector = (unsigned char) ss; + + printf("BIOS-devicecode: 0x%x\n", bios_device_code); + printf("Total T/H/S: (%d/%d/%d)\n", total_tracks, total_heads, + total_sectors); + printf("Start T/H/S: (%d/%d/%d)\n\n", start_track, start_head, + start_sector); + + if ((fd_out = open(argv[5], O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644)) < 0) + die("Unable to open output file."); + + if ((fd = open(argv[1], O_RDONLY | O_BINARY, 0)) < 0) + die("Unable to open input file."); + + if (read(fd, bootsector, SECTOR) < 0) + die("Unable to read bootsector."); + + close(fd); + + if (stat(argv[2], &info) != 0) + die("Can't stat setup file."); + + setup_size = (unsigned short) + ((info.st_size + SECTOR - 1) / SECTOR); + printf("Setup size is %d sectors.\n", (int) setup_size); + + if (stat(argv[3], &info) != 0) + die("Can't stat system file."); + to_read = info.st_size; + printf("System size is %d bytes.\n", to_read); + + system_sectors = (to_read + SECTOR - 1) / SECTOR; + printf("# System sectors is %d.\n", system_sectors); + +#if 0 + *(unsigned short*)(bootsector+4) = total_tracks; + *(unsigned short*)(bootsector+6) = total_heads; + *(unsigned short*)(bootsector+8) = total_sectors; + + *(unsigned short*)(bootsector+10) = setup_size; + *(unsigned short*)(bootsector+12) = + (unsigned short)((to_read + SECTOR - 1) / SECTOR); + *(unsigned char*)(bootsector+14) = bios_device_code; + *(unsigned char*)(bootsector+15) = start_track; + *(unsigned char*)(bootsector+16) = start_head; + *(unsigned char*)(bootsector+17) = start_sector; +#else + *(unsigned char *) (bootsector + 4) = (total_tracks) & 0xff; + *(unsigned char *) (bootsector + 5) = (total_tracks >> 8) & 0xff; + *(unsigned char *) (bootsector + 6) = (total_heads) & 0xff; + *(unsigned char *) (bootsector + 7) = (total_heads >> 8) & 0xff; + *(unsigned char *) (bootsector + 8) = (total_sectors) & 0xff; + *(unsigned char *) (bootsector + 9) = (total_sectors >> 8) & 0xff; + + *(unsigned char *) (bootsector + 10) = (setup_size) & 0xff; + *(unsigned char *) (bootsector + 11) = (setup_size >> 8) & 0xff; + *(unsigned char *) (bootsector + 12) = system_sectors & 0xff; + *(unsigned char *) (bootsector + 13) = (system_sectors >> 8) & 0xff; + *(unsigned char *) (bootsector + 14) = bios_device_code; + *(unsigned char *) (bootsector + 15) = start_track; + *(unsigned char *) (bootsector + 16) = start_head; + *(unsigned char *) (bootsector + 17) = start_sector; +#endif + + write(fd_out, bootsector, SECTOR); + + if ((fd = open(argv[2], O_RDONLY | O_BINARY, 0)) < 0) + die("Unable to open setup file."); + + do { + if ((bytes_read = read(fd, setupsector, SECTOR)) < 0) + die("Unable to read setup."); + + if (bytes_read > 0) + write(fd_out, setupsector, SECTOR); + + } while (bytes_read > 0); + + + close(fd); + + if ((fd = open(argv[3], O_RDONLY | O_BINARY, 0)) < 0) + die("Unable to open system file."); + + while (to_read > 0) { + int l; + + l = (to_read < SECTOR) ? to_read : SECTOR; + + if ((bytes_read = read(fd, setupsector, l)) != l) + die("Unable to read system."); + + write(fd_out, setupsector, l); + + to_read -= l; + } + + close(fd); + close(fd_out); + + return 0; +} + + + + diff --git a/src/bootdisk/setup.asm b/src/bootdisk/setup.asm new file mode 100644 index 0000000..504912c --- /dev/null +++ b/src/bootdisk/setup.asm @@ -0,0 +1,200 @@ +; $Id: setup.asm 1484 2009-02-11 21:03:19Z hsc $ + +;****************************************************************************** +;* Betriebssysteme * +;*----------------------------------------------------------------------------* +;* * +;* S E T U P * +;* * +;*----------------------------------------------------------------------------* +;* Der Setup-Code liegt im System-Image direkt hinter dem Bootsektor und wird * +;* von diesem direkt nach dem Laden aktiviert. Der Code wird noch im * +;* 'Real-Mode' gestartet, so dass zu Beginn auch noch BIOS-Aufrufe erlaubt * +;* sind. Dann werden jedoch alle Interrupts verboten, die Adressleitung A20 * +;* aktiviert und die Umschaltung in den 'Protected-Mode' vorgenommen. Alles * +;* weitere uebernimmt der Startup-Code des Systems. * +;****************************************************************************** + +; +; Konstanten +; + SETUPSEG equ 0x9000 ; Setup-Code (max. 64K inkl. Stack) + SYSTEMSEG equ 0x1000 ; System-Code (max. 512K) + SECTORSZ equ 512 ; Groesse eines Sektors in Bytes + SYSTEMSTART equ 0x100000 ; Hierhin wird das System nach Umschalten in den + ; Protected Mode kopiert, da GRUB das auch tut + ; (und GRUB kann nur an Adressen >1M laden). + +[SECTION .text] +[BITS 16] +; +; Segmentregister initialisieren +; +start: + mov dx, ax ; Anzahl Systemsektoren in DX sichern. + + mov ax,cs ; Daten-, Code- und Stacksegment sollen + mov ds,ax ; hierher zeigen. + mov ss,ax ; Alle drei Segment duerfen nicht mehr + mov sp,0xfffe ; als 64 KByte einnehmen (zusammen). + + mov [system_sectors], dx ; Anzahl der Systemsektoren im Speicher ablegen + +; +; Ausgabe einer Meldung mit Hilfe eines BIOS-Aufrufs +; + mov ah,0x03 ; Feststellen der Cursor-Position + xor bh,bh + int 0x10 + + mov cx,14 + mov bx,0x0007 ; page 0, attribute 7 (normal) + mov ax,ds + mov es,ax + mov bp,setupmessage + mov ax,0x1301 ; Ausgabe des Textes, Cursor bewegen + int 0x10 +; +; So, jetzt werden die Interrupts abgeschaltet +; + cli ; Maskierbare Interrupts verbieten + mov al,0x80 ; NMI verbieten + out 0x70,al +; +; IDT und GDT setzen +; + lidt [idt_48] + lgdt [gdt_48] +; +; Aktivieren der Adressleitung A20 +; + call empty_8042 + mov al,0xd1 + out 0x64,al + call empty_8042 + mov al,0xdf + out 0x60,al + call empty_8042 + mov al,0xff + out 0x64,al + call empty_8042 +; +; Moeglichen Koprozessor zuruecksetzen +; + xor ax,ax + out 0xf0,al + call delay + out 0xf1,al + call delay +; +; Umschalten in den Protected Mode +; + mov eax,cr0 ; Setze PM-Bit im Kontrollregister 1 + or eax,1 + mov cr0,eax + + jmp dword 0x08:SETUPSEG*0x10+copy_system ; Far-Jump, um + ; a) fetch Pipeline zu leeren + ; b) CS Register sinnvoll zu belegen +[BITS 32] +; Arbeite jetzt im Protected Mode +copy_system: +; +; Systemcode von 0x10000 nach 0x100000 kopieren. +; + + mov ax, 0x10 ; 0x10 entspricht dem Data-Eintrag in der GDT. + mov ds, ax ; DS und ES werden von movsd benoetigt. + mov es, ax + + xor ecx, ecx ; Anzahl Systemsektoren laden + mov cx, [SETUPSEG*0x10+system_sectors] + + imul ecx, SECTORSZ/4 + + mov esi, SYSTEMSEG*0x10 ; Hier liegt der Systemcode noch ... + mov edi, SYSTEMSTART ; ... und hierhin moechten wir ihn verschieben + + cld ; Nach jedem movsb ESI,EDI inkrementieren + rep movsd ; Kopiere 4 Byte von [ESI] nach [EDI] ecx male + + +; +; Sprung in den Startup-Code des Systems +; + + jmp dword 0x08:SYSTEMSTART + +error: + hlt +[BITS 16] +; Ab hier wieder Real-Mode Code fuer die Codeteile +; vor der Umschaltung in den Protected Mode + +; +; empty_8042 +; +; Ein- und Ausgabepuffer des Tastaturcontrollers leeren +; +empty_8042: + call delay + in al,0x64 ; 8042 Status Port + test al,1 ; Ausgabepuffer voll? + jz no_output + call delay + in al,0x60 ; wenn ja: ueberlesen + jmp empty_8042 +no_output: + test al,2 ; Eingabepuffer voll? + jnz empty_8042 ; wenn ja, noch mal testen, irgendwann + ret ; muss es weg sein. +; +; delay: +; +; Kurze Verzoegerung fuer in/out-Befehle +; +delay: + out 0x80,al + ret + +; +; Datenbereich +; +[SECTION .data] + +; Meldung + +system_sectors: + dw 0 + +setupmessage: + db 13,10 + db 'setup active' +; +; Descriptor-Tabellen +; +gdt: + dw 0,0,0,0 ; NULL Deskriptor + + dw 0xFFFF ; 4Gb - (0x100000*0x1000 = 4Gb) + dw 0x0000 ; base address=0 + dw 0x9A00 ; code read/exec + dw 0x00CF ; granularity=4096, 386 (+5th nibble of limit) + + dw 0xFFFF ; 4Gb - (0x100000*0x1000 = 4Gb) + dw 0x0000 ; base address=0 + dw 0x9200 ; data read/write + dw 0x00CF ; granularity=4096, 386 (+5th nibble of limit) + + dw 0xFFFF ; 4Gb - (0x100000*0x1000 = 4Gb) + dw 0x4000 ; 0x4000 -> base address=0x24000 (siehe BIOS.cc) + dw 09A02h ; 0x2 -> base address =0x24000 (siehe BIOS.cc) und code read/exec; + dw 0008Fh ; granularity=4096, 16-bit code + +idt_48: + dw 0 ; idt limit=0 + dw 0,0 ; idt base=0L + +gdt_48: + dw 0x20 ; GDT Limit=24, 3 GDT Eintraege + dd SETUPSEG*0x10+gdt; Physikalische Adresse der GDT diff --git a/src/device/bios/BIOS.cc b/src/device/bios/BIOS.cc new file mode 100644 index 0000000..c2a28db --- /dev/null +++ b/src/device/bios/BIOS.cc @@ -0,0 +1,324 @@ +/***************************************************************************** + * * + * B I O S * + * * + *---------------------------------------------------------------------------* + * Beschreibung: BIOS-Schnittstelle * + * * + * Autor: Michael Schoettner, 29.11.2018 * + *****************************************************************************/ + +#include "BIOS.h" +#include "kernel/system/Globals.h" + +// 16-Bit Code aufrufen, siehe Konstruktor und Aufruf in startup.asm +extern "C" { + void bios_call(); +} + +// in startup.asm im GDT-Eintrag so festgeschrieben! +constexpr const unsigned int BIOS16_CODE_MEMORY_START = 0x24000; + +// Parameter fuer BIOS-Aufrufe (Register) +constexpr const unsigned int BIOS16_PARAM_BASE = 0x26000; + +// Zeiger auf Speichbereich fuer Parameter fuer BIOS-Aufruf (siehe BIOS.h) +BIOScall_params* BC_params = reinterpret_cast(BIOS16_PARAM_BASE); + +/***************************************************************************** + * Methode: BIOS::BIOS * + *---------------------------------------------------------------------------* + * Beschreibung: Konstruktor. Baut manuell ein 16-Bit Code Segment fuer * + * den BIOS-Aufruf. Startadresse dieser Funktion steht * + * im 4. GDT-Eintrag (siehe startup.asm). * + *****************************************************************************/ +BIOS::BIOS() { + unsigned char* codeAddr = reinterpret_cast(BIOS16_CODE_MEMORY_START); + + // mov eax, 25000 (Adresse wohin aktuelles esp gesichert wird) + *codeAddr = 0x66; + codeAddr++; + *codeAddr = 0xB8; + codeAddr++; + *codeAddr = 0x00; + codeAddr++; + *codeAddr = 0x50; + codeAddr++; + *codeAddr = 0x02; + codeAddr++; + *codeAddr = 0x00; + codeAddr++; + + // mov [eax], esp (esp abspeichern) + *codeAddr = 0x66; + codeAddr++; + *codeAddr = 0x67; + codeAddr++; + *codeAddr = 0x89; + codeAddr++; + *codeAddr = 0x20; + codeAddr++; + + // mov eax,cr0 (cr0 auslesen) + *codeAddr = 0x0F; + codeAddr++; + *codeAddr = 0x20; + codeAddr++; + *codeAddr = 0xC0; + codeAddr++; + + // and eax, 7FFEFFFE (Bitmaske zum Abschlaten des Protected-Mode) + *codeAddr = 0x66; + codeAddr++; + *codeAddr = 0x25; + codeAddr++; + *codeAddr = 0xFE; + codeAddr++; + *codeAddr = 0xFF; + codeAddr++; + *codeAddr = 0xFE; + codeAddr++; + *codeAddr = 0x7F; + codeAddr++; + + // mov cr0, eax (cr0 syetzen um den Protected-Mode auszuschalten) + *codeAddr = 0x0F; + codeAddr++; + *codeAddr = 0x22; + codeAddr++; + *codeAddr = 0xC0; + codeAddr++; + + // jmp 2400:001B Instruktions-Pipeline leeren und Dekodierungseinheit auf 16-Bit code umschalten + // Wir springen hier zur naechsten Instruktion (*) + // 2400:001B (2400<<4 = 24000 + 1B) + *codeAddr = 0xEA; + codeAddr++; + *codeAddr = 0x1B; + codeAddr++; + *codeAddr = 0x00; + codeAddr++; + *codeAddr = 0x00; + codeAddr++; + *codeAddr = 0x24; + codeAddr++; + + // (*) mov dx,2400 (Lade 0x2400 nach dx (fuer Parameter-Zugriff -> BIOS16_PARAM_BAS) + *codeAddr = 0xBA; + codeAddr++; + *codeAddr = 0x00; + codeAddr++; + *codeAddr = 0x24; + codeAddr++; + + // mov ss,dx (Lade Stack-Segment-Register) + *codeAddr = 0x8E; + codeAddr++; + *codeAddr = 0xD2; + codeAddr++; + + // mov gs,dx + *codeAddr = 0x8E; + codeAddr++; + *codeAddr = 0xEA; + codeAddr++; + + // mov esp,2000 -> BIOS16_PARAM_BASE 0x260000 (= 0x2400:2000) + *codeAddr = 0x66; + codeAddr++; + *codeAddr = 0xBC; + codeAddr++; + *codeAddr = 0x00; + codeAddr++; + *codeAddr = 0x20; + codeAddr++; + *codeAddr = 0x00; + codeAddr++; + *codeAddr = 0x00; + codeAddr++; + + // Register laden (stehen in BIOS16_PARAM_BASE, ab 0x260000) + // (pop erhöht die Adressen) + + // pop ds + *codeAddr = 0x1F; + codeAddr++; + + // pop es + *codeAddr = 0x07; + codeAddr++; + + // pop fs + *codeAddr = 0x0f; + codeAddr++; + *codeAddr = 0xa1; + codeAddr++; + + // pop ax + *codeAddr = 0x58; + codeAddr++; + + // popad + *codeAddr = 0x66; + codeAddr++; + *codeAddr = 0x61; + codeAddr++; + + // int(nr) + *codeAddr = 0xCD; + codeAddr++; // 'int' Instruktion + *codeAddr = 0x00; + codeAddr++; // Nummer (wird direkt von BIOS::Int direkt hier reingeschrieben) + + // Register speichern in BIOS16_PARAM_BASE (ab 0x260000) + + // pushad + *codeAddr = 0x66; + codeAddr++; + *codeAddr = 0x60; + codeAddr++; + + // pushf + *codeAddr = 0x9C; + codeAddr++; + + // push fs + *codeAddr = 0x0f; + codeAddr++; + *codeAddr = 0xa0; + codeAddr++; + + // push es + *codeAddr = 0x06; + codeAddr++; + + // push ds + *codeAddr = 0x1E; + codeAddr++; + + // mov eax,cr0 + *codeAddr = 0x0F; + codeAddr++; + *codeAddr = 0x20; + codeAddr++; + *codeAddr = 0xC0; + codeAddr++; + + // or eax, 00010001 (protected mode without paging) + *codeAddr = 0x66; + codeAddr++; + *codeAddr = 0x0D; + codeAddr++; + *codeAddr = 0x01; + codeAddr++; + *codeAddr = 0x00; + codeAddr++; + *codeAddr = 0x01; + codeAddr++; + *codeAddr = 0x00; + codeAddr++; + + // mov cr0, eax + *codeAddr = 0x0F; + codeAddr++; + *codeAddr = 0x22; + codeAddr++; + *codeAddr = 0xC0; + codeAddr++; + + // jmp 0018:0049, flush pipeline & switch decoding (active 32 Bit PM) + // 0018:0049 + *codeAddr = 0xEA; + codeAddr++; + *codeAddr = 0x49; + codeAddr++; + *codeAddr = 0x00; + codeAddr++; + *codeAddr = 0x18; + codeAddr++; + *codeAddr = 0x00; + codeAddr++; + + // mov dx,0010 + *codeAddr = 0xBA; + codeAddr++; + *codeAddr = 0x10; + codeAddr++; + *codeAddr = 0x00; + codeAddr++; + + // mov ds,dx + *codeAddr = 0x8E; + codeAddr++; + *codeAddr = 0xDA; + codeAddr++; + + // mov es,dx + *codeAddr = 0x8E; + codeAddr++; + *codeAddr = 0xC2; + codeAddr++; + + // mov es,dx + *codeAddr = 0x8E; + codeAddr++; + *codeAddr = 0xE2; + codeAddr++; + + // mov fs,dx + *codeAddr = 0x8E; + codeAddr++; + *codeAddr = 0xEA; + codeAddr++; + + // mov ss,dx + *codeAddr = 0x8E; + codeAddr++; + *codeAddr = 0xD2; + codeAddr++; + + // mov eax, 25000 + *codeAddr = 0x66; + codeAddr++; + *codeAddr = 0xB8; + codeAddr++; + *codeAddr = 0x00; + codeAddr++; + *codeAddr = 0x50; + codeAddr++; + *codeAddr = 0x02; + codeAddr++; + *codeAddr = 0x00; + codeAddr++; + + // mov esp, [eax] + *codeAddr = 0x66; + codeAddr++; + *codeAddr = 0x67; + codeAddr++; + *codeAddr = 0x8B; + codeAddr++; + *codeAddr = 0x20; + codeAddr++; + + // far ret + *codeAddr = 0x66; + codeAddr++; + *codeAddr = 0xCB; +} + +/***************************************************************************** + * Methode: BIOS::Int * + *---------------------------------------------------------------------------* + * Beschreibung: Fuehrt einen BIOS-Aufruf per Software-Interrupt durch. * + *****************************************************************************/ +void BIOS::Int(int inter) { + unsigned char* ptr = reinterpret_cast(BIOS16_CODE_MEMORY_START); + + // Interrupt-Nummer in 16-Bit Code-Segment schreiben (unschoen, aber ...) + *(ptr + 48) = static_cast(inter); + + CPU::disable_int(); // Interrupts abschalten + bios_call(); + CPU::enable_int(); +} diff --git a/src/device/bios/BIOS.h b/src/device/bios/BIOS.h new file mode 100644 index 0000000..608df36 --- /dev/null +++ b/src/device/bios/BIOS.h @@ -0,0 +1,53 @@ +/***************************************************************************** + * * + * B I O S * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Zugriff auf das 16-Bit BIOS. Fuer VESA-Funktionen. * + * * + * Autor: Michael Schoettner, 13.9.2016 * + *****************************************************************************/ +#ifndef BIOS_include__ +#define BIOS_include__ + +// Speicherseite fuer Rueckgabewerte von BIOS-Aufrufen +constexpr const unsigned int RETURN_MEM = 0x9F000; + +// Struktur fuer Parameteruebergabe fuer einen BIOS-Aufruf +struct BIOScall_params { + unsigned short DS; + unsigned short ES; + unsigned short FS; + unsigned short Flags; + unsigned int DI; + unsigned int SI; + unsigned int BP; + unsigned int SP; + unsigned int BX; + unsigned int DX; + unsigned int CX; + unsigned int AX; +} __attribute__((packed)); +// kein Auffuellen von bytes auf Wortgrenzen + +// Zeiger auf Speichbereich fuer Parameter fuer BIOS-Aufruf +extern BIOScall_params* BC_params; + +class BIOS { +private: + // Initialisierung: manuelles Anlegen einer Funktion + BIOS(); + +public: + BIOS(const BIOS& copy) = delete; // Verhindere Kopieren + + static BIOS& instance() { + static BIOS bios; + return bios; + } + + // BIOS-Aufruf, per Software-Interrupt + static void Int(int inter); +}; + +#endif diff --git a/src/device/cpu/CPU.h b/src/device/cpu/CPU.h new file mode 100755 index 0000000..fa6ed57 --- /dev/null +++ b/src/device/cpu/CPU.h @@ -0,0 +1,52 @@ +/***************************************************************************** + * * + * C P U * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Implementierung einer Abstraktion fuer den Prozessor. * + * Derzeit wird nur angeboten, Interrupts zuzulassen, zu * + * verbieten oder den Prozessor anzuhalten. * + * * + * Autor: Michael Schoettner, 30.7.16 * + *****************************************************************************/ +#ifndef CPU_include__ +#define CPU_include__ + +class CPU { +public: + CPU(const CPU& copy) = delete; // Verhindere Kopieren + + CPU() = default; + + // Erlauben von (Hardware-)Interrupts + static inline void enable_int() { + asm volatile("sti"); + } + + // Interrupts werden ignoriert/verboten + static inline void disable_int() { + asm volatile("cli"); + } + + // Prozessor bis zum naechsten Interrupt anhalten + static inline void idle() { + asm volatile("sti;" + "hlt"); + } + + // Prozessor anhalten + static inline void halt() { + asm volatile("cli;" + "hlt"); + } + + // Time-Stamp-Counter auslesen + static inline unsigned long long int rdtsc() { + unsigned long long int ret; + asm volatile("rdtsc" + : "=A"(ret)); + return ret; + } +}; + +#endif diff --git a/src/device/graphics/CGA.cc b/src/device/graphics/CGA.cc new file mode 100755 index 0000000..94ae45a --- /dev/null +++ b/src/device/graphics/CGA.cc @@ -0,0 +1,201 @@ +/***************************************************************************** + * * + * C G A * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Mit Hilfe dieser Klasse kann man auf den Bildschirm des * + * PCs zugreifen. Der Zugriff erfolgt direkt auf der Hard- * + * wareebene, d.h. ueber den Bildschirmspeicher und den * + * I/O-Ports der Grafikkarte. * + * * + * Autor: Olaf Spinczyk, TU Dortmund * + * Aenderungen von Michael Schoettner, HHU, 21.8.2016 * + *****************************************************************************/ +#include "CGA.h" +#include "lib/mem/Memory.h" + +const IOport CGA::index_port(0x3d4); +const IOport CGA::data_port(0x3d5); + +const bse::span CGA::SCREEN{reinterpret_cast(0xb8000U)}; +const bse::span CGA::SCREEN_ROWS{reinterpret_cast(0xb8000U)}; +CGA::cga_page_t* const CGA::SCREEN_PAGE {reinterpret_cast(0xb8000U)}; + +/***************************************************************************** + * Methode: CGA::setpos * + *---------------------------------------------------------------------------* + * Beschreibung: Setzen des Cursors in Spalte x und Zeile y. * + *****************************************************************************/ +void CGA::setpos(unsigned int x, unsigned int y) { + + /* Hier muess Code eingefuegt werden */ + + // NOTE: The cursor addresses positions on screen, not bytes + unsigned short pos = x + y * COLUMNS; + unsigned char cursor_low = pos & 0xFF; + unsigned char cursor_high = (pos >> 8) & 0xFF; + + index_port.outb(0xF); // Cursor(low) + data_port.outb(cursor_low); + + index_port.outb(0xE); // Cursor(high) + data_port.outb(cursor_high); +} + +/***************************************************************************** + * Methode: CGA::getpos * + *---------------------------------------------------------------------------* + * Beschreibung: Abfragem der Cursorposition * + * * + * Rückgabewerte: x und y * + *****************************************************************************/ +void CGA::getpos(unsigned int& x, unsigned int& y) { + + /* Hier muess Code eingefuegt werden */ + + index_port.outb(0xF); // Cursor(low) + unsigned char cursor_low = data_port.inb(); + + index_port.outb(0xE); // Cursor(high) + unsigned char cursor_high = data_port.inb(); + + unsigned short cursor = + (cursor_low & 0xFF) | ((cursor_high << 8) & 0xFF00); + + x = cursor % COLUMNS; + y = (cursor / COLUMNS); +} + +/***************************************************************************** + * Methode: CGA::show * + *---------------------------------------------------------------------------* + * Beschreibung: Anzeige eines Zeichens mit Attribut an einer bestimmten * + * Stelle auf dem Bildschirm. * + * * + * Parameter: * + * x,y Position des Zeichens * + * character Das auszugebende Zeichen * + * attrib Attributbyte fuer das Zeichen * + *****************************************************************************/ +void CGA::show(unsigned int x, unsigned int y, char character, unsigned char attrib) { + + /* Hier muess Code eingefuegt werden */ + + if (x >= COLUMNS || y >= ROWS) { + // Out of bounds + return; + } + + cga_char_t* pos = SCREEN[x + y * COLUMNS]; + pos->cga_char = character; + pos->cga_attribute = attrib; +} + +/***************************************************************************** + * Methode: CGA::print * + *---------------------------------------------------------------------------* + * Beschreibung: Anzeige mehrerer Zeichen ab der aktuellen Cursorposition * + * '\n' fuer Zeilenvorschub. * + * * + * Parameter: * + * substring Auszugebende Zeichenkette * + * n Laenger der Zeichenkette * + * attrib Attributbyte fuer alle Zeichen der Zeichenkette * + *****************************************************************************/ +void CGA::print(const bse::string_view string, unsigned char attrib) const { + + /* Hier muess Code eingefuegt werden */ + + unsigned int cursor_x = 0; + unsigned int cursor_y = 0; // Don't poll registers every stroke + getpos(cursor_x, cursor_y); + + for (char current : string) { + if (current == '\n') { + cursor_x = 0; + cursor_y = cursor_y + 1; + + if (cursor_y >= ROWS) { + // Bottom of screen reached + scrollup(); + cursor_y = cursor_y - 1; + } + + continue; + } + + if (current == '\0') { + // Don't need to run to end if null terminated + break; + } + + show(cursor_x, cursor_y, current, attrib); + cursor_x = cursor_x + 1; + + if (cursor_x >= COLUMNS) { + // Right of screen reached + cursor_x = 0; + cursor_y = cursor_y + 1; + + if (cursor_y >= ROWS) { + // Bottom of screen reached + scrollup(); + cursor_y = cursor_y - 1; + } + } + } + + setpos(cursor_x, cursor_y); +} + +/***************************************************************************** + * Methode: CGA::scrollup * + *---------------------------------------------------------------------------* + * Beschreibung: Verschiebt den Bildschirminhalt um eine Zeile nach oben. * + * Die neue Zeile am unteren Bildrand wird mit Leerzeichen * + * gefuellt. * + *****************************************************************************/ +void CGA::scrollup() const { + + /* Hier muss Code eingefuegt werden */ + + // Move up + bse::memcpy(SCREEN_ROWS[0], SCREEN_ROWS[1], ROWS - 1); + + // Clear last line + bse::zero(SCREEN_ROWS[ROWS - 1]); +} + +/***************************************************************************** + * Methode: CGA::clear * + *---------------------------------------------------------------------------* + * Beschreibung: Lösche den Textbildschirm. * + *****************************************************************************/ +void CGA::clear() { + + /* Hier muess Code eingefuegt werden */ + + bse::zero(SCREEN_PAGE); + setpos(0, 0); +} + +/***************************************************************************** + * Methode: CGA::attribute * + *---------------------------------------------------------------------------* + * Beschreibung: Hilfsfunktion zur Erzeugung eines Attribut-Bytes aus * + * Hintergrund- und Vordergrundfarbe und der Angabe, ob das * + * Zeichen blinkend darzustellen ist. * + * * + * Parameter: * + * bg Background color * + * fg Foreground color * + * blink ywa/no * + *****************************************************************************/ +unsigned char CGA::attribute(CGA::color bg, CGA::color fg, bool blink) { + + /* Hier muess Code eingefuegt werden */ + + return static_cast(blink) << 7 // B0000000 + | (bg & 0x7) << 4 // 0HHH0000 (Hintergrund) + | (fg & 0xF); // 0000VVVV (Vordergrund) +} diff --git a/src/device/graphics/CGA.h b/src/device/graphics/CGA.h new file mode 100755 index 0000000..ce87677 --- /dev/null +++ b/src/device/graphics/CGA.h @@ -0,0 +1,108 @@ +/***************************************************************************** + * * + * C G A * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Mit Hilfe dieser Klasse kann man auf den Bildschirm des * + * PCs zugreifen. Der Zugriff erfolgt direkt auf der Hard- * + * wareebene, d.h. ueber den Bildschirmspeicher und den * + * I/O-Ports der Grafikkarte. * + * * + * Autor: Olaf Spinczyk, TU Dortmund * + * Aenderungen von Michael Schoettner, HHU, 21.8.2016 * + *****************************************************************************/ +#ifndef CGA_include_H_ +#define CGA_include_H_ + +#include "device/port/IOport.h" +#include "lib/util/Array.h" +#include "lib/util/Span.h" +#include "lib/util/String.h" +#include "lib/util/StringView.h" + +class CGA { +private: + static const IOport index_port; // Auswahl eines Register der Grafikkarte + static const IOport data_port; // Lese-/Schreib-Zugriff auf Register der Grafikk. + +public: + // Copy Konstrutkor unterbinden + CGA(const CGA& copy) = delete; + + // Konstruktur mit Initialisierung der Ports + CGA() { + CGA::setpos(0, 0); + } + +// virtual ~CGA() = default; + + // Konstanten fuer die moeglichen Farben im Attribut-Byte. + typedef enum { + BLACK, + BLUE, + GREEN, + CYAN, + RED, + MAGENTA, + BROWN, + LIGHT_GREY, + DARK_GREY, + LIGHT_BLUE, + LIGHT_GREEN, + LIGHT_CYAN, + LIGHT_RED, + LIGHT_MAGENTA, + YELLOW, + WHITE + } color; + + // Standardzeichenfarbe + enum { STD_ATTR = BLACK << 4 | LIGHT_GREY }; + + // Groesse des Bildschirms (25 Zeilen, 80 Spalten) + enum { ROWS = 25, + COLUMNS = 80 }; + + // Easier access to memory (also easier copying of lines/pages etc) + struct cga_char_t { + char cga_char; + unsigned char cga_attribute; + }; + + struct cga_line_t { + // Can use these arrays since they don't have memory overhead (except for the methods that are elsewhere) + bse::array cga_line; + }; + + struct cga_page_t { + bse::array cga_page; + }; + + static const bse::span SCREEN; + static const bse::span SCREEN_ROWS; + static cga_page_t* const SCREEN_PAGE; // No span because can't address anything in [0, 1] + + // Setzen des Cursors in Spalte x und Zeile y. + static void setpos(unsigned int x, unsigned int y); + + // Abfragen der Cursorpostion + static void getpos(unsigned int& x, unsigned int& y) ; + + // Anzeige eines Zeichens mit Attribut an einer bestimmten Stelle + static void show(unsigned int x, unsigned int y, char character, unsigned char attrib = STD_ATTR); + + // Anzeige mehrerer Zeichen ab der aktuellen Cursorposition + void print(const bse::string_view substring, unsigned char attrib = STD_ATTR) const; + + // Verschiebt den Bildschirminhalt um eine Zeile nach oben. + // Neue Zeile am unteren Bildrand mit Leerzeichen fuellen + virtual void scrollup() const; + + // Lösche den Textbildschirm + virtual void clear(); + + // Hilfsfunktion zur Erzeugung eines Attribut-Bytes + static unsigned char attribute(CGA::color bg, CGA::color fg, bool blink); +}; + +#endif diff --git a/src/device/graphics/CGA_Stream.cc b/src/device/graphics/CGA_Stream.cc new file mode 100755 index 0000000..697b4d5 --- /dev/null +++ b/src/device/graphics/CGA_Stream.cc @@ -0,0 +1,41 @@ +/***************************************************************************** + * * + * C G A _ S T R E A M * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Die Klasse CGA_Stream ermoeglicht die Ausgabe verschied. * + * Datentypen als Zeichenketten auf dem CGA-Bildschirm eines* + * PCs. Fuer weitergehende Formatierung oder spezielle * + * Effekte stehen die Methoden der Klasse CGA_Stream zur * + * Verfuegung. * + * * + * Autor: Olaf Spinczyk, TU Dortmund * + * Aenderungen von Michael Schoettner, HHU, 1.8.16 * + *****************************************************************************/ + +#include "CGA_Stream.h" + +/***************************************************************************** + * Methode: CGA_Stream::flush * + *---------------------------------------------------------------------------* + * Beschreibung: Methode zur Ausgabe des Pufferinhalts der Basisklasse * + * StringBuffer. Die Methode wird implizit aufgerufen, * + * sobald der Puffer voll ist, kann aber auch explizit * + * verwendet werden, um eine Ausgabe zu erzwingen. * + *****************************************************************************/ +void CGA_Stream::flush() { + buffer[pos] = '\0'; // I removed the n argument from print so nullterminate the string + print(buffer.data(), attribute(color_bg, color_fg, blink)); // print(buffer...) would work syntactically + // but the system wouldn't start, as the bse::array + // would be implicitly converted to bse::string and + // that is dynamically allocated. + // print(buffer.data()...) just uses the stack location of + // the internal buffer of bse::array + + // Flushing resets attributes + blink = false; + color_bg = CGA::BLACK; + color_fg = CGA::LIGHT_GREY; + + pos = 0; +} diff --git a/src/device/graphics/CGA_Stream.h b/src/device/graphics/CGA_Stream.h new file mode 100755 index 0000000..3135d6d --- /dev/null +++ b/src/device/graphics/CGA_Stream.h @@ -0,0 +1,91 @@ +/***************************************************************************** + * * + * C G A _ S T R E A M * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Die Klasse CGA_Stream ermoeglicht die Ausgabe verschied. * + * Datentypen als Zeichenketten auf dem CGA-Bildschirm eines* + * PCs. Fuer weitergehende Formatierung oder spezielle * + * Effekte stehen die Methoden der Klasse CGA zur * + * Verfuegung. * + * * + * Autor: Olaf Spinczyk, TU Dortmund * + * Aenderungen von Michael Schoettner, HHU, 06.04.20 * + *****************************************************************************/ +#ifndef CGA_Stream_include_H_ +#define CGA_Stream_include_H_ + +#include "CGA.h" +#include "lib/stream/OutStream.h" +#include "lib/async/Semaphore.h" + +// Allow for easier stream-like color changing +class fgc { +public: + constexpr fgc(const CGA::color fg) : fg(fg) {} + const CGA::color fg; +}; + +class bgc { +public: + constexpr bgc(const CGA::color bg) : bg(bg) {} + const CGA::color bg; +}; + +constexpr const fgc white = fgc(CGA::WHITE); +constexpr const fgc black = fgc(CGA::BLACK); +constexpr const fgc green = fgc(CGA::GREEN); +constexpr const fgc red = fgc(CGA::RED); +constexpr const fgc lgrey = fgc(CGA::LIGHT_GREY); + +class CGA_Stream : public OutStream, public CGA { +private: + // Allow for synchronization of output text, needed when running something in parallel to + // the PreemptiveThreadDemo for example + // NOTE: Should only be used by threads (like the demos) to not lock the system + Semaphore sem; + + CGA::color color_fg; + CGA::color color_bg; + bool blink; + + friend class Logger; // Give access to the color + +public: + CGA_Stream(CGA_Stream& copy) = delete; // Verhindere Kopieren + + CGA_Stream() : sem(1), color_fg(CGA::LIGHT_GREY), color_bg(CGA::BLACK), blink(false) { + pos = 0; + } + + // CAn't make singleton because atexit + +// ~CGA_Stream() override = default; + + void lock() { sem.p(); } + void unlock() { sem.v(); } + + // Methode zur Ausgabe des Pufferinhalts der Basisklasse StringBuffer. + void flush() override; + + // Change stream color + template + friend T& operator<<(T& os, const fgc& fg) { + CGA::color old_bg = os.color_bg; + os.flush(); + os.color_bg = old_bg; + os.color_fg = fg.fg; + return os; + } + + template + friend T& operator<<(T& os, const bgc& bg) { + CGA::color old_fg = os.color_fg; + os.flush(); + os.color_fg = old_fg; + os.color_bg = bg.bg; + return os; + } +}; + +#endif diff --git a/src/device/graphics/Font_8x16.h b/src/device/graphics/Font_8x16.h new file mode 100644 index 0000000..bc2d572 --- /dev/null +++ b/src/device/graphics/Font_8x16.h @@ -0,0 +1,4623 @@ +// vim: set et ts=4 sw=4: + +/**********************************************/ +/* */ +/* Font file generated by cpi2fnt */ +/* */ +/**********************************************/ + +constexpr const unsigned int FONTDATAMAX_8x16 = 4096; + +constexpr const unsigned char fontdata_8x16[FONTDATAMAX_8x16] = { + + /* 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 */ + +}; + +#undef FONTDATAMAX diff --git a/src/device/graphics/Font_8x8.h b/src/device/graphics/Font_8x8.h new file mode 100644 index 0000000..03645c7 --- /dev/null +++ b/src/device/graphics/Font_8x8.h @@ -0,0 +1,2575 @@ +// vim: set et ts=4 sw=4: + +/**********************************************/ +/* */ +/* Font file generated by cpi2fnt */ +/* */ +/**********************************************/ + +constexpr const unsigned int FONTDATAMAX_8x8 = 2048; + +constexpr const unsigned char fontdata_8x8[FONTDATAMAX_8x8] = { + + /* 0 0x00 '^@' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 1 0x01 '^A' */ + 0x7e, /* 01111110 */ + 0x81, /* 10000001 */ + 0xa5, /* 10100101 */ + 0x81, /* 10000001 */ + 0xbd, /* 10111101 */ + 0x99, /* 10011001 */ + 0x81, /* 10000001 */ + 0x7e, /* 01111110 */ + + /* 2 0x02 '^B' */ + 0x7e, /* 01111110 */ + 0xff, /* 11111111 */ + 0xdb, /* 11011011 */ + 0xff, /* 11111111 */ + 0xc3, /* 11000011 */ + 0xe7, /* 11100111 */ + 0xff, /* 11111111 */ + 0x7e, /* 01111110 */ + + /* 3 0x03 '^C' */ + 0x6c, /* 01101100 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0x7c, /* 01111100 */ + 0x38, /* 00111000 */ + 0x10, /* 00010000 */ + 0x00, /* 00000000 */ + + /* 4 0x04 '^D' */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x7c, /* 01111100 */ + 0xfe, /* 11111110 */ + 0x7c, /* 01111100 */ + 0x38, /* 00111000 */ + 0x10, /* 00010000 */ + 0x00, /* 00000000 */ + + /* 5 0x05 '^E' */ + 0x38, /* 00111000 */ + 0x7c, /* 01111100 */ + 0x38, /* 00111000 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0xd6, /* 11010110 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + + /* 6 0x06 '^F' */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x7c, /* 01111100 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0x7c, /* 01111100 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + + /* 7 0x07 '^G' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 8 0x08 '^H' */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xe7, /* 11100111 */ + 0xc3, /* 11000011 */ + 0xc3, /* 11000011 */ + 0xe7, /* 11100111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + + /* 9 0x09 '^I' */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x42, /* 01000010 */ + 0x42, /* 01000010 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 10 0x0a '^J' */ + 0xff, /* 11111111 */ + 0xc3, /* 11000011 */ + 0x99, /* 10011001 */ + 0xbd, /* 10111101 */ + 0xbd, /* 10111101 */ + 0x99, /* 10011001 */ + 0xc3, /* 11000011 */ + 0xff, /* 11111111 */ + + /* 11 0x0b '^K' */ + 0x0f, /* 00001111 */ + 0x07, /* 00000111 */ + 0x0f, /* 00001111 */ + 0x7d, /* 01111101 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x78, /* 01111000 */ + + /* 12 0x0c '^L' */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + + /* 13 0x0d '^M' */ + 0x3f, /* 00111111 */ + 0x33, /* 00110011 */ + 0x3f, /* 00111111 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x70, /* 01110000 */ + 0xf0, /* 11110000 */ + 0xe0, /* 11100000 */ + + /* 14 0x0e '^N' */ + 0x7f, /* 01111111 */ + 0x63, /* 01100011 */ + 0x7f, /* 01111111 */ + 0x63, /* 01100011 */ + 0x63, /* 01100011 */ + 0x67, /* 01100111 */ + 0xe6, /* 11100110 */ + 0xc0, /* 11000000 */ + + /* 15 0x0f '^O' */ + 0x18, /* 00011000 */ + 0xdb, /* 11011011 */ + 0x3c, /* 00111100 */ + 0xe7, /* 11100111 */ + 0xe7, /* 11100111 */ + 0x3c, /* 00111100 */ + 0xdb, /* 11011011 */ + 0x18, /* 00011000 */ + + /* 16 0x10 '^P' */ + 0x80, /* 10000000 */ + 0xe0, /* 11100000 */ + 0xf8, /* 11111000 */ + 0xfe, /* 11111110 */ + 0xf8, /* 11111000 */ + 0xe0, /* 11100000 */ + 0x80, /* 10000000 */ + 0x00, /* 00000000 */ + + /* 17 0x11 '^Q' */ + 0x02, /* 00000010 */ + 0x0e, /* 00001110 */ + 0x3e, /* 00111110 */ + 0xfe, /* 11111110 */ + 0x3e, /* 00111110 */ + 0x0e, /* 00001110 */ + 0x02, /* 00000010 */ + 0x00, /* 00000000 */ + + /* 18 0x12 '^R' */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + + /* 19 0x13 '^S' */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + + /* 20 0x14 '^T' */ + 0x7f, /* 01111111 */ + 0xdb, /* 11011011 */ + 0xdb, /* 11011011 */ + 0x7b, /* 01111011 */ + 0x1b, /* 00011011 */ + 0x1b, /* 00011011 */ + 0x1b, /* 00011011 */ + 0x00, /* 00000000 */ + + /* 21 0x15 '^U' */ + 0x3e, /* 00111110 */ + 0x61, /* 01100001 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x86, /* 10000110 */ + 0x7c, /* 01111100 */ + + /* 22 0x16 '^V' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x7e, /* 01111110 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* 23 0x17 '^W' */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + + /* 24 0x18 '^X' */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 25 0x19 '^Y' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 26 0x1a '^Z' */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0xfe, /* 11111110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 27 0x1b '^[' */ + 0x00, /* 00000000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xfe, /* 11111110 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 28 0x1c '^\' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 29 0x1d '^]' */ + 0x00, /* 00000000 */ + 0x24, /* 00100100 */ + 0x66, /* 01100110 */ + 0xff, /* 11111111 */ + 0x66, /* 01100110 */ + 0x24, /* 00100100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 30 0x1e '^^' */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 31 0x1f '^_' */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0x7e, /* 01111110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 32 0x20 ' ' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 33 0x21 '!' */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 34 0x22 '"' */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x24, /* 00100100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 35 0x23 '#' */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + + /* 36 0x24 '$' */ + 0x18, /* 00011000 */ + 0x3e, /* 00111110 */ + 0x60, /* 01100000 */ + 0x3c, /* 00111100 */ + 0x06, /* 00000110 */ + 0x7c, /* 01111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 37 0x25 '%' */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xcc, /* 11001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x66, /* 01100110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 38 0x26 '&' */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 39 0x27 ''' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 40 0x28 '(' */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x00, /* 00000000 */ + + /* 41 0x29 ')' */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + + /* 42 0x2a '*' */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0xff, /* 11111111 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 43 0x2b '+' */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 44 0x2c ',' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + + /* 45 0x2d '-' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 46 0x2e '.' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 47 0x2f '/' */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xc0, /* 11000000 */ + 0x80, /* 10000000 */ + 0x00, /* 00000000 */ + + /* 48 0x30 '0' */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xd6, /* 11010110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + + /* 49 0x31 '1' */ + 0x18, /* 00011000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* 50 0x32 '2' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0x06, /* 00000110 */ + 0x1c, /* 00011100 */ + 0x30, /* 00110000 */ + 0x66, /* 01100110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + + /* 51 0x33 '3' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0x06, /* 00000110 */ + 0x3c, /* 00111100 */ + 0x06, /* 00000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 52 0x34 '4' */ + 0x1c, /* 00011100 */ + 0x3c, /* 00111100 */ + 0x6c, /* 01101100 */ + 0xcc, /* 11001100 */ + 0xfe, /* 11111110 */ + 0x0c, /* 00001100 */ + 0x1e, /* 00011110 */ + 0x00, /* 00000000 */ + + /* 53 0x35 '5' */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xfc, /* 11111100 */ + 0x06, /* 00000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 54 0x36 '6' */ + 0x38, /* 00111000 */ + 0x60, /* 01100000 */ + 0xc0, /* 11000000 */ + 0xfc, /* 11111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 55 0x37 '7' */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + + /* 56 0x38 '8' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 57 0x39 '9' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7e, /* 01111110 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x78, /* 01111000 */ + 0x00, /* 00000000 */ + + /* 58 0x3a ':' */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 59 0x3b ';' */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + + /* 60 0x3c '<' */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x06, /* 00000110 */ + 0x00, /* 00000000 */ + + /* 61 0x3d '=' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 62 0x3e '>' */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x00, /* 00000000 */ + + /* 63 0x3f '?' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 64 0x40 '@' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xde, /* 11011110 */ + 0xde, /* 11011110 */ + 0xde, /* 11011110 */ + 0xc0, /* 11000000 */ + 0x78, /* 01111000 */ + 0x00, /* 00000000 */ + + /* 65 0x41 'A' */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 66 0x42 'B' */ + 0xfc, /* 11111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0xfc, /* 11111100 */ + 0x00, /* 00000000 */ + + /* 67 0x43 'C' */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 68 0x44 'D' */ + 0xf8, /* 11111000 */ + 0x6c, /* 01101100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x6c, /* 01101100 */ + 0xf8, /* 11111000 */ + 0x00, /* 00000000 */ + + /* 69 0x45 'E' */ + 0xfe, /* 11111110 */ + 0x62, /* 01100010 */ + 0x68, /* 01101000 */ + 0x78, /* 01111000 */ + 0x68, /* 01101000 */ + 0x62, /* 01100010 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + + /* 70 0x46 'F' */ + 0xfe, /* 11111110 */ + 0x62, /* 01100010 */ + 0x68, /* 01101000 */ + 0x78, /* 01111000 */ + 0x68, /* 01101000 */ + 0x60, /* 01100000 */ + 0xf0, /* 11110000 */ + 0x00, /* 00000000 */ + + /* 71 0x47 'G' */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xce, /* 11001110 */ + 0x66, /* 01100110 */ + 0x3a, /* 00111010 */ + 0x00, /* 00000000 */ + + /* 72 0x48 'H' */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 73 0x49 'I' */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 74 0x4a 'J' */ + 0x1e, /* 00011110 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x78, /* 01111000 */ + 0x00, /* 00000000 */ + + /* 75 0x4b 'K' */ + 0xe6, /* 11100110 */ + 0x66, /* 01100110 */ + 0x6c, /* 01101100 */ + 0x78, /* 01111000 */ + 0x6c, /* 01101100 */ + 0x66, /* 01100110 */ + 0xe6, /* 11100110 */ + 0x00, /* 00000000 */ + + /* 76 0x4c 'L' */ + 0xf0, /* 11110000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x62, /* 01100010 */ + 0x66, /* 01100110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + + /* 77 0x4d 'M' */ + 0xc6, /* 11000110 */ + 0xee, /* 11101110 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0xd6, /* 11010110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 78 0x4e 'N' */ + 0xc6, /* 11000110 */ + 0xe6, /* 11100110 */ + 0xf6, /* 11110110 */ + 0xde, /* 11011110 */ + 0xce, /* 11001110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 79 0x4f 'O' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 80 0x50 'P' */ + 0xfc, /* 11111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0xf0, /* 11110000 */ + 0x00, /* 00000000 */ + + /* 81 0x51 'Q' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xce, /* 11001110 */ + 0x7c, /* 01111100 */ + 0x0e, /* 00001110 */ + + /* 82 0x52 'R' */ + 0xfc, /* 11111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0x6c, /* 01101100 */ + 0x66, /* 01100110 */ + 0xe6, /* 11100110 */ + 0x00, /* 00000000 */ + + /* 83 0x53 'S' */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 84 0x54 'T' */ + 0x7e, /* 01111110 */ + 0x7e, /* 01111110 */ + 0x5a, /* 01011010 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 85 0x55 'U' */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 86 0x56 'V' */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + + /* 87 0x57 'W' */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + + /* 88 0x58 'X' */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 89 0x59 'Y' */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 90 0x5a 'Z' */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0x8c, /* 10001100 */ + 0x18, /* 00011000 */ + 0x32, /* 00110010 */ + 0x66, /* 01100110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + + /* 91 0x5b '[' */ + 0x3c, /* 00111100 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 92 0x5c '\' */ + 0xc0, /* 11000000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x06, /* 00000110 */ + 0x02, /* 00000010 */ + 0x00, /* 00000000 */ + + /* 93 0x5d ']' */ + 0x3c, /* 00111100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 94 0x5e '^' */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 95 0x5f '_' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + + /* 96 0x60 '`' */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 97 0x61 'a' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 98 0x62 'b' */ + 0xe0, /* 11100000 */ + 0x60, /* 01100000 */ + 0x7c, /* 01111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + + /* 99 0x63 'c' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 100 0x64 'd' */ + 0x1c, /* 00011100 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 101 0x65 'e' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 102 0x66 'f' */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x60, /* 01100000 */ + 0xf8, /* 11111000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0xf0, /* 11110000 */ + 0x00, /* 00000000 */ + + /* 103 0x67 'g' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x7c, /* 01111100 */ + 0x0c, /* 00001100 */ + 0xf8, /* 11111000 */ + + /* 104 0x68 'h' */ + 0xe0, /* 11100000 */ + 0x60, /* 01100000 */ + 0x6c, /* 01101100 */ + 0x76, /* 01110110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0xe6, /* 11100110 */ + 0x00, /* 00000000 */ + + /* 105 0x69 'i' */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 106 0x6a 'j' */ + 0x06, /* 00000110 */ + 0x00, /* 00000000 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + + /* 107 0x6b 'k' */ + 0xe0, /* 11100000 */ + 0x60, /* 01100000 */ + 0x66, /* 01100110 */ + 0x6c, /* 01101100 */ + 0x78, /* 01111000 */ + 0x6c, /* 01101100 */ + 0xe6, /* 11100110 */ + 0x00, /* 00000000 */ + + /* 108 0x6c 'l' */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 109 0x6d 'm' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xec, /* 11101100 */ + 0xfe, /* 11111110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0x00, /* 00000000 */ + + /* 110 0x6e 'n' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xdc, /* 11011100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + + /* 111 0x6f 'o' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 112 0x70 'p' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xdc, /* 11011100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0x60, /* 01100000 */ + 0xf0, /* 11110000 */ + + /* 113 0x71 'q' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x7c, /* 01111100 */ + 0x0c, /* 00001100 */ + 0x1e, /* 00011110 */ + + /* 114 0x72 'r' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xdc, /* 11011100 */ + 0x76, /* 01110110 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0xf0, /* 11110000 */ + 0x00, /* 00000000 */ + + /* 115 0x73 's' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x06, /* 00000110 */ + 0xfc, /* 11111100 */ + 0x00, /* 00000000 */ + + /* 116 0x74 't' */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0xfc, /* 11111100 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x36, /* 00110110 */ + 0x1c, /* 00011100 */ + 0x00, /* 00000000 */ + + /* 117 0x75 'u' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 118 0x76 'v' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + + /* 119 0x77 'w' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + + /* 120 0x78 'x' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 121 0x79 'y' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7e, /* 01111110 */ + 0x06, /* 00000110 */ + 0xfc, /* 11111100 */ + + /* 122 0x7a 'z' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x4c, /* 01001100 */ + 0x18, /* 00011000 */ + 0x32, /* 00110010 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* 123 0x7b '{' */ + 0x0e, /* 00001110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x70, /* 01110000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x0e, /* 00001110 */ + 0x00, /* 00000000 */ + + /* 124 0x7c '|' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 125 0x7d '}' */ + 0x70, /* 01110000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x0e, /* 00001110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x70, /* 01110000 */ + 0x00, /* 00000000 */ + + /* 126 0x7e '~' */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 127 0x7f '' */ + 0x00, /* 00000000 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + + /* 128 0x80 '�' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x0c, /* 00001100 */ + 0x78, /* 01111000 */ + + /* 129 0x81 '�' */ + 0xcc, /* 11001100 */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 130 0x82 '�' */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 131 0x83 '�' */ + 0x7c, /* 01111100 */ + 0x82, /* 10000010 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 132 0x84 '�' */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 133 0x85 '�' */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 134 0x86 '�' */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 135 0x87 '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x7e, /* 01111110 */ + 0x0c, /* 00001100 */ + 0x38, /* 00111000 */ + + /* 136 0x88 '�' */ + 0x7c, /* 01111100 */ + 0x82, /* 10000010 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 137 0x89 '�' */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 138 0x8a '�' */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 139 0x8b '�' */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 140 0x8c '�' */ + 0x7c, /* 01111100 */ + 0x82, /* 10000010 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 141 0x8d '�' */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 142 0x8e '�' */ + 0xc6, /* 11000110 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 143 0x8f '�' */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 144 0x90 '�' */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xf8, /* 11111000 */ + 0xc0, /* 11000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + + /* 145 0x91 '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0xd8, /* 11011000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* 146 0x92 '�' */ + 0x3e, /* 00111110 */ + 0x6c, /* 01101100 */ + 0xcc, /* 11001100 */ + 0xfe, /* 11111110 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xce, /* 11001110 */ + 0x00, /* 00000000 */ + + /* 147 0x93 '�' */ + 0x7c, /* 01111100 */ + 0x82, /* 10000010 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 148 0x94 '�' */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 149 0x95 '�' */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 150 0x96 '�' */ + 0x78, /* 01111000 */ + 0x84, /* 10000100 */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 151 0x97 '�' */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 152 0x98 '�' */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7e, /* 01111110 */ + 0x06, /* 00000110 */ + 0xfc, /* 11111100 */ + + /* 153 0x99 '�' */ + 0xc6, /* 11000110 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + + /* 154 0x9a '�' */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 155 0x9b '�' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 156 0x9c '�' */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x64, /* 01100100 */ + 0xf0, /* 11110000 */ + 0x60, /* 01100000 */ + 0x66, /* 01100110 */ + 0xfc, /* 11111100 */ + 0x00, /* 00000000 */ + + /* 157 0x9d '�' */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 158 0x9e '�' */ + 0xf8, /* 11111000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xfa, /* 11111010 */ + 0xc6, /* 11000110 */ + 0xcf, /* 11001111 */ + 0xc6, /* 11000110 */ + 0xc7, /* 11000111 */ + + /* 159 0x9f '�' */ + 0x0e, /* 00001110 */ + 0x1b, /* 00011011 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0xd8, /* 11011000 */ + 0x70, /* 01110000 */ + 0x00, /* 00000000 */ + + /* 160 0xa0 '�' */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 161 0xa1 '�' */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 162 0xa2 '�' */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 163 0xa3 '�' */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 164 0xa4 '�' */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0xdc, /* 11011100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + + /* 165 0xa5 '�' */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0xe6, /* 11100110 */ + 0xf6, /* 11110110 */ + 0xde, /* 11011110 */ + 0xce, /* 11001110 */ + 0x00, /* 00000000 */ + + /* 166 0xa6 '�' */ + 0x3c, /* 00111100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x3e, /* 00111110 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 167 0xa7 '�' */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 168 0xa8 '�' */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x63, /* 01100011 */ + 0x3e, /* 00111110 */ + 0x00, /* 00000000 */ + + /* 169 0xa9 '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 170 0xaa '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 171 0xab '�' */ + 0x63, /* 01100011 */ + 0xe6, /* 11100110 */ + 0x6c, /* 01101100 */ + 0x7e, /* 01111110 */ + 0x33, /* 00110011 */ + 0x66, /* 01100110 */ + 0xcc, /* 11001100 */ + 0x0f, /* 00001111 */ + + /* 172 0xac '�' */ + 0x63, /* 01100011 */ + 0xe6, /* 11100110 */ + 0x6c, /* 01101100 */ + 0x7a, /* 01111010 */ + 0x36, /* 00110110 */ + 0x6a, /* 01101010 */ + 0xdf, /* 11011111 */ + 0x06, /* 00000110 */ + + /* 173 0xad '�' */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 174 0xae '�' */ + 0x00, /* 00000000 */ + 0x33, /* 00110011 */ + 0x66, /* 01100110 */ + 0xcc, /* 11001100 */ + 0x66, /* 01100110 */ + 0x33, /* 00110011 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 175 0xaf '�' */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0x66, /* 01100110 */ + 0x33, /* 00110011 */ + 0x66, /* 01100110 */ + 0xcc, /* 11001100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 176 0xb0 '�' */ + 0x22, /* 00100010 */ + 0x88, /* 10001000 */ + 0x22, /* 00100010 */ + 0x88, /* 10001000 */ + 0x22, /* 00100010 */ + 0x88, /* 10001000 */ + 0x22, /* 00100010 */ + 0x88, /* 10001000 */ + + /* 177 0xb1 '�' */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + + /* 178 0xb2 '�' */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + + /* 179 0xb3 '�' */ + 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 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 181 0xb5 '�' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 182 0xb6 '�' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf6, /* 11110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 183 0xb7 '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 184 0xb8 '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 185 0xb9 '�' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf6, /* 11110110 */ + 0x06, /* 00000110 */ + 0xf6, /* 11110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 186 0xba '�' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 187 0xbb '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x06, /* 00000110 */ + 0xf6, /* 11110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 188 0xbc '�' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf6, /* 11110110 */ + 0x06, /* 00000110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 189 0xbd '�' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 190 0xbe '�' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 191 0xbf '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 192 0xc0 '�' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 193 0xc1 '�' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 194 0xc2 '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 195 0xc3 '�' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 196 0xc4 '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 197 0xc5 '�' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 198 0xc6 '�' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 199 0xc7 '�' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x37, /* 00110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 200 0xc8 '�' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x37, /* 00110111 */ + 0x30, /* 00110000 */ + 0x3f, /* 00111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 201 0xc9 '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3f, /* 00111111 */ + 0x30, /* 00110000 */ + 0x37, /* 00110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 202 0xca '�' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf7, /* 11110111 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 203 0xcb '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0xf7, /* 11110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 204 0xcc '�' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x37, /* 00110111 */ + 0x30, /* 00110000 */ + 0x37, /* 00110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 205 0xcd '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 206 0xce '�' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf7, /* 11110111 */ + 0x00, /* 00000000 */ + 0xf7, /* 11110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 207 0xcf '�' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 208 0xd0 '�' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 209 0xd1 '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 210 0xd2 '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 211 0xd3 '�' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x3f, /* 00111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 212 0xd4 '�' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 213 0xd5 '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 214 0xd6 '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3f, /* 00111111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 215 0xd7 '�' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xff, /* 11111111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 216 0xd8 '�' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 217 0xd9 '�' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 218 0xda '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 219 0xdb '�' */ + 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 */ + 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 */ + + /* 222 0xde '�' */ + 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 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 224 0xe0 '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0xc8, /* 11001000 */ + 0xdc, /* 11011100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 225 0xe1 '�' */ + 0x78, /* 01111000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xd8, /* 11011000 */ + 0xcc, /* 11001100 */ + 0xc6, /* 11000110 */ + 0xcc, /* 11001100 */ + 0x00, /* 00000000 */ + + /* 226 0xe2 '�' */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x00, /* 00000000 */ + + /* 227 0xe3 '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + + /* 228 0xe4 '�' */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + + /* 229 0xe5 '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0x70, /* 01110000 */ + 0x00, /* 00000000 */ + + /* 230 0xe6 '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0xc0, /* 11000000 */ + + /* 231 0xe7 '�' */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 232 0xe8 '�' */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + + /* 233 0xe9 '�' */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + + /* 234 0xea '�' */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0xee, /* 11101110 */ + 0x00, /* 00000000 */ + + /* 235 0xeb '�' */ + 0x0e, /* 00001110 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x3e, /* 00111110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 236 0xec '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0xdb, /* 11011011 */ + 0xdb, /* 11011011 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 237 0xed '�' */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x7e, /* 01111110 */ + 0xdb, /* 11011011 */ + 0xdb, /* 11011011 */ + 0x7e, /* 01111110 */ + 0x60, /* 01100000 */ + 0xc0, /* 11000000 */ + + /* 238 0xee '�' */ + 0x1e, /* 00011110 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x7e, /* 01111110 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x1e, /* 00011110 */ + 0x00, /* 00000000 */ + + /* 239 0xef '�' */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 240 0xf0 '�' */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 241 0xf1 '�' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* 242 0xf2 '�' */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* 243 0xf3 '�' */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* 244 0xf4 '�' */ + 0x0e, /* 00001110 */ + 0x1b, /* 00011011 */ + 0x1b, /* 00011011 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 245 0xf5 '�' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0x70, /* 01110000 */ + + /* 246 0xf6 '�' */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 247 0xf7 '�' */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 248 0xf8 '�' */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 249 0xf9 '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 250 0xfa '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 251 0xfb '�' */ + 0x0f, /* 00001111 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0xec, /* 11101100 */ + 0x6c, /* 01101100 */ + 0x3c, /* 00111100 */ + 0x1c, /* 00011100 */ + + /* 252 0xfc '�' */ + 0x6c, /* 01101100 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 253 0xfd '�' */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 254 0xfe '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 255 0xff '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + +}; + +#undef FONTDATAMAX diff --git a/src/device/graphics/Font_acorn_8x8.h b/src/device/graphics/Font_acorn_8x8.h new file mode 100644 index 0000000..664ba16 --- /dev/null +++ b/src/device/graphics/Font_acorn_8x8.h @@ -0,0 +1,264 @@ +// vim: set et ts=4 sw=4: + +/* Acorn-like font definition, with PC graphics characters */ + +constexpr const unsigned char acorndata_8x8[] = { + /* 00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ^@ */ + /* 01 */ 0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e, /* ^A */ + /* 02 */ 0x7e, 0xff, 0xbd, 0xff, 0xc3, 0xe7, 0xff, 0x7e, /* ^B */ + /* 03 */ 0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, /* ^C */ + /* 04 */ 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, /* ^D */ + /* 05 */ 0x00, 0x18, 0x3c, 0xe7, 0xe7, 0x3c, 0x18, 0x00, /* ^E */ + /* 06 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 07 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 08 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 09 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0A */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0B */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0C */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0D */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0E */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0F */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 10 */ 0x00, 0x60, 0x78, 0x7e, 0x7e, 0x78, 0x60, 0x00, /* |> */ + /* 11 */ 0x00, 0x06, 0x1e, 0x7e, 0x7e, 0x1e, 0x06, 0x00, /* <| */ + /* 12 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 13 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 14 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 15 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 16 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 17 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 18 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 19 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 1A */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 1B */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 1C */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 1D */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 1E */ 0x00, 0x18, 0x18, 0x3c, 0x3c, 0x7e, 0x7e, 0x00, /* /\ */ + /* 1F */ 0x00, 0x7e, 0x7e, 0x3c, 0x3c, 0x18, 0x18, 0x00, /* \/ */ + /* 20 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* */ + /* 21 */ 0x18, 0x3c, 0x3c, 0x18, 0x18, 0x00, 0x18, 0x00, /* ! */ + /* 22 */ 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, /* " */ + /* 23 */ 0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00, /* # */ + /* 24 */ 0x0C, 0x3F, 0x68, 0x3E, 0x0B, 0x7E, 0x18, 0x00, /* $ */ + /* 25 */ 0x60, 0x66, 0x0C, 0x18, 0x30, 0x66, 0x06, 0x00, /* % */ + /* 26 */ 0x38, 0x6C, 0x6C, 0x38, 0x6D, 0x66, 0x3B, 0x00, /* & */ + /* 27 */ 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, /* ' */ + /* 28 */ 0x0C, 0x18, 0x30, 0x30, 0x30, 0x18, 0x0C, 0x00, /* ( */ + /* 29 */ 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x18, 0x30, 0x00, /* ) */ + /* 2A */ 0x00, 0x18, 0x7E, 0x3C, 0x7E, 0x18, 0x00, 0x00, /* * */ + /* 2B */ 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00, /* + */ + /* 2C */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, /* , */ + /* 2D */ 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, /* - */ + /* 2E */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, /* . */ + /* 2F */ 0x00, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x00, 0x00, /* / */ + /* 30 */ 0x3C, 0x66, 0x6E, 0x7E, 0x76, 0x66, 0x3C, 0x00, /* 0 */ + /* 31 */ 0x18, 0x38, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x00, /* 1 */ + /* 32 */ 0x3C, 0x66, 0x06, 0x0C, 0x18, 0x30, 0x7E, 0x00, /* 2 */ + /* 33 */ 0x3C, 0x66, 0x06, 0x1C, 0x06, 0x66, 0x3C, 0x00, /* 3 */ + /* 34 */ 0x0C, 0x1C, 0x3C, 0x6C, 0x7E, 0x0C, 0x0C, 0x00, /* 4 */ + /* 35 */ 0x7E, 0x60, 0x7C, 0x06, 0x06, 0x66, 0x3C, 0x00, /* 5 */ + /* 36 */ 0x1C, 0x30, 0x60, 0x7C, 0x66, 0x66, 0x3C, 0x00, /* 6 */ + /* 37 */ 0x7E, 0x06, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x00, /* 7 */ + /* 38 */ 0x3C, 0x66, 0x66, 0x3C, 0x66, 0x66, 0x3C, 0x00, /* 8 */ + /* 39 */ 0x3C, 0x66, 0x66, 0x3E, 0x06, 0x0C, 0x38, 0x00, /* 9 */ + /* 3A */ 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, /* : */ + /* 3B */ 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x30, /* ; */ + /* 3C */ 0x0C, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0C, 0x00, /* < */ + /* 3D */ 0x00, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00, 0x00, /* = */ + /* 3E */ 0x30, 0x18, 0x0C, 0x06, 0x0C, 0x18, 0x30, 0x00, /* > */ + /* 3F */ 0x3C, 0x66, 0x0C, 0x18, 0x18, 0x00, 0x18, 0x00, /* ? */ + /* 40 */ 0x3C, 0x66, 0x6E, 0x6A, 0x6E, 0x60, 0x3C, 0x00, /* @ */ + /* 41 */ 0x3C, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00, /* A */ + /* 42 */ 0x7C, 0x66, 0x66, 0x7C, 0x66, 0x66, 0x7C, 0x00, /* B */ + /* 43 */ 0x3C, 0x66, 0x60, 0x60, 0x60, 0x66, 0x3C, 0x00, /* C */ + /* 44 */ 0x78, 0x6C, 0x66, 0x66, 0x66, 0x6C, 0x78, 0x00, /* D */ + /* 45 */ 0x7E, 0x60, 0x60, 0x7C, 0x60, 0x60, 0x7E, 0x00, /* E */ + /* 46 */ 0x7E, 0x60, 0x60, 0x7C, 0x60, 0x60, 0x60, 0x00, /* F */ + /* 47 */ 0x3C, 0x66, 0x60, 0x6E, 0x66, 0x66, 0x3C, 0x00, /* G */ + /* 48 */ 0x66, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00, /* H */ + /* 49 */ 0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x00, /* I */ + /* 4A */ 0x3E, 0x0C, 0x0C, 0x0C, 0x0C, 0x6C, 0x38, 0x00, /* J */ + /* 4B */ 0x66, 0x6C, 0x78, 0x70, 0x78, 0x6C, 0x66, 0x00, /* K */ + /* 4C */ 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7E, 0x00, /* L */ + /* 4D */ 0x63, 0x77, 0x7F, 0x6B, 0x6B, 0x63, 0x63, 0x00, /* M */ + /* 4E */ 0x66, 0x66, 0x76, 0x7E, 0x6E, 0x66, 0x66, 0x00, /* N */ + /* 4F */ 0x3C, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00, /* O */ + /* 50 */ 0x7C, 0x66, 0x66, 0x7C, 0x60, 0x60, 0x60, 0x00, /* P */ + /* 51 */ 0x3C, 0x66, 0x66, 0x66, 0x6A, 0x6C, 0x36, 0x00, /* Q */ + /* 52 */ 0x7C, 0x66, 0x66, 0x7C, 0x6C, 0x66, 0x66, 0x00, /* R */ + /* 53 */ 0x3C, 0x66, 0x60, 0x3C, 0x06, 0x66, 0x3C, 0x00, /* S */ + /* 54 */ 0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, /* T */ + /* 55 */ 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00, /* U */ + /* 56 */ 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00, /* V */ + /* 57 */ 0x63, 0x63, 0x6B, 0x6B, 0x7F, 0x77, 0x63, 0x00, /* W */ + /* 58 */ 0x66, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x66, 0x00, /* X */ + /* 59 */ 0x66, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x18, 0x00, /* Y */ + /* 5A */ 0x7E, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x7E, 0x00, /* Z */ + /* 5B */ 0x7C, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7C, 0x00, /* [ */ + /* 5C */ 0x00, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x00, 0x00, /* \ */ + /* 5D */ 0x3E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x3E, 0x00, /* ] */ + /* 5E */ 0x3C, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ^ */ + /* 5F */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, /* _ */ + /* 60 */ 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* */ + /* 61 */ 0x00, 0x00, 0x3C, 0x06, 0x3E, 0x66, 0x3E, 0x00, /* a */ + /* 62 */ 0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x7C, 0x00, /* b */ + /* 63 */ 0x00, 0x00, 0x3C, 0x66, 0x60, 0x66, 0x3C, 0x00, /* c */ + /* 64 */ 0x06, 0x06, 0x3E, 0x66, 0x66, 0x66, 0x3E, 0x00, /* d */ + /* 65 */ 0x00, 0x00, 0x3C, 0x66, 0x7E, 0x60, 0x3C, 0x00, /* e */ + /* 66 */ 0x1C, 0x30, 0x30, 0x7C, 0x30, 0x30, 0x30, 0x00, /* f */ + /* 67 */ 0x00, 0x00, 0x3E, 0x66, 0x66, 0x3E, 0x06, 0x3C, /* g */ + /* 68 */ 0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x66, 0x00, /* h */ + /* 69 */ 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x3C, 0x00, /* i */ + /* 6A */ 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x70, /* j */ + /* 6B */ 0x60, 0x60, 0x66, 0x6C, 0x78, 0x6C, 0x66, 0x00, /* k */ + /* 6C */ 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, /* l */ + /* 6D */ 0x00, 0x00, 0x36, 0x7F, 0x6B, 0x6B, 0x63, 0x00, /* m */ + /* 6E */ 0x00, 0x00, 0x7C, 0x66, 0x66, 0x66, 0x66, 0x00, /* n */ + /* 6F */ 0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x00, /* o */ + /* 70 */ 0x00, 0x00, 0x7C, 0x66, 0x66, 0x7C, 0x60, 0x60, /* p */ + /* 71 */ 0x00, 0x00, 0x3E, 0x66, 0x66, 0x3E, 0x06, 0x07, /* q */ + /* 72 */ 0x00, 0x00, 0x6C, 0x76, 0x60, 0x60, 0x60, 0x00, /* r */ + /* 73 */ 0x00, 0x00, 0x3E, 0x60, 0x3C, 0x06, 0x7C, 0x00, /* s */ + /* 74 */ 0x30, 0x30, 0x7C, 0x30, 0x30, 0x30, 0x1C, 0x00, /* t */ + /* 75 */ 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3E, 0x00, /* u */ + /* 76 */ 0x00, 0x00, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00, /* v */ + /* 77 */ 0x00, 0x00, 0x63, 0x6B, 0x6B, 0x7F, 0x36, 0x00, /* w */ + /* 78 */ 0x00, 0x00, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x00, /* x */ + /* 79 */ 0x00, 0x00, 0x66, 0x66, 0x66, 0x3E, 0x06, 0x3C, /* y */ + /* 7A */ 0x00, 0x00, 0x7E, 0x0C, 0x18, 0x30, 0x7E, 0x00, /* z */ + /* 7B */ 0x0C, 0x18, 0x18, 0x70, 0x18, 0x18, 0x0C, 0x00, /* { */ + /* 7C */ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, /* | */ + /* 7D */ 0x30, 0x18, 0x18, 0x0E, 0x18, 0x18, 0x30, 0x00, /* } */ + /* 7E */ 0x31, 0x6B, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, /* ~ */ + /* 7F */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /*  */ + /* 80 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 81 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 82 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 83 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 84 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 85 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 86 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 87 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 88 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 89 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 8A */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 8B */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 8C */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 8D */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 8E */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 8F */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 90 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 91 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 92 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 93 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 94 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 95 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 96 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 97 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 98 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 99 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 9A */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 9B */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 9C */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 9D */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 9E */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 9F */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* A0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* A1 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* A2 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* A3 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* A4 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* A5 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* A6 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* A7 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* A8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* A9 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* AA */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* AB */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* AC */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* AD */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* AE */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* AF */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* B0 */ 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, + /* B1 */ 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, + /* B2 */ 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, + /* B3 */ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + /* B4 */ 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, + /* B5 */ 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, + /* B6 */ 0x66, 0x66, 0x66, 0xe6, 0x66, 0x66, 0x66, 0x66, + /* B7 */ 0x00, 0x00, 0x00, 0xfe, 0x66, 0x66, 0x66, 0x66, + /* B8 */ 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, + /* B9 */ 0x66, 0x66, 0xe6, 0x06, 0xe6, 0x66, 0x66, 0x66, + /* BA */ 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, + /* BB */ 0x00, 0x00, 0xfe, 0x06, 0xe6, 0x66, 0x66, 0x66, + /* BC */ 0x66, 0x66, 0xe6, 0x06, 0xfe, 0x00, 0x00, 0x00, + /* BD */ 0x66, 0x66, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, + /* BE */ 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, + /* BF */ 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, + /* C0 */ 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, + /* C1 */ 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, + /* C2 */ 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, + /* C3 */ 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, + /* C4 */ 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, + /* C5 */ 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, + /* C6 */ 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, + /* C7 */ 0x66, 0x66, 0x66, 0x67, 0x66, 0x66, 0x66, 0x66, + /* C8 */ 0x66, 0x66, 0x67, 0x60, 0x7f, 0x00, 0x00, 0x00, + /* C9 */ 0x00, 0x00, 0x7f, 0x60, 0x67, 0x66, 0x66, 0x66, + /* CA */ 0x66, 0x66, 0xe7, 0x00, 0xff, 0x00, 0x00, 0x00, + /* CB */ 0x00, 0x00, 0xff, 0x00, 0xe7, 0x66, 0x66, 0x66, + /* CC */ 0x66, 0x66, 0x67, 0x60, 0x67, 0x66, 0x66, 0x66, + /* CD */ 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, + /* CE */ 0x66, 0x66, 0xe7, 0x00, 0xe7, 0x66, 0x66, 0x66, + /* CF */ 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, + /* D0 */ 0x66, 0x66, 0x66, 0xff, 0x00, 0x00, 0x00, 0x00, + /* D1 */ 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, + /* D2 */ 0x00, 0x00, 0x00, 0xff, 0x66, 0x66, 0x66, 0x66, + /* D3 */ 0x66, 0x66, 0x66, 0x7f, 0x00, 0x00, 0x00, 0x00, + /* D4 */ 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, + /* D5 */ 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, + /* D6 */ 0x00, 0x00, 0x00, 0x7f, 0x66, 0x66, 0x66, 0x66, + /* D7 */ 0x66, 0x66, 0x66, 0xff, 0x66, 0x66, 0x66, 0x66, + /* D8 */ 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, + /* D9 */ 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, + /* DA */ 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, + /* DB */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /* DC */ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + /* DD */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, + /* DE */ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, + /* DF */ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + /* E0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* E1 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* E2 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* E3 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* E4 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* E5 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* E6 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* E7 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* E8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* E9 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* EA */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* EB */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* EC */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* ED */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* EE */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* EF */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* F0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* F1 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* F2 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* F3 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* F4 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* F5 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* F6 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* F7 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* F8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* F9 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* FA */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* FB */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* FC */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* FD */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* FE */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* FF */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +#undef FONTDATAMAX diff --git a/src/device/graphics/Font_pearl_8x8.h b/src/device/graphics/Font_pearl_8x8.h new file mode 100644 index 0000000..7826cf7 --- /dev/null +++ b/src/device/graphics/Font_pearl_8x8.h @@ -0,0 +1,2580 @@ +// vim: set et ts=4 sw=4: + +/**********************************************/ +/* */ +/* Font file generated by cpi2fnt */ +/* ------------------------------ */ +/* Combined with the alpha-numeric */ +/* portion of Greg Harp's old PEARL */ +/* font (from earlier versions of */ +/* linux-m86k) by John Shifflett */ +/* */ +/**********************************************/ + +constexpr const unsigned int FONTDATAMAX_PEARL_8x8 = 2048; + +constexpr const unsigned char fontdata_pearl_8x8[FONTDATAMAX_PEARL_8x8] = { + + /* 0 0x00 '^@' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 1 0x01 '^A' */ + 0x7e, /* 01111110 */ + 0x81, /* 10000001 */ + 0xa5, /* 10100101 */ + 0x81, /* 10000001 */ + 0xbd, /* 10111101 */ + 0x99, /* 10011001 */ + 0x81, /* 10000001 */ + 0x7e, /* 01111110 */ + + /* 2 0x02 '^B' */ + 0x7e, /* 01111110 */ + 0xff, /* 11111111 */ + 0xdb, /* 11011011 */ + 0xff, /* 11111111 */ + 0xc3, /* 11000011 */ + 0xe7, /* 11100111 */ + 0xff, /* 11111111 */ + 0x7e, /* 01111110 */ + + /* 3 0x03 '^C' */ + 0x6c, /* 01101100 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0x7c, /* 01111100 */ + 0x38, /* 00111000 */ + 0x10, /* 00010000 */ + 0x00, /* 00000000 */ + + /* 4 0x04 '^D' */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x7c, /* 01111100 */ + 0xfe, /* 11111110 */ + 0x7c, /* 01111100 */ + 0x38, /* 00111000 */ + 0x10, /* 00010000 */ + 0x00, /* 00000000 */ + + /* 5 0x05 '^E' */ + 0x38, /* 00111000 */ + 0x7c, /* 01111100 */ + 0x38, /* 00111000 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0xd6, /* 11010110 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + + /* 6 0x06 '^F' */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x7c, /* 01111100 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0x7c, /* 01111100 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + + /* 7 0x07 '^G' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 8 0x08 '^H' */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xe7, /* 11100111 */ + 0xc3, /* 11000011 */ + 0xc3, /* 11000011 */ + 0xe7, /* 11100111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + + /* 9 0x09 '^I' */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x42, /* 01000010 */ + 0x42, /* 01000010 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 10 0x0a '^J' */ + 0xff, /* 11111111 */ + 0xc3, /* 11000011 */ + 0x99, /* 10011001 */ + 0xbd, /* 10111101 */ + 0xbd, /* 10111101 */ + 0x99, /* 10011001 */ + 0xc3, /* 11000011 */ + 0xff, /* 11111111 */ + + /* 11 0x0b '^K' */ + 0x0f, /* 00001111 */ + 0x07, /* 00000111 */ + 0x0f, /* 00001111 */ + 0x7d, /* 01111101 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x78, /* 01111000 */ + + /* 12 0x0c '^L' */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + + /* 13 0x0d '^M' */ + 0x3f, /* 00111111 */ + 0x33, /* 00110011 */ + 0x3f, /* 00111111 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x70, /* 01110000 */ + 0xf0, /* 11110000 */ + 0xe0, /* 11100000 */ + + /* 14 0x0e '^N' */ + 0x7f, /* 01111111 */ + 0x63, /* 01100011 */ + 0x7f, /* 01111111 */ + 0x63, /* 01100011 */ + 0x63, /* 01100011 */ + 0x67, /* 01100111 */ + 0xe6, /* 11100110 */ + 0xc0, /* 11000000 */ + + /* 15 0x0f '^O' */ + 0x18, /* 00011000 */ + 0xdb, /* 11011011 */ + 0x3c, /* 00111100 */ + 0xe7, /* 11100111 */ + 0xe7, /* 11100111 */ + 0x3c, /* 00111100 */ + 0xdb, /* 11011011 */ + 0x18, /* 00011000 */ + + /* 16 0x10 '^P' */ + 0x80, /* 10000000 */ + 0xe0, /* 11100000 */ + 0xf8, /* 11111000 */ + 0xfe, /* 11111110 */ + 0xf8, /* 11111000 */ + 0xe0, /* 11100000 */ + 0x80, /* 10000000 */ + 0x00, /* 00000000 */ + + /* 17 0x11 '^Q' */ + 0x02, /* 00000010 */ + 0x0e, /* 00001110 */ + 0x3e, /* 00111110 */ + 0xfe, /* 11111110 */ + 0x3e, /* 00111110 */ + 0x0e, /* 00001110 */ + 0x02, /* 00000010 */ + 0x00, /* 00000000 */ + + /* 18 0x12 '^R' */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + + /* 19 0x13 '^S' */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + + /* 20 0x14 '^T' */ + 0x7f, /* 01111111 */ + 0xdb, /* 11011011 */ + 0xdb, /* 11011011 */ + 0x7b, /* 01111011 */ + 0x1b, /* 00011011 */ + 0x1b, /* 00011011 */ + 0x1b, /* 00011011 */ + 0x00, /* 00000000 */ + + /* 21 0x15 '^U' */ + 0x3e, /* 00111110 */ + 0x61, /* 01100001 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x86, /* 10000110 */ + 0x7c, /* 01111100 */ + + /* 22 0x16 '^V' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x7e, /* 01111110 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* 23 0x17 '^W' */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + + /* 24 0x18 '^X' */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 25 0x19 '^Y' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 26 0x1a '^Z' */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0xfe, /* 11111110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 27 0x1b '^[' */ + 0x00, /* 00000000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xfe, /* 11111110 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 28 0x1c '^\' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 29 0x1d '^]' */ + 0x00, /* 00000000 */ + 0x24, /* 00100100 */ + 0x66, /* 01100110 */ + 0xff, /* 11111111 */ + 0x66, /* 01100110 */ + 0x24, /* 00100100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 30 0x1e '^^' */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 31 0x1f '^_' */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0x7e, /* 01111110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 32 0x20 ' ' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 33 0x21 '!' */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 34 0x22 '"' */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 35 0x23 '#' */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + + /* 36 0x24 '$' */ + 0x18, /* 00011000 */ + 0x3e, /* 00111110 */ + 0x60, /* 01100000 */ + 0x3c, /* 00111100 */ + 0x06, /* 00000110 */ + 0x7c, /* 01111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 37 0x25 '%' */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xcc, /* 11001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x66, /* 01100110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 38 0x26 '&' */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x68, /* 01101000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 39 0x27 ''' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 40 0x28 '(' */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x00, /* 00000000 */ + + /* 41 0x29 ')' */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + + /* 42 0x2a '*' */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0xff, /* 11111111 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 43 0x2b '+' */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 44 0x2c ',' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + + /* 45 0x2d '-' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 46 0x2e '.' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 47 0x2f '/' */ + 0x03, /* 00000011 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xc0, /* 11000000 */ + 0x00, /* 00000000 */ + + /* 48 0x30 '0' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xde, /* 11011110 */ + 0xfe, /* 11111110 */ + 0xf6, /* 11110110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 49 0x31 '1' */ + 0x18, /* 00011000 */ + 0x78, /* 01111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 50 0x32 '2' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + + /* 51 0x33 '3' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0x06, /* 00000110 */ + 0x1c, /* 00011100 */ + 0x06, /* 00000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 52 0x34 '4' */ + 0x1c, /* 00011100 */ + 0x3c, /* 00111100 */ + 0x6c, /* 01101100 */ + 0xcc, /* 11001100 */ + 0xfe, /* 11111110 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x00, /* 00000000 */ + + /* 53 0x35 '5' */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xfc, /* 11111100 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 54 0x36 '6' */ + 0x38, /* 00111000 */ + 0x60, /* 01100000 */ + 0xc0, /* 11000000 */ + 0xfc, /* 11111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 55 0x37 '7' */ + 0xfe, /* 11111110 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x00, /* 00000000 */ + + /* 56 0x38 '8' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 57 0x39 '9' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7e, /* 01111110 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + + /* 58 0x3a ':' */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 59 0x3b ';' */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + + /* 60 0x3c '<' */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x00, /* 00000000 */ + + /* 61 0x3d '=' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 62 0x3e '>' */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + + /* 63 0x3f '?' */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 64 0x40 '@' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xde, /* 11011110 */ + 0xde, /* 11011110 */ + 0xde, /* 11011110 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 65 0x41 'A' */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 66 0x42 'B' */ + 0xfc, /* 11111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfc, /* 11111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfc, /* 11111100 */ + 0x00, /* 00000000 */ + + /* 67 0x43 'C' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 68 0x44 'D' */ + 0xfc, /* 11111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfc, /* 11111100 */ + 0x00, /* 00000000 */ + + /* 69 0x45 'E' */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xf8, /* 11111000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + + /* 70 0x46 'F' */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xf8, /* 11111000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x00, /* 00000000 */ + + /* 71 0x47 'G' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc0, /* 11000000 */ + 0xce, /* 11001110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 72 0x48 'H' */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 73 0x49 'I' */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* 74 0x4a 'J' */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 75 0x4b 'K' */ + 0xc6, /* 11000110 */ + 0xcc, /* 11001100 */ + 0xd8, /* 11011000 */ + 0xf0, /* 11110000 */ + 0xd8, /* 11011000 */ + 0xcc, /* 11001100 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 76 0x4c 'L' */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + + /* 77 0x4d 'M' */ + 0x82, /* 10000010 */ + 0xc6, /* 11000110 */ + 0xee, /* 11101110 */ + 0xfe, /* 11111110 */ + 0xd6, /* 11010110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 78 0x4e 'N' */ + 0xc6, /* 11000110 */ + 0xe6, /* 11100110 */ + 0xf6, /* 11110110 */ + 0xde, /* 11011110 */ + 0xce, /* 11001110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 79 0x4f 'O' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 80 0x50 'P' */ + 0xfc, /* 11111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfc, /* 11111100 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x00, /* 00000000 */ + + /* 81 0x51 'Q' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xf6, /* 11110110 */ + 0xde, /* 11011110 */ + 0x7c, /* 01111100 */ + 0x06, /* 00000110 */ + + /* 82 0x52 'R' */ + 0xfc, /* 11111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfc, /* 11111100 */ + 0xd8, /* 11011000 */ + 0xcc, /* 11001100 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 83 0x53 'S' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0x60, /* 01100000 */ + 0x38, /* 00111000 */ + 0x0c, /* 00001100 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 84 0x54 'T' */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 85 0x55 'U' */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 86 0x56 'V' */ + 0xc3, /* 11000011 */ + 0xc3, /* 11000011 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 87 0x57 'W' */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xd6, /* 11010110 */ + 0xfe, /* 11111110 */ + 0xee, /* 11101110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 88 0x58 'X' */ + 0xc3, /* 11000011 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0xc3, /* 11000011 */ + 0x00, /* 00000000 */ + + /* 89 0x59 'Y' */ + 0xc3, /* 11000011 */ + 0xc3, /* 11000011 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 90 0x5a 'Z' */ + 0xfe, /* 11111110 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + + /* 91 0x5b '[' */ + 0x3c, /* 00111100 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 92 0x5c '\' */ + 0xc0, /* 11000000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x06, /* 00000110 */ + 0x03, /* 00000011 */ + 0x00, /* 00000000 */ + + /* 93 0x5d ']' */ + 0x3c, /* 00111100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 94 0x5e '^' */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 95 0x5f '_' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + + /* 96 0x60 '`' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 97 0x61 'a' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0x06, /* 00000110 */ + 0x7e, /* 01111110 */ + 0xc6, /* 11000110 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* 98 0x62 'b' */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xfc, /* 11111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfc, /* 11111100 */ + 0x00, /* 00000000 */ + + /* 99 0x63 'c' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 100 0x64 'd' */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x7e, /* 01111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* 101 0x65 'e' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 102 0x66 'f' */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x60, /* 01100000 */ + 0xf0, /* 11110000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x00, /* 00000000 */ + + /* 103 0x67 'g' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7e, /* 01111110 */ + 0x06, /* 00000110 */ + 0x7c, /* 01111100 */ + + /* 104 0x68 'h' */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xfc, /* 11111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 105 0x69 'i' */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 106 0x6a 'j' */ + 0x06, /* 00000110 */ + 0x00, /* 00000000 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + + /* 107 0x6b 'k' */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xcc, /* 11001100 */ + 0xd8, /* 11011000 */ + 0xf0, /* 11110000 */ + 0xd8, /* 11011000 */ + 0xcc, /* 11001100 */ + 0x00, /* 00000000 */ + + /* 108 0x6c 'l' */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 109 0x6d 'm' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xec, /* 11101100 */ + 0xfe, /* 11111110 */ + 0xd6, /* 11010110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 110 0x6e 'n' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfc, /* 11111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 111 0x6f 'o' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 112 0x70 'p' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfc, /* 11111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfc, /* 11111100 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + + /* 113 0x71 'q' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7e, /* 01111110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + + /* 114 0x72 'r' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xdc, /* 11011100 */ + 0xe6, /* 11100110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x00, /* 00000000 */ + + /* 115 0x73 's' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x06, /* 00000110 */ + 0xfc, /* 11111100 */ + 0x00, /* 00000000 */ + + /* 116 0x74 't' */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x7c, /* 01111100 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x36, /* 00110110 */ + 0x1c, /* 00011100 */ + 0x00, /* 00000000 */ + + /* 117 0x75 'u' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 118 0x76 'v' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + + /* 119 0x77 'w' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xd6, /* 11010110 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + + /* 120 0x78 'x' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 121 0x79 'y' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc3, /* 11000011 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + + /* 122 0x7a 'z' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x0c, /* 00001100 */ + 0x38, /* 00111000 */ + 0x60, /* 01100000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + + /* 123 0x7b '{' */ + 0x0e, /* 00001110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x70, /* 01110000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x0e, /* 00001110 */ + 0x00, /* 00000000 */ + + /* 124 0x7c '|' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 125 0x7d '}' */ + 0x70, /* 01110000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x0e, /* 00001110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x70, /* 01110000 */ + 0x00, /* 00000000 */ + + /* 126 0x7e '~' */ + 0x72, /* 01110010 */ + 0x9c, /* 10011100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 127 0x7f '' */ + 0x00, /* 00000000 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + + /* 128 0x80 '�' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x0c, /* 00001100 */ + 0x78, /* 01111000 */ + + /* 129 0x81 '�' */ + 0xcc, /* 11001100 */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 130 0x82 '�' */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 131 0x83 '�' */ + 0x7c, /* 01111100 */ + 0x82, /* 10000010 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 132 0x84 '�' */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 133 0x85 '�' */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 134 0x86 '�' */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 135 0x87 '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x7e, /* 01111110 */ + 0x0c, /* 00001100 */ + 0x38, /* 00111000 */ + + /* 136 0x88 '�' */ + 0x7c, /* 01111100 */ + 0x82, /* 10000010 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 137 0x89 '�' */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 138 0x8a '�' */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 139 0x8b '�' */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 140 0x8c '�' */ + 0x7c, /* 01111100 */ + 0x82, /* 10000010 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 141 0x8d '�' */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 142 0x8e '�' */ + 0xc6, /* 11000110 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 143 0x8f '�' */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 144 0x90 '�' */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xf8, /* 11111000 */ + 0xc0, /* 11000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + + /* 145 0x91 '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0xd8, /* 11011000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* 146 0x92 '�' */ + 0x3e, /* 00111110 */ + 0x6c, /* 01101100 */ + 0xcc, /* 11001100 */ + 0xfe, /* 11111110 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xce, /* 11001110 */ + 0x00, /* 00000000 */ + + /* 147 0x93 '�' */ + 0x7c, /* 01111100 */ + 0x82, /* 10000010 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 148 0x94 '�' */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 149 0x95 '�' */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 150 0x96 '�' */ + 0x78, /* 01111000 */ + 0x84, /* 10000100 */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 151 0x97 '�' */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 152 0x98 '�' */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7e, /* 01111110 */ + 0x06, /* 00000110 */ + 0xfc, /* 11111100 */ + + /* 153 0x99 '�' */ + 0xc6, /* 11000110 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + + /* 154 0x9a '�' */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 155 0x9b '�' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 156 0x9c '�' */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x64, /* 01100100 */ + 0xf0, /* 11110000 */ + 0x60, /* 01100000 */ + 0x66, /* 01100110 */ + 0xfc, /* 11111100 */ + 0x00, /* 00000000 */ + + /* 157 0x9d '�' */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 158 0x9e '�' */ + 0xf8, /* 11111000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xfa, /* 11111010 */ + 0xc6, /* 11000110 */ + 0xcf, /* 11001111 */ + 0xc6, /* 11000110 */ + 0xc7, /* 11000111 */ + + /* 159 0x9f '�' */ + 0x0e, /* 00001110 */ + 0x1b, /* 00011011 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0xd8, /* 11011000 */ + 0x70, /* 01110000 */ + 0x00, /* 00000000 */ + + /* 160 0xa0 '�' */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 161 0xa1 '�' */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 162 0xa2 '�' */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 163 0xa3 '�' */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 164 0xa4 '�' */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0xdc, /* 11011100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + + /* 165 0xa5 '�' */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0xe6, /* 11100110 */ + 0xf6, /* 11110110 */ + 0xde, /* 11011110 */ + 0xce, /* 11001110 */ + 0x00, /* 00000000 */ + + /* 166 0xa6 '�' */ + 0x3c, /* 00111100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x3e, /* 00111110 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 167 0xa7 '�' */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 168 0xa8 '�' */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x63, /* 01100011 */ + 0x3e, /* 00111110 */ + 0x00, /* 00000000 */ + + /* 169 0xa9 '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 170 0xaa '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 171 0xab '�' */ + 0x63, /* 01100011 */ + 0xe6, /* 11100110 */ + 0x6c, /* 01101100 */ + 0x7e, /* 01111110 */ + 0x33, /* 00110011 */ + 0x66, /* 01100110 */ + 0xcc, /* 11001100 */ + 0x0f, /* 00001111 */ + + /* 172 0xac '�' */ + 0x63, /* 01100011 */ + 0xe6, /* 11100110 */ + 0x6c, /* 01101100 */ + 0x7a, /* 01111010 */ + 0x36, /* 00110110 */ + 0x6a, /* 01101010 */ + 0xdf, /* 11011111 */ + 0x06, /* 00000110 */ + + /* 173 0xad '�' */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 174 0xae '�' */ + 0x00, /* 00000000 */ + 0x33, /* 00110011 */ + 0x66, /* 01100110 */ + 0xcc, /* 11001100 */ + 0x66, /* 01100110 */ + 0x33, /* 00110011 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 175 0xaf '�' */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0x66, /* 01100110 */ + 0x33, /* 00110011 */ + 0x66, /* 01100110 */ + 0xcc, /* 11001100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 176 0xb0 '�' */ + 0x22, /* 00100010 */ + 0x88, /* 10001000 */ + 0x22, /* 00100010 */ + 0x88, /* 10001000 */ + 0x22, /* 00100010 */ + 0x88, /* 10001000 */ + 0x22, /* 00100010 */ + 0x88, /* 10001000 */ + + /* 177 0xb1 '�' */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + + /* 178 0xb2 '�' */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + + /* 179 0xb3 '�' */ + 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 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 181 0xb5 '�' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 182 0xb6 '�' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf6, /* 11110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 183 0xb7 '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 184 0xb8 '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 185 0xb9 '�' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf6, /* 11110110 */ + 0x06, /* 00000110 */ + 0xf6, /* 11110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 186 0xba '�' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 187 0xbb '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x06, /* 00000110 */ + 0xf6, /* 11110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 188 0xbc '�' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf6, /* 11110110 */ + 0x06, /* 00000110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 189 0xbd '�' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 190 0xbe '�' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 191 0xbf '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 192 0xc0 '�' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 193 0xc1 '�' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 194 0xc2 '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 195 0xc3 '�' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 196 0xc4 '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 197 0xc5 '�' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 198 0xc6 '�' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 199 0xc7 '�' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x37, /* 00110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 200 0xc8 '�' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x37, /* 00110111 */ + 0x30, /* 00110000 */ + 0x3f, /* 00111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 201 0xc9 '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3f, /* 00111111 */ + 0x30, /* 00110000 */ + 0x37, /* 00110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 202 0xca '�' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf7, /* 11110111 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 203 0xcb '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0xf7, /* 11110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 204 0xcc '�' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x37, /* 00110111 */ + 0x30, /* 00110000 */ + 0x37, /* 00110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 205 0xcd '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 206 0xce '�' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf7, /* 11110111 */ + 0x00, /* 00000000 */ + 0xf7, /* 11110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 207 0xcf '�' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 208 0xd0 '�' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 209 0xd1 '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 210 0xd2 '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 211 0xd3 '�' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x3f, /* 00111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 212 0xd4 '�' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 213 0xd5 '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 214 0xd6 '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3f, /* 00111111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 215 0xd7 '�' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xff, /* 11111111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 216 0xd8 '�' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 217 0xd9 '�' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 218 0xda '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 219 0xdb '�' */ + 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 */ + 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 */ + + /* 222 0xde '�' */ + 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 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 224 0xe0 '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0xc8, /* 11001000 */ + 0xdc, /* 11011100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 225 0xe1 '�' */ + 0x78, /* 01111000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xd8, /* 11011000 */ + 0xcc, /* 11001100 */ + 0xc6, /* 11000110 */ + 0xcc, /* 11001100 */ + 0x00, /* 00000000 */ + + /* 226 0xe2 '�' */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x00, /* 00000000 */ + + /* 227 0xe3 '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + + /* 228 0xe4 '�' */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + + /* 229 0xe5 '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0x70, /* 01110000 */ + 0x00, /* 00000000 */ + + /* 230 0xe6 '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0xc0, /* 11000000 */ + + /* 231 0xe7 '�' */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 232 0xe8 '�' */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + + /* 233 0xe9 '�' */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + + /* 234 0xea '�' */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0xee, /* 11101110 */ + 0x00, /* 00000000 */ + + /* 235 0xeb '�' */ + 0x0e, /* 00001110 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x3e, /* 00111110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 236 0xec '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0xdb, /* 11011011 */ + 0xdb, /* 11011011 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 237 0xed '�' */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x7e, /* 01111110 */ + 0xdb, /* 11011011 */ + 0xdb, /* 11011011 */ + 0x7e, /* 01111110 */ + 0x60, /* 01100000 */ + 0xc0, /* 11000000 */ + + /* 238 0xee '�' */ + 0x1e, /* 00011110 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x7e, /* 01111110 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x1e, /* 00011110 */ + 0x00, /* 00000000 */ + + /* 239 0xef '�' */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 240 0xf0 '�' */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 241 0xf1 '�' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* 242 0xf2 '�' */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* 243 0xf3 '�' */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* 244 0xf4 '�' */ + 0x0e, /* 00001110 */ + 0x1b, /* 00011011 */ + 0x1b, /* 00011011 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 245 0xf5 '�' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0x70, /* 01110000 */ + + /* 246 0xf6 '�' */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 247 0xf7 '�' */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 248 0xf8 '�' */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 249 0xf9 '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 250 0xfa '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 251 0xfb '�' */ + 0x0f, /* 00001111 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0xec, /* 11101100 */ + 0x6c, /* 01101100 */ + 0x3c, /* 00111100 */ + 0x1c, /* 00011100 */ + + /* 252 0xfc '�' */ + 0x6c, /* 01101100 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 253 0xfd '�' */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 254 0xfe '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 255 0xff '�' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + +}; + +#undef FONTDATAMAX diff --git a/src/device/graphics/Font_sun_12x22.h b/src/device/graphics/Font_sun_12x22.h new file mode 100644 index 0000000..ae1ea2d --- /dev/null +++ b/src/device/graphics/Font_sun_12x22.h @@ -0,0 +1,6208 @@ +// vim: set et ts=4 sw=4: + +constexpr const unsigned int FONTDATAMAX_SUN_12x22 = 11264; + +constexpr const unsigned char fontdata_sun_12x22[FONTDATAMAX_SUN_12x22] = { + + /* 0 0x00 '^@' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 1 0x01 '^A' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 2 0x02 '^B' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 3 0x03 '^C' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 4 0x04 '^D' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 5 0x05 '^E' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 6 0x06 '^F' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 7 0x07 '^G' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 8 0x08 '^H' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 9 0x09 '^I' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 10 0x0a '^J' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 11 0x0b '^K' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 12 0x0c '^L' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 13 0x0d '^M' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 14 0x0e '^N' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 15 0x0f '^O' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 16 0x10 '^P' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 17 0x11 '^Q' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 18 0x12 '^R' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 19 0x13 '^S' */ + 0x00, 0x00, /* 000000000000 */ + 0x31, 0x80, /* 001100011000 */ + 0x31, 0x80, /* 001100011000 */ + 0x31, 0x80, /* 001100011000 */ + 0x31, 0x80, /* 001100011000 */ + 0x31, 0x80, /* 001100011000 */ + 0x31, 0x80, /* 001100011000 */ + 0x31, 0x80, /* 001100011000 */ + 0x31, 0x80, /* 001100011000 */ + 0x31, 0x80, /* 001100011000 */ + 0x31, 0x80, /* 001100011000 */ + 0x31, 0x80, /* 001100011000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x31, 0x80, /* 001100011000 */ + 0x31, 0x80, /* 001100011000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 20 0x14 '^T' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x1f, 0xf0, /* 000111111111 */ + 0x3c, 0xc0, /* 001111001100 */ + 0x7c, 0xc0, /* 011111001100 */ + 0x7c, 0xc0, /* 011111001100 */ + 0x7c, 0xc0, /* 011111001100 */ + 0x3c, 0xc0, /* 001111001100 */ + 0x1c, 0xc0, /* 000111001100 */ + 0x0c, 0xc0, /* 000011001100 */ + 0x0c, 0xc0, /* 000011001100 */ + 0x0c, 0xc0, /* 000011001100 */ + 0x0c, 0xc0, /* 000011001100 */ + 0x0c, 0xc0, /* 000011001100 */ + 0x0c, 0xc0, /* 000011001100 */ + 0x1c, 0xe0, /* 000111001110 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 21 0x15 '^U' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x1f, 0x00, /* 000111110000 */ + 0x31, 0x80, /* 001100011000 */ + 0x31, 0x80, /* 001100011000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x1f, 0x00, /* 000111110000 */ + 0x31, 0x80, /* 001100011000 */ + 0x31, 0x80, /* 001100011000 */ + 0x1f, 0x00, /* 000111110000 */ + 0x01, 0x80, /* 000000011000 */ + 0x01, 0x80, /* 000000011000 */ + 0x31, 0x80, /* 001100011000 */ + 0x31, 0x80, /* 001100011000 */ + 0x1f, 0x00, /* 000111110000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 22 0x16 '^V' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 23 0x17 '^W' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 24 0x18 '^X' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 25 0x19 '^Y' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 26 0x1a '^Z' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 27 0x1b '^[' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 28 0x1c '^\' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 29 0x1d '^]' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 30 0x1e '^^' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 31 0x1f '^_' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 32 0x20 ' ' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 33 0x21 '!' */ + 0x00, 0x00, /* 000000000000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 34 0x22 '"' */ + 0x00, 0x00, /* 000000000000 */ + 0x19, 0x80, /* 000110011000 */ + 0x19, 0x80, /* 000110011000 */ + 0x19, 0x80, /* 000110011000 */ + 0x19, 0x80, /* 000110011000 */ + 0x19, 0x80, /* 000110011000 */ + 0x19, 0x80, /* 000110011000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 35 0x23 '#' */ + 0x00, 0x00, /* 000000000000 */ + 0x03, 0x30, /* 000000110011 */ + 0x03, 0x30, /* 000000110011 */ + 0x03, 0x30, /* 000000110011 */ + 0x06, 0x60, /* 000001100110 */ + 0x1f, 0xf0, /* 000111111111 */ + 0x1f, 0xf0, /* 000111111111 */ + 0x0c, 0xc0, /* 000011001100 */ + 0x0c, 0xc0, /* 000011001100 */ + 0x19, 0x80, /* 000110011000 */ + 0x19, 0x80, /* 000110011000 */ + 0x7f, 0xc0, /* 011111111100 */ + 0x7f, 0xc0, /* 011111111100 */ + 0x33, 0x00, /* 001100110000 */ + 0x66, 0x00, /* 011001100000 */ + 0x66, 0x00, /* 011001100000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 36 0x24 '$' */ + 0x00, 0x00, /* 000000000000 */ + 0x06, 0x00, /* 000001100000 */ + 0x1f, 0x80, /* 000111111000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x66, 0xe0, /* 011001101110 */ + 0x66, 0x60, /* 011001100110 */ + 0x66, 0x00, /* 011001100000 */ + 0x3e, 0x00, /* 001111100000 */ + 0x1f, 0x80, /* 000111111000 */ + 0x07, 0xc0, /* 000001111100 */ + 0x06, 0x60, /* 000001100110 */ + 0x06, 0x60, /* 000001100110 */ + 0x66, 0x60, /* 011001100110 */ + 0x7f, 0xc0, /* 011111111100 */ + 0x3f, 0x80, /* 001111111000 */ + 0x06, 0x00, /* 000001100000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 37 0x25 '%' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x38, 0xc0, /* 001110001100 */ + 0x4c, 0xc0, /* 010011001100 */ + 0x45, 0x80, /* 010001011000 */ + 0x65, 0x80, /* 011001011000 */ + 0x3b, 0x00, /* 001110110000 */ + 0x03, 0x00, /* 000000110000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0d, 0xc0, /* 000011011100 */ + 0x1a, 0x60, /* 000110100110 */ + 0x1a, 0x20, /* 000110100010 */ + 0x33, 0x20, /* 001100110010 */ + 0x31, 0xc0, /* 001100011100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 38 0x26 '&' */ + 0x00, 0x00, /* 000000000000 */ + 0x07, 0x00, /* 000001110000 */ + 0x0f, 0x80, /* 000011111000 */ + 0x18, 0xc0, /* 000110001100 */ + 0x18, 0xc0, /* 000110001100 */ + 0x18, 0xc0, /* 000110001100 */ + 0x0f, 0x80, /* 000011111000 */ + 0x1e, 0x00, /* 000111100000 */ + 0x3e, 0x00, /* 001111100000 */ + 0x77, 0x00, /* 011101110000 */ + 0x63, 0x60, /* 011000110110 */ + 0x61, 0xe0, /* 011000011110 */ + 0x61, 0xc0, /* 011000011100 */ + 0x61, 0x80, /* 011000011000 */ + 0x3f, 0xe0, /* 001111111110 */ + 0x1e, 0x60, /* 000111100110 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 39 0x27 ''' */ + 0x00, 0x00, /* 000000000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x1e, 0x00, /* 000111100000 */ + 0x1e, 0x00, /* 000111100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x18, 0x00, /* 000110000000 */ + 0x10, 0x00, /* 000100000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 40 0x28 '(' */ + 0x00, 0x00, /* 000000000000 */ + 0x01, 0x80, /* 000000011000 */ + 0x03, 0x00, /* 000000110000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x03, 0x00, /* 000000110000 */ + 0x01, 0x80, /* 000000011000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 41 0x29 ')' */ + 0x00, 0x00, /* 000000000000 */ + 0x18, 0x00, /* 000110000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x03, 0x00, /* 000000110000 */ + 0x03, 0x00, /* 000000110000 */ + 0x03, 0x00, /* 000000110000 */ + 0x03, 0x00, /* 000000110000 */ + 0x03, 0x00, /* 000000110000 */ + 0x03, 0x00, /* 000000110000 */ + 0x03, 0x00, /* 000000110000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x18, 0x00, /* 000110000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 42 0x2a '*' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x0f, 0x00, /* 000011110000 */ + 0x06, 0x00, /* 000001100000 */ + 0x66, 0x60, /* 011001100110 */ + 0x76, 0xe0, /* 011101101110 */ + 0x19, 0x80, /* 000110011000 */ + 0x00, 0x00, /* 000000000000 */ + 0x19, 0x80, /* 000110011000 */ + 0x76, 0xe0, /* 011101101110 */ + 0x66, 0x60, /* 011001100110 */ + 0x06, 0x00, /* 000001100000 */ + 0x0f, 0x00, /* 000011110000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 43 0x2b '+' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 44 0x2c ',' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x1e, 0x00, /* 000111100000 */ + 0x1e, 0x00, /* 000111100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x18, 0x00, /* 000110000000 */ + 0x10, 0x00, /* 000100000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 45 0x2d '-' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 46 0x2e '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x1e, 0x00, /* 000111100000 */ + 0x1e, 0x00, /* 000111100000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 47 0x2f '/' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x60, /* 000000000110 */ + 0x00, 0xc0, /* 000000001100 */ + 0x00, 0xc0, /* 000000001100 */ + 0x01, 0x80, /* 000000011000 */ + 0x01, 0x80, /* 000000011000 */ + 0x03, 0x00, /* 000000110000 */ + 0x03, 0x00, /* 000000110000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x18, 0x00, /* 000110000000 */ + 0x18, 0x00, /* 000110000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x60, 0x00, /* 011000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 48 0x30 '0' */ + 0x00, 0x00, /* 000000000000 */ + 0x07, 0x00, /* 000001110000 */ + 0x0f, 0x80, /* 000011111000 */ + 0x11, 0x80, /* 000100011000 */ + 0x10, 0xc0, /* 000100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0x80, /* 001100001000 */ + 0x18, 0x80, /* 000110001000 */ + 0x1f, 0x00, /* 000111110000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 49 0x31 '1' */ + 0x00, 0x00, /* 000000000000 */ + 0x02, 0x00, /* 000000100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x1e, 0x00, /* 000111100000 */ + 0x36, 0x00, /* 001101100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 50 0x32 '2' */ + 0x00, 0x00, /* 000000000000 */ + 0x1f, 0x00, /* 000111110000 */ + 0x3f, 0x80, /* 001111111000 */ + 0x61, 0xc0, /* 011000011100 */ + 0x40, 0xc0, /* 010000001100 */ + 0x00, 0xc0, /* 000000001100 */ + 0x00, 0xc0, /* 000000001100 */ + 0x00, 0xc0, /* 000000001100 */ + 0x01, 0x80, /* 000000011000 */ + 0x03, 0x00, /* 000000110000 */ + 0x06, 0x00, /* 000001100000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x18, 0x00, /* 000110000000 */ + 0x30, 0x20, /* 001100000010 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 51 0x33 '3' */ + 0x00, 0x00, /* 000000000000 */ + 0x0f, 0x80, /* 000011111000 */ + 0x1f, 0xc0, /* 000111111100 */ + 0x20, 0xe0, /* 001000001110 */ + 0x40, 0x60, /* 010000000110 */ + 0x00, 0x60, /* 000000000110 */ + 0x00, 0xe0, /* 000000001110 */ + 0x07, 0xc0, /* 000001111100 */ + 0x0f, 0xc0, /* 000011111100 */ + 0x00, 0xe0, /* 000000001110 */ + 0x00, 0x60, /* 000000000110 */ + 0x00, 0x60, /* 000000000110 */ + 0x40, 0x60, /* 010000000110 */ + 0x60, 0x40, /* 011000000100 */ + 0x3f, 0x80, /* 001111111000 */ + 0x1f, 0x00, /* 000111110000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 52 0x34 '4' */ + 0x00, 0x00, /* 000000000000 */ + 0x01, 0x80, /* 000000011000 */ + 0x03, 0x80, /* 000000111000 */ + 0x03, 0x80, /* 000000111000 */ + 0x05, 0x80, /* 000001011000 */ + 0x05, 0x80, /* 000001011000 */ + 0x09, 0x80, /* 000010011000 */ + 0x09, 0x80, /* 000010011000 */ + 0x11, 0x80, /* 000100011000 */ + 0x11, 0x80, /* 000100011000 */ + 0x21, 0x80, /* 001000011000 */ + 0x3f, 0xe0, /* 001111111110 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x01, 0x80, /* 000000011000 */ + 0x01, 0x80, /* 000000011000 */ + 0x01, 0x80, /* 000000011000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 53 0x35 '5' */ + 0x00, 0x00, /* 000000000000 */ + 0x0f, 0xc0, /* 000011111100 */ + 0x0f, 0xc0, /* 000011111100 */ + 0x10, 0x00, /* 000100000000 */ + 0x10, 0x00, /* 000100000000 */ + 0x20, 0x00, /* 001000000000 */ + 0x3f, 0x80, /* 001111111000 */ + 0x31, 0xc0, /* 001100011100 */ + 0x00, 0xe0, /* 000000001110 */ + 0x00, 0x60, /* 000000000110 */ + 0x00, 0x60, /* 000000000110 */ + 0x00, 0x60, /* 000000000110 */ + 0x40, 0x60, /* 010000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x30, 0xc0, /* 001100001100 */ + 0x1f, 0x80, /* 000111111000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 54 0x36 '6' */ + 0x00, 0x00, /* 000000000000 */ + 0x07, 0x00, /* 000001110000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x18, 0x00, /* 000110000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x60, 0x00, /* 011000000000 */ + 0x67, 0x80, /* 011001111000 */ + 0x6f, 0xc0, /* 011011111100 */ + 0x70, 0xe0, /* 011100001110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x70, 0x40, /* 011100000100 */ + 0x3f, 0x80, /* 001111111000 */ + 0x1f, 0x00, /* 000111110000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 55 0x37 '7' */ + 0x00, 0x00, /* 000000000000 */ + 0x1f, 0xe0, /* 000111111110 */ + 0x3f, 0xe0, /* 001111111110 */ + 0x60, 0x40, /* 011000000100 */ + 0x00, 0x40, /* 000000000100 */ + 0x00, 0xc0, /* 000000001100 */ + 0x00, 0x80, /* 000000001000 */ + 0x00, 0x80, /* 000000001000 */ + 0x01, 0x80, /* 000000011000 */ + 0x01, 0x00, /* 000000010000 */ + 0x01, 0x00, /* 000000010000 */ + 0x03, 0x00, /* 000000110000 */ + 0x02, 0x00, /* 000000100000 */ + 0x02, 0x00, /* 000000100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x04, 0x00, /* 000001000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 56 0x38 '8' */ + 0x00, 0x00, /* 000000000000 */ + 0x0f, 0x00, /* 000011110000 */ + 0x11, 0x80, /* 000100011000 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x18, 0x80, /* 000110001000 */ + 0x0d, 0x00, /* 000011010000 */ + 0x06, 0x00, /* 000001100000 */ + 0x0b, 0x00, /* 000010110000 */ + 0x11, 0x80, /* 000100011000 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x18, 0x80, /* 000110001000 */ + 0x0f, 0x00, /* 000011110000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 57 0x39 '9' */ + 0x00, 0x00, /* 000000000000 */ + 0x0f, 0x80, /* 000011111000 */ + 0x11, 0xc0, /* 000100011100 */ + 0x20, 0xe0, /* 001000001110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x70, 0xe0, /* 011100001110 */ + 0x3f, 0x60, /* 001111110110 */ + 0x1e, 0x60, /* 000111100110 */ + 0x00, 0x60, /* 000000000110 */ + 0x00, 0xc0, /* 000000001100 */ + 0x00, 0xc0, /* 000000001100 */ + 0x01, 0x80, /* 000000011000 */ + 0x07, 0x00, /* 000001110000 */ + 0x3c, 0x00, /* 001111000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 58 0x3a ':' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x1e, 0x00, /* 000111100000 */ + 0x1e, 0x00, /* 000111100000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x1e, 0x00, /* 000111100000 */ + 0x1e, 0x00, /* 000111100000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 59 0x3b ';' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x1e, 0x00, /* 000111100000 */ + 0x1e, 0x00, /* 000111100000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x1e, 0x00, /* 000111100000 */ + 0x1e, 0x00, /* 000111100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x18, 0x00, /* 000110000000 */ + 0x10, 0x00, /* 000100000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 60 0x3c '<' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x60, /* 000000000110 */ + 0x01, 0xc0, /* 000000011100 */ + 0x07, 0x00, /* 000001110000 */ + 0x1c, 0x00, /* 000111000000 */ + 0x70, 0x00, /* 011100000000 */ + 0x70, 0x00, /* 011100000000 */ + 0x1c, 0x00, /* 000111000000 */ + 0x07, 0x00, /* 000001110000 */ + 0x01, 0xc0, /* 000000011100 */ + 0x00, 0x60, /* 000000000110 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 61 0x3d '=' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 62 0x3e '>' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x60, 0x00, /* 011000000000 */ + 0x38, 0x00, /* 001110000000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x03, 0x80, /* 000000111000 */ + 0x00, 0xe0, /* 000000001110 */ + 0x00, 0xe0, /* 000000001110 */ + 0x03, 0x80, /* 000000111000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x38, 0x00, /* 001110000000 */ + 0x60, 0x00, /* 011000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 63 0x3f '?' */ + 0x00, 0x00, /* 000000000000 */ + 0x0f, 0x00, /* 000011110000 */ + 0x1f, 0x80, /* 000111111000 */ + 0x39, 0xc0, /* 001110011100 */ + 0x20, 0xc0, /* 001000001100 */ + 0x00, 0xc0, /* 000000001100 */ + 0x00, 0xc0, /* 000000001100 */ + 0x01, 0x80, /* 000000011000 */ + 0x03, 0x00, /* 000000110000 */ + 0x06, 0x00, /* 000001100000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 64 0x40 '@' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x0f, 0x80, /* 000011111000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x30, 0x60, /* 001100000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x67, 0x20, /* 011001110010 */ + 0x6f, 0xa0, /* 011011111010 */ + 0x6c, 0xa0, /* 011011001010 */ + 0x6c, 0xa0, /* 011011001010 */ + 0x67, 0xe0, /* 011001111110 */ + 0x60, 0x00, /* 011000000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x3f, 0xe0, /* 001111111110 */ + 0x0f, 0xe0, /* 000011111110 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 65 0x41 'A' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x0b, 0x00, /* 000010110000 */ + 0x0b, 0x00, /* 000010110000 */ + 0x09, 0x00, /* 000010010000 */ + 0x11, 0x80, /* 000100011000 */ + 0x11, 0x80, /* 000100011000 */ + 0x10, 0x80, /* 000100001000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x20, 0xc0, /* 001000001100 */ + 0x20, 0x40, /* 001000000100 */ + 0x40, 0x60, /* 010000000110 */ + 0x40, 0x60, /* 010000000110 */ + 0xe0, 0xf0, /* 111000001111 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 66 0x42 'B' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0xff, 0x00, /* 111111110000 */ + 0x60, 0x80, /* 011000001000 */ + 0x60, 0xc0, /* 011000001100 */ + 0x60, 0xc0, /* 011000001100 */ + 0x60, 0xc0, /* 011000001100 */ + 0x61, 0x80, /* 011000011000 */ + 0x7f, 0x80, /* 011111111000 */ + 0x60, 0xc0, /* 011000001100 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0xc0, /* 011000001100 */ + 0xff, 0x80, /* 111111111000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 67 0x43 'C' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x0f, 0xc0, /* 000011111100 */ + 0x10, 0x60, /* 000100000110 */ + 0x20, 0x20, /* 001000000010 */ + 0x20, 0x00, /* 001000000000 */ + 0x60, 0x00, /* 011000000000 */ + 0x60, 0x00, /* 011000000000 */ + 0x60, 0x00, /* 011000000000 */ + 0x60, 0x00, /* 011000000000 */ + 0x60, 0x00, /* 011000000000 */ + 0x60, 0x00, /* 011000000000 */ + 0x20, 0x00, /* 001000000000 */ + 0x30, 0x20, /* 001100000010 */ + 0x18, 0x40, /* 000110000100 */ + 0x0f, 0x80, /* 000011111000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 68 0x44 'D' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0xff, 0x00, /* 111111110000 */ + 0x61, 0xc0, /* 011000011100 */ + 0x60, 0xc0, /* 011000001100 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x40, /* 011000000100 */ + 0x61, 0x80, /* 011000011000 */ + 0xfe, 0x00, /* 111111100000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 69 0x45 'E' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x7f, 0xc0, /* 011111111100 */ + 0x30, 0x40, /* 001100000100 */ + 0x30, 0x40, /* 001100000100 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x80, /* 001100001000 */ + 0x3f, 0x80, /* 001111111000 */ + 0x30, 0x80, /* 001100001000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x20, /* 001100000010 */ + 0x30, 0x20, /* 001100000010 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 70 0x46 'F' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x7f, 0xc0, /* 011111111100 */ + 0x30, 0x40, /* 001100000100 */ + 0x30, 0x40, /* 001100000100 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x80, /* 001100001000 */ + 0x3f, 0x80, /* 001111111000 */ + 0x30, 0x80, /* 001100001000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x78, 0x00, /* 011110000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 71 0x47 'G' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x0f, 0xc0, /* 000011111100 */ + 0x10, 0x60, /* 000100000110 */ + 0x20, 0x20, /* 001000000010 */ + 0x20, 0x00, /* 001000000000 */ + 0x60, 0x00, /* 011000000000 */ + 0x60, 0x00, /* 011000000000 */ + 0x60, 0x00, /* 011000000000 */ + 0x60, 0x00, /* 011000000000 */ + 0x61, 0xf0, /* 011000011111 */ + 0x60, 0x60, /* 011000000110 */ + 0x20, 0x60, /* 001000000110 */ + 0x30, 0x60, /* 001100000110 */ + 0x18, 0x60, /* 000110000110 */ + 0x0f, 0x80, /* 000011111000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 72 0x48 'H' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0xf0, 0xf0, /* 111100001111 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0xf0, 0xf0, /* 111100001111 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 73 0x49 'I' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x1f, 0x80, /* 000111111000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x1f, 0x80, /* 000111111000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 74 0x4a 'J' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x1f, 0x80, /* 000111111000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x04, 0x00, /* 000001000000 */ + 0x38, 0x00, /* 001110000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 75 0x4b 'K' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0xf0, 0xe0, /* 111100001110 */ + 0x61, 0x80, /* 011000011000 */ + 0x63, 0x00, /* 011000110000 */ + 0x66, 0x00, /* 011001100000 */ + 0x6c, 0x00, /* 011011000000 */ + 0x78, 0x00, /* 011110000000 */ + 0x78, 0x00, /* 011110000000 */ + 0x7c, 0x00, /* 011111000000 */ + 0x6e, 0x00, /* 011011100000 */ + 0x67, 0x00, /* 011001110000 */ + 0x63, 0x80, /* 011000111000 */ + 0x61, 0xc0, /* 011000011100 */ + 0x60, 0xe0, /* 011000001110 */ + 0xf0, 0x70, /* 111100000111 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 76 0x4c 'L' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x78, 0x00, /* 011110000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x20, /* 001100000010 */ + 0x30, 0x20, /* 001100000010 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 77 0x4d 'M' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0xe0, 0x70, /* 111000000111 */ + 0x60, 0xe0, /* 011000001110 */ + 0x70, 0xe0, /* 011100001110 */ + 0x70, 0xe0, /* 011100001110 */ + 0x70, 0xe0, /* 011100001110 */ + 0x59, 0x60, /* 010110010110 */ + 0x59, 0x60, /* 010110010110 */ + 0x59, 0x60, /* 010110010110 */ + 0x4d, 0x60, /* 010011010110 */ + 0x4e, 0x60, /* 010011100110 */ + 0x4e, 0x60, /* 010011100110 */ + 0x44, 0x60, /* 010001000110 */ + 0x44, 0x60, /* 010001000110 */ + 0xe4, 0xf0, /* 111001001111 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 78 0x4e 'N' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0xc0, 0x70, /* 110000000111 */ + 0x60, 0x20, /* 011000000010 */ + 0x70, 0x20, /* 011100000010 */ + 0x78, 0x20, /* 011110000010 */ + 0x58, 0x20, /* 010110000010 */ + 0x4c, 0x20, /* 010011000010 */ + 0x46, 0x20, /* 010001100010 */ + 0x47, 0x20, /* 010001110010 */ + 0x43, 0x20, /* 010000110010 */ + 0x41, 0xa0, /* 010000011010 */ + 0x40, 0xe0, /* 010000001110 */ + 0x40, 0xe0, /* 010000001110 */ + 0x40, 0x60, /* 010000000110 */ + 0xe0, 0x30, /* 111000000011 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 79 0x4f 'O' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x0f, 0x00, /* 000011110000 */ + 0x11, 0xc0, /* 000100011100 */ + 0x20, 0xc0, /* 001000001100 */ + 0x20, 0x60, /* 001000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x20, 0x40, /* 001000000100 */ + 0x30, 0x40, /* 001100000100 */ + 0x18, 0x80, /* 000110001000 */ + 0x0f, 0x00, /* 000011110000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 80 0x50 'P' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x7f, 0x80, /* 011111111000 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0x60, /* 001100000110 */ + 0x30, 0x60, /* 001100000110 */ + 0x30, 0x60, /* 001100000110 */ + 0x30, 0xc0, /* 001100001100 */ + 0x37, 0x80, /* 001101111000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x78, 0x00, /* 011110000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 81 0x51 'Q' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x0f, 0x00, /* 000011110000 */ + 0x11, 0xc0, /* 000100011100 */ + 0x20, 0xc0, /* 001000001100 */ + 0x20, 0x60, /* 001000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x30, 0x40, /* 001100000100 */ + 0x38, 0x40, /* 001110000100 */ + 0x1f, 0x80, /* 000111111000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x1f, 0x00, /* 000111110000 */ + 0x23, 0x90, /* 001000111001 */ + 0x01, 0xe0, /* 000000011110 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 82 0x52 'R' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0xff, 0x00, /* 111111110000 */ + 0x61, 0x80, /* 011000011000 */ + 0x60, 0xc0, /* 011000001100 */ + 0x60, 0xc0, /* 011000001100 */ + 0x60, 0xc0, /* 011000001100 */ + 0x60, 0x80, /* 011000001000 */ + 0x7f, 0x00, /* 011111110000 */ + 0x7c, 0x00, /* 011111000000 */ + 0x6e, 0x00, /* 011011100000 */ + 0x67, 0x00, /* 011001110000 */ + 0x63, 0x80, /* 011000111000 */ + 0x61, 0xc0, /* 011000011100 */ + 0x60, 0xe0, /* 011000001110 */ + 0xf0, 0x70, /* 111100000111 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 83 0x53 'S' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x1f, 0xe0, /* 000111111110 */ + 0x30, 0x60, /* 001100000110 */ + 0x60, 0x20, /* 011000000010 */ + 0x60, 0x20, /* 011000000010 */ + 0x70, 0x00, /* 011100000000 */ + 0x3c, 0x00, /* 001111000000 */ + 0x1e, 0x00, /* 000111100000 */ + 0x07, 0x80, /* 000001111000 */ + 0x01, 0xc0, /* 000000011100 */ + 0x00, 0xe0, /* 000000001110 */ + 0x40, 0x60, /* 010000000110 */ + 0x40, 0x60, /* 010000000110 */ + 0x60, 0xc0, /* 011000001100 */ + 0x7f, 0x80, /* 011111111000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 84 0x54 'T' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x46, 0x20, /* 010001100010 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x1f, 0x80, /* 000111111000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 85 0x55 'U' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0xf0, 0x70, /* 111100000111 */ + 0x60, 0x20, /* 011000000010 */ + 0x60, 0x20, /* 011000000010 */ + 0x60, 0x20, /* 011000000010 */ + 0x60, 0x20, /* 011000000010 */ + 0x60, 0x20, /* 011000000010 */ + 0x60, 0x20, /* 011000000010 */ + 0x60, 0x20, /* 011000000010 */ + 0x60, 0x20, /* 011000000010 */ + 0x60, 0x20, /* 011000000010 */ + 0x60, 0x20, /* 011000000010 */ + 0x70, 0x40, /* 011100000100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x1f, 0x80, /* 000111111000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 86 0x56 'V' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0xe0, 0xe0, /* 111000001110 */ + 0x60, 0x40, /* 011000000100 */ + 0x30, 0x80, /* 001100001000 */ + 0x30, 0x80, /* 001100001000 */ + 0x30, 0x80, /* 001100001000 */ + 0x19, 0x00, /* 000110010000 */ + 0x19, 0x00, /* 000110010000 */ + 0x19, 0x00, /* 000110010000 */ + 0x0a, 0x00, /* 000010100000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x04, 0x00, /* 000001000000 */ + 0x04, 0x00, /* 000001000000 */ + 0x04, 0x00, /* 000001000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 87 0x57 'W' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0xfe, 0xf0, /* 111111101111 */ + 0x66, 0x20, /* 011001100010 */ + 0x66, 0x20, /* 011001100010 */ + 0x66, 0x20, /* 011001100010 */ + 0x76, 0x20, /* 011101100010 */ + 0x77, 0x40, /* 011101110100 */ + 0x33, 0x40, /* 001100110100 */ + 0x37, 0x40, /* 001101110100 */ + 0x3b, 0xc0, /* 001110111100 */ + 0x3b, 0x80, /* 001110111000 */ + 0x19, 0x80, /* 000110011000 */ + 0x19, 0x80, /* 000110011000 */ + 0x19, 0x80, /* 000110011000 */ + 0x19, 0x80, /* 000110011000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 88 0x58 'X' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0xf0, 0x70, /* 111100000111 */ + 0x60, 0x20, /* 011000000010 */ + 0x30, 0x40, /* 001100000100 */ + 0x38, 0x80, /* 001110001000 */ + 0x18, 0x80, /* 000110001000 */ + 0x0d, 0x00, /* 000011010000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x0b, 0x00, /* 000010110000 */ + 0x11, 0x80, /* 000100011000 */ + 0x11, 0xc0, /* 000100011100 */ + 0x20, 0xc0, /* 001000001100 */ + 0x40, 0x60, /* 010000000110 */ + 0xe0, 0xf0, /* 111000001111 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 89 0x59 'Y' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0xf0, 0x70, /* 111100000111 */ + 0x60, 0x20, /* 011000000010 */ + 0x30, 0x40, /* 001100000100 */ + 0x18, 0x80, /* 000110001000 */ + 0x18, 0x80, /* 000110001000 */ + 0x0d, 0x00, /* 000011010000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x0f, 0x00, /* 000011110000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 90 0x5a 'Z' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xe0, /* 001111111110 */ + 0x20, 0xc0, /* 001000001100 */ + 0x00, 0xc0, /* 000000001100 */ + 0x01, 0x80, /* 000000011000 */ + 0x01, 0x80, /* 000000011000 */ + 0x03, 0x00, /* 000000110000 */ + 0x03, 0x00, /* 000000110000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x18, 0x00, /* 000110000000 */ + 0x18, 0x20, /* 000110000010 */ + 0x3f, 0xe0, /* 001111111110 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 91 0x5b '[' */ + 0x00, 0x00, /* 000000000000 */ + 0x0f, 0x80, /* 000011111000 */ + 0x0f, 0x80, /* 000011111000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0f, 0x80, /* 000011111000 */ + 0x0f, 0x80, /* 000011111000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 92 0x5c '\' */ + 0x00, 0x00, /* 000000000000 */ + 0x60, 0x00, /* 011000000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x18, 0x00, /* 000110000000 */ + 0x18, 0x00, /* 000110000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x03, 0x00, /* 000000110000 */ + 0x03, 0x00, /* 000000110000 */ + 0x01, 0x80, /* 000000011000 */ + 0x01, 0x80, /* 000000011000 */ + 0x00, 0xc0, /* 000000001100 */ + 0x00, 0xc0, /* 000000001100 */ + 0x00, 0x60, /* 000000000110 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 93 0x5d ']' */ + 0x00, 0x00, /* 000000000000 */ + 0x1f, 0x00, /* 000111110000 */ + 0x1f, 0x00, /* 000111110000 */ + 0x03, 0x00, /* 000000110000 */ + 0x03, 0x00, /* 000000110000 */ + 0x03, 0x00, /* 000000110000 */ + 0x03, 0x00, /* 000000110000 */ + 0x03, 0x00, /* 000000110000 */ + 0x03, 0x00, /* 000000110000 */ + 0x03, 0x00, /* 000000110000 */ + 0x03, 0x00, /* 000000110000 */ + 0x03, 0x00, /* 000000110000 */ + 0x03, 0x00, /* 000000110000 */ + 0x03, 0x00, /* 000000110000 */ + 0x1f, 0x00, /* 000111110000 */ + 0x1f, 0x00, /* 000111110000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 94 0x5e '^' */ + 0x00, 0x00, /* 000000000000 */ + 0x04, 0x00, /* 000001000000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x1b, 0x00, /* 000110110000 */ + 0x31, 0x80, /* 001100011000 */ + 0x60, 0xc0, /* 011000001100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 95 0x5f '_' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 96 0x60 '`' */ + 0x00, 0x00, /* 000000000000 */ + 0x01, 0x00, /* 000000010000 */ + 0x03, 0x00, /* 000000110000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x07, 0x80, /* 000001111000 */ + 0x07, 0x80, /* 000001111000 */ + 0x03, 0x00, /* 000000110000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 97 0x61 'a' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x0f, 0x80, /* 000011111000 */ + 0x18, 0xc0, /* 000110001100 */ + 0x10, 0xc0, /* 000100001100 */ + 0x03, 0xc0, /* 000000111100 */ + 0x1c, 0xc0, /* 000111001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x39, 0xc0, /* 001110011100 */ + 0x1e, 0xe0, /* 000111101110 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 98 0x62 'b' */ + 0x00, 0x00, /* 000000000000 */ + 0x20, 0x00, /* 001000000000 */ + 0x60, 0x00, /* 011000000000 */ + 0xe0, 0x00, /* 111000000000 */ + 0x60, 0x00, /* 011000000000 */ + 0x60, 0x00, /* 011000000000 */ + 0x67, 0x80, /* 011001111000 */ + 0x6f, 0xc0, /* 011011111100 */ + 0x70, 0xe0, /* 011100001110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x70, 0x60, /* 011100000110 */ + 0x78, 0xc0, /* 011110001100 */ + 0x4f, 0x80, /* 010011111000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 99 0x63 'c' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x1f, 0x80, /* 000111111000 */ + 0x31, 0xc0, /* 001100011100 */ + 0x20, 0xc0, /* 001000001100 */ + 0x60, 0x00, /* 011000000000 */ + 0x60, 0x00, /* 011000000000 */ + 0x60, 0x00, /* 011000000000 */ + 0x60, 0x00, /* 011000000000 */ + 0x70, 0x40, /* 011100000100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x1f, 0x80, /* 000111111000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 100 0x64 'd' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x60, /* 000000000110 */ + 0x00, 0xe0, /* 000000001110 */ + 0x00, 0x60, /* 000000000110 */ + 0x00, 0x60, /* 000000000110 */ + 0x00, 0x60, /* 000000000110 */ + 0x0f, 0x60, /* 000011110110 */ + 0x31, 0xe0, /* 001100011110 */ + 0x20, 0xe0, /* 001000001110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x70, 0xe0, /* 011100001110 */ + 0x39, 0x60, /* 001110010110 */ + 0x1e, 0x70, /* 000111100111 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 101 0x65 'e' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x0f, 0x00, /* 000011110000 */ + 0x30, 0xc0, /* 001100001100 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x60, 0x00, /* 011000000000 */ + 0x60, 0x00, /* 011000000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x18, 0x60, /* 000110000110 */ + 0x0f, 0x80, /* 000011111000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 102 0x66 'f' */ + 0x00, 0x00, /* 000000000000 */ + 0x03, 0x80, /* 000000111000 */ + 0x04, 0xc0, /* 000001001100 */ + 0x04, 0xc0, /* 000001001100 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x3f, 0x80, /* 001111111000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x1e, 0x00, /* 000111100000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 103 0x67 'g' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x1f, 0x20, /* 000111110010 */ + 0x31, 0xe0, /* 001100011110 */ + 0x60, 0xc0, /* 011000001100 */ + 0x60, 0xc0, /* 011000001100 */ + 0x60, 0xc0, /* 011000001100 */ + 0x31, 0x80, /* 001100011000 */ + 0x3f, 0x00, /* 001111110000 */ + 0x60, 0x00, /* 011000000000 */ + 0x7f, 0xc0, /* 011111111100 */ + 0x3f, 0xe0, /* 001111111110 */ + 0x20, 0x60, /* 001000000110 */ + 0x40, 0x20, /* 010000000010 */ + 0x40, 0x20, /* 010000000010 */ + 0x7f, 0xc0, /* 011111111100 */ + 0x3f, 0x80, /* 001111111000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 104 0x68 'h' */ + 0x00, 0x00, /* 000000000000 */ + 0x10, 0x00, /* 000100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x70, 0x00, /* 011100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x37, 0x80, /* 001101111000 */ + 0x39, 0xc0, /* 001110011100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x79, 0xe0, /* 011110011110 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 105 0x69 'i' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x1e, 0x00, /* 000111100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x1f, 0x80, /* 000111111000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 106 0x6a 'j' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0xc0, /* 000000001100 */ + 0x00, 0xc0, /* 000000001100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x03, 0xc0, /* 000000111100 */ + 0x00, 0xc0, /* 000000001100 */ + 0x00, 0xc0, /* 000000001100 */ + 0x00, 0xc0, /* 000000001100 */ + 0x00, 0xc0, /* 000000001100 */ + 0x00, 0xc0, /* 000000001100 */ + 0x00, 0xc0, /* 000000001100 */ + 0x00, 0xc0, /* 000000001100 */ + 0x00, 0xc0, /* 000000001100 */ + 0x00, 0xc0, /* 000000001100 */ + 0x20, 0xc0, /* 001000001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x38, 0x80, /* 001110001000 */ + 0x1f, 0x00, /* 000111110000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 107 0x6b 'k' */ + 0x00, 0x00, /* 000000000000 */ + 0x60, 0x00, /* 011000000000 */ + 0xe0, 0x00, /* 111000000000 */ + 0x60, 0x00, /* 011000000000 */ + 0x60, 0x00, /* 011000000000 */ + 0x60, 0x00, /* 011000000000 */ + 0x61, 0xc0, /* 011000011100 */ + 0x63, 0x00, /* 011000110000 */ + 0x66, 0x00, /* 011001100000 */ + 0x7c, 0x00, /* 011111000000 */ + 0x78, 0x00, /* 011110000000 */ + 0x7c, 0x00, /* 011111000000 */ + 0x6e, 0x00, /* 011011100000 */ + 0x67, 0x00, /* 011001110000 */ + 0x63, 0x80, /* 011000111000 */ + 0xf1, 0xe0, /* 111100011110 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 108 0x6c 'l' */ + 0x00, 0x00, /* 000000000000 */ + 0x1e, 0x00, /* 000111100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x1f, 0x80, /* 000111111000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 109 0x6d 'm' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0xdd, 0xc0, /* 110111011100 */ + 0x6e, 0xe0, /* 011011101110 */ + 0x66, 0x60, /* 011001100110 */ + 0x66, 0x60, /* 011001100110 */ + 0x66, 0x60, /* 011001100110 */ + 0x66, 0x60, /* 011001100110 */ + 0x66, 0x60, /* 011001100110 */ + 0x66, 0x60, /* 011001100110 */ + 0x66, 0x60, /* 011001100110 */ + 0xef, 0x70, /* 111011110111 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 110 0x6e 'n' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x27, 0x80, /* 001001111000 */ + 0x79, 0xc0, /* 011110011100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x79, 0xe0, /* 011110011110 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 111 0x6f 'o' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x0f, 0x80, /* 000011111000 */ + 0x11, 0xc0, /* 000100011100 */ + 0x20, 0xe0, /* 001000001110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x70, 0x40, /* 011100000100 */ + 0x38, 0x80, /* 001110001000 */ + 0x1f, 0x00, /* 000111110000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 112 0x70 'p' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0xef, 0x80, /* 111011111000 */ + 0x71, 0xc0, /* 011100011100 */ + 0x60, 0xe0, /* 011000001110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x40, /* 011000000100 */ + 0x70, 0x80, /* 011100001000 */ + 0x7f, 0x00, /* 011111110000 */ + 0x60, 0x00, /* 011000000000 */ + 0x60, 0x00, /* 011000000000 */ + 0x60, 0x00, /* 011000000000 */ + 0x60, 0x00, /* 011000000000 */ + 0xf0, 0x00, /* 111100000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 113 0x71 'q' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x0f, 0x20, /* 000011110010 */ + 0x11, 0xe0, /* 000100011110 */ + 0x20, 0xe0, /* 001000001110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x70, 0x60, /* 011100000110 */ + 0x38, 0xe0, /* 001110001110 */ + 0x1f, 0xe0, /* 000111111110 */ + 0x00, 0x60, /* 000000000110 */ + 0x00, 0x60, /* 000000000110 */ + 0x00, 0x60, /* 000000000110 */ + 0x00, 0x60, /* 000000000110 */ + 0x00, 0xf0, /* 000000001111 */ + 0x00, 0x00, /* 000000000000 */ + + /* 114 0x72 'r' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x73, 0x80, /* 011100111000 */ + 0x34, 0xc0, /* 001101001100 */ + 0x38, 0xc0, /* 001110001100 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x78, 0x00, /* 011110000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 115 0x73 's' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x1f, 0xc0, /* 000111111100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0x40, /* 001100000100 */ + 0x38, 0x00, /* 001110000000 */ + 0x1e, 0x00, /* 000111100000 */ + 0x07, 0x80, /* 000001111000 */ + 0x01, 0xc0, /* 000000011100 */ + 0x20, 0xc0, /* 001000001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x3f, 0x80, /* 001111111000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 116 0x74 't' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x04, 0x00, /* 000001000000 */ + 0x04, 0x00, /* 000001000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x7f, 0xc0, /* 011111111100 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x20, /* 000011000010 */ + 0x0e, 0x40, /* 000011100100 */ + 0x07, 0x80, /* 000001111000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 117 0x75 'u' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x79, 0xe0, /* 011110011110 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x39, 0xc0, /* 001110011100 */ + 0x1e, 0x60, /* 000111100110 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 118 0x76 'v' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0xf0, 0x70, /* 111100000111 */ + 0x60, 0x20, /* 011000000010 */ + 0x30, 0x40, /* 001100000100 */ + 0x30, 0x40, /* 001100000100 */ + 0x18, 0x80, /* 000110001000 */ + 0x18, 0x80, /* 000110001000 */ + 0x0d, 0x00, /* 000011010000 */ + 0x0d, 0x00, /* 000011010000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 119 0x77 'w' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0xff, 0x70, /* 111111110111 */ + 0x66, 0x20, /* 011001100010 */ + 0x66, 0x20, /* 011001100010 */ + 0x66, 0x20, /* 011001100010 */ + 0x37, 0x40, /* 001101110100 */ + 0x3b, 0x40, /* 001110110100 */ + 0x3b, 0x40, /* 001110110100 */ + 0x19, 0x80, /* 000110011000 */ + 0x19, 0x80, /* 000110011000 */ + 0x19, 0x80, /* 000110011000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 120 0x78 'x' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0xf8, 0xf0, /* 111110001111 */ + 0x70, 0x40, /* 011100000100 */ + 0x38, 0x80, /* 001110001000 */ + 0x1d, 0x00, /* 000111010000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x07, 0x00, /* 000001110000 */ + 0x0b, 0x80, /* 000010111000 */ + 0x11, 0xc0, /* 000100011100 */ + 0x20, 0xe0, /* 001000001110 */ + 0xf1, 0xf0, /* 111100011111 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 121 0x79 'y' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0xf0, 0xf0, /* 111100001111 */ + 0x60, 0x20, /* 011000000010 */ + 0x30, 0x40, /* 001100000100 */ + 0x30, 0x40, /* 001100000100 */ + 0x18, 0x80, /* 000110001000 */ + 0x18, 0x80, /* 000110001000 */ + 0x0d, 0x00, /* 000011010000 */ + 0x0d, 0x00, /* 000011010000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x04, 0x00, /* 000001000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x08, 0x00, /* 000010000000 */ + 0x78, 0x00, /* 011110000000 */ + 0x70, 0x00, /* 011100000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 122 0x7a 'z' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x60, 0xe0, /* 011000001110 */ + 0x41, 0xc0, /* 010000011100 */ + 0x03, 0x80, /* 000000111000 */ + 0x07, 0x00, /* 000001110000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x1c, 0x00, /* 000111000000 */ + 0x38, 0x20, /* 001110000010 */ + 0x70, 0x60, /* 011100000110 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 123 0x7b '{' */ + 0x00, 0x00, /* 000000000000 */ + 0x03, 0x80, /* 000000111000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x38, 0x00, /* 001110000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x03, 0x80, /* 000000111000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 124 0x7c '|' */ + 0x00, 0x00, /* 000000000000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 125 0x7d '}' */ + 0x00, 0x00, /* 000000000000 */ + 0x1c, 0x00, /* 000111000000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x03, 0x00, /* 000000110000 */ + 0x01, 0xc0, /* 000000011100 */ + 0x03, 0x00, /* 000000110000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x1c, 0x00, /* 000111000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 126 0x7e '~' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x1c, 0x20, /* 000111000010 */ + 0x3e, 0x60, /* 001111100110 */ + 0x67, 0xc0, /* 011001111100 */ + 0x43, 0x80, /* 010000111000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 127 0x7f '.' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 128 0x80 '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x0f, 0xc0, /* 000011111100 */ + 0x10, 0x60, /* 000100000110 */ + 0x20, 0x20, /* 001000000010 */ + 0x20, 0x00, /* 001000000000 */ + 0x60, 0x00, /* 011000000000 */ + 0x60, 0x00, /* 011000000000 */ + 0x60, 0x00, /* 011000000000 */ + 0x60, 0x00, /* 011000000000 */ + 0x60, 0x00, /* 011000000000 */ + 0x60, 0x00, /* 011000000000 */ + 0x20, 0x00, /* 001000000000 */ + 0x30, 0x20, /* 001100000010 */ + 0x18, 0x40, /* 000110000100 */ + 0x0f, 0x80, /* 000011111000 */ + 0x06, 0x00, /* 000001100000 */ + 0x03, 0x00, /* 000000110000 */ + 0x01, 0x80, /* 000000011000 */ + 0x0f, 0x00, /* 000011110000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 129 0x81 '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x19, 0x80, /* 000110011000 */ + 0x19, 0x80, /* 000110011000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x79, 0xe0, /* 011110011110 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x39, 0xc0, /* 001110011100 */ + 0x1e, 0x60, /* 000111100110 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 130 0x82 '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x01, 0x80, /* 000000011000 */ + 0x03, 0x00, /* 000000110000 */ + 0x06, 0x00, /* 000001100000 */ + 0x00, 0x00, /* 000000000000 */ + 0x0f, 0x00, /* 000011110000 */ + 0x30, 0xc0, /* 001100001100 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x60, 0x00, /* 011000000000 */ + 0x60, 0x00, /* 011000000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x18, 0x60, /* 000110000110 */ + 0x0f, 0x80, /* 000011111000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 131 0x83 '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x02, 0x00, /* 000000100000 */ + 0x07, 0x00, /* 000001110000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x18, 0xc0, /* 000110001100 */ + 0x00, 0x00, /* 000000000000 */ + 0x0f, 0x80, /* 000011111000 */ + 0x18, 0xc0, /* 000110001100 */ + 0x10, 0xc0, /* 000100001100 */ + 0x03, 0xc0, /* 000000111100 */ + 0x1c, 0xc0, /* 000111001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x39, 0xc0, /* 001110011100 */ + 0x1e, 0xe0, /* 000111101110 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 132 0x84 '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x19, 0x80, /* 000110011000 */ + 0x19, 0x80, /* 000110011000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x0f, 0x80, /* 000011111000 */ + 0x18, 0xc0, /* 000110001100 */ + 0x10, 0xc0, /* 000100001100 */ + 0x03, 0xc0, /* 000000111100 */ + 0x1c, 0xc0, /* 000111001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x39, 0xc0, /* 001110011100 */ + 0x1e, 0xe0, /* 000111101110 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 133 0x85 '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x06, 0x00, /* 000001100000 */ + 0x03, 0x00, /* 000000110000 */ + 0x00, 0x00, /* 000000000000 */ + 0x0f, 0x80, /* 000011111000 */ + 0x18, 0xc0, /* 000110001100 */ + 0x10, 0xc0, /* 000100001100 */ + 0x03, 0xc0, /* 000000111100 */ + 0x1c, 0xc0, /* 000111001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x39, 0xc0, /* 001110011100 */ + 0x1e, 0xe0, /* 000111101110 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 134 0x86 '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x07, 0x00, /* 000001110000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x07, 0x00, /* 000001110000 */ + 0x00, 0x00, /* 000000000000 */ + 0x0f, 0x80, /* 000011111000 */ + 0x18, 0xc0, /* 000110001100 */ + 0x10, 0xc0, /* 000100001100 */ + 0x03, 0xc0, /* 000000111100 */ + 0x1c, 0xc0, /* 000111001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x39, 0xc0, /* 001110011100 */ + 0x1e, 0xe0, /* 000111101110 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 135 0x87 '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x1f, 0x80, /* 000111111000 */ + 0x31, 0xc0, /* 001100011100 */ + 0x20, 0xc0, /* 001000001100 */ + 0x60, 0x00, /* 011000000000 */ + 0x60, 0x00, /* 011000000000 */ + 0x60, 0x00, /* 011000000000 */ + 0x60, 0x00, /* 011000000000 */ + 0x70, 0x40, /* 011100000100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x1f, 0x80, /* 000111111000 */ + 0x06, 0x00, /* 000001100000 */ + 0x03, 0x00, /* 000000110000 */ + 0x01, 0x80, /* 000000011000 */ + 0x0f, 0x00, /* 000011110000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 136 0x88 '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x02, 0x00, /* 000000100000 */ + 0x07, 0x00, /* 000001110000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x18, 0xc0, /* 000110001100 */ + 0x00, 0x00, /* 000000000000 */ + 0x0f, 0x00, /* 000011110000 */ + 0x30, 0xc0, /* 001100001100 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x60, 0x00, /* 011000000000 */ + 0x60, 0x00, /* 011000000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x18, 0x60, /* 000110000110 */ + 0x0f, 0x80, /* 000011111000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 137 0x89 '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x19, 0x80, /* 000110011000 */ + 0x19, 0x80, /* 000110011000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x0f, 0x00, /* 000011110000 */ + 0x30, 0xc0, /* 001100001100 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x60, 0x00, /* 011000000000 */ + 0x60, 0x00, /* 011000000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x18, 0x60, /* 000110000110 */ + 0x0f, 0x80, /* 000011111000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 138 0x8a '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x06, 0x00, /* 000001100000 */ + 0x03, 0x00, /* 000000110000 */ + 0x00, 0x00, /* 000000000000 */ + 0x0f, 0x00, /* 000011110000 */ + 0x30, 0xc0, /* 001100001100 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x60, 0x00, /* 011000000000 */ + 0x60, 0x00, /* 011000000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x18, 0x60, /* 000110000110 */ + 0x0f, 0x80, /* 000011111000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 139 0x8b '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x19, 0x80, /* 000110011000 */ + 0x19, 0x80, /* 000110011000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x1e, 0x00, /* 000111100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x1f, 0x80, /* 000111111000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 140 0x8c '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x04, 0x00, /* 000001000000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x1b, 0x00, /* 000110110000 */ + 0x31, 0x80, /* 001100011000 */ + 0x00, 0x00, /* 000000000000 */ + 0x1e, 0x00, /* 000111100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x1f, 0x80, /* 000111111000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 141 0x8d '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x18, 0x00, /* 000110000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x06, 0x00, /* 000001100000 */ + 0x00, 0x00, /* 000000000000 */ + 0x1e, 0x00, /* 000111100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x1f, 0x80, /* 000111111000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 142 0x8e '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x19, 0x80, /* 000110011000 */ + 0x19, 0x80, /* 000110011000 */ + 0x00, 0x00, /* 000000000000 */ + 0x04, 0x00, /* 000001000000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x0b, 0x00, /* 000010110000 */ + 0x0b, 0x00, /* 000010110000 */ + 0x19, 0x80, /* 000110011000 */ + 0x11, 0x80, /* 000100011000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x20, 0xc0, /* 001000001100 */ + 0x60, 0x60, /* 011000000110 */ + 0x40, 0x60, /* 010000000110 */ + 0xe0, 0xf0, /* 111000001111 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 143 0x8f '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x0f, 0x00, /* 000011110000 */ + 0x19, 0x80, /* 000110011000 */ + 0x0f, 0x00, /* 000011110000 */ + 0x04, 0x00, /* 000001000000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x0b, 0x00, /* 000010110000 */ + 0x0b, 0x00, /* 000010110000 */ + 0x19, 0x80, /* 000110011000 */ + 0x11, 0x80, /* 000100011000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x20, 0xc0, /* 001000001100 */ + 0x60, 0x60, /* 011000000110 */ + 0x40, 0x60, /* 010000000110 */ + 0xe0, 0xf0, /* 111000001111 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 144 0x90 '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x03, 0x00, /* 000000110000 */ + 0x06, 0x00, /* 000001100000 */ + 0x08, 0x00, /* 000010000000 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x30, 0x20, /* 001100000010 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x80, /* 001100001000 */ + 0x3f, 0x80, /* 001111111000 */ + 0x30, 0x80, /* 001100001000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x20, /* 001100000010 */ + 0x30, 0x20, /* 001100000010 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 145 0x91 '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3d, 0xe0, /* 001111011110 */ + 0x66, 0x30, /* 011001100011 */ + 0x46, 0x30, /* 010001100011 */ + 0x06, 0x30, /* 000001100011 */ + 0x3f, 0xf0, /* 001111111111 */ + 0x66, 0x00, /* 011001100000 */ + 0xc6, 0x00, /* 110001100000 */ + 0xc6, 0x00, /* 110001100000 */ + 0xe7, 0x30, /* 111001110011 */ + 0x7d, 0xe0, /* 011111011110 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 146 0x92 '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x03, 0xf0, /* 000000111111 */ + 0x07, 0x10, /* 000001110001 */ + 0x07, 0x10, /* 000001110001 */ + 0x0b, 0x00, /* 000010110000 */ + 0x0b, 0x00, /* 000010110000 */ + 0x0b, 0x20, /* 000010110010 */ + 0x13, 0xe0, /* 000100111110 */ + 0x13, 0x20, /* 000100110010 */ + 0x3f, 0x00, /* 001111110000 */ + 0x23, 0x00, /* 001000110000 */ + 0x23, 0x00, /* 001000110000 */ + 0x43, 0x10, /* 010000110001 */ + 0x43, 0x10, /* 010000110001 */ + 0xe7, 0xf0, /* 111001111111 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 147 0x93 '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x02, 0x00, /* 000000100000 */ + 0x07, 0x00, /* 000001110000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x18, 0xc0, /* 000110001100 */ + 0x00, 0x00, /* 000000000000 */ + 0x0f, 0x80, /* 000011111000 */ + 0x11, 0xc0, /* 000100011100 */ + 0x20, 0xe0, /* 001000001110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x70, 0x40, /* 011100000100 */ + 0x38, 0x80, /* 001110001000 */ + 0x1f, 0x00, /* 000111110000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 148 0x94 '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x19, 0x80, /* 000110011000 */ + 0x19, 0x80, /* 000110011000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x0f, 0x80, /* 000011111000 */ + 0x11, 0xc0, /* 000100011100 */ + 0x20, 0xe0, /* 001000001110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x70, 0x40, /* 011100000100 */ + 0x38, 0x80, /* 001110001000 */ + 0x1f, 0x00, /* 000111110000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 149 0x95 '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x06, 0x00, /* 000001100000 */ + 0x03, 0x00, /* 000000110000 */ + 0x00, 0x00, /* 000000000000 */ + 0x0f, 0x80, /* 000011111000 */ + 0x11, 0xc0, /* 000100011100 */ + 0x20, 0xe0, /* 001000001110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x70, 0x40, /* 011100000100 */ + 0x38, 0x80, /* 001110001000 */ + 0x1f, 0x00, /* 000111110000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 150 0x96 '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x02, 0x00, /* 000000100000 */ + 0x07, 0x00, /* 000001110000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x18, 0xc0, /* 000110001100 */ + 0x00, 0x00, /* 000000000000 */ + 0x79, 0xe0, /* 011110011110 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x39, 0xc0, /* 001110011100 */ + 0x1e, 0x60, /* 000111100110 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 151 0x97 '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x18, 0x00, /* 000110000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x06, 0x00, /* 000001100000 */ + 0x00, 0x00, /* 000000000000 */ + 0x79, 0xe0, /* 011110011110 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x39, 0xc0, /* 001110011100 */ + 0x1e, 0x60, /* 000111100110 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 152 0x98 '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x19, 0x80, /* 000110011000 */ + 0x19, 0x80, /* 000110011000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0xf0, 0xf0, /* 111100001111 */ + 0x60, 0x20, /* 011000000010 */ + 0x30, 0x40, /* 001100000100 */ + 0x30, 0x40, /* 001100000100 */ + 0x18, 0x80, /* 000110001000 */ + 0x18, 0x80, /* 000110001000 */ + 0x0d, 0x00, /* 000011010000 */ + 0x0d, 0x00, /* 000011010000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x04, 0x00, /* 000001000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x08, 0x00, /* 000010000000 */ + 0x78, 0x00, /* 011110000000 */ + 0x70, 0x00, /* 011100000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 153 0x99 '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x19, 0x80, /* 000110011000 */ + 0x19, 0x80, /* 000110011000 */ + 0x00, 0x00, /* 000000000000 */ + 0x0f, 0x80, /* 000011111000 */ + 0x11, 0xc0, /* 000100011100 */ + 0x20, 0xc0, /* 001000001100 */ + 0x20, 0x60, /* 001000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x20, 0x40, /* 001000000100 */ + 0x30, 0x40, /* 001100000100 */ + 0x18, 0x80, /* 000110001000 */ + 0x0f, 0x00, /* 000011110000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 154 0x9a '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x19, 0x80, /* 000110011000 */ + 0x19, 0x80, /* 000110011000 */ + 0xe0, 0x30, /* 111000000011 */ + 0x60, 0x20, /* 011000000010 */ + 0x60, 0x20, /* 011000000010 */ + 0x60, 0x20, /* 011000000010 */ + 0x60, 0x20, /* 011000000010 */ + 0x60, 0x20, /* 011000000010 */ + 0x60, 0x20, /* 011000000010 */ + 0x60, 0x20, /* 011000000010 */ + 0x60, 0x20, /* 011000000010 */ + 0x60, 0x20, /* 011000000010 */ + 0x70, 0x40, /* 011100000100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x1f, 0x80, /* 000111111000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 155 0x9b '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x1f, 0x80, /* 000111111000 */ + 0x36, 0xc0, /* 001101101100 */ + 0x26, 0xc0, /* 001001101100 */ + 0x66, 0x00, /* 011001100000 */ + 0x66, 0x00, /* 011001100000 */ + 0x66, 0x00, /* 011001100000 */ + 0x66, 0x00, /* 011001100000 */ + 0x76, 0x40, /* 011101100100 */ + 0x36, 0xc0, /* 001101101100 */ + 0x1f, 0x80, /* 000111111000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 156 0x9c '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x0f, 0x80, /* 000011111000 */ + 0x1c, 0xc0, /* 000111001100 */ + 0x18, 0xc0, /* 000110001100 */ + 0x18, 0x00, /* 000110000000 */ + 0x18, 0x00, /* 000110000000 */ + 0x18, 0x00, /* 000110000000 */ + 0x7e, 0x00, /* 011111100000 */ + 0x7e, 0x00, /* 011111100000 */ + 0x18, 0x00, /* 000110000000 */ + 0x18, 0x00, /* 000110000000 */ + 0x18, 0x00, /* 000110000000 */ + 0x18, 0x00, /* 000110000000 */ + 0x3e, 0x20, /* 001111100010 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x61, 0xc0, /* 011000011100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 157 0x9d '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x30, 0xc0, /* 001100001100 */ + 0x19, 0x80, /* 000110011000 */ + 0x19, 0x80, /* 000110011000 */ + 0x0f, 0x00, /* 000011110000 */ + 0x06, 0x00, /* 000001100000 */ + 0x1f, 0x80, /* 000111111000 */ + 0x06, 0x00, /* 000001100000 */ + 0x1f, 0x80, /* 000111111000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 158 0x9e '.' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 159 0x9f '.' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 160 0xa0 '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x01, 0x80, /* 000000011000 */ + 0x03, 0x00, /* 000000110000 */ + 0x06, 0x00, /* 000001100000 */ + 0x00, 0x00, /* 000000000000 */ + 0x0f, 0x80, /* 000011111000 */ + 0x18, 0xc0, /* 000110001100 */ + 0x10, 0xc0, /* 000100001100 */ + 0x03, 0xc0, /* 000000111100 */ + 0x1c, 0xc0, /* 000111001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x39, 0xc0, /* 001110011100 */ + 0x1e, 0xe0, /* 000111101110 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 161 0xa1 '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x01, 0x80, /* 000000011000 */ + 0x03, 0x00, /* 000000110000 */ + 0x06, 0x00, /* 000001100000 */ + 0x00, 0x00, /* 000000000000 */ + 0x1e, 0x00, /* 000111100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x1f, 0x80, /* 000111111000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 162 0xa2 '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x01, 0x80, /* 000000011000 */ + 0x03, 0x00, /* 000000110000 */ + 0x06, 0x00, /* 000001100000 */ + 0x00, 0x00, /* 000000000000 */ + 0x0f, 0x80, /* 000011111000 */ + 0x11, 0xc0, /* 000100011100 */ + 0x20, 0xe0, /* 001000001110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x70, 0x40, /* 011100000100 */ + 0x38, 0x80, /* 001110001000 */ + 0x1f, 0x00, /* 000111110000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 163 0xa3 '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x01, 0x80, /* 000000011000 */ + 0x03, 0x00, /* 000000110000 */ + 0x06, 0x00, /* 000001100000 */ + 0x00, 0x00, /* 000000000000 */ + 0x79, 0xe0, /* 011110011110 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x39, 0xc0, /* 001110011100 */ + 0x1e, 0x60, /* 000111100110 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 164 0xa4 '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x1c, 0x40, /* 000111000100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x23, 0x80, /* 001000111000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x27, 0x80, /* 001001111000 */ + 0x79, 0xc0, /* 011110011100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x79, 0xe0, /* 011110011110 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 165 0xa5 '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x1c, 0x40, /* 000111000100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x23, 0x80, /* 001000111000 */ + 0xc0, 0x70, /* 110000000111 */ + 0x60, 0x20, /* 011000000010 */ + 0x70, 0x20, /* 011100000010 */ + 0x78, 0x20, /* 011110000010 */ + 0x5c, 0x20, /* 010111000010 */ + 0x4e, 0x20, /* 010011100010 */ + 0x47, 0x20, /* 010001110010 */ + 0x43, 0xa0, /* 010000111010 */ + 0x41, 0xe0, /* 010000011110 */ + 0x40, 0xe0, /* 010000001110 */ + 0x40, 0x60, /* 010000000110 */ + 0xe0, 0x30, /* 111000000011 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 166 0xa6 '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x1f, 0x00, /* 000111110000 */ + 0x31, 0x80, /* 001100011000 */ + 0x01, 0x80, /* 000000011000 */ + 0x07, 0x80, /* 000001111000 */ + 0x19, 0x80, /* 000110011000 */ + 0x31, 0x80, /* 001100011000 */ + 0x31, 0x80, /* 001100011000 */ + 0x33, 0x80, /* 001100111000 */ + 0x1d, 0xc0, /* 000111011100 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 167 0xa7 '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x07, 0x00, /* 000001110000 */ + 0x19, 0x80, /* 000110011000 */ + 0x10, 0xc0, /* 000100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0x80, /* 001100001000 */ + 0x19, 0x80, /* 000110011000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 168 0xa8 '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x03, 0x00, /* 000000110000 */ + 0x03, 0x00, /* 000000110000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x03, 0x00, /* 000000110000 */ + 0x03, 0x00, /* 000000110000 */ + 0x06, 0x00, /* 000001100000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x18, 0x00, /* 000110000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x40, /* 001100000100 */ + 0x39, 0xc0, /* 001110011100 */ + 0x1f, 0x80, /* 000111111000 */ + 0x0f, 0x00, /* 000011110000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 169 0xa9 '.' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 170 0xaa '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0xc0, /* 000000001100 */ + 0x00, 0xc0, /* 000000001100 */ + 0x00, 0xc0, /* 000000001100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 171 0xab '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x10, 0x00, /* 000100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x10, 0x00, /* 000100000000 */ + 0x10, 0x40, /* 000100000100 */ + 0x10, 0x80, /* 000100001000 */ + 0x11, 0x00, /* 000100010000 */ + 0x3a, 0x00, /* 001110100000 */ + 0x05, 0xc0, /* 000001011100 */ + 0x0a, 0x20, /* 000010100010 */ + 0x10, 0x20, /* 000100000010 */ + 0x20, 0xc0, /* 001000001100 */ + 0x41, 0x00, /* 010000010000 */ + 0x02, 0x00, /* 000000100000 */ + 0x03, 0xe0, /* 000000111110 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 172 0xac '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x10, 0x00, /* 000100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x10, 0x00, /* 000100000000 */ + 0x10, 0x40, /* 000100000100 */ + 0x10, 0x80, /* 000100001000 */ + 0x11, 0x00, /* 000100010000 */ + 0x3a, 0x40, /* 001110100100 */ + 0x04, 0xc0, /* 000001001100 */ + 0x09, 0x40, /* 000010010100 */ + 0x12, 0x40, /* 000100100100 */ + 0x24, 0x40, /* 001001000100 */ + 0x47, 0xe0, /* 010001111110 */ + 0x00, 0x40, /* 000000000100 */ + 0x00, 0x40, /* 000000000100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 173 0xad '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 174 0xae '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x06, 0x60, /* 000001100110 */ + 0x0c, 0xc0, /* 000011001100 */ + 0x19, 0x80, /* 000110011000 */ + 0x33, 0x00, /* 001100110000 */ + 0x66, 0x00, /* 011001100000 */ + 0x33, 0x00, /* 001100110000 */ + 0x19, 0x80, /* 000110011000 */ + 0x0c, 0xc0, /* 000011001100 */ + 0x06, 0x60, /* 000001100110 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 175 0xaf '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x66, 0x00, /* 011001100000 */ + 0x33, 0x00, /* 001100110000 */ + 0x19, 0x80, /* 000110011000 */ + 0x0c, 0xc0, /* 000011001100 */ + 0x06, 0x60, /* 000001100110 */ + 0x0c, 0xc0, /* 000011001100 */ + 0x19, 0x80, /* 000110011000 */ + 0x33, 0x00, /* 001100110000 */ + 0x66, 0x00, /* 011001100000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 176 0xb0 '.' */ + 0x0c, 0x30, /* 000011000011 */ + 0x08, 0x20, /* 000010000010 */ + 0x61, 0x80, /* 011000011000 */ + 0x20, 0x80, /* 001000001000 */ + 0x0c, 0x30, /* 000011000011 */ + 0x08, 0x20, /* 000010000010 */ + 0x61, 0x80, /* 011000011000 */ + 0x20, 0x80, /* 001000001000 */ + 0x0c, 0x30, /* 000011000011 */ + 0x08, 0x20, /* 000010000010 */ + 0x61, 0x80, /* 011000011000 */ + 0x20, 0x80, /* 001000001000 */ + 0x0c, 0x30, /* 000011000011 */ + 0x08, 0x20, /* 000010000010 */ + 0x61, 0x80, /* 011000011000 */ + 0x20, 0x80, /* 001000001000 */ + 0x0c, 0x30, /* 000011000011 */ + 0x08, 0x20, /* 000010000010 */ + 0x61, 0x80, /* 011000011000 */ + 0x20, 0x80, /* 001000001000 */ + 0x0c, 0x30, /* 000011000011 */ + 0x08, 0x20, /* 000010000010 */ + + /* 177 0xb1 '.' */ + 0x77, 0x70, /* 011101110111 */ + 0x22, 0x20, /* 001000100010 */ + 0x88, 0x80, /* 100010001000 */ + 0xdd, 0xd0, /* 110111011101 */ + 0x88, 0x80, /* 100010001000 */ + 0x22, 0x20, /* 001000100010 */ + 0x77, 0x70, /* 011101110111 */ + 0x22, 0x20, /* 001000100010 */ + 0x88, 0x80, /* 100010001000 */ + 0xdd, 0xd0, /* 110111011101 */ + 0x88, 0x80, /* 100010001000 */ + 0x22, 0x20, /* 001000100010 */ + 0x77, 0x70, /* 011101110111 */ + 0x22, 0x20, /* 001000100010 */ + 0x88, 0x80, /* 100010001000 */ + 0xdd, 0xd0, /* 110111011101 */ + 0x88, 0x80, /* 100010001000 */ + 0x22, 0x20, /* 001000100010 */ + 0x77, 0x70, /* 011101110111 */ + 0x22, 0x20, /* 001000100010 */ + 0x88, 0x80, /* 100010001000 */ + 0xdd, 0xd0, /* 110111011101 */ + + /* 178 0xb2 '.' */ + 0xf3, 0xc0, /* 111100111100 */ + 0xf7, 0xd0, /* 111101111101 */ + 0x9e, 0x70, /* 100111100111 */ + 0xdf, 0x70, /* 110111110111 */ + 0xf3, 0xc0, /* 111100111100 */ + 0xf7, 0xd0, /* 111101111101 */ + 0x9e, 0x70, /* 100111100111 */ + 0xdf, 0x70, /* 110111110111 */ + 0xf3, 0xc0, /* 111100111100 */ + 0xf7, 0xd0, /* 111101111101 */ + 0x9e, 0x70, /* 100111100111 */ + 0xdf, 0x70, /* 110111110111 */ + 0xf3, 0xc0, /* 111100111100 */ + 0xf7, 0xd0, /* 111101111101 */ + 0x9e, 0x70, /* 100111100111 */ + 0xdf, 0x70, /* 110111110111 */ + 0xf3, 0xc0, /* 111100111100 */ + 0xf7, 0xd0, /* 111101111101 */ + 0x9e, 0x70, /* 100111100111 */ + 0xdf, 0x70, /* 110111110111 */ + 0xf3, 0xc0, /* 111100111100 */ + 0xf7, 0xd0, /* 111101111101 */ + + /* 179 0xb3 '.' */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + + /* 180 0xb4 '.' */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0xfe, 0x00, /* 111111100000 */ + 0xfe, 0x00, /* 111111100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + + /* 181 0xb5 '.' */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0xfe, 0x00, /* 111111100000 */ + 0xfe, 0x00, /* 111111100000 */ + 0x06, 0x00, /* 000001100000 */ + 0xfe, 0x00, /* 111111100000 */ + 0xfe, 0x00, /* 111111100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + + /* 182 0xb6 '.' */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0xfd, 0x80, /* 111111011000 */ + 0xfd, 0x80, /* 111111011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + + /* 183 0xb7 '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0xff, 0x80, /* 111111111000 */ + 0xff, 0x80, /* 111111111000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + + /* 184 0xb8 '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0xfe, 0x00, /* 111111100000 */ + 0xfe, 0x00, /* 111111100000 */ + 0x06, 0x00, /* 000001100000 */ + 0xfe, 0x00, /* 111111100000 */ + 0xfe, 0x00, /* 111111100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + + /* 185 0xb9 '.' */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0xfd, 0x80, /* 111111011000 */ + 0xfd, 0x80, /* 111111011000 */ + 0x01, 0x80, /* 000000011000 */ + 0xfd, 0x80, /* 111111011000 */ + 0xfd, 0x80, /* 111111011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + + /* 186 0xba '.' */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + + /* 187 0xbb '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0xff, 0x80, /* 111111111000 */ + 0xff, 0x80, /* 111111111000 */ + 0x01, 0x80, /* 000000011000 */ + 0xfd, 0x80, /* 111111011000 */ + 0xfd, 0x80, /* 111111011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + + /* 188 0xbc '.' */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0xfd, 0x80, /* 111111011000 */ + 0xfd, 0x80, /* 111111011000 */ + 0x01, 0x80, /* 000000011000 */ + 0xff, 0x80, /* 111111111000 */ + 0xff, 0x80, /* 111111111000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 189 0xbd '.' */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0xff, 0x80, /* 111111111000 */ + 0xff, 0x80, /* 111111111000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 190 0xbe '.' */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0xfe, 0x00, /* 111111100000 */ + 0xfe, 0x00, /* 111111100000 */ + 0x06, 0x00, /* 000001100000 */ + 0xfe, 0x00, /* 111111100000 */ + 0xfe, 0x00, /* 111111100000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 191 0xbf '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0xfe, 0x00, /* 111111100000 */ + 0xfe, 0x00, /* 111111100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + + /* 192 0xc0 '.' */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x07, 0xf0, /* 000001111111 */ + 0x07, 0xf0, /* 000001111111 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 193 0xc1 '.' */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 194 0xc2 '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + + /* 195 0xc3 '.' */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x07, 0xf0, /* 000001111111 */ + 0x07, 0xf0, /* 000001111111 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + + /* 196 0xc4 '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 197 0xc5 '.' */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + + /* 198 0xc6 '.' */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x07, 0xf0, /* 000001111111 */ + 0x07, 0xf0, /* 000001111111 */ + 0x06, 0x00, /* 000001100000 */ + 0x07, 0xf0, /* 000001111111 */ + 0x07, 0xf0, /* 000001111111 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + + /* 199 0xc7 '.' */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0xf0, /* 000011011111 */ + 0x0d, 0xf0, /* 000011011111 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + + /* 200 0xc8 '.' */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0xf0, /* 000011011111 */ + 0x0d, 0xf0, /* 000011011111 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0f, 0xf0, /* 000011111111 */ + 0x0f, 0xf0, /* 000011111111 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 201 0xc9 '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x0f, 0xf0, /* 000011111111 */ + 0x0f, 0xf0, /* 000011111111 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0d, 0xf0, /* 000011011111 */ + 0x0d, 0xf0, /* 000011011111 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + + /* 202 0xca '.' */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0xfd, 0xf0, /* 111111011111 */ + 0xfd, 0xf0, /* 111111011111 */ + 0x00, 0x00, /* 000000000000 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 203 0xcb '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0x00, 0x00, /* 000000000000 */ + 0xfd, 0xf0, /* 111111011111 */ + 0xfd, 0xf0, /* 111111011111 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + + /* 204 0xcc '.' */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0xf0, /* 000011011111 */ + 0x0d, 0xf0, /* 000011011111 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0d, 0xf0, /* 000011011111 */ + 0x0d, 0xf0, /* 000011011111 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + + /* 205 0xcd '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0x00, 0x00, /* 000000000000 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 206 0xce '.' */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0xfd, 0xf0, /* 111111011111 */ + 0xfd, 0xf0, /* 111111011111 */ + 0x00, 0x00, /* 000000000000 */ + 0xfd, 0xf0, /* 111111011111 */ + 0xfd, 0xf0, /* 111111011111 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + + /* 207 0xcf '.' */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0x00, 0x00, /* 000000000000 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 208 0xd0 '.' */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 209 0xd1 '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0x00, 0x00, /* 000000000000 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + + /* 210 0xd2 '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + + /* 211 0xd3 '.' */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0f, 0xf0, /* 000011111111 */ + 0x0f, 0xf0, /* 000011111111 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 212 0xd4 '.' */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x07, 0xf0, /* 000001111111 */ + 0x07, 0xf0, /* 000001111111 */ + 0x06, 0x00, /* 000001100000 */ + 0x07, 0xf0, /* 000001111111 */ + 0x07, 0xf0, /* 000001111111 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 213 0xd5 '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x07, 0xf0, /* 000001111111 */ + 0x07, 0xf0, /* 000001111111 */ + 0x06, 0x00, /* 000001100000 */ + 0x07, 0xf0, /* 000001111111 */ + 0x07, 0xf0, /* 000001111111 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + + /* 214 0xd6 '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x0f, 0xf0, /* 000011111111 */ + 0x0f, 0xf0, /* 000011111111 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + + /* 215 0xd7 '.' */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + 0x0d, 0x80, /* 000011011000 */ + + /* 216 0xd8 '.' */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0x06, 0x00, /* 000001100000 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + + /* 217 0xd9 '.' */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0xfe, 0x00, /* 111111100000 */ + 0xfe, 0x00, /* 111111100000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 218 0xda '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x07, 0xf0, /* 000001111111 */ + 0x07, 0xf0, /* 000001111111 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + + /* 219 0xdb '.' */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + + /* 220 0xdc '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + + /* 221 0xdd '.' */ + 0xfc, 0x00, /* 111111000000 */ + 0xfc, 0x00, /* 111111000000 */ + 0xfc, 0x00, /* 111111000000 */ + 0xfc, 0x00, /* 111111000000 */ + 0xfc, 0x00, /* 111111000000 */ + 0xfc, 0x00, /* 111111000000 */ + 0xfc, 0x00, /* 111111000000 */ + 0xfc, 0x00, /* 111111000000 */ + 0xfc, 0x00, /* 111111000000 */ + 0xfc, 0x00, /* 111111000000 */ + 0xfc, 0x00, /* 111111000000 */ + 0xfc, 0x00, /* 111111000000 */ + 0xfc, 0x00, /* 111111000000 */ + 0xfc, 0x00, /* 111111000000 */ + 0xfc, 0x00, /* 111111000000 */ + 0xfc, 0x00, /* 111111000000 */ + 0xfc, 0x00, /* 111111000000 */ + 0xfc, 0x00, /* 111111000000 */ + 0xfc, 0x00, /* 111111000000 */ + 0xfc, 0x00, /* 111111000000 */ + 0xfc, 0x00, /* 111111000000 */ + 0xfc, 0x00, /* 111111000000 */ + + /* 222 0xde '.' */ + 0x03, 0xf0, /* 000000111111 */ + 0x03, 0xf0, /* 000000111111 */ + 0x03, 0xf0, /* 000000111111 */ + 0x03, 0xf0, /* 000000111111 */ + 0x03, 0xf0, /* 000000111111 */ + 0x03, 0xf0, /* 000000111111 */ + 0x03, 0xf0, /* 000000111111 */ + 0x03, 0xf0, /* 000000111111 */ + 0x03, 0xf0, /* 000000111111 */ + 0x03, 0xf0, /* 000000111111 */ + 0x03, 0xf0, /* 000000111111 */ + 0x03, 0xf0, /* 000000111111 */ + 0x03, 0xf0, /* 000000111111 */ + 0x03, 0xf0, /* 000000111111 */ + 0x03, 0xf0, /* 000000111111 */ + 0x03, 0xf0, /* 000000111111 */ + 0x03, 0xf0, /* 000000111111 */ + 0x03, 0xf0, /* 000000111111 */ + 0x03, 0xf0, /* 000000111111 */ + 0x03, 0xf0, /* 000000111111 */ + 0x03, 0xf0, /* 000000111111 */ + 0x03, 0xf0, /* 000000111111 */ + + /* 223 0xdf '.' */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 224 0xe0 '.' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 225 0xe1 '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x0f, 0x00, /* 000011110000 */ + 0x19, 0x80, /* 000110011000 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x31, 0x80, /* 001100011000 */ + 0x37, 0x80, /* 001101111000 */ + 0x31, 0x80, /* 001100011000 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x31, 0x80, /* 001100011000 */ + 0x77, 0x00, /* 011101110000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 226 0xe2 '.' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 227 0xe3 '.' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 228 0xe4 '.' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 229 0xe5 '.' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 230 0xe6 '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x39, 0xc0, /* 001110011100 */ + 0x36, 0xe0, /* 001101101110 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x60, 0x00, /* 011000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 231 0xe7 '.' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 232 0xe8 '.' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 233 0xe9 '.' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 234 0xea '.' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 235 0xeb '.' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 236 0xec '.' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 237 0xed '.' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 238 0xee '.' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 239 0xef '.' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 240 0xf0 '.' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 241 0xf1 '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x00, 0x00, /* 000000000000 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 242 0xf2 '.' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 243 0xf3 '.' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 244 0xf4 '.' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 245 0xf5 '.' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 246 0xf6 '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 247 0xf7 '.' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 248 0xf8 '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x0f, 0x00, /* 000011110000 */ + 0x19, 0x80, /* 000110011000 */ + 0x19, 0x80, /* 000110011000 */ + 0x19, 0x80, /* 000110011000 */ + 0x0f, 0x00, /* 000011110000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 249 0xf9 '.' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 250 0xfa '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x06, 0x00, /* 000001100000 */ + 0x0f, 0x00, /* 000011110000 */ + 0x0f, 0x00, /* 000011110000 */ + 0x06, 0x00, /* 000001100000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 251 0xfb '.' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 252 0xfc '.' */ + /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 253 0xfd '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x0f, 0x00, /* 000011110000 */ + 0x1f, 0x80, /* 000111111000 */ + 0x31, 0x80, /* 001100011000 */ + 0x21, 0x80, /* 001000011000 */ + 0x03, 0x00, /* 000000110000 */ + 0x06, 0x00, /* 000001100000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x18, 0x40, /* 000110000100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 254 0xfe '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + + /* 255 0xff '.' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + +}; + +#undef FONTDATAMAX diff --git a/src/device/graphics/Font_sun_8x16.h b/src/device/graphics/Font_sun_8x16.h new file mode 100644 index 0000000..b556459 --- /dev/null +++ b/src/device/graphics/Font_sun_8x16.h @@ -0,0 +1,265 @@ +// vim: set et ts=4 sw=4: + +constexpr const unsigned int FONTDATAMAX_SUN8x16 = 4096; + +constexpr const unsigned char fontdata_sun_8x16[FONTDATAMAX_SUN8x16] = { + /* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x7e,0x81,0xa5,0x81,0x81,0xbd,0x99,0x81,0x81,0x7e,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x7e,0xff,0xdb,0xff,0xff,0xc3,0xe7,0xff,0xff,0x7e,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x00,0x6c,0xfe,0xfe,0xfe,0xfe,0x7c,0x38,0x10,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x00,0x10,0x38,0x7c,0xfe,0x7c,0x38,0x10,0x00,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x18,0x3c,0x3c,0xe7,0xe7,0xe7,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x18,0x3c,0x7e,0xff,0xff,0x7e,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x3c,0x3c,0x18,0x00,0x00,0x00,0x00,0x00,0x00, + /* */ 0xff,0xff,0xff,0xff,0xff,0xff,0xe7,0xc3,0xc3,0xe7,0xff,0xff,0xff,0xff,0xff,0xff, + /* */ 0x00,0x00,0x00,0x00,0x00,0x3c,0x66,0x42,0x42,0x66,0x3c,0x00,0x00,0x00,0x00,0x00, + /* */ 0xff,0xff,0xff,0xff,0xff,0xc3,0x99,0xbd,0xbd,0x99,0xc3,0xff,0xff,0xff,0xff,0xff, + /* */ 0x00,0x00,0x1e,0x0e,0x1a,0x32,0x78,0xcc,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x3c,0x66,0x66,0x66,0x66,0x3c,0x18,0x7e,0x18,0x18,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x3f,0x33,0x3f,0x30,0x30,0x30,0x30,0x70,0xf0,0xe0,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x7f,0x63,0x7f,0x63,0x63,0x63,0x63,0x67,0xe7,0xe6,0xc0,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x18,0x18,0xdb,0x3c,0xe7,0x3c,0xdb,0x18,0x18,0x00,0x00,0x00,0x00, + /* */ 0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfe,0xf8,0xf0,0xe0,0xc0,0x80,0x00,0x00,0x00,0x00, + /* */ 0x00,0x02,0x06,0x0e,0x1e,0x3e,0xfe,0x3e,0x1e,0x0e,0x06,0x02,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x18,0x3c,0x7e,0x18,0x18,0x18,0x7e,0x3c,0x18,0x00,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x66,0x66,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x7f,0xdb,0xdb,0xdb,0x7b,0x1b,0x1b,0x1b,0x1b,0x1b,0x00,0x00,0x00,0x00, + /* */ 0x00,0x7c,0xc6,0x60,0x38,0x6c,0xc6,0xc6,0x6c,0x38,0x0c,0xc6,0x7c,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xfe,0xfe,0xfe,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x18,0x3c,0x7e,0x18,0x18,0x18,0x7e,0x3c,0x18,0x7e,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x18,0x3c,0x7e,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7e,0x3c,0x18,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x00,0x00,0x18,0x0c,0xfe,0x0c,0x18,0x00,0x00,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x00,0x00,0x30,0x60,0xfe,0x60,0x30,0x00,0x00,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xc0,0xc0,0xfe,0x00,0x00,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x00,0x00,0x24,0x66,0xff,0x66,0x24,0x00,0x00,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x00,0x10,0x38,0x38,0x7c,0x7c,0xfe,0xfe,0x00,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x00,0xfe,0xfe,0x7c,0x7c,0x38,0x38,0x10,0x00,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /*!*/ 0x00,0x00,0x18,0x3c,0x3c,0x3c,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00, + /*"*/ 0x00,0x66,0x66,0x66,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /*#*/ 0x00,0x00,0x00,0x6c,0x6c,0xfe,0x6c,0x6c,0x6c,0xfe,0x6c,0x6c,0x00,0x00,0x00,0x00, + /*$*/ 0x18,0x18,0x7c,0xc6,0xc2,0xc0,0x7c,0x06,0x06,0x86,0xc6,0x7c,0x18,0x18,0x00,0x00, + /*%*/ 0x00,0x00,0x00,0x00,0xc2,0xc6,0x0c,0x18,0x30,0x60,0xc6,0x86,0x00,0x00,0x00,0x00, + /*&*/ 0x00,0x00,0x38,0x6c,0x6c,0x38,0x76,0xdc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, + /*'*/ 0x00,0x30,0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /*(*/ 0x00,0x00,0x0c,0x18,0x30,0x30,0x30,0x30,0x30,0x30,0x18,0x0c,0x00,0x00,0x00,0x00, + /*)*/ 0x00,0x00,0x30,0x18,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x18,0x30,0x00,0x00,0x00,0x00, + /***/ 0x00,0x00,0x00,0x00,0x00,0x66,0x3c,0xff,0x3c,0x66,0x00,0x00,0x00,0x00,0x00,0x00, + /*+*/ 0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x7e,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00, + /*,*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00,0x00, + /*-*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /*.*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x00,0x02,0x06,0x0c,0x18,0x30,0x60,0xc0,0x80,0x00,0x00,0x00,0x00, + /*0*/ 0x00,0x00,0x7c,0xc6,0xc6,0xce,0xde,0xf6,0xe6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, + /*1*/ 0x00,0x00,0x18,0x38,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x7e,0x00,0x00,0x00,0x00, + /*2*/ 0x00,0x00,0x7c,0xc6,0x06,0x0c,0x18,0x30,0x60,0xc0,0xc6,0xfe,0x00,0x00,0x00,0x00, + /*3*/ 0x00,0x00,0x7c,0xc6,0x06,0x06,0x3c,0x06,0x06,0x06,0xc6,0x7c,0x00,0x00,0x00,0x00, + /*4*/ 0x00,0x00,0x0c,0x1c,0x3c,0x6c,0xcc,0xfe,0x0c,0x0c,0x0c,0x1e,0x00,0x00,0x00,0x00, + /*5*/ 0x00,0x00,0xfe,0xc0,0xc0,0xc0,0xfc,0x06,0x06,0x06,0xc6,0x7c,0x00,0x00,0x00,0x00, + /*6*/ 0x00,0x00,0x38,0x60,0xc0,0xc0,0xfc,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, + /*7*/ 0x00,0x00,0xfe,0xc6,0x06,0x06,0x0c,0x18,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x00, + /*8*/ 0x00,0x00,0x7c,0xc6,0xc6,0xc6,0x7c,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, + /*9*/ 0x00,0x00,0x7c,0xc6,0xc6,0xc6,0x7e,0x06,0x06,0x06,0x0c,0x78,0x00,0x00,0x00,0x00, + /*:*/ 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00, + /*;*/ 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x00, + /*<*/ 0x00,0x00,0x00,0x06,0x0c,0x18,0x30,0x60,0x30,0x18,0x0c,0x06,0x00,0x00,0x00,0x00, + /*=*/ 0x00,0x00,0x00,0x00,0x00,0x7e,0x00,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /*>*/ 0x00,0x00,0x00,0x60,0x30,0x18,0x0c,0x06,0x0c,0x18,0x30,0x60,0x00,0x00,0x00,0x00, + /*?*/ 0x00,0x00,0x7c,0xc6,0xc6,0x0c,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00, + /*@*/ 0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xde,0xde,0xde,0xdc,0xc0,0x7c,0x00,0x00,0x00,0x00, + /*A*/ 0x00,0x00,0x10,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, + /*B*/ 0x00,0x00,0xfc,0x66,0x66,0x66,0x7c,0x66,0x66,0x66,0x66,0xfc,0x00,0x00,0x00,0x00, + /*C*/ 0x00,0x00,0x3c,0x66,0xc2,0xc0,0xc0,0xc0,0xc0,0xc2,0x66,0x3c,0x00,0x00,0x00,0x00, + /*D*/ 0x00,0x00,0xf8,0x6c,0x66,0x66,0x66,0x66,0x66,0x66,0x6c,0xf8,0x00,0x00,0x00,0x00, + /*E*/ 0x00,0x00,0xfe,0x66,0x62,0x68,0x78,0x68,0x60,0x62,0x66,0xfe,0x00,0x00,0x00,0x00, + /*F*/ 0x00,0x00,0xfe,0x66,0x62,0x68,0x78,0x68,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00, + /*G*/ 0x00,0x00,0x3c,0x66,0xc2,0xc0,0xc0,0xde,0xc6,0xc6,0x66,0x3a,0x00,0x00,0x00,0x00, + /*H*/ 0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, + /*I*/ 0x00,0x00,0x3c,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, + /*J*/ 0x00,0x00,0x1e,0x0c,0x0c,0x0c,0x0c,0x0c,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00,0x00, + /*K*/ 0x00,0x00,0xe6,0x66,0x66,0x6c,0x78,0x78,0x6c,0x66,0x66,0xe6,0x00,0x00,0x00,0x00, + /*L*/ 0x00,0x00,0xf0,0x60,0x60,0x60,0x60,0x60,0x60,0x62,0x66,0xfe,0x00,0x00,0x00,0x00, + /*M*/ 0x00,0x00,0xc3,0xe7,0xff,0xff,0xdb,0xc3,0xc3,0xc3,0xc3,0xc3,0x00,0x00,0x00,0x00, + /*N*/ 0x00,0x00,0xc6,0xe6,0xf6,0xfe,0xde,0xce,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, + /*O*/ 0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, + /*P*/ 0x00,0x00,0xfc,0x66,0x66,0x66,0x7c,0x60,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00, + /*Q*/ 0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xd6,0xde,0x7c,0x0c,0x0e,0x00,0x00, + /*R*/ 0x00,0x00,0xfc,0x66,0x66,0x66,0x7c,0x6c,0x66,0x66,0x66,0xe6,0x00,0x00,0x00,0x00, + /*S*/ 0x00,0x00,0x7c,0xc6,0xc6,0x60,0x38,0x0c,0x06,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, + /*T*/ 0x00,0x00,0xff,0xdb,0x99,0x18,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, + /*U*/ 0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, + /*V*/ 0x00,0x00,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0x66,0x3c,0x18,0x00,0x00,0x00,0x00, + /*W*/ 0x00,0x00,0xc3,0xc3,0xc3,0xc3,0xc3,0xdb,0xdb,0xff,0x66,0x66,0x00,0x00,0x00,0x00, + /*X*/ 0x00,0x00,0xc3,0xc3,0x66,0x3c,0x18,0x18,0x3c,0x66,0xc3,0xc3,0x00,0x00,0x00,0x00, + /*Y*/ 0x00,0x00,0xc3,0xc3,0xc3,0x66,0x3c,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, + /*Z*/ 0x00,0x00,0xff,0xc3,0x86,0x0c,0x18,0x30,0x60,0xc1,0xc3,0xff,0x00,0x00,0x00,0x00, + /*[*/ 0x00,0x00,0x3c,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3c,0x00,0x00,0x00,0x00, + /*\*/ 0x00,0x00,0x00,0x80,0xc0,0xe0,0x70,0x38,0x1c,0x0e,0x06,0x02,0x00,0x00,0x00,0x00, + /*]*/ 0x00,0x00,0x3c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x3c,0x00,0x00,0x00,0x00, + /*^*/ 0x10,0x38,0x6c,0xc6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /*_*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00,0x00, + /* */ 0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /*a*/ 0x00,0x00,0x00,0x00,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, + /*b*/ 0x00,0x00,0xe0,0x60,0x60,0x78,0x6c,0x66,0x66,0x66,0x66,0x7c,0x00,0x00,0x00,0x00, + /*c*/ 0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0xc0,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00, + /*d*/ 0x00,0x00,0x1c,0x0c,0x0c,0x3c,0x6c,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, + /*e*/ 0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00, + /*f*/ 0x00,0x00,0x38,0x6c,0x64,0x60,0xf0,0x60,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00, + /*g*/ 0x00,0x00,0x00,0x00,0x00,0x76,0xcc,0xcc,0xcc,0xcc,0xcc,0x7c,0x0c,0xcc,0x78,0x00, + /*h*/ 0x00,0x00,0xe0,0x60,0x60,0x6c,0x76,0x66,0x66,0x66,0x66,0xe6,0x00,0x00,0x00,0x00, + /*i*/ 0x00,0x00,0x18,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, + /*j*/ 0x00,0x00,0x06,0x06,0x00,0x0e,0x06,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3c,0x00, + /*k*/ 0x00,0x00,0xe0,0x60,0x60,0x66,0x6c,0x78,0x78,0x6c,0x66,0xe6,0x00,0x00,0x00,0x00, + /*l*/ 0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, + /*m*/ 0x00,0x00,0x00,0x00,0x00,0xe6,0xff,0xdb,0xdb,0xdb,0xdb,0xdb,0x00,0x00,0x00,0x00, + /*n*/ 0x00,0x00,0x00,0x00,0x00,0xdc,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00, + /*o*/ 0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, + /*p*/ 0x00,0x00,0x00,0x00,0x00,0xdc,0x66,0x66,0x66,0x66,0x66,0x7c,0x60,0x60,0xf0,0x00, + /*q*/ 0x00,0x00,0x00,0x00,0x00,0x76,0xcc,0xcc,0xcc,0xcc,0xcc,0x7c,0x0c,0x0c,0x1e,0x00, + /*r*/ 0x00,0x00,0x00,0x00,0x00,0xdc,0x76,0x66,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00, + /*s*/ 0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0x60,0x38,0x0c,0xc6,0x7c,0x00,0x00,0x00,0x00, + /*t*/ 0x00,0x00,0x10,0x30,0x30,0xfc,0x30,0x30,0x30,0x30,0x36,0x1c,0x00,0x00,0x00,0x00, + /*u*/ 0x00,0x00,0x00,0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, + /*v*/ 0x00,0x00,0x00,0x00,0x00,0xc3,0xc3,0xc3,0xc3,0x66,0x3c,0x18,0x00,0x00,0x00,0x00, + /*w*/ 0x00,0x00,0x00,0x00,0x00,0xc3,0xc3,0xc3,0xdb,0xdb,0xff,0x66,0x00,0x00,0x00,0x00, + /*x*/ 0x00,0x00,0x00,0x00,0x00,0xc3,0x66,0x3c,0x18,0x3c,0x66,0xc3,0x00,0x00,0x00,0x00, + /*y*/ 0x00,0x00,0x00,0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7e,0x06,0x0c,0xf8,0x00, + /*z*/ 0x00,0x00,0x00,0x00,0x00,0xfe,0xcc,0x18,0x30,0x60,0xc6,0xfe,0x00,0x00,0x00,0x00, + /*{*/ 0x00,0x00,0x0e,0x18,0x18,0x18,0x70,0x18,0x18,0x18,0x18,0x0e,0x00,0x00,0x00,0x00, + /*|*/ 0x00,0x00,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00, + /*}*/ 0x00,0x00,0x70,0x18,0x18,0x18,0x0e,0x18,0x18,0x18,0x18,0x70,0x00,0x00,0x00,0x00, + /*~*/ 0x00,0x00,0x76,0xdc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x00,0x10,0x38,0x6c,0xc6,0xc6,0xc6,0xfe,0x00,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x3c,0x66,0xc2,0xc0,0xc0,0xc0,0xc2,0x66,0x3c,0x0c,0x06,0x7c,0x00,0x00, + /* */ 0x00,0x00,0xcc,0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, + /* */ 0x00,0x0c,0x18,0x30,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00, + /* */ 0x00,0x10,0x38,0x6c,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0xcc,0x00,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, + /* */ 0x00,0x60,0x30,0x18,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, + /* */ 0x00,0x38,0x6c,0x38,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x00,0x3c,0x66,0x60,0x60,0x66,0x3c,0x0c,0x06,0x3c,0x00,0x00,0x00, + /* */ 0x00,0x10,0x38,0x6c,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0xc6,0x00,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00, + /* */ 0x00,0x60,0x30,0x18,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x66,0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, + /* */ 0x00,0x18,0x3c,0x66,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, + /* */ 0x00,0x60,0x30,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, + /* */ 0x00,0xc6,0x00,0x10,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, + /* */ 0x38,0x6c,0x38,0x00,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, + /* */ 0x18,0x30,0x60,0x00,0xfe,0x66,0x60,0x7c,0x60,0x60,0x66,0xfe,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x00,0x00,0x6e,0x3b,0x1b,0x7e,0xd8,0xdc,0x77,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x3e,0x6c,0xcc,0xcc,0xfe,0xcc,0xcc,0xcc,0xcc,0xce,0x00,0x00,0x00,0x00, + /* */ 0x00,0x10,0x38,0x6c,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0xc6,0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, + /* */ 0x00,0x60,0x30,0x18,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, + /* */ 0x00,0x30,0x78,0xcc,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, + /* */ 0x00,0x60,0x30,0x18,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0xc6,0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7e,0x06,0x0c,0x78,0x00, + /* */ 0x00,0xc6,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, + /* */ 0x00,0xc6,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, + /* */ 0x00,0x18,0x18,0x7e,0xc3,0xc0,0xc0,0xc0,0xc3,0x7e,0x18,0x18,0x00,0x00,0x00,0x00, + /* */ 0x00,0x38,0x6c,0x64,0x60,0xf0,0x60,0x60,0x60,0x60,0xe6,0xfc,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0xc3,0x66,0x3c,0x18,0xff,0x18,0xff,0x18,0x18,0x18,0x00,0x00,0x00,0x00, + /* */ 0x00,0xfc,0x66,0x66,0x7c,0x62,0x66,0x6f,0x66,0x66,0x66,0xf3,0x00,0x00,0x00,0x00, + /* */ 0x00,0x0e,0x1b,0x18,0x18,0x18,0x7e,0x18,0x18,0x18,0x18,0x18,0xd8,0x70,0x00,0x00, + /* */ 0x00,0x18,0x30,0x60,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, + /* */ 0x00,0x0c,0x18,0x30,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, + /* */ 0x00,0x18,0x30,0x60,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, + /* */ 0x00,0x18,0x30,0x60,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x76,0xdc,0x00,0xdc,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00, + /* */ 0x76,0xdc,0x00,0xc6,0xe6,0xf6,0xfe,0xde,0xce,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, + /* */ 0x00,0x3c,0x6c,0x6c,0x3e,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* */ 0x00,0x38,0x6c,0x6c,0x38,0x00,0x7c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x30,0x30,0x00,0x30,0x30,0x60,0xc0,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0x06,0x06,0x06,0x06,0x00,0x00,0x00,0x00,0x00, + /* */ 0x00,0xc0,0xc0,0xc2,0xc6,0xcc,0x18,0x30,0x60,0xce,0x9b,0x06,0x0c,0x1f,0x00,0x00, + /* */ 0x00,0xc0,0xc0,0xc2,0xc6,0xcc,0x18,0x30,0x66,0xce,0x96,0x3e,0x06,0x06,0x00,0x00, + /* */ 0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x18,0x3c,0x3c,0x3c,0x18,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x00,0x00,0x36,0x6c,0xd8,0x6c,0x36,0x00,0x00,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x00,0x00,0xd8,0x6c,0x36,0x6c,0xd8,0x00,0x00,0x00,0x00,0x00,0x00, + /* */ 0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44, + /* */ 0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa, + /* */ 0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77, + /* */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + /* */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + /* */ 0x18,0x18,0x18,0x18,0x18,0xf8,0x18,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + /* */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xf6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, + /* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, + /* */ 0x00,0x00,0x00,0x00,0x00,0xf8,0x18,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + /* */ 0x36,0x36,0x36,0x36,0x36,0xf6,0x06,0xf6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, + /* */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, + /* */ 0x00,0x00,0x00,0x00,0x00,0xfe,0x06,0xf6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, + /* */ 0x36,0x36,0x36,0x36,0x36,0xf6,0x06,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* */ 0x18,0x18,0x18,0x18,0x18,0xf8,0x18,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + /* */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + /* */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + /* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + /* */ 0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + /* */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, + /* */ 0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x00,0x00,0x3f,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, + /* */ 0x36,0x36,0x36,0x36,0x36,0xf7,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xf7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, + /* */ 0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, + /* */ 0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* */ 0x36,0x36,0x36,0x36,0x36,0xf7,0x00,0xf7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, + /* */ 0x18,0x18,0x18,0x18,0x18,0xff,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + /* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, + /* */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* */ 0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x00,0x00,0x1f,0x18,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + /* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, + /* */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xff,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, + /* */ 0x18,0x18,0x18,0x18,0x18,0xff,0x18,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + /* */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + /* */ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + /* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + /* */ 0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0, + /* */ 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f, + /* */ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x00,0x00,0x76,0xdc,0xd8,0xd8,0xd8,0xdc,0x76,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x78,0xcc,0xcc,0xcc,0xd8,0xcc,0xc6,0xc6,0xc6,0xcc,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0xfe,0xc6,0xc6,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x00,0xfe,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0xfe,0xc6,0x60,0x30,0x18,0x30,0x60,0xc6,0xfe,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x00,0x00,0x7e,0xd8,0xd8,0xd8,0xd8,0xd8,0x70,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x7c,0x60,0x60,0xc0,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x00,0x76,0xdc,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x7e,0x18,0x3c,0x66,0x66,0x66,0x3c,0x18,0x7e,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0x6c,0x38,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x38,0x6c,0xc6,0xc6,0xc6,0x6c,0x6c,0x6c,0x6c,0xee,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x1e,0x30,0x18,0x0c,0x3e,0x66,0x66,0x66,0x66,0x3c,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x00,0x00,0x7e,0xdb,0xdb,0xdb,0x7e,0x00,0x00,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x03,0x06,0x7e,0xdb,0xdb,0xf3,0x7e,0x60,0xc0,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x1c,0x30,0x60,0x60,0x7c,0x60,0x60,0x60,0x30,0x1c,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x00,0x18,0x18,0x7e,0x18,0x18,0x00,0x00,0xff,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x30,0x18,0x0c,0x06,0x0c,0x18,0x30,0x00,0x7e,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x0c,0x18,0x30,0x60,0x30,0x18,0x0c,0x00,0x7e,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x0e,0x1b,0x1b,0x1b,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + /* */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xd8,0xd8,0xd8,0x70,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x7e,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x00,0x00,0x76,0xdc,0x00,0x76,0xdc,0x00,0x00,0x00,0x00,0x00,0x00, + /* */ 0x00,0x38,0x6c,0x6c,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* */ 0x00,0x0f,0x0c,0x0c,0x0c,0x0c,0x0c,0xec,0x6c,0x6c,0x3c,0x1c,0x00,0x00,0x00,0x00, + /* */ 0x00,0xd8,0x6c,0x6c,0x6c,0x6c,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* */ 0x00,0x70,0xd8,0x30,0x60,0xc8,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x00,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x00,0x00,0x00,0x00,0x00, + /* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; + +#undef FONTDATAMAX + diff --git a/src/device/graphics/Fonts.cc b/src/device/graphics/Fonts.cc new file mode 100644 index 0000000..faf0dea --- /dev/null +++ b/src/device/graphics/Fonts.cc @@ -0,0 +1,19 @@ +// Jakob Falke, oostubs +// Github: https://gitlab.cs.fau.de/um15ebek/oostubs + +// vim: set et ts=4 sw=4: + +#include "Fonts.h" +#include "Font_8x16.h" +#include "Font_8x8.h" +#include "Font_acorn_8x8.h" +#include "Font_pearl_8x8.h" +#include "Font_sun_12x22.h" +#include "Font_sun_8x16.h" + +const Font_8x16 std_font_8x16; +const Font_8x8 std_font_8x8; +const Font_acorn_8x8 acorn_font_8x8; +const Font_pearl_8x8 pearl_font_8x8; +const Font_sun_12x22 sun_font_12x22; +const Font_sun_8x16 sun_font_8x16; diff --git a/src/device/graphics/Fonts.h b/src/device/graphics/Fonts.h new file mode 100644 index 0000000..f4d7010 --- /dev/null +++ b/src/device/graphics/Fonts.h @@ -0,0 +1,67 @@ +// Jakob Falke, oostubs +// Github: https://gitlab.cs.fau.de/um15ebek/oostubs + +// Schriften in Form von Rastergrafiken (separate Datein) +// Generiert mit cpi2fnt +// Keine Proportionalschriften +// Monochrome Speicherung: 1 Bit pro Pixel +// Je nach Breite wird auf Bytegrenzen aufgerundet: +// 8 Pixel -> 1 Byte; 12 Pixel -> 2 Byte + +#ifndef FONTS_H__ +#define FONTS_H__ + +#include "lib/util/Array.h" + +class Font { +public: + virtual ~Font() = default; + + virtual const unsigned char* getChar(int c) const = 0; + virtual unsigned int get_char_width() const = 0; + virtual unsigned int get_char_height() const = 0; +}; + +template +class FontInstance : public Font { + const unsigned int char_width; + const unsigned int char_height; + const unsigned int char_mem_size; + const unsigned char* font_data; + +public: + FontInstance() : char_width(width), char_height(height), char_mem_size((((char_width + (8 >> 1)) / 8) * char_height)), font_data(data) {} + + inline const unsigned char* getChar(int c) const override { + return &font_data[char_mem_size * c]; + } + inline unsigned int get_char_width() const override { + return char_width; + } + inline unsigned int get_char_height() const override { + return char_height; + } +}; + +extern const unsigned char fontdata_8x16[]; +extern const unsigned char fontdata_8x8[]; +extern const unsigned char acorndata_8x8[]; +extern const unsigned char fontdata_pearl_8x8[]; +extern const unsigned char fontdata_sun_12x22[]; +extern const unsigned char fontdata_sun_8x16[]; + +using Font_8x16 = FontInstance<8, 16, fontdata_8x16>; +using Font_8x8 = FontInstance<8, 8, fontdata_8x8>; +using Font_acorn_8x8 = FontInstance<8, 8, acorndata_8x8>; +using Font_pearl_8x8 = FontInstance<8, 8, fontdata_pearl_8x8>; +using Font_sun_12x22 = FontInstance<12, 22, fontdata_sun_12x22>; +using Font_sun_8x16 = FontInstance<8, 16, fontdata_sun_8x16>; + +extern const Font_8x16 std_font_8x16; +extern const Font_8x8 std_font_8x8; +extern const Font_acorn_8x8 acorn_font_8x8; +extern const Font_pearl_8x8 pearl_font_8x8; +extern const Font_sun_12x22 sun_font_12x22; +extern const Font_sun_8x16 sun_font_8x16; + +#endif diff --git a/src/device/graphics/LFBgraphics.cc b/src/device/graphics/LFBgraphics.cc new file mode 100644 index 0000000..111abaf --- /dev/null +++ b/src/device/graphics/LFBgraphics.cc @@ -0,0 +1,291 @@ +/***************************************************************************** + * * + * L F B G R A P H I C S * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Zeichenfunktionen fuer Grafikmodi, die auf einem * + * linearen Framebuffer basieren. Verwendet in VESA und * + * QemuVGA. * + * * + * Autor: Michael Schoettner, HHU, 19.9.2016 * + * Der Code fuer das Zeichnen der Linie ist von Alan Wolfe * + * https://blog.demofox.org/2015/01/17/bresenhams-drawing-algorithms * + *****************************************************************************/ + +#include "LFBgraphics.h" + +/* Hilfsfunktionen */ +void swap(unsigned int* a, unsigned int* b); +int abs(int a); + +/***************************************************************************** + * Methode: LFBgraphics::drawMonoBitmap * + *---------------------------------------------------------------------------* + * Parameter: x,y Startpunkt ab dem Text ausgegeben wird. * + * width Breite in Pixel * + * height Hoehe in Pixel * + * bitmap Zeiger auf Pixel der monochromen Rastergrafik * + * col Farbe der Pixel * + * * + * Beschreibung: Gibt die gegebene monochrome Rastergrafik an der Position* + * x,y zeilenweise aus. (x,y) ist der linke obere Punkt; * + * ist in der bitmap eine '1', so wird ein Pixel mit der * + * Farbe col ausgegeben, ansonsten bei '0' nichts. * + * Diese Funktion basiert auf dem Format der Fonts, welche * + * mit cpi2fnt (AmigaOS) erzeugt wurden. Das Format erklaert* + * sich in den C-Dateien in fonts/ von selbst. * + *****************************************************************************/ +inline void LFBgraphics::drawMonoBitmap(unsigned int x, unsigned int y, + unsigned int width, unsigned int height, + const unsigned char* bitmap, unsigned int color) const { + // Breite in Bytes + unsigned short width_byte = width / 8 + ((width % 8 != 0) ? 1 : 0); + + for (unsigned int yoff = 0; yoff < height; ++yoff) { + unsigned int xpos = x; + unsigned int ypos = y + yoff; + for (unsigned int xb = 0; xb < width_byte; ++xb) { + for (int src = 7; src >= 0; --src) { + if ((1 << src) & *bitmap) { + drawPixel(xpos, ypos, color); + } + xpos++; + } + bitmap++; + } + } +} + +/***************************************************************************** + * Methode: LFBgraphics::drawString * + *---------------------------------------------------------------------------* + * Parameter: fnt Schrift * + * x,y Startpunkt ab dem Text ausgegeben wird. * + * col Farbe des Textes * + * str Zeiger auf Zeichenkette * + * len Laenge der Zeichenkette * + * * + * Beschreibung: Gibt eine Zeichenkette mit gewaehlter Schrift an der * + * Position x,y aus. * + *****************************************************************************/ +void LFBgraphics::drawString(const Font& fnt, unsigned int x, unsigned int y, + unsigned int col, const char* str, unsigned int len) const { + for (unsigned int i = 0; i < len; ++i) { + drawMonoBitmap(x, y, fnt.get_char_width(), fnt.get_char_height(), fnt.getChar(*(str + i)), col); + x += fnt.get_char_width(); + } +} + +/***************************************************************************** + * Methode: LFBgraphics::drawPixel * + *---------------------------------------------------------------------------* + * Parameter: x, y Koordinaten des Pixels * + * col Farbe * + * * + * Beschreibung: Zeichnen eines Pixels. * + *****************************************************************************/ +void LFBgraphics::drawPixel(unsigned int x, unsigned int y, unsigned int col) const { + unsigned char* ptr = reinterpret_cast(lfb); + + if (hfb == 0 || lfb == 0) { + return; + } + + if (mode == BUFFER_INVISIBLE) { + ptr = reinterpret_cast(hfb); + } + + // Pixel ausserhalb des sichtbaren Bereichs? + if (x < 0 || x >= xres || y < 0 || y > yres) { + return; + } + + // Adresse des Pixels berechnen und Inhalt schreiben + switch (bpp) { + case 8: + ptr += (x + y * xres); + *ptr = col; + return; + case 15: + case 16: + ptr += (2 * x + 2 * y * xres); + *ptr = col; + return; + case 24: + ptr += (3 * x + 3 * y * xres); + *ptr = (col & 0xFF); + ptr++; + *ptr = ((col >> 8) & 0xFF); + ptr++; + *ptr = ((col >> 16) & 0xFF); + ptr; + return; + case 32: + ptr += (4 * x + 4 * y * xres); + *ptr = (col & 0xFF); + ptr++; + *ptr = ((col >> 8) & 0xFF); + ptr++; + *ptr = ((col >> 16) & 0xFF); + ptr; + return; + } +} + +void LFBgraphics::drawStraightLine(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, unsigned int col) const { + // Don't set mode inside the drawing function to use them in animations + + if (x1 == x2 && y2 > y1) { + // Vertical line + for (unsigned int i = y1; i <= y2; ++i) { + drawPixel(x1, i, col); + } + } else if (y1 == y2 && x2 > x1) { + // Horizontal line + for (unsigned int i = x1; i <= x2; ++i) { + drawPixel(i, y1, col); + } + } else { + // Not straight + } +} + +// (x1, y1)---(x2, y1) +// | | +// (x1, y2)---(x2, y2) +void LFBgraphics::drawRectangle(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, unsigned int col) const { + drawStraightLine(x1, y1, x2, y1, col); + drawStraightLine(x2, y1, x2, y2, col); + drawStraightLine(x1, y2, x2, y2, col); + drawStraightLine(x1, y1, x1, y2, col); +} + +void LFBgraphics::drawCircle(unsigned int x, unsigned int y, unsigned int rad, unsigned int col) const { + // TODO +} + +void LFBgraphics::drawSprite(unsigned int width, unsigned int height, unsigned int bytes_pp, const unsigned char* pixel_data) const { + const unsigned char* ptr; + for (unsigned int x = 0; x < width; ++x) { + for (unsigned int y = 0; y < height; ++y) { + ptr = pixel_data + (x + y * width) * bytes_pp; + + switch (bytes_pp) { + case 2: + // TODO: Never tested, probably doesn't work + drawPixel(x, y, RGB_24(*ptr & 0b11111000, ((*ptr & 0b111) << 3) | (*(ptr + 1) >> 5), + *(ptr + 1) & 0b11111)); // RGB 565 + break; + case 3: + case 4: + // Alpha gets ignored anyway + drawPixel(x, y, RGB_24(*ptr, *(ptr + 1), *(ptr + 2))); + break; + } + } + } +} + +/***************************************************************************** + * Methode: LFBgraphics::clear * + *---------------------------------------------------------------------------* + * Beschreibung: Bildschirm loeschen. * + *****************************************************************************/ +void LFBgraphics::clear() const { + unsigned int* ptr = reinterpret_cast(lfb); + unsigned int i; + + if (hfb == 0 || lfb == 0) { + return; + } + + if (mode == 0) { + ptr = reinterpret_cast(hfb); + } + + switch (bpp) { + case 8: + for (i = 0; i < ((xres / 4) * yres); i++) { + *(ptr++) = 0; + } + return; + case 15: + case 16: + for (i = 0; i < (2 * (xres / 4) * yres); i++) { + *(ptr++) = 0; + } + return; + case 24: + for (i = 0; i < (3 * (xres / 4) * yres); i++) { + *(ptr++) = 0; + } + return; + case 32: + for (i = 0; i < (4 * (xres / 4) * yres); i++) { + *(ptr++) = 0; + } + return; + } +} + +/***************************************************************************** + * Methode: LFBgraphics::setDrawingBuff * + *---------------------------------------------------------------------------* + * Beschreibung: Stellt ein, ob in den sichtbaren Puffer gezeichnet wird. * + *****************************************************************************/ +void LFBgraphics::setDrawingBuff(int v) { + mode = v; +} + +/***************************************************************************** + * Methode: LFBgraphics::copyHiddenToVisible * + *---------------------------------------------------------------------------* + * Beschreibung: Kopiert den versteckten Puffer in den sichtbaren LFB. * + *****************************************************************************/ +void LFBgraphics::copyHiddenToVisible() const { + unsigned int* sptr = reinterpret_cast(hfb); + unsigned int* dptr = reinterpret_cast(lfb); + unsigned int i; + + if (hfb == 0 || lfb == 0) { + return; + } + + switch (bpp) { + case 8: + for (i = 0; i < ((xres / 4) * yres); i++) { + *(dptr++) = *(sptr++); + } + return; + case 15: + case 16: + for (i = 0; i < (2 * (xres / 4) * yres); i++) { + *(dptr++) = *(sptr++); + } + return; + case 24: + for (i = 0; i < (3 * (xres / 4) * yres); i++) { + *(dptr++) = *(sptr++); + } + return; + case 32: + for (i = 0; i < (4 * (xres / 4) * yres); i++) { + *(dptr++) = *(sptr++); + } + return; + } +} + +void swap(unsigned int* a, unsigned int* b) { + unsigned int h = *a; + + *a = *b; + *b = h; +} + +int abs(int a) { + if (a < 0) { + return -a; + } + return a; +} diff --git a/src/device/graphics/LFBgraphics.h b/src/device/graphics/LFBgraphics.h new file mode 100644 index 0000000..771cf49 --- /dev/null +++ b/src/device/graphics/LFBgraphics.h @@ -0,0 +1,64 @@ +/***************************************************************************** + * * + * L F B G R A P H I C S * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Zeichenfunktionen fuer Grafikmodi, die auf einem * + * linearen Framebuffer basieren. Verwendet in VESA und * + * QemuVGA. * + * * + * Autor: Michael Schoettner, HHU, 19.9.2016 * + * Der Code fuer das Zeichnen der Linie ist von Alan Wolfe * + * https://blog.demofox.org/2015/01/17/bresenhams-drawing-algorithms * + *****************************************************************************/ + +#ifndef LFBgraphics_include__ +#define LFBgraphics_include__ + +#include "Fonts.h" + +// Hilfsfunktionen um Farbwerte fuer einen Pixel zu erzeugen +constexpr unsigned int RGB_24(unsigned int r, unsigned int g, unsigned int b) { + return ((r << 16) + (g << 8) + b); +} + +constexpr const bool BUFFER_INVISIBLE = false; +constexpr const bool BUFFER_VISIBLE = true; + +class LFBgraphics { +private: + // Hilfsfunktion fuer drawString + void drawMonoBitmap(unsigned int x, unsigned int y, + unsigned int width, unsigned int height, + const unsigned char* bitmap, unsigned int col) const; + +public: + LFBgraphics(const LFBgraphics& copy) = delete; // Verhindere Kopieren + + LFBgraphics() : mode(BUFFER_VISIBLE) {}; + + unsigned int xres, yres; // Aufloesung in Pixel + unsigned int bpp; // Farbtiefe (Bits per Pixel) + unsigned int lfb; // Adresse des Linearen Framebuffers + unsigned int hfb; // Adresse des versteckten Buffers (optional, fuer Animationen) + unsigned int mode; // Zeichnen im sichtbaren = 1 oder unsichtbaren = 0 Puffer + + void clear() const; + void drawPixel(unsigned int x, unsigned int y, unsigned int col) const; + + void drawString(const Font& fnt, unsigned int x, unsigned int y, unsigned int col, const char* str, unsigned int len) const; + + void drawCircle(unsigned int x, unsigned int y, unsigned int rad, unsigned int col) const; + void drawStraightLine(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, unsigned int col) const; + void drawRectangle(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, unsigned int col) const; + + void drawSprite(unsigned int width, unsigned int height, unsigned int bytes_pp, const unsigned char* pixel_data) const; + + // stellt ein, ob in den sichtbaren Puffer gezeichnet wird + void setDrawingBuff(int v); + + // kopiert 'hfb' nach 'lfb' + void copyHiddenToVisible() const; +}; + +#endif diff --git a/src/device/graphics/VESA.cc b/src/device/graphics/VESA.cc new file mode 100644 index 0000000..2efb84c --- /dev/null +++ b/src/device/graphics/VESA.cc @@ -0,0 +1,131 @@ +/***************************************************************************** + * * + * V E S A * + * * + *---------------------------------------------------------------------------* + * Beschreibung: VESA-Treiber ueber 16-Bit BIOS. * + * * + * Autor: Michael Schoettner, HHU, 18.3.2017 * + *****************************************************************************/ + +#include "VESA.h" +#include "device/bios/BIOS.h" + +// Informationen ueber einen VESA-Grafikmodus +// (siehe http://wiki.osdev.org/VESA_Video_Modes) +struct VbeModeInfoBlock { + unsigned short attributes; + unsigned char winA, winB; + unsigned short granularity; + unsigned short winsize; + unsigned short segmentA, segmentB; + unsigned short realFctPtr[2]; + unsigned short pitch; // Bytes pro Scanline + + unsigned short Xres, Yres; + unsigned char Wchar, Ychar, planes, bpp, banks; + unsigned char memory_model, bank_size, image_pages; + unsigned char reserved0; + + unsigned char red_mask, red_position; + unsigned char green_mask, green_position; + unsigned char blue_mask, blue_position; + unsigned char rsv_mask, rsv_position; + unsigned char directcolor_attributes; + + unsigned int physbase; // Adresse des Linear-Framebuffers + unsigned int OffScreenMemOffset; + unsigned short OffScreenMemSize; +} __attribute__((packed)); + +// Informationen ueber die Grafikkarte +// (siehe http://wiki.osdev.org/VESA_Video_Modes) +struct VbeInfoBlock { + char VbeSignature[4]; // == "VESA" + unsigned short VbeVersion; // == 0x0300 for VBE 3.0 + unsigned short OemStringPtr[2]; // isa vbeFarPtr + unsigned char Capabilities[4]; + unsigned short VideoModePtr[2]; // isa vbeFarPtr + unsigned short TotalMemory; // as # of 64KB blocks +} __attribute__((packed)); + +/***************************************************************************** + * Methode: VESA::initTextMode * + *---------------------------------------------------------------------------* + * Beschreibung: Schalter in den Text-Modus 80x25 Zeichen. * + *****************************************************************************/ +void VESA::initTextMode() { + BC_params->AX = 0x4f02; // SVFA BIOS, init mode + BC_params->BX = 0x4003; // 80x25 + BIOS::Int(0x10); +} + +/***************************************************************************** + * Methode: VESA::initGraphicMode * + *---------------------------------------------------------------------------* + * Parameter: Nummer des Grafikmodus (siehe VESA.h) * + * * + * Beschreibung: Bestimmten Grafikmodus einschalten. Dies wird durch * + * einen Aufruf des BIOS gemacht. * + *****************************************************************************/ +bool VESA::initGraphicMode(unsigned short mode) { + + // Alle Grafikmodi abfragen + BC_params->AX = 0x4F00; + BC_params->ES = RETURN_MEM >> 4; + BC_params->DI = RETURN_MEM & 0xF; + BIOS::Int(0x10); + + VbeInfoBlock* ib = reinterpret_cast(RETURN_MEM); + + // Signaturen pruefen + if (BC_params->AX != 0x004F) { + log.error() << "VESA wird nicht unterstuetzt." << endl; + return false; + } + if (ib->VbeSignature[0] != 'V' || ib->VbeSignature[1] != 'E' || + ib->VbeSignature[2] != 'S' || ib->VbeSignature[3] != 'A') { + log.error() << "VESA wird nicht unterstuetzt." << endl; + return false; + } + + // kout << "TotalVideoMemory: " << ((ib->TotalMemory*65536) / (1024*1024)) << " MB" << endl; + + // Gewuenschten Grafikmodus aus Antwort suchen + unsigned short* modePtr = reinterpret_cast((ib->VideoModePtr[1] << 4) + ib->VideoModePtr[0]); + for (int i = 0; modePtr[i] != 0xFFFF; ++i) { + // Gewuenschter Grafikmodus gefunden? + if (modePtr[i] == mode) { + VbeModeInfoBlock* minf = reinterpret_cast(RETURN_MEM); + + // Weitere Infos ueber diesen Grafikmodus abfragen + BC_params->AX = 0x4F01; + BC_params->CX = mode; + BC_params->ES = RETURN_MEM >> 4; + BC_params->DI = RETURN_MEM & 0xF; + BIOS::Int(0x10); + + // Text-Modi 0-3 haben keinen LFB + if (mode > 3 && (minf->attributes & 0x90) == 0) { + log.error() << "Grafikmodus bietet keinen linearen Framebuffer." << endl; + return false; + } + + mode_nr = mode; + xres = minf->Xres; + yres = minf->Yres; + bpp = static_cast(minf->bpp); + lfb = minf->physbase; + + hfb = reinterpret_cast(new char[xres * yres * bpp / 8]); + + // Grafikmodus einschalten + BC_params->AX = 0x4f02; // SVFA BIOS, init mode + BC_params->BX = mode; + BIOS::Int(0x10); + return true; + } + } + log.error() << "Grafikmodus nicht gefunden." << endl; + return false; +} diff --git a/src/device/graphics/VESA.h b/src/device/graphics/VESA.h new file mode 100644 index 0000000..43eb8f3 --- /dev/null +++ b/src/device/graphics/VESA.h @@ -0,0 +1,42 @@ +/***************************************************************************** + * * + * V E S A * + * * + *---------------------------------------------------------------------------* + * Beschreibung: VESA-Treiber ueber 16-Bit BIOS. * + * * + * Autor: Michael Schoettner, HHU, 19.5.2022 * + *****************************************************************************/ + +#ifndef VESA_include__ +#define VESA_include__ + +#include "LFBgraphics.h" +#include "kernel/log/Logger.h" + +// Ausgewaehlte Grafikmodi mit Mode-Nummer +constexpr const unsigned int MODE_640_480_16BITS = 0x111; +constexpr const unsigned int MODE_640_480_24BITS = 0x112; +constexpr const unsigned int MODE_800_600_16BITS = 0x114; +constexpr const unsigned int MODE_800_600_24BITS = 0x115; +constexpr const unsigned int MODE_1024_768_16BITS = 0x117; +constexpr const unsigned int MODE_1024_768_24BITS = 0x118; + +class VESA : public LFBgraphics { +private: + int mode_nr; // Nummer des Modus + NamedLogger log; + +public: + VESA(const VESA& copy) = delete; // Verhindere Kopieren + + VESA() : log("VESA") {} + + // Can't make singleton because atexit + + // Bestimmten Grafikmodus einschalten + bool initGraphicMode(unsigned short mode); + static void initTextMode(); +}; + +#endif diff --git a/src/device/hid/Key.h b/src/device/hid/Key.h new file mode 100755 index 0000000..40ac21e --- /dev/null +++ b/src/device/hid/Key.h @@ -0,0 +1,117 @@ +/***************************************************************************** + * * + * K E Y * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Taste, bestehend aus ASCII-, Scan-Code und Modifier-Bits.* + * * + * Autor: Olaf Spinczyk, TU Dortmund * + *****************************************************************************/ +#ifndef Key_include__ +#define Key_include__ + +class Key { + // Kopieren erlaubt! + + unsigned char asc; // ASCII code + unsigned char scan; // scan code + unsigned char modi; // modifier + + // Bit-Masken fuer die Modifier-Tasten + struct mbit { + enum { + shift = 1, + alt_left = 2, + alt_right = 4, + ctrl_left = 8, + ctrl_right = 16, + caps_lock = 32, + num_lock = 64, + scroll_lock = 128 + }; + }; + +public: + // DEFAULT-KONSTRUKTOR: setzt ASCII, Scancode und Modifier auf 0 + // und bezeichnet so einen ungueltigen Tastencode + Key() : asc(0), scan(0), modi(0) {} + + // VALID: mit Scancode = 0 werden ungueltige Tasten gekennzeichnet. + bool valid() const { return scan != 0; } + + // INVALIDATE: setzt den Scancode auf Null und sorgt somit fuer einen + // ungueltigen Tastencode. + void invalidate() { scan = 0; } + + // ASCII, SCANCODE: Setzen und Abfragen von Ascii und Scancode + void ascii(unsigned char a) { asc = a; } + void scancode(unsigned char s) { scan = s; } + unsigned char ascii() const { return asc; } + unsigned char scancode() const { return scan; } + + // + // Funktionen zum Setzen und Loeschen von SHIFT, ALT, CTRL usw. + // + void shift(bool pressed) { + modi = pressed ? modi | mbit::shift : modi & ~mbit::shift; + } + + void alt_left(bool pressed) { + modi = pressed ? modi | mbit::alt_left : modi & ~mbit::alt_left; + } + + void alt_right(bool pressed) { + modi = pressed ? modi | mbit::alt_right : modi & ~mbit::alt_right; + } + + void ctrl_left(bool pressed) { + modi = pressed ? modi | mbit::ctrl_left : modi & ~mbit::ctrl_left; + } + + void ctrl_right(bool pressed) { + modi = pressed ? modi | mbit::ctrl_right : modi & ~mbit::ctrl_right; + } + + void caps_lock(bool pressed) { + modi = pressed ? modi | mbit::caps_lock : modi & ~mbit::caps_lock; + } + + void num_lock(bool pressed) { + modi = pressed ? modi | mbit::num_lock : modi & ~mbit::num_lock; + } + + void scroll_lock(bool pressed) { + modi = pressed ? modi | mbit::scroll_lock : modi & ~mbit::scroll_lock; + } + + // + // Funktionen zum Abfragen von SHIFT, ALT, CTRL usw. + // + bool shift() const { return (modi & mbit::shift) != 0; } + bool alt_left() const { return (modi & mbit::alt_left) != 0; } + bool alt_right() const { return (modi & mbit::alt_right) != 0; } + bool ctrl_left() const { return (modi & mbit::ctrl_left) != 0; } + bool ctrl_right() const { return (modi & mbit::ctrl_right) != 0; } + bool caps_lock() const { return (modi & mbit::caps_lock) != 0; } + bool num_lock() const { return (modi & mbit::num_lock) != 0; } + bool scroll_lock() const { return (modi & mbit::scroll_lock) != 0; } + bool alt() const { return alt_left() || alt_right(); } + bool ctrl() const { return ctrl_left() || ctrl_right(); } + + operator char() const { return static_cast(asc); } + + // Scan-Codes einiger spezieller Tasten + struct scan { + enum { + f1 = 0x3b, + del = 0x53, + up = 72, + down = 80, + left = 75, + right = 77, + div = 8 + }; + }; +}; + +#endif diff --git a/src/device/hid/Keyboard.cc b/src/device/hid/Keyboard.cc new file mode 100755 index 0000000..eee74aa --- /dev/null +++ b/src/device/hid/Keyboard.cc @@ -0,0 +1,349 @@ +/***************************************************************************** + * * + * K E Y B O A R D * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Treiber für den Tastaturcontroller des PCs. * + * * + * Autor: Olaf Spinczyk, TU Dortmund * + *****************************************************************************/ + +#include "Keyboard.h" +#include "kernel/system/Globals.h" +#include "Key.h" + +const IOport Keyboard::ctrl_port(0x64); +const IOport Keyboard::data_port(0x60); + +/* Tabellen fuer ASCII-Codes (Klassenvariablen) intiialisieren */ + +constexpr const unsigned char Keyboard::normal_tab[] = { + 0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 225, 39, '\b', + 0, 'q', 'w', 'e', 'r', 't', 'z', 'u', 'i', 'o', 'p', 129, '+', '\n', + 0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 148, 132, '^', 0, '#', + 'y', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '-', 0, + '*', 0, ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '-', + 0, 0, 0, '+', 0, 0, 0, 0, 0, 0, 0, '<', 0, 0}; + +constexpr const unsigned char Keyboard::shift_tab[] = { + 0, 0, '!', '"', 21, '$', '%', '&', '/', '(', ')', '=', '?', 96, 0, + 0, 'Q', 'W', 'E', 'R', 'T', 'Z', 'U', 'I', 'O', 'P', 154, '*', 0, + 0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 153, 142, 248, 0, 39, + 'Y', 'X', 'C', 'V', 'B', 'N', 'M', ';', ':', '_', 0, + 0, 0, ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '>', 0, 0}; + +constexpr const unsigned char Keyboard::alt_tab[] = { + 0, 0, 0, 253, 0, 0, 0, 0, '{', '[', ']', '}', '\\', 0, 0, + 0, '@', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '~', 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 230, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '|', 0, 0}; + +constexpr const unsigned char Keyboard::asc_num_tab[] = { + '7', '8', '9', '-', '4', '5', '6', '+', '1', '2', '3', '0', ','}; + +constexpr const unsigned char Keyboard::scan_num_tab[] = { + 8, 9, 10, 53, 5, 6, 7, 27, 2, 3, 4, 11, 51}; + +/***************************************************************************** + * Methode: Keyboard::key_decoded * + *---------------------------------------------------------------------------* + * Beschreibung: Interpretiert die Make- und Break-Codes der Tastatur. * + * * + * Rueckgabewert: true bedeutet, dass das Zeichen komplett ist * + * false es fehlen noch Make- oder Break-Codes. * + *****************************************************************************/ +bool Keyboard::key_decoded() { + bool done = false; + + // Die Tasten, die bei der MF II Tastatur gegenueber der aelteren + // AT Tastatur hinzugekommen sind, senden immer erst eines von zwei + // moeglichen Prefix Bytes. + if (code == prefix1 || code == prefix2) { + prefix = code; + return false; + } + + // Das Loslassen einer Taste ist eigentlich nur bei den "Modifier" Tasten + // SHIFT, CTRL und ALT von Interesse, bei den anderen kann der Break-Code + // ignoriert werden. + if (code & break_bit) { + code &= ~break_bit; // Der Break-Code einer Taste ist gleich dem + // Make-Code mit gesetzten break_bit. + switch (code) { + case 42: + case 54: + gather.shift(false); + break; + case 56: + if (prefix == prefix1) { + gather.alt_right(false); + } else { + gather.alt_left(false); + } + break; + case 29: + if (prefix == prefix1) { + gather.ctrl_right(false); + } else { + gather.ctrl_left(false); + } + break; + } + + // Ein Prefix gilt immer nur fuer den unmittelbar nachfolgenden Code. + // Also ist es jetzt abgehandelt. + prefix = 0; + + // Mit einem Break-Code kann man nichts anfangen, also false liefern. + return false; + } + + // Eine Taste wurde gedrueckt. Bei den Modifier Tasten wie SHIFT, ALT, + // NUM_LOCK etc. wird nur der interne Zustand geaendert. Durch den + // Rueckgabewert 'false' wird angezeigt, dass die Tastatureingabe noch + // nicht abgeschlossen ist. Bei den anderen Tasten werden ASCII + // und Scancode eingetragen und ein 'true' fuer eine erfolgreiche + // Tastaturabfrage zurueckgegeben, obwohl genaugenommen noch der Break- + // code der Taste fehlt. + + switch (code) { + case 42: + case 54: + gather.shift(true); + break; + case 56: + if (prefix == prefix1) { + gather.alt_right(true); + } else { + gather.alt_left(true); + } + break; + case 29: + if (prefix == prefix1) { + gather.ctrl_right(true); + } else { + gather.ctrl_left(true); + } + break; + case 58: + gather.caps_lock(!gather.caps_lock()); + set_led(led::caps_lock, gather.caps_lock()); + break; + case 70: + gather.scroll_lock(!gather.scroll_lock()); + set_led(led::scroll_lock, gather.scroll_lock()); + break; + case 69: // Numlock oder Pause ? + if (gather.ctrl_left()) { // Pause Taste + // Auf alten Tastaturen konnte die Pause-Funktion wohl nur + // ueber Ctrl+NumLock erreicht werden. Moderne MF-II Tastaturen + // senden daher diese Codekombination, wenn Pause gemeint ist. + // Die Pause Taste liefert zwar normalerweise keinen ASCII- + // Code, aber Nachgucken schadet auch nicht. In jedem Fall ist + // die Taste nun komplett. + get_ascii_code(); + done = true; + } else { // NumLock + gather.num_lock(!gather.num_lock()); + set_led(led::num_lock, gather.num_lock()); + } + break; + + default: // alle anderen Tasten + // ASCII-Codes aus den entsprechenden Tabellen auslesen, fertig. + get_ascii_code(); + done = true; + } + + // Ein Prefix gilt immer nur fuer den unmittelbar nachfolgenden Code. + // Also ist es jetzt abgehandelt. + prefix = 0; + + return done; +} + +/***************************************************************************** + * Methode: Keyboard::get_ascii_code * + *---------------------------------------------------------------------------* + * Beschreibung: Ermittelt anhand von Tabellen aus dem Scancode und den * + * gesetzten Modifier-Bits den ASCII-Code der Taste. * + *****************************************************************************/ +void Keyboard::get_ascii_code() { + // Sonderfall Scancode 53: Dieser Code wird sowohl von der Minustaste + // des normalen Tastaturbereichs, als auch von der Divisionstaste des + // Ziffernblocks gesendet. Damit in beiden Faellen ein Code heraus- + // kommt, der der Aufschrift entspricht, muss im Falle des Ziffern- + // blocks eine Umsetzung auf den richtigen Code der Divisionstaste + // erfolgen. + if (code == 53 && prefix == prefix1) { // Divisionstaste des Ziffernblocks + gather.ascii('/'); + gather.scancode(Key::scan::div); + } + + // Anhand der Modifierbits muss die richtige Tabelle ausgewaehlt + // werden. Der Einfachheit halber hat NumLock Vorrang vor Alt, + // Shift und CapsLock. Fuer Ctrl gibt es keine eigene Tabelle + else if (gather.num_lock() && !prefix && code >= 71 && code <= 83) { + // Bei eingeschaltetem NumLock und der Betaetigung einer der + // Tasten des separaten Ziffernblocks (Codes 71-83), sollen + // nicht die Scancodes der Cursortasten, sondern ASCII- und + // Scancodes der ensprechenden Zifferntasten geliefert werden. + // Die Tasten des Cursorblocks (prefix == prefix1) sollen + // natuerlich weiterhin zur Cursorsteuerung genutzt werden + // koennen. Sie senden dann uebrigens noch ein Shift, aber das + // sollte nicht weiter stoeren. + gather.ascii(asc_num_tab[code - 71]); + gather.scancode(scan_num_tab[code - 71]); + } else if (gather.alt_right()) { + gather.ascii(alt_tab[code]); + gather.scancode(code); + } else if (gather.shift()) { + gather.ascii(shift_tab[code]); + gather.scancode(code); + } else if (gather.caps_lock()) { + // Die Umschaltung soll nur bei Buchstaben gelten + if ((code >= 16 && code <= 26) || (code >= 30 && code <= 40) || (code >= 44 && code <= 50)) { + gather.ascii(shift_tab[code]); + gather.scancode(code); + } else { + gather.ascii(normal_tab[code]); + gather.scancode(code); + } + } else { + gather.ascii(normal_tab[code]); + gather.scancode(code); + } +} + +/***************************************************************************** + * Konstruktor: Keyboard::Keyboard * + *---------------------------------------------------------------------------* + * Beschreibung: Initialisierung der Tastatur: alle LEDs werden ausge- * + * schaltet und die Wiederholungsrate auf maximale * + * Geschwindigkeit eingestellt. * + *****************************************************************************/ +Keyboard::Keyboard() { + // alle LEDs ausschalten (bei vielen PCs ist NumLock nach dem Booten an) + set_led(led::caps_lock, false); + set_led(led::scroll_lock, false); + set_led(led::num_lock, false); + + // maximale Geschwindigkeit, minimale Verzoegerung + set_repeat_rate(0, 0); +} + +/***************************************************************************** + * Methode: Keyboard::key_hit * + *---------------------------------------------------------------------------* + * Beschreibung: Diese Methode soll einen Tastendruck zurueckliefern. * + * Hierzu soll die Tastatur in einer Schleife "gepollt" * + * werden, bis ein Zeichen eingegebn wurde. * + * * + * Das Byte von der Tastatur soll in dem Attribut 'code' * + * (siehe Keyboard.h) gespeichert werden. Die Dekodierung * + * soll mithilfe der vorgegebenen Funktion 'key_decoded' * + * erfolgen. * + * * + * Rückgabewert: Wenn der Tastendruck abgeschlossen ist und ein Scancode, * + * sowie gegebenenfalls ein ASCII-Code emittelt werden * + * konnte, werden diese in 'gather' (siehe Keyboard.h) * + * zurueckgeliefert. Anderenfalls liefert key_hit () einen * + * ungueltigen Wert zurueck, was mit Key::valid () * + * ueberprueft werden kann. * + *****************************************************************************/ +Key Keyboard::key_hit() { + Key invalid; // nicht explizit initialisierte Tasten sind ungueltig + + /* Hier muss Code eingefuegt werden. */ + + bool outbyte; + do { + outbyte = ctrl_port.inb() & outb; + } while (!outbyte); + + // Ignore PS2 Mouse + bool auxbyte = ctrl_port.inb() & auxb; + if (auxbyte) { + return invalid; + } + + code = data_port.inb(); + if (key_decoded()) { + return gather; + } + + return invalid; +} + +/***************************************************************************** + * Methode: Keyboard::reboot * + *---------------------------------------------------------------------------* + * Beschreibung: Fuehrt einen Neustart des Rechners durch. * + *****************************************************************************/ +void Keyboard::reboot() { + int status; + + // Dem BIOS mitteilen, dass das Reset beabsichtigt war + // und kein Speichertest durchgefuehrt werden muss. + *reinterpret_cast(0x472) = 0x1234; + + // Der Tastaturcontroller soll das Reset ausloesen. + do { + status = ctrl_port.inb(); // warten, bis das letzte Kommando + } while ((status & inpb) != 0); // verarbeitet wurde. + ctrl_port.outb(cpu_reset); // Reset +} + +/***************************************************************************** + * Methode: Keyboard::set_repeat_rate * + *---------------------------------------------------------------------------* + * Beschreibung: Einstellen der Wiederholungsrate der Tastatur. * + * * + * Parameter: * + * delay: Bestimmt, wie lange eine Taste gedrueckt werden muss, * + * bevor die Wiederholung einsetzt. Erlaubt sind Werte * + * zw. 0 (minimale Wartezeit) und 3 (maximale Wartezeit). * + * speed: Bestimmt, wie schnell die Tastencodes aufeinander folgen * + * sollen. Erlaubt sind Werte zwischen 0 (sehr schnell) * + * und 31 (sehr langsam). * + *****************************************************************************/ +void Keyboard::set_repeat_rate(int speed, int delay) { + + /* Hier muss Code eingefuegt werden. */ +} + +/***************************************************************************** + * Methode: Keyboard::set_led * + *---------------------------------------------------------------------------* + * Beschreibung: Setzt oder loescht die angegebene Leuchtdiode. * + * * + * Parameter: * + * led: Welche LED? (caps_lock, num_lock, scroll_lock) * + * on: 0 = aus, 1 = an * + *****************************************************************************/ +void Keyboard::set_led(char led, bool on) { + + /* Hier muss Code eingefuegt werden. */ +} + +// Registriert die Tastatur ISR im IntDispatcher +// und erlaubt den keyboard interrupt im PIC +void Keyboard::plugin() { + intdis.assign(IntDispatcher::keyboard, *this); + PIC::allow(PIC::keyboard); +} + +void Keyboard::trigger() { + Key key = key_hit(); + // lastkey = key.ascii(); + + // NOTE: My keyboard has no delete key... + if (key.ctrl_left() && key.alt_left() && static_cast(key) == 'r') { + reboot(); + } else if (key != 0) { + kevman.broadcast(key); // Send key to all subscribed threads + } +} diff --git a/src/device/hid/Keyboard.h b/src/device/hid/Keyboard.h new file mode 100755 index 0000000..b16cc3d --- /dev/null +++ b/src/device/hid/Keyboard.h @@ -0,0 +1,100 @@ +/***************************************************************************** + * * + * K E Y B O A R D * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Treiber für den Tastaturcontroller des PCs. * + * * + * Autor: Olaf Spinczyk, TU Dortmund * + * Modifikationen, Michael Schoettner, 2.6.2022 * + *****************************************************************************/ +#ifndef Keyboard_include__ +#define Keyboard_include__ + +#include "Key.h" +#include "kernel/interrupt/ISR.h" +#include "device/port/IOport.h" + +class Keyboard : public ISR { +private: + unsigned char code; // Byte von Tastatur + unsigned char prefix; // Prefix von Tastatur + Key gather; // letzter dekodierter Key + char leds; // Zustand LEDs + + // Benutzte Ports des Tastaturcontrollers + static const IOport ctrl_port; // Status- (R) u. Steuerregister (W) + static const IOport data_port; // Ausgabe- (R) u. Eingabepuffer (W) + + // Bits im Statusregister + enum { outb = 0x01, + inpb = 0x02, + auxb = 0x20 }; + + // Kommandos an die Tastatur + struct kbd_cmd { + enum { set_led = 0xed, + set_speed = 0xf3 }; + }; + enum { cpu_reset = 0xfe }; + + // Namen der LEDs + struct led { + enum { caps_lock = 4, + num_lock = 2, + scroll_lock = 1 }; + }; + + // Antworten der Tastatur + struct kbd_reply { + enum { ack = 0xfa }; + }; + + // Konstanten fuer die Tastaturdekodierung + enum { break_bit = 0x80, + prefix1 = 0xe0, + prefix2 = 0xe1 }; + + // Klassenvariablen + static const unsigned char normal_tab[]; + static const unsigned char shift_tab[]; + static const unsigned char alt_tab[]; + static const unsigned char asc_num_tab[]; + static const unsigned char scan_num_tab[]; + + // Interpretiert die Make und Break-Codes der Tastatur. + bool key_decoded(); + + // Ermittelt anhand von Tabellen den ASCII-Code. + void get_ascii_code(); + + // Tastaturabfrage (vorerst Polling) + Key key_hit(); + +public: + Keyboard(const Keyboard& copy) = delete; // Verhindere Kopieren + + // Initialisierung der Tastatur. + Keyboard(); + +// ~Keyboard() override = default; + + // unsigned int lastkey; // speichert den ASCII-Code der zuletzt gedrückten Taste + + // Fuehrt einen Neustart des Rechners durch. + static void reboot(); + + // Einstellen der Wiederholungsrate der Tastatur. + void set_repeat_rate(int speed, int delay); + + // Setzt oder loescht die angegebene Leuchtdiode. + void set_led(char led, bool on); + + // Aktivierung der Unterbrechungen fuer die Tastatur + void plugin(); + + // Unterbrechnungsroutine der Tastatur. + void trigger() override; +}; + +#endif diff --git a/src/device/interrupt/PIC.cc b/src/device/interrupt/PIC.cc new file mode 100755 index 0000000..0ff1e20 --- /dev/null +++ b/src/device/interrupt/PIC.cc @@ -0,0 +1,105 @@ +/***************************************************************************** + * * + * P I C * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Mit Hilfe des PICs koennen Hardware-Interrupts (IRQs) * + * einzeln zugelassen oder unterdrueckt werden. Auf diese * + * Weise wird also bestimmt, ob die Unterbrechung eines * + * Geraetes ueberhaupt an den Prozessor weitergegeben wird. * + * Selbst dann erfolgt eine Aktivierung der Unterbrechungs- * + * routine nur, wenn der Prozessor bereit ist, auf Unter- * + * brechungen zu reagieren. Dies kann mit Hilfe der Klasse * + * CPU festgelegt werden. * + * * + * Autor: Olaf Spinczyk, TU Dortmund * + *****************************************************************************/ + +#include "PIC.h" + +IOport const PIC::IMR1(0x21); // interrupt mask register von PIC 1 +IOport const PIC::IMR2(0xa1); // interrupt mask register von PIC 2 + +/***************************************************************************** + * Methode: PIC::allow * + *---------------------------------------------------------------------------* + * Beschreibung: Sorgt dafuer, dass der uebergebene IRQ ab sofort durch * + * den PIC an den Prozessor weitergereicht wird. Um eine * + * Unterbrechungsbehandlung zu ermoeglichen, muss * + * zusaetzlich CPU::enable_int() aufgerufen werden. * + * * + * Parameter: * + * irq: IRQ der erlaubt werden soll * + *****************************************************************************/ +void PIC::allow(int irq) { + + /* hier muss Code eingefuegt werden */ + + // NOTE: allow sets the bit to 0 + + unsigned char IMR; + unsigned char mask = ~(0x1 << (irq % 8)); + if (irq < 8) { + // PIC 1 + IMR = IMR1.inb(); // We don't want to change the other interrupt masks so use this as start value + IMR1.outb(IMR & mask); + } else { + // PIC 2 + IMR = IMR2.inb(); + IMR2.outb(IMR & mask); + } +} + +/***************************************************************************** + * Methode: PIC::forbid * + *---------------------------------------------------------------------------* + * Beschreibung: Unterdrueckt mit Hilfe des PICs einen bestimmten IRQ. * + * * + * Parameter: * + * interrupt: IRQ der maskiert werden soll * + *****************************************************************************/ +void PIC::forbid(int irq) { + + /* hier muss Code eingefuegt werden */ + + // NOTE: forbid sets the bit to 1 + + unsigned char IMR; + unsigned char mask = 0x1 << (irq % 8); + if (irq < 8) { + // PIC 1 + IMR = IMR1.inb(); // We don't want to change the other interrupt masks so use this as start value + IMR1.outb(IMR | mask); + } else { + // PIC 2 + IMR = IMR2.inb(); + IMR2.outb(IMR | mask); + } +} + +/***************************************************************************** + * Methode: PIC::status * + *---------------------------------------------------------------------------* + * Beschreibung: Liefert den aktuellen Zustand des Maskierbits eines * + * bestimmten IRQs. * + * * + * Parameter: * + * irq: IRQ dessen Status erfragt werden soll * + *****************************************************************************/ +bool PIC::status(int irq) { + + /* hier muss Code eingefuegt werden */ + + unsigned char IMR; + if (irq < 8) { + // PIC 1 + IMR = IMR1.inb(); + } else { + // PIC 2 + IMR = IMR2.inb(); + } + + // Use % 8 to account for two PICs + unsigned char mask = 0x1 << (irq % 8); + return IMR & mask; +} diff --git a/src/device/interrupt/PIC.h b/src/device/interrupt/PIC.h new file mode 100755 index 0000000..0219cb6 --- /dev/null +++ b/src/device/interrupt/PIC.h @@ -0,0 +1,51 @@ +/***************************************************************************** + * * + * P I C * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Mit Hilfe des PICs koennen Hardware-Interrupts (IRQs) * + * einzeln zugelassen oder unterdrueckt werden. Auf diese * + * Weise wird also bestimmt, ob die Unterbrechung eines * + * Geraetes ueberhaupt an den Prozessor weitergegeben wird. * + * Selbst dann erfolgt eine Aktivierung der Unterbrechungs- * + * routine nur, wenn der Prozessor bereit ist, auf Unter- * + * brechungen zu reagieren. Dies kann mit Hilfe der Klasse * + * CPU festgelegt werden. * + * * + * Autor: Olaf Spinczyk, TU Dortmund * + *****************************************************************************/ +#ifndef PIC_include__ +#define PIC_include__ + +#include "device/port/IOport.h" + +class PIC { +private: + static const IOport IMR1; // interrupt mask register von PIC 1 + static const IOport IMR2; // interrupt mask register von PIC 2 + +public: + PIC(const PIC& copy) = delete; // Verhindere Kopieren + + PIC() = default; + + // Can't make static because atexit + + // IRQ-Nummern von Geraeten + enum { + timer = 0, // Programmable Interrupt Timer (PIT) + keyboard = 1, // Tastatur + com1 = 4 + }; + + // Freischalten der Weiterleitung eines IRQs durch den PIC an die CPU + static void allow(int irq); + + // Unterdruecken der Weiterleitung eines IRQs durch den PIC an die CPU + static void forbid(int irq); + + // Abfragen, ob die Weiterleitung fuer einen bestimmten IRQ unterdrueckt ist + static bool status(int interrupt_device); +}; + +#endif diff --git a/src/device/port/IOport.h b/src/device/port/IOport.h new file mode 100755 index 0000000..f109ea8 --- /dev/null +++ b/src/device/port/IOport.h @@ -0,0 +1,97 @@ +/***************************************************************************** + * * + * I O P O R T * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Diese Klasse dient dem Zugriff auf die Ein-/Ausgabe * + * Ports des PCs. Beim PC gibt es einen gesonderten I/O- * + * Adressraum, der nur mittels der Maschineninstruktionen * + * 'in' und 'out' angesprochen werden kann. Ein IOport- * + * Objekt wird beim Erstellen an eine Adresse des I/O- * + * Adressraums gebunden und kann dann fuer byte- oder * + * wortweise Ein- oder Ausgaben verwendet werden. * + * * + * Autor: Michael Schoettner, 28.8.2016 * + *****************************************************************************/ +#ifndef IOport_include__ +#define IOport_include__ + +class IOport { +private: + // 16-Bit Adresse im I/O-Adressraum + const unsigned short address; + +public: + // Konstruktor, speichert Port-Adresse + explicit IOport(unsigned short a) : address(a) {}; + + // Byteweise Ausgabe eines Wertes ueber einen I/O-Port. + void outb(unsigned char val) const { + asm volatile("outb %0, %1" + : + : "a"(val), "Nd"(address)); + } + + // NOTE: I added this for easier init of COM1 port + void outb(unsigned char offset, unsigned char val) const { + asm volatile("outb %0, %1" + : + : "a"(val), "Nd"(static_cast(address + offset))); + } + + // Wortweise Ausgabe eines Wertes ueber einen I/O-Port. + void outw(unsigned short val) const { + asm volatile("outw %0, %1" + : + : "a"(val), "Nd"(address)); + } + + // 32-Bit Ausgabe eines Wertes ueber einen I/O-Port. + void outdw(unsigned int val) const { + asm volatile("outl %0, %1" + : + : "a"(val), "Nd"(address)); + } + + // Byteweises Einlesen eines Wertes ueber einen I/O-Port. + unsigned char inb() const { + unsigned char ret; + + asm volatile("inb %1, %0" + : "=a"(ret) + : "Nd"(address)); + return ret; + } + + // NOTE: I added this for COM1 port + unsigned char inb(unsigned char offset) const { + unsigned char ret; + + asm volatile("inb %1, %0" + : "=a"(ret) + : "Nd"(static_cast(address + offset))); + return ret; + } + + // Wortweises Einlesen eines Wertes ueber einen I/O-Port. + unsigned short inw() const { + unsigned short ret; + + asm volatile("inw %1, %0" + : "=a"(ret) + : "Nd"(address)); + return ret; + } + + // 32-Bit Einlesen eines Wertes ueber einen I/O-Port. + unsigned int indw() const { + unsigned int ret; + + asm volatile("inl %1, %0" + : "=a"(ret) + : "Nd"(address)); + return ret; + } +}; + +#endif diff --git a/src/device/port/SerialOut.cc b/src/device/port/SerialOut.cc new file mode 100644 index 0000000..d6407fc --- /dev/null +++ b/src/device/port/SerialOut.cc @@ -0,0 +1,47 @@ +#include "SerialOut.h" + +const IOport SerialOut::com1(0x3f8); + +SerialOut::SerialOut() { + // NOTE: I could add different ports for every register but this was easier as it's that way on OSDev + com1.outb(1, 0x00); // Disable all interrupts + com1.outb(3, 0x80); // Enable DLAB (set baud rate divisor) + com1.outb(0x03); // Set divisor to 3 (lo byte) 38400 baud + com1.outb(1, 0x00); // (hi byte) + com1.outb(3, 0x03); // 8 bits, no parity, one stop bit + com1.outb(2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold + com1.outb(4, 0x0B); // IRQs enabled, RTS/DSR set + com1.outb(4, 0x1E); // Set in loopback mode, test the serial chip + com1.outb(0xAE); // Test serial chip (send byte 0xAE and check if serial returns same byte) + + // Check if serial is faulty (i.e: not same byte as sent) + if (com1.inb() == 0xAE) { + // If serial is not faulty set it in normal operation mode + // (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled) + com1.outb(4, 0x0F); + } +} + +int SerialOut::serial_received() { + return com1.inb(5) & 1; +} + +int SerialOut::is_transmit_empty() { + return com1.inb(5) & 0x20; +} + +char SerialOut::read() { + while (serial_received() == 0) {} + return com1.inb(); +} + +void SerialOut::write(const char a) { + while (is_transmit_empty() == 0) {} + com1.outb(a); +} + +void SerialOut::write(const bse::string_view a) { + for (char current : a) { + write(current); + } +} diff --git a/src/device/port/SerialOut.h b/src/device/port/SerialOut.h new file mode 100644 index 0000000..15c5659 --- /dev/null +++ b/src/device/port/SerialOut.h @@ -0,0 +1,28 @@ +#ifndef SerialOut_Include_H_ +#define SerialOut_Include_H_ + +#include "IOport.h" +#include "lib/util/String.h" +#include "lib/util/StringView.h" + +// NOTE: I took this code from https://wiki.osdev.org/Serial_Ports + +class SerialOut { +private: + static const IOport com1; + + static int serial_received(); + static int is_transmit_empty(); + +public: + SerialOut(); + SerialOut(const SerialOut& copy) = delete; + + // Can't make singleton because atexit + + static char read(); + static void write(char a); + static void write(const bse::string_view a); +}; + +#endif diff --git a/src/device/sound/PCSPK.cc b/src/device/sound/PCSPK.cc new file mode 100755 index 0000000..054b363 --- /dev/null +++ b/src/device/sound/PCSPK.cc @@ -0,0 +1,845 @@ +/***************************************************************************** + * * + * P C S P K * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Mit Hilfe dieser Klasse kann man Toene auf dem * + * PC-Lautsprecher ausgeben. * + * * + * Achtung: Qemu muss mit dem Parameter -soundhw pcspk aufgerufen * + * werden. Ansonsten kann man nichts hoeren. * + * * + * Autor: Michael Schoettner, HHU, 22.9.2016 * + *****************************************************************************/ + +#include "PCSPK.h" +#include "kernel/system/Globals.h" + +const IOport PCSPK::control(0x43); +const IOport PCSPK::data2(0x42); +const IOport PCSPK::ppi(0x61); + +/***************************************************************************** + * Methode: PCSPK::play * + *---------------------------------------------------------------------------* + * Beschreibung: Ton abspielen. * + * * + * Rückgabewerte: f: Frequenz des Tons * + * len: Laenge des Tons in ms * + *****************************************************************************/ +void PCSPK::play(float f, int len) { + int freq = static_cast(f); + int cntStart = 1193180 / freq; + int status; + + // Zaehler laden + control.outb(0xB6); // Zaehler-2 konfigurieren + data2.outb(cntStart % 256); // Zaehler-2 laden (Lobyte) + data2.outb(cntStart / 256); // Zaehler-2 laden (Hibyte) + + // Lautsprecher einschalten + status = static_cast(ppi.inb()); // Status-Register des PPI auslesen + ppi.outb(status | 3); // Lautpsrecher Einschalten + + // Pause + delay(len); + + // Lautsprecher ausschalten + off(); +} + +/***************************************************************************** + * Methode: PCSPK::off * + *---------------------------------------------------------------------------* + * Beschreibung: Lautsprecher ausschalten. * + *****************************************************************************/ +void PCSPK::off() { + int status; + + status = static_cast(ppi.inb()); // Status-Register des PPI auslesen + ppi.outb((status >> 2) << 2); // Lautsprecher ausschalten +} + +/***************************************************************************** + * Methode: PCSPK::delay * + *---------------------------------------------------------------------------* + * Beschreibung: Verzoegerung um X ms (in 1ms Schritten; Min. 1ms). * + * * + * Parameter: time (delay in ms) * + *****************************************************************************/ +inline void PCSPK::delay(int time) { + + /* Hier muess Code eingefuegt werden */ + + unsigned long start_time = systime; + + // systime is incremented in 10ms steps + while ((systime - start_time) * 10 < time) {} +} + +/***************************************************************************** + * Methode: PCSPK::tetris * + *---------------------------------------------------------------------------* + * Beschreibung: Tetris Sound, Kévin Rapaille, August 2013 * + * https://gist.github.com/XeeX/6220067 * + *****************************************************************************/ +void PCSPK::tetris() { + play(658, 125); + play(1320, 500); + play(990, 250); + play(1056, 250); + play(1188, 250); + play(1320, 125); + play(1188, 125); + play(1056, 250); + play(990, 250); + play(880, 500); + play(880, 250); + play(1056, 250); + play(1320, 500); + play(1188, 250); + play(1056, 250); + play(990, 750); + play(1056, 250); + play(1188, 500); + play(1320, 500); + play(1056, 500); + play(880, 500); + play(880, 500); + delay(250); + play(1188, 500); + play(1408, 250); + play(1760, 500); + play(1584, 250); + play(1408, 250); + play(1320, 750); + play(1056, 250); + play(1320, 500); + play(1188, 250); + play(1056, 250); + play(990, 500); + play(990, 250); + play(1056, 250); + play(1188, 500); + play(1320, 500); + play(1056, 500); + play(880, 500); + play(880, 500); + delay(500); + play(1320, 500); + play(990, 250); + play(1056, 250); + play(1188, 250); + play(1320, 125); + play(1188, 125); + play(1056, 250); + play(990, 250); + play(880, 500); + play(880, 250); + play(1056, 250); + play(1320, 500); + play(1188, 250); + play(1056, 250); + play(990, 750); + play(1056, 250); + play(1188, 500); + play(1320, 500); + play(1056, 500); + play(880, 500); + play(880, 500); + delay(250); + play(1188, 500); + play(1408, 250); + play(1760, 500); + play(1584, 250); + play(1408, 250); + play(1320, 750); + play(1056, 250); + play(1320, 500); + play(1188, 250); + play(1056, 250); + play(990, 500); + play(990, 250); + play(1056, 250); + play(1188, 500); + play(1320, 500); + play(1056, 500); + play(880, 500); + play(880, 500); + delay(500); + play(660, 1000); + play(528, 1000); + play(594, 1000); + play(495, 1000); + play(528, 1000); + play(440, 1000); + play(419, 1000); + play(495, 1000); + play(660, 1000); + play(528, 1000); + play(594, 1000); + play(495, 1000); + play(528, 500); + play(660, 500); + play(880, 1000); + play(838, 2000); + play(660, 1000); + play(528, 1000); + play(594, 1000); + play(495, 1000); + play(528, 1000); + play(440, 1000); + play(419, 1000); + play(495, 1000); + play(660, 1000); + play(528, 1000); + play(594, 1000); + play(495, 1000); + play(528, 500); + play(660, 500); + play(880, 1000); + play(838, 2000); + off(); +} + +/***************************************************************************** + * Methode: PCSPK::tetris * + *---------------------------------------------------------------------------* + * Beschreibung: Clint, Part of Daft Punk’s Aerodynamic * + * https://www.kirrus.co.uk/2010/09/linux-beep-music/ * + *****************************************************************************/ +void PCSPK::aerodynamic() { + play(587.3, 122); + play(370.0, 122); + play(493.9, 122); + play(370.0, 122); + play(587.3, 122); + play(370.0, 122); + play(493.9, 122); + play(370.0, 122); + play(587.3, 122); + play(370.0, 122); + play(493.9, 122); + play(370.0, 122); + play(587.3, 122); + play(370.0, 122); + play(493.9, 122); + play(370.0, 122); + play(587.3, 122); + play(415.3, 122); + play(493.9, 122); + play(415.3, 122); + play(587.3, 122); + play(415.3, 122); + play(493.9, 122); + play(415.3, 122); + play(587.3, 122); + play(415.3, 122); + play(493.9, 122); + play(415.3, 122); + play(587.3, 122); + play(415.3, 122); + play(493.9, 122); + play(415.3, 122); + play(784.0, 122); + play(493.9, 122); + play(659.3, 122); + play(493.9, 122); + play(784.0, 122); + play(493.9, 122); + play(659.3, 122); + play(493.9, 122); + play(784.0, 122); + play(493.9, 122); + play(659.3, 122); + play(493.9, 122); + play(784.0, 122); + play(493.9, 122); + play(659.3, 122); + play(493.9, 122); + play(659.3, 122); + play(440.0, 122); + play(554.4, 122); + play(440.0, 122); + play(659.3, 122); + play(440.0, 122); + play(554.4, 122); + play(440.0, 122); + play(659.3, 122); + play(440.0, 122); + play(554.4, 122); + play(440.0, 122); + play(659.3, 122); + play(440.0, 122); + play(554.4, 122); + play(440.0, 122); + play(1174.7, 122); + play(740.0, 122); + play(987.8, 122); + play(740.0, 122); + play(1174.7, 122); + play(740.0, 122); + play(987.8, 122); + play(740.0, 122); + play(1174.7, 122); + play(740.0, 122); + play(987.8, 122); + play(740.0, 122); + play(1174.7, 122); + play(740.0, 122); + play(987.8, 122); + play(740.0, 122); + play(1174.7, 122); + play(830.6, 122); + play(987.8, 122); + play(830.6, 122); + play(1174.7, 122); + play(830.6, 122); + play(987.8, 122); + play(830.6, 122); + play(1174.7, 122); + play(830.6, 122); + play(987.8, 122); + play(830.6, 122); + play(1174.7, 122); + play(830.6, 122); + play(987.8, 122); + play(830.6, 122); + play(1568.0, 122); + play(987.8, 122); + play(1318.5, 122); + play(987.8, 122); + play(1568.0, 122); + play(987.8, 122); + play(1318.5, 122); + play(987.8, 122); + play(1568.0, 122); + play(987.8, 122); + play(1318.5, 122); + play(987.8, 122); + play(1568.0, 122); + play(987.8, 122); + play(1318.5, 122); + play(987.8, 122); + play(1318.5, 122); + play(880.0, 122); + play(1108.7, 122); + play(880.0, 122); + play(1318.5, 122); + play(880.0, 122); + play(1108.7, 122); + play(880.0, 122); + play(1318.5, 122); + play(880.0, 122); + play(1108.7, 122); + play(880.0, 122); + play(1318.5, 122); + play(880.0, 122); + play(1108.7, 122); + play(1174.7, 122); + play(740.0, 122); + play(987.8, 122); + play(740.0, 122); + play(1174.7, 122); + play(740.0, 122); + play(987.8, 122); + play(740.0, 122); + play(1174.7, 122); + play(740.0, 122); + play(987.8, 122); + play(740.0, 122); + play(1174.7, 122); + play(740.0, 122); + play(987.8, 122); + play(740.0, 122); + play(1174.7, 122); + play(830.6, 122); + play(987.8, 122); + play(830.6, 122); + play(1174.7, 122); + play(830.6, 122); + play(987.8, 122); + play(830.6, 122); + play(1174.7, 122); + play(830.6, 122); + play(987.8, 122); + play(830.6, 122); + play(1174.7, 122); + play(830.6, 122); + play(987.8, 122); + play(830.6, 122); + play(1568.0, 122); + play(987.8, 122); + play(1318.5, 122); + play(987.8, 122); + play(1568.0, 122); + play(987.8, 122); + play(1318.5, 122); + play(987.8, 122); + play(1568.0, 122); + play(987.8, 122); + play(1318.5, 122); + play(987.8, 122); + play(1568.0, 122); + play(987.8, 122); + play(1318.5, 122); + play(987.8, 122); + play(1318.5, 122); + play(880.0, 122); + play(1108.7, 122); + play(880.0, 122); + play(1318.5, 122); + play(880.0, 122); + play(1108.7, 122); + play(880.0, 122); + play(1318.5, 122); + play(880.0, 122); + play(1108.7, 122); + play(880.0, 122); + play(1318.5, 122); + play(880.0, 122); + play(1108.7, 122); + play(1174.7, 122); + play(740.0, 122); + play(987.8, 122); + play(740.0, 122); + play(1174.7, 122); + play(740.0, 122); + play(987.8, 122); + play(740.0, 122); + play(1174.7, 122); + play(740.0, 122); + play(987.8, 122); + play(740.0, 122); + play(1174.7, 122); + play(740.0, 122); + play(987.8, 122); + play(740.0, 122); + play(1174.7, 122); + play(830.6, 122); + play(987.8, 122); + play(830.6, 122); + play(1174.7, 122); + play(830.6, 122); + play(987.8, 122); + play(830.6, 122); + play(1174.7, 122); + play(830.6, 122); + play(987.8, 122); + play(830.6, 122); + play(1174.7, 122); + play(830.6, 122); + play(987.8, 122); + play(830.6, 122); + play(1568.0, 122); + play(987.8, 122); + play(1318.5, 122); + play(987.8, 122); + play(1568.0, 122); + play(987.8, 122); + play(1318.5, 122); + play(987.8, 122); + play(1568.0, 122); + play(987.8, 122); + play(1318.5, 122); + play(987.8, 122); + play(1568.0, 122); + play(987.8, 122); + play(1318.5, 122); + play(987.8, 122); + play(1318.5, 122); + play(880.0, 122); + play(1108.7, 122); + play(880.0, 122); + play(1318.5, 122); + play(880.0, 122); + play(1108.7, 122); + play(880.0, 122); + play(1318.5, 122); + play(880.0, 122); + play(1108.7, 122); + play(880.0, 122); + play(1318.5, 122); + play(880.0, 122); + play(1108.7, 122); + play(1174.7, 122); + play(740.0, 122); + play(987.8, 122); + play(740.0, 122); + play(1174.7, 122); + play(740.0, 122); + play(987.8, 122); + play(740.0, 122); + play(1174.7, 122); + play(740.0, 122); + play(987.8, 122); + play(740.0, 122); + play(1174.7, 122); + play(740.0, 122); + play(987.8, 122); + play(740.0, 122); + play(1174.7, 122); + play(830.6, 122); + play(987.8, 122); + play(830.6, 122); + play(1174.7, 122); + play(830.6, 122); + play(987.8, 122); + play(830.6, 122); + play(1174.7, 122); + play(830.6, 122); + play(987.8, 122); + play(830.6, 122); + play(1174.7, 122); + play(830.6, 122); + play(987.8, 122); + play(830.6, 122); + play(1568.0, 122); + play(987.8, 122); + play(1318.5, 122); + play(987.8, 122); + play(1568.0, 122); + play(987.8, 122); + play(1318.5, 122); + play(987.8, 122); + play(1568.0, 122); + play(987.8, 122); + play(1318.5, 122); + play(987.8, 122); + play(1568.0, 122); + play(987.8, 122); + play(1318.5, 122); + play(987.8, 122); + play(1318.5, 122); + play(880.0, 122); + play(1108.7, 122); + play(880.0, 122); + play(1318.5, 122); + play(880.0, 122); + play(1108.7, 122); + play(880.0, 122); + play(1318.5, 122); + play(880.0, 122); + play(1108.7, 122); + play(880.0, 122); + play(1318.5, 122); + play(880.0, 122); + play(1108.7, 122); + play(1174.7, 122); + play(740.0, 122); + play(987.8, 122); + play(740.0, 122); + play(1174.7, 122); + play(740.0, 122); + play(987.8, 122); + play(740.0, 122); + play(1174.7, 122); + play(740.0, 122); + play(987.8, 122); + play(740.0, 122); + play(1174.7, 122); + play(740.0, 122); + play(987.8, 122); + play(740.0, 122); + play(1174.7, 122); + play(830.6, 122); + play(987.8, 122); + play(830.6, 122); + play(1174.7, 122); + play(830.6, 122); + play(987.8, 122); + play(830.6, 122); + play(1174.7, 122); + play(830.6, 122); + play(987.8, 122); + play(830.6, 122); + play(1174.7, 122); + play(830.6, 122); + play(987.8, 122); + play(830.6, 122); + play(1568.0, 122); + play(987.8, 122); + play(1318.5, 122); + play(987.8, 122); + play(1568.0, 122); + play(987.8, 122); + play(1318.5, 122); + play(987.8, 122); + play(1568.0, 122); + play(987.8, 122); + play(1318.5, 122); + play(987.8, 122); + play(1568.0, 122); + play(987.8, 122); + play(1318.5, 122); + play(987.8, 122); + play(1318.5, 122); + play(880.0, 122); + play(1108.7, 122); + play(880.0, 122); + play(1318.5, 122); + play(880.0, 122); + play(1108.7, 122); + play(880.0, 122); + play(1318.5, 122); + play(880.0, 122); + play(1108.7, 122); + play(880.0, 122); + play(1318.5, 122); + play(880.0, 122); + play(1108.7, 122); + play(587.3, 122); + play(370.0, 122); + play(493.9, 122); + play(370.0, 122); + play(587.3, 122); + play(370.0, 122); + play(493.9, 122); + play(370.0, 122); + play(587.3, 122); + play(370.0, 122); + play(493.9, 122); + play(370.0, 122); + play(587.3, 122); + play(370.0, 122); + play(493.9, 122); + play(370.0, 122); + play(587.3, 122); + play(415.3, 122); + play(493.9, 122); + play(415.3, 122); + play(587.3, 122); + play(415.3, 122); + play(493.9, 122); + play(415.3, 122); + play(587.3, 122); + play(415.3, 122); + play(493.9, 122); + play(415.3, 122); + play(587.3, 122); + play(415.3, 122); + play(493.9, 122); + play(415.3, 122); + play(784.0, 122); + play(493.9, 122); + play(659.3, 122); + play(493.9, 122); + play(784.0, 122); + play(493.9, 122); + play(659.3, 122); + play(493.9, 122); + play(784.0, 122); + play(493.9, 122); + play(659.3, 122); + play(493.9, 122); + play(784.0, 122); + play(493.9, 122); + play(659.3, 122); + play(493.9, 122); + play(659.3, 122); + play(440.0, 122); + play(554.4, 122); + play(440.0, 122); + play(659.3, 122); + play(440.0, 122); + play(554.4, 122); + play(440.0, 122); + play(659.3, 122); + play(440.0, 122); + play(554.4, 122); + play(440.0, 122); + play(659.3, 122); + play(440.0, 122); + play(554.4, 122); + play(587.3, 122); + play(370.0, 122); + play(493.9, 122); + play(370.0, 122); + play(587.3, 122); + play(370.0, 122); + play(493.9, 122); + play(370.0, 122); + play(587.3, 122); + play(370.0, 122); + play(493.9, 122); + play(370.0, 122); + play(587.3, 122); + play(370.0, 122); + play(493.9, 122); + play(370.0, 122); + play(587.3, 122); + play(415.3, 122); + play(493.9, 122); + play(415.3, 122); + play(587.3, 122); + play(415.3, 122); + play(493.9, 122); + play(415.3, 122); + play(587.3, 122); + play(415.3, 122); + play(493.9, 122); + play(415.3, 122); + play(587.3, 122); + play(415.3, 122); + play(493.9, 122); + play(415.3, 122); + play(784.0, 122); + play(493.9, 122); + play(659.3, 122); + play(493.9, 122); + play(784.0, 122); + play(493.9, 122); + play(659.3, 122); + play(493.9, 122); + play(784.0, 122); + play(493.9, 122); + play(659.3, 122); + play(493.9, 122); + play(784.0, 122); + play(493.9, 122); + play(659.3, 122); + play(493.9, 122); + play(659.3, 122); + play(440.0, 122); + play(554.4, 122); + play(440.0, 122); + play(659.3, 122); + play(440.0, 122); + play(554.4, 122); + play(440.0, 122); + play(659.3, 122); + play(440.0, 122); + play(554.4, 122); + play(440.0, 122); + play(659.3, 122); + play(440.0, 122); + play(554.4, 122); + play(1174.7, 122); + play(740.0, 122); + play(987.8, 122); + play(740.0, 122); + play(1174.7, 122); + play(740.0, 122); + play(987.8, 122); + play(740.0, 122); + play(1174.7, 122); + play(740.0, 122); + play(987.8, 122); + play(740.0, 122); + play(1174.7, 122); + play(740.0, 122); + play(987.8, 122); + play(740.0, 122); + play(1174.7, 122); + play(830.6, 122); + play(987.8, 122); + play(830.6, 122); + play(1174.7, 122); + play(830.6, 122); + play(987.8, 122); + play(830.6, 122); + play(1174.7, 122); + play(830.6, 122); + play(987.8, 122); + play(830.6, 122); + play(1174.7, 122); + play(830.6, 122); + play(987.8, 122); + play(830.6, 122); + play(1568.0, 122); + play(987.8, 122); + play(1318.5, 122); + play(987.8, 122); + play(1568.0, 122); + play(987.8, 122); + play(1318.5, 122); + play(987.8, 122); + play(1568.0, 122); + play(987.8, 122); + play(1318.5, 122); + play(987.8, 122); + play(1568.0, 122); + play(987.8, 122); + play(1318.5, 122); + play(987.8, 122); + play(1318.5, 122); + play(880.0, 122); + play(1108.7, 122); + play(880.0, 122); + play(1318.5, 122); + play(880.0, 122); + play(1108.7, 122); + play(880.0, 122); + play(1318.5, 122); + play(880.0, 122); + play(1108.7, 122); + play(880.0, 122); + play(1318.5, 122); + play(880.0, 122); + play(1108.7, 122); + play(1174.7, 122); + play(740.0, 122); + play(987.8, 122); + play(740.0, 122); + play(1174.7, 122); + play(740.0, 122); + play(987.8, 122); + play(740.0, 122); + play(1174.7, 122); + play(740.0, 122); + play(987.8, 122); + play(740.0, 122); + play(1174.7, 122); + play(740.0, 122); + play(987.8, 122); + play(740.0, 122); + play(1174.7, 122); + play(830.6, 122); + play(987.8, 122); + play(830.6, 122); + play(1174.7, 122); + play(830.6, 122); + play(987.8, 122); + play(830.6, 122); + play(1174.7, 122); + play(830.6, 122); + play(987.8, 122); + play(830.6, 122); + play(1174.7, 122); + play(830.6, 122); + play(987.8, 122); + play(830.6, 122); + play(1568.0, 122); + play(987.8, 122); + play(1318.5, 122); + play(987.8, 122); + play(1568.0, 122); + play(987.8, 122); + play(1318.5, 122); + play(987.8, 122); + play(1568.0, 122); + play(987.8, 122); + play(1318.5, 122); + play(987.8, 122); + play(1568.0, 122); + play(987.8, 122); + play(1318.5, 122); + play(987.8, 122); + play(1318.5, 122); + play(880.0, 122); + play(1108.7, 122); + play(880.0, 122); + play(1318.5, 122); + play(880.0, 122); + play(1108.7, 122); + play(880.0, 122); + play(1318.5, 122); + play(880.0, 122); + play(1108.7, 122); + play(880.0, 122); + play(1318.5, 122); + play(880.0, 122); + play(1108.7, 122); + play(880.0, 122); + off(); +} diff --git a/src/device/sound/PCSPK.h b/src/device/sound/PCSPK.h new file mode 100755 index 0000000..111cbec --- /dev/null +++ b/src/device/sound/PCSPK.h @@ -0,0 +1,89 @@ +/***************************************************************************** + * * + * P C S P K * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Mit Hilfe dieser Klasse kann man Toene auf dem * + * PC-Lautsprecher ausgeben. * + * * + * Achtung: Qemu muss mit dem Parameter -soundhw pcspk aufgerufen * + * werden. Ansonsten kann man nichts hoeren. * + * * + * Autor: Michael Schoettner, HHU, 22.9.2016 * + *****************************************************************************/ + +#ifndef PCSPK_include__ +#define PCSPK_include__ + +#include "device/port/IOport.h" + +// Note, Frequenz +constexpr const float C0 = 130.81; +constexpr const float C0X = 138.59; +constexpr const float D0 = 146.83; +constexpr const float D0X = 155.56; +constexpr const float E0 = 164.81; +constexpr const float F0 = 174.61; +constexpr const float F0X = 185.00; +constexpr const float G0 = 196.00; +constexpr const float G0X = 207.65; +constexpr const float A0 = 220.00; +constexpr const float A0X = 233.08; +constexpr const float B0 = 246.94; + +constexpr const float C1 = 261.63; +constexpr const float C1X = 277.18; +constexpr const float D1 = 293.66; +constexpr const float D1X = 311.13; +constexpr const float E1 = 329.63; +constexpr const float F1 = 349.23; +constexpr const float F1X = 369.99; +constexpr const float G1 = 391.00; +constexpr const float G1X = 415.30; +constexpr const float A1 = 440.00; +constexpr const float A1X = 466.16; +constexpr const float B1 = 493.88; + +constexpr const float C2 = 523.25; +constexpr const float C2X = 554.37; +constexpr const float D2 = 587.33; +constexpr const float D2X = 622.25; +constexpr const float E2 = 659.26; +constexpr const float F2 = 698.46; +constexpr const float F2X = 739.99; +constexpr const float G2 = 783.99; +constexpr const float G2X = 830.61; +constexpr const float A2 = 880.00; +constexpr const float A2X = 923.33; +constexpr const float B2 = 987.77; +constexpr const float C3 = 1046.50; + +class PCSPK { +private: + static const IOport control; // Steuerregister (write only) + static const IOport data2; // Zaehler-2 Datenregister + static const IOport ppi; // Status-Register des PPI + + // Verzoegerung um X ms (in 1ms Schritten; Min. 1ms) + static inline void delay(int time); + +public: + PCSPK(const PCSPK& copy) = delete; // Verhindere Kopieren + + // Konstruktor. Initialisieren der Ports. + PCSPK() = default; + + // Can't make singleton because atexit + + // Demo Sounds + static void tetris(); + static void aerodynamic(); + + // Ton abspielen + static void play(float f, int len); + + // Lautsprecher ausschalten + static void off(); +}; + +#endif diff --git a/src/device/time/PIT.cc b/src/device/time/PIT.cc new file mode 100755 index 0000000..eddf5fd --- /dev/null +++ b/src/device/time/PIT.cc @@ -0,0 +1,88 @@ +/***************************************************************************** + * * + * P I T * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Programmable Interval Timer. * + * * + * Autor: Michael Schoettner, 3.7.2022 * + *****************************************************************************/ + +#include "PIT.h" +#include "kernel/system/Globals.h" + +const IOport PIT::control(0x43); +const IOport PIT::data0(0x40); + +/***************************************************************************** + * Methode: PIT::interval * + *---------------------------------------------------------------------------* + * Beschreibung: Zeitinervall programmieren. * + * * + * Parameter: * + * us: Zeitintervall in Mikrosekunden, nachdem periodisch ein * + * Interrupt erzeugt werden soll. * + *****************************************************************************/ +void PIT::interval(int us) { + + /* hier muss Code eingefuegt werden */ + + control.outb(0x36); // Zähler 0 Mode 3 + + unsigned int cntStart = static_cast((1193180.0 / 1000000.0) * us); // 1.19Mhz PIT + + data0.outb(cntStart & 0xFF); // Zaehler-0 laden (Lobyte) + data0.outb(cntStart >> 8); // Zaehler-0 laden (Hibyte) +} + +/***************************************************************************** + * Methode: PIT::plugin * + *---------------------------------------------------------------------------* + * Beschreibung: Unterbrechungen fuer den Zeitgeber erlauben. Ab sofort * + * wird bei Ablauf des definierten Zeitintervalls die * + * Methode 'trigger' aufgerufen. * + *****************************************************************************/ +void PIT::plugin() { + + /* hier muss Code eingefuegt werden */ + + intdis.assign(IntDispatcher::timer, *this); + PIC::allow(PIC::timer); +} + +/***************************************************************************** + * Methode: PIT::trigger * + *---------------------------------------------------------------------------* + * Beschreibung: ISR fuer den Zeitgeber. Wird aufgerufen, wenn der * + * Zeitgeber eine Unterbrechung ausloest. Anzeige der Uhr * + * aktualisieren und Thread wechseln durch Setzen der * + * Variable 'forceSwitch', wird in 'int_disp' behandelt. * + *****************************************************************************/ +void PIT::trigger() { + + /* hier muss Code eingefuegt werden */ + + // log << TRACE << "Incrementing systime" << endl; + + // alle 10ms, Systemzeit weitersetzen + systime++; + + // Bei jedem Tick einen Threadwechsel ausloesen. + // Aber nur wenn der Scheduler bereits fertig intialisiert wurde + // und ein weiterer Thread rechnen moechte + + /* hier muss Code eingefuegt werden */ + + // Indicator + if (systime - last_indicator_refresh >= 10) { + indicator_pos = (indicator_pos + 1) % 4; + CGA::show(79, 0, indicator[indicator_pos]); + last_indicator_refresh = systime; + } + + // Preemption + if (scheduler.preemption_enabled()) { + // log << TRACE << "Preemption" << endl; + scheduler.preempt(); + } +} diff --git a/src/device/time/PIT.h b/src/device/time/PIT.h new file mode 100755 index 0000000..bfd7d6a --- /dev/null +++ b/src/device/time/PIT.h @@ -0,0 +1,54 @@ +/***************************************************************************** + * * + * P I T * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Programmable Interval Timer. * + * * + * Autor: Michael Schoettner, 23.8.2016 * + *****************************************************************************/ + +#ifndef PIT_include__ +#define PIT_include__ + +#include "kernel/interrupt/ISR.h" +#include "device/port/IOport.h" +#include "lib/util/Array.h" + +class PIT : public ISR { +private: + const static IOport control; + const static IOport data0; + + enum { time_base = 838 }; /* ns */ + int timer_interval; + + const bse::array indicator{'|', '/', '-', '\\'}; + unsigned int indicator_pos = 0; + unsigned long last_indicator_refresh = 0; + +public: + PIT(const PIT& copy) = delete; // Verhindere Kopieren + +// ~PIT() override = default; + + // Zeitgeber initialisieren. + explicit PIT(int us) { + PIT::interval(us); + } + + // Konfiguriertes Zeitintervall auslesen. + int interval() const { return timer_interval; } + + // Zeitintervall in Mikrosekunden, nachdem periodisch ein Interrupt + //erzeugt werden soll. + static void interval(int us); + + // Aktivierung der Unterbrechungen fuer den Zeitgeber + void plugin(); + + // Unterbrechnungsroutine des Zeitgebers. + void trigger() override; +}; + +#endif diff --git a/src/kernel/demo/ArrayDemo.cc b/src/kernel/demo/ArrayDemo.cc new file mode 100644 index 0000000..13e9b98 --- /dev/null +++ b/src/kernel/demo/ArrayDemo.cc @@ -0,0 +1,40 @@ +#include "ArrayDemo.h" + +void ArrayDemo::run() { + bse::array arr1 {}; + bse::array arr2 {}; + + kout.lock(); + kout.clear(); + + kout << "Adding..." << endl; + for (int i = 0; i < 10; ++i) { + arr1[i] = i; + } + + kout << "Iterator printing arr1:" << endl; + for (int i : arr1) { + kout << i << " "; + } + kout << endl; + + kout << "Swapping arr1 and arr2..." << endl; + arr1.swap(arr2); + + kout << "Iterator printing arr1:" << endl; + for (int i : arr1) { + kout << i << " "; + } + kout << endl; + + kout << "Iterator printing arr2:" << endl; + for (int i : arr2) { + kout << i << " "; + } + kout << endl; + + // arr1.swap(arr3); // Not possible as type/size has to match + + kout.unlock(); + scheduler.exit(); +} diff --git a/src/kernel/demo/ArrayDemo.h b/src/kernel/demo/ArrayDemo.h new file mode 100644 index 0000000..a726df9 --- /dev/null +++ b/src/kernel/demo/ArrayDemo.h @@ -0,0 +1,16 @@ +#ifndef ArrayDemo_include__ +#define ArrayDemo_include__ + +#include "kernel/system/Globals.h" +#include "lib/util/Array.h" + +class ArrayDemo : public Thread { +public: + ArrayDemo(const ArrayDemo& copy) = delete; + + ArrayDemo() : Thread("ArrayDemo") {} + + void run() override; +}; + +#endif diff --git a/src/kernel/demo/HeapDemo.cc b/src/kernel/demo/HeapDemo.cc new file mode 100755 index 0000000..85ba182 --- /dev/null +++ b/src/kernel/demo/HeapDemo.cc @@ -0,0 +1,78 @@ +/***************************************************************************** + * * + * H E A P D E M O * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Demonstration der dynamischen Speicherverwaltung. * + * * + * Autor: Michael Schoettner, HHU, 27.12.2016 * + *****************************************************************************/ + +#include "HeapDemo.h" + +void HeapDemo::run() { + kout.lock(); + kout.clear(); + kout << "HEAP_DEMO ===================================================================" << endl; + + /* hier muss Code eingefuegt werden */ + + allocator.dump_free_memory(); + + // Rounding to word border + kout << "ROUNDING ====================================================================" << endl; + void* alloc = allocator.alloc(1); // 1 Byte + allocator.dump_free_memory(); + allocator.free(alloc); + allocator.dump_free_memory(); + + // Some objects and forward/backward merging + kout << "SOME OBJECTS ================================================================" << endl; + MyObj* a = new MyObj(5); + allocator.dump_free_memory(); + MyObj* b = new MyObj(10); + allocator.dump_free_memory(); + MyObj* c = new MyObj(15); + allocator.dump_free_memory(); + delete b; // No merge + allocator.dump_free_memory(); + delete a; // Merge forward BUG: Bluescreen + allocator.dump_free_memory(); + delete c; + allocator.dump_free_memory(); + + // Allocate too whole heap + // void* ptr = allocator.alloc(1024 * 1024 - 24); + // allocator.dump_free_memory(); + // allocator.free(ptr); + // allocator.dump_free_memory(); + + // Allocate too much + kout << "TOO MUCH ====================================================================" << endl; + allocator.alloc(1024 * 1024); // should fail as only 1024 * 1024 - Headersize bytes are available + allocator.dump_free_memory(); + + // A lot of allocations + // MyObj* objs[1024]; + // for (unsigned int i = 0; i < 1024; ++i) { + // objs[i] = new MyObj(5); + // } + // allocator.dump_free_memory(); + // waitForReturn(); + // for (unsigned int i = 0; i < 1024; ++i) { + // delete objs[i]; + // } + // allocator.dump_free_memory(); + + // Array allocation + kout << "ARRAY =======================================================================" << endl; + MyObj* objs = new MyObj[1024]; + allocator.dump_free_memory(); + delete[] objs; + allocator.dump_free_memory(); + + kout << "HEAP_DEMO END ===============================================================" << endl; + + kout.unlock(); + scheduler.exit(); +} diff --git a/src/kernel/demo/HeapDemo.h b/src/kernel/demo/HeapDemo.h new file mode 100755 index 0000000..44e3d42 --- /dev/null +++ b/src/kernel/demo/HeapDemo.h @@ -0,0 +1,32 @@ +/***************************************************************************** + * * + * H E A P D E M O * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Demonstration der dynamischen Speicherverwaltung. * + * * + * Autor: Michael Schoettner, HHU, 25.9.2016 * + *****************************************************************************/ +#ifndef HeapDemo_include__ +#define HeapDemo_include__ + +#include "kernel/system/Globals.h" +#include "kernel/process/Thread.h" + +class MyObj { +public: + constexpr MyObj() : value(5) {}; + constexpr MyObj(const unsigned int val) : value(val) {}; + const unsigned int value; +}; + +class HeapDemo : public Thread { +public: + HeapDemo(const HeapDemo& copy) = delete; + + HeapDemo() : Thread("HeapDemo") {} + + void run() override; +}; + +#endif diff --git a/src/kernel/demo/KeyboardDemo.cc b/src/kernel/demo/KeyboardDemo.cc new file mode 100755 index 0000000..168ca2e --- /dev/null +++ b/src/kernel/demo/KeyboardDemo.cc @@ -0,0 +1,34 @@ +/***************************************************************************** + * * + * K E Y B O A R D D E M O * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Testausgaben für den CGA-Treiber. * + * * + * Autor: Michael Schoettner, HHU, 26.10.2018 * + *****************************************************************************/ + +#include "KeyboardDemo.h" + +void KeyboardDemo::run() { + + /* Hier muess Code eingefuegt werden */ + + kout << "Keyboard Demo: " << endl; + + kout.lock(); + kout.clear(); + kout << "Info: Die Keyboard Demo sperrt den Output Stream:\n" + << " Wenn die Preemption Demo laeuft wird diese also erst\n" + << " fortfahren wenn die Keyboard Demo wieder beendet ist." << endl; + kout << "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nInput: "; + kout.flush(); + + while (running) { + kout << listener.waitForKeyEvent(); + kout.flush(); + } + + kout.unlock(); + scheduler.exit(); +} diff --git a/src/kernel/demo/KeyboardDemo.h b/src/kernel/demo/KeyboardDemo.h new file mode 100755 index 0000000..99cf4d0 --- /dev/null +++ b/src/kernel/demo/KeyboardDemo.h @@ -0,0 +1,44 @@ +/***************************************************************************** + * * + * K E Y B O A R D D E M O * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Testausgaben für den CGA-Treiber. * + * * + * Autor: Michael Schoettner, HHU, 26.10.2018 * + *****************************************************************************/ + +#ifndef KeyboardDemo_include__ +#define KeyboardDemo_include__ + +#include "kernel/system/Globals.h" +#include "kernel/process/Thread.h" +#include "kernel/event/KeyEventListener.h" + +class KeyboardDemo : public Thread { +private: + KeyEventListener listener; + +public: + KeyboardDemo(const KeyboardDemo& copy) = delete; + + KeyboardDemo() : Thread("KeyboardDemo"), listener(tid) { + kevman.subscribe(listener); + } + + // Base class destructor will be called automatically + ~KeyboardDemo() override { + if (running) { + // NOTE: If the thread was exited nicely it can unlock before destructor, + // but on forced kill kout has to be unlocked in the destructor. + // This is bad since it could release the lock although some other + // thread set it (so use nice_kill) + kout.unlock(); + } + kevman.unsubscribe(listener); + } + + void run() override; +}; + +#endif diff --git a/src/kernel/demo/MainMenu.cc b/src/kernel/demo/MainMenu.cc new file mode 100644 index 0000000..4bf783d --- /dev/null +++ b/src/kernel/demo/MainMenu.cc @@ -0,0 +1,90 @@ +#include "MainMenu.h" +#include "ArrayDemo.h" +#include "HeapDemo.h" +#include "KeyboardDemo.h" +#include "PagingDemo.h" +#include "PCSPKdemo.h" +#include "PreemptiveThreadDemo.h" +#include "SmartPointerDemo.h" +#include "StringDemo.h" +#include "TextDemo.h" +#include "VBEdemo.h" +#include "VectorDemo.h" + +void print_demo_menu() { + kout.lock(); + kout.clear(); + kout << "Demo Menu, press number to start, k/K to kill:\n" + << "1 - Text Demo\n" + << "2 - PCSPK Demo\n" + << "3 - Keyboard Demo\n" + << "4 - Heap Demo\n" + << "5 - VBE Demo\n" + << "6 - Paging Demo\n" + << "7 - Preemption Demo\n" + << "Extra demos:\n" + << "8 - bse::vector demo\n" + << "9 - bse::array demo\n" + << "0 - bse::unique_ptr demo\n" + << "! - bse::string demo\n" + << endl; + kout.unlock(); +} + +void MainMenu::run() { + print_demo_menu(); + + char input = '\0'; + unsigned int running_demo = 0; + while (running) { + input = listener.waitForKeyEvent(); + + if ((input >= '0' && input <= '9') || input == '!') { + switch (input) { + case '1': + running_demo = scheduler.ready(); + break; + case '2': + running_demo = scheduler.ready(&PCSPK::aerodynamic); + break; + case '3': + running_demo = scheduler.ready(); + break; + case '4': + running_demo = scheduler.ready(); + break; + case '5': + running_demo = scheduler.ready(); + break; + case '6': + running_demo = scheduler.ready(); + break; + case '7': + running_demo = scheduler.ready(3); + break; + + case '8': + running_demo = scheduler.ready(); + break; + case '9': + running_demo = scheduler.ready(); + break; + case '0': + running_demo = scheduler.ready(); + break; + case '!': + running_demo = scheduler.ready(); + break; + } + } else if (input == 'k') { + scheduler.nice_kill(running_demo); // NOTE: If thread exits itself this will throw error + print_demo_menu(); + } else if (input == 'K') { + scheduler.kill(running_demo); + print_demo_menu(); + } + } + + scheduler.exit(); + // This thread won't be deleted... +} diff --git a/src/kernel/demo/MainMenu.h b/src/kernel/demo/MainMenu.h new file mode 100644 index 0000000..d823a8d --- /dev/null +++ b/src/kernel/demo/MainMenu.h @@ -0,0 +1,26 @@ +#ifndef MainMenu_Inlucde_H_ +#define MainMenu_Inlucde_H_ + +#include "kernel/system/Globals.h" +#include "kernel/process/Thread.h" +#include "kernel/event/KeyEventListener.h" + +class MainMenu : public Thread { +private: + KeyEventListener listener; + +public: + MainMenu(const MainMenu& copy) = delete; + + MainMenu() : Thread("MainMenu"), listener(tid) { + kevman.subscribe(listener); + } + + ~MainMenu() override { + kevman.unsubscribe(listener); + } + + void run() override; +}; + +#endif diff --git a/src/kernel/demo/PCSPKdemo.cc b/src/kernel/demo/PCSPKdemo.cc new file mode 100644 index 0000000..a0f0331 --- /dev/null +++ b/src/kernel/demo/PCSPKdemo.cc @@ -0,0 +1,16 @@ +#include "PCSPKdemo.h" + +void PCSPKdemo::run() { + kout.lock(); + kout.clear(); + kout << "Playing..." << endl; + kout.unlock(); + + (*melody)(); // This syntax is confusing as hell + + kout.lock(); + kout << "Finished" << endl; + kout.unlock(); + + scheduler.exit(); +} diff --git a/src/kernel/demo/PCSPKdemo.h b/src/kernel/demo/PCSPKdemo.h new file mode 100644 index 0000000..8306453 --- /dev/null +++ b/src/kernel/demo/PCSPKdemo.h @@ -0,0 +1,23 @@ +#ifndef PCSPKdemo_INCLUDE_H_ +#define PCSPKdemo_INCLUDE_H_ + +#include "kernel/system/Globals.h" +#include "kernel/process/Thread.h" + +class PCSPKdemo : public Thread { +private: + void (*melody)(); // Allow to pass a melody to play when initializing the demo + +public: + PCSPKdemo(const PCSPKdemo& copy) = delete; + + PCSPKdemo(void (*melody)()) : Thread("PCSPKdemo"), melody(melody) {} + + ~PCSPKdemo() override { + PCSPK::off(); + } + + void run() override; +}; + +#endif diff --git a/src/kernel/demo/PagingDemo.cc b/src/kernel/demo/PagingDemo.cc new file mode 100644 index 0000000..6796cae --- /dev/null +++ b/src/kernel/demo/PagingDemo.cc @@ -0,0 +1,50 @@ +#include "PagingDemo.h" + +void PagingDemo::writeprotect_page() { + kout << "Accessing a writeprotected page triggers bluescreen,\nif you can read this it didn't work" << endl; + + // BlueScreen 1 + // asm("int $3"); + + // BlueScreen 2 + log.info() << "Allocating page" << endl; + unsigned int* page = pg_alloc_page(); + *page = 42; + log.info() << "Writeprotecting page..." << endl; + pg_write_protect_page(page); + + log.info() << "Accessing writeprotected page" << endl; + *page = 42; // We map logical to physical 1:1 so no need to do any lookup + + // No free because bluescreen +} + +void PagingDemo::notpresent_page() { + kout << "Produces pagefault, if you can read this it didn't work" << endl; + + log.info() << "Allocating page" << endl; + unsigned int* page = pg_alloc_page(); + *page = 42; + + log.info() << "Marking page notpresent..." << endl; + pg_notpresent_page(page); + + log.info() << "Accessing page" << endl; + kout << "Page not accessible: " << *page << endl; + + // No free because bluescreen +} + +void PagingDemo::run() { + kout << "Press w for writeprotect demo, n for notpresent demo" << endl; + switch(listener.waitForKeyEvent()) { + case 'w': + writeprotect_page(); + break; + case 'n': + notpresent_page(); + break; + } + + scheduler.exit(); +} diff --git a/src/kernel/demo/PagingDemo.h b/src/kernel/demo/PagingDemo.h new file mode 100644 index 0000000..60ffe69 --- /dev/null +++ b/src/kernel/demo/PagingDemo.h @@ -0,0 +1,30 @@ +#ifndef BlueScreenDemo_include__ +#define BlueScreenDemo_include__ + +#include "kernel/system/Globals.h" +#include "kernel/process/Thread.h" +#include "kernel/event/KeyEventListener.h" + +class PagingDemo: public Thread { +private: + void writeprotect_page(); + void free_page(); + void notpresent_page(); + + KeyEventListener listener; + +public: + PagingDemo(const PagingDemo& copy) = delete; + + PagingDemo(): Thread("PagingDemo"), listener(tid) { + kevman.subscribe(listener); + } + + ~PagingDemo() override { + kevman.unsubscribe(listener); + } + + void run() override; +}; + +#endif diff --git a/src/kernel/demo/PreemptiveThreadDemo.cc b/src/kernel/demo/PreemptiveThreadDemo.cc new file mode 100644 index 0000000..bf286fe --- /dev/null +++ b/src/kernel/demo/PreemptiveThreadDemo.cc @@ -0,0 +1,34 @@ +#include "PreemptiveThreadDemo.h" + +void PreemptiveLoopThread::run() { + int cnt = 0; + + while (running) { + // Basic synchronization by semaphore + kout.lock(); + + // Saving + restoring kout position doesn't help much as preemption still occurs + CGA_Stream::setpos(55, id); + kout << fillw(3) << id << fillw(0) << ": " << dec << cnt++ << endl; + + kout.unlock(); + } + + scheduler.exit(); +} + +void PreemptiveThreadDemo::run() { + kout.lock(); + kout.clear(); + + kout << "Preemptive Thread Demo:" << endl; + + kout << "Readying LoopThreads" << endl; + for (unsigned int i = 0; i < number_of_threads; ++i) { + scheduler.ready(i); + } + + kout << "Exiting main thread" << endl; + kout.unlock(); + scheduler.exit(); +} diff --git a/src/kernel/demo/PreemptiveThreadDemo.h b/src/kernel/demo/PreemptiveThreadDemo.h new file mode 100644 index 0000000..a9e58fb --- /dev/null +++ b/src/kernel/demo/PreemptiveThreadDemo.h @@ -0,0 +1,35 @@ +#ifndef preemptive_thread_include__ +#define preemptive_thread_include__ + +#include "kernel/system/Globals.h" +#include "kernel/process/Thread.h" +#include "lib/async/Semaphore.h" + +class PreemptiveLoopThread : public Thread { +private: + int id; + +public: + PreemptiveLoopThread(const PreemptiveLoopThread& copy) = delete; // Verhindere Kopieren + + // Gibt der Loop einen Stack und eine Id. + PreemptiveLoopThread(int i) : Thread("LoopThread"), id(i) {} + + // Zaehlt einen Zaehler hoch und gibt ihn auf dem Bildschirm aus. + void run() override; +}; + +class PreemptiveThreadDemo : public Thread { +private: + unsigned int number_of_threads; + +public: + PreemptiveThreadDemo(const PreemptiveThreadDemo& copy) = delete; // Verhindere Kopieren + + PreemptiveThreadDemo(unsigned int n) : Thread("PreemptiveThreadDemo"), number_of_threads(n) {} + + // Thread-Startmethode + void run() override; +}; + +#endif diff --git a/src/kernel/demo/SmartPointerDemo.cc b/src/kernel/demo/SmartPointerDemo.cc new file mode 100644 index 0000000..632e55e --- /dev/null +++ b/src/kernel/demo/SmartPointerDemo.cc @@ -0,0 +1,122 @@ +#include "SmartPointerDemo.h" +#include "kernel/process/IdleThread.h" + +void SmartPointerDemo::run() { + kout.lock(); + kout.clear(); + + kout << "Output is written to log to be able to trace memory allocations/deallocations" << endl; + + { + log.info() << "Allocating new unique_ptr..." << endl; + bse::unique_ptr ptr = bse::make_unique(1); + log.info() << "Leaving scope..." << endl; + } + log.info() << "Should be deleted by now..." << endl; + + { + log.info() << "Allocating new unique_ptr..." << endl; + bse::unique_ptr ptr1 = bse::make_unique(1); + bse::unique_ptr ptr2; + + log.info() << "*ptr1 == " << *ptr1 << ", (bool)ptr2 == " << static_cast(ptr2) << endl; + log.info() << "Moving ptr1 => ptr2 (no allocations should happen)..." << endl; + ptr2 = std::move(ptr1); + log.info() << "(bool)ptr1 == " << static_cast(ptr1) << ", *ptr2 == " << *ptr2 << endl; + + log.info() << "Leaving scope..." << endl; + } + log.info() << "Should be deleted by now..." << endl; + + { + log.info() << "Allocating (2) new unique_ptr..." << endl; + bse::unique_ptr ptr1 = bse::make_unique(1); + bse::unique_ptr ptr2 = bse::make_unique(1); + + log.info() << "Moving ptr1 => ptr2 (ptr1 should be freed)..." << endl; + ptr2 = std::move(ptr1); + + log.info() << "Leaving scope..." << endl; + } + log.info() << "Should be deleted by now..." << endl; + + // ===================================================================== + + { + log.info() << "Allocating new unique_ptr..." << endl; + bse::unique_ptr ptr = bse::make_unique(10); + ptr[0] = 1; + log.info() << "ptr[0] == " << ptr[0] << endl; + } + log.info() << "Should be deleted by now..." << endl; + + { + log.info() << "Allocating new unique_ptr..." << endl; + bse::unique_ptr ptr1 = bse::make_unique(10); + bse::unique_ptr ptr2; + + log.info() << "Moving ptr1 => ptr2 (no allocations should happen)..." << endl; + ptr2 = std::move(ptr1); + + log.info() << "Leaving scope..." << endl; + } + log.info() << "Should be deleted by now..." << endl; + + { + log.info() << "Allocating (2) new unique_ptr..." << endl; + bse::unique_ptr ptr1 = bse::make_unique(10); + bse::unique_ptr ptr2 = bse::make_unique(10); + + log.info() << "Moving ptr1 => ptr2 (ptr1 should be freed)..." << endl; + ptr2 = std::move(ptr1); + + log.info() << "Leaving scope..." << endl; + } + log.info() << "Should be deleted by now..." << endl; + + // NOTE: This wasn't working because of a missing operator[] delete in the allocator + log.info() << "Allocating unique_ptr*..." << endl; + bse::unique_ptr* ptrptr = new bse::unique_ptr[10]; + delete[] ptrptr; + log.info() << "Should be deleted by now..." << endl; + + // ===================================================================== + + { + log.info() << "Stackallocating Array, 10>..." << endl; + bse::array, 10> arr; + log.info() << "Populating slot 0..." << endl; + arr[0] = bse::make_unique(1); + log.info() << "Moving slot 0 to slot 1..." << endl; + arr[1] = std::move(arr[0]); + log.info() << "Leaving scope" << endl; + } + log.info() << "Should be deleted by now..." << endl; + + { + log.info() << "Heapallocating Array, 10>..." << endl; + bse::array, 10>* arr = new bse::array, 10>; + log.info() << "Populating slot 0..." << endl; + (*arr)[0] = bse::make_unique(1); + log.info() << "Moving slot 0 to slot 1..." << endl; + (*arr)[1] = std::move((*arr)[0]); + log.info() << "Deleting" << endl; + delete arr; + log.info() << "Leaving scope" << endl; + } + log.info() << "Should be deleted by now..." << endl; + + { + log.info() << "ArrayList>..." << endl; + bse::vector> vec; + log.info() << "2x insertion" << endl; + vec.push_back(bse::make_unique(1)); + vec.push_back(bse::make_unique(2)); + + log.info() << "Leaving scope" << endl; + } + log.info() << "Should be deleted by now..." << endl; + + kout.unlock(); + scheduler.exit(); +} diff --git a/src/kernel/demo/SmartPointerDemo.h b/src/kernel/demo/SmartPointerDemo.h new file mode 100644 index 0000000..2d91346 --- /dev/null +++ b/src/kernel/demo/SmartPointerDemo.h @@ -0,0 +1,15 @@ +#ifndef SmartPointerDemo_include__ +#define SmartPointerDemo_include__ + +#include "kernel/system/Globals.h" + +class SmartPointerDemo : public Thread { +public: + SmartPointerDemo(const SmartPointerDemo& copy) = delete; + + SmartPointerDemo() : Thread("SmartPointerDemo") {} + + void run() override; +}; + +#endif diff --git a/src/kernel/demo/StringDemo.cc b/src/kernel/demo/StringDemo.cc new file mode 100644 index 0000000..89304f5 --- /dev/null +++ b/src/kernel/demo/StringDemo.cc @@ -0,0 +1,56 @@ +#include "StringDemo.h" + +void StringDemo::run() { + kout.lock(); + kout.clear(); + + log.info() << "Allocating new string" << endl; + bse::string str1 = "This is a dynamically allocated string!"; + kout << str1 << endl; + + log.info() << "Reassign string" << endl; + str1 = "Hello"; + kout << str1 << " has length " << dec << str1.size() << endl; + kout << "Again with strlen: Hello has length " << dec << bse::strlen("Hello") << endl; + + kout << "Adding strings: " << str1 << " + World" << endl; + log.info() << "Adding strings" << endl; + str1 = str1 + " World"; + kout << str1 << endl; + + kout << "Hello += World" << endl; + log.info() << "Hello += World" << endl; + bse::string str3 = "Hello"; + str3 += " World"; + kout << str3 << endl; + + kout << "Hello World *= 3" << endl; + str3 *= 3; + kout << str3 << endl; + + kout << "String iterator!" << endl; + for (const char c : str1) { + kout << c << " "; + } + kout << endl; + + log.info() << "Allocating new string" << endl; + bse::string str2 = "Hello World"; + kout << "str1 == str2: " << static_cast(str1 == str2) << endl; + kout << "strcmp(Hello, Hello): " << bse::strcmp("Hello", "Hello") << endl; + + log.info() << "Reassign str2" << endl; + str2 = "Hello"; + + bse::array arr{}; + arr[0] = 'H'; + arr[1] = 'e'; + arr[2] = 'l'; + arr[3] = 'l'; + arr[4] = 'o'; + kout << "bse::array to bse::string: " << static_cast(arr) << ", size: " << (bse::string(arr)).size() << endl; + kout << "(bse::string)arr (" << static_cast(arr) << ") == str2 (" << str2 << "): " << static_cast(bse::string(arr) == str2) << endl; + + kout.unlock(); + scheduler.exit(); +} diff --git a/src/kernel/demo/StringDemo.h b/src/kernel/demo/StringDemo.h new file mode 100644 index 0000000..566d03c --- /dev/null +++ b/src/kernel/demo/StringDemo.h @@ -0,0 +1,15 @@ +#ifndef StringDemo_include__ +#define StringDemo_include__ + +#include "kernel/system/Globals.h" + +class StringDemo : public Thread { +public: + StringDemo(const StringDemo& copy) = delete; + + StringDemo() : Thread("StringDemo") {} + + void run() override; +}; + +#endif diff --git a/src/kernel/demo/TextDemo.cc b/src/kernel/demo/TextDemo.cc new file mode 100755 index 0000000..365e484 --- /dev/null +++ b/src/kernel/demo/TextDemo.cc @@ -0,0 +1,43 @@ +/***************************************************************************** + * * + * T E X T D E M O * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Testausgaben für den CGA-Treiber. * + * * + * Autor: Michael Schoettner, HHU, 26.10.2018 * + *****************************************************************************/ + +#include "TextDemo.h" + +void TextDemo::run() { + + /* Hier muess Code eingefuegt werden */ + + kout.lock(); + kout.clear(); + kout << "TextDemo\n" + << endl; + + kout << "Attribut (GREEN on WHITE): " + << bgc(CGA::WHITE) << green << "GREEN on WHITE" << endl + << "Attribut (WHITE on BLACK): " + << bgc(CGA::BLACK) << white << "WHITE on BLACK" << endl; + kout << endl; + + kout << "Test der Zahlenausgabefunktion:" << endl + << "| dec | hex | bin |" << endl + << "+-------+-------+-------+" << endl; + + for (unsigned short num = 0; num < 17; ++num) { + kout << fillw(0) << "| " << fillw(6) << dec << num + << fillw(0) << "| " << fillw(6) << hex << num + << fillw(0) << "| " << fillw(6) << bin << num + << fillw(0) << "|" << endl; + } + + kout << endl; + + kout.unlock(); + scheduler.exit(); +} diff --git a/src/kernel/demo/TextDemo.h b/src/kernel/demo/TextDemo.h new file mode 100755 index 0000000..b15b32f --- /dev/null +++ b/src/kernel/demo/TextDemo.h @@ -0,0 +1,26 @@ +/***************************************************************************** + * * + * T E X T D E M O * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Testausgaben für den CGA-Treiber. * + * * + * Autor: Michael Schoettner, HHU, 26.10.2018 * + *****************************************************************************/ + +#ifndef TextDemo_include__ +#define TextDemo_include__ + +#include "kernel/system/Globals.h" +#include "kernel/process/Thread.h" + +class TextDemo : public Thread { +public: + TextDemo(const TextDemo& copy) = delete; + + TextDemo() : Thread("TextDemo") {} + + void run() override; +}; + +#endif diff --git a/src/kernel/demo/VBEdemo.cc b/src/kernel/demo/VBEdemo.cc new file mode 100644 index 0000000..2ef1de8 --- /dev/null +++ b/src/kernel/demo/VBEdemo.cc @@ -0,0 +1,106 @@ +/***************************************************************************** + * * + * V B E D E M O * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Demo zu VESA. * + * * + * Autor: Michael Schoettner, HHU, 26.12.2016 * + *****************************************************************************/ + +#include "VBEdemo.h" +#include "bmp_hhu.cc" + +/***************************************************************************** + * Methode: VBEdemo::linInterPol1D * + *---------------------------------------------------------------------------* + * Beschreibung: Farbwert in einer Dimension interpoliert berechnen. * + *****************************************************************************/ +int VBEdemo::linInterPol1D(int x, int xr, int l, int r) { + return ((((l >> 16) * (xr - x) + (r >> 16) * x) / xr) << 16) | (((((l >> 8) & 0xFF) * (xr - x) + ((r >> 8) & 0xFF) * x) / xr) << 8) | (((l & 0xFF) * (xr - x) + (r & 0xFF) * x) / xr); +} + +/***************************************************************************** + * Methode: VBEdemo::linInterPol2D * + *---------------------------------------------------------------------------* + * Beschreibung: Farbwert in zwei Dimensionen interpoliert berechnen. * + *****************************************************************************/ +int VBEdemo::linInterPol2D(int x, int y, int lt, int rt, int lb, int rb) { + return linInterPol1D(y, vesa.yres, + linInterPol1D(x, vesa.xres, lt, rt), + linInterPol1D(x, vesa.xres, lb, rb)); +} + +/***************************************************************************** + * Methode: VBEdemo::drawColors * + *---------------------------------------------------------------------------* + * Beschreibung: Pixel-Demo. * + *****************************************************************************/ +void VBEdemo::drawColors() { + int x_res = 640; + int y_res = 480; + + for (int y = 0; y < y_res; y++) { + for (int x = 0; x < x_res; x++) { + vesa.drawPixel(x, y, linInterPol2D(x, y, 0x0000FF, 0x00FF00, 0xFF0000, 0xFFFF00)); + } + } +} + +/***************************************************************************** + * Methode: VBEdemo::drawBitmap * + *---------------------------------------------------------------------------* + * Beschreibung: Bitmap aus GIMP ausgeben. * + *****************************************************************************/ +void VBEdemo::drawBitmap() { + unsigned int sprite_width = hhu.width; + unsigned int sprite_height = hhu.height; + unsigned int sprite_bpp = hhu.bytes_per_pixel; + const unsigned char* sprite_pixel = reinterpret_cast(hhu.pixel_data); + + /* Hier muss Code eingefuegt werden */ + + vesa.drawSprite(sprite_width, sprite_height, sprite_bpp, sprite_pixel); +} + +/***************************************************************************** + * Methode: VBEdemo::drawFonts * + *---------------------------------------------------------------------------* + * Beschreibung: Fonts ausgeben. * + *****************************************************************************/ +void VBEdemo::drawFonts() { + + /* Hier muss Code eingefuegt werden */ + + vesa.drawString(std_font_8x8, 0, 300, 0, "STD FONT 8x8", 12); + vesa.drawString(std_font_8x16, 0, 320, 0, "STD FONT 8x16", 13); + vesa.drawString(acorn_font_8x8, 0, 340, 0, "ACORN FONT 8x8", 14); + vesa.drawString(sun_font_8x16, 0, 360, 0, "SUN FONT 8x16", 13); + vesa.drawString(sun_font_12x22, 0, 380, 0, "SUN FONT 12x22", 14); + vesa.drawString(pearl_font_8x8, 0, 400, 0, "PEARL FONT 8x8", 14); +} + +/***************************************************************************** + * Methode: VBEdemo::run * + *---------------------------------------------------------------------------* + * Beschreibung: Der Anwendungsthread erzeugt drei Threads die Zaehler * + * ausgeben und terminiert sich selbst. * + *****************************************************************************/ +void VBEdemo::run() { + + // In den Grafikmodus schalten (32-Bit Farbtiefe) + vesa.initGraphicMode(MODE_640_480_24BITS); + vesa.setDrawingBuff(BUFFER_VISIBLE); + + drawColors(); + + /* Hier muss Code eingefuegt werden */ + vesa.drawRectangle(100, 100, 300, 300, 0); + drawBitmap(); + drawFonts(); + + while (running) {} + + // selbst terminieren + scheduler.exit(); +} diff --git a/src/kernel/demo/VBEdemo.h b/src/kernel/demo/VBEdemo.h new file mode 100644 index 0000000..5727c4d --- /dev/null +++ b/src/kernel/demo/VBEdemo.h @@ -0,0 +1,46 @@ +/***************************************************************************** + * * + * V B E D E M O * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Demo zu VESA. * + * * + * Autor: Michael Schoettner, HHU, 26.12.2016 * + *****************************************************************************/ +#ifndef VBEdemo_include__ +#define VBEdemo_include__ + +#include "kernel/system/Globals.h" +#include "kernel/process/Thread.h" + +class VBEdemo : public Thread { +private: + // Hilfsfunktionen fuer drawColors() + static int linInterPol1D(int x, int xr, int l, int r); + static int linInterPol2D(int x, int y, int lt, int rt, int lb, int rb); + +public: + VBEdemo(const VBEdemo& copy) = delete; // Verhindere Kopieren + + // Gib dem Anwendungsthread einen Stack. + VBEdemo() : Thread("VBEdemo") {} + + ~VBEdemo() override { + allocator.free(reinterpret_cast(vesa.hfb)); // Memory is allocated after every start and never deleted, so add that + VESA::initTextMode(); + } + + // Thread-Startmethode + void run() override; + + // Farbraum ausgeben + void drawColors(); + + // Bitmap aus GIMP ausgeben + static void drawBitmap(); + + // Fonts ausgeben + static void drawFonts(); +}; + +#endif diff --git a/src/kernel/demo/VectorDemo.cc b/src/kernel/demo/VectorDemo.cc new file mode 100644 index 0000000..c1a774d --- /dev/null +++ b/src/kernel/demo/VectorDemo.cc @@ -0,0 +1,110 @@ +#include "VectorDemo.h" + +void print(OutStream& os, const bse::vector& list) { + os << "Printing List: "; + for (const int i : list) { + os << i << " "; + } + os << endl; +} + +void VectorDemo::run() { + bse::vector list; + + kout.lock(); + kout.clear(); + kout << "Logs are written to serial to see the memory interactions" << endl; + + log.info() << "Initial list size: " << dec << list.size() << endl; + + log.info() << "Adding elements in order" << endl; + for (int i = 0; i < 5; ++i) { + list.push_back(i); + } + print(log.info(), list); + + log.info() << "Removing all elements from the front" << endl; + for (unsigned int i = 0; i < 5; ++i) { + list.erase(list.begin()); + } + print(log.info(), list); + + // ============================================================ + + log.info() << "Adding elements in order with realloc" << endl; + for (int i = 0; i < 10; ++i) { + log.info() << "Add " << dec << i << endl; + list.push_back(i); + } + print(log.info(), list); + + log.info() << "Removing all elements from the back" << endl; + for (unsigned int i = 0; i < 10; ++i) { + list.erase(list.end() - 1); + } + print(log.info(), list); + + // ============================================================ + + for (int i = 0; i < 5; ++i) { + list.push_back(i); + } + print(log.info(), list); + + log.info() << "Adding inside the list (at idx 0, 2, 5)" << endl; + list.insert(list.begin() + 0, 10); + list.insert(list.begin() + 2, 10); + list.insert(list.begin() + 5, 10); + print(log.info(), list); + + log.info() << "Removing inside the list (at idx 0, 2, 5)" << endl; + list.erase(list.begin() + 0); + list.erase(list.begin() + 2); + list.erase(list.begin() + 5); + print(log.info(), list); + + for (unsigned int i = 0; i < 5; ++i) { + list.erase(list.begin()); + } + print(log.info(), list); + + // ============================================================ + + log.info() << "Mirror scheduling behavior" << endl; + + // These are the threads + int active = 0; // Idle thread + list.push_back(1); + list.push_back(2); + list.push_back(3); + print(log.info(), list); + + log.info() << "Starting..." << endl; + for (unsigned int n = 0; n < 10000; ++n) { + list.push_back(active); + active = list[0]; + list.erase(list.begin()); + + if (list.size() != 3 || active == -1) { + log.info() << "ERROR: Thread went missing" << endl; + break; + } + + if (n < 5) { + print(log.info(), list); + } + } + log.info() << "Finished." << endl; + + print(log.info(), list); + + // ============================================================ + + log.info() << "Range based for support" << endl; + for (int i : list) { + log.info() << "List contains element: " << dec << i << endl; + } + + kout.unlock(); + scheduler.exit(); +} diff --git a/src/kernel/demo/VectorDemo.h b/src/kernel/demo/VectorDemo.h new file mode 100644 index 0000000..2e66f1f --- /dev/null +++ b/src/kernel/demo/VectorDemo.h @@ -0,0 +1,17 @@ +#ifndef VectorDemo_include__ +#define VectorDemo_include__ + +#include "kernel/system/Globals.h" +#include "kernel/process/Thread.h" +#include "lib/util/Vector.h" + +class VectorDemo : public Thread { +public: + VectorDemo(const VectorDemo& copy) = delete; + + VectorDemo() : Thread("VectorDemo") {} + + void run() override; +}; + +#endif diff --git a/src/kernel/demo/bmp_hhu.cc b/src/kernel/demo/bmp_hhu.cc new file mode 100644 index 0000000..74c7591 --- /dev/null +++ b/src/kernel/demo/bmp_hhu.cc @@ -0,0 +1,1576 @@ +/* GIMP RGB C-Source image dump (hhulogo.c) */ + +static constexpr struct { + unsigned int width; + unsigned int height; + unsigned int bytes_per_pixel; /* 2:RGB16, 3:RGB, 4:RGBA */ + unsigned char pixel_data[200 * 52 * 3 + 1]; +} hhu = { + 200, + 52, + 3, + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\375\376\376\375\375\376\375\375\376" + "\375\375\376\375\375\376\375\375\376\375\375\376\375\375\376\375\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\375\376\376" + "\375\375\376\375\375\376\375\375\376\375\375\376\375\375\376\375\375\376" + "\375\375\376\375\375\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\374\375\376\267\314\341" + "\231\266\324\231\266\324\231\266\324\231\266\324\231\266\324\231\266\324" + "\231\266\323\260\307\336\374\375\375\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\327\342\356\232\266\324\231\266\324\231\266\324\231\266\324" + "\231\266\324\231\266\324\231\266\324\237\272\326\364\367\372\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\373\374\375|\243\314\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264i\230" + "\307\373\374\375\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\276\316" + "\343\005l\263\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\064y\270\356\364\370" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\373\374\375|\243\314\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264" + "\000l\264i\231\307\373\374\375\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\276\316\343\005l\263\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\065y\270" + "\356\364\370\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\373\374\375|\243\314\000l\264\000l\264\000l\264\000l\264" + "\000l\264\000l\264\000l\264i\231\307\373\374\375\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\276\316\343\005l\263\000l\264\000l\264\000l\264\000l\264\000l\264\000" + "l\264\065y\270\356\364\370\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\373\374\375|\243\314\000l\264\000l\264\000" + "l\264\000l\264\000l\264\000l\264\000l\264i\231\307\373\374\375\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\276\316\343\005l\263\000l\264\000l\264\000l\264\000l\264" + "\000l\264\000l\264\065y\270\356\364\370\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\373\374\375|\243\314\000l\264" + "\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264i\231\307\373\374\375\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\276\316\343\005l\263\000l\264\000l\264\000l" + "\264\000l\264\000l\264\000l\264\065y\270\356\364\370\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\373\374\375|\243" + "\314\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264i\231\307\373\374\375" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\276\316\343\005l\263\000l\264" + "\000l\264\000l\264\000l\264\000l\264\000l\264\065y\270\356\364\370\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\373\374" + "\375|\243\314\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264i\231\307\373" + "\374\375\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\276\316\343\005l\263" + "\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\065y\270\356\364\370\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\373\374\375|\243\314\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264i\231" + "\307\373\374\375\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\276\316" + "\343\005l\263\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\065y\270\356\364\370" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\373\374\375|\243\314\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264" + "\000l\264i\231\307\373\374\375\376\376\376\376\376\376\376\376\376\375\376" + "\376\373\374\375\372\374\375\372\373\374\372\373\374\373\374\375\374\375" + "\375\375\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\276\316\343\005l\263\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\065y\270" + "\356\364\370\376\376\376\376\376\376\376\376\376\376\376\376\374\375\375" + "\373\374\375\372\373\375\372\373\374\372\374\375\373\374\375\375\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\375\375\375\375\375\375\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\373\374\375|\243\314\000l\264\000l\264\000l\264\000l\264" + "\000l\264\000l\264\000l\264i\231\307\373\374\375\374\375\375\354\362\367\307\327" + "\347\246\275\330{\242\313\\\221\303P\212\277Q\212\277_\223\304\177\245\314" + "\252\300\331\312\332\351\360\365\370\374\375\375\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\276\316\343\005l\263\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\065y\270\356" + "\364\370\375\375\376\363\367\372\320\336\353\260\305\334\206\251\316c\225" + "\305R\213\300P\212\300Y\217\303u\237\311\237\271\325\302\323\344\345\356" + "\365\373\374\375\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\367\372\374\357\365\371\357\365" + "\371\357\365\371\357\365\371\357\365\371\357\365\371\357\365\371\360\365" + "\371\374\375\375\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\365\370\372\357\365" + "\371\357\365\371\357\365\371\357\365\371\357\365\371\357\365\371\357\365" + "\371\362\366\372\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\367\367\367\372\372\372\376\376\376\376\376\376\374\374" + "\374\364\364\364\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\375\375\375\325\325\325\343\343\343\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\346\346\346\322\322\322\375\375" + "\375\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\313\313" + "\313\324\324\324\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\364\364\364\374\374\374\376\376" + "\376\376\376\376\372\372\372\367\367\367\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\373\373\373\305\305\305\364\364" + "\364\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\373\374\375|\243\314\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264" + "d\227\305\316\335\352\207\251\316\071{\271\024m\264\001l\264\000l\264\000l\264\000" + "l\264\000l\264\000l\264\000l\264\002l\264\027n\264?~\272\221\257\321\327\343\356\373" + "\374\375\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\276\316\343\005l\263\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\062" + "x\270\317\337\353\240\272\325I\204\274\034o\264\003l\264\000l\264\000l\264\000l\264" + "\000l\264\000l\264\000l\264\001l\264\016l\264\061w\267w\237\310\307\327\346\367\371" + "\373\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\276\317\341\067y\271\066y\271\066y\271\066y\271\066y\271\066y\271\066y\271" + "L\204\275\356\364\367\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\374\375\376\232\266\324\066y" + "\271\066y\271\066y\271\066y\271\066y\271\066y\271\066y\271e\226\305\372\374\375" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\375\375\375\252\252\252" + "\311\311\311\376\376\376\376\376\376\353\353\353vvv\373\373\373\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\375\375\375\301\301\301" + "\326\326\326\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\333\333\333\274\274\274\375\375\375\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\262\262\262\300\300\300\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\373\373\373" + "zzz\346\346\346\376\376\376\376\376\376\315\315\315\240\240\240\375\375\375" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\371\371\371" + "\247\247\247\357\357\357\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\373\374\375|\243\314\000l\264\000l\264\000l\264\000l\264" + "\000l\264\000l\264\000l\264\024p\266\036p\265\001l\264\000l\264\000l\264\000l\264\000l\264" + "\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\001l\264'r\266\211" + "\253\316\344\354\363\375\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\276\316\343\005l\263\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\006n" + "\265't\266\003l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264" + "\000l\264\000l\264\000l\264\000l\264\000l\264\030n\264h\225\304\322\337\353\374\375" + "\375\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\274\315\340\005l\264\000" + "l\264\000l\264\000l\264\000l\264\000l\264\000l\264\065x\270\356\364\367\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\374\375\376\223\261\322\000k\264\000l\264\000l\264\000l\264\000l\264\000" + "l\264\000l\264U\216\300\372\373\375\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\375\375\375\244\244\244\306\306\306\376\376\376\376\376\376\352" + "\352\352hhh\372\372\372\376\376\376\374\374\374\364\364\364\370\370\370\376" + "\376\376\376\376\376\373\373\373\374\374\374\376\376\376\373\373\373\374" + "\374\374\365\365\365\367\367\367\375\375\375\376\376\376\373\373\373\374" + "\374\374\370\370\370\375\375\375\374\374\374\373\373\373\376\376\376\376" + "\376\376\373\373\373\363\363\363\370\370\370\375\375\375\262\262\262\300" + "\300\300\367\367\367\365\365\365\375\375\375\376\376\376\376\376\376\376" + "\376\376\376\376\376\373\373\373mmm\345\345\345\376\376\376\376\376\376\312" + "\312\312\231\231\231\375\375\375\376\376\376\373\373\373\363\363\363\372" + "\372\372\376\376\376\376\376\376\372\372\372\375\375\375\375\375\375\373" + "\373\373\373\373\373\363\363\363\372\372\372\376\376\376\376\376\376\375" + "\375\375\367\367\367\366\366\366\375\375\375\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\373\374\375|\243" + "\314\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264" + "\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000" + "l\264\000l\264\000l\264\000l\264\002l\264C\177\272\303\324\345\373\375\374\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\276\316\343\005l\263\000l\264\000l\264\000l\264\000l\264" + "\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000" + "l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264(s\266" + "\243\274\330\366\371\373\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\274\315\340" + "\005l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\065y\270\356\364\367\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\374\375\376\223\261\322\000k\264\000l\264\000l\264\000l\264" + "\000l\264\000l\264\000l\264U\216\300\372\373\375\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\375\375\375\244\244\244\303\303\303\372\372\372\372\372" + "\372\347\347\347hhh\372\372\372\371\371\371\245\245\245\230\230\230\206\206" + "\206\333\333\333\375\375\375\261\261\261\315\315\315\373\373\373\213\213" + "\213\243\243\243\213\213\213ppp\324\324\324\374\374\374\226\226\226\237\237" + "\237}}}\310\310\310\317\317\317\253\253\253\375\375\375\350\350\350\214\214" + "\214\244\244\244\213\213\213\361\361\361\262\262\262\207\207\207\212\212" + "\212vvv\266\266\266\375\375\375\376\376\376\376\376\376\376\376\376\373\373" + "\373mmm\341\341\341\372\372\372\372\372\372\307\307\307\232\232\232\375\375" + "\375\355\355\355\217\217\217\240\240\240\211\211\211\354\354\354\373\373" + "\373\201\201\201\357\357\357\346\346\346\203\203\203\230\230\230\210\210" + "\210~~~\361\361\361\374\374\374\275\275\275\220\220\220\217\217\217\302\302" + "\302\375\375\375\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\373\374\375|\243\314\000l\264\000l\264\000l\264\000l\264\000l\264" + "\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000" + "l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264" + "$r\265\254\304\334\373\374\375\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\276\316\343\005l\263\000" + "l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264" + "\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000" + "l\264\000l\264\000l\264\000l\264\016m\264\206\247\314\361\366\371\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\274\315\340\005l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\065" + "y\270\356\364\367\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\374\375\376\223\261\322\000k\264\000" + "l\264\000l\264\000l\264\000l\264\000l\264\000l\264U\216\300\372\373\375\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\375\375\375\244\244\244jjj\204\204\204" + "\204\204\204|||```\372\372\372\312\312\312\234\234\234\367\367\367\325\325" + "\325\211\211\211\373\373\373\244\244\244\305\305\305\373\373\373}|}\267\267" + "\267\373\373\373\304\304\304\241\241\241\373\373\373\216\216\216\272\272" + "\272\362\362\362\360\360\360\310\310\310\235\235\235\373\373\373\217\217" + "\217\310\310\310\374\374\374\372\372\372\375\375\375\262\262\262\223\223" + "\223\371\371\371\340\340\340ooo\373\373\373\376\376\376\376\376\376\376\376" + "\376\373\373\373gggyyy\204\204\204\204\204\204lll\231\231\231\373\373\373" + "\245\245\245\275\275\275\371\371\371\270\270\270\270\270\270\372\372\372" + "fff\354\354\354\351\351\351TTT\344\344\344\371\371\371\206\206\206\322\322" + "\322\343\343\343www\362\362\362\356\356\356kkk\367\367\367\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\373\374\375|\243" + "\314\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264" + "\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000" + "l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\035p\265\257\306\335\374\375" + "\374\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\276\316\343\005l\263\000l\264\000l\264\000l\264\000l\264\000l\264\000" + "l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264" + "\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\007" + "l\264\205\247\314\366\371\373\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\274\315\340\005l\264\000l\264\000l\264" + "\000l\264\000l\264\000l\264\000l\264\065y\270\356\364\367\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\374\375\376\223\261\322\000k\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264" + "U\216\300\372\373\375\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\375" + "\375\375\244\244\244\303\303\303\373\373\373\373\373\373\350\350\350hhh\372" + "\372\372\252\252\252ooo\216\216\216\207\207\207\207\207\207\372\372\372\244" + "\244\244\305\305\305\373\373\373\201\200\201\331\331\331\376\376\376\313" + "\313\313\234\234\234\373\373\373\221\221\221\325\325\325\376\376\376\376" + "\376\376\310\310\310\235\235\235\370\370\370bbb\352\352\352\376\376\376\376" + "\376\376\376\376\376\262\262\262\277\277\277\376\376\376\351\351\351lll\372" + "\372\372\376\376\376\376\376\376\376\376\376\373\373\373mmm\342\342\342\373" + "\373\373\373\373\373\307\307\307\232\232\232\371\371\371rrr~~~\216\216\216" + "~~~\261\261\261\371\371\371fff\354\354\354\351\351\351kkk\372\372\372\374" + "\374\374\223\223\223\316\316\316\311\311\311\\\\\\\216\216\216\215\215\215" + "rrr\361\361\361\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\373\374\375|\243\314\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264" + "\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000" + "l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264" + "\000l\264)s\266\313\331\350\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\276\316\343\005l\263\000l\264\000l\264\000l" + "\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264" + "\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000" + "l\264\000l\264\000l\264\000l\264\015m\264\240\273\327\374\374\375\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\274\315\340\005l\264" + "\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\065y\270\356\364\367\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\374\375\376\223\261\322\000k\264\000l\264\000l\264\000l\264\000l\264\000" + "l\264\000l\264U\216\300\372\373\375\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\375\375\375\244\244\244\306\306\306\376\376\376\376\376\376\352" + "\352\352hhh\372\372\372\266\266\266\264\264\264\372\372\372\372\372\372\370" + "\370\370\375\375\375\244\244\244\305\305\305\373\373\373\201\200\201\332" + "\332\332\376\376\376\313\313\313\234\234\234\373\373\373\221\221\221\327" + "\327\327\376\376\376\376\376\376\310\310\310\235\235\235\371\371\371kkk\340" + "\340\340\376\376\376\375\375\375\375\375\375\262\262\262\300\300\300\376" + "\376\376\351\351\351lll\372\372\372\376\376\376\376\376\376\376\376\376\373" + "\373\373mmm\345\345\345\376\376\376\376\376\376\312\312\312\232\232\232\372" + "\372\372\204\204\204\321\321\321\372\372\372\372\372\372\372\372\372\372" + "\372\372fff\354\354\354\351\351\351lll\372\372\372\374\374\374\223\223\223" + "\316\316\316\320\320\320\214\214\214\370\370\370\373\373\373\370\370\370" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\373\374\375|\243\314\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264" + "\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000" + "l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264" + "\000l\264\000l\264N\205\275\353\362\367\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\276\316\343\005l\263\000l\264\000l\264\000l\264" + "\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000" + "l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264" + "\000l\264\000l\264\000l\264\000l\264&r\265\317\335\352\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\274\315\340\005l\264\000l\264\000" + "l\264\000l\264\000l\264\000l\264\000l\264\065y\270\356\364\367\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\374\375\376\223\261\322\000k\264\000l\264\000l\264\000l\264\000l\264\000l\264\000" + "l\264U\216\300\372\373\375\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\375\375\375\245\245\245\306\306\306\376\376\376\376\376\376\352\352\352" + "jjj\372\372\372\345\345\345sss\304\304\304\300\300\300\250\250\250\373\373" + "\373\245\245\245\306\306\306\373\373\373\202\202\202\332\332\332\376\376" + "\376\313\313\313\235\235\235\373\373\373\222\222\222\327\327\327\376\376" + "\376\376\376\376\311\311\311\236\236\236\374\374\374\274\274\274\220\220" + "\220\313\313\313\250\250\250\345\345\345\263\263\263\301\301\301\376\376" + "\376\351\351\351nnn\373\373\373\376\376\376\376\376\376\376\376\376\373\373" + "\373ppp\345\345\345\376\376\376\376\376\376\312\312\312\233\233\233\374\374" + "\374\314\314\314\204\204\204\311\311\311\264\264\264\305\305\305\372\372" + "\372hhh\355\355\355\351\351\351nnn\373\373\373\374\374\374\224\224\224\317" + "\317\317\364\364\364}}}\267\267\267\307\307\307\234\234\234\366\366\366\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\373" + "\374\375|\243\314\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264" + "\000l\264\000l\264\000l\264\000l\264\003l\264#q\265A\200\273U\215\301S\214\301>~\272" + "\037p\264\002l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000" + "l\264\005l\264\236\271\325\374\375\375\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\276\316\343\005l\263\000l\264\000l\264\000l\264\000l\264\000" + "l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\001l\264\032n\264\071|\272Q\213" + "\300V\216\302E\203\274(r\266\006l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000" + "l\264\000l\264\000l\264\000l\264\001l\264d\223\303\366\371\373\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\274\315\340\005l\264\000l\264\000l\264" + "\000l\264\000l\264\000l\264\000l\264\065y\270\356\364\367\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\374\375\376\223\261\322\000k\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264" + "U\216\300\372\373\375\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\345\345\345\356\356\356\376\376\376\376\376\376\370\370\370\333" + "\333\333\375\375\375\376\376\376\352\352\352\307\307\307\315\315\315\367" + "\367\367\376\376\376\345\345\345\356\356\356\375\375\375\337\337\337\364" + "\364\364\376\376\376\360\360\360\344\344\344\375\375\375\342\342\342\363" + "\363\363\376\376\376\376\376\376\357\357\357\344\344\344\376\376\376\374" + "\374\374\332\332\332\306\306\306\340\340\340\375\375\375\351\351\351\354" + "\354\354\376\376\376\370\370\370\333\333\333\375\375\375\376\376\376\376" + "\376\376\376\376\376\375\375\375\334\334\334\367\367\367\376\376\376\376" + "\376\376\357\357\357\343\343\343\376\376\376\374\374\374\336\336\336\305" + "\305\305\326\326\326\373\373\373\375\375\375\332\332\332\371\371\371\370" + "\370\370\334\334\334\375\375\375\375\375\375\342\342\342\361\361\361\376" + "\376\376\361\361\361\313\313\313\310\310\310\357\357\357\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\373" + "\374\375|\243\314\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264" + "\000l\264\000l\264\001l\264\066y\270\237\271\326\327\344\356\366\370\372\372\373" + "\375\372\373\374\363\367\371\322\340\354\221\260\321+u\267\001l\264\000l\264" + "\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\067z\271\346\356\365\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\276\316\343\005l\263" + "\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\040" + "q\265\203\246\315\314\333\352\360\365\370\372\373\374\372\373\375\370\371" + "\373\335\350\361\253\302\332C\200\273\003l\264\000l\264\000l\264\000l\264\000l\264" + "\000l\264\000l\264\000l\264\000l\264\026n\264\304\325\345\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\274\315\340\005l\264\000l\264\000l\264\000l" + "\264\000l\264\000l\264\000l\264\065y\270\356\364\367\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\374" + "\375\376\223\261\322\000k\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264U\216" + "\300\372\373\375\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\373\374" + "\375|\243\314\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l" + "\264\004l\264i\225\304\337\350\361\375\375\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\374\375\375\325\341\355U\211" + "\277\002l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\006l\264\260\305" + "\334\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\276\316" + "\343\005l\263\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\001l\264" + "@~\271\307\327\346\373\374\375\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\375\376\376\350\357\364\177\243\312\011l\264" + "\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\001l\264s\235\307\373\374" + "\375\376\376\376\376\376\376\376\376\376\376\376\376\274\315\340\005l\264\000" + "l\264\000l\264\000l\264\000l\264\000l\264\000l\264\065y\270\356\364\367\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\374\375\376\223\261\322\000k\264\000l\264\000l\264\000l\264\000l\264\000" + "l\264\000l\264U\216\300\372\373\375\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\373\374\375|\243\314\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000" + "l\264\000l\264\002l\264g\224\303\353\361\367\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\343\354\362O\206\275\001l\264\000l\264\000l\264\000l\264\000l\264" + "\000l\264\000l\264\000l\264a\223\303\372\373\374\376\376\376\376\376\376\376\376" + "\376\376\376\376\276\316\343\005l\263\000l\264\000l\264\000l\264\000l\264\000l\264\000" + "l\264\000l\264\000l\264\071z\271\327\342\355\375\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\363\367\372\202\244\313\004l\264\000l\264\000l\264\000l\264\000l\264\000" + "l\264\000l\264\000l\264/v\267\344\355\364\376\376\376\376\376\376\376\376\376" + "\376\376\376\274\315\340\005l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264" + "\065y\270\356\364\367\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\374\375\376\223\261\322\000k\264" + "\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264U\216\300\372\373\375\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\373\374\375|\243\314\000l\264\000l\264\000" + "l\264\000l\264\000l\264\000l\264\000l\264\000l\264\062x\270\335\347\360\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\315\334\351" + "\"q\266\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264/v\267\345\356\364" + "\376\376\376\376\376\376\376\376\376\376\376\376\276\316\343\005l\263\000l\264" + "\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\023m\264\267\314\340\375\375\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\352\360\366" + "J\204\275\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\016m\264\301\323" + "\344\376\376\376\376\376\376\376\376\376\376\376\376\274\315\340\005l\264\000" + "l\264\000l\264\000l\264\000l\264\000l\264\000l\264\065y\270\356\364\367\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\374\375\376\223\261\322\000k\264\000l\264\000l\264\000l\264\000l\264\000" + "l\264\000l\264U\216\300\372\373\375\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\367\367\367\374\374\374\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\371\371\371\371\371\371\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\375\375\375\376" + "\376\376\375\375\375\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\373\374\375|\243\314\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000" + "l\264\002l\264\232\266\324\374\375\375\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\373\374\375~\243\313\000l\264\000l\264\000" + "l\264\000l\264\000l\264\000l\264\000l\264\025m\264\311\331\351\376\376\376\376\376" + "\376\376\376\376\376\376\376\276\316\343\005l\263\000l\264\000l\264\000l\264\000l\264" + "\000l\264\000l\264\000l\264\\\217\301\366\371\372\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\375\376\376\264\311\336\013l\264" + "\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\001l\264\240\271\326\375\376\376" + "\376\376\376\376\376\376\376\376\376\274\315\340\005l\264\000l\264\000l\264\000l" + "\264\000l\264\000l\264\000l\264\065y\270\356\364\367\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\374" + "\375\376\223\261\322\000k\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264U\216" + "\300\372\373\375\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\375\375" + "\375\315\315\315\340\340\340\376\376\376\376\376\376\374\374\374\273\273" + "\273\362\362\362\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\373\373\373\205\205\205\326\326\326\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\270\270\270\262\262\262\375\375\375\376\376\376\374\374" + "\374\376\376\376\376\376\376\351\351\351\262\262\262\364\364\364\252\252" + "\252\370\370\370\376\376\376\375\375\375\374\374\374\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\373\374" + "\375|\243\314\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\"q\265\325" + "\343\356\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\375\305\326\346\023m\264\000l\264\000l\264\000l\264" + "\000l\264\000l\264\000l\264\005l\264\272\313\341\376\376\376\376\376\376\376\376" + "\376\376\376\376\276\316\343\005l\263\000l\264\000l\264\000l\264\000l\264\000l\264\000" + "l\264\005l\264\261\306\334\376\376\375\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\351\360\366\064x\270\000l\264" + "\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264x\242\312\373\374\375\376\376\376" + "\376\376\376\376\376\376\274\315\340\005l\264\000l\264\000l\264\000l\264\000l\264\000" + "l\264\000l\264\065y\270\356\364\367\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\374\375\376\223" + "\261\322\000k\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264U\216\300\372\373" + "\375\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\375\375\375\236\236" + "\236\306\306\306\376\376\376\376\376\376\373\373\373lll\350\350\350\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\355\355\355\372\372\372\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\375\375\375\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\375\375\375\376\376\376\376\376\376\364\364" + "\364\363\363\363\376\376\376\353\353\353\224\224\224\374\374\374\376\376" + "\376\363\363\363\324\324\324\370\370\370\320\320\320\373\373\373\376\376" + "\376\306\306\306\312\312\312\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\373\374\375|\243\314\000l\264\000l\264" + "\000l\264\000l\264\000l\264\000l\264\000l\264B\201\274\366\370\373\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\347\357\365\060v\267\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\001" + "l\264\252\300\331\375\376\376\376\376\376\376\376\376\376\376\376\276\316" + "\343\005l\263\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\036o\264\322\341\355" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\372\374\375a\224\304\000l\264\000l\264\000l\264\000l\264" + "\000l\264\000l\264\000l\264^\223\304\373\374\375\376\376\376\376\376\376\376\376" + "\376\274\315\340\005l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\065y\270" + "\356\364\367\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\374\375\376\223\261\322\000k\264\000l\264" + "\000l\264\000l\264\000l\264\000l\264\000l\264U\216\300\372\373\375\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\375\375\375\236\236\236\306\306\306\376" + "\376\376\376\376\376\373\373\373lll\350\350\350\367\367\367\313\313\313\332" + "\332\332\261\261\261\303\303\303\371\371\371\375\375\375\321\321\321\356" + "\356\356\343\343\343\333\333\333\376\376\376\376\376\376\343\343\343\346" + "\346\346\374\374\374\317\317\317\262\262\262\316\316\316\374\374\374\374" + "\374\374\312\312\312\333\333\333\273\273\273\357\357\357\363\363\363\300" + "\300\300\264\264\264\334\334\334\376\376\376\343\343\343\341\341\341\371" + "\371\371\264\264\264^^^\305\305\305\371\371\371\367\367\367\303\303\303\262" + "\262\262\315\315\315\374\374\374\350\350\350\215\215\215\225\225\225\330" + "\330\330\375\375\375\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\373\374\375|\243\314\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000" + "l\264^\222\304\373\374\375\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\367\372\373B\202\274\000l" + "\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\241\272\327\375\376\376\376" + "\376\376\376\376\376\376\376\376\276\316\343\005l\263\000l\264\000l\264\000l\264" + "\000l\264\000l\264\000l\264/u\267\347\357\365\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\374\375\375" + "\210\253\317\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264U\215\303\372" + "\373\375\376\376\376\376\376\376\376\376\376\274\315\340\005l\264\000l\264\000" + "l\264\000l\264\000l\264\000l\264\000l\264\065y\270\356\364\367\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\374\375\376\223\261\322\000k\264\000l\264\000l\264\000l\264\000l\264\000l\264\000" + "l\264U\216\300\372\373\375\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\375\375\375\236\236\236\306\306\306\376\376\376\376\376\376\373\373\373" + "lll\350\350\350\362\362\362SSS\247\247\247\330\330\330\177\177\177\316\316" + "\316\373\373\373|||\327\327\327\335\335\335sss\371\371\371\373\373\373\213" + "\213\213\342\342\342\301\301\301\233\233\233\346\346\346\222\222\222\321" + "\321\321\373\373\373ccc\250\250\250\276\276\276\336\336\336\256\256\256\267" + "\267\267\350\350\350\337\337\337\376\376\376\272\272\272\265\265\265\373" + "\373\373\306\306\306ggg\327\327\327\373\373\373\320\320\320\271\271\271\346" + "\346\346uuu\342\342\342\360\360\360\235\235\235\244\244\244\345\345\345\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\373" + "\374\375|\243\314\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264i\231\307" + "\373\374\375\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\372\373\374I\207\277\000l\264\000l\264\000" + "l\264\000l\264\000l\264\000l\264\000l\264\240\271\326\375\376\376\376\376\376\376" + "\376\376\376\376\376\276\316\343\005l\263\000l\264\000l\264\000l\264\000l\264\000l\264" + "\000l\264\064x\270\355\363\370\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\374\375\376\224\262\323" + "\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264U\215\303\372\373\375\376" + "\376\376\376\376\376\376\376\376\274\315\340\005l\264\000l\264\000l\264\000l\264" + "\000l\264\000l\264\000l\264\062w\267\352\362\366\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\374\375" + "\376\213\255\317\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264V\216\301" + "\372\373\375\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\375\375\375" + "\236\236\236\306\306\306\376\376\376\376\376\376\373\373\373lll\350\350\350" + "\364\364\364___\361\361\361\376\376\376\255\255\255\303\303\303\374\374\374" + "|||\327\327\327\373\373\373\201\201\201\330\330\330\345\345\345\220\220\220" + "\370\370\370uuu\260\260\260\314\314\314\235\235\235\256\256\256\372\372\372" + "mmm\344\344\344\375\375\375\375\375\375\271\271\271\203\203\203\320\320\320" + "\371\371\371\376\376\376\271\271\271\265\265\265\376\376\376\343\343\343" + "vvv\373\373\373\376\376\376\374\374\374\353\353\353\322\322\322vvv\332\332" + "\332\376\376\376\266\266\266\300\300\300\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\373\374\375|\243\314" + "\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264i\231\307\373\374\375\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\372\373\374J\207\277\000l\264\000l\264\000l\264\000l\264\000l" + "\264\000l\264\000l\264\240\271\327\375\376\376\376\376\376\376\376\376\376\376" + "\376\276\316\343\005l\263\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\065y\270" + "\356\364\370\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\374\375\376\225\262\323\000l\264\000l\264" + "\000l\264\000l\264\000l\264\000l\264\000l\264U\215\303\372\373\375\376\376\376\376" + "\376\376\376\376\376\277\320\343\007l\264\000l\264\000l\264\000l\264\000l\264\000l\264" + "\000l\264$q\265\331\346\360\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\373\374\375k\232\307\000l" + "\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\\\221\303\372\374\375\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\375\375\375\244\244\244\302" + "\302\302\376\376\376\376\376\376\372\372\372ggg\354\354\354\365\365\365d" + "dd\367\367\367\376\376\376\256\256\256\303\303\303\374\374\374|||\327\327" + "\327\376\376\376\306\306\306\243\243\243\265\265\265\317\317\317\373\373" + "\373iii\266\266\266\312\312\312\312\312\312\342\342\342\372\372\372ppp\355" + "\355\355\376\376\376\376\376\376\372\372\372\315\315\315\210\210\210\232" + "\232\232\374\374\374\271\271\271\265\265\265\376\376\376\343\343\343vvv\373" + "\373\373\376\376\376\312\312\312\224\224\224\307\307\307rrr\332\332\332\376" + "\376\376\266\266\266\300\300\300\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\373\374\375|\243\314\000l\264" + "\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264i\231\307\373\374\375\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\372\373\374J\207\277\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264" + "\000l\264\240\271\327\375\376\376\376\376\376\376\376\376\376\376\376\276\316" + "\343\005l\263\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\065y\270\356\364\370" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\374\375\376\225\262\323\000l\264\000l\264\000l\264\000l" + "\264\000l\264\000l\264\000l\264U\215\303\372\373\375\376\376\376\376\376\376\376" + "\376\376\305\326\347\020m\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\013" + "l\264\274\317\342\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\360\365\370=~\272\000l\264\000l\264" + "\000l\264\000l\264\000l\264\000l\264\000l\264q\236\310\373\374\375\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\307\307\307\212\212\212\366" + "\366\366\373\373\373\325\325\325rrr\371\371\371\364\364\364ddd\367\367\367" + "\376\376\376\256\256\256\303\303\303\374\374\374|||\327\327\327\376\376\376" + "\363\363\363iii|||\367\367\367\374\374\374\233\233\233\272\272\272\372\372" + "\372\353\353\353\337\337\337\372\372\372ooo\355\355\355\376\376\376\376\376" + "\376\343\343\343\365\365\365\342\342\342qqq\373\373\373\271\271\271\265\265" + "\265\376\376\376\345\345\345qqq\367\367\367\373\373\373\221\221\221\314\314" + "\314\360\360\360jjj\327\327\327\376\376\376\270\270\270\273\273\273\373\373" + "\373\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\373\374\375|\243\314\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264" + "i\231\307\373\374\375\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\372\373\374J\207\277\000l\264" + "\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\240\271\327\375\376\376\376\376" + "\376\376\376\376\376\376\376\276\316\343\005l\263\000l\264\000l\264\000l\264\000l\264" + "\000l\264\000l\264\065y\270\356\364\370\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\374\375\376\225" + "\262\323\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264U\215\303\372\373" + "\375\376\376\376\376\376\376\376\376\376\325\343\357!p\265\000l\264\000l\264" + "\000l\264\000l\264\000l\264\000l\264\000l\264v\236\310\372\374\374\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\303" + "\324\346\024m\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\230\264" + "\323\375\375\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\371\371\371\255\255\255}}}\205\205\205\205\205\205\336\336\336\376\376" + "\376\367\367\367\234\234\234\371\371\371\376\376\376\305\305\305\323\323" + "\323\374\374\374\247\247\247\342\342\342\376\376\376\375\375\375\264\264" + "\264\301\301\301\376\376\376\376\376\376\355\355\355\232\232\232\201\201" + "\201\230\230\230\347\347\347\373\373\373\241\241\241\362\362\362\376\376" + "\376\375\375\375\306\306\306\211\211\211\214\214\214\322\322\322\376\376" + "\376\315\315\315\311\311\311\376\376\376\367\367\367\217\217\217\215\215" + "\215\355\355\355\327\327\327}}}\232\232\232\261\261\261\225\225\225\372\372" + "\372\334\334\334zzz\257\257\257\374\374\374\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\373\374\375|\243\314\000l\264\000l\264\000l\264\000" + "l\264\000l\264\000l\264\000l\264i\231\307\373\374\375\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\372" + "\373\374J\207\277\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\240\271" + "\327\375\376\376\376\376\376\376\376\376\376\376\376\276\316\343\005l\263\000" + "l\264\000l\264\000l\264\000l\264\000l\264\000l\264\065y\270\356\364\370\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\374\375\376\225\262\323\000l\264\000l\264\000l\264\000l\264\000l\264\000" + "l\264\000l\264U\215\303\372\373\375\376\376\376\376\376\376\376\376\376\360" + "\365\371:|\272\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\"q\265\317" + "\335\352\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\364\370\372f\223\303\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000" + "l\264\010l\264\273\316\341\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\375\375\375\372\372\372\371\371\371" + "\373\373\373\376\376\376\376\376\376\376\376\376\374\374\374\376\376\376" + "\376\376\376\375\375\375\375\375\375\376\376\376\374\374\374\376\376\376" + "\376\376\376\376\376\376\375\375\375\375\375\375\376\376\376\376\376\376" + "\376\376\376\374\374\374\373\373\373\374\374\374\376\376\376\376\376\376" + "\374\374\374\376\376\376\376\376\376\376\376\376\375\375\375\373\373\373" + "\373\373\373\376\376\376\376\376\376\375\375\375\375\375\375\376\376\376" + "\376\376\376\374\374\374\373\373\373\376\376\376\376\376\376\373\373\373" + "\374\374\374\375\375\375\373\373\373\376\376\376\376\376\376\373\373\373" + "\374\374\374\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\373\374\375|\243\314\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264" + "\000l\264i\231\307\373\374\375\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\372\373\374J\207\277" + "\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\240\271\327\375\376\376" + "\376\376\376\376\376\376\376\376\376\276\316\343\005l\263\000l\264\000l\264\000l" + "\264\000l\264\000l\264\000l\264\065y\270\356\364\370\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\374" + "\375\376\225\262\323\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264U\215" + "\303\372\373\375\376\376\376\376\376\376\376\376\376\373\374\375r\235\310" + "\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264Y\213\277\350\357" + "\365\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\373\374\374\241\274" + "\327\015m\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264'r\265\333\347" + "\360\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\373\374" + "\375|\243\314\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264i\231\307\373" + "\374\375\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\372\373\374J\207\277\000l\264\000l\264\000l\264" + "\000l\264\000l\264\000l\264\000l\264\240\271\327\375\376\376\376\376\376\376\376" + "\376\376\376\376\276\316\343\005l\263\000l\264\000l\264\000l\264\000l\264\000l\264\000" + "l\264\065y\270\356\364\370\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\374\375\376\225\262\323" + "\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264U\215\303\372\373\375\376" + "\376\376\376\376\376\376\376\376\376\376\376\270\313\337\012l\264\000l\264\000" + "l\264\000l\264\000l\264\000l\264\000l\264\000l\264\003l\264j\225\304\343\354\363\375" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\367\371\373\245\276\331\034p\265\000l\264\000l\264\000l\264" + "\000l\264\000l\264\000l\264\000l\264\000l\264^\220\302\371\372\374\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\373\374\375|\243\314\000l\264" + "\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264i\231\307\373\374\375\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\372\373\374J\207\277\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264" + "\000l\264\240\271\327\375\376\376\376\376\376\376\376\376\376\376\376\276\316" + "\343\005l\263\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\065y\270\356\364\370" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\374\375\376\225\262\323\000l\264\000l\264\000l\264\000l" + "\264\000l\264\000l\264\000l\264U\215\303\372\373\375\376\376\376\376\376\376\376" + "\376\376\376\376\376\352\360\366;|\271\000l\264\000l\264\000l\264\000l\264\000l\264" + "\000l\264\000l\264\000l\264\002l\264B\177\273\261\307\335\353\361\366\373\374\375" + "\374\375\376\375\375\376\374\375\375\366\371\372\316\335\352s\234\307\021" + "n\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\013l\264\265" + "\311\337\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\375" + "\375\375\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\373\374\375|\243\314\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000" + "l\264i\231\307\373\374\375\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\372\373\374J\207\277\000l" + "\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\240\271\327\375\376\376\376" + "\376\376\376\376\376\376\376\376\276\316\343\005l\263\000l\264\000l\264\000l\264" + "\000l\264\000l\264\000l\264\065y\270\356\364\370\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\374\375" + "\376\225\262\323\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264U\215\303" + "\372\373\375\376\376\376\376\376\376\376\376\376\376\376\376\375\375\376" + "\240\272\326\005l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264" + "\000l\264\013l\264\070z\271m\232\307\224\262\322\232\266\323\201\246\314M\207" + "\276\035o\264\001l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264" + "\000l\264K\204\274\356\364\370\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\355\355\355\337\337\337\336\336" + "\336\355\355\355\374\374\374\376\376\376\376\376\376\376\376\376\362\362" + "\362\366\366\366\366\366\366\361\361\361\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\356\356\356\274\274\274\374\374\374\376\376" + "\376\376\376\376\376\376\376\375\375\375\312\312\312\347\347\347\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\373\373" + "\373\310\310\310\253\253\253\324\324\324\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\375\376\376\344\355\364\332\347" + "\361\332\346\361\332\347\361\332\347\361\332\347\361\332\347\361\332\347" + "\361\337\352\362\363\367\372\374\375\375\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\373\374\375|\243\314\000l\264\000l\264\000l\264\000" + "l\264\000l\264\000l\264\000l\264i\231\307\373\374\375\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\372" + "\373\374J\207\277\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\240\271" + "\327\375\376\376\376\376\376\376\376\376\376\376\376\276\316\343\005l\263\000" + "l\264\000l\264\000l\264\000l\264\000l\264\000l\264\065y\270\356\364\370\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\374\375\376\225\262\323\000l\264\000l\264\000l\264\000l\264\000l\264\000" + "l\264\000l\264U\215\303\372\373\375\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\352\361\366J\203\274\001l\264\000l\264\000l\264\000l\264\000l" + "\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264" + "\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000" + "l\264\025n\264\272\315\340\375\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\375\375\375\242\242\242\230\230\230" + "\274\274\274\231\231\231\221\221\221\353\353\353\376\376\376\375\375\375" + "\266\266\266\313\313\313\316\316\316\260\260\260\375\375\375\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\341\341\341qqq\373\373\373\376\376\376" + "\376\376\376\376\376\376\374\374\374\230\230\230\324\324\324\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\320\320\320" + "\234\234\234\360\360\360\354\354\354\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\373\374\375{\242\312%q\265%q\265%q\265" + "%q\265%q\265%q\265%q\265(r\265B\200\273\225\263\323\346\355\364\375\376\376" + "\376\376\376\376\376\376\376\376\376\373\374\375|\243\314\000l\264\000l\264\000" + "l\264\000l\264\000l\264\000l\264\000l\264i\231\307\373\374\375\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\372\373\374J\207\277\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264" + "\240\271\327\375\376\376\376\376\376\376\376\376\376\376\376\276\316\343" + "\005l\263\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\065y\270\356\364\370\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\374\375\376\225\262\323\000l\264\000l\264\000l\264\000l\264" + "\000l\264\000l\264\000l\264U\215\303\372\373\375\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\305\325\346#q\266\000l\264\000l\264" + "\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000" + "l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264" + "\000l\264\003l\264\201\245\313\370\372\373\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\375\375\375\240\240\240" + "\306\306\306\376\376\376\373\373\373\273\273\273\210\210\210\373\373\373" + "\375\375\375\371\371\371\374\374\374\375\375\375\372\372\372\375\375\375" + "\376\376\376\375\375\375\367\367\367\370\370\370\375\375\375\376\376\376" + "\374\374\374\366\366\366\370\370\370\375\375\375\376\376\376\376\376\376" + "\371\371\371\367\367\367\375\375\375\376\376\376\341\341\341qqq\373\373\373" + "\376\376\376\374\374\374\367\367\367\370\370\370\230\230\230\324\324\324" + "\376\376\376\375\375\375\371\371\371\366\366\366\373\373\373\376\376\376" + "\376\376\376\374\374\374\374\374\374\371\371\371\375\375\375\374\374\374" + "\265\265\265\276\276\276\373\373\373\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\373\374\375w\240\312\000l" + "\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\003l\264H\201" + "\274\325\341\354\376\376\376\376\376\376\376\376\376\373\374\375|\243\314" + "\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264i\231\307\373\374\375\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\372\373\374J\207\277\000l\264\000l\264\000l\264\000l\264\000l" + "\264\000l\264\000l\264\240\271\327\375\376\376\376\376\376\376\376\376\376\376" + "\376\276\316\343\005l\263\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\065y\270" + "\356\364\370\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\374\375\376\225\262\323\000l\264\000l\264" + "\000l\264\000l\264\000l\264\000l\264\000l\264U\215\303\372\373\375\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\373\374\375\244" + "\276\331\024n\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264" + "\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000" + "l\264\000l\264\000l\264\000l\264\001l\264_\217\301\352\360\366\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\375\375\375\241\241\241\305\305\305\376\376\376\376\376\376\362\362" + "\362ZZZ\347\347\347\340\340\340\224\224\224\374\374\374\374\374\374\234\234" + "\234\333\333\333\374\374\374\252\252\252\236\236\236\222\222\222\343\343" + "\343\373\373\373\242\242\242\241\241\241\220\220\220\351\351\351\375\375" + "\375\314\314\314\211\211\211\221\221\221\264\264\264\374\374\374\341\341" + "\341qqq\373\373\373\370\370\370\242\242\242\207\207\207\216\216\216ttt\324" + "\324\324\375\375\375\307\307\307\202\202\202\225\225\225\216\216\216\353" + "\353\353\374\374\374\240\240\240\241\241\241~~~\276\276\276\324\324\324h" + "hhnnn\244\244\244\374\374\374\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\373\374\375w\240\312\000l\264\000l\264\000l\264\000" + "l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\001l\264J\203\274\347\356\364" + "\376\376\376\376\376\376\373\374\375|\243\314\000l\264\000l\264\000l\264\000l\264" + "\000l\264\000l\264\000l\264i\231\307\373\374\375\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\372\373" + "\374J\207\277\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\240\271\327" + "\375\376\376\376\376\376\376\376\376\376\376\376\276\316\343\005l\263\000l\264" + "\000l\264\000l\264\000l\264\000l\264\000l\264\065y\270\356\364\370\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\374\375\376\225\262\323\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000" + "l\264U\215\303\372\373\375\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\372\373\374\235\270\325\030n\264\000l\264" + "\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000" + "l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\003l\264\\\215" + "\300\344\354\363\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\375\375\375\243\243" + "\243\305\305\305\376\376\376\376\376\376\372\372\372ccc\330\330\330\332\332" + "\332|||\373\373\373\374\374\374\210\207\207\324\324\324\364\364\364ddd\353" + "\353\353\371\371\371\375\375\375\355\355\355ggg\356\356\356\371\371\371\375" + "\375\375\355\355\355lll\354\354\354\364\364\364ppp\352\352\352\341\341\341" + "qqq\373\373\373\307\307\307\222\222\222\371\371\371\362\362\362jjj\324\324" + "\324\352\352\352ddd\354\354\354\373\373\373\271\271\271\234\234\234\373\373" + "\373\231\231\231\257\257\257\362\362\362\354\354\354\374\374\374\265\265" + "\265\300\300\300\374\374\374\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\373\374\375w\240\312\000l\264\000l\264" + "\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\003l\264\235" + "\270\325\375\375\376\376\376\376\373\374\375|\243\314\000l\264\000l\264\000l\264" + "\000l\264\000l\264\000l\264\000l\264i\231\307\373\374\375\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\372\373\374J\207\277\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\240" + "\271\327\375\376\376\376\376\376\376\376\376\376\376\376\276\316\343\005l\263" + "\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\065y\270\356\364\370\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\374\375\376\225\262\323\000l\264\000l\264\000l\264\000l\264\000l\264\000" + "l\264\000l\264U\215\303\372\373\375\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\372\374\375\256" + "\305\334.u\267\001l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000" + "l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\017m" + "\264x\237\310\347\357\365\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\375\375\375\244\244\244\304\304\304\376\376\376\376\376\376\367\367\367" + "]]]\343\343\343\332\332\332|||\373\373\373\374\374\374\207\207\207\324\324" + "\324\374\374\374\257\257\257jjj\247\247\247\362\362\362\373\373\373\246\246" + "\246lll\254\254\254\365\365\365\322\322\322TTT\220\220\220\220\220\220mm" + "m\337\337\337\341\341\341qqq\372\372\372\246\246\246\301\301\301\376\376" + "\376\374\374\374\227\227\227\324\324\324\321\321\321zzz\373\373\373\376\376" + "\376\331\331\331nnn\371\371\371\233\233\233\315\315\315\376\376\376\376\376" + "\376\376\376\376\265\265\265\302\302\302\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\373\374" + "\375w\240\312\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l" + "\264\000l\264\000l\264\000l\264K\206\275\367\371\373\376\376\376\373\374\375|\243" + "\314\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264i\231\307\373\374\375" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\372\373\374J\207\277\000l\264\000l\264\000l\264\000l\264" + "\000l\264\000l\264\000l\264\240\271\327\375\376\376\376\376\376\376\376\376\376" + "\376\376\276\316\343\005l\263\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\065" + "y\270\356\364\370\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\374\375\376\225\262\323\000l\264\000" + "l\264\000l\264\000l\264\000l\264\000l\264\000l\264U\215\303\372\373\375\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\374\375\375\326\341\355h\225\303\024n\264\000l\264" + "\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000" + "l\264\000l\264\000l\264\004l\263<{\271\256\304\334\365\371\373\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\375\375\375\244\244\244\304" + "\304\304\376\376\376\375\375\375\314\314\314\177\177\177\372\372\372\333" + "\333\333zzz\373\373\373\372\372\372ttt\324\324\324\376\376\376\373\373\373" + "\356\356\356\227\227\227\273\273\273\376\376\376\373\373\373\353\353\353" + "\214\214\214\304\304\304\332\332\332www\366\366\366\372\372\372\371\371\371" + "\374\374\374\341\341\341qqq\372\372\372\263\263\263\262\262\262\376\376\376" + "\372\372\372\177\177\177\324\324\324\337\337\337jjj\370\370\370\376\376\376" + "\314\314\314\205\205\205\372\372\372\233\233\233\317\317\317\376\376\376" + "\376\376\376\376\376\376\265\265\265\302\302\302\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\373\374\375w\240\312\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000" + "l\264\000l\264\000l\264\000l\264\000l\264\061v\267\351\361\366\376\376\376\373\374" + "\375}\244\314\031n\264\031n\264\031n\264\031n\264\031n\264\031n\264\031n\264l\231" + "\307\373\374\375\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\372\373\374N\210\277\031n\264\031" + "n\264\031n\264\031n\264\031n\264\031n\264\031m\264\241\271\326\375\376\376\376" + "\376\376\376\376\376\376\376\376\276\316\343\033m\264\031n\264\031n\264\031n" + "\264\031n\264\031n\264\031n\264;z\270\356\364\370\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\374" + "\375\376\226\263\323\031n\264\031n\264\031n\264\031n\264\031n\264\031n\264\031n" + "\264X\216\303\372\373\375\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\366\371\372\300\321\343e\224\304$q\265\004l\264\000l\264\000l\264" + "\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\001l\264\024m\264C\200\273\237\271" + "\326\346\355\364\375\375\375\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\375\375\375\246\246\246\231\231\231\306\306" + "\306\257\257\257\205\205\205\347\347\347\376\376\376\353\353\353ccc\303\303" + "\303\255\255\255___\320\320\320\365\365\365\245\245\245\324\324\324\232\232" + "\232\313\313\313\357\357\357\247\247\247\325\325\325\221\221\221\323\323" + "\323\370\370\370\205\205\205\262\262\262\314\314\314\237\237\237\353\353" + "\353\341\341\341rrr\373\373\373\343\343\343ooo\307\307\307\261\261\261\\" + "\\\\\320\320\320\373\373\373\231\231\231\246\246\246\307\307\307{{{\325\325" + "\325\374\374\374\234\234\234\317\317\317\376\376\376\376\376\376\376\376" + "\376\265\265\265\302\302\302\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\373\374\375w\240\312" + "\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000" + "l\264\000l\264\063x\267\354\362\367\376\376\376\375\376\376\333\347\361\314" + "\334\353\314\334\353\314\334\353\314\334\353\314\335\353\314\335\353\314" + "\334\353\330\344\357\375\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\375\375\375\323" + "\341\355\314\334\353\314\334\353\314\334\353\314\334\353\314\334\353\314" + "\334\353\314\334\353\342\353\363\376\376\376\376\376\376\376\376\376\376" + "\376\376\352\360\366\314\334\353\314\335\353\314\334\353\314\334\353\314" + "\334\353\314\334\353\314\334\353\317\336\354\371\373\374\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\375\376\376\337\352\362\314\334\353\314\334\353\314\334\353\314" + "\334\353\314\334\353\314\335\353\314\334\353\324\342\356\375\375\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\371\373\374\327\343\356\257\303\333t\237\311G\205\276\065y\270-t" + "\266+t\266\060v\267>~\273^\222\303\230\264\323\307\327\347\360\365\370\375" + "\375\375\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\344\344\344\316\316\316\315" + "\315\315\336\336\336\371\371\371\376\376\376\376\376\376\375\375\375\337" + "\337\337\303\303\303\333\333\333\340\340\340\357\357\357\374\374\374\332" + "\332\332\305\305\305\325\325\325\374\374\374\373\373\373\327\327\327\305" + "\305\305\330\330\330\374\374\374\376\376\376\363\363\363\312\312\312\305" + "\305\305\350\350\350\376\376\376\366\366\366\332\332\332\375\375\375\376" + "\376\376\345\345\345\304\304\304\327\327\327\340\340\340\357\357\357\376" + "\376\376\371\371\371\320\320\320\304\304\304\344\344\344\375\375\375\376" + "\376\376\342\342\342\360\360\360\376\376\376\376\376\376\376\376\376\350" + "\350\350\353\353\353\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\373\374\375w\240\312\000l\264" + "\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000" + "l\264X\215\301\371\373\374\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\373\374\375\370\372\373\355\363\370" + "\344\356\365\342\354\364\351\360\366\365\370\372\372\374\374\375\375\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\373\374\375w\240\312\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000" + "l\264\000l\264\000l\264\000l\264\012l\264\257\305\334\375\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\373\374\375w\240\312\000l\264\000l\264\000l\264" + "\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\002l\264i\224\303\361\365" + "\371\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\373\374" + "\375w\240\312\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l\264\000l" + "\264\021m\264o\230\305\346\356\364\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\374\374\375\206\253\316@\200\273@\200\273" + "@\200\273@\200\273@\200\273@\200\273@\200\273F\204\275r\235\310\274\316\341" + "\364\370\372\375\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\370\372\373\367\371\372\367\371\372" + "\367\371\372\367\371\372\367\371\372\367\371\372\367\371\372\371\373\373" + "\373\374\375\375\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376" + "\376\376\376\376\376\376\376\376\376", +}; diff --git a/src/kernel/event/KeyEventListener.cc b/src/kernel/event/KeyEventListener.cc new file mode 100644 index 0000000..ed10436 --- /dev/null +++ b/src/kernel/event/KeyEventListener.cc @@ -0,0 +1,12 @@ +#include "kernel/event/KeyEventListener.h" +#include "kernel/system/Globals.h" + +void KeyEventListener::trigger(char c) { + lastChar = c; +} + +char KeyEventListener::waitForKeyEvent() const { + Logger::instance() << DEBUG << "KEvLis:: Thread with id: " << tid << " waiting for key event" << endl; + scheduler.block(); + return lastChar; // This is only executed after thread is woken up by manager +} diff --git a/src/kernel/event/KeyEventListener.h b/src/kernel/event/KeyEventListener.h new file mode 100644 index 0000000..006921f --- /dev/null +++ b/src/kernel/event/KeyEventListener.h @@ -0,0 +1,22 @@ +#ifndef KeyEventListener_Include_H_ +#define KeyEventListener_Include_H_ + +#include "kernel/process/Thread.h" + +class KeyEventListener { +private: + char lastChar = '\0'; + + friend class KeyEventManager; + unsigned int tid; // Thread which contains this listener, so the listener can block the thread + +public: + KeyEventListener(const KeyEventListener& copy) = delete; + + KeyEventListener(unsigned int tid) : tid(tid) {} + + char waitForKeyEvent() const; // Blocks the thread until woken up by manager + void trigger(char c); // Gets called from KeyEventManager +}; + +#endif diff --git a/src/kernel/event/KeyEventManager.cc b/src/kernel/event/KeyEventManager.cc new file mode 100644 index 0000000..9d325c4 --- /dev/null +++ b/src/kernel/event/KeyEventManager.cc @@ -0,0 +1,26 @@ +#include "KeyEventManager.h" +#include "kernel/system/Globals.h" + +void KeyEventManager::subscribe(KeyEventListener& sub) { + log.debug() << "Subscribe, Thread ID: " << dec << sub.tid << endl; + listeners.push_back(&sub); +} + +void KeyEventManager::unsubscribe(KeyEventListener& unsub) { + log.debug() << "Unsubscribe, Thread ID: " << dec << unsub.tid << endl; + for (bse::vector::iterator it = listeners.begin(); it != listeners.end(); ++it) { + if ((*it)->tid == unsub.tid) { + listeners.erase(it); + return; + } + } +} + +void KeyEventManager::broadcast(char c) { + log.trace() << "Beginning Broadcast" << endl; + for (KeyEventListener* listener : listeners) { + log.trace() << "Broadcasting " << c << " to Thread ID: " << dec << listener->tid << endl; + listener->trigger(c); + scheduler.deblock(listener->tid); + } +} diff --git a/src/kernel/event/KeyEventManager.h b/src/kernel/event/KeyEventManager.h new file mode 100644 index 0000000..b3f7ce9 --- /dev/null +++ b/src/kernel/event/KeyEventManager.h @@ -0,0 +1,31 @@ +#ifndef KeyEventManager_Include_H_ +#define KeyEventManager_Include_H_ + +#include "kernel/event/KeyEventListener.h" +#include "kernel/log/Logger.h" +#include "lib/util/Vector.h" + +// NOTE: Could do this more generally but we only have key events +// Also pretty limited: One thread can have one listener as identification is done over tid + +class KeyEventManager { +private: + NamedLogger log; + + bse::vector listeners; + +public: + KeyEventManager(const KeyEventManager& copy) = delete; + + KeyEventManager() : log("KEvMan"), listeners(true) {} + + void init() { + listeners.reserve(); + } + + void subscribe(KeyEventListener& sub); + void unsubscribe(KeyEventListener& unsub); + void broadcast(char c); // Unblocks all input waiting threads, I don't have a method to direct input +}; + +#endif diff --git a/src/kernel/interrupt/Bluescreen.cc b/src/kernel/interrupt/Bluescreen.cc new file mode 100644 index 0000000..33aee63 --- /dev/null +++ b/src/kernel/interrupt/Bluescreen.cc @@ -0,0 +1,305 @@ +/***************************************************************************** + * * + * B L U E S C R E E N * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Ein Bluescreen, falls eine x86 Exception auftritt. Evt. * + * ist der Stack und oder Heap kaputt, weswegen hier nicht * + * kout etc. verwendet wird. * + * * + * Autor: Michael Schoettner, 11.12.2018 * + *****************************************************************************/ +#include "kernel/system/Globals.h" + +// in startup.asm +extern "C" { + // CR2 auslesen + unsigned int get_page_fault_address(); + + // 1st level interrupt handler in startup.asm sichert Zeiger auf Stackframe + // unmittelbar nach dem Interrupt und nachdem alle Register mit PUSHAD + // gesichert wurden + // |-------------| + // |  EFLAGS | + // |-------------| + // | CS | + // |-------------| + // | EIP | + // |-------------| + // | [ErrorCode] | + // |-------------| + // | EAX | + // |-------------| + // | ECX | + // |-------------| + // | EDX | + // |-------------| + // | EBX | + // |-------------| + // | ESP | + // |-------------| + // | EBP | + // |-------------| + // | ESI | + // |-------------| + // | EDI | + // |-------------| <-- int_esp + + void get_int_esp(unsigned int** esp); +} + +void break_on_bluescreen() { + + /* wenn auf diese Methode ein breakpoint in GDB gesetzt wird + so kann man sich mithilfe des Hex-Dumps umsehen + */ +} + +// Cursor-Position +int bs_xpos = 0; +int bs_ypos = 0; + +/***************************************************************************** + * Funktion: bs_clear * + *---------------------------------------------------------------------------* + * Beschreibung: Bildschirm loeschen. * + *****************************************************************************/ +void bs_clear() { + unsigned int x; + unsigned int y; + unsigned short* ptr = reinterpret_cast(0xb8000); + + for (x = 0; x < 80; x++) { + for (y = 0; y < 25; y++) { + *(ptr + y * 80 + x) = static_cast(0x1F00); + } + } + + bs_xpos = 0; + bs_ypos = 0; +} + +/***************************************************************************** + * Funktion: bs_lf * + *---------------------------------------------------------------------------* + * Beschreibung: Zeilenvorschub. * + *****************************************************************************/ +void bs_lf() { + bs_ypos++; + bs_xpos = 0; +} + +/***************************************************************************** + * Funktion: bs_print_char * + *---------------------------------------------------------------------------* + * Beschreibung: Ein Zeichen ausgeben. * + *****************************************************************************/ +void bs_print_char(char c) { + unsigned char* ptr = reinterpret_cast(0xb8000); + + *(ptr + bs_ypos * 80 * 2 + bs_xpos * 2) = c; + bs_xpos++; +} + +/***************************************************************************** + * Funktion: bs_print_string * + *---------------------------------------------------------------------------* + * Beschreibung: Eine Zeichenkette ausgeben. * + *****************************************************************************/ +void bs_print_string(char* str) { + + while (*str != '\0') { + bs_print_char(*str); + str++; + } +} + +/***************************************************************************** + * Funktion: bs_printHexDigit * + *---------------------------------------------------------------------------* + * Beschreibung: Ein Hex-Zeichen ausgeben. * + *****************************************************************************/ +void bs_printHexDigit(int c) { + if (c < 10) { + bs_print_char('0' + static_cast(c)); + } else { + bs_print_char('A' + static_cast(c - 10)); + } +} + +/***************************************************************************** + * Funktion: bs_print_uintHex * + *---------------------------------------------------------------------------* + * Beschreibung: Integer ausgeben. * + *****************************************************************************/ +void bs_print_uintHex(unsigned int c) { + for (int i = 28; i >= 0; i = i - 4) { + bs_printHexDigit((c >> i) & 0xF); + } +} + +/***************************************************************************** + * Funktion: bs_printReg * + *---------------------------------------------------------------------------* + * Beschreibung: String mit Integer ausgeben. Wird verwendet um ein * + * Register auszugeben. * + *****************************************************************************/ +void bs_printReg(char* str, unsigned int value) { + bs_print_string(str); + bs_print_uintHex(value); + bs_print_string(" \0"); +} + +/***************************************************************************** + * Funktion: bs_dump * + *---------------------------------------------------------------------------* + * Beschreibung: Hauptroutine des Bluescreens. * + *****************************************************************************/ +void bs_dump(unsigned int exceptionNr) { + unsigned int* int_esp; + unsigned int* sptr; + unsigned int faultAdress; + unsigned int has_error_code = 0; + + bs_clear(); + bs_print_string("HHUos crashed with Exception \0"); + + // Exception mit Error-Code? + if ((exceptionNr >= 8 && exceptionNr <= 14) || exceptionNr == 17 || exceptionNr == 30) { + has_error_code = 1; + } + + // Liegt ein Page-Fault vor? + if (exceptionNr == 14) { + faultAdress = get_page_fault_address(); + // Zugriff auf Seite 0 ? -> Null-Ptr. Exception + if ((faultAdress & 0xFFFFF000) == 0) { + exceptionNr = 0x1B; + } + } + + bs_print_uintHex(exceptionNr); + bs_print_string(" (\0"); + + // Spruch ausgeben + switch (exceptionNr) { + case 0x00: bs_print_string("Divide Error\0"); break; + case 0x01: bs_print_string("Debug Exception\0"); break; + case 0x02: bs_print_string("NMI\0"); break; + case 0x03: bs_print_string("Breakpoint Exception\0"); break; + case 0x04: bs_print_string("Into Exception\0"); break; + case 0x05: bs_print_string("Index out of range Exception\0"); break; + case 0x06: bs_print_string("Invalid Opcode\0"); break; + case 0x08: bs_print_string("Double Fault\0"); break; + case 0x0D: bs_print_string("General Protection Error\0"); break; + case 0x0E: bs_print_string("Page Fault\0"); break; + case 0x18: bs_print_string("Stack invalid\0"); break; + case 0x19: bs_print_string("Return missing\0"); break; + case 0x1A: bs_print_string("Type Test Failed\0"); break; + case 0x1B: bs_print_string("Null pointer exception\0"); break; + case 0x1C: bs_print_string("MAGIC.StackTest failed\0"); break; + case 0x1D: bs_print_string("Memory-Panic\0"); break; + case 0x1E: bs_print_string("Pageload failed\0"); break; + case 0x1F: bs_print_string("Stack overflow\0"); break; + default: bs_print_string("unknown\0"); + } + bs_print_string(")\0"); + bs_lf(); + + // Zeiger auf int_esp ueber startup.asm beschaffen (Stack-Layout siehe Anfang dieser Datei) + get_int_esp(&int_esp); + + // wir müssen den Inhalt auslesen und das als Zeiger verwenden, um den Stack auszulesen + sptr = reinterpret_cast(*int_esp); + + bs_lf(); + + // wichtigste Register ausgeben + + // Exception mit Error-Code? + bs_printReg("EIP=\0", *(sptr + 8 + has_error_code)); + bs_printReg("EBP=\0", *(sptr + 2)); + bs_printReg("ESP=\0", *(sptr + 3)); + bs_printReg(" CS=\0", *(sptr + 9 + has_error_code)); + bs_lf(); + + // verbleibende nicht-fluechtige Register ausgeben + bs_printReg("EBX=\0", *(sptr + 4)); + bs_printReg("ESI=\0", *(sptr + 1)); + bs_printReg("EDI=\0", *(sptr)); + bs_lf(); + + // verbleibende fluechtige Register ausgeben + bs_printReg("EDX=\0", *(sptr + 5)); + bs_printReg("ECX=\0", *(sptr + 6)); + bs_printReg("EAX=\0", *(sptr + 7)); + bs_printReg("EFL=\0", *(sptr + 10)); + bs_lf(); + + // Pagefault oder Null-Pointer? + if (exceptionNr == 14 || exceptionNr == 0x1B) { + bs_lf(); + bs_print_string("Fault address = \0"); + bs_print_uintHex(faultAdress); + bs_lf(); + + bs_print_string("Last useable address = \0"); + bs_print_uintHex(total_mem - 1); + + bs_lf(); + } + + // Exception mit Error-Code? + if (has_error_code == 1) { + unsigned int error_nr = *(sptr + 8); + + if (exceptionNr == 14) { + if (error_nr == 3) { + bs_print_string("Error: write access to read-only page.\0"); + } else if (error_nr == 2) { + bs_print_string("Error: read access to not-present page.\0"); + } else if (error_nr == 0) { + bs_print_string("Error: access to a not-present page.\0"); + } else { + bs_print_string("Error code = \0"); + bs_print_uintHex(error_nr); + } + bs_lf(); + } else { + bs_print_string("Error code = \0"); + bs_print_uintHex(error_nr); + bs_lf(); + } + } + + // Calling stack ... + bs_lf(); + bs_print_string("Calling Stack:\0"); + bs_lf(); + int x = 0; + unsigned int* ebp = reinterpret_cast(*(sptr + 2)); + unsigned int raddr; + + // solange eip > 1 MB && ebp < 128 MB, max. Aufruftiefe 10 + while (*ebp > 0x100000 && *ebp < 0x8000000 && x < 10) { + + raddr = *(ebp + 1); + bs_printReg(" raddr=\0", raddr); + bs_lf(); + + // dynamische Kette -> zum Aufrufer + ebp = reinterpret_cast(*ebp); + + x++; + } + if (x == 0) { + bs_print_string(" empty\0"); + bs_lf(); + } + bs_lf(); + + // nur falls gdb benutzt werden soll + break_on_bluescreen(); + + bs_print_string("System halted\0"); +} diff --git a/src/kernel/interrupt/Bluescreen.h b/src/kernel/interrupt/Bluescreen.h new file mode 100644 index 0000000..0c9c215 --- /dev/null +++ b/src/kernel/interrupt/Bluescreen.h @@ -0,0 +1,19 @@ +/***************************************************************************** + * * + * B L U E S C R E E N * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Ein Bluescreen, falls eine x86 Exception auftritt. Evt. * + * ist der Stack und oder Heap kaputt, weswegen hier nicht * + * kout etc. verwendet wird. * + * * + * Autor: Michael Schoettner, 2.2.2017 * + *****************************************************************************/ + +#ifndef Bluescreen_include__ +#define Bluescreen_include__ + +// dump blue screen (will not return) +void bs_dump(unsigned int exceptionNr); + +#endif diff --git a/src/kernel/interrupt/ISR.h b/src/kernel/interrupt/ISR.h new file mode 100755 index 0000000..ce8bdcd --- /dev/null +++ b/src/kernel/interrupt/ISR.h @@ -0,0 +1,27 @@ +/***************************************************************************** + * * + * I S R * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Interrupt Service Routine. Jeweils ein Objekt pro ISR. * + * Erlaubt es einen Kontext mit Variablen fuer die Unter- * + * brechungsroutine bereitzustellen. * + * * + * Autor: Michael Schoettner, 06.04.20 * +*****************************************************************************/ +#ifndef ISR_include__ +#define ISR_include__ + +class ISR { +public: + ISR(const ISR& copy) = delete; // Verhindere Kopieren + +// virtual ~ISR() = default; + + ISR() = default; + + // Unterbrechungsbehandlungsroutine + virtual void trigger() = 0; +}; + +#endif diff --git a/src/kernel/interrupt/IntDispatcher.cc b/src/kernel/interrupt/IntDispatcher.cc new file mode 100755 index 0000000..57b5f2d --- /dev/null +++ b/src/kernel/interrupt/IntDispatcher.cc @@ -0,0 +1,109 @@ +/***************************************************************************** + * * + * I N T D I S P A T C H E R * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Zentrale Unterbrechungsbehandlungsroutine des Systems. * + * Der Parameter gibt die Nummer des aufgetretenen * + * Interrupts an. Wenn eine Interrupt Service Routine * + * registriert ist, wird diese aufgerufen. * + * * + * Autor: Michael Schoettner, 31.8.2016 * + *****************************************************************************/ +#include "IntDispatcher.h" +#include "device/cpu/CPU.h" +#include "kernel/system/Globals.h" +#include "kernel/interrupt/Bluescreen.h" + +extern "C" void int_disp(unsigned int vector); + +/***************************************************************************** + * Prozedur: int_disp * + *---------------------------------------------------------------------------* + * Beschreibung: Low-Level Interrupt-Behandlung. * + * Diese Funktion ist in der IDT fuer alle Eintraege einge- * + * tragen. Dies geschieht bereits im Bootloader. * + * Sie wird also fuer alle Interrupts aufgerufen. Von hier * + * aus sollen die passenden ISR-Routinen der Treiber-Objekte* + * mithilfe von 'IntDispatcher::report' aufgerufen werden. * + * Parameter: * + * vector: Vektor-Nummer der Unterbrechung * + *****************************************************************************/ +void int_disp(unsigned int vector) { + + /* hier muss Code eingefuegt werden */ + + if (vector < 32) { + bs_dump(vector); + CPU::halt(); + } + + if (intdis.report(vector) < 0) { + kout << "Panic: unexpected interrupt " << vector; + kout << " - processor halted." << endl; + CPU::halt(); + } +} + +/***************************************************************************** + * Methode: IntDispatcher::assign * + *---------------------------------------------------------------------------* + * Beschreibung: Registrierung einer ISR. * + * * + * Parameter: * + * vector: Vektor-Nummer der Unterbrechung * + * isr: ISR die registriert werden soll * + * * + * Rueckgabewert: 0 = Erfolg, -1 = Fehler * + *****************************************************************************/ +int IntDispatcher::assign(unsigned int vector, ISR& isr) { + + /* hier muss Code eingefuegt werden */ + + if (vector >= size) { + log.error() << "Invalid vector number when assigning" << endl; + return -1; + } + + map[vector] = &isr; + log.info() << "Registered ISR for vector " << dec << vector << endl; + + return 0; +} + +/***************************************************************************** + * Methode: IntDispatcher::report * + *---------------------------------------------------------------------------* + * Beschreibung: Eingetragene ISR ausfuehren. * + * * + * Parameter: * + * vector: Gesuchtes ISR-Objekt fuer diese Vektor-Nummer. * + * * + * Rueckgabewert: 0 = ISR wurde aufgerufen, -1 = unbekannte Vektor-Nummer * + *****************************************************************************/ +int IntDispatcher::report(unsigned int vector) { + + /* hier muss Code eingefuegt werden */ + + if (vector >= size) { + return -1; + } + + ISR* isr = map[vector]; + + if (isr == nullptr) { + log.error() << "No ISR registered for vector " << vector << endl; + return -1; + } + + // 32 = Timer + // 33 = Keyboard + // log.trace() << "Interrupt: " << dec << vector << endl; + if (vector == 33) { + log.debug() << "Keyboard Interrupt" << endl; + } + + isr->trigger(); + + return 0; +} diff --git a/src/kernel/interrupt/IntDispatcher.h b/src/kernel/interrupt/IntDispatcher.h new file mode 100755 index 0000000..57e43b0 --- /dev/null +++ b/src/kernel/interrupt/IntDispatcher.h @@ -0,0 +1,51 @@ +/***************************************************************************** + * * + * I N T D I S P A T C H E R * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Zentrale Unterbrechungsbehandlungsroutine des Systems. * + * Der Parameter gibt die Nummer des aufgetretenen * + * Interrupts an. Wenn eine Interrupt Service Routine (ISR) * + * in der Map registriert ist, so wird diese aufgerufen. * + * * + * Autor: Michael Schoettner, 30.7.16 * + *****************************************************************************/ +#ifndef IntDispatcher_include__ +#define IntDispatcher_include__ + +#include "ISR.h" +#include "lib/util/Array.h" +#include "kernel/log/Logger.h" + +class IntDispatcher { +private: + NamedLogger log; + + enum { size = 256 }; + bse::array map; + +public: + IntDispatcher(const IntDispatcher& copy) = delete; // Verhindere Kopieren + + // Vektor-Nummern + enum { + timer = 32, + keyboard = 33, + com1 = 36 + }; + + // Initialisierung der ISR map mit einer Default-ISR. + IntDispatcher() : log("IntDis") { + for (ISR*& slot : map) { + slot = nullptr; + } + } + + // Registrierung einer ISR. (Rueckgabewert: 0 = Erfolg, -1 = Fehler) + int assign(unsigned int vector, ISR& isr); + + // ISR fuer 'vector' ausfuehren + int report(unsigned int vector); +}; + +#endif diff --git a/src/kernel/log/Logger.cc b/src/kernel/log/Logger.cc new file mode 100644 index 0000000..3998ebd --- /dev/null +++ b/src/kernel/log/Logger.cc @@ -0,0 +1,117 @@ +#include "Logger.h" +#include "kernel/system/Globals.h" + +bool Logger::kout_enabled = true; +bool Logger::serial_enabled = true; + +Logger::LogLevel Logger::level = Logger::ERROR; + +constexpr const char* ansi_red = "\033[1;31m"; +constexpr const char* ansi_green = "\033[1;32m"; +constexpr const char* ansi_yellow = "\033[1;33m"; +constexpr const char* ansi_blue = "\033[1;34m"; +constexpr const char* ansi_magenta = "\033[1;35m"; +constexpr const char* ansi_cyan = "\033[1;36m"; +constexpr const char* ansi_white = "\033[1;37m"; +constexpr const char* ansi_default = "\033[0;39m "; + +void Logger::log(const bse::string_view message, CGA::color col) const { + if (Logger::kout_enabled) { + CGA::color old_col = kout.color_fg; + kout << fgc(col) + << Logger::level_to_string(current_message_level) << "::" + << message << fgc(old_col); + kout.flush(); // Don't add newline, Logger already does that + } + if (Logger::serial_enabled) { + switch (col) { + case CGA::WHITE: + SerialOut::write(ansi_white); + break; + case CGA::LIGHT_MAGENTA: + SerialOut::write(ansi_magenta); + break; + case CGA::LIGHT_RED: + SerialOut::write(ansi_red); + break; + case CGA::LIGHT_BLUE: + SerialOut::write(ansi_blue); + break; + default: + SerialOut::write(ansi_default); + } + SerialOut::write(Logger::level_to_string(current_message_level)); + SerialOut::write(":: "); + SerialOut::write(message); + SerialOut::write('\r'); + // serial.write("\r\n"); + } +} + +void Logger::flush() { + buffer[pos] = '\0'; + + switch (current_message_level) { + case Logger::TRACE: + trace(buffer.data()); + break; + case Logger::DEBUG: + debug(buffer.data()); + break; + case Logger::ERROR: + error(buffer.data()); + break; + case Logger::INFO: + info(buffer.data()); + break; + } + + current_message_level = Logger::INFO; + pos = 0; + Logger::unlock(); +} + +void Logger::trace(const bse::string_view message) const { + if (Logger::level <= Logger::TRACE) { + log(message, CGA::WHITE); + } +} + +void Logger::debug(const bse::string_view message) const { + if (Logger::level <= Logger::DEBUG) { + log(message, CGA::LIGHT_MAGENTA); + } +} + +void Logger::error(const bse::string_view message) const { + if (Logger::level <= Logger::ERROR) { + log(message, CGA::LIGHT_RED); + } +} + +void Logger::info(const bse::string_view message) const { + if (Logger::level <= Logger::INFO) { + log(message, CGA::LIGHT_BLUE); + } +} + +// Manipulatoren +Logger& TRACE(Logger& log) { + log.current_message_level = Logger::TRACE; + return log; +} + +Logger& DEBUG(Logger& log) { + log.current_message_level = Logger::DEBUG; + return log; +} + +Logger& ERROR(Logger& log) { + log.current_message_level = Logger::ERROR; + return log; +} + +Logger& INFO(Logger& log) { + log.current_message_level = Logger::INFO; + return log; +} diff --git a/src/kernel/log/Logger.h b/src/kernel/log/Logger.h new file mode 100644 index 0000000..6a523ea --- /dev/null +++ b/src/kernel/log/Logger.h @@ -0,0 +1,121 @@ +#ifndef Logger_Include_H_ +#define Logger_Include_H_ + +#include "device/graphics/CGA.h" +#include "lib/stream/OutStream.h" +#include "lib/async/SpinLock.h" +#include "lib/util/String.h" +#include "lib/util/StringView.h" + +class Logger : public OutStream { +public: + static Logger& instance() { + static Logger log; + return log; + } + +private: + Logger() = default; + + static bool kout_enabled; + static bool serial_enabled; + + void log(const bse::string_view message, CGA::color col) const; + + friend class NamedLogger; // Allow NamedLogger to lock/unlock + + SpinLock sem; // Semaphore would be a cyclic include + static void lock() { Logger::instance().sem.acquire(); } + static void unlock() { Logger::instance().sem.release(); } + // static void lock() {} + // static void unlock() {} + +public: +// ~Logger() override = default; + + Logger(const Logger& copy) = delete; + void operator=(const Logger& copy) = delete; + + enum LogLevel { + TRACE, + DEBUG, + ERROR, + INFO + }; + static LogLevel level; + LogLevel current_message_level = Logger::INFO; // Use this to log with manipulators + + void flush() override; + + void trace(const bse::string_view message) const; + void debug(const bse::string_view message) const; + void error(const bse::string_view message) const; + void info(const bse::string_view message) const; + + // TODO: Make lvl change accessible over menu + static void set_level(LogLevel lvl) { + Logger::level = lvl; + } + + static bse::string_view level_to_string(LogLevel lvl) { + switch (lvl) { + case Logger::TRACE: + return "TRACE"; + case Logger::DEBUG: + return "DEBUG"; + case Logger::ERROR: + return "ERROR"; + case Logger::INFO: + return "INFO"; + } + } + + static void enable_kout() { + Logger::kout_enabled = true; + } + static void disable_kout() { + Logger::kout_enabled = false; + } + static void enable_serial() { + Logger::serial_enabled = true; + } + static void disable_serial() { + Logger::serial_enabled = false; + } +}; + +// Manipulatoren +Logger& TRACE(Logger& log); +Logger& DEBUG(Logger& log); +Logger& ERROR(Logger& log); +Logger& INFO(Logger& log); + +class NamedLogger { +private: + const char* name; + +public: + explicit NamedLogger(const char* name) : name(name) {} + + Logger& trace() { + Logger::lock(); + return Logger::instance() << TRACE << name << "::"; + } + + Logger& debug() { + Logger::lock(); + return Logger::instance() << DEBUG << name << "::"; + } + + Logger& error() { + Logger::lock(); + return Logger::instance() << ERROR << name << "::"; + } + + Logger& info() { + Logger::lock(); + return Logger::instance() << INFO << name << "::"; + } +}; + +#endif diff --git a/src/kernel/memory/Allocator.cc b/src/kernel/memory/Allocator.cc new file mode 100755 index 0000000..20a988d --- /dev/null +++ b/src/kernel/memory/Allocator.cc @@ -0,0 +1,80 @@ +/***************************************************************************** + * * + * A L L O C A T O R * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Einfache Speicherverwaltung. 'new' und 'delete' werden * + * durch Ueberladen der entsprechenden Operatoren * + * realisiert. * + * * + * Memory-Laylout * + * * + * boot.asm * + * 0x07c0: Bootsector vom BIOS geladen * + * 0x0060: Boot-Code verschiebt sich hier hin * + * 0x9000: Setup-Code (max. 64K inkl. Stack) vom * + * Bootsector-Code geladen * + * setup.asm * + * 0x1000: System-Code (max. 512K) geladen * + * System-Code * + * 0x100000: System-Code, kopiert nach Umschalten in * + * den Protected Mode kopiert (GRUB kann nur * + * an Adressen >1M laden) * + * Globale Variablen: Direkt nach dem Code liegen die globalen * + * Variablen. * + * Heap: * + * 0x300000: Start-Adresse der Heap-Verwaltung * + * 0x400000: Letzte Adresse des Heaps * + * * + * Achtung: Benötigt einen PC mit mindestens 8 MB RAM! * + * * + * Autor: Michael Schoettner, HHU, 1.3.2022 * + *****************************************************************************/ + +#include "Allocator.h" +#include "kernel/system/Globals.h" + +constexpr const unsigned int MEM_SIZE_DEF = 8 * 1024 * 1024; // Groesse des Speichers = 8 MB +constexpr const unsigned int HEAP_START = 0x300000; // Startadresse des Heaps +constexpr const unsigned int HEAP_SIZE = 1024 * 1024; // Default-Groesse des Heaps, falls \ + // nicht über das BIOS ermittelbar + +/***************************************************************************** + * Konstruktor: Allocator::Allocator * + *****************************************************************************/ +Allocator::Allocator() : heap_start(HEAP_START), heap_end(HEAP_START + HEAP_SIZE), heap_size(HEAP_SIZE), initialized(1) { + // Groesse des Hauptspeichers (kann über das BIOS abgefragt werden, + // aber sehr umstaendlich, daher hier fest eingetragen + total_mem = MEM_SIZE_DEF; +} + +/***************************************************************************** + * Nachfolgend sind die Operatoren von C++, die wir hier ueberschreiben * + * und entsprechend 'mm_alloc' und 'mm_free' aufrufen. * + *****************************************************************************/ +void* operator new(std::size_t size) { + return allocator.alloc(size); +} + +void* operator new[](std::size_t count) { + return allocator.alloc(count); +} + +void operator delete(void* ptr) { + allocator.free(ptr); +} + +void operator delete[](void* ptr) { + allocator.free(ptr); +} + +void operator delete(void* ptr, unsigned int sz) { + allocator.free(ptr); +} + +// I don't know if accidentally deleted it but one delete was missing +// https://en.cppreference.com/w/cpp/memory/new/operator_delete + +void operator delete[](void* ptr, unsigned int sz) { + allocator.free(ptr); +} diff --git a/src/kernel/memory/Allocator.h b/src/kernel/memory/Allocator.h new file mode 100755 index 0000000..d1ef5bc --- /dev/null +++ b/src/kernel/memory/Allocator.h @@ -0,0 +1,58 @@ +/***************************************************************************** + * * + * A L L O C A T O R * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Einfache Speicherverwaltung. 'new' und 'delete' werden * + * durch Ueberladen der entsprechenden Operatoren * + * realisiert. * + * * + * Memory-Laylout * + * * + * boot.asm * + * 0x07c0: Bootsector vom BIOS geladen * + * 0x0060: Boot-Code verschiebt sich hier hin * + * 0x9000: Setup-Code (max. 64K inkl. Stack) vom * + * Bootsector-Code geladen * + * setup.asm * + * 0x1000: System-Code (max. 512K) geladen * + * System-Code * + * 0x100000: System-Code, kopiert nach Umschalten in * + * den Protected Mode kopiert (GRUB kann nur * + * an Adressen >1M laden) * + * Globale Variablen: Direkt nach dem Code liegen die globalen * + * Variablen. * + * Heap: * + * 0x300000: Start-Adresse der Heap-Verwaltung * + * 0x400000: Letzte Adresse des Heaps * + * * + * Achtung: Benötigt einen PC mit mindestens 4 MB RAM! * + * * + * Autor: Michael Schoettner, HHU, 13.6.2020 * + *****************************************************************************/ +#ifndef Allocator_include__ +#define Allocator_include__ + +constexpr const unsigned int BASIC_ALIGN = 4; // 32 Bit so 4 Bytes? +constexpr const unsigned int HEAP_MIN_FREE_BLOCK_SIZE = 64; // min. Groesse eines freien Blocks + +class Allocator { +public: + Allocator(Allocator& copy) = delete; // Verhindere Kopieren + + Allocator(); + +// virtual ~Allocator() = default; + + unsigned int heap_start; + unsigned int heap_end; + unsigned int heap_size; + unsigned int initialized; + + virtual void init() = 0; + virtual void dump_free_memory() = 0; + virtual void* alloc(unsigned int req_size) = 0; + virtual void free(void* ptr) = 0; +}; + +#endif diff --git a/src/kernel/memory/BumpAllocator.cc b/src/kernel/memory/BumpAllocator.cc new file mode 100755 index 0000000..3a8aa68 --- /dev/null +++ b/src/kernel/memory/BumpAllocator.cc @@ -0,0 +1,76 @@ +/***************************************************************************** + * * + * B U M P A L L O C A T O R * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Eine sehr einfache Heap-Verwaltung, welche freigegebenen * + * Speicher nicht mehr nutzen kann. * + * * + * Autor: Michael Schoettner, HHU, 3.3.2022 * + *****************************************************************************/ + +#include "BumpAllocator.h" +#include "kernel/system/Globals.h" + +/***************************************************************************** + * Methode: BumpAllocator::init * + *---------------------------------------------------------------------------* + * Beschreibung: BumpAllokartor intitialisieren. * + *****************************************************************************/ +void BumpAllocator::init() { + + /* Hier muess Code eingefuegt werden */ + + allocations = 0; + next = reinterpret_cast(heap_start); + + log.info() << "Initialized Bump Allocator" << endl; +} + +/***************************************************************************** + * Methode: BumpAllocator::dump_free_memory * + *---------------------------------------------------------------------------* + * Beschreibung: Ausgabe der Freispeicherinfos. Zu Debuggingzwecken. * + *****************************************************************************/ +void BumpAllocator::dump_free_memory() { + + /* Hier muess Code eingefuegt werden */ + + kout << "Freier Speicher:" << endl + << " - Next: " << hex << reinterpret_cast(next) + << ", Allocations: " << dec << allocations << endl; +} + +/***************************************************************************** + * Methode: BumpAllocator::alloc * + *---------------------------------------------------------------------------* + * Beschreibung: Einen neuen Speicherblock allozieren. * + *****************************************************************************/ +void* BumpAllocator::alloc(unsigned int req_size) { + + /* Hier muess Code eingefuegt werden */ + + log.debug() << "Requested " << hex << req_size << " Bytes" << endl; + + if (req_size + reinterpret_cast(next) > heap_end) { + log.error() << " - More memory requested than available :(" << endl; + return nullptr; + } + + void* allocated = next; + next = reinterpret_cast(reinterpret_cast(next) + req_size); + allocations = allocations + 1; + + log.trace() << " - Allocated " << hex << req_size << " Bytes." << endl; + + return allocated; +} + +/***************************************************************************** + * Methode: BumpAllocator::free * + *---------------------------------------------------------------------------* + * Beschreibung: Nicht implementiert. * + *****************************************************************************/ +void BumpAllocator::free(void* ptr) { + log.error() << " mm_free: ptr= " << hex << reinterpret_cast(ptr) << ", not supported" << endl; +} diff --git a/src/kernel/memory/BumpAllocator.h b/src/kernel/memory/BumpAllocator.h new file mode 100755 index 0000000..b78899c --- /dev/null +++ b/src/kernel/memory/BumpAllocator.h @@ -0,0 +1,38 @@ +/***************************************************************************** + * * + * B U M P A L L O C A T O R * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Eine sehr einfache Heap-Verwaltung, welche freigegebenen * + * Speicher nicht mehr nutzen kann. * + * * + * Autor: Michael Schoettner, HHU, 3.3.2022 * + *****************************************************************************/ + +#ifndef BumpAllocator_include__ +#define BumpAllocator_include__ + +#include "Allocator.h" +#include "kernel/log/Logger.h" + +class BumpAllocator : Allocator { +private: + unsigned char* next; + unsigned int allocations; + + NamedLogger log; + +public: + BumpAllocator(Allocator& copy) = delete; // Verhindere Kopieren + + BumpAllocator() : log("BMP-Alloc") {}; // Allocator() called implicitely in C++ + +// ~BumpAllocator() override = default; + + void init() override; + void dump_free_memory() override; + void* alloc(unsigned int req_size) override; + void free(void* ptr) override; +}; + +#endif diff --git a/src/kernel/memory/LinkedListAllocator.cc b/src/kernel/memory/LinkedListAllocator.cc new file mode 100755 index 0000000..6ed7393 --- /dev/null +++ b/src/kernel/memory/LinkedListAllocator.cc @@ -0,0 +1,310 @@ +/***************************************************************************** + * * + * L I N K E D L I S T A L L O C A T O R * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Einfache Speicherverwaltung, welche den freien Speicher * + * mithilfe einer einfach verketteten Liste verwaltet. * + * * + * Autor: Michael Schoettner, HHU, 13.6.2020 * + *****************************************************************************/ + +#include "LinkedListAllocator.h" +#include "kernel/system/Globals.h" + +// I don't order the list by size so that the block order corresponds to the location in memory +// Then I can easily merge adjacent free blocks by finding the previous block without looking at +// memory addresses of each block +// (That was the plan at least) + +/***************************************************************************** + * Methode: LinkedListAllocator::init * + *---------------------------------------------------------------------------* + * Beschreibung: Liste der Freispeicherbloecke intitialisieren. * + * Anker zeigt auf ein Dummy-Element. Danach folgt * + * ein Block der den gesamten freien Speicher umfasst. * + * * + * Wird automatisch aufgerufen, sobald eine Funktion der * + * Speicherverwaltung erstmalig gerufen wird. * + *****************************************************************************/ +void LinkedListAllocator::init() { + + /* Hier muess Code eingefuegt werden */ + + free_start = reinterpret_cast(heap_start); + free_start->allocated = false; + free_start->size = heap_size - sizeof(free_block_t); + free_start->next = free_start; // Only one block, points to itself + + log.info() << "Initialized LinkedList Allocator" << endl; +} + +/***************************************************************************** + * Methode: LinkedListAllocator::dump_free_memory * + *---------------------------------------------------------------------------* + * Beschreibung: Ausgabe der Freispeicherliste. Zu Debuggingzwecken. * + *****************************************************************************/ +void LinkedListAllocator::dump_free_memory() { + + /* Hier muess Code eingefuegt werden */ + + kout << "Freier Speicher:" << endl; + + if (free_start == nullptr) { + kout << " - No free Blocks" << endl; + } else { + kout << " - Freelist start: " << hex << reinterpret_cast(free_start) << endl; + + free_block_t* current = free_start; + do { + kout << " - Free Block (Start: " << hex << reinterpret_cast(current) + << " Size: " << hex << current->size << ")" << endl; + current = current->next; + } while (current != free_start); + } +} + +/***************************************************************************** + * Methode: LinkedListAllocator::alloc * + *---------------------------------------------------------------------------* + * Beschreibung: Einen neuen Speicherblock allozieren. * + *****************************************************************************/ +void* LinkedListAllocator::alloc(unsigned int req_size) { + lock.acquire(); + + /* Hier muess Code eingefuegt werden */ + // NOTE: next pointer zeigt auf headeranfang, returned wird zeiger auf anfang des nutzbaren freispeichers + + log.debug() << "Requested " << hex << req_size << " Bytes" << endl; + + if (free_start == nullptr) { + log.error() << " - No free memory remaining :(" << endl; + lock.release(); + return nullptr; + } + + // Round to word borders + unsigned int req_size_diff = (BASIC_ALIGN - req_size % BASIC_ALIGN) % BASIC_ALIGN; + unsigned int rreq_size = req_size + req_size_diff; + if (req_size_diff > 0) { + log.trace() << " - Rounded to word border (+" << dec << req_size_diff << " bytes)" << endl; + } + + free_block_t* current = free_start; + do { + if (current->size >= rreq_size) { // Size doesn't contain header, only usable + // Current block large enough + // We now have: [<> | current | <>] + + // Don't subtract to prevent underflow + if (current->size >= rreq_size + sizeof(free_block_t) + HEAP_MIN_FREE_BLOCK_SIZE) { + // Block so large it can be cut + + // Create new header after allocated memory and rearrange pointers + // [<> | current | new_next | <>] + // In case of only one freeblock: + // [current | new_next] + free_block_t* new_next = + reinterpret_cast(reinterpret_cast(current) + sizeof(free_block_t) + rreq_size); + + // If only one block exists, current->next is current + // This shouldn't be a problem since the block gets removed from the list later + new_next->next = current->next; + new_next->size = current->size - (rreq_size + sizeof(free_block_t)); + new_next->allocated = false; + + current->next = new_next; // We want to reach the next free block from the allocated block + current->size = rreq_size; + + // Next-fit + free_start = new_next; + + log.trace() << " - Allocated " << hex << rreq_size << " Bytes with cutting" << endl; + } else { + // Block too small to be cut, allocate whole block + + // Next-fit + free_start = current->next; // Pointer keeps pointing to current if last block + if (free_start == current) { + // No free block remaining + log.trace() << " - Disabled freelist" << endl; + free_start = nullptr; + } + + log.trace() << " - Allocated " << hex << current->size << " Bytes without cutting" << endl; + } + + // Block aushängen + // If block was cut this is obvious, because current->next is a free block + // If block wasn't cut it also works as current was a free block before, so it's next + // block should also be free + free_block_t* previous = LinkedListAllocator::find_previous_block(current); + previous->next = current->next; // Current block was free so previous block pointed at it + current->allocated = true; + + // We leave the current->next pointer intact although the block is allocated + // to allow easier merging of adjacent free blocks + + // HACK: Checking list integrity + // free_block_t* c = current; + // log.debug() << "Checking list Integrity" << endl; + // while (c->allocated) { + // log.debug() << hex << (unsigned int)c << endl; + // c = c->next; + // } + // log.debug() << "Finished check" << endl; + + log.debug() << "returning memory address " << hex << reinterpret_cast(current) + sizeof(free_block_t) << endl; + lock.release(); + return reinterpret_cast(reinterpret_cast(current) + sizeof(free_block_t)); // Speicheranfang, nicht header + } + + current = current->next; + } while (current != free_start); // Stop when arriving at the first block again + + log.error() << " - More memory requested than available :(" << endl; + lock.release(); + return nullptr; +} + +/***************************************************************************** + * Methode: LinkedListAllocator::free * + *---------------------------------------------------------------------------* + * Beschreibung: Einen Speicherblock freigeben. * + *****************************************************************************/ +void LinkedListAllocator::free(void* ptr) { + lock.acquire(); + + /* Hier muess Code eingefuegt werden */ + + // Account for header + free_block_t* block_start = reinterpret_cast(reinterpret_cast(ptr) - sizeof(free_block_t)); + + log.debug() << "Freeing " << hex << reinterpret_cast(ptr) << ", Size: " << block_start->size << endl; + + if (!block_start->allocated) { + log.error() << "Block already free" << endl; + lock.release(); + return; + } + + // Reenable the freelist if no block was available + // This also means that no merging can be done + if (free_start == nullptr) { + free_start = block_start; + block_start->allocated = false; + block_start->next = block_start; + + log.trace() << " - Enabling freelist with one block" << endl; + lock.release(); + return; + } + + free_block_t* next_block = + reinterpret_cast(reinterpret_cast(block_start) + sizeof(free_block_t) + block_start->size); + + // Find the next free block, multiple next blocks can be allocated so walk through them + free_block_t* next_free = block_start->next; + while (next_free->allocated) { + next_free = next_free->next; + } + + free_block_t* previous_free = LinkedListAllocator::find_previous_block(next_free); + free_block_t* previous_free_next = + reinterpret_cast(reinterpret_cast(previous_free) + sizeof(free_block_t) + previous_free->size); + + // We have: [previous_free | previous_free_next | <> | block_start | next_block | <> | next_free] + // The <> spaces don't have to exist and next_block could be the same as next_free + // or previous_free_next the same as block_start + // Also next_block and previous_free_next could be allocated blocks + + // If previous_free/next_free and block_start are adjacent and free, they can be merged: + // - If next_block and next_free are the same block we can merge forward + // Should result in: [previous_free | previous_free_next | <> | block_start] + // - If previous_free_next and block_start are the same block we can merge backward + // Should result in: [block_start] + + // log.trace() << "Before doing any merging:" << endl; + // log.trace() << "previous_free:" << hex << (unsigned int)previous_free << "Size:" << previous_free->size << "Next:" << (unsigned int)previous_free->next << endl; + // log.trace() << "previous_free_next:" << hex << (unsigned int)previous_free_next << "Size:" << previous_free_next->size << "Next:" << (unsigned int)previous_free_next->next << endl; + // log.trace() << "block_start:" << hex << (unsigned int)block_start << "Size:" << block_start->size << "Next:" << (unsigned int)block_start->next << endl; + // log.trace() << "next_block:" << hex << (unsigned int)next_block << "Size:" << next_block->size << "Next:" << (unsigned int)next_block->next << endl; + // log.trace() << "next_free:" << hex << (unsigned int)next_free << "Size:" << next_free->size << "Next:" << (unsigned int)next_free->next << endl; + + // Try to merge forward ======================================================================== + if (next_block == next_free) { + log.trace() << " - Merging block forward" << endl; + + // Current and next adjacent block can be merged + // [previous_free | previous_free_next | <> | block_start | next_free] + + // [block_start | next_free | next_free->next] => [block_start | next_free->next] + block_start->next = next_free->next; // We make next_free disappear + if (block_start->next == next_free) { + // If next_free is the only free block it points to itself, so fix that + // [block_start | next_free], but we want to remove next_free + block_start->next = block_start; + // [block_start] + } + block_start->size = block_start->size + sizeof(free_block_t) + next_free->size; + + // There shouldn't exist any other allocated blocks pointing to next_free, + // the current one should be the only one (or else I have done something wrong) + // If thats the case I should set the next pointer to the next adjacent block + // when allocating a new block + + if (free_start == next_free) { + // next_free is now invalid after merge + log.trace() << " - Moving freelist start to " << hex << reinterpret_cast(block_start) << endl; + free_start = block_start; + } + } else { + // Can't merge forward so size stays the same + // [previous_free | previous_free_next | <> | block_start | <> | next_free] + + block_start->next = next_free; + } + + // Attach new free block to freelist + // This could write into a free block, but doesn't matter + previous_free->next = block_start; + + // Try to merge backward ===================================================================== + if (previous_free_next == block_start) { + log.trace() << " - Merging block backward" << endl; + + // Current and previous adjacent block can be merged + // [previous_free | block_start] + + previous_free->next = block_start->next; + previous_free->size = previous_free->size + sizeof(free_block_t) + block_start->size; + + // For pointers to block_start the same as above applies + // so I don't think I have to manage anything else here + + if (free_start == block_start) { + // block_start is now invalid after merge + log.trace() << " - Moving freelist start to " << hex << reinterpret_cast(previous_free) << endl; + free_start = previous_free; + } + } + + // Depending on the merging this might write into the block, but doesn't matter + block_start->allocated = false; + lock.release(); +} + +free_block_t* LinkedListAllocator::find_previous_block(free_block_t* next_block) { + // Durchlaufe die ganze freispeicherliste bis zum Block der auf next_block zeigt + free_block_t* current = next_block; + while (current->next != next_block) { + // NOTE: This will get stuck if called on the wrong block + current = current->next; + } + + // if (current == next_block) { + // kout << "LinkedListAllocator::find_previous_block returned the input block" << endl; + // } + + return current; +} diff --git a/src/kernel/memory/LinkedListAllocator.h b/src/kernel/memory/LinkedListAllocator.h new file mode 100755 index 0000000..3567b7b --- /dev/null +++ b/src/kernel/memory/LinkedListAllocator.h @@ -0,0 +1,58 @@ +/***************************************************************************** + * * + * L I N K E D L I S T A L L O C A T O R * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Einfache Speicherverwaltung, welche den freien Speicher * + * mithilfe einer einfach verketteten Liste verwaltet. * + * * + * Autor: Michael Schoettner, HHU, 13.6.2020 * + *****************************************************************************/ + +#ifndef LinkedListAllocator_include__ +#define LinkedListAllocator_include__ + +#include "Allocator.h" +#include "lib/async/SpinLock.h" +#include "kernel/log/Logger.h" + +// Format eines freien Blocks, 4 + 4 + 4 Byte +typedef struct free_block { + bool allocated; // NOTE: I added this to allow easier merging of free blocks: + // When freeing an allocated block, its next-pointer can + // point to another allocated block, the next free block + // can be found by traversing the leading allocated blocks. + // We only need a way to determine when the free block is reached. + // This also means that the whole list has to be traversed + // to merge blocks. Would be faster with doubly linked list. + unsigned int size; + struct free_block* next; +} free_block_t; + +class LinkedListAllocator : Allocator { +private: + // freie Bloecke werden verkettet + struct free_block* free_start = nullptr; + + // Traverses the whole list forward till previous block is reached. + // This can only be called on free blocks as allocated blocks + // aren't reachable from the freelist. + static struct free_block* find_previous_block(struct free_block*); + + NamedLogger log; + SpinLock lock; + +public: + LinkedListAllocator(Allocator& copy) = delete; // Verhindere Kopieren + + LinkedListAllocator() : log("LL-Alloc") {} + +// ~LinkedListAllocator() override = default; + + void init() override; + void dump_free_memory() override; + void* alloc(unsigned int req_size) override; + void free(void* ptr) override; +}; + +#endif diff --git a/src/kernel/memory/Paging.cc b/src/kernel/memory/Paging.cc new file mode 100644 index 0000000..88b8082 --- /dev/null +++ b/src/kernel/memory/Paging.cc @@ -0,0 +1,213 @@ +/***************************************************************************** + * * + * P A G I N G * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Rudimentaeres Paging: 1:1 Mapping fuer gesamten logischen* + * Adressraum. logische Adresse = physikalische Adresse * + * * + * Page-Directory (alle Eintraege present, read/write * + * 0. Eintrag zeigt auf eine Page-Table (4 KB Eintraege)* + * Alle restl. Eintraege sind 4 MB Seiten und verweisen * + * somit auf keine Page-Tabelle sondern direkt auf die * + * 4 MB Seite. * + * * + * Page-Table (Logische Adressen 0 - 4 MB) * + * 1. Eintrag not present, read-only * + * -> Null-Pointer abfangen * + * 2. restl. Eintraege present & read/write * + * * + * Memory-Laylout * + * * + * boot.asm * + * 0x07c0: Bootsector vom BIOS geladen * + * 0x0060: Boot-Code verschiebt sich hier hin * + * 0x9000: Setup-Code (max. 64K inkl. Stack) vom * + * Bootsector-Code geladen * + * setup.asm * + * 0x1000: System-Code (max. 512K) geladen * + * BIOS-Aufruf * + * 0x24000: Parameter fuer BIOS-Aufurf * + * 0x25000: Altes ESP sichern, vor BIOS-Aufruf * + * 0x26000: 16-Bit Code-Segment fuer BIOS-Aufurf * + * System-Code * + * 0x100000: System-Code, kopiert nach Umschalten in * + * den Protected Mode kopiert (GRUB kann nur * + * an Adressen >1M laden) * + * Globale Variablen: Direkt nach dem Code liegen die globalen * + * Variablen. * + * Paging: * + * 0x200000: Page-Directory * + * 0x201000: Page-Table * + * 0x202000: erste allozierbare Page (via Paging.cc) * + * 0x3FF000: Anfang der letzten allozierbaren Page * + * Heap: * + * 0x400000: Start-Adresse der Heap-Verwaltung * + * Ende: Letzte Adresse des phys. Speichers * + * * + * * + * Autor: Michael Schoettner, 20.12.2018 * + *****************************************************************************/ +#include "kernel/memory/Paging.h" +#include "kernel/system/Globals.h" +#include "kernel/log/Logger.h" + +// Bits fuer Eintraege in der Page-Table +constexpr const unsigned int PAGE_PRESENT = 0x001; +constexpr const unsigned int PAGE_WRITEABLE = 0x002; +constexpr const unsigned int PAGE_BIGSIZE = 0x080; +constexpr const unsigned int PAGE_RESERVED = 0x800; // Bit 11 ist frei fuer das OS + +// Adresse des Page-Directory (benoetigt 4 KB) +constexpr const unsigned int PAGE_DIRECTORY = 0x200000; + +// Adresse der Page-Table (benoetigt 4 KB) +constexpr const unsigned int PAGE_TABLE = 0x201000; + +// Start- und End-Adresse der 4 KB Seiten die durch die Page-Table adressiert werden +constexpr const unsigned int FST_ALLOCABLE_PAGE = 0x202000; +constexpr const unsigned int LST_ALLOCABLE_PAGE = 0x2FF000; + +/***************************************************************************** + * Funktion: pg_alloc_page * + *---------------------------------------------------------------------------* + * Beschreibung: Alloziert eine 4 KB Seite. Allozieren heisst hier * + * lediglich Setzen eines eigenen RESERVED-Bits. * + *****************************************************************************/ +unsigned int* pg_alloc_page() { + unsigned int* p_page; + + p_page = reinterpret_cast(PAGE_TABLE); + + // 1. Eintrag ist fuer Null-Pointer-Exception reserviert + // ausserdem liegt an die Page-Table an Adresse PAGE_TABLE + // somit ist est PAGE_TABLE + 4 KB frei (bis max. 3 MB, da beginnt der Heap) + for (int i = 1; i < 1024; i++) { + p_page++; + // pruefe ob Page frei + if (((*p_page) & PAGE_RESERVED) == 0) { + *p_page = (*p_page | PAGE_RESERVED); + return reinterpret_cast(i << 12); // Address without flags (Offset 0) + } + } + return nullptr; +} + +/***************************************************************************** + * Funktion: pg_write_protect_page * + *---------------------------------------------------------------------------* + * Beschreibung: Schreibschutz fuer die uebergebene Seite aktivieren. * + * Dies fuer das Debugging nuetzlich. * + *****************************************************************************/ +void pg_write_protect_page(const unsigned int* p_page) { + + /* hier muss Code eingefügt werden */ + + unsigned int* page = reinterpret_cast(PAGE_TABLE) + (reinterpret_cast(p_page) >> 12); // Pagetable entry + + unsigned int mask = PAGE_WRITEABLE; // fill to 32bit + *page = *page & ~mask; // set writable to 0 + + invalidate_tlb_entry(p_page); +} + +/***************************************************************************** + * Funktion: pg_notpresent_page * + *---------------------------------------------------------------------------* + * Beschreibung: Seite als ausgelagert markieren. Nur fuer Testzwecke. * + *****************************************************************************/ +void pg_notpresent_page(const unsigned int* p_page) { + + /* hier muss Code eingefügt werden */ + + unsigned int* page = reinterpret_cast(PAGE_TABLE) + (reinterpret_cast(p_page) >> 12); // Pagetable entry + + unsigned int mask = PAGE_PRESENT; + *page = *page & ~mask; // set present to 0 + + invalidate_tlb_entry(p_page); +} + +/***************************************************************************** + * Funktion: pg_free_page * + *---------------------------------------------------------------------------* + * Beschreibung: Gibt eine 4 KB Seite frei. Es wird hierbei das RESERVED- * + * Bit geloescht. * + *****************************************************************************/ +void pg_free_page(unsigned int* p_page) { + unsigned int idx = reinterpret_cast(p_page) >> 12; + + // ausserhalb Page ? + if (idx < 1 || idx > 1023) { + return; + } + + // Eintrag einlesen und aendern (PAGE_WRITEABLE loeschen) + p_page = reinterpret_cast(PAGE_TABLE); + p_page += idx; + + *p_page = ((idx << 12) | PAGE_WRITEABLE | PAGE_PRESENT); +} + +/***************************************************************************** + * Funktion: pg_init * + *---------------------------------------------------------------------------* + * Beschreibung: Page-Tables einrichten und Paging mithilfe von * + * startup.asm aktivieren. * + *****************************************************************************/ +void pg_init() { + unsigned int i; + unsigned int* p_pdir; // Zeiger auf Page-Directory + unsigned int* p_page; // Zeiger auf einzige Page-Table fuer 4 KB Pages + unsigned int num_pages; // Anzahl 4 MB Pages die phys. Adressraum umfassen + + // wie viele 4 MB Seiten sollen als 'Present' angelegt werden, + // sodass genau der physikalische Adressraum abgedeckt ist? + num_pages = total_mem / (4096 * 1024); + + Logger::instance() << INFO << "pg_init: " << total_mem << endl; + Logger::instance() << INFO << " total_mem: " << total_mem << endl; + Logger::instance() << INFO << " #pages: " << total_mem / (4096 * 1024) << endl; + + // + // Aufbau des Page-Directory + // + + // Eintrag 0: Zeiger auf 4 KB Page-Table + p_pdir = reinterpret_cast(PAGE_DIRECTORY); + *p_pdir = PAGE_TABLE | PAGE_WRITEABLE | PAGE_PRESENT; + + // Eintraege 1-1023: Direktes Mapping (1:1) auf 4 MB Pages (ohne Page-Table) + for (i = 1; i < 1024; i++) { + p_pdir++; + if (i > num_pages) { + *p_pdir = ((i << 22) | PAGE_BIGSIZE); + } else { + *p_pdir = ((i << 22) | PAGE_BIGSIZE | PAGE_WRITEABLE | PAGE_PRESENT); + } + } + + // + // 1. Page-Table + // + p_page = reinterpret_cast(PAGE_TABLE); + + // ersten Eintrag loeschen -> not present, write protected -> Null-Pointer abfangen + *p_page = 0; + + // Eintraege 1-1023: Direktes Mapping (1:1) auf 4 KB page frames + for (i = 1; i < 1024; i++) { + p_page++; + + // Seiten unter FST_ALLOCABLE_PAGE reservieren, damit diese nicht + // alloziert werden und das System kaputt geht + if ((i << 12) >= FST_ALLOCABLE_PAGE) { + *p_page = ((i << 12) | PAGE_WRITEABLE | PAGE_PRESENT); + } else { + *p_page = ((i << 12) | PAGE_WRITEABLE | PAGE_PRESENT | PAGE_RESERVED); + } + } + + // Paging aktivieren (in startup.asm) + paging_on(reinterpret_cast(PAGE_DIRECTORY)); +} \ No newline at end of file diff --git a/src/kernel/memory/Paging.h b/src/kernel/memory/Paging.h new file mode 100644 index 0000000..335e908 --- /dev/null +++ b/src/kernel/memory/Paging.h @@ -0,0 +1,76 @@ +/***************************************************************************** + * * + * P A G I N G * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Rudimentaeres Paging: 1:1 Mapping fuer gesamten logischen* + * Adressraum. logische Adresse = physikalische Adresse * + * * + * Page-Directory (alle Eintraege present, read/write * + * 0. Eintrag zeigt auf eine Page-Table (4 KB Eintraege)* + * Alle restl. Eintraege sind 4 MB Seiten und verweisen * + * somit auf keine Page-Tabelle sondern direkt auf die * + * 4 MB Seite. * +* * + * Page-Table (Logische Adressen 0 - 4 MB) * + * 1. Eintrag not present, read-only * + * -> Null-Pointer abfangen * + * 2. restl. Eintraege present & read/write * + * * + * Memory-Laylout * + * * + * boot.asm * + * 0x07c0: Bootsector vom BIOS geladen * + * 0x0060: Boot-Code verschiebt sich hier hin * + * 0x9000: Setup-Code (max. 64K inkl. Stack) vom * + * Bootsector-Code geladen * + * setup.asm * + * 0x1000: System-Code (max. 512K) geladen * + * BIOS-Aufruf * + * 0x24000: Parameter fuer BIOS-Aufurf * + * 0x25000: Altes ESP sichern, vor BIOS-Aufruf * + * 0x26000: 16-Bit Code-Segment fuer BIOS-Aufurf * + * System-Code * + * 0x100000: System-Code, kopiert nach Umschalten in * + * den Protected Mode kopiert (GRUB kann nur * + * an Adressen >1M laden) * + * Globale Variablen: Direkt nach dem Code liegen die globalen * + * Variablen. * + * Paging: * + * 0x200000: Page-Directory * + * 0x201000: Page-Table * + * 0x202000: erste allozierbare Page (via Paging.cc) * + * 0x3FF000: letzte allozierbare Page * + * Heap: * + * 0x400000: Start-Adresse der Heap-Verwaltung * + * Ende: Letzte Adresse des phys. Speichers * + * * + * * + * Autor: Michael Schoettner, 2.2.2017 * + *****************************************************************************/ + +#ifndef Paging_include__ +#define Paging_include__ + +// Externe Funktionen in startup.asm +extern "C" { + void paging_on(unsigned int* p_pdir); // Paging einschalten + void invalidate_tlb_entry(const unsigned int* ptr); // Page in TLB invalid. +} + +// ativiert paging +extern void pg_init(); + +// alloziert eine 4 KB Page +extern unsigned int* pg_alloc_page(); + +// Schreibschutz auf Seite setzen -> fuer debugging nuetzlich +extern void pg_write_protect_page(const unsigned int* p_page); + +// Present Bit loeschen +extern void pg_notpresent_page(const unsigned int* p_page); + +// gibt eine 4 KB Page frei +extern void pg_free_page(unsigned int* p_page); + +#endif diff --git a/src/kernel/memory/TreeAllocator.cc b/src/kernel/memory/TreeAllocator.cc new file mode 100755 index 0000000..71000f7 --- /dev/null +++ b/src/kernel/memory/TreeAllocator.cc @@ -0,0 +1,163 @@ +#include "TreeAllocator.h" +#include "kernel/system/Globals.h" + +void TreeAllocator::init() { + free_start = reinterpret_cast(heap_start); + free_start->allocated = false; + free_start->left = nullptr; + free_start->right = nullptr; + free_start->parent = nullptr; + free_start->red = false; // The root is always black + free_start->next = reinterpret_cast(free_start); + free_start->previous = reinterpret_cast(free_start); + + log.info() << "Initialized Tree Allocator" << endl; +} + +void TreeAllocator::dump_free_memory() { + kout << "Free Memory:" << endl; + list_block_t* current = reinterpret_cast(heap_start); + do { + if (!current->allocated) { + kout << " - Free Block at " << reinterpret_cast(current) << ", Size: " + << reinterpret_cast(current->next) - reinterpret_cast(current) + << endl; + } + current = current->next; + } while (reinterpret_cast(current) != heap_start); +} + +void* TreeAllocator::alloc(unsigned int req_size) { + log.debug() << "Requested " << dec << req_size << " Bytes" << endl; + + // Round to word borders + tree_block size + unsigned int rreq_size = req_size; + if (rreq_size < sizeof(tree_block_t) - sizeof(list_block_t)) { + // the list_block_t is part of every block, but when freeing + // memory we need enough space to store the rbt metadata + rreq_size = sizeof(tree_block_t) - sizeof(list_block_t); + log.trace() << " - Increased block size for rbt metadata" << endl; + } + unsigned int req_size_diff = (BASIC_ALIGN - rreq_size % BASIC_ALIGN) % BASIC_ALIGN; + rreq_size = rreq_size + req_size_diff; + if (req_size_diff > 0) { + log.trace() << " - Rounded to word border (+" << dec << req_size_diff << " bytes)" << endl; + } + + // Finds smallest block that is large enough + tree_block_t* best_fit = rbt_search_bestfit(rreq_size); + if (best_fit == nullptr) { + log.error() << " - No block found" << endl; + return nullptr; + } + if (best_fit->allocated) { + // Something went really wrong + log.error() << " - Block already allocated :(" << endl; + return nullptr; + } + best_fit->allocated = true; + unsigned int size = get_size(best_fit); + log.trace() << " - Found best-fit: " << hex << reinterpret_cast(best_fit) << endl; + + // HACK: I didn't want to handle situations with only one block (where the tree root would + // get removed), so I make sure there are always at least 2 blocks by inserting a dummy + // block. This is not fast at all but it was fast to code... + // I should change this so it only happens when only one block exists in the freelist + tree_block_t dummy; + dummy.allocated = false; + rbt_insert(&dummy); // I use the address of the stack allocated struct because it is + // removed before exiting the function + + rbt_remove(best_fit); // BUG: Can trigger bluescreen + if (size > HEAP_MIN_FREE_BLOCK_SIZE + rreq_size + sizeof(list_block_t)) { + // Block can be cut + log.trace() << " - Allocating " << dec << rreq_size << " Bytes with cutting" << endl; + + // [best_fit_start | sizeof(list_block_t) | rreq_size | new_block_start] + tree_block_t* new_block + = reinterpret_cast(reinterpret_cast(best_fit) + sizeof(list_block_t) + rreq_size); + new_block->allocated = false; + dll_insert(best_fit, new_block); + rbt_insert(new_block); + } else { + // Don't cut block + // The block is already correctly positioned in the linked list so we only + // need to remove it from the freelist, which is done for both cases + log.trace() << " - Allocating " << dec << rreq_size << " Bytes without cutting" << endl; + } + + // HACK: Remove the dummy element + rbt_remove(&dummy); + + log.trace() << " - Returned address " << hex + << reinterpret_cast(reinterpret_cast(best_fit) + sizeof(list_block_t)) + << endl; + return reinterpret_cast(reinterpret_cast(best_fit) + sizeof(list_block_t)); +} + +void TreeAllocator::free(void* ptr) { + log.info() << "Freeing " << hex << reinterpret_cast(ptr) << endl; + + list_block_t* block = reinterpret_cast(reinterpret_cast(ptr) - sizeof(list_block_t)); + if (!block->allocated) { + // Block already free + return; + } + block->allocated = false; // If the block is merged backwards afterwards this is unnecessary + + list_block_t* previous = block->previous; + list_block_t* next = block->next; + + if (next->allocated && previous->allocated) { + // No merge + rbt_insert(reinterpret_cast(block)); + return; + } + + // HACK: Same as when allocating + tree_block_t dummy; + dummy.allocated = false; + rbt_insert(&dummy); // I use the address of the stack allocated struct because it is + + if (!next->allocated) { + // Merge forward + log.trace() << " - Merging forward" << endl; + + // Remove the next block from all lists as it is now part of our freed block + dll_remove(next); + rbt_remove(reinterpret_cast(next)); // BUG: Bluescreen if next is the only block in the freelist + if (previous->allocated) { + // Don't insert if removed later because of backward merge + rbt_insert(reinterpret_cast(block)); + } + } + + if (!previous->allocated) { + // Merge backward + log.trace() << " - Merging backward" << endl; + + // Remove the current block from all lists as it is now part of the previous block + // It doesn't have to be removed from rbt as it wasn't in there as it was allocated before + dll_remove(block); + rbt_remove(reinterpret_cast(previous)); + rbt_insert(reinterpret_cast(previous)); // Reinsert with new size + } + + // HACK: Same as when allocating + rbt_remove(&dummy); +} + +unsigned int TreeAllocator::get_size(list_block_t* block) const { + if (block->next == block) { + // Only one block exists + return heap_end - (reinterpret_cast(block) + sizeof(list_block_t)); + } + + if (reinterpret_cast(block->next) > reinterpret_cast(block)) { + // Next block is placed later in memory + return reinterpret_cast(block->next) - (reinterpret_cast(block) + sizeof(list_block_t)); + } + + // Next block is placed earlier in memory which means block is at memory end + return reinterpret_cast(heap_end) - (reinterpret_cast(block) + sizeof(list_block_t)); +} diff --git a/src/kernel/memory/TreeAllocator.h b/src/kernel/memory/TreeAllocator.h new file mode 100755 index 0000000..9ffffde --- /dev/null +++ b/src/kernel/memory/TreeAllocator.h @@ -0,0 +1,81 @@ +#ifndef TreeAllocator_include__ +#define TreeAllocator_include__ + +#include "Allocator.h" +#include "kernel/log/Logger.h" + +// I can't imagine that this is fast with all the tree logic? + +typedef struct list_block { + // Doubly linked list for every block + bool allocated; + struct list_block* next; + struct list_block* previous; +} list_block_t; + +// The free blocks are organized in a red-black tree to enable fast insertion with best-fit strategy. +// To allow fast merging of freed blocks every block is part of a doubly linked list. +// Because the red-black tree only contains the free blocks, the memory overhead comes +// down to 4 + 4 + 4 Bytes for the allocated flag, next and previous pointers. +// The size can be calculated by using the next pointer so it doesn't have to be stored. +typedef struct tree_block { + // Doubly linked list for every block + // Locate this at the beginning so we can just cast to allocated_block_t and overwrite the rbt data + bool allocated; + struct list_block* next; + struct list_block* previous; + // RB tree for free blocks + struct tree_block* left; + struct tree_block* right; + struct tree_block* parent; + bool red; // RB tree node color +} tree_block_t; + +class TreeAllocator : Allocator { +private: + // Root of the rbt + tree_block_t* free_start; + + NamedLogger log; + + // Returns the size of the usable memory of a block + unsigned int get_size(list_block_t* block) const; + unsigned int get_size(tree_block_t* block) const { return get_size(reinterpret_cast(block)); } + + void dump_free_memory(tree_block_t* node); + + // NOTE: Would be nice to have this stuff somewhere else for general use (scheduling?), + // makes no sense to have this as members. I'll move it later + void rbt_rot_l(tree_block_t* x); + void rbt_rot_r(tree_block_t* x); + void rbt_transplant(tree_block_t* a, tree_block_t* b); + tree_block_t* rbt_minimum(tree_block_t* node); + + void rbt_insert(tree_block_t* node); + void rbt_fix_insert(tree_block_t* k); + void rbt_remove(tree_block_t* z); + void rbt_fix_remove(tree_block_t* x); + + tree_block_t* rbt_search_bestfit(tree_block_t* node, unsigned int req_size); + tree_block_t* rbt_search_bestfit(unsigned int req_size) { return rbt_search_bestfit(free_start, req_size); } + + void dll_insert(list_block_t* previous, list_block_t* node); + void dll_insert(tree_block_t* previous, tree_block_t* node) { + dll_insert(reinterpret_cast(previous), reinterpret_cast(node)); + } + void dll_remove(list_block_t* node); + +public: + TreeAllocator(Allocator& copy) = delete; // Verhindere Kopieren + + TreeAllocator() : log("RBT-Alloc") {}; + +// ~TreeAllocator() override = default; + + void init() override; + void dump_free_memory() override; + void* alloc(unsigned int req_size) override; + void free(void* ptr) override; +}; + +#endif diff --git a/src/kernel/memory/TreeAllocatorOperations.cc b/src/kernel/memory/TreeAllocatorOperations.cc new file mode 100755 index 0000000..f872cc7 --- /dev/null +++ b/src/kernel/memory/TreeAllocatorOperations.cc @@ -0,0 +1,302 @@ +#include "TreeAllocator.h" + +// RBT code taken from https://github.com/Bibeknam/algorithmtutorprograms + +// START copy from algorithmtutorprograms +void TreeAllocator::rbt_transplant(tree_block_t* a, tree_block_t* b) { + if (a->parent == nullptr) { + free_start = b; + } else if (a == a->parent->left) { + a->parent->left = b; + } else { + a->parent->right = b; + } + b->parent = a->parent; +} + +// insert the key to the tree in its appropriate position +// and fix the tree +void TreeAllocator::rbt_insert(tree_block_t* node) { + // Ordinary Binary Search Insertion + node->parent = nullptr; + node->left = nullptr; + node->right = nullptr; + node->red = true; // new node must be red + + tree_block_t* y = nullptr; + tree_block_t* x = free_start; + + while (x != nullptr) { + y = x; + if (get_size(node) < get_size(x)) { + x = x->left; + } else { + x = x->right; + } + } + + // y is parent of x + node->parent = y; + if (y == nullptr) { + free_start = node; + } else if (get_size(node) < get_size(y)) { + y->left = node; + } else { + y->right = node; + } + + // if new node is a root node, simply return + if (node->parent == nullptr) { + node->red = false; + return; + } + + // if the grandparent is null, simply return + if (node->parent->parent == nullptr) { + return; + } + + // Fix the tree + rbt_fix_insert(node); +} + +// fix the red-black tree +void TreeAllocator::rbt_fix_insert(tree_block_t* k) { + tree_block_t* u; + while (k->parent->red) { + if (k->parent == k->parent->parent->right) { + u = k->parent->parent->left; // uncle + if (u->red) { + // case 3.1 + u->red = false; + k->parent->red = false; + k->parent->parent->red = true; + k = k->parent->parent; + } else { + if (k == k->parent->left) { + // case 3.2.2 + k = k->parent; + rbt_rot_r(k); + } + // case 3.2.1 + k->parent->red = false; + k->parent->parent->red = true; + rbt_rot_l(k->parent->parent); + } + } else { + u = k->parent->parent->right; // uncle + + if (u->red) { + // mirror case 3.1 + u->red = false; + k->parent->red = false; + k->parent->parent->red = true; + k = k->parent->parent; + } else { + if (k == k->parent->right) { + // mirror case 3.2.2 + k = k->parent; + rbt_rot_l(k); + } + // mirror case 3.2.1 + k->parent->red = false; + k->parent->parent->red = true; + rbt_rot_r(k->parent->parent); + } + } + if (k == free_start) { + break; + } + } + free_start->red = false; +} + +// rotate left at node x +void TreeAllocator::rbt_rot_l(tree_block_t* x) { + tree_block_t* y = x->right; + x->right = y->left; + if (y->left != nullptr) { + y->left->parent = x; + } + y->parent = x->parent; + if (x->parent == nullptr) { + free_start = y; + } else if (x == x->parent->left) { + x->parent->left = y; + } else { + x->parent->right = y; + } + y->left = x; + x->parent = y; +} + +// rotate right at node x +void TreeAllocator::rbt_rot_r(tree_block_t* x) { + tree_block_t* y = x->left; + x->left = y->right; + if (y->right != nullptr) { + y->right->parent = x; + } + y->parent = x->parent; + if (x->parent == nullptr) { + free_start = y; + } else if (x == x->parent->right) { + x->parent->right = y; + } else { + x->parent->left = y; + } + y->right = x; + x->parent = y; +} + +// find the node with the minimum key +tree_block_t* TreeAllocator::rbt_minimum(tree_block_t* node) { + while (node->left != nullptr) { + node = node->left; + } + return node; +} + +void TreeAllocator::rbt_remove(tree_block_t* z) { + tree_block_t* x; + tree_block_t* y; + + y = z; + bool y_original_red = y->red; + if (z->left == nullptr) { + x = z->right; + rbt_transplant(z, z->right); + } else if (z->right == nullptr) { + x = z->left; + rbt_transplant(z, z->left); + } else { + y = rbt_minimum(z->right); + y_original_red = y->red; + x = y->right; + if (y->parent == z) { + x->parent = y; + } else { + rbt_transplant(y, y->right); + y->right = z->right; + y->right->parent = y; + } + + rbt_transplant(z, y); + y->left = z->left; + y->left->parent = y; + y->red = z->red; + } + if (!y_original_red) { + rbt_fix_remove(x); + } +} + +// fix the rb tree modified by the delete operation +void TreeAllocator::rbt_fix_remove(tree_block_t* x) { + tree_block_t* s; + while (x != free_start && !x->red) { + if (x == x->parent->left) { + s = x->parent->right; + if (s->red) { + // case 3.1 + s->red = false; + x->parent->red = true; + rbt_rot_l(x->parent); + s = x->parent->right; + } + + if (!s->left->red && !s->right->red) { + // case 3.2 + s->red = true; + x = x->parent; + } else { + if (!s->right->red) { + // case 3.3 + s->left->red = false; + s->red = true; + rbt_rot_r(s); + s = x->parent->right; + } + + // case 3.4 + s->red = x->parent->red; + x->parent->red = false; + s->right->red = false; + rbt_rot_l(x->parent); + x = free_start; + } + } else { + s = x->parent->left; + if (s->red) { + // case 3.1 + s->red = false; + x->parent->red = true; + rbt_rot_r(x->parent); + s = x->parent->left; + } + + if (!s->right->red) { + // case 3.2 + s->red = true; + x = x->parent; + } else { + if (!s->left->red) { + // case 3.3 + s->right->red = false; + s->red = true; + rbt_rot_l(s); + s = x->parent->left; + } + + // case 3.4 + s->red = x->parent->red; + x->parent->red = false; + s->left->red = false; + rbt_rot_r(x->parent); + x = free_start; + } + } + } + x->red = false; +} +// END copy from algorithmtutorprograms + +// This is recursive and depends on luck +tree_block_t* TreeAllocator::rbt_search_bestfit(tree_block_t* node, unsigned int req_size) { + if (node == nullptr) { + return nullptr; + } + + if (req_size < get_size(node)) { + if (node->left != nullptr && get_size(node->left) >= req_size) { + return rbt_search_bestfit(node->left, req_size); + } + + return node; + } + + if (req_size > get_size(node)) { + if (node->right != nullptr && get_size(node->right) >= req_size) { + return rbt_search_bestfit(node->right, req_size); + } + + // Block doesn't fit + return nullptr; + } + + // Perfect fit + return node; +} + +// DLL code +void TreeAllocator::dll_insert(list_block_t* previous, list_block_t* node) { + previous->next->previous = node; + node->next = previous->next; + node->previous = previous; + previous->next = node; +} + +void TreeAllocator::dll_remove(list_block_t* node) { + node->previous->next = node->next; + node->next->previous = node->previous; +} diff --git a/src/kernel/process/IdleThread.h b/src/kernel/process/IdleThread.h new file mode 100644 index 0000000..66671e6 --- /dev/null +++ b/src/kernel/process/IdleThread.h @@ -0,0 +1,38 @@ +/***************************************************************************** + * * + * I D L E T H R E A D * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Wird nur aktiviert, wenn kein Thread arbeiten moechte. * + * * + * Autor: Michael, Schoettner, HHU, 13.8.2016 * + *****************************************************************************/ + +#ifndef IdleThread_include__ +#define IdleThread_include__ + +#include "kernel/system/Globals.h" +#include "Thread.h" + +class IdleThread : public Thread { +public: + IdleThread(const Thread& copy) = delete; // Verhindere Kopieren + + IdleThread() : Thread("IdleThread") {} + + [[noreturn]] void run() override { + // Idle-Thread läuft, ab jetzt ist der Scheduler fertig initialisiert + log.info() << "IdleThread enabled preemption" << endl; + scheduler.enable_preemption(tid); + if (!scheduler.preemption_enabled()) { + log.error() << "Preemption disabled" << endl; + } + + while (true) { + // kout << "Idle!" << endl; + scheduler.yield(); + } + } +}; + +#endif diff --git a/src/kernel/process/Scheduler.cc b/src/kernel/process/Scheduler.cc new file mode 100644 index 0000000..60f2e16 --- /dev/null +++ b/src/kernel/process/Scheduler.cc @@ -0,0 +1,341 @@ +/***************************************************************************** + * * + * S C H E D U L E R * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Implementierung eines einfachen Zeitscheiben-Schedulers. * + * Rechenbereite Threads werden in 'readQueue' verwaltet. * + * * + * Der Scheduler wird mit 'schedule' gestartet. Neue Threads* + * können mit 'ready' hinzugefügt werden. Ein Thread muss * + * die CPU::freiwillig mit 'yield' abgeben, damit andere auch* + * rechnen koennen. Ein Thread kann sich selbst mit 'exit' * + * terminieren. Ein Thread kann einen anderen Thread mit * + * 'kill' beenden. Ein erzwungener Threadwechsel erfolgt * + * mit der Funktion 'preempt', welche von der Timer-ISR * + * aufgerufen wird. * + * * + * Zusaetzlich gibt es nun fuer die Semaphore zwei neue * + * Funktionen 'block' und 'deblock'. * + * * + * Autor: Michael, Schoettner, HHU, 23.11.2018 * + *****************************************************************************/ + +#include "Scheduler.h" +#include "IdleThread.h" +#include + +constexpr const bool INSANE_TRACE = false; + +/***************************************************************************** + * Methode: Dispatcher::dispatch * + *---------------------------------------------------------------------------* + * Beschreibung: Auf den active thread wechseln. * + * * + * Parameter: * + * next Thread der die CPU::erhalten soll. * + *****************************************************************************/ +void Scheduler::start(bse::vector>::iterator next) { + active = next; + if (active >= ready_queue.end()) { + active = ready_queue.begin(); + log.debug() << "Scheduler::start started different thread than passed" << endl; + } + if constexpr (INSANE_TRACE) { + log.trace() << "Starting Thread with id: " << dec << (*active)->tid << endl; + } + (*active)->start(); // First dereference the Iterator, then the unique_ptr to get Thread +} + +void Scheduler::switch_to(Thread* prev_raw, bse::vector>::iterator next) { + active = next; + if (active >= ready_queue.end()) { + active = ready_queue.begin(); + // log.debug() << "Scheduler::switch_to started different thread than passed" << endl; + } + if constexpr (INSANE_TRACE) { + log.trace() << "Switching to Thread with id: " << dec << (*active)->tid << endl; + } + prev_raw->switchTo(**active); +} + +/***************************************************************************** + * Methode: Scheduler::schedule * + *---------------------------------------------------------------------------* + * Beschreibung: Scheduler starten. Wird nur einmalig aus main.cc gerufen.* + *****************************************************************************/ +void Scheduler::schedule() { + + /* hier muss Code eingefuegt werden */ + + // We need to start the idle thread first as this one sets the scheduler to initialized + // and enables preemption. + // Otherwise preemption will be blocked and nothing will happen if the first threads + // run() function is blocking + + ready_queue.push_back(bse::make_unique()); + log.info() << "Starting scheduling: starting thread with id: " << dec << (*(ready_queue.end() - 1))->tid << endl; + start(ready_queue.end() - 1); +} + +/***************************************************************************** + * Methode: Scheduler::ready * + *---------------------------------------------------------------------------* + * Beschreibung: Thread in readyQueue eintragen. * + *****************************************************************************/ +void Scheduler::ready(bse::unique_ptr&& thread) { + CPU::disable_int(); + log.debug() << "Adding to ready_queue, ID: " << dec << thread->tid << endl; + ready_queue.push_back(std::move(thread)); + CPU::enable_int(); +} + +/***************************************************************************** + * Methode: Scheduler::exit * + *---------------------------------------------------------------------------* + * Beschreibung: Thread ist fertig und terminiert sich selbst. Hier muss * + * nur auf den naechsten Thread mithilfe des Dispatchers * + * umgeschaltet werden. Der aktuell laufende Thread ist * + * nicht in der readyQueue. * + *****************************************************************************/ +void Scheduler::exit() { + + /* hier muss Code eingefuegt werden */ + + // Thread-Wechsel durch PIT verhindern + CPU::disable_int(); + + if (ready_queue.size() == 1) { + log.error() << "Can't exit last thread, active ID: " << dec << (*active)->tid << endl; + CPU::enable_int(); + return; + } + + log.debug() << "Exiting thread, ID: " << dec << (*active)->tid << endl; + start(ready_queue.erase(active)); // erase returns the next iterator after the erased element + // cannot use switch_to here as the previous thread no longer + // exists (was deleted by erase) + + // Interrupts werden in Thread_switch in Thread.asm wieder zugelassen + // dispatch kehr nicht zurueck +} + +/***************************************************************************** + * Methode: Scheduler::kill * + *---------------------------------------------------------------------------* + * Beschreibung: Thread mit 'Gewalt' terminieren. Er wird aus der * + * readyQueue ausgetragen und wird dann nicht mehr aufge- * + * rufen. Der Aufrufer dieser Methode muss ein anderer * + * Thread sein. * + * * + * Parameter: * + * that Zu terminierender Thread * + *****************************************************************************/ +void Scheduler::kill(unsigned int tid, bse::unique_ptr* ptr) { + CPU::disable_int(); + + unsigned int prev_tid = (*active)->tid; + + // Block queue, can always kill + for (bse::vector>::iterator it = block_queue.begin(); it != block_queue.end(); ++it) { + if ((*it)->tid == tid) { + // Found thread to kill + + if (ptr != nullptr) { + // Move old thread out of queue to return it + unsigned int pos = bse::distance(block_queue.begin(), it); + *ptr = std::move(block_queue[pos]); // Return the killed thread + } + + // Just erase from queue, do not need to switch + block_queue.erase(it); + log.info() << "Killed thread from block_queue with id: " << tid << endl; + + CPU::enable_int(); + return; + } + } + + // Ready queue, can't kill last one + if (ready_queue.size() == 1) { + log.error() << "Kill: Can't kill last thread in ready_queue with id: " << tid << endl; + CPU::enable_int(); + return; + } + + for (bse::vector>::iterator it = ready_queue.begin(); it != ready_queue.end(); ++it) { + if ((*it)->tid == tid) { + // Found thread to kill + + if (ptr != nullptr) { + // Move old thread out of queue to return it + unsigned int pos = bse::distance(ready_queue.begin(), it); + *ptr = std::move(ready_queue[pos]); // Return the killed thread + } + + if (tid == prev_tid) { + // If we killed the active thread we need to switch to another one + log.info() << "Killed active thread from ready_queue with id: " << tid << endl; + + // Switch to current active after old active was removed + start(ready_queue.erase(it)); + } + + // Just erase from queue, do not need to switch + ready_queue.erase(it); + log.info() << "Killed thread from ready_queue with id: " << tid << endl; + + CPU::enable_int(); + return; + } + } + + log.error() << "Kill: Couldn't find thread with id: " << tid << " in ready- or block-queue" << endl; + log.error() << "Mabe it already exited itself?" << endl; + CPU::enable_int(); +} + +// TODO: Can't retrive the thread right now because it's not clear when it's finished, +// maybe introduce a exited_queue and get it from there +void Scheduler::nice_kill(unsigned int tid, bse::unique_ptr* ptr) { + CPU::disable_int(); + + for (bse::unique_ptr& thread : block_queue) { + if (thread->tid == tid) { + thread->suicide(); + log.info() << "Nice killed thread in block_queue with id: " << tid << endl; + deblock(tid); + CPU::enable_int(); + return; + } + } + + for (bse::unique_ptr& thread : ready_queue) { + if (thread->tid == tid) { + thread->suicide(); + log.info() << "Nice killed thread in ready_queue with id: " << tid << endl; + CPU::enable_int(); + return; + } + } + + log.error() << "Can't nice kill thread (not found) with id: " << tid << endl; + log.error() << "Mabe it already exited itself?" << endl; + CPU::enable_int(); +} + +/***************************************************************************** + * Methode: Scheduler::yield * + *---------------------------------------------------------------------------* + * Beschreibung: CPU::freiwillig abgeben und Auswahl des naechsten Threads.* + * Naechsten Thread aus der readyQueue holen, den aktuellen * + * in die readyQueue wieder eintragen. Das Umschalten soll * + * mithilfe des Dispatchers erfolgen. * + * * + * Achtung: Falls nur der Idle-Thread läuft, so ist die * + * readyQueue leer. * + *****************************************************************************/ +void Scheduler::yield() { + + /* hier muss Code eingefuegt werden */ + + // Thread-Wechsel durch PIT verhindern + CPU::disable_int(); + + if (ready_queue.size() == 1) { + if constexpr (INSANE_TRACE) { + log.trace() << "Skipping yield as no thread is waiting, active ID: " << dec << (*active)->tid << endl; + } + CPU::enable_int(); + return; + } + if constexpr (INSANE_TRACE) { + log.trace() << "Yielding, ID: " << dec << (*active)->tid << endl; + } + switch_to((*active).get(), active + 1); // prev_raw is valid since no thread was killed/deleted +} + +/***************************************************************************** + * Methode: Scheduler::preempt * + *---------------------------------------------------------------------------* + * Beschreibung: Diese Funktion wird aus der ISR des PITs aufgerufen und * + * schaltet auf den naechsten Thread um, sofern einer vor- * + * handen ist. * + *****************************************************************************/ +void Scheduler::preempt() { + + /* Hier muss Code eingefuegt werden */ + + CPU::disable_int(); + yield(); +} + +/***************************************************************************** + * Methode: Scheduler::block * + *---------------------------------------------------------------------------* + * Beschreibung: Aufrufer ist blockiert. Es soll auf den naechsten Thread * + * umgeschaltet werden. Der Aufrufer soll nicht in die * + * readyQueue eingefuegt werden und wird extern verwaltet. * + * Wird bei uns nur fuer Semaphore verwendet. Jede Semaphore* + * hat eine Warteschlange wo der Thread dann verwaltet wird.* + * Die Methode kehrt nicht zurueck, sondern schaltet um. * + *****************************************************************************/ +void Scheduler::block() { + + /* hier muss Code eingefuegt werden */ + + CPU::disable_int(); + + if (ready_queue.size() == 1) { + log.error() << "Can't block last thread, active ID: " << dec << (*active)->tid << endl; + CPU::enable_int(); + return; + } + + Thread* prev_raw = (*active).get(); + std::size_t pos = bse::distance(ready_queue.begin(), active); + block_queue.push_back(std::move(ready_queue[pos])); + + if constexpr (INSANE_TRACE) { + log.trace() << "Blocked thread with id: " << prev_raw->tid << endl; + } + + switch_to(prev_raw, ready_queue.erase(active)); // prev_raw is valid as thread was moved before vector erase +} + +/***************************************************************************** + * Methode: Scheduler::deblock * + *---------------------------------------------------------------------------* + * Beschreibung: Thread 'that' deblockieren. 'that' wird nur in die * + * readyQueue eingefuegt und dann zurueckgekehrt. In der * + * einfachsten Form entspricht diese Funktion exakt 'ready' * + * Man koennte alternativ aber den deblockierten Thread auch* + * am Anfang der readyQueue einfuegen, um ihn zu beorzugen. * + * * + * Parameter: that: Thread der deblockiert werden soll. * + *****************************************************************************/ +void Scheduler::deblock(unsigned int tid) { + + /* hier muss Code eingefuegt werden */ + + CPU::disable_int(); + + for (bse::vector>::iterator it = block_queue.begin(); it != block_queue.end(); ++it) { + if ((*it)->tid == tid) { + // Found thread with correct tid + + std::size_t pos = bse::distance(block_queue.begin(), it); + ready_queue.insert(active + 1, std::move(block_queue[pos])); // We insert the thread after the active + // thread to prefer deblocked threads + block_queue.erase(it); + if constexpr (INSANE_TRACE) { + log.trace() << "Deblocked thread with id: " << tid << endl; + } + CPU::enable_int(); + return; + } + } + + log.error() << "Couldn't deblock thread with id: " << tid << endl; + CPU::enable_int(); +} diff --git a/src/kernel/process/Scheduler.h b/src/kernel/process/Scheduler.h new file mode 100644 index 0000000..8defe79 --- /dev/null +++ b/src/kernel/process/Scheduler.h @@ -0,0 +1,109 @@ +/***************************************************************************** + * * + * S C H E D U L E R * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Implementierung eines einfachen Zeitscheiben-Schedulers. * + * Rechenbereite Threads werden in 'readQueue' verwaltet. * + * * + * Autor: Michael, Schoettner, HHU, 22.8.2016 * + *****************************************************************************/ + +#ifndef Scheduler_include__ +#define Scheduler_include__ + +#include "Thread.h" +#include "lib/mem/UniquePointer.h" +#include "kernel/log/Logger.h" +#include "lib/util/Vector.h" + +class Scheduler { +private: + NamedLogger log; + + bse::vector> ready_queue; + bse::vector> block_queue; + + // NOTE: It makes sense to keep track of the active thread through this as it makes handling the + // unique_ptr easier and reduces the copying in the vector when cycling through the threads + bse::vector>::iterator active = nullptr; + + // Scheduler wird evt. von einer Unterbrechung vom Zeitgeber gerufen, + // bevor er initialisiert wurde + unsigned int idle_tid = 0U; + + // Roughly the old dispatcher functionality + void start(bse::vector>::iterator next); // Start next without prev + void switch_to(Thread* prev_raw, bse::vector>::iterator next); // Switch from prev to next + + // Kann nur vom Idle-Thread aufgerufen werden (erster Thread der vom Scheduler gestartet wird) + void enable_preemption(unsigned int tid) { idle_tid = tid; } + friend class IdleThread; + + void ready(bse::unique_ptr&& thread); + +public: + Scheduler(const Scheduler& copy) = delete; // Verhindere Kopieren + + Scheduler() : log("SCHED"), ready_queue(true), block_queue(true) {} // lazy queues, wait for allocator + + // The scheduler has to init the queues explicitly after the allocator is available + void init() { + ready_queue.reserve(); + block_queue.reserve(); + } + + unsigned int get_active() const { + return (*active)->tid; + } + + // Scheduler initialisiert? + // Zeitgeber-Unterbrechung kommt evt. bevor der Scheduler fertig + // intiialisiert wurde! + bool preemption_enabled() const { return idle_tid != 0U; } + + // Scheduler starten + void schedule(); + + // Helper that directly constructs the thread, then readys it + template + unsigned int ready(Args... args) { + bse::unique_ptr thread = bse::make_unique(std::forward(args)...); + unsigned int tid = thread->tid; + + ready(std::move(thread)); + + return tid; + } + + // Thread terminiert sich selbst + // NOTE: When a thread exits itself it will disappear... + // Maybe put exited threads in an exited queue? + // Then they would have to be acquired from there to exit... + void exit(); // Returns on error because we don't have exceptions + + // Thread mit 'Gewalt' terminieren + void kill(unsigned int tid, bse::unique_ptr* ptr); + void kill(unsigned int tid) { kill(tid, nullptr); } + + // Asks thread to exit + // NOTE: I had many problems with killing threads that were stuck in some semaphore + // or were involved in any locking mechanisms, so with this a thread can make sure + // to "set things right" before exiting itself (but could also be ignored) + void nice_kill(unsigned int tid, bse::unique_ptr* ptr); + void nice_kill(unsigned int tid) { nice_kill(tid, nullptr); } + + // CPU freiwillig abgeben und Auswahl des naechsten Threads + void yield(); // Returns when only the idle thread runs + + // Thread umschalten; wird aus der ISR des PITs gerufen + void preempt(); // Returns when only the idle thread runs + + // Blocks current thread (move to block_queue) + void block(); // Returns on error because we don't have exceptions + + // Deblock by tid (move to ready_queue) + void deblock(unsigned int tid); +}; + +#endif diff --git a/src/kernel/process/Thread.asm b/src/kernel/process/Thread.asm new file mode 100755 index 0000000..36da5b0 --- /dev/null +++ b/src/kernel/process/Thread.asm @@ -0,0 +1,133 @@ +;***************************************************************************** +;* * +;* C O R O U T I N E * +;* * +;*---------------------------------------------------------------------------* +;* Beschreibung: Assemblerdarstellung der 'struct CoroutineState' aus * +;* CoroutineState.h * +;* * +;* Die Reihenfolge der Registerbezeichnungen muss unbedingt * +;* mit der von 'struct CoroutineState' uebereinstimmen. * +;* * +;* Autor: Olaf Spinczyk, TU Dortmund * +;***************************************************************************** + +; EXPORTIERTE FUNKTIONEN + +[GLOBAL Thread_switch] +[GLOBAL Thread_start] + +; IMPLEMENTIERUNG DER FUNKTIONEN + +[SECTION .text] + +Thread_start: +; * +; * Hier muss Code eingefuegt werden +; * + + ;; NOTE: New code with pusha/popa, restores all registers as I use this not only for first start + ;; == High address == + ;; ESP + ;; SP --> RET ADDR + ;; == Low address == + + mov esp, [esp + 0x4] + ;; == High address == + ;; *OBJECT + ;; 0x13115 + ;; *KICKOFF + ;; EAX + ;; ECX + ;; EDX + ;; EBX + ;; ESP + ;; EBP + ;; ESI + ;; EDI + ;; SP --> EFLAGS + ;; == Low address == + + popf + popa + ;; == High address == + ;; *OBJECT + ;; 0x13115 + ;; SP --> *KICKOFF + ;; == Low address == + + sti + ret + + +Thread_switch: +; * +; * Hier muss Code eingefuegt werden +; * + + ;; NOTE: The thread switching works like this: + ;; 1. Prev thread is running, pit interrupt triggers preemption, interrupt handler called + ;; 2. Prev registers are pushed to prev stack after the return address + ;; 3. Switch to next stack + ;; 3. Registers are popped from stack, the esp now points + ;; to the return address (that was written to the stack when it + ;; was switched from) + ;; 4. Return follows the return address to resume normal stack execution + + ;; == High address == + ;; ESP_NEXT + ;; *ESP_PREV + ;; SP --> RET ADDR + ;; == Low address == + + pusha + pushf + ;; == High address == + ;; + 0x2c ESP_NEXT + ;; + 0x28 *ESP_PREV + ;; + 0x24 RET ADDR + ;; EAX + ;; ECX + ;; EDX + ;; EBX + ;; ESP + ;; EBP + ;; ESI + ;; EDI + ;; SP --> EFLAGS + ;; == Low address == + + mov eax, [esp + 0x28] ; Point to *ESP_PREV (Address) + mov [eax], esp ; Update thread esp variable + + ;; ============================================================ + + mov esp, [esp + 0x2c] ; Move to next coroutines stack + ;; == High address == + ;; NEW + ;; THREAD + ;; STACK + ;; RET ADDR + ;; EAX + ;; ECX + ;; EDX + ;; EBX + ;; ESP + ;; EBP + ;; ESI + ;; EDI + ;; SP --> EFLAGS + ;; == Low address == + + popf ; Load new registers from stack + popa + ;; == High address == + ;; NEW + ;; THREAD + ;; STACK + ;; SP --> RET ADDR + ;; == Low address == + + ;; Enable interrupts again + sti + ret diff --git a/src/kernel/process/Thread.cc b/src/kernel/process/Thread.cc new file mode 100755 index 0000000..0bc3df9 --- /dev/null +++ b/src/kernel/process/Thread.cc @@ -0,0 +1,133 @@ +/***************************************************************************** + * * + * C O R O U T I N E * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Implementierung eines Koroutinen-Konzepts. * + * Die Koroutinen sind miteinander verkettet, weswegen die * + * Klasse Coroutine ein Subtyp von 'Chain' ist. * + * * + * Im Konstruktor wird der initialie Kontext der Koroutine * + * eingerichtet. Mit 'start' wird ein Koroutine aktiviert. * + * Das Umschalten auf die naechste Koroutine erfolgt durch * + * Aufruf von 'switchToNext'. * + * * + * Um bei einem Koroutinenwechsel den Kontext sichern zu * + * koennen, enthaelt jedes Koroutinenobjekt eine Struktur * + * CoroutineState, in dem die Werte der nicht-fluechtigen * + * Register gesichert werden koennen. * + * * + * Autor: Michael, Schoettner, HHU, 13.08.2020 * + *****************************************************************************/ + +#include "Thread.h" + +// Funktionen, die auf der Assembler-Ebene implementiert werden, muessen als +// extern "C" deklariert werden, da sie nicht dem Name-Mangeling von C++ +// entsprechen. +extern "C" { + void Thread_start(unsigned int esp); + + // NOTE: Only when backing up the previous thread the esp gets updated, + // so only esp_pre is a pointer + void Thread_switch(unsigned int* esp_prev, unsigned int esp_next); +} + +unsigned int ThreadCnt = 1; // Skip tid 0 as the scheduler indicates no preemption with 0 + +/***************************************************************************** + * Prozedur: Coroutine_init * + *---------------------------------------------------------------------------* + * Beschreibung: Bereitet den Kontext der Koroutine fuer den ersten * + * Aufruf vor. * + *****************************************************************************/ +void Thread_init(unsigned int* esp, unsigned int* stack, void (*kickoff)(Thread*), void* object) { + + // NOTE: c++17 doesn't allow register + // register unsigned int** sp = (unsigned int**)stack; + // unsigned int** sp = (unsigned int**)stack; + + // Stack initialisieren. Es soll so aussehen, als waere soeben die + // eine Funktion aufgerufen worden, die als Parameter den Zeiger + // "object" erhalten hat. + // Da der Funktionsaufruf simuliert wird, kann fuer die Ruecksprung- + // adresse nur ein unsinniger Wert eingetragen werden. Die aufgerufene + // Funktion muss daher dafuer sorgen, dass diese Adresse nie benoetigt + // wird, sie darf also nicht terminieren, sonst kracht's. + + // I thought this syntax was a bit clearer than decrementing a pointer + stack[-1] = reinterpret_cast(object); + stack[-2] = 0x131155U; + stack[-3] = reinterpret_cast(kickoff); + stack[-4] = 0; // EAX + stack[-5] = 0; // ECX + stack[-6] = 0; // EDX + stack[-7] = 0; // EBX + stack[-8] = reinterpret_cast(&stack[-3]); // ESP + stack[-9] = 0; // EBP + stack[-10] = 0; // ESI + stack[-11] = 0; // EDI + stack[-12] = 0x200U; + + *esp = reinterpret_cast(&stack[-12]); +} + +/***************************************************************************** + * Funktion: kickoff * + *---------------------------------------------------------------------------* + * Beschreibung: Funktion zum Starten einer Korutine. Da diese Funktion * + * nicht wirklich aufgerufen, sondern nur durch eine * + * geschickte Initialisierung des Stacks der Koroutine * + * angesprungen wird, darf er nie terminieren. Anderenfalls * + * wuerde ein sinnloser Wert als Ruecksprungadresse * + * interpretiert werden und der Rechner abstuerzen. * + *****************************************************************************/ +[[noreturn]] void kickoff(Thread* object) { + object->run(); + + // object->run() kehrt (hoffentlich) nie hierher zurueck + while (true) {} +} + +/***************************************************************************** + * Methode: Coroutine::Coroutine * + *---------------------------------------------------------------------------* + * Beschreibung: Initialer Kontext einer Koroutine einrichten. * + * * + * Parameter: * + * stack Stack für die neue Koroutine * + *****************************************************************************/ +Thread::Thread(char* name) : stack(new unsigned int[1024]), esp(0), log(name), name(name), tid(ThreadCnt++) { + if (stack == nullptr) { + log.error() << "Couldn't initialize Thread (couldn't alloc stack)" << endl; + return; + } + + log.info() << "Initialized thread with ID: " << tid << " (" << name << ")" << endl; + Thread_init(&esp, &stack[1024], kickoff, this); // Stack grows from top to bottom +} + +/***************************************************************************** + * Methode: Coroutine::switchToNext * + *---------------------------------------------------------------------------* + * Beschreibung: Auf die nächste Koroutine umschalten. * + *****************************************************************************/ +void Thread::switchTo(Thread& next) { + + /* hier muss Code eingefügt werden */ + + // log.trace() << name << ":: Has esp " << hex << esp << endl; + Thread_switch(&esp, next.esp); +} + +/***************************************************************************** + * Methode: Coroutine::start * + *---------------------------------------------------------------------------* + * Beschreibung: Aktivierung der Koroutine. * +*****************************************************************************/ +void Thread::start() const { + + /* hier muss Code eingefügt werden */ + + Thread_start(esp); +} diff --git a/src/kernel/process/Thread.h b/src/kernel/process/Thread.h new file mode 100644 index 0000000..396ddf6 --- /dev/null +++ b/src/kernel/process/Thread.h @@ -0,0 +1,69 @@ +/***************************************************************************** + * * + * T H R E A D * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Implementierung eines kooperativen Thread-Konzepts. * + * Thread-Objekte werden vom Scheduler in einer verketteten * + * Liste 'readylist' verwaltet. * + * * + * Im Konstruktor wird der initialie Kontext des Threads * + * eingerichtet. Mit 'start' wird ein Thread aktiviert. * + * Die CPU sollte mit 'yield' freiwillig abgegeben werden. * + * Um bei einem Threadwechsel den Kontext sichern zu * + * koennen, enthaelt jedes Threadobjekt eine Struktur * + * ThreadState, in dem die Werte der nicht-fluechtigen * + * Register gesichert werden koennen. * + * * + * Zusaetzlich zum vorhandenen freiwilligen Umschalten der * + * CPU mit 'Thread_switch' gibt es nun ein forciertes Um- * + * durch den Zeitgeber-Interrupt ausgeloest wird und in * + * Assembler in startup.asm implementiert ist. Fuer das * + * Zusammenspiel mit dem Scheduler ist die Methode * + * 'prepare_preemption' in Scheduler.cc wichtig. * + * * + * Autor: Michael, Schoettner, HHU, 16.12.2016 * + *****************************************************************************/ + +#ifndef Thread_include__ +#define Thread_include__ + +#include "kernel/log/Logger.h" + +class Thread { +private: + unsigned int* stack; + unsigned int esp; + +protected: + Thread(char* name); + + NamedLogger log; + + bool running = true; // For soft exit, if thread uses infinite loop inside run(), use this as condition + char* name; // For logging + unsigned int tid; // Thread-ID (wird im Konstruktor vergeben) + friend class Scheduler; // Scheduler can access tid + +public: + Thread(const Thread& copy) = delete; // Verhindere Kopieren + + virtual ~Thread() { + log.info() << "Uninitialized thread, ID: " << dec << tid << " (" << name << ")" << endl; + delete[] stack; + } + + // Thread aktivieren + void start() const; + + // Umschalten auf Thread 'next' + void switchTo(Thread& next); + + // Ask thread to terminate itself + void suicide() { running = false; } + + // Methode des Threads, muss in Sub-Klasse implementiert werden + virtual void run() = 0; +}; + +#endif diff --git a/src/kernel/system/Globals.cc b/src/kernel/system/Globals.cc new file mode 100755 index 0000000..4b61ee2 --- /dev/null +++ b/src/kernel/system/Globals.cc @@ -0,0 +1,33 @@ +/***************************************************************************** + * * + * G L O B A L S * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Globale Variablen des Systems. * + * * + * Autor: Michael Schoettner, 30.7.16 * + *****************************************************************************/ + +#include "Globals.h" + +CGA_Stream kout; // Ausgabe-Strom fuer Kernel +const BIOS& bios = BIOS::instance(); // Schnittstelle zum 16-Bit BIOS +VESA vesa; // VESA-Treiber + +PIC pic; // Interrupt-Controller +IntDispatcher intdis; // Unterbrechungsverteilung +PIT pit(10000); // 10000 +PCSPK pcspk; // PC-Lautsprecher +Keyboard kb; // Tastatur + +// BumpAllocator allocator; +LinkedListAllocator allocator; +// TreeAllocator allocator; + +Scheduler scheduler; + +KeyEventManager kevman; +SerialOut serial; + +unsigned int total_mem; // RAM total +unsigned long systime = 0; diff --git a/src/kernel/system/Globals.h b/src/kernel/system/Globals.h new file mode 100755 index 0000000..df2c35b --- /dev/null +++ b/src/kernel/system/Globals.h @@ -0,0 +1,54 @@ +/***************************************************************************** + * * + * G L O B A L S * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Globale Variablen des Systems. * + * * + * Autor: Michael Schoettner, 30.7.16 * + *****************************************************************************/ +#ifndef Globals_include__ +#define Globals_include__ + +#include "device/graphics/CGA_Stream.h" +#include "device/hid/Keyboard.h" +#include "device/sound/PCSPK.h" +#include "device/time/PIT.h" +#include "device/graphics/VESA.h" +#include "kernel/memory/BumpAllocator.h" +#include "kernel/memory/LinkedListAllocator.h" +#include "kernel/memory/TreeAllocator.h" +#include "device/bios/BIOS.h" +#include "device/cpu/CPU.h" +#include "kernel/interrupt/IntDispatcher.h" +#include "device/interrupt/PIC.h" +#include "kernel/memory/Paging.h" +#include "kernel/process/Scheduler.h" +#include "device/port/SerialOut.h" +#include "kernel/event/KeyEventManager.h" + +// I wanted to make more of these singletons but there were problems with atexit missing because of nostdlib I guess + +extern CGA_Stream kout; // Ausgabe-Strom fuer Kernel +extern const BIOS& bios; // Schnittstelle zum 16-Bit BIOS +extern VESA vesa; // VESA-Treiber + +extern PIC pic; // Interrupt-Controller +extern IntDispatcher intdis; // Unterbrechungsverteilung +extern PIT pit; // Zeitgeber +extern PCSPK pcspk; // PC-Lautsprecher +extern Keyboard kb; // Tastatur + +// extern BumpAllocator allocator; +extern LinkedListAllocator allocator; +// extern TreeAllocator allocator; + +extern Scheduler scheduler; + +extern KeyEventManager kevman; +extern SerialOut serial; + +extern unsigned int total_mem; // RAM total +extern unsigned long systime; // wird all 10ms hochgezaehlt + +#endif diff --git a/src/lib/async/Semaphore.cc b/src/lib/async/Semaphore.cc new file mode 100644 index 0000000..06888b6 --- /dev/null +++ b/src/lib/async/Semaphore.cc @@ -0,0 +1,41 @@ +#include "Semaphore.h" +#include "kernel/system/Globals.h" + +void Semaphore::p() { + // Lock to allow deterministic operations on counter/queue + lock.acquire(); + + if (counter > 0) { + // Semaphore can be acquired + counter = counter - 1; + lock.release(); + } else { + // Block and manage thread in semaphore queue until it's woken up by v() again + if (!wait_queue.initialized()) { // TODO: I will replace this suboptimal datastructure in the future + wait_queue.reserve(); + } + wait_queue.push_back(scheduler.get_active()); + + CPU::disable_int(); // Make sure the block() comes through after releasing the lock + lock.release(); + scheduler.block(); // Moves to next thread, enables int + } +} + +void Semaphore::v() { + lock.acquire(); + + if (!wait_queue.empty()) { + // Semaphore stays busy and unblocks next thread to work in critical section + unsigned int tid = wait_queue.front(); + wait_queue.erase(wait_queue.begin()); + + CPU::disable_int(); // Make sure the deblock() comes through after releasing the lock + lock.release(); + scheduler.deblock(tid); // Enables int + } else { + // No more threads want to work so free semaphore + counter = counter + 1; + lock.release(); + } +} diff --git a/src/lib/async/Semaphore.h b/src/lib/async/Semaphore.h new file mode 100755 index 0000000..6bb44de --- /dev/null +++ b/src/lib/async/Semaphore.h @@ -0,0 +1,39 @@ +/***************************************************************************** + * * + * S E M A P H O R E * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Implementierung von Sempahor-Objekten. * + * * + * Autor: Michael Schoettner, 2.9.2016 * + *****************************************************************************/ + +#ifndef Semaphore_include__ +#define Semaphore_include__ + +#include "kernel/process/Thread.h" +#include "SpinLock.h" +#include "lib/util/Vector.h" + +class Semaphore { +private: + // Queue fuer wartende Threads. + bse::vector wait_queue; + SpinLock lock; + + int counter; + +public: + Semaphore(const Semaphore& copy) = delete; // Verhindere Kopieren + + // Konstruktor: Initialisieren des Semaphorzaehlers + Semaphore(int c) : wait_queue(true), counter(c) {} + + // 'Passieren': Warten auf das Freiwerden eines kritischen Abschnitts. + void p(); + + // 'Vreigeben': Freigeben des kritischen Abschnitts. + void v(); +}; + +#endif diff --git a/src/lib/async/SpinLock.cc b/src/lib/async/SpinLock.cc new file mode 100644 index 0000000..ab4f4f4 --- /dev/null +++ b/src/lib/async/SpinLock.cc @@ -0,0 +1,64 @@ +/***************************************************************************** + * * + * S P I N L O C K * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Implementierung eines Spinlocks mithilfe der cmpxchg * + * Instruktion. * + * * + * Autor: Michael Schoettner, 2.2.2018 * + *****************************************************************************/ + +#include "SpinLock.h" + +/***************************************************************************** + * Methode: CAS * + *---------------------------------------------------------------------------* + * Parameter: *ptr Adresse der Variable des Locks * + * old Wert gegen den verglichen wird * + * _new Wert der gesetzt werden soll * + * * + * Beschreibung: Semantik der Funktion CAS = Cmompare & Swap: * + * if old == *ptr then * + * *ptr := _new * + * return prev * + *****************************************************************************/ +static inline unsigned long CAS(const unsigned long* ptr) { + unsigned long prev; + + /* + AT&T/UNIX assembly syntax + + The 'volatile' keyword after 'asm' indicates that the instruction + has important side-effects. GCC will not delete a volatile asm if + sit is reachable. + */ + asm volatile("lock;" // prevent race conditions with other cores + "cmpxchg %1, %2;" // %1 = _new; %2 = *ptr + // constraints + : "=a"(prev) // output: =a: RAX -> prev (%0)) + : "r"(1), "m"(*ptr), "a"(0) // input = %1, %2, %3 (r=register, m=memory, a=accumlator = eax + : "memory"); // ensures assembly block will not be moved by gcc + + return prev; // return pointer instead of prev to prevent unnecessary second call +} + +/***************************************************************************** + * Methode: SpinLock::acquire * + *---------------------------------------------------------------------------* + * Beschreibung: Lock belegen. * + *****************************************************************************/ +void SpinLock::acquire() { + // If lock == 0 the SpinLock can be aquired without waiting + // If lock == 1 the while loop blocks until aquired + while (CAS(ptr) != 0) {} +} + +/***************************************************************************** + * Methode: SpinLock::release * + *---------------------------------------------------------------------------* + * Beschreibung: Lock freigeben. * + *****************************************************************************/ +void SpinLock::release() { + lock = 0; +} diff --git a/src/lib/async/SpinLock.h b/src/lib/async/SpinLock.h new file mode 100644 index 0000000..20169ee --- /dev/null +++ b/src/lib/async/SpinLock.h @@ -0,0 +1,30 @@ +/***************************************************************************** + * * + * S P I N L O C K * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Implementierung eines Spinlocks mithilfe der cmpxchg * + * Instruktion. * + * * + * Autor: Michael Schoettner, 2.2.2018 * + *****************************************************************************/ + +#ifndef SpinLock_include__ +#define SpinLock_include__ + +class SpinLock { +private: + unsigned long lock; + unsigned long* ptr; + +public: + SpinLock(const SpinLock& copy) = delete; // Verhindere Kopieren + + SpinLock() : lock(0), ptr(&lock) {} + + void acquire(); + + void release(); +}; + +#endif diff --git a/src/lib/mem/Memory.cc b/src/lib/mem/Memory.cc new file mode 100755 index 0000000..5f97d1f --- /dev/null +++ b/src/lib/mem/Memory.cc @@ -0,0 +1,7 @@ +#include "Memory.h" + +void bse::memset(char* destination, const char value, std::size_t bytes) { + for (std::size_t byte = 0; byte < bytes; ++byte) { + *(destination + byte) = value; + } +} diff --git a/src/lib/mem/Memory.h b/src/lib/mem/Memory.h new file mode 100755 index 0000000..ff2b481 --- /dev/null +++ b/src/lib/mem/Memory.h @@ -0,0 +1,26 @@ +#ifndef MYSTDLIB_INCLUDE_H_ +#define MYSTDLIB_INCLUDE_H_ + +#include + +namespace bse { + + // add using byte or sth to replace char + + template + void memcpy(T* destination, const T* source, std::size_t count = 1) { + for (unsigned int i = 0; i < count; ++i) { + *(destination + i) = *(source + i); + } + } + + void memset(char* destination, char value, std::size_t bytes); + + template + void zero(T* destination) { + memset(reinterpret_cast(destination), '\0', sizeof(T)); + } + +} // namespace bse + +#endif diff --git a/src/lib/mem/UniquePointer.h b/src/lib/mem/UniquePointer.h new file mode 100644 index 0000000..1e55f45 --- /dev/null +++ b/src/lib/mem/UniquePointer.h @@ -0,0 +1,132 @@ +#ifndef UniquePointer_Include_H_ +#define UniquePointer_Include_H_ + +#include + +// https://en.cppreference.com/w/cpp/memory/unique_ptr + +// NOTE: Because of the way the scheduling works our functions are not executed completely. +// This means that object destructors are not called if the objects live in a scope +// that is left because of thread switching (e.g. a threads run function)... + +namespace bse { + + // T is the type make_unique is called with, meaning int or int[] for example + // T_ is the bare type without extents (int in both cases), so we have a + // int* pointer type for both unique_ptr and unique_ptr + template + class unique_ptr { + private: + using T_ = std::remove_extent_t; + + T_* ptr = nullptr; + + // Only use make_unique or reset for construction + unique_ptr(T_* ptr) : ptr(ptr) {} + + // I didn't want to introduce custom deleters for my small needs + void del() { + if constexpr (std::is_array_v) { + delete[] ptr; + } else { + delete ptr; + } + ptr = nullptr; + } + + public: + // Forbid copying + unique_ptr(const unique_ptr& copy) = delete; + unique_ptr& operator=(const unique_ptr& copy) = delete; + + // Construction + unique_ptr() = default; // Allow declaration without explicit definition + + template + friend typename std::enable_if_t, unique_ptr> + make_unique(Args&&... args); + + template + friend typename std::enable_if_t, unique_ptr> + make_unique(std::size_t size); + + // Deletion + ~unique_ptr() { + del(); + } + + // Moving + unique_ptr(unique_ptr&& move) noexcept { reset(move.release()); }; + + // Implicit upcasting is needed: for sth like + // unique_ptr ptr = make_unique(); + // IdleThread is derived from Thread so the assert passes + template + unique_ptr(unique_ptr&& move) noexcept { + static_assert(std::is_base_of_v, "Has to be derived type"); + reset(move.release()); + } + + unique_ptr& operator=(unique_ptr&& move) noexcept { + reset(move.release()); + return *this; + } + + // Resetting: Replaces managed object, deleting the old one + void reset() { del(); } + void reset(T_* pt) { + del(); + ptr = pt; + } + + // Release: Releases ownership without deletion + T_* release() { + // T* old = ptr; + // ptr = nullptr; + // return old; + return std::exchange(ptr, nullptr); + } + + // Get: Access the raw pointer without taking ownership + T_* get() const { + return ptr; + } + + // Pointer operators + T_* operator->() { return ptr; } + const T_* operator->() const { return ptr; } + T_& operator*() { return *ptr; } + const T_& operator*() const { return *ptr; } + + explicit operator void*() const { return ptr; } + explicit operator bool() const { return (ptr != nullptr); } + + bool operator==(const unique_ptr& other) const { return ptr == other.ptr; } + + // These are only for array unique_ptr but I didn't enforce that + T_& operator[](std::size_t i) { return ptr[i]; } + const T_& operator[](std::size_t i) const { return ptr[i]; } + }; + + // make_unique implementation ======================================= + + // Allow initialization of unique_ptr with optional constructor arguments + // and unique_ptr without constructor arguments + template + + // We make the return type dependent on whether T is an array type or not + typename std::enable_if_t, unique_ptr> + make_unique(Args&&... args) { + return unique_ptr(new T(std::forward(args)...)); + } + + template + typename std::enable_if_t, unique_ptr> + make_unique(std::size_t size) { + using T_ = typename std::remove_extent_t; + return unique_ptr(new T_[size]); + } + +} // namespace bse + +#endif diff --git a/src/lib/stream/OutStream.cc b/src/lib/stream/OutStream.cc new file mode 100755 index 0000000..32745fb --- /dev/null +++ b/src/lib/stream/OutStream.cc @@ -0,0 +1,84 @@ +/***************************************************************************** + * * + * O U T S T R E A M * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Die Klasse OutStream enthaelt die Definition des * + * << Operators fuer die wichtigsten der vordefinierten * + * Datentypen und realisiert somit die bekannte Ausgabe- * + * funktion der C++ iO_Stream Bibliothek. Zur Zeit wird * + * die Darstellung von Zeichen, Zeichenketten und ganzen * + * Zahlen unterstuetzt. Ein weiterer << Operator erlaubt * + * die Verwendung von Manipulatoren. * + * * + * Neben der Klasse OutStream sind hier auch die * + * Manipulatoren hex, dec, oct und bin fuer die Wahl der * + * Basis bei der Zahlendarstellung, sowie endl fuer den * + * Zeilenumbruch definiert. * + * * + * Autor: Olaf Spinczyk, TU Dortmund * + * Aenderungen von Michael Schoettner, HHU, 1.8.16 * + *****************************************************************************/ + +#include "OutStream.h" + +void OutStream::put(char c) { + if (fill_width == 0) { + StringBuffer::put(c); + } else if (fill_used == fill_width - 1) { + // This indicates that content has been cut + StringBuffer::put('@'); + fill_use_char(); + } else if (fill_used == fill_width) { + // do nothing + } else { + StringBuffer::put(c); + fill_use_char(); + } +} + +void OutStream::fill_finalize() { + if (fill_width == 0 || fill_used == fill_width) { + // do nothing + } else if (fill_used > fill_width) { + // should never happen + } else { + for (unsigned char i = 0; i < fill_width - fill_used; ++i) { + StringBuffer::put(fill_char); + } + } + + fill_used = 0; +} + +void OutStream::fill_use_char() { + if (fill_width == 0) { + return; + } + fill_used++; +} + +void OutStream::flush() { + // Flushing resets fixed width + base = 10; + fill_char = ' '; + fill_width = 0; + fill_used = 0; +} + +// +// Zeichen und Zeichenketten in Stream ausgeben +// +// NOTE: The implementations now reside in the OutStream.h as I switched them to templated functions + +// +// Manipulatorfunktionen +// +// Die folgenden Funktionen erhalten und liefern jeweils eine Referenz auf +// ein OutStream Objekt. Da die Klasse O_Stream einen Operator << fuer +// derartige Funktionen definiert, koennen sie mit Hilfe dieses Operators +// aufgerufen und sogar in weitere Eingaben eingebettet werden. +// Aufgabe der Manipulatoren ist, die Darstellung der nachfolgenden Ausgaben +// zu beeinflussen, z.B durch die Wahl des Zahlensystems. + +// NOTE: The implementations now resides in the OutStream.h as I switched them to templated functions diff --git a/src/lib/stream/OutStream.h b/src/lib/stream/OutStream.h new file mode 100755 index 0000000..6baa55a --- /dev/null +++ b/src/lib/stream/OutStream.h @@ -0,0 +1,235 @@ +/***************************************************************************** + * * + * O U T S T R E A M * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Die Klasse OutStream enthaelt die Definition des * + * << Operators fuer die wichtigsten der vordefinierten * + * Datentypen und realisiert somit die bekannte Ausgabe- * + * funktion der C++ iO_Stream Bibliothek. Zur Zeit wird * + * die Darstellung von Zeichen, Zeichenketten und ganzen * + * Zahlen unterstuetzt. Ein weiterer << Operator erlaubt * + * die Verwendung von Manipulatoren. * + * * + * Neben der Klasse OutStream sind hier auch die * + * Manipulatoren hex, dec, oct und bin fuer die Wahl der * + * Basis bei der Zahlendarstellung, sowie endl fuer den * + * Zeilenumbruch definiert. * + * * + * Autor: Olaf Spinczyk, TU Dortmund * + * Aenderungen von Michael Schoettner, HHU, 06.04.20 * + *****************************************************************************/ +#ifndef OutStream_include__ +#define OutStream_include__ + +#include "lib/util/StringBuffer.h" +#include "lib/util/String.h" +#include "lib/util/StringView.h" + +// Some basic width formatting +class fillw { +public: + constexpr fillw(const unsigned int w) : w(w) {} + const unsigned int w; +}; + +class fillc { +public: + constexpr fillc(const char c) : c(c) {} + const char c; +}; + +class OutStream : public StringBuffer { +private: + // Some stream formatting + unsigned char fill_used; // indicates how many characters are already used by the text internally + unsigned char fill_width; // If input is shorter than fill_width fill remaining space up with fill_char + char fill_char; // fill character for fixed width + int base; // Basis des Zahlensystems: z.B. 2, 8, 10 oder 16 + + void fill_use_char(); // recognizes that one char from the print width has been used up + void fill_finalize(); // does the filling after text has been written to buffer + +public: + OutStream(const OutStream& copy) = delete; // Verhindere Kopieren + + OutStream() : fill_used(0), fill_width(0), fill_char(' '), base(10) {} + +// ~OutStream() override = default; + + // Methode zur Ausgabe des Pufferinhalts der Basisklasse StringBuffer. + void flush() override; + + void put(char c) override; + + // OPERATOR << : Umwandlung des angegebenen Datentypes in eine + // Zeichenkette. + + // NOTE: I changed the stream manipulators to templates to be usable with different streams. + // If a Stream derived from OutStream gets passed to a operator<< the type won't be "lowered". + // This allows chaining of operator<< of different streams. + // Needed because I added operator<< overloads to the CGA_Stream class to change color with manipulators. + + // Darstellung eines Zeichens (trivial) + template + friend T& operator<<(T& os, char c) { + os.put(c); + if (c != '\n') { + // endl() doesn't has access to StringBuffer::put(), so ignore \n here + os.fill_finalize(); + } + return os; + } + + template + friend T& operator<<(T& os, unsigned char c) { return os << static_cast(c); } + + // Darstellung einer nullterminierten Zeichenkette + template + friend T& operator<<(T& os, const bse::string_view string) { + for (char current : string) { + os.put(current); + } + os.fill_finalize(); + return os; + } + + // Darstellung ganzer Zahlen im Zahlensystem zur Basis base + template + friend T& operator<<(T& os, short ival) { return os << static_cast(ival); } + + template + friend T& operator<<(T& os, unsigned short ival) { return os << static_cast(ival); } + + template + friend T& operator<<(T& os, int ival) { return os << static_cast(ival); } + + template + friend T& operator<<(T& os, unsigned int ival) { return os << static_cast(ival); } + + template + friend T& operator<<(T& os, long ival) { + // Bei negativen Werten wird ein Minuszeichen ausgegeben. + if (ival < 0) { + os.put('-'); + ival = -ival; + } + // Dann wird der Absolutwert als vorzeichenlose Zahl ausgegeben. + return os << static_cast(ival); + } + + template + friend T& operator<<(T& os, unsigned long ival) { + unsigned long div; + char digit; + + if (os.base == 8) { + os.put('0'); // oktale Zahlen erhalten eine fuehrende Null + } else if (os.base == 16) { + os.put('0'); // hexadezimale Zahlen ein "0x" + os.put('x'); + } + + // Bestimmung der groessten Potenz der gewaehlten Zahlenbasis, die + // noch kleiner als die darzustellende Zahl ist. + for (div = 1; ival / div >= static_cast(os.base); div *= os.base) {} + + // ziffernweise Ausgabe der Zahl + for (; div > 0; div /= static_cast(os.base)) { + digit = ival / div; + if (digit < 10) { + os.put('0' + digit); + } else { + os.put('a' + digit - 10); + } + ival %= div; + } + os.fill_finalize(); + return os; + } + + // Darstellung eines Zeigers als hexadezimale ganze Zahl + template + friend T& operator<<(T& os, void* ptr) { + int oldbase = os.base; + os.base = 16; + os << reinterpret_cast(ptr); + os.base = oldbase; + return os; + } + + // Aufruf einer Manipulatorfunktion + template + friend T& operator<<(T& os, T& (*f)(T&)) { return f(os); } + + // For stream formatting + template + friend T& operator<<(T& os, const fillw& w) { + os.flush(); // Flush the buffer to not modify previous output + os.fill_width = w.w; + return os; + } + + template + friend T& operator<<(T& os, const fillc& c) { + os.flush(); + os.fill_char = c.c; + return os; + } + + // Allow access to base member + template friend T& endl(T& os); + template friend T& bin(T& os); + template friend T& oct(T& os); + template friend T& dec(T& os); + template friend T& hex(T& os); +}; + +// +// Manipulatorfunktionen +// +// Die folgenden Funktionen erhalten und liefern jeweils eine Referenz auf +// ein OutStream Objekt. Da die Klasse OutStream einen Operator << fuer +// derartige Funktionen definiert, koennen sie mit Hilfe dieses Operators +// aufgerufen und sogar in weitere Eingaben eingebettet werden. +// Aufgabe der Manipulatoren ist, die Darstellung der nachfolgenden Ausgaben +// zu beeinflussen, z.B durch die Wahl des Zahlensystems. + +// Zeilenumbruch in Ausgabe einfuegen. +template +T& endl(T& os) { + // os << '\r'; + os << '\n'; + os.flush(); + return os; +} + +// Waehle binaeres Zahlensystem aus. +template +T& bin(T& os) { + os.base = 2; + return os; +} + +// Waehle oktales Zahlensystem aus. +template +T& oct(T& os) { + os.base = 8; + return os; +} + +// Waehle dezimales Zahlensystem aus. +template +T& dec(T& os) { + os.base = 10; + return os; +} + +// Waehle hexadezimales Zahlensystem aus. +template +T& hex(T& os) { + os.base = 16; + return os; +} + +#endif diff --git a/src/lib/util/Array.h b/src/lib/util/Array.h new file mode 100644 index 0000000..7fc7883 --- /dev/null +++ b/src/lib/util/Array.h @@ -0,0 +1,62 @@ +#ifndef ARRAY_INCLUDE_H +#define ARRAY_INCLUDE_H + +#include "Iterator.h" +#include + +namespace bse { + + template + class array { + public: + using iterator = ContinuousIterator; + + private: + T buf[N]; + + public: + array() = default; // If i write default something like bse::array arr; is not initialized... + + // Construct like this: bse::array {1, 2, 3, 4, 5}; + array(std::initializer_list list) { + typename std::initializer_list::iterator it = list.begin(); + for (unsigned int i = 0; i < N; ++i) { + buf[i] = *it; + ++it; + } + } + + iterator begin() { return iterator(&buf[0]); } + iterator begin() const { return iterator(&buf[0]); } + iterator end() { return iterator(&buf[N]); } + iterator end() const { return iterator(&buf[N]); } + + constexpr T& operator[](std::size_t i) { return buf[i]; } + constexpr const T& operator[](std::size_t i) const { return buf[i]; } + + T* data() { return &buf[0]; } + const T* data() const { return &buf[0]; } + + void swap(array& other) { + for (std::size_t i = 0; i < N; ++i) { + std::swap(buf[i], other[i]); + } + } + + // Array& other has to have size n: + // arr1.swap_n<5>(arr2) => arr2 has size 5, arr1 has size >= 5 + template + void swap_n(array& other) { + for (std::size_t i = 0; i < n; ++i) { + std::swap(buf[i], other[i]); + } + } + + constexpr std::size_t size() const { + return N; + } + }; + +} // namespace bse + +#endif diff --git a/src/lib/util/Iterator.h b/src/lib/util/Iterator.h new file mode 100644 index 0000000..ea6ce01 --- /dev/null +++ b/src/lib/util/Iterator.h @@ -0,0 +1,60 @@ +#ifndef Iterator_Include_H_ +#define Iterator_Include_H_ + +namespace bse { + + // This iterator works for structures where the elements are adjacent in memory. + template + class ContinuousIterator { + private: + T* ptr = nullptr; + + public: + ContinuousIterator() = delete; + + // Use const_cast as the iterator has to increment the pointer + ContinuousIterator(const T* ptr) : ptr(const_cast(ptr)) {} + + ContinuousIterator& operator++() { + ++ptr; + return *this; + } + + ContinuousIterator& operator--() { + --ptr; + return *this; + } + + ContinuousIterator operator+(unsigned int add) { + return ContinuousIterator(ptr + add); + } + + ContinuousIterator operator-(unsigned int sub) { + return ContinuousIterator(ptr - sub); + } + + // Convenience + T* operator->() { return ptr; } + const T* operator->() const { return ptr; } + T& operator*() { return *ptr; } + const T& operator*() const { return *ptr; } + + bool operator<(const ContinuousIterator& other) const { return ptr < other.ptr; } + bool operator<=(const ContinuousIterator& other) const { return ptr <= other.ptr; } + bool operator>(const ContinuousIterator& other) const { return ptr > other.ptr; } + bool operator>=(const ContinuousIterator& other) const { return ptr >= other.ptr; } + bool operator==(const ContinuousIterator& other) const { return ptr == other.ptr; } + bool operator!=(const ContinuousIterator& other) const { return ptr != other.ptr; } + + template + friend unsigned int distance(const ContinuousIterator& first, const ContinuousIterator& last); + }; + + template + unsigned int distance(const ContinuousIterator& first, const ContinuousIterator& last) { + return last.ptr - first.ptr; + } + +} // namespace bse + +#endif diff --git a/src/lib/util/Math.h b/src/lib/util/Math.h new file mode 100644 index 0000000..7316801 --- /dev/null +++ b/src/lib/util/Math.h @@ -0,0 +1,19 @@ +#ifndef MATH_INCLUDE_H_ +#define MATH_INCLUDE_H_ + +namespace bse { + + // I didn't add any numeric constraints, will do with c++20 + + template + T& min(const T& a, const T& b) { return a < b ? a : b; } + + template + T& max(const T& a, const T& b) { return a > b ? a : b; } + + template + std::make_unsigned abs(const T& a) { return a < 0 ? -a : a; } + +} // namespace bse + +#endif diff --git a/src/lib/util/Span.h b/src/lib/util/Span.h new file mode 100644 index 0000000..0431ec0 --- /dev/null +++ b/src/lib/util/Span.h @@ -0,0 +1,65 @@ +#ifndef SPAN_INCLUDE_H +#define SPAN_INCLUDE_H + +#include "Iterator.h" +#include + +namespace bse { + + // 0 is unchecked + template + class span { + public: + using iterator = ContinuousIterator; + + private: + T* const ptr; + const std::size_t sz = N; + + public: + span() = default; + + span(T* first) : ptr(first) {} + + span(T* first, T* last) : ptr(first), sz(last - first) {} + + iterator begin() { return iterator(ptr); } + iterator begin() const { return iterator(ptr); } + // If size is unchecked end() is equal to begin() + iterator end() { return iterator(&ptr[N]); } + iterator end() const { return iterator(&ptr[N]); } + + T* operator[](std::size_t i) { + if constexpr (N != 0) { + if (i < 0 || i >= N) { return nullptr; } + } + return &ptr[i]; + } + + T* operator[](std::size_t i) const { + if constexpr (N != 0) { + if (i < 0 || i >= N) { return nullptr; } + } + return &ptr[i]; + } + + T* data() { return ptr; } + const T* data() const { return ptr; } + + explicit operator T*() { + return ptr; + } + + // First is inclusive, last exclusive [first, last) + span& subspan(std::size_t first, std::size_t last = N) { + return span(ptr + first, ptr + last - 1); + } + + std::size_t size() const { + return sz; + } + }; + +} // namespace bse + +#endif diff --git a/src/lib/util/String.cc b/src/lib/util/String.cc new file mode 100644 index 0000000..329d735 --- /dev/null +++ b/src/lib/util/String.cc @@ -0,0 +1,36 @@ +#include "String.h" +#include "lib/mem/Memory.h" + +std::size_t bse::strlen(const char* str) { + const char* current = str; + while (*current != '\0') { ++current; } + return current - str; +} + +void bse::strncpy(char* destination, std::size_t n, const char* source) { + memcpy(destination, source, n); +} + +// Only compares equal length strings +int bse::strcmp(const char* a, const char* b) { + std::size_t a_len = strlen(a); + std::size_t b_len = strlen(b); + + if (a_len < b_len) { + return -1; + } + if (b_len < a_len) { + return 1; + } + + for (std::size_t i = 0; i < a_len; ++i) { + if (a[i] < b[i]) { + return -1; + } + if (b[i] < a[i]) { + return 1; + } + } + + return 0; +} diff --git a/src/lib/util/String.h b/src/lib/util/String.h new file mode 100644 index 0000000..92a934f --- /dev/null +++ b/src/lib/util/String.h @@ -0,0 +1,178 @@ +#ifndef String_Include_H_ +#define String_Include_H_ + +#include "Array.h" +#include "Iterator.h" + +// A heap dynamically heap-allocated string (mutable) + +namespace bse { + + unsigned int strlen(const char* str); + void strncpy(char* destination, unsigned int n, const char* source); + int strcmp(const char* a, const char* b); + + class string { + private: + std::size_t len = 0; + char* buf = nullptr; + + public: + using iterator = ContinuousIterator; + + string() = default; + + string(const char* str) : len(strlen(str)), buf(new char[len + 1]) { + strncpy(buf, len + 1, str); + } + + // Convert char array to string + template + explicit string(const array& arr) : len(N), buf(new char[len + 1]) { + for (std::size_t i = 0; i < N; ++i) { + buf[i] = arr[i]; + } + buf[N] = '\0'; + } + + string(const string& copy) : len(copy.len), buf(new char[len + 1]) { + strncpy(buf, len + 1, copy.buf); + } + + string& operator=(const string& copy) { + if (© != this) { + len = copy.len; + buf = new char[len + 1]; + strncpy(buf, len + 1, copy.buf); + } + + return *this; + } + + string(string&& move) noexcept : len(move.len), buf(move.buf) { + move.len = 0; + move.buf = nullptr; + } + + string& operator=(string&& move) noexcept { + if (&move != this) { + len = move.len; + buf = move.buf; + + move.len = 0; + move.buf = nullptr; + } + + return *this; + } + + ~string() { + delete[] buf; + } + + iterator begin() { return iterator(buf); } + iterator begin() const { return iterator(buf); } + iterator end() { return iterator(&buf[len]); } + iterator end() const { return iterator(&buf[len]); } + + explicit operator char*() { return buf; } + explicit operator char*() const { return buf; } + + char operator[](std::size_t pos) { return buf[pos]; } + char operator[](std::size_t pos) const { return buf[pos]; } + + string operator+(const string& other) const { + string new_str; + new_str.len = len + other.len; + new_str.buf = new char[new_str.len + 1]; + + strncpy(new_str.buf, len, buf); // Copy this content + strncpy(&new_str.buf[len], other.len + 1, other.buf); // Copy other content + + return new_str; + } + + string operator+(const char* other) const { + std::size_t other_len = strlen(other); + + string new_str; + new_str.len = len + other_len; + new_str.buf = new char[new_str.len + 1]; + + strncpy(new_str.buf, len, buf); + strncpy(&new_str.buf[len], other_len + 1, other); + + return new_str; + } + + string& operator+=(const string& other) { + unsigned int new_len = len + other.size(); + char* new_buf = new char[new_len + 1]; + + strncpy(new_buf, len, buf); + strncpy(&new_buf[len], other.size() + 1, other.buf); + + delete[] buf; + buf = new_buf; + len = new_len; + + return *this; + } + + string& operator+=(const char* other) { + unsigned int other_len = strlen(other); + unsigned int new_len = len + other_len; + char* new_buf = new char[new_len + 1]; + + strncpy(new_buf, len, buf); + strncpy(&new_buf[len], other_len + 1, other); + + delete[] buf; + buf = new_buf; + len = new_len; + + return *this; + } + + string operator*(unsigned int n) const { + string new_str; + new_str.len = len * n; + new_str.buf = new char[new_str.len]; + + for (unsigned int i = 0; i < n; ++i) { + strncpy(&new_str.buf[i * len], len, buf); + } + + return new_str; + } + + string& operator*=(unsigned int n) { + unsigned int new_len = len * n; + char* new_buf = new char[new_len]; + + for (unsigned int i = 0; i < n; ++i) { + strncpy(&new_buf[i * len], len, buf); + } + + delete[] buf; + buf = new_buf; + len = new_len; + return *this; + } + + bool operator==(const string& other) const { + return strcmp(buf, other.buf) == 0; + } + + bool operator!=(const string& other) const { + return strcmp(buf, other.buf) != 0; + } + + std::size_t size() const { + return len; + } + }; + +} // namespace bse + +#endif diff --git a/src/lib/util/StringBuffer.cc b/src/lib/util/StringBuffer.cc new file mode 100755 index 0000000..ebdf78e --- /dev/null +++ b/src/lib/util/StringBuffer.cc @@ -0,0 +1,37 @@ +/***************************************************************************** + * * + * S T R I N G B U F F E R * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Die Klasse StringBuffer stellt einen Puffer fuer die * + * Sammlung von Zeichen zur Darstellung auf dem Bildschirm * + * oder anderen Ausgabegeraeten bereit. Die Ausgabe der * + * Zeichen erfolgt, sobald der Puffer voll ist oder wenn * + * explizit die Methode flush() aufgerufen wird. * + * Da StringBuffer geraeteunabhaengig sein soll, ist * + * flush() eine virtuelle Methode, die von den abgeleiteten * + * Klassen definiert werden muss. * + * * + * Autor: Olaf Spinczyk, TU Dortmund * + * Aenderungen von Michael Schoettner, HHU, 1.8.16 * + *****************************************************************************/ + +#include "StringBuffer.h" + +/***************************************************************************** + * Methode: StringBuffer::put * + *---------------------------------------------------------------------------* + * Beschreibung: Fuegt ein Zeichen in den Puffer ein. Wenn der Puffer * + * daraufhin voll ist, wird er durch Aufruf der Methode * + * flush geleert. * + * * + * Parameter: * + * c: Einzufuegendes Zeichen. * + *****************************************************************************/ +void StringBuffer::put(char c) { + buffer[pos] = c; + pos++; + if (pos == buffer.size()) { + flush(); + } +} diff --git a/src/lib/util/StringBuffer.h b/src/lib/util/StringBuffer.h new file mode 100755 index 0000000..6a76afb --- /dev/null +++ b/src/lib/util/StringBuffer.h @@ -0,0 +1,48 @@ +/***************************************************************************** + * * + * S T R I N G B U F F E R * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Die Klasse StringBuffer stellt einen Puffer fuer die * + * Sammlung von Zeichen zur Darstellung auf dem Bildschirm * + * oder anderen Ausgabegeraeten bereit. Die Ausgabe der * + * Zeichen erfolgt, sobald der Puffer voll ist oder wenn * + * explizit die Methode flush() aufgerufen wird. * + * Da StringBuffer geraeteunabhaengig sein soll, ist * + * flush() eine virtuelle Methode, die von den abgeleiteten * + * Klassen definiert werden muss. * + * * + * Autor: Olaf Spinczyk, TU Dortmund * + * Aenderungen von Michael Schoettner, HHU, 06.04.20 * + *****************************************************************************/ +#ifndef StringBuffer_include__ +#define StringBuffer_include__ + +#include "Array.h" + +class StringBuffer { + // Alle Variablen und Methoden dieser Klasse sind "protected", + // da die abgeleiteten Klassen einen direkten Zugriff auf den + // Puffer, den Konstruktor, den Destruktor und die Methode put + // benoetigen. Die Methode flush() muss sowieso neu definiert + // werden und kann dann auch public werden. + +protected: + bse::array buffer; + int pos; + + // StringBuffer: Im Konstruktor wird der Puffer als leer markiert. + StringBuffer() : pos(0) {} + + // Fuegt ein Zeichen in den Puffer ein. Wenn der Puffer + virtual void put(char c); + + // Methode zur Ausgabe des Pufferinhalts + virtual void flush() = 0; +public: + StringBuffer(const StringBuffer& copy) = delete; // Verhindere Kopieren + +// virtual ~StringBuffer() = default; +}; + +#endif diff --git a/src/lib/util/StringView.cc b/src/lib/util/StringView.cc new file mode 100644 index 0000000..8a1368f --- /dev/null +++ b/src/lib/util/StringView.cc @@ -0,0 +1,12 @@ +#include "StringView.h" + +bse::string_view bse::string_view::substring(std::size_t first, std::size_t last) const { + if (first < 0 || first > len || last <= first || last > len) { + return nullptr; + } + + string_view new_view; + new_view.len = last - first; + new_view.buf = &buf[first]; + return new_view; +} \ No newline at end of file diff --git a/src/lib/util/StringView.h b/src/lib/util/StringView.h new file mode 100644 index 0000000..01b0479 --- /dev/null +++ b/src/lib/util/StringView.h @@ -0,0 +1,40 @@ +#ifndef C_OS_STRINGVIEW_H +#define C_OS_STRINGVIEW_H + +#include "String.h" +#include "Iterator.h" +#include + +namespace bse { + + class string_view { + private: + std::size_t len = 0; + const char* buf = nullptr; + + public: + using iterator = ContinuousIterator; + + string_view() = default; + + // Important that char* and string& can be implicitly converted: Only have to provide one + // implementation using stringview for everything (OutStream only uses string_view for example) + string_view(const char* str) : len(strlen(str)), buf(str) {} + string_view(const string& str) : len(str.size()), buf(static_cast(str)) {} + + iterator begin() const { return iterator(buf); } + iterator end() const { return iterator(&buf[len]); } + + explicit operator const char*() const { return buf; } + char operator[](std::size_t pos) const { return buf[pos]; } + bool operator==(const string_view& other) const { return buf == other.buf; } + bool operator!=(const string_view& other) const { return buf != other.buf; } + + std::size_t size() const { return len; } + + string_view substring(std::size_t first, std::size_t last) const; + }; + +} // namespace bse + +#endif //C_OS_STRINGVIEW_H diff --git a/src/lib/util/Vector.h b/src/lib/util/Vector.h new file mode 100644 index 0000000..495989e --- /dev/null +++ b/src/lib/util/Vector.h @@ -0,0 +1,302 @@ +#ifndef VECTOR_INCLUDE_H_ +#define VECTOR_INCLUDE_H_ + +// NOTE: I decided to implement this because I wanted some sort of dynamic array (for example for the keyeventmanager). +// Also I wanted to template the Queue (for the scheduler) but with this I can just replace the Queue and use the +// ArrayList instead + +#include "Iterator.h" +#include + +// https://en.cppreference.com/w/cpp/container/vector +namespace bse { + + template + class vector { + public: + using iterator = ContinuousIterator; + + private: + static constexpr const std::size_t default_cap = 10; // Arbitrary but very small because this isn't a real OS :( + static constexpr const std::size_t min_cap = 5; // Slots to allocate extra when array full + + T* buf = nullptr; // Heap allocated as size needs to change during runtime + // Can't use Array for the same reason so we use a C Style array + std::size_t buf_pos = 0; + std::size_t buf_cap = 0; + + void init(std::size_t cap = vector::default_cap) { + if (buf != nullptr) { + return; + } + buf = new T[cap]; + buf_cap = cap; + } + + std::size_t get_rem_cap() const { + return buf_cap - size(); + } + + // Enlarges the buffer if we run out of space + void min_expand() { + // Init if necessary + if (buf == nullptr) { + init(); + return; // Dont have to realloc after init + } + + // Since we only ever add single elements this should never get below zero + if (get_rem_cap() < min_cap) { + switch_buf(buf_cap + min_cap); + } + } + + // 1. Allocates new buffer + // 2. Moves stuff to new buffer + // 3. Deletes old buffer + // 4. Sets new pos/cap + void switch_buf(std::size_t cap) { + // Alloc new array + T* new_buf = new T[cap]; + + // Swap current elements to new array + for (std::size_t i = 0; i < size(); ++i) { + new_buf[i] = std::move(buf[i]); + buf[i].~T(); // TODO: I think delete[] buf calls these, verify that + } + + // Move new array to buf, deleting the old array + delete[] buf; + buf = new_buf; + buf_cap = cap; + } + + // Index is location where space should be made + void copy_right(std::size_t i) { + if (i >= size()) { + // We don't need to copy anything as space is already there + return; + } + + for (std::size_t idx = size(); idx > i; --idx) { + buf[idx].~T(); // Delete previously contained element that will be overridden + buf[idx] = std::move(buf[idx - 1]); // This leaves a "shell" of the old object that has to be deleted + buf[idx - 1].~T(); // Delete element in moved-out state + } + } + + // Index is the location that will be removed + void copy_left(std::size_t i) { + if (i >= size()) { + // We don't need to copy anything as nothing will be overridden + return; + } + + for (std::size_t idx = i; idx < size(); ++idx) { + buf[idx].~T(); // Delete the element that will be overwritten + buf[idx] = std::move(buf[idx + 1]); + buf[idx + 1].~T(); + } + } + + public: + explicit vector(bool lazy = false) { + if (!lazy) { // I added this as a work around, the scheduler can't initialize the queues right + // away because when the scheduler is started the allocator is not ready. + init(); + } + }; + + // Initialize like this: bse::vector vec {1, 2, 3, 4, 5}; + vector(std::initializer_list list) : buf_cap(list.size()), buf(new T[buf_cap]) { + typename std::initializer_list::iterator it = list.begin(); + for (unsigned int i = 0; i < buf_pos; ++i) { + buf[i] = *it; + ++it; + } + } + + + vector(const vector& copy) : buf_pos(copy.buf_pos), buf_cap(copy.buf_cap), buf(new T[buf_cap]) { + for (unsigned int i = 0; i < buf_pos; ++i) { + buf[i] = copy[i]; // Does a copy since copy is marked const reference + } + } + + vector& operator=(const vector& copy) { + if (this != ©) { + ~vector(); + + buf_cap = copy.buf_cap; + buf_pos = copy.buf_pos; + buf = new T[buf_cap]; + for (unsigned int i = 0; i < buf_pos; ++i) { + buf[i] = copy[i]; + } + } + return *this; + } + + vector(vector&& move) noexcept : buf(move.buf), buf_pos(move.buf_pos), buf_cap(move.buf_cap) { + move.buf_cap = 0; + move.buf_pos = 0; + move.buf = nullptr; + } + + vector& operator=(vector&& move) noexcept { + if (this != &move) { + buf_cap = move.buf_cap; + buf_pos = move.buf_pos; + buf = move.buf; + + move.buf_cap = 0; + move.buf_pos = 0; + move.buf = nullptr; + } + return *this; + } + + ~vector() { + if (buf == nullptr) { + return; + } + + for (std::size_t i = 0; i < size(); ++i) { + buf[i].~T(); // TODO: I think delete[] buf calls these, verify that + } + delete[] buf; + } + + // Iterator + iterator begin() { return iterator(&buf[0]); } + iterator begin() const { return iterator(&buf[0]); } + iterator end() { return iterator(&buf[size()]); } + iterator end() const { return iterator(&buf[size()]); } + + // Add elements + // https://en.cppreference.com/w/cpp/container/vector/push_back + void push_back(const T& copy) { + buf[size()] = copy; + ++buf_pos; + min_expand(); + } + + void push_back(T&& move) { + buf[size()] = std::move(move); + ++buf_pos; + min_expand(); + } + + // https://en.cppreference.com/w/cpp/container/vector/insert + // The element will be inserted before the pos iterator, pos can be the end() iterator + iterator insert(iterator pos, const T& copy) { + std::size_t idx = distance(begin(), pos); // begin() does init if necessary + copy_right(idx); // nothing will be done if pos == end() + buf[idx] = copy; + ++buf_pos; + min_expand(); + return iterator(&buf[idx]); + } + + iterator insert(iterator pos, T&& move) { + std::size_t idx = distance(begin(), pos); // begin() does init if necessary + copy_right(idx); + buf[idx] = std::move(move); + ++buf_pos; + min_expand(); + return iterator(&buf[idx]); + } + + // Remove elements + // https://en.cppreference.com/w/cpp/container/vector/erase + // Returns the iterator after the removed element, pos can't be end() iterator + iterator erase(iterator pos) { + std::size_t idx = distance(begin(), pos); + copy_left(idx); + --buf_pos; + // shrink(); + return iterator(&buf[idx]); + } + + // Access + T& front() { + return buf[0]; + } + + const T& front() const { + return buf[0]; + } + + T& back() { + return buf[size() - 1]; + } + + const T& back() const { + return buf[size() - 1]; + } + + T& operator[](std::size_t pos) { + return buf[pos]; + } + + const T& operator[](std::size_t pos) const { + return buf[pos]; + } + + // Misc + bool empty() const { + return !size(); + } + + std::size_t size() const { + return buf_pos; + } + + void clear() { + while (buf_pos > 0) { + --buf_pos; + buf[buf_pos].~T(); + } + } + + void reserve(std::size_t cap = vector::default_cap) { + // The first reserve could allocate double if cap != default_cap + if (buf == nullptr) { + // Directly init with correct size + init(cap); + return; + } + + if (cap == buf_cap) { + // Would change nothing + return; + } + + switch_buf(cap); + } + + bool initialized() const { + return buf != nullptr; + } + }; + + // Erase all elements that match a predicate + // NOTE: pred is no real predicate as one would need closures for this, but we don't have available + // This means the result has to be passed separately and the function differs from the c++20 std::erase_if + template + std::size_t erase_if(vector& vec, arg (*pred)(const T&), arg result) { + std::size_t erased_els = 0; + for (typename vector::Iterator it = vec.begin(); it != vec.end(); /*Do nothing*/) { + if (pred(*it) == result) { + it = vec.erase(it); // erase returns the iterator to the next element + ++erased_els; + } else { + ++it; // move forward when nothing was deleted + } + } + return erased_els; + } + +} // namespace bse + +#endif diff --git a/src/link.ld b/src/link.ld new file mode 100755 index 0000000..b0899c6 --- /dev/null +++ b/src/link.ld @@ -0,0 +1,73 @@ +/* $Id: sections 5834 2013-10-08 17:04:08Z os $ */ + +ENTRY(boot) +OUTPUT_FORMAT(elf32-i386) + +SECTIONS +{ + . = 0x100000; /* Startadresse des Systems */ + + .text : + { + *(".text") + *(".text.*") + *(".text$") + *(".init") + *(".fini") + *(".gnu.linkonce.*") + } + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + KEEP (*(".ctors")) + KEEP (*(".ctor")) + PROVIDE_HIDDEN (__init_array_end = .); + } + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array)) + KEEP (*(".dtors")) + KEEP (*(".dtor")) + PROVIDE_HIDDEN (__fini_array_end = .); + } + + .data : + { + *(".data") + *(".data$") + *(".rodata") + *(".rodata.*") + *(".got") + *(".got.plt") + *(".eh_frame") + *(".eh_fram") + *(".jcr") + *(".note.*") + } + + .bss : + { + ___BSS_START__ = .; + *(".bss") + *(".bss.*") + ___BSS_END__ = .; + } + +/* + /DISCARD/ : + { + *(".note") + *(".comment") + *(".debug_line") + *(".debug_info") + *(".debug_abbrev") + *(".debug_aranges") + } +*/ +} diff --git a/src/main.cc b/src/main.cc new file mode 100755 index 0000000..f7a52d4 --- /dev/null +++ b/src/main.cc @@ -0,0 +1,169 @@ +/***************************************************************************** + * * + * M A I N * + * * + *---------------------------------------------------------------------------* + * Beschreibung: Startroutine, wird direkt vom Bootlader angesprungen, * + * nachdem dieser in den Protected Mode geschaltet hat und * + * die GDT und IDT initalisiert hat. * + * * + * Autor: Michael Schoettner, HHU, 11.11.2016 * + *****************************************************************************/ + +#include "kernel/system/Globals.h" +#include "kernel/demo/MainMenu.h" +#include "kernel/log/Logger.h" +#include "device/cpu/CPU.h" +#include "kernel/memory/Paging.h" +#include "lib/stream/OutStream.h" + +void print_startup_message() { + kout.lock(); + kout.clear(); + kout << "BSEos 1.0\n" + << "=========\n" + << "Unterstuetzte Funktionen:\n" + << " - Bildschirmausgaben\n" + << " - Sound ueber den PC-Lautsprecher\n" + << " - Tastatureingaben per Abfrage\n" + << " - Einfache Heapverwaltung\n" + << " - Tastatureingaben per Interrupt\n" + << " - Kooperative Threads\n" + << " - VESA Graphics Mode\n" + << " - Einfaches Paging\n" + << " - Preemptive Threads\n" + << " - Einfache Synchronisierung\n" + + << " - Einfache (Tastatur-)Eventverwaltung\n" + << " - Serial Output Logging\n" + << "\nPress Enter to continue\n" + << endl; + kout.unlock(); +} + +// #include "test/VectorTest.h" + +int main() { + Logger::set_level(Logger::TRACE); + Logger::disable_kout(); + Logger::enable_serial(); + + // Speicherverwaltung initialisieren + allocator.init(); + scheduler.init(); + kevman.init(); + + // Tastatur-Unterbrechungsroutine 'einstoepseln' + kb.plugin(); + pit.plugin(); + + // Interrupts erlauben (Tastatur, PIT) + CPU::enable_int(); + + // Activate paging + // This has to happen after the allocator is initialized but before the scheduler is started + pg_init(); + + // Startmeldung + print_startup_message(); + + // Scheduler starten (schedule() erzeugt den Idle-Thread) + scheduler.ready(); // NOTE: A thread that manages other threads has to be added before scheduler.schedule(), + // because scheduler.schedule() doesn't return, only threads get cpu time + scheduler.schedule(); + + // NOTE: Pre-Post ToDo's + // TODO: Reorganize the project similar to hhuOS: + // - TODO: Use CMake + // - TODO: Copy file structure: build, cmake, src + // - TODO: Translate the src/Makefile and boot/Makefile + // TODO: Update some parts to C++20 (I wanted to use reference optionals somewhere...) + // TODO: Namespace that shit + + // NOTE: Post ToDo's + // TODO: Generalize key event system to eventbus (where custom events can be registered) + // TODO: Introduce kernel services and abstract time, memory, scheduler, interrupt etc. (like in hhuOS) + // TODO: Use linear framebuffer to draw output/shell/text instead of CGA + // TODO: Add worker threads that execute a function and return a value + // TODO: Manage exited threads in scheduler + // TODO: Query thread state in scheduler + // TODO: Bitfield lib class that has defined behavior regarding ordering/packing (for easy register access)? + + // NOTE: Large post ToDo's + // TODO: Add a RB-Tree datastructure and use it for memory management + // TODO: Enable full paging (check hhuOS for implementation example) + + // NOTE: Filesystem enable ToDo's (huge) + // TODO: Very simple floppy disk device driver (floppy is common and simple) + // TODO: Very simple FAT8 filesystem driver (or something similar that is extremely simple) + // TODO: Need the infastructure to mount filesystems (check hhuOS for implementation example) + // TODO: Write a very simple program loader to load binaries stored on the filesystem to memory and execute them + // TODO: Add simple Unix-like binaries that get compiled for BSEos during build time (check hhuOS) + // TODO: Add simple shell (check hhuOS) + + // NOTE: Insane ToDo's + // TODO: Write a very simple text editor that can save files to the filesystem + // TODO: Small compiler to write small programs inside the system (I don't want to deal with register allocation so compile to bytecode and use a VM?) + + // NOTE: Enforced ToDo's (needed) + // DONE: Rewrite demos for threads + // DONE: Make menu for demos + // DONE: Thread switching stops after a while + // DONE: Threads are not cleanup after exit, use managed pointer? + // DONE: Fix PCSKP/Keyboard Demos: Keyboard Thread gets missing after blocking waiting for input, kevman doesn't wake up... + + // NOTE: Main ToDo's (extra) + // DONE: Basic event management for keyboard events so threads can utilize interrupt based inputs + // This also works well with a blocked-queue in the scheduler for threads waiting for input + // DONE: Serial output + // CANCELED: Output graphviz stuff over serial? + // CANCELED: Fix the damn TreeAllocator: Allow root deletion without bluescreen + // Maybe just remove the red black tree stuff and replace with usual binary search tree? + // I can just balance this tree unefficiantly by reinserting all nodes + // CANCELED: Implement BST data structure with Tree interface? + // CANCELED: Implement RBT tree interface implementation? + // CANCELED: Switch treealloc so the underlying tree can be swapped easily + // CANCELED: Implement realloc so ArrayList can realloc instead of newly allocate bigger block + // DONE: Array wrapper + // DONE: Rewrite Logging with a basic logger + // DONE: Static Logger + // DONE: String wrapper + // DONE: Linked List + // DONE: Iterator support for structures + // DONE: Implement own basic managed pointers + // DONE: Scheduler should own threads + // DONE: Remove CoroutineState/ThreadState and just use pusha/popa, start/switch methods should + // just get esp as argument + // CANCELED: Use singleton pattern for some device classes/classes used only in globals (needs stdlib for exita) + // DONE: Introduce name to threads? + // DONE: Allow to gracefully kill threads + // CANCELED: Request thread status from scheduler (don't need it) + + // NOTE: Cleanup + // DONE: Use templates for queue so threads don't have to be casted down from chain + // DONE: Only use references instead of pointers where possible + // DONE: Unify debug output format + // DONE: Cleanup: Remove I added this... Notes, just leave explanations + // DONE: Remove Math "lib" or do something with it + // CANCELED: Add some fixed point math like sine approximation or fractions? + // DONE: Cleanup imports: Only import stuff in implementation when only needed there + // CANCELED: Switch cpu_disableint() to semaphore etc (Spinlock in the scheduler?) + // CANCELED: Change mylib types to not use T* but T and call with memcpy instead of memcpy? + // DONE: Make more stuff const and static and static constexpr const + // DONE: Remove ArrayList init and do this inside ArrayList when an operation on the list is done + // DONE: Kevman unsubscribe is needed, because exited threads will still be woken up by kevman + // Or check if thread is still running + // DONE: Delete copy constructors that weren't already deleted + // DONE: Switch out semaphore Queue with ArrayList? Or switch back Scheduler to Queue? + // CANCELED: Add virtual destructors and make sure to call them with delete when objects are removed + // DONE: Replace empty constructors/destructors with default keyword + // DONE: Synchronize the outstream + // DONE: Remove Iterator from List.h + // DONE: Move Array/ArrayList/LinkedList/List to bse namespace + // DONE: Remove the Input.h file and replace functionality with kevman + // DONE: Replace C style casts with C++ casts + // DONE: Add Move/Copy/Assignment stuff to vector, array etc (all where it's missing) + + // Scheduler doesn't return + return 0; +} diff --git a/src/startup.asm b/src/startup.asm new file mode 100644 index 0000000..0ac0ca4 --- /dev/null +++ b/src/startup.asm @@ -0,0 +1,393 @@ +;****************************************************************************** +;* * +;* S T A R T U P . A S M * +;* * +;*----------------------------------------------------------------------------* +;* Beschreibung: 'startup' ist der Eintrittspunkt des eigentlichen Systems.* +;* Die Umschaltung in den Protected-Mode ist bereits erfolgt.* +;* Es wird alles vorbereitet, damit so schnell wie moeglich * +;* die weitere Ausfuehrung durch C-Code erfolgen kann. * +;* * +;* Hier erweitert, um BIOS callund Paging-Aktivierung, * +;* Unterstuetzung des Bluescreens und preemptives * +;* Thread-Switching. * +;* * +;* Autor: Olaf Spinczyk, TU Dortmund * +;* Michael Schoettner, HHU, 3.7.2022 * +;****************************************************************************** + + +; Multiboot-Konstanten +MULTIBOOT_PAGE_ALIGN equ 1<<0 +MULTIBOOT_MEMORY_INFO equ 1<<1 + +; Magic-Number fuer Multiboot +MULTIBOOT_HEADER_MAGIC equ 0x1badb002 +; Multiboot-Flags (ELF-spezifisch!) +MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO +MULTIBOOT_HEADER_CHKSUM equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) +MULTIBOOT_EAX_MAGIC equ 0x2badb002 + +; +; System +; + +[GLOBAL startup] +[GLOBAL idt] +[GLOBAL __cxa_pure_virtual] +[GLOBAL bios_call] +[GLOBAL invalidate_tlb_entry] +[GLOBAL paging_on] +[GLOBAL get_page_fault_address] +[GLOBAL get_int_esp] + + +; Michael Schoettner: +; Nachfolgender label steht fuer das 'delete', welches jetzt implementiert +; wird. Damit der Linker nicht wegen doppelter Definition "meckert" +; nun auskommentieren! +; [GLOBAL _ZdlPv] + +[EXTERN main] +[EXTERN int_disp] + +[EXTERN ___BSS_START__] +[EXTERN ___BSS_END__] +[EXTERN __init_array_start] +[EXTERN __init_array_end] +[EXTERN __fini_array_start] +[EXTERN __fini_array_end] + +[SECTION .text] + +startup: + jmp skip_multiboot_hdr + +multiboot_header: + align 4 + dd MULTIBOOT_HEADER_MAGIC + dd MULTIBOOT_HEADER_FLAGS + dd MULTIBOOT_HEADER_CHKSUM + +skip_multiboot_hdr: +; GCC-kompilierter Code erwartet das so. + + cld + + cmp eax,MULTIBOOT_EAX_MAGIC + jne floppy_boot +; +; GDT setzen (notwendig, falls wir durch GRUB geladen wurden) +; + lgdt [gdt_48] + +floppy_boot: + +; Globales Datensegment + + mov ax,0x10 + mov ds,ax + mov es,ax + mov fs,ax + mov gs,ax + +; Stack festlegen + + mov ss,ax + mov esp,init_stack+4096 + +; Unterbrechungsbehandlung sicherstellen + + call setup_idt + call reprogram_pics + +; BSS loeschen + mov edi, ___BSS_START__ +clear_bss: + mov byte [edi], 0 + inc edi + cmp edi, ___BSS_END__ + jne clear_bss + +; Aufruf des C-Codes + + call _init ; Konstruktoren globaler Objekte ausfuehren + call main ; C/C++ Level System + call _fini ; Destruktoren + hlt + +;; Ausfuehrung der Konstruktoren globaler Objekte +_init: + mov edi, __init_array_start +_init_loop: + cmp edi, __init_array_end + je _init_done + mov eax, [edi] + call eax + add edi, 4 + ja _init_loop +_init_done: + ret + +;; Ausfuehrung der Destruktoren globaler Objekte +_fini: + mov edi, __fini_array_start +_fini_loop: + cmp edi, __fini_array_end + je _fini_done + mov eax, [edi] + call eax + add edi, 4 + ja _fini_loop +_fini_done: + ret + +; Default Interrupt Behandlung + +; Spezifischer Kopf der Unterbrechungsbehandlungsroutinen + +%macro wrapper 1 +wrapper_%1: + pushad ; alle Register sichern (fuer den Bluescreen) + mov ecx, int_esp ; Stack_zeiger sichern, fuer Zugriff im Bluescreen + mov [ecx], esp + mov al,%1 + jmp wrapper_body +%endmacro + +; ... wird automatisch erzeugt. +%assign i 0 +%rep 256 +wrapper i +%assign i i+1 +%endrep + +; Gemeinsamer Rumpf +wrapper_body: + cld ; das erwartet der gcc so. + push ecx ; Sichern der fluechtigen Register + push edx + and eax,0xff ; Der generierte Wrapper liefert nur 8 Bits + push eax ; Nummer der Unterbrechung uebergeben + call int_disp; Interrupt-Dispatcher aufrufen + add esp,4 ; Parameter vom Stack entfernen + pop edx ; fluechtige Register wieder herstellen + pop ecx + popad ; alle Register wiederherstellen + iret ; fertig! + +; +; setup_idt +; +; Relokation der Eintraege in der IDT und Setzen des IDTR + +setup_idt: + mov eax,wrapper_0 ; ax: niederwertige 16 Bit + mov ebx,eax + shr ebx,16 ; bx: hoeherwertige 16 Bit + mov ecx,255 ; Zaehler +.loop: add [idt+8*ecx+0],ax + adc [idt+8*ecx+6],bx + dec ecx + jge .loop + + lidt [idt_descr] + ret + +; +; reprogram_pics +; +; Neuprogrammierung der PICs (Programmierbare Interrupt-Controller), damit +; alle 15 Hardware-Interrupts nacheinander in der idt liegen. + +reprogram_pics: + mov al,0x11 ; ICW1: 8086 Modus mit ICW4 + out 0x20,al + call delay + out 0xa0,al + call delay + mov al,0x20 ; ICW2 Master: IRQ # Offset (32) + out 0x21,al + call delay + mov al,0x28 ; ICW2 Slave: IRQ # Offset (40) + out 0xa1,al + call delay + mov al,0x04 ; ICW3 Master: Slaves an IRQs + out 0x21,al + call delay + mov al,0x02 ; ICW3 Slave: Verbunden mit IRQ2 des Masters + out 0xa1,al + call delay + mov al,0x03 ; ICW4: 8086 Modus und automatischer EIO + out 0x21,al + call delay + out 0xa1,al + call delay + + mov al,0xff ; Hardware-Interrupts durch PICs + out 0xa1,al ; ausmaskieren. Nur der Interrupt 2, + call delay ; der der Kaskadierung der beiden + mov al,0xfb ; PICs dient, ist erlaubt. + out 0x21,al + + ret + +; delay +; +; Kurze Verzoegerung fuer in/out Befehle. + +delay: + jmp .L2 +.L2: ret + +; Die Funktion wird beim abarbeiten der globalen Konstruktoren aufgerufen +; (unter Linux). Das Label muss definiert sein (fuer den Linker). Die +; Funktion selbst kann aber leer sein, da bei StuBs keine Freigabe des +; Speichers erfolgen muss. + +__cxa_pure_virtual: +_ZdlPv: + ret + +; +; bios_call +; +; BIOS-Aufruf (siehe BIOS.cc) +; +bios_call: + lidt [idt16_descr] + pushf + pusha + call 0x18:0 + popa + popf + lidt [idt_descr] + ret + +; Paging aktivieren +; (siehe Paging.cc) +paging_on: + mov eax,[4+esp] ; Parameter Addr. Page-Dir. ins eax Register + mov ebx, cr4 + or ebx, 0x10 ; 4 MB Pages aktivieren + mov cr4, ebx ; CR4 schreiben + mov cr3, eax ; Page-Directory laden + mov ebx, cr0 + or ebx, 0x80010000 ; Paging aktivieren + mov cr0, ebx + ret + +; Paging-Fault-Adresse holen +; (siehe Paging.cc) +get_page_fault_address: + mov eax,cr2 + ret + +; Invalidiert eine Seite im TLB. Dies notwendig, falls eine +; die Bits Present, R/W in einem Seitentabelleneintrag +; geaendert werden. Falls die Seite im TLB gespeichert ist +; wuerde die MMU nichts von diesen Aenderungen erkennen, +; da die MMU dann nicht auf die Seitentabellen zugreift. +; (siehe Paging.cc) +invalidate_tlb_entry: + mov eax, [esp+4] + invlpg [eax] + ret + +; Auslesen von 'int_esp' +; wird im Bluescreen benoetigt, um den Stacks zuzugreifen +; +; C Prototyp: void get_int_esp (unsigned int** esp); +get_int_esp: + mov eax,[4+esp] ; esp + mov ecx, int_esp + mov [eax], ecx + ret + + +[SECTION .data] + +; 'interrupt descriptor table' mit 256 Eintraegen. + +idt: + +%macro idt_entry 1 + dw (wrapper_%1 - wrapper_0) & 0xffff + dw 0x0008 + dw 0x8e00 + dw ((wrapper_%1 - wrapper_0) & 0xffff0000) >> 16 +%endmacro + +; ... wird automatisch erzeugt. + +%assign i 0 +%rep 256 +idt_entry i +%assign i i+1 +%endrep + +idt_descr: + dw 256*8-1 ; idt enthaelt 256 Eintraege + dd idt + +; Stack und interrupt descriptor table im BSS Bereich + +[SECTION .bss] + +init_stack: + resb 4096 + +[SECTION .data] +; +; Descriptor-Tabellen +; +gdt: + dw 0,0,0,0 ; NULL Deskriptor + + dw 0xFFFF ; 4Gb - (0x100000*0x1000 = 4Gb) + dw 0x0000 ; base address=0 + dw 0x9A00 ; code read/exec + dw 0x00CF ; granularity=4096, 386 (+5th nibble of limit) + + dw 0xFFFF ; 4Gb - (0x100000*0x1000 = 4Gb) + dw 0x0000 ; base address=0 + dw 0x9200 ; data read/write + dw 0x00CF ; granularity=4096, 386 (+5th nibble of limit) + + dw 0xFFFF ; 4Gb - (0x100000*0x1000 = 4Gb) + dw 0x4000 ; 0x4000 -> base address=0x24000 (siehe BIOS.cc) + dw 09A02h ; 0x2 -> base address =0x24000 (siehe BIOS.cc) und code read/exec; + dw 0008Fh ; granularity=4096, 16-bit code + +gdt_48: + dw 0x20 ; GDT Limit=24, 3 GDT Eintraege + dd gdt ; Physikalische Adresse der GDT + + +; +; IDT des Realmode ; +; (Michael Schoettner) +; +idt16_descr: + dw 1024 ; idt enthaelt max. 1024 Eintraege + dd 0 ; Adresse 0 + +; +; Stack-Zeiger fuer Bluescreen +; (genauerer Stack-Aufbau siehe Bluescreen.cc) +; +; |-------------| +; | EFLAGS | +; |-------------| +; | CS | +; |-------------| +; | EIP | +; |-------------| +; | [ErrorCode] | +; |-------------| +; | alle Regs. | +; | (PUSHAD) | +; |-------------| <-- int_esp +int_esp: + db 0,0,0,0 +