From 93568c5589e58b1fe442c854728324994bd30426 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Czekan=CC=81ski?= Date: Mon, 30 Mar 2020 01:29:01 +0200 Subject: [PATCH] gpu/vram-to-vram-overlap investigate srcX < dstX case --- common.mk | 2 +- common/gpu.c | 7 ++- gpu/vram-to-vram-overlap/main.cpp | 100 ++++++++++++++---------------- gpu/vram-to-vram-overlap/vram.png | Bin 10961 -> 14418 bytes 4 files changed, 52 insertions(+), 57 deletions(-) diff --git a/common.mk b/common.mk index 03d1e47..d2e5b91 100644 --- a/common.mk +++ b/common.mk @@ -5,7 +5,7 @@ LIBDIRS := -L$(PSN00BSDK)/libpsn00b GCC_VERSION = 7.4.0 GCC_BASE = /usr/local/mipsel-unknown-elf -CFLAGS ?= -g -msoft-float -O3 -fno-builtin -fdata-sections -ffunction-sections -Wall -Wextra -Wno-strict-aliasing -Wno-sign-compare +CFLAGS ?= -g -msoft-float -O3 -D__PLAYSTATION__ -fno-builtin -fdata-sections -ffunction-sections -Wall -Wextra -Wno-strict-aliasing -Wno-sign-compare CPPFLAGS ?= $(CFLAGS) -fno-exceptions -std=c++1z AFLAGS ?= -g -msoft-float LDFLAGS ?= -g -Ttext=0x80010000 -gc-sections -T $(GCC_BASE)/mipsel-unknown-elf/lib/ldscripts/elf32elmip.x diff --git a/common/gpu.c b/common/gpu.c index ad8deb5..45569fc 100644 --- a/common/gpu.c +++ b/common/gpu.c @@ -8,6 +8,11 @@ void setResolution(int w, int h) { SetDefDispEnv(&disp, 0, 0, w, h); SetDefDrawEnv(&draw, 0, 0, 1024, 512); + if (h == 480) { + disp.isinter = true; // Interlace mode + draw.dfe = true; // Drawing to display area (odd and even lines) + } + PutDispEnv(&disp); PutDrawEnv(&draw); } @@ -89,7 +94,7 @@ void vramPut(int x, int y, uint16_t pixel) { uint32_t vramGet(int x, int y) { VRAM2CPU buf = {0}; - setcode(&buf, 0xC0); // CPU -> VRAM + setcode(&buf, 0xC0); // VRAM -> CPU setlen(&buf, 3); buf.x0 = x; // VRAM position diff --git a/gpu/vram-to-vram-overlap/main.cpp b/gpu/vram-to-vram-overlap/main.cpp index 3e5505a..54050a8 100644 --- a/gpu/vram-to-vram-overlap/main.cpp +++ b/gpu/vram-to-vram-overlap/main.cpp @@ -1,24 +1,11 @@ #include #include "font.h" -// 24 bit to 15 bit value -constexpr uint16_t rgb(uint8_t r, uint8_t g, uint8_t b) { - uint16_t c = 0; - c |= ((r >> 3) & 0x1f); - c |= ((g >> 3) & 0x1f) << 5; - c |= ((b >> 3) & 0x1f) << 10; - return c; -} - -constexpr uint16_t randomColor(int c) { - return rgb(64+(c*432)%192, 64+(c*127)%192, 64+(c*941)%192); -} - // Write sizexsize rect to vram void writeRect(int dstX, int dstY, int size) { for (int y = 0; y +constexpr size_t count(T (&)[N]) { return N; } -const int COLS = 10; -const int CELL_SIZE = 48; +constexpr int TEST_W = 3; // Test x from -3 to 3 +constexpr int TEST_H = 1; // Test y from -1 to 1 +const int COLS = (TEST_W*2 + 1) * (TEST_H*2 + 1); +const int CELL_SIZE = 42; const int MARGIN = 4; void drawDebugInfo() { // Draw grid, vertical lines - for (int size = 0; size < SIZES + 1; size++) { + for (int size = 0; size < count(testCases) + 1; size++) { line( 0, size * CELL_SIZE, - CELL_SIZE * COLS, size * CELL_SIZE + CELL_SIZE * (COLS+1), size * CELL_SIZE ); } // Horizontal - for (int i = 0; i%~b~-}PJn#|@&4+_sLcyg`u$$+%&2}3E6~-&h9+L&{wY>K@+CmU& z9Rv}6f*=9-i0}b|A`BpC$P0o@Z$Xe+NNU*ubMS@SaU1KMkVN{MK_Ml8PZosiIT{8* zn$M+wu%N~W3kWhkxOeBagVCKIdnggZuT=FqP5sPw_@1XNikxrullpU|{#${sPZ#Zo zUiB1wqH%6}hBkM3v+@hXeA&GFyB38lR5El?e?eB5m*uj?O3a#^EQTOj6%vV5+9z;- zO?1R1kt_!%qhbV3VgWW<%$*Py#7?jVKcY<%CnnrpbDMM#>Efs1#59%>)RbkDq~~51 z&Th&I-YDXC@kxA+J+;_ku}D?uX5i49fB!1SVh7hngV@rur!hS`cC46 zfHmgwnn`k&6Q>r;IGa4ZIT2-o**`83V{h%}D;E%%!m=ObGH?ypAwk}}rPmU~9#$@> znNYQnhlFGotNM1C$>Xa|G#_OTS}dG#yCmD(3?F*AeIIJHJ)9p~va#A*do3q;;vV4v&k1(IIR1uBaq|T3 z8=t#LrY7^9nrhqOLp}1|VUovzc()tOa1e3myH&sBj(GF$^+G^;`{6)7mQi&V4+!brM=db!S-O6?a zS*^{5>s7`ISpj=D^o`&Usd!xT)vMIdI%RXYe9O1HRj!3B9urPT2ctYF+9+Z1bzu9n zvsS)t8Aj=^AdvWji#a}tlG+1v_iye-@^ndL6#9f#jYcXQEN$1&4TGW%0hu+TOlpIP zEnLNq8b~ZlB4>(=5zvLnczlwE7oCzUz5kyVLcN{eM|)BBNFSc(CZqLfaME)Lda@99OuC&o zMl349B)`C?&xV~jPUp5sL`Nj0E7Nhx-A44#F^3=Ei{6$E_}grvAWlK1rVEXcN!JD8eBx z;ljaTt_YDNvGZI$EgZN(;9n*XZM5+fZp+5ZV-gzKvM<~xvFeSvVOS)XNA)S;;Jrlf zXcokCr}ZnSqNjxU5=nXxlB8yE~m3(Huad}r?N z7rL$vEK1J&EskT_R%DCipc9%ePPyP?${L8^!5ADYmUhS6Wp=ir;pLM41mdjbxCtb& z?<>h>&2E**Lxk!rw_B5@oCtdK2}yTnn{L#%GYW*|mJozKGoEhAU~!1ljY(9h_}#>9 zF>4iFL|tI%PGT?3KvF#)e3@`w^&aNUS5AbVH{&5FI-06%kM{tvYFbFI9TrY7$bOvt zts6-UTyIcBboq)Wi4(#x+=6Y^lzbS7y|KJmTp@>@CbZF}Egue1)e;VnpOb_ybtB+n6tS#U)lFnOfoLGa8|Xzt(AH z`UNwohFY=4;>=vf*69=1bKPdUx=vYw;Il7A%$>=XcoNzA_+PfHkUlnJv%;}9pP5;T z#GcOg^k@^7yzgfR4m#ox7UFS^Eq)>4%M69H%l9#F_R(P+*t4 zOx^KI*qgPh#5B-YP$wWCF7M(sMK^zLf1-nP*7k0}o=sEo%g};!KlL`~u6a?!diDX) zpfZ_TDc_=6UBSu>ia@>6XLj>itldWt>8*K4T00-poELpoZ!D&|o7b8bfoh1Dc|3Wn z3LG34>P&*tkh6LmHbcSBl3Lu^qT(BuUT#Y)J#*w(-WhmYYm%P&S!*;f;$y4Oh6_=oMZnY!?n+PhZ+S z)4n8rrj-}51sw=Sh6>r!emH~ z-&90{vAO4!_Ao!ThjI8k?+QcYHR>7RN@2RB>cHrb3Sl{;?frH;A4$zjv8Cmq$J(Ni z!#^^@_?Xdln;}tpIm?xid7rWoT_fksaE&i(=XE2AW>Ys%RMzNBYu+wV(9`a|8+k9Y z$w9hC$S681j&iq`!>%^3ao+zqI7@?L#UwAVqe|Nff~@8%fn_!F3jfp%4$)*nVrY(N z3s;-3(13DAVUhF*_oqrHDN~d2@TD1qvtT8gosn0vqKF41VJi*g%MQ>a$hhRQJsbM) z)d#p#b=ky$Ths60{@T?~!KOGdsZh2#z*AqQJT6yurTmn+v*HFBv;5>9&RSImCTBPi zKGc?p4S^lays3vJvg@8O<@y+#iV3}JuIx8^h}vF9P{(105z5V%&%1F?H5C?66myt)jU)o9cu>3{o1YV0+#TT{$b0BEJRdz+c-p#T*Fc(+Ip5aQ`9A95uz&JAzHJRU6GH-Q%nEjIsM+5mTOM zH3zEeogFZ0P`%Jn)ihoZ5-{XxeK+ZL2foKf#^Lp(rq>Zc%?WjbA4KmSEYW(Sx&o3l zkAxkP3Gq`Rz%|PuwzsIvkb^i>*WcQVKM0#_9Rb^#-q_m=nPx6xe-~k#jj&6DE^UDn zUg>4{LtuYR{DeIjz#H7|7whUIIUw8YS_HOhQoh-IM?R+wKl_8PSQJ=wrZ2xw2VCQk zV$KQ(?C)9zp+qaNr3Q}(wVWLj!z~?>hsbNg!v@xTXl@`*U?5Sj?rfNpRUMMafH@F& z)wTtmnfhwGRYPX5dvFv}A)-V+)cu>VlgbW$lH#bflhv*nDP|`jv350M+cdR+x_qb| zE{+<{J>>(Flurztk$rc+O@FbFMcl?7?A#T)no;}m#5pWuIG&tAuvODSu6>LXF|WUD z?f_j1&~C%O;XEro7B>tViYGtp3HQYsK@7S*4uwh<0}yvY7@N5E579|or4{w@c3S7d z*=Bp`8js*jiqoXT8_qP#;8GLW{Zq3~;6v|(KK&A*UvtjzBuB!@f%}(Q2oXGUn=%m9 znZF>EhhX9u^f|+Tk?I>R&}NHu!wk8;)`=E%vCm9vm3;i~OrwmKHXYoS=ZR%|y3qgAdKP=72 z4PLY*t=hhgItl2yR*#=dNWdeD&6k49YK|scLxw<5duE?9oZAhcuDj@!T%Ryr07Qf1 zBxU|G2zsJ(y#RVLs|G=%sZIn4^0Jdv=N{XOa-b`b zJ7vJu>|4y@5X-Y1{l{-ND}*wfnXlW8kyC+L)fF;Ff>5Wry{p8_q)~r?=xJIvPsMff zr#Q_lk2mW}XOME!dfovQaB4nd()hYX!toJhbI_Rn03T3XZmWOQI<3&Ms-66c$4!xD z`%b~nOTF=gLJ}tiL_3Gqn_Z)BXtr>~A!e2shrlxb#i*PFpuW?J4wsv+;E7y8D6r1U2otcl^XP zZ+r9iNhI=U?pij5xa=~8s>$B_EG-^6ek<74)A(^t;frimC)cT#?ae{eZ4Oo^LG{FA z9m2$d+dIOn1ejwoO;Ki3-9n@Y9FN$nxbm8XXFGw{6NlvE>@DBBGGu1d$@D_bOz_IV zd=J>IP1r!acRQzush&cv)2@^zdXVAPFY&q*4PfDZXYHe;(*{PA$(+l!^d4@hxBfjo zdNdtOUNfhvR!OhJ{=3>UZwAh-qMsVU5~0P-R@bhDAaf{5 zeq%AKsQB*hkiY~30wOD}`(+oQ^`)o0>;@|s7HHhaw+mMgIvivpSlK zLbOTbElKfGhq(Un8rf#YxEQeU*Vgw|%(+bU5QJ;gDsG)($J|tN5QMwcDt@@0?rMdl zx;iQ3cq)%Pll8gkQpUq(Z}#?9qLIA)VQ1Mo3KwmIbu+BL3i4Y{L}*0p6Z{N6&Tv(H zWvi^8VTddtsIV8yHV^9Zt~BoYK_U7 zuC$+d2(_`?Q@xVHMaDxr7|m2UQc`ON9!rzUNW7q#VJ)b6Zj|99sJUTB*ksfNZRk6u zkh6lI3nF&(E%@E|Nzjye=ee}u4p>A-TcsVuv`(B0^O!EVa9fE1V}Zd1IV)I)>_H_0 z*f$}JM9z$-)E(zzv+v$-EhBh5=42b=imdSWvRHAg{+1BX@BUPF(u#SV%W)KLDYr}qk6H~(rY7~ z7po?r2=>p2K&yQMwQ3KuAMerSyaY2f_V)G+qP-+)XkeY6j+bSaCX$a=uHKbp7$S`|zQ<5{3Z{HaF#PAN)0+6}~-_0xYUsXad?U=s7(U=&1-hqz?=r(n6HxDWntvh=tZ;xMM1qpIb6A`0i z4bg}VTI4?r9~UAu`h*oif5_< zrYsz+g1&;tT-D=>ISE(wXL?sr^-@LrcA3%&^#e@JzH(l7VZuofP%Y!yg0m9$>f z!HI80IkIed@-A4Z>>j#8pvy(w3_GKWcj(yJvXCjJxAHp|gJ0v2v~$wNSsZOEXZ1@Y z(t0(RPM^(}$Kd*%qf4*35_k_9v(HPtgaMn1s8tFr~ zz^Gzd<0(yisW^|w4Bt@A(Du_;#BFX~DC|2(yTQZBKHca}wtikt8C zw;0MsNA(5@!i$Sio>o*CDIF^luWRyiydpYVU6IGTJsF%ANoHq_=WL#;UM4JQs(r+i zN!jCh9e}LC6c0%^vV-l5@g25n$`te^Q2_jTi>a5==g=2=n7&IL5z(mc-eQ`7Mx|JU<>v5$ z(=?+MqYij|LCMUx8MYv)y5@aTN?ch4+vc_F#6?AWYC>UB5FZ_c>f1yeokv7IUNE*3GZ{nPGOR`w?nOVwdLpFIt1$^*zpga-$J zf}@A~o-Tk*hXV-v9_v1bq4VwSH)dpyo<$WJWDr^(;4h!z;#;A_rdFAsNW_i7GN`-6jU)4xdDTkwQ6`Ad?R#W02-N_jj!2un*`?`1 z62Fnfq=?5SZ!Mwm``_`P$ys@uP6CdNcy9)i`vb65W=s6j_||GMC({JhY7R+QfxuBWv_M&H(QnwI!%S~dRiSXLoQ4~lfpxKU4-lGBr!6wcYUIx z6s`4tS8~N?dJ*pL?nDeB+^quBMAm8mMngWqD8tALBPjJI^*kf}2QW&xESGWYtFu*w z$W21Ufs;<^*M1SR+mAVqwfqYtP40%a>=%%jnNe2m7D8pFOlgp^-%e!*=brEHKa601 z^M(%;O_79~pYdl5z7IQ@DvIR*^sHn9^gKlV`M$rq=?=^(C@8II$>3uV_iEb+HiOU& zzb|JclL4{gQ#=fzt3{GA0M_OGypOO78@h(srB)*R@$*wD9xw-5%s*h>_??JHPcf?^ zoAbWvq3SmzZ{>$t$fyw?Hd>*vW%pY)yJiye9$3yPf;}-jO1%BTxaZx2z0GKSI-5Al7fQ- zLz#M0%J##pnqG4<^{JKGwE4*(prcHY@=r0H0t4y6)}^^lga%Dq5}!BRM%PI3{5Yhr z*_z&yZHygyUiK05*OIhiG|Vo!DJhZsZn0YWXWiM&qj}?cxZ3>Ny{P7hWRX7R#mnqZ zuB51e5j7gOf)LEsf8$*@JJgc}1>Dc3%rm+xYuak4Dz2U$F(e;49q;Oi8lpWchgL zk2WQ$DZORIzq^tE$=7&p(*50M5wtSMC+4&!v}y}jMh{m@#zPl?WCU#xX7h38wC+~~ zkU!^8K3p9&Zj@0xZUYj5fZ3Twy@4Lv`o#^d#Vl+-LfeFqYdvE1v>ER24=YY|dA;c# zK_H&|;US@Odh%P*#Q@#DWzwydTM(?6a$&3xk)SZ$-e;sLmSK&|@@ zYs#;K`R?g{N5v`|QCsWTSu54lLay}4aJoSF7vW|V za5y?JMaK$o2x({H^SOEA%HG(In|8x?&J%S9)j1wcDQ91r^P?^>B;OZfA zKBD3o5B~g%uWiv#l^c2nlBDXMTrysnhA z_`e;YR))YC<$Nf&TGO$8C|ocsMa2%uFZmfpLF5S0m{PXdzkjCV4B^z=nOeY^giXKs zpUy@e>c-7wxM?}YU*3)bZ)_ETjl$f)4QQ2i>N&$~3W~CfeDuIl_T+hn5e05={Kve1 zz9y01mz`P#d@l4!Ts^P^mf6MgJdiZiD!ZShQa*4^dV0Fsyl(8j(cE^{DIuXVwKq$? z{Z;$&;5R^3GqpZ!iKn_rTIsCjs{5{O_@{q+uYje-Z=6kjB4nIPVGN)NAFrf6vrs3v zCQRPmi(%L{B>%*=)Ce%S=@@6s+~6f>85mdiu z-rFCT$e#4Q$rL7ltUrM`AE(~fOI!nD^z4h|IsJ3hg{wfTj?KT~oXz=sF%N}0(n{4Ia zE}FC1!+2qK#JNX$LFXeV-a)8?RAJ@E*|CK^Z|72!cFHk*phFfz$MNjqppP(Vf->l( zV)$A5kMHNwZP>C7%2lZpKOtV4(aII#qnW87cS)W?ooRVi=bxAPq>Gnr?|y`w7EGxi zE->2qPZF2I7OcD4*u60}nrHeyXD8{l%I5Feki<|TJI~sk)FF8e@ZqzN=a^$zt(Zke z)-!v{749EPn-b2MA<%C(F_SBT zP9E^SWJ@n*k!~`odna%C^}co@$fa0TKH_V8ZjJ@c(9CnWyPU|8Qa)M$8d&(MZq>q8 zJcO~!HPEA?bX*-dTYkbghzJN1bL(q&@PK;@I^AAf8nHB?PO(To8)XrD{6oG7YmmYW zKpiYjI-%d;1s<{kYAGO@8CLD#$l-S*nPtT}%&ST2ZjS(WXa(uZFDhPiYyHg6r@kTu z3+t7njLK_+iJ(d zOtJ_Ao3>CWgwStngY`2sy$2E$bFx-)6}ASBt-VJmX?(ctvo+qsxP3-ViMFr08UAZi zo64eF6~7Y3zT^sJ6i%Kt@-V$pc8}nF8ij^EW3QDgZhK7eUJzIspq=&f@k*TGL%_(H z_@pd+zN({Dpqr(Cb5j;)bJ|gmuCt0{xPyA2-|Xm!ueAIt+jw2CT_`Wua1;KBRY0xi zfKPW$io({`M&1;B9agdU-<)9`@fkpxJgD@I%(Gh>G1G~DSWR=^PeShf;!>CUI`D)TbNVp zC+SCPwSDZr@&Pt<-*uNtiC)^Ozjdcq5UM)x)0(dg%~D5^R-$p$l9YxAlO!lFM4GT% z8uEos{JlWtTwsvpr}coqUNiJR5!kYo>~@)rdw`Zb`tJ*Db-MyhucJVr?j7%dx|1K! z_rFaE3T<735%18gzNu*UmZ?=zNJtuizs1{bQ3ZVF=$zIMJLU!hsc8pVw&FDlU^LxK z(tizei*psZdI?Rg)*;U zSC8=C$iACGE9}t+KHLwkqfS9~umq%KKB3cy6E9JB?y88DT+IarhWxC0lv`O4Y5jB) zt_NfO_K`wg$uCMY-rbBMB0ohSL#t}O8zXs4IKebSQV!L|`AHDveNV!B>;C1Ky(gxLG7FtbR1TdZQoj!c30a)N6EC9Ummr>UH-WrxQlsUIQnpTs?9oHqd$3$b?}}*ECkNd5)z?YnR`G61C9g@0?)_A3lny%UCOTmp z7TKtrHCHrriH;}sV1j>B?q`X>KgdzvtQ+0;2M=6&SYYJbVb(_{6lfDjF_&cZo*Y@M zJzHY^)Es}xm2FEbdl+QKG)0c7j{ZvHnJq`NBdM%xYYi@AQa?VSKFb(bME|K|w}T0$ zda*8%Gu!^FVxjMta*v6(SGl{onU_r|2)2-Lhskg8Qj%6V(>(+r3MsF_MU2wpnJY&SCBm z!(u{mnf%bp=da*HR|gwpo2z^WvM$7xQ3&2j7DFzI^AD@H#p`C21Wqg~m+!3>KRV5# zzUY;m3>#<4vL#iTGR0>^IiHR5z=yEuBa&M#bKdyz7GNICRsLwRe^fmA+SJ$bZCpqE zllBj-yfL`T*UoukcPL`JRP0;qBzN0--gy%|-rse4pZ?&JCj{@0j8H^Uad)w6EhU41 z49o_^iDPQ4m5#Nh09f1mVop9&#ZxU4PvuzSSQbn3J%tzVagM4hk-6W?)C=F#p(R%+J!vx!M)zZi)Gk z{g>WK&WG&tG@f^@ls|lO3~0PjByFfLc4>)en)r7P@XOV2l|7C=|py#oIE`i%cM$OTkoh%}Qui$Hb3g(c~|h4N2?e@s?KG5_7> zjMWrp<%j1B6ORASRr%Z)?AY!o!qqEjiH9Osd+8;)M?)-u^)C zP-&fv14Y21(SNhtxKUbe{4(3#xST8{6`6HJczDbOdLBNlO%OVi=Ssl=xD^*y3IR1<{1f!_yK?6 z1jnhucVYdX%Zssf8$QpV3YlX3gZ)?fBM%T zB-RyF3xe{EMce1<6({b2Befv&-3-A$VgZZa@6Ff`p{q+PXib<3>;3T3PRG`3WOAKKL6cCZMq(+8H#8@OjXc9?DB#|Z| zc?4Q3!qRYp7evyb~GNLwFv1`{a>FOq~0@xn<= zK#EXOtRP7lDi&cuk%Tgc%=AKoP)ylIWY&^FC8$z@5d@B4Wmu4yP^OWY ziD*zHrVtQtGy)B(P+~+aA&{Y7ZCFVykyt`{h*7vCi6X)yk}L^A6L}bl60$ZDuSL-k zOeP_40)-P(N{Gx%GDw6faV!%ff_S9T1I^T60tEr5MMzLVCZV zjmwrStlC$1YYV&>jd`r!1%TBp>Id0DhPlGVQK3s$EE-jBJkG%613ntg2Ecad(uMQa zL_Tdj#mul=79Ke9amwyZ^RB%PwA?o4s)5hG2a2B)($lxBC^z<9{H#34KKF(I{!|1F zEPuB4#pB~UC+>JINk97a+Tz)&bHC+e2^ZhF++nr3v9in<$(gCQVRO!ynz1<(Hn{b_ zx%))uoKU2E@yV#_j(2AJ2Oi%mirdM>11&ABtgN2%=K1I%Zaz6w-C>BkymdUkQ5x4W zt|-sa^7LR#-ztBZpb7-Z@RYm3dheRcpWQPT^CgWY;=P z(KnzbA$VT@mae8oEb!=b{7k{Uy{`E!UbI@=pdM+2MMH zt?uC2bbM>k!}7O`NY?I`1NUG2(o}Dj;vMPx6IT+i-(TEpAv@(GpJ|+040afw-?ukG zuNa(OShrgDP`k)2|3>YAzqIx(!_v|vcB|wq<0MOgb3v3oInmSG_5%=A8?fW_pq;Q@ z(Rj1V=e*nbj2ipgyS zy8?OEEptDTz4QPz2QE$Dd#Nen^vFlMB-iQ?NgOsPm{q&2GuMQ9dS0%Xtnp;KICl17 z>!R)(d>{YPyh^yryKcM@u6rA(>y~f0GFW{@Sjfb7NmfT0bBtFVT~c)?y5Q=ql;9Hy zgRdH+@`QHyzE(%v-@#Ka(^Pgx-R@&mqVl%tK6L4b&d2%Q%HnOuW;J zitan&M*w#$W8F5u0UhG1Z0&J36(hTFFt3?$Qm2Yy14I;XU{kF2Jkn3?RA>M); zW5oI9WOJzElg6QK*|bQwD|(t@TaPd-s?9%ki>W?Zmk!tMdZROgcglQ*Wp?nGkex?R zmOg6Lou=N0JKN{!=S;{h0m0$@lKz>l1(2el`PzI9eK ziVIz3S03BQg1^iiwZOPz7T zs)|dZi$^7T*bUyC)!ennYyv8T}t3x?s%<2_0C>R-X_nC$DpG2rGT6%xg_^O!kV-P?vB-u*yp1h(A8ZToU)r5wB=6qsLUhG&Rr%$;TEm$mICP z6ZFJJyEhj0I)Wz6n}Jis;5(+*sZoh(QO1I3+n;Ru^TWR{a8gZhE3FAfJ|7x&_-1O< z^ITEmCPb8w1h>#n0dNB-(}4F$+ZzXNt}HT#R~GP9&iVEqV24{*tGxY`yz7O0^@)h- z;?v0id-!%lY}Eq4;!tAsaMex0vU*RVUk-Sc$d=pWtg&#-ySs#;GjVePP)Pnj$oOf7u-Iydt5`C*f_ z7i1nDkJar)Z)$DNt{C)AR+-7#?}Fn|;K)?Qtk|~Zn(N(Rxxxiu^MlPZD>G)9Ta5l~ zHx#^6n*Eo5(>1r>V9a`AK{%NZj*Eba^^Nuw!Exn2@^yUj1oJ!fxg_Rd_pH;&-X7;% zZMHW{cgN&{mCgp46?#DxZy0OXmm`=$<+I`!%AYBd^EyXwS*JE(rsZHXN` zf|#edbuQYVsBbB2&>GKOk2QP(cjq=_gNt|W?9H*D_eR+QzlI3pLnNr?Wv&KvL?2Hm z6tJkxTTE@-L_U7sq)7Pz5_&A5P_dUY{4VLYXYi-j`2+Jgd@4}x6%x2E&I9|V1eKaGmvbe%K zDfeFS(}kYJ0c>FYy4^~T7yAv?&}5}o65~rhtOv=C}UzBcpQZ%rWb>&5g(4fn7eh!HOk44#cXF2(0}|Im#A}oOgv_`pQ>xuP(REwdmwB=Z7`a78rPR*MJLMjdEXCmV`Ugl-&C@aM zW9}dF>nQ9ID)w3TwJmwO*PNBsJF%GYo9JzCWPIq1Wgcd?cA0nH-|OQ+KO;o2tUj8FO*0m}MrQnKsOY?T-cS9s z=7x4mM(^7uS6#e)Tq!r`0-o-+b7W+;t~Lkz@``(m6bmh6WqLu-eT$X^$2>eC@2Jj; z?X~k8d|D%Iue4tubq(GYHgX$uwc*>=(6`M{GHRKv{F~N&-8SnC{h-+O4qG9mJcTC@t~y8F)Vp*pied}My3m**!T3HxJ==ifTlFz02`IJHlhk$x zvWaq+PUio)1JBszn^_TEoZ9Q~z1`w_#Z+i(v@T=*I1smYs&S15?2Tg7p8Rr3!svaU zo5SVq|j!_4I zd+iT<=O!bMjEFfVrjBY0S@%l!1>Iq-QzACQ;GB}%%2?BQqrN<*aXjk|l&2mIa6CC` zMAqo=$Jns*bmw@3xnm%`4F|)i4AZ3T8*u@g4%I1?vPbUvZ-qm=0`f%C1WL-M8`W834`cQIA^>UeISve;F7 z&@-<2p__ny4D{L(!_t#b8H!zPO8cBC|Kp99mC*k8W}mmT@k(y=;3ux?Csnapmfyew zlOLJW+2Rh{B&L(Q6BU~edU{;cR#K7isDT5uyY<`J?tdchY|OjfwcSr!<}K~+3XV}H zRP6nM#p_*N%ot~rP6gmcwv*QD8a2Mi$*=S*ptG3s!6o8`oo0dDHRn-0HF2xH{gYax zgQ_L;cxXozb;;vgAArSH=sqsm&&9KK%zSW*x(-l>bsQ>gE%zUomEXqXgVk_UsY=Fe zdQ3a_B4>;D1WSKjBB#S(vsAB8XyVvKXq+4e2M3tZVR2xYLAX))+<*y;@< z5)NH>jVrrLkL>|-{_`dGQ!7>9u+eJWUOvvEraUIc@R2JOyXC4>gP>VLC56000rC%! z`b(q@VHn2ugzt#|Og{dV|j#F<4k`li9rZbPB^??E;w<6OgydRxz9Rd!XBr&=G*tCS}n?MX5* z{bDsp4IDE${%ECNxcLwgJ}jN`Kk;Yryk!o))?eh>+HJ!c?22m|C%RSrn4F$#>31sm z%E8k~#auA0tbU$>xbL!}q-vglsQ3CSh`|vtdEgcf6gwYyfW8aj`~a|SzGsEAn}Nd8 z?UYn)f&LD%)Zl|Jl96py<1POtBrk9nt3LF<;n1RpOWGsSH_o~r{djvNBaOOuDVqqQCZEWP ziQ%U|&)CC7<3)%2f}wVdqb5PYxAmY0o0vA~jP{c-#E7=^9v4tX*0ND&Y5>b=g)vWA zrK`*bS;!_RYGsZfA8dvTEze;Qw8h(8nKHq@(}OLWNSO>rKBfmNr!WQ%elwdBObtj; z09p&c;z8$D#-=eGH5ebmCSuvLOx;yJev&f1PsO;bVpw#^B`gt42=#*6XfT5FjX=Jp zO?vBpN1KddbLb8u>l4dH$5V4t4jGW5Y?OXsBiA%ZL4%w0vEIszxA_Ywh+3sP6pDOG z*=J&gN2GiZBA7gx@sN7sDxV~K* zcNmHdo|ev#xNPQ3J-p3#Ub(~m$&d&v%FHIxNwuxoL0i%kjyu|V9TbST@wk*i{D_Z(R~~D6zJ)` z{+g_2I0e68D^g!w|K-po2sG<^n5OO*o887iXAUR_pF(Grz1Sn1JvC@6lAiaD)mFZ< z?!h7_C~?{S3`3jsT^Wa=EFIhoV36i1-pQmXA78$LSNQZWHOFTKzxgyB`aT@$eo=Ox z=UoUqkDPD_Jk#zoJ&c|f?1kM-`z3#j5H&2#g8E`jKX*RuMetgE!I%SKClq-afn@gu zlS~Kt`dI<^-8#=cp}k&tiyewAhhvfd%<`H^*}u(nEzDW|t_qUAyT`gg=QoUx$51w| z0`BSLxU(!T^OUu^?fKv{y+r6Gacs^9Xy}AE%Kf2{OqQ1eWn@Gn*6M!G2l>dte`*Bm zl+7Z>qmW?U*NF4lXJN<;%A^6U5#na4KO1$VYz=w*d96=4(qUi(kc)1k-kHZCmt9(EcZ%Qi zSm(sYFCb3B<6w3OqxSl*!zz)bi>IH$-{A9fDm<41;8HtLV;OYnFI+o0jQlMs=8CmG zFHp&FLEIhIf69DTCH!9oCDo)EoBV2$LcC$ZW83?bi^2@3up;nY&NK*k1+a|y(&bOd z=0}QusL$3o)NZN$BO6`*AzuINe3Ko~(~|Sgyk{v$YT1&l&b#5Qzq>398Jj11?yZO_ zvz?^Vl*70(d9-Zj+SV{_NwgnckW-Eo#5YLY?_YGE)8YGp@?8j3hd8FMkYshw5x%`) zFPm4hS@Oa?M9x;6_Vh^VbF-Gi`=YxHP~f#O1z37N_HFXK-ouor@{RL+Jl^#)p7)F{ zU8QTPk5;iTxf4oN6(@n>wO49-SF2(XD+#x#)jXxY5SYZchdk2tYU=tKE@ETTCS-=y zGPdHUp8THVn0|?`%{3LPt;BZHl0nabL7qV(jIp7JxsoxfS@ZZt@wHAITKQH)QHcVZ=gS{i(L_-G12qhL8VDwbMDu(58p2 zbhj9Q5=3c!z)O{fn%f~CmRUE_m0U?+_T(?}-vNcWbD*8Qmg0!;P$4MLcW z-TPC+Auf8CZm?rar)&t1anbLn5zc1|_Hgkt+GnB2hwm>ER5%VjUL}KmsPH@&cc5NQ zi6MHDIYmA}2{j_*k?<1K2+Gb;^QguFVed>T;9F97WIB#oVp!hX8~JhYeTo=X>Bba* z0KKz+XvDiAl31miUH~-$zM&(x%+a{VKd}T<=M@DIFA}9+f%pzb{5eC950=6G6#R?= z3^4p;-c$j(-nh5^;e6vQ4-#I_klHBub3YTxide%%pdzNsiWP=2|8bEuXI2NSqb%>_qR{0BxAf&_DjtkJpf0Z3 zZj*ZCQ=Qw1xq~_FFBpb;47|AXtQtHx_iu7AwZ23CF;W!EpIgR|H@P70Lmd{|(qk8R? zV|%-O5A>H@fK1-#_fyH#v;2aMA5vu$p7-OGMo**1y$dL2n7Nm2Xp%?y;aAAG{8m(AIVFzu-xX4_~81DmM2{xmAayl)CtHbzW=j6ahF zWz6{VsX?mw=M$2cpYQ+v+C8bd5V($z$^x1#cACMk#BH<=gZlKZiR14GgMj)%h38ic zYd`PFJ%P~QZ6?9EPGv4sT=xO&swHj@D4)pEO{Rnea>GO^OJvB&51&GL5JVU{Wr0S1 z-Gh{X$pj) zp)@6HC{2N*+-JwQqGIrd)0Fp!;=fBAeZodh#;w-kWkcDn2f@n}^oqa=6E5amg|*n&-<*LyVKz#}ch3cr(G@GysUD^-4li?7v{haoc!(%SnI3KMg> zr&j;4aUapA*H<3hEKC8*^(v?Xp2ff>%I+IjwH zE+~Z+)zgzRyidbQX_A{o@Cm8)MAZaq&bOCuo$?+~*80VR%c~9C3(>rk-^!^%>~iNb zvnXP5OBYUI2X*w1{?%bay`JISt%tLteL$+u=nm@#^UYAh9C$c$7TsqvRF-uLHbN_k z%lhF_C5-j|4GnQ(NMe@EH6hw&#PZi*FZGKI>YJ{L$`>E>6T{l>h=x2@gUhj=P5Q!Bm%*$oy=vQ9>Rj_hz25CC*2CqlYdg2C~Mxnoj_N9$d=6 zHmr?4<@h7*0@u?!^$x1yI&d@c*}$L$jNHJn-i({2x$h|3J0dC}|5j8U zOvn92VYw_pL88ld1lMver8`qefgwlVo60dxFih1KIttqn{Wp%d5t8XM>ffKy{=&h_ z7nZ!Wo#OehW)XAivT3`FIqE3td`6|&f$T>RS^cJWQQ&FeIkg48mi$OvnT*UT_H0tQ z70PrXd5bz5TXfX%;{|^6g9kgyHN0ezx-ad(h-?RHHbP+FflYi*uIRPP?;V