From c3b741d010b488f9051e8fca5fe49396f334c826 Mon Sep 17 00:00:00 2001 From: "goprife@gmail.com" Date: Sun, 21 Oct 2012 04:33:52 +0000 Subject: [PATCH] add simulator bsp for win32, which can be compiled by visual studio (2005 or newer version) git-svn-id: https://rt-thread.googlecode.com/svn/trunk@2357 bbd45198-f89e-11dd-88c7-29a3b14d5316 --- bsp/simulator/SConscript | 33 ++ bsp/simulator/SConstruct | 55 +++ bsp/simulator/application.c | 118 +++++ bsp/simulator/board.c | 45 ++ bsp/simulator/board.h | 32 ++ bsp/simulator/nand_sim.c | 234 ++++++++++ bsp/simulator/platform.c | 36 ++ bsp/simulator/rtconfig.h | 188 ++++++++ bsp/simulator/rtconfig.py | 80 ++++ bsp/simulator/sd_sim.c | 193 ++++++++ bsp/simulator/serial.c | 164 +++++++ bsp/simulator/serial.h | 22 + bsp/simulator/sst25vfxx_mtd.h | 24 + bsp/simulator/sst25vfxx_mtd_sim.c | 229 +++++++++ bsp/simulator/startup.c | 102 +++++ bsp/simulator/testfs.c | 107 +++++ bsp/simulator/usart_sim.c | 131 ++++++ bsp/simulator/vc.sln | 20 + bsp/simulator/vc.suo | Bin 0 -> 132096 bytes bsp/simulator/vs2005.vcproj | 739 ++++++++++++++++++++++++++++++ 20 files changed, 2552 insertions(+) create mode 100644 bsp/simulator/SConscript create mode 100644 bsp/simulator/SConstruct create mode 100644 bsp/simulator/application.c create mode 100644 bsp/simulator/board.c create mode 100644 bsp/simulator/board.h create mode 100644 bsp/simulator/nand_sim.c create mode 100644 bsp/simulator/platform.c create mode 100644 bsp/simulator/rtconfig.h create mode 100644 bsp/simulator/rtconfig.py create mode 100644 bsp/simulator/sd_sim.c create mode 100644 bsp/simulator/serial.c create mode 100644 bsp/simulator/serial.h create mode 100644 bsp/simulator/sst25vfxx_mtd.h create mode 100644 bsp/simulator/sst25vfxx_mtd_sim.c create mode 100644 bsp/simulator/startup.c create mode 100644 bsp/simulator/testfs.c create mode 100644 bsp/simulator/usart_sim.c create mode 100644 bsp/simulator/vc.sln create mode 100644 bsp/simulator/vc.suo create mode 100644 bsp/simulator/vs2005.vcproj diff --git a/bsp/simulator/SConscript b/bsp/simulator/SConscript new file mode 100644 index 0000000000..0eba347dc6 --- /dev/null +++ b/bsp/simulator/SConscript @@ -0,0 +1,33 @@ +import rtconfig +Import('RTT_ROOT') +from building import * + +src_bsp = ['application.c', 'startup.c', 'board.c', 'platform.c'] +src_drv = ['serial.c', 'usart_sim.c'] + +if GetDepend('RT_USING_DFS'): + src_drv += ['sd_sim.c'] + +if GetDepend('RT_USING_MTD_NAND'): + src_drv += ['nand_sim.c'] + +if GetDepend('RT_USING_MTD_NOR'): + src_drv += ['sst25vfxx_mtd_sim.c'] + +if GetDepend('RT_USING_RTGUI'): + src_drv += ['touch.c', 'calibration.c'] + +if GetDepend('RT_USING_RTGUI'): + if rtconfig.RT_USING_LCD_TYPE == 'FMT0371': + src_drv += ['lcd_a70.c'] + elif rtconfig.RT_USING_LCD_TYPE == 'ILI932X': + src_drv += ['ili_lcd_general.c'] + elif rtconfig.RT_USING_LCD_TYPE == 'SSD1289': + src_drv += ['ssd1289.c'] + +src = src_bsp + src_drv +CPPPATH = [ GetCurrentDir() ] +CPPDEFINES = [] +group = DefineGroup('Startup', src, depend = [''], CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES) + +Return('group') diff --git a/bsp/simulator/SConstruct b/bsp/simulator/SConstruct new file mode 100644 index 0000000000..03992addea --- /dev/null +++ b/bsp/simulator/SConstruct @@ -0,0 +1,55 @@ +import os +import sys +import rtconfig + +if os.getenv('RTT_ROOT'): + RTT_ROOT = os.getenv('RTT_ROOT') +else: + RTT_ROOT = os.path.normpath(os.getcwd() + '/../..') + +sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')] +from building import * + +TARGET = 'rtthread-win32.' + rtconfig.TARGET_EXT + +env = Environment() + +Export('RTT_ROOT') +Export('rtconfig') + +# prepare building environment + +libs = Split(''' +kernel32 +msvcrt +winmm +user32 +gdi32 +winspool +comdlg32 +advapi32 +shell32 +ole32 +oleaut32 +uuid +odbc32 +odbccp32 +''') + +env.Append(CCFLAGS=rtconfig.CFLAGS) +env.Append(LINKFLAGS=rtconfig.LFLAGS) +env['LIBS']=libs + +objs = PrepareBuilding(env, RTT_ROOT) + +# firemare library building script +# objs = objs + SConscript( GetCurrentDir() + '/Libraries/SConscript', variant_dir='build/bsp/Libraries', duplicate=0) + +if GetDepend('RT_USING_RTGUI'): + objs = objs + SConscript(RTT_ROOT + '/examples/gui/SConscript', variant_dir='build/examples/gui', duplicate=0) + +# build program +env.Program(TARGET, objs) + +# end building +EndBuilding(TARGET) diff --git a/bsp/simulator/application.c b/bsp/simulator/application.c new file mode 100644 index 0000000000..2125b3a37e --- /dev/null +++ b/bsp/simulator/application.c @@ -0,0 +1,118 @@ +/* + * File : application.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2009-01-05 Bernard the first version + */ + +#include +#include +#include + +#ifdef RT_USING_DFS +/* dfs init */ +#include +/* dfs filesystem:ELM filesystem init */ +#include +/* dfs Filesystem APIs */ +#include +#endif + +void rt_init_thread_entry(void* parameter) +{ +#ifdef RT_USING_COMPONENTS_INIT + /* initialization RT-Thread Components */ + rt_components_init(); +#endif + + rt_platform_init(); + + /* Filesystem Initialization */ +#ifdef RT_USING_DFS + { +#ifdef RT_USING_DFS_ELMFAT + /* mount sd card fat partition 1 as root directory */ + if (dfs_mount("sd0", "/", "elm", 0, 0) == 0) + { + rt_kprintf("fatfs initialized!\n"); + } + else + rt_kprintf("fatfs initialzation failed!\n"); +#endif + +#ifdef RT_USING_DFS_ELMFAT + /* mount sd card fat partition 1 as root directory */ + if (dfs_mount("nand0", "/nand", "uffs", 0, 0) == 0) + { + rt_kprintf("uffs initialized!\n"); + } + else + rt_kprintf("uffs initialzation failed!\n"); +#endif + +#ifdef RT_USING_DFS_JFFS2 + /* mount sd card fat partition 1 as root directory */ + if (dfs_mount("nor", "/nor", "jffs2", 0, 0) == 0) + { + rt_kprintf("jffs2 initialized!\n"); + } + else + rt_kprintf("jffs2 initialzation failed!\n"); +#endif + + } +#endif +} + +void rt_test_thread_entry(void* parameter) +{ + int i; + for(i=0; i<10; i++) + { + rt_kprintf("hello, world\n"); + rt_thread_delay(100); + } +} + +#include +int rt_application_init() +{ + rt_thread_t thread; + +#if (RT_THREAD_PRIORITY_MAX == 32) + thread = rt_thread_create("init", + rt_init_thread_entry, RT_NULL, + 2048, 8, 20); +#else + thread = rt_thread_create("init", + rt_init_thread_entry, RT_NULL, + 2048, 80, 20); +#endif + + if (thread != RT_NULL) + rt_thread_startup(thread); + + thread = rt_thread_create("test", + rt_test_thread_entry, RT_NULL, + 2048, 9, 20); + if (thread != RT_NULL) + rt_thread_startup(thread); + + return 0; +} + +extern int rt_application_init(void); +#if 1 +FINSH_FUNCTION_EXPORT(rt_application_init, app init) +void testfun() +{} +FINSH_FUNCTION_EXPORT(testfun, test fun) +#endif +/*@}*/ diff --git a/bsp/simulator/board.c b/bsp/simulator/board.c new file mode 100644 index 0000000000..d73c29f508 --- /dev/null +++ b/bsp/simulator/board.c @@ -0,0 +1,45 @@ +/* + * File : board.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2009 RT-Thread Develop Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2009-01-05 Bernard first implementation + */ + +#include +#include + +#include "board.h" + +/** + * @addtogroup STM32 + */ + +/** + * This function will initial STM32 board. + */ +void rt_hw_board_init() +{ +#if 0 + /* NVIC Configuration */ + NVIC_Configuration(); + + /* Configure the SysTick */ + SysTick_Config( SystemCoreClock / RT_TICK_PER_SECOND ); +#endif + +#if defined(RT_USING_CONSOLE) + rt_hw_usart_init(); + rt_hw_serial_init(); + rt_console_set_device(RT_CONSOLE_DEVICE_NAME); +#endif + +} + +/*@}*/ diff --git a/bsp/simulator/board.h b/bsp/simulator/board.h new file mode 100644 index 0000000000..cf7c375cc1 --- /dev/null +++ b/bsp/simulator/board.h @@ -0,0 +1,32 @@ +/* + * File : board.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2009, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2009-09-22 Bernard add board.h to this bsp + */ + +#ifndef __BOARD_H__ +#define __BOARD_H__ + +void rt_hw_board_led_on(int n); +void rt_hw_board_led_off(int n); +void rt_hw_board_init(void); + +void rt_hw_serial_init(void); + +/* SD Card init function */ +void rt_hw_sdcard_init(void); + +int rt_hw_mtd_nand_init(void); + +int sst25vfxx_mtd_init(const char * nor_name, unsigned int block_start, unsigned int block_end); + +void rt_platform_init(void); +#endif diff --git a/bsp/simulator/nand_sim.c b/bsp/simulator/nand_sim.c new file mode 100644 index 0000000000..69a328f3f4 --- /dev/null +++ b/bsp/simulator/nand_sim.c @@ -0,0 +1,234 @@ +#include +#include +#include +#include +#include + +// #define NAND_TRACE rt_kprintf +#define NAND_TRACE(...) + +#define NAND_SIM "nand.bin" + +struct nand_device +{ + struct rt_mtd_nand_device parent; + FILE * file; +}; +static struct nand_device _nand; + +#define NAND_DEVICE(device) (( struct nand_device*)(device)) + +#define PAGE_DATA_SIZE 2048 /* page data size in bytes */ +#define PAGE_SPARE_SIZE 64 /* oob size in bytes */ +#define BLOCK_PAGES 64 /* the number of pages in a block */ +#define BLOCK_SIZE ((PAGE_DATA_SIZE + PAGE_SPARE_SIZE) * BLOCK_PAGES) + +#define BLOCK_COUNT 128 /* 128 blocks == 16M */ +#define BLOCK_MARK_SPARE_OFFSET 4 + +static rt_mutex_t lock; + +/* RT-Thread device interface */ + +static rt_err_t k9f1g08_mtd_check_block( + struct rt_mtd_nand_device* device, + rt_uint32_t block) +{ + rt_uint8_t block_status; + int result; + + struct nand_device * nand; + nand = NAND_DEVICE(device); + + fseek(nand->file, block * device->pages_per_block * + (device->page_size + device->oob_size) + + device->page_size + BLOCK_MARK_SPARE_OFFSET, + SEEK_SET); + result = fread(&block_status, 1, 1, nand->file); + if (result < 0) + { + NAND_TRACE("nand fread error\n"); + return -RT_ERROR; + } + + return block_status == 0xFF ? RT_EOK : -RT_ERROR; +} + +static rt_err_t k9f1g08_mtd_mark_bad_block( + struct rt_mtd_nand_device* device, + rt_uint32_t block) +{ + rt_uint8_t block_status; + int result; + + struct nand_device * nand; + nand = NAND_DEVICE(device); + + fseek(nand->file, block * device->pages_per_block * + (device->page_size + device->oob_size) + + device->page_size + BLOCK_MARK_SPARE_OFFSET, + SEEK_SET); + + block_status = 0x00; + result = fwrite(&block_status, 1, 1, nand->file); + if (result < 0) + { + NAND_TRACE("nand fwrite error\n"); + return -RT_ERROR; + } + + return RT_EOK; +} + +static char block_buffer[BLOCK_SIZE]; + +static rt_err_t k9f1g08_mtd_erase_block( + struct rt_mtd_nand_device* device, + rt_uint32_t block) +{ + int result; + + struct nand_device * nand; + nand = NAND_DEVICE(device); + + fseek(nand->file, block * device->pages_per_block * + (device->page_size + device->oob_size), + SEEK_SET); + + memset(block_buffer, 0xFF, sizeof(BLOCK_SIZE)); + result = fwrite(block_buffer, BLOCK_SIZE, 1, nand->file); + if (result < 0) + { + NAND_TRACE("nand fwrite error\n"); + return -RT_ERROR; + } + + return RT_EOK; +} + +/* return 0, ecc ok, 1, can be fixed , -1 can not be fixed */ +static rt_err_t k9f1g08_mtd_read( + struct rt_mtd_nand_device * device, + rt_off_t page, + rt_uint8_t * data, rt_uint32_t data_len, //may not always be 2048 + rt_uint8_t * spare, rt_uint32_t spare_len) +{ + int result; + int ecc_status = 0; + + struct nand_device * nand; + nand = NAND_DEVICE(device); + + if (data != RT_NULL && data_len != 0) + { + fseek(nand->file, page * (device->page_size + device->oob_size), + SEEK_SET); + result = fread(data, data_len, 1, nand->file); + if (result < 0) + ecc_status = -1; + } + + if (spare != RT_NULL && spare_len != 0) + { + fseek(nand->file, page * (device->page_size + device->oob_size) + +device->page_size, + SEEK_SET); + result = fread(spare, spare_len, 1, nand->file); + if (result < 0) + ecc_status = -1; + } + + return ecc_status; +} + +static rt_err_t k9f1g08_mtd_write ( + struct rt_mtd_nand_device * device, + rt_off_t page, + const rt_uint8_t * data, rt_uint32_t data_len,//will be 2048 always! + const rt_uint8_t * spare, rt_uint32_t spare_len) +{ + int result; + int ecc_status = 0; + + struct nand_device * nand; + nand = NAND_DEVICE(device); + + if (data != RT_NULL && data_len != 0) + { + fseek(nand->file, page * (device->page_size + device->oob_size), + SEEK_SET); + result = fwrite(data, data_len, 1, nand->file); + if (result < 0) + ecc_status = -1; + } + + if (spare != RT_NULL && spare_len != 0) + { + fseek(nand->file, page * (device->page_size + device->oob_size) + +device->page_size, + SEEK_SET); + result = fwrite(spare, spare_len, 1, nand->file); + if (result < 0) + ecc_status = -1; + } + + return ecc_status; +} + + +const static struct rt_mtd_nand_driver_ops k9f1g08_mtd_ops = +{ + RT_NULL, + k9f1g08_mtd_read, + k9f1g08_mtd_write, + k9f1g08_mtd_erase_block, + k9f1g08_mtd_check_block, + k9f1g08_mtd_mark_bad_block, +}; + +/* interface of nand and rt-thread device */ +static struct rt_mtd_nand_device nand_part[2]; + +int rt_hw_mtd_nand_init(void) +{ + int size; + rt_uint32_t id, total_block; + struct nand_device * nand; + struct rt_mtd_nand_device * nand_part; + + nand = &_nand; + nand_part = &(nand->parent); + + lock = rt_mutex_create("nand", RT_IPC_FLAG_FIFO); + + /* open sd card file, if not exist, then create it */ + nand->file = fopen(NAND_SIM, "rb+"); + if (nand->file == NULL) + { + int i; + /* create a file to simulate sd card */ + nand->file = fopen(NAND_SIM, "wb+"); + + memset(block_buffer, 0xFF, sizeof(block_buffer)); + for(i=0; ifile, i * BLOCK_SIZE, SEEK_SET); + fwrite(block_buffer, BLOCK_SIZE, 1, nand->file); + } + } + fseek(nand->file, 0, SEEK_SET); + + /* the first partition of nand */ + nand_part->page_size = PAGE_DATA_SIZE; + nand_part->pages_per_block = BLOCK_PAGES;//don't caculate oob size + nand_part->block_start = 0; + nand_part->block_end = BLOCK_COUNT -1; + nand_part->oob_size = PAGE_SPARE_SIZE; + nand_part->ops = &k9f1g08_mtd_ops; + rt_mtd_nand_register_device("nand0", nand_part); + return RT_EOK; +} + +#ifdef RT_USING_FINSH +#include +#endif diff --git a/bsp/simulator/platform.c b/bsp/simulator/platform.c new file mode 100644 index 0000000000..f74fced86c --- /dev/null +++ b/bsp/simulator/platform.c @@ -0,0 +1,36 @@ +#include +#include "board.h" + +void rt_platform_init(void) +{ +#ifdef RT_USING_DFS + /* initilize sd card */ +#ifdef RT_USING_DFS_ELMFAT + rt_hw_sdcard_init(); +#endif + +#ifdef RT_USING_MTD_NAND + rt_hw_mtd_nand_init(); +#endif + +#ifdef RT_USING_MTD_NOR + sst25vfxx_mtd_init("nor", 0, RT_UINT32_MAX); +#endif + +#endif /* RT_USING_DFS */ + +#ifdef RT_USING_RTGUI + /* initilize touch panel */ + rtgui_touch_hw_init("spi21"); + + /* initilize ra8875 lcd controller */ + ra8875_init(); + + /* initilize key module */ + rt_hw_key_init(); +#endif /* RT_USING_RTGUI */ + + rt_thread_delay(50); + rt_device_init_all(); +} + diff --git a/bsp/simulator/rtconfig.h b/bsp/simulator/rtconfig.h new file mode 100644 index 0000000000..da82ac636c --- /dev/null +++ b/bsp/simulator/rtconfig.h @@ -0,0 +1,188 @@ +/* RT-Thread config file */ +#ifndef __RTTHREAD_CFG_H__ +#define __RTTHREAD_CFG_H__ +#ifdef _MSC_VER +#undef RT_USING_NEWLIB +#undef RT_USING_MINILIBC +#define NORESOURCE //RT_VESRION in winuser.h +#define _CRT_ERRNO_DEFINED //errno macro redefinition +#endif + +#define RT_USING_COMPONENTS_INIT + +#define RT_USING_MTD_NAND +#define RT_USING_MTD_NOR +#define RT_USING_DFS_UFFS +#define RT_USING_DFS_JFFS2 + +/* RT_NAME_MAX*/ +#define RT_NAME_MAX 8 + +/* RT_ALIGN_SIZE*/ +#define RT_ALIGN_SIZE 4 + +/* PRIORITY_MAX */ +#define RT_THREAD_PRIORITY_MAX 32 + +/* Tick per Second */ +#define RT_TICK_PER_SECOND 1000 + +/* SECTION: RT_DEBUG */ +/* Thread Debug */ +#define RT_DEBUG +#define RT_THREAD_DEBUG + +#define RT_USING_OVERFLOW_CHECK + +/* Using Hook */ +#define RT_USING_HOOK + +/* Using Software Timer */ +/* #define RT_USING_TIMER_SOFT */ +//#define RT_TIMER_THREAD_PRIO 4 +//#define RT_TIMER_THREAD_STACK_SIZE 512 +//#define RT_TIMER_TICK_PER_SECOND 10 + +/* SECTION: IPC */ +/* Using Semaphore*/ +#define RT_USING_SEMAPHORE + +/* Using Mutex */ +#define RT_USING_MUTEX + +/* Using Event */ +#define RT_USING_EVENT + +/* Using MailBox */ +#define RT_USING_MAILBOX + +/* Using Message Queue */ +#define RT_USING_MESSAGEQUEUE + +/* SECTION: Memory Management */ +/* Using Memory Pool Management*/ +//#define RT_USING_MEMPOOL + +/* Using Dynamic Heap Management */ +#define RT_USING_HEAP + +/* Using Small MM */ +#define RT_USING_SMALL_MEM +//#define RT_TINY_SIZE + +/* SECTION: Device System */ +/* Using Device System */ +#define RT_USING_DEVICE +#define RT_USING_SERIAL +//#define RT_USING_UART1 + +/* SECTION: Console options */ +#define RT_USING_CONSOLE +/* the buffer size of console*/ +#define RT_CONSOLEBUF_SIZE 128 +#define RT_CONSOLE_DEVICE_NAME "sci0" + +/* SECTION: finsh, a C-Express shell */ +#define RT_USING_FINSH +/* Using symbol table */ +#define FINSH_USING_SYMTAB +#define FINSH_USING_DESCRIPTION + +/* SECTION: device filesystem */ +#define RT_USING_DFS + +#define RT_USING_DFS_ELMFAT +#define RT_DFS_ELM_WORD_ACCESS +/* Reentrancy (thread safe) of the FatFs module. */ +#define RT_DFS_ELM_REENTRANT +/* Number of volumes (logical drives) to be used. */ +#define RT_DFS_ELM_DRIVES 2 +/* #define RT_DFS_ELM_USE_LFN 1 */ +#define RT_DFS_ELM_MAX_LFN 255 +/* Maximum sector size to be handled. */ +#define RT_DFS_ELM_MAX_SECTOR_SIZE 512 + +/* the max number of mounted filesystem */ +#define DFS_FILESYSTEMS_MAX 4 +/* the max number of opened files */ +#define DFS_FD_MAX 4 + +/* SECTION: lwip, a lighwight TCP/IP protocol stack */ +/* #define RT_USING_LWIP */ +/* LwIP uses RT-Thread Memory Management */ +#define RT_LWIP_USING_RT_MEM +/* Enable ICMP protocol*/ +#define RT_LWIP_ICMP +/* Enable UDP protocol*/ +#define RT_LWIP_UDP +/* Enable TCP protocol*/ +#define RT_LWIP_TCP +/* Enable DNS */ +#define RT_LWIP_DNS + +/* the number of simulatenously active TCP connections*/ +#define RT_LWIP_TCP_PCB_NUM 5 + +/* Using DHCP */ +/* #define RT_LWIP_DHCP */ + +/* ip address of target*/ +#define RT_LWIP_IPADDR0 192 +#define RT_LWIP_IPADDR1 168 +#define RT_LWIP_IPADDR2 1 +#define RT_LWIP_IPADDR3 30 + +/* gateway address of target*/ +#define RT_LWIP_GWADDR0 192 +#define RT_LWIP_GWADDR1 168 +#define RT_LWIP_GWADDR2 1 +#define RT_LWIP_GWADDR3 1 + +/* mask address of target*/ +#define RT_LWIP_MSKADDR0 255 +#define RT_LWIP_MSKADDR1 255 +#define RT_LWIP_MSKADDR2 255 +#define RT_LWIP_MSKADDR3 0 + +/* tcp thread options */ +#define RT_LWIP_TCPTHREAD_PRIORITY 12 +#define RT_LWIP_TCPTHREAD_MBOX_SIZE 10 +#define RT_LWIP_TCPTHREAD_STACKSIZE 1024 + +/* ethernet if thread options */ +#define RT_LWIP_ETHTHREAD_PRIORITY 15 +#define RT_LWIP_ETHTHREAD_MBOX_SIZE 10 +#define RT_LWIP_ETHTHREAD_STACKSIZE 512 + +/* TCP sender buffer space */ +#define RT_LWIP_TCP_SND_BUF 8192 +/* TCP receive window. */ +#define RT_LWIP_TCP_WND 8192 + +/* SECTION: RT-Thread/GUI */ +/* #define RT_USING_RTGUI */ + +/* name length of RTGUI object */ +#define RTGUI_NAME_MAX 12 +/* support 16 weight font */ +#define RTGUI_USING_FONT16 +/* support Chinese font */ +#define RTGUI_USING_FONTHZ +/* use DFS as file interface */ +#define RTGUI_USING_DFS_FILERW +/* use font file as Chinese font */ +#define RTGUI_USING_HZ_FILE +/* use Chinese bitmap font */ +#define RTGUI_USING_HZ_BMP +/* use small size in RTGUI */ +#define RTGUI_USING_SMALL_SIZE +/* use mouse cursor */ +/* #define RTGUI_USING_MOUSE_CURSOR */ +/* default font size in RTGUI */ +#define RTGUI_DEFAULT_FONT_SIZE 16 + +/* image support */ +/* #define RTGUI_IMAGE_XPM */ +/* #define RTGUI_IMAGE_BMP */ + +#endif diff --git a/bsp/simulator/rtconfig.py b/bsp/simulator/rtconfig.py new file mode 100644 index 0000000000..057332b705 --- /dev/null +++ b/bsp/simulator/rtconfig.py @@ -0,0 +1,80 @@ +# toolchains options +ARCH='x86' +#CPU='posix' +CPU='win32' +CROSS_TOOL='msvc' #win32 + +# lcd panel options +# 'FMT0371','ILI932X', 'SSD1289' +# RT_USING_LCD_TYPE = 'SSD1289' + +# cross_tool provides the cross compiler +# EXEC_PATH is the compiler execute path, for example, CodeSourcery, Keil MDK, IAR +if CROSS_TOOL == 'gcc': + PLATFORM = 'gcc' + EXEC_PATH = '/usr/bin/gcc' + + +if CROSS_TOOL == '': + PLATFORM = 'gcc' + EXEC_PATH = '/usr/bin/gcc' + +if CROSS_TOOL == 'msvc': + PLATFORM = 'cl' + EXEC_PATH = '' + +BUILD = 'debug' +#BUILD = '' + +if PLATFORM == 'gcc': + # toolchains + PREFIX = '' + CC = PREFIX + 'gcc' + AS = PREFIX + 'gcc' + AR = PREFIX + 'ar' + LINK = PREFIX + 'gcc' + TARGET_EXT = 'axf' + SIZE = PREFIX + 'size' + OBJDUMP = PREFIX + 'objdump' + OBJCPY = PREFIX + 'objcopy' + + DEVICE = ' -ffunction-sections -fdata-sections' + CFLAGS = DEVICE + AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp' + #LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread-linux.map,-cref,-u,Reset_Handler -T stm32_rom.ld' + LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread-linux.map -lpthread' + + CPATH = '' + LPATH = '' + + if BUILD == 'debug': + CFLAGS += ' -O0 -gdwarf-2' + AFLAGS += ' -gdwarf-2' + else: + CFLAGS += ' -O2' + + POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n' + +elif PLATFORM == 'cl': + # toolchains + PREFIX = '' + TARGET_EXT = 'exe' + AS = PREFIX + 'cl' + CC = PREFIX + 'cl' + AR = PREFIX + 'cl' + LINK = PREFIX + 'cl' + AFLAGS = '' + + CFLAGS = '/MT /ZI /Od /W 3 /WL /DMSVC /D_TIME_T_DEFINED' + #LFLAGS = '/SUBSYSTEM:WINDOWS /NODEFAULTLIB /MACHINE:X86 /DEBUG' + LFLAGS = '/SUBSYSTEM:CONSOLE /NODEFAULTLIB /MACHINE:X86 ' + + CPATH = '' + LPATH = '' + + if BUILD == 'debug': + CFLAGS += ' /DEBUG' + else: + CFLAGS += '' + + POST_ACTION = '' diff --git a/bsp/simulator/sd_sim.c b/bsp/simulator/sd_sim.c new file mode 100644 index 0000000000..bb83fcc37d --- /dev/null +++ b/bsp/simulator/sd_sim.c @@ -0,0 +1,193 @@ +#include +#include +#include +#include + +// #define SD_TRACE rt_kprintf +#define SD_TRACE(...) + +//#define SDCARD_SIM "F:\\Project\\tools\\SDCARD" +#define SDCARD_SIM "sd.bin" +#define SDCARD_SIZE (16*1024*1024) //16M + +struct sdcard_device +{ + struct rt_device parent; + FILE* file; +}; +static struct sdcard_device _sdcard; + +#define SDCARD_DEVICE(device) (( struct sdcard_device*)(device)) + +static rt_mutex_t lock; + +/* RT-Thread device interface */ + +static rt_err_t rt_sdcard_init(rt_device_t dev) +{ + return RT_EOK; +} + +static rt_err_t rt_sdcard_open(rt_device_t dev, rt_uint16_t oflag) +{ + return RT_EOK; +} + +static rt_err_t rt_sdcard_close(rt_device_t dev) +{ + return RT_EOK; +} + +/* position: block page address, not bytes address + * buffer: + * size : how many blocks + */ +static rt_size_t rt_sdcard_read(rt_device_t device, rt_off_t position, void* buffer, rt_size_t size) +{ + struct sdcard_device * sd; + int result = 0; + + SD_TRACE("sd read: pos %d, size %d\n", position, size); + + rt_mutex_take(lock, RT_WAITING_FOREVER); + sd = SDCARD_DEVICE(device); + fseek(sd->file, position * SECTOR_SIZE, SEEK_SET); + + result = fread(buffer, size * SECTOR_SIZE, 1, sd->file); + if (result < 0) + goto _err; + + rt_mutex_release(lock); + return size; + +_err: + SD_TRACE("sd read errors!\n"); + rt_mutex_release(lock); + return 0; +} + +/* position: block page address, not bytes address + * buffer: + * size : how many blocks + */ +static rt_size_t rt_sdcard_write(rt_device_t device, rt_off_t position, const void* buffer, rt_size_t size) +{ + struct sdcard_device * sd; + int result = 0; + + SD_TRACE("sst write: pos %d, size %d\n", position, size); + + rt_mutex_take(lock, RT_WAITING_FOREVER); + sd = SDCARD_DEVICE(device); + fseek(sd->file, position * SECTOR_SIZE, SEEK_SET); + + result = fwrite(buffer, size * SECTOR_SIZE, 1, sd->file); + if (result < 0) + goto _err; + + rt_mutex_release(lock); + return size; + +_err: + SD_TRACE("sd write errors!\n"); + rt_mutex_release(lock); + return 0; +} + +static rt_err_t rt_sdcard_control(rt_device_t dev, rt_uint8_t cmd, void *args) +{ + struct sdcard_device * sd; + unsigned int size; + + RT_ASSERT(dev != RT_NULL); + + sd = SDCARD_DEVICE(dev); + + if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME) + { + struct rt_device_blk_geometry *geometry; + + geometry = (struct rt_device_blk_geometry *)args; + if (geometry == RT_NULL) return -RT_ERROR; + + geometry->bytes_per_sector = SECTOR_SIZE; + geometry->block_size = SECTOR_SIZE; + + fseek(sd->file, 0, SEEK_END); + size = ftell(sd->file); + + geometry->sector_count = size/SECTOR_SIZE; + } + return RT_EOK; +} + + +rt_err_t rt_hw_sdcard_init(const char * spi_device_name) +{ + int size; + rt_uint32_t id, total_block; + struct sdcard_device * sd; + struct rt_device * device; + + sd = &_sdcard; + device = &(sd->parent); + + lock = rt_mutex_create("lock", RT_IPC_FLAG_FIFO); + + /* open sd card file, if not exist, then create it */ + sd->file = fopen(SDCARD_SIM, "rb+"); + if (sd->file == NULL) + { + /* create a file to simulate sd card */ + sd->file = fopen(SDCARD_SIM, "wb+"); + + fseek(sd->file, 0, SEEK_END); + size = ftell(sd->file); + + fseek(sd->file, 0, SEEK_SET ); + if (size < SDCARD_SIZE) + { + int i; + unsigned char* ptr; + + ptr = (unsigned char*) malloc (1024 * 1024); + if (ptr == NULL) + { + SD_TRACE("malloc error, no memory!\n"); + return RT_ERROR; + } + memset(ptr, 0x0, 1024 * 1024); + + fseek(sd->file, 0, SEEK_SET); + + for(i=0; i<(SDCARD_SIZE / (1024*1024)); i++) + fwrite(ptr, 1024 * 1024, 1, sd->file); + + free(ptr); + } + } + fseek(sd->file, 0, SEEK_SET); + + device->type = RT_Device_Class_Block; + device->init = rt_sdcard_init; + device->open = rt_sdcard_open; + device->close = rt_sdcard_close; + device->read = rt_sdcard_read; + device->write = rt_sdcard_write; + device->control = rt_sdcard_control; + device->user_data = NULL; + + rt_device_register(device, "sd0", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE); + + return RT_EOK; +} + +#ifdef RT_USING_FINSH +#include +void eraseall(void) +{ + printf("had not implemented yet!\n"); +} +FINSH_FUNCTION_EXPORT(eraseall, erase all block in SPI flash); +#endif diff --git a/bsp/simulator/serial.c b/bsp/simulator/serial.c new file mode 100644 index 0000000000..b5e9cb01a6 --- /dev/null +++ b/bsp/simulator/serial.c @@ -0,0 +1,164 @@ +/* +****************************************************************************** +* By : parai +* email:parai@foxmail.com +* 这并不是一个真的串口设备,只是为了能够让内核打印信息而创建 +****************************************************************************** +*/ + +#include "rtthread.h" +//#ifdef RT_USING_SERIAL + +#define _DEBUG_SERIAL 0 +#include "serial.h" +#include +struct rt_device serial_device; +extern struct serial_int_rx serial_rx; + +/*@{*/ + +/* RT-Thread Device Interface */ +/** + * This function initializes serial + */ +static rt_err_t rt_serial_init (rt_device_t dev) +{ + if (!(dev->flag & RT_DEVICE_FLAG_ACTIVATED)) + { + if (dev->flag & RT_DEVICE_FLAG_INT_RX) + { + rt_memset(serial_rx.rx_buffer, 0, + sizeof(serial_rx.rx_buffer)); + serial_rx.read_index = 0; + serial_rx.save_index = 0; + } + + dev->flag |= RT_DEVICE_FLAG_ACTIVATED; + } + return RT_EOK; +} + +static rt_err_t rt_serial_open(rt_device_t dev, rt_uint16_t oflag){ +#if _DEBUG_SERIAL==1 + printf("in rt_serial_open()\n"); +#endif + return RT_EOK; +} + +static rt_err_t rt_serial_close(rt_device_t dev) +{ +#if _DEBUG_SERIAL==1 + printf("in rt_serial_close()\n"); +#endif + return RT_EOK; +} +static rt_size_t rt_serial_read (rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size) +{ + rt_uint8_t* ptr; + rt_err_t err_code; + +#if 1 + ptr = buffer; + err_code = RT_EOK; + + if (dev->flag & RT_DEVICE_FLAG_INT_RX) + { + /* interrupt mode Rx */ + while (size) + { + rt_base_t level; + + /* disable interrupt */ + level = rt_hw_interrupt_disable(); + + if (serial_rx.read_index != serial_rx.save_index) + { + /* read a character */ + *ptr++ = serial_rx.rx_buffer[serial_rx.read_index]; + size--; + + /* move to next position */ + serial_rx.read_index ++; + if (serial_rx.read_index >= SERIAL_RX_BUFFER_SIZE) + serial_rx.read_index = 0; + } + else + { + /* set error code */ + err_code = -RT_EEMPTY; + + /* enable interrupt */ + rt_hw_interrupt_enable(level); + break; + } + + /* enable interrupt */ + rt_hw_interrupt_enable(level); + } + } + + + /* set error code */ + rt_set_errno(err_code); + return (rt_uint32_t)ptr - (rt_uint32_t)buffer; +#endif + +} +static rt_size_t rt_serial_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size) +{ +#if _DEBUG_SERIAL==1 + printf("in rt_serial_write()\n"); +#endif + printf("%s",(char*)buffer); + return size; +} + +static rt_err_t rt_serial_control (rt_device_t dev, rt_uint8_t cmd, void *args) +{ + RT_ASSERT(dev != RT_NULL); + + switch (cmd){ + case RT_DEVICE_CTRL_SUSPEND: + /* suspend device */ + dev->flag |= RT_DEVICE_FLAG_SUSPENDED; + break; + + case RT_DEVICE_CTRL_RESUME: + /* resume device */ + dev->flag &= ~RT_DEVICE_FLAG_SUSPENDED; + break; + } + + return RT_EOK; +} + +/* + * serial register + */ +static rt_err_t rt_hw_serial_register(rt_device_t device, const char* name, rt_uint32_t flag) +{ + RT_ASSERT(device != RT_NULL); +#if _DEBUG_SERIAL==1 + printf("in rt_serial_register()\n"); +#endif + device->type = RT_Device_Class_Char; + device->rx_indicate = RT_NULL; + device->tx_complete = RT_NULL; + device->init = rt_serial_init; + device->open = rt_serial_open; + device->close = rt_serial_close; + device->read = rt_serial_read; + device->write = rt_serial_write; + device->control = rt_serial_control; + device->user_data = RT_NULL; + + /* register a character device */ + return rt_device_register(device, name, RT_DEVICE_FLAG_RDWR | flag); +} + +rt_err_t rt_hw_serial_init(void) +{ + return rt_hw_serial_register(&serial_device,"sci0", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM); +} +//#endif diff --git a/bsp/simulator/serial.h b/bsp/simulator/serial.h new file mode 100644 index 0000000000..fe82957b34 --- /dev/null +++ b/bsp/simulator/serial.h @@ -0,0 +1,22 @@ +/* +********************************************************************************************************* +* MC9S12DP256/DG128 Specific code +* BANKED MEMORY MODEL +* +* File : rthw.c +* By : parai +* email:parai@foxmail.com +*******************************************************************************************************/ + +#ifndef __RT_HW_SERIAL_H__ +#define __RT_HW_SERIAL_H__ + +#define SERIAL_RX_BUFFER_SIZE 80 +struct serial_int_rx +{ + rt_uint8_t rx_buffer[SERIAL_RX_BUFFER_SIZE]; + rt_uint32_t read_index, save_index; +}; + +rt_err_t rt_hw_serial_init(void); +#endif diff --git a/bsp/simulator/sst25vfxx_mtd.h b/bsp/simulator/sst25vfxx_mtd.h new file mode 100644 index 0000000000..6b08662474 --- /dev/null +++ b/bsp/simulator/sst25vfxx_mtd.h @@ -0,0 +1,24 @@ +/* + * File : sst25vfxx_mtd.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2011, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2011-12-16 aozima the first version + * 2012-02-01 mbbill MTD driver version + */ + +#ifndef SST25VFXX_MTD_H +#define SST25VFXX_MTD_H + +#include +#include + +rt_err_t sst25vfxx_mtd_init(const char *spi_device_name, rt_uint32_t block_start, rt_uint32_t block_end); + +#endif diff --git a/bsp/simulator/sst25vfxx_mtd_sim.c b/bsp/simulator/sst25vfxx_mtd_sim.c new file mode 100644 index 0000000000..d799a98040 --- /dev/null +++ b/bsp/simulator/sst25vfxx_mtd_sim.c @@ -0,0 +1,229 @@ +/* + * File : rtdef.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2011, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2011-12-16 aozima the first version + * 2012-02-01 mbbill MTD device version + */ + +#include +#include +#include +#include +#include "sst25vfxx_mtd.h" + +#ifdef RT_USING_MTD_NOR +#define NOR_SIM "nor.bin" +/* JEDEC Manufacturers ID */ +#define MF_ID (0xBF) +/* JEDEC Device ID : Memory Type */ +#define MT_ID (0x25) +/* JEDEC Device ID: Memory Capacity */ +#define MC_ID_SST25VF016 (0x41) +#define MC_ID_SST25VF032 (0x4A) +#define MC_ID_SST25VF064 (0x4B) + +#define BLOCK_SIZE (64*1024) + + +#define SST25_MTD(device) ((struct sst25_mtd*)(device)) +struct sst25_mtd +{ + struct rt_mtd_nor_device parent; + FILE * file; +}; +static struct sst25_mtd _sst25_mtd; + +static struct rt_mutex flash_lock; + +/* RT-Thread MTD device interface */ +static rt_uint32_t sst25vfxx_read_id(struct rt_mtd_nor_device* device) +{ + rt_uint8_t id_recv[3] = {MF_ID, MT_ID, MC_ID_SST25VF016}; + + return (id_recv[0] << 16) | (id_recv[1] << 8) | id_recv[2]; +} + +static int sst25vfxx_read(struct rt_mtd_nor_device* device, rt_off_t position, rt_uint8_t *data, rt_size_t size) +{ + struct sst25_mtd *sst25; + int result; + + sst25 = SST25_MTD(device); + RT_ASSERT(sst25 != RT_NULL); + + rt_mutex_take(&flash_lock, RT_WAITING_FOREVER); + + fseek(sst25->file, position, SEEK_SET); + result = fread(data, size, 1, sst25->file); + if (result < 0) + rt_kprintf("sst read error.\n"); + + rt_mutex_release(&flash_lock); + return size; +} + +static int sst25vfxx_write(struct rt_mtd_nor_device* device, rt_off_t position, + const rt_uint8_t *data, rt_size_t size) +{ + struct sst25_mtd *sst25; + int result; + + sst25 = SST25_MTD(device); + RT_ASSERT(sst25 != RT_NULL); + + rt_mutex_take(&flash_lock, RT_WAITING_FOREVER); + + fseek(sst25->file, position, SEEK_SET); + result = fwrite(data, size, 1, sst25->file); + if (result < 0) + rt_kprintf("sst write error.\n"); + + rt_mutex_release(&flash_lock); + return size; +} + +static char block_buffer[BLOCK_SIZE]; + +static rt_err_t sst25vfxx_erase_block(struct rt_mtd_nor_device* device, rt_uint32_t block) +{ + struct sst25_mtd *sst25; + int result; + + sst25 = SST25_MTD(device); + + RT_ASSERT(sst25 != RT_NULL); + + rt_mutex_take(&flash_lock, RT_WAITING_FOREVER); + + memset(block_buffer, 0xFF, BLOCK_SIZE); + fseek(sst25->file, block, SEEK_SET); + + result = fwrite(block_buffer, BLOCK_SIZE, 1, sst25->file); + if (result < 0) + rt_kprintf("sst write error.\n"); + + rt_mutex_release(&flash_lock); + return RT_EOK; +} + +const static struct rt_mtd_nor_driver_ops sst25vfxx_mtd_ops = +{ + sst25vfxx_read_id, + sst25vfxx_read, + sst25vfxx_write, + sst25vfxx_erase_block, +}; +static rt_err_t sst25vfxx_hw_init(struct sst25_mtd *mtd) +{ + mtd = mtd; + return RT_EOK; +} + +/** + * SST25vfxx API + */ +rt_err_t sst25vfxx_mtd_init(const char * nor_name, + rt_uint32_t block_start, + rt_uint32_t block_end) +{ + rt_uint32_t id, total_block; + struct sst25_mtd * sst25; + struct rt_mtd_nor_device *mtd; + + + sst25 = &_sst25_mtd; + mtd = &(sst25->parent); + + /* set page size and block size */ + mtd->block_size = 64 * 1024; /* 64kByte */ + mtd->ops = &sst25vfxx_mtd_ops; + + /* initialize mutex */ + if (rt_mutex_init(&flash_lock, nor_name, RT_IPC_FLAG_FIFO) != RT_EOK) + { + rt_kprintf("init sd lock mutex failed\n"); + } + + /* initialize flash */ + id = sst25vfxx_read_id(mtd); + switch (id & 0xff) + { + case MC_ID_SST25VF016: + total_block = (16 * 1024 * 1024 / 8) / mtd->block_size; + break; + case MC_ID_SST25VF032: + total_block = (32 * 1024 * 1024 / 8) / mtd->block_size; + break; + case MC_ID_SST25VF064: + total_block = (64 * 1024 * 1024 / 8) / mtd->block_size; + break; + default: + rt_kprintf("SST25 detection error, id: %x\n", id); + return -RT_ERROR; + } + + if ((block_end == RT_UINT32_MAX) || (block_end == 0)) + { + block_end = total_block; + } + else if (block_end > total_block) + { + rt_kprintf("SST25 total block: %d, out of block\n", total_block); + return -RT_ERROR; + } + + mtd->block_start = block_start; + mtd->block_end = block_end; + + /* open nor file, if not exist, then create it */ + sst25->file = fopen(NOR_SIM, "rb+"); + if (sst25->file == NULL) + { + int i; + /* create a file to simulate nor */ + sst25->file = fopen(NOR_SIM, "wb+"); + + memset(block_buffer, 0xFF, sizeof(block_buffer)); + for(i=0; ifile, i * BLOCK_SIZE, SEEK_SET); + fwrite(block_buffer, BLOCK_SIZE, 1, sst25->file); + } + } + + fseek(sst25->file, 0, SEEK_SET); + + /* initialize hardware */ + sst25vfxx_hw_init(&_sst25_mtd); + + /* register MTD device */ + rt_mtd_nor_register_device("nor", mtd); + + return RT_EOK; +} + +#ifdef RT_USING_FINSH +#include +void nor_erase(void) +{ + rt_uint32_t index; + struct rt_mtd_nor_device *mtd; + + mtd = SST25_MTD(&_sst25_mtd); + for (index = mtd->block_start; index < mtd->block_end; index ++) + { + sst25vfxx_erase_block(mtd, index * mtd->block_size); + } +} +FINSH_FUNCTION_EXPORT(nor_erase, erase all block in SPI flash); +#endif + +#endif diff --git a/bsp/simulator/startup.c b/bsp/simulator/startup.c new file mode 100644 index 0000000000..8ce9257c08 --- /dev/null +++ b/bsp/simulator/startup.c @@ -0,0 +1,102 @@ +/* + * File : startup.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, RT-Thread Develop Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://openlab.rt-thread.com/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2012-09-03 prife first implementation + */ + +#include +#include + +#include "board.h" + +/** + * @addtogroup win32 + */ +#define HEAP_SIZE (1024*1024*10) +static rt_uint8_t * heap; + +void vs_heap_init(void) +{ + heap = malloc(HEAP_SIZE); + if (heap == RT_NULL) + rt_kprintf("there is no memory in pc."); +} +/*@{*/ + +extern int rt_application_init(void); +#ifdef RT_USING_FINSH +extern void finsh_system_init(void); +extern void finsh_set_device(const char* device); +#endif + +/** + * This function will startup RT-Thread RTOS. + */ +void rtthread_startup(void) +{ + /* init board */ + rt_hw_board_init(); + + /* show version */ + rt_show_version(); + + /* init tick */ + rt_system_tick_init(); + + /* init kernel object */ + rt_system_object_init(); + + /* init timer system */ + rt_system_timer_init(); + +#ifdef RT_USING_HEAP + /* init memory system */ +#if (MSVC) + vs_heap_init(); +#endif + rt_system_heap_init((void*)heap, (void*)&heap[HEAP_SIZE-1]); +#endif + + /* init scheduler system */ + rt_system_scheduler_init(); + + /* init all device */ +#ifdef RT_USING_DEVICE + rt_device_init_all(); +#endif + /* init application */ + rt_application_init(); + + /* init timer thread */ + rt_system_timer_thread_init(); + + /* init idle thread */ + rt_thread_idle_init(); + + /* start scheduler */ + rt_system_scheduler_start(); + + /* never reach here */ + return ; +} + +int main(void) +{ + /* disable interrupt first */ + rt_hw_interrupt_disable(); + + /* startup RT-Thread RTOS */ + rtthread_startup(); + + return 0; +} + +/*@}*/ diff --git a/bsp/simulator/testfs.c b/bsp/simulator/testfs.c new file mode 100644 index 0000000000..109a948836 --- /dev/null +++ b/bsp/simulator/testfs.c @@ -0,0 +1,107 @@ +/* + * File : application.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2009-01-05 Bernard the first version + */ + +#include +#include +#include + +#ifdef RT_USING_DFS +/* dfs init */ +#include +/* dfs filesystem:ELM filesystem init */ +#include +/* dfs Filesystem APIs */ +#include +#endif + +#include + +int testfat(void) +{ + int Fd,i; + int res; + + Fd = open("/nor/test.txt", O_WRONLY | O_CREAT | O_TRUNC, 0); //ļ + if (Fd>=0) + { + rt_kprintf("begin\n"); + for (i = 0; i < 94520 ; i++) + //for (i = 0; i < 512 ; i++) + { + res = write(Fd, &i, 1); + if (res < 0) + { + rt_kprintf("write %d bytes, then meet a error, break\n", i); + break; + } + } + close(Fd); + rt_kprintf("over\n"); + } + else + { + rt_kprintf("failed\n"); + } + return 0; +} + +static char buf[94520]; +int testfat2(void) +{ + int Fd,i; + + Fd = open("/nor/test2.txt", O_WRONLY | O_CREAT | O_TRUNC, 0); //ļ + if (Fd>=0) + { + rt_kprintf("begin\n"); + for (i = 0; i < 94520 ; i++) + { + write(Fd, buf, 1); + } + close(Fd); + rt_kprintf("over\n"); + } + else + { + rt_kprintf("failed\n"); + } + return 0; +} + + +int testfat3(void) +{ + int Fd,i; + + Fd = open("/nor/test3.txt", O_WRONLY | O_CREAT | O_TRUNC, 0); //ļ + if (Fd>=0) + { + rt_kprintf("begin\n"); + { + write(Fd, buf, 94520); + } + close(Fd); + rt_kprintf("over\n"); + } + else + { + rt_kprintf("failed\n"); + } + return 0; +} + +#include +FINSH_FUNCTION_EXPORT(testfat, test fs); +FINSH_FUNCTION_EXPORT(testfat2, test fs); +FINSH_FUNCTION_EXPORT(testfat3, test fs); \ No newline at end of file diff --git a/bsp/simulator/usart_sim.c b/bsp/simulator/usart_sim.c new file mode 100644 index 0000000000..d77328bf32 --- /dev/null +++ b/bsp/simulator/usart_sim.c @@ -0,0 +1,131 @@ +#include +#include +#include +#include +#include "serial.h" + +struct serial_int_rx serial_rx; +extern struct rt_device serial_device; + +/* + * Handler for OSKey Thread + */ +static HANDLE OSKey_Thread; +static DWORD OSKey_ThreadID; + +static DWORD WINAPI ThreadforKeyGet(LPVOID lpParam); +void rt_hw_usart_init(void) +{ + + /* + * create serial thread that revice key input from keyboard + */ + + OSKey_Thread = CreateThread(NULL, + 0, + (LPTHREAD_START_ROUTINE)ThreadforKeyGet, + 0, + CREATE_SUSPENDED, + &OSKey_ThreadID); + if(OSKey_Thread == NULL) + { + //Display Error Message + + return; + } + SetThreadPriority(OSKey_Thread, + THREAD_PRIORITY_NORMAL); + SetThreadPriorityBoost(OSKey_Thread, + TRUE); + SetThreadAffinityMask(OSKey_Thread, + 0x01); + /* + * Start OS get key Thread + */ + ResumeThread(OSKey_Thread); + +} + +/* + * () 0xe04b + * () 0xe048 + * () 0xe04d + * () 0xe050 + */ +static int savekey(unsigned char key) +{ + /* save on rx buffer */ + { + rt_base_t level; + + /* disable interrupt */ + //ʱرжϣΪҪuartݽṹ + level = rt_hw_interrupt_disable(); + + /* save character */ + serial_rx.rx_buffer[serial_rx.save_index] = key; + serial_rx.save_index ++; + //Ĵsave_indexǷѾβתͷΪһλ + if (serial_rx.save_index >= SERIAL_RX_BUFFER_SIZE) + serial_rx.save_index = 0; + + //ʾתsave_index׷read_indexread_indexһɵ + /* if the next position is read index, discard this 'read char' */ + if (serial_rx.save_index == serial_rx.read_index) + { + serial_rx.read_index ++; + if (serial_rx.read_index >= SERIAL_RX_BUFFER_SIZE) + serial_rx.read_index = 0; + } + + /* enable interrupt */ + //uartݽṹѾɣʹж + rt_hw_interrupt_enable(level); + } + + /* invoke callback */ + if (serial_device.rx_indicate != RT_NULL) + { + rt_size_t rx_length; + + /* get rx length */ + rx_length = serial_rx.read_index > serial_rx.save_index ? + SERIAL_RX_BUFFER_SIZE - serial_rx.read_index + serial_rx.save_index : + serial_rx.save_index - serial_rx.read_index; + + serial_device.rx_indicate(&serial_device, rx_length); + } + return 0; +} +static DWORD WINAPI ThreadforKeyGet(LPVOID lpParam) +{ + unsigned char key; + + (void)lpParam; //prevent compiler warnings + + for(;;) + { + key = _getch();//getchar(); + if (key == 0xE0) + { + key = _getch(); + + if (key == 0x48) //up key , 0x1b 0x5b 0x41 + { + savekey(0x1b); + savekey(0x5b); + savekey(0x41); + } + else if (key == 0x50)//0x1b 0x5b 0x42 + { + savekey(0x1b); + savekey(0x5b); + savekey(0x42); + } + + continue; + } + + savekey(key); + } +} /*** ThreadforKeyGet ***/ \ No newline at end of file diff --git a/bsp/simulator/vc.sln b/bsp/simulator/vc.sln new file mode 100644 index 0000000000..7a984aaae2 --- /dev/null +++ b/bsp/simulator/vc.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vs", "vs2005.vcproj", "{4A6BF1B1-C645-4BAD-A9B7-7B6E3DB67B2C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4A6BF1B1-C645-4BAD-A9B7-7B6E3DB67B2C}.Debug|Win32.ActiveCfg = Debug|Win32 + {4A6BF1B1-C645-4BAD-A9B7-7B6E3DB67B2C}.Debug|Win32.Build.0 = Debug|Win32 + {4A6BF1B1-C645-4BAD-A9B7-7B6E3DB67B2C}.Release|Win32.ActiveCfg = Release|Win32 + {4A6BF1B1-C645-4BAD-A9B7-7B6E3DB67B2C}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/bsp/simulator/vc.suo b/bsp/simulator/vc.suo new file mode 100644 index 0000000000000000000000000000000000000000..a6b475de334f0842adef743ec8d27e88d43e4311 GIT binary patch literal 132096 zcmeF42b>nw6}J~r>{!5#xJy%1kX{w(iXtkYSWtRXniR2%4YBtcHTKwI?_KOInna_q zVofxb7>&Jr&oguG?tt*JlqBEx`+W!gd(QixbLZZ>BCwnq_6nVXq8+{^gfn5pT& z5v&Bfx2u9xz-nN1P#e?%YXF)+*;-(2P#0_t)&c8+^}!}!L(m><1nPl}L4B|pXaX97 z2A~mW40Z(TflWad&=hO|nu9GtGq4qC3tE7dpcQBh+JJVT0(1b~Ku6FCbOu|4Z9qBL z7IX#O!2r+$^aQ;?Z?GNM9`pe_fStfJuqWsTb_V^yu3$9S4NL|5g5AL&um>0p_6K`| z!C)V-9~c6Lf?;437y(9ty}%e?pBjrE2W|l4!3;0~Oazm_WN-kO0uBTxfa#zwI0zgG z4hDySL&0I-aBu`T3S0sDbEZjLSvgle5j`bK!GUVZy0n_q%)R%e=Xm$@Bel1F$U;oeI$S5iZNjR{=W%aIj8{oHbgfH z+qhu=H%6rMsO^vTe{EyHg8IL4!Q;jpV?gTv$79?7M*`!DKK7+SyG7uOC?EfCK|EulO#r|)M@SY6?!+j`~Pj+MEm~{a2~Ur8lUX{#sXu7F<}1wudn_8NYIwF2j9E>s5=HX z=y~ScKVJOM0nb^~#gc#aSb4Gh{}ax(=k0rU8obMtN&Af&F>UaSNmKS8+<#!Rfn%qP z8a7g^+vLfE2aTK9y48>>dcM!i4;*pOWKLiKYi&Jo`uOo(%36<|Hf?gJt+tvvV(h31 z!=^T$FmA+@NmD0{p4NQCqzPM%9ChHR@slQxnzGe|sl%s_8$WWZRxMhzCizawsw~Z? zPaWkAU)lnBiiOA?j40#FcA*`PAPNqny^msSn@n38M>Lv9bSf>zzqN3w1!!8ol=jY# z(uK+z)Ap2}jRDI1`FE#>jiLQiw<`HsX2siJ|MBzw8CknH}9CQ3Rk&MRZG^xH%BW|lRWc9f6iqewZ8&r^v-6VX%n(_!|< z9?sFp=mYUhc7FESkx4X>d9sufj#bX5)XPFVk8!nU;X1}p+F|sMa;|P1^Xh@AN@ zT$ZH$I|imR&Y%BI+~o=6>O6Q*)Wsx5(}l%=EhGNeW~+Ps&Xa9xiv4|B*0UyNt*5G` z&D)oHP$py1sO)D|X*xyz=B?ysE&a22{r`*hm$%CQe*3p&kDxu-H%DdtFV&M}S#q%{ zJLhe|y=*bxzdS-YQ%w>LKYh$}b-8&GWglu0y=&B9jSV^j=iAR;-)8O4fBx(jdF9<) z&BHrh+h%*xu0~KJ6QX4m+x#vZn@S%jH5X_R?awi#y6w*%{d!z-sr=JgtS3EV8d#7t zCx6!`#+2&jzaGAA;$+4-TSU6Xyq}Hcs>fvU&z$p_P$Za7(f_l2&0Cr8@B%-s54&Gn z|IWm?{TNdmYv%9cyJsty1)idkWc^pewNjpY_403k|Iu*<=WaW3rQ@^fbmSUFNgTf> zSB~cHnmA{37sYxzl%L($Y3a_m*pi88eMsn3vHSf;VvMo#1*ta<4u(x$1X4o$dL2L9atNrwb<9}Sa z;m)W3a{RY1%(>DfIcx8~)ouKzn;JIU?#>V1IegRM6QTnTDC;n~?wp_J)bD%c#UpP# zum0y97cV`#1WT2E*K+5|%Vzd_AZ?;mHh#3FH8?MxOkZ?&ET8lKC-Uh*JF_iL&E~M9 z=!^45A!~o(;`-0nP#07;{uSpRsUJHJnoL=odAZKWd%N?U(qjJZsTxkJn}1_`zm3!G z#+<-hhh=kuk(DtoU%^z(v%>vX%Kf(#d#js&@%p!?7mdvFp2#(ir!>8@5y=_K6z
nfH{c6`LdY!t!**=KiWHw#h`V#a+3M;Cd&J(iwT0j}N9C zqdB8%-h7pne;$(gIg2`o+8Du=J~I6D@4e!@wVb@n^RK${gDHzWXhK%5{m97@wkniy z275iuea2J1i5bQedR|YM`B(gwyeRa)#cuzPbAopD^0Um}daB#+QyJ>f|DEQp0IJ*n zn&P`zoFMJ2OLUsWoD>|Y>{OuN*}(Hzj&p!=8<0~{ySWcr&Ng#@ zX8&*EXNv9n5jlHg<40PnIs$ZKEO4ANq8fqSMVyvJ6^~8kUs}-)W?t+1+kL~q>YH=yNL%?g`Zko=Cqwm%*nTz$0d zL9q|%=dR+JK)Dyl*>~+T%8NkG`Pd(U@>ACG%CkE+?~b+ic5v2)i#ulC;e21aIpZX6 zT{J%Xzjpr?G=G^wPg%P8U%q4SbyfHJ9Wf`e;>~N|$|YF)Em`|5UcXOjrces^5(WcH zG@Tiy&lvK#X+Ha%5~ZBB`JwN4zl&p#pI0bb+VY(5;|V^S#?NOI z9xt7LY84ARlOsaD{%L?qb@M+F-?7W(=PaGS<49@o`YUj02&$X^@9=fztyGPlj+;L3 zA4_}or?F*x^r|s6ZpzA=a`=*z-oUSyy8SIW{}JSK&8a^>gUa$$C-KTHhdt98P#kOJ zHUje6-bZy^uzA>tbKFep7uOW}tp}XrDz+9mql7J2dtm6@(B7jW=X}`KPz!k6WBTk7 zw!6A=oz^g9RW=bYeNp!^2NDHj3#t^{(<`>z7Z zbs+g&kFDP=!PP_G3Y5Ene)hC`fbs~C>kj4s>mAbn!3kiR5#@-+os6Mf1(u`NH;`7Ce3x`%jfU zBu2sj3y^Cto8tW0Y5~ zIAhVzcww7Y?CWw{u+zHu?Z3Ewo3#Y#7u^2yRn=h5mv&wkz5h6d`D$JxXAYmSyH{4M zkuCY0qPctv&jDB%q(iZv&fwJ3z|g zJ8aMULvZrT^TWGP3+-pIIzK!|-Qdh)eQZaXjSAcr*ha>!3Y^dH9j#InG;O!=+adf= zW&QY3f!?*ijl?!;j0?`uCXE~^| z?d)Vl?BAnTK{o?az%6{f71(cY2lm@L!Cl~Ca1XGvJ%+j;TuPb;(GHuI?Gf}G@F;j3 zybPWIPlBhw)8IMqEO58^dGsH^3&5$uAAtkdpTSq)d+>Mg3V54f@K^L};C1i@coVz@ z-Uf5QJK%4ecP#i6`vYLP{)YYrd;~rQ{{Slz6q?}o8TRKuzc0}L0$+l)IsR|79oJ*u zq7Q>!wJum*-aVDNZEldFqrk0 z>tEl*aTm>F`LkP}1?GEw&mOh%QPvq<%kGo4gMF9a{--h5J=Xd6?|diPa-_Gf^PE@g z(QVJFoCmXml=lDf$dK-|k--^=kw~s7Fd}F>J4t?PV(7O~jir5lzWDp6^X?yC8uhm< z_7C&j{p!p=t>JuMyK4Tv;Nd*4|CPV1>A+A~f7;gHYQe38cAjJJs~cQrw6oGWz@BN{ z>+h^fAA6i3u6JpM{>bAvPOyTD_PiYcw5qiO#goW~sn<#f`|dvgV_{u~kIw3oxs zZ^PiMtINTPAkEr6UpXJm zh26n}$S%QoKb+|+djzNLOr$1ypWv+fA>lVUxOL%XU~h#!C^*crQ?N~YR)IS=I9CY# z&)TQ6v!2*#wP0CR2bTS}9LuBNOh$mEdH*KQ&pu%Nnzu7MwbBB^vZhthVC=2q_)eKl zv2;44Wd7#r5Ug>my7P5qv$3~2<*AI>+DdI;E@Kz6zfkHoSE@69Hz?~3W6YPI^5V;^YRN3$N;rjWS0{0ZQbB?EjGm8BNTlq3LkN-Qk z4Jc;Hw;a16#~KBvODpW|=r+Nj%DVBxe7hI8?Xg?H^(k=v{^pi&V}di^jj)yDf-{fv zv5ndn6u9TG^?yD%%lI#BqsKSFZHhe`TiJjE`gp#ru(w6G2~L+@*v-(rgF}@K1muIGLpaV|L(XnUF~Fl<#azjLY5;`Q4i zv&ye#{r?4jaEBMTnZX@X;7$qd zi~@IdaOW1dOM|<-z~vFq8Hu@W1RUX&-au|G;JBdd0_2okfzfmTNPYvcl|4c7+Y4Ji z=dNuIxdsFT?D zJnx3UKCf*QvK1MHyjD4nIqy@9#d69jxtfOys**F0t%0*tYuvO1!|a=-dZLXfa{5^Z z)@`bT#@LR19v>dsn==AfrlUcApO!X$tUt&dqbTfClQmP5HC{L=gOa^A0w zp?jhAb*;H0@V=$FvU@1~fY(`!qXYPC-g^Vndf)c}MwNX*I^QsC?}c@c{H9>r`)x;Z zYlDNpTHs(HXTFC3>+Mh==jwI_a1v@ykn`L}fz5#RD`#0x0u{hfM$X=TI*>aH$eG94 zK<-?SIA=NLab9q?^VvXsVQ{v=i-G#G;H}Q2mF3yso(oRDSAcEw)!;neUxDrQwczXvZvy?_E^zN-Zwx*N&inQ;u)h9L;Qoz$ zHTb%~eUCi@{7~Rlrl9tBpYB;^@7Ed_mSwHrR>v;K9*eFB&i-mUTM0mA_Nr*>)B7xE zeOrFp%9=o~4)A&v>niUFet*Zp-UgmO#`yGOY2#o1klODEN$;`FyMHx#+k4)!gqFA{ zMj*Mg7qsBiPk!CpF1OIsYZEmWKYlOx`IUR>{w`6~JIKZNd-L76T~GO}%lzfB@7r&^ z8vCH}#D1qOmp*TfZ5xww9M}Xj26?YbXE3FA)~M=T*ITiLC{2KzewzZNEl7Utuq{!C z;PmeZlp!Gb4aL@PX`eqW-t&|E8)W?5&@^r@-S2Ot-#51X72g0c#@=*Cqjyo2SFG(7 zTXWWeeaHLp)@>{IK+WUlJ*yp@eb7GVy)rJRwBE5bc-oM+zh&|KXGz{4KYf|C|3%He zi|_BJXS}1C)hvGhOMTw`-&}T~QoT3n89{GspAlHsV?yh>U-H0uwNQq`B5ZinrN);BoE{{El=7!aIk z2Lg}n7M$~eT|q6ddvN*<3T|+46=KgNH+mFPjuK@FXGdTU;0;YXCIPJdx+xT2yS?qfsfX3iMkjnfCw(=QBW&Rx7a{e--FHnQ_l7GWv+7)v>UH$i$Cvgt14t)om^3(mBwhF=?O*H-J69DiD6 z&-`#LAxkp;bmn|UKBd(7*D8yBx!=NmE=m5^aWdZ`P)g_T%AmB6fA;;Ow$ugnt_7vO z0rEba~LZNm29I@|GK?cf|oYGbd6t`pqq*y~}t z-mVv%?QUai+j#xpwAaP8=_f^L-g<-fmzIgjWkw;res>|^$Ox$L}XV~w?* z(pm#Gf&C(JErN3%CFglN0p}V$fShG-jNy5kpyjlEkH@la8k}i;b6+mK?^BNLJ3IEb zj^WoGdmC)a=T0yGvpVgL(G|N#aOUg#KpoM&g2OD^9@{eZ32q1M9k4xLdRNGMv@={Y zv~z#{XV>AoLLXuG56(3Guq|`($+F*}VIG6RuRpeHhlc31Zg58L`$fizeZ$W(`<~HW z=%K-RF9&0r$FSfq%SK|G$Ee^;<62}>v~N4}pS9#c%Y6P(^=_Z*&dvcuRpodGE%d`Jc`2Ctw)+d`c*{C72xC0m0c8Tu1JWo?750VSB!5!Fj)ZOG9pY zaG2RUX||7pgWDbZ5bVb2LxXc{I}+P=IWsudBu8T}hn^LjWjQ|lW*4}lu+8^`;5^R} z!JQZ!RN3j+mgTJA`eC1qU4cF)xN__Zu+vk8Ro;gY)=J*v8;ngL4&p1GcgHw&1qLcCX$T zb5C%l_01g9J`kK~@5DCkgTWbN9>s2jek?eTKOWo@!5JUsV0*qNgENn(f_pYN^LPZ? zb37NEE3d`h|0wQ14(Du~EQ^jK(8>WoPMHE~f@vW6O~+Qw1bZz({>A;5WV>fv_05_2 zZs)a!o$AE+SL5>faF)fgX@ESIJ2w!{{INPUp}S8*@4e)k8bpR0D|C6N4H#@6qZ;Fd?f0qi|*2iF_@Dp39g zOsn7bpd9=NY4VKdG9(=HGVYcgFf1w#9GX z^ch+HPKa;dkEOKtZ~C;Itg@$QD``Zu=i58&(e_?zWo6I>*z>!A#My)7j1Y3RL8FRx ziWbi1b`CB@20mtQuvnwUPFt=ld#b)X_957{ z&~3mUt2^ z19+aj(0c<{$@>6T)2^b2f?;4dm|2Fkyd*3wH3T?9;@q<{`52^g-i{h;GywjdO z#Xdk$G8w*<@ndPf|00!t{-@t(*8774XJt9H?X!-gmfgNz59E7UGWK@oB2I8jD%T#g z0&;0iqMy7Gy93bA=;8dtv3qMEXHMG!N2;zMaXo_TnQ>L$D`JFOvE9`-pfX=|lGQO% zK51T35u8`iARJSScW#sBQkLJemO0I(9GT>dc$Qb`3gjk&Za_)VF-6tH(ExwR9B4Jg z{gV-pJH6c}o0@p8qNKTtWvz$<+WPGS8V1)mI6pQ4`gkq+d9B_X$2zYkaYpREz`0%G zMq_(zQ-br3JAB9;8Ju-_8&K{8rd93-Yk)_AoOlLUzt6?zZs^B=@($2Pc{f+tj9t!l z^Ko$Bpp)OX!TlIqO>{X2v-&~nC${2;?b2xJXUp&tP>ghP%61s#Xd|4QFml;;jb46U z4vfOE4vd;|n*$@FVnhlvi%fDxCAogU=%m~ooVNQCwb5zcp*8kH;rBto?+fhZIaZTG zc(@*Dj_o~e5u9s=R@ly2S_fwv{V>kgB{-z!29IDLUxHG1t-?-CnE}ZrJLHOC8Kg2d3{XMt_*cW3fUk9iCEw=l? z-v_q~_K)FLkIXHzvN5*j+ax&4wG}_I_7|MV{LMW(dD{Zl9^1CrA-J8fE3lPr!D;&& ze%5o(f?x0O8(Hx4H~qXX={Nn%_cA!!*X7}7xv#}G#$F$ses^KlMc)%#C+z*Ol_!GJ zeiGYyc{(`H_ak=J$AUB7_?v?sTZIO!_I`XrMnw*)Y&9D=vPSrMd^2qQn+9jO)(XG$ z+k{YMZG-C&eqP76*xvK51#S?w^|xonrSZ=%)A0R9zn#D8Z{FnlSpAypb{GjN@3OYy zXk`iO0BcZftCO?m*oqy+wB>9W_M{G=IY?YfY@@NfoM{{l{oEbMd2S=St+p4CGxBT% zl0vyn|d*8_6q;krO^jvr?B-8T9;znAlV_Kbs$W?^O{ zn(fkgwVd_myxID5?wq(If}2_3P7Ur%bm~9(cg2jO@A#dWBRI>**`K|Ms?1T_J8$13 zVb&Vg!`FG+C13a57d4NspH~acmSpQyy!)nCItMDya<(2@jxon^QO=gQAyDiwDXlT8 z`2C-YdVkk)zOj9;>rIu;p{>|UC9_l zE8ZhH&(Z)W#)`yQ8_KRArR|?FRd0@&cK6`+4?o+P{krP?>-pdA&hO$Sr_C_*ME~7L z6X^-e&HAj`rEZ0NR>oAlweQDUgL@EdD(})m!F?E~dqktgv0Z%X!|lfUUyMwsX(#-A?DX-5K5V-3;g_=Y6xL z?E`Y_1Lr7~xj9IFEwD}7GC13#A9?_Vmc-2()Kg9ymi@5q)fMMkQy@<>*t@)6Qk#X{#F7s;(bdsWGxBrk(~X_d#qTid0ErDjz{Bi0yqX73r+&>g5$w# za2WUKMD+9EH^6-($G_9S>EMju&O)CJ&H;7E?!4eHKtBrRfQ!Jz;1cj#a67mRTn?@P zSAwg+)xdnNL0=251J{Eafc%ZF82kf#0zL(wfzQD|fve(wfiJ;V;NReD z@D2Eg^xvVs2S0!x!B4<4{DRJcLbeXuh)>3<251jBPP_Z+xYM-2b-+Fzu45&4>Qe3> zvbN(~j%7XKoU38m!fd~`GX7_=#@W_HY+IU~W1uZ=CfZgfXWX}z6l+LRKWj>{mNbnt z*2H?~pM$e+cn7S9718<`_gBF-7N@@nBIb{HwSlH zaOLRdz<>Yymq%u+yx}pDkG*w22cWE+>LkuOEW0&ir1!2^3vy~lJx8PB{9)eb3%{O6 z%zM1*dy&(7%|_i**PnbA>R07S5zc(mEX>h6_q4rkz&$w>yk+415Xeg)O`xt#`KmO%K+sdSDhMCX0H-2?o1umJdI*D^5 z)9(#znM!jYr)&i*dn+KvEzas=OZ2wE4MIDIQ~Ch?x`G{mG7iY~0>&j}8j#xq90-(| zKu$RdnD1;LC%kV)gInXX-1EVCFZ^6@Dc?UT{{Ei7jXLieK(i+G%ldY@J7k#2D*QBe zXPw3Vo8|-ye*ZoF)Y9a$5!WPaX)d2ZDcAK!=^k(Fi=$Nm1y5#+VX>T7+5 z%JNn#KJ{Ii=TG@q)rK40owKz=du85ZXTnAZ_h983fbFqcp!)=8yVwD{6WVWx($Ds~ z-F%$K2f%ee?;d`(KW9ejJ%h7--UHNW25#En9Jegv!_PZ#Ft+DAG&u8hw&nTK4BE7( zzlz7Sh+kJxK-UE&_HwzHlZ^gjP~&bVx4=RJD9 z$z2Ax%tM{T@yt}#*h)dJ7M#7#XyEZRLmP#R5{g&kF*)P6Vg!)0SC)s}IJ9}JzW}Zs zTqDpvj#*>Ypm`gmJfG*VJjzZ$&hrfhrrig~nRZ`bc~g&Xh}|D3GeAl^6WhLWba19U z2AJn@!I|&LK)C>z);u=@O5%)67Xpv>w=Jw#o z;L^Ih0`BzSev8)he3u4yLvUWNGkN8{;OsXK2e)e0KJ)dib1!AH;A|aR2ABH0$-2RL zJ>A1^cWl2IPD$VVrrj?%SHY&Up2r3^1Dzt~XzZGCEQ(b&A-IWXIbmI?y(gnFHbjpJ zZe#4ju&wjMgYzD{(otU>oGoP>w(?+bJ+L1N&ee%#7vL&Iab==u`CXydGhLa;*~47H z$hjhs)6a34qGziLImK0l*Xe3PZVliH!rtXPSJ5vzKjzZCk4soV{&hY@QQ{&m+qI8{wsJf z$ar+Pl}*ByKDfYLgKaFf%=+aqF^>xON1hKvo@;YlC=V6#^uAd)O@Zeq2S%I*z_uu7 zlregFzpX1d%h?H751oOW*X8|HoCeEz{2XB0Iv2=UXXgRARRP7x?wQ9F^Hb7wS+ABy zX%F<1Gk;}QkkY0II3PIv>_^J}KtHeV0HB--M&{ph06eg36_}LKjU4r>n`u2ipJiGACJ7@6u3~%4sH}Pa^-cOISMpwq{XM%s;ig>gNA0XG}BN()m~G{%6;n%22YfanRX#+7UH& z^`kzFD?6k4pT)ENF&rbN2j}SC$AgG_?uwE8wy^ICKY91vl{8~r4?E3R(+;f1-LF=h zX)4CMZ^L$nHOy>wXpG+gPVs#Hts9T0ReGx8Bdlg&mufeU0o(uK>?*Q|4#`GHSeD8x)7H5Q}{U$hP#Lm|C z0zU@ljO%CMOw}N0S~+KPa?7FRY&*+iIIgY`oU`r~vG+x<6r6smVDF7ywZJ*f4~DB9 zoY%1?wt1{o;Ob%zf?Fpz%ls`+HVjVNCof*x#=%*Z`q)aNf}gWU{WcBGw&@d^cIeH6 zb6&Fr_GaibcgD=#05xrTY9r?uC}*GMe>VScSHZeZI|G>6JM8+os?|?1e#%WQa5I8C zC^+k7CbswYsNgoiJ{NmK^!dRVV=ls0r`-bEfx8Zt<+||0%zg{je2cNBC7%a)5V5{- zFB=NXSMgpYZl8>)noAAmvrwG->1VlZ*NR+<1q+K`b4X;F9z~np`(oTvo(WF-Ic)u$ z_juSmT&d6h7aQ)WIP`1|Wj<}t>*M2mZG%YH2)iD(dt9l_?226uXPd4FzuwrkAKRsE zhyU5{qS$6yV5g^grN$rYc2QCuc>EGPu^*ZLpi6UDxtIdnVig zqa3?SaP~vvmC`l1{8Rq3J6vAQ{IB5}23`Qr+0(K=q2>Nu;9d>xqXPF?a9;$s8v0w{ zJn{SBT;e$=$U;q&Mb5c^ob!PEJ3{>S4xgR*7i-o2E`R!~Z$I7llLKp3LPs!5*Z`yw zu8;jPaOD0A@JdYZ5-^unfLsN50~o>I1ahW*8+g9CAfrQSDV48At1?U7Cf<~Y* zXaY6`?)EnYn}aQYbA9LdrriqdZ+)}`?g0DS9zF$h?(dx6UH=ZCBhY^kdTX!^=mNF{ zT|qbC(*k{bV%RHep8#$T`hXpPPY3&goq$gdTu+#0S9Jfd2cmZayT@mb?}@z^*c%K6 z`+$AH5HJ)B1H-`xp#LbePaS+R;rhgN$$nseFdj?*u2Cj|$>0Dm1^8Pkrk{>J5X^|r z2Z#14qsI?N9|4X8GXZZvfxkwZuzkIZT?_qMaJ8}D!fuFuJ2>0U+~D2`&Yu4!w)(x` zvNnpX{wO&6$%okH@o{kG@fmhw^yk5u$3KJnA~THAE&Wuqtv&hK>OE%5moqSO1B<%+tZ($lrI#9o_Yt%7r=)!Lha zObbrmBeAXTnFa2AZ0r7l0(T2`Q@GoL+Yx(u*!PFF-Ty1fl{l!fhd8dx2|srZ9u4k; z;5`0ea32L{Kl?{;Ul#nn3htZWypHd&S4RI3+}7CNhF=XDVXBwqY>-H;;GBQ27+jr# zU)|u=3$7=A>j$@G!LM0xErN5V)GD|h1;3ubZCCK?6Wp!^zy87P5!{}fZ_nU{1h*;N zC~Vuo=mK{HwzHk13*7ABPA+iQVmmpyEx4Vqhhi&pg42F9xF>?^2lr%fFBSY=4(^TM z>~C{}`y@Ey(C5K@8Jzw0tKjM~8SozU0_!+2KpF-o-voPe^ya~J!)_FQy@P`)+b*~r zf~&#$aPfctJN?c}@sIgby%m%{3Ho_zyZ6m8wJhz9VD;c!;~S+3LX~eXV`l5(Mrfmr zX}be!N3l1{IoCC+D(!%ry{`jM++&m59oQ2U*Zy+KzPZYNt3b|jrTO^H*mADVZwuRf zFFE&b`+LV9Gz{E zuLox@dIQ_Ej->q0%JwRTb@#X6FthiDP3x$spW?_V=l-jl=leH?=lec5uhr4n^ZgJU zW;R-yHjSzr%HGsX^;@gp>t33^s}#63f=hd49L~Ns!YJ!r2mdo^7=BHHv;N%MvMr=_ ziUDjb;HYld*Wicgjf_8IINMF5HD)$HwLH#G^)o^^Pc^OcPC28rqq=FGhooN2BJ?%ME^yD_+%3fw)x-G|Pfd0QfD z;~}8^Xz1PU0)o?ET_TT~@lh-Ljx;+S!+ zy7_k|@AUjDe{aKfVP0DSZRbO3+f-*DKN`r{(^J$P7o77UqjCcTLfOFKt)Md~Ep7O&FyXa97TXf4Qjl`8>z(5gVr zc;r~-F=LUO@yGE)PRJP>?DtvBDRA=U;d%5k4%#!#e`Ao+I^LPKJUIQWZS%4``kAL= zs&UG=EoYidfn_tM$(hIIz_M)tl3#0V%hM(}%it_T-%i1qW*g8L^bF3j*#1@n&Xzo% z>2?8f{ehf*y8+9&J4j{O6Wj9b6`W1MW|sE-=c@N-()VYjT=LKHUe0=xU$V4bQBk}j=_;LIITtZ*0ZZlKghX*3Z@==bf>|D5;fb?+x@D z3iL~N+SZuvv}HCn*(y?O((eG^HG9WRtDkq>7BLOT*|UcM_OZ2HzjA#@2q=e7O)(%0ZFsoW<50qrvzt2H~}aZ1O3W5)Boc4pKBj+ z=c$&%G8APEKFHZ_Y_n?HhMW;3t5>wwC1*b|D%%fT!N`?^EkOfdf0Xk)?SSo~BapLw z+3$>uj?r@V!7f0t?a6uE_Gfv{1#(8m^MIW9yel`i1-ctLox6K*J%Y1exNBStDM)iC$?$bb(OPjM`9b-Mg>=aJtF+vebvuA+IC=#uxl1V0%>uWyg%6?lLQ`Xe7y(P9g>efZtQ7^}KoqrwLU2pzpbG;R~BVLcY-g4G`&9GMv zy*8ZdY>y|-df5cd(WN|&dDq>s_FlTq(cdz=EBzR{U2xlC8+ANxk5^k}d$r>8i^SPt zl=FgfRx&8K3krU>VcQb#C~)^;>+f1QmE}R~?r;wWSC0KOwsrdF;Ij6Dt^P}Jm}PHZ z^S|t^;4Jey637Py?&IJ-4bFD8B14?(hqcg_#dG_+^4j%7dmsGvtgX@I!C9vbv8~g_ z!Ifigjy)2+MS*J`oZq^Y>aPd3_0p@r?SO5)>=>N)s6Tdh^uXY3&)Z_FM+9f@e=V-f zZ^SYWBjr?VN2}=tKY!ywnH`*Em=N5F!I}1y;7$u}6}SdKNt|u_OpbewvkGZVubcyy z&p7P4n^29G%#}eiZ0}O@;H=@Tf@`tD2tJjAWj7D6+WGU_Xr2Fz=U+Y#Uy+>tw{QHV zzY|*Z8-Lc5b@DT?m;VA%-5H)c^0_8j&X%}3P*#M;Z|k+NIysaH^c9}g5Uet`h6JO^4R|jzn=ro=>TXZCZZ|DCJR00!e*O zd+qS68-C8h)(OA)ztv7UeXE^)#lC5Annqg3A^V)IZ*Xwd=8&+5hPG|n?=6>H+Oxr| z+;7IrzP(=VKA^Ad{6S!zb3nS*^J%$N-xofH8TBw$IpvH&>9=_O3u1n&n|~i|D)9Gl z%h`7s$EWFdkLT0k{Keb-nY&m01`0(%PNO*al~m{Nuca00G|rP>i8a;J6CpbQPM2M= z>o{dsAgA8|pg1Zf&NZPj6r{AnB#<#6`I(uFxLbp}J2>m*p5PuTaE}D{WPy7s zxIYAEzAps#a&YGRN^ox$xVM6PKREOKAh>@NxKD%ovcP>6-1otm?+?M%pyJd0FxDup zO%vx61SPFgP3!toSugx7vujtSL4j)+oNqa4TIOcKwF}PqY5U-uZEG5tdIi@nIQ^W3 zD}#g6Z=c{s2WJl-6Wp}mjFQuXt6DSX?;p*`den6Kq2EH3KQXHH$re*d68-9DEE5}h zG@N5vYq>bP@Pq4DRkZRq@Ans-|&W6VQX% zha1g5zqi1@gP8sb(c*lIyVsWfYVd#euO{U?YC{Uw(42^~bl+c4RddC8!w70C{Z3uW zZ*Dk^OU~|_TCok61Mg*T;C<9i_uO@{_0$2l;_;Ycyldaaz?qs{yG15Rq!WouxeoVjfiwr7rlW~)3tR_^-S z25oyDcbraseX*6Dft+`77obc6a?X|5?Y3wxZvp{(rq_l5@{dR$S2HUiA zgKLAf)hQ{GJC@j7J&!FyE%zSqUN{cQwFS<#m5SgTU(y)YI5k-_j;Jmi6*vjF-SubgvIx0AiA02+j1n2!dF1Txh^Zs5J_U{XvJ2l>qw6mh$ zEpWZizWaum?O3$O_Bwo5O>PCy5!?9HDLBVd_ZhpR(>|kq?l0=MbND&FH4EGQLC>eS zN2sKILEHS0;KqlaWt|Y*!NHmDmDslZtAaD%tFdjHzbp8;`q%HXg5T%i=V~Th?;+TV z-=8gK+jU2v8@e2w_v{7D(({#61%9rgOzZgHFwR#N=R;*H8}I3Q1 zDcyqWkKH}ELBaKd+atIm(RukigEJ6YyR~WWmGdt9S=|N5Z3G&E5kUUR7)Oim#w_al z6pMccu4)|3N9pSQ9pC-4`If(zKc4xB-+n!j*mDqe{?}0^!cC%#`^TKj`uorC6pSU8 zmB8d>Hn&K1l2%^%Xa6SVyx*TNhtIa}6bEhB#y>e@ns;th@C8u519I*OIIqtHB5|u> z*c8_e&hwoOikxZJH38Bn{H*6SGbZO^WNS|YZBGE{$@KAX4!1OJ9Z4FSVv0wu1B^4u zNpU{ylf%!os)zMET?0wG#M33x68g$B==j`PxIf7gI-y6^WTFzF(>Xy>HHnrN{jiMZ%^E+o4-$= z-mu9crSor@JC*pE@;7g#glpv?=YFSGe$v#mF?h5rtFbxxMf=RSgd=^6KK*!AMLdjrX@MfmxoPHr&RI_#Z7LuG#n%JcaIPCv)| zJ;Qb%Ku*~YL%%7(8R@5neMo5ioP+7-yo&$X9#(oXc1m!Ln#M4tYX6O=dVDrb6L45) zgQcAD_Xw~lFi_Meo4L%#n1!wU9b+euo4;A*=$yVwy#Eznc`22>=QQkEAhih(o)7E` z7l3pf7h-Q%cH;l2{LU2I)ffZPj?K9(>pM7RC3J*X(GQ4ZD)nj^llL4sBlGgXHAKr5 z#VDQk>wB?`-Kh__=D7=80!(#zXjJ7s;+5EWYFkrx-1Kxt+yjF!z*Q`({fmXoF;aWT zN2tl~tztpvxlYTrNpRiJ*ZjeoB)#FiP-v`8C)mySwOiIB)`kB z^}9AWqu6yoNj0o(l+o`oVA`F*<3RZ{NauSATff(WvwW`uWfh!~->Mk;)d{W_cHKCb zR(Gaxb*JBE;ph2W$th{qQrlfi{knvo(R$nP+ch}-`iEbNN^RkMPe3`R;CF8LT^yW| z{*v%}Ik@%V-p4k=d>Gsc*nh+J*x!TO82k0G>(SUSvt3o68EZEVT_1b1u)Bob0~9U^$y?QTQ~8%B4`R0KGZ4oi636WN zzcI)5xyv~6&wId8k8ZKDR}dGXncczE0~~kDC6R4G^6QH2op!b(XYAh|D8oVW8-cCg z_~4B76M!-sBtLtNeyOK8=BJ)=Q^D`%@Vh6tW@uxP@(D=i`xM*reG{Bx{UjzmdVUz#bKT zX$&@v`}O)A8h*}64h#Fj(6+?iU^^zIo`RWu$E9hn4nObd@356Sg44beTfh5*vj;p7 zejgY7{tnzjdNlcs_rl!Sih#TwUz?*h-6nU(4`wf5p=@0Pe9UeS*{80o(Jr zm!h9zu=^>>(1PEv@EaSP`Hl;}6DEvL~?3;|~SDKVo~1^c2~s@-kcp zbb1S;5%vpk%IlF<+cz^5_d)W=koWfHtmyOSD*3g{yME8pqQU$-MJ&y@9<$ zX#?aY17oO?dSp}VJ{gn0nX2DjVBg@TqUF4rLxY=%mQ#)b*2pnHE~`1TlExZq=P$tH zb3@x2UjjypcY<@5PhNQsLt#m?0Ftv4LF|JN>e`O>v(EAXb<$WMS8`i>jdQVbDXqH zUY(rLxf}3U4G2K2tc)kcpBdrW9| zFopxgyJ}uu$9QlQ72=Mib@+dqTtm681wR0Pcl`$R@4=1WCU7&j1>6ce{vg_SzwQKg zfxCgc?|}LKm+zxI0Nj;*2zcxfw0i+YrpLhJz{vC@cnbJl*fZc+@Emv^7_m(IBHD=M zyDz>sX4EoT8L3_YuL9qF@qH;Hl@ZG5^cHv<%mwd&cfotWcV0dKp8Id;zk`p!$KW5} z6X3DW(4T{Ez!%_O;7jlo_&4|(==Ux9JMevc{t@l_FF&Jy0d|m5`wwlZxBoIv+u^K> zl&*Np4X@Jqw+*j_EA~IKerNyWl7CsaXVsA%F+W>A|6Dr%)>VlXV!8jKmnE%k{*DoS z4Ngeu{5$4OC4PGSTXWplU)}tV!*^nwvvmGOy3(>F`%f2f%B}_>q*VTGtJnT&IEHiu z)xCblfot$rO6TwVuC!SH=9{FncYbsy)a~I|I)CS=r6twBH$E`{G2tY_WgInv{r?YE3sS28 zwafOqbH9cCT$29ZoBZ8_S4!t^8!0VIlE16o6#w(HPe!G-b3kNxaB#N8LxMXxxN`L9 z`8eB?Q9(Hcc)k^Y5kNT?$k}K14t+sz_KQn^v+pZ{GvBL&yCJyx=v#q(?XlqOhffCQ zD#$#_!5hF)@l7CSU;Zfcx)5^4clR7T*08{Bj@=k8Jqz&Ke78`Y_8!Wyd%;ab?-*&D zWAB2k3=GaX*ey7B+%)R~cka~t1n0SjVyj07XI=U3MR)Wu!EJy&4qH7dIP2vEZ1oet z8Mj`oTLV0!fs6>wHoiZ$_hWo; zUfXHdt$n1YCfavYEQ0OWm4f0*Ku*6O zf^#(>wT`2GZaAL^08*t3{TK6}H->t!QfOB-NK;IGE*4TGqTlaSb=a_Iew*BM&;10xo09%<8 z+_l(`2KP*G=fORPZC(5^ILq=Zw%75e;BLl#8C!WPxQnspVw?8E;7t4We4P9IAHgZ< zd$)#S``utY&|gPd`_@-s`(0tysdGKQOH4a)#+={5*%!WzW8SYHupNVb49@#n4vL(8 z6w%ZfsN1Fk+T%P1)G9Pft)SiGGNIr2XeOHD?vH9 z3M4;A-pzsQBspv363_-*59E~Ffcf4D68B(m4;8q_gL9-#e$Qg36^rSYqy~JSd};oE z+^^pooBtgt-&W6`-0W4i=_eGkvi#a!yHU?;vX@x5N-vPEvp2SWI|bJT-47_!LGn8g zTfZZM8;w2^DEEWpXAjmd)uk=-8K4ZnDfu}A(J#$9TsiC=2ahZGIg8LQy;)#nJT?5T zDfnF*em4i#9zWmSR30pFkA&_1vWIPBPlo+MXrsnM*iF&SQkLZ2lN3oc-VmD;W#0nc z$ODL1EVnN(C#4yX>jRoE!|$IN$*OW3=kt94f72oV`=&_`VVq8X=X3-)uX6n}%~4rN z)Jcpemd?Isy(t?5xov=LO>yLtGa`HCihW&f5b(+sM+`Y@z$;fAt>vr%XC6vBAh##* zzH0Xk?P%hNlel^BmAUGv91QeQ93N~|rvf?s&IL_*}k%MRA%-oV@cMZ4>QAh*s4NG=Wkt<7T5pARcmhE zcDe9$FOdJ$HWj3F{`Qp8V*cj43vSiT|73jEY@46AbpDREr6uL>in_Y_f5`P4!&0v%!hrDR2@v2b==z(Wima!5QF8a27Zl%mU|v^T7Gw0^r=_H{c?0 zF}MU60WJlX0iRVk2e}4Z1&jnnfNO!{-av3Y(C_!?8^KNBW^fC*58MWB2X}xw!Cl~P za1Xc_7)c%gj{u{_L*QXB2YBxu1&@KhfG5C{;A!v%cm_NRo&(Q=KY$m&i{Ml6C-7(R z5_lOHMP31~g1>^-!0W(B<28u4vFCz!z`Ni*@ILqedVdwX zK9Ex!2bKe!fLs$`$20zp26F2FTVpL?>yxVkY-#3mBamAK7^jPz`P;(Owp9Hrv#m@0 zIFMTx*o)M*BDvLp?|f{6PO~SuZ{W5>e~(UnwYdn(z9u?x71)j88U)uA`$+88=wpK0 z0sFYHPYgW~?&Ppf54{51vDo(VGlKJc_h8$*ed1}plR037JiT*af;vR)*e*&8Z=Wp`MdCyt}*FLxx;W`E9@5Sh6{W+>AJqz6S;n#2F+|T3v zvAduL1ZP{@6WeyRS8%qqJ3*0Ko6ojYWiWnrd1LMW_V@qOa}}SoXs5S&zpQ!9mzLDp zDauNGkgE-B?e<)4xwXJ*z@BKYms=IsYvfXIH=V6XZBI_;YlLkL*(>Cf&44#ybCB|| zcUhZlg3~ran1AQsyrWwKqs=zKS+)?32Yl5g5>A;Y~=npIM4SPu)R1oC%=DUd*8kY&bId{uq^*7aNlA(VtiNNehBWT z;B4D;`K;}mfq8g7R}@}j%>uU)w*6-10_SgI$*o@C{LL)Sn^rVlZ+*D>=<@LMxKBw; z+aNgo8e{iBZyKES=ljarp?!kF|13?busekIeCf9+x(DaA_YQl9(B{`S?6iWC^Ic~C zm+c@z~I0#^a} zSe7{3B*8h8vpA4P=^z%MW-s&otMtBo{?}}(zIox-zklKHPv-NZS%h1!!d`O{wzYR^ zaF}K1U|YMl1ZPyeBka2h+-=zHIhHtU;}N)a=sDr%xgW)DjD9RQqrd}UKT+WB!#3Z< z*$e*ww=??1@G}y<6!u%88^F!QHm~=B!z}w4dnfd_1#UG8xiegQv~{42#I{B57o08Z zw_(pM_`Qp5%lV+deHz?11+FFq_j)%&r#zZrTlVI`SqJUI-lpK!6?+Gc^$*T81H;~< z;I}unW!bmD%?$3C0(VMq7Zte6vAstR1!w)u3HyoA6>!gl{fE%yaDNQ@3oe-zp_^pCLr6?#*+ufqPJ!2J~V@^r&gf3>i^-j##f0(;f4*9^Tm+}dHU7uvFH z5O)0nR~~lb(5>*>H0-THw}fjMcE`{y;5vuhqrmkFd#BL2mFxB_=saDNYOOVWOfZ9n=~aF*{Y z?B&rv1&3Mo3-Q-#i-c|5>F#MhhZXn0s z!fu708=Pt0!ETOzH#p3)FR;zytKb~1zQ)%7yMo_O;rB~$jXAy?!@qUDPH4=s^{_qP z2EiFO>V;iDbiJ|~HSq#9fvc$%fZvt2BJgRj`wgq0R}I^hR&B5baHZvOpA7qi*Y8pD z$?&?sC&PYQfGe*J!A8I*#6BH%73S)z98`b?pdoN2wi##wT#5Ol*zZ?69r(0(OVAAX z9fz*aT7Z_o6J( z*v&&Xglidg>(CA0+J)UAv~jsp*u6qSm2HP@`|J~(eQJ-e_YUp(_6d7vXjgvwg*_p3 zIo#y14-IYqJ~HfMLz{M1*t0`Jm7R!fSxzo+=LUCva9+oS*!IWY7W^&`zbk`l!ttxa zzCJWvwd^@;<%Qrp&x^tRIXKJwdDvfub~gDFwkrmw>h^PI!QaO5n!$Ov7Pi;1QgEiN zjcwYsf-|nH9CqD;-$vnAzu>oS*cG9-CT%0^Z1x|Vb=oZKHlbY^bq;&`(6*r+!rnEs zbB^7@-Z!*k?9j0H3*828eArV%Zv{6!?1Ky3p4d)6s$c8%&J zOsO+&B-*~>*ymiqy0ETncaC%AKyC~$PTBsQ_a#4LjeXMklXEWRJkGxBSe^WA6Xwx2 zI8^q&koTZ-aCF0LH^_5r8yr)iY}d$qy9Q_Zx&hl`kKimrZ=m!CDc=DZlfTC+r|b#L zcV8g4I~WC;fzcqP^_pF~j1A7?3XblQJ-zaLCkN+T>vZ6CoDrO9&jen_S;1+a226W)a9-Q_z_@flaHhQw*w%g% zoc4LZv=;?u+Dn1ga~VkY=yGi1<`u!&hJFi7du4Fl(boXm;I+Y-?{&a(ULTzH?|^A< z2+n+O2G-dv!I}0}p#N>bY2O4)dwX!Ey&F`3dxA6Vy}&Zx7hE0mUBI;W2WNYE7C`O#1_nTMhgK*7h?*@>?E5zgofR=Z;)w zblQN zch&Yr_X|$How4m7#rG0?Z`phYg`aih4x5s8)x7pma1GF-!_V`L!S4Ha?51#2f@^}kKelpE!SCSUW(Mc+i?A)IWJ)qCnMKABKl4~fNl1psEdT5KJlEFk;7D)0 z{-4+Sob}w-`R;q|wf5R;t-bbs_TG;fWxmClZ@u-G2|SNY+I!5VNZ&8bF`qk=^p~l> z1qg*jX4LsB(zMA}&9;{29%|b2lEAoknz~qOM*n%;dbus@TPd9*`+*tjTP4l35uzg|qA;fk|f0n8~BQ{b7xzVa)>LOc};mGV3L9h79A(IAxp_!#V`k-E34~ zrd)-|XSQ z9y5E!jPd0qX^wp_n^C@3q)W=aY9^VyDcxRnabQcODa-P}el**5^Y!(|J>&RwH)FqD zA>C4TM(}&meoqCq+$_D%SxGYYEwjFDRoHYN?I8`@E3k@Y2bgi(Zy-%*V#dEs%{rK| zypuHR>upBgIzgJ_OkXpZq#qv&>2EI|DSeGtGufH;0Ta+1nyELJoI$ydS zTS=4eHfH$kAWi-|n&n6rlWrxuvl-_^#igm+UCl_lhctFiGqT)Ex{mDLX0(ItqzO4@ zl)0!h<9Mza%PUJ$zJ1L&mQ<9+zhUs}X1^Y0prml&=!|+c^Jp|Em@$j%F8J8*VaGUQohfmE8wVsC*5zG zNmIVf1KY~1NMPHW?Px~dFD6ac%Zz+^9~Z}r5@yUT%G`rVLbIm>d&%rIGurF~>&3S8qt((|$*u|P3$t}*EdN-V z`u@p`w(+4g6KvWB{qcP;wq6$)jezwOwv|k_mS%n1n31-q^$x*rXKBX2dVw{RCT+{WI+z_7 zSQoQyf%P)$6WB>+L(FL7!>msZe&eLs2UXNb*dA?Svad93e=~GNY1&$Kv+C02tZUeE z{iC1t5L^29FzZung_3)v+1^J3E1`x2Dqwzi@!8h@7ufUGZ`;Z(Std=H-!r5BR!S4rm}SNb>4sw8ndM0TC|yu? z2MuV{DQqWcSk=I)oAov$j}xRD%l0*sOa@3(mVsuu(u1r=1;1PDcbi!$`OUGO7yRzA z-+gA(>3nJW`9py%GJDpnw3a_$y~4J<*h=fQw)Eext&3{_rw$l~bER9#mNujQ%9vF! zDqOxlZ~(*_+Jj zNZ)LBOJMWN?hNd1>00u?H?Zf;UNF<*g1L7LMS2)+s2Gz&)#Oa!LPhog}~ZMbH38vjJ9#C zbZglTfpwN{BX)dXJ)~);Jp(&IdZ<`mGq$(CbXVB{ft@5x`x|5?nGBU?JBFJvrye6s znZ}u+M@v&@rv<+=>^C8>v&_ymBkk$Zq&>%sW8Nrf>i*ooCYzlf*ac=&&6qQcw4P>L zLTrZhRkr2DW?J81E0o+O&Gya->>;y<%_!?*(u_F^&2pq4wSL-GD0xnr^}P_-J7!A* zTVwWRVB4v|k#>98v|Uvq4{v~(To`oXV>{h9@KxY?0r99KJ9cMpEO?bqLo z%wlv#&o>>X$iPq-_zf0_QS@4@;eYvfYCbOiegV|=( z!5r&*0=wV(5nKAlX+DMc3NHgl7 zo%ON7ucQ4snXzrhTMrFvxb-Ak_U~lrgJjP)WB*=Yc9EG-a)~r$xx$R?xYGJMTaGi= zTi;^KasM{!J8fwjcU#|Y%XOCp(u60>bgGjqG+Sgw`JOR*-i$OaNmIU8%xL4USueGv z{yww*)>c!_%oh{1ogx~*(>An|H1mXFW;xP3Snp~plngTF$$rwTuZbCLqnY&)wwsG}lGbpYbT%X3w${hnGA4GFrayHzqyBnGv#)xY zWv(qsA1v0-OfnfDO<9Hnzv0py#73CWr-xaOv1QxFTAyYsluVHBCOgrLdYK|km}bWL z%(>QA*y3`f^-Np(`AyQzWN$X34rW>3V#_|i!}<-|T(KqAU)oaU+ocI>&CuUSQwQtJ zib($?O}p7FC)-}A(}L2>n>IH?7m+6Hm9yS&Z)rlwoGinyj5MK2PL?qyRgCe+EvrlrpmmL}B8$+F|6uawqdHkl_&8|S+2OVWf_bFz%}y(Ud~J7+z6 zPMWYhC(Cr|n>;B^NE!9FGAFxyl`ZU3>o06ei>oyiDnhF?$Op~*wW7@Nz)F_Goy`9w7$fa^50}V$Ch#94(t1DS>J=wTgom7 zY@sxHJQdhW_It&QG2#L1H*AHH#nRNvTY-IP_LUiB?q4FiUkBNecA_+C&oQHX^Q9@v zLuPEpUDl7-RuNlh{j@E|nU}2>+X^LbOK&Fou301LmDcNQIltRX15W|j?QA8J-K0so zM_{>TB?GHyRwb~SX7$Z9*-mC08@ou;XSOYxzymhsfR>*sW%_1vW>z znf&GkHcz^x*j;9l$s^L_`&eL4n=K0Ld9xP-d(&)jU~ii(3+xlK&&`;Ftd(vj`&IBO zq{d2F3d_3#O5y5Yi{YIOq8z-k(pBenlvftUk?^5f_gWnAM z%`{^yc}$u%^hEG`%6?CqG0uOPF4uu0-5;AtQ!ksF;kSkLHo>o`{k9K&J6i7={C2nB zp22T#>zv?M!hWU9WReQjRcwWl{iP{iH8b{aUF!zHuaW(ln8_qfty|l&ZHKTxVSpK9 z;z+YmX7uIZc~~K_lg-YyA87}hO)@)D>^$kFvQy1=l)lXRa$Dvlj6v)N7I$LvUD5S*UZ>n?m1&#z&&dE%N#4;lW3!F zjE3qC-|R16@(h13y+?S6_Ak$k*2>)LEcbi@@1HqF%iAmFS3_|X^Yzb}2KnV*JM%qh zO!;d~{w;+!SKQG2KhtnFi)v8FFMob&@{fY@&*V$qgg^3U`Kijg=LY3p^AA_Y_A}zO zRou}0f7JH#TLgqtbpQFLdVk(8-+z|(-P?oIrhfU0mA#e!*OkYvq#RU7F~zhO(j!yG z?2*8knyW2y#!Aa)7Ll?XX;>Mvon)y&Mju)~eypReBD0EmiZGTpP-IkTs0d@dO%&-- zO%+qW=F<2bWL8|Zl_DceYcuj?Hb7uTMp{O>qZP@Y{sLor8D)17vWpN@jkk3%~u$ zIA7b}n)l%1PiQZV-*IMTr8`-t_kH5WeV_Q9;$`f;vDR1F;&-()f%n>GYlWOh`K%(E zdVF4y{rjpSjD5>tt&8G2imBf+>3)hdKG-&jZ(4t7OWHT`F!K0V@i4_Tihtkp`$Ki4 z=3SH>)r+v5HF9T3_U)9jTNJrM1IoBdn+*ZHRVK zTM<@Xkz+EUiz1A5bX6quQG~IM6BG&k6;r=crT0}l&5YyYKt;l2Mf{kHahxaIrwF6> z-mget&%*Xsd_j@$qauv9^^+o@xB!gUNFTYfO=S6>$g%nW*>+}>c^4Kar1!M5t=-JH z?;OdzXO!6~W-Y|Vnw@KwE5@552v?f1zN^e`He+9KEGKZ^Ig-(2fmz!37-_a)rzxcG zzounYGOH;|5@KU%wx@|%d+A#CJJ?Jp^SfTyUS^Csz3s=n)_*+ekeV=AZE#Z^KeDa+ z_ugNTw)T!cxBK<))a;{DWP8D_^$wUzxi)kQuK6#NKYhdOZ*5Wf{?I;pE~~${Y4#zf zFoDhNVQd;`RqS;}OnMigh9Zn{irzzDJcQ*aa?B$%RD|U>|EZnnYk2>DVE#c}caqD7 z*7;T%v}bsg`Q=|LGY(C*w(U+c&NS|_{>XMmv7OWa$!lj>%0YXas}J_cJ!bIl zm4@)78ToyhhixzRe_BrYX6n?5bexggV9k4(VED}rEbZ9?Sg0^q7RfGqO5$+Y^tm_A zFP;(OX!ET7D8@_Dj2Ju%pL?S&nI}F}DoWFz2xaV7TRQzck@UQV?W|_MI`$(? zU1|1j`g+9fU)M-cS$8AabhBWHT=@|Y4Y3{|FgcYGiiSL+r(AG&+v>W{k7x`d80IM5<5{ddgd(gjr#dt z5y<<-^uby~AI*7ss}!Xa`)#th8P_8E==wv)VyjzjcJ>7G4rROQuSN!cQ;vDhM z)qVDD^~|UTC}nmZFq-_Gzpua%cAQGi`9!w$^-@{7sAc77zw}Xi=#e@9JyE)wme6(w zXvq*QA0{?fX9iv5l_NDoy1Uo_{a0J-;}^g?>i_<-{W8mXWa=)xDwX|}2U;HE>)+S% z$gx%?$EKO>Zl|)RzaY?9Tfnx`cG)88Vn}BHbW9qnh6d`K6w*ao(nh>nX6rlZT40Y% zZ|tb6d&89SKwZIVs!!TEsj}zu8?$HQo8vp`O%JuzE<5Ti5R{Q$U#B(lR{75Qq#f}- zk8aA3@%rz|j~cD2c*@_}lGs1p)oysRezy0}bK7sk2-a15Y@lkA7Mtp>s!e{iu)FKC zwAS5bBi5asc@EJSJ4mgh%g<|M=J{8Ymc7B%nVH)E8*(H`w>WM+b<5V%rw6(QI1(P= z8u&9us=On>`u?BYYX!94zxSQ!*_Ojdl`R2BgsvO0Z-1-ix~RSeW?Cg` zIxwD&%#1CJ7+hPVmogU8m-}k@AoXnC9NICnmj2oUBc!uO>i%MkI(=PoW?;Ykb@dI~ z=f8DK?x<3*uLi57l3(vkDf&65!pdpjM%2--b7FsUEUv6bNUw`<>^)GC^VjBz_`zB! zPE}-v1zUeTmQoH94=uW7!)2cXsoi%x>1tHO6g{ zUKD%5`kC4gig_;707vFb>f-h@pIkZ^BsEkNoJh;3|Hj)jS+zjlV(PJvKeVdD{>}siW#%|@rpX_|Hbzf)AT># z8b!*oi{iD4gc}u8c2kCAXYVPy)9iuZH{a~hz#cPuIuDqVvkY)|!1E*bipu)jsN=AS+Qw-+2Vv+AO^ex2xC=W_%BWgzaj^ zRlk(&W0qd8!>^24rQlcDtXg2z&A7gYByByj#(_04YY|vWvqQ}|(j8`&evd?ZX>WG4 z{Wz=ZCVir8cQgEYNYmE13qXIFv%@|Tmr0*shF@Q4()KgkO1g_Qp?~oE_xjEM>h&9a zXQ-*Ln?&XfyR?lQGk7U!LgnCB#jI-Zt7*ntYt!}d_FBf;^qoEMu3mnjE#qm&JWME= z>a^3njH@6srMZ&NyL(s{jQ8$v_OZYWewFn?Tk^Op4--nB6{CF5c^PSW?+&)0R*EI< z^Ldz1QkYB?ir6pXYrRiMyGQD&57uyj4y)6MATXGm9& z9dE|^I!Y5RF+*P}&Gt?+V|L(Ryq6$=!`nxV%@Q|8mmD9bt0IkJ-iyF{8iW}C?*H|T>rZZac} z3D)y$8H-QP!-SH1#mM)5FC*W_qzRj;!dMso7L?{(Xj?PN-%8gI`_7E{%@5LC0sPU7GJh|vzhqrtuS?U9bGFRZDcf-jP6}nr z&}F5mm-1$O7tv6fYyM3GJ6O7y*x_bu$8pk>`6M&)*w=cnE$yH}9wwBG6eEoGGU{rA zH0zsW#0Kn!RF1Sw51kB)iIt zvV1I^E4$i^w)TTG*CyAQQI^ehBHU57kSzbxm$#9oE{d9wc6;ePS#DNby0~;B*L7IB$8`z1`?7#kI?`&zd=LR#j z<0k3qvNs2IhjbmWd1jPlhBVGjbc~`os?DD`q zmOe;qwHawYk*1zM4SsuR04pW7k1S;)-?y}!P{NF~C8eqRiovgjG;O1%8R-`~Z6hncQ zS(XOBRnjc`H28gH_GR$OvEQNgqd&Gc>tIG6oup}3eat9x zM`^aFpBZI7LYgqh3_aLvm>KDIFMn6bY3(u5^}Ej9bxjODxot+ni0Gtz!1P1sR8h5re~r12|m z2H%sNrqDL{wX@$*!LNh;&Io?v?Ki=Ux|(i3&JkEYbzYi^QmAG|+rC&0i1DwwSySne z_Uq*15otU77;u{zX-C-a6SEw#Z>%|{kuTQ;ezGp;v6E{%9P6+g=kQ~m!Euf5u#;J7 z>B81Iwxroo8k=jzJfoC#XG2KTw+f)Lb^bhl6cku5yh8 z>zFMItEqU41jq37*%6lCCRRA#`_F1;_PJd13F-ZR-Q<&&Bp>(8BCfV@M-?Hz``>DB z;PWR(YdzG;hUWi&$~(Q2H~;*ZYvdoe|Be}07sUUS-NZ|2p|+uBB=HGcs>z z{(a>;)oVr{smSi&sEyrUk)w5Fv{dT(NyTHljNZ+*&rv+ijGofTj254+ud6h@w|iiH zq*?C?W@xUoo})N6u(PDeW1<=PUZ6Ny@j^55y-4w7#f!~YAKQ6{;qi0oa8 zjBt0GQTBTjYb)MscBt%qiu9!W&Dib-6zOI2%}UD7%fr~#hZSj2k0??v97P{ejEn)9 z^0NFfTlVeTJdAzxlp>?}A}@nIugH2|Fxx?Pp(5ce#dLqHkY<0Z4D4fR>TIqJ3_jdbQ9SF&3Z~V zmu?|@klE4FT%~O)%N1JvW!hIOiRRL+&8X9+)@^Ka#TbY5_w#Q|?j+qvfYI?_FQZP6 zkfxs726l`z^?a-u^_*T2=1Q*qGPA;WZPP2b_Qb{oWx~nAr`A03)cm82xoI0FJKV3Cw8#zHR~_Sy-@tmorXh2`bz&+ z-~6Myie|WnZi@Rn@_!~Q-mTP4cQW--iPJkqxW8?1=GZnW!`8p)faCTMZD0E4gY5r* ze%wlP%KxtC?47k8HHLAA;QBjk8Q;@8hPY3tvdYUE2WReaIzVcmNPj(_sUVW&WhaEfz7@rfVt>Gehm8xj=gFAG77F{^9*0JD=ZFbD{p)`u>@*gS!dSxlj?+ z!+)N`0a^=(0?uDH-CghT-p%#8b7oAVEiv}hQ~dky(WWi&mXqwgwv|m%JkRVm%D!7W^>}Kb*l3E>z?4qdtNYDxiL@4d#uVn zlQ2}{6XQp=bX;dSb0fy3-#gB4_>nX{&i7Kw&$j+bDho4^O>wToEN6($Lu+Ur*Hia2 zj?mFLoo&Psqonfu=e)0iD;AsTD8bu`r~~#$wtg#U?bODft>53<*T3wCzn;^j{f#kz z>rFRq!n`-Uo&EkCIBkK9SUr7i-9vT7Ia3VWwH5#WBYlDVxfARn#fufEC|;s?sUp9D zK24T8z_@$sa>XkYXDD8&c$MPSiq|M!tH|A9+!@9%x^3uhwf|B1{)x-q_Vz86eOGar z;&R3J6jvy|ueee%t%HxGS1Eq1xLWZO#ZMJk{<-WL#V-`UH2X8#+)ZsYNAa&YKE&rX z$Z1Q(^yqk)#^nLJ_P-%d1^r&H%)e*+*84TmxzzeMhVWEo+FLip5j+1fZP*#>@AX!$ zT;wWF`mc;Gv=Pqy)^9_0tSzn*&2)+W-WvRK=X}}wqW=1p&R#04xM`kHiqBT8Zx`7; z@$VBxLw-Ku^KD7mFE&Lh{N)ip@BA|F^VR8m>)+?6xmRJ+ok>#f`8~N$U*jruKYa_x zT<_oKr{mSz|KvNZzyI9)-{+^ZPkzUzy=mWN6=&)j?M-zqv*9z8-#@;lGqUVk8PYRs zzOVStuSsQVA@7-fcCPX7H-NwQO--fL>t<&FkMI!qi7tXr4ccu46j2|0v^q^Jn78c&klI@|~U&56bMypLR z56g~Ld0TgSE|R^Tk-fghx5b<4icmNLVyv?ABP zIYQw_;QNJwiu)?2tgkfRxb!#U+vn31`Q~7{8TWZzp-7min5Mm6nzXkDHqY#?!0tCo z??}|Y$rENz%BJgk#_YMkmYBV5#&z2F6bTL!5k@^OwO(yY9ery3MPO^K zzq6G|eo$oF)+w?+>b!sib)4QUD4BVF96#4>TR#gg)?`7?r5F9OD{)! zAF+7S0E^4)D^GujaEGp0XRF=IcZ?;5XdCX{*Sp8ieh znbAMe_loxne!Mpvzf%L7Yc|h}_VkeTBevzl9yK>7_hV~*m4NlJ&(~P5wWY3pkfyzEp#cRy>gpRW-_neBz}t1X zYn8X$;>Xyyt2BLKH#63=yEMn@J!>ngu!_9c!gM10&&CU$$ zJhSry;~N9=<=cleE#DHr_?94Lv&?3jQCA;Wb447#N{VZx3D;;tVT`}mve63rsKLQ# zLv3h$3he{qIa&hGwcHp^6!Oi>v>H{mkftd^13(YDQhPlBO-SHluuPq{)WoZpnl4 zwKO{<_#G-;Sj!GG;~1Gfv%1!dvQ$?FtPfV(tiBn`tLcM$8<>@lu58`Vma&QF z6RXOeVn&&HRuMMNj65!oE-iau@Vm(D;^23^bVd24&ls}48_aGDe)FZvYuSTl_&sE{ zz>Io+S(@;c8D;6FfsT6zyUS7sr0rqW(+t0%X6f^F`0;!lX-5RV3DUL1&N9PqqS@JI zj0ZPK6V?WHaFJ|1x0R(Vl=%i}!rUU+b8XHQInU$#u+PtTM--FC@t%_&_8)&+v;HiR zd-P7!H%{5}1=>J5^Zn0r$(|Qv&q?#2`L2Io7iSpp?z?U(5xsfC0%Jfr*CYjVN&@|j z`ey7&*T(!3)bcR#p4wTCo95gD~?tq+@lDi-`#Khpe=LidleffKBUOEj53)yH+8U`VpCz(w)V?4OXY>pZK&NWN7gMC2x3GXYi zKDKS8;*N?RD5l#c`3IqjlIO^0KUvnqxpp}T_C!-NdMnSfaQ{jA>p|I+IEWc`VMB~+gY)^Viz;~*xSVw``B($X7XR3Ltod0oM*K5z4^ zrObQ>&%Qn148KLz%WPTSa_K6v@0pRdh$@A3Pqf8vlJyg|Ldms!C_E{)vF#?i20rPl zj8(LKa^KxnCV4z){wFL{jJYyzC@YrE3)myPlY?{LA+oG9SCKgff%kF12&2r#m^BkS z#q4x5<{W2A)56X&qbHqVzYENSk_)BxmA%M}ZM#)EM>c&XnO1kP7-6CP7(1RcOXoBt z#CZP(;dA@3Z9KcIotC8U+<@(^Lc-E#jrWoM!fDgzg@uwj^4ml909opQmfBjHWe->(!&`>h%E#5Dof zPiFOHcT#56WcQRMUsx%L+OlQL=z)!-IgT;%>Mt{o=V`)X(&^KJv?-nlB&6?bW8bBL z-|+jRI;7vQEt@HpQS|CEeWJAfPmg0989FPrR6Jf0KlWE!MZ!6XY1&EB8c2SA#~}QA zMcUX+iu_NTxj>O{uOjR~MMf>cQ;IN-w@)h)-d2Rs-rrFqyr&2&r^vo1e5VK_e4jO$ zeE}<}xUU5JCq3%HdD@bFkv?I`==P%`A^j~x`esL*6?g(0*-Y_dGp?N=Y13RQq1{Y2 zYau<3g$h@g;dhJuZZ%_{UuD1ach1Q7L9<8g$GV>|d)*Ab_oQh*>2DIicw(FL#UJd) zwsEb5c3WIlIHPxwX20>f0Wiw91fkHxjO}PDP2hJsQojLar<)z6-{=kF7X)Cn7bX=rO zA8sb|b71yI-Te&y75`t<0Q;6PZZ!u(1>QviV_aD!tx0C`z1c3(Z8W8Y@s1h%IPRV( zO&DWVM|zz7&NQRlOtjyHW{jzC+i$fQ$Cb~_zB1!Dd7TcRD^r7&TEPk+W&9>GgF=g9Ivu!(>as1vZ)wV)O3u%VjR%Xg7xmz0ld(0@y zy=M2Bacr7z{kko6IzyUy$s1;@uaOQyWn~-7rrXxUtf`q6Cqtwu%P=$2o*|tpJKl`4 zoM|>8_)RsN7W}50U1p}F$qZ@oxXO$??w776`+ymF%r|?`OelF+nzWAw_PW`dW~}dX zY1X&KjP-qC_NAFnvb`o;tZzqI>V>o=q?r$uG$U;(v(mw@rZnxVR`9EBRwwu!Vs>co zJIw6x;MZN6e0v1Ho@Tv*-zc+_gWqVgF~M(=*}1`Qve|iNl>cBgB-&|vS?Yi=MVflK z)Qs_Zs`ZTEca{CF3G8;Wxq&@z_M#bQ%Wq557nhpRf0tW-71-C-TdPs0`>2R?Y58w! z#y%=)w!N8#nIuP=K2g#vM|x-L(!p=iQ&56SD+AKFp}KS@nY#cbc;*HD^v&?xvdHfs|6j*_PCj}Csvm>nDZPLihX2L->uWb(l?Nn^AxFOH(fo z1i$%a4+g)N%w7(Dub90W{8mfX(E2_JexI6s7W@jTn&7KT???^Mx zUK;$~HCq<^)=G0O@m28q+U%R)S4102y=)_!?%!?AikfBiuQcr-C-~)>l?Z;dq^rrV zcJQlXRyX(^DP2c?ZOs@r+L^UCBj3K#T+8Yg{7y9MAN)?2X1qEh_>DI^Gx$xDZYaO$ z!S6D&%Y)zT(g(_KPVk#+c1Q4gTDp$>7MZaf&zL=H#&*0X&33E^e(#&D41QlrGp>CT z{Ju5&F8CGE!HfO7jqK0+&8(Y#^N&)_#)nmQN}{6?CMGCN$$Pmv}(Zl>m%jFHZfeZq`&#@50(5ePaA=eooLqIjO{qd`ZQb0GDVvHdx;rkxzucG@Vj1`JZ1;K8_aGDeh--~ z2!0QnJrevDn=J``Z<)Ov{63dvd|ng$zA*bT`0b<<7|xT5$)@djXS3pF?2p}~b)hsV zZAKl`l%@`9nNbI|&FTcd7G^DjUn{fLW?YLt#QJbs^5`a=Y2#+((Zj4~@Eb18adkxS z8)-Hw_)U~%d(RGj=a@}0W1pXAJ;RndxJH^V-%Qn*ERbd%vC51xuahn<`;!@E=41v| zKsIg9J4!R=>|};tF|(b6-@ek6dB5PdzggAbcc3(7Y99O!GHYSRwzanIWJ{VZ(rm}s zW^Bi0(k#2&jPhM!Hp7hdU2Q$rmb8ycQ|2ekNW0MNNi$VXvPhbI-wSM&bXBp{fvvIM zwtHvmkF+~T6DkI_ui24ilx2uCeQ>B5Wf^8RJosHGT}R6<3Vs)xO$mOtOP7}4oZvUt z?2h2~nAzjO?+LSo!S8ix`sy3O?@hDC!EZ}dXf^p2mQDNWR%Tn9X>n3anqx(AGwPs> zG-WPpMjezhDi44!S4XG`oV9QG;Mcy@Ec(^GWboBrvIKB{3e^77yPb~X3V}e z_{}uCF8D2wCf|pH-y>#^2ES#}x$;{c{N6KLVMd!+W&Me*Q1XK`_4kt*eV|EB_8hjG zY}$Wcldh*_ubWY)Z#^2ES#}jkS*D!S6k@6=rPjSJITPVCnVyx0f{isJ9tq>0@?+8D$>ZMxnt8P{!__dH` zds_y-R%We(UnjH9!S8spE@t|wCFw3rlkO4xdYbhzV>?Dj)7C}?zfoo<2fwq;&Ix{# z%+59ASayLl;T<#b_)I!i_H#4pbdA{;WXlI7s(Pm?V-)Ux-2EXZMi_DnszGk+UN>$u6>#h4aRpr8O)jyPC0Y_ORa5c55*!m?**yZ^p}GkZ^Jr;T{B`nTSy%)1J+zjFV}Cxbb5Y^rxE{I{R;NZ-%%-+9hs zxSnC*T{3AO;Rx~1eg2vA!GH2|F*8)Yf{Iruatz}*KUa~F=PpIq4vP0GHdcH{5yqTj zf#RWxPbk7TK3=X!cuEn*eC16==3-ZI1Q6Gi4wpPG@!XJ((9$z<+9rp#Xl z_JcHRU0|ClGuRfgBif1;1rx+)Jy!O!&a;!@xc_bJjHEi>w`zO*hQB@N7|mu6-Mnh7N>q*>n~f%P)$W44=?r@vg)H~5`ozd>f? zF-DrUdx{xl;oe>t_w`a{W;hefCI)t{*<>@)PBJ^+Y#Xuu(j{asFr(dHC`}$0nMo$o zq}jI10-I?zD=_Xe#xH$VI!F3WFTXeV-DkfC%YyE;Pb^4MtVU-#B6KT?>&rid?HT&Lv)E`bdElkp9rCA@(O2dlCrtPn& z+4h0){B#5Pbv9$$x?0C)pnHqyFFC=>IFIOSeUhzEGE`cB3C~QY`KHfJj|qO`?01?O z?f7)-iMDLpSZTu9X0)qw&2BSe`CMu6JTqP5OYXFOz!tv;rSF$%XS3pF ztZ#Q|Y)5|8F{oaYi&l_L!=2E%yOiUx9(xf@?O$x zZyz(#c9JFx3x1>QH#)EhW)saQ-?h@EWoMdEzU$0pnQbd}t~6n`*>=*Cq%+qf%vj$8 z(zK=dW~}c)vxkD;8`34U?9Je}*ldXzbBmGEgmq@<&9qYLU~}2D9qeSbb6~rg?QX`o zTmfm?^FC&jxw15K@G539$-ZX$nc>%1nrkLa%w&?LX3fm-J5ri<)z(ZV;WyV|>2I!6 zN8`PGqAh8!kgg{?!%QZ*((EcT{O&MIe^+W3~16ym&4oLf80cpmlLS}MFwlLe;j68}- zb56ROnPlcY543|^vm(;vr8$OIFe7aV>q@q?=e?u}wam~5NVC2M!S5jZ9UT04mjr%C zn~_I%Y4&LkGxF#yO*qMnIbmJ1lg(Iusx<36JusdMg-tfg%%7#Jh+Sz$zO$tHzTc6+(%xgnvEp9qhiqBj3(~CbMKjj-ytMw3m&_!S#nP;g_hF>{?E|xq%yP7RmG!5# zw6*m87wJ1M$m4S@=bCn8--}U}qFZM3pnSVZ!*(;HU6nJd7#P13k6-$34Ezo-%X6bXRuqkGj*sq@0rDjvj*p6vt)6FRJ4C$(}GXuL`y1rQYTrB0gON_GIXFs;% z5wlm#@S879cs($F|DCi;0$XGDO<>=deIMA5X6bJLv;Q|MoLyh~+rQ+yg<1N0zie9( zv+ZQrm-v-2<9B>v`0*Sr<>T4fl<~X0Fn+T)P0Mff!uT!Tl<^z9uqI}bncv=}-M0#U zJi|-7J}UTil*X@9@Ea-3TyAvm8)v`Mg5R0aW#l)(j4|R^Y4SMBOfoq~nmo=8>>{%% zX4Jt{Y0^$JD=K}xbPd_rX0)Lj%x*LjN^X@VkJ|&g+w9)J7MML^M!t_)FA9Fo+V45D zlJa}r`laCaiv3;-Y=zlMGxAt1T|)L#vz?@uOA|g1eru&UrtG}c`u%$fol;>}GxXll zY;R6ryuSvPzMlragUt@LAMLN5G@(Oa$C;gIMwthi4GMn4q?>Emh~Rg!G}l!|2gdtw zV7v>5c1k!yn(~bge!K&RHk7^thkDsVj4;)H=trcPzdUNjb}W_7m3=p`0y@yLzJju8 z|JYrcy5GZ$ZR7XuVS5L^=~@q=rWyJGY0BKdjPliyrkyr4qbvtY(`VA(yN4Za#&6fB zWoc*D-i&$OQD#S*(Z-K4JJw7n^WGlH!n=CXI_)D3>l@f0vms`ji;tFO-aFQeJjR)w zZbn&7wjOWGcJh87@|$c+`#j(Jioj-A^PV64>AyEimzBNMjC^l1n`6e@=YDDG_5rh8 z>3P-<+GhHybOkMY%#1QWY5lA%Wq#iJWn1>gLTSpLGRfq1G3xKl;P;L+^RT66_${~J zioiZH``C;;)=1N?zBHrE-<>cME=d*l#bhOnbL375vKBubdhAmbb1N{A${-wi)}kl{9tQ+Km0%#*BA6u^sH! z!>oJQl6ItYdD&5Bq&?Yev>9o~T2HnmE$@h;jofHP+MCR7HWNy2m!_`fnz4`Wl4ibf zpBeMr>e7VyX5{;ZH0Q+cn2~mw{Z^QGtLQkuEfLuT}q$IKR+(Fd1E6IPm$_B-hcvOfg2&WzU+rFHd)SbO;uG$UxlSw-3BeQ?a@atmM)r@UxBu(gUhVCOx9rQJ$J@=QcEjz$WCb>`_ zWqCrHG3Qw`@_k;KP*D?tw7*r6#;>{=E)A^@ z41Nuy2}hcd<~*|-%vk=kG~4@(8D&`_%`xch;P;{ZRtNT(*%~v-@`d&HfvuA+tz|!% zQ3re(1}hMrRWBq>oo-=<-D&4iL7(v+F!?5P*>Eoxmnu-&99YT52)tZxsqJ%eA4 zbY(5e4SpreN(R4rW(Nen`eqG+-;vVwwZ68&ubo-@;CGxfZKG50>uh#>@arXAO@6(D zUmvp*g5Owa>Tg`|JJsy8;CHDshI>@cZ=Dr z!S5Yu%C|K5y=%5C_^mbjD)@bE_D%3BtqX$tYJFv7({ZS*SvfPt=YymfpIZjMR?>{m zZGvB0`?U{#N7?TfGuqnm(#)m01i!9k-ORK&=_yS+?QKR``bcveKEaGO+1IR}nKm(5 zslGz!Z$`djrRg){%t(8x*=c4PrjwJT3B137dLc}drYz@}(a(8D1L0~j@_1RA>q)Pe gk;kiMubDB=;r$QP>8Ba?tD05H3zJ^%m! literal 0 HcmV?d00001 diff --git a/bsp/simulator/vs2005.vcproj b/bsp/simulator/vs2005.vcproj new file mode 100644 index 0000000000..f716ebc87d --- /dev/null +++ b/bsp/simulator/vs2005.vcproj @@ -0,0 +1,739 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +