From 56d9b67c34be35bec69f3325e2d0f1ce88046d91 Mon Sep 17 00:00:00 2001 From: Svjatoslav Agejenko Date: Mon, 4 Aug 2025 23:13:22 +0300 Subject: [PATCH] Document TSR communication driver --- .../LPT communication driver/diagram.png | Bin 0 -> 44416 bytes .../LPT communication driver/index.html | 606 ++++++++++++++++++ Networking/LPT communication driver/index.org | 199 +++++- Tools/Update web site | 1 + index.org | 6 + 5 files changed, 791 insertions(+), 21 deletions(-) create mode 100644 Networking/LPT communication driver/diagram.png create mode 100644 Networking/LPT communication driver/index.html diff --git a/Networking/LPT communication driver/diagram.png b/Networking/LPT communication driver/diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..baf5beeff97d61951f08b20f05c6798b55141d41 GIT binary patch literal 44416 zcmce;2{hMl+dcZNR1~3zQ07cYluVgrPKYQ|MKXktc`719=Ao1lA+wZut|UsCQ^rgY znJO9M?9cPQ&-<*i&TqZzoORavKf_w$JKUdpxUPNey{|h&TT6v%2h$D`iA1HQs-#OI zZ80E`Ht~>e!*5Rdl{4ZW0oIC&+G>i5Y}cF|EUm9zCXslfeWImRU(2z)F*DK#)1y1Y zI~)T6RFW;Oq*lr+Cvqo}cNTM@I ztKZ-b+$(&5WpSjx`fa~d-C(Xr*AF#Pw&lJ=J>AAJgTPjSSL7GSCOW@5zn8e(IoFV&3IjYSSA1c;abPT z5L z9lAupLDrc0#Gn6Ay>*wWaCFMwwA+65^I@YgP5PTS-)^?iW|#1tlU?f1JC}6-dMt+; z+tQ_8R&zNk1}o94tE-<&jCka}?kj7TTtC0(-e0cjwzf+uavR65Irg`WN`H0Q&gk3D zt>~0SI^|bLUX|P?Hg@x+(POs{(|OgA9oyM7Owt{01SnppQu;D=V0M?=;-A?>S3g<4 zH%=iFT+0Dim2H+;OHvD?e7f4L4l>i#u% zLehD5=22q#QRi<1iL^AdH-#G*&F=^|d^XYL{Geo z_)#nWzh8DIR^Y$>#yBz>`rj`TFTeEvc!#6YoB!p5|MQOj^@IOuDF5`q|1^|;_~8HV z&zK{mSG&G4Rp24~Y*GI5Wo}(v-Ke{Fd6u`3L`6k2Gxhu)4t?)<+W78WO!m`^jBTQ# z#gc!6Ru^YSCcAP}wX}jlLwEdMSQtwcqBU>k=qP;M#bt2G#KXg*vAH>}(`)%B zcTsV%?VW|exutpYJFKz?wr$(?tfXWcNl8V;yy4D1tM2^$_mA71pK38KwxQp3-~_pY z!z|PL_=JSv`H{CVmwyhw*=c2Cqrgk|>A^I<>@eMql>Gd|XYALO=2g|z{a?Ir4zNnb znBL}_RDK;B<1Wq{9UXmKR758!Dd{wo{`Bd{mls!f`T6}HJu=O!U2KZwVLWO{iD9-? zxJ+%RT`ey!FT4JIw|!sP&A2!^D_h&{@1@U6V`F0ja&r%z@LMXjDkO)8hiT~O$e5X#8JU?kY-<-j7n&PZdy0B{d$0d8-(|ibdFhAr z{O|8)HnaVDnw6#2U+MOgiut&$k(_Mv^XJb~U8X+i=<9b$g)g+GDALi; z$Sp4~@93r_Clje{Yi*6PY`!NiWL6UwcT_|q_2TQGuAJk0Sy@kS+O&y|mR2XnQ$j+b zGfizzPmy(O=XDJYjm>hW9vn}9{#+!{vn5%UM^I33vs{0LOHPM_@6sImrpF6Y-L=2Q zq8~lddVQOk2Tzjd(o^Z?P~o{?6EHA7(_0$3dGqGXw6rwSwMVCA{}%Q9&Cbc0^85MV z(xpqhY-~5|`zsb2o~x;;anX=lEzJ#yCQJ?1%2EU>ylZYw+ry(pLz2Wi)%sR-b#=w} zv>g3YL*wMxG$1xJGjmVYPbQcgqf+tqKC!+uLQS@H>&5p8g5q9(4ryv?T1@`^`CjOV zh={_;lUv(6ItqPOU7H_DF}!*6#<0qLp1D?xpMQt6=kK~qohKI@9H>d3UtFO+TVNXg zGGO~iPq8fxIhn3YRaMmy*B^#i)_WAR%W_+O9i=2Yu<+l$HZ1r2(+Gqs~ z^2tbP>FF28KRz@pwcr2fgopo@?Yl@M*Xf?EoSaWQi;bO~ooRRP-i(zlD=XtQb{KmX zPqQPCQOrK6xvC+YnNv!N`RVE8pycG_&ML**yHavX zvdSjhH`Ugb!@zN-(^?m0aU5rUrzqauP0A9uJNzgI(WzU))Ul=OO&CLZ#%xb<7^yXm z?@U_8_}G{Z*8Z}kCI9c`lP6F9o*Pp1oF5MC{C%b6(ZBw3!a7Xk_G5{IWXs zQBL4a2K7^?)zsLdRh0ydO5(D9jW+Ee{_gMZFXrp3uTP(zk)f-uzJr!l(6s6vNpH0> zXR3U%yCAu zekZRpE&B5E@(&XtZ{OaIZ&?|MlpXyjBqa3o*|Q_%9eeid;p65GtEr{b z*Vl{rGSKQ+Tk~;a^jcb4554ja$arUJd(2n3`}8)ov=lf#h;jSj@p~e=@6o*Z+la30 zE7prM{bV(KYjX>=i42_twDaHQ@eWOvQvCgk|rtBZ)06a zsp#VCZO=wetgNIJ6r6sl^)TDT>7>#z zn@-*=yN;fo`^u3A1QU}J5|r_ZB1D1n&o11wC`;1jO(WucQrTWQy4HKb=Bg$pCcB?J zeE6_Astp@0s-{MUo1437?ckOzTkcDH9jElL+~%7%B3L9i#LCYXUfO!j&`{Mb@}ZPl#>9kGU`)=P zJCrM51E^KGcB@UgO?Ikf)SM7=7~mouvub4v?6t+7#sG+iIpZtB57AeiKSB5+Z-` zBKxU_lJVECU+219TwH8DQ01Ydbj)c~wY+yDr?)%f)PuAd4aBT(mG9oaS2Ht9{??Lw z8tE*){)o$D=Z2b7SA~l$la%WryD!fJDJdz*NmTnK^_+%?d~i!4WmHT`LZa#Fp578W zP9Gni3gm4MFE5QhX2fi}&6=u}BfY97Bu7Lnn|?KjZ0HVR8QY^<%`( zw|DJNlbOBE>dS_2PaH{$kEdT=TAHIE_bQk(3A$5#sXmyNbOTG&ZJ3{(z2kwHgR-Zm zB;dfnq!cFy2ixwD)*2tLL=S}ZfCmqlE8J!yPRlHlUA%bFVZS-?MP>AJEnDbtR&F1? z^6@M3fw=n|TXuH#*QqH1zMX5ojzm;doya|3yyLErSwqBrscYYw_mx#tY$nCT#?CK~ zCyyZim-+sc{PW{Wz>gnS-90?mWo2tW)gG0RIZ*AjsI08K?ay@Y?Wyhp^X`0;GUxGK zCr+H0`#JXBtz_W+`}ar+TcxF?ffxEJ-Kc$5|GdHJo&VJ$O8~xmVh#rge1_%IJ9}1r za_`=~9PI3y5VY%;=0|9mm_oa93lNgom!d$$r@mamLzUDzjMs{KK&-CX~hrt}qy>lXk> z0q1iUtIVC@;Y*Z^M@SfYY@8q;pS-E*BfaKJ!`pL7aN)j(@ zDEpW!OAXv{9kHO{V$$ZDr0vuP;xv29oq6sbv(~j+)zH#vD6;OLIdC9?Sz#`<6P z`QfeGC>d`c7Bl&EAR)FsJgOZIm9A8dj*hy&4x827Au5X4(=s~~CB97el2s@xJ-^@1wcBRHa@xhYy8;7S7e*zZr;3!V0o#Yd^b7S_0>OiSu19~ z%iNnDV;iVuczAlgtLOc5IB07^LP9$tgc=)-_SC05Zi59gzsGNo&nZa7R&5H|Dyg}- zcK~u5J37vY2%b2RL~6wzPpgq)XTOOMnr09iYz3H3c7s^Hf{$65sy@mlL0cuIq~7n3 zShi`2clV;%sC@oBruoAMZbb@ProBtqMy2+&q#lH>aA^Y^ii0=hW}BHl3;>N!PH`$Zpgue|x|*l5KBz0jOjj6H^S*O6RqP zckk4lkYrAsI@L5QC?s_EggdXG;B;QZCM+ppGeBnC%AQgePEJl;9i0^HimZy-wVyjT zJ?7R(P(8)q@GIH-XNW})=8=MQ>fRCg>>ueGcgab1IEo^9C9gM|No$38g`3Hq?XUJS z5IHrlMNnpKPO-hMEoF4nqI~r&@(c~F4$222L846Hy4=^_&xb5Uq`uX;pFf>YSHyY@uj=!YNVzcDZ~8$(d{AoB!H`uI@lb~v+Gs`L2A;tB;p z*YEAz&G&@20Dvt`<`krT1Kc~|`J4RPw{J0kl-6^RVo=tGfA8ldnrZ))m%MdGD@%rtODsqM8vM$yLVg2%mz@)+(<|`TWsL-Mq%}xq#7Z zagw-%#6{#&(hWdRaVe=MC^U2z4r<=JG4}rMNOR&*M#<}$ovxfS3*HQf#gPY3-6xTL z{`#eJ?i|I@qes_Jgo#i~d-Nl6rDSFCE!V1YDZGu?AARp0ugk)@s{K{jm)|GgwAY#W z{SCyFHg(Nzq$8~b9%vWw{B5RP2{FvWU5g#8f?l??_{N9>+a%YwY&U`>&q3~hTs$f)2iokuS zo}+&VsjI7B8+%8;wlosS%gZb0?k-L&Ah6@;`1tGoev@yj_3uSdO#+B|$GjZa2_o%J zD5#OdEqR}-JbtAGort@8_sQvG8FETWB?X1e2tCg{ep!02PM7K~;M;g(*+BKYe*1R& zr%#{6eO8M4+!Crx-}d#fFdx5qBP?tuplj+iCwfN4;Jt$9<#41jGBU0?Ir)c&hg+;8 zg&uJjI6;i1vy%=H9Yrp$fI#e_NP}vbABtDIvh@v1uI|G_T(GpZ7EmPo4xM2pYZW>MCw<>kUr4fB&6k2TC+1WxfLm7U0XylwgCBQ&GLa z`i{zo{xZqQ%+$8}0`}`=eLWdc>}$k4FbI)2PWnc^SOV}1!l7Yd+`Yxw+5Ev1;l1Xl zCQ*FrOqVQr_If`QkM{WUBT?bK+=;cb11nZt+3{)3IZg2#Q|B}XJiV*0;?<dBmAUwek(h2@9r`G=N2YXnfG6Es+ItF@h7cyFo0 zljqNMZH#<<%5ANzhUUvCcEx9x-|x*DI)lJ?@SK=6=NL}oUOd2zz&!P z@{aqLZXZHbW_I>FO#_Sa?k+4%;k6-!9|P6QH8nK^P&y_mI_NHR-+fThqLBuGRL(xp zAl7pJWYyfdwf@Z;_7f*q{`~plWTtyat8+a^rT=IHi1CdS z6pmMWOQ?{S&Q9DSzcIQaZRu8BSC{@wmsDX{nYg>B=c~Fp5?0-bT3OU%?(0h_Y3-BB z%Bjzv?>=hT9HpLHZ!lx~APz{e!OF|)j8`Hg|ZKV!oiKByH(4I>N-~NG_*K~5CTKiQO z-QAtHL{@!#9uQ=BanMf%<$ap(DW13-gMuJ!-g?w&hIZw^BsYVPIDga33L|ry9nha> zSOF$xKYVx>7VAuA>72{Jz<^a>nXv1R&o>i~UODTVHrqiIqrrd3h1Y9PEm2uaXNz?^N&WocVVecQ(S^ZQnOEY~wlos2(tti=n)}5J-oZ zZ5Q>7$#%>7)yDO|t0SnCi24kqyAav7ZD+l7G;^_Wj~qX)tgE|Q(rsp~VesmeE8CGB z)ttBo%*4gT>lz!$-$t^&MIslz{En`C;f$^>!qw;>U6D`P^BtSNcohJoBW(sCmO42( z%>k=xJZd}}3v^6yp4ynyiNGxC11IDV0UxKQ2cop>bl<208_j+C>hAYVO)s&1H+@a^ zVjI}%81n~ASypTyP-*vf=lUkrxfUN=VB*}~2(^=2!T6lKe!ZwOw!I#CoLez$ogs*t zHR9GSGVDMj8!3uiyMpA{GUu&L3wBfYdvdHLain6UTK zwI($K)Ipm_Dv<}`dz69mm=jy*sROc4RUJNj7=(R{$Io*vYAtxRBXBO0kY;0VK5Ep< zGj_QjK_Eh?xLxi%o|>JlZewa~{hfKFqpRypd%6Yzcc^8SNJvTX_fIQuv(V+XrQmg$H-~$dk#vUv`4#l z{;Pxpdx{TbFE3C(L3s^374SCRtCoK5^laXfC*}{8j~vO!EgKK5c0-{l=)vNOf#4Yl z9CPo%gApLAt^-^?-riiVPZE0q+6#i>1yHM^5rYgnckFl-%X9j|#fvvFQF4~+06SdL zmR^5;5EOJ9aQiWb0TyJj;Najo#A#uaC!n)yV=oU45Bs0ZJAV-(KyXNieC)wf$Qz*m zHc_1<=OGXM=Lq9R24*g{1`#UkZOdGO#tml_5>adF1Bwzhl6tapP$2nM&Gf;bTp z5<+B8#K`mm@8%DGNS0;g(MqZ#=!Cs{x1lDx6&N@K*hNqeEG#T^D=ZEU4igg-bpX5{ zKYnce^r<09!g+E{{Eu5YGO=OBbv_~$;L|VG-PlB+LL@8bJhoZ&S-{rUoSk21>*qw> zyBCa?ji9tXA}SicZ`WfJ!p5=GU(m42_I{u=ayUX>4hEivlDnE{<#8PyXE@&!9*Uh!V{Eo9(RL zH?VD3#IKPQQl9k;h0Ml40NcePeuG^xsP5CJy+EgdpzsNi;NCq(E*>6@8Fpusyu)w8 z=E1VRe))3KfddCx+uIeugc9H*a^`^eH8#tZM=1ZPuTS^TBY+w{yRb>p^+#}?QR%DK zueV@!8HF#AA@L|ED9o)bJ7Xz-gje6YVUezL9>*d;=aDVMC`kCiQ{~c)lC_n z72e+u5p0z7^yomjUmI&KU)hUd?x0^`KAcq|lvFpL?5KcpjibCJCe+2n1q;*tc`7C`F@%V%U%r$#7`C^!w}NMFTA{7oz&KB3 z+~pJ!I&Hc9d$MaMC|Oli=ewh1|Mmi?%7N6|v2*7<&J00Diu8s>Mp6To(=agHMv)Cx zjS&@soU7|`5LanIYACrWQ5w*MC?TB?$hgmyI|B&4(rtDawdOrZm+a0eREO7pe5OST z&UZX#aplUBGf%Z*ympEnJ9flat?67u@&fJsc6{@Js`;E+&l zMqTX&RS5FxRzScOJQB_R{o$BcD=VuDz^f3C?CNVG$r6VOkI`1`<(6w& z&9vvBW>lOVgdp&EQJ9>@M%A>8j8wB)-_Mn91IYH_^sP@Mld;O-F=< zUt*d0%RfU(kx<&CBf-kcadYnJ*0$*&n+( zs))elaaIL%vLc|8<8VDiIgj-neM0yH;-ms1e6#b(0X`w2+aL-sXY>7TgY%m&&eGS6 z!v^x%?;XMyvfV3q2HYCe7D-L+gnBc+u9?=mOCrk3cvv_rz+#WtTjCKYrj^KJ(PZ37eYI4_S1Y_(AW2?;&h)TWCW$G*jpjvDK zHI2age(TFu0?wCWCzGQ>g6^9(ZDVcy5?mx64KkcoK$I|bP(-#4Tx?I84L;?^J zxgXyIcK`L@AS=G<2#D<>6EQI{=xa~pxf7rogM~YaXuCC9mF%V*3ID@)5?O?N=T3<1 zJ`DTzQEcD7y&2egzvT5g$k2|n1JVRmf(rzo@D=o*uiw9ipe9d`bVG1_R#^BFfp~uC zHtTRf?YaVN6sb?16nZZ^o$y|w!FjtU<5SUYMk~a}_i{YhF9O^aQB6ZQ3Jwh=UJc}X z1NmcUZs@gDZ;2q%Z0hf+8vhA3@?M#3R=?Gz>=vhc2|7uE=($+_rc&(54t;EW&rOlau_@i zwpY*}_OZ0-0Wca;ZZo&Q^lhU)K#7P1{)Nw{3PmXARXaP!rMZiQCy3#&aa2)1$^ooN z3gF5;3FnMF2-0r#o+JH#%fWRum05OXgAaKA$Z>dla74tTj zuzq}bu^q}vs*ltlXy z(G;jhNm;pJHC|g=IxaC$jRZ+#plaD{`6ISqEKVpa5D8As&N+e%u!iAWTiDpBBdKy; zF23+`GaL&~i*37gQ8^ZmeN2*26g*$_7@%I;*SAKuVddwT#w5m>_~1cD)|sc-f(AM| z^3Yug5$C>y^FicPzROkAtTJ5Cv3V zN)nI$`SWMC;38BwCr3wiXXjr`cQt&(u6$%^Z*6@{IPHK7ipNkPpF)i_Iy0lSb?a93 zeYOw};rfdX4BQ$R6!ht{Yj>WJ3IwZTZZpQ|CZ&tBgFN70COe)|;~YKfal&f}fsS}O zd^Nva6-W$3JJI_hmv>0}tylFp`EC3aTln!M_K=_;pNxztpE+pcR1}R#MMXsu;7rpH zM{VAtKqEx8EMURkn2Yo~VzRQyo{KZ5h-m_YeAXzxsw(MI?m0yusoz}&W_;5n-tZ=f z2n(|lt^`%p%o1ZQtzF^!js_h&c5DKfPMvuchX&q`HfX%xA<~E*X1H?Y3gPyHvCi#h zKV;y9QF6qc1*hd}aHZS4|@L!R~Q55NJv(wiM}JwsCV;zDlj{J{``5-N4Zt} z($WvHNt@ok*WlX|fl5;wK1E(`?vp7$fna&|@81uzNnrb%`*-iEAiRR0SHa=h(Y5@i z*Fg>ALGX$@JOCyxMwKfS=R-iRCN1q&5am7v5IRpmET@OLfsRPa%QG2idY5xR)>jkQ zk{uLux@{%4!syhL27W=ZSJ1PEL(|eM!V;rKhLw=sH*9EfJ!` z0b^ly`x`H4XS;U<{sw;I)2k^fy9WI}26K){C;N0=3Jb2U>WadL<$#7wF)I6%dR zBk_Ex{X>PZu+UH|&<+-Mb|&T=4Ndx6)bmlNHa0W_$-sknzDqz*kQ+gR>4f_;UC~fP zhA14U>Avz8XBQyLsX|ry?&^(W&3Wq7hx3afsL^jIanPF7`kG`76SWtz4vI*fyh#X_ zH*<4yV)42m*=~BE8T>M*P-x_;~#*#hxiD328QnJ0g%gCD17w{4Kt4wej6W; zh2I6IuJF@aTWC*A5>9EldA*<i&rglGV60ZCY5?Y_ zo4O#>W?6S+hed*_n$kCD2p69qJ2NW9XVhhGjm7jps#?aG)#HMCMLux6T*2*OC*es zqlX1xu1h~xO1PyUc!Ry_N?2a|)zSn72nWo<)!Wk2QsjNMj1gQIiTCa`QhGc%;UOY{ zvi>hYQfD`#hErvuX+=nkJ7_8^E6XH)?Q!#ORQ!ZbtJu0D2ym$B%a?QC(%_>K?JTlB zlP(d=Ku?eQpEl2=@~q7Ym==pqApD**AD_hu16`v2!XE#G_}_|ibh&2?DWVDfG@N1U ziPn@jNT;!xa3jAzl(RyJW1UqV&WY>}AliV5t7boR(sGO*wiFKFvGcGy zZQZs__wHen31syIFZTM^uLIzdQ2+;(juN#UV`;3fR~m{Y-zWxsVbh*Qk!M^U;~x-U z{k87q=)?rCb2JyC#$F*)O&J*(;uqf^{`vVc6%mU6Lj@{Cku1n#aIxWG!yuP85fnim zRzL%66Y=!VOG}@^#+-nt-q_d}?7K9yJw3z?0=k8@wHj*FW7h3llLOUKc)vzQAI#R+ zIYGn_0c;+Fv$=WLq(W))&98Z}SG4jcJ)96mPQsd6WYM%c(F4bp2=Jh-IpHw3ku`69 zEI&FsTR<1iAtUn$JIEr)5BzTE-b04OT4N?vVb0yR4`x=%2mFT*XJC!^K15sqLLzL? ziLtW)hmxMZd0~}oMM-Q0LpreZLFWzF$C{UEZ6vL)O312 zgc}-ERa0E0=K?>h1nK3a_V809!U`Pq0aJ@D#N!Fe_T|f$b->-aO!w$#^nuC7SxjwM zb)O7_k|!c6nhpSFYU2r0;Fr&z2~P>Hl+*(pXccVp1gSe8J33x`dU9%A0N?|T?FpP% z!pm|V>TI!n|9zx2PG^}*wze8Tyzs)x1Dr#8WYY2Ul!S+(+q0<2?=p;p7FVxo!c_bi z0J04rfZ~Rxi1&1lC=)#Uf@U>IB-O*@CROgySTCFYsRgrrlGk~u4xG3LI#doJB^@y$ z8bVm#$S?SY_+SwQIz0)OZ4plXj$OMBf?-K#EHOEMULBk02_h8XZnOp!caml-4C6`ThS$U4wv3izi>fqtadUf$a;bLyCHHt8im&eu%@0LsmYbucjN*IVShS&3>ehdj=2;J%#!b;4PBT#zE4iR z^U1seM^oqeI35RS?VvM90v2cUO*y_GVHIWN7-X>KzwZq4joDMQc|{L7;Q@}pzm?ds zG5A%x#F-Kr9%!gL@b zG9{!pFLS;VdzrD0iS&I7POr}XU7EMBd~2cLT^-bbej=(?7JxA>h8!(FpZzUfdQ{+ zI^IH1XxPEP`|%v6)YOq;2^yN3O0X6opIUtLaCiTTjlZxiO@)sJiIjQVltaPP^Z;nU zXZHP);xJbr1ZE_G#U=V?JZtS82C71^W_5^VGiw-$IZ_?SN&VvFi(r)T{9hq6s22*B z+IH`PInHT(wzrg;Q~6FEoN+lmcK)z|f<1KnyW)~=R|y)F@MsWBKIBf#M3M9!m9>h> z$`Mfc03W&Cg=h8jzTzJaeFiwKL-3z4O1WMwp66HW4G#%<`TnjDXkGrJEpS_a0z8Ru z1owFe*w9z_4Hh*!3Cs#iS8*BBV4-Qj%jtF?{-mI}2enPpG3+0rBy#GWMlN=Qfnl3- zU$xKbaY>g+G8ENKMcDj9aFAYeb5nsWvf7W<4*LimzFh4pQAam7gHSsO5Ox^b1YlF% z6j8jxhpY7K+lMwBjP&3|JodHg*OhS6>G?N+f?@3cijoDTqklnx5aC7zlHIm=xU{>v zyGb9SDE9T@+2l6RoA>VD=iuYZ8hHEQ-aT?DsY$gk-iKeTaL zX3a`KTL)lK^q3vM5+VXo;2EJ5T!6L=Z(%fZfkG5wH+kw@dD%o2O@u>?q397ktiti6rpM($1lj}4}n zFyT-=pOzFCCy{(tr^Wu|mL;mV=4Q>r=ZIK};2@cr9Syt-zb@F-fye-|2dDZPs|A+V zsKER~bF&iKixlQR)qnh`WnFR^+|9)I?_JpgP-_T6S;G0-v3n!=Cs1z$m6uDv4o|3i z1Vaxr1D5qnXbHmHegeRJn>=T7%=Qx{aHl$LL3FfE@h<^>{yFdh3W|zb;32+ir0o6E zba2Gy&yRg1J>~+)Qm74e^z?2)M@I}$wAV!F(ZBB^;9ztZoa{^VSGIxS7HiB(pra2jasB0JN^+9@9vAx#~!RBvn0z z*&LpyX5RB#p{wE091=4{8JXUn0P9O2A$j0IiPHk(<0cYTpq|hjJA0p}+La=*;Q{TU z?7G1j5eNBhIgq(i!5^`-66SsTLZHBV|87$eow*xdKE1h4sCLc&+zU&!{0Je?Rq#_M zNTp@q=@3=GK@5QldxfkG+C^_#`&-bpKA(87dCk83AZfsLQO%U)G)lxjFE#NXe87=1 zE2>Uy1?;SDW?hBmDtDMfcfgQfknJu}?irTDIXi44@9J98H)OaVZ0cdK6Lxi?F$y+Z zB0fP3%Mw2Ob-Fised;9u~p{wyvSBL_sFx$dePlLw*jW+_?=yQ?v z9?}IQl?k-g=sLXr*<%l17(SS51DO0RNDB%tuhnf|T>Ja_TFV^GVXV;?nTE3CbbIXB ztrCF}5F?Z<;?Eik>LJrzYtJR3SL534}A(QV5SY9P3+Qn~3>Nn3uj#5MmDwQr;rf6Tl*PnkCRFIg2Pu9PE`vg7|T^@dja4{RQzH5vm zq7R{b`y`6D<_BV@`AWv%Lr?sUO#qEt5j5%JoSZO(h|Q#LA0G;wIS%Ov8mfA~YjIH# z4GRk;3I<{uzy?EbeijyKeRf|^sn1kPFNEB@xd~Mi5o?er-Z%T91(fjagWKy`l6cqY znk?-Vgw39Kn_SSijE2D2sJ4jSfFH<=pqXwXruCIbA>F5cPJkG|=QhBT?7bNYnLJQ| zIGt!4dfOPydHJ2R`y2^9jOyL4PftAvLWuqf&FAy;%R2%30zoSh>@2o3_)5vD>S|gV znj5gbJci^m0d@(r# z19zzjK=U?uXSWb$c3Mtl-Zv$OYQ~+h&&8ca$x*TD7#mY!djNfILAg?f#0w!T1d&_8 zz<>c&A$n@-5#$^}3enNizXT;6n-iq&o%{iSkXx)Hlz{G*DhFqqEZ{eQkKv2aVBNCA z8!0eiNQ`p4Ya2N=czkitTAIrSr`yfKyMbE{?#qirIYxAFVA9l2nUy{*?u*qQNF9In;@43rdP+93!9jVVo1IR^%HXcHd?HjehpPjr+-{9S}Xy*VP=vsBR zv$MMhp90Lun)i>X*$lun^!3M&JK$;K;^T+F@C=#y&abH@#*7bd({Fe4H!QWwq1)|7zJLDXr|D~q#{ zc-Y~bf*Rt_T=O;4dzRMo2s{zm+NuruR$=!z0%LlF{P0f2;bj1d*ye8dNZ`22sXkpI zV-5ZV9nr+F(ZAD_WLxFg_odMMwx&Y_+Qb0B0*TaVU5O+m2XulaqQlMy@SHooCg1KL z+HOEtC_&?gYW{U(WDD3;7@4+#-bs+s&6M{@9&`rU&M^>Tf*&ECQLkjJ>?N!g zpq$dXRP+iQyZkOrvWwtAi3s5H!rSLJbRLAMRP2%NEZ_6znXp9Om_hC7=d`Oabp|t?SlZma4u#j51vVU#&MQ+u6BoAd!wAY~uobQIs z#0-R|j=FkiJ4+|gL=6b3E5xtYiT#v?^P_j}T-LF9V7kulc3**vN56iR!&98SZ%DZO zOiUhPk_@IQ(CCanauSJ9_r7~1i-ZDVjIL0!UMIXNNd2c~!k$d!0IljEXHETn^%F-` z7e5Y8z6sy>Bi}bLV48CGMr}Sw)*sW;)>sZOMbNU;PMyl@xqG8~bm;Z%w3HP2+P{Au zwAXvheU(Smnt>%d-wiA!WNl^D*&EC60c(yDSP+;vpP%pEkD?oGd1}^|=y_^GtH{<| zfPyS+Z3Px~53d~lua=EId}$LRGVvf0tg`vX=84X3wAW8vZ}Y^VB%TQXGRau<_b3v0 zs5dOyO-&&P5p?-?(Ho8uqzIi;x(AV8EKs6N5X^s8WKNCU;t%|9e0An*hsQWtqS{@bWgpDWan)393S=)anW?~UN81kXKJ z%K9`-FuC>hX`c+Jpx zK=$|+wBq1fz60$RXQM_?LN|wchb?yr`l`UzWb2>yLSc$oKpRuC?wj*y+$F97AmkGd zkMdUwKo4rCPe;~ltgn`?QzaSm$-^Kz4>9Eow&8a$>^mMNftb<89=0uZ>|y}uAk001 zdtM`t$DsAYXL;;y+MR^MChFK(*C#vq0^fl)N>bv8el<4L8_|M(mE62MK0dzh;bUQ8 zVQBV^L>`aJW>7iA$r(Vj=e~VQ7_aCgC2ZkufhvOj7bpPCd-p2Cel%47FKrU7J~JFq zpHUd80c{Vl>mZS-i{6^lN7Ntv_Dvaa=D*EKnxfzR8ue&fDjOmR=RYb)iuAQ>; z0mw=ibxuBd^hjOQQ{e}W5!dbzIxR|I0W}Q02(26GS1XB%0MUxqTi$i(RUpC0B7 zqFgs-G;|{Qq7G0v7l=|xw96IqE+}v)<{3imaSX3R zm?^FqK0D}*fWSq!!y1HFTynD6^e%Hy|uag8?P(KW!88m3o9$)0nSWtsQb9AEjbe57e+CCuiZp%JP;z$tq$;^ zH(62%5f0-ZcuxL9hvJNIs1l)nsGd0!i;l>YqC#Zb7~C*{KC1S7la0t~DeCupejB89 z`$1KHYkmHB3qdmtT{VlAy#P^1pPw}6Gv8l%@kiywhR=8Pf;mny+6JpzchqFY{aIbS zZPsFNM#r+|=)-TmCf&{^k}cybEj}O1lgInUy+4k#1-@$v?vxXnT~rrW#=m25xiU;^R{jIGamz zea6$>J*uea7>;vV!)zaVRB#|kkf^$s)eU@NphO|`5<3A?ohR&uUTPfoTOiqMvyHC$ z%ujX+5HSy&j5f?%;pLTAS`OIs6!B3p9h=CpSE03Wd_`Si`K- z693h7MD%BF-^D_>7>Ev0Kmnq~2zm?@YvOthqVU|hbFZG%=ESHfxS;?wmB4iq%+uw| zTS1;wc`fb&ESvlDCkQTGqP-B#t{uK}d!czX-xu8pik48v!8TAM#KFcnf^7kpf*e?( zLJU=&a?7d&PRi#JJLUu-vt7_ODffwxfmDhD4-D4;R+l6%^=1aiT<1ztk@ z`UFi+iCq|~3q=)`?a=86w-9YjfbvY?%$Yq1 z-tMpu0vz$)RR{Yi6ju34*J-74BXscq zuNjwJ+XPkF5V{F$t5_2wcHr#SfCYq^;rC2GGm;qLAi+W?mFHw+1c5(%jC%w8Tl&F` zn4=%M5k7a|F``n^nSn8TCwS;*&!4{nm>?_{OMU$)I^k{Jia@0^gC~M4Z~#;?IW_g| zoE(8q`6fFtaq@2;BqRiZdmM)R0KsJofcWJ~na@owA20{`HbZF?LLN3rZg!*G@FUnYc8Z36=p1QxSoF^b{1ib5q7KBc`A%etRE^I%p4k_E=MLSNJ(dA*0cL7Y$=mO+ zNa)V-+*rR?3FU{F2HeCDm6Sw@I*|B&2pAv-Sg~K2^k!C;mcD{mB)%VZQ3#Dn<-JHW z+u|#6sKi|+>EP(2Wo8Zo1XVA$y>OxRvC|?}OWb!&90JB|lzk+kL6Bwteqprm*RGM# zFc@qW{P&$u3t=>&0*(Wk|Got3&A+dWa&-LnB~ZrybGy{Y@V^a!Wo7@qHtO)dKj}`` zzi*c^|Ia%Z{^vfbfB4}4yyJiW;C~v*KYXz8KMducKDgl@hVq{g|HC^9R}^9lUdoO@ zQ6Xm4Ur~W3If?{KTh!SRpg34VH1yrSe?A~2KKR=B$NfYZk901Nb~cncI}oWU_e;_d zp4+4(TNUC% zSY@qjtzW-u-vK!hhCzGna)KEHqcHOEVXvyD<}Fy9e*ga6T3WCL4mH@AdmcN9adDBM zVo)+PWW?oHkKv~##sVG=eOfnibFX47&z{i`V?jd(SeGc=kN~Ef@cBT!@<-Cfr729B zRsZ*WhWL()q+YkT@5WFFH2}v1Y>kKH2>OU@{)0)!`) zXpH$iJID$|NOf=kW|%q<_W%Kknwpg8YsA%85vV?1H8oNE_t8QdFP|GCE*NCacLd)l z)4INWK0e3qtK9X;B5SySUqz4bw3ej{=RQ36cq&SVjaxMLeC4hRPfz0Z02slyvd$6? zWOH-E=}lxV2$hCq*VvWsFm3|D0~KN`?v23nUk&(N0}B_XwgGj$yb|N_tBfG*iT*~U zVuC^j6AIVa9`9U4%FktvoY$|rJiFedTV?xam-3VF){8dVRf}TlqJOEhLhaE^I!23W z^N$pR<((i~fB+90i&O2~$yrt&{(7`YG37}Io$T5(CivcnTaXZw$ygn*QcyxJ*xH6c zz$PL;pie#U0^7lZMCya~O>|&TakwG1Py=wF^rry9L<|-UKEYs!a1+PoV#E=R!`Ht+wFu7R_Xt{qU80xBfky;>io}N1`G1peIn2j`02DJXNX4yJOu| z=zRT;zHWSX;+)d`7Z;^O_3e~D9Y2mPUY^hH=%7{8(u#mqs0n2&tK<}#8w5=%;;?0# zKG6Xe^x6kTFz zm-q9&^W|ON?|qLtyHhX}q5f)Bfm!WAlm5M(C3zHEwKTZqkq`p6G7~NyloHy=o8N)Cx=H{^ zpFq-w__+hu0%^<3-@Gs)jbNmvq0tdc%gM{mp3-w1c%%remoYIhsf05AtT5s3-46e) zJ5|r0zYkf34;QaAm=^%4N5k!8QsaH@**wv}k9&kf9R`wciqD$QfRYLTLT;+7yMcX@ znewIDt29#?SStT+a&%Zutr|SI);88UPajoJl=297?LC`Z^QYfiwPz*B;>+t$;zTew zK(i+X2I11SzXk-czqG1RwWrI&nli%JhOh>67EhVs`*-geKMq86{_eE;5_`F8uYPjP zac+lH*S|eF&f(t(=SZ1*Y)lL|m)LET6DL_^l=O@YeO5xlDi!n27jqdIG4l%w(i>NS zm-ZQ%CGn|J%xeq#@cf1*%QkY_U-i8`1l#{0VqKqp#QGC zYP)iCpHArV@E5II!V5wpsktE!5q6KqC3c{}K)bYJ%S;{{gkMfoLBZdCpo%Zk z9Y;?MsBm;-r&4x0gG)+E3wb%0kimhsNF;RO zz)EtI%#Zb>>QkLLNq3f6k#<_v>8@gK{Ys{urs>wKPO@LyvQ)&K=E$+hxP#q+-@_>OG~m9SCy3B! z^`~v^cDSh)t9;hRKznYJ*W!VSd;-yX{`nDt%7^??FWN2@%*VK8v*CPH7DZIlvnWA61}SO_2*4ZcY(b`Z`OV&H~R?!9f`Ii)^}f5F!iuUWwK%*iT-4`LYl6 zHBIrag@u!FLZ^G!UA_8sVj>vZ?O!6_uxke7)(aR!s`+jgmj%zoeI9aQwJ$3crY=fb zh_9VydHp7!a{g-)=GCk?I_&qgLRWcV-d#x-%Tz}12Wpy1)* zAudu7hdT`3>oe)oIAqbWv1hFBgM0xP`8qu<80`KRMG2BTUQF1)VS1`VVxL0-;Rdpp)N8bt?J zvxaTl`AhxD&Y0(3U;nd<(#FQhXnu&e@ax;(xj!{Q9Z!97ikOdD9`{}Sz#I|b10B&z zGjaH4QWE;@rp#f>@(&h82O-4Jpu2Y&kaB@l~*aphf==fV!$ z96;P@!NJKnge((G0EqdO1>4}TFyb~TG>*vwqT^oHK!=)T<<1!}#Sq1}1BGpeL5R2k z<{qxQLnGHUxZzREk#h_{c&A12))~58YEF08zmJb zA!8{*MN#MT-S4#4S?~Iwg>$;R_RlV?Qurw(0VpsSmWW^6fy zrC_p{x~C3K#kc}cRA=u>oFre zxDk*HMH@WMCZiu=HQ}+ks%j6q;5$51_>u@3cn~AK6epfO+o1s0LHhupAAuMbRV|8f zhCa7PWZ!Jtt{w8AdcAKv?!9>Ydz;oy>GWLri^o_Ml_Qe;i{DDL%YWzoRd;S%d3;Qb zw9C*R^{4L)4?-Gi!4<9o>TwKa{K8oF?4Zp32YvsjPq~S zJeZHbv@t@TWJb%6dzV; zjVie8n)%wh{H-5A`YWzlD%xERkA_NWMAAc z(9+i4H`MtW?-ZDpWA>i+hDYeL^*0rrC-gh;Tt}|f-|zW+)NuYC?pSfd>}rKL1S zroc6I$2SEiFP*vp{rhWDrGlEl?*|QSc#B7w5R8?&z(@~ORc*bq`sAronl#I5*U>y4 zg4MTp7RvwCsl)x$tV)ZVsbDD&>!N9GJ&1Z->R3AA&Frk)5_9wYh>{0f`;5X)=$j~K z4>(`DfkIpi>e@dKTD@wO(uTrw=Z5avzkdZWKirPu3vU})?F=wqYHA^>un$Z}Xohe= zPM}U18GcK@&Dio`H)op1df+mT9x4efdEBcu?UEXj(>e}&`hKSL*RT1TzkJavG@Cpr zEUt7x&qo%W0VJuKTIG{c%>^T^g0~)3UPjVAt@TeQ&3@V|m!8kLLrO_|=wsXWzacNB4EfwZ83#>T5U?81KEel-?7AviVPn zM9gxjuaf243wsIpMb}ohKp~R2aKZF%T!&DXgK2|y$8{VE!IMR7qiCQ_@jvHmVP=+m z&pn-TB$vZa2W}qw7CVbB3NN@|7N>SWT2YcOgXAuHh@eu1x?&j}v#=203bsF!4%iK* ztHlu>YaowTf7G^k%LFBAvqIf z1|l-kI0cq=8M7TJZ_M*+15p(a7A>l7F%T^j(K8XBa2mV`2T0w9DJbkmbu!s!?f1@J zBNIJa<2n0^F>XJXO`1BROP+_d_vap=aVb4bj5jFwG&|FjIBeY<2JlEK((%Y5ky7g2 z!bmP3F?K;(tlw0nU1=NIJgJ&^;`nj&34>|inUEG*RH&m(4WE{vIkdhS=bEJ&JEqv~ zZ1}I?Gq3-U3OKT$mx05RI2q%|#!@ngX|6TWcURv}nQf9ZjpAnCr%%?v{e4eQf7?Ya zNQR5Q{B13wh)X*gH-7*0tTzddDe66Ry^Nyie2a{T(1c_#yl!P_c@V>k*;pPx%7uT_ zHhnu|34oNg6i`_9n_BrUx51|cYy}&&Co|JM{=|q2pJOz-Ym2fF=(&<|($K^tcETfg z%FFO~)NXUQ{e2P*H*W_(m=-nN@?Tm2VUNR1LF}h2hvGQRxpOioURkmhdI;K+y=W{d zX`wt11RWY{K6X?@M9-ifU+ug9;XbIBzrW~DBtt(MOmd!3czNxqj&mO^>7+ZxPIKn8 z8%PC9hGZ0CEQVN6} zTutfD*xNOTw6_WCCm|$Znla|;)QJ<@eQ_Fjos>`s?;)%fhHkz_2;qga&U^V-07Pxv zGNdz^nWPQuKxN%g0`9Pq8V%+}=2Hq11~1?+fhuA|J>Y$BIXR)?8t+g%uHXiyJ3G}C z-@lGoZiwL2N%j1VrwQ&o940ljwsVvyj#0@iJ6WQp=Frj3u7Ae;1&JjVPD&_KKgB*g zLI@DZAKyBBqF4Q_7ffj!=zcY3M(?IEpl8H(r{L)`b=It~;u?)vGk(?Gn|sG^`P{wtmy&G6 z?B&h8q$u1Kg`W}E0P`l{X+s!mhb9gKJyZKKCX)uubTRziNJVjqW zOXq8^FZl50#qrHwqtXFLy%8?1vrTZ3YE$`I?+bR?PA}e9=HE^n^7}|okIy51WzV`W zO5x?NmNV-vMtcouHz>@pv~SbJ*37IqTE^1H7RldwVK?Y2)8WU0Ju%9oGr?p`a+7g{ z{SfN}kzv^WPz6%4%o1@JsCFpHoq8OR@_1}f{pikCFo4Hb+UMzcORmcak6^rRkVkv+ zn}jHA(vvYVLaL>?X_Fcw7+pXo1db}Qh?v<%B=j23CqeFUr3CM$>GqL%k`YrUGPzfA zKJ`*Rzels?u34{e@BTfROUjZJuUC9{Tde;?y=Lox*F$obKR@dfcp_lPu_GtWcwJWQ z*wG`S%^!dKP_KQy!{_MH3als(*H>?!vuIJr^K-lHi?$nk)nTpY_?6Gqw%7Jqwf6n8 zkB@yfZ5!hG*I(-|M6B+lvfbn7Te%Fv4~=zr_G(&(f@B8^iG1j4ptz}&u`B2pPO2?$ z3p(kErdQL*=(5fB&T)S%qoS1|j|k&Pfmr|oFOS%J`QZC@zU<5(5(=D|DhHx;I>$no zPq_U28nMiID*X*;XTM47dXjU`!A>_lBy;sTQ;w0otZ;i|T(gq4YcT^}JS=KFZ)jW3 zBh#YIhj2t&q?2fqDGYtMXK}V!LnQg|^WUpWdH_T1;k1YWZ0<%uO9hfsAz|eGJnt<9 z1HgKE1<6?K&p;h3B@v$jIMWH00-G}iF%C0_z$>(b6#RVbVX!UGz_RrTQHijG!$yzx z<`)YSOPa(O|8yEnI_l&!Y8_oPB)7^06aPB(#=*wDU!S`e z(QdNx;0p@3i=K9y7aP%LTywV$l8hg-`dpcCrRc>uEBVU!AN~}MS|mEx`X-l~gM0TL zQFVlU2J}iBUveb(;5md*)FFh{G)e5qXanRQ=iJWTeFUL~tsuhBTF|IQ5ghaVoNKtE zbI?gQ^NgYa`VJtM<#tJyuCZ=L$mZ?112?M9j6MwhX> ze8v(eY)+p%c~Woc9XdpzV~6_n1iZi-RPu6VBhr*u)gyoW@N4~|s~3)>ROl3_y2kJL zx{6aieBwltCl|x-8#1n-J=&W%}JUs71u8{CQf->W7^R;e~`_;AK@EOwxxkS8v$ zqwx#O9$Mv)!I8Q}@1oPOG&I+wU~nA0w+mBl;w%X)jkn|(@B;5;vR43dpXDVg%F4d5 z=0iz|g7YD;!^0`fa!d%Xeksq?Z5sk<`1AOh*($9UT48@k)pHFEdouQou-kCV_HW<5 z>9kV)Pvln$XH2S-m&~sS!~-}Nf%_Pr=NlAnM-4f03SZ>mO<&6(XOIjIdn&s?JAbO$ z>=MlpYF|Tk*d`zDmZUHzR(HhdS)0>dYmm8OA>=MHtif*`#Ih3 zcIs_c4+$vmkrT@GYMU=k?5iC7)9gMTJ|X}gp;Iks-Y^g^1sbJ8L!zuK&|2r?vBx*k z>F84bj9Yq%T8=PZWUu&DBaPu-u0$O}Jq*?$zZJtdDCvLv_~BOcOCWNTPH^of_2w)s znTL=?P+2&SzO1cnF}qKa>p_qHg_#)MwHevEz(2uuf5h~j2Gt_om=yE!^=sqLmE~Bt z(}H<{_JO(;?`Xk2;c00pIy&Q?7KxM?!qE6MgI}@lY>|w>wd`lo($#imNiLWpW{`Om zbS7_Hp9KbbuV}ReN?Nh_W$lsJtRZu=n=__Al9#LNmDRCn<*T;aHE*LAkj$Hxr+2>i z$sO=LLwZ59m(s&+P%rTA<{!(JT8UB>cSR|q#cg&syKT?NsOwed_quwfqm$-%t%m(K z-4k|Zs>bd1vru^dAjB_p*L2Uu&)=$Nww|B&$m!=--$eD)=5)r9S29Rzdxk0MS})Q! zwIqNVB9R_YUj)g<*v;Gd0Z+v^$<6Ze!Kl<-m^rl=>_$U8n7k6(=q3B5?%o@^t4o9y zy|oPv)c|dxpk~d2s?UZpMzC;{blX~6TbeAqB0WD~qb}SQm6gR;yD@z`bN%f%_wZ-F zjk3EATx9wqF-%3PDE!j8g}QubKRh>LtZPUm1uS{ zPq0291klWJYz$CB4^EYs6n?Gs72tlkM9#`_Ae%r%%r< zZo2MRpAFiFJBJ^Nz=(z4ba3l`c4hVA>&~kKJDw`G;A;xm5D;V4ucPm&&0leT(Vqt{ zONpmj76N;2=fSkGCB=N*0;Wkct&hctCXh<8==$uYFR$7`@b05BlMdH^8F{_BvT`rq zzu4{uxl0I}sKsKw9xZLsBMArvIPj$L$73qVP9O4z@yHh09skP%#<*M!LspkOk=$Hh!&CrQnV%#Z;hi5)$Db&~HktJ!O9N4eK+{kmk(*6sb~ zR}C0&{OnnkRF`WT%H~q{ZDH$=W%8m03oh`829T<;wC$quf}+SD=_(9Rag00cAb#pT z`~VzaQc{xcyhYxn4IA_a226ci92alv*3DAgXJo`k!F+li!pkFFuzOSqBg3Dn-jMDx z;%>oZ)sG+6nXFlJ@#SkFk{Y9^n2*lGp-3G7^6=rq>x3ZeemOlc?9foSVD{^{#lO1_ zE+Kvtc%%Kb4MOWYZ=Uy{!Goh|!_B|Ji|hvzfV9}@c}UP}{GWBSg30!+uW~wyUqp~E z_`6?Wt&c-Ayyg~qe9L5yZ|}M>l${T|(_YSj@w8?Xo@FdyX4EuhSfYQTx3aF~ z++Zpt)u-;y%F05-E2^Fp91pC&nk&%k*;NJSCyKiOTDGiG%t3IF4Wvtf zM;G|wr z>T5$o-}M>vY=Y7cW^QKn+O;K5Rgf+-KF2N-SLmBje+tFQ-SYA?gis-34SlebODE+0 zWCUZpUWQgaV0QrR7x-udteyLm?XVm3`H8FRpH0ZFy^m?IxG#t>Ld)l|ZfqSsa)8W@ z&njh95>iv`)sP@YCr6K&Y!|cOcbbjrv(x@3-t(i05a_$M&va*sU zrTOmLpbm@~y(2?fvVBdk`_K^|Q9I&Fp~*EFK{Xx>%^=&SPp9d{=+(rw7vKjLKU}23 zEC90_14S#G48#OC+7v42aM%v%U4ln5&T8{}zOkkMU*4w*FN_HIbHvlVeJiXMOnmro zXvnE47ouY3@6X-eXV9Q=KU|2!2Ju!QM`L0pz#^YYu$eXY)vJ;*<335BQO`UC0-;4g z@gy;HPJE*0leM(dkyM8MKuGaC4!pnk7(9XV_?ywlr~Qu~zW_U0z zmU4E>%bRVO{TKp5gJbKpbu@-zb{?2keCuq-GOBriWAQw)|KcKYR70dQUf$k?_yDa# z5P1RTT)4F@P-)qDnC2-9pA6dP0+e)jD=I?8-YPtFBdD7Ss99=UgilkXt_*9$l(TJQNJ8$DXWbVb$MGJ0vrJb^&OMyV9qBe_g_%@YEDe z7eL?n$41PP%Gv;mc=yGNv*PU2Rcry|GOFcMoPtH1kJKD6?*kX-Nl(OXcg&KJE`6k9 zUbSK6oX2deTP)jWKmj@+WHtI&W&yv6!+;|47=5v#4FcSzcOi}+fNuC(dZGXtDq8vj zEAToQ4b><-IU+7xm=xuLDt^I;dA=9s9`w})8P-3xdXYYx>k?mjWN2Upt}SkkL-kp} z7UhH2@D*Uc(Vrc*pAcTM6f}-=sO{P z@nugg{@Aw(DJfHgBLqUG7w2BPe|^*0{o8}7$jyz$Y{yDQADXQ1n;O~B&Di1$00EwC z|GlDODQ7~6G9aam=))(QYAGhTC^mSsoSjM(o(<;4DeBfTBn$n3_yZlCx3T**`UWFM zgXV5W<5k~seW`~RW}8gb;2oNo?YH2&es3{7PS5 z+rV3ad$vx#Ze?h=o15vewAOsk)Tvvv`W-wYKm1n@Y~PwoMoN9DTb_n#eQU7G+c$4o z%<5VOb~pWF`?T!?!##33dwMw3LansMHmu&Up1_TQvClW zfBerc{vRct|4~Wy`_C)>Pj!|5O|bbtYe)avEB^CQ2K2hy)Y1l$_87|yto|WYz3g$B zg5yc^BgMJerWNX@|B!UJ^!TTI)eQYo*S|^e>#0^l|G6>scl)Zhfnz06k@AQB;dj}v zNN)U!74=^?>wcB~=g(Z$@Js)fVdMXN3H~otu4BiH*#m@5wc)Z_4WCDAYj;!h;y5(8 z{rD1QlXwpC5ou+_=+Tk)cG6!8TRTl{kB_Z8&`U$q>?+EDkNLyBY0H^+Z0O4-f>jr} z`k{@7FBz!q59g|2?ht?uyU`LLpFe1J=8{1cS&QWs9CNI4}^kDa?#; z0e8Xxni>M0{eg`x1;is@|O;VVR#)IUPJN!Hrc`g{BO zXII*@JLod)bFM2uA@A_L{-;&hOYvW8J{$o*V z>*tCrZxC|+a2W6`vcN|vs<fsi7n{Ds0)@aSRCa+Yem+6aa2fX_ z#K^7j)s1vyG+xtS0mWJ{vmG9Y=$X@QE^)hFvSvoxo4lvEyRu`=MGlbUBar~ic}=B_ zXy&D@9*#bd(WrAPJNWx`ldcE39w` zr?VNZqEegWlnb^Dn5ZqKuYX_3Vl|!h4kh(#xB_xH&qYNouAD$NA;w9Ym=q4^aT9jg zm)DwGDPq&tn^LKr1QK+PzJ3?(^LdLX#gWoRXd2>cPMbqA|{;>W#_JaC)tM6^|Dx8Z_7TM>`{0!EVm{9951`QVBm~ zr62MdyAFeg3))r)!I84>fdn|{&)d$ug+eluK<5BQC*R-l9vr#AXA*dr+CrVIL1JK|{e= z0o#5wHN8d}E!Mk;&4XNzaEnBnqsM=Jws;TwsfP3%QKo6I&E=&+Sw>BEu;mfJak-oADuGDiOQYxU6QrwlL|Ax)g(9>mJ^| zB~Uo;RyjDCq3x0YJIB{aK2v)Cc;wO2&eparVzG~yje%MP=mE16 zM32DiLPA2;sf+oe)YRE9^~4LI?q_g#$V``^_M7nzMKwK}@Ir|tuxWy;<%VktPEK|9 zha#l8{@x&&kR32WM~KvTYYq~;<`hO1ffcnNgo*lKd;1BL1JbwQz&98~O~~BDoRWPR z*`*EW3uE+O&iDmrJ+A=(r@r$C9jAs z0*4e!;WiAUEjE%#Ww^LQ2nlI_KT1I)BieTY$!j1m%h{ewABBEEEKuTN&2w@217YEE zFe#xZXZ{P!lbN5660Xk^`<4M&eMXKNzw4KaB+6N*PM==^hWbIZ?ieNu$EdU}ykEuY|RUg8;|7qf8ZS1MQ*M9DuGd%6#-d`}Dzdh2o>3APXaC zhlkgaI>p|BRy|?syj9cVJimYuJq1+7AdtNIQC zWD3X-x(gN@CM}M!uf*MxIDV0XHhlQO0|$mdh+zuK%-V3Hbm0YLxs7_*j)`P#ZDCd^ z`9M^$J^Y@3O6{hVIN+lQ2*EQYK#1@uJpKw20EceFha-j^$UCoAr1NaC5;D>1|sDdHpfYLo;Wm_jhp95($ClC`y;uz!e_I_-lPH76PN zqjQRV++@Kek1tbQ!Ubz{4opYsGa?{E0;G0pD+KmDl3tNY9-f0#5sS2hz+Liz&^kHg z8Bh#{5A{j+e*#g_K%5koGQka8^0u?-cx`_TDtgd5iVjF>_YifrA9qqH`=5YsNq6n~ ztE{As(5W8YLwUy(Ow3)a}ulp3siNoN}>q<(>AY(*h+--gbMP_P4c5i##<+Vs`CCQy_{n4=_vMytwQLAIla;~?v`Z%uQq9b6B5Vm!z%+OpGxKhZ<=ew!=gUHe>?PY&a$7yB zzA;s9)?~$#%WVow@g;?W4BNh)h|c!6s;vid&1}J{^6Qp^G?V#s@PlkIYm5>_zK2(q z`&9yffhf{M7KfxsajXy_lp@7&(#U$~7Bcy$s@L0C2g>7bI;H~yS4zJ@4NWBS9Un^6 zyT32TNAgkk;!TX+BX2d@@<>mo?4Zi#tuk;NBx}8n_6THg`|j=gQdn1a>*lN4*AZm+ z79-`as;k8it4CdHLchm0=H?AaHIyKmz&r5X>4RhPKwZ?{l5Y$9zcHAb4w zql$*R=%y}Hk-5{Gdi7Al8Fa@G6U%r2Sh~X0*&wc?6HT&FW9g%xN#9D$P)!rey>V+y zc(~X3mn{1;Y&JZk7$1%vgClhE52qE$-_Yrqo!Z7JMZ|1=N`+Jfj7l1Ny~y2W)Tjvi zNOw!?W~{28K26n22S)xCQLQp%VTDlb-CuBK^yrCZwFGhPUK3KxIxJ&Zl^3Ev>?0fo zsa;Il8A(B6KThjFl)0ZRYyV>F)bEv^UL5r?>37lfkEnh)3@eeEWBb-;R)=i10x`B1 zRn*u+bf8t5PG(^%-rQK!C4e@Ce9#}8Yf0ntuZz4rQ`kwM2l04h2$if(ER78C~D z#g-07UoSmagXBV7f&Q*NJGzKwh_Irw_8j7QvDO0&`_Zljq1@xYoFL)Z#p0=!XAR)J z?RV=vN{#VDCoDGAiC)cy*3uign4YKrnY>;NN5p>6@Axp3?Kxa&Z7(6W6jK1dXv;(u zAV$oHLDYj!s&<%rY->ql`sNO|TnOD;R(fsX!4z#FFKZojKMBuvpq?1zIOt0$hG3N1 z=gX&WX?d2X|Mc0j18IMFFe36<)yk2_;15HJBxOSQ~!$3_Dlb+h{SoXt0;1C zkQyflObQ?npO?^3r2Bn%Lm~tiXCIr8(4A8!tj~p{E;%{=TkBLJ54R@=ojvuhWcT;) zTMB+Jg4n@dKF0aW4I$NITMdViYIP1zvH5!*vH|@h10b@!KIebo163E|(ui?UP-)ruAfKsCrbh1EohtL5l)5$HaZkVlb{N zOozqCvnA3LWs;VrjXoUX#d8|2b-(lC%4&U~E9u_7dth3TcqJyGG0s`}{7YNpeK<9l zGAmr}i&IaZgW02%x~CHCj)40f7?P@l_Xk5H%kcfA8V)}?aF*+qzDi z1Nk52r0Bx*T7qt5NyOM$Jl?nH^6$^ID0pS^^oX|;->bL zm2E#<3*etTDdHAwiI^f4V+`_R1WID=FC+8&*~FrClf=9Zl47y`jlqahdeLg@jB48l3sZ-|x>|55~*lUxRM_AF+Mu}|^ zki~Y$HrOJtJ??Q;z>Rm*-#Nr;B3Li?lRp#fnc~4qKm&_~<{%qCm^35Lo`76%r^6W4 z6-v(CZQ7kPj@Hf^LkxsPaAFcha+9E;2EfFb8(A$0L^U!XM_CzyFG_`_uukaj2$g>{Gs@WfAV@bFd!3S!bufP|$~p_J)}vnO?m- z(O|w>xRoyRtlL*zOw>*;a6MmSFV+LS;*cV_5NopOC`w}m?7?LG!YiL9#Eo_C_Xpo%oGly zAcZ$&>-r5HP5_pHwYBbln0I~}stSfih!YF7!~{FW_ripQdfVe;y({NcR4*L)zV~6E z`jZ%1?@(mT2RXW=YPr@iw>dodFQ>^Um_nhQvSiTE*UE&mAw^*+ibIa%+Tt^kvNVhurgTR*T2;lk*cQP)8Xevv@~-Xhxy zv9|G@TX=EDjc*TU+;Ysx$q~8*QJAufT_TA$Kg3Z+^HzJTL={0QeRd8SV5+5;XU!iz>^VR?FM=rHf~&3`X`TPTiI)>$#CUa z*QzlfR#U7R5F67S-Q3KZ1X-6bHeUH)YK1oPh^bZEP+uIz!{D#e(|SAq4BeR-2OL6* zV#nnky$Das_*|l!*tSA^$Y$n8l*}N(WpAaNA!LOQ32Va{Rx4k>Bh$tYNLVcVW1d-g zVJkL(T0{?YbNMP;H}kl!N34TfP*^zv9tJCWVEr7&;hZltg!3ufD;V zKZlprG0E7aHH%v>e1wF~Gs5`5WQSr_IJO=u5yQknUnABvV#Om`I^+F5Up^&0dQEXI zY#XqM*uwo;gnK{F z+|k3acmwiyfZ~905f@?-68Z)feB5%uJXSZd@Yvk*VdVaM4<2lA?q6g-8Kc<8;--u< z!9@q~a0`tcQpeu!HbWS-os9;O*AZTxy!q^4Z?8CgdN5yme!O{rW&A}#g3&3=B(J6p z@-?%tCW%(u8WGeltIJq$LJouLpMEQkhYjR2$?^233vCTOlMY4=Pv0i@Vz=r@~XBLhg5Lsle%XiLR z*0ZVs`A+;s4KVSclJGP><8TQs#PXfLIi|LBYs@B<>lqjXUX?TX?wWb&7badq9UQ9H z+|SF+HHIcZBH_)W8=`DwVls!58G(IhnEMo)i$Ed96fa5cnw1Uf-qh3>0H4~Y4Bo$Q zUp{`E3ji;KALEq9Kpu6e-GJ4@W0E*+0XXNWh3>B|+SJS>5!bgD?P#*yZ<2B+iLk$m zZ(0g|ib8DCG@HmmWJ)vJaN7O|_#J*Z{$gaL3A|`*>5KH?yB&jNPOG!-uCaizcr0g(Ca1C&jc+3(+1O zJwAS8B+#qRejKVEQ#FK~-iDnq62E-9oPF-+ojio+KDKuX&H3+6G!opTb^|#nk4eIn z#8@dXyi%l?Hs^R4zulGD8Atva;s6$=5U8gkqRfd09ByKD+u6wZM+V)uL){U+*M$9= zH2Viwr=q79;onEPJzkCn2xOzDO#|)XpVN5g`nNg9O0YxS-*A&@W#{pefKc*sLVq-KAAPtbHOZ>jV1n1Am^eX-RoT{FypFTIek zj^)bT*$)IsfUDy|eCM#F)#SA=XaS5)3F|h-voe3a3%Ovbq#I#;4A=-6>tfSdBA3|I zB<ROvhvi7x0Mm>Ia)db7*Z5slrvoI595&OvN)(eY^i!T@|e#q&e(I+>Qtshun z=|-Ef&9whkBA9cpbB2oR5ZB?rFk)OYs*)%+GugP+=@>_wa)Gfz*(-F!ueJ;SWf6h6 zba&ZFgb01UN|1h41uI#g*hUR#V7sXag|2q>^DmA-YFf{zNsr<+#hTeY)Z{?#2gC;F z!x}*I`Nd2(aPSJ!Ki|;T7N+?D>)#hkS#;RD$5cs{?Z}}%KEgetOW$!lb2S>DZ>GO; zX=<)$UC3QKt~W|(Y)C$q<*HZvSPK~xV}T!unBPks5|jH`GT`pW(La3ePkPap19mSw1ymL}c=XnCHQt2$bF#xejF z!1Q8B%GS-rNzX@kCJ@0>L$%u&~U3Xi|@j0MA-+~0a~+{9c; z$vEHP!-xM_R+fIpnTtu#7G9Pp!|pCq%jdU=by7gyW26(f&SK5TqygPn2>Td*LM*`Q zW&QKV53$B)Uw|QJ$JVXR%W&hXTVBG+6=|;a_q?Ttxs*qrk^ zrb^Rye7&HU%6Y>&(Ez@~)XGYq9w(9qxQoS2pqsl7A0DAf5GRuanMqwJHG9kO&s9}= zJRm{Vvh8Oh5ctjsKbpPl9DfwR^cCODy3b*zU<+XP$P57_K%PYw@5p)1UwIB8b=3a!+-#12Z#c2_KkM zYW4OS^ft_RVn3eMzqJqh{gOb=rz!i-J_Y4V@EU?{&5(ENE{* zh(Uj=HNba2AM(SgwP(XX#CRWI4q~eNf?;}DYp<@B_L45B1w6aQoOU;oTHdi*gKZ_coPgf+XLjJ_mh$rQkF*=#X(fd5 z5ORbg&`}|0*5I6bK{YBdF;ck4lCeG_o4Zg_{gI=|eerT{HS&z5=trX(vG(i^F;=$4^c>zb;&M9IecF^xp@-pMLl}T7@V4*)9Ic3sMHA!i-;g#g_vC#dyE{_ScWPZ4up_($uW;gXvdJu_J}tEg&+ zFk^7OK8T{kr6##V4a*0R)hSC}l$2b%>wanZ4A+xV<7tuepbl7L^g^XMXklc)CtI8j z)cSR021RSrrZ00Ad4PPmfLx%?D&FX>g@lK$G|W^9V-{~B*R_*A=jvKYkQ5n(<`22i z(&WH6;LAV@n;jqQ#AG5LFg&I5&tUG z2&6>XtL^kN58pT6`xi#$pv4i(+67)iqwMB+dx+H_>&tn;Ank(S z{jg=aVxYlPi^@GQPHPj4qi1V}cQsTB)N}SPQ&Y2#9wZqyXF0B_418$66{A4NbJ|L% zCG$TyYbaH^j_o5|cjULmx46W_sXx=nV#0h!NFp}B>ne7{NL&c$qdNXRQKcVQsQb>* zdjG|D6^l1-Wihajda!p^e_=1AdMcf}9@gBl*|Jo{AbF}u^^?@o3lsw4{GuC1Q4Q6Y zg&AI5yw*4A)TtF}{RG4e2fGrvmH%`Hw+ZFJ(;Xhdvld=lZy#UYvCJODh@oO1vB;Ov zg04avBTP~i7M(rJBRK*z(8ImeJ{~|d=lSzN0_fb2(pG40#M~>72c`j$Qw%nPQlEsS z4B1uqyrslOkk+(k`fZC+8n*kDmRz07?_79x<^in6)QxuwPadIGJeH!f^OM|7`HxRf zayZfFBG2fY7sF8Fa?TS7h+W~fl8;+x-TiCAjH8#S^&2uRl|^%7g$puY!lYjcQnybP zS@JyDuU{S%;98DYjVe~ho*%=(HcCx>@?=@)=JBV38;pb- zK$xLWn?U1iykbq-3C`TPa;C2In&fQ~Nf#|$ZB0{$2c46QqmLi|1{bwJVGd0$IoRtJ zv>hSD|K=k_KwY5fI|vI3A{WWO+V>0kmRYvhA&Z8J0Yt`A3eKEmNeS zZ%4ZT*ge^*WJAH@ZFMjYCAJ>ErKOgyx_6QRa*Ds}_~vS0_OhFF^V*|3Lp{iCn1~&T z?!jsz5ooS!rp>xVJi46t{dy7h*QPg*MQ3>Hf^NXbJy)$&=Aq*t>3UD8v84eNpWD?n zP4UvyT@I1Un|JkN>f*%nVg7el3FMp~ZL#n?-O3|M|veR`HJ!w?19&i(4vO{$FQi$iXo8PFPq~ z?+UnX>9R`5_Hh0bo01{f_w_!966spCW(gHXcaEc&)}#RQdIb`J=T%hx&qwT9CQaU9 zN_Na~1pYmTEN45I_W}inqIp|p&767k%o$(4=JJ!QTm`A#%V(^lMv({+#0okWd|pih zEHZs_eElZ%k`dq!dd(>%LY}l+UC)Zsg+SA&e5Z>G&dNW-64aPym!}_#{;)DY zdmrl{+i;N_zkO%Eat}>Dh6VC;WH?%)iT z);DOUh3kQznTHq^q|913X+TdI5}^_Mjy^e}u+8C-)%IAV{&OUI)%GzBFHB4x)Y?)y zgg4M*d#w$1?2WzQu?xXoec4FrWZYwq*K?(UhF+yJ`)aBj7V6}0|ulkub^&N;+@jOTWA>%wilyDdUr(Z*G3#O`S*XkQu*9`|o^S zR9r0feF)@$Grz;t)gNC?W+!}Xq!xjiQBC{PWdCex@;8pYz`;K>!9-{7T)hdZJSH-d zVL7MAhv`%X{RG!n)yqe9@b>@|y&aVgOFesU%LmvAsqeXsReg-fu$Nf zLm3u?F_?~O%fQ0y^z?KS+?E8qgARj0IOlkNc-{7};IB*wvtyzE){l?9sG3DXow zR=Uv`2{Z*qD0q_L_?ZQ3c-&A7^P;KaNX<9CJg{pA%d{_Gj1dE=jADe2cNdGshn-qr0vciG zykzg*y*hVAlRsY};24_K>*?tMpdes8&MC7So(350ocY)Nr=eSlrjH+wZ>B738NGq+ zXe>us+!jcEvSl}_xx3AOpr|B+i=p}bcFC4#{d+Jlj>>8d%{6!L<*Qf2Tw5|>J#Myo z{CvS?*MaaGdr4sYOQv5x#p}{8p!-zGnhF77q*;7|j#;;#q7qW~JMtn!fnis!^nz){ zYBOom+X+NTgeGGA05i+G+j}FTtr{Zdv_Vkp5l}rKwSs;edvCyUJfEOO_x_(Z) zc_k9~eEVcU28$N$ROrIUIVcm=4Cwv9OKv`Uw&Z*2L8x510)XRDWvYDd>1Vogl*zii zQjCbv2*yRCGuK#%p3#RC(XVRyY}#~bQ_!CuAUO601oY-%3)wK5 z;E2S!Z`CSfh*VKS2%f^7Kv+kS?WX?xGYlFCz-qR(OI36viPMOYL%Y9UrlcfHI`?f? zI$SNB{o>8LAccUv?(CNbD$I@x0i*_84WdU7YMcgHlkM$LPX@<-Lw82`(YdqAf}%y0 z?w7`Z&nw7>vDxVO_x5ucKOtt?eO1vmX|{mg_nKkSVXv^{7M43aP!Mxg&$AA1bqo~3U{sF zhsM|^Tc&=?Kg!$RZMnrNq14_bC(>8u&ZzI!8~}(f=%onb<*;oJR3Zz2Ar>ecTW4*{ ziQ|&Z<%k%lmjYq8K@x)EX6a+UskK&Hrk`17yMD{^fjkeMM5ufZBIqriobN7MNxppl ze2S(upZy1fTB~g>iGJl2cj1B*KmkIcIsD4;%Wm#A&m6d#@|h1zNoEupS+Gv{1DwaW z0{Y&+ahidhTgQ?pr;62|yqT*6v&D$9;&t7z%Xw`C;oLCVp`Z2mVt)|6*KBFZWBo(w zgq9q!jgA$9{lT^0-diTv;C}xilm&I&tjY!+hJd=xgg1pPhTi@Udp+Q_>8F1Z-nswp zne6|aVE_B0{p0Qa3#tC!DDwZj;@=ecQ``Hk?QT`5ZH}>Cx>>@1bafVLCulA6{9k~x BYhVBX literal 0 HcmV?d00001 diff --git a/Networking/LPT communication driver/index.html b/Networking/LPT communication driver/index.html new file mode 100644 index 0000000..cf57632 --- /dev/null +++ b/Networking/LPT communication driver/index.html @@ -0,0 +1,606 @@ + + + + + + + +LPT Communication Driver + + + + + + +
+

LPT Communication Driver

+ + +
+

1. Overview

+
+

+This is weird networking solution. It allows to send data using +parallel LPT port serially(!) by bit-banging between two connected +computers :) +

+ +

+Out of 25 physical wires in LPT port, only 3 are used: +

+ +
+
Pin 14
Carries a synchronization signal which uses a periodic +pattern (e.g., 010101…) to maintain timing alignment between the +communicating computers.
+ +
Pin 17
Functions as the bidirectional data line, responsible for +transmitting and receiving data between the connected computers.
+ +
Pin 18
Acts as the ground connection, providing a common +reference for electrical signals to ensure consistency in +communication.
+
+ + +
+

diagram.png +

+
+ +

+By utilizing only three wires and software controlled bit-banging +algorithm, custom, comparatively simple, cheap and long cable can be +built to connect 2 computers in a DIY network setup. +

+
+
+ +
+

2. LPT Communication Driver

+
+
+
+

2.1. Overview

+
+

+The LPT Communication Driver is a Terminate and Stay Resident (TSR) +driver designed to facilitate communication between computers using +parallel printer ports (LPT). This driver uses bit-banging to send and +receive data serially over the LPT port, utilizing only three wires +for communication. +

+ +

+Driver hooks into the system's IRQ 0 to ensure that system timer +always keeps executing it in the background. While operating as a +background process, it periodically monitors LPT port to detect +incoming transmission. When transmission is detected, driver receives, +decodes and stores it into preallocated 5000 byte receive buffer. +

