From 6a2c6b6363ac2b7a48241899c3469268377a7851 Mon Sep 17 00:00:00 2001 From: tomch Date: Tue, 19 Aug 2008 21:36:31 +0000 Subject: [PATCH] Merged from Ken's branch (for CP/M card support) --- AppleWin/Applewin.vcproj | 36 + AppleWin/Disks/CPM_Apple_CPM.dsk | Bin 0 -> 143360 bytes AppleWin/resource/Applewin.rc | 6 +- AppleWin/resource/resource.h | 14 +- AppleWin/source/Applewin.cpp | 22 +- AppleWin/source/Applewin.h | 4 + AppleWin/source/CPU.cpp | 48 +- AppleWin/source/CPU.h | 3 + AppleWin/source/Common.h | 7 + AppleWin/source/Frame.cpp | 3 + AppleWin/source/Memory.cpp | 10 + AppleWin/source/Mockingboard.cpp | 11 + AppleWin/source/PropertySheetPage.cpp | 36 + AppleWin/source/PropertySheetPage.h | 2 + AppleWin/source/Structs.h | 1 + AppleWin/source/Z80/z80codes.h | 219 +++ AppleWin/source/Z80/z80cpu.cpp | 2592 +++++++++++++++++++++++++ AppleWin/source/Z80/z80cpu.h | 182 ++ AppleWin/source/Z80/z80daa.h | 2063 ++++++++++++++++++++ AppleWin/source/Z80/z80emu.cpp | 56 + AppleWin/source/Z80/z80emu.h | 18 + AppleWin/source/Z80/z80io.cpp | 17 + AppleWin/source/Z80/z80io.h | 70 + 23 files changed, 5409 insertions(+), 11 deletions(-) create mode 100644 AppleWin/Disks/CPM_Apple_CPM.dsk create mode 100644 AppleWin/source/Z80/z80codes.h create mode 100644 AppleWin/source/Z80/z80cpu.cpp create mode 100644 AppleWin/source/Z80/z80cpu.h create mode 100644 AppleWin/source/Z80/z80daa.h create mode 100644 AppleWin/source/Z80/z80emu.cpp create mode 100644 AppleWin/source/Z80/z80emu.h create mode 100644 AppleWin/source/Z80/z80io.cpp create mode 100644 AppleWin/source/Z80/z80io.h diff --git a/AppleWin/Applewin.vcproj b/AppleWin/Applewin.vcproj index 35af070e..78872504 100644 --- a/AppleWin/Applewin.vcproj +++ b/AppleWin/Applewin.vcproj @@ -525,6 +525,42 @@ > + + + + + + + + + + + + + + + + + + HdS8#iY6-0NI^)VY z^0V4pWm-D)Cs&n=F?vu!jtZZgm94~}Om~4z?hgE_H$odEZ`G=4+!R%(fjJ$@Di=c&<_2e7p!ZijOZ}+Y<(5VJ`o`Fs<&~gJk-aw}qXobP(&aMe0RdwY>=4hh= zBdB_6PMyP1E$gY5Y^!xrsyb)XTeVJmxW=@-uH)H^z;Ie_+Eq71{$qVHxu>oK;8p~3 zyeMg%>2#flmguVLk|vO!*A)kP=-#VC$u)I>WObb=3HQ*QuH&%i1l{$zK$LOa4R1s6 z7v1m%H+&DkUm1YE4)CHR%tLnvTCuIx&fwOQ4{G_rQVeb zt!|HA;8{zQVVp8*qJj9jJ_!?zL0Ro?Q1}==CA?~>FKQ{B-t?J%0L$>C!u5O~0jHLN zmc;4_&)UhN5{>C=y_%Bhi#^EC^~LZR^ufsI0*J=IXP}pn9|lba;^BwGoA|t5tuZ8F z)j(~i(jRM~xg>BhGMn6&Q~@jPDl~5jm9mJhqYfLa;Yt zsZ5LoO=n_T3OEHYia_J<|eA*d;^5e8{1HJwM@}dBv0+B z!xt9|@34f)nJLM_%>FH@JKhxR#IS<@pVmnr8$>x9{4zh|Nmrfwh7jmdWhA*2y%pZl7Z9Pkn3eede~B8uQ2e zQ>;pbkh$E*v>k5`XfL62=gc6U12!J^*XvojMs66 zRakWL&Ks;F_dU*Rt0};r@!55=%HMp`2cPSgQ^GDNPXMf*E@4NHk+M$TXYVXwS0+H% z1Mut50z7ATaNSbZ!Gg@gS6P2pGzP$z_&f=;Rt2`>8f!-<%dq1rYlo9n zRj{+0RmI(DXH^Z&^eVyq`MbRE5&hyN*@ykax39B~*jd*){mmZxu-l!ix9zMY$=4a? z)+#S33DF!t0snA+2Xr7Vs9^56SVxX(V^%{oN=!0H+H*1^L+unxVKx$_6snYU{y zyw2>XxxAysd~cii{*ptG0&#a@=90`MZ{PPod4T8JUT3z~9KOaXR~)|10=e?X^2t?g zb`=KYEP=o5@A&%@8cNtbVF>Cy09x{&Gwt^L_5BY%`uLLrpMCzt;Um?@ zPki~+NzLi6zxnpe+3)J9#-{VF7i{epFJ11q;^_Y2`VHsJTep9_(|fn?-cJu6{`||Y zbU(&;Z!eSeA=`sf@wa`S?yvOpI#_kc+lR~ZJ$j7q=Pw8dJQWli5-JP}uhHtrT7BI) zgV8jkVd$_3v!yw*#flScQKIN)Vup)5?caA@jg`b*iyx7YC><&5ag7>1CTVQ){c-Z~ zDXEGHjU{Y-%r0hSjFESgaWEN==bfI;gCVFKF2oagr(Zzf?ie!(FCic;mL>6sJ9MV3 z=0IG*K7q+S9vm1CW?crNtD6N3sW=*s7&a9BtcZ_^iX068=ivE2UTOutt!DvHu>a3l zR`cB(?vU}2`A)^Gf#6~D4>xX9VcWLEe2akQV7~if_F}%~+rLlnHkfa_0c?;LIPhtQ z+2>JtJuf5|RQ$3f#$aZ5$Mp0LkMf~D)?}nQs&% zZyo-23Fpkt8kp_U^@lOv@|ddrkN#9MY)4Jzk{cE5%q93&KEMvDtoWBcRfo{yFg)I? zm}O?2#(d}W^A4Sv<$GZGM^M6!nr&uhWz3B^m^Vs1Qo z)DMpVUQ=*Gn7IVLfy)00i>7xS(OA#mVo32BWe~MWX`g2Ay4fY&ojUKj5>HRhGEjEV z-y86k;j8m97y%UWM83LFh7u!(r4A5*YBJGa1Sx+L=sId+wT!Aq%9SA%l!vnh5V)U+ z4M^aieo^@bs2UaaCj*C@Gyzn{ZH5TUN?osQxN*)j#3;XA@8{>&U7%945}Mb{H`3lZ8~T>C8C;-*=!O`ntF`2N1`D|rsh%`fH_^z*HBz4;y%ZFYF}gR- zfz~_+y+8qhet>KZxf+IWJcK(s+ys?^z6tHvT2HPqrlPp*9JR>JE@PYniVSmr5{+8N)?4hlpN(XT5yjeTQ*;ay!_!24MmC$P zWmcPBGO5W)5LlSHdt;wERHP2=j#Q}!boUIGXgP3Cj_!{a2pkJ5CU{s_=^kCi1%i)- zmF(%>Xxex|Z>9FNShNW&xw0w6wB-VVS&8yjP%~Oknr`C-tv-RxgFGtQn&2@Ar>!O# zO%7_QC8@@)-5^soktG&>KgGJxptTzL7z(gjjn1$f4u*5pei&7G!S0w>x<^#*L) z0FY3&1)c5f_p(HnKx1*nW>z?*6| zQ**6^vPrGc(XFYnE?W|&qgog@`@Nms;b+@Jt;Gx$24Qu8qF>f*BmG+dc#LrXHxA+p zThyc`(6fc-0i$*Z8=Qn67RDD;7Xvq#Y$bewI;b5M>euryjMY#A5Cwo55Mp?kw>qUe zve>lQnjzQQDu`y=0n^)7@(U}2iFuD!cl()6TKRqhh3mes%Fo+UAO(m84c|#CS#71} zw!r8hilICZp(q$=^!m~0xd+XSgl;Qcru!LSt<}&$gm4sdkE96#Zud(xvx z!N9E?44UWd1oF^QswRqTBI_*B<40tq7WkuHK`*Fu3*SG2M=@Hc5$DO_Ep7;u!N(q_ zKHKuB3kK?dS>5M=Vi8^NaVsjk#9~2YoP*Fd+3qSXJzHY>V~YZ7hesKJ0fB}U8`Ywd zaW&z^fuiu@A#pIXl})l6Hks2#MObRkxR%vCt_0`}YVbx?c=P=c<(aOvs5Rlbi!H?( zoxMdJa8?&-C4X(9{@mh3e_-;6v_i?~+~%Z?gfdmugI# z&xg|!OzY2=(7y1bdEutj=Ydh^0B`Hh>vJg2^I8Z8irBtn-g)^ATQ>_jNwnD1q2}sh zBUGm7N25GA3WLap3X&Yqgjbp=7$GQX|M}^2N{^Z>=ebrrHKsYT`Q~}8MN(&5_m{OF zHs3uTsJBj>I+$+Jk~QZ;Q>cZ_c8js}sIKNbfnmU4BKo6l*o+bbOx_zd5rnC~SenC{ zN!sFW702UE4;|htyKY0%mTaPc$B`dfO1nK%=FKiet5c+^1o59YkEu%B(G1CVHgC1( zFx{+XqZKOernSfXf^`d)yzXozj6VR!F z@I@iuYVzwgw<#1+H{#Yt#OyKjyjNCi1gxV{*6k6k{n!YE)E2lZZnbgUUy9a#xY)?= zm)wNx1~e#UJ@u1Wat5L|ZDCrTsn&AV0Ptoi-eLsQerN%<3B5YiL;_>%w7?7}j@igA z3vn8?nT&3SrZ^?XZ2U4()kNH|sYPdNQjA2upSkoeB_Fo?nVn$leb{8zTOCeGqb&^B zdqlfM@)hc!MWR73ZRxwJlJ_$tW}B0ewogkZiFSgtod3g+G^nOV+%V~u51ZD~>Bf!dyz}`1}X_S*T2*jr9cA2Ao zumQJMLCJsns>lri9eea!9nm8s@G2aJD^;yy}jIwQCz`FI`9@n3jK}JmkD4nNJhBq7jzOn1M94 zM;uwzNPFnUHtHRek*bz)n@AT$`|C0r9fU8eAbX1KFof<>! zr^uW}I#~BgBXx|jlXi*@&>d*hLquzL=%K>58bvuCQ0PX=t|dzv9de&0jmbqp0eheo z@IB$vG)A|#5vmgvv-J*@8&XZPN_1x$X@&{IPPhL^*;jxmIFq6{6ylh{?eHv3F?BYk zm^keuubtwwYfQUslsC$dvoLrPENrFG3G{oOqC}XchV*Wyer}+GsJ1>8wTp5YXG>x0bfCal0@LfucG15LYzy?a8+U8wUAO9sPlXBgAR#ghpcqYZi zAqu0>?Wx-XNdE#Q@Y?xa&>_AEvLFp|32xI_vm2B=P4Rspo$mvv@S&p(EIsOq7P^SW zl-mRoF-PR!V1VwQ8@e~zwXiV3(EFGM_O(bs!`_CJL)w8=Vb#2TBUl#Vq|B{CY^TTqC|0RB3w-O#v;YHSQ>_iJxyyw%v-c)t-w zyiwh@xlP&jVOwR}=WT|z3vHck-EBA9`r7C=w#~;Tu*F+KZNqFawh^{8TZV0#jo+4M zV>hvzKCls{2FlUk#<7vGHjrO75O(+T5=tjAY~sSA)wpuiDqOW3$K`nR#Q6*Hyut-* zidIGE6)uB7^yH<>3h~@TRWu@8n2&X7vbqMw*A3KpN(+Akze$~BvZv}+)`NNhdIix_ z?@)v8rtqf<>g;OS<$CvS!V72z6b;L-k|f6oI{0FpuD3)Yj{>#07yJ3&`#LYlN` zJM6H*w&(z2x7Q0=>(TzJcbyg5Y#}z+Q_s3J&R6OQjNxz&s(`Q=$Edf%)>xPTtKIPK z`uCex)|2+O)p0B0Rw8NY>IJ)deZi5AgjB(mq7}eyCDo5a04Qlrlf5CMX+vZiq)tmm zl0dbM{IppPvt?q_Swk^Nw1ME*VS_oL?v6}_Swu%Pzt#q{C%a-(!yM}FET)ugAdmpW z$zr1-3h^VDXoqc3QnhSi6DX}w$B=ddMNz9P)QmQAMhklGYvE%~*sC__+K^;TPpEb0 zx+P)qx&`D>n79Clx^f+TM}2snWSmEzerrWf+B#SsXcUke(gL~A4Kfz>51QeGdO>&q zkqVMP@PQ|S8}Eku#s<8=2>qn{b>nT&e)ym}QkK?aL`A=Q0X;u-KbtQ=*ES^1Tb~Gp z@1MQl(|J&q6MDDd)1vkJ7DG>s@(vKwcOxVvVe(FQxLAJ02G|1JNc@@}NR&+*(ox9@ zCTKVy@_M?}UP6*W ziORYxqio7$`KDeC&Lxgq5tQ{ZLaW z_hP$)nt0JJ682uX#J)W8a=_)Gmx<|Dge+ppl{d?a)bWdojG8+uuJpJItg4%v~8jBZAX>}qdGHy><$iFNa3-3YR1eiVFh0^rtmRLhQbtRt}dk@drF zJ%6f$QHIHnb!c#p6i9d8Ix0Wj5vjn;)ani}=pOA*FbS|;J9`Nh9~vXS(W^07X#X0C zZ^L!Wo5kb!F?`s*o?c9@2OlK2&pNP?7z0KHYghb5#=^jRDry2?g6(#?@{mThvXY13 z9O7tX6#rr$HRp;eYT_j{q$4gWSh8Q+<)?cA!V5B@5-&%T$-hR?AOsjSxd$wAH!cw+ z_h7%~kdYjJkt(>Xj+Fiq59zlr5z`FNK9s9A3K$rvxJ>EW6SV5kqUe4#MN-{OMk^{sd^b8$QXR?ALw2svQej5^Ul^<0@3Nxaih zUX(*rcWA`y&rgdz;{5xBgn$e7Nsa1`=u-Dam0rHDm*YuYzNjssJ#i0^#6N{%_IJql zb!a5pdc`cs*52y^FsP(ol2mrcKkF!_Ub!R@_sFAr=7scxMOAjFWuJA>oypAGc=v>R z&lVd?G-56>{-T3uxl~@X{CX+vi+fbdqI-<@$^eW_T<$%B{Ns9l6_zUc8Hx!qS&!XF z+=acpqQz0sJt$B6voT>JBjH0vLO3JgxtL#!l0zLEXmK(#0b5TClbJCX01B;NANz98 z-u)kID!xO537&U9$FBqgD|=wfWcTmMGJ53wKf*w^;xdDrjj2eiR#Mh`U5<5zg6H1! zi^S)>9F9t)7HJ+1zj#`0@V{GXL|sk1h(M$dW&WKLB8}k2Cj%q83am=qEEt`sl6Rnt zfrw;Fub3nCl)TY+O5X0pznAP9Na4}!>?mQ{_?5Z8i=Vynhu_6bSJwV6-g@P&D>%mT#5Q7ySPjMlw?%;` zMx5#mQ@65kPZ-W5R#I>(?v3UqhUVrl9Eb$#TnExQAw!2fE+*sm-$&xa zpyv`eEy1ok_C!8>pNV{!+#XDi3YetInGAl(Dkuh$| z;-qxtuLva8~fqzRD417yd!e(VN|Am1#!N zu4eEXyum{5eoK~suU~KW!mu0rXW(|>(I0VE(9xH>b1QR={=05g_-)B`m$la-+~)rf zK$?W`FLTK@a~~>LR5_w2xXNEYqjJV|M)?e*$5BCY0m|@z+I9_v20*4@${vuU%@9At$KC-nl**15b!^eX`)d%gHTJCFHT5Eh@MpR>Z|jYFGRLo zu;sdonZ0W1nnHZ~s-iVu*DYKaJxH_w2}0DG!U3SHMAhIoS<7FazijD3Jbl&D*9)PB ztmUfyn^|UGa-PsKz=Kq|MG$-Ga;Nid*rC!@>YF8Vz{+Vpf)-sAT9E?)BcYz+2F zre!@|-+U%4{e6Bm7W%YzXh&Ifoa{-;p)|Jz9)ZXZq5LwTnzcYaZseI;(4X3*A%`wz)c^2 zo%ZzCZpQBE=H8Ei=F0KnrOTEf1`KEH@|5YmK9h=;uUWeMwZcJ{K~&eH_26+0#Y>hh zSTfMc33&9le`@{zZu7-+T9Gw})opUx)tg^u&@Uk49wA3x4YG#Mhxu9iFJ7$`h*&l~1q0s>bcbhCoFX zv#KO}`%!31TGe!18(I}pK5`sWFpfzX81gbq7Q)n+K4Zw=z$kyF%!eg=mDQS->_5sz*(BNT$xvasYIbv@* z2k)aA7{Ua22sR;D0t*^E2L?yoAn_y=%%l7P`G~#p$vhNJ zSIy2rJbo~L)zkTtrcWD_^q7C=uU_-o>%}FdYuByc;D&TODj)W~pZ*lZAIoP@1VkBs zK#5QMJkFnF;6h^DqZhUe~YQ#i_ieUv-p&mjq>x z4%)}b7KT({$F9L4#`*39tn$s>*9>P0vHYSU9Q4gnd=a<{t;XCEOKu@J6RDOjE5+O@ zB);11P=psEjT9SjD|!s!4EpFiyzujGE8>&W#S{?hPUF}chI%;n6(OdFGC2C>AfY}PW?tE^S51FY{@ z7g@JiJhm@;Dtin21NMIQ*X(9?EBgXFr}n3b=Q;U}{5&#fW`5IW*v$NVRb!G;X>I{w zKTrRyDyQYWY-L*WJ6Sm`L-KOY4NafeFl?4lGV6TYtlD_hd0uAj{@}FihGVK}(^QQo zGSjjezf@(bnkg(TU%MrX+NzwKm)~5aoDAO|f^g2c&y|y*j4zaRdz9JAeEk7s!vQR( zc2jnq{$mg`_50GZT0Vt45SsVrHaK#dyPq?2Rdoq7S|4Jn=6~vB`fpg+8oX!`zIx3n zu)W}`SIl2fh~*7L*1)t_Rt zTe`e(A^sZJTku7%Enl!^Y0+{lrwCMvyqVLK*uV>vfHg~sURyIbpJpy!0oAXW|1#`{ z4a~4*wMNn$d>xHWpEh{RSy+^LYN#7bX zbDtT2>M(Olfq&LfII?X#x`?w4j{H_+-}*Idnjhnj`1X6xjEft2biC8W!I;1WuU&o9 z+*f%OLX{49RAIZX6(D9QT*@lER(@?4v-^5M_cb$mRjw(&R{2`__3V{F#{0Degm;{=RORIy#YLUOt`^(ub`^GytCYn z5)X$kjbgJ0Fk}csn}u%fD9xnY#+z7f+9draX%i1#X}X-LZ0tyD^i@9BQitVb<(#{g z*KEhq8UoXDr{_02v$GnT^3!yN>8kUiv8?ob!$)aZEmk0BeYG;D_GoTazWzAyvJH*Htp=#e*5w^P~jb#nuznx;Po)i-7|TP7i9e11A0t{EC*%!5AM zQa-mo49l55v!%T5k2%1dujjOQOf&zSGgUcf|Lq*OMkh}X&eB=g4O&duvMnn|e^`}P zdj{~Qn+`~6`5-$hujNDNRye%hRh{!uk%`JifpT*Geuk<}iYaq5^k-GIzf8^AKXPi` ze%aLY{iCwd_p>lS)Mm7S(NM3-M`)}_o2IW(Uih=Bs&d^ zkr;~r6)~SFOJP$>n6n{7r|On5QA#*UnRhF%1I6e>fs~2+pimy(A&_FX^1f$U32^u9 zgbP5Jf?rr0z7_MRGw$l2N7dWqoy-hytk&Ghm3o9J0n{P4Gc|n;UQAalpK0IlC4L#T zbsYkRcA)Tf6ecjQsB68HfeDIcC^dlz#c$ZJyT(8OU$CGG(Ddjzcn4(Ndj5OnTJUU0 zk=X&vEzxAGn!f^UEURH5m=C6%!sTo5_=GQi?bVkH2Sp@Q#G<0tfPX*Eezj;};eh-!f7vRKph^*oUk+T`Ep;IS{u3hB zBap(9rK{JhcC&Uj*rL~#EyJ>wuYd()#r)O4!v||vRk)yN)xt+jcwFc5`L7nbYk>SU zPxKJ1QqW{_#!GkOX2xSJ%0mIuGn#?}!;Xw^4!ajz5Ij0KGW08DX7HE6mf$93VQAgt zI{a?>iy?oDXo!lP{EqKCzAuJq@t1K+aOz~m+MXewdH$K>&on+`dB!{D#h7{{xUwbGZqzH~JR zUHHqT_}ao%MUU%WxD?SpmS4J}5Px;)YS@)quml>4Oh5m-O}t4(D@xJk+u~L8Ume)= z`$s!@AnyEr=MH@~xTWWww@+{4xp$U-+rlftON(9uM6X_gEYGjbf29zg4=iK}$b1W+ zB(VGrib(&!2>n=SLuTmArE4CUu>b9iK~x@dSyTs;T*(l;#HLWOpb#4!<*7=FxVPzza zAR8gLFSs3~`k)Gz;0nua9$dsCPch(2#PY%9X#9uUxT2?L`@iB(V?Z2oiVP6S3%oMq zqq%gy*z;5iC%ySyVJlzyOCtG}u#dVLNPUXK6$)Kq#*np|J4r$TtjdxFUhBWYL*&nU zY2+_@;Vk(}UPUQlP7Fr9p5U}opDJVHT&-OW@T^0C3^5%3#{CeqsYEEB>m_7CZHb$c zxhY}+#Ytb6`tV(0N(NlYuzRBa&vvMiTp3y|d)~{jxF~9Ym)!^jmeV4WD3AJL8WkBv zofuD@h_^bZs%(q4{i;$Ahq$R%GVKZ$$qkv1Tez?YU$m;|RkYZx0>44H<4|LI$Cr-6 z?~xnA>~@kC%3tSdbUS>t1f>dqvr6}dYRSz4Q6I!yt#UDko`QRUcT6%@HjdjmQz!QC zQ){}`+r`|o;`TnZ2*8B5iDwxbcB|IEmqEC^ssjSy*Qk&O1aeD{)Co9yUEhKv|Q>%OQkpI1o1Ue><{-}NPTE;sM1HwRN#H`aexy>DmhjV2U+5W zkaZ8T?ud+vg|gSUsOO(5d#ui=Vy;s@mfJ_|3U@iEaGco1qb9`JEm{ZF6dbjZOE9r< zRJ5-J7kXRcX2rcE5;-I*xztBWyY5neO4NBo~vJJ)G_gvPE62%Rbsa{!$X614DWk7Sm>%yZBzJVDaJbBNG!zolM) zMQMO!55lHJDj=4ifYe)Ip=M8UQt6rS>Y_5@EOsNkAD6i2k8(TpbI{roVsEO-Z~7d2 z^X_10)ON13P5wu&W}QL)oYy>3>q{NS)fx0ou?LLs_PD9OC8mZz>X#rozDC$9_#+oC zjQpE#itIVB05!cC#O9xaYSy06EeK8#vZ0O|$(vlKWHUEvv6r((t-;wM^g}iUL#Z_y zlQRe?Qs9GG#bH!Wkh4o1=!9D0of3wXYR$A$1(~!niGlh@tx9j$Hz~lb1wYJjT$lok z@eIKoFEt%yk_Et-G#;GxlLyF?xf->O7eG%??6&GnEPLQo3aoi-uMMf^Vnk9$buTwzC_NS4BF9V!*K_DMN3 zjfbd3QF3k!RurY+g6nH4mv|}2rGc9%P;%TN;SVXEkZ9El6kKNpH8swuwLpdopfqrw zPV?13S~?*m)fnL~PvO#j(h%A=IY6S|;+{a1FqlqiSpvxnlBaTIW4W}K*bnleT6mIY zxlye=$RHG4>JM=ch+r`yn2ZQEBf^V1JDKs0ufDA{O_c!zPxs=!Xl|XI3@Ip~WOrLi z7x6w9$Yr%C75~|;hM5ED!a4-@Dc%#|0dqi2CpabLT&L-3U>u~=h%0tEB#XVeU_M-? zx`vq!`8FT&9pI~X#spG#@pmzHXeshw?_AM(k%*JP!*cwR@D}MR;4BP_kfapw-a2 zsr_Cs{d}_u_k>B~B)k~ja1>tegv*NLW|($TNCNU!9 zLR_*Mu`e{`|>mtpdSRf1fl z)UKNf%u%wD8#TZQ5rAjZ+gxYVF0N!dcl}pR;*VUh*8$vPjFYSgtS+7-d)bTHz;yz{ z|2YV7?Sy-ioIz0=xU#ied(=9vmYmOr!58;rYz7eR!0-i!Q0C|pmlGZ#@p11H_|zL36VYJHZzV#0-V z7d#wvy!a)0yy;z`7OHaq*#LL17)33~Ou}K+89g9tje#H%pu`~{aAl;Ju7rXdrGeMh z3DS^L!a$I~GE&5TAXjO`-jK#jMUot)&9p-Uo{+*~+=cMvF90}_#H!-@7-Ix_dWV7j z%s?MB&<70krv|#xKsyZd#|HW>1O2Xn{?I^gH_#mhdZ)ovt%H66Bh^~ykNX;?1-R%N zx|@PNYFdEePrzJVedK6Zq7uYDw7j`pKug=(1t8UE)LP3!UVu1~PJlH;!3Rhy;GKFu zpv$=dBJ1q~jM)k|{5~@hlC>5Gtis?|9t=HSuTd~@-iE>iKiWrXt`i6?eSURA;0vOK z2M9}M5oVsNPYnq!nEUtaz~KcK*nw!ZC<_QY8;;*4{}e#S;6oiS3U=z+P&yO15mUi? zn*RT%#rY-ohnWu+nrcL3{e~|Tm0{+`e zIRc@1!doII6fL|2NVkfEEFhR!#Ua3M0JXhn%>cIku)ns)&6_N+NGTB09oioT0j@AyRTZnzfExaak z6%Qs6gvUBM1C$aOto%f>ha#p`Fb@sWF#Lf7B+4#0Ymam600woO&9n>XeyAC7vRCE; zkFDK4N};8Gnplmv>3jJU6d3Fa%NYo@t;~jt3ZlOsEnI7XElrZF<2qp3vRJ9l{S=a9 z(09-}_P1<{lvfQ*S9r?(43uo(h9%#%3Lc<}EYcgmi{&GIG~zEw?Xv)#`~_epB~@J6 zH^4tYPijbwvr19@6K!{C^_Qxn zEH10KSqOcCMZ-w_G1oyzeaOZzP&B>6K+$Amgz4!hxE=0gFSyh|!-KoGGGTOZ?`nvk z@neI?Fy4V!tkEIYz{>0ccg63XIMA!AY`12b6z{YNr}Ahlw~C zlH1*SsmUP(F}8<}#c%ne)f@;Q9tZ$1AFsP31a8~Tqwa>u+j*%FMGHiOe2N`WID!!G zcLz0g9W6|X7kW4(?{V){%UV{HFjAMoTppqT@VhLJ9tj_lHk-aA|{g`^WYHB zJaDP9Fd}f6eb{tjZZee=C*;6`x+^Ks7~~gt8k0C~mz0;7;-rLePD&gH{6EaxN9D#X zc2Rxe^%`KscNT~#!0Ab`Xtb$CmcXDwV}*IuyE4=t%oC~KpDj}FRb8@+mn^8xDAnM@ zr{otFm9%=%op?{R>;liY{;T7-PpLV+T zX^ZJiaR~%9zZk@mMe6RdDitY?8(I@o!>i$!jjkcj%ha2py0@UZ?J6VD##1L2R~PNd z*zm!;4e!t1uvcZ|V69%so|ERz;A6D3jh0U^B4k?ieN;h^ixCs0r@5wYlWCsmyJTRD zWW^}01(;Zbispiz&Wp&zxr!JjE7-6OJwS-1*%4SWCxQ?&BS6+d)CfnX#Q5Xfv95z3TLtcAp`%ZU@7n@BV~`Gh?mslvZVaKBH_mupBa4%<#d4KY&cTBi;^U3NO+Xi)ivQ-*#Anznk2AVJQ4(2L(YX zrdh*M={w>sy4PeJ3Yy^3O!}&+aTpzAx;K>W#?fqm`R<^mMS#-laK{nr04X2hP8<~q zEfUiroJ&>XV4}#ilN*N)aN$_TfZ#>Vj0a%5DKCP)ZpxoZQ>J%^)8|coV)~}3WH@~b zg>IXsq|-l`c2A+pO@*`Q?@fjXYDYK}9cv8PK)o9dtk*#~C15Z*G2Y<>jRJaJ`-eC? z+*$hQ|1F?nbUz0TEOST<5Pmm!j1A_ww5Rqs4yR!kIQkSpvZx*c3ym7hrHY=B&+2s9 zWwSb|&f&PX$O?$17RFc{is7>O9$QiMJ{N)3n_O$c|ixI96rdGv3f$N~;wNQlv zO12vrVkt__fMg{kkLYm_;`_qk@R=1pcaOFaiU!-#r|4T+Ed2n0jZ|Zd1CFIqOeli- z3fjVw7Qyz{D-L3QXPDZ~f*;~bE|q{gA4uNf#YMfvTmO~pO`hH5==LNYu#xsneKE{# zbgz6R$MBzwX!#bc|H@ty!2@Oib${<>ZYNdbsqwVht+dda(TlWCCBf|W0WLt}e;k*+ z=rxbpgUepW*6NB8TA^j%0{(Y7o3T@F23 z8>rwsAdx;Cl{Gs9WCb2#lC#Ck5IHA4j#`!p;(|)Pg9rCkIf;qkT~?A80-&xw1|F`5 zNkT@9M4!4D_D{kt6xMZwSx_NPok?l6lkW?WT7U;2O)i3M`eIO*TMf$+XbM|!JJ}ls zIP4)|-G(U=7lK*g9y^ew1VgK3HXaBTK-5}w)T>VNHk`xGu_Uj zd1m4k8-%lxSznv=j8DV$Yw3-qaYN`C?URRe)AU-?mF?lB$o`7>gAwljqSi!<$Uj8)k$#iF6oz!2 zyK%xH4&p#G@HgtsYzx?Ots*4s44yrHG6#vX~vfX3jMSm<7(j7P)XBVJRnDclL07O6iIk5z& z(c22**Tkt7@i6FDJcPwTE)+sK3efV}6QCM8yPSwMTVT$9?pLtX0;J@GIc(9o99E&f zHw2vy!Y#DeA#8nVooLo^r$y|EWHu*$1^#0Xk=9}#NEiD;X-KkkdV^H$1l?Ir!@^w3 z1t~8MwbI}=#(@kYcBv5hOU1LnoG3&@vmL*IUVOX@joR81xQ}o+#G2h>2u%ZdIyn^y zV!be|AhChSg|3{VwvVz~;)I|7=B5OjY$|agorz009)R|1$U^M|bF^GKu2q^mM#urV zFtK%PEc|>`lC&jlscthbTW)CW52IHwhjGiVM&#$yq!WjuyLmmuA1Bgr>1#G z+oHvGou^#k$-z8TdWe_O9?iRk4X|wxPQV7)!s~)X=s51|5{6OQp>ZWQwEkVV4*39 zf2PPL1BZp=YX|9G91oykfwBkg+@@p2;UJ270IbjtE?-4 zN8y%%VEj(<)(yb7dqy#Z-=?U+Kn+(-i|8A;TdxX&ANu2lu6T#uO3Ywp@So+0@?Qj< z>AvXBM}+zm?s9^Cmq~wLYSGTaxu^nIuut-Yf%Nk@2enNY;!f;`pxDb@ugR6UPRLS= z=5=obDGOpJ?$`Vk z0gEp(;aQ*r^gmR^Q$=z1sAir$%FKg}C2<@i5iAcd#(S0*?fA=L_kW0`2Ot+RtFpxx z?Jxy|?O>JES_oecVe6onhm4nCXhpfumr^=hE#}hIVl#adr~K=U^c!M5y&2beAY+!; zh`8yX;S%`YiSb&*0t7dsLB|9J87CO}Oc!W)cB`>ZZsUQf;_5>Sm&-_1J>wwedF{FL z@-tgyV~`wWH%53;yPlDZ=E9MF&7IB944m07FIu<7LA^1_zCjogf)Rg(!|ocxodb~T zzBS~HNiOn@NkHOg8zXg~*q5N#(@^YauJAJuZ!nP4?8s#30k&dLfuSY`k%*?7e4bb8 zVz@v8s+`d&&+n86iQyUm;<;ZSuNp)(Zl4tvB3NbZFt9Gz`Qfu+@g?r}k9$C^ii5H0 zgXI@Zw*b^x2M`8&3%_;AB6u#1cmg0Asvif|YQhT}_rQ|CiXQ^I4!My-h75tP%QNH= zJXIOJ5O_e}2Dro==Xt9@*kU9{>h)x32ow&;94t0gVTDG>Pjc(neSRuvhD(*0QWOJC zaR}TZnmy`Et|WpNb&{JtjX1>>fS{d#!xm`-4@5W7Bhd}Du{<0N5-eOmfw(}hgbNe| z%T+Q5?N5D}DfyC{|Dt=XHw7gyR1tc5GR|4|Rnhw6MtVAgD&eX+BMlRH-QlA3hm5og z_gZ%tcIc=@ltA4gcY%IAY8&83w{KEM4AOE ztIG+32om8K;EXjy>Prify&)!7a5bSS5U;$v;bL6$F%p|U#k*j2L>htENu}Y`C>$9} z;08dk4mP!bdx9cO$C@CF#=`|5P>-e$M$(C<5UG+r6mqIZ7)m2mYa?f`i=0;ynIZfUY=WEE@Bb9G zIeNjQ&96~Aw^VK1{06!vVAJjLj!AE;M^IF{-fr$ti`Y0tzscho}l#=4O5)gsYaKqZ4x3<(&uMN%p|7we4D#R9IT zKS!()JBZ`44!Apnhg8dWhcm(}a(1cI%L=MYn57YmRIPX4?F$X=_BUOMExCth3|os| zblQ!e=c?cu-8h0NrJez;9jY*0k|p#*C8I}clg|eRD%e7fRd766;Xy4N3nmgLVum76 zHd}a{ME1ZqOMeOjc44uv5V^Fe_yqtgwz#jtc)$$aXYc=HWYxR{$LW67cg7+7lY>^& zG7Mu6#LMdTt9P=nXV?1o&c(2bRXIX$4D+vSxdxEeUe64L*Hvyl`X9PX?~jKkX7BTW zXW5?jP~_Q(e&|)PmEk`e^B;bVwGjSWF9uefq2n<0p#N$G4xY6-z=O@_h`spi*gp;Y zYIM%z(o~Z(8MaP;O0KSx((?AZ$#tHvRbTBZ_VQqxT9fTYLm$!rt{#!NZgNJtQjJ!} zK*F_HNRYbhmK3A4WP66*0b(u6x$~k7@FJkle3FLczZi?`qbl$9nuoJxfFU~!WA@0> zK5BdXSgDY)=Fb8wn%We1XN`=4DyZ!;;bm%HJjEG_*ffkfioBg5G(15A>%hkC?diGM zb1Rr#A4Y5>_l?w$-lJR&q7^B$-+wEUck#$GveF}=c1V}E@yIrr%jE*)J`}-0LLv&3 zlFU&KD=ct=@=?^pIC=RfS+l!sY50qMrZyPRYSJnl@42N4SdEtv7deqV5# zq-t-9tC{}?;WcP`=fmysu(-j*ppL|YT?wp5#ChIi@}w9ss3Y;~XGUP0U2qdNz?uQ@ zm+kSuUSYX|RZro?P_W6l@sMR85BX-OX3x`ry%UPcjXSdVmyUSFdvKGmczx(4gP4PX zoyl$-vi8%I8ZeQ7{R61}&i#0>W>NR!Nhd1*zBJNwXw1A)O|8Fd^Fv-zwZ89{0NF!+ zl6KuL?YuWi9>ylU^X}c)v3e?XtWZG3jxD7Yk5yH_^DYGS87iuHto9hr0=}|26`-b* zg<~967L-4KkQmTm1AqaPO@wJN;Q2@NttSGH=AaBGJBKi-9A04Yi*L&rSE&V zEvY&&r7Y!*47lpEc&zL0$gwcJv@YG}Nz^A2*h;BQjRU^sN@i`|^^Tqrj&WL`GHW%W z#_umDAdQm|1GkFA5)E!aO~C7+4W+U!UYvmA%fLL<0W0IwvSY=9QqBdSkd|pY;j2kmZ88punAI6NO!r$Hf!yrP|clONvM3dB(l4v zujI?GOw%L^-2Nr05r?h|oresUp{m%D&l#FbYkcyaH~CM8%#RLQ?1}&qNK7=a-|qHEqj0z9?nmINd;^~eH$*{ zhr}WtEfwDe{r3i)fV1L~r0cr<#qf?^*UhepTVa&F$|bsaNjO?RoDy(_ku>uhP7v@e zf|y60AI(wnF^Bq;Y0YTZ?8_ewn|=AC{}*}h0^d}b?fob8LQ0a-&;p?#%>^_xTuOQ+ zw4s!?DWy$Hffg#XTzlbGF47B^(t=8T9UTx<)HzHY%)!rcIp9RAUBe=H{gn|H% z{!_H$OL6WU*6;D>#*c9kZ^r~8*=)f10S*t>;XqpnQmqnU;NkJGdE!=mEF9Tp`#rIs zrs!i~$v%-puM%-9$H3i0vGRRmP0w+D+hc9nuIyE@*iu#< zguX&qO^3lC+WNTE&41{yIBYj>Zf6uPr!tJ9ybj^JS#20YH*ryMN3HL~((6T$W)7I}|r>}=cq>1omU_L5cBjsj}M^mZu?$>`PIa>$wov?q4r*=5EUgM_6 zw$8g-5oy+p+KNkpU4rzuM!p3!dlj0iZiU|zCn-s-m zxGY`dH4%5RPxsrzrB85JWTi=HU(65d zg!koe!q6?A6m!i1Gq-q>%jbaoxy^}d34cy5#ZHE43_{#Gw0?)BN%l(8G~f2PF%Ilw z%M&HwYZR($pEYZ>F_$q#qsFRiS0lASiXUt^3zrsyE?AZib=6LoaR&?wY%R?0!SUCc zggIl|JS+_3b_s6^7MGtvl&6jl|4;DPb0&MW8X=81y2k1-zyJPZ?+OgoGg=!avk1^? zSR3@&PEm`8Z1V;qYMJMyv{q;-ZdFhZr@DyD($Yx-sPAdNmmSO=DwRuUj7?* z(O&oIA`}5ldrO>Kc9&cophMTG_yG~>Gk6SeA^+;6aRygBo^GH-(RJaw$#B829Xuv{ zp}eYfdgLd4dz2q{Vxs5F>hbQA`!OsY{u~>!u)LouZPD;TK&;p*Z|0*?(dQ{NWy3TW zO(wvAotL<5cje6Opt~t@7t;N61__yVW z7Kg*O`IW6VK8Sw1^=$OEz4$}BMSm~*iv%8S&t67Gntl5TR|ktCpJ?5$rMrC1V&hI~ zTi=hStAyYA1A2ll!)K!@W4;P*hqew~!42kYxHU@hEexvPR;%3!+AG@lgb9<9(U8s$ ziuv)Bo^;{CnsLF#*wk&_z|H3l$47PLCI|z9xtWO_o6iTqAA$|q(tPH*X!4CfA&W)y zW*s(CIwflTZ^Vy3)=ufISG`b7#N81-5Ko~&g!L$@H>TaXxN`WZhfgNr-}1x`>%tEtp`wE7&1&S3(^O=O;v#zIAms-VxDCx$hQf8wguo0w zSbc7nrd|I5W*w(ZqAA6T^;+#~)iykX!2{!3)Io|H3yG@RW zZsnw=$VZ0&w}fX6vys?+u&Bvg`)oBfylz|X#B^k+!zmMpOdA(yhbpeiFP#c0Y;p{3 zca9d-MOAAt6)(SxwlPd7|29-qH@uq8mt2E(<|E-L-5d?SXnlC_K;$)cYKDi3+Mji!+JFuCiQVC z8B`Z+FmF_4o@RN7#~Bh6;7&9+cn@dW@XD>j%iJl7uUwW+>t7~pJz(VWC%U#aUqSa} ze!Q~wcl2nHUtc(JD=cq|3l4r$@P2srom|AkrX5jbTcRqt`QzR4Gw_ATC4qkkD`eD~ zWFJwJF2jWLut~|DP?6dhnOR*kWTaM#^{WT4dG4BnN z8o)=)=8knTn}_RMqe;Fpc}lZ=Ky0(UQPbI0du=;x>lM=!%moBauylCP<{Vq2{86L$$Msx2Zq0r;KBwQetpT_C4g^y&n)gd(( zNyONYTa@Ljn%Fr2|MOmScuuT+`nOj9kE2=E9qpk&1CCojlkt2t5;F7cv zL)!--^};JX6P6wzztSA)_Fz8B6}?J4$sBw$L`|`;fk^OCyWBQ6I8>Mdde0;LIIC?i z5+%G-eF+yZI2NR9cslEL<1&<13=@=$sA+B;Jsp`4yO401=5V)OOuZ1C-p!?Cv#GsZ zX+gNQd(z||hu)M2h6)YtAgt+dYr5JHR>bUvrOk;aV0x&ajqA!rst7)~lkL~1r#yjj zhrl4bqpiR9Y;HDaPwq)`+dTY~W$Uwr4puKQcm`@OM2bNOvZd&XL~ePaH$)N2!u42m zaiHQVev#+AR5LPZ6fy%Tr%xkxDi?`PIL-)WAmQMqCNP;c^Z;#TraV*3S0T6iUJ=%8 zZpXyy-7&*u+T_k*1H5A~t1<@vluLTq)Iz^Pmy9#P=XZl>FSaNQ z@|Zn1B|P$O!2`*aBV76iB*$BqChH%Rysh|1e?QtrL=*Oa=|pUcR0sKIg(a45o1?o^ zhID~{%g|hwsq^q^e?D2Jqc@t*WnJ_|ho%5Cy3`Bn_lfG0%@|@}VjE4s8G?!k%I11P zjP84%SPMoPawmT1*r4t}!{pL1Pv%xeN?X;T){IaLWFfN}jEh4_KgGB;?o+AwYYk41 z-i;JenT%SFEBaBEXKyn!>E1^`^YGM8r}7l_#5nP8betZFNm8U7?~k<}kai>YZ67sW z%vyKg$6!r|jBVhc`D<3zK?z!Tx3~gXW`o4dHy+Ovi%0k-RU-$42PnR$AMgYkzdx-R znRs>H=^uOVoo2HS&cGOM5cd_E6vrnz0lc`PSBPBrhVodQ2$Zo5SC@l4wN6bkt%MLv z*9_#Pg`>!1uy-Kl0YWqb4FjoBUaY3+pTMDtE?a^i3psbcpGNC$*Nmb03ILRjrg}$$ z5v3W1Z6{*eXl#48SCRCIw?r}8P!bfViNYSVL9&Udola?8b0P+{>N;&T#KJwb-kV7x zH-Dg)cS{1>T!5E?x~AqHOSib$k*zyZDMDn;4H~Kt!cS@s($-;rLlswT{1la?1K}Oy zY_%tP)K*(4`)C)YTQeya8_yno-&FGBpXEjnKgEZdq{2Y)+`xW+v1tx9j8T&L30+R!fGC;_lO6J?k`#?D0Q&C(Lzx zw*9FoqpJ3+9zVQ)&}YW|b2^@SYEa~J`&Ycf?LS{_*iWZdekim2sjnZa2LL-$MVz?F1_Q#|55CcapXr*RD-4Oi#n#U*<0@dr%1G1E$6^9- zq$Z@>Pzjx868F&jbB=NJOZU&kFQv5A)^}&?*NB=a^|e);(T%B7mMPX@X>!=_=&<{HknmGw}t=S%$iMxxR)NT!a#o!8e*ur5o%Oc-ttxAT1J3hO(7K5v`I@w{v z>;)#6*l+~`^XxuiZY?@N+>O*F**+0+N+-Ea4Tz%Ys#+QnwWTP2aAJ2J7x$M4x9Yga zfp0C8NP;h-kBj63vAjvQPo#f>T!GDpN7}zhvAA6rXC)WHw%MnqV74vDyND*QFm*#S za|vQ_p=C}FjHrRxM9SjPWE3M$;w@awMDcM&VBIkdN=rr|5r*!x;$wXRD*T?2y3=!E zb)K+S7-S*LWx%POP<(_r6l5~A804A+pV7qOx}8cB^$zEbq&v8o#;zmjPV_;-2xLI9 zg)UVlPG*J3VI7>|B+H7%=>rPNt=smNY<;@W=0Ot2ZzXO#Y^p~jCl60WCNuJwTlY(^ zchY$|qaUGp1AKOLbk=#)ousk;vJn=h+o}I8Jko(w$TwEobaI5oK?QxxO+(x^4yifh znyI_78&qGgm4l*pOXOnig$cL>m`p}~h6DIaWSHPc-P~&k2JFW6nh+P}XDb$4cZ5?u zHFBtNnOh&E6lAVQK5D)*bO0(m7TWXDyb48tBSq{(8NA=4H~uj3UXH(yIFlwYj#stprc<IhX?V+PO`qo^gUC1+#7mI zq-=}+DR|0HH~>s_Lz0AQg%)78PdOTMdG&M{SaMrP_D54|2CTh*i`Oz~>wS}--gbXV z(YE&Od+PpjJg08;fdiz++(4(=PQA784^!LFz!JnJ)IA{?p~;8`39;0PNmDdZr0oPE z`!5J-4N1|)w&0t1Jg?OUV%UlLANG|SU&XM>(;DwR$ltN(_KA^lL>VT?B&EzFG*|t* zXoj*TWNjgND>xDrRSALWupeastSd~@qCewvQkrxRi$NxMNK6GbnPQel9{?Y_iF-2x z&kdX{xGS``Gv;{~zs**wuPd{~aN@bSW05t^JuPp7eK{&d$|0t)F@=pOZt^AD&`fPx zA8XmR*H+hkLNQ3)O~2x-_3Ln?6uNM#not)~vz&Y;778l0s{LY@ttHvomC@qC5h)d% zKa%p=O$((kc((mMSrdYaAgU4CjXEMEtbgCejZr$B$YVDs&+JJ%iJB_PNkpwEAaH3PW6tmcTGc+p5Yx~pP1^6u>WP6H{5=6ns=!EtyHhZJ`UcL zM&Xs)?@sl~3qkQT(O}F55lI`r*$WKa6%<+&xPyLP}%(PG<=B< z<*7*n)PZ%!6|SL*zoKttX*?EdAl7Ne16`Mnbea&naOJ5(72jdWo-|wCIhc-WHN1Sc z{W-&W^*ZhqgPLqP3jNlI*Q;Sghu0=aJTTUm#K;A8#|*FptoI-S#MMr~(El%(4o;hOJjQcnKC(3FB{2C4?zDL(RtWLG;f;V(zDIQ-QBXfBH@cyo$|izbV> zv6BW1XfQ4eI;ndR%4W9yVWx7FMAg_k9zp4#g!MhcQ3;81@&7QmQ5zh{y*RUp>SN@e zM>nF;Ap5|Dt_qQ6Y>Q3_*4V`lhTgM~M^AgO+h^9PJ!)iB8px`x&E6!Tn$UkhebwC}bU5nU=Q@i$V zK}g;LEx-0-=?>i2ip5%Mz)Ut6?M7;8H{9bo8kyR-n*}tIZ4=f5@q=qj?gkjM_GOD$ z)jm8q*!cJ-%prBns0l`p72#HHVhge??Y)jQz#BGeA=M5#eVQD`LU4&ct%xUl&jdm|I4wXib~-XjPB z={iAx!`Rs11!0P2`&Ow37ov1k3A&a+CUxCisFMuVj?#__O}z_W)}Bx8+A8&qJhxRU z1z?|gTnM}BDl^4An!BST4q@zZ86%85`U-BX~a$z=ya0Zlv~ z;=m=MOAo%LBAD3J+IXt>AcKq{5aI@8mFbgVJRT=`t3ibqtifL8ANhQ@(YTAb6@_aKdd#1ehYG!FsAasI-*FuNPeAKR%B>#n!l-YV$i*rYylO;D zaDvF=E`eivylb75hUXhaBSzrr4{Aoj;amC2aRMAIK>3CM=`@A`m@^j|L>^=|xw)dO z=n65?nyimx8-zkbfY2~7W{|^)oFM$cn3QT@DUqBKtx!x?lGBMqA}1n5E{DZ!gnQ%| z*NrKky4^@`O@1p$Seqpc7Id;Z5@PH?)(EwI7uKLqxU@a&2gq{3ne*pGV(;T9_}scJ zhoUxune;56L0hMe?k$|LzL3NH`wYyyUCv1m$isnAEflfb!*_Doa)l083whqwplSLg zqGrQF-4YS}3(a|4&A=e7Mp{QV;+-HZUKDTQ53N3VP_Pg~jwK?u8ROSK(T183W&vv{ za%Jg8s4g+v($U@Kq;QqT?Vy`(anNroaCOukixC=ko82E~6u{6(>V|-IJGsC@|6Rx^ zz!+Wu?)8vx`3*OAeGe zLO$m5adF(;o^5pPo!H!EaeFih8c+q$s5`)Ztbn4v-?-6bTK8v>G6G6#F(~M&l3HIW zK)IKF9dfR*J0+eSJf@=uc>^>fFq?|=SzN)T&9}&%hWaNcp&#kFk>`caS#L(?X|igr z)f=0*gDJ?T+$2`u+1DsS-11p?#hFm`7!r)bXeC(bLe7}XQlXt`vy}7moGel?EpO1Z z`T;gdaf*DH&@jrhYKH*1>w|;Miail^P7%)w$(?qp#NH(b^TZof$ zTW)O4YvW$b!&)QYL?Au-e7`tI?c*gizbhQcheK>Wd#Z_Y_T3NJRN7M;+Y@$i0mmbw z%&fP(*Lpi2lnoYiVH8=E)q(gY1@=&Aht=-R#{ZSiM|L}LwH@6oMp`+3Li?a00pao= zU_N0P5FgKWwRGk!7-{0|vLeVBg6;$$-7GPgVl94R3!ELBFn2Vyu%^PgX8!%EY>GgT zWwBwDj0YMA-Dts~_>0Bb30*CE+R-vl3Iv-Jg!K@6t>DE&U4)qMt9^4i82@DL9SvUwGPU}i7t~KgAWQy^M;YIQYR0iTHz#SK& zo9q<2hc*?KcrfY89zFC6fe}L$S0FAEYTV)-4>|d~`S>bn1{s~3=FMJJErMcFrzY2d zkisZ4)~P*tX%4NTfO3&|3!>gbyyFd0@U1iK%G3*>A$uh59n;IOVnQ6hc@$@joD96QRoLVgM z{~RW4vL0S=t%(`MTEy<=voKC#JHmR;E{b)zG#Se+N_aYW zYRMI_amVsClUB72%3BcLi8}Sj@e>pSng%Er6*}RT86xF#c}sk9Kp}ZSp<&pKW!ShT zB%>>SL@gFG*a6DB1?a3_gUQyewVFrsi>byex@l5mq35(pFNOSPW z?h%Zr^VU1hzD$93cS*FnxIo(Y;LTE;p;%r&Pe8ZC)6Va$kCmi>r|>p8Dj&S zDu=#O1T-P~1P6JqGiLj|*Be@4VHD}+$Jo88U%KSH5(-%=q<1-_|C^9*bPphZ{R%oB&POh z)fCvbfo^IyxhF%TK$YA217ZGOma=_&)A#;iuVcDJOyjXU%ncjvGIo zVdG%6b4R1L6mE`lMCOKWChx(Go@{ZfL(B|z8r7Rv4P85`5;1`;^k~A}Fx1SUVz!k{ z3eh`qzPo+aow-;Rhr3OP03US~NJ>x1?ra-xo!fsMAgmIoP zWH*F;w(p-?hpM6H3p?a)VR9iZwIb5l=8;X9ham6hN9ak zi=Wr|b!S@>H)XN-7aD^CMG?@Y4s|j=n ze_0tbwQftdxziaPSB(A&>$_0Qg4@}(17S1QdN!jdZ@GqHFk6|tR12nmV9GPQ>&)=E z=<+n%r~1X3V)&Msq**Xb0Dl1?MAkaGOa<<6q^07%A?{&N?s24OWF09QsU<}dg8Ujt zXr<>moXQDi6yG0}blb@3;w1=}2+0Xao$Q1Fu}8E)HT6#Dq*yV+NeS=%v@wSV^Di`+j&1UUTeU=g}9((fu}ibSJ1fqqi&=0|AQ!4L2ra?jqHD z5(h2_`Ym_s*Ll>a(I}7FH{~&h71q^-O`DO`r`KGQ9mZiO(H@0}TKQLaqjA#2Hk)>$ z6f}dd&1ew8aIzr@dl&Y1i%kF-F^(hM8W&e@ij7qSg|PS`RfDV-qvUN2PLsZB{iBJ# z@K@dOBVKmD={#uWi6m1(giV6!ZL#Rvc@Z23X0;y-=k;ZTI|Oe*VFp%Deg&(&)dH_D z6HY6P2xMmFWFn9Tzta)e!dg5 z5jIGbaiY+{FyYDeHB#lfB76*%P*H5y4XU@|OCqtlo)h8Q6PV8H*`T#i8aiC|u82mu zHgY1^HDLqVl~M}o4!Za`W?#)3=`f*pre@%<0B=4X8`|yoPX7Z&AGS2(k?JVvM90%w zEA7A!`u%(aH$9uVL-)GzJClZPX>R??0_A!17z!kvrKuC9s}trpHhbW!In{JRIAsjY z6xS03vIxP51i}AU{pZL$fuPD9U$$ujU`#bWHQ%`_Hms?DtglMHM{sVLSg=P096Kb(#j>!*qu?nWW$nW*k~iI`Hy81S~GT{BBv5U!1GA_owR(@i7T~1F$eJC z>LnXi(5e%bOKH_O+Ub(zlXyu`S{EFs(h8i+5>hc$q^+)8wu;s_E)S*kXHQhj-UL}s zp9m>^vuOEX!5%&Sr<%jV873%HQw7z_!vv2gLU#-FiiZ``$6Qv;Rw@3h_!BTWPc4@T zW?#O!PcwbYxbFtX=pRC`P0rWP~cI7$&w}z&isSoj6F+fTgSS`r>BIR6Kk5924Z^JPRFg ze4>-k6(kgM(TlKo-U17Eb)kdb@J*Z+^%rU!LGdC|<$5+rz$QtwiHqMx&LM(cDT2d_ z)m;d$3pQ76tE#U;(#_@{HxJpeq-uFpS=HY%XBf|A{`coU@UW91|C zPI)3rRTxTRgIQ9QP-vZ643xLInm7p%>FvY!7AVqc?_04E+MO#_K!8jN5}I@n!=p|B z2t0p9)kH=7M4fcdy*xXd>EIUN8N?H_ND7kLy4npDW##wvayI+#eg*{1Amy!BOx8^> zRaRl2I7mllIDB)5+v9`>Kcq91eEp8lVa(1yAeD#nCSM`u_Dc|wTO$pZf7#(4(urZf z2!0j>wYd~7Ehs|B3ZvC&^J(Hjh?X5%zYd1>M+{+GFzL)e)>wEWSEh>x%ro83jVrcgkUGWrB8z;Sj?=DLPeB|%E~nZ zRr-e%p%DVX*wRQryJE0ZZ&M5o*Y8n$r5Q0^rBIEVN(;jD52z*>6sqyl$LL|N9ur`P zGqNt@(0^8hMuJ38I#TeYf{u>EjK|^iPbw6WSN$Ia=F(9D90u}@TT1T|JdE?k>Hk@Q zL+oD0;Wp$m`>(|F&Co>OWr9Zl9TL7=CT|859=wqo|*hte@2gm-xP5W(Y$*$V8} zAQ+E*j}I-zKNyDV%fkgT=H};I9-{w~zFiRkqpMJ8wRh+b{Cx!zqsA&KtUjE6A+R$^ zD-H&47+Cfr1VL%$0;T#V8wBPZtm8|#^D5cTfPUTTrg|JQ2fvy zn;wb+y6P3fe2b=&nGYQ^Zb##a;lAIFtBD&bXjvf_`FNG{G2%zAvc8K-7U;_ecA#SJ&Kum_B+Iz~Rx&z*Dz{(;FPyhJ9{Z z)XCK>a*?I;n8&#m;dv5@rSN!t5yW=PrEY7e-1@$tEOPg29!%hF zt7o6wuQdz_mnsH?ih~p%2215bO607nCHSnrRU{O z2R6c_m^XK3&dj+B1g%R0*s6b98pu{90rPx9g7jM4+?g}-&2!9|SY(+m^^vXWZk5s7=e7*K(S80$7IsBk7ae=ON6LDvna>U35#r zG+6i>wod3;AhgrrQ7Q!^;uOK^IK=>UTrEO^gWV{Q2}0b+8(}b!0wtm;1rE$aml+eSQSR!q#Ts9))(e_16s&u>x6;V z1R-f2ihI#-v%xWhqA=PsJaNpIrf{!peiGRpn_3 z4;l`o9jvI7R!Y+nUraTo9*uvmqNSp(B4FjprKb{plTew~k?>{O{c*eE{#V>1aStbL ziGOzed+TF1G;TT)|JH`^^hN0xw|%$u)0(B*mu!EwroMVyO>EusTSMv$wJEhrYc6j) zk@3fj)Ql%H4rd(AxRjBWS(EwO%u|^kX6t87&AOJUGR|B3z}iRG)|ocvRhS-G`1B(D zzMQ`d2~bhAQ(Vb7Wo_T>e}C(*zha zLPMTzsD`Uk;EJo>miV#;j)+yGB+0~zdz-;yyQTJ;Q%w%RW ztP@tVgVdh3{=t#l;-MfuPRY%3VsIqxi*yP+BnYD4FG0=TKjt9u5_N}}ORhIz27p{d zBpV3@s?|kXbpwUMK-TVDs=4W^m~>TRIK+lv`(3I(&+xx%?0I)N%_aN6Jwo=wJ#@M< zFaPo*|02|2q0)1YN+=+DP4L~J5I0e-|meq&rAS9=cdDA16dY z0EM55M3CXqAOG%rfF?L4?~*wzKP2BUXY|}k^NX|oW7d$|O}PPP^=$d<8MD8d8e{%% z&c7JdPx5&-r>Eid^TNs`YaN%EO9p^{TI9Fos7;+W*KEw)GU zc|@<|^TX0P*F0tyc1Yamein+g;@TRZibLvWArC;(H z2O!C3TP&Bll1V<>VtL8u>RTkAZLyGi#%hhJB>DUhFZsL_`lhy6EtW&I*A+*Sr}!Oq znDJh5%hc6O+%l@-OkDbZkmXTtl_qlDX&P7RjH3Bamz(ZNpCD& zq%UORmh+)K7hZ@FY@=V?GQ5;iuVdntg-qNMf5W4Tdc-ZGDoEUNzE~g1#4Tqm$J!9L zw8iq`mS4ni+jZ!e&b(*pdcsB0#{|WKz_klZ(f53awcK`pg za7VIh7s~X8gmQsAx_s9`SAW7kPiTTDn2V}#v|4mPJ`^+LgR?FChrh-U@`1JRuH?y1;no-)`EVxLOUMVj5c1(nazEq)eaVmyctgksy!en0 ze~oeA)9uKIGsz73Fiq!2KJ1CP1^Iw|5c0t>9mt1iIzm2t72`)f#Odf4x$!Vsr7;Zo z@aLFtCV3t?nU_4Lxg@phgImR&Q+(pid7|i4k*We?(DG=LNQI9TVpXchY6y+a{5f%F zdn~N;ZQ{f%HUq)!&_zO)xX_XEcPKEDtY9?M4wD3oQs2)3}?s(coX4;Kt6<* z0{MXEvnrM$A3lu-@*ytupFuv1V8{m`KZf(jj}hYYzYKSXs_20`s6wqTNYQB!RzajM z_rV=1D*kD>L!KCy;TPZz=_1u)BxOG>(LL{jJ1i9oUy?=_i>+773GNUtie4yIEyq0L zVlkb?K!l)ONJ@w1^Lx$@DdCRB^Wx@<#oav7 z`oAgM@t=Tu{~sV9U`To7gHA`thmOe}PNxI%0S=VMIs%?5k9>G41D-hMABLFU^IsOUMTd4hZ>h=;x3RaXRH837#`dO1#RD z4>&xJe2~WYkq;|$Jo4c_9glpl#X2}H*^hjn(`e&9O}1FeC;!hS#O=8Q-0Qy^+~}X^ z)?&3(7io+2AupmTeg=8*NVyMrvAvqxQ!ZQ;%a9k!aEbtmXH_z z?|{6(Py@zPxhl3l@&bdxpGRKs!w5Et==2XGx{bY(&;L2YiGHD1^0|QO12@dT7$FV+ zrsLln{L9eahbT}DB%jyA5N{+;1D}}Wb0tYWS4wpoA^Cit1lQDt!V_*my4q?^_gMFo zBKWll{biMzB%dEn=TcX5A?rH2N-Ie6`K7r`^0~^a8e7c$X3@VO`HcQ!J(GO4#iHu{ zR>|jwd>txQ!I||+p8iXcmzQSi6NzCc6En%nkIY=5p_6+t8F^Wm%4NAIM8_}<36<}x zf#l^O)L7VJF=+0QytKvYNAi-FQB3lZHpU1K0Sn4b@kw6Zoyy5mDO!gdDNXBIwNc)sKAqVK$JDV=H=) zkF+A?q!RKGYugtk`7f6r`Pf(nlQpdhpY8Jx{Y zXnJrZY@D65s^Z+)I0`eRuC^$L67r#vM?OSVFyuoePW%*9*c z=z^!OJogR;Ze1C1$*9BiBOhK%#z@e$3do1UDX9PaG?^hE(2C=Me9#%tUF#2#t>+ANHj>x!F~aYfI*X89eggY#jHInOeI&$>9Ckets>G4>d+0A1)fb zf3q(#0{QTFBajbg%7A)$(nA?X2N7ALq4*f{t)^BhJ1XGAs?&aU8+(-KEibd@-ZIB$7iLuUq0mH z*a{x`cqo>0#33mX$j5R*KGp&G81F|uei28=$E(goz%7i{FYwG7CIGD1Eq?~i=glhPmgklurQcu0ziPsoRS zF^~`X5+EOF&;sNGUaZS1t$6GR`GAY?WU5XNz{8eQ-4q}40ZXRxOHvSD0P=xfE4d%? z0n7M~f=52EkKDtl80FH?iXk78L>Bh&ywbpjV0(}cYE%G_{c)Umt*i(65LIF6Qt`-# zrD6=Ckg>r_o`;vZ5lDmNv$C9*e7{8KzxWqMZFZb|YvTdd#flYCZ| z_mO4Xe-x|sBE?zxxLEcNT8N6-AH~sSkbL&tI@;MvJzX6dc($iN@;O5c z9~!L`lFw+LqgO}o@k>5K7$rc-cJ8_!t&|S39-ab2dnpNqRyckNk35=2$fJFd7S6Sb zG9^P$uuo4o+TGX+AdhCOCgjmRj7$l66kdv1QjAWu>zHNkgFHf?gS&@rs~33$TSIo) zZcpliJVKXE$fHUgdGt{dvQvRr`eX{IN-3=$B{}hv(3v8s))q_imJE3WXUEanox~%L zHWBh@4nrQ18H_LSBag`FXX)`}g~Y`ghO70-D(sGsAGX*+BaeKbZ93x!`G9vcM!~6| z&gm>38&?}5?1X%1WXOl83Rl^5!+IP`WKK74LtI}7Rw_aDy71PJ0KrEGP`WO$OoJ!kPiCgeKM6HAK*CkARjK79kRER3HfmJ*O3nmCWd^d(Zi|qAs-F_`Ov7xV|WYl zp~}pV4?oQIZm~ZxTNr2XNuIxno2)7l>k8ow%?I)kqts1$ni{8zj)JSP6@+|jG!gRA z7E8#-jCcT34#mPtAmrnbc=)(jw-53$Nn|xAqM~$g6*V!MOWK|UIwOHG7)}MGhY12$EiH>QHJR! zKk~7$j2=#$0NVxch270|5~`m<$j3zJ^&GQ)pQulP%!o|Pg-ln54&nsUxyCXc`5-7K zuyOU_E2pOO$cMc^KEUIezVd7j^2-+6=|eu` zPi=z2s4@fj@Nr6CAT5bL>SvoSAxOz=TDFd>Gmv z`QSFWX)OaF7`CD>To6-@=75w z^vc6zC7u*Q9(_Co57uQXqSrLRq;N?(jj&_@D!gwY8@9to%N$RqqfAdl9q zxdnODsAtHd(Nlpu(oSW_BkfcSyKvQkJlf?$9$nE>rhVI&ctzj{Z`I@;wB3%pz)u76 zBAtpHC~yn=A75gjUn%QIN8}wH1l091y73i5UL2L6t0LqD>JMz(qZv+RGT0Qxj0bf? zpmCAGkQbXWqGdetqCBH7@*=RTKl0*Xe9Mp*fn{!MU>WQqxp6>V&~B$v0d5%j
;$pXqTQW_sLjtZ9xI_Xv6YJj~2(mVJGB4 zk9Kkf)1$>T_vz813nD#Qj7^|N`~F;BkJc93_0l}((dNzb>Cpzvb5axRqesj1xI=Q7 z9(PMWJ?U7L74Zc~AgdvTWX2A(JL1=)r7ko2Ft0~@ z%tRv{6a*b6J=#Nk^k@(H^k^e`^=Ps8+x2MQmdM&o(4(aXkWgo;!ULe(a}4<)c}u-(+!n zvaK)9R9fi0{0fd`eKf1}<*eFW_UE(e4!-bObDQ)T)+7DUqIXvY)gSex>p zNBVib@=eKwtNG9)J&a6^(aKkD*P{)|3BqDLHqBR_%x8MEM@Wx0B&S{f3iN0#w2K}+ z+E@GN(H0aiJ=)JC%C{v}XTIT4yvpc7)cq~ruSaXXuq@|}JkBFO&*Kcu@$oq6Jiy}& z$*DohZ~iGe$Is(DVCuu;oLA6~$BC2u1s>=BMIMXM)cg%%44>!tcq~J5@wj5#dW3i^ zPn(nna<~tfQ#3cD2l?1$R1os<$y9D;=IzMGsKAt)kEA}EE3p4v6ACohA&w=+GFEh%)AZx zcsP?GAHPDMz&(v~>5qJ5$g_{k`XPioyCKel1;T~lV)96B5l#4Y@HmokV0o~}$K$xy z1dDVQEB++TqZGPVC2&c29tT7n+Ed!CyLxyW*wu$7@HiId5s#xf2Rx4K9Pl`n<@EA6 z5S)S?y|Ouvt1@w$^Q>!V|HR|Kshl>WF_9kqA=0By&hzQfe>V$y^z_A@^ypji5K6K} z=K1yL`E&5;(Yy2TY?)zXNsm5wjvG%*6P`)v(bwkF6JaxTBJhI~_!tid>2VuP$~+SU zQB2U|KFsvE?=t_q9`|h1+pYN~=yB(pY}g&bKr#y%i=MqOJ#MxipB{Il*{{c)X>QFk z*>GrF?H};tzkJ*be^2@Gy$CL#)8l?HTlbr}{jA3;Tr$?Q>OD_6^8=3tH*O-OUf%ccMyT52y#iOBa&UYxjA`6(oegL+fIe*97fwG=*ET#u+jN}F#}Ew zEExgtoCtkgZhG{mMqZEmm48W(`|z!L+(uJ7^O4}C{FDp7=vF=M&+=jTd-b@{{0>Vv z>72fL+%#nc9t&>X^mD(PBdeLiHz})O4z+xS=l0>Te3(02|8lOM$MQigp(ubGw~IVe7v052l;4^1@aMF+=6_>P?V652=)7rkG9w_ zHvi&`-Ydbm-x2wUX4OzHK$R2zqoZ{ht(WPruilBrv3iLQps{*MA0Edivv1>ZoHw_* zFt`MdgBsCyv#qiMNDO~uc6M^y?Av)9)wBIPj&-xaw5I1vq_Ks!`Y-q|B>0RNB@zT`n6AH`}F8z^4u2( zwA8>e9gZF|4E8`J2*VrMfH0vq>f6_0O$1?)m$nZH-wYzbH5;bIws_^6|16Ao-QNRy zTVj51?yz}3gPum`OnDeN(;H{vEleI~kEP%c7CE`^vJiFtOmq1Y{pZHVCndv-RV;?R zf}MqF`=l?DlaTCNdXVf0;)BP2;a=_-+;#jxkBNSoY`^^g+)>73=bvC7kNravc-mV77R=-zT3g(MawN+ZJ_-eSLA-rNvRF@3LlQ^9I}fK&4GI z_}skg34=w6r{!J6*{9!1JU!y$)34h^yRNLx9zPI^*R|f4-F#YhV=Mk%KOJ`Z2c)G% z&zl#$eS3ZVfzHkYH*cby!g}NW$T6M}T?_!TCO{)me(inf+aiT!96Sc^w|WF9(x;?cc77d$#~UN4U>ze05W z_^0$}ugy}9DYjZLvj3O$xDOO_&&;A8yGM^3BMtPR58`%m|1ry_wH;u-aeuK-j~mml zydF2}U$0h~eCyz2m5KR!SN0S`fA+9M`9?8Uun2mzhe?n2u!QAp{<Dsxt zVw&YOntp0r_!AC*Q|-~C?aSjznGYUU#Qc6du9W%2m$sICtd5Rc|`5#!MuEaD!%7d#rJ zDdp5=jU9OtUy{d%Nr2*~^OXv0fSBH@#!))1oauSdJEjPz)^xyzwPyKtHJzktViD$OEmy)%z<%|h@v*DS>7 zsCFUGUIlB;pYkKZHT!5MJSoo0lg~o+vs!aIqOb*)QkX#>+Wk{}GTmT;Dm^`j= zE(Tt1c)j!?EFV11ULW{29_N^O&DMttV9nvax2Jq*DA2b^tkVh@kMrRI{hJbNQ33Hd z4}-^v^{@au&W8(Xt@jsz$N8#6Hn5O8Y0?iY)HSgkY%jp7)*ZAPACE4}$D^av*4B3l zm<-y>1&|ncrvM|lqmt+>5obe?5U6u$uj>g5kJdUN{ar~u3zl`xXmS9Q;QteA5$n{b!l^_qL503-698neE zar|K;UhS&IvLo~cJdXG13m=aIQAqvzK0J<%JdcA4kT#Nj<9enTjKr269>>I`ydM2} zrbquniC>RCZKul14>|Kl?RIdSv_t{1)?__FTAIO^ti*J$DO*etCIA%*Wa$kJ$e1t_gdX>LWJM5<<<*j3;;|(7cq|cOI2HPQ@K`1+xne6J9!v9L@K~A` zHz7O2sb3Br%M#+T>=nx%hnVKlems^4;;|@O!Q-m9jmI@`K^t~`E04<-+lR+>ZGJD0 z>-+-nxW2fTOErVXRlLAq!DMD19v9pV;{x!wjHZ*xMGni2oeOv#7p(GoMKJY;PrikJ z7mGTqf1Xb~*2m`Uyz%G);<4_VcVqVgKacg`0x-M|7PVm`@K_HP)pB1KF&-&u|WUAhc<+zrd1 z$31m9#7_?{^XYN_aT(L&4ljl2Xe_f2Ysa29e^TW$>2p z;hSas^|*N-$@(B|5A9h&In(17lyl!KN?Sm2g{$AW|Q;j!Gk42SK* zV}XhPRUV6=96XlSm-%=s%W~lhG@iR_5qMOS7V%CC<54LVL6B{ha>^o#2_SVU8-p@@ zO}@#M@r$6`h3Su+0w0g+fazCwR8N~^J7*(z4`I0>xinUU@W@N1K0GQ~dJG|r7ial- zEXa^izLK0FqCgVef#=W%9<`tvxyr4&4eaN6oN1Q(mQ7YdJB4TbdT=W#ZgTvrT*jK>Mb zpXYIA6OS`O+|@eY{`P!~It~;fU;^JmX=Oal>|1%9n+n0>#FV3-$N6hK)@(8ML_AiE z`J$1h7Tv`2SdS5pb>4hGkM&w1c&z6Ok%@o4knvdmROsiiw)OMTh{s`zYl7j?Z-lvL zJdV{%`tms5UF_p=u%acFHX82daja)Nj*Xbuh3W6%aYWpa#}ST9oEpaCSeE;Q-L-^x z9GDtL|8T<3<49X7KZlFw)1y}|B|Z9yOQA=vEQfAvHtEra`}F8H-lj+YV_vTweL^{x zUXCt?^ysN~fgXMKo%QH@c%0}hGwy||YoG9I6L%^PJkGz~i~jXu5x8kRJkBrkc^>DN z`F(kuuS&>SAs*-cS>T@~=fV3W9_Pe`(|p^bCEkh0S(u~7s{F2cdF*iu!DDB~?cuRw zcCRmw{ZJns`^BPviO1fDM-5y1(*nk$9#quJqrP6`zIwO_=K&t|gd$F9LY>FS_e^L9 zejfGH^TDJ3YCiF(aS=<3Xne8fTuG6v_T$(^mX{2#u1N1T}Xz8QVbF`gOSDN2ae1osLVE!>7kRb}3I&XuGdhkJh(0pB^p0BOaFUB@9B3 z9xbxnX-6LjoA2wRN6UT^>Cv(TUWZSQ_S7oUqva@Nc*kne{ z3bSUA(SROztS$meN6{9eJ$QIJ?;yue0toOem(9p zYj4%#p1-=k9{1;~D!JFOmzFhj#4~Gq^k_TQLXY-rTpQ=8gdXjpwYTWe;;eOs{(7`H z-RI}>dbEf#BefiQv{;6eX$+uwJ=&*PT8W1oSPnd{IG)E9M?9|ZQtu$*aUq-Yu`=Ru zrI!nD@u^Of6^nvlX0DM8}BzRowz~jp6!{h3x z0gns!r=>#olmuybx&mA_@MtPoS|qAs^iN}A96Xx)B&aL_kEYtkqk-%cT!E7&rLfq~ zqbVmIO{th_0@Y$BeGmZMgC;Jq0%I36UGxaFw=*3zmT2EO$D+7~PxK)@(p9m)tVfD8 z&pvvj50M^eK2n9DM~X{~q*JF0SDEJSP{*6ypM{5(!P%8u~JP`M$hsXI4@i>cCxA9UHG`j~w;#A&)ZN{=^ zTex?1>pg3f*Tt$8z2i|=G=?mEXoVq-4xi#TExEX4zBf<8dYe0hic^#~EIV+{#;coO=x)lD#YG{rmf=4$EJi3jm{XDt|Jd=z^hm=q7 z=!PJQ3Lf1MF=}yAC>YSoqr=(AZsE}dVq5_p-Bcfs4#i90(NT!H^=2jAwH>R;cHxal}DY2Z^DE^=vtK9F1kfd~v$@p|-+RoK<*cs+XU zI)tRH!`4BM{?t0?(Jxuot4Gfch2&P!qsJPGu3_tVJ$hCmKzj77Q>3SYy2WlJaT zm=fyY87n$H3R zkHt~hi7bD1ay}l*vRogJN6{^?oesJzO|<;&FY!a?ux8bReLqRc+#VTnj6}OT77ILZN_$NdbIK=jsZA%69&1iAN2kNbDf<7Smx?$%ZJ;d1bL+~05H zHLh@S*tEYMH+FR-p7gje`eSEoQk0k;;78^doK_DJW z*G8VlV%f;^Sg2?6@mN|m@*P0&M#f{op>gZ&#pn*GhLbF)J!cKiqw4EoIaE2lE>;fj zV!bbnT+`!XL6Mhr0z8i@s^V99R9HKr+|Q$WU^R0_yOH|>T2Y8&~t><7K5Y~vSfqfx& zqjlOQeKussP?y{KNICI1SsC9Qd7LopXLeUiLc4CZ@2&uk6DGYK?HU*lDe+iQR5J*F zeAP^h$4aFD;IX1xXo9it&tpX(DE!RAGF=?;SRbpf&aObaa&lM86n-A-!ZJ|fR)NPV zUdzW#SwBw6|6jx*u|s6l>llwCyc9f+Ve9zVGR*ZDnrZ-#W7s;BlgO zrZ0~(#!NiUVy=BcW@!0cCoM9n&?9&%w z48n>>(2ENPuWch9J9J+#=HfnI1s*#_7Q|zpzZ!LmxANHI7>^o#jf@#g#-nD2h%{wj zfO>e;!&fpMb)Rt`1@Jfec+~J)Pr3W>sP~k^%N)d=VHJD!J>_IY@#2Ep&GV>v{}Y)V zsGwrDiFnjl2|QMQBPs@CJXToMgmMRWdSzDvq^l}<9xGeuQmIk3lLj8^9(;p6!+E?D zk99TAV_hjZ8D9d&8in+@-+mtJMq-EXV^Lnjn*2*}=O35AQW1|NORRqek+IO|XNgDh zI|;WhjhjL|lIJBfm}s3+gE5V6mdN^V)lFCi0Tb*FYpwu~WW5->0*~Zz33h{a*2^Q= zD2{%C@kr2B*m3V02cyp<9?7a$>yh}L>LGMYbfqxXjOTALtQ;GqVrtyaqeHz9dG|gZ z9j+mL0*?-E7xC!u2+vr}UWrG?Y?qHm7uK+CFZ8(IZTNpkkDDbZ{r~uf>!`V-9{1f_ zd%+I}M7Qg4XZO|PJ|N=txZkUDoVjOo!%_36>#hK83S=p)0f{xv`hjDtj*RXpGWc z9?f2fOLe|X^+uU$O{`yqba9#g-JqU#8%lXS(rvStT-Z+jrJjFzkY1FVXZiF1ke%bp8&~BR#|PNYgQLnkLePiFrGL!fp(7Rf&D|NHsn^+9zjm%Th^?_DPA)Yu+PP zT^Exct(x>`*Fo8Jrz&r!K7VI(>ztj*y8NBI9&O%E`<$IUdbIW(q(_^#lk{lefZ{8^ z9&O%ErbqkpJkH0q^zb-wJNxlC$t0nhYPK)F7bMIE3$63F% zACL1W&*KzhpWv}9_!%Bc|HsnDW672(pBCY1=;g8a^-8e1{(uPIozivFbQpBs&Z9fp;OB81Yv6etZ#VSkaUfDd zJdSr7d^`?hnSsYqUC($NZ#Mw8)xf<{uR7L1JdUdRemst&4QkcV1|N^Zx5+VV@-}Va z;K*jBvv@u3sEV^zbq&+wMkT3FkJ|=0py(&br$nj8 z9rd{1X*l!JU`|^FJ#OQzdfYbVFOlm59?QaC<+0!j{VP0{vvEEi3re5K03B_(mB+OY z$&vnNh{Y;=Jg%b+m=M7FE`%THCzil%?#JWeRay|GU_7q3*7W0Xy<6*xam2vBV{@Lz zwUKyS%sc8jTkEbR&z135-&*tQJk~$e_V8E_*YZ5pKh@rm$9iEE7rC0}u{P9_r#-e} z4E|}zDncV>&Q5fGc%XfH+=F*QkDJZEU>!YoKAG3!J{w1R+(_+S$Mm?>q{j`%YZO+R zWEJe>cT20gV77boxYbOLTTOc0u-Y9BDw9Z-N1bdxJ?>wcdkfO0UsQ>Ly~#f4HBP9s&>$cQi>lNog5 z&+@2@;8DT+5s!*>u=D{us$9mS(pR+>Fdo(2TX`N;>~=RiZN{T2-3A{B!nXZ+RCwgn zWRP#=Q4x>j#+EztSeEwXv1}q9OZLz5SU%o{kR`ko%N7b;_2sdQtZ0GL$DPPvJQkkE zxvm<{%P;Ua+4p^UoLGCbkHaKHrCUoYFx(JkCq2Fx^CvD5|8s@X}oO zhtJQwg~u7c4LnZxRs3**wJaH3W&F!WV+4~~28?4uM*Iqo<7Ry)ccUIWj;IQnNTTr* z{IrAy@Hif*;np<3B_yy0njQa8wCxjy zpj+?NqhDH1fj8*U|8Mr*1U{-N%^SYAQdQY%O;shSs#M*&m9$VrSW<)tR}u_aAdrnD z2)MIE2ulJ42y4Jr+`7RHw{`;;RBXi^*9dh1smK*5m3~c+_RuzTI~iL9v0Gci`+v^8 zmBenRXWs9d`DWg4h99YW_H*vJ&v~BzdCv0GUxz)b8#}P^828a1x*qq@-)EvBg2^`S zqyOWELHE%Q*yFsA@L}H%?Qs^C;HFgstM)i?R)p+vUJPpHyNef+P3BF1WsmdPwg1oT zaYDr5{J{QoAQBV-@G;09JJpxeeR31K%;87vvF}^gZ;$=rf7KrQx9gOFsq}QJvwoX&~NsL znJH3j4Z+mVia^tX=H&xchHUc#u*!p6Us}_UolGmi1LH~_7%^f7mGY_hXUVdXbR8F* zFOsRFU1!gb@uht0c`ko`kW-BtT|PgT%)bQ!l`C84GRtse7p32#9P>ZsMxzxvJA>9lFgG3UTeLHZwCWKcgg88?`qOET_uVhAv&+ zwgT;Ip2tj4-NbR%uet%1ATim9BEw1dueuTaN?8^+2Wn?8X`TR6RF!#T^Xm4Ym3g5= zLTbh&v~5ILT}_Y~$;!ZYRMSx6>yS9VDnBEHB-DIL8|1!hyBefYnRmJ}@64n;PFOly zwK@|Bl6^qUn9ZvJym5X8)%sc>Bj36yP}+!o;6^T;1G7wMs`NU7Gq_nx=W-2Y4dt*s z1yg7hr+bIyq9-W@d8OKV`oi#rxI355!&@SN-ttZA>OgQJ>=9nmf|tCeZTXVfD_{vL zVd*R9O`UX|baSv_`b26uXx_R}+RDAxGA=Y+{}^r9;-DJ z43I^zizKZS82eI7fw><_!%baSOjXsEoyi~*V;6DU4GT*&a)%utyzQ_+!hmC-aW0I= zwGND%a+=0iMK7BK<2P=T_Ft0$rEQa(U?Rxp2?(u`qJ`-{3&Nm+*t{P=L8Y5 z9;f&$?oaJ2@p)BRu3OrynQWZfwqz+88ynQaxFhj8=}l@YNN(7QRm{8*OrfEj|GM?Z z0PGdjtmuHnuuSBj^nteJ0o7pS(1wvSLLk|TxMeF=YxW+=G}xD4&?x$o>YBj}fT8BK zE7ow#g4p#d)^ZqWuqC!<#X1z6jSoZymzYJehUR4}TVM;b8Z`~a7#})oWG$;hvq7en zKdZm|T2_7&$Nh21bXGn}BkN>H!KkBb@)_$UZf5HxsL4tunt};KnDinEt`!*CICAoj z)YI5s&tz85CCrdnIH}i*pqzf1ey_a$8pMmTP zh@$BY$%lcjTwsO%0 z1^86KnX_R0sttBb>#ou4{7ngcaoTi-!+TX$p3dN2TDFieAtHDeM)`>4i%>R2AqAuS zKrnemX+v#Q?IbBs8dy4e#oPsf1+&`&vlo-ZSQD5-qi@OVd1Uo82;-(JT3S~&lThfG zz2--0OCy|sWik8GiD5Ho`C`V8$}1Y1zfQ26yZ7CHUM`+OQoMpBW$yH2W-Z zNA*j=r}9e1M(GC(gqSNi+1T8-w3(xlPye>QVk+YTV6oM;177Dq`I($|*)<%x!rm_r zYU`yb2`-GiN5+5xG;&5oSDRh6EA!9via!dDd^=tk?}?9eTWw7^Lql- z#G@K2nyM503hv1XR%P16NmEru#VuX7Kq~~YZXw4#wydT9TRPBC)5f!B)WXkZgua4t z!-W@vCVt}%1z{7dv2A(V+(6Z|KtW^_z8njN1>DKA*ETQ4Cu|NBj2YD*0fV>YvsXZR z&TE;SNDRxibt?de5`N8cExep{Q7Ohi7U*HH#oF+qiGw(pX0TRenbnKRe#~TT!enD9 z$6dat9Pc{qG&A8?&2hIbs(`4Sb{ZUj7#r&P*SJnU@?a@fE}z>RyojVeyyea9cx7gg z7tG)vR;(w%#ccWphL%dhD4}g;*9p7&)Cwj0UuMX-`_x^;N1l^Z!AF|yWMPS$!$@tsY-JDX4N3=|Rg4(2%#a_Vfp z>1ysQg?{e{ePxB|-<6xV@`ub-+9cPETn*2~Y?`%A~d{z{*y) zT?ue94M|NgG!WoG>Ew{2IUSuW|B0N$&yjXrgtvPFF>`i>YAkPg(j)=f+jB$#y~ za)%blomddjxabex4GBqXB)5#lH`a>#k_ih?6W%RBSa_R@xZ;+=!4g5ui$0-zsA+IM zjUJJWD{C2pckgT|q8>Km^?yIqYGr0siQdhys!FD*=`;P9Vbvl);g$| zeETx>#Zg*h|RvI9O+b zgRvsP`TF^`BgCz5Z--!*N`heu6+IP*mE1_n?Q36wxWTnQy10(GUuGycEr1yg8DkA{ zUoWl)8$pNKiG~Nb6?Li#J*Lr^CA71QQ7n#>gJ;0J_MJmvUK?qcZEY|rHUqT4?%JtX0oCo?i;F4;@n0awzeZk_9Cu{VBo2eTe>gJWMFD_a zUoDzEFkwg|wgiZUxHDDxjg>>E<+C|%-=ZpFF(n*lTs%d!2)cNx7BX>hwK|Yh3!Z-u zxHEIQF7B$uHQF~Tpl>#~8-v`|#kC+2RXCGHW5RbZ4qA1_aS^#7=3ppY1AIU>%wlLW zSpi87axbpBssCMazT#c_=IIEmM@EILHXW?I1 zuLdNj#ym^SS6zme2(W6;S_4!qx3FUiF(vRZY77hdWyeT!as~6%qdO1Un2-&D-{?YpI8cU6`UoQvs@&cCr%IIvp zlA3h9G_t``SK@vxeu1n@lW*pJZcI;`BlbLX`Q7*T5TC0S&f!%crE_Do?lPVG5!s3Z0^l< zPjiH<2*dRbg)1)vW+4&48XN@P^2c?*OvZ3AZwi)`)&^$P zO>YR4*4I~81j?%#>#Iv=1*+?2R5S$2z=bCe*n*Y_Gd7R~vyZFc4UJnd>B(Aw;ra2| zd^-^-)hgYSPzSit?txLEta%7vhivUqJkgKUhXhlk#!K@~EJM$cC7tSGfmP$j?;uT2hr; z3^DN^4NHeD3;)K@izVVMhR7!f`Yj7OfgoEV=yxpWQv^9!u2al^5`HI=#Kb=^|L@^< zG5Xlb7@*_asSEcSPKG}>>`Uu_D>v9{fG0Qj zxk28ji-~8cBz`Eb{E6p>vENq=aEH$rU^5%f(}r(i{I%Qx|3-`@WvMQ_iBpGF5ywmX z0T|V6<`B$Z&MC<{=@Zl#O-ka6`LX$o|G5G~>jVZ`4isToh zrRI+rl^;PMrJ>|S^nWz+j2f$jab=w^a@Pk&<&R_G5w*P0h-UuL5tgoKYPDeHR1%4(^^HLZ@X;R%%|ei7ocLOg8n)S@<)$F4WsDQ#^#T~2$@3M^%GL&X-tvmcna}V?xl`f0fDx1 zzv;M*gS1z*n2d$0VqVLNsQxS`J8lQS>g%|JChC}mU`#X4%SQTE&b#_f8s=&c31ZTA zZDXu?D_6F98$~iNg$6GOYN|FBSTJmg=G3gdi)8jzj@z*MZpv{jH9ZqrNRmv$36iMA zs_&Eq1tn$?7bE9GtMB2W0jMS!lEITc=l}b!U;6*$*MIom@9U4sXZ+9_;2v1N8=uXw z;W-di+2UpZvUa9H%r9HKJg}lIP*K-7;H=KCZW~@rI`I|Ft5@VtZW-)pThbgTTe-Zw zZFzp_ym`x;+uIXfH8e1NX};#FY+DY^{XA~vhUbZ%M~wklj>^CALJTYrKOO~RF(wPy z&?p=QXMVwj7$8UksvcKJ;}rMbW6+MKL5k6aGzAz5k#RK6Fo@x#!V0(#HoSlu1`R$+ zLxU%O3b^>QYai42F9-%aHXrj#)=-S8oF+?`wo8|R+r}3BI$=qjacarpEL%_6~ z3sD5_sR?mu>z;tx{`{>&gTat=Hx?OGnBGg$f&?r#e%+HC!ZQ-#;Pg!Jf-^e_vYXz) zx&=IL<~ejW#5JvZigGv-InY*C(zbQGP!*d6^bSSiSTRWGgpQif{^=^Hd`Qa+heM({ z2^=m`(E|mDD~v^(VkH~#?27*+iCAQ@4sa-tRN{$IBqyyf!laS0xX#F7lNFH4N+a%o zpOYlLY8W4R)lgS5?zQ-wB=J>4(Wqga<2w@mJ>)NxRvM4b?(@V~B*As+D&)lz$itx2 zP%Sqn@r?|Nh^tT&ZO2$;5!YLacxk;wh;P!1s|li|CIMv~_Z&PAbVM);j(wAN2=PS> zilud{kSs4+M34+g`|_fvk`mBsG$lGdis7`>*W!Ii{1%4OMgu_+V^>*gf@-*b=zJNp z(oZ|Yl))rGg+=3tzzPfU3&w%X5AsJwje>t%5%;IgSCAD25{-iGj>^AaawUof1?Fws zLs4M;AmIy9El4>+6pc~~AQ(oY=&{7TLFU}_jjvJ@B1HZWHe=`yNr|nGp+BT6L>NR> z0ga0yZvDpBC_@p|ONFBKlm;LQZk9Sw!I{*}D{R1?DLGh!@ zAKbCk_i>D7&OlN+06R?z=IMeVfGvZ)g*swXxE zCN~ADD+8A_L8BTdYX~&f1sbaY<<%ACWd-GBk@B+9dJ0!`!;RAEqmabXeGJnB}p>solf^pzKSjwB;CmYC`(aqEgawi2fMm?5)& zFwle*h!_&!AtnJ_|2Yz%<3C&i9RG0%K#R*kuIt}C13LYGJOgt7TW3J`{%6d9CVCy6Jpq6}0&y>!vqJjrFBv6`}vX`%`Q(`_F%-Q+B7yOKf5iSH#H?o95&PoJpGV zHlc{al`s}wF>sMv1th%5`i%7z>)Y0D>xb5Vw4Sz}wSH~=#`>N0yj5p2*ivkETaImr zEn<_l3XvpEY7&I_9X9Dve`Kp5KI$)Wgl`pUlnM()KkAomL-aq`B)wmVzhIM|@Q;r? z;b;1Q$ZdlBmQA`G#FC4C|Ytq8X!{I#jAB9!cO|LD_E32!Yg>}Hd z@VthKY16A3DjEZ2^&@KnkrAVyvJcc&ke;FvuDbe)23FCCyy>+K6=ijkYO5}-C})d$ zS`+dh?Wp7#4OLAQc~!NSlvY=j2kNWpseqc&rbK*0MQM3|bYn$*DGIJ@$SXMG<2PXv zyoo>TSF+Qj!y4f{?pLZ)dU2KB^*&Pm)aaFQDGKi8$xOvA!3>K^ec#VASfoj#{93s?_~Zr znE!S7UCjR$^S=pyW}=9zk%m7t}Y@RyQ`)H`PzCFPL5*sh?ik)HJKCp=o+qL0MfbAY(;cB?k@PRMcEr zjx9?Kplar4BSH&6GpZ_QX&xFbrI_zy2$VHpq%~I6PQ^$pEhl$VU41>qCeYj8B!fn= ztRfEvSyEHUKF4SLd7m9DWUH^ojY|pBFaU_wrACfibeZWI(=yXW(=DdEOxsP*nqH%K3~ms@8w8angH67l zLX*FA{xNzvV!1oOa(DQ_GYg|<)1+pM!x&irL>QP282Jyl>fUr>wG&cRiM3G(Pe$iW z_KWL?^R5$)Z+ckVDC`vCkEDm!p(juR)YAfb{-jdqqt@(8yPKrjMgdt0qz^O9c}UYlWioV7Gl-^h!hcJ0BB&94Af%=Mt0X=P~@CDC(R*hV+ylySJ}3$azL` z>Z7tj+6DUW1xxoA9Iw|UU{#9ih=tDkNoRolyF>! z39)$2_lgidPC1lEa(+;dK58&3H{~b?bCB_XU!*Fs)0E%jC=ZWh4AgD~Tg2r2=K`KF zaSJ+ei*US@*yN?~-K`}XYen$afyfpC&zSU>zqqc%@LJCjt29FprwOl|0~BH9EwQR- zWS*7K$ggyeHzkgk2Up^+vj2}k9BK_pIpXVSB zDPlhu_o3}5f7cHg zLe+rs(pm5#f#kwMq1WOee~IaRz9i*+{?~kRax&I{QsswIf1Pw{V@zB|2?2P*OKHH4 zOM&QyL<-&N6Txi>MbrTJH1s2j>5X8bwbN@RB8&hF_6s%D)nVzSc2a*DCMxnOYRj)@)pa+* zWXUXECm_e&9bi0&jki+37rvnJ0^^k8Vqs^85Wi1@VUL&* zad1=}K{0VNl5G}F{aL`jI%Pd}IS8k$y*br>AMdm4c}EztSN+iK)k9emwdd z(NW3D5tqCnnS9RZ#mS)43XAGLZg^NU_`%W}lf@a-o=5$FTx*j7;NW4sw> zdj`Fqx!Y?5XC{Wpq8W4VXWYki8mBEY@*UJ9ygWo3*tjlwrI9%A+-&hlf6;k)oe`xS zcMuabAcQed^z%9+f1CCy<1ydE3*2Hv+kd1dit(cC?VmOB53;JBpe}s^61Xc_l~QUh zd@t67<2nY7&-qlY{yBSxF0DBZCMlArcT3XL_M9uRv+1DA8pA9ROU&Z85RpUe(zm|i z$hSVg^q<&q3mSMhqW+AiN;@87hSh>~gP(LpZWqKq`3hsocq^QkeKy(Ev~xiE8|>jZ zAhT!eLVT@Vnj=L1AK*M*L+_vr~EAiGe;we9B*>0~iAz`H55d4y3wG2;T*op@3Ju4udo2AK{NL{sVqij$K;+Yn({vYM93p?Q67GQ!uUl=q){1xt9nQW zH@0vKbfKNf6f-4 zg+OA8zUa5v{Hv^-3s8<7Og3Dran4!=YC)AgKq^9pYzLj+O@Nb#l%tV>DNI1zMZ#tm z$SK~KLC^GPO$HG!M0yq@AHv(v;OXuUWZKky&GW$A2wgfEgjQk+e^sUj!5 zA4<;s0`3u7>w7smA%`zxO0+755w7*dXcBl3tf(X%kFK5@bHWGdwT6(CdX#3&G*h8O+UuA0`MbK0<-{=Cl&1Q-qMuNXSU;lqoO#6sOJ<{lfTz~`0 z6M3{3Y+9b<1;`6`;YADFG5-8{J81Pz-^&mIOi{d7K!*+@UZzZ-S?)G=FGy4X!5%-4 z)cjt-9u>|(H>0ll?)QeH_!?0`c>>oCd5PXhhaElXE#d4a@_u}w6JCBCK_+~c7)!mE ziaV8bBmKK7lNPewC;c{g4`Y;#cxlE!r)h5=uW~V<@UWl~)NxND1#RIYP}Xy?OAfj; za@(Rgu*&=}s0yphb6w)YAP0F+%zZ4TXNxQRFi1nG^PLRe2gknDUL zX7(t)-v_Rk_!OICJ}I08=K&+ihKBqZ;lDfo-H|@w21?&5Z7w_ z{HJdIQ!0_9z(2VX%m?h7(Q@}^ZU}~CA^xdbx&~^m58XV^7>*;Q4s5z_R(IUZ=dzFy zDg0=CzsMj)ln^Pz+>EL8%R~t=whQUQ^VlY#ikPoGuf>fHViO7W8V_lRNN@~7MEaQg zyn`5MQui3>adtr4MVQMeJ_15}&LM6G*-6_0tha;4lWxb92RodVg@qho2(d;VF?8jgPFfX)Td;=F^z6|^XR5nTe+ zSWKNukvfg0(~KPyYt8K$?juDU#9EyY>jnGh^=xi)cz!-V2KTzh+txldKSo;Q(8*9} zUn&cHxoz!BTA(>P&&Q(I?-Ay25ZcVqRv$}qSKHbL=Eu-S>uzsbd++>M%hkBF&T~6T zh6jd4J$J#06h_lzbMz@+ar8+amTLb!|7Bz;!?UE_pl53qaB2y*T0T#Ff(7MgiM#P( z!_TR@rkM0B(v8m&pG6>BaG`u_vlO#E@`3;*!3-9~%jH@92uXSYoa_OB-v|7Cbv>)H z_;8Yvk%ds2R4T<;k=F#++XBPvxg$#=cZ_~ZNv#-vEDOp)N=+dLaT)i9EMneJGG>7R z$CO`Yi7#U&7*pQJLKj}$0u(UMcM`r6$|b&-a#?2Nb&~L}^+d7(;MhkMXF~T3zz2i} z6#al-Tt18~bB2E@boS+SUziC;$;O@GUBWp$_Dz1R`+`i`c)bhaW|x4-+~6+-IXM&H zp57Yho0e%CGWiGnB-|jNh(MXJh*971;sam}^qwyZeNy**nanT2qp1^N9(G=IH>g&_Q?eoBvZA_)sc5*A`P9P{NGXEkC$r~&ReEY8jdz)#A+KsX#Iozu1) zr`+M>N^v{Ds^-9SoWl=D2_NmsX_q*>Uw{j!2iN*{(6r!e+uU}p=$#PMHaWKN!4SY2 z&!ysSrjT1Y6nZ6cD1-<4NwS5zLj3Du2uzF|zEEoKKBYZb{?w}E8{{;c>af4+QvS*L za&)GRe?3Ww>*dQG(%}#Q$(w2fSlRt$D2EMLgtzeGgDypO_70=_-3sMDK+ZklVk1L*%moa% z6F(R*kGSCK>bX8meB1@veiWf4NqBViEKdtR=AudJc9;8P_)$3dS+3M$p04f|mKX~l zuEJrM4W~(uyM*|LG-)Rw$xc^cba)yDn79i?DdUX(6n-49xYHs}xIpz!rb)Y8jFu@u zp@cv~G&`ME5S{|yK^Cm2paD;y0j_jJ!{80%%{V?4y73kh|BOy~UN1f6BGiZEOc>45 zBBdu?2W^ojLFTwOp|ridWq#`t?B3#LEXPhPbpij9=H=}zZ8!?9oegiNCH)YG4>m3s zafwZ?Z_i6>c+2(5Xfu)^7F4xKujric zDL1B#6ykWkZVpFW-^9eAYgsr*J&6_PYA3BY-=@bL^frAAN@Vf8_adddywD)N}z1lhkxQiH$1P`mKo}t%wbaC5Qn0cp;XI4u4n>5Znr@i;==Zh zG8>*6NI|x zuI@D!N|-KRZ;=j$j;BMqM&1p3wS{FpAue0l-}Wj zS_pTg7DkIw_#+{u)WC;9#afr%nKIC&M4m@Nm=dmX^_}eAk|M2gof0UJir|T#T#+)k zhUh>IokIK#@?qIbZ4c5FM(<6D@t?Amjx`)Cts`QQ@WcOs$CnTLUAeh15Wy*LIfM7O zcms!!R6vZR@I9_xWxF$Y-Ecp2+(m4C`Ot^G^ zX9_>#g85jNveCINvfD*Ip-KNL(0?Q)hHW#tSK0(0Sfn|V`7Dl6Ka;1rQtugv+I{$(W@4z2ozu&T7 z7rhl9V&m%xYNE=3pH4>sf6If%CV>zcuP!m+(be- zi2=V}!M+@DSuxB$PRK?3a_XFsA&^b^ENB>l>{^hz2}g}qHw_Rg9l_EKM>-D`MG;=5 zL3Ly&965<79}Bsh!#cB;SU^b7@6y(ssl<_B&Lf!!2(ZQ#uo_08hFtP1orb{!8~Y=a zhn&GCH2D%_yu?+be63er#1_7pl+ThR&S0WF9B{cylI=5GCza*STo{~t0aaZE&Q2OD zfQJ#*e}QXvB=~cZl`&9v2$SLtO#he5gU&psG7W0{eN zx5CuP>tKn;lx8PyQa!vLPq3=a6FVV-)HmFx;VI} zXnLn&oBX9!dM5<9C>1hZF5O2_cxyMBkgtSvkUjHPOKTnKR9-bP$k0j~d zR6dyi1+*%Al2w0z{CsjhTctGPSXep>V^hMAnzo6B>sff``2N>YBikqvOj-49WIn$O zokk^YWjW1>S}5p23c`59jDbEfN&EYe*=`#GLB&{!^0YptTxtkD2tAa_M}Y7EQoFHl z??KlFA#O|yKkTYmF?+?zcDk5=Fgw^LJvauV8~dXO(sNa+7*LTCKy@)kcPo`QFK)s8 z2F=U4#9sA5Q0j*XAZ19xv_r%!nT@-MfU>Zc9=M*%4>UsBG$TQx5VoJbpPh5S`m{&B zhVIm2pq?N04ebkyr$^=U1&gF_o%yEHs2nn2JVsirLU(blnMNe5;Xh`&&&NDfbnuO zeP|UnzGlX=xDF-9FvOLo%%Tqs5D$ln&MS)@Li~4Tns{*09;}@n4i!fZhvd^{z)*;$ z(`MxY>=*!yd)2ieaych10Q3`M;(V7j2NoAVK0w}FqrS`Xd=0e_R3X}NkWKf{omQ1B`QcFVW*pg%7l0=Q+#V&gj_|c_KhQ{FS zG0JngZh zNUfM`e3=Y{hmrMb0}@IrT|y6^VqfOs+gwUJjUMr8`iMz*boCS&!&ejQ4PQy~7;+}& zF(ZvMPq`WbGSvv-6TX7t=rk1iw$2FPUnq|=inHl$XS@3J@l(cuB#}8TQbfep8pCry z7rjP#qY*-{7X^uPT-X?JuJd?4>$&IQlKNfYe%FY8S4qEXe7{RoQvvw?W}s5&oe_G{EZ1KL-14V zQg=v?|Z9B@WsMQtuDBF{_Q=WRsWKBp*J)3OgU8K_qwBLC*Y91`F^7_l9Ub zfhqCF&iIxLRPk5yTO=M~I|+;r?shqMA}u4yF+BR5UA!FI^jX25*=hdrs6pCD^QvFl z`BPN1e99i)z$G{$NHHOA@Nz1bRKv{Cp(#>|Pt*7%``E-y<^L(ll}=?&wo;iT|1nJp zXlazK84OSLrb(i&uQa+QMGRm?HXQT?FYtxiJi(zP;*m;-&rVTVu@w(4tjX-M7H(S2l9I4JBgKby zkHjl;cI-D^uRGJ z*ycf|HVVc-#Hme!&q+%#8&1H{4LW5w@v_J~FWA-XI^`1+obrP@ zX`Z(jF7^8^<|54$|2zf5DZi?dni1dZ#lnU%-7MDliqdF$7i3+Z=Mxv8TG^9Su*4%8 zeMPzQIi2R5FyJhqAZj1~0uSByIAa1SMn^i~)hltGAJ-~@kF<{IRDC;ts2-N_V^ zP*L=yL@S)ooyZ7%-5kShx-xCL(X3Ew{I=zjwYPey=mt`(-iq1|*_Gy`kRtGtSiF=;O{T^?nEN%k2_Qp9bZt{$IJ@ny*tqqxz7k9a43 z_;!zyZ$f0zCTX=7)1`?<>fbtasxmzT1P8@rqmif%5tH!!B_mcXuQQ58UTG4@^EzXA z5|QUC9!8!B8y}g(sPrl$Mwexp@?EwNzu(9gdzEIBl59pG#vTo^;n8P}%E4?JWgPi) zqi-9P8#53je`i!Ka^vWWQJLbVC@K1pQ51be)ygV2BGn)yI+%?F2*V)83h;NvaE>oG znB${CDj)r5yZmANgZR5!wnq;f+aCV_&h1;aAKt&OKm6#SeF*vBBl_)rKfe9_1C(gX z_M?X>Wd8vfAqU=--}?YXymw&x2l0>g?T^2xmiNvPdEenJ`{TzC#N%29D*DmKUV3gz zw{rA@BhMrBC>5+6-G1o3{fCim%RBoHAKrfiMNx}1_ZGEflzHE?$B!IF^{iPG0Ply& zfi2tL|9~QosIjbZRDc{mAb-HZWYm#JtHm(IW7fTlKs0U9LhM^UOCB27ygIRt&qiVVw8s$j1Js#TCjh9v~ACRXI@ z>;NcGoswK1EEO(yD8Iv%EYD>q8Cc5Q8-f}LDj>)OloLK2qHV-kj>I-%wP_`rUZECt z$bv&_EGhL9A!?h{G$FmRCqtR(BwBGr-FoGVbY-Sp4(X*9FPKSJ90|sy%Wl2gY@jqL z(Qdu8z#CcUtt;VPi&yF)#;a`*<3XQd@LLk1yHTy7~Sa9(Zc{Bi!aIZ@B6}!)Zgn<2(JQr;<0{`gqIEg%tR^#YgoA z79qmsJAHQZwj1txDhZL>cHZ^7)}zS>mK;s0p5;S2ZaeqJUW#H%uEDKjb5It4k#@}b#!4eaFph&kNzT=L8BX4tvojT5xlx5nPD3|zQ|If zZ287yEqzn;$z%Ca-xxs3DswYJzGkJDXHiR?*m4H4%H-Czejdrg!ys zxOxvQ?RT%KsKNgCyoo4iY9N>w43stn@-Rv{hGEQWi%`iCr7J3hJFleT%H1PjS zKpWFcb=BoQwy=Vkt~yJQ@5_h*bJIWj5ljZ&48;HdF<0tvU>-F>Z=dDjTR9cZZ*)Lq zdR*OubE#`!$>a$KO>g;a+vft{`mQ3)SF(u<;Qk6g^1+ELv7WQYmJE_f&FSNy_cu**A0m6rm(= z+@%KMU~rnFn+;TJ8opMwO}>SBIQfkv`K2U^_jKP+bxF<~uw5+SK4l>41t+azDCt!L zm?oubh~8i%NX9FZG8j)hVNd~F{MQD6e8O;tSlIz-n@2q&K&Z@O9FbyQ;o$KE-VNcRFmK8eggFwvujHSDu} z3xhpB0-{vx^U8BS1X2W{08;iHRxuPXiwc-j820E(DzZV?^9*;fLbM{3j|h8dSWH7+ ztlfzS!c_=I#uv6|FMxJ^gs^=w^2I)25bh&tKLFSM!yg?!O4Vvz@cusK0P1CLvhP_| zJ9SE;a22{~pbxRzw$=j79?|l#>xJLO{`X7Wp zjbsBcYSXtLIQHT8U21pidsbHVBMEvbffKiEj~|KS4UQfnBpH?8PrNaF)ZC--1MkJ6 zhv@@TKWNQ+5ncE`fC3o3ib5Kk;VK`dQu5Qjsage%(NSsYM4HK%;c4pp87PLqB;;0wkTlU33HYcaOyECv(-O)#yyXS#EfYYZ zC>t*;kIP2IF|iEqQ{up*t7mpLYimO`+KSV}c8^qs&M5OmCuGN13#rLD*pq^J3%%)W z+59pO)&IG>=N4Ax7L?$WmmxVAgBd)7F$g?kq7`jq%xShQQto4}J8T4_%6%g-*M4PK z2TQ}@BOp|H1Z7ma(pG;K?s#fO3W* z4ODNWheLm6fe;xeliR~Mhe>42-#5NUi6AQW# zLF$Rco4rMw_?x{-j;a3`p%DMIiI$(}@VeSf>M9kTV>IV13!Cu?69>_)IrM6loG26^ zjBd0Iu7J(7!S$SEVrPf|O>WmWZFm_@uUgybhD>q4mYb*&O&2I zT;oLwHF23OCR%*U7&_>lg%M$46RDVJN1)x8xN^YmQ_s@I#0=lEa0b%Mwh8gAHYvk* z>Z%xiW1<5YtZ44zwy*>7Yiu#efnb-9RMl7+&i08}#CkY;He*iR+4is#hjQTC80G)$^ezpiJzFhtqzbMbs3Gq}DN}$-N1d zIwK0x%&S})gPj?DF-^JD!eIU7bXbD4NzEqtxislQFGlWl6eeDXX|EbVzjv8bEfV5} zn=xMqU*HQ)^?~#9QyEWu4jX3Kcdk{oSxKEd6$g%{`rGc4*6|gkJD9t&k5Z`8k^UIE5vd8%){ywz7_*-`{&v(KN*%_l{ zqi#nGQVhQ|6~a=m%BSve65S6axx<6YeeRCmOaRUSYZ%d(SL*#$m6&qsLu zb2o9t@7+DGI#mTTC4d}7ac-0sqhzWqdEbdart|

Rpi{Aj#+{CnQ!((*Q_Cz7FLP z2OfAQ&ZS`R+rv!Sfg~akUpOCyhEeD!*7;b9NMrh1T(maY5gtXXRQ^6AoB_Q-Moxks zbIPY~S~QJ}_DK;RKKLRB@mP+}_o;<5O|rb&!Itcbg9#=+#4FiY zNz0}bBa%*rvyjMM>DAUIs&S%boHuy2mjuxq=xwl2A!3^qC$7iO2yrlnS#3_JPq1>R zF&8XmG^oP^%ZdEOR98Z}A}U`SIlnT4P4$nXcg+|_{3UEgM-yGM)XYIU*K6jl8WeU7 zg?(e@JE%;48*wyj4N_MalF*TZz*kNda8!(8jWxD&gC%ymhp=4?M9_<#r4f=^zQMZ;|KAm?$xB#2ELjStNT|N@4^P7$f*7 zODZK|eJe{Dn}s@aQ7nU6Z&3qLqN>;`Wr{6g6ca$b6MXTzfX}iRX}=28 zXrz^@(lXTA8IU4kRC`2~1GCXJb#?$2DABs&uiIJESKHBa1OOIy_3XqUSbLhv$9LGn zX`t;iA2#t|OhtFFgan&4Y|S7Oz%_$Rtp1oC?5~axm_#@&D}z*a9P3w-kIo!SAGwSH zeEco?2%G)v^7q)(VwVjW(lsFbl=N75zL&rOyX8h)>|G`;_TmnWJVJwor==ps*=I}GprDfiO7e|(PS@;Yz)=Zy|U~WuoCqyOh$1a!)A#rWgeXj6@ zkhs*F7lN(!&nkwwh>0q@h&8DMHx>kkTQ9~EZB{WxDtlf1@P4I>STa_`z`2)^zNH6C z&6qeWcPU<%Tn|i7iy12KN0BNbVd89?OQ~@&F}8!H-R9yUFqlp&j@+TFNCgZ=YC3^35&_5q9dM@Nl{`5yjrHIp zFivc}Px_;roc48C|i1pE4k6x?wn|c1=X<5zS&WsNOT=|h}U>BFg`F>b7` zs*?-Q5RSV|_Tlsf4*Y1-HMStP(haT)#UIV~aUAAkcrxJozEm(^TD7Zp$8aH@27&H% zt22084q=?nRX8d?#X>m(MYbG-66^larBd0=mP(&@C)Pt1)z!Zq`YZR}Ul0BFJWKN* zQkGb#>pIkNm3n^|0860zRnsS>F{w}&>r_6mbml^x_@)Vf{1ZzI8zhXWp1uj)Z%&~ua5oX}OZr7Ynw5{LqU$?FQ)3W~}J@7yH=fB8@_@8F{r}TjQ zk0yDCS?)H=g%)|2MgGJhW4gpy<&jnydo#va|Fu??HrD+8B)IbU?7CD&zLiK^e%mGX{)eCeB zb>ciudDav`9{eH+esLmetWHr(%20Fnb!Ksv?&L}G6_}4H>G-pmr3+DX_d{lJtrj)5 zKT788BBu}DuiG6d*F|RPBDp$6G}}?$XPDaJ06uHt+Bf&Edn^Dc< z7NjFB^!++xiuj=Jz)6dfvKhD&`}SBiMa`r=v25~mIB?3*l%sqakQ;<>Z(zeq`#%og z)J3p2pcrBOlE?KVZ+oSidF(BI+bh56?XyRJ<(mm3$YNQJ+kIv3HH$vGEa$15y*Z!c zxO~|@zwct-jlM0uCw%Yul(a+{NztF@NH_7t-9OKnq}Pi#^M>vlat>7Ho>V3WPVAFc z<)AM4e!4g^9OKvT*?%lhff(f*L3!PelcZPX$OQtGwlkm{!=?Cf-W`nd!K1tue9V86 z(w`_FoJk(YB$;^ZyFwAi{HpWYoZ#nyl0d}7D`jOh^=0){<)x+NrRC+YbXqnOSGnRI z`^nX~7QdmYcIK3t`s(u1>X}tFb>%g6m(*NRRa;k&9cy(BrF9LH>KdwWxpzIT*>0TC zP+HwkiaTCmgR86oR#UMjZsNqoiB*jiO^uVQ8z&>6w6UoS_k}l3ubNrcFted_W~QKtU)C+t6}Q9zHD-J{q)Ak$Wq=|k9b;RU0ecbv8B>`9Kl*i*z`rwz3kJ@5H$@@?`Q z^leX#cuqM+I@Aq#v^P(^m)1;gGaXm^)4skzcaEEXaEmO(Hk!3NZ%Z2+D{3ZI&oUpF z#7KE{_r10c&xyIZ&OP1N+xl!hi*3rQHu-v6_$c2S7IoMmle+G$=(V=BZ+728Q3wx; zI%K%AFq0GWbnY)Zj_r$`v*O<=tFqhnD_zUI`73jayEl6->6Mpx zaSg{dPxuBNPGzSnTHx)o#V_#ond+p)+0mChl&|DG8nZ@D^6rURya%M)v-fm=;$iLR zKs#RT`Gi{6o@mrQ`8Cfz>_LhqdDTXL=PB;MOqa#?nYzzItL)uvFlHI_dcBd?Ij}Oq zaY^jA|Ebgb1JBfyloXEB=_nVTY2;5yN#pRJ3-a7g{tvnHs7dKN|1v0#ZJ6FTEX?V+ zlpWl)HZvD+^BgbYi0QlVr=@YD3QX^PIw<{VmysKiqy>1AxxiSRZtN&7g?6&kJ#fMpnJP69L*dNq^ou14E2R-5LJOP3fzt#9H=$xcM_cTji z*6QdK3sjHtG|Pu4l|~Dt3qNSYg=R)~M=!4Jh7-0(_M7*D;S(J_Xhf8Kmd2mn>V13nWMySNH)+k=v12F=XM(nSWw%Feb<1PjKmG;&CbU<)BfAr9S7zJaBU2WDHY|a~q-$WF2$cZ{|H+j@;-gS?1`@tbNB$tc&5NXK&V2`KGKg{LyE- zndh^jeNzq@_xF_@;vIYY8t7Bv7^XQJcb1*W0(&uMi$CLw0(=T*Z_g5Mp+chu`C^A0 zvCDh0DTGsux^vjGILeO08l&ve^?cvz_$WJwVSMCzUNrIG%dszGN|im5W=BX#S|ru3 zxO62pc)%}j;v?y}qxdGiv+v@btL*qbeg}P@T(^{F?}*`kslB^9VsIZH)t8oa3O7hC zv+pHuX`hk2s?)<_erDf`SPJT!{lEIw9mUoBX;@1(QPuKrM~pbNM`hESd9;WUrgnd2 z@4Kk`gdJC6er}gi@fvvI{$*v4z583ce8T>9065@V3X5MM4*at(1uUJOcCg4Z(3Lxn%lb_-8u6&WV@r1}j(Y%qHLy_M9xKK;jeqLTS*D*c~|n zkm691>`Ic37)Wmbz=z<^=LvMB>jo^-M?Ypw3KP!Z0@3vX03Eh}tQR0nx<}<`?dtQQ zNzxI1&;DNpWZ=Grb$6|Opf_IX3ckw&_VtRFIcdaPhVw)?6orG)y*LPKzllc=^o(?s z*d`U{Vr9kCVTg`)?S>OuFQ>Sa44v%PHO{J;SXUirD#aH5Kpjk!RKh~B8QdW2)agkm zJ2$uUl=ZoenChgv+)rV3b*mG8keE9+H#c@t+2}e(qa07VI)M1c)!FiOS+XsAzv~0n zDc4UkpUr$L)0SG8p7d7c$C+Pb&d6GlWgZ#|56d4uvUFludBx=Fn(~R|RppK4Gb*a8 zDgo9S=*Il2((*C@ywdWj(%RC}+Vaxcsxknn8c;bXdr!B^I;m6XwdAfYmW@^-ZZmv< z3b1Qn;!9Q+1#*j{L#(k$@L>&V@6s5-`8q3j{f3wDEb)N3$`h&Li2m^81tkcN5}?L5J#LRjAJU5c7|Lf3g zm#HClX%Tm8&wI4zz1s5;?U{f&I?bPWSo>>Eg#6o{CA>T?1FW{&mQkXElNjlcsF<-E zjJ6~R0brsRW-yN7(t-Gk0*u|4=p&nXq=f|7vws?KRK^z%^(F0p$S$TaA0J(up)9m_ z|8Mr*1um*G{~teR?gMiLFJKAh%*-kdrZ^(f2q-s!QgKl$+ugKQ%XUjkEkFg)w5+r> z+jXn&*0OGvR)%f0Xr&8t7-R;I3@GSeqO%31R6;~IYxuuEX9jPz``zz;fB*0I|N8es z=bY#Id7krJKF{ZQp3fyMO5AR45YnQs2FaqsA#2R8G^wyc?_*KHpSpe%m7x)~M+Ng; zl~E`m(o7W)-iabKp5@v@m3uQPn3ECV+82c-W)e~mHhh?cXOfcd?E zI*0i2=8Por9!@hJCD7+KXJojz%QmPJ;zJwU(59D)kt%|PB&fs&JwquLMx#cZ2o8wz zB#F^(j*`7kivk>N(LugtO+1nN-6O;MbZuNzTwI(jE;TMQZg$+lxVz&@;?}JqqjES1 zh%N@ztBw%=rWHQdin}7gB5^vh!|56tadQ9)Dk2u(*N}n(Yg)v@yDfT?unL^7 z^uO3T(v?k)egNooodzdaguAm9aKtS-m~c@;Ff!z+-J93E{^pWEtp{e#cB%M3M_@bk zM1*)D(kiTv5DRqnlSc6lo%nU6U2lRzP^$G2vvO~l3j=0bP7nhm@V6bb<0t z@p{T2o{JRCx&SDc^AW*uUZuKIJT#bmO*OKW1&Xc0zKAN}>j*6PU<|0!@rCL9^(w8{ zCllpztowgd@F^ZgB%DJTghw47Kbuogk10|3^!bI7KNQiKSH&tOYMzRuIe(T zdzUJL^7h*mZAu7-N#JdA03m=jxnV3a0S-TGu!MuMP}t`RK1wA#qu>pfVvucBSE{j) z|5QnU1h;}erwrFDoDb!S2dR>!D2+cNr4#=w>&Nfr-UZ_CRD)434n~RF!eKb`v9y7L z0fs~<>7_l!Nq=YAr@|1Y* z;oRaiGO$$!Im8{_%{k9=K~rtZJzR;nox?ug3gX2RKCKb*x%#A_^F+NGDxEm~JV(SL zP)uyGr$0mVjYlBa)9=nG0^wBK>*?>zxQR$8xH58t zF0Magw)C7KJ!c`R_lKw}AbD$Si&jJ87jGCbro=fqmr`wi-Dr6$JPgY*xU6ESu02cR zd_h(1O4F2esaRpUS9>pLfF-9}-*H{gl)Q}x z_MD)!tS4c+g84!v{*)CrGr~_N5J$3K)WBmmFs+;8HZ zkAs0o95@1Xz8)uj8z&Br7tQe@H$6X#3#NKuo41D?$gUwH_=HI88mom3hQdaY4qChZ9fO56rv;N1z<&W{%D$aXJd?({ni-cGC8hqjSoux3gJXHiyGR zE}xr$&21)^1#X8N{POXG&1xy{)T!y5WM}qSVV6qSs}kZ2!nsJntP?Io3fJp|+jT;n zPIy))%z-6&h8aj@-nTq&d>@DObXonHir=NeSrcI^6;tK-vyo?53<*_O<`&Sm<3Ja0I?JUqUOLakSuux$X0&}a+BzHWOtf_-hht>?V1BYFo5Nu; zYOYRol<6!PXV-|& z!4GB4%R>Gvz+p`$A)US21ZHZ|58V8t|Im{;b7>1Q2YV2Q4a@^>w>c@qEa`lwuTAc~ z1*iPCuo-N+;{}cVW7hJb#@Wp}c4}&QHB+9x_2xLHm1ktYZx6AN|`TX1G7HOzF%&Ae_7e^Wi5YVM{Iyd$|G#^IOZ&Dzx|0g((RSRi2gh&d3#6=w(Ez~ z&a#n?9V4CPBl#U*DDTzq-(Ks4tL2==zJtW3z9WY5hhXI=m3gO+Vj-IWQ@;%3JPS_H zV&_g(6jl&I&$3JCxw#X#H#SURg!et<1wB&bSi?Yn7-$WHmj4Ab0qQ|2!3UaSo)+h= zSz5h!ffhSPVV>5YfI{|FT7EGl2W7Gf3IZv)a5oZdkP@we8X-W%8W2MN5%OZ|nzso5 zZ>D_Z;O5P*!QOdoFgNtN#nTNUsqCpW&vtvnx3oTtc~2+CDBJ=13^=`KperZ5)GSv+ zhbP?6YrR7w0%nGd?F64B1n+jK0@W_yL!vH>*ow>LARe+*Xe?kydZ2Ydr-15_%ezz{ zjzDe9q2SpRHjV*GUIW^w3_mF)qKFBWri#-9f*Ugm%c_A%bKNgbb3jimCd}{U;`1uk zG$n6hK=(Z)pX8mUM7a1T6-_uQkN!hjB`6m@SIL^0gWm5HAWi=yH$Z*vS#rKAH>eJJ zkC3xk-c=Kv=6zEUtnltstm-<{rtof8qo{AIjY>pFFa{cbmInNkrTQJr;Ev3hN40{2EFSBBKYZMY>I2S zbW1fz{uhO|6m&W>0_1;?hl>tn=q-h0%mGM*tPZKc=bKnss9(BEcAwp-J{^gnh37`i^BS#oqL%#6s~?r#sP^Zq&VQh&i zDS4gF`!OYKe@~6YfXE}sOGyPSQDbFYJJ)w_OzQ!ozci}~3qh!75$~+Z&baWAlDGoO4ngHZC&fNDM@?;^FM-S zdg${&rCrN-uV)Mjv=vaE-Zg_UDB&(fJVpJA0lte-3b!ys_;DUO`#n+rb1f1m95t3Ip{}!xn$#mvC-fZNl>}6`O4YskpsR|pt~%I|n3$+{?PT;Gm7>+WN;Tr3 z%gYd>_W`Ea1A@-Wn7JBaK_UUTSm=zfd*UTeTNMmHcvQ1K`T2$ndbk3Ek<) zM34$%iC%yuc*5AOF_Gj`s@X_}ml+Ov(;}_7Eg2svV8BWVPDi>iVZ>Sb@D{XASB(i1 z23d<8e#@4~(DpMZqftIwe^+KkP<$lvh0MFk@Om=}(3K5p;gLw!bK#V{##D^ZPH~c+ z&O^!B>URE&>00Y;h#bZ&;9M`CsfZ$wU(W)`OM zR7_<+FhrQa`i?F4J4Q>j(UZXe zlCc+9agiMJl#HQ)L_k_}Vw0Sn1JZLa?O$Z9S%$QNM+RkJ6#rZpibuwdp&0RuOq>D% zbG;6N?z)gH+ns8fu|64QtPfEJ-TfI_JP)?0;Nu-B7)>&)DO%&eUJIkUg` z{M&DWtXd;i;sJ*=3Ms z9`@h649-epwQGk#JZ+$97@Ca34HLg?o;v8^bj{+i`T*STU3ZEqYKG29Rz!(=|NyZ32O6*VuV{Q>3XDs zQc)G3rcb7BIxmMP)4eM8c7iNKtL(#cgSnkk^~E0c9tgC_?aA2Li-~e}wd5NX_B}>E zu}j4c)0vZ{Izqo`vJU4C5IuwzK*XT-QVfgg%o0rm$!bZ~ft2#egq^DJsK9Hm2+++K z5EShZ=PMjQfd8w1|J(Ra7A8T0Ya4LW2o(gK{M*Lz>I}U%K{v@>ZNxc4wNcdQ0-j(* zOR}y$2|LvK$#@JNQQ38LL}l0E!stR|Mg(H$(mfJjyI8t)?_Prgq%v%3gKJw>>R>Gc zsm38yxBU&!@XLsZr^`(2;ICL5Pe*pseCqbl;WZ9XNsrW9%dp~z8+5Lnx^530-gNRW z8M8qGz62fZsYdHa)5hIu z#|W^M*`=T{2pTQ|gYe^Zk|C7D=2|3eb&l7iJH`Wld2dnJ6Lp>T>vXjd#c)|Ii8^?! zmg{uF1ck>Q31_6vJRldhtJ{|=;AbN=S{U#IYLUYENSa^m?F!-d3LHWsK`bI#N)$r7 zf-vW4xg!aZm9DoHm|^a4ekiT40G@MA1~v&6Q-tPfgodVxQNo6hfF>kq)Is}%ZqV3tw~Rb6HrN?db{Rl+)BS1R@h$PC=vEyfWrA;#F;iVy$|r*DpK#s3U8ZF0af zARKZHh==M1JckYqoIRvERNusYXgO5#>yu?Uolfp0MlptR6 zX3d|Q8`2W!Bv6?%3UWBG27?gGgGRyZ{M_stac(s;bbHM~@gN;UUaZCpa8`1cyqAE{ zp_Q#DH@mPXXO2{lxghs!#B(fBbRpb`{h|3~?~ewD(?o0 z9j@1V9r}2|t_P<|n~K*PFvw$X8#cfjO|c%(>6jATkVw4{NfiGAy*OGg+I6^%NJmhw z>wY~*db&#Rh|~3;TRhlHNE>Z;Cw2~jT7|VF7}@fczF)dy*rhLl#=c#8+K6kBU)ZJZ z1=#iq+G7aP6SPr(tD8unRy~LuP(wIUNg1Gha8RF!%M1iwyt)YL`;oEt4evKnHR%{D zsHfQ4=9Cej0$`CvuM}iTjAU@_q^lhh2=8)A;ZI8E1fAKb6PK$cEhdQT$8SMxzBofo zICPi}>KjsY;>+r{TyvB_XBKz>V4@Bg(+SRi_dz8>3dQdz+KL>)e5E;62bzY6u16^} z5x5z1i6#=LrRS9_bTfkRsZgO#1T$I3ChN@UddlEZ8koyqy`&_2MZl{mAxz3PNWRpt z@3`c1hJ9U1UJZR55Um`xkD<>zl= zwVZ96MV4>NnwF#COcff_lbWq8r(t=`dWC6yj%nL88wjY192@tjX&a-NCM(cnnpv$a z%96=x8Ch1&wgQfM)RJjiZ;moqqBL6{wb|Bl+sw8nqZHg$E=#M~w2t9emNiYw$|?W@ zfyS(rnJTyq9H+=KZ366REVGSSKP}5tptaeyZk>ih*lE*D6`3~8lTo}zX3=V81sv)M zpDYLIHCe1|+B!yq`fi(+V=0I#;PHtH1(#`I=gpf}VB5ghw6ZMDR-lzJz>zo|@>~OK zs0HF=xUI}IM#G!7nfR!zd`4@MO=C>cG@48qvpy?dtL3tIe7z;gY%*=i$}h0lwxQ*4 z61~B;!L&_l+Lm9S<<{pYP|podYVz^ikYlrP`5FcID-;aAN|R;Urr>QkHpM0jGTXLp z%h6;X^eSS`1E=`6TBrs5iH@-oe{yHAtA>8X`e+K#9*5Y zHr<TIbwgUhaa=E!I}A$eC)q~iGAj$a*fhrneWhIn zd?|frS06NdDbsLx?lD_pKAH1TUyS*apAAz=F16V*oE&B5BIP}!nAkg)Sjv2mlG+q;j?HkWId? zcDHh04B7oMJ@(-7bmg-?`F>{j{DEOFA9!~7i=&?dn9VhteBC=ootw{SDe$!tRVZ{n zKEZb`l#cs)$nK7dpt|8g>BzY-CVvT1qu7Pwet9rG0XuWnY*vap2r1}$0s$%gzMU~@MjAMw>F;wYT0xd@}oZ7WYN)ek|CD9}EyQ(zr zFt%BYlZW7A4#p^*G0HS9%5KCAOt6S0n1ULMQJJAzkcLPc$Xhhv!@hIbn+ZzMA&+Sm z=g7^!QN_s38a0aL8I9#5nn`E+(own-r7vO3!&Cw)|Nd@fi^{Zn^A@#fPnX=Y(5K$> zf!rhOk2L>PgtG*z%QP zHv=e3@SD*P^TN2pC5oO{LYHJi6=souN>?oYJ!ij~~xqMK3LEu*cZbV`$*mR+w)%W>1$>n+3_gUq$A?F_7 zhr5|g8%DiLN#=hv^o3E+FvESHUKs$4`>B+`|ItuibSPtoFJcf{&(BjAR(`c%RD(~^ zHL9mC6yNIW8H`71@=)MgRNBVTlE=Prl=S||sAtA9xuZ9kKHTN24khdGy>>D03o#36 z0Xx79$0CE33+vcOM*Cz&!-0tu5?ZoGPLx9Kye#BS3fVb|5U`{g$O(+Rh7s;lIB~l_ z6gtcaO;aSP3F0jyEW?yQ$ijSuxK6wc_^+2xE@ zR(nr?`z|Q!RWXk=nhJRfxFJKD7M%uVH5aL>2y|j`D7KourXon`ZMC^kBYa1s_< z8(H!?CssM4l|q!G?EVskZBmka z|5u7FC5oNn;8s5KmBJ){rbID=ANCk^*{+58SQ~zI=OiRw5^;Hog~5S=;D71IXq9r^ zfJzpjQ4B+$AFo7kJhjyHfGDG@;woTEhA#KoR{xWnYOS)_NYx; zWJ7kPo;7Sy#XRjfxK$o=w+Y^;jnkfvxm&d*!cfU<)*5!pD~D`M+mOEdsmfs+Gd4`+ z9*W-0RK`d_Rh6-qf-5ER6JEv~-E&Q*x!9Pon9fsu<1?@Q^9kELD6G~7G z9ZHNFP|_2!ltf?KiN3CIShQw~7B@+-@Z?fBt=gbGwS$-eY}(G)6tE(IS~?QU=I(|g zn91EiuesdM@B(2~w?pm@ku$YKFa1pck}09GlYdM}H&M#?RJqmkjrfkD97W+3P{ol8 zvqSs~n;-|Vjv`|k$#cOIHvr~X%op5Xg8N1liAnUWDh|XKIZzvOltjlNN<($}NpM_( z1|%K_O76T$ZpJkmLX8M9Af)e~wax!-+$(!tt9t9N)o;IZ;Naidj<=sY)p7b<_a~p8 z@BiYUVfTM+evDC%d`7~Aqv1MCF0bj0JbAXsf0b6Vwo!V*dnYdS7Fz{)KVyp7*;E@uAd(>9h&QTuSUUpY1w`|z{ zw}*pt+c`RhTRv=mJ-NF^`2@UT0AP&Vu1tLSKt;`qi3@j_y%IU60y!tE&r3ba`aWLB zuo_d0Os-I>xP&CNHg#G={_I;KbKblC9N5!YNhGLE-cZ3~zDWYm2nqboLT zl_Y@1ji2C{_;h9RuD$yvrA)rwS<~Q~l6K-u#z#G0{iD8IAgTPsMNO}Vm;qo8?gz=F ze->!a>mnfrt5zu$av99IvQpjE8f`?Rjxnm`5i*rt%W8Cre+GnMa0feA`~3}m=6(0w z1MAa;bBIKhq=Cq?Gq-a2?MqkOxp+Bu-|}U5Ex-L(_9N@KcMz{ zfbWK};^R!3r&at9rr8kT)w8Y6pFmjA&ZIk1Sg`y^@jMPFNq{m%Z%v7?rr1!yR0179 z2{2~Z1@ZDioi)V6b{6z3a`6TRYqm3mO*i1ce~-dhX28L_MZuRDCV{?L@5v< zsEFQ$`g4W7)G$-5QwX?wT_UBw&2_s%)XLj#ca#|lGh+9*+@v5Y0WZmf+bBM*kWw#E z*vmrsUX&wHQef;@W3ZQm0-u$8?5hl5q4-=0yNIO*$@Edb6AmV%)HuHVWpI`ml0zC- zFQo+|o*+dCd%&``+5jsRU^scuU>;D5&nR0u6zn3Z3PRZjRa)n2L$R~Okme{sP0RMT ze5YX7P_&1Ahm+|Wsgm5Xh27sG}#)i3MrrME9H#fiZ^upzx{={=>koV%AxXATH_;GTQn1@^k+BD^9U zJ6w5yVIz~#w=W%B0d~yW%{<5Gy{2z=?Ra(Uj+Zy#pfBSl9sQnRv>*A-KkYlWFjYFQ z8$7(*!|1<%ZueG1=-lqj2%OvDu?LT*D{rE6JN^6t-OC4V(*MA@-A(%Mo!e15t~vte zc7ve0$u)pS`0(!BrPI4XDa?QW&F&oS(fXpLeTTLNhf_b_m;p+M=^EX|yuj2%!l)c$ z+JBv9WBNTA3?oyhG!Z%jD_5$uk$PjL(B$(=HlZqa3A-y_-@k8frRWh_nvOQrAFJF` zd8D!O->=#KOirbEos2)J1WWuoO7RymXNMA;X(N?vHO&ukmC{j8m;qM5$_TmUq{9ubCJs${{yin)imnTQ!n z^RxWwJ96wR!c5UWOfw}VP2g+{6l6+QB9LZ4vVZR)+yQ**(y};$eH`3k*AeCic4n^x z4X&4j_;g1?JZ>{*Mc8d%!yXk+TrakGtHl-%4-7WM3!@_>R+CwA_BWwM`ZkR?S<8=! z2cCU(B;E(x4@TH$L4DC*$i9a7u$HYJ3G=xQdpsI=PlOY1*8BSi_O~*zN{fV+*`c)1 zc>U@~$C!AbnnX1b5o?(h2Y3|>S7DP)tH{c8sB9g$R%^aI7C4}}LeZ;@l=$GYUvS-hnl!9&q z>m{l)cg4yF9xN^?UA1~mS*Yu8BpH{`Untk)_#ZuBfYnj6@E=*R6H4Kk_3UFh?{HqJ%uHQ z!X#;-HchSjGKrzL!V*Kf1|^1$ha`r)mn4Rch9rjeOArj9dhSBTxRZ57G_+(AI4z$eae)i#PYP_L4P&*lbsK!+HQyF#7a3_&|~s|3U5#z zN^vHY@~E7hBjH1cpQSLw9QUAsUt@q(jx~n(mI?)5LL{124l1i{1kB9zOJvlbS(;x< zq*#PEM3UKDDMXSXY0&2Ck`Izz6Dbi?)f1hj-QNEX{Psf|u6 ziTP}c($RsSze_;@1epedK9GXmM^Lnst4s2C!aoE_Jp4zJ|3mnPO8#?_|1A8&20@%x zUcpUxUYYJVk2S~pqRif{?6iNPB)ri?Z`6EUWMqZqnrI$8w~gWO_k1msbSEDHH=CzJlq6MY9Sr z$8y(CynYh!GjOvO*jfu@jm%j%5zs$3MH7J zog%4sqkzI0fIfHr?A+;6UWazdO$FNQu@pZY;7N2)OOW9v@y;w>lJd+6y-=zaJ7K9N z)NHqa)oUhrz%ui4xlDl2N6ab6n^ic=sm;mKj=t2aBraG`IE$MwF4;C(9|7fgGw0+< ziL#5v&X_)SG+6F0Yv`~h6An3ucZ{-7i`A|S*??Pg)7Ckp>84UdapLE2@WQ;-@` zn%dm4Xv_bsGp77dJ+g~tOvlzjOE5FXW>fJ}pGx(+7(V0TC(q8#D$16I!u0H{#0itM zQ>fcU6B`~e%wbWUhYwCj;^r1|6C9~y^btsxU34+WL^OZ)Jg7XRRHUV0%wW!0^JZqD zI|j2(4rQG&>r&QU-pRVR%^yp&2?UU}bEvRBzxylSOUFbEm_kMEdKh$aaYfw6?VIbbqGcn+q976Q=P zOd3)MOqZUC6A+9FX))roQ?jU7Bo5gkCcxnV$HBsJ!L00}TpA+OulN{rFelX~+(Ocn z2y-l6{5l%9;SZE@WoBWP&YO#`7#u^~Ad{n11muO0oQ6r}*qKxeu{wrImkP_w&Ym}O z-i%C={3C<`f{hRWwQM$&Q_knI3NVE)j$9g~=(Eh6`4ou3Kp&3}l+q&ThHT9ASp{Kk+C zUj)G=%q;?jDVQ$xU#Mj<_DRSnoGm=bB)KDfgoJt}c#fnnqP|oc`kL%4DRxpeT1y&0 zz~gg^plB-#1Np|mv4MJ_u2Ra>B%}=CM2Yt{{1F$&oix$V4_It6XG=J}C>srmzQ6bk zb=a(etU-(hCr~fqu_|aG{C}|n5J9=Zs{%NBFCxJZcW-!opx($C3)~&z8U~;5;KD%~ zO=snCHy6y!C!5{?7Q%<&jtFDa@Hbp)nb5EZFI9uZ+Pow^CK)`JL70tCy7&>H?0t0(PcU){w4;+~aMQ@e#zY#oQ?z*) z3^W}tPfxG_&>6~b4voXhzJS)Ba37-2b2GVw z!3B*Bs!Ov616IPlb7qg7Gxx^1(!@dm#P&T%1%VYiWUw7LF4Q|xI}iZ@R5K5#GK|YF zt?U3w?c|t*8Gr}P5oth^_4h&bWubnd*;05TK-^dWofOkUB6`4ng;*4%;d?P3&}&id zST3&s)wp8BNi{{A;M_j^F*##Hlm}IVs)^)qN|i->g=;GTrrwjJ0ttCbAt1#t2tW%W z2lQnSO1(9=sE|5T!nXtnOGIdKoRU2Q6dpIYE{2v;sp3+j=8Q!$WC)FO2{FJYRVg%{ zr%)5on3F(X{C?^4kaDo2X>!walln!P=~7h(i~9$32LRBjda)81pg`vwDU86!fS63m z$5_uQESx)sMuAi$X&4z6K={Zm^FuREU1W3BrUih>`HaV0)v7s zF4NSV5}bKiMbKh_WdP#{ArfZA*M<20FX7n)kX4vUGv-Tc5Mkb%3uer~{TS8uACX#@ zQ*T$2U0EQyFD|qwIZWFm5?DaQ?cgw)5kjy@nKb=r!J3{ct@KoXsqL>s%{jR= zndr*_7=4~|iTDAkmwJrU@kw#hFU4V5k$_!_n=9dUKuE-zbg8GMr7L0LW%WlJAXO2@ zHZ}&7egfz-0*1c0G#qnhTwH0VXQS%jiCsu@DLj`$oif<}(ny0ROiV~4KSW4lZc4dn zVrp+7go^SoS28iDC1?`_KW5Nu+kghlKY5z|wOwi{^$#4xuW17M6UX{D`EK7B);xiSE9- zTcx%@CsI1lFi3_G06ao16GBs=eI@NFQ<5omPHqtvm5C1QP;SDMkrH8xE3Jn_UILQz z&6gc!{u|E!?fvhM{r-pfMk_oXZ5Ruc7dA7r039bS(F}pvG_`1Cyu%piL~GDW z$}Pq)1~uHph(}ZdR9mE}g-MKfP1KE9q`|^1<}$UeH1(A_EDj=}YY{Y3blV%Wq|Blm z$}IE;8+4L7i{*%L9@gSUGfkb5@8}q&QgoUdv{0fv;_yD^pzBph!^Jbua1k(nI}odP zJprLb&->Q*ku;d!5WJ-!I3EQMW1J1z;Lp4P$R6^qX~laPz=LKJ{?ssN#7wW8&kB|)?_^AQRaD@hqE$HvVOpOQRzuIpI7pN00mJhpRz z_zoMe3aKnQ!@vw%ht$Qp3#~(4v(Q(+V&k$9kH=H2kjKW2gJ)3MAucZz=rEn3Ad;~# z2Uzj1Fhj{WUpvz!^FGC{c2u45z!Ts87uLy~2|naq%L#Y^v5cKagS@c(#ce(1{~rCjYYvF6<} z@kMHU@oO1GcJ-Ib?3UJNI!4OOudqlVKFemvAd;IA?Ks;9+@Kl_AzgPTBy`1XEQ#lO z7qRA2Svwg_{+nP3$YdJgiu3DullQqMN+Ka3iSVw}%GxZ^9XMwSY z#hyI|RonoEMYZ=?!UX7Qx(5s~f`qu2FUmlJ;WosIAaTHjIB_rWMN^jVvqlf{LjTzN zKXevCrXwz1xSr!lFnT^1<5eb!G5#t&fN59i0o1CoRkABZ8{^F+J%Epg^Z?E!J%Eox z51>{}QOijWpj{~}WSoy*r3VmsGa1A|j|~e&VUL3!3^w)lGT?^&^&O=5h%{|<%b||i z^(2#Z<7(0rxRG($!Ec~sQiK!%;}A@`SMIsG?T@QytM%a}y@98~dIKLPy@4`tqCf*Q zL-KFGl%&e8l7G7?Bx(lvw{zz%lYnFNBmt+tBmox+xFi9GxPKr4_wBzT0k{3%l7OpZ zcHHDmx&Ybd+Zer_eh}pFeey2|Z`6scZsFlZtca4a5JtSM-leT~_B8g3a~s67b*@q` zFE*M_HL6TvR)c+0UAI_RA58a7^#&KXR(N6JYEvEMS>f%?<9iyhEX?=ryAR&`svKe? z0C?~9n&B`|DdM?9^t`h{(AKl-z2ZxC@Jfqx?kxqdmdA)+9fH|2ZT$l0kw%OGZM`_u zEj-#NLLDmwxaz#9S+)1kMlg*uieud3fjUH++ZstTr?$Qob#CS#Y80n6h`u`SuN$H1 zsk2)=;iejVUFTvOCGk2lQ%Bl!TkdZZ0>aM^3AY?t%Y+cirRVq9I>4oIH46vFUByiH z-|%Yc7zVN^Kyz+!b6qV_N!#k6P7DtY54ZSqU7)kQCIi3|ojfg~ND zHl~4JToCH29G^7eYlX%-g9%=PnI2JiP~ho0$;KsNRgYna@Hql!>@n_ns76!5nGAc@ z)g&zZ|A5f<6x}7E?;_)#Zh3;w>|uMZl>L^(zL|)NV&A`tyi)9YgYgQn?;_(8uE;p! zZ-%hgH{_5Y_PD{gL|e}vX@qW1LOBx~tfZb4i!!;_Wu`IuNGb#tJ^)QTE5`Xc}1RtMQW%ja4w#Lx1e%I>d^n+`{@pBdVdO5L2NcnBEXv&=4Hg5Ohk$ z2htjX84VsOx+YpEtlzlIXY+tJ9GG{0eP?Htqo*;vdURVJtLqLxTlJ&$9n#Z>5w!1!Ms_;sEF(%p5^%PuFA1zeXTT?itYk$2; z4h8FH>!T^+td!nQ=}$`O8>I9-NPjw%{w&g4Qy8V|v-)lu{pdAlj?UwJ1q;!3H-f7(n7RXX=2siV#ySdl2dmTJ zM)G6H+3q&0>wp!Cxb=`DpNwxQFce$A4E>;S!xQmeu-{6sU+0_luPb8uBSX7-%`i#Jve+3J2Lkd%c zb&?7_Ul+nY=7d8$b67=m(B)#^8O9#__r<>V1mwH+KWBur_a7x`??}zw?Fn3c*8GG!1%E>?I>B{~NBp2pc)FpPXqDUQgORQ*4_o8` zwIW_m9WlwZ{*bjiIGdGJj9A3frjlU-{)p|Fhi5Y{D2_`1}Q+rzJs5AN``{H8N=6qs(qN2@i@!GVXUtmJ&xdLW%gIQ1pOG;j zUhsblQwQpWn>xUmOk3c%VPHlL;yLC6CV~-JcHu%Km(jP@$ZO;;A~N*9=As?9|2pRU zXF0b2{@MR{?)g8y_|hw{LW=t@Z@dXX?)`7S^DacW8^t3{N8673+fTj+iSEv>56_;&4b%W6aIp}>P z2ptnUqNdg*)Vb>qHF&(&9EMc1uel}uSS!b$fOPavMvYE56Zrf4A3!+zqp{bG8=o}6 z(bGFI8M4u-UtRBe3#9PILB9Nwo)Rufa%@De=Y8MJiZ3$(BITfnf~u z*ZI8ZkO9(+DxdjCqly^%3#H{F?GVx5a}Sl0686GFI$`3WDu=pm!YhsL(vT&m1t8?b zeRYmk8f#0tj6}SHC{ou|yPiITRJ6MI+@NJP*JWhT=)c|#6o#RTP)d7SeVw!?sdnx3 zisKIPwTEa+D5<$PTig)u`GseX$K-v&yVJ|}J!oO-c&6?wd-{;@Qk}$|AaTwxY!3xs zqeB}GnwmtExlG(1Ak(Z8D)_acBRklOei{!k7+Lk)RFcdAe9z9m+YHC7~mL{?C=wY~ydQMPul_R5P znKQkop1Z3!<}-OrYJOU3O#Z-z^v#c$w=fLhqW_IQOdFaxWybvHHr4EApoIh4IJof_ zxTk{LqroLR2A=h(dQ6qf{u|6aD(;i-8hrgT77tV!_AfC%Ghjqx?PsE%VPtSr_U<2u zdS-x}oA=2#q;1-eQF(}~FrV9*(G$ZBH*cKwa3)@7n4UQIG~b91GJ8h&hID0YZa`yi zIV9iGA%|iOZp&%;4yGr5hoVyXdfKT6%|30V8je-w9=X@o{m~hjPyXpX`3vcfJ@b`p zQ%#NUdBZ;W&J1i1MnVb4#*JxPHrAj#s&L{J6*lcZAN|aED5Lsvx3GmVp-9%WyM2qy z8%THEPg_z92<%@w%R#$mn8bzkfpW*GMrk+ob0T6?JgwiFI&5$=Xlt6$XcdwgRg8HZ z#A~a)g^dar-pFn&fsh=HW~k;I;TBk zbV_*il<>qU;i*%?pHEeJn1y#=R4(;)$5ZXko_3xdES3B(p1$D<|6fkudWHYs>0e#p z_nuyLg}?3eW2ZS%(X#fUiWak);rI2$mbb|{wYcz9iacd#I;RyseUE1v#3?67asf!) zomu_nU7iUQjPs{wc*Y=pbXwfeUgdbR!%@|dAwY8=FK>rrp93V3>M+iVSoG2pr=Sw; zFI=mNv1d1FyT#iedR^Eg3Qa&XvhcHZa^_`tpvQJxtZ6IR#_txJ3Y`_Tzas?`}na8 zrX7z8Br_u%mXfW1O{^JF91WT6YZ9@t=QcUc`5oPUF|N5ryt}!pqUK^DEKHx=)~ux> zv<8#&lpl8QkCj)CaGg9>T7R|41jVZ^~e| z7YBs%Vlc+F;7Gt3*~IIb4z>iuN#YBlFzZNgsO#59#Mi}u5D4X` zN364y0J>HT)Cwg>I-L#YR1jSj474FVLDP?(3UgA1%1hSG0 zv%mek7`P8dA^D=H5(TzN9NLa&X`1)Uku>CU@qmZAfMdj+$9bNKh2>+|H?~*#omowV;yE8qlIAxB4(BzM#h*av z%p5VY*;3^f{@mhh^Yd9v2OEk7{si>(b@&0NybBVeZT?_f%L69>z;W7N?l|M`I#Vp> zo^WP1A;n*dJsB3N4~{SQ_yMWPk<|pE&GNcmY;OiAae1@&(-Xo^kI{3-F$2?$wc6`C zA!1|&r`Aca(nt`_HrxGvOLh|y(x;rIeBvLD3hYtJ`fe*dgRNnBHu8$Yjv>}wHDEdC z_t+c!-S%^SE8ODmnp|i&9%bw&81!Hv;{Yp z(&TmVmWZc!2x{IojWvGZVnEfr54{ z*Xu2IFDm^vKQyw6e`>P7;ZLERofvF3;MSl;nt-=8XLKI)wzQzR54yf+v6i>l@Jh#g z!e;5$E#l^8p(RAu2Td*QSHX|V@EzY(s$&mBN*{V%1=CWBKO1}PV7AK z%87;($4{I&(RJeE6a6QGClvk&zu7;wdANV1f0X|^f2KdrKhtkGF~_fHQZ)UCpZ6XX zI}gJa5wuS5t%rp-5Ay-(`5uJ}43o8J*$NWy=L(l{929eB-45wZNgsf1&fn;pCvoGQ`!n6#oK%kyE}Na>`hmG8x+8^O_omdMs^eMk(PSadED<^ z)Fv)!ULoAm2B~qa7X4(9Idhw6AU)=Dw))f4UGKEjx=W>Zr+vTw=3?uR&o;M-XPWIF z`VBHbbc@YRwc@@ed#B&PIP3g*JNH>#&$a~+g&9JTAS#<`QC~jbKiJ;VR-9}AmCv7U z>nA+9wzwCFj5&_NV0f1~F1Gl@TU+_uCNM+=+tMBHV=%eIW9-KR+HNg0WejgEX5|dr zImX{FfQEPi)XC~2+& z1aZeP8i~{}I>?Qtb;TEZA8O5Wy8V@Wi~mLM6RpClt*ngECc`$m_phykc-{4CtMjNo z4Iv_CYkxBwLRG7H>oN3B6OHB`q(Y$2$EU+x?_a~8@}~?`d!K89&6R;_j~LTl zWq->LQ}gy}dV0js?ZP`vqP@Mkf!7`uZfFAL!d=xlA4Y}cV?W>N2PQ#UnwoFr=<+`3LFQavZ%~Hh#gH@mM2XxVh}l3jnJd*uCt} z%hv3;3z**H?7%YpBrOsUEj}Z;i=C(az&ThO?8c_A?YT{5IRqJZt*sdPqWbt@d7Gz` zx~Aga>Ysm@sl|EBk8g4JV@!_EE3GW-t$ea89`_Fej$?lQgdgS%nk;@l@G7t@Y9gUl z?{AM{z3Cni?DXDnv{hW&+}!fpqd@P@6MoF~QW*9-Isz-znxiGS8eDTUs2ky3addmv zS{K%)HAmgEMD@{HxT9f7OPF(1T4^v0`D6a_;l3*LaIiUJ0F@e~!X#v#(~JUAI#C5+ zZcu0d^}^BF^RZ$yAB_aLJ*g$W<>RBZ%@{(Gq1exlM!Q?HZVZQG*{V4@JWX8G5@`06 z?se511$y^@aAT@#1Z}%`;jlPFJkeh$ZWUqo4E9(eB-3XavdZE#U=HPi!f5Ye8$d_| zqg`1dy$Ls0c^n2zBM%WTt~*4xXcd8!bnUfnr@pDW&e&dC3W5gKWs-xOZxT-9NOzyt>we9vX_VU?s>h|r8qrMxgI~xbHH#!!Io}!AQA{Y4YFp*9~FHc6z>gAGXU6UR1tFk}AEjAau`)4nF4FgStXd7!iR zn}KCfXTjEv1-9G%y5CSC6gKhafEN$eqJez0t`MbrWcF@m!J1_WWVfC$!*Sm6kc^R7Rh0eeG_1>TR zs)q}6d=(Ns4U$hH3B33FmX2aPT3RPOpeKMSKt=#*d$7Ehz3FiZemKUYySDl)ANsM{ z7XtF1-dZN5K;xnNC3skIyP>fjMmJvbm1BwPE_Vd{Ac=v%UUdB3Prt zxZ4@<7gH~KmL2rchw&>=k`y!DKWXCzrEN@~`x%RE4mY zUH#4Ill#jXOrMu}%-B1OKS@cFz5&E+~9!c=oH}{>L{6~IAM{(nR zYk74-`XuM}KK_-C1YPxKZ=6i*TDze1sbWv{HwR88im#uvzue*cQ(yIGO*n4-#XY}V zu%U4E#(tGryzaeTRYYOT%sl>uj`9W7oZ0#NzUls6PUI{5z-dvNdNevZ zLlL8DHUA|wLn$tr?C$R*gN$zL`>;8xQ;k;%4b6 z;A`2?9f5&APT0NRmwyQk$p7ZK#_-qha#O)Dijcpe{)O@_a%S2pQ{Sx&Q@MOrjFw?c zJCA*Ylpj5qKOC?asN~tiY5;O+InBRo{RlB-VOVhpGskm$UGPR0~&9{G^TCa|Zj;hip zXp{!KWl~6El-0U;4_B{vL{%NHOIpY<0pl_B|bC?{a$knLg*Pjsu*c^xcGs&b=Mg zbt^iYdpaDib>xLiIh0&x$^j{t-45%a+%^YxBu z4hmBCc65KT*ZG%@_zcD;uIRvl#@>z$ScwmtcEA~qWY?iNXsWU651(bUa-GV^Mkw@Z zjVuz@UKr-34rT(wW_TP-d&ch^a)y-FPCZ$L`#8E_P$tE<$y2Z4RQ%p}i{WIyIRA97 zCF?zL?rF<)Co|-Z@7kUFVVXKsg9yv`Q*jl}x5+z%5?UrLD6OtDIUf2(mr~{K|2E3; zjUlCW_14-2>r1{Fld|op&&N!5i|LbN%;K2IrQ%(a3#+z01*bc&P%NHY`#LALZ;pH@ z9jRsuizjuqijR(MuJYcR0((_)D$#A9T=#ZLptirXx*vs96t3!01ld2{ysq%6em9l1 zDy6p9-T%#|l&bM*6>019u;LX@?)`kiWK6HxUe_xr;venh!EtrziI&Zgy{Yntwr+Ea zF_XHRQCMqLzxe*hzn@BR9@hn*Y&n%;&Pe4?>BPK5@!j#gZ4v!3U7~(6lAP;JVY8n! ze_bf9ON>#Or>BYs6F<{V?iJ;Z{+J&-|66r};+6dg%0yFt3~!Fa`dnT3nf1M{wS{iy zjy~YgQzv1kroIHZ{o%f|v?%1fXW!Z3e5s>Y{PlbGgdV4@ zXTh+ZSj*0ia>q*@!856{Pr0tCUra0ZlvF1~@>5QB^2grWxNPa!(x9GGRyk}vo-Znp zOu?V(dyVeLdcKP(%@|-araBxwINJOicYDk3ve;mGT8 z4xAU=?QNVx7fed{G&nZlTyPvGPfST#-DOI^+qSw(QImL|$8m2Y-=$08unkM>w)$64<>rwNe*7;-IfdkY&b)zcw}83c)#9Brrf2;3(@SkuD!{n z8-m(E%c5j3qo33XHOXt%1*6C>>`JZ;2#c*bH>%?=q5P$kSX4>vscdrF)-F-lP`~<_FjV`EGIE*eWqT`LDve z6Y1ThNsy%^c8jXS?$6$xm~tJ6_-=ck_DyR_lJnlkn}<6mN48I!iO4Bn=AU*Vaz9cais2ix=&nm+W8-S&PAvB6{m3-aoPK2EvhuNaF7s4>cHilK&>u+HD`cG{)?0nV5Ag6p zlh`<@5pyI#O7n*}c5#(E1z2BQ=ehE>_+Kf1FsE~O2hJ42U>0+~INd8oIr@Ppd#js0 zge>DGvnzjV{>mCcma_<120mjap9MEpN|H6^YfjMsXFD@LP^hF@!3B0?*1Xu@{u6;W3Cy6n702!8m zlbpB5V)O@UtIV&aP7UW5Cng2}WA*k0*k9aiEq%T)F)^t}Y)!BtsRW9;;wl1yn{vbd zvv60>Ko7@Y7k|(2K;U5+7z$inyn+Km!yWy@T?0KGy+gf%ft#B#RCxx5yZU>0y97IW zdIU!J1%`)4=tTKO1!7T3fe>ZwAGZ&{9@(oqiWT30{nb?`4_n^`6`Aq|e{_K2z&R#g z&>Ry;w(g`L@MuW8yTD>o?_iy{#UEfYu4 z2f%F5_n;cwL2b?dcv5i9Jw;%f1$>7CSDlb>rI4cWEr|zG<$A!80Hc-nPQG>C0csy@ z0kw}d-UE(yDVIz5C+Y#G1nyM=dl>wB9KhySy3&?=S}X1;ZM&zqQ% F008YL- #include "MouseInterface.h" +#include "z80\z80cpu.h" char VERSIONSTRING[] = "xx.yy.zz.ww"; @@ -74,7 +75,13 @@ bool g_bDisableDirectSound = false; CSuperSerialCard sg_SSC; CMouseInterface sg_Mouse; +#ifdef SUPPORT_CPM +UINT g_Slot4 = CT_Empty; +#else UINT g_Slot4 = CT_Mockingboard; // CT_Mockingboard or CT_MouseInterface +#endif + +eCPU g_ActiveCPU = CPU_6502; HANDLE g_hCustomRomF8 = INVALID_HANDLE_VALUE; // Cmd-line specified custom ROM at $F800..$FFFF static bool g_bCustomRomF8Failed = false; // Set if custom ROM file failed @@ -471,7 +478,20 @@ void LoadConfiguration () g_uMouseShowCrosshair = dwTmp; if(LOAD(TEXT(REGVALUE_MOUSE_RESTRICT_TO_WINDOW), &dwTmp)) g_uMouseRestrictToWindow = dwTmp; + +#ifdef SUPPORT_CPM + if(LOAD(TEXT(REGVALUE_Z80_IN_SLOT5), &dwTmp)) + g_uZ80InSlot5 = dwTmp; + + if (g_uZ80InSlot5) + MB_SetSoundcardType(SC_NONE); + + g_Slot4 = g_uMouseInSlot4 ? CT_MouseInterface + : g_uZ80InSlot5 ? CT_Empty + : CT_Mockingboard; +#else g_Slot4 = g_uMouseInSlot4 ? CT_MouseInterface : CT_Mockingboard; +#endif // @@ -547,7 +567,7 @@ void RegisterExtensions () //=========================================================================== void ApppleWin_RegisterHotKeys() { - bool bStatus = RegisterHotKey( + BOOL bStatus = RegisterHotKey( g_hFrameWindow , // HWND hWnd VK_SNAPSHOT , // int id (user/custom id) 0 , // UINT fsModifiers diff --git a/AppleWin/source/Applewin.h b/AppleWin/source/Applewin.h index df288b9b..1c066bef 100644 --- a/AppleWin/source/Applewin.h +++ b/AppleWin/source/Applewin.h @@ -45,3 +45,7 @@ extern bool g_bDisableDirectSound; // Cmd line switch: don't init DS (so n extern UINT g_Slot4; // Mockingboard or Mouse in slot4 extern HANDLE g_hCustomRomF8; // NULL if no custom rom + +enum eCPU {CPU_6502=1, CPU_Z80}; +extern eCPU g_ActiveCPU; + diff --git a/AppleWin/source/CPU.cpp b/AppleWin/source/CPU.cpp index fc30752d..233c7827 100644 --- a/AppleWin/source/CPU.cpp +++ b/AppleWin/source/CPU.cpp @@ -88,6 +88,12 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #pragma hdrstop #include "MouseInterface.h" +#ifdef SUPPORT_CPM +#include "z80\z80cpu.h" +#include "z80\z80emu.h" +#include "z80\z80io.h" +#endif + #define AF_SIGN 0x80 #define AF_OVERFLOW 0x40 #define AF_RESERVED 0x20 @@ -823,6 +829,18 @@ static __forceinline void DoIrqProfiling(DWORD uCycles) //=========================================================================== +BYTE CpuRead(USHORT addr, ULONG uExecutedCycles) +{ + return READ; +} + +void CpuWrite(USHORT addr, BYTE a, ULONG uExecutedCycles) +{ + WRITE(a); +} + +//=========================================================================== + static __forceinline int Fetch(BYTE& iOpcode, ULONG uExecutedCycles) { //g_uInternalExecutedCycles = uExecutedCycles; @@ -911,6 +929,14 @@ static DWORD Cpu65C02 (DWORD uTotalCycles) UINT uExtraCycles = 0; BYTE iOpcode; +#ifdef SUPPORT_CPM + if (g_ActiveCPU == CPU_Z80) + { + const UINT uZ80Cycles = InternalZ80Execute(uTotalCycles, uExecutedCycles); CYC(uZ80Cycles) + } + else +#endif + { if (!Fetch(iOpcode, uExecutedCycles)) break; @@ -1173,7 +1199,7 @@ static DWORD Cpu65C02 (DWORD uTotalCycles) case 0xFE: ABSX INC_CMOS CYC(6) break; case 0xFF: INV NOP CYC(2) break; } - + } CheckInterruptSources(uExecutedCycles); NMI(uExecutedCycles, uExtraCycles, flagc, flagn, flagv, flagz); @@ -1211,6 +1237,14 @@ static DWORD Cpu6502 (DWORD uTotalCycles) UINT uExtraCycles = 0; BYTE iOpcode; +#ifdef SUPPORT_CPM + if (g_ActiveCPU == CPU_Z80) + { + const UINT uZ80Cycles = InternalZ80Execute(uTotalCycles, uExecutedCycles); CYC(uZ80Cycles) + } + else +#endif + { if (!Fetch(iOpcode, uExecutedCycles)) break; @@ -1473,6 +1507,7 @@ static DWORD Cpu6502 (DWORD uTotalCycles) case 0xFE: ABSX INC_NMOS CYC(6) break; case 0xFF: INV ABSX INS CYC(7) break; } + } CheckInterruptSources(uExecutedCycles); NMI(uExecutedCycles, uExtraCycles, flagc, flagn, flagv, flagz); @@ -1593,6 +1628,12 @@ void CpuInitialize () g_bCritSectionValid = true; CpuIrqReset(); CpuNmiReset(); + +#ifdef SUPPORT_CPM + // Z80 + InitTables(); + Z80_Reset(); +#endif } //=========================================================================== @@ -1694,6 +1735,11 @@ void CpuReset() regs.sp = 0x0100 | ((regs.sp - 3) & 0xFF); regs.bJammed = 0; + +#ifdef SUPPORT_CPM + g_ActiveCPU = CPU_6502; + Z80_Reset(); +#endif } //=========================================================================== diff --git a/AppleWin/source/CPU.h b/AppleWin/source/CPU.h index 311ed24b..5ca395bd 100644 --- a/AppleWin/source/CPU.h +++ b/AppleWin/source/CPU.h @@ -28,3 +28,6 @@ void CpuNmiDeassert(eIRQSRC Device); void CpuReset (); DWORD CpuGetSnapshot(SS_CPU6502* pSS); DWORD CpuSetSnapshot(SS_CPU6502* pSS); + +BYTE CpuRead(USHORT addr, ULONG uExecutedCycles); +void CpuWrite(USHORT addr, BYTE a, ULONG uExecutedCycles); diff --git a/AppleWin/source/Common.h b/AppleWin/source/Common.h index 9b7b378f..96a6f670 100644 --- a/AppleWin/source/Common.h +++ b/AppleWin/source/Common.h @@ -1,9 +1,15 @@ #pragma once +#define SUPPORT_CPM + const double _M14 = (157500000.0 / 11.0); // 14.3181818... * 10^6 const double CLK_6502 = ((_M14 * 65.0) / 912.0); // 65 cycles per 912 14M clocks //const double CLK_6502 = 23 * 44100; // 1014300 +// The effective Z-80 clock rate is 2.041MHz +// See: http://www.apple2info.net/hardware/softcard/SC-SWHW_a2in.pdf +const double CLK_Z80 = 2.041e6; + const UINT uCyclesPerLine = 65; // 25 cycles of HBL & 40 cycles of HBL' const UINT uVisibleLinesPerFrame = 64*3; // 192 const UINT uLinesPerFrame = 262; // 64 in each third of the screen & 70 in VBL @@ -87,6 +93,7 @@ enum AppMode_e #define REGVALUE_THE_FREEZES_F8_ROM "The Freeze's F8 Rom" #define REGVALUE_CLONETYPE "Clone Type" #define REGVALUE_CIDERPRESSLOC "CiderPress Location" +#define REGVALUE_Z80_IN_SLOT5 "Z80 in slot 5" // Preferences #define REGVALUE_PREF_START_DIR "Starting Directory" diff --git a/AppleWin/source/Frame.cpp b/AppleWin/source/Frame.cpp index 2b8754e2..daebd840 100644 --- a/AppleWin/source/Frame.cpp +++ b/AppleWin/source/Frame.cpp @@ -1398,6 +1398,9 @@ void ResetMachineState () { MB_Reset(); SpkrReset(); sg_Mouse.Reset(); +#ifdef SUPPORT_CPM + g_ActiveCPU = CPU_6502; +#endif SoundCore_SetFade(FADE_NONE); } diff --git a/AppleWin/source/Memory.cpp b/AppleWin/source/Memory.cpp index 58fcc5f8..e4de58c3 100644 --- a/AppleWin/source/Memory.cpp +++ b/AppleWin/source/Memory.cpp @@ -29,6 +29,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "StdAfx.h" #pragma hdrstop #include "MouseInterface.h" +#ifdef SUPPORT_CPM +#include "z80\z80emu.h" +#include "z80\z80cpu.h" +#endif #include "..\resource\resource.h" #define MF_80STORE 0x00000001 @@ -1050,6 +1054,9 @@ void MemInitialize() sg_SSC.CommInitialize(pCxRomPeripheral, 2); // $C200 : SSC if (g_Slot4 == CT_MouseInterface) sg_Mouse.Initialize(pCxRomPeripheral, 4); // $C400 : Mouse f/w +#ifdef SUPPORT_CPM + ConfigureSoftcard(pCxRomPeripheral, 5, g_uZ80InSlot5); // $C500 ; Z80 card +#endif DiskLoadRom(pCxRomPeripheral, 6); // $C600 : Disk][ f/w HD_Load_Rom(pCxRomPeripheral, 7); // $C700 : HDD f/w @@ -1102,6 +1109,9 @@ void MemReset () CpuInitialize(); //Sets Caps Lock = false (Pravets 8A/C only) +#ifdef SUPPORT_CPM + Z80_Reset(); +#endif } //=========================================================================== diff --git a/AppleWin/source/Mockingboard.cpp b/AppleWin/source/Mockingboard.cpp index 7d5bc684..b5f87d20 100644 --- a/AppleWin/source/Mockingboard.cpp +++ b/AppleWin/source/Mockingboard.cpp @@ -1308,6 +1308,16 @@ void MB_Initialize() // +#ifdef SUPPORT_CPM + if (g_Slot4 == CT_Mockingboard) + { + const UINT uSlot4 = 4; + RegisterIoHandler(uSlot4, PhasorIO, PhasorIO, MB_Read, MB_Write, NULL, NULL); + + const UINT uSlot5 = 5; + RegisterIoHandler(uSlot5, PhasorIO, PhasorIO, MB_Read, MB_Write, NULL, NULL); + } +#else if (g_Slot4 == CT_Mockingboard) { const UINT uSlot4 = 4; @@ -1316,6 +1326,7 @@ void MB_Initialize() const UINT uSlot5 = 5; RegisterIoHandler(uSlot5, PhasorIO, PhasorIO, MB_Read, MB_Write, NULL, NULL); +#endif } //----------------------------------------------------------------------------- diff --git a/AppleWin/source/PropertySheetPage.cpp b/AppleWin/source/PropertySheetPage.cpp index c88b8182..9f32cb6a 100644 --- a/AppleWin/source/PropertySheetPage.cpp +++ b/AppleWin/source/PropertySheetPage.cpp @@ -111,6 +111,8 @@ UINT g_uMouseInSlot4 = 0; UINT g_uMouseShowCrosshair = 0; UINT g_uMouseRestrictToWindow = 0; +UINT g_uZ80InSlot5 = 0; + // UINT g_uTheFreezesF8Rom = 0; @@ -513,6 +515,7 @@ static void InputDlg_OK(HWND window, UINT afterclose) SAVE(TEXT(REGVALUE_MOUSE_IN_SLOT4),g_uMouseInSlot4); SAVE(TEXT(REGVALUE_MOUSE_CROSSHAIR),g_uMouseShowCrosshair); SAVE(TEXT(REGVALUE_MOUSE_RESTRICT_TO_WINDOW),g_uMouseRestrictToWindow); + SAVE(TEXT(REGVALUE_Z80_IN_SLOT5),g_uZ80InSlot5); // @@ -638,6 +641,33 @@ static BOOL CALLBACK InputDlgProc (HWND window, } break; + case IDC_Z80_IN_SLOT5: + { + UINT uNewState = IsDlgButtonChecked(window, IDC_Z80_IN_SLOT5) ? 1 : 0; + LPCSTR pMsg = uNewState ? + TEXT("The emulator needs to restart as the slot configuration has changed.\n") + TEXT("Microsoft CP/M SoftCard will be placed in slot 5.\n\n") + TEXT("Would you like to restart the emulator now?") + : + TEXT("The emulator needs to restart as the slot configuration has changed.\n") + TEXT("Microsoft CP/M SoftCard will be removed from slot 5\n\n") + TEXT("Would you like to restart the emulator now?"); + if (MessageBox(window, + pMsg, + TEXT("Configuration"), + MB_ICONQUESTION | MB_YESNO | MB_SETFOREGROUND) == IDYES) + { + g_uZ80InSlot5 = uNewState; + afterclose = WM_USER_RESTART; + PropSheet_PressButton(GetParent(window), PSBTN_OK); + } + else + { + CheckDlgButton(window, IDC_Z80_IN_SLOT5, g_uZ80InSlot5 ? BST_CHECKED : BST_UNCHECKED); + } + } + break; + case IDC_PASTE_FROM_CLIPBOARD: ClipboardInitiatePaste(); break; @@ -663,6 +693,7 @@ static BOOL CALLBACK InputDlgProc (HWND window, CheckDlgButton(window, IDC_MOUSE_RESTRICT_TO_WINDOW, g_uMouseRestrictToWindow ? BST_CHECKED : BST_UNCHECKED); EnableWindow(GetDlgItem(window, IDC_MOUSE_CROSSHAIR), g_uMouseInSlot4 ? TRUE : FALSE); EnableWindow(GetDlgItem(window, IDC_MOUSE_RESTRICT_TO_WINDOW), g_uMouseInSlot4 ? TRUE : FALSE); + CheckDlgButton(window, IDC_Z80_IN_SLOT5, g_uZ80InSlot5 ? BST_CHECKED : BST_UNCHECKED); afterclose = 0; break; @@ -796,6 +827,11 @@ static BOOL CALLBACK SoundDlgProc (HWND window, { EnableWindow(GetDlgItem(window, IDC_PHASOR_ENABLE), FALSE); } + + if (g_uZ80InSlot5) + { + EnableWindow(GetDlgItem(window, IDC_MB_ENABLE), FALSE); + } afterclose = 0; break; diff --git a/AppleWin/source/PropertySheetPage.h b/AppleWin/source/PropertySheetPage.h index 48a9663a..27838f99 100644 --- a/AppleWin/source/PropertySheetPage.h +++ b/AppleWin/source/PropertySheetPage.h @@ -16,3 +16,5 @@ extern UINT g_uTheFreezesF8Rom; extern DWORD g_uCloneType; extern HWND hwConfigTab; extern HWND hwAdvancedTab; + +extern UINT g_uZ80InSlot5; diff --git a/AppleWin/source/Structs.h b/AppleWin/source/Structs.h index 57c21c25..e340a22b 100644 --- a/AppleWin/source/Structs.h +++ b/AppleWin/source/Structs.h @@ -148,6 +148,7 @@ enum SS_CARDTYPE CT_GenericHDD, // Hard disk CT_GenericClock, CT_MouseInterface, + CT_Z80, }; ///////////////////////////////////////////////////////////////////////////////// diff --git a/AppleWin/source/Z80/z80codes.h b/AppleWin/source/Z80/z80codes.h new file mode 100644 index 00000000..c047e5ca --- /dev/null +++ b/AppleWin/source/Z80/z80codes.h @@ -0,0 +1,219 @@ +/*** Z80Em: Portable Z80 emulator *******************************************/ +/*** ***/ +/*** Z80Codes.h ***/ +/*** ***/ +/*** This file contains various macros used by the emulation engine ***/ +/*** ***/ +/*** Copyright (C) Marcel de Kogel 1996,1997 ***/ +/*** You are not allowed to distribute this software commercially ***/ +/*** Please, notify me, if you make any changes to this file ***/ +/****************************************************************************/ + +#define M_POP(Rg) \ + R.Rg.D=M_RDSTACK(R.SP.D)+(M_RDSTACK((R.SP.D+1)&65535)<<8); \ + R.SP.W.l+=2 +#define M_PUSH(Rg) \ + R.SP.W.l-=2; \ + M_WRSTACK(R.SP.D,R.Rg.D); \ + M_WRSTACK((R.SP.D+1)&65535,R.Rg.D>>8) +#define M_CALL \ +{ \ + int q; \ + q=M_RDMEM_OPCODE_WORD(); \ + M_PUSH(PC); \ + R.PC.D=q; \ + Z80_ICount-=7; \ +} +#define M_JP \ + R.PC.D=M_RDOP_ARG(R.PC.D)+((M_RDOP_ARG((R.PC.D+1)&65535))<<8) +#define M_JR \ + R.PC.W.l+=((offset)M_RDOP_ARG(R.PC.D))+1; Z80_ICount-=5 +#define M_RET M_POP(PC); Z80_ICount-=6 +#define M_RST(Addr) M_PUSH(PC); R.PC.D=Addr +#define M_SET(Bit,Reg) Reg|=1<>7); \ + R.AF.B.l=(R.AF.B.l&0xEC)|(R.AF.B.h&C_FLAG) + +#define M_RRCA \ + R.AF.B.l=(R.AF.B.l&0xEC)|(R.AF.B.h&0x01); \ + R.AF.B.h=(R.AF.B.h>>1)|(R.AF.B.h<<7) + +#define M_RLA \ +{ \ + int i; \ + i=R.AF.B.l&C_FLAG; \ + R.AF.B.l=(R.AF.B.l&0xEC)|((R.AF.B.h&0x80)>>7); \ + R.AF.B.h=(R.AF.B.h<<1)|i; \ +} + +#define M_RRA \ +{ \ + int i; \ + i=R.AF.B.l&C_FLAG; \ + R.AF.B.l=(R.AF.B.l&0xEC)|(R.AF.B.h&0x01); \ + R.AF.B.h=(R.AF.B.h>>1)|(i<<7); \ +} + +#define M_RLC(Reg) \ +{ \ + int q; \ + q=Reg>>7; \ + Reg=(Reg<<1)|q; \ + R.AF.B.l=ZSPTable[Reg]|q; \ +} +#define M_RRC(Reg) \ +{ \ + int q; \ + q=Reg&1; \ + Reg=(Reg>>1)|(q<<7); \ + R.AF.B.l=ZSPTable[Reg]|q; \ +} +#define M_RL(Reg) \ +{ \ + int q; \ + q=Reg>>7; \ + Reg=(Reg<<1)|(R.AF.B.l&1); \ + R.AF.B.l=ZSPTable[Reg]|q; \ +} +#define M_RR(Reg) \ +{ \ + int q; \ + q=Reg&1; \ + Reg=(Reg>>1)|(R.AF.B.l<<7); \ + R.AF.B.l=ZSPTable[Reg]|q; \ +} +#define M_SLL(Reg) \ +{ \ + int q; \ + q=Reg>>7; \ + Reg=(Reg<<1)|1; \ + R.AF.B.l=ZSPTable[Reg]|q; \ +} +#define M_SLA(Reg) \ +{ \ + int q; \ + q=Reg>>7; \ + Reg<<=1; \ + R.AF.B.l=ZSPTable[Reg]|q; \ +} +#define M_SRL(Reg) \ +{ \ + int q; \ + q=Reg&1; \ + Reg>>=1; \ + R.AF.B.l=ZSPTable[Reg]|q; \ +} +#define M_SRA(Reg) \ +{ \ + int q; \ + q=Reg&1; \ + Reg=(Reg>>1)|(Reg&0x80); \ + R.AF.B.l=ZSPTable[Reg]|q; \ +} + +#define M_INC(Reg) \ + ++Reg; \ + R.AF.B.l=(R.AF.B.l&C_FLAG)|ZSTable[Reg]| \ + ((Reg==0x80)?V_FLAG:0)|((Reg&0x0F)?0:H_FLAG) + +#define M_DEC(Reg) \ + R.AF.B.l=(R.AF.B.l&C_FLAG)|N_FLAG| \ + ((Reg==0x80)?V_FLAG:0)|((Reg&0x0F)?0:H_FLAG); \ + R.AF.B.l|=ZSTable[--Reg] + +#define M_ADD(Reg) \ +{ \ + int q; \ + q=R.AF.B.h+Reg; \ + R.AF.B.l=ZSTable[q&255]|((q&256)>>8)| \ + ((R.AF.B.h^q^Reg)&H_FLAG)| \ + (((Reg^R.AF.B.h^0x80)&(Reg^q)&0x80)>>5); \ + R.AF.B.h=q; \ +} + +#define M_ADC(Reg) \ +{ \ + int q; \ + q=R.AF.B.h+Reg+(R.AF.B.l&1); \ + R.AF.B.l=ZSTable[q&255]|((q&256)>>8)| \ + ((R.AF.B.h^q^Reg)&H_FLAG)| \ + (((Reg^R.AF.B.h^0x80)&(Reg^q)&0x80)>>5); \ + R.AF.B.h=q; \ +} + +#define M_SUB(Reg) \ +{ \ + int q; \ + q=R.AF.B.h-Reg; \ + R.AF.B.l=ZSTable[q&255]|((q&256)>>8)|N_FLAG| \ + ((R.AF.B.h^q^Reg)&H_FLAG)| \ + (((Reg^R.AF.B.h)&(Reg^q)&0x80)>>5); \ + R.AF.B.h=q; \ +} + +#define M_SBC(Reg) \ +{ \ + int q; \ + q=R.AF.B.h-Reg-(R.AF.B.l&1); \ + R.AF.B.l=ZSTable[q&255]|((q&256)>>8)|N_FLAG| \ + ((R.AF.B.h^q^Reg)&H_FLAG)| \ + (((Reg^R.AF.B.h)&(Reg^q)&0x80)>>5); \ + R.AF.B.h=q; \ +} + +#define M_CP(Reg) \ +{ \ + int q; \ + q=R.AF.B.h-Reg; \ + R.AF.B.l=ZSTable[q&255]|((q&256)>>8)|N_FLAG| \ + ((R.AF.B.h^q^Reg)&H_FLAG)| \ + (((Reg^R.AF.B.h)&(Reg^q)&0x80)>>5); \ +} + +#define M_ADDW(Reg1,Reg2) \ +{ \ + int q; \ + q=R.Reg1.D+R.Reg2.D; \ + R.AF.B.l=(R.AF.B.l&(S_FLAG|Z_FLAG|V_FLAG))| \ + (((R.Reg1.D^q^R.Reg2.D)&0x1000)>>8)| \ + ((q>>16)&1); \ + R.Reg1.W.l=q; \ +} + +#define M_ADCW(Reg) \ +{ \ + int q; \ + q=R.HL.D+R.Reg.D+(R.AF.D&1); \ + R.AF.B.l=(((R.HL.D^q^R.Reg.D)&0x1000)>>8)| \ + ((q>>16)&1)| \ + ((q&0x8000)>>8)| \ + ((q&65535)?0:Z_FLAG)| \ + (((R.Reg.D^R.HL.D^0x8000)&(R.Reg.D^q)&0x8000)>>13); \ + R.HL.W.l=q; \ +} + +#define M_SBCW(Reg) \ +{ \ + int q; \ + q=R.HL.D-R.Reg.D-(R.AF.D&1); \ + R.AF.B.l=(((R.HL.D^q^R.Reg.D)&0x1000)>>8)| \ + ((q>>16)&1)| \ + ((q&0x8000)>>8)| \ + ((q&65535)?0:Z_FLAG)| \ + (((R.Reg.D^R.HL.D)&(R.Reg.D^q)&0x8000)>>13)| \ + N_FLAG; \ + R.HL.W.l=q; \ +} + diff --git a/AppleWin/source/Z80/z80cpu.cpp b/AppleWin/source/Z80/z80cpu.cpp new file mode 100644 index 00000000..94325e30 --- /dev/null +++ b/AppleWin/source/Z80/z80cpu.cpp @@ -0,0 +1,2592 @@ +#include "..\stdafx.h" +#include "z80cpu.h" + +int Z80_ICount = 0; + +/* Get next opcode argument and increment program counter */ +INLINE unsigned M_RDMEM_OPCODE (void) +{ + unsigned retval; + retval=M_RDOP_ARG(R.PC.D); + R.PC.W.l++; + return retval; +} + +INLINE unsigned M_RDMEM_WORD (dword A) +{ + int i; + i=M_RDMEM(A); + i+=M_RDMEM(((A)+1)&0xFFFF)<<8; + return i; +} + +INLINE void M_WRMEM_WORD (dword A,word V) +{ + M_WRMEM (A,V&255); + M_WRMEM (((A)+1)&0xFFFF,V>>8); +} + +INLINE unsigned M_RDMEM_OPCODE_WORD (void) +{ + int i; + i=M_RDMEM_OPCODE(); + i+=M_RDMEM_OPCODE()<<8; + return i; +} + +#define M_XIX ((R.IX.D+(offset)M_RDMEM_OPCODE())&0xFFFF) +#define M_XIY ((R.IY.D+(offset)M_RDMEM_OPCODE())&0xFFFF) +#define M_RD_XHL M_RDMEM(R.HL.D) +INLINE unsigned M_RD_XIX(void) +{ + int i; + i=M_XIX; + return M_RDMEM(i); +} +INLINE unsigned M_RD_XIY(void) +{ + int i; + i=M_XIY; + return M_RDMEM(i); +} +INLINE void M_WR_XIX(byte a) +{ + int i; + i=M_XIX; + M_WRMEM(i,a); +} +INLINE void M_WR_XIY(byte a) +{ + int i; + i=M_XIY; + M_WRMEM(i,a); +} + +#ifdef X86_ASM +#include "Z80CDx86.h" +#else +#include "Z80Codes.h" +#endif + +static void adc_a_xhl(void) { byte i=M_RD_XHL; M_ADC(i); } +static void adc_a_xix(void) { byte i=M_RD_XIX(); M_ADC(i); } +static void adc_a_xiy(void) { byte i=M_RD_XIY(); M_ADC(i); } +static void adc_a_a(void) { M_ADC(R.AF.B.h); } +static void adc_a_b(void) { M_ADC(R.BC.B.h); } +static void adc_a_c(void) { M_ADC(R.BC.B.l); } +static void adc_a_d(void) { M_ADC(R.DE.B.h); } +static void adc_a_e(void) { M_ADC(R.DE.B.l); } +static void adc_a_h(void) { M_ADC(R.HL.B.h); } +static void adc_a_l(void) { M_ADC(R.HL.B.l); } +static void adc_a_ixl(void) { M_ADC(R.IX.B.l); } +static void adc_a_ixh(void) { M_ADC(R.IX.B.h); } +static void adc_a_iyl(void) { M_ADC(R.IY.B.l); } +static void adc_a_iyh(void) { M_ADC(R.IY.B.h); } +static void adc_a_byte(void) { byte i=M_RDMEM_OPCODE(); M_ADC(i); } + +static void adc_hl_bc(void) { M_ADCW(BC); } +static void adc_hl_de(void) { M_ADCW(DE); } +static void adc_hl_hl(void) { M_ADCW(HL); } +static void adc_hl_sp(void) { M_ADCW(SP); } + +static void add_a_xhl(void) { byte i=M_RD_XHL; M_ADD(i); } +static void add_a_xix(void) { byte i=M_RD_XIX(); M_ADD(i); } +static void add_a_xiy(void) { byte i=M_RD_XIY(); M_ADD(i); } +static void add_a_a(void) { M_ADD(R.AF.B.h); } +static void add_a_b(void) { M_ADD(R.BC.B.h); } +static void add_a_c(void) { M_ADD(R.BC.B.l); } +static void add_a_d(void) { M_ADD(R.DE.B.h); } +static void add_a_e(void) { M_ADD(R.DE.B.l); } +static void add_a_h(void) { M_ADD(R.HL.B.h); } +static void add_a_l(void) { M_ADD(R.HL.B.l); } +static void add_a_ixl(void) { M_ADD(R.IX.B.l); } +static void add_a_ixh(void) { M_ADD(R.IX.B.h); } +static void add_a_iyl(void) { M_ADD(R.IY.B.l); } +static void add_a_iyh(void) { M_ADD(R.IY.B.h); } +static void add_a_byte(void) { byte i=M_RDMEM_OPCODE(); M_ADD(i); } + +static void add_hl_bc(void) { M_ADDW(HL,BC); } +static void add_hl_de(void) { M_ADDW(HL,DE); } +static void add_hl_hl(void) { M_ADDW(HL,HL); } +static void add_hl_sp(void) { M_ADDW(HL,SP); } +static void add_ix_bc(void) { M_ADDW(IX,BC); } +static void add_ix_de(void) { M_ADDW(IX,DE); } +static void add_ix_ix(void) { M_ADDW(IX,IX); } +static void add_ix_sp(void) { M_ADDW(IX,SP); } +static void add_iy_bc(void) { M_ADDW(IY,BC); } +static void add_iy_de(void) { M_ADDW(IY,DE); } +static void add_iy_iy(void) { M_ADDW(IY,IY); } +static void add_iy_sp(void) { M_ADDW(IY,SP); } + +static void and_xhl(void) { byte i=M_RD_XHL; M_AND(i); } +static void and_xix(void) { byte i=M_RD_XIX(); M_AND(i); } +static void and_xiy(void) { byte i=M_RD_XIY(); M_AND(i); } +static void and_a(void) { R.AF.B.l=ZSPTable[R.AF.B.h]|H_FLAG; } +static void and_b(void) { M_AND(R.BC.B.h); } +static void and_c(void) { M_AND(R.BC.B.l); } +static void and_d(void) { M_AND(R.DE.B.h); } +static void and_e(void) { M_AND(R.DE.B.l); } +static void and_h(void) { M_AND(R.HL.B.h); } +static void and_l(void) { M_AND(R.HL.B.l); } +static void and_ixh(void) { M_AND(R.IX.B.h); } +static void and_ixl(void) { M_AND(R.IX.B.l); } +static void and_iyh(void) { M_AND(R.IY.B.h); } +static void and_iyl(void) { M_AND(R.IY.B.l); } +static void and_byte(void) { byte i=M_RDMEM_OPCODE(); M_AND(i); } + +static void bit_0_xhl(void) { byte i=M_RD_XHL; M_BIT(0,i); } +static void bit_0_xix(void) { byte i=M_RD_XIX(); M_BIT(0,i); } +static void bit_0_xiy(void) { byte i=M_RD_XIY(); M_BIT(0,i); } +static void bit_0_a(void) { M_BIT(0,R.AF.B.h); } +static void bit_0_b(void) { M_BIT(0,R.BC.B.h); } +static void bit_0_c(void) { M_BIT(0,R.BC.B.l); } +static void bit_0_d(void) { M_BIT(0,R.DE.B.h); } +static void bit_0_e(void) { M_BIT(0,R.DE.B.l); } +static void bit_0_h(void) { M_BIT(0,R.HL.B.h); } +static void bit_0_l(void) { M_BIT(0,R.HL.B.l); } + +static void bit_1_xhl(void) { byte i=M_RD_XHL; M_BIT(1,i); } +static void bit_1_xix(void) { byte i=M_RD_XIX(); M_BIT(1,i); } +static void bit_1_xiy(void) { byte i=M_RD_XIY(); M_BIT(1,i); } +static void bit_1_a(void) { M_BIT(1,R.AF.B.h); } +static void bit_1_b(void) { M_BIT(1,R.BC.B.h); } +static void bit_1_c(void) { M_BIT(1,R.BC.B.l); } +static void bit_1_d(void) { M_BIT(1,R.DE.B.h); } +static void bit_1_e(void) { M_BIT(1,R.DE.B.l); } +static void bit_1_h(void) { M_BIT(1,R.HL.B.h); } +static void bit_1_l(void) { M_BIT(1,R.HL.B.l); } + +static void bit_2_xhl(void) { byte i=M_RD_XHL; M_BIT(2,i); } +static void bit_2_xix(void) { byte i=M_RD_XIX(); M_BIT(2,i); } +static void bit_2_xiy(void) { byte i=M_RD_XIY(); M_BIT(2,i); } +static void bit_2_a(void) { M_BIT(2,R.AF.B.h); } +static void bit_2_b(void) { M_BIT(2,R.BC.B.h); } +static void bit_2_c(void) { M_BIT(2,R.BC.B.l); } +static void bit_2_d(void) { M_BIT(2,R.DE.B.h); } +static void bit_2_e(void) { M_BIT(2,R.DE.B.l); } +static void bit_2_h(void) { M_BIT(2,R.HL.B.h); } +static void bit_2_l(void) { M_BIT(2,R.HL.B.l); } + +static void bit_3_xhl(void) { byte i=M_RD_XHL; M_BIT(3,i); } +static void bit_3_xix(void) { byte i=M_RD_XIX(); M_BIT(3,i); } +static void bit_3_xiy(void) { byte i=M_RD_XIY(); M_BIT(3,i); } +static void bit_3_a(void) { M_BIT(3,R.AF.B.h); } +static void bit_3_b(void) { M_BIT(3,R.BC.B.h); } +static void bit_3_c(void) { M_BIT(3,R.BC.B.l); } +static void bit_3_d(void) { M_BIT(3,R.DE.B.h); } +static void bit_3_e(void) { M_BIT(3,R.DE.B.l); } +static void bit_3_h(void) { M_BIT(3,R.HL.B.h); } +static void bit_3_l(void) { M_BIT(3,R.HL.B.l); } + +static void bit_4_xhl(void) { byte i=M_RD_XHL; M_BIT(4,i); } +static void bit_4_xix(void) { byte i=M_RD_XIX(); M_BIT(4,i); } +static void bit_4_xiy(void) { byte i=M_RD_XIY(); M_BIT(4,i); } +static void bit_4_a(void) { M_BIT(4,R.AF.B.h); } +static void bit_4_b(void) { M_BIT(4,R.BC.B.h); } +static void bit_4_c(void) { M_BIT(4,R.BC.B.l); } +static void bit_4_d(void) { M_BIT(4,R.DE.B.h); } +static void bit_4_e(void) { M_BIT(4,R.DE.B.l); } +static void bit_4_h(void) { M_BIT(4,R.HL.B.h); } +static void bit_4_l(void) { M_BIT(4,R.HL.B.l); } + +static void bit_5_xhl(void) { byte i=M_RD_XHL; M_BIT(5,i); } +static void bit_5_xix(void) { byte i=M_RD_XIX(); M_BIT(5,i); } +static void bit_5_xiy(void) { byte i=M_RD_XIY(); M_BIT(5,i); } +static void bit_5_a(void) { M_BIT(5,R.AF.B.h); } +static void bit_5_b(void) { M_BIT(5,R.BC.B.h); } +static void bit_5_c(void) { M_BIT(5,R.BC.B.l); } +static void bit_5_d(void) { M_BIT(5,R.DE.B.h); } +static void bit_5_e(void) { M_BIT(5,R.DE.B.l); } +static void bit_5_h(void) { M_BIT(5,R.HL.B.h); } +static void bit_5_l(void) { M_BIT(5,R.HL.B.l); } + +static void bit_6_xhl(void) { byte i=M_RD_XHL; M_BIT(6,i); } +static void bit_6_xix(void) { byte i=M_RD_XIX(); M_BIT(6,i); } +static void bit_6_xiy(void) { byte i=M_RD_XIY(); M_BIT(6,i); } +static void bit_6_a(void) { M_BIT(6,R.AF.B.h); } +static void bit_6_b(void) { M_BIT(6,R.BC.B.h); } +static void bit_6_c(void) { M_BIT(6,R.BC.B.l); } +static void bit_6_d(void) { M_BIT(6,R.DE.B.h); } +static void bit_6_e(void) { M_BIT(6,R.DE.B.l); } +static void bit_6_h(void) { M_BIT(6,R.HL.B.h); } +static void bit_6_l(void) { M_BIT(6,R.HL.B.l); } + +static void bit_7_xhl(void) { byte i=M_RD_XHL; M_BIT(7,i); } +static void bit_7_xix(void) { byte i=M_RD_XIX(); M_BIT(7,i); } +static void bit_7_xiy(void) { byte i=M_RD_XIY(); M_BIT(7,i); } +static void bit_7_a(void) { M_BIT(7,R.AF.B.h); } +static void bit_7_b(void) { M_BIT(7,R.BC.B.h); } +static void bit_7_c(void) { M_BIT(7,R.BC.B.l); } +static void bit_7_d(void) { M_BIT(7,R.DE.B.h); } +static void bit_7_e(void) { M_BIT(7,R.DE.B.l); } +static void bit_7_h(void) { M_BIT(7,R.HL.B.h); } +static void bit_7_l(void) { M_BIT(7,R.HL.B.l); } + +static void call_c(void) { if (M_C) { M_CALL; } else { M_SKIP_CALL; } } +static void call_m(void) { if (M_M) { M_CALL; } else { M_SKIP_CALL; } } +static void call_nc(void) { if (M_NC) { M_CALL; } else { M_SKIP_CALL; } } +static void call_nz(void) { if (M_NZ) { M_CALL; } else { M_SKIP_CALL; } } +static void call_p(void) { if (M_P) { M_CALL; } else { M_SKIP_CALL; } } +static void call_pe(void) { if (M_PE) { M_CALL; } else { M_SKIP_CALL; } } +static void call_po(void) { if (M_PO) { M_CALL; } else { M_SKIP_CALL; } } +static void call_z(void) { if (M_Z) { M_CALL; } else { M_SKIP_CALL; } } +static void call(void) { M_CALL; } + +static void ccf(void) { R.AF.B.l=((R.AF.B.l&0xED)|((R.AF.B.l&1)<<4))^1; } + +static void cp_xhl(void) { byte i=M_RD_XHL; M_CP(i); } +static void cp_xix(void) { byte i=M_RD_XIX(); M_CP(i); } +static void cp_xiy(void) { byte i=M_RD_XIY(); M_CP(i); } +static void cp_a(void) { M_CP(R.AF.B.h); } +static void cp_b(void) { M_CP(R.BC.B.h); } +static void cp_c(void) { M_CP(R.BC.B.l); } +static void cp_d(void) { M_CP(R.DE.B.h); } +static void cp_e(void) { M_CP(R.DE.B.l); } +static void cp_h(void) { M_CP(R.HL.B.h); } +static void cp_l(void) { M_CP(R.HL.B.l); } +static void cp_ixh(void) { M_CP(R.IX.B.h); } +static void cp_ixl(void) { M_CP(R.IX.B.l); } +static void cp_iyh(void) { M_CP(R.IY.B.h); } +static void cp_iyl(void) { M_CP(R.IY.B.l); } +static void cp_byte(void) { byte i=M_RDMEM_OPCODE(); M_CP(i); } + +static void cpd(void) +{ + byte i,j; + i=M_RDMEM(R.HL.D); + j=R.AF.B.h-i; + --R.HL.W.l; + --R.BC.W.l; + R.AF.B.l=(R.AF.B.l&C_FLAG)|ZSTable[j]| + ((R.AF.B.h^i^j)&H_FLAG)|(R.BC.D? V_FLAG:0)|N_FLAG; +} + +static void cpdr(void) +{ + cpd (); + if (R.BC.D && !(R.AF.B.l&Z_FLAG)) { Z80_ICount += 5; R.PC.W.l-=2; } +} + +static void cpi(void) +{ + byte i,j; + i=M_RDMEM(R.HL.D); + j=R.AF.B.h-i; + ++R.HL.W.l; + --R.BC.W.l; + R.AF.B.l=(R.AF.B.l&C_FLAG)|ZSTable[j]| + ((R.AF.B.h^i^j)&H_FLAG)|(R.BC.D? V_FLAG:0)|N_FLAG; +} + +static void cpir(void) +{ + cpi (); + if (R.BC.D && !(R.AF.B.l&Z_FLAG)) { Z80_ICount += 5; R.PC.W.l-=2; } +} + +static void cpl(void) { R.AF.B.h^=0xFF; R.AF.B.l|=(H_FLAG|N_FLAG); } + +static void daa(void) +{ + int i; + i=R.AF.B.h; + if (R.AF.B.l&C_FLAG) i|=256; + if (R.AF.B.l&H_FLAG) i|=512; + if (R.AF.B.l&N_FLAG) i|=1024; + R.AF.W.l=DAATable[i]; +}; + +static void dec_xhl(void) +{ + byte i; + i=M_RDMEM(R.HL.D); + M_DEC(i); + M_WRMEM(R.HL.D,i); +} +static void dec_xix(void) +{ + byte i; + int j; + j=M_XIX; + i=M_RDMEM(j); + M_DEC(i); + M_WRMEM(j,i); +} +static void dec_xiy(void) +{ + byte i; + int j; + j=M_XIY; + i=M_RDMEM(j); + M_DEC(i); + M_WRMEM(j,i); +} +static void dec_a(void) { M_DEC(R.AF.B.h); } +static void dec_b(void) { M_DEC(R.BC.B.h); } +static void dec_c(void) { M_DEC(R.BC.B.l); } +static void dec_d(void) { M_DEC(R.DE.B.h); } +static void dec_e(void) { M_DEC(R.DE.B.l); } +static void dec_h(void) { M_DEC(R.HL.B.h); } +static void dec_l(void) { M_DEC(R.HL.B.l); } +static void dec_ixh(void) { M_DEC(R.IX.B.h); } +static void dec_ixl(void) { M_DEC(R.IX.B.l); } +static void dec_iyh(void) { M_DEC(R.IY.B.h); } +static void dec_iyl(void) { M_DEC(R.IY.B.l); } + +static void dec_bc(void) { --R.BC.W.l; } +static void dec_de(void) { --R.DE.W.l; } +static void dec_hl(void) { --R.HL.W.l; } +static void dec_ix(void) { --R.IX.W.l; } +static void dec_iy(void) { --R.IY.W.l; } +static void dec_sp(void) { --R.SP.W.l; } + +static void di(void) { R.IFF1=R.IFF2=0; } + +static void djnz(void) { if (--R.BC.B.h) { M_JR; } else { M_SKIP_JR; } } + +static void ex_xsp_hl(void) +{ + int i; + i=M_RDMEM_WORD(R.SP.D); + M_WRMEM_WORD(R.SP.D,R.HL.D); + R.HL.D=i; +} + +static void ex_xsp_ix(void) +{ + int i; + i=M_RDMEM_WORD(R.SP.D); + M_WRMEM_WORD(R.SP.D,R.IX.D); + R.IX.D=i; +} + +static void ex_xsp_iy(void) +{ + int i; + i=M_RDMEM_WORD(R.SP.D); + M_WRMEM_WORD(R.SP.D,R.IY.D); + R.IY.D=i; +} + +static void ex_af_af(void) +{ + int i; + i=R.AF.D; + R.AF.D=R.AF2.D; + R.AF2.D=i; +} + +static void ex_de_hl(void) +{ + int i; + i=R.DE.D; + R.DE.D=R.HL.D; + R.HL.D=i; +} + +static void exx(void) +{ + int i; + i=R.BC.D; + R.BC.D=R.BC2.D; + R.BC2.D=i; + i=R.DE.D; + R.DE.D=R.DE2.D; + R.DE2.D=i; + i=R.HL.D; + R.HL.D=R.HL2.D; + R.HL2.D=i; +} + +static void halt(void) +{ + --R.PC.W.l; + R.HALT=1; + //if (Z80_ICount>0) Z80_ICount=0; +} + +static void im_0(void) { R.IM=0; } +static void im_1(void) { R.IM=1; } +static void im_2(void) { R.IM=2; } + +static void in_a_c(void) { M_IN(R.AF.B.h); } +static void in_b_c(void) { M_IN(R.BC.B.h); } +static void in_c_c(void) { M_IN(R.BC.B.l); } +static void in_d_c(void) { M_IN(R.DE.B.h); } +static void in_e_c(void) { M_IN(R.DE.B.l); } +static void in_h_c(void) { M_IN(R.HL.B.h); } +static void in_l_c(void) { M_IN(R.HL.B.l); } +static void in_0_c(void) { byte i; M_IN(i); } + +static void in_a_byte(void) +{ + byte i=M_RDMEM_OPCODE(); + R.AF.B.h=DoIn(i,R.AF.B.h); +} + +static void inc_xhl(void) +{ + byte i; + i=M_RDMEM(R.HL.D); + M_INC(i); + M_WRMEM(R.HL.D,i); +} +static void inc_xix(void) +{ + byte i; + int j; + j=M_XIX; + i=M_RDMEM(j); + M_INC(i); + M_WRMEM(j,i); +} +static void inc_xiy(void) +{ + byte i; + int j; + j=M_XIY; + i=M_RDMEM(j); + M_INC(i); + M_WRMEM(j,i); +} +static void inc_a(void) { M_INC(R.AF.B.h); } +static void inc_b(void) { M_INC(R.BC.B.h); } +static void inc_c(void) { M_INC(R.BC.B.l); } +static void inc_d(void) { M_INC(R.DE.B.h); } +static void inc_e(void) { M_INC(R.DE.B.l); } +static void inc_h(void) { M_INC(R.HL.B.h); } +static void inc_l(void) { M_INC(R.HL.B.l); } +static void inc_ixh(void) { M_INC(R.IX.B.h); } +static void inc_ixl(void) { M_INC(R.IX.B.l); } +static void inc_iyh(void) { M_INC(R.IY.B.h); } +static void inc_iyl(void) { M_INC(R.IY.B.l); } + +static void inc_bc(void) { ++R.BC.W.l; } +static void inc_de(void) { ++R.DE.W.l; } +static void inc_hl(void) { ++R.HL.W.l; } +static void inc_ix(void) { ++R.IX.W.l; } +static void inc_iy(void) { ++R.IY.W.l; } +static void inc_sp(void) { ++R.SP.W.l; } + +static void ind(void) +{ + --R.BC.B.h; + M_WRMEM(R.HL.D,DoIn(R.BC.B.l,R.BC.B.h)); + --R.HL.W.l; + R.AF.B.l=(R.BC.B.h)? N_FLAG:(N_FLAG|Z_FLAG); +} + +static void indr(void) +{ + ind (); + if (R.BC.B.h) { Z80_ICount += 5; R.PC.W.l-=2; } +} + +static void ini(void) +{ + --R.BC.B.h; + M_WRMEM(R.HL.D,DoIn(R.BC.B.l,R.BC.B.h)); + ++R.HL.W.l; + R.AF.B.l=(R.BC.B.h)? N_FLAG:(N_FLAG|Z_FLAG); +} + +static void inir(void) +{ + ini (); + if (R.BC.B.h) { Z80_ICount+=5; R.PC.W.l-=2; } +} + +static void jp(void) { M_JP; } +static void jp_hl(void) { R.PC.D=R.HL.D; } +static void jp_ix(void) { R.PC.D=R.IX.D; } +static void jp_iy(void) { R.PC.D=R.IY.D; } +static void jp_c(void) { if (M_C) { M_JP; } else { M_SKIP_JP; } } +static void jp_m(void) { if (M_M) { M_JP; } else { M_SKIP_JP; } } +static void jp_nc(void) { if (M_NC) { M_JP; } else { M_SKIP_JP; } } +static void jp_nz(void) { if (M_NZ) { M_JP; } else { M_SKIP_JP; } } +static void jp_p(void) { if (M_P) { M_JP; } else { M_SKIP_JP; } } +static void jp_pe(void) { if (M_PE) { M_JP; } else { M_SKIP_JP; } } +static void jp_po(void) { if (M_PO) { M_JP; } else { M_SKIP_JP; } } +static void jp_z(void) { if (M_Z) { M_JP; } else { M_SKIP_JP; } } + +static void jr(void) { M_JR; } +static void jr_c(void) { if (M_C) { M_JR; } else { M_SKIP_JR; } } +static void jr_nc(void) { if (M_NC) { M_JR; } else { M_SKIP_JR; } } +static void jr_nz(void) { if (M_NZ) { M_JR; } else { M_SKIP_JR; } } +static void jr_z(void) { if (M_Z) { M_JR; } else { M_SKIP_JR; } } + +static void ld_xbc_a(void) { M_WRMEM(R.BC.D,R.AF.B.h); } +static void ld_xde_a(void) { M_WRMEM(R.DE.D,R.AF.B.h); } +static void ld_xhl_a(void) { M_WRMEM(R.HL.D,R.AF.B.h); } +static void ld_xhl_b(void) { M_WRMEM(R.HL.D,R.BC.B.h); } +static void ld_xhl_c(void) { M_WRMEM(R.HL.D,R.BC.B.l); } +static void ld_xhl_d(void) { M_WRMEM(R.HL.D,R.DE.B.h); } +static void ld_xhl_e(void) { M_WRMEM(R.HL.D,R.DE.B.l); } +static void ld_xhl_h(void) { M_WRMEM(R.HL.D,R.HL.B.h); } +static void ld_xhl_l(void) { M_WRMEM(R.HL.D,R.HL.B.l); } +static void ld_xhl_byte(void) { byte i=M_RDMEM_OPCODE(); M_WRMEM(R.HL.D,i); } +static void ld_xix_a(void) { M_WR_XIX(R.AF.B.h); } +static void ld_xix_b(void) { M_WR_XIX(R.BC.B.h); } +static void ld_xix_c(void) { M_WR_XIX(R.BC.B.l); } +static void ld_xix_d(void) { M_WR_XIX(R.DE.B.h); } +static void ld_xix_e(void) { M_WR_XIX(R.DE.B.l); } +static void ld_xix_h(void) { M_WR_XIX(R.HL.B.h); } +static void ld_xix_l(void) { M_WR_XIX(R.HL.B.l); } +static void ld_xix_byte(void) +{ + int i,j; + i=M_XIX; + j=M_RDMEM_OPCODE(); + M_WRMEM(i,j); +} +static void ld_xiy_a(void) { M_WR_XIY(R.AF.B.h); } +static void ld_xiy_b(void) { M_WR_XIY(R.BC.B.h); } +static void ld_xiy_c(void) { M_WR_XIY(R.BC.B.l); } +static void ld_xiy_d(void) { M_WR_XIY(R.DE.B.h); } +static void ld_xiy_e(void) { M_WR_XIY(R.DE.B.l); } +static void ld_xiy_h(void) { M_WR_XIY(R.HL.B.h); } +static void ld_xiy_l(void) { M_WR_XIY(R.HL.B.l); } +static void ld_xiy_byte(void) +{ + int i,j; + i=M_XIY; + j=M_RDMEM_OPCODE(); + M_WRMEM(i,j); +} +static void ld_xbyte_a(void) +{ int i=M_RDMEM_OPCODE_WORD(); M_WRMEM(i,R.AF.B.h); } +static void ld_xword_bc(void) { M_WRMEM_WORD(M_RDMEM_OPCODE_WORD(),R.BC.D); } +static void ld_xword_de(void) { M_WRMEM_WORD(M_RDMEM_OPCODE_WORD(),R.DE.D); } +static void ld_xword_hl(void) { M_WRMEM_WORD(M_RDMEM_OPCODE_WORD(),R.HL.D); } +static void ld_xword_ix(void) { M_WRMEM_WORD(M_RDMEM_OPCODE_WORD(),R.IX.D); } +static void ld_xword_iy(void) { M_WRMEM_WORD(M_RDMEM_OPCODE_WORD(),R.IY.D); } +static void ld_xword_sp(void) { M_WRMEM_WORD(M_RDMEM_OPCODE_WORD(),R.SP.D); } +static void ld_a_xbc(void) { R.AF.B.h=M_RDMEM(R.BC.D); } +static void ld_a_xde(void) { R.AF.B.h=M_RDMEM(R.DE.D); } +static void ld_a_xhl(void) { R.AF.B.h=M_RD_XHL; } +static void ld_a_xix(void) { R.AF.B.h=M_RD_XIX(); } +static void ld_a_xiy(void) { R.AF.B.h=M_RD_XIY(); } +static void ld_a_xbyte(void) +{ int i=M_RDMEM_OPCODE_WORD(); R.AF.B.h=M_RDMEM(i); } + +static void ld_a_byte(void) { R.AF.B.h=M_RDMEM_OPCODE(); } +static void ld_b_byte(void) { R.BC.B.h=M_RDMEM_OPCODE(); } +static void ld_c_byte(void) { R.BC.B.l=M_RDMEM_OPCODE(); } +static void ld_d_byte(void) { R.DE.B.h=M_RDMEM_OPCODE(); } +static void ld_e_byte(void) { R.DE.B.l=M_RDMEM_OPCODE(); } +static void ld_h_byte(void) { R.HL.B.h=M_RDMEM_OPCODE(); } +static void ld_l_byte(void) { R.HL.B.l=M_RDMEM_OPCODE(); } +static void ld_ixh_byte(void) { R.IX.B.h=M_RDMEM_OPCODE(); } +static void ld_ixl_byte(void) { R.IX.B.l=M_RDMEM_OPCODE(); } +static void ld_iyh_byte(void) { R.IY.B.h=M_RDMEM_OPCODE(); } +static void ld_iyl_byte(void) { R.IY.B.l=M_RDMEM_OPCODE(); } + +static void ld_b_xhl(void) { R.BC.B.h=M_RD_XHL; } +static void ld_c_xhl(void) { R.BC.B.l=M_RD_XHL; } +static void ld_d_xhl(void) { R.DE.B.h=M_RD_XHL; } +static void ld_e_xhl(void) { R.DE.B.l=M_RD_XHL; } +static void ld_h_xhl(void) { R.HL.B.h=M_RD_XHL; } +static void ld_l_xhl(void) { R.HL.B.l=M_RD_XHL; } +static void ld_b_xix(void) { R.BC.B.h=M_RD_XIX(); } +static void ld_c_xix(void) { R.BC.B.l=M_RD_XIX(); } +static void ld_d_xix(void) { R.DE.B.h=M_RD_XIX(); } +static void ld_e_xix(void) { R.DE.B.l=M_RD_XIX(); } +static void ld_h_xix(void) { R.HL.B.h=M_RD_XIX(); } +static void ld_l_xix(void) { R.HL.B.l=M_RD_XIX(); } +static void ld_b_xiy(void) { R.BC.B.h=M_RD_XIY(); } +static void ld_c_xiy(void) { R.BC.B.l=M_RD_XIY(); } +static void ld_d_xiy(void) { R.DE.B.h=M_RD_XIY(); } +static void ld_e_xiy(void) { R.DE.B.l=M_RD_XIY(); } +static void ld_h_xiy(void) { R.HL.B.h=M_RD_XIY(); } +static void ld_l_xiy(void) { R.HL.B.l=M_RD_XIY(); } +static void ld_a_a(void) { } +static void ld_a_b(void) { R.AF.B.h=R.BC.B.h; } +static void ld_a_c(void) { R.AF.B.h=R.BC.B.l; } +static void ld_a_d(void) { R.AF.B.h=R.DE.B.h; } +static void ld_a_e(void) { R.AF.B.h=R.DE.B.l; } +static void ld_a_h(void) { R.AF.B.h=R.HL.B.h; } +static void ld_a_l(void) { R.AF.B.h=R.HL.B.l; } +static void ld_a_ixh(void) { R.AF.B.h=R.IX.B.h; } +static void ld_a_ixl(void) { R.AF.B.h=R.IX.B.l; } +static void ld_a_iyh(void) { R.AF.B.h=R.IY.B.h; } +static void ld_a_iyl(void) { R.AF.B.h=R.IY.B.l; } +static void ld_b_b(void) { } +static void ld_b_a(void) { R.BC.B.h=R.AF.B.h; } +static void ld_b_c(void) { R.BC.B.h=R.BC.B.l; } +static void ld_b_d(void) { R.BC.B.h=R.DE.B.h; } +static void ld_b_e(void) { R.BC.B.h=R.DE.B.l; } +static void ld_b_h(void) { R.BC.B.h=R.HL.B.h; } +static void ld_b_l(void) { R.BC.B.h=R.HL.B.l; } +static void ld_b_ixh(void) { R.BC.B.h=R.IX.B.h; } +static void ld_b_ixl(void) { R.BC.B.h=R.IX.B.l; } +static void ld_b_iyh(void) { R.BC.B.h=R.IY.B.h; } +static void ld_b_iyl(void) { R.BC.B.h=R.IY.B.l; } +static void ld_c_c(void) { } +static void ld_c_a(void) { R.BC.B.l=R.AF.B.h; } +static void ld_c_b(void) { R.BC.B.l=R.BC.B.h; } +static void ld_c_d(void) { R.BC.B.l=R.DE.B.h; } +static void ld_c_e(void) { R.BC.B.l=R.DE.B.l; } +static void ld_c_h(void) { R.BC.B.l=R.HL.B.h; } +static void ld_c_l(void) { R.BC.B.l=R.HL.B.l; } +static void ld_c_ixh(void) { R.BC.B.l=R.IX.B.h; } +static void ld_c_ixl(void) { R.BC.B.l=R.IX.B.l; } +static void ld_c_iyh(void) { R.BC.B.l=R.IY.B.h; } +static void ld_c_iyl(void) { R.BC.B.l=R.IY.B.l; } +static void ld_d_d(void) { } +static void ld_d_a(void) { R.DE.B.h=R.AF.B.h; } +static void ld_d_c(void) { R.DE.B.h=R.BC.B.l; } +static void ld_d_b(void) { R.DE.B.h=R.BC.B.h; } +static void ld_d_e(void) { R.DE.B.h=R.DE.B.l; } +static void ld_d_h(void) { R.DE.B.h=R.HL.B.h; } +static void ld_d_l(void) { R.DE.B.h=R.HL.B.l; } +static void ld_d_ixh(void) { R.DE.B.h=R.IX.B.h; } +static void ld_d_ixl(void) { R.DE.B.h=R.IX.B.l; } +static void ld_d_iyh(void) { R.DE.B.h=R.IY.B.h; } +static void ld_d_iyl(void) { R.DE.B.h=R.IY.B.l; } +static void ld_e_e(void) { } +static void ld_e_a(void) { R.DE.B.l=R.AF.B.h; } +static void ld_e_c(void) { R.DE.B.l=R.BC.B.l; } +static void ld_e_b(void) { R.DE.B.l=R.BC.B.h; } +static void ld_e_d(void) { R.DE.B.l=R.DE.B.h; } +static void ld_e_h(void) { R.DE.B.l=R.HL.B.h; } +static void ld_e_l(void) { R.DE.B.l=R.HL.B.l; } +static void ld_e_ixh(void) { R.DE.B.l=R.IX.B.h; } +static void ld_e_ixl(void) { R.DE.B.l=R.IX.B.l; } +static void ld_e_iyh(void) { R.DE.B.l=R.IY.B.h; } +static void ld_e_iyl(void) { R.DE.B.l=R.IY.B.l; } +static void ld_h_h(void) { } +static void ld_h_a(void) { R.HL.B.h=R.AF.B.h; } +static void ld_h_c(void) { R.HL.B.h=R.BC.B.l; } +static void ld_h_b(void) { R.HL.B.h=R.BC.B.h; } +static void ld_h_e(void) { R.HL.B.h=R.DE.B.l; } +static void ld_h_d(void) { R.HL.B.h=R.DE.B.h; } +static void ld_h_l(void) { R.HL.B.h=R.HL.B.l; } +static void ld_l_l(void) { } +static void ld_l_a(void) { R.HL.B.l=R.AF.B.h; } +static void ld_l_c(void) { R.HL.B.l=R.BC.B.l; } +static void ld_l_b(void) { R.HL.B.l=R.BC.B.h; } +static void ld_l_e(void) { R.HL.B.l=R.DE.B.l; } +static void ld_l_d(void) { R.HL.B.l=R.DE.B.h; } +static void ld_l_h(void) { R.HL.B.l=R.HL.B.h; } +static void ld_ixh_a(void) { R.IX.B.h=R.AF.B.h; } +static void ld_ixh_b(void) { R.IX.B.h=R.BC.B.h; } +static void ld_ixh_c(void) { R.IX.B.h=R.BC.B.l; } +static void ld_ixh_d(void) { R.IX.B.h=R.DE.B.h; } +static void ld_ixh_e(void) { R.IX.B.h=R.DE.B.l; } +static void ld_ixh_ixh(void) { } +static void ld_ixh_ixl(void) { R.IX.B.h=R.IX.B.l; } +static void ld_ixl_a(void) { R.IX.B.l=R.AF.B.h; } +static void ld_ixl_b(void) { R.IX.B.l=R.BC.B.h; } +static void ld_ixl_c(void) { R.IX.B.l=R.BC.B.l; } +static void ld_ixl_d(void) { R.IX.B.l=R.DE.B.h; } +static void ld_ixl_e(void) { R.IX.B.l=R.DE.B.l; } +static void ld_ixl_ixh(void) { R.IX.B.l=R.IX.B.h; } +static void ld_ixl_ixl(void) { } +static void ld_iyh_a(void) { R.IY.B.h=R.AF.B.h; } +static void ld_iyh_b(void) { R.IY.B.h=R.BC.B.h; } +static void ld_iyh_c(void) { R.IY.B.h=R.BC.B.l; } +static void ld_iyh_d(void) { R.IY.B.h=R.DE.B.h; } +static void ld_iyh_e(void) { R.IY.B.h=R.DE.B.l; } +static void ld_iyh_iyh(void) { } +static void ld_iyh_iyl(void) { R.IY.B.h=R.IY.B.l; } +static void ld_iyl_a(void) { R.IY.B.l=R.AF.B.h; } +static void ld_iyl_b(void) { R.IY.B.l=R.BC.B.h; } +static void ld_iyl_c(void) { R.IY.B.l=R.BC.B.l; } +static void ld_iyl_d(void) { R.IY.B.l=R.DE.B.h; } +static void ld_iyl_e(void) { R.IY.B.l=R.DE.B.l; } +static void ld_iyl_iyh(void) { R.IY.B.l=R.IY.B.h; } +static void ld_iyl_iyl(void) { } +static void ld_bc_xword(void) { R.BC.D=M_RDMEM_WORD(M_RDMEM_OPCODE_WORD()); } +static void ld_bc_word(void) { R.BC.D=M_RDMEM_OPCODE_WORD(); } +static void ld_de_xword(void) { R.DE.D=M_RDMEM_WORD(M_RDMEM_OPCODE_WORD()); } +static void ld_de_word(void) { R.DE.D=M_RDMEM_OPCODE_WORD(); } +static void ld_hl_xword(void) { R.HL.D=M_RDMEM_WORD(M_RDMEM_OPCODE_WORD()); } +static void ld_hl_word(void) { R.HL.D=M_RDMEM_OPCODE_WORD(); } +static void ld_ix_xword(void) { R.IX.D=M_RDMEM_WORD(M_RDMEM_OPCODE_WORD()); } +static void ld_ix_word(void) { R.IX.D=M_RDMEM_OPCODE_WORD(); } +static void ld_iy_xword(void) { R.IY.D=M_RDMEM_WORD(M_RDMEM_OPCODE_WORD()); } +static void ld_iy_word(void) { R.IY.D=M_RDMEM_OPCODE_WORD(); } +static void ld_sp_xword(void) { R.SP.D=M_RDMEM_WORD(M_RDMEM_OPCODE_WORD()); } +static void ld_sp_word(void) { R.SP.D=M_RDMEM_OPCODE_WORD(); } +static void ld_sp_hl(void) { R.SP.D=R.HL.D; } +static void ld_sp_ix(void) { R.SP.D=R.IX.D; } +static void ld_sp_iy(void) { R.SP.D=R.IY.D; } +static void ld_a_i(void) +{ + R.AF.B.h=R.I; + R.AF.B.l=(R.AF.B.l&C_FLAG)|ZSTable[R.I]|(R.IFF2<<2); +} +static void ld_i_a(void) { R.I=R.AF.B.h; } +static void ld_a_r(void) +{ + R.AF.B.h=(R.R&127)|(R.R2&128); + R.AF.B.l=(R.AF.B.l&C_FLAG)|ZSTable[R.AF.B.h]|(R.IFF2<<2); +} +static void ld_r_a(void) { R.R=R.R2=R.AF.B.h; } + +static void ldd(void) +{ + M_WRMEM(R.DE.D,M_RDMEM(R.HL.D)); + --R.DE.W.l; + --R.HL.W.l; + --R.BC.W.l; + R.AF.B.l=(R.AF.B.l&0xE9)|(R.BC.D? V_FLAG:0); +} +static void lddr(void) +{ + ldd (); + if (R.BC.D) { Z80_ICount+=5; R.PC.W.l-=2; } +} +static void ldi(void) +{ + M_WRMEM(R.DE.D,M_RDMEM(R.HL.D)); + ++R.DE.W.l; + ++R.HL.W.l; + --R.BC.W.l; + R.AF.B.l=(R.AF.B.l&0xE9)|(R.BC.D? V_FLAG:0); +} +static void ldir(void) +{ + ldi (); + if (R.BC.D) { Z80_ICount+=5; R.PC.W.l-=2; } +} + +static void neg(void) +{ + byte i; + i=R.AF.B.h; + R.AF.B.h=0; + M_SUB(i); +} + +static void nop(void) { }; + +static void or_xhl(void) { byte i=M_RD_XHL; M_OR(i); } +static void or_xix(void) { byte i=M_RD_XIX(); M_OR(i); } +static void or_xiy(void) { byte i=M_RD_XIY(); M_OR(i); } +static void or_a(void) { R.AF.B.l=ZSPTable[R.AF.B.h]; } +static void or_b(void) { M_OR(R.BC.B.h); } +static void or_c(void) { M_OR(R.BC.B.l); } +static void or_d(void) { M_OR(R.DE.B.h); } +static void or_e(void) { M_OR(R.DE.B.l); } +static void or_h(void) { M_OR(R.HL.B.h); } +static void or_l(void) { M_OR(R.HL.B.l); } +static void or_ixh(void) { M_OR(R.IX.B.h); } +static void or_ixl(void) { M_OR(R.IX.B.l); } +static void or_iyh(void) { M_OR(R.IY.B.h); } +static void or_iyl(void) { M_OR(R.IY.B.l); } +static void or_byte(void) { byte i=M_RDMEM_OPCODE(); M_OR(i); } + +static void outd(void) +{ + --R.BC.B.h; + DoOut (R.BC.B.l,R.BC.B.h,M_RDMEM(R.HL.D)); + --R.HL.W.l; + R.AF.B.l=(R.BC.B.h)? N_FLAG:(Z_FLAG|N_FLAG); +} +static void otdr(void) +{ + outd (); + if (R.BC.B.h) { Z80_ICount+=5; R.PC.W.l-=2; } +} +static void outi(void) +{ + --R.BC.B.h; + DoOut (R.BC.B.l,R.BC.B.h,M_RDMEM(R.HL.D)); + ++R.HL.W.l; + R.AF.B.l=(R.BC.B.h)? N_FLAG:(Z_FLAG|N_FLAG); +} +static void otir(void) +{ + outi (); + if (R.BC.B.h) { Z80_ICount+=5; R.PC.W.l-=2; } +} + +static void out_c_a(void) { DoOut(R.BC.B.l,R.BC.B.h,R.AF.B.h); } +static void out_c_b(void) { DoOut(R.BC.B.l,R.BC.B.h,R.BC.B.h); } +static void out_c_c(void) { DoOut(R.BC.B.l,R.BC.B.h,R.BC.B.l); } +static void out_c_d(void) { DoOut(R.BC.B.l,R.BC.B.h,R.DE.B.h); } +static void out_c_e(void) { DoOut(R.BC.B.l,R.BC.B.h,R.DE.B.l); } +static void out_c_h(void) { DoOut(R.BC.B.l,R.BC.B.h,R.HL.B.h); } +static void out_c_l(void) { DoOut(R.BC.B.l,R.BC.B.h,R.HL.B.l); } +static void out_c_0(void) { DoOut(R.BC.B.l,R.BC.B.h,0); } +static void out_byte_a(void) +{ + byte i=M_RDMEM_OPCODE(); + DoOut(i,R.AF.B.h,R.AF.B.h); +} + +static void pop_af(void) { M_POP(AF); } +static void pop_bc(void) { M_POP(BC); } +static void pop_de(void) { M_POP(DE); } +static void pop_hl(void) { M_POP(HL); } +static void pop_ix(void) { M_POP(IX); } +static void pop_iy(void) { M_POP(IY); } + +static void push_af(void) { M_PUSH(AF); } +static void push_bc(void) { M_PUSH(BC); } +static void push_de(void) { M_PUSH(DE); } +static void push_hl(void) { M_PUSH(HL); } +static void push_ix(void) { M_PUSH(IX); } +static void push_iy(void) { M_PUSH(IY); } + +static void res_0_xhl(void) +{ + byte i; + i=M_RDMEM(R.HL.D); + M_RES(0,i); + M_WRMEM(R.HL.D,i); +}; +static void res_0_xix(void) +{ + byte i; + int j; + j=M_XIX; + i=M_RDMEM(j); + M_RES(0,i); + M_WRMEM(j,i); +}; +static void res_0_xiy(void) +{ + byte i; + int j; + j=M_XIY; + i=M_RDMEM(j); + M_RES(0,i); + M_WRMEM(j,i); +}; +static void res_0_a(void) { M_RES(0,R.AF.B.h); }; +static void res_0_b(void) { M_RES(0,R.BC.B.h); }; +static void res_0_c(void) { M_RES(0,R.BC.B.l); }; +static void res_0_d(void) { M_RES(0,R.DE.B.h); }; +static void res_0_e(void) { M_RES(0,R.DE.B.l); }; +static void res_0_h(void) { M_RES(0,R.HL.B.h); }; +static void res_0_l(void) { M_RES(0,R.HL.B.l); }; + +static void res_1_xhl(void) +{ + byte i; + i=M_RDMEM(R.HL.D); + M_RES(1,i); + M_WRMEM(R.HL.D,i); +}; +static void res_1_xix(void) +{ + byte i; + int j; + j=M_XIX; + i=M_RDMEM(j); + M_RES(1,i); + M_WRMEM(j,i); +}; +static void res_1_xiy(void) +{ + byte i; + int j; + j=M_XIY; + i=M_RDMEM(j); + M_RES(1,i); + M_WRMEM(j,i); +}; +static void res_1_a(void) { M_RES(1,R.AF.B.h); }; +static void res_1_b(void) { M_RES(1,R.BC.B.h); }; +static void res_1_c(void) { M_RES(1,R.BC.B.l); }; +static void res_1_d(void) { M_RES(1,R.DE.B.h); }; +static void res_1_e(void) { M_RES(1,R.DE.B.l); }; +static void res_1_h(void) { M_RES(1,R.HL.B.h); }; +static void res_1_l(void) { M_RES(1,R.HL.B.l); }; + +static void res_2_xhl(void) +{ + byte i; + i=M_RDMEM(R.HL.D); + M_RES(2,i); + M_WRMEM(R.HL.D,i); +}; +static void res_2_xix(void) +{ + byte i; + int j; + j=M_XIX; + i=M_RDMEM(j); + M_RES(2,i); + M_WRMEM(j,i); +}; +static void res_2_xiy(void) +{ + byte i; + int j; + j=M_XIY; + i=M_RDMEM(j); + M_RES(2,i); + M_WRMEM(j,i); +}; +static void res_2_a(void) { M_RES(2,R.AF.B.h); }; +static void res_2_b(void) { M_RES(2,R.BC.B.h); }; +static void res_2_c(void) { M_RES(2,R.BC.B.l); }; +static void res_2_d(void) { M_RES(2,R.DE.B.h); }; +static void res_2_e(void) { M_RES(2,R.DE.B.l); }; +static void res_2_h(void) { M_RES(2,R.HL.B.h); }; +static void res_2_l(void) { M_RES(2,R.HL.B.l); }; + +static void res_3_xhl(void) +{ + byte i; + i=M_RDMEM(R.HL.D); + M_RES(3,i); + M_WRMEM(R.HL.D,i); +}; +static void res_3_xix(void) +{ + byte i; + int j; + j=M_XIX; + i=M_RDMEM(j); + M_RES(3,i); + M_WRMEM(j,i); +}; +static void res_3_xiy(void) +{ + byte i; + int j; + j=M_XIY; + i=M_RDMEM(j); + M_RES(3,i); + M_WRMEM(j,i); +}; +static void res_3_a(void) { M_RES(3,R.AF.B.h); }; +static void res_3_b(void) { M_RES(3,R.BC.B.h); }; +static void res_3_c(void) { M_RES(3,R.BC.B.l); }; +static void res_3_d(void) { M_RES(3,R.DE.B.h); }; +static void res_3_e(void) { M_RES(3,R.DE.B.l); }; +static void res_3_h(void) { M_RES(3,R.HL.B.h); }; +static void res_3_l(void) { M_RES(3,R.HL.B.l); }; + +static void res_4_xhl(void) +{ + byte i; + i=M_RDMEM(R.HL.D); + M_RES(4,i); + M_WRMEM(R.HL.D,i); +}; +static void res_4_xix(void) +{ + byte i; + int j; + j=M_XIX; + i=M_RDMEM(j); + M_RES(4,i); + M_WRMEM(j,i); +}; +static void res_4_xiy(void) +{ + byte i; + int j; + j=M_XIY; + i=M_RDMEM(j); + M_RES(4,i); + M_WRMEM(j,i); +}; +static void res_4_a(void) { M_RES(4,R.AF.B.h); }; +static void res_4_b(void) { M_RES(4,R.BC.B.h); }; +static void res_4_c(void) { M_RES(4,R.BC.B.l); }; +static void res_4_d(void) { M_RES(4,R.DE.B.h); }; +static void res_4_e(void) { M_RES(4,R.DE.B.l); }; +static void res_4_h(void) { M_RES(4,R.HL.B.h); }; +static void res_4_l(void) { M_RES(4,R.HL.B.l); }; + +static void res_5_xhl(void) +{ + byte i; + i=M_RDMEM(R.HL.D); + M_RES(5,i); + M_WRMEM(R.HL.D,i); +}; +static void res_5_xix(void) +{ + byte i; + int j; + j=M_XIX; + i=M_RDMEM(j); + M_RES(5,i); + M_WRMEM(j,i); +}; +static void res_5_xiy(void) +{ + byte i; + int j; + j=M_XIY; + i=M_RDMEM(j); + M_RES(5,i); + M_WRMEM(j,i); +}; +static void res_5_a(void) { M_RES(5,R.AF.B.h); }; +static void res_5_b(void) { M_RES(5,R.BC.B.h); }; +static void res_5_c(void) { M_RES(5,R.BC.B.l); }; +static void res_5_d(void) { M_RES(5,R.DE.B.h); }; +static void res_5_e(void) { M_RES(5,R.DE.B.l); }; +static void res_5_h(void) { M_RES(5,R.HL.B.h); }; +static void res_5_l(void) { M_RES(5,R.HL.B.l); }; + +static void res_6_xhl(void) +{ + byte i; + i=M_RDMEM(R.HL.D); + M_RES(6,i); + M_WRMEM(R.HL.D,i); +}; +static void res_6_xix(void) +{ + byte i; + int j; + j=M_XIX; + i=M_RDMEM(j); + M_RES(6,i); + M_WRMEM(j,i); +}; +static void res_6_xiy(void) +{ + byte i; + int j; + j=M_XIY; + i=M_RDMEM(j); + M_RES(6,i); + M_WRMEM(j,i); +}; +static void res_6_a(void) { M_RES(6,R.AF.B.h); }; +static void res_6_b(void) { M_RES(6,R.BC.B.h); }; +static void res_6_c(void) { M_RES(6,R.BC.B.l); }; +static void res_6_d(void) { M_RES(6,R.DE.B.h); }; +static void res_6_e(void) { M_RES(6,R.DE.B.l); }; +static void res_6_h(void) { M_RES(6,R.HL.B.h); }; +static void res_6_l(void) { M_RES(6,R.HL.B.l); }; + +static void res_7_xhl(void) +{ + byte i; + i=M_RDMEM(R.HL.D); + M_RES(7,i); + M_WRMEM(R.HL.D,i); +}; +static void res_7_xix(void) +{ + byte i; + int j; + j=M_XIX; + i=M_RDMEM(j); + M_RES(7,i); + M_WRMEM(j,i); +}; +static void res_7_xiy(void) +{ + byte i; + int j; + j=M_XIY; + i=M_RDMEM(j); + M_RES(7,i); + M_WRMEM(j,i); +}; +static void res_7_a(void) { M_RES(7,R.AF.B.h); }; +static void res_7_b(void) { M_RES(7,R.BC.B.h); }; +static void res_7_c(void) { M_RES(7,R.BC.B.l); }; +static void res_7_d(void) { M_RES(7,R.DE.B.h); }; +static void res_7_e(void) { M_RES(7,R.DE.B.l); }; +static void res_7_h(void) { M_RES(7,R.HL.B.h); }; +static void res_7_l(void) { M_RES(7,R.HL.B.l); }; + +static void ret(void) { M_RET; } +static void ret_c(void) { if (M_C) { M_RET; } else { M_SKIP_RET; } } +static void ret_m(void) { if (M_M) { M_RET; } else { M_SKIP_RET; } } +static void ret_nc(void) { if (M_NC) { M_RET; } else { M_SKIP_RET; } } +static void ret_nz(void) { if (M_NZ) { M_RET; } else { M_SKIP_RET; } } +static void ret_p(void) { if (M_P) { M_RET; } else { M_SKIP_RET; } } +static void ret_pe(void) { if (M_PE) { M_RET; } else { M_SKIP_RET; } } +static void ret_po(void) { if (M_PO) { M_RET; } else { M_SKIP_RET; } } +static void ret_z(void) { if (M_Z) { M_RET; } else { M_SKIP_RET; } } + +static void reti(void) { Z80_Reti(); M_RET; } +static void retn(void) { R.IFF1=R.IFF2; Z80_Retn(); M_RET; } + +static void rl_xhl(void) +{ + byte i; + i=M_RDMEM(R.HL.D); + M_RL(i); + M_WRMEM(R.HL.D,i); +} +static void rl_xix(void) +{ + byte i; + int j; + j=M_XIX; + i=M_RDMEM(j); + M_RL(i); + M_WRMEM(j,i); +} +static void rl_xiy(void) +{ + byte i; + int j; + j=M_XIY; + i=M_RDMEM(j); + M_RL(i); + M_WRMEM(j,i); +} +static void rl_a(void) { M_RL(R.AF.B.h); } +static void rl_b(void) { M_RL(R.BC.B.h); } +static void rl_c(void) { M_RL(R.BC.B.l); } +static void rl_d(void) { M_RL(R.DE.B.h); } +static void rl_e(void) { M_RL(R.DE.B.l); } +static void rl_h(void) { M_RL(R.HL.B.h); } +static void rl_l(void) { M_RL(R.HL.B.l); } +static void rla(void) { M_RLA; } + +static void rlc_xhl(void) +{ + byte i; + i=M_RDMEM(R.HL.D); + M_RLC(i); + M_WRMEM(R.HL.D,i); +} +static void rlc_xix(void) +{ + byte i; + int j; + j=M_XIX; + i=M_RDMEM(j); + M_RLC(i); + M_WRMEM(j,i); +} +static void rlc_xiy(void) +{ + byte i; + int j; + j=M_XIY; + i=M_RDMEM(j); + M_RLC(i); + M_WRMEM(j,i); +} +static void rlc_a(void) { M_RLC(R.AF.B.h); } +static void rlc_b(void) { M_RLC(R.BC.B.h); } +static void rlc_c(void) { M_RLC(R.BC.B.l); } +static void rlc_d(void) { M_RLC(R.DE.B.h); } +static void rlc_e(void) { M_RLC(R.DE.B.l); } +static void rlc_h(void) { M_RLC(R.HL.B.h); } +static void rlc_l(void) { M_RLC(R.HL.B.l); } +static void rlca(void) { M_RLCA; } + +static void rld(void) +{ + byte i; + i=M_RDMEM(R.HL.D); + M_WRMEM(R.HL.D,(i<<4)|(R.AF.B.h&0x0F)); + R.AF.B.h=(R.AF.B.h&0xF0)|(i>>4); + R.AF.B.l=(R.AF.B.l&C_FLAG)|ZSPTable[R.AF.B.h]; +} + +static void rr_xhl(void) +{ + byte i; + i=M_RDMEM(R.HL.D); + M_RR(i); + M_WRMEM(R.HL.D,i); +} +static void rr_xix(void) +{ + byte i; + int j; + j=M_XIX; + i=M_RDMEM(j); + M_RR(i); + M_WRMEM(j,i); +} +static void rr_xiy(void) +{ + byte i; + int j; + j=M_XIY; + i=M_RDMEM(j); + M_RR(i); + M_WRMEM(j,i); +} +static void rr_a(void) { M_RR(R.AF.B.h); } +static void rr_b(void) { M_RR(R.BC.B.h); } +static void rr_c(void) { M_RR(R.BC.B.l); } +static void rr_d(void) { M_RR(R.DE.B.h); } +static void rr_e(void) { M_RR(R.DE.B.l); } +static void rr_h(void) { M_RR(R.HL.B.h); } +static void rr_l(void) { M_RR(R.HL.B.l); } +static void rra(void) { M_RRA; } + +static void rrc_xhl(void) +{ + byte i; + i=M_RDMEM(R.HL.D); + M_RRC(i); + M_WRMEM(R.HL.D,i); +} +static void rrc_xix(void) +{ + byte i; + int j; + j=M_XIX; + i=M_RDMEM(j); + M_RRC(i); + M_WRMEM(j,i); +} +static void rrc_xiy(void) +{ + byte i; + int j; + j=M_XIY; + i=M_RDMEM(j); + M_RRC(i); + M_WRMEM(j,i); +} +static void rrc_a(void) { M_RRC(R.AF.B.h); } +static void rrc_b(void) { M_RRC(R.BC.B.h); } +static void rrc_c(void) { M_RRC(R.BC.B.l); } +static void rrc_d(void) { M_RRC(R.DE.B.h); } +static void rrc_e(void) { M_RRC(R.DE.B.l); } +static void rrc_h(void) { M_RRC(R.HL.B.h); } +static void rrc_l(void) { M_RRC(R.HL.B.l); } +static void rrca(void) { M_RRCA; } + +static void rrd(void) +{ + byte i; + i=M_RDMEM(R.HL.D); + M_WRMEM(R.HL.D,(i>>4)|(R.AF.B.h<<4)); + R.AF.B.h=(R.AF.B.h&0xF0)|(i&0x0F); + R.AF.B.l=(R.AF.B.l&C_FLAG)|ZSPTable[R.AF.B.h]; +} + +static void rst_00(void) { M_RST(0x00); } +static void rst_08(void) { M_RST(0x08); } +static void rst_10(void) { M_RST(0x10); } +static void rst_18(void) { M_RST(0x18); } +static void rst_20(void) { M_RST(0x20); } +static void rst_28(void) { M_RST(0x28); } +static void rst_30(void) { M_RST(0x30); } +static void rst_38(void) { M_RST(0x38); } + +static void sbc_a_byte(void) { byte i=M_RDMEM_OPCODE(); M_SBC(i); } +static void sbc_a_xhl(void) { byte i=M_RD_XHL; M_SBC(i); } +static void sbc_a_xix(void) { byte i=M_RD_XIX(); M_SBC(i); } +static void sbc_a_xiy(void) { byte i=M_RD_XIY(); M_SBC(i); } +static void sbc_a_a(void) { M_SBC(R.AF.B.h); } +static void sbc_a_b(void) { M_SBC(R.BC.B.h); } +static void sbc_a_c(void) { M_SBC(R.BC.B.l); } +static void sbc_a_d(void) { M_SBC(R.DE.B.h); } +static void sbc_a_e(void) { M_SBC(R.DE.B.l); } +static void sbc_a_h(void) { M_SBC(R.HL.B.h); } +static void sbc_a_l(void) { M_SBC(R.HL.B.l); } +static void sbc_a_ixh(void) { M_SBC(R.IX.B.h); } +static void sbc_a_ixl(void) { M_SBC(R.IX.B.l); } +static void sbc_a_iyh(void) { M_SBC(R.IY.B.h); } +static void sbc_a_iyl(void) { M_SBC(R.IY.B.l); } + +static void sbc_hl_bc(void) { M_SBCW(BC); } +static void sbc_hl_de(void) { M_SBCW(DE); } +static void sbc_hl_hl(void) { M_SBCW(HL); } +static void sbc_hl_sp(void) { M_SBCW(SP); } + +static void scf(void) { R.AF.B.l=(R.AF.B.l&0xEC)|C_FLAG; } + +static void set_0_xhl(void) +{ + byte i; + i=M_RDMEM(R.HL.D); + M_SET(0,i); + M_WRMEM(R.HL.D,i); +}; +static void set_0_xix(void) +{ + byte i; + int j; + j=M_XIX; + i=M_RDMEM(j); + M_SET(0,i); + M_WRMEM(j,i); +}; +static void set_0_xiy(void) +{ + byte i; + int j; + j=M_XIY; + i=M_RDMEM(j); + M_SET(0,i); + M_WRMEM(j,i); +}; +static void set_0_a(void) { M_SET(0,R.AF.B.h); }; +static void set_0_b(void) { M_SET(0,R.BC.B.h); }; +static void set_0_c(void) { M_SET(0,R.BC.B.l); }; +static void set_0_d(void) { M_SET(0,R.DE.B.h); }; +static void set_0_e(void) { M_SET(0,R.DE.B.l); }; +static void set_0_h(void) { M_SET(0,R.HL.B.h); }; +static void set_0_l(void) { M_SET(0,R.HL.B.l); }; + +static void set_1_xhl(void) +{ + byte i; + i=M_RDMEM(R.HL.D); + M_SET(1,i); + M_WRMEM(R.HL.D,i); +}; +static void set_1_xix(void) +{ + byte i; + int j; + j=M_XIX; + i=M_RDMEM(j); + M_SET(1,i); + M_WRMEM(j,i); +}; +static void set_1_xiy(void) +{ + byte i; + int j; + j=M_XIY; + i=M_RDMEM(j); + M_SET(1,i); + M_WRMEM(j,i); +}; +static void set_1_a(void) { M_SET(1,R.AF.B.h); }; +static void set_1_b(void) { M_SET(1,R.BC.B.h); }; +static void set_1_c(void) { M_SET(1,R.BC.B.l); }; +static void set_1_d(void) { M_SET(1,R.DE.B.h); }; +static void set_1_e(void) { M_SET(1,R.DE.B.l); }; +static void set_1_h(void) { M_SET(1,R.HL.B.h); }; +static void set_1_l(void) { M_SET(1,R.HL.B.l); }; + +static void set_2_xhl(void) +{ + byte i; + i=M_RDMEM(R.HL.D); + M_SET(2,i); + M_WRMEM(R.HL.D,i); +}; +static void set_2_xix(void) +{ + byte i; + int j; + j=M_XIX; + i=M_RDMEM(j); + M_SET(2,i); + M_WRMEM(j,i); +}; +static void set_2_xiy(void) +{ + byte i; + int j; + j=M_XIY; + i=M_RDMEM(j); + M_SET(2,i); + M_WRMEM(j,i); +}; +static void set_2_a(void) { M_SET(2,R.AF.B.h); }; +static void set_2_b(void) { M_SET(2,R.BC.B.h); }; +static void set_2_c(void) { M_SET(2,R.BC.B.l); }; +static void set_2_d(void) { M_SET(2,R.DE.B.h); }; +static void set_2_e(void) { M_SET(2,R.DE.B.l); }; +static void set_2_h(void) { M_SET(2,R.HL.B.h); }; +static void set_2_l(void) { M_SET(2,R.HL.B.l); }; + +static void set_3_xhl(void) +{ + byte i; + i=M_RDMEM(R.HL.D); + M_SET(3,i); + M_WRMEM(R.HL.D,i); +}; +static void set_3_xix(void) +{ + byte i; + int j; + j=M_XIX; + i=M_RDMEM(j); + M_SET(3,i); + M_WRMEM(j,i); +}; +static void set_3_xiy(void) +{ + byte i; + int j; + j=M_XIY; + i=M_RDMEM(j); + M_SET(3,i); + M_WRMEM(j,i); +}; +static void set_3_a(void) { M_SET(3,R.AF.B.h); }; +static void set_3_b(void) { M_SET(3,R.BC.B.h); }; +static void set_3_c(void) { M_SET(3,R.BC.B.l); }; +static void set_3_d(void) { M_SET(3,R.DE.B.h); }; +static void set_3_e(void) { M_SET(3,R.DE.B.l); }; +static void set_3_h(void) { M_SET(3,R.HL.B.h); }; +static void set_3_l(void) { M_SET(3,R.HL.B.l); }; + +static void set_4_xhl(void) +{ + byte i; + i=M_RDMEM(R.HL.D); + M_SET(4,i); + M_WRMEM(R.HL.D,i); +}; +static void set_4_xix(void) +{ + byte i; + int j; + j=M_XIX; + i=M_RDMEM(j); + M_SET(4,i); + M_WRMEM(j,i); +}; +static void set_4_xiy(void) +{ + byte i; + int j; + j=M_XIY; + i=M_RDMEM(j); + M_SET(4,i); + M_WRMEM(j,i); +}; +static void set_4_a(void) { M_SET(4,R.AF.B.h); }; +static void set_4_b(void) { M_SET(4,R.BC.B.h); }; +static void set_4_c(void) { M_SET(4,R.BC.B.l); }; +static void set_4_d(void) { M_SET(4,R.DE.B.h); }; +static void set_4_e(void) { M_SET(4,R.DE.B.l); }; +static void set_4_h(void) { M_SET(4,R.HL.B.h); }; +static void set_4_l(void) { M_SET(4,R.HL.B.l); }; + +static void set_5_xhl(void) +{ + byte i; + i=M_RDMEM(R.HL.D); + M_SET(5,i); + M_WRMEM(R.HL.D,i); +}; +static void set_5_xix(void) +{ + byte i; + int j; + j=M_XIX; + i=M_RDMEM(j); + M_SET(5,i); + M_WRMEM(j,i); +}; +static void set_5_xiy(void) +{ + byte i; + int j; + j=M_XIY; + i=M_RDMEM(j); + M_SET(5,i); + M_WRMEM(j,i); +}; +static void set_5_a(void) { M_SET(5,R.AF.B.h); }; +static void set_5_b(void) { M_SET(5,R.BC.B.h); }; +static void set_5_c(void) { M_SET(5,R.BC.B.l); }; +static void set_5_d(void) { M_SET(5,R.DE.B.h); }; +static void set_5_e(void) { M_SET(5,R.DE.B.l); }; +static void set_5_h(void) { M_SET(5,R.HL.B.h); }; +static void set_5_l(void) { M_SET(5,R.HL.B.l); }; + +static void set_6_xhl(void) +{ + byte i; + i=M_RDMEM(R.HL.D); + M_SET(6,i); + M_WRMEM(R.HL.D,i); +}; +static void set_6_xix(void) +{ + byte i; + int j; + j=M_XIX; + i=M_RDMEM(j); + M_SET(6,i); + M_WRMEM(j,i); +}; +static void set_6_xiy(void) +{ + byte i; + int j; + j=M_XIY; + i=M_RDMEM(j); + M_SET(6,i); + M_WRMEM(j,i); +}; +static void set_6_a(void) { M_SET(6,R.AF.B.h); }; +static void set_6_b(void) { M_SET(6,R.BC.B.h); }; +static void set_6_c(void) { M_SET(6,R.BC.B.l); }; +static void set_6_d(void) { M_SET(6,R.DE.B.h); }; +static void set_6_e(void) { M_SET(6,R.DE.B.l); }; +static void set_6_h(void) { M_SET(6,R.HL.B.h); }; +static void set_6_l(void) { M_SET(6,R.HL.B.l); }; + +static void set_7_xhl(void) +{ + byte i; + i=M_RDMEM(R.HL.D); + M_SET(7,i); + M_WRMEM(R.HL.D,i); +}; +static void set_7_xix(void) +{ + byte i; + int j; + j=M_XIX; + i=M_RDMEM(j); + M_SET(7,i); + M_WRMEM(j,i); +}; +static void set_7_xiy(void) +{ + byte i; + int j; + j=M_XIY; + i=M_RDMEM(j); + M_SET(7,i); + M_WRMEM(j,i); +}; +static void set_7_a(void) { M_SET(7,R.AF.B.h); }; +static void set_7_b(void) { M_SET(7,R.BC.B.h); }; +static void set_7_c(void) { M_SET(7,R.BC.B.l); }; +static void set_7_d(void) { M_SET(7,R.DE.B.h); }; +static void set_7_e(void) { M_SET(7,R.DE.B.l); }; +static void set_7_h(void) { M_SET(7,R.HL.B.h); }; +static void set_7_l(void) { M_SET(7,R.HL.B.l); }; + +static void sla_xhl(void) +{ + byte i; + i=M_RDMEM(R.HL.D); + M_SLA(i); + M_WRMEM(R.HL.D,i); +} +static void sla_xix(void) +{ + byte i; + int j; + j=M_XIX; + i=M_RDMEM(j); + M_SLA(i); + M_WRMEM(j,i); +} +static void sla_xiy(void) +{ + byte i; + int j; + j=M_XIY; + i=M_RDMEM(j); + M_SLA(i); + M_WRMEM(j,i); +} +static void sla_a(void) { M_SLA(R.AF.B.h); } +static void sla_b(void) { M_SLA(R.BC.B.h); } +static void sla_c(void) { M_SLA(R.BC.B.l); } +static void sla_d(void) { M_SLA(R.DE.B.h); } +static void sla_e(void) { M_SLA(R.DE.B.l); } +static void sla_h(void) { M_SLA(R.HL.B.h); } +static void sla_l(void) { M_SLA(R.HL.B.l); } + +static void sll_xhl(void) +{ + byte i; + i=M_RDMEM(R.HL.D); + M_SLL(i); + M_WRMEM(R.HL.D,i); +} +static void sll_xix(void) +{ + byte i; + int j; + j=M_XIX; + i=M_RDMEM(j); + M_SLL(i); + M_WRMEM(j,i); +} +static void sll_xiy(void) +{ + byte i; + int j; + j=M_XIY; + i=M_RDMEM(j); + M_SLL(i); + M_WRMEM(j,i); +} +static void sll_a(void) { M_SLL(R.AF.B.h); } +static void sll_b(void) { M_SLL(R.BC.B.h); } +static void sll_c(void) { M_SLL(R.BC.B.l); } +static void sll_d(void) { M_SLL(R.DE.B.h); } +static void sll_e(void) { M_SLL(R.DE.B.l); } +static void sll_h(void) { M_SLL(R.HL.B.h); } +static void sll_l(void) { M_SLL(R.HL.B.l); } + +static void sra_xhl(void) +{ + byte i; + i=M_RDMEM(R.HL.D); + M_SRA(i); + M_WRMEM(R.HL.D,i); +} +static void sra_xix(void) +{ + byte i; + int j; + j=M_XIX; + i=M_RDMEM(j); + M_SRA(i); + M_WRMEM(j,i); +} +static void sra_xiy(void) +{ + byte i; + int j; + j=M_XIY; + i=M_RDMEM(j); + M_SRA(i); + M_WRMEM(j,i); +} +static void sra_a(void) { M_SRA(R.AF.B.h); } +static void sra_b(void) { M_SRA(R.BC.B.h); } +static void sra_c(void) { M_SRA(R.BC.B.l); } +static void sra_d(void) { M_SRA(R.DE.B.h); } +static void sra_e(void) { M_SRA(R.DE.B.l); } +static void sra_h(void) { M_SRA(R.HL.B.h); } +static void sra_l(void) { M_SRA(R.HL.B.l); } + +static void srl_xhl(void) +{ + byte i; + i=M_RDMEM(R.HL.D); + M_SRL(i); + M_WRMEM(R.HL.D,i); +} +static void srl_xix(void) +{ + byte i; + int j; + j=M_XIX; + i=M_RDMEM(j); + M_SRL(i); + M_WRMEM(j,i); +} +static void srl_xiy(void) +{ + byte i; + int j; + j=M_XIY; + i=M_RDMEM(j); + M_SRL(i); + M_WRMEM(j,i); +} +static void srl_a(void) { M_SRL(R.AF.B.h); } +static void srl_b(void) { M_SRL(R.BC.B.h); } +static void srl_c(void) { M_SRL(R.BC.B.l); } +static void srl_d(void) { M_SRL(R.DE.B.h); } +static void srl_e(void) { M_SRL(R.DE.B.l); } +static void srl_h(void) { M_SRL(R.HL.B.h); } +static void srl_l(void) { M_SRL(R.HL.B.l); } + +static void sub_xhl(void) { byte i=M_RD_XHL; M_SUB(i); } +static void sub_xix(void) { byte i=M_RD_XIX(); M_SUB(i); } +static void sub_xiy(void) { byte i=M_RD_XIY(); M_SUB(i); } +static void sub_a(void) { R.AF.D=Z_FLAG|N_FLAG; } +static void sub_b(void) { M_SUB(R.BC.B.h); } +static void sub_c(void) { M_SUB(R.BC.B.l); } +static void sub_d(void) { M_SUB(R.DE.B.h); } +static void sub_e(void) { M_SUB(R.DE.B.l); } +static void sub_h(void) { M_SUB(R.HL.B.h); } +static void sub_l(void) { M_SUB(R.HL.B.l); } +static void sub_ixh(void) { M_SUB(R.IX.B.h); } +static void sub_ixl(void) { M_SUB(R.IX.B.l); } +static void sub_iyh(void) { M_SUB(R.IY.B.h); } +static void sub_iyl(void) { M_SUB(R.IY.B.l); } +static void sub_byte(void) { byte i=M_RDMEM_OPCODE(); M_SUB(i); } + +static void xor_xhl(void) { byte i=M_RD_XHL; M_XOR(i); } +static void xor_xix(void) { byte i=M_RD_XIX(); M_XOR(i); } +static void xor_xiy(void) { byte i=M_RD_XIY(); M_XOR(i); } +static void xor_a(void) { R.AF.D=Z_FLAG|V_FLAG; } +static void xor_b(void) { M_XOR(R.BC.B.h); } +static void xor_c(void) { M_XOR(R.BC.B.l); } +static void xor_d(void) { M_XOR(R.DE.B.h); } +static void xor_e(void) { M_XOR(R.DE.B.l); } +static void xor_h(void) { M_XOR(R.HL.B.h); } +static void xor_l(void) { M_XOR(R.HL.B.l); } +static void xor_ixh(void) { M_XOR(R.IX.B.h); } +static void xor_ixl(void) { M_XOR(R.IX.B.l); } +static void xor_iyh(void) { M_XOR(R.IY.B.h); } +static void xor_iyl(void) { M_XOR(R.IY.B.l); } +static void xor_byte(void) { byte i=M_RDMEM_OPCODE(); M_XOR(i); } + +static void no_op(void) +{ + --R.PC.W.l; +} + +static void patch(void) { Z80_Patch(&R); } + +static unsigned cycles_main[256]= +{ + 4,10,7,6,4,4,7,4, + 4,11,7,6,4,4,7,4, + 8,10,7,6,4,4,7,4, + 7,11,7,6,4,4,7,4, + 7,10,16,6,4,4,7,4, + 7,11,16,6,4,4,7,4, + 7,10,13,6,11,11,10,4, + 7,11,13,6,4,4,7,4, + 4,4,4,4,4,4,7,4, + 4,4,4,4,4,4,7,4, + 4,4,4,4,4,4,7,4, + 4,4,4,4,4,4,7,4, + 4,4,4,4,4,4,7,4, + 4,4,4,4,4,4,7,4, + 7,7,7,7,7,7,4,7, + 4,4,4,4,4,4,7,4, + 4,4,4,4,4,4,7,4, + 4,4,4,4,4,4,7,4, + 4,4,4,4,4,4,7,4, + 4,4,4,4,4,4,7,4, + 4,4,4,4,4,4,7,4, + 4,4,4,4,4,4,7,4, + 4,4,4,4,4,4,7,4, + 4,4,4,4,4,4,7,4, + 5,10,10,10,10,11,7,11, + 5,4,10,0,10,10,7,11, + 5,10,10,11,10,11,7,11, + 5,4,10,11,10,0,7,11, + 5,10,10,19,10,11,7,11, + 5,4,10,4,10,0,7,11, + 5,10,10,4,10,11,7,11, + 5,6,10,4,10,0,7,11 +}; + +static unsigned cycles_cb[256]= +{ + 8,8,8,8,8,8,15,8, + 8,8,8,8,8,8,15,8, + 8,8,8,8,8,8,15,8, + 8,8,8,8,8,8,15,8, + 8,8,8,8,8,8,15,8, + 8,8,8,8,8,8,15,8, + 8,8,8,8,8,8,15,8, + 8,8,8,8,8,8,15,8, + 8,8,8,8,8,8,12,8, + 8,8,8,8,8,8,12,8, + 8,8,8,8,8,8,12,8, + 8,8,8,8,8,8,12,8, + 8,8,8,8,8,8,12,8, + 8,8,8,8,8,8,12,8, + 8,8,8,8,8,8,12,8, + 8,8,8,8,8,8,12,8, + 8,8,8,8,8,8,15,8, + 8,8,8,8,8,8,15,8, + 8,8,8,8,8,8,15,8, + 8,8,8,8,8,8,15,8, + 8,8,8,8,8,8,15,8, + 8,8,8,8,8,8,15,8, + 8,8,8,8,8,8,15,8, + 8,8,8,8,8,8,15,8, + 8,8,8,8,8,8,15,8, + 8,8,8,8,8,8,15,8, + 8,8,8,8,8,8,15,8, + 8,8,8,8,8,8,15,8, + 8,8,8,8,8,8,15,8, + 8,8,8,8,8,8,15,8, + 8,8,8,8,8,8,15,8, + 8,8,8,8,8,8,15,8 +}; +static unsigned cycles_xx_cb[]= +{ + 0,0,0,0,0,0,23,0, + 0,0,0,0,0,0,23,0, + 0,0,0,0,0,0,23,0, + 0,0,0,0,0,0,23,0, + 0,0,0,0,0,0,23,0, + 0,0,0,0,0,0,23,0, + 0,0,0,0,0,0,23,0, + 0,0,0,0,0,0,23,0, + 20,20,20,20,20,20,20,20, + 20,20,20,20,20,20,20,20, + 20,20,20,20,20,20,20,20, + 20,20,20,20,20,20,20,20, + 20,20,20,20,20,20,20,20, + 20,20,20,20,20,20,20,20, + 20,20,20,20,20,20,20,20, + 20,20,20,20,20,20,20,20, + 0,0,0,0,0,0,23,0, + 0,0,0,0,0,0,23,0, + 0,0,0,0,0,0,23,0, + 0,0,0,0,0,0,23,0, + 0,0,0,0,0,0,23,0, + 0,0,0,0,0,0,23,0, + 0,0,0,0,0,0,23,0, + 0,0,0,0,0,0,23,0, + 0,0,0,0,0,0,23,0, + 0,0,0,0,0,0,23,0, + 0,0,0,0,0,0,23,0, + 0,0,0,0,0,0,23,0, + 0,0,0,0,0,0,23,0, + 0,0,0,0,0,0,23,0, + 0,0,0,0,0,0,23,0, + 0,0,0,0,0,0,23,0 +}; +static unsigned cycles_xx[256]= +{ + 0,0,0,0,0,0,0,0, + 0,15,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,15,0,0,0,0,0,0, + 0,14,20,10,9,9,9,0, + 0,15,20,10,9,9,9,0, + 0,0,0,0,23,23,19,0, + 0,15,0,0,0,0,0,0, + 0,0,0,0,9,9,19,0, + 0,0,0,0,9,9,19,0, + 0,0,0,0,9,9,19,0, + 0,0,0,0,9,9,19,0, + 9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9, + 19,19,19,19,19,19,19,19, + 0,0,0,0,9,9,19,0, + 0,0,0,0,9,9,19,0, + 0,0,0,0,9,9,19,0, + 0,0,0,0,9,9,19,0, + 0,0,0,0,9,9,19,0, + 0,0,0,0,9,9,19,0, + 0,0,0,0,9,9,19,0, + 0,0,0,0,9,9,19,0, + 0,0,0,0,9,9,19,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,14,0,23,0,15,0,0, + 0,8,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,10,0,0,0,0,0,0 +}; +static unsigned cycles_ed[256]= +{ + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 12,12,15,20,8,8,8,9, + 12,12,15,20,8,8,8,9, + 12,12,15,20,8,8,8,9, + 12,12,15,20,8,8,8,9, + 12,12,15,20,8,8,8,18, + 12,12,15,20,8,8,8,18, + 12,12,15,20,8,8,8,0, + 12,12,15,20,8,8,8,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 16,16,16,16,0,0,0,0, + 16,16,16,16,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0 +}; + +static void no_op_xx(void) { +++R.PC.W.l; } + +static opcode_fn opcode_dd_cb[256]= +{ + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,rlc_xix ,no_op_xx , + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,rrc_xix ,no_op_xx , + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,rl_xix ,no_op_xx , + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,rr_xix ,no_op_xx , + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,sla_xix ,no_op_xx , + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,sra_xix ,no_op_xx , + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,sll_xix ,no_op_xx , + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,srl_xix ,no_op_xx , + bit_0_xix,bit_0_xix,bit_0_xix,bit_0_xix,bit_0_xix,bit_0_xix,bit_0_xix,bit_0_xix, + bit_1_xix,bit_1_xix,bit_1_xix,bit_1_xix,bit_1_xix,bit_1_xix,bit_1_xix,bit_1_xix, + bit_2_xix,bit_2_xix,bit_2_xix,bit_2_xix,bit_2_xix,bit_2_xix,bit_2_xix,bit_2_xix, + bit_3_xix,bit_3_xix,bit_3_xix,bit_3_xix,bit_3_xix,bit_3_xix,bit_3_xix,bit_3_xix, + bit_4_xix,bit_4_xix,bit_4_xix,bit_4_xix,bit_4_xix,bit_4_xix,bit_4_xix,bit_4_xix, + bit_5_xix,bit_5_xix,bit_5_xix,bit_5_xix,bit_5_xix,bit_5_xix,bit_5_xix,bit_5_xix, + bit_6_xix,bit_6_xix,bit_6_xix,bit_6_xix,bit_6_xix,bit_6_xix,bit_6_xix,bit_6_xix, + bit_7_xix,bit_7_xix,bit_7_xix,bit_7_xix,bit_7_xix,bit_7_xix,bit_7_xix,bit_7_xix, + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,res_0_xix,no_op_xx , + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,res_1_xix,no_op_xx , + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,res_2_xix,no_op_xx , + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,res_3_xix,no_op_xx , + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,res_4_xix,no_op_xx , + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,res_5_xix,no_op_xx , + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,res_6_xix,no_op_xx , + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,res_7_xix,no_op_xx , + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,set_0_xix,no_op_xx , + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,set_1_xix,no_op_xx , + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,set_2_xix,no_op_xx , + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,set_3_xix,no_op_xx , + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,set_4_xix,no_op_xx , + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,set_5_xix,no_op_xx , + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,set_6_xix,no_op_xx , + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,set_7_xix,no_op_xx +}; + +static opcode_fn opcode_fd_cb[256]= +{ + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,rlc_xiy ,no_op_xx , + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,rrc_xiy ,no_op_xx , + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,rl_xiy ,no_op_xx , + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,rr_xiy ,no_op_xx , + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,sla_xiy ,no_op_xx , + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,sra_xiy ,no_op_xx , + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,sll_xiy ,no_op_xx , + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,srl_xiy ,no_op_xx , + bit_0_xiy,bit_0_xiy,bit_0_xiy,bit_0_xiy,bit_0_xiy,bit_0_xiy,bit_0_xiy,bit_0_xiy, + bit_1_xiy,bit_1_xiy,bit_1_xiy,bit_1_xiy,bit_1_xiy,bit_1_xiy,bit_1_xiy,bit_1_xiy, + bit_2_xiy,bit_2_xiy,bit_2_xiy,bit_2_xiy,bit_2_xiy,bit_2_xiy,bit_2_xiy,bit_2_xiy, + bit_3_xiy,bit_3_xiy,bit_3_xiy,bit_3_xiy,bit_3_xiy,bit_3_xiy,bit_3_xiy,bit_3_xiy, + bit_4_xiy,bit_4_xiy,bit_4_xiy,bit_4_xiy,bit_4_xiy,bit_4_xiy,bit_4_xiy,bit_4_xiy, + bit_5_xiy,bit_5_xiy,bit_5_xiy,bit_5_xiy,bit_5_xiy,bit_5_xiy,bit_5_xiy,bit_5_xiy, + bit_6_xiy,bit_6_xiy,bit_6_xiy,bit_6_xiy,bit_6_xiy,bit_6_xiy,bit_6_xiy,bit_6_xiy, + bit_7_xiy,bit_7_xiy,bit_7_xiy,bit_7_xiy,bit_7_xiy,bit_7_xiy,bit_7_xiy,bit_7_xiy, + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,res_0_xiy,no_op_xx , + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,res_1_xiy,no_op_xx , + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,res_2_xiy,no_op_xx , + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,res_3_xiy,no_op_xx , + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,res_4_xiy,no_op_xx , + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,res_5_xiy,no_op_xx , + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,res_6_xiy,no_op_xx , + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,res_7_xiy,no_op_xx , + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,set_0_xiy,no_op_xx , + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,set_1_xiy,no_op_xx , + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,set_2_xiy,no_op_xx , + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,set_3_xiy,no_op_xx , + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,set_4_xiy,no_op_xx , + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,set_5_xiy,no_op_xx , + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,set_6_xiy,no_op_xx , + no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,no_op_xx ,set_7_xiy,no_op_xx +}; + +static void dd_cb(void) +{ + unsigned opcode; + opcode=M_RDOP_ARG((R.PC.D+1)&0xFFFF); + Z80_ICount += cycles_xx_cb[opcode]; + (*(opcode_dd_cb[opcode]))(); + ++R.PC.W.l; +}; +static void fd_cb(void) +{ + unsigned opcode; + opcode=M_RDOP_ARG((R.PC.D+1)&0xFFFF); + Z80_ICount+=cycles_xx_cb[opcode]; + (*(opcode_fd_cb[opcode]))(); + ++R.PC.W.l; +}; + +static opcode_fn opcode_cb[256]= +{ + rlc_b ,rlc_c ,rlc_d ,rlc_e ,rlc_h ,rlc_l ,rlc_xhl ,rlc_a , + rrc_b ,rrc_c ,rrc_d ,rrc_e ,rrc_h ,rrc_l ,rrc_xhl ,rrc_a , + rl_b ,rl_c ,rl_d ,rl_e ,rl_h ,rl_l ,rl_xhl ,rl_a , + rr_b ,rr_c ,rr_d ,rr_e ,rr_h ,rr_l ,rr_xhl ,rr_a , + sla_b ,sla_c ,sla_d ,sla_e ,sla_h ,sla_l ,sla_xhl ,sla_a , + sra_b ,sra_c ,sra_d ,sra_e ,sra_h ,sra_l ,sra_xhl ,sra_a , + sll_b ,sll_c ,sll_d ,sll_e ,sll_h ,sll_l ,sll_xhl ,sll_a , + srl_b ,srl_c ,srl_d ,srl_e ,srl_h ,srl_l ,srl_xhl ,srl_a , + bit_0_b,bit_0_c,bit_0_d,bit_0_e,bit_0_h,bit_0_l,bit_0_xhl,bit_0_a, + bit_1_b,bit_1_c,bit_1_d,bit_1_e,bit_1_h,bit_1_l,bit_1_xhl,bit_1_a, + bit_2_b,bit_2_c,bit_2_d,bit_2_e,bit_2_h,bit_2_l,bit_2_xhl,bit_2_a, + bit_3_b,bit_3_c,bit_3_d,bit_3_e,bit_3_h,bit_3_l,bit_3_xhl,bit_3_a, + bit_4_b,bit_4_c,bit_4_d,bit_4_e,bit_4_h,bit_4_l,bit_4_xhl,bit_4_a, + bit_5_b,bit_5_c,bit_5_d,bit_5_e,bit_5_h,bit_5_l,bit_5_xhl,bit_5_a, + bit_6_b,bit_6_c,bit_6_d,bit_6_e,bit_6_h,bit_6_l,bit_6_xhl,bit_6_a, + bit_7_b,bit_7_c,bit_7_d,bit_7_e,bit_7_h,bit_7_l,bit_7_xhl,bit_7_a, + res_0_b,res_0_c,res_0_d,res_0_e,res_0_h,res_0_l,res_0_xhl,res_0_a, + res_1_b,res_1_c,res_1_d,res_1_e,res_1_h,res_1_l,res_1_xhl,res_1_a, + res_2_b,res_2_c,res_2_d,res_2_e,res_2_h,res_2_l,res_2_xhl,res_2_a, + res_3_b,res_3_c,res_3_d,res_3_e,res_3_h,res_3_l,res_3_xhl,res_3_a, + res_4_b,res_4_c,res_4_d,res_4_e,res_4_h,res_4_l,res_4_xhl,res_4_a, + res_5_b,res_5_c,res_5_d,res_5_e,res_5_h,res_5_l,res_5_xhl,res_5_a, + res_6_b,res_6_c,res_6_d,res_6_e,res_6_h,res_6_l,res_6_xhl,res_6_a, + res_7_b,res_7_c,res_7_d,res_7_e,res_7_h,res_7_l,res_7_xhl,res_7_a, + set_0_b,set_0_c,set_0_d,set_0_e,set_0_h,set_0_l,set_0_xhl,set_0_a, + set_1_b,set_1_c,set_1_d,set_1_e,set_1_h,set_1_l,set_1_xhl,set_1_a, + set_2_b,set_2_c,set_2_d,set_2_e,set_2_h,set_2_l,set_2_xhl,set_2_a, + set_3_b,set_3_c,set_3_d,set_3_e,set_3_h,set_3_l,set_3_xhl,set_3_a, + set_4_b,set_4_c,set_4_d,set_4_e,set_4_h,set_4_l,set_4_xhl,set_4_a, + set_5_b,set_5_c,set_5_d,set_5_e,set_5_h,set_5_l,set_5_xhl,set_5_a, + set_6_b,set_6_c,set_6_d,set_6_e,set_6_h,set_6_l,set_6_xhl,set_6_a, + set_7_b,set_7_c,set_7_d,set_7_e,set_7_h,set_7_l,set_7_xhl,set_7_a +}; + +static opcode_fn opcode_dd[256]= +{ + no_op ,no_op ,no_op ,no_op ,no_op ,no_op ,no_op ,no_op , + no_op ,add_ix_bc ,no_op ,no_op ,no_op ,no_op ,no_op ,no_op , + no_op ,no_op ,no_op ,no_op ,no_op ,no_op ,no_op ,no_op , + no_op ,add_ix_de ,no_op ,no_op ,no_op ,no_op ,no_op ,no_op , + no_op ,ld_ix_word,ld_xword_ix,inc_ix ,inc_ixh ,dec_ixh ,ld_ixh_byte,no_op , + no_op ,add_ix_ix ,ld_ix_xword,dec_ix ,inc_ixl ,dec_ixl ,ld_ixl_byte,no_op , + no_op ,no_op ,no_op ,no_op ,inc_xix ,dec_xix ,ld_xix_byte,no_op , + no_op ,add_ix_sp ,no_op ,no_op ,no_op ,no_op ,no_op ,no_op , + no_op ,no_op ,no_op ,no_op ,ld_b_ixh ,ld_b_ixl ,ld_b_xix ,no_op , + no_op ,no_op ,no_op ,no_op ,ld_c_ixh ,ld_c_ixl ,ld_c_xix ,no_op , + no_op ,no_op ,no_op ,no_op ,ld_d_ixh ,ld_d_ixl ,ld_d_xix ,no_op , + no_op ,no_op ,no_op ,no_op ,ld_e_ixh ,ld_e_ixl ,ld_e_xix ,no_op , + ld_ixh_b,ld_ixh_c ,ld_ixh_d ,ld_ixh_e ,ld_ixh_ixh ,ld_ixh_ixl ,ld_h_xix ,ld_ixh_a, + ld_ixl_b,ld_ixl_c ,ld_ixl_d ,ld_ixl_e ,ld_ixl_ixh ,ld_ixl_ixl ,ld_l_xix ,ld_ixl_a, + ld_xix_b,ld_xix_c ,ld_xix_d ,ld_xix_e ,ld_xix_h ,ld_xix_l ,no_op ,ld_xix_a, + no_op ,no_op ,no_op ,no_op ,ld_a_ixh ,ld_a_ixl ,ld_a_xix ,no_op , + no_op ,no_op ,no_op ,no_op ,add_a_ixh ,add_a_ixl ,add_a_xix ,no_op , + no_op ,no_op ,no_op ,no_op ,adc_a_ixh ,adc_a_ixl ,adc_a_xix ,no_op , + no_op ,no_op ,no_op ,no_op ,sub_ixh ,sub_ixl ,sub_xix ,no_op , + no_op ,no_op ,no_op ,no_op ,sbc_a_ixh ,sbc_a_ixl ,sbc_a_xix ,no_op , + no_op ,no_op ,no_op ,no_op ,and_ixh ,and_ixl ,and_xix ,no_op , + no_op ,no_op ,no_op ,no_op ,xor_ixh ,xor_ixl ,xor_xix ,no_op , + no_op ,no_op ,no_op ,no_op ,or_ixh ,or_ixl ,or_xix ,no_op , + no_op ,no_op ,no_op ,no_op ,cp_ixh ,cp_ixl ,cp_xix ,no_op , + no_op ,no_op ,no_op ,no_op ,no_op ,no_op ,no_op ,no_op , + no_op ,no_op ,no_op ,dd_cb ,no_op ,no_op ,no_op ,no_op , + no_op ,no_op ,no_op ,no_op ,no_op ,no_op ,no_op ,no_op , + no_op ,no_op ,no_op ,no_op ,no_op ,no_op ,no_op ,no_op , + no_op ,pop_ix ,no_op ,ex_xsp_ix,no_op ,push_ix ,no_op ,no_op , + no_op ,jp_ix ,no_op ,no_op ,no_op ,no_op ,no_op ,no_op , + no_op ,no_op ,no_op ,no_op ,no_op ,no_op ,no_op ,no_op , + no_op ,ld_sp_ix ,no_op ,no_op ,no_op ,no_op ,no_op ,no_op +}; + +static opcode_fn opcode_ed[256]= +{ + nop ,nop ,nop ,nop ,nop,nop ,nop ,nop , + nop ,nop ,nop ,nop ,nop,nop ,nop ,nop , + nop ,nop ,nop ,nop ,nop,nop ,nop ,nop , + nop ,nop ,nop ,nop ,nop,nop ,nop ,nop , + nop ,nop ,nop ,nop ,nop,nop ,nop ,nop , + nop ,nop ,nop ,nop ,nop,nop ,nop ,nop , + nop ,nop ,nop ,nop ,nop,nop ,nop ,nop , + nop ,nop ,nop ,nop ,nop,nop ,nop ,nop , + in_b_c,out_c_b,sbc_hl_bc,ld_xword_bc,neg,retn,im_0 ,ld_i_a, + in_c_c,out_c_c,adc_hl_bc,ld_bc_xword,neg,reti,im_0 ,ld_r_a, + in_d_c,out_c_d,sbc_hl_de,ld_xword_de,neg,retn,im_1 ,ld_a_i, + in_e_c,out_c_e,adc_hl_de,ld_de_xword,neg,reti,im_2 ,ld_a_r, + in_h_c,out_c_h,sbc_hl_hl,ld_xword_hl,neg,retn,im_0 ,rrd , + in_l_c,out_c_l,adc_hl_hl,ld_hl_xword,neg,reti,im_0 ,rld , + in_0_c,out_c_0,sbc_hl_sp,ld_xword_sp,neg,retn,im_1 ,nop , + in_a_c,out_c_a,adc_hl_sp,ld_sp_xword,neg,reti,im_2 ,nop , + nop ,nop ,nop ,nop ,nop,nop ,nop ,nop , + nop ,nop ,nop ,nop ,nop,nop ,nop ,nop , + nop ,nop ,nop ,nop ,nop,nop ,nop ,nop , + nop ,nop ,nop ,nop ,nop,nop ,nop ,nop , + ldi ,cpi ,ini ,outi ,nop,nop ,nop ,nop , + ldd ,cpd ,ind ,outd ,nop,nop ,nop ,nop , + ldir ,cpir ,inir ,otir ,nop,nop ,nop ,nop , + lddr ,cpdr ,indr ,otdr ,nop,nop ,nop ,nop , + nop ,nop ,nop ,nop ,nop,nop ,nop ,nop , + nop ,nop ,nop ,nop ,nop,nop ,nop ,nop , + nop ,nop ,nop ,nop ,nop,nop ,nop ,nop , + nop ,nop ,nop ,nop ,nop,nop ,nop ,nop , + nop ,nop ,nop ,nop ,nop,nop ,nop ,nop , + nop ,nop ,nop ,nop ,nop,nop ,nop ,nop , + nop ,nop ,nop ,nop ,nop,nop ,nop ,nop , + nop ,nop ,nop ,nop ,nop,nop ,patch,nop +}; + +static opcode_fn opcode_fd[256]= +{ + no_op ,no_op ,no_op ,no_op ,no_op ,no_op ,no_op ,no_op , + no_op ,add_iy_bc ,no_op ,no_op ,no_op ,no_op ,no_op ,no_op , + no_op ,no_op ,no_op ,no_op ,no_op ,no_op ,no_op ,no_op , + no_op ,add_iy_de ,no_op ,no_op ,no_op ,no_op ,no_op ,no_op , + no_op ,ld_iy_word,ld_xword_iy,inc_iy ,inc_iyh ,dec_iyh ,ld_iyh_byte,no_op , + no_op ,add_iy_iy ,ld_iy_xword,dec_iy ,inc_iyl ,dec_iyl ,ld_iyl_byte,no_op , + no_op ,no_op ,no_op ,no_op ,inc_xiy ,dec_xiy ,ld_xiy_byte,no_op , + no_op ,add_iy_sp ,no_op ,no_op ,no_op ,no_op ,no_op ,no_op , + no_op ,no_op ,no_op ,no_op ,ld_b_iyh ,ld_b_iyl ,ld_b_xiy ,no_op , + no_op ,no_op ,no_op ,no_op ,ld_c_iyh ,ld_c_iyl ,ld_c_xiy ,no_op , + no_op ,no_op ,no_op ,no_op ,ld_d_iyh ,ld_d_iyl ,ld_d_xiy ,no_op , + no_op ,no_op ,no_op ,no_op ,ld_e_iyh ,ld_e_iyl ,ld_e_xiy ,no_op , + ld_iyh_b,ld_iyh_c ,ld_iyh_d ,ld_iyh_e ,ld_iyh_iyh ,ld_iyh_iyl ,ld_h_xiy ,ld_iyh_a, + ld_iyl_b,ld_iyl_c ,ld_iyl_d ,ld_iyl_e ,ld_iyl_iyh ,ld_iyl_iyl ,ld_l_xiy ,ld_iyl_a, + ld_xiy_b,ld_xiy_c ,ld_xiy_d ,ld_xiy_e ,ld_xiy_h ,ld_xiy_l ,no_op ,ld_xiy_a, + no_op ,no_op ,no_op ,no_op ,ld_a_iyh ,ld_a_iyl ,ld_a_xiy ,no_op , + no_op ,no_op ,no_op ,no_op ,add_a_iyh ,add_a_iyl ,add_a_xiy ,no_op , + no_op ,no_op ,no_op ,no_op ,adc_a_iyh ,adc_a_iyl ,adc_a_xiy ,no_op , + no_op ,no_op ,no_op ,no_op ,sub_iyh ,sub_iyl ,sub_xiy ,no_op , + no_op ,no_op ,no_op ,no_op ,sbc_a_iyh ,sbc_a_iyl ,sbc_a_xiy ,no_op , + no_op ,no_op ,no_op ,no_op ,and_iyh ,and_iyl ,and_xiy ,no_op , + no_op ,no_op ,no_op ,no_op ,xor_iyh ,xor_iyl ,xor_xiy ,no_op , + no_op ,no_op ,no_op ,no_op ,or_iyh ,or_iyl ,or_xiy ,no_op , + no_op ,no_op ,no_op ,no_op ,cp_iyh ,cp_iyl ,cp_xiy ,no_op , + no_op ,no_op ,no_op ,no_op ,no_op ,no_op ,no_op ,no_op , + no_op ,no_op ,no_op ,fd_cb ,no_op ,no_op ,no_op ,no_op , + no_op ,no_op ,no_op ,no_op ,no_op ,no_op ,no_op ,no_op , + no_op ,no_op ,no_op ,no_op ,no_op ,no_op ,no_op ,no_op , + no_op ,pop_iy ,no_op ,ex_xsp_iy,no_op ,push_iy ,no_op ,no_op , + no_op ,jp_iy ,no_op ,no_op ,no_op ,no_op ,no_op ,no_op , + no_op ,no_op ,no_op ,no_op ,no_op ,no_op ,no_op ,no_op , + no_op ,ld_sp_iy ,no_op ,no_op ,no_op ,no_op ,no_op ,no_op +}; + +static void cb(void) +{ + unsigned opcode; + ++R.R; + opcode=M_RDOP(R.PC.D); + R.PC.W.l++; + Z80_ICount+=cycles_cb[opcode]; + (*(opcode_cb[opcode]))(); +} +static void dd(void) +{ + unsigned opcode; + ++R.R; + opcode=M_RDOP(R.PC.D); + R.PC.W.l++; + Z80_ICount+=cycles_xx[opcode]; + (*(opcode_dd[opcode]))(); +} +static void ed(void) +{ + unsigned opcode; + ++R.R; + opcode=M_RDOP(R.PC.D); + R.PC.W.l++; + Z80_ICount+=cycles_ed[opcode]; + (*(opcode_ed[opcode]))(); +} +static void fd (void) +{ + unsigned opcode; + ++R.R; + opcode=M_RDOP(R.PC.D); + R.PC.W.l++; + Z80_ICount+=cycles_xx[opcode]; + (*(opcode_fd[opcode]))(); +} + +static opcode_fn opcode_main[256]= +{ + nop ,ld_bc_word,ld_xbc_a ,inc_bc ,inc_b ,dec_b ,ld_b_byte ,rlca , + ex_af_af,add_hl_bc ,ld_a_xbc ,dec_bc ,inc_c ,dec_c ,ld_c_byte ,rrca , + djnz ,ld_de_word,ld_xde_a ,inc_de ,inc_d ,dec_d ,ld_d_byte ,rla , + jr ,add_hl_de ,ld_a_xde ,dec_de ,inc_e ,dec_e ,ld_e_byte ,rra , + jr_nz ,ld_hl_word,ld_xword_hl,inc_hl ,inc_h ,dec_h ,ld_h_byte ,daa , + jr_z ,add_hl_hl ,ld_hl_xword,dec_hl ,inc_l ,dec_l ,ld_l_byte ,cpl , + jr_nc ,ld_sp_word,ld_xbyte_a ,inc_sp ,inc_xhl ,dec_xhl ,ld_xhl_byte,scf , + jr_c ,add_hl_sp ,ld_a_xbyte ,dec_sp ,inc_a ,dec_a ,ld_a_byte ,ccf , + ld_b_b ,ld_b_c ,ld_b_d ,ld_b_e ,ld_b_h ,ld_b_l ,ld_b_xhl ,ld_b_a , + ld_c_b ,ld_c_c ,ld_c_d ,ld_c_e ,ld_c_h ,ld_c_l ,ld_c_xhl ,ld_c_a , + ld_d_b ,ld_d_c ,ld_d_d ,ld_d_e ,ld_d_h ,ld_d_l ,ld_d_xhl ,ld_d_a , + ld_e_b ,ld_e_c ,ld_e_d ,ld_e_e ,ld_e_h ,ld_e_l ,ld_e_xhl ,ld_e_a , + ld_h_b ,ld_h_c ,ld_h_d ,ld_h_e ,ld_h_h ,ld_h_l ,ld_h_xhl ,ld_h_a , + ld_l_b ,ld_l_c ,ld_l_d ,ld_l_e ,ld_l_h ,ld_l_l ,ld_l_xhl ,ld_l_a , + ld_xhl_b,ld_xhl_c ,ld_xhl_d ,ld_xhl_e ,ld_xhl_h,ld_xhl_l,halt ,ld_xhl_a, + ld_a_b ,ld_a_c ,ld_a_d ,ld_a_e ,ld_a_h ,ld_a_l ,ld_a_xhl ,ld_a_a , + add_a_b ,add_a_c ,add_a_d ,add_a_e ,add_a_h ,add_a_l ,add_a_xhl ,add_a_a , + adc_a_b ,adc_a_c ,adc_a_d ,adc_a_e ,adc_a_h ,adc_a_l ,adc_a_xhl ,adc_a_a , + sub_b ,sub_c ,sub_d ,sub_e ,sub_h ,sub_l ,sub_xhl ,sub_a , + sbc_a_b ,sbc_a_c ,sbc_a_d ,sbc_a_e ,sbc_a_h ,sbc_a_l ,sbc_a_xhl ,sbc_a_a , + and_b ,and_c ,and_d ,and_e ,and_h ,and_l ,and_xhl ,and_a , + xor_b ,xor_c ,xor_d ,xor_e ,xor_h ,xor_l ,xor_xhl ,xor_a , + or_b ,or_c ,or_d ,or_e ,or_h ,or_l ,or_xhl ,or_a , + cp_b ,cp_c ,cp_d ,cp_e ,cp_h ,cp_l ,cp_xhl ,cp_a , + ret_nz ,pop_bc ,jp_nz ,jp ,call_nz ,push_bc ,add_a_byte ,rst_00 , + ret_z ,ret ,jp_z ,cb ,call_z ,call ,adc_a_byte ,rst_08 , + ret_nc ,pop_de ,jp_nc ,out_byte_a,call_nc ,push_de ,sub_byte ,rst_10 , + ret_c ,exx ,jp_c ,in_a_byte ,call_c ,dd ,sbc_a_byte ,rst_18 , + ret_po ,pop_hl ,jp_po ,ex_xsp_hl ,call_po ,push_hl ,and_byte ,rst_20 , + ret_pe ,jp_hl ,jp_pe ,ex_de_hl ,call_pe ,ed ,xor_byte ,rst_28 , + ret_p ,pop_af ,jp_p ,di ,call_p ,push_af ,or_byte ,rst_30 , + ret_m ,ld_sp_hl ,jp_m ,ei ,call_m ,fd ,cp_byte ,rst_38 +}; + +static void ei(void) +{ + unsigned opcode; + /* If interrupts were disabled, execute one more instruction and check the */ + /* IRQ line. If not, simply set interrupt flip-flop 2 */ + if (!R.IFF1) + { +#ifdef DEBUG + if (R.PC.D==Z80_Trap) Z80_Trace=1; + if (Z80_Trace) Z80_Debug(&R); +#endif + R.IFF1=R.IFF2=1; + ++R.R; + opcode=M_RDOP(R.PC.D); + R.PC.W.l++; + Z80_ICount+=cycles_main[opcode]; + (*(opcode_main[opcode]))(); + Interrupt(Z80_IRQ); + } + else + R.IFF2=1; +} + +/****************************************************************************/ +/* Reset registers to their initial values */ +/****************************************************************************/ +void Z80_Reset (void) +{ + memset (&R,0,sizeof(Z80_Regs)); + R.SP.D=0x0000; // Modificado de 0xF000 para 0x0000 + R.R=rand(); + Z80_ICount = 0; +} + +/****************************************************************************/ +/* Initialise the various lookup tables used by the emulation code */ +/****************************************************************************/ +void InitTables (void) +{ + static int InitTables_virgin=1; + byte zs; + int i,p; + if (!InitTables_virgin) return; + InitTables_virgin=0; + for (i=0;i<256;++i) + { + zs=0; + if (i==0) + zs|=Z_FLAG; + if (i&0x80) + zs|=S_FLAG; + p=0; + if (i&1) ++p; + if (i&2) ++p; + if (i&4) ++p; + if (i&8) ++p; + if (i&16) ++p; + if (i&32) ++p; + if (i&64) ++p; + if (i&128) ++p; + PTable[i]=(p&1)? 0:V_FLAG; + ZSTable[i]=zs; + ZSPTable[i]=zs|PTable[i]; + } + for (i=0;i<256;++i) + { + ZSTable[i+256]=ZSTable[i]|C_FLAG; + ZSPTable[i+256]=ZSPTable[i]|C_FLAG; + PTable[i+256]=PTable[i]|C_FLAG; + } +} + +/****************************************************************************/ +/* Issue an interrupt if necessary */ +/****************************************************************************/ +static void Interrupt (int j) +{ + if (j==Z80_IGNORE_INT) return; + if (j==Z80_NMI_INT || R.IFF1) + { + /* Clear interrupt flip-flop 1 */ + R.IFF1=0; + /* Check if processor was halted */ + if (R.HALT) + { + ++R.PC.W.l; + R.HALT=0; + } + if (j==Z80_NMI_INT) + { + M_PUSH (PC); + R.PC.D=0x0066; + } + else + { + /* Interrupt mode 2. Call [R.I:databyte] */ + if (R.IM==2) + { + M_PUSH (PC); + R.PC.D=M_RDMEM_WORD((j&255)|(R.I<<8)); + } + else + /* Interrupt mode 1. RST 38h */ + if (R.IM==1) + { + Z80_ICount+=cycles_main[0xFF]; + (*(opcode_main[0xFF]))(); + } + else + /* Interrupt mode 0. We check for CALL and JP instructions, if neither */ + /* of these were found we assume a 1 byte opcode was placed on the */ + /* databus */ + { + switch (j&0xFF0000) + { + case 0xCD: + M_PUSH(PC); + case 0xC3: + R.PC.D=j&0xFFFF; + break; + default: + j&=255; + Z80_ICount+=cycles_main[j]; + (*(opcode_main[j]))(); + break; + } + } + } + } +} + +/****************************************************************************/ +/* Set all registers to given values */ +/****************************************************************************/ +void Z80_SetRegs (Z80_Regs *Regs) +{ + R=*Regs; +} + +/****************************************************************************/ +/* Get all registers in given buffer */ +/****************************************************************************/ +void Z80_GetRegs (Z80_Regs *Regs) +{ + *Regs=R; +} + +/****************************************************************************/ +/* Return program counter */ +/****************************************************************************/ +unsigned Z80_GetPC (void) +{ + return R.PC.D; +} + +/****************************************************************************/ +/* Dump register contents and (optionally) a PC trace to stdout */ +/****************************************************************************/ +void Z80_RegisterDump (void) +{ + int i; + printf + ( + "AF:%04X HL:%04X DE:%04X BC:%04X PC:%04X SP:%04X IX:%04X IY:%04X\n", + R.AF.W.l,R.HL.W.l,R.DE.W.l,R.BC.W.l,R.PC.W.l,R.SP.W.l,R.IX.W.l,R.IY.W.l + ); + printf ("STACK: "); + for (i=0;i<10;++i) printf ("%04X ",M_RDMEM_WORD((R.SP.D+i*2)&0xFFFF)); + puts (""); +#ifdef TRACE + puts ("PC TRACE:"); + for (i=1;i<=256;++i) printf ("%04X\n",pc_trace[(pc_count-i)&255]); +#endif +} + +/****************************************************************************/ +/* Set number of memory refresh wait states (i.e. extra cycles inserted */ +/* when the refresh register is being incremented) */ +/****************************************************************************/ +void Z80_SetWaitStates (int n) +{ + int i; + for (i=0;i<256;++i) + { + cycles_main[i]+=n; + cycles_cb[i]+=n; + cycles_ed[i]+=n; + cycles_xx[i]+=n; + } +} + +// ------------------------------------------------------ + +/**************************************************************************** +* +* OPCODE TABLE +* +***/ + +//=========================================================================== + +// NB. Z80_ICount can legitimately go -ve! + +static const double uZ80ClockMultiplier = CLK_Z80 / CLK_6502; +inline static ULONG ConvertZ80TStatesTo6502Cycles(UINT uTStates) +{ + return (uTStates < 0) ? 0 : (ULONG) ((double)uTStates / uZ80ClockMultiplier); +} + +DWORD InternalZ80Execute (ULONG totalcycles, ULONG uExecutedCycles) +{ + // Nb. If uExecutedCycles == 0 (single-step) then just execute a single opcode + + totalcycles = (ULONG) ((double)totalcycles * uZ80ClockMultiplier); + uExecutedCycles = (ULONG) ((double)uExecutedCycles * uZ80ClockMultiplier); + int cycles = uExecutedCycles; // Must be signed int, as cycles can go -ve + + do { +#ifdef CPUDEBUG // ...xxx...xxx + if (g_nCumulativeCycles > 0) fprintf(arquivocpu, "%4X\n", regs.pc); + fflush(arquivocpu); +#endif // Z80 +#ifdef TRACE + pc_trace[pc_count]=R.PC.D; + pc_count=(pc_count+1)&255; +#endif +#ifdef DEBUG + if (R.PC.D==Z80_Trap) Z80_Trace=1; + if (Z80_Trace) Z80_Debug(&R); +#endif + ++R.R; + unsigned int opcode = M_RDOP(R.PC.D); + R.PC.W.l++; + Z80_ICount = cycles; + Z80_ICount += cycles_main[opcode]; + (*(opcode_main[opcode]))(); + cycles = Z80_ICount; + if (g_ActiveCPU != CPU_Z80) + break; + } + while (cycles < (int)totalcycles); + + Interrupt (Z80_Interrupt()); + + return ConvertZ80TStatesTo6502Cycles(cycles - uExecutedCycles); +} + +// +// ----- ALL GLOBALLY ACCESSIBLE FUNCTIONS ARE BELOW THIS LINE ----- +// + +// Implementação da CPU Z80: + +/****************************************************************************/ +/* Input a byte from given I/O port */ +/****************************************************************************/ +byte Z80_In (byte Port) +{ + return 0; +} + +/****************************************************************************/ +/* Output a byte to given I/O port */ +/****************************************************************************/ +void Z80_Out (byte Port,byte Value) +{ +} + +/****************************************************************************/ +/* Read a byte from given memory location */ +/****************************************************************************/ +unsigned Z80_RDMEM(DWORD Addr) +{ + WORD addr; + + switch (Addr / 0x1000) + { + case 0x0: + case 0x1: + case 0x2: + case 0x3: + case 0x4: + case 0x5: + case 0x6: + case 0x7: + case 0x8: + case 0x9: + case 0xA: + addr = (WORD)Addr + 0x1000; + return CpuRead( addr, ConvertZ80TStatesTo6502Cycles(Z80_ICount) ); + break; + + case 0xB: + case 0xC: + case 0xD: + addr = (WORD)Addr + 0x2000; + return CpuRead( addr, ConvertZ80TStatesTo6502Cycles(Z80_ICount) ); + break; + + case 0xE: + addr = (WORD)Addr - 0x2000; + if ((addr & 0xF000) == 0xC000) + { + return IORead[(addr>>4) & 0xFF]( regs.pc, addr, 0, 0, ConvertZ80TStatesTo6502Cycles(Z80_ICount) ); + } + else + { + return *(mem+addr); + } + break; + + case 0xF: + addr = (WORD)Addr - 0xF000; + return CpuRead( addr, ConvertZ80TStatesTo6502Cycles(Z80_ICount) ); + break; + } + return 255; +} + +/****************************************************************************/ +/* Write a byte to given memory location */ +/****************************************************************************/ +void Z80_WRMEM(DWORD Addr, BYTE Value) +{ + unsigned int laddr; + WORD addr; + + laddr = Addr & 0x0FFF; + switch (Addr & 0xF000) + { + case 0x0000: addr = laddr+0x1000; break; + case 0x1000: addr = laddr+0x2000; break; + case 0x2000: addr = laddr+0x3000; break; + case 0x3000: addr = laddr+0x4000; break; + case 0x4000: addr = laddr+0x5000; break; + case 0x5000: addr = laddr+0x6000; break; + case 0x6000: addr = laddr+0x7000; break; + case 0x7000: addr = laddr+0x8000; break; + case 0x8000: addr = laddr+0x9000; break; + case 0x9000: addr = laddr+0xA000; break; + case 0xA000: addr = laddr+0xB000; break; + case 0xB000: addr = laddr+0xD000; break; + case 0xC000: addr = laddr+0xE000; break; + case 0xD000: addr = laddr+0xF000; break; + case 0xE000: addr = laddr+0xC000; break; + case 0xF000: addr = laddr+0x0000; break; + } + CpuWrite( addr, Value, ConvertZ80TStatesTo6502Cycles(Z80_ICount) ); +} + +/* Called when ED FE occurs. Can be used */ +/* to emulate disk access etc. */ +void Z80_Patch (Z80_Regs *Regs) +{ +} + +/* This is called after IPeriod T-States */ +/* have been executed. It should return */ +/* Z80_IGNORE_INT, Z80_NMI_INT or a byte */ +/* identifying the device (most often */ +/* 0xFF) */ +int Z80_Interrupt(void) +{ + return Z80_IGNORE_INT; +} + +/* Called when RETI occurs */ +void Z80_Reti (void) +{ +} + +/* Called when RETN occurs */ +void Z80_Retn (void) +{ +} + diff --git a/AppleWin/source/Z80/z80cpu.h b/AppleWin/source/Z80/z80cpu.h new file mode 100644 index 00000000..2db18e30 --- /dev/null +++ b/AppleWin/source/Z80/z80cpu.h @@ -0,0 +1,182 @@ +#pragma once + +/* #define DEBUG */ /* Compile debugging version */ +/* #define X86_ASM */ /* Compile optimised GCC/x86 version */ + #define LSB_FIRST /* Compile for low-endian CPU */ +/* #define __64BIT__ */ /* Compile for 64 bit machines */ +/* #define __128BIT__ */ /* Compile for 128 bit machines */ + +#ifndef EMU_TYPES +#define EMU_TYPES + +/****************************************************************************/ +/* sizeof(byte)=1, sizeof(word)=2, sizeof(dword)>=4 */ +/****************************************************************************/ +typedef unsigned char byte; +typedef unsigned short word; +typedef unsigned dword; +typedef signed char offset; + +/****************************************************************************/ +/* Define a Z80 word. Upper bytes are always zero */ +/****************************************************************************/ +typedef union +{ +#ifdef __128BIT__ + #ifdef LSB_FIRST + struct { byte l,h,h2,h3,h4,h5,h6,h7, + h8,h9,h10,h11,h12,h13,h14,h15; } B; + struct { word l,h,h2,h3,h4,h5,h6,h7; } W; + dword D; + #else + struct { byte h15,h14,h13,h12,h11,h10,h9,h8, + h7,h6,h5,h4,h3,h2,h,l; } B; + struct { word h7,h6,h5,h4,h3,h2,h,l; } W; + dword D; + #endif +#elif __64BIT__ + #ifdef LSB_FIRST + struct { byte l,h,h2,h3,h4,h5,h6,h7; } B; + struct { word l,h,h2,h3; } W; + dword D; + #else + struct { byte h7,h6,h5,h4,h3,h2,h,l; } B; + struct { word h3,h2,h,l; } W; + dword D; + #endif +#else + #ifdef LSB_FIRST + struct { byte l,h,h2,h3; } B; + struct { word l,h; } W; + dword D; + #else + struct { byte h3,h2,h,l; } B; + struct { word h,l; } W; + dword D; + #endif +#endif +} regpair; + +#endif /* EMU_TYPES */ + +/****************************************************************************/ +/*** End of machine dependent definitions ***/ +/****************************************************************************/ + +#ifndef INLINE +#define INLINE static inline +#endif + +/****************************************************************************/ +/* The Z80 registers. HALT is set to 1 when the CPU is halted, the refresh */ +/* register is calculated as follows: refresh=(Regs.R&127)|(Regs.R2&128) */ +/****************************************************************************/ +typedef struct +{ + regpair AF,BC,DE,HL,IX,IY,PC,SP; + regpair AF2,BC2,DE2,HL2; + unsigned IFF1,IFF2,HALT,IM,I,R,R2; +} Z80_Regs; + +/****************************************************************************/ +/* Set Z80_Trace to 1 when PC==Z80_Trap. When trace is on, Z80_Debug() is */ +/* called after every instruction */ +/****************************************************************************/ +#ifdef DEBUG +extern int Z80_Trace; +extern int Z80_Trap; +void Z80_Debug(Z80_Regs *R); +#endif + +extern int Z80_Running; /* When 0, emulation terminates */ +extern int Z80_IPeriod; /* Number of T-states per interrupt */ +extern int Z80_ICount; /* T-state count */ +extern int Z80_IRQ; /* Current IRQ status. Checked after EI occurs */ + +#define Z80_IGNORE_INT -1 /* Ignore interrupt */ +#define Z80_NMI_INT -2 /* Execute NMI */ + +DWORD InternalZ80Execute (ULONG totalcycles, ULONG uExecutedCycles); +unsigned Z80_GetPC (void); /* Get program counter */ +void InitTables (void); +void Z80_GetRegs (Z80_Regs *Regs); /* Get registers */ +void Z80_SetRegs (Z80_Regs *Regs); /* Set registers */ +void Z80_Reset (void); /* Reset registers to the initial values */ +//int Z80_Execute (void); /* Execute IPeriod T-States */ +word Z80 (void); /* Execute until Z80_Running==0 */ +void Z80_RegisterDump (void); /* Prints a dump to stdout */ +void Z80_SetWaitStates (int n); /* Set number of memory wait states. */ + /* This only affects opcode fetching, so */ + /* wait state adjustment is still */ + /* necessary in Z80_RDMEM, Z80_RDOP_ARG, */ + /* Z80_RDSTACK and Z80_WRSTACK */ +void Z80_Patch (Z80_Regs *Regs); /* Called when ED FE occurs. Can be used */ + /* to emulate disk access etc. */ +int Z80_Interrupt(void); /* This is called after IPeriod T-States */ + /* have been executed. It should return */ + /* Z80_IGNORE_INT, Z80_NMI_INT or a byte */ + /* identifying the device (most often */ + /* 0xFF) */ +void Z80_Reti (void); /* Called when RETI occurs */ +void Z80_Retn (void); /* Called when RETN occurs */ + +/****************************************************************************/ +/* Definitions of functions to read/write memory and I/O ports */ +/* You can replace these with your own, inlined if necessary */ +/****************************************************************************/ +#include "Z80IO.h" + + + +// --------------------------------------------------------- + +#define M_RDMEM(A) Z80_RDMEM(A) +#define M_WRMEM(A,V) Z80_WRMEM(A,V) +#define M_RDOP(A) Z80_RDOP(A) +#define M_RDOP_ARG(A) Z80_RDOP_ARG(A) +#define M_RDSTACK(A) Z80_RDSTACK(A) +#define M_WRSTACK(A,V) Z80_WRSTACK(A,V) + +#define DoIn(lo,hi) Z80_In((lo)+(((unsigned)(hi))<<8)) +#define DoOut(lo,hi,v) Z80_Out((lo)+(((unsigned)(hi))<<8),v) + +static void Interrupt(int j); +static void ei(void); + +#define S_FLAG 0x80 +#define Z_FLAG 0x40 +#define H_FLAG 0x10 +#define V_FLAG 0x04 +#define N_FLAG 0x02 +#define C_FLAG 0x01 + +#define M_SKIP_CALL R.PC.W.l+=2 +#define M_SKIP_JP R.PC.W.l+=2 +#define M_SKIP_JR R.PC.W.l+=1 +#define M_SKIP_RET + +static Z80_Regs R; +#ifdef DEBUG +int Z80_Trace=0; +int Z80_Trap=-1; +#endif +#ifdef TRACE +static unsigned pc_trace[256]; +static unsigned pc_count=0; +#endif + +static byte PTable[512]; +static byte ZSTable[512]; +static byte ZSPTable[512]; +#include "Z80DAA.h" + +typedef void (*opcode_fn) (void); + +#define M_C (R.AF.B.l&C_FLAG) +#define M_NC (!M_C) +#define M_Z (R.AF.B.l&Z_FLAG) +#define M_NZ (!M_Z) +#define M_M (R.AF.B.l&S_FLAG) +#define M_P (!M_M) +#define M_PE (R.AF.B.l&V_FLAG) +#define M_PO (!M_PE) diff --git a/AppleWin/source/Z80/z80daa.h b/AppleWin/source/Z80/z80daa.h new file mode 100644 index 00000000..b1a3c0ba --- /dev/null +++ b/AppleWin/source/Z80/z80daa.h @@ -0,0 +1,2063 @@ +/*** Z80Em: Portable Z80 emulator *******************************************/ +/*** ***/ +/*** Z80DAA.h ***/ +/*** ***/ +/*** This file contains the DAA emulation lookup table. It is included ***/ +/*** from Z80.c ***/ +/*** ***/ +/*** Copyright (C) Marcel de Kogel 1996,1997 ***/ +/*** You are not allowed to distribute this software commercially ***/ +/*** Please, notify me, if you make any changes to this file ***/ +/****************************************************************************/ + +static short DAATable[2048]= +{ +68, +256, +512, +772, +1024, +1284, +1540, +1792, +2056, +2316, +4112, +4372, +4628, +4880, +5140, +5392, +4096, +4356, +4612, +4864, +5124, +5376, +5632, +5892, +6156, +6408, +8240, +8500, +8756, +9008, +9268, +9520, +8224, +8484, +8740, +8992, +9252, +9504, +9760, +10020, +10284, +10536, +12340, +12592, +12848, +13108, +13360, +13620, +12324, +12576, +12832, +13092, +13344, +13604, +13860, +14112, +14376, +14636, +16400, +16660, +16916, +17168, +17428, +17680, +16384, +16644, +16900, +17152, +17412, +17664, +17920, +18180, +18444, +18696, +20500, +20752, +21008, +21268, +21520, +21780, +20484, +20736, +20992, +21252, +21504, +21764, +22020, +22272, +22536, +22796, +24628, +24880, +25136, +25396, +25648, +25908, +24612, +24864, +25120, +25380, +25632, +25892, +26148, +26400, +26664, +26924, +28720, +28980, +29236, +29488, +29748, +30000, +28704, +28964, +29220, +29472, +29732, +29984, +30240, +30500, +30764, +31016, +-32624, +-32364, +-32108, +-31856, +-31596, +-31344, +-32640, +-32380, +-32124, +-31872, +-31612, +-31360, +-31104, +-30844, +-30580, +-30328, +-28524, +-28272, +-28016, +-27756, +-27504, +-27244, +-28540, +-28288, +-28032, +-27772, +-27520, +-27260, +-27004, +-26752, +-26488, +-26228, +85, +273, +529, +789, +1041, +1301, +69, +257, +513, +773, +1025, +1285, +1541, +1793, +2057, +2317, +4113, +4373, +4629, +4881, +5141, +5393, +4097, +4357, +4613, +4865, +5125, +5377, +5633, +5893, +6157, +6409, +8241, +8501, +8757, +9009, +9269, +9521, +8225, +8485, +8741, +8993, +9253, +9505, +9761, +10021, +10285, +10537, +12341, +12593, +12849, +13109, +13361, +13621, +12325, +12577, +12833, +13093, +13345, +13605, +13861, +14113, +14377, +14637, +16401, +16661, +16917, +17169, +17429, +17681, +16385, +16645, +16901, +17153, +17413, +17665, +17921, +18181, +18445, +18697, +20501, +20753, +21009, +21269, +21521, +21781, +20485, +20737, +20993, +21253, +21505, +21765, +22021, +22273, +22537, +22797, +24629, +24881, +25137, +25397, +25649, +25909, +24613, +24865, +25121, +25381, +25633, +25893, +26149, +26401, +26665, +26925, +28721, +28981, +29237, +29489, +29749, +30001, +28705, +28965, +29221, +29473, +29733, +29985, +30241, +30501, +30765, +31017, +-32623, +-32363, +-32107, +-31855, +-31595, +-31343, +-32639, +-32379, +-32123, +-31871, +-31611, +-31359, +-31103, +-30843, +-30579, +-30327, +-28523, +-28271, +-28015, +-27755, +-27503, +-27243, +-28539, +-28287, +-28031, +-27771, +-27519, +-27259, +-27003, +-26751, +-26487, +-26227, +-24395, +-24143, +-23887, +-23627, +-23375, +-23115, +-24411, +-24159, +-23903, +-23643, +-23391, +-23131, +-22875, +-22623, +-22359, +-22099, +-20303, +-20043, +-19787, +-19535, +-19275, +-19023, +-20319, +-20059, +-19803, +-19551, +-19291, +-19039, +-18783, +-18523, +-18259, +-18007, +-16235, +-15983, +-15727, +-15467, +-15215, +-14955, +-16251, +-15999, +-15743, +-15483, +-15231, +-14971, +-14715, +-14463, +-14199, +-13939, +-12143, +-11883, +-11627, +-11375, +-11115, +-10863, +-12159, +-11899, +-11643, +-11391, +-11131, +-10879, +-10623, +-10363, +-10099, +-9847, +-8015, +-7755, +-7499, +-7247, +-6987, +-6735, +-8031, +-7771, +-7515, +-7263, +-7003, +-6751, +-6495, +-6235, +-5971, +-5719, +-3915, +-3663, +-3407, +-3147, +-2895, +-2635, +-3931, +-3679, +-3423, +-3163, +-2911, +-2651, +-2395, +-2143, +-1879, +-1619, +85, +273, +529, +789, +1041, +1301, +69, +257, +513, +773, +1025, +1285, +1541, +1793, +2057, +2317, +4113, +4373, +4629, +4881, +5141, +5393, +4097, +4357, +4613, +4865, +5125, +5377, +5633, +5893, +6157, +6409, +8241, +8501, +8757, +9009, +9269, +9521, +8225, +8485, +8741, +8993, +9253, +9505, +9761, +10021, +10285, +10537, +12341, +12593, +12849, +13109, +13361, +13621, +12325, +12577, +12833, +13093, +13345, +13605, +13861, +14113, +14377, +14637, +16401, +16661, +16917, +17169, +17429, +17681, +16385, +16645, +16901, +17153, +17413, +17665, +17921, +18181, +18445, +18697, +20501, +20753, +21009, +21269, +21521, +21781, +20485, +20737, +20993, +21253, +21505, +21765, +22021, +22273, +22537, +22797, +24629, +24881, +25137, +25397, +25649, +25909, +1540, +1792, +2056, +2316, +2572, +2824, +3084, +3336, +3592, +3852, +4112, +4372, +4628, +4880, +5140, +5392, +5632, +5892, +6156, +6408, +6664, +6924, +7176, +7436, +7692, +7944, +8240, +8500, +8756, +9008, +9268, +9520, +9760, +10020, +10284, +10536, +10792, +11052, +11304, +11564, +11820, +12072, +12340, +12592, +12848, +13108, +13360, +13620, +13860, +14112, +14376, +14636, +14892, +15144, +15404, +15656, +15912, +16172, +16400, +16660, +16916, +17168, +17428, +17680, +17920, +18180, +18444, +18696, +18952, +19212, +19464, +19724, +19980, +20232, +20500, +20752, +21008, +21268, +21520, +21780, +22020, +22272, +22536, +22796, +23052, +23304, +23564, +23816, +24072, +24332, +24628, +24880, +25136, +25396, +25648, +25908, +26148, +26400, +26664, +26924, +27180, +27432, +27692, +27944, +28200, +28460, +28720, +28980, +29236, +29488, +29748, +30000, +30240, +30500, +30764, +31016, +31272, +31532, +31784, +32044, +32300, +32552, +-32624, +-32364, +-32108, +-31856, +-31596, +-31344, +-31104, +-30844, +-30580, +-30328, +-30072, +-29812, +-29560, +-29300, +-29044, +-28792, +-28524, +-28272, +-28016, +-27756, +-27504, +-27244, +-27004, +-26752, +-26488, +-26228, +-25972, +-25720, +-25460, +-25208, +-24952, +-24692, +85, +273, +529, +789, +1041, +1301, +1541, +1793, +2057, +2317, +2573, +2825, +3085, +3337, +3593, +3853, +4113, +4373, +4629, +4881, +5141, +5393, +5633, +5893, +6157, +6409, +6665, +6925, +7177, +7437, +7693, +7945, +8241, +8501, +8757, +9009, +9269, +9521, +9761, +10021, +10285, +10537, +10793, +11053, +11305, +11565, +11821, +12073, +12341, +12593, +12849, +13109, +13361, +13621, +13861, +14113, +14377, +14637, +14893, +15145, +15405, +15657, +15913, +16173, +16401, +16661, +16917, +17169, +17429, +17681, +17921, +18181, +18445, +18697, +18953, +19213, +19465, +19725, +19981, +20233, +20501, +20753, +21009, +21269, +21521, +21781, +22021, +22273, +22537, +22797, +23053, +23305, +23565, +23817, +24073, +24333, +24629, +24881, +25137, +25397, +25649, +25909, +26149, +26401, +26665, +26925, +27181, +27433, +27693, +27945, +28201, +28461, +28721, +28981, +29237, +29489, +29749, +30001, +30241, +30501, +30765, +31017, +31273, +31533, +31785, +32045, +32301, +32553, +-32623, +-32363, +-32107, +-31855, +-31595, +-31343, +-31103, +-30843, +-30579, +-30327, +-30071, +-29811, +-29559, +-29299, +-29043, +-28791, +-28523, +-28271, +-28015, +-27755, +-27503, +-27243, +-27003, +-26751, +-26487, +-26227, +-25971, +-25719, +-25459, +-25207, +-24951, +-24691, +-24395, +-24143, +-23887, +-23627, +-23375, +-23115, +-22875, +-22623, +-22359, +-22099, +-21843, +-21591, +-21331, +-21079, +-20823, +-20563, +-20303, +-20043, +-19787, +-19535, +-19275, +-19023, +-18783, +-18523, +-18259, +-18007, +-17751, +-17491, +-17239, +-16979, +-16723, +-16471, +-16235, +-15983, +-15727, +-15467, +-15215, +-14955, +-14715, +-14463, +-14199, +-13939, +-13683, +-13431, +-13171, +-12919, +-12663, +-12403, +-12143, +-11883, +-11627, +-11375, +-11115, +-10863, +-10623, +-10363, +-10099, +-9847, +-9591, +-9331, +-9079, +-8819, +-8563, +-8311, +-8015, +-7755, +-7499, +-7247, +-6987, +-6735, +-6495, +-6235, +-5971, +-5719, +-5463, +-5203, +-4951, +-4691, +-4435, +-4183, +-3915, +-3663, +-3407, +-3147, +-2895, +-2635, +-2395, +-2143, +-1879, +-1619, +-1363, +-1111, +-851, +-599, +-343, +-83, +85, +273, +529, +789, +1041, +1301, +1541, +1793, +2057, +2317, +2573, +2825, +3085, +3337, +3593, +3853, +4113, +4373, +4629, +4881, +5141, +5393, +5633, +5893, +6157, +6409, +6665, +6925, +7177, +7437, +7693, +7945, +8241, +8501, +8757, +9009, +9269, +9521, +9761, +10021, +10285, +10537, +10793, +11053, +11305, +11565, +11821, +12073, +12341, +12593, +12849, +13109, +13361, +13621, +13861, +14113, +14377, +14637, +14893, +15145, +15405, +15657, +15913, +16173, +16401, +16661, +16917, +17169, +17429, +17681, +17921, +18181, +18445, +18697, +18953, +19213, +19465, +19725, +19981, +20233, +20501, +20753, +21009, +21269, +21521, +21781, +22021, +22273, +22537, +22797, +23053, +23305, +23565, +23817, +24073, +24333, +24629, +24881, +25137, +25397, +25649, +25909, +70, +258, +514, +774, +1026, +1286, +1542, +1794, +2058, +2318, +1026, +1286, +1542, +1794, +2058, +2318, +4098, +4358, +4614, +4866, +5126, +5378, +5634, +5894, +6158, +6410, +5126, +5378, +5634, +5894, +6158, +6410, +8226, +8486, +8742, +8994, +9254, +9506, +9762, +10022, +10286, +10538, +9254, +9506, +9762, +10022, +10286, +10538, +12326, +12578, +12834, +13094, +13346, +13606, +13862, +14114, +14378, +14638, +13346, +13606, +13862, +14114, +14378, +14638, +16386, +16646, +16902, +17154, +17414, +17666, +17922, +18182, +18446, +18698, +17414, +17666, +17922, +18182, +18446, +18698, +20486, +20738, +20994, +21254, +21506, +21766, +22022, +22274, +22538, +22798, +21506, +21766, +22022, +22274, +22538, +22798, +24614, +24866, +25122, +25382, +25634, +25894, +26150, +26402, +26666, +26926, +25634, +25894, +26150, +26402, +26666, +26926, +28706, +28966, +29222, +29474, +29734, +29986, +30242, +30502, +30766, +31018, +29734, +29986, +30242, +30502, +30766, +31018, +-32638, +-32378, +-32122, +-31870, +-31610, +-31358, +-31102, +-30842, +-30578, +-30326, +-31610, +-31358, +-31102, +-30842, +-30578, +-30326, +-28538, +-28286, +-28030, +-27770, +-27518, +-27258, +-27002, +-26750, +-26486, +-26226, +13347, +13607, +13863, +14115, +14379, +14639, +16387, +16647, +16903, +17155, +17415, +17667, +17923, +18183, +18447, +18699, +17415, +17667, +17923, +18183, +18447, +18699, +20487, +20739, +20995, +21255, +21507, +21767, +22023, +22275, +22539, +22799, +21507, +21767, +22023, +22275, +22539, +22799, +24615, +24867, +25123, +25383, +25635, +25895, +26151, +26403, +26667, +26927, +25635, +25895, +26151, +26403, +26667, +26927, +28707, +28967, +29223, +29475, +29735, +29987, +30243, +30503, +30767, +31019, +29735, +29987, +30243, +30503, +30767, +31019, +-32637, +-32377, +-32121, +-31869, +-31609, +-31357, +-31101, +-30841, +-30577, +-30325, +-31609, +-31357, +-31101, +-30841, +-30577, +-30325, +-28537, +-28285, +-28029, +-27769, +-27517, +-27257, +-27001, +-26749, +-26485, +-26225, +-27517, +-27257, +-27001, +-26749, +-26485, +-26225, +-24409, +-24157, +-23901, +-23641, +-23389, +-23129, +-22873, +-22621, +-22357, +-22097, +-23389, +-23129, +-22873, +-22621, +-22357, +-22097, +-20317, +-20057, +-19801, +-19549, +-19289, +-19037, +-18781, +-18521, +-18257, +-18005, +-19289, +-19037, +-18781, +-18521, +-18257, +-18005, +-16249, +-15997, +-15741, +-15481, +-15229, +-14969, +-14713, +-14461, +-14197, +-13937, +-15229, +-14969, +-14713, +-14461, +-14197, +-13937, +-12157, +-11897, +-11641, +-11389, +-11129, +-10877, +-10621, +-10361, +-10097, +-9845, +-11129, +-10877, +-10621, +-10361, +-10097, +-9845, +-8029, +-7769, +-7513, +-7261, +-7001, +-6749, +-6493, +-6233, +-5969, +-5717, +-7001, +-6749, +-6493, +-6233, +-5969, +-5717, +-3929, +-3677, +-3421, +-3161, +-2909, +-2649, +-2393, +-2141, +-1877, +-1617, +-2909, +-2649, +-2393, +-2141, +-1877, +-1617, +71, +259, +515, +775, +1027, +1287, +1543, +1795, +2059, +2319, +1027, +1287, +1543, +1795, +2059, +2319, +4099, +4359, +4615, +4867, +5127, +5379, +5635, +5895, +6159, +6411, +5127, +5379, +5635, +5895, +6159, +6411, +8227, +8487, +8743, +8995, +9255, +9507, +9763, +10023, +10287, +10539, +9255, +9507, +9763, +10023, +10287, +10539, +12327, +12579, +12835, +13095, +13347, +13607, +13863, +14115, +14379, +14639, +13347, +13607, +13863, +14115, +14379, +14639, +16387, +16647, +16903, +17155, +17415, +17667, +17923, +18183, +18447, +18699, +17415, +17667, +17923, +18183, +18447, +18699, +20487, +20739, +20995, +21255, +21507, +21767, +22023, +22275, +22539, +22799, +21507, +21767, +22023, +22275, +22539, +22799, +24615, +24867, +25123, +25383, +25635, +25895, +26151, +26403, +26667, +26927, +25635, +25895, +26151, +26403, +26667, +26927, +28707, +28967, +29223, +29475, +29735, +29987, +30243, +30503, +30767, +31019, +29735, +29987, +30243, +30503, +30767, +31019, +-32637, +-32377, +-32121, +-31869, +-31609, +-31357, +-31101, +-30841, +-30577, +-30325, +-31609, +-31357, +-31101, +-30841, +-30577, +-30325, +-28537, +-28285, +-28029, +-27769, +-27517, +-27257, +-27001, +-26749, +-26485, +-26225, +-27517, +-27257, +-27001, +-26749, +-26485, +-26225, +-1346, +-1094, +-834, +-582, +-326, +-66, +70, +258, +514, +774, +1026, +1286, +1542, +1794, +2058, +2318, +2590, +2842, +3102, +3354, +3610, +3870, +4098, +4358, +4614, +4866, +5126, +5378, +5634, +5894, +6158, +6410, +6682, +6942, +7194, +7454, +7710, +7962, +8226, +8486, +8742, +8994, +9254, +9506, +9762, +10022, +10286, +10538, +10810, +11070, +11322, +11582, +11838, +12090, +12326, +12578, +12834, +13094, +13346, +13606, +13862, +14114, +14378, +14638, +14910, +15162, +15422, +15674, +15930, +16190, +16386, +16646, +16902, +17154, +17414, +17666, +17922, +18182, +18446, +18698, +18970, +19230, +19482, +19742, +19998, +20250, +20486, +20738, +20994, +21254, +21506, +21766, +22022, +22274, +22538, +22798, +23070, +23322, +23582, +23834, +24090, +24350, +24614, +24866, +25122, +25382, +25634, +25894, +26150, +26402, +26666, +26926, +27198, +27450, +27710, +27962, +28218, +28478, +28706, +28966, +29222, +29474, +29734, +29986, +30242, +30502, +30766, +31018, +31290, +31550, +31802, +32062, +32318, +32570, +-32638, +-32378, +-32122, +-31870, +-31610, +-31358, +-31102, +-30842, +-30578, +-30326, +-30054, +-29794, +-29542, +-29282, +-29026, +-28774, +-28538, +-28286, +-28030, +-27770, +13347, +13607, +13863, +14115, +14379, +14639, +14911, +15163, +15423, +15675, +15931, +16191, +16387, +16647, +16903, +17155, +17415, +17667, +17923, +18183, +18447, +18699, +18971, +19231, +19483, +19743, +19999, +20251, +20487, +20739, +20995, +21255, +21507, +21767, +22023, +22275, +22539, +22799, +23071, +23323, +23583, +23835, +24091, +24351, +24615, +24867, +25123, +25383, +25635, +25895, +26151, +26403, +26667, +26927, +27199, +27451, +27711, +27963, +28219, +28479, +28707, +28967, +29223, +29475, +29735, +29987, +30243, +30503, +30767, +31019, +31291, +31551, +31803, +32063, +32319, +32571, +-32637, +-32377, +-32121, +-31869, +-31609, +-31357, +-31101, +-30841, +-30577, +-30325, +-30053, +-29793, +-29541, +-29281, +-29025, +-28773, +-28537, +-28285, +-28029, +-27769, +-27517, +-27257, +-27001, +-26749, +-26485, +-26225, +-25953, +-25701, +-25441, +-25189, +-24933, +-24673, +-24409, +-24157, +-23901, +-23641, +-23389, +-23129, +-22873, +-22621, +-22357, +-22097, +-21825, +-21573, +-21313, +-21061, +-20805, +-20545, +-20317, +-20057, +-19801, +-19549, +-19289, +-19037, +-18781, +-18521, +-18257, +-18005, +-17733, +-17473, +-17221, +-16961, +-16705, +-16453, +-16249, +-15997, +-15741, +-15481, +-15229, +-14969, +-14713, +-14461, +-14197, +-13937, +-13665, +-13413, +-13153, +-12901, +-12645, +-12385, +-12157, +-11897, +-11641, +-11389, +-11129, +-10877, +-10621, +-10361, +-10097, +-9845, +-9573, +-9313, +-9061, +-8801, +-8545, +-8293, +-8029, +-7769, +-7513, +-7261, +-7001, +-6749, +-6493, +-6233, +-5969, +-5717, +-5445, +-5185, +-4933, +-4673, +-4417, +-4165, +-3929, +-3677, +-3421, +-3161, +-2909, +-2649, +-2393, +-2141, +-1877, +-1617, +-1345, +-1093, +-833, +-581, +-325, +-65, +71, +259, +515, +775, +1027, +1287, +1543, +1795, +2059, +2319, +2591, +2843, +3103, +3355, +3611, +3871, +4099, +4359, +4615, +4867, +5127, +5379, +5635, +5895, +6159, +6411, +6683, +6943, +7195, +7455, +7711, +7963, +8227, +8487, +8743, +8995, +9255, +9507, +9763, +10023, +10287, +10539, +10811, +11071, +11323, +11583, +11839, +12091, +12327, +12579, +12835, +13095, +13347, +13607, +13863, +14115, +14379, +14639, +14911, +15163, +15423, +15675, +15931, +16191, +16387, +16647, +16903, +17155, +17415, +17667, +17923, +18183, +18447, +18699, +18971, +19231, +19483, +19743, +19999, +20251, +20487, +20739, +20995, +21255, +21507, +21767, +22023, +22275, +22539, +22799, +23071, +23323, +23583, +23835, +24091, +24351, +24615, +24867, +25123, +25383, +25635, +25895, +26151, +26403, +26667, +26927, +27199, +27451, +27711, +27963, +28219, +28479, +28707, +28967, +29223, +29475, +29735, +29987, +30243, +30503, +30767, +31019, +31291, +31551, +31803, +32063, +32319, +32571, +-32637, +-32377, +-32121, +-31869, +-31609, +-31357, +-31101, +-30841, +-30577, +-30325, +-30053, +-29793, +-29541, +-29281, +-29025, +-28773, +-28537, +-28285, +-28029, +-27769, +-27517, +-27257, +-27001, +-26749, +-26485, +-26225 +}; diff --git a/AppleWin/source/Z80/z80emu.cpp b/AppleWin/source/Z80/z80emu.cpp new file mode 100644 index 00000000..0577b8f6 --- /dev/null +++ b/AppleWin/source/Z80/z80emu.cpp @@ -0,0 +1,56 @@ +/* Emulador do computador TK3000 //e (Microdigital) + * por Fábio Belavenuto - Copyright (C) 2004 + * + * Adaptado do emulador Applewin por Michael O'Brien + * Part of code is Copyright (C) 2003-2004 Tom Charlesworth + * + * Este arquivo é distribuido pela Licença Pública Geral GNU. + * Veja o arquivo Licenca.txt distribuido com este software. + * + * ESTE SOFTWARE NÃO OFERECE NENHUMA GARANTIA + * + */ + +// Emula a CPU Z80 + +#include "..\StdAfx.h" +#include "z80emu.h" + +// Variaveis +int CPMZ80Slot = 0; +int Z80_IRQ = 0; + +BYTE __stdcall CPMZ80_IONull(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nCyclesLeft) +{ + return IO_Null(PC, uAddr, bWrite, uValue, nCyclesLeft); +} + +BYTE __stdcall CPMZ80_IOWrite(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nCyclesLeft) +{ + if ((uAddr & 0xFF00) == (0xC000 + (CPMZ80Slot << 8))) + { + g_ActiveCPU = (g_ActiveCPU == CPU_6502) ? CPU_Z80 : CPU_6502; + } + return IO_Null(PC, uAddr, bWrite, uValue, nCyclesLeft); +} + +//=========================================================================== +void ConfigureSoftcard(LPBYTE pCxRomPeripheral, int Slot, UINT addOrRemove) +{ + //LPBYTE pCxRomPeripheral = MemGetCxRomPeripheral(); + //if (pCxRomPeripheral == NULL) + // return; + + //UINT uOffset = (m_by6821B << 7) & 0x0700; + //memcpy(pCxRomPeripheral+m_uSlot*256, m_pSlotRom+uOffset, 256); + //if (mem) + // memcpy(mem+0xC000+m_uSlot*256, m_pSlotRom+uOffset, 256); + + memset(pCxRomPeripheral + (Slot << 8), 0xFF, 256); + + CPMZ80Slot = Slot; + + RegisterIoHandler(Slot, CPMZ80_IONull, CPMZ80_IONull, CPMZ80_IONull, addOrRemove ? CPMZ80_IOWrite : NULL, NULL, NULL); +} + +// EOF \ No newline at end of file diff --git a/AppleWin/source/Z80/z80emu.h b/AppleWin/source/Z80/z80emu.h new file mode 100644 index 00000000..09f334cb --- /dev/null +++ b/AppleWin/source/Z80/z80emu.h @@ -0,0 +1,18 @@ +/* Emulador do computador TK3000 //e (Microdigital) + * por Fábio Belavenuto - Copyright (C) 2004 + * + * Adaptado do emulador Applewin por Michael O'Brien + * + * Este arquivo é distribuido pela Licença Pública Geral GNU. + * Veja o arquivo Licenca.txt distribuido com este software. + * + * ESTE SOFTWARE NÃO OFERECE NENHUMA GARANTIA + * + */ + +// Emula a CPU Z80 + +// Protótipos +void ConfigureSoftcard(LPBYTE pCxRomPeripheral, int slot, UINT addOrRemove); + +// EOF \ No newline at end of file diff --git a/AppleWin/source/Z80/z80io.cpp b/AppleWin/source/Z80/z80io.cpp new file mode 100644 index 00000000..956a2386 --- /dev/null +++ b/AppleWin/source/Z80/z80io.cpp @@ -0,0 +1,17 @@ +/* Emulador do computador TK3000 //e (Microdigital) + * por Fábio Belavenuto - Copyright (C) 2004 + * + * Adaptado do emulador Applewin por Michael O'Brien + * + * Este arquivo é distribuido pela Licença Pública Geral GNU. + * Veja o arquivo Licenca.txt distribuido com este software. + * + * ESTE SOFTWARE NÃO OFERECE NENHUMA GARANTIA + * + */ + +// Emula a CPU Z80 + +#include "..\stdafx.h" +#include "Z80IO.h" + diff --git a/AppleWin/source/Z80/z80io.h b/AppleWin/source/Z80/z80io.h new file mode 100644 index 00000000..638aac9a --- /dev/null +++ b/AppleWin/source/Z80/z80io.h @@ -0,0 +1,70 @@ +/*** Z80Em: Portable Z80 emulator *******************************************/ +/*** ***/ +/*** Z80IO.h ***/ +/*** ***/ +/*** This file contains the prototypes for the functions accessing memory ***/ +/*** and I/O ***/ +/*** ***/ +/*** Copyright (C) Marcel de Kogel 1996,1997 ***/ +/*** You are not allowed to distribute this software commercially ***/ +/*** Please, notify me, if you make any changes to this file ***/ +/****************************************************************************/ + +/****************************************************************************/ +/* Input a byte from given I/O port */ +/****************************************************************************/ +byte Z80_In (BYTE Port); + +/****************************************************************************/ +/* Output a byte to given I/O port */ +/****************************************************************************/ +void Z80_Out (BYTE Port,BYTE Value); + +/****************************************************************************/ +/* Read a byte from given memory location */ +/****************************************************************************/ +unsigned Z80_RDMEM(DWORD A); + +/****************************************************************************/ +/* Write a byte to given memory location */ +/****************************************************************************/ +void Z80_WRMEM(DWORD A,BYTE V); + +/****************************************************************************/ +/* Just to show you can actually use macros as well */ +/****************************************************************************/ +/* + extern byte *ReadPage[256]; + extern byte *WritePage[256]; + #define Z80_RDMEM(a) ReadPage[(a)>>8][(a)&0xFF] + #define Z80_WRMEM(a,v) WritePage[(a)>>8][(a)&0xFF]=v +*/ + +/****************************************************************************/ +/* Z80_RDOP() is identical to Z80_RDMEM() except it is used for reading */ +/* opcodes. In case of system with memory mapped I/O, this function can be */ +/* used to greatly speed up emulation */ +/****************************************************************************/ +#define Z80_RDOP(A) Z80_RDMEM(A) + +/****************************************************************************/ +/* Z80_RDOP_ARG() is identical to Z80_RDOP() except it is used for reading */ +/* opcode arguments. This difference can be used to support systems that */ +/* use different encoding mechanisms for opcodes and opcode arguments */ +/****************************************************************************/ +#define Z80_RDOP_ARG(A) Z80_RDOP(A) + +/****************************************************************************/ +/* Z80_RDSTACK() is identical to Z80_RDMEM() except it is used for reading */ +/* stack variables. In case of system with memory mapped I/O, this function */ +/* can be used to slightly speed up emulation */ +/****************************************************************************/ +#define Z80_RDSTACK(A) Z80_RDMEM(A) + +/****************************************************************************/ +/* Z80_WRSTACK() is identical to Z80_WRMEM() except it is used for writing */ +/* stack variables. In case of system with memory mapped I/O, this function */ +/* can be used to slightly speed up emulation */ +/****************************************************************************/ +#define Z80_WRSTACK(A,V) Z80_WRMEM(A,V) +