@L}5 _$% l0$)$$Hȱ$ UhL" `e$$%`$%`  R@P!( L(1   Y I`  d  Ld M * @  $ % CC$$)%1 Udߥ$9%: !0 S$% DD˙`  }J)Lr d M * @  $ % CC$$)%1 Udߥ$9%: !0 S$%} DD˙`  }J)Lr J  ((  p L ()   J}L= ( L 0q A    IB JC;? D W } LL  ` W )LA!  ߰")-݆ p" } $G@LL 08`Q")<2Q0 -G$Ș݆ UL# ; p8(()(0ʥ)NQ` }$GȘ݆LU )L ݆ L GȘ ݆LL )W>Z   HH)H }p h  hyhy D L> L JJ    ! LA*` BF }7'8  M HN H` 8 Z  \LdJJ!"! GFE@F (!L }EE !E^ ^ E E7EȩEdE/EȩE  D } .L }  ;F d  ;?F7F? ( .   Z D LL d } . D  L    p  E` , d)  D L) 0BM݊L݉} ML  N݆ L NLML [ TEqEHȱEqEh 0Gȹ G} HLL GɛL  LFREIE SEKT.  G) *Gȩ GȽG GȌ*jj >G}J,}Λ "J\DOS SYSCOPY3TO2COM/}B}B}-}CDOS SYS `----------- `-----------`----------- `-------}---- C C*(> C8jJ3j2CD( C202C ԠBX` N 1? l LlD:RAMDISK}.COMLu L1 L ;LHL  T`  `8  ɐ     `TU  } L ? .  t`GBJ ~DEHI B V0dV!}QDEHI VF9 ,0 ,0 s0hhL  L` H hDHEh"}DEL8HI4 0 HI,0 0  9 .G VLO#},0 L4*IJ`llD1:AUTORUN.SYSLADEN NUR MIT MEM.SAV MOEGLICH.D8:MEM.SAV J y08 B|DEHI$} V0 0`B;DEL`?<0LV`@ʆ v s? F0Ξ05: [ BDEHI%} VJ8 B V  @  /DE `E:D8:DUP.SYSPROGRAMM-SPEICHERUNG FEHLERHAFT!DOS DENNOC&}H LADEN? >J/N B;DE J  (` 9 V⪍ ઍ  -'}LLu ÝDEHILV 9 .l 9 .l  `` s$B BH(}I|DE V BLV nB,DE JLV B V BLVDEIʩ BꭝLu } 3E:}DISKETTEN BETRIEBSSYSTEM II VERS. COPYRIGHT 1985 ATARI CORP.A. DISK-INHALT I. FORMATIERENB. ZUM STECKMOD*}UL J. DISK KOPIEREN C. DATEI KOPIEREN K. BINAER SAVED. DATEI LOESCHEN L. BINAER LOADE. NAMEN AENDERN M. START BEI ADR+}.F. DATEI SICHERN N. MEM.SAV ANLEGENG. DAT. FREIGEBEN O. DAT. KOPIERENH. DOS SCHREIBEN P. FORMATIEREN ӛL !N',}#"&))9(&*)/h)''-&؆莟R'S  vL/ˢ L }DOS 2.0s EINLEGEN -> Y, x -}DEfHI 1莏#q! @ y0ɛ8A0,' ȅ 1 1ild! 1L!FALSCHE WAHLBITTE .}WAEHLEN, -> MENUE! 0 .z:*{}.|{ 1 0 0JB 18L%|DL/}%INHALT [SUCHBEGRIFF,AUSGABEGER.]?[# 0 0 &|D3" 1L!KEINE DISKDATEIN !B 1L!E# 1 !BD0}ED:}:1BJ|DE 1DEBHI 1 h0ߢ 0.1}  0?詛 1 y0JЛ 1 ;#L" ;#L! BL1->J ZUM LOESCHEN... LOESCHE DAT.NAME2}KOPIE-VON, AUF?DAS KANN ICH NICHT161 FREIE SEKT. KOPIERE---D1:PACCRS.COMl# 0|D .L/%#3}##JB|DE 1BHID#E 1#0: B 1L!#͑### B 1#c$0SY4}S1}:## # # .#Ƚ# # 𩛙## 1,#PD#ELJ- <.BJD#E 5}1 1HH 0hh|DL%1}:̳# L% #D#EL% 1 0 . .0O% 1L!KEINE 'WILD CARD6}S' IM ZIEL-DATEINAMEN 0 <.|K}N 2 FORMAT. t* 5) 1L!`) 0NΞ 0 L1) 1 L!FORMATFEHLER!WELCHE DATEI LADEN? ) 0 ?}0#B 1L!SICHERN DAT.-NAME?) 0 0$B 1L!FREIGEBEN DAT.-NAME?DUP DISK-ORIGINAL,ZIEL STAT?PROGRAMM-SPEICHER BE@}NUTZEN? (J/N)ACHTUNG: MEM.SAV WIRD DANN INAKTIV.FE! +L1   `*  70 2 2A} 0.* 1 y0 0)BEIDE DISKETTEN EINLEGEN, Ԯ^, 1 y038逍 N, 1L! ,B}C, t*  Lx+, 0 ^, 1 y0 , ,0,0 ,L+ ,I0 ,Vǭ0C}Ξ, 0 }, 1 y0C,ШC, 0K'!" H H 'h h Lx+!EF 5L1L!D,I,HhD}` ZU WENIG RAM! ORIGINAL EINLEGEN, ZIEL DISKETTE EINLEGEN, E}`  `8 rL1`-* 1P* 1 y0J`hhL!UEBERTRAGE DATEI:...?- 0 0|DL% <.F},^ 1 70 0 .@L# .BJ 1  DEHIB V L1 ,} 1 70,L.  G}JB|,#P#DE 1 HI BDEHHII 1 B 1 ,^ 1 70,0La- B V,#PH},^ 1 70 0L#L!-* 1P* 1 y0Jj383}mm ݭI}}`8}``|* ? ɛ,`|:-)| / 1L!`DOS.SYS ALS ZIEL VERBOJ}TEN! 0 0H{ 24Δ 28/L!/) 2 Π 2 0 ξK}hAΞB,0 J 1 BDEHI,HÝDE 1HIHIDELSAVE-DAT.NL}AME,START,ENDE(,INIT,RUN)O S0 1`BDEPHI V` S0H 1 L!M}0 0 1L~0`BITTE NUR 1 ZEICHEN ,0`hhL! 70 1L0L<1 ,;ɛ7,"ɛ:ݦ1ݥN}A"D|ݤD|ȩ:|ȩ|ɛ,,(/+.ީ1 1,ɛ`轤{NAMEO} ZU LANG! B VL!` L1I H1EΝDL1|mDiE` V0`8d/8 i:222 1 LP}!ERROR- 139ɛ+,' 20*.. өr2 1``2EINGABE ZU LANGUNGUELTIGE HQ}EXADEZ. PARAMETER800 0 8 00`,0'D800 H,ɛh`2L1D1 - D8 ANGEBENuR} XADEZ. PARAMETER800 0 8 00`,0'D800 H,ɛh`2L1D1 - D8 ANGEBENu./ H.  . . . w/ . /*E' h `+",#-..-`++,`$"%#Ɗ$e* T}*)M$%`&-"+#,*$ %!ߥ$%$$-ʝ.-ަ+,++L.. U.? U.I0 U.I1 d/p/ d/p/2 U}/ S/*H S/h*-?? {.010?Np v~#x7W:O^oyKa!#%"4Iz(*,G0246!|8: b}<>+A;CEGIKLMO{QSU%$WY[]_anegijkk(mopqsuwy|&~? Zd`P@j ,fDU c}@rAu\ Dm_8ci㘪mzrpn:9C Fch|mq# d}lDsNe{3Mīcfƫ7=_(9Kei158].ހ!oWBTBԛB Z w>rK lCjV6@&q ?>69D] e}q8#~ˮNHuE"S W Fc_w& +ڬxxX( w2ݷ;f &r٤ړzm2Kx@󴍦2aq N^LPȨ" ' 6^]EyG0 !XTJNU h}>eHJ!4Kn՚W~Kw[a96I<+1IRHrNHME,Irahڔ9kd|{`<'y9'MR\Mo/ i}77ކӆߢCa CPG&}s6 fl&+/vշOp!GHM:aVhH&/kbԗv y-ޮ͛ j}ݞw ɝU`޿^ 4kd! u =B1 eZoDopiQmCZaR21[_{lf"SpSX+w[4C^h k}>qu,5и:Y;DO +/h lA୔uwU| kk u>!xϼ 'FFՀ^AjO"PBA"i%wE,5 l}k``6c=W!C78gi3;[j7"AV!c^TX&>:֣]6Ap` n}t8{x1.B.p.%LH>TA]d_%_& ,`W`ʼn耱IcWU8U9rwICP.5kcQѵ&!" }*A ca˺ o}]op;< zW,,g%cZa9_{bO_~ s]Nz<<s{9"Cb uo=h{$-aҒ07t: p}"IК20Ɗ+Jt}n0tUy4Βa(hڕ . 6paDBw:4,Ɗ˗[ KPV Y'&GJ: q}?tY<8ތ}Dsr{,1]!P&k*b3z|1+2R&?{ϻbtm(eLMX"GPUY@i5lƻӷj@B> r}) j.1CYƪ#Kj;Ͻ W g;w~ >!';Wٳu2YxUhӑLXQ9#FMC{Q4hЌ^ s}F x6_ _l &k*T(0y GxR\h }IMR0LԳb3L-$KX-qkCae| ;dEb3A"cn t}!ƈ@}) |CW[DPNHinCCُU3P,ؼ@#(!#˥h0xa`N {Q30J&8t(: w}6(+ 2ģVס | _6 Kh9Za'aSEC5su@'7i:GT,!_aǰ)z7r: Dog x}pTŢZTp27Pa@5R1lJ@\# N+с: uC11X"66J=JCd0/fY+ @, I X y}L`6Q R*"s}T26c>ɰ )!&f<.M_bg ̞A.&<Cl"7Y1C%FQz@2@?ܖb unKn3S z}p ? @ndu}B]4K"CA %`R ` zIpƤY-!n Sh" ˷ 0T*mX%.4WӅtmuJ {}uP!$< 눨}vh)i͵qw&EAbcZO=H.1sr(tyE1r#۶b%&(DYݤzD2L/!# \ |}3;:G ;ѷ>=ԇcF8w[~YSU<5@%v`LsF4mT7CÚ CU*>ay1<72*W[lcۤ }}'3F#r ˞8P%F6lt)"f;Нoƌ/͕60|0P`ہާ$crpP tzi9@:GfiF7~ ~}X𜰯c/7ljCql +=^74!V/64hgqC#Ք_=tz>Rar)BR$Oj]>q~7f$ޒ i`e`xLB }ʟa# Pd;5 4Ji M̈́#Km”~Wy ;&H7wv#oU=5a _zUl `cWjf\t%U4 }Fc]X\_6DŽlfi{!9 njI&#zlp?bV |jv4UCFy@6_ H(=AgfKD?omccU }$oJz~?f찍?s["5}~ZhF!Ý! 6͔<%y{vCk&uLfڢz@urрAF*IF4Қ6f4o j }^BZo墭Z`@/l~٩2dV_I)C{`pmo1h,6HlB>/ >_C툶kͲxo$I<j=# uCcl }6ߙ5}iV#kY-b>2er<'IG ZIbhtaL#+!ƍ$Ia 0QF8CPA%HKb+C JѭI }EEt-dK:YZKc0e E&QRe[kV+vWeVѭ6_B;#\Q [,$F_`KfKT,e<ﲄ{e~#[_] }3* 5yCEJB4FgxNr$#}"19)w}2['~/tAsFUdcX6PP|&ca]2DDmGɟ }YZ(Š.Xג}I9VIz1Y +.ՋEP $3EI&B`V#|dDf Bvd 2hvf'z(:>{{h2'n⃤LA }j d8U,eHC:d@}F-C$ġCIdmBT-Fw}"!BKIAeH:B }f;h/*=Q*k-}&$j($K£L%*. S% }EI$:ɞER[$B*!܇4aCPer2ER0.xCG#zORR^(}%ԘtLHxpvjpU_t{\$5B>b!JFj }jPgK^XۅQc$RL?)Hcn3Ҵ8i6^PQR;eɈ|^N)آ";LQhQآZL#[' TmB G[P ę } ũ.ʥ&3'&#IP@]dRZ^^bu d{Ѳ*/ Âeಎkm;^S'd'fBi0גry'd }y ^V)pQE(*MjK^EKŨאT>ʰU"ŊXqNk.;Q:!٤QTj%.FzNPEyF-Jb^Ey2F$Ѷ%] })e%Yl\݆^%]R[É2j4&@(F$3(`\If*xhѧ|x=\`R>D-;&1&'LNJe }CseWzFH"ƈX[CxJAL 7ι]ŋ Mez]b)"Jo5X$?)U"F7Ūai% ;L*8 t }$h('fS%:Xj8 K@bMV )ą3 !$-Cf#ZooX3%4@${7-| )@ X4 }!`@T(%K.AoPfLn|^VD50; `X׵+\sN 5ɫl0 tsQE+z_Y&E h9"Հ }Er4"@8L GL0,O< Ij8^tIR'Ӳ8(2 F#nX?R\7ϛ>w){F)0gC<Տ"¥& |02 / }PV°kh`<\6! ` L A3T5fjΊh5fD UIQF7Upn a| P@Xbt9Ț@z \H]* }A*yCv,|3W_ ]T$ u#TS%Uր sl@R:###8ydnO0:#"0l3+,N`q-& l ,UAQA4 }K.)$|#Զ0Fl0SCa 0WbB*lJ$/rNb,)fVo6'>sEHTNPL*!6 }fUG4m*Ę4toT@u`Ԁ\N3`Cm}/2"'kA; Ϙ9I<5R &gb/+rrwZ(:|( t>h:Z!+.⃭FuR K8 ҡtI~n }a o Խx$ @h;2¾Hp! uܚ}Cp H>|'QVZk2~q D&X 9rS)րDd`oR:dauGCȈ }(h>DsBR! փpt PK 4FM F4ٿ|+7ßO }<ןIw?6jYQRcEZ+!Rk9YE[⊰H))nTR+~%"7nj _1sU8hs8ȇ:"g`|6:)>0o }I6~747jl;8<]};;y܎;yܣh5GuP&Q_rn{ݰ{$ֆ.np6oCD:J!+m }[d~+{MiMnA9}Ao>[Efbe0š&Qь1A^%Š^Il7Ŏ灨x`p9 Mj,Zb|-# f5R}rGGF }\..6hT.hi "j".IJIUWW灁/ }0H  - }M(77 uMD.zb }FG7EUUD..hji`.jp"*.7dp 9cy 0[N&Oz;s "$& }+g( +-/13579;=k>@EACFYDeIKMOQjRTUUVX[\^`bdffiknprtvxz|!#-5:l ,`oC8aI }i!#% nJ{')^*F, .02Z468:<? QB DEGHVJLNPSWYZ]_aceghjlmoqsuwy{}~ p>|t{ }eea64B$%$$$%%vXIIIXXc@a%(/ y2y{yy/f@8/\o`rprrr  rо,R) qe'DB }8qnȄ _+*' @pRr @G+ALy34 A\  s` 4*' >D\pAv6Tw>UV :m*n?oUm>Pw mLV-uۏJݼ }nlpL<69pD%xY"0OJ. )i>c 6&ՠ֫e̓\;q%zA(ZעݹuvUa!G}А^ }t45S2IL^&ݹqLs񄢈Aq40Qun;rBջurwdqs B36ɷ˜ͯfylĤf^&2iH xbqw }8锹f׈̦сgdؑ1AJ˱u4ޒH|/K.J|`6S㵭F//EJoF#*S}db: Tկ)}P_>#Zo" }{TX7%JwTO~ z3iTqԖdvnC1q oK'R#9Jgz`9gLـ> f wg DCs?_'kD_ִ3C } <`ɞ)2ktAEn1J@ku) e u[ tAZdƌ11)Iz|=:k.\XцAL̨asS2Oɐ PW~zf3S1 }M Tҫ,tҥ,RvX"8<Ɗ x!Å$EB&*#SS|\ɼѦS9X"J=B da,A%@4ԙ2<Àv8 N<qMM }~2\)d`eL cX{DL6zf.<_O-Dji Zىk0V\G3+,e@4Ԁd޸ϰ& -KQZM"$MZM"Ex }yy4y׾;^믣>z=tx]v ӥh>{8CGG|w̦>8̦3)stsIAŀ`5W }t 00B4qJ..jvp.vP4UK[\YkGduWl Mr wnzmyvo7 "9=}#j>&(; }R*,F/612-A4679(;=,IABD$4FHJ!KOMN"3H^RTUVWXYZ\@^ PcefSjilop8rsuw0z|}Lə }л©bZ]VTc{XqCgas ~:tB<!+_$% }E''x)+-.0p1fŦ?D:<>?/@hCE%GIQLO. 2PQS e[]_`abd5gh|ikmnqJtvxy{ *~)`  } Ną<' C>|BX pU\&Z9/kom_3*u/w }tkr&(ڿCm]`^A0|vC8|=! TJ H||.šH ! A*Ġ|9>)> j^ }Nbp. 7uCv7oCv7k& xnۃvTv7iCv7rCvf ݮD7kaZ nw*w( ݎwLݓv nچn } 87n! ܀ݘv:Z,W/ES5Lp O LNT>>CB`7Ѹ>A>>$>a}- }CE,|>,> }r><>}Ѩ}^LKH>@ka`:N75ͼ>m*`4V9!3|h|5d>ca }|a|_>mC>r̜7݇@|Am:RdLEPNC d.A0d7Cpd@2BȒa$ hdRBd-Bd,@dJAa( }A; `ȡ xd/#2CȗFd!2."@d!2O`vʡNǡ?*`ġV!3h)Ű-d?a }a _?C?`]@ Am:!!ث܄BfK܎_M݊7tF<fѢde˒cE###*4L/ݙ, }|V{T 3 o^JfR pjBQH eŴ 2 Q̞ݲ ? tuȈ1G<\e|Ϝe }@p `쀌 97yO8|idL$sƃW=48sSD^dy*7џRI21 gZR]|ӯ@|I!()D S!jVU },/H`zBPW+fݛ~jsu>0KיIpI4gƴn@W׃XPlCyvIK SW";5 XaS? }P[/iێ/lP{?~?o~? ZVP7x`2ZMzD۲ԉpڲU߯_5߉W18It֍58ƋLTIī,( }׃\Ai$a Y4"iwB*1 :/>cZE[!uqӐ@8ƖCSNPqO=Y@D|lZOm6S }}'i}eF P*5׉FxZzi-jSu`-c1z%=a7Z`I{Xk:a_;N]"bѶH3q0Kj**4ڸ$$$fg&LjҥJ TT }LLSW 8cFGc!H$@ v[-ffYcX<o6BP%}>' pꈈ5cY՘(:/Or/%KFrU`7.Mr$ })0YZmfO+r)W93g;6H 1s̓ %]s~$1%pq (%(N5H9"uVu(2 }u֯\ZEW֩j G>RKjJkd-E3!f(]Ӳc&XFv\5jGZ+B؅XBǔZ$lEK6{vQq'Dž }ŦZA )@SBMjHkD0,jlEbLrjPӋ dMcQ|ZHf iUF,QܪrU\(ѝ+wWҰ8>|\ }:]"8wWGL"Q,(B;+"j̆䬛2% -rGket;'!1e%VL83`p)LPeqh }q/!KMش.+ )w3$ }.&L.AIG$Jx_1r P(ڀe|J;+@KcIrp)rTdd4i6X9/rD*H Ȕ6 2%E(l aO*x }6 x.A8\) 68ZQ|)ÖeCC=r" t' z9"(gHD5w $c3\Ŋ`R'"#E{EuB, }_e%|rr3a I@Te遂}ZR x޵ c;\ڻ j)^e)l L- kT%ŭ#$I Jx2\ &o Tj+$01jg Q| }AnP$T@( PRS @-!T'. "V K0`5` `a bZ Obx Th & TcSRg&+ 9vgV, }LzFg3kg,@U4 ' Ƹu&E DͰNhNBwބg;E6\Դʼ`05 m)fڲqRrEv$+l!+`TB }AEa:/23BY rX[aa{r񴨑?F R$ H'霆 I3}đ>vCY]]c@zDn6R FRE61b7,C\`h }ﭩ>R;<yɒ)eYtCe0 V^@8^cg>?Xm1bŜB@@vn![ ]7re 7re?iҒ6j }h\lHJf{\$ "evj$&(O4VS'M2YOL2^Y[pJV7.=ZA 0s5\йIhh }޺Q5LA0H9IɆjeS}}``HAA@F`l3Uf rP'g+-c[+3œkri̭9iXƕM VXᓎ&~VBxb@PQ4+ }W YJ)11`K^P(NLT Ķ#ZUKgˮ7 &0;PU]=! :&[@Fv|KȘSb\ıA=d2DơA}?h/RVGd }+ $@VqdTbX&*+ $qT;"d QTRGvtL*CNkGzd.!=P#:S"GPcP8yDC5cq flk }ԑ tkgKqAD„DݡfVLWiVV]eU1IL3^eo]m+R# N!uXt0:ĘU66btd@X*I-&ﻷhRNO0wU;נW }IۊUrd.[m$?Kᵞb(:bqOT Q0p9ryXLZx4I8K4*Aә\g~wb1ID'Edȅ婶 }QFBr߸; ^%@KSk(O&>vFt!% ZzZ'3~Tʨ5TrkDJcnz,g I3Q2X& }I3@B X&pk&2oZÒkv!!@#;9=x1мk3ܛ?QnOC75O| Qnli[ v%I bEl }~-⒢<1 4m7Q<M҈/=N~yyGv~t$-@Pć b | ZM!8_ 5@ΆydtLl~o 3LCr|,GY5K! }7J~[3RO~su@Dު~D;qLgn.,˖&&n?1F B<>` ' EѴTbmNАqt6Q@@jD }*J6KaO|LAu'1=*!bns|? ]5#;%,z:>M)y'-=X)^ v/gIz6]3Z }/?5ᑱXUi$MEC 1D]K>ù7ٝq@V )wMsc CQ\hK=_d0َpV5jDOιi Y ]KgxOUڬE0|X (RwH:H… aGfg[6_Di8ew0n }Zg^6 ;Fu }5M4>4 |,t-c=;<TD]sGF `*!YD8 v|CqzKFټN }]*ɀ5<9ۍÒ3x#C&0!T8lq؂gE-܏ pl+<䉖h\dJNZdl }kr$ hD' tE $9eě3T Q9z!"=TY";<OJO@!"#hs~%r^i5 }U܏v6=@K2_.}:#AS`hÛM&'Ij LH9?n4aHvxr75blQؿd/ܿ/ }~eh FvBr5Eq-7Nxx΢X-]=l9`NH"9y0zq8wnt/2㻴v( ;hqh8 }+:D]%mOSh( 7+:V( S{cԺErYN3`4WBI$fh5;12*۠_]ـT/ũ orT61߲ivrvg }m  EOvE$#ZzO35 be=UUՑ&4h+_,LXOKpIOܰ=#DQBC }孭%&VR LqH+#5;Qc[k& vZZ M( ؖ uuY c L;Zvʤqo ~u*n^։$(kv>O@A }S-n"MAő&J&n@M1*HW<;1cxնܡk&3Ŭ@eάi d58 3kɄ7^$"I~n9|JF%&ф7^B[ }WyWXtW'z1˪@!qsFL[%dlO>kxR"ngp0 v:7xiD3wmh 7>i8Q},R Fc9 }>B"JHK,Dz[:w5y5F`<)0<z1I3RwMl )f9J=$gs[`M:Ƹ&l,:Y@@uu'" }1"p%M$jO ,iXձhc`Ȫ [\bW+R0_߳-\5ٙGԤ.D &N-lR6=h0QQ4x؂G7F@EK(xEO }Ų!emN|XgF."&xD=j:!h#ޤjlUUA/]R:7E)9 }`wj dz瀶"czsHD^kj[2472FV "q ]7NȘ.\.&䀬 5 S|~/,[T }1d%/"3XQ`'A>D3 POO?w ?Y1{7.!G0 #R]BےMo!/E^ h58^93@Ʋ }o xHFD @\ qs !Ewv;Z$ć 6Dcvh } >`"ۉthc>_)$&_6Bϓ|^Κ: |iJ3@('x**h%3@ՕO'bѸ,n'5'P }F',=2Fm*p%F5ѓ"C/Bx(WlSm*&A&ѝ!(Y7 ӑj]šɃVKeo4s t }BW$6OD#P\%EOP%? U}:Hg]$$+,+zIfL.oeaoT0NѩP'3eI e-;$M[0 gm 4 }$}PPwBA(@g9pj;*K} ʙ *'f (Գ彙\e ='W  An٪RC&恶Pw/f vm >ׂ)c2 }]~3@*ren9S Ii >mVlEz'9x9c2YeH.@^.wO3&D^@QlrAD'-`Vv }c:)X v\D{ad>cP{*1aw"L&b 80 v$J .S7"O0`J[Q`] DiO91q!Vfy[D }yP #6VSd).pA^FI;I“\ CTȦ ,Gw)Ia 1@KS*ԃ0p@K#7"IHq~NDkěn }bc$/b!ƭ tL]}Ŷ^!4SH.Q`eӍ7e9eGmY[pP?4sfv H3qhz7Ȱ,ȶE_ }Jȹ質β!-MQ.5Qucǩ5uXueqtFrz~i(yloi!'̖k3=JY<",NED8NI }K&b-ZKc} P]QwҾdULqODc{ hC @&&`ʨE(!f 9՚$WEOst0Lŵ*X+Rv%qRزFJ, }2;֣@(`>B4ٳ>EW: Ao2hs~xK>&8+YPEOwjYm3ϙT J" ϑ` -+w¼j@ j +^48X } KT*IG2}u#N`uJVf ;:!*&e 9QRMY>{[(ѣO+3'3bi5 ڱ8MP MP7 } j[gINueҜ $w^ im8,C l`sUNEQ`Kbx/GPTW~Ŕğ_&h`LP0G %gV) 4 }+YH#H.Z&/"RZ(:LP#rʔ JvQ{ 7BEєu ) [8eݼ@u * Jq=A#2dC˞o:@Y }1zRS+:FI +`Ʊ}ЉJyl;;twO˂K$/W@PA?W@9{ܔ%K gt:_Ct9PsAbs:-esh }ܠ|\)};)ܧlӹk*^1 ؖR"P~ro4;rrESe;p" ܔid'"I(I% iFrf vY$( }8K6&:&3B M;PA{h`(,ܐl6PҼE` H ˈ b4GPz| g\?KbZ: !b!8 )pG }Hi(NED`P5eH g@ԣQ֓xm-s%(+$b B+wE`|8P엋F/ޑ1AeRBWx@5b }' ЉGechmК(^PcL!>)2 Y$Jύ[wMoV]hW6| a PD' D҃w^ }T3( BBZzOR,DT)-@`Ux𡟫 **E`7.yTlk -tZ:HQ{UeR4H' obD҉lc [vyp8)❜u '9@ q$a&)@91>gȚx9(Hc x }O &Ȓ#:|q:[_5BsHƣR  q =4^X3LZx 2dL5:PD%@S{-N'EY9Cb&,b#&| P }U%f0r?@$C>b/(d8ՀY`dJu04 Y-&/R΁g@ P /:LD{:`JةMUs0f͖fH2| }ʵZ,SI r(;~dYo)'幹,..vQ.0 @`a H`  ` ` ` wa ` a*E' h `+",#-.`-`++,`$"%#Ɗ$e*}*)M$%`&-"+#,*$ %!ߥ$%$$-ʝ`-ަ+,++L`. U`? U`I0 U`I1 dapa dapa2}a Sa*H Sah*d?? {`010?ދ⏛}1 _+g4d#Zj!'.7{6W "Kw-:[&(3X}*"B],.024v572:<>@BD8EGYnNHJLNGQSraUWY[]}AoaceFhiyiklfmnpruvxz}@Dɑ= LEР`>x@@?@}|<^zgTgz\!x/u}%IoD w}ag(PvHPrr{ pq}߯H_g "^}^_~D.Pwr+KQ6TS-$M]!D,CV5EDQ V'}QMo쨵B n09:ss-FQ<}hpB Ɗ֊`N [zQ }pZeUn.~/Y%_sB%DS_~߿ZufUR}]٤Q(JKQk9ߨ;ehhe[RQ(lC[؊}/QKZ7⏗8k#}Q0*Q)/tx"ʊyj0(zchlG#dAQTa>t7)PX'>_瞚4V#Ei(\w 2[*?4>}x>(W( x$}ǗN)wqMG_BVF]QB7ars)q=mj)7~7 sTPUzF~7ߞ~ yoC[^ :] *4hX%}FfVPG_~eJW3oWu_o/yGvcs,C =6neO1إԺAI0\H2ErF!-.Thd-\8&}ۀ2#]5A % 9aۈ0 ܍&'D' o .$.u(%܃>CRnt3 $m-ՏɆ";)}g7ppJ*PEj02Q8$ !h+$A*g*}=IMz{OXUϐx%w|Gvu\Q|ыIGfZNTrD/ 8 XΟ(yr˓g *}|`C߹Vю\p4#'.$tϛ(C!,;h+XZ%D5X Qoܱ˽go?5kӃaOJ^WNJ R_N+} '^ 졦\X)Ü{\3k_8X/%IAFm];lYM[/Ÿ\[amܯs kˆե\LZj?'Wv=qJә?#,}ノ( w/&'—E*'8t"\0CJ۸ZmS|,Qn%3M]/ h d701 >MC7@ |5^򆓰ʽ(6BBŷ4t$.  KQü.}+ޜHD (L*MrJ43} g@gPTKg-98WրfTN]0P2ѼɡVCjV"C# g>,8Eln`Qaff2lXaolX:p"4}CDΥj&tE :p$pÒ%T(BvUz(UowS^p;ӥ`n2>&77[o+Em /΃ gͰaC{<42m7V5}7pp`J#k 2Hps*-9R`TbͶ:|l"ËrET|EvM3c£KmJ<$WJ9<$ jS~6j6}6JQo+YYq1ĵ}rJ #h&W2!vQ0Ȇ .er8go*|Gn +5C[%ꉁ܀3~;Šiej?:;Á077}NGOKI} 'oz9ڧJ)<RMoRjA* CJDzim8@R퀇{2s'B] iVj#=:}fٱTًy8$Tٟ {N [=ʕ6`'f6X::7lXz *D̀:O#BTwci3 _HIݛ%_ 1&D"6mVhua *&fo^ޒGq%$-;}zhH F-v5)RLzrf)րCFb ]#JzOTRmZXz T  =,_nOBaK˱<}gj66 ډ]LCQH)hAR E&-p8͠hj@P6 n$nJAmh'jNC3)g -i-gb9Hznx$R]*=}'bX?wcSofI_@  &_k? jW![ .ړ`8H|^|"`p6z$ !oLUvoCm3P,$Tfhs6,>}U6䊬I$?&eav4{ , Sό' րCz;i*pGo0 Ld Ѝ.S/`T6E=HA6#  V[^$PF?}lTL Fԃ@EGQħF*)JX <!:3H?QOS*h k&gF )ޖV"C (l]ԴOct` HJ$F!yr}bMBvS=ḡa¡t#eߐ5-PϱwiBGPOf ƅᅔaD}Qa$OF@$ )GƖhlLb "3_ lx7w |hLkac%b,(Rˍ肋fGBOax2OS?IE}3*'X% ŜŠhy96~~Exz}XyQݛ nbA[g/O,NXC[o;FBGkI+ l*B(+YX:V -lF}*6B kWRa͝a$,Qq0jgp1Q&CXE5+Q*͂@v" :JZʂFIaIh(BX Q03gDG}k揕d)3!0MDjrMjrM- U6߳{$KTbg0s _A1FkBȣBZ@OPɢ`pv/!cDd!衐MFFѾ ¸H}0xt$Yb<< = 5 9}ǹM U0޴)N kA"ٌ$r 4LuI_zaG<]$#@"z>B} I}jY>~_ YZY!HBx(V 9.V[cTCcm'XPAc*#rD [=UX#Xkz QF'4([dJ}Ytc F-a&IfTlgY棽9X<$^'7/ŧX?"EI ڭJʜL5Kh;un"&k H`S͚ 5oh_LWK}5h棸 UVJk5?R^5`@/of4m$@m,ĉ@ϒ b U! vޒCҁwCi:. GC͙- ?L} /py/wwLw ܦ/ i~E !Wݏ>``@]X`DJ THE INSIDE OF NETWORK GAMES =========================== About two years ago I released a network-!N}game for the 8-bit Atari called MULTI DASH. Since that time, several people asked me for informations or ready routines usefu!O}l for writing more such games, but I wasn't able to help them: Although I answered a lot of questions, and although I even ga!P}ve a part of MULTI DASH source text to a certain man, it seems that no one was able to use it. There are lots of things aroun!Q}d to explain, and unfortunately also the networking system of MULTI DASH was not designed for use in any other games. This !R}year, I've written another network-game called MULTI RACE, and this time I didn't forget about you... The new improved networ!S}king system used in this game is relatively universal, and I'm now releasing it in the form of a simple example-game called M!T}ULTI WORMS (16 hungry worms eating apples), with full commented source texts. But however, there are still some more things t!U}o explain - and that's why I'm smashing my keyboard now... Well, first let me say some characteristics of a good Atari 8-bi!V}t network-game. Of course, it should be a game working on more interconnected computers, allowing several people to play toge!W}ther. But beside of that, the game should be also fully playable on a single computer, just like any other Atari 8-bit game -!X} connecting is just for very few computer-meetings, but we want to have the game more useful. As for hardware requirements, t!Y}he game should work on a plain 64kB machine, and be somehow playable also from keyboard. Why? Just imagine a typical computer!Z}-meeting: 9 computers in a room (only 3 with big RAM), and only 4 joysticks... In such a situation, the little requirements a![}re quite an important thing. The game should also transfer itself into the other computers without of need to run around with!\} a floppy disk. The networking system should be somehow "idiot-proof", ie. it should overcome a wide range of errors withou!]}t of any fatal interference to the other players' game, and with no need of user's intervention. (The errors I'm talking abou!^}t may look like: Switching terminal-systems on/off, pressing RESET, disconnecting computers, trying to start another network-!_}games, accidentally disconnecting the electric-power to a half of room, data-losses caused by weak network-hardware and dirty!`} connectors, etc. etc. - all in any possible moment...) ...And beside of all that, the game should be funny, interesting an!a}d playable! (This is allways the most difficult part.) So, now it's almost the time to look at the network-game's inside - !b}but first I must say one thing: It's impossible to patch into an existing game to get a network version! A network game must !c}be written in a special way from its begin to end, otherwise there's no chance... SERIAL LINE ON ATARI To underst!d}and how it all works, we must begin with some theory about serial data-transfer. We're ofcourse talking about network games f!e}or the hardware originally called GAMELINK2, which is actually a simple line connecting together the serial ports of all comp!f}uters, so that any data sent from any computer will come to all others. Fortunately, we don't have to take care about exact!g} timing and collecting single serial-bits together, because Atari already contains a powerfull hardware for this task inside !q}b%DOS SYSb*)DUP SYS`-----------bSMULTIRACCOM`-----------`-----------b7MWORMS COM`-----------bjMNTWGAM1 TXTbeNTWGAM2 TXTb%NTWGAM3 TXT#0MWSOURCEARC`-----------the POKEY chip (although it's not so well-known like PMG or Display-List). It uses the standard format of serial data support!r}ed also by most other computers around this world:(no data) (Start) (data-bits) (Stop)(1111111) 0 x x x x x x x !s}x 1 Each data-byte begins with one zero-bit called "Start", which is used (its begin) to synchronize the receiver. Then !t}8 data-bits are sent at a previously-known speed, and follows one "Stop" bit to provide high-state before another Start-bit, !u}and also to leave some time for data-processing. The POKEY chip have several different modes for serial data-transfer (sync!v}hronic/asynchronic, timing from different sound-channels or from an external clock, frequency-modulated output etc.), but all!w} we need is sending and asynchronic receiving with timing from sound channel 4. We must switch sound channels 3 and 4 to a !x}16-bit counter with 1.79MHz clock to get exact timing, and set the division-value (AUDF3,4) to the time of half a serial bit !y}(counted in clock cycles). Processing serial data via POKEY is then quite simple: After setting the necessary sound- and se!z}rial-mode, we only need to write a byte at SEROUT ($D20D), and POKEY will send it as soon, as the previous byte is finished. !{}When it's the time to write another byte, an IRQ interrupt come - and if no byte was written, another IRQ indicates the end o!|}f transmission after a while. Receiving is similar: POKEY reads data from the line, and once it have a whole byte, IRQ tell u!}}s to read it from SERIN ($D20D). (We must also check some error flags in the status register.) In the networking system for!~} a game, we'll also need to detect end of data-block. For this purpose, POKEY have one almost forgotten bit in the status reg!}ister, indicating whether the serial receiver works or not. Since the serial-input-IRQ is allways coming at the time of Stop-!}bit, we only have to wait the time of two serial bits, and then read this status-bit. When it's active, another Start-bit was!} found, otherwise it's the end of block. A complete description of POKEY's serial I/O functions would be too long for this !}article, so look into the source text (or better into some books) for details... LIVING WITH SERIAL I/O While the!} serial data-transfer works, there are some special limitations to the game-program (it's somehow similar to demo-effects at !}the time of loading from a disk drive). At first, the program may not play with the interrupts too much, because each appro!}x. 940 clock cycles (for standard speed of transmission) comes an important IRQ - so the other interrupt routines must be sho!}rt, and ofcourse we may not disable IRQ. The POKEY's sound registers are shared between the serial transfer, and game sound!}s. Since the channels 3 and 4 are used for I/O timing, we have only the other two channels (1 and 2) left for making sounds. !}We can't use the STIMER ($D209) register to start counters, and while writing to AUDCTL ($D208), the bits 3 and 5 must be all!}ways set to keep the proper mode of I/O timing. The last limitation is a bit unexpected, and also most difficult to overcom!}e. I didn't have a chance to examine all the details, but it's quite sure that a hardware-bug inside the 6502 causes VBI and !}DLI interrupts to be delayed or even lost! The problem occurs in the situation, when both the interrupt-signals supported by !}6502 (NMI and IRQ) come at the same time. Depending on the phase and length of both the signals, NMI may be lost, or executed!} much later (DLI may "fall" even two scanlines down with a heavy IRQ jam). This 6502-bug is mostly unimportant, because norma!}lly the only rare IRQ is coming from keyboard, and during the disk operations a lost VBI is no problem (although I already su!}cceed to crash a certain music-menu full of DLI's just by pressing a key), but while DLI's or exact VBI-timing run together w!}ith the serial I/O, the probability of troubles is much higher... (Have you already seen strange flashes of incorrect colors !}on a nice "loading" screen, while the disk drive works? That's it!) How to overcome this problem? We must write the interru!}pt routines in a special way. At first, the length of IRQ-signal activity must be minimized. Normally POKEY keeps the signal !}active quite long, but fortunately we can stop it by clearing IRQEN ($D20E) to zero as soon as possible. Shorter signal means!} lower probability of troubles. (If we'll be lucky to have IRQ shorter than NMI - which seems to be about 24 clock cycles lon!}g - the problem of lost NMI is probably solved; but this is mostly impossible.) While writing the NMI routines, we must rem!}ember that any NMI may be ignored or delayed. While with VBI mostly no fatal problem occurs, incorrect DLI's are quite a visi!}ble problem. The best way is to avoid the use of DLI's at all, but there are also other things you can do: The first very use!}ful thing is one STA WSYNC ($D40A) instruction at the begin of NMI routine - mostly it will synchronize the routine correctly!}, no matter whether it was a little delayed or not. When there are more DLI's on screen, the decision which one is currentl!}y executed should be based one and only on the VCOUNT ($D40B) register. VCOUNT allways shows the correct Y-position, while me!}thods like counting number of DLI's executed or changing DLI-address by the previous routine may fail when one DLI is lost. !} The last trick is quite simple: Leave some free space between your screen-windows, and put double DLI's into the gaps (when !}one is lost, the other works). This is probably the only safe way to really overcome the problem of lost DLI's, but unfortuna!}tely it's sometimes impossible to have gaps between the screen lines... (Note that also VBI-setting of screen colors etc. sho!}uld be doubled by a DLI somewhere at the top or bottom of screen.) THE GROUNDS OF GAME-NETWORKING Now let's look !}at the principles of a game working on more computers together. At first, we'll divide the operations executed inside a typic!}al game-program into two groups: Moving players, and the graphics/sound presentation. In this chapther, we'll talk about the !}first group only, since the presentation (re-drawing screen, playing music, screen-animation etc.) is just a local job with n!}o output back to the network. The most important idea is: Every operations affecting the game-situation must be executed EX!}ACTLY the same way on all the computers!!! This means, that the routines for moving players and other such operations must be!} executed allways in the same order, and should use ONLY the input data transferred via network - so forget about reading of !}local random numbers, sticks, keyboards or timers directly from your game-action code! Although we have more computers work!}ing simultaneously, it's impossible to do more operations at the same time - it would lead to different results on different !}computers, meaning the game's death. (Unless you're going to solve a very complex problem of transfering and re-compiling the!} whole game-situation after each game-step). In other words, a network game should virtually work just like any other game: O!}ne player's move, then another, then for example a new object, etc. etc. - never two things simultaneously. One of the ways!} is to distribute the operations between the computers, ie. each one executes its part, and sends the results (game-situation!} update) to the others. This is how MULTI DASH works, but it's not a good way for making an universal networking system - the!}re are lots of game-specific things to transfer. Another method is to run the full multi-player game on all the computers, !}transfering only the state of all joysticks in the network. It might look like a crazy idea, but actually it's better: All th!}e game-operations must be executed one-after-one anyway, no matter which computer(s) execute it, but now we have less data to!} transfer (the transfer is allways the slowest thing). This is the system used in MULTI RACE and MULTI WORMS. It's also ver!}y important to have a really safe data-transfer, because any data-loss may also cause differences in game situation - and as !}I've said already: It's the game's death. So we should NEVER just send some bytes, and assume that the other computers got it!}... We should allways send data to one and only computer - with block-type, address, and checksum - and wait for an answer. W!}hen no answer came, we should try again after a certain time, and when it wasn't successful several times, the computer shoul!}d be removed from the network. (Ofcourse each computer in the network must have an unique address!) This is probably the only!} safe method, and actually the same system is running on your Atari everyday - while working with a disk drive or other SIO-p!}eripherals. It's also necessary to have some block-start or block-end identificator which may not occur inside a data block!}; otherwise we may not be sure whether we've found a new game-networking block, or just a random sequence inside some boot-se!}ctor data. Since the game-network have no extra wire for a "block-start" signal (like the COMMAND line used between Atari and!} common peripherals), we must find an other way - and the solution is rather simple: When there is a gap between data bytes, !}it's the end of block. The easiest way to handle all the network-operations, and to overcome problems like disconnecting co!}mputers, is to have one "Master" system taking control over the whole network, ie. all communications should be done from/to !}the Master. In addition, in all known Atari network-games the Master also emulates a disk drive, allowing the other computers!} to boot the game software via network. Then it's clear who is who: The first computer (booted from a disk) is the Master, an!}d the others (booted from this Master) are Terminals. 7 THE UNIVERSAL NETWORKING MODULE The published source text of MULTI WORMS is divided into two major files: The gam%}e-routines, and the communication module. While the game part with hungry worms is just an example, the communication module %}is a relatively universal base for making further network-games. Actually, this module is an independent network-game matchin%}g all the above specifications, with all the game-specific parts replaced by JSR-calls to the second file. The game-part is t%}hen just a set of subroutines - you're free to replace this part by your own game, as described below. But first I'm going to%} present some outline informations about the networking module itself. (It's allways better to know how the program works, wh%}en you're going to use it in your own game.) A game built on this module is working without of the Operating System - all t%}he ROMs are simply banked-out, and the program operates directly on hardware registers. This is probably the best solution fo%}r a game, because the O.S. is not very useful for this purpose (a poor character-set and a few VBI-handled variables - that's%} all we can use), we have maximum of free memory, and we don't have to worry about problems with thousands of modified ROM-ve%}rsions (Attract mode is one of the smallest troubles). It's also easier to overcome problems with interrupts (see above), whe%}n there's no additional OS-code executed before our own interrupt routines. The data-transfer works at the standard speed 1%}9200bps, with a checksum at the end of each data-block. This is compatible with the standard Atari SIO transfer, allowing us %}to use the same routines for both game-networking and terminal booting. The speed is also reasonable for the use of long cabl%}es without of advanced hardware. The main IRQ routine does almost everything around the physical layer of data transfer. Wh%}ile sending a block, first a gap is done using the POKEY's counter as a timer: Instead of starting the transmission a timer i%}s set, and the actual data transfer is started with a certain delay by the IRQ from that timer - leaving enough time for the %}detection of previous block's end. Ofcourse the end-of-block detection is done at the end of receiving IRQ routine, as descri%}bed above. Since it's necessary to clear IRQEN as soon as possible to avoid NMI-problems, the routines allways enable only on%}e IRQ type at a time, so that there's no need to detect the interrupt source (saving time). Because of this, the game-program%} may not use any other IRQ's! (The only common use is keyboard input, which may be easily done also on VBI - as shown in MULT%}I WORMS source.) The module also takes control over NMI interrupts, executing a part of networking operations on VBI, and c%}alling actual interrupt routines of the game as subroutines. Because the VBI should not freeze IRQ-controlled data transfer f%}or too long time, VBI routines are divided into Immediate and Deferred part - just like the Atari O.S. does. The Immediate pa%}rt - which must be rather short - is allways executed (unless the NMI is lost), while the Deferred part - which may be long -%} is sometimes omitted: To avoid IRQ-freezing, the VBI system detects if some IRQ routine was running before NMI - if so, the %}Deferred part is not executed, allowing the IRQ to finish its work in time. Otherwise, another IRQ's are enabled before execu%}ting the Deferred part, so that long Deferred-VBI routines are not blocking further IRQ data-transfer. The communications p%}rotocol is relatively simple. The table below shows the structure of all data blocks transferred: ID Length Block type /%} Sent by Structure (offset, function)------------------------------------------------- $40 6 0:Log-in acc%}epted / Master +1-2: Random numbers used by terminal +3-4: Game identification bytes %} +5: Given terminal-number $48 5 1:Log-in request / Terminal +1-2: Random numbers +3-4: Game id%}entification bytes$50+t 2 2:Menu-status question / Master +1: Game-start wanted (0=Not)$58+t 20 3:Menu-st%}atus answer / Terminal +1: Ready for game (0=No, 1=Yes) +2-17: Two local player-names +%}18-19: Random numbers$60+t 122 4:Info-block before game / Master +1: Info-block number +2-121: Gam%}e-specific data, or player-names$68+t 2 5:Info-block accepted / Terminal +1: Info-block number$70+t 12 6:%}New game-step / Master +1: Number of step +2-9: Joysticks of all computers +10-11: Cen%}tral random numbers$78+t 3 7:Game-step accepted / Terminal +1: Number of step +2: Joysticks %}of the terminal($31) 4 SIO Command-block / Booting terminal +0: Device code ($31=Disk drive 1) %} +1: Command (R=Read, S=Status) +2-3: Number of sector --- 1 SIO ACK-byte / Master (emulating disk drive)%} +0: A=Accepted, C=Complete executed (A single byte with no checksum!)($00) 4 Drive status /%} Master (emulating disk drive) +0: $00=Single density +1-3: $FF, $FE, $00 (common answer) --- 1%}28 Boot-sector / Master (emulating disk drive) +0-127: Data of the sector The first part of the table shows the%} game-networking blocks, while the rest is actually a very simplified part of the Atari SIO protocol necessary for the Termin%}al-booting process. All the game-networking blocks begin with one ID-byte (shown in the left column), which is used togethe%}r with the block-length as the identification of block-type and address. The structure of this byte is following: b7 b6%} b5 b4 b3 b2 b1 b0 ------ ---------- ---------- Protocol Block Terminal version type numbe%}r The communication is allways between the Master and the terminal specified in the ID-byte, only the Log-in blocks are se%}nt with zero as the Terminal-number (because the terminal have no number yet). The block-types 0-7 are corresponding with the%} table above, and the "Protocol version" bits are allways 01 (MULTI DASH uses 00, other codes are waiting for future use). %}The terminal-booting process is quite simple: The Master system recognize some SIO-commands coming from the network, and send%}s data from its own memory as an answer, so that the other computers may read a portion of Master's memory as if it were a di%}sk inserted into a floppy-drive. Once a terminal-computer is switched on, it does try to boot a disk, and so it reads a copy %}of the game-program from Master into its own memory. To be sure that the program was transferred correctly, a 16-bit checksum%} of the whole memory-block is checked after boot. Now let's look how the whole system works: First the game program is star%}ted in the Master system. Since no terminals are logged-in, the computer doesn't send anything to the serial port, so that no%} interference with connected peripherals may occur while playing on a single computer. When a terminal is connected and switc%}hed on, it starts to boot a disk, and so it gets a copy of the game program from Master's memory. Then, the terminal sends %}a Log-in request, and gets its own terminal-number from the Master. This is a very important operation, because having unique%} terminal-numbers is a basic condition for a successful networking. To avoid false log-ins, the transferred data also contain%} two game-identification bytes (more network-games at a meeting?), and random numbers which must be sent back as a part of va%}lid answer (for the case that two terminals are trying to log-in at the same time). Now the Master each three seconds sends%} Menu-questions to all the logged-in terminals to be sure that they are still connected. The terminal's answer contains also %}random numbers as a further arrangement against having two terminals with the same number: If by some mistake two terminals h&}ave the same number (possibly caused by connection problems at the time of log-in, or by RESET on the Master), and so both ar&}e answering to the same question, the different random numbers coming to the network simultaneously cause the answer to be un&}readable for Master, and so the terminal-number is unlogged after a while. Also the terminals are checking the connection by &}counting the time between received Master's questions (or boot sectors - during a boot the Master sends no questions): When i&}t's quiet for a too long time, the terminal execute the Log-in process again, to resume the connection. After a while, this&} system overcome all the problems, and every connected terminals are logged-in. Simultaneously, the menu-screens are displaye&}d on every computers, the players are editing their names and making another selections, and then it's finally the time to st&}art the game (the user of the Master system clicks on a "Start" option in his menu). The Master first waits until it's quie&}t on the network for a few seconds (so that a running boot may be finished), and then it starts to send the Menu-questions ag& }ain, but now with the "Game start wanted" flag active in it - so the terminals display a message, that the players should get& } ready for the game. After a while, the players finish their menu-settings (and click on a "Ready" option), and so the Mast& }er finally receive all the answers with the "Ready for game" flag set. At this moment, all the player-names are already colle& }cted in the Master system, because these are also included in the terminal's answers. Now the Master prepare the map or other& } game-specific data, and send it to all the terminals - divided into several short blocks; as the last block all the user-nam&}es are sent. Once all the blocks are transferred, the game begins. (From this point on, the communication is fully controll&}ed by interrupt-routines, allowing relatively long game-routines to be executed simultaneously.) Now, 10 times a second (a re&}asonable game-speed, also limited by the data transfer) the Master system starts a new game-step (unless there's a delay caus&}ed by heavy communication problems): First the Master reads its own joysticks and generate central random-numbers, then it se&}nds the central joystick-register to all the terminals, and receive the update (i.e. status of terminal's local sticks) as an&} answer. The block of all network's joystick-data is on each computer written to a buffer, which is then read by the main g&}ame-loop as soon as possible. This loop then calls the actual game-routines with ready input data. Although the transmission &}is done at a different point of the main game-loop for each terminal (to have fast response on local joysticks), the system p&}rovides exactly the same data-stream in all the computers. When the game is over, all the computers read some more joystick&} blocks to clear any additional data hanging around in the system, and jump back to the menu. Since the game works in full on&} all the computers, the game-results are already available and so there's no need to transfer these via network. To minimiz&}e the amount of transferred data, each joystick is encoded into four bits of the terminal-byte on network (two players per co&}mputer are supported). The code describes the changes of stick position, and when no change occurs, then the status of FIRE b&}utton is encoded (it's nonsence to change the stick position 10 times a second, so there's allways some time left to transfer&} FIRE). Also the existence of single players is transferred. The codes are: 5 1 6 9 = FIRE is active \ | / &} 10 = No FIRE 3 - 0 - 4 / | \ 11 = Player not exist 8 2 7 (12-15: unused) A little problem is with t&}he keyboard controls. As I said, it's useful to have a network game playable also without of full amount of joysticks, so my &}software supports also keyboard as the input device. But since the POKEY chip may only detect one key at a time, it's impossi& }ble to do diagonal directions on normal cursor keys. After some experiments, I finally decided to use the system known from a&!} Slovak game called DYNAKILLERS: XL computer: SELECT XE computer: Q | &"} | A - - S START - - SELECT | | SHIFT=FIRE STA&#}RT SHIFT=FIRE A This layout is maybe a bit strange, but with two experienced hands it is playable, and it's pr&$}obably the best we can do on the Atari keyboard.$2 WRITING OWN NETWORK GAMES To create your own network game with the use of my networking module, you need to write*&} a set of game-specific subroutines described below, to define a few labels, and to include the file "B" from the supplied so*'}urce of MULTI WORMS. (The source texts are in the format for MAE assembler.) All the label names used inside the networking m*(}odule begins with the character "N" to avoid problems with duplicate labels - you can use any other names in your part. All*)} your routines must be written in the style of common interrupt routines, ie. there may not be any long loops: The routine sh**}ould allways quickly (<<1 frame) execute one operation, and exit (using variables to keep the info about overall situation).*+} You can do all you want with the screen (ANTIC/GTIA programming), and with the first two sound channels, but setting up int*,}errupts or anything around the serial I/O is not your business (that's the job of my networking module). You can enable or di*-}sable DLI, but VBI must be allways active (so be sure that you allways write $40 or $C0 to NMIEN at $D40E). During the game-p*.}lay, you may not read any input data (such as joysticks, random numbers, collision registers, timers, keyboard etc.) directly*/} from hardware: You should use only the data provided by the networking system. You must also remember that it'll all work *0}with the Operating System banked out. Maybe that someone don't know how it looks like, so let me to say a few words about the*1} situation with no O.S.: The RAM is free between $400 and $CFFF, and also between $D800 and $FFF9. Page 1 is still the stack,*2} and also the hardware registers between $D000 and $D7FF are still in place, but since the OS-variables are gone, we can use *3}a great part of pages 0, 2 & 3 for our own variables. But however, we can't overwrite the areas used by RESET routines - that*4}'s $00-$0F, $244, $33D-$33F, and $3ED-$3FF - otherwise the computer may lock-up after RESET. Because the game will be RESET-p*5}roof, we must also remember that RESET allways clears the areas $10-$7F, $200-$3EC, and $BC20-$BFFF. The last six bytes of me*6}mory are interrupt-vectors: $FFFA,B is address of NMI routine, and $FFFE,F is IRQ address (the $FFFC,D RESET-vector is not wo*7}rking, because the ROM is allways banked-in by the RESET button). The most important thing for your routines is that the so c*8}alled Shadow registers are not working, so that you should write everything directly to the hardware (for example the backgro*9}und color to the GTIA register at $D01A, and not to the shadow register at $2C8). Because of the Terminal-booting process, *:}the game-program (including all the pre-defined data like graphics, sound, fonts etc.) must be located somewhere in the norma*;}l system-memory ($580-$BC1F), while the upper RAM above $C000 is ideal for screen memory, buffers, game-maps and such. The po*<}sition of program-data in memory is defined by a few important labels, as shown below (higher addresses at the top): *=} Variables, screen memory etc. -----------------------------L Master-specific game routinesL ------*>}-----------------------L Netw.module (Master-specific)L NBOOENDLB Networking module (main part)LB ---*?}--------------------------LB Main part of game routinesLB -----------------------------LB Data (sound, g*@}raphics etc.)LB NDATA ----------------------------- B (Space for the Boot-loader) B NBOOTER ( = NDATA - $100 ) *A} ----------------------------- Variables, screen memory etc. The letter "L" shows the area initially loaded f*B}rom disk while starting the game on Master, and "B" is the area transferred to the Terminals. All important routines and pre-*C}defined data for the game must be between the labels NDATA and NBOOEND (which is contained inside the networking module), oth*D}erwise it'll not be transferred to the terminals. (The "Master-specific" part contains the things necessary only for the Mast*E}er computer - such as creating the game-map, or some of the communication routines - which needn't to be transferred.) With*F}in the menu, your routines may not do any changes in the terminal booting area (marked with "B" above), otherwise the booting*G} process will be impossible: There is a checksum over this area. But however, the game-part may be self modifying (for exampl*H}e some animation inside font data), because the booting checksum is updated while re-entering the menu. So, the memory all*I}ocation is the first thing you must define: The NDATA label (plus NBOOTER which should be $100 bytes lower). Also the areas f*J}or variables of the networking module must be located somewhere: NMZPG (2 bytes in the zero page), and NVRS (385 bytes anywhe*K}re). Another thing to define are the two Game-identification bytes called GIDBYT1 and 2. These bytes should be some unique *L}code idetifying your game. You can use the game name's initials, random numbers, or the date of your birthday - simply anythi*M}ng you want. But don't use the stupid combinations like $0000, $FFFF, $8080 etc. - otherwise we'll have lots of games with th*N}e same code, resulting in problems while booting one network game over another at a meeting. You should also define the Mac*O}ro called GBOOVRM containing 40 bytes of screen memory (a text in ATASCII screen codes) to be displayed on the terminal's scr*P}een while booting. There are a few variables of the networking system containing some informations useful for your routine*Q}s (remember that you may only read them, not write):--- NTERM contains the number of terminal (0=Master). Beside of the ide*R}ntification, on which computer in the network your routine currently works, it's also useful for detecting local players (for*S} example while re-drawing player's screens or making sound-effects connected to the game actions - look at MULTI WORMS): The *T}numbers of local players are allways NTERM*2 and NTERM*2+1.--- NEXIST (16 player-bytes; 0=Exist) - here you'll find the info*U}rmation whether a certain player exists in the game (current or just finished) or not. This is useful while starting the game*V} (putting players at their initial positions), during the game (to avoid random collisions with non-existent players), and al*W}so while printing game-results to the screen (to skip senseless lines).--- NRND (2 bytes) - If you need random numbers in yo*X}ur game, you should read it from this variable. The random numbers here are transferred via network, so that the same numbers*Y} occur in all the computers. (Note that the numbers are updated only once per game-step, ie. they are the same for all the pl*Z}ayer movements and other operations of the step. It works only during the game, ie. not in menu or initializations.)--- NALL*[}NAM (128 bytes) contains the names of all players playing the current or just finished game - 8 bytes per player. It's mostly*\} used for printing game-results to the screen, but it might be also useful during the game for some kinds of score presentati*]}on.--- NMYNAM (16 bytes, writing possible) - this buffer contains the local player's names (8 bytes per player); when the ga*^}me is loaded, it's initialized to names like "PLAYER x" using the screen-code ATASCII. Your menu-routines should allow the us*_}er to edit the names before start of the game.--- NJOYTYP (2 bytes, writing possible) - the settings of controller type for *`}the two local players: 1-2=Sticks, 3=Keyboard XL, 4=Keyboard XE, 0=Player will not play. Your menu-routines should allow the *a}user to change these settings before start of the game.--- NACTIVE (Master only) is a bit-oriented list of logged-in termina*b}ls (highest bit is #0 (Master), lowest is terminal #7). It's useful for screen-presentation of network status on Master.--- *c}NBOOFLG (Master only; 0=Not) - a flag indicating that some terminal is currently booting (for screen-presentation on Master).*d}--- NIOBUF (128 bytes) - the main buffer for data transfer, which is important for the GINFOUT and GINFIN routines. The g*e}ame-routines you should create are listed below - all the routines excepting GDLI must end with the RTS instruction. (It's a *f}good idea to examine how the example game MULTI WORMS is done, before writing your own routines.)--- GRESINI - This is the *g}very first initialization after loading the game, or after RESET, which is executed with black screen and no interrupts activ*h}e. You should set all your menu-settings to the default (plus clear the game-results list), and initialize variables for a sa*i}fe start of your interrupt routines (but NOT enable the interrupts youself). This is the only routine with no time-limit, so *j}you should also execute all really long (over 5 seconds) initializations required for your game. Note that the networking-sys*k}tem variables like NTERM are not set while executing this routine.--- GWTSCR - This should set up a simple screen with a kin*l}d of "Please wait" message. It's used for example while a terminal executes its Log-in, or while the game-start preparation w*m}orks.--- GMNUINI - This is executed while entering the menu-screen. You should initialize the menu (cursor-positions and suc*n}h), set up your menu-screen, and redraw its contents. The A register contains zero when you should show the basic menu-screen*o} (first entry or RESET), or 128 while the game-results page is required (re-entering menu after game). The list of game resul*p}ts should be based on NEXIST, NALLNAM, and your own score-variables. Mostly there are some central settings in a network game*q}, so that you'll probably need to check NTERM, and display a little different menu on the Master.--- GMNUEXE - The main subr*r}outine for the menu (executed inside the networking module's main menu-loop), allowing the user to edit menu-settings. When t*s}he A register is negative (>127), the game-start is allowed/required, so that on a terminal you should display a kind of "Get*t} ready" message. At the end, this routine should set or clear the Carry-flag to indicate whether the user clicked on a "Start*u} the game" or "Ready for the game" option, or not. This routine should be allways executed quickly, otherwise it'll slow down*v} the terminal booting process. It's also nice to show a sort of network-status line on your menu-screen, ie. on terminal its *w}number, and on Master also the list of logged-in terminals, and the flag of boot process (read from NTERM, NACTIVE, and NBOOF*x}LG).--- GVBMNUI and GVBGAMI - The immediate-VBI routines for menu and game (should be short). This is useful for setting-up *y}screen colors, running your own VBI-timers (during the game only for screen-presentation!), and such.--- GVBMNUD and GVBGAMD*z} - The deferred-VBI routines for menu and game. It's useful for larger VBI-operations, such as keyboard-reading (in the menu)*{}, screen animation, or playing music.--- GDLI - The main routine for the DLI interrupt used for both menu and game. This is *|}a real interrupt routine (no subroutine), so that you should store registers to the stack, and exit with RTI at the end. Also*}} the detection whether menu- or game-screen is active is on you. Note that this routine is executed almost one scanline lower*~} than a normal DLI (after one STA WSYNC instruction), so you should make your screen-settings immediately, or call the DLI on*}e scanline higher from the Display List. You should also remember that this routine must be short (6 scanlines is the maximum*} - otherwise the serial data transfer will crash), and that more DLI's on a screen must be identified using VCOUNT (see above*}).--- GINITM - Initialize the game-map (this is executed only on the Master computer). You should prepare all the central ga*}me-data such as the map, player's and creatures' starting positions etc. - everything what will be tranferred inside the Info*} blocks. This routine may be relatively long (up to about 10 seconds).--- GIBLKS - This is another label you should define: *}GIBLKS = The number of so called Info-blocks used in your game. Each of these blocks contains 120 data-bytes, which may be us*}ed to transfer the game-map, central settings, and other such data from Master to all the terminals. You must transfer all th*}e data affecting the game-situation, unless it's initialized the same way in all the computers, or pre-defined in the game-pr*}ogram.--- GINFOUT - Create Info-block (executed only on Master). In the A register you'll get a number of block between 0 an*}d GIBLKS-1, and you should store the block's data at NIOBUF+2 (up to 120 bytes).--- GINFIN - Store Info-block (executed on t*}erminals). This is reverse to the above: You should take the Info-block data from NIOBUF+2, and store into your game-data str*}uctures.--- GINITP - Initialize game-routines. This is the first initialization of the game itself, which is executed before*} setting up the game-data transfer, and so it may be relatively long (up to 5 seconds). Since all the Info-blocks are already*} transferred, this routine is useful for decoding game-maps or filling tables with pre-calculated values, and you should also*} initialize the variables for a safe start of your game-VBI routines.--- GINITS - Start the game. Now the NEXIST flags are a*}lready filled with correct player-existence flags, so you should initialize the variables like player's positions, scores etc*}., and then set up your game-screen. You can also execute some "count down" presentation before the actual game start as a pa*}rt of this routine: Just make a loop with JSR call to a routine NWTJOY inside - this routine is a network-synchronized 0.1 se*}c. waiting.--- GPLREXE - Move one player. The X register is number of player (0-15), and A register contains the joystick of*} that player in the following format: b7 b6 b5 b4 b3 b2 b1 b0 Remove Fire Right Left Back Forwar*}ds The active state of all the bits is "1". Once the "Remove" bit is active, you should delete the playe*}r from the game - the corresponding computer was disconnected from network, and so the player no more exists (this routine wi*}ll not be executed for that player anymore). If you need it, you may read random numbers from NRND.--- GOTHEXE - Execute gam*}e-operations other than player-moving. This routine is executed at the end of each game-step, allowing you to move monsters, *}set up new objects, count the time (0.1 sec. per game-step), and so on. (You can use NRND if necessary.) You should also chec*}k whether the game is over or not (all players dead, a time limit, or a similar condition), and set the Carry-flag when it's *}the end of game.--- GREDRAW - This is the routine for transfering game-situation to the screen, when it takes a longer time.*} (For example MULTI RACE is re-drawing both the 3-D screens in this routine.) It's executed only when there's enough time lef*}t for a longer operation, so this routine may be relatively long - the maximum is about 10 frames. But since this routine is *}executed without of a safe network-synchronization, it may not affect the game situation!--- GFINGAM - Finish the game. This*} is executed at the time of game-over, just before the ending 0.8 sec. pause before removing game-screen. This routine gives *}you a chance for the last update of scores, and for sorting the game-results before return to menu. You may also execute some*} final presentation, such as animation-end, total explosion of the game-field etc. - this may be a loop with the JSR NWTJOY c*}all inside (synchronized 0.1 sec. waiting). You should also initialize variables for a safe start of menu-VBI routines if nec*}essary, and clear all sounds you've used within the game. FINAL WORDS With the last routine, we've finished the g*}ame, and I think that it's the right time to finish also this article. Maybe you need further information, but since this are*}ticle is long enough already, I must only say: You should read the source texts of MULTI WORMS for more info. And the last *}request: While using my networking module in your own games, it would be nice if you include a short notice about the source *}of this module (ie. "Networking code from BEWESOFT" or something like that). Thank you, and happy coding! Jir*}i Bernasek - BEWESOFT(MWORMA.MAEd / ;T@2) H$TT -X "x´æ 7ey#gM3=6„JWHi2Ņ FX!#i: )oia&h ̐.}fΜ2mİcgÈPHd :dAGnIA%)4rҀRFeրh1ȕ"SB 2Ļs n*HMr.mD:sqtyc;e q.}4 3ƣT9l݂[lZ2Q bÀ`# a"mS7iyf-$=Ï_  pgfP%Ga0ZF ˝&N4G$;p.}BTS%Vm2R8a#Y>1Jmc<8c&PHAŏ" (h$tHqZUEYS~V$zl1F7VH1E$0e(0 >R vXZ5y.} D 8O,i#X\.AP4$EjgȡћOS-QJsDZxa~M 5a 6Wx'ƕJ<}a7` 0y̑&R0TTYVnQ7{5E3QPDa.}peT/f(c3xHVa0%Q.Y' Bl<&&uh:STatPCt1*BsFTBrH$q FYĞ{MQ(U8zX.} Xm-Fg̡&]pDJ:a S*G̾RcnŮʐC W/ZjEJ* 0[d, ¸2niC T,ƁNIt\l&hL -W {oQ.}/0p!ӐsJڛ N1l-:Ka0$DZu{GE3 uar\#tPI3 īsrtBtXݛwRAYȩ(1!ɑG QUE .}Vnq=CexFyd.uƐۅ-C QrLܲe NQaN)28E!``. DdL24B"PgP0Nځ .}|%-0ۈD,aYAIu M.qw@t]V򬖕ijK1s@Љ@2:d- ,|0jS &qy~sKR.}*;\ e}>E0ݪT jNS(ײ *a_@Y:J8VA e)ԕf.s]eIppY{$)SyGBrȶ쉶̆<.}ͮTÎI@&7C;UDO_D"! L~w@y24Ɔ$#ޖzO#ml5Cx5['4YΕkl} YOV(E?(.}`ȡ#awbjNa I™ `A`Nux1_A@ l)>XvI<;FSGF<Geg(^RN:g*ّ٨.} 8)26PW~Z: M)J#diYF*\Pgb-!eHunhj-8)hwWzdn% <=]:V+EPzZq:4d׬Xx8<=D&ا.}G:7ViE0BЕ:tXEqJqQIIꚘݚtY  V(B0[=YtSvBlIxC򺯏'=𪯗ů6o^B.}:wƕzʈI:X:@w :՚s)}s|Q5 QAS6w'wG2)}3hJ&i14(U\{|D}$0UA놷akqQP.}#SV}ηFr=,2,@A}7Rgtl| qrQiC4WO*q)qۗɵQz`S;۹[gCAZV[.}tK}Bq\:w,p˺7{i]ɤtr!P Ij3щ|A ~~,}30w NU=e~BKeUS[VNa2&R.}9IacAO:7PkePp+_&wV%Gdz ;>Ple5pa$FBq%l';DKLA̴%<].E}0;PVs.}"΂Wu |x||q%?eQF|W SI'jfeyDI-QIPD UDjvj.}SD@1VT̤\WDD@2$CO0Bsgڮi-;EeBi!twwTFgXRh]Xb}%r`R/e5W7-l=\\?0IMk3lIYۇሃ3Y Yc2#)Ep.}lSzARA"`tCe c.=l1mZV"4V$ݫA̍bmo]|-H]W'SDhm-W̶LvWTHܽ.}PU2l $p#Soq |ȦVxo m .xRŕsqUhSƕ%'p-o'mvuK@ݰ 1 PA`&hBvK7Zٰmhl:-.}010 ēIz-c4s QcJQ%ۙ,ta|Y&=2U+k&rgr+f[Z ը]񡞃g->.}ſ1xs&k̹l2.>\"(r^WCf.$מJ>+R@ bn}Z( (k.r.O.}Yl2!lu+Ȉs+,oV>_Ei-b/K.4?pgg0W`([",|`7.!)W*?-;(&.}EoOOe)PcfP51,52JSrl`ym[;F-/$7F~yUKc0斅2 2\,0xW61s{3|loSuN[R+R.}1b_=^Q rNrVfVNV+X=T)"ΑP4okkm@=ncc0vVAxkn(E7n>/x3+ .}#ըr/@Ȁua%*x&l,8%͖)Bku8"σ&}w1Su ¼C]a98&5lW :'NDn&-KQK~a.}<<ŗJC_ wWۮLm!zh >EzИ`3swIqB1(W ; 0+@w"88b/.p9Hd\M`{OP,ʈ}bvJe.}UUW?r]05\h-#AR-U/W,;rH2ȼQ9aUl,6-%b. n6f>NV"ꧢ/L*h.},gA>ar1>+&L*.OR>+v<Vɉqe0eU9pH.gh;P0c:AqX~3cEk+>a3Fz8ܬQ.}߻|UuU66o(@Ssjq2"Q9a6+7V,̎X [5u2^p^떱n{,XNs8`/+X_!.}%<{~tݫ8]@X>gҴd1|'hRF Vn5u d32/T<>)pIɁ=0VOBKlBF9(-.}8;#Q,L" lrBK@m-SoH?pXmPEPSds71lXh2"vJѥ3vqs,.},(N L*o-Rp?HbodU9UqA6qӒ+Έ-&Xh2OȈsWt>t>it0184;d2)7lςBKP\m-Rp.}?bodU9UqA6qӒ+l-&Xh2OȈsWt>t> P2a&o=  Hq)CEBK0lkP.}CPN L">QW'+LoD {QCP88ֱ1CFWsS+]CQ|N LoP"}4 $W3(-kgG7`}7K0! .}} ~!}7 , ? Aѥ< u*5()208}toylPEPF5U;1Fk=H]r@#ߺNw\d!-A.}unPt>Q^SPb .}Ö3 Q/T8vp}3l luxk礘1hjL0GYP}g.16..ЊixnG[&02h͓..p[.}jhʈrG-X5+V&S0RfO++z4I]a9\ZD@G(-@YIVnqtV%l@\ZD@7 97#58PWY4p.} ]l@(x3+oӷDaG@/à+`MPDpE!-XMPp-KrVwD|VRW|VMPpbod(kZGP܋hEMPD~.}Q]\DfkG!=VZG!om#@snSDkyd(MPpixy㐌Mng·UUWXa7!-;V1`-5LFZL9j[v`.}lsfÇZbJ[1M{fq:ZV 5D]zsclklj+g `hR &ȶMd5il[ݻGp5/K!(UCd$k}G.}YizHRmvV wFBFEQ.k$T!ri (.mO-"%D6ju+"+"+ [ aF6mqd 6DVV?M.}f(hA6mqdFp80'qZIZvj!ACl&dO`n IkS0VGZ-鈇V2#M= yocu5n:?1?q+"-~.})?VGZ똔[p"-"&Pc)6+ wj6/MPDiesl`јиHNƥJj-S?I0|9-P,.U|0|9`< @-.}Öų &`c>AV6J`YIXU8_m-KQ@V>(?:TǕ#U@@V8}qW%Sp c{3<23-;}3. fb)l.}i|tx7Xc̓dopR>,l`a)iPnQ1"A&Xyunr]W`(jIW`(2,W`(2 pzwW{d4Ö0|9]G`'\U.}yWs5Y8 1`-5\T~a;l2\z9Mpl8.%%ocdG0V|ARDP\D>?!b~pE!>?1#d|ՃQpSG0(.}ҼFF.v5+(L]"xt,:VBRI7Jwh(ŅDt8Vc.\T L9kyF`((MPDuk 8eQ.}F`( MPDieQ3F`((np3( 8xywF`( n+ ?G0(F`((n+h^;w3-R\;l@p8x \9m52c0.}"<)/R\Y^N,&7EP M֩YV|sH,*j#17SYwW`(,(yHD,fy" G0V,:g `1Q..}w38&8}3.8;dM5_!5S$$pHlEdd>G@Zz_?Su!A6;1M{fqkc"-;TtԌU^ß=.}Qw2; ]3 UeX`WBm*֦lҎCmPdO^BKP\4ӯxWLf-Dtє?z1>[=O +q"!qnkl.}+s/¼#OO"gCNEBKV0EHO\IiWEaA1OBKVGKNm\ v!Dzs1(q NA*p'd;.}M>SwܗR_RbGKQ>dC>S).@vw?`WBg0̲As@84;dCNd֒ʹd6U@@ua v%5p.}D(8ñS {1kAI7JAtO ,8gFzepOgyP9M !Ayv5dC>Sxg\ v!!/3vսFzX8EBKR1k/}rNFYGb0hPCGBcl5ajk9yf&g͓~clt{SuV5+(LhlL]0c0|Y1U v!w4RYNCC/}7@dO^BKP\4ӯ^=O +-tw~dւ<0l9/tBd!$(\Jώ"6nVwB&cn-E&8}c:*H-l/}MPD9TƆ|QB2/}!"/-^z797ʮH@R?`X@-EdkƇ.i#$rƥT"Ffۮy+(L]ν22ѥHg1x4l"qA63./}!U:>xc2S^^1]cEIx9M kMPD^@'8h)3&WCzy Ta2>+l@prNI-d6xIuVht-s/}l}AX7q]cEtPO>,iE:5EBKkOFYGbN\ 5>Lw4IbVdSJN\/}Ewkn`d?L*V;#AI?"l+"njxu"A+_8aknle5Ȣ7&ãQBSMa# gf+(Lh/}lL\ls}}5 - W:F5>Gђ֫A0cEISnu IsY-&8.ñy|O~5LS[-} 2Rs/}O"wTOvrUz&VHފft''@QOlsE"+7lNbJ[(=nunfV]Εqߕp g< 3ql4Uz%66ӯ/ }&Wcy)[w. Δ"q~Lc+4 u{*%t 5o#,O8VlBdeѡk,nARDP~ERul!֦$El/ }Ed6pE O;L9joF2=¼,@s;zL!7?!=eEdfq4Rlpr]|I0Pb,c0C.yXGbG]xld(csK/ }>@c0mՕCzXEq?pR@!QwF31]wuq?aFc01(oAUU=[EAd"%7a,@"H26!ԏcv/ }lKdsۜΔfod(clMPD6"j8x# mE}H`P Hs=[7fBdÃO`nr~/Hs=$g'-![E./ }1.S *W-5&gi%ꑲ;QEm4zwET<>'f΂eJ&%rz12sr0s6P` W@|G]D v/}Phqt(v= @A=cuFg0[b3VGV0vc*,l`Fr438.%rdV}5/K!CC/}{fqrVMS|5dѝ]=2ݩ68IFMP C\DlEd6rbJ[AQ? 2,'H7Ta|sߠcZ1fk)ZG>VU9/}VXJ?`XXceMPDVi vZt@ݽ"s[dñ1'\UW[MauGG5D-U!sw= X[dkM9=LfiKpwÈ }B6; Q 0N4ѽyllllCC+-Ma0_d6U@@Cm#ѥ32(lo "Dl̀0EhhN<>74v /}νгr詪ג-b[MvJPam-RpvU 4+I,AI7JA1#?jz8u{3iŎPJ/}m-qR.>dL#zA.Y'Lع^w%,d'!%0_qSs?Ca:1Ql>O= ƍ{71>6Lg{";'#r/}AG324l5]x73n1A##|x4s C#74 ޝL> OA;+JRrV/}/%8#+(7sl#l8N>26-#+Ɩ{`-rPp4T~/MPDlu+p>6+ w MPDsl` ]3Hf?glvy/}=R3 .(_>"Niu^ß=Qw2qA6е8(+q,maEˋnR\OERzYep_1),%"?g8X1m%يK!%|U/}0c0QU8.`c`WBmJr:DO3lO7,ds?-?>GVa58S.8us 3dN L`&1\nyx!L!r:DG>!.Zl/}e;IEBKS ]b;v1kqrNF7=>^CG0(~w>n#p!m2+ZY)^w鹞Ku&dGf:OP/ }Vn8V7[xg\rw,wEOiOP~A:I;+G)g~Ku&qݕJQӒiQ+h8ѥ+(LhlL/!}ήGK!L<r.P1#,?&!a)/#}/7?D>6-@86 KQ6-@868e id7xys}2s?8xy/$}C+xǐFu=$/-p4)l"5S 3&wfUw`MPpUMPp28 ds?-?>GV[pG4<@trxF%Sar""0cEI#䭟,L' w$@ `M,gAwk_2/&}&'C ~ÕxBկ,LkfUw$p-/|8VZGǀ>?&Ҽynb(p*n}BK@>h)`WBsckq5/'}Ρ"_A".C[QLܘsr!~-2}+. v%5pD(ra VGBu7@^+q,wEK!L!&7}CAR/(},mO j#sayg0o%8+"Y"TB2!"" Cɂs`m5uJ2o&UiqS5VBWt0. S8sB1k0/)}pEdo vBKЦڬw38%%u1!;$MCibRסA[T148#foi|q)(8\Ӷ2'W 7 `1.)/*}[ -$_pt8RCi =`.`CJ#Q3cEI#li|?:T/6rx7s66p:d-12pcP66nV%.O;7B]`o v/+}u-x9Mpڬw#A[n+S" ?X@U##SCiPV9mO)L*E#QBN6GBVf"AuceO/,}s1&a=mA1)%]TU#AI"A8VrUMPDu8}c:X@-`EY,)SsV8V!$}Z)7nˇ/-}ڧ1P" 2!bm$knjH[0jzc2.797ʮ/8P"h{N6VEYF2|8rE!nX@->hFR70=iziIOB/.}KۮBR7v5w+y9TDtih{KQ\T L_9>Ym1k7^CP+\DNTp9_+c0+Cy+y95Ҕc9S3://} Bd"g5x9Mpݤ|Ku&C]W'}7A:I;z1ZNTp9]7V8ckƇ#׭ix  vռEdkG1k0rEixy/0}I L*wVs= vBK{#n7+<"12S%KGp΃@b 8õRPCմd(x&QQ7}7)2]n3"[5V"@RBF/1}9:w)4xM'5'@K!kMP>8rP@.ZpE.8"xcs6.Zu $nE! :c6]b< Ƒ\@;9tp/2}Jb\czP釡?+[5 7_4(`IT?C/5dl#<ks96T :S|1[3Ow#[1ecX~v8c38x-x9Mple/3};#`A[n뱭:`X Q 3.pSuZGC˥n$iE:5OBKvc%L*u~c1\ny +Dt/4}fEBK 2\HgL~a@MPDu~c3|:1Y,3K>EDہ38lU?$ sƇ(/8?t!$%8njx!/5}R!&g5x9Mpڬw[A[nm;j\DMPD%;x7b,c0ՏZ 5V8ckƇ. ׭ix  p#7}7sAc0//6}MPD!&.?WW'!Na|&"m~U9CeUSA׻AfX AE!XN_9D A:I;r2+y}7)SMPDjxcäF/7}'!ӿ83#`lKu7;~wQ^-[h.d]M3DSݛFg0q\Z4=W`(2ix 4[0×K4/8}GbDtJs9leCys[)[d?p‚ }Bkz̵8x hh7.P-$xѭb.;H\w:R[EJłzq\M0/9}I+ukb~^'c<p4\w^@ᡄ#bi:P0!LElee_/:}DfviUc?Rl)Ikw9pk=αvB8Ac38Bc0C-.& S#)CuXJN -Z&0ReP132(lo/;} "Dl!Oe-9x 9ъf]nSn+A1&"LKQm*0 .(I66ӯdcW`{KQ\T L>s9LFY9/<}=y8ek3`_9Cn|OAu7t7}7 `}4R`Xu38TW[լkjE#@Bzc1V2[dNlνгreג-b[MOW3#WA©)x7`XXu38l2C6P#:r!pX9/>}Ku&;& _93B@f/pڷn?A`X@Z&0RvA1[w&-_9#Ws9T:8: .g5x9MpݤyP/?}Ku&84;duuA:I;1wSۮLF,)w$ h[EJvoأxu9MpM-7PF j/@}E#Qm$E[vud2I-sVm 1pHnlBus$Es5΃MlP4^Q?,<31LgF)sT~_/B}/-^4pK$82%"O0x)lDwrJ>;k 'VCK`#+8G|65}1Ws-tių}1Wsl +U!/C}UQ"{P -pfp-3n9"R>6 \!#+N>6] s?˒?g<Ch1yV#P#wwl|^'"/D}=ńzZ|\\Ak14npl|ic0XA3mUlgAXuVQ+dI+ [ʈ= L떊˩, QZ$`>?H\Ag/E}zZmOPZ4';ğ*" Cɂs`fG5@C 0QΐQE<-CypxD -y0ų!RWw8P}xD -yxw /F}&c:-yhr7Pc:FOU@@-y, 6 )k[!-ycU5[!-y,1Pg9[n/G}fE)G\Ag1OW_N~%U@@mupG9p04S S); ELurltvOePDw~" " }f?.^,xDZ.~uVV$/H}KQ |108V i1N=D#]#SC$!&-U@@~>O=D1$7s?"c<S8?eo|177`}7/I}7`}77`}77P.y0pw0pw0p~26 ƵZ}1f1y]2c<s5a)<2R-s@p7sfqzl]w/J}0U?;K`#` TaQ:h2x MWORMC.MAEnBdqz ;T@2) H$TT -X "x´æ 7ey#gM3=6/K}JWHi2Ņ FX!#i:7u93 X&Ǝ-llqɔ ЙS?;otQZBPFNBqYRd#T@ȀCVlnEsই!5/L}#B FLǦuȒ!F2P A͝ ECavtsFSvF)1; GoMiӔ!20+RjB"# SƐ,ɛqq=<7 {/M}i~!QDD`y0cpImTaop'!Y\( 4`{("$QDLXX@Ì}(GMFP &>/5.yP8%IHQTa6p/N}ID]en@D%vCOle\suP0Q#G9cQFnlBĄDf0RvJ1-S;LFlєaZ(hrAIŖ/O}u!RJ11 A!ENP!d:ZRrvA&Kŕ6Zb n[Tp3Fʑ C!8urqF0ǀv/P}i *Y 3a%т$}5:D/p}1Fr4K1&SW-ŹX?ʫ >8R _hvvچ14m--Q%a^rXݹDRp/Q}VD T1,Q/>*xmFyhdlrESz9n7(ts1!S ΰ%oѴpKh? 2So=ߡ=nx>.nh /R}P"w"XA|{|TS}8U4)QACL6(4o_c*83f?* phR99NImT虂T,fE `h) +$QT̐5/S}=` ap\1j ANuC"T%NIH\17%y'U½US0a3TNlpT@P7NYN%д2f/T} ]=4 "ȀeRce2c!{Nfp€M:\, ox~0` Fن>~`@07 Is9b, A*0/U}rëH7`Fbh4/1zЄA,@EUPoy&5& b#Lj ;=hJR@|ZԨEI UȥLSeJSf!sLj0/V}fHMA-$: "Xw跻>n ]hCL=)FiP>H S%jWR&,Ws*V4hA6BfS+k]8 6 `sۃV?U+ey/W}P=hL{^H4~W*t1HSRgM ʄjSW-j둁q"6AS,rMf~KW@'6=;}BW jaKw5ġ/X}C+0͐Fր.氆e (x&F F]#IcH\ca? 6"9 Ip!=>D^@c%\9Fr,3S/Y}y!crg<#k ꌇ{D( Yx,ome-l) # #yk;6\UA`Si|d!fUC h8CPT27T $eڸ/Z}= UtGڄn~3qlvŀE0~6IS,=p{#`~ 0dOH @M: N:˒PdA%&( !/[} GPĤYT2G4YP^(DCo|G N3 vO">C*0 ɼ S9=5> 4^0}?PhgQz0/\}YkCԏ@ EuS;@LS3&X ~.x+r ,8~aP[KE6S_?} /]}4"G=i}1 jgX~Eph$gЇ~ݷo7xGZr~~n8}m80~! H}0t%xW|HP2| PV/^}},~>} vL4XGJGp>H7HaQG|8D|ؗ=n ȅX&jȄȁ>m(f&mXlKGjsA 5fqB7//_}2mqe:7/9srLx8mNP"z]KADX{xVfP6dI=:':Q#S0X,BHDF`8.岉.B`S0#ry(qP/`}f;qkLEgxHy9?`&PG`wbN 0AE8]LxY| *hw ׍C0UXGVd@=q0ȍ9G?P?~x/a}& wI/g@,XǓobbHFOdNuzd'nUD_XSPN pL-z\SG !3!0V?'kIX)D9uUwH/b}u`qGkOOT (ԡ/`Xzr'3Lx$rIN G7Y2kr PS-T0ٗO* "CxytBКŶQ-PlY;pN1,/c}8)W1pcɹKؓ 8'woX@ Gņ(0t"tSJ@%y()Ċa)v0eU3Plw̶/1%rDR0 ㎢'k)"/d}I( +  6G&VjR7z/E p6zӉOm"` A4Y!:umSp&ֈAu)3_9|O m #0J''1ByWyG͙+-/e}9 +J,9X["u ;Iy'ynA Ө)zʂ|: Tbt H\$)qȣ"GQDH1.:q'c0B(%DLAEJ*c :rtE/f}*sGY1|ȇ뱂GyNݪ4m=(uaISGvn`&cF&j#OIr*sK.IB!P*R%u;++1'/g}5sc8$721m( # O26r9HKa`|1sc+6xW0qP"_}v/[2גt/FʗZ@! K2VPm;s:Ǒf!u/h})89[-OO~uN9N9# (&Ouw/UG$@ߧ_UP.89ZrudFvDT:]BT@OPR<2!EIUE1y/x/i}02b ==.I+cO/@iK;=?K)q݋ m08#<!MU]i9PY:`4`qeF‚D? |/j}$X {Et*C!+N @NΛo}z'#7kFӸF@'= 9 #Q*Vћč7-JMHblW|Z/k}0 ,4< %x[VvsOwTd\CЗhE(ɛkgwbH9 4/q}旴(p{fnK1`*dPA`= ִ|7.y4`"j"َ.k@o)`%pP.B" =`"0 v%ۙ-bz@wZ|n/r}/@&" .떾_"9PE7Pٵ_8>`h@.  +0dn.L:\O쨾_+.I!`>n뻽BZ@>&'P"[]/s}'M/RP.TpQŞ'-@p-FDG0A+XT=~¾m> CP1@ɮ_ O/t}"$of->?l?5OM2#WP `S{W wKt|e_ VT 6>}DCJXoXS>:[bd^b,㋣/u}J!Gie`@ah˾N 2.srԡ5+\3AԏG07ζXf C6c)G:K5}4ѫQ OaaH\2NJw/v}kH9&杹Ґ?6kOà_uO?> ݢW{$e;kp0Na+anD-7mڌ'xei}Jޱ՜aϡZ/w}S.3"{ݳRϱ2%o(-pM 9,1q@53IZcW*ƿh?_3Mk,1qۗIpwQp}Ip95,Oopg9*ߨ/&,r4$/x}$m@T-}&,PNM{"(t@ZiV;1s1 -B בp y";P)wk;4: ))Q!"@'u7/y}WkVN)ı-476ۡI )=Z%Ao-R%ARğbmvy"Uh-Nz1=UY00Ͷ+R!nOUq;/)*nj f/{GU/z}$ EeqIZHPpx xU$EܜL̡ᦽˠr?$ɡEG?$ElG#L`Tz80gaI 'We[%L`_mJI0/{}an$2P;4DEk+R!9swIUqӜ QnbfZ ;@h."#8- qZ .pꯪ@ՕFJD:q+Z%L`r3Eq/|}i;1S7LxSk$JAL#L=kXXUY@ *Ҡ)g3}3dl-bb۲ˮ"J;$)/}9d=񃳺;zK!GN y5:ڙ?Sévbw {Mi-(pl($ݳL'Qx-IY2fb?岈9%E?͆9/}z,K*tjY2P,K8MTY.C;,Kr|ic-*2}qnrJ_ilY2P'2r1vFJ*|KܢB-vͼAF+2/}Vfb?1].SRYil`zK!GE!iw=,$aA`!JɼIt8!pJ坸\(@,sAS7Lpɯ/` "8NΛX1@)Unv)I/}wq(!` %ibE.o P#NΛX1@)UɞbZcibZcWfИ\,zUJunmnNB3[-Fki۲\/}҈5(i"+A&IuA6j{n.YR:qxS0vz.`i*e˥NzA_hi.HI)/ iY /}ϱNл!=EXݻs⎃3FNe)U.oP{NM~Xݻߨ/` `kaRfR5PDT鹟y쫰DOe&k7C8$/}wipEwo(_k8먚!o5)Kζo4{wo( 'r-)Yٯz,1i(ګ/}HHLlj|C֘ fwi ګwoxA[DkAk3zZw)$/}01h8M|,,K83q8t@J_z9%E?͆9z,KrT"zrqWT+P`4X/4eС+iwI47-/}2'+0(2}qn:E{0|il 20Pmd۲S{5 *83gc7K ĢNıER L+-N|/ *'ibU/}HvŜYpE."ι8o-@;DŽ"CS7LxS7LL|+x0yy )Y*ҠXSҧҞ/}!mډȷz"7B{[n/,0|-xlf!/,"ڊ~/%L"`;-QQRQō-7Y$p"RPS{/}m-$+MNm8py , ?n:4w-2IJ$ubNYцm x;[r.kd-E`?ApH˲h(j$oީ{DFn`Fx( ɒZG/}T ɒrH`]q'v_^zq#A?)0<]NPF6=U)TIA[M>?n:4pETNJ59re@x;[raEbwk;ub^/}m[MNm ,i&W,/n.4J'-;! u<]NPX8JeC rNYCQ$?n4%oƠTD>Ey w{9/}(rHft. q|;(/z@#4ةO5: T,+Yfb?Apbb/nT9y +$%)߳^}I @GNhvS.T/}CHPv2B_U0[=1Cy)}աrNǓ?2ҍV'BbOYqk/4)ISBMo+o5)KΠwW+YJe*T/}8m ,p1kV3 #X9d5΢E{ i?Ap-,KEA6LpE?O E&.JC{f5`}?O*ed-E`?Ap ԭTr/}T L`tRg K7Iת(!XH2iW=.Gi&)iph@2ҍVI z},1o5 pEȆG ^?пP!6,N`;F=b/}{==UpEȆGIl!9MȲ$K!GER{e2RdHiD>-*EȆG)I#`V$aTH->D",:I +", ¼ /}s@ߙ3k+L++Yfb?Ap\r:*r'%/{G)L*89*zOYWſ,w0ͭCQ9, ¼HpkY`t/}*AL9P=LN' wǥ8yO`M?кRI#PԬ_)ȴ/Pz;vicŜ2/}CDw HKYِW/PW<[lHpP 6ODeD>R;MQGݐWNn D>3P:M./}C CG :QT  YK/h쫰$Hkg&WZRWӌuEaB/{'iB/4 +JO-wkN=÷W㵯hTzq#/}AI]B_kEıٗ:^*xS{9k^ Sݢpsp$;$3dQ̫f^ͻv{+MW.מK E 1H¾v&閧Hm^Mƿh/}z7ןHQx5kfb?ApefNlG18J]Qu+XFh.Y}o ב榪š1!PER/}EȦlrFW[ ۞cwj*kwz lpEI͑>rt5͡ g.F35$󘑹k- YQٶ*ZHPpʼG1$*%/}R4I&f&My+:w-XDr S.CDW.SG=] ( %iPzQ|RUy+;lFwR""Kl3'T9I͑i)/}WTz:|{fN;'WqX xNPPTTխ(5,P݊RHTխ(5,P݊RHiM-=_p/}b&XpD⇱rq+Z%Ak KG4_#ɒfOؙ" Bq©j`$db&h;$*%MT/}ϱ\JҚBԸ욾EXl/)db&h⦂,opg#$Ī#F&f&G_2Lq}3qB0[`dCRHM&f&3"'Cd94I&f&nz/}e`7{-3bCuނ*8o$ޜO -R!C5"7'6$E&f&Vj3M?@&'y ? >D@&5d" /}OVYpbCt2V2lh⦂C8xV3#0 ePD K`yGCdRY-w^vg~7R8O*@<;L`odb&h⦽bw h8۞/}J&f&n*w#*08:=U'AwEJr=O=ճ9bsg5޻@-,y<]W +B]IF#ۻkAp9B-B&f&njpbCr*+R!n/}J{ָW伖8"Rp"@m`I$Pj&YY@.S|ș8"@SpqyC7Cq#ګ$n.r+4+R!kAЧwFki/}'q+ƛPz} R{[ C7l A0)E?p(bN!AaG-J;S-mKt¾ Z, Z=o+R!npEjwo+4/}SU}I&lҡu'%= 2F&f&'*gETN+ Okg&Mo.U`d/Ai&Mok #ګ'T1V^/}J;xNB)w(piK&¾ ;w x(a FQJ`ǭ3tk9H͡E` `9K'=z$3psCך1SU2{*/}&l E '-7 |p|gAwǡQp fӵpW"ٕZHm SG=] w+LZl zjpLআw&CZH;POx/} :4͑ h9hYԃ"l.ɪ ]}¾yubG#ګwR"rF`۲+49FAWӱ4"$wL1H)gc/}+0xuYWT,3bC8tj?@&g=T3ەT݊X꺝z'6D'תANխ5)MBHJ3y==C8T=d` h8ջ@#xN@@B@p&C /}AEk}H+ګ^WD9T݊P?Y xNP5,U;D"6$OT *Q=&lSU2Ҟ.W ~iwճ`F-b_+ ѡ-͉񹽻/}q+'I9BJ[#A;@Oۂ{G+R!n=c#.L\%Lpr4`I$P0+4n:Hn94)kFA yA{C 8AKMWFONT.DATyedH+ % 4 /}`l@q? ` va6f$$R,=xH%< mpŃhD 0ф|&3 q/!X`EnjȀU3rʅ/}ӾˆJ&Ԫ:|׍V Zzd=R>n F5dn@'|aB,Be(#<|b/.8Ϛ 6\i2c.^6-b9Ggp1F@ 6v衇nxt oX C;^x 5l@C^C- @0v@L ?\N@(@T2/}A 7:|p@Bu/ $`p 9ǜӦn30Iw3 cxکg:8rhuNcTP$~NDr nFi~^rI%R)~Rj/}CFx-vmJjkYZB0`Wxe֮W|lo%UA_eeNW[KK6FwvVRέ;i1dWP"Ua0 IA,w(