+ +

+Applications can then communicate with the driver on their own +schedule using INT 63h to poll for and retrieve received messages, if +any. Applications can also send outgoing messages into 5000 byte +driver outbox memory buffer. Thereafter driver will transmit those +messages in background mode over the wire. +

+ +

+The driver is half-duplex: it prioritizes receiving over sending and +does not transmit while receiving. +

+ +

+During active transmission/reception, the driver can consume 100% CPU +due to busy-wait loops in the IRQ handler, potentially causing random +temporary hiccups for application running in the +foreground. Unsuitable for real-time systems. +

+ +

+Download: +

+ +
+
+ +
+

2.2. Data transmission implementation details

+
+

+When there is incoming data transmission, the TSR driver detects it +during its periodic execution in the IRQ 0 (timer) handler, which runs +approximately every 55ms. +

+ +

+Driver checks for possible transmission comparatively rarely (every 55 +ms) and for this reason it is important to have quite long +transmission start indicator/header before actual data is sent. This +allows long enough time for recipient computer communication driver to +detect that transmission line is active and start listening to it now +in exclusive busy-wait loop. So, the TSR driver steals 100% of the CPU +for the duration of transmission. +

+ +

+The start of transmission is detected by reading the port (37Ah) +value, and checking if bit 3 of the raw input is high. It then enters +a "skip header" loop. Once bit 1 goes low, bit reception begins. The +end is detected via a timeout: during bit reception, a counter +increments on each poll. If there is no change in the port value for +30 consecutive polls (indicating no new bit transition), it assumes +the transmission is complete, appends a 2-byte length to the receive +buffer, and exits the routine. +

