├── img ├── picox86pcb.jpg ├── picox86back.jpg ├── picox86color.jpg ├── picox86screen.jpg ├── picox86screen2.jpg └── picox86screen3.jpg ├── picox86 ├── spiflash.h ├── tmds_encode_font_2bpp.h ├── CMakeLists.txt ├── cpux86.h ├── spiflash.c ├── main.c ├── cpux86.c ├── tmds_encode_font_2bpp.S └── VGA_ROM_F16.h └── README.md /img/picox86pcb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathijsvandenberg/picox86/HEAD/img/picox86pcb.jpg -------------------------------------------------------------------------------- /img/picox86back.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathijsvandenberg/picox86/HEAD/img/picox86back.jpg -------------------------------------------------------------------------------- /img/picox86color.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathijsvandenberg/picox86/HEAD/img/picox86color.jpg -------------------------------------------------------------------------------- /img/picox86screen.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathijsvandenberg/picox86/HEAD/img/picox86screen.jpg -------------------------------------------------------------------------------- /img/picox86screen2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathijsvandenberg/picox86/HEAD/img/picox86screen2.jpg -------------------------------------------------------------------------------- /img/picox86screen3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathijsvandenberg/picox86/HEAD/img/picox86screen3.jpg -------------------------------------------------------------------------------- /picox86/spiflash.h: -------------------------------------------------------------------------------- 1 | #ifndef SPIFLASH_H 2 | #define SPIFLASH_H 3 | 4 | void InitSPIFlash(void); 5 | void ReadJEDEC(uint8_t *); 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /picox86/tmds_encode_font_2bpp.h: -------------------------------------------------------------------------------- 1 | #ifndef _TMDS_ENCODE_FONT_2BPP_H 2 | #define _TMDS_ENCODE_FONT_2BPP_H 3 | 4 | #include "pico/types.h" 5 | 6 | // Render characters using an 8px-wide font and a per-character 2bpp 7 | // foreground/background colour. This function is fast enough to run 3 times 8 | // per scanline on one core, so RGB222 coloured text can be rendered (with 9 | // separate R/G/B colour planes). 10 | // 11 | // charbuf: pointer to the row of characters (8 bits each) for the current 12 | // scanline (byte-aligned) 13 | // 14 | // colourbuf: pointer to a list of 2bpp foreground/background colour pairs for 15 | // each character (word-aligned, least-significant first within each word) 16 | // 17 | // font_line: pointer to list of 8 pixel bitmaps, each representing the 18 | // intersection of a font character with the current scanline. (byte-aligned) 19 | 20 | void tmds_encode_font_2bpp(const uint8_t *charbuf, const uint32_t *colourbuf, 21 | uint32_t *tmdsbuf, uint n_pix, const uint8_t *font_line); 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /picox86/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Replace TMDS with 10 bit UART (same baud rate): 2 | # add_definitions(-DDVI_SERIAL_DEBUG=1) 3 | # add_definitions(-DRUN_FROM_CRYSTAL) 4 | 5 | add_executable(picox86 6 | main.c 7 | spiflash.c 8 | cpux86.c 9 | tmds_encode_font_2bpp.S 10 | tmds_encode_font_2bpp.h 11 | ) 12 | 13 | # TODO this should work ok with DVI_N_TMDS_BUFFERS=2 (perhaps need to 14 | # rearrange some pushes/pops) and also as we are monochrome the buffers are 3x 15 | # as big as they need to be 16 | #target_compile_definitions(picox86 PRIVATE DVI_VERTICAL_REPEAT=1 DVI_N_TMDS_BUFFERS=3 DVI_MONOCHROME_TMDS) 17 | target_compile_definitions(picox86 PRIVATE DVI_VERTICAL_REPEAT=1) 18 | 19 | # We have a lot in SRAM4 (particularly TMDS LUT) but don't need much stack on 20 | # core 1. Probably even 256 bytes would be fine. 21 | target_compile_definitions(picox86 PRIVATE PICO_CORE1_STACK_SIZE=0x200) 22 | 23 | 24 | 25 | target_link_libraries(picox86 26 | pico_stdlib 27 | hardware_adc 28 | hardware_spi 29 | pico_multicore 30 | #pico_util 31 | libdvi 32 | ) 33 | 34 | # create map/bin/hex file etc. 35 | pico_add_extra_outputs(picox86) 36 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # picox86 2 | x86 emulator on Raspberry Pi Pico 3 | 4 | ![](img/picox86color.jpg) 5 | Several opcodes implemented, more to go. Now in color and realtime register display 6 | 7 | 8 | ![](img/picox86pcb.jpg) 9 | PCB front, got some awful cheap solder at home, better get some good quality solder 10 | ![](img/picox86back.jpg) 11 | PCB back fitted with RAM and FLASH (and some decoup + tank capacitors) and the 8 270 Ohm resistors 12 | ![](img/picox86screen.jpg) 13 | First attempts for basic output in VGA 16x8 font 14 | ![](img/picox86screen2.jpg) 15 | Getting CPU temperature, start with register output 16 | ![](img/picox86screen3.jpg) 17 | 2021-03-03 FLASH working, can read out JEDEC to verify, print out CPU regs realtime and read first sector to boot from to 0000:7C00 (INT 0x19). Will put some initial sources online soon 18 | 19 | 20 | 21 | 22 | 23 | Quick links: 24 | 25 | [Wren6991 PicoDVI](https://github.com/Wren6991/PicoDVI) 26 | 27 | [Next186](https://opencores.org/projects/next186_soc_pc/) 28 | 29 | About this Project 30 | ----------------- 31 | 32 | I started this project inspired by the fact that the Pi Pico can actually output DVI streams without any external component (only 8 resistors and a connector). This is found and proved by Engineer Wren6991 (Check his PicoDVI repository [here](https://github.com/Wren6991/PicoDVI)) 33 | 34 | A similar x86 project is also made by Nicolae Dumitrache with his FPGA version of a 80186. This is a complete working solution, however I think it would be very cool if a simple MCU can have a minimal implementation too using PIO,DMA and some trial and error. 35 | 36 | 37 | 38 | Hardware used on bottom of PCB: 39 | 40 | - SPI Flash chip 16Mbit (for storing FDD image to boot from, Goal is that this can be programmed in circuit by USB or TTL UART) 41 | - QSPI PSRAM 64Mbit (can clock up to 133 MHz / 4bit) which results in up to 66 Mbyte/sec sequential access and about 13 Mbyte/sec random access. Goal is to offload the RAM access with PIO and a small cache. 42 | 43 | 44 | -------------------------------------------------------------------------------- /picox86/cpux86.h: -------------------------------------------------------------------------------- 1 | #ifndef _CPUX86_H 2 | #define _CPUX86_H 3 | 4 | #include 5 | #include 6 | #include "pico/stdlib.h" 7 | 8 | void x86IRQ(int irq); 9 | void InitCPU(); 10 | extern inline void CPUCycle(); 11 | static inline uint8_t ReadInstr(); 12 | static inline uint8_t ReadData(uint16_t Address); 13 | static inline void WriteData(uint16_t Address,uint8_t Value); 14 | 15 | #define ES 0 16 | #define CS 1 17 | #define SS 2 18 | #define DS 3 19 | 20 | #define AX 0 21 | #define CX 1 22 | #define DX 2 23 | #define BX 3 24 | #define SP 4 25 | #define BP 5 26 | #define SI 6 27 | #define DI 7 28 | 29 | #define AL 0 30 | #define CL 1 31 | #define DL 2 32 | #define BL 3 33 | #define AH 4 34 | #define CH 5 35 | #define DH 6 36 | #define BH 7 37 | 38 | /* 39 | #define ADD 0 40 | #define OR 1 41 | #define ADC 2 42 | #define SBB 3 43 | #define AND 4 44 | #define SUB 5 45 | #define XOR 6 46 | #define CMP 7 47 | */ 48 | 49 | 50 | typedef struct cpu_8086_s cpu_t; 51 | struct cpu_8086_s { 52 | struct { 53 | union { 54 | uint16_t ax; 55 | struct { 56 | uint8_t al; 57 | uint8_t ah; 58 | }; 59 | }; 60 | union { 61 | uint16_t cx; 62 | struct { 63 | uint8_t cl; 64 | uint8_t ch; 65 | }; 66 | }; 67 | union { 68 | uint16_t dx; 69 | struct { 70 | uint8_t dl; 71 | uint8_t dh; 72 | }; 73 | }; 74 | union { 75 | uint16_t bx; 76 | struct { 77 | uint8_t bl; 78 | uint8_t bh; 79 | }; 80 | }; 81 | uint16_t sp; 82 | uint16_t bp; 83 | uint16_t si; 84 | uint16_t di; 85 | }; 86 | struct { 87 | uint16_t es; 88 | uint16_t cs; 89 | uint16_t ss; 90 | uint16_t ds; 91 | }; 92 | uint16_t ip; 93 | union { 94 | uint16_t flags; 95 | struct { 96 | uint8_t c: 1; 97 | uint8_t : 1; 98 | uint8_t p: 1; 99 | uint8_t : 1; 100 | uint8_t a: 1; 101 | uint8_t : 1; 102 | uint8_t z: 1; 103 | uint8_t s: 1; 104 | uint8_t t: 1; 105 | uint8_t i: 1; 106 | uint8_t d: 1; 107 | uint8_t o: 1; 108 | }; 109 | }; 110 | int16_t counter; 111 | }; 112 | 113 | #endif -------------------------------------------------------------------------------- /picox86/spiflash.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "pico/stdlib.h" 5 | #include "pico/multicore.h" 6 | #include "hardware/clocks.h" 7 | #include "hardware/spi.h" 8 | #include "hardware/irq.h" 9 | #include "hardware/sync.h" 10 | #include "hardware/gpio.h" 11 | #include "hardware/vreg.h" 12 | #include "hardware/structs/bus_ctrl.h" 13 | #include "hardware/structs/ssi.h" 14 | #include "hardware/dma.h" 15 | #include "pico/sem.h" 16 | 17 | #define FLASH_PAGE_SIZE 256 18 | #define FLASH_SECTOR_SIZE 4096 19 | 20 | #define FLASH_CMD_PAGE_PROGRAM 0x02 21 | #define FLASH_CMD_READ 0x03 22 | #define FLASH_CMD_STATUS 0x05 23 | #define FLASH_CMD_WRITE_EN 0x06 24 | #define FLASH_CMD_SECTOR_ERASE 0x20 25 | #define FLASH_CMD_READ_JEDEC 0x9F 26 | 27 | #define FLASH_STATUS_BUSY_MASK 0x01 28 | 29 | #define PIN_MISO 0 30 | #define PIN_CS 1 31 | #define PIN_SCK 2 32 | #define PIN_MOSI 3 33 | 34 | static inline void cs_select(uint cs_pin) { 35 | asm volatile("nop \n nop \n nop"); // FIXME 36 | gpio_put(cs_pin, 0); 37 | asm volatile("nop \n nop \n nop"); // FIXME 38 | } 39 | 40 | static inline void cs_deselect(uint cs_pin) { 41 | asm volatile("nop \n nop \n nop"); // FIXME 42 | gpio_put(cs_pin, 1); 43 | asm volatile("nop \n nop \n nop"); // FIXME 44 | } 45 | 46 | void __not_in_flash_func(flash_read)(spi_inst_t *spi, uint cs_pin, uint32_t addr, uint8_t *buf, size_t len) { 47 | cs_select(cs_pin); 48 | uint8_t cmdbuf[4] = { 49 | FLASH_CMD_READ, 50 | addr >> 16, 51 | addr >> 8, 52 | addr 53 | }; 54 | spi_write_blocking(spi, cmdbuf, 4); 55 | spi_read_blocking(spi, 0, buf, len); 56 | cs_deselect(cs_pin); 57 | } 58 | 59 | void __not_in_flash_func(flash_write_enable)(spi_inst_t *spi, uint cs_pin) { 60 | cs_select(cs_pin); 61 | uint8_t cmd = FLASH_CMD_WRITE_EN; 62 | spi_write_blocking(spi, &cmd, 1); 63 | cs_deselect(cs_pin); 64 | } 65 | 66 | void __not_in_flash_func(flash_wait_done)(spi_inst_t *spi, uint cs_pin) { 67 | uint8_t status; 68 | do { 69 | cs_select(cs_pin); 70 | uint8_t buf[2] = {FLASH_CMD_STATUS, 0}; 71 | spi_write_read_blocking(spi, buf, buf, 2); 72 | cs_deselect(cs_pin); 73 | status = buf[1]; 74 | } while (status & FLASH_STATUS_BUSY_MASK); 75 | } 76 | 77 | void __not_in_flash_func(flash_sector_erase)(spi_inst_t *spi, uint cs_pin, uint32_t addr) { 78 | uint8_t cmdbuf[4] = { 79 | FLASH_CMD_SECTOR_ERASE, 80 | addr >> 16, 81 | addr >> 8, 82 | addr 83 | }; 84 | flash_write_enable(spi, cs_pin); 85 | cs_select(cs_pin); 86 | spi_write_blocking(spi, cmdbuf, 4); 87 | cs_deselect(cs_pin); 88 | flash_wait_done(spi, cs_pin); 89 | } 90 | 91 | void __not_in_flash_func(flash_page_program)(spi_inst_t *spi, uint cs_pin, uint32_t addr, uint8_t data[]) { 92 | uint8_t cmdbuf[4] = { 93 | FLASH_CMD_PAGE_PROGRAM, 94 | addr >> 16, 95 | addr >> 8, 96 | addr 97 | }; 98 | flash_write_enable(spi, cs_pin); 99 | cs_select(cs_pin); 100 | spi_write_blocking(spi, cmdbuf, 4); 101 | spi_write_blocking(spi, data, FLASH_PAGE_SIZE); 102 | cs_deselect(cs_pin); 103 | flash_wait_done(spi, cs_pin); 104 | } 105 | 106 | void printbuf(uint8_t buf[FLASH_PAGE_SIZE]) { 107 | for (int i = 0; i < FLASH_PAGE_SIZE; ++i) { 108 | if (i % 16 == 15) 109 | printf("%02x\n", buf[i]); 110 | else 111 | printf("%02x ", buf[i]); 112 | } 113 | } 114 | 115 | void InitSPIFlash() 116 | { 117 | // Enable SPI 0 at 1 MHz and connect to GPIOs 118 | spi_init(spi0, 16*1000 * 1000); 119 | gpio_set_function(PIN_MISO, GPIO_FUNC_SPI); 120 | gpio_set_function(PIN_SCK, GPIO_FUNC_SPI); 121 | gpio_set_function(PIN_MOSI, GPIO_FUNC_SPI); 122 | 123 | // Chip select is active-low, so we'll initialise it to a driven-high state 124 | gpio_init(PIN_CS); 125 | gpio_put(PIN_CS, 1); 126 | gpio_set_dir(PIN_CS, GPIO_OUT); 127 | 128 | } 129 | 130 | void ReadJEDEC(uint8_t * jedec) 131 | { 132 | cs_select(PIN_CS); 133 | uint8_t cmdbuf[1] = { 134 | FLASH_CMD_READ_JEDEC 135 | }; 136 | spi_write_blocking(spi0, cmdbuf,1); 137 | spi_read_blocking(spi0, 0, jedec, 3); 138 | cs_deselect(PIN_CS); 139 | 140 | } -------------------------------------------------------------------------------- /picox86/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "pico/stdlib.h" 6 | #include "pico/multicore.h" 7 | #include "hardware/clocks.h" 8 | #include "hardware/adc.h" 9 | #include "hardware/irq.h" 10 | #include "hardware/sync.h" 11 | #include "hardware/gpio.h" 12 | #include "hardware/vreg.h" 13 | #include "hardware/structs/bus_ctrl.h" 14 | #include "hardware/structs/ssi.h" 15 | #include "hardware/dma.h" 16 | #include "pico/sem.h" 17 | 18 | #include "dvi.h" 19 | #include "dvi_serialiser.h" 20 | #include "common_dvi_pin_configs.h" 21 | //#include "tmds_encode.h" 22 | #include "tmds_encode_font_2bpp.h" 23 | 24 | #include "cpux86.h" 25 | #include "spiflash.h" 26 | #include "font_8x8.h" 27 | 28 | 29 | #define DEBUG 1 30 | 31 | // ACTIVITY LED 32 | #define LED_PIN 25 33 | 34 | #define INTERRUPT_AFTER_CYCLES 1000 35 | 36 | 37 | // VGA 640x480x60 at DVDD 1.2V (1.1V seems ok too) 38 | #define FRAME_WIDTH 640 39 | #define FRAME_HEIGHT 480 40 | #define VREG_VSEL VREG_VOLTAGE_1_20 41 | #define DVI_TIMING dvi_timing_640x480p_60hz 42 | 43 | // FONT 44 | #include "VGA_ROM_F16.h" 45 | #define FONT_CHAR_WIDTH 8 46 | #define FONT_CHAR_HEIGHT 16 47 | 48 | uint8_t fontcolor[16] = { 0b000000,0b000010,0b001000,0b001010, 49 | 0b100000,0b100010,0b100100,0b101010, 50 | 0b010101,0b010111,0b011101,0b011111, 51 | 0b110101,0b110111,0b111101,0b111111}; 52 | uint8_t fontcolor_fg=0; 53 | uint8_t fontcolor_bg=0; 54 | 55 | 56 | 57 | #define CHAR_COLS (FRAME_WIDTH / FONT_CHAR_WIDTH) 58 | #define CHAR_ROWS (FRAME_HEIGHT / FONT_CHAR_HEIGHT) 59 | #define COLOUR_PLANE_SIZE_WORDS (CHAR_ROWS * CHAR_COLS * 4 / 32) 60 | 61 | struct dvi_inst dvi0; 62 | 63 | char charbuf[CHAR_ROWS * CHAR_COLS]; 64 | uint32_t colourbuf[3 * COLOUR_PLANE_SIZE_WORDS]; 65 | 66 | 67 | uint8_t VGA_ROM_F16_COLOR[4096]; 68 | 69 | 70 | 71 | int charoffset=0; 72 | int charoffset_backup=0; 73 | 74 | 75 | double ADC=0; 76 | double cputemp=0; 77 | 78 | extern cpu_t cpu; 79 | 80 | // Some prototypes to be put in seperate header files, instead of heading it in top of the main.c 81 | void InitPSRAM() 82 | { 83 | // TBD 84 | } 85 | 86 | void InitFont() 87 | { 88 | int a=0; 89 | int line=0; 90 | int chr=0; 91 | for(line=0;line<16;line++) 92 | { 93 | for(chr=0;chr<256;chr++) 94 | { 95 | VGA_ROM_F16_COLOR[a++] = VGA_ROM_F16[(chr*16)+line]; 96 | } 97 | } 98 | } 99 | 100 | 101 | // Pixel format RGB222 102 | 103 | static inline void SetColor(uint8_t fg, uint8_t bg) { 104 | fontcolor_fg = fontcolor[fg % 16]; 105 | fontcolor_bg = fontcolor[bg % 16]; 106 | 107 | } 108 | 109 | 110 | static inline void SetCharColour(uint offset, uint8_t fg, uint8_t bg) { 111 | uint bit_index = offset % 8 * 4; 112 | uint word_index = offset / 8; 113 | for (int plane = 0; plane < 3; ++plane) { 114 | uint32_t fg_bg_combined = (fg & 0x3) | (bg << 2 & 0xc); 115 | colourbuf[word_index] = (colourbuf[word_index] & ~(0xfu << bit_index)) | (fg_bg_combined << bit_index); 116 | fg >>= 2; 117 | bg >>= 2; 118 | word_index += COLOUR_PLANE_SIZE_WORDS; 119 | } 120 | } 121 | 122 | void __not_in_flash("main") core1_main() { 123 | dvi_register_irqs_this_core(&dvi0, DMA_IRQ_0); 124 | dvi_start(&dvi0); 125 | static uint8_t scanbuf[80]; 126 | static uint y = 1; 127 | uint32_t *tmdsbuf=0; 128 | 129 | for (;;) 130 | { 131 | for (uint i = 0; i < CHAR_COLS; ++i) 132 | { 133 | uint c = charbuf[i + y / FONT_CHAR_HEIGHT * CHAR_COLS]; 134 | scanbuf[i] = VGA_ROM_F16[c*16 + (y % FONT_CHAR_HEIGHT)]; 135 | } 136 | queue_remove_blocking_u32(&dvi0.q_tmds_free, &tmdsbuf); 137 | tmds_encode_1bpp((const uint32_t*)scanbuf, tmdsbuf, FRAME_WIDTH); 138 | queue_add_blocking_u32(&dvi0.q_tmds_valid, &tmdsbuf); 139 | y = (y + 1) % FRAME_HEIGHT; 140 | } 141 | } 142 | 143 | void __not_in_flash("main") core1_main_rgb222() { 144 | dvi_register_irqs_this_core(&dvi0, DMA_IRQ_0); 145 | dvi_start(&dvi0); 146 | while (true) { 147 | for (uint y = 0; y < FRAME_HEIGHT; ++y) { 148 | uint32_t *tmdsbuf; 149 | queue_remove_blocking(&dvi0.q_tmds_free, &tmdsbuf); 150 | for (int plane = 0; plane < 3; ++plane) { 151 | tmds_encode_font_2bpp( 152 | (const uint8_t*)&charbuf[y / FONT_CHAR_HEIGHT * CHAR_COLS], 153 | &colourbuf[y / FONT_CHAR_HEIGHT * (COLOUR_PLANE_SIZE_WORDS / CHAR_ROWS) + plane * COLOUR_PLANE_SIZE_WORDS], 154 | tmdsbuf + plane * (FRAME_WIDTH / DVI_SYMBOLS_PER_WORD), 155 | FRAME_WIDTH, 156 | (const uint8_t*)&VGA_ROM_F16_COLOR[y % FONT_CHAR_HEIGHT * 256] 157 | ); 158 | } 159 | queue_add_blocking(&dvi0.q_tmds_valid, &tmdsbuf); 160 | } 161 | } 162 | } 163 | 164 | 165 | 166 | void dviprintf(char * message, ...) 167 | { 168 | char buffer[80*2]; 169 | va_list args; 170 | va_start(args,message); 171 | int len = vsprintf(buffer,message,args); 172 | va_end(args); 173 | 174 | for(int x=0;x 1919) // Hit the last line (25) 183 | { 184 | memcpy(&charbuf[800],&charbuf[880],14*80); // Scroll lines 11-24 -> 10-23 185 | charoffset -= 80; 186 | 187 | // TODO: scroll the colourbuffer as well! 188 | } 189 | charbuf[charoffset] = buffer[x]; 190 | SetCharColour(charoffset,fontcolor_fg,fontcolor_bg); 191 | charoffset++; 192 | } 193 | } 194 | } 195 | 196 | void SetCursor(int y,int x) 197 | { 198 | charoffset = x+(y*CHAR_COLS); 199 | } 200 | 201 | void ClrScreen() 202 | { 203 | for (int x=0;x<(CHAR_COLS*CHAR_ROWS);x++) 204 | { 205 | charbuf[x] = 0x20; 206 | SetCharColour(x,fontcolor[7],fontcolor[0]); 207 | } 208 | } 209 | 210 | void PrintRegs() 211 | { 212 | SetColor(15,1); 213 | SetCursor(0,61); dviprintf("\xDA\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xBF"); 214 | SetCursor(1,61); dviprintf("\xB3 AX:%04X CS:%04X \xB3",cpu.ax,cpu.cs); 215 | SetCursor(2,61); dviprintf("\xB3 BX:%04X DS:%04X \xB3",cpu.bx,cpu.ds); 216 | SetCursor(3,61); dviprintf("\xB3 CX:%04X SS:%04X \xB3",cpu.cx,cpu.ss); 217 | SetCursor(4,61); dviprintf("\xB3 DX:%04X ES:%04X \xB3",cpu.dx,cpu.es); 218 | SetCursor(5,61); dviprintf("\xB3 SP:%04X BP:%04X \xB3",cpu.sp,cpu.bp); 219 | SetCursor(6,61); dviprintf("\xB3 SI:%04X DI:%04X \xB3",cpu.si,cpu.di); 220 | SetCursor(7,61); dviprintf("\xB3 IP:%04X FL:%04X \xB3",cpu.ip,cpu.flags); 221 | SetCursor(8,61); dviprintf("\xC0\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xD9"); 222 | SetColor(7,0); 223 | } 224 | 225 | int __not_in_flash("main") main() 226 | { 227 | double cnt=0; 228 | vreg_set_voltage(VREG_VSEL); 229 | sleep_ms(10); 230 | set_sys_clock_khz(DVI_TIMING.bit_clk_khz, true); 231 | setup_default_uart(); 232 | gpio_init(LED_PIN); 233 | gpio_set_dir(LED_PIN, GPIO_OUT); 234 | 235 | InitFont(); 236 | 237 | printf("Configuring DVI\n"); 238 | dvi0.timing = &DVI_TIMING; 239 | dvi0.ser_cfg = DEFAULT_DVI_SERIAL_CONFIG; 240 | dvi_init(&dvi0, next_striped_spin_lock_num(), next_striped_spin_lock_num()); 241 | ClrScreen(); 242 | 243 | 244 | 245 | printf("Core 1 start\n"); 246 | hw_set_bits(&bus_ctrl_hw->priority, BUSCTRL_BUS_PRIORITY_PROC1_BITS); 247 | //multicore_launch_core1(core1_main); 248 | multicore_launch_core1(core1_main_rgb222); 249 | 250 | charbuf[0] = 0x00; 251 | charbuf[1] = 0x10; 252 | charbuf[2] = 0x20; 253 | charbuf[3] = 0x30; 254 | charbuf[4] = 0x40; 255 | charbuf[5] = 0x50; 256 | charbuf[6] = 0x60; 257 | charbuf[7] = 0x70; 258 | charbuf[8] = 0x80; 259 | 260 | SetCursor(1,0);dviprintf("123456789"); 261 | SetCursor(2,0);dviprintf("ABCDEFGHI"); 262 | //while (1){ __wfi(); } 263 | 264 | ClrScreen(); 265 | 266 | sleep_ms(1000); 267 | SetColor(15,1); 268 | SetCursor(0,0); dviprintf("PICOx86 PC BIOS v0.1 2021 Mathijs van den Berg"); 269 | SetCursor(1,0); SetColor(7,0);dviprintf("CPU: ");SetColor(15,0);dviprintf("80186 Pi Pico"); 270 | SetCursor(2,0); SetColor(7,0);dviprintf("VIDEO: ");SetColor(15,0);dviprintf("DVI 640x480 60Hz 1bit by Luke Wren (Wren6991)"); 271 | for (int x=0;x<8193;x++) 272 | { 273 | SetCursor(3,0); dviprintf("RAM: ");SetColor(15,0);dviprintf("%4d",x);SetColor(7,0);dviprintf(" KB [");SetColor(15,0);dviprintf("Espressif ESP-PSRAM64H 64Mbit PSRAM");SetColor(7,0);dviprintf("]"); 274 | sleep_us(250); 275 | } 276 | SetCursor(4,0); SetColor(7,0);dviprintf("FDD: 1.44 MB [");SetColor(15,0);dviprintf("ADESTO AT25SF161 16Mbit SPI Flash");SetColor(7,0);dviprintf("]"); 277 | SetCursor(5,0); SetColor(7,0);dviprintf("CPUTEMP: "); 278 | 279 | 280 | // Init ADC for temperature measurement on the die 281 | adc_init(); 282 | adc_select_input(4); 283 | adc_set_temp_sensor_enabled(true); 284 | 285 | // Init PSRAM Memory 286 | InitPSRAM(); 287 | 288 | 289 | // Init FLASH Memory on SPI0 (GPIO 0,1,2,3) 290 | InitSPIFlash(); 291 | uint8_t jedec[3]; 292 | ReadJEDEC(jedec); 293 | SetCursor(7,0); dviprintf("Checking SPI Flash JEDEC: %02X %02X %02X",jedec[0],jedec[1],jedec[2]); 294 | 295 | // Load first 512 bytes of the floppy image to 0000:7C00 for booting (BIOS IRQ 0x19) 296 | InitCPU(); 297 | x86IRQ(0x19); 298 | SetCursor(8,0); dviprintf("Loaded bootsector at 0000:7C00! Booting up!",cnt); 299 | SetCursor(10,0); 300 | sleep_ms(500); 301 | cpu.counter = 0; 302 | 303 | // Infinite loop using for(;;), faster than while(1) 304 | for (;;) 305 | { 306 | CPUCycle(); 307 | 308 | //dviprintf("Testing scrolling buffer %d\n",cpu.counter); 309 | 310 | 311 | if (cpu.counter < 0 || DEBUG) 312 | { 313 | gpio_put(LED_PIN, 1); 314 | charoffset_backup = charoffset; 315 | 316 | // Print CPU Registers 317 | PrintRegs(); 318 | 319 | // Get temperature 320 | ADC = (adc_read()*3.3/4096.0); 321 | cputemp = 27 - (ADC - 0.706)/0.001721; 322 | SetCursor(5,9); SetColor(10,0); dviprintf("%3.2lf",cputemp);SetColor(7,0); dviprintf(" \xF8\x43"); 323 | 324 | cpu.counter =+ INTERRUPT_AFTER_CYCLES; 325 | charoffset = charoffset_backup; 326 | gpio_put(LED_PIN, 0); 327 | } 328 | } 329 | 330 | // This code should never run 331 | __builtin_unreachable(); 332 | } 333 | 334 | -------------------------------------------------------------------------------- /picox86/cpux86.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "pico/stdlib.h" 6 | #include "pico/multicore.h" 7 | #include "hardware/clocks.h" 8 | #include "hardware/spi.h" 9 | #include "hardware/irq.h" 10 | #include "hardware/sync.h" 11 | #include "hardware/gpio.h" 12 | #include "hardware/vreg.h" 13 | #include "hardware/structs/bus_ctrl.h" 14 | #include "hardware/structs/ssi.h" 15 | #include "hardware/dma.h" 16 | #include "pico/sem.h" 17 | #include "cpux86.h" 18 | 19 | #include "floppy.h" 20 | /* 21 | static uint8_t floppy_img[] = { 0x66, 0xB8, 0x23, 0x01, 22 | 0x66, 0xBB, 0x67, 0x45, 23 | 0x66, 0xB9, 0xAB, 0x89, 24 | 0x66, 0xBA, 0xEF, 0xCD, 25 | 0x90, 26 | 0xB0, 0x01, 27 | 0xB3, 0x02, 28 | 0xB1, 0x03, 29 | 0xB2, 0x04, 30 | 0x90, 31 | 0xB4, 0x01, 32 | 0xB7, 0x02, 33 | 0xB5, 0x03, 34 | 0xB6, 0x04, 35 | 0x90, 36 | 0x60}; 37 | */ 38 | 39 | uint8_t ram[128*1024]; 40 | cpu_t cpu; 41 | 42 | uint16_t track; 43 | uint16_t head; 44 | uint16_t sector; 45 | 46 | 47 | 48 | void dviprintf(char * message, ...); 49 | 50 | 51 | void memcpy_seg(uint16_t seg,uint16_t offset,uint8_t * src,uint32_t len) 52 | { 53 | memcpy(&ram[(seg<<4)+offset],src,len); 54 | } 55 | 56 | void x86IRQ(int irq) 57 | { 58 | switch(irq) 59 | { 60 | case 0x13: // Floppy and harddrive access 61 | 62 | // Read Disk Sectors 63 | if (cpu.ah == 2) 64 | { 65 | track = cpu.ch + (cpu.cl >> 6)*256; 66 | head = cpu.dh; 67 | sector = cpu.cl & 0x3F; 68 | 69 | dviprintf("\n[INT13,2] Read %d sector(s) from drive %d [t=%d h=%d s=%d] to %04X:%04X",cpu.al,cpu.dl,track,head,sector,cpu.es,cpu.bx); 70 | 71 | // 180k 5.12 Floppy 72 | memcpy_seg(cpu.es,cpu.bx,&floppy_img[(track*4096)+sector*512],cpu.al*512); 73 | } 74 | 75 | break; 76 | 77 | case 0x19: // Boot OS 78 | // testset for instruction test 79 | //memcpy_seg(0,0x7c00,floppy_img,sizeof(floppy_img)); 80 | 81 | // Uncomment if a floppy bootsector is present in floppy_img 82 | memcpy_seg(0,0x7c00,floppy_img,512); 83 | cpu.cs=0x0000; 84 | cpu.ds=0x3333; 85 | cpu.ip=0x7c00; 86 | break; 87 | 88 | default: dviprintf("Unhandled interrupt 0x%02X! (AH=%02X)\n",irq,cpu.ah);while (1){ __wfi(); } 89 | } 90 | } 91 | 92 | uint8_t opcode; 93 | uint8_t operand; 94 | uint8_t oi=0; // opcode byte index 95 | uint8_t seg; 96 | 97 | uint16_t * p1; 98 | uint16_t * p2; 99 | uint16_t temp; 100 | 101 | 102 | bool lock=false; 103 | bool OO=false; 104 | bool AO=false; 105 | 106 | #define endi() oi=0 107 | 108 | 109 | void push(uint16_t value) 110 | { 111 | cpu.sp--; 112 | cpu.sp--; 113 | ram[(cpu.ss << 4) + cpu.sp]=(value >> 0) & 0xFF; 114 | ram[(cpu.ss << 4) + cpu.sp+1]=(value >> 8) & 0xFF; 115 | } 116 | 117 | void pop(uint16_t * value) 118 | { 119 | *value = ram[(cpu.ss << 4) + cpu.sp] + (ram[(cpu.ss << 4) + cpu.sp+1] << 8); 120 | cpu.sp++; 121 | cpu.sp++; 122 | } 123 | 124 | void x86OUT(uint16_t address, uint16_t value) 125 | { 126 | dviprintf("\n[OUT] PORT[%04X]=0x%04X",address,value); 127 | } 128 | 129 | void InitCPU() 130 | { 131 | cpu.ax=0x5555; 132 | cpu.bx=0x7c00; 133 | cpu.cx=0x0001; 134 | cpu.dx=0x0000; 135 | 136 | cpu.si=0x0000; 137 | cpu.di=0xfffe; 138 | cpu.bp=0x0000; 139 | cpu.sp=0x0100; 140 | 141 | cpu.ds=0x0000; 142 | cpu.cs=0x0000; 143 | cpu.es=0x0000; 144 | cpu.ss=0x7000; 145 | 146 | cpu.flags = 0x0000; 147 | cpu.i = 1; 148 | } 149 | /* 150 | inline void ModR16(uint8_t op1,uint8_t op2) 151 | { 152 | // Register addressing mode 153 | if (((op1 >> 6) & 0x03) == 0x00 154 | { 155 | switch ((op1 >> 3) & 0x07) 156 | { 157 | case 0: p1 = &cpu.es;break; 158 | case 1: p1 = &cpu.cs;break; 159 | case 2: p1 = &cpu.ss;break; 160 | case 3: p1 = &cpu.ds;break; 161 | case 4: p1 = &cpu.es;break; 162 | case 5: p1 = &cpu.cs;break; 163 | case 6: p1 = &cpu.ss;break; 164 | case 7: p1 = &cpu.ds;break; 165 | 166 | default: break; 167 | } 168 | } 169 | } 170 | */ 171 | 172 | 173 | static inline uint8_t EffectiveAddress(uint16_t * reg,uint16_t index) 174 | { 175 | uint16_t address; 176 | 177 | switch(*reg) 178 | { 179 | case 0: address = cpu.bx + cpu.si;break; 180 | case 1: address = cpu.bx + cpu.di;break; 181 | case 2: address = cpu.bp + cpu.si;break; 182 | case 3: address = cpu.bp + cpu.si;break; 183 | case 4: address = cpu.si + cpu.si;break; 184 | case 5: address = cpu.di + cpu.si;break; 185 | case 6: address = cpu.bx + cpu.si;break; 186 | case 7: address = cpu.bx + cpu.si;break; 187 | 188 | } 189 | 190 | switch (seg) 191 | { 192 | case ES: return(ram[(cpu.es << 4) + address]); 193 | } 194 | 195 | } 196 | 197 | 198 | inline void ModRegRMSeg(uint8_t opcode) 199 | { 200 | // Register addressing mode 201 | if (((opcode >> 6) & 0x03) == 0x03) 202 | { 203 | switch ((opcode >> 3) & 0x07) 204 | { 205 | case ES: p1 = &cpu.es;break; 206 | case CS: p1 = &cpu.cs;break; 207 | case SS: p1 = &cpu.ss;break; 208 | case DS: p1 = &cpu.ds;break; 209 | default: break; 210 | } 211 | 212 | switch ((opcode >> 0) & 0x07) 213 | { 214 | case AX: p2 = &cpu.ax;break; 215 | case CX: p2 = &cpu.cx;break; 216 | case DX: p2 = &cpu.dx;break; 217 | case BX: p2 = &cpu.bx;break; 218 | case SP: p2 = &cpu.sp;break; 219 | case BP: p2 = &cpu.bp;break; 220 | case SI: p2 = &cpu.si;break; 221 | case DI: p2 = &cpu.di;break; 222 | default: break; 223 | } 224 | } 225 | } 226 | 227 | inline void ModRegRM(uint8_t opcode) 228 | { 229 | // Register addressing mode Mod=11 230 | if (((opcode >> 6) & 0x03) == 0x03) 231 | { 232 | switch ((opcode >> 3) & 0x07) 233 | { 234 | case AX: p1 = &cpu.ax;break; 235 | case CX: p1 = &cpu.cx;break; 236 | case DX: p1 = &cpu.dx;break; 237 | case BX: p1 = &cpu.bx;break; 238 | case SP: p1 = &cpu.sp;break; 239 | case BP: p1 = &cpu.bp;break; 240 | case SI: p1 = &cpu.si;break; 241 | case DI: p1 = &cpu.di;break; 242 | default: break; 243 | } 244 | 245 | switch ((opcode >> 0) & 0x07) 246 | { 247 | case AX: p2 = &cpu.ax;break; 248 | case CX: p2 = &cpu.cx;break; 249 | case DX: p2 = &cpu.dx;break; 250 | case BX: p2 = &cpu.bx;break; 251 | case SP: p2 = &cpu.sp;break; 252 | case BP: p2 = &cpu.bp;break; 253 | case SI: p2 = &cpu.si;break; 254 | case DI: p2 = &cpu.di;break; 255 | default: break; 256 | } 257 | } 258 | } 259 | 260 | inline void CPUCycle() 261 | { 262 | sleep_ms(100); 263 | opcode = ReadInstr(); 264 | 265 | switch(opcode) 266 | { 267 | // Illegal 268 | case 0x00: sleep_ms(500);endi();break; 269 | 270 | // NOP 271 | case 0x90: endi();break; 272 | 273 | // OUT 274 | case 0xE6: x86OUT(cpu.al,ReadInstr());endi();break; 275 | case 0xE7: x86OUT(cpu.ax,ReadInstr());endi();break; 276 | case 0xEE: x86OUT(cpu.al,cpu.dx);endi();break; 277 | case 0xEF: x86OUT(cpu.ax,cpu.dx);endi();break; 278 | 279 | // JMP 280 | //case 0xEA: cp 281 | case 0xEB: cpu.ip=cpu.ip+ReadInstr()+1;endi();break; 282 | 283 | 284 | 285 | // JC 286 | case 0x72: if (cpu.c) { cpu.ip += (int8_t)(ReadInstr());} else {ReadInstr(); } 287 | 288 | //CLI 289 | case 0xFA: cpu.i=0;endi();break; 290 | 291 | //STI 292 | case 0xFB: cpu.i=1;endi();break; 293 | 294 | // CALL (rel16) 295 | case 0xE8: temp = ReadInstr()+256*ReadInstr(); 296 | push(cpu.ip); 297 | cpu.ip += temp; 298 | endi();break; 299 | 300 | //INT 301 | case 0xCD: x86IRQ(ReadInstr());endi();break; 302 | 303 | //MOV 8B Reg to Reg 304 | case 0x8B: ModRegRM(ReadInstr());*p1=*p2;endi();break; 305 | 306 | //MOV 8C Reg to Seg 307 | case 0x8C: ModRegRMSeg(ReadInstr());*p2=*p1;endi();break; 308 | 309 | //MOV 8E Seg to Reg 310 | case 0x8E: ModRegRMSeg(ReadInstr());*p1=*p2;endi();break; 311 | 312 | // MOV AX,DS:[XXXX] 313 | case 0xA1: cpu.ax = ReadData(ReadInstr()+256*ReadInstr());endi();break; 314 | 315 | //MOV Immediate to Reg 316 | case 0xB0: cpu.al=ReadInstr();endi();break; 317 | case 0xB1: cpu.cl=ReadInstr();endi();break; 318 | case 0xB2: cpu.dl=ReadInstr();endi();break; 319 | case 0xB3: cpu.bl=ReadInstr();endi();break; 320 | case 0xB4: cpu.ah=ReadInstr();endi();break; 321 | case 0xB5: cpu.ch=ReadInstr();endi();break; 322 | case 0xB6: cpu.dh=ReadInstr();endi();break; 323 | case 0xB7: cpu.bh=ReadInstr();endi();break; 324 | 325 | case 0xB8: cpu.ax=ReadInstr()+256*ReadInstr();endi();break; 326 | case 0xB9: cpu.cx=ReadInstr()+256*ReadInstr();endi();break; 327 | case 0xBA: cpu.dx=ReadInstr()+256*ReadInstr();endi();break; 328 | case 0xBB: cpu.bx=ReadInstr()+256*ReadInstr();endi();break; 329 | case 0xBC: cpu.sp=ReadInstr()+256*ReadInstr();endi();break; 330 | case 0xBD: cpu.bp=ReadInstr()+256*ReadInstr();endi();break; 331 | case 0xBE: cpu.si=ReadInstr()+256*ReadInstr();endi();break; 332 | case 0xBF: cpu.di=ReadInstr()+256*ReadInstr();endi();break; 333 | 334 | // PUSH registers 335 | case 0x50: push(cpu.ax);endi();break; 336 | case 0x51: push(cpu.cx);endi();break; 337 | case 0x52: push(cpu.dx);endi();break; 338 | case 0x53: push(cpu.bx);endi();break; 339 | case 0x54: push(cpu.sp);endi();break; 340 | case 0x55: push(cpu.bp);endi();break; 341 | case 0x56: push(cpu.si);endi();break; 342 | case 0x57: push(cpu.di);endi();break; 343 | case 0x9C: push(cpu.flags);endi();break; 344 | 345 | // PUSH segments 346 | case 0x06: push(cpu.es);endi();break; 347 | case 0x0E: push(cpu.cs);endi();break; 348 | case 0x16: push(cpu.ss);endi();break; 349 | case 0x1e: push(cpu.ds);endi();break; 350 | 351 | // POP registers 352 | case 0x58: pop(&cpu.ax);endi();break; 353 | case 0x59: pop(&cpu.cx);endi();break; 354 | case 0x5A: pop(&cpu.dx);endi();break; 355 | case 0x5B: pop(&cpu.bx);endi();break; 356 | case 0x5C: pop(&cpu.sp);endi();break; 357 | case 0x5D: pop(&cpu.bp);endi();break; 358 | case 0x5E: pop(&cpu.si);endi();break; 359 | case 0x5F: pop(&cpu.di);endi();break; 360 | case 0x9D: pop(&cpu.flags);endi();break; 361 | 362 | // POP segments 363 | case 0x07: pop(&cpu.es);endi();break; 364 | case 0x0F: pop(&cpu.cs);endi();break; 365 | case 0x17: pop(&cpu.ss);endi();break; 366 | case 0x1F: pop(&cpu.ds);endi();break; 367 | 368 | 369 | // Segment override prefix 370 | case 0x26: seg=ES;break; 371 | case 0x2E: seg=CS;break; 372 | case 0x36: seg=SS;break; 373 | case 0x3E: seg=DS;break; 374 | 375 | // Operand size override prefix 376 | case 0x66: OO=true;break; 377 | 378 | // Address size override prefix 379 | case 0x67: AO=true;break; 380 | 381 | // Repeat/lock prefix 382 | case 0xF0: lock=true;break; // LOCK 383 | 384 | // String manipulation prefixes 385 | case 0xF2: break; // REPNE/REPNZ 386 | case 0xF3: break; // REPE/REPZ 387 | 388 | default: 389 | dviprintf("Unknown opcode '%02X'. System halted!",opcode); 390 | while (1){ __wfi(); } 391 | break; 392 | } 393 | cpu.counter--; 394 | 395 | } 396 | 397 | 398 | static inline uint8_t ReadInstr() 399 | { 400 | if (oi==0) // New opcode to parse 401 | { 402 | dviprintf("\n[%04X:%04X] ",cpu.cs,cpu.ip); 403 | } 404 | dviprintf("%02X ",ram[(cpu.cs << 4) + cpu.ip]); 405 | oi++; 406 | return(ram[(cpu.cs << 4) + cpu.ip++]); 407 | } 408 | 409 | 410 | 411 | static inline uint8_t ReadData(uint16_t Address) 412 | { 413 | return(ram[(cpu.ds << 4) + Address]); 414 | } 415 | 416 | static inline void WriteData(uint16_t Address,uint8_t Value) 417 | { 418 | ram[(cpu.ds << 4) + Address]=Value; 419 | } -------------------------------------------------------------------------------- /picox86/tmds_encode_font_2bpp.S: -------------------------------------------------------------------------------- 1 | #include "hardware/regs/addressmap.h" 2 | #include "hardware/regs/sio.h" 3 | 4 | .syntax unified 5 | .cpu cortex-m0plus 6 | .thumb 7 | 8 | // Using the following: 9 | // 10 | // - A font stored as a 1bpp bitmap, with row 0 of each character stored in 11 | // one contiguous array, then row 1, etc, where each character is 8 bits 12 | // wide 13 | // 14 | // - A character buffer 15 | // 16 | // - A colour buffer for each of R, G, B (so 3 planes total), each buffer 17 | // storing a 2-bit foreground and background colour for each character 18 | // 19 | // Generate encoded TMDS buffers, fast enough to fit all the encode on one 20 | // core, and with small memory footprint (so no framebuffer of any depth!) The 21 | // main trick here is a LUT with an 8 bit index, composed of 4x1bpp pixels 22 | // (the 4 LSBs of the index) and a 2x2-bit palette (the four MSBs of the 23 | // index). Each LUT entry is 4 TMDS symbols, so 2 32-bit words, giving a total 24 | // table size of 2 kB. 25 | 26 | // Offsets suitable for ldr/str (must be <= 0x7c): 27 | #define ACCUM0_OFFS (SIO_INTERP0_ACCUM0_OFFSET - SIO_INTERP0_ACCUM0_OFFSET) 28 | #define ACCUM1_OFFS (SIO_INTERP0_ACCUM1_OFFSET - SIO_INTERP0_ACCUM0_OFFSET) 29 | #define ACCUM1_ADD_OFFS (SIO_INTERP0_ACCUM1_ADD_OFFSET - SIO_INTERP0_ACCUM0_OFFSET) 30 | #define PEEK0_OFFS (SIO_INTERP0_PEEK_LANE0_OFFSET - SIO_INTERP0_ACCUM0_OFFSET) 31 | #define PEEK1_OFFS (SIO_INTERP0_PEEK_LANE1_OFFSET - SIO_INTERP0_ACCUM0_OFFSET) 32 | #define PEEK2_OFFS (SIO_INTERP0_PEEK_FULL_OFFSET - SIO_INTERP0_ACCUM0_OFFSET) 33 | #define INTERP1 (SIO_INTERP1_ACCUM0_OFFSET - SIO_INTERP0_ACCUM0_OFFSET) 34 | 35 | // There is no vertical repeat, so the the budget (ignoring DMA IRQs) is 8000 36 | // cycles per 640 pixels, and there are three symbols to be generated per 37 | // pixel, so 4.17 cyc/pix. 38 | 39 | 40 | // Once in the loop: 41 | // r0 contains character buffer pointer (only updated once per 8 chars) 42 | // r1 contains 8 2-colour 2bpp palettes, enough for 8 characters 43 | // r2 contains output buffer pointer 44 | // r3 contains a mask for the colour lookup bits 45 | // r4-r7 are for scratch + pixels 46 | // r8 contains a pointer to the font bitmap for this scanline. 47 | // r9 contains the TMDS LUT base. 48 | .macro do_char charbuf_offs colour_shift_instr colour_shamt 49 | // Get 8x font bits for next character, put 4 LSBs in bits 6:3 of r4 (so 50 | // scaled to 8-byte LUT entries), and 4 MSBs in bits 6:3 of r6. 51 | ldrb r4, [r0, #\charbuf_offs] // 2 52 | add r4, r8 // 1 53 | ldrb r4, [r4] // 2 54 | lsrs r6, r4, #4 // 1 55 | lsls r6, #3 // 1 56 | lsls r4, #28 // 1 57 | lsrs r4, #25 // 1 58 | 59 | // Get colour bits, add to TMDS LUT base and font bits 60 | \colour_shift_instr r5, r1, #\colour_shamt // 1 61 | ands r5, r3 // 1 62 | add r5, r9 // 1 63 | add r4, r5 // 1 64 | add r6, r5 // 1 65 | 66 | // Look up and write out 8 TMDS symbols 67 | ldmia r4, {r4, r5} // 3 68 | ldmia r6, {r6, r7} // 3 69 | stmia r2!, {r4-r7} // 5 70 | .endm 71 | 72 | 73 | // r0 is character buffer 74 | // r1 is colour buffer 75 | // r2 is output TMDS buffer 76 | // r3 is pixel count 77 | // First stack argument is the font bitmap for this scanline. 78 | 79 | .section .scratch_x.tmds_encode_font_2bpp, "ax" 80 | .global tmds_encode_font_2bpp 81 | .type tmds_encode_font_2bpp,%function 82 | .thumb_func 83 | tmds_encode_font_2bpp: 84 | push {r4-r7, lr} 85 | mov r4, r8 86 | mov r5, r9 87 | mov r6, r10 88 | push {r4-r6} 89 | 90 | lsls r3, #1 91 | add r3, r2 92 | mov ip, r3 93 | ldr r3, =(0xf0 * 8) 94 | 95 | ldr r7, [sp, #32] // 8 words saved, so 32-byte offset to first stack argument 96 | mov r8, r7 97 | ldr r7, =palettised_1bpp_tables 98 | mov r9, r7 99 | 100 | mov r10, r1 101 | 102 | b 2f 103 | 1: 104 | mov r4, r10 105 | ldmia r4!, {r1} 106 | mov r10, r4 107 | do_char 0 lsls 7 108 | do_char 1 lsls 3 109 | do_char 2 lsrs 1 110 | do_char 3 lsrs 5 111 | do_char 4 lsrs 9 112 | do_char 5 lsrs 13 113 | do_char 6 lsrs 17 114 | do_char 7 lsrs 21 115 | adds r0, #8 116 | 2: 117 | cmp r2, ip 118 | blo 1b 119 | 120 | pop {r4-r6} 121 | mov r8, r4 122 | mov r9, r5 123 | mov r10, r6 124 | pop {r4-r7, pc} 125 | 126 | 127 | // Table generation: 128 | // levels_2bpp_even = [0x05, 0x50, 0xaf, 0xfa] 129 | // levels_2bpp_odd = [0x04, 0x51, 0xae, 0xfb] 130 | // 131 | // def level(bg, fg, x, pix): 132 | // index = fg if pix & 1 << x else bg 133 | // return (levels_2bpp_odd if x & 1 else levels_2bpp_even)[index] 134 | // 135 | // for background in range(4): 136 | // for foreground in range(4): 137 | // print(f"// background, foreground = {background:02b}, {foreground:02b}") 138 | // for pixrun in range(16): 139 | // sym = list(enc.encode(level(background, foreground, x, pixrun), 0, 1) for x in range(4)) 140 | // assert(enc.imbalance == 0) 141 | // print(f".word 0x{sym[1] << 10 | sym[0]:05x}, 0x{sym[3] << 10 | sym[2]:05x} // {pixrun:04b}") 142 | 143 | .section .scratch_x.palettised_1bpp_tables, "a" 144 | .align 2 145 | palettised_1bpp_tables: 146 | // background, foreground = 00, 00 147 | .word 0x7f103, 0x7f103 // 0000 148 | .word 0x7f103, 0x7f103 // 0001 149 | .word 0x7f103, 0x7f103 // 0010 150 | .word 0x7f103, 0x7f103 // 0011 151 | .word 0x7f103, 0x7f103 // 0100 152 | .word 0x7f103, 0x7f103 // 0101 153 | .word 0x7f103, 0x7f103 // 0110 154 | .word 0x7f103, 0x7f103 // 0111 155 | .word 0x7f103, 0x7f103 // 1000 156 | .word 0x7f103, 0x7f103 // 1001 157 | .word 0x7f103, 0x7f103 // 1010 158 | .word 0x7f103, 0x7f103 // 1011 159 | .word 0x7f103, 0x7f103 // 1100 160 | .word 0x7f103, 0x7f103 // 1101 161 | .word 0x7f103, 0x7f103 // 1110 162 | .word 0x7f103, 0x7f103 // 1111 163 | // background, foreground = 00, 01 164 | .word 0x7f103, 0x7f103 // 0000 165 | .word 0x7f130, 0x7f103 // 0001 166 | .word 0x73d03, 0x7f103 // 0010 167 | .word 0x73d30, 0x7f103 // 0011 168 | .word 0x7f103, 0x7f130 // 0100 169 | .word 0x7f130, 0x7f130 // 0101 170 | .word 0x73d03, 0x7f130 // 0110 171 | .word 0x73d30, 0x7f130 // 0111 172 | .word 0x7f103, 0x73d03 // 1000 173 | .word 0x7f130, 0x73d03 // 1001 174 | .word 0x73d03, 0x73d03 // 1010 175 | .word 0x73d30, 0x73d03 // 1011 176 | .word 0x7f103, 0x73d30 // 1100 177 | .word 0x7f130, 0x73d30 // 1101 178 | .word 0x73d03, 0x73d30 // 1110 179 | .word 0x73d30, 0x73d30 // 1111 180 | // background, foreground = 00, 10 181 | .word 0x7f103, 0x7f103 // 0000 182 | .word 0x7f230, 0x7f103 // 0001 183 | .word 0xb3d03, 0x7f103 // 0010 184 | .word 0xb3e30, 0x7f103 // 0011 185 | .word 0x7f103, 0x7f230 // 0100 186 | .word 0x7f230, 0x7f230 // 0101 187 | .word 0xb3d03, 0x7f230 // 0110 188 | .word 0xb3e30, 0x7f230 // 0111 189 | .word 0x7f103, 0xb3d03 // 1000 190 | .word 0x7f230, 0xb3d03 // 1001 191 | .word 0xb3d03, 0xb3d03 // 1010 192 | .word 0xb3e30, 0xb3d03 // 1011 193 | .word 0x7f103, 0xb3e30 // 1100 194 | .word 0x7f230, 0xb3e30 // 1101 195 | .word 0xb3d03, 0xb3e30 // 1110 196 | .word 0xb3e30, 0xb3e30 // 1111 197 | // background, foreground = 00, 11 198 | .word 0x7f103, 0x7f103 // 0000 199 | .word 0x7f203, 0x7f103 // 0001 200 | .word 0xbf103, 0x7f103 // 0010 201 | .word 0xbf203, 0x7f103 // 0011 202 | .word 0x7f103, 0x7f203 // 0100 203 | .word 0x7f203, 0x7f203 // 0101 204 | .word 0xbf103, 0x7f203 // 0110 205 | .word 0xbf203, 0x7f203 // 0111 206 | .word 0x7f103, 0xbf103 // 1000 207 | .word 0x7f203, 0xbf103 // 1001 208 | .word 0xbf103, 0xbf103 // 1010 209 | .word 0xbf203, 0xbf103 // 1011 210 | .word 0x7f103, 0xbf203 // 1100 211 | .word 0x7f203, 0xbf203 // 1101 212 | .word 0xbf103, 0xbf203 // 1110 213 | .word 0xbf203, 0xbf203 // 1111 214 | // background, foreground = 01, 00 215 | .word 0x73d30, 0x73d30 // 0000 216 | .word 0x73d03, 0x73d30 // 0001 217 | .word 0x7f130, 0x73d30 // 0010 218 | .word 0x7f103, 0x73d30 // 0011 219 | .word 0x73d30, 0x73d03 // 0100 220 | .word 0x73d03, 0x73d03 // 0101 221 | .word 0x7f130, 0x73d03 // 0110 222 | .word 0x7f103, 0x73d03 // 0111 223 | .word 0x73d30, 0x7f130 // 1000 224 | .word 0x73d03, 0x7f130 // 1001 225 | .word 0x7f130, 0x7f130 // 1010 226 | .word 0x7f103, 0x7f130 // 1011 227 | .word 0x73d30, 0x7f103 // 1100 228 | .word 0x73d03, 0x7f103 // 1101 229 | .word 0x7f130, 0x7f103 // 1110 230 | .word 0x7f103, 0x7f103 // 1111 231 | // background, foreground = 01, 01 232 | .word 0x73d30, 0x73d30 // 0000 233 | .word 0x73d30, 0x73d30 // 0001 234 | .word 0x73d30, 0x73d30 // 0010 235 | .word 0x73d30, 0x73d30 // 0011 236 | .word 0x73d30, 0x73d30 // 0100 237 | .word 0x73d30, 0x73d30 // 0101 238 | .word 0x73d30, 0x73d30 // 0110 239 | .word 0x73d30, 0x73d30 // 0111 240 | .word 0x73d30, 0x73d30 // 1000 241 | .word 0x73d30, 0x73d30 // 1001 242 | .word 0x73d30, 0x73d30 // 1010 243 | .word 0x73d30, 0x73d30 // 1011 244 | .word 0x73d30, 0x73d30 // 1100 245 | .word 0x73d30, 0x73d30 // 1101 246 | .word 0x73d30, 0x73d30 // 1110 247 | .word 0x73d30, 0x73d30 // 1111 248 | // background, foreground = 01, 10 249 | .word 0x73d30, 0x73d30 // 0000 250 | .word 0x73e30, 0x73d30 // 0001 251 | .word 0xb3d30, 0x73d30 // 0010 252 | .word 0xb3e30, 0x73d30 // 0011 253 | .word 0x73d30, 0x73e30 // 0100 254 | .word 0x73e30, 0x73e30 // 0101 255 | .word 0xb3d30, 0x73e30 // 0110 256 | .word 0xb3e30, 0x73e30 // 0111 257 | .word 0x73d30, 0xb3d30 // 1000 258 | .word 0x73e30, 0xb3d30 // 1001 259 | .word 0xb3d30, 0xb3d30 // 1010 260 | .word 0xb3e30, 0xb3d30 // 1011 261 | .word 0x73d30, 0xb3e30 // 1100 262 | .word 0x73e30, 0xb3e30 // 1101 263 | .word 0xb3d30, 0xb3e30 // 1110 264 | .word 0xb3e30, 0xb3e30 // 1111 265 | // background, foreground = 01, 11 266 | .word 0x73d30, 0x73d30 // 0000 267 | .word 0x73e03, 0x73d30 // 0001 268 | .word 0xbf130, 0x73d30 // 0010 269 | .word 0xbf203, 0x73d30 // 0011 270 | .word 0x73d30, 0x73e03 // 0100 271 | .word 0x73e03, 0x73e03 // 0101 272 | .word 0xbf130, 0x73e03 // 0110 273 | .word 0xbf203, 0x73e03 // 0111 274 | .word 0x73d30, 0xbf130 // 1000 275 | .word 0x73e03, 0xbf130 // 1001 276 | .word 0xbf130, 0xbf130 // 1010 277 | .word 0xbf203, 0xbf130 // 1011 278 | .word 0x73d30, 0xbf203 // 1100 279 | .word 0x73e03, 0xbf203 // 1101 280 | .word 0xbf130, 0xbf203 // 1110 281 | .word 0xbf203, 0xbf203 // 1111 282 | // background, foreground = 10, 00 283 | .word 0xb3e30, 0xb3e30 // 0000 284 | .word 0xb3d03, 0xb3e30 // 0001 285 | .word 0x7f230, 0xb3e30 // 0010 286 | .word 0x7f103, 0xb3e30 // 0011 287 | .word 0xb3e30, 0xb3d03 // 0100 288 | .word 0xb3d03, 0xb3d03 // 0101 289 | .word 0x7f230, 0xb3d03 // 0110 290 | .word 0x7f103, 0xb3d03 // 0111 291 | .word 0xb3e30, 0x7f230 // 1000 292 | .word 0xb3d03, 0x7f230 // 1001 293 | .word 0x7f230, 0x7f230 // 1010 294 | .word 0x7f103, 0x7f230 // 1011 295 | .word 0xb3e30, 0x7f103 // 1100 296 | .word 0xb3d03, 0x7f103 // 1101 297 | .word 0x7f230, 0x7f103 // 1110 298 | .word 0x7f103, 0x7f103 // 1111 299 | // background, foreground = 10, 01 300 | .word 0xb3e30, 0xb3e30 // 0000 301 | .word 0xb3d30, 0xb3e30 // 0001 302 | .word 0x73e30, 0xb3e30 // 0010 303 | .word 0x73d30, 0xb3e30 // 0011 304 | .word 0xb3e30, 0xb3d30 // 0100 305 | .word 0xb3d30, 0xb3d30 // 0101 306 | .word 0x73e30, 0xb3d30 // 0110 307 | .word 0x73d30, 0xb3d30 // 0111 308 | .word 0xb3e30, 0x73e30 // 1000 309 | .word 0xb3d30, 0x73e30 // 1001 310 | .word 0x73e30, 0x73e30 // 1010 311 | .word 0x73d30, 0x73e30 // 1011 312 | .word 0xb3e30, 0x73d30 // 1100 313 | .word 0xb3d30, 0x73d30 // 1101 314 | .word 0x73e30, 0x73d30 // 1110 315 | .word 0x73d30, 0x73d30 // 1111 316 | // background, foreground = 10, 10 317 | .word 0xb3e30, 0xb3e30 // 0000 318 | .word 0xb3e30, 0xb3e30 // 0001 319 | .word 0xb3e30, 0xb3e30 // 0010 320 | .word 0xb3e30, 0xb3e30 // 0011 321 | .word 0xb3e30, 0xb3e30 // 0100 322 | .word 0xb3e30, 0xb3e30 // 0101 323 | .word 0xb3e30, 0xb3e30 // 0110 324 | .word 0xb3e30, 0xb3e30 // 0111 325 | .word 0xb3e30, 0xb3e30 // 1000 326 | .word 0xb3e30, 0xb3e30 // 1001 327 | .word 0xb3e30, 0xb3e30 // 1010 328 | .word 0xb3e30, 0xb3e30 // 1011 329 | .word 0xb3e30, 0xb3e30 // 1100 330 | .word 0xb3e30, 0xb3e30 // 1101 331 | .word 0xb3e30, 0xb3e30 // 1110 332 | .word 0xb3e30, 0xb3e30 // 1111 333 | // background, foreground = 10, 11 334 | .word 0xb3e30, 0xb3e30 // 0000 335 | .word 0xb3e03, 0xb3e30 // 0001 336 | .word 0xbf230, 0xb3e30 // 0010 337 | .word 0xbf203, 0xb3e30 // 0011 338 | .word 0xb3e30, 0xb3e03 // 0100 339 | .word 0xb3e03, 0xb3e03 // 0101 340 | .word 0xbf230, 0xb3e03 // 0110 341 | .word 0xbf203, 0xb3e03 // 0111 342 | .word 0xb3e30, 0xbf230 // 1000 343 | .word 0xb3e03, 0xbf230 // 1001 344 | .word 0xbf230, 0xbf230 // 1010 345 | .word 0xbf203, 0xbf230 // 1011 346 | .word 0xb3e30, 0xbf203 // 1100 347 | .word 0xb3e03, 0xbf203 // 1101 348 | .word 0xbf230, 0xbf203 // 1110 349 | .word 0xbf203, 0xbf203 // 1111 350 | // background, foreground = 11, 00 351 | .word 0xbf203, 0xbf203 // 0000 352 | .word 0xbf103, 0xbf203 // 0001 353 | .word 0x7f203, 0xbf203 // 0010 354 | .word 0x7f103, 0xbf203 // 0011 355 | .word 0xbf203, 0xbf103 // 0100 356 | .word 0xbf103, 0xbf103 // 0101 357 | .word 0x7f203, 0xbf103 // 0110 358 | .word 0x7f103, 0xbf103 // 0111 359 | .word 0xbf203, 0x7f203 // 1000 360 | .word 0xbf103, 0x7f203 // 1001 361 | .word 0x7f203, 0x7f203 // 1010 362 | .word 0x7f103, 0x7f203 // 1011 363 | .word 0xbf203, 0x7f103 // 1100 364 | .word 0xbf103, 0x7f103 // 1101 365 | .word 0x7f203, 0x7f103 // 1110 366 | .word 0x7f103, 0x7f103 // 1111 367 | // background, foreground = 11, 01 368 | .word 0xbf203, 0xbf203 // 0000 369 | .word 0xbf130, 0xbf203 // 0001 370 | .word 0x73e03, 0xbf203 // 0010 371 | .word 0x73d30, 0xbf203 // 0011 372 | .word 0xbf203, 0xbf130 // 0100 373 | .word 0xbf130, 0xbf130 // 0101 374 | .word 0x73e03, 0xbf130 // 0110 375 | .word 0x73d30, 0xbf130 // 0111 376 | .word 0xbf203, 0x73e03 // 1000 377 | .word 0xbf130, 0x73e03 // 1001 378 | .word 0x73e03, 0x73e03 // 1010 379 | .word 0x73d30, 0x73e03 // 1011 380 | .word 0xbf203, 0x73d30 // 1100 381 | .word 0xbf130, 0x73d30 // 1101 382 | .word 0x73e03, 0x73d30 // 1110 383 | .word 0x73d30, 0x73d30 // 1111 384 | // background, foreground = 11, 10 385 | .word 0xbf203, 0xbf203 // 0000 386 | .word 0xbf230, 0xbf203 // 0001 387 | .word 0xb3e03, 0xbf203 // 0010 388 | .word 0xb3e30, 0xbf203 // 0011 389 | .word 0xbf203, 0xbf230 // 0100 390 | .word 0xbf230, 0xbf230 // 0101 391 | .word 0xb3e03, 0xbf230 // 0110 392 | .word 0xb3e30, 0xbf230 // 0111 393 | .word 0xbf203, 0xb3e03 // 1000 394 | .word 0xbf230, 0xb3e03 // 1001 395 | .word 0xb3e03, 0xb3e03 // 1010 396 | .word 0xb3e30, 0xb3e03 // 1011 397 | .word 0xbf203, 0xb3e30 // 1100 398 | .word 0xbf230, 0xb3e30 // 1101 399 | .word 0xb3e03, 0xb3e30 // 1110 400 | .word 0xb3e30, 0xb3e30 // 1111 401 | // background, foreground = 11, 11 402 | .word 0xbf203, 0xbf203 // 0000 403 | .word 0xbf203, 0xbf203 // 0001 404 | .word 0xbf203, 0xbf203 // 0010 405 | .word 0xbf203, 0xbf203 // 0011 406 | .word 0xbf203, 0xbf203 // 0100 407 | .word 0xbf203, 0xbf203 // 0101 408 | .word 0xbf203, 0xbf203 // 0110 409 | .word 0xbf203, 0xbf203 // 0111 410 | .word 0xbf203, 0xbf203 // 1000 411 | .word 0xbf203, 0xbf203 // 1001 412 | .word 0xbf203, 0xbf203 // 1010 413 | .word 0xbf203, 0xbf203 // 1011 414 | .word 0xbf203, 0xbf203 // 1100 415 | .word 0xbf203, 0xbf203 // 1101 416 | .word 0xbf203, 0xbf203 // 1110 417 | .word 0xbf203, 0xbf203 // 1111 418 | -------------------------------------------------------------------------------- /picox86/VGA_ROM_F16.h: -------------------------------------------------------------------------------- 1 | #ifndef _IMG_ASSET_SECTION 2 | #define _IMG_ASSET_SECTION ".data" 3 | #endif 4 | 5 | 6 | static const char __attribute__((aligned(4), section(_IMG_ASSET_SECTION ".VGA_ROM_F16"))) VGA_ROM_F16[] = { 7 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 8 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 9 | 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xff, 10 | 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, 11 | 0x00, 0x00, 0x00, 0x00, 0x36, 0x7f, 0x7f, 0x7f, 0x7f, 0x3e, 0x1c, 0x08, 12 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x1c, 0x3e, 0x7f, 13 | 0x3e, 0x1c, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 14 | 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 15 | 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 16 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 17 | 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 18 | 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 19 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 20 | 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 21 | 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x78, 0x70, 22 | 0x58, 0x4c, 0x1e, 0x33, 0x33, 0x33, 0x33, 0x1e, 0x00, 0x00, 0x00, 0x00, 23 | 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 24 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xcc, 0xfc, 0x0c, 0x0c, 0x0c, 25 | 0x0c, 0x0e, 0x0f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 26 | 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xe6, 0xe7, 0x67, 0x03, 0x00, 0x00, 0x00, 27 | 0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 28 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x7f, 0x1f, 29 | 0x0f, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0x70, 30 | 0x78, 0x7c, 0x7f, 0x7c, 0x78, 0x70, 0x60, 0x40, 0x00, 0x00, 0x00, 0x00, 31 | 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 32 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 33 | 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xdb, 34 | 0xdb, 0xdb, 0xde, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0x00, 0x00, 0x00, 0x00, 35 | 0x00, 0x3e, 0x63, 0x06, 0x1c, 0x36, 0x63, 0x63, 0x36, 0x1c, 0x30, 0x63, 36 | 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 37 | 0x7f, 0x7f, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 38 | 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 39 | 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 40 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 41 | 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 42 | 0x00, 0x18, 0x30, 0x7f, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 43 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x7f, 0x06, 0x0c, 0x00, 0x00, 44 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 45 | 0x03, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 46 | 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 47 | 0x00, 0x00, 0x00, 0x00, 0x08, 0x1c, 0x1c, 0x3e, 0x3e, 0x7f, 0x7f, 0x00, 48 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x3e, 0x3e, 49 | 0x1c, 0x1c, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 50 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 51 | 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 52 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 53 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 54 | 0x36, 0x7f, 0x36, 0x36, 0x36, 0x7f, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 55 | 0x18, 0x18, 0x3e, 0x63, 0x43, 0x03, 0x3e, 0x60, 0x60, 0x61, 0x63, 0x3e, 56 | 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x63, 0x30, 0x18, 57 | 0x0c, 0x06, 0x63, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x36, 58 | 0x36, 0x1c, 0x6e, 0x3b, 0x33, 0x33, 0x33, 0x6e, 0x00, 0x00, 0x00, 0x00, 59 | 0x00, 0x0c, 0x0c, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 60 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 61 | 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 62 | 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 63 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 64 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 65 | 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 66 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x0c, 0x00, 0x00, 0x00, 67 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 68 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 69 | 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 70 | 0x40, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 71 | 0x00, 0x00, 0x3c, 0x66, 0xc3, 0xc3, 0xdb, 0xdb, 0xc3, 0xc3, 0x66, 0x3c, 72 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x1c, 0x1e, 0x18, 0x18, 0x18, 73 | 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x63, 74 | 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x63, 0x7f, 0x00, 0x00, 0x00, 0x00, 75 | 0x00, 0x00, 0x3e, 0x63, 0x60, 0x60, 0x3c, 0x60, 0x60, 0x60, 0x63, 0x3e, 76 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x38, 0x3c, 0x36, 0x33, 0x7f, 77 | 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x03, 78 | 0x03, 0x03, 0x3f, 0x60, 0x60, 0x60, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00, 79 | 0x00, 0x00, 0x1c, 0x06, 0x03, 0x03, 0x3f, 0x63, 0x63, 0x63, 0x63, 0x3e, 80 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x63, 0x60, 0x60, 0x30, 0x18, 81 | 0x0c, 0x0c, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x63, 82 | 0x63, 0x63, 0x3e, 0x63, 0x63, 0x63, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00, 83 | 0x00, 0x00, 0x3e, 0x63, 0x63, 0x63, 0x7e, 0x60, 0x60, 0x60, 0x30, 0x1e, 84 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 85 | 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 86 | 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 87 | 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 88 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 89 | 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 90 | 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00, 91 | 0x00, 0x00, 0x3e, 0x63, 0x63, 0x30, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 92 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x63, 0x63, 0x7b, 0x7b, 93 | 0x7b, 0x3b, 0x03, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x1c, 94 | 0x36, 0x63, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x63, 0x00, 0x00, 0x00, 0x00, 95 | 0x00, 0x00, 0x3f, 0x66, 0x66, 0x66, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x3f, 96 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x43, 0x03, 0x03, 0x03, 97 | 0x03, 0x43, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x36, 98 | 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x36, 0x1f, 0x00, 0x00, 0x00, 0x00, 99 | 0x00, 0x00, 0x7f, 0x66, 0x46, 0x16, 0x1e, 0x16, 0x06, 0x46, 0x66, 0x7f, 100 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x66, 0x46, 0x16, 0x1e, 0x16, 101 | 0x06, 0x06, 0x06, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 102 | 0x43, 0x03, 0x03, 0x7b, 0x63, 0x63, 0x66, 0x5c, 0x00, 0x00, 0x00, 0x00, 103 | 0x00, 0x00, 0x63, 0x63, 0x63, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x63, 0x63, 104 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 105 | 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x30, 106 | 0x30, 0x30, 0x30, 0x30, 0x33, 0x33, 0x33, 0x1e, 0x00, 0x00, 0x00, 0x00, 107 | 0x00, 0x00, 0x67, 0x66, 0x66, 0x36, 0x1e, 0x1e, 0x36, 0x66, 0x66, 0x67, 108 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x06, 0x06, 0x06, 0x06, 0x06, 109 | 0x06, 0x46, 0x66, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xe7, 110 | 0xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, 111 | 0x00, 0x00, 0x63, 0x67, 0x6f, 0x7f, 0x7b, 0x73, 0x63, 0x63, 0x63, 0x63, 112 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x63, 0x63, 0x63, 0x63, 0x63, 113 | 0x63, 0x63, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x66, 114 | 0x66, 0x66, 0x3e, 0x06, 0x06, 0x06, 0x06, 0x0f, 0x00, 0x00, 0x00, 0x00, 115 | 0x00, 0x00, 0x3e, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x6b, 0x7b, 0x3e, 116 | 0x30, 0x70, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x66, 0x66, 0x66, 0x3e, 0x36, 117 | 0x66, 0x66, 0x66, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x63, 118 | 0x63, 0x06, 0x1c, 0x30, 0x60, 0x63, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00, 119 | 0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 120 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 121 | 0x63, 0x63, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 122 | 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 123 | 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66, 124 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 125 | 0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 126 | 0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 127 | 0x00, 0x00, 0xff, 0xc3, 0x61, 0x30, 0x18, 0x0c, 0x06, 0x83, 0xc3, 0xff, 128 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 129 | 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 130 | 0x03, 0x07, 0x0e, 0x1c, 0x38, 0x70, 0x60, 0x40, 0x00, 0x00, 0x00, 0x00, 131 | 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 132 | 0x00, 0x00, 0x00, 0x00, 0x08, 0x1c, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00, 133 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 134 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 135 | 0x0c, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 136 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x3e, 137 | 0x33, 0x33, 0x33, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x06, 138 | 0x06, 0x1e, 0x36, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x00, 0x00, 0x00, 0x00, 139 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x63, 0x03, 0x03, 0x03, 0x63, 0x3e, 140 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x30, 0x30, 0x3c, 0x36, 0x33, 141 | 0x33, 0x33, 0x33, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 142 | 0x00, 0x3e, 0x63, 0x7f, 0x03, 0x03, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00, 143 | 0x00, 0x00, 0x1c, 0x36, 0x26, 0x06, 0x0f, 0x06, 0x06, 0x06, 0x06, 0x0f, 144 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x33, 0x33, 145 | 0x33, 0x33, 0x33, 0x3e, 0x30, 0x33, 0x1e, 0x00, 0x00, 0x00, 0x07, 0x06, 146 | 0x06, 0x36, 0x6e, 0x66, 0x66, 0x66, 0x66, 0x67, 0x00, 0x00, 0x00, 0x00, 147 | 0x00, 0x00, 0x18, 0x18, 0x00, 0x1c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 148 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x70, 0x60, 0x60, 149 | 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x07, 0x06, 150 | 0x06, 0x66, 0x36, 0x1e, 0x1e, 0x36, 0x66, 0x67, 0x00, 0x00, 0x00, 0x00, 151 | 0x00, 0x00, 0x1c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 152 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0xff, 0xdb, 153 | 0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 154 | 0x00, 0x3b, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 155 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x63, 0x63, 0x63, 0x63, 0x63, 0x3e, 156 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x66, 0x66, 157 | 0x66, 0x66, 0x66, 0x3e, 0x06, 0x06, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 158 | 0x00, 0x6e, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3e, 0x30, 0x30, 0x78, 0x00, 159 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x6e, 0x66, 0x06, 0x06, 0x06, 0x0f, 160 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x63, 0x06, 161 | 0x1c, 0x30, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0c, 162 | 0x0c, 0x3f, 0x0c, 0x0c, 0x0c, 0x0c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 163 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x6e, 164 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 165 | 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 166 | 0x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00, 167 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3, 168 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x63, 169 | 0x63, 0x63, 0x63, 0x7e, 0x60, 0x30, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 170 | 0x00, 0x7f, 0x33, 0x18, 0x0c, 0x06, 0x63, 0x7f, 0x00, 0x00, 0x00, 0x00, 171 | 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 172 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 173 | 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x18, 174 | 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00, 175 | 0x00, 0x00, 0x6e, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 176 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x1c, 0x36, 0x63, 177 | 0x63, 0x63, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 178 | 0x43, 0x03, 0x03, 0x03, 0x43, 0x66, 0x3c, 0x30, 0x60, 0x3e, 0x00, 0x00, 179 | 0x00, 0x00, 0x33, 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x6e, 180 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x00, 0x3e, 0x63, 0x7f, 181 | 0x03, 0x03, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x1c, 0x36, 182 | 0x00, 0x1e, 0x30, 0x3e, 0x33, 0x33, 0x33, 0x6e, 0x00, 0x00, 0x00, 0x00, 183 | 0x00, 0x00, 0x33, 0x00, 0x00, 0x1e, 0x30, 0x3e, 0x33, 0x33, 0x33, 0x6e, 184 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x00, 0x1e, 0x30, 0x3e, 185 | 0x33, 0x33, 0x33, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x36, 0x1c, 186 | 0x00, 0x1e, 0x30, 0x3e, 0x33, 0x33, 0x33, 0x6e, 0x00, 0x00, 0x00, 0x00, 187 | 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x06, 0x06, 0x66, 0x3c, 0x30, 0x60, 188 | 0x3c, 0x00, 0x00, 0x00, 0x00, 0x08, 0x1c, 0x36, 0x00, 0x3e, 0x63, 0x7f, 189 | 0x03, 0x03, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x00, 190 | 0x00, 0x3e, 0x63, 0x7f, 0x03, 0x03, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00, 191 | 0x00, 0x06, 0x0c, 0x18, 0x00, 0x3e, 0x63, 0x7f, 0x03, 0x03, 0x63, 0x3e, 192 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x1c, 0x18, 0x18, 193 | 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x66, 194 | 0x00, 0x1c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 195 | 0x00, 0x06, 0x0c, 0x18, 0x00, 0x1c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 196 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x00, 0x08, 0x1c, 0x36, 0x63, 0x63, 197 | 0x7f, 0x63, 0x63, 0x63, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x36, 0x1c, 0x00, 198 | 0x1c, 0x36, 0x63, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x00, 0x00, 0x00, 0x00, 199 | 0x18, 0x0c, 0x06, 0x00, 0x7f, 0x66, 0x06, 0x3e, 0x06, 0x06, 0x66, 0x7f, 200 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, 201 | 0x7e, 0x1b, 0x3b, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x36, 202 | 0x33, 0x33, 0x7f, 0x33, 0x33, 0x33, 0x33, 0x73, 0x00, 0x00, 0x00, 0x00, 203 | 0x00, 0x08, 0x1c, 0x36, 0x00, 0x3e, 0x63, 0x63, 0x63, 0x63, 0x63, 0x3e, 204 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x3e, 0x63, 0x63, 205 | 0x63, 0x63, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 206 | 0x00, 0x3e, 0x63, 0x63, 0x63, 0x63, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00, 207 | 0x00, 0x0c, 0x1e, 0x33, 0x00, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x6e, 208 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x00, 0x33, 0x33, 0x33, 209 | 0x33, 0x33, 0x33, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x00, 210 | 0x00, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x7e, 0x60, 0x30, 0x1e, 0x00, 211 | 0x00, 0x63, 0x00, 0x3e, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x3e, 212 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x00, 0x63, 0x63, 0x63, 0x63, 0x63, 213 | 0x63, 0x63, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 214 | 0xc3, 0x03, 0x03, 0x03, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 215 | 0x00, 0x1c, 0x36, 0x26, 0x06, 0x0f, 0x06, 0x06, 0x06, 0x06, 0x67, 0x3f, 216 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18, 217 | 0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x66, 0x66, 218 | 0x3e, 0x46, 0x66, 0xf6, 0x66, 0x66, 0x66, 0xcf, 0x00, 0x00, 0x00, 0x00, 219 | 0x00, 0x70, 0xd8, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 220 | 0x1b, 0x0e, 0x00, 0x00, 0x00, 0x18, 0x0c, 0x06, 0x00, 0x1e, 0x30, 0x3e, 221 | 0x33, 0x33, 0x33, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 222 | 0x00, 0x1c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 223 | 0x00, 0x18, 0x0c, 0x06, 0x00, 0x3e, 0x63, 0x63, 0x63, 0x63, 0x63, 0x3e, 224 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0x06, 0x00, 0x33, 0x33, 0x33, 225 | 0x33, 0x33, 0x33, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 226 | 0x00, 0x3b, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 227 | 0x6e, 0x3b, 0x00, 0x63, 0x67, 0x6f, 0x7f, 0x7b, 0x73, 0x63, 0x63, 0x63, 228 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x36, 0x36, 0x7c, 0x00, 0x7e, 0x00, 229 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x36, 0x36, 230 | 0x1c, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 231 | 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x0c, 0x0c, 0x06, 0x03, 0x63, 0x63, 0x3e, 232 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x03, 233 | 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 234 | 0x00, 0x00, 0x7f, 0x60, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 235 | 0x00, 0x03, 0x03, 0x43, 0x63, 0x33, 0x18, 0x0c, 0x06, 0x73, 0xd9, 0x60, 236 | 0x30, 0xf8, 0x00, 0x00, 0x00, 0x03, 0x03, 0x43, 0x63, 0x33, 0x18, 0x0c, 237 | 0x66, 0x73, 0x69, 0x7c, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 238 | 0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 239 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x36, 0x1b, 0x36, 0x6c, 0x00, 0x00, 240 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x36, 0x6c, 241 | 0x36, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x22, 0x88, 0x22, 242 | 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 243 | 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 244 | 0xaa, 0x55, 0xaa, 0x55, 0xbb, 0xee, 0xbb, 0xee, 0xbb, 0xee, 0xbb, 0xee, 245 | 0xbb, 0xee, 0xbb, 0xee, 0xbb, 0xee, 0xbb, 0xee, 0x18, 0x18, 0x18, 0x18, 246 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 247 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 248 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 249 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x6c, 0x6c, 0x6c, 0x6c, 250 | 0x6c, 0x6c, 0x6c, 0x6f, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 251 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x6c, 0x6c, 0x6c, 0x6c, 252 | 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 253 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x6c, 0x6c, 0x6c, 0x6c, 254 | 0x6c, 0x6f, 0x60, 0x6f, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 255 | 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 256 | 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x60, 0x6f, 257 | 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 258 | 0x6c, 0x6f, 0x60, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 259 | 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x7f, 0x00, 0x00, 0x00, 0x00, 260 | 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 261 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 262 | 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 263 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 264 | 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 265 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 266 | 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 267 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 268 | 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 269 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 270 | 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 271 | 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 272 | 0x18, 0x18, 0x18, 0x18, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0xec, 273 | 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 274 | 0x6c, 0xec, 0x0c, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 275 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0c, 0xec, 0x6c, 0x6c, 0x6c, 0x6c, 276 | 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0xef, 0x00, 0xff, 277 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 278 | 0x00, 0xff, 0x00, 0xef, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 279 | 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0xec, 0x0c, 0xec, 0x6c, 0x6c, 0x6c, 0x6c, 280 | 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 281 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, 0x6c, 0x6c, 282 | 0x6c, 0xef, 0x00, 0xef, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 283 | 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 284 | 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0xff, 285 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 286 | 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 287 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x6c, 0x6c, 0x6c, 0x6c, 288 | 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0xfc, 289 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 290 | 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 291 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 292 | 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 293 | 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 294 | 0x6c, 0x6c, 0x6c, 0xff, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 295 | 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 296 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 297 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 298 | 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 299 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 300 | 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 301 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x0f, 0x0f, 0x0f, 302 | 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 303 | 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 304 | 0xf0, 0xf0, 0xf0, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 305 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 306 | 0x00, 0x6e, 0x3b, 0x1b, 0x1b, 0x1b, 0x3b, 0x6e, 0x00, 0x00, 0x00, 0x00, 307 | 0x00, 0x00, 0x1e, 0x33, 0x33, 0x33, 0x1b, 0x33, 0x63, 0x63, 0x63, 0x33, 308 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x63, 0x63, 0x03, 0x03, 0x03, 309 | 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 310 | 0x7f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 311 | 0x00, 0x00, 0x00, 0x7f, 0x63, 0x06, 0x0c, 0x18, 0x0c, 0x06, 0x63, 0x7f, 312 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x1b, 0x1b, 313 | 0x1b, 0x1b, 0x1b, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 314 | 0x66, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x06, 0x06, 0x03, 0x00, 0x00, 0x00, 315 | 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 316 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 317 | 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 318 | 0x36, 0x63, 0x63, 0x7f, 0x63, 0x63, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00, 319 | 0x00, 0x00, 0x1c, 0x36, 0x63, 0x63, 0x63, 0x36, 0x36, 0x36, 0x36, 0x77, 320 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x18, 0x30, 0x7c, 0x66, 321 | 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 322 | 0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 323 | 0x00, 0x00, 0x00, 0xc0, 0x60, 0x7e, 0xdb, 0xdb, 0xcf, 0x7e, 0x06, 0x03, 324 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x0c, 0x06, 0x06, 0x3e, 0x06, 325 | 0x06, 0x06, 0x0c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 326 | 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x00, 0x00, 0x00, 0x00, 327 | 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x7f, 0x00, 328 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 329 | 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 330 | 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 331 | 0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 332 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0xd8, 0x18, 0x18, 0x18, 333 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 334 | 0x18, 0x18, 0x18, 0x18, 0x1b, 0x1b, 0x1b, 0x0e, 0x00, 0x00, 0x00, 0x00, 335 | 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 336 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x00, 337 | 0x6e, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x36, 0x36, 338 | 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 339 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 340 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 341 | 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x30, 0x30, 342 | 0x30, 0x30, 0x30, 0x37, 0x36, 0x36, 0x3c, 0x38, 0x00, 0x00, 0x00, 0x00, 343 | 0x00, 0x1b, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 344 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1b, 0x0c, 0x06, 0x13, 0x1f, 0x00, 345 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 346 | 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 347 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 348 | 0x00, 0x00, 0x00, 0x00 349 | }; --------------------------------------------------------------------------------