├── .gitignore ├── .gitmodules ├── CMakeLists.txt ├── LICENSE ├── README.md ├── common ├── audio.c ├── audio.h ├── game.c ├── game.h ├── keyboard.c ├── keyboard.h ├── ram.c ├── ram.h ├── rom.c ├── rom.h ├── rom_data.h ├── video.c ├── video.h └── video_char_data.h ├── icon.png ├── images ├── main_py_screenshot.png ├── perf_board.png ├── pi_pico_vga_demo_board.png ├── pico-iie_bin_file_download.jpg ├── pico-iie_block_diagram.drawio.png ├── pico-iie_board.jpg ├── pico-iie_board_assembled.jpg ├── pico-iie_board_enclosure.jpg ├── pico-iie_bootup_screen.jpg ├── pico-iie_cosmic_impalas.jpg ├── pico-iie_jumpers_bottom.jpg ├── pico-iie_jumpers_top.jpg ├── pico-iie_pcb.png ├── pico-iie_schematics.png └── pico-iie_setup.drawio.png ├── main.c ├── main.h ├── main.py ├── mcu ├── clock.c ├── clock.h ├── joystick.c ├── joystick.h ├── key.c ├── key.h ├── menu.c ├── menu.h ├── serial.c ├── serial.h ├── speaker.c ├── speaker.h ├── test.c ├── test.h ├── vga.c └── vga.h ├── parallel.pio ├── pcb ├── pico-iie.dch └── pico-iie.dip └── pico_sdk_import.cmake /.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "m6502"] 2 | path = m6502 3 | url = https://github.com/pyrex8/m6502.git 4 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12) 2 | 3 | include(pico_sdk_import.cmake) 4 | 5 | project(pico-iie C CXX ASM) 6 | set(CMAKE_C_STANDARD 11) 7 | set(CMAKE_CXX_STANDARD 17) 8 | 9 | pico_sdk_init() 10 | 11 | add_executable(pico-iie 12 | main.c 13 | mcu/clock.c 14 | mcu/test.c 15 | mcu/joystick.c 16 | mcu/key.c 17 | mcu/menu.c 18 | mcu/serial.c 19 | mcu/speaker.c 20 | mcu/vga.c 21 | common/audio.c 22 | common/game.c 23 | common/keyboard.c 24 | common/ram.c 25 | common/rom.c 26 | common/video.c 27 | m6502/c6502.c 28 | ) 29 | 30 | pico_generate_pio_header(pico-iie ${CMAKE_CURRENT_LIST_DIR}/parallel.pio) 31 | 32 | target_link_libraries( 33 | pico-iie 34 | pico_stdlib 35 | pico_multicore 36 | hardware_vreg 37 | hardware_pio 38 | hardware_adc 39 | hardware_dma 40 | hardware_pwm 41 | hardware_irq 42 | hardware_structs 43 | hardware_flash 44 | hardware_sync 45 | ) 46 | 47 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2") 48 | 49 | add_compile_options(-Wall 50 | -Wno-format # int != int32_t as far as the compiler is concerned because gcc has int32_t as long int 51 | -Wno-unused-function # we have some for the docs that aren't called 52 | -Wno-maybe-uninitialized 53 | ) 54 | 55 | pico_add_extra_outputs(pico-iie) 56 | 57 | pico_define_boot_stage2(slower_boot2 ${PICO_DEFAULT_BOOT_STAGE2_FILE}) 58 | target_compile_definitions(slower_boot2 PRIVATE PICO_FLASH_SPI_CLKDIV=4) 59 | pico_set_boot_stage2(pico-iie slower_boot2) 60 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 pyrex8 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # pico-iie 2 | 3 | Apple IIe emulator that runs on the Pi Pico. The pico-iie pcb is shown on the right and the fully enclosed project is on the left. 4 | 5 |

6 | enclosure 7 | assembled pcb 8 |