+ +

+So, both receive and send routines execute within the IRQ 0 handler +using busy-wait polling loops (for receive) or timed output loops (for +send). These can hold the CPU for the full duration of a transmission, +as the handler does not yield until complete. +

+ +

+It bit-bangs data by treating the LPT control port (37Ah) as both +output and input, using bit 3 (pin 17, data line) for the serial data +bit and bit 1 (pin 14, sync line) for a clock that alternates (low on +even bit indices, high on odd) to signal transitions. +

+ +

+For sending: the port is first set to 0xFF (all bits high) as a +header, held for ~110ms (2 timer ticks). +

+ +

+For receiving: after start detection, it polls the port for value +changes (transitions). On each change, it reads the port again (to +ensure that synchronization bit did not arrive ahead data bit over the +separate physical wire), extracts bit 3 as the data bit, shifts it +into a byte accumulator, and resets the timeout counter. Once a full +byte is accumulated, it stores it in the receive buffer. No ACK or +error checking. +

+ +

+Driver can receive multiple transmissions into its 5000-byte receive +buffer before the client program reads it out. Each incoming +transmission appends its data bytes followed by a 2-byte length word +directly to the end of the buffer (updating dbufsiz to the new total +used). As long as the cumulative size doesn't exceed 5000 bytes, +multiple can queue up. The buffer acts as a FIFO for concatenated +packets; overflows are not handled (it would corrupt without +checks). The client retrieves the entire buffer contents at once when +polling. +

