From a865750dca191ddc3c251884907a1df051f3b8c8 Mon Sep 17 00:00:00 2001 From: ABelliqueux Date: Sat, 1 May 2021 14:51:25 +0200 Subject: [PATCH] Add cmd checksum check --- Overlay.ovl0 | Bin 2256 -> 2256 bytes Overlay.ovl1 | Bin 2192 -> 2192 bytes OverlayExample.bin | Bin 2591904 -> 2594256 bytes ovl-upload.c | 15 ++- ovl-upload.ps-exe | Bin 86016 -> 88064 bytes ovl-upload.py | 271 ++++++++++++++++++++++----------------------- pcdrv.c | 29 ++++- pcdrv.h | 28 ++++- 8 files changed, 187 insertions(+), 156 deletions(-) diff --git a/Overlay.ovl0 b/Overlay.ovl0 index 3cf02fe2106c8323f4f0dcae32bf896707532fa3..3c10c0cddc7b228624220057fd21e7bba435ad00 100755 GIT binary patch delta 31 mcmca0ctKE%;T>~>2oSe?V{S~>2oT$RV{VZ7%G@yL19L;nyNzO1900b~3_1V+ delta 31 lcmbOrI6+X1;Tdy-2oT%6V{VXn%iJ*M1#?5pvyEa^900Ti3<>}M diff --git a/OverlayExample.bin b/OverlayExample.bin index c62c23b344c51910010a2989d29d8b10579fae1d..4cfee0c8d7d66b8378492211a9e58d24e5068b4c 100644 GIT binary patch delta 38188 zcmcG%2UrtJ*El}A1O!A3y@;5E5CH*05fLLsx`+ta5D^iua}|3xh=`~tXwX$`ND;0g zpki-WE_TJ<6+0>@)~i_ZKWCF*x!(WxzTfx!!sFfDnKNh3oHl39%d*{$9$Uf=lUPm)OW^W?d#i@&EMny zeCV2Hc23`1|(5R~^k7*hk+v$L#IggUQF8x%N{o?mc(RL1SIwnq&0x73ov= zx6jwi7&u|_^O5t;jeODlria~-=Lwpek5i{*w2KmU?Hanjwqwtk^Cy)(JI!XjxvB}XG;y~lRvHP+4?Yp$z69(Kx6d6Rs~(zFM1iI5)E+IZ2fo~EoS zKjqY7B}E9elBi0apNcc>i7HBEuq(v8A-1C*(DY5Hb+;YH> zxnqW}yl8o1((cd8wpY~Yt&3cEYr97NZP~Ypz@PlXL-^^E1C6+!WN~s z=BI4WHmk9iJ6cQOULwBKweQ}0y|M&z-`?1^=aB4H*Bsj%y6owGqu~!Y@54C2pt<(YI~j2pkgeg33JJp>E7%-(eSZ^`Ggr@L-hupxc&S*Ki&bveSj zJFB+ZK6qrk_OCyIRGXVWR4E zrznj}mckvk?wT}suS|G8^5UV+lRA#OvYXC}u3KM7U#V#3!QB*QoMG`=c5i#wrJ*`h z*7lvZA2j2bPF@ryU-QVGs$n)9rj6t`9+_~wa*`Y5Z=ftmZuQvC(y^|2F3V41PjYUV zSoS_O>9Zn2BWC4#dCcRsEjr&HQglJlZsg_TW2GPE%N`FOo~3QeN!F2sMcCVF5*-6& zTe5{iv~9mCbWHG>PS%uUw<#1_NQpK@IKnW+fwt+Syi6mRE78iLmuVzxNEF0JoK3bv znUO>@D=v?d6_<;38Dwi2*2zPjSb2>g`DHzb)L0|gKtdVg-0TdjGW7a%TXDClz zpDIiu6=j@cV~Jl@iYSrnEQ=+1WnmEqMbK>~(!$A#&q7+vNgP)r*^H$f>u`)}dMTnI zL>LR=%f<2^$Q)j(nH8ItNb)j~&aeo7A<~KTey5Y@B|xW$oX&c%q9q|*TXRCNb2Z`} z3SVPHx=lg2Rxo}Vm}j*<9{6BWS_@^GS@MHVE#v5{nvM7T06h~%2 zV53%+CX6#LQ!{JWvMAs|ScD&-<4A1nq~vRNqGty@!LAV=$3zhyM|jS&CbW>wk~`O$ z%A{G3(zJ<>FpT6C0lPA#HsIm3HHBk(5IsIA2>&D7|GKbG?lU21kT+1S<=NaB!Vpv*oQ zd^;qyAVZrx7FF^%BmpFY(!~0iAO$`zn<$5u3S{{J$sB@x3J{SoG*UO1Nj7IDlafq+ zWE{mIM>4}A_mY#QXM$PUDY;%W};*CW}Y z>)=0Zd4vebp)wxXR%Qi0;tc4zIrx-5J(N1X1eB|R7z(EnO<^REp9_A618yT$b$yR4%X&-G z-0D=gC3+g5s4%WHqM#*y)$-taOBwdkH556RLZn%~Y0+Rl;6jKY4B-rGCmb4kiG}8s z8XO^^XrVE1*|67#^@|LG9M3%15?@DsSvIfQOY6ksmX*uMo!YS@{d8X5f6`^`ef`(> z#&>!4u}|;kJ2Xdg1NC(O8nv{gW$*EYVIw~DKH}pNEwi{Ce7|MR!nEkHTz;k%-Rnlx z*85gvmpn6KTUqpIf zdZ@)+z14BOu3nAsw#tb-rQe}^cA_{Z`u>ExWh(-Wm#z&zU0k%d?#-0;PVp6!ME7Fr z3ar;@wW#|A~up|H!(c~t%P;cGc$2UY~&qyMQrXRQl z5e+T}^i>;-Gq+4inhB4gTtM*Yz)`MzYrPq$(1EtKDzz~NwQ&nUpQD_D>Qru0nkBb> zWeVa-6@C|&Mw7TW;B@_}eT3h|=0{op8l2IjS#%mIj?{=IU)uNx{jySp<*aB?r8mw=$92QtOQs-Hx68z1}If|CdWRmM4Qyex4$wF7=z2SP0l6ec;yiq2D3zu zaF*PK{$QlUEkyq0mB3W}h-eW78U<8YH<-%GVX#`Pq7|0m{A)!vmKl?RGA<|<1uR09 zk6d3URN0B%c7ltO| zGZLT+y822XHAY0vKopkup$k;-DJuAR$vBW!{~+48iD(&3QiSF}A+nh!^O9TnvZhL) zj79c4;>-c|KOqi@0$3K0CXsURSh8@7D*$z;N4CuVM*qH{Dp(quKI1p(b zSd)_VK(G}BdVpnI&^CTDOlxN}C1=kRy2~ucJm}CxL=motD<$NJx%N*AX~Rt+V$g6t zFP6MhB!i*}^3;eOxHPS!A_Q@OZ)58a7uJ0S1y$m95h0NVbiVxTPw+OfyhJ}-b8tn! zXVE`dkK8~GAs6(1;0WptaskYa71zIU0EdShK*E|4SqiM@eZU(D@{WKE8)1YjCsasM zz$CFFT@`Ye#SF0%fKS2ya!7BsQ}yVv?T_49_S0y8!yOq=q2z#z2<5G8_{a7w^V=vTjH-%8T_h+${ZEaJ-NHv&DG<)iy*J&-mmr6o-SFxV&b1?-nV?_t2u2>h(`Tl z&F!Mt`Cn&k7+*1Zn(>6xlQwVSeU3I9wt6xxUB0h_rQOQ}owv!Nu^(>C@{jAdrgDNL zM9|vfPPFV)pBraR%?$0ZVCRxM=MFEbUR%GpqR0KTJI|=#gpm{1>-rna%{o8rj7nwriJiq?{(h-p}U z@VO5_Ykaa$Pd=eF$^Mt-q;{if1@-?)(QNZjA!+CYbqmcBpHXk1V^DVAES$6mvB{Gm z094>So~d*=;Z2hRDv8R>xM+5Sh+&oMBX)q!DB=Q|t~5^vZW6Io5rFvk$+2uZ@cG7k z9*-`D_zkbhIw{Nv8#7C=%nrtH20%8+;ZRtfi2!I;zavKNev$PElgYxmZd6@MZNYNd z!%T-k1|j~rSWb}$k=h@iLqfOA=Pjev+@pw0=|uQ;JX+bXZ?3w50;XcPFT;i(!IL2} zY>cqwNIe8tYFLCpm(0%!`w0)q8S5HV?f)@r%3$)r(P)3mHO3JriIC>*h0~uGNnsVI8A*nW4VX2+xC1J@M_HQyEFV$>>T(+3 z_;y$~PZ;cv8Z2e&uzPF+*#;nk(;PZV&7fd06YMW9eQinG*~?G8_7GwB7>7IBr^1zj zu3(%bg}oQUJ+3Om_Hxl1FFMvs9{0w}A!j(zOXsBuQ(?$_9?s_+;Yz#*A`(>tQ4UOA z^+rVVyyP$6IOE0oEqe)l>xxe)Z=GB4pmXFpa@?2+=Tk=V>bKmVin+fpHg76+$g%gy zR*Mn)wF9I$Y*39K$~B-|KI)w{z0zL3@SUZu&?_Fsh|u!Vca}0oXvF715`*}cm<19& zOOB>67Y6D{I3l$vHxE$Cn1y=KnLbpaoqCxmRg7n7PrUya^3xVcNuLE9deFTVJ0 z&5imt`{Y;pi0unzMm;cGZn9ysjop&9n%&K3UV8BN;))gb^6z=c=K5&77k*r`W^$+K zD=$8FX2eF`NeMo=9iD{BI(B_ZUOANwy!ye=vHRo`R*|lI-}nS<7-*Joy8l)82k(!~ zGX7&#NObnPr6Qkp(vOFj#Af_kXXE@%eJ$Hktrs}$-h@sQ-?Z8JYHHc0W>fuI-hbPx zZI7^^b#4y6!v=-ScImtB?b?H_nwQP}`q1Fu=i2I?B{#y`^xd4t_qoB&VYbR?47A-2 zM1al}A`H+<9_Z{sU@wQHlq3(6d%YK-{Nmm_cnO=N?4OO0xPCkXTA9QO1I>mb5khM* zu~~tFp@{&5!pghqeE^u5T>pcYAwr<2PT0o-7PdC(gSCUus}PE{Ksl;FmGZI)IST(E zQ3SSYs&ecIF7}e=eGo`%pd#NSyH2Bt{_rdn{t z^ntn@pEaNyBLAi`BnS|X`Q#O_5|kH{7eFPO!?nUG0i4dvCf*^a$}a$iU?ygV?@BZ_ z5;7OYguIo%{A6kB2-Q=jXh_gyOqmkzjvSgeOm5xiAo{fz1MuU>88jC(E5w2XHJSpJ z_zZVKvl-cBmWa3#qd<91V}Q5RE0s-6Cjba0w9r)$Fev0-EbuiN3``rm8U>#Ax>ccY zChG!Wod(18Yc03_Z0dk6t_Hk}F{JnS>97QYGzHqQ)C;0uKnJk`bb;vPF`s>CDG2p* zjO#?`7(3H~+z)nu>_;9Z0XFQcuC=l=5NZi_me>Y6qm#Vk!C!*uiC*#*UqtwH@QV*# z=&u62h`xHbX!BWh$v{=X5T9iylz{_o<{Xlv&gbhoqCqIVUC=RzzC&T61scakniQ4?P!b4CYh)AD>$r zlvYV~eJX8Xy#}To)zT}m zN39;Oby;n*BrWbjvQvgfu+HwrqcZV~GL0vzT=I7?W^RYAyG>a-^x@vBKkih=8;sKC zp9rb%QDt%b&#R(PgOlT)|8ZgB9J%3e-`I}`{q&O175?u|*0#_8)c=Ja-* z@on6?+0XAkyghRHmruj~2pHP_t7ycq2RbgTURA^rkHk)q{r0+FyR@wCZX4=>XS;P~ z#@VckY4R}kY7Zmt|LqU@z;JohH*eZGNUo(==fIOF=MD#$U}62i>MIKOU0bD!2qi*R z^JWIf&nZMh?Ic`?wFtyoQrZ!8r2^7y$wVX~G)Dx|BoKQMj39zd1O>@plbDSKa3SAQ z3PIl1vZ(-X4rQnTxu9>@2H}GM9yO9D;g!r}7EqK8&66;t6cy~zt~=4jAVq`38cQMY zMKHSnUI}Jq2%m;$nCSxIVWy9B#yY;Xkeu;ioN3CEF85-BY05ev$mD4@l4eeFi!9-v zBjma=Tz61a1~%X2)G=7 zY^UAS4m`Sqan_(rWp)9n8JM-yCVdKYNxuR;(z`&P^e^B*-$56Y+~#ZBko{h+EXVQw z1lT(t7Wznwa%?u_n3tf0ZF2?NXiE5Y`A}8}lX*%LOr@8w1meqFc2btGVHk5%gEHw? z>BU_FYi3LI3RWzUAUPl)*u*CrR}T7w-sr$}W#eit#K_nIPl8#&0&s##M)SGJu!;cL znU7~XvQ-HdXj%X=~&&8P_31Mdli4}3k>q;vf27T1n6Uqvq%7N1p7I&^mG)*1Px z11$SPdp*EQ0whaHjK z)~XEX+R{TFzF&UUn%>AP{}%zF>F_MA{J-nCM^ z?aAsvM?0+hocMBCRoU%@G1|{AXHS?Ays^CJhyCWRUEJ>WG(TQv?YiNF-{YZK?VtWV z@UHfDdAobRtggjsw?UZnW|XJpKjaIUXfzz5gt^&_vNSyAWs|{QnGCUhtg$Do&mILc zTH2I|2KhN_Q?m^p1uG3%Oj0~y26F5d%pBCF`q5#0##D!LFdql?PO$%ghKhc{f-DC= z#uYK?x|AQiBbYg-3)mb3m=C&CD7`b73207PTkn8Yn2uC09WnaHMKqQb`|V0;PQ_6) zx5ut0dK693y?QXuTYwI%>;ZNNKV8_6#;f`n^_45Y30PC&8BhpUEjG|f4yb~At|U1? z?f;-H>-)5Xuv*eX9123S8{<>K&|%%;o(=Q55RCF_A9Nx-@P8c0#L;>1kJ+bBnS_$S zc!)CSWeSC+Fc}hBkh(|jBxmD4CUCaL^TK$LP`K*-I6l3 z7PG|Dl9>TYZ>IB63e4oO)9lm$CZZ)60>GxVqy(*$FhjGxDTcw4ad;LE9^w52smysx z%7V%Dqc}`WOG=xb6Tm!&Cb~&Y=owQk*czbp;(}95_h+KGl*lqAzz0r~C|8&mfv6)7 z=rRZ3WM98_{WIoUoX5e_*ZwRNo;154b=ozp;m{b<5k&^Q3r-!lq}O=u`K6I_zGR%v zIQA^Mn)>*8lXXDghM-=F5r_8s*ckZQd-_ScmW{~Q2{+$hv~Ty8>YU>debxo%4A{T- z)$DgUnYG=|&s|$yKJ0Rf!Def3h8IlPe(0@<;hfVZ(kb>wWT%U^o+@uQD)CGwA~@cj zKicu%1IF&TJmJ{hDT5|?%^Wn+)HQX=ww0%t`j5rgqm~x#a=o^|WYX)3>tmTm zp=Q*Pw$oDo7&Rw)u;zB(ho?W$_k}OVh+AG8azmW>%->|?u{xV2e=X-$ZtG%jdy&Lw z)atDhpWf(hoc7n>@9(sKC0)5ofBUMfyRP?-7KdEAl7D)Tg_At&Yx8ye-G834U7BnU zg^Pkh;iL+fDy~w1jlg}6+$L%KC~WZPgqV&Z!k-mJgTtQuKqWAsJWvTr&B1;u{sjm2 z3$Rrx*lz|P?W_<+U`P#Pb{kPb(>WnT`vlvVBdKjd!n`p8HBl3MS-@BuQx0^UfC)AR zHR&0`j4}oz2E@yZsQ~(;fVrtEZ#1TyvE0Fg3bo|eq{2q;p|YN^YX`0X!VRL<;AJLM zfF<|e>)$|oT`Q=!V%syprj$tF(NpPq*!eIpUZ_y`x#DR90=t8ly+wLVsbFNvU4U<* z-_C~7H>09-rGe-QG$f9JjI}xC%;cI;92Kx7Q)x!&38c`Yn#!MSPuygCFUYECG1U z3Rvn#Gxa>G4RhUs;>x_wFIzF}m{FTmm31S|ke+L|F`bQh(5;0yEMq=1${nP!r6aO*l)yeo1@`V(uvN}-7C+9Ojvx| zql()m!OVQ0c=;GTmk-f8@dJ&j69@j4x9ehNzfp&;wBPu7$LyYwGjnwAo|g63$sTET zVctlyt217&%doz5==`*MefLaG+Spli{dn}<`IbjkE^eb(UAcYD(EEGrpOO-d?T0vx zSC+S3AI(Hd-MrkSl8cc?uB_dWU2!+6_JRGQ;5DWet0zV-IMrM->4s%Er(w+pr|O$Y zpYGqAHL~3S_co*Z^731B=iG`BiwBGx78HfD`!*h! z#BrhH?C@Dixa>1(Qc)+>id zI=mMX!2^4TK67}KgJ^0%VTLVCjSz#g;U8+ZEiZu$7wZDhl31oZ=TWZQx+bP5XFj>~ zy)h%@g8>4z06rB#*M>1Ue9A*lKO9bxIBF7YA}D2&3@Br!flu*h_i)BgKzSoru#oaF z{Si!?aME;%W*We(6Huo5HDSuR9F7c#I)^iRg_I?8TR=%Ltia|YI>OPG>kkN*#n93VyI?Bm&<)*Yrd@dafb*-VoBN>O{HqQYb4 z&M^}4x#8}^M>2yZIGkN(IIE{_`rT`90`64`D|7~}EjyndFYXeu|FPBG^#{bRQ>ITa zURZe3EpKOso?4Ud9_W3$*P$&u@i;=a*8LW}ZE;zYX2Rb$-@1k#Z`N_lg|@l zwmxX`jn^1Iyk(r-GsD*Hq7P?%sR2HzsDGH!b%3=S z`qR_^#@mJx2-1F2mlhD8%>jMFUDMWKOo|Ov^}iIMGt(fTJWc;E1gs8YHi@V_`bHQN z+LkK)1y=wJMhgeC$qroc&x29cr3F-F!>$Wgp^-0c7S2T3QC|Ni98TfP8#^%i0pX0d zJs53zAhXvVjJY6?xoZy|A~%rvW>1-VtPG527lwo+z@n0ttOF!iuPpxNmN@XmIiq6EL^<#&OVg)@zS;}>2ih5lWz@xnvl zj8{7F&k-n>&FW3`;80Bo2Xaxi+;D==u&ON8glFLbJwh>eR(Lo-HWiJ#%nuYY1C}~ z=M8$Es9GKrG>0?))s|z~x3ahG8GPi*(=p{?r+Sz!jC?gWg1_pmeb@P1`=itA%0I`9 zE6CVcJ<{Z*b-U6H&gnDE?#UeeZaZ;moYwcaJlrv6Q2#LoQLSt38=ggOk17gizP5PZ z0L7>)+ha6V-{>56`+A?!!Rf;Cnw7mv8t!#Hs;It@(Kun-;Af+@I&{$*o3^@s-q=?s z&L?PYe*3e@x;L4ug1~WNMZ7x)v^mlQ_KqybkrMI*mU!kikW$u^z)3__ML;~`9jO4V z(ZKph6Xu{J<>Q4agyBA%L`>sA4!SwXi?a)5);gCXAsi!# zT5F|0Xf1$zbD}IEo1p>VkPhL{U;&s?1s8OmR3I~^J!NXjmJaAn%4;FzM-7?NZ|!qH&k>vWYxsjVpkEsg@(NJI%SHfG&k7WB!5V=qd)kpB#1 zOvNyfP3+5z5>u9zXkEW!)tUc+Rku{E3hDj-$Exp^-RB=XG8+OO`hRAVifxr@wyB=~ z!LE2%ivP$$R$4b*esC@rF`!gclGJyF$OJ^-?MjI}kd+$Xoc>Ez=C~>y$T?SVgdqBt zcmn|~^f6+?C~FdDtnLH|pX?6I1O{w$ryN|%15+~) zIo5aVqs+2lR{vvIp)eiFap%N=@C^Boec>c)ODaqlx&tt>IFRw^04w*$Ffcxs$A-A- z0U!bDw5JqOl$TZ-ycxctwZnSxAK%h;i54`pyV+xI=*~HXRz|#%?3*E(Zjb!XPA)bQ|u=7KKwA< zaQn-Z`y!~+DeL6dPrn_)J0&SzBZ+vu%&667YmzlF{GfO6aY5>Z(w66EnY4)hV{XRU zV+T6xjcRCLacja&&r**RYd2D(>pS?b+8Hk^26-pxbn7_ix$D`>kF0yOj!NlxfywGd znLA_pnmtem8Bh)=K!r&>?8*DWy)tcW1ac`c5vYXAyzD?(>Xw*@e|j!A!St{OC=pxl zU2Nh8&uXROfU@AGw^FH4c~IuXpg_M@KqkNgbOd$9gAzIXsC>nMN3EoYX8@VYtpGgO z7r<8myf-Kw3xj%~?o*riHtAr7DhY+zUDPksGgvmL91P>o5%Le9jFVvRrC`3mZ+~qd$?de8d!Z9w|2|%-{fR$j@Sv@A(kKuQC$W zM$~lTm`d33ATOH?iG|ToWd)UE^FSzDh5J`2X3KS<;2F^hyUDg#PZ~+2^K- zk^}U7cPPyW?TSLiSpQ;QM%0-S#VJEdIOC-1ORa!v&*-i4jKAY$GnD|GRBhF5T$EX|HrYud9n#QCy23CQ-b%yb)`&J2*74na=!4OxiDBv)CB$T&h9ULXXS6CWU zo2C0%WuYXMflQ7Bf(dm!(!U>h1wRMaz|@2Ew_45sds9L=$kGF=K!Jg0u#ktNoUAez zvr0}&FhEet8ELYC{T$qz`c5lu$p^BVr(H>*_`8w*UPqMrVZ-W*smj;^K6VrvuLTfXe}<&aIn`Oq!SHV*CL4-N^bxc#d0fi8(R@^d>6 zt}?fOeR+ACk6jBUJ8awSGD6qsXn&@2tB2f|f2PjdTl#9i_^)M-o6EM$n`wE(*ldjL zim#9Mt{QYxdamw%Tgz(q6FQxy(JtEJu$4DYEqME=Ta@f}|DLS}e{TKlrM>B$^9l`< zBaH{ctzWjZkC1%G=y-Z-T>ad(^QJq*2Ny_pJwJ1G>r=lAdluLna6R6mc*%p0@sV?5 zUmtt9@kzTsceeRhy;x`0KC|=rFEbpzzHu>1TWj`px<%I8w|~_|j=z-lfEO8Cc7VVC ze%_Rwn`-{jI#knvyE8@h?4;G#uY;nbE0>?18Ea*6!}m<56^~jbjQ*(qb4>2h6qDD1 z%KVrL{ZZ{uy#G{BUJ1B?42ynX;^2DJrqdctM@JQDfdg0Dj&)bc+K@zl4+2o{AhQzM zl?v$hYo7H#?Yz(LI{(l6_L5TGjM$Xo_WPd5RVIS}Qv#O$LV)=9jspj;r5rpH;R9>; zeb5fWQH8=662!2<%qEC6fFbDYVKWzu-v<&|s_c2pzolvaQ#v32LMJPw|C~{!zLbZS zGJ<2C`$D3v*okrW1Ls}rl$wE=L>JgDf*F_Q^Q53)v``1m+TqJ$7=08wDV-MIJOQ3z zQgN~=aq16eP%N1>ew3rfxc*9B!2G#{1AD=*VgD7*SC`W8a+oHGP&qk{^1DKm#A<|cp;67+~ok{)S=LJ0X)2#j+O6=&K6uNK+}b0Upo zHU>dZPy-Qa5cPl&cc*lj2f=|cC&|v04C?(R;0Q0Mv&*=A}yk#2TZ-wc~coBkAaSI4< zQHLXAL5Fz+Vu6CTVQ{Yj=9Qo-qreqm{fH5%!omSc+X+&^B*GQjVBZA#hV!ay5~CSd z3J?#2=Sc8Gs~wnOjY6Y0>=NR#GOpxTLLew&8(?|ud_0!!2QP*BXCN_%=$fiy?5K7= zcEni%=f;)<#WL1ml$RIQ^GHew;#T`ZgslNs$l;ViE`%jagLLB{zR)N<i#L1j8~8jl;-Ri! z_PMl+i{Dn28y~ByzLspTS7`8R)q&;n$1gC5I8)A-M1Qrq!7Z9tSh4R^SyG6l#z9Rj z>qniLNiY2#ynS%zqB*?$e)ZY|zv^u*Hig`B_4sqaoDz?QW~a0^&m8zVKGMcjyyB#- zR#oGdT{S^F=9X7Y8Nf3weaFAGe8J_T%iMBY{v5Kj&sgocJKCM*8Gm`S>dDibsjsAA zEkB+8^IFyQM;Go)i5XM*>YhV5e^70jv*5(d*)Y*dmBmjt93eiA59ujAN(!AwAZ+V(O=s+IuG1u`C>)u z+>?U$@G5Q759IFIWQ1an6siw$9aSj^I9xe26=nyHun6wKbrMujUOFr*m=58TFK8?Z zj+q@!g$Dmm0{PF;Go}%gPXKn0Zy+OHJ`cP8*&=Ykhoq`4!V%!`8B%Cs_2E=dmUR(u z$_h1G3Yv|Iq#nw5>#yzr z&hfJ|D>9)5tWKfO0PFMxEAnX~R80h$I?n7U!*?J*jpQ(;c_AlZdMo{vlbBQ0f{uUm zANUL@^(8n;l_>)k;B^dI_*KPG zghBs@t^uWd9g?QVd8`M20`&c}9?RPeR7ylGIibpj!P=@hm!B>rLWoCzIJzI@YKffI zOGi!%m;9`nOlUvK)bigootfQ_5?HG{`KYjAB?Xr2j~KoY%&`$l&i;T1@~$* zssS@XU#eF1cYqI7Jv53L6-oK9{QUx&Y!2`5YZF%yemnpZ{V?9DNXQ<+^+P1A|J45b zkwU!Wz(7VY0DQP~Fw<`UHHI!9&Q!rwHdR;~=-Ou^XoxWAVc3SIqDeR8kX)*B7lE;Zx=5M%M zeysIO+o~Rd$+8#cLiu2VWcA6VoBGP1+s&TQ zale9Rbm{t+0f)_pH>=ubzrx@4XwQ-jkBwjDHhb)rG&zyCa)b7J@1xoSXLorNef62y zxFo&5$Cyv(JC;9UDM#;ByLXkJA{Xgee-ORVUOJu=w0pSArQy*R2OS)CEbpE|@b}$5 z-%dw-?B4sR|D1i#+y3mYJ2m<10&r?LrE|c}PdKFtGoqQ`D9Y0LjFU2KXa_rAC_!{e z9QcgF8K;OP%6kKVcVW*ML=I+_MNuMGF?=~C84i%?0X(kOl|FGR z=P#;f9y}vlWHgw5Iu9JM(iJ>Y(6EQ13`=m;kSZE;a|axm4gi;51~9DKAn znE-DvM~I}v$KeLNYiAB;jDMsLgldjBkv1WVqDw5*nJyX5Opk^0BemU`jj^!#a2j|a zWM5{0$qwYwoWMCWIHK_*sw^c>npolv=w7RMkICa$+d^Rp7?LI^Kk!sFgzqv){-ynh z@9i1iAyn%aBm(>*tw+ND(Rj3~vAOCyI4F~q-x07Ojaqmp6R=ie;5Dl(2)o~wIXHwe zr5oIst3#+L(^@yT5)LRMUt3J-+)yD!%ivT{Kpf@Z|Kp$$7bceZ={7V62FbT8Ck<|x z3D=VF#nq(NtqSg&N%)=(fafWj!??}zc}E=OYhUNa1EW;(0CisshN)H=zmtHm$ve~Owqyi zOw_8|@5c&;O!>SogOa(1+)5ujr2fH?J(GJcY{)Tn8*O1wlKvnuI_YlthbLy?t}9L! zbYGD$Mryil@B&%KK_~0teJzKKiQjl?>%*3MMem0^s<4UnzB}n>&n<28+&EA2lkvra zZDr`0-?_nyud26la2`ebLtCqJQ+jfcC97M_NN;#UH<>O5g@rH^JhIdnPBuk|tYVnG z@su|NB=9m;I`b`_3Y8sW1rCd_?p%>tNzqL=SFQNe5=Nt)35tplnA&j|i&BM$W0Z-W zAK_37SdXg>Ux`sU8Fzps@Z63|(|yq?WTCS#(U8F}&g^5AeYE$Jgt?rrxI#V5nbj*VC+Ao+Pbq6HcbqlKenJUHBp?IFDboRsD& z31bcpqbxhrIu&Lqwfh2j=2QjusNJv0bEl_pui_@mi%4`N5Nr&eMoVT|45!+e)`t5C zk@juih!DL}Sus$>d6cGwhF%JD&08Lm;M} zVfj4#e%dbm5tJ7-0Ecin{rll)e17!HGaj6-NymjYA?n#LS~c6ji&>fG@F^bk;c9jL zJjP`VW#)?LPQXNjLqd=f>G%T3_aD}u`Jw(yI`e!a$U4na}BikPr&6sD%WNhC3a{JUVkB*x}guP5Z|Dl7QY{Q9!;$<-% zcDGsGBXqXS+M5$aS<@V)x>@lhMgtD&4s;o`Jo}YS^x5~luN^$H$SSRKPlJ^!FIyf? zi|2G)c5U|QHV!*Ei{B>|bP8Gb+1_W!-*KLs?p#Vc?vP?(_wZ_3Pgk=G*V`v_8%0H> z`wcSJU+FTib?%OvL2<3O-JZovndLPjXwx6_t=-Pr)IDuke13#==bQ(9Z*FucDww%v z=+B<3Ta)Kf5IJboKeVG1IIEJqyqXv(o;2bGam64r_j}B<1-G)a=J# z{8*1Ke&BfV(>WOn1#BD3AHtK%=}hQ2O2memx4)+eSsvYnP!-;$lUo3O{LEl$5-vtu zm!TZ5*CFP{zBQrm)<5*Ejzl!T$>V1pkPfwzCw7=e_#PG^49rR$RUT7GxCVq5m(#1j z-86$vo@OWqq1=eCOUKQ7Wmu|b$2g1!Aq3emq2nn_gMvlzz@WHX4k%V_c)YMX<1~S4 z>t8bjrWK&^U-_~?$rnT53-S^5@>f(kEGlb6g_2c+AlmOeG7b|c2U~S_G#q!qdSnl> zt6-6!i83WRx@HKI2Tk+~7WqI*$(OBe2xo3ipq!mEnk0-flm=)39(SUJh@OyGfQ5KF zT*=LXMU2Np%3HGm2CYPGieLziV71@DcK!?|Krk%;Lzc2>TaXXTI&w9OC3cL@BnSd< zWsgZTjbv*{UHV-}{~AjY7i2?-YzPC3fGE5#e0ao2SgGLyT~ZPfAt=H5IQB|qg7?ST zOIh`H9Ssv(@?>AU)|fe5Z~1nYS5d1J<5`XEdNOWFLAs*Ps}2l2Z#00;a*FAs+2$@S zN^%ig{CvB7=D3`{ZI{X{-)j^tA5$N<#;)Ybz{oYcsI&8#`nK;EZ9lwsj;-Ok7UO;1 zmD}mNcYFA3+xZ)Xo7}Q)IvIuZ-Co{d=mgQzvqgVseVq}YMP;XK5!q@N?fJIEu;A48 z;T9nQg~xW^@mU*{`{J34wCaOk=EwxCx^c~1Td%r$yZ7zO2`?`0O1jl!#CF-p;77~i zE>5G0d&fYscGtIvLs(a-={a1`%nipZ*#x7)1%OU04JNYCm)onjsFMQ4A zRS84eeJza8c+vNPp~AI#ZvE6m!{FE6cdN3_```ZAGx{`n#%Mbw2RRYE66B;daI#JY z?8l55YBq^bZmj)y8URBRPK44W@Xc`*qedbqkq}yfC!$-a%w8?(%Wd(rfFFL^Wf=zd z+7X4UrSZ9aNHUK@z}0{SDlL+Uo=jQEa4GQ!TB)N3H+bC?9V)Ir{lU=j{x3L$15M#8 zwcpo3-&I-Zlr+GRWT+Cv{A4MyB*YMO)fLxGU@$CJtzIB=aB~I~02A9k=Zz$A zatb1FO*Y5LQF*9KPvvg8pl^I0?j900afJ2i3GE`RZoaVr1mesmKh8x{0jD?tKIjAW z%76l2*|cHS&!jALl{2uA)TA>v3gxP>b()@{{#^~D;Zo$pQb}eDmNr! z4etM)AL{)ZotCp94WHYWa0xScHl_a$^?n}z|K2Ozf49~xa+Trm?jz^O_Gs+sebCG) zGe{$UV?=}h$Nks8$mcHfIaJ`~TCl%k54%G_!4(g_uKD|e<8X`5TezkfUG^Rs@4wlH zPiD0-&Mfl1tugT4fCNR>xV4QLyU!K(yEls)Hmmcbt%Kh_)=7L~79E>AIBrIxqH>_w zp*(JfZ{=>y__0STPrla;JzYAl!a`>I{&9AYY+8ND)P^%#clKFRVe2VX?0YzQ|Dd#~ zX|p?qTrHVcY^ZVRxvkghi&vw97oN(=EbY5gbSy{K_FS;u@zaM=YtQ#z>ffc=jKzlw z7kD@~uZ{ZSiYK3w0Ix3jwF#?;*>QaMQlrC%9D0TJzA*K|tPzdJwhew7H_xPV?jz$_ z2{Oue+yc{_*Z|Md!JDrxee(0X=G!!{eRt%kO@8@*C2)S{YGMzm#D+i~-d!D_J~0w?kYSzqG^XjHhY` zYlT)CXolGFKLdGYb~0=`f1eZmShL3fABXk303Y4L_j=_V+6)5n`ld{SGGL`4ETl;s zJ4pCm1>ogC|8TffMHnmx)P32gI#b4$*+9Lm5e=UYs{uz8SAvA+E@H-~P_EXwP^aih z3(Kjvf^G1Rs-)dF!Bsgp=12-9h*NSmPp%vQcC6;^&t<>o?$0nv?*3c`i>83Nkf=pp zcZOZNEAt2Vd|maN1cAq8xW{Dd!%CfPLP%Yz)|EC^Kdr<<(EUXpj(N2~H(-=@Vc|F@Wg^)AU@JTDboR zrE31iP>T6Bk1~z;HQIGBpG)J^)(W;IF@pLz$`wMCEBGbK4f|zwVTPqq)(*eMxa)>~ zpG_b>WygnHtz5*Erok&@NsEMFE*Mh!WZ?JDG5v~TEQB%gVEu0e2|`TIVyc#~AJ=n( z51>W-FXCU}@7!iba5G9@_|Nz^p{W7JzeivoYFLOPO6S7{Q#BAx6D@ol1ylug*FZIr zo4g-vXhFTNPL(@+Xqxp2*P-49{Dj&^)W9?1gy)P^Lqgk~+}8cC9fO;#3^qM%wL~^r zRDE+_vFWsQmxHTDi9UPT4;$YnXue;|o{RhkPdo3*Es+&D@di9EZu8{C?G9nX-!?vN zwqGL$&!G$}L)W%#bK70-(0#+)=bV{yI5mCW3}@y{ zj$6BN&(0H$%ini5mVI6tv7qYs)*MG_=HBq3$(P5@uDX3^A7A&?y1w%#e^`Cz?tHDQ z&2^S;S#q#w?e#VC$L?1)EL@zqqx62_>%h|1MdufDFY!LdT?*xOI`(GW)lnC^joF;N zsMEkoZoiUQOSAfve0gHiFg^L_8PTt4MkF1ObIHmVwNQs@o8|yNNR859Ga8aQv{rZl zfsmoB2&xw`G3juo_R)9NLpewCXc4m{o$`o65uqzb5urO*&O@*bhoa_x7xg=U`%%W+tjo<%8V)yuxw(jP4x5PC`IR+IA59BZ`DOLNH`Qm`$lt01aeN*gzEtLbld!F4 zEUiq*7&dj!u$Pj&jDef^Wv%2{El$V#*QK1kL|Nm_iA3?IMv^l zS7#nbgZsd6N+%s2qq{R^%7+z5W&d|S@odponAe%@UCEc;nc&w2If=l8Vv z;5NE>q`B9X6|d8U1F9Fc?4%vu^Txv~2K(2}GYDwm{L$>rlUY?%WyIMv%n&!!r;r~{+w@1zogAQ&78ctv4*N_(e0Aqo4phCaf>3~ z`p@q&%jFbv{Gs=Vvj%=gt*%jyt`)<-u4uc}HadGtVs7fe^NqtZF_n?J*wr19XFTX9yi{=Be3t} z2hmx#bdvg5j`;mw%jiKL{yu-svelQb>(}LO@Go8RX`S*fa;^T~Z+eZC?fT%nX<3@9 z)wvey4<4*Z8lN*t$3FXW%<3hEx5HSRvfrTA?z-cBn=>Mdw+fRrlk>X=bbF~rduB~> zwRm9uZM{{aJ8!waZt;adIg)3gf)*bR{XK*h8##>S9-L*Gms;-7@b_Og?wx(H`;Yt6 z3VQO=r2%O>>>JEw`##N=myHeR-r}8P zb7s&sySH;a^8Z#e# zQ%?_Ebg6rCpxB&~t21O`s_sxb?LQ|!F6P`c($Sl!9`?U;^V0F1amdX#y{KMZQ#vm) z>b~~jHvcYn2Q-G=PoF;~)+g;{uVuOEi7jN)^QP2ZK3pg?G8m>t`|sTJZkXzkHP)ov z-P1g3PvpD$(7MgtgctjJo7BGhcs_gjm5fxgy#x1MTF^s!J*0L^x82@rCk^hhbn_oe zgM;)Ei`>sko!6N^T(l^uW;i`P)N_4eWuj~2-jmng_1SXO(DUB@(B>`Hewt??n6DXo zt8LGpxf#^N&0V)knl$oV8S+rz(86<{$^CmVU;O!FvfDl1@!8qg^ZK;2G0&X0JWtKv z@=c3-BW3%>*s?j3UtJiOX=N`Tu%|jzIoyBeVZ*>S2B*h3+|8Z8z(u;e&%Uxbq2q^~ z41CRRxVWm#=N{$TwQcTnDp)$zM)qRUfxWF0nw{7f^|{|wCE9=I;os)F{n~2x5^s3^ z*Ws1B-n?70X~WmSZF)-zPVX5!;6=w#-+U`ixV$8hI-Rakt{3->7`atH{6*Aj_o&BV zK@XRg4BfwBaMyPYNrwH`c~1MB$E_Gq?Ygt0eyg1pvgqA^Z7HHFS9Hr>F>kME;Oys9 z%zox!_a+`TdB(_QOwCd%QRb(ayj`t^sETS`_)o6?&cY~%=JjedL{>N9qIim9mt@7U)E>Y~+cMcCNZ_?ON8%j>QDJJOreZx#D@BuriQ>-Bux%#Vws`g&i-xjVoPMI3N-*;o#`&}Gab!l z&(ZVWw`YKRu4c#qiSqBs`Yt(v?Zl7Pc`Zz>@p2#iux-M0yVQiY7iNWY7`i3y(TXEo zH?_8SUP;#7v3#c~-q+#JVa+o-&Nf*W6ZK?JnC|OF+eIUyg-lHTs>XKX&&PIsz0H-k zdUA1}0sEidw_iHwqu=;IJ94!5!Jb{*58?mRLj5Cz4sT-QuEY~)&v%iBsi%>L`dgkl z5Al55uP9|?j%oB6r-7F`#@@Vk!Yk`;*w{zb;@10%to+5?8*2*_h=~r0kEk3*HSCEK=??#$pX|AR^>%YP_wWy4cJ={6bk}>w^EZKNIZ9BQ9 z;oB2qavYxMNU>8DQPU9^6!@a_iUlX;ZOAKu#)KJsw_9=qut3E?=0Q@SHk@){Gh?NB zdjm7JIFXH;iuC7?${gKAJ89bGj%VGH+4pO1_@8)F?XhyF?|%B^97VW}Q){4FvAy+oUQZ1_EaL8ilWX8&L3 zb=>#Q!Uk2#bvgrUQn^*M6_P*qDT@yA^we;F#l>rC71J6KP>Xz=L-TZYv6m4QZ+3ZI zTqaHW{_n8=ENp6xjOLE+jTQS{{YdNcG2fI*DBw;7VPq_!LEkS7BWeta-t5(tl9h3H zc+ds1_uIlBjv7yo@4nLot&B9Ny3*8DkLNJqU$mQbok|qE!r^h{j$oN>qM=sNDx@U^ zjf47R6_vmTqiYyCO2tE*O*;L*k`80p0^G6fWEMn#$?pNtVhP7j$8q5pND<381)9Y} zC9Ejjo$evCtP83mP}hArez+-CBY9=fk2S_!FN!=u(&c={qwVZk?Ixsrl3g}am;ZRL zRa@+f_ooK_St+)3fXTA|vBu1iBfOkMx#D`)hmLAR71G%CF+`!FI;S1ey-z8*>%9CZ zP+{opH$sJs40rkkUQ!7c1V)_O+nWa)o&Up&H z;QGjh=*m-`UDkm=j(Pj^YmhlZ*mKSv@$|Dw4gOM!J)ApD%RlEr>c!KvY<6jVJl%6z z;D7QXJ8tiYxQcC3sgX$%yq+%;R#^9N=26O|UY?Gb|_;ZRB%Wfo6a_8>HUPX?U_xkSLhJ~(KBoho@;Ng)M9W z8RKHt)RBILrl;1xJs!Sglq-UTE0n-+}h$bPd%{adF3xti3o4vl_0)Y$+WCheRK z=|Mrl*_MP(YY}UKQcqOOYx< zNSBC)dalt!n>Wt5(LV}zLheXrJKFGRmY1G=^6^7G70uiq<%7+D@m-vpAyWA(qfY&g ztM~WPL8Q7%;M%6Aa@?VodA_YF%6jiyX5&$&T_Pkb^HTjDk>FopcTXgHWT#lPz;#P% z`$1NT6#T!!n!l%dKNuHgG)whxVv43KHP18mk^R2oD~}hY?%JbE4mfroB~UFtn}l(^ z@Q$!&@gwt(Lf<}2Pri%x>QG@LPatN*WWt!;bHDf%&bz{%S&Zfij_u$PZhAk@ygMbR zzZgkh-BJZBPX2Zdw=V_hFMmN7Xdd&t9bz8yc}6JA~Yp9-g0(qX;%dlw158+JOS z6f-Wf<4(}SFzp7&<3X2f5uT8mG@YPGNn9<|E}aQ#r}y=`$hD?}pJD%5q3K4&hPpJm4}!&98}WYLsXLeo`D`I#Zk!(=e3E2 z*WYN|!J$MPsELOAga!pb=1Z{3*Zm0l&kDO{i8?4;*haqfMG`1E20u)tFom}xLre`wWqVeLU(Mxx~^Hi zbbpqG^Z@Z$-K6GKD3@S=-p! z*`GF8AqAn6DE~dOIU7h`s0{OqIAls~T8xqOu1l^{wpF1+iC06qZqoIH8`8VdyVP?s zw<6m92I|iZqIvex@lw364tU`wc#1cJt(noXYen|uoIs5&V-xaf@Dl+;7FMz}T}ZkGLR zhOqjpZ*rkO?V|pL<{AnRnx5=zcMJht^q<>ies-BH5HF4#;MWTP>!ZN&r`_rHA2G^+ z{ij`xSz`xxp_sTq=%If}BG4|4>)*Hkd)%u3ejQvi6E{YJ1H6hgz6h4XLuGJPu8}-3 z@ugE^K(-~SSC-f-;9u{HUr}`*F|u>@J!c+o20WJjrM?okLufFpLvrAY;}FJ?;t4;h z@p1AFwEPR5g8#)P4DVH9@d<$*jI8#w;)P2cPLh-$p*?Y0zI)p1@MC;vhISs4O6O$Iwv-8DG+@hm)a1=L<-n$- zX?6jd>?N(wTrgsNZ?1ueVs+l?2PsZ^y*vV0qMNB9A;fYw`FcjcAe zo(J;KKSa7@=f>UmCx8dL;URy$uKHgY6ku{%d18#A2dh@qU*2(-RQQm+HU~x&A z&e>i_)?@EhR<2t}QO(s;DuR?1_`^>+efZ=zHvI;j>N zj8{5dr1Hnld}(g99hFQWi21~8!T2oe_S!_`!Dy;W`JoxgkjeKXZ1L!+#gZY8`P0Pw z#Oq(%T+39uI$jc}!&%Di9;8IXNzWPHUF=^=;II_p<{u#xV|wMS<*$tAw;alcy=EO! zokDe`UrSWYSBwttH4dJIIJMI`8b$9uyVS=I!+SNTj?ptpiVV?ay+VG=@Gy-1cgowkxg=oUB zB#pt(Bfg8zMr?tmVLS-klwNEn?PW`e#drZGgq3+ThEee z2gZ|FG;UtmCb&_#qsvBuV{gGRHDh(>{rhQ>7?Sq)zwLXC8veGT!MNe$weYZ~)2)Gw(H!R;-F zd+qd!rR_nAAKRUyzO}oR#ka?5N4dmp$sIXnWE>r2=pG4V9W0vbr!S7`doCX8bNUDB zyZeLnmHp4@C!ze$>pS_+>!ao$>0h50)X$suC`cpF8h0Q_97kZ8$0M&Vt0GouX8oT{YlhsrN0@e8+$)lXo|FtdCsD zoJog>I0lB=mqN3lL1NvGEW>=rmEC7Y0hFu?GwCwlC&>hz93?Uqt0L8$lIzy!+0xQq znN(aa9`l-C#+=o6^S8c2n^S#-4yXF$-bj;w<_%2d%mSeErC*lTNl6wKQCQ(c+$ z_qt4L1>az6sRVLsvz1+IEBGU13S0mw4nNS6ho@?x;hkE(V{ZptuGDR>T6Pl2?o1%- z4ClW(5sTae4e#S>Ra%B$EoAfKMc%+&hQ!Pm#~RlQk-Qw3II@xbq9(Jl9u+g)HZhR? zC4e^XiM;!z0)^M=qj5OJ=iRT%Cv+*^*k-~ppyg-B-BjM6IycwB5+v`6S-S_O$BsIm zx*Bymb#>EyfHJAPh?%*(o;km~X9tG7k@p_?HO~u~k++Xrk}5PS*|cwDN@^=-eyF!mMAiE% zN_3`8<#vAFyxmD(p3zy2E7^Jf$g;C6^&WjE?0W^>J8Z`kv~0da%PiRiD|S zSdVVuu1B<7x0SPAw|!?FWGig#uk2}Euk2=hK{?$zK>5kxrt-x@q%xfKvGU6BlCt{n zxN@6olyZ^l)J;2AQCAz+Tvrm;U00pBZr8-XO$rWqMqwHGJYjNqRpAk9COZl1RyzXg zHM_fVX?C@8-|YnCpmtd(xq)M8x$@&kxg@qf8gzRKcHX=nNkc0jhOv*cBJ08il z$w?=|Q%J`yd?Bs55KP*AL6UUu0uO2Jg=?gRVF9GNVF#qmDVqCIDF#7LQh0(UIZA?z zIRb)8zfJ{JacKv2b72Vw-2dq7DSq9zR_xX%SKJjiMq(bQN1_wBNy5$8M#91?ILoEF<|8lt}^(@*(lI8a>Ifng|A2{Smx4*c^-;Tn?^btPgISW)EhXrV3F@ z{Db7#+h(*q>CGT@YlstWC!ZJgPK4ZwrXY9DRI-NK+StZ|CfRD~v&f6O)?Kg}q9>7u za^z^rT#*y?yI!_w!5^Z{d!(OY56Q`9zzdcFDe;45Y_oco{4z2Gp`6p#c|PwI;vNv( zH()xe&;6G^tV0BN5RAPUeQM7L{7Qa%CeE;FrpYj6hMP4_?hC8FoIIa zhXJw6QGxvA20?aHw?UFBIUrUR576=!AIKnT611%Of_FjFjdxD-4NrvTJkMoK6`oHO zy}ZKC>~uCd8g#xoZ|OcFzNk_nBvoG^(p4WInpL$Rd#WXnK-C>c6iQVa0-30RcqyAe z+?jG9+FLUaw#YfivBFipc?EI44+_VeFBH-^i51*AeH&08VmVWC7zg@9EK6GRGUWzn z&h3>p((C)F6^^fkN(3Z8BK1`B-04L`ApY02o*!Fm58353&%){J^xMY5-+o+=u1=KA zo;uvJb!V1|4G7$)SzImqPyYOa@%{&clK$)x4ba3^DD+vY8#J?37wT@B2t6_FfFez|p#`R`Q2Q1Z z=z2>A^!3!aH>OisZ;Gda%4s#L%jc|&%dJ>>%NbmV%8y-=%Lhqy8DnGbOqa(-O$)}p z7R{wIZqK0;Z~sQe*}hM=Y%xzqW$~Gg!(stNcg13i?sCTsx}uI*Ix7y3)&q`?Rw<5? zrv4hSrp3pEO&KGVP57y?O;V{GP2`8^9y~q*oq=zteXxeGufb#u*SNQ8_|Zy3`mL{m z?01n@L)Nkaga{pT5lLVA_*Fab%~-L}dxN^u5c$or#>Y0+WnZ(mZEh;yG3V&*4Aoa~ zP54M>-55E9EFvr(zCM1NeFYroO-U(<_xbRwKF@flH0Ce`T!V@RZYB}}-~-?WU<&~J zSB}04AO|1@zze_%Ko39)06e%9y#}xXFat33bGZws8vx1xa(`|+ZS#wy|5*OH4TkOk z0yYCw0Tcpc0we z!_uBgKgpG7 zb^T-9P&{-TK}^=T;T3=s7@_=hZK9H3ufd9_=$$^(+Y60X1q{nY`i#${1n?t~)2~yW zVyp*2I|EFZLeLE+5VVvb1bwK7B`*Xo5g_bzEg%9o5BaX*Z1W8;A^A>(#KjqeYI#PS zg*mE;OL&IZ{W*?>Fc-?e{0PZS_tIpXkwI4+zQNGB<-w`sFSUfpUrKUCkfsmxM@pPM z(53;&7*C)riXav_GMsfYHXJgu zSe)DKyHUyQu~FP2_)!9)(*rL$i$V77m?5AoD)aJz!fRUFla94ar6yyCD}EN)$YI%X z?j$}EfA(wdA>!90WVpxd6U-1?U3px*A-bg3K#~nAi>9ipx}gq2y!5yg80wY+X!F#G zqKnLVf#EL>f<}(Jm+~Qj_$_{0+LG_^!B&bA87$PiXFoH?#r;!4a4R4I1i@-+;sVz| z@P5|#KWl=YHQ~>i=x0swv!?t}hnutD0zd%p0Pq0_00;qy0Ehud07wDI0LTHL02Ba} z0OtUx0H^_I0B8Z|0O$c20L}w20x$tE16%-L0bm7y0k8qE1Hb_|01#MnmWyy(Y|tAH OULuel78QIEM)ZG09}yM+ delta 35191 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 diff --git a/ovl-upload.c b/ovl-upload.c index 65fd674..b53193b 100644 --- a/ovl-upload.c +++ b/ovl-upload.c @@ -110,7 +110,7 @@ char * ptrToChar[8]; // Will hold the name of the file to load. volatile u_char loadFileID = 0; // Will hold an ID that's unique for each file. -u_char overlayFileID, loadFileIDwas; +u_char overlayFileID = 0, loadFileIDwas = 0; // Timer for the pad @@ -124,6 +124,8 @@ u_char protocol = 1; // Hypothetical ID number for the pcdrv protocol in u_char command = LOAD; // We're loading the data here +uint32_t checkSum = 0; + // Prototypes void init(void); @@ -334,9 +336,9 @@ int main() { // We send the memory address where the file should be loaded, the memory address of the loadFileID, so that the screen is updated when it changes, and the file id. // format : 00(:)01(:)06(:)04 xx xx xx xx(:)04 xx xx xx xx(:)01 (separators are not send) // 14 bytes - + PCload( &load_all_overlays_here, &loadFileID, overlayFileID ); - + #ifdef USECD // We can do that because we only have two files @@ -429,15 +431,12 @@ int main() { nextpri += sizeof(DR_MODE); + FntPrint("Hello overlay!\n"); #ifndef USECD - //~ u_int cmdChecksum = 8 + ptrChecksum(&load_all_overlays_here) + - //~ 8 + ptrChecksum((u_long *)&loadFileID) + - //~ overlayFileID; - - FntPrint("Overlay with id %d loaded at 0x%08x", overlayFileID, &load_all_overlays_here ); + FntPrint("Overlay with id %d loaded at 0x%08x\n%x", overlayFileID, &load_all_overlays_here, &overlayFileID ); #endif diff --git a/ovl-upload.ps-exe b/ovl-upload.ps-exe index 5985912a40c804ad2b7d6e39ac2185d1f217eead..4c252297ca0cf7da1420b45a03868cf209dd0298 100755 GIT binary patch delta 12803 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 diff --git a/ovl-upload.py b/ovl-upload.py index 725bf4e..8ccae06 100755 --- a/ovl-upload.py +++ b/ovl-upload.py @@ -25,7 +25,6 @@ import serial import time import calendar import math -import signal DEBUG = 1 @@ -100,12 +99,6 @@ Transfer = 0 sleepTime = 0.08 # Seems like safe minimum -def sig_interrupt_handler(signal, frame): - - global Run - - Run = False - def setDEBG(): global sleepTime, ser, uniDebugMode @@ -126,6 +119,19 @@ def setDEBG(): uniDebugMode = 1 +# stole it here : https://gist.github.com/amakukha/7854a3e910cb5866b53bf4b2af1af968 +# TODO : fixit to have the same results as https://github.com/grumpycoders/pcsx-redux/blob/main/src/mips/common/util/djbhash.h + +def hash_djb2(s): + + hash = 5381 + + for x in s: + + hash = ((( hash << 5) + hash) ^ x) & 0xFFFFFFFF + + return hash + def WaitForResponse( expectedAnswer ): # Get incoming data from the serial port in a rolling buffer @@ -498,166 +504,151 @@ def main(args): if inputBuffer: # We're expecting the command with format : 00 01 06 08 xx xx xx xx 08 xx xx xx xx 01 xx xx (16 bytes) - - # Rolling buffer - - # ~ byte = ser.read(1) - - # Make sure byte value is < 128 so that it can be decoded to ascii - - # ~ if byte[0] < 128: - - # ~ inputBuffer += byte.decode('ascii') - - # ~ else: - # ~ inputBuffer += '.' - - if len(inputBuffer) >= 32: + if len(inputBuffer) == 38: if DEBUG: - print( "Incoming data : " + inputBuffer ) + print( "Incoming data : " + inputBuffer ) - # If inputBuffer is > 32, remove first char + # Get the checksum and remove it from the buffer - # ~ if len(inputBuffer) > 32: - - # ~ inputBuffer = inputBuffer[1:] - - # Parse command + CmdCheckSum = inputBuffer[-10:] - if inputBuffer[:2] == pcdrvEscape: + if DEBUG: + + print( "Received ChkSm: " + CmdCheckSum ) - if DEBUG: + # Remove checksum from data + + inputBuffer = inputBuffer[:28] + + dataCheckSum = hash_djb2(bytes(inputBuffer, 'ascii')) + + if DEBUG: + + print( "Computed ChkSm: " + str(dataCheckSum) ) + + # Not using the checksum for now + + # ~ dataCheckSum = 0 + + # ~ CmdCheckSum = 0 + + # Check + + if int(dataCheckSum) == int(CmdCheckSum): - print( "Received Escape : " + inputBuffer[:2] ) + # Parse command - # Escape byte received, remove it from buffer and continue - - inputBuffer = inputBuffer[2:] - - if inputBuffer[:2] == pcdrvProtocol: + if inputBuffer[:2] == pcdrvEscape: if DEBUG: - - print( "Received Proto: " + inputBuffer[:2] ) - # Protocol byte is pcdrv (01), remove it from buffer and continue + print( "Received Escape : " + inputBuffer[:2] ) + + # Escape byte received, remove it from buffer and continue inputBuffer = inputBuffer[2:] - if inputBuffer[:2] == pcdrvCommand: - - if DEBUG: + if inputBuffer[:2] == pcdrvProtocol: - print( "Received Cmd: " + inputBuffer[:2] ) - - # Command byte is valid (06), remove it from buffer and continue + if DEBUG: + + print( "Received Proto: " + inputBuffer[:2] ) + + # Protocol byte is pcdrv (01), remove it from buffer and continue inputBuffer = inputBuffer[2:] - - # Get 2 checksum bytes in buffer - CmdCheckSum = inputBuffer[-4:] - - if DEBUG: - - print( "Received ChkSm: " + CmdCheckSum ) - - # Calculate checksum on the data - 2 checksum bytes - - dataInBuffer = inputBuffer[:-4] - - if DEBUG: - - print( "Data in buffer: " + dataInBuffer ) - - # TODO find a way to calc command checksum in ovl-upload.c ( see l.440 ) - - # ~ work = dataInBuffer - - # ~ for c in dataInBuffer: + if inputBuffer[:2] == pcdrvCommand: + + if DEBUG: - # ~ dataCheckSum += int(c, 16) + print( "Received Cmd: " + inputBuffer[:2] ) + + # Command byte is valid (06), remove it from buffer and continue - # ~ if DEBUG: - - # ~ print( "Generated ChkSm: " + str(dataCheckSum) ) - - # Not using the checksum for now - - dataCheckSum = 0 - - CmdCheckSum = 0 - - # Check - - if int(dataCheckSum) == int(CmdCheckSum): - - dataLen = 0 + inputBuffer = inputBuffer[2:] - # Get data length byte - - dataLen = dataInBuffer[:2] - - dataInBuffer = dataInBuffer[2:] - - # Get actual data - - for b in dataInBuffer : - - if len(memAddr) < int(dataLen) : - - memAddr += b - - # Remove data from buffer - - dataInBuffer = dataInBuffer[int(dataLen):] - - if DEBUG > 1: - - print( "Data in buffer 1: " + dataInBuffer ) - - dataLen = 0 - - dataLen = dataInBuffer[:2] - - dataInBuffer = dataInBuffer[2:] - - # Get actual data - - for b in dataInBuffer : - - if len(flagAddr) < int(dataLen) : - - flagAddr += b - - # Remove data from buffer - - dataInBuffer = dataInBuffer[int(dataLen):] - - if DEBUG > 1: - - print( "Data in buffer 2: " + dataInBuffer ) - - # We should only have two bytes remaining - - if len(dataInBuffer) == 2: - - loadFile = int(dataInBuffer) + dataInBuffer = inputBuffer if DEBUG: - - print( memAddr + " - " + flagAddr + " - " + str(loadFile) ) + + print( "Data in buffer: " + dataInBuffer ) + + dataLen = 0 + + # Get data length byte + + dataLen = dataInBuffer[:2] + + dataInBuffer = dataInBuffer[2:] + + # Get actual data + + for b in dataInBuffer : + + if len(memAddr) < int(dataLen) : + + memAddr += b + + # Remove data from buffer + + dataInBuffer = dataInBuffer[int(dataLen):] + + if DEBUG > 1: + + print( "Data in buffer 1: " + dataInBuffer ) + + dataLen = 0 + + dataLen = dataInBuffer[:2] + + dataInBuffer = dataInBuffer[2:] + + # Get actual data + + for b in dataInBuffer : + + if len(flagAddr) < int(dataLen) : + + flagAddr += b + + # Remove data from buffer + + dataInBuffer = dataInBuffer[int(dataLen):] + + if DEBUG > 1: + + print( "Data in buffer 2: " + dataInBuffer ) + + # We should only have two bytes remaining + + if len(dataInBuffer) == 2: + + loadFile = int(dataInBuffer) + + if DEBUG: + + print( memAddr + " - " + flagAddr + " - " + str(loadFile) ) - ser.reset_input_buffer() + ser.reset_input_buffer() + + inputBuffer = "" + + Listen = 0 + + break + else: - inputBuffer = "" - - Listen = 0 - - break + print("Command checksum not matching ! Aborting...") + + ser.reset_input_buffer() + + inputBuffer = "" + + break else: diff --git a/pcdrv.c b/pcdrv.c index a2f5a7e..0d76655 100644 --- a/pcdrv.c +++ b/pcdrv.c @@ -1,6 +1,6 @@ #include "pcdrv.h" -int ptrChecksum( u_long * pointer ){ +int doChecksum( u_long * pointer ){ u_int checksum = 0; @@ -8,7 +8,7 @@ int ptrChecksum( u_long * pointer ){ work = ( u_long ) pointer - 0x80000000 ; - while( work != 0 ){ + while( work != 0 ){ checksum += work % 10; @@ -19,12 +19,25 @@ int ptrChecksum( u_long * pointer ){ }; +// Hashing algorythm from @nicolasnoble : https://github.com/grumpycoders/pcsx-redux/blob/main/src/mips/common/util/djbhash.h + +static inline uint32_t djbProcess(uint32_t hash, const char str[], unsigned n) { + + return n ? djbProcess ( ( ( hash << 5 ) + hash ) ^ str[0], str + 1, n - 1) : hash; +} + +static inline uint32_t djbHash( const char* str, unsigned n ){ + + return djbProcess( 5381, str, n); + +}; + int waitForSIODone( int * flag ){ // This should wait for a signal from the SIO to tell when it's done // Returns val < 0 if wrong - uint timeOut = 1000; + uint16_t timeOut = 1000; char result = 0; @@ -51,8 +64,14 @@ void PCload( u_long * loadAddress, volatile u_char * flagAddress, u_char overlay u_char protocol = 1; // Hypothetical protocol indicator for unirom - u_char cmdChecksum = 0; // Not using that yet, ideally, should allow to check that the received command on the pc is the same as the one sent by the psx + //~ u_char cmdChecksum = 0; // Not using that yet, ideally, should allow to check that the received command on the pc is the same as the one sent by the psx - printf("%02u%02u%02u08%08x08%08x%02u%04u", escape, protocol, LOAD, loadAddress, flagAddress, overlayFileID, cmdChecksum); + char commandBuffer[28]; + + sprintf(commandBuffer, "%02u%02u%02u08%08x08%08x%02u", escape, protocol, LOAD, loadAddress, flagAddress, overlayFileID); + + u_int cmdChecksum = djbHash(commandBuffer, 28); + + printf("%s%10u", commandBuffer, cmdChecksum); }; diff --git a/pcdrv.h b/pcdrv.h index 1f2beab..b9d22f8 100644 --- a/pcdrv.h +++ b/pcdrv.h @@ -1,7 +1,24 @@ +// https://discord.com/channels/642647820683444236/646765703143227394/836663602718048297 +// 28-04-2021 - @nicolasnoble: +// +// step 0 : have a protocol that can handle open / close / seek / read / write +// +// step 1 : have an unhandled exception handler installed in the kernel to capture the pcdrv functions; that sounds scary, but it's extremely straightforward (I think @sickle currently has one for his debugger) +// +// step 1.5: implement the pcopen / pcclose / pcread / pcwrite / pcseek functions, which are basically the same model as my syscalls.h file +// +// step 2 : implement the unhandler exception handler in a way that properly redirects the calls to the step 0 protocol, and returns gracefully to the caller when done - that can be a bit tricky, but it's totally doable +// this step requires understanding the ReturnFromException mechanism basically which, to be fair, is sort of understandable from this one file: +// https://github.com/grumpycoders/pcsx-redux/blob/main/src/mips/openbios/handlers/syscall.c +// you can see the syscall_unresolvedException() call at the bottom , this just needs to follow the same pattern +// and break down the caller, modify the current thread's registers, and return to the caller +// at this point, we have a working basic pcdrv feature, using pcopen / pcclose / pcread / pcwrite / pcseek +// +// step 3 : add a kernel driver for "pcdrv:" that just piggy backs on pc* functions so that people can simply do a int file = open("pcdrv:blah.txt", O_RDONLY); +// (and thus support things like CSOTN technically) +// // https://discord.com/channels/642647820683444236/646765703143227394/837416216640618558 - // So like we'd have, say, - // 00 01 00 03 58 58 58 01 xx for pcdrv' file open to open the file name "XXX" and attribute 1 // (escape) (pcdrv command) (pcdrv open) (filename with length as prefix) (attributes) (checksum) @@ -10,6 +27,7 @@ #pragma once #include +#include #include @@ -23,7 +41,11 @@ #define CREATE 5 #define LOAD 6 -int ptrChecksum( u_long * pointer ); +static inline uint32_t djbHash( const char* str, unsigned n ); + +static inline uint32_t djbProcess(uint32_t hash, const char str[], unsigned n); + +int doChecksum( u_long * pointer ); int waitForSIODone( int * flag );