9 | 10 | 11 | ### Project History 12 | 13 | This project started in 2020 after a failed attempt at installing an Apple II emulator on a Linux machine. 14 | The most active project on github was LinApple (https://github.com/linappleii/linapple). I had some trouble compiling the project so I went looking for alternatives. I found some historical background on LinApple from the person who originally ported AppleWin over to Linux. 15 | (http://linapple.sourceforge.net/). 16 | 17 | Then I was able to find a fork of the sourceforge code. From the initial commit it looks like this started in 2012 (https://github.com/LasDesu/linapple.git). I was able to easily compile this version and get it running. This doesn't seem to be actively updated but I found the code simpler than the more active https://github.com/linappleii/linapple. 18 | 19 | After looking at the source code for a while I understood a little about how it worked, but only at the most rudimentary level. The project was written in C++, but I couldn't find anything in the code that required C++ over C. I'm far more comfortable writing code in C so I was starting to wonder if it could just be in C. A lot of the modules were coupled together calling each others functions which made the conversion to C and understanding the code difficult. 20 | 21 | I started playing with the code to see if I could accomplish a few things: 22 | 1. Simplify the code. 23 | 2. Remove features that I don't find useful. 24 | 3. Decouple all the modules. 25 | 4. Convert all the files to C. 26 | 27 | At this point in 2020 I started what I called my deconstruction project. It basically was a process with two steps. 28 | 1. Remove a feature, simplify, or refactor some code. 29 | 2. Run a game and see if it still works. 30 | 31 | This may sound like a tedious process, but it was super fun and gave me an excuse to try out Apple II games on a regular bases. 32 | 33 | The original LinApple code uses 6502 emulation that executes a complete instruction every call as opposed to a per cycle emulator that executes one clock cycle per execution. This is one of the main reasons the code had so much coupling between modules. A per instruction emulation requires accessing RAM, ROM, and peripherals from the actual instruction. I looked around for a per cycle emulator. I found this project https://github.com/floooh/chips. It was surprisingly easy to integrate into the project. This allowed decoupling of all the other modules from the 6502 emulation. The trade off is that per cycle emulation is slower than per instruction emulation. 34 | 35 | I ended up removing the SDL1 layer used in the project and used Pygame as the interface to the code just to test the C portion of the emulator. This simplified the C code but slowed down the project further. At this point the emulator code was cleaner but running slower than the original project. The other issue was with emulating sound on Pygame. I have not been able to update sound without glitching/clicking between updates. I'm not sure if this is an inherent problem with Pygame or just my lack of understanding. 36 | 37 | I decide to try running the emulator on a microcontroller. After trying out a few processors I landed on using the Pi Pico. 38 | 39 | The projects use both cores and is overclocked at 470MHz. 40 | 41 | #### Core 0 42 | - VGA scan line updating 43 | - Getting video memeory from RAM 44 | - Converting video memory for the scan line to data needed to display 45 | - Serial UART operations: 46 | - keyboard 47 | - joystick 48 | - bin files 49 | - disk files 50 | 51 | #### Core 1 52 | - 6502 53 | - RAM 54 | - ROM 55 | - Disk 56 | - Keybaord 57 | - Speaker 58 | - Video 59 | - Cassette (just output as a debug pin for getting timing information from programs running on emulator) 60 | 61 | The emulator takes approximately 1 microsecond to complete a machine cycle and access peripherals. 62 | 63 | ### Development Hardware 64 | The emulator runs on a Pi Pico using a Pimoroni Pico VGA Demo Base (https://shop.pimoroni.com/products/pimoroni-pico-vga-demo-base?variant=32369520672851) with a few modifications. 65 | 66 | dev board 67 | 68 | ### Setup 69 | The pico-iie requires 3 cables: 70 | - USB to UART cable with 3.3V signals. 71 | - A VGA cable 72 | - An audio cable 73 | 74 | setup 75 | 76 | ### Pico VGA Demo Board Modifications 77 | 78 | The pico VGA Demo board requires 3 cut traces, 5 jumpers, and removal of some components 79 | 80 | modifications 81 | 82 | ### Perf Board 83 | 84 | The perf (perforated) board adds the red LED and the serial connector for the USB to UART cable. J1 of the perf board plugs into J7 on the Pico VGA Demo Board. 85 | 86 | perf board 87 | 88 | 89 | ### Compiling and Downloading to Pi Pico 90 | 91 | There are good resources on the web for compiling and downloading C Pi Pico projects. The short version of this after git clone(ing) this project and setting up the tool chain navigate to the ```build``` folder. In build folder: 92 | 93 | ``` 94 | export PICO_SDK_PATH=../../pico-sdk 95 | cmake .. 96 | make 97 | ``` 98 | 99 | To program through the Pi Pico USB connector hold the BOOTSEL pin and press RUN. After the USB drive shows up in your file browser drag the ```pico-iie.uf2``` file onto the drive icon. 100 | 101 | At this point if everything is wired up correctly you should see the ```Apple //e``` text at the top of the VGA screen with the blinking prompt and the familiar beep can be heard. The pico-iie can be powered by the USB micro connector on the Pi Pico or the USB to UART cable 5V. 102 | 103 | boot up screen 104 | 105 | ### main.py 106 | 107 | Running ```main.py``` brings up a black pygame window (shown below). As long as the pygame window is in focus on the desktop, keyboard and game controller inputs are sent down to the pico-iie from your PC to the pi pico through the USB to UART cable as serial data. 108 | 109 | 110 | main.py 111 | 112 | The disk is not automatically detected. By starting ```main.py``` communication starts between a Linux PC and the Pi Pico. If main.py is started with a .dsk file the emulator will automatically reboot with the dsk imag. 113 | 114 | main.py can load a ```bin``` or ```dsk``` file. 115 | 116 | If you use the menu command Download ROM image for Cosmic Impalas and save locally 117 | https://8bitworkshop.com/v3.9.0/?file=cosmic.c&platform=apple2 118 | 119 | You can download the bin file directly to the pico-iie though the USB to serial cable 120 | 121 | ``` 122 | python3 main.py cosmic.bin 123 | ``` 124 | 125 | The green LED on the pi pico turn on solid green for a few seconds as it downloads then the game will start automatically. 126 | 127 | cosmic impalas 128 | 129 | The red LED indicates Disk operation. 130 | 131 | Example: 132 | ``` 133 | python3 main.py Choplifter.dsk 134 | ``` 135 | 136 | After the file is downloaded and running the main.py can be used for keyboard input and/or game controller input through the serial cable. This eliminates the need for direct connection to peripherals to the Pi Pico. 137 | 138 | - F1 is used for breaking your program, the same as CRTL-C on the original machine. 139 | - F2 key toggles pausing the emulator. 140 | - F9 reboots 141 | - F10 exits main.py program. 142 | 143 | ### Pi Pico Pinout Block Diagram 144 | 145 | From the block diagram it can be seen that the peripherals use are: 146 | - GPIO 147 | - UART1 148 | - PWM0, PWM1, PWM2 149 | - PIO0 150 | - DMA0, DMA1 151 | 152 | VGA is data is produced using PIO0 as a 16 bit parallel port controlled by a circular DMA. The length of the buffer is equivalent to one VGA scan line. This would allow a similar implementation on other Microcontrollers. 153 | 154 | Pi Pico Block Diagram 155 | 156 | ### Emulator Simplification 157 | 158 | There are some simplifications/limitations to the emulator. 159 | 160 | - Only emulates a 48K RAM. 161 | - TEXT and HIRES modes only, no LORES mode. 162 | - No blinking text, just NORMAL and INVERSE. FLASH displays as inverse and some odd characters. 163 | - Most of the soft switch read "side affect" are not emulated. 164 | - Vertical blanking register is not updated. This is due to it only being in the IIe so most games don't use it. 165 | - Communication on UART is very rudamentary: 166 | - Only raw data is sent down with no error checking. 167 | - Data is only on direction so disk data is not saved back to PC. 168 | - bin files always load at 0x803. This is hard coded for now to be compatable with https://8bitworkshop.com Apple II generated bin files. 169 | 170 | ### PCB (WIP) 171 | 172 | A dedicated PCB is in the works. The schematics is in Diptrace (https://diptrace.com/). 173 | 174 | schematics 175 | 176 | 177 | PCB is shared on OSH Park https://oshpark.com/shared_projects/atsJNRzd 178 | 179 | 180 | pcb 181 | 182 | pico-iie pcb (Note: OSH Park requires 3 pcbs per order and price here is per pcb) 183 | 184 | | # | Description | Part Number | Price | 185 | |---|-----------------------|-------------|-------| 186 | | 1 | pico-iie rev a pyrex8 | pico-iie |$12.03 | 187 | 188 | 189 | 190 | PCB bill of Materials 191 | 192 | | # | RefDes |Description | Part Number | Price | 193 | |---| ------------------ |--------------------- | ----------------- | ----- | 194 | | 1 | U1 | Header | | | 195 | | 2 | J1 | DB15F_HD | AHDF15A-KG-TAXB |$1.36 | 196 | | 3| J2 |CONN HEADER R/A 40POS | PRPC040SBAN-M71RC |$0.83 | 197 | | 4 | J3 |STX-3000 | STX-3000 |$0.74 | 198 | | 5 | D1 |1N914 | | | 199 | | 6 | D2 | LED Red | | | 200 | | 7 | D3 | LED GREEN | | | 201 | | 8 |C1 | 0.1uF | | | 202 | | 9 |C2 | 47uF | | | 203 | | 11 |R5, R6, R7, R8 | 499 | | | 204 | |10 | R1, R2, R3, R4 | 75 | | | 205 | | 12 | R9, R10, R11, R12 | 1k | | | 206 | | 13 |R13, R14, R15, R16 | 2k | | | 207 | | 14 | R17, R18, R19 | 4.02k | | | 208 | | 15 |R20, R21, R22 | 8.06k | | | 209 | | 16 | R23, R24, R25 | 100k | | | 210 | 211 | 212 | 213 | Pi Pico 214 | 215 | | # | Description | Part Number | Price | 216 | |---|--------------------------|-------------|-------| 217 | | 1 | RASPBERRY PI PICO RP2040 | SC0915 | $4.00 | 218 | 219 | The pcb is designed to fit in this case: http://www.hammondmfg.com/pdf/1593L.pdf 220 | 221 | | # | Description | Part Number | Price | 222 | |---|--------------------------------|-------------|-------| 223 | | 1 |BOX ABS BLACK 3.631"L X 2.607"W | 1593LBK | $5.24 | 224 | 225 | 226 | Cables 227 | 228 | | # | Description | Part Number | Price | 229 | |---|----------------------------|-------------|-------| 230 | | 1 | CABLE USB UART 3.3V .1"HDR | |$15.00 | 231 | | 1 | VGA cable | | $5.00 | 232 | | 1 | 3.5mm Audio cable | | $3.00 | 233 | -------------------------------------------------------------------------------- /common/audio.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "audio.h" 5 | 6 | #define TOGGLES_PER_RESET_MAX 0x400 7 | #define DATA_TOGGLE_CLK_INDEX_MAX (TOGGLES_PER_RESET_MAX - 1) 8 | 9 | static uint8_t audio_data_last = 0; 10 | static uint16_t audio_clk = 0; 11 | static uint16_t last_index = 0; 12 | static uint16_t data_toggle_clk_cycle[TOGGLES_PER_RESET_MAX] = {0}; 13 | 14 | 15 | 16 | void audio_data_clear(void) 17 | { 18 | last_index = 0; 19 | audio_clk = 0; 20 | } 21 | 22 | void audio_update(uint8_t data) 23 | { 24 | audio_clk++; 25 | if (data != audio_data_last) 26 | { 27 | data_toggle_clk_cycle[last_index] = audio_clk; 28 | audio_data_last = data; 29 | if (last_index < DATA_TOGGLE_CLK_INDEX_MAX) 30 | { 31 | last_index++; 32 | } 33 | } 34 | } 35 | 36 | uint16_t audio_data(uint16_t index) 37 | { 38 | uint16_t rtn_index = index & DATA_TOGGLE_CLK_INDEX_MAX; 39 | return data_toggle_clk_cycle[rtn_index]; 40 | } 41 | 42 | uint16_t audio_data_length(void) 43 | { 44 | return last_index; 45 | } 46 | -------------------------------------------------------------------------------- /common/audio.h: -------------------------------------------------------------------------------- 1 | #ifndef __AUDIO_H__ 2 | #define __AUDIO_H__ 3 | 4 | void audio_data_clear(void); 5 | void audio_update(uint8_t data); 6 | 7 | #endif /* __AUDIO_H__ */ 8 | -------------------------------------------------------------------------------- /common/game.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "game.h" 5 | 6 | #define GAME_BUTTON0_ADDR 0xC061 7 | #define GAME_BUTTON1_ADDR 0xC062 8 | #define GAME_PADDLE0_ADDR 0xC064 9 | #define GAME_PADDLE1_ADDR 0xC065 10 | 11 | #define GAME_ALT_BIT_MASK_ADDR 0xFFF7 12 | 13 | #define GAME_TIMER_RESET_ADDR 0xC070 14 | 15 | #define GAME_TIMER_COUNT_MULT 255 16 | #define GAME_TIMER_COUNT_DIV 2816 17 | 18 | // 2816 us / 31.84us 19 | 20 | #define GAME_TIMER_COUNT_MAX (GAME_TIMER_COUNT_DIV) 21 | 22 | #define GAME_DATA_PIN_LOW 0x7F 23 | #define GAME_DATA_PIN_HIGH 0xFF 24 | 25 | static uint8_t button0 = 0; 26 | static uint8_t button1 = 0; 27 | static uint8_t paddle0 = 0; 28 | static uint8_t paddle1 = 0; 29 | 30 | static uint16_t timer_count = 0; 31 | static uint32_t counter_threshold = 0; 32 | 33 | void game_update(uint8_t read, uint16_t address, uint8_t *byte) 34 | { 35 | if (timer_count < GAME_TIMER_COUNT_MAX) 36 | { 37 | timer_count++; 38 | } 39 | 40 | if (address == GAME_TIMER_RESET_ADDR) 41 | { 42 | timer_count = 0; 43 | } 44 | 45 | if ((address & 0xFFF0) == 0xC060) 46 | { 47 | if (read) 48 | { 49 | if ((address & GAME_ALT_BIT_MASK_ADDR) == GAME_BUTTON0_ADDR) 50 | { 51 | *byte = button0; 52 | } 53 | 54 | else if ((address & GAME_ALT_BIT_MASK_ADDR) == GAME_BUTTON1_ADDR) 55 | { 56 | *byte = button1; 57 | } 58 | 59 | else if ((address & GAME_ALT_BIT_MASK_ADDR) == GAME_PADDLE0_ADDR) 60 | { 61 | counter_threshold = (timer_count * GAME_TIMER_COUNT_MULT) / GAME_TIMER_COUNT_DIV; 62 | if(counter_threshold < paddle0) 63 | { 64 | *byte = GAME_DATA_PIN_HIGH; 65 | } 66 | else 67 | { 68 | *byte = GAME_DATA_PIN_LOW; 69 | } 70 | } 71 | 72 | else if ((address & GAME_ALT_BIT_MASK_ADDR) == GAME_PADDLE1_ADDR) 73 | { 74 | counter_threshold = (timer_count * GAME_TIMER_COUNT_MULT) / GAME_TIMER_COUNT_DIV; 75 | if(counter_threshold < paddle1) 76 | { 77 | *byte = GAME_DATA_PIN_HIGH; 78 | } 79 | else 80 | { 81 | *byte = GAME_DATA_PIN_LOW; 82 | } 83 | } 84 | } 85 | } 86 | } 87 | 88 | void game_state_set(uint8_t btn0, uint8_t btn1, uint8_t pdl0, uint8_t pdl1) 89 | { 90 | if(btn0) 91 | { 92 | button0 = GAME_DATA_PIN_HIGH; 93 | } 94 | else 95 | { 96 | button0 = GAME_DATA_PIN_LOW; 97 | } 98 | 99 | if(btn1) 100 | { 101 | button1 = GAME_DATA_PIN_HIGH; 102 | } 103 | else 104 | { 105 | button1 = GAME_DATA_PIN_LOW; 106 | } 107 | 108 | // Only update if timer is not running 109 | if (timer_count >= GAME_TIMER_COUNT_MAX) 110 | { 111 | paddle0 = pdl0; 112 | paddle1 = pdl1; 113 | } 114 | } 115 | 116 | void game_btn0_set(uint8_t btn0) 117 | { 118 | if(btn0) 119 | { 120 | button0 = GAME_DATA_PIN_HIGH; 121 | } 122 | else 123 | { 124 | button0 = GAME_DATA_PIN_LOW; 125 | } 126 | } 127 | 128 | void game_btn1_set(uint8_t btn1) 129 | { 130 | if(btn1) 131 | { 132 | button1 = GAME_DATA_PIN_HIGH; 133 | } 134 | else 135 | { 136 | button1 = GAME_DATA_PIN_LOW; 137 | } 138 | } 139 | 140 | void game_pdl0_set(uint8_t pdl0) 141 | { 142 | // Only update if timer is not running 143 | if (timer_count >= GAME_TIMER_COUNT_MAX) 144 | { 145 | paddle0 = pdl0; 146 | } 147 | } 148 | 149 | void game_pdl1_set(uint8_t pdl1) 150 | { 151 | // Only update if timer is not running 152 | if (timer_count >= GAME_TIMER_COUNT_MAX) 153 | { 154 | paddle1 = pdl1; 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /common/game.h: -------------------------------------------------------------------------------- 1 | #ifndef __GAME_H__ 2 | #define __GAME_H__ 3 | 4 | void game_update(uint8_t read, uint16_t address, uint8_t *byte); 5 | void game_state_set(uint8_t btn0, uint8_t btn1, uint8_t pdl0, uint8_t pdl1); 6 | void game_btn0_set(uint8_t btn0); 7 | void game_btn1_set(uint8_t btn1); 8 | void game_pdl0_set(uint8_t pdl0); 9 | void game_pdl1_set(uint8_t pdl1); 10 | 11 | #endif /* __GAME_H__ */ 12 | -------------------------------------------------------------------------------- /common/keyboard.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "keyboard.h" 5 | 6 | #define KEYBOARD_MASK 0xFFF0 7 | 8 | static bool mem_key_waiting = false; 9 | static uint8_t mem_key_code = 0; 10 | 11 | uint8_t keyboard_data_read(void) 12 | { 13 | int rtn = mem_key_code | (mem_key_waiting ? 0x80 : 0); 14 | return rtn; 15 | } 16 | 17 | uint8_t keyboard_flag_read(void) 18 | { 19 | int rtn = mem_key_code | (mem_key_waiting ? 0x80 : 0); 20 | 21 | mem_key_waiting = false; 22 | return rtn; 23 | } 24 | 25 | void keyboard_update(uint8_t read, uint16_t address, uint8_t *byte) 26 | { 27 | if((address & KEYBOARD_MASK) == 0xC000) 28 | { 29 | *byte = keyboard_data_read(); 30 | } 31 | 32 | if((address & KEYBOARD_MASK) == 0xC010) 33 | { 34 | *byte = keyboard_flag_read(); 35 | } 36 | } 37 | 38 | void keyboard_key_code_set(uint8_t key_code) 39 | { 40 | // if (key_code > 0 && key_code < 128) 41 | { 42 | mem_key_waiting = true; 43 | mem_key_code = key_code; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /common/keyboard.h: -------------------------------------------------------------------------------- 1 | #ifndef __KEYBOARD_H__ 2 | #define __KEYBOARD_H__ 3 | 4 | void keyboard_update(uint8_t read, uint16_t address, uint8_t *byte); 5 | void keyboard_key_code_set(uint8_t key_code); 6 | 7 | #endif /* __KEYBOARD_H__ */ 8 | -------------------------------------------------------------------------------- /common/ram.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "ram.h" 6 | 7 | #define RAM_SIZE 0xC000 8 | 9 | static uint8_t memory_ram[RAM_SIZE] = {0}; 10 | static uint16_t location = 0; 11 | static uint16_t location_start = 0; 12 | 13 | void ram_init(void) 14 | { 15 | memset(memory_ram, 0, RAM_SIZE); 16 | } 17 | 18 | void ram_deinit(void) 19 | { 20 | 21 | } 22 | 23 | void ram_update(uint8_t read, uint16_t address, uint8_t *byte) 24 | { 25 | if (address < RAM_SIZE) 26 | { 27 | if (read) 28 | { 29 | *byte = memory_ram[address]; 30 | } 31 | else 32 | { 33 | memory_ram[address] = *byte; 34 | } 35 | } 36 | } 37 | 38 | 39 | void ram_data_get(uint16_t length, uint16_t address, uint8_t *data) 40 | { 41 | memcpy(data, &memory_ram[address], length); 42 | } 43 | 44 | void ram_data_set(uint16_t length, uint16_t address, uint8_t *data) 45 | { 46 | memcpy(&memory_ram[address], data, length); 47 | } 48 | 49 | void ram_all_get(uint8_t *buffer) 50 | { 51 | memcpy(buffer, memory_ram, RAM_SIZE); 52 | } 53 | 54 | void ram_bin_reset(uint8_t unused) 55 | { 56 | location = location_start; 57 | } 58 | 59 | void ram_bin_addr_lsb(uint8_t data) 60 | { 61 | location &= 0xFF00; 62 | location |= data; 63 | location_start = location; 64 | } 65 | 66 | void ram_bin_addr_msb(uint8_t data) 67 | { 68 | location &= 0x00FF; 69 | location |= (((uint16_t)data) << 8); 70 | location_start = location; 71 | } 72 | 73 | void ram_bin_addr_set(uint16_t address) 74 | { 75 | location = address; 76 | location_start = location; 77 | } 78 | 79 | uint16_t ram_bin_addr_get(void) 80 | { 81 | return location_start; 82 | } 83 | 84 | void ram_bin_data_set(uint8_t data) 85 | { 86 | ram_update(MEMORY_WRITE, location, &data); 87 | location++; 88 | } 89 | -------------------------------------------------------------------------------- /common/ram.h: -------------------------------------------------------------------------------- 1 | #ifndef __RAM_H__ 2 | #define __RAM_H__ 3 | 4 | typedef enum 5 | { 6 | MEMORY_WRITE = 0, 7 | MEMORY_READ 8 | } MemoryRWStatus; 9 | 10 | void ram_init(void); 11 | void ram_deinit(void); 12 | void ram_update(uint8_t read, uint16_t address, uint8_t *byte); 13 | void ram_data_get(uint16_t length, uint16_t address, uint8_t *data); 14 | void ram_data_set(uint16_t length, uint16_t address, uint8_t *data); 15 | void ram_bin_reset(uint8_t unused); 16 | void ram_bin_addr_lsb(uint8_t data); 17 | void ram_bin_addr_msb(uint8_t data); 18 | void ram_bin_addr_set(uint16_t address); 19 | uint16_t ram_bin_addr_get(void); 20 | void ram_bin_data_set(uint8_t data); 21 | 22 | #endif /* __RAM_H__ */ 23 | -------------------------------------------------------------------------------- /common/rom.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "rom.h" 9 | #include "rom_data.h" 10 | 11 | #define ROM_LOCATION 0xC000 12 | #define ROM_END 0xFFFF 13 | #define ROM_SIZE (ROM_END - ROM_LOCATION) 14 | #define ROM_RESET_VECTOR_LB_LOCATION (0xFFFC - ROM_LOCATION) 15 | #define ROM_RESET_VECTOR_HB_LOCATION (0xFFFD - ROM_LOCATION) 16 | 17 | static uint8_t rom_in_ram[ROM_SIZE]; 18 | 19 | void rom_init(void) 20 | { 21 | memcpy(rom_in_ram, iie_enhanced_rom, ROM_SIZE); 22 | } 23 | 24 | void rom_update(uint8_t read, uint16_t address, uint8_t *byte) 25 | { 26 | if ((read) && (address >= ROM_LOCATION)) 27 | { 28 | *byte = rom_in_ram[address - ROM_LOCATION]; 29 | } 30 | } 31 | 32 | void rom_reset_vector_write(uint16_t address) 33 | { 34 | rom_in_ram[ROM_RESET_VECTOR_LB_LOCATION] = (uint8_t)((address) & 0xFF); 35 | rom_in_ram[ROM_RESET_VECTOR_HB_LOCATION] = (uint8_t)((address >> 8) & 0xFF); 36 | } 37 | -------------------------------------------------------------------------------- /common/rom.h: -------------------------------------------------------------------------------- 1 | #ifndef __ROM_H__ 2 | #define __ROM_H__ 3 | 4 | void rom_init(void); 5 | void rom_update(uint8_t read, uint16_t address, uint8_t *byte); 6 | void rom_reset_vector_write(uint16_t address); 7 | 8 | #endif /* __ROM_H__ */ 9 | -------------------------------------------------------------------------------- /common/rom_data.h: -------------------------------------------------------------------------------- 1 | #ifndef __ROM_DATA_H__ 2 | #define __ROM_DATA_H__ 3 | 4 | const int8_t iie_enhanced_rom[] = 5 | "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 6 | "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 7 | "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 8 | "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 9 | "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 10 | "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 11 | "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 12 | "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 13 | "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 14 | "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 15 | "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 16 | "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 17 | "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 18 | "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 19 | "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 20 | "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 21 | "\x4C\x13\xC2\xA4\x24\xA5\x25\x48\x20\x03\xCE\x20\xF4\xC1\xA0\x00" 22 | "\x68\x69\x00\xC5\x23\x90\xF0\xB0\x34\xA5\x22\x85\x25\xA0\x00\x84" 23 | "\x24\xF0\xE4\xA5\x22\x48\x20\x03\xCE\xA5\x28\x85\x2A\xA5\x29\x85" 24 | "\x2B\xA4\x21\x88\x68\x69\x01\xC5\x23\xB0\x0D\x48\x20\x03\xCE\xB1" 25 | "\x28\x91\x2A\x88\x10\xF9\x30\xE1\xA0\x00\x20\xF4\xC1\xA5\x25\x4C" 26 | "\x03\xCE\xA9\x28\x85\x21\xA9\x18\x85\x23\xA9\x17\x85\x25\xD0\xEF" 27 | "\xA4\x2A\x4C\xF4\xC1\x4C\xEB\xCB\x4C\x9A\xCC\xA4\x2A\x4C\x9D\xCC" 28 | "\x4C\x74\xCC\x4C\xA0\xC2\x4C\xB0\xC2\x4C\xF2\xC2\x20\x90\xCC\xAD" 29 | "\x7B\x05\x85\x24\x8D\x7B\x04\x4C\xFE\xCD\xB4\x00\xF0\x0F\xC0\x1B" 30 | "\xF0\x0E\x20\x80\xCD\xB4\x00\xF0\x04\xA9\xFD\x95\x01\xB5\x01\x60" 31 | "\xA5\x37\xC9\xC3\xD0\xF3\x4C\x32\xC8\xA4\x24\xB1\x28\x48\x29\x3F" 32 | "\x09\x40\x91\x28\x68\x60\xA8\xA5\x28\x20\xBA\xCA\x90\x4C\x20\x14" 33 | "\xCE\xA0\x03\xD9\xEE\xC2\xD0\x03\xB9\xA4\xC9\x88\x10\xF5\x30\x3A" 34 | "\x20\x70\xC8\x4C\x0A\xC2\x8A\x29\x03\x85\x2F\xA5\x2A\x29\x8F\x4C" 35 | "\x71\xCA\x20\xF0\xFC\x8A\x85\x34\x60\xAC\x7B\x05\x20\x44\xCE\x09" 36 | "\x80\x60\xA4\x24\xA9\xA0\x2C\x1E\xC0\x10\x06\x24\x32\x30\x02\xA9" 37 | "\x20\x4C\xA8\xCC\xA8\xA5\x28\x20\x03\xCE\x28\x30\x03\x4C\xC5\xFE" 38 | "\x4C\xC8\xFE\x88\x30\xBA\x88\x30\xA5\x88\x30\x9A\x88\x30\x3D\x88" 39 | "\x30\xE2\xA9\xC2\x48\xA9\x09\x48\xAD\xFB\x04\x29\xD6\xD0\x0D\x98" 40 | "\x18\x69\x0C\x48\x20\x50\xC8\x20\xFE\xCD\x68\xA8\xA9\xC1\x48\xB9" 41 | "\x44\xC2\x48\x60\x18\x22\xF1\x5F\x75\x02\xA8\x51\xE1\x94\xE8\xD5" 42 | "\x7B\x64\x67\x6A\x75\x6F\x78\x72\xE1\x89\xE8\xD5\x2C\x1F\xC0\x10" 43 | "\x06\x20\x74\xC8\x4C\x0A\xC2\xA8\x8A\x48\x98\x48\x48\x68\xC9\xFF" 44 | "\xF0\x04\xA9\xFF\xD0\x02\x68\x48\x48\xA4\x24\x91\x28\xE6\x4E\xD0" 45 | "\x0A\xA5\x4F\xE6\x4F\x45\x4F\x29\x40\xD0\xE2\xAD\x00\xC0\x10\xED" 46 | "\x68\x68\xA4\x24\x91\x28\x68\xAA\xAD\x00\xC0\x8D\x10\xC0\x30\xC4" 47 | "\x20\x52\xC1\x2C\x1F\xC0\x10\x02\x06\x21\xA5\x25\x8D\xFB\x05\x60" 48 | "\xA9\xFF\x8D\xFB\x04\xAD\x5D\xC0\xAD\x5F\xC0\xAD\x62\xC0\x10\x03" 49 | "\x4C\x00\xC6\xAD\x61\xC0\x10\x1A\xA0\xB0\xA9\x00\x85\x3C\xA9\xBF" 50 | "\x38\x85\x3D\x48\xA9\xA0\x91\x3C\x88\x91\x3C\x68\xE9\x01\xC9\x01" 51 | "\xD0\xEF\x8D\x0B\xC0\x20\x89\xCA\xD0\x03\x8D\x0A\xC0\x60\x88\x95" 52 | "\x8A\x8B\xA4\x24\xB1\x28\x2C\x1F\xC0\x30\xF2\x4C\x26\xCE\x00\x00" 53 | "\x2C\x43\xCE\x70\x12\x38\x90\x18\xB8\x50\x0C\x01\x88\x4A\x50\x56" 54 | "\x5C\x4C\x76\xC3\x4C\xC3\xC3\x8D\x7B\x06\x98\x48\x8A\x48\x08\xAD" 55 | "\xFB\x04\x2C\xF8\x07\x30\x05\x09\x08\x8D\xFB\x04\x20\x6D\xC3\x28" 56 | "\x70\x15\x90\x10\xAA\x10\x0D\x20\x5B\xCD\x68\xAA\x68\xA8\xAD\x7B" 57 | "\x06\x6C\x38\x00\x4C\x7C\xC8\x4C\x03\xC8\x20\x6D\xC3\x4C\xB4\xC9" 58 | "\x20\x6D\xC3\x4C\xD6\xC9\x20\x6D\xC3\x4C\xF0\xC9\xAA\xF0\x08\xCA" 59 | "\xD0\x07\x2C\x00\xC0\x10\x04\x38\x60\xA2\x03\x18\x60\xA2\xC3\x8E" 60 | "\xF8\x07\xAE\xFF\xCF\x60\x48\x98\x48\xAD\x13\xC0\x48\xAD\x14\xC0" 61 | "\x48\x90\x08\x8D\x02\xC0\x8D\x05\xC0\xB0\x06\x8D\x04\xC0\x8D\x03" 62 | "\xC0\xA0\x00\xB1\x3C\x91\x42\xE6\x42\xD0\x02\xE6\x43\xA5\x3C\xC5" 63 | "\x3E\xA5\x3D\xE5\x3F\xE6\x3C\xD0\x02\xE6\x3D\x90\xE6\x8D\x04\xC0" 64 | "\x68\x10\x03\x8D\x05\xC0\x8D\x02\xC0\x68\x10\x03\x8D\x03\xC0\x68" 65 | "\xA8\x68\x60\x48\xAD\xED\x03\x48\xAD\xEE\x03\x48\x90\x08\x8D\x03" 66 | "\xC0\x8D\x05\xC0\xB0\x06\x8D\x02\xC0\x8D\x04\xC0\x68\x8D\xEE\x03" 67 | "\x68\x8D\xED\x03\x68\x70\x05\x8D\x08\xC0\x50\x03\x8D\x09\xC0\x6C" 68 | "\xED\x03\x00\x00\x8D\x81\xC0\x4C\x7A\xFC\x2C\x15\xC0\x8D\x07\xC0" 69 | "\xD8\x38\x30\x01\x18\x48\x48\x48\x8A\xBA\xE8\xE8\xE8\xE8\x48\x98" 70 | "\x48\xBD\x00\x01\x29\x10\xA8\xAD\x18\xC0\x2D\x1C\xC0\x29\x80\xF0" 71 | "\x05\xA9\x20\x8D\x54\xC0\x2A\x2C\x13\xC0\x10\x05\x8D\x02\xC0\x09" 72 | "\x20\x2C\x14\xC0\x10\x05\x8D\x04\xC0\x09\x10\x2C\x12\xC0\x10\x0C" 73 | "\x09\x0C\x2C\x11\xC0\x10\x02\x49\x06\x8D\x81\xC0\x2C\x16\xC0\x10" 74 | "\x0D\xBA\x8E\x01\x01\xAE\x00\x01\x9A\x8D\x08\xC0\x09\x80\x88\x30" 75 | "\x0C\x85\x44\x68\xA8\x68\xAA\x68\x68\x68\x4C\x47\xFA\x48\xAD\xF8" 76 | "\x07\x48\xA9\xC3\x48\xA9\xF4\x48\x08\x4C\x74\xFC\xAD\x81\xC0\x68" 77 | "\x10\x07\x8D\x09\xC0\xAE\x01\x01\x9A\xA0\x06\x10\x06\xBE\xC1\xC4" 78 | "\xFE\x00\xC0\x88\x30\x03\x0A\xD0\xF2\x0A\x0A\x68\xA8\xBA\xA9\x40" 79 | "\x48\xA9\xC0\x48\xA9\x06\x69\x00\x48\xA9\x8D\x48\x9A\x8A\x69\x03" 80 | "\xAA\x38\xE9\x07\x9D\x00\x01\xE8\xA9\x01\x9D\x00\x01\x68\xAA\x68" 81 | "\x60\x83\x8B\x8B\x05\x03\x55\x00\x20\x13\xFF\x84\x34\xDD\xB4\xF9" 82 | "\xD0\x13\x20\x13\xFF\xDD\xBA\xF9\xF0\x0D\xBD\xBA\xF9\xF0\x07\xC9" 83 | "\xA4\xF0\x03\xA4\x34\x18\x88\x26\x44\xE0\x03\xD0\x0D\x20\xA7\xFF" 84 | "\xA5\x3F\xF0\x01\xE8\x86\x35\xA2\x03\x88\x86\x3D\xCA\x10\xC9\x60" 85 | "\x90\x48\xA9\x00\x85\x3D\x85\x3F\xA0\x50\x84\x3C\xC8\x84\x3E\x20" 86 | "\xD1\xC5\x18\xA5\x73\xAA\xCA\x86\x3E\xE5\x50\x48\xA5\x74\xA8\xE8" 87 | "\xD0\x01\x88\x84\x3F\xE5\x51\xC5\x6E\x90\x02\xD0\x02\x38\x60\x85" 88 | "\x74\x85\x70\x85\x3D\x85\xE9\x68\x85\xE8\x85\x73\x85\x6F\x85\x3C" 89 | "\x20\x98\xC5\xA9\x03\x20\xD6\xC5\x18\x60\xA5\x9B\x65\x50\x85\x3E" 90 | "\xA5\x9C\x65\x51\x85\x3F\xA0\x04\xB1\x9B\x20\xEF\xE0\xA5\x94\x85" 91 | "\x3C\xA5\x95\x85\x3D\x18\x60\xA0\x4B\x20\x79\xC5\xD0\xF9\x69\xFE" 92 | "\xB0\xF5\xA0\x21\x20\x79\xC5\xC8\xC8\x88\xD0\xFD\x90\x05\xA0\x32" 93 | "\x88\xD0\xFD\xAC\x20\xC0\xA0\x2C\xCA\x60\xA2\x08\x48\x20\x98\xC5" 94 | "\x68\x2A\xA0\x3A\xCA\xD0\xF5\x60\x20\x9B\xC5\x88\xAD\x60\xC0\x45" 95 | "\x2F\x10\xF8\x45\x2F\x85\x2F\xC0\x80\x60\x20\x67\xC5\xA0\x27\xA2" 96 | "\x00\x41\x3C\x48\xA1\x3C\x20\xC8\xC5\x20\xBA\xFC\xA0\x1D\x68\x90" 97 | "\xEE\xA0\x22\x20\xC8\xC5\xF0\x08\xA2\x10\x0A\x20\x74\xC5\xD0\xFA" 98 | "\x60\x20\x98\xC5\xA9\x16\x20\x67\xC5\x85\x2E\x20\x98\xC5\xA0\x24" 99 | "\x20\x9B\xC5\xB0\xF9\x20\x9B\xC5\xA0\x3B\x20\x8A\xC5\x81\x3C\x45" 100 | "\x2E\x85\x2E\x20\xBA\xFC\xA0\x35\x90\xF0\x20\x8A\xC5\xC5\x2E\x60" 101 | "\x8D\x50\xC0\xA0\x04\xA2\x00\x18\x79\xB4\xC7\x95\x00\xE8\xD0\xF7" 102 | "\x18\x79\xB4\xC7\xD5\x00\xD0\x10\xE8\xD0\xF5\x6A\x2C\x19\xC0\x10" 103 | "\x02\x49\xA5\x88\x10\xE1\x30\x06\x55\x00\x18\x4C\xCD\xC6\x86\x01" 104 | "\x86\x02\x86\x03\xA2\x04\x86\x04\xE6\x01\xA8\x8D\x83\xC0\x8D\x83" 105 | "\xC0\xA5\x01\x29\xF0\xC9\xC0\xD0\x0C\xAD\x8B\xC0\xAD\x8B\xC0\xA5" 106 | "\x01\x69\x0F\xD0\x02\xA5\x01\x85\x03\x98\xA0\x00\x18\x7D\xB4\xC7" 107 | "\x91\x02\xCA\x10\x02\xA2\x04\xC8\xD0\xF2\xE6\x01\xD0\xCC\xE6\x01" 108 | "\xA8\xAD\x83\xC0\xAD\x83\xC0\xA5\x01\x29\xF0\xC9\xC0\xD0\x09\xAD" 109 | "\x8B\xC0\xA5\x01\x69\x0F\xD0\x02\xA5\x01\x85\x03\x98\xA0\x00\x18" 110 | "\x7D\xB4\xC7\x51\x02\xD0\x35\xB1\x02\xCA\x10\x02\xA2\x04\xC8\xD0" 111 | "\xEE\xE6\x01\xD0\xCB\x6A\x2C\x19\xC0\x10\x02\x49\xA5\xC6\x04\x10" 112 | "\x87\xAA\x20\x8D\xC9\xD0\x07\x0E\x00\x0C\x0A\xCD\x00\x0C\xD0\x76" 113 | "\xCD\x00\x08\xF0\x71\x8A\x8D\x09\xC0\x4C\x03\xC6\x38\xAA\xAD\x13" 114 | "\xC0\xB8\x10\x03\x2C\xB4\xC7\xA9\xA0\xA0\x06\x99\xFE\xBF\x99\x06" 115 | "\xC0\x88\x88\xD0\xF6\x8D\x51\xC0\x8D\x54\xC0\x99\x00\x04\x99\x00" 116 | "\x05\x99\x00\x06\x99\x00\x07\xC8\xD0\xF1\x8A\xF0\x27\xA0\x03\xB0" 117 | "\x02\xA0\x05\xA9\xAA\x50\x03\x8D\xB0\x05\xB9\xEA\xC7\x99\xB1\x05" 118 | "\x88\x10\xF7\xA0\x10\x8A\x4A\xAA\xA9\x58\x2A\x99\xB6\x05\x88\x88" 119 | "\xD0\xF3\xF0\xFE\xA0\x02\xB9\xF0\xC7\x90\x03\xB9\xF3\xC7\x99\xB8" 120 | "\x05\x88\x10\xF2\x30\xFE\xA0\x01\xA9\x7F\x6A\xBE\xB9\xC7\xF0\x0F" 121 | "\x90\x03\xBE\xC9\xC7\x9D\xFF\xBF\xC8\xD0\xEF\xAE\x30\xC0\x2A\x88" 122 | "\xBE\xD9\xC7\xF0\x13\x30\xF4\x2A\x90\x07\x1E\x00\xC0\x90\x17\xB0" 123 | "\xEE\x1E\x00\xC0\xB0\x10\x90\xE7\x2A\xC8\x38\xE9\x01\xB0\xCB\x88" 124 | "\xD0\x0B\xA0\x09\xD0\xC2\xA2\x00\xC0\x0A\x4C\xD7\xC6\x46\x80\xD0" 125 | "\xB5\xA9\xA0\xA0\x00\x99\x00\x04\x99\x00\x05\x99\x00\x06\x99\x00" 126 | "\x07\xC8\xD0\xF1\xAD\x61\xC0\x2D\x62\xC0\x0A\xE6\xFF\xA5\xFF\x90" 127 | "\x03\x4C\x00\xC6\xAD\x51\xC0\xA0\x08\xB9\xF6\xC7\x99\xB8\x05\x88" 128 | "\x10\xF7\x30\xE0\x53\x43\x2B\x29\x07\x00\x89\x31\x03\x05\x09\x0B" 129 | "\x01\x00\x83\x51\x53\x55\x57\x0F\x0D\x00\x81\x31\x04\x06\x0A\x0C" 130 | "\x02\x00\x84\x52\x54\x56\x58\x10\x0E\x00\x11\xFF\x13\x14\x16\x17" 131 | "\x18\x00\x12\x1A\x1B\x1C\x1D\x1E\x1F\x00\xD2\xC1\xCD\xA0\xDA\xD0" 132 | "\xCD\xCD\xD5\xC9\xCF\xD5\xD3\xF9\xF3\xF4\xE5\xED\xA0\xCF\xCB\x00" 133 | "\x4C\xB0\xC9\x20\xF4\xCE\x20\x2A\xC8\x20\x2E\xCD\xA9\x01\x8D\xFB" 134 | "\x04\x20\x90\xCA\xD0\x08\x06\x21\x8D\x01\xC0\x8D\x0D\xC0\x8D\x0F" 135 | "\xC0\x20\x90\xCC\xAC\x7B\x05\x4C\x7E\xC8\xA9\x07\x85\x36\xA9\xC3" 136 | "\x85\x37\xA9\x05\x85\x38\xA9\xC3\x85\x39\x60\xE6\x4E\xD0\x02\xE6" 137 | "\x4F\xAD\x00\xC0\x10\xF5\x8D\x10\xC0\x60\x00\x00\x00\x4C\x50\xC3" 138 | "\xA5\x25\x8D\xFB\x05\xA4\x24\xCC\x7B\x04\xF0\x03\x8C\x7B\x05\xA5" 139 | "\x21\x18\xED\x7B\x05\xB0\x05\xA0\x00\x8C\x7B\x05\xAC\x7B\x05\x60" 140 | "\xA4\x35\x18\xB0\x38\x8D\x7B\x06\x98\x48\x8A\x48\xB0\x5E\x20\x50" 141 | "\xC8\xAD\x7B\x06\xC9\x8D\xD0\x18\xAE\x00\xC0\x10\x13\xE0\x93\xD0" 142 | "\x0F\x2C\x10\xC0\xAE\x00\xC0\x10\xFB\xE0\x83\xF0\x03\x2C\x10\xC0" 143 | "\x29\x7F\xC9\x20\xB0\x06\x20\xD2\xCA\x4C\xBD\xC8\xAD\x7B\x06\x20" 144 | "\x38\xCE\xC8\x8C\x7B\x05\xC4\x21\x90\x03\x20\x51\xCB\xAD\xFB\x04" 145 | "\x29\xF7\x8D\xFB\x04\xAD\x7B\x05\x2C\x1F\xC0\x10\x02\xA9\x00\x85" 146 | "\x24\x8D\x7B\x04\x68\xAA\x68\xA8\xAD\x7B\x06\x60\xA4\x24\xAD\x7B" 147 | "\x06\x91\x28\x20\x50\xC8\x20\x26\xCE\x20\x3B\xC8\x8D\x7B\x06\x20" 148 | "\x26\xCE\xA8\xAD\xFB\x04\x29\x08\xF0\xCB\xC0\x8D\xD0\x08\xAD\xFB" 149 | "\x04\x29\xF7\x8D\xFB\x04\xC0\x9B\xF0\x11\xC0\x95\xD0\xB7\xAC\x7B" 150 | "\x05\x20\x44\xCE\x09\x80\x8D\x7B\x06\xD0\xAA\x20\xB1\xCE\x20\x3B" 151 | "\xC8\x20\xC4\xCE\x20\x14\xCE\x29\x7F\xA0\x10\xD9\x7C\xC9\xF0\x05" 152 | "\x88\x10\xF8\x30\x0F\xB9\x6B\xC9\x29\x7F\x20\xD6\xCA\xB9\x6B\xC9" 153 | "\x30\xD9\x10\xA2\xA8\xAD\xFB\x04\xC0\x11\xD0\x0B\x20\x4D\xCD\xA9" 154 | "\x98\x8D\x7B\x06\x4C\xC5\xC8\xC0\x05\xD0\x08\x29\xDF\x8D\xFB\x04" 155 | "\x4C\xE6\xC8\xC0\x04\xD0\xF9\x09\x20\xD0\xF2\x0C\x1C\x08\x0A\x1F" 156 | "\x1D\x0B\x9F\x88\x9C\x8A\x11\x12\x88\x8A\x9F\x9C\x40\x41\x42\x43" 157 | "\x44\x45\x46\x49\x4A\x4B\x4D\x34\x38\x08\x0A\x0B\x15\x2C\x13\xC0" 158 | "\x30\x11\xA9\xEE\x8D\x05\xC0\x8D\x03\xC0\x8D\x00\x0C\x8D\x00\x08" 159 | "\xCD\x00\x0C\x60\xCA\xCB\xCD\xC9\x00\x00\xAD\x7B\x06\x4C\x56\xC3" 160 | "\xA9\x83\xD0\x02\xA9\x81\x48\x20\x90\xCA\xF0\x04\x68\xA2\x09\x60" 161 | "\x68\x8D\xFB\x04\x8D\x01\xC0\x8D\x0D\xC0\x8D\x0F\xC0\x20\xD4\xCE" 162 | "\x20\x90\xCC\x4C\x1F\xCA\x20\xD4\xCE\x20\x3B\xC8\x29\x7F\x8D\x7B" 163 | "\x06\xA2\x00\xAD\xFB\x04\x29\x02\xF0\x02\xA2\xC3\xAD\x7B\x06\x60" 164 | "\x29\x7F\xAA\x20\xD4\xCE\xA9\x08\x2C\xFB\x04\xD0\x32\x8A\x2C\x2E" 165 | "\xCA\xF0\x50\xAC\x7B\x05\x24\x32\x10\x02\x09\x80\x20\x70\xCE\xC8" 166 | "\x8C\x7B\x05\xC4\x21\x90\x08\xA9\x00\x8D\x7B\x05\x20\xD8\xCB\xA5" 167 | "\x28\x8D\x7B\x07\xA5\x29\x8D\xFB\x07\x20\x1F\xCE\xA2\x00\x60\x20" 168 | "\x1F\xCE\x8A\x38\xE9\x20\x2C\xFB\x06\x30\x30\x8D\xFB\x05\x85\x25" 169 | "\x20\xBA\xCA\xAD\xFB\x06\x8D\x7B\x05\xA9\xF7\x2D\xFB\x04\x8D\xFB" 170 | "\x04\xD0\xCC\x20\x1F\xCE\x8A\xC9\x1E\xF0\x06\x20\xD6\xCA\x4C\x1F" 171 | "\xCA\xA9\x08\x0D\xFB\x04\x8D\xFB\x04\xA9\xFF\x8D\xFB\x06\x4C\x29" 172 | "\xCA\xAA\xA5\x2A\xA0\x03\xE0\x8A\xF0\x0B\x4A\x90\x08\x4A\x4A\x09" 173 | "\x20\x88\xD0\xFA\xC8\x88\xD0\xF2\x60\x20\xB7\xF8\xD0\x02\xC8\x60" 174 | "\xAD\x1C\xC0\x0A\xA9\x88\x2C\x18\xC0\x8D\x01\xC0\x08\x8D\x55\xC0" 175 | "\xAC\x00\x04\x8D\x00\x04\xAD\x00\x04\x8C\x00\x04\x28\xB0\x03\x8D" 176 | "\x54\xC0\x30\x03\x8D\x00\xC0\xC9\x88\x60\x48\x4A\x29\x03\x09\x04" 177 | "\x85\x29\x68\x29\x18\x90\x02\x69\x7F\x85\x28\x0A\x0A\x05\x28\x85" 178 | "\x28\x60\x2C\x06\xCB\x50\xB8\x8D\x7B\x07\x48\x98\x48\xAC\x7B\x07" 179 | "\xC0\x05\x90\x13\xB9\xB4\xCB\xF0\x0E\x50\x12\x30\x10\x8D\x7B\x07" 180 | "\xAD\xFB\x04\x29\x28\xF0\x03\x38\xB0\x09\xAD\x7B\x07\x09\x80\x20" 181 | "\x07\xCB\x18\x68\xA8\x68\x60\x48\xB9\x99\xCB\x48\x60\xAD\xFB\x04" 182 | "\x10\x05\x29\xEF\x8D\xFB\x04\x60\xAD\xFB\x04\x10\xFA\x09\x10\xD0" 183 | "\xF3\xA9\x40\x20\x34\xCB\xA0\xC0\xA9\x0C\x20\x34\xCB\xAD\x30\xC0" 184 | "\x88\xD0\xF5\x60\x38\x48\xE9\x01\xD0\xFC\x68\xE9\x01\xD0\xF6\x60" 185 | "\xCE\x7B\x05\x10\x0B\xA5\x21\x8D\x7B\x05\xCE\x7B\x05\x20\x79\xCB" 186 | "\x60\xA9\x00\x8D\x7B\x05\xAD\xFB\x04\x30\x03\x20\xD8\xCB\x60\xA5" 187 | "\x22\x85\x25\xA9\x00\x8D\x7B\x05\x4C\xFE\xCD\xEE\x7B\x05\xAD\x7B" 188 | "\x05\xC5\x21\x90\x03\x20\x51\xCB\x60\xA5\x22\xC5\x25\xB0\x1E\xC6" 189 | "\x25\x4C\xFE\xCD\xAD\xFB\x04\x10\x02\x29\xFB\xA0\xFF\xD0\x09\xAD" 190 | "\xFB\x04\x10\x02\x09\x04\xA0\x7F\x8D\xFB\x04\x84\x32\x60\x0C\x17" 191 | "\x20\x3F\x00\xD7\x73\x8F\x50\x83\x8E\x00\xE9\xFB\x00\x00\x4C\xD3" 192 | "\xEA\x3C\x5E\x95\x43\x6A\x99\x00\x78\x4B\x4B\xCB\xCB\x00\xCB\x4C" 193 | "\x4C\xCB\x4B\x4B\x00\x4C\x4C\x00\x00\x4D\x4B\x4B\x4D\x4B\x4C\x4D" 194 | "\x4B\x4C\x00\x4B\xA0\x00\xF0\x15\xE6\x25\xA5\x25\x8D\xFB\x05\xC5" 195 | "\x23\xB0\x03\x4C\x03\xCE\xCE\xFB\x05\xC6\x25\xA0\x01\x8A\x48\x8C" 196 | "\x7B\x07\xA5\x21\x48\x2C\x1F\xC0\x10\x1C\x8D\x01\xC0\x4A\xAA\xA5" 197 | "\x20\x4A\xB8\x90\x03\x2C\x06\xCB\x2A\x45\x21\x4A\x70\x03\xB0\x01" 198 | "\xCA\x86\x21\xAD\x1F\xC0\x08\xA6\x22\x98\xD0\x03\xA6\x23\xCA\x8A" 199 | "\x20\x03\xCE\xA5\x28\x85\x2A\xA5\x29\x85\x2B\xAD\x7B\x07\xF0\x32" 200 | "\xE8\xE4\x23\xB0\x32\x8A\x20\x03\xCE\xA4\x21\x28\x08\x10\x1E\xAD" 201 | "\x55\xC0\x98\xF0\x07\xB1\x28\x91\x2A\x88\xD0\xF9\x70\x04\xB1\x28" 202 | "\x91\x2A\xAD\x54\xC0\xA4\x21\xB0\x04\xB1\x28\x91\x2A\x88\x10\xF9" 203 | "\x30\xC1\xCA\xE4\x22\x10\xCE\x28\x68\x85\x21\x20\x96\xCC\x20\xFE" 204 | "\xCD\x68\xAA\x60\x20\x9A\xCC\xA5\x25\x48\x10\x06\x20\x03\xCE\x20" 205 | "\x96\xCC\xE6\x25\xA5\x25\xC5\x23\x90\xF2\x68\x85\x25\x4C\xFE\xCD" 206 | "\x20\x5F\xCB\x4C\x74\xCC\xA0\x00\xF0\x03\xAC\x7B\x05\xA5\x32\x29" 207 | "\x80\x09\x20\x2C\x1F\xC0\x30\x15\x91\x28\xC8\xC4\x21\x90\xF9\x60" 208 | "\x86\x2A\xA2\xD8\xA0\x14\xA5\x32\x29\xA0\x4C\xD5\xCC\x86\x2A\x48" 209 | "\x98\x48\x38\xE5\x21\xAA\x98\x4A\xA8\x68\x45\x20\x6A\xB0\x03\x10" 210 | "\x01\xC8\x68\xB0\x0B\x2C\x55\xC0\x91\x28\x2C\x54\xC0\xE8\xF0\x06" 211 | "\x91\x28\xC8\xE8\xD0\xEF\xA6\x2A\x38\x60\xAD\xFB\x04\x30\x4D\x20" 212 | "\x31\xCD\x2C\x1F\xC0\x10\x12\x20\x91\xCD\x90\x0D\x20\x90\xCA\xD0" 213 | "\x3B\x2C\x1F\xC0\x30\x03\x20\xC4\xCD\xAD\x7B\x05\x18\x65\x20\x2C" 214 | "\x1F\xC0\x30\x06\xC9\x28\x90\x02\xA9\x27\x8D\x7B\x05\x85\x24\xA5" 215 | "\x25\x20\xBA\xCA\x2C\x1F\xC0\x10\x05\x20\x71\xCD\xF0\x03\x20\x6D" 216 | "\xCD\xA9\x00\x2C\x1A\xC0\x30\x02\xA9\x14\x85\x22\x60\xAD\xFB\x04" 217 | "\x09\x01\xD0\x05\xAD\xFB\x04\x29\xFE\x8D\xFB\x04\x60\xAD\xFB\x04" 218 | "\x30\x1A\x20\x2E\xCD\x20\x80\xCD\x20\x64\xCD\xA9\xFD\x85\x39\xA9" 219 | "\x1B\x85\x38\x60\xA9\xFD\x85\x37\xA9\xF0\x85\x36\x60\xA9\x28\xD0" 220 | "\x02\xA9\x50\x85\x21\xA9\x18\x85\x23\xA9\x00\x85\x22\x85\x20\x60" 221 | "\x2C\x1F\xC0\x10\x03\x20\xEF\xCC\x8D\x0E\xC0\xA9\xFF\x8D\xFB\x04" 222 | "\x60\x8A\x48\xA2\x17\x8D\x01\xC0\x8A\x20\xBA\xCA\xA0\x27\x84\x2A" 223 | "\x98\x4A\xB0\x03\x2C\x55\xC0\xA8\xB1\x28\x2C\x54\xC0\xA4\x2A\x91" 224 | "\x28\x88\x10\xEA\xCA\x30\x04\xE4\x22\xB0\xDD\x8D\x00\xC0\x8D\x0C" 225 | "\xC0\x4C\xF8\xCD\x8A\x48\xA2\x17\x8A\x20\xBA\xCA\xA0\x00\x8D\x01" 226 | "\xC0\xB1\x28\x84\x2A\x48\x98\x4A\xB0\x03\x8D\x55\xC0\xA8\x68\x91" 227 | "\x28\x8D\x54\xC0\xA4\x2A\xC8\xC0\x28\x90\xE6\x20\xB0\xCC\xCA\x30" 228 | "\x04\xE4\x22\xB0\xD3\x8D\x0D\xC0\x20\xFE\xCD\x68\xAA\x60\xA5\x25" 229 | "\x8D\xFB\x05\x20\xBA\xCA\xA5\x20\x2C\x1F\xC0\x10\x01\x4A\x18\x65" 230 | "\x28\x85\x28\x60\xC9\xE1\x90\x06\xC9\xFB\xB0\x02\x29\xDF\x60\xAD" 231 | "\xFB\x04\x29\x10\xD0\x11\x48\x98\x48\xAC\x7B\x05\x20\x44\xCE\x49" 232 | "\x80\x20\x70\xCE\x68\xA8\x68\x60\x48\x24\x32\x30\x02\x29\x7F\x20" 233 | "\x70\xCE\x68\x60\xB1\x28\x2C\x1F\xC0\x10\x19\x8D\x01\xC0\x84\x2A" 234 | "\x98\x45\x20\x6A\xB0\x04\xAD\x55\xC0\xC8\x98\x4A\xA8\xB1\x28\x2C" 235 | "\x54\xC0\xA4\x2A\x2C\x1E\xC0\x10\x06\xC9\x20\xB0\x02\x09\x40\x60" 236 | "\x48\x29\xFF\x30\x16\xAD\xFB\x04\x6A\x68\x48\x90\x0E\x2C\x1E\xC0" 237 | "\x10\x09\x49\x40\x2C\xAC\xCE\xF0\x02\x49\x40\x2C\x1F\xC0\x10\x1D" 238 | "\x8D\x01\xC0\x48\x84\x2A\x98\x45\x20\x4A\xB0\x04\xAD\x55\xC0\xC8" 239 | "\x98\x4A\xA8\x68\x91\x28\xAD\x54\xC0\xA4\x2A\x68\x60\x91\x28\x68" 240 | "\x60\x48\x98\x48\xAC\x7B\x05\x20\x44\xCE\x8D\x7B\x06\x29\x80\x49" 241 | "\xAB\x4C\xCD\xCE\x48\x98\x48\xAC\x7B\x05\xAD\x7B\x06\x20\x70\xCE" 242 | "\x68\xA8\x68\x60\x20\x71\xCD\xA9\xFF\x85\x32\xAD\xFB\x04\x29\x04" 243 | "\xF0\x02\x46\x32\xAD\x7B\x07\x85\x28\xAD\xFB\x07\x85\x29\xAD\xFB" 244 | "\x05\x85\x25\x60\x2C\x12\xC0\x10\x3D\xA9\x06\xCD\xB3\xFB\xF0\x36" 245 | "\xA2\x03\x2C\x11\xC0\x30\x02\xA2\x0B\x8D\xB3\xFB\x2C\x80\xC0\xAD" 246 | "\xB3\xFB\xC9\x06\xF0\x01\xE8\x2C\x81\xC0\x2C\x81\xC0\xA0\x00\xA9" 247 | "\xF8\x85\x37\x84\x36\xB1\x36\x91\x36\xC8\xD0\xF9\xE6\x37\xD0\xF5" 248 | "\xBD\x80\xC0\xBD\x80\xC0\x60\x00\x00\x00\xE9\x81\x4A\xD0\x14\xA4" 249 | "\x3F\xA6\x3E\xD0\x01\x88\xCA\x8A\x18\xE5\x3A\x85\x3E\x10\x01\xC8" 250 | "\x98\xE5\x3B\xD0\x40\xA4\x2F\xB9\x3D\x00\x91\x3A\x88\x10\xF8\x20" 251 | "\x48\xF9\x20\x1A\xFC\x20\x1A\xFC\x4C\xE3\xFC\xA5\x3D\x20\x8E\xF8" 252 | "\xAA\xBD\x00\xFA\xC5\x42\xD0\x13\xBD\xC0\xF9\xC5\x43\xD0\x0C\xA5" 253 | "\x44\xA4\x2E\xC0\x9D\xF0\xB3\xC5\x2E\xF0\xCA\xC6\x3D\xD0\xDC\xE6" 254 | "\x44\xC6\x35\xF0\xD6\xA4\x34\x98\xAA\x4C\xD2\xFC\x20\xC7\xFF\xAD" 255 | "\x00\x02\xC9\xA0\xF0\x12\xC9\x8D\xD0\x01\x60\x20\xA7\xFF\xC9\x93" 256 | "\xD0\xE5\x8A\xF0\xE2\x20\x78\xFE\xA9\x03\x85\x3D\x20\x13\xFF\x0A" 257 | "\xE9\xBE\xC9\xC2\x90\xD1\x0A\x0A\xA2\x04\x0A\x26\x42\x26\x43\xCA" 258 | "\x10\xF8\xC6\x3D\xF0\xF4\x10\xE4\xA2\x05\x20\xC8\xC4\xA5\x44\x0A" 259 | "\x0A\x05\x35\xC9\x20\xB0\x06\xA6\x35\xF0\x02\x09\x80\x85\x44\x84" 260 | "\x34\xB9\x00\x02\xC9\xBB\xF0\x04\xC9\x8D\xD0\xB4\x4C\x6B\xCF\xDF" 261 | "\x6F\xD8\x65\xD7\xF8\xDC\x94\xD9\xB1\xDB\x30\xF3\xD8\xDF\xE1\xDB" 262 | "\x8F\xF3\x98\xF3\xE4\xF1\xDD\xF1\xD4\xF1\x24\xF2\x31\xF2\x40\xF2" 263 | "\xD7\xF3\xE1\xF3\xE8\xF6\xFD\xF6\x68\xF7\x6E\xF7\xE6\xF7\x57\xFC" 264 | "\x20\xF7\x26\xF7\x74\xF7\x6C\xF2\x6E\xF2\x72\xF2\x76\xF2\x7F\xF2" 265 | "\x4E\xF2\x6A\xD9\x55\xF2\x85\xF2\xA5\xF2\xCA\xF2\x17\xF3\xBB\xF3" 266 | "\x9E\xF3\x61\xF2\x45\xDA\x3D\xD9\x11\xD9\xC8\xD9\x48\xD8\xF4\x03" 267 | "\x20\xD9\x6A\xD9\xDB\xD9\x6D\xD8\xEB\xD9\x83\xE7\xC8\xD8\xAF\xD8" 268 | "\x12\xE3\x7A\xE7\xD4\xDA\x95\xD8\xA4\xD6\x69\xD6\x9F\xDB\x48\xD6" 269 | "\x90\xEB\x23\xEC\xAF\xEB\x0A\x00\xDE\xE2\x12\xD4\xCD\xDF\xFF\xE2" 270 | "\x8D\xEE\xAE\xEF\x41\xE9\x09\xEF\xEA\xEF\xF1\xEF\x3A\xF0\x9E\xF0" 271 | "\x64\xE7\xD6\xE6\xC5\xE3\x07\xE7\xE5\xE6\x46\xE6\x5A\xE6\x86\xE6" 272 | "\x91\xE6\x79\xC0\xE7\x79\xA9\xE7\x7B\x81\xE9\x7B\x68\xEA\x7D\x96" 273 | "\xEE\x50\x54\xDF\x46\x4E\xDF\x7F\xCF\xEE\x7F\x97\xDE\x64\x64\xDF" 274 | "\x45\x4E\xC4\x46\x4F\xD2\x4E\x45\x58\xD4\x44\x41\x54\xC1\x49\x4E" 275 | "\x50\x55\xD4\x44\x45\xCC\x44\x49\xCD\x52\x45\x41\xC4\x47\xD2\x54" 276 | "\x45\x58\xD4\x50\x52\xA3\x49\x4E\xA3\x43\x41\x4C\xCC\x50\x4C\x4F" 277 | "\xD4\x48\x4C\x49\xCE\x56\x4C\x49\xCE\x48\x47\x52\xB2\x48\x47\xD2" 278 | "\x48\x43\x4F\x4C\x4F\x52\xBD\x48\x50\x4C\x4F\xD4\x44\x52\x41\xD7" 279 | "\x58\x44\x52\x41\xD7\x48\x54\x41\xC2\x48\x4F\x4D\xC5\x52\x4F\x54" 280 | "\xBD\x53\x43\x41\x4C\x45\xBD\x53\x48\x4C\x4F\x41\xC4\x54\x52\x41" 281 | "\x43\xC5\x4E\x4F\x54\x52\x41\x43\xC5\x4E\x4F\x52\x4D\x41\xCC\x49" 282 | "\x4E\x56\x45\x52\x53\xC5\x46\x4C\x41\x53\xC8\x43\x4F\x4C\x4F\x52" 283 | "\xBD\x50\x4F\xD0\x56\x54\x41\xC2\x48\x49\x4D\x45\x4D\xBA\x4C\x4F" 284 | "\x4D\x45\x4D\xBA\x4F\x4E\x45\x52\xD2\x52\x45\x53\x55\x4D\xC5\x52" 285 | "\x45\x43\x41\x4C\xCC\x53\x54\x4F\x52\xC5\x53\x50\x45\x45\x44\xBD" 286 | "\x4C\x45\xD4\x47\x4F\x54\xCF\x52\x55\xCE\x49\xC6\x52\x45\x53\x54" 287 | "\x4F\x52\xC5\xA6\x47\x4F\x53\x55\xC2\x52\x45\x54\x55\x52\xCE\x52" 288 | "\x45\xCD\x53\x54\x4F\xD0\x4F\xCE\x57\x41\x49\xD4\x4C\x4F\x41\xC4" 289 | "\x53\x41\x56\xC5\x44\x45\xC6\x50\x4F\x4B\xC5\x50\x52\x49\x4E\xD4" 290 | "\x43\x4F\x4E\xD4\x4C\x49\x53\xD4\x43\x4C\x45\x41\xD2\x47\x45\xD4" 291 | "\x4E\x45\xD7\x54\x41\x42\xA8\x54\xCF\x46\xCE\x53\x50\x43\xA8\x54" 292 | "\x48\x45\xCE\x41\xD4\x4E\x4F\xD4\x53\x54\x45\xD0\xAB\xAD\xAA\xAF" 293 | "\xDE\x41\x4E\xC4\x4F\xD2\xBE\xBD\xBC\x53\x47\xCE\x49\x4E\xD4\x41" 294 | "\x42\xD3\x55\x53\xD2\x46\x52\xC5\x53\x43\x52\x4E\xA8\x50\x44\xCC" 295 | "\x50\x4F\xD3\x53\x51\xD2\x52\x4E\xC4\x4C\x4F\xC7\x45\x58\xD0\x43" 296 | "\x4F\xD3\x53\x49\xCE\x54\x41\xCE\x41\x54\xCE\x50\x45\x45\xCB\x4C" 297 | "\x45\xCE\x53\x54\x52\xA4\x56\x41\xCC\x41\x53\xC3\x43\x48\x52\xA4" 298 | "\x4C\x45\x46\x54\xA4\x52\x49\x47\x48\x54\xA4\x4D\x49\x44\xA4\x00" 299 | "\x4E\x45\x58\x54\x20\x57\x49\x54\x48\x4F\x55\x54\x20\x46\x4F\xD2" 300 | "\x53\x59\x4E\x54\x41\xD8\x52\x45\x54\x55\x52\x4E\x20\x57\x49\x54" 301 | "\x48\x4F\x55\x54\x20\x47\x4F\x53\x55\xC2\x4F\x55\x54\x20\x4F\x46" 302 | "\x20\x44\x41\x54\xC1\x49\x4C\x4C\x45\x47\x41\x4C\x20\x51\x55\x41" 303 | "\x4E\x54\x49\x54\xD9\x4F\x56\x45\x52\x46\x4C\x4F\xD7\x4F\x55\x54" 304 | "\x20\x4F\x46\x20\x4D\x45\x4D\x4F\x52\xD9\x55\x4E\x44\x45\x46\x27" 305 | "\x44\x20\x53\x54\x41\x54\x45\x4D\x45\x4E\xD4\x42\x41\x44\x20\x53" 306 | "\x55\x42\x53\x43\x52\x49\x50\xD4\x52\x45\x44\x49\x4D\x27\x44\x20" 307 | "\x41\x52\x52\x41\xD9\x44\x49\x56\x49\x53\x49\x4F\x4E\x20\x42\x59" 308 | "\x20\x5A\x45\x52\xCF\x49\x4C\x4C\x45\x47\x41\x4C\x20\x44\x49\x52" 309 | "\x45\x43\xD4\x54\x59\x50\x45\x20\x4D\x49\x53\x4D\x41\x54\x43\xC8" 310 | "\x53\x54\x52\x49\x4E\x47\x20\x54\x4F\x4F\x20\x4C\x4F\x4E\xC7\x46" 311 | "\x4F\x52\x4D\x55\x4C\x41\x20\x54\x4F\x4F\x20\x43\x4F\x4D\x50\x4C" 312 | "\x45\xD8\x43\x41\x4E\x27\x54\x20\x43\x4F\x4E\x54\x49\x4E\x55\xC5" 313 | "\x55\x4E\x44\x45\x46\x27\x44\x20\x46\x55\x4E\x43\x54\x49\x4F\xCE" 314 | "\x20\x45\x52\x52\x4F\x52\x07\x00\x20\x49\x4E\x20\x00\x0D\x42\x52" 315 | "\x45\x41\x4B\x07\x00\xBA\xE8\xE8\xE8\xE8\xBD\x01\x01\xC9\x81\xD0" 316 | "\x21\xA5\x86\xD0\x0A\xBD\x02\x01\x85\x85\xBD\x03\x01\x85\x86\xDD" 317 | "\x03\x01\xD0\x07\xA5\x85\xDD\x02\x01\xF0\x07\x8A\x18\x69\x12\xAA" 318 | "\xD0\xD8\x60\x20\xE3\xD3\x85\x6D\x84\x6E\x38\xA5\x96\xE5\x9B\x85" 319 | "\x5E\xA8\xA5\x97\xE5\x9C\xAA\xE8\x98\xF0\x23\xA5\x96\x38\xE5\x5E" 320 | "\x85\x96\xB0\x03\xC6\x97\x38\xA5\x94\xE5\x5E\x85\x94\xB0\x08\xC6" 321 | "\x95\x90\x04\xB1\x96\x91\x94\x88\xD0\xF9\xB1\x96\x91\x94\xC6\x97" 322 | "\xC6\x95\xCA\xD0\xF2\x60\x0A\x69\x36\xB0\x35\x85\x5E\xBA\xE4\x5E" 323 | "\x90\x2E\x60\xC4\x70\x90\x28\xD0\x04\xC5\x6F\x90\x22\x48\xA2\x09" 324 | "\x98\x48\xB5\x93\xCA\x10\xFA\x20\x84\xE4\xA2\xF7\x68\x95\x9D\xE8" 325 | "\x30\xFA\x68\xA8\x68\xC4\x70\x90\x06\xD0\x05\xC5\x6F\xB0\x01\x60" 326 | "\xA2\x4D\x24\xD8\x10\x03\x4C\xE9\xF2\x20\xFB\xDA\x20\x5A\xDB\xBD" 327 | "\x60\xD2\x48\x20\x5C\xDB\xE8\x68\x10\xF5\x20\x83\xD6\xA9\x50\xA0" 328 | "\xD3\x20\x3A\xDB\xA4\x76\xC8\xF0\x03\x20\x19\xED\x20\xFB\xDA\xA2" 329 | "\xDD\x20\x2E\xD5\x86\xB8\x84\xB9\x46\xD8\x20\xB1\x00\xAA\xF0\xEC" 330 | "\xA2\xFF\x86\x76\x90\x06\x20\x59\xD5\x4C\x05\xD8\xA6\xAF\x86\x69" 331 | "\xA6\xB0\x86\x6A\x20\x0C\xDA\x20\x59\xD5\x84\x0F\x20\x1A\xD6\x90" 332 | "\x44\xA0\x01\xB1\x9B\x85\x5F\xA5\x69\x85\x5E\xA5\x9C\x85\x61\xA5" 333 | "\x9B\x88\xF1\x9B\x18\x65\x69\x85\x69\x85\x60\xA5\x6A\x69\xFF\x85" 334 | "\x6A\xE5\x9C\xAA\x38\xA5\x9B\xE5\x69\xA8\xB0\x03\xE8\xC6\x61\x18" 335 | "\x65\x5E\x90\x03\xC6\x5F\x18\xB1\x5E\x91\x60\xC8\xD0\xF9\xE6\x5F" 336 | "\xE6\x61\xCA\xD0\xF2\xAD\x00\x02\xF0\x38\xA5\x73\xA4\x74\x85\x6F" 337 | "\x84\x70\xA5\x69\x85\x96\x65\x0F\x85\x94\xA4\x6A\x84\x97\x90\x01" 338 | "\xC8\x84\x95\x20\x93\xD3\xA5\x50\xA4\x51\x8D\xFE\x01\x8C\xFF\x01" 339 | "\xA5\x6D\xA4\x6E\x85\x69\x84\x6A\xA4\x0F\xB9\xFB\x01\x88\x91\x9B" 340 | "\xD0\xF8\x20\x65\xD6\xA5\x67\xA4\x68\x85\x5E\x84\x5F\x18\xA0\x01" 341 | "\xB1\x5E\xD0\x0B\xA5\x69\x85\xAF\xA5\x6A\x85\xB0\x4C\x3C\xD4\xA0" 342 | "\x04\xC8\xB1\x5E\xD0\xFB\xC8\x98\x65\x5E\xAA\xA0\x00\x91\x5E\xA5" 343 | "\x5F\x69\x00\xC8\x91\x5E\x86\x5E\x85\x5F\x90\xD2\xA2\x80\x86\x33" 344 | "\x20\x6A\xFD\xE0\xEF\x90\x02\xA2\xEF\xA9\x00\x9D\x00\x02\x8A\xF0" 345 | "\x0B\xBD\xFF\x01\x29\x7F\x9D\xFF\x01\xCA\xD0\xF5\xA9\x00\xA2\xFF" 346 | "\xA0\x01\x60\x20\x0C\xFD\x29\x7F\x60\xA6\xB8\xCA\xA0\x04\x84\x13" 347 | "\x24\xD6\x10\x08\x68\x68\x20\x65\xD6\x4C\xD2\xD7\xE8\x20\x8C\xF7" 348 | "\x24\x13\x70\x04\xC9\x20\xF0\xF4\x85\x0E\xC9\x22\xF0\x74\x70\x4D" 349 | "\xC9\x3F\xD0\x04\xA9\xBA\xD0\x45\xC9\x30\x90\x04\xC9\x3C\x90\x3D" 350 | "\x84\xAD\xA9\xD0\x85\x9D\xA9\xCF\x85\x9E\xA0\x00\x84\x0F\x88\x86" 351 | "\xB8\xCA\xC8\xD0\x02\xE6\x9E\xE8\x20\x8C\xF7\xC9\x20\xF0\xF8\x38" 352 | "\xF1\x9D\xF0\xEE\xC9\x80\xD0\x41\x05\x0F\xC9\xC5\xD0\x0D\x20\x87" 353 | "\xF7\xC9\x4E\xF0\x34\xC9\x4F\xF0\x30\xA9\xC5\xA4\xAD\xE8\xC8\x99" 354 | "\xFB\x01\xB9\xFB\x01\xF0\x39\x38\xE9\x3A\xF0\x04\xC9\x49\xD0\x02" 355 | "\x85\x13\x38\xE9\x78\xD0\x86\x85\x0E\x20\x8C\xF7\xF0\xDF\xC5\x0E" 356 | "\xF0\xDB\xC8\x99\xFB\x01\xE8\xD0\xF0\xA6\xB8\xE6\x0F\xB1\x9D\xC8" 357 | "\xD0\x02\xE6\x9E\x0A\x90\xF6\xB1\x9D\xD0\x9D\x20\x9A\xF7\x10\xBB" 358 | "\x99\xFD\x01\xC6\xB9\xA9\xFF\x85\xB8\x60\xA5\x67\xA6\x68\xA0\x01" 359 | "\x85\x9B\x86\x9C\xB1\x9B\xF0\x1F\xC8\xC8\xA5\x51\xD1\x9B\x90\x18" 360 | "\xF0\x03\x88\xD0\x09\xA5\x50\x88\xD1\x9B\x90\x0C\xF0\x0A\x88\xB1" 361 | "\x9B\xAA\x88\xB1\x9B\xB0\xD7\x18\x60\xD0\xFD\xA9\x00\x85\xD6\xA8" 362 | "\x91\x67\xC8\x91\x67\xA5\x67\x69\x02\x85\x69\x85\xAF\xA5\x68\x69" 363 | "\x00\x85\x6A\x85\xB0\x20\x97\xD6\xA9\x00\xD0\x2A\xA5\x73\xA4\x74" 364 | "\x85\x6F\x84\x70\xA5\x69\xA4\x6A\x85\x6B\x84\x6C\x85\x6D\x84\x6E" 365 | "\x20\x49\xD8\xA2\x55\x86\x52\x68\xA8\x68\xA2\xF8\x9A\x48\x98\x48" 366 | "\xA9\x00\x85\x7A\x85\x14\x60\x18\xA5\x67\x69\xFF\x85\xB8\xA5\x68" 367 | "\x69\xFF\x85\xB9\x60\x90\x0A\xF0\x08\xC9\xC9\xF0\x04\xC9\x2C\xD0" 368 | "\xE5\x20\x0C\xDA\x20\x1A\xD6\x20\xB7\x00\xF0\x10\xC9\xC9\xF0\x04" 369 | "\xC9\x2C\xD0\x84\x20\xB1\x00\x20\x0C\xDA\xD0\xCA\x68\x68\xA5\x50" 370 | "\x05\x51\xD0\x06\xA9\xFF\x85\x50\x85\x51\xA0\x01\xB1\x9B\xF0\x44" 371 | "\x20\x58\xD8\x20\xFB\xDA\xC8\xB1\x9B\xAA\xC8\xB1\x9B\xC5\x51\xD0" 372 | "\x04\xE4\x50\xF0\x02\xB0\x2D\x84\x85\x20\xAA\xF7\xA9\x20\xA4\x85" 373 | "\x29\x7F\x20\x5C\xDB\x20\xB4\xF7\xEA\x90\x07\x20\xFB\xDA\xA9\x05" 374 | "\x85\x24\xC8\xB1\x9B\xD0\x1D\xA8\xB1\x9B\xAA\xC8\xB1\x9B\x86\x9B" 375 | "\x85\x9C\xD0\xB6\xA9\x0D\x20\x5C\xDB\x4C\xD2\xD7\xC8\xD0\x02\xE6" 376 | "\x9E\xB1\x9D\x60\x10\xCC\x38\xE9\x7F\xAA\x84\x85\xA0\xD0\x84\x9D" 377 | "\xA0\xCF\x84\x9E\xA0\xFF\xCA\xF0\x07\x20\x2C\xD7\x10\xFB\x30\xF6" 378 | "\xA9\x20\x20\x5C\xDB\x20\x2C\xD7\x30\x05\x20\x5C\xDB\xD0\xF6\x20" 379 | "\x5C\xDB\xA9\x20\xD0\x98\xA9\x80\x85\x14\x20\x46\xDA\x20\x65\xD3" 380 | "\xD0\x05\x8A\x69\x0F\xAA\x9A\x68\x68\xA9\x09\x20\xD6\xD3\x20\xA3" 381 | "\xD9\x18\x98\x65\xB8\x48\xA5\xB9\x69\x00\x48\xA5\x76\x48\xA5\x75" 382 | "\x48\xA9\xC1\x20\xC0\xDE\x20\x6A\xDD\x20\x67\xDD\xA5\xA2\x09\x7F" 383 | "\x25\x9E\x85\x9E\xA9\xAF\xA0\xD7\x85\x5E\x84\x5F\x4C\x20\xDE\xA9" 384 | "\x13\xA0\xE9\x20\xF9\xEA\x20\xB7\x00\xC9\xC7\xD0\x06\x20\xB1\x00" 385 | "\x20\x67\xDD\x20\x82\xEB\x20\x15\xDE\xA5\x86\x48\xA5\x85\x48\xA9" 386 | "\x81\x48\xBA\x86\xF8\x20\x58\xD8\xA5\xB8\xA4\xB9\xA6\x76\xE8\xF0" 387 | "\x04\x85\x79\x84\x7A\xA0\x00\xB1\xB8\xD0\x57\xA0\x02\xB1\xB8\x18" 388 | "\xF0\x34\xC8\xB1\xB8\x85\x75\xC8\xB1\xB8\x85\x76\x98\x65\xB8\x85" 389 | "\xB8\x90\x02\xE6\xB9\x24\xF2\x10\x14\xA6\x76\xE8\xF0\x0F\xA9\x23" 390 | "\x20\x5C\xDB\xA6\x75\xA5\x76\x20\x24\xED\x20\x57\xDB\x20\xB1\x00" 391 | "\x20\x28\xD8\x4C\xD2\xD7\xF0\x62\xF0\x2D\xE9\x80\x90\x11\xC9\x40" 392 | "\xB0\x14\x0A\xA8\xB9\x01\xD0\x48\xB9\x00\xD0\x48\x4C\xB1\x00\x4C" 393 | "\x46\xDA\xC9\x3A\xF0\xBF\x4C\xC9\xDE\x38\xA5\x67\xE9\x01\xA4\x68" 394 | "\xB0\x01\x88\x85\x7D\x84\x7E\x60\xAD\x00\xC0\xC9\x83\xF0\x01\x60" 395 | "\x20\x53\xD5\xA2\xFF\x24\xD8\x10\x03\x4C\xE9\xF2\xC9\x03\xB0\x01" 396 | "\x18\xD0\x3C\xA5\xB8\xA4\xB9\xA6\x76\xE8\xF0\x0C\x85\x79\x84\x7A" 397 | "\xA5\x75\xA4\x76\x85\x77\x84\x78\x68\x68\xA9\x5D\xA0\xD3\x90\x03" 398 | "\x4C\x31\xD4\x4C\x3C\xD4\xD0\x17\xA2\xD2\xA4\x7A\xD0\x03\x4C\x12" 399 | "\xD4\xA5\x79\x85\xB8\x84\xB9\xA5\x77\xA4\x78\x85\x75\x84\x76\x60" 400 | "\x38\xA5\xAF\xE5\x67\x85\x50\xA5\xB0\xE5\x68\x85\x51\x20\xF0\xD8" 401 | "\x20\xCD\xFE\x20\x01\xD9\x4C\xCD\xFE\x20\xF0\xD8\x20\xFD\xFE\x18" 402 | "\xA5\x67\x65\x50\x85\x69\xA5\x68\x65\x51\x85\x6A\xA5\x52\x85\xD6" 403 | "\x20\x01\xD9\x20\xFD\xFE\x24\xD6\x10\x03\x4C\x65\xD6\x4C\xF2\xD4" 404 | "\xA9\x50\xA0\x00\x85\x3C\x84\x3D\xA9\x52\x85\x3E\x84\x3F\x84\xD6" 405 | "\x60\xA5\x67\xA4\x68\x85\x3C\x84\x3D\xA5\x69\xA4\x6A\x85\x3E\x84" 406 | "\x3F\x60\x08\xC6\x76\x28\xD0\x03\x4C\x65\xD6\x20\x6C\xD6\x4C\x35" 407 | "\xD9\xA9\x03\x20\xD6\xD3\xA5\xB9\x48\xA5\xB8\x48\xA5\x76\x48\xA5" 408 | "\x75\x48\xA9\xB0\x48\x20\xB7\x00\x20\x3E\xD9\x4C\xD2\xD7\x20\x0C" 409 | "\xDA\x20\xA6\xD9\xA5\x76\xC5\x51\xB0\x0B\x98\x38\x65\xB8\xA6\xB9" 410 | "\x90\x07\xE8\xB0\x04\xA5\x67\xA6\x68\x20\x1E\xD6\x90\x1E\xA5\x9B" 411 | "\xE9\x01\x85\xB8\xA5\x9C\xE9\x00\x85\xB9\x60\xD0\xFD\xA9\xFF\x85" 412 | "\x85\x20\x65\xD3\x9A\xC9\xB0\xF0\x0B\xA2\x16\x2C\xA2\x5A\x4C\x12" 413 | "\xD4\x4C\xC9\xDE\x68\x68\xC0\x42\xF0\x3B\x85\x75\x68\x85\x76\x68" 414 | "\x85\xB8\x68\x85\xB9\x20\xA3\xD9\x98\x18\x65\xB8\x85\xB8\x90\x02" 415 | "\xE6\xB9\x60\xA2\x3A\x2C\xA2\x00\x86\x0D\xA0\x00\x84\x0E\xA5\x0E" 416 | "\xA6\x0D\x85\x0D\x86\x0E\xB1\xB8\xF0\xE8\xC5\x0E\xF0\xE4\xC8\xC9" 417 | "\x22\xD0\xF3\xF0\xE9\x68\x68\x68\x60\x20\x7B\xDD\x20\xB7\x00\xC9" 418 | "\xAB\xF0\x05\xA9\xC4\x20\xC0\xDE\xA5\x9D\xD0\x05\x20\xA6\xD9\xF0" 419 | "\xB7\x20\xB7\x00\xB0\x03\x4C\x3E\xD9\x4C\x28\xD8\x20\xF8\xE6\x48" 420 | "\xC9\xB0\xF0\x04\xC9\xAB\xD0\x89\xC6\xA1\xD0\x04\x68\x4C\x2A\xD8" 421 | "\x20\xB1\x00\x20\x0C\xDA\xC9\x2C\xF0\xEE\x68\x60\xA2\x00\x86\x50" 422 | "\x86\x51\xB0\xF7\xE9\x2F\x85\x0D\xA5\x51\x85\x5E\xC9\x19\xB0\xD4" 423 | "\xA5\x50\x0A\x26\x5E\x0A\x26\x5E\x65\x50\x85\x50\xA5\x5E\x65\x51" 424 | "\x85\x51\x06\x50\x26\x51\xA5\x50\x65\x0D\x85\x50\x90\x02\xE6\x51" 425 | "\x20\xB1\x00\x4C\x12\xDA\x20\xE3\xDF\x85\x85\x84\x86\xA9\xD0\x20" 426 | "\xC0\xDE\xA5\x12\x48\xA5\x11\x48\x20\x7B\xDD\x68\x2A\x20\x6D\xDD" 427 | "\xD0\x18\x68\x10\x12\x20\x72\xEB\x20\x0C\xE1\xA0\x00\xA5\xA0\x91" 428 | "\x85\xC8\xA5\xA1\x91\x85\x60\x4C\x27\xEB\x68\xA0\x02\xB1\xA0\xC5" 429 | "\x70\x90\x17\xD0\x07\x88\xB1\xA0\xC5\x6F\x90\x0E\xA4\xA1\xC4\x6A" 430 | "\x90\x08\xD0\x0D\xA5\xA0\xC5\x69\xB0\x07\xA5\xA0\xA4\xA1\x4C\xB7" 431 | "\xDA\xA0\x00\xB1\xA0\x20\xD5\xE3\xA5\x8C\xA4\x8D\x85\xAB\x84\xAC" 432 | "\x20\xD4\xE5\xA9\x9D\xA0\x00\x85\x8C\x84\x8D\x20\x35\xE6\xA0\x00" 433 | "\xB1\x8C\x91\x85\xC8\xB1\x8C\x91\x85\xC8\xB1\x8C\x91\x85\x60\x20" 434 | "\x3D\xDB\x20\xB7\x00\xF0\x24\xF0\x29\xC9\xC0\xF0\x3C\xC9\xC3\x18" 435 | "\xF0\x37\xC9\x2C\x18\xF0\x1C\xC9\x3B\xF0\x44\x20\x7B\xDD\x24\x11" 436 | "\x30\xDD\x20\x34\xED\x20\xE7\xE3\x4C\xCF\xDA\xA9\x0D\x20\x5C\xDB" 437 | "\x49\xFF\x60\x20\xB4\xF7\x30\x09\xC9\x18\x90\x05\x20\xFB\xDA\xD0" 438 | "\x1E\x69\x10\x29\xF0\xAA\x38\xB0\x0C\x08\x20\xF5\xE6\xC9\x29\xD0" 439 | "\x62\x28\x90\x07\xCA\x20\xC3\xF7\x90\x05\xAA\xE8\xCA\xD0\x06\x20" 440 | "\xB1\x00\x4C\xD7\xDA\x20\x57\xDB\xD0\xF2\x20\xE7\xE3\x20\x00\xE6" 441 | "\xAA\xA0\x00\xE8\xCA\xF0\xBB\xB1\x5E\x20\x5C\xDB\xC8\xC9\x0D\xD0" 442 | "\xF3\x20\x00\xDB\x4C\x44\xDB\xA9\x20\x2C\xA9\x3F\x09\x80\xC9\xA0" 443 | "\x90\x02\x05\xF3\x20\xED\xFD\x29\x7F\x48\xA5\xF1\x20\xA8\xFC\x68" 444 | "\x60\xA5\x15\xF0\x12\x30\x04\xA0\xFF\xD0\x04\xA5\x7B\xA4\x7C\x85" 445 | "\x75\x84\x76\x4C\xC9\xDE\x68\x24\xD8\x10\x05\xA2\xFE\x4C\xE9\xF2" 446 | "\xA9\xEF\xA0\xDC\x20\x3A\xDB\xA5\x79\xA4\x7A\x85\xB8\x84\xB9\x60" 447 | "\x20\x06\xE3\xA2\x01\xA0\x02\xA9\x00\x8D\x01\x02\xA9\x40\x20\xEB" 448 | "\xDB\x60\xC9\x22\xD0\x0E\x20\x81\xDE\xA9\x3B\x20\xC0\xDE\x20\x3D" 449 | "\xDB\x4C\xC7\xDB\x20\x5A\xDB\x20\x06\xE3\xA9\x2C\x8D\xFF\x01\x20" 450 | "\x2C\xD5\xAD\x00\x02\xC9\x03\xD0\x10\x4C\x63\xD8\x20\x5A\xDB\x4C" 451 | "\x2C\xD5\xA6\x7D\xA4\x7E\xA9\x98\x2C\xA9\x00\x85\x15\x86\x7F\x84" 452 | "\x80\x20\xE3\xDF\x85\x85\x84\x86\xA5\xB8\xA4\xB9\x85\x87\x84\x88" 453 | "\xA6\x7F\xA4\x80\x86\xB8\x84\xB9\x20\xB7\x00\xD0\x1E\x24\x15\x50" 454 | "\x0E\x20\x0C\xFD\x29\x7F\x8D\x00\x02\xA2\xFF\xA0\x01\xD0\x08\x30" 455 | "\x7F\x20\x5A\xDB\x20\xDC\xDB\x86\xB8\x84\xB9\x20\xB1\x00\x24\x11" 456 | "\x10\x31\x24\x15\x50\x09\xE8\x86\xB8\xA9\x00\x85\x0D\xF0\x0C\x85" 457 | "\x0D\xC9\x22\xF0\x07\xA9\x3A\x85\x0D\xA9\x2C\x18\x85\x0E\xA5\xB8" 458 | "\xA4\xB9\x69\x00\x90\x01\xC8\x20\xED\xE3\x20\x3D\xE7\x20\x7B\xDA" 459 | "\x4C\x72\xDC\x48\xAD\x00\x02\xF0\x30\x68\x20\x4A\xEC\xA5\x12\x20" 460 | "\x63\xDA\x20\xB7\x00\xF0\x07\xC9\x2C\xF0\x03\x4C\x71\xDB\xA5\xB8" 461 | "\xA4\xB9\x85\x7F\x84\x80\xA5\x87\xA4\x88\x85\xB8\x84\xB9\x20\xB7" 462 | "\x00\xF0\x33\x20\xBE\xDE\x4C\xF1\xDB\xA5\x15\xD0\xCC\x4C\x86\xDB" 463 | "\x20\xA3\xD9\xC8\xAA\xD0\x12\xA2\x2A\xC8\xB1\xB8\xF0\x5F\xC8\xB1" 464 | "\xB8\x85\x7B\xC8\xB1\xB8\xC8\x85\x7C\xB1\xB8\xAA\x20\x98\xD9\xE0" 465 | "\x83\xD0\xDD\x4C\x2B\xDC\xA5\x7F\xA4\x80\xA6\x15\x10\x03\x4C\x53" 466 | "\xD8\xA0\x00\xB1\x7F\xF0\x07\xA9\xDF\xA0\xDC\x4C\x3A\xDB\x60\x3F" 467 | "\x45\x58\x54\x52\x41\x20\x49\x47\x4E\x4F\x52\x45\x44\x0D\x00\x3F" 468 | "\x52\x45\x45\x4E\x54\x45\x52\x0D\x00\xD0\x04\xA0\x00\xF0\x03\x20" 469 | "\xE3\xDF\x85\x85\x84\x86\x20\x65\xD3\xF0\x04\xA2\x00\xF0\x69\x9A" 470 | "\xE8\xE8\xE8\xE8\x8A\xE8\xE8\xE8\xE8\xE8\xE8\x86\x60\xA0\x01\x20" 471 | "\xF9\xEA\xBA\xBD\x09\x01\x85\xA2\xA5\x85\xA4\x86\x20\xBE\xE7\x20" 472 | "\x27\xEB\xA0\x01\x20\xB4\xEB\xBA\x38\xFD\x09\x01\xF0\x17\xBD\x0F" 473 | "\x01\x85\x75\xBD\x10\x01\x85\x76\xBD\x12\x01\x85\xB8\xBD\x11\x01" 474 | "\x85\xB9\x4C\xD2\xD7\x8A\x69\x11\xAA\x9A\x20\xB7\x00\xC9\x2C\xD0" 475 | "\xF1\x20\xB1\x00\x20\xFF\xDC\x20\x7B\xDD\x18\x24\x38\x24\x11\x30" 476 | "\x03\xB0\x03\x60\xB0\xFD\xA2\xA3\x4C\x12\xD4\xA6\xB8\xD0\x02\xC6" 477 | "\xB9\xC6\xB8\xA2\x00\x24\x48\x8A\x48\xA9\x01\x20\xD6\xD3\x20\x60" 478 | "\xDE\xA9\x00\x85\x89\x20\xB7\x00\x38\xE9\xCF\x90\x17\xC9\x03\xB0" 479 | "\x13\xC9\x01\x2A\x49\x01\x45\x89\xC5\x89\x90\x61\x85\x89\x20\xB1" 480 | "\x00\x4C\x98\xDD\xA6\x89\xD0\x2C\xB0\x7B\x69\x07\x90\x77\x65\x11" 481 | "\xD0\x03\x4C\x97\xE5\x69\xFF\x85\x5E\x0A\x65\x5E\xA8\x68\xD9\xB2" 482 | "\xD0\xB0\x67\x20\x6A\xDD\x48\x20\xFD\xDD\x68\xA4\x87\x10\x17\xAA" 483 | "\xF0\x56\xD0\x5F\x46\x11\x8A\x2A\xA6\xB8\xD0\x02\xC6\xB9\xC6\xB8" 484 | "\xA0\x1B\x85\x89\xD0\xD7\xD9\xB2\xD0\xB0\x48\x90\xD9\xB9\xB4\xD0" 485 | "\x48\xB9\xB3\xD0\x48\x20\x10\xDE\xA5\x89\x4C\x86\xDD\x4C\xC9\xDE" 486 | "\xA5\xA2\xBE\xB2\xD0\xA8\x68\x85\x5E\xE6\x5E\x68\x85\x5F\x98\x48" 487 | "\x20\x72\xEB\xA5\xA1\x48\xA5\xA0\x48\xA5\x9F\x48\xA5\x9E\x48\xA5" 488 | "\x9D\x48\x6C\x5E\x00\xA0\xFF\x68\xF0\x23\xC9\x64\xF0\x03\x20\x6A" 489 | "\xDD\x84\x87\x68\x4A\x85\x16\x68\x85\xA5\x68\x85\xA6\x68\x85\xA7" 490 | "\x68\x85\xA8\x68\x85\xA9\x68\x85\xAA\x45\xA2\x85\xAB\xA5\x9D\x60" 491 | "\xA9\x00\x85\x11\x20\xB1\x00\xB0\x03\x4C\x4A\xEC\x20\x7D\xE0\xB0" 492 | "\x64\xC9\x2E\xF0\xF4\xC9\xC9\xF0\x55\xC9\xC8\xF0\xE7\xC9\x22\xD0" 493 | "\x0F\xA5\xB8\xA4\xB9\x69\x00\x90\x01\xC8\x20\xE7\xE3\x4C\x3D\xE7" 494 | "\xC9\xC6\xD0\x10\xA0\x18\xD0\x38\xA5\x9D\xD0\x03\xA0\x01\x2C\xA0" 495 | "\x00\x4C\x01\xE3\xC9\xC2\xD0\x03\x4C\x54\xE3\xC9\xD2\x90\x03\x4C" 496 | "\x0C\xDF\x20\xBB\xDE\x20\x7B\xDD\xA9\x29\x2C\xA9\x28\x2C\xA9\x2C" 497 | "\xA0\x00\xD1\xB8\xD0\x03\x4C\xB1\x00\xA2\x10\x4C\x12\xD4\xA0\x15" 498 | "\x68\x68\x4C\xD7\xDD\x20\xE3\xDF\x85\xA0\x84\xA1\xA6\x11\xF0\x05" 499 | "\xA2\x00\x86\xAC\x60\xA6\x12\x10\x0D\xA0\x00\xB1\xA0\xAA\xC8\xB1" 500 | "\xA0\xA8\x8A\x4C\xF2\xE2\x4C\xF9\xEA\x20\xB1\x00\x20\xEC\xF1\x8A" 501 | "\xA4\xF0\x20\x71\xF8\xA8\x20\x01\xE3\x4C\xB8\xDE\xC9\xD7\xF0\xE9" 502 | "\x0A\x48\xAA\x20\xB1\x00\xE0\xCF\x90\x20\x20\xBB\xDE\x20\x7B\xDD" 503 | "\x20\xBE\xDE\x20\x6C\xDD\x68\xAA\xA5\xA1\x48\xA5\xA0\x48\x8A\x48" 504 | "\x20\xF8\xE6\x68\xA8\x8A\x48\x4C\x3F\xDF\x20\xB2\xDE\x68\xA8\xB9" 505 | "\xDC\xCF\x85\x91\xB9\xDD\xCF\x85\x92\x20\x90\x00\x4C\x6A\xDD\xA5" 506 | "\xA5\x05\x9D\xD0\x0B\xA5\xA5\xF0\x04\xA5\x9D\xD0\x03\xA0\x00\x2C" 507 | "\xA0\x01\x4C\x01\xE3\x20\x6D\xDD\xB0\x13\xA5\xAA\x09\x7F\x25\xA6" 508 | "\x85\xA6\xA9\xA5\xA0\x00\x20\xB2\xEB\xAA\x4C\xB0\xDF\xA9\x00\x85" 509 | "\x11\xC6\x89\x20\x00\xE6\x85\x9D\x86\x9E\x84\x9F\xA5\xA8\xA4\xA9" 510 | "\x20\x04\xE6\x86\xA8\x84\xA9\xAA\x38\xE5\x9D\xF0\x08\xA9\x01\x90" 511 | "\x04\xA6\x9D\xA9\xFF\x85\xA2\xA0\xFF\xE8\xC8\xCA\xD0\x07\xA6\xA2" 512 | "\x30\x0F\x18\x90\x0C\xB1\xA8\xD1\x9E\xF0\xEF\xA2\xFF\xB0\x02\xA2" 513 | "\x01\xE8\x8A\x2A\x25\x16\xF0\x02\xA9\x01\x4C\x93\xEB\x20\xFB\xE6" 514 | "\x20\x1E\xFB\x4C\x01\xE3\x20\xBE\xDE\xAA\x20\xE8\xDF\x20\xB7\x00" 515 | "\xD0\xF4\x60\xA2\x00\x20\xB7\x00\x86\x10\x85\x81\x20\xB7\x00\x20" 516 | "\x7D\xE0\xB0\x03\x4C\xC9\xDE\xA2\x00\x86\x11\x86\x12\x4C\x07\xE0" 517 | "\x4C\x28\xF1\x4C\x3C\xD4\xC4\x20\xB1\x00\x90\x05\x20\x7D\xE0\x90" 518 | "\x0B\xAA\x20\xB1\x00\x90\xFB\x20\x7D\xE0\xB0\xF6\xC9\x24\xD0\x06" 519 | "\xA9\xFF\x85\x11\xD0\x10\xC9\x25\xD0\x13\xA5\x14\x30\xC6\xA9\x80" 520 | "\x85\x12\x05\x81\x85\x81\x8A\x09\x80\xAA\x20\xB1\x00\x86\x82\x38" 521 | "\x05\x14\xE9\x28\xD0\x03\x4C\x1E\xE1\x24\x14\x30\x02\x70\xF7\xA9" 522 | "\x00\x85\x14\xA5\x69\xA6\x6A\xA0\x00\x86\x9C\x85\x9B\xE4\x6C\xD0" 523 | "\x04\xC5\x6B\xF0\x22\xA5\x81\xD1\x9B\xD0\x08\xA5\x82\xC8\xD1\x9B" 524 | "\xF0\x6C\x88\x18\xA5\x9B\x69\x07\x90\xE1\xE8\xD0\xDC\xC9\x41\x90" 525 | "\x05\xE9\x5B\x38\xE9\xA5\x60\x68\x48\xC9\xD7\xD0\x0F\xBA\xBD\x02" 526 | "\x01\xC9\xDE\xD0\x07\xA9\x9A\xA0\xE0\x60\x00\x00\xA5\x6B\xA4\x6C" 527 | "\x85\x9B\x84\x9C\xA5\x6D\xA4\x6E\x85\x96\x84\x97\x18\x69\x07\x90" 528 | "\x01\xC8\x85\x94\x84\x95\x20\x93\xD3\xA5\x94\xA4\x95\xC8\x85\x6B" 529 | "\x84\x6C\xA0\x00\xA5\x81\x91\x9B\xC8\xA5\x82\x91\x9B\xA9\x00\xC8" 530 | "\x91\x9B\xC8\x91\x9B\xC8\x91\x9B\xC8\x91\x9B\xC8\x91\x9B\xA5\x9B" 531 | "\x18\x69\x02\xA4\x9C\x90\x01\xC8\x85\x83\x84\x84\x60\xA5\x0F\x0A" 532 | "\x69\x05\x65\x9B\xA4\x9C\x90\x01\xC8\x85\x94\x84\x95\x60\x90\x80" 533 | "\x00\x00\x20\xB1\x00\x20\x67\xDD\xA5\xA2\x30\x0D\xA5\x9D\xC9\x90" 534 | "\x90\x09\xA9\xFE\xA0\xE0\x20\xB2\xEB\xD0\x7E\x4C\xF2\xEB\xA5\x14" 535 | "\xD0\x47\xA5\x10\x05\x12\x48\xA5\x11\x48\xA0\x00\x98\x48\xA5\x82" 536 | "\x48\xA5\x81\x48\x20\x02\xE1\x68\x85\x81\x68\x85\x82\x68\xA8\xBA" 537 | "\xBD\x02\x01\x48\xBD\x01\x01\x48\xA5\xA0\x9D\x02\x01\xA5\xA1\x9D" 538 | "\x01\x01\xC8\x20\xB7\x00\xC9\x2C\xF0\xD2\x84\x0F\x20\xB8\xDE\x68" 539 | "\x85\x11\x68\x85\x12\x29\x7F\x85\x10\xA6\x6B\xA5\x6C\x86\x9B\x85" 540 | "\x9C\xC5\x6E\xD0\x04\xE4\x6D\xF0\x3F\xA0\x00\xB1\x9B\xC8\xC5\x81" 541 | "\xD0\x06\xA5\x82\xD1\x9B\xF0\x16\xC8\xB1\x9B\x18\x65\x9B\xAA\xC8" 542 | "\xB1\x9B\x65\x9C\x90\xD7\xA2\x6B\x2C\xA2\x35\x4C\x12\xD4\xA2\x78" 543 | "\xA5\x10\xD0\xF7\xA5\x14\xF0\x02\x38\x60\x20\xED\xE0\xA5\x0F\xA0" 544 | "\x04\xD1\x9B\xD0\xE1\x4C\x4B\xE2\xA5\x14\xF0\x05\xA2\x2A\x4C\x12" 545 | "\xD4\x20\xED\xE0\x20\xE3\xD3\xA9\x00\xA8\x85\xAE\xA2\x05\xA5\x81" 546 | "\x91\x9B\x10\x01\xCA\xC8\xA5\x82\x91\x9B\x10\x02\xCA\xCA\x86\xAD" 547 | "\xA5\x0F\xC8\xC8\xC8\x91\x9B\xA2\x0B\xA9\x00\x24\x10\x50\x08\x68" 548 | "\x18\x69\x01\xAA\x68\x69\x00\xC8\x91\x9B\xC8\x8A\x91\x9B\x20\xAD" 549 | "\xE2\x86\xAD\x85\xAE\xA4\x5E\xC6\x0F\xD0\xDC\x65\x95\xB0\x5D\x85" 550 | "\x95\xA8\x8A\x65\x94\x90\x03\xC8\xF0\x52\x20\xE3\xD3\x85\x6D\x84" 551 | "\x6E\xA9\x00\xE6\xAE\xA4\xAD\xF0\x05\x88\x91\x94\xD0\xFB\xC6\x95" 552 | "\xC6\xAE\xD0\xF5\xE6\x95\x38\xA5\x6D\xE5\x9B\xA0\x02\x91\x9B\xA5" 553 | "\x6E\xC8\xE5\x9C\x91\x9B\xA5\x10\xD0\x62\xC8\xB1\x9B\x85\x0F\xA9" 554 | "\x00\x85\xAD\x85\xAE\xC8\x68\xAA\x85\xA0\x68\x85\xA1\xD1\x9B\x90" 555 | "\x0E\xD0\x06\xC8\x8A\xD1\x9B\x90\x07\x4C\x96\xE1\x4C\x10\xD4\xC8" 556 | "\xA5\xAE\x05\xAD\x18\xF0\x0A\x20\xAD\xE2\x8A\x65\xA0\xAA\x98\xA4" 557 | "\x5E\x65\xA1\x86\xAD\xC6\x0F\xD0\xCA\x85\xAE\xA2\x05\xA5\x81\x10" 558 | "\x01\xCA\xA5\x82\x10\x02\xCA\xCA\x86\x64\xA9\x00\x20\xB6\xE2\x8A" 559 | "\x65\x94\x85\x83\x98\x65\x95\x85\x84\xA8\xA5\x83\x60\x84\x5E\xB1" 560 | "\x9B\x85\x64\x88\xB1\x9B\x85\x65\xA9\x10\x85\x99\xA2\x00\xA0\x00" 561 | "\x8A\x0A\xAA\x98\x2A\xA8\xB0\xA4\x06\xAD\x26\xAE\x90\x0B\x18\x8A" 562 | "\x65\x64\xAA\x98\x65\x65\xA8\xB0\x93\xC6\x99\xD0\xE3\x60\xA5\x11" 563 | "\xF0\x03\x20\x00\xE6\x20\x84\xE4\x38\xA5\x6F\xE5\x6D\xA8\xA5\x70" 564 | "\xE5\x6E\xA2\x00\x86\x11\x85\x9E\x84\x9F\xA2\x90\x4C\x9B\xEB\xA4" 565 | "\x24\xA9\x00\x38\xF0\xEC\xA6\x76\xE8\xD0\xA1\xA2\x95\x2C\xA2\xE0" 566 | "\x4C\x12\xD4\x20\x41\xE3\x20\x06\xE3\x20\xBB\xDE\xA9\x80\x85\x14" 567 | "\x20\xE3\xDF\x20\x6A\xDD\x20\xB8\xDE\xA9\xD0\x20\xC0\xDE\x48\xA5" 568 | "\x84\x48\xA5\x83\x48\xA5\xB9\x48\xA5\xB8\x48\x20\x95\xD9\x4C\xAF" 569 | "\xE3\xA9\xC2\x20\xC0\xDE\x09\x80\x85\x14\x20\xEA\xDF\x85\x8A\x84" 570 | "\x8B\x4C\x6A\xDD\x20\x41\xE3\xA5\x8B\x48\xA5\x8A\x48\x20\xB2\xDE" 571 | "\x20\x6A\xDD\x68\x85\x8A\x68\x85\x8B\xA0\x02\xB1\x8A\x85\x83\xAA" 572 | "\xC8\xB1\x8A\xF0\x99\x85\x84\xC8\xB1\x83\x48\x88\x10\xFA\xA4\x84" 573 | "\x20\x2B\xEB\xA5\xB9\x48\xA5\xB8\x48\xB1\x8A\x85\xB8\xC8\xB1\x8A" 574 | "\x85\xB9\xA5\x84\x48\xA5\x83\x48\x20\x67\xDD\x68\x85\x8A\x68\x85" 575 | "\x8B\x20\xB7\x00\xF0\x03\x4C\xC9\xDE\x68\x85\xB8\x68\x85\xB9\xA0" 576 | "\x00\x68\x91\x8A\x68\xC8\x91\x8A\x68\xC8\x91\x8A\x68\xC8\x91\x8A" 577 | "\x68\xC8\x91\x8A\x60\x20\x6A\xDD\xA0\x00\x20\x36\xED\x68\x68\xA9" 578 | "\xFF\xA0\x00\xF0\x12\xA6\xA0\xA4\xA1\x86\x8C\x84\x8D\x20\x52\xE4" 579 | "\x86\x9E\x84\x9F\x85\x9D\x60\xA2\x22\x86\x0D\x86\x0E\x85\xAB\x84" 580 | "\xAC\x85\x9E\x84\x9F\xA0\xFF\xC8\xB1\xAB\xF0\x0C\xC5\x0D\xF0\x04" 581 | "\xC5\x0E\xD0\xF3\xC9\x22\xF0\x01\x18\x84\x9D\x98\x65\xAB\x85\xAD" 582 | "\xA6\xAC\x90\x01\xE8\x86\xAE\xA5\xAC\xF0\x04\xC9\x02\xD0\x0B\x98" 583 | "\x20\xD5\xE3\xA6\xAB\xA4\xAC\x20\xE2\xE5\xA6\x52\xE0\x5E\xD0\x05" 584 | "\xA2\xBF\x4C\x12\xD4\xA5\x9D\x95\x00\xA5\x9E\x95\x01\xA5\x9F\x95" 585 | "\x02\xA0\x00\x86\xA0\x84\xA1\x88\x84\x11\x86\x53\xE8\xE8\xE8\x86" 586 | "\x52\x60\x46\x13\x48\x49\xFF\x38\x65\x6F\xA4\x70\xB0\x01\x88\xC4" 587 | "\x6E\x90\x11\xD0\x04\xC5\x6D\x90\x0B\x85\x6F\x84\x70\x85\x71\x84" 588 | "\x72\xAA\x68\x60\xA2\x4D\xA5\x13\x30\xB8\x20\x84\xE4\xA9\x80\x85" 589 | "\x13\x68\xD0\xD0\xA6\x73\xA5\x74\x86\x6F\x85\x70\xA0\x00\x84\x8B" 590 | "\xA5\x6D\xA6\x6E\x85\x9B\x86\x9C\xA9\x55\xA2\x00\x85\x5E\x86\x5F" 591 | "\xC5\x52\xF0\x05\x20\x23\xE5\xF0\xF7\xA9\x07\x85\x8F\xA5\x69\xA6" 592 | "\x6A\x85\x5E\x86\x5F\xE4\x6C\xD0\x04\xC5\x6B\xF0\x05\x20\x19\xE5" 593 | "\xF0\xF3\x85\x94\x86\x95\xA9\x03\x85\x8F\xA5\x94\xA6\x95\xE4\x6E" 594 | "\xD0\x07\xC5\x6D\xD0\x03\x4C\x62\xE5\x85\x5E\x86\x5F\xA0\x00\xB1" 595 | "\x5E\xAA\xC8\xB1\x5E\x08\xC8\xB1\x5E\x65\x94\x85\x94\xC8\xB1\x5E" 596 | "\x65\x95\x85\x95\x28\x10\xD3\x8A\x30\xD0\xC8\xB1\x5E\xA0\x00\x0A" 597 | "\x69\x05\x65\x5E\x85\x5E\x90\x02\xE6\x5F\xA6\x5F\xE4\x95\xD0\x04" 598 | "\xC5\x94\xF0\xBA\x20\x23\xE5\xF0\xF3\xB1\x5E\x30\x35\xC8\xB1\x5E" 599 | "\x10\x30\xC8\xB1\x5E\xF0\x2B\xC8\xB1\x5E\xAA\xC8\xB1\x5E\xC5\x70" 600 | "\x90\x06\xD0\x1E\xE4\x6F\xB0\x1A\xC5\x9C\x90\x16\xD0\x04\xE4\x9B" 601 | "\x90\x10\x86\x9B\x85\x9C\xA5\x5E\xA6\x5F\x85\x8A\x86\x8B\xA5\x8F" 602 | "\x85\x91\xA5\x8F\x18\x65\x5E\x85\x5E\x90\x02\xE6\x5F\xA6\x5F\xA0" 603 | "\x00\x60\xA6\x8B\xF0\xF7\xA5\x91\x29\x04\x4A\xA8\x85\x91\xB1\x8A" 604 | "\x65\x9B\x85\x96\xA5\x9C\x69\x00\x85\x97\xA5\x6F\xA6\x70\x85\x94" 605 | "\x86\x95\x20\x9A\xD3\xA4\x91\xC8\xA5\x94\x91\x8A\xAA\xE6\x95\xA5" 606 | "\x95\xC8\x91\x8A\x4C\x88\xE4\xA5\xA1\x48\xA5\xA0\x48\x20\x60\xDE" 607 | "\x20\x6C\xDD\x68\x85\xAB\x68\x85\xAC\xA0\x00\xB1\xAB\x18\x71\xA0" 608 | "\x90\x05\xA2\xB0\x4C\x12\xD4\x20\xD5\xE3\x20\xD4\xE5\xA5\x8C\xA4" 609 | "\x8D\x20\x04\xE6\x20\xE6\xE5\xA5\xAB\xA4\xAC\x20\x04\xE6\x20\x2A" 610 | "\xE4\x4C\x95\xDD\xA0\x00\xB1\xAB\x48\xC8\xB1\xAB\xAA\xC8\xB1\xAB" 611 | "\xA8\x68\x86\x5E\x84\x5F\xA8\xF0\x0A\x48\x88\xB1\x5E\x91\x71\x98" 612 | "\xD0\xF8\x68\x18\x65\x71\x85\x71\x90\x02\xE6\x72\x60\x20\x6C\xDD" 613 | "\xA5\xA0\xA4\xA1\x85\x5E\x84\x5F\x20\x35\xE6\x08\xA0\x00\xB1\x5E" 614 | "\x48\xC8\xB1\x5E\xAA\xC8\xB1\x5E\xA8\x68\x28\xD0\x13\xC4\x70\xD0" 615 | "\x0F\xE4\x6F\xD0\x0B\x48\x18\x65\x6F\x85\x6F\x90\x02\xE6\x70\x68" 616 | "\x86\x5E\x84\x5F\x60\xC4\x54\xD0\x0C\xC5\x53\xD0\x08\x85\x52\xE9" 617 | "\x03\x85\x53\xA0\x00\x60\x20\xFB\xE6\x8A\x48\xA9\x01\x20\xDD\xE3" 618 | "\x68\xA0\x00\x91\x9E\x68\x68\x4C\x2A\xE4\x20\xB9\xE6\xD1\x8C\x98" 619 | "\x90\x04\xB1\x8C\xAA\x98\x48\x8A\x48\x20\xDD\xE3\xA5\x8C\xA4\x8D" 620 | "\x20\x04\xE6\x68\xA8\x68\x18\x65\x5E\x85\x5E\x90\x02\xE6\x5F\x98" 621 | "\x20\xE6\xE5\x4C\x2A\xE4\x20\xB9\xE6\x18\xF1\x8C\x49\xFF\x4C\x60" 622 | "\xE6\xA9\xFF\x85\xA1\x20\xB7\x00\xC9\x29\xF0\x06\x20\xBE\xDE\x20" 623 | "\xF8\xE6\x20\xB9\xE6\xCA\x8A\x48\x18\xA2\x00\xF1\x8C\xB0\xB8\x49" 624 | "\xFF\xC5\xA1\x90\xB3\xA5\xA1\xB0\xAF\x20\xB8\xDE\x68\xA8\x68\x85" 625 | "\x91\x68\x68\x68\xAA\x68\x85\x8C\x68\x85\x8D\xA5\x91\x48\x98\x48" 626 | "\xA0\x00\x8A\xF0\x1D\x60\x20\xDC\xE6\x4C\x01\xE3\x20\xFD\xE5\xA2" 627 | "\x00\x86\x11\xA8\x60\x20\xDC\xE6\xF0\x08\xA0\x00\xB1\x5E\xA8\x4C" 628 | "\x01\xE3\x4C\x99\xE1\x20\xB1\x00\x20\x67\xDD\x20\x08\xE1\xA6\xA0" 629 | "\xD0\xF0\xA6\xA1\x4C\xB7\x00\x20\xDC\xE6\xD0\x03\x4C\x4E\xE8\xA6" 630 | "\xB8\xA4\xB9\x86\xAD\x84\xAE\xA6\x5E\x86\xB8\x18\x65\x5E\x85\x60" 631 | "\xA6\x5F\x86\xB9\x90\x01\xE8\x86\x61\xA0\x00\xB1\x60\x48\xA9\x00" 632 | "\x91\x60\x20\xB7\x00\x20\x4A\xEC\x68\xA0\x00\x91\x60\xA6\xAD\xA4" 633 | "\xAE\x86\xB8\x84\xB9\x60\x20\x67\xDD\x20\x52\xE7\x20\xBE\xDE\x4C" 634 | "\xF8\xE6\xA5\x9D\xC9\x91\xB0\x9A\x20\xF2\xEB\xA5\xA0\xA4\xA1\x84" 635 | "\x50\x85\x51\x60\xA5\x50\x48\xA5\x51\x48\x20\x52\xE7\xA0\x00\xB1" 636 | "\x50\xA8\x68\x85\x51\x68\x85\x50\x4C\x01\xE3\x20\x46\xE7\x8A\xA0" 637 | "\x00\x91\x50\x60\x20\x46\xE7\x86\x85\xA2\x00\x20\xB7\x00\xF0\x03" 638 | "\x20\x4C\xE7\x86\x86\xA0\x00\xB1\x50\x45\x86\x25\x85\xF0\xF8\x60" 639 | "\xA9\x64\xA0\xEE\x4C\xBE\xE7\x20\xE3\xE9\xA5\xA2\x49\xFF\x85\xA2" 640 | "\x45\xAA\x85\xAB\xA5\x9D\x4C\xC1\xE7\x20\xF0\xE8\x90\x3C\x20\xE3" 641 | "\xE9\xD0\x03\x4C\x53\xEB\xA6\xAC\x86\x92\xA2\xA5\xA5\xA5\xA8\xF0" 642 | "\xCE\x38\xE5\x9D\xF0\x24\x90\x12\x84\x9D\xA4\xAA\x84\xA2\x49\xFF" 643 | "\x69\x00\xA0\x00\x84\x92\xA2\x9D\xD0\x04\xA0\x00\x84\xAC\xC9\xF9" 644 | "\x30\xC7\xA8\xA5\xAC\x56\x01\x20\x07\xE9\x24\xAB\x10\x57\xA0\x9D" 645 | "\xE0\xA5\xF0\x02\xA0\xA5\x38\x49\xFF\x65\x92\x85\xAC\xB9\x04\x00" 646 | "\xF5\x04\x85\xA1\xB9\x03\x00\xF5\x03\x85\xA0\xB9\x02\x00\xF5\x02" 647 | "\x85\x9F\xB9\x01\x00\xF5\x01\x85\x9E\xB0\x03\x20\x9E\xE8\xA0\x00" 648 | "\x98\x18\xA6\x9E\xD0\x4A\xA6\x9F\x86\x9E\xA6\xA0\x86\x9F\xA6\xA1" 649 | "\x86\xA0\xA6\xAC\x86\xA1\x84\xAC\x69\x08\xC9\x20\xD0\xE4\xA9\x00" 650 | "\x85\x9D\x85\xA2\x60\x65\x92\x85\xAC\xA5\xA1\x65\xA9\x85\xA1\xA5" 651 | "\xA0\x65\xA8\x85\xA0\xA5\x9F\x65\xA7\x85\x9F\xA5\x9E\x65\xA6\x85" 652 | "\x9E\x4C\x8D\xE8\x69\x01\x06\xAC\x26\xA1\x26\xA0\x26\x9F\x26\x9E" 653 | "\x10\xF2\x38\xE5\x9D\xB0\xC7\x49\xFF\x69\x01\x85\x9D\x90\x0E\xE6" 654 | "\x9D\xF0\x42\x66\x9E\x66\x9F\x66\xA0\x66\xA1\x66\xAC\x60\xA5\xA2" 655 | "\x49\xFF\x85\xA2\xA5\x9E\x49\xFF\x85\x9E\xA5\x9F\x49\xFF\x85\x9F" 656 | "\xA5\xA0\x49\xFF\x85\xA0\xA5\xA1\x49\xFF\x85\xA1\xA5\xAC\x49\xFF" 657 | "\x85\xAC\xE6\xAC\xD0\x0E\xE6\xA1\xD0\x0A\xE6\xA0\xD0\x06\xE6\x9F" 658 | "\xD0\x02\xE6\x9E\x60\xA2\x45\x4C\x12\xD4\xA2\x61\xB4\x04\x84\xAC" 659 | "\xB4\x03\x94\x04\xB4\x02\x94\x03\xB4\x01\x94\x02\xA4\xA4\x94\x01" 660 | "\x69\x08\x30\xE8\xF0\xE6\xE9\x08\xA8\xA5\xAC\xB0\x14\x16\x01\x90" 661 | "\x02\xF6\x01\x76\x01\x76\x01\x76\x02\x76\x03\x76\x04\x6A\xC8\xD0" 662 | "\xEC\x18\x60\x81\x00\x00\x00\x00\x03\x7F\x5E\x56\xCB\x79\x80\x13" 663 | "\x9B\x0B\x64\x80\x76\x38\x93\x16\x82\x38\xAA\x3B\x20\x80\x35\x04" 664 | "\xF3\x34\x81\x35\x04\xF3\x34\x80\x80\x00\x00\x00\x80\x31\x72\x17" 665 | "\xF8\x20\x82\xEB\xF0\x02\x10\x03\x4C\x99\xE1\xA5\x9D\xE9\x7F\x48" 666 | "\xA9\x80\x85\x9D\xA9\x2D\xA0\xE9\x20\xBE\xE7\xA9\x32\xA0\xE9\x20" 667 | "\x66\xEA\xA9\x13\xA0\xE9\x20\xA7\xE7\xA9\x18\xA0\xE9\x20\x5C\xEF" 668 | "\xA9\x37\xA0\xE9\x20\xBE\xE7\x68\x20\xD5\xEC\xA9\x3C\xA0\xE9\x20" 669 | "\xE3\xE9\xD0\x03\x4C\xE2\xE9\x20\x0E\xEA\xA9\x00\x85\x62\x85\x63" 670 | "\x85\x64\x85\x65\xA5\xAC\x20\xB0\xE9\xA5\xA1\x20\xB0\xE9\xA5\xA0" 671 | "\x20\xB0\xE9\xA5\x9F\x20\xB0\xE9\xA5\x9E\x20\xB5\xE9\x4C\xE6\xEA" 672 | "\xD0\x03\x4C\xDA\xE8\x4A\x09\x80\xA8\x90\x19\x18\xA5\x65\x65\xA9" 673 | "\x85\x65\xA5\x64\x65\xA8\x85\x64\xA5\x63\x65\xA7\x85\x63\xA5\x62" 674 | "\x65\xA6\x85\x62\x66\x62\x66\x63\x66\x64\x66\x65\x66\xAC\x98\x4A" 675 | "\xD0\xD6\x60\x85\x5E\x84\x5F\xA0\x04\xB1\x5E\x85\xA9\x88\xB1\x5E" 676 | "\x85\xA8\x88\xB1\x5E\x85\xA7\x88\xB1\x5E\x85\xAA\x45\xA2\x85\xAB" 677 | "\xA5\xAA\x09\x80\x85\xA6\x88\xB1\x5E\x85\xA5\xA5\x9D\x60\xA5\xA5" 678 | "\xF0\x1F\x18\x65\x9D\x90\x04\x30\x1D\x18\x2C\x10\x14\x69\x80\x85" 679 | "\x9D\xD0\x03\x4C\x52\xE8\xA5\xAB\x85\xA2\x60\xA5\xA2\x49\xFF\x30" 680 | "\x05\x68\x68\x4C\x4E\xE8\x4C\xD5\xE8\x20\x63\xEB\xAA\xF0\x10\x18" 681 | "\x69\x02\xB0\xF2\xA2\x00\x86\xAB\x20\xCE\xE7\xE6\x9D\xF0\xE7\x60" 682 | "\x84\x20\x00\x00\x00\x20\x63\xEB\xA9\x50\xA0\xEA\xA2\x00\x86\xAB" 683 | "\x20\xF9\xEA\x4C\x69\xEA\x20\xE3\xE9\xF0\x76\x20\x72\xEB\xA9\x00" 684 | "\x38\xE5\x9D\x85\x9D\x20\x0E\xEA\xE6\x9D\xF0\xBA\xA2\xFC\xA9\x01" 685 | "\xA4\xA6\xC4\x9E\xD0\x10\xA4\xA7\xC4\x9F\xD0\x0A\xA4\xA8\xC4\xA0" 686 | "\xD0\x04\xA4\xA9\xC4\xA1\x08\x2A\x90\x09\xE8\x95\x65\xF0\x32\x10" 687 | "\x34\xA9\x01\x28\xB0\x0E\x06\xA9\x26\xA8\x26\xA7\x26\xA6\xB0\xE6" 688 | "\x30\xCE\x10\xE2\xA8\xA5\xA9\xE5\xA1\x85\xA9\xA5\xA8\xE5\xA0\x85" 689 | "\xA8\xA5\xA7\xE5\x9F\x85\xA7\xA5\xA6\xE5\x9E\x85\xA6\x98\x4C\xA6" 690 | "\xEA\xA9\x40\xD0\xCE\x0A\x0A\x0A\x0A\x0A\x0A\x85\xAC\x28\x4C\xE6" 691 | "\xEA\xA2\x85\x4C\x12\xD4\xA5\x62\x85\x9E\xA5\x63\x85\x9F\xA5\x64" 692 | "\x85\xA0\xA5\x65\x85\xA1\x4C\x2E\xE8\x85\x5E\x84\x5F\xA0\x04\xB1" 693 | "\x5E\x85\xA1\x88\xB1\x5E\x85\xA0\x88\xB1\x5E\x85\x9F\x88\xB1\x5E" 694 | "\x85\xA2\x09\x80\x85\x9E\x88\xB1\x5E\x85\x9D\x84\xAC\x60\xA2\x98" 695 | "\x2C\xA2\x93\xA0\x00\xF0\x04\xA6\x85\xA4\x86\x20\x72\xEB\x86\x5E" 696 | "\x84\x5F\xA0\x04\xA5\xA1\x91\x5E\x88\xA5\xA0\x91\x5E\x88\xA5\x9F" 697 | "\x91\x5E\x88\xA5\xA2\x09\x7F\x25\x9E\x91\x5E\x88\xA5\x9D\x91\x5E" 698 | "\x84\xAC\x60\xA5\xAA\x85\xA2\xA2\x05\xB5\xA4\x95\x9C\xCA\xD0\xF9" 699 | "\x86\xAC\x60\x20\x72\xEB\xA2\x06\xB5\x9C\x95\xA4\xCA\xD0\xF9\x86" 700 | "\xAC\x60\xA5\x9D\xF0\xFB\x06\xAC\x90\xF7\x20\xC6\xE8\xD0\xF2\x4C" 701 | "\x8F\xE8\xA5\x9D\xF0\x09\xA5\xA2\x2A\xA9\xFF\xB0\x02\xA9\x01\x60" 702 | "\x20\x82\xEB\x85\x9E\xA9\x00\x85\x9F\xA2\x88\xA5\x9E\x49\xFF\x2A" 703 | "\xA9\x00\x85\xA1\x85\xA0\x86\x9D\x85\xAC\x85\xA2\x4C\x29\xE8\x46" 704 | "\xA2\x60\x85\x60\x84\x61\xA0\x00\xB1\x60\xC8\xAA\xF0\xC4\xB1\x60" 705 | "\x45\xA2\x30\xC2\xE4\x9D\xD0\x21\xB1\x60\x09\x80\xC5\x9E\xD0\x19" 706 | "\xC8\xB1\x60\xC5\x9F\xD0\x12\xC8\xB1\x60\xC5\xA0\xD0\x0B\xC8\xA9" 707 | "\x7F\xC5\xAC\xB1\x60\xE5\xA1\xF0\x28\xA5\xA2\x90\x02\x49\xFF\x4C" 708 | "\x88\xEB\xA5\x9D\xF0\x4A\x38\xE9\xA0\x24\xA2\x10\x09\xAA\xA9\xFF" 709 | "\x85\xA4\x20\xA4\xE8\x8A\xA2\x9D\xC9\xF9\x10\x06\x20\xF0\xE8\x84" 710 | "\xA4\x60\xA8\xA5\xA2\x29\x80\x46\x9E\x05\x9E\x85\x9E\x20\x07\xE9" 711 | "\x84\xA4\x60\xA5\x9D\xC9\xA0\xB0\x20\x20\xF2\xEB\x84\xAC\xA5\xA2" 712 | "\x84\xA2\x49\x80\x2A\xA9\xA0\x85\x9D\xA5\xA1\x85\x0D\x4C\x29\xE8" 713 | "\x85\x9E\x85\x9F\x85\xA0\x85\xA1\xA8\x60\xA0\x00\xA2\x0A\x94\x99" 714 | "\xCA\x10\xFB\x90\x0F\xC9\x2D\xD0\x04\x86\xA3\xF0\x04\xC9\x2B\xD0" 715 | "\x05\x20\xB1\x00\x90\x5B\xC9\x2E\xF0\x2E\xC9\x45\xD0\x30\x20\xB1" 716 | "\x00\x90\x17\xC9\xC9\xF0\x0E\xC9\x2D\xF0\x0A\xC9\xC8\xF0\x08\xC9" 717 | "\x2B\xF0\x04\xD0\x07\x66\x9C\x20\xB1\x00\x90\x5C\x24\x9C\x10\x0E" 718 | "\xA9\x00\x38\xE5\x9A\x4C\xA0\xEC\x66\x9B\x24\x9B\x50\xC3\xA5\x9A" 719 | "\x38\xE5\x99\x85\x9A\xF0\x12\x10\x09\x20\x55\xEA\xE6\x9A\xD0\xF9" 720 | "\xF0\x07\x20\x39\xEA\xC6\x9A\xD0\xF9\xA5\xA3\x30\x01\x60\x4C\xD0" 721 | "\xEE\x48\x24\x9B\x10\x02\xE6\x99\x20\x39\xEA\x68\x38\xE9\x30\x20" 722 | "\xD5\xEC\x4C\x61\xEC\x48\x20\x63\xEB\x68\x20\x93\xEB\xA5\xAA\x45" 723 | "\xA2\x85\xAB\xA6\x9D\x4C\xC1\xE7\xA5\x9A\xC9\x0A\x90\x09\xA9\x64" 724 | "\x24\x9C\x30\x11\x4C\xD5\xE8\x0A\x0A\x18\x65\x9A\x0A\x18\xA0\x00" 725 | "\x71\xB8\x38\xE9\x30\x85\x9A\x4C\x87\xEC\x9B\x3E\xBC\x1F\xFD\x9E" 726 | "\x6E\x6B\x27\xFD\x9E\x6E\x6B\x28\x00\xA9\x58\xA0\xD3\x20\x31\xED" 727 | "\xA5\x76\xA6\x75\x85\x9E\x86\x9F\xA2\x90\x38\x20\xA0\xEB\x20\x34" 728 | "\xED\x4C\x3A\xDB\xA0\x01\xA9\x2D\x88\x24\xA2\x10\x04\xC8\x99\xFF" 729 | "\x00\x85\xA2\x84\xAD\xC8\xA9\x30\xA6\x9D\xD0\x03\x4C\x57\xEE\xA9" 730 | "\x00\xE0\x80\xF0\x02\xB0\x09\xA9\x14\xA0\xED\x20\x7F\xE9\xA9\xF7" 731 | "\x85\x99\xA9\x0F\xA0\xED\x20\xB2\xEB\xF0\x1E\x10\x12\xA9\x0A\xA0" 732 | "\xED\x20\xB2\xEB\xF0\x02\x10\x0E\x20\x39\xEA\xC6\x99\xD0\xEE\x20" 733 | "\x55\xEA\xE6\x99\xD0\xDC\x20\xA0\xE7\x20\xF2\xEB\xA2\x01\xA5\x99" 734 | "\x18\x69\x0A\x30\x09\xC9\x0B\xB0\x06\x69\xFF\xAA\xA9\x02\x38\xE9" 735 | "\x02\x85\x9A\x86\x99\x8A\xF0\x02\x10\x13\xA4\xAD\xA9\x2E\xC8\x99" 736 | "\xFF\x00\x8A\xF0\x06\xA9\x30\xC8\x99\xFF\x00\x84\xAD\xA0\x00\xA2" 737 | "\x80\xA5\xA1\x18\x79\x6C\xEE\x85\xA1\xA5\xA0\x79\x6B\xEE\x85\xA0" 738 | "\xA5\x9F\x79\x6A\xEE\x85\x9F\xA5\x9E\x79\x69\xEE\x85\x9E\xE8\xB0" 739 | "\x04\x10\xDE\x30\x02\x30\xDA\x8A\x90\x04\x49\xFF\x69\x0A\x69\x2F" 740 | "\xC8\xC8\xC8\xC8\x84\x83\xA4\xAD\xC8\xAA\x29\x7F\x99\xFF\x00\xC6" 741 | "\x99\xD0\x06\xA9\x2E\xC8\x99\xFF\x00\x84\xAD\xA4\x83\x8A\x49\xFF" 742 | "\x29\x80\xAA\xC0\x24\xD0\xAA\xA4\xAD\xB9\xFF\x00\x88\xC9\x30\xF0" 743 | "\xF8\xC9\x2E\xF0\x01\xC8\xA9\x2B\xA6\x9A\xF0\x2E\x10\x08\xA9\x00" 744 | "\x38\xE5\x9A\xAA\xA9\x2D\x99\x01\x01\xA9\x45\x99\x00\x01\x8A\xA2" 745 | "\x2F\x38\xE8\xE9\x0A\xB0\xFB\x69\x3A\x99\x03\x01\x8A\x99\x02\x01" 746 | "\xA9\x00\x99\x04\x01\xF0\x08\x99\xFF\x00\xA9\x00\x99\x00\x01\xA9" 747 | "\x00\xA0\x01\x60\x80\x00\x00\x00\x00\xFA\x0A\x1F\x00\x00\x98\x96" 748 | "\x80\xFF\xF0\xBD\xC0\x00\x01\x86\xA0\xFF\xFF\xD8\xF0\x00\x00\x03" 749 | "\xE8\xFF\xFF\xFF\x9C\x00\x00\x00\x0A\xFF\xFF\xFF\xFF\x20\x63\xEB" 750 | "\xA9\x64\xA0\xEE\x20\xF9\xEA\xF0\x70\xA5\xA5\xD0\x03\x4C\x50\xE8" 751 | "\xA2\x8A\xA0\x00\x20\x2B\xEB\xA5\xAA\x10\x0F\x20\x23\xEC\xA9\x8A" 752 | "\xA0\x00\x20\xB2\xEB\xD0\x03\x98\xA4\x0D\x20\x55\xEB\x98\x48\x20" 753 | "\x41\xE9\xA9\x8A\xA0\x00\x20\x7F\xE9\x20\x09\xEF\x68\x4A\x90\x0A" 754 | "\xA5\x9D\xF0\x06\xA5\xA2\x49\xFF\x85\xA2\x60\x81\x38\xAA\x3B\x29" 755 | "\x07\x71\x34\x58\x3E\x56\x74\x16\x7E\xB3\x1B\x77\x2F\xEE\xE3\x85" 756 | "\x7A\x1D\x84\x1C\x2A\x7C\x63\x59\x58\x0A\x7E\x75\xFD\xE7\xC6\x80" 757 | "\x31\x72\x18\x10\x81\x00\x00\x00\x00\xA9\xDB\xA0\xEE\x20\x7F\xE9" 758 | "\xA5\xAC\x69\x50\x90\x03\x20\x7A\xEB\x85\x92\x20\x66\xEB\xA5\x9D" 759 | "\xC9\x88\x90\x03\x20\x2B\xEA\x20\x23\xEC\xA5\x0D\x18\x69\x81\xF0" 760 | "\xF3\x38\xE9\x01\x48\xA2\x05\xB5\xA5\xB4\x9D\x95\x9D\x94\xA5\xCA" 761 | "\x10\xF5\xA5\x92\x85\xAC\x20\xAA\xE7\x20\xD0\xEE\xA9\xE0\xA0\xEE" 762 | "\x20\x72\xEF\xA9\x00\x85\xAB\x68\x20\x10\xEA\x60\x85\xAD\x84\xAE" 763 | "\x20\x21\xEB\xA9\x93\x20\x7F\xE9\x20\x76\xEF\xA9\x93\xA0\x00\x4C" 764 | "\x7F\xE9\x85\xAD\x84\xAE\x20\x1E\xEB\xB1\xAD\x85\xA3\xA4\xAD\xC8" 765 | "\x98\xD0\x02\xE6\xAE\x85\xAD\xA4\xAE\x20\x7F\xE9\xA5\xAD\xA4\xAE" 766 | "\x18\x69\x05\x90\x01\xC8\x85\xAD\x84\xAE\x20\xBE\xE7\xA9\x98\xA0" 767 | "\x00\xC6\xA3\xD0\xE4\x60\x98\x35\x44\x7A\x68\x28\xB1\x46\x20\x82" 768 | "\xEB\xAA\x30\x18\xA9\xC9\xA0\x00\x20\xF9\xEA\x8A\xF0\xE7\xA9\xA6" 769 | "\xA0\xEF\x20\x7F\xE9\xA9\xAA\xA0\xEF\x20\xBE\xE7\xA6\xA1\xA5\x9E" 770 | "\x85\xA1\x86\x9E\xA9\x00\x85\xA2\xA5\x9D\x85\xAC\xA9\x80\x85\x9D" 771 | "\x20\x2E\xE8\xA2\xC9\xA0\x00\x4C\x2B\xEB\xA9\x66\xA0\xF0\x20\xBE" 772 | "\xE7\x20\x63\xEB\xA9\x6B\xA0\xF0\xA6\xAA\x20\x5E\xEA\x20\x63\xEB" 773 | "\x20\x23\xEC\xA9\x00\x85\xAB\x20\xAA\xE7\xA9\x70\xA0\xF0\x20\xA7" 774 | "\xE7\xA5\xA2\x48\x10\x0D\x20\xA0\xE7\xA5\xA2\x30\x09\xA5\x16\x49" 775 | "\xFF\x85\x16\x20\xD0\xEE\xA9\x70\xA0\xF0\x20\xBE\xE7\x68\x10\x03" 776 | "\x20\xD0\xEE\xA9\x75\xA0\xF0\x4C\x5C\xEF\x20\x21\xEB\xA9\x00\x85" 777 | "\x16\x20\xF1\xEF\xA2\x8A\xA0\x00\x20\xE7\xEF\xA9\x93\xA0\x00\x20" 778 | "\xF9\xEA\xA9\x00\x85\xA2\xA5\x16\x20\x62\xF0\xA9\x8A\xA0\x00\x4C" 779 | "\x66\xEA\x48\x4C\x23\xF0\x81\x49\x0F\xDA\xA2\x83\x49\x0F\xDA\xA2" 780 | "\x7F\x00\x00\x00\x00\x05\x84\xE6\x1A\x2D\x1B\x86\x28\x07\xFB\xF8" 781 | "\x87\x99\x68\x89\x01\x87\x23\x35\xDF\xE1\x86\xA5\x5D\xE7\x28\x83" 782 | "\x49\x0F\xDA\xA2\xA6\xD3\xC1\xC8\xD4\xC8\xD5\xC4\xCE\xCA\xA5\xA2" 783 | "\x48\x10\x03\x20\xD0\xEE\xA5\x9D\x48\xC9\x81\x90\x07\xA9\x13\xA0" 784 | "\xE9\x20\x66\xEA\xA9\xCE\xA0\xF0\x20\x5C\xEF\x68\xC9\x81\x90\x07" 785 | "\xA9\x66\xA0\xF0\x20\xA7\xE7\x68\x10\x03\x4C\xD0\xEE\x60\x0B\x76" 786 | "\xB3\x83\xBD\xD3\x79\x1E\xF4\xA6\xF5\x7B\x83\xFC\xB0\x10\x7C\x0C" 787 | "\x1F\x67\xCA\x7C\xDE\x53\xCB\xC1\x7D\x14\x64\x70\x4C\x7D\xB7\xEA" 788 | "\x51\x7A\x7D\x63\x30\x88\x7E\x7E\x92\x44\x99\x3A\x7E\x4C\xCC\x91" 789 | "\xC7\x7F\xAA\xAA\xAA\x13\x81\x00\x00\x00\x00\xE6\xB8\xD0\x02\xE6" 790 | "\xB9\xAD\x60\xEA\xC9\x3A\xB0\x0A\xC9\x20\xF0\xEF\x38\xE9\x30\x38" 791 | "\xE9\xD0\x60\x80\x4F\xC7\x52\x58\xA2\xFF\x86\x76\xA2\xFB\x9A\xA9" 792 | "\x28\xA0\xF1\x85\x01\x84\x02\x85\x04\x84\x05\x20\x73\xF2\xA9\x4C" 793 | "\x85\x00\x85\x03\x85\x90\x85\x0A\xA9\x99\xA0\xE1\x85\x0B\x84\x0C" 794 | "\xA2\x1C\xBD\x0A\xF1\x95\xB0\x86\xF1\xCA\xD0\xF6\x86\xF2\x8A\x85" 795 | "\xA4\x85\x54\x48\xA9\x03\x85\x8F\x20\xFB\xDA\xA9\x01\x8D\xFD\x01" 796 | "\x8D\xFC\x01\xA2\x55\x86\x52\xA9\x00\xA0\x08\x85\x50\x84\x51\xA0" 797 | "\x00\xE6\x51\xB1\x50\x49\xFF\x91\x50\xD1\x50\xD0\x08\x49\xFF\x91" 798 | "\x50\xD1\x50\xF0\xEC\xA4\x50\xA5\x51\x29\xF0\x84\x73\x85\x74\x84" 799 | "\x6F\x85\x70\xA2\x00\xA0\x08\x86\x67\x84\x68\xA0\x00\x84\xD6\x98" 800 | "\x91\x67\xE6\x67\xD0\x02\xE6\x68\xA5\x67\xA4\x68\x20\xE3\xD3\x20" 801 | "\x4B\xD6\xA9\x3A\xA0\xDB\x85\x04\x84\x05\xA9\x3C\xA0\xD4\x85\x01" 802 | "\x84\x02\x6C\x01\x00\x20\x67\xDD\x20\x52\xE7\x6C\x50\x00\x20\xF8" 803 | "\xE6\x8A\x4C\x8B\xFE\x20\xF8\xE6\x8A\x4C\x95\xFE\x20\xF8\xE6\xE0" 804 | "\x30\xB0\x13\x86\xF0\xA9\x2C\x20\xC0\xDE\x20\xF8\xE6\xE0\x30\xB0" 805 | "\x05\x86\x2C\x86\x2D\x60\x4C\x99\xE1\x20\xEC\xF1\xE4\xF0\xB0\x08" 806 | "\xA5\xF0\x85\x2C\x85\x2D\x86\xF0\xA9\xC5\x20\xC0\xDE\x20\xF8\xE6" 807 | "\xE0\x30\xB0\xE2\x60\x20\xEC\xF1\x8A\xA4\xF0\xC0\x28\xB0\xD7\x4C" 808 | "\x00\xF8\x20\x09\xF2\x8A\xA4\x2C\xC0\x28\xB0\xCA\xA4\xF0\x4C\x19" 809 | "\xF8\x20\x09\xF2\x8A\xA8\xC0\x28\xB0\xBC\xA5\xF0\x4C\x28\xF8\x20" 810 | "\xF8\xE6\x8A\x4C\x64\xF8\x20\xF8\xE6\xCA\x8A\xC9\x18\xB0\xA7\x4C" 811 | "\x5B\xFB\x20\xF8\xE6\x8A\x49\xFF\xAA\xE8\x86\xF1\x60\x38\x90\x18" 812 | "\x66\xF2\x60\xA9\xFF\xD0\x02\xA9\x3F\xA2\x00\x85\x32\x86\xF3\x60" 813 | "\xA9\x7F\xA2\x40\xD0\xF5\x20\x67\xDD\x20\x52\xE7\xA5\x50\xC5\x6D" 814 | "\xA5\x51\xE5\x6E\xB0\x03\x4C\x10\xD4\xA5\x50\x85\x73\x85\x6F\xA5" 815 | "\x51\x85\x74\x85\x70\x60\x20\x67\xDD\x20\x52\xE7\xA5\x50\xC5\x73" 816 | "\xA5\x51\xE5\x74\xB0\xE0\xA5\x50\xC5\x69\xA5\x51\xE5\x6A\x90\xD6" 817 | "\xA5\x50\x85\x69\xA5\x51\x85\x6A\x4C\x6C\xD6\xA9\xAB\x20\xC0\xDE" 818 | "\xA5\xB8\x85\xF4\xA5\xB9\x85\xF5\x38\x66\xD8\xA5\x75\x85\xF6\xA5" 819 | "\x76\x85\xF7\x20\xA6\xD9\x4C\x98\xD9\x86\xDE\xA6\xF8\x86\xDF\xA5" 820 | "\x75\x85\xDA\xA5\x76\x85\xDB\xA5\x79\x85\xDC\xA5\x7A\x85\xDD\xA5" 821 | "\xF4\x85\xB8\xA5\xF5\x85\xB9\xA5\xF6\x85\x75\xA5\xF7\x85\x76\x20" 822 | "\xB7\x00\x20\x3E\xD9\x4C\xD2\xD7\xA5\xDA\x85\x75\xA5\xDB\x85\x76" 823 | "\xA5\xDC\x85\xB8\xA5\xDD\x85\xB9\xA6\xDF\x9A\x4C\xD2\xD7\x4C\xC9" 824 | "\xDE\xB0\xFB\xA6\xAF\x86\x69\xA6\xB0\x86\x6A\x20\x0C\xDA\x20\x1A" 825 | "\xD6\xA5\x9B\x85\x60\xA5\x9C\x85\x61\xA9\x2C\x20\xC0\xDE\x20\x0C" 826 | "\xDA\xE6\x50\xD0\x02\xE6\x51\x20\x1A\xD6\xA5\x9B\xC5\x60\xA5\x9C" 827 | "\xE5\x61\xB0\x01\x60\xA0\x00\xB1\x9B\x91\x60\xE6\x9B\xD0\x02\xE6" 828 | "\x9C\xE6\x60\xD0\x02\xE6\x61\xA5\x69\xC5\x9B\xA5\x6A\xE5\x9C\xB0" 829 | "\xE6\xA6\x61\xA4\x60\xD0\x01\xCA\x88\x86\x6A\x84\x69\x4C\xF2\xD4" 830 | "\xAD\x56\xC0\xAD\x53\xC0\x4C\x40\xFB\xAD\x54\xC0\x4C\x39\xFB\x20" 831 | "\xD9\xF7\xA0\x03\xB1\x9B\xAA\x88\xB1\x9B\xE9\x01\xB0\x01\xCA\x85" 832 | "\x50\x86\x51\x20\xCD\xFE\x20\x77\xF7\x4C\xCD\xFE\x20\xD9\xF7\x20" 833 | "\xFD\xFE\xA0\x02\xB1\x9B\xC5\x50\xC8\xB1\x9B\xE5\x51\xB0\x03\x4C" 834 | "\x10\xD4\x20\x77\xF7\x4C\xFD\xFE\x2C\x55\xC0\x2C\x52\xC0\xA9\x40" 835 | "\xD0\x08\xA9\x20\x2C\x54\xC0\x2C\x53\xC0\x85\xE6\xAD\x57\xC0\xAD" 836 | "\x50\xC0\xA9\x00\x85\x1C\xA5\xE6\x85\x1B\xA0\x00\x84\x1A\xA5\x1C" 837 | "\x91\x1A\x20\x7E\xF4\xC8\xD0\xF6\xE6\x1B\xA5\x1B\x29\x1F\xD0\xEE" 838 | "\x60\x85\xE2\x86\xE0\x84\xE1\x48\x29\xC0\x85\x26\x4A\x4A\x05\x26" 839 | "\x85\x26\x68\x85\x27\x0A\x0A\x0A\x26\x27\x0A\x26\x27\x0A\x66\x26" 840 | "\xA5\x27\x29\x1F\x05\xE6\x85\x27\x8A\xC0\x00\xF0\x05\xA0\x23\x69" 841 | "\x04\xC8\xE9\x07\xB0\xFB\x84\xE5\xAA\xBD\xB9\xF4\x85\x30\x98\x4A" 842 | "\xA5\xE4\x85\x1C\xB0\x28\x60\x20\x11\xF4\xA5\x1C\x51\x26\x25\x30" 843 | "\x51\x26\x91\x26\x60\x10\x23\xA5\x30\x4A\xB0\x05\x49\xC0\x85\x30" 844 | "\x60\x88\x10\x02\xA0\x27\xA9\xC0\x85\x30\x84\xE5\xA5\x1C\x0A\xC9" 845 | "\xC0\x10\x06\xA5\x1C\x49\x7F\x85\x1C\x60\xA5\x30\x0A\x49\x80\x30" 846 | "\xDD\xA9\x81\xC8\xC0\x28\x90\xE0\xA0\x00\xB0\xDC\x18\xA5\xD1\x29" 847 | "\x04\xF0\x25\xA9\x7F\x25\x30\x31\x26\xD0\x19\xE6\xEA\xA9\x7F\x25" 848 | "\x30\x10\x11\x18\xA5\xD1\x29\x04\xF0\x0E\xB1\x26\x45\x1C\x25\x30" 849 | "\xD0\x02\xE6\xEA\x51\x26\x91\x26\xA5\xD1\x65\xD3\x29\x03\xC9\x02" 850 | "\x6A\xB0\x92\x30\x30\x18\xA5\x27\x2C\xB9\xF5\xD0\x22\x06\x26\xB0" 851 | "\x1A\x2C\xCD\xF4\xF0\x05\x69\x1F\x38\xB0\x12\x69\x23\x48\xA5\x26" 852 | "\x69\xB0\xB0\x02\x69\xF0\x85\x26\x68\xB0\x02\x69\x1F\x66\x26\x69" 853 | "\xFC\x85\x27\x60\x18\xA5\x27\x69\x04\x2C\xB9\xF5\xD0\xF3\x06\x26" 854 | "\x90\x18\x69\xE0\x18\x2C\x08\xF5\xF0\x12\xA5\x26\x69\x50\x49\xF0" 855 | "\xF0\x02\x49\xF0\x85\x26\xA5\xE6\x90\x02\x69\xE0\x66\x26\x90\xD1" 856 | "\x48\xA9\x00\x85\xE0\x85\xE1\x85\xE2\x68\x48\x38\xE5\xE0\x48\x8A" 857 | "\xE5\xE1\x85\xD3\xB0\x0A\x68\x49\xFF\x69\x01\x48\xA9\x00\xE5\xD3" 858 | "\x85\xD1\x85\xD5\x68\x85\xD0\x85\xD4\x68\x85\xE0\x86\xE1\x98\x18" 859 | "\xE5\xE2\x90\x04\x49\xFF\x69\xFE\x85\xD2\x84\xE2\x66\xD3\x38\xE5" 860 | "\xD0\xAA\xA9\xFF\xE5\xD1\x85\x1D\xA4\xE5\xB0\x05\x0A\x20\x65\xF4" 861 | "\x38\xA5\xD4\x65\xD2\x85\xD4\xA5\xD5\xE9\x00\x85\xD5\xB1\x26\x45" 862 | "\x1C\x25\x30\x51\x26\x91\x26\xE8\xD0\x04\xE6\x1D\xF0\x62\xA5\xD3" 863 | "\xB0\xDA\x20\xD3\xF4\x18\xA5\xD4\x65\xD0\x85\xD4\xA5\xD5\x65\xD1" 864 | "\x50\xD9\x81\x82\x84\x88\x90\xA0\xC0\x1C\xFF\xFE\xFA\xF4\xEC\xE1" 865 | "\xD4\xC5\xB4\xA1\x8D\x78\x61\x49\x31\x18\xFF\xA5\x26\x0A\xA5\x27" 866 | "\x29\x03\x2A\x05\x26\x0A\x0A\x0A\x85\xE2\xA5\x27\x4A\x4A\x29\x07" 867 | "\x05\xE2\x85\xE2\xA5\xE5\x0A\x65\xE5\x0A\xAA\xCA\xA5\x30\x29\x7F" 868 | "\xE8\x4A\xD0\xFC\x85\xE1\x8A\x18\x65\xE5\x90\x02\xE6\xE1\x85\xE0" 869 | "\x60\x86\x1A\x84\x1B\xAA\x4A\x4A\x4A\x4A\x85\xD3\x8A\x29\x0F\xAA" 870 | "\xBC\xBA\xF5\x84\xD0\x49\x0F\xAA\xBC\xBB\xF5\xC8\x84\xD2\xA4\xE5" 871 | "\xA2\x00\x86\xEA\xA1\x1A\x85\xD1\xA2\x80\x86\xD4\x86\xD5\xA6\xE7" 872 | "\xA5\xD4\x38\x65\xD0\x85\xD4\x90\x04\x20\xB3\xF4\x18\xA5\xD5\x65" 873 | "\xD2\x85\xD5\x90\x03\x20\xB4\xF4\xCA\xD0\xE5\xA5\xD1\x4A\x4A\x4A" 874 | "\xD0\xD4\xE6\x1A\xD0\x02\xE6\x1B\xA1\x1A\xD0\xCA\x60\x86\x1A\x84" 875 | "\x1B\xAA\x4A\x4A\x4A\x4A\x85\xD3\x8A\x29\x0F\xAA\xBC\xBA\xF5\x84" 876 | "\xD0\x49\x0F\xAA\xBC\xBB\xF5\xC8\x84\xD2\xA4\xE5\xA2\x00\x86\xEA" 877 | "\xA1\x1A\x85\xD1\xA2\x80\x86\xD4\x86\xD5\xA6\xE7\xA5\xD4\x38\x65" 878 | "\xD0\x85\xD4\x90\x04\x20\x9C\xF4\x18\xA5\xD5\x65\xD2\x85\xD5\x90" 879 | "\x03\x20\x9D\xF4\xCA\xD0\xE5\xA5\xD1\x4A\x4A\x4A\xD0\xD4\xE6\x1A" 880 | "\xD0\x02\xE6\x1B\xA1\x1A\xD0\xCA\x60\x20\x67\xDD\x20\x52\xE7\xA4" 881 | "\x51\xA6\x50\xC0\x01\x90\x06\xD0\x1D\xE0\x18\xB0\x19\x8A\x48\x98" 882 | "\x48\xA9\x2C\x20\xC0\xDE\x20\xF8\xE6\xE0\xC0\xB0\x09\x86\x9D\x68" 883 | "\xA8\x68\xAA\xA5\x9D\x60\x4C\x06\xF2\x20\xF8\xE6\xE0\x08\xB0\xF6" 884 | "\xBD\xF6\xF6\x85\xE4\x60\x00\x2A\x55\x7F\x80\xAA\xD5\xFF\xC9\xC1" 885 | "\xF0\x0D\x20\xB9\xF6\x20\x57\xF4\x20\xB7\x00\xC9\xC1\xD0\xE6\x20" 886 | "\xC0\xDE\x20\xB9\xF6\x84\x9D\xA8\x8A\xA6\x9D\x20\x3A\xF5\x4C\x08" 887 | "\xF7\x20\xF8\xE6\x86\xF9\x60\x20\xF8\xE6\x86\xE7\x60\x20\xF8\xE6" 888 | "\xA5\xE8\x85\x1A\xA5\xE9\x85\x1B\x8A\xA2\x00\xC1\x1A\xF0\x02\xB0" 889 | "\xA5\x0A\x90\x03\xE6\x1B\x18\xA8\xB1\x1A\x65\x1A\xAA\xC8\xB1\x1A" 890 | "\x65\xE9\x85\x1B\x86\x1A\x20\xB7\x00\xC9\xC5\xD0\x09\x20\xC0\xDE" 891 | "\x20\xB9\xF6\x20\x11\xF4\xA5\xF9\x60\x20\x2D\xF7\x4C\x05\xF6\x20" 892 | "\x2D\xF7\x4C\x61\xF6\x38\x90\x18\x8D\x07\xC0\x20\x00\xC5\x8D\x06" 893 | "\xC0\xB0\x01\x60\x4C\x10\xD4\xBD\x01\x02\x10\x11\xA5\x0E\xF0\x16" 894 | "\xC9\x22\xF0\x12\xA5\x13\xC9\x49\xF0\x0C\xBD\x00\x02\x08\xC9\x61" 895 | "\x90\x02\x29\x5F\x28\x60\xBD\x00\x02\x60\x48\xA9\x20\x20\x5C\xDB" 896 | "\x68\x4C\x24\xED\xA5\x24\xC9\x21\x2C\x1F\xC0\x10\x05\xAD\x7B\x05" 897 | "\xC9\x49\x60\x8A\x2C\x1F\xC0\x30\x08\x2C\x85\x24\x38\x8A\xE5\x24" 898 | "\x60\xED\x7B\x05\x60\x00\x00\x00\x00\xA9\x40\x85\x14\x20\xE3\xDF" 899 | "\xA9\x00\x85\x14\x4C\xF0\xD8\x20\xF8\xE6\xCA\xA9\x28\xC5\x21\xB0" 900 | "\x02\xA5\x21\x20\xCA\xF7\x86\x24\x90\xD6\xAA\x20\xFB\xDA\xD0\xEB" 901 | "\x4A\x08\x20\x47\xF8\x28\xA9\x0F\x90\x02\x69\xE0\x85\x2E\xB1\x26" 902 | "\x45\x30\x25\x2E\x51\x26\x91\x26\x60\x20\x00\xF8\xC4\x2C\xB0\x11" 903 | "\xC8\x20\x0E\xF8\x90\xF6\x69\x01\x48\x20\x00\xF8\x68\xC5\x2D\x90" 904 | "\xF5\x60\xA0\x2F\xD0\x02\xA0\x27\x84\x2D\xA0\x27\xA9\x00\x85\x30" 905 | "\x20\x28\xF8\x88\x10\xF6\x60\x48\x4A\x29\x03\x09\x04\x85\x27\x68" 906 | "\x29\x18\x90\x02\x69\x7F\x85\x26\x0A\x0A\x05\x26\x85\x26\x60\xA5" 907 | "\x30\x18\x69\x03\x29\x0F\x85\x30\x0A\x0A\x0A\x0A\x05\x30\x85\x30" 908 | "\x60\x4A\x08\x20\x47\xF8\xB1\x26\x28\x90\x04\x4A\x4A\x4A\x4A\x29" 909 | "\x0F\x60\xA6\x3A\xA4\x3B\x20\x96\xFD\x20\x48\xF9\xA1\x3A\xA8\x4A" 910 | "\x90\x09\x6A\xB0\x10\xC9\xA2\xF0\x0C\x29\x87\x4A\xAA\xBD\x62\xF9" 911 | "\x20\x79\xF8\xD0\x04\xA0\x80\xA9\x00\xAA\xBD\xA6\xF9\x85\x2E\xAA" 912 | "\x84\x2A\xA0\x10\x4C\xB4\xFB\x8D\x06\xC0\xA2\x02\xBD\x05\xC3\xDD" 913 | "\x9C\xFC\xD0\x07\xCA\xCA\x10\xF4\x88\xD0\xEF\x8D\x07\xC0\x60\x00" 914 | "\x20\x82\xF8\x48\xB1\x3A\x20\xDA\xFD\xA2\x01\x20\x4A\xF9\xC4\x2F" 915 | "\xC8\x90\xF1\xA2\x03\xC0\x04\x90\xF2\x68\xA8\xB9\xC0\xF9\x85\x2C" 916 | "\xB9\x00\xFA\x85\x2D\xA9\x00\xA0\x05\x06\x2D\x26\x2C\x2A\x88\xD0" 917 | "\xF8\x69\xBF\x20\xED\xFD\xCA\xD0\xEC\x20\x48\xF9\xA4\x2F\xA2\x06" 918 | "\xE0\x03\xF0\x1C\x06\x2E\x90\x0E\xBD\xB3\xF9\x20\xED\xFD\xBD\xB9" 919 | "\xF9\xF0\x03\x20\xED\xFD\xCA\xD0\xE7\x60\x88\x30\xE7\x20\xDA\xFD" 920 | "\xA5\x2E\xC9\xE8\xB1\x3A\x90\xF2\x20\x56\xF9\xAA\xE8\xD0\x01\xC8" 921 | "\x98\x20\xDA\xFD\x8A\x4C\xDA\xFD\xA2\x03\xA9\xA0\x20\xED\xFD\xCA" 922 | "\xD0\xF8\x60\x38\xA5\x2F\xA4\x3B\xAA\x10\x01\x88\x65\x3A\x90\x01" 923 | "\xC8\x60\x04\x20\x54\x30\x0D\x80\x04\x90\x03\x22\x54\x33\x0D\x80" 924 | "\x04\x90\x04\x20\x54\x33\x0D\x80\x04\x90\x04\x20\x54\x3B\x0D\x80" 925 | "\x04\x90\x00\x22\x44\x33\x0D\xC8\x44\x00\x11\x22\x44\x33\x0D\xC8" 926 | "\x44\xA9\x01\x22\x44\x33\x0D\x80\x04\x90\x01\x22\x44\x33\x0D\x80" 927 | "\x04\x90\x26\x31\x87\x9A\x00\x21\x81\x82\x00\x00\x59\x4D\x91\x92" 928 | "\x86\x4A\x85\x9D\xAC\xA9\xAC\xA3\xA8\xA4\xD9\x00\xD8\xA4\xA4\x00" 929 | "\x1C\x8A\x1C\x23\x5D\x8B\x1B\xA1\x9D\x8A\x1D\x23\x9D\x8B\x1D\xA1" 930 | "\x00\x29\x19\xAE\x69\xA8\x19\x23\x24\x53\x1B\x23\x24\x53\x19\xA1" 931 | "\x00\x1A\x5B\x5B\xA5\x69\x24\x24\xAE\xAE\xA8\xAD\x29\x00\x7C\x00" 932 | "\x15\x9C\x6D\x9C\xA5\x69\x29\x53\x84\x13\x34\x11\xA5\x69\x23\xA0" 933 | "\xD8\x62\x5A\x48\x26\x62\x94\x88\x54\x44\xC8\x54\x68\x44\xE8\x94" 934 | "\x00\xB4\x08\x84\x74\xB4\x28\x6E\x74\xF4\xCC\x4A\x72\xF2\xA4\x8A" 935 | "\x00\xAA\xA2\xA2\x74\x74\x74\x72\x44\x68\xB2\x32\xB2\x00\x22\x00" 936 | "\x1A\x1A\x26\x26\x72\x72\x88\xC8\xC4\xCA\x26\x48\x44\x44\xA2\xC8" 937 | "\x85\x45\xA5\x45\x4C\xFA\xC3\x8D\x06\xC0\x85\x45\x28\x20\x4C\xFF" 938 | "\x68\x85\x3A\x68\x85\x3B\x6C\xF0\x03\x20\x82\xF8\x20\xDA\xFA\x4C" 939 | "\x65\xFF\xD8\x20\x84\xFE\x20\x2F\xFB\x20\x93\xFE\x20\x89\xFE\xAD" 940 | "\x58\xC0\xAD\x5A\xC0\xA0\x09\x20\xB4\xFB\xEA\xAD\xFF\xCF\x2C\x10" 941 | "\xC0\xD8\x20\x3A\xFF\xAD\xF3\x03\x49\xA5\xCD\xF4\x03\xD0\x17\xAD" 942 | "\xF2\x03\xD0\x0F\xA9\xE0\xCD\xF3\x03\xD0\x08\xA0\x03\x8C\xF2\x03" 943 | "\x4C\x00\xE0\x6C\xF2\x03\x20\x60\xFB\xA2\x05\xBD\xFC\xFA\x9D\xEF" 944 | "\x03\xCA\xD0\xF7\xA9\xC8\x86\x00\x85\x01\xA0\x05\xC6\x01\xA5\x01" 945 | "\xC9\xC0\xF0\xD7\x8D\xF8\x07\xB1\x00\xD9\x01\xFB\xD0\xEC\x88\x88" 946 | "\x10\xF5\x6C\x00\x00\x00\x00\x20\x8E\xFD\xA9\x45\x85\x40\xA9\x00" 947 | "\x85\x41\xA2\xFB\xA9\xA0\x20\xED\xFD\xBD\x1E\xFA\x20\xED\xFD\xA9" 948 | "\xBD\x20\xED\xFD\xB5\x4A\x20\xDA\xFD\xE8\x30\xE8\x60\x59\xFA\x00" 949 | "\xE0\x45\x20\xFF\x00\xFF\x03\xFF\x3C\xC1\xF0\xF0\xEC\xE5\xA0\xDD" 950 | "\xDB\xC4\xC2\xC1\xFF\xC3\xFF\xFF\xFF\xC1\xD8\xD9\xD0\xD3\xAD\x70" 951 | "\xC0\xA0\x00\xEA\xEA\xBD\x64\xC0\x10\x04\xC8\xD0\xF8\x88\x60\xA9" 952 | "\x00\x85\x48\xAD\x56\xC0\xAD\x54\xC0\xAD\x51\xC0\xA9\x00\xF0\x0B" 953 | "\xAD\x50\xC0\xAD\x53\xC0\x20\x36\xF8\xA9\x14\x85\x22\xA9\x00\x85" 954 | "\x20\xA0\x0C\xD0\x5F\xA9\x18\x85\x23\xA9\x17\x85\x25\x4C\x22\xFC" 955 | "\x20\x58\xFC\xA0\x09\xB9\x09\xFF\x99\x0E\x04\x88\xD0\xF7\x60\xAD" 956 | "\xF3\x03\x49\xA5\x8D\xF4\x03\x60\xC9\x8D\xD0\x18\xAC\x00\xC0\x10" 957 | "\x13\xC0\x93\xD0\x0F\x2C\x10\xC0\xAC\x00\xC0\x10\xFB\xC0\x83\xF0" 958 | "\x03\x2C\x10\xC0\x4C\xFD\xFB\x38\x4C\x2C\xFC\xA8\xB9\x48\xFA\x20" 959 | "\x97\xFB\x20\x21\xFD\xC9\xCE\xB0\xEE\xC9\xC9\x90\xEA\xC9\xCC\xF0" 960 | "\xE6\xD0\xE8\x06\x2C\x15\xC0\x08\x8D\x07\xC0\x4C\x00\xC1\x00\x00" 961 | "\xE0\x48\x4A\x29\x03\x09\x04\x85\x29\x68\x29\x18\x90\x02\x69\x7F" 962 | "\x85\x28\x0A\x0A\x05\x28\x85\x28\x60\xC9\x87\xD0\x12\xA9\x40\x20" 963 | "\xA8\xFC\xA0\xC0\xA9\x0C\x20\xA8\xFC\xAD\x30\xC0\x88\xD0\xF5\x60" 964 | "\xA4\x24\x91\x28\xE6\x24\xA5\x24\xC5\x21\xB0\x66\x60\xC9\xA0\xB0" 965 | "\xEF\xA8\x10\xEC\xC9\x8D\xF0\x5A\xC9\x8A\xF0\x5A\xC9\x88\xD0\xC9" 966 | "\xC6\x24\x10\xE8\xA5\x21\x85\x24\xC6\x24\xA5\x22\xC5\x25\xB0\xDC" 967 | "\xC6\x25\xA5\x25\x85\x28\x98\xA0\x04\xD0\x89\x00\x49\xC0\xF0\x28" 968 | "\x69\xFD\x90\xC0\xF0\xDA\x69\xFD\x90\x2C\xF0\xDE\x69\xFD\x90\x5C" 969 | "\xD0\xBA\xA0\x0A\xD0\xE3\x2C\x1F\xC0\x10\x04\xA0\x00\xF0\x0B\x98" 970 | "\x48\x20\x78\xFB\x68\xA4\x35\x60\xA0\x05\x4C\xB4\xFB\x53\x5C\x5C" 971 | "\x00\x00\xA9\x00\x85\x24\xE6\x25\xA5\x25\xC5\x23\x90\xB6\xC6\x25" 972 | "\xA0\x06\xD0\xB5\x8D\x06\xC0\x6C\xFE\x03\x68\x8D\xF8\x07\xC9\xC1" 973 | "\x90\x0D\x8D\xFF\xCF\xA0\x00\xA6\x01\x85\x01\xB1\x00\x86\x01\x8D" 974 | "\x07\xC0\x4C\x7C\xC4\x90\x02\x25\x32\x4C\xF7\xFD\x38\x90\x18\x84" 975 | "\x2A\xA0\x07\xB0\x78\xC8\xD0\x75\x38\x48\xE9\x01\xD0\xFC\x68\xE9" 976 | "\x01\xD0\xF6\x60\xE6\x42\xD0\x02\xE6\x43\xA5\x3C\xC5\x3E\xA5\x3D" 977 | "\xE5\x3F\xE6\x3C\xD0\x02\xE6\x3D\x60\x8D\x07\xC0\x20\x67\xC5\x4C" 978 | "\xC5\xFE\x8D\x06\xC0\x20\x4A\xF9\xA9\xDE\x20\xED\xFD\x20\x3A\xFF" 979 | "\x4C\xF0\xFC\x8D\x06\xC0\x20\xD0\xF8\x20\x53\xF9\x84\x3B\x85\x3A" 980 | "\xA9\xA1\x85\x33\x20\x67\xFD\x8D\x07\xC0\x4C\x9C\xCF\xB9\x00\x02" 981 | "\xC8\xC9\xE1\x90\x06\xC9\xFB\xB0\x02\x29\xDF\x60\xA0\x0B\xD0\x03" 982 | "\x4C\x18\xFD\x20\xB4\xFB\xEA\xEA\x6C\x38\x00\xA0\x03\x4C\xB4\xFB" 983 | "\xEA\x20\x0C\xFD\xA0\x01\xD0\xF5\x4E\xF8\x07\x4C\x0C\xFD\xEA\x20" 984 | "\x21\xFD\x20\xA5\xFB\x20\x28\xFD\xC9\x9B\xF0\xF3\x60\xA0\x0F\x20" 985 | "\xB4\xFB\xA4\x24\x9D\x00\x02\x20\xED\xFD\xEA\xEA\xEA\xBD\x00\x02" 986 | "\xC9\x88\xF0\x1D\xC9\x98\xF0\x0A\xE0\xF8\x90\x03\x20\x3A\xFF\xE8" 987 | "\xD0\x13\xA9\xDC\x20\xED\xFD\x20\x8E\xFD\xA5\x33\x20\xED\xFD\xA2" 988 | "\x01\x8A\xF0\xF3\xCA\x20\x35\xFD\xC9\x95\xD0\x08\xB1\x28\x2C\x1F" 989 | "\xC0\x30\xBA\xEA\x9D\x00\x02\xC9\x8D\xD0\xBC\x20\x9C\xFC\xA9\x8D" 990 | "\xD0\x5B\xA4\x3D\xA6\x3C\x20\x8E\xFD\x20\x40\xF9\xA0\x00\xA9\xAD" 991 | "\x4C\xED\xFD\xA5\x3C\x09\x07\x85\x3E\xA5\x3D\x85\x3F\xA5\x3C\x29" 992 | "\x07\xD0\x03\x20\x92\xFD\xA9\xA0\x20\xED\xFD\xB1\x3C\x20\xDA\xFD" 993 | "\x20\xBA\xFC\x90\xE8\x60\x4A\x90\xEA\x4A\x4A\xA5\x3E\x90\x02\x49" 994 | "\xFF\x65\x3C\x48\xA9\xBD\x20\xED\xFD\x68\x48\x4A\x4A\x4A\x4A\x20" 995 | "\xE5\xFD\x68\x29\x0F\x09\xB0\xC9\xBA\x90\x02\x69\x06\x6C\x36\x00" 996 | "\x48\xC9\xA0\x4C\x95\xFC\x48\x84\x35\xA8\x68\x4C\x46\xFC\xEA\xEA" 997 | "\xC6\x34\xF0\x9F\xCA\xD0\x16\xC9\xBA\xD0\xBB\x85\x31\xA5\x3E\x91" 998 | "\x40\xE6\x40\xD0\x02\xE6\x41\x60\xA4\x34\xB9\xFF\x01\x85\x31\x60" 999 | "\xA2\x01\xB5\x3E\x95\x42\x95\x44\xCA\x10\xF7\x60\xB1\x3C\x91\x42" 1000 | "\x20\xB4\xFC\x90\xF7\x60\xB1\x3C\xD1\x42\xF0\x1C\x20\x92\xFD\xB1" 1001 | "\x3C\x20\xDA\xFD\xA9\xA0\x20\xED\xFD\xA9\xA8\x20\xED\xFD\xB1\x42" 1002 | "\x20\xDA\xFD\xA9\xA9\x20\xED\xFD\x20\xB4\xFC\x90\xD9\x60\x20\x75" 1003 | "\xFE\xA9\x14\x48\x20\xD0\xF8\x20\x53\xF9\x85\x3A\x84\x3B\x68\x38" 1004 | "\xE9\x01\xD0\xEF\x60\x8A\xF0\x07\xB5\x3C\x95\x3A\xCA\x10\xF9\x60" 1005 | "\xA0\x3F\xD0\x02\xA0\xFF\x84\x32\x60\xA9\x00\x85\x3E\xA2\x38\xA0" 1006 | "\x1B\xD0\x08\xA9\x00\x85\x3E\xA2\x36\xA0\xF0\xA5\x3E\x29\x0F\xF0" 1007 | "\x04\x09\xC0\xA0\x00\x94\x00\x95\x01\xA0\x0E\x4C\xB4\xFB\xEA\x00" 1008 | "\x4C\x00\xE0\x4C\x03\xE0\x20\x75\xFE\x20\x3F\xFF\x6C\x3A\x00\x4C" 1009 | "\xD7\xFA\x60\xEA\x60\x8D\x06\xC0\x60\xEA\x4C\xF8\x03\xA9\x40\x8D" 1010 | "\x07\xC0\x20\xAA\xC5\xF0\x2C\xA0\x01\xA5\x43\xF0\x04\xD1\x3C\xD0" 1011 | "\x0A\x88\xA5\x42\xD1\x3C\xD0\x03\x20\x92\xFD\x20\xBA\xFC\x90\xE7" 1012 | "\x60\xA0\x0D\x20\xB4\xFB\x20\x00\xFE\x68\x68\xD0\x6C\x8D\x07\xC0" 1013 | "\x20\xD1\xC5\x8D\x06\xC0\xF0\x32\xD0\x23\xC1\xF0\xF0\xEC\xE5\xA0" 1014 | "\xAF\xAF\xE5\x20\xFD\xFC\xC9\xA0\xF0\xF9\x60\xB0\x6D\xC9\xA0\xD0" 1015 | "\x28\xB9\x00\x02\xA2\x07\xC9\x8D\xF0\x7D\xC8\xD0\x63\xA9\xC5\x20" 1016 | "\xED\xFD\xA9\xD2\x20\xED\xFD\x20\xED\xFD\xA9\x87\x4C\xED\xFD\xA5" 1017 | "\x48\x48\xA5\x45\xA6\x46\xA4\x47\x28\x60\x85\x45\x86\x46\x84\x47" 1018 | "\x08\x68\x85\x48\xBA\x86\x49\xD8\x60\x20\x84\xFE\x20\x2F\xFB\x20" 1019 | "\x93\xFE\x20\x89\xFE\xD8\x20\x3A\xFF\xA9\xAA\x85\x33\x20\x67\xFD" 1020 | "\x20\xC7\xFF\x20\xA7\xFF\x84\x34\xA0\x17\x88\x30\xE8\xD9\xCC\xFF" 1021 | "\xD0\xF8\x20\xBE\xFF\xA4\x34\x4C\x73\xFF\xA2\x03\x0A\x0A\x0A\x0A" 1022 | "\x0A\x26\x3E\x26\x3F\xCA\x10\xF8\xA5\x31\xD0\x06\xB5\x3F\x95\x3D" 1023 | "\x95\x41\xE8\xF0\xF3\xD0\x06\xA2\x00\x86\x3E\x86\x3F\x20\xFD\xFC" 1024 | "\xEA\x49\xB0\xC9\x0A\x90\xD3\x69\x88\xC9\xFA\x4C\x1B\xFF\xA9\xFE" 1025 | "\x48\xB9\xE3\xFF\x48\xA5\x31\xA0\x00\x84\x31\x60\xBC\xB2\xBE\x9A" 1026 | "\xEF\xC4\xEC\xA9\xBB\xA6\xA4\x06\x95\x07\x02\x05\xF0\x00\xEB\x93" 1027 | "\xA7\xC6\x99\xB2\xC9\xBE\xF0\x35\x8C\xD6\x96\xAF\x17\x17\x2B\x1F" 1028 | "\x83\x7F\x5D\xCC\xB5\xFC\x17\x17\xF5\x03\xFB\x03\x62\xFA\xFA\xC3" 1029 | ; 1030 | 1031 | #endif /* __ROM_DATA_H__ */ 1032 | -------------------------------------------------------------------------------- /common/video.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "video.h" 4 | #include "video_char_data.h" 5 | 6 | #define VIDEO_RESOLUTION_X 280 7 | #define VIDEO_RESOLUTION_Y 192 8 | #define VIDEO_BUFFER_SIZE (VIDEO_RESOLUTION_X) 9 | 10 | #define TEXT_BYTES 8 11 | #define TEXT_BYTES_MASK 0x07 12 | 13 | #define VGA_COLORS 3 14 | #define VGA_LINE_BYTES 50 15 | #define SCAN_LINE_BYTES (VGA_COLORS * VGA_LINE_BYTES) 16 | #define H_SYNC_COUNTER_START 410 //406 to 414, 20 counts = 1 pixel 17 | 18 | #define H_BUFFER_OFFSET 4 19 | #define H_BUFFER_VISIBLE 35 20 | 21 | #define VGA_BLACK 0x0000 22 | #define VGA_GREEN 0x0032 23 | #define VGA_PURPLE 0x01CD 24 | #define VGA_ORANGE 0x0017 25 | #define VGA_BLUE 0x01E8 26 | #define VGA_WHITE 0x01FF 27 | 28 | enum HCOLOR 29 | { 30 | BLACK = 0, 31 | PURPLE, 32 | GREEN, 33 | GREEN_1, 34 | PURPLE_1, 35 | BLUE, 36 | ORANGE_0, 37 | ORANGE_1, 38 | BLUE_1, 39 | WHITE, 40 | HCOLOR_LENGTH, 41 | }; 42 | 43 | const uint16_t hcolor[] = 44 | { 45 | VGA_BLACK, 46 | VGA_PURPLE, 47 | VGA_GREEN, 48 | VGA_GREEN, 49 | VGA_PURPLE, 50 | VGA_BLUE, 51 | VGA_ORANGE, 52 | VGA_ORANGE, 53 | VGA_BLUE, 54 | VGA_WHITE, 55 | }; 56 | 57 | typedef enum 58 | { 59 | VIDEO_TEXT_MODE = 0, 60 | VIDEO_GRAPHICS_MODE 61 | } VideoModeStatus; 62 | 63 | typedef enum 64 | { 65 | VIDEO_PAGE_1 = 0, 66 | VIDEO_PAGE_2 67 | } VideoPageStatus; 68 | 69 | static uint8_t video_char_set[CHARACTER_SET_ROM_SIZE]; 70 | static uint16_t video_buffer[VIDEO_BUFFER_SIZE] = {0}; 71 | static uint8_t video_mode = VIDEO_TEXT_MODE; 72 | static uint8_t video_page = VIDEO_PAGE_1; 73 | static uint16_t video_scan_line; 74 | 75 | void video_init(void) 76 | { 77 | memcpy(video_char_set, char_rom, CHARACTER_SET_ROM_SIZE); 78 | } 79 | 80 | void video_update(uint8_t read, uint16_t address, uint8_t *byte) 81 | { 82 | if ((address & 0xFFF0) == 0xC050) 83 | { 84 | if (address == 0xC054) 85 | { 86 | video_page = VIDEO_PAGE_1; 87 | } 88 | if (address == 0xC055) 89 | { 90 | video_page = VIDEO_PAGE_2; 91 | } 92 | 93 | if (address == 0xC050) 94 | { 95 | video_mode = VIDEO_GRAPHICS_MODE; 96 | } 97 | 98 | if (address == 0xC051) 99 | { 100 | video_mode = VIDEO_TEXT_MODE; 101 | } 102 | } 103 | } 104 | 105 | 106 | void video_hires_line_update(uint16_t video_line_number, uint8_t *video_line_data) 107 | { 108 | uint16_t data = 0; 109 | uint16_t pixel_pre = 0; 110 | uint16_t pixel_post = 0; 111 | uint16_t data_extended = 0; 112 | uint8_t address_odd = 0; 113 | uint8_t color_offset = 0; 114 | uint8_t color = 0; 115 | uint8_t pixel = 0; 116 | uint8_t pixel_left1 = 0; 117 | uint8_t pixel_right1 = 0; 118 | 119 | if (video_line_number < VIDEO_RESOLUTION_Y) 120 | { 121 | for(int j = 0; j < VIDEO_BYTES_PER_LINE; j++) 122 | { 123 | data = video_line_data[j]; 124 | pixel_pre = (video_line_data[j - 1] & 0x60)>>5; 125 | pixel_post = video_line_data[j + 1] & 3; 126 | address_odd = (j & 1)<<1; 127 | color_offset = (data & 0x80)>>5; 128 | data_extended = pixel_pre + ((data & 0x7F)<<2) + (pixel_post<<9); 129 | 130 | for(int i = 0; i < 7; i++) 131 | { 132 | color = BLACK; 133 | pixel = (data_extended >> (i + 2)) & 1; 134 | pixel_left1 = (data_extended >> (i + 1)) & 1; 135 | pixel_right1 = (data_extended >> (i + 3)) & 1; 136 | 137 | if (pixel) 138 | { 139 | if (pixel_left1 || pixel_right1) 140 | { 141 | color = WHITE; 142 | } 143 | else 144 | { 145 | color = color_offset + address_odd + (i & 1) + 1; 146 | } 147 | } 148 | else 149 | { 150 | if (pixel_left1 && pixel_right1) 151 | { 152 | 153 | color = color_offset + address_odd + 1 - (i & 1) + 1; 154 | } 155 | } 156 | video_buffer[j*7 + i] |= hcolor[color]; 157 | } 158 | } 159 | } 160 | } 161 | 162 | void video_text_line_update(uint16_t video_line_number, uint8_t *video_line_data) 163 | { 164 | uint16_t text_char = 0; 165 | uint16_t data = 0; 166 | uint8_t color = 0; 167 | uint8_t pixel_color = WHITE; 168 | uint8_t pixel = 0; 169 | uint16_t rom_char = 0; 170 | uint16_t rom_char_offset = 0; 171 | 172 | if (video_line_number < VIDEO_RESOLUTION_Y) 173 | { 174 | for(int j = 0; j < VIDEO_BYTES_PER_LINE; j++) 175 | { 176 | text_char = video_line_data[j]; 177 | 178 | if((text_char & 0xC0) == 0x40) 179 | { 180 | // text_char &= 0x3F; 181 | // if(text_char < 0x20) 182 | // { 183 | // text_char += 0x40; 184 | // } 185 | } 186 | 187 | rom_char = text_char * TEXT_BYTES; 188 | rom_char_offset = video_line_number & TEXT_BYTES_MASK; 189 | data = video_char_set[rom_char + rom_char_offset]; 190 | 191 | for(int i = 0; i < 7; i++) 192 | { 193 | color = pixel_color; 194 | pixel = (data >> (i)) & 1; 195 | if (pixel) 196 | { 197 | color = BLACK; 198 | } 199 | video_buffer[j*7 + i] |= hcolor[color]; 200 | } 201 | } 202 | } 203 | } 204 | 205 | void video_scan_line_set(uint16_t line) 206 | { 207 | video_scan_line = line; 208 | } 209 | 210 | void video_buffer_clear(void) 211 | { 212 | memset(video_buffer, 0, VIDEO_BUFFER_SIZE * 2); 213 | } 214 | 215 | void video_buffer_get(uint16_t *buffer) 216 | { 217 | memcpy(buffer, video_buffer, VIDEO_BUFFER_SIZE * 2); 218 | } 219 | 220 | uint16_t video_address_get(void) 221 | { 222 | uint16_t address; 223 | if (video_mode == VIDEO_TEXT_MODE) 224 | { 225 | address = 0x400 + (0x400 * video_page) + 226 | (((video_scan_line>>3) & 0x07) * SCREEN_LINE_OFFSET) + 227 | ((video_scan_line>>6) * VIDEO_SEGMENT_OFFSET); 228 | } 229 | else 230 | { 231 | address = 0x2000 + (0x2000 * video_page) + 232 | (video_scan_line & 7) * 0x400 + 233 | ((video_scan_line>>3) & 7) * 0x80 + 234 | (video_scan_line>>6) * 0x28; 235 | } 236 | return address; 237 | } 238 | 239 | void video_line_data_get(uint8_t *video_line_data) 240 | { 241 | if (video_mode == VIDEO_TEXT_MODE) 242 | { 243 | video_text_line_update(video_scan_line, video_line_data); 244 | } 245 | else 246 | { 247 | video_hires_line_update(video_scan_line, video_line_data); 248 | } 249 | } 250 | -------------------------------------------------------------------------------- /common/video.h: -------------------------------------------------------------------------------- 1 | #ifndef __VIDEO_H__ 2 | #define __VIDEO_H__ 3 | 4 | #include 5 | #include 6 | 7 | #define VIDEO_BYTES_PER_LINE 40 8 | #define SCREEN_LINE_OFFSET 0x80 9 | #define VIDEO_SEGMENT_OFFSET 0x28 10 | 11 | void video_init(void); 12 | void video_update(uint8_t read, uint16_t address, uint8_t *byte); 13 | void video_scan_line_set(uint16_t line); 14 | void video_buffer_clear(void); 15 | void video_buffer_get(uint16_t *buf); 16 | uint16_t video_address_get(void); 17 | void video_line_data_get(uint8_t *video_line_data); 18 | 19 | #endif /* __VIDEO_H__ */ 20 | -------------------------------------------------------------------------------- /common/video_char_data.h: -------------------------------------------------------------------------------- 1 | #ifndef __CHAR_ROM_H__ 2 | #define __CHAR_ROM_H__ 3 | 4 | #define CHARACTER_SET_ROM_SIZE 4096 5 | 6 | const uint8_t char_rom[] = 7 | { 8 | 0x1C, 0x22, 0x2A, 0x3A, 0x1A, 0x02, 0x3C, 0x00, 0x08, 0x14, 0x22, 0x22, 0x3E, 0x22, 0x22, 0x00, 9 | 0x1E, 0x22, 0x22, 0x1E, 0x22, 0x22, 0x1E, 0x00, 0x1C, 0x22, 0x02, 0x02, 0x02, 0x22, 0x1C, 0x00, 10 | 0x1E, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1E, 0x00, 0x3E, 0x02, 0x02, 0x1E, 0x02, 0x02, 0x3E, 0x00, 11 | 0x3E, 0x02, 0x02, 0x1E, 0x02, 0x02, 0x02, 0x00, 0x3C, 0x02, 0x02, 0x02, 0x32, 0x22, 0x3C, 0x00, 12 | 0x22, 0x22, 0x22, 0x3E, 0x22, 0x22, 0x22, 0x00, 0x1C, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1C, 0x00, 13 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x1C, 0x00, 0x22, 0x12, 0x0A, 0x06, 0x0A, 0x12, 0x22, 0x00, 14 | 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x3E, 0x00, 0x22, 0x36, 0x2A, 0x2A, 0x22, 0x22, 0x22, 0x00, 15 | 0x22, 0x22, 0x26, 0x2A, 0x32, 0x22, 0x22, 0x00, 0x1C, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1C, 0x00, 16 | 0x1E, 0x22, 0x22, 0x1E, 0x02, 0x02, 0x02, 0x00, 0x1C, 0x22, 0x22, 0x22, 0x2A, 0x12, 0x2C, 0x00, 17 | 0x1E, 0x22, 0x22, 0x1E, 0x0A, 0x12, 0x22, 0x00, 0x1C, 0x22, 0x02, 0x1C, 0x20, 0x22, 0x1C, 0x00, 18 | 0x3E, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1C, 0x00, 19 | 0x22, 0x22, 0x22, 0x22, 0x22, 0x14, 0x08, 0x00, 0x22, 0x22, 0x22, 0x2A, 0x2A, 0x36, 0x22, 0x00, 20 | 0x22, 0x22, 0x14, 0x08, 0x14, 0x22, 0x22, 0x00, 0x22, 0x22, 0x14, 0x08, 0x08, 0x08, 0x08, 0x00, 21 | 0x3E, 0x20, 0x10, 0x08, 0x04, 0x02, 0x3E, 0x00, 0x3E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x3E, 0x00, 22 | 0x00, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, 0x00, 0x3E, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3E, 0x00, 23 | 0x00, 0x00, 0x08, 0x14, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 24 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x08, 0x00, 25 | 0x14, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14, 0x3E, 0x14, 0x3E, 0x14, 0x14, 0x00, 26 | 0x08, 0x3C, 0x0A, 0x1C, 0x28, 0x1E, 0x08, 0x00, 0x06, 0x26, 0x10, 0x08, 0x04, 0x32, 0x30, 0x00, 27 | 0x04, 0x0A, 0x0A, 0x04, 0x2A, 0x12, 0x2C, 0x00, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 28 | 0x08, 0x04, 0x02, 0x02, 0x02, 0x04, 0x08, 0x00, 0x08, 0x10, 0x20, 0x20, 0x20, 0x10, 0x08, 0x00, 29 | 0x08, 0x2A, 0x1C, 0x08, 0x1C, 0x2A, 0x08, 0x00, 0x00, 0x08, 0x08, 0x3E, 0x08, 0x08, 0x00, 0x00, 30 | 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 31 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x00, 0x00, 32 | 0x1C, 0x22, 0x32, 0x2A, 0x26, 0x22, 0x1C, 0x00, 0x08, 0x0C, 0x08, 0x08, 0x08, 0x08, 0x1C, 0x00, 33 | 0x1C, 0x22, 0x20, 0x18, 0x04, 0x02, 0x3E, 0x00, 0x3E, 0x20, 0x10, 0x18, 0x20, 0x22, 0x1C, 0x00, 34 | 0x10, 0x18, 0x14, 0x12, 0x3E, 0x10, 0x10, 0x00, 0x3E, 0x02, 0x1E, 0x20, 0x20, 0x22, 0x1C, 0x00, 35 | 0x38, 0x04, 0x02, 0x1E, 0x22, 0x22, 0x1C, 0x00, 0x3E, 0x20, 0x10, 0x08, 0x04, 0x04, 0x04, 0x00, 36 | 0x1C, 0x22, 0x22, 0x1C, 0x22, 0x22, 0x1C, 0x00, 0x1C, 0x22, 0x22, 0x3C, 0x20, 0x10, 0x0E, 0x00, 37 | 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x08, 0x04, 0x00, 38 | 0x10, 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x3E, 0x00, 0x00, 0x00, 39 | 0x04, 0x08, 0x10, 0x20, 0x10, 0x08, 0x04, 0x00, 0x1C, 0x22, 0x10, 0x08, 0x08, 0x00, 0x08, 0x00, 40 | 0x1C, 0x22, 0x2A, 0x3A, 0x1A, 0x02, 0x3C, 0x00, 0x08, 0x14, 0x22, 0x22, 0x3E, 0x22, 0x22, 0x00, 41 | 0x1E, 0x22, 0x22, 0x1E, 0x22, 0x22, 0x1E, 0x00, 0x1C, 0x22, 0x02, 0x02, 0x02, 0x22, 0x1C, 0x00, 42 | 0x1E, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1E, 0x00, 0x3E, 0x02, 0x02, 0x1E, 0x02, 0x02, 0x3E, 0x00, 43 | 0x3E, 0x02, 0x02, 0x1E, 0x02, 0x02, 0x02, 0x00, 0x3C, 0x02, 0x02, 0x02, 0x32, 0x22, 0x3C, 0x00, 44 | 0x22, 0x22, 0x22, 0x3E, 0x22, 0x22, 0x22, 0x00, 0x1C, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1C, 0x00, 45 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x1C, 0x00, 0x22, 0x12, 0x0A, 0x06, 0x0A, 0x12, 0x22, 0x00, 46 | 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x3E, 0x00, 0x22, 0x36, 0x2A, 0x2A, 0x22, 0x22, 0x22, 0x00, 47 | 0x22, 0x22, 0x26, 0x2A, 0x32, 0x22, 0x22, 0x00, 0x1C, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1C, 0x00, 48 | 0x1E, 0x22, 0x22, 0x1E, 0x02, 0x02, 0x02, 0x00, 0x1C, 0x22, 0x22, 0x22, 0x2A, 0x12, 0x2C, 0x00, 49 | 0x1E, 0x22, 0x22, 0x1E, 0x0A, 0x12, 0x22, 0x00, 0x1C, 0x22, 0x02, 0x1C, 0x20, 0x22, 0x1C, 0x00, 50 | 0x3E, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1C, 0x00, 51 | 0x22, 0x22, 0x22, 0x22, 0x22, 0x14, 0x08, 0x00, 0x22, 0x22, 0x22, 0x2A, 0x2A, 0x36, 0x22, 0x00, 52 | 0x22, 0x22, 0x14, 0x08, 0x14, 0x22, 0x22, 0x00, 0x22, 0x22, 0x14, 0x08, 0x08, 0x08, 0x08, 0x00, 53 | 0x3E, 0x20, 0x10, 0x08, 0x04, 0x02, 0x3E, 0x00, 0x3E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x3E, 0x00, 54 | 0x00, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, 0x00, 0x3E, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3E, 0x00, 55 | 0x00, 0x00, 0x08, 0x14, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 56 | 0x04, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x20, 0x3C, 0x22, 0x3C, 0x00, 57 | 0x02, 0x02, 0x1E, 0x22, 0x22, 0x22, 0x1E, 0x00, 0x00, 0x00, 0x3C, 0x02, 0x02, 0x02, 0x3C, 0x00, 58 | 0x20, 0x20, 0x3C, 0x22, 0x22, 0x22, 0x3C, 0x00, 0x00, 0x00, 0x1C, 0x22, 0x3E, 0x02, 0x3C, 0x00, 59 | 0x18, 0x24, 0x04, 0x1E, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x1C, 0x22, 0x22, 0x3C, 0x20, 0x1C, 60 | 0x02, 0x02, 0x1E, 0x22, 0x22, 0x22, 0x22, 0x00, 0x08, 0x00, 0x0C, 0x08, 0x08, 0x08, 0x1C, 0x00, 61 | 0x10, 0x00, 0x18, 0x10, 0x10, 0x10, 0x12, 0x0C, 0x02, 0x02, 0x22, 0x12, 0x0E, 0x12, 0x22, 0x00, 62 | 0x0C, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1C, 0x00, 0x00, 0x00, 0x36, 0x2A, 0x2A, 0x2A, 0x22, 0x00, 63 | 0x00, 0x00, 0x1E, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x1C, 0x22, 0x22, 0x22, 0x1C, 0x00, 64 | 0x00, 0x00, 0x1E, 0x22, 0x22, 0x1E, 0x02, 0x02, 0x00, 0x00, 0x3C, 0x22, 0x22, 0x3C, 0x20, 0x20, 65 | 0x00, 0x00, 0x3A, 0x06, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x3C, 0x02, 0x1C, 0x20, 0x1E, 0x00, 66 | 0x04, 0x04, 0x1E, 0x04, 0x04, 0x24, 0x18, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x32, 0x2C, 0x00, 67 | 0x00, 0x00, 0x22, 0x22, 0x22, 0x14, 0x08, 0x00, 0x00, 0x00, 0x22, 0x22, 0x2A, 0x2A, 0x36, 0x00, 68 | 0x00, 0x00, 0x22, 0x14, 0x08, 0x14, 0x22, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x3C, 0x20, 0x1C, 69 | 0x00, 0x00, 0x3E, 0x10, 0x08, 0x04, 0x3E, 0x00, 0x38, 0x0C, 0x0C, 0x06, 0x0C, 0x0C, 0x38, 0x00, 70 | 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0E, 0x18, 0x18, 0x30, 0x18, 0x18, 0x0E, 0x00, 71 | 0x2C, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x14, 0x2A, 0x14, 0x2A, 0x00, 0x00, 72 | 0xE3, 0xDD, 0xD5, 0xC5, 0xE5, 0xFD, 0xC3, 0xFF, 0xF7, 0xEB, 0xDD, 0xDD, 0xC1, 0xDD, 0xDD, 0xFF, 73 | 0xE1, 0xDD, 0xDD, 0xE1, 0xDD, 0xDD, 0xE1, 0xFF, 0xE3, 0xDD, 0xFD, 0xFD, 0xFD, 0xDD, 0xE3, 0xFF, 74 | 0xE1, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xE1, 0xFF, 0xC1, 0xFD, 0xFD, 0xE1, 0xFD, 0xFD, 0xC1, 0xFF, 75 | 0xC1, 0xFD, 0xFD, 0xE1, 0xFD, 0xFD, 0xFD, 0xFF, 0xC3, 0xFD, 0xFD, 0xFD, 0xCD, 0xDD, 0xC3, 0xFF, 76 | 0xDD, 0xDD, 0xDD, 0xC1, 0xDD, 0xDD, 0xDD, 0xFF, 0xE3, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xE3, 0xFF, 77 | 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDD, 0xE3, 0xFF, 0xDD, 0xED, 0xF5, 0xF9, 0xF5, 0xED, 0xDD, 0xFF, 78 | 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xC1, 0xFF, 0xDD, 0xC9, 0xD5, 0xD5, 0xDD, 0xDD, 0xDD, 0xFF, 79 | 0xDD, 0xDD, 0xD9, 0xD5, 0xCD, 0xDD, 0xDD, 0xFF, 0xE3, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xE3, 0xFF, 80 | 0xE1, 0xDD, 0xDD, 0xE1, 0xFD, 0xFD, 0xFD, 0xFF, 0xE3, 0xDD, 0xDD, 0xDD, 0xD5, 0xED, 0xD3, 0xFF, 81 | 0xE1, 0xDD, 0xDD, 0xE1, 0xF5, 0xED, 0xDD, 0xFF, 0xE3, 0xDD, 0xFD, 0xE3, 0xDF, 0xDD, 0xE3, 0xFF, 82 | 0xC1, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xFF, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xE3, 0xFF, 83 | 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xEB, 0xF7, 0xFF, 0xDD, 0xDD, 0xDD, 0xD5, 0xD5, 0xC9, 0xDD, 0xFF, 84 | 0xDD, 0xDD, 0xEB, 0xF7, 0xEB, 0xDD, 0xDD, 0xFF, 0xDD, 0xDD, 0xEB, 0xF7, 0xF7, 0xF7, 0xF7, 0xFF, 85 | 0xC1, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0xC1, 0xFF, 0xC1, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xC1, 0xFF, 86 | 0xFF, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xFF, 0xFF, 0xC1, 0xCF, 0xCF, 0xCF, 0xCF, 0xCF, 0xC1, 0xFF, 87 | 0xFF, 0xFF, 0xF7, 0xEB, 0xDD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 88 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xFF, 0xF7, 0xFF, 89 | 0xEB, 0xEB, 0xEB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEB, 0xEB, 0xC1, 0xEB, 0xC1, 0xEB, 0xEB, 0xFF, 90 | 0xF7, 0xC3, 0xF5, 0xE3, 0xD7, 0xE1, 0xF7, 0xFF, 0xF9, 0xD9, 0xEF, 0xF7, 0xFB, 0xCD, 0xCF, 0xFF, 91 | 0xFB, 0xF5, 0xF5, 0xFB, 0xD5, 0xED, 0xD3, 0xFF, 0xF7, 0xF7, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 92 | 0xF7, 0xFB, 0xFD, 0xFD, 0xFD, 0xFB, 0xF7, 0xFF, 0xF7, 0xEF, 0xDF, 0xDF, 0xDF, 0xEF, 0xF7, 0xFF, 93 | 0xF7, 0xD5, 0xE3, 0xF7, 0xE3, 0xD5, 0xF7, 0xFF, 0xFF, 0xF7, 0xF7, 0xC1, 0xF7, 0xF7, 0xFF, 0xFF, 94 | 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0xF7, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xC1, 0xFF, 0xFF, 0xFF, 0xFF, 95 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0xFF, 0xFF, 96 | 0xE3, 0xDD, 0xCD, 0xD5, 0xD9, 0xDD, 0xE3, 0xFF, 0xF7, 0xF3, 0xF7, 0xF7, 0xF7, 0xF7, 0xE3, 0xFF, 97 | 0xE3, 0xDD, 0xDF, 0xE7, 0xFB, 0xFD, 0xC1, 0xFF, 0xC1, 0xDF, 0xEF, 0xE7, 0xDF, 0xDD, 0xE3, 0xFF, 98 | 0xEF, 0xE7, 0xEB, 0xED, 0xC1, 0xEF, 0xEF, 0xFF, 0xC1, 0xFD, 0xE1, 0xDF, 0xDF, 0xDD, 0xE3, 0xFF, 99 | 0xC7, 0xFB, 0xFD, 0xE1, 0xDD, 0xDD, 0xE3, 0xFF, 0xC1, 0xDF, 0xEF, 0xF7, 0xFB, 0xFB, 0xFB, 0xFF, 100 | 0xE3, 0xDD, 0xDD, 0xE3, 0xDD, 0xDD, 0xE3, 0xFF, 0xE3, 0xDD, 0xDD, 0xC3, 0xDF, 0xEF, 0xF1, 0xFF, 101 | 0xFF, 0xFF, 0xF7, 0xFF, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0xFF, 0xF7, 0xF7, 0xFB, 0xFF, 102 | 0xEF, 0xF7, 0xFB, 0xFD, 0xFB, 0xF7, 0xEF, 0xFF, 0xFF, 0xFF, 0xC1, 0xFF, 0xC1, 0xFF, 0xFF, 0xFF, 103 | 0xFB, 0xF7, 0xEF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFF, 0xE3, 0xDD, 0xEF, 0xF7, 0xF7, 0xFF, 0xF7, 0xFF, 104 | 0xE3, 0xDD, 0xD5, 0xC5, 0xE5, 0xFD, 0xC3, 0xFF, 0xF7, 0xEB, 0xDD, 0xDD, 0xC1, 0xDD, 0xDD, 0xFF, 105 | 0xE1, 0xDD, 0xDD, 0xE1, 0xDD, 0xDD, 0xE1, 0xFF, 0xE3, 0xDD, 0xFD, 0xFD, 0xFD, 0xDD, 0xE3, 0xFF, 106 | 0xE1, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xE1, 0xFF, 0xC1, 0xFD, 0xFD, 0xE1, 0xFD, 0xFD, 0xC1, 0xFF, 107 | 0xC1, 0xFD, 0xFD, 0xE1, 0xFD, 0xFD, 0xFD, 0xFF, 0xC3, 0xFD, 0xFD, 0xFD, 0xCD, 0xDD, 0xC3, 0xFF, 108 | 0xDD, 0xDD, 0xDD, 0xC1, 0xDD, 0xDD, 0xDD, 0xFF, 0xE3, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xE3, 0xFF, 109 | 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDD, 0xE3, 0xFF, 0xDD, 0xED, 0xF5, 0xF9, 0xF5, 0xED, 0xDD, 0xFF, 110 | 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xC1, 0xFF, 0xDD, 0xC9, 0xD5, 0xD5, 0xDD, 0xDD, 0xDD, 0xFF, 111 | 0xDD, 0xDD, 0xD9, 0xD5, 0xCD, 0xDD, 0xDD, 0xFF, 0xE3, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xE3, 0xFF, 112 | 0xE1, 0xDD, 0xDD, 0xE1, 0xFD, 0xFD, 0xFD, 0xFF, 0xE3, 0xDD, 0xDD, 0xDD, 0xD5, 0xED, 0xD3, 0xFF, 113 | 0xE1, 0xDD, 0xDD, 0xE1, 0xF5, 0xED, 0xDD, 0xFF, 0xE3, 0xDD, 0xFD, 0xE3, 0xDF, 0xDD, 0xE3, 0xFF, 114 | 0xC1, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xFF, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xE3, 0xFF, 115 | 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xEB, 0xF7, 0xFF, 0xDD, 0xDD, 0xDD, 0xD5, 0xD5, 0xC9, 0xDD, 0xFF, 116 | 0xDD, 0xDD, 0xEB, 0xF7, 0xEB, 0xDD, 0xDD, 0xFF, 0xDD, 0xDD, 0xEB, 0xF7, 0xF7, 0xF7, 0xF7, 0xFF, 117 | 0xC1, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0xC1, 0xFF, 0xC1, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xC1, 0xFF, 118 | 0xFF, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xFF, 0xFF, 0xC1, 0xCF, 0xCF, 0xCF, 0xCF, 0xCF, 0xC1, 0xFF, 119 | 0xFF, 0xFF, 0xF7, 0xEB, 0xDD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 120 | 0xFB, 0xF7, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE3, 0xDF, 0xC3, 0xDD, 0xC3, 0xFF, 121 | 0xFD, 0xFD, 0xE1, 0xDD, 0xDD, 0xDD, 0xE1, 0xFF, 0xFF, 0xFF, 0xC3, 0xFD, 0xFD, 0xFD, 0xC3, 0xFF, 122 | 0xDF, 0xDF, 0xC3, 0xDD, 0xDD, 0xDD, 0xC3, 0xFF, 0xFF, 0xFF, 0xE3, 0xDD, 0xC1, 0xFD, 0xC3, 0xFF, 123 | 0xE7, 0xDB, 0xFB, 0xE1, 0xFB, 0xFB, 0xFB, 0xFF, 0xFF, 0xFF, 0xE3, 0xDD, 0xDD, 0xC3, 0xDF, 0xE3, 124 | 0xFD, 0xFD, 0xE1, 0xDD, 0xDD, 0xDD, 0xDD, 0xFF, 0xF7, 0xFF, 0xF3, 0xF7, 0xF7, 0xF7, 0xE3, 0xFF, 125 | 0xEF, 0xFF, 0xE7, 0xEF, 0xEF, 0xEF, 0xED, 0xF3, 0xFD, 0xFD, 0xDD, 0xED, 0xF1, 0xED, 0xDD, 0xFF, 126 | 0xF3, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xE3, 0xFF, 0xFF, 0xFF, 0xC9, 0xD5, 0xD5, 0xD5, 0xDD, 0xFF, 127 | 0xFF, 0xFF, 0xE1, 0xDD, 0xDD, 0xDD, 0xDD, 0xFF, 0xFF, 0xFF, 0xE3, 0xDD, 0xDD, 0xDD, 0xE3, 0xFF, 128 | 0xFF, 0xFF, 0xE1, 0xDD, 0xDD, 0xE1, 0xFD, 0xFD, 0xFF, 0xFF, 0xC3, 0xDD, 0xDD, 0xC3, 0xDF, 0xDF, 129 | 0xFF, 0xFF, 0xC5, 0xF9, 0xFD, 0xFD, 0xFD, 0xFF, 0xFF, 0xFF, 0xC3, 0xFD, 0xE3, 0xDF, 0xE1, 0xFF, 130 | 0xFB, 0xFB, 0xE1, 0xFB, 0xFB, 0xDB, 0xE7, 0xFF, 0xFF, 0xFF, 0xDD, 0xDD, 0xDD, 0xCD, 0xD3, 0xFF, 131 | 0xFF, 0xFF, 0xDD, 0xDD, 0xDD, 0xEB, 0xF7, 0xFF, 0xFF, 0xFF, 0xDD, 0xDD, 0xD5, 0xD5, 0xC9, 0xFF, 132 | 0xFF, 0xFF, 0xDD, 0xEB, 0xF7, 0xEB, 0xDD, 0xFF, 0xFF, 0xFF, 0xDD, 0xDD, 0xDD, 0xC3, 0xDF, 0xE3, 133 | 0xFF, 0xFF, 0xC1, 0xEF, 0xF7, 0xFB, 0xC1, 0xFF, 0xC7, 0xF3, 0xF3, 0xF9, 0xF3, 0xF3, 0xC7, 0xFF, 134 | 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF1, 0xE7, 0xE7, 0xCF, 0xE7, 0xE7, 0xF1, 0xFF, 135 | 0xD3, 0xE5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD5, 0xEB, 0xD5, 0xEB, 0xD5, 0xFF, 0xFF, 136 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xEE, 0xBB, 0xFE, 0xFE, 0xFF, 0xFF, 137 | 0xFD, 0xFD, 0xDD, 0x77, 0xFD, 0xFD, 0xFF, 0xFF, 0xFC, 0xFC, 0xCC, 0x33, 0xFC, 0xFC, 0xFF, 0xFF, 138 | 0xFB, 0xFB, 0xBB, 0xEE, 0xFB, 0xFB, 0xFF, 0xFF, 0xFA, 0xFA, 0xAA, 0xAA, 0xFA, 0xFA, 0xFF, 0xFF, 139 | 0xF9, 0xF9, 0x99, 0x66, 0xF9, 0xF9, 0xFF, 0xFF, 0xF8, 0xF8, 0x88, 0x22, 0xF8, 0xF8, 0xFF, 0xFF, 140 | 0xF7, 0xF7, 0x77, 0xDD, 0xF7, 0xF7, 0xFF, 0xFF, 0xF6, 0xF6, 0x66, 0x99, 0xF6, 0xF6, 0xFF, 0xFF, 141 | 0xF5, 0xF5, 0x55, 0x55, 0xF5, 0xF5, 0xFF, 0xFF, 0xF4, 0xF4, 0x44, 0x11, 0xF4, 0xF4, 0xFF, 0xFF, 142 | 0xF3, 0xF3, 0x33, 0xCC, 0xF3, 0xF3, 0xFF, 0xFF, 0xF2, 0xF2, 0x22, 0x88, 0xF2, 0xF2, 0xFF, 0xFF, 143 | 0xF1, 0xF1, 0x11, 0x44, 0xF1, 0xF1, 0xFF, 0xFF, 0xF0, 0xF0, 0x00, 0x00, 0xF0, 0xF0, 0xFF, 0xFF, 144 | 0xEF, 0xEF, 0xFF, 0xFF, 0xEF, 0xEF, 0xEE, 0xBB, 0xEE, 0xEE, 0xEE, 0xBB, 0xEE, 0xEE, 0xEE, 0xBB, 145 | 0xED, 0xED, 0xDD, 0x77, 0xED, 0xED, 0xEE, 0xBB, 0xEC, 0xEC, 0xCC, 0x33, 0xEC, 0xEC, 0xEE, 0xBB, 146 | 0xEB, 0xEB, 0xBB, 0xEE, 0xEB, 0xEB, 0xEE, 0xBB, 0xEA, 0xEA, 0xAA, 0xAA, 0xEA, 0xEA, 0xEE, 0xBB, 147 | 0xE9, 0xE9, 0x99, 0x66, 0xE9, 0xE9, 0xEE, 0xBB, 0xE8, 0xE8, 0x88, 0x22, 0xE8, 0xE8, 0xEE, 0xBB, 148 | 0xE7, 0xE7, 0x77, 0xDD, 0xE7, 0xE7, 0xEE, 0xBB, 0xE6, 0xE6, 0x66, 0x99, 0xE6, 0xE6, 0xEE, 0xBB, 149 | 0xE5, 0xE5, 0x55, 0x55, 0xE5, 0xE5, 0xEE, 0xBB, 0xE4, 0xE4, 0x44, 0x11, 0xE4, 0xE4, 0xEE, 0xBB, 150 | 0xE3, 0xE3, 0x33, 0xCC, 0xE3, 0xE3, 0xEE, 0xBB, 0xE2, 0xE2, 0x22, 0x88, 0xE2, 0xE2, 0xEE, 0xBB, 151 | 0xE1, 0xE1, 0x11, 0x44, 0xE1, 0xE1, 0xEE, 0xBB, 0xE0, 0xE0, 0x00, 0x00, 0xE0, 0xE0, 0xEE, 0xBB, 152 | 0xDF, 0xDF, 0xFF, 0xFF, 0xDF, 0xDF, 0xDD, 0x77, 0xDE, 0xDE, 0xEE, 0xBB, 0xDE, 0xDE, 0xDD, 0x77, 153 | 0xDD, 0xDD, 0xDD, 0x77, 0xDD, 0xDD, 0xDD, 0x77, 0xDC, 0xDC, 0xCC, 0x33, 0xDC, 0xDC, 0xDD, 0x77, 154 | 0xDB, 0xDB, 0xBB, 0xEE, 0xDB, 0xDB, 0xDD, 0x77, 0xDA, 0xDA, 0xAA, 0xAA, 0xDA, 0xDA, 0xDD, 0x77, 155 | 0xD9, 0xD9, 0x99, 0x66, 0xD9, 0xD9, 0xDD, 0x77, 0xD8, 0xD8, 0x88, 0x22, 0xD8, 0xD8, 0xDD, 0x77, 156 | 0xD7, 0xD7, 0x77, 0xDD, 0xD7, 0xD7, 0xDD, 0x77, 0xD6, 0xD6, 0x66, 0x99, 0xD6, 0xD6, 0xDD, 0x77, 157 | 0xD5, 0xD5, 0x55, 0x55, 0xD5, 0xD5, 0xDD, 0x77, 0xD4, 0xD4, 0x44, 0x11, 0xD4, 0xD4, 0xDD, 0x77, 158 | 0xD3, 0xD3, 0x33, 0xCC, 0xD3, 0xD3, 0xDD, 0x77, 0xD2, 0xD2, 0x22, 0x88, 0xD2, 0xD2, 0xDD, 0x77, 159 | 0xD1, 0xD1, 0x11, 0x44, 0xD1, 0xD1, 0xDD, 0x77, 0xD0, 0xD0, 0x00, 0x00, 0xD0, 0xD0, 0xDD, 0x77, 160 | 0xCF, 0xCF, 0xFF, 0xFF, 0xCF, 0xCF, 0xCC, 0x33, 0xCE, 0xCE, 0xEE, 0xBB, 0xCE, 0xCE, 0xCC, 0x33, 161 | 0xCD, 0xCD, 0xDD, 0x77, 0xCD, 0xCD, 0xCC, 0x33, 0xCC, 0xCC, 0xCC, 0x33, 0xCC, 0xCC, 0xCC, 0x33, 162 | 0xCB, 0xCB, 0xBB, 0xEE, 0xCB, 0xCB, 0xCC, 0x33, 0xCA, 0xCA, 0xAA, 0xAA, 0xCA, 0xCA, 0xCC, 0x33, 163 | 0xC9, 0xC9, 0x99, 0x66, 0xC9, 0xC9, 0xCC, 0x33, 0xC8, 0xC8, 0x88, 0x22, 0xC8, 0xC8, 0xCC, 0x33, 164 | 0xC7, 0xC7, 0x77, 0xDD, 0xC7, 0xC7, 0xCC, 0x33, 0xC6, 0xC6, 0x66, 0x99, 0xC6, 0xC6, 0xCC, 0x33, 165 | 0xC5, 0xC5, 0x55, 0x55, 0xC5, 0xC5, 0xCC, 0x33, 0xC4, 0xC4, 0x44, 0x11, 0xC4, 0xC4, 0xCC, 0x33, 166 | 0xC3, 0xC3, 0x33, 0xCC, 0xC3, 0xC3, 0xCC, 0x33, 0xC2, 0xC2, 0x22, 0x88, 0xC2, 0xC2, 0xCC, 0x33, 167 | 0xC1, 0xC1, 0x11, 0x44, 0xC1, 0xC1, 0xCC, 0x33, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0xCC, 0x33, 168 | 0xBF, 0xBF, 0xFF, 0xFF, 0xBF, 0xBF, 0xBB, 0xEE, 0xBE, 0xBE, 0xEE, 0xBB, 0xBE, 0xBE, 0xBB, 0xEE, 169 | 0xBD, 0xBD, 0xDD, 0x77, 0xBD, 0xBD, 0xBB, 0xEE, 0xBC, 0xBC, 0xCC, 0x33, 0xBC, 0xBC, 0xBB, 0xEE, 170 | 0xBB, 0xBB, 0xBB, 0xEE, 0xBB, 0xBB, 0xBB, 0xEE, 0xBA, 0xBA, 0xAA, 0xAA, 0xBA, 0xBA, 0xBB, 0xEE, 171 | 0xB9, 0xB9, 0x99, 0x66, 0xB9, 0xB9, 0xBB, 0xEE, 0xB8, 0xB8, 0x88, 0x22, 0xB8, 0xB8, 0xBB, 0xEE, 172 | 0xB7, 0xB7, 0x77, 0xDD, 0xB7, 0xB7, 0xBB, 0xEE, 0xB6, 0xB6, 0x66, 0x99, 0xB6, 0xB6, 0xBB, 0xEE, 173 | 0xB5, 0xB5, 0x55, 0x55, 0xB5, 0xB5, 0xBB, 0xEE, 0xB4, 0xB4, 0x44, 0x11, 0xB4, 0xB4, 0xBB, 0xEE, 174 | 0xB3, 0xB3, 0x33, 0xCC, 0xB3, 0xB3, 0xBB, 0xEE, 0xB2, 0xB2, 0x22, 0x88, 0xB2, 0xB2, 0xBB, 0xEE, 175 | 0xB1, 0xB1, 0x11, 0x44, 0xB1, 0xB1, 0xBB, 0xEE, 0xB0, 0xB0, 0x00, 0x00, 0xB0, 0xB0, 0xBB, 0xEE, 176 | 0xAF, 0xAF, 0xFF, 0xFF, 0xAF, 0xAF, 0xAA, 0xAA, 0xAE, 0xAE, 0xEE, 0xBB, 0xAE, 0xAE, 0xAA, 0xAA, 177 | 0xAD, 0xAD, 0xDD, 0x77, 0xAD, 0xAD, 0xAA, 0xAA, 0xAC, 0xAC, 0xCC, 0x33, 0xAC, 0xAC, 0xAA, 0xAA, 178 | 0xAB, 0xAB, 0xBB, 0xEE, 0xAB, 0xAB, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 179 | 0xA9, 0xA9, 0x99, 0x66, 0xA9, 0xA9, 0xAA, 0xAA, 0xA8, 0xA8, 0x88, 0x22, 0xA8, 0xA8, 0xAA, 0xAA, 180 | 0xA7, 0xA7, 0x77, 0xDD, 0xA7, 0xA7, 0xAA, 0xAA, 0xA6, 0xA6, 0x66, 0x99, 0xA6, 0xA6, 0xAA, 0xAA, 181 | 0xA5, 0xA5, 0x55, 0x55, 0xA5, 0xA5, 0xAA, 0xAA, 0xA4, 0xA4, 0x44, 0x11, 0xA4, 0xA4, 0xAA, 0xAA, 182 | 0xA3, 0xA3, 0x33, 0xCC, 0xA3, 0xA3, 0xAA, 0xAA, 0xA2, 0xA2, 0x22, 0x88, 0xA2, 0xA2, 0xAA, 0xAA, 183 | 0xA1, 0xA1, 0x11, 0x44, 0xA1, 0xA1, 0xAA, 0xAA, 0xA0, 0xA0, 0x00, 0x00, 0xA0, 0xA0, 0xAA, 0xAA, 184 | 0x9F, 0x9F, 0xFF, 0xFF, 0x9F, 0x9F, 0x99, 0x66, 0x9E, 0x9E, 0xEE, 0xBB, 0x9E, 0x9E, 0x99, 0x66, 185 | 0x9D, 0x9D, 0xDD, 0x77, 0x9D, 0x9D, 0x99, 0x66, 0x9C, 0x9C, 0xCC, 0x33, 0x9C, 0x9C, 0x99, 0x66, 186 | 0x9B, 0x9B, 0xBB, 0xEE, 0x9B, 0x9B, 0x99, 0x66, 0x9A, 0x9A, 0xAA, 0xAA, 0x9A, 0x9A, 0x99, 0x66, 187 | 0x99, 0x99, 0x99, 0x66, 0x99, 0x99, 0x99, 0x66, 0x98, 0x98, 0x88, 0x22, 0x98, 0x98, 0x99, 0x66, 188 | 0x97, 0x97, 0x77, 0xDD, 0x97, 0x97, 0x99, 0x66, 0x96, 0x96, 0x66, 0x99, 0x96, 0x96, 0x99, 0x66, 189 | 0x95, 0x95, 0x55, 0x55, 0x95, 0x95, 0x99, 0x66, 0x94, 0x94, 0x44, 0x11, 0x94, 0x94, 0x99, 0x66, 190 | 0x93, 0x93, 0x33, 0xCC, 0x93, 0x93, 0x99, 0x66, 0x92, 0x92, 0x22, 0x88, 0x92, 0x92, 0x99, 0x66, 191 | 0x91, 0x91, 0x11, 0x44, 0x91, 0x91, 0x99, 0x66, 0x90, 0x90, 0x00, 0x00, 0x90, 0x90, 0x99, 0x66, 192 | 0x8F, 0x8F, 0xFF, 0xFF, 0x8F, 0x8F, 0x88, 0x22, 0x8E, 0x8E, 0xEE, 0xBB, 0x8E, 0x8E, 0x88, 0x22, 193 | 0x8D, 0x8D, 0xDD, 0x77, 0x8D, 0x8D, 0x88, 0x22, 0x8C, 0x8C, 0xCC, 0x33, 0x8C, 0x8C, 0x88, 0x22, 194 | 0x8B, 0x8B, 0xBB, 0xEE, 0x8B, 0x8B, 0x88, 0x22, 0x8A, 0x8A, 0xAA, 0xAA, 0x8A, 0x8A, 0x88, 0x22, 195 | 0x89, 0x89, 0x99, 0x66, 0x89, 0x89, 0x88, 0x22, 0x88, 0x88, 0x88, 0x22, 0x88, 0x88, 0x88, 0x22, 196 | 0x87, 0x87, 0x77, 0xDD, 0x87, 0x87, 0x88, 0x22, 0x86, 0x86, 0x66, 0x99, 0x86, 0x86, 0x88, 0x22, 197 | 0x85, 0x85, 0x55, 0x55, 0x85, 0x85, 0x88, 0x22, 0x84, 0x84, 0x44, 0x11, 0x84, 0x84, 0x88, 0x22, 198 | 0x83, 0x83, 0x33, 0xCC, 0x83, 0x83, 0x88, 0x22, 0x82, 0x82, 0x22, 0x88, 0x82, 0x82, 0x88, 0x22, 199 | 0x81, 0x81, 0x11, 0x44, 0x81, 0x81, 0x88, 0x22, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x88, 0x22, 200 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x77, 0xDD, 0xFE, 0xFE, 0xEE, 0xBB, 0xFE, 0xFE, 0x77, 0xDD, 201 | 0xFD, 0xFD, 0xDD, 0x77, 0xFD, 0xFD, 0x77, 0xDD, 0xFC, 0xFC, 0xCC, 0x33, 0xFC, 0xFC, 0x77, 0xDD, 202 | 0xFB, 0xFB, 0xBB, 0xEE, 0xFB, 0xFB, 0x77, 0xDD, 0xFA, 0xFA, 0xAA, 0xAA, 0xFA, 0xFA, 0x77, 0xDD, 203 | 0xF9, 0xF9, 0x99, 0x66, 0xF9, 0xF9, 0x77, 0xDD, 0xF8, 0xF8, 0x88, 0x22, 0xF8, 0xF8, 0x77, 0xDD, 204 | 0xF7, 0xF7, 0x77, 0xDD, 0xF7, 0xF7, 0x77, 0xDD, 0xF6, 0xF6, 0x66, 0x99, 0xF6, 0xF6, 0x77, 0xDD, 205 | 0xF5, 0xF5, 0x55, 0x55, 0xF5, 0xF5, 0x77, 0xDD, 0xF4, 0xF4, 0x44, 0x11, 0xF4, 0xF4, 0x77, 0xDD, 206 | 0xF3, 0xF3, 0x33, 0xCC, 0xF3, 0xF3, 0x77, 0xDD, 0xF2, 0xF2, 0x22, 0x88, 0xF2, 0xF2, 0x77, 0xDD, 207 | 0xF1, 0xF1, 0x11, 0x44, 0xF1, 0xF1, 0x77, 0xDD, 0xF0, 0xF0, 0x00, 0x00, 0xF0, 0xF0, 0x77, 0xDD, 208 | 0xEF, 0xEF, 0xFF, 0xFF, 0xEF, 0xEF, 0x66, 0x99, 0xEE, 0xEE, 0xEE, 0xBB, 0xEE, 0xEE, 0x66, 0x99, 209 | 0xED, 0xED, 0xDD, 0x77, 0xED, 0xED, 0x66, 0x99, 0xEC, 0xEC, 0xCC, 0x33, 0xEC, 0xEC, 0x66, 0x99, 210 | 0xEB, 0xEB, 0xBB, 0xEE, 0xEB, 0xEB, 0x66, 0x99, 0xEA, 0xEA, 0xAA, 0xAA, 0xEA, 0xEA, 0x66, 0x99, 211 | 0xE9, 0xE9, 0x99, 0x66, 0xE9, 0xE9, 0x66, 0x99, 0xE8, 0xE8, 0x88, 0x22, 0xE8, 0xE8, 0x66, 0x99, 212 | 0xE7, 0xE7, 0x77, 0xDD, 0xE7, 0xE7, 0x66, 0x99, 0xE6, 0xE6, 0x66, 0x99, 0xE6, 0xE6, 0x66, 0x99, 213 | 0xE5, 0xE5, 0x55, 0x55, 0xE5, 0xE5, 0x66, 0x99, 0xE4, 0xE4, 0x44, 0x11, 0xE4, 0xE4, 0x66, 0x99, 214 | 0xE3, 0xE3, 0x33, 0xCC, 0xE3, 0xE3, 0x66, 0x99, 0xE2, 0xE2, 0x22, 0x88, 0xE2, 0xE2, 0x66, 0x99, 215 | 0xE1, 0xE1, 0x11, 0x44, 0xE1, 0xE1, 0x66, 0x99, 0xE0, 0xE0, 0x00, 0x00, 0xE0, 0xE0, 0x66, 0x99, 216 | 0xDF, 0xDF, 0xFF, 0xFF, 0xDF, 0xDF, 0x55, 0x55, 0xDE, 0xDE, 0xEE, 0xBB, 0xDE, 0xDE, 0x55, 0x55, 217 | 0xDD, 0xDD, 0xDD, 0x77, 0xDD, 0xDD, 0x55, 0x55, 0xDC, 0xDC, 0xCC, 0x33, 0xDC, 0xDC, 0x55, 0x55, 218 | 0xDB, 0xDB, 0xBB, 0xEE, 0xDB, 0xDB, 0x55, 0x55, 0xDA, 0xDA, 0xAA, 0xAA, 0xDA, 0xDA, 0x55, 0x55, 219 | 0xD9, 0xD9, 0x99, 0x66, 0xD9, 0xD9, 0x55, 0x55, 0xD8, 0xD8, 0x88, 0x22, 0xD8, 0xD8, 0x55, 0x55, 220 | 0xD7, 0xD7, 0x77, 0xDD, 0xD7, 0xD7, 0x55, 0x55, 0xD6, 0xD6, 0x66, 0x99, 0xD6, 0xD6, 0x55, 0x55, 221 | 0xD5, 0xD5, 0x55, 0x55, 0xD5, 0xD5, 0x55, 0x55, 0xD4, 0xD4, 0x44, 0x11, 0xD4, 0xD4, 0x55, 0x55, 222 | 0xD3, 0xD3, 0x33, 0xCC, 0xD3, 0xD3, 0x55, 0x55, 0xD2, 0xD2, 0x22, 0x88, 0xD2, 0xD2, 0x55, 0x55, 223 | 0xD1, 0xD1, 0x11, 0x44, 0xD1, 0xD1, 0x55, 0x55, 0xD0, 0xD0, 0x00, 0x00, 0xD0, 0xD0, 0x55, 0x55, 224 | 0xCF, 0xCF, 0xFF, 0xFF, 0xCF, 0xCF, 0x44, 0x11, 0xCE, 0xCE, 0xEE, 0xBB, 0xCE, 0xCE, 0x44, 0x11, 225 | 0xCD, 0xCD, 0xDD, 0x77, 0xCD, 0xCD, 0x44, 0x11, 0xCC, 0xCC, 0xCC, 0x33, 0xCC, 0xCC, 0x44, 0x11, 226 | 0xCB, 0xCB, 0xBB, 0xEE, 0xCB, 0xCB, 0x44, 0x11, 0xCA, 0xCA, 0xAA, 0xAA, 0xCA, 0xCA, 0x44, 0x11, 227 | 0xC9, 0xC9, 0x99, 0x66, 0xC9, 0xC9, 0x44, 0x11, 0xC8, 0xC8, 0x88, 0x22, 0xC8, 0xC8, 0x44, 0x11, 228 | 0xC7, 0xC7, 0x77, 0xDD, 0xC7, 0xC7, 0x44, 0x11, 0xC6, 0xC6, 0x66, 0x99, 0xC6, 0xC6, 0x44, 0x11, 229 | 0xC5, 0xC5, 0x55, 0x55, 0xC5, 0xC5, 0x44, 0x11, 0xC4, 0xC4, 0x44, 0x11, 0xC4, 0xC4, 0x44, 0x11, 230 | 0xC3, 0xC3, 0x33, 0xCC, 0xC3, 0xC3, 0x44, 0x11, 0xC2, 0xC2, 0x22, 0x88, 0xC2, 0xC2, 0x44, 0x11, 231 | 0xC1, 0xC1, 0x11, 0x44, 0xC1, 0xC1, 0x44, 0x11, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0x44, 0x11, 232 | 0xBF, 0xBF, 0xFF, 0xFF, 0xBF, 0xBF, 0x33, 0xCC, 0xBE, 0xBE, 0xEE, 0xBB, 0xBE, 0xBE, 0x33, 0xCC, 233 | 0xBD, 0xBD, 0xDD, 0x77, 0xBD, 0xBD, 0x33, 0xCC, 0xBC, 0xBC, 0xCC, 0x33, 0xBC, 0xBC, 0x33, 0xCC, 234 | 0xBB, 0xBB, 0xBB, 0xEE, 0xBB, 0xBB, 0x33, 0xCC, 0xBA, 0xBA, 0xAA, 0xAA, 0xBA, 0xBA, 0x33, 0xCC, 235 | 0xB9, 0xB9, 0x99, 0x66, 0xB9, 0xB9, 0x33, 0xCC, 0xB8, 0xB8, 0x88, 0x22, 0xB8, 0xB8, 0x33, 0xCC, 236 | 0xB7, 0xB7, 0x77, 0xDD, 0xB7, 0xB7, 0x33, 0xCC, 0xB6, 0xB6, 0x66, 0x99, 0xB6, 0xB6, 0x33, 0xCC, 237 | 0xB5, 0xB5, 0x55, 0x55, 0xB5, 0xB5, 0x33, 0xCC, 0xB4, 0xB4, 0x44, 0x11, 0xB4, 0xB4, 0x33, 0xCC, 238 | 0xB3, 0xB3, 0x33, 0xCC, 0xB3, 0xB3, 0x33, 0xCC, 0xB2, 0xB2, 0x22, 0x88, 0xB2, 0xB2, 0x33, 0xCC, 239 | 0xB1, 0xB1, 0x11, 0x44, 0xB1, 0xB1, 0x33, 0xCC, 0xB0, 0xB0, 0x00, 0x00, 0xB0, 0xB0, 0x33, 0xCC, 240 | 0xAF, 0xAF, 0xFF, 0xFF, 0xAF, 0xAF, 0x22, 0x88, 0xAE, 0xAE, 0xEE, 0xBB, 0xAE, 0xAE, 0x22, 0x88, 241 | 0xAD, 0xAD, 0xDD, 0x77, 0xAD, 0xAD, 0x22, 0x88, 0xAC, 0xAC, 0xCC, 0x33, 0xAC, 0xAC, 0x22, 0x88, 242 | 0xAB, 0xAB, 0xBB, 0xEE, 0xAB, 0xAB, 0x22, 0x88, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x22, 0x88, 243 | 0xA9, 0xA9, 0x99, 0x66, 0xA9, 0xA9, 0x22, 0x88, 0xA8, 0xA8, 0x88, 0x22, 0xA8, 0xA8, 0x22, 0x88, 244 | 0xA7, 0xA7, 0x77, 0xDD, 0xA7, 0xA7, 0x22, 0x88, 0xA6, 0xA6, 0x66, 0x99, 0xA6, 0xA6, 0x22, 0x88, 245 | 0xA5, 0xA5, 0x55, 0x55, 0xA5, 0xA5, 0x22, 0x88, 0xA4, 0xA4, 0x44, 0x11, 0xA4, 0xA4, 0x22, 0x88, 246 | 0xA3, 0xA3, 0x33, 0xCC, 0xA3, 0xA3, 0x22, 0x88, 0xA2, 0xA2, 0x22, 0x88, 0xA2, 0xA2, 0x22, 0x88, 247 | 0xA1, 0xA1, 0x11, 0x44, 0xA1, 0xA1, 0x22, 0x88, 0xA0, 0xA0, 0x00, 0x00, 0xA0, 0xA0, 0x22, 0x88, 248 | 0x9F, 0x9F, 0xFF, 0xFF, 0x9F, 0x9F, 0x11, 0x44, 0x9E, 0x9E, 0xEE, 0xBB, 0x9E, 0x9E, 0x11, 0x44, 249 | 0x9D, 0x9D, 0xDD, 0x77, 0x9D, 0x9D, 0x11, 0x44, 0x9C, 0x9C, 0xCC, 0x33, 0x9C, 0x9C, 0x11, 0x44, 250 | 0x9B, 0x9B, 0xBB, 0xEE, 0x9B, 0x9B, 0x11, 0x44, 0x9A, 0x9A, 0xAA, 0xAA, 0x9A, 0x9A, 0x11, 0x44, 251 | 0x99, 0x99, 0x99, 0x66, 0x99, 0x99, 0x11, 0x44, 0x98, 0x98, 0x88, 0x22, 0x98, 0x98, 0x11, 0x44, 252 | 0x97, 0x97, 0x77, 0xDD, 0x97, 0x97, 0x11, 0x44, 0x96, 0x96, 0x66, 0x99, 0x96, 0x96, 0x11, 0x44, 253 | 0x95, 0x95, 0x55, 0x55, 0x95, 0x95, 0x11, 0x44, 0x94, 0x94, 0x44, 0x11, 0x94, 0x94, 0x11, 0x44, 254 | 0x93, 0x93, 0x33, 0xCC, 0x93, 0x93, 0x11, 0x44, 0x92, 0x92, 0x22, 0x88, 0x92, 0x92, 0x11, 0x44, 255 | 0x91, 0x91, 0x11, 0x44, 0x91, 0x91, 0x11, 0x44, 0x90, 0x90, 0x00, 0x00, 0x90, 0x90, 0x11, 0x44, 256 | 0x8F, 0x8F, 0xFF, 0xFF, 0x8F, 0x8F, 0x00, 0x00, 0x8E, 0x8E, 0xEE, 0xBB, 0x8E, 0x8E, 0x00, 0x00, 257 | 0x8D, 0x8D, 0xDD, 0x77, 0x8D, 0x8D, 0x00, 0x00, 0x8C, 0x8C, 0xCC, 0x33, 0x8C, 0x8C, 0x00, 0x00, 258 | 0x8B, 0x8B, 0xBB, 0xEE, 0x8B, 0x8B, 0x00, 0x00, 0x8A, 0x8A, 0xAA, 0xAA, 0x8A, 0x8A, 0x00, 0x00, 259 | 0x89, 0x89, 0x99, 0x66, 0x89, 0x89, 0x00, 0x00, 0x88, 0x88, 0x88, 0x22, 0x88, 0x88, 0x00, 0x00, 260 | 0x87, 0x87, 0x77, 0xDD, 0x87, 0x87, 0x00, 0x00, 0x86, 0x86, 0x66, 0x99, 0x86, 0x86, 0x00, 0x00, 261 | 0x85, 0x85, 0x55, 0x55, 0x85, 0x85, 0x00, 0x00, 0x84, 0x84, 0x44, 0x11, 0x84, 0x84, 0x00, 0x00, 262 | 0x83, 0x83, 0x33, 0xCC, 0x83, 0x83, 0x00, 0x00, 0x82, 0x82, 0x22, 0x88, 0x82, 0x82, 0x00, 0x00, 263 | 0x81, 0x81, 0x11, 0x44, 0x81, 0x81, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 264 | }; 265 | 266 | #endif /* __CHAR_ROM_H__ */ 267 | -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyrex8/pico-iie/0a78fc5ff2bdd10bef6eb3710a34350b7dedbb8a/icon.png -------------------------------------------------------------------------------- /images/main_py_screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyrex8/pico-iie/0a78fc5ff2bdd10bef6eb3710a34350b7dedbb8a/images/main_py_screenshot.png -------------------------------------------------------------------------------- /images/perf_board.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyrex8/pico-iie/0a78fc5ff2bdd10bef6eb3710a34350b7dedbb8a/images/perf_board.png -------------------------------------------------------------------------------- /images/pi_pico_vga_demo_board.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyrex8/pico-iie/0a78fc5ff2bdd10bef6eb3710a34350b7dedbb8a/images/pi_pico_vga_demo_board.png -------------------------------------------------------------------------------- /images/pico-iie_bin_file_download.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyrex8/pico-iie/0a78fc5ff2bdd10bef6eb3710a34350b7dedbb8a/images/pico-iie_bin_file_download.jpg -------------------------------------------------------------------------------- /images/pico-iie_block_diagram.drawio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyrex8/pico-iie/0a78fc5ff2bdd10bef6eb3710a34350b7dedbb8a/images/pico-iie_block_diagram.drawio.png -------------------------------------------------------------------------------- /images/pico-iie_board.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyrex8/pico-iie/0a78fc5ff2bdd10bef6eb3710a34350b7dedbb8a/images/pico-iie_board.jpg -------------------------------------------------------------------------------- /images/pico-iie_board_assembled.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyrex8/pico-iie/0a78fc5ff2bdd10bef6eb3710a34350b7dedbb8a/images/pico-iie_board_assembled.jpg -------------------------------------------------------------------------------- /images/pico-iie_board_enclosure.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyrex8/pico-iie/0a78fc5ff2bdd10bef6eb3710a34350b7dedbb8a/images/pico-iie_board_enclosure.jpg -------------------------------------------------------------------------------- /images/pico-iie_bootup_screen.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyrex8/pico-iie/0a78fc5ff2bdd10bef6eb3710a34350b7dedbb8a/images/pico-iie_bootup_screen.jpg -------------------------------------------------------------------------------- /images/pico-iie_cosmic_impalas.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyrex8/pico-iie/0a78fc5ff2bdd10bef6eb3710a34350b7dedbb8a/images/pico-iie_cosmic_impalas.jpg -------------------------------------------------------------------------------- /images/pico-iie_jumpers_bottom.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyrex8/pico-iie/0a78fc5ff2bdd10bef6eb3710a34350b7dedbb8a/images/pico-iie_jumpers_bottom.jpg -------------------------------------------------------------------------------- /images/pico-iie_jumpers_top.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyrex8/pico-iie/0a78fc5ff2bdd10bef6eb3710a34350b7dedbb8a/images/pico-iie_jumpers_top.jpg -------------------------------------------------------------------------------- /images/pico-iie_pcb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyrex8/pico-iie/0a78fc5ff2bdd10bef6eb3710a34350b7dedbb8a/images/pico-iie_pcb.png -------------------------------------------------------------------------------- /images/pico-iie_schematics.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyrex8/pico-iie/0a78fc5ff2bdd10bef6eb3710a34350b7dedbb8a/images/pico-iie_schematics.png -------------------------------------------------------------------------------- /images/pico-iie_setup.drawio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyrex8/pico-iie/0a78fc5ff2bdd10bef6eb3710a34350b7dedbb8a/images/pico-iie_setup.drawio.png -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "pico/stdlib.h" 4 | #include "pico/multicore.h" 5 | #include "pico/binary_info.h" 6 | #include "hardware/pio.h" 7 | #include "hardware/clocks.h" 8 | #include "hardware/pwm.h" 9 | #include "hardware/dma.h" 10 | #include "hardware/irq.h" 11 | #include "hardware/structs/mpu.h" 12 | #include "hardware/structs/vreg_and_chip_reset.h" 13 | #include "hardware/watchdog.h" 14 | #include "hardware/flash.h" 15 | 16 | #include "main.h" 17 | 18 | #include "mcu/clock.h" 19 | #include "mcu/test.h" 20 | #include "mcu/joystick.h" 21 | #include "mcu/key.h" 22 | #include "mcu/menu.h" 23 | #include "mcu/serial.h" 24 | #include "mcu/speaker.h" 25 | #include "mcu/vga.h" 26 | 27 | #include "m6502/c6502.h" 28 | 29 | #include "common/rom.h" 30 | #include "common/ram.h" 31 | #include "common/keyboard.h" 32 | #include "common/game.h" 33 | #include "common/audio.h" 34 | #include "common/video.h" 35 | 36 | static C6502_interface interface_c; 37 | static uint8_t video_line_data[VIDEO_BYTES_PER_LINE] = {0}; 38 | static uint16_t video_address = 0x2000; 39 | static bool reset = false; 40 | static uint8_t running = 1; 41 | static uint8_t menu = 0; 42 | static uint8_t menu_data[MENU_CHARACTERS_SIZE]; 43 | static uint16_t scan_line; 44 | static int16_t overscan_line; 45 | static uint8_t overscan_line_odd; 46 | 47 | static SerialOperation serial_operation; 48 | static KeyOperation key_operation; 49 | static uint8_t operation_data; 50 | 51 | static const void (*main_serial_operation[SERIAL_OPERATIONS_TOTAL]) (uint8_t data) = 52 | { 53 | [SERIAL_MAIN_NULL] = main_null, 54 | [SERIAL_MAIN_REBOOT] = main_reboot, 55 | [SERIAL_MAIN_START_BIN] = main_start_bin, 56 | [SERIAL_RAM_BIN_RESET] = ram_bin_reset, 57 | [SERIAL_RAM_BIN_SIZE_LSB] = menu_bin_size_lsb_set, 58 | [SERIAL_RAM_BIN_SIZE_MSB] = menu_bin_size_msb_set, 59 | [SERIAL_RAM_BIN_ADDR_LSB] = main_bin_addr_lsb_set, 60 | [SERIAL_RAM_BIN_ADDR_MSB] = main_bin_addr_msb_set, 61 | [SERIAL_RAM_BIN_DATA] = main_bin_data_set, 62 | [SERIAL_MENU_BANK] = menu_bank_set, 63 | [SERIAL_NAME_DATA] = menu_name_set, 64 | [SERIAL_MAIN_BIN_STORE] = main_store_bin, 65 | }; 66 | 67 | static const void (*main_key_operation[KEY_OPERATIONS_TOTAL]) (uint8_t data) = 68 | { 69 | [KEY_MAIN_NULL] = main_null, 70 | [KEY_MAIN_PAUSE] = main_pause, 71 | [KEY_MAIN_RESUME] = main_resume, 72 | [KEY_MAIN_RESET] = main_reset, 73 | [KEY_MAIN_MENU] = main_menu, 74 | [KEY_MAIN_MENU_SELECT] = main_menu_select, 75 | }; 76 | 77 | void main_init(void) 78 | { 79 | rom_init(); 80 | ram_init(); 81 | video_init(); 82 | c6502_init(); 83 | speaker_init(); 84 | menu_init(); 85 | } 86 | 87 | void main_null(uint8_t unused) 88 | { 89 | } 90 | 91 | void main_reboot(uint8_t unused) 92 | { 93 | watchdog_enable(1, 1); 94 | while(1); 95 | } 96 | 97 | void main_reset(uint8_t unused) 98 | { 99 | reset = true; 100 | } 101 | 102 | void main_pause(uint8_t unused) 103 | { 104 | running = 0; 105 | } 106 | 107 | void main_resume(uint8_t unused) 108 | { 109 | running = 1; 110 | } 111 | 112 | void main_bin_addr_lsb_set(uint8_t data) 113 | { 114 | menu_bin_addr_lsb_set(data); 115 | ram_bin_addr_lsb(data); 116 | } 117 | 118 | void main_bin_addr_msb_set(uint8_t data) 119 | { 120 | menu_bin_addr_msb_set(data); 121 | ram_bin_addr_msb(data); 122 | } 123 | 124 | void main_bin_data_set(uint8_t data) 125 | { 126 | menu_bin_data_set(data); 127 | ram_bin_data_set(data); 128 | } 129 | 130 | void main_menu(uint8_t unused) 131 | { 132 | ram_bin_addr_set(36); 133 | ram_bin_data_set(0); 134 | menu_data_get(menu_data); 135 | ram_data_set(MENU_CHARACTERS_SIZE, 0x0400, menu_data); 136 | } 137 | 138 | void main_start_bin(uint8_t unused) 139 | { 140 | rom_reset_vector_write(ram_bin_addr_get()); 141 | main_reset(0); 142 | } 143 | 144 | void main_store_bin(uint8_t unused) 145 | { 146 | menu_bin_store(); 147 | } 148 | 149 | void main_menu_select(uint8_t unused) 150 | { 151 | uint8_t line_number; 152 | ram_data_get(1, 37, &line_number); 153 | menu_bin_select(line_number); 154 | ram_bin_addr_set(menu_bin_addr_get()); 155 | uint16_t bin_size = menu_bin_size_get(); 156 | for (int i = 0; i < bin_size; i++) 157 | { 158 | ram_bin_data_set(menu_bin_data_get()); 159 | } 160 | main_start_bin(0); 161 | } 162 | 163 | void main_core1(void) 164 | { 165 | while (1) 166 | { 167 | if (reset == true) 168 | { 169 | reset = false; 170 | c6502_reset(&interface_c); 171 | } 172 | 173 | if (running) 174 | { 175 | c6502_update(&interface_c); 176 | 177 | ram_update(interface_c.rw, interface_c.address, &interface_c.data); 178 | rom_update(interface_c.rw, interface_c.address, &interface_c.data); 179 | keyboard_update(interface_c.rw, interface_c.address, &interface_c.data); 180 | game_update(interface_c.rw, interface_c.address, &interface_c.data); 181 | speaker_update(interface_c.rw, interface_c.address, &interface_c.data); 182 | video_update(interface_c.rw, interface_c.address, &interface_c.data); 183 | } 184 | } 185 | } 186 | 187 | int main(void) 188 | { 189 | clock_init(); 190 | test_pin_init(); 191 | serial_init(); 192 | joystick_init(); 193 | key_init(); 194 | 195 | main_init(); 196 | 197 | multicore_launch_core1(main_core1); 198 | 199 | vga_init(); 200 | 201 | while (1) 202 | { 203 | vga_wait_for_new_overscan_line(); 204 | 205 | scan_line = vga_scan_line_get(); 206 | video_scan_line_set(scan_line); 207 | overscan_line_odd = vga_overscan_line_is_odd(); 208 | 209 | key_update(); 210 | 211 | if (overscan_line_odd) 212 | { 213 | video_buffer_get(vga_scan_line_buffer()); 214 | } 215 | else 216 | { 217 | video_buffer_clear(); 218 | video_address = video_address_get(); 219 | ram_data_get(VIDEO_BYTES_PER_LINE, video_address, video_line_data); 220 | video_line_data_get(video_line_data); 221 | } 222 | 223 | serial_update(&serial_operation, &operation_data); 224 | (*main_serial_operation[serial_operation]) (operation_data); 225 | 226 | key_command(&key_operation, &operation_data); 227 | (*main_key_operation[key_operation]) (operation_data); 228 | 229 | if (vga_scan_line_get() == 0) 230 | { 231 | test_pin_high(); 232 | joystick_update(); 233 | game_btn0_set(joystick_btn0_get()); 234 | game_btn1_set(joystick_btn1_get()); 235 | game_pdl0_set(joystick_pdl0_get()); 236 | game_pdl1_set(joystick_pdl1_get()); 237 | 238 | serial_state_send(); 239 | 240 | key_scan_start(); 241 | 242 | test_pin_low(); 243 | } 244 | 245 | if (scan_line == 0 && key_data_waiting()) 246 | { 247 | keyboard_key_code_set(key_data_get()); 248 | } 249 | } 250 | } -------------------------------------------------------------------------------- /main.h: -------------------------------------------------------------------------------- 1 | #ifndef __MAIN_H__ 2 | #define __MAIN_H__ 3 | 4 | #include 5 | 6 | void main_null(uint8_t unused); 7 | void main_reboot(uint8_t unused); 8 | void main_reset(uint8_t unused); 9 | void main_pause(uint8_t unused); 10 | void main_resume(uint8_t unused); 11 | void main_menu(uint8_t unused); 12 | void main_bin_addr_lsb_set(uint8_t data); 13 | void main_bin_addr_msb_set(uint8_t data); 14 | void main_bin_data_set(uint8_t data); 15 | void main_start_bin(uint8_t unused); 16 | void main_menu_select(uint8_t unused); 17 | void main_store_bin(uint8_t unused); 18 | #endif /* __MAIN_H__ */ 19 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """ 3 | pico-iie emulator binary downloader 4 | """ 5 | 6 | import os 7 | import time 8 | import numpy 9 | import sys 10 | import serial 11 | 12 | bin_name = "" 13 | banks = "0123456789ABCDEFGHIJKLMN" 14 | bank = 0 15 | store = False 16 | file_name = " " 17 | 18 | SERIAL_BIN_DATA = 0x82 19 | SERIAL_SIZE_LSB = 0x83 20 | SERIAL_SIZE_MSB = 0x84 21 | SERIAL_ADDR_LSB = 0x85 22 | SERIAL_ADDR_MSB = 0x86 23 | SERIAL_REBOOT = 0x87 24 | SERIAL_BANK = 0x88 25 | SERIAL_NAME = 0x89 26 | SERIAL_BIN_START = 0x8A 27 | SERIAL_BIN_STORE = 0x8B 28 | 29 | FILE_NAME_LENGTH = 27 30 | 31 | BAUDRATE = 115200 32 | COM_PORT = '/dev/ttyUSB0' 33 | ser = serial.Serial(COM_PORT, baudrate=BAUDRATE, rtscts=False) 34 | 35 | # wait for byte returned from HC-06 36 | while ser.inWaiting() == 0: 37 | pass 38 | ser.flush() 39 | 40 | try: 41 | arg_name = str(sys.argv[1]) 42 | file_name = arg_name[:-9] + file_name 43 | file_ext = arg_name[-3:] 44 | 45 | if len(sys.argv) > 2: 46 | arg_bank = str(sys.argv[2])[0:1] 47 | bank = banks.find(arg_bank) 48 | if bank < 0: 49 | bank = 0 50 | store = True 51 | print("bank:", bank) 52 | else: 53 | print("no bank specified") 54 | if file_ext == 'bin': 55 | bin_name = arg_name 56 | print ("file name:", file_name) 57 | except: 58 | pass 59 | 60 | if bin_name != "": 61 | # read bin file on startup 62 | ser.flush() 63 | 64 | bin_cmd = bytearray() 65 | bin_cmd.append(SERIAL_REBOOT) 66 | ser.write(bin_cmd) 67 | 68 | time.sleep(0.5) 69 | 70 | bin_image = open(bin_name, 'rb') 71 | 72 | file_size = os.path.getsize(bin_name) 73 | file_size_hex = hex(file_size) 74 | file_size_lsb = int(file_size_hex[-2:], 16) 75 | file_size_msb = int(file_size_hex[-4:-2], 16) 76 | 77 | result = bin_name.index('.') 78 | bin_address_lsb = int(bin_name[result - 2: result], 16) 79 | bin_address_msb = int(bin_name[result - 4: result - 2], 16) 80 | 81 | bin_cmd = bytearray() 82 | bin_cmd.append(SERIAL_BANK) 83 | bin_cmd.append(bank) 84 | ser.write(bin_cmd) 85 | 86 | bin_cmd = bytearray() 87 | bin_cmd.append(SERIAL_NAME) 88 | for i in range(FILE_NAME_LENGTH + 1): 89 | bin_cmd.append(ord(file_name[i])) 90 | ser.write(bin_cmd) 91 | 92 | bin_cmd = bytearray() 93 | bin_cmd.append(SERIAL_SIZE_LSB) 94 | bin_cmd.append(file_size_lsb) 95 | ser.write(bin_cmd) 96 | 97 | bin_cmd = bytearray() 98 | bin_cmd.append(SERIAL_SIZE_MSB) 99 | bin_cmd.append(file_size_msb) 100 | ser.write(bin_cmd) 101 | 102 | bin_cmd = bytearray() 103 | bin_cmd.append(SERIAL_ADDR_LSB) 104 | bin_cmd.append(bin_address_lsb) 105 | ser.write(bin_cmd) 106 | 107 | bin_cmd = bytearray() 108 | bin_cmd.append(SERIAL_ADDR_MSB) 109 | bin_cmd.append(bin_address_msb) 110 | ser.write(bin_cmd) 111 | 112 | bin_cmd = bytearray() 113 | bin_cmd.append(SERIAL_BIN_DATA) 114 | ser.write(bin_cmd) 115 | 116 | bin_file = bytearray() 117 | 118 | 119 | while 1: 120 | 121 | # read by character 122 | char = bin_image.read(1) 123 | 124 | if not char: 125 | break 126 | 127 | bin_data = ord(char) 128 | 129 | bin_file.append(bin_data) 130 | 131 | # add one byte at end 132 | bin_file.append(0) 133 | 134 | if store == True: 135 | bin_file.append(SERIAL_BIN_STORE) 136 | else: 137 | bin_file.append(SERIAL_BIN_START) 138 | 139 | bin_file.append(0) 140 | 141 | bin_image.close() 142 | 143 | ser.flush() 144 | ser.write(bin_file) 145 | time.sleep(2) 146 | 147 | print('bin file name:', bin_name) 148 | print('bin file size:',file_size, 'bytes') 149 | 150 | ser.flush() 151 | ser.close() 152 | print("end serial") 153 | -------------------------------------------------------------------------------- /mcu/clock.c: -------------------------------------------------------------------------------- 1 | #include "clock.h" 2 | #include "pico/stdlib.h" 3 | 4 | void clock_init(void) 5 | { 6 | vreg_set_voltage(VREG_VOLTAGE_1_30); 7 | set_sys_clock_khz(CLK_FREQUENCY_KHZ, true); 8 | } 9 | -------------------------------------------------------------------------------- /mcu/clock.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __CLOCK_H__ 3 | #define __CLOCK_H__ 4 | 5 | #define VREG_VOLTAGE_1_30 0b1111 // 1.30v 6 | #define CLK_FREQUENCY_HZ 420000000 // overclocking at 420MHz 7 | #define CLK_FREQUENCY_KHZ (CLK_FREQUENCY_HZ / 1000) 8 | 9 | void clock_init(void); 10 | 11 | #endif /* __CLOCK_H__ */ 12 | -------------------------------------------------------------------------------- /mcu/joystick.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "joystick.h" 5 | #include "hardware/adc.h" 6 | #include "pico/stdlib.h" 7 | 8 | #define JOYSTICK_SW0_PIN 20 9 | #define JOYSTICK_SW1_PIN 22 10 | #define JOYSTICK_SW2_PIN 21 11 | #define JOYSTICK_SW3_PIN 19 12 | #define JOYSTICK_X_PIN 27 13 | #define JOYSTICK_Y_PIN 26 14 | #define JOYSTICK_X_ADC 1 15 | #define JOYSTICK_Y_ADC 0 16 | 17 | #define JOYSTICK_ADC_FULL_COUNT 4095 18 | #define JOYSTICK_ADC_HALF_COUNT (JOYSTICK_ADC_FULL_COUNT >> 1) 19 | 20 | #define JOYSTICK_PDL_FULL_COUNT 255 21 | 22 | #define JOYSTICK_FULL_COUNT (JOYSTICK_ADC_FULL_COUNT * JOYSTICK_PDL_FULL_COUNT) 23 | 24 | static uint8_t joystick_btn0 = 0; 25 | static uint8_t joystick_btn1 = 0; 26 | static uint8_t joystick_btn0n = 0; 27 | static uint8_t joystick_btn1n = 0; 28 | static uint8_t joystick_pdl0 = 0; 29 | static uint8_t joystick_pdl1 = 0; 30 | 31 | void joystick_init(void) 32 | { 33 | gpio_init(JOYSTICK_SW0_PIN); 34 | gpio_init(JOYSTICK_SW1_PIN); 35 | gpio_init(JOYSTICK_SW2_PIN); 36 | gpio_init(JOYSTICK_SW3_PIN); 37 | 38 | gpio_set_dir(JOYSTICK_SW0_PIN, GPIO_IN); 39 | gpio_set_dir(JOYSTICK_SW1_PIN, GPIO_IN); 40 | gpio_set_dir(JOYSTICK_SW2_PIN, GPIO_IN); 41 | gpio_set_dir(JOYSTICK_SW3_PIN, GPIO_IN); 42 | 43 | gpio_pull_down(JOYSTICK_SW0_PIN); 44 | gpio_pull_down(JOYSTICK_SW1_PIN); 45 | gpio_pull_up(JOYSTICK_SW2_PIN); 46 | gpio_pull_up(JOYSTICK_SW3_PIN); 47 | 48 | adc_init(); 49 | gpio_set_dir(JOYSTICK_X_PIN, GPIO_IN); 50 | gpio_set_dir(JOYSTICK_Y_PIN, GPIO_IN); 51 | adc_gpio_init(JOYSTICK_X_PIN); 52 | adc_gpio_init(JOYSTICK_Y_PIN); 53 | } 54 | 55 | void joystick_update(void) 56 | { 57 | joystick_btn0 = gpio_get(JOYSTICK_SW0_PIN) ? 1 : 0; 58 | joystick_btn1 = gpio_get(JOYSTICK_SW1_PIN) ? 1 : 0; 59 | joystick_btn0n = gpio_get(JOYSTICK_SW2_PIN) ? 0 : 1; 60 | joystick_btn1n = gpio_get(JOYSTICK_SW3_PIN) ? 0 : 1; 61 | 62 | adc_select_input(JOYSTICK_X_ADC); 63 | uint16_t joy_x = adc_read(); 64 | adc_select_input(JOYSTICK_Y_ADC); 65 | uint16_t joy_y = adc_read(); 66 | 67 | joystick_pdl0 = JOYSTICK_PDL_FULL_COUNT; 68 | joystick_pdl1 = JOYSTICK_PDL_FULL_COUNT; 69 | 70 | if (joy_x > JOYSTICK_ADC_HALF_COUNT) 71 | { 72 | joystick_pdl0 = JOYSTICK_FULL_COUNT / joy_x - JOYSTICK_PDL_FULL_COUNT; 73 | } 74 | 75 | if (joy_y > JOYSTICK_ADC_HALF_COUNT) 76 | { 77 | joystick_pdl1 = JOYSTICK_FULL_COUNT / joy_y - JOYSTICK_PDL_FULL_COUNT; 78 | } 79 | } 80 | 81 | uint8_t joystick_btn0_get(void) 82 | { 83 | return joystick_btn0 | joystick_btn0n; 84 | } 85 | 86 | uint8_t joystick_btn1_get(void) 87 | { 88 | return joystick_btn1 | joystick_btn1n; 89 | } 90 | 91 | uint8_t joystick_pdl0_get(void) 92 | { 93 | return joystick_pdl0; 94 | } 95 | 96 | uint8_t joystick_pdl1_get(void) 97 | { 98 | return joystick_pdl1; 99 | } 100 | -------------------------------------------------------------------------------- /mcu/joystick.h: -------------------------------------------------------------------------------- 1 | #ifndef __JOYSTICK_H__ 2 | #define __JOYSTICK_H__ 3 | 4 | void joystick_init(void); 5 | void joystick_update(void); 6 | uint8_t joystick_btn0_get(void); 7 | uint8_t joystick_btn1_get(void); 8 | uint8_t joystick_pdl0_get(void); 9 | uint8_t joystick_pdl1_get(void); 10 | 11 | #endif /* __JOYSTICK_H__ */ 12 | -------------------------------------------------------------------------------- /mcu/key.c: -------------------------------------------------------------------------------- 1 | // Includes ------------------------------------------------------------------- 2 | #include 3 | #include 4 | #include 5 | #include "key.h" 6 | #include "pico/stdlib.h" 7 | 8 | // Definitions ---------------------------------------------------------------- 9 | #define KEY_DATA_PIN 14 10 | #define KEY_SCK_PIN 15 11 | #define KEY_MATRIX_MASK 0x7F 12 | #define KEY_MATRIX_TOTAL (KEY_MATRIX_MASK + 1) 13 | #define KEY_MATRIX_VALID (KEY_MATRIX_TOTAL - 0x10) 14 | #define KEY_PRESSES_RESET 0 15 | #define KEY_PRESSES_MAX 16 16 | 17 | #define KEY_REPEAT_DELAY_SCANS 48 18 | #define KEY_REPEAT_SCANS 4 19 | #define KEY_REPEAT_SCAN_COUNT (KEY_REPEAT_DELAY_SCANS + KEY_REPEAT_SCANS) 20 | 21 | // Apple IIe keyboard codes 22 | #define UP 0x0B 23 | #define DOWN 0x0A 24 | #define LEFT 0x08 25 | #define RGHT 0x15 26 | #define RTN 0x0D 27 | #define TAB 0x09 28 | #define ESC 0x1B 29 | #define DEL 0x7F 30 | 31 | // Matrix scan codes index 32 | #define KEY_SHIFT 0x60 33 | #define KEY_CTRL 0x38 34 | #define KEY_CAPS_LOCK 0x28 35 | #define KEY_RESET 0x48 36 | #define KEY_ESC 0x07 37 | #define KEY_TAB 0x04 38 | #define KEY_DEL 0x5D 39 | #define KEY_RTN 0x58 40 | 41 | #define KEY_OFFSET_CAPS_LOCK_OFF 0x000 42 | #define KEY_OFFSET_CAPS_LOCK_ON 0x080 43 | #define KEY_OFFSET_CAPS_SHIFT 0x100 44 | 45 | #define KEY_DATA_EMPTY 0 46 | #define KEY_DATA_READY 1 47 | #define KEY_USED_FALSE 0 48 | #define KEY_USED_TRUE 1 49 | 50 | #define KEY_SWITCH_CLOSED 0 51 | 52 | // Consts --------------------------------------------------------------------- 53 | static const uint8_t key_iie[KEY_MATRIX_TOTAL * 4] = 54 | { 55 | // caps lock off 56 | 57 | //0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 58 | 0x00, 0x00, 'z', 0x00, TAB, 0x00, 'a', ESC, //0x0 59 | 0x00, 0x00, 'x', 0x00, 'q', 0x00, 'd', '1', //0x1 60 | 0x00, 0x00, 'c', 0x00, 'w', 0x00, 's', '2', //0x2 61 | 0x00, 0x00, 'v', 0x00, 'e', 0x00, 'h', '3', //0x3 62 | 0x00, 0x00, 'b', 0x00, 'r', 0x00, 'f', '4', //0x4 63 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x5 64 | 0x00, 0x00, 'n', 0x00, 'y', 0x00, 'g', '6', //0x6 65 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x7 66 | ' ', '0', '.', '[', 'i', LEFT, ';', '8', //0x8 67 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x9 68 | '\'', '-', '/', ']', 'o', RGHT, 'l', '9', //0xA 69 | RTN, '\\', 'm', '`', 't', DEL, 'j', '5', //0xB 70 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0xC 71 | UP, '=', ',', 'p', 'u', DOWN, 'k', '7', //0xD 72 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0xE 73 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0xF 74 | 75 | // caps lock on 76 | 77 | //0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 78 | 0x00, 0x00, 'Z', 0x00, TAB, 0x00, 'A', ESC, //0x0 79 | 0x00, 0x00, 'X', 0x00, 'Q', 0x00, 'D', '1', //0x1 80 | 0x00, 0x00, 'C', 0x00, 'W', 0x00, 'S', '2', //0x2 81 | 0x00, 0x00, 'V', 0x00, 'E', 0x00, 'H', '3', //0x3 82 | 0x00, 0x00, 'B', 0x00, 'R', 0x00, 'F', '4', //0x4 83 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x5 84 | 0x00, 0x00, 'N', 0x00, 'Y', 0x00, 'G', '6', //0x6 85 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x7 86 | ' ', '0', '.', '[', 'I', LEFT, ';', '8', //0x8 87 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x9 88 | '\'', '-', '/', ']', 'O', RGHT, 'L', '9', //0xA 89 | RTN, '\\', 'M', '`', 'T', DEL, 'J', '5', //0xB 90 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0xC 91 | UP, '=', ',', 'P', 'U', DOWN, 'K', '7', //0xD 92 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0xE 93 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0xF 94 | 95 | // shift + caps lock off 96 | 97 | //0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 98 | 0x00, 0x00, 'Z', 0x00, TAB, 0x00, 'A', ESC, //0x0 99 | 0x00, 0x00, 'X', 0x00, 'Q', 0x00, 'D', '!', //0x1 100 | 0x00, 0x00, 'C', 0x00, 'W', 0x00, 'S', '@', //0x2 101 | 0x00, 0x00, 'V', 0x00, 'E', 0x00, 'H', '#', //0x3 102 | 0x00, 0x00, 'B', 0x00, 'R', 0x00, 'F', '$', //0x4 103 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x5 104 | 0x00, 0x00, 'N', 0x00, 'Y', 0x00, 'G', '^', //0x6 105 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x7 106 | ' ', ')', '>', '{', 'I', LEFT, ':', '*', //0x8 107 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x9 108 | '\"', '_', '?', '}', 'O', RGHT, 'L', '(', //0xA 109 | RTN, '|', 'M', '~', 'T', DEL, 'J', '%', //0xB 110 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0xC 111 | UP, '+', ',', 'P', 'U', DOWN, 'K', '&', //0xD 112 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0xE 113 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0xF 114 | 115 | // shift + caps lock on 116 | 117 | //0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 118 | 0x00, 0x00, 'Z', 0x00, TAB, 0x00, 'A', ESC, //0x0 119 | 0x00, 0x00, 'X', 0x00, 'Q', 0x00, 'D', '!', //0x1 120 | 0x00, 0x00, 'C', 0x00, 'W', 0x00, 'S', '@', //0x2 121 | 0x00, 0x00, 'V', 0x00, 'E', 0x00, 'H', '#', //0x3 122 | 0x00, 0x00, 'B', 0x00, 'R', 0x00, 'F', '$', //0x4 123 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x5 124 | 0x00, 0x00, 'N', 0x00, 'Y', 0x00, 'G', '^', //0x6 125 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x7 126 | ' ', ')', '>', '{', 'I', LEFT, ':', '*', //0x8 127 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x9 128 | '\"', '_', '?', '}', 'O', RGHT, 'L', '(', //0xA 129 | RTN, '|', 'M', '~', 'T', DEL, 'J', '%', //0xB 130 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0xC 131 | UP, '+', ',', 'P', 'U', DOWN, 'K', '&', //0xD 132 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0xE 133 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0xF 134 | }; 135 | 136 | // Variables ------------------------------------------------------------------ 137 | static bool key_scanning = false; 138 | static uint8_t key_clk_state = 0; 139 | static uint8_t key_test = 0; 140 | static uint8_t key_index = 0; 141 | static uint8_t key_index_last = 0; 142 | static bool key_index_last_released = false; 143 | static uint8_t key_index_waiting = 0; 144 | static uint8_t key_presses_consecutive = KEY_PRESSES_RESET; 145 | static uint8_t key_repeat_scan_counter = 0; 146 | 147 | static uint8_t key_shift = 0; 148 | static uint8_t key_ctrl = 0; 149 | static uint8_t key_caplock = 0; 150 | static uint8_t menu_enabled = 0; 151 | 152 | static KeyOperation key_operation; 153 | 154 | // Helper functions ----------------------------------------------------------- 155 | 156 | void key_clk_low(void) 157 | { 158 | gpio_put(KEY_SCK_PIN, 0); 159 | } 160 | 161 | void key_clk_high(void) 162 | { 163 | gpio_put(KEY_SCK_PIN, 1); 164 | } 165 | 166 | void index_update(void) 167 | { 168 | bool end_of_scan = (key_presses_consecutive == KEY_PRESSES_MAX? true : false); 169 | 170 | if (end_of_scan) 171 | { 172 | key_index = 0; 173 | key_scanning = false; 174 | } 175 | else 176 | { 177 | key_index = (key_index + 1) & KEY_MATRIX_MASK; 178 | } 179 | } 180 | 181 | void operation_test(void) 182 | { 183 | if (menu_enabled == 1 && key_index == KEY_RTN) 184 | { 185 | menu_enabled = 0; 186 | key_operation = KEY_MAIN_MENU_SELECT; 187 | } 188 | 189 | if (key_ctrl == 1) 190 | { 191 | if (key_index == KEY_ESC) 192 | { 193 | key_operation = KEY_MAIN_PAUSE; 194 | } 195 | if (key_index == KEY_TAB) 196 | { 197 | key_operation = KEY_MAIN_RESUME; 198 | } 199 | 200 | if (key_index == KEY_DEL) 201 | { 202 | menu_enabled = 1; 203 | key_operation = KEY_MAIN_MENU; 204 | } 205 | } 206 | 207 | if (key_index == KEY_RESET) 208 | { 209 | key_operation = KEY_MAIN_RESET; 210 | } 211 | } 212 | 213 | void shift_key_test(void) 214 | { 215 | if (key_index == KEY_SHIFT) 216 | { 217 | key_shift = key_test; 218 | } 219 | } 220 | 221 | void ctrl_key_test(void) 222 | { 223 | if (key_index == KEY_CTRL) 224 | { 225 | key_ctrl = key_test; 226 | } 227 | } 228 | 229 | void caps_lock_key_test(void) 230 | { 231 | if (key_index == KEY_CAPS_LOCK) 232 | { 233 | key_caplock = key_test; 234 | } 235 | } 236 | 237 | // Functions ------------------------------------------------------------------ 238 | void key_init(void) 239 | { 240 | gpio_init(KEY_DATA_PIN); 241 | gpio_init(KEY_SCK_PIN); 242 | gpio_set_dir(KEY_DATA_PIN, GPIO_IN); 243 | gpio_set_dir(KEY_SCK_PIN, GPIO_OUT); 244 | } 245 | 246 | void key_scan_start(void) 247 | { 248 | key_scanning = true; 249 | } 250 | 251 | void key_update(void) 252 | { 253 | if (key_scanning == false) 254 | { 255 | return; 256 | } 257 | 258 | key_clk_state ^= 1; 259 | if (key_clk_state) 260 | { 261 | key_clk_high(); 262 | return; 263 | } 264 | 265 | key_clk_low(); 266 | 267 | key_test = gpio_get(KEY_DATA_PIN) == KEY_SWITCH_CLOSED? 1 : 0; 268 | if (key_test) 269 | { 270 | key_presses_consecutive++; 271 | 272 | operation_test(); 273 | 274 | // key_index_last_released 275 | if ((key_index < KEY_MATRIX_VALID) && (key_index_last_released == true)) 276 | { 277 | if (key_iie[(uint16_t)key_index] != 0) 278 | { 279 | key_index_waiting = key_index; 280 | key_index_last_released = false; 281 | } 282 | } 283 | } 284 | else 285 | { 286 | if (key_index_last == key_index) 287 | { 288 | key_index_last_released = true; 289 | key_index_last = 0; 290 | } 291 | key_presses_consecutive = KEY_PRESSES_RESET; 292 | } 293 | 294 | shift_key_test(); 295 | ctrl_key_test(); 296 | caps_lock_key_test(); 297 | 298 | index_update(); 299 | 300 | } 301 | 302 | void key_command(KeyOperation *operation, uint8_t *data) 303 | { 304 | *operation = key_operation; 305 | key_operation = KEY_MAIN_NULL; 306 | *data = 0; 307 | } 308 | 309 | uint8_t key_data_waiting(void) 310 | { 311 | return key_index_waiting; 312 | } 313 | 314 | uint8_t key_data_get(void) 315 | { 316 | uint8_t key = 0; 317 | uint16_t key_iie_offset = KEY_OFFSET_CAPS_LOCK_OFF; 318 | 319 | key_iie_offset |= key_caplock * KEY_OFFSET_CAPS_LOCK_ON; 320 | key_iie_offset |= key_shift * KEY_OFFSET_CAPS_SHIFT; 321 | 322 | key = key_iie[(uint16_t)key_index_waiting + key_iie_offset]; 323 | key_index_last = key_index_waiting; 324 | key_index_waiting = 0; 325 | return key; 326 | } 327 | -------------------------------------------------------------------------------- /mcu/key.h: -------------------------------------------------------------------------------- 1 | // one keyboard scan per screen refresh (60Hz) of 16ms 2 | // 3600 PRO Keyboard decoder emulation 3 | // debounce of 7ms to 13ms (one scan is 16ms) 4 | // roll over lockout - if second key is pressed it is locked out until 5 | // current key is released. 6 | // key held down for 534 to 801 ms before auto repeat (48 scans) 7 | // auto repeat at 15 Hz (every 4 scans) 8 | 9 | #ifndef __KEY_H__ 10 | #define __KEY_H__ 11 | 12 | typedef enum 13 | { 14 | KEY_MAIN_NULL = 0, 15 | KEY_MAIN_PAUSE, 16 | KEY_MAIN_RESUME, 17 | KEY_MAIN_RESET, 18 | KEY_MAIN_MENU, 19 | KEY_MAIN_MENU_SELECT, 20 | KEY_OPERATIONS_TOTAL, 21 | } KeyOperation; 22 | 23 | void key_init(void); 24 | void key_scan_start(void); 25 | void key_update(void); 26 | void key_command(KeyOperation *operation, uint8_t *data); 27 | uint8_t key_data_waiting(void); 28 | uint8_t key_data_get(void); 29 | 30 | #endif /* __KEY_H__ */ 31 | -------------------------------------------------------------------------------- /mcu/menu.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "menu.h" 6 | #include "hardware/flash.h" 7 | #include "hardware/sync.h" 8 | #include "pico/stdlib.h" 9 | 10 | #define MENU_BANKS_TOTAL 24 11 | #define MENU_BANKS_SELECT_LAST (MENU_BANKS_TOTAL - 1) 12 | #define MENU_BANKS_SELECT_DEFAULT (MENU_BANKS_SELECT_LAST / 2) 13 | #define MENU_BANK_NUMBER_LENGTH 1 14 | #define MENU_NAME_LENGTH 27 15 | #define MENU_HEX_LENGTH 4 16 | #define MENU_ITEM_SPACING 1 17 | #define MENU_BANK_NUMBER_COLUMN (MENU_ITEM_SPACING) 18 | #define MENU_FILE_NAME_COLUMN (MENU_BANK_NUMBER_COLUMN +MENU_ITEM_SPACING + MENU_BANK_NUMBER_LENGTH) 19 | #define MENU_FILE_SIZE_COLUMN (MENU_FILE_NAME_COLUMN + MENU_ITEM_SPACING + MENU_NAME_LENGTH) 20 | #define MENU_BIN_ADDRESS_COLUMN (MENU_FILE_SIZE_COLUMN + MENU_ITEM_SPACING + MENU_HEX_LENGTH) 21 | #define MENU_CHARACTER_OFFSET 128 22 | #define MENU_BIN_LENGTH 0xC000 23 | #define MENU_PAGE_LENGTH (MENU_BIN_LENGTH + MENU_NAME_LENGTH + 5) 24 | 25 | // FLASH_SECTOR_SIZE 0x1000 26 | #define FLASH_WRITE_SIZE ((MENU_PAGE_LENGTH / FLASH_PAGE_SIZE) + 1) // 0xC1 27 | #define FLASH_SECTOR_COUNT (((FLASH_WRITE_SIZE * FLASH_PAGE_SIZE) / FLASH_SECTOR_SIZE) + 1) // 0x0D 28 | #define FLASH_BANK_SIZE (FLASH_SECTOR_SIZE * FLASH_SECTOR_COUNT) // 0xD000 29 | #define FLASH_PROGRAM_SIZE (FLASH_PAGE_SIZE * FLASH_WRITE_SIZE) // 0xC100 30 | 31 | // 0xD000 x 24 = 1277952, 1277952 / 1024 = 1248k 32 | #define FLASH_TARGET_OFFSET (512 * 1024) // choosing to start at 512K 33 | #define FLASH_TARGET_BASE (XIP_BASE + FLASH_TARGET_OFFSET) 34 | 35 | static uint8_t menu[MENU_CHARACTERS_SIZE]; 36 | const static uint8_t menu_select[MENU_BANKS_TOTAL] = 37 | { 38 | '0', '1', '2', '3', '4', '5', '6', '7', 39 | '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 40 | 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 41 | }; 42 | const static uint16_t line[] = 43 | { 44 | 0x000, 0x080, 0x100, 0x180, 0x200, 0x280, 0x300, 0x380, 45 | 0x028, 0x0A8, 0x128, 0x1A8, 0x228, 0x2A8, 0x328, 0x3A8, 46 | 0x050, 0x0D0, 0x150, 0x1D0, 0x250, 0x2D0, 0x350, 0x3D0, 47 | }; 48 | 49 | static uint8_t name_index = 0; 50 | static uint16_t binary_index = 0; 51 | 52 | struct __attribute__((__packed__)) storage 53 | { 54 | struct __attribute__((__packed__)) menu 55 | { 56 | uint8_t bank; 57 | uint8_t name[MENU_NAME_LENGTH]; 58 | uint16_t bin_size; 59 | uint16_t address; 60 | } menu; 61 | uint8_t binary[MENU_BIN_LENGTH]; 62 | } storage; 63 | 64 | void flash_data_save(uint8_t bank) 65 | { 66 | const uint8_t *data = (const uint8_t *) &storage; 67 | uint32_t flash_offset = FLASH_TARGET_OFFSET + bank * FLASH_BANK_SIZE; 68 | uint32_t interrupts = save_and_disable_interrupts(); 69 | flash_range_erase(flash_offset, FLASH_BANK_SIZE); 70 | flash_range_program(flash_offset, data, FLASH_PROGRAM_SIZE); 71 | restore_interrupts(interrupts); 72 | } 73 | 74 | void flash_menu_read(uint8_t bank) 75 | { 76 | const uint8_t* flash_target_contents = (const uint8_t *) (FLASH_TARGET_BASE + bank * FLASH_BANK_SIZE); 77 | memcpy(&storage.menu, flash_target_contents, MENU_PAGE_LENGTH); 78 | } 79 | 80 | void flash_data_read(uint8_t bank) 81 | { 82 | const uint8_t* flash_target_contents = (const uint8_t *) (FLASH_TARGET_BASE + bank * FLASH_BANK_SIZE); 83 | memcpy(&storage, flash_target_contents, MENU_PAGE_LENGTH); 84 | } 85 | 86 | void menu_str_print(uint8_t *str, uint8_t x, uint8_t y) 87 | { 88 | for (int i = 0; i < MENU_NAME_LENGTH; i++) 89 | { 90 | if (str[i] >= MENU_CHARACTER_OFFSET) 91 | { 92 | str[i] = '.'; 93 | } 94 | menu[line[y] + x + i] = str[i] + MENU_CHARACTER_OFFSET; 95 | } 96 | } 97 | 98 | void menu_hex_print(uint16_t value, uint8_t x, uint8_t y) 99 | { 100 | menu[line[y] + x] = menu_select[(value >> 12) & 0x0F] + MENU_CHARACTER_OFFSET; 101 | menu[line[y] + x + 1] = menu_select[(value >> 8) & 0x0F] + MENU_CHARACTER_OFFSET; 102 | menu[line[y] + x + 2] = menu_select[(value >> 4) & 0x0F] + MENU_CHARACTER_OFFSET; 103 | menu[line[y] + x + 3] = menu_select[(value) & 0x0F] + MENU_CHARACTER_OFFSET; 104 | } 105 | 106 | void menu_select_update(void) 107 | { 108 | uint8_t menu_char; 109 | for (int i = 0; i < sizeof(menu_select); i++) 110 | { 111 | menu_char = menu_select[i] + MENU_CHARACTER_OFFSET; 112 | menu[line[i] + MENU_BANK_NUMBER_COLUMN] = menu_char; 113 | } 114 | } 115 | 116 | void menu_init(void) 117 | { 118 | memset(menu, ' ' + MENU_CHARACTER_OFFSET, MENU_CHARACTERS_SIZE); 119 | for (int i = 0; i < sizeof(menu_select); i++) 120 | { 121 | flash_menu_read(i); 122 | menu_str_print(storage.menu.name, MENU_FILE_NAME_COLUMN, i); 123 | menu_hex_print(storage.menu.bin_size, MENU_FILE_SIZE_COLUMN, i); 124 | menu_hex_print(storage.menu.address, MENU_BIN_ADDRESS_COLUMN, i); 125 | } 126 | 127 | menu_select_update(); 128 | } 129 | 130 | void menu_data_get(uint8_t *data) 131 | { 132 | memcpy(data, &menu[0], MENU_CHARACTERS_SIZE); 133 | } 134 | 135 | void menu_bank_set(uint8_t data) 136 | { 137 | storage.menu.bank = data; 138 | name_index = 0; 139 | binary_index = 0; 140 | } 141 | 142 | void menu_name_set(uint8_t data) 143 | { 144 | storage.menu.name[name_index] = data; 145 | name_index++; 146 | if (name_index == MENU_NAME_LENGTH) 147 | { 148 | name_index = 0; 149 | } 150 | } 151 | 152 | void menu_bin_size_lsb_set(uint8_t data) 153 | { 154 | storage.menu.bin_size &= 0xFF00; 155 | storage.menu.bin_size |= data; 156 | } 157 | 158 | void menu_bin_size_msb_set(uint8_t data) 159 | { 160 | storage.menu.bin_size &= 0x00FF; 161 | storage.menu.bin_size |= (((uint16_t)data) << 8); 162 | } 163 | 164 | void menu_bin_addr_lsb_set(uint8_t data) 165 | { 166 | storage.menu.address &= 0xFF00; 167 | storage.menu.address |= data; 168 | } 169 | 170 | void menu_bin_addr_msb_set(uint8_t data) 171 | { 172 | storage.menu.address &= 0x00FF; 173 | storage.menu.address |= (((uint16_t)data) << 8); 174 | } 175 | 176 | void menu_bin_data_set(uint8_t data) 177 | { 178 | storage.binary[binary_index] = data; 179 | binary_index++; 180 | if (binary_index == MENU_BIN_LENGTH) 181 | { 182 | binary_index = 0; 183 | } 184 | } 185 | 186 | uint16_t menu_bin_size_get(void) 187 | { 188 | return storage.menu.bin_size; 189 | } 190 | 191 | uint16_t menu_bin_addr_get(void) 192 | { 193 | return storage.menu.address; 194 | } 195 | 196 | uint8_t menu_bin_data_get(void) 197 | { 198 | uint8_t data = storage.binary[binary_index]; 199 | binary_index++; 200 | if (binary_index == MENU_BIN_LENGTH) 201 | { 202 | binary_index = 0; 203 | } 204 | return data; 205 | } 206 | 207 | void menu_bin_store(void) 208 | { 209 | flash_data_save(storage.menu.bank); 210 | } 211 | 212 | void menu_bin_select(uint8_t bank_select) 213 | { 214 | flash_data_read(bank_select); 215 | binary_index = 0; 216 | } -------------------------------------------------------------------------------- /mcu/menu.h: -------------------------------------------------------------------------------- 1 | #ifndef __MENU_H__ 2 | #define __MENU_H__ 3 | 4 | #define MENU_CHARACTERS_SIZE 0x400 5 | 6 | void menu_init(void); 7 | void menu_data_get(uint8_t *data); 8 | void menu_bank_set(uint8_t data); 9 | void menu_name_set(uint8_t data); 10 | void menu_bin_size_lsb_set(uint8_t data); 11 | void menu_bin_size_msb_set(uint8_t data); 12 | void menu_bin_addr_lsb_set(uint8_t data); 13 | void menu_bin_addr_msb_set(uint8_t data); 14 | void menu_bin_data_set(uint8_t data); 15 | uint16_t menu_bin_size_get(void); 16 | uint16_t menu_bin_addr_get(void); 17 | uint8_t menu_bin_data_get(void); 18 | void menu_bin_store(void); 19 | void menu_bin_select(uint8_t bank_select); 20 | 21 | #endif /* __MENU_H__ */ 22 | -------------------------------------------------------------------------------- /mcu/serial.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "serial.h" 3 | #include "pico/stdlib.h" 4 | 5 | #define SERIAL_NAME_LENGTH 27 6 | 7 | typedef enum 8 | { 9 | SERIAL_READY = 0x81, 10 | SERIAL_BIN = 0x82, 11 | SERIAL_SIZE_LSB = 0x83, 12 | SERIAL_SIZE_MSB = 0x84, 13 | SERIAL_ADDR_LSB = 0x85, 14 | SERIAL_ADDR_MSB = 0x86, 15 | SERIAL_REBOOT = 0x87, 16 | SERIAL_BANK = 0x88, 17 | SERIAL_NAME = 0x89, 18 | SERIAL_BIN_START = 0x8A, 19 | SERIAL_BIN_STORE = 0x8B, 20 | } SerialMode; 21 | 22 | static SerialMode serial_loader = SERIAL_READY; 23 | static uint16_t bin_data_length = 0; 24 | static uint16_t bin_data_counter = 0; 25 | static uint16_t name_data_counter = 0; 26 | 27 | static uint8_t game_x = 0; 28 | static uint8_t game_y = 0; 29 | static uint8_t button_0 = 0; 30 | static uint8_t button_1 = 0; 31 | 32 | void serial_init(void) 33 | { 34 | uart_init(UART_ID, UART_BAUD_RATE); 35 | gpio_set_function(UART_TX_PIN, GPIO_FUNC_UART); 36 | gpio_set_function(UART_RX_PIN, GPIO_FUNC_UART); 37 | } 38 | 39 | void serial_update(SerialOperation *operation, uint8_t *data) 40 | { 41 | uint8_t serial_byte = 0; 42 | *operation = SERIAL_MAIN_NULL; 43 | 44 | if(uart_is_readable(UART_ID)) 45 | { 46 | serial_byte = uart_getc(UART_ID); 47 | 48 | if(serial_loader == SERIAL_BIN) 49 | { 50 | if (bin_data_counter >= bin_data_length) 51 | { 52 | serial_loader = SERIAL_READY; 53 | bin_data_counter = 0; 54 | *operation = SERIAL_MAIN_NULL; 55 | } 56 | else 57 | { 58 | bin_data_counter++; 59 | *operation = SERIAL_RAM_BIN_DATA; 60 | } 61 | } 62 | else if(serial_loader == SERIAL_NAME) 63 | { 64 | if (name_data_counter >= SERIAL_NAME_LENGTH) 65 | { 66 | serial_loader = SERIAL_READY; 67 | name_data_counter = 0; 68 | *operation = SERIAL_MAIN_NULL; 69 | } 70 | else 71 | { 72 | name_data_counter++; 73 | *operation = SERIAL_NAME_DATA; 74 | } 75 | } 76 | else if(serial_loader == SERIAL_BANK) 77 | { 78 | serial_loader = SERIAL_READY; 79 | *operation = SERIAL_MENU_BANK; 80 | } 81 | else if(serial_loader == SERIAL_SIZE_LSB) 82 | { 83 | serial_loader = SERIAL_READY; 84 | bin_data_length &= 0xFF00; 85 | bin_data_length |= serial_byte; 86 | *operation = SERIAL_RAM_BIN_SIZE_LSB; 87 | bin_data_counter = 0; 88 | } 89 | else if(serial_loader == SERIAL_SIZE_MSB) 90 | { 91 | serial_loader = SERIAL_READY; 92 | bin_data_length &= 0x00FF; 93 | bin_data_length |= (((uint16_t)serial_byte) << 8); 94 | *operation = SERIAL_RAM_BIN_SIZE_MSB; 95 | bin_data_counter = 0; 96 | } 97 | else if(serial_loader == SERIAL_ADDR_LSB) 98 | { 99 | serial_loader = SERIAL_READY; 100 | *operation = SERIAL_RAM_BIN_ADDR_LSB; 101 | } 102 | else if(serial_loader == SERIAL_ADDR_MSB) 103 | { 104 | serial_loader = SERIAL_READY; 105 | *operation = SERIAL_RAM_BIN_ADDR_MSB; 106 | } 107 | else if(serial_loader == SERIAL_READY) 108 | { 109 | if(serial_byte == SERIAL_BIN) 110 | { 111 | serial_loader = SERIAL_BIN; 112 | bin_data_counter = 0; 113 | *operation = SERIAL_RAM_BIN_RESET; 114 | } 115 | else if(serial_byte == SERIAL_SIZE_LSB) 116 | { 117 | serial_loader = SERIAL_SIZE_LSB; 118 | *operation = SERIAL_MAIN_NULL; 119 | } 120 | else if(serial_byte == SERIAL_SIZE_MSB) 121 | { 122 | serial_loader = SERIAL_SIZE_MSB; 123 | *operation = SERIAL_MAIN_NULL; 124 | } 125 | else if(serial_byte == SERIAL_ADDR_LSB) 126 | { 127 | serial_loader = SERIAL_ADDR_LSB; 128 | *operation = SERIAL_MAIN_NULL; 129 | } 130 | else if(serial_byte == SERIAL_ADDR_MSB) 131 | { 132 | serial_loader = SERIAL_ADDR_MSB; 133 | *operation = SERIAL_MAIN_NULL; 134 | } 135 | else if(serial_byte == SERIAL_NAME) 136 | { 137 | serial_loader = SERIAL_NAME; 138 | *operation = SERIAL_MAIN_NULL; 139 | } 140 | else if(serial_byte == SERIAL_BANK) 141 | { 142 | serial_loader = SERIAL_BANK; 143 | *operation = SERIAL_MAIN_NULL; 144 | } 145 | else if(serial_byte == SERIAL_REBOOT) 146 | { 147 | *operation = SERIAL_MAIN_REBOOT; 148 | } 149 | else if(serial_byte == SERIAL_BIN_START) 150 | { 151 | *operation = SERIAL_MAIN_START_BIN; 152 | } 153 | else if(serial_byte == SERIAL_BIN_STORE) 154 | { 155 | *operation = SERIAL_MAIN_BIN_STORE; 156 | } 157 | else 158 | { 159 | *operation = SERIAL_MAIN_NULL; 160 | } 161 | } 162 | } 163 | *data = serial_byte; 164 | } 165 | 166 | 167 | void serial_state_send(void) 168 | { 169 | uart_putc(UART_ID, 'A'); 170 | } 171 | -------------------------------------------------------------------------------- /mcu/serial.h: -------------------------------------------------------------------------------- 1 | #ifndef __SERIAL_H__ 2 | #define __SERIAL_H__ 3 | 4 | #include 5 | 6 | // Configuration 7 | #define UART_ID uart0 8 | #define UART_BAUD_RATE_AT_MODE 9600 9 | #define UART_BAUD_RATE 115200 10 | 11 | #define UART_TX_PIN 16 12 | #define UART_RX_PIN 17 13 | 14 | typedef enum 15 | { 16 | SERIAL_MAIN_NULL = 0, 17 | SERIAL_MAIN_REBOOT, 18 | SERIAL_MAIN_START_BIN, 19 | SERIAL_RAM_BIN_RESET, 20 | SERIAL_RAM_BIN_SIZE_LSB, 21 | SERIAL_RAM_BIN_SIZE_MSB, 22 | SERIAL_RAM_BIN_ADDR_LSB, 23 | SERIAL_RAM_BIN_ADDR_MSB, 24 | SERIAL_RAM_BIN_DATA, 25 | SERIAL_MENU_BANK, 26 | SERIAL_NAME_DATA, 27 | SERIAL_MAIN_BIN_STORE, 28 | SERIAL_OPERATIONS_TOTAL, 29 | } SerialOperation; 30 | 31 | void serial_init(void); 32 | void serial_update(SerialOperation *operation, uint8_t *data); 33 | void serial_state_send(void); 34 | 35 | #endif /* __SERIAL_H__ */ 36 | -------------------------------------------------------------------------------- /mcu/speaker.c: -------------------------------------------------------------------------------- 1 | #include "speaker.h" 2 | #include "pico/stdlib.h" 3 | 4 | #define SPEAKER_ADDR 0xC030 5 | #define SPEAKER_ADDR_ALT_MASK 0xFFF0 6 | 7 | const uint SPEAKER_PIN = SPEAKER_PIN_NUMBER; 8 | 9 | static uint8_t pin_state = 0; 10 | 11 | void speaker_init(void) 12 | { 13 | gpio_init(SPEAKER_PIN); 14 | gpio_set_dir(SPEAKER_PIN, GPIO_OUT); 15 | } 16 | 17 | void speaker_update(uint8_t read, uint16_t address, uint8_t *byte) 18 | { 19 | // read or write toggles speaker driver 20 | if ((address & SPEAKER_ADDR_ALT_MASK) == SPEAKER_ADDR) 21 | { 22 | pin_state ^= 1; 23 | gpio_put(SPEAKER_PIN, pin_state); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /mcu/speaker.h: -------------------------------------------------------------------------------- 1 | #ifndef __SPEAKER_H__ 2 | #define __SPEAKER_H__ 3 | 4 | #include 5 | 6 | // Configuration 7 | #define SPEAKER_PIN_NUMBER 28 8 | 9 | void speaker_init(void); 10 | 11 | void speaker_update(uint8_t read, uint16_t address, uint8_t *byte); 12 | 13 | #endif /* __SPEAKER_H__ */ 14 | -------------------------------------------------------------------------------- /mcu/test.c: -------------------------------------------------------------------------------- 1 | #include "test.h" 2 | #include "pico/stdlib.h" 3 | 4 | const uint TEST_PIN = TEST_PIN_NUMBER; 5 | 6 | void test_pin_init(void) 7 | { 8 | gpio_init(TEST_PIN); 9 | gpio_set_dir(TEST_PIN, GPIO_OUT); 10 | } 11 | 12 | void test_pin_low(void) 13 | { 14 | gpio_put(TEST_PIN, 0); 15 | } 16 | 17 | void test_pin_high(void) 18 | { 19 | gpio_put(TEST_PIN, 1); 20 | } -------------------------------------------------------------------------------- /mcu/test.h: -------------------------------------------------------------------------------- 1 | #ifndef __TEST_H__ 2 | #define __TEST_H__ 3 | 4 | #include 5 | 6 | // Configuration 7 | #define TEST_PIN_NUMBER 5 8 | 9 | void test_pin_init(void); 10 | void test_pin_low(void); 11 | void test_pin_high(void); 12 | 13 | #endif /* __TEST_H__ */ 14 | -------------------------------------------------------------------------------- /mcu/vga.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "vga.h" 5 | 6 | #include "pico/stdlib.h" 7 | #include "pico/multicore.h" 8 | #include "pico/binary_info.h" 9 | #include "hardware/pio.h" 10 | #include "hardware/clocks.h" 11 | #include "hardware/pwm.h" 12 | #include "hardware/dma.h" 13 | #include "hardware/irq.h" 14 | #include "hardware/structs/mpu.h" 15 | #include "hardware/structs/vreg_and_chip_reset.h" 16 | #include "parallel.pio.h" 17 | 18 | // Pixel freq 25.175MHz for VGA Signal 640 x 480 @ 60 Hz 19 | #define PCLK_DIVIDER_INTEGER 16 20 | #define PCLK_DIVIDER_FRACT 12 21 | #define PCLK_PWM_COUNT 1 22 | #define PCLK_PWM_VALUE 1 23 | 24 | // Vertical refresh 31.46875 kHz 25 | #define VGA_H_VISIBLE_AREA 640 26 | #define VGA_H_FRONT_PORCH 16 27 | #define VGA_H_SYNC_PULSE 96 28 | #define VGA_H_BACK_PORCH 48 29 | #define VGA_H_WHOLE_LINE 800 30 | 31 | #define HSYNC_DIVIDER 1 32 | #define HSYNC__DIVIDER_INTEGER (PCLK_DIVIDER_INTEGER) 33 | #define HSYNC__DIVIDER_FRACT (PCLK_DIVIDER_FRACT) 34 | #define HSYNC_PWM_COUNT (VGA_H_WHOLE_LINE - 1) 35 | #define HSYNC_PWM_VALUE (VGA_H_WHOLE_LINE - VGA_H_SYNC_PULSE) 36 | 37 | // Screen refresh rate 60 Hz 38 | #define VGA_V_VISIBLE_AREA 480 39 | #define VGA_V_FRONT_PORCH 10 40 | #define VGA_V_SYNC_PULSE 2 41 | #define VGA_V_BACK_PORCH 33 42 | #define VGA_V_WHOLE_FRAME 525 43 | 44 | // // 800 / 8 = 100 45 | #define VSYNC_CLK_MULTIPLIER 8 46 | #define VSYNC_SCAN_MULTIPLIER (VGA_H_WHOLE_LINE / VSYNC_CLK_MULTIPLIER) 47 | 48 | #define VSYNC_DIVIDER_INTEGER 134 // 8 * (16 + 12 / 16) 49 | #define VSYNC_DIVIDER_FRACT 0 50 | #define VSYNC_PWM_COUNT (VGA_V_WHOLE_FRAME * VSYNC_SCAN_MULTIPLIER - 1) 51 | #define VSYNC_PWM_VALUE (VSYNC_SCAN_MULTIPLIER * (VGA_V_WHOLE_FRAME - VGA_V_SYNC_PULSE)) 52 | 53 | #define VGA_TO_VIDEO_SCAN_LINES_DIVIDER 2 54 | #define VIDEO_SCAN_LINES (VGA_V_WHOLE_FRAME / VGA_TO_VIDEO_SCAN_LINES_DIVIDER) 55 | 56 | #define VIDEO_RESOLUTION_X 280 57 | #define VIDEO_RESOLUTION_Y 192 58 | #define VIDEO_BORDER_X ((VGA_H_VISIBLE_AREA / 2 - VIDEO_RESOLUTION_X) / 2) 59 | #define VIDEO_BORDER_Y ((VGA_V_VISIBLE_AREA / 2 - VIDEO_RESOLUTION_Y) / 2) 60 | 61 | #define VIDEO_SCAN_BUFFER_OFFSET ((VGA_H_BACK_PORCH + (VGA_H_VISIBLE_AREA - VIDEO_RESOLUTION_X * 2) / 2) / 2) //44 62 | #define VIDEO_SCAN_LINE_OFFSET ((VGA_V_BACK_PORCH + (VGA_V_VISIBLE_AREA - VIDEO_RESOLUTION_Y * 2) / 2)) //40.5 rounded down 63 | 64 | // one last value of zero otherwise last pixel repeats to the end of the scan line 65 | #define VIDEO_SCAN_BUFFER_LEN ((VGA_H_BACK_PORCH + VGA_H_VISIBLE_AREA) / 2 + 1) 66 | #define VIDEO_SCAN_LINE_LEN (VGA_H_WHOLE_LINE / 2) 67 | 68 | const uint VSYNC_PIN = 0; 69 | const uint HSYNC_PIN = 2; 70 | const uint PCLK_PIN = 4; 71 | const uint R0_PIN = 5; 72 | 73 | PIO pio; 74 | uint offset; 75 | uint sm; 76 | int pio_dma_chan; 77 | 78 | uint hsync_slice; 79 | uint hsync_channel; 80 | 81 | uint vsync_slice; 82 | uint vsync_channel; 83 | 84 | int pclk_slice; 85 | uint pclk_channel; 86 | 87 | static uint16_t scan_line_buffer[VIDEO_SCAN_LINE_LEN] = {0}; 88 | static uint16_t *p_scan_line_buffer; 89 | volatile bool scan_line_old = true; 90 | 91 | static uint16_t scan_line; 92 | static int16_t overscan_line; 93 | static uint8_t overscan_line_odd; 94 | 95 | 96 | void __attribute__((noinline, long_call, section(".time_critical"))) vga_scan_line(void) 97 | { 98 | pwm_clear_irq(hsync_slice); 99 | scan_line_old = false; 100 | overscan_line = pwm_get_counter(vsync_slice) / VSYNC_SCAN_MULTIPLIER - VIDEO_SCAN_LINE_OFFSET; 101 | overscan_line_odd = overscan_line & 0x01; 102 | if (overscan_line >= 0) 103 | { 104 | scan_line = overscan_line / 2; 105 | } 106 | else 107 | { 108 | scan_line = VIDEO_SCAN_LINES + overscan_line / 2; 109 | } 110 | } 111 | 112 | void vga_init(void) 113 | { 114 | p_scan_line_buffer = scan_line_buffer; 115 | 116 | pio = pio0; 117 | offset = pio_add_program(pio, ¶llel_program); 118 | sm = pio_claim_unused_sm(pio, true); 119 | parallel_program_init(pio, sm, offset, R0_PIN); 120 | 121 | gpio_set_function(HSYNC_PIN, GPIO_FUNC_PWM); 122 | hsync_slice = pwm_gpio_to_slice_num(HSYNC_PIN); 123 | hsync_channel = pwm_gpio_to_channel(HSYNC_PIN); 124 | 125 | pwm_clear_irq(hsync_slice); 126 | pwm_set_irq_enabled(hsync_slice, true); 127 | irq_set_exclusive_handler(PWM_IRQ_WRAP, vga_scan_line); 128 | irq_set_priority(PWM_IRQ_WRAP, 0); 129 | irq_set_enabled(PWM_IRQ_WRAP, true); 130 | 131 | pwm_set_clkdiv_int_frac (hsync_slice, HSYNC__DIVIDER_INTEGER, HSYNC__DIVIDER_FRACT); 132 | pwm_set_wrap(hsync_slice, HSYNC_PWM_COUNT); 133 | pwm_set_chan_level(hsync_slice, hsync_channel, HSYNC_PWM_VALUE); 134 | 135 | gpio_set_function(VSYNC_PIN, GPIO_FUNC_PWM); 136 | vsync_slice = pwm_gpio_to_slice_num(VSYNC_PIN); 137 | vsync_channel = pwm_gpio_to_channel(VSYNC_PIN); 138 | pwm_set_clkdiv_int_frac (vsync_slice, VSYNC_DIVIDER_INTEGER, VSYNC_DIVIDER_FRACT); 139 | pwm_set_wrap(vsync_slice, VSYNC_PWM_COUNT); 140 | pwm_set_chan_level(vsync_slice, vsync_channel, VSYNC_PWM_VALUE); 141 | 142 | gpio_set_function(PCLK_PIN, GPIO_FUNC_PWM); 143 | pclk_slice = pwm_gpio_to_slice_num(PCLK_PIN); 144 | pclk_channel = pwm_gpio_to_channel(PCLK_PIN); 145 | pwm_set_clkdiv_int_frac (pclk_slice, PCLK_DIVIDER_INTEGER, PCLK_DIVIDER_FRACT); 146 | pwm_set_wrap(pclk_slice, PCLK_PWM_COUNT); 147 | pwm_set_chan_level(pclk_slice, pclk_channel, PCLK_PWM_VALUE); 148 | 149 | int ctrl_chan = dma_claim_unused_channel(true); 150 | pio_dma_chan = dma_claim_unused_channel(true); 151 | 152 | // Setup the control channel 153 | dma_channel_config c = dma_channel_get_default_config(ctrl_chan); // default configs 154 | channel_config_set_transfer_data_size(&c, DMA_SIZE_32); // 32-bit txfers 155 | channel_config_set_read_increment(&c, false); // no read incrementing 156 | channel_config_set_write_increment(&c, false); // no write incrementing 157 | channel_config_set_chain_to(&c, pio_dma_chan); 158 | channel_config_set_dreq(&c, DREQ_PWM_WRAP0 + pclk_slice); 159 | 160 | dma_channel_configure( 161 | ctrl_chan, 162 | &c, 163 | &dma_hw->ch[pio_dma_chan].al3_read_addr_trig, 164 | &p_scan_line_buffer, 165 | 1, 166 | false 167 | ); 168 | 169 | dma_channel_config pio_dma_chan_config = dma_channel_get_default_config(pio_dma_chan); 170 | 171 | channel_config_set_transfer_data_size(&pio_dma_chan_config, DMA_SIZE_16); 172 | channel_config_set_read_increment(&pio_dma_chan_config, true); 173 | channel_config_set_write_increment(&pio_dma_chan_config, false); 174 | channel_config_set_chain_to(&pio_dma_chan_config, ctrl_chan); 175 | channel_config_set_dreq(&pio_dma_chan_config, DREQ_PWM_WRAP0 + pclk_slice); 176 | 177 | dma_channel_configure( 178 | pio_dma_chan, 179 | &pio_dma_chan_config, 180 | &pio->txf[sm], 181 | scan_line_buffer, 182 | VIDEO_SCAN_LINE_LEN - 1, 183 | true); 184 | 185 | pwm_set_mask_enabled ((1 << hsync_slice) | (1 << vsync_slice) | (1 << pclk_slice)); 186 | } 187 | 188 | int16_t vga_overscan_line_get(void) 189 | { 190 | return overscan_line; 191 | } 192 | 193 | uint16_t *vga_scan_line_buffer(void) 194 | { 195 | return &scan_line_buffer[VIDEO_SCAN_BUFFER_OFFSET]; 196 | } 197 | 198 | bool vga_overscan_line_is_odd(void) 199 | { 200 | return overscan_line_odd; 201 | } 202 | 203 | uint16_t vga_scan_line_get(void) 204 | { 205 | return scan_line; 206 | } 207 | 208 | void vga_wait_for_new_overscan_line(void) 209 | { 210 | while(scan_line_old) 211 | { 212 | } 213 | scan_line_old = true; 214 | } 215 | -------------------------------------------------------------------------------- /mcu/vga.h: -------------------------------------------------------------------------------- 1 | #ifndef __VGA_H__ 2 | #define __VGA_H__ 3 | 4 | #include 5 | #include 6 | 7 | void vga_init(void); 8 | int16_t vga_overscan_line_get(void); 9 | uint16_t *vga_scan_line_buffer(void); 10 | bool vga_overscan_line_is_odd(void); 11 | uint16_t vga_scan_line_get(void); 12 | void vga_wait_for_new_overscan_line(void); 13 | 14 | #endif /* __VGA_H__ */ 15 | -------------------------------------------------------------------------------- /parallel.pio: -------------------------------------------------------------------------------- 1 | ; parallel data out 2 | 3 | .program parallel 4 | 5 | loop: 6 | pull block 7 | out pins, 9 8 | jmp loop 9 | 10 | % c-sdk { 11 | static inline void parallel_program_init(PIO pio, uint sm, uint offset, uint pin) { 12 | pio_sm_config c = parallel_program_get_default_config(offset); 13 | for(uint i = 5; i < 14; i++) { 14 | pio_gpio_init(pio, i); 15 | } 16 | pio_sm_set_consecutive_pindirs(pio, sm, pin, 9, true); 17 | sm_config_set_out_pins(&c, pin, 9); 18 | sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX); 19 | pio_sm_init(pio, sm, offset, &c); 20 | pio_sm_set_enabled(pio, sm, true); 21 | } 22 | %} 23 | -------------------------------------------------------------------------------- /pcb/pico-iie.dch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyrex8/pico-iie/0a78fc5ff2bdd10bef6eb3710a34350b7dedbb8a/pcb/pico-iie.dch -------------------------------------------------------------------------------- /pcb/pico-iie.dip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyrex8/pico-iie/0a78fc5ff2bdd10bef6eb3710a34350b7dedbb8a/pcb/pico-iie.dip -------------------------------------------------------------------------------- /pico_sdk_import.cmake: -------------------------------------------------------------------------------- 1 | # This is a copy of /external/pico_sdk_import.cmake 2 | 3 | # This can be dropped into an external project to help locate this SDK 4 | # It should be include()ed prior to project() 5 | 6 | if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH)) 7 | set(PICO_SDK_PATH $ENV{PICO_SDK_PATH}) 8 | message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')") 9 | endif () 10 | 11 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT)) 12 | set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT}) 13 | message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')") 14 | endif () 15 | 16 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH)) 17 | set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH}) 18 | message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')") 19 | endif () 20 | 21 | set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK") 22 | set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable") 23 | set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK") 24 | 25 | if (NOT PICO_SDK_PATH) 26 | if (PICO_SDK_FETCH_FROM_GIT) 27 | include(FetchContent) 28 | set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR}) 29 | if (PICO_SDK_FETCH_FROM_GIT_PATH) 30 | get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") 31 | endif () 32 | FetchContent_Declare( 33 | pico_sdk 34 | GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk 35 | GIT_TAG master 36 | ) 37 | if (NOT pico_sdk) 38 | message("Downloading Raspberry Pi Pico SDK") 39 | FetchContent_Populate(pico_sdk) 40 | set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR}) 41 | endif () 42 | set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE}) 43 | else () 44 | message(FATAL_ERROR 45 | "SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git." 46 | ) 47 | endif () 48 | endif () 49 | 50 | get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") 51 | if (NOT EXISTS ${PICO_SDK_PATH}) 52 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found") 53 | endif () 54 | 55 | set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake) 56 | if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE}) 57 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK") 58 | endif () 59 | 60 | set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE) 61 | 62 | include(${PICO_SDK_INIT_CMAKE_FILE}) 63 | --------------------------------------------------------------------------------