+ +

+When the client program reads received data from the TSR (via INT 63h +AH=2), the driver copies the full buffer contents (up to dbufsiz +bytes) to the client's specified ES:DI pointer, returns the byte count +in AX, and immediately resets dbufsiz to 0, clearing the buffer. This +ensures the data is not served again on subsequent reads, as the +buffer is emptied after each retrieval. If no data is available, AX=0 +is returned. +

+
+
+ +
+

2.3. Driver API

+
+

+The driver uses INT 63h for its API, with functions selected via the +AH register. It maintains two internal buffers: +

+ +
    +
  • Download Buffer: 5000 bytes for incoming (received) data. Multiple +transmissions can be queued here, each appended with a 2-byte length +footer.
  • +
  • Upload Buffer: 5000 bytes for outgoing (to-be-sent) data. Data is +copied here and transmitted when the line is free.
  • +
+ + +

+Communication is polling-based for applications; the driver handles +transmission/reception in the background. +

+ +

+No error checking, acknowledgments, or flow control; it's a simple, +unidirectional-per-turn protocol. +

+ +

+To use the driver: +

+
    +
  • Load the TSR (e.g., run lptdrv.com).
  • +
  • Activate it via the API.
  • +
  • Poll for received data or queue sends as needed.
  • +
  • Deactivate when done.
  • +
