From 2689ad40118cfc371352e53a60a707d43916d6d6 Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Fri, 15 Dec 2023 17:13:53 +0800 Subject: [PATCH] example: add maple_controller This broke maple_wink. I have not yet found why this happened. --- common.mk | 2 +- example/example.mk | 9 ++++ example/maple_controller.cpp | 37 +++++++++++++++ example/maple_wink.cpp | 18 +++++-- maple/maple.cpp | 88 +++++++++++++++++++++++++++-------- maple/maple.hpp | 38 +++++++++++++-- maple/maple_bus_bits.hpp | 14 ++++++ maple/maple_bus_commands.hpp | 75 ++++++++++++++--------------- regs/gen/core_bits.py | 12 +++++ regs/maple_bus_bits.csv | 2 + regs/maple_bus_bits.ods | Bin 14515 -> 15709 bytes 11 files changed, 227 insertions(+), 68 deletions(-) create mode 100644 example/maple_controller.cpp diff --git a/common.mk b/common.mk index 9bf6328..1380afc 100644 --- a/common.mk +++ b/common.mk @@ -2,7 +2,7 @@ MAKEFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) DIR := $(dir $(MAKEFILE_PATH)) LIB ?= . -OPT ?= -O0 +OPT ?= -Os DEBUG ?= -g -gdwarf-4 GENERATED ?= diff --git a/example/example.mk b/example/example.mk index d5eaa91..e7f774b 100644 --- a/example/example.mk +++ b/example/example.mk @@ -54,6 +54,15 @@ CUBE_OBJ = \ example/cube.elf: LDSCRIPT = $(LIB)/alt.lds example/cube.elf: $(START_OBJ) $(CUBE_OBJ) +MAPLE_CONTROLLER_OBJ = \ + example/maple_controller.o \ + vga.o \ + serial.o \ + maple/maple.o + +example/maple_controller.elf: LDSCRIPT = $(LIB)/alt.lds +example/maple_controller.elf: $(START_OBJ) $(MAPLE_CONTROLLER_OBJ) + MAPLE_WINK_OBJ = \ example/maple_wink.o \ vga.o \ diff --git a/example/maple_controller.cpp b/example/maple_controller.cpp new file mode 100644 index 0000000..356f2f6 --- /dev/null +++ b/example/maple_controller.cpp @@ -0,0 +1,37 @@ +#include "align.hpp" + +#include "maple/maple.hpp" +#include "maple/maple_bus_commands.hpp" +#include "serial.hpp" + +constexpr uint32_t command_data_size = (sizeof (device_request::data_fields)); +constexpr uint32_t response_data_size = (sizeof (device_status::data_fields)); + +constexpr uint32_t host_command_size = ((sizeof (struct maple::host_command))); +constexpr uint32_t command_response_size = ((sizeof (struct maple::command_response)) + 31) & ~31; + +uint32_t _command_buf[host_command_size * 4 + 32] = {0}; +uint32_t _receive_buf[command_response_size * 4 + 32] = {0}; + +void main() +{ + uint32_t * command_buf = align_32byte(_command_buf); + uint32_t * receive_buf = align_32byte(_receive_buf); + + maple::init_host_command_all_ports(command_buf, receive_buf, + device_request::command_code, command_data_size, response_data_size); + + maple::dma_start(command_buf); + + uint8_t * buf = reinterpret_cast(receive_buf); + for (uint8_t port = 0; port < 4; port++) { + serial::string("port "); + serial::integer(port); + for (uint32_t i = 0; i < command_response_size; i++) { + serial::integer(buf[port * command_response_size + i]); + } + serial::character('\n'); + } + + while (1); +} diff --git a/example/maple_wink.cpp b/example/maple_wink.cpp index 6e105e0..5d552d2 100644 --- a/example/maple_wink.cpp +++ b/example/maple_wink.cpp @@ -1,6 +1,7 @@ #include #include "maple/maple.hpp" +#include "maple/maple_bus_bits.hpp" #include "vga.hpp" #include "align.hpp" #include "serial.hpp" @@ -30,18 +31,25 @@ void main() constexpr int height = 32; constexpr int pixels_per_byte = 8; - uint32_t wink_buf[width * height / pixels_per_byte]; + uint32_t __attribute__((aligned(4))) wink_buf[(width * height / pixels_per_byte + 32) / 4]; make_wink(wink_buf); + if ((((uint32_t)wink_buf) & 3) != 0) serial::string("misaligned\n"); - uint32_t _command_buf[128 / 4]; - uint32_t _receive_buf[128 / 4]; + uint32_t _command_buf[(1024 + 32) / 4]; + uint32_t _receive_buf[(1024 + 32) / 4]; uint32_t * command_buf = align_32byte(_command_buf); uint32_t * receive_buf = align_32byte(_receive_buf); + if ((((uint32_t)command_buf) & 31) != 0) serial::string("misaligned\n"); + if ((((uint32_t)receive_buf) & 31) != 0) serial::string("misaligned\n"); - maple::init_block_write(command_buf, receive_buf, wink_buf); + maple::init_block_write(command_buf, receive_buf, + host_instruction::port_select::a, + ap::de::expansion_device | ap::port_select::a | ap::lm_bus::_0, + wink_buf, + 192); maple::dma_start(command_buf); - for (int i = 0; i < 32; i++) { + for (int i = 0; i < 1; i++) { serial::integer(receive_buf[i]); } diff --git a/maple/maple.cpp b/maple/maple.cpp index 9a7e5c3..e0aee50 100644 --- a/maple/maple.cpp +++ b/maple/maple.cpp @@ -13,32 +13,73 @@ namespace maple { -void init_host_command(uint32_t * buf, uint32_t * receive_buf, uint8_t command_code, uint8_t data_size) +void init_host_command(uint32_t * command_buf, uint32_t * receive_buf, + uint32_t destination_port, + uint8_t destination_ap, uint8_t command_code, uint8_t data_size, + bool end_flag) { // this function does not care about the template instantiation of // host_command--data_fields is not manipulated here. - auto host_command = reinterpret_cast *>(buf); + auto host_command = reinterpret_cast *>(command_buf); - host_command->host_instruction = host_instruction::end_flag - | host_instruction::port_select::a + host_command->host_instruction = (end_flag ? host_instruction::end_flag : 0) + | (destination_port & host_instruction::port_select::bit_mask) // host_instruction::port_select::a | host_instruction::transfer_length((data_size / 4)); - host_command->receive_data_storage_address = reinterpret_cast(receive_buf) & 0x1fff'ffff; + host_command->receive_data_storage_address = receive_data_storage_address::address(reinterpret_cast(receive_buf)); host_command->bus_data.command_code = command_code; - host_command->bus_data.destination_ap = ap::de::expansion_device | ap::port_select::a | ap::lm_bus::_0; - host_command->bus_data.source_ap = ap::port_select::a; + host_command->bus_data.destination_ap = destination_ap; //ap::de::expansion_device | ap::port_select::a | ap::lm_bus::_0 + + host_command->bus_data.source_ap = destination_ap & ap::port_select::bit_mask; host_command->bus_data.data_size = data_size / 4; } -void init_device_request(uint32_t * buf, uint32_t * receive_buf) +void init_host_command_all_ports(uint32_t * buf, uint32_t * receive_buf, + uint8_t command_code, uint32_t command_data_size, uint32_t response_data_size) { - init_host_command(buf, receive_buf, device_request::command_code, (sizeof (struct device_request::data_fields))); + const uint32_t command_size = (((sizeof (struct host_command)) + command_data_size)); + const uint32_t response_size = (((sizeof (struct command_response)) + response_data_size) + 31) & ~31; + + init_host_command(&buf[(command_size / 4) * 0], &receive_buf[(response_size / 4) * 0], + host_instruction::port_select::a, // destination_port + ap::de::device | ap::port_select::a, command_code, command_data_size, + false); // end_flag + + init_host_command(&buf[(command_size / 4) * 1], &receive_buf[(response_size / 4) * 1], + host_instruction::port_select::b, // destination_port + ap::de::device | ap::port_select::b, command_code, command_data_size, + false); // end_flag + + init_host_command(&buf[(command_size / 4) * 2], &receive_buf[(response_size / 4) * 2], + host_instruction::port_select::c, // destination_port + ap::de::device | ap::port_select::c, command_code, command_data_size, + false); // end_flag + + init_host_command(&buf[(command_size / 4) * 3], &receive_buf[(response_size / 4) * 3], + host_instruction::port_select::d, // destination_port + ap::de::device | ap::port_select::d, command_code, command_data_size, + true); // end_flag } -void init_get_condition(uint32_t * buf, uint32_t * receive_buf) +void init_device_request(uint32_t * buf, uint32_t * receive_buf, + uint32_t destination_port, + uint8_t destination_ap) { - init_host_command(buf, receive_buf, get_condition::command_code, (sizeof (struct get_condition::data_fields))); + init_host_command(buf, receive_buf, + destination_port, + destination_ap, device_request::command_code, (sizeof (struct device_request::data_fields)), + true); +} + +void init_get_condition(uint32_t * buf, uint32_t * receive_buf, + uint32_t destination_port, + uint8_t destination_ap) +{ + init_host_command(buf, receive_buf, + destination_port, + destination_ap, get_condition::command_code, (sizeof (struct get_condition::data_fields)), + true); auto host_command = reinterpret_cast *>(buf); @@ -47,11 +88,18 @@ void init_get_condition(uint32_t * buf, uint32_t * receive_buf) fields.function_type = std::byteswap(function_type::controller); } -void init_block_write(uint32_t * buf, uint32_t * receive_buf, uint32_t * data) +void init_block_write(uint32_t * command_buf, uint32_t * receive_buf, + uint32_t destination_port, + uint8_t destination_ap, + uint32_t * data, + uint32_t data_size) { - init_host_command(buf, receive_buf, block_write::command_code, (sizeof (struct block_write::data_fields))); + init_host_command(command_buf, receive_buf, + destination_port, + destination_ap, block_write::command_code, (sizeof (struct block_write::data_fields)) + data_size, + true); - auto host_command = reinterpret_cast> *>(buf); + auto host_command = reinterpret_cast> *>(command_buf); auto& fields = host_command->bus_data.data_fields; // BW LCD function type @@ -66,16 +114,16 @@ void init_block_write(uint32_t * buf, uint32_t * receive_buf, uint32_t * data) // plane 0 (2 total levels of gradation) fields.block_no = std::byteswap(0x0000); - for (uint32_t i = 0; i < (192 / 4); i++) { + for (uint32_t i = 0; i < (data_size / 4); i++) { fields.written_data[i] = data[i]; } } void dma_start(uint32_t * command_buf) { - sh7091.DMAC.DMAOR = DMAOR__DDT /* on-demand data transfer mode */ - | DMAOR__PR__CH2_CH0_CH1_CH3 /* priority mode; CH2 > CH0 > CH1 > CH3 */ - | DMAOR__DME; /* DMAC master enable */ + sh7091.DMAC.DMAOR = DMAOR__DDT // on-demand data transfer mode + | DMAOR__PR__CH2_CH0_CH1_CH3 // priority mode; CH2 > CH0 > CH1 > CH3 + | DMAOR__DME; // DMAC master enable // clear maple-DMA end status system.ISTNRM = ISTNRM__END_OF_DMA_MAPLE_DMA; @@ -90,8 +138,8 @@ void dma_start(uint32_t * command_buf) maple_if.MSYS = msys::time_out_counter(one_msec) | msys::sending_rate::_2M; - /* top address: the first/lowest address - bottom address: the last/highest address */ + // top address: the first/lowest address + // bottom address: the last/highest address maple_if.MDAPRO = mdapro::security_code | mdapro::top_address(0x00) | mdapro::bottom_address(0x7f); diff --git a/maple/maple.hpp b/maple/maple.hpp index 9450fd3..6900633 100644 --- a/maple/maple.hpp +++ b/maple/maple.hpp @@ -17,11 +17,39 @@ struct host_command { } bus_data; }; -void init_host_command(uint32_t * command_buf, uint32_t * receive_buf); -void init_device_request(uint32_t * command_buf, uint32_t * receive_buf); -void init_get_condition(uint32_t * command_buf, uint32_t * receive_buf); -void init_block_write(uint32_t * command_buf, uint32_t * receive_buf, uint32_t * data); +template +struct command_response { + struct bus_data { + uint8_t command_code; + uint8_t destination_ap; + uint8_t source_ap; + uint8_t data_size; + T data_fields; + } bus_data; +}; + +void init_host_command(uint32_t * buf, uint32_t * receive_buf, + uint32_t destination_port, + uint8_t destination_ap, uint8_t command_code, uint8_t data_size, + bool end_flag); + +void init_host_command_all_ports(uint32_t * buf, uint32_t * receive_buf, + uint8_t command_code, uint32_t command_data_size, uint32_t response_data_size); + +void init_device_request(uint32_t * buf, uint32_t * receive_buf, + uint32_t destination_port, + uint8_t destination_ap); + +void init_get_condition(uint32_t * buf, uint32_t * receive_buf, + uint32_t destination_port, + uint8_t destination_ap); + +void init_block_write(uint32_t * buf, uint32_t * receive_buf, + uint32_t destination_port, + uint8_t destination_ap, + uint32_t * data, + uint32_t data_size); + void dma_start(uint32_t * command_buf); } - diff --git a/maple/maple_bus_bits.hpp b/maple/maple_bus_bits.hpp index 85c2980..ce4e37d 100644 --- a/maple/maple_bus_bits.hpp +++ b/maple/maple_bus_bits.hpp @@ -10,6 +10,8 @@ namespace host_instruction { constexpr uint32_t b = 1 << 16; constexpr uint32_t c = 2 << 16; constexpr uint32_t d = 3 << 16; + + constexpr uint32_t bit_mask = 0x3 << 16; } namespace pattern { @@ -18,23 +20,33 @@ namespace host_instruction { constexpr uint32_t reset = 0b011 << 8; constexpr uint32_t return_from_light_gun_mode = 0b100 << 8; constexpr uint32_t nop = 0b111 << 8; + + constexpr uint32_t bit_mask = 0x7 << 8; } constexpr uint32_t transfer_length(uint32_t num) { return (num & 0xff) << 0; } } +namespace receive_data_storage_address { + constexpr uint32_t address(uint32_t num) { return (num & 0x1fffffff) << 0; } +} + namespace ap { namespace port_select { constexpr uint32_t a = 0b00 << 6; constexpr uint32_t b = 0b01 << 6; constexpr uint32_t c = 0b10 << 6; constexpr uint32_t d = 0b11 << 6; + + constexpr uint32_t bit_mask = 0x3 << 6; } namespace de { constexpr uint32_t device = 1 << 5; constexpr uint32_t expansion_device = 0 << 5; constexpr uint32_t port = 0 << 5; + + constexpr uint32_t bit_mask = 0x1 << 5; } namespace lm_bus { @@ -43,6 +55,8 @@ namespace ap { constexpr uint32_t _2 = 0b00100 << 0; constexpr uint32_t _1 = 0b00010 << 0; constexpr uint32_t _0 = 0b00001 << 0; + + constexpr uint32_t bit_mask = 0x1f << 0; } } diff --git a/maple/maple_bus_commands.hpp b/maple/maple_bus_commands.hpp index 560291e..377646b 100644 --- a/maple/maple_bus_commands.hpp +++ b/maple/maple_bus_commands.hpp @@ -2,35 +2,35 @@ namespace device_request { constexpr uint32_t command_code = 0x1; - + struct data_fields { }; } namespace all_status_request { constexpr uint32_t command_code = 0x2; - + struct data_fields { }; } namespace device_reset { constexpr uint32_t command_code = 0x3; - + struct data_fields { }; } namespace device_kill { constexpr uint32_t command_code = 0x4; - + struct data_fields { }; } namespace device_status { constexpr uint32_t command_code = 0x5; - + struct data_fields { uint8_t device_id[16]; uint8_t destination_code; @@ -40,13 +40,13 @@ namespace device_status { uint16_t low_consumption_standby_current; uint16_t maximum_current_consumption; }; - + static_assert((sizeof (struct data_fields)) == 112); } namespace device_all_status { constexpr uint32_t command_code = 0x6; - + template struct data_fields { uint8_t device_id[16]; @@ -58,66 +58,66 @@ namespace device_all_status { uint16_t maximum_current_consumption; T free_device_status; }; - + static_assert((sizeof (struct data_fields)) == 112); } namespace device_reply { constexpr uint32_t command_code = 0x7; - + struct data_fields { }; } namespace data_transfer { constexpr uint32_t command_code = 0x8; - + template struct data_fields { uint32_t function_type; T data; }; - + static_assert((sizeof (struct data_fields)) == 4); } namespace get_condition { constexpr uint32_t command_code = 0x9; - + struct data_fields { uint32_t function_type; }; - + static_assert((sizeof (struct data_fields)) == 4); } namespace get_media_info { constexpr uint32_t command_code = 0xa; - + struct data_fields { uint32_t function_type; uint32_t pt; }; - + static_assert((sizeof (struct data_fields)) == 8); } namespace block_read { constexpr uint32_t command_code = 0xb; - + struct data_fields { uint32_t function_type; uint8_t pt; uint8_t phase; uint16_t block_no; }; - + static_assert((sizeof (struct data_fields)) == 8); } namespace block_write { constexpr uint32_t command_code = 0xc; - + template struct data_fields { uint32_t function_type; @@ -126,107 +126,108 @@ namespace block_write { uint16_t block_no; T written_data; }; - + static_assert((sizeof (struct data_fields)) == 8); + static_assert((offsetof (struct data_fields, written_data)) == 8); + static_assert((offsetof (struct data_fields, written_data)) == 8); } namespace get_last_error { constexpr uint32_t command_code = 0xd; - + struct data_fields { uint32_t function_type; uint8_t pt; uint8_t phase; uint16_t block_no; }; - + static_assert((sizeof (struct data_fields)) == 8); } namespace set_condition { constexpr uint32_t command_code = 0xe; - + template struct data_fields { uint32_t function_type; T write_in_data; }; - + static_assert((sizeof (struct data_fields)) == 4); } namespace ft4_control { constexpr uint32_t command_code = 0xf; - + template struct data_fields { uint32_t function_type; T ft4_data; }; - + static_assert((sizeof (struct data_fields)) == 4); } namespace ar_control { constexpr uint32_t command_code = 0x10; - + template struct data_fields { uint32_t function_type; T data; }; - + static_assert((sizeof (struct data_fields)) == 4); } namespace function_type_unknown { constexpr uint32_t command_code = 0xfe; - + struct data_fields { }; } namespace command_unknown { constexpr uint32_t command_code = 0xfd; - + struct data_fields { }; } namespace transmit_again { constexpr uint32_t command_code = 0xfc; - + struct data_fields { }; } namespace file_error { constexpr uint32_t command_code = 0xfb; - + struct data_fields { uint32_t function_error_code; }; - + static_assert((sizeof (struct data_fields)) == 4); } namespace lcd_error { constexpr uint32_t command_code = 0xfa; - + struct data_fields { uint32_t function_error_code; }; - + static_assert((sizeof (struct data_fields)) == 4); } namespace ar_error { constexpr uint32_t command_code = 0xf9; - + struct data_fields { uint32_t function_error_code; }; - + static_assert((sizeof (struct data_fields)) == 4); } - diff --git a/regs/gen/core_bits.py b/regs/gen/core_bits.py index aca89c1..5c2949b 100644 --- a/regs/gen/core_bits.py +++ b/regs/gen/core_bits.py @@ -175,10 +175,22 @@ def render_defs(bit_def): else: yield from render_read_only(bit_def) +def render_enum_mask(enum_def): + all_bits = set(bit_def["bits"] for bit_def in enum_def.defs) + assert len(all_bits) == 1 + assert all(bit_def["bit_name"] != "bit_mask" for bit_def in enum_def.defs), bit_def + _bits = next(iter(all_bits)) + bits = parse_bit_range(_bits) + mask_value = mask_from_bits(bits) + bit_ix = min(bits) + yield "" + yield f"constexpr uint32_t bit_mask = {hex(mask_value)} << {bit_ix};" + def render_enum(enum_def): yield f"namespace {enum_def.name.lower()} {{" for bit_def in enum_def.defs: yield from render_defs(bit_def) + yield from render_enum_mask(enum_def) yield "}" def render_register(register): diff --git a/regs/maple_bus_bits.csv b/regs/maple_bus_bits.csv index 029a65e..2644cc4 100644 --- a/regs/maple_bus_bits.csv +++ b/regs/maple_bus_bits.csv @@ -14,6 +14,8 @@ ,,,,,, "host_instruction",,"7-0","transfer_length",,"0xff", ,,,,,, +"receive_data_storage_address",,"31-0","address",,"0x1fff_ffff", +,,,,,, "ap","port_select","7-6","a","0b00",, "ap","port_select","7-6","b","0b01",, "ap","port_select","7-6","c","0b10",, diff --git a/regs/maple_bus_bits.ods b/regs/maple_bus_bits.ods index 16322fc287b7737d4d77e8794df4315e82924e74..3c5318cbecaa18542e7355448000ef8e510f69d9 100644 GIT binary patch delta 13717 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 delta 12588 zcmaia1yEc~(=M)y+u{}+g1fVUAi*uTy9IX^0xS-JMS^E>Cj<|!!QC~1;1*m1m%Q(% z|9@}YQ+2ARW_o(&%seeKr&s-IU9r@Z5RnMs;LzaU;2mNUvD6Wt3G@)2_aBrNiYbbL z`JXIiw9s65!hbafiu|u;?!TK8=LG+7C7SX7Mbbt7B6GCRG*RroB%-0A{TZ~@5J3$7 zFL{}WhC!3Qs0K9l$8}%>X+)3HbySElp1`CkJXz3o3wjRZ%>fB zd^{Zydvp3uIDHp6AU}JRHUpP1Bt^x};ACR@Q8Oz);>_qrPHsICEXz^V6cq4YO}1@D zAn!^so$?N^ThDaG(`c$N>YU#?te~mC3`6@N4+i#6um~6<3S0l%>58BBp3ZHgaml@=rnvkc83{R8VkWQVD=j@*RyR(MWIV?zdujV-yh{^* z*cmTwUUU#`uf{QK?+9Y5sy91&@9GmaL1kUgB5J)QrBOx(S0i-D ziE0-&FI#04T#4eoi08kzdjC0$J7=v}Y@N^trtB-VH(^rowmxV?Kd6xUTI^}$+@-ch zGS&h1z=6eQbw%P2VLJAEojE~0iNukQhcgSFlwvn>0Cjlth2Y2P)hJ8k9}8WWynFvn z?|ZpRn9FaREowC-R5a+wD^wUf9Go&D9Ngas`p0JK!u`jC`CPVearUrs_IT;zWIU>y_V5!p!bqCwOhM?=_`9Ryw{`4&?n!$KZB>k;kY^<2 zE!TI5GQ!KpYb5W^BHHjb4+vt!_>-oJa3DuAIO;Dfjm0m*r29n!2YKTz8Mg#1=!2F` z-chM2yVryDjVk0w!u+-ytBWdlg$&(!^RG%azX#6rbeUTE6(I_7rJ_}}j|XTF#A;GZez)a2{V|>iJn=t}~er zS?Mq|bpdX<`4^TQP@RH6xB;Cz8Ox@~(`@Sp!|ki4!s9&S95_RKWEK3DsHg8DVT6OM z!4?hRz0|P0bs)HZD3FqXr1`c#Cx0a1HLvR|E#nQOS%v27BUeA8^&722X>FqUU&q5~;q{GDscTDEoSsc;_-lP^I+flB^hG&#ri9F!6CDFb^Q|F`a1PUmm=iCQ9RA_y8w$&`buC!`pV=sz+vi%$=&5FF3w2Xb<1dr^GO)7Xe z*3`vRp5c^V2Bvg7I&B%8b@&LU2V%necQphgW_qn&iRK}VntdC*c~K>b4C;+N+9MSC7Bbi#0aV7$ zsMUTU(;@e=#P0MxmjpC|m=F9VA*0RUOQx{Wp({6hz;a{b@5K7`&M=`y7fbDf`6ZTb z>CHf&`jlg*T74*6!_97_r9gBe{eBg>&UNaqs&d2Qig94?#CG<6eHGS$W-*zx=qZm{ zbXu3fw-}UP{&2qxnF6rBUjs~ADB*BY;KXL&=HRMYJnT_B>Fc%o6%fI1Rhwrwk>6q4 zHHuV*a35=#NtNKdD`rJK?~)p?<+pcW?ma8<+LrBllN06@XRMU3o8LJ111)q_rR#<5 z<&auv1F@~|tI%|%C`te63x~bIP&v0Y7MBHnOI5L3D)s9`;_&EivD$~t0<4S$8Fxa+ z@b0wPW?Rgg_EDdpFiLjKrdrg0w(CTFD&}tFq1C7s()5d|n<>?#S z8oE8v5N^NER44-uL_d-B9F4W}IhzP8khc4HIQJBseK#Ilvu1z?izMT$HUF|XFWIng z;MX?xYOR%MIecW-bYZZM)#s9`;e>W6nIvD{?y*rGbSw63PSsrH`L zknc#?Kt7K{oc0k9?A0_5Uv1xFR!#1Zc|~EkjEU>>ZX1MZx01u_%%r%=CyYD;K|($g z_aUpciJh;}5Y%q{x*ortYMawauYq_K3-4b!qdZ>>x9|YZinYLta>!KZT;@|>McEItwBJx$#hU=we`ZB`@FlHL(J+--8zto(C3aj-W}o)BiK$ZnZy8J zjAS8BDUa8}VK_m=U=TWdI&160qf1^^#+GU+Q%F{PbDH1Xh}J04luX2!YdI8j6m)lg z4E_^VY%i14M_@n4qM`x+Bd&mUU{Qh(T$TlJpV~WQ)I!V<8I>BK0$2E`ffcKB0?bKX z_iwrI8QcqBg%oTSfPdd4v*;xe?M!;Ae0bHm-sa=|GjZs2&ojP_O`eplFG`Y1wjDL* z3Su$S2NcjY`u6)#C5&_+lHuUnNpltObNFB! zOz}lHVW%K0+$!7Ud?ZC*oQhXqi|H}x+>HuyaOqc<6OT69ov;HdK&CK0pUC6Qc+rF< z9+hYJF&zCnO_R*K-@R^zoW5&A+&QDxusnTRnKSIkO*I+>9|j6j;!*QxMTwcfI4??7 z^w9`6rHbK9#P-8qd&~ixk^A4k_ujtF@54 z0xqM5Q*pjcf1c1)zFf*eD_{@1u0SWG$aM8!N(h6Yzvjhp{RE!j9YGt; z0BgnQ*A@^W)YW^<(5obciYgo8fR{obC{*wXCK^Ejuu6TKMgkR2TCR|YN7A*d8RDd+ zq!6v4bhPq`rfHb0-k7%sqti-{A!tQvLz3Mi3}Se*#;ipyNxXL6L@n@Z;`Y#la9hV% zIKAdS+_NdY>IDZK2m0)^AxGw4uVs?7Gr4uixQDr@JWxw3EL3AWa^p%cpB8-qPLi@x>oCGv!Cjt< ztnue_3dn6(^<5i7V^Yk#J{xab>l;?t%;@y5eR;@=!&`O#=0Fxf^K*C6eO*!<%)SuA zJhH~+2g4_t{7;4`h0Jf|h4DGc8PV%L$PCd)$A-!XfF^fwi84u{nTrCsUux<1H1Y-k zfkZ!DwcPk2(utK)U`B{348^==&6V}dqsI@yJ`{5-L|F$*0jbhXgnBaNx(xQCgDH(z zMI|5KhRV0j{6OPIYe$eLvXi#4dRj?oJKb;BqWA0gvwbzjQ=>!1nDq)v11`a0=gIjp zm1F7OmDC_Y1dOb*96U~0jYO?eS2wHZ#9q8l*dbz~mt6kZU^gAq(oa=QY{=TjrgRN0 zOo?}V?#^zeZYl|T{nfY;$iad=4v}997a*MIDk9U0N^Vg@Dxi8g%CD*R@JCT!YT={cU-icPn$pA~tg!a& zM4@9H`t6th6nMv*&2{tor$7*x&}*d>$)DAbee@mY;!ufw5o>&ZfYJLKB{?f4iUo7k zKBjoVQ$$i0IP90Mou%xl2+osDG`f5&DHE@*1}AsZOT-iKV)0J~)n9acy%w|SN-rD# zh1SX#Msm%oxhh9`pUFmrzbX>ll2)zam*RxN-8$wR<_W%2`~kn3q9jpatpzWe!Q3}- zS4FoBub2O7jUa@Gi82yW)b(icu2c6A#(IoJJ81kRPVaukkfJ<;T!T#g;=+y)E4PBT zX=7$_jcSm-HX3khE6|etnzJ+i+v_`?iA*7#wkcDWN0hpS#&8Ee53tT}ITl!g3G&=P z_G7_5?ktN-H7iQjsEWYBWLIjrKTbuV<=2iZ5dX zyI9`jY%AFMJ;aQaOq~>3xaS`y04bb_T z<4-yCsBmy#=KtwXuLwE88}`}ZIy1%ETp0EtEgapeU+-%Zt%A*^Q8>Qcy2A zH+J_aNOHkLZBI)m5?J0x zdt&zHGg3VW7k0bv=DK8?WkT`2Mu#R@!u0()b0=BUJs8&~uTDq|FJ*#8<`b5!b82hN zY?85cCl&q6GVYRU#0Z+A9vMl4MkEBR%j`2nI13BG4DdZPWTq6y z`!lp?mYo}K^lmjsk+FDS2H~Z53i*z!^_aPt)nG#71d4H!yNVCL5kq!(O>{hYe5|&3 z135I<6v3aL^4}^wZ99Q=)*4D5&Pliiu3e5T3Gk4k0v}Y;UQ2H%#J{@w<`OjxzYt!6 zaD)!3BgQWh3=YNkPOl;Y*G#wjOXgaKs+|{=u&H}QStJ9aPoR%_LTAH93mAjzbzfSL#mWLi!rc47L zEj$|RmDz+Urt(tE^w&nkk%iQJy^h7oQ{zkD0rU#~k76Suk50R$Sk1g!2@mN>#bhOw z1|7yC>dB~9{6VBRgtG#DPu+O#el+*`swp|1Rh)q78=RlI6-&f>Mf5&xGiMVDRCC+<|N4KrL3A&MJcfSW&OD+!J9U!@2icWkW z`E=4yQ63RAhdohPj_1FNyp^$_LdHf3LN3%m zaItcEpms&Y(+NM;nkTPpf*Dx3)SVe$gUQ@KPfgQQcG(4ush`!$rw+YvT?)=?5LF{J zycm;Y`zo?GQ?#Wvi3&$2=+89id*U?vZLNUl%3@zKFi4a0j;r)i@{f^!+*8RPLWYA| zdht&q|Bw58-7R0lPoX4maDQIl^KGn_t*4W@vzeWvJEw=OC-hDX14>J-L*(b@7aAHG z6B7f4LNhZn^Yin|%F3Xz_+npaY{>qK$7L~mRPYF$BdqgqmSVic41w6n<3 z6RTP3k7{z5AN~p_TfDgl)|vcBTU=s)By~vZY{dR3+}dMDow-Rb3w$@l;6ssUkRn&K zPg37E`DN*gT_{wuAE*umA`14z=jDj%=+S8;%XL|l+g0rDy~JY>^l?7@5UDTvYheq~zE4Ec*2k5ykEKumOpTKGfsyk=$+|gb z;UK+k)hHE<%tj=&%1~UAyQEMQQ#^Gvf1)>Wf-A(~ZxgkG7qr zR1U$k?kIxq68NGr;6Zv>v=0^p^xJ1-*?j~Zr)p>b%HWaGLfGZTie~+RGCyLq$+iMRWip`PPQ7ng!eBPWL6* z@O@mkJcK!rHJ!21b+wrE61+BTvWwMMpzR~L9a89y)hGI;3qBa6*V%4pVakw$B(FJsW7iD|BJ(Pb6nWe>!L z?M#cT>#8aigAbTJ&PHbv)Lve5*-+KWZ%Zr?ieg`$a+TR1oC6CJH%sydN1(plGn!CV zrYe8>SQ&Giu`FNb3XI52ljDX4A#_$3V0z-*LUB94Ew0N~Yi0IaJRj9elyX^ZikRHk zen;c^nfdVpBbK>n@^^Yeqgx%)L9{Wup^e>i{_5Ok5vqmhg1Lw**nWti z4B(biSuL2cO7sa}?%P;lNZ&;>SOmtm;zX?|gT*$dLXn`WRFg2ra+Pu)Ov}25mx8SE z)A1WHfvG}gFIx&gHEUdw*;3*5TT&K+?C&z3l@{IZhN+S93nwk-&en#0C3545zt@TF zh*S^beiX^&31f;e4sHwpCB&0iPwfYTNIM0*L70fx?u z;OHAlCX{70!+PnZWw8~@vrzpkI?-LGIx)d|8L=7nV>vN(fGh5Xa-;>mYQVtqzzeGS z;?=hV-oh%M8@%Y$Cv-Y|yPtcpzvz*zQA1e~M=iaLX;8&OVC!wMzuVmbQA4eB#Z zy9y(GHMoCL+gU=V_S=@n_$L~9)+ta9r#lauJ-;q{L2S2_V5pNV zR@utFAHZD~j8TcK@S5gqy5PdgW9HK^Zt8uvs*?Gi3dkg8MOw zgv=$mdl}0Zu9FFC_xr4k@MAUru0;)*Uit6rJU`sdMWMoE#k?*PRdF?R z_P1qC#cGe2&r*-$15PIdIfez6hhU2Papl ztfL>LpCQW{iA_nf5GZY4y*e8fB|Im`BMd5(JXs=*))4|J(c5a|Z#B#l)1gza+3_ZG z+CbBlK?uIFbDpyXGy9cyA5v?YfQ=s6cxu{ZZtdL!73R*94k?C=Qq6(6{UQ)aKYZAxzQd6W5f)opC8 zJlqzb(m^+Cx~I`PZ9ylHv!THr6_;5y)P4C^Z2sQcqlI0wX|ftKbGy3MYsxm@lG|+F z8M3~wi=@%h6N`rc4y@ehfNfYha+Bu9<$y_*(R=6&hHngleY2wQrA{EH$s`HKY+tJ6 z>y4!Wg2tz@-R(D7B;3xT=-9dqzKz*1r>0hf-l{B^8$r!+5ig&~7J#EdLgnYQzHp#= zjv-NwN=-byFT3lmIV;<6zE%;~0MClV;L$J2Hg)>Vt)Xhnlp(wMnbnggWg6mzlhV0r za7f&k+SS(i81tK;%@`8SZ?)BI)kDpdf}?d&-jvmDkT01|muGHb{%IqBVLlkPl<$uX zpwx*eMuvPLh1mNw7LmEE_X~EZ34i$LjRpE`(Ww^X15|vBfLY=I!FQMZzA`+M9bhT| zWqs#_EDckK{)IkJANKRW;fyFR|JD+?lo-b~b4v{o!GKt=wR6=;NC2{x+|fa^bp9^D zAyqDq#W)q9;yBmL6e37-2LS@%42RuF0?Xvx&fWksurMGQUrm|CdnRt+xMqAYfkRi} zu+X>jh8>L5tUz$I2^^@hlB+J)l-YpzmH-fEj0VcA=Bf+C0vrulMXDQd@u33m=D0kD z-(@BAs9|#vnlk?qL&L=}-DT=ldz9mvxkCUc4L9u9Zv;m2UKjwQ-4)!uLSfIEy7nIS z+a9QhjSNbB4|DhiFv0{OqJ#E)hdsHH6@dFe#DLKYaF^N+GZ$eSJpd~n4n&glpaG0- z?3oyMhX~}!(~~ZBAb>`_!(d&--4j_Myo9E^&RiZAjl`zRG%VkJX{eAo)q-Ii-4p)) zKsb;~=Y(hOZN3UaPko#6EI(F{$6R+y^yNO5qS9*cLRoy_jS^P3L~ddl1NGLVv(ao*KFs8m`KQKXJTG9{w6jA7yny7l3Z;MZh>LW^vQtJcLjHv%Dcm$?Xm~$e`bx zTy^yE?f_t!69NM==rW;)tApT)2n-Raj)1AAOYQA(%@~_9FX2HXtPl!MOquDD8T?F3 z+>t@)yFAoLkhvvO=5#aWNh}c4=}XhyV2)`CIKWoGCX%9{X^DlX>U-FB4%Y=K0duyQ zZENSmBRZE>10TJ;EOhna^?O*n1khfB1d_3DSGSG`k+4B1B!p@xE!}e}GfM56E(M)$Axjdfjz#Fy#Bp`-7h7T1|Br4a1YWK4qdLRO< z;6T?DydEJi#==}AkY_BZ9|T7A2je(BY6S!kk>^UmI8r}Eh!-^yX#E?h-z%U!0ze!W z5co%xm^&wo5Ws&l=^5~$aR1gDIFKX~#2&2tm~YCgKBk8BXDFw?l;%HqX#Xh6--`AR zmHN-t|6+f(7JtPB|D^wp6A-}v5il5Yu0;rgv;l9R&uXUps9?XCie@ua;mOWB{bH>q z3#J;~;B^14;gudy7WJi)_4hJmZW$&ZF0s)p|{Wc-Qc? zciBeZ*65gOyomMLAv}Zde_4@#S{123mh&HLaT3~hzz@dS6N(4FZQb9_JzT)@SMgk@ zzJB&z?4L(=$D;+8)&Y7~xiOc^93B0IynOEaD9{BIAZA#9lc*KoU<_5lYZnXW-2~X@W zZnYbkNCht&8+^(V)tRzpHX$nU5N4PEak=coBlilXov1a^u z?#kCnC&0?FQ8VC0X`!{LsNsNmT3|4WsZ?%YCkKY7NEfUjwW0VtV z3>y8t!7(<`kOXO-n58pz#HKq(+3H&EQGW(Bnf93l-ibz1ym_vLh?h8Y){E+mma+BK zz{lJe-ehc6gHkF`BU_a`Yk8$@o%qw`hOz}@>hG8YW3p-fEs-00fzPyQo&_80Jy`zk z*!gtq-tz5qI>spvJvtq)V`8RU$zuK})B=Jn##amHt=LL+J1oxErC=Z4Dhpq4SeQlj zMr*}pbcQj_;1Qo>Y+@x+e8vthAx(X3xwX%UtUe&ZUNnJ}bqK~@cveyN*=GACNskBmI?ZvXSGhgP{nB9PIfb4rg%rwdu}6=i#QgklYi)Fnnfqu!`&15bqisXPx zc*tYZ)_fBLmhT1BrzD2N>znP;h=kmk*#_DIm+-Q=>gF_^B=I2IgWzwSYR^_<&I`B{ zNCg;0K?aSEa`92>zaSI)<0`4&!%~TX(R4V^;Yo^ktethC6BnO~XQxsy%%IO-5a?Hb zTNYt-R6U6J$D?k9_|UA?Aeioow_yjv4hRrUciXbZJh|#nfkX2>6H?u3ersp*a6pls z34rNtvkNAd2iR)eivZB~JW>QKu7sH$PX-Qv4E)-#R0V+v|MBG>plzp6SUG|zvl@|< z1`Sm&HOaF_7jKKdH`@*5fdjOmgHA?h|IGF2WElalN<-B-;S^{P3}d@*SbiQ~+$|XP z)T0LA@(>5`!##Wc)xQ_Ib7FLrHy8#EF8Isg|KHCm{}~8e$c{_3&YG1;DoCn#jhu@m zJ*l5YGf{VX@@5F!^^s38TLiH8+0-hf#BCZ|8U_2Jn<4)XOI&7jFte0sEdvBOWm%nV#FQ3c-~kzUcXwc`&dpQ4kQp$1s-T z)$^{5f?=tg12g->mb3-2#NZ9KI({Qzf~m!um7O*e9=TW7yk{xA9!&0=_t#E~K@CeC za42uPq~fm+m)}3{d@fc|whtu=B;F<0_kNX!5D>Wig8|_A#0==$f>y6!n%cJfS)Dcf z-`zYaa1eNQ;wr_P9WMmZ+qj&vkZrF_RfjRK(A-~J;M(I2mDI= zJOElSjQkmwMcdCV6*Uz8-vYqT68?2+{ePZbLxn#2G&026~L(VxZ zem0G+}~p>n0VW-RGHsWS5cWxx)>T-S+e(QJ<6D8{C=xkvcRbZ}YaepCGO= zb@cqm?%F=Xlyin|ZEXxZfqzaBUb=@;N}9!+5IM!SGSZwSEy6twOv%Ist&V9;m!6Ff zOKQG;_IIMsLQ~|%F;A;|nNAB#l#=^1dZEz4#>`g#wngvr-WhH@NjJ^EJQyqQcveRH zkXVdhiuG74MYD$i{jU02^hmyf7-JZ((Z8)6bYED0&RrgdRe3kf#fNI=8V+KGH*_3-Byqef zJ1QML*q*x4ff|G@2Wc*!_9NDxV}<&wQ2vmP@$nZ0EkED(-hDUX%ck4}8J150LZDjc zCx~eUtmo0=q%gJTC>n!Jg-5(%# zJx2QonlbxFkfvb&%6Jgu@|ehBdya1E*Ik~&{pG+vxY!?QK?aEi!>+BLLBWxZ%HupK-F!)j5Gv-hj)tL7ji1B<}U;*5*%+vx2P3 zt121O_y3jtTsnFjk^eQ6cP#IxDC>8<+)Ib#DuRQnXI{4^B7ZNCrC@#%& z2K;{|O_Ti*{;#JK4q79^{LfwpH*in~5yt;dpO^4ZYIrIvcmzVYe`WSVTZPFHtl^=H z!mR(F-k;zT-~G?dF3+78;Gwa?9DmK^Sr#-@l>M*r7g0g1KcDcgjBx0cC=2zUn(gI( z=W_kY1poJA1(gsZd;5pyKYveS{F~vqRDlHt=kDR_XyyJVbzDv9@2~l1mid4F@c{f+ zKU5;