+ +

+API overview: +

+ + + +++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AH registerAPI function
0Deactivate the driver
1Activate the driver
2Retrieve downloaded data from the driver's input buffer
3Upload data to the driver's output buffer for transmission
+
+ +
+

2.3.1. Deactivate the driver

+
+

+Disables the driver, stopping background monitoring and +transmission. The LPT port is reset (set to 0). +

+ +
    +
  • AH: 0
  • +
  • Parameters: None
  • +
  • Returns: None
  • +
  • Side Effects: Clears the enabled flag.
  • +
  • Usage Notes: Call this before unloading the TSR or when +communication is no longer needed to free system resources.
  • +
+
+
+ +
+

2.3.2. Activate the driver

+
+

+Enables the driver, starting background LPT port monitoring for +incoming data. The LPT port is reset (set to 0) upon activation. +

+ +
    +
  • AH: 1
  • +
  • Parameters: None
  • +
  • Returns: None
  • +
  • Side Effects: Sets the enabled flag. Existing buffer contents are +preserved.
  • +
  • Usage Notes: Must be called after loading the TSR and before any +send/receive operations. Can be called multiple times; redundant +activations are harmless.
  • +
+
+
+ +
+

2.3.3. Retrieve downloaded data from the driver's input buffer

+
+

+Copies all accumulated received data from the driver's download buffer +to the caller's memory location and clears the buffer. +

+ +
    +
  • AH : 2
  • +
  • Parameters : +
      +
    • ES:DI : Pointer to the buffer where received data should be +copied (must be large enough to hold up to 5000 bytes).
    • +
  • +
  • Returns : +
      +
    • AX : Number of bytes copied (0 if no data available).
    • +
  • +
  • Side Effects : Resets the download buffer size to 0, preventing +re-retrieval of the same data.
  • +
  • Usage Notes : +
      +
    • Data is retrieved as a concatenated stream of all queued +transmissions.
    • +
    • Each transmission in the buffer ends with a 2-byte length word +(little-endian) indicating its payload size (excluding the length +itself).
    • +
    • Poll this function periodically in a loop to check for new data.
    • +
    • If AX=0, no copy occurs.
    • +
    • Example: In assembly, set ES:DI to your receive buffer and call +INT 63h; then process AX bytes if >0.
    • +
  • +
+
+
+ +
+

2.3.4. Upload data to the driver's output buffer for transmission

+
+

+Copies the specified data to the driver's upload buffer for background +transmission. Transmission occurs when the line is free (no incoming +data). +

+ +
    +
  • AH : 3
  • +
  • Parameters : +
      +
    • DS:SI : Pointer to the data to upload.
    • +
    • CX : Number of bytes to upload (must not exceed remaining upload +buffer space; no checks performed).
    • +
  • +
  • Returns : None
  • +
  • Side Effects : Appends data to the upload buffer and updates its +size. Transmission is asynchronous.
  • +
  • Usage Notes : +
      +
    • Data is sent as a single transmission (no automatic framing; +caller can add headers if needed).
    • +
    • If the buffer is full (total >5000 bytes), behavior is undefined +(overflow).
    • +
    • Multiple calls can queue data sequentially in the buffer.
    • +
    • Transmission starts in the next IRQ 0 tick if the line is idle.
    • +
    • The driver adds no footer; the receiver sees exactly the sent bytes.
    • +
    • Example: Load DS:SI with your message, CX with length, call INT +63h; the driver handles sending.
    • +
  • +
+
+
+
+
+
+
+

Created: 2025-08-04 ma 02:12

+

Validate

+
+ + diff --git a/Networking/LPT communication driver/index.org b/Networking/LPT communication driver/index.org index 5ba91f0..cb82b14 100755 --- a/Networking/LPT communication driver/index.org +++ b/Networking/LPT communication driver/index.org @@ -26,6 +26,7 @@ Out of [[https://en.wikipedia.org/wiki/Parallel_port][25 physical wires in LPT p reference for electrical signals to ensure consistency in communication. +[[file:diagram.png]] By utilizing only three wires and software controlled bit-banging algorithm, custom, comparatively simple, cheap and long cable can be @@ -33,6 +34,7 @@ built to connect 2 computers in a DIY network setup. * LPT Communication Driver +** Overview The LPT Communication Driver is a Terminate and Stay Resident (TSR) driver designed to facilitate communication between computers using @@ -52,40 +54,195 @@ any. Applications can also send outgoing messages into 5000 byte driver outbox memory buffer. Thereafter driver will transmit those messages in background mode over the wire. +The driver is half-duplex: it prioritizes receiving over sending and +does not transmit while receiving. + +During active transmission/reception, the driver can consume 100% CPU +due to busy-wait loops in the IRQ handler, potentially causing random +temporary hiccups for application running in the +foreground. Unsuitable for real-time systems. + Download: - Source code: [[file:lptdrv.asm][lptdrv.asm]] - Compiled binary: [[file:lptdrv.com][lptdrv.com]] +** Data transmission implementation details + +When there is incoming data transmission, the TSR driver detects it +during its periodic execution in the IRQ 0 (timer) handler, which runs +approximately every 55ms. + +Driver checks for possible transmission comparatively rarely (every 55 +ms) and for this reason it is important to have quite long +transmission start indicator/header before actual data is sent. This +allows long enough time for recipient computer communication driver to +detect that transmission line is active and start listening to it now +in exclusive busy-wait loop. So, the TSR driver steals 100% of the CPU +for the duration of transmission. + +The start of transmission is detected by reading the port (37Ah) +value, and checking if bit 3 of the raw input is high. It then enters +a "skip header" loop. Once bit 1 goes low, bit reception begins. The +end is detected via a timeout: during bit reception, a counter +increments on each poll. If there is no change in the port value for +30 consecutive polls (indicating no new bit transition), it assumes +the transmission is complete, appends a 2-byte length to the receive +buffer, and exits the routine. + +So, both receive and send routines execute within the IRQ 0 handler +using busy-wait polling loops (for receive) or timed output loops (for +send). These can hold the CPU for the full duration of a transmission, +as the handler does not yield until complete. + +It bit-bangs data by treating the LPT control port (37Ah) as both +output and input, using bit 3 (pin 17, data line) for the serial data +bit and bit 1 (pin 14, sync line) for a clock that alternates (low on +even bit indices, high on odd) to signal transitions. + +For sending: the port is first set to 0xFF (all bits high) as a +header, held for ~110ms (2 timer ticks). + +For receiving: after start detection, it polls the port for value +changes (transitions). On each change, it reads the port again (to +ensure that synchronization bit did not arrive ahead data bit over the +separate physical wire), extracts bit 3 as the data bit, shifts it +into a byte accumulator, and resets the timeout counter. Once a full +byte is accumulated, it stores it in the receive buffer. No ACK or +error checking. + +Driver can receive multiple transmissions into its 5000-byte receive +buffer before the client program reads it out. Each incoming +transmission appends its data bytes followed by a 2-byte length word +directly to the end of the buffer (updating dbufsiz to the new total +used). As long as the cumulative size doesn't exceed 5000 bytes, +multiple can queue up. The buffer acts as a FIFO for concatenated +packets; overflows are not handled (it would corrupt without +checks). The client retrieves the entire buffer contents at once when +polling. + +When the client program reads received data from the TSR (via INT 63h +AH=2), the driver copies the full buffer contents (up to dbufsiz +bytes) to the client's specified ES:DI pointer, returns the byte count +in AX, and immediately resets dbufsiz to 0, clearing the buffer. This +ensures the data is not served again on subsequent reads, as the +buffer is emptied after each retrieval. If no data is available, AX=0 +is returned. ** Driver API -*** Deactivate the driver -*Parameters*: -: AH = 0 +The driver uses INT 63h for its API, with functions selected via the +AH register. It maintains two internal buffers: -*Returns*: None +- Download Buffer: 5000 bytes for incoming (received) data. Multiple + transmissions can be queued here, each appended with a 2-byte length + footer. +- Upload Buffer: 5000 bytes for outgoing (to-be-sent) data. Data is + copied here and transmitted when the line is free. -*** Activates the driver -*Parameters*: -: AH = 1 +Communication is polling-based for applications; the driver handles +transmission/reception in the background. -*Returns*: None - -*** Retrieve downloaded data from the driver's input buffer +No error checking, acknowledgments, or flow control; it's a simple, +unidirectional-per-turn protocol. -*Parameters*: -: AH = 2 -: ES:DI = Pointer to the location where downloaded data should be placed +To use the driver: +- Load the TSR (e.g., run lptdrv.com). +- Activate it via the API. +- Poll for received data or queue sends as needed. +- Deactivate when done. -*Returns*: -: AX : Number of bytes downloaded +API overview: +| AH register | API function | +|-------------+---------------------------------------------------------| +| 0 | [[id:a7aaa0e6-92de-467c-bcd4-b3d3216b15d4][Deactivate the driver]] | +| 1 | [[id:944be7b6-d3ba-486a-98bd-1a66cfffe6e5][Activate the driver]] | +| 2 | [[id:49350196-55b9-4d50-b672-b3c6d6d55e53][Retrieve downloaded data from the driver's input buffer]] | +| 3 | [[id:53fd0c68-4057-4e9e-b908-87fab6eab5c8][Upload data to the driver's output buffer for transmission]] | -*** Upload data to the driver's output buffer for transmission +*** Deactivate the driver +:PROPERTIES: +:ID: a7aaa0e6-92de-467c-bcd4-b3d3216b15d4 +:END: + +Disables the driver, stopping background monitoring and +transmission. The LPT port is reset (set to 0). + +- AH: 0 +- Parameters: None +- Returns: None +- Side Effects: Clears the enabled flag. +- Usage Notes: Call this before unloading the TSR or when + communication is no longer needed to free system resources. + +*** Activate the driver +:PROPERTIES: +:ID: 944be7b6-d3ba-486a-98bd-1a66cfffe6e5 +:END: + +Enables the driver, starting background LPT port monitoring for +incoming data. The LPT port is reset (set to 0) upon activation. + +- AH: 1 +- Parameters: None +- Returns: None +- Side Effects: Sets the enabled flag. Existing buffer contents are + preserved. +- Usage Notes: Must be called after loading the TSR and before any + send/receive operations. Can be called multiple times; redundant + activations are harmless. -*Parameters*: -: AH = 3 -: DS:SI: Pointer to the data to be uploaded -: CX: Number of bytes to upload +*** Retrieve downloaded data from the driver's input buffer +:PROPERTIES: +:ID: 49350196-55b9-4d50-b672-b3c6d6d55e53 +:END: + +Copies all accumulated received data from the driver's download buffer +to the caller's memory location and clears the buffer. + +- *AH* : 2 +- *Parameters* : + - *ES:DI* : Pointer to the buffer where received data should be + copied (must be large enough to hold up to 5000 bytes). +- *Returns* : + - *AX* : Number of bytes copied (0 if no data available). +- *Side Effects* : Resets the download buffer size to 0, preventing + re-retrieval of the same data. +- *Usage Notes* : + - Data is retrieved as a concatenated stream of all queued + transmissions. + - Each transmission in the buffer ends with a 2-byte length word + (little-endian) indicating its payload size (excluding the length + itself). + - Poll this function periodically in a loop to check for new data. + - If AX=0, no copy occurs. + - Example: In assembly, set ES:DI to your receive buffer and call + INT 63h; then process AX bytes if >0. -*Returns*: None +*** Upload data to the driver's output buffer for transmission +:PROPERTIES: +:ID: 53fd0c68-4057-4e9e-b908-87fab6eab5c8 +:END: + +Copies the specified data to the driver's upload buffer for background +transmission. Transmission occurs when the line is free (no incoming +data). + +- *AH* : 3 +- *Parameters* : + - *DS:SI* : Pointer to the data to upload. + - *CX* : Number of bytes to upload (must not exceed remaining upload + buffer space; no checks performed). +- *Returns* : None +- *Side Effects* : Appends data to the upload buffer and updates its + size. Transmission is asynchronous. +- *Usage Notes* : + - Data is sent as a single transmission (no automatic framing; + caller can add headers if needed). + - If the buffer is full (total >5000 bytes), behavior is undefined + (overflow). + - Multiple calls can queue data sequentially in the buffer. + - Transmission starts in the next IRQ 0 tick if the line is idle. + - The driver adds no footer; the receiver sees exactly the sent bytes. + - Example: Load DS:SI with your message, CX with length, call INT + 63h; the driver handles sending. diff --git a/Tools/Update web site b/Tools/Update web site index acd87ee..f162ed4 100755 --- a/Tools/Update web site +++ b/Tools/Update web site @@ -43,6 +43,7 @@ export_org_to_html "Math/Truth table" export_org_to_html "Miscellaneous/Mouse driver" export_org_to_html "Networking/Digital data over analog audio" +export_org_to_html "Networking/LPT communication driver" # Upload project homepage to the server. rsync -avz --delete -e 'ssh -p 10006' ./ \ diff --git a/index.org b/index.org index 59e8acf..ae99e95 100644 --- a/index.org +++ b/index.org @@ -888,6 +888,12 @@ How It Works: Download source code: [[file:Networking/LPT%20to%20COM%20port%20data%20transfer.bas][LPT to COM port data transfer.bas]] +** LPT communication driver + +TSR driver that allows 2 computers to communicate over parallel port serially. + +[[file:Networking/LPT%20communication%20driver/index.html][Read more]] + ** Data over analog audio CODEC Utilities to encode digital data to sound file and back. -- 2.20.1