https://github.com/qemu/qemu
Raw File
Tip revision: f9baca549e44791be0dd98de15add3d8452a8af0 authored by Peter Maydell on 24 August 2021, 16:59:52 UTC
Update version for v6.1.0 release
Tip revision: f9baca5
slof.bin
؈(headermagic123"git-dd0dcaa1c108qemu0 !1噍7ÿÿÿÿÿÿÿÿ@(stage1H?Þ­¾à?||C¦|	¦|C¦|¦|C¦è`|	¦8N€ A@|C¦|	¦|C¦|¦|C¦èà|	¦8€N€ A@|C¦|	¦|C¦|¦|C¦è`|	¦8N€ A@|C¦|	¦|C¦|¦|C¦èà|	¦8€N€ A@|C¦|	¦|C¦|¦|C¦è`|	¦8N€ A@|C¦|	¦|C¦|¦|C¦èà|	¦8€N€ A@|C¦|	¦|C¦|¦|C¦è`|	¦8N€ A@|C¦|	¦|C¦|¦|C¦è`|	¦8N€ A@|C¦|	¦|C¦|¦|C¦è`|	¦8N€ A@|C¦|	¦|C¦|¦|C¦è`|	¦8N€ A@|C¦|	¦|C¦|¦|C¦è`|	¦8	N€ A@|C¦|	¦|C¦|¦|C¦è	`|	¦8
N€ A@|C¦|	¦|C¦|¦|C¦è
`|	¦8N€ A@|C¦|	¦|C¦|¦|C¦è`|	¦8N€ A@|C¦|	¦|C¦|¦|C¦è`|	¦8
N€ A@|C¦|	¦|C¦|¦|C¦è
`|	¦8N€ A@|C¦|	¦|C¦|¦|C¦è`|	¦8N€ A@|C¦|	¦|C¦|¦|C¦è`|	¦8N€ A@|C¦|	¦|C¦|¦|C¦è`|	¦8N€ A@|C¦|	¦|C¦|¦|C¦è`|	¦8N€ A@|C¦|	¦|C¦|¦|C¦è`|	¦8N€ A@|C¦|	¦|C¦|¦|C¦è`|	¦8N€ A@|C¦|	¦|C¦|¦|C¦è`|	¦8N€ A@|C¦|	¦|C¦|¦|C¦è`|	¦8N€ A@|C¦|	¦|C¦|¦|C¦è`|	¦8N€ A@|C¦|	¦|C¦|¦|C¦è`|	¦8N€ A@|C¦|	¦|C¦|¦|C¦è`|	¦8N€ A@|C¦|	¦|C¦|¦|C¦è`|	¦8N€ A@|C¦|	¦|C¦|¦|C¦è`|	¦8N€ A@|C¦|	¦|C¦|¦|C¦è`|	¦8N€ A@|C¦|	¦|C¦|¦|C¦è`|	¦8N€ A@|C¦|	¦|C¦|¦|C¦è`|	¦8N€ A@|C¦|	¦|C¦|¦|C¦è`|	¦8N€ A@|C¦|	¦|C¦|¦|C¦è`|	¦8 N€ A@|C¦|	¦|C¦|¦|C¦è `|	¦8!N€ A@|C¦|	¦|C¦|¦|C¦è!`|	¦8"N€ A@|C¦|	¦|C¦|¦|C¦è"`|	¦8#N€ A@|C¦|	¦|C¦|¦|C¦è#`|	¦8$N€ A@|C¦|	¦|C¦|¦|C¦è$`|	¦8%N€ A@|C¦|	¦|C¦|¦|C¦è%`|	¦8&N€ A@|C¦|	¦|C¦|¦|C¦è&`|	¦8'N€ A@|C¦|	¦|C¦|¦|C¦è'`|	¦8(N€ A@|C¦|	¦|C¦|¦|C¦è(`|	¦8)N€ A@|C¦|	¦|C¦|¦|C¦è)`|	¦8*N€ A@|C¦|	¦|C¦|¦|C¦è*`|	¦8+N€ A@|C¦|	¦|C¦|¦|C¦è+`|	¦8,N€ A@|C¦|	¦|C¦|¦|C¦è,`|	¦8-N€ A@|C¦|	¦|C¦|¦|C¦è-`|	¦8.N€ A@|C¦|	¦|C¦|¦|C¦è.`|	¦8/N€ A@|x}`¦9€ yŒƒÆ}kcx}`dL,8`
HE8`
H=8`
H58`SH-8`LH%8`OH8`FHHq8`I|i¦N€!xfÁÆ8`X8€8 D"N€ git-dd0dcaa1c1085c15èb€è#èA@èaHèPè¡XèÁ`èáhépé!xéA€éaˆéé¡˜éÁ éá¨ê°ê!¸êAÀêaÈêÐê¡ØêÁàêáèëðë!øëAëaëë¡ëÁ ëá(éÁ8}Ú¦éÁ@}Û¦éÁH}Ïñ è/ð|	¦è0è!8N€ |)¦< ø!þ¡øA@øaHøPø¡XøÁ`øáhùpù!xùA€ùaˆùù¡˜ùÁ ùá¨ú°ú!¸úAÀúaÈúÐú¡ØúÁàúáèûðû!øûAûaûû¡ûÁ ûá(ø0}ɦùÁ8}Ú¦ùÁ8}Û¦ùÁ@}À&ùÁH}Á¦ùÁPHÁèb€ø#|xH1éÁ8}Ú¦éÁ@}Û¦éÁH}Ïñ éÁP}Á¦èA@èaHèPè¡XèÁ`èáhépé!xéA€éaˆéé¡˜éÁ éá¨ê°ê!¸êAÀêaÈêÐê¡ØêÁàêáèëðë!øëAëaëë¡ëÁ ëá(è!8|B¦|	¦|B¦|¦|B¦L$è„øƒ`N€ |ˆ¦H¹[?25l **********************************************************************
QEMU Starting
 Build Date = Jul 12 2021 00:02:25
 FW Version = git-dd0dcaa1c1085c15
|h¦|ˆ¦H<


E1001 - Boot ROM CRC failure




E1002 - Memory could not be initialized




E1003 - Firmware image incomplete

       internal FLS1-FFS-0.


E1004 - Unspecified Internal Firmware Error

       internal FLSX-SE-0.|x|ž#x|½+x|Ü3x9@ãP9@‚(£ëx|J¦|c#xHáƒãx;€|#àA‚HÅH}è¦|#x8à|#8A‚HÙ}B¦,A‚4HxèÄ}B¦8à|'0A‚8àè„|' 8`A‚P|ˆ#x|qB¦ùèˆ8à|' A‚|„øèˆøèˆøèˆ|„ø(8ˆ ø 8`~ƒx}è¦N€ }è¦|°+x|±+xH9,@‚}è¦N€ |ɦ:ÿÿ8¥ÿÿŽEžPBÿø~%‹x}è¦N€ }(¦|ˆ#x|jx|…#x8¥ |«+xHE,@‚ è¤,|„*@‚ÿÔ8`}(¦N€ 8`è¤èÄèä|¥B}(¦N€ 9Jÿø9kÿøéª	éË	|-p9€A‚N€ qÎÿ@‚ÿä9€N€ ø!ÿ±|¦ø0ùá8ùÁ@ù¡H|¯+xKÿÿYè0|¦øø¯øÏøïé¡HéÁ@éá88!PN€ }¦|ixˆi,A‚H	9)Kÿÿì}¦N€ }¦|ixy#' pc,
A€8c8c0HÕy#F pc,
A€8c8c0H¹y#e pc,
A€8c8c0Hy#„ pc,
A€8c8c0Hy#£ pc,
A€8c8c0Hey# pc,
A€8c8c0HIy#á pc,
A€8c8c0H-y#"pc,
A€8c8c0Hy#'pc,
A€8c8c0Hõy#Fpc,
A€8c8c0HÙy#epc,
A€8c8c0H½y#„pc,
A€8c8c0H¡y#£pc,
A€8c8c0H…y#Âpc,
A€8c8c0Hiy#ápc,
A€8c8c0HMy#pc,
A€8c8c0H1}¦N€ }¦|ixKÿÿ}¦|ixKÿÿt}¦|ixKÿÿ xfÁÆ8`X8€8 D"N€ |jx8`T8€D"|ƒ#yA‚x£F ˜jN€ <``cxcÆdc`c‚<€`„x„Æd„`„€T„èÿA‚8 |‰¦ø£	Bÿü< `!x!Æd!`!8a€|¦øH58`äûxHé< `!x!Æd!`!8!€èa|h¦N€ <@`BxBÆdB`B„N€ |fx8`8€< `¥D\Kÿúá|„8„Tc0T„0|ƒ PT„Éþ|‰¦|l|¬|¬|¬L,8c€BÿèN€ ``B|¦øø!ÿ‘="ÿÿxjÉÂøA(9)|yJ$})R=ÿÿøh|é),)A‚,éIéi}I¦èIN€!èA(8!pè|¦N€ 9 /ðé),)@‚€<‚ÿÿè„|<bÿÿ8c÷hHÑ`|º¦<bÿÿx¤"8c÷€H¹`|»¦<bÿÿx¤"8c÷˜H¡`|²B¦<bÿÿx¤"8c÷°H‰`|³B¦<bÿÿx¤"8c÷ÈHq`HKÿõy`Kÿÿ|€```B="ÿÿ|c>t9)|xc$|iøƒN€ ``B|¦ûAÿÐûaÿØûÿàû¡ÿèûÁÿðûáÿøøø!ÿ8 ||x|ž#x<bÿþ8c|<‚ÿÿ8„÷HøA(H+
`,#@‚Ð,>A‚è?þÿ¿< @{ÿä8€ãûx;aH-`9 =Bÿÿ<bÿÿ8cø ù*~èH`<bÿÿäûxeÛx8cøHKÿúa`|dy@‚ìé!˜?Bÿÿ;¡p;Zø€¥ëxCÓxäûxû‰Kÿú1`,#@‚ü血èx8`H­`éA€9 }JJ9JU)0UJ0}IPPUJÉþ}I¦|Hl|¬|O¬|¬L,9)€Bÿè<bÿÿäûxeÛx8cø¨Kÿù½`|dy@‚<Ÿþ4„@èa˜<âÿÿ8À8çúX¥ëxH•`<¢ÿÿ<‚ÿÿ<bÿÿ8¥øè8„øð8cøøHu`é!pù!xL,|¬é!p<ÀePé}äûxÇóxÃóx`ÆAP8 })¦è]N€!èA(L,|¬8!ðèëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ ```B<bÿÿ8c÷èHé`Kÿõ%`,>@‚þ <bÿÿ8c÷ðH)`Kÿþ```B<bÿÿ8cøXH©`<Ÿþ4„Aþð<bÿÿø°8cø¸Hé`聰KÿþÔ``B<bÿÿ?Bÿÿ8cøX;Zø€Ha`é!˜;¡pCÓx¥ëxäûxû‰Kÿø9`,#A‚þ<bÿÿDÓx8cøˆH%`KÿþH€|¦øûáÿøø!ÿ|?x|ix™?°‰?°}#KxKÿúI``8?€è|¦ëáÿøN€ €|¦øûáÿøø!ÿq|?x|ixøŸÈø¿Ð‘?Àé?Èù?x?À,	A‚?À,	A‚9 H`9 ù?pH@é?x‰)(	
@‚8`
KÿÿEé?x9Iù_x‰)}#KxKÿÿ-é?p9)ù?pé_pé?Ð|*H@A€ÿ¸é?p}#Kx8?è|¦ëáÿøN€ €|¦ùÁÿpùáÿxúÿ€ú!ÿˆúAÿøø!ÿ|hx|€#x|x}CxKÿõA`8!èéÁÿpéáÿxêÿ€ê!ÿˆêAÿ|¦N€ €N€ `C= Ea)LF|
H@‚°ûáÿøø!ÿ|x‰#,	A‚‰#(	A‚l(	A‚D¡?9)ÿþU)>(	A€¡?9)ÿìU)>(	A|ˆ8!€ëáÿøN€ ``B|¦øH	`è|¦Kÿÿ¨`B|¦øHé`è|¦Kÿÿˆ`B8`ÿÿN€ ``B8`ÿýKÿÿ˜``B8`ÿüKÿÿˆ€```B|¦ûaÿØûÿàû¡ÿèûÁÿðûáÿøøø!ÿa|#x|¼+x|Û3x|~xKÿþÑ,|xA‚D,A‚œè}8!  c|cèã8ëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ `BfÛx…ãx8€ÃóxHQ`ø}‰>,	A‚ÿ¨8!  c;à|cèã8ëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ `BfÛx…ãx8€ÃóxH
1`ø}‰>,	A‚ÿHÃóxHÕ`Tc¾,è}A‚@8!  c;à|cèã8ëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ ``B;àKÿþè€```B|¦ûAÿÐûaÿØûÿàû¡ÿèûÁÿðûáÿøøø!ÿQ|œ#x|º+x|Ý3x|û;x|~xKÿýI,|xA‚Œ,@‚PÃóxH=`fÛx¥ëx|ƒàPÃóxøpH	1`èp„ÃóxûšH©`‰>,	@‚˜8!°ãûxèëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ ``BÃóxH}`fÛx¥ëxƒàPÃóx„ãxHq`8!°ƒâãûxûšèëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ `BÃóxH-`8!°T¾èëAÿÐëaÿØëÿàkÿë¡ÿèëÁÿðÿ4|¦WÿÙ~;ÿãûxëáÿøN€ €``BC= Ea)LF|
H@‚|¦ûáÿøøø!ÿ|x‰#,	A‚‰#(	A‚„(	A‚l¡?9)ÿþU)>(	Ax¡?9)ÿìU)>(	Ad‰?(	A‚x(	@‚PãûxH	y`8!€èëáÿø|¦N€ ```BH
Ñ`Kÿÿ`BHÁ`Kÿÿ€`B8!€8`ÿÿèëáÿø|¦N€ ``BãûxHÍ`8!€èëáÿø|¦N€ 8`ÿÿN€ €```B($@|m
E,
LF@‚lø!ÿ‘‰#(	A‚<(	A‚8`ÿÿ8!pN€ `B|¦ø€Hy`è€8!p|¦N€ |¦ø€HI`è€8!p|¦N€ 8`ÿÿN€ €```|¦ûÿÀû!ÿÈ}€&ûAÿÐûaÿØûÿàû¡ÿèûÁÿðûáÿøø‘ø!ÿQ; .%-¦øA(|~x|»+x|Ù3x|š#xƒããúH ¡,9=¡^*}=´|HÿRA€Ð?,	@‚ÿ܀¿€Ÿ| @š*ƒãx@‚ôƒA’(é;€Ÿé{})¦è[N€!èA(,#@‚ÿ˜€¿|žÂƒãxHÙ`€€¿8€|£(P|câx¥ HÙ`€Ÿ,$A‚ÿXƒãxAŽÿPé9éy})¦èYN€!èA(¡,9=¡^*}=´|HÿR@€ÿ88!°€~聁ëÿÀë!ÿÈëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦}‘ } N€ ``B<bÿÿ8cùH	`8!°8`聁ëÿÀë!ÿÈëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦}‘ } N€ €`B¡,#9H}#JqG9A‚ €é,A‚P,¡*})BA‚LUJø~9JÿÿyJ 9J}I¦H¡*}I@n,
A‚})BB@I,
@‚ÿà€iN€ `B8`N€ ```B€c$N€ ```Bû¡ÿèûÁÿð9#8ã.ûáÿø9 N,9#| >,8ã0ÀN,9#|À>,8ã2}@L,9#|à>,}€L,9# àL,9#$|L,9#(}`N,9#*|€N,9#,} N,‘C9C³£³Ã}@T,‘ƒ“㠐$±c(°ƒ*°£.°Ã0°ã2‘C±#,yI }#J```B9IàL,}€T,9I|T,9I}`T,9H9	|€D,9	| D,9	|ÀD,9	|àD,“é}H´‘‰	‘i‰©Éé Ã, ã*|P}):@€ÿŒë¡ÿèëÁÿðëáÿøN€ ```B($|£"@¡#(,	4@‚ûÿàû¡ÿèûÁÿðûáÿø‰#¡c*(	}CBA‚(U
À>UiÆ>Q
BQ
F>UhD.})CxyJ U+>}CR9#,£ƒ,98À#Ë N,#ëA‚h©ëx}JZˆH@9~ª(@y @œhA•P|êð.}*ø.A‚$TìÀ>U À>PìBQ BPìF>Q F>y‡ x	 }):y) ¦H@@œÿ¤}&Kx@‚ÿ ‰ãx}JZˆH@9~ª(@y Aœÿ # ¡c.A‚U*À>UhD.Q*BQ*F>UiÆ>})CxyJ U+>}CR9#0£ƒ09#Ë#ë N,`BA‚h©ëx}JZˆH@9~ª(@y @œhA•€|êð.}*ø.A‚$TàÀ>U#À>PàBQ#BPàF>Q#F>x xi }):y) ¦H@@œÿ¤}&Kx@‚ÿ ‰ãx}JZˆH@9~ª(@y Aœÿ 8fxcd|$@@€```B8`ÿÿëÿàë¡ÿèëÁÿðëáÿøN€ ``B}CJKÿÿ 8`ÿÿN€ `|¦ûÿÀû!ÿÈ}€&ûAÿÐûaÿØûÿàû¡ÿèûÁÿðûáÿøø‘ø!ÿQ; .%-¦øA(|~x|»+x|Ù3x|š#xëã ãúH ¡89=¡^6}=´|HÿRA€Ì?,	@‚ÿÜè¿èŸ|% @š*ƒãx@‚ôëA’(é;èŸ(é{})¦è[N€!èA(,#@‚ÿ˜è¿ |žÂƒãxH
™`è è¿(8€|£(P||H	`èŸ(,$A‚ÿ\ƒãxAŽÿTé9éy})¦èYN€!èA(¡89=¡^6}=´|HÿR@€ÿ<8!°è~聁ëÿÀë!ÿÈëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦}‘ } N€ ```B<bÿÿ8cù@H
É`8!°8`聁ëÿÀë!ÿÈëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦}‘ } N€ €`B¡8é# 9H}#JqG9A‚ €é,A‚P,¡6})BA‚LUJø~9JÿÿyJ 9J}I¦H¡6}I@n,
A‚})BB@I,
@‚ÿàèiN€ `B8`N€ ```B|¦úáÿ¸ûÿÀû!ÿÈûAÿÐûaÿØûÿàû¡ÿèûÁÿðûáÿøøø!ÿA;?‚ÿÿ?¢ÿÿëÃ(|x|™#x;œù ;½ù€Ãò;~H `B¡_<98;{@}8´|
HA€Œ;,	@‚ÿà;(y)6d}>Jé)q)A‚ÿÈè»,%A‚ÿ¼‚û$;@8Àz÷6d~þº`Bé; 8è÷è |ÆJ8c}2|jxqI}?è‹xˆ"}:|ÿBA‚ }.,A‚\,#¡6})BA‚˜UJø~9JÿÿyJ 9J}I¦H(```B¡6}I@n,
A‚})BB@\I,
@‚ÿà}_0*é)|*H@A€Pé+(@é}YRx„ }9J})BA0<âÿÿ8çÜ`xˆd}Bª}:}	¦N€ Фܘ   ŒÀ°     „ì    ```BƒãxH
`è»é;4IÒ{Z |:(@FÓxA€ýÜ¡_<98;{@}8´|
H@€ý|8!Àèêáÿ¸ëÿÀë!ÿÈëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ é*})Êù*è»KÿÿŒU(þy)„}(J±*è»Kÿÿty)„ ±*è»Kÿÿdy)"±*è»KÿÿT‘*è»KÿÿHy)„±*è»Kÿÿ8U):±*è»Kÿÿ(`B}_0*KÿýÀ``B£ëxH
`è»Kÿÿ€	û¡ÿèûÁÿð9#8ã:ûáÿø9 N,9#| >,8ã<ÀN,9#|À>,8ã>}@L,9#|à>,}€L(9#(àL(9#0|L,9#4}`N,9#6|€N,9#8} N,‘C9C ³£³Ã}@T(ùƒûã(0±c4°ƒ6°£:°Ã<°ã>ùC ±#8}#R9IàL,}€T,9I|T(9I}`T(9H9	|€D(9	 | D(9	(|ÀD(9	0|àD(“é}H´‘‰ø	ùiø‰ø© øÉ(øé0 Ã8 ã6|P}):@€ÿŒë¡ÿèëÁÿðëáÿøN€ ```B€c0N€ ```B($|£"@¡#4,	@@‚„ûaÿØûÿàû¡ÿèûÁÿðûáÿø‰#éC ¡c6(	}RA‚<yI"UHÀ>QHBU'À>QHF>Q'BQ'F>UjD.UiÆ>yÆ};x})Sx}BU+>9#8£Ã89@8À!‹àN,  ``BA‚”éûx}ZŠH@9J~¨(@yJ @œ”A•°|è`*}(*A‚Txü"|ý;xTçÀ>W›À>S§BS›BS§F>S›F>}=Kxy<"xçÆU)À>|çÛxS©BW›À>S©F>S›By)ÆS›F>})Ûx}):¦H@@œÿx}&Kx@‚ÿtÉóx}ZŠH@9J~¨(@yJ Aœÿté#(¡c:A‚8y*"U(À>Q(BUGÀ>Q(F>QGBQGF>UiÆ>UjD.yÆ};x})Sx}BU+>9#<£Ã<9@  k àN,`BA‚”éûx}ZŠH@9J~¨(@yJ @œ”A• |è*}(*A‚Txü"|ý;xTçÀ>W›À>S§BS›BS§F>S›F>}=Kxy<"xçÆU)À>|çÛxS©BW›À>S©F>S›By)ÆS›F>})Ûx}):¦H@@œÿx}&Kx@‚ÿtÉóx}ZŠH@9J~¨(@yJ Aœÿt8fxcd|$@@€8`ÿÿëaÿØëÿàë¡ÿèëÁÿðëáÿøN€ `B}JKÿÿ8`ÿÿN€ `,%9#ÿÿT„>M‚ pª9Eÿÿ@‚(xªøB}I¦9I˜‰9)˜ŠBÿðN€ `B,*˜ƒ|ix@‚ÿÐN€ ,%M‚ p©9Cÿÿ9$ÿÿ9ÿÿ@‚8x¨øB}	¦ˆÉ8é9
9)9J˜Êÿÿˆç˜èBÿàN€ `B,(‰|‰#x|jx™@‚ÿ¸N€ ``|$@@€\}$*|)@A€P,%M‚ pª9ÿÿ}C*@‚¨x¨øB}	¦ˆÉÿÿ8éÿÿ9
ÿÿ9)ÿþ9Jÿþ˜Êˆçÿÿ˜èÿÿBÿàN€ `B,%9$ÿÿ9CÿÿM‚ p¨9ÿÿ@‚8x¨øB}	¦ˆÉ8é9
9)9J˜Êÿÿˆç˜èBÿàN€ `B,(‰|‰#x|jx™@‚ÿ¸N€ `B,(	ÿÿ
ÿÿ@‚ÿPN€ |¦øø!ÿ‘|kx<bÿÿ8cýÐø¨}d[xø¡°8¡¨øÁ¸øáÀùÈù!ÐùAØH%`8!pè|¦N€ €|¦ûÁÿðûáÿøøø!ÿ?Âÿÿ;ÞýÐøa°ëþHm`聰|exãûxKÿå­`<‚ÿÿ8 8„ùÐ|xè~Kÿå‘`8!€ã´èëÁÿðëáÿø|¦N€ €```‰#,	A‚H|ix!```B|hJI|c´,
M‚ |hJI|c´,
@‚ÿÜN€ `B8`N€ ```|¦û¡ÿèûÁÿðûáÿøøø!þ1;Áp|¦+x|}x|…#xÃóx8€@HÁ`Äóx|xè}åûxKÿä`8!Ðãûxèë¡ÿèëÁÿðëáÿø|¦N€ €`|¦û!ÿÈûAÿÐûaÿØûÿàû¡ÿèûÁÿðûáÿøøø!ÿQ||x|ß3x|£+x|›#x8 
8€ë<|ý;x}Cx}>KxH	ñ`,?|c´A‚°9@H`````B|=ø@9Jÿë’}J´@ÿðyJ }^R|P@@}JPé<9JÿÿyJ 9J}I¦H›Ié<9)ù<B@}YHP|*Ø@A€ÿä8!°èë!ÿÈëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ `B9@Kÿÿ„€```B}€&ûAÿÐû¡ÿèûÁÿðûáÿø‘ø!ÿQ="ÿÿ|½+y9)ùØ|zx|ß3xéIéiùApùaxA‚àªëx9 `B|*ø@9)}Jû’})´@€ÿð}>Kx|$ð@A€|¦ûûaˆ.'ÜóxøÀH`B|=ø@é:}Ûx|iá®A€@}û’;œÿÿ};ùÒ})èP}!JˆipA’ÿÔH!`|=ø@é:}ÛxTc>|iá®@€ÿÈé:})òù:èÀëaˆë|¦8!°ëAÿÐë¡ÿèëÁÿðëáÿø} N€ `B;ÀKÿÿD€```BûÁÿðø!þ‘|~yøa A‚p,$8`A‚Ðùáèû¡XÏóx;¤ÿÿ‰%,)A‚˜=BÿÿúÁ û0:Áp9Jùøû!8ûáh; ùAÀH0```B™/}CxéA 9êùá ‰%,)A‚4þxP|?è@@€((	%9@‚ÿ̉%8á9H\``B(	iA‚l(	uA‚d(	xA‚\(	XA‚T(	pA‚L(	cA‚D(	sA‚<(	%A‚Ô(	OA‚,(	oA‚$'|¹+x8ˆ%}Cx|ˆ´(	d@‚ÿ”}BûP8c|c´9F™( |v9 ùAÈÿèP™# 놉‘9(ÿÒq)ýA‚„9  8á‘ù!¸,(A‚à|¦9 ú!øúaúá(ûA@ù!°}<ÐûaHúðúA::@ù!Ðú:€ø€ú¡}õ{x~ï¨P|?¸@@X9(ÿ±‹g;GU&>(+A<Âÿÿ8Æêày)¨}&Jª})2})¦N€ ððððððððððððððððððð°`ððð`ððpðððððpð`ðððxêÁ ë0ë!8ëáh9 ™/èa éáèë¡XÞPô8!pëÁÿðN€ ``B9(ÿÐU)>(		A}!¢:”GÓxz” ™	phÛx,(@‚þ¤è€~¯«xêðê!øêAêaêê¡êá(ëA@ëaH|¦èÁÈëP8¹Kÿý(u}!¢“ãxšIpA‚LéA°9UI89)ÿÿ}	H6‰H9A‚09 -™5yI$éAÀ~jH*é!Ð}3˜8é! 9)~ïHPù! é¸|—øP8à
~f›x~ųx9 ÃxKÿù©è ~e›x~ƒx8À
HPé!°éAÀ|Á¢|—øP8à~ųxšFpÃxy($9 ~ê@*鸗¸8~æ»xKÿùY聠~å»x~ƒx8À| PÃx|„øPKÿúiê¡ GÓxhÛx,(@‚ýdKÿþÀ```B}!¢8 
8€~óxšIpH=`|sxƒãxKÿ÷ý`zs |˜@xc A€Xêa ~ï˜P: ~÷øPH}ˆ®:1™é 9ù ƒãxKÿ÷µ`|1@@€ÿdê¡ }¨P|7@@AÿÈGÓxhÛxKÿÿT``B:é!°éAÀ|Á¢|—øP8à~ųxšFpÃxy($9 ~ê@*鸗¸8~æ»xKÿø5聠~å»x~ƒx8ÀKÿþÜ```B(lA‚ì9 GÓxhÛxù!°KÿþÐ`B(hA‚¼9 GÓxhÛxù!°Kÿþ°`B|¡¢9 9 8à
šEp|—øP8À~ųxÃxKÿ÷­é! GÓxhÛx›‰ê¡ :µú¡ Kÿþd``B|¡¢ùÁà|—øP9 9 šEp8à†ãx~ųxÃx9ÀKÿ÷Uê¡ >"ÿÿ:1ùï~ï¨P:q~÷øPH,`B}5 P|7H@@419Ι$é! 9)ù! ~c›xKÿö`聠|.@A€ÿÈ| P~ƒx|„øP8À…ãxÃxKÿø
ê¡ éÁàGÓxhÛxKÿý `B99 %8¹ù ™/`Béá Kÿù˜9 0‰’8á’ù!¸Kÿú|```B|c˜P~÷øPêa 9#ÿÿy) 9)})¦H9  ™3êa :súa B@ý|}5˜P|7H@AÿàKÿýl``B9 ù!°Kÿüü9 ù!°Kÿüì8!p8`ëÁÿðN€ €`9#ÿŸ(	M 8cÿà|c´N€ ```,$|ixA‚H($ù$A<àxçƒä`ç&H``BA‚à9)ù$‰I+Š |èT6q@ÿä,%@‚Ì(
0@‚8‰I8 
,
xA‚ì9@0```B8`H4``B}4|(9)}EÒL€ ù$|hR‰I,*M‚ 9
ÿÐ8êÿŸU>Tç>(	+‡}4@ÿÀ8êÿ¿9
ÿ©@ÿ°Tç>9JÿÉ(}H4M |(9)}EÒA€ÿ N€ `B,%A‚,``B,A‚D,*@‚ÿT8`N€ ``B8 
Kÿÿä``B8ÿðKÿþ¸9	ù‰I}	Cx(
08 @‚ÿ¸‰I,
x@‚þô9	ù‰I}	CxKÿÿ˜8 
Kÿþè``|¦< Dûáÿø8`(`¥"8€øH9` }ˆ¦}kb«|Xl|¬|_¬L,è8cëáÿø|ct|¦xcтN€ `B|¦û¡ÿèûÁÿðûáÿøøø!ÿq|¿+y|~x|#xA‚|_mIH,	A‚LKÿÿY,#A‚l<àÿÿ8`< <xç |?ðÄóx@d=@àaJH`B;ÿÿü|?ð@H?|	P@‚ÿì?,	@‚ÿà?,	@‚ÿԁ?,	@‚ÿȁ?,	@‚ÿ¼äûxþûx|= ¦ëx@”ÊðøÉóx}]RyJ÷â|8A‚,9>|)è@€0,*A‚I|
8A‚ð9)|)èA€ì```B,#A‚¼< h= "`¥|a)DÊðø8€}J2yJ÷â|HA‚<;Þ|>0@€,*A‚H^|
HA‚°;Þ|>0A€0HÜ```B9^|HA‚p;Ê|>0@€´^|
H@‚ÿܐ¾Êóx|ˆ#x}R9UJ0U0}
@PUÉþ}	¦|Pl|¬|W¬|¬L,9J€Bÿè9^|H@‚ÿ˜¾}HSx|‡#x|çB8çU0Tç0|è8PTçÉþ|é¦|@l|¬|G¬|¬L,9€Bÿè;Ê|>0A€ÿT8!8`èë¡ÿèëÁÿðëáÿø|¦N€ `BKÿý,#A‚$8àÿÿ8`8 <xç Kÿý¸Kÿüñ,#@‚¨8!8`èë¡ÿèëÁÿðëáÿø|¦N€ `BI|
(A‚PI9)}(Kx|
8A‚09(|)è@€þ(I|
8A‚ÿ́I9)}(Kx|
8@‚ÿ؁I|
(@‚ÿÌ,#}&KxA‚8< h= "`¥|a)DH$``B< |= D¦ëxÄóx`¥ha)"|$0@€þðÊðø8€}J2yJ÷â|H@‚ý̐¾Èóx|‡#x|çB8çU0Tç0|è8PTçÉþ|é¦|@l|¬|G¬|¬L,9€BÿèKÿý„```B< |= D`¥ha)"KÿýHI|
(@‚ýKÿÿ(```B|(@‚üÐKÿÿ¾Êóx|ˆ#x}R9UJ0U0}
@PUÉþ}	¦|Pl|¬|W¬|¬L,9J€BÿèKÿý< |= D`¥ha)"Kÿþð€
 exception %llx 
SRR0 = %08llx%08llx  SRR1 = %08llx%08llx 
SPRG2 = %08llx%08llx  SPRG3 = %08llx%08llx 


SLOFERROR: Flatten device tree not available! Press "s" to enter Open Firmware.

bootinfo  !!! roomfs lookup(bootinfo) = %d
xvectCannot find romfs file %s
ofw_mainERROR: Not enough memory for Open Firmware[?25h%s%sELF32: VirtAddr(%lx) != PhysAddr(%lx) not supported, aborting
ELF64: VirtAddr(%lx) != PhysAddr(%lx) not supported, aborting

ELF relocation out of bounds!
ERROR: Unhandled relocation (A) type %i

0123456789abcdef0xÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ@”„Ià„J0„K@„Kp„Nt„NÄ„O„P„Q„R€„T„U@„Uà„WЄXp„X„Yð„\ „^„^°„b„cà„d„f°„g„g„h€„hà„ip„ià„j`„k„lЄtp„t „vP„vÀ„ðP@P„èÿÿÿÿÿÿÿÿ?0?(xvectè`/ð|i¦8N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8€N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8€N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8€N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8	N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8
N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8
N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8 N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8!N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8"N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8#N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8$N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8%N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8&N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8'N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8(N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8)N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8*N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8+N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8,N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8-N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8.N€ |C¦|	¦|C¦|¦|C¦è/ð|	¦8/N€ 6ÿÿÿÿÿÿÿÿ
ßP
ß0ofw_mainELF@
ÛX@8@NÔ²¿?àcÿÄø?àcÿÄøŸ?àcÿÄøß?àcÿÄøÿ|¦|¦<``cècø`/ð<``c<€`„ü8 HåH |1C¦BŸ|(¦è!ÿðøAøaø ø¡(øÁ0øá8ù@ù!HùAPùaXù`ù¡hùÁpùáxú€ú!ˆúAúa˜ú ú¡¨úÁ°úá¸ûÀû!ÈûAÐûaØûàû¡èûÁðûáø8`|x|B¦ø|B¦ø,	@‚|¶¦<ÿ|¦|&ø|¦ø|B¦ø|B¦ø|¦ø |¦ø(|¦ø0|¦ø8BŸ
©
|H¦è"|!8øÿñø!ÿ<@èÄ`|¦èBÄhL$|¦BŸ ¼}¦|¦è}Bèø(|xèøH|xèøh|xè øˆ |xè(ø¨(|xè0øÈ0|xè8øè8|xèhù¨h|
xèpùÈp|xèxùèx|xè€ú€|xèˆú(ˆ|xèúH|xè˜úh˜|xè úˆ |xè¨ú¨¨|xè°úÈ°|xè¸úè¸|xèÀûÀ|xèÈû(È|xèÐûHÐ|xèØûhØ|xèàûˆà|xèèû¨è|xèðûÈð|xèøûèø|xè} &|ñ ù(è(} ¦|d|¬L,ù((N€ |ˆ¦Kÿþu|ˆ¦8`N€ |ˆ¦|i¦Kÿþ],
A‚N€!H } ¦i­}»¦}©¦}¬kx}º¦L$Kÿþ-|ˆ¦8`ÿÿN€ [?25lQEMU Starting
 Build Date = Jul 12 2021 00:02:25
 FW Version = git-dd0dcaa1c1085c15
`````|„8„Tc0T„0|ƒ PT„Éþ|‰¦|l|¬|¬|¬L,8c€BÿèN€ ``B|¦øø!ÿ‘Hmi`8!pè|¦N€ €,$M‚ |¦øø!ÿ‘Tc>Hm1`8!pè|¦N€ €`B(A<#=B9Jç8`ÿÿ}
H.,M‚ 98`}
I.N€ ```B8`ÿÿN€ ```B|¦ùÁÿpùáÿxúÿ€úaÿ˜úÿ ú¡ÿ¨úÁÿ°úáÿ¸ûÿÀû!ÿÈøûAÿÐûaÿØûÿàû¡ÿèûÁÿðûáÿøø!þÑ?â?B;ÿç|{x|ž#x;Zç?ƒ,	@‚@<Âÿý8Ɵ,9@`8â³è9ƒø‘_ƒ9?©9_¤øß©`ùƒù_¤ù?©øâ³à="¦9)‡9Ax|*H@@€?© ,	A‚AØsiA‚é?ƒ9Iø©ù_ƒsiA‚é?ƒ9IûÉù_ƒsi@‚lsi@‚Ð``9"³:â²X}*Kxù!xëª97à>Âÿÿ;Z;€ù!9?d:Ö[ëÝ:¡p:Ÿuù!˜:„}0Kx9ÿÔ9ßÐɦN€ si8`A‚é?ƒ9Iÿøù_ƒèi8!0èéÁÿpéáÿxêÿ€êaÿ˜êÿ ê¡ÿ¨êÁÿ°êáÿ¸ëÿÀë!ÿÈëAÿÐ|¦ëaÿØëÿàë¡ÿèëÁÿðëáÿøN€ é¤`9?©8â²x`|ê;x:â²Xøáx8èù(øÿ¤Kÿÿ éAxé?ƒëª8Éÿøè©8éÿð9J9	ÿèëÝø߃ùAxè‰ÿøøÿƒèiÿðùƒHfý`ɦN€ é!x럃ë©9\ÿøèœ9)ù!xëÝù_ƒè|ÿøHd¥`ɦø|ÿøN€ é!x럃ë©9ÿøè¼9\ÿð9)ëÝùƒù!xèœÿøù_ƒè|ÿðHc=`ɦø|ÿðN€ é!xéƒ9_ºë©8è9)ù!xëÝøÿƒùHɦN€ é!xéƒ9_ªë©8è9)ù!xëÝøÿƒùHɦN€ é!xé_ƒë©9)9
ù!xé!˜ëÝùƒù*ɦN€ é!xé_ƒë©9
9)ù!xëÝú
ùƒÉ¦N€ é!xé_ƒë©9
9)ù!xëÝùêùƒÉ¦N€ é!xé_ƒë©9
9)ù!xëÝùÊùƒÉ¦N€ é?¤éAx9ùxùI9)ù?¤ë½ëÝɦN€ é!xé_ƒétë©8ê9)ù!xëÝøÿƒù
ɦN€ é!xé_ƒétë©8ê9)ù!xëÝøÿƒù
ɦN€ é!xé_ƒétë©8ê9)ù!xëÝøÿƒù
ɦN€ é!xé_ƒétë©8ê9)ù!xëÝøÿƒù
ɦN€ é!xé_ƒéÀë©8ê9)ù!xëÝøÿƒù
ɦN€ é!xé_ƒé¸ë©8ê9)ù!xëÝøÿƒù
ɦN€ é!xé_ƒ=ÿý9˜ë©8ê9)ù!xëÝøÿƒù
ɦN€ éxé_ƒë¨é*8èøáxëÝy)$!)ÿøɦ}*H*ù*N€ é!xé_ƒë©èêÿø9)9
ù!xëÝøêùƒÉ¦N€ é!xé_ƒë©èê9)9
ù!xëÝøêùƒÉ¦N€ é!xé_ƒé	8Ê8éø߃øáxù
ë©ëÝɦN€ é!xé_ƒé	8Ê8éø߃øáxù
ë©ëÝɦN€ é?¤éAxéùI9)ùxù?¤ë·àëÝɦN€ é_ƒéxèê9(,'@‚<<é9Jÿøù_ƒ})B9)ë©ù!xëÝɦN€ é!xéI9)})R9Ië©ùAxëÝɦN€ é?ƒ;½éAxû©9)9
ù?ƒùxëªëÝɦN€ é?ƒ;½éAxû©9)9
ù?ƒùxëªëÝɦN€ éƒèýéAxé(8ÊøÁx}):ù(ëªëÝɦN€ éé?ƒéAxù	9)9
ù?ƒùxëªëÝɦN€ éé?ƒéAxù	9)9
ù?ƒùxëªëÝɦN€ ë½ëÝɦN€ ë½ëÝɦN€ é?¤èáxé_ƒ9øé9)8êù?¤øÿƒé=ù
ù!xë©ëÝɦN€ é!xé_ƒë©é
9)ù!xë݁(ɦy( ‘!pù
N€ éAxé?ƒëªèéÿø9Jé	9)ÿðùAxëÝxêÂù?ƒ˜è™HɦN€ é!xé_ƒë©é
9)ù!xëÝ¡(ɦU(>±!pù
N€ éAxé?ƒëªé	èéÿø9J9)ÿðùAxëÝù?ƒøèɦN€ é!xé_ƒë©é
9)ù!xëÝé(ɦù*N€ éAxé?ƒëªé	€éÿü9J9)ÿðùAxëÝù?ƒèɦN€ é!xé_ƒë©é
9)ù!xë݁(ɦù*N€ éAxé?ƒëªé	 éÿþ9J9)ÿðùAxëÝù?ƒ°èɦN€ é!xé_ƒë©é
9)ù!xëÝ¡(ɦù*N€ éAxé?ƒëªé	ˆéÿÿ9J9)ÿðùAxëÝù?ƒ˜èɦN€ é!xé_ƒë©é
9)ù!xë݉(ɦù*N€ éAxé?ƒëªé	èéÿø9J9)ÿðùAxëÝù?ƒøèɦN€ é!xé_ƒë©é
9)ù!xëÝé(ɦù*N€ é_ƒé!xé
ÿøèêë©9)ù!x}	:xëÝù*ÿøɦé?ƒ9)ÿøù?ƒN€ é_ƒé!xé
ÿøèêë©9)ù!x}	;xëÝù*ÿøɦé?ƒ9)ÿøù?ƒN€ é_ƒé!xé
ÿøèêë©9)ù!x}	88ëÝù*ÿøɦé?ƒ9)ÿøù?ƒN€ é_ƒé!xé
ÿøèêë©9)ù!x}	>4ëÝù*ÿøɦé?ƒ9)ÿøù?ƒN€ é_ƒé!xé
ÿøèêë©9)ù!x}	<6ëÝù*ÿøɦé?ƒ9)ÿøù?ƒN€ é_ƒé!xé
ÿøèêë©9)ù!x}	86ëÝù*ÿøɦé?ƒ9)ÿøù?ƒN€ é_ƒé!xé
ÿøèêë©9)ù!x}(9ÒëÝɦù*ÿøé?ƒ9)ÿøù?ƒN€ é_ƒé!xèêÿøé
ë©9)ù!x}(8PëÝù*ÿøɦé?ƒ9)ÿøù?ƒN€ é_ƒé!xé
ÿøèêë©9)ù!x}(:ëÝù*ÿøɦé?ƒ9)ÿøù?ƒN€ éxé_ƒèÿ¤ë¨é*8ÈøÁxëÝy)$})8Pɦé)ù*N€ éxé_ƒë¨é*99JÿøùxëÝy)$ù_ƒ9)ÿø}4Jɦù?¤N€ éAxé?¤éƒëª}4HP9J})t8è9)ùAxëÝøÿƒù(ɦN€ éAxé?ƒëªé)9JùAxëÝy)$9)ÿø}3Jɦù?ƒN€ é!xéƒë©8è9)}S8P}Jtù!xëÝøÿƒùHɦN€ é!xé_ƒé¤ë©8ê9)ù!xëÝøÿƒÉ¦é(ù*N€ é!xé_ƒé¤ë©8Ê9)8èÿøù!xëÝø߃ɦé(øÿ¤ù*N€ é!xé_¤éƒë©8Ê9)8èÿøù!xëÝøߤɦé(øÿƒù*N€ é_ƒé!xèêë©é
ÿø9)ù!xëÝøêÿøɦé?ƒù	N€ é!xé_ƒë©9Jÿø9)ù!xëÝù_ƒÉ¦N€ éAxé?ƒëªèi9J9)ÿøùAxëÝù?ƒH¯ù`ɦN€ é!xé_ƒë©èj9)ù!xëÝH«M`é?ƒ,#A‚7ɦøi9ÿÿé?ƒ9Iù	ù_ƒN€ é!xé_ƒë©8ªÿøèj8Šÿð8Êÿè9
ÿà9)8êÿØëÝø¿ƒù!xèªÿøøŸƒèŠÿðø߃é*ÿèùƒ0Éÿÿ|ÆIé
ÿàøÿƒèêÿØH¥‰`ɦé?ƒøiN€ éAxé?ƒëªèi9J9)ÿøùAxëÝù?ƒHª-`ɦN€ é!xé_ƒë©èj9)ù!xëÝH¨q`é?ƒÉ¦øiN€ é!x럃ë©9ÿøèœ9\ÿð9)ëÝùƒù!xè¼ÿøù_ƒè|ÿðH¡å`ɦø|ÿðN€ éAxé?ƒëªèi9J9)ÿøùAxëÝù?ƒH¡M`ɦN€ éAxé?ƒèÉëª8©ÿø8éÿð9	ÿè9JëÝø¿ƒùAxè©ÿøøÿƒè‰ÿðùƒèiÿèHŸ]`ɦé_ƒ|i4U)Ù~})Ðù*N€ éAxé?ƒ8àëª8Éÿøèi8©ÿð9	ÿè9JëÝø߃ùAxèÉÿøø¿ƒè©ÿðùƒè‰ÿèH˜e`ɦé?ƒøiN€ éAxé?ƒ8àëª8Éÿøèi8©ÿð9	ÿè9JëÝø߃ùAxèÉÿøø¿ƒè©ÿðùƒè‰ÿèH˜	`ɦé?ƒøiN€ éAxé?ƒëªèi9J9)ÿøùAxëÝù?ƒH—}`ɦN€ é!xé_ƒë©èj9)ù!xëÝH•Ñ`é?ƒÉ¦øiN€ é!x럃è¼ë©9ÿø9\ÿð9)ëÝùƒù!xèœÿþù_ƒè|ÿðH’e`ɦø|ÿðN€ é!xé_ƒèŠë©9
ÿø9)ù!xëÝùƒèjÿøHƒ9`ɦé?ƒøiN€ é!x럃ë©€|9)ù!xëÝH‚Õ`ɦø|N€ é!x럃ë©9\9)ù!xëÝù_ƒH€Q`ɦø|N€ é!xë©9)ù!xëÝHt©`,#A‚08ɦ=Bÿý9J/@é?ƒ=ÿý9/,Jù	9	ùƒùIN€ é!xé_ƒ8``cðë©èŠ9)ù!xëÝH|)`é?ƒÉ¦øiN€ éAxé?ƒëª8Éÿøè‰8éÿð9J9	ÿèëÝø߃ùAxèiÿøøÿƒè©ÿðùƒHta`ɦN€ éAxé?ƒëªèi9J9)ÿøùAxëÝù?ƒH{…`ɦN€ é!x럃ë©9ÿøè¼9\ÿð9)ëÝùƒù!xèœÿøù_ƒè|ÿðH|¡`ɦø|ÿðN€ é!x럃ë©8Üÿøèü8¼ÿð9ÿè9\ÿà9)ëÝø߃ù!xèÜÿøø¿ƒè¼ÿðùƒèœÿèù_ƒè|ÿàH|`ɦø|ÿàN€ éAxé?ƒ8`ëª8éÿøè‰9J9	ÿðùAxëÝøÿƒè©ÿøùƒH{½`ɦN€ é!x럃8`ë©èœ9)ù!xëÝH{i`ɦø|N€ éAxé?ƒ8`ëª8éÿøè‰9J9	ÿðùAxëÝøÿƒè©ÿøùƒx¥ H{A`ɦN€ é!x럃8`ë©èœ9)ù!xëÝHzí`ɦø|N€ éAxé?ƒ8`ëª8éÿøè‰9J9	ÿðùAxëÝøÿƒè©ÿøùƒT¥>HzÅ`ɦN€ é!x럃8`ë©èœ9)ù!xëÝHzq`ɦø|N€ éAxé?ƒ8`ëª8éÿøè‰9J9	ÿðùAxëÝøÿƒè©ÿøùƒT¥>HzI`ɦN€ é!x럃8`ë©èœ9)ù!xëÝHyõ`ɦø|N€ éAxé?ƒ8` ëª8éÿøèÉ9	ÿð9JëÝøÿƒùAxè©ÿøùƒ€‰ÿôHxÅ`ɦé?ƒøiN€ é!xé_ƒë©9
ÿøèŠ9)ù!xëÝùƒ€jÿüHy%`ɦé?ƒøiN€ éAxé?ƒ8`몀‰9
9)ÿøùxëÝù?ƒHxE`ɦN€ é!x럃8`üë©9ÿøèÜ9\ÿð9)ëÝùƒù!xè¼ÿøù_ƒ€œÿôHwý`ɦø|ÿðN€ é!xé_ƒèjë©9)ù!xëÝHx`é?ƒÉ¦øiN€ é!xé_ƒèjë©9)ù!xëÝHwµ`é?ƒÉ¦øiN€ éAxé?ƒëª8éÿøˆi9J9	ÿðùAxëÝøÿƒè‰ÿþùƒHwY`ɦN€ ú!¸é!xé_ƒë©ë*9
ÿø9)ù!xëÝùƒ,9ê*ÿøA‚1¼úAÀ:1ÿÿ2Ëx;€``BŒq{œ¤œÊxH€%`6Rÿÿ||âx@‚ÿäɦéƒ{‰hêAÀ}:Jù(ê!¸N€ é!xé_ƒë©9
9)ù!xëÝûJùƒÉ¦N€ é!x8 ÿÿCÓxT¥ 8€ë©9)ù!xëÝHzá`ɦN€ é!xé_ƒë©èj9)ù!xëÝHw5`é?ƒÉ¦9Iøiù_ƒN€ éƒéAxèèëª9(ÿø9JùAx,'ëÝù?ƒA‚(Èɦé(ÿøù(ÿðé?ƒ9)ÿøù?ƒN€ é!x迃ë©8Åÿøé8åÿð9)9EÿèëÝø߃ù!xë%ÿøøÿƒé%ÿðù_ƒ|(H@A‚/Äɦ9 ù%ÿèN€ éAxé?ƒëª8Éÿøè©8éÿð9J9	ÿèëÝø߃T¥>ùAxè‰ÿøøÿƒèiÿðùƒHrY`ɦN€ éAxé?ƒëª8©ÿøèé8Éÿð9	ÿè9JëÝø¿ƒùAxè‰ÿøø߃è©ÿðùƒ|©#x});xy)`()A‚,A4,)A‚)4()@‚08`xçøB`cð8À9D"ɦN€ ()A‚ÿÜ8`8À`cð9D"ɦN€ é!xé_ƒë©8êÿø8Êÿð9
ÿè9)ëÝøÿƒù!xèêø߃èŠÿøùƒ|‰;xèªÿð})+xy)`()A‚*ØA4,)A‚(l()@‚/P8`xçøB`cð8À9D"ɦN€ ()A‚ÿÜ8`8À`cð9D"ɦN€ è߃9Fÿø8¦ÿð9&ÿèù_ƒéø¿ƒ,(èæÿøù?ƒé&ÿð@'Èq}
Cx|é8P}J@‚'”yJøB}I¦H0``BA€+l9I‰	}*8®|H@A A€+T9*B@'|‰	}I8®|P@@ÿÐ9@ø¿ƒé!xùFÿð9IùAxë©ëÝɦN€ é?ƒ8éÿø9Iÿð9	ÿèøÿƒˆÉù_ƒxÊEä}J3xè©ÿøùƒyGƒä|êSx|¨+xé)ÿð}'+xxç`('A‚) ('A‚(ì,'A‚(€,%@*”pª9Eÿÿ@‚*ðy
øB}I¦9I˜É9)˜ÊBÿðé!xë©9)ù!xëÝɦN€ ```BéAxéƒëª8¨ÿøé(8èÿð9J8ÈÿèëÝø¿ƒùAxéHÿøøÿƒèèÿðø߃|èSx}Kxy`((A‚)hA ,(A‚&œ((@‚˜|*8@A€*ø|ÇJ|*0@@€*ì,)}
JA‚-9Iÿþ}CxqJ|Å3x@‚8¦ÿþ¡Fÿþ}J|&@µGÿþA‚,Ì …ÿþ9ÿþ8¥ÿü9Gÿþ°‡ÿþ|åJ|&88êÿþ¡ÿþ±
ÿþ@‚ÿØɦN€ ```B((A‚ÿp|*8@A€+D}J|*@@@€+8,)}JJA‚,lq'8éÿÿA‚,'ŒèÿÿœêÿÿA‚,Py)øB})¦ˆÈÿÿ8èÿÿ9*ÿÿ9ÿþ9Jÿþ˜Êˆçÿÿ˜éÿÿBÿàɦN€ ``Bé?ƒ9Iÿøù_ƒë©ëÝɦN€ é?¤9Iÿøù_¤é)ë©9)ù!xëÝɦN€ é?¤9Iÿøù_¤é)ë©9)ù!xëÝɦN€ é_ƒéx8êÿø9(éøÿƒù!xéJ,*A‚$é_¤})B9)ë©9Jÿðù!xù_¤ëÝɦN€ é!xé¤éI9ÿðù¤9J})R9Ië©ùAxëÝɦN€ èÿƒé¤é!x8ÇÿøéHè©9)ø߃èÇèè|ç2,&øèé¤A€%èˆèÈÿø}GPø|ç2}J P|'P@@€%9ÿðë©9)ù¤ù!xëÝɦN€ é¤é!xéHèÉ9)9JùHé_¤èêé
ÿø|'@A‚$à})29)ë©ù!xëÝɦN€ é_ƒèÁx9
ÿø8êÿð9&ùƒé
øÿƒèêÿø|(8A‚$¸é_¤9)øêù
8Êøߤë©ù!xëÝɦN€ éAxé?¤éƒëª8©9J8É8èÿðùAxëÝø¿¤É¦éHÿøøߤùIéHøÿƒùIN€ é!xéƒë©éH9)ù!xëÝ1Jÿÿ})Iɦù(N€ éƒéAxé(ÿøèèëª9JùAx}):xëÝ1)ÿÿ})Iɦù(ÿøé?ƒ9)ÿøù?ƒN€ éAxéƒëªé(9JùAxëÝ})þv})´É¦ù(N€ é_ƒé!xèêÿøé
ë©9)ù!x}8ëÝ})I})´É¦ù*ÿøé?ƒ9)ÿøù?ƒN€ èÿƒéxéGÿøé'ë¨9ùx}Hþv}IPëÝy)à})Aɦi)})Ð})´ù'ÿøé?ƒ9)ÿøù?ƒN€ èáxé?ƒë§é	ÿøéI8ç9)ÿðøáxëÝyF"ù?ƒy„"y	Â"™
˜Ê˜êɦ™*N€ é!xé_ƒë©9
9)ù!xëÝùƒ}6¦É¦ù*N€ éxé?ƒë¨9éIùxëÝ}V¦É¦9)ÿøù?ƒN€ éxé?ƒë¨8ÉÿøéI8éÿð9ëÝø߃ùxé)ÿøøÿƒ}JJ9JU)0UJ0}IPPUJÉþ}I¦|Hl|¬|O¬|¬L,9)€BÿèɦN€ é!x럃ë©8üÿøèÜ9ÿð9\ÿè9)ëÝøÿƒù!xè¼ÿøùƒèœÿðù_ƒè|ÿèHFù`ɦø|ÿèN€ é!x럃8 ë©9ÿøèÜ9\ÿð9)ëÝùƒù!xèœÿøù_ƒè|ÿðHF­`ɦø|ÿðN€ H```Bé!x럃ë©è|9)ù!xëÝKÿÙ­`ɦø|N€ éAxé?ƒëª9Jé	ùAxëÝ|@l|¬|G¬|¬L,ɦ9)ÿøù?ƒN€ é!xé_ƒë©9
9)ù!xëÝùƒ|¬}3¦É¦ù*N€ éAxé?ƒëª9Jé	ùAxëÝ|¬}æL,ɦ9)ÿøù?ƒN€ é!xé_ƒë©9
9)ù!xëÝùƒ}1J¦É¦ù*N€ éxé?ƒë¨9éIùxëÝ}QK¦É¦9)ÿøù?ƒN€ é!xé_ƒë©9
9)ù!xëÝùƒ}0J¦É¦ù*N€ éxé?ƒë¨9éIùxëÝ}PK¦É¦9)ÿøù?ƒN€ é!xé_ƒë©9
9)ù!xëÝùƒ}3B¦É¦ù*N€ éxé?ƒë¨9éIùxëÝ}SC¦É¦9)ÿøù?ƒN€ é!xé_ƒë©9
9)ù!xëÝùƒ}2B¦É¦ù*N€ éxé?ƒë¨9éIùxëÝ}RC¦É¦9)ÿøù?ƒN€ é!xé_ƒë©9
9)ù!xëÝùƒ}1B¦É¦ù*N€ éxé?ƒë¨9éIùxëÝ}QC¦É¦9)ÿøù?ƒN€ é!xé_ƒë©9
9)ù!xëÝùƒ}0B¦É¦ù*N€ éxé?ƒë¨9éIùxëÝ}PC¦É¦9)ÿøù?ƒN€ é!xé_ƒë©9
9)ù!xëÝùƒ}7J¦É¦ù*N€ éAxé?ƒëª9Jé	ùAxëÝ}K¦É¦9)ÿøù?ƒN€ é!xé_ƒë©9
9)ù!xëÝùƒ}5ú¦É¦ù*N€ éAxé?ƒëª9Jé	ùAxëÝ}û¦É¦9)ÿøù?ƒN€ é!xé_ƒë©9
9)ù!xëÝùƒ}-B¦É¦ù*N€ é!xé_ƒë©9
9)ù!xëÝùƒ},B¦É¦ù*N€ é!xé_ƒë©9
9)ù!xëÝùƒ}?ú¦É¦ù*N€ é!xé_ƒë©9
9)ù!xëÝùƒ}?B¦É¦ù*N€ é!xé_ƒë©9
9)ù!xëÝùƒ}9¦É¦ù*N€ éAxé?ƒëª9Jé	ùAxëÝ}¦É¦9)ÿøù?ƒN€ é!xé_ƒë©9
9)ù!xëÝùƒ} ¦É¦ù*N€ éAxé?ƒëª9Jé	ùAxëÝ}dɦ9)ÿøù?ƒN€ é!xé_ƒë©9
9)ù!xëÝùƒ}6ú¦É¦ù*N€ éAxé?ƒëª9Jé	ùAxëÝ}û¦É¦9)ÿøù?ƒN€ é!xé_ƒë©9
9)ù!xëÝùƒ}4ú¦É¦ù*N€ éAxé?ƒëª9Jé	ùAxëÝ|¬}û¦L,ɦ9)ÿøù?ƒN€ é!xé_ƒë©9
9)ù!xëÝùƒ}1ú¦É¦ù*N€ éAxé?ƒëª9Jé	ùAxëÝ}û¦}û¦L,ɦ9)ÿøù?ƒN€ é!xé_ƒë©9
9)ù!xëÝùƒ}0ú¦É¦ù*N€ éxé?ƒë¨9éIùxëÝ|¬}Pû¦}Pú¦}Pú¦}Pú¦}Pú¦}Pú¦}Pú¦É¦9)ÿøù?ƒN€ é!xé_ƒë©8êÿøé
8Êÿð8ªÿè8Šÿà8jÿØ9)ëÝøÿƒy ù!xèêÿøø߃èÊÿðø¿ƒxÆ èªÿèøŸƒ€Šÿäøƒ€jÿÜH<Ù`ɦé?ƒøiN€ éAxèƒëª9ÿø#8ãÿð8Ãÿè8£ÿà8ƒÿØ9cÿÐëÝùƒ9JùAxÿüøÿƒèãÿðø߃èÃÿèø¿ƒè£ÿàøŸƒ€ƒÿÜùƒ€cÿÔH;=`ɦé?ƒøiN€ é!xé_ƒë©9J9)ù!xëÝù_ƒHC`é?ƒÉ¦øiN€ éAxé?ƒëª8éÿøè‰9J9	ÿðùAxëÝøÿƒx„ èiÿøùƒH@é`ɦN€ éAxé?ƒëª8éÿøè‰9J9	ÿðùAxëÝøÿƒx„ èiÿøùƒH?`ɦN€ é!xë©9)ù!xëÝHEQ`ɦN€ é!xé_ƒë©9J9)ù!xëÝù_ƒHCa`é?ƒÉ¦øiN€ é!xé_ƒë©9J9)ù!xëÝù_ƒH3‰`é?ƒÉ¦øiN€ éAxé?ƒëª8éÿøè©9	ÿð9JëÝøÿƒx¥ ùAxè‰ÿøùƒ€iÿôH<`ɦé?ƒøiN€ é!xé_ƒë©9
ÿøèŠ9)ù!xëÝùƒx„ €jÿüH:µ`ɦé?ƒøiN€ é!xé_ƒë©9J9)ù!xëÝù_ƒH8í`é?ƒÉ¦øiN€ éAxé?ƒëªèi9J9)ÿøùAxëÝxc ù?ƒHC`ɦN€ é!xé_ƒë©9J9)ù!xëÝù_ƒHBý`é?ƒÉ¦øiN€ éAxé?ƒè‰ëª8éÿø9J9	ÿðùAxëÝøÿƒèiÿøùƒH7¥`ɦN€ é!xé_ƒë©9J9)ù!xëÝù_ƒH55`é?ƒÉ¦øiN€ é!xë©9)ù!xëÝH4Ù`ɦN€ é!xé_ƒë©9J9)ù!xëÝù_ƒH1ù`é?ƒÉ¦øiN€ é!xë©9)ù!xëÝH"`ɦN€ é!xé_ƒë©9
ÿøèŠ9)ù!xëÝùƒx„ èjÿøHŠñ`ɦé?ƒøiN€ éAxé?ƒëª8©ÿøèÉ8éÿð9	ÿè9JëÝø¿ƒxÆ ùAxè©ÿøøÿƒè‰ÿðùƒ|„´èiÿèHv!`ɦé?ƒøiN€ éAxé?ƒëª8Éÿøë‰8éÿð9	ÿè9JëÝø߃†ãxùAxè©ÿøøÿƒè‰ÿðùƒT„> iÿîHp‘`é?ƒ,#@‚ɦû‰9@9ÿÿé?ƒùI9Iù	ù_ƒN€ é!xé_ƒèŠë©9
ÿø9)ù!xëÝùƒèjÿøHn`ɦé?ƒøiN€ é!xé_ƒèŠë©9
ÿø9)ù!xëÝùƒèjÿøHl`ɦé?ƒøiN€ éAxé?ƒëªèi9J9)ÿøùAxëÝù?ƒHj`ɦN€ é?ƒéAxèiëª9)ÿø9JùAxëÝù?ƒHeÍ`é?ƒ,#A‚œÉ¦9ÿÿøi9Iù	ù_ƒN€ éAxé?ƒëª8éÿøè©9	ÿð9JëÝøÿƒùAxè‰ÿþùƒèiÿðH`¹`ɦé?ƒøiN€ éAxé?ƒëª8éÿøè©9	ÿð9JëÝøÿƒùAxè‰ÿþùƒèiÿðH^ý`ɦé?ƒøiN€ éAxé?ƒëªèi9J9)ÿøùAxëÝù?ƒH]ñ`ɦN€ éAxé?ƒëª8©ÿøèÉ8éÿð9	ÿè9JëÝø¿ƒxÆ ùAxè©ÿøøÿƒè‰ÿðùƒx„ èiÿèHZ©`é?ƒ,#A‚@ɦøi9ÿÿé?ƒ9Iù	ù_ƒN€ é!xé_ƒ9ë©8ê9)ù!xëÝøÿƒù
ɦN€ é!xé_ƒ9ë©8ê9)ù!xëÝøÿƒù
ɦN€ é!xé_ƒ9ë©8ê9)ù!xëÝøÿƒù
ɦN€ é!xé_ƒë©9J9)ù!xëÝù_ƒHN…`é?ƒÉ¦øiN€ é!xé_ƒ9ë©8ê9)ù!xëÝøÿƒù
ɦN€ éAxé?ƒëª8©ÿøèÉ8‰ÿð8éÿè9J9	ÿàëÝø¿ƒùAxè©ÿøøŸƒx¥ €‰ÿôøÿƒèiÿèùƒxc H4Ý`ɦN€ éAxé?ƒëª8éÿøè‰9	ÿð9JëÝøÿƒùAxèiÿøùƒHC}`é?ƒ,#A‚@ɦ9ÿÿ9Iù	ù_ƒN€ éAxé?ƒëª8éÿøè‰9	ÿð9JëÝøÿƒùAxèiÿøùƒHEA`é?ƒ,#A‚
Ðɦ9ÿÿ9Iù	ù_ƒN€ é!xé_ƒë©8êÿøé
8Êÿð8ªÿè8Šÿà8jÿØ9)ëÝøÿƒ9jÿÐy ù!xèêÿøø߃èÊÿðø¿ƒxÆ èªÿèøŸƒèŠÿàøƒèjÿØùƒHT
`é?ƒ,#A‚
(ɦ9ÿÿ9Iù	ù_ƒN€ éAxé?ƒëª8©ÿøèÉ8‰ÿð8éÿè9	ÿà9JëÝø¿ƒxÆ ùAxè©ÿøøŸƒè‰ÿðøÿƒèiÿèùƒHQU`é?ƒ,#A‚üɦ9ÿÿ9Iù	ù_ƒN€ é!xé_ƒë©8êÿøé
8Êÿð8ªÿè8Šÿà8jÿØ9)ëÝøÿƒ9jÿÐy ù!xèêÿøø߃èÊÿðø¿ƒxÆ èªÿèøŸƒèŠÿàøƒèjÿØùƒHO`é?ƒ,#A‚|ɦ9ÿÿ9Iù	ù_ƒN€ éAxé?ƒëª8©ÿøèÉ8‰ÿð8éÿè9	ÿà9JëÝø¿ƒxÆ ùAxè©ÿøøŸƒè‰ÿðøÿƒèiÿèùƒHL‰`|iyA‚
œëŸƒù<9<ù?ƒHY‰`ɦé?ƒ9ÿÿø|9Iù	ù_ƒN€ é!xë©9)ù!xëÝHJÍ`ɦN€ é!xë©9)ù!xëÝH>i`ɦN€ é!xë©9)ù!xëÝHFÅ`ɦN€ éAxé?ƒëª8Éÿøèi8éÿð9J9	ÿèëÝø߃ùAxè‰ÿøøÿƒè©ÿöùƒHB‰`é?ƒ,#9Iù_ƒ@‚
èɦ9@ÿÿùIN€ é!xé_ƒÃxèêë©8Êÿø8ªÿð8Šÿè9)9
ÿàëÝø߃ù!xèÊÿþø¿ƒèªÿðøŸƒèŠÿîùƒH?`é8é,)@‚
¬É¦é?ƒ9ÿÿ9Iù	ù_ƒN€ é!xé_ƒÃxèªë©9
ÿø9)ù!xëÝùƒèŠÿøH:q`éXé9*()é?ƒ@ìɦù	8àé?ƒ9	ùIøéùƒN€ é!xé_ƒÃx8 ë©€Š9)ù!xëÝH6y`éXé9*()é?ƒ@tɦù	8àé?ƒ9	ùIøéùƒN€ é!xé_ƒë©èŠÿø€j9)ù!xëÝH3õ`é?ƒÉ¦9)ÿðù?ƒN€ é!xé_ƒë©€Šÿü€j9)ù!xëÝH2‰`é?ƒÉ¦9)ÿðù?ƒN€ é!xé_ƒë© Šÿþ€j9)ù!xëÝH1`é?ƒÉ¦9)ÿðù?ƒN€ é!xé_ƒë©ˆŠÿÿ€j9)ù!xëÝH/±`é?ƒÉ¦9)ÿðù?ƒN€ é!x럃ë©€|9)ù!xëÝH2i`ɦø|N€ é!xé_ƒë©€j9)ù!xëÝH1	`é?ƒÉ¦øiN€ é!xé_ƒë©€j9)ù!xëÝH/¥`é?ƒÉ¦øiN€ é!xé_ƒë©€j9)ù!xëÝH.A`é?ƒÉ¦øiN€ é!xé_ƒ<Âÿÿ8Æa~dzx~¥«xë©9
ÿøèŠ9)ù!xëÝùƒèjÿøH7`ɦé?ƒéApùIé?ƒ9Iøiù_ƒN€ é!xé_ƒ<¢ÿÿ8¥a~Ƴx~¤«xë©èj9)ù!xëÝH5©`é?ƒéApɦùIé?ƒ9Iøiù_ƒN€ é!xë©9)ù!xëÝH4a`ɦN€ é!xé_ƒë©9
ÿøˆŠ9)ù!xëÝùƒ¨jÿþH3á`ɦé_ƒ|i4U)Ù~i)})Ðù*N€ éAxé?ƒëª8éÿøˆ‰9J9	ÿðùAxëÝøÿƒ¨iÿþùƒH3­`ɦN€ éAxé?ƒëª8Éÿøè‰8éÿð9J9	ÿèëÝø߃ùAx¨©ÿþøÿƒ¨iÿöùƒH3!`ɦN€ éAxé?ƒëª8éÿøè‰9J9	ÿðùAxëÝøÿƒ¨iÿþùƒH2Á`ɦN€ éAxé?ƒëª8Éÿøè‰8éÿð9J9	ÿèëÝø߃ùAx¨©ÿþøÿƒ¨iÿöùƒH2}`ɦN€ éAxé?ƒëªèi9J9)ÿøùAxëÝ|c4ù?ƒH1½`ɦN€ é!xé_ƒé
ë©8êÿø8Êÿð8ªÿè8Šÿà8jÿØëÝøÿƒ9)ù!xèêÿøø߃èÊÿðø¿ƒèªÿèøŸƒèŠÿæøƒèjÿØH£Á`ɦé?ƒøiN€ éAxé?ƒëª8éÿøè©9	ÿð9JëÝøÿƒùAxè‰ÿøùƒèiÿðH¢¥`ɦé?ƒøiN€ é!xé_ƒë©èj9)ù!xëÝH§!`é?ƒÉ¦øiN€ é!xé_ƒë©èj9)ù!xëÝH¦`é?ƒÉ¦øiN€ é!xé_ƒë©èj9)ù!xëÝHõ‰`é?ƒÉ¦øiN€ é!xé_ƒë©èj9)ù!xëÝHó•`é?ƒÉ¦øiN€ é!xé_ƒë©èj9)ù!xëÝHô!`é?ƒÉ¦øiN€ é!xé_ƒë©èj9)ù!xëÝH¤­`é?ƒÉ¦øiN€ é!xé_ƒë©èj9)ù!xëÝH£Ù`é?ƒÉ¦øiN€ éAxé?ƒëªèi9J9)ÿøùAxëÝù?ƒHŸM`ɦN€ éAxé?ƒëªèi9J9)ÿøùAxëÝù?ƒHžY`ɦN€ é!xë©9)ù!xëÝH!å`ɦN€ é!xë©9)ù!xëÝHÛ!`ɦN€ é!xë©9)ù!xëÝHÇ
`ɦN€ é!xé_ƒë©èj9)ù!xëÝH‹A`é?ƒÉ¦øiN€ é!xé_ƒë©èj9)ù!xëÝH‰=`é?ƒÉ¦øiN€ éAxé?ƒëª8éÿøè‰9J9	ÿðùAxëÝøÿƒT„>èiÿøùƒH†á`ɦN€ éAxé?ƒëªèi9J9)ÿøùAxëÝù?ƒH†-`ɦN€ é!xé_ƒë©èj9)ù!xëÝHƒQ`é?ƒÉ¦øiN€ éAxé?ƒëª8éÿøèi9	ÿð9JëÝøÿƒùAxè©ÿþùƒè‰ÿðH€u`ɦé?ƒøiN€ éAxé?ƒëª8éÿøèi9	ÿð9JëÝøÿƒùAxè©ÿþùƒè‰ÿðH}y`ɦé?ƒøiN€ <b8cæP`ø¡p8‚€øHiM`9 è¡p‘?© Kÿ¾É¦9)ÿøù?ƒN€ 9Jÿøë©9)ù_ƒù!xëÝɦN€ ɦ9Iøiù_ƒN€ ɦ9Iøiù_ƒN€ ɦ9Iøiù_ƒN€ ɦ9@ùIN€ ɦ9Iøiù_ƒN€ ɦ9Iøiù_ƒN€ ɦé_ƒ8àù
9
ù*øêùƒN€ ë©9)ù!xëÝɦN€ ɦ=Bÿý9J/(é?ƒ=ÿý9/Jù	9	ùƒùIN€ ɦ9@ùIN€ ˆi|‰8®| @AØ¬A€à9)|)@@@‚ØT9@ø¿ƒé!xùFÿð9IùAxë©ëÝɦN€ 8`xçèÂ`cð8À9D"ɦN€ 8`xçèÂ`cð8À9D"ɦN€ |*8@A€Ø|§J|*(@@€Ì,)}JJA‚p9	ÿøq|¨+x@‚9ÿøèåÿø|ÈJ|%0øêÿùA‚Pèˆÿø8Èÿø9ÿð8êÿøøŠÿø}HJ|%P9GÿøèÆÿøøÇÿø@‚ÿØɦN€ ɦé_ƒ9
ù*ùƒN€ ɦ9@ÿÿùIN€ ɦ9@ÿÿùIN€ }DSxéHèÈÿø}GPø}J P|ç2|'P@A€Úô})*9)ë©ù!xëÝɦN€ 9Jÿðë©9)ù_¤ù!xëÝɦN€ éF})R9)ë©ù!xëÝɦN€ 4ÅÿøyGÆ|çSxA€9ÿ÷9@,(ÿÿ@€PqH9
ÿÿ@‚äyJøB}I¦9Iøé9)øêBÿðé!xë©9)ù!xëÝɦN€ 4ÅÿüA€´9ÿûyG ,(ÿÿ9@@€äqH9
ÿÿ@‚$yJøB}I¦9Ié9)êBÿðé!xë©9)ù!xëÝɦN€ ɦøiN€ ɦøiN€ ɦ9Iøiù_ƒN€ 8`xçð‚`cð8À9D"ɦN€ 4ÅÿþA€9ÿýUJ>,(ÿÿ9@€Pq8èÿÿ@‚dyøB}	¦9	±I9)±HBÿðé!xë©9)ù!xëÝɦN€ 8`xçð‚`cð8À9D"ɦN€ |*8@A€8|ÇJ|*0@@€,,)}JJA‚°9	ÿü|Å3xq@‚8¦ÿüÿü|åJ|&8•
ÿüA‚l€…ÿü8åÿü8¥ÿø9
ÿüŠÿü}EJ|&P9Hÿü€çÿüèÿü@‚ÿØɦN€ ,(øé9)@‚þé!xë©9)ù!xëÝɦN€ 9@ÿÿø¿ƒé!xùFÿð9IùAxë©ëÝɦN€ xÊð‚9JKÿþxÊèÂ9JKÿý¬xÈøB9Kÿþ¬,*˜É9)@‚ÕKÿÿˆ,'±I9)@‚þ”Kÿÿt,(é9)@‚ýÔKÿÿ````B,)8§ÿü8ŠÿüA‚„}8P}Jq@‚,)}DSx|å;x‘
A‚lE8Å8¥98„‘Dÿü}EHP!J|*8F‘H@‚ÿÔɦN€ ,)8§ÿþ8ŠÿþA‚}8P}Jq@‚,)¡}DSx|å;x±
A‚¡E8Å8¥98„±Dÿþ}EHP!J|*8¡F±H@‚ÿÔɦN€ ,)8§ÿø8ŠÿøA‚¤}8P}Jq@‚,)é}DSx|å;xù
A‚XéE8Å8¥98„ùDÿø}EHP!J|*8éFùH@‚ÿÔɦN€ ,)8§ÿÿ8ÊÿÿA‚4q(9	ÿÿA‚,(‰|å;x}FSx™
A‚y)øB})¦‰9E9&8¥8Æ™ÿÿ‰J™IBÿàɦN€ úAÀ,(9 ÿÿêEÿèù%ÿèA‚°9ÿÿú!¸;9ÿÿ’B:RÿÿH|<@A‚TŒrHNý`|qxŒyHNí`|A‚ÿØɦé?ƒ9@ùIê!¸êAÀN€ ɦûHê!¸N€ ɦê!¸êAÀN€ é!xë©9)ù!xëÝɦN€ ɦN€ ɦN€ ɦêAÀN€ ɦN€ ɦN€ ɦN€ ɦN€ ɦN€ 8`8À`cð9D"ɦN€ 8`8À`cð9D"ɦN€ €```B9#ÿÿ(	AHû¡ÿèûÁÿðûáÿøø!ÿq|Ÿ#x|½+x=")j,	A‚Ä,ûp`;‚ A‚¬|¦ø HD```BKÿ´1|ŸðP8 8`;þKÿ´ƒãxHE`…ãx|dx8`Kÿ´8€
ãûxHCÕ`äûx8 |~y8`@‚ÿ¬ãûxHDÅ`|~µ@‚˜ëpè |¦8!£ëxë¡ÿèëÁÿðëáÿøN€ ëp,;ÿÿÿ{¾ @ÿØ|¦ø HH )`9>ÿÿy>!A‚ÿ°Œ(
@‚ÿä8`
H `ˆKÿÿÐ```B8`N€ ``Bäûx8 8``Kÿ³!;â(Äóx8 8`Kÿ³
ãûxHCõ`åûx|dx8`Kÿ²ñè ëp|¦Kÿÿ(€|¦ûÁÿðûáÿøøø!ÿ8 |ž#x|x8`Kÿ²­Ãóx`HC‘`8 ;0|dx8`Kÿ²‰äûx8 8`Kÿ²yÃóxHCa`Åóx|dx8`Kÿ²]8 8€8`Kÿ²M,#@‚$8!€èëÁÿðëáÿø|¦N€ ``B8!€8 8€8`èëÁÿðëáÿø|¦Kÿ²€ûáÿøø!ÿ18cÿÿ(`é‚8`éB‚@`¡"‚HùpùAx±!€A$,@‚,%@‚|¦û¡¸?¢û°;½ç|Ü3x;à=Høà,	A‚P9@;à}I¦9=H,``BI`}´9)09,
A‚}´B@IH9,
@‚ÿÔ`ûÁÀ8¢‚|£+xø¡HB
`衐|dx8`Kÿ±	8 8€8`Kÿ°ù|~yA‚x`ûA ûa¨_8‚hKÿþ	}Ò,#ø{A‚8`Ãóx8‚˜Kÿýé,#ø{A‚L;ap8 dÛx8`Kÿ°™cÛx`HA}`8 ;bÈ|dx8`Kÿ°uÄóx8 8`Kÿ°ecÛxHAM`eÛx|dx8`Kÿ°I8 8€8`Kÿ°9,#@‚|8 8€8`Kÿ°!8 8€|~x8`Kÿ°
Þ´8 ;Þÿú|dxƒãx|„òHDÁ`9 }=Ñ.ëA ëa¨èà끰롸ëÁÀ|¦8!ÐãûxëáÿøN€ èàëA ëa¨ë°ë¡¸ëÁÀ|¦;àÿÿKÿÿÐ`;àÿÿ8bpH\5`Kÿÿœ`;àÿÿ8b@H\`KÿÿŒ`;àÿÿ8b H\`Kÿÿl``B`;àÿþ8bØH[å`èà끰롸|¦KÿÿX€```B(A¼ûÁÿðø!ÿ#=B9Jç8`ÿÿÊJ}*H.,	A‚|,&@‚t|¦ûáx8`|¿+x8 øKÿ®±äûx8 8``Kÿ®èž;â‚P8 8`Kÿ®‰ãûxH?q`åûx|dx8`Kÿ®mèëáx|c´|¦8!€ëÁÿðN€ ```B8`ÿÿN€ €```B(A¼ûÁÿðø!ÿ#=B9Jç8`ÿÿÊJ}*H.,	A‚|,&@‚t|¦ûáx8`|¿+x8 øKÿ­Ñäûx8 8``Kÿ­½èž;â‚P8 8`Kÿ­©ãûxH>‘`åûx|dx8`Kÿ­èëáx|c´|¦8!€ëÁÿðN€ ```B8`ÿÿN€ €```BTcú,A‚8`N€ ```Bûÿàø!ÿa,%|¼+xA‚¤|¦ûÁ`ûaxû¡ˆûá˜|›#x;‚X;à; ø°H$```By? |{é®|?à@ýûx@€,ÃóxH=©`Åóx|dx8`Kÿ¬¥9?pcÿ@‚ÿÈè°ãûxëax롈ëÁëá˜|¦8! ëÿàN€ 8`Kÿÿð€``|¦øø!ÿ`8¢‚p|£+xø¡pH=%`è¡p|dx8`Kÿ¬!`8 8€8`Kÿ¬
`8!€èxc |¦N€ €`B|¦ûÁÿðûáÿøøø!ÿ`|~x;â‚pãûxH<­`åûx|dx8`Kÿ«©`8 8€8`Kÿ«•`|còx~ HãûxH<m`åûx|dx8`Kÿ«i`8 8€8`Kÿ«U`|@AÿÈ8!€èëÁÿðëáÿø|¦N€ €|¦ûáÿøøø!ÿ8 `|dx;₀8`Kÿªý`ãûxH;á`åûx|dx8`KÿªÝ`8!€èëáÿø|¦N€ €`B|¦ûáÿøøø!ÿq`|x8¢‚p|£+xø¡pH;}`è¡p|dx8`Kÿªy`8 8€8`Kÿªe`8!="†èÿ“é‡ëáÿø|¦N€ €|¦ûáÿøøø!ÿq`8¢‚p?Ↄÿ‡|£+xø¡pH:ù`è¡p|dx8`Kÿ©õ`8 8€8`Kÿ©á`8!è|cøPëáÿø|c´|¦N€ €8`èN€ ```B|¦ûáÿøøø!ÿ8 `|dx;₈8`Kÿ©m`ãûxH:Q`åûx|dx8`Kÿ©M`8 8€8`Kÿ©9`8!€èëáÿø|¦N€ €|¦ûÁÿðûáÿøøø!ÿ8 |Ÿ#x`|dx8`Kÿ¨é`;‚˜äûx8 8`Kÿ¨Ñ`ÃóxH9µ`Åóx|dx8`Kÿ¨±`8!€èëÁÿðëáÿø|¦N€ €`B|¦ûáÿøøø!ÿ8 `|dx;₨8`Kÿ¨]`ãûxH9A`åûx|dx8`Kÿ¨=`8 8€8`Kÿ¨)`8!€èëáÿø|¦N€ €|¦û¡ÿèûÁÿðûáÿøøø!ÿq8 `|Ÿ#x;¢‚¨|dx|~x8`Kÿ§Í`£ëxH8±`¥ëx|dx8`Kÿ§­`8 8€8`Kÿ§™`}#û’})ùÒ|#H@‚$8!èë¡ÿèëÁÿðëáÿø|¦N€ `Bûp|dx8 `8`Kÿ§M`;‚‚¸Äóx8 8`Kÿ§5`ƒãxH8`…ãx|dx8`Kÿ§`|žú8 8„ÿÿ8`Kÿ¦ý`£ëxH7á`¥ëx|dx8`Kÿ¦Ý`8 8€8`Kÿ¦É`ëp8!9?ÿÿÿÐè|ië¡ÿèëÁÿðã8ëáÿø|¦N€ €`B|¦ûÁÿðûáÿøøø!ÿ8 |Ÿ#x`|dx8`Kÿ¦Y`;‚¸äûx8 8`Kÿ¦A`ÃóxH7%`Åóx|dx8`Kÿ¦!`8!€èëÁÿðëáÿø|¦N€ €`B|¦ûÁÿðûáÿøøø!ÿ|ž#x|¿+x|dx8 8`Kÿ¥É`Äóx8 `8`Kÿ¥±`;‚Èäûx8 8`Kÿ¥™`ÃóxH6}`Åóx|dx8`Kÿ¥y`8 8€8`Kÿ¥e`8!€èëÁÿðëáÿø|¦N€ €``B|¦ûÁÿðûáÿøøø!ÿ|¿+x|~x8 8`Kÿ¥
`Äóx8 `8`Kÿ¤õ`;‚Øäûx8 8`Kÿ¤Ý`ÃóxH5Á`Åóx|dx8`Kÿ¤½`8!€èëÁÿðëáÿø|¦N€ €|¦ûáÿøøø!ÿ8 `|dx;â‚è8`Kÿ¤m`ãûxH5Q`åûx|dx8`Kÿ¤M`8 8€8`Kÿ¤9`8!€èëáÿø|¦N€ €|¦ûáÿøøø!ÿ8 `|dx;â‚ø8`Kÿ£í`ãûxH4Ñ`åûx|dx8`Kÿ£Í`8 8€8`Kÿ£¹`8!€èëáÿø|¦N€ €|¦ûáÿøøø!ÿ8 `|dx;âƒ8`Kÿ£m`ãûxH4Q`åûx|dx8`Kÿ£M`8 8€8`Kÿ£9`8!€èëáÿø|¦N€ €|¦ûÁÿðûáÿøøø!ÿ8 |x`8`;ƒKÿ¢é`äûx8 8`Kÿ¢Õ`ÃóxH3¹`Åóx|dx8`Kÿ¢µ`8!€èëÁÿðëáÿø|¦N€ €``B|¦ûÁÿðûáÿøøø!ÿ8 |x`8`;ƒ(Kÿ¢Y`äûx8 8`Kÿ¢E`ÃóxH3)`Åóx|dx8`Kÿ¢%`8!€èëÁÿðëáÿø|¦N€ €``B|¦ûÁÿðûáÿøøø!ÿ8 |x`8`;ƒ8Kÿ¡É`äûx8 8`Kÿ¡µ`ÃóxH2™`Åóx|dx8`Kÿ¡•`8!€èëÁÿðëáÿø|¦N€ €``B|¦ûáÿøøø!ÿ8 `|dx;âƒH8`Kÿ¡=`ãûxH2!`åûx|dx8`Kÿ¡`8 8€8`Kÿ¡	`8!€èëáÿø|¦N€ €|¦ûÁÿðûáÿøøø!ÿ|ž#x|¿+x|dx8 8`Kÿ ¹`Äóx8 `8`Kÿ ¡`;ƒ`äûx8 8`Kÿ ‰`ÃóxH1m`Åóx|dx8`Kÿ i`8!€èëÁÿðëáÿø|c´|¦N€ €``B|¦û¡ÿèûÁÿðûáÿøøø!ÿq8 `|x;¢ƒp8`Kÿ `£ëx`H0å`¥ëx;ƒ€|dx8`KÿŸÝ`äûx8 8`KÿŸÉ`ãûxH0­`8 |dx8`KÿŸ©`ÃóxH0`Åóx|dx8`KÿŸ‰`8!èë¡ÿèëÁÿðëáÿø|¦N€ €``B|¦û¡ÿèûÁÿðûáÿøøø!ÿq|x|¾+x`8 8`;¢ƒKÿŸ!`Äóx8 8``KÿŸ	`£ëx;ƒ€H/é`¥ëx|dx8`Kÿžå`äûx8 8`KÿžÑ`ãûxH/µ`8 |dx8`Kÿž±`ÃóxH/•`Åóx|dx8`Kÿž‘`8!èë¡ÿèëÁÿðëáÿø|¦N€ €|…#x|dx`8bƒ Kÿÿ|…#x|dx`8bƒ°Kÿþà|¦ûÿàû¡ÿèûÁÿðûáÿøøø!ÿq|ž#x|x|½+x8`8 |Ü3xKÿí`Ãóx`H.Í`8 ;ƒÀ|dx8`KÿÅ`äûx8 8`Kÿ±`ãûxH.•`8 |dx8`Kÿ‘`ÃóxH.u`Åóx|dx8`Kÿq`8 8€8`Kÿ]`,#@‚`8 8€8`KÿA`8 8€|ix8`‘<Kÿ%`|ix8`ù=8!èëÿàë¡ÿèëÁÿðëáÿø|¦N€ 8`ÿÿKÿÿÜ€```B|¦øø!ÿ`8¢ƒØ|£+xø¡pH-¥`è¡p|dx8`Kÿœ¡`8 8€8`Kÿœ`8!€è|c´|¦N€ €`B|¦øø!ÿ`8¢ƒà|£+xø¡pH-5`è¡p|dx8`Kÿœ1`8!€è|¦N€ €```B|¦øø!ÿ`8¢ƒð|£+xø¡pH,Õ`è¡p|dx8`Kÿ›Ñ`8 8€8`Kÿ›½`8!€è|¦N€ €``ûÁÿðø!ÿa|~y@‚8! ëÁÿðN€ `B|¦ûApûax`û€û¡ˆ8b„`ûá˜``;ž(;à;¢¥¸;B™8ø°;b©èÞè¾èžHGq``8b„0HGa`é>é}IC’}
AÒ})Bx1)ÿÿ}J”,*A‚˜`Bé´Wê¾y)т£ëxy)$|œH*|„T6x„àHG`é>é8ÿxê xÿ .ª/¿}IC’}
AÒ})Bx1)ÿÿ}J”|?P@@€4Ažÿ péA–@‚ÿ”CÓxHF½`Kÿÿ„cÛxHF­`Kÿÿt`8b„€HF™`è°ëApëax끀롈ëá˜8! |¦ëÁÿðN€ €```BûÁÿðø!ÿQ|ž#yA‚ô|¦,%ûaˆû¡˜û!xûA€|{x|½+xûûá¨øÀ@‚; žë’}<éÒÉJx1)ÿÿœ”{‰ {šÑ‚1)ÿÿZ”;:{9$#ËxKÿñ
`|yA‚`ûûß8¹ÿØ8€ÿû_û¿8(ûŸ H-Í`èÀãûxë!xëA€ëaˆëë¡˜ëá¨8!°|¦ëÁÿðN€ `BèÀë!xëA€ëaˆëë¡˜ëá¨|¦8!°8`ëÁÿðN€ €`Bûáÿø|yA‚Ôûÿàû¡ÿè8`ÿÿë¿ëŸ |ë’} éÒ|„Jx0„ÿÿ|”|<@A€°ûÁÿðx ëß}^ë’}*éÒÉJx3ÉÿÿÞIÞR{Þ!A‚”9Ÿ(9H(```B98Æ|@@xÆ y A‚0}´U¾x©Ñ‚|£+xy)$}lH*}i$6q)A‚ÿÈ|0@A€|@@}	Cx@Ü}
@ø}J2yJ 9J}I¦H ``ByJ$}LP*}J<6qJA‚ÿ€9)}*´U'¾yJтy) BÿØ|à*8À|(8@A€<`B|àP|céÒé?ø |cJëÿàë¡ÿèëÁÿðëáÿøN€ ``B}lH*9(xªÑ‚y( |Ä 6|(8@}k x})´yJ$y)т}´}lQ*y)$U¾A€ÿÈëŸ ë¿KÿÿŒA‚ÿt98Æ|@@xÆ y @‚þØëÿàë¡ÿèëÁÿðëáÿø8`ÿÿN€ ëáÿø8`ÿÿN€ ëÿàë¡ÿèëáÿøN€ ëÿàë¡ÿèëÁÿðKÿÿL```B,#M‚ é#|§+xè£|) @AØ}I*}:|*@@A€ÈéC|‰ Pé }'S’|ÄS’|©QÒxÄ xÊ |ç*x0çÿÿ})”|É2}(J|$0@ù# L€ 8c(8 ```B}I´UH¾y)т8êy)$xê |§@6|*0@}H*};x}I*L€ }I´UH¾y)т8êy)$xê |§@6|*0@}H*};x}I*A€ÿ¤N€ ```B|¦øø!ÿ‘`|†#x8b„ˆ}$KxHB`8!pè|¦N€ €=B¦|ix9J‡=†9‡èj,#A‚4}#J|)P@Aù*N€ ```B8`ÿÿN€ ``Bù
}CxKÿÿÈ|ɦN€ }è¦|#x8à|#8A‚HÙ}B¦,A‚4HxèÄ}B¦8à|'0A‚8àè„|' 8`A‚P|ˆ#x|qB¦ùèˆ8à|' A‚|„øèˆøèˆøèˆ|„ø(8ˆ ø 8`~ƒx}è¦N€ }è¦|°+x|±+xH9,@‚}è¦N€ |ɦ:ÿÿ8¥ÿÿŽEžPBÿø~%‹x}è¦N€ }(¦|ˆ#x|jx|…#x8¥ |«+xHE,@‚ è¤,|„*@‚ÿÔ8`}(¦N€ 8`è¤èÄèä|¥B}(¦N€ 9Jÿø9kÿøéª	éË	|-p9€A‚N€ qÎÿ@‚ÿä9€N€ ø!ÿ±|¦ø0ùá8ùÁ@ù¡H|¯+xKÿÿYè0|¦øø¯øÏøïé¡HéÁ@éá88!PN€ N€ xfÁÆ8`X8€8 D"N€ |jx8`T8€D"|ƒ#yA‚x£F ˜jN€ }¦|ixˆi,A‚Kÿÿ±9)Kÿÿì}¦N€ }¦|ixy#' pc,
A€8c8c0Kÿÿ}y#F pc,
A€8c8c0Kÿÿay#e pc,
A€8c8c0KÿÿEy#„ pc,
A€8c8c0Kÿÿ)y#£ pc,
A€8c8c0Kÿÿ
y#Â pc,
A€8c8c0Kÿþñy#á pc,
A€8c8c0KÿþÕy#"pc,
A€8c8c0Kÿþ¹y#'pc,
A€8c8c0Kÿþy#Fpc,
A€8c8c0Kÿþy#epc,
A€8c8c0Kÿþey#„pc,
A€8c8c0KÿþIy#£pc,
A€8c8c0Kÿþ-y#Âpc,
A€8c8c0Kÿþy#ápc,
A€8c8c0Kÿýõy#pc,
A€8c8c0KÿýÙ}¦N€ }¦|ixKÿÿ}¦|ixKÿÿt}¦|ixKÿÿ |è¦H|Ȧ|è¦8ÆÿxxgÆj|æ8î|8N€ }h¦|ix8`CKÿüù}#KxKÿÿ18`
Kÿüé}h¦N€ }h¦|ix|Š#x|¬+x8`
KÿüÉ8`
KÿüÁ}ƒcxKÿü¹}#KxKÿþñ8` Kÿü©}CSxKÿüÝ8`
Kÿü™8`
Kÿü‘}h¦N€ 8 EKÿÿ¤}h¦KÿÿQ}h¦8 W@ÿN€ }h¦8¥ Kÿÿ5}h¦8 D@ÿtN€ }h¦|…#xTc@.Kÿÿ8`A8`}h¦N€ |¨¦H|Ȧ8Æþtpc|Ã2˜†|¨¦N€ N€ `C= Ea)LF|
H@‚°ûáÿøø!ÿ|x‰#,	A‚‰#(	A‚l(	A‚D¡?9)ÿþU)>(	A€¡?9)ÿìU)>(	A|ˆ8!€ëáÿøN€ ``B|¦øH	`è|¦Kÿÿ¨`B|¦øHé`è|¦Kÿÿˆ`B8`ÿÿN€ ``B8`ÿýKÿÿ˜``B8`ÿüKÿÿˆ€```B|¦ûaÿØûÿàû¡ÿèûÁÿðûáÿøøø!ÿa|#x|¼+x|Û3x|~xKÿþÑ,|xA‚D,A‚œè}8!  c|cèã8ëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ `BfÛx…ãx8€ÃóxHQ`ø}‰>,	A‚ÿ¨8!  c;à|cèã8ëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ `BfÛx…ãx8€ÃóxH
1`ø}‰>,	A‚ÿHÃóxHÕ`Tc¾,è}A‚@8!  c;à|cèã8ëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ ``B;àKÿþè€```B|¦ûAÿÐûaÿØûÿàû¡ÿèûÁÿðûáÿøøø!ÿQ|œ#x|º+x|Ý3x|û;x|~xKÿýI,|xA‚Œ,@‚PÃóxH=`fÛx¥ëx|ƒàPÃóxøpH	1`èp„ÃóxûšH©`‰>,	@‚˜8!°ãûxèëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ ``BÃóxH}`fÛx¥ëxƒàPÃóx„ãxHq`8!°ƒâãûxûšèëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ `BÃóxH-`8!°T¾èëAÿÐëaÿØëÿàkÿë¡ÿèëÁÿðÿ4|¦WÿÙ~;ÿãûxëáÿøN€ €``BC= Ea)LF|
H@‚|¦ûáÿøøø!ÿ|x‰#,	A‚‰#(	A‚„(	A‚l¡?9)ÿþU)>(	Ax¡?9)ÿìU)>(	Ad‰?(	A‚x(	@‚PãûxH	y`8!€èëáÿø|¦N€ ```BH
Ñ`Kÿÿ`BHÁ`Kÿÿ€`B8!€8`ÿÿèëáÿø|¦N€ ``BãûxHÍ`8!€èëáÿø|¦N€ 8`ÿÿN€ €```B($@|m
E,
LF@‚lø!ÿ‘‰#(	A‚<(	A‚8`ÿÿ8!pN€ `B|¦ø€Hy`è€8!p|¦N€ |¦ø€HI`è€8!p|¦N€ 8`ÿÿN€ €```|¦ûÿÀû!ÿÈ}€&ûAÿÐûaÿØûÿàû¡ÿèûÁÿðûáÿøø‘ø!ÿQ; .%-¦øA(|~x|»+x|Ù3x|š#xƒããúH ¡,9=¡^*}=´|HÿRA€Ð?,	@‚ÿ܀¿€Ÿ| @š*ƒãx@‚ôƒA’(é;€Ÿé{})¦è[N€!èA(,#@‚ÿ˜€¿|žÂƒãxHé`€€¿8€|£(P|câx¥ Hé`€Ÿ,$A‚ÿXƒãxAŽÿPé9éy})¦èYN€!èA(¡,9=¡^*}=´|HÿR@€ÿ88!°€~聁ëÿÀë!ÿÈëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦}‘ } N€ ``B`8b„ÐH4)`8!°8`聁ëÿÀë!ÿÈëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦}‘ } N€ €`B¡,#9H}#JqG9A‚ €é,A‚P,¡*})BA‚LUJø~9JÿÿyJ 9J}I¦H¡*}I@n,
A‚})BB@I,
@‚ÿà€iN€ `B8`N€ ```B€c$N€ ```Bû¡ÿèûÁÿð9#8ã.ûáÿø9 N,9#| >,8ã0ÀN,9#|À>,8ã2}@L,9#|à>,}€L,9# àL,9#$|L,9#(}`N,9#*|€N,9#,} N,‘C9C³£³Ã}@T,‘ƒ“㠐$±c(°ƒ*°£.°Ã0°ã2‘C±#,yI }#J```B9IàL,}€T,9I|T,9I}`T,9H9	|€D,9	| D,9	|ÀD,9	|àD,“é}H´‘‰	‘i‰©Éé Ã, ã*|P}):@€ÿŒë¡ÿèëÁÿðëáÿøN€ ```B($|£"@¡#(,	4@‚ûÿàû¡ÿèûÁÿðûáÿø‰#¡c*(	}CBA‚(U
À>UiÆ>Q
BQ
F>UhD.})CxyJ U+>}CR9#,£ƒ,98À#Ë N,#ëA‚h©ëx}JZˆH@9~ª(@y @œhA•P|êð.}*ø.A‚$TìÀ>U À>PìBQ BPìF>Q F>y‡ x	 }):y) ¦H@@œÿ¤}&Kx@‚ÿ ‰ãx}JZˆH@9~ª(@y Aœÿ # ¡c.A‚U*À>UhD.Q*BQ*F>UiÆ>})CxyJ U+>}CR9#0£ƒ09#Ë#ë N,`BA‚h©ëx}JZˆH@9~ª(@y @œhA•€|êð.}*ø.A‚$TàÀ>U#À>PàBQ#BPàF>Q#F>x xi }):y) ¦H@@œÿ¤}&Kx@‚ÿ ‰ãx}JZˆH@9~ª(@y Aœÿ 8fxcd|$@@€```B8`ÿÿëÿàë¡ÿèëÁÿðëáÿøN€ ``B}CJKÿÿ 8`ÿÿN€ `|¦ûÿÀû!ÿÈ}€&ûAÿÐûaÿØûÿàû¡ÿèûÁÿðûáÿøø‘ø!ÿQ; .%-¦øA(|~x|»+x|Ù3x|š#xëã ãúH ¡89=¡^6}=´|HÿRA€Ì?,	@‚ÿÜè¿èŸ|% @š*ƒãx@‚ôëA’(é;èŸ(é{})¦è[N€!èA(,#@‚ÿ˜è¿ |žÂƒãxH©`è è¿(8€|£(P||H­`èŸ(,$A‚ÿ\ƒãxAŽÿTé9éy})¦èYN€!èA(¡89=¡^6}=´|HÿR@€ÿ<8!°è~聁ëÿÀë!ÿÈëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦}‘ } N€ ```B`8b…H-é`8!°8`聁ëÿÀë!ÿÈëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦}‘ } N€ €`B¡8é# 9H}#JqG9A‚ €é,A‚P,¡6})BA‚LUJø~9JÿÿyJ 9J}I¦H¡6}I@n,
A‚})BB@I,
@‚ÿàèiN€ `B8`N€ ```B|¦úáÿ¸ûÿÀû!ÿÈûAÿÐûaÿØûÿàû¡ÿèûÁÿðûáÿøøø!ÿA;``ëÃ(|x|™#x;‚…p;¢…PÃò;~H `B¡_<98;{@}8´|
HA€Œ;,	@‚ÿà;(y)6d}>Jé)q)A‚ÿÈè»,%A‚ÿ¼‚û$;@8Àz÷6d~þº`Bé; 8è÷è |ÆJ8c}2|jxqI}?è‹xˆ"}:|ÿBA‚ }.,A‚\,#¡6})BA‚˜UJø~9JÿÿyJ 9J}I¦H(```B¡6}I@n,
A‚})BB@\I,
@‚ÿà}_0*é)|*H@A€Pé+(@é}YRx„ }9J})BA0<âÿý8çÐxˆd}Bª}:}	¦N€ Фܘ   ŒÀ°     „ì    ```BƒãxH*-`è»é;4IÒ{Z |:(@FÓxA€ýÜ¡_<98;{@}8´|
H@€ý|8!Àèêáÿ¸ëÿÀë!ÿÈëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ é*})Êù*è»KÿÿŒU(þy)„}(J±*è»Kÿÿty)„ ±*è»Kÿÿdy)"±*è»KÿÿT‘*è»KÿÿHy)„±*è»Kÿÿ8U):±*è»Kÿÿ(`B}_0*KÿýÀ``B£ëxH)-`è»Kÿÿ€	û¡ÿèûÁÿð9#8ã:ûáÿø9 N,9#| >,8ã<ÀN,9#|À>,8ã>}@L,9#|à>,}€L(9#(àL(9#0|L,9#4}`N,9#6|€N,9#8} N,‘C9C ³£³Ã}@T(ùƒûã(0±c4°ƒ6°£:°Ã<°ã>ùC ±#8}#R9IàL,}€T,9I|T(9I}`T(9H9	|€D(9	 | D(9	(|ÀD(9	0|àD(“é}H´‘‰ø	ùiø‰ø© øÉ(øé0 Ã8 ã6|P}):@€ÿŒë¡ÿèëÁÿðëáÿøN€ ```B€c0N€ ```B($|£"@¡#4,	@@‚„ûaÿØûÿàû¡ÿèûÁÿðûáÿø‰#éC ¡c6(	}RA‚<yI"UHÀ>QHBU'À>QHF>Q'BQ'F>UjD.UiÆ>yÆ};x})Sx}BU+>9#8£Ã89@8À!‹àN,  ``BA‚”éûx}ZŠH@9J~¨(@yJ @œ”A•°|è`*}(*A‚Txü"|ý;xTçÀ>W›À>S§BS›BS§F>S›F>}=Kxy<"xçÆU)À>|çÛxS©BW›À>S©F>S›By)ÆS›F>})Ûx}):¦H@@œÿx}&Kx@‚ÿtÉóx}ZŠH@9J~¨(@yJ Aœÿté#(¡c:A‚8y*"U(À>Q(BUGÀ>Q(F>QGBQGF>UiÆ>UjD.yÆ};x})Sx}BU+>9#<£Ã<9@  k àN,`BA‚”éûx}ZŠH@9J~¨(@yJ @œ”A• |è*}(*A‚Txü"|ý;xTçÀ>W›À>S§BS›BS§F>S›F>}=Kxy<"xçÆU)À>|çÛxS©BW›À>S©F>S›By)ÆS›F>})Ûx}):¦H@@œÿx}&Kx@‚ÿtÉóx}ZŠH@9J~¨(@yJ Aœÿt8fxcd|$@@€8`ÿÿëaÿØëÿàë¡ÿèëÁÿðëáÿøN€ `B}JKÿÿ8`ÿÿN€ `|¦ûÁÿðûáÿøøø!ÿ8 |Ÿ#x`|dx8`Kÿxy`;… äûx8 8`Kÿxa`ÃóxH	E`Åóx|dx8`KÿxA`8 8€8`Kÿx-`8!€èëÁÿðëáÿø|c´|¦N€ €```|¦< Dûáÿø8`(`¥"8€øH9` }ˆ¦}kb«|Xl|¬|_¬L,è8cëáÿø|ct|¦xcтN€ `B|¦û¡ÿèûÁÿðûáÿøøø!ÿq|¿+y|~x|#xA‚|_mIH,	A‚LKÿÿY,#A‚l<àÿÿ8`< <xç |?ðÄóx@d=@àaJH`B;ÿÿü|?ð@H?|	P@‚ÿì?,	@‚ÿà?,	@‚ÿԁ?,	@‚ÿȁ?,	@‚ÿ¼äûxþûx|= ¦ëx@”ÊðøÉóx}]RyJ÷â|8A‚,9>|)è@€0,*A‚I|
8A‚ð9)|)èA€ì```B,#A‚¼< h= "`¥|a)DÊðø8€}J2yJ÷â|HA‚<;Þ|>0@€,*A‚H^|
HA‚°;Þ|>0A€0HÜ```B9^|HA‚p;Ê|>0@€´^|
H@‚ÿܐ¾Êóx|ˆ#x}R9UJ0U0}
@PUÉþ}	¦|Pl|¬|W¬|¬L,9J€Bÿè9^|H@‚ÿ˜¾}HSx|‡#x|çB8çU0Tç0|è8PTçÉþ|é¦|@l|¬|G¬|¬L,9€Bÿè;Ê|>0A€ÿT8!8`èë¡ÿèëÁÿðëáÿø|¦N€ `BKÿý,#A‚$8àÿÿ8`8 <xç Kÿý¸Kÿüñ,#@‚¨8!8`èë¡ÿèëÁÿðëáÿø|¦N€ `BI|
(A‚PI9)}(Kx|
8A‚09(|)è@€þ(I|
8A‚ÿ́I9)}(Kx|
8@‚ÿ؁I|
(@‚ÿÌ,#}&KxA‚8< h= "`¥|a)DH$``B< |= D¦ëxÄóx`¥ha)"|$0@€þðÊðø8€}J2yJ÷â|H@‚ý̐¾Èóx|‡#x|çB8çU0Tç0|è8PTçÉþ|é¦|@l|¬|G¬|¬L,9€BÿèKÿý„```B< |= D`¥ha)"KÿýHI|
(@‚ýKÿÿ(```B|(@‚üÐKÿÿ¾Êóx|ˆ#x}R9UJ0U0}
@PUÉþ}	¦|Pl|¬|W¬|¬L,9J€BÿèKÿý< |= D`¥ha)"Kÿþð€``|¦û!ÿÈûÿàû¡ÿèøø!ýQ($|#x|yx|¤+x@H8 ;pƒãxH)`(=@ÜûA€;]ýÿûp{ZºBûaˆ;`ûÁ ;ûá¨c{ð?ËxÃxH4`BcÛxäûx…ãx8À8à@9D",>;ÿ;ÞÿÿA‚P{é`()A‚üAÈ,)A‚ÿÀ()@‚ÀcÛxäûx…ãx8À8à9D",>;ÿ;Þÿÿ@‚ÿ¸{M¤{ZM¤ëaˆëÁ ëá¨;½þ9ÂëpºèPëA€)ëxy)`()A‚TAð,)@‚˜8`$Ëx…ãx{§èÂ`cð8À9D"8!°èë!ÿÈëÿàë¡ÿè|¦N€ ``B()A‚ÿHcÛxäûx…ãx8À8à9D"Kÿþø``BcÛxäûx…ãx8À8à€9D"KÿþÐ()@‚T8`$Ëx…ãx{§øB`cð8À9D"8!°èë!ÿÈëÿàë¡ÿè|¦N€ ```B()A‚ÿ´8`$Ëx…ãx§ëx`cð8À9D"8!°èë!ÿÈëÿàë¡ÿè|¦N€ ```B¥ëxKÿý¼``B8`$Ëx…ãx{§ð‚`cð8À9D"8!°èë!ÿÈëÿàë¡ÿè|¦N€ €<€`„ < `¥Œøƒø£N€ D"N€ xfÁÆ8`X8 D"N€ }H¦H-}H¦,M‚ = ¹a)€‰|dH®8„‰N€ |dx8`ÿÿ= ¹a)€©€É|0@L‚ 8`TD"= ¹a)‰8`i(M‚ 8`ÿÿø©øÉN€ è¤èÄ|dx8`D"N€ 9`}*Kx}	Cx|è;x|Ç3x|¦+x|…#x|dx8` D"N€ |…#x|dx8`<D",#|ƒ#xM‚ 8`ÿÿN€ |¦+x|…#x|dx8`@D"N€ |è;x|Ç3x|¦+x|…#x|dx<``cðD"N€ |¦+x|…#x|dx<``cðD"N€ |dx<``cðD"N€ |dx<``cð|hN€ ```|¦û¡ÿèûÁÿðûáÿøøø!ÿq|~x|#xˆc8cxchKÿɵ`pi|xA‚D9 xcd™>	KÿÌÅ`8!|cêø~èë¡ÿèëÁÿðëáÿø|¦N€ ``Bpi@‚<9 {ãä™>	KÿÌ}`8!|cêø~èë¡ÿèëÁÿðëáÿø|¦N€ ˆ~8cxchKÿÉ`9 xcƙ>	ÿx{ãäKÿÿ¬€``Bûáÿø|xû¡ÿè8€ûÁÿð8`@åûx<ÀD";¿8`<¥ëx8€D",#@‚dTžÀ>åûxPžB8`@PžF>8À{ÞÆ8€D"8`<¥ëx8€D",#@‚\TƒÀ>ë¡ÿèëáÿøPƒBPƒF>xc ÃxëÁÿðN€ ;Àÿÿåûx{ÞÄ8`@8€8ÀD"8`<¥ëx8€D",#A‚ÿ¬<`ÿÿë¡ÿèëáÿø`cÿÿxc ÃxëÁÿðN€ |¦û¡ÿèøø!ÿ18`KÿÃÝ`|}yA‚8`4ûáÈKÿȵ`pÿA‚$ûû!˜;8;=ûA ûa¨;](;}Húáˆû°ûÁÀH`B8~KÿÈm`pÿA‚Àãûxþ´KÿÈU`Tc>,	@‚ÿÔ8~KÿÈ=`||x8~KÿÈ-`Wœ>|wx8~KÿÇ`(V÷>xd A‚$AÐ(A‚8(@‚ÿ€8øp_ÓxKÿÆá`èp}hšÿãûxKÿü雟
8~Kÿǽ`pÿ@‚ÿT```Bêáˆëë!˜ëA ëa¨ë°ëÁÀ‰=",	A‚‰=2,	@‚`9 8€8}ù=™=™=KÿüuëáÈ8!Уëxèë¡ÿè|¦N€ `B(Ûx@‚þ¸šÿãûxKÿü=›Ÿ
KÿÿT‰=B,	A‚ÿœ‰=R,	A‚ÿ= y)ƒäù=ëáÈKÿÿœ`BÃxãûxšÿKÿûõ›Ÿ
Kÿÿ``B?ËxKÿþì`8b…¸H‘`Kÿÿ\€	``B#xc$8cxcä9)y)ä|iN€ `BûáÿøT‰D.T†Æ>|ÆKx|xTÆ>é#y)ãA‚Pè£8€8`@8¥D"|¬è¿8`<8€8¥D",#@‚PTƒÆ>T‰D.ëáÿø|cKxTc>N€ è£8€8`@8¥D"|¬è¿8`<8€8¥D",#A‚ÿ¸ëáÿø8`ÿÿxc N€ „8|c"èc€N€ `B„8|c"ècˆN€ `B„8|c"ècN€ `BûAÿÐûaÿØûÿàû¡ÿèûÁÿðûáÿøø!ÿQ|}x€cë}ä–}I–ÿÖ}JÖx£ãÿ P}JHPÿ´U^>{ú&ä›ÒA‚¬x©ÿáA‚`|¦û!x|Ù3xøÀé=(,)A‚¸|Ã3x|ä;xùøá8 {ÿ$KÿÂM`é=(|fx)ù*èÀéèáë!x|¦9<|ÛÕ(8!°|àM,9<}O,9<ÀO,ëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿøN€ ``B|ÛÑ*ü±³Ü8!°ëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿøN€ <b8cæP`8‚…ØH‘`èÀë!x|¦Kÿÿ¼€```B= x¥ðDy)ƒäx¥‚|%HL‚ ûÁÿðûáÿøø!ÿ|xCé(}$S–})QÖ|‰ P|„´xž$}(ð*,)A‚D|¦x‰&ä8€øéC}
J|jL(9(| L,KÿÁ½`é?(9@}Iñ*è|¦8!€ëÁÿðëáÿøN€ €`B„8|ƒ"é$˜,)A‚x¥$|i(*N€ éCé$€x¥&äyJã|i(*M‚ xj"|ixTcÀ>UHÀ>Q#BQHBQ#F>QHF>xcÆ|cCxN€ é#y)ãA‚(è£8€8`@8À8¥D"N€ ``Bè£8€8`@8À8¥D"N€ ``BûÁÿðûáÿøT‰D.TžÆ>ÞKx|xWÞ>é#y)ãA‚Œû¡ÿè8€Æóxè£8`@;¥8¥D"|¬8`<¥ëx8€D",#@‚€TŠD.T‰Æ>})SxU*>?hè¿(Æóx8`@8€})QÖy) |¥JD"ë¡ÿèëÁÿðëáÿøN€ ``Bè£Æóx8`@8€8¥D"ëÁÿðëáÿøN€ ```B9@ÿÿyJ KÿÿŒ``B|¦ûaÿØøø!ÿQ(Alû¡˜¤8ûÁ |ž#x8 8ûA€û8€ûá¨Ú´|x;}pƒêcÚcÛxHøý`DÓxãûxKÿú8€C|pxi$9)y)ä8jxcä|cJKÿ¼U`,#ø|€A‚€¼p8€x¨&äxª¤}#B9J}IRyJäù<ˆx¥$8¥ù\x¥ä9(y)ä|©*Høm`é?뜀y)ã@‚øè¿WÉD.WÆÆ>|ÆKxWž£>TÆ>8`@8€8¥D"|¬è¿WÆÀ>8`@SÆB8€SÆF>xÆ 8¥D"é}?ê9@é)ˆyã@‚P±I¿ê9@é=ˆ±Ié?y)ÿá@‚TëA€ëë¡˜ëÁ cÛxëá¨8!°èëaÿØ|¦N€ 9@¿ê±I9@é=ˆ±Ié?y)ÿáA‚ÿ´€}p8€xc$Kÿ»`ø}˜Kÿÿ˜DÓxãûxû!xûpKÿøñé?|~xxy&äy)ÿá@‚ë_W†À>{˜"S†B8`@S†F>8€xÆ 8º D"WÀ>8º$SB8`@SF>8€xÆ D"œÊë_8`@W†À>{™"S†B8€S†F>8º(xÆ D"W&À>8º,S&B8`@S&F>8€xÆ D"{Þ¤ë_8`@Þâ8€;Þ{Éä8º0U&À>{Þ"Q&BQ&F>xÆ D"WÆÀ>8º4SÆB8`@SÆF>8€xÆ D"è¿8`@8€8À8¥D"ëpë!xKÿþ(``B8ƒ99ÿx„¤Z8|„Jxi$9)x„ä|‰"ƒãxx„ä8 Kÿ»‘`_Ò||xøz Kÿþ¤``B`;`8b…øH
¥`8!°cÛxèëaÿØ|¦N€ `B`;`8b†H
u`KÿýÀ€```B|¦ûaÿØûÿàû¡ÿèøø!ÿa||x|#xèd(|»+x,#A‚ȁD,*A‚ˆûá˜ûAp?@ûÁ{Zƒä;À```Bé<y)ðDy)‚|)Ð@‚\}>S–8€})QÖ})ðP})´y?$y(&ä}#ø*,)A‚4é=}IB|iD(9*| L,Kÿ»!`é=(9@}Iù*è}(]9>|
H@y> AÿˆëApëÁëá˜yD$Kÿ¹•`è},#A‚8é<y)ÿá@‚h=‰y)$9)y)ä8„x„ä|„JKÿ¹U`£ëx8 88€Hô1`8! èëaÿØëÿàë¡ÿè|¦N€ ```Bd´ƒãxKÿõ™8€|ixè}09Iy%&ä8¥ÿyJ¤}J*y%$8¥yIä|¥Jx¥äKÿº!`è}KÿÿP8€Kÿÿ(€```Bé#T†>y)ãA‚$è£8€8`@8¥D"N€ ``Bè£8€8`@8¥D"N€ ```Bûáÿø|Ÿ#xé#y)ãA‚@è£8€8`<8¥D",#9 ÿ@‚T‰>‘?ëáÿøN€ ```Bè£8€8`<8¥D",#9 ÿA‚ÿȑ?ëáÿøN€ ``BûÁÿðTžÀ>PžBPžF>{Þ é#y)ãA‚”ûÿàûáÿø<ÀxŸ"û¡ÿè8€ë£8`@;…ãxD"WæÀ>;½SæB¥ëxSæF>8`@xÆ 8€D"8`@…ãx8€8ÀD"8`@¥ëxÆóx8€D"ëÿàë¡ÿèëáÿøëÁÿðN€ `Bè£Æóx8`@8€8¥D"ëÁÿðN€ `Bé#y)ãA‚ècKÿïÐ```Bè£8€8`<D",#@‚TƒÀ>PƒBPƒF>xc N€ `B<`ÿÿ`cÿÿxc N€ `B|¦ûáÿøøø!ÿa|xé#y)ã@‚Tè£8€8`<D",#@‚,T…À>P…BP…F>x¥ <b8cæP`8‚†8H‰`8`ÿÿHÔ``BûÁ|ž#xècKÿîõxiã|exA‚8xiÿáA‚9 ÿÿy>ŽÄóxãûxKÿþ
é?y)ã@‚ è¿8`<8€D",#@‚¨TƒÀ>PƒBPƒF>xc Éy@‚ û¡ˆ;¡pãûx¤ëxKÿý-!pãûxa)}$´‘!pKÿüµ¤ëxãûxKÿý	!pq)A‚Œûß8`롈ëÁ8! èëáÿø|¦N€ `BèKÿîKÿÿ„`B< ÿÿ`¥ÿÿx¥ KÿþÜ<`ÿÿ`cÿÿxc Kÿÿ`<b8cæP`Åóx8‚†hHM`ëÁ8`ÿÿKÿÿ”``B롈ëÁ8`ÿÿKÿÿ|ëÁKÿþ„€```BûÁÿðûáÿø|ž#x|xû¡ÿèé#y)ãA‚,ë£HA‚Ad,A‚l,@‚D|½ò8`<8€D",#@‚ÜTŠ>xƒ é?y)ãA‚UCÆ>UID.ë¡ÿèëÁÿðëáÿø|cKxTc>N€ `B,@‚ìûÿà8`<8€|½òD",#xœ @‚Œ8¾8`<|½*8€D",#@‚Pé?x„ y)ãA‚T‰À>WƒÀ>ë¡ÿèëÁÿðëáÿøP‰BSƒBP‰F>SƒF>ëÿày$Æxc |ƒxN€ `B,ë£;½@‚ÿ|½ò8`<8€D",#@‚¼xŠ xƒ é?y)ãA‚,UCÀ>ë¡ÿèëÁÿðëáÿøQCBQCF>xc N€ `B8`ÿÿë¡ÿèëÁÿðëáÿøN€ ```B|½ò8`<8€D"|ix8`ÿ,)@‚ÿÈë¡ÿèëÁÿðëáÿøTƒ>N€ ```BxƒÆë¡ÿèëÁÿðëáÿø|cãxëÿàN€ `B<`ÿÿ`cÿÿxc |jxKÿÿ@```B<€ÿÿ`„ÿÿKÿþ¬`B8`ÿÿxc |jxKÿþ$?€ÿÿcœÿÿ{œ Kÿþl`Bûÿàû¡ÿè|Ü3xûÁÿðûáÿøé#y)ãA‚„é#H,{Ÿ ;ÿÿÿÉ*{ÿ ;¤ÿÿ;ÿ@D```B8`<8€ÅóxD",#9 ÿ;Þ@‚T‰>,?=;ÿÿÿ@‚ÿЃãxë¡ÿèëÿàëÁÿðëáÿøN€ `Bé#9)Kÿÿ|``|¦ûáÿøøø!ÿq9 |x‘!pKÿñ…`èrãûxKÿø•`!pãûxa)}$´‘!pKÿøy`é?y)ãA‚<€ãûxx„ƒä`„@Kÿú•`,#A‚X``8‚‡(8b†€H¥`!pãûxa)€}$´‘!pKÿø`9 8!}#Kxèëáÿø|¦N€ `B8pãûxKÿøI`8€ãûxKÿò`,#A‚ÿˆ!pãûxa)}$´‘!pKÿ÷µ`ãûxKÿùy`9 pj@A‚ÿŒãûx8 8€Kÿû©`8!èëáÿø|i´}#Kx|¦N€ `B8€@ãûxKÿøI`Kÿÿp€|¦ûáÿøøø!ÿ8€€|xKÿ÷)`ãûxKÿïý`8!€èëáÿø|¦N€ €`B|¦úÁÿ°ûAÿÐû¡ÿèûÁÿðûáÿøøø!ÿ!9@ÿÿ|¾+x|–#x8 8€™Ap|Ý3x|ú;x|xKÿúÍ`9>ÿÿ})ê|)@Aø8 8€û ãûxKÿú¥`piÿ|e´xx @‚ú€ú¡ˆúá˜û!¨ûa¸ûÀé_éˆyI㢨A‚V¨Æ>V©D.}KxU>}%ñÒ,
럐gJ€£|y)¸"@‚H<â¦9‘G§(=B¦ù*§0="¦‘	§,_pV©<è¿;?p})ª<¦#Ëx9ÉS–8à8Ƨ(ÞQÖÞHPWÔ>×´94~ä»xU)>Kÿì`sI|}ÁÖè¿;9´xg @‚994~ƳxU)>Ãx#Ëx;ÞKÿë½`è¿Ö´9 98à~ijx8Áp#ËxKÿë•`pèÿé_ˆxçã}5C–})AÖ})¨Py) A‚VˆÆ>V‡D.};xU>y)¤}*J²‰|¬é95é_ˆU)>yãA‚U(Æ>U'D.};xU	>±*8€ãûxKÿî`Kÿ§`;È{Þ H ``B|¬Kÿ§m`|ð@A¡<|	Ø@A‚ÿäè¿~ä»x#ËxKÿì5`è¿Ãx#ËxKÿì!`è¿#Ëx~ijxKÿì
`‰!p£´,)A‚ ˆ¡p`DÓx8b†ðHÿ•`8`ꁀꡈêá˜ë ë!¨ëa¸ëÀ8!àèêÁÿ°ëAÿÐë¡ÿèëÁÿðëáÿø|¦N€ ``B<â¦=8ç§(}@=,=B¦9J§0} U(="¦‘	§,Kÿý´``B`8b†Hÿi`8!à8`èêÁÿ°ëAÿÐë¡ÿèëÁÿðëáÿø|¦N€ ``B<b8cæP`8‚†ÈHþq`ë 8!à8`èêÁÿ°ëAÿÐë¡ÿèëÁÿðëáÿø|¦N€ €|¦ú¡ÿ¨úÁÿ°úáÿ¸ûÿÀû!ÿÈûAÿÐûaÿØûÿàû¡ÿèûÁÿðøûáÿøø!ÿ1||x|—#x8€|µ+x|Ù3x|ú;xKÿçñ`è¼ëܐé\ˆ;p|vxx©㣾£êA‚WéÆ>WêD.})SxU?>Wû<z§ };ú~æ»x}I³–9Ãxj±Ö{HPWu>w´95~ä»xU)>;{Kÿè™`€úè¼{´9 9dÛx&ËxÃxKÿèq`}?³–éé\ˆyã})±Ö})øPy) A‚V¨Æ>V§D.};xU>y)¤}*J²©|¬é\;ÿé<ˆWÿ>yJãA‚WêÆ>WèD.}JCxU_>³é8€ƒãxKÿêå`¡>|H@@‚ì= L?à˜a)K@cÿ–})¦H,``B}_´|¬¡>9_ÿÿ|	è@@‚ }_´B@¬|¬¡>9_ÿÿ|	è@A‚ÿÐè¼~ä»xÃxKÿèñ`è¼dÛxÃxKÿèÝ`,?A‚”}@Ì,:|	P@AP‘:8`8!Ðèê¡ÿ¨êÁÿ°êáÿ¸ëÿÀë!ÿÈëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ ``B}ISxKÿÿ°è¼~ä»xÃxKÿè]`è¼dÛxÃxKÿèI`Kÿÿt8`ÿÿKÿÿ„€``Bûÿàø!ÿa9 =B¦‘!p늧:,<@‚$|¦Ê§8û¡ˆ|#xûÁûá˜|¾+x|xø°Kÿèý`èrãûxKÿð
`!pãûxa)}$´‘!pKÿïñ`é?y)ã@‚8€ãûxKÿðÅ`8€ãûxKÿê`,#A‚¨!pãûxa)}$´‘!pKÿï¡`<bÿÿÆóx¥ëxäûx8cc¸HE`è°ë¡ˆëÁëá˜|¦8! ƒãxëÿàN€ ``B<€ãûxx„ƒäKÿñ…`,#@‚(8pãûxKÿï`KÿÿX;€ÿÿKÿÿ´``B``8‚‡Ø8b†€Húq`!pãûx;€ÿÿa)€}$´‘!pKÿîá`Kÿÿ\€``B|¦ûáÿøøø!ÿ8€€|xKÿî©`ãûxKÿç}`8!€9 =B¦èëáÿø‘*§8|¦N€ €``B|¦ûÿàû¡ÿèûÁÿðûáÿøøø!þ‘9 `9<¦€Æ§88â‡89@ø0;Á|¼+xù!ù!(8 8€ù!ðù! Áù!ø|}xù!øá‘(‘AðûÁKÿò`Tf>(@8À;ápTÆ>äûx8 £ëxKÿô9`Ãóxûá HÙ`|y@‚¬Ãóx;¡0Hq`8€|yA‚ H¼``Bé!0‰),	A‚”¦ëx8 ÃóxH E`8€,|x@€ÿÐ|dx`8b‡xHø¡`€(ÃóxH1`8!pãûxèëÿàë¡ÿèëÁÿðëáÿø|¦N€ `B`äûx8b‡@HøU`Kÿÿ´``BûaH;aðcÛxH%õ`|y@‚˜8€cÛxH#-`|y@‚è¡; ;à,%@‚ H|`BAžà衽|%è@@Ð|½(P¦ëxx¥ |œêcÛxH$	`,/£|x@€ÿÄ|dx`8b‡ÀH÷¥`H ``B`äûx8b‡H÷…`€ðÃóxH`€(ÃóxH`ëaH8!pãûxèëÿàë¡ÿèëÁÿðëáÿø|¦N€ `B`äûx8b‡`H÷%`Kÿþ„``B¿ëxKÿÿ`äûx8b‡¨Höý`Kÿÿx€`|¦úaÿ˜úÿ }€&ú¡ÿ¨úÁÿ°úáÿ¸ûÿÀû!ÿÈûAÿÐøûaÿØûÿàû¡ÿèûÁÿðûáÿø‘ø!ÿ!|x|³+xèc|Ô3x|ö;xé?ø}Cx;_àxjã£ÉA‚WÉÆ>WÊD.})SxU>>_àWÛ<.6ë¿};ò|†#x|ex9iS–8à3£CÓx{QÖ{HPWu>w´95~ä»xU)>;;Kÿàí`9´A’,8@‚xè¿~f›x9 98àl$ËxCÓxKÿà¹`àèÿé_øxçã}>C–})AÖ})ðPy) A‚V¨Æ>V§D.};xU>y)¤}*J²©|¬é_;Þé?øWÞ>yJãA‚WÊÆ>WÈD.}JCxU^>³É8€ãûxKÿã)`Kÿœ±`8cˆx~ H$```B|¬Kÿœ`|ð@A¡=|	à@A‚ÿäè¿~ä»xCÓxKÿáU`è¿$ËxCÓxKÿáA`A’,8@‚Ð8!à8`聁êaÿ˜êÿ ê¡ÿ¨êÁÿ°êáÿ¸ëÿÀë!ÿÈëAÿÐëaÿØëÿà|¦ë¡ÿèëÁÿðëáÿø} N€ ```BúAp,495:›U)>~”´{ è¿A‚p~f›x98àl$ËxCÓxKÿß)`è¿~G“x~Ƴx~„£x9 9CÓxKÿß`êApKÿþH`Bè¿8›CÓx|„´KÿàQ`Kÿÿ`B~G“x~Ƴx9$ËxCÓxKÿÞ½`è¿~f›x~„£x9 98àlCÓxKÿޙ`êApKÿýÜ€```B|¦ûáÿøøø!ÿa9 8€|x‘!pKÿè`!pãûxa)}$´‘!pKÿçå`é?y)ãA‚D<€ãûxx„ƒäKÿê`,#@‚à8pãûxû¡ˆûÁKÿè`H$``B8€ãûxû¡ˆûÁKÿèq`8€ãûxKÿá±`8€|~xãûxKÿá`8€|}xãûxKÿá‰`,>A‚\,=A‚T,#A‚L!pãûxa)}$´‘!pKÿç`롈ëÁ8`8! èëáÿø|¦N€ ```B롈ëÁ``8‚‡è8b†€Hò9`!pãûxa)€}$´‘!pKÿæ­`8`ÿÿKÿÿ €|¦ûáÿøøø!ÿ8€€|xKÿæy`ãûxKÿßM`8!€èëáÿø|¦N€ €`|¦ûÿÀûáÿøøø!ÿ1|x8`(KÿœÅ`|xyA‚,?9 û°;˜‘8A‚häûx8 úሃãxHÙÝ`ƒãxKÿÞÁ`8€ƒãxKÿåÑ`êø9 ‘!p,7A‚(êáˆë°8!ÐÃxèëÿÀëáÿø|¦N€ 8€ƒãxKÿå‰`é8y)ã@‚9 
=B¦û!˜ûa¨8€ƒãx‘*§<KÿæI`8€ƒãxKÿ߉`8€|yxƒãxKÿßu`,9|{xA‚,,#A‚$<b¦€c§<ûA ;à;@û¡¸ûÁÀ?¢¦;½§<8cêxc8(Kÿ›`,#øy|~xA‚üúÁ€H```BëÙ€ýè¸WI>ä´9#ËxWö>;ÿ9Gê{ÿ }J¹ÖyJ ÞRÆóxKÿÚÕ`€Ýè¸9 98àêD´#Ëx|ÆòKÿÚ­`èØ9Wzç¤é9,
€}W´9xÊây /ªVÈD.VÊÆ>}):}JCxAžUV>²É@‚ÿP|¬ééY9 yãA‚9 ±*9 €ééYyãA‚9 ÿÿU) ±*éXé9 yJã¡)=B¦A‚œ9J§@} W,é[9 ±*9@ƒãx;Àé;±I!pa)}$´‘!pKÿã}`8€ƒãxKÿÜ­`9 ‘8Ä´8 ƒãx;þKÿçm`ä´8 |ixƒãx}8ñ®;ÞKÿçM`,?|xù®@‚ÿÀêÁ€êáˆë!˜ëA Ãxëa¨ë°ë¡¸ëÁÀ8!ÐèëÿÀëáÿø|¦N€ `8bˆ HîE`ë!˜ëA ëa¨ë¡¸ëÁÀ!pƒãxa)€}$´‘!pKÿâ¥`êáˆÃx8€(Kÿ›1`끰8!Ð;ÃxèëÿÀëáÿø|¦N€ <€ƒãxx„ƒä`„ Kÿä•`,#@‚ÿ9 =B¦û!˜ûa¨8pƒãx‘*§<Kÿâ‰`Kÿüб*§@é[9 Kÿþl`8b‡øHíu`KÿüPƒãx8€ƒKÿáñ`êáˆë!˜ëa¨KÿÿD€
```Bûáÿøø!ÿ|yA‚0|¦ø?,	@‚0ãûx8€(Kÿš5`è|¦8!€ëáÿøN€ ``BûÁp;ß8€€ÃóxKÿáa`ÃóxKÿÚ5`9 <‚¦€„§<舑?8„êx„8(Kÿ™Ñ`9 Ãóx8 8Ÿ€ù?ˆKÿß5`Ãóx8 8Ÿ¸Kÿß!`ëÁpKÿÿX€`Bû¡ÿèûáÿøø!ÿQ|yA‚Œ,$ûaˆ|›#xA‚pûûÁ ;Ÿ=¦¡§@y é_é? yJã¡I@‚„|
@@; A‚|¦û!xûA€x¹ ?¢¦ƒ½§<øÀ€}GC–}JAÖ}J8PyJH})RƒÉI9>½PPÉC–|(@{º ÞAÖÞHP{Þ Aœ½´Å´8€ƒãx;ÞÿÿKÿ؁`EÓxWÞ>|dxcÛxHÓé`é?<â¦é˜¡G§@y)ã¡(9J±G§@€ÿ€A‚$U*D.U&Æ>|ÆSxWÉD.WÊÆ>}JKxTÉ>U^>}I;–}J9Ö}JHPyJ yJ¤}HR³Ê|¬é9)é_˜U)>yãA‚U(Æ>U'D.};xU	>±*ƒãx8€Kÿؕ`èÀë!xëA€ëaˆëëÁ |¦8!°£ëxë¡ÿèëáÿøN€ ```BUFÆ>UDD.|Æ#x; TÊ>|
@@A‚ˆ|¦û!xûA€x¹ ?¢¦ƒ½§<øÀ€}GC–}JAÖ}J8PyJH})R9I9)ÀT,}@L,9>½PPÉC–|(@{º ÞAÖÞHP{Þ @þl`|½+x8bˆH:ËxHéí`KÿþTëaˆëëÁ 8!°£ëxë¡ÿèëáÿøN€ ëaˆ; ÿÿKÿÿ; ÿÿKÿÿ€ûáÿøø!ÿA|yA‚p,$ûa˜|›#xA‚T|¦,êúÁpûAû ;_|¼+x:߸øÐAìû!ˆúáx?"¦û€û¡¨;9§BûÁ°é?y)ãA‚?"¦;9§L<¢¦€¥§<8€#ËxHÑ9`è¿é?Ðxª㣩A‚W©Æ>WªD.})SxU=>_¸W¾<~óxÉóxÞS–ÞQÖÞHPØ´{× Ãx;ÞKÿÕ`è¿Þ´~óxÄóxV÷>KÿÔõ`<⦀ç§<è¿97Ãx&ËxU)>9~óxKÿÓY`è¿9 9{‡ ÄóxfÛx~óxKÿÓ5`¸èÿé_Ðxçã}=C–})AÖ})èPy) A‚VèÆ>VçD.};xU>y)¤}*J²é|¬é_;½é?ÐW½>yJã@‚d³©|¬8€CÓxKÿÕ±`èЃãxêÁpêáxë€ë!ˆëAëa˜ë ë¡¨ëÁ°|¦8!ÀëáÿøN€ ```BWªÆ>W¨D.}JCxU]>Kÿÿ```B`8bˆxHçi`èÐêÁpëAëa˜8`끠8!À|¦ëáÿøN€ ``Bëa˜8`ÿÿKÿÿ€8`ÿÿKÿÿx€
|¦ûÿàøø!ÿa9 ||x‘!pKÿÔe`èrƒãxKÿÛu`!pƒãxa)}$´‘!pKÿÛY`é<y)ãA‚x<€ƒãxx„ƒäKÿÝy`,#A‚Ä``8‚ˆè8b†€Hæ‰`!pƒãxa)€}$´‘!pKÿÚý`8! 8`èëÿà|¦N€ ```B8€ƒãxû¡ˆKÿÕ`|}yA‚|8`ûá˜;àKÿ‘I`,#ø}A‚dûÁH```Bè}è¼þ´{ædÄóx|Ã29 98à£ëxKÿЩ`é\èWé>{Þ¤;ÿU(Æ>U'D.(?€yJâ};x/ªÄòAžU	>±>@‚ÿ”éé]9 €yãA‚9 ÿÿU) ±*|¬é\é= yJã¡)A‚U*Æ>U(D.}JCxUI>=B¦8€ƒãx±*§XKÿÓù`,#A‚”!pƒãxa)}$´‘!pKÿٕ`롈ëÁëá˜8! 8`èëÿà|¦N€ 8pƒãxû¡ˆKÿÙ½`8€ƒãxKÿӍ`|}y@‚þŒë¡ˆKÿþ`8bˆ˜Hä`롈ëá˜Kÿýô롈ëÁëá˜Kÿýä€```B|¦ûáÿøøø!ÿ8€€|xKÿØÙ`8Ÿ¨ãûx8 KÿÖå`8Ÿpãûx8 KÿÖÑ`ãûxKÿх`8!€èëáÿø|¦N€ €```BûÁÿðø!ÿQé#¸˜è,)A‚Ü|¦ûA€ûá¨;C¨ûpû!x|xûaˆûû¡˜øÀè£é#Àxª㣉A‚W‰Æ>WŠD.})SxU<>€Ÿ¨ë¿È9 8à8Áè9CÓx{˜ }\#–£}}J!Ö}JàP}Y´y^ $ËxKÿÎ`€ß¨è¿èÿÀWÊ>x¥ã}83–})1Ö})ÀPy) A‚UHÆ>UFD.}3xU
>y)¤}'J±I|¬é_;œé?ÀWœ>yJã@‚¨³‰8€ãûxKÿЙ`KÿŠ!`8cˆx~ H$```B|¬Kÿ‰ý`|ð@A€¡=|	Ø@A‚ÿä;Àè¿$ËxCÓxKÿÎÁ`èÀëpë!xëA€Ãóxëaˆëë¡˜ëá¨8!°|¦ëÁÿðN€ `BWŠÆ>WˆD.}JCxU\>KÿÿL```B`;À8bˆÈHâ`Kÿÿ€``B8!°;ÀÃóxëÁÿðN€ €|¦ûáÿøøø!ÿ9 |x8 x8€8axù!pHÉÉ`é_é?=¦¡§XyJã¡IA‚HUGÆ>UFD.|ç3x8`Tê>|P@A‚ûÁð_p|èS–|çQÖ}@PyH})B9)} L,9)8€ÉS–ãûxÞQÖÞHP;ÞÿÿÅ´WÞ>KÿÎ!`8 |dx8apHɍ`é_<â¦éˆ¡'§XyJã¡H9)±'§X€ÿpA‚$UID.UFÆ>|ÆKxWÊD.WÉÆ>})SxTÊ>U>>}*;–})9Ö})PPy) y)¤}(J³É|¬é9Jé?ˆUJ>yãA‚UHÆ>UGD.};xU
>±I|¬8€ãûxKÿÎ5`ˆapëÁð8!èëáÿø|¦N€ |
@@8`A‚ÿäûÁð_p|èS–|çQÖ}@PyH})B)KÿþЀ`BéCé#yJã¡)A‚U*Æ>U(D.}JCxUI><b¦ c§X|cJx|c4TcÙ~hcN€ `="¦øi§`="¦ø‰§h="¦ø©§p="¦øɧxN€ |¦ûáÿøøø!ÿ8  ?â¦8€è§pHǁ`<b¦èc§x8  8€HÇi`8!€é?§p=B¦èëáÿøù*§€|¦N€ €`Bûáÿøø!þ±?â¦="¦é)§`<‚¦è„§p<¢¦è¥§€C;ÿ§`,)‘A8|¤(PA‚,$A‚èß,&A‚ô(
 A¼x¨ |
@@A€À|¦øA(è|¥´8á8ø`}%,éIéi}I¦èIN€!èA(,#@‚”é_é?9
|àF,9	}F,|@@@‚4‰	(kA‚ˆ‰*9)|	@@‚(è`|¦8!PëáÿøN€ è`8`ÿú|¦Kÿÿèè`8`ÿû|¦KÿÿØ8`ÿóKÿÿÐ``B8`ÿüKÿÿÀ``Bè`8`ÿù|¦Kÿÿ¨8`ÿôKÿÿ 8`ÿøKÿÿ˜ûÁ@;Áp8 È8€ÃóxHÅÍ`èŸ9$8„	| N,(Æ@8 ÇÃóxHÃ5``Äóx8b‰HÝq`è`ëÁ@8`ÿý|¦Kÿÿ,€``B|¦ûaÿØûÿàû¡ÿèûÁÿðûáÿøøø!ÿa8  ?¢¦|x?b¦8€è}§p?‚¦`;‰HÅ`è{§x8  8€HÅ	`é=§p8à9d9@ÿÿÃóxù<§€éé<§€8éøü§€™	é<§€9	ù§€±Ié<§€9Iù\§€}@ü,‘Ié<§€9)ù<§€HÁ%`é<§€|jxÃóx}@O,뼧€;½û¼§€HÁ`Äóx|ex£ëxHÄÍ`ÃóxHÀá`é<§€|jxãûx})Rù<§€Kÿý|~yA‚,8! ÃóxèëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ é;§x_9	}D,|
@@@}
Cx‘_8‰
9)`8b‰ | N,HÀÍ`,#@‚ÿ˜;ÀÿþKÿÿ€``B|¦ûÁÿðûáÿøøø!ÿa|xècHÀ`|~xèHÀ`?Þ;Þ|	ð@A€¼?¦8  û€û¡ˆ8€; ÿÿè~§pHÃM`<b¦èc§x8  8€HÃ5`é>§p<¦8à9h9@|Ü3xù&§€éé&§€8éø槀™	é&§€9	ù§€±I9?`B}@L,é&§€9	ù§€‘Ié&§€9IùF§€“©é&§€è9)ù&§€H¿1`é<§€|`O,ëܧ€èŸ;Þ|ƒ#xøpûܧ€H¿	`èp|exÃóxHÂÕ`èH¾é`é<§€|jxè})Rù<§€H¾Í`é<§€|`O,ëܧ€èŸ;Þ|ƒ#xøpûܧ€H¾¥`èp|exÃóxHÂq`èH¾…`é\§€|ixãûx}
Jù§€ªI.é<§€ë¡ˆ9)ù<§€ë€8! èëÁÿðëáÿø|¦KÿúŒ``B8! 8`ÿüèëÁÿðëáÿø|¦N€ €``B|¦û¡ÿèûÁÿðûáÿøøø!ÿq8  ?¢¦|~x|Ÿ#x8€è}§pHÁQ`<b¦èc§x8  8€HÁ9`é=§p<¦8à9x9@8!Ãóxù&§€éé&§€8éø槀™	é&§€9	ù§€±Ié&§€9IùF§€àU,èé&§€ë¡ÿèëÁÿðëáÿø|¦9)ù&§€KÿùŒ€```BûÁÿðø!ÿ1ëÆ,>A‚`|¦ûA ?B¦û|xxû°û¡¸|œ#xèz§p|½+x8€úáˆ8  û!˜ûa¨|Û3xûáÈúÁ€`ßóxøàHÀ9`<b¦èc§x8  8€:à;"›ðHÀ`é:§p<¢¦9@8àn9ù%§€‘Ié%§€8Éøŧ€˜éé%§€8éø姀±	é%§€9	ù§€€E,é%§€9	ù§€ E,é%§€9	ù§€±Ié%§€9)ù%§€‰>,)A‚ú¡x``B+‰/üûx@ž(`B?(	/A‚ÿø,)üûx```BA‚?+‰/,)@žÿð¼øP„ãx¥ëx#ËxH¼`,#A‚„<â¦è秀="¦é)§p:·?B¦U
;Z§`~¶´})8P9)})ê9J	|	@@A||P@A€t ?,„ãx¥ëxèz 8cøz H¿`é: ,})êù: A‚h~׳x‰?,)@‚ÿ,7@‚ê¡xÃóxH»`,#@‚L9 :À=B¦éJ§pûûÃx±*Kÿ÷%,#@‚”="¦é)§x9)} N,|	°A‚ð,)9)ÿÿ}*´A‚X‰>(	/@‚4`B>(	/A‚ÿø,)A‚$```B>(	/A‚,)@‚ÿð9*ÿÿ,	ÿÿ}*´@‚ÿ°ûۈ~|c4TcÙ~hcèàêÁ€êáˆëë!˜ëA ëa¨ë°ë¡¸ëáÈ|¦8!ÐëÁÿðN€ VéÆ>VêD.ê¡x})Sx~ö»xU)>Kÿÿ‹üÿÿ,7kÿ/ÿ4WÿÙ~ÿàPA‚þÄKÿÿÈëÛKÿÿxê¡x9 KÿþÌ8`ÿ÷Kÿÿ 8`ÿöKÿÿl€`B|¦ûaÿØûÿàû¡ÿèûÁÿðûáÿøøø!ÿa8  ?‚¦|x?b¦|ž#xè|§p8€ë¿sÞ_H¼Í`è{§x8  8€H¼¹`èü§p<¦9 9p9@£ëxø槀‘?è槀‘'é&§€8éø槀™	é&§€9	ù§€±Ié&§€9IùF§€}@ü,‘Ié&§€9IùF§€›Éé&§€9)ù&§€Kÿõ	,#@‚é;§x9)} L,‘?8! èëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ €```B|¦ûAÿÐûaÿØûÿàû¡ÿèûÁÿðûáÿøøø!ÿa?¦|x|½+x|›#xè~§p8  8€ë_|Ü3xH»™`<b¦èc§x8  8€H»`é>§p=B¦ù*§€ƒÚ;Þÿõ|è@@¾ëx8à<¦9t9@éCÓxé&§€8éø槀™	é&§€9	ù§€±Ié&§€9IùF§€}@ü,‘Ié&§€9IùF§€€U(é&§€9	9)ÀE,ù&§€Kÿó¹,#@‚4<‚¦è„§x9$àL,|ø@{å A€D8„cÛxH»`ã´8! èëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ `B8`ÿõKÿÿЀ```B|¦ûÿàû¡ÿèûÁÿðûáÿøøø!ÿq8  ?¢¦|x?‚¦8€è}§pëßHº)`è|§x8  8€Hº`é]§p<¦9 8à|9ù?™?ÃóxùF§€‘*é&§€9IùF§€˜éé&§€9IùF§€±	é&§€9IùF§€}@ü,‘Ié&§€9)ù&§€Kÿòu,#@‚é<§x9I*}@T(ù_‰)™?8!èëÿàë¡ÿèëÁÿðëáÿø|¦N€ €`|¦ûÁÿðûáÿøøø!ÿ?¦?â¦ëÿ§ˆ;Þ§ˆ,?A‚Hé?=B¦8 €8€ãûxù*§ˆH¹
`9 ù?8!€ãûxèëÁÿðëáÿø|¦N€ 8`Kÿ{í`|yA‚d9@9?€ù_A‚ù)ÿ€9}	¦ùI9)€B@0()€A‚ù)ÿ€,)ùI9)€A‚ÿÜù)ÿ€ùI9)€BÿØ="¦û駈KÿÿLûþKÿÿl€``B,#="¦é)§ˆA‚$}*Kxé),)@‚ÿôøjù#N€ `B,)@‚ÿÜN€ ``B|¦øø!ÿ‘|iyA‚`é),)A‚Té),)A‚Hé)0,)A‚<øA(éIéi}I¦èIN€!èA(8!pè|¦N€ ```B``8‚‰h8b‰(HÏa`8!p8`è|¦N€ €``B|iyM‚ é),)M‚ é),)M‚ é),)M‚ é)@,)M‚ |¦øø!ÿ‘øA(éIéi}I¦èIN€!èA(8!pè|¦N€ €`B|iyA‚|éI9 ,*A‚péJ,*A‚déJ,*A‚XéJH,*A‚L|¦øø!ÿ‘øA(é*éj})¦èJN€!èA(8!pè|¦N€ ```B9 }#KxN€ €``Bûáÿøø!ÿ|yA‚T="¦é)§,)A‚$}*Kxé)P,)@‚ÿôûêP8!€ëáÿøN€ ="¦8!€û駐ëáÿøN€ ```B|¦`8b‰8øHÍ¡`è|¦Kÿÿ€ø!ÿ‘,#="¦é)§A‚€,)A‚déH```Bé)P,)A‚DIX|*@@‚ÿì|¦øA(ø€ù#é)éIéi}I¦èIN€!èA(è€|¦8!pN€ ```B|¦`8b‰@ø€HÌá`è€|¦KÿÿÌ€ø!ÿ‘|iyA‚Hé)é),)A‚0|¦øA(ø€éIéi}I¦èIN€!èA(è€|¦8!pN€ |¦`8b‰@ø€HÌa`è€|¦KÿÿØ€|iyA‚œ|¦øø!ÿ‘é),)A‚Té),)A‚Hé),)A‚<é)(,)A‚0øA(éIéi}I¦èIN€!èA(8!pè|¦N€ ``8‚‰x8b‰(HËÁ`8!p8`è|¦N€ `B8`N€ €```B,#M‚ é#,)M‚ |¦øø!ÿ<à8p8 C¡èi 9 áp±!v}ICx9At} W,Kÿþñ8!€è|¦N€ €,#A‚¬èc ,#A‚ |¦øø!ÿ‘é#,)A‚Xé),)A‚Lé),)A‚@é)(,)A‚4øA(éIéi}I¦èIN€!èA(8!pè|¦N€ `B``8‚‰x8b‰(Hʁ`8!p8`è|¦N€ `B8`N€ €```B|iyA‚˜,$|ª+x|Å3x|æ;xA‚xèi(,#A‚x|¦øø!ÿ‘é),)A‚té),)A‚hé)8,)A‚\øA(}DSxèééi|é¦}CxèIN€!èA(8!pè|¦N€ `Bèi0,#@‚ÿ8`N€ ```B``8‚‰ˆ8b‰(HɁ`8!p8`è|¦N€ €``Bûáÿøø!ÿ|x‰$y) (	A‚((	A‚€8!€8`ëáÿøN€ ```B|¦‰$U)Éþ,	øA‚,Kÿùø(8`è8!€ëáÿø|¦N€ ``BKÿøñø08`è8!€ëáÿø|¦N€ |¦øKÿøÉø8`è8!€ëáÿø|¦N€ €```Bûáÿøø!ÿ|iyA‚4Id= ;àa)|
HA‚<8!€ãûxëáÿøN€ ``B8!€;àãûxëáÿøN€ ```B|¦øHLY`è8!€ãûxëáÿø|¦N€ €```Bûáÿøø!ÿ|iyA‚4Id= ;àa)|
HA‚<8!€ãûxëáÿøN€ ``B8!€;àãûxëáÿøN€ ```B|¦øHM©`è8!€ãûxëáÿø|¦N€ €```Bûáÿøø!ÿq|yA‚¤‰?e,	A‚8!8`ëáÿøN€ `B_`,
A‚ÿä|¦û¡xûÁ€; ;ß8ø ‰>U)¾,	A‚09=;Þ|
H@y= Aÿàè ë¡xëÁ€|¦Kÿÿ”`B8À8 ÄóxãûxKÿýA_`Kÿÿ¼`B8!8`ëáÿøN€ €`Bûáÿøø!ÿ|yA‚t‰?e,	A‚8!€8`ëáÿøN€ `B|¦øè(,#A‚Kÿöíè0,#A‚ KÿöÝè8!€8`ëáÿø|¦N€ è|¦Kÿÿ¤`B8!€8`ëáÿøN€ €`B|iyA‚Üø!ÿ99)x=@!ÿèiÿ¨±v} N,‘Ap,#±!tA‚ |¦øé#,)A‚\é),)A‚Pé),)A‚Dé)(,)A‚8øA(8p8 éIéi}I¦èIN€!èA(è8!€|¦N€ ``8‚‰x8b‰(HÅ`è8`8!€|¦N€ `B8`8!€N€ `B8`N€ €```B|¦ûáÿøøø!ÿ|xèc(Kÿù)è0Kÿù!8`Kÿli`8!€èëáÿø|¦N€ €|¦ûaÿØûÿàû¡ÿèûÁÿðûáÿøøø!ÿ!; 9 8Àƒt“£l8 |œ#x8”‘!–|x;a‚;ÁpKÿôA= €dÛxa)Åóxy)Æø a)ù;Kÿ÷½,#A‚¨é? ‰Aw±I?h,	A‚P9\9 “¡†ë¿è 8 dÛx±!‚‘_t9=.} N,±!„Kÿ÷i,#A‚Xé=(9Iù](‘?l|¬8`dKÿkU`= €9A‚è a)Åóxy)ÆdÛxa)ù*Kÿ÷,#@‚08`8!àèëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ `B= €;Á‹è a)eÛxy)ÆÄóxa)	ù>Kÿö½,#A‚ÿ¨9!„£¡„`N,(	A‚ÿ”cÛxûA°Kÿlõ`|zyA‚(è = €9@³¡‘a)EÓxÄóx±A‘!‹Kÿöa,#@‚(CÓxdÛxKÿm-`ëA°8`Kÿÿ4``B9@‰!‡9	è Äóx8 ‘A9A±‹} W,Kÿö	,#A‚ÿ¬û!¨|¬8`d;º	Kÿiý`9;ÿ÷; U>>H8`B@‚ ?`‰Y(	±_x@Œ9)‘?`}<ðP½âq>ÿÿA‚¤‰=‹+‰(	@žÿÀ‰=‰]‰¹ëxU)€UJ@.})Sx})Cx‘?dKÿÿ¸`B``…ãx8‚‰ 8b‰PHÁ`ëA°8`Kÿþ4``B9)8 y)H¤ëx|JH©Ý`?`KÿÿX```BCÓxdÛxKÿkÙ`ë!¨ëA°8`KÿýÜ€`N€ ,#A‚Ü|¦ûáÿøøø!ÿëã è¿8¥|¬<ÀÃ8`@xÆ 8€D"8`Kÿh‘`è¿8¥|¬8`@8€8ÀD"蟰,$A‚$è¸8 Kÿo	`è°8€Kÿk`èŸ,$A‚$è¨8 hKÿnÝ`è8€hKÿjí`ãûx8€ÀKÿmm`8!€èëáÿø|¦N€ é# à€```BûÁÿðûáÿøø!ÿ!|~yA‚<|¦úá˜û |·+xû¡Èû!¨|#x|Ø3xûÀøðé>ë) ëù,?A‚ôé?,)ù9A‚¤8  8€ãûxH§µ`9 ûßù?‰=y( (‘>h‘?9=} N,±?U<>‰=y) ±?‰]UJ0‘_A‚P(A‚(èðêá˜ë ë!¨ëÀë¡È|¦8!àãûxëÁÿðëáÿøN€ `Bù9 Kÿÿ\``Bdm
,
A‚=@	|P@‚ÿ¤ú€~˜ã’úaxWŠ^ú¡ˆûA°U)80ûa¸€þhlëyë_0}J;xU~}JCx}IKxa)P9_ÿð} U,:tz™ ~u´zµ&ä~£«xKÿh•`|}yA‚(8 ~¤«xúÁKÿl`~¥«x8€|vx£ëxH¦a`Ãx8€~ã»xH¦M`8 Ãx~ã»xKÿkÙ`,úß8û¿ ’Lúÿ(“Hø@|jx@ä99ÿÿ8Üÿÿy) xÆ 9)8 ð})¦9=```B8‰ÿô|ê2}HP}@%,8‰ÿü©ÿð}²}Jâ|à%,8éÿø9)}=,BÿÐ99ÿÿy)'½J})²9=@aJ‘‘ÿü9ÿø~ÀE,9ÿô} E,>d|	PA‚è=@	|	PA‚¨?êaxꁀꡈêÁ,	@‚$ëA°ëa¸```B?8À,	@‚8À>l€þh¡¡_U)~|ç3x});xU^UJ=p})Cx})Sx9_ÿða)@} U,Kÿý8`KÿfÝ`,#øy°||xA‚Ø8 8€ú¡ˆúÁûA°ûa¸KÿjM``Ÿãx:Ü`;@øy¸|{x:¢‰¸H(`B|6ø@}<øP})Ú9_pù?@A‚<ù_;ÿ`séû_A‚ÿØ~£«xH¼1`|6ø@}<øP})Ú9_pù?@@‚ÿÌé9;ü,)A‚¼é9 ûéëù;œpû™ ꡈêÁëA°ëa¸Kÿü,``Bèðêá˜ë ë!¨ëÀë¡È|¦8!à;àãûxëÁÿðëáÿøN€ 9;@M,?ÿðU)‘?ÿðêaxꁀꡈêÁëA°ëa¸Kÿü0WIÀ>SIBSIF>‘;‘; ‘;@‘;`Kÿÿ¸ûùKÿÿP``8‚08b‰ðH»1`êaxꁀꡈëA°ëa¸KÿûÔ~ɳxKÿýŒèðêá˜ë ë!¨ëA°ëa¸ëÀë¡È|¦KÿûÈ€
ûáÿøø!ÿa|yA‚pé?,)A‚d|¦ûÁø°é)ëÉ é> ,)A‚Xûé?,	A‚X9 ûþ ãûx8  8€ù?ù?H¢‰`è°ëÁ|¦8! ëáÿøN€ ``BûþKÿÿ¬``Bû¡ˆ= a)뿁]d|
HA‚= 	|
HA‚롈Kÿÿ€ûaxû€?ÿðëžë0e)@‘?ÿð|¬9 €¿HèŸ(è@‘?ÿø‘?ÿô‘?ÿüKÿhE`€¿LèŸ è8x¥&äKÿh-`€ŸLè x„&äKÿd9`]dmI,	A‚D= 	|
HA‚ëax끀롈Kÿþä`B9<`M,ëax끀롈KÿþÈ``BWiÀ>SiBSiF>‘<‘< ‘<@‘<`Kÿÿ°€`BN€ |¦úAÿúaÿ˜}€&úÿ ú¡ÿ¨úÁÿ°úáÿ¸ûÿÀû!ÿÈøûAÿÐûaÿØûÿàû¡ÿèûÁÿðûáÿø‘ø!ÿ!:à|›#x|Ú3xëƒ|~x|¹+xKÿ_ý``>b`{{ 8cˆXÓxx} :À:¢Š0:s߸:‚ŠH``B|¬è¾8`<8€8¥D",#@‚lT‰À>P‰BP‰F>q*y? ```B@‚HKÿ_}`|è@A |¬è¾8`<8€8¥D"/£T‰À>P‰BP‰F>q*y? Ažÿ¼9<„|€L,,$A‚ÿl’Ü„|¬.8A’ˆù Pé&t|)Ð@€lÿÚA‚d;ÿÿ|¬} ü,_y('#U2'>@‚aJ9?|€L,’ß‘_|¬/¤ù Pé&t.8ÿÚ~ºHAž A’@•@‚ÿ¨`B~£«xH·=`è¾8¥|¬8`@8€<ÀD"|¬è¾8`<8€8¥D"@’þ H$``B`äûx8bŠ:àH¶á`8!à~ã»x聁êAÿêaÿ˜êÿ ê¡ÿ¨êÁÿ°êáÿ¸ëÿÀë!ÿÈëAÿÐëaÿØ|¦ëÿàë¡ÿèëÁÿðëáÿø} N€ `By$åûx~ƒ£x|“@*H¶q`(_}2Ð@þØ}7´KÿþЀ`B|¦ûÁÿðøø!ÿQ#,	@‚|éfp})”û|ü;x(	AÐ,$|ž#xA‚$ûA€û¡˜8€|½+xûá¨ûp|x8 û!xûaˆ|Ú3xƒcÃóxHí`FÓxˆãx,;@‚È= ðy) ,<A‚¨U%À>;€Q%B8€Q%F>Éóxx¥ H@`B8iÿô}
@Q;œ|À,8iÿü|ÆR}`,TëÀ>©ÿðPëBPëF>yg ‘iÿøA‚`+¨9)|þHP,&9fÿÿ}
Cx|ý:@9@}kR@‚ÿ }
@QTëÀ>Éÿô‰ÿüPëB©ÿð|ÆRPëF>;œyg ‘iÿø@‚ÿ¨W£À>S£BS£F>?8€,	@‚8€迁_ÿø ß¡9`%l€¥hÿÿôTƁ^UJŽ}JxU=p‘ÿü|§#xU)~‘_ÿø});x9_ÿð})3x})Cxa)@} U,|¬?ÿðé_4U)‘?ÿðé(ë	 ëX;:(|¬UFÀ>%ËxQFB8`@QFF>8€xÆ D"|¬8º|¬8`@8€<ÀD"Kÿ[m`8cˆx{ H ``B?ÿø_ÿôU)
|	PA‚Kÿ[=`|Ø@A€ÿà|¬Äóx†ãx¥ëxÃxKÿú¹|~x|¬?ÿðe)@‘?ÿð|¬|¬8`@%Ëx8€8ÀD"8º,|¬8`@8€8ÀD"9?ÿø} L,q)@‚ ÞÐ{Þàëpë!xëA€ëaˆëë¡˜ëá¨8!°ÃóxèëÁÿð|¦N€ `;À8bŠ`H³`8!°ÃóxèëÁÿð|¦N€ `B= ðy) Kÿý<`B``8‚H8bŠ°H²Ñ`끐KÿÿŒ`8bŠÈH²¹`9?ÿð``8‚H}L,9?ÿü8bŠØ|àL,9?ÿô|ÀL,9?ÿø| L,H²`?ÿøU)‘?ÿø|¬,ÿüÞÐ{Þà@‚ÿèKÿí•`Kÿþø``B`|ä;x8bŠ€;ÀH²1`끐8!°ÃóxèëÁÿð|¦N€ ```BW£À>;€S£BS£F>xg Kÿý€```B|¦úAÿúaÿ˜}€&úÿ ú¡ÿ¨úÁÿ°úáÿ¸ûÿÀû!ÿÈøûAÿÐûaÿØûÿàû¡ÿèûÁÿðûáÿø‘ø!ÿ9$|x8`0‹d|#x~€N,|¹+xKÿ[‰`8 8€0{{Ïâ|~xKÿ_`8 08€z— |zxÃóxH™U`£ëx8 8€{X Kÿ^Ý`{V 98||yA‚ø99\.7€E,9}@E,9^} U,9 ò‘>@’ì,;9>:`: @‚¨9@ó9‘IVÆÀ>RÆB‘	ù	RÆF>¡?_ÿøU'^UJŽ}J3xé?)l‘_ÿø9_ÿð‘ÿü‘ÿôU)~});xa)@} U,|¬?ÿðé_4U)‘?ÿðé(êÉ ëv:û |¬UFÀ>~å»xQFB8`@QFF>8€xÆ D"|¬8»|¬8`@8€<ÀD"KÿWa`8cˆxr H```B|	PA‚ÄKÿW9`?ÿø_ÿô|@U)
A€ÿà|	PA‚ ``ú€ú!ˆ8‚`8b‹ùáxH¯™```8b‹(:ÿÿH¯`:@:"‹8ˆ9ð~#‹x:H¯a`ˆ92ÿÿ~#‹xy2 H¯I`92ÿÿy2!@‚ÿÈ`8b©H¯-`éáxê€ê!ˆEÓx~f›x~óxÄóxKÿö	|zx|¬?ÿðe)@‘?ÿð|¬|¬8`@~å»x8€8ÀD"8»$|¬8`@8€8ÀD"8 ¤ëxƒãxKÿ]1`@’Ãx8 0ÄóxKÿ]`Ãóx8€0KÿY)`8!|zÐxcà聁êAÿêaÿ˜êÿ ê¡ÿ¨êÁÿ°êáÿ¸ëÿÀë!ÿÈëAÿÐëaÿØ|¦ëÿàë¡ÿèëÁÿðëáÿø} N€ ``B9@óKÿý\``B9^.7“ž“ž} U,9 ò‘>A’ý8 ~„£x#ËxKÿ[¥`{h]$,;9ó9> /£|ux8ø @ž@~~9^‘:`|àU,KÿüÜ~…£x$Ëx~£«xKÿ\`Kÿþè``B8Þ9Wÿÿ}J|`5,8Þ}@5,Kÿÿ´€``Bûáÿø|yA‚¼ûÁÿð8`<|ž#x8€é?é)é) è©8¥<D",#@‚˜T‰À>P‰BP‰F>U)>=B¦¡J§˜|
HA‚hé?8`<8€é)é) è©8¥<D",#@‚`TˆÀ>PˆBPˆF>U>9?ÿôé_88ÿÿøè¿ |ÀL,?L|€<,<⦱§˜|Ê0P9)ÿÿ|Ç&ty( 8çT„:}'CÒ}J P}ER|Å2})AÒ})8Py,'y) }b|(P@A‚È¡_èŸ(èÿ@}*IÖy) |é:|dJ}$L,,)A‚89@9>ÿÿ}I¦#Þ}cJ9I9)|ð®}cR˜	ÿÿ}kð®™jBÿà9@ð9 }Ea.9H|àU,‘(9H¡?9)ÿÿ}):} U,é? é_8}	@P}RU	À>Q	BQ	F>‘&|¬‘?ÿô8`ëÁÿðëáÿøN€ `BëÁÿðëáÿø8`N€ 9 ÿÿy) Kÿþt`B9ÿÿy Kÿþ¬``B|¦ûÁÿðûáÿøøø!ÿ1|~x`8b‹@H«1`8`ÀKÿVU`|yA‚(9 ûþ 8€8 Àù>(H“!`9 ûß8`hù?ù? é>ù?KÿTý`,#ø|dxA‚û¡¸p}ÿA‚\롸`8b‹€Hª­`è8€hKÿU=`ãûx8€ÀKÿW½`8!ÐèëÁÿðëáÿø|¦N€ ```B8 8€hû°úáˆûûA ûa¨KÿX`ëŸø¨8¼|¬8`@8€8ÀD"8`dKÿQé`8¼|¬<Àÿÿ8`@`Æÿÿ8€xÆ D";œ|¬8`@…ãx8€<ÀD"|¬;À```B8`<8€…ãxD"9>ÿÿ/£y>!T‰À>P‰BP‰F>8`y)à.©@žA–(A‚KÿR`Kÿÿ¸`B`8b‹¸H©i`é?99@ëß8À8 8p8(™s±Atù?8KÿÙU`,#ø@||xA‚˜è8 8€ë|0H‘-`8 8€8|ÿðH‘`=@WjÀ>SjB9 ‘ÿð9SjF>}	¦yJ ```Bèßy'd9)y(ˆ9)y) }F9.èÿ}GA.Bÿ܁?¬8¾|¬U&À>8`@Q&B8€Q&F>xÆ D"8¾ |¬8`@8€8ÀD"8¾(|¬8`@8€8ÀD";ž8`<…ãx8€D",#@‚xT†œdÆ·|¬8`@…ãx8€D"8`dKÿOÕ`8¾4|¬<Àß.8`@`Æx'8€xÆ D"8¾@|¬8`@8€<À/*D";žH8`<…ãx8€D",#@‚ìT„T„Vd„x† |¬8`@…ãx8€D"8¾L|¬8`@8€8ÀD"|¬8`dKÿO5`ë_8`<8€8ºHD",#;`ÿ@‚T‰À>P‰BP‰F>U;>8ºP|¬8`@8€8ÀD"8`d`KÿNÝ`,;`;ZT;Œ:âŒ;ÀA‚HúÁ€û!˜H8```B,<@‚Œ,=@‚Œ9;ÿÿ;Þy;!{Þ ;ZA‚°8`<8€EÓxD",#@‚DT‰À>P‰BP‰F>u*@‚8`<8€EÓxD",#@‚¨T‰À>P‰BP‰F>u*U9œU<Z@‚”,9A‚ÿtg½{½ |¬W¦À>EÓxS¦B8`@S¦F>8€xÆ D"9;ÿÿ;Þy;!{Þ ;Z@‚ÿXêÁ€êáˆëë!˜ëA ëa¨ë°ë¡¸8!ÐèëÁÿðëáÿø|¦N€ `B?€? Kÿԉ`é?Äóxg½{½ |vxù#Kÿá)`,#A‚|~óxHÕ`Kÿÿ4``Bq)@‚ÃxH¥e`Kÿþà``B|¬8`@EÓx8€<ÀD"|¬8`dg½{½ KÿLù`Kÿþ¤```BÄóx~ã»xH¥	`Kÿþ¸```B`8b‹XH¤é`8!ÐèëÁÿðëáÿø|¦N€ ``B<Àÿö`ÆÿÿxÆ Kÿý<À·xÆ KÿüŒêáˆëëA ëa¨ë°ë¡¸Kÿú`8b‹ÐH¤`Kÿý€
``B|¦øø!ÿ‘<b8cà8KÿÖ=`8!pè|¦N€ €``````N€ ,#M‚ é#,)M‚ |¦øø!ÿ‘é)é) éI0,*A‚@øj9@øi08  8€ùCùCH‹Ñ`8!pè|¦N€ ``B9@øi(øi08  8€ùCùCH‹•`8!pè|¦N€ €û¡ÿèûáÿøø!ÿa|}yA‚°|¦ûaxû€|›#xø°é=ë‰ ëü(,?A‚¨é?,)ù<(A‚ˆ8  8€ãûxH‹`9 û¿ù?‰;U)¾‘?=h‘?¡;±?‰;U)Éþ‘?‰;U)>±?è°ëax끀|¦8! ãûxë¡ÿèëáÿøN€ ```Bù<0Kÿÿx``B8`ûÁKÿL‰`,#ø|X|~xA‚¨8€8 KÿP	`9^À9}	¦8€ø|`9>€ø~`ù^HH ```Bø©Høê`9*€øÊH9I€ø‰H8©À}PP8É@|è}HP}ù	`BÿÌé<(;þ@,)A‚Dé<0ûéëü(;ÞÀûÜ0ëÁKÿþœè°ëax끀ëÁ|¦``B;àKÿþìûü(KÿÿÈ€`BûÁÿðø!ÿ|¦|~yøA‚œ=B¦*§œ9),	‘*§œATûáxëþ ,?A‚è¿8`<8€D",#@‚l9 ÿÿy$Ê,x† è¿|¬8`@8€D"è¿8¥|¬8`@8€8ÀD"èŸX,$A‚$è`8 KÿOI`èX8€KÿKY`èŸ ,$A‚$èH8 @KÿO`è 8€@KÿK-`èŸ,$A‚$è@8 @KÿNñ`è8€@KÿK`èŸ8,$A‚$èP8 KÿNÅ`è88€KÿJÕ`ãûx8€hKÿMU`9 ù> èëáx8!€ëÁÿð|¦N€ ```B``8‚¨8bpHŸá`è8!€ëÁÿð|¦N€ `Bûáxé> à`B<Àÿÿ`ÆÿÿxÆ Kÿþ˜€`BN€ |¦ûÁÿðûáÿøøø!ÿ|~x|¬8`<è¾8€D",#@‚àd†@xÆ è¾|¬8`@8€D"|¬KÿF`;ãˆ{ÿ H``B@‚DKÿFm`8€|ix8`<|H@@dè¾8¥D"/£T‰À>P‰BP‰F>q) AžÿÀè¾8¥|¬8`@8€<À D"8!€8`èëÁÿðëáÿø|¦N€ `B8!€8`èëÁÿðëáÿø|¦N€ `B<Àÿÿ`ÆÿÿxÆ Kÿÿ €`B|¦ûáÿøøø!ÿ!C,
@‚È= ûÁÐ|þ;xa)@|HAúaxú€:e |Ÿ#xúÁúá˜|Ô3x|wxû û!¨zs :ÄûA°ûa¸;$œ|»+xú¡ˆûÀ?@û¡Èé#ƒƒé)œ4WœÙ~ë© kœW˜@.{œEè:¶ÿä8  ~£«x8€H…¹`9T{È 8öÿðyIä}H¢9}	¦~€=,|*H@|8ç} =,9)Bÿì|)P@€d})PP8öÿì}(µ})ðPU*€}Jãx})´eJ€aJ€}@=,A‚P9Vÿä:Ö ~”J~`U,“VÿÈ|6È@:s zs A‚D}CxKÿÿT``BWɀ9U})Ãxe)€a)€} U,= y)ù5```B|¬97ÿÐ8·ÿÀ`M,7¡¡WU)`&U€UJ@.èý@è×`ç|à-,€æl});x})Cx})Sx9WÿÄ} U,|¬é7 é]a)} U,|¬?€;€KÿC±`8cˆx~ H ```B9?} L,q)€A‚KÿC`|@Aÿä|¬?|	àA‚ 9?} L,q)€@‚;ÿ |?Ø@@‚ÿ˜;àé=@é]a)} U,|¬£ëxKÿüI,#A‚€êaxꁀꡈêÁãûxêá˜ë ë!¨ëA°ëa¸ëÀë¡ÈëÁÐ8!àèëáÿø|¦N€ `B`;à8bH›e`8!àãûxèëáÿø|¦N€ `B``8‚¸8bŽH›1`;àKÿÿh`;à8b°H›`ëÁÐ8!àãûxèëáÿø|¦N€ `;à8bØHšå`Kÿþü€
```B|¦û¡ÿèûáÿøøø!ÿA|x`8bŽHš¡`8`hKÿEÅ`|}yA‚8 h8€û€û!ˆûAûa˜û ûÁ°H‚…`9 û¿ 8`<8€ù?(ûýëÿûýåûxD",#9 ÿ@‚T‰>ÿJûýKÿA}`è½8€;ãú8`<{ÿ D",#@‚hT„ÊT„d†xÆ è½|¬8`@8€D"H```BKÿA!`|@Aÿôè½8`<8€D",#@‚DT‰À>xœ P‰BP‰F>q)@‚,8`KÿC`|{yA‚œ8 8€KÿG%`|yx8`@KÿCu`|yA‚`8 8€@KÿFý`8 @8€|xxãûxHE`=@@<àxçc‘_9@TÈÀ>}I¦øÿ= PÈBPÈF>‘?‘?9;ÿüy ```B9I‘	9)‘
Bÿðè½8¥|¬W&À>8`@S&B8€S&F>xÆ D"8`@KÿB±`|~yA‚@8 8€@KÿF9`8 @8€|zxÃóxH€`cG=€=@@= |àõ,‘y)‘^ù>è½8¥|¬WFÀ>8`@SFB8€SFF>xÆ D"ûÝû]@ûý ûHû}8û=Pè½|¬g†!8`@xÆ 8€D"è½8¥@|¬8`@8€<ÀD"è½8`<8€8¥D",#@‚T‰À>P‰BP‰F>q)A‚¬úÁpúáx?ÿþ? ûÿ`cÿÿc9ÿÿ}>Kx;€D;à:à:{ {9 ;@þûH,```B@žL9>ÿÿ;ÿy>!{ÿ ;œA‚<è½8`<8€|¥âD"T‰À>,#P‰BP‰F>y)à/©A‚ÿ¸è½8`<8€|¥âD"T‰À>,#P‰B&ËxP‰F>IH8a)U*À>Q*BQ*F>@‚yF è½|¥â|¬8`@8€D"8`Kÿ>e`è½8`<8€|¥âD",#Ãx@‚T†xÆ è½|¥â|¬8`@8€D"8`Kÿ>`KÿÅ`é=äûx’ãh|{xù#Kÿѵ`äûx,#cÛxA‚`H]`9>ÿÿ;ÿy>!{ÿ ;œ@‚þÌêÁpêáxë€ë!ˆëAëa˜ë ëÁ°8!Àèë¡ÿèëáÿø|¦N€ `B~óxH•­`KÿþhúÁpúáx9 Kÿþ<ÀÏÿ`ÆÿÿxÆ Kÿû `8bŽ0H•y`8!Àèë¡ÿèëáÿø|¦N€ `8bŽXH•Q`KÿýŒ`8bŽØH•=`Ãxäûx8 @KÿC©`ãûx8€@Kÿ?¹`#ËxdÛx8 KÿC…`cÛx8€Kÿ?•`Kÿý0`8bŽ H”á`KÿÿÈ`8bŽpH”Í`Kÿý€
`B|¦ûáÿøøø!ÿ1#,	@‚ÈûA û°|x|œ#xû¡¸û|º+xé#8``é)ë	 Kÿ>‰`|}yA‚œ8 8€`û!˜ûa¨ú¡xúÁ€úáˆûÁÀKÿAù`8 `8€|yx£ëxH|A`8 8€ƒãxKÿAÍ`=99 yÆ9]e€8à} í,|é¦a9#|{xù|`U,y)ä9|(H@9J} U,9)Bÿì9<‹Ü9] :À~àN,WÞÉþzõ!@‚D!>=yU)@.e)€9Ja)€ù
ÿø} U,|¬9?ÿÐ8¿ÿÀ M,?¡¡_U)`&U€UJ@.èø@èß`ç|à-,€æl});x})Cx})Sx9_ÿÄ} U,|¬é? éXa)} U,|¬Kÿ:e`¿ëx> ;È{Þ H,``B|¬Kÿ:=`|@A€4?|	¨A‚$9?} L,q)€@‚ÿÔKÿ:`;ÿ |@@€ÿÔ`;à8bpH’‘`é8@éXa)} U,|¬ÃxKÿòñ,#A‚ð„ãxcÛx8 Kÿ@Ù`~å»xDÓx~óxKÿ@Å`{# 8 `¤ëxKÿ@±`£ëx8€`Kÿ<Á`ê¡xêÁ€êáˆëãûxë!˜ëA ëa¨ë°ë¡¸ëÁÀ8!Ðèëáÿø|¦N€ ``B`;à8b8H‘Å`8!Ðãûxèëáÿø|¦N€ `Bé8@éX;àa)} U,|¬ÃxKÿò,#@‚ÿ``8‚Ð8bŽH‘i`;àKÿþø``B8 ~ä»xCÓxVµ€Kÿ?`WÊ@.99@8Ý ~µSxfª€<à} 5,aJ€8Ý(9,ý$9#}@5,9@|vx}I¦|`E,|ãºy)ä|'H@9} E,9)Bÿì9]@Kÿý@```B`;à8bXHµ`ëëA ë°ë¡¸8!Ðãûxèëáÿø|¦N€ €``B|¦øø!ÿ‘<b8cà˜KÿÂM`8!pè|¦N€ €``ø!ÿa= a)€Ãt€ãléCdøapÁxá||
Hé(‘!€é(‘!„A‚4mI,	A‚ÈUI†>,	A‚ì= 	|
HA‚€8! N€ `B|¦ûá˜`9 8 8p8`;âàø°‘!ˆKþãI`ãûxHt-`åûx|dx8`Kþã)`è°ëá˜8! |¦N€ ```B|¦ûá˜`9 8 8p8`;â@ø°Kÿÿ``B|¦ûá˜`9 8 8p8`;âø°Kÿÿ```B|¦ûá˜`9 8 8p8`;␠ø°Kÿÿ0€```Bûáÿøø!ÿ|x€ƒdT‰†>(	A‚X(		A‚@(	A‚8|¦`8bøHŽu`è8!€ëáÿø|¦N€ ``B8!€ãûxëáÿøKÿþ|¦p‰P,	PøA‚0`8bXHŽ%`è8!€ëáÿø|¦N€ ``BKÿÈA`,#@‚$``8‚¸8bxHá`Kÿÿl`B8`dKÿ5`è8!€ãûxëáÿø|¦Kÿý€€````<¢¦=¦‰§¡=B¦9J§ ‰%§ 8é}&´|@M‚ }J2˜å§ ˜jN€ ```Bùáÿxúÿ€ú!ÿˆúAÿúaÿ˜úÿ ú¡ÿ¨úÁÿ°úáÿ¸ûÿÀû!ÿÈûAÿÐûaÿØûÿàû¡ÿèûÁÿðûáÿøø!þñ||x="¦é)¨¨,)A‚¸="¦é)¨°,)A‚¨‰<q)"A‚=B¦‰*¨¸U)ú™*¨¸;Ü=B¦?b¦;¼ßóx9J§ ;{¨Å;@; [9àA:B: D:@C:`6;~:àO:€F: 3:À5H``B|=ø@A‚\9(ÿÿU)>(	cAÿè9*|éØPpçA‚(ˆê 9* |@A‚ÿÈ|;H@A‚8```Bˆé9)|@A‚ÿ¤ˆé9)|@A‚ÿ”|;H@@‚ÿÜ9(ÿÎU'>(!AL<âÿþ8ç¾Ty)¨}'Jª}):})¦N€ Œ,,,,,,Œ
ô	Ä
\ðˆD	œÐP,Ì,Üxœ0Ä
8
Ì@´\Œ`B`9B”è=¦`9"”€ùH¨¨=B¦ù*¨°Kÿþ<```B9J9 ``B9)ÿÿq)ÿ
@‚ÿð8!éáÿxêÿ€ê!ÿˆêAÿêaÿ˜êÿ ê¡ÿ¨êÁÿ°êáÿ¸ëÿÀë!ÿÈëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿøN€ ‰*q)A‚
ô9(ÿüU)>(	AHé*|é@®,'A‚þ‰*ˆÊ8©}(´|0A‚ýð}
B˜ª˜èKÿýà```B‰*i)™*Kÿýĉ*ˆª9	}&´|(A‚ý¬U>|Ê2™
8ç|(›FU>A‚ýŒTè>|Ê298‰|(›&Tæ>˜ŠA‚ýhU>|Ê28ç8`1|(8‰˜fU>˜ŠA‚ý@Tæ>}
B8Æ8€9|(8ɘˆTè>˜ÊA‚ý9)}
B™*›Kÿý‰*ˆÊ8é}%´|0A‚üìTè>|ä;x9|ª*|0˜ŠTç>›EA‚üÈU>|ê:8¥U>|08É›'˜ÊA‚ü¤9)}
B™*™èKÿü‰*ˆª9	}&´|(A‚üxU>|Ê2™
8ç|(›FU>A‚üXTè>|Ê298‰|(›&Tæ>˜ŠA‚ü4U>|Ê28ç8`2|(8‰˜fU>˜ŠA‚üTæ>}
B8Æ8€0|(8ɘˆTè>˜ÊA‚ûä9)}
B™*›KÿûЉ*ˆª9	}&´|(A‚û¸U>|Ê2™
8ç|(›FU>A‚û˜Tè>|Ê298‰|(›&Tæ>˜ŠA‚ûtU>|Ê28ç8`2|(8‰˜fU>˜ŠA‚ûLTæ>}
B8Æ8€1|(8ɘˆTè>˜ÊA‚û$9)}
B™*›Kÿû‰*ˆª8é}&´|(A‚úøTè>|Ê2˜ê9|(›FTæ>A‚úØU>|Ê28ç8‰|(›&U>˜ŠA‚ú´Tè>|Ê298`2|(8‰˜fTç>˜ŠA‚úŒU>|ê:8ÆU>|(8Éš§˜ÊA‚úh9)}
B™*›KÿúT‰*ˆª9	}&´|(A‚ú<U>|Ê2™
8ç|(›FU>A‚úTè>|Ê298‰|(›&Tæ>˜ŠA‚ùøU>|Ê28ç8`2|(8‰˜fU>˜ŠA‚ùÐTæ>}
B8Æ8€4|(8ɘˆTè>˜ÊA‚ù¨9)}
B™*›Kÿù”‰*i)™*Kÿù„‰*ˆª8é}&´|(A‚ùlTè>|ä;x9|Ê2|(˜ŠTç>›FA‚ùHU>|ê:8Æ8‰|(›'U>˜ŠA‚ù$TÇ>}
B8ç8€2|(8阈TÈ>˜êA‚øü9)}
B™*›Kÿøè‰*ˆÊ8é}%´|0A‚øÐTè>|ä;x9|ª*|0˜ŠTç>›EA‚ø¬U>|ê:8¥U>|08Éšç˜ÊA‚øˆ9)}
B8àH™*˜èKÿøp‰*ˆª9	}&´|(A‚øXU>|Ê2™
8ç|(›FU>A‚ø8Tè>|Ê298‰|(›&Tç>˜ŠA‚øU>|ê:8ÆU>|(8Éšç˜ÊA‚÷ð9)}
B8àS™*˜èKÿ÷؉*ˆª8é}&´|(A‚÷ÀTè>|Ê2˜ê9|(›FTæ>A‚÷ U>|Ê28ç8‰|(›&U>˜ŠA‚÷|Tè>|Ê298`1|(8‰˜fTç>˜ŠA‚÷TU>|ê:8ÆU>|(8ɚǘÊA‚÷09)}
B™*›Kÿ÷‰*ˆª9	}&´|(A‚÷U>|Ê2™
8ç|(›FU>A‚öäTè>|Ê298‰|(›&Tæ>˜ŠA‚öÀU>|Ê28ç8`1|(8‰˜fU>˜ŠA‚ö˜Tæ>}
B8Æ8€7|(8ɘˆTè>˜ÊA‚öp9)}
B™*›Kÿö\‰*ˆª9	}&´|(A‚öDU>|Ê2™
8ç|(›FU>A‚ö$Tè>|Ê298‰|(›&Tæ>˜ŠA‚öU>|Ê28ç8`1|(8‰˜fU>˜ŠA‚õØTæ>}
B8Æ8€8|(8ɘˆTè>˜ÊA‚õ°9)}
B™*›Kÿõœ‰*ˆª9	}&´|(A‚õ„U>|Ê2™
8ç|(›FU>A‚õdTè>|Ê298‰|(›&Tç>˜ŠA‚õ@U>|ê:8ÆU>|(8Éšç˜ÊA‚õ9)}
B8àQ™*˜èKÿõ‰*ˆª9	}&´|(A‚ôìU>|Ê2™
8ç|(›FU>A‚ôÌTè>|Ê298‰|(›&Tç>˜ŠA‚ô¨U>|ê:8ÆU>|(8Éšç˜ÊA‚ô„9)}
B8àR™*˜èKÿôl‰*ˆª9	}&´|(A‚ôTU>|Ê2™
8ç|(›FU>A‚ô4Tè>|Ê298‰|(›&Tç>˜ŠA‚ôU>|ê:8ÆU>|(8Éšç˜ÊA‚óì9)}
B8àP™*˜èKÿóԉ*i)™*Kÿóĉ*ˆª9	}&´|(A‚ó¬U>|Ê2™
8ç|(›FU>A‚óŒTè>|Ê298‰|(›&Tç>˜ŠA‚óhU>|ê:8ÆU>|(8ɚǘÊA‚óD9)}
B™*›Kÿó0‰*ˆª9	}&´|(A‚óU>|Ê2™
8ç|(›FU>A‚òøTè>|Ê298‰|(›&Tç>˜ŠA‚òÔU>|ê:8ÆU>|(8Éš§˜ÊA‚ò°9)}
B™*›Kÿòœ‰*ˆÊ8é}%´|0A‚ò„Tè>|ä;x9|ª*|0˜ŠTç>›EA‚ò`U>|ê:8¥U>|08Éšç˜ÊA‚ò<9)}
B™*šˆKÿò(‰*ˆª9	}&´|(A‚òU>|Ê2™
8ç|(›FU>A‚ñðTè>|Ê298‰|(›&Tç>˜ŠA‚ñÌU>|ê:8ÆU>|(8Éšg˜ÊA‚ñ¨9)}
B™*›Kÿñ”‰*ˆÊ8é}%´|0A‚ñ|Tè>|ä;x9|ª*|0˜ŠTç>›EA‚ñXU>|ê:8¥U>|08É›'˜ÊA‚ñ49)}
B™*šHKÿñ ‰*ˆÊ8é}%´|0A‚ñTè>|ä;x9|ª*|0˜ŠTç>›EA‚ðäU>|ê:8¥U>|08É›'˜ÊA‚ðÀ9)}
B™*š(Kÿð¬‰*ˆÊ8é}%´|0A‚ð”Tè>|ä;x9|ª*|0˜ŠTç>›EA‚ðpU>|ê:8¥U>|08É›'˜ÊA‚ðL9)}
B™*šKÿð8‰<,)A‚\q'"@‚òq'@‚„(	@@‚ð`9"”|i@®,#A‚ð|¦ùApø KÿîÁè éAp|¦Kÿïà```Bé*|é@®,'A‚ïĉ*ˆÊ8©}(´|0A‚ï¬}
B˜ª˜èKÿïœ`9"“°|i@®,#A‚ïˆ|¦ùApø KÿîIè éAp|¦Kÿïh€``B|¦û¡ÿèûÁÿðûáÿøøø!ÿa|~yA‚„û€9>x=@!;áp;€8 äûx‘Ap³v;¡x} N,è~ ±!tKÿ¯`9^xè~ = !
³va)}äûx}@V,8 ‘!p±AtKÿ®í`8 8€£ëxHc9`9^xè~ = ¡9a)}@V,äûx¥ëx±v‘!p±AtKÿ®¥`,#A‚ˆ£ëxKÿí‘끀8`€Kÿ$å`="¦,#øi¨ÈA‚À^`;þ8; ,
A‚(‰?U)¾,	A‚L9=;ÿ|
H@y= Aÿà8`8! èë¡ÿèëÁÿðëáÿø|¦N€ `B끀Kÿÿ„``B<¢¦è¥¨È8À€äûxÃóxKÿ°Ý`^`Kÿÿ˜```B8 8€8axHb%`Kÿÿ4``B``8‚‘8bØHyá`8`Kÿÿd€`B|¦ûáÿøøø!ÿ|xèc,#A‚Kÿªq`9 ù?<b¦èc¨È8€€Kÿ$%`8!€8`èëáÿø|¦N€ €``Bûáÿøø!ÿq|yA‚”|¦ûÁ€;Áp8 8€Ãóxø HaE`èÄóxKÿªe`,#@‚Hè <b¦ˆc§¡="¦‰)§ ëÁ€8!ëáÿø|¦|cJx|c4TcÙ~hcN€ ```BÃóxKÿë}Kÿÿ´`B8!8`ëáÿøN€ €`Bûáÿøø!ÿq|yA‚ |¦ûÁ€;Áp8 8€Ãóxø H`…`èÄóxKÿ©¥`,#@‚x<â¦=¦‰§ =B¦9J§ ‰'§¡|HA‚8è 9	ëÁ€}*J8!ˆi™§¡|¦ëáÿøN€ ```Bè ëÁ€|¦8!8`ëáÿøN€ `BÃóxKÿê<â¦=¦‰§ =B¦9J§ ‰'§¡|H@‚ÿˆKÿÿ¸€``|¦ûÁÿðøø!ÿ|~yA‚œûáè;áx8 û¡Ø8€ãûxH_`=  è~ ;¡pa))åûxy)Ƥëxa)ù!pKÿªõ`‰!z,	A‚lúÁ úá¨`>à#û°?#ú¡˜b÷û!¸ûAÀc;àûaÈûÐ; ;A€ú?`£;€: :‘(H<``Bq)@‚ü‰Az99}9´|
H@Ì9)U?Æ>U*D.ÿSxWÿ>è~ EÓx¤ëx“ap³át³vKÿª9`,#A‚ÿ´9!€} N,q*@‚ÿœè~ 8 ¤ëx±Av“p³átKÿª`8`dKÿ`Kÿ`8cˆxt H<``Bè~ EÓx¤ëx“ap³át³vKÿ©¹`9!€} N,q)@‚$KÿA`|@AÿÄ9!€} N,q)A‚ÿè~ 8 ¤ëx²¡v’áp³átKÿ©i`8`dKÿm`Kÿõ`8cˆxt `BKÿá`|@@þ¼è~ EÓx¤ëx“ap³át³vKÿ©`9!€} N,q)@‚ÿÄé>{4 é),)A‚ Kÿ£ý`~„£xûÃ|xé>ù#Kÿ°¡`,#@‚ä$Ëx~óxHtù`‰Az99}9´|
HAþ<ꁐꡘêÁ êá¨ë°ë!¸ëAÀëaÈëÐë¡Øëáè8!ð8`èëÁÿð|¦N€ ``Bè~ EÓx¤ëx“ap³át³vKÿ¨9`9!€<À } N,q*@‚q)<À@A‚Dé>~…£xÄóxèi H)Ñ`,#@‚ý|Kÿÿ0```BãûxKÿåm`Kÿý\é><À~…£xÄóxèi H)`,#@‚ý8Kÿþì``B`8b‘HsÙ`8!ð8`èëÁÿð|¦N€ €```````|¦ûÿàû¡ÿèûÁÿðûáÿøøø!ÿq|~x|œ#x|¬ë£4h9=àL,Kÿ½`(||xA‚8;ƒˆ{œ H,```B|¬9=àL,Kÿ…`|à@AX>4|Wÿþ|H@‚ÿØ|¬9=} L,y(¶¢U*²¾(!}CxA‚XqI=,	 A‚`8b‘XHrÑ`9=9@ù>4h‘]9>4|àì(ù]} L,‘=èÞ4hé^4Pé4p}*0P}&fp|Æ”q'ÿTÆ`&|ÆHP|Æ´|ÆB@‚>4|ù^4h})4U)Ù~‘>4|è¾8¥8|¬xÊ"|É3xTÆÀ>UHÀ>Q&BQHBQ&F>QHF>xÆÆ8`@|ÆCx8€D",?@‚,8!£ëxèëÿàë¡ÿèëÁÿðëáÿø|¦N€ `B8!ýûx£ëxèëÿàë¡ÿèëÁÿðëáÿø|¦N€ ``B8!; £ëxèëÿàë¡ÿèëÁÿðëáÿø|¦N€ ``B9]}@T,UJF>,
A‚9 ‘>4äKÿþ¬U)F>‘>4äKÿþ €``Bûáÿøø!ÿ|yA‚xé?,)A‚l|¦ûÁpø_é)(
ëÉ A‚|(
A‚Pé>48,)A‚|ûé9 ûþ48ãûx8  8€ù?ù?HY`èëÁp|¦8!€ëáÿøN€ èŸ(è0€¿8Kÿ5`€Ÿ8è(KÿE`9 ù? é>48,)@‚ÿŒûþ40Kÿÿˆ€`B|¦ûÁÿðûáÿøøø!ÿ9|~xëã4˜éC9?8ÿ} L,|€ý,| =,‘9})HøU)þ})3x} E,|¬8`@}ESx8€8ÀD";ÿ8€ÃóxKÿümûþ4˜8!€èëÁÿðëáÿø|¦N€ €|¦ûÁÿðûáÿøøø!ÿ|x8`|ž#xKÿÑ`,#øA‚ =@9“ß0øyJƒäø8 aJù8€ù_(HW‘`(A‚,?(é_9 <à|ÀD(y)&ä9)ÿð}
J|ÊI*øèè8 8€Kÿí`8!€|ix8`ù? èëÁÿðëáÿø|¦N€ 8!€8`èëÁÿðëáÿø|¦N€ €``B}€&ûáÿø‘ø!ÿ1é#,)A‚HéI;à,*A‚Œ|¦ûa¨û¡¸|½+xûÁÀú¡x|ž#x8 úÁ€úáˆ8€Ãóxûû!˜ûA û°øàë‰XëJ ƒë:ëüPKÿ
`9>é9@} N,|{x,)A‚‰>U)KÞ=I9?} L,ù=‘})HøU)þ})Sx9_a)@} U,|¬9>~àN,zõ .5@’Ü;ÿ:À9 9?9@} L,ù_‘_9_})HøU)þ})Cx} U,|¬{d;ÿ|¹*|¬8`@8€<ÀD"8€CÓxKÿùéûüPÄóx8 |ixcÛx3éÿÿÿIKÿÙ`@’Àèàê¡xêÁ€êáˆëë!˜ëA ëa¨ë°ë¡¸ëÁÀ|¦8!Ðãûxëáÿø} N€ `B8 ~ä»x£ëxKÿµ`9?9_9} L,~ U,xj"|vx|`E,9})Hø}@E,9_U)þe)a)} U,|¬=;ÿ a KÿþÐ``B~å»x¤ëx~óxKÿ`Kÿÿ0``B8!Ð;àãûxëáÿø} N€ €``BéC,*A‚(èª,%A‚é# ,)A‚|¦øø!ÿa9að|@AtûApûaxû€û¡ˆûÁûá˜ë‰ëé	(èŠXë¥ }_àP9hÿÿ€„yJáè½9J|
XA‚X9\ùI9\é	 xÉ"}@T,|Àå,8Ü|à5,8ü} =,}IPø}\BU)þÿPPa) 9\} U,|¬¡#xŠd|¥RU)<})Cx|¬U&À>8`@Q&B8€Q&F>xÆ D"Kÿ‘`?B¦;`;Z¨Ð8cˆx~ HAžð“zKÿi`|ð@A<8€£ëxKÿ÷a|#ø@/£@‚ÿÔ8`9 ù<ù<|¬H``B8`ëApëax끀롈ëÁëá˜8! è|¦N€ `B`8b‘hHj‰`8! 8`è|¦N€ ```B9I y&ä9ÿð=`|T(9@ûé‘I,}_B|A*ùj|¬ëéKÿþ€``B8`Kÿÿ@``B8`N€ €```BûÁÿðûáÿøø!ÿa|~yA‚|¦û¡ˆûax|#xû€ø°é>ëi ëû40,?A‚ôé?,)ù;40A‚”8  8€ãûxHQµ`9@ûßù_‰=y< (“Ÿ>h‘?¡=±?‰=U)Éþ‘?‰=U)>±?A‚H(A‚@è°ëax끀롈|¦8! ãûxëÁÿðëáÿøN€ `Bù;48Kÿÿl``Bdm	,	A‚<``åûx8‚“ 8b‘ÈHhÝ`ƒŸKÿÿŒ```B8`KÿÝ`,#ø{4ð||xA‚¼8 8€Kÿ]`9@‰ãx}I¦9ø{4øù	9)@B@D()@A‚ù)ÿÈ,)ù	9I@A‚ùJÿÈ,)ÿÀù
9)€A‚ÿÈù)ÿÈù	9)@BÿÄé;40Ÿãx,)A‚œé;48û‰ëû40;œÀû›48Kÿþ````Bë¾X,=A‚þ¼_é>;Ýè,
ëi @‚è~,#A‚P=@9ø~ø~yJƒä9 aJù8 ‘>08€ù^(HOÁ`>(é^9 <à|ÀD(y)&ä9)ÿð}
J|ÊI*øè8àðW‰8¡_e)ð°ÿa)U'À>UJ<Q'B}JCxQ'F>‰=,	@‚d€½ 9*èÝ9}
P0<€aJcÛx}))Ö8 y) }&J9)éÿü,èþ ‰};x}M(9&}@M,¦€ÝxÆÀ(`Æ0è x…"T„6KÿöUûß Kÿý€9 ë¾X±?;xè}x,#A‚D=9 ù]€ø}ˆyƒäø}8 a‘=¨8€ù HN‘`= é]x9˜<à|ÀD(y)&ä9)ÿð}
J|ÊI*øè xcB(8KÿU`€Ÿ88 ø(Kÿá`ø0‰=,	@‚Ø¡_?€ èÝ9<  ÿcÛx;`UJ<}JKxTç€9*`ç>})!Ö}
P0aJy) }&J9	9)|àE,¤èý˜©};x}M(9&}@M,“f€ÝxÆÀ(`Æ0è x…"T„6Kÿõ	ûŸ éˆèýx] }'@P8Šÿÿy&á8¨8Æ| A‚ˆø½ˆ ÿ9H})&tèß08¨}@T,})9Ö|à-,8è}JPøUJþy) aJ })2}@=,y*"} E,9(}@M,|¬ƒŸKÿû¬è°ëax끀롈|¦;àKÿû¬;Ý°;€KÿüìyI&ä9]˜9)ÿð<À| T(}GJøýˆ“}¤|§I*øÊ|¬é=x})@PKÿÿLû›40Kÿüp8€ÃóxKÿô­,#@‚ý`8b‘ðHdi`Kÿû$8€ƒãxKÿô…,#@‚þ`8b‘HdA`KÿûH¡?€Ÿ€½ é]<À8à¡U)<})#xU€}))Öa>y) }*J9I9)}U,]¤é˜É}JCx}@M(çà é=< 8À}HQÖyJ })R9)éÿü^,é ©}JCx}@M(Æà€``Bûáÿøø!ÿq|yA‚Øé_,*A‚Ìé
,(A‚ÀûÁ€<¦€Æ¨Ð,¡?€ÿëß U)<});xA‚´|¦û¡xûp|#xø éJXëˆ Jè¼yJd|¥R|¬U&À>8`@Q&B8€Q&F>xÆ D"8€ƒãxKÿïM,#A‚$|¬èþé>(|ˆ8P9)ÿÿxŠá9J|
HA‚9ù|‰&t£ëx8  Ÿë¿(|„IÖx„ ½"¤ëxHJý`£ëx8 8€HJ‰`èÞé^(è ëpë¡x|¦}&PP8¨ÿÿy'áx¥ 8ç|(@A‚9
ù ÿ9
})&tèß08ª}D,})9Ö|à-,8ê}@øUþy) a })2}=,y("} U,9*}M,|¬ëÁ€8!8`ëáÿøN€ ```Bè ëpë¡xëÁ€|¦8!8`ëáÿøN€ ```BèÞèž9 =B¦(‘*¨Ð}& P9Hÿÿy)áyE 9)|Ç3x|	P@A‚8äé^øþ}&PPy'á8ç|(@@‚ÿ9> y&ä9ÿð8€| L(<à}&Bøސž,|¦A*øé|¬é>})PPKÿþЀû¡ÿèûÁÿðûáÿøø!ÿq;Ã|x|#x8`<Åóx8€D",#@‚T‰À>P‰BP‰F>q)@‚Ø|¦8`<8€åûxø D",#@‚ìT‰À>P‰BP‰F>y) ,=U*<A‚a)y* |¬UFÀ>åûxQFB8`@QFF>8€xÆ D"|¬;à@``B8`<8€ÅóxD"9?ÿÿ/£y? T‰À>P‰B.¿P‰F>8`dq)@žA‚A–Kÿq`Kÿÿ¸`Bè 8`|¦8!ë¡ÿèëÁÿðëáÿøN€ 8!8`ë¡ÿèëÁÿðëáÿøN€ ``B= ÿÿa)ÿÿy) Kÿÿ€`B|¦ûAÿÐûaÿØûÿàû¡ÿèûÁÿðûáÿøøø!ÿa|{yA‚˜ë› ,<@‚Dƒãx8€5Kÿa`9 8! ù; èëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ ë\8€;ü;À+CÓxKÿþé?ÿÀ,)A‚XèŸp;¿p,$A‚$è8 Kÿ
=`èp8€Kÿ	M`£ëx8€8 8;¿¨HFµ`蟨,$A‚$èÈ8 Kÿù`è¨8€Kÿ		`£ëx8€8 8;¿8HFq`èŸ8,$A‚$èX8 Kÿµ`è88€KÿÅ`8€£ëx8 8HF1`èŸ,$A‚$è 8 Kÿu`è8€Kÿ…`8 88€ãûxHEñ`èŸÿØèÿà8 Kÿ=`èÿØ8€KÿM`èŸÿðèÿø8 Kÿ`èÿð8€Kÿ)`9>ÿÿ;ÿ(y>!@‚þ”ëü8¿(|¬8`@8€8ÀD"8¿0|¬8`@8€8ÀD"|¬èœ4À,$A‚$è|4È8 Kÿ¥`è|4À8€Kÿµ`èœ4P;ü4P,$A‚$è|4p8 Kÿu`è|4P8€Kÿ…`ãûx8 88€;úHDí`8`<åûx8€D",#@‚ôx†DxÆð‚|¬8`@åûx8€D"èœ4ˆ;ü4ˆ,$A‚$è|4¨8 Kÿ
ù`è|4ˆ8€Kÿ	`ãûx8 88€HDu`8º0|¬8`@8€8ÀD"èœ4@,$A‚$è|4H8 Kÿ
¡`è|4@8€Kÿ±`8`2KÿÕ`ƒãx8€5Kÿ	%`9 8! ù; èëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ <À?xÆÆKÿÿé; à€```B|¦ûÁÿðøø!ÿA(,|¾+xAÈúáxû€|÷;x|Ø3xûAûa˜;@@|›#xûá¸û |xû¡¨#4è,	A‚Lž(8`¿â“Ý0“]HKÿE`,#ø}@A‚P9 9@úÁpû!ˆ8 8€™=8‘]<HC`è}@8 8€Kÿ`‰=8ø}H,	@‚€ë=@= HÓxù9‰=8,	A‚9}?â,;;¸èé@{¸ {ª |çBA‚8iÛx````B	té),)}CxQF 6xÊ @‚ÿèUJá>U‚}J»x9'eJ8|h}M,~ß8€}@=,~óxKÿêY,#A‚Ì}_âHÓx‰*8,	@‚{H¤~ÿâ=@&aJ@<àé7@8`})B9)‘IÿüW”鈐é}JCx}@M(Kÿí`,#øwXA‚$9@9 8 8€‘WT™7PHAÁ`èwX8 8€KÿM`{É$øw`é_4@|jM(‰7P,	A‚;@~ÿâWÞÀcÆ,ãûxè—Hé7XxÆ x…"T„6IÒKÿèÍ|¬= cÞ0{Æ ãûxù9è—Hx…"T„6Kÿè¥|¬Kÿ‡Ý`é 9@9<(}?JÃx‘Ch|~xù‰Z“£tûcù#X‘Cløw(Kÿ”]`,#@‚@è—Xèw`8 Kÿ1`èwX8€KÿA`ßâèžh,$A‚$è~ˆ8 Kÿ`è~h8€Kÿ`~óx8 88€H@}`ÿâ8 èŸ@èHKÿÅ`è@8€KÿÕ`êÁpêáxë€ë!ˆ8`ëAëa˜ë ë¡¨ëá¸8!ÀèëÁÿð|¦N€ ž(;@ 8`¿â“Ý0“]HKÿù`,#ø}@@‚ü¸êáxë€8`Kÿÿ `B`|¤+x8b’ 8 ,HW¡`8!À8`èëÁÿð|¦N€ ÃóxKÿÈÍ`êÁpêáxë€ë!ˆ8`KÿÿH```BÃxKÿüø9 ‘)à€
}€&û!ÿÈûAÿÐûaÿØûÿàûáÿø‘ø!ÿQ|{x|š#x8`<8€ëûë;8¿D",#;€ÿ@‚T‰À>P‰BP‰F>y<F"8`<8€8¿D",#@‚T‰À>P‰BP‰F>y)„#A‚$û¡˜ûÁ ;À```By)d8`<ÿJ8€åûxD",#@‚T‰À>P‰BP‰F>U)>,	A‚Ü8`<8€åûxD"|}y@‚´T‰À>P‰BP‰F>y)Æ#@‚ÿ ,>A‚˜}>â9^ÿÿ9)ÿÿ|
H@@€L|¦;þ?*?@ÿÿ{ÿ&ä?ÀcZÿÿùúcÞ{Z øÀH4T‰À>P‰BP‰F>@’q),	A‚09<ÿÿ;½y<!;ÿA‚ä8`<8€åûxD",#A‚ÿ¼8`<8€åûxD",#FÓx@‚d†xÆ |¬8`@åûx8€D"8`Kþý-`cÛx8€Kÿá½åûx8`<8€D",#? ð@‚T™À>P™BP™F>W9R8 8À$8€cÛxKÿ䝀»4ä,%A‚ÿ<{¦ 'Ëx8€cÛxKÿù]9<ÿÿ;½y<!;ÿ@‚ÿ(`BèÀ|¦ë¡˜ëÁ 8!°8`ë!ÿÈëAÿÐëaÿØëÿàëáÿø} N€ ``B9 ÿKÿýü``B8`<8€åûxD",#@‚þT‰À>P‰BP‰F>U)F>|	Ð@‚ýü8`<8€åûxD",#@‚ýäT‰À>P‰BP‰F>u)ÿ@‚ýÐ;ß8`<Åóx8€D",#;€ÿ@‚T‰À>P‰BP‰F>y<Æ"Åóx8`<8€D",#;Àÿ@‚ý„TžÀ>PžBPžF>WÞ>Kÿýp`BÉH8|	ð@‚ýôKÿþ9 ÿÿû¡˜ûÁ y) Kÿý```B롘ëÁ 8!°8`ë!ÿÈëAÿÐëaÿØëÿàëáÿø} N€ €`B|¦ûÁÿðûáÿøøø!ÿQ|x`8b’PHS1`é?8`5y)$ù?KþþI`|~yA‚,8 58€û¡˜ûaˆûH;`9 ûß 8`<8€ù?(ûþ ë¿û¾¥ëxD",#9 ÿ@‚T‰>½Jè¾8`<8€û¾8¥ë¿D",#@‚T‰À>P‰BP‰F>y) ½Jè¾8`<8€û¾8¥ëÿD",#@‚ÈT‰À>P‰BP‰F>y) ëžÿJë~8`<8€ûþ;¼¥ëxD",#@‚,T‰À>P‰BP‰F>q)@‚8€ƒãxKÿñ,#A‚$8`<8€¥ëxD",#@‚T‰À>P‰BP‰F>q)@‚ø8`<8€…ãxD",#@‚Àd†xÆ |¬8`@…ãx8€D";à@```B8`<8€¥ëxD"9?ÿÿ/£y? T‰À>P‰B.¿P‰F>8`dq)@žA‚ØA–ÔKþùÑ`Kÿÿ¸|¬8`@%Ëx8€8ÀD"|¬8`@eÛx8€8ÀD"|¬èž4Àè~4È8 Kþÿu`è~4À8€Kþû…`ë!xèž4P,$A‚$è~4p8 KþÿE`è~4P8€KþûU`8 88€8~4PH8Á`8`<8€EÓxD",#@‚ðx†DxÆð‚|¬8`@EÓx8€D"|¬èž4ˆ,$A‚$è~4¨8 KþþÍ`è~4ˆ8€KþúÝ`£ëx8 88€H8I`ëA€|¬8`@åûx8€8ÀD"|¬èž4@è~4H8 Kþþu`è~4@8€Kþú…````B`8b’ÀHOÉ`ëaˆëë¡˜8!°èëÁÿðëáÿø|¦N€ ```B= ÿÿa)ÿÿy) Kÿý@= ÿÿa)ÿÿy) Kÿüø8¼8|¬8`@8€<À,D"è¾8`<8€8¥D",#@‚T‰À>P‰BP‰F>q*y)÷â‘>4è@‚|8`Kþù=`,#ø~4@A‚ÿ<8 8€H7!`è~4@8 8€;ü0Kþü©`ø~4H|fx|¬xÊ"|É3xTÆÀ>UHÀ>Q&BQHBQ&F>QHF>xÆÆ8`@|ÆCxåûx8€D";¾4ˆ8€£ëxKÿÞÁ,#A‚þlûA€;\8`<EÓx8€D",#9 ?@‚,xŠ"T‰À>P‰BUHÀ>P‰F>QHBQHF>y)Æ})Cxy) èÞ4¨xÆd|ÆKx|¬xÊ"|É3xTÆÀ>UHÀ>Q&BQHBQ&F>QHF>xÆÆ8`@|ÆCxEÓx8€D"8`Kþø
`,#ø~4PA‚ýD=@9ø~4`ø~4hyJƒä9 aJù4X8 ‘>4€8€ù^4xH5É`è~4P8 8€KþûU`|ix8`ù>4pKþ÷¡`,#ø~4ÀA‚ü˜8 8€û!xKþû!`9 è¾4ÀèÞ4pø~4ȑ>4Ð|¬xÊ"|É3xTÆÀ>UHÀ>Q&BQHBQ&F>QHF>xÆÆ8`@|ÆCx8€D"è¾4À>4x8¥|¬U&À>8`@Q&B8€Q&F>xÆ D"è¾4À8¥|¬8`@8€8ÀD";;88`<%Ëx8€D",#9 @‚,xŠ"T‰À>P‰BUHÀ>P‰F>QHBQHF>y)Æ})Cxy) èÞ4pxÆä|ÆKx|¬xÊ"|É3xTÆÀ>UHÀ>Q&BQHBQ&F>QHF>xÆÆ8`@%Ëx|ÆCx8€D";;(8`<%Ëx8€D",#@‚”T‰À>P‰BP‰F>U*>4Ð})Sx|¬U&À>%ËxQ&B8`@Q&F>8€xÆ D";{08`<eÛx8€D",#9 ?@‚,xŠ"T‰À>P‰BUHÀ>P‰F>QHBQHF>y)Æ})Cxy) èÞ4ÈxÆd|ÆKx|¬xÊ"|É3xTÆÀ>UHÀ>Q&BQHBQ&F>QHF>xÆÆ8`@|ÆCxeÛx8€D"|¬8€ƒãxKÿêa,#A‚ú8€ÃóxKÿóý8€||xÃóxKÿóíœx,A‚ùÜë!xëA€ëaˆëë¡˜KÿûD`B<Àÿÿ`ÆÿÿxÆ Kÿù@`8b’hHJÙ`8!°èëÁÿðëáÿø|¦N€ ``B9 ‘>4è`8b’HJ¡`KÿúÈ<À?xÆÆKÿú=@ÿÿyJ Kÿþx€|¦ûÿàû¡ÿèûÁÿðûáÿøøø!ÿq|x|ž#x|½+x|Ü3x8 8À$8€KÿÙɀ4ä,#A‚$|ex‡ãx¦ëxÄóxãûxKÿî…0£ÿÿ|e8!èëÿàë¡ÿèëÁÿðëáÿø|¦N€ €```B|¦øø!ÿ‘<b8càøKÿ{­`8!pè|¦N€ €``|¦úÁÿ°úáÿ¸ûÿÀû!ÿÈûAÿÐûaÿØûÿàû¡ÿèûÁÿðûáÿøøø!ÿ;€?¦x} |x>¨Ø9)ÿÿ|=H@AX<à=¦¨Ü9!ûˆxçƒä9@“¡|`ç8`ÿÿ‘!€Tc&8p‘p‘A„øátKÿ,¡`>¨Ø‹9)ÿÿ>à;ÿ;½?¦z÷ƒä;`ÿÿ{ÿ {½ :À;Þ¨Øb÷;; ;ApW{&H``B>9)ÿÿ|?H@DÓxcÛxA4>úÁˆúát“á|“€“!„‘!pKÿ,`ˆa|câT|>;ÿ|ø@{ÿ @‚ÿ¬8!ðWƒÂ>|câèêÁÿ°êáÿ¸ëÿÀTc>ë!ÿÈëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ €
``BûÁÿðø!ÿ="¦)¨Ø,	A‚È|¦ú ûAÐ?@ûÀûà;{Zƒäûáø;€ÿÿ?â¦ú¡¨úÁ°úá¸{ ;ÿ¨Øû!ÈûaØ; ;apøû¡ècZ; :àWœ&:À?dÛxƒãxû!ˆûAt“¡|¾´:€’¡€’á„‘!pKÿ*å`‰!9dÛxy
 ƒãx,)A‚ȁ?9)ÿÿ|*H@A,?û!ˆûAt‘|“€’á„‘!pKÿ*•`ŠÃóxKÿýQ9^dÛxyH |ixƒãx|	 @‚l?9)ÿþ|(H@A\?‘A|û!ˆûAt“€’Á„‘!pKÿ*9`¡A,*UI 6})êy= A‚ _}>´|
H@9
ÿÿ½@@@@þðèꁠꡨêÁ°êá¸ëÀë!ÈëAÐëaØëàë¡èëáø|¦8!ÃóxëÁÿðN€ ;ÀKÿÿì€|¦úÁÿ°úáÿ¸ûAÿÐûÿàû¡ÿèûÁÿðûáÿøøø!þñ|×3x|Ÿ#x|¾+x||xKÿýÙ?¢¦ƒ½¨Ø;W|vxKÿýÅWI6|cèP?¢¦|H@;½¨Ø@€L9 8!ƒãxù<ù<èêÁÿ°êáÿ¸ëAÿÐëÿàë¡ÿèëÁÿðëáÿø|¦N€ ```B="¦)¨ØûaèzÛ úA úa¨ú°ú¡¸9IÿÿûÐû!Ø|;P@›áAP<à9!“a|xçƒä8À`ç9@‘!€8`ÿÿ8pøÁˆ‘pTc&øát‘A„Kÿ(}`=9[9)ÿþyH WZá>|(H@³AAP<à=¦¨à‘A|8Àxçƒä9!`ç9@øÁˆ8`ÿÿ8p‘p‘!€Tc&øát‘A„Kÿ(`>`;@ÿÿzsƒä;à;:@bs:: ;!pWZ&HL`B=|þø®9)ÿÿ˜á|(H@A(=úAˆúat‘A|’€’¡„‘!pKÿ'¡`;ÿ{ÿ ÃóxH(‰`}Xú$ËxyH |?@CÓxA€ÿœ~óx;ûKÿú1="¦)¨Ø{ê ˜a9)ÿÿ|*H@AP<à=¦¨à8À“á|xçƒä9!`ç9@øÁˆ8`ÿÿ8p‘p‘!€Tc&øát‘A„Kÿ'`;{úüƒãx{{ û|êA êa¨ê°ê¡¸ëÐë!Øëaè8!èêÁÿ°êáÿ¸ëAÿÐëÿàë¡ÿèëÁÿðëáÿø|¦N€ €```B="¦i¨Ü="¦‰¨à="¦©¨Ø="¦øɨèN€ ="¦)¨Ø9)ÿÿ|#H@@8`N€ `B|¦øø!ÿa<àxçƒä9!=¦¨Üa|8À`ç9@8`ÿÿ‘!€8pTc&øÁˆøát‘p‘A„Kÿ%å`ˆa8! è|¦N€ €``Bø!ÿq="¦)¨Ø˜È9)ÿÿ|#H@A`|¦<à=¦¨àa|xçƒä8À`ç9AÈ9 8`ÿÿøÁˆ‘p8pTc&øát‘A€ø ‘!„Kÿ%M`è |¦8!N€ €`B="¦)¨Ø9)ÿþ|#H@@8`N€ `B|¦øø!ÿa<àxçƒä9!=¦¨Üa|8À`ç9@8`ÿÿ‘!€8pTc&øÁˆøát‘p‘A„Kÿ$µ` a8! è|¦N€ €``Bø!ÿq="¦)¨Ø°È9)ÿþ|#H@A`|¦<à=¦¨àa|xçƒä8À`ç9AÈ9 8`ÿÿøÁˆ‘p8pTc&øát‘A€ø ‘!„Kÿ$`è |¦8!N€ €`B="¦)¨Ø9)ÿü|#H@@8`N€ `B|¦øø!ÿa<àxçƒä9!=¦¨Üa|8À`ç9@8`ÿÿ‘!€8pTc&øÁˆøát‘p‘A„Kÿ#…`€a8! è|¦N€ €``Bø!ÿq="¦)¨ØÈ9)ÿü|#H@A`|¦<à=¦¨àa|xçƒä8À`ç9AÈ9 8`ÿÿøÁˆ‘p8pTc&øát‘A€ø ‘!„Kÿ"í`è |¦8!N€ €`B="¦)¨Ø9)ÿø|#H@@8`N€ `B|¦øø!ÿa<àxçƒä9!=¦¨Üa|8À`ç9@8`ÿÿ‘!€8pTc&øÁˆøát‘p‘A„Kÿ"U`èa8! è|¦N€ €``Bø!ÿq="¦)¨ØøÈ9)ÿø|#H@A`|¦<à=¦¨àa|xçƒä8À`ç9AÈ9 8`ÿÿøÁˆ‘p8pTc&øát‘A€ø ‘!„Kÿ!½`è |¦8!N€ €`B=B¦J¨Ø="¦9)¨Ø|
@A€,=B¦‰J¨ð,
@‚9@ÿÿèi™IN€ ``B8`N€ ```B9 =B¦™*¨ðN€ `B|¦ûÿàøø!þq|kx8apøÈø¡Ð}d[x8¡ÈøÁØøáàùèù!ðùAøH<•`,||x@”piû¡xûÁ€;£ÿÿûáˆ;Áox A‚$|>x8 8€Œ~pKþ`{¿!A‚Hˆ~;¾8 8€;ÞKþÝ`ˆ}9?ÿÿ8 y? 8€KþÁ`9?ÿÿy?!@‚ÿÀë¡xëÁ€ëáˆ8!ƒãxèëÿà|¦N€ €```B}€&úáÿ¸ûÿà‘ø!þÑ|wx="¦)¨Ø,)A‚,|¦ùÁ ùá¨.$û¡ûÁ -¥-ÿÿûá(úÐ>‚¦;€ûA?@ú!¸:”¨÷úaÈ>"¦{Zƒäú°ø@>b¦úAÀ:1¨Øú¡ØúÁà|µ+x|–#xûðû!ø"T; ûacZ;a;:p:s¨ø9\9)ÿÿyH Ÿ´|(H@;ÀA818`ÿÿ~ƒxû!ˆTc&ûAt‘A|“a€“„‘!pKÿ`‹ÁãûxKÿñ½|ð@‚ì1;ÿ{è 9Iÿþ|(P@Al19@8`ÿÿû!ˆTc&~ƒxûAt“á|“a€‘A„‘!pKÿ¡`£¡A’ì,=A‚@ŠèAŽ˜9àÿÿ~ž£x;à}ÒâUï&``B1}ò~ƒxy }ã{x9@9)ÿÿ|'H@A,1û!ˆûAt‘|“a€“„‘!pKÿ%`‰A9?ÿÿ^y?!@‚ÿ¨8 ~¤«x~c›xHi`,#@‚Üè@W© 6éÁ éá¨ê°;œê!¸êAÀêaÈêÐ9)ÿð{œ ê¡ØêÁàëðë!øy) |¦ëAëaë¡ëÁ ëá(û—ù78!0~ã»xêáÿ¸ëÿà}’ }‘ } N€ @’h; 9)ÿÿ|)à@A€þЁ18`ÿÿ~ƒxû!ˆTc&ûAt“|“a€“„‘!pKÿ)`‰!|	°@A‚þ”1W½ 6½â{¼ |	è@Aý¼è@éÁ éá¨ê°ê!¸êAÀêaÈêÐê¡ØêÁàëðë!ø|¦ëAëaë¡ëÁ ëá(9 ÿÿ;€Kÿÿ1KÿÿH19)ÿÿ|<H@Aÿ€Kÿÿ@€```B|¦ûÿàû¡ÿèûÁÿðûáÿøøø!ÿq9%|?x})´é|¾+x9)|}xy*äy)ä}JP|!PA‚ùð|!P@‚ÿøy) Åóx})Ð}Ij;pƒãxH á`<€ÿÿ9 `„ÿÿ…ãx£ëxx„ }<ñ®KÿûÝ8?£ëxèëÿàë¡ÿèëÁÿðëáÿø|¦N€ €``BúÁÿ°û¡ÿèûÁÿðûáÿøø!ÿ>¦|x="¦)¨Ø:Ö¨Ø|H@A(?¦‹Þ¨ð,@‚ë¶9@ÿÿ™V,=@‚ð|„ú| |ž´@€Ä|¦û°?úá¨{ƒä; ÿÿû!¸ûAÀûaÈûÐ;`:àc;!;@;pøW½&H69)ÿÿ{ê ›a|*H@„ãx£ëxA(6úáˆût‘A|“!€“A„‘!pKÿ¹`;ÿ|øÿ´@‚ÿ°èêá¨ë°ë!¸ëAÀëaÈëÐ|¦8!ðêÁÿ°ë¡ÿèëÁÿðëáÿøN€ `B|¦ûÐ|…#xxœ £ëx8€øHÅ`=@69“á|yJƒä8`ÿÿ“¡€“„aJ8pùˆTc&‘!pùAtKÿ	`èëÐ8!ð›Öë¡ÿèêÁÿ°ëÁÿðëáÿø|¦N€ €
``B="¦8`艨ÚKÿþ`B|¦øø!ÿ‘,%8cÿð|c´@‚(8„|„´KÿýÝ8!p8`è|¦N€ `B8€Kÿý½8!p8`è|¦N€ €``B|¦ûaÿØûÿàû¡ÿèûÁÿðûáÿøøø!ÿQ;¡p|x|œ#x£ëx|»+x8€8 |Þ3xKÿøñé!xèap9)()@8cÿð8€|c´Kÿý-eÛx„ãx{Æ £ëxKÿïëxëap|>àA‚;€;`?¦ƒÞ¨ØKÿí`8€8¢•P|fx;Þÿð|ÆðP£ëxxÆ KÿîÑûûŸ8!°ãûxèëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ €|¦øø!ÿ9}	¦|À3x9ao|æ;x9 9@``B|P9)ÿÿ9y) @}P®9JBÿà8¡pøa°™!|Kÿþ¡èa°8!€è|¦N€ €```B9$()@ø|¦úÿ û!ÿÈûAÿÐûÁÿðûáÿøøø!þá|d"„ÿð="¦)¨Øx xš z™ |H@@€úa¸û¡?¦úÁÐ>Àû;€ÿÿzփäú¡ÈúáØ;Þ¨Øûàûaø: bÖ:á;;apWœ&`B9)ÿÿ¿Ê|?H@dÛxƒãx{³ 9@A,>ú¡ˆúÁt“á|’ဓ„‘!pKÿÉ`‰A>™AdÛxƒãx9Iÿÿ|3P@A,>ú¡ˆúÁt“¡|’ဓ„‘!pKÿ…`>9_|
H@y_ A€ÿhêa¸ê¡ÈêÁÐêáØëàëaøëë¡|i¢8šÿð;Á |„´|c´Kÿú‘8 Ãóx8€Kÿö!聨èa 8„8cÿð|„´|c´Kÿúe?⦃ÿ¨ØKÿêi`8€8¢•P|fx;ÿÿð|ÆøPÃóxxÆ Kÿì58! 8`èêÿ ë!ÿÈëAÿÐëÁÿðëáÿø|¦N€ ``B8`N€ €
```B,#@‚8`N€ |¦øø!ÿ‘|c´|„´Kÿù½8!p8`è|¦N€ €``B|% @€8`N€ |¦úÁÿ°ûÿÀûÿàûÁÿðûáÿøøø!þÁ; |Ÿ#x|¾+x||x8 Ãx8€Kÿôåé8êÁ 9ÿÿ,)ÿÿA‚}_ðP|*HA9Vÿð~ßâúÀúáø|
°úaØûa{œ û¡({ÿ }P´~×´@="¦)¨Ø~ÖPPû!?"¦;9¨ØzÛ |H@Aœ=B¦‰J¨ð,*@‚ŒûAëY™,:A‚Ø>`ùá¸;ZÿÿùÁ°zsƒä9àÿÿú!ÈúAÐúàú¡è~ý»xQÓx:@bs:: 9ÁpUï&H``B99)ÿÿ{ª |*H@}Äsx}ã{x9 A,9úAˆúat‘A|’€’¡„‘!pKÿ¹`‰!;½1|è½´@‚ÿ¨£ëx8€Kÿ÷í}>â]Óx~ÖJ~ZHP|H{Ó @ˆ> : ÿÿzµƒä:€bµ:Á;@:pV1&``B9}Rê~ƒxyH ~#‹x9)ÿÿ|(H@=™!A(9úˆú¡t‘A|’Á€“A„‘!pKÿ`9;ÿÿy;!@‚ÿ¬9 =B¦éÁ°éá¸ê!ÈêAÐêàê¡èë!ëA™*¨ðÿ˜P?b¦ä´~ã»xKÿ÷
ƒû¨Ø;¼ÿò³Á{ª 9?ÿþ|*H@AT<à=¦¨à8À“¡|xçƒä9!`ç9@øÁˆ8`ÿÿ8p‘p‘!€Tc&øát‘A„KÿM`ƒû¨ØKÿæ­;ÿÿð`8¢•P8€ãøPÃx{æ Kÿè}êÀêaØêáøëa8`ë¡(8!@èêÁÿ°ëÿÀëÿàëÁÿðëáÿø|¦N€ ```BêÀêaØêáøë!ëaë¡(8!@8`èêÁÿ°ëÿÀëÿàëÁÿðëáÿø|¦N€ ~ƒx8€Kÿõé{Ó KÿþÄ```BêÀêaØêáøë!ëAëaë¡(Kÿÿœ€`B|¦ûÿàû¡ÿèûÁÿðûáÿøøø!ÿ!8`?‚¦?àib;Ácÿm,蜨Ú;¡ Kÿõi= CPÅóxûÁ°“áa)U0£ëxy)Æ8Àðe)lo8€Qa)gù!”Kÿç5= CPè¡°£ëxëÁ “áa)U18Àðy)Æ8€Qe)loa)gù!”Kÿç<¨Ø9@@{È ëá {Þ ±Aœ9Iÿþ|(P@AX<à=¦¨à9!œ“Á|xçƒä9@8À`ç‘!€8`ÿÿ8p‘A„‘pTc&øÁˆøátKÿ9`<¨Ø9Iÿþ98ày |&P@°áœAX<À<⦀ç¨à9!œ‘|xƃä8 `Æ9@‘!€8`ÿÿ8pø¡ˆápTc&øÁt‘A„KÿÍ`="¦)¨Ø;Þ9Iÿü{Ç 9|'P@‘œAX<à=¦¨à9!œ“Á|xçƒä8À`ç9@‘!€8`ÿÿ8pøÁˆ‘pTc&øát‘A„Kÿ]`="¦)¨Ø{è 9Iÿþ|(P@9@{ÿ ±œA\<à=¦¨à9!œ“á|xçƒä9@8À`ç‘!€8`ÿÿ8p‘A„‘pTc&øÁˆøátKÿí`="¦)¨Ø9Iÿþ98ày |&P@°áœAX<À<⦀ç¨à9!œ‘|xƃä8 `Æ9@‘!€8`ÿÿ8pø¡ˆápTc&øÁt‘A„Kÿ}`="¦)¨Ø;ÿ9)ÿü{è 9@|(H@‘AœAP<à=¦¨à8À“á|xçƒä9!œ`ç9@øÁˆ8`ÿÿ8p‘p‘!€Tc&øát‘A„Kÿ
``8b•`Kÿìé`8Àð8¢•ˆ8€p£ëxKÿäA?⦃ÿ¨ØKÿâE`8€8¢•P|fx;ÿÿð|ÆøP£ëxxÆ Kÿä8!àèëÿàë¡ÿèëÁÿðëáÿø|¦N€ €N€ <b¦€c¨ØN€ ``|¦ûÿÀû!ÿÈûAÿÐûaÿØûÿàû¡ÿèûÁÿðûáÿøøø!ÿQ?B¦|~x;Z©|˜#x|¹+xCÓx8 8€Þ´H```B;à{Ü ;¾HAž|zù®;ÿ|â}=úxc }>´Kÿæu`û´+¿,#@‚ÿÐ%ËxDÓxÃxH`,#A‚,;@‚ÿœ;Àÿÿ8!°ÃóxèëÿÀë!ÿÈëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ %ËxDÓxÃxH
µ`,#@‚ÿHKÿÿ°€`B|iyA‚ä|¦úÁÿ°úáÿ¸ûÿÀû!ÿÈûAÿÐûaÿØûÿàû¡ÿèûÁÿðûáÿøøø!ÿA:à?¦?b¦|º+x|Ù3x}>´;©;{ª`B;à{Ü :ÞHAžœ};ù®;ÿ|â}6úxc }>´KÿåE`ý´+¿|iy@‚ÿÐ}Xê%ËxdÛxCÓx™*HÙ`,#A‚¸,=@‚ÿ”8!À8`èêÁÿ°êáÿ¸ëÿÀë!ÿÈëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ %ËxdÛxšøCÓxHu`,#@‚ÿ8‰8; ,	=@‚X9|{B8!ÀèêÁÿ°êáÿ¸ëÿÀë!ÿÈëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ ‰8,	=A‚ÿ¸,=A‚ÿ°,9=ÿÿy) gÛx9)9@AH4,)9)ÿÿA‚ÿˆŒÇ9
9J}´}J´,=@‚ÿÜ|{BKÿÿh9 KÿÿØ8`N€ €
`B|¦ûÿÀû!ÿÈûAÿÐûaÿØûÿàû¡ÿèûÁÿðûáÿøøø!ÿA|xxc ÿ´|½+x|Ù3x|ú;x}CxKÿã…`|À@€\úáx´H``BAž@{û |~xcÛx;ÿKÿãM`Ÿ¸ÿ´|~óxWÞ>,@‚ÿÐêáxH`Bêáx?`ÿÿc{ÿÿ{{ 9<ÀP})Ê|H@A€Ø,9A‚@;Ýÿÿ?Ëx¾ØP``B|}òŒžxc Kÿãu`9?ÿÿy?!@‚ÿä{Ê{{ cÛx8€=KÿãQ`,<;û{ÿ ;ZÿÿA‚<H````BŒšãûx;ÿ{ÿ Kÿã`9ÿÿy!@‚ÿà8`8!ÀèëÿÀë!ÿÈëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ 8`ÿÿKÿÿÌ€	`Bû¡ÿèø!ÿ1|}yA‚|¦ûÁÀûáÈ{¾ |Ÿ#xûa¨ÃóxûA ßò»´û°úáˆûû!˜|¼+x|Ú3xøàKÿá½`|ðÞ´|ixA€H´}[´Až¬{c }?KxKÿá‘`9[Šð|ûx|ixWÿ>,@‚ÿÐE´„ãx£ëxKÿúa;ãÿÿ|xxÿ´H```B}?´{ù #ËxKÿá5`9?ÿÿ,#@‚ÿä}8ØP;Ÿy= }?Kx£ëxKÿåÍ`,|wx@¤;Cÿÿú¡xúÁ€¿ëx^Óx{V ~ºÀPH``````B|uòxc Kÿà¹`9?ÿÿy?!œ~@‚ÿä;96ÈPH`````B|yÒŒšxc Kÿá`9=ÿÿy=!@‚ÿäê¡xêÁ€~ã»xKÿåu`|œÚcÛx|˜ P|„´Kÿêí`èàêáˆëë!˜8`ëA ëa¨ë°ëÁÀëáÈ|¦8!Ðë¡ÿèN€ ```B;`ÿÿKÿþ€8`ÿÿKÿÿÜ€`B}€&ûAÿБø!ÿA|zyA‚À|¦úáxû€|×3xû!ˆûa˜|ø;x|›#xû ûá¸}Cx|¹+xøÐKÿùµ|yA‚HÉ`|#àA‚ÜûÁ°{^ _´û¡¨{òÃóxKÿßQ`|Ø{´A€Hœ``BAž{ý |~x£ëx;ÿKÿß`ŸØÿ´|~óxWÞ>,@‚ÿÐ$Ëx~å´CÓxKÿ÷ñCèPxy {^ ÃóxKÿã`|{yA‚¬.>:ûÿÿúÁpßóx~×ÈPA’\H````B|vºxc Kÿޙ`9?ÿÿy?!œw@‚ÿä#ËxKÿÞ}`99ÿÿ,=A‚(``By9 #ËxKÿÞY`99ÿÿ,=@‚ÿè,<:ùzã A‚D;ÿÿ|x™ãx``BŒ˜ãûx;ÿ{ÿ KÿÞ±`99ÿÿy9!@‚ÿà||ºxc ;#8€{? Kÿމ`A’L;›ÿÿH`````BŒœãûx;ÿ{ÿ KÿÞQ`9>ÿÿy>!@‚ÿàúÊ{ÿ cÛxKÿâ±`|ø@ATêÁp롨ëÁ°èÐêáxë€ë!ˆ8`ëa˜ë ëá¸|¦8!ÀëAÿÐ} N€ ```B¿èPs©{¾ ;½ÿÿA‚0ãûx8€Kÿݵ`{¾!;ÿ{ÿ A‚ÿ€```Bãûx8€;ÿKÿ݅`{ÿ 9>ÿÿy> ãûx8€;ÿKÿÝe`9>ÿÿ{ÿ y>!@‚ÿÀKÿÿ,``B? ÿÿc½ÿÿ{½ Kÿý˜ãûx…ãxÃxHE`,#@‚ýKÿÿèÐëḈãxÃx끠ë€~æ»x%Ëxêáxë!ˆdÛxëa˜8!À|¦CÓxëAÿÐ} KÿøXèÐêáxë€ë!ˆëa˜ë ë¡¨ëÁ°ëá¸|¦8`ÿÿKÿþ¨€
``|¦ûÁÿðøø!ÿa,&@‚Üûá˜|x8`û€û¡ˆ|¼+x|#xKþɍ`|~yA‚l(A‚ˆ8 äûxÃóx?â¦Hµ`9 <â¦=@€8€‘>‘'«="¦8` ‘?‚¦?¢¦‘I«;½«KþÉ¥`8€|ix8`9Iù?«ù\« KþɅ`=B¦|ix<``cù*«(KþÈé`è¿«="¦øi«0,%A‚0èü« ,'A‚$é],*A‚,#A‚é<À€€ž`i`ÆyJ 9)xÆÆ}F3xy„8`ù=(;àKÿí`|dy@‚xûax?`€?€c{{{Æ`Bé=(8`}IúyE }Iù*|¥Ûx;ÿ€žKÿ¥`|?à@‚ÿÔ9 Ãóx‘>ëax끀롈ëá˜8! èëÁÿð|¦N€ ‰?,	@‚þt‰?,	@‚þh;ÿKÿþ``;À8b•H•`8! ÃóxèëÁÿð|¦N€ `B`8b•ÐHi`<b¦èc«,#A‚8€ KþÉ}`<b¦èc«(,#A‚8€KþÉa`<b¦èc«0,#A‚<€`„KþÉA`Ãóx8€KþÉ1`;À끀롈ëá˜Kÿÿ\`8b•°HÝ`끀롈ëá˜Kÿÿ<`8b•øH½`KÿÿT€`Bûáÿøø!ÿ|yA‚0|¦ø?,	@‚0ãûx8€KþÈ¥`è|¦8!€ëáÿøN€ ``B€Ÿ8`Kþþí`<b¦èc«,#A‚8€ KþÈ]`<b¦èc«(,#A‚8€KþÈA`<b¦èc«0,#A‚<€`„KþÈ!`9 ‘?Kÿÿd€ûÿÀû¡ÿèø!ÿQ|}yA‚H|¦ûá¨ûA€?@€=B¦J«û!xcZ`ûÁ ?¦ûaˆ;"–(ûx› |¼+x;Þ«{ZÆøÀé>yJ&䁣ëx;|‰P.})RëéTŠt‡@Š@T„>|Ÿ"@ž¼A‚ )|H@A€Œ}8´ÃxH¡`€œ{ÿ 8`åÓxKþý­`>/¸9)q*ÿU)>‘>@‚>=)€‘>AžÿhèÀë!xëA€ëaˆëëÁ ëá¨|¦8!°ÃxëÿÀë¡ÿèN€ }$Kx#ËxH™`Kÿÿx```B;Kÿÿ¨;ÿÿKÿÿÀ€`B|jyA‚l|¦ûáÿøøø!ÿ9 dˆ€|Ÿ#x€ey
8à}DSx98À8 Kþý}`,#@‚,8!€ãûxèëáÿø|¦N€ ``B8`ÿÿN€ |dx`8b–X;àÿÿHÙ`KÿÿÀ€ûaÿØû¡ÿèûÁÿðûáÿøø!ÿ19@|{x; 9ÿÿ9Jÿþ8è‰(yJ!9ˆç©ê½:{½ @‚ÿÜ,=A‚Ð9[} Ü,?¦;Þ«@àV,?¢¦U&À>Q&B8`@轫HQ&F>8€xÆ 8¥TD"gÿ€è½«H8`@WæÀ>8€SæBSæF>8¥TxÆ D";àT; è¾8`@8€8À|¿*D"é>8¿8`@8€8À|¥JD",=;ÿ;½ÿÿ@‚ÿÀ8`8!ÐëaÿØë¡ÿèëÁÿðëáÿøN€ |¦úáˆû°?€ÿÿû?¦;ÿÿû!˜cœÿÿûA ;Þ«@;An{ ; {œ øàé^9 :àqJ"A‚p©H0è¾8`@a)8€U&À>Q&B8¥Q&F>xÆ D"è¾8`<8€8¥D",#@‚T‰À>*¸0P‰B7¸0P‰F>}JH8,
@‚;àçH```By!A‚8@žP8`Kþ¾‘`è¾8`<8€8¥D"T‰À>,#P‰B9ÿÿP‰F>~êH8y) yJ /ªA‚ÿ°‰ãxy)„;½µ:({½ @‚ÿ="¦é)«@q)@‚€£át9!r¡Ar|àN,9!p}N,9;àO,°û{ÿ ±¡!pQI€y) èàêáˆëë!˜ëA ë°|¦Kÿý¤``B	ÃxKÿÿx``B9 :àKÿþŒ<¢¦è¥«H8`<8€8¥D",#£át@‚T‰À>P‰BP‰F>q)A‚ÿTkÿKÿÿL,*@‚ÿ`8b–€H…`èàêáˆëë!˜8`ÿÿëA ë°|¦Kÿý¤y)„"Kÿþà€	`B9 a)€†|	@‚d<âx„ 8çâ¸9@|è;x9 H`B…(9J,)A‚4|	 @@‚ÿìJ9 =¦8`ù(«H}GRé*=B¦ù*«@N€ 8`ÿÿN€ ```B|¦û!ÿÈûAÿÐøø!ÿQ|ix=B¦8`?B¦ù*«HKþ¿¹`;Z«@|yyA‚œ8 8€û¡˜ûá¨Hü…`<€8 `„@ CÓxKþÂ
`?â¦?º<Àÿÿ8€è¿«H}:P`Æÿÿ8`@xÆ ù=@ 8¥ØD"è¿«H8`<8€8¥D",#@‚lT‰À>P‰BP‰F>q)@‚X;à18`dKþ»­`èº8`<8€8¥D"9?ÿÿ/£y?!T‰À>P‰BP‰F>U)¼.©@žA‚˜A–ÿ¸`B#ËxKÿúÍ,#@‚ˆûaˆ;zû;šûÁ Ûx;Ú`B8 8€ãûxHûu`|¬é=@ }Iò;Þ0}@ý(;ÿ|?à@@‚ÿÐûJèº8`@{é"8€U&À>Q&B8¥8Q&F>xÆ D"èºWæÀ>8`@SæB8€SæF>xÆ 8¥8D"èº8`@8€<À8¥8D"èº8`@8€8À8¥8D"èº8`@8€8À8¥8D"èº<Àú8`@`Æ8€xÆ 8¥D"èº8`@8€8À8¥D"?ÚŸãx;Þ(;z```B8 8€ãûxHúU`|¬é=@ }Iò;Þ0}@ý(;ÿ|;ø@@‚ÿÐœJèº9 {Š"8`@UFÀ>‘=@8€QFB8¥(QFF>xÆ D"èºW†À>8`@S†B8€S†F>xÆ 8¥(D"èº8`@8€<À8¥(D"èº8`@8€8À8¥(D"èº8`@8€<À8¥(D"èº8`@8€8À8¥( D"èº8`@8€<À€8¥D"9 ‘9ëaˆëë¡˜ëÁ ëá¨8!°#Ëxèë!ÿÈëAÿÐ|¦N€ ,)@‚ýp#Ëx8€Kþ¾%`; 롘ëá¨KÿÿÀ`8b‡øHÕ`Kÿÿ¬€```B#,	M‚ |¦ûÁÿðûáÿøøø!ÿ8€?¦|x8À8`@辫H8¥D"辫H8`@8€8À8¥D"8`
Kþ¸%`辫H8`@8€8À8¥(D"辫H8`@8€8À8¥(D"辫H8`@8€8À8¥8D"辫H8`@8€8À8¥8D"辫H8`<8€8¥TD",#@‚?¦T†nxÆ 8`@辫H8€8¥TD"8`<辫H8€D",#@‚`†€xÆ ="¦8`@}>Kx8€è©«HD"8`
Kþ·E`辫H8`<8€D",#@‚Ø`†xÆ ?¦<¢¦è¥«H8`@;Þ«@8€D"8`
Kþ¶ý`=>< Äóx`¥@ èi@ |~Kþ½`9 ãûx8€‘?Kþ¼%`8!€èëÁÿðëáÿø|¦N€ `B?¦<Àÿÿ`Æÿ8`@辫HxÆ 8€8¥TD"8`<辫H8€D",#A‚ÿ<Àÿÿ`ÆÿÿxÆ Kÿþø`B<Àÿÿ`ÆÿÿxÆ Kÿÿ(€`BûaÿØûÁÿðø!ÿa|~yA‚<¢¦è¥«HûAp8`<|š#xû€û¡ˆ8€ûá˜8¥(D",#@‚<TŠÀ>PŠBPŠF>yJ ?⮃ÿëP?¢¦?‚®;½«@;œ«@;`|P@A‚;ÿ{ê&ä}=R‰	q@‚0ëAp끀롈ëá˜8! cÛxëaÿØëÁÿðN€ ``B|¦9)|T(EÓxø°} N,9)ÿü|H@};´A¬é<@ x¥ Ãóx|‰ PHõé`{ã&ä8 8c8€|}Hõm`|¬<¢¦è¥«H9<@8`@8€|ÀL,8¥(D"<@è°ëAp롈cÛxëá˜|¦9)U)~‘<@끀8! ëaÿØëÁÿðN€ `B=@ÿÿaJÿÿyJ KÿþÌ}%KxKÿÿT``B;`ÿÿKÿÿ€```Bû¡ÿèø!ÿa|}yA‚t<¢¦è¥«HûÁ8`<|ž#xûá˜8€8¥8D",#@‚8TŸÀ>PŸBPŸF>{ÿ <¢¦è¥«H8`<8€8¥8D",#@‚èTŠÀ>;ÿPŠBWÿ~PŠF>|P@yI @‚ëÁëá˜8! ë¡ÿèN€ |¦9JUJ~UFÀ>QFBQFF>ø°xÆ ?â¦9)øÁp;ÿ«@y)&ä=¤ëx|L({Å ÿJé@ |hPHô1`9 9_ÀW,±?|¬<¢¦è¥«HèÁp8`@8€8¥8D"è°Ãóxëá˜ëÁ8! ë¡ÿè|¦N€ ``B|¦= ÿÿa)ÿÿ8Ày) ø°KÿÿX`B?àÿÿcÿÿÿ{ÿ KÿþÐ8`ÿÿKÿÿ€```B9 a)€†|	@‚¼|¦ûáÿøøø!ÿ9@<â|£+x8çâ¸|ß3xx„ |è;x9 H ```B…(9J,)A‚T|	 @@‚ÿìJ="¦8 8€øi«Hãûx}GRé*=B¦ù*«@Hò‘`8!€ãûxèëáÿø|¦Kÿñ”8!€8`ÿÿèëáÿø|¦N€ 8`ÿÿN€ €`````|¦û¡ÿèûÁÿðûáÿøøø!þq;Áp|Ÿ#x`ø¡Ð|}xøáà|ex8‚˜€ùèù!ðÃóxùAøøÁØHþ•`8ÁÐåûx ƒ|x|~Hi`8Ÿÿú£4|„´|ž"KþÍe`ÃóxHî%`8 ‘xd ÃóxKþ¼A`8!èë¡ÿèëÁÿðëáÿø|¦N€ €|¦û¡ÿèûÁÿðûáÿøøø!ÿQ;¡p|~x§ëxHyý`,|x@<|eVp`8ž@8b˜Hù`8!°ãûxèë¡ÿèëÁÿðëáÿø|¦N€ 9 |ex¤ëxÃóx8áˆ8Á€ù!€H€u`聀|x,$A‚ÿ°èaŠKÿþ‰8!°ãûxèë¡ÿèëÁÿðëáÿø|¦N€ €``B|¦úáÿ¸ûÿÀ}€&û!ÿÈûAÿÐûaÿØûÿàû¡ÿèûÁÿðøûáÿø‘ø!ÿA-†;å|Þ3x|¸+x||x|#xÿ´AŽœ,A‚4``8‚– 8b™Hñ`H^©`H(```B``8‚™@8b™HÁ`H›)``?b®.>-;B˜¸;{ëh; :àHL```BAŽð@Š8è}R8€’ûHŒ­`¤ëxƒãxH›-`|~yA‚P,ÿÿ@‚X;ÿÿÿCÓxÿ´äûxH5`HÍ`/¿,A‚ÜAžø@’ÿ”¤ëxƒãx“;H^%`,ÿÿ|~xA‚ÿ|`8b˜øHé`8!ÀÃóx聁êáÿ¸ëÿÀë!ÿÈëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦}’ }‘ } N€ ``B¤ëxƒãx“;H]¥`|~xKÿÿ,`B``8‚™8b™Ha`H]`Kÿþ ```B`;Àÿÿ8b˜ÀH5`KÿÿL``B`Ãx8b˜Ð;ÀÿÿH`Kÿÿ(`BHñ`8 |dx8}Hîm`Kÿþô€	`B|¦û!ÿÈûAÿÐ}€&ûaÿØûÿàû¡ÿèø‘ø!ú9`9 9Bœ‘x=®|yx8`¸éjéJ‘(ëh|š#x|»+x|Ü3xùA`ùahKþ°™`|}yA‚´8 ¸8€û°ûÁàûáèHíe``;€8b™p;ÁpH`8 X8€Ãx;àHí5`Æóx8 8€8`Kþ¦½`,ÿþ|jx@‚hH‰`,A‚|9?,	
}?´A‚lKþ®É`Kþ­Á`Kþ®9`,AÿôÆóx8 8€8`Kþ¦Y`,ÿþ|jxA‚ÿ ,ÿÿ@‚˜`8`08‚™ˆ;€ÿœKÿú]H`B`8`08‚œh;€ÿ›KÿúA8€¸£ëxKþ±u`èaÀHøÙ`èaÈHøÍ`ë°ëÁàëáè8!ðƒãx聁ë!ÿÈëAÿÐëaÿØëÿàë¡ÿè|¦} N€ ‰!u‰tˆásˆÁr`ˆ¡qˆp8b™¨‘AÐú¡˜úÁ úá¨H¹`ÃóxH&`},B¦€ar|cJxxc Hô…`,<A‚ü(ÿAÀ:á€dÛx…ãx~ã»xHé`â9 ;aØ8 ¸™<€8€cÛxHëi`~ã»xH]`.#|vx@’8="®9@é)ëj‘A<,	A‚\,	A‚
,;X9 
9@‘AŒ}?HP,	
@€9 
8 „ãx‘!ˆÃxHëY`="®é)ëj,	A‚,	A‚D!<(	Aä=ÿþ9G€y*d}(Rª})B})¦N€ Ä|`DÀ€¡ˆ8ÀÃx£ëxKÿú	|x,A€ü="®é)ëj,	A‚˜,	A‚¸8(@‰!Ø:áÀ,	@‚="®é)ëj,	‘!ÔA‚¸,	A‚<~ã»xHæ¥`,|c´@t8cÿÿ;a€|´};ú‰)@,	/A‚<é!À;€,)A‚¸‰!Ø,	@‚ûú‰?@,	/A‚@.!<,	A‚¸èaÒKþTå`@ê¡˜êÁ êá¨Kÿý0;á`:áHäûx~ã»x8 HëU`,#@‚Ä9 ‘!<€¡ˆ8ÀÃx£ëxKÿøÝ|xKÿþԀ¡ˆ8ÀÃx£ëxKÿøÁ|xKÿþ¸;áp8 ãûx8xHêõ`,#@‚
”9 ÿÿ‘!˜€¡ˆÃx£ëxHGÑ`|xKÿþt;á`:á`äûx~ã»x8 Hê­`|yèaÒA‚Ø~ä»xH…å`="®é)ëj,	A‚Ø;àKÿþ@`B‰!Ø,	@‚è,#@‚\ëaŽ8`Hñu`="®,#øiëpA‚À;;á€``†ãxåûx8‚›ˆ8b›˜Kþµ½`,#@‚
¸!è¡€,	$@
Èûp<â®èçëpÄóx9@éûx9fÛxÃxHù`.||xA8,#A‚hé!’8 ÿ~ã»x{{ y).¤}?Jè‰Håa`9 fÛxEÓx$ËxÃx™!¿KÿöQ.||x@‘äé!’y).¤}_JèŠ,$A‚”ÃÐP,Þ´@
x98 ÿ~ã»xHäý`fÛxÅóx$ËxÃxKÿõõ,|{xA€Ô|cðPeÛx$Ëx|yHè`Ùò`|›ðP8bœ(Kþ²}``Äóx8bœ@Kþ²i`é!’y).¤ÿJèŸ,$A‚,|ƒ#xø€Hãa`聀8£`8bœXKþ³	`<b®ècëpHó9`Kÿüì;aØ8 ¸8€cÛxHæ`= 
9@y)ƒä;Xa)8 ‘A<„ãxÃxù!ˆHæÍ`="®é)ëj,	@‚ûx8x8 ƒãxø€Hè`聀,#A‚û\;á@8 ãûxHçõ`,#A‚û@‰!Ø,	A‚û4äûx8 8a˜Hæ]`9 ‘!<="®;àé)ëj,	@‚ût;à:áx8 ~ä»xƒãxHç•`,#@‚L;@~ä»xƒãx8 Hçu`,#@‚`€a€H+‘`H`B,ÿÿA‚\="®é)ëj,	A‚ô,	@‚,8€8aˆø€HŒõ`聀`8bšxHý!`,ÿþ@‚úԀ¡˜`8`08‚š˜;€ÿšT¨>x§Æ"x¦†"x¥FKÿòÝèaÒKþP5`ꡘêÁ êá¨Kÿø„```B`;€ÿù8b™ðHý`ꡘêÁ êá¨KÿøT‰!Ø,	A‚ü(èaҁ!<;€,	A‚¼KþOÍ`é!>,	A0,	A0@‚úØ8€¸£ëxKþ±¥`ꡘêÁ êá¨Kÿ÷ô,	@‚ú°8€¸£ëxKþ±`ꡘêÁ êá¨Kÿ÷ÌdÛx8 ÿ~ã»xHá¹`9 ™!¿KÿùÔ:¡ø8Àd~¥«x8€~ã»xHá``~£«x8‚šHæm`9 ,#A‚`~£«x8‚š HæM`,#A‚p`~£«x8‚š(Hæ1`,#A‚„="®9@é)ëj‘A<,	A‚À,	A‚œ;XHx€€`8bšPT‡>x†Æ"x…†"x„FHû=`Kÿþ9 ~ã»x8€‘!<HÑ`="®:ÖÿÿzÖ é)ëj|wx,	A‚L,	.6;XA‚ A’÷è:¡ø8Àd~¥«x8€~ã»xHÕ`‰!ø,	@‚¼9 
‘!ˆ~ã»x8€Ha`(|wxA‚8Àd~¥«x8€H‘`‰!ø,	@‚ 9 ‘!Œ~ã»x8€H`é!ŠKÿ÷h€¡˜`~ä»x8bšðT¨>x§Æ"x¦†"x¥FHú=`Kÿø,`8`08‚šÈ;€ÿ•KÿðèaÒKþMi`ꡘêÁ êá¨Kÿõ¸`8`08‚š0;€ÿ›KÿïáèaÒKþM9`ꡘêÁ êá¨Kÿõˆ`~ä»x;á€8b›(HùÁ`äûx8a ûá€H‰m`聀`8b‰Hù™`Kÿ÷ˆ;`:á`„ãx~ã»x8 Hãi`,#@‚ :áH„ãx~ã»x8 HãI`,#A‚ûô; 8 „ãx~ã»xHã)`,#A‚ûÔ~ä»xƒãx8 Há`Kÿû¼€ÁŒEÓx$ËxÃxKÿïÁ.||x@‘÷0!<,	@‚,èaÒHR±`Kÿ÷@8€H~`H€¹`8 |dx8aˆHá5`="®é)ëj,	@‚öX;àKÿúä‰!Ø,	A‚÷8~ä»x8 8a Hàý`9 ‘!<Kÿ÷ `;€ÿÿ8b›È.Hø¹`Kÿù°:Áˆ8 ~ijx~ã»xHâ-`,#A‚þÈ~ä»x~óx8 Hà¡`Kÿþ°;ãÿÿ;€ÿ´;a€KÿöL9 ~ã»x8€:Öÿÿ‘!<H`9 =B®zÖ ‘*ëh|wx.6A’ì:¡8Àd~¥«x8€~ã»x;HH
±`~£«x„ãxH…`,#@‚$‰!,	@‚Xƒãx8 8€Hߙ`~ã»x8€;–ÿÿH`{œ!|wx@‚œ:À9 .6™!Ø8 8€8a`HßU`8 8€8ax;XHß=`Kÿü(é!ŠKÿô8 
8€~£«xHåí`|c´,aˆ@€ü0Kÿü$~£«x8 
8€HåÅ`|c´,aŒ@€üLKÿü@8 8€8a@:ÀHÞÉ`9 .6™!Ø;X8 ƒãx8€HÞ¥`8 8€8apHޑ`Kÿû|äûx8 8a˜HÞÙ`Kÿõd8 ÃxƒãxHà1`,#A‚ø „ãx8 ÃxHÞ¥`Kÿøˆ:á˜8 ~ä»xƒãxHßù`,#A‚øˆ„ãx~ã»x8 HÞm`Kÿøp8 8€8aH:ÀHÝñ`Kÿþ|HO•`èaÒKÿù<.6A’þøú:8Àd~…£x8€~ã»x;@H‘`~ƒ£x„ãxH`,#@‚$‰!ƒãx8 8€,	@‚8HÝy`~ã»x8€:¶ÿÿH	õ`zµ!|wx@‚ꁐ:ÀKÿþˆ~Õ³xHÝA`8ÀdeÛx8€~ã»xH	`‰!ØjÛx9/,)A‚8H``````B(	\@‚™
*,)@‚ÿì~ã»x8€H	a`(|wxA‚è8Àd~…£x8€;XH
`„ãx~ƒ£xH}`,#@‚$‰!8 8€ƒãx,	@‚øHÜu`~ã»x8€Hõ`95ÿþy) ,)|wxA‚d8Àd~…£x8€~ã»x:¡pH
`~ƒ£x~¤«xH`,#@‚$‰!~£«x8 8€,	@‚hHÛý`~ã»x8€H}`ꁐ|wxKÿøÐú8ÀdeÛx8€~ã»xH	¥`‰!ØjÛx9/,)A‚4H`````B(	\@‚™
*,)@‚ÿì~ã»x8€H`(|wxA‚8Àd~¥«x8€:`H	-`~„£x~£«xH€}`,#@‚$‰!~ƒ£x8 8€,	@‚èHÛ`~ã»x8€H•`9<ÿþy) ,)|wxA‚8Àd~¥«x8€~ã»x;xHµ`~£«x„ãxH€`,#@‚”‰!ƒãx8 8€;X,	A‚þ Hڙ`ꁐKÿ÷€8 KÿòXHځ`Kÿþ0.||xKÿó¬`8b› Hò¡`8 Kÿò(ƒãx8 ú8€~ܳxHÚ=`Kÿþ`HÚ1`Kÿÿ@~ã»x8€H­`;Xꁐ|wxKÿöü`;€ÿÿ8b›ø.Hò5`Kÿó,ꁐKÿûHꁐKÿúêKÿû ꁐKÿúl`;€ÿÿ8b™HHñý`Kÿí|`;€ÿÿ8b›PHñå`KÿïÔ€```|¦ûÿàûÁÿðûáÿøøø!üá8 ;È|Ÿ#x|~x8€ƒãxHÙQ`9?ÿÿ(	ýAû¡;¡ÈÄóxåûx£ëx;ÁpHم`þú9 £ëx™?XH
`9 
|y‘!ÔA‚È(A‚8À@Åóx8€£ëxH½`„ãxÃóxH
­`,#A‚8À@Åóx8€£ëxH`„ãxÃóxH
}`,#A‚`£ëx8€H`|}x8À@Åóx8€£ëxHI`8¡Ø8ÌÃóxHe`,#A‚£ëx8€HÍ`(|}xA‚è8À@Åóx8€Hý`8ÐÃóxH	í`,#A‚Уëx8€H…`(|xA‚ 8À@Åóx8€Hµ`ãûx8 
8€Hޑ`aÔHp£ëx8€ûaøH5`8À@Åóx8€;ÿÿ|}xHi`„ãxÃóxH	Y`{ ,#A‚Ô£ëx8€Hí`(ëaø|}x@‚þÐ8 X8€Ãóx;¡àH×5``8bœøHï`¦ëx8 8€8`Kþ­`,ÿÿ|xA‚L,ÿþA‚(‰!å‰äˆáãˆÁâ`ˆ¡ሁà8bx“áÀHî­`£ëxH`!Ì,	@‚€Äóx8À8 8`Kÿæ`|i4,	ÿÿA‚¨€apH…`€p`8bÀT‡>x†Æ"x…†"x„FHîA`H¹`|~y@‚”„ãx8 8aˆH֝`€ˆ`8bžT‡>x†Æ"x…†"x„FHíù`€ˆãûxH&9`Kþ—á`= ffÔa*fg|ix|cþp})P–})p|cHP|cAÖ|c´Kþ–±`H `BH`H&Ù`,#A‚,Kþ—	`|ixãûx,	AÿÔ`;àÿÿ8b‹ Híe`èa°Háù`èa¸Háí`èaÂKþ@‘`ë¡8! ãûxèëÿàëÁÿðëáÿø|¦N€ `B;¡ÌÃóx¤ëx8 HՁ`€aÐ,#@‚ €aØ,#A‚ôHA`€apHõ`€p`8bÀT‡>x†Æ"x…†"x„FHì±`H)`|~yA‚þt`8bàHì‘``WÇ>{ÆÆ"{ņ"{ÄF"8bðHìq`Kÿþ@`B`;à8bžHìU`Kÿþð``B8À@Åóx8€£ëxH1`„ãxÃóxH!`,#@‚üðë¡`;àÿÿ8bœ Hì`KÿþÄ`B£ëxH`aØKÿÿ```BHñ`KÿþÜ`;àÿÿ8b˜Hë¹`KÿþT`;àÿ›8bHHë¡`ë¡Kÿþ``;àÿœ8b Hë…`ë¡KÿþDëaøë¡Kÿÿ`€```,$9@M‚ `B‰#(	,@‚H$#(	,A‚,)@‚ÿð8`N€ `B9*8c|H@y* @‚ÿÀN€ ```B9```B‰#(	,A‚,H````B,)A‚,#(	,@‚ÿð98cy KÿÿÀ```B}CxN€ ```B‰#(	,A‚8,)|jx8`9M‚ *y (	,M‚ ,)9@‚ÿèN€ 8`N€ ```BûÁÿðø!ÿ|ˆ#y|¾+x|dx|Å3xA‚Ü9@‰$(	,@‚H4$(	,A‚(,)@‚ÿð8!€8`ëÁÿðN€ ```B9*8„|H@y* @‚ÿ°|¦ûáxø‰$(	,A‚ˆ|Š#x;àH``B*y (	,A‚,)9@‚ÿèÃóxHÎñ`,#A‚49 Ãóx}>ù®èëáx8!€ëÁÿð|¦N€ ,#@‚ÿ|KÿÿHèëáx|¦Kÿÿ8;àKÿÿ¨€```B}€&ûáÿø‘ø!ÿ!|xˆc,#A‚œ|¦ú€ú¡ˆ.%ûÁÐûA°`úÁúá˜;B›ð:àû û!¨;|¹+xûa¸ûÀ;dÿÿ;pøðû¡È:Àÿÿ; HÔÅ`,#A‚¸DÓxãûxHÏ`|~yA‚`DÓxãûxHÏ`|P|c4(	x~ A|Åóx~¿òÁòäûxƒãxHÍ¥`šþp8 
8€ƒãxHÖÍ`(ÿA@|{é®,8{´ ‹õkÿ.ÿ4WÿÙ~õú@‚lˆ,#A‚p;½(=@‚ÿ@8`èðꁀꡈêÁêá˜ë ë!¨ëA°ëa¸ëÀë¡ÈëÁÐ|¦8!àëáÿø} N€ `B;ÿ8 	äûxƒãxHÌá`8 
8€šáyƒãxHÖ	`|~xƒãxHË©`9>ÿÿ(	ÿAÿdA’ÿH#Þ ~Þð0“ÙKÿÿ8```B8€\ãûxHÊY`|uyA‚\8€\ãûxHÊA`|¿P|¥4(	x¸ AÿÃxäûxƒãx~¿ÂHÌ5`|¡Â;›ÅpKÿþˆ```B8 	äûxƒãxHÌ`ƒãxš¡yHÊå`~¿KÿþP`Bjƒ|c4TcÙ~|cÐ|c´Kÿþ8`Kÿþ¼€`B8 Kÿý,```````|¦û¡ÿèûÁÿðûáÿøøø!ÿQ;¡pxÆ §ëx|~xHV‰`,|xAx,ÿýA‚¨9 |ex¤ëxÃóx8áˆ8Á€ù!€H]1`聀|x,$A‚`8bžpHåQ`8!°ãûxèë¡ÿèëÁÿðëáÿø|¦N€ ``B|ex`8ž@8bž(Hå`8!°ãûxèë¡ÿèëÁÿðëáÿø|¦N€ `8bžPHäá`Kÿÿ€``Bû¡ÿèûÁÿðø!ÿ9 £"|#è@‘'@€X,ûà|Ü3x@P|¦ûáø8„ÿÿûaØ|xc"ú€ú!ˆ8€
ãûxúAúa˜ú ú¡¨``úÁ°úá¸``ûÀû!È|¹+x`ûAÐø|ú;x`ùÁpùáxHÇ©``:à;À:,#;ž¨:¢ž°:Bž¸:‚žÈ:"žÐ:bžÀ:žˆA‚```B9ã9#ÿÿš|?H@A0}?P})¦`B#ÿÿq*û(	 /Š	A‚@žšBÿä‰?(	 +‰	A‚@ž;ÿKÿÿè`B,)A‚x(	#A‚p8€ ãûxHÆé`,#A‚@š9Ã````B‰.(	 +‰	A‚@ž9ÎKÿÿè`BäûxÃxHÍ©`,#@‚@}×sx|/è@@€ˆ|à@€€}ÿ{x8€
ãûxHÆi`,#@‚þücÛx¯ëxKÿþôäûx~£«xHÍU`,#@‚È,7{É.¤}ÙI*A‚ }Ãsx~ä»xHÆm`,#@‚“Ú|/è@;ÞÞ´A€ÿ€èéÁpéáxê€ê!ˆêAêa˜ê ê¡¨êÁ°êá¸ëÀ|¦ë!ÈëAÐëaØëàëáø8!Ãóxë¡ÿèëÁÿðN€ 8€	ãûxHŕ`,#@‚þ°äûx~óxHáí`Kÿþðäûx~C“xHÌy`,#@‚P,>@‚8äûx~c›xHÌY`äûx~ƒ£xHÌI`äûx~#‹xHá™`Kÿþœ{É.¤}9JùÉÿèKÿþŒäûx~c›xHÌ`,#@‚0,>A‚ÿ°{É.¤}9JùÉÿðKÿþ\;ÀKÿÿ(ëà;ÀKÿÿäûx~ƒ£xHËÑ`,#@‚ÿ„,>A‚ÿ|{É.¤}9JùÉÿøKÿþ€```B|¦úaÿ˜ú¡ÿ¨úÁÿ°úáÿ¸ûÿÀû!ÿÈûAÿÐûaÿØûÿàû¡ÿèøûÁÿðûáÿøø!ÿ|~x;hÿÿècHêá`}Cx|#x|µ+x|Ö3x|ü;x}9Kx,#}XSx{´A‚@HÅ`(Üx AôèžH:~@;ÿ@~c›x{ÿ þúHı``8bŸ€Hà¡`è~@,#A‚`úHÄÉ`|tx~c›xHĹ`~”(4A¨èž@ãûxHÄ]`~ƳxeÛx„ãxÃóxKÿúꁐ,øapA,5A‚0~¤«xãûxHÄ!`~ƳxeÛx„ãxÃóxKÿùÙ,AÐ‰]‰=‰ˆý`ãûxˆÝˆ½8‚ŸÐHÔI`~ƳxeÛx„ãxÃóxKÿù‘,Aˆ>T,	A‚``ãûx8‚ž¨HÝ`~ƳxeÛx„ãxÃóxKÿùU,@€L8!ðèêaÿ˜ê¡ÿ¨êÁÿ°êáÿ¸ëÿÀë!ÿÈëAÿÐëaÿØëÿàë¡ÿèëÁÿð|¦ëáÿøN€ ꁐ`B|A,<b8cæP``8À÷8¢ 8‚ HÞ]`H9 8!ð8ƒ~ç»x}<®Ãx%Ëxƒãx|„´èêaÿ˜ê¡ÿ¨êÁÿ°êáÿ¸ëÿÀë!ÿÈëAÿÐëaÿØëÿàë¡ÿèëÁÿð|¦ëáÿøKÿù„:~@8€/~c›xHÉå`|yA‚¨;ÿ}3øP()ÎAÔ`ãûx8‚ŸpHÂi`ãûxH`ÿKÿý¨ú`ãûx8‚Ÿø;¿	:Ÿ: €¾T¨>x§Æ"x¦†"x¥FHҍ``Bž½ÿÿ~ƳxeÛx„ãxÃóxKÿ÷Í´è@,Aþ¸@žÿÜꁐKÿþ<~›xKÿÿh`8bžðHÝÑ`8`ÿÿKÿþL`8bŸ Hݹ`ꁐ8`ÿÿKÿþ0`8bŸHݝ`8`ÿÿKÿþ€
|¦øø!ÿ‘8 |dyA‚,<b®8cëxHŁ`8!pè|¦N€ ``B<b®8€8cëxHÄõ`8!pè|¦N€ €<b®8cëxN€ ``B|¦ûÿàûÁÿðûáÿøøø!ÿa8 î?®|x;Þë€8€Ãóx?‚®HÄ}`ãûxÄóx8À8 îKþ€õ`;œëx,#A‚`,
û¡ˆx} @Ô`8 8‚ ¨ÃóxHÆ`,#@‚T="®¡)ëŒ(	A‚4m*ÿÿ,
†ÝA‚¨(	8`ÿÿA‚Ü롈8! èëÿàëÁÿðëáÿø|¦N€ ``B<‚8 8„åÃóxHő`,#A‚ÿ”8 „ãxÃóxHÅu`,#A‚ÿx9 33Ãóx8 8p±!pHÅQ`,#A‚ÿT롈8`ÿÿKÿÿt`B8½ÿò8œx¥ ãûxHcA`롈8! èëÿàëÁÿðëáÿø|c´|¦N€ `B8½ÿò8œx¥ ãûxHQ`롈8! èëÿàëÁÿðëáÿø|c´|¦N€ `B8½ÿò8œx¥ ãûxH¡`롈8! èëÿàëÁÿðëáÿø|c´|¦N€ €``B|¦øø!ÿ‘8ÀKþñ`8!pè|¦N€ €```B|¦ûÁÿðûáÿøøø!ÿ|‰#x|Þ3x|x|¤+x±#8 8cH`Äóxãûx8 HÂm`8!€èëÁÿðëáÿø|¦N€ €````|¦û¡ÿèûÁÿðûáÿøøø!ÿq9 =B®?â®;ÿñ€;À
‘*ñp=B®; ‘*ñt=B®‘*ñx```Bãûx8 “¿ÿü8€;ÿHÁm`9>ÿÿ“¿ÿô“¿ÿøy>!@‚ÿÔ8!="ÿÿ9)r@=B®èë¡ÿèëÁÿðëáÿøù*-€|¦N€ €``B9%()îA |¦ûÿÀû!ÿÈûAÿÐûaÿØûÿàû¡ÿèûÁÿðûáÿøøø!ÿ|¾+x|}x$|Ÿ#x,)@‚„="®)-ˆ‘$8à9ÿþ9 
9@°ÿ
8à8À|é¦8è ¨9)ÿþy) 9 ç}J*|Æ:Bÿà}J2ˆÿ	yH„yJ }HRyH„,}JB}JPø±_
A‚èƒ,ÿÿ?B®=®ñx;ZñpA‚0="®)-jHø,
A‚Z<|
ØA‚<Z<}JÚx}IH8,	@‚ā:|	@@A‚´< ÌÌ`¥ÌÍH```BAž I8é}'(|ÚRU)èþ€Æ)
|Ø})8P‰@@y) @‚ÿÐ;`˜R8 8Ü8‚ ¸|Ã3x`øÁHÁI`;" °èÁ,#@‚|ú ú¡¨úÁ°úá¸=®ñx8 *8€:è
:È~øº~¸²~ã»xH¿)`KÿúQ`= >‚®‚”-ˆ8 a)y)Æ|dxe)8ua)}8±*H¿M`’•8 $Ëx8uH¿5`“uKÿùù`&Ëx8€|ex~ã»xKÿüa`~ä»x8 *£ëxKÿü
`,<@‚<®=@ÌÌ=®ñtaJÌ̀fñx8ã}'PU)èþ)
})8P|	@@‘&ñx@‚9}(PU)èþ)
})@P‘:c9 8 8€š8c|x‘<“|H¾`KÿùA`8Ù8€|ex8z<(Kÿû©`Åóxäûx8z<6;ÞH¾A`="®“É3ˆKþ±`Kþ~©`H ```BKþ`,@£ëxKÿøí`<,	@‚ÿÜꁠꡨêÁ°êá¸8!8`èëÿÀë!ÿÈëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ `B(	@‚üˆ=B®J-ˆ="®)-Œ‘D‘$Kÿül```BZ<}JÚx}IH8,	@‚À9Z`8 °ŠBøÁKÿø`èÁ;|
8€|excÛxKÿúy`Åóxäûx8|H½`8¾dÛx|¥´£ëxKÿú
`8!èëÿÀë!ÿÈëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ `B±?8 8€8apH¼Q`¡?é‰_	ƒy'!±!rù|™AyA‚ 8çÿÿ9@Tæø~9 9q8àA‚xÉa9@¡?A‚<Uø~9ÿÿy 9}	¦9
|ßR.y 9H}B.})2yJ |çBBÿà}):99An}	¦8àH`````B9
 Ê9J¡})2|çBBÿè}):y*„y) }*Jy*„})R})Høq)ÿÿ@‚9 ÿÿ±?Kÿû`B:<|	ØA‚h="®)ñt?b®ƒ{-”|	@@A‚À< ÌÌ`¥ÌÍHAž`I8é}'(|ÚRU)èþ€Æ)
|Ø})8P‰@@y) @‚ÿÐKÿû@``B9Z<Â8ÆåŠBKÿýÔ``B`ú ú¡¨;€úÁ°úá¸;" °?®;ñ|KÿûD9 KÿþÌꁠꡨêÁ°êá¸8`ÿþKÿýØ8`ÿÿN€ `ú ú¡¨;€úÁ°úá¸;" °?®;ñ|Kÿúô`ú ú¡¨;€úÁ°úá¸;;" °KÿúЀ``B="®i-ˆKÿø(``B<b®€c-ˆN€ ``B= =C |
H@@€DTh†~="®<â9@i-Œ="™å=°iå9 ^±Hå=B™*åN€ ``B|¦øø!ÿ‘9 =B®<b8 8€ÿ8cå‘*-ŒH¹I`8!pè|¦N€ €`B<b®€c-ŒN€ ``B="®i-”Kÿ÷(``B<b®€c-”N€ ``B="®i-Kÿöè``B<b®€c-N€ ``B‰#}*t,
A49Iÿ€UJ>(
?@D9)@U)>(	@$8`N€ ``B<`ÿxc N€ `B<`ÿÿ`cÿxc N€ <`ÿÿxc N€ ``B9 9E°ƒ˜£	9@ÿÿÃã±‘#™C±#
N€ `B(@l|¦ûAÿÐûaÿØûÿàû¡ÿèûÁÿðûáÿøøø!ÿa|?x|}x="®)-Œ€¤|ž#x,)@‚=@à|P@A€ü= ð|H@A€¨,ÿÿA‚="®)-ˆ,)A‚|	(@@‚ˆ9 ž
9^ÿþ9 8à±
9}	¦9
 Ê9J¡})2|çBBÿè}):y*„y) }*Jy*„})R})HøU)>|H@‚$¡>q*ÿ@‚€q) @‚¨‰>	(	A‚|(	A‚T(	8`ÿÿA‚Ø8? èëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ ```B|	(@A‚ÿ0,ÿÿ@‚ÿKÿÿ$```B=®¡3”¡>?‚®;œñp|H@‚8=®‰3™‰>	|H@‚$B,>|H@‚<B0|	(A‚`B8`8? èëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ `B‰>¡^(	yH A‚(	A‚<,)8`@‚ÿ¡^a)Ôv|
H@‚ä¡>,	@‚Ø=®^(ñp|
H@‚Ä,)A‚¼9 ‘(ñpKÿþÄ`B ¾£ëx8ž8¥ÿìx¥ H`Kÿþ  ž8~8„ÿì|„´HA`Kÿþ„`B ¾<b®Äóx8c3Hµq`8`Kÿþ` ¾yJ$;|B 8j8ž|{8¥ÿìHµE`¡>q* @‚þÔ¡^U)8~Ûx})R±<B"Kÿýø8`ÿÿKÿþ‰>%(	A‚8(	@‚þ ˆ¾9ÿ|8~0y H`8`KÿýÜ9*èÁ|<xU'æ}[´|çPU)ö|!8A‚øÁð|!8@‚ÿøy) <àÿ})Ð8žxç ;@|ÁIj8`E9ÿì}´>;Áp°ap8a„“^±^øþ‘>H´e`9›^³^9A‚}	¦9 8à````B9
 Ê9J¡})2|çBBÿè}):eÛxy*„y) }*J£ëxy*„Äóx})R})Hø±>Kÿòyé!8`ù<ãxKÿüЈ¾9ÿ|8~0y H‘`8`KÿýX8`ÿÿN€ €```B(@Hûáÿøø!ÿQ|Ÿ#x¡$,	@‚´¡$,	@‚¨û=B®J-ˆ?‚®;œñp$|	P@‚øûaˆ|{x¡$(	A‚4(	@‚|¦øÀKÿíñ`8 8ŸH´`,#@‚Ô€¿,%A‚<€œ|	 @A‚€<ÀÌÌû!xûA€û¡˜ûÁ `ÆÌÍH``BAžà	9I}*0ÜBU)èþ;^€þ)
|(})PP‰ @y) @‚ÿÌ}B`;¨8 8‚ ¸£ëxH³á`|yy@‚„8Ÿ8 £ëxH²U`>,	@‚¤ë!xëA€ë¡˜ëÁ èÀ|¦H0`Bëaˆë8!°8`ÿÿëáÿøN€ ``B,*@‚Lëaˆë8!°8`ëáÿøN€ èÀë!xëA€ëaˆëë¡˜ëÁ |¦8`ÿÿ8!°ëáÿøN€ |¦û!xûA€;<û¡˜ûp8 *;ÿûÁ øÀƒÜƒ8€Þ;¾
;Þ¹êYò£ëxH±`Kÿì-`æûx8€|ex£ëxKÿî•`Kÿì
`= ƒœ<8 a)y)Æ|dxe)8za)}9ñ*H±
`“šäûx8 8zH°õ`“¤ëxcÛx8 *Kÿíí`ëp8`èÀë!xëA€ëaˆëë¡˜ëÁ 8!°|¦ëáÿøN€ ;ü<(¤ëx8 ãûxH°‘`è¼BäûxcÛxKÿí`û:ø8`Kÿÿ èÀëaˆë8`ÿÿ|¦Kÿþ˜ë8`ÿÿKÿþŒ8`ÿÿN€ €,$="®‰ñpM‚ |¦ûáÿøøø!ÿ= =Ey)Æap=@ÿ€e)ÔvyÆyJÆa)|x8 Tùp8€*8aŒùAxù!„H¯m`99A‚}	¦9 8à9
 Ê9J¡})2|çBBÿè}):8py*„y) }*Jãûxy*„8 p})R})Hø±!†Kÿíù8!ðèëáÿø|¦N€ €`B<b®€cñpN€ ``(@,ø!ÿ‘¡D(
ÑA‚¬AH(
DA‚Ð(
"@‚ˆ|¦8¥ÿø8d|¤´ø€H[A`è€8!p|ct|¦N€ `BmHÿÿ,€@‚H¡D,
5@‚<|¦8¥ÿø8d|¤´ø€H
u`è€8!p|ct|¦N€ ``B8`ÿÿ8!pN€ `B|¦|¥´ø€H05`è€8!p|ct|¦N€ ``B¡D,
C@‚ÿ¸|¦8¥ÿø8„|¥´ø€H ñ`è€8!p|¦N€ ``B8`ÿÿN€ €```B(L ¡#,	ÑL‚ |¦øø!ÿ‘|£+xH5Ý`8!pè|¦N€ €``B9 °ƒ°£°Ã±#N€ ```8`ÿÿN€ ```BN€ |¦ûaÿØûÿàû¡ÿèûÁÿðûáÿøøø!ÿa;`|½+x||x|Ÿ#x|¾+x‰?}]ðPäûxÃóxU'2}(t,À}JB8¨/¨.ªþ|¥´A‚\AžxA•´H¬±`‰?})t9)ÿJÞJ}]ðPäûx‰?ÃóxU'2}(t,À}JB8¨/¨.ªþ|¥´@‚ÿ¬ Ÿ;xŸ üúKÿÿd```B,;™A‚x8! cÛxèëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ ```B`£ëx8‚– ;`H§Ñ`8! cÛxèëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ 8! ;cÛxèëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ €``B|¦úáÿ¸ûÿÀ}€&û!ÿÈûAÿÐûaÿØûÿàû¡ÿèûÁÿðøûáÿø‘ø!ÿ!*|zx|ƒ#xøA(|œ#xH§U`x} ;ãA’d;`(:à09 (;(;½?¯;Þ9€½J{¥ 8€Ãóx;ÿHª‘`= 4}^ºa)9;*„ãx}>¹.±
#ËxWÿ>H¦¡`ƒãxH¦Õ`|ix|~Ú9)A’=@8 aJ8À5`¥€äûx}YI.;pKÿüý`8 8žøû€ƒãxHªe`HIÍ`èá€äûx8 |fxÃóxHJÁ`="®9)-€¥´ÄóxCÓxé)éIéi}I¦èIN€!èA(8!à聁êáÿ¸ëÿÀë!ÿÈëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦} N€ ```B;`:à9 ;Kÿþ ```B=@8 aJäûx`¥€8À5}YI.Kÿü`<⯀ç?p|˜ú8ÀT„>8 ÃóxKÿñ`Kÿÿ €	``B,%A‚="¯i?p8`N€ ``B|¦øø!ÿ‘8 <b¯8c?xH©	`8!p8`è|¦N€ €|¦úáÿ¸ûÿÀ}€&û!ÿÈûAÿÐûaÿØûÿàû¡ÿèûÁÿðøûáÿø‘ø!ÿ19 `?⯙%:■;ÿ@ˆ|ž#x|{x~ä»xãûx|¹+x|Ú3x?¢¯H¤U``Ãóx8‚ À;½9€H¦½`,#A‚`Ãóx8‚ ÈH¦¡`;Ã`Ãóx8‚ƒøpH¦…`,#A‚èpÃóxH¦m`;Ã`Ãóx8‚›˜øpH¦Q`,#A‚¤èpÃóxH¦9`|~PTx>`Ãóx8‚ ÐøpH¦`,#A‚LèpÃóxH¦`žPWœ>|À@@ÃxWœ>9<ÿÿU)>(	þA´…ãxÄóxãûxâH¤‘`9 ;~ä»xÃx™<H£%`ãûxH£Y`(#ÿA0úÁ€éûx;Ý	ÃxH0`B™AüH¤9`‰>ÿÿ|üú,	A‚T;Þ~ɳx‰^ÿÿ;þÿÿ;‡éøP}$KxWè>ƒãx(
.+ˆ?.ªÖóxåûxA‚ÿ¨A–ÿ¤}6KxKÿÿ¼``B=B¯J?p™',
A‚*A’8‘=9 =B¯;Ý ~ä»xÃóx™*Aœ)šH¢E`;€ÃóxH¢u`EÓx,#A‚$ÄóxcÛxKÿú¹Kþgµ`Kþf­`H4=,	A‚AŽ¤‰=,	A‚A’TKþg`,@cÛxKÿàÝ`‰=}?uA‚ÿ¼êÁ€;àH$```B`;à8b ØH½5`8!Ðãûx聁êáÿ¸ëÿÀë!ÿÈëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦}‘ } N€ ``BÃóxH¡}`T|>KÿýÀ```BÃóxH¡]`Tx>Kÿýh```BÃxcÛxKÿù™Kÿþà~ä»xÃxH é`êÁ€`;à8b ðH¼q`Kÿÿ<`B;œÿÿ{œ!@‚þ€`8€8b¡XH¼I`êÁ€Kÿÿ``B8#Ëx8 ;àH¤¡`êÁ€Kÿþè`;à8b¡H¼`êÁ€KÿþÌ`B8#Ëx8 ;àH¤a`êÁ€Kÿþ¨8 8€8}H£å`Kÿý¼€
```B¡#,	4A‚8`N€ ```Bû¡ÿèø!ÿQ9 a)€|}x¡CUH(|H@‚ÀqI@‚È|¦ûá¨û;ãûÁ øÀ¡#,	A‚Ä?‚¯;œB ;ÀH¡]|
H@¨äûx…ãx£ëxKÿöi9>}>´|y;ÿ@‚ÿÔ8`ÿÿèÀ끐ëÁ ëá¨8!°ë¡ÿè|¦N€ ë!xëA€ëaˆèÀ끐ëÁ ëá¨|¦```B8`8!°ë¡ÿèN€ 9 =B¯8`™*AœKÿÿä```B¡=,	A‚ÿ¨û!xûA€?"¯?‚¯ûaˆ?B¯?b¯;À;99€;œB ;{?ˆ;ZA H¡]9>}>´|
H@ÿTäûx…ãx£ëxKÿõq|yA‚С?,	@‚ÿÌdÛxƒãxHÑ`,#@‚4¡?(	A‚ˆ(	A‚`(	A‚8¡?9)
ÿJKÿÿˆ`BDÓxƒãxH‰`,#A‚ÿ¼KÿÿÔ`B?
=B¯8`‘*A˜ë!xëA€ëaˆKÿþˆ8Ÿ
8y8 H¡å`8`KÿÿØ`BEÓx8Ÿ
£ëxKÿô¥,#@‚ÿxë!xëA€ëaˆKÿþ<€```|¦úAÿúaÿ˜úÿ ú¡ÿ¨úÁÿ°úáÿ¸ûÿÀû!ÿÈûAÿÐûaÿØøûÿàû¡ÿèûÁÿðûáÿøø!ÿ!9 |}x`‘$:…|?x8b¡€`|ž#xzœ ;B¡¨`:¢¡Ø:ÀH¸•`="¯„´CÓx:àû©C H¸y`,<; A‚Ôé!|;x8 V8€ù!þ¡;!p#ËxH i`€þ#Ëx8À8 8€HKÿèM`8ÀC8 D8a„8€4Kÿó`²ÁŒšáŽ~¤«x8aøHœ]`KÿÛE`8 |dx8a¨H a`è~R ¡r$ËxKÿÞÝ`é!8 Ð8€ù;aÛxé!ù!ø1:ap;š~c›x;!¶HŸ¹`Kþa‘`Kþ`‰`è~R8À8 Ð~d›xKþ\!`,#A‚”9 ³³³9S}	¦9 8à9
 Ê9J¡})2|çBBÿè}):y*„y) }*Jy*„})R})HøU)>|H@‚4‰3,	@‚(¡3$,	D@‚¡3",	C@‚‰3*,	A‚\Kþ`Q`,AÿDé!;œÿÿCÓx{œ „´ù;aÛxH¶¥`,<@‚þ4`z„ 8b¡°:@ÿÿH¶…`H€KÿÙÉ`8 $ËxH Y`|ry@‚ÿŒ<b¯ècC ,#A‚Ãx8 ¸HžÁ`3>S:8“–8~@‘>‘^Hš`é!`8b¡àù;aÛxH¶`8?à~C“xèêAÿêaÿ˜êÿ ê¡ÿ¨êÁÿ°êáÿ¸ëÿÀë!ÿÈëAÿÐëaÿØëÿà|¦ë¡ÿèëÁÿðëáÿøN€ €`````|¦ûAÿÐûaÿØûÿàû¡ÿèûÁÿðûáÿøøø!ûa;e|#x{{ €„ ¥ÿþ|Ü3x|~xãØ®;Ap|¥"CÓxÿ(P{ÿ |Ÿ Påûx|ž"H­`‰<€}DÓxåûx|cJ|P|~H‰`€}ˆ¼8œ|P|~Hm`}>Ø®‰\})R}>Ù®‰\=})R‘=8! èëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ €û¡ÿèûáÿøø!ÿA(|#x@H|¦úÁpúáx;àû€û!ˆ;;%ûAûa˜;E;`û ûÁ°|¼+x|~xøÐ`B}>ø®}úI®}>ø®(	CAœ=Bÿÿ9J–y)d}*Jª})R})¦N€ l<ܬ|<ÌŒ```B9?9_y) þH®ÿR{ÿ ``B|ø@AþŒèÐêÁpêáxë€ë!ˆëAëa˜ë ëÁ°|¦8!À£úx|ctë¡ÿèëáÿøxcтN€ `B:ÿ8Ÿz÷ |ž"#Ëx|¾¸®HšÙ`}>¸®9_}<J›iþ¸®ÿR{ÿ Kÿÿt:ÿ8Ÿz÷ |ž"CÓx|¾¸®Hš™`}>¸®9_}<J›iþ¸®ÿR{ÿ Kÿÿ49?9_y) ‘þH®ÿR{ÿ Kÿÿ```B9?y* }P®9HÿÿUJ>(
A|™;ÿ{ÿ þø®})úy? KÿþÌ``B9?;ÿy* {ÿ }^P®™\þø®})úy? Kÿþœ``B9?9_y) ‘þH®ÿR{ÿ Kÿþp```B›9?9_y) ‘þH®ÿR{ÿ Kÿþ<``B›9?9_y) ‘þH®ÿR{ÿ Kÿþ``B›9?9_y) ‘þH®ÿR{ÿ KÿýÜ``B;ÿ{ÿ KÿýÈ`B(	ÒA‚ì@H(	ÿ@‚ý8`èÐêÁpêáxë€ë!ˆëAëa˜ë ëÁ°8!À|¦ë¡ÿèëáÿøN€ (	]A‚l(	Ñ@‚ýD:ÿ>¯z÷ |~¸®8cH¡`,#øvC¨A‚$|¾¸®8Ÿ|ž"H˜m`}>¸®éVC¨jI®}>¸®;ÿéú{ÿ Kÿý`B9_9?yJ y) ;ÿ}^P®}>H®{ÿ QI@.±<KÿüØ`B:ÿ>¯z÷ |~¸®8cH `,#øvC°A‚ÿ”|¾¸®8Ÿ;ÿ|ž"H—Ù`}>¸®éVC°jI®}>¸®éú{ÿ Kÿüx;àKÿü 8`KÿþÀ€
``BûÁÿðûáÿøø!ÿq9 5=¯<â¯=B¯?⯱(Dĉ#‰|~x9JC¨;ÿDÇ,)™DÆA‚94<â¯;ê"™'Dɱ
‰>2,	A‚9 2;ÿ±?ÿú>‘?ÿü‰>6,	A‚9 6;ÿ±?ÿú>‘?ÿü8Þÿ9 |È3x9@H`````BŒè9)ÿÿq)ÿÿ}GRUJ>@‚ÿì,*A‚L8à7™_|È3x9 ;ÿ˜ÿÿþ``BH9)ÿÿq)ÿÿ/Š9Hÿÿ}FPPAž™_;ÿ@‚ÿ܉>B,	@‚D‰>C,	@‚˜‰>],	A‚= ];ÿa)‘?ÿü9 ÿÿ8!™?ëÁÿðëáÿøN€ |¦9 B8ž|ƒ#xøpø ™?H’!`èp8£8T¥>˜¿H•å`‰?è |¦9)ÿJ‰>C,	A‚ÿp|¦9 C8ž|ƒ#xøpø ™?H‘Á`èp8£8T¥>˜¿H•…`‰?è |¦9)ÿJKÿÿ€``B|¦ûAÿÐûaÿØûÿàû¡ÿèûÁÿðûáÿøøø!ÿa|œ#x|x€„|½+x|Û3x,$A‚T9 H ``B}?P®}):y) |H@@0}H®9I8éyJ (ÿ/¨A‚D@žÿÐ}ISx|H@AÿØ;À|ýð®]ò,'A‚Ð(ÿA‚˜€|,#A‚T8 H}?@®})Zy% |(@@8}_(®99ey |P@+Šÿ.ªA‚àAž@–ÿÈ}Cx|(@AÿЈº|DÓx8¥H”9`<‰Z9)})R‘<H¬``B8! 8`èëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ `B;Þ{Þ |ð@Aÿ8! còx|ctèëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿøxcт|¦N€ ```B‘<KÿþÌ``BFÓx„ãxãûxKÿõe9>9^y) ÝH®ÞR{Þ Kÿÿ€€``B|¦ûaÿØûÿàû¡ÿèûÁÿðûáÿøøø!ûA8 H?¯8€;ÞC¸|xÃóx;€H’¥`=¯9@="¯)I¨?¢¯;ap³ˆCÔ=¯;½C¨™HCÖ=B¯‘*CØKÿ͝`8 |dx8}HH’¹`8 8€cÛxH’E`9 <‚³²8}8 8„å ™!„™!q™!v™!s™!ÍH’q`‰A„(
A9 })P6q)šA‚cÛxKÿú¹8}$8ÀC8 D8€4Kÿäµ`<¯€ÆI¬<àÿÿÃóx`çÿÿ8 xç 8€HKÿÙ­`Äóxãûx8 HKÿЉ`8!ÀèëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ €|¦ûáÿøøø!ÿH™á`|xH™Õ`8!€Wÿ€="¯èÿx“éI¨ëáÿø|¦N€ €```B|¦ûAÿÐûaÿØûÿàû¡ÿèûÁÿðûáÿøøø!ÿA9 |Ÿ#x?b¯`;{I°‘!pë_R8‚– |~x?¢¯cÛxø€;½C¨HŒé`聀;ƒãxHŒÕ`=B¯9 CÓxûÊK°=B¯;Àù*C°=B¯ù*C¨Kÿý‰9 =B¯™*K¸KþR9`KþQ1`CÓxKÿ˕`‰=+‰(	Až@@‚ü8`ÿÿ8!ÀèëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ ```B?,)A‚‘=?,)@‚ȉ?@,	@‚ЃãxHŒE`,#@‚à="¯)K¼,)A‚8‘!p=B¯JI¬‘?dÛx8@‘_H‹É`<â¯<¯8!À9 éC¨éFC°8`ù&C°ù'C¨ù@ù_HèëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ KþP‘`,AþÜ(A‚þô;ÀKÿþ¼=B¯‘*K¼‰?@,	A‚ÿ88Ÿ@cÛxH‹5`ƒãxH‹i`,#A‚ÿ(;ÁpƒãxÄóxKÿÀ­`,#A‚!pKÿÿ`BÅóx„ãxCÓx8ÀKÿæ!`,#@‚ÿ؁=,)@‚þä8`ÿüKÿþ\```B8`ÿýKÿþH€```B|¦ûÿàû¡ÿèûÁÿðûáÿøøø!ûQ8 H?¯8€;ÞC¸|xÃóx?¢¯HŽ`<¯8à=B¯JI¨99 °æCÔ<â¯;½C¨;p™CÖ=¯‘HCØ=B¯™*D@KÿÉ`8 |dx8}HHŽ!`="¯)I¬=B¯8 8€ƒãx‘*CàH`="¯)KÀ9@9<‚8}8 8„å ™A¦™„‘!pHÉ`‰A„(
A9 })P6q)šA‚ƒãxKÿö8}$8ÀC8 D8€4Kÿà
`<⯀çKÀ<¯€ÆI¬Ãóx8 8€HKÿÕ	`Äóxãûx8 HKÿËå`8!°èëÿàë¡ÿèëÁÿðëáÿø|¦N€ €|¦û!ÿÈûAÿÐûaÿØûáÿøøø!öñ|Ÿ#x;!ˆ|zx|»+x#Ëx8 8€HŒ‰`‰?,	@‚dû¡ø="¯)I¨?¢¯;½C¨_|
H@‚øûð?‚ûÁ	;ßì;œå Ãóx„ãx8 HŽ`,#@‚88 8€#ËxHŒ`8 „ãxÃóxHÕ`,#@‚ØûÐ;ÿ%ËxúáÈ{ ÃóxÃx{w Kÿï%,#A‚ ‰!,	@‚‰!œ,)A‚ä=B¯‰JK¸(
A‚¤(
8`ÿÿ@‚8(	A‚ (	@‚9 9@8`‘=‘=™]```BêáÈëÐëðë¡øëÁ	8!	èë!ÿÈëAÿÐëaÿØëáÿø|¦N€ êáÈëÐ`Bëðë¡øëÁ	8!	8`ÿÿèë!ÿÈëAÿÐëaÿØëáÿø|¦N€ _?;ß,Ãóx‘]‘=?ýܑ=H‡Q`,#A‚4ƒ,@‚(Äóx8 @8}Hˆ9`›H```B;ÿlãûxH‡	`,#@‚¼ëðë¡øëÁ	8!	9 =B¯èë!ÿÈëAÿÐëaÿØ8`ëáÿø™*K¸|¦N€ ```BúÁÀ:÷ÿ:ÁpÃxÄóx~óx’á HŠu`‰!(	A‚ä(	A‚œ(	A‚êÁÀ8`ÿÿKÿþˆ`B8À€8¿l8 8atKÿôá|c4,#A‚ÿÔ8 8€ƒÁ #ËxH‰±`8 „ãx~óxH‹m`,#@‚ÿ 8ž%Ëxx„ ~óxKÿìÍ,#A‚ÿ„êÁÀKÿý°``B8 ;ÁtÃóx8À€8¿lø°KÿôY聰,#A‚ÿLÃóx8À@8¿,Kÿô=|c4Kÿÿ\8À@8¿,8 8atKÿô!|c4Kÿÿ@`B(	A‚œ8`êáÈëÐëðë¡øëÁ	Kÿý”```B_?=¯;ß,?‚¯Ãóx‘HI¬‘<K¼H…1`,#A‚ƒœK¼,A‚H;ßlÃóxH…
`,#@‚ð9@=¯?ýܙHK¸=B¯‘*KÀ<b¯€cI¬KÿÎ]`<b¯ècK°,#A‚,¸AeÛxäûxHˆ•`‰!‰,	A‚4‰!‹,	A‚(€a”KÿÏ`€a˜KÿÏE````B‰!Ž,	A‚þð€a8 8€KÿÞù`8`KÿþØ``Bäûx8}8 €H…E`9 =B¯™*J0Kÿý(```BÄóx8}8 €H…`9 =B¯™*J0Kÿþô```B_!ˆ;Ý8 H8€Ãóx;`;!p‘]‘=H‡9`=9@³},;à™].‘=0KÿÂI`8 |dx8}HH‡e`8 8€#ËxH†ñ`9 8 88at™!„H‡5`8 8›á¢8apH‡`„ãx8 ›á¦›áq8}›áv›ás³a²³aA›á͛áÍH†é`‰A„(
A9 })P6q)šA‚#ËxKÿï18}$8ÀC8 D8€4KÿÙ-`<àÿÿ8À`çÿÿ8 xç 8€HÃóxKÿÎ)`ÄóxCÓx8 HKÿÅ`9 =B¯8`™*K¸Kÿúœ``B‹Áʁ!ˆ_,‘‘=‘]@‚à‰!›Ý9)ÿþU)>(	@,*A‚Ô‹ÁË,@‚”‰!=B¯›ÊI°q)ý,	A‚;ŸlƒãxH‚`,#@‚´9 =B¯™*K¸Kÿýë¡øKÿúH``BÄóx8 @8}H‚Õ`›HKÿü¤`Bäûx8 ¸H…‰`Kÿüô```B8}8žHI`Kÿÿ```B8ž8}H)`Kÿÿ48 @8Ÿ,8}H‚a`›ÝHKÿÿ„ãx8 €8}H‚E`›ÝˆKÿÿ8€
``ûáÿøø!ÿ="¯|Ÿ#xè©KÊ}% P})¦p,	@p|¦="¯)KÌûÁð`;¡ð,	øA‚ŒäVtÃóxHœ!`è="¯ëÁð8!9@=¯“éKÈëáÿø9 |¦‘HKÌ=B‘*å(N€ =")å(q*ÿA‚ÿˆ,#@‚ÿ€8!9)y) =Bëáÿø‘*å(N€ ```Bû¡è;¡p|¥Vt£ëxÄóxH]`‰Ap©ëx9,
A‚™	I,
@‚ÿô`¤ëx8b¤PH›U`ë¡èKÿÿ €``B|¦ûAÿÐûaÿØûÿàû¡ÿèûÁÿðûáÿøøø!ÿa?b¯|~x;{KÐ|#xøA(|¿+xcÛx8 8€Hƒ	`="¯?‚¯;œKÈé)LÒ,	A‚¼,	@‚äH"±`èü8 8€;œ0;@4|fxcÛx8ç H#™`æûxƒãx8 Ñ8€KÿՁ`9@³¼
="®9)-€EÓxdÛxÃóx±\é)éIéi}I¦èIN€!èA(8! èëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ `B="¯é)LØ8À8 8€ cÛx;œ;@ €éKÿÊ
`KÿÿTæûx8 Ñ8€8`KÿÔÑ`9 ±)à€|¦úÁÿ°úáÿ¸ûÿÀû!ÿÈûAÿÐûaÿØûÿàû¡ÿèûÁÿðûáÿøøø!ÿ!8 ?b¯||x`¡"¢`B¢;{KÐ8€øA(cÛx?¯;ÞKȱ!t‘ApHa`="¯é)LÒ,	A‚l,	<b¯ècLØ8c@@‚èH}µ`;p`;"¢;^|xÃxH}•`:þ0|ix#ËxÿJH}}`|dxCÓxÿ"H}i`ÿH ­`èþ8Ÿ;¿6T„>8 |fxcÛx8ç ½´H!‘`<b¯ècLØ;×
8c@H}`|xÃxH}	`|dx#Ëxÿ"H|õ`Wÿ>;ÿ|vxCÓxH|Ý`|Ÿ²8ÀE8 Ñ|„~ã»xT„>KÿÓ`9 <‚¯è„Lر78„@|ƒ#xø€H|™`聀8£ÃóxH€e`<b¯ècLØ8c@H|q`|ixÃx9)ÞJH|Y`Ãx8£ÃóxH€%`ÃxH|9`|ix#Ëx9)ÞJH|!`$Ëx8£ÃóxHí`#ËxH|`|ixCÓx9)ÞJH{é`DÓx|exÃóx8¥H±`="®9)-€¥ëxdÛxƒãxé)éIéi}I¦èIN€!èA(8!àèêÁÿ°êáÿ¸ëÿÀë!ÿÈëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ >¯;p`;^èvLØ;"¢:þ8c@H{A`|xÃxH{1`|}x#ËxH{!`ÿê;ÿ"|}xCÓxH{	`é6LØ¿ê8À8 ½cÛx€éW¤>½´KÿÆ]`Kÿý¬HzÑ`|x8apHzÁ`|ix`8b¢ÿJHz©`Wÿ>|dx8~|ž#xHz‘`8Ÿ8ÀE|„ò8 Ñ|„8`T„>KÿÐÍ`9 ±)à€
```Bû¡ÿèø!ÿa="é)å0,)ÿÿA‚¼|¦="¯ûÁû€|ž#x||xûApûá˜è‰Lê8`|¿+x?B¯;ZKÈø°KÿøáKþ?M`Kþ>E`©>£¾=B¯(	³ªLìA‚¸(	A‚U*>,
A‚¤(	@‚\¡Z,¡>
8ê}$´|HA‚dmHÿÿ,ÿÿA‚˜|
H@A‚¬="¯é)M@´I; 9J‘IëApè°ë€ëÁëá˜8! £ëxë¡ÿè|¦N€ ``B°ú,="¯é)M8à=B¯=¯MéJLêé ¾}%R9)ÿô|	@Al<bècå08¥ÿô8ž|¥´|cRH|Á`<¢¯ ¥L젞
ƒãxKÿøù=B¯¡JLî¡<¯€æLè9J9(ÿô|
@}):‘&Lè@€¡Z,mIÿÿ,	ÿÿA‚0è°ëAp끀ëÁëá˜|¦8! ; £ëxë¡ÿèN€ ```BéZ8; *9)‘*KÿþÜ``B9 ¥ëxƒãx8€±:&; KÿøIKÿþ´{å ;þ
ûaxÞ*|?ð@@€À`;b¢HL```Bãûx8€HvÉ`,#A‚¼8c8€Hv±`,#A‚¤;ã|?ð@@€˜cÛxHw¡`dÛx8£ãûxH|Ý`|}y@‚ÿ cÛxHwy`8 
8€8c|H€`=B¯Tc>9#ÿÿU)>°jLî(	“A<¢¯ ¥Lìƒãx8€Kÿ÷]ëApëaxKÿýÄ```BøA(?¢¯£½Lì9 =B¯±*Lî;ú8 ãûx8€Hzi`="¯é)LÒ,	A‚H,	@‚¨H`èú8 8€
;Ú0;`5|fxãûx8ç H`¦ëx8 Ñ8€
ÃóxKÿÌé`= 9=B®9J-€a)eÛx™äûxƒãx‘>é*; ÿøéIéi}I¦èIN€!èA(9 ÿøëax‘:(```B9 =B¯‘*MKÿü´øA(¡>
U*>(
Að=Bÿÿ9J¸Ðy)¨}*Jª})R})¦N€ и¤Ð|ÐhøA(é9@ÿÖ=¯; ÿ֑HLð¡^
‘IKÿÿ€```B9 ÿþ=B¯øA(; ÿþ‘*LðKÿÿ\9 ÿù=B¯; ÿù‘*LðKÿÿH9 ÿú=B¯; ÿú‘*LðKÿÿ49 ÿû=B¯; ÿû‘*LðKÿÿ 9 ÿü=B¯; ÿü‘*LðKÿÿ9 ÿý=B¯; ÿý‘*LðKÿþø`B9 ÿÿ=B¯; ÿÿ‘*LðKÿþà```B0,A‚ûd(	Aû\±:,Kÿû¬¥ëxƒãxKÿôý=¯éM<â¯; GLü(9J9)‘GLü‘(Kÿû@9 ; ‘:DKÿû0="¯é)LØ8À8 8€!ãûx;Ú;`!€éKÿ¿é`Kÿýȁ:0,	@‚ûÌ9 ÿ÷øA(; ÿ÷‘:(Kÿþ øA(Kÿý4øA(?¢¯£½LìKÿý0¦ëx8 Ñ8€
8`KÿÊu`9 ±)à€`B9 =B¯ cÿö‘*M="¯iLðN€ ``B|¦ûÿàû¡ÿèûÁÿðûáÿøøø!ÿq9 ?‚¯9@ƒãTù'8ÿÿ9`ÿÿø|LØ<b¯=¯|#x`£M<¢¯øèM8à9<b¯ÅM<¯8 ”8‚¥¸8cLà“æLÐ<¯?â¯`;ÿKȑ&Lè<¯;¢(‘&M<¯‘&Lü<¯‘&KÈ="¯‘ILð="¯±ILô="¯°	Lì="¯‘iKÌ="¯éLø="¯±	LîHƒ``8b¢HŽ5`8€8`ÿÿKÿñµ="û©å0Kþ8`Kþ7`é<LØèiRKÿôQH<``Bé?èiRKÿ±Y`é_8?H
|H@A¬J|
H@A¤?D,	@‚(Kþ75`,Aÿ¸é_8 ¿$*|¨4(	@°,ÿÿA‚° Ÿ,(@é?T¥>èiRKÿò=é_8*9)‘*Kþ7Y`Kþ6Q`é?èiRKÿ°±`é_8?H
|H@@ÿ\9@ÿØ8!9 ÿÿ8`ÿؑ_(=Bù*å0èëÿàë¡ÿèëÁÿðëáÿø|¦N€ ```B,ÿÿ@‚ÿ|¡,,@‚ÿpU(¾,@‚ÿdÃóxHŒ½`é?èiRKÿòýé_8*Kÿÿ@```Bè*9 ÿÿ=Bù*å0,#@‚4èŸ"8`ÿÿKÿð`8b©HŒe`èŸ6,$@‚t="¯èiLê8!èëÿàë¡ÿèëÁÿðëáÿø|¦N€ ``B9@ÿ×8!9 ÿÿ8`ÿב_(=Bù*å0èëÿàë¡ÿèëÁÿðëáÿø|¦N€ ``B`8b¢PH‹Ù`Kÿÿ€€|¦û!ÿÈûAÿÐûaÿØûÿàû¡ÿèûÁÿðûáÿøøø!þA|}x|ã;x|þ;x|œ#x|»+x|Ú3xH|‘`|yA‚<Åóx¤ëxHq``8 8‚¢˜ãûxHpa`|yy@‚ä8€[ãûxHnÉ`|~yA‚‰>,	[A‚8€.ãûxHn¥`|~yA‚8€.8~Hn`,#A‚ Ãóx8€/Hnu`|~yA‚¸9?9û€}IðP;¡p}J´}$Kx£ëx;p}	Q®Ho
`¤ëxCÓxÃx8ÀKÿÊ5`,#A‚Ãx„ãxH=`8žcÛxHnÍ`ãûxH`ë€8!À#Ëxèë!ÿÈëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ `B8€]Hm­`,#A‚¾P8€/Ãóx½´Hm`|zyA‚Ð>鮄ãx8~HA`,#A‚,8šcÛxHn)`ãûxH~]`8!À#Ëxèë!ÿÈëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ `B`; ÿÿ8b£PH‰u`ë€Kÿÿ`B`äûx8b¢ ; ÿÿH‰Q`ãûxH}å`Kÿþè`; ÿÿ8b¢hH‰-`KÿþÐ`äûx8b¢Ð; ÿÿH‰`ãûxH}¥`Kÿþ¨`äûx8b£; ÿÿHˆé`ãûxH}}`Kÿþ€`äûx8b£8; ÿÿHˆÁ`ãûxH}U`KÿþX`äûx8b¢ð; ÿÿHˆ™`ãûxH}-`Kÿþ0`äûx8b¢¸; ÿÿHˆq`ãûxH}`Kÿþ€```Bûáÿøø!ÿ,ÿÿ|ß3x|è;xA‚8,ÿþA‚D,ÿýA‚ì,ÿüA‚,ÿûA‚l,ÿúA‚H,ÿùA‚$,ÿøA‚¨,ÿ÷A‚„9E(
@0,ÿØ|‰#xA‚˜,ÿ×A‚D,ÿÖA‚Ô8!€|£+xëáÿøN€ |¦8¥ûÁp(øAü=Bÿÿ9J”x¥ˆ}**ª})R})¦N€ |pdX`8¢£à9 0?¯;ÞM`‘(Ãóx8‚¥H|`ûß8 ÿ—èëÁp|¦Kÿÿh`8¢£€Kÿÿ¼`8¢£Kÿÿ°`8¢£¨Kÿÿ¤`8¢£ÀKÿÿ˜`9@09"£ø8 ÿ™‘Gù&Kÿÿ`9@09"¤¨8 ÿ‘Gù&Kÿÿ`9@09"¤ˆ8 ÿ‘‘Gù&Kÿþä`9@09"¤p8 ÿ’‘Gù&KÿþÈ`9@09"¤X8 ÿ“‘Gù&Kÿþ¬`9@09"¤è8 ÿ‹‘Gù&Kÿþ`9@09"¤À8 ÿŒ‘Gù&Kÿþt|¦9 0	ûÁp?¯`;ÞM8Ã@8¢¤@Ãóx8€Pø‘'H•Á`ûß8 ÿ”èëÁp|¦Kÿþ$|¦9 0ûÁp=B¯?¯;ÞM`èÊM
8ã@8¢¤Ãóxø‘(8€PH•i`ûß8 ÿ˜èëÁp|¦KÿýÌ|¦9@0ûÁp?¯`;ÞM8‚¥XÃóxø‘G€©Hz-`ûß8 ÿŽèëÁp|¦Kÿý€|¦9@0ûÁp?¯`;ÞM8‚¥ Ãóxø‘G€©Hyá`ûß8 ÿèëÁp|¦Kÿý4|¦9@0ûÁp?¯`;ÞM8‚¥ˆÃóxø‘G€©€ÉHy‘`ûß8 ÿèëÁp|¦Kÿüä`8¢£hKÿý8€``````ûáÿøø!ÿA?â¯ëÿMh,?A‚Ä|¦ûa˜û ;apû¡¨ûÁ°|}x|œ#x;Á€øÐH```Bëÿ8,?A‚hé_é8 dÛxû¡pÃóxûxù^ù~Hmá`,#@‚ÿÄèÐëa˜ë ë¡¨8`ëÁ°8!À|¦ëáÿøN€ ``BèÐëa˜ë ë¡¨ëÁ°|¦8!À8`ëáÿøN€ €```B|¦ûÿàû¡ÿèûÁÿðûáÿøøø!ÿA||x;Áp|½+x|Ÿ#xÃóx„ãx8 (Hk¹`,=‰\9 ‘!p™!v™AwA‚Ä;½ÿÿ9@{½øb9=})¦````B‰‰?;ÿQ	@.})´}JJBÿè¤þ}ISx9@
9}I¦H ```B Þ ê;Þ}29^}):Bÿè8!À})By#„y) è}#Jëÿàë¡ÿèëÁÿðy#„ëáÿø|cJ|¦|cøTc>N€ 9@Kÿÿ|€|¦û!ÿÈûAÿÐû¡ÿèûáÿøøø!ÿ!;!|¿+x|š#x|}x8„#Ëx8 Hj‰`9?()îA4ûa¸ûÀ?‚¯8 ûÁÐ;œMh;ÁpÄóx8a€é\é|;z(é:éùApùaxù!ˆù€Hk`9:,#A‚‰:(	A‚$(	:A‚˜‰!,	ÿA‚l="¯é)Mh,)A‚,éHé)8,)A‚éI|*@@‚ÿìèaè˜û H#-`|xyA‚;|8 dÛxÃxHk
`,#@‚Ð8 dÛxcÛxHjñ`,#@‚؁8~Ûx,	@‚È$Ëx£ëxHÙ`Kÿ¤!`8€Æóx`„†Ý|ex8x(Kÿ¦…`åûxDÓx8x6Hi!`“øKþ*•`Kþ)`HKþ*`,@@£ëxKÿ£Ý`‰8,	@‚ÿÜë ëa¸ëÀëÁÐãûxHŒèzèšH ¹`|~yA‚\?b¯;{Mp|>ØA‚LKÿ£i`;|(8€Æóx`„†Ý|excÛxKÿ¥É`åûxDÓx8|6Hhe`8¿dÛx|¥´£ëxKÿ¥]`ëa¸ëÀëÁÐ8!àèë!ÿÈëAÿÐë¡ÿèëáÿø|¦N€ ``B<‚¯è„Mˆ}#Kx8 Hh`‰:(	@‚ýä ºdÛxCÓxKÿûñ,#A‚°z.KÿýÌ```B8 dÛxÃxHi%`,#A‚$ë Kÿÿ```B9 338 8œ8ar±!pHg}`KÿþÜ ºdÛxCÓxKÿûu°z*KÿýX``Bëa¸ëÀëÁÐ8`ÿÿ8!àèë!ÿÈëAÿÐë¡ÿèëáÿø|¦N€ 8` Ho­`|xyA‚t8  8€Hf¥`8 $Ëx8xHfñ`9 Ãx±8H-`?b¯;{MpKÿý@``B9 ÿÿ±:.Kÿü´ë ëa¸ëÀëÁÐ8`Kÿþhë ëa¸ëÀëÁÐ8`ÿÿKÿÿH8,	A‚ýë KÿýÔ€`BûÁÿðø!ÿ1|~xˆc,#A‚”|¦úáˆû:àû!˜ûA ? ;ÿþûa¨û¡¸;ap; û°ûáÈ;DÿÿøàHt`BÞúAüáúHc%`8 8€šÿpcÛxHlM`|È@|i´})Fp@€È}8é®|z鮈~(:@‚ˆ~;Þ,#A‚ä;½(=A‚˜Hiµ`8€:|ixÃóx,)A‚|H`‰`Äóx||ycÛxþàPÿ4+Ÿ{ÿ åûx@‚ÿP8 Hby`cÛx›tHaY`8 8€ÞcÛxHk‘`|È@|i´})FpA€ÿH``B8`èàêáˆëë!˜ëA ëa¨ë°ë¡¸ëáÈ|¦8!ÐëÁÿðN€ ``B£´KÿÿÀ8`Kÿÿà€	`Bûáÿøø!ÿ|x‰#,	ÿ@‚L="¯é)Mh,)A‚ì="¯é)S€ûé89@="¯8!€ù_8ûéS€9 }#KxëáÿøN€ ``B|¦8`@ûÁpøHlÁ`9 |~yA‚ 8 @8€Hcµ`= =@ÿa)ÿyJÆy)ƒäù^ù>`Bè~‰?
™>
‰?™>‰?™>`BèžKÿöÙ,#@‚`ÃóxKÿÿ="¯é)MhèëÁp|¦,)@‚ÿ$``B="¯ûéMhKÿÿ`BèëÁp8!€}#Kxëáÿø|¦N€ `BèëÁp|¦KÿþÌ€`B|¦û¡ÿèûÁÿð}€&ûáÿøø‘ø!ÿa|x8`@|#xHk¥`|~yA‚°.=8 @8€Hb™`="¯ûÉMˆA’¸¤ëxÃóx8 HbÙ`?¯ëÞMˆ,>A‚ è~èžKÿõÉ,#@‚ÃóxKÿþ	< ÿ<b¯<â®8ç-€x¥Æ<‚¯9@<Âÿÿø£S<¢¯‰$Sˆ8Ævx=¯?¯ùES˜9Mh9@øÇU)~<â¯;ÞS™$Sˆèh(ùGMx<â¯èˆ0ùGM€KÿõI,#@‚ÃóxKÿý‰HU`ãûx;ÀH5`Hm`,#@‚XKþ#}`Kþ"u`H``BKþ"á`,@ ãûxKÿœ½`H%`,#A‚ÿØ9>ÿÿy>!@‚ÿ @’P="¯é)Mh,)A‚@=þ€yÆ```B‰I,
ÿA‚éIyJD|*@@‚´é)8,)@‚ÿÜ8! èë¡ÿèëÁÿðëáÿø|¦} N€ `Bû€Kÿ›ý`?‚¯ëœMˆ= þ€;Áxy)Æ8 |dx|}xù<ÃóxH`ý`88 8a}H`é`9 ÿþÄóx8 8ap±!{H`Í`é!pù<끀Kÿýè=B¯ù*MˆKÿÿT€```B<b¯ècMˆN€ ``B|¦û¡ÿèûÁÿðûáÿøøø!ÿq|Ÿ#x|}xèdè„ |¾+xKÿóU,#A‚ ('@‰?(	A‚h(	:A‚08!8`ÿÿèë¡ÿèëÁÿðëáÿø|¦N€ ```Båûx8Ÿÿ<£ëxHå`8!èë¡ÿèëÁÿðëáÿø|¦N€  ¿8Ÿ(£ëxKÿ°•`8!èë¡ÿèëÁÿðëáÿø|¦N€ €`B|¦ûÁÿðûáÿøøø!ÿ=@`9 ÿÿ|þ;x‘C°ƒ|x|Ä3x™#˜£8 8cH_A`Äóx88 H_-`8!€èëÁÿðëáÿø|¦N€ €|¦ûÁÿðûáÿøøø!ÿq8 ;áx|~xÄóxãûxH^Ù`8ž8 8a}H^Å`9 ÿþäûx8 8ap±!{H^©`èap8!èëÁÿðëáÿø|¦N€ €``B|¦û¡ÿèûÁÿðûáÿøøø!ÿQ= þ€y)Æ;Áxøa€|Ÿ#x|}xù$8 |dxÃóxH^1`88 8a}H^`9 ÿþÄóx8 8ap±!{H^`é!p8!°ù?èë¡ÿèëÁÿðëáÿø|¦N€ €``B="¯é)Mh,)A‚4éH``Bé)8,)A‚éI|*@@‚ÿì8`N€ 8`N€ ```B|¦ûáÿøøø!ÿ8`(HeÝ`|yA‚8 (8€H\Õ`8!€ãûxèëáÿø|¦N€ €``B|¦ûáÿøøø!ÿaøaÐ8`@øØHeu`|yA‚¬8 @8€û€û¡ˆûÁH\a`8 8Ðãûx;¡xH\©`Kÿ—q`8 ;Áp||x£ëx„ãxH\…`8œ8 8a}H\q`9 ÿþ¤ëxÃóx8 ±!{H\U`Äóx8 8H\A`끀롈ëÁ8! ãûxèëáÿø|¦N€ €``Bûáÿøø!ÿ|yA‚L|¦øèèŸKÿîñ,#@‚(è8!€ãûxëáÿø|¦Kÿ÷ ```Bè|¦8!€8`ëáÿøN€ €```B|¦øø!ÿ‘øa ø¨8a 8°ø¡°8 øÁ¸H\É`8!pè|c4TcÙ~|¦N€ €```B|¦ûaÿØûÿàûáÿøøø!ÿ18 ||x|›#x|ƒ#x8€HZ•`ƒãx8€:HUõ`|iyA‚Ðû¡¸ûÁÀ; ;ÀH,)}^´A‚D8i8€:}?KxHU¹`9^ÿP|ix,?@‚ÿÐ,);Þÿÿ;½Þ´½´@‚ÿÄ,A`A‚,@‚T`ƒãx8‚¥ÀHXµ`|yA‚`ƒãx8‚¥ÈHU™`,#A‚$|¼øPT¾>(@<``B롸ëÁÀ;à8!ÐãûxèëaÿØëÿàëáÿø|¦N€ `BûA ;ApÅóx„ãxCÓxHVý`Áò9 ;¡8™>p¤ëxKÿóM|yA‚4 åûx|c´¤ëx|{HY`¤ëxCÓxKÿó|ey@‚„ëA Kÿÿ\``B,AÿL,ÿÿA‚ÿD`ƒãx8‚¥ÀHW¥`|y@‚þô롸ëÁÀ8!ÐdÛxƒãxèëaÿØëÿàëáÿø|¦Kÿò¬9 ;à™;롸ëÁÀKÿþð¤ëxcÛxHXé`ëA ë¡¸ëÁÀKÿþЀ`B|¦ûÿÀû!ÿÈûAÿÐûaÿØûÿàû¡ÿèûÁÿðûáÿøøø!ÿQ9 ````™$|#x|~x;à;c;"¥è;B¥à;¥Ð;‚ ÐH@``BDÓx£ëxHd™`(?„ãx;ÿ£ëxA‚HRÍ`(?A‚`}>ø®|Ûø®,)/¦@‚,¥ëx@žÿ´$Ëx£ëxHR™`Kÿÿ°```B|Ç3x¥ëx}&KxÃx£ëxHd`Kÿÿ„`¾ëx;‚¥ð`B„ãxÃóxHV	`/£}>P})µ|x}>JAžÔ;ÃA‚‰)ÿÿ,	:@‚ÿÈ}=øP9@})´,)}]I®@‚à`£ëx8‚¥ÀHQñ`‰?;ÿ,	A‚D`;Â¥øH```B?,	A‚ 8 ÄóxãûxHS™`,#A‚ÿÜäûx£ëxHQ‘``£ëx8‚¦HR=`,#@‚`£ëx8‚¥ÀHR¡`8!°èëÿÀë!ÿÈëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ ``B`£ëx8‚ ÐHQ`Kÿÿ$€```|¦û¡ÿèûÁÿðûáÿøøø!ù8 î|~x8€8ap?¢¯HUÅ`Kÿõ`;½SÐ;á~§ëx8 |fx8€*ãûxKÿöy`8À#8a¦8 "8€*Kÿ¨a`9 8@8 8a¯™!®HUÅ`= 9A²a)
y)Æe)a)ù*Kÿq`8 |dx8aºHU`=@= aJa)yJÆy)ÆeJe)aJa);äûxÃóx8 RùAÀù!ÈKÿê‰`8!€èë¡ÿèëÁÿðëáÿø|¦N€ €``B|¦øø!ÿ‘H]5`="¯˜iTH]%`="¯˜iTH]`8!p="¯è˜iT|¦N€ €``B|¦û¡ÿèûÁÿðûáÿøøø!ÿq=@ÿyJÆ=¯ëäR= ?ÂùHSÐ=B¯a); øŠT=B¯ãûx;Þå8ù*SØKÿþ
9 =B‘*å8KþÍ`KþÅ`ãûxKÿ)`>/©(	AžT@‚08!8`ÿÿèë¡ÿèëÁÿðëáÿø|¦N€ ```BKþñ`,Aÿ¨(A‚ÿÀ; Kÿÿˆ8!8`èë¡ÿèëÁÿðëáÿø|¦N€ €`B|¦ûaÿØûÁÿðûáÿøøø!þA8 |ž#x<‚¯|x8„T8c?b¯HTÝ`;{SÐ,#@‚<û!ˆûA‰?,	@‚="iå8;Þÿü;ÿ,;ApÞ´; @œû û¡¨H`B,@|‰? ¿üûx+‰ÅðP(	;;¾ÿü9%¾´ÿJAž€@‚ÿÌ8œCÓxHP` üè›HCÓxèÄR}!:8¤@8„ ›)pKÿÞi`,ÿÿ@‚ÿŒ``B끠롨ë!ˆëA8!À8`èëaÿØëÁÿðëáÿø|¦N€ è{H8œ8 øp8c0HRM`èp8 8`Kÿ¨ù`Kÿÿ ```B8!À<`ÿÿèëaÿØëÁÿðëáÿø`cÿÿxc |¦N€ €```|¦ûÁÿðûáÿøøø!ÿa|~x8`îHZU`|yA‚Ø=@ÿ9 øA(û¡ˆyJÆ;¿ù!xùApKÿñ`8áp8 :8€|fx£ëxKÿñù`9@…9 ±_6±?>KÿŒ1`8 |dx8@HQM`="®9)-€¤ëx8 8Ãóxé)éIéi}I¦èIN€!èA(ãûxH]1`롈8! èëÁÿðëáÿø|¦N€ ```B<b8cæP`8‚¦Hh`8! èëÁÿðëáÿø|¦N€ €`B="¯èiT"N€ ``B|¦û¡ÿèûÁÿðûáÿøøø!ÿa|}x8`î|ž#xHXí`|yA‚8 î8€øA(û€HOÝ`<à‰^
¡>=ÿ`çÿyÆxçƒä;Ÿùpøáx™A}±!~Kÿïu`8áp8 :8€ |fxƒãxKÿði`9 ‡Äóx8 8>±?6HOÍ`9 ±?NKÿŠ`8 |dx8PHO©`="®9)-€„ãx8 H£ëxé)éIéi}I¦èIN€!èA(ãûxH[`끀8! èë¡ÿèëÁÿðëáÿø|¦N€ `B<b8cæP`8‚¦8Hfa`8! èë¡ÿèëÁÿðëáÿø|¦N€ €|¦ûaÿØûÿàû¡ÿèûÁÿðûáÿøøø!ù;…;¡x|¾+x|Ÿ#x8 „ãx|{x£ëxHNÁ`8Ÿ8 8apHN­`‰>((	‡A‚<(	ˆA‚T(	†8`ÿÿA‚x8!ðèëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ 8`îHVí`|yA‚ øA(Kÿí¹`;Ÿ§ëx;ß>8 :|fx8€ ƒãxKÿî¥`¤ëx8 Ãóx;¿PHN
`9 ±?NKÿˆÍ`8 |dx£ëxHMé`‰?:9ˆ9@8 8€±6±_NÃóxU)þa)`™?:HMU`Kÿí`8 |dxÃóxHM™`Kÿˆa`8 |dx£ëxHM}`="®9)-€„ãx8 HcÛxé)éIéi}I¦èIN€!èA(ãûxHYa`8!ð8`èëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ `B¦˜`¡"¦œè~èž‘A°±!´H1`|}yA‚Ô¡>.=¯9Sˆ;þ8‘=ˆè>0‘=>4‘= ¡>‰^-9)ÿðPê¾,)}>´™H@àûAÀ?@þ€;a{ZÆ``B‰_(
A‚ø(
@‚8 8ŸcÛxHLa`é!y)D|)ÐA‚l_?|
H@A\è{è›Kÿï1`||yA‚DKÿîa`,#A‚4Kÿî±`|dyA‚$8 (8|HKù`ƒãxKÿïí``B‰_UI8yJh})ðPÿR,	}>´AÿDëAÀ8!ð9 =B¯èëaÿØëÿàë¡ÿè8`ëÁÿðëáÿø‘*T |¦N€ ``B8Ÿ8 £ëxHKu`‰_UI8yJh})ðPÿR,	}>´AþÐKÿÿŒ``B9>(;¾ÿòûÁ˜„ãx8 8a°ù! û¡HK!`èa°è¸H`|yA‚T聐8 8„HJõ`?9@™_,	@‚\8`8!ðèëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ £ëx8Hy`,#A‚ÿÄHé`8`Kÿÿ¸``B;ß(8 äûxÃóxHJq`€¿ÄóxcÛx8¥|¥´Kÿ‡e`9 8`‘?Kÿÿl```B<b8cæP`8‚¦hHaQ`8`Kÿûèžè¾8a°H¥`|}xH`Kÿý€|iyA‚\=B¯éJT(,*A‚,<â¯9@8`éT0ù'T0ù((ùI(N€ ``B=¯ùI(8`ù(T(=¯ù(T0N€ `B8`ÿÿN€ ```B|¦ûÁÿðûáÿøøø!ÿq|~x8`0øÈø¡ÐHQÍ`|yA‚H8 08€û¡xHHÁ`;¡ÈÄóx8 ãûxHI	`¤ëx8 8HHõ`ë¡x8!ãûxèëÁÿðëáÿø|¦N€ €ûáÿøø!ÿq?â¯ëÿT(,?A‚Œ|¦û¡xûÁ€|}x|ž#xø H```Bëÿ(,?A‚Hè蟥ëxÆóxKÿìå`,#A‚ÿØè ë¡xëÁ€8!ãûxëáÿø|¦N€ `Bè ë¡xëÁ€|¦8!;àãûxëáÿøN€ €=¯éT(,(A‚0}	CxH``Bé)(,)A‚éI|*@‚ÿì}(Kx}CxN€ |iyA‚\=B¯éJT8,*A‚,<â¯9@8`éT@ù'T@ù( ùI N€ ``B=¯ùI 8`ù(T8=¯ù(T@N€ `B8`ÿÿN€ ```B|¦ûÁÿðûáÿøøø!ÿ8` |ž#xHO¥`|yA‚L8  8€HF`èž8 ãûx8„HFå`èž8 88„HFÍ`9 ™?8!€ãûxèëÁÿðëáÿø|¦N€ €`Bûáÿøø!ÿq?â¯ëÿT8,?A‚Œ|¦û¡xûÁ€|}x|ž#xø H```Bëÿ ,?A‚Hè蟥ëxÆóxKÿêµ`,#A‚ÿØè ë¡xëÁ€8!ãûxëáÿø|¦N€ `Bè ë¡xëÁ€|¦8!;àãûxëáÿøN€ €9 =B¯ù*T(=B¯ù*T0=B¯ù*T8=B¯ù*T@N€ ```|¦ú¡ÿ¨úÁÿ°úáÿ¸ûÿÀû!ÿÈûAÿÐûaÿØûÿàû¡ÿèûÁÿðøûáÿøø!ÿ1;À="¯?b¯>â¯`ëéTJ``|yx;{TH:÷TP;¦ ;B¦¨:À:¢¦¸H``BHQa`ë›äûx8 8`Ký°)`ãûx; HA	`8 |dx8`Ký°`CÓxH@é`EÓx|dx8`Ký¯å`8 8€8`Ký¯Ñ`|y8A‚@HM`8 8€|}y8`A‚äKý¯¡`åûx|dx£ëxHD]`~Ýù®é;{œ&ä;Þ›â/ž
Þ´û¼y*&ä9)}[R}?´éJ,*A‚L‘;AžD,#{ÿ&ä÷ú/¾Æóx%ËxÃxãûxA @žþÜ$ËxãûxH?Á`KÿþÐ`B8!Ðèê¡ÿ¨êÁÿ°êáÿ¸ëÿÀë!ÿÈëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ `B~£«xH[m`Kÿÿ4€`B|¦û¡ÿèûÁÿðûáÿøøø!ÿqKþ9```;â¦Ø;¢ƒØ|~xHD``BH?Q`åûx|dx8`Ký®M`8 8€8`Ký®9`,@‚<KþÙ`|ixãûx}>HP(		@ÿ°8!èë¡ÿèëÁÿðëáÿø|¦N€ £ëxH>Ý`¥ëx|dx8`Ký­Ù`8 8€8`Ký­Å`Kþm`|~xKÿÿˆ€|¦ûáÿøøø!ÿq`?â¯8b¦à;ÿTHKÿüÁ`8b¦èKÿüµ`8b¦ðKÿü©="¯)TH,	A‚¨`ûpû¡x`8b§ûÁ€;¿HYé`="¯)TH;À;‚§H,	@P``B,8ž1|„´9>X@}$´èÝ¥ëxƒãx;½HY9`_9>}>´|
HAÿÀ`;¦ØÃóxH=±`Åóx|dx8`Ký¬­`8 8€8`Ký¬™`,@‚Ì`;¢ƒØÃóxH=m`Åóx|dx8`Ký¬i`8 8€8`Ký¬U`,A‚ÿÈ£ëxH=1`¥ëx|dx8`Ký¬-`8 8€8`Ký¬`Ti>(	Z}#KxA(	@A,(	0A‚t9)ÿÏU)>(	Aä8cÿÏ|c´,A€ÿT?|	@ÿHxc&ä;ßÞ8 Äóx8`Ký«­`ÃóxH<‘`8 |dx8`Ký«`=¯;Àé(TJ,	9)ÿÿ}*´‘(TH@@`ByJ&ä}_RèjHLE`é?,	y(&ä}B9)ÿÿ}*´ûÈ‘?AÿÌëpë¡xëÁ€8!èëáÿø|¦N€ ``BKÿüaKÿþ|``B9)ÿŸU)>(	Aÿä8cÿ¨|c´Kÿÿ`B8iÿÈ|c´Kÿþð`BKÿü!Kÿþ4``B`8b¦øHWY`8!èëáÿø|¦N€ ```B8 8€8`Kýªu`Kÿþè€```û¡ÿèø!ÿa?¢¯ë½V¨,=A‚Üû€=B¯éJV˜;†=¯éV |ixœ"ûÁ8`|ýâ|Þ3x}J8P|(P@@€ 끀ëÁ8! ë¡ÿèN€ ``B|¦ûá˜;äûax}$Kx|»+x£ëxåûxø°H>`,>Ýý,ýú@‚X=B¯è°ëaxëÁëá˜8`é*V¨|¦‰âûŠV¨ë€8! ë¡ÿèN€ ```B8! 8`ë¡ÿèN€ ÅóxdÛx8H>`Kÿÿ˜€```B|¦ûÁÿðûáÿøøø!ø18 à;áp8€ãûxH=m``= 9B§Xa)9aP8€èÊèê}c[x8 p‘!„øÁpøáxH=1`= ?¯ëÞV¸=B¯‘!T€
V°|kx8Þ|€ž,$A‚8‰8è|æ:| 8@A€„=‚9@8€9Œå@`B,(A‚°‰&,	A‚¤ Æ9 (A‚T ¬9 8`|i¦90|(@8©A‚4x© B@¨ ¨8i|(@A‚ ¨xi 90|(@8©@‚ÿÔ)yHd9(ß},J‰	Ad9$8„y)dx„ }?J8©9)|À/,}O,>|	P@@T‰9J|æ;xyJ 9(}'J| H@A€4}'KxKÿÿ``B8!Ð8`ÿÿèëÁÿðëáÿø|¦N€ |Ç3x|'@@‚ÿÜ9!ˆx†d8Æ9@|€M,xÉ 8Æ}!Jåûx}c[xxÆ ™Ip8€KÿüÅ8!ÐèëÁÿðëáÿø|c´|¦N€ |Ç3x8€Kÿÿœ€```B|¦øø!ÿa=@€< !<À	yJÆ`¥@a‹`Æ@eJ x¥ÆxÆÆd¥dÆ	ùAp9 99@
ø¡xøÁ€8¡8Áœ8p±ˆ™!Š8à8`™!‘AœH$ù`8! è|¦N€ €`B=B¯ûáÿø="¯é)V¸=‚=b9Œå@€
V°9@9kåX;é™C™D|	‰	8¨|¿*| (@A€$ûÁÿð ÿ9 (A‚T Ë9 ;Àɦ9K|0@8ÉA‚4xÉ B@ü Ê;É|0@A‚ Ê{É 9J0|0@8É@‚ÿÔ)},Jˆéy!‰#});x™#A‚„9ÿÿ9_y 9?}
B}I@PqFA‚ˆß9?,@‚H|)@@A‚LyJøB}I¦H ```B‰J,
@‚B@$‰	9I9*,A‚ÿà‰$}';x˜ä‰|¿+x9(|¥J| (@@€þìëÁÿðëáÿøN€ ```B8àKÿÿ8```B}€&ú!ÿˆú¡ÿ¨úÁÿ°úáÿ¸ûAÿÐûÁÿð‘ø!ÿ|Ö3x|wx="¯é)V¸?B¯ƒZV°:#ƒÉ8ÉIÒ,>A‚‰I:ª~¦ª|:¨@A€à|¦øA(úA€.6úaˆú;Àûáèû°;pû!¸ûaÈ; |»+xûÐû¡Ø|œ#x; ø```B,*A‚0‰&,	A‚$¡>B9 :Rå@|@@A‚X<â çåX9 8 |©¦9R0|@@8éA‚4xé B@< ê8‰|@@A‚ êx‰ 9J0|@@8é@‚ÿÔ)}2JŠ‰:”~‘¢|4À@Aø@’U	Æ>U
D.})SxU(>±;ò:1:RÃ9 ¢fH`B;ÿ|?@A‚P¡?ÿý|H@@‚ÿì9?
~%‹xdÛxƒãxé),)A‚péIéi;ÿ}I¦èIN€!èA(|?@@‚ÿ¸;Þ~‘£x{Þ =B¯éJV¸9=y= J|
H@@¤‰U~¦«x9*}5J|:H@A€Œ}5KxKÿþ”ˆ¿8€ÿ~#‹xH6Å`KÿÿL``BèêA€êaˆêë°ë!¸ëaÈëÐë¡Øëáè|¦8!ð8`ÿÿê!ÿˆê¡ÿ¨êÁÿ°êáÿ¸ëAÿÐëÁÿð} N€ ``BèêA€êaˆêë°ë!¸ëaÈëÐë¡Øëáè|¦|:¨@@‚ÿœ,68wA‚8“×|£ˆP|£´8!ðê!ÿˆê¡ÿ¨êÁÿ°êáÿ¸ëAÿÐëÁÿð} N€ WÉÀ>|£ˆPSÉB|£´SÉF>y> “×Kÿÿ¼|Õ3x;ÀKÿÿ|Õ3xKÿÿˆ€```B|¦û!ÿÈûAÿÐûaÿØûÿàû¡ÿèûÁÿðûáÿøøø!ü1;aó|~x|Ÿ#x|¹+x8€8 pcÛx|ý;x}Cx|Ú3xH5A`9!÷…ãxÀÝ,¤ëxcÛx8ÀàM,Kÿü,A€|ÀÜ,<à	= €`ç@8cxçƒäy)Æ`ç	Ám8Áqù$8 ‚9øæ9@9 
;Áp|x°¡k‘y8 Ãóx™A}‘!ˆH5`åûx8û8a‹H4ý`9?Äóx8à8Áˆ8¡~8`‘!rH©`!ˆ,	
@‚˜!„}#x,@‚ˆ…ãx¤ëx8ÀcÛxKÿûEFÓx%ËxäûxcÛxKÿõq8!Ðèë!ÿÈëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ 8!Ð8`èë!ÿÈëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ <`@`cKÿø‰<`@`cKÿø}8!Ð=B¯8`èë!ÿÈëAÿÐëaÿ؉*Vëÿàë¡ÿèëÁÿðëáÿø|¦U)ò™*VN€ €```B=B¯‰*Vq(€A‚èjVxcàN€ `B|¦ûáÿøøø!ÿ9@ÿÿ?â¯yI8,™?VHÑ`8!€‰?Vè|jxxcàyI6lyI.¬|¦™?VëáÿøN€ €|¦ûÁÿðûáÿøøø!þÁ9@ÿÿ=¯}Cx‰(VyI8,™(VHe`‰?Vxjàxi6lxi.¬q'€™?V@‚,9@ÿÿyI8,™?VH5`‰?Vxjàxi6lxi.¬™?V,*;ÀA‚¤=@€= Dû û¡(yJÆ;ápeJ;€@‘!ø8 @8€ãûx;¡ùAð“;ÁðH2`åûx¦ëxÄóx8à8`H1`,#@‚t!v,)@‚h=@€= C“yJÆa)eJ8 @8€ãûx‘!øùAðH1¹`8à¦ëxåûxÄóx8`HÍ`,#@‚!v,)@‚<à€=z‘!xçÆyÆdçe9@9 €øáð¦ëxåûxùøÄóx8à±A‘!Hm`,#@‚°ƒár(€A¤ƒÁv,>@‚˜(@;ÿÿñ({å @€|£+xø¡Kýô`=B¯è¡,#øjV¸A‚<8H15`="¯ë ë¡(“éV°8!@ÃóxèëÁÿðëáÿø|¦N€ `|¤+x8b§hHHu````B<`@?Àÿÿ`ccÞÿÿKÿõ1<`@{Þ `cKÿõ!=B¯ë ë¡(‰*VU)ò™*VKÿÿˆ€`B|¦øø!ÿ‘H5`8!pè|¦N€ €|¦ûaÿØûÿàû¡ÿèûÁÿðøø!ÿ=@€= FyJÆeJa);¡¼;¨ùAp‘!xH8Q`;Áp9 
¦ëx…ãxøa|Äóx8à‘!¼8`HÅ`ƒa¼,
@‚D!®}#x,@‚4=€= {ûAÐyÆa)e9@ ;AÈ8à‘!ÄFÓxÅóxù¼‘AȤëx8`Ha`!È,	 @‚@!vûáø}?x,@‚8 8|ƒãxH/]`<à)=	›á “aÈ<À€`ç@a@=@xÆÆxçÆyÆyJÆ9 dÆ1dçe	eJ„ãxù!ù!˜8 8aøÁpøáxù€ùAˆH.í`FÓx¥ëxÄóx8à8`H¡`!È,	
@‚p!ÂëAÐëáø}#x,A‚0`B<`@`cKÿòù<`@`cKÿòí=B¯‰*VU)ò™*V8!8`èëaÿØëÿàë¡ÿèëÁÿð|¦N€ `BëAÐëáøKÿÿ¨`BëAÐKÿÿœ€```B|¦øø!ÿ‘="¯ø‰V ="¯øiV˜="¯øiV¨Kÿð
,#@‚8!pè|¦N€ <`@`cKÿò9<`@`cKÿò-=B¯8!p‰*Vè|¦U)ò™*VN€ €```B="¯é)V¨<b¯ècV˜|cHPxc N€ ``Bûÿàû¡ÿèûÁÿðûáÿøø!þa,)|#x|¿+x|~x|Ä3x|å;x}CxA‚4|¦ãûxøápø°Kþ=`è¡p|iy@<è°}$Kx|¦8! xˆ çûx†ãx¤ëxëÿàë¡ÿèëáÿøÃóxëÁÿðKÿöä;áp|¦+x`8€8¢§ãûxHSù`ãûxH(Í`||xãûxH(½`{† ¤ëxçûxåûxxh ÃóxKÿöè°8! ëÿàë¡ÿèëÁÿðëáÿø|¦N€ €```B|¦øø!ÿ‘y KÿöA8!p|c4èTcÙ~|¦|cÐxc N€ €û¡ÿèûáÿøø!ÿq=B¯|x|#x‰*Vq(€A‚ é*Vy)à,)8`A‚|(8`Ap|è@Ah|¦ûÁ€`;ªø H```BAœ4ãûx9Çóx8ÀÅóx8€Kÿõ…;ÿø@{ÿ ,#A‚ÿÐè ëÁ€|¦8!ë¡ÿèëáÿøN€ |¦9@ÿÿûÁ€yI8,?¯™>Vø Hu`‰^Vè xià|¦xj6lxj.¬™^VëÁ€Kÿÿ(€```B|¦û¡ÿèûÁÿðûáÿøøø!ÿa=B¯|~x|#x|¿+x‰*Vq(€A‚Pé*Vy)à,)A‚|(ÿ@˜(€`8⧨A‚è|ã;xøápH&`èáp8€xh 8`|å;x}CxKÿôm,#A‚$8! èë¡ÿèëÁÿðëáÿø|¦N€ `B`8¢§è|£+xø¡pH&A`è¡p9¸§ëx8€
xf 8`Kÿô,#@‚ÿ¨`8¢§ð|£+xø¡pH&`è¡p8! 8ý¸9H8€èë¡ÿèëÁÿðëáÿøxf 8`|¦Kÿó¼``B`8â§È|ã;xøápH%±`èáp8€xh 8`|å;x}CxKÿó,#@‚ÿKÿÿ49@ÿÿû€?‚¯yI8,™<VH`‰\Vxià,)xj6lxj.¬™\Vë€@‚þŒ8! 8`èë¡ÿèëÁÿðëáÿø|¦N€ `B8! 8`èë¡ÿèëÁÿðëáÿø|¦N€ €`BûÁÿðûáÿøø!ÿq=B¯|~x|Ÿ#x‰*Vq(€A‚Àé*Vy)à,)@‚ 8!ëÁÿðëáÿøN€ ```B|¦ûpû¡x?‚¯?¢¯è|VÈèVÀø Kýí`9 8`ù=VÀKýêý`,#ø|VÈA‚Ü(A”{å ÄóxH()`="¯é)VÈ9@ùIè ëpë¡x|¦8!ëÁÿðëáÿøN€ |¦9@ÿÿû¡xyI8,?¢¯™=Vø H%`‰]Vè xià|¦xj6lxj.¬™]Vë¡xKÿÿ``B;àÄóx{å H'•`="¯é)VÈ9@ùIè ëpë¡x|¦Kÿÿl``Bè ëpë¡x8!ëÁÿðëáÿø|¦N€ €`Bû¡ÿèûÁÿðûáÿøø!ÿq=B¯|~x|Ÿ#x‰*Vq(€A‚,é*Vy)à,)A‚$="¯é)VÈ?¢¯;½V,)A‚(A8!ë¡ÿèëÁÿðëáÿøN€ `B|¦`8 8‚ª Ãóxø H(`,#A‚üûpëý8é]0é?y<>$;œˆ|*à@@€DƒãxKýé%`|yA‚Øè½0è8H&]`è0è}8Kýêý`ûý8û0é?y)>$Äóx8i8 €|H&%`=B¯éJVÈé*9)ù*è ëp8!ë¡ÿèëÁÿðëáÿø|¦N€ ``B|¦9@ÿÿyI8,?¢¯™=Vø H`‰]Vè xià|¦xj6lxj.¬™]VKÿþ¤è |¦KÿþÀ`Bè0è}8Kýê9`è ûý0ëpûý8|¦Kÿþ”€```B=B¯‰*Vq(€A‚dé*Vy)à,)A‚D<â¯èçVÈ<€€8``„x„ é|å;xy>$9y }CxKÿï```B8`N€ ``B|¦ûáÿøøø!ÿ9@ÿÿyI8,?⯙?VH`‰_Vxià,)xj6lxj.¬™_VA‚P<â¯èçVÈ8!€<€€`„8`èëáÿøx„ é|å;x|¦y>$9y }CxKÿîl``B8!€8`èëáÿø|¦N€ €```B|¦øø!ÿQ8|	¦8áp`éb©à`èb©è`肩ð`袩ø9g|é;x`èª`¡Bªùapøaxø€ø¡ˆøÁ±A˜H`B}V,9)±	ÿþ}N,±	9IBÿè9*|å;x8À*8€8`Kÿí‘,#@‚H`8¢¨|£+xø¡ H…`=ÿÿ9Z¼<âÿý8ç™è¡ 8€xf 8`}@Py KÿíE8!°è|¦N€ €`B="¯‰)Vq)@@‚8`N€ ``B|¦øø!ÿ‘Hõ`8!pèxc |¦N€ €```B="¯‰)Vq)@M‚ |¦øø!ÿ‘|c´HÁ`8!pè|¦N€ €```B|¦ùÁÿpùáÿx}€&ú!ÿˆúAÿúaÿ˜û¡ÿèûáÿøø‘ø!þa``9"©h``?¢ù!ø?â``:"¨:B¨(:b¨H;½å@;ÿåZ9â©9©(~#‹xH9i`~C“xH9]`~c›xH9Q`Kýð)`.ƒ1/ƒ2,A–DAž@@‚ÿä8! èéÁÿpéáÿxê!ÿˆêAÿêaÿ˜ë¡ÿèëáÿø|¦} N€ `B8Û8aÚú@ú¡HúÁPûax``û€ú `:‚¨àúáXû`;b©:¢©8û!hûAp:ÀûÁKÿæ!‹Û~ƒ£x;@H8‘`; `B‰Ú9 (@8(A‚Tˆÿ9 8À|ɦ9_|8@8éA‚4xé B@8ˆê8É|8@A‚ˆêxÉ 9J0|8@8é@‚ÿÔ)W^>}=Jè©,%A‚,D´}ã{xH7ý`‰È8,	@‚ìcÛxH7å`;Z{9((	{Z @‚ÿL.<~£«xH7Á`@’$9!Ø;@:Ù;!pù!à9!:á°;Èù!è9!Ôù!ð``BKýîa`,5AT,0Aœ,@‚ÿäcÛxH7]`ê ê@ê¡HêÁPêáXë`ë!hëApëax끀ëÁKÿý¼`B,a@‚ÿœA’ÿ˜`èâª<À	@ûApèaà9xÆÆûA€ûAˆ9@€dÆ	³A9 
øáx`Æ8á~ƒx‘!ÔøǙ’±ApKÿäAˆ¡Ø98À9@8€``B|©P8,	A‚¨|P@9 A‚Tˆ9 9`}i¦8ÿ|P@8iA‚4xi B@tˆg9i|P@A‚ˆgyi 8ç0|P@8i@‚ÿÔ)|ýJ.,'A‚<‰P8f})48Æ|Æ´U)Ù~9)ÿÿ|yU)>°ã@˜ƒB™#C™#D™#E9ÿÿyJ(y!@‚ÿD¦èaèxÆ ~ä»xÁ‹øÁHI`èÁ8àÃx$Ëx8`&èÁð9)‘!rHí`,#@‚þ!Î,)@‚þ=€=@EyÆ9 @e8 @‘A¸8€#Ëx‘!Èù°Hu`8àÃx%Ëx~ä»x8`H‰`,#@‚ý¬!v,)@‚ý Kýìm`Kÿý”W^>Kÿý0``B}ÃsxH4ý`Kÿý< €<à'x¥Æ`ç@=	d¥xçÆa@dçyÆø¡p9 
e	=@8ÁÈøáx8¡°8p‘!Èù€8à8`‘AˆøÁðø¡èøàHÙ`!È,	
@‚ˆ!¶}#x,@‚x`èbª8`‰"ªJ`ébª0`éª@8à`¡BªHèÁðè¡èèàøax8`™!Šùapù€±AˆHe`!È,	
@‚!¶}#x,A‚úˆ`8€ÿÿ8b¨°H3å`Kÿúp``B8cÿÐTc>|ð@AüD‰!Ú8cÿÿ|j´}#0piA‚ü,9 }*P0}\âxWœ>KÿûèaøH3‘`KÿûÔ€``|¦û!ÿÈûAÿÐûaÿØûÿàû¡ÿèûÁÿðûáÿøøø!ÿQ?"|›#x?âëÿæ|¾+x8€Yæ 8 |}x|Ü3x|ú;xyJ&äÿRãûxH1`9æ =BéJæ9)yJáy( |(P‘9æ @‚9 ‘9æ ûþ=";àÿÿ{£ dÛx“‰æ0="?¢;½æ“éæ4Kþù`,#@‚xé>=B“Jæ0=B‰)“êæ4q)€@‚œ8`èKýÛ`9 8`y)ù=08!°èë!ÿÈëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ ```B8!°= y)ƒä=Bèë!ÿÈëAÿÐëaÿØa)
8`ëÿàë¡ÿèëÁÿðëáÿøù*æ0|¦N€ 8`Kÿÿ€€``B<‚è„æ,$M‚ |¦øø!ÿ‘8`x„ KþQ`8!p9 =Bèù*æ|¦N€ €```B="èiæ6N€ ``B="iæ4N€ ``B|¦ûáÿøøø!ÿQ?â="é)æ;ÿæ,)A‚Ü=")æ4,	ÿÿA‚<``8‚¬8bª˜H0é`8`8!°èëáÿø|¦N€ ``B= <ÂèÆæ<¢è¥æ<‚€„æ=Ba)ÿÿ8`üy)ƒäa)ÿÿù*æ0Kþ1`,#@‚ ? ,	A‚°="¯)VÐûÁ ?¯;ÞVÐ,	A‚àëÁ 8!°8`èëáÿø|¦N€ `B<bècæKýÛY`=B,#øjæA‚dè¿8€H)`Kýç±`,#ø@‚þè``8‚«ð8bªpH/Ý`8`Kÿþô```Bè9 À8à8À8¡˜8€±!€Kÿü5,#A‚|9 ûÁ ?¯;ÞVБ?="¯)VÐ,	@‚ÿ(<bècæ9 €8à8À8¡8p±!pKÿûå,#A‚Lé!=@
=aJÿÿyJƒä iaJÿÿ="ùHæ0xe (ÿ©æ8@ˆKýÚE`,#ø@A‚$9 8`‘>ëÁ Kÿþ```B= `y)ƒä`a)8‚¬8bª¸ù?0H.Á`8`KÿýØ``8‚«ð8bªPH.¡`8`Kÿý¸``8‚¬ 8b«(H.`= ëÁ y)ƒäa)ù?0<‚€„æ8`Kþý`8!°9 =B8`èëáÿøù*æ|¦N€ ```B``8‚¬8bªØH.`Kÿÿ¤`B``8‚¬ 8bªøH-ñ`ëÁ Kÿÿ€``€¿88‚¬ 8b«pKÿÿL€```BûÁÿðûáÿøø!ÿ1|y@‚¼|¦="û°?‚ëÉæ6;œæ,ÿÿøà@‚\úáˆûa¨|Û3x|—#xû¡¸<€Ææ8ƒ¤|0@A< û!˜ë<8€ûA |º+x8 û|ø;xy)&ä9J#ËxHA`< é\9)yJáy( |(P‘< @‚“ü <¢€¥æ8<bècæ@9 €=B³¡r±!pû*æ(|è@xi ‘9‘!t@¥ëxx¥ ~ä»xH1`= <b€cæ?"a)ÿÿ8py)ƒäa)ÿÿù9æ0KþÉ`,#A‚ˆ= y)ƒäa)=Bù*æ0êáˆëë!˜ëA H0```B``¥ëx8‚¬88b«ÀH,-`êáˆèàëa¨ë°ë¡¸|¦8!ÐÃóxëÁÿðëáÿøN€ ``B`{d9"«ð;à|é:9 ÿÿy)ƒ§\ù9æ0,=@‚ H”KýÔQ`9?è|H@y? @|é<(8`è‰IqJ€A‚ÿ؁[£é=aÿÿyƒä|P@aÿÿù0@}_Sx€‰{þ CÓxÅóx#Þ	{ÞàHÕ`9 =B“û;Þÿÿù*æ(KÿþØ`B9 y)KÿþÀ`B``8‚¬88b« H+`èà끰8!Ð;ÀÿÿÃóxëÁÿðëáÿø|¦N€ ;ÀÿÿKÿþÔ€	9 @úÁÿ°úáÿ¸9ÿü})¦ûÿÀû!ÿÈ9@@ûAÿÐûaÿØûÿàû¡ÿèûÁÿðûáÿø``B}Cx9Jÿÿ„ÈyJ '8€§$€ç})*x}):x})2xU)>‘(@BÿЃDƒdƒ„ƒ¤=€<nكÄaŒ¼Ü?àZ‚yŒ `ë¡cÿy™KÓxyÛx†ãx¥ëxØóxHX`B}*x|xy #Uv(>W'ð>})Âxç })B})º})²y) 9J|¸+x}y[x|Å3xyJ 8c|æ;x}+Kx(
+Š'@8(
;(2x@ÿœ|Ç+x|È(8|çÈ8}—cx|çCxA4xè Kÿÿˆ``B|È*x÷ûx}È8}*xy Kÿÿh``B€ã=8Êc(2x9)ÁÖ(
O}*x}):})BUh(>})BW'ð>y) xç @‚ÿL}:J}{ZêÁÿ°êáÿ¸ëÿÀë!ÿÈ|ü:|Ý2ëAÿÐëaÿØëÿàë¡ÿè|¾*ëáÿøëÁÿð‘$‘däÄ¤N€ 
``B|¦ûÿÀû!ÿÈûAÿÐûaÿØûÿàû¡ÿèûÁÿðûáÿøøø!þ(?|¸+x|zx|›#x@T;¥ÿÀ;ÀW¹Ñ¾;p;9{? ``B|›ò8 @ƒãx;Þ@HÑ`DÓxƒãxKÿýq9?ÿÿ{Þ y?!@‚ÿÐW½2{9O;½@{½ {êW½>}=ÀPdÛxU>>y*hÅóxƒãx*ÊHy` ¾?}!ò,9@ÿ€|¥´™Ip@8~8€||Hé`(7A\8 8°û!°8a¨H)`DÓxƒãxKÿüÉ8!èëÿÀë!ÿÈëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ `BDÓxƒãxKÿü‰8 <8€ƒãxHi`Kÿÿˆ```B; ; ;pKÿÿ€`B|¦ûÁÿðûáÿøøø!ÿa`|‡#x9"¬X`¬h;áp|dx|¾+xéIé)|å;xãûx‘€ùApù!xKÿþäûxÃóx8 H1`8! èëÁÿðëáÿø|¦N€ €`9 0úaÿ˜úÿ 8cÿü})¦ú¡ÿ¨úÁÿ°|hxúáÿ¸ûÿÀû!ÿÈûAÿÐûaÿØûÿàû¡ÿèûÁÿðûáÿø```B€È<H((„¨TÇx>TËh>TƲ¾|çZx|ç2x})*UFp>UEÈ>UJèþ|Æ*x}):}J2x})R‘(@Bÿ¸‚Ă䃃$`> BŠƒDƒdƒ„ƒ¤9 @;¬l})¦bµ/˜~Ƴx~à»xÃx?ËxGÓxlÛx…ãx´ëxH0``B†¾|´+x}[x}…cx|x|ì;x|À3x}GSx}&Kx…#}Š*xTó¨>TèÐ>}šx}J88Tó8>}šx}J*x}J|	[x}R}*08}¢|	X8TÔð>TӘ>~”šx}IKxTÊP>~ŠRx}ª})R}Hú}(JyJ y) Bÿpœb}6Jêaÿ˜êÿ ê¡ÿ¨êÁÿ°|×2|êáÿ¸ëÿÀëÁÿðëáÿø}yZ}ZR“„ë!ÿÈëAÿÐ|û:|½*ëaÿØëÿàë¡ÿè‘$Ä‘d‘Dä¤N€ 
``B|¦úáÿ¸ûÿÀû!ÿÈûAÿÐûaÿØûÿàû¡ÿèûÁÿðûáÿøøø!þ`(?9B¬l|—#x|{x|¹+xèÊèêé
é*øÁpøáxù€ù!ˆ@x;¤ÿÀ;ÀW¸Ñ¾;p;;Ap{ ``B|›ò8 @ƒãx;Þ@HA`DÓxƒãxKÿý19?ÿÿ{Þ y?!@‚ÿÐW½2{H(;½@{½ {êW½>}=¸PdÛxU>>U*xÅóxƒãx
ÂHé`!>?}Aò,	9ÿ€{ }%´™
p@8~8€||HU`(7Ax8 8û8a¨H•`DÓxƒãxKÿü…DÓx#Ëx8  Hu`8!ðèêáÿ¸ëÿÀë!ÿÈëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ ``BDÓxƒãxKÿü)8 <8€ƒãxH
¹`Kÿÿl```B; ;;p;ApKÿþì€	9 @úAÿúaÿ˜8cÿø})¦úÿ ú¡ÿ¨|hxúÁÿ°úáÿ¸ûÿÀû!ÿÈûAÿÐûaÿØûÿàû¡ÿèûÁÿðûáÿø``BèÈxéHé(Pè¨	xÇhxËxÆт|çZx|ç2x})*yFÀyEøyJÉÂ|Æ*x}):}J2x})Rù(€Bÿ¸> BŠêÄêäëë$`ëD ëd(ë„0ë¤8bµ/˜9 P})¦zµÆfµ×(;­bµ®"~Ƴx~ë»xÃx?ËxGÓxlÛx€ãx´ëxH4```B|¿+x}e[x|Ë3x~¦«xê¾	|x}€cx|ì;x}GSxêC	|ó`8xépxê}JJx|8xxé¸}JJx}šx}J’}i*x}R}*08}¢}i(8xÔ xÓð~”šx}IJxxÊÈ~ŠRx~¨ª})R}Uú~µJBÿx~¶ªœbêAÿêaÿ˜êÿ êÁÿ°|×2}xZêáÿ¸ëÿÀëÁÿðëáÿø|¹*}ZRú¤û„0|û:|ê¡ÿ¨ë!ÿÈëAÿÐëaÿØëÿàë¡ÿèøÄùdø¤ùD øä(ø8N€ ```B|¦ûÿÀû!ÿÈûAÿÐûaÿØûÿàû¡ÿèûÁÿðûáÿøøø!üÁ(|¸+x|zx|›#x@T;¥ÿ€;ÀW¹Éþ;p;9{? ``B|›ò8 €ƒãx;ހHA`DÓxƒãxKÿýQ9?ÿÿ{Þ y?!@‚ÿÐW½0{9W;½€{½ {êW½>}=ÀPdÛxU>>y*hÅóxƒãx*ÊHé` ¾}!ò,9@ÿ€|¥´™Ip@8~8€||HY`(oA\8 8ðû!ð8aèH™`DÓxƒãxKÿü©8!@èëÿÀë!ÿÈëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ `BDÓxƒãxKÿüi8 €8€ƒãxHÙ`Kÿÿˆ```B; ; ;pKÿÿ€`B|¦ûÁÿðûáÿøøø!ÿA`|Œ#x`ëâ°`éb° `è°(`èâ°0|dx|¾+xè°`é°8`éB°@`é"°H}…cxûáp;ápùa€ãûxøxøÁˆøáù˜ùA ù!¨KÿýÅäûxÃóx8 0He`8!ÀèëÁÿðëáÿø|¦N€ €``B|¦ûÁÿðûáÿøøø!ÿA`|Œ#x`ëâ°P`éb°``è°h`èâ°p|dx|¾+xè°X`é°x`éB°€`é"°ˆ}…cxûáp;ápùa€ãûxøxøÁˆøáù˜ùA ù!¨KÿüõäûxÃóx8 @H•`8!ÀèëÁÿðëáÿø|¦N€ €``|¦ûáÿøøø!ÿ|xø¸Hi`聸|c´|H`8!€ãûxèëáÿø|¦N€ €``````‰#T„>,)A‚(````B|H@M‚ #,)@‚ÿð8`N€ ``‰C‰$,*@‚(HT```B@ž(C,*A‚4}Cx‰$9,)‰P@@‚ÿÜ}C´|iP|c´N€ ``B‰$8`|iP|c´N€ 8„ÿÿ9Cÿÿ``B$,)*M‚ $,)*@‚ÿäN€ ‰#,	A‚H|ix!```B|hJI|c´,
M‚ |hJI|c´,
@‚ÿÜN€ `B8`N€ ```,%A‚l‰C8¥ÿÿ‰$|¤*|¤(P,*9}	¦@‚ HXB@,@ž(C,*A‚@}Cx‰$9,)‰P@@‚ÿØ}C´|iP|c´N€ `B8`N€ ``B‰$8`|iP|c´N€ ‰D,*A‚,%M‚ p©8åÿÿ|ix|¨+x@‚¼yøB}	¦H,```B™I9)8¥ÿÿ‰H,*A‚(B@¸™I99)8¥ÿÿ‰D8ˆ,*@‚ÿÈ,%9IÿÿM‚ p¨8åÿÿ9A‚,'™	}*KxM‚ x©øB})¦````B9*™
9J™	BÿðN€ ``B™C9#|å;xD,*A‚ÿˆ,'@‚ÿ,N€ ```BN€ |ixKÿÿd``ûáÿøø!ÿq|yA‚À,$ûÁ€|ž#xA‚|¦ûpû¡xø Kÿý‘`|}xÃóxKÿý`,||´@¬½´¿ê|?è@@€X}?èPq)@‚t…ãxÄóxãûxKÿýµ`…ãxÄóx,#A‚l;ÿãûxKÿý•`,#A‚T;ÿ|?è@@‚ÿ¼è ëpë¡xëÁ€|¦8!;àãûxëáÿøN€ …ãxÄóxãûxKÿýE`,#@‚ÿ´è ëpë¡xëÁ€8!ãûxëáÿø|¦N€ ëÁ€Kÿÿ¨€```,%9#ÿÿT„>M‚ pª9Eÿÿ@‚(xªøB}I¦9I˜‰9)˜ŠBÿðN€ `B,*˜ƒ|ix@‚ÿÐN€ ,%M‚ p©9Cÿÿ9$ÿÿ9ÿÿ@‚8x¨øB}	¦ˆÉ8é9
9)9J˜Êÿÿˆç˜èBÿàN€ `B,(‰|‰#x|jx™@‚ÿ¸N€ ``|$@@€\}$*|)@A€P,%M‚ pª9ÿÿ}C*@‚¨x¨øB}	¦ˆÉÿÿ8éÿÿ9
ÿÿ9)ÿþ9Jÿþ˜Êˆçÿÿ˜èÿÿBÿàN€ `B,%9$ÿÿ9CÿÿM‚ p¨9ÿÿ@‚8x¨øB}	¦ˆÉ8é9
9)9J˜Êÿÿˆç˜èBÿàN€ `B,(‰|‰#x|jx™@‚ÿ¸N€ `B,(	ÿÿ
ÿÿ@‚ÿPN€ ,%8¥ÿÿA‚ˆ9E9ÿÿqI|£*8äÿÿ@‚PyIøB})¦Hˆf‰*|H@@‚(B@Pˆh‰'8È9G98ê|H@A‚ÿÐ})P}#´N€ ‰$|hxˆc|‡#x|H@@‚ÿà|((@@‚ÿ˜8`N€ ```û¡ÿèûáÿøø!ÿq|}x|Ÿ#xˆc,#A‚Ü|¦ûÁ€ø H8HA`|~xˆH1`9?|@‚PŒ},#A‚t}?Kx‰?,)@‚ÿÄè ˆ}ëÁ€|¦8!|iP|c´ë¡ÿèëáÿøN€ ``Bè ˆ}‰?ëÁ€8!ë¡ÿèëáÿø|¦|iP|c´N€ `Bè ‰?ëÁ€8!ë¡ÿèëáÿø|¦|iP|c´N€ ‰$Kÿÿ„€`|¦ûÁÿðûáÿøøø!ÿ|~xTŸ>KÿøÕ`9#ÿÿ|~J|>@AT‰C}>Py)à|
øA‚D8cÿÿ|>@A4,)@‚H`B‰#|	øA‚ #ÿÿ|	øA‚8cÿÿ|>@@ÿà8`8!€èëÁÿðëáÿø|¦N€ ‰#|	ø@‚ÿÐKÿÿÜ€`8cÿÐxc  c	xcàhcN€ ```Tjò9#ÿÐ8jÿ¿y) xc !)	 cy)àxcài)hc|cKxN€ 9#ÿ¿(	M 8c |c´N€ ```9#ÿŸ(	M 8cÿà|c´N€ ```,$|ixA‚H($ù$A<àxçƒä`ç&H``BA‚à9)ù$‰I+Š |èT6q@ÿä,%@‚Ì(
0@‚8‰I8 
,
xA‚ì9@0```B8`H4``B}4|(9)}EÒL€ ù$|hR‰I,*M‚ 9
ÿÐ8êÿŸU>Tç>(	+‡}4@ÿÀ8êÿ¿9
ÿ©@ÿ°Tç>9JÿÉ(}H4M |(9)}EÒA€ÿ N€ `B,%A‚,``B,A‚D,*@‚ÿT8`N€ ``B8 
Kÿÿä``B8ÿðKÿþ¸9	ù‰I}	Cx(
08 @‚ÿ¸‰I,
x@‚þô9	ù‰I}	CxKÿÿ˜8 
Kÿþè``,$|ixA‚H($ù$8`M <àxçƒä`ç&H`BA‚ð9)ù$‰I+Š |èT6q@ÿä(
-@‚Ì9	,%9`ù‰I}	CxA‚¼```B,A‚ô,*A‚8`H4``B}4|(}EÒ9)@€`ù$|hR‰I,*A‚L9
ÿÐ8êÿŸU>Tç>(	+‡}4@ÿÀ8êÿ¿9
ÿ©@ÿ°Tç>9JÿÉ(}H4@ÿ ``B,+M‚ |cÐN€ ,%9`@‚ÿX(
08 
@‚ÿT‰I,
xA‚(9@0KÿÿH`B($8ÿðù$8`@þ¼N€ 9	ù‰I}	Cx(
08 @‚ÿ‰I,
x@‚ÿ¸9	ù‰I}	CxKÿþè8`Kÿÿh``== IÆa)NméHæH})QÒ=)9)‡y#„bù(æHN€ ```B="øiæHN€ ``|¦ûÿÀû!ÿÈûAÿÐûaÿØûÿàû¡ÿèûÁÿðûáÿøøø!ÿQ;ã?b¯;C{ÿä;{VØ||x]´þ´è{,#A‚é;}CÒ|*H@@,é[}ISx‰	©@qð@‚8ˆÉˆé‰	ˆ©xÄÁ(xçƒä|ç#xyEä};xxÆ |¨Cx|(à@@€@@œDˆ©ˆÉˆé‰	x¥Á(xƃä|Æ+xxçEä|ç3x};x9})BKÿÿˆ`B|)@A€è|*@@€$8€8ÀHÄ`BAž@‹*‰j‰ˆ8€ˆêˆ¦‰Š‰&yÁ(xƒä{9Á(ykƒä|Ãxx¥Eä}kËxxçEä|¥x|ç[x})+x}‡;x}):U69)y'G"y%†"};xy'Æ"™&˜¦™˜æˆªˆê‰
‰*x¥Á(xçƒä|ç+xyEä};x})Cx9)}JJ|*@@€P‰*/¦q)ðA‚ÿ8ˆªˆê‰
‰*8Àx¥Á(xçƒä|ç+xyEä};x})Cx9)}JJ|*@A€ÿ¸,$@‚þ4£ëxKýÊí`é;|#H@@‚<|cÒø{Kÿþ```B}FSxKÿÿ@``BÃóxKýÊ­`,#ÿÿø{A‚ü}#ú}CÒø{|*H@ù;AýÜ{‰ =¯e)8ãùHVؑ#8!°|ã;xèëÿÀë!ÿÈëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ |(Ð@8é@P}@P{† U
>dÈ8!°|ã;x‘	}Gá.èëÿÀë!ÿÈëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ `Æ8!°|ã;x˜ÉèëÿÀë!ÿÈëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ 8àKÿÿ4€```,#M‚ ‰#ÿüU)>™#ÿüN€ ```ø!ÿ‘,#ø¡°øÁ¸øáÀùÈù!ÐùAØA‚0,$A‚(|¦8¡°ø€H
Y`è€|¦8!pN€ 8`ÿÿKÿÿô€```````|¦û!ÿÈûAÿÐûaÿØûÿàû¡ÿèûÁÿðûáÿøøø!ÿQ||x|ß3x|£+x|›#x8 
8€ë<|ý;x}Cx}>KxKÿ÷¡`,?|c´A‚°9@H`````B|=ø@9Jÿë’}J´@ÿðyJ }^R|P@@}JPé<9JÿÿyJ 9J}I¦H›Ié<9)ù<B@}YHP|*Ø@A€ÿä8!°èë!ÿÈëAÿÐëaÿØëÿàë¡ÿèëÁÿðëáÿø|¦N€ `B9@Kÿÿ„€```B}€&ûAÿÐû¡ÿèûÁÿðûáÿø‘ø!ÿQ`|½+y9"°|zx|ß3xéIéiùApùaxA‚àªëx9 `B|*ø@9)}Jû’})´@€ÿð}>Kx|$ð@A€|¦ûûaˆ.'ÜóxøÀH`B|=ø@é:}Ûx|iá®A€@}û’;œÿÿ};ùÒ})èP}!JˆipA’ÿÔKÿõÑ`|=ø@é:}ÛxTc>|iá®@€ÿÈé:})òù:èÀëaˆë|¦8!°ëAÿÐë¡ÿèëÁÿðëáÿø} N€ `B;ÀKÿÿD€```BûÁÿðø!þ‘|~yøa A‚p,$8`A‚Ðùáèû¡XÏóx;¤ÿÿ‰%,)A‚˜`úÁ û0:Áp9B°°û!8ûáh; ùAÀH0```B™/}CxéA 9êùá ‰%,)A‚4þxP|?è@@€((	%9@‚ÿ̉%8á9H\``B(	iA‚l(	uA‚d(	xA‚\(	XA‚T(	pA‚L(	cA‚D(	sA‚<(	%A‚Ô(	OA‚,(	oA‚$'|¹+x8ˆ%}Cx|ˆ´(	d@‚ÿ”}BûP8c|c´9F™( |v9 ùAÈÿèP™# 놉‘9(ÿÒq)ýA‚„9  8á‘ù!¸,(A‚à|¦9 ú!øúaúá(ûA@ù!°}<ÐûaHúðúA::@ù!Ðú:€ø€ú¡}õ{x~ï¨P|?¸@@X9(ÿ±‹g;GU&>(+A<Âÿÿ8ÆCày)¨}&Jª})2})¦N€ ððððððððððððððððððð°`ððð`ððpðððððpð`ðððxêÁ ë0ë!8ëáh9 ™/èa éáèë¡XÞPô8!pëÁÿðN€ ``B9(ÿÐU)>(		A}!¢:”GÓxz” ™	phÛx,(@‚þ¤è€~¯«xêðê!øêAêaêê¡êá(ëA@ëaH|¦èÁÈëP8¹Kÿý(u}!¢“ãxšIpA‚LéA°9UI89)ÿÿ}	H6‰H9A‚09 -™5yI$éAÀ~jH*é!Ð}3˜8é! 9)~ïHPù! é¸|—øP8à
~f›x~ųx9 ÃxKÿù©è ~e›x~ƒx8À
HPé!°éAÀ|Á¢|—øP8à~ųxšFpÃxy($9 ~ê@*鸗¸8~æ»xKÿùY聠~å»x~ƒx8À| PÃx|„øPKÿúiê¡ GÓxhÛx,(@‚ýdKÿþÀ```B}!¢8 
8€~óxšIpKÿðí`|sxƒãxKÿè=`zs |˜@xc A€Xêa ~ï˜P: ~÷øPH}ˆ®:1™é 9ù ƒãxKÿçõ`|1@@€ÿdê¡ }¨P|7@@AÿÈGÓxhÛxKÿÿT``B:é!°éAÀ|Á¢|—øP8à~ųxšFpÃxy($9 ~ê@*鸗¸8~æ»xKÿø5聠~å»x~ƒx8ÀKÿþÜ```B(lA‚ì9 GÓxhÛxù!°KÿþÐ`B(hA‚¼9 GÓxhÛxù!°Kÿþ°`B|¡¢9 9 8à
šEp|—øP8À~ųxÃxKÿ÷­é! GÓxhÛx›‰ê¡ :µú¡ Kÿþd``B|¡¢ùÁà|—øP9 9 šEp8à†ãx~ųxÃx9ÀKÿ÷Uê¡ `:"°§~ï¨P:q~÷øPH,`B}5 P|7H@@419Ι$é! 9)ù! ~c›xKÿæY`聠|.@A€ÿÈ| P~ƒx|„øP8À…ãxÃxKÿø
ê¡ éÁàGÓxhÛxKÿý `B99 %8¹ù ™/`Béá Kÿù˜9 0‰’8á’ù!¸Kÿú|```B|c˜P~÷øPêa 9#ÿÿy) 9)})¦H9  ™3êa :súa B@ý|}5˜P|7H@AÿàKÿýl``B9 ù!°Kÿüü9 ù!°Kÿüì8!p8`ëÁÿðN€ €`|¦øø!ÿ‘|‰#x8€ÿÿ|¦+xx„`}%KxKÿøA`8!pè|¦N€ €```|¦øø!ÿ‘ø¡°8¡°øÁ¸øáÀùÈù!ÐùAØHY`8!pè|¦N€ €`|¦øø!ÿ‘|kx<b8cæpø¨}d[xø¡°8¡¨øÁ¸øáÀùÈù!ÐùAØHõ`8!pè|¦N€ €|¦ûÁÿðûáÿøøø!ÿ?Â;Þæpøa°ëþKÿä`聰|exãûxKýž‰``8 8‚°ø|xè~Kýžm`8!€ã´èëÁÿðëáÿø|¦N€ €```ûáÿøø!ÿq|x#,	A‚|èƒ,$A‚pé#
,)A‚,	O@¼|¦8 Pø èKý¥9`,|c´A€x,O@tè é_9 |¦‘?8!ˆjëáÿøN€ ``B|¦8 8pø èKý¤Ý`,#@‚`è ˆap|¦8!ëáÿøN€ `B8`é?9@}I®Kÿÿ„```B}H®}DJ,A‚ÿ<9)})´Kÿÿl`Bè 8`ÿÿ|¦Kÿÿ¤€`B‰$,)A‚¤|¦úÿ ú¡ÿ¨úÁÿ°úáÿ¸ûÿÀû!ÿÈûAÿÐûaÿØûÿàû¡ÿèøûÁÿðûáÿøø!þ1>àz÷ƒä|~x|º+x;„; ;à;:À&;!p;aob÷&``B9Iÿ±UH>()AÔ=ÿÿ9LÜyJ¨}HRª}JB}I¦N€ ´´´´´´´´´´´´´´´´´´´$ô´´´´ô´´´´´´´´4´´´´´```B9)ÿÐU*>(
	A})ê}=´``B<,)@‚þø8!Ð8`èêÿ ê¡ÿ¨êÁÿ°êáÿ¸ëÿÀë!ÿÈëAÿÐëaÿØëÿàë¡ÿèëÁÿð|¦ëáÿøN€ ÃóxKÿüýTi>(	 A~êL6qJ@‚ÿäéZÃóx9
ùéJ™*KÿüÉTc>, A~ã6pi@‚ÿ````B>,	A‚ÿHé>
,	@ÿ<9)ÿÿ‘>Kÿÿ0```BÃóxKÿüm,=Ti>Tt>A‚ü,	 ~ƒ£xA‚à,		A‚Ø,	
A‚Ð,	
A‚È,4A‚	|ø@T:¿ÿÿ~¹ª```BKÿçÁ`,#A‚Lž•ÃóxKÿûù9}´Tj>Tt>,
 ~ƒ£xA‚l,
	A‚$,

A‚,

A‚,4@‚Ü``B}!ú›	p~Ã6pi@‚0>,	A‚$é>
,	@9)ÿÿ‘>```B#ËxKÿß`,#A‚ì8 8€#ËxKÿéQ`é:9IùZé)iKÿýäÃóxKÿû-,=Ti>Tt>A‚¼,	 ~ƒ£xA‚,		A‚ˆ,	
A‚€,	
A‚x,4A‚°|ø@t:¿ÿÿ~¹ª```BKÿæQ`,#A‚ž•ÃóxKÿú¹9}´Tj>Tt>,
 ~ƒ£xA‚,
	A‚$,

A‚,

A‚,4@‚ü``B}!ú›	p~Ã6pi@‚0>,	A‚$é>
,	@9)ÿÿ‘>```B#ËxKÿÝÝ`,#A‚¬8 
KÿþÀ`BÃóxKÿú
,=Tj>Ti>A‚Ì,
 }#KxA‚h,
	A‚`,

A‚X,

A‚P,)A‚€|ø@49IÿÐ:¿UJ>~µ´(
A```BÃóx};©®~¿´Kÿù•Tj>Ti>,
 }#KxA‚ø,
	A‚(,

A‚ ,

A‚,)@‚°```B}!ú›	p~Ã6pi@‚0>,	A‚$é>
,	@9)ÿÿ‘>```B#ËxKÿܽ`,#A‚Œ8 Kÿý `BÃóxKÿøí,=Ti>Th>A‚¬,	 }CxA‚P,		A‚H,	
A‚@,	
A‚8,(A‚P|ø:¿ÿÿ~¹ª@\```BÃóxKÿø‰9_}_´Ti>Th>,	 }CxA‚ì,		A‚$,	
A‚,	
A‚,(@‚ü``B}!ú›	p~Ã6pi@‚0>,	A‚$é>
,	@9)ÿÿ‘>```Bé:$Ëx9IùZèiKÿÛ]`Kÿú”|è@‚ûÌ¿ëx}Aúxi ›
p(	
Aü(Kÿü```B|è@€9IÿÐ:µUJ>(
@ýø,
}!ú›	pAþLKÿþ<|è@‚ü¬¿ëx}Aúxi ›
p(	
AýKÿüø```B|
è@‚þ¼¿ëx,
}!ú›	pAÿKÿþü,	 Tc>A‚¨,		A‚°,	
A‚¨,	
A‚ ,#A‚˜;ÿÃóxõ´~¿´}©®KÿöñTi>Th>,	 }CxA‚\``B,		A‚þŒ,	
A‚þ„,	
A‚þ|,#:µA‚þpÃóx}©®~¿´Kÿö¡Ti>Th>,	 }Cx@‚ÿ¼``B}!ú›	pKÿþx`B}!ú›©pKÿþh`B,	 Tc>A‚è,		A‚À,	
A‚¸,	
A‚°,#A‚¨Kÿáå`:¿ÿÿ~¹ª,#A‚h```Bž•Ãóx;ÿÿ´KÿöTj>Tt>,
 ~ƒ£xA‚|,
	A‚ú4,

A‚ú,,

A‚ú$,4A‚úKÿáy`,#@‚ÿ¬,4 }!ú~ƒ´›	pA‚ú8z‰ KÿýØ```B}!ú#Ëx›©pKÿÙ5`,#@‚ú8!Ð8`èêÿ ê¡ÿ¨êÁÿ°êáÿ¸ëÿÀë!ÿÈëAÿÐëaÿØëÿàë¡ÿèëÁÿð|¦ëáÿøN€ ,
 Tc>A‚ ,
	A‚°,

A‚¨,

A‚ ,#A‚˜9IÿÐUJ>(
Aýd;ÿõ´H@``B,
	A‚ûŒ,

A‚û„,

A‚û|,)A‚ût9IÿÐ:µUJ>(
AýÃóx};©®~¿´Kÿô¡Tj>Ti>,
 }#Kx@‚ÿ¬}!ú›	pKÿûp```B}!ú›©pKÿûX`B,	 Tc>A‚Ø,		A‚À,	
A‚¸,	
A‚°,#A‚¨Kÿßµ`:¿ÿÿ~¹ª,#A‚h```Bž•Ãóx;ÿÿ´KÿôTj>Tt>,
 ~ƒ£xA‚l,
	A‚ùt,

A‚ùl,

A‚ùd,4A‚ù\KÿßI`,#@‚ÿ¬,4 }!ú~ƒ´›	pA‚ùxz‰ Kÿü8```B}!ú›©pKÿùX`B}!ú›	pKÿùH`B}!ú›	pKÿ÷ø`B}!ú™	pKÿûX`B}!ú˜ipKÿú8`B}!úš‰pKÿù`B}!úš‰pKÿ÷¸8`N€ €}€&û¡ÿ葁ø!ÿA‰$ø¡,)A‚€|¦ûAûa˜; û ûÁ°||x;Àûá¸;A|Ÿ#x;apøÐH``B‰);ÿ,)A‚ô(	%éûx@‚ÿè‰?9o9@H4`BAž€A–|AšxA†tA’pAŽl|¸ A‚œ|ø A‚\AŠX(8ê}KSx?|ê´)	%(	d+‰i*‰x|²&T¥@)	O+	X(‰p*	c|ò&Tç@)‰s)	o@‚ÿˆ`B9k}AR}k´EÓx}aZ™*pdÛxƒãx›ËpKÿó
,@$;½½´éûx;ÿ‰),)@‚ÿ`BèÐëAëa˜ë ëÁ°ëá¸|¦8!À£ëxë¡ÿè}’ }‘ } N€ ; KÿÿÜ€Kÿñ`<b8cæKÿñH``ø!ÿ‘,#øÁ¸øáÀùÈù!ÐùAØA‚4,%A‚,|¦8Á¸ø€KÿçÍ`è€|¦8!pN€ `B8`ÿÿKÿÿð€```|¦û¡ÿèûÁÿðûáÿøøø!þ1;Áp|¦+x|}x|…#xÃóx8€@Kÿça`Äóx|xè}åûxKýŽ©`8!Ðãûxèë¡ÿèëÁÿðëáÿø|¦N€ € iði i`iÀiR0iSðiTÐiWÀiX iY€iZpiZài[ i\i\i]i]0i]°i^@i^Ài`@i`Ðiaib0ib°ic0ic°id@idÐie`ieàifigpih`ih€ih iiðij`ijÀik0ilÀimàipiq0iÄiØiq˜iwpixpiyði{€i|°i}Pi@iài€i`iƒi…€i† iŠi‹Pi‹piŽ iŽÐi@i“Ði˜Pi™PišPiœ iœÐii°iÐiðiŸ`i i €i ài¡ài¥Ài§ i¨i¨i©pi©ài«Ài® i®ài°`i°°i´i·@i¸ài¹@i¼0i¿€iÁiÁ`iÅàiÆÀiÉpiÌiΰiÏ0iÑ@iÓiÓ`iӐiÔiÕÐi׀iÙ°iڐiÞ ißPiàÐiáàiâàiã0iãàiä`iåiåiæPiæÐiçièièÐiéÀiê ië@iëàiì°iíPiîPiî iòiòióiø@iúiúiüÐi@iÀiÀi°iiiÀi i€iiÀiPi`i" i"ài$`i%€i%Ði7`i9Pi9Ài:€i;€i?€iAÀiB iC@iD@iFÐiI iOiR0iS iW€i[ài_Àih ii@ii€ik imip0ip`iqiqir0irÀis`isðitiu iu€iu iv°iz@i{i|ði}i}€i~€ii0i€i…pi‰0i‰@i‰`iŠiŒiŽPii”€i—pi˜@i™°išPiÐiž`i¢`i¤°i¦pi¨i©i©Ðiª°i­@iÁ°iÇÀiÈ0iÈ°iÉiÊ@iÍiÍ@iÎPiÒ iÕðiÖ`iրiØ iØàiÙ`iÚ iá0iáPiápiâiâ0iâPiâpiâiâ°iã0iãpièië`iìPiìpiíÀiîiî@iî`iîpiðiòPiò°i÷piúiý€iþ€ii@iPi	Ði
0iàipi iài`ipi#Ài#ði'Pi*Ði. i/ i0Ði50i6ði8Pi;i; i<i<i= i=Ði>0i>i?i@i@piBÐiE@iF€iFàiGðiI°iJðiKiLiQ°iR0iRÐiSiSàiT`iUiUÀiViX iY i\pi] i_ði`ib0ie igÐihPikik0impinin0ioPioip°irÀit`iv@iwpix€ixàiy0i i@i iÀiài…`iˆ@iŠPiŒiŒiŽ°i°i’ài”i•`i–0i– i–ði—pi—°i˜ i˜Ài™ði›0i›iœii°ižÀiŸ€iŸ°iŸði  i Pi¢i£Ài¤i¤ i§°i§ài¨`i©iªÐi²pi²Ài³i³pi´iµ0iÀði i°iÂÐiÃ@i
ERROR: stack overflow in engine()!
type crtypefind-methodCan not open socket, no parent instancereadCan not open socket, no 'read' methodwriteCan not open socket, no 'write' methodget-propertyCan not open socket, file descriptor list is fullmy-parent ?dup IF ihandle>phandle THENlocal-mac-addressEXECUTEkey? IF key ELSE 0 THENget-msecsusdma-allocdma-freealloc-memfree-memdma-map-indma-map-outconfig-l@config-w@config-b@config-l!config-w!config-b!translate-my-addresswrite-mm-logencode-intset-chosenencode-bytesbootp-responsedhcp-responsefind-node get-propertykeyreset-allvtpm-unitBITMAP: start %lx, size %ld, blocksize %ld

0                 16                32                48              63


Error: Bitmap start %lx, size %ld, requested address %lx, size %ld
ELF32: VirtAddr(%lx) != PhysAddr(%lx) not supported, aborting
ELF64: VirtAddr(%lx) != PhysAddr(%lx) not supported, aborting

ELF relocation out of bounds!
ERROR: Unhandled relocation (A) type %i
elf-claim-segmentFailed to allocate memoryIOMMU setup has not been done!
Queue index is too big!
memory allocation failed!
Device does not support virtio 1.0 %llx
Features error %llx
%s: failed
virtioblk_transfer: Access beyond end of device!virtio-blk: Unaligned sector size %d
virtioblk_transfer failed! type=%i, status = %i
virtioblk_initslofVersion check failed, rc = %d
Attach failed, rc = %d
Walk failed, rc = %d
Stat failed, rc = %d
Open failed, rc = %d
Read failed, rc = %d
virtio_9p_initvirtioscsi_initUnable to allocate virtio-net driver
virtionet: Failed to allocate buffers!
virtio-net: Receive buffer not big enough!
virtionet: Packet too big!
virtio-serial: Failed to allocate buffers!
virtio_serial_putchar failed! 
virtio_serial_init
Error: %s
9P2000.uunknown%s: Failed
ErrorDevice Error%s: alloc failed %d
usb_get_pipeusb_send_ctrlusb_transfer_bulkusb_setup_new_deviceusb-ohci: Warning ED not aligned to 16byte boundary%s: alloc failed
Timed out waiting for interrupt %x
USB: Error TD null %p
USB: Error %s %p
usb-ohci: Not a bulk pipe.
usb-ohci: buffer size not supported - %d
%s: tds NULL recieved
ED Halted
%s: headp %08X tailp %08X next_td %08X attr %08X
%s: timed out - failed
Request: %02X   OHCI: initializing
usb-ohci: Unable to allocate memory
usb-ohci: Unable to allocate/unaligned HCCA memory %p
 ** HCD Reset failed...usb-ohci: oops could not allocate intr_pipe
Start removing device
usb-ohci: unable to setup device on port %d
ohci-hcdNOERRORCRCBITSTUFFINGDATATOGGLEMISMATCHSTALLDEVICENOTRESPONDINGPIDCHECKFAILUREUNEXPECTEDPIDDATAOVERRUNDATAUNDERRUNreservedBUFFEROVERRUNBUFFERUNDERRUNNOT ACCESSEDohci_get_pipe_introhci_transfer_bulkohci_send_ctrl%s: already called once 
usb-ehci: Not a bulk pipe.
usb-ehci: bulk transfer size too big
usb-ehci: bulk transfer timed out_
%s: handshake failed
  EHCI: Initializing
usb-ehci: Unable to allocate memory
usb-ehci: reset failed
usb-ehci: Unable to allocate frame list
usb-ehci: Unable to allocate interrupt queue head
usb-ehci: Unable to allocate async queue head
usb-ehci: unable to setup device on port %d
usb-ehci: Not a control pipe.
Error allocating qTDs.
usb-ehci: control transfer timed out_
ehci-hcdehci_exitehci_transfer_bulkehci_send_ctrls" dev-keyb.fs" INCLUDEDs" dev-mouse.fs" INCLUDEDs" dev-storage.fs" INCLUDEDs" dev-hub.fs" INCLUDEDDevice not supported %06X
%s: bulk reset failed
USB Interface class -%x- Not supported
usb_slof_populate_new_device%s: unable to allocate keyboard buffer
usb_hid_kbd_initusb-hub: NULL
usb-hub: unable to setup device on port %d
TRB_TYPE  %d
usb-xhci: bulk transfer size too big
usb-xhci: allocation failed for interrupt endpoint
usb-xhci: %s alloc_intr failed  %p
usb-xhci: allocation failed for bulk endpoint
USB3 slot ID %d is too high (max is %d)
  XHCI: Initializing
usb-xhci: Unable to allocate memory
usb-xhci: 64 Byte context not supported
usb-xhci: failed to initialize XHCI controller.
xhci-hcdPowered-OFFPolling***  Disconnected ***DisabledLoopbackCompliancek******  Reset  ************ Enabled ******ERRORxhci_get_pipe	

@{[]}\~|ABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()
	 _+{}||:"~<>?079.136428/*-+
1234567890.|abcdefghijklmnopqrstuvwxyz1234567890
	 -=[]\\;'`,.//*-+
1234567890.\free spaceCreating common NVRAM partition
commonvio reg must 1 cell long
Unable to allocate veth driver
veth: Failed to allocate memory !
veth: Error %ld registering interface !
veth: Dropping too big packet [%d bytes]
veth: Error %ld sending packet !
Failed to read MAC address from EEPROM!
82547EI/GI Copper82547EI Mobile52546EB Copper, Dual Port82546EB Fiber, Dual Port82546GB Copper, Dual Port82546GB Fiber, Dual Port82546GB SerDes, Dual Port82545EM Copper82545EM Fiber82545GM Copper82545GM Fiber82545GM SerDes82544EI Copper82544GC Copper82541EI Copper82541EI Mobile82541GI Copper82541GI Mobile82541ER Copper82541PI82540EM Mobile82540EP Mobile82540EP Desktop82540EM DesktopE%04X: (net)   TFTP: Received %s (%d KBytes)
%03d
Aborted

Giving up after %d DHCP requests
done
v4  Requesting information via DHCP%s:     v6ERROR: Unable to allocate memory
 Initializing NICCould not read MAC address  Reading MAC address from device: %02x:%02x:%02x:%02x:%02x:%02x
ERROR: Parameter string is too long.bootpdhcpipv6Could not get IP address  Using IPv4 address: %d.%d.%d.%d
  Using IPv6 address: %s
ARP request to TFTP server (%d.%d.%d.%d) failedCan't obtain TFTP server IP address  Requesting file "%s" via TFTP from %d.%d.%d.%d
  Requesting file "%s" via TFTP from Not enough memory for pxelinux config file buffer!system-id/Warning: UUID property is too short.No valid entries in pxelinux config file.  Not enough space for loading the initrd!linux,initrd-startlinux,initrd-endbootargsCould not initialize network device
ping device-path:[device-args,]server-ip,[client-ip[\nn]],[gateway-ip][,timeout]

  Reading MAC address from device: 
E3000: Could not read MAC address

E3006: Could not initialize network device
%02x:%02x:%02x:%02x:%02x:%02x

  DHCP: Could not get ip address
  Own IP address: %d.%d.%d.%d
  Netmask : %d.%d.%d.%d
  Ping to %d.%d.%d.%d success

  TFTP: Received %s (%d bytes)

                           

  TFTP error: %s
Failed to parse this line:
 %s
defaultlabelkernelinitrdappendCommand '%s' is not supported.
Error: pxelinux prefix is too long!Error: The bootfile string is too long for deriving the pxelinux.cfg file name from it.pxelinux.cfg/Trying pxelinux.cfg files...Error: pxelinux.cfg prefix + filename too long!01-%02x-%02x-%02x-%02x-%02x-%02x%02X%02X%02X%02XERROR: Assertion 'rc < cfgsize' failed!
(function %s, file /home/aik/p/qemu-slof/roms/SLOF/lib/libnet/pxelinux.c, line %i)
pxelinux_load_parse_cfgÿÿÿÿÿÿÿÿÿÿÿÿ:////:
ERROR:			Bad URL!

ERROR:			Bad host name!

ERROR:			Can't resolve domain name (DNS server is not presented)!

Giving up after %d DNS requests
  Requesting IP address via BOOTP:    %02d
Giving up after %d bootp requests
bladone
%d KBytesblksizeoctet  Receiving data:  
Repeating TFTP read request...
Lost ACK packets: %d

 unable to allocate memory, parsing failed
tftp://
 tftp missing in %s

 missing ] in %s

 missing filename in %s

 wrong format IPV6 address in %s

 missing . seperator in %s

 missing domain in %s

 DNS failed for IPV6
source route failednet unreachableprotocol unreachableport unreachablefragmentation needed and DF sethost unreachableunknown TFTP errorTFTP buffer of %d bytes is too small for %sfile not found: %sTFTP access violationillegal TFTP operationunknown TFTP transfer IDno such TFTP userTFTP blocksize negotiation failedfile exceeds maximum TFTP transfer sizeICMP ERROR "%s"TFTP error occurred after %d bad packets receivedTFTP error occurred after missing %d responsesTFTP error missing block %d, expected block was %d::::1%s%x%02x%s%x00:0:0:::0send_router_solicitation: Out of memory
send_neighbour_solicitation: Out of memory
send_neighbour_advertisement: Out of memory
%s%ifind-aliasOut of memory in find_aliaskey?cdromdisknetNo available boot devices!
Select boot device (or press '0' to abort):%c) %6s : %s
Spec ID Event03TCGBIOS: Failed to allocated %u bytes.
BAD ELF FILE: %sBooting BCV device 00h (Floppy)Booting BCV device 80h (HDD)MBRMBR PARTITION TABLES-CRTM Contents1. Clear TPM
2. Change active PCR banks

If not change is desired or if this menu was reached by mistake, press ESC to
continue the boot.
An error occurred clearing the TPM: 0x%x

Toggle active PCR banks by pressing number key

  %d: %s (enabled)
ESC: return to previous menu without changes
a  : activate selection
SHA1SHA256SHA384SHA512SM3-256SHA3-256SHA3-384SHA3-512git-dd0dcaa1c1085c15+@ÿÿÿÿ€&@	@	%s: Unable to allocate memory
%s: Could not get valid vtpm-unit
%s: CRQ: In failure mode
%s: CRQ registration failed
%s: Initializing CRQ failed
%s: Failure getting RTCE buffer size from CRQ
%s: RTCE buffer size of %u bytes is too small. Minimum is 1024 bytes.
%s: Could not allocate buffer of size %u.
%s: VTPM CRQ: In failure mode
%s: VTPM CRQ: Send buffer too large: %u > %u
spapr_vtpm_probespapr_vtpm_activatespapr_vtpm_get_paramsspapr_vtpm_senddataq°„€„€gE#ïÍ«‰˜ºÜþ2TvÃÒáðBŠ/˜q7D‘µÀûÏéµÛ¥9VÂ[Yññ’?‚¤«^Õت˜ƒ[$1…¾U}Ãr¾]t€Þ±þ›Ü§Á›ñtä›iÁï¾G†ÁÆ$¡Ì-é,oJt„ª\°©ÜvùˆÚ˜>QR¨1Æm°'È¿YÇÆàóÕ§‘GÊcQ))g'·
….!8M,müS8
e
sTvj
»ÂÉ.’r,…¢¿è¡¨fKÂK‹pÇlQ£Ñ’è֙$ô5…j p¤Á7l'HwL4°¼µ9³NتJ[œÊOh.oót‚îx¥co„ÈxŒÇ¾ÿú¤Plë¾ù£÷Æqxòj	æg»g®…<nór¥Oõ:QR›hŒƒÙ«[àÍBŠ/˜×(®"q7D‘#ïe͵ÀûÏìM;/éµÛ¥‰Û¼9VÂ[óHµ8Yññ¶Ð’?‚¤¯O›«^ÕÚmØª˜£Bƒ[Epo¾$1…¾N䲌U}ÃÕÿ´âr¾]tò{‰o€Þ±þ;–±›Ü§%Ç5Á›ñtÏi&”ä›iÁžñJÒï¾G†8O%ãÁÆ‹ŒÕµ$¡Ìw¬œe-é,oY+uJt„ªn¦äƒ\°©Ü½AûÔvùˆÚƒSµ˜>QRîfß«¨1Æm-´2°'Șû!?¿YǾïäÆàó=¨ÂÕ§‘G“
§%ÊcQà‚o))g
np'·
…FÒ/ü.!8\&É&M,müZÄ*íS8
•³ße
sT‹¯cÞvj
»<w²¨ÂÉ.Gí®æ’r,…‚5;¢¿è¡Lñd¨fK¼B0ÂK‹pÐø—‘ÇlQ£T¾0ђèÖïR֙$Ue©ô5…Wq *j p2»Ñ¸¤Á¸ÒÐÈ7lQA«S'HwLߎë™4°¼µá›H¨9³ÅÉZcNتJãAŠË[œÊOwcãsh.oóÖ²¸£t‚î]ï²üx¥coC/`„Èx¡ð«rŒÇd9쐾ÿú#c(¤Plëނ½é¾ù£÷²ÆyÆqxòãrS+Ê'>Îê&aœÑ†¸Ç!ÀÂêÚ}ÖÍàëõ}OînÑxðgªroº
c}ŢȘ¦?˜¾ù
®q5G(Ûwõ#}„2Ê«{@Ç$“<ž¾
ɾ¼CgĜ
LLÅÔ¾Ë>B¶Y)œüe~*_Ëo«:ÖúìlDŒJGXË»]ÁžØbš)*6|Õ‘YZ0pÝ/ìØ÷Y9g3&gÿÀ1Ž´J‡hXÛ.
dù§GµH¾úO¤j	ægó¼É»g®…„ʧ;<nórþ”ø+¥Oõ:_6ñQR­æ‚Ñ›hŒ+>lƒÙ«ûA½k[àÍ~!y0123456789abcdef0xÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
%(HEREDÂЫØCLIENT-ENTRY-POINTtÈ8¬ROMFS-LOOKUP-ENTRYts®NICEINIT
¬H¨+àQPHi(+àiH-à+àgà0®00H²x ¸HpMð® $(‡àEVALUATE
¬€ð%X+àO¸`O!T¨!+àOpH‡øMðNˆ$(%x ˆ`0#0ø(À¨˜Ø8`08#0ø¬0„è‹e€FORTH-WORDLISTÄe˜€LASTWORD
¬$(ð˜ðàBP´TIB	È@POCKETS	˜XEREGS
€xCIREGS
TCISTACK
(¨COMP-BUFFER	øÈPAFLOF-STARTøè
HEAP-STARTÈHEAP-END˜(	FDT-STARThH
ROMFS-BASE8hEPAPR-MAGICˆEPAPR-IMA-SIZE
بBRANCH
ŒÈ0BRANCH
L 
BREAKPOINT
 LITð DOTICKÀ8DUPPOVER`hPICK,€DROPœ˜SWAPh°>R,ÈR>ðàR@¼øRPICK¤ DEPTHˆ (DEPTH!T @RDEPTH XRDEPTH!Ü p+h -, ¨*ð ÀLSHIFT´ ØRSHIFTx ðASHIFT<!AND! ORÄ!8XORˆ!P@\!h!(!€C@ü!˜C!È!°W@œ!ÈW!h!àL@<!øL!"X@Ü"(X!¨"@UNALIGNED-W@t"XUNALIGNED-W!8"xUNALIGNED-L@"˜UNALIGNED-L!)D"¸<(ð"ØU<(¬"ð0<(|#=(8# 0=(#8DODO'¼#PDO?DO'd#hDOLOOP'#€DO+LOOP& #˜DOLEAVE&l#¸DO?LEAVE&#ØEXIT%ô#ø	SEMICOLON%Ì$EXECUTE%°$0MOVE$@$PRMOVE"0$hMRMOVE!ˆ$€RFILL!8$˜ZCOUNT `$°	HASH-SIZEt$ÈHASHt$ð
CLEAN-HASH ,%
HASH-TABLE -1tÿÿÿÿÿÿÿÿ%H0t%h1t%ˆ2t%¨3t%È4t%è8t&H#10t&(H#20t &HH#FFtÿ&hH#FFFFtÿÿ&ˆ
H#FFFFFFFFtÿÿÿÿ&¨D#10t
&Ð/Ct&ð/Wt'/Lt'0/Xt'P/Nt'pCELLt'/C*
¬' Ð$('°/W*
¬'  Ð$('à/L*
¬'@ Ð$((/X*
¬'` Ð$((@/N*
¬'€ Ð$((pCA+
¬'À  $(( WA+
¬'ð  $((ÐLA+
¬(   $()XA+
¬(P  $()0NA+
¬(€  $()`CA1+
¬'  $()WA1+
¬'   $()ÀLA1+
¬'@  $()ðXA1+
¬'`  $(* NA1+
¬'€  $(*PCHAR+
¬) $(*€CELL+
¬*`$(*¨CHAR-
¬' ¸$(*ÐCELL-
¬'€ ¸$(+CHARS
¬'À$(+0CELLS
¬(€$(+XCHARS+
¬(°$(+€CELLS+
¬)p$(+¨DOTO
¬ð*¸`Ø!x*¸!$(+ÐSLITERAL
¬ð*¸``!¨  0ÿÿÿÿÿÿÿø!0Ø$(,(?DUP
¬`ø`$(, TUCK
¬Àx$(,à2DUP
¬xx$(-3DUP
¬%¸%¸%¸$(-@2OVER
¬%ؐ%ؐ$(-2DROP
¬¨¨$(-Ð3DROP
¬¨¨¨$(.NIP
¬À¨$(.8CLEAR
¬%x P$(.hROT
¬ØÀðÀ$(.˜-ROT
¬ÀØÀð$(.Ø2SWAP
¬Ø.èð.è$(/2ROT
¬ØØ/(ðð/($(/XROLL
¬`,°ø0.¨Ø%˜ ¸Øÿÿÿÿÿÿÿ¸,°ø0ð.è%˜ ¸Øÿÿÿÿÿÿÿ¸$(/¨-ROLL
¬`,°øHØ.¨ðÀØ%˜ ¸Øÿÿÿÿÿÿÿ ,°ø0ðÀ%˜ ¸Øÿÿÿÿÿÿÿ¸$(0`2>R
¬ð.¨ØÀØØ$(102R>
¬ððð.¨ØÀ$(1€2R@
¬ðð xØ.¨ØÀ$(1Ð?PICK œ202*
¬%˜ è$(2HU2/
¬%˜!$(2x2/
¬%˜!$(2¨<<
¬ è$(2Ø>>
¬!$(3>>A
¬!$(3(INVERT
¬%X!`$(3PNOT
¬3`$(3€TRUEtÿÿÿÿÿÿÿÿ3¨FALSEt3È>
¬À"è$(3èU>
¬À#$(4<=
¬3ø#H$(4H<>
¬#0#H$(4x>=
¬"è#H$(4¨0<=
¬%x4X$(4Ø0<>
¬%x4ˆ$(50>
¬%x3ø$(580>=
¬%x4¸$(5hU<=
¬4(#H$(5˜U>=
¬##H$(5ÈWITHIN
¬.¨`.¨4¸ø-à3Ø$3øø3Ø$3¸$(5øBETWEEN
¬%˜  6$(6D2*
¬2Xx# ¸Ø2Xð$(6ÐUD2/
¬Ø2ˆ 0? è!Hð2ˆ$(7(D2/
¬Ø2ˆ 0? è!Hð2¸$(7NEGATE
¬%xÀ ¸$(7øABS
¬`#ø8$(80MAX
¬- "èøÀ¨$(8xUMAX
¬- #øÀ¨$(8ÈMIN
¬- 3øøÀ¨$(9U*
¬ Ð$(9h1+
¬%˜  $(91-
¬%˜ ¸$(9À2+
¬%¸  $(9ð2-
¬%¸ ¸$(: EVEN
¬9 %X!0$(:PBOUNDS
¬x  À$(:ˆS>D
¬`#$(:ÀDNEGATE
¬3`Ø8`#HðÀ ¸$(:ðDABS
¬`#ø;$(;XM+
¬ÀØ`Ø  `ð#ðÀ ¸$(; D+
¬Ø;°ð  $(<D-
¬;<($(<X*'
¬Ø`#Ø6àðø ;°ð$(<ˆUM*
¬%x.è0@%x#`<˜#ÿÿÿÿÿÿÿè¨$(=M*
¬- !`ØØ8@ð8@=ð#ø;$(=p/'
¬Ø`#Ø6àðx 5Ø!Hø0Ø%˜!Hð  ¸ð$(=øUM/MOD
¬0@%x#`>#ÿÿÿÿÿÿÿè¨À$(>°SM/REM
¬xØØ;h 8@>Àð#ø8ð#ø 8À8À$(?FM/MOD
¬`Ø- !`#Ø?(x5ð!0ø09ÐÀð  À$ð¨$(?ØU/MOD
¬%xÀ>À$(@ /MOD
¬Ø:Ðð?è$(@Ø/
¬@è.H$(AMOD
¬@è¨$(AH*/MOD
¬Ø=€ð?è$(Ax*/
¬Aˆ.H$(A¸WBSPLIT
¬`&x!0À&!$(AèLWSPLIT
¬`&˜!0À&8!$(B@XLSPLIT
¬`&À!0À&X!$(B˜LBSPLIT
¬BXØBðB$(BðXWSPLIT
¬B°ØBXðBX$(C@XBSPLIT
¬B°ØCðC$(CBWJOIN
¬& è!H$(CàWLJOIN
¬&8 è!H$(DBLJOIN
¬CðØCððD($(DPWBFLIP
¬BÀCð$(D˜LWFLIP
¬BXÀD($(DÐLXJOIN
¬&X è!H$(EXLFLIP
¬B°ÀE$(E@LBFLIP
¬CÀ/(ÀD`$(ExWXJOIN
¬D(ØD(ðE$(EÀXWFLIP
¬CXÀ/(ÀEÐ$(FBXJOIN
¬D`ØD`ðE$(FPXBFLIP
¬B°EˆÀEˆE$(F˜ALIGNED
¬'€9Ð  '€8!0$(FàI
¬ð ÀØ$(G8J
¬ððð ÀØÀØÀØ$(GxUNLOOP
¬ððð-àØ$(Gè+!
¬,ð!x  À!$(H0COMP"ØHxOFF
¬3ØÀ!$(HON
¬3¸À!$(HÈ<W@
¬!Ø`0€4¸ø0 ¸$(I2@
¬`*¸!xÀ!x$(Ip2!
¬`Ø!ð*¸!$(I¸WBFLIPS
¬:˜#x@GH!ØD¨GH!ð' #°ÿÿÿÿÿÿÿÀ$(JLWFLIPS
¬:˜#x@GH"DàGH" '@#°ÿÿÿÿÿÿÿÀ$(JˆLBFLIPS
¬:˜#x@GH"EˆGH" '@#°ÿÿÿÿÿÿÿÀ$(KXBFLIPS
¬:˜#x@GH"8F¨GH"P'`#°ÿÿÿÿÿÿÿÀ$(KˆXWFLIPS
¬:˜#x@GH"8FGH"P'`#°ÿÿÿÿÿÿÿÀ$(LXLFLIPS
¬:˜#x@GH"8EPGH"P'`#°ÿÿÿÿÿÿÿÀ$(LˆFILL#ŒMBLANK
¬0 M$(M ERASE
¬0M$(MXCATCHER
äM
ABORT"-STR
äM¸CATCH
¬ 8ØM¨!xØ hM¨!$HðM¨!ð¨%x$(MàTHROW
¬,°ø`M¨!x ˆðM¨!ðÀØ P¨ð$(NxABORT
¬%XNˆ$(O#TIB
äO@IBDO`#IB
äO€	SOURCE-IDDO SOURCE
¬OpO!x$(OÈ>IN
äPTERMINAL
¬P+àOpOP!xO!%x+àO¸$(P BLt P˜BELLtP¸BStPØCARRETt
PøLINEFEEDt
QEMIT´Q@CR´Q`TYPE
¬:˜#x(GH!¨QP#ÿÿÿÿÿÿÿØ$(Q€LL-CR
¬QQPQ0QP$(QàSPACE
¬P¨QP$(R SPACES
¬%x#xR0#ÿÿÿÿÿÿÿè$(RPCOUNT
¬`*À!¨$(R PACK
¬`Ø9 À` !À$`ð$(RàUPC
¬`0a0z6¨ø0  ¸$(SHLCC
¬`0A0Z6¨ø0   $(SÀKEY´T8KEY?´TXACCEPT´TxSPAN
äT˜EXPECT
¬TˆT¨!$(T¸REFILL
¬O¸#Hø8OØTÈ%xP!3¸$O¸%X#0ø3Ø$0eNˆ$(TðBASE
äU¸DECIMAL
¬&àUÈ!$(UØHEX
¬&8UÈ!$(VOCTAL
¬&UÈ!$(VPPAD
¬0  $(VˆTODIGIT
¬`0	3øø0'  00  $(VÈMU/MOD
¬`Ø@°ðÀØ>Àð$(WP<#
¬V˜`!$(W°HOLD
¬V˜`!x9Ð,ðÀ!!À$(WèSIGN
¬#ø0-Wø$(XH#
¬UÈ!xW`.¨VàWø$(X˜#S
¬X¨- !HøØÿÿÿÿÿÿÿÈ$(Xè#>
¬-àV˜`!x,ð ¸$(Y@(.)
¬WÀ`Ø8@%xXøðXXYP$(YU#
¬UÈ!x@°ÀVàWø$(YøU#S
¬Z`øØÿÿÿÿÿÿÿÐ$(ZHU#>
¬¨V˜`!x,ð ¸$(Z˜(U.)
¬WÀZXZ¨$(Zè.
¬Y QR0$([ S.
¬[0$([XU.
¬ZøQR0$([€.R
¬ÀY .¨- "èø(x ¸R`بQ$([¸U.R
¬ÀZø.¨- "èø(x ¸R`بQ$(\H.D
¬UÈ!xÀUð[0UÈ!$(\Ø.H
¬UÈ!xÀV([0UÈ!$(]0.S
¬ 8`#ø¨$%x#x@ 8GH ¸9А[0#ÿÿÿÿÿÿÿÀ$(]ˆ?
¬!x[0$(^8DIGIT
¬xSX`0A0Z6¨ø0 ¸00 ¸`.¨%xÀ6ø .H3¸Ø¨3Ø$(^h>NUMBER
¬`#Hø$x!¨UÈ!x^xø¸ÀØÀØØUÈ!x9xÀUÈ!x=.¨  ð%x<(ð*ð9ÐØÿÿÿÿÿÿþè¨$(_p$NUMBER
¬`#Hø ¨¨3¸$Ø`Ø!¨0-#0`øxð*ð9Ð`#Hø(¨¨¨3¸$ØØ%x%xðð_ˆ.H#Hø8¨Àø83Ø$¨¨¨3¸$(`¸ALLOT
¬  +à$(bˆ,
¬!'€b˜$(bÈC,
¬!À'b˜$(cW,
¬!ð' b˜$(cHL,
¬" '@b˜$(cˆX,
¬"P'`b˜$(cÈALIGN
¬'€9Ð!0ø %xcØÿÿÿÿÿÿÿ°$(dPLACE
¬- !À*À+@:˜#xH`!¨GH!À*%˜+@#°ÿÿÿÿÿÿÿ¸¨$(dxSTRING,
¬x9 +@b˜dˆ$(e(NOOP
¬$(°CURRENTDØe LAST
¬e¸*¸$(eÈSEARCH-ORDER
äØeøCONTEXTDff˜	LINK>NAME
¬*¸$(fÀNAME>
¬*`!¨9 +Fø$(fðLINK>
¬fØg$(g@NAME>STRING
¬*R°$(gpLATEST
äg¨(REVEAL)´gÈHEADER
¬deØ!xbØg¸!%xce@d$(gðREVEAL
¬g¸!xfØgˆgàg¸!xeØ!$(hh	STRING=CI ähÐ(FIND)´hð((FIND))
¬`øxØ-  fØgˆhèø-àð$ð!xØÿÿÿÿÿÿÿp.3Ø$(i(FIND-ORDER)
¬f°`Øf5Øø-  !x*¸!xi,°ø(.H.Hð¨$ð+Øÿÿÿÿÿÿÿ@ð.%x$(iØ($FIND)
¬ið`ø0fØ`gÀ!¨3¸$(jà$FIND
¬- jøø0¨.H.H3¸Ø3Ø$(kX
'IMMEDIATEtkÐ
IMMEDIATE?
¬kè!05$(kø	IMMEDIATE
¬eØ!x*¸`!¨kè!HÀ!À$(l8FINDCHAR
¬À%x#xÀxGH  !¨x`P¨#0ø4XØ#0ø0GHGø.H.H3¸$#ÿÿÿÿÿÿÿ@¨¨3Ø$(l¨PARSE
¬ØOpP!x  T¨!xP!x ¸- ðlÀø0.H`%˜  Ø`PH@$(mÈSKIPWS
¬OpT¨!x`P!x3øøpxP!x  !¨P¨4Xø(%˜PH@Øÿÿÿÿÿÿÿ`¨¨$(n¨
PARSE-WORD
¬n¸P¨mØ$(oWHICHPOCKET
äoÐPOCKET
¬poè!x0 Ð  oè!x%˜  `0#0ø¨%xoè!$(oøWORD
¬pØmØ` !À:˜ð`/(#x8*GH!¨x!À#ÿÿÿÿÿÿÿȨ$(pÀCHAR
¬o¨¨!¨$(q€(
¬0)mØ-à$(q¸\
¬P!x9ÐP!Q0mØ-à$(qøSTATE
ärX[
¬rhH $(rx]
¬0rh!$(r¨?COMP
¬rh!xø$0ÿÿÿÿÿÿÿzNˆ$(rèCOMPILE,
¬bØ$(sH:
¬o¨hH
¬s`r¸$(sx:NONAME
¬dH
¬s`r¸$(sÈ;
¬røH$(s`hxrˆ$(t C"
¬rø0"mØH,@s``c:˜#x(GH!¨c#ÿÿÿÿÿÿÿØd$(tpS"
¬rh!xø(t€HR°s`$0"mØ`Øp`ØÀ$`ðð$(u Z"
¬u0-   %xÀ!À¨$(uè."
¬rh!xø(u0HQs`$0"mØQ$(v@.(
¬0)mØQ$(vÈCOMPILE
¬ð*¸`!xs`Ø$(wTHERE
äw`+COMP
¬rh!x%˜rhH@ø$wp!à+àw 
¬$(w€-COMP
¬%XrhH@rh!xø$w $wp!x+àà$H$(x RESOLVE-ORIG
¬x*¸ ¸À!$(xÀAHEAD
¬wHØs`%xs`$(yIF
¬wHøs`%xs`$(ypTHEN
¬røxØx0$(yÈELSE
¬røHØs`%xs`ÀxØ$(zCASE
¬w%x$(zhENDCASE
¬røH¨s`,°ø(9ÐÀyØØÿÿÿÿÿÿÿÀx0$(z˜OF
¬rø9 ØHxs`H#0s`y€H¨s`ð$({(ENDOF
¬røØzð$({¸RESOLVE-DEST
¬*¸ ¸s`$({øBEGIN
¬w$(|@AGAIN
¬røHØs`|x0$(|pUNTIL
¬røHøs`|x0$(|ÀWHILE
¬røy€À$(}REPEAT
¬rø|€yØ$(}HLEAVES
ä}€RESOLVE-LOOP
¬}!x,°øP`!xÀx ¸À!Øÿÿÿÿÿÿÿ˜ ¸s`}!$(} DO
¬w}!xH#`s`%x}!$(~h?DO
¬w}!xH#xs`}!%xs`$(~ØLOOP
¬røH#s`}¸x0$(X+LOOP
¬røH#°s`}¸x0$(¨LEAVE
¬røH#Ðs`}!x}!s`$(ø?LEAVE
¬røH#ðs`}!x}!s`$(€hSAVE-SOURCE
¬ðOpØO!xØO¸ØT¨!xØP!xØØ$(€ØRESTORE-SOURCE
¬ððP!ðT¨!ð+àO¸ðO!ð+àOpØ$(xOK-STRok‚(ABORTED-STRAborted‚@
EXCEPTION-STRException #‚`UNKNOWN-STRUndefined word‚ˆHW-EXCEPTION-HANDLER´‚°SHOW-STACK?D‚à	SHOWSTACK
¬%X+à‚ø$(ƒNOSHOWSTACK
¬%x+à‚ø$(ƒHPRINT-STACK
¬‚øø(ØØ]˜ðð$(ƒˆPRINT-EXCEPTION
¬`0ÿÿÿÿÿÿÿ#0ø8H‚ R°QQp¨$`0#0ø¨$‚Ð$(ƒðPRINT-STATUS
¬R0`#Hø(ƒ H‚8Ø8`%X#0ø0H‚XR°QØP`0ÿÿÿÿÿÿÿþ#0ø8MÐ!xR°Q¨Ø„Qp$(„ÐCOMPILE-WORD
¬- jøøPlø .H.H$H$s`-à$- `Ðø Q0ÿÿÿÿÿÿÿNˆH0s`s`-à$(†INTERPRET-WORD
¬- jøø(¨.H.H$H$- `Ðø Q0ÿÿÿÿÿÿÿNˆØ-àð$(‡	INTERPRET
¬%xP!o¨`øPrh!xø†0؇0Øÿÿÿÿÿÿÿ-à$(XEVAL
¬p$(ˆ˜DOABORT"
¬Àø(MÐ!0ÿÿÿÿÿÿÿþNˆ¨$(ˆÀABORT"
¬t€HˆØs`$(‰0
UNDEFINED-STRundefined word ‰pSET-UNDEFINED-WORD
¬pØH‰ˆ`!¨9  À$` `!¨9   À` !¨   !À$`ð$(‰˜'
¬o¨kh#Hø ‰¸3¸ÀˆØ$(ŠˆQUIT
¬%x ˆrˆP8 8[00>QPR0UøPR0H‡øMð`„èøÿÿÿÿÿÿÿxØÿÿÿÿÿÿÿH$(ŠðMAP-FILE´‹È
UNMAP-FILE´‹ð
WRITE-FILE´ŒINCLUDED
¬‹à- ØØ:˜#x¨ð ÀØ  ¸ À- Q0lÀø.H`Øpð9 #°ÿÿÿÿÿÿÿXððŒ$(Œ@INCLUDE
¬o¨ŒX$(`$CREATE
¬hHÄs`He*¸s`hx$(˜CREATE
¬o¨°$(ŽDODOES>
¬ð*¸g¸!xgP*¸!$(Ž8DOES>
¬HŽPs`$(Ž˜CONSTANT
¬o¨hHts`s`hx$(ŽÐVALUE
¬o¨hHDs`s`hx$(0VARIABLE
¬o¨hH
äs`%xs`hx$(ˆBUFFER:
¬o¨hH
´s`b˜hx$(ðDEFER
¬o¨hH´s`HO s`hx$(PALIAS
¬o¨hH¤s`Š˜s`hx$(¸STRUCT
¬%x$(‘
END-STRUCT
¬¨$(‘@FIELD
¬o¨hHs`xbØ  hx$(‘pLITERAL
¬H0s`s`$(‘Ø	[COMPILE]
¬Š˜s`$(’ POSTPONE
¬o¨- jø#Hø ‰¸3¸ÀˆØl#Hø0HHs`s`Hs`s`-à$(’X[CHAR]
¬q‘ð$(“0[']
¬Š˜HHs`s`$(“`FIND
¬`R°jøøH.¨¨3¸Àlø8$3Ø$$(“¨TO
¬Š˜rh!xø(H+às`s`$*¸!$(”HBEHAVIOR
¬*¸!x$(”È>BODY
¬%¸+h  $(•BODY>
¬%¸+h ¸$(•8	RECURSIVE
¬hx$(•pRECURSE
¬g¸!xgPs`$(• d#
¬o¨UÈ!xØUðpðUÈ!$(•èh#
¬o¨UÈ!xØV(pðUÈ!$(–Po#
¬o¨UÈ!xØV`pðUÈ!$(–¸
hv-putchar4— 
hv-getchar—@
hv-hascharÌ—`
hv-reg-crq€—€hv-free-crqH— hv-send-crq—À
hv-put-tce¸—àcheck-and-patch-sc1¤˜hv-rtas-get˜(RB@„˜HRB!<˜`RW@˜xRW!À˜RL@Œ˜¨RL!D˜ÀRX@˜ØRX!̘ðhv-logical-memopl™hv-cas$™0hv-update-dth™Hget-print-versionð™hvirtio-setup-vdà™virtio-vring-size°™¸virtio-get-qsizep™àvirtio-get-config(švirtio-blk-initôš0virtio-blk-shutdownÀšXvirtio-blk-readdš€virtio-blk-writeš¨virtio-scsi-initôšÐvirtio-scsi-shutdownÀšøvirtio-scsi-sendH› virtio-fs-init¤›Hvirtio-fs-shutdownp›hvirtio-fs-load(›virtio-net-openø›°virtio-net-closeÄ›Øvirtio-net-readIœvirtio-net-writeHÈœ(virtio-serial-initH”œPvirtio-serial-shutdownH`œxvirtio-serial-putcharHœ virtio-serial-getcharGèœÈvirtio-serial-hascharG´œðUSB-OHCI-REGISTERGUSB-EHCI-REGISTERGl@USB-XHCI-REGISTERGHhUSB-HCD-INITGUSB-HCD-EXITFà°USB-HID-INITF¬ÐUSB-HID-EXITFxð
USB-READ-KEYBFDžUSB-KEY-AVAILABLEFž0USB-HUB-INITEÜžXUSB-MSC-INITE¨žxUSB-MSC-EXITEtž˜USB-TRANSFER-CTRLE(ž¸USB-TRANSFER-BULKD¸žà
bootmsg-cpD€Ÿbootmsg-warningD4Ÿ(
bootmsg-errorCôŸPbootmsg-debugcpC¨Ÿpbootmsg-setlevelChŸ˜bootmsg-nvupdateBôŸÀbootmsg-checklevelCŸè
ELF-LOAD-FILEBœ ELF-LOAD-FILE-TO-ADDRB8 0nvram-c@B Xnvram-c!A0 xnvram-w@AР˜nvram-w!@ô ¸nvram-l@Aœ Ønvram-l!@¸ ønvram-x@Al¡nvram-x!@|¡8internal-reset-nvram>˜¡Xnvram-debug>P¡€
wipe-nvram>t¡ get-nvram-partition@¡Àget-named-nvram-partition?¤¡ènew-nvram-partition?$¢increase-nvram-partition>¼¢@erase-nvram-partition;À¢pdelete-nvram-partition;d¢˜internal-get-env=¼¢Àinternal-add-env=(¢èinternal-del-env<°£internal-set-env<£8internal-nvram-init;£`get-nvram-base:Ô£ˆget-nvram-size:œ£¨get-flash-base:l£Èget-flash-size:<£èget-mbx-base:¤LIBVETH-OPEN9¤(
LIBVETH-CLOSE9\¤HLIBVETH-READ9¤h
LIBVETH-WRITE8ĤˆE1K-OPEN8p¤¨	E1K-CLOSE8<¤ÈE1K-READ7ü¤è	E1K-WRITE7¼¥
E1K-MAC-SETUP78¥(NET-LOAD6Ø¥HNET-PING6”¥h	boot-menu6p¥ˆ	tpm-start68¥¨tpm-finalize6¥Ètpm-leave-firmware5Ü¥ètpm-set-log-parameters5œ¦tpm-get-logsize4ô¦8tpm-add-event-separators4°¦`tpm-measure-bcv-mbr4`¦tpm-is-working4(¦¸tpm-measure-scrtm3ð¦Øtpm-driver-get-failure-reason5d§tpm-driver-set-failure-reason5,§0
tpm20-menu3̧`tpm-gpt-set-lba13ˆ§€tpm-gpt-add-entry3D§¨tpm-measure-gpt3§Ð tpm-hash-log-extend-event-buffer2§øtpm-2hash-ext-log2¨0HID0!1̨XHID0@1œ¨pHID1!1d¨ˆHID1@14¨ HID4!0ü¨¸HID4@0̨ÐHID5!0œ¨èHID5@0l©MSR@0©MSR!0<©0SDR1@/¬©HSDR1!/Ü©`PVR@/|©xPIR@/L©TBL@/©¨TBU@.ì©ÀDABR@.Œ©ØDABR!.¼©ðHIOR@.,ªHIOR!.\ª SPRG0@-̪8SPRG0!-üªPSPRG1@-lªhSPRG1!-œª€SPRG2@-ª˜SPRG2!-<ª°SPRG3@,¬ªÈSPRG3!,ܪàHSPRG0@,LªøHSPRG0!,|«HSPRG1@+ì«8HSPRG1!,«XDEC@)«xDEC!)À«MMCR0!+´«¨PMC1@+€«ÀICBI+@ JUMP-CLIENT+«ðCLIENTINTERFACE´P.WRITE-LOG-BYTE-ENTRYtĬ@WRITE-LOG-BYTE-ENTRY
¬¬`!x$(¬pCALL-C*`¬°
START-RTAS*´¬È
FLUSHCACHE)ð¬èBM-ALLOCATOR-INIT	P­BM-ALLOC	­0BM-FREEÈ­PCRASH+­pDAAR
äð­ˆDUMBER
¬­˜!x!À0­˜H@$(­¨BOOT-EXCEPTION-HANDLER´hex
' ll-cr to cr
get-flash-base VALUE flash-addr
get-nvram-base CONSTANT nvram-base
get-nvram-size CONSTANT nvram-size
0 CONSTANT default-hvtermno
4096 CONSTANT disp-size
CREATE prevga-disp-buf 4096 allot
0 value disp-ptr
true value store-prevga?
: store-to-disp-buffer         ( ch  --  )
prevga-disp-buf disp-ptr disp-size MOD + c!
disp-ptr 1 + to disp-ptr
;
: hvterm-emit
store-prevga? IF
dup store-to-disp-buffer
THEN
default-hvtermno SWAP hv-putchar
;
: hvterm-key?  default-hvtermno hv-haschar ;
: hvterm-key   BEGIN hvterm-key? UNTIL default-hvtermno hv-getchar ;
' hvterm-emit to emit
' hvterm-key  to key
' hvterm-key? to key?
: serial-emit hvterm-emit ;
: serial-key? hvterm-key? ;
: serial-key  hvterm-key  ;
clean-hash
: hash-find ( str len head -- 0 | link )
>r 2dup 2dup hash                  ( str len str len hash          R: head )
dup >r @ dup                       ( str len str len *hash *hash   R: head hash )
IF                                 ( str len str len *hash         R: head hash )
link>name name>string string=ci ( str len true|false            R: head hash )
dup 0=
IF
THEN
ELSE
nip nip                         ( str len 0                     R: head hash )
THEN
IF                                 \ hash found
2drop r> @ r> drop              (  *hash                        R: )
exit
THEN                               \ hash not found
r> r> swap >r ((find))             ( str len head                  R: hash=0 )
dup
IF
dup r> !                        ( link                          R: )
ELSE
r> drop                         ( 0                             R: )
THEN
;
: hash-reveal  hash off ;
' hash-reveal to (reveal)
' hash-find to (find)
: >name ( xt -- nfa ) \ note: still has the "immediate" field!
BEGIN char- dup c@ UNTIL ( @lastchar )
dup dup aligned - cell+ char- ( @lastchar lenmodcell )
dup >r -
BEGIN dup c@ r@ <> WHILE
cell- r> cell+ >r
REPEAT
r> drop char-
;
VARIABLE mask -1 mask !
: default-hw-exception s" Exception #" type . ;
' default-hw-exception to hw-exception-handler
: diagnostic-mode? false ;	\ 2B DOTICK'D later in envvar.fs
: memory-test-suite ( addr len -- fail? )
diagnostic-mode? IF
." Memory test mask value: " mask @ . cr
." No memory test suite currently implemented! " cr
THEN
false
;
: 0.r  0 swap <# 0 ?DO # LOOP #> type ;
: 2log ( n -- lb{n} )
8 cells 0 DO 1 rshift dup 0= IF drop i LEAVE THEN LOOP
;
: log2  ( n -- log2-n )
1- 2log 1+
;
CREATE $catpad 400 allot
: $cat ( str1 len1 str2 len2 -- str3 len3 )
>r >r dup >r $catpad swap move
r> dup $catpad + r> swap r@ move
r> + $catpad swap ;
: $cat-space ( str2 len2 str1 len1 -- "str1 str2" len1+len2+1 )
2dup + bl swap c! 1+ 2swap $cat
;
: $cathex ( str len val -- str len' )
(u.) $cat
;
: 2CONSTANT    CREATE , , DOES> [ here ] 2@ ;
CONSTANT <2constant>
: $2CONSTANT  $CREATE , , DOES> 2@ ;
: 2VARIABLE    CREATE 0 , 0 ,  DOES> ;
: (is-user-word) ( name-str name-len xt -- ) -rot $CREATE , DOES> @ execute ;
: zplace ( str len buf -- )  2dup + 0 swap c! swap move ;
: rzplace ( str len buf -- )  2dup + 0 swap rb! swap rmove ;
: strdup ( str len -- dupstr len ) here over allot swap 2dup 2>r move 2r> ;
: str= ( str1 len1 str2 len2 -- equal? )
rot over <> IF 3drop false ELSE comp 0= THEN ;
: from-cstring ( addr - len )
dup dup BEGIN c@ 0 <> WHILE 1 + dup REPEAT
swap -
;
: test-string ( param len -- true | false )
0 ?DO
dup i + c@                     \ Get character / byte at current index
dup 20 <  swap 7e >  OR IF     \ Is it out of range 32 to 126 (=ASCII)
drop FALSE UNLOOP EXIT      \ FALSE means: No ASCII string
THEN
LOOP
drop TRUE    \ Only ASCII found --> it is a string
;
: #aligned ( adr alignment -- adr' ) negate swap negate and negate ;
: #join  ( lo hi #bits -- x )  lshift or ;
: #split ( x #bits -- lo hi )  2dup rshift dup >r swap lshift xor r> ;
: /string ( str len u -- str' len' )
>r swap r@ chars + swap r> - ;
: skip ( str len c -- str' len' )
>r BEGIN dup WHILE over c@ r@ = WHILE 1 /string REPEAT THEN r> drop ;
: scan ( str len c -- str' len' )
>r BEGIN dup WHILE over c@ r@ <> WHILE 1 /string REPEAT THEN r> drop ;
: split ( str len char -- left len right len )
>r 2dup r> findchar IF >r over r@ 2swap r> 1+ /string ELSE 0 0 THEN ;
: rfindchar ( str len char -- offs true | false )
swap 1 - 0 swap do
over i + c@
over dup bl = if <= else = then if
2drop i dup dup leave
then
-1 +loop =
;
: rsplit ( str len char -- left len right len )
>r 2dup r> rfindchar IF >r over r@ 2swap r> 1+ /string ELSE 0 0 THEN ;
: left-parse-string ( str len char -- R-str R-len L-str L-len )
split 2swap ;
: replace-char ( str len chout chin -- )
>r -rot BEGIN 2dup 4 pick findchar WHILE tuck - -rot + r@ over c! swap REPEAT
r> 2drop 2drop
;
: \-to-/ ( str len -- str' len ) strdup 2dup [char] \ [char] / replace-char ;
: isdigit ( char -- true | false )
30 39 between
;
: $dh-number ( addr len -- true | number false )
base @ >r
decimal
dup 2 > IF
over dup c@ [char] 0 =
over 1 + c@ 20 or [char] x =
AND IF hex 2 + swap 2 - rot THEN drop
THEN
$number
r> base !
;
: //  dup >r 1- + r> / ; \ division, round up
: c@+ ( adr -- c adr' )  dup c@ swap char+ ;
: 2c@ ( adr -- c1 c2 )  c@+ c@ ;
: 4c@ ( adr -- c1 c2 c3 c4 )  c@+ c@+ c@+ c@ ;
: 8c@ ( adr -- c1 c2 c3 c4 c5 c6 c7 c8 )  c@+ c@+ c@+ c@+ c@+ c@+ c@+ c@ ;
: 4dup  ( n1 n2 n3 n4 -- n1 n2 n3 n4 n1 n2 n3 n4 )  2over 2over ;
: 4drop  ( n1 n2 n3 n4 -- )  2drop 2drop ;
: 5dup  ( 1 2 3 4 5 -- 1 2 3 4 5 1 2 3 4 5 )
4 pick 4 pick 4 pick 4 pick 4 pick ;
: 5drop 4drop drop ;
: 5nip
nip nip nip nip nip ;
: 6dup  ( 1 2 3 4 5 6 -- 1 2 3 4 5 6 1 2 3 4 5 6 )
5 pick 5 pick 5 pick 5 pick 5 pick 5 pick ;
: signed ( n1 -- n2 ) dup 80000000 and IF FFFFFFFF00000000 or THEN ;
: <l@ ( addr -- x ) l@ signed ;
: -leading  BEGIN dup WHILE over c@ bl <= WHILE 1 /string REPEAT THEN ;
: (parse-line)  skipws 0 parse ;
: hex-byte ( char0 char1 -- value true|false )
10 digit IF
swap 10 digit IF
4 lshift or true EXIT
ELSE
2drop 0
THEN
ELSE
drop
THEN
false EXIT
;
: parse-hexstring ( dst-adr -- dst-adr' )
[char] ) parse cr                 ( dst-adr str len )
bounds ?DO                        ( dst-adr )
i c@ i 1+ c@ hex-byte IF       ( dst-adr hex-byte )
>r dup r> swap c! 1+ 2      ( dst-adr+1 2 )
ELSE
drop 1                      ( dst-adr 1 )
THEN
+LOOP
;
: add-specialchar ( dst-adr special -- dst-adr' )
over c! 1+                        ( dst-adr' )
1 >in +!                          \ advance input-index
;
: parse-" ( dst-adr -- dst-adr' )
[char] " parse dup 3 pick + >r    ( dst-adr str len R: dst-adr' )
>r swap r> move r>                ( dst-adr' )
;
: (") ( dst-adr -- dst-adr' )
begin                             ( dst-adr )
parse-"                        ( dst-adr' )
>in @ dup span @ >= IF         ( dst-adr' >in-@ )
drop
EXIT
THEN
ib + c@
CASE
[char] ( OF parse-hexstring ENDOF
[char] " OF [char] " add-specialchar ENDOF
dup      OF EXIT ENDOF
ENDCASE
again
;
CREATE "pad 100 allot
: " ( [text<">< >] -- text-str text-len )
state @ IF                        \ compile sliteral, pstr into dict
"pad dup (") over -            ( str len )
['] sliteral compile, dup c,   ( str len )
bounds ?DO i c@ c, LOOP
align ['] count compile,
ELSE
pocket dup (") over -          \ Interpretation, put string
THEN                              \ in temp buffer
; immediate
: (cr carret emit ;
: $forget ( str len -- )
2dup last @            ( str len str len last-bc )
BEGIN
dup >r             ( str len str len last-bc R: last-bc )
cell+ char+ count  ( str len str len found-str found-len R: last-bc )
string=ci IF       ( str len R: last-bc )
r> @ last ! 2drop clean-hash EXIT ( -- )
THEN
2dup r> @ dup 0=   ( str len str len next-bc next-bc )
UNTIL
drop 2drop 2drop            \ clean hash table
;
: forget ( "old-name<>" -- )
parse-word $forget
;
: linked ( var -- )  here over @ , swap ! ;
HEX
VARIABLE wordlists  forth-wordlist wordlists !
: wordlist ( -- wid )  here wordlists linked 0 , ;
10 CONSTANT max-in-search-order	\ should define elsewhere
: also ( -- )  clean-hash  context dup cell+ dup to context  >r @ r> ! ;
: previous ( -- )  clean-hash  context cell- to context ;
: only ( -- )  clean-hash  search-order to context  ( minimal-wordlist search-order ! ) ;
: seal ( -- )  clean-hash  context @  search-order dup to context  ! ;
: get-order ( -- wid_n .. wid_1 n )
context >r search-order BEGIN dup r@ u<= WHILE
dup @ swap cell+ REPEAT r> drop
search-order - cell / ;
: set-order ( wid_n .. wid_1 n -- )	\ XXX: special cases for 0, -1
clean-hash  1- cells search-order + dup to context
BEGIN dup search-order u>= WHILE
dup >r ! r> cell- REPEAT drop ;
: get-current ( -- wid )  current ;
: set-current ( wid -- )  to current ;
: definitions ( -- )  context @ set-current ;
: VOCABULARY ( C: "name" -- ) ( -- )  CREATE wordlist drop  DOES> clean-hash  context ! ;
: FORTH ( -- )  clean-hash  forth-wordlist context ! ;
: .voc ( wid -- ) \ display name for wid \ needs work ( body> or something like that )
dup cell- @ ['] vocabulary ['] forth within IF
2 cells - >name name>string type ELSE u. THEN  space ;
: vocs ( -- ) \ display all wordlist names
cr wordlists BEGIN @ dup WHILE dup .voc REPEAT drop ;
: order ( -- )
cr ." context:  " get-order 0 ?DO .voc LOOP
cr ." current:  " get-current .voc ;
: voc-find ( wid -- 0 | link )
clean-hash  cell+ @ (find)  clean-hash ;
: (function) ;
defer (defer)
0 value (value)
0 constant (constant)
variable (variable)
create (create)
alias (alias) (function)
cell buffer: (buffer:)
' (function) @        \ ( <colon> )
' (function) cell + @ \ ( ... <semicolon> )
' (defer) @           \ ( ... <defer> )
' (value) @           \ ( ... <value> )
' (constant) @	      \ ( ... <constant> )
' (variable) @        \ ( ... <variable> )
' (create) @          \ ( ... <create> )
' (alias) @           \ ( ... <alias> )
' (buffer:) @         \ ( ... <buffer:> )
forget (function)
constant <buffer:>
constant <alias>
constant <create>
constant <variable>
constant <constant>
constant <value>
constant <defer>
constant <semicolon>
constant <colon>
' lit      constant <lit>
' sliteral constant <sliteral>
' 0branch  constant <0branch>
' branch   constant <branch>
' doloop   constant <doloop>
' dotick   constant <dotick>
' doto     constant <doto>
' do?do    constant <do?do>
' do+loop  constant <do+loop>
' do       constant <do>
' exit     constant <exit>
' doleave  constant <doleave>
' do?leave  constant <do?leave>
500 CONSTANT AVAILABLE-SIZE
4000 CONSTANT MIN-RAM-RESERVE \ prevent from using first pages
: MIN-RAM-SIZE         \ Initially available memory size
epapr-ima-size IF
epapr-ima-size
ELSE
20000000         \ assumed minimal memory size
THEN
;
MIN-RAM-SIZE CONSTANT MIN-RAM-SIZE
STRUCT
cell field available>address
cell field available>size
CONSTANT /available
CREATE available AVAILABLE-SIZE /available * allot available AVAILABLE-SIZE /available * erase
VARIABLE mem-pre-released 0 mem-pre-released !
: available>size@	available>size @ ;
: available>address@	available>address @ ;
: available>size!	available>size ! ;
: available>address!	available>address ! ;
: available! ( addr size available-ptr -- )
dup -rot available>size! available>address!
;
: available@ ( available-ptr -- addr size )
dup available>address@ swap available>size@
;
: (?available-segment<) ( start1 end1 start2 end2 -- true/false ) drop < nip ;
: (?available-segment>) ( start1 end1 start2 end2 -- true/false ) -rot 2drop > ;
: (?available-segment-#) ( start1 end1 start2 end2 -- true/false )
2dup 5 roll -rot                ( e1 s2 e2 s1 s2 e2 )
between >r between r> and not
;
: (find-available) ( addr addr+size-1 a-ptr a-size -- a-ptr' found )
?dup 0= IF -rot 2drop false EXIT THEN	\ Not Found
2dup 2/ dup >r /available * +
dup available>size@ 0= IF 2drop r> RECURSE EXIT THEN
dup >r available@
over + 1- 2>r 2swap
2dup 2r@ (?available-segment>) IF
2swap 2r> 2drop r>
/available + -rot r> - 1- nip RECURSE EXIT	\ Look Right
THEN
2dup 2r@ (?available-segment<) IF
2swap 2r> 2drop r>
2drop r> RECURSE EXIT	\ Look Left
THEN
2dup 2r@ (?available-segment-#) IF	\ Conflict - segments overlap
2r> 2r> 3drop 3drop 2drop
1212 throw
THEN
2r> 3drop 3drop r> r> drop	( a-ptr' -- )
dup available>size@ 0<>		( a-ptr' found -- )
;
: (find-available) ( addr size -- seg-ptr found )
over + 1- available AVAILABLE-SIZE ['] (find-available) catch IF
2drop 2drop 0 false
THEN
;
: dump-available ( available-ptr -- )
cr
dup available - /available / AVAILABLE-SIZE swap - 0 ?DO
dup available@ ?dup 0= IF
2drop UNLOOP EXIT
THEN
swap . . cr
/available +
LOOP
dup
;
: .available available dump-available ;
: (drop-available) ( available-ptr -- )
dup available - /available /	\ current element index
AVAILABLE-SIZE swap -		\ # of remaining elements
( first nelements ) 1- 0 ?DO
dup /available + dup available@
( current next next>address next>size ) ?dup 0= IF
2drop LEAVE \ NULL element - goto last copy
THEN
3 roll available!		( next )
LOOP
0 0 rot available!
;
: (stick-to-previous-available) ( addr size available-ptr -- naddr nsize nptr success )
dup available = IF
false EXIT		\ This was the first available segment
THEN
dup /available - dup available@
+ 4 pick = IF
nip	\ Drop available-ptr since we are going to previous one
rot drop	\ Drop start addr, we take the previous one
dup available@ 3 roll + rot true
ELSE
drop false
THEN
;
: (insert-available) ( available-ptr -- available-ptr )
dup				\ current element
dup available - /available /	\ current element index
AVAILABLE-SIZE swap -		\ # of remaining elements
dup 0<= 3 pick available>size@ 0= or IF
drop drop EXIT
THEN
over available@ rot
( first	first/=current/ first>address first>size nelements ) 1- 0 ?DO
2>r
/available + dup available@
2r> 4 pick available! dup 0= IF
rot /available + available!
UNLOOP EXIT
THEN
LOOP
( first next/=last/ last[0]>address last[0]>size ) ?dup 0<> IF
cr ." release error: available map overflow"
cr ." Dumping available property"
.available
cr ." No space for one before last entry:" cr swap . .
cr ." Dying ..." cr 123 throw
THEN
2drop
;
: insert-available ( addr size available-ptr -- addr size available-ptr )
dup available>address@ 0<> IF
dup available>address@ rot dup -rot -
3 pick = IF	\ if (available>address@ - size == addr)
over available>size@ + swap
(stick-to-previous-available) IF
dup /available + (drop-available)
THEN
ELSE
swap (stick-to-previous-available)
not IF (insert-available) THEN
THEN
ELSE
(stick-to-previous-available) drop
THEN
;
defer release
: drop-available ( addr size available-ptr -- addr )
dup >r available@
over 4 pick swap - ?dup 0<> IF
dup 3 roll swap r> available! -
over - ?dup 0= IF
drop
ELSE
swap 2 pick + swap release
THEN
ELSE
nip ( req_addr req_size segment_size )
over - ?dup 0= IF
drop r> (drop-available)
ELSE
-rot over + rot r> available!
THEN
THEN
;
: pwr2roundup ( value -- pwr2value )
dup CASE
0 OF EXIT ENDOF
1 OF EXIT ENDOF
ENDCASE
dup 1 DO drop i dup +LOOP
dup +
;
: (claim-best-fit) ( len align -- len base )
pwr2roundup 1- -1 -1
available AVAILABLE-SIZE /available * + available DO
i		\ Must be saved now, before we use Return stack
-rot >r >r swap >r
available@ ?dup 0= IF drop r> r> r> LEAVE THEN		\ EOL
2 pick - dup 0< IF
2drop			\ Can't Fit: Too Small
ELSE
dup 2 pick r@ and - 0< IF
2drop		\ Can't Fit When Aligned
ELSE
r> -rot dup r@ U< IF
2r> 2drop
swap 2 pick + 2 pick invert and >r >r >r
ELSE
2drop >r
THEN
THEN
THEN
r> r> r>
/available +LOOP
-rot 2drop	( len best-fit-base/or -1 if none found/ )
;
: (adjust-release0) ( 0 size -- addr' size' )
2dup MIN-RAM-SIZE dup 3 roll + -rot -
dup 0< IF 2drop ELSE
2swap 2drop 0 mem-pre-released !
THEN
;
: claim ( [ addr ] len align -- base )
?dup 0<> IF
(claim-best-fit) dup -1 = IF
2drop cr ." claim error : aligned allocation failed" cr
." available:" cr .available
321 throw EXIT
THEN
swap
THEN
2dup (find-available) not IF
drop
2drop
321 throw EXIT
THEN
( req_addr req_size available-ptr ) drop-available
;
: .release ( addr len -- )
over 0= mem-pre-released @ and IF (adjust-release0) THEN
2dup (find-available) IF
drop swap
cr ." release error: region " . ." , " . ." already released" cr
ELSE
?dup 0= IF
swap 
cr ." release error: Bad/conflicting region " . ." , " .
." or available list full " cr
ELSE
( addr size available-ptr ) insert-available
( addr size available-ptr ) available!
THEN
THEN
;
' .release to release
0 MIN-RAM-SIZE release 1 mem-pre-released !
0 MIN-RAM-RESERVE 0 ' claim CATCH IF ." claim failed!" cr 2drop THEN drop
paflof-start ffff not and 1f00000 0 ' claim CATCH IF
." claim failed!" cr 2drop
THEN drop
heap-end heap-start - log2 1+ CONSTANT (max-heads#)
CREATE heads (max-heads#) cells allot
heads (max-heads#) cells erase
: size>head  ( size -- headptr )  log2 3 max cells heads + ;
: alloc-mem  ( len -- a-addr )
dup 0= IF EXIT THEN
1 over log2 3 max                   ( len 1 log_len )
dup (max-heads#) >= IF cr ." Out of internal memory." cr 3drop 0 EXIT THEN
lshift >r                           ( len  R: 1<<log_len )
size>head dup @ IF
dup @ dup >r @ swap ! r> r> drop EXIT
THEN                                ( headptr  R: 1<<log_len)
r@ 2* recurse dup                   ( headptr a-addr2 a-addr2  R: 1<<log_len)
dup 0= IF r> 2drop 2drop 0 EXIT THEN
r> + >r 0 over ! swap ! r>
;
: free-mem  ( a-addr len -- )
dup 0= IF 2drop EXIT THEN size>head 2dup @ swap ! !
;
: #links  ( a -- n )
@ 0 BEGIN over WHILE 1+ swap @ swap REPEAT nip
;
: .free  ( -- )
0 (max-heads#) 0 DO
heads i cells + #links dup IF
cr dup . ." * " 1 i lshift dup . ." = " * dup .
THEN
+
LOOP
cr ." Total " .
;
heap-start heap-end heap-start - free-mem
false VALUE debug-find-component?
VARIABLE device-tree
VARIABLE current-node
: get-node  current-node @ dup 0= ABORT" No active device tree node" ;
STRUCT
cell FIELD node>peer
cell FIELD node>parent
cell FIELD node>child
cell FIELD node>properties \ points to wid (grep wid>names)
cell FIELD node>words
cell FIELD node>instance-template
cell FIELD node>instance-size
cell FIELD node>space?
cell FIELD node>space
cell FIELD node>addr1
cell FIELD node>addr2
cell FIELD node>addr3
END-STRUCT
: find-method ( str len phandle -- false | xt true )
node>words @ voc-find dup IF link> true THEN ;
0 VALUE my-self
400 CONSTANT max-instance-size
STRUCT
/n FIELD instance>node
/n FIELD instance>parent
/n FIELD instance>args
/n FIELD instance>args-len
/n FIELD instance>size
/n FIELD instance>#units
/n FIELD instance>unit1          \ For instance-specific "my-unit"
/n FIELD instance>unit2
/n FIELD instance>unit3
/n FIELD instance>unit4
CONSTANT /instance-header
: >instance  ( offset -- myself+offset )
my-self 0= ABORT" No instance!"
dup my-self instance>size @ >= ABORT" Instance access out of bounds!"
my-self +
;
: (create-instance-var) ( initial-value -- )
get-node
dup node>instance-size @ cell+ max-instance-size
>= ABORT" Instance is bigger than max-instance-size!"
dup node>instance-template @      ( iv phandle tmp-ih )
swap node>instance-size dup @     ( iv tmp-ih *instance-size instance-size )
dup ,                             \ compile current instance ptr
swap 1 cells swap +!              ( iv tmp-ih instance-size )
+ !
;
: create-instance-var ( "name" initial-value -- )
CREATE (create-instance-var) PREVIOUS
;
: (create-instance-buf) ( buffersize -- )
aligned                               \ align size to multiples of cells
dup get-node node>instance-size @ +   ( buffersize' newinstancesize )
max-instance-size > ABORT" Instance is bigger than max-instance-size!"
get-node node>instance-template @  get-node node>instance-size @ +
over erase                            \ clear according to IEEE 1275
get-node node>instance-size @         ( buffersize' old-instance-size )
dup ,                                 \ compile current instance ptr
+ get-node node>instance-size !       \ store new size
;
: create-instance-buf ( "name" buffersize -- )
CREATE (create-instance-buf) PREVIOUS
;
VOCABULARY instance-words  ALSO instance-words DEFINITIONS
: VARIABLE  0 create-instance-var DOES> [ here ] @ >instance ;
: VALUE       create-instance-var DOES> [ here ] @ >instance @ ;
: DEFER     0 create-instance-var DOES> [ here ] @ >instance @ execute ;
: BUFFER:     create-instance-buf DOES> [ here ] @ >instance ;
PREVIOUS DEFINITIONS
CONSTANT <instancebuffer>
CONSTANT <instancedefer>
CONSTANT <instancevalue>
CONSTANT <instancevariable>
: (instance?) ( xt -- xt true|false )
dup @ <create> = IF
dup cell+ @ cell+ @ ['] >instance =
ELSE
false
THEN
;
: (doito) ( value R:*CFA -- )
r> cell+ dup >r
@ cell+ cell+ @ >instance !
;
' (doito) CONSTANT <(doito)>
: to ( value wordname<> -- )
' (instance?)
state @ IF
IF ['] (doito) ELSE ['] DOTO THEN
, , EXIT
THEN
IF
cell+ cell+ @ >instance ! \ interp mode instance value
ELSE
cell+ !                   \ interp mode normal value
THEN
; IMMEDIATE
: behavior  ( defer-xt -- contents-xt )
dup cell+ @ <instancedefer> = IF   \ Is defer-xt an INSTANCE DEFER ?
2 cells + @ >instance @
ELSE
behavior
THEN
;
: INSTANCE  ALSO instance-words ;
: my-parent  my-self instance>parent @ ;
: my-args    my-self instance>args 2@ swap ;
: set-my-args   ( old-addr len -- )
dup alloc-mem                   \ allocate space for new args ( old-addr len new-addr )
2dup my-self instance>args 2!   \ write into instance struct  ( old-addr len new-addr )
swap move                       \ and copy the args           ( )
;
: create-instance-data ( -- instance )
get-node dup node>instance-template @    ( phandle instance-template )
swap node>instance-size @                ( instance-template instance-size )
dup >r
dup alloc-mem dup >r swap move r>        ( instance )
dup instance>size r> swap !              \ Store size for destroy-instance
dup instance>#units 0 swap !             \ Use node unit by default
;
: create-instance ( -- )
my-self create-instance-data
dup to my-self instance>parent !
get-node my-self instance>node !
;
: destroy-instance ( instance -- )
dup instance>args @ ?dup IF               \ Free instance args?
over instance>args-len @  free-mem
THEN
dup instance>size @  free-mem
;
: ihandle>phandle ( ihandle -- phandle )
dup 0= ABORT" no current instance" instance>node @
;
: push-my-self ( ihandle -- )  r> my-self >r >r to my-self ;
: pop-my-self ( -- )  r> r> to my-self >r ;
: call-package  push-my-self execute pop-my-self ;
: $call-static ( ... str len node -- ??? )
find-method IF execute ELSE -1 throw THEN
;
: $call-my-method  ( str len -- )
my-self ihandle>phandle $call-static
;
: $call-method  ( str len ihandle -- )
push-my-self
['] $call-my-method CATCH ?dup IF
pop-my-self THROW
THEN
pop-my-self
;
0 VALUE calling-child
: $call-parent
my-self ihandle>phandle TO calling-child
my-parent $call-method
0 TO calling-child
;
: create-node ( parent -- new )
max-instance-size alloc-mem        ( parent instance-mem )
dup max-instance-size erase >r     ( parent  R: instance-mem )
align wordlist >r wordlist >r      ( parent  R: instance-mem wl wl )
here                               ( parent new  R: instance-mem wl wl )
0 , swap , 0 ,                     \ Set node>peer, node>parent & node>child
r> , r> ,                          \ Set node>properties & node>words to wl
r> , /instance-header ,            \ Set instance-template & instance-size
FALSE , 0 ,                        \ Set node>space? and node>space
0 , 0 , 0 ,                        \ Set node>addr*
;
: peer    node>peer   @ ;
: parent  node>parent @ ;
: child   node>child  @ ;
: peer  dup IF peer ELSE drop device-tree @ THEN ;
: link ( new head -- ) \ link a new node at the end of a linked list
BEGIN dup @ WHILE @ REPEAT ! ;
: link-node ( parent child -- )
swap dup IF node>child link ELSE drop device-tree ! THEN ;
: set-node ( phandle -- )
current-node @ IF previous THEN
dup current-node !
?dup IF node>words @ also context ! THEN
definitions ;
: get-parent  get-node parent ;
: new-node ( -- phandle ) \ active node becomes new node's parent;
current-node @ dup create-node
tuck link-node dup set-node ;
: finish-node ( -- )
get-node parent set-node
;
: device-end ( -- )  0 set-node ;
CREATE $indent 100 allot  VARIABLE indent 0 indent !
true value encode-first?
: decode-int  over >r 4 /string r> 4c@ swap 2swap swap bljoin ;
: decode-64 decode-int -rot decode-int -rot 2swap swap lxjoin ;
: decode-string ( prop-addr1 prop-len1 -- prop-addr2 prop-len2 str len )
dup 0= IF 2dup EXIT THEN \ string properties with zero length
over BEGIN dup c@ 0= IF 1+ -rot swap 2 pick over - rot over - -rot 1-
EXIT THEN 1+ AGAIN ;
: (prune) ( name len head -- )
dup >r (find) ?dup IF r> BEGIN dup @ WHILE 2dup @ = IF
>r @ r> ! EXIT THEN @ REPEAT 2drop ELSE r> drop THEN ;
: prune ( name len -- )  last (prune) ;
: set-property ( data dlen name nlen phandle -- )
true to encode-first?
get-current >r  node>properties @ set-current
2dup prune  $2CONSTANT  r> set-current ;
: delete-property ( name nlen -- )
get-node get-current >r  node>properties @ set-current
prune r> set-current ;
: property ( data dlen name nlen -- )  get-node set-property ;
: get-property ( str len phandle -- true | data dlen false )
?dup 0= IF cr cr cr ." get-property for " type ."  on zero phandle"
cr cr true EXIT THEN
node>properties @ voc-find dup IF link> execute false ELSE drop true THEN ;
: get-package-property ( str len phandle -- true | data dlen false )
get-property ;
: get-my-property ( str len -- true | data dlen false )
my-self ihandle>phandle get-property ;
: get-parent-property ( str len -- true | data dlen false )
my-parent ihandle>phandle get-property ;
: get-inherited-property ( str len -- true | data dlen false )
my-self ihandle>phandle
BEGIN
3dup get-property 0= IF
rot drop rot drop rot drop false EXIT
THEN
parent dup 0= IF
3drop true EXIT
THEN
AGAIN
;
20 CONSTANT indent-prop
: .prop-int ( str len -- )
space
400 min 0
?DO
i over + dup                                 ( str act-addr act-addr )
c@ 2 0.r 1+ dup c@ 2 0.r 1+ dup c@ 2 0.r 1+ c@ 2 0.r ( str )
i c and c = IF                           \ check for multipleof 16 bytes
cr indent @ indent-prop + 1+ 0        \ linefeed + indent
DO
space                              \ print spaces
LOOP
ELSE
space space                           \ print two spaces
THEN
4 +LOOP
drop
;
: .prop-bytes ( str len -- )
2dup -4 and .prop-int                       ( str len )
dup 3 and dup IF                            ( str len len%4 )
>r -4 and + r>                           ( str' len%4 )
bounds                                   ( str' str'+len%4 )
DO
i c@ 2 0.r                            \ Print last 3 bytes
LOOP
ELSE
3drop
THEN
;
: .prop-string ( str len )
2dup space type
cr indent @ indent-prop + 0 DO space LOOP   \ Linefeed
.prop-bytes
;
: .propbytes ( xt -- )
execute dup
IF
over cell- @ execute
ELSE
2drop
THEN
;
: .property ( lfa -- )
cr indent @ 0
?DO
space
LOOP
link> dup >name name>string 2dup type nip ( len )
indent-prop swap -                        ( xt 20-len )
dup 0< IF drop 0 THEN 0                   ( xt number-of-space 0 )
?DO
space
LOOP
.propbytes
;
: (.properties) ( phandle -- )
node>properties @ cell+ @ BEGIN dup WHILE dup .property @ REPEAT drop ;
: .properties ( -- )
get-node (.properties) ;
: next-property ( str len phandle -- false | str' len' true )
?dup 0= IF device-tree @ THEN  \ XXX: is this line required?
node>properties @
>r 2dup 0= swap 0= or IF 2drop r> cell+ ELSE r> voc-find THEN
@ dup IF link>name name>string true THEN ;
: encode-start ( -- prop 0 )
['] .prop-int compile,
false to encode-first?
here 0
;
: encode-int ( val -- prop prop-len )
encode-first? IF
['] .prop-int compile,             \ Execution token for print
false to encode-first?
THEN
here swap lbsplit c, c, c, c, /l
;
: encode-bytes ( str len -- prop-addr prop-len )
encode-first? IF
['] .prop-bytes compile,           \ Execution token for print
false to encode-first?
THEN
here over 2dup 2>r allot swap move 2r>
;
: encode-string ( str len -- prop-addr prop-len )
encode-first? IF
['] .prop-string compile,          \ Execution token for print
false to encode-first?
THEN
encode-bytes 0 c, char+
;
: encode+ ( prop1-addr prop1-len prop2-addr prop2-len -- prop-addr prop-len )
nip + ;
: encode-int+  encode-int encode+ ;
: encode-64    xlsplit encode-int rot encode-int+ ;
: encode-64+   encode-64 encode+ ;
: device-name  encode-string s" name"        property ;
: device-type  encode-string s" device_type" property ;
: model        encode-string s" model"       property ;
: compatible   encode-string s" compatible"  property ;
: #address-cells  s" #address-cells" rot parent get-property
ABORT" parent doesn't have a #address-cells property!"
decode-int nip nip
;
: my-#address-cells  ( -- #address-cells )
get-node #address-cells
;
: child-#address-cells  ( -- #address-cells )
s" #address-cells" get-node get-property
ABORT" node doesn't have a #address-cells property!"
decode-int nip nip
;
: child-#size-cells  ( -- #address-cells )
s" #size-cells" get-node get-property
ABORT" node doesn't have a #size-cells property!"
decode-int nip nip
;
: encode-phys  ( phys.hi ... phys.low -- prop len )
encode-first?  IF  encode-start  ELSE  here 0  THEN
my-#address-cells 0 ?DO rot encode-int+ LOOP
;
: encode-child-phys  ( phys.hi ... phys.low -- prop len )
encode-first?  IF  encode-start  ELSE  here 0  THEN
child-#address-cells 0 ?DO rot encode-int+ LOOP
;
: encode-child-size  ( size.hi ... size.low -- prop len )
encode-first? IF  encode-start  ELSE  here 0  THEN
child-#size-cells 0 ?DO rot encode-int+ LOOP
;
: decode-phys
my-#address-cells BEGIN dup WHILE 1- >r decode-int r> swap >r REPEAT drop
my-#address-cells BEGIN dup WHILE 1- r> swap REPEAT drop ;
: decode-phys-and-drop
my-#address-cells BEGIN dup WHILE 1- >r decode-int r> swap >r REPEAT 3drop
my-#address-cells BEGIN dup WHILE 1- r> swap REPEAT drop ;
: reg  >r encode-phys r> encode-int+ s" reg" property ;
: >space    node>space @ ;
: >space?   node>space? @ ;
: >address  dup >r #address-cells dup 3 > IF r@ node>addr3 @ swap THEN
dup 2 > IF r@ node>addr2 @ swap THEN
1 > IF r@ node>addr1 @ THEN r> drop ;
: >unit     dup >r >address r> >space ;
: (my-phandle)  ( -- phandle )
my-self ?dup IF
ihandle>phandle
ELSE
get-node dup 0= ABORT" no active node"
THEN
;
: my-space ( -- phys.hi )
(my-phandle) >space
;
: my-address  (my-phandle) >address ;
: my-unit
my-self instance>#units @ IF
0 my-self instance>#units @ 1- DO
my-self instance>unit1 i cells + @
-1 +LOOP
ELSE
my-self ihandle>phandle >unit
THEN
;
: my-unit-64 ( -- phys.lo+1|phys.lo )
my-unit                                ( phys.lo ... phys.hi )
(my-phandle) #address-cells            ( phys.lo ... phys.hi #ad-cells )
CASE
1   OF EXIT ENDOF
2   OF lxjoin EXIT ENDOF
3   OF drop lxjoin EXIT ENDOF
dup OF 2drop lxjoin EXIT ENDOF
ENDCASE
;
: set-space    get-node dup >r node>space ! true r> node>space? ! ;
: set-address  my-#address-cells 1 ?DO
get-node node>space i cells + ! LOOP ;
: set-unit     set-space set-address ;
: set-unit-64 ( phys.lo|phys.hi -- )
my-#address-cells 2 <> IF
." set-unit-64: #address-cells <> 2 " abort
THEN
xlsplit set-unit
;
: set-args ( arg-str len unit-str len -- )
s" decode-unit" get-parent $call-static set-unit set-my-args
;
: $cat-unit
dup parent 0= IF drop EXIT THEN
dup >space? not IF drop EXIT THEN
dup >r >unit s" encode-unit" r> parent $call-static
dup IF
dup >r here swap move s" @" $cat here r> $cat
ELSE
2drop
THEN
;
: $cat-instance-unit
dup parent 0= IF drop EXIT THEN
dup instance>#units @ 0= IF
ihandle>phandle $cat-unit
EXIT
THEN
dup >r push-my-self
['] my-unit CATCH IF pop-my-self r> drop EXIT THEN
pop-my-self
s" encode-unit"
r> ihandle>phandle parent
$call-static
dup IF
dup >r here swap move s" @" $cat here r> $cat
ELSE
2drop
THEN
;
: node>name  dup >r s" name" rot get-property IF r> (u.) ELSE 1- r> drop THEN ;
: node>qname dup node>name rot ['] $cat-unit CATCH IF drop THEN ;
: node>path
here 0 rot
BEGIN dup WHILE dup parent REPEAT
2drop
dup 0= IF [char] / c, THEN
BEGIN
dup
WHILE
[char] / c, node>qname here over allot swap move
REPEAT
drop here 2dup - allot over -
;
: interposed? ( ihandle -- flag )
dup instance>parent @ dup 0= IF 2drop false EXIT THEN
ihandle>phandle swap ihandle>phandle parent <> ;
: instance>qname
dup >r interposed? IF s" %" ELSE 0 0 THEN
r@ dup ihandle>phandle node>name
rot ['] $cat-instance-unit CATCH IF drop THEN
$cat r> instance>args 2@ swap
dup IF 2>r s" :" $cat 2r> $cat ELSE 2drop THEN
;
: instance>qpath \ With interposed nodes.
here 0 rot BEGIN dup WHILE dup instance>parent @ REPEAT 2drop
dup 0= IF [char] / c, THEN
BEGIN dup WHILE [char] / c, instance>qname here over allot swap move
REPEAT drop here 2dup - allot over - ;
: instance>path \ Without interposed nodes.
here 0 rot BEGIN dup WHILE
dup interposed? 0= IF dup THEN instance>parent @ REPEAT 2drop
dup 0= IF [char] / c, THEN
BEGIN dup WHILE [char] / c, instance>qname here over allot swap move
REPEAT drop here 2dup - allot over - ;
: .node  node>path type ;
: pwd  get-node .node ;
: .instance instance>qpath type ;
: .chain    dup instance>parent @ ?dup IF recurse THEN
cr dup . instance>qname type ;
defer find-node
: set-alias ( alias-name len device-name len -- )
encode-string
2swap s" /aliases" find-node ?dup IF
set-property
ELSE
4drop
THEN
;
: find-alias ( alias-name len -- false | dev-path len )
s" /aliases" find-node dup IF
get-property 0= IF 1- dup 0= IF nip THEN ELSE false THEN
THEN
;
: .alias ( alias-name len -- )
find-alias dup IF type ELSE ." no alias available" THEN ;
: (.print-alias) ( lfa -- )
link> dup >name name>string
2dup s" name" string=ci IF 2drop drop
ELSE cr type space ." : " execute type
THEN ;
: (.list-alias) ( phandle -- )
node>properties @ cell+ @ BEGIN dup WHILE dup (.print-alias) @ REPEAT drop ;
: list-alias ( -- )
s" /aliases" find-node dup IF (.list-alias) THEN ;
d# 10 CONSTANT MAX-ALIAS
1 VALUE alias-ind
: get-next-alias ( $alias-name -- $next-alias-name|FALSE )
2dup find-alias IF
drop
1 TO alias-ind
BEGIN
2dup alias-ind $cathex 2dup find-alias
WHILE
drop 2drop
alias-ind 1 + TO alias-ind
alias-ind MAX-ALIAS = IF
2drop FALSE EXIT
THEN
REPEAT
strdup 2swap 2drop
THEN
;
: devalias ( "{alias-name}<>{device-specifier}<cr>" -- )
parse-word parse-word dup IF set-alias
ELSE 2drop dup IF .alias
ELSE 2drop list-alias THEN THEN ;
: sub-alias ( arg-str arg-len -- arg' len' | false )
2dup
2dup [char] / findchar ?dup IF ELSE 2dup [char] : findchar THEN
( a l a l [p] -1|0 ) IF nip dup ELSE 2drop 0 THEN >r
find-alias ?dup IF ( a l a' p' -- R:p | a' l' -- R:0 )
r@ IF
2swap r@ - swap r> + swap $cat strdup ( a" l-p+p' -- )
ELSE
( a' l' -- R:0 ) r> drop ( a' l' -- )
THEN
ELSE
( a l -- R:p | -- R:0 ) r> IF 2drop THEN
false ( 0 -- )
THEN
;
: de-alias ( arg-str arg-len -- arg' len' )
BEGIN
over c@ [char] / <> dup IF drop 2dup sub-alias ?dup THEN
WHILE
2swap 2drop
REPEAT
;
: +indent ( not-last? -- )
IF s" |   " ELSE s"     " THEN $indent indent @ + swap move 4 indent +! ;
: -indent ( -- )  -4 indent +! ;
: ls-phandle ( node -- )  . ." :  " ;
: ls-node ( node -- )
cr dup ls-phandle
$indent indent @ type
dup peer IF ." |-- " ELSE ." +-- " THEN
node>qname type
;
: (ls) ( node -- )
child BEGIN dup WHILE dup ls-node dup child IF
dup peer +indent dup recurse -indent THEN peer REPEAT drop ;
: ls ( -- )
get-node cr
dup ls-phandle
dup node>path type
(ls)
0 indent !
;
: show-devs ( {device-specifier}<eol> -- )
skipws 0 parse dup IF de-alias ELSE 2drop s" /" THEN   ( str len )
find-node dup 0= ABORT" No such device path" (ls)
;
VARIABLE interpose-node
2VARIABLE interpose-args
: interpose ( arg len phandle -- )  interpose-node ! interpose-args 2! ;
0 VALUE user-instance-#units
CREATE user-instance-units 4 cells allot
: copy-instance-unit  ( -- )
user-instance-#units IF
user-instance-#units my-self instance>#units !
user-instance-units my-self instance>unit1 user-instance-#units cells move
0 to user-instance-#units
THEN
;
: open-node ( arg len phandle -- ihandle|0 )
current-node @ >r  my-self >r            \ Save current node and instance
set-node create-instance set-my-args
copy-instance-unit
s" open" get-node find-method IF execute ELSE TRUE THEN
0= IF
my-self destroy-instance 0 to my-self
THEN
my-self                                  ( ihandle|0 )
r> to my-self  r> set-node               \ Restore current node and instance
interpose-node @ IF
my-self >r to my-self
interpose-args 2@ interpose-node @
interpose-node off recurse
r> to my-self
THEN
;
: close-node ( ihandle -- )
my-self >r to my-self
s" close" ['] $call-my-method CATCH IF 2drop THEN
my-self destroy-instance r> to my-self ;
: close-dev ( ihandle -- )
my-self >r to my-self
BEGIN my-self WHILE my-parent my-self close-node to my-self REPEAT
r> to my-self ;
: new-device ( -- )
my-self new-node                     ( parent-ihandle phandle )
node>instance-template @             ( parent-ihandle ihandle )
dup to my-self                       ( parent-ihanlde ihandle )
instance>parent !
get-node my-self instance>node !
max-instance-size my-self instance>size !
;
: finish-device ( -- )
get-node >space? 0= IF
s" reg" get-node get-property 0= IF
decode-int set-space 2drop
THEN
THEN
finish-node my-parent to my-self
;
: extend-device  ( phandle -- )
my-self >r
dup set-node
node>instance-template @
dup to my-self
r> swap instance>parent !
;
: split ( str len char -- left len right len )
>r 2dup r> findchar IF >r over r@ 2swap r> 1+ /string ELSE 0 0 THEN ;
: generic-decode-unit ( str len ncells -- addr.lo ... addr.hi )
dup >r -rot BEGIN r@ WHILE r> 1- >r [char] , split 2swap
$number IF 0 THEN r> swap >r >r REPEAT r> 3drop
BEGIN dup WHILE 1- r> swap REPEAT drop ;
: generic-encode-unit ( addr.lo ... addr.hi ncells -- str len )
0 0 rot ?dup IF 0 ?DO rot (u.) $cat s" ," $cat LOOP 1- THEN ;
: hex-decode-unit ( str len ncells -- addr.lo ... addr.hi )
base @ >r hex generic-decode-unit r> base ! ;
: hex-encode-unit ( addr.lo ... addr.hi ncells -- str len )
base @ >r hex generic-encode-unit r> base ! ;
: hex64-decode-unit ( str len ncells -- addr.lo ... addr.hi )
dup 2 <> IF
hex-decode-unit
ELSE
drop
base @ >r hex
$number IF 0 0 ELSE xlsplit THEN
r> base !
THEN
;
: hex64-encode-unit ( addr.lo ... addr.hi ncells -- str len )
dup 2 <> IF
hex-encode-unit
ELSE
drop
base @ >r hex
lxjoin (u.)
r> base !
THEN
;
: handle-leading-/ ( path len -- path' len' )
dup IF over c@ [char] / = IF 1 /string device-tree @ set-node THEN THEN ;
: match-name ( name len node -- match? )
over 0= IF 3drop true EXIT THEN
s" name" rot get-property IF 2drop false EXIT THEN
1- string=ci ; \ XXX should use decode-string
0 VALUE #search-unit
CREATE search-unit 4 cells allot
: match-unit ( node -- match? )
dup >space? IF
node>space search-unit #search-unit 0 ?DO 2dup @ swap @ <> IF
2drop false UNLOOP EXIT THEN cell+ swap cell+ swap LOOP 2drop true
ELSE drop true THEN
;
: match-node ( name len node -- match? )
dup >r match-name r> match-unit and ; \ XXX e3d
: find-kid ( name len -- node|0 )
dup -1 = IF \ are we supposed to stay in the same node? -> resolve-relatives
2drop get-node
ELSE
get-node child >r BEGIN r@ WHILE 2dup r@ match-node
IF 2drop r> EXIT THEN r> peer >r REPEAT
r> 3drop false
THEN ;
: set-search-unit ( unit len -- )
0 to #search-unit
0 to user-instance-#units
dup 0= IF 2drop EXIT THEN
s" #address-cells" get-node get-property THROW
decode-int to #search-unit 2drop
s" decode-unit" get-node $call-static
#search-unit 0 ?DO search-unit i cells + ! LOOP
;
: resolve-relatives ( path len -- path' len' )
2dup 2 = swap s" .." comp 0= and IF
get-node parent ?dup IF
set-node drop -1
ELSE
s" Already in root node." type
THEN
THEN
2dup 1 = swap c@ [CHAR] . = and IF
drop -1
THEN
;
: set-instance-unit  ( unitaddr len -- )
dup 0= IF 2drop  0 to user-instance-#units  EXIT THEN
2dup 0 -rot bounds ?DO
i c@ [char] , = IF 1+ THEN      \ Count the commas
LOOP
1+ dup to user-instance-#units
hex-decode-unit
user-instance-#units 0 ?DO
user-instance-units i cells + !
LOOP
;
: split-component  ( path. -- path'. args. name. unit. )
[char] / split 2swap     ( path'. component. )
[char] : split 2swap     ( path'. args. name@unit. )
[char] @ split           ( path'. args. name. unit. )
;
: find-component  ( path len -- path' len' args len node|0 )
debug-find-component? IF
." find-component for " 2dup type cr
THEN
split-component           ( path'. args. name. unit. )
debug-find-component? IF
." -> unit  =" 2dup type cr
." -> stack =" .s cr
THEN
['] set-search-unit CATCH IF
." WARNING: Obsolete old wildcard hack " .s cr
set-instance-unit
THEN
resolve-relatives find-kid        ( path' len' args len node|0 )
dup IF dup >space? not #search-unit 0 > AND user-instance-#units 0= AND IF
#search-unit dup to user-instance-#units 0 ?DO
search-unit i cells + @ user-instance-units i cells + !
LOOP
THEN THEN
dup IF dup >space? user-instance-#units 0 > AND IF
cr ." find-component with unit mismatch!" .s cr
drop 0
THEN THEN
;
: .find-node ( path len -- phandle|0 )
current-node @ >r
handle-leading-/ current-node @ 0= IF 2drop r> set-node 0 EXIT THEN
BEGIN dup WHILE \ handle one component:
find-component ( path len args len node ) dup 0= IF
3drop 2drop r> set-node 0 EXIT THEN
set-node 2drop REPEAT 2drop
get-node r> set-node ;
' .find-node to find-node
: find-node ( path len -- phandle|0 ) de-alias find-node ;
: delete-node ( phandle -- )
dup node>instance-template @ max-instance-size free-mem
dup node>parent @ node>child @ ( phandle 1st peer )
2dup = IF
node>peer @ swap node>parent @ node>child !
EXIT
THEN
dup node>peer @
BEGIN
2 pick 2dup <>
WHILE
drop
nip dup node>peer @
dup 0= IF 2drop drop unloop EXIT THEN
REPEAT
drop
node>peer @  swap node>peer !
drop
;
: open-dev ( path len -- ihandle|0 )
0 to user-instance-#units
de-alias current-node @ >r
handle-leading-/ current-node @ 0= IF 2drop r> set-node 0 EXIT THEN
my-self >r
0 to my-self
0 0 >r >r
BEGIN
dup
WHILE \ handle one component:
( arg len ) r> r> get-node open-node to my-self
find-component ( path len args len node ) dup 0= IF
3drop 2drop my-self close-dev
r> to my-self
r> set-node
0 EXIT
THEN
set-node
>r >r
REPEAT
2drop
r> r> get-node open-node to my-self
my-self r> to my-self r> set-node
;
: select-dev  open-dev dup to my-self ihandle>phandle set-node ;
: unselect-dev  my-self close-dev  0 to my-self  device-end ;
: find-device ( str len -- ) \ set as active node
find-node dup 0= ABORT" No such device path" set-node ;
: dev  parse-word find-device ;
: (lsprop) ( node --)
dup cr $indent indent @ type ."     node: " node>qname type
false +indent (.properties) cr -indent
;
: (show-children) ( node -- )
child BEGIN
dup
WHILE
dup (lsprop) dup child IF false +indent dup recurse -indent THEN peer
REPEAT
drop
;
: lsprop ( {device-specifier}<eol> -- )
skipws 0 parse dup IF de-alias ELSE 2drop s" /" THEN
find-device get-node dup dup
cr ." node: " node>path type (.properties) cr (show-children)
0 indent !
;
: (node>path) node>path ;
: node>path ( phandle -- str len )
node>path dup allot
;
0 VALUE packages
: find-package  ( name len -- false | phandle true )
dup 0 <= IF
2drop FALSE EXIT
THEN
over c@ [char] / = IF
find-node dup IF TRUE THEN EXIT
THEN
0 >r packages child
BEGIN
dup
WHILE
dup >r node>name 2over string=ci r> swap IF
r> drop dup >r
THEN
peer
REPEAT
3drop
r> dup IF true THEN
;
: open-package ( arg len phandle -- ihandle | 0 )  open-node ;
: close-package ( ihandle -- )  close-node ;
: $open-package ( arg len name len -- ihandle | 0 )
find-package IF open-package ELSE 2drop false THEN ;
: pci-address-type  ( node address prop_type -- type )
-rot 2 pick ( prop_type node address prop_type )
0= IF
swap s" reg" rot get-property  ( prop_type address data dlen false )
ELSE
swap s" assigned-addresses" rot get-property  ( prop_type address data dlen false )
THEN
IF  2drop -1  EXIT  THEN  4 / 5 /
0 DO
dup l@ FF AND 0<> ( prop_type address data cfgspace_offset? )
3 pick 0= ( prop_type address data cfgspace_offset? reg_prop? )
AND NOT IF 
2dup 4 + ( prop_type address data address data' )
2dup @ 2 pick 8 + @ + <= -rot @  >= and  IF
l@ 03000000 and 18 rshift nip
swap drop ( type )
UNLOOP EXIT
THEN
THEN
4 5 * +
LOOP
3drop -1
;
: (range-read-cells)  ( range-addr #cells -- range-value )
1 =  IF  l@  ELSE  @  THEN
;
: (map-one-range)  ( type range pnac nsc nac address -- address true | address false )
over 3 = 5 pick l@ 3000000 and 18 rshift 7 pick <> and  IF
>r 2drop 3drop r> false EXIT
THEN
4 pick 4 pick 3 pick + 4 * +
3 pick
(range-read-cells)
5 pick 3 pick 3 =  IF
4 +
THEN
3 pick
(range-read-cells)
dup >r dup 3 pick > >r + over <= r> or  IF
>r 2drop 3drop r> r> drop false EXIT
THEN
dup r> -
5 pick 5 pick 3 =  IF
4 +
THEN
3 pick 4 * +
5 pick
(range-read-cells)
+ >r 3drop 3drop r> true
;
: translate-address  ( node address -- address )
2dup 1 pci-address-type  ( node address type )
dup -1 = IF
drop 2dup 0 pci-address-type ( node address type )
THEN
rot parent BEGIN
dup parent 0=  IF  2drop EXIT  THEN
s" #address-cells" 2 pick get-property 2drop l@ >r        \ nac
s" #size-cells" 2 pick get-property 2drop l@ >r           \ nsc
s" #address-cells" 2 pick parent get-property 2drop l@ >r \ pnac
-rot ( node address type )
s" ranges" 4 pick get-property  IF
3drop
ABORT" no ranges property; not translatable"
THEN
r> r> r> 3 roll
4 / >r 3dup + + >r 5 roll r> r> swap / 0 ?DO
6dup (map-one-range) IF
nip leave
THEN
nip
4 roll
4 pick 4 pick 4 pick + + 4 * + 4 -roll
LOOP
>r 2drop 2drop r> ( node type address )
swap rot parent ( address type node )
dup 0=
UNTIL
;
: translate-my-address  ( address -- address' )
get-node swap translate-address
;
: find-substr ( basestr-ptr basestr-len substr-ptr substr-len -- pos )
dup 0 = IF
2drop 2drop 0 exit THEN
dup 3 pick <= IF
2 pick over - 1+ 0 DO dup 0 DO
over i + c@ 4 pick j + i + c@ = IF
dup i 1+ = IF
2drop 2drop j unloop unloop exit THEN
ELSE leave THEN
LOOP LOOP
THEN
2drop nip
;
: find-isubstr ( basestr-ptr basestr-len substr-ptr substr-len -- pos )
dup 0 = IF
2drop 2drop 0 exit THEN
dup 3 pick <= IF
2 pick over - 1+ 0 DO dup 0 DO
over i + c@ lcc 4 pick j + i + c@ lcc = IF
dup i 1+ = IF
2drop 2drop j unloop unloop exit THEN
ELSE leave THEN
LOOP LOOP
THEN
2drop nip
;
: find-nextline ( str-ptr str-len -- pos )
dup 0 ?DO over i + c@ CASE
0a OF
dup 1- i = IF
2drop i 1+ unloop exit THEN
over i 1+ + c@ 0d = IF
2drop i 2+ ELSE
2drop i 1+ THEN
unloop exit
ENDOF
0d OF
dup 1- i = IF
2drop i 1+ unloop exit THEN
over i 1+ + c@ 0a = IF
2drop i 2+ ELSE
2drop i 1+ THEN
unloop exit
ENDOF
ENDCASE LOOP nip
;
: string-at ( str1-ptr str1-len pos -- str2-ptr str2-len )
-rot 2 pick - -rot swap chars + swap
;
: string-cat ( addr1 len1 addr2 len2 -- addr1 len1+len2 )
rot dup >r over + -rot
3 pick r> chars + -rot
0 ?DO
2dup c@ swap c!
char+ swap char+ swap
LOOP 2drop
;
: char-cat ( addr len character -- addr len+1 )
-rot 2dup >r >r 1+ rot r> r> chars + c!
;
: overlap ( src dest size -- true|false )
3dup over + within IF 3drop true ELSE rot tuck + within THEN
;
: parse-2int ( str len -- val.lo val.hi )
[char] , split ?dup IF eval ELSE drop 0 THEN
-rot ?dup IF eval ELSE drop 0 THEN
;
: cpeek ( addr -- false | byte true ) c@ true ;
: cpoke ( byte addr -- success? ) c! true ;
: wpeek ( addr -- false | word true ) w@ true ;
: wpoke ( word addr -- success? ) w! true ;
: lpeek ( addr -- false | lword true ) l@ true ;
: lpoke ( lword addr -- success? ) l! true ;
defer reboot ( -- )
defer halt ( -- )
defer disable-watchdog ( -- )
defer reset-watchdog ( -- )
defer set-watchdog ( +n -- )
defer set-led ( type instance state -- status )
defer get-flashside ( -- side )
defer set-flashside ( side -- status )
defer read-bootlist ( -- )
defer furnish-boot-file ( -- adr len )
defer set-boot-file ( adr len -- )
defer mfg-mode? ( -- flag )
defer of-prompt? ( -- flag )
defer debug-boot? ( -- flag )
defer bmc-version ( -- adr len )
defer cursor-on ( -- )
defer cursor-off ( -- )
: nop-reboot ( -- ) ." reboot not available" abort ;
: nop-halt ( -- ) ." halt not available" abort ;
: nop-disable-watchdog ( -- )  ;
: nop-reset-watchdog ( -- )  ;
: nop-set-watchdog ( +n -- ) drop ;
: nop-set-led ( type instance state -- status ) drop drop drop ;
: nop-get-flashside ( -- side ) ." Cannot get flashside" cr ABORT ;
: nop-set-flashside ( side -- status ) ." Cannot set flashside" cr ABORT ;
: nop-read-bootlist ( -- ) ;
: nop-furnish-bootfile ( -- adr len ) s" net:" ;
: nop-set-boot-file ( adr len -- ) 2drop ;
: nop-mfg-mode? ( -- flag ) false ;
: nop-of-prompt? ( -- flag ) false ;
: nop-debug-boot? ( -- flag ) false ;
: nop-bmc-version ( -- adr len ) s" XXXXX" ;
: nop-cursor-on ( -- ) ;
: nop-cursor-off ( -- ) ;
' nop-reboot to reboot
' nop-halt to halt
' nop-disable-watchdog to disable-watchdog
' nop-reset-watchdog   to reset-watchdog
' nop-set-watchdog     to set-watchdog
' nop-set-led          to set-led
' nop-get-flashside    to get-flashside
' nop-set-flashside    to set-flashside
' nop-read-bootlist    to read-bootlist
' nop-furnish-bootfile to furnish-boot-file
' nop-set-boot-file    to set-boot-file
' nop-mfg-mode?        to mfg-mode?
' nop-of-prompt?       to of-prompt?
' nop-debug-boot?      to debug-boot?
' nop-bmc-version      to bmc-version
' nop-cursor-on        to cursor-on
' nop-cursor-off       to cursor-off
: reset-all reboot ;
10000000 VALUE default-load-base
2000000 VALUE flash-load-base
0 VALUE load-base-override
: get-load-base
load-base-override 0<> IF load-base-override ELSE
" load-base" evaluate 
THEN
;
: xt>name ( xt -- str len )
BEGIN
cell - dup c@ 0 2 within IF
dup 2+ swap 1+ c@ exit
THEN
AGAIN
;
cell -1 * CONSTANT -cell
: cell- ( n -- n-cell-size )
[ cell -1 * ] LITERAL +
;
: find-xt-addr ( addr -- xt )
BEGIN
dup @ <colon> = IF
EXIT
THEN
cell-
AGAIN
;
: (.immediate) ( xt -- )
xt>name drop 2 - c@ \ skip len and flags
immediate? IF
."  IMMEDIATE"
THEN
;
: (.xt) ( xt -- )
xt>name type
;
: trace-back (  )
1
BEGIN
cr dup dup . ."  : " rpick dup . ."  : "
['] tib here within IF
dup rpick find-xt-addr (.xt)
THEN
1+ dup rdepth 5 - >= IF cr drop EXIT THEN
AGAIN
;
VARIABLE see-my-type-column
: (see-my-type) ( indent limit xt str len -- indent limit xt )
dup see-my-type-column @ + dup 50 >= IF
-rot over "  " comp 0= IF
2drop see-my-type-column !
ELSE
rot drop                     ( indent limit xt str len )
pocket swap 2dup >r >r       ( indent limit xt str pk len  R: len pk )
move r> r>                   ( indent limit xt pk len )
2 pick (u.) dup -rot
cr type                      ( indent limit xt pk len xt-len )
" :" type 1+                 ( indent limit xt pk len prefix-len )
5 pick dup spaces +          ( indent limit xt pk len prefix-len )
over + see-my-type-column !  ( indent limit xt pk len )
type
THEN                            ( indent limit xt )
ELSE
see-my-type-column ! type       ( indent limit xt )
THEN
;
: (see-my-type-init) ( -- )
ffff see-my-type-column !        \ just enforce a new line
;
: (see-colon-body) ( indent limit xt -- indent limit xt )
(see-my-type-init)                              \ enforce new line
BEGIN                                           ( indent limit xt )
cell+ 2dup <>
over @
dup <semicolon> <>
rot and			                   ( indent limit xt @xt flag )
WHILE                                           ( indent limit xt @xt )
xt>name (see-my-type) "  " (see-my-type)
dup @                                        ( indent limit xt @xt)
CASE
<0branch>  OF cell+ dup @
over + cell+ dup >r
(u.) (see-my-type) r>          ( indent limit xt target)
2dup < IF
over 4 pick 3 + -rot recurse
nip nip nip cell-           ( indent limit xt )
ELSE
drop                        ( indent limit xt )
THEN
(see-my-type-init) ENDOF       \ enforce new line
<branch>   OF cell+ dup @ over + cell+ (u.)
(see-my-type) "  " (see-my-type) ENDOF
<do?do>    OF cell+ dup @ (u.) (see-my-type)
"  " (see-my-type) ENDOF
<lit>      OF cell+ dup @ (u.) (see-my-type)
"  " (see-my-type) ENDOF
<dotick>   OF cell+ dup @ xt>name (see-my-type)
"  " (see-my-type) ENDOF
<doloop>   OF cell+ dup @ (u.) (see-my-type)
"  " (see-my-type) ENDOF
<do+loop>  OF cell+ dup @ (u.) (see-my-type)
"  " (see-my-type) ENDOF
<doleave>  OF cell+ dup @ over + cell+ (u.)
(see-my-type) "  " (see-my-type) ENDOF
<do?leave> OF cell+ dup @ over + cell+ (u.)
(see-my-type) "  " (see-my-type) ENDOF
<sliteral> OF cell+ " """ (see-my-type) dup count dup >r
(see-my-type) " """ (see-my-type)
"  " (see-my-type)
r> -cell and + ENDOF
ENDCASE
REPEAT
drop
;
: (see-colon) ( xt -- )
(see-my-type-init)
1 swap 0 swap                                    ( indent limit xt )
" : " (see-my-type) dup xt>name (see-my-type)
rot drop 4 -rot (see-colon-body)                 ( indent limit xt )
rot drop 1 -rot (see-my-type-init) " ;" (see-my-type)
3drop 
;
: (see-create) ( xt -- )
dup cell+ @
CASE
<2constant> OF
dup cell+ cell+ dup @ swap cell+ @ . .  ." 2CONSTANT "
ENDOF
<instancevalue> OF
dup cell+ cell+ @ . ." INSTANCE VALUE "
ENDOF
<instancevariable> OF
." INSTANCE VARIABLE "
ENDOF
dup OF
." CREATE "
ENDOF
ENDCASE
(.xt)
;
: (see) ( xt -- )
cr dup dup @
CASE
<variable> OF ." VARIABLE " (.xt) ENDOF
<value>    OF dup execute . ." VALUE " (.xt) ENDOF
<constant> OF dup execute . ." CONSTANT " (.xt) ENDOF
<defer>    OF dup cell+ @ swap ." DEFER " (.xt) ."  is " (.xt) ENDOF
<alias>    OF dup cell+ @ swap ." ALIAS " (.xt) ."  " (.xt) ENDOF
<buffer:>  OF ." BUFFER: " (.xt) ENDOF
<create>   OF (see-create) ENDOF
<colon>    OF (see-colon)  ENDOF
dup        OF ." ??? PRIM " (.xt) ENDOF
ENDCASE
(.immediate) cr
;
: see ( "old-name<>" -- )
' (see)
;
0    value forth-ip
true value trace>stepping?
true value trace>print?
true value trace>up?
0    value trace>depth
0    value trace>rdepth
0    value trace>recurse
: trace-depth+ ( -- ) trace>depth 1+ to trace>depth ;
: trace-depth- ( -- ) trace>depth 1- to trace>depth ;
: stepping ( -- )
true to trace>stepping?
;
: tracing ( -- )
false to trace>stepping?
;
: trace-print-on ( -- )
true to trace>print?
;
: trace-print-off ( -- )
false to trace>print?
;
: fip-add ( n -- )
forth-ip + to forth-ip
;
0 value debug-last-xt
0 value debug-last-xt-content
: trace-print ( -- )
forth-ip cr u. ." : "
forth-ip @ 
dup ['] breakpoint = IF drop debug-last-xt-content THEN
xt>name type ."  "
."     ( " .s  ."  )  | "
;
: trace-interpret ( -- )
rdepth 1- to trace>rdepth
BEGIN
depth . [char] > dup emit emit space
source expect                        ( str len )
['] interpret catch print-status
AGAIN
;
: trace-xt ( xt -- )
trace>recurse IF
r> drop                                \ Drop return of 'trace-xt call
cell+                                  \ Step over ":"
ELSE
debug-last-xt-content <colon> = IF
['] breakpoint @ debug-last-xt !    \ Re-arm break point
r> drop                             \ Drop return of 'trace-xt call
cell+                               \ Step over ":"
ELSE
['] breakpoint debug-last-xt !      \ Re-arm break point
2r> 2drop
THEN
THEN
to forth-ip
true to trace>print?
BEGIN
trace>print? IF trace-print THEN
forth-ip                                              ( ip )
trace>stepping? IF
BEGIN
key
CASE
[char] d OF dup @ @ <colon> = IF             \ recurse only into colon definitions
trace-depth+
1 to trace>recurse
dup >r @ recurse
THEN true ENDOF
[char] u OF trace>depth IF tracing trace-print-off true ELSE false THEN ENDOF
[char] f OF drop cr trace-interpret ENDOF	\ quit trace and start interpreter FIXME rstack
[char] c OF tracing true ENDOF
[char] t OF trace-back false ENDOF
[char] q OF drop cr quit ENDOF
20       OF true ENDOF
dup      OF cr ." Press d:       Down into current word" cr
." Press u:       Up to caller" cr
." Press f:       Switch to forth interpreter, 'resume' will continue tracing" cr
." Press c:       Switch to tracing" cr
." Press <space>: Execute current word" cr
." Press q:       Abort execution, switch to interpreter" cr
false ENDOF
ENDCASE
UNTIL
THEN	                                              ( ip' )
dup to forth-ip @                                      ( xt )
dup ['] breakpoint = IF drop debug-last-xt-content THEN
dup                                                    ( xt xt )
CASE
<sliteral>  OF drop forth-ip cell+ dup dup c@ + -cell and to forth-ip ENDOF
<dotick>    OF drop forth-ip cell+ @ cell fip-add ENDOF
<lit>       OF drop forth-ip cell+ @ cell fip-add ENDOF
<doto>      OF drop forth-ip cell+ @ cell+ ! cell fip-add ENDOF
<(doito)>   OF drop forth-ip cell+ @ cell+ cell+ @ >instance ! cell fip-add ENDOF
<0branch>   OF drop IF
cell fip-add
ELSE
forth-ip cell+ @ cell+ fip-add THEN
ENDOF
<do?do>     OF drop 2dup <> IF
swap >r >r cell fip-add
ELSE
forth-ip cell+ @ cell+ fip-add 2drop THEN
ENDOF
<branch>    OF drop forth-ip cell+ @ cell+ fip-add ENDOF
<doleave>   OF drop r> r> 2drop forth-ip cell+ @ cell+ fip-add ENDOF		
<do?leave>  OF drop IF
r> r> 2drop forth-ip cell+ @ cell+ fip-add
ELSE
cell fip-add
THEN
ENDOF		
<doloop>    OF drop r> 1+ r> 2dup = IF
2drop cell fip-add
ELSE >r >r
forth-ip cell+ @ cell+ fip-add THEN
ENDOF
<do+loop>   OF drop r> + r> 2dup >= IF
2drop cell fip-add
ELSE >r >r
forth-ip cell+ @ cell+ fip-add THEN
ENDOF
<semicolon> OF trace>depth 0> IF
trace-depth- 1 to trace>recurse
stepping drop r> recurse
ELSE
drop exit THEN
ENDOF
<exit>      OF trace>depth 0> IF
trace-depth- stepping drop r> recurse
ELSE
drop exit THEN
ENDOF
dup         OF execute ENDOF
ENDCASE
forth-ip cell+ to forth-ip
AGAIN
;
: resume ( -- )
trace>rdepth rdepth!
forth-ip cell - trace-xt
;
: debug-off ( -- )
debug-last-xt IF
debug-last-xt-content debug-last-xt !  \ Restore overwritten token
0 to debug-last-xt
THEN
;
: (break-entry) ( -- )
debug-last-xt dup @ ['] breakpoint <> swap  ( debug-addr? debug-last-xt )
debug-last-xt-content swap !                \ Restore overwritten token
r> drop                                     \ Don't return to bp, but to caller
debug-last-xt-content <colon> <> and IF     \ Execute non colon definition
debug-last-xt cr u. ." : "
debug-last-xt xt>name type ."  "
."     ( " .s  ."  )  | "
key drop
debug-last-xt execute
ELSE
debug-last-xt 0 to trace>depth 0 to trace>recurse trace-xt   \ Trace colon definition
THEN
;
' (break-entry) to BP
: debug-address ( addr --  )
debug-off                       ( xt )  \ Remove active breakpoint
dup to debug-last-xt            ( xt )  \ Save token for later debug
dup @ to debug-last-xt-content  ( xt )  \ Save old value
['] breakpoint swap !
;
: (debug ( xt --  )
debug-off                       ( xt )  \ Remove active breakpoint
dup to debug-last-xt            ( xt )  \ Save token for later debug
dup @ to debug-last-xt-content  ( xt )  \ Save old value
['] breakpoint @ swap !
;
: debug ( "old-name<>" -- )
parse-word $find IF                       \ Get xt for old-name
(debug
ELSE
." undefined word " type cr
THEN
;
: words
last @
BEGIN ?dup WHILE
dup cell+ char+ count type space @
REPEAT
;
: .calls    ( xt -- )
current-node @ >r 0 set-node    \ only search commands, according too IEEE1275
last BEGIN @ ?dup WHILE    ( xt currxt )
dup cell+ char+         ( xt currxt name* )
dup dup c@ + 1+ aligned ( xt currxt name* CFA )
dup @ <colon> = IF      ( xt currxt name* CFA )
BEGIN
cell+ dup @ ['] semicolon <>
WHILE		      ( xt currxt *name pos )
dup @ 4 pick = IF ( xt currxt *name pos )
over count type space
BEGIN cell+ dup @ ['] semicolon = UNTIL cell - \ eat up other occurrences
THEN
REPEAT
THEN
2drop ( xt currxt )
REPEAT
drop
r> set-node		   \ restore node
;
0 value #sift-count
false value sift-compl-only
: $inner-sift ( text-addr text-len LFA -- ... word-addr word-len true | false )
dup cell+ char+ count           \ get word name
2dup 6 pick 6 pick find-isubstr \ is there a partly match?
sift-compl-only IF 0= ELSE over < THEN
IF
#sift-count 1+ to #sift-count \ count completions
true
ELSE
2drop false
THEN
;
: $sift    ( text-addr text-len -- )
current-node @ >r 0 set-node	\ only search commands, according too IEEE1275
sift-compl-only >r false to sift-compl-only \ all substrings, not only compl.
last BEGIN @ ?dup WHILE	\ walk the whole dictionary
$inner-sift IF type space THEN
REPEAT
2drop
0 to #sift-count	   \ we don't need completions here.
r> to sift-compl-only    \ restore previous sifting mode
r> set-node		   \ restore node
;
: sifting    ( "text< >" -- )
parse-word $sift
;
: ([IF])
BEGIN
BEGIN parse-word dup 0= WHILE
2drop refill
REPEAT
2dup s" [IF]" str= IF 1 throw THEN
2dup s" [ELSE]" str= IF 2 throw THEN
2dup s" [THEN]" str= IF 3 throw THEN
s" \" str= IF linefeed parse 2drop THEN
AGAIN
;
: [IF] ( flag -- )
IF exit THEN
1 BEGIN
['] ([IF]) catch 
CASE
1 OF 1+ ENDOF
2 OF dup 1 = if 1- then ENDOF
3 OF 1- ENDOF
ENDCASE
dup 0 <=
UNTIL drop
; immediate
: [ELSE] 0 [COMPILE] [IF] ; immediate
: [THEN] ; immediate
: $dnumber base @ >r decimal $number r> base ! ;
: (.d) base @ >r decimal (.) r> base ! ;
4000 to default-load-base
deadbeef here l!
here c@ de = CONSTANT ?bigendian
here c@ ef = CONSTANT ?littleendian
?bigendian [IF]
: x!-le >r xbflip r> x! ;
: x@-le x@ xbflip ;
: l!-le  >r lbflip r> l! ;
: l@-le  l@ lbflip ;
: w!-le  >r wbflip r> w! ;
: w@-le  w@ wbflip ;
: rx!-le  >r xbflip r> rx! ;
: rx@-le  rx@ xbflip ;
: rl!-le  >r lbflip r> rl! ;
: rl@-le  rl@ lbflip ;
: rw!-le  >r wbflip r> rw! ;
: rw@-le  rw@ wbflip ;
: l!-be  l! ;
: l@-be  l@ ;
: w!-be  w! ;
: w@-be  w@ ;
: rl!-be  rl! ;
: rl@-be  rl@ ;
: rw!-be  rw! ;
: rw@-be  rw@ ;
[ELSE]
: x!-le x! ;
: x@-le x@ ;
: l!-le  l! ;
: l@-le  l@ ;
: w!-le  w! ;
: w@-le  w@ ;
: rx!-le  rx! ;
: rx@-le  rx@ ;
: rl!-le  rl! ;
: rl@-le  rl@ ;
: rw!-le  rw! ;
: rw@-le  rw@ ;
: l!-be  >r lbflip r> l! ;
: l@-be  l@ lbflip ;
: w!-be  >r wbflip r> w! ;
: w@-be  w@ wbflip ;
: rl!-be  >r lbflip r> rl! ;
: rl@-be  rl@ lbflip ;
: rw!-be  >r wbflip r> rw! ;
: rw@-be  rw@ wbflip ;
[THEN]
: #join  ( lo hi #bits -- x )  lshift or ;
: #split ( x #bits -- lo hi )  2dup rshift dup >r swap lshift xor r> ;
: blink ;
: reset-dual-emit ;
: console-clean-fifo ;
: bootmsg-nvupdate ;
: asm-cout 2drop drop ;
defer nvramlog-write-byte
: .nvramlog-write-byte ( byte -- )
drop
;
' .nvramlog-write-byte to nvramlog-write-byte
: nvramlog-write-string ( str len -- )
dup 0> IF
0 DO dup c@ 
nvramlog-write-byte char+ LOOP
ELSE
drop
THEN drop ;
: nvramlog-write-number ( number format -- )
0 swap <# 0 ?DO # LOOP #> 
nvramlog-write-string ;
: nvramlog-write-string-cr ( str len -- )
nvramlog-write-string
a nvramlog-write-byte d nvramlog-write-byte ;
: log-string ( str len -- ) type ;
: log-string 2drop ;
create debugstr 255 allot
0 VALUE debuglen
: cp ( checkpoint -- )
bootmsg-cp ;
: (warning) ( id level ptr len -- )
dup TO debuglen
debugstr swap move           \ copy into buffer
0 debuglen debugstr + c!     \ terminate '\0'
debugstr bootmsg-warning
;
: warning" ( id level [text<">] -- )
postpone s" state @
IF
['] (warning) compile,
ELSE
(warning)
THEN
; immediate
: (debug-cp) ( id level ptr len -- )
dup TO debuglen
debugstr swap move           \ copy into buffer
0 debuglen debugstr + c!     \ terminate '\0'
debugstr bootmsg-debugcp
;
: debug-cp" ( id level [text<">] -- )
postpone s" state @
IF
['] (debug-cp) compile,
ELSE
(debug-cp)
THEN
; immediate
: (error) ( id ptr len -- )
dup TO debuglen
debugstr swap move           \ copy into buffer
0 debuglen debugstr + c!     \ terminate '\0'
debugstr bootmsg-error
;
: error" ( id level [text<">] -- )
postpone s" state @
IF
['] (error) compile,
ELSE
(error)
THEN
; immediate
bootmsg-nvupdate
000 cp
STRUCT
cell FIELD >r0   cell FIELD >r1   cell FIELD >r2   cell FIELD >r3
cell FIELD >r4   cell FIELD >r5   cell FIELD >r6   cell FIELD >r7
cell FIELD >r8   cell FIELD >r9   cell FIELD >r10  cell FIELD >r11
cell FIELD >r12  cell FIELD >r13  cell FIELD >r14  cell FIELD >r15
cell FIELD >r16  cell FIELD >r17  cell FIELD >r18  cell FIELD >r19
cell FIELD >r20  cell FIELD >r21  cell FIELD >r22  cell FIELD >r23
cell FIELD >r24  cell FIELD >r25  cell FIELD >r26  cell FIELD >r27
cell FIELD >r28  cell FIELD >r29  cell FIELD >r30  cell FIELD >r31
cell FIELD >cr   cell FIELD >xer  cell FIELD >lr   cell FIELD >ctr
cell FIELD >srr0 cell FIELD >srr1 cell FIELD >dar  cell FIELD >dsisr
CONSTANT ciregs-size
: .16  10 0.r 3 spaces ;
: .8   8 spaces 8 0.r 3 spaces ;
: .4regs  cr 4 0 DO dup @ .16 8 cells+ LOOP drop ;
: .fixed-regs
cr ."     R0 .. R7           R8 .. R15         R16 .. R23         R24 .. R31"
dup 8 0 DO dup .4regs cell+ LOOP drop
;
: .special-regs
cr ."     CR / XER           LR / CTR          SRR0 / SRR1        DAR / DSISR"
cr dup >cr  @ .8   dup >lr  @ .16  dup >srr0 @ .16  dup >dar @ .16
cr dup >xer @ .16  dup >ctr @ .16  dup >srr1 @ .16    >dsisr @ .8
;
: .regs
cr .fixed-regs
cr .special-regs
cr cr
;
: .hw-exception ( reason-code exception-nr -- )
." ( " dup . ." ) "
CASE
200 OF ." Machine Check" ENDOF
300 OF ." Data Storage" ENDOF
380 OF ." Data Segment" ENDOF
400 OF ." Instruction Storage" ENDOF
480 OF ." Instruction Segment" ENDOF
500 OF ." External" ENDOF
600 OF ." Alignment" ENDOF
700 OF ." Program" ENDOF
800 OF ." Floating-point unavailable" ENDOF
900 OF ." Decrementer" ENDOF
980 OF ." Hypervisor Decrementer" ENDOF
C00 OF ." System Call" ENDOF
D00 OF ." Trace" ENDOF
F00 OF ." Performance Monitor" ENDOF
F20 OF ." VMX Unavailable" ENDOF
1200 OF ." System Error" ENDOF
1600 OF ." Maintenance" ENDOF
1800 OF ." Thermal" ENDOF
dup OF ." Unknown" ENDOF
ENDCASE
."  Exception [ " . ." ]"
;
: .sw-exception ( exception-nr -- )
."  Exception [ " . ." ] triggered by boot firmware."
;
: be-hw-exception ( [reason-code] exception-nr -- )
cr cr
dup 0> IF .hw-exception ELSE .sw-exception THEN
cr eregs .regs
;
' be-hw-exception to hw-exception-handler
: (boot-exception-handler) ( x1...xn exception-nr -- x1...xn)
dup IF
dup 0 > IF
negate cp 9 emit ." : " type
ELSE
CASE
-6d OF cr ." W3411: Client application returned." cr ENDOF
-6c OF cr ." E3400: It was not possible to boot from any device "
." specified in the VPD." cr
ENDOF
-6b OF cr ." E3410: Boot list successfully read from VPD "
." but no useful information received." cr
ENDOF
-6a OF cr ." E3420: Boot list could not be read from VPD." cr
ENDOF
-69 OF
cr ." E3406: Client application returned an error"
abort"-str @ count dup IF
." :    " type cr
ELSE
." ." cr
2drop
THEN
ENDOF
-68 OF cr ." E3405: No such device" cr ENDOF
-67 OF cr ." E3404: Not a bootable device!" cr ENDOF
-66 OF cr ." E3408: Failed to claim memory for the executable" cr
ENDOF
-65 OF cr ." E3407: Load failed" cr ENDOF
-64 OF cr ." E3403: Bad executable:   " abort"-str @ count type cr
ENDOF
-63 OF cr ." E3409: Unknown FORTH Word" cr ENDOF
-2 OF cr ." E3401: Aborting boot,  " abort"-str @ count type cr
ENDOF
dup OF ." E3402: Aborting boot, internal error" cr ENDOF
ENDCASE
THEN
ELSE
drop
THEN
;
' (boot-exception-handler) to boot-exception-handler
: throw-error ( error-code "error-string" -- )
skipws 0a parse rot throw
;
: enable-ext-int ( -- )
msr@ 8000 or msr!
;
: disable-ext-int ( -- )
msr@ 8000 not and msr!
;
: gen-ext-int ( -- )
7fffffff dec!               \ Reset decrementer
enable-ext-int              \ Enable interrupt
FF 20000508418 rx!          \ Interrupt priority mask
10 20000508410 rx!          \ Interrupt priority
;
: mm-log-warning 2drop ;
: write-mm-log ( data length type -- status )
3drop 0
;
100 cp
: beep  bell emit ;
: TABLE-EXECUTE
CREATE DOES> swap cells+ @ ?dup IF execute ELSE beep THEN ;
0 VALUE accept-adr
0 VALUE accept-max
0 VALUE accept-len
0 VALUE accept-cur
: esc  1b emit ;
: csi  esc 5b emit ;
: move-cursor ( -- )
esc ." 8" accept-cur IF
csi base @ decimal accept-cur 0 .r base ! ." C"
THEN
;
: redraw-line ( -- )
accept-cur accept-len = IF EXIT THEN
move-cursor
accept-adr accept-len accept-cur /string type
csi ." K" move-cursor
;
: full-redraw-line ( -- )
accept-cur 0 to accept-cur move-cursor
accept-adr accept-len type
csi ." K" to accept-cur move-cursor
;
: redraw-prompt ( -- )
cr depth . [char] > emit
;
: insert-char ( char -- )
accept-len accept-max = IF drop beep EXIT THEN
accept-cur accept-len <> IF csi ." @" dup emit
accept-adr accept-cur + dup 1+ accept-len accept-cur - move
ELSE dup emit THEN
accept-adr accept-cur + c!
accept-cur 1+ to accept-cur
accept-len 1+ to accept-len redraw-line
;
: delete-char ( -- )
accept-cur accept-len = IF beep EXIT THEN
accept-len 1- to accept-len
accept-adr accept-cur + dup 1+ swap accept-len accept-cur - move
csi ." P" redraw-line
;
STRUCT
cell FIELD his>next
cell FIELD his>prev
cell FIELD his>len
0 FIELD his>buf
CONSTANT /his
0 VALUE his-head
0 VALUE his-tail
0 VALUE his-cur
: add-history ( -- )
accept-len 0= IF EXIT THEN
/his accept-len + alloc-mem
his-tail IF dup his-tail his>next ! ELSE dup to his-head THEN
his-tail over his>prev !  0 over his>next !  dup to his-tail
accept-len over his>len !  accept-adr swap his>buf accept-len move
;
: history  ( -- )
his-head BEGIN dup WHILE
cr dup his>buf over his>len @ type
his>next @ REPEAT drop
;
: select-history ( his -- )
dup to his-cur dup IF
dup his>len @ accept-max min dup to accept-len to accept-cur
his>buf accept-adr accept-len move ELSE
drop 0 to accept-len 0 to accept-cur THEN
full-redraw-line
;
0 value ?tab-pressed
0 value tab-last-adr
0 value tab-last-len
: $same-string ( addr-1 len-1 addr-2 len-2 -- addr-1 len-1' )
dup 0= IF    \ The second parameter is not a string.
2drop EXIT \ bail out
THEN
rot min 0 0 -rot ( addr1 addr2 0 len' 0 )
DO ( addr1 addr2 len-1' )
2 pick i + c@ lcc
2 pick i + c@ lcc
= IF 1 + ELSE leave THEN
LOOP
nip
;
: $tab-sift-words    ( text-addr text-len -- sift-count )
sift-compl-only >r true to sift-compl-only \ save sifting mode
last BEGIN @ ?dup WHILE \ loop over all words
$inner-sift IF \ any completions possible?
2dup bounds DO I c@ lcc I c! LOOP
?tab-pressed IF 2dup type space THEN  \ <tab><tab> prints possibilities
tab-last-adr tab-last-len $same-string \ find matching substring ...
to tab-last-len to tab-last-adr       \ ... and save it
THEN
repeat
2drop
#sift-count 0 to #sift-count	\ how many words were found?
r> to sift-compl-only		\ restore sifting completion mode
;
0 value current-stack
: new-stack ( cells <>name -- )
create >r here    ( here R: cells )
dup r@ 2 + cells  ( here here bytes R: cells )
dup allot erase   ( here R: cells)
cell+ r>          ( here+1cell cells )
swap !            ( )
DOES> to current-stack
;
: reset-stack ( -- )
0 current-stack !
;
: stack-depth ( -- depth )
current-stack @
;
: push ( value -- )
current-stack @
current-stack cell+ @ over <= ABORT" Stack overflow"
cells
1 current-stack +!
current-stack 2 cells + + !
;
: pop ( -- value )
current-stack @ 0= ABORT" Stack underflow"
current-stack @ cells
current-stack + cell+ @
-1 current-stack +!
;
10 new-stack device-stack
: (next-dev) ( node -- node' addr len )
device-stack
dup (node>path) rot
dup child IF dup push child -rot EXIT THEN
dup peer IF peer -rot EXIT THEN
drop
BEGIN
stack-depth
WHILE
pop peer ?dup IF -rot EXIT THEN
REPEAT
0 -rot
;
: $inner-sift-nodes ( text-addr text-len node -- ... path-addr path-len true | false )
(next-dev) ( text-addr text-len node' path-addr path-len )
dup 0= IF drop false EXIT THEN
2dup 6 pick 6 pick find-isubstr ( text-addr text-len node' path-addr path-len pos )
0= IF
#sift-count 1+ to #sift-count \ count completions
true
ELSE
2drop false
THEN
;
: .nodes ( -- )
s" /" find-node BEGIN dup WHILE
(next-dev)
type cr
REPEAT
drop
reset-stack
;
create sift-node-buffer 1000 allot
0 value sift-node-num
: sift-node-buffer
sift-node-buffer sift-node-num 100 * +
sift-node-num 1+ dup 10 = IF drop 0 THEN
to sift-node-num
;
: $tab-sift-nodes    ( text-addr text-len -- sift-count )
s" /" find-node BEGIN dup WHILE
$inner-sift-nodes IF \ any completions possible?
sift-node-buffer swap 2>r 2r@ move 2r> \ make an almost permanent copy without strdup
?tab-pressed IF 2dup type space THEN  \ <tab><tab> prints possibilities
tab-last-adr tab-last-len $same-string \ find matching substring ...
to tab-last-len to tab-last-adr       \ ... and save it
THEN
REPEAT
2drop drop
#sift-count 0 to #sift-count	\ how many words were found?
reset-stack
;
: $tab-sift    ( text-addr text-len -- sift-count )
?tab-pressed IF beep space THEN \ cosmetical fix for <tab><tab>
dup IF bl rsplit dup IF 2swap THEN ELSE 0 0 THEN >r >r
0 dup to tab-last-len to tab-last-adr	\ reset last possible match
current-node @ IF			\ if we are in a node?
2dup 2>r				\ save text
$tab-sift-words to #sift-count	\ search in current node first
2r>				\ fetch text to complete, again
THEN
2dup 2>r
current-node @ >r 0 set-node		\ now search in global words
$tab-sift-words to #sift-count
r> set-node
2r> $tab-sift-nodes
r> r> dup IF s"  " $cat THEN tab-last-adr tab-last-len $cat
to tab-last-len to tab-last-adr  \ ... and save the whole string
;
: handle-^A
0 to accept-cur move-cursor ;
: handle-^B
accept-cur ?dup IF 1- to accept-cur ( csi ." D" ) move-cursor THEN ;
: handle-^D
delete-char ( redraw-line ) ;
: handle-^E
accept-len to accept-cur move-cursor ;
: handle-^F
accept-cur accept-len <> IF accept-cur 1+ to accept-cur csi ." C" THEN ;
: handle-^H
accept-cur 0= IF beep EXIT THEN
handle-^B delete-char
;
: handle-^I
accept-adr accept-len
$tab-sift 0 > IF
?tab-pressed IF
redraw-prompt full-redraw-line
false to ?tab-pressed
ELSE
tab-last-adr accept-adr tab-last-len move    \ copy matching substring
tab-last-len dup to accept-len to accept-cur \ len and cursor position
full-redraw-line		\ redraw new string
true to ?tab-pressed	\ second tab will print possible matches
THEN
THEN
;
: handle-^K
BEGIN accept-cur accept-len <> WHILE delete-char REPEAT ;
: handle-^L
history redraw-prompt full-redraw-line ;
: handle-^N
his-cur IF his-cur his>next @ ELSE his-head THEN
dup to his-cur select-history
;
: handle-^P
his-cur IF his-cur his>prev @ ELSE his-tail THEN
dup to his-cur select-history
;
: handle-^Q  \ Does not handle terminal formatting yet.
key insert-char ;
: handle-^R
full-redraw-line ;
: handle-^U
0 to accept-len 0 to accept-cur full-redraw-line ;
: handle-fn
key drop beep
;
TABLE-EXECUTE handle-CSI
0 , ' handle-^P , ' handle-^N , ' handle-^F ,
' handle-^B , 0 , 0 , 0 ,
' handle-^A , 0 , 0 , ' handle-^E ,
0 , 0 , 0 , 0 ,
0 , 0 , 0 , 0 ,
0 , 0 , 0 , 0 ,
0 , 0 , 0 , 0 ,
0 , 0 , 0 , 0 ,
: handle-CSI-key
key 1f and handle-CSI
;
TABLE-EXECUTE handle-meta
0 , 0 , 0 , 0 ,
0 , 0 , 0 , 0 ,
0 , 0 , 0 , 0 ,
0 , 0 , 0 , ' handle-fn ,
0 , 0 , 0 , 0 ,
0 , 0 , 0 , 0 ,
0 , 0 , 0 , ' handle-CSI-key ,
0 , 0 , 0 , 0 ,
: handle-ESC-O
key
dup 48 = IF
handle-^A
ELSE
dup 46 = IF
handle-^E
THEN
THEN drop
;
: handle-ESC-5b
key
dup 31 = IF \ HOME
key drop ( drops closing 7e ) handle-^A
ELSE
dup 33 = IF \ DEL
key drop handle-^D
ELSE
dup 34 = IF \ END
key drop handle-^E
ELSE
dup 1f and handle-CSI
THEN
THEN
THEN drop
;
: handle-ESC
key
dup 5b = IF
handle-ESC-5b
ELSE
dup 4f = IF
handle-ESC-O
ELSE
dup 1f and handle-meta
THEN
THEN drop
;
TABLE-EXECUTE handle-control
0 , \ ^@:
' handle-^A ,
' handle-^B ,
0 , \ ^C:
' handle-^D ,
' handle-^E ,
' handle-^F ,
0 , \ ^G:
' handle-^H ,
' handle-^I , \ tab
0 , \ ^J:
' handle-^K ,
' handle-^L ,
0 , \ ^M: enter: handled in main loop
' handle-^N ,
0 , \ ^O:
' handle-^P ,
' handle-^Q ,
' handle-^R ,
0 , \ ^S:
0 , \ ^T:
' handle-^U ,
0 , \ ^V:
0 , \ ^W:
0 , \ ^X:
0 , \ ^Y: insert save buffer
0 , \ ^Z:
' handle-ESC ,
0 , \ ^\:
0 , \ ^]:
0 , \ ^^:
0 , \ ^_:
: (accept) ( adr len -- len' )
cursor-on
to accept-max to accept-adr
0 to accept-len 0 to accept-cur
0 to his-cur
1b emit 37 emit
BEGIN
key dup 0d <>
WHILE
dup 9 <> IF 0 to ?tab-pressed THEN \ reset state machine
dup 7f = IF drop 8 THEN \ Handle DEL as if it was BS. ??? bogus
dup bl < IF handle-control ELSE
dup 80 and IF
dup a0 < IF 7f and handle-meta ELSE drop beep THEN
ELSE
insert-char
THEN
THEN
REPEAT
drop add-history
accept-len to accept-cur
move-cursor space
accept-len
cursor-off
;
' (accept) to accept
120 cp
1 VALUE /dump
' c@ VALUE 'dump
0 VALUE dump-first
0 VALUE dump-last
0 VALUE dump-cur
: .char ( c -- )  dup bl 7f within 0= IF drop [char] . THEN emit ;
: dump-line ( -- )
cr dump-cur dup 8 0.r [char] : emit 10 /dump / 0 DO
space dump-cur dump-first dump-last within IF
dump-cur 'dump execute /dump 2* 0.r ELSE
/dump 2* spaces THEN dump-cur /dump + to dump-cur LOOP
/dump 1 <> IF drop EXIT THEN
to dump-cur 2 spaces
10 0 DO dump-cur dump-first dump-last within IF
dump-cur 'dump execute .char ELSE space THEN dump-cur 1+ to dump-cur LOOP ;
: (dump) ( addr len reader size -- )
to /dump to 'dump bounds /dump negate and to dump-first to dump-last
dump-first f invert and to dump-cur
base @ hex BEGIN dump-line dump-cur dump-last >= UNTIL base ! ;
: du ( -- )  dump-last 100 'dump /dump (dump) ;
: dump     ['] c@      1 (dump) ;
: wdump    ['] w@      2 (dump) ;
: ldump    ['] l@      4 (dump) ;
: xdump    ['] x@      8 (dump) ;
: rdump    ['] rb@     1 (dump) ;
cistack ciregs >r1 ! \ kernel wants a stack :-)
140 cp
STRUCT
cell field romfs>file-header
cell field romfs>data
cell field romfs>data-size
cell field romfs>flags
CONSTANT /romfs-lookup-control-block
CREATE romfs-lookup-cb /romfs-lookup-control-block allot
romfs-lookup-cb /romfs-lookup-control-block erase
: create-filename ( string -- string\0 )
here >r dup 8 + allot
r@ over 8 + erase
r@ zplace r> ;
: romfs-lookup ( fn-str fn-len -- data size | false )
create-filename romfs-base
romfs-lookup-cb romfs-lookup-entry call-c
0= IF romfs-lookup-cb dup romfs>data @ swap romfs>data-size @ ELSE
false THEN ;
: ibm,romfs-lookup ( fn-str fn-len -- data-high data-low size | 0 0 false )
romfs-lookup dup
0= if drop 0 0 false else
swap dup 20 rshift swap ffffffff and then ;
: romfs-lookup-client ibm,romfs-lookup ;
STRUCT
cell field romfs>next-off
cell field romfs>size
cell field romfs>flags
cell field romfs>data-off
cell field romfs>name
CONSTANT /romfs-cb
: romfs-map-file ( fn-str fn-len -- file-addr file-size )
romfs-base >r
BEGIN 2dup r@ romfs>name zcount string=ci not WHILE
( fn-str fn-len ) ( R: rom-cb-file-addr )
r> romfs>next-off dup @ dup 0= IF 1 THROW THEN + >r REPEAT
( fn-str fn-len ) ( R: rom-cb-file-addr )
2drop r@ romfs>data-off @ r@ + r> romfs>size @ ;
: flash-header ( -- address | false )
get-flash-base 28 +         \ prepare flash header file address
dup rx@                     \ fetch "magic123"
6d61676963313233 <> IF      \ IF flash is not valid
drop                     \ | forget address
false                    \ | return false
THEN                        \ FI
;
CREATE bdate-str 10 allot
: bdate2human ( -- addr len )
flash-header 40 + rx@ (.)
drop dup 0 + bdate-str 6 + 4 move
dup 4 + bdate-str 0 + 2 move
dup 6 + bdate-str 3 + 2 move
dup 8 + bdate-str b + 2 move
a + bdate-str e + 2 move
2d bdate-str 2 + c!
2d bdate-str 5 + c!
20 bdate-str a + c!
3a bdate-str d + c!
bdate-str 10
;
: included  ( fn fn-len -- )
2dup >r >r romfs-lookup dup IF
r> drop r> drop evaluate
ELSE
drop ." Cannot open file : " r> r> type cr
THEN
;
: include  ( " fn " -- )
parse-word included
;
: ?include  ( flag " fn " -- )
parse-word rot IF included ELSE 2drop THEN
;
: include?  ( nargs flag " fn " -- )
parse-word rot IF
rot drop included
ELSE
2drop 0 ?DO drop LOOP
THEN
;
: (print-romfs-file-info)  ( file-addr -- )
9 emit  dup b 0.r  2 spaces  dup 8 + @ 6 0.r  2 spaces  20 + zcount type cr
;
: romfs-list  ( -- )
romfs-base 0 cr BEGIN + dup (print-romfs-file-info) dup @ dup 0= UNTIL 2drop
;
200 cp
: banner
cr ."   Type 'boot' and press return to continue booting the system."
cr ."   Type 'reset-all' and press return to reboot the system."
cr cr
;
: .banner banner console-clean-fifo ;
DEFER find-boot-sector ( -- )
240 cp
d# 512000000 VALUE tb-frequency   \ default value - needed for "ms" to work
-1 VALUE cpu-frequency
: slof-build-id  ( -- str len )
flash-header 10 + dup from-cstring a min
;
: slof-revision s" 001" ;
: read-version-and-date
flash-header 0= IF
s"  " encode-string
ELSE
flash-header 10 + 10
here swap rmove
here 10
s" , " $cat
bdate2human $cat encode-string THEN
;
: invert-region-cs ( addr len cellsize -- )
>r over swap r@ rshift r> swap 1 hv-logical-memop drop
;
: invert-region ( addr len -- )
2dup or 7 and CASE
0 OF 3 invert-region-cs ENDOF
4 OF 2 invert-region-cs ENDOF
3 and
2 OF 1 invert-region-cs ENDOF
dup OF 0 invert-region-cs ENDOF
ENDCASE
;
260 cp
: tb@  ( -- tb )
BEGIN tbu@ tbl@ tbu@ rot over <> WHILE 2drop REPEAT
20 lshift swap ffffffff and or
;
: milliseconds ( -- ms ) tb@ d# 1000 * tb-frequency / ;
: microseconds ( -- us ) tb@ d# 1000000 * tb-frequency / ;
: ms ( ms-to-wait -- ) milliseconds + BEGIN milliseconds over >= UNTIL drop ;
: get-msecs ( -- n ) milliseconds ;
: us  ( us-to-wait -- )  microseconds +  BEGIN microseconds over >= UNTIL  drop ;
2e0 cp
100 CONSTANT quiesce-xt#
CREATE quiesce-xts quiesce-xt# cells allot
quiesce-xts quiesce-xt# cells erase
0 VALUE quiesce-done?
: add-quiesce-xt  ( xt -- )
quiesce-xt# 0 DO
quiesce-xts I cells +    ( xt arrayptr )
dup @ 0=                 ( xt arrayptr true|false )
IF
! UNLOOP EXIT
ELSE                     ( xt arrayptr )
over swap             ( xt xt arrayptr )
@ =                   \ xt already stored ?
IF
drop UNLOOP EXIT
THEN                  ( xt )
THEN
LOOP
drop                        ( xt -- )
." Warning: quiesce xt list is full." cr
;
: quiesce  ( -- )
quiesce-done? IF EXIT THEN
true to quiesce-done?
quiesce-xt# 0 DO
quiesce-xts I cells +    ( arrayptr )
@ dup IF                 ( xt )
EXECUTE
ELSE
drop UNLOOP EXIT
THEN
LOOP
;
300 cp
: load-dev-hci ( num name-str name-len )
s" dev-hci.fs" INCLUDED
;
0 VALUE ohci-init
0 VALUE ehci-init
0 VALUE xhci-init
0 VALUE usb-alias-num
: get-usb-alias-num
usb-alias-num dup 1+ to usb-alias-num
;
: set-ohci-alias  (  -- )
1 to ohci-init 
get-usb-alias-num       ( num )
s" ohci" 1 load-dev-hci
;
: set-ehci-alias  (  -- )
1 to ehci-init
get-usb-alias-num       ( num )
s" ehci" 2 load-dev-hci
;
: set-xhci-alias  (  -- )
1 to xhci-init 
get-usb-alias-num       ( num )
s" xhci" 3 load-dev-hci
;
: usb-enumerate ( hcidev -- )
USB-HCD-INIT
;
: usb-scan ( -- )
." Scanning USB " cr
ohci-init 1 = IF USB-OHCI-REGISTER THEN
ehci-init 1 = IF USB-EHCI-REGISTER THEN
xhci-init 1 = IF USB-XHCI-REGISTER THEN
usb-alias-num 0 ?DO
" usb" i $cathex find-device
" get-hci-dev" get-node find-method
IF
execute usb-enumerate
ELSE
." get-base-address method not found for usb@" i . 
."  Device type: "
" device_type" get-node get-property 0= IF decode-string type cr 2drop THEN
THEN
LOOP
0 set-node     \ FIXME Setting it back
;
320 cp
false VALUE scsi-supp-present?
: scsi-xt-err ." SCSI-ERROR (Intern) " ;
' scsi-xt-err VALUE scsi-open-xt        \ preset with an invalid token
: .wordlists      ( -- )
get-order      ( -- wid1 .. widn n )
dup space 28 emit .d ." word lists : "
0 DO
. 08 emit 2c emit
LOOP
08 emit                 \ 'bs'
29 emit                 \ ')'
cr space 28 emit
." Context: " context dup .
@ 5b emit . 8 emit 5d emit
space
." / Current: " current .
cr
;
: scsi-open  ( -- )
scsi-supp-present? NOT
IF
s" scsi-support.fs" included  ( xt-open )
to scsi-open-xt               (  )
true to scsi-supp-present?
THEN
scsi-open-xt execute
;
340 cp
0 VALUE fdt-debug
TRUE VALUE fdt-cas-fix?
0 VALUE fdt-cas-pass
0 VALUE fdt-generation#
: fdt-update-from-fdt ( -- )
fdt-generation# encode-int s" slof,from-fdt" property
;
fdt-start 0 = IF -1 throw THEN
struct
4 field >fdth_magic
4 field >fdth_tsize
4 field >fdth_struct_off
4 field >fdth_string_off
4 field >fdth_rsvmap_off
4 field >fdth_version
4 field >fdth_compat_vers
4 field >fdth_boot_cpu
4 field >fdth_string_size
4 field >fdth_struct_size
constant /fdth
h# d00dfeed constant OF_DT_HEADER
h#        1 constant OF_DT_BEGIN_NODE
h#        2 constant OF_DT_END_NODE
h#        3 constant OF_DT_PROP
h#        4 constant OF_DT_NOP
h#        9 constant OF_DT_END
0 value fdt-start-addr
0 value fdt-struct
0 value fdt-strings
: fdt-init ( fdt-start -- )
dup to fdt-start-addr
dup dup >fdth_struct_off l@ + to fdt-struct
dup dup >fdth_string_off l@ + to fdt-strings
drop
;
fdt-start fdt-init
: fdt-check-header ( -- )
fdt-start-addr dup 0 = IF
." No flat device tree !" cr drop -1 throw EXIT THEN
hex
fdt-debug IF
." Flat device tree header at 0x" dup . s" :" type cr
."  magic            : 0x" dup >fdth_magic l@ . cr
."  total size       : 0x" dup >fdth_tsize l@ . cr
."  offset to struct : 0x" dup >fdth_struct_off l@ . cr
."  offset to strings: 0x" dup >fdth_string_off l@ . cr
."  offset to rsvmap : 0x" dup >fdth_rsvmap_off l@ . cr
."  version          : " dup >fdth_version l@ decimal . hex cr
."  last compat vers : " dup >fdth_compat_vers l@ decimal . hex cr
dup >fdth_version l@ 2 >= IF
."  boot CPU         : 0x" dup >fdth_boot_cpu l@ . cr
THEN
dup >fdth_version l@ 3 >= IF
."  strings size     : 0x" dup >fdth_string_size l@ . cr
THEN
dup >fdth_version l@ 11 >= IF
."  struct size      : 0x" dup >fdth_struct_size l@ . cr
THEN
THEN
dup >fdth_magic l@ OF_DT_HEADER <> IF
." Flat device tree has incorrect magic value !" cr
drop -1 throw EXIT
THEN
dup >fdth_version l@ 10 < IF
." Flat device tree has usupported version !" cr
drop -1 throw EXIT
THEN
drop
;
fdt-check-header
: fdt-next-tag ( addr -- nextaddr tag )
0	       	      	 	( dummy tag on stack for loop )
BEGIN
drop			( drop previous tag )
dup l@			( read new tag )
swap 4 + swap		( increment addr )
dup OF_DT_NOP <> UNTIL 	( loop until not nop )
;
: fdt-fetch-unit ( addr -- addr $name )
dup from-cstring	       \  get string size
2dup + 1 + 3 + fffffffc and -rot
;
: fdt-reg-unit ( prop-addr prop-len -- )
decode-phys               ( prop-addr' prop-len' phys.lo ... phys.hi )
set-unit                  ( prop-addr' prop-len' )
2drop
;
: fdt-fetch-string ( index -- str-addr str-len )
fdt-strings + dup from-cstring
;
: fdt-create-dec  s" decode-unit" $CREATE , DOES> @ hex64-decode-unit ;
: fdt-create-enc  s" encode-unit" $CREATE , DOES> @ hex64-encode-unit ;
: fdt-prop-is-string?  ( addr len -- string? )
dup 1 < IF 2drop FALSE EXIT THEN                \ Check for valid length
1-
2dup + c@ 0<> IF 2drop FALSE EXIT THEN          \ Check zero-termination
test-string
;
: fdt-encode-prop  ( addr len -- pa ps )
2dup fdt-prop-is-string? IF
1- encode-string
ELSE
encode-bytes
THEN
;
: fdt-unflatten-node ( start -- end )
recursive
fdt-next-tag dup OF_DT_BEGIN_NODE <> IF
s" Weird tag 0x" type . " at start of node" type cr
-1 throw
THEN drop
new-device
fdt-fetch-unit
dup 0 = IF drop drop " /" THEN
40 left-parse-string
device-name
dup IF
" #address-cells" get-parent get-package-property IF
2drop
ELSE
decode-int nip nip
hex-decode-unit
set-unit
THEN
ELSE 2drop THEN
BEGIN
fdt-next-tag dup OF_DT_END_NODE <>
WHILE
dup OF_DT_PROP = IF
drop dup			( drop tag, dup addr     : a1 a1 )
dup l@ dup rot 4 +	( fetch size, stack is   : a1 s s a2)
dup l@ swap 4 +		( fetch nameid, stack is : a1 s s i a3 )
rot			( we now have: a1 s i a3 s )
fdt-encode-prop rot	( a1 s pa ps i)
fdt-fetch-string		( a1 s pa ps na ns )
2dup s" reg" str= IF
2swap 2dup fdt-reg-unit 2swap
THEN
property
+ 8 + 3 + fffffffc and
ELSE dup OF_DT_BEGIN_NODE = IF
drop			( drop tag )
4 -
fdt-unflatten-node
ELSE
drop -1 throw
THEN THEN
REPEAT drop \ drop tag
" #address-cells" get-node get-package-property IF ELSE
decode-int dup fdt-create-dec fdt-create-enc 2drop
THEN
fdt-update-from-fdt
finish-device  
;
: fdt-unflatten-tree
fdt-debug IF
." Unflattening device tree..." cr THEN
fdt-struct fdt-unflatten-node drop
fdt-debug IF
." Done !" cr THEN
;
fdt-unflatten-tree
: fdt-parse-memory
" /memory@0" find-device
" reg" get-node get-package-property IF throw -1 THEN
decode-phys 2drop decode-phys
my-#address-cells 1 > IF 20 << or THEN
fdt-debug IF
dup ." Memory size: " . cr
THEN
MIN-RAM-SIZE swap MIN-RAM-SIZE - release
2drop device-end
;
fdt-parse-memory
: fdt-claim-reserve
fdt-start-addr
dup dup >fdth_tsize l@ 0 claim drop
dup >fdth_rsvmap_off l@ +
BEGIN
dup dup x@ swap 8 + x@
dup 0 <>
WHILE
fdt-debug IF
2dup swap ." Reserve map entry: " . ." : " . cr
THEN
0 claim drop
10 +
REPEAT drop drop drop
;
fdt-claim-reserve 
0 VALUE (fdt-phandle-replaced)
: fdt-replace-interrupt-map  ( old new prop-addr prop-len -- old new )
BEGIN
dup                    ( old new prop-addr prop-len prop-len )
WHILE
swap dup 10 +          ( old new prop-len prop-addr prop-addr+10 )
dup l@ 5 pick = IF
3 pick swap l!
TRUE TO (fdt-phandle-replaced)
ELSE
drop
THEN
1c + swap 1c -
REPEAT
2drop
;
: (fdt-replace-phandles) ( old new propname propnamelen node -- )
get-property IF 2drop EXIT THEN
BEGIN
dup
WHILE                   ( old new prop-addr prop-len )
over l@
4 pick = IF
2 pick 2 pick l! \ replace old with new in place
TRUE TO (fdt-phandle-replaced)
THEN
4 - swap 4 + swap
REPEAT
2drop 2drop
;
: (phandle>node) ( phandle current -- node|0 )
dup s" phandle" rot get-property 0= IF
decode-int nip nip ( phandle current phandle-prop )
2 pick = IF
fdt-debug IF ."        Found phandle; " dup . ."  <= " over . cr THEN
nip            ( current )
EXIT
THEN
ELSE
dup s" linux-phandle" rot get-property 0= IF
decode-int nip nip ( phandle current phandle-prop )
2 pick = IF
fdt-debug IF ."        Found linux-phandle; " dup . ."  <= " over . cr THEN
nip            ( current )
EXIT
THEN
THEN
THEN
child BEGIN
dup
WHILE
2dup
RECURSE
?dup 0<> IF
nip nip
EXIT
THEN
PEER
REPEAT
2drop 0
;
: phandle>node ( phandle -- node ) s" /" find-node (phandle>node)  ;
: (fdt-patch-phandles) ( prop-addr prop-len -- )
BEGIN
dup
WHILE                   ( prop-addr prop-len )
over l@ phandle>node
?dup 0<> IF
fdt-debug IF ."     ### Patching phandle=" 2 pick l@ . cr THEN
2 pick l!
TRUE TO (fdt-phandle-replaced)
THEN
4 - swap 4 + swap
REPEAT
2drop
;
: (fdt-patch-interrupt-map) ( prop-addr prop-len -- )
over 10 + l@ phandle>node ?dup 0= IF 2drop EXIT THEN
-rot
fdt-debug IF ."      ### Patching interrupt-map: " over 10 + l@ . ."  => " 2 pick . cr THEN
TRUE TO (fdt-phandle-replaced)
BEGIN
dup
WHILE                   ( newph prop-addr prop-len )
2 pick 2 pick 10 + l!
1c - swap 1c  + swap
REPEAT
3drop
;
: fdt-patch-phandles ( prop-addr prop-len nameadd namelen -- )
2dup s" interrupt-map" str= IF 2drop (fdt-patch-interrupt-map) EXIT THEN
2dup s" interrupt-parent" str= IF 2drop (fdt-patch-phandles) EXIT THEN
2dup s" ibm,gpu" str= IF 2drop (fdt-patch-phandles) EXIT THEN
2dup s" ibm,npu" str= IF 2drop (fdt-patch-phandles) EXIT THEN
2dup s" ibm,nvlink" str= IF 2drop (fdt-patch-phandles) EXIT THEN
2dup s" memory-region" str= IF 2drop (fdt-patch-phandles) EXIT THEN
4drop
;
: fdt-replace-all-phandles ( old new node -- )
>r
s" interrupt-map" r@ get-property 0= IF
fdt-replace-interrupt-map
THEN
2dup s" interrupt-parent" r@ (fdt-replace-phandles)
2dup s" ibm,gpu" r@ (fdt-replace-phandles)
2dup s" ibm,npu" r@ (fdt-replace-phandles)
2dup s" ibm,nvlink" r@ (fdt-replace-phandles)
2dup s" memory-region" r@ (fdt-replace-phandles)
r>
child BEGIN
dup
WHILE
3dup RECURSE
PEER
REPEAT
3drop
;
: fdt-update-phandle ( val node -- )
>r
FALSE TO (fdt-phandle-replaced)
r@ s" /" find-node               ( val node root )
fdt-replace-all-phandles
(fdt-phandle-replaced) IF
r@ set-node
s" phandle" delete-property
s" linux,phandle" delete-property
ELSE
diagnostic-mode? IF
cr ." Warning: Did not replace phandle in " r@ node>path type cr
THEN
THEN
r> drop
;
: fdt-fix-node-phandle  ( node -- )
>r
s" phandle" r@ get-property 0= IF
decode-int nip nip
r@ fdt-update-phandle
THEN
r> drop
;
: fdt-fix-phandles  ( node -- )
dup fdt-fix-node-phandle
child BEGIN
dup
WHILE
dup RECURSE
PEER
REPEAT
drop
device-end
;
: str=phandle? ( s len -- true|false )
2dup s" phandle" str= >r
s" linux,phandle" str=
r> or
;
: fdt-cas-finish-device ( -- )
" reg" get-node get-package-property IF ELSE fdt-reg-unit THEN
get-node finish-device set-node
;
: (fdt-fix-cas-node) ( start -- end )
recursive
fdt-next-tag dup OF_DT_BEGIN_NODE <> IF
." Error " cr
false to fdt-cas-fix?
EXIT
THEN drop
fdt-fetch-unit		    ( a1 $name )
dup 0 = IF drop drop " /" THEN
40 left-parse-string
2swap ?dup 0 <> IF
nip
1 + + \ Add the string len +@
ELSE
drop
THEN
fdt-cas-pass 0= IF
2dup " interrupt-controller" find-substr 0= IF
" interrupt-controller" find-node ?dup 0 <> IF
fdt-debug IF ." Deleting existing node: " dup .node cr THEN
delete-node
THEN
THEN
THEN
2dup find-node ?dup 0 <> IF
set-node
fdt-debug IF ." Setting node: " 2dup type cr THEN
2drop
0
ELSE
fdt-cas-pass 0 <> IF
." Cannot handle FDT update for the " 2dup type
."  node, rebooting" cr
reset-all
THEN
fdt-debug IF ." Creating node: " 2dup type cr THEN
new-device
2dup " @" find-substr nip
device-name
1
THEN
swap			( newnode? a1 )
fdt-debug IF ." Current  now: " pwd  get-node ."  = " . cr THEN
fdt-cas-pass 0= IF
fdt-update-from-fdt
THEN
BEGIN
fdt-next-tag dup OF_DT_END_NODE <>
WHILE
dup OF_DT_PROP = IF
drop dup		( newnode? a1 a1 )
dup l@ dup rot 4 +	( newnode? a1 s s a2)
dup l@ swap 4 +	( newnode? a1 s s i a3 )
rot			( newnode? a1 s i a3 s )
fdt-encode-prop rot	( newnode? a1 s pa ps i)
fdt-fetch-string	( newnode? a1 s pa ps na ns )
fdt-cas-pass CASE
0 OF
2dup str=phandle? 7 pick or IF
fdt-debug IF 4dup ."   Property: " type ." =" swap ." @" . ."  " .d ."  bytes" cr THEN
property
ELSE
4drop
THEN
ENDOF
1 OF
2dup str=phandle? not IF
fdt-debug IF 4dup ."   Property: "  type ." =" swap ." @" . ."  " .d ."  bytes" cr THEN
4dup fdt-patch-phandles
property
ELSE
4drop
THEN
ENDOF
2 OF
2dup str=phandle? IF
fdt-debug IF 4dup ."   Deleting: " type ." =" swap ." @" . ."  " .d ."  bytes" cr THEN
delete-property
2drop
ELSE
4drop
THEN
ENDOF
ENDCASE
+ 8 + 3 + fffffffc and
ELSE		( newnode? a1 tag )
dup OF_DT_BEGIN_NODE = IF
2 pick IF
rot drop 0 -rot
fdt-cas-finish-device
fdt-debug IF ." Finished node: " pwd  get-node ."  = " . cr THEN
THEN
drop			( a1 )
4 -
(fdt-fix-cas-node)
get-parent set-node
ELSE
." Error " cr
drop
false to fdt-cas-fix?
EXIT
THEN
THEN
REPEAT
drop
swap		( a1 newnode? )
IF
fdt-cas-finish-device
fdt-debug IF ." Finished subnode: " pwd  get-node ."  = " . cr THEN
THEN
;
: alias-dev-path ( xt -- dev-path len )
link> execute decode-string	2swap 2drop
;
: alias-name ( xt -- alias-name len )
link> >name name>string
;
: fdt-cas-alias-obsolete? ( xt -- true|false )
alias-dev-path find-node 0=
;
: (fdt-cas-delete-obsolete-aliases) ( xt -- )
dup IF
dup @
recurse
dup alias-name s" name" str= IF ELSE
dup fdt-cas-alias-obsolete? IF
fdt-debug IF ." Deleting obsolete alias: " dup alias-name type ."  -> " dup alias-dev-path type cr THEN
dup alias-name
delete-property
THEN
THEN
THEN
drop
;
: fdt-cas-delete-obsolete-aliases ( -- )
s" /aliases" find-device
get-node node>properties @ cell+ @ (fdt-cas-delete-obsolete-aliases)
device-end
;
: fdt-cas-node-obsolete? ( node -- true|false)
s" slof,from-fdt" rot get-package-property IF
false
ELSE
decode-int nip nip fdt-generation# <
THEN
;
: (fdt-cas-search-obsolete-nodes) ( node -- )
dup child
BEGIN
dup
WHILE
dup recurse
peer
REPEAT
drop
dup fdt-cas-node-obsolete? IF
fdt-debug IF dup ." Deleting obsolete node: " dup .node ." = " . cr THEN
dup delete-node
THEN
drop
;
: fdt-cas-delete-obsolete-nodes ( -- )
s" /" find-device get-node (fdt-cas-search-obsolete-nodes)
fdt-cas-delete-obsolete-aliases
;
: fdt-fix-cas-node ( start -- )
fdt-generation# 1+ to fdt-generation#
0 to fdt-cas-pass dup (fdt-fix-cas-node) drop \ Add phandles
fdt-cas-delete-obsolete-nodes                 \ Delete removed devices
1 to fdt-cas-pass dup (fdt-fix-cas-node) drop \ Patch+add other properties
2 to fdt-cas-pass dup (fdt-fix-cas-node) drop \ Delete phandles from pass 0
drop
;
: fdt-fix-cas-success
fdt-cas-fix?
;
s" /" find-node fdt-fix-phandles
360 cp
defer (client-exec)
defer client-exec
defer callback
defer continue-client
0 VALUE chosen-node
: chosen
chosen-node dup 0= IF
drop s" /chosen" find-node dup to chosen-node
THEN
;
: set-chosen ( prop len name len -- )
chosen set-property ;
: get-chosen ( name len -- [ prop len ] success )
chosen get-property 0= ;
VARIABLE chosen-cpu-ihandle
: set-chosen-cpu ( -- )
s" /cpus" find-node  dup 0= ABORT" /cpus not found"
child                dup 0= ABORT" /cpus/cpu not found"
0 0 rot open-node
dup chosen-cpu-ihandle !  encode-int s" cpu" set-chosen
;
: chosen-cpu-unit ( -- ret ) chosen-cpu-ihandle @ ihandle>phandle >unit ;
" /" find-node dup 0= IF
drop
new-device
s" /" device-name
ELSE
extend-device
THEN
" /chosen" find-node dup 0= IF
drop
new-device
s" chosen" device-name
s" " encode-string s" bootargs" property
s" " encode-string s" bootpath" property
finish-device
ELSE
drop
THEN
new-device
s" aliases" device-name
: open  true ;
: close ;
finish-device
new-device
s" options" device-name
finish-device
new-device
s" openprom" device-name
0 0 s" relative-addressing" property
finish-device
new-device 
s" packages" device-name
get-node to packages
new-device
s" deblocker" device-name
INSTANCE VARIABLE offset
INSTANCE VARIABLE block-size
INSTANCE VARIABLE max-transfer
INSTANCE VARIABLE my-block
INSTANCE VARIABLE adr
INSTANCE VARIABLE len
INSTANCE VARIABLE fail-count
: open
s" block-size" ['] $call-parent CATCH IF 2drop false EXIT THEN
block-size !
s" max-transfer" ['] $call-parent CATCH IF 2drop false EXIT THEN
max-transfer !
block-size @ alloc-mem my-block !
0 offset !
true ;
: close  my-block @ block-size @ free-mem ;
: seek ( lo hi -- status ) \ XXX: perhaps we should fail if the underlying
lxjoin offset !  0 ;
: block+remainder ( -- block# remainder )  offset @ block-size @ u/mod swap ;
: read-blocks ( addr block# #blocks -- actual )  s" read-blocks" $call-parent ;
: read ( addr len -- actual )
dup >r  len ! adr !
block+remainder dup IF ( block# offset-in-block )
>r my-block @ swap 1 read-blocks drop
my-block @ r@ + adr @ block-size @ r> - len @ min dup >r move
r> dup negate len +! dup adr +! offset +! ELSE 2drop THEN
0 fail-count !
BEGIN len @ block-size @ >= WHILE
adr @ block+remainder drop len @ max-transfer @ min block-size @ / read-blocks
dup 0= IF
1 fail-count +!
fail-count @ 5 >= IF r> drop EXIT THEN
ELSE
0 fail-count !
THEN
block-size @ * dup negate len +! dup adr +! offset +!
REPEAT
len @ IF my-block @ block+remainder drop 1 read-blocks drop
my-block @ adr @ len @ move THEN
r> ;
: write-blocks ( addr block# #blocks -- #writtenblks )
s" write-blocks" $call-parent
;
: write ( addr len -- actual )
dup block-size @ mod IF
." ERROR: Can not write partial sector length." cr
2drop 0 EXIT
THEN
block-size @ /                             ( addr #blocks )
offset @                                   ( addr #blocks offset )
dup block-size @ mod IF
." ERROR: Can not write at partial sector offset." cr
3drop 0 EXIT
THEN
block-size @ / swap                        ( addr block# #blocks )
write-blocks                               ( #writtenblks )
block-size @ *
dup offset +!
;
finish-device
new-device
false VALUE debug-disk-label?
d# 65536 value max-prep-partition-blocks
d# 4096 CONSTANT block-array-size
s" disk-label" device-name
0 INSTANCE VALUE partition
0 INSTANCE VALUE part-offset
0 INSTANCE VALUE disk-chrp-boot
0 INSTANCE VALUE part-start
0 INSTANCE VALUE lpart-start
0 INSTANCE VALUE part-size
0 INSTANCE VALUE dos-logical-partitions
0 INSTANCE VALUE block-size
0 INSTANCE VALUE block
0 INSTANCE VALUE args
0 INSTANCE VALUE args-len
0 INSTANCE VALUE gpt-part-size
0 INSTANCE VALUE seek-pos
INSTANCE VARIABLE block#  \ variable to store logical sector#
INSTANCE VARIABLE hit#    \ partition counter
INSTANCE VARIABLE success-flag
0ff constant END-OF-DESC
3 constant  PARTITION-ID
48 constant VOL-PART-LOC
STRUCT
1b8 field mbr>boot-loader
/l field mbr>disk-signature
/w field mbr>null
40 field mbr>partition-table
/w field mbr>magic
CONSTANT /mbr
STRUCT
/c field part-entry>active
/c field part-entry>start-head
/c field part-entry>start-sect
/c field part-entry>start-cyl
/c field part-entry>id
/c field part-entry>end-head
/c field part-entry>end-sect
/c field part-entry>end-cyl
/l field part-entry>sector-offset
/l field part-entry>sector-count
CONSTANT /partition-entry
STRUCT
8 field gpt>signature
4 field gpt>revision
4 field gpt>header-size
4 field gpt>header-crc32
4 field gpt>reserved
8 field gpt>current-lba
8 field gpt>backup-lba
8 field gpt>first-lba
8 field gpt>last-lba
10 field gpt>disk-guid
8 field gpt>part-entry-lba
4 field gpt>num-part-entry
4 field gpt>part-entry-size
4 field gpt>part-array-crc32
1a4 field gpt>reserved
CONSTANT /gpt-header
STRUCT
10 field gpt-part-entry>part-type-guid
10 field gpt-part-entry>part-guid
8 field gpt-part-entry>first-lba
8 field gpt-part-entry>last-lba
8 field gpt-part-entry>attribute
48 field gpt-part-entry>part-name
CONSTANT /gpt-part-entry
: offset ( d.rel -- d.abs )
part-offset xlsplit d+
;
: seek  ( pos.lo pos.hi -- status )
offset
debug-disk-label? IF 2dup ." seek-parent: pos.hi=0x" u. ." pos.lo=0x" u. THEN
s" seek" $call-parent
debug-disk-label? IF dup ." status=" . cr THEN
;
: read ( addr len -- actual )
debug-disk-label? IF 2dup swap ." read-parent: addr=0x" u. ." len=" .d THEN
s" read" $call-parent
debug-disk-label? IF dup ." actual=" .d cr THEN
;
: write ( addr len -- actual )
debug-disk-label? IF 2dup swap ." write-parent: addr=0x" u. ." len=" .d THEN
s" write" $call-parent
debug-disk-label? IF dup ." actual=" .d cr THEN
;
: read-sector ( sector-number -- )
block-size * 0 seek drop      \ seek to sector
block block-size read drop    \ read sector
;
: (.part-entry) ( part-entry )
cr ." part-entry>active:        " dup part-entry>active c@ .d
cr ." part-entry>start-head:    " dup part-entry>start-head c@ .d
cr ." part-entry>start-sect:    " dup part-entry>start-sect c@ .d
cr ." part-entry>start-cyl:     " dup part-entry>start-cyl  c@ .d
cr ." part-entry>id:            " dup part-entry>id c@ .d
cr ." part-entry>end-head:      " dup part-entry>end-head c@ .d
cr ." part-entry>end-sect:      " dup part-entry>end-sect c@ .d
cr ." part-entry>end-cyl:       " dup part-entry>end-cyl c@ .d
cr ." part-entry>sector-offset: " dup part-entry>sector-offset l@-le .d
cr ." part-entry>sector-count:  " dup part-entry>sector-count l@-le .d
cr
;
: (.name) r@ begin cell - dup @ <colon> = UNTIL xt>name cr type space ;
: init-block ( -- )
s" block-size" ['] $call-parent CATCH IF ABORT" parent has no block-size." THEN
to block-size
block-array-size alloc-mem
dup block-array-size erase
to block
debug-disk-label? IF
." init-block: block-size=" block-size .d ." block=0x" block u. cr
THEN
;
: partition>part-entry ( partition -- part-entry )
1- /partition-entry * block mbr>partition-table +
;
: partition>start-sector ( partition -- sector-offset )
partition>part-entry part-entry>sector-offset l@-le
;
: no-mbr? ( -- true|false )
0 read-sector
1 partition>part-entry part-entry>id c@ ee = IF TRUE EXIT THEN \ GPT partition found
block mbr>magic w@-le aa55 <>
;
: no-gpt? ( -- true|false )
0 read-sector
1 partition>part-entry part-entry>id c@ ee <> IF true EXIT THEN
block mbr>magic w@-le aa55 <>
;
: pc-extended-partition? ( part-entry-addr -- true|false )
part-entry>id c@      ( id )
dup 5 = swap          ( true|false id )
dup f = swap          ( true|false true|false id )
85 =                  ( true|false true|false true|false )
or or                 ( true|false )
;
: count-dos-logical-partitions ( -- #logical-partitions )
no-mbr? IF 0 EXIT THEN
0 5 1 DO                                ( current )
i partition>part-entry               ( current part-entry )
dup pc-extended-partition? IF
part-entry>sector-offset l@-le    ( current sector )
dup to part-start to lpart-start  ( current )
BEGIN
part-start read-sector          \ read EBR
1 partition>start-sector IF
1+
THEN \ another logical partition
2 partition>start-sector
?dup IF lpart-start + to part-start false ELSE true THEN
UNTIL
ELSE
drop
THEN
LOOP
;
: (get-dos-partition-params) ( ext-part-start part-entry -- offset count active? id )
dup part-entry>sector-offset l@-le rot + swap ( offset part-entry )
dup part-entry>sector-count l@-le swap        ( offset count part-entry )
dup part-entry>active c@ 80 = swap            ( offset count active? part-entry )
part-entry>id c@                              ( offset count active? id )
;
: find-dos-partition ( partition# -- false | offset count active? id true )
to partition 0 to part-start 0 to part-offset
partition 0<= IF 0 to partition false EXIT THEN
no-mbr? IF 0 to partition false EXIT THEN
partition 4 <= IF \ Is this a primary partition?
0 partition partition>part-entry
(get-dos-partition-params)
true EXIT
ELSE
partition 4 - 0 5 1 DO                      ( logical-partition current )
i partition>part-entry                   ( log-part current part-entry )
dup pc-extended-partition? IF
part-entry>sector-offset l@-le        ( log-part current sector )
dup to part-start to lpart-start      ( log-part current )
BEGIN
part-start read-sector             \ read EBR
1 partition>start-sector IF        \ first partition entry
1+ 2dup = IF                    ( log-part current )
2drop
part-start 1 partition>part-entry
(get-dos-partition-params)
true UNLOOP EXIT
THEN
2 partition>start-sector
?dup IF lpart-start + to part-start false ELSE true THEN
ELSE
true
THEN
UNTIL
ELSE
drop
THEN
LOOP
2drop false
THEN
;
: try-dos-partition ( -- okay? )
no-mbr? IF
debug-disk-label? IF cr ." No DOS disk-label found." cr THEN
false EXIT
THEN
count-dos-logical-partitions TO dos-logical-partitions
debug-disk-label? IF
." Found " dos-logical-partitions .d ." logical partitions" cr
." Partition = " partition .d cr
THEN
partition 1 5 dos-logical-partitions +
within 0= IF
cr ." Partition # not 1-" 4 dos-logical-partitions + . cr false EXIT
THEN
partition find-dos-partition IF
2drop
to part-size
block-size * to part-offset
true
ELSE
false
THEN
;
: has-iso9660-filesystem  ( -- TRUE|FALSE )
10 800 * 0 seek drop      \ seek to sector
block 800 read drop       \ read sector
block c@ 1 =
block 1+ 5 s" CD001"  str=
and
dup IF 800 to block-size THEN
;
: fat-bootblock? ( addr -- flag )
dup c@ e9 = IF drop true EXIT THEN
dup c@ eb = swap 2+ c@ 90 = and
;
: measure-mbr ( addr length -- )
s" /ibm,vtpm" find-node ?dup IF
s" measure-hdd-mbr" rot $call-static
ELSE
2drop
THEN
;
: load-from-dos-boot-partition ( addr -- size )
no-mbr? IF drop FALSE EXIT THEN  \ read MBR and check for DOS disk-label magic
count-dos-logical-partitions TO dos-logical-partitions
debug-disk-label? IF
." Found " dos-logical-partitions .d ." logical partitions" cr
." Partition = " partition .d cr
THEN
5 dos-logical-partitions + 1 DO
i find-dos-partition IF        ( addr offset count active? id )
41 = and                    ( addr offset count prep-boot-part? )
IF                          ( addr offset count )
max-prep-partition-blocks min  \ reduce load size
swap                     ( addr count offset )
block-size * to part-offset
0 0 seek drop            ( addr offset )
block-size * read        ( size )
block block-size measure-mbr
UNLOOP EXIT
ELSE
2drop                    ( addr )
THEN
THEN
LOOP
drop 0
;
: uuid! ( v1 v2 v3 v4 addr -- ) >r r@ 8 + x! r@ 6 + w!-le r@ 4 + w!-le r> l!-le ;
: uuid= ( addr1 addr2 -- true|false )  10 comp 0= ;
CREATE GPT-PREP-PARTITION 10 allot
9E1A2D38 C612 4316 AA268B49521E5A8B GPT-PREP-PARTITION uuid!
: gpt-prep-partition? ( -- true|false )
block gpt-part-entry>part-type-guid
GPT-PREP-PARTITION uuid=
;
CREATE GPT-BASIC-DATA-PARTITION 10 allot
EBD0A0A2 B9E5 4433 87C068B6B72699C7 GPT-BASIC-DATA-PARTITION uuid!
: gpt-basic-data-partition? ( -- true|false )
block gpt-part-entry>part-type-guid
GPT-BASIC-DATA-PARTITION uuid=
;
CREATE GPT-LINUX-PARTITION 10 allot
0FC63DAF 8483 4772 8E793D69D8477DE4 GPT-LINUX-PARTITION uuid!
: gpt-linux-partition? ( -- true|false )
block gpt-part-entry>part-type-guid
GPT-LINUX-PARTITION uuid=
;
4546492050415254 CONSTANT GPT-SIGNATURE
: get-gpt-partition ( -- true|false )
no-gpt? IF false EXIT THEN
debug-disk-label? IF cr ." GPT partition found " cr  THEN
1 read-sector
block gpt>part-entry-lba x@-le
block-size * to seek-pos
block gpt>part-entry-size l@-le to gpt-part-size
gpt-part-size block-array-size > IF
cr ." GPT part size exceeds buffer allocated " cr
false exit
THEN
block gpt>signature x@ GPT-SIGNATURE =
;
: measure-gpt-partition ( -- )
s" /ibm,vtpm" find-node ?dup IF
get-gpt-partition 0= if drop EXIT THEN
block block-size tpm-gpt-set-lba1
block gpt>num-part-entry l@-le
1+ 1 ?DO
seek-pos 0 seek drop
block gpt-part-size read drop
block gpt-part-size tpm-gpt-add-entry
seek-pos gpt-part-size + to seek-pos
LOOP
s" measure-gpt" rot $call-static
THEN
;
: measure-bootloader ( data-ptr data-len -- )
s" /ibm,vtpm" find-node IF
4 -rot                    ( 4 data-ptr data-len )
c -rot                    ( 4 c data-ptr data-len )
s" BOOTLOADER"            ( 4 c data-ptr data-len desc-ptr desc-len )
true tpm-hash-log-extend-event-buffer   ( errcode )
drop
ELSE
2drop
THEN
;
: load-from-gpt-prep-partition ( addr -- size )
get-gpt-partition 0= IF false EXIT THEN
block gpt>num-part-entry l@-le dup 0= IF false exit THEN
1+ 1 ?DO
seek-pos 0 seek drop
block gpt-part-size read drop gpt-prep-partition? IF
debug-disk-label? IF  ." GPT PReP partition found " cr THEN
block gpt-part-entry>first-lba x@-le ( addr first-lba )
block gpt-part-entry>last-lba x@-le  ( addr first-lba last-lba)
over - 1+                            ( addr first-lba blocks )
swap                                 ( addr blocks first-lba )
block-size * to part-offset          ( addr blocks )
0 0 seek drop                        ( addr blocks )
over swap                            ( addr addr blocks)
block-size * read                    ( addr size )
2dup measure-bootloader              ( addr size )
nip                                  ( size)
UNLOOP EXIT
THEN
seek-pos gpt-part-size + to seek-pos
LOOP
false
;
: (interpose-filesystem) ( str len -- )
find-package IF args args-len rot interpose THEN
;
: try-ext2-files ( -- found? )
2 read-sector               \ read first superblock
block d# 56 + w@-le         \ fetch s_magic
ef53 <> IF false EXIT THEN  \ s_magic found?
s" ext2-files" (interpose-filesystem)
true
;
: try-gpt-dos-partition ( -- true|false )
measure-gpt-partition
get-gpt-partition 0= IF false EXIT THEN
block gpt>num-part-entry l@-le dup 0= IF false EXIT THEN
1+ 1 ?DO
seek-pos 0 seek drop
block gpt-part-size read drop
gpt-basic-data-partition? gpt-linux-partition? or IF
debug-disk-label? IF ." GPT BASIC DATA partition found " cr THEN
block gpt-part-entry>first-lba x@-le       ( first-lba )
dup to part-start                          ( first-lba )
block gpt-part-entry>last-lba x@-le        ( first-lba last-lba )
over - 1+                                  ( first-lba s1 )
block-size * to part-size                  ( first-lba )
block-size * to part-offset                ( )
0 0 seek drop
block block-size read drop
block fat-bootblock?                    ( true|false )
UNLOOP EXIT
THEN
seek-pos gpt-part-size + to seek-pos
LOOP
false
;
: parse-bootinfo-txt  ( addr len -- str len )
2dup s" <boot-script>" find-substr       ( addr len pos1 )
2dup = IF
3drop 0 0 EXIT
THEN
dup >r - swap r> + swap                  ( addr1 len1 )
2dup s" &device;:" find-substr           ( addr1 len1 posdev )
2dup = IF
3drop 0 0 EXIT
THEN
9 +                                      \ Skip the "&device;:" string
dup >r - swap r> + swap                  ( addr2 len2 )
2dup s" </boot-script>" find-substr nip  ( addr2 len3 )
debug-disk-label? IF
." Extracted boot loader from bootinfo.txt: '"
2dup type ." '" cr
THEN
;
: load-chrp-boot-file ( addr -- size )
my-parent instance>path
disk-chrp-boot @ 1 = IF
s" :1,\ppc\bootinfo.txt" $cat strdup       ( addr str len )
ELSE
s" :\ppc\bootinfo.txt" $cat strdup       ( addr str len )
THEN
open-dev dup 0= IF 2drop 0 EXIT THEN
>r dup                                   ( addr addr R:ihandle )
dup s" load" r@ $call-method             ( addr addr size R:ihandle )
r> close-dev                             ( addr addr size )
parse-bootinfo-txt                       ( addr fnstr fnlen )
dup 0= IF 3drop 0 EXIT THEN
2dup 20 findchar IF
>r 2dup r@ - 1- swap r@ + 1+ swap     ( addr fnstr fnlen pstr plen  R: offset )
encode-string s" bootargs" set-chosen
drop r>
THEN
my-parent instance>path      ( addr fnstr fnlen nstr nlen )
s" :" $cat 2swap $cat strdup             ( addr str len )
2dup encode-string s" bootpath" set-chosen
open-dev dup 0= IF ." failed to load CHRP boot loader." 2drop 0 EXIT THEN
>r s" load" r@ $call-method              ( size R:ihandle )
r> close-dev                             ( size )
;
: load-from-boot-partition ( addr -- size )
debug-disk-label? IF ." Trying DOS boot " .s cr THEN
dup load-from-dos-boot-partition ?dup 0 <> IF nip EXIT THEN
debug-disk-label? IF ." Trying CHRP boot " .s cr THEN
1 disk-chrp-boot !
dup load-chrp-boot-file ?dup 0 <> IF nip EXIT THEN
0 disk-chrp-boot !
debug-disk-label? IF ." Trying GPT boot " .s cr THEN
load-from-gpt-prep-partition
;
: parse-partition ( -- okay? )
0 to partition
0 to part-offset
0 to part-size
my-args to args-len to args
debug-disk-label? IF
cr ." disk-label parse-partition: my-args=" my-args type cr
THEN
args-len 0 = IF true EXIT THEN
my-args [char] , findchar 0= IF \ no comma?
args c@ isdigit not IF       \ ... and not a partition number?
true EXIT                 \ ... then it's not a partition we can parse
THEN
ELSE
drop
THEN
my-args [char] , split to args-len to args
dup 0= IF 2drop true EXIT THEN \ no first argument
base @ >r decimal $number r> base !
IF cr ." Not a partition #" false EXIT THEN
to partition
true
;
: try-dos-files ( -- found? )
no-mbr? IF false EXIT THEN
block fat-bootblock? 0= IF false EXIT THEN
s" fat-files" (interpose-filesystem)
true
;
: try-iso9660-files
has-iso9660-filesystem 0= IF false exit THEN
s" iso-9660" (interpose-filesystem)
true
;
: try-files ( -- found? )
args-len 0= IF true EXIT THEN
try-dos-files IF true EXIT THEN
try-ext2-files IF true EXIT THEN
try-iso9660-files IF true EXIT THEN
false
;
: try-partitions ( -- found? )
try-dos-partition IF try-files EXIT THEN
try-gpt-dos-partition IF try-files EXIT THEN
false
;
: close ( -- )
debug-disk-label? IF ." Closing disk-label: block=0x" block u. ." block-size=" block-size .d cr THEN
block block-array-size free-mem
;
: open ( -- true|false )
init-block
parse-partition 0= IF
close
false EXIT
THEN
partition IF
try-partitions
ELSE
try-files
THEN
dup 0= IF debug-disk-label? IF ." not found." cr THEN close THEN \ free memory again
;
: load ( addr -- size )
debug-disk-label? IF
." load: " dup u. cr
THEN
args-len IF
TRUE ABORT" Load done w/o filesystem"
ELSE
partition IF
0 0 seek drop
part-size IF
part-size max-prep-partition-blocks min   \ Load size
ELSE
max-prep-partition-blocks
THEN
200 *  read
ELSE
has-iso9660-filesystem IF
dup load-chrp-boot-file ?dup 0 > IF nip EXIT THEN
THEN
load-from-boot-partition
dup 0= ABORT" No boot partition found"
THEN
THEN
;
finish-device
new-device
s" fat-files" device-name
INSTANCE VARIABLE bytes/sector
INSTANCE VARIABLE sectors/cluster
INSTANCE VARIABLE #reserved-sectors
INSTANCE VARIABLE #fats
INSTANCE VARIABLE #root-entries
INSTANCE VARIABLE fat32-root-cluster
INSTANCE VARIABLE total-#sectors
INSTANCE VARIABLE media-descriptor
INSTANCE VARIABLE sectors/fat
INSTANCE VARIABLE sectors/track
INSTANCE VARIABLE #heads
INSTANCE VARIABLE #hidden-sectors
INSTANCE VARIABLE fat-type
INSTANCE VARIABLE bytes/cluster
INSTANCE VARIABLE fat-offset
INSTANCE VARIABLE root-offset
INSTANCE VARIABLE cluster-offset
INSTANCE VARIABLE #clusters
: seek  s" seek" $call-parent ;
: read  s" read" $call-parent ;
INSTANCE VARIABLE data
INSTANCE VARIABLE #data
: free-data
data @ ?dup IF #data @ free-mem  0 data ! THEN ;
: read-data ( offset size -- )
free-data  dup #data ! alloc-mem data !
xlsplit seek            -2 and ABORT" fat-files read-data: seek failed"
data @ #data @ read #data @ <> ABORT" fat-files read-data: read failed" ;
CREATE fat-buf 8 allot
: read-fat ( cluster# -- data )
fat-buf 8 erase
1 #split fat-type @ * 2/ 2/ fat-offset @ +
xlsplit seek -2 and ABORT" fat-files read-fat: seek failed"
fat-buf 8 read 8 <> ABORT" fat-files read-fat: read failed"
fat-buf 8c@ bxjoin fat-type @ dup >r 2* #split drop r> #split
rot IF swap THEN drop ;
INSTANCE VARIABLE next-cluster
: read-cluster ( cluster# -- )
dup bytes/cluster @ * cluster-offset @ + bytes/cluster @ read-data
read-fat dup #clusters @ >= IF drop 0 THEN next-cluster ! ;
: read-dir ( cluster# -- )
?dup 0= IF
#root-entries @ 0= IF
fat32-root-cluster @ read-cluster
ELSE
root-offset @ #root-entries @ 20 * read-data 0 next-cluster !
THEN
ELSE
read-cluster
THEN
;
: get-cluster ( direntry -- cluster# )
fat-type @ 20 = IF
dup 14 + 2c@ bwjoin 10 lshift
ELSE 0 THEN
swap 1a + 2c@ bwjoin +
;
: .time ( x -- )
base @ >r decimal
b #split 2 0.r [char] : emit  5 #split 2 0.r [char] : emit  2* 2 0.r
r> base ! ;
: .date ( x -- )
base @ >r decimal
9 #split 7bc + 4 0.r [char] - emit  5 #split 2 0.r [char] - emit  2 0.r
r> base ! ;
: .attr ( attr -- )
6 0 DO dup 1 and IF s" RHSLDA" drop i + c@ ELSE bl THEN emit u2/ LOOP drop ;
: .dir-entry ( adr -- )
dup 0b + c@ 8 and IF drop EXIT THEN \ volume label, not a file
dup c@ e5 = IF drop EXIT THEN \ deleted file
cr
dup get-cluster [char] # emit 8 0.r space \ starting cluster
dup 18 + 2c@ bwjoin .date space
dup 16 + 2c@ bwjoin .time space
dup 1c + 4c@ bljoin base @ decimal swap a .r base ! space \ size in bytes
dup 0b + c@ .attr space
dup 8 BEGIN 2dup 1- + c@ 20 = over and WHILE 1- REPEAT type
dup 8 + 3 BEGIN 2dup 1- + c@ 20 = over and WHILE 1- REPEAT dup IF
[char] . emit type ELSE 2drop THEN
drop ;
: .dir-entries ( adr n -- )
0 ?DO dup i 20 * + dup c@ 0= IF drop LEAVE THEN .dir-entry LOOP drop ;
: .dir ( cluster# -- )
read-dir BEGIN data @ #data @ 20 / .dir-entries next-cluster @ WHILE
next-cluster @ read-cluster REPEAT ;
: str-upper ( str len adr -- ) \ Copy string to adr, uppercase
-rot bounds ?DO i c@ upc over c! char+ LOOP drop ;
CREATE dos-name b allot
: make-dos-name ( str len -- )
dos-name b bl fill
2dup [char] . findchar IF
3dup 1+ /string 3 min dos-name 8 + str-upper nip THEN
8 min dos-name str-upper ;
: (find-file) ( -- cluster file-len is-dir? true | false )
data @ BEGIN dup data @ #data @ + < WHILE
dup dos-name b comp WHILE 20 + REPEAT
dup get-cluster
swap dup 1c + 4c@ bljoin swap 0b + c@ 10 and 0<> true
ELSE drop false THEN ;
: find-file ( dir-cluster name len -- cluster file-len is-dir? true | false )
make-dos-name read-dir BEGIN (find-file) 0= WHILE next-cluster @ WHILE
next-cluster @ read-cluster REPEAT false ELSE true THEN ;
: find-path ( dir-cluster name len -- cluster file-len true | false )
dup 0= IF 3drop false ."  empty name " EXIT THEN
over c@ [char] \ = IF 1 /string  RECURSE EXIT THEN
[char] \ split 2>r find-file 0= IF 2r> 2drop false ."  not found " EXIT THEN
r@ 0<> <> IF 2drop 2r> 2drop false ."  no dir<->file match " EXIT THEN
r@ 0<> IF drop 2r> RECURSE EXIT THEN
2r> 2drop true ;
: do-super ( -- )
0 200 read-data
data @ 0b + 2c@ bwjoin bytes/sector !
data @ 0d + c@ sectors/cluster !
bytes/sector @ sectors/cluster @ * bytes/cluster !
data @ 0e + 2c@ bwjoin #reserved-sectors !
data @ 10 + c@ #fats !
data @ 11 + 2c@ bwjoin #root-entries !
data @ 13 + 2c@ bwjoin total-#sectors !
data @ 15 + c@ media-descriptor !
data @ 16 + 2c@ bwjoin sectors/fat !
data @ 18 + 2c@ bwjoin sectors/track !
data @ 1a + 2c@ bwjoin #heads !
data @ 1c + 2c@ bwjoin #hidden-sectors !
total-#sectors @ 0= IF data @ 20 + 4c@ bljoin total-#sectors ! THEN
sectors/fat @ 0= IF data @ 24 + 4c@ bljoin sectors/fat ! THEN
#root-entries @ 0= IF data @ 2c + 4c@ bljoin ELSE 0 THEN fat32-root-cluster !
total-#sectors @ #reserved-sectors @ - sectors/fat @ #fats @ * -
#root-entries @ 20 * bytes/sector @ // - sectors/cluster @ /
dup #clusters !
dup ff5 < IF drop c ELSE fff5 < IF 10 ELSE 20 THEN THEN fat-type !
base @ decimal base !
#reserved-sectors @ bytes/sector @ * fat-offset !
#fats @ sectors/fat @ * bytes/sector @ * fat-offset @ + root-offset !
#root-entries @ 20 * bytes/sector @ tuck // * root-offset @ +
bytes/cluster @ 2* - cluster-offset ! ;
INSTANCE VARIABLE file-cluster
INSTANCE VARIABLE file-len
INSTANCE VARIABLE current-pos
INSTANCE VARIABLE pos-in-data
: seek ( lo hi -- status )
lxjoin dup current-pos ! file-cluster @ read-cluster
BEGIN dup #data @ >= WHILE #data @ - next-cluster @ dup 0= IF
2drop true EXIT THEN read-cluster REPEAT pos-in-data ! false ;
: read ( adr len -- actual )
file-len @ current-pos @ - min \ can't go past end of file
#data @ pos-in-data @ - min >r \ length for this transfer
data @ pos-in-data @ + swap r@ move \ move the data
r@ pos-in-data +!  r@ current-pos +!  pos-in-data @ #data @ = IF
next-cluster @ ?dup IF read-cluster 0 pos-in-data ! THEN THEN r> ;
: read ( adr len -- actual )
file-len @ min                \ len cannot be greater than file size
dup >r BEGIN dup WHILE 2dup read dup 0= ABORT" fat-files: read failed"
/string ( tuck - >r + r> ) REPEAT 2drop r> ;
: load ( adr -- len )
file-len @ read dup file-len @ <> ABORT" fat-files: failed loading file" ;
: close  free-data ;
: open
do-super
0 my-args find-path 0= IF close false EXIT THEN
file-len !  file-cluster !  0 0 seek 0= ;
finish-device
new-device
s" rom-files" device-name
INSTANCE VARIABLE length
INSTANCE VARIABLE next-file
INSTANCE VARIABLE buffer
INSTANCE VARIABLE buffer-size
INSTANCE VARIABLE file
INSTANCE VARIABLE file-size
INSTANCE VARIABLE found
: open  true 
100 dup buffer-size ! alloc-mem buffer ! false found ! ;
: close buffer @ buffer-size @ free-mem ;
: read ( addr len -- actual ) s" read" $call-parent ;
: seek ( lo hi -- status ) s" seek" $call-parent ;
: .read-file-name ( offset -- str len )
0 seek drop 
buffer @ buffer-size @ read drop
buffer-size @ 1 - buffer @ + 0 swap c!
buffer @ zcount ;
: .print-info ( offset -- )
dup 2 spaces 6 0.r 2 spaces dup
8 + 0 seek drop length 8 read drop
6 length @ swap 0.r 2 spaces
20 + .read-file-name type cr ;
: .list-header cr
s" --offset---size-----file-name----" type cr ;
: list
.list-header
0 0 BEGIN + dup 
.print-info dup 0 seek drop
next-file 8 read drop next-file @
dup 0= UNTIL 2drop ;
: (find-file)  ( name len -- offset | -1 )
0 0 seek drop false found !
file-size ! file ! 0 0 BEGIN + dup
20 + .read-file-name file @ file-size @
str= IF true found ! THEN
dup 0 seek drop
next-file 8 read drop next-file @
dup 0= found @ or UNTIL drop found @ 0=
IF drop -1 THEN ;
: load  ( addr -- size )
my-parent instance>args 2@ [char] \ left-parse-string 2drop
(find-file) dup -1 = IF 2drop 0 ELSE
0 0 seek drop
dup 8 + 0 seek drop
here 8 read drop here @  ( dest-addr offset file-size )
over 18 + 0 seek drop
here 8 read drop here @  ( dest-addr offset file-size data-offset )
rot + 0 seek drop  ( dest-addr file-size )
read 
THEN
;
finish-device
new-device
s" ext2-files" device-name
INSTANCE VARIABLE first-block
INSTANCE VARIABLE inode-size
INSTANCE VARIABLE block-size
INSTANCE VARIABLE inodes/group
INSTANCE VARIABLE blocks-per-group
INSTANCE VARIABLE group-descriptors
INSTANCE VARIABLE desc-size
: seek  s" seek" $call-parent ;
: read  s" read" $call-parent ;
INSTANCE VARIABLE data
INSTANCE VARIABLE #data
INSTANCE VARIABLE indirect-block
INSTANCE VARIABLE dindirect-block
: free-data
data @ ?dup IF #data @ free-mem  0 data ! THEN ;
: read-data ( offset size -- )
free-data  dup #data ! alloc-mem data !
xlsplit seek            -2 and ABORT" ext2-files read-data: seek failed"
data @ #data @ read #data @ <> ABORT" ext2-files read-data: read failed" ;
: read-block ( block# -- )
block-size @ * block-size @ read-data ;
INSTANCE VARIABLE inode
INSTANCE VARIABLE file-len
INSTANCE VARIABLE blocks  \ data from disk blocks
INSTANCE VARIABLE #blocks
INSTANCE VARIABLE ^blocks \ current pointer in blocks
INSTANCE VARIABLE #blocks-left
: blocks-read ( n -- )  dup negate #blocks-left +! 4 * ^blocks +! ;
: read-indirect-blocks ( indirect-block# -- )
read-block data @ data off
dup #blocks-left @ 4 * block-size @ min dup >r ^blocks @ swap move
r> 2 rshift blocks-read block-size @ free-mem ;
: read-double-indirect-blocks ( double-indirect-block# -- )
read-block data @ indirect-block ! data off
BEGIN
indirect-block @ l@-le dup 0 <>
WHILE
read-indirect-blocks
4 indirect-block +!       \ point to next indirect block
REPEAT
drop                         \ drop 0, the invalid block number
;
: read-triple-indirect-blocks ( triple-indirect-block# -- )
read-block data @ dindirect-block ! data off
BEGIN
dindirect-block @ l@-le dup 0 <>
WHILE
read-double-indirect-blocks
4 dindirect-block +!      \ point to next double indirect block
REPEAT
drop                         \ drop 0, the invalid block number
;
: inode-i-block ( inode -- block ) 28 + ;
80000 CONSTANT EXT4_EXTENTS_FL
: inode-i-flags ( inode -- i_flags ) 20 + l@-le ;
F30A CONSTANT EXT4_EH_MAGIC
: extent-tree-entries ( iblock -- entries ) C + ;
STRUCT
2 field ext4-eh>magic
2 field ext4-eh>entries
2 field ext4-eh>max
2 field ext4-eh>depth
4 field ext4-eh>generation
CONSTANT /ext4-eh
STRUCT
4 field ext4-ee>block
2 field ext4-ee>len
2 field ext4-ee>start_hi
4 field ext4-ee>start_lo
CONSTANT /ext4-ee
: ext4-ee-start ( entries -- ee-start )
dup ext4-ee>start_hi w@-le 32 lshift
swap
ext4-ee>start_lo l@-le or
;
: expand-blocks ( start len -- )
bounds
?DO
i ^blocks @ l!-le
1 blocks-read
1 +LOOP
;
: read-extent-tree ( inode -- )
inode-i-block
dup ext4-eh>magic w@-le EXT4_EH_MAGIC <> IF ." BAD extent tree magic" cr EXIT THEN
dup ext4-eh>depth w@-le 0 <> IF ." Root inode is not lead, not supported" cr EXIT THEN
dup ext4-eh>entries w@-le
>r
/ext4-eh +
r>
0
DO
dup ext4-ee-start
over ext4-ee>len w@-le ( ext4_extent^ start len )
expand-blocks
/ext4-ee +
LOOP
drop
;
: read-block#s ( -- )
blocks @ ?dup IF #blocks @ 4 * free-mem THEN \ free blocks if allocated
inode @ 4 + l@-le file-len !                 \ *file-len = i_size_lo
file-len @ block-size @ // #blocks !         \ *#blocks = roundup(file-len/block-size)
#blocks @ 4 * alloc-mem blocks !             \ *blocks = allocmem(*#blocks)
blocks @ ^blocks !  #blocks @ #blocks-left !
inode @ inode-i-flags EXT4_EXTENTS_FL and IF inode @ read-extent-tree EXIT THEN
#blocks-left @ c min \ # direct blocks
inode @ inode-i-block over 4 * ^blocks @ swap move blocks-read
#blocks-left @ IF inode @ 58 + l@-le read-indirect-blocks THEN
#blocks-left @ IF inode @ 5c + l@-le read-double-indirect-blocks THEN
#blocks-left @ IF inode @ 60 + l@-le read-triple-indirect-blocks THEN
;
: read-inode-table ( groupdesc -- table )
dup 8 + l@-le             \ reads bg_inode_table_lo
desc-size @ 20 > IF
over 28 + l@-le         \ reads bg_inode_table_hi
20 lshift or
THEN
nip
;
: read-inode ( inode# -- )
1- inodes/group @ u/mod
desc-size @ * group-descriptors @ +
read-inode-table
block-size @ *          \ # in group, inode table
swap inode-size @ * + xlsplit seek drop  inode @ inode-size @ read drop
;
: .rwx ( bits last-char-if-special special? -- )
rot dup 4 and IF ." r" ELSE ." -" THEN
dup 2 and IF ." w" ELSE ." -" THEN
swap IF 1 and 0= IF upc THEN emit ELSE
1 and IF ." x" ELSE ." -" THEN drop THEN ;
CREATE mode-chars 10 allot s" ?pc?d?b?-?l?s???" mode-chars swap move
: .mode ( mode -- )
dup c rshift f and mode-chars + c@ emit
dup 6 rshift 7 and over 800 and 73 swap .rwx
dup 3 rshift 7 and over 400 and 73 swap .rwx
dup          7 and swap 200 and 74 swap .rwx ;
: .inode ( -- )
base @ >r decimal
inode @      w@-le .mode \ file mode
inode @ 1a + w@-le 5 .r \ link count
inode @ 02 + w@-le 9 .r \ uid
inode @ 18 + w@-le 9 .r \ gid
inode @ 04 + l@-le 9 .r \ size
r> base ! ;
80 CONSTANT EXT4_INCOMPAT_64BIT
: super-feature-incompat ( data -- flags ) 60 + l@-le ;
: super-desc-size ( data -- size ) FE + w@-le ;
: super-feature-incompat-64bit ( data -- true|false )
super-feature-incompat EXT4_INCOMPAT_64BIT and 0<>
;
: do-super ( -- )
400 400 read-data
data @ 14 + l@-le first-block !
400 data @ 18 + l@-le lshift block-size !
data @ 28 + l@-le inodes/group !
data @ 4c + l@-le 0= IF
80 inode-size !
ELSE
data @ 58 + w@-le inode-size !
THEN
data @ 20 + l@-le blocks-per-group !
data @ super-feature-incompat-64bit IF
data @ super-desc-size desc-size !
ELSE
20 desc-size !
THEN
first-block @ 1+ block-size @ *
blocks-per-group @
read-data
data @ group-descriptors !
data off
;
INSTANCE VARIABLE current-pos
: read ( adr len -- actual )
file-len @ current-pos @ - min \ can't go past end of file
current-pos @ block-size @ u/mod 4 * blocks @ + l@-le read-block
block-size @ over - rot min >r ( adr off r: len )
data @ + swap r@ move r> dup current-pos +! ;
: read ( adr len -- actual )
dup >r BEGIN dup WHILE 2dup read dup 0= ABORT" ext2-files: read failed"
/string REPEAT 2drop r> ;
: seek ( lo hi -- status )
lxjoin dup file-len @ > IF drop true EXIT THEN current-pos ! false ;
: load ( adr -- len )
file-len @ read dup file-len @ <> ABORT" ext2-files: failed loading file" ;
: .name ( adr -- )  dup 8 + swap 6 + c@ type ;
: read-dir ( inode# -- adr )
read-inode read-block#s file-len @ alloc-mem
0 0 seek ABORT" ext2-files read-dir: seek failed"
dup file-len @ read file-len @ <> ABORT" ext2-files read-dir: read failed"
;
: .dir ( inode# -- )
read-dir dup BEGIN 2dup file-len @ - > over l@-le tuck and WHILE
cr dup 8 0.r space read-inode .inode space space dup .name
dup 4 + w@-le + REPEAT 2drop file-len @ free-mem
;
: (find-file) ( adr name len -- inode#|0 )
2>r dup BEGIN 2dup file-len @ - > over l@-le and WHILE
dup 8 + over 6 + c@ 2r@ str= IF 2r> 2drop nip l@-le EXIT THEN
dup 4 + w@-le + REPEAT 2drop 2r> 2drop 0
;
: find-file ( inode# name len -- inode#|0 )
2>r read-dir dup 2r> (find-file) swap file-len @ free-mem
;
: find-path ( inode# name len -- inode#|0 )
dup 0= IF 3drop 0 ."  empty name " EXIT THEN
over c@ [char] \ = IF 1 /string ."  slash " RECURSE EXIT THEN
[char] \ split 2>r find-file ?dup 0= IF
2r> 2drop false ."  not found " EXIT THEN
r@ 0<> IF 2r> ."  more... " RECURSE EXIT THEN
2r> 2drop ."  got it " ;
: close
inode @ inode-size @ free-mem
group-descriptors @ blocks-per-group @ free-mem
free-data
blocks @ ?dup IF #blocks @ 4 * free-mem THEN
;
: open
0 data ! 0 blocks ! 0 #blocks !
do-super
inode-size @ alloc-mem inode !
my-args nip 0= IF 0 0 ELSE
2 my-args find-path ?dup 0= IF close false EXIT THEN THEN
read-inode read-block#s 0 0 seek 0= ;
finish-device
new-device
s" obp-tftp" device-name
: open ( -- okay? ) 
true
;
: load ( addr -- size )
s" bootargs" get-chosen 0= IF 0 0 THEN >r >r
s" bootpath" get-chosen 0= IF 0 0 THEN >r >r
my-parent ihandle>phandle node>path encode-string
s" bootpath" set-chosen
dup paflof-start < IF
paflof-start
ELSE
MIN-RAM-SIZE
THEN                                  ( addr endaddr )
over -                                ( addr maxlen )
my-args
net-load dup 0< IF drop 0 THEN
r> r> over IF s" bootpath" set-chosen ELSE 2drop THEN
r> r> over IF s" bootargs" set-chosen ELSE 2drop THEN
;
: close ( -- )
;
: ping  ( -- )
my-args net-ping
;
finish-device
new-device
s" iso-9660" device-name
0 VALUE iso-debug-flag
: iso-debug-print ( str len -- )  iso-debug-flag IF type cr ELSE 2drop THEN  ;
0 VALUE  path-tbl-size
0 VALUE  path-tbl-addr
0 VALUE  root-dir-size
0 VALUE  vol-size
0 VALUE  logical-blk-size
0 VALUE  path-table
0 VALUE  count
INSTANCE VARIABLE dir-addr
INSTANCE VARIABLE data-buff
INSTANCE VARIABLE #data
INSTANCE VARIABLE ptable
INSTANCE VARIABLE file-loc
INSTANCE VARIABLE file-size
INSTANCE VARIABLE cur-file-offset
INSTANCE VARIABLE self
INSTANCE VARIABLE index
: seek  ( pos.lo pos.hi -- status )  s" seek" $call-parent  ;
: read  ( addr len -- actual )  s" read" $call-parent  ;
: free-data ( -- )
data-buff @                              ( data-buff )
?DUP  IF  #data @  free-mem  0 data-buff ! 0 #data ! THEN
;
: read-data ( offset size -- )
dup #data @ > IF
free-data dup dup                  ( offset size size size )
#data ! alloc-mem data-buff !      ( offset size )
THEN
swap xlsplit                          ( size pos.lo pos.hi )
seek   -2 and ABORT" seek failed."
data-buff @ over read                 ( size actual )
<> ABORT" read failed."
;
: extract-vol-info  (  --  )
10  800 * 800 read-data
data-buff @  88  + l@-be  to path-tbl-size   \ read path table size
data-buff @  94  + l@-be  to path-tbl-addr   \ read big-endian  path table
data-buff @  a2  + l@-be   dir-addr !        \ gather of root directory info
data-buff @  0aa + l@-be  to root-dir-size   \ get volume info
data-buff @  54  + l@-be  to vol-size        \ size in blocks
data-buff @  82  + l@-be  to logical-blk-size
path-tbl-size alloc-mem dup  TO path-table path-tbl-size erase
path-tbl-addr 800 *  xlsplit seek  drop
path-table  path-tbl-size  read  drop     \ pathtable in-system-memory copy
;
: file-name  ( str len --  str' len' )
2dup  [char] ; findchar  IF
nip                 \ Omit the trailing ";1" revision of ISO9660 file name
2dup + 1-           ( str newlen endptr )
c@ [CHAR] . = IF
1-               ( str len' )    \ Remove trailing dot
THEN
THEN
;
: dup3  ( num  -- num num num ) dup dup dup  ;
: get-next-record  ( rec-addr -- next-rec-offset )
dup3               ( rec-addr rec-addr rec-addr rec-addr )
self @ 1 +  self ! ( rec-addr rec-addr rec-addr rec-addr )
c@  1 AND  IF      ( rec-addr rec-addr rec-addr )
c@ +  9         ( rec-addr rec-addr' rec-len )
ELSE
c@ +  8         ( rec-addr rec-addr' rec-len )
THEN
+ swap  -          ( next-rec-offset )
;
: path-table-search ( str len -- TRUE | FALSE )
path-table path-tbl-size +  path-table ptable @ +  DO ( str len )
2dup  I 6 + w@-be index @ =                        ( str len str len )
-rot  I 8 +  I c@
iso-debug-flag IF
." ISO: comparing path name '"
4dup type ." ' with '" type ." '" cr
THEN
string=ci and  IF                                  ( str len )
s" Directory Matched!!  "   iso-debug-print     ( str len )
self @   index !                                ( str len )
I 2 + l@-be   dir-addr ! I  dup                 ( str len rec-addr )
get-next-record + path-table -   ptable !       ( str len )
2drop  TRUE UNLOOP EXIT                         ( TRUE )
THEN
I get-next-record                           ( str len next-rec-offset )
+LOOP
2drop
FALSE                                          ( FALSE )
s" Invalid path / directory "  iso-debug-print
;
: search-file-dir ( str len  -- TRUE | FALSE )
dir-addr @  800 *  dir-addr !             ( str len )
dir-addr @ 100 read-data                  ( str len )
data-buff @  0e + l@-be  dup >r           ( str len rec-len )
100 >  IF                                 ( str len )
s" size dir record"  iso-debug-print   ( str len )
dir-addr @ r@  read-data               ( str len )
THEN
r> data-buff @  + data-buff @  DO         ( str len )
I 19 + c@  2 and 0=  I c@ 0<> and IF   ( str len )
2dup                                ( str len  str len )
I 21 + I 20 + c@                    ( str len  str len  str' len' )
iso-debug-flag IF
." ISO: comparing file name '"
4dup type ." ' with '" type ." '" cr
THEN
file-name  string=ci  IF            ( str len )
s" File found!"  iso-debug-print ( str len )
I 6 + l@-be 800 *                ( str len file-loc )
file-loc !                       ( str len )
I 0e + l@-be  file-size !        ( str len )
2drop
TRUE                             ( TRUE )
UNLOOP
EXIT
THEN
THEN
I c@ ?dup 0= IF
800 I 7ff AND -
iso-debug-flag IF
." skipping " dup . ." bytes at end of sector" cr
THEN
THEN
+LOOP
2drop
FALSE                                     ( FALSE )
s" file not found"   iso-debug-print
;
: search-path ( str len -- FALSE|TRUE )
0  ptable !
1  self !
1  index !
dup                                             ( str len len )
0=  IF
3drop FALSE                                  ( FALSE )
s"  Empty path name "  iso-debug-print  EXIT ( FALSE )
THEN
OVER c@                                         ( str len char )
[char] \ =  IF                                  ( str len )
swap 1 + swap 1 -  BEGIN                     ( str len )
[char] \  split                           ( str len  str' len ' )
dup 0 =   IF                              ( str len  str' len ' )
2drop search-file-dir EXIT             ( TRUE | FALSE )
ELSE
2swap path-table-search  invert  IF    ( str' len ' )
2drop FALSE  EXIT                   ( FALSE )
THEN
THEN
AGAIN
ELSE   BEGIN
[char] \  split   dup 0 =   IF               ( str len str' len' )
2drop search-file-dir EXIT                ( TRUE | FALSE )
ELSE
2swap path-table-search  invert  IF       ( str' len ' )
2drop FALSE  EXIT                      ( FALSE )
THEN
THEN
AGAIN
THEN
;
0 VALUE loc
: load ( addr -- len )
dup to loc                     ( addr )
file-loc @  xlsplit seek drop
file-size @  read              ( file-size )
iso-debug-flag IF s" Bytes returned from read:" type dup . cr THEN
dup file-size @  <> ABORT" read failed!"
;
: close ( -- )
free-data   count 1 - dup to count  0 =  IF
path-table path-tbl-size free-mem
0 TO path-table
THEN
;
: open ( -- TRUE | FALSE )
0 data-buff !
0 #data !
0 ptable !
0 file-loc !
0 file-size !
0 cur-file-offset !
1 self !
1 index !
count 0 =  IF
s" extract-vol-info called "   iso-debug-print
extract-vol-info
THEN
count  1 + to count
my-args search-path  IF
file-loc @  xlsplit seek drop
TRUE    ( TRUE )
ELSE
close
FALSE   ( FALSE )
THEN
0 cur-file-offset !
s" opened ISO9660 package" iso-debug-print
;
: seek ( pos.lo pos.hi -- status )
lxjoin dup  cur-file-offset !  ( offset )
file-loc @  + xlsplit          ( pos.lo pos.hi )
s" seek" $call-parent          ( status )
;
: read ( addr len -- actual )
file-size @ cur-file-offset @ -             ( addr len remainder-of-file )
min                                         ( addr len|remainder-of-file )
s" read" $call-parent                       ( actual )
dup cur-file-offset @ +  cur-file-offset !  ( actual )
cur-file-offset @                           ( offset actual )
xlsplit seek drop                           ( actual )
;
finish-device
finish-device
: open true ;
: close ;
finish-device
370 cp
: check-boot-menu
s" qemu,boot-menu" get-chosen IF
decode-int 1 = IF
." Press F12 for boot menu." cr cr
THEN
2drop
THEN
;
check-boot-menu
380 cp
0 VALUE fdtfl-debug
VARIABLE fdtfl-struct
VARIABLE fdtfl-struct-here
VARIABLE fdtfl-strings
VARIABLE fdtfl-strings-cache
VARIABLE fdtfl-strings-here
VARIABLE fdtfl-strings-reused \ debug only
VARIABLE fdlfl-ms \ debug only
: fdt-skip-string ( cur -- cur ) zcount + char+  4 #aligned ;
: zstring=  ( str len zstr -- flag )
2dup + c@ 0<> IF
3drop false
EXIT
THEN
swap comp 0=
;
: fdt-find-string ( name namelen -- nameoff true | false )
fdtfl-strings @
BEGIN
dup fdtfl-strings-cache @ <
WHILE
3dup zstring= IF
nip nip             ( curstr )
fdtfl-strings @ -
true
EXIT
THEN
fdt-skip-string
REPEAT
3drop
false
;
: fdt-str-allot ( len -- ) fdtfl-strings-here @ + to fdtfl-strings-here ;
: fdt-str-c, ( char -- ) fdtfl-strings-here @ 1 fdt-str-allot c! ;
: fdt-str-align  ( -- )
fdtfl-strings-here @
dup dup 4 #aligned swap -   ( here bytes-to-erase )
dup -rot
erase
fdt-str-allot
;
: fdt-str-bytes, ( data len -- ) fdtfl-strings-here @ over fdt-str-allot swap move ;
: fdt-str-ztr, ( str len -- ) fdt-str-bytes, 0 fdt-str-c, ;
: fdt-add-string ( name namelen -- nameoff )
fdtfl-strings-here @ -rot
fdt-str-ztr,
fdt-str-align
fdtfl-strings @ -
;
: fdt-get-string ( name namelen -- nameoff )
2dup fdt-find-string IF
-rot 2drop
fdtfl-debug IF
1 fdtfl-strings-reused +!
THEN
EXIT
THEN
fdt-add-string
;
: fdt-allot ( len -- ) fdtfl-struct-here @ + to fdtfl-struct-here ;
: fdt-c, ( char -- ) fdtfl-struct-here @ 1 fdt-allot c! ;
: fdt-align  ( -- )
fdtfl-struct-here @
dup dup 4 #aligned swap -   ( here bytes-to-erase )
dup -rot
erase
fdt-allot
;
: fdt-bytes, ( data len -- ) fdtfl-struct-here @ over fdt-allot swap move ;
: fdt-ztr, ( str len -- ) fdt-bytes, 0 fdt-c, ;
: fdt-l, ( token -- ) fdtfl-struct-here @ l! /l fdt-allot ;
: fdt-begin-node ( phandle -- )
OF_DT_BEGIN_NODE fdt-l,
dup device-tree @ = IF drop s" " ELSE node>qname THEN
fdt-ztr,
fdt-align
;
: fdt-end-node ( -- ) OF_DT_END_NODE fdt-l, ;
: fdt-prop ( prop len name namelen -- )
OF_DT_PROP fdt-l,
fdt-get-string      ( prop len nameoff )
over fdt-l,
fdt-l,              ( prop len )
fdt-bytes,
fdt-align
;
: fdt-end ( -- ) OF_DT_END fdt-l, ;
: fdt-copy-property ( link -- )
dup link> execute
rot
link>name name>string
2dup s" name" str= IF 4drop EXIT THEN \ skipping useless "name"
fdt-prop
;
: for-all-words ( wid xt -- ) \ xt has sig ( lfa -- )
>r
cell+ @ BEGIN dup WHILE dup r@ execute @ REPEAT
r> 2drop
;
: fdt-copy-properties ( phandle -- )
dup encode-int s" phandle" fdt-prop
node>properties @
['] fdt-copy-property for-all-words
;
: fdt-copy-node ( node --  )
fdtfl-debug 1 > IF dup node>path type cr THEN
dup fdt-begin-node
dup fdt-copy-properties
child BEGIN dup WHILE dup recurse peer REPEAT
drop
fdt-end-node
;
: fdtfl-strings-preload ( -- )
s" reg" fdt-add-string drop
s" status" fdt-add-string drop
s" 64-bit" fdt-add-string drop
s" phandle" fdt-add-string drop
s" ibm,vmx" fdt-add-string drop
s" ibm,dfp" fdt-add-string drop
s" slb-size" fdt-add-string drop
s" ibm,purr" fdt-add-string drop
s" vendor-id" fdt-add-string drop
s" device-id" fdt-add-string drop
s" min-grant" fdt-add-string drop
s" class-code" fdt-add-string drop
s" compatible" fdt-add-string drop
s" interrupts" fdt-add-string drop
s" cpu-version" fdt-add-string drop
s" #size-cells" fdt-add-string drop
s" ibm,req#msi" fdt-add-string drop
s" revision-id" fdt-add-string drop
s" device_type" fdt-add-string drop
s" max-latency" fdt-add-string drop
s" ibm,chip-id" fdt-add-string drop
s" ibm,pft-size" fdt-add-string drop
s" ibm,slb-size" fdt-add-string drop
s" devsel-speed" fdt-add-string drop
s" ibm,loc-code" fdt-add-string drop
s" subsystem-id" fdt-add-string drop
s" d-cache-size" fdt-add-string drop
s" i-cache-size" fdt-add-string drop
s" #address-cells" fdt-add-string drop
s" clock-frequency" fdt-add-string drop
s" cache-line-size" fdt-add-string drop
s" ibm,pa-features" fdt-add-string drop
s" ibm,my-drc-index" fdt-add-string drop
s" d-cache-line-size" fdt-add-string drop
s" i-cache-line-size" fdt-add-string drop
s" assigned-addresses" fdt-add-string drop
s" d-cache-block-size" fdt-add-string drop
s" i-cache-block-size" fdt-add-string drop
s" timebase-frequency" fdt-add-string drop
s" subsystem-vendor-id" fdt-add-string drop
s" ibm,segment-page-sizes" fdt-add-string drop
s" ibm,ppc-interrupt-server#s" fdt-add-string drop
s" ibm,processor-segment-sizes" fdt-add-string drop
s" ibm,ppc-interrupt-gserver#s" fdt-add-string drop
;
: fdt-append-blob ( bytes cur blob -- cur )
3dup -rot swap move
drop +
;
: fdt-flatten-tree ( -- tree )
100000 alloc-mem dup fdtfl-struct-here ! fdtfl-struct !
100000 alloc-mem dup fdtfl-strings-here ! fdtfl-strings !
fdtfl-debug IF
0 fdtfl-strings-reused !
milliseconds fdlfl-ms !
THEN
fdtfl-strings-preload
fdtfl-strings-here @ fdtfl-strings-cache !
device-tree @ fdt-copy-node
fdt-end
fdtfl-struct-here @ fdtfl-struct @ -
fdtfl-strings-here @ fdtfl-strings @ - ( struct-len strings-len )
2dup + /fdth +
10 + \ Reserve 16 bytes for an empty reserved block
fdtfl-debug IF
3dup
." FDTsize=" .d ." Strings=" .d ." Struct=" .d
." Reused str=" fdtfl-strings-reused @ .d
milliseconds fdlfl-ms @ - .d ." ms"
cr
THEN
dup alloc-mem                   ( struct-len strings-len total-len fdt )
>r                              ( struct-len strings-len total-len r: fdt )
OF_DT_HEADER        r@ >fdth_magic l!
dup                 r@ >fdth_tsize l!
/fdth 10 + 2 pick + r@ >fdth_struct_off l!
/fdth 10 +          r@ >fdth_string_off l!
/fdth               r@ >fdth_rsvmap_off l!
11                  r@ >fdth_version l!
10                  r@ >fdth_compat_vers l!
chosen-cpu-unit     r@ >fdth_boot_cpu l!
over                r@ >fdth_string_size l!
2 pick              r@ >fdth_struct_size l!
drop                            ( struct-len strings-len r: fdt )
r@ /fdth +                      ( struct-len strings-len cur r: fdt )
0 over ! cell+ 0 over ! cell+
fdtfl-strings @ fdt-append-blob
fdtfl-struct @ fdt-append-blob
drop
fdtfl-struct @ 100000 free-mem
fdtfl-strings @ 100000 free-mem
r>
;
: fdt-flatten-tree-free ( tree )
dup >fdth_tsize l@ free-mem
;
371 cp
STRUCT
/l field rtas>token
/l field rtas>nargs
/l field rtas>nret
/l field rtas>args0
/l field rtas>args1
/l field rtas>args2
/l field rtas>args3
/l field rtas>args4
/l field rtas>args5
/l field rtas>args6
/l field rtas>args7
/l C * field rtas>args
/l field rtas>bla
CONSTANT /rtas-control-block
CREATE rtas-cb /rtas-control-block allot
rtas-cb /rtas-control-block erase
0 VALUE rtas-base
0 VALUE rtas-size
0 VALUE rtas-node
s" /rtas" find-node to rtas-node
373 cp
: enter-rtas ( -- )
rtas-cb rtas-base 0 rtas-base call-c drop
;
: rtas-get-token ( str len -- token | 0 )
rtas-node get-package-property IF 0 ELSE drop l@ THEN
;
: rtas-power-off   ( x y -- status )
[ s" power-off" rtas-get-token ] LITERAL rtas-cb rtas>token l!
2 rtas-cb rtas>nargs l!
1 rtas-cb rtas>nret l!
rtas-cb rtas>args0 l!
rtas-cb rtas>args1 l!
enter-rtas
rtas-cb rtas>args2 l@
;
: power-off  ( -- )  0 0 rtas-power-off ;
: rtas-system-reboot  ( -- status )
[ s" system-reboot" rtas-get-token ] LITERAL rtas-cb rtas>token l!
0 rtas-cb rtas>nargs l!
1 rtas-cb rtas>nret l!
rtas-cb rtas>args0 l!
enter-rtas
rtas-cb rtas>args1 l@
;
: rtas-start-cpu  ( pid loc r3 -- status )
[ s" start-cpu" rtas-get-token ] LITERAL rtas-cb rtas>token l!
3  rtas-cb rtas>nargs l!
1  rtas-cb rtas>nret l!
rtas-cb rtas>args2 l!
rtas-cb rtas>args1 l!
rtas-cb rtas>args0 l!
0 rtas-cb rtas>args3 l!
enter-rtas
rtas-cb rtas>args3 l@
;
: rtas-set-tce-bypass ( unit enable -- )
" ibm,set-tce-bypass" rtas-get-token rtas-cb rtas>token l!
2 rtas-cb rtas>nargs l!
0 rtas-cb rtas>nret l!
rtas-cb rtas>args1 l!
rtas-cb rtas>args0 l!
enter-rtas
;
: rtas-quiesce ( -- )
fdt-flatten-tree
dup hv-update-dt ?dup IF
dup -2 <> IF ." HV-UPDATE-DT error: " . cr ELSE drop THEN
THEN
fdt-flatten-tree-free
" quiesce" rtas-get-token rtas-cb rtas>token l!
0 rtas-cb rtas>nargs l!
0 rtas-cb rtas>nret l!
enter-rtas
;
0 value puid
: rtas-do-config-@ ( config-addr size -- value)
[ s" ibm,read-pci-config" rtas-get-token ] LITERAL rtas-cb rtas>token l!
4 rtas-cb rtas>nargs l!
2 rtas-cb rtas>nret l!
( addr size ) rtas-cb rtas>args3 l!
puid rtas-cb rtas>args2 l!
puid 20 rshift rtas-cb rtas>args1 l!
( addr ) rtas-cb rtas>args0 l!
enter-rtas
rtas-cb rtas>args4 l@ dup IF
drop ffffffff
ELSE
drop rtas-cb rtas>args5 l@
THEN
;
: rtas-do-config-! ( value config-addr size )
[ s" ibm,write-pci-config" rtas-get-token ] LITERAL rtas-cb rtas>token l!
5 rtas-cb rtas>nargs l!
1 rtas-cb rtas>nret l!
( value addr size ) rtas-cb rtas>args3 l!
puid rtas-cb rtas>args2 l!
puid 20 rshift rtas-cb rtas>args1 l!
( value addr ) rtas-cb rtas>args0 l!
( value ) rtas-cb rtas>args4 l!
enter-rtas
rtas-cb rtas>args5 l@ dup IF
." RTAS write config err " . cr
ELSE drop THEN
;
: rtas-config-b@ ( config-addr -- value )
1 rtas-do-config-@ ff and
;
: rtas-config-b! ( value config-addr -- )
1 rtas-do-config-!
;
: rtas-config-w@ ( config-addr -- value )
2 rtas-do-config-@ ffff and
;
: rtas-config-w! ( value config-addr -- )
2 rtas-do-config-!
;
: rtas-config-l@ ( config-addr -- value )
4 rtas-do-config-@ ffffffff and
;
: rtas-config-l! ( value config-addr -- )
4 rtas-do-config-!
;
: of-start-cpu rtas-start-cpu ;
' power-off to halt
' rtas-system-reboot to reboot
rtas-node set-node
: open true ;
: close ;
: store-rtas-loc ( adr )
s" /rtas" find-node >r
encode-int s" slof,rtas-base" r@ set-property
rtas-size encode-int s" slof,rtas-size" r> set-property
;
: instantiate-rtas ( adr -- entry )
dup store-rtas-loc
dup rtas-base swap rtas-size move
;
hv-rtas-get
s" rtas-size" rtas-node get-property
IF
dup encode-int s" rtas-size" rtas-node set-property
ELSE
decode-int nip nip
over 2dup < IF ." No enough space for RTAS: " . . cr abort THEN
2drop
THEN
to rtas-size
to rtas-base
device-end
374 cp
3f0 cp
: strequal ( str1 len1 str2 len2 -- flag )
rot dup rot = IF comp 0= ELSE 2drop drop 0 THEN ; 
400 cp
" /" find-device
200000 CONSTANT cas-buffer-size
: ibm,client-architecture-support         ( vec -- err? )
cas-buffer-size alloc-mem             ( vec memaddr )
dup 0= IF
." out of memory during ibm,client-architecture-support" cr
2drop TRUE
EXIT
THEN
swap over cas-buffer-size             ( memaddr vec memaddr size )
hv-cas 0= IF                          ( memaddr )
dup l@ 1 >= IF                    \ Version number >= 1
" /" find-node set-node
dup 4 + fdt-init
fdt-check-header
fdt-struct fdt-fix-cas-node
fdt-fix-cas-success NOT       ( memaddr err? )
ELSE
FALSE
THEN
ELSE
TRUE
THEN
>r cas-buffer-size free-mem r>
;
480 cp
new-device
s" mmu" 2dup device-name device-type
0 0 s" translations" property
: open  true ;
: close ;
finish-device
device-end
4c0 cp
: fixup-tbfreq
" /cpus" find-device
get-node child dup 0= ABORT" CPU not found"
set-node
" timebase-frequency" get-node get-package-property IF
2drop
ELSE
decode-int to tb-frequency 2drop
THEN
device-end
;
fixup-tbfreq
4d0 cp
include fbuffer.fs
500 cp
: populate-vios ( -- )
." Populating /vdevice methods" cr
" /vdevice" find-device get-node child
BEGIN
dup 0 <>
WHILE
dup set-node
dup " compatible" rot get-package-property 0 = IF
drop dup from-cstring
2dup " hvterm1" strequal IF
" vio-hvterm.fs" included
THEN
2dup " IBM,v-scsi" strequal IF
" vio-vscsi.fs" included
THEN
2dup " IBM,l-lan" strequal IF
" vio-veth.fs" included
THEN
2dup " qemu,spapr-nvram" strequal IF
" rtas-nvram.fs" included
THEN
2dup " IBM,vtpm20" strequal IF
" vio-vtpm-cdriver.fs" included
THEN
2drop
THEN
peer
REPEAT drop
device-end
;
populate-vios
5a0 cp
VARIABLE pci-next-mem           \ prefetchable memory mapped
VARIABLE pci-max-mem
VARIABLE pci-next-mmio          \ non-prefetchable memory
VARIABLE pci-max-mmio
VARIABLE pci-next-io            \ I/O space
VARIABLE pci-max-io
VARIABLE pci-next-mem64           \ prefetchable 64-bit memory mapped
VARIABLE pci-max-mem64
0 VALUE pci-mem-bar-min-align
0 VALUE pci-bus-number
0 VALUE pci-device-number
0 VALUE pci-device-slots
here 100 allot CONSTANT pci-device-vec
0 VALUE pci-device-vec-len
0 VALUE pci-hotplug-enabled
: int2str ( int len -- str len ) swap s>d rot <# 0 ?DO # LOOP #> ;
: pci-addr2bus ( addr -- busnr ) 10 rshift FF and ;
: pci-addr2dev ( addr -- dev ) B rshift 1F and ;
: pci-addr2fn ( addr -- dev ) 8 rshift 7 and ;
: pci-bus2addr ( busnr devnr -- addr ) B lshift swap 10 lshift + ;
: pci-addr-out ( addr -- ) dup pci-addr2bus 2 0.r space FFFF and 4 0.r ;
: pci-dump ( addr -- )
10 0 DO
dup
cr i 4 * +
dup pci-addr-out space
rtas-config-l@ 8 0.r
LOOP
drop cr
;
: pci-vendor@ ( addr -- id )                 rtas-config-l@ FFFF and ;
: pci-device@ ( addr -- id )                 rtas-config-l@ 10 rshift ;
: pci-status@ ( addr -- status )         4 + rtas-config-l@ 10 rshift ;
: pci-revision@ ( addr -- id )           8 + rtas-config-b@ ;
: pci-class@  ( addr -- class )          8 + rtas-config-l@ 8 rshift ;
: pci-cache@  ( addr -- size )           C + rtas-config-b@ ;
: pci-htype@  ( addr -- type )           E + rtas-config-b@  ;
: pci-sub-vendor@ ( addr -- sub-id )    2C + rtas-config-l@ FFFF and ;
: pci-sub-device@ ( addr -- sub-id )    2C + rtas-config-l@ 10 rshift FFFF and ;
: pci-interrupt@  ( addr -- interrupt ) 3D + rtas-config-b@ ;
: pci-min-grant@  ( addr -- min-gnt )   3E + rtas-config-b@ ;
: pci-max-lat@  ( addr -- max-lat )     3F + rtas-config-b@ ;
: pci-capabilities?  ( addr -- 0|1 ) pci-status@ 4 rshift 1 and ;
: pci-cap-next  ( cap-addr -- next-cap-off ) rtas-config-b@ FC and ;
: pci-cap-next-addr  ( cap-addr -- next-cap-addr ) 1+ dup pci-cap-next dup IF swap -100 and + ELSE nip THEN ;
: pci-cap-dump ( addr -- )
cr
dup pci-capabilities? IF
33 + BEGIN
pci-cap-next-addr dup 0<>
WHILE
dup pci-addr-out s"  : " type
dup rtas-config-b@ 2 0.r cr
REPEAT
s" end found "
ELSE
s" capabilities not enabled!"
THEN
type cr drop
;
: pci-cap-find ( addr id -- capp-addr|0 )
swap dup pci-capabilities? IF
33 + BEGIN
pci-cap-next-addr dup 0<> IF
dup rtas-config-b@ 2 pick =
ELSE
true
THEN
UNTIL
nip
ELSE
2drop 0
THEN
;
: pci-express? ( addr -- 0|1 ) 10 pci-cap-find 0<> ;
: pci-x? ( addr -- 0|1 ) 07 pci-cap-find 0<> ;
: pci-config-ext? ( addr -- 0|1 ) pci-express? ;
: pci-device-disable ( -- ) my-space 4 + dup rtas-config-l@ 7 invert and swap rtas-config-l! ;
: pci-master-enable ( -- ) my-space 4 + dup rtas-config-l@ 4 or swap rtas-config-l! ;
: pci-master-disable ( -- ) my-space 4 + dup rtas-config-l@ 4 invert and swap rtas-config-l! ;
: pci-mem-enable ( -- ) my-space 4 + dup rtas-config-w@ 2 or swap rtas-config-w! ;
: pci-io-enable ( -- ) my-space 4 + dup rtas-config-w@ 1 or swap rtas-config-w! ;
: pci-enable ( -- ) my-space 4 + dup rtas-config-w@ 7 or swap rtas-config-w! ;
: pci-error-enable ( -- ) my-space 4 + dup rtas-config-w@ 140 or swap rtas-config-w! ;
: pci-out ( addr char -- )
15 spaces
over pci-addr-out
s"  (" type emit s" ) : " type
dup pci-vendor@ 4 0.r space
pci-device@ 4 0.r
4 spaces
;
: pci-irq-line@  ( addr -- irq-pin ) 3C + rtas-config-b@ ;
: pci-irq-line!  ( pin addr -- ) 3C + rtas-config-b! ;
: pci-bus-prim! ( nr addr -- ) 18 + dup rtas-config-l@ FFFFFF00 and rot + swap rtas-config-l! ;
: pci-bus-prim@ ( addr -- nr ) 18 + rtas-config-l@ FF and ;
: pci-bus-scnd! ( nr addr -- ) 18 + dup rtas-config-l@ FFFF00FF and rot 8 lshift + swap rtas-config-l! ;
: pci-bus-scnd@ ( addr -- nr ) 18 + rtas-config-l@ 8 rshift FF and ;
: pci-bus-subo! ( nr addr -- ) 18 + dup rtas-config-l@ FF00FFFF and rot 10 lshift + swap rtas-config-l! ;
: pci-bus-subo@ ( addr -- nr ) 18 + rtas-config-l@ 10 rshift FF and ;
: pci-bus! ( subo scnd prim addr -- ) swap rot 8 lshift + rot 10 lshift + swap 18 + dup rtas-config-l@ FF000000 and rot + swap rtas-config-l! ;
: pci-bus@ ( addr -- subo scnd prim ) 18 + rtas-config-l@ dup 10 rshift FF and swap dup 8 rshift FF and swap FF and ;
: pci-reset-2nd ( addr -- ) 1C + dup rtas-config-l@ FFFF0000 or swap rtas-config-l! ;
: pci-vec ( -- )
cr s" device-vec(" type
pci-device-vec-len dup 2 0.r s" ):" type
1+ 0 DO
pci-device-vec i + c@
space 2 0.r
LOOP
cr
;
: pci-var-out ( -- )
." pci-next-io    = " pci-next-io @ 10 0.r cr
." pci-max-io     = " pci-max-io @ 10 0.r cr
." pci-next-mem   = " pci-next-mem @ 10 0.r cr
." pci-max-mem    = " pci-max-mem @ 10 0.r cr
." pci-next-mmio  = " pci-next-mmio @ 10 0.r cr
." pci-max-mmio   = " pci-max-mmio @ 10 0.r cr
." pci-next-mem64 = " pci-next-mem64 @ 10 0.r cr
." pci-max-mem64  = " pci-max-mem64 @ 10 0.r cr
;
: pci-set-slot ( addr -- )
pci-addr2dev dup                \ calc slot number
pci-device-vec-len              \ the end of the vector
pci-device-vec + c!             \ and update the vector
80000000 swap rshift            \ calc bit position of the device slot
pci-device-slots or             \ set this bit
TO pci-device-slots             \ and write it back
;
: pci-bridge-set-mmio-base ( addr -- )
pci-next-mmio @ 100000 #aligned         \ read the current Value and align to 1MB boundary
dup pci-next-mmio !                     \ and write it back
10 rshift                               \ mmio-base reg is only the upper 16 bits
pci-max-mmio @ 1- FFFF0000 and or       \ and Insert mmio Limit (set it to max)
swap 20 + rtas-config-l!                \ and write it into the bridge
;
: pci-bridge-set-mmio-limit ( addr -- )
pci-next-mmio @ 100000 +                \ add space for hot-plugging
100000 #aligned                         \ align to 1MB boundary
dup pci-next-mmio !                     \ and write it back
1- FFFF0000 and                         \ make it one less and keep upper 16 bits
over 20 + rtas-config-l@ 0000FFFF and   \ fetch original value
or swap 20 + rtas-config-l!             \ and write it into the Reg
;
: pci-bridge-set-mem-base ( addr -- )
dup 24 + rtas-config-w@ 1 and           \ does bridge support 64-bit?
pci-next-mem64 @ 0<> and IF             \ and do we have 64-bit memory?
pci-next-mem64 @ 100000000 #aligned
dup pci-next-mem64 x!
20 rshift over 28 + rtas-config-l!  \ set prefetch base upper 32 bits
pci-next-mem64 @ 10 rshift FFF0 and
pci-max-mem64 @ 1- FFF00000 and or
over 24 + rtas-config-l!            \ set prefetch limit & base lower
pci-max-mem64 @ 1- 20 rshift
swap 2C + rtas-config-l!            \ and set the limit upper 32 bits
ELSE
pci-next-mem @ 100000 #aligned
dup pci-next-mem !
10 rshift FFF0 and
pci-max-mem @ 1- FFF00000 and or
swap 24 + rtas-config-l!
THEN
;
: pci-bridge-set-mem-limit ( addr -- )
dup 24 + rtas-config-w@ 1 and           \ does bridge support 64-bit?
pci-next-mem64 @ 0<> and IF             \ and do we have 64-bit memory?
pci-next-mem64 @ 80000000 +
100000000 #aligned
dup pci-next-mem64 x!
1- 20 rshift
over 2C + rtas-config-l!            \ set the limit upper 32 bits
pci-next-mem64 @ 1- 10 rshift
swap 26 + rtas-config-w!            \ set limit lower bits
ELSE
pci-next-mem @ 100000 +
100000 #aligned
dup pci-next-mem !
1- 10 rshift
swap 26 + rtas-config-w!
THEN
;
: pci-bridge-set-io-base ( addr -- )
pci-next-io @ 1000 #aligned             \ read the current Value and align to 4KB boundary
dup pci-next-io !                       \ and write it back
over 1C + rtas-config-l@                \ check if 32bit support
1 and IF                                \ IF 32 bit support
2dup 10 rshift                  \ | keep upper 16 bits
pci-max-io @ FFFF0000 and or    \ | insert upper 16 bits of Max-Limit
swap 30 + rtas-config-l!        \ | and write it into the Base-Upper16-bits
THEN                                    \ FI
8 rshift 000000FF and                   \ keep upper 8 bits
pci-max-io @ 1- 0000FF00 and or         \ insert upper 8 bits of Max-Limit
over rtas-config-l@ FFFF0000 and        \ fetch original Value
or swap 1C + rtas-config-l!             \ and write it into the bridge
;
: pci-bridge-set-io-limit ( addr -- )
pci-next-io @ 800 +                     \ add space for hot-plugging
1000 #aligned                           \ align to 4KB boundary
dup pci-next-io !                       \ and write it back
1-                                      \ make limit one less than boundary
over 1D + rtas-config-b@                \ check if 32bit support
1 and IF                                \ IF 32 bit support
2dup FFFF0000 and               \ | keep upper 16 bits
over 30 + rtas-config-l@        \ | fetch original Value
or swap 30 + rtas-config-l!     \ | and write it into the Limit-Upper16-bits
THEN                                    \ FI
0000FF00 and                            \ keep upper 8 bits
over 1C + rtas-config-l@ FFFF00FF and   \ fetch original Value
or swap 1C + rtas-config-l!             \ and write it into the bridge
;
: pci-bridge-set-bases ( addr -- )
dup pci-bridge-set-mmio-base
dup pci-bridge-set-mem-base
pci-bridge-set-io-base
;
: pci-bridge-set-limits ( addr -- )
dup pci-bridge-set-mmio-limit
dup pci-bridge-set-mem-limit
pci-bridge-set-io-limit
;
DEFER func-pci-probe-bus
DEFER func-pci-bridge-range-props
: pci-bridge-probe ( addr -- )
dup pci-bridge-set-bases                        \ SetUp all Base Registers
dup func-pci-bridge-range-props                 \ Setup temporary "range
pci-bus-number 1+ TO pci-bus-number             \ increase number of busses found
pci-device-vec-len 1+ TO pci-device-vec-len     \ increase the device-slot vector depth
dup                                             \ stack config-addr for pci-bus!
FF swap                                         \ Subordinate Bus Number ( for now to max to open all subbusses )
pci-bus-number swap                             \ Secondary   Bus Number ( the new busnumber )
dup pci-addr2bus swap                           \ Primary     Bus Number ( the current bus )
pci-bus!                                        \ and set them into the bridge
pci-enable                                      \ enable mem/IO transactions
dup pci-bus-scnd@ func-pci-probe-bus            \ and probe the secondary bus
dup pci-bus-number swap pci-bus-subo!           \ set SubOrdinate Bus Number to current number of busses
pci-device-vec-len 1- TO pci-device-vec-len     \ decrease the device-slot vector depth
dup pci-bridge-set-limits                       \ SetUp all Limit Registers
drop                                            \ forget the config-addr
;
DEFER func-pci-bridge-probe
' pci-bridge-probe TO func-pci-bridge-probe
: pci-device-setup ( addr -- )
drop                            \ since the config-addr is coded in my-space, drop it here
s" pci-device.fs" included      \ and setup the device as node in the device tree
;
: pci-bridge-setup ( addr -- )
drop                            \ since the config-addr is coded in my-space, drop it here
s" pci-bridge.fs" included      \ and setup the bridge as node in the device tree
;
: pci-add-device ( addr -- )
new-device                      \ create a new device-tree node
dup set-space               \ set the config addr for this device tree entry
dup pci-set-slot            \ set the slot bit
dup pci-htype@              \ read HEADER-Type
7f and                      \ Mask bit 7 - multifunction device
CASE
0 OF pci-device-setup ENDOF  \ | set up the device
1 OF pci-bridge-setup ENDOF  \ | set up the bridge
dup OF dup pci-htype@ pci-out ENDOF
ENDCASE
finish-device                   \ and close the device-tree node
;
: pci-setup-device ( addr -- )
dup pci-htype@                      \ read HEADER-Type
80 and IF 8 ELSE 1 THEN             \ check for multifunction
0 DO                                \ LOOP over all possible functions (either 8 or only 1)
dup
i 8 lshift +                \ calc device-function-config-addr
dup pci-vendor@             \ check if valid function
FFFF = IF
drop                \ non-valid so forget the address
ELSE
pci-device-number 1+    \ increase the number of devices
TO pci-device-number    \ and store it
pci-add-device          \ and add the device to the device tree and set it up
THEN
LOOP                                \ next function
drop                                \ forget the device-addr
;
: pci-probe-device ( busnr devicenr -- )
pci-bus2addr                                    \ calc pci-address
dup pci-vendor@                                 \ fetch Vendor-ID
FFFF = IF                                       \ check if valid
drop                                    \ if not forget it
ELSE
pci-setup-device                        \ if valid setup the device
THEN
;
: pci-probe-bus ( busnr -- )
0 TO pci-device-slots           \ reset slot array to unpoppulated
20 0 DO
dup
i pci-probe-device
LOOP
drop
;
' pci-probe-bus TO func-pci-probe-bus
: pci-probe-all ( bus-max bus-min -- )                  \ Check all busses from bus-min up to bus-max if needed
0 TO pci-device-vec-len                         \ reset the device-slot vector
DO
i TO pci-bus-number                     \ set current Busnumber
0 TO pci-device-number                  \ reset Device Number
pci-bus-number pci-probe-bus            \ and probe this bus
pci-device-number 0 > IF LEAVE THEN     \ if we found a device we're done
LOOP                                            \ else next bus
;
: (probe-pci-host-bridge) ( bus-max bus-min -- )
0d emit ."  Adapters on " puid 10 0.r cr        \ print the puid we're looking at
( bus-max bus-min ) pci-probe-all               \ and walk the bus
pci-device-number 0= IF                         \ IF no devices found
15 spaces                               \ | indent the output
." None" cr                             \ | tell the world our result
THEN                                            \ FI
;
: probe-pci-host-bridge ( bus-max bus-min mmio-max mmio-base mem-max mem-base io-max io-base my-puid -- )
puid >r TO puid                                 \ save puid and set the new
pci-next-io !                                   \ save the next io-base address
pci-max-io !                                    \ save the max io-space address
pci-next-mem !                                  \ save the next mem-base address
pci-max-mem !                                   \ save the max mem-space address
pci-next-mmio !                                 \ save the next mmio-base address
pci-max-mmio !                                  \ save the max mmio-space address
(probe-pci-host-bridge)
r> TO  puid                                     \ restore puid
;
0 VALUE pci-net-num
0 VALUE pci-disk-num
0 VALUE pci-cdrom-num
: pci-set-alias ( str-addr str-len num -- )
$cathex strdup       \ create alias name
get-node node>path   \ get path string
set-alias            \ and set the alias
;
: unknown-enet ( -- pci-net-num )
pci-net-num dup 1+ TO pci-net-num
;
: pci-alias-net ( config-addr -- )
drop                                   \ forget the config address
pci-net-num dup 1+ TO pci-net-num      \ increase the pci-net-num
s" net" rot pci-set-alias              \ create the alias
;
: pci-alias-disk ( config-addr -- )
drop                                    \ forget the config address
pci-disk-num dup 1+ TO pci-disk-num     \ increase the pci-disk-num
s" disk" rot pci-set-alias              \ create the alias
;
: pci-alias-cdrom ( config-addr -- )
drop                                    \ forget the config address
pci-cdrom-num dup 1+ TO pci-cdrom-num     \ increase the pci-cdrom-num
s" cdrom" rot pci-set-alias              \ create the alias
;
: pci-alias ( config-addr -- )
dup pci-class@ 
10 rshift CASE
01 OF   pci-alias-disk ENDOF
02 OF   pci-alias-net  ENDOF
dup OF   drop           ENDOF
ENDCASE
;
: pci-gen-irq-map-one ( prop-addr prop-len slot pin -- prop-addr prop-len )
2dup + 1- 3 and 1+          ( prop-addr prop-len slot pin parentpin )
>r >r                       ( prop-addr prop-len slot R: parentpin pin )
B lshift encode-int+        ( prop-addr prop-len R: parentpin pin )
0 encode-64+
r> encode-int+              ( prop-addr prop-len R: parentpin )
get-parent encode-int+
get-node >space
pci-addr2dev B lshift       ( prop-addr prop-len parent-slot R: parentpin )
encode-int+
0 encode-64+
r> encode-int+              ( prop-addr prop-len R: )
;
: pci-gen-irq-entry ( prop-addr prop-len config-addr -- prop-addr prop-len )
pci-addr2dev                ( prop-addr prop-len slot )
-rot                        ( slot prop-addr prop-len )
5 1 DO
2 pick i                ( slot prop-addr prop-len slot pin )
pci-gen-irq-map-one
LOOP
rot drop
;
: pci-set-irq-line ( config-addr -- )
drop
;
: pci-msi-prop ( addr -- )
5 pci-cap-find          ( capaddr )
?dup IF
2+ rtas-config-w@   ( msi-control )
1 rshift 7 and      ( msi-control:3:1 )
dup 6 < IF
1 swap lshift   ( vectors# )
encode-int " ibm,req#msi" property
ELSE
." Invalid MSI vectors number " . cr
THEN
THEN
;
: pci-msix-prop ( addr -- )
11 pci-cap-find         ( capaddr )
?dup IF
2+ rtas-config-w@   ( msix-control )
7ff and             ( msix-control:10:0 )
1+                  ( vectors# )
?dup IF
encode-int " ibm,req#msi-x" property
THEN
THEN
;
: pci-set-capabilities ( config-addr -- )
dup pci-msi-prop
dup pci-msix-prop
drop
;
: pci-class-name-00 ( addr -- str len )
pci-class@ 8 rshift FF and CASE
01  OF s" display"               ENDOF
dup OF s" legacy-device"         ENDOF
ENDCASE
;
: pci-class-name-01 ( addr -- str len )
pci-class@ 8 rshift FF and CASE
00  OF s" scsi"         ENDOF
01  OF s" ide"          ENDOF
02  OF s" fdc"          ENDOF
03  OF s" ipi"          ENDOF
04  OF s" raid"         ENDOF
05  OF s" ata"          ENDOF
06  OF s" sata"         ENDOF
07  OF s" sas"          ENDOF
dup OF s" mass-storage" ENDOF
ENDCASE
;
: pci-class-name-02 ( addr -- str len )
pci-class@ 8 rshift FF and CASE
00  OF s" ethernet"   ENDOF
01  OF s" token-ring" ENDOF
02  OF s" fddi"       ENDOF
03  OF s" atm"        ENDOF
04  OF s" isdn"       ENDOF
05  OF s" worldfip"   ENDOF
05  OF s" picmg"      ENDOF
dup OF s" network"    ENDOF
ENDCASE
;
: pci-class-name-03 ( addr -- str len )
pci-class@ FFFF and CASE
0000  OF s" vga"             ENDOF
0100  OF s" xga"             ENDOF
0200  OF s" 3d-controller"   ENDOF
dup OF s" display"           ENDOF
ENDCASE
;
: pci-class-name-04 ( addr -- str len )
pci-class@ 8 rshift FF and CASE
00  OF s" video"             ENDOF
01  OF s" sound"             ENDOF
02  OF s" telephony"         ENDOF
dup OF s" multimedia-device" ENDOF
ENDCASE
;
: pci-class-name-05 ( addr -- str len )
pci-class@ 8 rshift FF and CASE
00  OF s" memory"            ENDOF
01  OF s" flash"             ENDOF
dup OF s" memory-controller" ENDOF
ENDCASE
;
: pci-class-name-06 ( addr -- str len )
pci-class@ 8 rshift FF and CASE
00  OF s" host"                 ENDOF
01  OF s" isa"                  ENDOF
02  OF s" eisa"                 ENDOF
03  OF s" mca"                  ENDOF
04  OF s" pci"                  ENDOF
05  OF s" pcmcia"               ENDOF
06  OF s" nubus"                ENDOF
07  OF s" cardbus"              ENDOF
08  OF s" raceway"              ENDOF
09  OF s" semi-transparent-pci" ENDOF
0A  OF s" infiniband"           ENDOF
dup OF s" unknown-bridge"       ENDOF
ENDCASE
;
: pci-class-name-07 ( addr -- str len )
pci-class@ FFFF and CASE
0000  OF s" serial"                   ENDOF
0100  OF s" parallel"                 ENDOF
0200  OF s" multiport-serial"         ENDOF
0300  OF s" modem"                    ENDOF
0400  OF s" gpib"                     ENDOF
0500  OF s" smart-card"               ENDOF
dup   OF s" communication-controller" ENDOF
ENDCASE
;
: pci-class-name-08 ( addr -- str len )
pci-class@ FFFF and CASE
0000  OF s" interrupt-controller" ENDOF
0100  OF s" dma-controller"       ENDOF
0200  OF s" timer"                ENDOF
0300  OF s" rtc"                  ENDOF
0400  OF s" hot-plug-controller"  ENDOF
0500  OF s" sd-host-controller"   ENDOF
dup   OF s" system-peripheral"    ENDOF
ENDCASE
;
: pci-class-name-09 ( addr -- str len )
pci-class@ 8 rshift FF and CASE
00  OF s" keyboard"         ENDOF
01  OF s" pen"              ENDOF
02  OF s" mouse"            ENDOF
03  OF s" scanner"          ENDOF
04  OF s" gameport"         ENDOF
dup OF s" input-controller" ENDOF
ENDCASE
;
: pci-class-name-0A ( addr -- str len )
pci-class@ 8 rshift FF and CASE
00  OF s" dock"            ENDOF
dup OF s" docking-station" ENDOF
ENDCASE
;
: pci-class-name-0B ( addr -- str len )
pci-class@ 8 rshift FF and CASE
02  OF s" pentium"       ENDOF
20  OF s" powerpc"       ENDOF
30  OF s" mips"          ENDOF
40  OF s" co-processor"  ENDOF
dup OF s" cpu"           ENDOF
ENDCASE
;
: pci-class-name-0C ( addr -- str len )
pci-class@ FFFF and CASE
0000  OF s" firewire"      ENDOF
0100  OF s" access-bus"    ENDOF
0200  OF s" ssa"           ENDOF
0300  OF s" usb-uhci"      ENDOF
0310  OF s" usb-ohci"      ENDOF
0320  OF s" usb-ehci"      ENDOF
0330  OF s" usb-xhci"      ENDOF
0380  OF s" usb-unknown"   ENDOF
03FE  OF s" usb-device"    ENDOF
0400  OF s" fibre-channel" ENDOF
0500  OF s" smb"           ENDOF
0600  OF s" infiniband"    ENDOF
0700  OF s" ipmi"          ENDOF
0701  OF s" ipmi"          ENDOF
0702  OF s" ipmi"          ENDOF
0800  OF s" sercos"        ENDOF
0900  OF s" canbus"        ENDOF
dup OF s" serial-bus"      ENDOF
ENDCASE
;
: pci-class-name-0D ( addr -- str len )
pci-class@ 8 rshift FF and CASE
00  OF s" irda"                ENDOF
01  OF s" consumer-ir"         ENDOF
10  OF s" rf-controller"       ENDOF
11  OF s" bluetooth"           ENDOF
12  OF s" broadband"           ENDOF
dup OF s" wireless-controller" ENDOF
ENDCASE
;
: pci-class-name-0E ( addr -- str len )
pci-class@ 8 rshift FF and CASE
dup OF s" intelligent-io" ENDOF
ENDCASE
;
: pci-class-name-0F ( addr -- str len )
pci-class@ 8 rshift FF and CASE
01  OF s" satellite-tv"     ENDOF
02  OF s" satellite-audio"  ENDOF
03  OF s" satellite-voice"  ENDOF
04  OF s" satellite-data"   ENDOF
dup OF s" satellite-device" ENDOF
ENDCASE
;
: pci-class-name-10 ( addr -- str len )
pci-class@ 8 rshift FF and CASE
00  OF s" network-encryption"       ENDOF
01  OF s" entertainment-encryption" ENDOF
dup OF s" encryption"               ENDOF
ENDCASE
;
: pci-class-name-11 ( addr -- str len )
pci-class@ 8 rshift FF and CASE
00  OF s" dpio"                       ENDOF
01  OF s" counter"                    ENDOF
10  OF s" measurement"                ENDOF
20  OF s" managment-card"             ENDOF
dup OF s" data-processing-controller" ENDOF
ENDCASE
;
: pci-class-name ( addr -- str len )
dup pci-class@ 10 rshift CASE
00  OF pci-class-name-00 ENDOF
01  OF pci-class-name-01 ENDOF
02  OF pci-class-name-02 ENDOF
03  OF pci-class-name-03 ENDOF
04  OF pci-class-name-04 ENDOF
05  OF pci-class-name-05 ENDOF
06  OF pci-class-name-06 ENDOF
07  OF pci-class-name-07 ENDOF
08  OF pci-class-name-08 ENDOF
09  OF pci-class-name-09 ENDOF
0A  OF pci-class-name-0A ENDOF
0B  OF pci-class-name-0B ENDOF
0C  OF pci-class-name-0C ENDOF
0D  OF pci-class-name-0D ENDOF
0E  OF pci-class-name-0E ENDOF
0F  OF pci-class-name-0F ENDOF
10  OF pci-class-name-10 ENDOF
11  OF pci-class-name-11 ENDOF
dup OF drop s" unknown"  ENDOF
ENDCASE
;
: pci-bar-size@     ( bar-addr -- bar-size ) -1 over rtas-config-l! rtas-config-l@ ;
: pci-bar-size-mem@ ( bar-addr -- mem-size ) pci-bar-size@ -10 and invert 1+ FFFFFFFF and ;
: pci-bar-size-io@  ( bar-addr -- io-size  ) pci-bar-size@ -4 and invert 1+ FFFFFFFF and ;
: pci-bar-size ( bar-addr -- bar-size-raw )
dup rtas-config-l@ swap \ fetch original Value  ( bval baddr )
-1 over rtas-config-l!  \ make BAR show size    ( bval baddr )
dup rtas-config-l@      \ and fetch the size    ( bval baddr bsize )
-rot rtas-config-l!     \ restore Value
;
: pci-bar-size-mem32 ( bar-addr -- bar-size )
pci-bar-size            \ fetch raw size
-10 and invert 1+       \ calc size
FFFFFFFF and            \ keep lower 32 bits
;
: pci-bar-size-rom ( bar-addr -- bar-size )
pci-bar-size            \ fetch raw size
FFFFF800 and invert 1+  \ calc size
FFFFFFFF and            \ keep lower 32 bits
;
: pci-bar-size-mem64 ( bar-addr -- bar-size )
dup pci-bar-size        \ fetch raw size lower 32 bits
swap 4 + pci-bar-size   \ fetch raw size upper 32 bits
20 lshift +             \ and put them together
-10 and invert 1+       \ calc size
;
: pci-bar-size-io ( bar-addr -- bar-size )
pci-bar-size            \ fetch raw size
-4 and invert 1+        \ calc size
FFFFFFFF and            \ keep lower 32 bits
;
: pci-bar-code@ ( bar-addr -- 0|1..4|5 )
rtas-config-l@ dup                \ fetch the BaseAddressRegister
1 and IF                          \ IO BAR ?
2 and IF 0 ELSE 1 THEN    \ only '01' is valid
ELSE                              \ Memory BAR ?
F and CASE
0   OF 2 ENDOF    \ Memory 32 Bit Non-Prefetchable
8   OF 3 ENDOF    \ Memory 32 Bit Prefetchable
4   OF 4 ENDOF    \ Memory 64 Bit Non-Prefetchable
C   OF 5 ENDOF    \ Memory 64 Bit Prefechtable
dup OF 0 ENDOF    \ Not a valid BarType
ENDCASE
THEN
;
: assign-var-align ( size align var -- al-mem )
dup >r @                        \ ( size align cur-mem )
swap #aligned                   \ ( size al-mem )
tuck +                          \ ( al-mem new-mem )
r> !                            \ ( al-mem )
;
: assign-var-min-align ( size min-align var -- al-mem )
>r over umax                    \ ( size align )
r> assign-var-align             \ ( al-mem )
;
: assign-bar-value32 ( bar size var -- 4 )
over IF                         \ IF size > 0
>r                      \ | ( bar size )
pci-mem-bar-min-align   \ | ( bar size min-align )
r> assign-var-min-align \ | ( bar al-mem ) set variable to next mem
swap rtas-config-l!     \ | ( -- )         set the bar to al-mem
ELSE                            \ ELSE
2drop drop              \ | clear stack
THEN                            \ FI
4                               \ size of the base-address-register
;
: assign-io-bar-value32 ( bar size var -- 4 )
over IF                         \ IF size > 0
>r                      \ | ( bar size )
dup                     \ | ( bar size size-align )
r> assign-var-align     \ | ( bar al-mem ) set variable to next mem
swap rtas-config-l!     \ | ( -- )         set the bar to al-mem
ELSE                            \ ELSE
2drop drop              \ | clear stack
THEN                            \ FI
4                               \ size of the base-address-register
;
: assign-bar-value64 ( bar size var -- 8 )
over IF                         \ IF size > 0
>r                      \ | ( bar size )
pci-mem-bar-min-align   \ | ( bar size min-align )
r> assign-var-min-align \ | ( bar al-mem ) set variable to next mem
swap                    \ | ( al-mem addr ) calc config-addr of this bar
2dup rtas-config-l!     \ | ( al-mem addr ) set the Lower part of the bar to al-mem
4 + swap 20 rshift      \ | ( al-mem>>32 addr ) prepare the upper part of the al-mem
swap rtas-config-l!     \ | ( -- ) and set the upper part of the bar
ELSE                            \ ELSE
2drop drop              \ | clear stack
THEN                            \ FI
8                               \ size of the base-address-register
;
: assign-mem64-bar ( bar-addr -- 8 )
dup pci-bar-size-mem64         \ fetch size
pci-next-mem64 @ 0 = IF          \ Check if we have 64-bit memory range
pci-next-mem
ELSE
pci-next-mem64
THEN
assign-bar-value64              \ and set it all
;
: assign-mem32-bar ( bar-addr -- 4 )
dup pci-bar-size-mem32          \ fetch size
pci-next-mem @ IF
pci-next-mem
ELSE
pci-next-mmio
THEN
assign-bar-value32              \ and set it all
;
: assign-mmio64-bar ( bar-addr -- 8 )
dup pci-bar-size-mem64          \ fetch size
pci-next-mmio
assign-bar-value64              \ and set it all
;
: assign-mmio32-bar ( bar-addr -- 4 )
dup pci-bar-size-mem32          \ fetch size
pci-next-mmio                   \ var to change
assign-bar-value32              \ and set it all
;
: assign-io-bar ( bar-addr -- 4 )
dup pci-bar-size-io             \ fetch size
pci-next-io                     \ var to change
assign-io-bar-value32           \ and set it all
;
: assign-rom-bar ( bar-addr -- )
dup pci-bar-size-rom            \ fetch size
dup IF                          \ IF size > 0
over >r                 \ | save bar addr for enable
pci-next-mmio           \ | var to change
assign-bar-value32      \ | and set it
drop                    \ | forget the BAR length
r@ rtas-config-l@       \ | fetch BAR
1 or r> rtas-config-l!  \ | and enable the ROM
ELSE                            \ ELSE
2drop                   \ | clear stack
THEN
;
: assign-bar ( bar-addr -- reg-size )
dup pci-bar-code@                       \ calc BAR type
dup IF                                  \ IF >0
CASE                            \ | CASE Setup the right type
1 OF assign-io-bar     ENDOF    \ | - set up an IO-Bar
2 OF assign-mmio32-bar ENDOF    \ | - set up an 32bit MMIO-Bar
3 OF assign-mem32-bar  ENDOF    \ | - set up an 32bit MEM-Bar (prefetchable)
4 OF assign-mmio64-bar ENDOF    \ | - set up an 64bit MMIO-Bar
5 OF assign-mem64-bar  ENDOF    \ | - set up an 64bit MEM-Bar (prefetchable)
ENDCASE                         \ | ESAC
ELSE                                    \ ELSE
ABORT                           \ | Throw an exception
THEN                                    \ FI
;
: assign-all-device-bars ( configaddr -- )
28 10 DO                        \ BARs start at 10 and end at 27
dup i +                 \ calc config-addr of the BAR
assign-bar              \ and set it up
+LOOP                           \ add 4 or 8 to the index and loop
30 + assign-rom-bar             \ set up the ROM if available
;
: assign-all-bridge-bars ( configaddr -- )
18 10 DO                        \ BARs start at 10 and end at 17
dup i +                 \ calc config-addr of the BAR
assign-bar              \ and set it up
+LOOP                           \ add 4 or 8 to the index and loop
38 + assign-rom-bar             \ set up the ROM if available
;
: gen-mem64-bar-prop ( prop-addr prop-len bar-addr -- prop-addr prop-len 8 )
dup pci-bar-size-mem64                  \ fetch BAR Size        ( paddr plen baddr bsize )
dup IF                                  \ IF Size > 0
>r dup rtas-config-l@           \ | save size and fetch lower 32 bits ( paddr plen baddr val.lo R: size)
over 4 + rtas-config-l@         \ | fetch upper 32 bits               ( paddr plen baddr val.lo val.hi R: size)
20 lshift + -10 and >r          \ | calc 64 bit value and save it     ( paddr plen baddr R: size val )
82000000 or encode-int+         \ | Encode config addr                ( paddr plen R: size val )
r> encode-64+                   \ | Encode assigned addr              ( paddr plen R: size )
r> encode-64+                   \ | Encode size                       ( paddr plen )
ELSE                                    \ ELSE
2drop                           \ | don't do anything
THEN                                    \ FI
8                                       \ sizeof(BAR) = 8 Bytes
;
: gen-pmem64-bar-prop ( prop-addr prop-len bar-addr -- prop-addr prop-len 8 )
dup pci-bar-size-mem64                  \ fetch BAR Size        ( paddr plen baddr bsize )
dup IF                                  \ IF Size > 0
>r dup rtas-config-l@           \ | save size and fetch lower 32 bits ( paddr plen baddr val.lo R: size)
over 4 + rtas-config-l@         \ | fetch upper 32 bits               ( paddr plen baddr val.lo val.hi R: size)
20 lshift + -10 and >r          \ | calc 64 bit value and save it     ( paddr plen baddr R: size val )
C3000000 or encode-int+         \ | Encode config addr                ( paddr plen R: size val )
r> encode-64+                   \ | Encode assigned addr              ( paddr plen R: size )
r> encode-64+                   \ | Encode size                       ( paddr plen )
ELSE                                    \ ELSE
2drop                           \ | don't do anything
THEN                                    \ FI
8                                       \ sizeof(BAR) = 8 Bytes
;
: gen-mem32-bar-prop ( prop-addr prop-len bar-addr -- prop-addr prop-len 4 )
dup pci-bar-size-mem32                  \ fetch BAR Size        ( paddr plen baddr bsize )
dup IF                                  \ IF Size > 0
>r dup rtas-config-l@           \ | save size and fetch value         ( paddr plen baddr val R: size)
-10 and >r                      \ | calc 32 bit value and save it     ( paddr plen baddr R: size val )
82000000 or encode-int+         \ | Encode config addr                ( paddr plen R: size val )
r> encode-64+                   \ | Encode assigned addr              ( paddr plen R: size )
r> encode-64+                   \ | Encode size                       ( paddr plen )
ELSE                                    \ ELSE
2drop                           \ | don't do anything
THEN                                    \ FI
4                                       \ sizeof(BAR) = 4 Bytes
;
: gen-pmem32-bar-prop ( prop-addr prop-len bar-addr -- prop-addr prop-len 4 )
dup pci-bar-size-mem32                  \ fetch BAR Size        ( paddr plen baddr bsize )
dup IF                                  \ IF Size > 0
>r dup rtas-config-l@           \ | save size and fetch value         ( paddr plen baddr val R: size)
-10 and >r                      \ | calc 32 bit value and save it     ( paddr plen baddr R: size val )
C2000000 or encode-int+         \ | Encode config addr                ( paddr plen R: size val )
r> encode-64+                   \ | Encode assigned addr              ( paddr plen R: size )
r> encode-64+                   \ | Encode size                       ( paddr plen )
ELSE                                    \ ELSE
2drop                           \ | don't do anything
THEN                                    \ FI
4                                       \ sizeof(BAR) = 4 Bytes
;
: gen-io-bar-prop ( prop-addr prop-len bar-addr -- prop-addr prop-len 4 )
dup pci-bar-size-io                     \ fetch BAR Size                      ( paddr plen baddr bsize )
dup IF                                  \ IF Size > 0
>r dup rtas-config-l@           \ | save size and fetch value         ( paddr plen baddr val R: size)
-4 and >r                       \ | calc 32 bit value and save it     ( paddr plen baddr R: size val )
81000000 or encode-int+         \ | Encode config addr                ( paddr plen R: size val )
r> encode-64+                   \ | Encode assigned addr              ( paddr plen R: size )
r> encode-64+                   \ | Encode size                       ( paddr plen )
ELSE                                    \ ELSE
2drop                           \ | don't do anything
THEN                                    \ FI
4                                       \ sizeof(BAR) = 4 Bytes
;
: gen-rom-bar-prop ( prop-addr prop-len bar-addr -- prop-addr prop-len )
dup pci-bar-size-rom                    \ fetch BAR Size                      ( paddr plen baddr bsize )
dup IF                                  \ IF Size > 0
>r dup rtas-config-l@           \ | save size and fetch value         ( paddr plen baddr val R: size)
FFFFF800 and >r                 \ | calc 32 bit value and save it     ( paddr plen baddr R: size val )
82000000 or encode-int+         \ | Encode config addr                ( paddr plen R: size val )
r> encode-64+                   \ | Encode assigned addr              ( paddr plen R: size )
r> encode-64+                   \ | Encode size                       ( paddr plen )
ELSE                                    \ ELSE
2drop                           \ | don't do anything
THEN                                    \ FI
;
: pci-add-assigned-address ( prop-addr prop-len bar-addr -- prop-addr prop-len bsize )
dup pci-bar-code@                               \ calc BAR type                         ( paddr plen baddr btype)
CASE                                            \ CASE for the BAR types                ( paddr plen baddr )
0 OF drop 4              ENDOF          \ - not a valid type so do nothing
1 OF gen-io-bar-prop     ENDOF          \ - IO-BAR
2 OF gen-mem32-bar-prop  ENDOF          \ - MEM32
3 OF gen-pmem32-bar-prop ENDOF          \ - MEM32 prefetchable
4 OF gen-mem64-bar-prop  ENDOF          \ - MEM64
5 OF gen-pmem64-bar-prop ENDOF          \ - MEM64 prefetchable
ENDCASE                                         \ ESAC ( paddr plen bsize )
;
: pci-device-assigned-addresses-prop ( addr -- )
encode-start                                    \ provide mem for property              ( addr paddr plen )
2 pick 30 + gen-rom-bar-prop                    \ assign the rom bar
28 10 DO                                        \ we have 6 possible BARs
2 pick i +                              \ calc BAR address                      ( addr paddr plen bar-addr )      
pci-add-assigned-address                \ and generate the props for the BAR
+LOOP                                           \ increase Index by returned len
s" assigned-addresses" property drop            \ and write it into the device tree
;
: pci-bridge-assigned-addresses-prop ( addr -- )
encode-start                                    \ provide mem for property
2 pick 38 + gen-rom-bar-prop                    \ assign the rom bar
18 10 DO                                        \ we have 2 possible BARs
2 pick i +                              \ ( addr paddr plen current-addr )
pci-add-assigned-address                \ and generate the props for the BAR
+LOOP                                           \ increase Index by returned len
s" assigned-addresses" property drop            \ and write it into the device tree
;
: pci-bridge-gen-range ( paddr plen base limit type -- paddr plen )
>r over -                       \ calc size             ( paddr plen base size R:type )
dup 0< IF                       \ IF Size < 0           ( paddr plen base size R:type )
2drop r> drop           \ | forget values       ( paddr plen )
ELSE                            \ ELSE
1+ swap 2swap           \ | adjust stack        ( size base paddr plen R:type )
r@ encode-int+          \ | Child type          ( size base paddr plen R:type )
2 pick encode-64+       \ | Child address       ( size base paddr plen R:type )
r> encode-int+          \ | Parent type         ( size base paddr plen )
rot encode-64+          \ | Parent address      ( size paddr plen )
rot encode-64+          \ | Encode size         ( paddr plen )
THEN                            \ FI
;
: pci-bridge-gen-mmio-range ( addr prop-addr prop-len -- addr prop-addr prop-len )
2 pick 20 + rtas-config-l@      \ fetch Value           ( addr paddr plen val )
dup 0000FFF0 and 10 lshift      \ calc base-address     ( addr paddr plen val base )
swap 000FFFFF or                \ calc limit-address    ( addr paddr plen base limit )
02000000 pci-bridge-gen-range   \ and generate it       ( addr paddr plen )
;
: pci-bridge-gen-mem-range ( addr prop-addr prop-len -- addr prop-addr prop-len )
2 pick 24 + rtas-config-l@      \ fetch Value           ( addr paddr plen val )
dup 000FFFFF or                 \ calc limit Bits 31:0  ( addr paddr plen val limit.31:0 )
swap 0000FFF0 and 10 lshift     \ calc base Bits 31:0   ( addr paddr plen limit.31:0 base.31:0 )
4 pick 28 + rtas-config-l@      \ fetch upper Basebits  ( addr paddr plen limit.31:0 base.31:0 base.63:32 )
20 lshift or swap               \ and calc Base         ( addr paddr plen base.63:0 limit.31:0 )
4 pick 2C + rtas-config-l@      \ fetch upper Limitbits ( addr paddr plen base.63:0 limit.31:0 limit.63:32 )
dup -rot 20 lshift or swap      \ and calc Limit        ( addr paddr plen base.63:0 limit.63:0 limit.63:32 )
IF 43000000 ELSE 42000000 THEN  \ 64-bit or 32-bit?     ( addr paddr plen base.63:0 limit.63:0 type )
pci-bridge-gen-range            \ and generate it       ( addr paddr plen )
;
: pci-bridge-gen-io-range ( addr prop-addr prop-len -- addr prop-addr prop-len )
2 pick 1C + rtas-config-l@      \ fetch Value           ( addr paddr plen val )
dup 0000F000 and 00000FFF or    \ calc Limit Bits 15:0  ( addr paddr plen val limit.15:0 )
swap 000000F0 and 8 lshift      \ calc Base Bits 15:0   ( addr paddr plen limit.15:0 base.15:0 )
4 pick 30 + rtas-config-l@      \ fetch upper Bits      ( addr paddr plen limit.15:0 base.15:0 val )
dup FFFF and 10 lshift rot or   \ calc Base             ( addr paddr plen limit.15:0 val base.31:0 )
-rot FFFF0000 and or            \ calc Limit            ( addr paddr plen base.31:0 limit.31:0 )
01000000 pci-bridge-gen-range   \ and generate it       ( addr paddr plen )
;
: pci-bridge-range-props ( addr -- )
encode-start                    \ provide mem for property
pci-bridge-gen-mmio-range       \ generate the non prefetchable Memory Entry
pci-bridge-gen-mem-range        \ generate the prefetchable Memory Entry
pci-bridge-gen-io-range         \ generate the IO Entry
dup IF                          \ IF any space present (propsize>0)
s" ranges" property     \ | write it into the device tree
ELSE                            \ ELSE
s" " s" ranges" property
2drop                   \ | forget the properties
THEN                            \ FI
drop                            \ forget the address
;
: pci-bridge-interrupt-map ( -- )
encode-start                                    \ create the property                           ( paddr plen )
get-node child                                  \ find the first child                          ( paddr plen handle )
BEGIN dup WHILE                                 \ Loop as long as the handle is non-zero        ( paddr plen handle )
dup >r >space                           \ Get the my-space                              ( paddr plen addr R: handle )
pci-gen-irq-entry                       \ and Encode the interrupt settings             ( paddr plen R: handle)
r> peer                                 \ Get neighbour                                 ( paddr plen handle )
REPEAT                                          \ process next childe node                      ( paddr plen handle )
drop                                            \ forget the null                               ( paddr plen )
s" interrupt-map" property                      \ and set it                                    ( -- )
1 encode-int s" #interrupt-cells" property      \ encode the cell#
f800 encode-int 0 encode-int+ 0 encode-int+     \ encode the bit mask for config addr (Dev only)
7 encode-int+ s" interrupt-map-mask" property   \ encode IRQ#=7 and generate property
;
: encode-mem32-bar ( prop-addr prop-len BAR-addr -- prop-addr prop-len 4 )
dup pci-bar-size-mem32                  \ calc BAR-size ( not changing the BAR )
dup IF                                  \ IF BAR-size > 0       ( paddr plen baddr bsize )
>r 02000000 or encode-int+      \ | save size and encode BAR addr
0 encode-64+                    \ | make mid and lo zero
r> encode-64+                   \ | encode size
ELSE                                    \ ELSE
2drop                           \ | don't do anything
THEN                                    \ FI
4                                       \ BAR-Len = 4 (32Bit)
;
: encode-pmem32-bar ( prop-addr prop-len BAR-addr -- prop-addr prop-len 4 )
dup pci-bar-size-mem32                  \ calc BAR-size ( not changing the BAR )
dup IF                                  \ IF BAR-size > 0       ( paddr plen baddr bsize )
>r 42000000 or encode-int+      \ | save size and encode BAR addr
0 encode-64+                    \ | make mid and lo zero
r> encode-64+                   \ | encode size
ELSE                                    \ ELSE
2drop                           \ | don't do anything
THEN                                    \ FI
4                                       \ BAR-Len = 4 (32Bit)
;
: encode-mem64-bar ( prop-addr prop-len BAR-addr -- prop-addr prop-len 8 )
dup pci-bar-size-mem64                  \ calc BAR-size ( not changing the BAR )
dup IF                                  \ IF BAR-size > 0       ( paddr plen baddr bsize )
>r 03000000 or encode-int+      \ | save size and encode BAR addr
0 encode-64+                    \ | make mid and lo zero
r> encode-64+                   \ | encode size
ELSE                                    \ ELSE
2drop                           \ | don't do anything
THEN                                    \ FI
8                                       \ BAR-Len = 8 (64Bit)
;
: encode-pmem64-bar ( prop-addr prop-len BAR-addr -- prop-addr prop-len 8 )
dup pci-bar-size-mem64                  \ calc BAR-size ( not changing the BAR )
dup IF                                  \ IF BAR-size > 0       ( paddr plen baddr bsize )
>r 43000000 or encode-int+      \ | save size and encode BAR addr
0 encode-64+                    \ | make mid and lo zero
r> encode-64+                   \ | encode size
ELSE                                    \ ELSE
2drop                           \ | don't do anything
THEN                                    \ FI
8                                       \ BAR-Len = 8 (64Bit)
;
: encode-rom-bar ( prop-addr prop-len configaddr -- prop-addr prop-len )
dup pci-bar-size-rom                            \ fetch raw BAR-size
dup IF                                          \ IF BAR is used
>r 02000000 or encode-int+              \ | save size and encode BAR addr
0 encode-64+                            \ | make mid and lo zero
r> encode-64+                           \ | calc and encode the size
ELSE                                            \ ELSE
2drop                                   \ | don't do anything
THEN                                            \ FI
;
: encode-io-bar ( prop-addr prop-len BAR-addr BAR-value -- prop-addr prop-len 4 )
dup pci-bar-size-io                     \ calc BAR-size ( not changing the BAR )
dup IF                                  \ IF BAR-size > 0       ( paddr plen baddr bsize )
>r 01000000 or encode-int+      \ | save size and encode BAR addr
0 encode-64+                    \ | make mid and lo zero
r> encode-64+                   \ | encode size
ELSE                                    \ ELSE
2drop                           \ | don't do anything
THEN                                    \ FI
4                                       \ BAR-Len = 4 (32Bit)
;
: encode-bar ( prop-addr prop-len bar-addr -- prop-addr prop-len bar-len )
dup pci-bar-code@                               \ calc BAR type
CASE                                            \ CASE for the BAR types ( paddr plen baddr val )
0 OF drop 4             ENDOF           \ - not a valid type so do nothing
1 OF encode-io-bar      ENDOF           \ - IO-BAR
2 OF encode-mem32-bar   ENDOF           \ - MEM32
3 OF encode-pmem32-bar  ENDOF           \ - MEM32 prefetchable
4 OF encode-mem64-bar   ENDOF           \ - MEM64
5 OF encode-pmem64-bar  ENDOF           \ - MEM64 prefetchable
ENDCASE                                         \ ESAC ( paddr plen blen )
;
: pci-reg-props ( configaddr -- )
dup encode-int                  \ configuration space           ( caddr paddr plen )
0 encode-64+                    \ make the rest 0
0 encode-64+                    \ encode the size as 0
2 pick pci-htype@               \ fetch Header Type             ( caddr paddr plen type )
1 and IF                        \ IF Bridge                     ( caddr paddr plen )
18 10 DO                \ | loop over all BARs
2 pick i +      \ | calc bar-addr               ( caddr paddr plen baddr )
encode-bar      \ | encode this BAR             ( caddr paddr plen blen )
+LOOP              \ | increase LoopIndex by the BARlen
2 pick 38 +             \ | calc ROM-BAR for a bridge   ( caddr paddr plen baddr )
encode-rom-bar          \ | encode the ROM-BAR          ( caddr paddr plen )
ELSE                            \ ELSE ordinary device          ( caddr paddr plen )
28 10 DO                 \ | loop over all BARs
2 pick i +      \ | calc bar-addr               ( caddr paddr plen baddr )
encode-bar      \ | encode this BAR             ( caddr paddr plen blen )
+LOOP              \ | increase LoopIndex by the BARlen
2 pick 30 +             \ | calc ROM-BAR for a device   ( caddr paddr plen baddr )
encode-rom-bar          \ | encode the ROM-BAR          ( caddr paddr plen )
THEN                            \ FI                            ( caddr paddr plen )
s" reg" property                \ and store it into the property
drop
;
: pci-common-props ( addr -- )
dup pci-class-name device-name
dup pci-vendor@    encode-int s" vendor-id"      property
dup pci-device@    encode-int s" device-id"      property
dup pci-revision@  encode-int s" revision-id"    property
dup pci-class@     encode-int s" class-code"     property
3 encode-int s" #address-cells" property
2 encode-int s" #size-cells"    property
dup pci-config-ext? IF 1 encode-int s" ibm,pci-config-space-type" property THEN
dup pci-status@
dup 9 rshift 3 and encode-int s" devsel-speed" property
dup 7 rshift 1 and IF 0 0 s" fast-back-to-back" property THEN
dup 6 rshift 1 and IF 0 0 s" 66mhz-capable" property THEN
5 rshift 1 and IF 0 0 s" udf-supported" property THEN
dup pci-cache@     ?dup IF encode-int s" cache-line-size" property THEN
pci-interrupt@ ?dup IF encode-int s" interrupts"      property THEN
;
: pci-device-props ( addr -- )
dup pci-common-props
dup pci-min-grant@ encode-int s" min-grant"   property
dup pci-max-lat@   encode-int s" max-latency" property
dup pci-sub-device@ ?dup IF encode-int s" subsystem-id" property THEN
dup pci-sub-vendor@ ?dup IF encode-int s" subsystem-vendor-id" property THEN
dup pci-device-assigned-addresses-prop
pci-reg-props
pci-hotplug-enabled IF
dup dup pci-addr2bus 8 lshift
swap pci-addr2dev 3 lshift or
40000000 + encode-int s" ibm,my-drc-index" property
dup dup pci-addr2bus 20 *
swap pci-addr2dev +
a base !
s" Slot " rot $cathex
hex
encode-string s" ibm,loc-code" property
THEN
;
: pci-bridge-props ( addr -- )
dup pci-bus@
encode-int s" primary-bus" property
encode-int s" secondary-bus" property
encode-int s" subordinate-bus" property
dup pci-bus@ drop encode-int rot encode-int+ s" bus-range" property
pci-device-slots encode-int s" slot-names" property
dup pci-bridge-range-props
dup pci-bridge-assigned-addresses-prop
s" interrupt-map" get-node get-property IF
pci-bridge-interrupt-map
ELSE 2drop THEN
pci-reg-props
;
: pci-bridge-generic-setup ( addr -- )
pci-device-slots >r             \ save the slot array on return stack
dup pci-common-props            \ set the common properties before scanning the bus
s" pci" device-type             \ the type is allways "pci"
dup func-pci-bridge-probe       \ find all device connected to it
dup assign-all-bridge-bars      \ set up all memory access BARs
dup pci-set-irq-line            \ set the interrupt pin
dup pci-set-capabilities        \ set up the capabilities
pci-bridge-props            \ and generate all properties
r> TO pci-device-slots          \ and reset the slot array
;
DEFER func-pci-device-props
: pci-device-generic-setup ( config-addr -- )
dup assign-all-device-bars      \ calc all BARs
dup pci-set-irq-line            \ set the interrupt pin
dup pci-set-capabilities        \ set up the capabilities
dup func-pci-device-props       \ and generate all properties
drop                            \ forget the config-addr
;
' pci-device-props TO func-pci-device-props
' pci-bridge-range-props TO func-pci-bridge-range-props
: populate-pci-busses ( -- )
" /" find-device get-node child
BEGIN
dup 0 <>
WHILE
dup set-node
dup " name" rot get-package-property 0 = IF
drop dup from-cstring
2dup s" pci" strequal IF
s" pci-phb.fs" included
THEN
2drop
THEN
peer
REPEAT drop
device-end
;
populate-pci-busses
600 cp
: check-patch-kernel-sc1 ( -- )
ciregs >r4 @
dup 1000000 +
dup 2000000 < IF 0 ELSE dup 2000000 - THEN
swap
check-and-patch-sc1
;
' check-patch-kernel-sc1 add-quiesce-xt
' rtas-quiesce add-quiesce-xt
6c0 cp
set-chosen-cpu
s" /memory@0" open-dev encode-int s" memory" set-chosen
700 cp
s" /openprom" find-device
s" SLOF," slof-build-id here swap rmove here slof-build-id nip $cat encode-string s" model" property
0 0 s" relative-addressing" property
device-end
s" /mmu" open-dev encode-int s" mmu" set-chosen
VARIABLE chosen-memory-ih 0 chosen-memory-ih !
: (chosen-memory-ph) ( -- phandle )
chosen-memory-ih @ ?dup 0= IF
s" memory" get-chosen IF
decode-int nip nip dup chosen-memory-ih !
ihandle>phandle
ELSE 0 THEN
ELSE ihandle>phandle THEN
;
: (set-available-prop) ( prop plen -- )
s" available"
(chosen-memory-ph) ?dup 0<> IF set-property ELSE
cr ." Can't find chosen memory node - "
." no available property created" cr
2dup 2dup
THEN
;
: update-available-property ( available-ptr -- )
dup >r available>size@
0= r@ available AVAILABLE-SIZE /available * + >= or IF
available r> available - encode-bytes (set-available-prop)
ELSE
r> /available + RECURSE
THEN
;
: update-available-property available update-available-property ;
: claim ( [ addr ] len align -- base ) claim update-available-property ;
: release ( addr len -- ) release update-available-property ;
update-available-property
0 VALUE read-xt
0 VALUE write-xt
VARIABLE stdin
VARIABLE stdout
: set-stdin ( ihandle -- )
stdin @ ?dup IF close-dev THEN
dup stdin !
encode-int s" stdin"  set-chosen
;
: set-stdout ( ihandle -- )
stdout @ ?dup IF close-dev THEN
dup stdout !
encode-int s" stdout" set-chosen
;
: input  ( dev-str dev-len -- )
open-dev ?dup IF
dup s" read" rot ihandle>phandle find-method
0= IF
drop
cr ." Cannot find the read method for the given input console " cr
EXIT
THEN
to read-xt
set-stdin
THEN
;
: output  ( dev-str dev-len -- )
open-dev ?dup IF
dup s" write" rot ihandle>phandle find-method
0= IF
drop
cr ." Cannot find the write method for the given output console " cr
EXIT
THEN
to write-xt
set-stdout
THEN
;
: io  ( dev-str dev-len -- )
2dup input output
;
1 BUFFER: (term-io-char-buf)
: term-io-emit ( char -- )
write-xt IF
(term-io-char-buf) c!
(term-io-char-buf) 1 write-xt stdout @ call-package
drop
ELSE
serial-emit
THEN
;
' term-io-emit to emit
: term-io-key  ( -- char )
read-xt IF
BEGIN
(term-io-char-buf) 1 read-xt stdin @ call-package
0 >
UNTIL
(term-io-char-buf) c@
ELSE
serial-key
THEN
;
' term-io-key to key
: term-io-key?  ( -- true|false )
stdin @ ?dup IF
>r \ store ihandle on return stack
s" device_type" r@ ihandle>phandle ( propstr len phandle )
get-property ( true | data dlen false )
IF
false
ELSE
1 - \ remove 1 from length to ignore null-termination char
2dup s" serial" str= IF
2drop serial-key? r> drop EXIT
THEN \ call serial-key, cleanup return-stack, exit
2dup s" keyboard" str= IF 
2drop ( )
s" key-available?" r@ ihandle>phandle find-method IF 
drop s" key-available?" r@ $call-method  
ELSE 
false 
THEN
r> drop EXIT \ cleanup return-stack, exit
THEN
2drop r> drop false EXIT \ unknown device_type cleanup return-stack, return false
THEN
ELSE
serial-key?
THEN
;
' term-io-key? to key?
800 cp
51 CONSTANT nvram-partition-type-cpulog
60 CONSTANT nvram-partition-type-sas
61 CONSTANT nvram-partition-type-sms
6e CONSTANT nvram-partition-type-debug
6f CONSTANT nvram-partition-type-history
70 CONSTANT nvram-partition-type-common
7f CONSTANT nvram-partition-type-freespace
a0 CONSTANT nvram-partition-type-linux
: rztype ( str len -- ) \ stop at zero byte, read with nvram-c@
0 DO
dup i + nvram-c@ ?dup IF ( str char )
emit
ELSE                     ( str )
drop UNLOOP EXIT
THEN
LOOP
;
create tmpStr 500 allot
: rzcount ( zstr -- str len )
dup tmpStr >r BEGIN
dup nvram-c@ dup r> dup 1+ >r c!
WHILE
char+
REPEAT
r> drop over - swap drop tmpStr swap
;
: calc-header-cksum ( offset -- cksum )
dup nvram-c@
10 2 DO
over I + nvram-c@ +
LOOP
wbsplit + nip
;
: bad-header? ( offset -- flag )
dup 2+ nvram-w@        ( offset length )
0= IF                  ( offset )
drop true EXIT      ( )
THEN
dup calc-header-cksum  ( offset checksum' )
swap 1+ nvram-c@       ( checksum ' checksum )
<>                     ( flag )
;
: .header ( offset -- )
cr                         ( offset )
dup bad-header? IF         ( offset )
."   BAD HEADER -- trying to print it anyway" cr
THEN
space                      ( offset )
dup nvram-c@ 2 0.r         ( offset )
space space                ( offset )
dup 2+ nvram-w@ 10 * 5 .r  ( offset )
space space                ( offset )
4 + 0c rztype              ( )
;
: .headers ( -- )
cr cr ." Type  Size  Name"
cr ." ========================"
0 BEGIN                      ( offset )
dup nvram-c@              ( offset type )
WHILE
dup .header               ( offset )
dup 2+ nvram-w@ 10 * +    ( offset offset' )
dup nvram-size < IF       ( offset )
ELSE
drop EXIT              ( )
THEN
REPEAT
drop                         ( )
cr cr
;
: reset-nvram ( -- )
internal-reset-nvram
;
: dump-partition     ['] nvram-c@      1 (dump) ;
: type-no-zero ( addr len -- )
0 DO
dup I + dup nvram-c@ 0= IF drop ELSE nvram-c@ emit THEN
LOOP
drop
;
: type-no-zero-part ( from-str cnt-str addr len )
0 DO
dup i + dup nvram-c@ 0= IF
drop
ELSE
3 pick 0= 3 pick 0 > AND IF
dup 1 type-no-zero
THEN
nvram-c@ a = IF
2 pick 0= IF
over 1- 0 max
rot drop swap
THEN
2 pick 1- 0 max
3 roll drop rot rot
THEN
THEN
LOOP
drop
;
: (dmesg-prepare) ( base-addr -- base-addr' addr len act-off )
10 - \ go back to header
dup 14 + nvram-l@ dup >r
( base-addr act-off ) ( R: act-off )
over over over + swap 10 + nvram-w@ + >r
( base-addr act-off ) ( R:  act-off nvram-act-addr )
over 2 + nvram-w@ 10 * swap - over swap
( base-addr base-addr start-size ) ( R:  act-off nvram-act-addr )
r> swap rot 10 + nvram-w@ - r>
;
: .dmesg ( base-addr -- )
(dmesg-prepare) >r
cr type-no-zero
( base-addr ) ( R: act-off )
dup 10 + nvram-w@ + r> type-no-zero
;
: .dmesg-part ( from-str cnt-str base-addr -- )
(dmesg-prepare) >r
>r >r -rot r> r>
cr type-no-zero-part rot
( base-addr ) ( R: act-off )
dup 10 + nvram-w@ + r> type-no-zero-part
;
: dmesg-part ( from-str cnt-str -- left-from-str left-cnt-str )
2dup
s" ibm,CPU0log" get-named-nvram-partition IF
2drop EXIT
THEN
drop .dmesg-part nip nip
;
: dmesg2 ( -- )
s" ibm,CPU1log" get-named-nvram-partition IF
." No log partition." cr EXIT
THEN
drop .dmesg
;
: dmesg ( -- )
s" ibm,CPU0log" get-named-nvram-partition IF
." No log partition." cr EXIT
THEN
drop .dmesg
;
880 cp
wordlist CONSTANT envvars
: listenv  ( -- )
get-current envvars set-current  words  set-current
;
: create-env ( "name" -- )
get-current  envvars set-current  CREATE  set-current
;
: env-int     ( n -- )  1 c, align , DOES> char+ aligned @ ;
: env-bytes   ( a len -- )
2 c, align dup , here swap dup allot move
DOES> char+ aligned dup @ >r cell+ r>
;
: env-string  ( str len -- )  3 c, align dup , here over allot swap move DOES> char+ aligned dup @ >r cell+ r> ;
: env-flag    ( f -- )  4 c, c, DOES> char+ c@ 0<> ;
: env-secmode ( sm -- )  5 c, c, DOES> char+ c@ ;
: default-int     ( n "name" -- )      create-env env-int ;
: default-bytes   ( a len "name" -- )  create-env env-bytes ;
: default-string  ( a len "name" -- )  create-env env-string ;
: default-flag    ( f "name" -- )      create-env env-flag ;
: default-secmode ( sm "name" -- )     create-env env-secmode ;
: set-option ( option-name len option len -- )
2swap encode-string
2swap s" /options" find-node dup IF set-property ELSE drop 2drop 2drop THEN
;
: findenv ( name len -- adr def-adr type | 0 )
2dup envvars voc-find dup 0<> IF ( ABORT" not a configuration variable" )
link> >body char+ >r (find-order) link> >body dup char+ swap c@ r> swap
ELSE
nip nip
THEN
;
: test-flag ( param len -- true | false )
2dup s" true" string=ci -rot s" false" string=ci or
;
: test-secmode ( param len -- true | false )
2dup s" none" string=ci -rot 2dup s" command" string=ci -rot s" full"
string=ci or or
;
: test-int ( param len -- true | false )
$dh-number IF false ELSE drop true THEN
;
: findtype ( param len name len -- param len name len type )
2dup findenv                         \ try to find type of envvar
dup IF                               \ found a type?
nip nip
EXIT
THEN
drop 2swap
2dup test-flag IF
4 -rot                         \ boolean type
ELSE
2dup test-secmode IF
5 -rot                      \ secmode type
ELSE
2dup test-int IF
1 -rot                   \ integer type
ELSE
2dup test-string
IF 3 ELSE 2 THEN         \ 3 = string, 2 = default to bytes
-rot
THEN
THEN
THEN
rot
>r 2swap r>
;
: $setenv ( param len name len -- )
4dup set-option
findtype
-rot $CREATE
CASE
1 OF $dh-number IF 0 THEN env-int ENDOF \ XXX: wants decimal and 0x...
2 OF env-bytes ENDOF
3 OF env-string ENDOF
4 OF evaluate env-flag ENDOF
5 OF evaluate env-secmode ENDOF \ XXX: recognize none, command, full
ENDCASE
;
: (printenv) ( adr type -- )
CASE
1 OF aligned @ . ENDOF
2 OF aligned dup cell+ swap @ swap . . ENDOF
3 OF aligned dup @ >r cell+ r> type ENDOF
4 OF c@ IF ." true" ELSE ." false" THEN ENDOF
5 OF c@ . ENDOF \ XXX: print symbolically
ENDCASE
;
: .printenv-header ( -- )
cr
s" ---environment variable--------current value-------------default value------"
type cr
;
DEFER old-emit
0 VALUE emit-counter
: emit-and-count emit-counter 1 + to emit-counter old-emit ;
: .enable-emit-counter
0 to emit-counter
['] emit behavior to old-emit
['] emit-and-count to emit
;
: .disable-emit-counter
['] old-emit behavior to emit
;
: .spaces ( number-of-spaces -- )
dup 0 > IF
spaces
ELSE
drop space
THEN
;
: .print-one-env ( name len -- )
3 .spaces
2dup dup -rot type 1c swap - .spaces
findenv rot over
.enable-emit-counter
(printenv) .disable-emit-counter
1a emit-counter - .spaces
(printenv)
;
: .print-all-env
.printenv-header
envvars cell+
BEGIN
@ dup
WHILE
dup link> >name
name>string .print-one-env cr
REPEAT
drop
;
: printenv
parse-word dup 0= IF
2drop .print-all-env
ELSE
findenv dup 0= ABORT" not a configuration variable"
rot over cr ." Current: " (printenv)
cr ." Default: " (printenv)
THEN
;
: (set-default)  ( def-xt -- )
dup >name name>string 2dup $CREATE
rot dup >body c@ >r
execute
r> CASE
1 OF dup env-int (.d) 2swap set-option ENDOF
2 OF 2dup env-bytes 2swap set-option ENDOF
3 OF 2dup env-string 2swap set-option ENDOF
4 OF dup env-flag IF s" true" ELSE s" false" THEN 2swap set-option ENDOF
5 OF dup env-secmode (.d) 2swap set-option ENDOF
ENDCASE
;
true default-flag auto-boot?
s" " default-string boot-device
s" " default-string boot-file
s" boot" default-string boot-command
s" " default-string diag-device
s" " default-string diag-file
false default-flag diag-switch?
true default-flag fcode-debug?
s" " default-string input-device
s" " default-string nvramrc
s" " default-string oem-banner
false default-flag oem-banner?
0 0 default-bytes oem-logo
false default-flag oem-logo?
s" " default-string output-device
200 default-int screen-#columns
200 default-int screen-#rows
0 default-int security-#badlogins
0 default-secmode security-mode
s" " default-string security-password
0 default-int selftest-#megs
false default-flag use-nvramrc?
false default-flag direct-serial?
true default-flag real-mode?
default-load-base default-int load-base
VARIABLE nvoff \ offset in envvar partition
: (nvupdate-one) ( adr type -- "value" )
CASE
1 OF aligned @ (.d) ENDOF
2 OF drop 0 0 ENDOF
3 OF aligned dup @ >r cell+ r> ENDOF
4 OF c@ IF s" true" ELSE s" false" THEN ENDOF
5 OF c@ (.) ENDOF \ XXX: print symbolically
ENDCASE
;
: nvupdate-one   ( def-xt -- )
>r nvram-partition-type-common get-nvram-partition       ( part.addr part.len FALSE|TRUE R: def-xt )
ABORT" No valid NVRAM." r>      ( part.addr part.len def-xt )
>name name>string               ( part.addr part.len var.a var.l )
2dup findenv nip (nvupdate-one)
internal-add-env
drop
;
: (nvupdate) ( -- )
nvram-partition-type-common get-nvram-partition ABORT" No valid NVRAM."
erase-nvram-partition drop
envvars cell+
BEGIN @ dup WHILE dup link> nvupdate-one REPEAT
drop
;
: nvupdate ( -- )
." nvupdate is obsolete." cr
;
: set-default
parse-word envvars voc-find
dup 0= ABORT" not a configuration variable" link> (set-default)
;
: (set-defaults)
envvars cell+
BEGIN @ dup WHILE dup link> (set-default) REPEAT
drop
;
(set-defaults)
: set-defaults
(set-defaults) (nvupdate)
;
: setenv  parse-word ( skipws ) 0d parse -leading 2swap $setenv (nvupdate) ;
: get-nv  ( -- )
nvram-partition-type-common get-nvram-partition ( addr offset not-found | not-found ) \ find partition header
IF
." No NVRAM common partition, re-initializing..." cr
internal-reset-nvram
(nvupdate)
EXIT
THEN
drop ( addr )           \ throw away offset
BEGIN
dup rzcount  dup     \ make string from offset and make condition
WHILE                   ( offset offset length )
2dup [char] = split  \ Split string at equal sign (=)
2swap                ( offset offset length param len name len )
$setenv              \ Set envvar
nip                  \ throw away old string begin
+ 1+                 \ calc new offset
REPEAT
2drop drop              \ cleanup
;
get-nv
: check-for-nvramrc  ( -- )
use-nvramrc?  IF
s" Executing following code from nvramrc: "
s" nvramrc" evaluate $cat
nvramlog-write-string-cr
s" (!) Executing code specified in nvramrc" type
cr s"  SLOF Setup = " type
.enable-emit-counter
s" nvramrc" evaluate ['] evaluate  CATCH  IF
2drop
emit-counter 0  DO  8 emit  LOOP
s" (!) Code in nvramrc triggered exception. "
2dup nvramlog-write-string
type cr 12 spaces s" Aborting nvramrc execution" 2dup
nvramlog-write-string-cr type cr
s"  SLOF Setup = " type
THEN
.disable-emit-counter
THEN
;
: (nv-findalias) ( alias-ptr alias-len -- pos )
here 0
s" devalias " string-cat
3 pick 3 pick string-cat
s"  " string-cat
s" nvramrc" evaluate
2swap find-substr
nip nip
;
: (nv-build-real-entry) ( name-ptr name-len dev-ptr dev-len -- str-ptr str-len )
2swap here 0
s" devalias " string-cat
2swap string-cat
s"  " string-cat
2swap string-cat
0d char-cat
0a char-cat
;
: (nv-build-null-entry) ( name-ptr name-len dev-ptr dev-len -- str-ptr str-len )
4drop here 0
;
: (nv-build-nvramrc) ( name-str name-len dev-str dev-len xt-build-entry -- )
4 pick 4 pick (nv-findalias)
dup s" nvramrc" evaluate nip >= IF
drop execute
s" nvramrc" evaluate string-cat
dup allot
s" nvramrc" $setenv
ELSE  \ if our alias is still defined in nvramrc
5 pick 5 pick 5 pick 5 pick 5 pick execute nip over +
s" nvramrc" evaluate 3 pick string-at
2dup find-nextline string-at nip +
alloc-mem 0
s" nvramrc" evaluate drop 3 pick string-cat
rot >r >r >r execute r> r> 2swap string-cat
( mem, len ) ( R: alias-pos )
s" nvramrc" evaluate r> string-at
2dup find-nextline string-at string-cat
2dup s" nvramrc" $setenv free-mem
THEN
;
: $nvalias ( name-str name-len dev-str dev-len -- )
4dup ['] (nv-build-real-entry) (nv-build-nvramrc)
set-alias
s" true" s" use-nvramrc?" $setenv
(nvupdate)
;
: nvalias ( "alias-name< >device-specifier<eol>" -- )
parse-word parse-word dup 0<> IF
$nvalias
ELSE
2drop 2drop
cr
"    Usage: nvalias (""alias-name< >device-specifier<eol>"" -- )" type
cr
THEN    
;
: $nvunalias ( name-str name-len -- )
s" " ['] (nv-build-null-entry) (nv-build-nvramrc)
(nvupdate)
;
: nvunalias ( "alias-name< >" -- )
parse-word $nvunalias
;
: diagnostic-mode? ( -- diag-switch? ) diag-switch? ;
check-for-nvramrc
890 cp
defer set-boot-device
defer add-boot-device
: add-boot-aliases ( str -- )
2dup add-boot-device               ( $str )
MAX-ALIAS 1 DO
2dup i $cathex 2dup              ( $str $strN $strN )
find-alias 0 > IF                ( $str $strN false | $result )
drop strdup add-boot-device  ( $str )
ELSE 2drop THEN
LOOP
2drop
;
: is-strict-boot?  ( bl-str bl-len -- strict? )
dup 4 > IF
+ 5 - 5 s"  HALT" str=
ELSE
s" HALT" str=
THEN
;
: qemu-read-bootlist ( -- )
" qemu,boot-list" get-chosen IF
1-                                 \ Ignore the trailing NUL character
2dup set-boot-device
is-strict-boot? IF EXIT THEN
ELSE
0 0 set-boot-device
THEN
" qemu,boot-device" get-chosen not IF
" boot-device" evaluate swap drop 0= IF
" disk" add-boot-aliases
" cdrom" add-boot-aliases
" net" add-boot-aliases
THEN
EXIT
THEN
0 ?DO
dup i + c@ CASE
0        OF ENDOF
[char] a OF ENDOF
[char] b OF ENDOF
[char] c OF " disk"  add-boot-aliases ENDOF
[char] d OF " cdrom" add-boot-aliases ENDOF
[char] n OF " net"   add-boot-aliases ENDOF
ENDCASE cr
LOOP
drop
;
' qemu-read-bootlist to read-bootlist
8a0 cp
: dma-alloc ( size -- virt )
s" dma-alloc" $call-parent
;
: dma-free ( virt size -- )
s" dma-free" $call-parent
;
: dma-map-in ( virt size cacheable? -- devaddr )
s" dma-map-in" $call-parent
;
: dma-map-out ( virt devaddr size -- )
s" dma-map-out" $call-parent
;
0 VALUE debug-client-interface?
VOCABULARY client-voc \ We store all client-interface callable words here.
6789  CONSTANT  sc-exit
4711  CONSTANT  sc-yield
VARIABLE  client-callback \ Address of client's callback function
: client-data  ciregs >r3 @ ;
: nargs  client-data la1+ l@ ;
: nrets  client-data la1+ la1+ l@ ;
: client-data-to-stack
client-data 3 la+ nargs 0 ?DO dup l@ swap la1+ LOOP drop ;
: stack-to-client-data
client-data nargs nrets + 2 + la+ nrets 0 ?DO tuck l! /l - LOOP drop ;
: call-client ( args len client-entry -- )
>r  ciregs >r7 !  ciregs >r6 !  client-entry-point @ ciregs >r5 !
cistack ciregs >r1 !
s" linux,initrd-end" get-chosen IF decode-int nip nip ELSE 0 THEN
s" linux,initrd-start" get-chosen IF decode-int nip nip ELSE 0 THEN
tuck -	    ( start len )
ciregs >r4 !
ciregs >r3 !
r> jump-client drop
BEGIN
client-data-to-stack
client-data l@ zcount
ALSO client-voc $find PREVIOUS
dup 0= >r IF 
CATCH
?dup IF
dup CASE
sc-exit OF drop r> drop EXIT ENDOF
sc-yield OF drop r> drop EXIT ENDOF
ENDCASE
THROW
THEN
stack-to-client-data
ELSE
cr type ."  NOT FOUND"
THEN
r> ciregs >r3 !  ciregs >r4 @ jump-client 
UNTIL ;
: flip-stack ( a1 ... an n -- an ... a1 )  ?dup IF 1 ?DO i roll LOOP THEN ;
: (callback) ( "service-name<>" "arguments<cr>" -- )
client-callback @  \ client-callback points to the function prolog
dup 8 + @ ciregs >r2 !  \ Set up the TOC pointer (???)
@ call-client ;  \ Resolve the function's address from the prolog
' (callback) to callback
: (continue-client)
s" "  \ make call-client happy, client won't use the string anyways.
ciregs >r4 @ call-client ;
' (continue-client) to continue-client
: string-to-buffer ( str len buf len -- len' )
2dup erase rot min dup >r move r> ;
ALSO client-voc DEFINITIONS
: exit  sc-exit THROW ;
: yield  sc-yield THROW ;
: test ( zstr -- missing? )
zcount
debug-client-interface? IF
." ci: test " 2dup type cr
THEN
ALSO client-voc $find PREVIOUS IF
drop FALSE
ELSE
2drop TRUE
THEN 
;
: finddevice ( zstr -- phandle )
zcount
debug-client-interface? IF
." ci: finddevice " 2dup type cr
THEN
2dup " /memory" str= IF
2drop
" /memory@0"
THEN
find-node dup 0= IF drop -1 THEN
;
: getprop ( phandle zstr buf len -- len' )
>r >r zcount rot                     ( str-adr str-len phandle   R: len buf )
debug-client-interface? IF
." ci: getprop " 3dup . ." '" type ." '"
THEN
get-property
debug-client-interface? IF
dup IF ."  ** not found **" THEN
cr
THEN
0= IF
r> swap dup r> min swap >r move r>
ELSE
r> r> 2drop -1
THEN
;
: getproplen ( phandle zstr -- len )
zcount rot get-property 0= IF nip ELSE -1 THEN ;
: setprop ( phandle zstr buf len -- size|-1 )
dup >r            \ save len
encode-bytes      ( phandle zstr prop-addr prop-len )
2swap zcount rot  ( prop-addr prop-len name-addr name-len phandle )
current-node @ >r \ save current node
set-node          \ change to specified node
property          \ set property
r> set-node       \ restore original node
r>                \ always return size, because we can not fail.
;
: canon ( zstr buf len -- len' )
2dup erase
>r >r zcount
>r dup c@ [char] / = IF
r> r> swap r> over >r min move r>
ELSE
r> find-alias ?dup 0= IF
r> r> 2drop -1
ELSE
dup -rot r> swap r> min move
THEN
THEN
;
: nextprop ( phandle zstr buf -- flag ) \ -1 invalid, 0 end, 1 ok
>r zcount rot next-property IF r> zplace 1 ELSE r> drop 0 THEN ; 
: open ( zstr -- ihandle )
zcount
debug-client-interface? IF
." ci: open " 2dup type cr
THEN
open-dev
;
: close ( ihandle -- )
debug-client-interface? IF
." ci: close " dup . cr
THEN
s" stdin" get-chosen IF
decode-int nip nip over = IF
close-dev
quiesce
ELSE
close-dev
THEN
ELSE
close-dev
THEN
;
: write ( ihandle str len -- len' )      rot s" write" rot
['] $call-method CATCH IF 2drop 3drop -1 THEN ;
: read  ( ihandle str len -- len' )      rot s" read"  rot
['] $call-method CATCH IF 2drop 3drop -1 THEN ;
: seek  ( ihandle hi lo -- status  ) swap rot s" seek" rot
['] $call-method CATCH IF 2drop 3drop -1 THEN ;
: claim  ( addr len align -- base )
debug-client-interface? IF
." ci: claim " .s cr
THEN
dup  IF  rot drop
['] claim CATCH  IF  2drop -1  THEN
ELSE
['] claim CATCH  IF  3drop -1  THEN
THEN
;
: release ( addr len -- )
debug-client-interface? IF
." ci: release " .s cr
THEN
release
;
: instance-to-package ( ihandle -- phandle )
ihandle>phandle ;
: package-to-path ( phandle buf len -- len' )
2>r node>path 2r> string-to-buffer ;
: instance-to-path ( ihandle buf len -- len' )
2>r instance>path 2r> string-to-buffer ;
: instance-to-interposed-path ( ihandle buf len -- len' )
2>r instance>qpath 2r> string-to-buffer ;
: call-method ( str ihandle arg ... arg -- result return ... return )
nargs flip-stack zcount
debug-client-interface? IF
." ci: call-method " 2dup type cr
THEN
rot ['] $call-method CATCH
nrets 0= IF drop ELSE \ if called with 0 return args do not return the catch result
dup IF nrets 1 ?DO -444 LOOP THEN
nrets flip-stack 
THEN
;
: test-method ( phandle str -- missing? )
zcount
debug-client-interface? IF
." ci: test-method " 2dup type cr
THEN
rot find-method dup IF nip THEN 0=
;
: milliseconds  milliseconds ;
: start-cpu ( phandle addr r3 -- )
>r >r 
s" reg" rot get-property 0= IF drop l@ 
ELSE true ABORT" start-cpu called with invalid phandle" THEN 
r> r> of-start-cpu drop
;
: quiesce  ( -- )
debug-client-interface? IF
." ci: quiesce" cr
THEN
quiesce
;
: boot  ( zstr -- )
zcount
debug-client-interface? IF
." ci: boot " 2dup type cr
THEN
" boot " 2swap $cat " boot-command" $setenv (nvupdate)
reset-all
;
: interpret ( ... zstr -- result ... )
zcount
debug-client-interface? IF
." ci: interpret " 2dup type cr
THEN
['] evaluate CATCH
;
: set-callback ( newfunc -- oldfunc )
client-callback @ swap client-callback ! ;
: fdt-fetch ( buf len -- ret )
fdt-flatten-tree    ( buf len dtb )
dup >r
>fdth_tsize l@      ( buf len size r: dtb )
2dup < IF
." ERROR: need " .d ." bytes, the buffer is " .d ." bytes only" cr
drop
-1
ELSE
nip r@ -rot move
0
THEN
r> fdt-flatten-tree-free
;
PREVIOUS DEFINITIONS
false value elf-claim?
0     value last-claim
0 VALUE cur-brk
: elf-claim-segment ( addr size -- errorcode )
2dup
elf-claim? IF
>r
here last-claim , to last-claim                \ Setup ptr to last claim
dup , r> dup , ( addr size )
0 ['] claim CATCH IF
." Memory for ELF file is already in use!" cr
true ABORT" Memory for ELF file already in use "
THEN
drop
ELSE
2drop
THEN
+ to cur-brk
0 
;
: elf-load-claim ( file-addr destaddr -- claim-list entry imagetype )
true to elf-claim?
0 to last-claim
dup -1 = IF             \ If destaddr == -1 then load to addr from ELF header
drop ['] elf-load-file CATCH IF false to elf-claim? ABORT THEN
ELSE
['] elf-load-file-to-addr CATCH IF false to elf-claim? ABORT THEN
THEN
>r
last-claim swap
false to elf-claim?
r>
;
: elf-release ( claim-list -- )
BEGIN
dup cell+                   ( claim-list claim-list-addr )
dup @ swap cell+ @          ( claim-list claim-list-addr claim-list-sz )
release                     ( claim-list )
@ dup 0=                    ( Next-element )
UNTIL
drop
;
CREATE bootdevice 2 cells allot bootdevice 2 cells erase
CREATE bootargs 2 cells allot bootargs 2 cells erase
CREATE load-list 2 cells allot load-list 2 cells erase
: start-elf ( arg len entry -- )
msr@ 7fffffffffffffff and 2000 or ciregs >srr1 ! call-client
;
: start-elf64 ( arg len entry r2 -- )
msr@ 2000 or ciregs >srr1 !
ciregs >r2  !
call-client \ entry point is pointer to .opd
;
: set-bootpath
s" disk" find-alias
dup IF ELSE drop s" boot-device" evaluate find-alias THEN
dup IF strdup ELSE 0 THEN
encode-string s" bootpath" set-chosen
;
: set-netbootpath
s" net" find-alias
?dup IF strdup encode-string s" bootpath" set-chosen THEN
;
: set-bootargs
skipws 0 parse dup 0= IF
2drop s" boot-file" evaluate
THEN
encode-string s" bootargs" set-chosen
;
: .(client-exec) ( arg len -- rc )
s" snk" romfs-lookup 0<> IF
paflof-start f00000 +
elf-load-file-to-addr drop \ FIXME - check this for LE, currently its BE only
dup @ swap 8 + @         \ populate entry r2
start-elf64 client-data
ELSE
2drop false
THEN
;
' .(client-exec) to (client-exec)
: .client-exec ( arg len -- rc ) set-bootargs (client-exec) ;
' .client-exec to client-exec
: ping  ( "{device-path:[device-args,]server-ip,[client-ip[\nn]],[gateway-ip][,timeout]}" -- )
my-self >r current-node @ >r  \ Save my-self
(parse-line) open-dev dup  IF
dup to my-self dup ihandle>phandle set-node
dup
s" ping" rot ['] $call-method CATCH  IF
cr
." Not a pingable device"
cr 3drop
THEN
swap close-dev
ELSE
cr
." Usage: ping device-path:[device-args,]server-ip,[client-ip[\nn]],[gateway-ip][,timeout]"
cr drop
THEN
r> set-node r> to my-self  \ Restore my-self
;
8a8 cp
CREATE version-str 10 ALLOT
0 value temp-ptr
: dump-display-write
s" screen" find-alias  IF
drop terminal-write drop
ELSE
s" vsterm" find-alias  IF
drop type
THEN
THEN
;
: dump-display-buffer
disp-ptr to temp-ptr
" SLOF **********************************************************************" dump-display-write
cr
version-str get-print-version
version-str @                   \ start
version-str 8 + @               \ end
over - dump-display-write
" Press 's' to enter Open Firmware." dump-display-write
s" /ibm,vtpm" find-node IF
"  Press 't' to enter TPM menu." dump-display-write
THEN
cr cr
temp-ptr disp-size > IF
temp-ptr disp-size MOD
dup
prevga-disp-buf + swap disp-size swap - dump-display-write
temp-ptr disp-size MOD
prevga-disp-buf swap 1 - dump-display-write
ELSE
prevga-disp-buf temp-ptr dump-display-write
THEN
;
: enable-framebuffer-output  ( -- )
s" screen" find-alias ?dup  IF
open-dev close-node
false to store-prevga?
s" display-emit" $find  IF
to emit
dump-display-buffer
ELSE
2drop
THEN
THEN
;
enable-framebuffer-output
8b0 cp
usb-scan
8c0 cp
romfs-base 400000 0 ' claim CATCH IF ." claim failed!" cr 2drop THEN drop
8d0 cp
: get-stdout-path ( - [ prop len ] success )
s" stdout-path" get-chosen ?dup NOT IF
s" linux,stdout-path" get-chosen ?dup NOT IF
FALSE
THEN
THEN
;
: set-default-console
get-stdout-path IF
decode-string
." Using default console: " 2dup type cr
io
2drop
ELSE
." No console specified "
" screen" find-alias dup IF nip THEN
" keyboard" find-alias dup IF nip THEN
AND IF
." using screen "
s" direct-serial?" evaluate IF
." & hvterm"
s" hvterm" input
ELSE
." & keyboard"
s" keyboard" input
THEN
cr
s" screen" output
ELSE
" hvterm" find-alias IF
drop
." using hvterm" cr
" hvterm" io
ELSE
" vsterm" find-alias IF
drop
." using vsterm" cr
" vsterm" io
false to store-prevga?
dump-display-buffer
ELSE
" /openprom" find-node ?dup IF
set-node
." and no default found, creating dev-null" cr
" dev-null.fs" included
" devnull-console" io
0 set-node
THEN
THEN
THEN
THEN
THEN
s" input-device" evaluate dup IF
." User selected input-device console: " 2dup type cr
input
ELSE
2drop
THEN
s" output-device" evaluate dup IF
." User selected output-device console: " 2dup type cr
output
ELSE
2drop
THEN
;
set-default-console
8e0 cp
0 VALUE direct-ram-boot-base
0 VALUE direct-ram-boot-size
: (boot-ram)
direct-ram-boot-size 0<> IF
." Booting from memory..." cr
s" go-args 2@ " evaluate
direct-ram-boot-base 0
s" true state-valid ! " evaluate
s" disable-watchdog go-64" evaluate
THEN
;
8e8 cp
: check-boot-from-ram
s" qemu,boot-kernel" get-chosen IF
decode-int -rot decode-int -rot ( n1 n2 p s )
decode-int -rot decode-int -rot ( n1 n2 n3 n4 p s )
2drop
swap 20 << or to direct-ram-boot-size
swap 20 << or to direct-ram-boot-base
." Detected RAM kernel at " direct-ram-boot-base .
." (" direct-ram-boot-size . ." bytes) " cr
s" boot-command" $create " (boot-ram)" env-string
THEN
;
check-boot-from-ram
8ff cp
: (boot) ( -- )
s" Executing following boot-command: "
boot-command $cat nvramlog-write-string-cr
s" boot-command" evaluate      \ get boot command
['] evaluate catch ?dup IF     \ and execute it
." boot attempt returned: "
abort"-str @ count type cr
nip nip                     \ drop string from 1st evaluate
throw
THEN
;
: (function-key) ( -- n )
key? IF
key CASE
50  OF 1 ENDOF
7e  OF 1 ENDOF
dup OF 0 ENDOF
ENDCASE
THEN
;
: (esc-sequence) ( -- n )
key? IF
key CASE
4f  OF (function-key) ENDOF
5b  OF
key key (function-key) ENDOF
dup OF 0 ENDOF
ENDCASE
THEN
;
: (s-pressed) ( -- )
s" An 's' has been pressed. Entering Open Firmware Prompt"
nvramlog-write-string-cr
;
: (t-pressed) ( -- )
s" /ibm,vtpm" find-node ?dup IF
s" vtpm-menu" rot $call-static
THEN
;
: (boot?) ( -- )
s" /ibm,vtpm" find-node ?dup IF
s" leave-firmware" rot $call-static
THEN
of-prompt? not auto-boot? and IF
(boot)
THEN
;
TRUE VALUE use-load-watchdog?
: boot-menu-start
boot-menu ?dup IF
s" boot " 2swap $cat
['] evaluate catch ?dup IF
." boot attempt returned: "
abort"-str @ count type cr
throw
THEN
0 0 load-list 2!
THEN
;
: boot-menu-enabled? ( -- true|false )
s" qemu,boot-menu" get-chosen IF
decode-int 1 = IF
2drop TRUE EXIT
THEN
2drop
THEN
FALSE
;
: f12-pressed?
34 = >r 32 = r> and IF
TRUE
ELSE
FALSE
THEN
;
: start-it ( -- )
key? IF
key CASE
[char] s  OF (s-pressed) ENDOF
[char] t  OF (t-pressed) (boot?) ENDOF
1b        OF
(esc-sequence) CASE
1   OF
console-clean-fifo
f12-pressed? boot-menu-enabled? and IF
boot-menu-start
ELSE
(boot?)
THEN
ENDOF
dup OF (boot?) ENDOF
ENDCASE
ENDOF
dup OF (boot?) ENDOF
ENDCASE
ELSE
(boot?)
THEN
disable-watchdog  FALSE to use-load-watchdog?
.banner
;
."      "   \ Clear last checkpoint
0 VALUE load-size
0 VALUE go-entry
VARIABLE state-valid false state-valid !
CREATE go-args 2 cells allot go-args 2 cells erase
4000 CONSTANT bootdev-size
0 VALUE bootdev-buf
: alloc-bootdev-buf ( -- )
bootdev-size alloc-mem ?dup 0= ABORT" Unable to allocate bootdev buffer!"
dup bootdev-size erase
to bootdev-buf
;
: free-bootdev-buf ( -- )
bootdev-buf bootdev-size free-mem
0 to bootdev-buf
;
: bootdev-string-cat ( addr1 len1 addr2 len2 -- addr1 len1+len2 )
dup 3 pick + bootdev-size > ABORT" bootdev size too big!"
string-cat
;
: $bootargs
bootargs 2@ ?dup IF
ELSE s" diagnostic-mode?" evaluate and IF s" diag-file" evaluate
ELSE s" boot-file" evaluate THEN THEN
;
: $bootdev ( -- device-name len )
alloc-bootdev-buf
bootdevice 2@ ?dup IF
swap bootdev-buf 2 pick move
bootdev-buf swap s"  " bootdev-string-cat
ELSE
drop bootdev-buf 0
THEN
s" diagnostic-mode?" evaluate IF
s" diag-device" evaluate
ELSE
s" boot-device" evaluate
THEN
bootdev-string-cat \ concatenate both
strdup
free-bootdev-buf
?dup 0= IF
disable-watchdog
drop true ABORT" No boot device!"
THEN
;
: set-boot-args ( str len -- ) dup IF strdup ELSE nip dup THEN bootargs 2! ;
: (set-boot-device) ( str len -- )
?dup IF 1+ strdup 1- ELSE drop 0 0 THEN bootdevice 2!
;
' (set-boot-device) to set-boot-device
: (add-boot-device) ( str len -- )	\ Concatenate " str" to "bootdevice"
bootdevice 2@ ?dup IF
alloc-bootdev-buf
swap bootdev-buf 2 pick move
bootdev-buf swap s"  " bootdev-string-cat
2swap bootdev-string-cat
ELSE drop THEN
set-boot-device
bootdev-buf 0 <> IF free-bootdev-buf THEN
;
' (add-boot-device) to add-boot-device
0 value claim-list
: no-go ( -- ) -64 boot-exception-handler ABORT ;
defer go ( -- )
: go-32 ( -- )
state-valid @ IF
0 ciregs >r3 ! 0 ciregs >r4 !
go-args 2@ go-entry start-elf client-data
claim-list elf-release 0 to claim-list
THEN
-6d boot-exception-handler ABORT
;
: go-64 ( args len entry r2 -- )
0 ciregs >r3 ! 0 ciregs >r4 !
start-elf64 client-data
claim-list elf-release 0 to claim-list
;
: set-le ( -- )
1 ciregs >r13 !
;
: set-be ( -- )
0 ciregs >r13 !
;
: go-64-be ( -- )
state-valid @ IF
set-be
go-args 2@
go-entry @
go-entry 8 + @
go-64
THEN
-6d boot-exception-handler ABORT
;
: go-32-be
set-be
go-32
;
: go-32-lev1
set-le
go-32
;
: go-64-lev1
state-valid @ IF
go-args 2@
go-entry @ xbflip
go-entry 8 + @ xbflip
set-le
go-64
THEN
-6d boot-exception-handler ABORT
;
: go-64-lev2
state-valid @ IF
go-args 2@
go-entry 0
set-le
go-64
THEN
-6d boot-exception-handler ABORT
;
: load-elf-init ( arg len file-addr -- success )
false state-valid !                            \ Not valid anymore ...
claim-list IF                                    \ Release claimed mem
claim-list elf-release 0 to claim-list        \ from last load
THEN
true swap -1                       ( arg len true file-addr -1 )
elf-load-claim                     ( arg len true claim-list entry elftype )
CASE
1  OF ['] go-32-be   ENDOF           ( arg len true claim-list entry go )
2  OF ['] go-64-be   ENDOF           ( arg len true claim-list entry go )
3  OF ['] go-64-lev1 ENDOF           ( arg len true claim-list entry go )
4  OF ['] go-64-lev2 ENDOF           ( arg len true claim-list entry go )
5  OF ['] go-32-lev1 ENDOF           ( arg len true claim-list entry go )
dup OF ['] no-go to go
2drop 3drop false EXIT   ENDOF                   ( false )
ENDCASE
to go to go-entry to claim-list
dup state-valid ! -rot
2 pick IF
go-args 2!
ELSE
2drop
THEN
;
: init-program ( -- )
$bootargs get-load-base ['] load-elf-init CATCH ?dup IF
boot-exception-handler
2drop 2drop false          \ Could not claim
ELSE IF
0 ciregs 2dup >r3 ! >r4 !  \ Valid (ELF ) Image
THEN
THEN
;
: do-load ( devstr len -- img-size )	\ Device method wrapper
use-load-watchdog? IF
4ec set-watchdog
THEN
2dup " HALT" str= IF 2drop 0 EXIT THEN
my-self >r current-node @ >r         \ Save my-self
." Trying to load: " $bootargs type ."  from: " 2dup type ."  ... "
2dup open-dev dup IF
dup to my-self
dup ihandle>phandle set-node
-rot                              ( ihandle devstr len )
encode-string s" bootpath" set-chosen
$bootargs encode-string s" bootargs" set-chosen
get-load-base s" load" 3 pick ['] $call-method CATCH IF
-67 boot-exception-handler 3drop drop false
ELSE
dup 0> IF
init-program
ELSE
false state-valid !
drop 0                                     \ Could not load
THEN
THEN
swap close-dev device-end dup to load-size
ELSE -68 boot-exception-handler 3drop false THEN
r> set-node r> to my-self                           \ Restore my-self
;
: parse-load ( "{devlist}" -- success )	\ Parse-execute boot-device list
cr BEGIN parse-word dup WHILE
de-alias do-load dup 0< IF drop 0 THEN IF
state-valid @ IF ."   Successfully loaded" cr THEN
true 0d parse strdup load-list 2! EXIT
THEN
REPEAT 2drop 0 0 load-list 2! false
;
: load ( "{params}<eol>"} -- success )	\ Client interface to load
parse-word 0d parse -leading 2swap ?dup IF
de-alias
set-boot-device
ELSE
drop
THEN
set-boot-args
save-source  -1 to source-id
$bootdev dup #ib ! span ! to ib
0 >in !
['] parse-load catch restore-source throw
;
: load-next ( -- success )	\ Continue after go failed
load-list 2@ ?dup IF
save-source  -1 to source-id
dup #ib ! span ! to ib
0 >in !
['] parse-load catch restore-source throw
ELSE drop false THEN
;
: noload false ;
' no-go to go
: (go-and-catch)  ( -- )
get-load-base c@ 5c =  get-load-base 1+ c@ 20 = AND IF
load-size alloc-mem            ( allocated-addr )
?dup 0= IF ." alloc-mem failed." cr EXIT THEN
load-size >r >r                ( R: allocate-addr load-size )
get-load-base r@ load-size move    \ Move away from load-base
r@ load-size evaluate          \ Run the script
r> r> free-mem
EXIT
THEN
['] go behavior CATCH IF -69 boot-exception-handler THEN
;
read-bootlist
: boot
load 0= IF -65 boot-exception-handler EXIT THEN
disable-watchdog (go-and-catch)
BEGIN load-next WHILE
disable-watchdog (go-and-catch)
REPEAT
;
: load load 0= IF -65 boot-exception-handler THEN ;
cr .(   Welcome to Open Firmware)
cr
cr .(   Copyright (c) char ) emit .(  2004, 2017 IBM Corporation All rights reserved.)
cr .(   This program and the accompanying materials are made available)
cr .(   under the terms of the BSD License available at)
cr .(   http://www.opensource.org/licenses/bsd-license.php)
cr cr
' start-it CATCH drop
: boot
boot
.banner
;
cr ." Ready!"
õXõ`õhõxõõ˜õ°õÀõÐõàõðõðööö ö õHÑàÑ ÑÑhÑ°Ñ8јÑPÑÈø˜Ò¸ÒXÒÒpÒÐÒ@Ò Ò(ûøÔøÔ°Ô8ÔhÔPÓðԀüüüü ü8ò8üH
üXühü€ü˜ ÿ° ÿÈÿØÿøyz8{Xxˆ&˜'¨(¸ÈØèøvwx(|8@P`p^ÿÿÿÿÿÿc‚Scÿÿÿÿÿÿÿÿÿÿÿÿˆå¨ åØ0˜æ 
@ æ8 ¨'  °(@0À)€@Ðÿÿÿÿ¿ðPÂÀ@PGNUµ;MN¨QS½v?’sŸ˜ËÖþÔGCC: (Ubuntu 10.3.0-1ubuntu1) 10.3.0ÄéøPë8à¨@#ÙHÜ1ÇØEæ˜@LÍÀ¤_Û¸oÄ`Kdvá@´„äÐhϸÀÂé `œèðD¥u¨³ÌlÌÖ¨„ÚÄÀÔß׀ìýÜ``ÙØdvì$ÅP€.Û@8ŀFOP RÉX,fwhwΰÔ€ç@ðÚéÈdˆÖHŒšܨD¥—ø¬ʨ,¾Æ( Ïãh¬Ùâ0œéä@œ$ÈPúÏ(ø
טÀË°Ô+Å8l7˜@ÖLbǐTmӐ¼Æp€•Êl¦Ü·È0ÄÐ`”ÑÍxÜáç(xèʤøÙÀýã˜4¸ð !é8„&ât3ÐHÔIãàjÏrÎhȁçÐ$‰ÛXš֘µrŒ«è`„²Æ@€ÉÍ0ÙèØœãÌИòÚ°pÌ(Ô"ʐH2Ïp|?Î80PÜÀH_è¨grȘt€â¨D‰݀„”ÖÀÈ¥ý€e·ÜH„ÃĨäÊɸDàÍDðËPpژÐä(-—˜@Ç0 [È°ˆqàÈ\}æ8ÈÊ0ˆ„àhXëÄØÔ›ÙL¥˜,¸ÍHLÌÚÈÜÅh€æç¸@ïO úܐè¸ÜØ$q˜à€ø/sd<ýeLÎøtTá¸t_ä¸D}×hH“Óxh¤ÅȀ³sÂ爼Ê×Pá͐°ðÖxÇH ˜()—¼©È8ùÄxÀ=Ð0ècéLOYshdáXƒæPXŠÞè(Âã€0šÖ0˜«É@TÁ×°Í娌Ò؈lßü°eíØèôöÐx”ÏX¨Ç`D"Íì1âPIáX<bäXÔtÞp(€Ú8̐ÇاĶæø4Úè04½؀ÌààdOÄðèØÖ`TéæÈ ñÌèX	Ìp€	Ó¨ø	!æà(	)˘Ô	>çp	IÕ¸Œ	ZãP€	iΘ(	sˀø	‡ÕИ	—Ä	£Õ ˜	³˜Cß`	»Å°Œ	ÉØXì	ÖÙðt	åß0¸	ùßt
	Îà$
ؼ
vd
*çX¤
1—
=Òè8
OÉÐ
aw }á(
tÅ À
€âHÀ
ŽÚP
–Éè¬
ªßðì
¶Þ@¤
½Æ¸
ÍÐØP
ãÈ h
èÈøì
üÉpìÆЀ*Ì@\<ÞÐLHà°TPÓ`ìa uð€~Á–€†ç`à€™× ­ÍØtÄåÙèHßËàˆñØ  ÿÄ	АÌÓÀä#Ø0ßx\:®0lé°OÝh´ZàPTiËhX}ÂÐ…É”
2—™—T{ِŒ¥Ù´®v@»å0Ð怀×Í`tæá  ôÊHÈÿሀ
Þ(T
:Шœèd
G–¼
RÙ¨d
ZØ(<
hÏè´
vÌX¸
‹ڀÄ
žŒ
°ÐÀô
¾H²
ÑÖŒ
ãÑø8
õ–ÐÐð\Î L+ݘl1ÞXCáРQÚø4\wlË8¬}ÓšvŒ¤Ú $¬Ý»ÇðÉÕ”×ßØèäˆúåØ΀¨ÐÄOp *Ì à=å`àLç $T¼ˆ^ÎÌtÛè…×È”vä¢Æ訯à˜t»åTÏØ@èÝÏЀêwDûáp
ä#åHt9ͨIÍð_áèÀküzÄ…Èà”—Õ茨ļ×8„ÓýèeãÖØØï—Ô㰄ÊÀÀ(ËÈT:Õ(8LãÈ(\äp$lÜxìvÜðÜ0<Œæ°d“ÝP`œçè$¤ÎÈŒ¬ØpÐºË dË–˜ÜՈ0ç Èhõæ Èü×øü
Åà|!æhH(Ɉ”<â`4Eãø@WÜxpÏ —l•Ǩh¨É à·ßÀ¤ÈÄ0<ÑÇxlää TÛpψ˜ÅøŒ´ÄHT*s¤3ÇðI–´TÚàbéà|k$|Ù0”†ËøÜ	Äèx$ Ål®Öð¹֐.LC13.LC3.LC2.patch_broken_sc1e1k_mac_setupSLOF_set_chosen_intstrcpyvirtio_serial_initset_ipv4_routerenginehandle_dhcpv6tpm20_menuusb_hcd_initvsprintfio_printhex16virtio_get_host_featuresget_partitionrecvincrease_nvram_partition_sizehandle_arpget_arg_ptrbootmsg_warningset_timersend_ipv4get_sec_ticksstderr_dataelf_get_file_size32bootmsg_nvupdatep9_clunkmemmovenvram_write_qwordhandle_udphv_casvirtio_vring_sizeSLOF_dma_map_outtpm_startneighbor_createtpm_gpt_set_lba1usb_devpool_getreset_nvramvirtio_queue_term_vqSLOF_usleephv_rtas_broken_sc1_sizevirtioblk_shutdownSLOF_resetusb_key_availableSLOF_pci_config_read8check_broken_sc1get_ipv4_netmaskSLOF_bm_freeusb_hid_initvirtionet_closememcpyelf_forth_claimpingtpm_leave_firmwarethe_system_stackputsneighbor_addusb_dev_populate_pipetpm_hash_log_extend_event_bufferp9_statp9_transactiontolowerset_ipv4_addressnvram_read_dwordmallocSLOF_pci_config_read32virtioscsi_initvsnprintfvirtio_9p_initset_mac_addressvirtio_negotiate_guest_featuresvirtio_setup_vdusb_put_pipep9_reg_transporthandle_udp_dunstrtoul_slof_textelf_load_filebootmenuhandle_dnsget_partition_fskeycodes_shift_UShandle_ipv4socketelf_byteswap_header64virtioscsi_sendvirtio_desc_addrpxelinux_load_parse_cfgtpm_measure_bcv_mbrhv_logical_ci_loadSLOF_encode_bootp_responseelf_load_file_to_addrstr_to_ipv6sha512ip6_create_prefix_infoe1k_closehv_rtas_broken_sc1virtioscsi_shutdownget_mac_addressget_timerisxdigitstdin_datapong_ipv4strtolfill_udphdr.call_cip6_prefix2addrwriteLogBytekeycodes_alt_GRp9_readrouter_addtpm_driver_set_failure_reasonclear_nvram_partitionusb_hid_kbd_exitSLOF_alloc_memc_romfs_lookupstrrchrdelete_nvram_partitionvirtionet_readfree_nvram_bufferSLOF_encode_dhcp_responsehv_rtas_sizehv_logical_ci_storeusb_transfer_bulk_start_OFio_putchardhcpv6_generate_transaction_idstrcathandle_tftp_dunnvram_read_qwordelf_byteswap_header32nvram_debugsha1libveth_readkeycodes_ctrle1k_openusb_hid_exitusb_get_pipeSLOF_get_propertyvirtio_9p_loadipv6_get_default_routersend_router_solicitationtpm_gpt_add_entryhandle_dhcpstrtoip_netmaskSLOF_bm_allocator_initepapr_ima_sizestrstrSLOF_dma_allocipv6_to_strget_nvram_bufferstrncmpvirtio_9p_shutdownvirtioblk_initusb_read_keybstrncpyvirtio_queue_init_vqstrcasecmpnvram_write_bytetpm_is_workingp9_attachvirtio_queue_notifynvram_read_wordepapr_magicnvram_read_bytehv_rtasSLOF_dma_freelibveth_openget_args_counttftp_get_error_infoparse_tftp_argsp9_opennvram_add_envbootmsg_cpmemcmp.hv_hascharusb_ehci_registerelf_get_eflags_64bootmsg_checklevelSLOF_msleepfind_neighborstrtoipelf_get_file_size64handle_ipv6dhcpv4SLOF_dma_map_inusb_msc_resetrecoverysbrkelf_load_segments32elf_load_segments64SLOF_translate_my_addressvirtio_get_confighandle_tftpip6_cmpusb_hid_kbd_initthe_exception_framethe_heapsend_ipmemsetfill_ip6hdrnew_nvram_partitionvirtio_serial_shutdownspapr_vtpm_get_errorsrandvirtio_get_statuslibveth_writefdt_startusb_msc_initusb_hub_init.call_clientsend_ipv6_binary_OF_fsi_startdns_get_ipunknown_prefixvirtio_reset_devicethe_memelf_get_base_addr32hv_send_crqe1k_readGET_WRNG_LVLspapr_vtpm_set_errorstrcmpvirtionet_openhandle_icmpv6fast_rfillsend_neighbour_solicitationdhcpv4_generate_transaction_idusb_msc_exithv_putcharnetloadnvram_del_envusb_send_ctrl__virtio_read_configpxelinux_parse_cfgprint_version_endusb_msc_reset_binary_OF_fsi_endnvram_write_dwordusb_ohci_registerhv_getcharusb_setup_new_devicevirtio_serial_hascharbootpdhcp_send_releaserouter_createsend_etherbootmsg_debugcpvirtio_free_descusb_slof_populate_new_deviceprint_msgargncpyhandle_tcp_dunSLOF_bm_allocusb3_dev_initget_ipv6_addresstpm_measure_scrtmsha256p9_versionusb_transfer_ctrlstdout_datavirtioblk_transferspapr_transmitisdigitip6_statevirtio_serial_getcharset_ipv4_netmaskget_nvram_sizebootmsg_errorwrite_mm_logip6addr_addspapr_vtpm_finalizenvram_set_envusb_hcd_exitbootmsg_setlevelis_ra_receivedtpm_add_event_separatorsspapr_is_vtpm_presentvirtionet_writevirtio_serial_putcharfind_router_slof_text_endromfs_baseelf_get_file_sizenvram_write_word.client_entry_pointnew_nvram_partition_fskeycodes_std_USerase_nvramhv_logical_memoptpm_set_log_parametersvirtio_get_qsizevirtio_set_statususb_xhci_registertpm_get_logsizetpm_measure_gptping_ipv4handle_tcpfill_iphdrstrlendns_inittoupperp9_walklibveth_closevirtio_fill_descget_print_bannernvram_initprint_versionsha384nvram_get_envSLOF_alloc_mem_alignedstrchrelf_get_base_addr64ndp_inittpm_2hash_ext_logget_default_ipv4_netmaskusb_hcd_registerhv_send_logical_lanSLOF_get_vtpm_unitelf_relocate64set_ipv6_addressasm_coutSLOF_get_keystroketpm_driver_get_failure_reasonfill_ethhdrusb_poll_intrSLOF_free_memio_printSLOF_set_chosen_byteshv_genericreceive_ethervfprintfthe_client_framee1k_writevirtio_set_guest_featuresSLOF_GetTimerwipe_nvramnvramlog_printfää33··&¤*¤:X>XJXNXR2V2\	
&Ù&A, *.969Hg,üy
8Ž
n2r0220"022,60,>22ðB02ðZ22èj@2ènA2rA0Î22Ò21`Ö02Ú01`î20ž21€¦01€ª21`²01`	:
	<
	„£
20è<
÷
¨a
äo
N
\
”¬
äP
L
¨
ä4
­
\Õ
˜<
Ì)
S
(8
>32B30Jn2Nn0Œd
àj
J
X(
¸:
ˆ
0e
|ˆ
¬e
øˆ
(e
tˆ
¤e
ðd
0ñ
pd
¸d
èð
	
dþ
ÌH
 PÜ
 |D
!xù
* M
*ìM
+,.
2xT
2ôE
3,@
3x 
3¼-
3à
4
4H³
4˜d
4Ü-
5?
5T}
5„]
5Ì;
5ü@
6(’
6X+
6„Z
6À?
7 ÿ
7€

7äh
8$ó
8`m
8”™
8øã
9D—
9€H
9ؼ
:¼$
;TK
;”ƒ
;ð~
<„)
<ü
=Á
>O
>(D
>d•
>ˆl
>¬0
>ø
?p7
?Ð\
@8
@œ&
@Ø
A5
AP²
Aˆ“
A¸J
Aì¶
B ¸
BB>2BF>0Bpg
B¦>2Bª>0BÈY
C"
C@Ç
C˜+
Cä
D$%
Dp
D¨Â
E‹
E\
Eü
EÄå
Eøæ
F,6
F`®
F”š
FÈ;
G*
G8
G\>
Gہ
G¤
GÐ
H"
HP0
H„ß
H°

Hü/
IH„
Ib 2If 0Ij2Ir0ItŒ
Jr‡2Jv‡0J~¹2J‚¹0Q$F
Q4F
RV2ƒRZ0ƒRn2(Rr0(R
R¤
R¬D
RÀ
RÌQ
RìD
S@Ž
SdŽ
Sž20S 
S¦00S´
S¼D
SÐ
T
T28T D
T.08T8
TH
TPD
Td
Tt
TÀ
Tâ2@Tæ@@Tê2Tî@Tò2Tö0U"2U*0U’2Uš0U¤D
U¸
UÈ
UÖ2pUæ0pUè
Uþ2 V0 V
V(
V22ÐV4D
VB0ÐVL
V\
VdD
Vx
Vˆ
V 
V´
VÐ=
W22xW:0xW<B
WJ2HWR0HWTB
Wb2¨Wj0¨WlB
W‚2àWŠ0àWŒB
WÖ2WÚ0X
X"2XX$
X.0XX8
X@D
XT
X¶2Xº0Xð
Y2XY
Y0XY
Y D
Y4
Y¾2`YÒ0`ZD
Z
Z~2xZ‚0xZŒD
Z 
Z´
Zö2xZþ0x[D
[
[,
[DD
[X
[l
[¶2ˆ[¾0ˆ[Ä
[ÐD
[ä
\"2x\*0x\4D
\H
\\
\j2 \v0 \¢2x\¦0x\ª2 \®0 \¸D
\Ì
\à
]F2]N0]T
]`D
]t
]ˆ
]Î2 ]Ø
]â0 ]ð
]üD
^
^V2°^^0°^d
^pD
^„
^˜
^Þ2°^æ0°^ô
_D
_
_(
_n2À_t
_~0À_Œ
_˜D
_¬
_Ä
_ÐD
_ä
_ø
`^2À`h
`r0À`€
`ŒD
` 
`ø
a
2Ða
a0Ða(
a4D
aH
a\
a´
aÆ2àaÌ
aÖ0àaä
aðD
b
bF2ðbN0ðbT
b`D
bt
bˆ
bÆ2bÎ0bÔ
bàD
bô
c
cF2cN0cT
c`D
ct
cˆ
cÎ2 cÖ0 cØ
cì
cøD
d
d^20df00dh
d|
dˆD
dœ
dî2@dö0@dø
e
eD
e,
ev2Pe~0Pe„
eD
e¤
e¸
f
f2hf 
f*0hf8
fDD
fX
f®2xf¶0xf¼
fÊ2ˆfÌD
fÚ0ˆfä
fø
gD
g
g$D
g8
g’2˜gž0˜g 
g¶2ˆg¸
gÆ0ˆgÈD
gÜ
gð
güD
h
hD
h0
hj2¨hn0¨hpc
hŠ2¸hŽ0¸hc
hÔ
hâ2ÈhäD
hò0Èhü
i
iD
i0
i<D
iP
id
i€
iœ
iþ2àj0àjD
j 
j4
jn2èjr0èj|D
j
jÎ2øjÒ0øjÜD
jð
k
k^2kj0kn2$Àkv2@kz2(k†0$ÀkŠ0@k’0(k 
kª28k®08k°
l
lT
ld
lr2ˆlv0ˆlx
m4€
mdÜ
pþ2q0q
q22¡ q:0¡ q>2 qB0 q´K
rTK
s4K
s¸Ž
sìŽ
tŽ
t$Ž
t@Ž
t\Ž
txŽ
t”Ž
t°Ž
t̎
tèŽ
uŽ
u Ž
u<Ž
uXŽ
utŽ
uŽ
vpŽ
vx
v€Ž
v Ž
v¨Ž
v°Ž
v¸
vÀŽ
vÈb
vЎ
v؎
vè
vðô
vüwô
ww,ô
wø`
x”
x 
€yÒ
y`Ó
y|Æ
z(
€zDR
z`Ó
zxY
zÄï
zàÒ
{$Æ
|R
|0`
|@”
|tï
|øÌ
}!
~($
~HÜ
~â2Ø~æ0Ø~è
„h$
„„Ü
…"2…&0…(
†V2x†Z2X†j0x†n0X‡¶2…Їº0…Јä
‰ä
Ž>2¨ŽH
ŽR0¨Ž`
ŽlD
Ž€
Ž”
x8
‘À8
‘à8
ӆ
–šL–žL–¢–¦–ÔÄ
–æ¡À–ê¡À—
¡À—¡À—*¡À—.¡À˜|M
˜œÔ
˜äÔ
™M
šd€
š|7
šÄ7
šÜ7
šô7
›7
›M
›PM
›h
`›t7
݆
`œ
`œ\
`œz2Àœ~0Àœ€
ž„Ï
Ÿ" 2Ÿ& 0Ÿ*2àŸ.0àŸ0Œ
ŸÔ*
¢4Ü
¢D<
¢lP
¢ÄÜ
£ÀP
£à<
¥@Ï
¥b2¥j0¥l
¥’2 ¥š0 ¥œ
¦p*
¦¬`
¦ì`
§Ü
§8<
§p*
©€
xª* 2ª. 0ª22@ª60@ª8Œ
ª\
xª„i
ªÔâ
ªì=
ªøâ
«4
x«b 2«f 0«j2p«r0p«tŒ
®üí
¯=
¯(=
¯LR
¯^20¯b2ˆ¯f00¯j0ˆ¯l
¯ˆ=
¯¸â
¯È°
¯ì=
¯ø
°Õ
°Hi
°x=
°„í
°ôÕ
±Õ
±Ž2¡À(±–0¡À(±š2¡À0±ž@¡À0±¢2¡À,±¦0¡À,±¾2¡À(±Ò0¡À(±ðI
²4I
²\I
²Üµ
²äk
³k
³,
³@
³T
³r2ø³z0ø³|
³Ò2¡À(³Ú0¡À(³â2¡À0³æ0¡À0³î2¡À,³ò0¡À,´2˜´0˜´B
´B 2´F 0´J2дN0дPŒ
´à<
µXI
µ€I
µüµ
¶p
¶„
·
·
·N2¡À8·V@¡À8·f0¡À8·„í
·”=
·°=
·Ìi
·Ü°
¸=
¸
2¸¸0¸¸U
¸\R
¸tâ
¸’2ถ2ˆ¸š0พ0ˆ¸ 
¸À=
¸ø=
¹í
¹2¡À8¹"0¡À8¹b2@¹j2¡À8¹n0¡À8¹r0@¹¼Õ
¹è
¹ø
º´
ºLG
ºj2€ºn0€ºp
º€#
º²2Hºº0Hº¼
ºÜF
ºôÀ
»H{
»f2È»j0È»l
»‚2˜»Š0˜»Œ
»œ#
»¬#
ȉ2hȐ0hȓ
¼
2°¼0°¼
½I
½8I
½¸µ
½Àk
½äk
¾
¾ 
¾ÈI
¾ìI
¿
¿4I
¿XI
¿ =
¿¼=
¿ÜR
¿üâ
À i
À0°
ÀD°
ÀX°
ÀŒ=
ÀÊ2ðÀÎ2ˆÀÒ0ðÀÖ0ˆÀØ
Àô=
Á(=
Á4í
Á|€
Á´=
ÁÀí
ÁÐ=
Â=
Â22¡À<ÂF0¡À<ÂHi
ÂX°
Âl°
Š2¡À<Ž0¡À<¦2¡À<ª0¡À<´€
ÃI
ÃDI
Ãæ2¡À@Ãî0¡À@Ä$=
Ä4µ
ÄTÕ
ÄtÕ
ÄÆ2(ÄÊ0(ÄÌ
Äü=
Å`
ÅLR
Åb2¡À<Åv0¡À<Åxâ
ņ0¡À@Ŗ2Ś0Ŝ
Å°=
Æ`
Æ@=
ÆLí
ÆZ2¡À<Æ^0¡À<Æp`
ƌ1
Æ 1
Æò2¡À@Æö0¡À@Ç.2¡À<Ç20¡À<ǐb
Ǩ=
Ƕ2¡À@Ǿ0¡À@ÇÎ0¡À@ÈLµ
Ⱦ2¡À<ÈÂ0¡À<É2PÉ0PÉ$
ÉÂ2¡ÀBÉÎ0¡ÀBÉâ2¡ÀLÉæ0¡ÀLÉê2¡À<Éî0¡À<ÉøÜ
ÊP
Êl
Êv2¡À<Êz0¡À<ʘI
ʼI
Ë0µ
Ë¢2€˦0€˨
Ìí
Ì,=
ÌH=
ÌhR
Ìz2ðÌ~2ˆ̂0ð̆0ˆ̈
̤=
ÌÜ°
Ìø€
ÍHI
ÍÚ2¡ÀXÍæ0¡ÀXÍè°
Î=
ÎDâ
ÎT°
În2 Îr0 Ît
ÎÈ=
ÎÜ1
Îð1
Îüí
ÏÔI
ÐHµ
ÐPk
Ðtk
Р
Ñ2ÐÑ
0ÐÑ
ÑhÜ
Ñz2¡ÀXÑ~0¡ÀXÑðb
Ò=
Ò2¡ÀXÒ0¡ÀXÒ*0¡ÀXÒ¬µ
Ó62¡ÀXÓ:0¡ÀXÓb2¡À`Óf@¡À`Ój2¡ÀhÓn@¡ÀhÓr2¡ÀpÓv@¡ÀpÓz2¡ÀxÓ~@¡ÀxÓ¦2¡ÀpÓ®@¡ÀpÓ°Ü
Óº2¡ÀxÓ¾@¡ÀxÓÈÜ
ÓÖ@¡ÀpÓÚ2¡À€Óæ@¡À€Ô
2¡À`Ô2¡À`Ô@¡À`Ô2¡ÀpÔ@¡ÀpÔ2¡À€Ô"@¡À€Ô*0¡À`ÕdÜ
Ռ¯
Ֆ2՞0ՠ
Õö2¡ÀpÕþ2¡ÀxÖ@¡ÀpÖ
2¡À€Ö2Ö0ÖÜ
Ö@¡ÀxÖ(Ü
Ö2@¡ÀpÖF@¡À€ÖN@¡À€ÖV@¡À€Ö^@¡À€Öf@¡À€Ön@¡À€Öv@¡À€ւ@¡À€֊@¡À€֌D
֖@¡À€Ö¦@¡À€Ö®@¡À€Ö°D
ÖÄ=
ÖÐD
ÖÚ@¡À€Öê@¡À€ÖìG
×"@¡Àx×J2(×N0(×T«
לD
׬D
×Ê2¡Àp×â@¡Àp×äÜ
×î2¡Àx×ò@¡Àx×üÜ
Ø@¡ÀpØ
2¡À€Ø@¡À€Ø&@¡À€Ø.@¡À€Ø6@¡À€Ø>@¡À€ØR@¡À€ØZ@¡À€Øb@¡À€Øj@¡À€Ør@¡À€Ø~@¡À€؀D
؊@¡À€ؒ@¡À€ئ@¡À€بD
ؼ=
ØÈD
ØÒ@¡À€Øâ@¡À€ØäD
Øî@¡À€Øö@¡À€Ù
@¡À€ÙD
Ù =
Ù,D
Ù6@¡À€ÙF@¡À€ÙN@¡À€ÙZ@¡À€ÙtG
ÙÎ2¡ÀpÙÞ@¡ÀpÙàÜ
Ùê2¡ÀxÙî@¡ÀxÙøÜ
Ú@¡ÀpÚ2¡À€Ú@¡À€Ú&@¡À€Ú.@¡À€Ú6@¡À€Ú>@¡À€ÚF@¡À€ÚN@¡À€ÚZ@¡À€Úr@¡À€ÚtG
Ú®2¡ÀpÚÆ@¡ÀpÚî2øÚøÜ
Û2¡ÀxÛ@¡ÀxÛ0øÛÜ
Û"@¡ÀpÛ&2¡À€Û6@¡À€Û>@¡À€ÛF@¡À€ÛN@¡À€ÛV@¡À€Û^@¡À€Ûf@¡À€Ûn@¡À€Ûv@¡À€Û~@¡À€ۆ@¡À€ێ@¡À€ۖ@¡À€Ü«
Ü2¡À€Ü@¡À€Ü2¡ÀpÜ"@¡ÀpÜ.2¡À`Ü60¡À`Üt=
Ü°D
ÜÊ2¡ÀpÜÎ@¡ÀpÜÜG
Üê2¡ÀxÜî@¡ÀxÞF2¡ÀpÞN2¡ÀxÞV@¡ÀpÞdÜ
Þn@¡ÀxÞxÜ
ނ@¡Àpކ2¡À€ޚ@¡À€Þ¢@¡À€Þª@¡À€Þ²@¡À€Þº@¡À€ÞÂ@¡À€ÞÊ@¡À€ÞÒ@¡À€ÞÞ@¡À€Þæ@¡À€Þî@¡À€Þö@¡À€ÞøG
ß@¡Àxßv2¡Àp߆@¡ÀpߘÜ
ߢ2¡Àxߦ@¡Àxß°Ü
ߺ@¡Àpß¾2¡À€ßÂ@¡À€ßÞ2¡À€ßò@¡À€ßú@¡À€à@¡À€à
@¡À€à@¡À€à@¡À€à&@¡À€à.@¡À€à6@¡À€àF@¡À€àHG
àV2¡ÀxàZ@¡Àxàx=
àò2¡Àpàú2¡Àxá@¡ÀpáÜ
á@¡ÀxáÜ
á&@¡Àpá*2¡À€áF@¡À€áN@¡À€áV@¡À€á^@¡À€áf@¡À€án@¡À€áv@¡À€á‚@¡À€áŠ@¡À€áŒG
áš@¡Àxáö2¡Àˆáú2¡Àˆáþ@¡Àˆâ0¡Àˆâ2¡Àˆâ"@¡Àˆâ$Ü
âT€
âº2¡Àˆâ¾@¡Àˆâæ2¡Àˆâê@¡Àˆã¢2pã¦20ãª0pã®00ã°
å2¡Àå@¡ÀåB2¡ÀåJ@¡Àåf2@åj0@åp
åš2¡Àåž@¡Àæ&2Hæ*0Hæ0
æ¦2Hæª0Hæ°
çB2€çF20çJ0€çN00çP
çà
è‚2€è†20èŠ0€èŽ00è
é‚2é†20éŠ0éŽ00é
ê›
ê@›
êh›
ëØ
ë¨
ì€D
ìôT
íT
íò2€íö20íú0€íþ00î
îh
îp
îxÉ
îð›
ï
ïh
ïŒÉ
ï¸
ð
ð<§
ðp
ð„»
ðÈ
ðäÉ
ñr2¨ñv2Xñ~0¨ñ‚0Xñ„
ñ´=
ñØ»
òPÉ
òˆ*
ò˜»
ò´*
òÄ»
òÔ`
ó|Ü
ôœ§
ô¸Ï
ôÐÜ
ôäÜ
ôøÏ
öT§
ö„Ï
öŽ2Àö¦0Àöà
÷Ò28÷Ö2ø÷Ú08÷Þ0ø÷à
ø¨Ü
ùL*
ùd*
ùx»
útk
ú~2	8ú‚2^Àú†2	Púž0	8ú¢0^Àú¦0	Púôk
ûÔ
ü"2	ü*0	ü0
ü 
ýDÜ
ÿk
ÿ4k
ÿX

€ÿò2	hÿú0	hÿü
22P62	¸:0P>0	¸@
R2	ÐV0	ÐX
f2Pj2	àn0Pz0	à
¼Ð
Ò2	ˆÚ0	ˆà
¨§
ÀÏ
ÜÜ
ôÏ
k
8k
^2hb2
n0hr0
x
‚2
0†2
@Š0
0
ž0
@°
È
Þ2(â0(ä


€`*
x*
ˆ»
,Ï
|*
2¡À˜0¡À˜r2¡À˜v0¡À˜Ú2
HÞ0
Hà
ì€
Ü
4§
^2
ˆb0
ˆd
t»
„`
ÌÏ
øÉ
	2
	¢2
À	¦0
À	¨
	ܛ

Ü

Ü
É
ƒ
2É
2 00 
X/

x


Œ

¬

èÉ

"2
`&0
`(
Š2
ØŽ0
ؐ
¾2_@Â0_@ÄV
`Ü
φ
Ü
¨§
ÈÏ
º2¡Àœ¾0¡ÀœÊ0¡ÀœH*
X»
t*
„»
 *
°»
Ì*
Ü»
ì`
"2°&2x*0°.0x0
äk
k
xÜ
Àk
ðk
H
ˆ¢2˜ª0˜¬
Ò2ÀÖ2
Ú0ÀÞ0
à
ò2¸ú0¸ü
"2à*0à,
j2
 n0
 p
|€
†
ôk
Pk
Ӥ
¬Ï
¼§
ÔÏ
ìÜ
ۤ
˜Ï
°Ü
–2²0|É
ÈÉ
Ð/
ì


d
’2
8–0
8˜
º2
`¾0
`À
Î2
àÒ0
àÔ
è*
ø»
*
»
*2
¨.0
¨0
>2
xB0
xD
¨§
ØÏ
ðÜ
Ï
 k
 4k
 `k
 v2x ~0x €
  
ˆ ¸*
 Ì*
 à*
 ð»
!B2@!J0@!L
!Œ
ˆ!š2Ø!ž2
!¢0Ø!¦0
!¨
!ÐÏ
"R2`"Z0`"\
"®2_ "²0_ "´V
#Z2è#n0è#x
#„D
#˜
#Ê2H#Þ0H#ú2$0$*2($>0($’2˜$–0˜$œ
$Ì
$æ2`$ê0`$ì
%
%"2À%&2€%*0À%.0€%0
%DÉ
%`
%‚2¡À %†2¡À¡%Š0¡À¡%Ž2¡À %’0¡À %–0¡À %®0¡À &2¡Á¨&"@¡Á¨&.2¡Á°&2@¡Á°&J2¡Á¸&N0¡Á¸&V0¡Á¸&^2¡À &b2¡ÁÅ&n0¡À &r0¡ÁÅ':2%T'>0%T'â82'æ80'ê2¡Á¨'î]2'ò]0'ö@¡Á¨'ú2¡Á°'þ@¡Á°6¢z26¦z06À
07˜27˜078
07´
7ä
7øÜ
8,
8@
H8L§
8V2¡ÁÈ8^@¡ÁÈ8Ò2¡ÁÈ8Ö@¡ÁÈ8äD
9Ü
9"29&2à9*09.0à90
9pT
9‚2¡ÁÈ9†@¡ÁÈ9Œ»
9ìÜ
9ü_
:2¡À¡:0¡À¡:2¡À :0¡À :T
H:†
:¼_
:Î2¡À¡:Ò2¡À :Ö0¡À :Ú2¡À :Þ0¡À :â0¡À¡;0¡À¡;D
H;J2¡À¡;N2¡À ;R0¡À ;V2¡À ;Z0¡À ;^0¡À¡;°Ü
;Ü
;ú20<B00<˜
<Ð
<ÜÉ
<äk
=
=0k
=h
=tÉ
=|k
=k
=¸
=ä/
>

>
>˜
>Ð
>ô
?
?22 ?60 ?8
?´k
?ìk
@:2`@>0`@@
B0Ü
B\*
Bl»
C
ØC`§
C Ü
CäÏ
DÄÏ
E˜
ØE¸*
FÏ
FŒ*
Gàk
Gê2¡ÁÐGò0¡ÁÐHk
H 
ØH‚2pH†0pHˆ
I|Ü
J"2¨J&2ÐJ.0¨J20ÐJ4
JT§
JtÏ
KpÜ
LL
L Ü
Lܧ
LðÏ
M˜
N”
 N¢2øN¦0øN¨
N¼
 NÊ2˜NÎ0˜NÐ
O¾2¡ÁÐOÂ0¡ÁÐP4
ØP”=
P¨Ü
Qž2¡ÁÐQ¦0¡ÁÐS02
Sà`
T,
˜TT*
Td»
T|Ü
T˜*
T¨»
TÀÜ
TÜ*
Tì»
UÜ
U*
U,»
U@Ü
UT*
Ud»
Ux*
Uˆ»
Uì*
Uü»
V*
V,»
VDÜ
V˜*
V¨»
V¼Ü
Vð*
W»
WÉ
W`
Wì§
X Ü
X4Ï
Xè
 YD§
YpÜ
Y„Ï
YÔ
Yü
Z/
ZD

Z`*
Zp»
Z*
Z »
Z´Ü
ZÌ*
ZÜ»
[8§
[b2([j0([p
[”
]´É
]Ä
Ø^
^$
È_Ú2X_Þ0X_à
_ø€
`Ü
a
˜aÐ2
b*
b,»
bL*
b\»
bpÜ
bÄ*
bÔ»
bèÜ
c*
c,»
cB2ÈcF0ÈcH
cô§
dÜ
d(Ï
d€
 e$§
ehÜ
e|Ï
e§
e°Ï
gÐ
˜gä
àgô
àh22ph60ph8
hj2˜hn0˜hp
hØ
hü
ÈiN2`iR0`iTV
iº2¡ÁØiÆ0¡ÁØiÚ2¡ÁÜiÞ0¡ÁÜjd
j0¡ÁØj62¡ÁØjN0¡ÁØj¤d
k*2¡ÁØk.0¡ÁØkb2¡ÁØkv0¡ÁØkÐd
l d
l0
@l|d
mH
XmN2¡ÁØmR0¡ÁØm\
Xmj2¡ÁØmr0¡ÁØmÂ2¡ÁØmÆ0¡ÁØn8d
nf2¡Áànj0¡Áàn¤d
od
o(D
oP
@oV2¡ÁØoZ0¡ÁØov2¡Áàoz0¡Áào´d
p22¡ÁÜp60¡ÁÜp:2¡Áàp>0¡ÁàpB2¡ÁØpF0¡ÁØpJ2¡ÁèpN@¡Áèpb2¡ÁØpf0¡ÁØpš2¡ÁÜpž0¡ÁÜpÐd
q2¡ÁØq
0¡ÁØq&2¡Áàq*0¡Áàqhd
q’2¡ÁØq–0¡ÁØqÊ2¡ÁÜqÎ0¡ÁÜrd
r62¡ÁØr:0¡ÁØrV2¡ÁàrZ0¡Áàr˜d
rÂ2¡ÁØrÆ0¡ÁØrú2¡ÁÜrþ0¡ÁÜs0d
sf2¡ÁØsj0¡ÁØs†2¡ÁàsŠ0¡ÁàsÈd
sò2¡ÁØsö0¡ÁØt*2¡ÁÜt.0¡ÁÜt`d
t–2¡ÁØtš0¡ÁØt¶2¡Áàtº0¡Áàtød
u"2¡ÁØu&0¡ÁØu*2¡ÁØu.0¡ÁØu:2¡Áðu>0¡Áðu†2¡ÁðuŠ0¡ÁðuÜ
v [
vD[
v`[
vÊ2¡ÁØvÎ0¡ÁØw2¡Á÷w0¡Á÷w2¡ÁØw.2¡Áøw60¡ÁØwn0¡Áøw´d
wÄ
@xd
xd
x¸«
yŒd
z°=
zÔ
{&2¡ÁØ{.2¡ÁØ{20¡ÁØ{60¡ÁØ{B2¡Áð{F0¡Áð{üd
|lÜ
|¬d
|ò2¡ÁØ|ú@¡ÁØ|ü9
}49
}T9
}À
}ä9
}ø
p~2¡ÁØ~0¡ÁØ~
X~"2X~*0X~@
p~àÞ
F2¡ÁØJ0¡ÁØj2¡ÁØŠ0¡ÁØìd
€0d
€€9
€
€¬9
€²2¡ÁØ€¶0¡ÁØ€¸
X€¾2X€Æ0X€Ü
pT9
Ì
‚&2¡ÁØ‚*0¡ÁØ‚62¡ÁØ‚:0¡ÁØ‚J2¡Áð‚N0¡Áð‚üd
ƒ$9
ƒ´d
ƒÎ2¡Áðƒò0¡Áðƒú2¡ÁØ„9
„
0¡ÁØ„*2¡Áà„.0¡Áà„hd
„r0¡ÁØ„t
X„~2X„‚0X„”
p…(9
…’2¡ÁØ…¢@¡ÁØ…¨9
…Ü
p†
p†0¡Á؆>2¡Áà†B0¡Áà†|d
††0¡Á؆ª2¡Áà†®0¡Áà†èd
†ò2¡Á؆ö0¡Á؇2¡Áà‡0¡Áà‡Xd
‡b2¡Á؇f0¡Á؇Š2¡Áà‡Ž0¡Áà‡Èd
‡Ò2¡Á؇Ö0¡Á؇ú2¡Áà‡þ0¡Áàˆ8d
ˆB2¡Á؈F0¡Á؈j2¡Áàˆn0¡Áàˆ¨d
ˆ²2hˆ¶0hˆ¸m
ˆ¾2ˆÆ0ˆÐ
pˆÖ2¡Á؈Ú0¡Á؈Ü
Xˆâ2Xˆê0X‰
p‰B2¡Á؉F0¡Á؉Ž2¡Â‰–0¡Â‰°Ü
‰ì¸
Š«
Šl«
ŠÒ2¡ÂŠÖ2¡ÃŠæ0¡ÂŠê0¡Ã‹¸
‹H«
‹¬«
ŒÜ¸
¸
Œ²
°²
ð²
Ž¤¸
ŽÐ¸

à,¸
Tª
¨¸
ì²
…
$9
ÜO
èD
‘¸
‘D¸
‘p
à‘„ª
‘ȸ
‘ä¸
’¸
’P²
’x²
’°²
’Ð…
“L²
“|²
“œ²
“Ü«
”8Á
”´€
”Ú2¡Ä”Ü=
”î2¡Ä”þ0¡Ä•2¡Ä•2¡Ä •2¡Ä•0¡Ä•0¡Ä•P
•6@¡Ä•:@¡Ä •<P
•F2¡Ä(•V@¡Ä(•X€
•b@¡Ä•f2¡Ä0•j@¡Ä0•v@¡Ä •Èd
–d
–r2˜–z0˜–|
–¢2Ø–¦0Ø–¨
–²2¡Ä–¶@¡Ä–Ä`
–Î2¡Ä(–Ò@¡Ä(–à`
–ê2¡Ä0–î@¡Ä0—`
—`
—.2¸—20¸—4
—N2—R0—T
—œ`
—Èd
—Ò2¡Ä—Ö@¡Ä—ä`
—î2¡Ä(—ò@¡Ä(˜`
˜
2¡Ä0˜@¡Ä0˜ `
˜f2¡Ä˜j0¡Ä˜v20˜~2¡Ä˜†00˜–0¡Ä˜ð=
™d
™x
™ðW
š.2`š20`š8
š®2¡Ä@š²0¡Ä@šº2¡ÄHšÊ@¡ÄHšæ@¡ÄH›†2¡Ä@›š0¡Ä@œPÉ
œ²2¡Ä@œ¶@¡Ä@>2¡ÄHB@¡ÄH†2ˆŠ0ˆŒ
â2aÀê0aÀž"2¡ÄHž*@¡ÄHž62¡Ä@ž:@¡Ä@žz2¡ÄHž‚2¡Ä@ž†@¡ÄHžˆ€
ž’0¡Ä@ž¬Ü
žÄÏ
žÎ2¡ÄHžÞ@¡ÄHžþ@¡ÄHŸ4É
Ÿ„
¸Ÿ¼Ü
 ÜÜ
¢`
¢62¢:0¢<
¢†2¡ÄH¢–@¡ÄH¢¢@¡ÄH¢¼É
¢Æ@¡ÄH¢Þ@¡ÄH¢ö@¡ÄH£@¡ÄH£&@¡ÄH£B2¡ÄH£R@¡ÄH£f@¡ÄH£‚2¡ÄH£’@¡ÄH£œÉ
£¦@¡ÄH£Æ2¡Ä@£Ê2¡ÄH£Î@¡ÄH£Ö0¡Ä@£äÉ
¤*
¤`
¤B2¡ÄH¤R@¡ÄH¤j@¡ÄH¤Æ2¡ÄH¤Ê@¡ÄH¥
2ªP¥0ªP¥2¡Ä@¥2©Ä@¥0¡Ä@¥0©Ä@¥¨=
¥ÄÜ
¥Ò2¡ÄH¥Ö@¡ÄH¦‚2¡ÄH¦†@¡ÄH¦¾2¡ÄH¦Â@¡ÄH§22¡Ä@§>0¡Ä@§`=
§~2¡ÄH§‚@¡ÄH¨62aÀ¨>0aÀ¨~2¡ÄH¨Š@¡ÄH¨š2¡Ä@¨ž@¡Ä@¨ Ü
¨¼
¸©"2ˆ©60ˆ©Lý
©hO
©€%
©ŒD
© &
©ôº
ª2˜ª0˜ª
ª\¾
ªx
`«2(«2«0(«0« 
«(û
«B2H«F2«J0H«N0«P
«X
«b2À«f2ªh«r0À«v0ªh«¤Z
«´È
«Ü
«äê
¬Î
¬"2¬&0¬(
¬ŒÎ
¬¢2¬¦2¬ª0¬®0¬°
¬¸û
¬Ò2ȬÚ0ȬÜ
¬ò2جú0Ø­
­
­$=
­n2˜­v0˜­~2ªh­’0ªh­¨€
­ÌÜ
­Ö2x­Þ0x­äB
­üÜ
®_
®(ê
®H
®P
®Xq
®x_
®–2®ž0®¤
`®²2p®º0p®À
`®Ì`
®Øj
®äj
¯:2°¯F0°¯X
¯dQ
¯|á
¯¤¯
¯ÈÜ
¯Ô½
¯ê2ªh¯ò@ªh°8=
°B2ªh°F@ªh°f2®€°j0®€°¨ò
°º2ªh°¾@ªh°î2ªh°ò@ªh±D
±|a
±¬Ã
±Ôò
±ðò
²Ã
²0
²TÃ
²lZ
²v2ªh²z@ªh²¬L
²¶2ªp²¾@ªp²Î2²Ò2 ²Þ0²â0 ²äœ
³
2ªp³@ªp³(c
³`¯
³€
x³Ä¯
³Ü
x³ü$
´
20´00´
´2H´&0H´(
´PD
´b2`´f0`´hc
´r2ªp´v@ªp´xj
´”Ü
´Ä=
´Î2ªh´Ò@ªh´ìÃ
µÃ
µ4=
µF2ªhµN@ªhµlÃ
µŒÃ
µ I
µº2ªhµ¾@ªhµÜ¨
µê2€µî0€µð
¶2 ¶0 ¶$
`¶,a
¶R2ø¶Z0ø¶\B
¶”a
¶¼f
¶ä†
·¯
·0
·:2 ·B0 ·D±
·Z2(·b0(·d±
·v20·~00·€±
·’2ªh·š@ªh·¾2X·Â0X·Ô
·ð
·ú2ªh¸@ªh¸<
¸`
¸€
¸¤
¸º2ø¸Â0ø¸Ô
¸â2иê0иð
`¸øa
¹28¹08¹ 
`¹(a
¹B20¹N00¹P
¹d¨
¹r2¹v0¹x
¹˜Ã
¹¸Ã
¹ØÃ
¹ô=
º
xº0

º@Z
ºH
º\=
ºf2ªhºj@ªhº”=
ºª2к²0к¸B
ºÔÃ
ºð=
»$
»22ªh»:0ªh»`
»ph
»˜Ü
»¬
»ÜÜ
»ôÜ
¼u
¼<u
¼hÜ
¼ŒÜ
¼ Ü
¼¸=
¼ÐÃ
¼ì=
½Ã
½$=
½@Ü
½L

½€
½Ë
½¸Ü
½Ì
½ðÜ
¾
¾`
¾„
¾”Ë
¾¼Ü
¾Ì
¾ü
¿Ë
¿4Ü
¿D
¿l
¿À
¿ä
¿ôh
ÀÜ
À,
À\
Àlh
À˜Ü
À°Ü
ÀÊ2¨ÀÎ0¨ÀÐB
ÀôÜ
ÁÜ
Á
Á.2Á60Á<B
Áj2PÁr0PÁtB
Á‚2XÁŠ0XÁŒB
爆
Â=
Â$½
ÂT
ÂdË
„
”Ë
¬
ÂÈ
ÂÜ¢
Âô
Ã
Ã$Ë
Ã<
Ã\
Ãpu
Ì
è
øË
ÃÔ
ÃüÜ
Ä2Ä
0Ä
Ä$_
ÄR2€Ä^0€Äd
ÄpQ
Ĕò
ĬI
ĺ2Èľ0ÈÄÐ
ÄØ9
Äô=
Å2Å0Å
Å(A
Å0
Å`
Åpe
Åxt
ňq
Å¢2
(Ū0
(Ŭ
Ÿj
ÅÄj
ÅÐa
Æ=
Æ0#
Æ<I
ÆJ2ÈÆN0ÈÆ`
Æh9
Æz2èÆ~0èƀ
Ɗ2øƞ0øÆ 
Ʋ2 ƺ0 Ƽ
Æà
ÆðË
Ç2¨Ç0¨Ç
Ç$U
Ç@
ÇN2 ÇV0 ÇX
Çf2PÇn0PÇp
ǂ2(NJ0(nj
ÉЯ
Êz2øʆ0øʼ 
ÊÔ¥
擴
˯
Ë4u
Ëà¯
Ëøu
ÌD
ÌHQ
Ì`Q
̌¯
̼¯
ÌÌD
Í¢
Íhº
Í ¾
ͺ2x;0xÍÀ
Íö20Íþ00Î
Î*2XÎ.0XÎ0
κ2Àξ2¸ÎÊ2ÐÎÎ2ØÎÞ2°Îî2ÈÎøQ
Ï2Ï0°Ï0¸Ï0ÀÏ"0ÐÏ&0ØÏ*0ÈÏ.0ϸQ
б
Ð8Q
Ð\±
Єö
ÑQ
Ñ$
Ñ8±
ÑX±
Ñh±
Ñx
ќ±
Ñà±
ҔD
ÒÀ
ÒÊ2ˆÒÎ0ˆÒÐB
ÒèD
ÒøD
Ó
Ó,
hÓP
Óh
hӆ2ØӖ0ØӘý
Ó°
hÓÊ2°ÓÒ0°ÓÔ
Óì
hÔJ 2ÔN 0ÔR2˜ÔV2Ô^0˜Ôb0ÔdŒ
ÔÌ
Ô܂
Ôþ2xÕ0xÕ
ÕD
Õ*2Õ20ÕTý
Õt
h՚2ø՞0øÕ B
Õ²2¨Õ¶0¨Õ¸B
ÕÎ2 ÕÒ0 ÕÔB
Ö
2ªxÖ0ªxÖ=
Ö22ªxÖ:0ªxÖ<Ü
Öb2ªxÖf0ªx֞2ª€Ö¦0ª€Ö²2ªxÖ´Ü
ÖÌ
ÖÖ0ªxÖò2°Öú0°×Ã
×2ªŒ×0ªŒ×b2d×j0d×pÃ
׌Ã
×°Ã
×àÍ
Ø ^
Ø`
Ø°l
Ù=
Ù$=
Ù~2ª
pق2ª
€ن0ª
€َ0ª
pْ2ª
tٚ0ª
tٞ2ª
xÙ¢0ª
xÙÄÜ
Ùæ2Ùê0Ùî2ªF€Ú@ªF€Úr2ªFˆÚv0ªFˆÚö2ª
pÚú2ª
xÚþ0ª
xÛ0ª
pÛ
2ªFÛ0ªFۚ2ÀÛª0ÀÛ²2¸Û¸Ã
ÛÂ0¸Ûâ2ª
xÛæ0ª
xÜÜ
Üp
Ü2ªFˆÜ"0ªFˆÜD=
Ü\=
Ühp
܀^
ܔ
ܦ2ª
xÜ®2ª
tܲ0ª
tܺ0ª
xÜÖ0ª
xÝÜ
Ý p
Ý8^
ÝP=
ÝZ2ªLˆÝ^0ªLˆÝ`
Ýh
݀q
ݔe
Ýú2ªFˆÝþ0ªFˆÞ2ªFŒÞ0ªFŒÞ>2¸ÞB0¸ÞLp
Þh^
Þ|=
ޔ
ÞàÜ
ßþ2ª
tà0ª
tà2ªF”à
0ªF”àj2d àn0d à‚2¸àš0¸àž2ª
|à¢0ª
|àÒ2¸àê0¸àî2ª
|àò0ª
|àú2¸á0¸á22ªFˆá60ªFˆá8
(áR2ªFˆáV0ªFˆá†2ªFŒáŠ2d#á’0ªFŒá–2d$áš0d#áž2d á¢0d$áª0d á®2d"á²0d"áÒ2ªFŒáÖ2d áâ0d áæ0ªFŒáèÜ
â2ªFŒâ0ªFŒâ22ªF”â60ªF”â8
(âR2ªF”âV0ªF”âr2ªFâv0ªFâx
(â’2ªFâ–0ªFã¦2ªFŒãª0ªFŒãÞ2ªFˆãâ0ªFˆäâ2ªL”äæ0ªL”äî2ª
päò0ª
päþ2ªL™å0ªL™å¦2ª
på®0ª
påÆ0ª
påä'
æB
æ2ªLæ0ªLæ =
æL=
æ¤V
ç,=
ç¨
çÐ
è22ªFˆè60ªFˆè:2ª
pè>0ª
pèpp
è€Ã
é2Àé0Àé Ã
é<=
ê,Ü
ê4p
êL^
êTp
ê„=
êœ=
ê´
ë=
ë
ëf2ª
pëj0ª
pëÄÜ
ì(
ìR2ª
pìV0ª
pì°
ìü[
í<Ö
퀡
íä‘
îà=
ï’2(ïš0(ï 
ð\D
ð†2«R€ðŠ0«R€ð Ü
ðÐ
ðÜD
ñv
ñ,=
ñ4
ñPÝ
ñZÛ2ñ^Û0òv
ò2«Xpò0«Xpò0C
òZ2«Xpò^0«Xpò‚2«Xxò†0«Xxòˆ=
òî2(òò2«Yˆòú0(òþ0«Yˆó2«R€ó
ó&2Èó.0Èó20«R€ó4¥
óF2ÐóN0ÐóP¥
ó^2óf0ól¥
ó„¥
ó’2 óš0 ó ¥
ó¸¥
óÊ2ØóÒ0ØóØ¥
óð¥
ô0¯
ôL
ôXD
ôˆ¯
ôò2«Xpôö0«Xpõ2«Zœõ&0«Zœõ,
õ<D
õX
8õ\
õd
õq
õ¤e
õÒ2àõÚ0àõÜ
ö4D
öTD
öx
8öˆ
ö–2øöž0øö 
ö¾2 `öÆ0 `öÈ
öð=
÷2 ÷
0 ÷
÷0=
÷LÜ
÷â2«[ ÷æ0«[ ø
 ø†2«ZœøŽ0«Zœø¶2«R€øº2«[ øÂ2«Z øÆ2«XˆøÎ0«R€øÒ0«[ øÖ0«XˆøÚ0«Z ù
 ù ö
ùhö
ù†2«Z˜ùŽ0«Z˜ù¬=
ùÌ
 úN2 ˆú^0 ˆúb2 °ún0 °úr2 àúv0 àú|
ú†2«\ ú–@«\ ú˜
úÈÜ
úäC
úüv
û
ûp
û0=
ûD
ûxÜ
û€
ûˆ
û 
ü@q
ül
ü~2 ¸ü†0 ¸üŒ
ü˜p
ü¨Ã
üº2«\ ü¾@«\ üÐ=
üð
üþ2 èý0 èý
ýä=
þ=
þ$=
þú2ýþþ0ý¸=
ø=
ö2«\¨L
@«\¨$=
2@«\¨†2«\°”L
¢@«\°¸=
Æ@«\°2«]Ä2«]Æ2«\¨2«]Ç"0«]Ä20«\¨60«]Ç>0«]ÆJ2«]ÉR0«]ɐD
¬=
ðD
=
X=

°v2«\¸~0«\¸ŒÜ
–2«\Ôž2«b¨¢0«b¨¦2«\¨®0«\Ô²2«\Ö¶0«\¨º0«\Ö¾2«\ØÂ0«\ØÄp
Ø=
ìÜ
ú2d(	
0d(	 =
	H
à	\v
	f2«b¬	j0«b¬	„C
	˜
	à¦
	ì¦
	þ2«b¨

0«b¨
^2«b°
b2(
f0«b°
r0(
z2«\¨
†0«\¨
ˆ

œ

¦2«d°
²@«d°
¶2«\°
¾@«\°
Â2«\¨
Æ@«\¨
È

Ò2«d¸
Ö0«d¸
Ø

à

ìe
lD
~2«d¼‚0«d¼’2«b¬–0«b¬¨
²2«\¨¶2«\°Â@«\¨Æ@«\°Î@«\°Ò@«\¨q
"2«d¼&0«d¼<
HD
dË
ë

2«\¸
0«\¸
2«\¨
Ü

"2«\Ô
*2«b¨
.0«b¨
:0«\Ô
>2«\Ö
B0«\¨
J0«\Ö
N2«\Ø
R0«\Ø
V2«]@
Z0«]@
\p

p=

z2«b¬
~0«b¬
‚2«\à
’0«\à
ӆ

ž2«dÀ
¢0«dÀ
®2d(
º0d(
È=

ð
àv
2«dÀ0«dÀ2«b¬0«b¬(C
<
¨Ü
Â2«b¨Æ0«b¨Ê2«\¨Î0«\¨â2d(î0d(üÃ
Ü
,Ã
\
È‚2«d¸†0«d¸`D
ˆ¯
¨D
Î2«d¸ê0«d¸=
`
ø€Ü
”Ã
´
Èè
ø
ø 
øj2«b¬r2«d¼z0«b¬~0«d¼€D
’0«d¼¤D
º2«d¸Â0«d¸Æ2«dÀÊ0«dÀÎ2«b¬Ò0«b¬ÔI
Þ2«d°â@«d°ü=
 
,#
XE
|¯
Š2«c0Ž0«c0¬¯
º2«c0¾0«c0øÜ
p
,=
@Ü
\=
t=
¨=
Ð
àäv
C

*2«d¸20«d¸–2«b°š0«b°°D
Æ2«d¸Ê0«d¸ì¯
=
(
H
`¯
|¯
ª2«dȲ@«dÈÊ2«dÌÎ0«dÌÖ2 øÚ0 øð
þ2«dÈ2«dÌ0«dÈ"0«dÌ&2d0*0d022d060d0V2d0^0d0„ý
²2#Xº0#X¼
2«dÐ0«dÐ(Ü
22«eÐ62«dÈ:0«dÈ>@«eÐP
xÝ
v
¢Û2¦Û02«eØ@«eØ$C
@v
š2«dТ2¦0ª2!®0!²0«dÐÂ2«dÈÆ0«dÈÐÜ
Ú2«eÐÞ@«eÐî2«eØò@«eØüD

2!0!D
4D
HD
T
€Ý
Š2«eØŽ@«eؘD
¨D
¼D
ÔD
ôv
2«eØ@«eØD
,=
62«eØ:@«eØ@D
XD
l=
xD
D
¤=
°D
ÈD
à=
êÛ2îÛ0R2«eØZ2!b@«eØf0!pD
€D
D
¨D
²@«eØÔC
àD
ðD
þ2!0!D
 D
Dv
z2d8~@d8Ž2«eèª@«eè¶2«dȺ0«dÈÀ
ˆÄ
Ì
Þ2«eìæ0«eì62«f:@«f†2«fŠ@«f’2«eè–2«fš0«fž@«eèº2d8¾@d8Ð=
Ú2«eìÞ0«eìè
 î2«eîò0«eîú2«eèþ0«eè0«eè˜
 º2!¾0!ØQ
ðQ
 D
 $Ã
 8D
 PW
 Z2«eî j0«eî v2«eì z0«eì „
  ¦2«eì ª0«eì ²2«eî ¶0«eî ÈÜ
 Ò2«eÐ Ö@«eÐ è
!Ý
!(v
!:Û2!>Û0!–2«f!š0«f!¶2Ð!º0Ð!þ2«eð"0«eð"&2«eð"20«eð">2«eð"F0«eð"R2«eð"Z0«eð"f2«eð"n0«eð"z2«eð"‚0«eð"Ž2«eð"–0«eð"¦2«eð"®0«eð"ä
 "ê2«f"î@«f"ò2«eü"ú0«eü#
0«eü#&2«eØ#*@«eØ#HC
#‚2«eì#†0«eì#œv
#Æ2«f#Î0«f#Ò2«eð#Ö0«eð$2«eØ$*@«eØ$.2«f$22«f$:2$À$>0«f$B2«f$F@«f$R2«eà$V0«f$Z2«eÐ$b0$À$f0«eà$j0«eÐ$n2«eè$r2«dÈ$v2!0$z0«dÈ$~0«eè$‚2«f$†0!0$Š0«f$Ž2«eü$’0«eü$–2«dÈ$š0«dÈ$ž2«eð$¢0«eð$¦2«eô$ª0«eô$®2«eì$²0«eì$¶2«dÌ$º0«dÌ$¾2«eø$Â0«eø$Æ2«eî$Ê0«eî$Ìý
$Ö2!$Ú0!$Ü
$ì
ˆ$ò2d8$ö@d8$ø
%
%
@«eØ%
¸%(e
%\q
%¤
 %¸
%À
%Ðe
&2d8&@d8&T
&d
¸&Š2d8&Ž@d8& 
ˆ&¦2(&ª0(&¬
&Â2«eè&Æ@«eè'2d8'
@d8'22!X'60!X'8
'L
'¨¯
'²2! 'º0! 'À«
'ØQ
'üQ
(Q
(,Q
(d
(|ë
(Ӭ
(¤
(°j
(ôQ
)Q
)0h
)H
)Tj
)’2"X)š0"X)œ
)²2!¨)º0!¨)À
)Ìj
)Ú2!p)â0!p)ä
)ò2!Ø)ú0!Ø*
*j
*2" *"0" *(
*4j
*B2"@*J0"@*P
*\j
*j2!ø*r0!ø*x
*„j
*’2!À*š0!À* 
*¬j
+z2)”+~0)”+ª2"è+®0"è+¶2«f+º0«f+¾2$+Ê0$+Ìý
+î2"ˆ+ò0"ˆ+ú2"˜+þ0"˜,2"°,
0"°,2"È,0"È,2#,&0#,:2#°,B0#°,V2#,^0#,r2#x,z0#x,Ž2#`,–0#`,ª2#ð,²0#ð,Æ2#È,Î0#È,î2«f,ò2#H,ö0«f,þ0#H-%
->2«f-B2«f-F0«f-J2#-N@«f-V0#-h%
-–2«f-š2$`-ž0«f-¢0$`-´ý
-â2«f-æ2$(-ê0«f-î0$(.ý
..2«f.22$.60«f.:0$.Pý
.r2"p.v0"p.ª2«fh.®@«fh/ Ã
/Ø=
1=
1&2«fh120«fh1dÃ
1š2«fh1ž@«fh1ÔÊ
1ôÃ
2Ã
28ú
2@p
2\^
2p=
2|
2„
2q
2¤e
2؞
2ê2«fp2î0«fp2øp
3^
3,=
3D
3‚2«fˆ3†@«fˆ3=
3°
`3ÜÃ
4=
4,
`4tL
4Ά
4 =
4´C
4¾2«fp4Â0«fp5œ¯
5´u
5ür
6Q
6H¯
6XD
6pu
7
2«fh7@«fh72«l€7@«l€7*2«l€76@«l€7`L
7|Ü
7È
H7Ø
¨7Þ2«fh7â@«fh82«fh8@«fh8|L
8˜Ü
8¢2«fˆ8¦@«fˆ8¸=
8Â2«fˆ8Æ@«fˆ8Ø
H8è
¨8ò2«l8öÛ28úÛ092«lˆ9
è29@«l92«l˜90«lˆ9è092«fh9"2«l9&@«l˜9*0«fh9:2«fx9>0«l9B0«lˆ9J@«fx9N2«f€9V@«f€9X
H9h
¨9lS
9|Ÿ
9„,
9”
9œ
9°q
9Äe
9Ì,
9î2«fh9ò@«fh:dp
:n2«fˆ:r@«fˆ:”=
:¨=
:Ä=
:Þ2«fˆ:â@«fˆ;2«fˆ;@«fˆ;L
H;¬ø
;Ü'
<P=
<d=
<¸=
<Ì=
<è=
=`=
=t=
==
=Ò2«fh=Ö@«fh>DL
>\Ü
>¬L
>ÐÜ
>è=
>ðp
?=
? =
?<=
?P=
?°
H?Ð
¨@8Ã
@φ
@¬Q
@èQ
A22$ÈA:0$ÈA<¥
AN2$ÐAV0$ÐAXö
Aį
Aä
B=
B
BB2$ÈBJ0$ÈBL¥
B„
B¨=
C2$ðC2$èC
2$ØC2ØC&0$ðC*0$èC.0$ØC20ØCHý
Cd
C˜
CÄý
CÒ2$øCÚ0$øCè¥
D62$ÈD>0$ÈD@
DZ2%D^0%Dˆ«
D 
Dª2%D²0%D´ö
DÆ2$ÈDÎ0$ÈDÐ
E2ØE0ØE
Ej2«lÐElÜ
Et
E~0«lÐE˜Ý
E°v
EÌ=
Eðp
F=
FHè
FŒ¦
F–2«mFš0«mFœ¦
F¦2«mFª0«mF¬¦
Fº2«mFÂ0«mG2«lÐG2d@G@«lÐG2«mG"@«mG&2«lØG.0d@G2@«lØG4
øG>2d@GB0d@GD
GL
GXe
G q
H2«mH0«mH"2«lÐH$Ã
H.0«lÐHN2d@HR0d@HÀ¯
Hè¿
ID=
IXE
IÌL
Iü
JÝ
J0p
JD=
JNÛ2JRÛ0J€j
J² 2J¶ 0Jº2%J¾0%JÀŒ
Jò2«m Jö@«m K4L
KTÜ
KŒ
K¨Ý
KÄ=
KÔp
Kè=
KòÛ2KöÛ0L$j
LR 2LV 0LZ2%@L^0%@L`Œ
LÐ=
Lä=
M4L
MH
MlÝ
M„=
M”p
M¨=
MÜÜ
Mä
Mø=
Np
N=
NÛ2N"Û0NPj
N‚2% N†0% NŠ2%¤NŽ0%¤N 1
N¶!2Nº!0O0=
O`x
Opì
O€k
O˜=
O¤'
OÞ2«m Oþ0«m P=
Pp=
P€Ê
Pœ=
Pè,
PøC
Q =
Q<
Qb 2Qf 0Qj2%pQn0%pQpŒ
QŒ
Q˜|
Qº2«m(Q¾@«m(QÊ2«m0QÖ@«m0QÚ@«m0Qò2«m(Qþ@«m(R2«m0R@«m0RTL
RpÜ
Rˆ=
Rœ=
RÚ2«m(RÞ@«m(S,×
S’2«m(S–@«m(Sê2«m8Sî@«m8Sú2«m@T@«m@T
@«m@T"2«m8T.@«m8T22«m@T6@«m@T|L
Tӆ
T¬=
TÄ=
U
2«m8U@«m8U\×
UÆ2«m(UÊ@«m(UÎ2«m0UÒ@«m0UÖ2«m8UÚ@«m8UÞ2«m@Uâ@«m@V>2«mHVB2«mHVF2«mPVJ2%¨VN@«mHVR2%°VV2%ÀV^0«mHVb0«mPVf0%¨Vj0%°Vr0%ÀV€ý
V˜
V¨D
V¼
VÈD
VÜ
Vð
WL
W 
W4=
W°
XB
X8k
XB2%àXF2àXJ0%àXN0àX`D
Xt
Xˆ
X˜k
XÔD
Xè
Xü
Yk
Y22%èY62«mHY:0%èY>0«mHY@
xYF2%ðYJ0%ðYL
xYR2%øYV0%øYX
xY^2«mHYb0«mHYn2& Yz2&PY~0& YˆB
Y’2«mHY–0«mHYž0&PYØ
Yö2%àYú0%àZD
Z
Z(
Z:2àZ>0àZDD
ZX
Zl
Z€D
Z”
Z¨
[
[ D
[4
[>2«mH[F@«mH[V0«mH[lj
[À
\
\2&\0&\B
\L
\z2«o¨\~@«o¨\Ž2«o˜\’@«o˜\š2«o \ž@«o ]=
]2«o¨]6@«o¨]B@«o¨]|=
]ÄÜ
]Î2&`]Ö0&`^Ü
^2«o¸^@«o¸^2«o°^0«o°^N2dH^Z0dH_¬
À`h
`’2«o°`š2«o¸`ž@«o¸`¢2dH`¦2d``ª0dH`®0«o°`¶0d`b^2«o¸bb@«o¸bf2«o°bj0«o°c
2dHc0dHc2d`c"0d`d&2«o¸d*@«o¸dlÜ
eðÜ
f
 f€=
f”=
f¸
fì
 g
Àgh
ðgt
ðg~2«og–0«og²0«ogÒ2«ogÖ0«ogâ@«oh2«oh0«oh.
h0«oh:0«ohj2«ohr0«ohz0«oh|.
h†0«ohš0«ohª0«oh¬.
h¶0«ohÆ0«oiÜ
i0
ixÜ
i”
iô
j<€
jF2«o¸jR@«o¸j\=
jf2«o°jr0«o°j’2&pjš0&pjœ
jÀ
ðjÐ
ðjÖ2«ojâ0«ojê0«ok(
kp¦
kœ
l
l4=
l¤=
lÀ
lø
ðm
ðm
2«om0«om0«om~2«o m‚@«o m†2«o˜mŠ@«o˜mŽ2«o¨m’@«o¨m”
Øm¸
ðmÄ
ðmÊ2«omÒ0«omâ0«on2«o¨n@«o¨n
2«o˜n@«o˜nt4
n¼
8nÊ2&˜nÒ0&˜nØ%
näD
nôD
o
8o`
8ož2«ooª0«oo¶@«ooæ2) oê0) p
8pb2«opf0«opl.
pv0«opŽ0«opÊ2«opÚ0«opæ@«oq2&°q0&°qD
q4
8qb2&ðqf0&ðqpD
q
8qž2&øq¢0&øq¬D
qä
8qò2&Ðqö0&ÐrD
r 
8r:2«orB0«orD.
rN0«orb0«orÎ2«orÚ0«oræ@«os2«oÈs"2«oÀs&@«oÈs*@«oÀs0`
sB@«oÀsD€
sR@«oÈsh=
sr2«oÈsv@«oÈs²2«os¶0«os¼.
sÆ0«osÞ0«osü=
t2«oÈt
@«oÈtr2«ot~0«otŠ@«otš2«oÈtž@«oÈt¢2«ot¦0«otÖ2)(tÞ0)(tèÃ
u€
u4=
uD`
ul=
uv2«oÈuz@«oÈu¾2«ouÂ0«ouÈ.
uÒ0«ouê0«ov`
vB2«ovF0«ovR@«ovb2«oÈvf@«oÈv
8vÊ2«ovÎ0«ovÐ.
vÚ0«ovî0«ovö2«oÈvú@«oÈw4
8wŠ2(èwŽ@(èw’2w–@wš2wž@w¢2w¦@w²2 w¶@ wº2(w¾0(x
8x2'x"0'x,D
x622x:20x>X2xBX0x\
8x‚2«ox†0«ox¬à
xâ2«oxæ0«oyõ
yb2(pyf2' yj0(pyn2'0yr2'Pyv2dHy~2dby‚2( y†2(0yŠ0' yŽ0'0y’0'Py–0dHyš0dbyž0( y¢0(0y¨
y´
yÀ
yÈ\
z:2'èz>2(zJ2(@zN0'èzZ0(z^0(@zp
z€
{
{,
{P
{\
{´
{þ2)|@)|P
}H=
}t
}¼Ü
}Ø
}ô5
~
~ˆ
~®2)@~²@)@~¶2)R~º0)R~¾2)8~Â@)8~Æ2)H~Ê@)H~Ò2)P~Ö0)P~ü
"2'¸*0'¸,
€
Ê2e(Ò2eÖ@eâ0e(€Ü
€
0e(€2e €@e €&0e(€20e(€:2e8€J0e8€N2e<€R2e€V0e€Z0e<€\ñ
€r2e8€v0e8€z2e<€‚0e<€2
€î2e8@e8B2eF@edd
v2e~@e¢2e<¦@e<Â2e<Æ0e<ò2eö2eú@eþ0e‚
2e<‚0e<‚2+‚2) ‚"0+‚&0) ‚(
‚V2e ‚Z@e ‚^2e‚b@e‚f2e‚j0e‚n2e8‚‚@e8‚„d
‚¦2«oЂª0«oЂ²2«oЂ¶0«oЂâ2e ‚æ@e ‚è€
‚ò2e‚ú@eƒÜ
ƒX
ƒ&2*øƒ*2)xƒ.0*øƒ20)xƒ4
ƒl
 胂2«oЃ†0«oЃŽ2«oЃ’0«oЃž2eƒ¢@eƒ¼
 èƒÒ2e8ƒæ2e@ƒê@e8ƒö0e@ƒü€
„62+„>2)À„F0+„J0)À„P
„b2*ø„f2)X„j0*ø„n0)X„p
„‚2+(„†2*0„Š0+(„Ž0*0„
„®2e„²0e„¸d
„Ê2e„Ú@e„ò2+„ö2)à„ú0+„þ0)à…
…2+(…2*…0+(…0*… 
…22+(…62*x…>0+(…B0*x…z2e<…‚2e…†@e<…Š0e…®2e@…²0e@…ðÜ
†2e@†"0e@†&2eH†*@eH†22e0†>@e0†`=
†n2e†r0e†v2e8†Š@e8†Œñ
†ª2e8†®@e8†Ò2+@†Ö2*ȆÞ0+@†â0*Ȇä
‡"2*ø‡*0*ø‡B@e8‡P2
‡¼=
‡Ê2e0‡Ö@e0‡ò2+@‡ö2*¨‡ú0+@‡þ0*¨ˆ
ŠÀ=
ŠÐ
!x‹=
‹HÜ
‹h=
‹x
!x‹¸
!x‹ÈÜ
Œ2+`Œ0+`Œ"2+pŒ&0+pŒP
!Œ`=
>2+tZ0+tŽâ2+tŽê0+tP=
`
!À¨=
ÜÜ
ü=

!À=
h
!ÀxÜ
‘b2,˜‘Š0,˜“P=
“`
!ð“¨=
“ØÜ
“ø=
”
!ð”H
!ð”XÜ
”¦2/ ”®2/”²@/”¶2/(”º@/(”¾2/0”Â@/0”Æ2/8”Ê@/8”Ö@/ ”Ú2/@”Þ@/@”â2/H”æ@/H”ê2/P”î@/P•
"•,=
•v2/`•~2/X•‚@/X•†2/h•Š@/h•Ž2/p•’@/p•–2/x•š@/x•¦@/`•ª2/€•®@/€•²2/ˆ•¶@/ˆ•º2/•¾@/•ì
"•ü=
–HD
–\
š D
š0D
šl«
šŒ«
šÜ«
àF
ðF
žÜD
£Â2eP£Î@eP£â@eP¤2eP¤@eP¤R2«oؤ^0«oئDÑ
¦„Ñ
¦¶2«oئÂ@«oب
¨°W
©®2/˜©¶0/˜ªPF
«2/¸«0/¸¬Æ2ªà¬Ê0ªà®¸
$¨¯
$¨¯(
$À¯dW
¯tD
¯¼D
°,
$¨°´
$¨±
$¨±2ÿÿÿÿÿÿÿÿ±0ÿÿÿÿÿÿÿÿ±XD
±„
$À²O
²èf
³"2³&0³Lf
³†2³Š0³”D
³¨Š
³²20³º00³ÄŠ
´H©
´¤©
µÂ2³ÜµÆ0³Ü·
%P·8
%P·”
%P·ðr
¸
%P¸”D
¸°u
¸Ô
%P¹0 
¹H
%P¹ÔD
¹ô
%Pºl
%PºôD
»
%P»x
%P¼
½
%P½`
%P½Ìr
¾
%P¾8r
¾|D
¿`
%P¿Ì 
À
%PÀ8 
Â$
%h 
%P²s2¶s0¸
%PÃO
ÃpO
Ȋ
Ä& Ä3Ä&ðÄ 3Ä0& Ä83ÄH&`ÄP3Ä`&ÀÄh3Äx&P0Ā3Đ&QðĘ3Ĩ&RÐÄ°3ÄÀ&UÀÄÈ3ÄØ&V Äà3Äð&W€Äø3Å&XpÅ3Å &XàÅ(3Å8&Y Å@3ÅP&ZÅX3Åh&ZÅp3ŀ&[ň3Ř&[0Å 3Å°&[°Ÿ3ÅÈ&\@ÅÐ3Åà&\ÀÅè3Åø&^@Æ3Æ&^ÐÆ3Æ(&_Æ03Æ@&`0ÆH3ÆX&`°Æ`3Æp&a0Æx3ƈ&a°Ɛ3Æ &b@ƨ3Ƹ&bÐÆÀ3ÆÐ&c`ÆØ3Æè&càÆð3Ç&dÇ3Ç&epÇ 3Ç0&f`Ç83ÇH&f€ÇP3Ç`&f Çh3Çx&gðǀ3ǐ&h`ǘ3Ǩ&hÀÇ°3ÇÀ&i0ÇÈ3ÇØ&jÀÇà3Çð&kàÇø3È&nÈ3È &o0È(3È86&È@3ÈPç&ÈX3Èhw&Èp3Ȁ&upȈ3Ș&vpÈ 3È°&wðȸ3ÈÈ&y€ÈÐ3Èà&z°Èè3Èø&{PÉ3É&}@É3É(&}àÉ03É@&~ÉH3ÉX&`É`3Ép&Éx3Ɉ&ƒ€ɐ3É &„ ɨ3ɸ&ˆÉÀ3ÉÐ&‰PÉØ3Éè&‰pÉð3Ê&Œ Ê3Ê&ŒÐÊ 3Ê0&@Ê83ÊH&‘ÐÊP3Ê`&–PÊh3Êx&—Pʀ3ʐ&˜Pʘ3ʨ&š Ê°3ÊÀ&šÐÊÈ3ÊØ&›Êà3Êð&›°Êø3Ë&›ÐË3Ë &›ðË(3Ë8&`Ë@3ËP&žËX3Ëh&ž€Ëp3ˀ&žàˈ3˘&ŸàË 3Ë°&£À˸3ËÈ&¥ ËÐ3Ëà&¦Ëè3Ëø&¦Ì3Ì&§pÌ3Ì(&§àÌ03Ì@&©ÀÌH3ÌX&¬ Ì`3Ìp&¬àÌx3̈&®`̐3Ì &®°̨3̸&²ÌÀ3ÌÐ&µ@ÌØ3Ìè&¶àÌð3Í&·@Í3Í&º0Í 3Í0&½€Í83ÍH&¿ÍP3Í`&¿`Íh3Íx&Ãà̀3͐&ÄÀ͘3ͨ&ÇpÍ°3ÍÀ&ÊÍÈ3ÍØ&Ì°Íà3Íð&Í0Íø3Î&Ï@Î3Î &ÑÎ(3Î8&Ñ`Î@3ÎP&ѐÎX3Îh&ÒÎp3΀&ÓÐΈ3Θ&ՀΠ3ΰ&×°θ3ÎÈ&ؐÎÐ3Îà&Ü Îè3Îø&ÝPÏ3Ï&ÞÐÏ3Ï(&ßàÏ03Ï@&ààÏH3ÏX&á0Ï`3Ïp&áàÏx3ψ&â`ϐ3Ï &ãϨ3ϸ&ãÏÀ3ÏÐ&äPÏØ3Ïè&äÐÏð3Ð&åÐ3Ð&æÐ 3Ð0&æÐÐ83ÐH&çÀÐP3Ð`&è Ðh3Ðx&é@Ѐ3А&éàИ3Ш&ê°а3ÐÀ&ëPÐÈ3ÐØ&ìPÐà3Ðð&ì Ðø3Ñ&ðÑ3Ñ &ðÑ(3Ñ8&ñÑ@3ÑP&ö@ÑX3Ñh&øÑp3р&øш3ј&úÐÑ 3Ñ°&ÿ@Ѹ3ÑÈ&ÀÑÐ3Ñà&ÀÑè3Ñø&°Ò3Ò&
Ò3Ò(&
Ò03Ò@&
ÀÒH3ÒX& Ò`3Òp&€Òx3҈&Ґ3Ò &ÀÒ¨3Ò¸&PÒÀ3ÒÐ&`ÒØ3Òè&  Òð3Ó& àÓ3Ó&"`Ó 3Ó0&#€Ó83ÓH&#ÐÓP3Ó`&5`Óh3Óx&7PӀ3Ӑ&7ÀӘ3Ó¨&8€Ó°3ÓÀ&9€ÓÈ3ÓØ&=€Óà3Óð&?ÀÓø3Ô&@ Ô3Ô &A@Ô(3Ô8&B@Ô@3ÔP&DÐÔX3Ôh&G Ôp3Ԁ&MԈ3Ԙ&P0Ô 3Ô°&Q Ô¸3ÔÈ&U€ÔÐ3Ôà&YàÔè3Ôø&]ÀÕ3Õ&f Õ3Õ(&g@Õ03Õ@&g€ÕH3ÕX&i Õ`3Õp&kÕx3Ո&n0Ր3Õ &n`Õ¨3Õ¸&oÕÀ3ÕÐ&oÕØ3Õè&p0Õð3Ö&pÀÖ3Ö&q`Ö 3Ö0&qðÖ83ÖH&rÖP3Ö`&s Öh3Öx&s€ր3֐&s ֘3Ö¨&t°Ö°3ÖÀ&x@ÖÈ3ÖØ&yÖà3Öð&zðÖø3×&{×3× &{€×(3×8&|€×@3×P&}×X3×h&0×p3׀&€׈3ט&ƒp× 3×°&‡0׸3×È&‡@×Ð3×à&‡`×è3×ø&ˆØ3Ø&ŠØ3Ø(&ŒPØ03Ø@&ŽØH3ØX&’€Ø`3Øp&•pØx3؈&–@ؐ3Ø &—°ب3ظ&˜PØÀ3ØÐ&›ÐØØ3Øè&œ`Øð3Ù& `Ù3Ù&¢°Ù 3Ù0&¤pÙ83ÙH&¦ÙP3Ù`&§Ùh3Ùx&§Ðـ3ِ&¨°٘3Ù¨&«@Ù°3ÙÀ&¿°ÙÈ3ÙØ&ÅÀÙà3Ùð&Æ0Ùø3Ú&Æ°Ú3Ú &ÇÚ(3Ú8&È@Ú@3ÚP&ËÚX3Úh&Ë@Úp3ڀ&ÌPڈ3ژ&Ð Ú 3Ú°&ÓðÚ¸3ÚÈ&Ô`ÚÐ3Úà&ԀÚè3Úø&Ö Û3Û&ÖàÛ3Û(&×`Û03Û@&Ø ÛH3ÛX&ß0Û`3Ûp&ßPÛx3ۈ&ßpې3Û &àÛ¨3Û¸&à0ÛÀ3ÛÐ&àPÛØ3Ûè&àpÛð3Ü&àÜ3Ü&à°Ü 3Ü0&á0Ü83ÜH&ápÜP3Ü`&æÜh3Üx&é`܀3ܐ&êPܘ3ܨ&êpÜ°3ÜÀ&ëÀÜÈ3ÜØ&ìÜà3Üð&ì@Üø3Ý&ì`Ý3Ý &ìpÝ(3Ý8&îÝ@3ÝP&ðPÝX3Ýh&ð°Ýp3݀&õp݈3ݘ&øÝ 3Ý°&û€ݸ3ÝÈ&ü€ÝÐ3Ýà&Ýè3Ýø&@Þ3Þ&PÞ3Þ(&ÐÞ03Þ@&0ÞH3ÞX&
àÞ`3Þp&pÞx3ވ& ސ3Þ &àÞ¨3Þ¸&`ÞÀ3ÞÐ&pÞØ3Þè&!ÀÞð3ß&!ðß3ß&%Pß 3ß0&(Ðß83ßH&, ßP3ß`&- ßh3ßx&.Ð߀3ߐ&30ߘ3ߨ&4ðß°3ßÀ&6PßÈ3ßØ&9ßà3ßð&9 ßø3à&:à3à &:à(3à8&; à@3àP&;ÐàX3àh&<0àp3à€&<àˆ3à˜&=à 3à°&>à¸3àÈ&>pàÐ3àà&@Ðàè3àø&C@á3á&D€á3á(&Dàá03á@&EðáH3áX&G°á`3áp&Hðáx3áˆ&Iá3á &Já¨3á¸&O°áÀ3áÐ&P0áØ3áè&PÐáð3â&Qâ3â&Qàâ 3â0&R`â83âH&SâP3â`&SÀâh3âx&Tâ€3â&V â˜3â¨&W â°3âÀ&ZpâÈ3âØ&[ âà3âð&]ðâø3ã&^ã3ã &`0ã(3ã8&c ã@3ãP&eÐãX3ãh&fPãp3ã€&iãˆ3ã˜&i0ã 3ã°&kpã¸3ãÈ&lãÐ3ãà&l0ãè3ãø&mPä3ä&mä3ä(&n°ä03ä@&pÀäH3äX&r`ä`3äp&t@äx3äˆ&upä3ä &v€ä¨3ä¸&vàäÀ3äÐ&w0äØ3äè&} äð3å&@å3å& å 3å0&Àå83åH&àåP3å`&ƒ`åh3åx&†@å€3å&ˆPå˜3å¨&Šå°3åÀ&ŠåÈ3åØ&Œ°åà3åð&Ž°åø3æ&àæ3æ &’æ(3æ8&“`æ@3æP&”0æX3æh&” æp3æ€&”ðæˆ3æ˜&•pæ 3æ°&•°æ¸3æÈ&– æÐ3æà&–Àæè3æø&—ðç3ç&™0ç3ç(&™ç03ç@&šçH3çX&›ç`3çp&›°çx3çˆ&œÀç3ç &€ç¨3ç¸&°çÀ3çÐ&ðçØ3çè&ž çð3è&žPè3è& è 3è0&¡Àè83èH&¢èP3è`&¢ èh3èx&¥°è€3è&¥àè˜3è¨&¦`è°3èÀ&§èÈ3èØ&¨Ðèà3èð&°pèø3é&°Àé3é &±é(3é8&±pé@3éP&²éX3éh&³0ép3é€&¾ðéˆ3é˜&À é 3é°&À°é¸3éÈ&ÀÐéÐ3éà&Á@éè3&;0&Dî& &Áà@&tH‰&P&Âp&tx&€&Ę&¬ &5P¨&5°°&Aè¸&gXÀ&5PÈ&0Ð&AèØ&à&5Pè&Cèð&Aèø&}è&58é&&58& &5€(&6À0&5P8&1x@&cøH&Ä(P&:0X&èp&¬x&–ø€&;`ˆ&Aè&eÀ˜&5h &e˜¨&7˜°&j°¸&7˜À&AèÈ&exÐ&5PØ&žà&cøè&—˜ð&dø&:0&;€&6&5h&58(&980&5@&5ÈH&5°P&0 X&4àh&5hp&58€&98ˆ&5˜&Â8 &šð¨&¡°&{ˆÈ&ÄÐ&{ è&0ˆ&¬&:0Ú&Ú&€ &4è0&´P&ÈX&3Hp&˜x&3`ˆ&€&3€ &T¨&3˜À&(È&3°à&øè&3Ð&	ø&3ð &	È(&4@&	˜H&40`&	hh&4P€&	8ˆ&4p &	¨&4À&ØÈ&4°Ø&Œà&4Ðø&L&3(&  &50&
ð8&5(H&
ÀP&5@`&
h&5Xx&
`€&5p&
,˜&5ˆ¨&œ°&5 À&hÈ&5¸Ø&,à&5Ðð&ðø&5è &¼ &6  &¤ (&6 8&ˆ @&60 P&T X&6H h& p&6` ˆ&Ü &6x  &h ¨&6˜ ¸&, À&6° Ð&ð Ø&6È è&´ ð&6à!&x!&6ø!&<! &7!0&!8&7(!H&Ä!P&7@!`&ˆ!h&7X!x&\!€&7p!&(!˜&7ˆ!¨&ü!°&7 !À&È!È&7¸!Ø&œ!à&7Ð!ð&h!ø&7è"&<"&8" &"(&8"8&
Ü"@&80"P&
¨"X&8H"p&
t"x&8`"&
8"˜&8€"°&
"¸&8 "Ð&'D"Ø&8À"è&&ð"ð&8à#&&¬#&8ø#&&|# &9#0&&8#8&9(#H&&#P&9@#`&%¼#h&9X#x&%d#€&9p#&%#˜&9ˆ#°&$ #¸&9 #Ð&$l#Ø&9À#ð&$#ø&9à$&#ô$&:$(&#Ì$0&:$H&#°$P&:8$`&"@$h&:X$x& 0$€&:p$&ˆ$˜&:ˆ$¨&8$°&: $À&`$È&:¸$à&t$ð&:Ð%&t%&:ø% &,%(&;%@&%H&0%X&t%h&;P%x&t%ˆ&;p%˜&t%¨&;%¸&t%È&;°%Ø&t%è&;Ð%ø&t&&;ð&&t&(&<&8&t&H&<0&X&t&h&<P&x&t&ˆ&<p&˜&t&¨&<&À&t&Ð&<°&à&t&ð&<Ø'&t'&<ø' &t'0&='@&t'P&=8'`&t'p&=X'€&t'&=x' &t'°&=˜'À&¬'È&='Ð&6Ø'Ø&:0'à&=¸'ð&¬'ø&=((&6Ø(&:0(&=è( &¬((&=H(0&6Ø(8&:0(@&>(P&¬(X&=h(`&6Ø(h&:0(p&>H(€&¬(ˆ&=ˆ(&6Ø(˜&:0( &>x(°&¬(¸&=È(À&6¨(È&:0(Ð&>¨(à&¬(è&=ø(ð&6¨(ø&:0)&>Ø)&¬)&>() &6¨)(&:0)0&?)@&¬)H&>X)P&6¨)X&:0)`&?8)p&¬)x&>ˆ)€&6¨)ˆ&:0)&?h) &¬)¨&=)°&6¨)¸&:0)À&?˜)Ð&¬)Ø&=()à&6¨)è&:0)ð&?È*&¬*&=H*&6¨*&:0* &?ø*0&¬*8&=h*@&6¨*H&:0*P&@(*`&¬*h&=ˆ*p&6¨*x&:0*€&@X*&¬*˜&?¨* &:0*¨&@ˆ*¸&¬*À&@h*È&:0*Ð&@°*à&¬*è&=*ð&6À*ø&:0+&@Ø+&¬+&=ˆ+ &6À+(&:0+0&A+@&¬+H&=È+P&:0+X&A8+h&¬+p&>ˆ+x&:0+€&A`+&¬+˜&>¸+ &:0+¨&Aˆ+¸&¬+À&?x+È&:0+Ð&A°+à&¬+è&5ø+ð&@À+ø&5h,&5à,&7€,&@À,&7˜, &:0,(&AØ,@&¬,H&5ø,P&@À,X&5h,`&5h,h&7°,p&6¨,x&58,ˆ&78,&5à,˜&:0, &B0,°&¬,¸&5h,À&5,Ð&5h,Ø&:0,à&B¨,ð&¬,ø&5È-&5€-&:0-&Bè- &¬-(&5€-0&5€-8&:0-@&C-P&¬-X&;À-`&5˜-h&;À-p&5˜-x&;À-€&5˜-ˆ&:0-&CH- &¬-¨&;à-°&5˜-¸&;à-À&5˜-È&:0-Ð&C˜-à&¬-è&5°-ð&5°-ø&:0.&CØ.&¬.&5°. &5°.(&5°.0&:0.8&D.H&¬.P&5È.X&5°.`&:0.h&D@.x&¬.€&;€.ˆ&6X.&:0.˜&Dp.¨&¬.°&5à.¸&5È.À&5ø.È&5È.Ð&:0.Ø&D .è&¬.ð&5È.ø&5à/&5È/&5ø/&:0/&Dà/(&¬/0&5à/8&Dð/@&5ø/H&Dð/P&:0/X&E /h&¬/p&5à/x&5à/€&E0/ˆ&5ø/&5ø/˜&E0/ &:0/¨&E`/¸&¬/À&5h/È&B¸/Ð&5/à&D°/è&5à/ð&; /ø&6À0&4à0&B¸0&50(&5ø00&Dð08&; 0@&6À0H&4à0X&:00`&E°0p&¬0x&5h0€&B¸0ˆ&50˜&5à0 &D°0¨&5ø0°&5È0¸&5à0À&; 0È&6À0Ð&4à0à&B¸0è&50ø&5ø1&5È1&; 1&6À1&4à1(&:010&Fh1@&¬1H&5ø1P&D°1X&5à1`&5È1h&5à1p&5à1x&:01€&G81&¬1˜&5ø1 &5ø1¨&5ø1°&D°1¸&5à1À&5È1È&:01Ð&Gˆ1à&¬1è&5ø1ð&5ø1ø&62&5€2&5à2&D°2&5à2 &5È2(&:020&GØ2@&œ2H&H82X&¬2`&; 2h&6ð2p&:02x&HP2ˆ&¬2&; 2˜&72 &:02¨&H€2¸&¬2À&; 2È&7 2Ð&:02Ø&H°2è&¬2ð&6ð2ø&:03&Hà3&¬3&73 &:03(&I38&¬3@&7 3H&:03P&I03`&¬3h&;`3p&7h3x&:03€&IX3&¬3˜&Ih3 &:03¨&Iˆ3¸&t3È&I°3Ø&t3è&IÐ3ø&¬4&5È4&8ð4&:04&Ið4(&¬40&5È48&94@&:04H&J 4X&¬4`&J4h&9P4p&:04x&JP4ˆ&¬4&984˜&9P4 &:04¨&J€4¸&¬4À&8ð4È&9P4Ð&:04Ø&J°4è&¬4ð&;€4ø&J`5&:05&Jà5&¬5 &;€5(&J50&:058&K5H&¬5P&;€5X&J5`&:05h&K@5x&¬5€&;€5ˆ&JÀ5&:05˜&Kp5¨&¬5°&J05¸&9P5À&:05È&K 5Ø&¬5à&95è&9P5ð&:05ø&KÐ6&¬6&D°6&5h6 &D°6(&JÀ60&56@&Cè6H&Ià6P&:6X&J6`&56p&Ià6x&:6€&IÀ6ˆ&:06&L6¨&¬6°&; 6¸&6¨6À&L6È&:06Ð&L˜6à&¬6è&H`6ð&5€6ø&9 7&6À7&5à7&H`7&5ø7 &:07(&LØ78&¬7@&5à7H&H7P&67X&587h&6ð7p&7P7x&5ø7€&H7ˆ&:07&M07 &¬7¨&5à7°&H7¸&67À&587Ð&6ð7Ø&7P7à&5ø7è&HÀ7ð&:07ø&M˜8&¬8&;€8&5È8 &6À8(&:080&N8@&¬8H&5h8P&9 8X&58h&N8p&:08x&N88ˆ&¬8&C(8˜&8ð8 &58°&5È8¸&5°8À&:08È&N€8Ø&¬8à&C(8è&98ð&59&5È9&5°9&:09&NÐ9(&¬90&C(98&J9@&59P&5È9X&5°9`&:09h&O 9x&¬9€&6Ø9ˆ&:09&Op9 &¬9¨&; 9°&6¨9¸&:09À&O˜9Ð&¬9Ø&; 9à&6À9è&:09ð&OÈ:&¬:&;À:&6¨:&:0: &Oø:0&¬:8&;À:@&6À:H&:0:P&P(:`&¬:h&O¨:p&;`:x&78:€&:0:ˆ&PX:˜&¬: &5€:¨&6¨:°&5È:¸&:0:À&P:Ð&¬:Ø&5h:à&9 :è&:0:ð&PÈ;&¬;&Ih;&5à; &N;(&5h;0&9P;8&5ø;@&5È;H&6À;P&:0;X&Pø;h&¬;p&5h;x&9 ;€&5;&Q;˜&:0; &Q`;°&¬;¸&5È;À&5à;È&5h;Ð&5à;Ø&6¨;à&5h;è&5ø;ð&9;ø&5ø<&5È<&6À<&:0<&Q¨<(&¬<0&5à<8&Q¸<@&5ø<H&6¨<P&:0<X&R <h&¬<p&Q<x&R0<€&:0<ˆ&R`<˜&¬< &5à<¨&5h<°&9 <¸&5à<À&Lè<È&5ø<Ð&5<à&6<è&Q¸<ð&5ø<ø&:0=&R=&¬=&;€= &Dð=(&58=8&;€=@&9h=H&R =P&9˜=`&5°=h&:0=p&S=€&¬=ˆ&C(=&7h=˜&5à= &5à=¨&NH=°&5ø=¸&NH=À&S=È&5ø=Ð&9 =Ø&5=è&Q=ð&:0=ø&Sx>&¬>&5à>&5h> &9 >(&5à>0&Lè>8&5ø>@&5€>H&6>P&Kà>X&7P>`&5>p&5à>x&; >€&7P>ˆ&5ø>&6>˜&6À> &5ø>¨&:0>°&T>À&¬>È&58>Ø&;€>à&9h>è&T>ð&9˜?&5°?&5È?&:0?&T¸?(&¬?0&5€?8&5à?@&5à?H&Qp?P&6?X&NH?`&TÈ?h&5ø?p&9 ?x&5?ˆ&N?&5ø?˜&9 ? &5?°&N?¸&5È?À&N?È&5È?Ð&:0?Ø&U ?è&¬?ð&5h?ø&5à@&C(@&7h@&9 @&5à@ &U0@(&5€@0&K @8&5ø@@&78@H&5@X&OØ@`&5È@h&5ø@p&6¨@x&5È@€&:@ˆ&5ø@&5°@˜&:0@ &Uà@°&¬@¸&;€@À&5È@È&TÈ@Ð&:0@Ø&V¨@è&¬@ð&5à@ø&PØA&5øA&UðA&:0A&VàA(&¬A0&VðA8&DPA@&:0AH&W AX&¬A`&VðAh&5°Ap&:0Ax&WPAˆ&¬A&5àA˜&SˆA &5øA¨&UðA°&:0A¸&W€AÈ&¬AÐ&WAØ&DPAà&:0Aè&WÀB&¬B&5hB&<€B&78B &5ÈB(&< B0&7B8&:0B@&WðBX&¬B`&5hBh&< Bp&78Bx&5ÈB€&<@Bˆ&7B&:0B˜&XHB°&¬B¸&5hBÀ&<ÈBÈ&78BÐ&5ÈBØ&<`Bà&7Bè&:0Bð&X C&¬C&X`C&5àC &XC(&5øC0&XC8&:0C@&XøCX&¬C`&X¸Ch&5àCp&X`Cx&5øC€&X`Cˆ&:0C&YHC¨&¬C°&X¸C¸&5àCÀ&YCÈ&5øCÐ&YCØ&:0Cà&Y˜Cð&¬Cø&< D&6ðD&7PD&:0D&YèD(&¬D0&<@D8&6ðD@&7PDH&:0DP&Z D`&¬Dh&YøDp&5àDx&YøD€&5øDˆ&Z0D&:0D˜&ZXD¨&¬D°&XD¸&5ÈDÀ&YøDÈ&:0DÐ&Z Dà&¬Dè&X`Dð&5ÈDø&Z0E&:0E&ZØE&¬E &<`E(&6ðE0&7PE8&:0E@&[EP&¬EX&X¸E`&5ÈEh&[ Ep&:0Ex&[HEˆ&¬E&YE˜&5ÈE &E0E¨&5ÈE°&ZhE¸&:0EÀ&[€EÐ&¬EØ&Z0Eà&5àEè&Z0Eð&5øEø&[ F&:0F&[ÈF&¬F &Y`F(&5ÈF0&E0F8&5ÈF@&[ØFH&:0FP&\F`&¬Fh&ZhFp&5àFx&ZhF€&5øFˆ&[ F&:0F˜&\XF¨&¬F°&X¸F¸&[FÀ&5ÈFÈ&[FÐ&[ FØ&:0Fà&\ Fø&¬G&=ˆG&OØG&6¨G&=ˆG &NG(&78G0&:0G8&\èGH&¬GP&5øGX&6G`&5ÈGh&5àGp&:0Gx&]@Gˆ&¬G&5øG˜&5øG &5øG¨&6G°&5ÈG¸&5àGÀ&5ÈGÈ&5àGÐ&5ÈGØ&5àGà&:0Gè&]€Gø&¬H&5øH&5øH&5øH&CèH &5àH(&:0H0&]ðH@&¬HH&BøHP&7€HX&6¨H`&5ÈHh&7˜Hp&:0Hx&^8Hˆ& ØH&^€H &¬H¨&IàH°&5ÈH¸&7˜HÀ&:0HÈ&^˜HØ&¬Hà&IÀHè&5ÈHð&7˜Hø&:0I&^ÐI&¬I&7àI &5hI(&58I8&JÀI@&5IP&58I`&6ÀIh&:0Ip&_I€&¬Iˆ&5hI&@ÀI˜&7€I &5ÈI¨&7€I°&:0I¸&_xIÈ&¬IÐ&5hIØ&5àIà&7˜Iè&5øIð&@ÀIø&7˜J&:0J&_ÀJ &¬J(&P J0&9€J@&]PJH&7àJP&Z°JX&]PJ`&7øJh&=(Jp&9¸J€&:0Jˆ&`J &¬J¨&P J°&9€JÀ&]PJÈ&8JÐ&ZèJØ&]PJà&8(Jè&=HJð&9¸K&:0K&`K &¬K(&P K0&9€K@&]PKH&8KP&[KX&]PK`&8(Kh&=HKp&9¸K€&:0Kˆ&aK &¬K¨&P K°&9€KÀ&]PKÈ&8@KÐ&\°KØ&]PKà&8XKè&=hKð&9¸L&:0L&aL &¬L(&P L0&9€L@&]PLH&8@LP&\ LX&]PL`&8XLh&=hLp&9¸L€&:0Lˆ&bL &¬L¨&P L°&9€LÀ&]PLÈ&8@LÐ&[XLØ&]PLà&8XLè&=hLð&9¸M&:0M&bM&!ŒM &cM0&¬M8&58MH&c MP&:0MX&c(Mh&¬Mp&58M€&c Mˆ&:0M&c`M¨&äM¸&c˜MÐ&äMà&cÀMð&¬Mø&6@N&5àN&c°N&7€N&5àN &6pN(&c°N0&7˜N8&:PN@&5øNH&c°NP&7˜NX&5øN`&5°Nh&;€Np&:0Nx&cèNˆ&¬N&B¸N˜&5N¨&c°N°&7€N¸&6NÀ&5øNÈ&c°NÐ&7˜NØ&5øNà&5ÈNè&5àNð&6XNø&5°O&5øO&:0O&d€O &¬O(&;`O0&dO8&:0O@&eOP&äO`&eHOp&DO€&ehO&äO &eˆO¸&DOÈ&e¨OØ&¬Oà&exOè&e˜Oð&7€Oø&:0P&eÐP&äP &fP8&¬P@&3XPH&AèPP&exPX&eXP`&7€Ph&e˜Pp&7˜Px&;€P€&AèPˆ&eÀP&:0P˜&f(P¨&tP¸&f PÈ&tPØ&fÀPè&tPø&fàQ&tQ&gQ0&tQ@&g QP&´Q`&gHQp&´Q€&ghQ&¬Q˜&P Q &9€Q°&]PQ¸&7°QÀ&gXQÈ&9˜QØ&:0Qà&gˆQð&¬Qø&gR&gXR&g8R&gXR&:0R &gèR0&¬R8&f°R@&gXRH&:0RP&h(R`&¬Rh&;€Rp&9€R€&h8Rˆ&9˜R˜&:0R &hXR°&¬R¸&5hRÀ&@˜RÈ&5ÈRÐ&7°RØ&:0Rà&h¨Rð&¬Rø&5hS&5àS&O¨S&5ÈS&5hS &6S(&7ÈS0&:hS8&5øS@&:0SH&hèSX&¬S`&5hSh&58Sx&58Sˆ&L°S&5S &58S°&6ÀS¸&:0SÀ&iPSÐ&¬SØ&5hSà&58Sð&58T&L°T&5T&58T(&6¨T0&:0T8&iÈTH&´TX&j@Th&´Tx&j`Tˆ&´T˜&j€T¨&äT¸&j TÈ&¬TÐ&jTØ&j°Tà&7˜Tè&:0Tð&jÀU&¬U&eÀU&9PU&5U(&eàU0&jÐU8&;€U@&fUH&7˜UP&IÀUX&:U`&eÀUh&;`Up&98Ux&5Uˆ&IàU&:U˜&58U¨&dU°&:0U¸&jøUÈ&äUØ&kÀUð&¬Uø&<èV&kÐV&7˜V&:0V&kàV(&¬V0&<@V8&kÐV@&7˜VH&:0VP&l V`&¬Vh&< Vp&kÐVx&7˜V€&:0Vˆ&lXV˜&¬V &0V¨&58V¸&6¨VÀ&:0VÈ&lVà&¬Vè&5hVð&58W&JW&5W&58W(&6¨W0&58W@&6¨WH&:0WP&lÐW`&¬Wh&5hWp&5àWx&V¸W€&5øWˆ&5ÈW&5àW˜&TÈW &5øW¨&:0W°&mXWÀ&¬WÈ&l WÐ&5hWØ&7˜Wà&:0Wè&m¸Wø&¬X&l X&5hX&7€X&OØX &BøX(&5ÈX0&7˜X8&7ÈX@&:0XH&mðXX&¬X`&9 Xh&5Xx&58Xˆ&nX&:0X˜&nPX¨&¬X°&kÐX¸&7€XÀ&mhXÈ&D°XÐ&lèXØ&nXà&:0Xè&n Xø&¬Y&n°Y&C(Y&7PY&5Y(&4àY8&:0Y@&nðYP&¬YX&CèY`&l Yh&5hYp&7€Yx&BøY€&6ÀYˆ&:0Y&oHY &¬Y¨&mÈY°&5hY¸&5àYÀ&NHYÈ&;€YÐ&oYØ&5øYà&n`Yè&oXYð&:0Yø&o˜Z&¬Z&kÐZ&7€Z &V¸Z(&5ÈZ0&lèZ8&nZ@&:0ZH&pZX&¬Z`&pZh&5hZp&5Z€&4àZ&:0Z˜&pPZ¨&¬Z°&5°Z¸&l ZÀ&5hZÈ&7€ZÐ&BøZØ&6ÀZà&:0Zè&p Zø&¬[&mÈ[&p`[&p°[&:0[ &pð[0&¬[8&o¨[@&g˜[H&h8[P&:0[X&q([h&¬[p&q8[x&:0[€&q`[&¬[˜&q[ &g˜[¨&h8[°&:0[¸&qˆ[È&¬[Ð&5È[Ø&o¨[à&D°[è&C([ð&8ð[ø&5\&5€\&6À\&hh\ &4à\0&5°\8&g˜\@&:0\H&qÀ\X&¬\`&5È\h&q\p&D°\x&C(\€&8ð\ˆ&5\˜&5€\ &6À\¨&hh\°&4à\À&5°\È&g˜\Ð&:0\Ø&rP\è&¬\ð&kÐ\ø&7€]&5È]&kø]&q8]&kÐ] &7˜](&:0]0&rà]@&¬]H&kÐ]P&7€]X&5È]`&l0]h&q8]p&kÐ]x&7˜]€&:0]ˆ&s8]˜&¬] &6@]¨&5h]°&9 ]¸&5]È&5°]Ð&:]Ø&;€]à&9€]ð&6@]ø&]P^&6À^&OØ^&5˜^&q8^ &9˜^0&:0^8&s^H&¬^P&7€^X&q8^`&:0^h&t@^x&¬^€&5€^ˆ&i`^&5h^˜&58^¨&58^¸&L°^À&5^Ð&58^à&6À^è&58^ø&6À_&5h_&D°_&;€_&5È_ &L_(&5_8&DP_@&IÀ_H&4à_X&5°_`&Ià_h&:0_p&tp_ˆ&¬_&5h_˜&9P_ &5_°&:_¸&5€_À&7°_È&kÐ_Ð&7€_Ø&t€_à&5_ð&5È_ø&5à`&5È`&5à`&5à`&kÐ` &7€`(&O€`0&5È`8&kÐ`@&7€`H&S`P&D°`X&6¨``&5ø`h&;€`p&R0`x&5ø`€&@˜`ˆ&5ø`&OØ`˜&4à`¨&5°`°&:0`¸&ux`Ð&¬`Ø&5h`à&9P`è&5`ø&5°a&5°a&IÀa&:a&5àa &5ha(&5àa0&7°a8&58aH&98aP&5haX&5ah&5øap&@˜ax&5øa€&OØaˆ&5ha&9Pa˜&5a¨&5°a°&5°a¸&5°aÀ&IÀaÈ&:aÐ&5àaØ&5àaà&;€aè&;€að&5øaø&5øb&ub&DPb&9Pb&5b(&5°b0&5Èb8&5bH&NbP&IàbX&:b`&5°bh&5°bp&5°bx&IÀb€&:0bˆ&vÀb˜&¬b &0b¨&6¨b°&Aèb¸&0bÀ&:0bÈ&xbØ&¬bà&0bè&7˜bð&=ˆbø&x c&:0c&xÐc&¬c &0c(&7Èc0&=c8&x c@&:0cH&ycX&¬c`&0ch&7øcp&=(cx&x c€&:0cˆ&yPc˜&¬c &0c¨&8(c°&=Hc¸&x cÀ&:0cÈ&ycØ&¬cà&0cè&8Xcð&=hcø&x d&:0d&yÐd&¬d &0d(&=ˆd0&OØd8&78d@&5dP&;€dX&y d`&4àdp&:0dx&zdˆ&¬d&C(d˜&7Èd &@˜d¨&5Èd°&AHd¸&P dÀ&9€dÐ&5hdØ&7°dà&]Pdè&7Èdð&@˜dø&; e&AHe&9¸e&5°e &:0e(&z€e@&¬eH&0eP&5€eX&O¨e`&AHeh&x ep&zex&:0e€&{0e&¬e˜&:0e &2¸e¸&DeÀ&2àeÈ&{¨eØ&¬eà&{Àeè&@Àeð&:0eø&{Ðf&äf&2àf˜&|f°&Df¸&| fÀ&| fØ&¬fà&@Àfè&:0fð&|Èg&¬g&@˜g&5hg&7°g &O¨g(&A˜g0&]g8&:0g@&|øgP&¬gX&|àg`&}gh&:0gp&}Hgˆ&¬g&@˜g˜&h¸g &:0g¨&}xg¸&ägÈ&}°gà&´gð&}Ðh&¬h&z h&0h&{àh &7€h(&xàh0&}Àh8&7˜h@&;€hH&y hP&{HhX&z h`&:0hh&}øhx&¬h€&}Àhˆ&7€h&|àh˜&}h &}èh¨&}Àh°&7€h¸&{àhÀ&7˜hÈ&:0hÐ&~phè&ähð&~Øi&´i&~øi(&¬i0&5hi8&5iH&5àiP&C(iX&6i`&|àih&}ip&~ðix&5iˆ&Cèi&5øi˜&:i &5øi¨&7€i°&4àiÀ&DiÈ&IàiÐ&:0iØ&ið&¬iø&|¸j&5hj&5àj&|j&Kàj &5j0&C(j8&6j@&7€jH&@ÀjP&7€jX&j`&B¸jh&5jx&DPj€&DPjˆ&5øj&5°j˜&:j &5øj¨&Aj°&4àjÀ&5øjÈ&DjÐ&;€jØ&:0jà&àjø&¬k&øk&5hk&5k &|àk(&5hk0&}k8&5Èk@&7°kH&IÀkP&:0kX&€èkh&¬kp&C(kx&k€&5k&5°k˜&DPk &DPk¨&IÀk°&4àkÀ&IàkÈ&:0kÐ&`kè&tkø&Øl&¬l&ðl &78l(&K l0&:0l8&‚lP&¬lX&{àl`&7€lh&@Àlp&5hlx&7°l€&ðlˆ&7Pl&5Èl˜&7Èl &:0l¨&‚@lÀ&¬lÈ&5ÈlÐ&;€lØ&9€lè&5€lð&]Plø&6¨m&7°m&5€m&5hm&f°m &98m(&5m8&J`m@&4àmP&98mX&5mh&]Pmp&^mx&DPm€&DPmˆ&IÀm&:m˜&9˜m¨&5°m°&5°m¸&IàmÀ&:0mÈ&‚°mØ&¬mà&5àmè&exmð&fmø&7€n&6¨n&j°n&7€n&fn &7€n(&6Àn0&C(n8&5øn@&‚ÈnH&5nX&DPn`&5hnh&; np&6¨nx&4ànˆ&5hn&fn˜&^Hn &:0n¨&ƒÐn¸&¬nÀ&exnÈ&j°nÐ&7€nØ&5hnà&fnè&7€nð&Jnø&5o&5€o&fo&7€o &6¨o(&7°o0&f°o8&J`o@&5oP&; oX&fo`&^Hoh&4àox&5°o€&5°oˆ&:0o&„°o¨&¬o°&„Ào¸&f°oÀ&ƒàoÈ&:0oÐ&…˜oè&äoø&…Øp&¬p&3xp&…ðp &7€p(&58p8&6Øp@&6¨pH&…ðpP&7€pX&; p`&6¨ph&5hpp&58p€&98pˆ&5p˜&5°p &;€p¨&…ðp°&7˜p¸&:0pÀ&†pÐ&¬pØ&†pà&5àpè&ƒàpð&5hpø&6q&7Èq&P q&5øq&5hq &E0q(&9€q8&@˜q@&]PqH&7°qP&5€qX&7Èq`&9˜qp&5°qx&:0q€&†Èq&¬q˜&…°q &5°q¨&7°q°&:0q¸&‡ˆqÈ&¬qÐ&58qà&ƒàqè&Cèqð&:0qø&‡Àr&¬r&fr&7€r &OØr(&fr0&7˜r8&g8r@&ƒàrH&CèrP&:0rX&ˆrh&ärx&ˆ`rˆ&¬r&ˆpr˜&^¨r &:0r¨&ˆ€r¸&¬rÀ&58rÐ&ˆprØ&7˜rà&:0rè&ˆ°rø&¬s&ˆps&7€s&5s &:s(&58s8&ds@&:0sH&ˆðs`&¬sh&xàsp&:0sx&‰Psˆ&¬s&…°s˜&~s &5Ps¨&¬s°&‰hs¸&ˆÀsÀ&:0sÈ&‰€sà&¬sè&z sð&0sø&5Pt&¬t&‰ht&ˆÀt&:0t &‰Ðt0&¬t8&‰t@&5PtH&:0tP&‰htX&~€t`&ˆth&:0tp&Š(t€&¬tˆ&‰t&58t &ƒàt¨&5Pt°&BHt¸&‰htÀ&5htÈ&y tÐ&P tØ&9€tè&]Ptð&7°tø&y u&9˜u&z u&:0u &Šxu0&¬u8&ˆpu@&7€uH&5uX&Šˆu`&5Puh&h¸up&‰hux&:u€&58u&ƒàu˜&5hu &5àu¨&†u°&5hu¸&5àuÀ&5ÈuÈ&:huÐ&5øuØ&5øuà&:0uè&‹(uø&¬v&‹8v&C(v&6¨v&;€v &5Èv(&7Èv0&5°v8&:0v@&‹ðvP&¬vX&ˆpv`&7€vh&5vx&‹8v€&5Pvˆ&g˜v&‰hv˜&:v &58v°&ƒàv¸&g˜vÀ&:0vÈ&ŒHvØ&¬và&58vð&ƒàvø&g˜w&:0w&ŒÐw &¬w(&5øw0&@Àw8&5hw@&7€wH&‰hwP&5àwX&:0w`&wp&äw€&hw&¬w˜&ˆpw &7€w¨&; w°&ˆpw¸&^HwÀ&5wÐ&:wØ&0wà&xwè&7˜wð&3èwø&Aèx&0x&(x&¬x&:0x &ˆx0&¬x8&;`x@&ˆpxH&^HxP&ˆpxX&7€x`&5xp&:xx&(x€&:xˆ&xx&7€x˜&Aèx &0x¨&3èx°&:Px¸&:0xÀ&Ž(xØ&¬xà&0xè&5€xð&@Àxø&6Ày&5Èy&7˜y&:0y&ŽÈy(&¬y0&˜y8&5Py@&4àyH&‰hyP&0yX&;€y`&‰hyh&:0yp& y€&¬yˆ&˜y&5Py˜&5y &‰hy¨&0y°&;€y¸&‰hyÀ&:0yÈ&xyØ&¬yà&‰yè&Žàyð&Ž8yø&:0z&Ðz&¬z&‰z &5Pz(&4àz0&‰hz8&0z@&;€zH&‰hzP&5ÈzX&Žàz`&:0zh&zx&¬z€&˜zˆ&;€z&:0z˜&pz°&¬z¸&‰zÀ&5PzÈ&5°zÐ&‰hzØ&B¸zà&5zð&OØzø&5È{&à{&4à{&Ž8{ &:0{(& {8&¬{@&‰{H&O¨{P&5à{X&5P{`&5€{h&‰h{p&5P{x&98{€&‰h{ˆ&ˆ{&5P{˜&5°{ &‰h{¨&5ø{°&:0{¸&‘0{È&¬{Ð&‰{Ø&5à{à&{è&5ø{ð&:0{ø&‘À|&¬|&0| &@À|(&6À|0&‰h|8&:0|@&’|P&¬|X&˜|`&0|h&:0|p&’H|€&¬|ˆ&‰|&5P|˜&4à| &‰h|¨&’|°&Ž8|¸&:0|À&’x|Ð&¬|Ø&‰|à&5P|è&5|ð&‰h|ø&’}&Ž8}&:0}&’È} &¬}(&‰}0&ˆ}8&5È}@&:0}H&“}X&¬}`&‰}h&’ˆ}p&à}x&:0}€&“P}&ä} &“ˆ}¸&¬}À&“˜}È&7€}Ð&B¸}Ø&5}è&5h}ð&7€}ø&5È~&0~&5€~&6À~&5È~ &7˜~(&4à~8&0~@&6À~H&‰h~P&“˜~X&7˜~`&:0~h&“¨~x&¬~€&˜~ˆ&“˜~&7€~˜&0~ &5P~¨&9h~°&‰h~¸&;€~À&“˜~È&7˜~Ð&:0~Ø&”p~è&¬~ð&˜~ø&“˜&7€&5P&9€&‰h &0(&00&“˜8&7˜@&;€H&‰hP&:0X&”àh&¬p&‰x&5P€&9˜ˆ&‰h&“À˜&Ž8 &:0¨&•`¸&¬À&‰È&5PÐ&9¸Ø&‰hà&“Àè&Ž8ð&:0ø&•°€&¬€&‰€&5P€ &9Ø€(&‰h€0&“˜€8&7€€@&0€H&“˜€P&7˜€X&‰h€`&:0€h&–€x&¬€€&‰€ˆ&5P€&9ø€˜&‰h€ &“˜€¨&7€€°&0€¸&“˜€À&7˜€È&‰h€Ð&:0€Ø&–p€ð&¬€ø&5ø&ex&5à&e˜&7€ &5à(&eÀ0&5à8&j°@&7€H&5àP&fX&7€`&5àh&5àp&:0x&–à&¬˜&5ø &5ø¨&f°&7˜¸&5øÀ&j°È&7˜Ð&5øØ&Aèà&eÀè&5øð&e˜ø&7˜‚&5ø‚&Aè‚&ex‚&5à‚ &:0‚(&—€‚@&˜0‚`&˜H‚ˆ&˜h‚°&˜‚Ð&´‚à&˜¸‚ø&Dƒ&˜èƒ &¬ƒ(&;`ƒ0&Aèƒ8&™ƒ@&:0ƒH&™ƒ`&¬ƒh&;€ƒp&Aèƒx&™ƒ€&:0ƒˆ&™Pƒ &¬ƒ¨&™ƒ°&5ƒÀ&5àƒÈ&5àƒÐ&s ƒØ&5øƒà&5øƒè&:0ƒð&™„&¬„&5h„ &58„0&98„8&5„H&5P„P&˜¨„X&h¸„`&g˜„h&gx„p&5°„x&:„€&5h„ˆ&58„˜&98„ &5„°&5°„¸&:„À&˜Ø„È&:0„Ð&™ø„è&¬„ð&h8„ø&5h…&9P…&5…&™¨… &5P…(&˜@…0&4à…@&5h…H&;`…P&98…X&5…h&5P…p&˜`…x&h¸…€&g˜…ˆ&4à…˜&5h… &58…°&98…¸&5…È&cØ…Ð&7€…Ø&h¸…à&g˜…è&5°…ð&4à†&š†&gx†&:0†&šØ†0&¬†8&C(†@&†H&5†X&‚†`&5†p&DP†x&DP†€&:P†ˆ&:†&‰h†˜&C膠&:†¨&C(†°&v؆¸&5†È&g˜†Ð&58†à&d†è&5P†ð&58†ø&‰h‡&‰h‡&Cè‡&:0‡&œ ‡0&¬‡8&C(‡@&‡H&5‡X&5°‡`&DP‡h&DP‡p&:P‡x&:‡€&C(‡ˆ&v؇&5‡ &g˜‡¨&58‡¸&d‡À&5à‡È&Cè‡Ð&5ø‡Ø&:0‡à& ‡ø&¬ˆ&;€ˆ&fˆ&7˜ˆ&…°ˆ &5hˆ(&5ˆ8&ˆpˆ@&7€ˆH&5ˆX&œ8ˆ`&4àˆp&8ˆx&4àˆˆ&C舐&:0ˆ˜&1`ˆ¨&¬ˆ°&1xˆ¸&:0ˆÀ&ž ˆØ&¬ˆà&5Ȉè&5ˆø&c؉&7˜‰&58‰&d‰ &5°‰(&:0‰0&žÈ‰@&¬‰H&Šˆ‰P&5P‰X&žà‰`&‰h‰h&:0‰p&Ÿ8‰˜&Ÿx‰¸&¬‰À&†‰È&5à‰Ð&5P‰Ø&Ÿ‰à&5h‰è&7°‰ð&O¨‰ø&6Š&5ÈŠ&:hŠ&6Š&5hŠ &7°Š(&O¨Š0&6¨Š8&5ÈŠ@&5hŠH&6ŠP&7°ŠX&6¨Š`&6Šh&7ÈŠp&:hŠx&5øŠ€&:0Šˆ&Ÿ Š˜&¬Š &…°Š¨&pŠ°&9PŠ¸&5ŠÈ&ŸÀŠÐ&IÀŠØ&5ÈŠà&žàŠè&:0Šð& ‹&¬‹&;€‹&6‹&ˆ‹ &f@‹(&6@‹0&q8‹8&58‹H&gX‹P&h8‹X&k‹`&5‹p&h8‹x&5P‹€&ž‹ˆ&cø‹&5h‹˜&šð‹ &5‹°&4à‹À&:0‹È& ø‹à&´‹ð&¡ÐŒ&´Œ&¡øŒ0&´Œ@&¢ ŒX&¬Œ`&¡èŒh&C(Œp&5àŒx&5àŒ€&P Œˆ&9€Œ˜&5øŒ &6Œ¨&5ÈŒ°&5àŒ¸&6ŒÀ&6ÀŒÈ&6ŒÐ&5ÈŒØ&C(Œà&g8Œè&‚ÈŒð&5&DP&5h&5à&1x &5ø(&O¨0&9¸@&5øH&5øP&¢X&:0`&¢Hx&¬€&…°ˆ&¢`&:0˜&£h°&¬¸&~À&5PÈ&čÐ&‰hØ&5Pà&{˜è&@Àð&‰hø&~€Ž&:0Ž&£ Ž&¬Ž &…°Ž(&£¸Ž0&:0Ž8&¤ŽP&¬ŽX&5øŽ`&@ÀŽh&}ÀŽp&7€Žx&}XŽ€&@ÀŽˆ&7˜Ž&:0Ž˜&¤@Ž¨&¬Ž°&5PŽ¸&¤XŽÀ&‰hŽÈ&:0ŽÐ&¤ Žè&¬Žð&…°Žø&~&5P&t&‰h&‰h &~€(&:00&¤Ø@&¬H&…°P&~X&5P`&Dh&‰hp&‰hx&~€€&:0ˆ&¥8 &¬¨&…°°&~¸&5PÀ&äÈ&‰hÐ&;€Ø&‰hà&~€è&:0ð&¥&¬&…°&~ &5P(&´0&‰h8&x @&~€H&:0P&¥ø`&¬h&…°p&~x&5P€&´ˆ&‰h&5P˜&e( &‰h¨&~€°&:0¸&¦XÈ&¬Ð&…°Ø&~à&5Pè&¤ð&‰hø&  ‘&‰h‘&~€‘&:0‘&¦À‘(&¬‘0&;€‘8&:0‘@&§ ‘X&¬‘`&5°‘h&:0‘p&§H‘€&¬‘ˆ&…°‘&~‘˜&5P‘ &‘¨&‰h‘°&5€‘¸&xà‘À&6¨‘È&~€‘Ð&:0‘Ø&§x‘ð&¬‘ø&5P’&58’&‰h’&‰h’&:0’ &§à’8&¬’@&  ’H&‰h’P&:0’X&¨(’p&¬’x&…°’€&C(’ˆ&’&9P’˜&5’¨&ŸÀ’°&IÀ’¸&5È’À&žà’È&‚’Ð&9P’Ø&5’è&5P’ð&5P’ø&‰h“&‰h“&5P“&‰h“&‰h“ &Cè“(&:0“0&¨`“@&¬“H&‡˜“P&§ø“X&:0“`&©8“p&¬“x&  “€&5P“ˆ&5P“&‰h“˜&‰h“ &:0“¨&©h“¸&¬“À&5h“È&h¸“Ð&“Ø&5“è&D°“ð&5°“ø&IÀ”&5È”&‚”&5” &N”(&:”0&Ià”8&:”@&:0”H&©°”X&¬”`&  ”h&ˆp”p&7€”x&5”ˆ&5P”&A蔘&‰h” &‰h”¨&:”°&@À”¸&7˜”À&:0”È&ªP”à&¬”è&@À”ð&7€”ø&:0•&ªÐ•&¬•&;À• &Ap•(&6¨•0&:0•8&«•H&¬•P&;À•X&Ap•`&6À•h&:0•p&«@•ˆ&¬•&~€•˜&:0• &«x•¸&¬•À&}À•È&7€•Ð&}X•Ø&‰h•à&:0•è&«¨•ø&¬–&…°–&kЖ&7€–&5à– &kø–(&1x–0&5ø–8&kЖ@&7˜–H&:0–P&«ð–`&¬–h&…°–p&kЖx&7€–€&5à–ˆ&l0–&1x–˜&5ø– &kЖ¨&7˜–°&:0–¸&¬X–È&¬–Ð&…°–Ø&kЖà&7€–è&5à–ð&lh–ø&1x—&5ø—&kЗ&7˜—&:0— &¬À—8&4—@&­(—X&—`&­H—x&Ì—€&­h—˜&€— &­ˆ—¸&H—À&­¨—Ø&—à&­È—ø&¸˜&­è˜ &¤˜(&®˜@&˜H&®0˜X&„˜`&®P˜p&<˜x&®h˜ˆ&˜&®€˜ &À˜¨&®˜˜¸&Œ˜À&®°˜Ð&D˜Ø&®È˜è&˜ð&®à™&Ì™&®ø™(&l™0&¯™@&$™H&¯8™`&h™h&¯P™ˆ&ð™&¯p™°&à™¸&¯˜™Ø&°™à&¯Àš&pš&¯èš(&(š0&°šP&ôšX&°8šx&Àš€&°`š &dš¨&°ˆšÈ&šÐ&°°šð&ôšø&°Ø›&À› &±›@&H›H&±(›`&¤›h&±P›ˆ&p›&±p›¨&(›°&±˜›Ð&ø›Ø&±¸›ø&Äœ&±àœ &Gœ(&²œH&FÈœP&²0œp&F”œx&²Xœ˜&F`œ &²€œÀ&FœÈ&²¨œè&Eèœð&²Ð&E´&²ø8&E@&³ `&Elh&³Hˆ&EH&³p¨&E°&³˜È&DàÐ&³¸è&D¬ð&³Øž&Dxž&³øž(&DDž0&´žP&DžX&´8žp&CÜžx&´`ž&C¨ž˜&´€ž°&Ctž¸&´ žØ&C(žà&´ÀŸ&B¸Ÿ&´èŸ &B€Ÿ(&µŸH&B4ŸP&µ0Ÿh&AôŸp&µXŸ&A¨Ÿ˜&µxŸ¸&AhŸÀ&µ Ÿà&@ôŸè&µÈ &A &µð (&@œ 0&¶ P&@8 X&¶8 p&@ x&¶` &?0 ˜&¶€ °&?Р¸&¶  Ð&>ô Ø&¶À ð&?œ ø&¶à¡&>¸¡&·¡0&?l¡8&· ¡P&>|¡X&·@¡x&<˜¡€&·`¡˜&<P¡ &·ˆ¡¸&<t¡À&·¨¡à&>¡è&·È¢&=¤¢&·ð¢8&=$¢@&¸ ¢h&<¼¢p&¸H¢&9À¢˜&¸x¢¸&9d¢À&¸ ¢à&;¼¢è&¸È£&;(£&¸ð£0&:°£8&¹£X&:£`&¹@£€&9£ˆ&¹h£ &8Ô£¨&¹£À&8œ£È&¹°£à&8l£è&¹Ð¤&8<¤&¹ð¤ &8¤(&º¤@&7¤H&º0¤`&7\¤h&ºP¤€&7¤ˆ&ºp¤ &6Ĥ¨&º¤À&6p¤È&º°¤à&6<¤è&ºÐ¥&5ü¥&ºð¥ &5¼¥(&»¥@&58¥H&»0¥`&4Ø¥h&»P¥€&4”¥ˆ&»p¥ &4p¥¨&»¥À&48¥È&»°¥à&4¥è&»Ð¦&3ܦ&»ð¦0&3œ¦8&¼¦X&2ô¦`&¼@¦ˆ&2°¦&¼h¦°&2`¦¸&¼˜¦Ð&2(¦Ø&¼À¦ø&1ð§&¼à§(&3d§0&½§X&3,§`&½8§x&1̧€&½h§ &1ˆ§¨&½ˆ§È&1D§Ð&½°§ð&1§ø&½Ø¨(&0¨0&¾¨P&0¨X&¾8¨h&/̨p&¾`¨€&/œ¨ˆ&¾x¨˜&/d¨ &¾¨°&/4¨¸&¾¨¨È&.ü¨Ð&¾À¨à&.̨è&¾Ø¨ø&.œ©&¾ð©&.l©&¿©(&.©0&¿ ©@&.<©H&¿8©X&-¬©`&¿P©p&-Ü©x&¿h©ˆ&-|©&¿€© &-L©¨&¿˜©¸&-©À&¿°©Ð&,ì©Ø&¿È©è&,Œ©ð&¿àª&,¼ª&¿øª&,,ª &Àª0&,\ª8&À(ªH&+̪P&À@ª`&+üªh&ÀXªx&+lª€&Àpª&+œª˜&Àˆª¨&+ª°&À ªÀ&+<ªÈ&À¸ªØ&*¬ªà&ÀЪð&*ܪø&Àè«&*L«&Á«0&*|«8&Á «P&)ì«X&Á@«p&*«x&Á`«ˆ&'«&Á€« &'À«¨&Á˜«¸&)´«À&Á°«Ð&)€«Ø&ÁÈ«è&)@«ð&0(¬&)¬&Áø¬0&´¬@&0X¬`&t¬h&¬p&ÂH¬&¬¬˜&Âh¬ &7€¬¨&:0¬°&Âx¬À&(`¬È&¸¬à&(´¬è&ÂЭ&'ð­&Âð­(&P­0&íH&­P&Ã8­h&È­p&ÃX­€&)­ˆ&Ãx­˜&ä­¨&Э¸&¬­À&à­È&7€­Ð&7È­Ø&58­è&à­ð&^H­ø&:0®&ð® &´H¸&`HÀ&hHÈ&pHÐ&€HØ&˜Hà& Hè&¸Hð&ÈHø&ØI&èI&øI&øI&I &I(&(I0&(I8&PI@&
àIH&
 IP&
IX&
hI`&
°Ih&
8Ip&
˜Ix&
PI€&
ÈI˜& I &¸I¨&XI°&I¸&pIÀ&ÐIÈ&@IÐ& IØ&(Iø&J&øJ&°J &8J(&hJ0&PJ8&ðJ@&€Jp&J& J°& JÐ&(Jð&@K&@K0&PKP&`Kp&pK&ˆK°& KÈ&¸Kà&ÐKø&àL&L(& L@&@LX&`Lp&€Lˆ&L & L¸&°LÐ&ÀLè&ÐM&àM&ðM0&MH&M`& Mx&0M&@M¨&HMÀ&XMØ&hMð&xNH&(NP–&N`&(˜Nh&Nx&( N€N&N&(¨N˜i&N¨&(°NÀ&(¸NØ&(ÈNð&(ØO€&«oðO &«p@.symtab.strtab.shstrtab.rela.slof.loader.rela.text.rela.opd.got.rela.data.comment.bss d@† h2Á¼ -@‡ˆ³¨=ÄÄ%ø8@	;0KðBéøéøLéøéøeÜG@	‡ SØR0OÔOÔ%[POÔ«pP"P

	rPÉ
Úø`ÿÿÿÿÿÿÿÿH0bootinfoÿÿÿÿÿÿÿÿ<<_(ide.fs1 encode-int s" #address-cells" property
0 encode-int s" #size-cells" property
: decode-unit  1 hex-decode-unit ;
: encode-unit  1 hex-encode-unit ;
0 VALUE >ata                                 \ base address for command-block
0 VALUE >ata1                                \ base address for control block
true VALUE no-timeout                        \ flag that no timeout occurred
0c  CONSTANT #cdb-bytes                      \ command descriptor block (12 bytes)
800 CONSTANT atapi-size
200 CONSTANT ata-size
: ata-ctrl! 2 >ata1 + io-c! ;                      \ device control reg
: ata-astat@ 2 >ata1 + io-c@ ;                     \ read alternate status
: ata-data@ 0 >ata + io-w@ ;                       \ data reg
: ata-data! 0 >ata + io-w! ;                       \ data reg
: ata-err@  1 >ata + io-c@ ;                       \ error reg
: ata-feat! 1 >ata + io-c! ;                       \ feature reg
: ata-cnt@  2 >ata + io-c@ ;                       \ sector count reg
: ata-cnt!  2 >ata + io-c! ;                       \ sector count reg
: ata-lbal! 3 >ata + io-c! ;                       \ lba low reg
: ata-lbal@ 3 >ata + io-c@ ;                       \ lba low reg
: ata-lbam! 4 >ata + io-c! ;                       \ lba mid reg
: ata-lbam@ 4 >ata + io-c@ ;                       \ lba mid reg
: ata-lbah! 5 >ata + io-c! ;                       \ lba high reg
: ata-lbah@ 5 >ata + io-c@ ;                       \ lba high reg
: ata-dev!  6 >ata + io-c! ;                       \ device reg
: ata-dev@  6 >ata + io-c@ ;                       \ device reg
: ata-cmd!  7 >ata + io-c! ;                       \ command reg
: ata-stat@ 7 >ata + io-c@ ;                       \ status reg
00 CONSTANT cmd#nop                                \ ATA and ATAPI
08 CONSTANT cmd#device-reset                       \ ATAPI only (mandatory)
20 CONSTANT cmd#read-sector                        \ ATA and ATAPI
90 CONSTANT cmd#execute-device-diagnostic          \ ATA and ATAPI
a0 CONSTANT cmd#packet                             \ ATAPI only (mandatory)
a1 CONSTANT cmd#identify-packet-device             \ ATAPI only (mandatory)
ec CONSTANT cmd#identify-device                    \ ATA and ATAPI
: set-regs ( n -- )
dup
01 and                                    \ only Chan 0 or Chan 1 allowed
3 lshift dup 10 + config-l@ -4 and to >ata
14 + config-l@ -4 and to >ata1
02 ata-ctrl!                              \ disable interrupts
02 and
IF
10
ELSE
00
THEN
ata-dev!
;
ata-size VALUE block-size
80000    VALUE max-transfer            \ Arbitrary, really
CREATE sector d# 512 allot
CREATE packet-cdb #cdb-bytes allot
CREATE return-buffer atapi-size allot
scsi-open                             \ add scsi functions
: show-regs
cr
cr ." alt. Status: " ata-astat@ .
cr ." Status     : " ata-stat@ .
cr ." Device     : " ata-dev@ .
cr ." Error-Reg  : " ata-err@ .
cr ." Sect-Count : " ata-cnt@ .
cr ." LBA-Low    : " ata-lbal@ .
cr ." LBA-Med    : " ata-lbam@ .
cr ." LBA-High   : " ata-lbah@ .
;
: status-check               ( -- )
ata-stat@
dup   
01 and                                    \ is 'check' flag set ?
IF
cr
."    - ATAPI-Status: " .
ata-err@                               \ retrieve sense code
dup
60 =                                   \ sense code = 6 ?
IF
." ( media changed or reset )"      \ 'unit attention'
drop                                \ drop err-reg content
ELSE
dup
." (Err : " .                       \ show err-reg content
space
rshift 4 .sense-text                \ show text string
29 emit
THEN
cr
ELSE
drop                                   \ remove unused status      
THEN      
;
: wait-for-ready
get-msecs                                 \ start timer
BEGIN
ata-stat@ 80 and 0<>                   \ busy flag still set ?
no-timeout and
WHILE                                  \ yes
dup get-msecs swap
-                                   \ calculate timer difference
FFFF AND                            \ reduce to 65.5 seconds
d# 5000 >                           \ difference > 5 seconds ?
IF
false to no-timeout
THEN
REPEAT
drop
;
: wait-for-status          ( val mask -- )
get-msecs                                 \ initial timer value (start)
>r
BEGIN
2dup                                   \ val mask
ata-stat@ and <>                       \ expected status ?
no-timeout and                         \ and no timeout ?
WHILE      
get-msecs r@ -                         \ calculate timer difference
FFFF AND                               \ mask-off overflow bits
d# 5000 >                              \ 5 seconds exceeded ?
IF
false to no-timeout                 \ set global flag
THEN      
REPEAT                  
r>                                        \ clean return stack
3drop
;
: cut-string      ( saddr nul -- )
swap
over +
swap   
1 rshift                                  \ bytecount -> wordcount
0 do
/w -
dup               ( addr -- addr addr )
w@                ( addr addr -- addr nuw )
dup               ( addr nuw -- addr nuw nuw )
2020 =
IF
drop
0 
ELSE
LEAVE         
THEN
over         
w!
LOOP
drop
drop
; 
: show-model          ( dev# chan# -- )
2dup
."    CH " .                  \ channel 0 / 1
0= IF ." / MA"                \ Master / Slave
ELSE  ." / SL"
THEN
swap
2 * + ."  (@" . ." ) : "      \ device number
sector 1 +
c@
80 AND 0=
IF
." ATA-Drive    "
ELSE
." ATAPI-Drive  "
THEN
22 emit                       \ start string display with "
sector d# 54 +                \ string starts 54 bytes from buffer start
dup
d# 40                         \ and is 40 chars long
cut-string                    \ remove all trailing spaces
BEGIN
dup
w@
wbflip
wbsplit
dup 0<>                    \ first char
IF                   
emit
dup 0<>                 \ second char
IF
emit
wa1+                 \ increment address for next
false
ELSE                    \ second char = EndOfString
drop
true
THEN   
ELSE                       \ first char = EndOfString
drop
drop
true
THEN
UNTIL                         \ end of string detected
drop
22 emit                       \ end string display
sector c@                     \ get lower byte of first doublet
80 AND                        \ check bit 7
IF
."  (removable media)"
THEN
sector 1 +
c@
80 AND 0= IF                  \ is this an ATA drive ?
sector d# 120 +            \ get word 60 + 61
rl@-le                     \ read 32-bit as little endian value
d# 512                     \ standard ATA block-size
swap
.capacity-text ( block-size #blocks -- )
THEN
sector d# 98 +               \ goto word 49
w@
wbflip
200 and 0= IF cr ."    ** LBA is not supported " THEN   
sector c@                     \ get lower byte of first doublet
03 AND 01 =                   \ we use 12-byte packet commands (=00b)
IF
cr ."    packet size = 16 ** not supported ! **"
THEN
no-timeout not                \ any timeout occurred so far ?
IF
cr   ."    ** timeout **"
THEN
;
: pio-sector ( addr -- )  100 0 DO ata-data@
over w! wa1+ LOOP drop ;
: pio-sector ( addr -- ) 
wait-for-ready pio-sector ;
: pio-sectors ( n addr -- )  swap 0 ?DO dup pio-sector 200 + LOOP drop ;
: lba!  lbsplit   
0f and 40 or                  \ always set LBA-mode + LBA (27..24)
ata-dev@ 10 and or            \ add current device-bit (DEV)
ata-dev!                      \ set LBA (27..24)
ata-lbah!                     \ set LBA (23..16)
ata-lbam!                     \ set LBA (15..8)
ata-lbal!                     \ set LBA (7..0)
;
: read-sectors ( lba count addr -- ) 
>r dup >r ata-cnt! lba! 20 ata-cmd! r> r> pio-sectors ;
: read-sectors ( lba count addr dev-nr -- )
set-regs             ( lba count addr ) \ Set ata regs 
BEGIN >r dup 100 > WHILE
over 100 r@ read-sectors
>r 100 + r> 100 - r> 20000 + REPEAT
r> read-sectors
;
: ata-read-blocks                ( addr block# #blocks dev# -- #read )
swap dup >r swap >r rot r>    ( addr block# #blocks dev # R: #blocks )
read-sectors r>               ( R: #read )
;    
: set-lba                              ( block-length -- )
lbsplit                             ( quad -- b1.lo b2 b3 b4.hi )
drop                                \ skip upper two bytes
drop
ata-lbah!
ata-lbam!
;
: read-pio-block                        ( buff-addr -- buff-addr-new )
ata-lbah@ 8 lshift                  \ get block length High
ata-lbam@ or                        \ get block length Low
1 rshift                            \ bcount -> wcount
dup
0> IF                               \ any data to transfer?
0 DO                             \ words to read
dup                           \ buffer-address
ata-data@ swap w!             \ write 16-bits
wa1+                          \ address of next entry
LOOP
ELSE
drop                          ( buff-addr wcount -- buff-addr )
THEN
wait-for-ready
;
: send-atapi-packet                    ( req-buffer -- )
>r                                  (   R: req-buffer )
atapi-size set-lba                  \ set regs to length limit
00 ata-feat!
cmd#packet ata-cmd!                 \ A0 = ATAPI packet command
48 C8  wait-for-status     ( val mask -- )  \ BSY:0 DRDY:1 DRQ:1
6 0  do
packet-cdb i 2 * +                \ transfer command block (12 bytes)
w@
ata-data!                        \ 6 doublets PIO transfer to device
loop                             \ copy packet to data-reg
status-check                        ( -- ) \ status err bit set ? -> display
wait-for-ready                      ( -- ) \ busy released ?
BEGIN
ata-stat@ 08 and 08 = WHILE         \ Data-Request-Bit set ?
r>                               \ get last target buffer address
read-pio-block                   \ only if from device requested
>r                               \ start of next block
REPEAT
r>                                  \ original value
drop                                \ return clean
;   
: atapi-packet-io                      ( -- )
return-buffer atapi-size erase      \ clear return buffer
return-buffer send-atapi-packet     \ send 'packet-cdb' , get 'return-buffer'
;
: atapi-test ( -- true|false )
packet-cdb scsi-build-test-unit-ready     \ command-code: 00
atapi-packet-io                           ( )  \ send CDB, get return-buffer
ata-stat@ 1 and IF false ELSE true THEN
;
: atapi-sense ( -- ascq asc sense-key )
d# 252 packet-cdb scsi-build-request-sense ( alloc-len cdb -- )
atapi-packet-io                           ( )  \ send CDB, get return-buffer
return-buffer scsi-get-sense-data         ( cdb-addr -- ascq asc sense-key )
;
: atapi-read-blocks                    ( address block# #blocks dev# -- #read-blocks )
set-regs                            ( address block# #blocks )
dup >r                              ( address block# #blocks )
packet-cdb scsi-build-read-10       ( address block# #blocks cdb -- )
send-atapi-packet                   ( address -- )
r>                                  \ return requested number of blocks
;
: atapi-read-capacity                        ( -- )
packet-cdb scsi-build-read-cap-10         \ fill block with command
atapi-packet-io                           ( )  \ send CDB, get return-buffer
return-buffer scsi-get-capacity-10        ( cdb -- block-size #blocks )
.capacity-text                            ( block-size #blocks -- )
status-check                              ( -- )
;
: atapi-read-capacity-ext                    ( -- )
packet-cdb scsi-build-read-cap-16         \ fill block with command
atapi-packet-io                           ( )  \ send CDB, get return-buffer
return-buffer scsi-get-capacity-16        ( cdb -- block-size #blocks )
.capacity-text                            ( block-size #blocks -- )
status-check                              ( -- )
;
: wait-for-media-ready                 ( -- true|false )
get-msecs                                 \ initial timer value (start)
>r
BEGIN
atapi-test                             \ unit ready? false if not      
not
no-timeout and
WHILE
atapi-sense  ( -- ascq asc sense-key )
02 =                                \ sense key 2 = media error
IF                                  \ check add. sense code
3A =                             \ asc: device not ready ?
IF
false to no-timeout
."  empty (" . 29 emit        \ show asc qualifier
ELSE
drop                          \ discard asc qualifier
THEN                             \ medium not present, abort waiting
ELSE
drop                             \ discard asc
drop                             \ discard ascq
THEN
get-msecs r@ -                      \ calculate timer difference
FFFF AND                            \ mask-off overflow bits
d# 5000 >                           \ 5 seconds exceeded ?
IF
false to no-timeout              \ set global flag
THEN      
REPEAT
r>
drop
no-timeout
;
2 CONSTANT #chan 
2 CONSTANT #dev
: #totaldev #dev #chan * ;
CREATE read-blocks-xt #totaldev cells allot read-blocks-xt #totaldev cells erase
: dev-read-blocks  ( address block# #blocks dev# -- #read-blocks )
dup cells read-blocks-xt + @ execute
;
: read-ident  ( -- true|false )
false
00 ata-lbal!                              \ clear previous signature
00 ata-lbam!
00 ata-lbah!
cmd#identify-device ata-cmd! wait-for-ready \ first try ATA, ATAPI aborts command
ata-stat@ CF and 48 =
IF
drop true                                          \ cmd accepted, this is a ATA
d# 512 set-lba                                     \ set LBA to sector-length
ELSE                                                  \ ATAPI sends signature instead
ata-lbam@ 14 = IF                                  \ cylinder low  = 14 ?
ata-lbah@ EB = IF                               \ cylinder high = EB ?
cmd#device-reset ata-cmd! wait-for-ready     \ only supported by ATAPI
cmd#identify-packet-device ata-cmd! wait-for-ready                     \ first try ata
ata-stat@ CF and 48 = IF               
drop true                                 \ replace flag
THEN
THEN
THEN
THEN
dup IF
ata-stat@ 8 AND IF                        \ data requested (as expected) ?      
sector read-pio-block 
drop                                   \ discard address end 
ELSE
drop false
THEN
THEN
no-timeout not IF                            \ check without any timeout ?
drop
false                                     \ no, detection discarded
THEN
;
scsi-close                             \ remove scsi commands from word list
: find-disks      ( -- )   
#chan 0 DO                                      \ check 2 channels (primary & secondary)
#dev 0 DO                                    \ check 2 devices per channel (master / slave)
i 2 * j +
set-regs                                  \ set base address and dev-register for register access
ata-stat@ 7f and 7f <>                    \ Check, if device is connected
IF
true to no-timeout                     \ preset timeout-flag
read-ident        ( -- true|false )
IF
i j show-model                      \ print manufacturer + device string
sector 1+ c@ C0 and 80 =            \ Check for ata or atapi
IF
wait-for-media-ready             \ wait up to 5 sec if not ready
no-timeout and
IF
atapi-read-capacity
atapi-size to block-size      \ ATAPI: 2048 bytes
80000 to max-transfer
['] atapi-read-blocks i 2 * j + cells read-blocks-xt + !
s" cdrom" strdup i 2 * j + s" generic-disk.fs" included
ELSE
."  -"                        \ show hint for not registered
THEN    
ELSE
ata-size to block-size           \ ATA: 512 bytes
80000 to max-transfer
['] ata-read-blocks i 2 * j + cells read-blocks-xt + !
s" disk" strdup i 2 * j + s" generic-disk.fs" included
THEN
cr
THEN    
THEN
i 2 * j + 200 + cp
LOOP
LOOP
;
find-disks
ÿÿÿÿÿÿÿÿ-P-0fbuffer.fs0 VALUE line#
0 VALUE column#
false VALUE inverse?
false VALUE inverse-screen?
18 VALUE #lines
50 VALUE #columns
false VALUE cursor
false VALUE saved-cursor
defer draw-character	\ 2B inited by display driver
defer reset-screen	\ 2B inited by display driver
defer toggle-cursor	\ 2B inited by display driver
defer erase-screen	\ 2B inited by display driver
defer blink-screen	\ 2B inited by display driver
defer invert-screen	\ 2B inited by display driver
defer insert-characters	\ 2B inited by display driver
defer delete-characters	\ 2B inited by display driver
defer insert-lines	\ 2B inited by display driver
defer delete-lines	\ 2B inited by display driver
defer draw-logo		\ 2B inited by display driver
: nop-toggle-cursor ( nop ) ;
' nop-toggle-cursor to toggle-cursor
: (cursor-off) ( -- ) cursor dup to saved-cursor
IF toggle-cursor false to cursor THEN ;
: (cursor-on) ( -- ) cursor dup to saved-cursor
0= IF toggle-cursor true to cursor THEN ;
: restore-cursor ( -- ) saved-cursor dup cursor
<> IF toggle-cursor to cursor ELSE drop THEN ;
' (cursor-off) to cursor-off
' (cursor-on) to cursor-on
false VALUE esc-on
false VALUE csi-on
defer esc-process
0 VALUE esc-num-parm
0 VALUE esc-num-parm2
0 VALUE saved-line#
0 VALUE saved-column#
: get-esc-parm ( default -- value )
esc-num-parm dup 0> IF nip ELSE drop THEN 0 to esc-num-parm ;
: get-esc-parm2 ( default -- value )
esc-num-parm2 dup 0> IF nip ELSE drop THEN 0 to esc-num-parm2 ;
: set-esc-parm ( newdigit -- ) [char] 0 - esc-num-parm a * + to esc-num-parm ;
: reverse-cursor ( oldpos -- newpos) dup IF 1 get-esc-parm - THEN ;
: advance-cursor ( bound oldpos -- newpos) tuck > IF 1 get-esc-parm + THEN ;
: erase-in-line #columns column# - dup 0> IF delete-characters ELSE drop THEN ;
: terminal-line++ ( -- )
line# 1+ dup #lines = IF 1- 0 to line# 1 delete-lines THEN
to line#
;
0 VALUE dang
0 VALUE blipp
false VALUE stopcsi
0 VALUE term-background
7 VALUE term-foreground
: set-term-color
dup d# 30 d# 39 between IF dup d# 30 - to term-foreground THEN
dup d# 40 d# 49 between IF dup d# 40 - to term-background THEN
0 = IF
0 to term-background
7 to term-foreground
THEN
term-foreground term-background <= to inverse?
;
: ansi-esc ( char -- )
csi-on IF
dup [char] 0 [char] 9 between IF set-esc-parm
ELSE true to stopcsi CASE
[char] A OF line# reverse-cursor to line# ENDOF
[char] B OF #lines line# advance-cursor to line# ENDOF
[char] C OF #columns column# advance-cursor to column# ENDOF
[char] D OF column# reverse-cursor to column# ENDOF
[char] E OF ( FIXME: Cursor Next Line - No idea what does it mean )
#lines line# advance-cursor to line#
ENDOF
[char] f OF
1 get-esc-parm2 to line# column# get-esc-parm to column#
ENDOF
[char] H OF
1 get-esc-parm2 to line# column# get-esc-parm to column#
ENDOF
[char] ; OF false to stopcsi 0 get-esc-parm to esc-num-parm2 ENDOF
[char] ? OF false to stopcsi ENDOF ( FIXME: Ignore that for now )
[char] l OF ENDOF ( FIXME: ?25l should hide cursor )
[char] h OF ENDOF ( FIXME: ?25h should show cursor )
[char] J OF
#lines line# - dup 0> IF
line# 1+ to line# delete-lines line# 1- to line#
ELSE drop THEN
erase-in-line
ENDOF
[char] K OF erase-in-line ENDOF
[char] L OF 1 get-esc-parm insert-lines ENDOF
[char] M OF 1 get-esc-parm delete-lines ENDOF
[char] @ OF 1 get-esc-parm insert-characters ENDOF
[char] P OF 1 get-esc-parm delete-characters ENDOF
[char] m OF 0 get-esc-parm set-term-color ENDOF
[char] p OF inverse-screen? IF false to inverse-screen?
inverse? 0= to inverse? invert-screen
THEN
ENDOF
[char] q OF inverse-screen? 0= IF true to inverse-screen?
inverse? 0= to inverse? invert-screen
THEN
ENDOF
[char] u OF saved-line# to line# saved-column# to column# ENDOF
dup dup to dang OF blink-screen ENDOF
ENDCASE stopcsi IF false to csi-on
false to esc-on 0 to esc-num-parm 0 to esc-num-parm2 THEN
THEN
ELSE CASE
[char] 7 OF line# to saved-line# column# to saved-column# ENDOF
[char] 8 OF saved-line# to line# saved-column# to column# ENDOF
[char] [ OF true to csi-on ENDOF
dup dup OF false to esc-on to blipp ENDOF
ENDCASE
csi-on 0= IF false to esc-on THEN 0 to esc-num-parm 0 to esc-num-parm2
THEN
;
' ansi-esc to esc-process
CREATE twtracebuf 4000 allot twtracebuf 4000 erase
twtracebuf VALUE twbp
0 VALUE twbc
0 VALUE twtrace-enabled?
: twtrace
twbc 4000 = IF 0 to twbc twtracebuf to twbp THEN
dup twbp c! twbp 1+ to twbp twbc 1+ to twbc
;
: terminal-write ( addr len -- actual-len )
cursor-off
tuck bounds ?DO i c@
twtrace-enabled? IF twtrace THEN
esc-on IF esc-process
ELSE CASE
1B OF true to esc-on ENDOF
carret OF 0 to column# ENDOF
linefeed OF terminal-line++ ENDOF
bell OF blink-screen ENDOF
9 ( TAB ) OF column# 7 + -8 and dup #columns < IF
to column#
ELSE drop THEN
ENDOF
B ( VT ) OF line# ?dup IF 1- to line# THEN ENDOF
C ( FF ) OF 0 to line# 0 to column# erase-screen ENDOF
bs OF	column# 1- dup 0< IF
line# IF
line# 1- to line#
drop #columns 1-
ELSE drop column#
THEN
THEN
to column# ( bl draw-character )
ENDOF
dup OF
i c@ draw-character
column# 1+ dup #columns >= IF
drop 0 terminal-line++
THEN
to column#
ENDOF
ENDCASE
THEN
LOOP
restore-cursor
;
0 VALUE char-height
0 VALUE char-width
0 VALUE fontbytes
CREATE display-emit-buffer 20 allot
defer dis-old-emit
' emit behavior to dis-old-emit
: display-write terminal-write ;
: display-emit dup dis-old-emit display-emit-buffer tuck c! 1 terminal-write drop ;
: is-install ( 'open -- )
s" defer vendor-open to vendor-open" eval
s" : open deadbeef vendor-open dup deadbeef = IF drop true ELSE nip THEN ;" eval
s" defer write ' display-write to write" eval
s" : draw-logo ['] draw-logo CATCH IF 2drop 2drop THEN ;" eval
s" : reset-screen ['] reset-screen CATCH drop ;" eval
;
: is-remove ( 'close -- )
s" defer close to close" eval
;
: is-selftest ( 'selftest -- )
s" defer selftest to selftest" eval
;
STRUCT
cell FIELD font>addr
cell FIELD font>width
cell FIELD font>height
cell FIELD font>advance
cell FIELD font>min-char
cell FIELD font>#glyphs
CONSTANT /font
CREATE default-font-ctrblk /font allot default-font-ctrblk
dup font>addr 0 swap !
dup font>width 8 swap !
dup font>height -10 swap !
dup font>advance 1 swap !
dup font>min-char 20 swap !
font>#glyphs 7f swap !
: display-default-font ( str len -- )
romfs-lookup dup 0= IF drop EXIT THEN
600 <> IF ." Only support 60x8x16 fonts ! " drop EXIT THEN
default-font-ctrblk font>addr !
;
s" default-font.bin" display-default-font
: .scan-lines ( height -- scanlines ) dup 0>= IF 1- ELSE negate THEN ;
: set-font ( addr width height advance min-char #glyphs -- )
default-font-ctrblk /font + /font 0
DO
1 cells - dup >r ! r> 1 cells
+LOOP drop
default-font-ctrblk dup font>height @ abs to char-height
dup font>width @ to char-width font>advance @ to fontbytes
;
: >font ( char -- addr )
dup default-font-ctrblk dup >r font>min-char @ dup r@ font>#glyphs + within
IF
r@ font>min-char @ -
r@ font>advance @ * r@ font>height @ .scan-lines *
r> font>addr @ +
ELSE
drop r> font>addr @
THEN
;
: default-font ( -- addr width height advance min-char #glyphs )
default-font-ctrblk /font 0 DO dup cell+ >r @ r> 1 cells +LOOP drop
;
0 VALUE frame-buffer-adr
0 VALUE screen-height
0 VALUE screen-width
0 VALUE screen-depth
0 VALUE screen-line-bytes
0 VALUE window-top
0 VALUE window-left
0 VALUE .sc
: screen-#rows  ( -- rows )
.sc IF
screen-height char-height /
ELSE
true to .sc
s" screen-#rows" eval
false to .sc
THEN
;
: screen-#columns ( -- columns )
.sc IF
screen-width char-width /
ELSE
true to .sc
s" screen-#columns" eval
false to .sc
THEN
;
: fb8-background inverse? ;
: fb8-foreground inverse? invert ;
: fb8-lines2bytes ( #lines -- #bytes ) char-height * screen-line-bytes * ;
: fb8-columns2bytes ( #columns -- #bytes ) char-width * screen-depth * ;
: fb8-line2addr ( line# -- addr )
char-height * window-top + screen-line-bytes *
frame-buffer-adr + window-left screen-depth * +
;
: fb8-erase-block ( addr len ) fb8-background rfill ;
0 VALUE .ab
CREATE bitmap-buffer 400 4 * allot
: active-bits ( -- new ) .ab dup 8 > IF 8 - to .ab 8 ELSE
char-width to .ab ?dup 0= IF recurse THEN
THEN ;
: fb8-char2bitmap ( font-height font-addr -- bitmap-buffer )
bitmap-buffer >r
char-height rot 0> IF r> char-width 2dup fb8-erase-block + >r 1- THEN
r> -rot char-width to .ab
fontbytes * bounds ?DO
i c@ active-bits 0 ?DO
dup 80 and IF fb8-foreground ELSE fb8-background THEN
( fb-addr fbyte colr ) 2 pick ! 1 lshift
swap screen-depth + swap
LOOP drop
LOOP drop
bitmap-buffer
;
: fb8-draw-logo ( line# addr width height -- ) ." fb8-draw-logo ( " .s ."  )" cr
2drop 2drop
;
: fb8-toggle-cursor ( -- )
line# fb8-line2addr column# fb8-columns2bytes +
char-height 2 - screen-line-bytes * +
2 0 ?DO
dup char-width screen-depth * invert-region
screen-line-bytes +
LOOP drop
;
: fb8-draw-character ( char -- )
>r default-font over + r@ -rot between IF
2swap 3drop r> >font fb8-char2bitmap ( bitmap-buf )
line# fb8-line2addr column# fb8-columns2bytes + ( bitmap-buf fb-addr )
char-height 0 ?DO
2dup char-width screen-depth * mrmove
screen-line-bytes + >r char-width screen-depth * + r>
LOOP 2drop
ELSE 2drop r> 3drop THEN
;
: fb8-insert-lines ( n -- )
fb8-lines2bytes >r line# fb8-line2addr dup dup r@ +
#lines line# - fb8-lines2bytes r@ - rmove
r> fb8-erase-block
;
: fb8-delete-lines ( n -- )
fb8-lines2bytes >r line# fb8-line2addr dup dup r@ + swap
#lines fb8-lines2bytes r@ - dup >r rmove
r> + r> fb8-erase-block
;
: fb8-insert-characters ( n -- )
line# fb8-line2addr column# fb8-columns2bytes + >r
#columns column# - 2dup >= IF
nip dup 0> IF fb8-columns2bytes r> ELSE r> 2drop EXIT THEN
ELSE
fb8-columns2bytes swap fb8-columns2bytes tuck -
over r@ tuck + rot char-height 0 ?DO
3dup rmove
-rot screen-line-bytes tuck + -rot + swap rot
LOOP
3drop r>
THEN
char-height 0 ?DO
dup 2 pick fb8-erase-block screen-line-bytes +
LOOP
2drop
;
: fb8-delete-characters ( n -- )
line# fb8-line2addr column# fb8-columns2bytes + >r
#columns column# - 2dup >= IF
nip dup 0> IF fb8-columns2bytes r> ELSE r> 2drop EXIT THEN
ELSE
fb8-columns2bytes swap fb8-columns2bytes tuck -
over r@ + 2dup + r> swap >r rot char-height 0 ?DO
3dup rmove
-rot screen-line-bytes tuck + -rot + swap rot
LOOP
3drop r> over -
THEN
char-height 0 ?DO
dup 2 pick fb8-erase-block screen-line-bytes +
LOOP
2drop
;
: fb8-reset-screen ( -- ) ( Left as no-op by design ) ;
: fb8-erase-screen ( -- )
frame-buffer-adr screen-height screen-line-bytes * fb8-erase-block
;
: fb8-invert-screen ( -- )
frame-buffer-adr screen-height screen-line-bytes * invert-region
;
: fb8-blink-screen ( -- ) fb8-invert-screen fb8-invert-screen ;
: fb8-install ( width height #columns #lines -- )
1 to screen-depth
2swap  to screen-height  to screen-width
screen-width to screen-line-bytes
screen-#rows min to #lines
screen-#columns min to #columns
screen-height char-height #lines * - 2/ to window-top
screen-width char-width #columns * - 2/ to window-left
['] fb8-toggle-cursor to toggle-cursor
['] fb8-draw-character to draw-character
['] fb8-insert-lines to insert-lines
['] fb8-delete-lines to delete-lines
['] fb8-insert-characters to insert-characters
['] fb8-delete-characters to delete-characters
['] fb8-erase-screen to erase-screen
['] fb8-blink-screen to blink-screen
['] fb8-invert-screen to invert-screen
['] fb8-reset-screen to reset-screen
['] fb8-draw-logo to draw-logo
;
: fb-install  ( width height #columns #lines depth -- )
>r
fb8-install
r> to screen-depth
screen-width screen-depth * to screen-line-bytes
;
: fb8-dump-bitmap cr char-height 0 ?do char-width 0 ?do dup c@ if ." @" else ." ." then 1+ loop cr loop drop ;
: fb8-dump-char >font -b swap fb8-char2bitmap fb8-dump-bitmap ;
ÿÿÿÿÿÿÿÿðµ0graphics.fs: draw-rectangle ( adr x y w h -- )
frame-buffer-adr 0= IF 4drop drop EXIT THEN
0 ?DO
4dup drop                              ( adr x y w adr x y )
i + screen-width * + screen-depth *    ( adr x y w adr offs )
frame-buffer-adr +                     ( adr x y w adr fb_adr )
over 3 pick screen-depth * i * +       ( adr x y w adr fb_adr src )
swap 3 pick screen-depth *             ( adr x y w adr src fb_adr len )
rmove                                  \ copy line ( adr x y w adr )
drop                                   ( adr x y w )
LOOP
4drop
;
: fill-rectangle ( col x y w h -- )
frame-buffer-adr 0= IF 4drop drop EXIT THEN
0 ?DO
4dup drop                              ( col x y w col x y )
i + screen-width * + screen-depth *    ( col x y w col offs )
frame-buffer-adr +                     ( col x y w col adr )
2 pick screen-depth * 2 pick           ( col x y w col adr len col )
rfill                                  \ draw line ( col x y w col )
drop                                   ( col x y w )
LOOP
4drop
;
: read-rectangle ( adr x y w h -- )
frame-buffer-adr 0= IF 4drop drop EXIT THEN
0 ?DO
4dup drop                              ( adr x y w adr x y )
i + screen-width * + screen-depth *    ( adr x y w adr offs )
frame-buffer-adr +                     ( adr x y w adr fb_adr )
over 3 pick screen-depth * i * +       ( adr x y w adr fb_adr dst )
3 pick                                 ( adr x y w adr fb_adr dst w )
rmove                                  \ copy line ( adr x y w adr )
drop                                   ( adr x y w )
LOOP
4drop
;
: dimensions ( -- width height )
screen-width screen-height
;
: init-default-palette
100 10 DO
i i i i color!
LOOP
00 00 00 0 color!
00 00 aa 1 color!
00 aa 00 2 color!
00 aa aa 3 color!
aa 00 00 4 color!
aa 00 aa 5 color!
aa 55 00 6 color!
aa aa aa 7 color!
55 55 55 8 color!
55 55 ff 9 color!
55 ff 55 a color!
55 ff ff b color!
ff 55 55 c color!
ff 55 ff d color!
ff ff 55 e color!
ff ff ff f color!
;
ÿÿÿÿÿÿÿÿÐ0generic-disk.fsnew-device set-unit                                          ( str len )
2dup device-name 
s" 0 pci-alias-" 2swap $cat evaluate
s" block" device-type      
s" block-size" $call-parent   CONSTANT block-size
s" max-transfer" $call-parent CONSTANT max-transfer 
: read-blocks ( addr block# #blocks -- #read )
my-unit s" dev-read-blocks" $call-parent
;    
INSTANCE VARIABLE deblocker
: open ( -- okay? )
0 0 s" deblocker" $open-package dup deblocker ! dup IF 
s" disk-label" find-package IF
my-args rot interpose
THEN
THEN 0<> ;
: close ( -- )
deblocker @ close-package ;
: seek ( pos.lo pos.hi -- status )
s" seek" deblocker @ $call-method ;
: read ( addr len -- actual )
s" read" deblocker @ $call-method ;
finish-device
ÿÿÿÿÿÿÿÿH0dma-function.fs: dma-alloc ( size -- virt )
my-phandle TO calling-child
s" dma-alloc" my-phandle parent $call-static
0 TO calling-child
;
: dma-free ( virt size -- )
my-phandle TO calling-child
s" dma-free" my-phandle parent $call-static
0 TO calling-child
;
: dma-map-in ( virt size cacheable? -- devaddr )
my-phandle TO calling-child
s" dma-map-in" my-phandle parent $call-static
0 TO calling-child
;
: dma-map-out ( virt devaddr size -- )
my-phandle TO calling-child
s" dma-map-out" my-phandle parent $call-static
0 TO calling-child
;
ÿÿÿÿÿÿÿÿP@dma-instance-function.fs: dma-alloc ( size -- virt )
s" dma-alloc" $call-parent
;
: dma-free ( virt size -- )
s" dma-free" $call-parent
;
: dma-map-in ( virt size cacheable? -- devaddr )
s" dma-map-in" $call-parent
;
: dma-map-out ( virt devaddr size -- )
s" dma-map-out" $call-parent
;
ÿÿÿÿÿÿÿÿ¨i0pci-device.fsget-node CONSTANT my-phandle
s" my-puid" my-phandle parent $call-static CONSTANT my-puid
: config-b@  puid >r my-puid TO puid my-space + rtas-config-b@ r> TO puid ;
: config-w@  puid >r my-puid TO puid my-space + rtas-config-w@ r> TO puid ;
: config-l@  puid >r my-puid TO puid my-space + rtas-config-l@ r> TO puid ;
: config-b!  puid >r my-puid TO puid my-space + rtas-config-b! r> TO puid ;
: config-w!  puid >r my-puid TO puid my-space + rtas-config-w! r> TO puid ;
: config-l!  puid >r my-puid TO puid my-space + rtas-config-l! r> TO puid ;
: config-dump puid >r my-puid TO puid my-space pci-dump r> TO puid ;
: open
puid >r             \ save the old puid
my-puid TO puid     \ set up the puid to the devices Hostbridge
pci-master-enable   \ And enable Bus Master, IO and MEM access again.
pci-mem-enable      \ enable mem access
pci-io-enable       \ enable io access
r> TO puid          \ restore puid
true
;
: close 
puid >r             \ save the old puid
my-puid TO puid     \ set up the puid
pci-device-disable  \ and disable the device
r> TO puid          \ restore puid
;
s" dma-function.fs" included
: devicefile ( -- str len )
s" pci-device_"
my-space pci-vendor@ 4 int2str $cat
s" _" $cat
my-space pci-device@ 4 int2str $cat
s" .fs" $cat
;
: classfile ( -- str len )
s" pci-class_"
my-space pci-class@ 10 rshift 2 int2str $cat
s" .fs" $cat
;
: setup ( -- )
devicefile romfs-lookup ?dup
IF
evaluate
ELSE
classfile romfs-lookup ?dup
IF
evaluate
ELSE
my-space pci-class-name type 2a emit cr
my-space pci-device-generic-setup
THEN
THEN
;
pci-device-disable
pci-error-enable
my-space 44 pci-out     \ config-addr ascii('D')
setup
ÿÿÿÿÿÿÿÿ°s0pci-bridge.fsget-node CONSTANT my-phandle
s" my-puid" my-phandle parent $call-static CONSTANT my-puid
pci-bus-number 1+ CONSTANT my-bus
s" pci-config-bridge.fs" included
s" dma-function.fs" included
: filename ( -- str len )
s" pci-bridge_"
my-space pci-vendor@ 4 int2str $cat
s" _" $cat
my-space pci-device@ 4 int2str $cat
s" .fs" $cat
;
: setup ( -- )
filename romfs-lookup ?dup
IF
evaluate
ELSE
my-space pci-class-name type 2a emit cr
my-space pci-bridge-generic-setup
my-space pci-reset-2nd
THEN
;
pci-device-disable
pci-error-enable
my-space 42 pci-out     \ config-addr ascii('B')
setup
pci-master-enable
pci-mem-enable
pci-io-enable
ÿÿÿÿÿÿÿÿ…„Ë8pci-properties.fs: pci-class-name-00 ( addr -- str len )
pci-class@ 8 rshift FF and CASE
01  OF s" display"               ENDOF
dup OF s" legacy-device"         ENDOF
ENDCASE
;
: pci-class-name-01 ( addr -- str len )
pci-class@ 8 rshift FF and CASE
00  OF s" scsi"         ENDOF
01  OF s" ide"          ENDOF
02  OF s" fdc"          ENDOF
03  OF s" ipi"          ENDOF
04  OF s" raid"         ENDOF
05  OF s" ata"          ENDOF
06  OF s" sata"         ENDOF
07  OF s" sas"          ENDOF
dup OF s" mass-storage" ENDOF
ENDCASE
;
: pci-class-name-02 ( addr -- str len )
pci-class@ 8 rshift FF and CASE
00  OF s" ethernet"   ENDOF
01  OF s" token-ring" ENDOF
02  OF s" fddi"       ENDOF
03  OF s" atm"        ENDOF
04  OF s" isdn"       ENDOF
05  OF s" worldfip"   ENDOF
05  OF s" picmg"      ENDOF
dup OF s" network"    ENDOF
ENDCASE
;
: pci-class-name-03 ( addr -- str len )
pci-class@ FFFF and CASE
0000  OF s" vga"             ENDOF
0100  OF s" xga"             ENDOF
0200  OF s" 3d-controller"   ENDOF
dup OF s" display"           ENDOF
ENDCASE
;
: pci-class-name-04 ( addr -- str len )
pci-class@ 8 rshift FF and CASE
00  OF s" video"             ENDOF
01  OF s" sound"             ENDOF
02  OF s" telephony"         ENDOF
dup OF s" multimedia-device" ENDOF
ENDCASE
;
: pci-class-name-05 ( addr -- str len )
pci-class@ 8 rshift FF and CASE
00  OF s" memory"            ENDOF
01  OF s" flash"             ENDOF
dup OF s" memory-controller" ENDOF
ENDCASE
;
: pci-class-name-06 ( addr -- str len )
pci-class@ 8 rshift FF and CASE
00  OF s" host"                 ENDOF
01  OF s" isa"                  ENDOF
02  OF s" eisa"                 ENDOF
03  OF s" mca"                  ENDOF
04  OF s" pci"                  ENDOF
05  OF s" pcmcia"               ENDOF
06  OF s" nubus"                ENDOF
07  OF s" cardbus"              ENDOF
08  OF s" raceway"              ENDOF
09  OF s" semi-transparent-pci" ENDOF
0A  OF s" infiniband"           ENDOF
dup OF s" unknown-bridge"       ENDOF
ENDCASE
;
: pci-class-name-07 ( addr -- str len )
pci-class@ FFFF and CASE
0000  OF s" serial"                   ENDOF
0100  OF s" parallel"                 ENDOF
0200  OF s" multiport-serial"         ENDOF
0300  OF s" modem"                    ENDOF
0400  OF s" gpib"                     ENDOF
0500  OF s" smart-card"               ENDOF
dup   OF s" communication-controller" ENDOF
ENDCASE
;
: pci-class-name-08 ( addr -- str len )
pci-class@ FFFF and CASE
0000  OF s" interrupt-controller" ENDOF
0100  OF s" dma-controller"       ENDOF
0200  OF s" timer"                ENDOF
0300  OF s" rtc"                  ENDOF
0400  OF s" hot-plug-controller"  ENDOF
0500  OF s" sd-host-controller"   ENDOF
dup   OF s" system-peripheral"    ENDOF
ENDCASE
;
: pci-class-name-09 ( addr -- str len )
pci-class@ 8 rshift FF and CASE
00  OF s" keyboard"         ENDOF
01  OF s" pen"              ENDOF
02  OF s" mouse"            ENDOF
03  OF s" scanner"          ENDOF
04  OF s" gameport"         ENDOF
dup OF s" input-controller" ENDOF
ENDCASE
;
: pci-class-name-0A ( addr -- str len )
pci-class@ 8 rshift FF and CASE
00  OF s" dock"            ENDOF
dup OF s" docking-station" ENDOF
ENDCASE
;
: pci-class-name-0B ( addr -- str len )
pci-class@ 8 rshift FF and CASE
02  OF s" pentium"       ENDOF
20  OF s" powerpc"       ENDOF
30  OF s" mips"          ENDOF
40  OF s" co-processor"  ENDOF
dup OF s" cpu"           ENDOF
ENDCASE
;
: pci-class-name-0C ( addr -- str len )
pci-class@ FFFF and CASE
0000  OF s" firewire"      ENDOF
0100  OF s" access-bus"    ENDOF
0200  OF s" ssa"           ENDOF
0300  OF s" usb-uhci"      ENDOF
0310  OF s" usb-ohci"      ENDOF
0320  OF s" usb-ehci"      ENDOF
0330  OF s" usb-xhci"      ENDOF
0380  OF s" usb-unknown"   ENDOF
03FE  OF s" usb-device"    ENDOF
0400  OF s" fibre-channel" ENDOF
0500  OF s" smb"           ENDOF
0600  OF s" infiniband"    ENDOF
0700  OF s" ipmi"          ENDOF
0701  OF s" ipmi"          ENDOF
0702  OF s" ipmi"          ENDOF
0800  OF s" sercos"        ENDOF
0900  OF s" canbus"        ENDOF
dup OF s" serial-bus"      ENDOF
ENDCASE
;
: pci-class-name-0D ( addr -- str len )
pci-class@ 8 rshift FF and CASE
00  OF s" irda"                ENDOF
01  OF s" consumer-ir"         ENDOF
10  OF s" rf-controller"       ENDOF
11  OF s" bluetooth"           ENDOF
12  OF s" broadband"           ENDOF
dup OF s" wireless-controller" ENDOF
ENDCASE
;
: pci-class-name-0E ( addr -- str len )
pci-class@ 8 rshift FF and CASE
dup OF s" intelligent-io" ENDOF
ENDCASE
;
: pci-class-name-0F ( addr -- str len )
pci-class@ 8 rshift FF and CASE
01  OF s" satellite-tv"     ENDOF
02  OF s" satellite-audio"  ENDOF
03  OF s" satellite-voice"  ENDOF
04  OF s" satellite-data"   ENDOF
dup OF s" satellite-device" ENDOF
ENDCASE
;
: pci-class-name-10 ( addr -- str len )
pci-class@ 8 rshift FF and CASE
00  OF s" network-encryption"       ENDOF
01  OF s" entertainment-encryption" ENDOF
dup OF s" encryption"               ENDOF
ENDCASE
;
: pci-class-name-11 ( addr -- str len )
pci-class@ 8 rshift FF and CASE
00  OF s" dpio"                       ENDOF
01  OF s" counter"                    ENDOF
10  OF s" measurement"                ENDOF
20  OF s" managment-card"             ENDOF
dup OF s" data-processing-controller" ENDOF
ENDCASE
;
: pci-class-name ( addr -- str len )
dup pci-class@ 10 rshift CASE
00  OF pci-class-name-00 ENDOF
01  OF pci-class-name-01 ENDOF
02  OF pci-class-name-02 ENDOF
03  OF pci-class-name-03 ENDOF
04  OF pci-class-name-04 ENDOF
05  OF pci-class-name-05 ENDOF
06  OF pci-class-name-06 ENDOF
07  OF pci-class-name-07 ENDOF
08  OF pci-class-name-08 ENDOF
09  OF pci-class-name-09 ENDOF
0A  OF pci-class-name-0A ENDOF
0B  OF pci-class-name-0B ENDOF
0C  OF pci-class-name-0C ENDOF
0D  OF pci-class-name-0D ENDOF
0E  OF pci-class-name-0E ENDOF
0F  OF pci-class-name-0F ENDOF
10  OF pci-class-name-10 ENDOF
11  OF pci-class-name-11 ENDOF
dup OF drop s" unknown"  ENDOF
ENDCASE
;
: pci-bar-size@     ( bar-addr -- bar-size ) -1 over rtas-config-l! rtas-config-l@ ;
: pci-bar-size-mem@ ( bar-addr -- mem-size ) pci-bar-size@ -10 and invert 1+ FFFFFFFF and ;
: pci-bar-size-io@  ( bar-addr -- io-size  ) pci-bar-size@ -4 and invert 1+ FFFFFFFF and ;
: pci-bar-size ( bar-addr -- bar-size-raw )
dup rtas-config-l@ swap \ fetch original Value  ( bval baddr )
-1 over rtas-config-l!  \ make BAR show size    ( bval baddr )
dup rtas-config-l@      \ and fetch the size    ( bval baddr bsize )
-rot rtas-config-l!     \ restore Value
;
: pci-bar-size-mem32 ( bar-addr -- bar-size )
pci-bar-size            \ fetch raw size
-10 and invert 1+       \ calc size
FFFFFFFF and            \ keep lower 32 bits
;
: pci-bar-size-rom ( bar-addr -- bar-size )
pci-bar-size            \ fetch raw size
FFFFF800 and invert 1+  \ calc size
FFFFFFFF and            \ keep lower 32 bits
;
: pci-bar-size-mem64 ( bar-addr -- bar-size )
dup pci-bar-size        \ fetch raw size lower 32 bits
swap 4 + pci-bar-size   \ fetch raw size upper 32 bits
20 lshift +             \ and put them together
-10 and invert 1+       \ calc size
;
: pci-bar-size-io ( bar-addr -- bar-size )
pci-bar-size            \ fetch raw size
-4 and invert 1+        \ calc size
FFFFFFFF and            \ keep lower 32 bits
;
: pci-bar-code@ ( bar-addr -- 0|1..4|5 )
rtas-config-l@ dup                \ fetch the BaseAddressRegister
1 and IF                          \ IO BAR ?
2 and IF 0 ELSE 1 THEN    \ only '01' is valid
ELSE                              \ Memory BAR ?
F and CASE
0   OF 2 ENDOF    \ Memory 32 Bit Non-Prefetchable
8   OF 3 ENDOF    \ Memory 32 Bit Prefetchable
4   OF 4 ENDOF    \ Memory 64 Bit Non-Prefetchable
C   OF 5 ENDOF    \ Memory 64 Bit Prefechtable
dup OF 0 ENDOF    \ Not a valid BarType
ENDCASE
THEN
;
: assign-var-align ( size align var -- al-mem )
dup >r @                        \ ( size align cur-mem )
swap #aligned                   \ ( size al-mem )
tuck +                          \ ( al-mem new-mem )
r> !                            \ ( al-mem )
;
: assign-var-min-align ( size min-align var -- al-mem )
>r over umax                    \ ( size align )
r> assign-var-align             \ ( al-mem )
;
: assign-bar-value32 ( bar size var -- 4 )
over IF                         \ IF size > 0
>r                      \ | ( bar size )
pci-mem-bar-min-align   \ | ( bar size min-align )
r> assign-var-min-align \ | ( bar al-mem ) set variable to next mem
swap rtas-config-l!     \ | ( -- )         set the bar to al-mem
ELSE                            \ ELSE
2drop drop              \ | clear stack
THEN                            \ FI
4                               \ size of the base-address-register
;
: assign-io-bar-value32 ( bar size var -- 4 )
over IF                         \ IF size > 0
>r                      \ | ( bar size )
dup                     \ | ( bar size size-align )
r> assign-var-align     \ | ( bar al-mem ) set variable to next mem
swap rtas-config-l!     \ | ( -- )         set the bar to al-mem
ELSE                            \ ELSE
2drop drop              \ | clear stack
THEN                            \ FI
4                               \ size of the base-address-register
;
: assign-bar-value64 ( bar size var -- 8 )
over IF                         \ IF size > 0
>r                      \ | ( bar size )
pci-mem-bar-min-align   \ | ( bar size min-align )
r> assign-var-min-align \ | ( bar al-mem ) set variable to next mem
swap                    \ | ( al-mem addr ) calc config-addr of this bar
2dup rtas-config-l!     \ | ( al-mem addr ) set the Lower part of the bar to al-mem
4 + swap 20 rshift      \ | ( al-mem>>32 addr ) prepare the upper part of the al-mem
swap rtas-config-l!     \ | ( -- ) and set the upper part of the bar
ELSE                            \ ELSE
2drop drop              \ | clear stack
THEN                            \ FI
8                               \ size of the base-address-register
;
: assign-mem64-bar ( bar-addr -- 8 )
dup pci-bar-size-mem64         \ fetch size
pci-next-mem64 @ 0 = IF          \ Check if we have 64-bit memory range
pci-next-mem
ELSE
pci-next-mem64
THEN
assign-bar-value64              \ and set it all
;
: assign-mem32-bar ( bar-addr -- 4 )
dup pci-bar-size-mem32          \ fetch size
pci-next-mem @ IF
pci-next-mem
ELSE
pci-next-mmio
THEN
assign-bar-value32              \ and set it all
;
: assign-mmio64-bar ( bar-addr -- 8 )
dup pci-bar-size-mem64          \ fetch size
pci-next-mmio
assign-bar-value64              \ and set it all
;
: assign-mmio32-bar ( bar-addr -- 4 )
dup pci-bar-size-mem32          \ fetch size
pci-next-mmio                   \ var to change
assign-bar-value32              \ and set it all
;
: assign-io-bar ( bar-addr -- 4 )
dup pci-bar-size-io             \ fetch size
pci-next-io                     \ var to change
assign-io-bar-value32           \ and set it all
;
: assign-rom-bar ( bar-addr -- )
dup pci-bar-size-rom            \ fetch size
dup IF                          \ IF size > 0
over >r                 \ | save bar addr for enable
pci-next-mmio           \ | var to change
assign-bar-value32      \ | and set it
drop                    \ | forget the BAR length
r@ rtas-config-l@       \ | fetch BAR
1 or r> rtas-config-l!  \ | and enable the ROM
ELSE                            \ ELSE
2drop                   \ | clear stack
THEN
;
: assign-bar ( bar-addr -- reg-size )
dup pci-bar-code@                       \ calc BAR type
dup IF                                  \ IF >0
CASE                            \ | CASE Setup the right type
1 OF assign-io-bar     ENDOF    \ | - set up an IO-Bar
2 OF assign-mmio32-bar ENDOF    \ | - set up an 32bit MMIO-Bar
3 OF assign-mem32-bar  ENDOF    \ | - set up an 32bit MEM-Bar (prefetchable)
4 OF assign-mmio64-bar ENDOF    \ | - set up an 64bit MMIO-Bar
5 OF assign-mem64-bar  ENDOF    \ | - set up an 64bit MEM-Bar (prefetchable)
ENDCASE                         \ | ESAC
ELSE                                    \ ELSE
ABORT                           \ | Throw an exception
THEN                                    \ FI
;
: assign-all-device-bars ( configaddr -- )
28 10 DO                        \ BARs start at 10 and end at 27
dup i +                 \ calc config-addr of the BAR
assign-bar              \ and set it up
+LOOP                           \ add 4 or 8 to the index and loop
30 + assign-rom-bar             \ set up the ROM if available
;
: assign-all-bridge-bars ( configaddr -- )
18 10 DO                        \ BARs start at 10 and end at 17
dup i +                 \ calc config-addr of the BAR
assign-bar              \ and set it up
+LOOP                           \ add 4 or 8 to the index and loop
38 + assign-rom-bar             \ set up the ROM if available
;
: gen-mem64-bar-prop ( prop-addr prop-len bar-addr -- prop-addr prop-len 8 )
dup pci-bar-size-mem64                  \ fetch BAR Size        ( paddr plen baddr bsize )
dup IF                                  \ IF Size > 0
>r dup rtas-config-l@           \ | save size and fetch lower 32 bits ( paddr plen baddr val.lo R: size)
over 4 + rtas-config-l@         \ | fetch upper 32 bits               ( paddr plen baddr val.lo val.hi R: size)
20 lshift + -10 and >r          \ | calc 64 bit value and save it     ( paddr plen baddr R: size val )
82000000 or encode-int+         \ | Encode config addr                ( paddr plen R: size val )
r> encode-64+                   \ | Encode assigned addr              ( paddr plen R: size )
r> encode-64+                   \ | Encode size                       ( paddr plen )
ELSE                                    \ ELSE
2drop                           \ | don't do anything
THEN                                    \ FI
8                                       \ sizeof(BAR) = 8 Bytes
;
: gen-pmem64-bar-prop ( prop-addr prop-len bar-addr -- prop-addr prop-len 8 )
dup pci-bar-size-mem64                  \ fetch BAR Size        ( paddr plen baddr bsize )
dup IF                                  \ IF Size > 0
>r dup rtas-config-l@           \ | save size and fetch lower 32 bits ( paddr plen baddr val.lo R: size)
over 4 + rtas-config-l@         \ | fetch upper 32 bits               ( paddr plen baddr val.lo val.hi R: size)
20 lshift + -10 and >r          \ | calc 64 bit value and save it     ( paddr plen baddr R: size val )
C3000000 or encode-int+         \ | Encode config addr                ( paddr plen R: size val )
r> encode-64+                   \ | Encode assigned addr              ( paddr plen R: size )
r> encode-64+                   \ | Encode size                       ( paddr plen )
ELSE                                    \ ELSE
2drop                           \ | don't do anything
THEN                                    \ FI
8                                       \ sizeof(BAR) = 8 Bytes
;
: gen-mem32-bar-prop ( prop-addr prop-len bar-addr -- prop-addr prop-len 4 )
dup pci-bar-size-mem32                  \ fetch BAR Size        ( paddr plen baddr bsize )
dup IF                                  \ IF Size > 0
>r dup rtas-config-l@           \ | save size and fetch value         ( paddr plen baddr val R: size)
-10 and >r                      \ | calc 32 bit value and save it     ( paddr plen baddr R: size val )
82000000 or encode-int+         \ | Encode config addr                ( paddr plen R: size val )
r> encode-64+                   \ | Encode assigned addr              ( paddr plen R: size )
r> encode-64+                   \ | Encode size                       ( paddr plen )
ELSE                                    \ ELSE
2drop                           \ | don't do anything
THEN                                    \ FI
4                                       \ sizeof(BAR) = 4 Bytes
;
: gen-pmem32-bar-prop ( prop-addr prop-len bar-addr -- prop-addr prop-len 4 )
dup pci-bar-size-mem32                  \ fetch BAR Size        ( paddr plen baddr bsize )
dup IF                                  \ IF Size > 0
>r dup rtas-config-l@           \ | save size and fetch value         ( paddr plen baddr val R: size)
-10 and >r                      \ | calc 32 bit value and save it     ( paddr plen baddr R: size val )
C2000000 or encode-int+         \ | Encode config addr                ( paddr plen R: size val )
r> encode-64+                   \ | Encode assigned addr              ( paddr plen R: size )
r> encode-64+                   \ | Encode size                       ( paddr plen )
ELSE                                    \ ELSE
2drop                           \ | don't do anything
THEN                                    \ FI
4                                       \ sizeof(BAR) = 4 Bytes
;
: gen-io-bar-prop ( prop-addr prop-len bar-addr -- prop-addr prop-len 4 )
dup pci-bar-size-io                     \ fetch BAR Size                      ( paddr plen baddr bsize )
dup IF                                  \ IF Size > 0
>r dup rtas-config-l@           \ | save size and fetch value         ( paddr plen baddr val R: size)
-4 and >r                       \ | calc 32 bit value and save it     ( paddr plen baddr R: size val )
81000000 or encode-int+         \ | Encode config addr                ( paddr plen R: size val )
r> encode-64+                   \ | Encode assigned addr              ( paddr plen R: size )
r> encode-64+                   \ | Encode size                       ( paddr plen )
ELSE                                    \ ELSE
2drop                           \ | don't do anything
THEN                                    \ FI
4                                       \ sizeof(BAR) = 4 Bytes
;
: gen-rom-bar-prop ( prop-addr prop-len bar-addr -- prop-addr prop-len )
dup pci-bar-size-rom                    \ fetch BAR Size                      ( paddr plen baddr bsize )
dup IF                                  \ IF Size > 0
>r dup rtas-config-l@           \ | save size and fetch value         ( paddr plen baddr val R: size)
FFFFF800 and >r                 \ | calc 32 bit value and save it     ( paddr plen baddr R: size val )
82000000 or encode-int+         \ | Encode config addr                ( paddr plen R: size val )
r> encode-64+                   \ | Encode assigned addr              ( paddr plen R: size )
r> encode-64+                   \ | Encode size                       ( paddr plen )
ELSE                                    \ ELSE
2drop                           \ | don't do anything
THEN                                    \ FI
;
: pci-add-assigned-address ( prop-addr prop-len bar-addr -- prop-addr prop-len bsize )
dup pci-bar-code@                               \ calc BAR type                         ( paddr plen baddr btype)
CASE                                            \ CASE for the BAR types                ( paddr plen baddr )
0 OF drop 4              ENDOF          \ - not a valid type so do nothing
1 OF gen-io-bar-prop     ENDOF          \ - IO-BAR
2 OF gen-mem32-bar-prop  ENDOF          \ - MEM32
3 OF gen-pmem32-bar-prop ENDOF          \ - MEM32 prefetchable
4 OF gen-mem64-bar-prop  ENDOF          \ - MEM64
5 OF gen-pmem64-bar-prop ENDOF          \ - MEM64 prefetchable
ENDCASE                                         \ ESAC ( paddr plen bsize )
;
: pci-device-assigned-addresses-prop ( addr -- )
encode-start                                    \ provide mem for property              ( addr paddr plen )
2 pick 30 + gen-rom-bar-prop                    \ assign the rom bar
28 10 DO                                        \ we have 6 possible BARs
2 pick i +                              \ calc BAR address                      ( addr paddr plen bar-addr )      
pci-add-assigned-address                \ and generate the props for the BAR
+LOOP                                           \ increase Index by returned len
s" assigned-addresses" property drop            \ and write it into the device tree
;
: pci-bridge-assigned-addresses-prop ( addr -- )
encode-start                                    \ provide mem for property
2 pick 38 + gen-rom-bar-prop                    \ assign the rom bar
18 10 DO                                        \ we have 2 possible BARs
2 pick i +                              \ ( addr paddr plen current-addr )
pci-add-assigned-address                \ and generate the props for the BAR
+LOOP                                           \ increase Index by returned len
s" assigned-addresses" property drop            \ and write it into the device tree
;
: pci-bridge-gen-range ( paddr plen base limit type -- paddr plen )
>r over -                       \ calc size             ( paddr plen base size R:type )
dup 0< IF                       \ IF Size < 0           ( paddr plen base size R:type )
2drop r> drop           \ | forget values       ( paddr plen )
ELSE                            \ ELSE
1+ swap 2swap           \ | adjust stack        ( size base paddr plen R:type )
r@ encode-int+          \ | Child type          ( size base paddr plen R:type )
2 pick encode-64+       \ | Child address       ( size base paddr plen R:type )
r> encode-int+          \ | Parent type         ( size base paddr plen )
rot encode-64+          \ | Parent address      ( size paddr plen )
rot encode-64+          \ | Encode size         ( paddr plen )
THEN                            \ FI
;
: pci-bridge-gen-mmio-range ( addr prop-addr prop-len -- addr prop-addr prop-len )
2 pick 20 + rtas-config-l@      \ fetch Value           ( addr paddr plen val )
dup 0000FFF0 and 10 lshift      \ calc base-address     ( addr paddr plen val base )
swap 000FFFFF or                \ calc limit-address    ( addr paddr plen base limit )
02000000 pci-bridge-gen-range   \ and generate it       ( addr paddr plen )
;
: pci-bridge-gen-mem-range ( addr prop-addr prop-len -- addr prop-addr prop-len )
2 pick 24 + rtas-config-l@      \ fetch Value           ( addr paddr plen val )
dup 000FFFFF or                 \ calc limit Bits 31:0  ( addr paddr plen val limit.31:0 )
swap 0000FFF0 and 10 lshift     \ calc base Bits 31:0   ( addr paddr plen limit.31:0 base.31:0 )
4 pick 28 + rtas-config-l@      \ fetch upper Basebits  ( addr paddr plen limit.31:0 base.31:0 base.63:32 )
20 lshift or swap               \ and calc Base         ( addr paddr plen base.63:0 limit.31:0 )
4 pick 2C + rtas-config-l@      \ fetch upper Limitbits ( addr paddr plen base.63:0 limit.31:0 limit.63:32 )
dup -rot 20 lshift or swap      \ and calc Limit        ( addr paddr plen base.63:0 limit.63:0 limit.63:32 )
IF 43000000 ELSE 42000000 THEN  \ 64-bit or 32-bit?     ( addr paddr plen base.63:0 limit.63:0 type )
pci-bridge-gen-range            \ and generate it       ( addr paddr plen )
;
: pci-bridge-gen-io-range ( addr prop-addr prop-len -- addr prop-addr prop-len )
2 pick 1C + rtas-config-l@      \ fetch Value           ( addr paddr plen val )
dup 0000F000 and 00000FFF or    \ calc Limit Bits 15:0  ( addr paddr plen val limit.15:0 )
swap 000000F0 and 8 lshift      \ calc Base Bits 15:0   ( addr paddr plen limit.15:0 base.15:0 )
4 pick 30 + rtas-config-l@      \ fetch upper Bits      ( addr paddr plen limit.15:0 base.15:0 val )
dup FFFF and 10 lshift rot or   \ calc Base             ( addr paddr plen limit.15:0 val base.31:0 )
-rot FFFF0000 and or            \ calc Limit            ( addr paddr plen base.31:0 limit.31:0 )
01000000 pci-bridge-gen-range   \ and generate it       ( addr paddr plen )
;
: pci-bridge-range-props ( addr -- )
encode-start                    \ provide mem for property
pci-bridge-gen-mmio-range       \ generate the non prefetchable Memory Entry
pci-bridge-gen-mem-range        \ generate the prefetchable Memory Entry
pci-bridge-gen-io-range         \ generate the IO Entry
dup IF                          \ IF any space present (propsize>0)
s" ranges" property     \ | write it into the device tree
ELSE                            \ ELSE
s" " s" ranges" property
2drop                   \ | forget the properties
THEN                            \ FI
drop                            \ forget the address
;
: pci-bridge-interrupt-map ( -- )
encode-start                                    \ create the property                           ( paddr plen )
get-node child                                  \ find the first child                          ( paddr plen handle )
BEGIN dup WHILE                                 \ Loop as long as the handle is non-zero        ( paddr plen handle )
dup >r >space                           \ Get the my-space                              ( paddr plen addr R: handle )
pci-gen-irq-entry                       \ and Encode the interrupt settings             ( paddr plen R: handle)
r> peer                                 \ Get neighbour                                 ( paddr plen handle )
REPEAT                                          \ process next childe node                      ( paddr plen handle )
drop                                            \ forget the null                               ( paddr plen )
s" interrupt-map" property                      \ and set it                                    ( -- )
1 encode-int s" #interrupt-cells" property      \ encode the cell#
f800 encode-int 0 encode-int+ 0 encode-int+     \ encode the bit mask for config addr (Dev only)
7 encode-int+ s" interrupt-map-mask" property   \ encode IRQ#=7 and generate property
;
: encode-mem32-bar ( prop-addr prop-len BAR-addr -- prop-addr prop-len 4 )
dup pci-bar-size-mem32                  \ calc BAR-size ( not changing the BAR )
dup IF                                  \ IF BAR-size > 0       ( paddr plen baddr bsize )
>r 02000000 or encode-int+      \ | save size and encode BAR addr
0 encode-64+                    \ | make mid and lo zero
r> encode-64+                   \ | encode size
ELSE                                    \ ELSE
2drop                           \ | don't do anything
THEN                                    \ FI
4                                       \ BAR-Len = 4 (32Bit)
;
: encode-pmem32-bar ( prop-addr prop-len BAR-addr -- prop-addr prop-len 4 )
dup pci-bar-size-mem32                  \ calc BAR-size ( not changing the BAR )
dup IF                                  \ IF BAR-size > 0       ( paddr plen baddr bsize )
>r 42000000 or encode-int+      \ | save size and encode BAR addr
0 encode-64+                    \ | make mid and lo zero
r> encode-64+                   \ | encode size
ELSE                                    \ ELSE
2drop                           \ | don't do anything
THEN                                    \ FI
4                                       \ BAR-Len = 4 (32Bit)
;
: encode-mem64-bar ( prop-addr prop-len BAR-addr -- prop-addr prop-len 8 )
dup pci-bar-size-mem64                  \ calc BAR-size ( not changing the BAR )
dup IF                                  \ IF BAR-size > 0       ( paddr plen baddr bsize )
>r 03000000 or encode-int+      \ | save size and encode BAR addr
0 encode-64+                    \ | make mid and lo zero
r> encode-64+                   \ | encode size
ELSE                                    \ ELSE
2drop                           \ | don't do anything
THEN                                    \ FI
8                                       \ BAR-Len = 8 (64Bit)
;
: encode-pmem64-bar ( prop-addr prop-len BAR-addr -- prop-addr prop-len 8 )
dup pci-bar-size-mem64                  \ calc BAR-size ( not changing the BAR )
dup IF                                  \ IF BAR-size > 0       ( paddr plen baddr bsize )
>r 43000000 or encode-int+      \ | save size and encode BAR addr
0 encode-64+                    \ | make mid and lo zero
r> encode-64+                   \ | encode size
ELSE                                    \ ELSE
2drop                           \ | don't do anything
THEN                                    \ FI
8                                       \ BAR-Len = 8 (64Bit)
;
: encode-rom-bar ( prop-addr prop-len configaddr -- prop-addr prop-len )
dup pci-bar-size-rom                            \ fetch raw BAR-size
dup IF                                          \ IF BAR is used
>r 02000000 or encode-int+              \ | save size and encode BAR addr
0 encode-64+                            \ | make mid and lo zero
r> encode-64+                           \ | calc and encode the size
ELSE                                            \ ELSE
2drop                                   \ | don't do anything
THEN                                            \ FI
;
: encode-io-bar ( prop-addr prop-len BAR-addr BAR-value -- prop-addr prop-len 4 )
dup pci-bar-size-io                     \ calc BAR-size ( not changing the BAR )
dup IF                                  \ IF BAR-size > 0       ( paddr plen baddr bsize )
>r 01000000 or encode-int+      \ | save size and encode BAR addr
0 encode-64+                    \ | make mid and lo zero
r> encode-64+                   \ | encode size
ELSE                                    \ ELSE
2drop                           \ | don't do anything
THEN                                    \ FI
4                                       \ BAR-Len = 4 (32Bit)
;
: encode-bar ( prop-addr prop-len bar-addr -- prop-addr prop-len bar-len )
dup pci-bar-code@                               \ calc BAR type
CASE                                            \ CASE for the BAR types ( paddr plen baddr val )
0 OF drop 4             ENDOF           \ - not a valid type so do nothing
1 OF encode-io-bar      ENDOF           \ - IO-BAR
2 OF encode-mem32-bar   ENDOF           \ - MEM32
3 OF encode-pmem32-bar  ENDOF           \ - MEM32 prefetchable
4 OF encode-mem64-bar   ENDOF           \ - MEM64
5 OF encode-pmem64-bar  ENDOF           \ - MEM64 prefetchable
ENDCASE                                         \ ESAC ( paddr plen blen )
;
: pci-reg-props ( configaddr -- )
dup encode-int                  \ configuration space           ( caddr paddr plen )
0 encode-64+                    \ make the rest 0
0 encode-64+                    \ encode the size as 0
2 pick pci-htype@               \ fetch Header Type             ( caddr paddr plen type )
1 and IF                        \ IF Bridge                     ( caddr paddr plen )
18 10 DO                \ | loop over all BARs
2 pick i +      \ | calc bar-addr               ( caddr paddr plen baddr )
encode-bar      \ | encode this BAR             ( caddr paddr plen blen )
+LOOP              \ | increase LoopIndex by the BARlen
2 pick 38 +             \ | calc ROM-BAR for a bridge   ( caddr paddr plen baddr )
encode-rom-bar          \ | encode the ROM-BAR          ( caddr paddr plen )
ELSE                            \ ELSE ordinary device          ( caddr paddr plen )
28 10 DO                 \ | loop over all BARs
2 pick i +      \ | calc bar-addr               ( caddr paddr plen baddr )
encode-bar      \ | encode this BAR             ( caddr paddr plen blen )
+LOOP              \ | increase LoopIndex by the BARlen
2 pick 30 +             \ | calc ROM-BAR for a device   ( caddr paddr plen baddr )
encode-rom-bar          \ | encode the ROM-BAR          ( caddr paddr plen )
THEN                            \ FI                            ( caddr paddr plen )
s" reg" property                \ and store it into the property
drop
;
: pci-common-props ( addr -- )
dup pci-class-name device-name
dup pci-vendor@    encode-int s" vendor-id"      property
dup pci-device@    encode-int s" device-id"      property
dup pci-revision@  encode-int s" revision-id"    property
dup pci-class@     encode-int s" class-code"     property
3 encode-int s" #address-cells" property
2 encode-int s" #size-cells"    property
dup pci-config-ext? IF 1 encode-int s" ibm,pci-config-space-type" property THEN
dup pci-status@
dup 9 rshift 3 and encode-int s" devsel-speed" property
dup 7 rshift 1 and IF 0 0 s" fast-back-to-back" property THEN
dup 6 rshift 1 and IF 0 0 s" 66mhz-capable" property THEN
5 rshift 1 and IF 0 0 s" udf-supported" property THEN
dup pci-cache@     ?dup IF encode-int s" cache-line-size" property THEN
pci-interrupt@ ?dup IF encode-int s" interrupts"      property THEN
;
: pci-device-props ( addr -- )
dup pci-common-props
dup pci-min-grant@ encode-int s" min-grant"   property
dup pci-max-lat@   encode-int s" max-latency" property
dup pci-sub-device@ ?dup IF encode-int s" subsystem-id" property THEN
dup pci-sub-vendor@ ?dup IF encode-int s" subsystem-vendor-id" property THEN
dup pci-device-assigned-addresses-prop
pci-reg-props
pci-hotplug-enabled IF
dup dup pci-addr2bus 8 lshift
swap pci-addr2dev 3 lshift or
40000000 + encode-int s" ibm,my-drc-index" property
dup dup pci-addr2bus 20 *
swap pci-addr2dev +
a base !
s" Slot " rot $cathex
hex
encode-string s" ibm,loc-code" property
THEN
;
: pci-bridge-props ( addr -- )
dup pci-bus@
encode-int s" primary-bus" property
encode-int s" secondary-bus" property
encode-int s" subordinate-bus" property
dup pci-bus@ drop encode-int rot encode-int+ s" bus-range" property
pci-device-slots encode-int s" slot-names" property
dup pci-bridge-range-props
dup pci-bridge-assigned-addresses-prop
s" interrupt-map" get-node get-property IF
pci-bridge-interrupt-map
ELSE 2drop THEN
pci-reg-props
;
: pci-bridge-generic-setup ( addr -- )
pci-device-slots >r             \ save the slot array on return stack
dup pci-common-props            \ set the common properties before scanning the bus
s" pci" device-type             \ the type is allways "pci"
dup func-pci-bridge-probe       \ find all device connected to it
dup assign-all-bridge-bars      \ set up all memory access BARs
dup pci-set-irq-line            \ set the interrupt pin
dup pci-set-capabilities        \ set up the capabilities
pci-bridge-props            \ and generate all properties
r> TO pci-device-slots          \ and reset the slot array
;
DEFER func-pci-device-props
: pci-device-generic-setup ( config-addr -- )
dup assign-all-device-bars      \ calc all BARs
dup pci-set-irq-line            \ set the interrupt pin
dup pci-set-capabilities        \ set up the capabilities
dup func-pci-device-props       \ and generate all properties
drop                            \ forget the config-addr
;
' pci-device-props TO func-pci-device-props
ÿÿÿÿÿÿÿÿ	x	38pci-config-bridge.fs: config-xt  ( config-addr xt -- data )
puid >r                            \ Safe puid
my-puid TO puid                    \ Set my-puid
swap dup ffff00 AND 0= IF          \ Has bus-device-function been specified?
my-space OR                     \ No: use my-space instead
THEN
swap execute                       \ Execute the rtas-config-xx function
r> TO puid                         \ Restore previous puid
;
: config-b@  ( config-addr -- data )  ['] rtas-config-b@ config-xt ;
: config-w@  ( config-addr -- data )  ['] rtas-config-w@ config-xt ;
: config-l@  ( config-addr -- data )  ['] rtas-config-l@ config-xt ;
: config-b!  ( data config-addr -- )  ['] rtas-config-b! config-xt ;
: config-w!  ( data config-addr -- )  ['] rtas-config-w! config-xt ;
: config-l!  ( data config-addr -- )  ['] rtas-config-l! config-xt ;
: config-dump puid >r my-puid TO puid my-space pci-dump r> TO puid ;
: decode-unit ( addr len -- phys.lo ... phys.hi )
2 hex-decode-unit       \ decode string
B lshift swap           \ shift the devicenumber to the right spot
8 lshift or             \ add the functionnumber
my-bus 10 lshift or     \ add the busnumber
0 0 rot                 \ make phys.lo = 0 = phys.mid
;
: encode-unit ( phys.lo ... phys.hi -- unit-str unit-len )
nip nip                         \ forget the both zeros
dup 8 rshift 7 and swap         \ calc Functionnumber
B rshift 1F and                 \ calc Devicenumber
over IF                         \ IF Function!=0
2 hex-encode-unit       \ | create string with DevNum,FnNum
ELSE                            \ ELSE
nip 1 hex-encode-unit   \ | create string with only DevNum
THEN                            \ FI
;
: map-in ( phys.lo phys.mid phys.hi size -- virt )
drop nip nip                         ( phys.hi )
dup FF AND dup 10 28 WITHIN NOT swap 30 <> AND IF
cr ." phys.hi = " . cr
ABORT" map-in with illegal config space address"
THEN
00FFFFFF AND                         \ Need only bus-dev-fn+register bits
dup config-l@                        ( phys.hi' bar.lo )
dup 7 AND 4 = IF                     \ Is it a 64-bit BAR?
swap 4 + config-l@ lxjoin         \ Add upper part of 64-bit BAR
ELSE
nip
THEN
F NOT AND                            \ Clear indicator bits
translate-my-address
;
: map-out ( virt size -- )
2drop 
;
: dma-sync ( virt devaddr size -- )
2drop drop
;
: open true ;
: close ;
ÿÿÿÿÿÿÿÿø¾0update_flash.fsfalse value flash-new
: update-flash-help ( -- )
cr ." update-flash tool to flash host FW " cr
."              -f <filename>      : Flash from file (e.g. net:\boot_rom.bin)" cr
."              -l                 : Flash from load-base" cr
."              -d                 : Flash from old load base (used by drone)" cr
."              -c                 : Flash from temp to perm" cr
."              -r                 : Flash from perm to temp" cr
;
: flash-read-temp ( -- success? )
get-flashside 1 = IF flash-addr get-load-base over flash-image-size rmove true
ELSE
false
THEN
;
: flash-read-perm ( -- success? )
get-flashside 0= IF
flash-addr get-load-base over flash-image-size rmove true
ELSE
false
THEN
;
: flash-switch-side ( side -- success? )
set-flashside 0<> IF
s" Cannot change flashside" type cr false
ELSE
true
THEN
;
: flash-ensure-temp ( -- success? )
get-flashside 0= IF
cr ." Cannot flash perm! Switching to temp side!"
1 flash-switch-side
ELSE
true
THEN
;
: update-flash ( "text" )
get-flashside >r                              \ Save old flashside
parse-word                      ( str len )   \ Parse first string
drop dup c@                     ( str first-char )
[char] - <> IF
update-flash-help r> 2drop EXIT
THEN
1+ c@                           ( second-char )
CASE
[char] f OF
parse-word cr s" do-load" evaluate
flash-ensure-temp TO flash-new
ENDOF
[char] l OF
flash-ensure-temp
ENDOF
[char] d OF
flash-load-base get-load-base 200000 move
flash-ensure-temp
ENDOF
[char] c OF
flash-read-temp 0= flash-new or IF
." Cannot commit temp, need to boot on temp first " cr false
ELSE
0 flash-switch-side
THEN
ENDOF
[char] r OF
flash-read-perm 0= IF
." Cannot commit perm, need to boot on perm first " cr false
ELSE
1 flash-switch-side
THEN
ENDOF
dup      OF
false
ENDOF
ENDCASE
0= IF
update-flash-help r> drop EXIT
THEN
get-load-base flash-write 0= IF ." Flash write failed !! " cr THEN
r> set-flashside drop                           \ Restore old flashside
;
ÿÿÿÿÿÿÿÿ0ø0xmodem.fs01 CONSTANT XM-SOH   \ Start of header
04 CONSTANT XM-EOT   \ End-of-transmission
06 CONSTANT XM-ACK   \ Acknowledge
15 CONSTANT XM-NAK   \ Neg. acknowledge
0 VALUE xm-retries   \ Retry count
0 VALUE xm-block#
: xmodem-get-byte  ( timeout -- byte|-1 )
d# 1000 *
0 DO
key? IF key UNLOOP EXIT THEN
1 ms
LOOP
-1
;
: xmodem-rx-packet  ( address -- success? )
1 xmodem-get-byte    \ Get block number
dup 0 < IF
2drop false EXIT  \ Timeout
THEN
1 xmodem-get-byte    \ Get neg. block number
dup 0 < IF
3drop false EXIT  \ Timeout
THEN
rot 0                ( blk# ~blk# address chksum )
80 0 DO
1 xmodem-get-byte dup 0 < IF     ( blk# ~blk# address chksum byte )
3drop 2drop UNLOOP FALSE EXIT
THEN
dup 3 pick c!            ( blk# ~blk# address chksum byte )
+ swap 1+ swap           ( blk# ~blk# address+1 chksum' )
LOOP
0ff and
1 xmodem-get-byte <> IF
3drop FALSE EXIT
THEN
drop                        ( blk# ~blk# )
over xm-block# <> IF
2drop FALSE EXIT
THEN                        ( blk# ~blk# )
ff xor =
;
: (xmodem-load)  ( address -- bytes )
1 to xm-block#
0 to xm-retries
dup
BEGIN
d# 10 xmodem-get-byte dup >r
CASE
XM-SOH OF
dup xmodem-rx-packet IF
XM-ACK emit
80 +                     ( start-addr next-addr  R: rx-byte )
0 to xm-retries                    \ Reset retry count
xm-block# 1+ ff and to xm-block#   \ Increase current block#
ELSE
XM-NAK emit
xm-retries 1+ to xm-retries  \ Increase retry count
THEN
ENDOF
XM-EOT OF
XM-ACK emit
ENDOF
dup OF
XM-NAK emit
xm-retries 1+ to xm-retries  \ Increase retry count
ENDOF
ENDCASE
r> XM-EOT =
xm-retries d# 10 >= OR
UNTIL                         ( start-address end-address )
swap -                        ( bytes received )
;
: xmodem-load  ( -- bytes )
cr ." Waiting for start of XMODEM upload..." cr
get-load-base (xmodem-load)
;
ÿÿÿÿÿÿÿÿÉ0scsi-disk.fsnew-device
s" disk" device-name
s" block" device-type
false VALUE scsi-disk-debug?
scsi-open
: execute-scsi-command ( buf-addr buf-len dir cmd-addr cmd-len -- ... )
" execute-scsi-command" $call-parent
;
: retry-scsi-command ( buf-addr buf-len dir cmd-addr cmd-len #retries -- ... )
" retry-scsi-command" $call-parent
;
0 INSTANCE VALUE block-size
0 INSTANCE VALUE max-transfer
0 INSTANCE VALUE max-block-num
0 INSTANCE VALUE is_cdrom
INSTANCE VARIABLE deblocker
CREATE scratch 100 allot
CREATE cdb 10 allot
: dump-scsi-error ( sense-buf sense-len stat name namelen -- )
." SCSI-DISK: " my-self instance>path type ." ," type ."  failed" cr
." SCSI-DISK: Status " dup . .status-text
0<> IF
."  Sense " scsi-get-sense-data dup . .sense-text
."  ASC " . ." ASCQ " . cr
ELSE drop THEN
;
: read-blocks ( addr block# #blocks -- #read )
scsi-disk-debug? IF
." SCSI-DISK: read-blocks " .s cr
THEN
2dup + max-block-num > IF
." SCSI-DISK: Access beyond end of device ! " cr
drop
dup max-block-num > IF
drop drop 0 EXIT
THEN
dup max-block-num swap -
THEN
dup block-size *                            ( addr block# #blocks len )
>r rot r> 			                ( block# #blocks addr len )
2swap                                       ( addr len block# #blocks )
dup >r
cdb                                         ( addr len block# #blocks cdb )
max-block-num FFFFFFFF > IF
scsi-build-read-16                      ( addr len )
ELSE
scsi-build-read-10                      ( addr len )
THEN
r> -rot                                     ( #blocks addr len )
scsi-dir-read cdb scsi-param-size 10
retry-scsi-command
dup 0<> IF " read-blocks" dump-scsi-error -65 throw ELSE drop THEN
;
: write-blocks ( addr block# #blocks -- #written )
scsi-disk-debug? IF
." SCSI-DISK: write-blocks " .s cr
THEN
over 22 < IF
." SCSI-DISK ERROR: Write access to partition table is not allowed." cr
3drop 0 EXIT
THEN
2dup + max-block-num > IF
." SCSI-DISK: Access beyond end of device ! " cr
3drop 0 EXIT
THEN
dup block-size *                            ( addr block# #blocks len )
>r rot r>                                   ( block# #blocks addr len )
2swap                                       ( addr len block# #blocks )
dup >r
cdb                                         ( addr len block# #blocks cdb )
max-block-num FFFFFFFF > IF
scsi-build-write-16
ELSE
scsi-build-write-10
THEN
r> -rot                                     ( #blocks addr len )
scsi-dir-write cdb scsi-param-size 10
retry-scsi-command
dup 0<> IF s" write-blocks" dump-scsi-error -65 throw ELSE drop THEN
;
: (inquiry) ( size -- buffer | NULL )
dup cdb scsi-build-inquiry
scratch swap scsi-dir-read cdb scsi-param-size 10 retry-scsi-command
0= IF scratch ELSE 2drop 0 THEN
;
: inquiry ( -- buffer | NULL )
scsi-disk-debug? IF
." SCSI-DISK: inquiry " .s cr
THEN
d# 36 (inquiry) 0= IF 0 EXIT THEN
scratch inquiry-data>add-length c@ 5 +
(inquiry)
;
: read-capacity ( -- blocksize #blocks )
scsi-disk-debug? IF
." SCSI-DISK: read-capacity " .s cr
THEN
scratch 10 erase
cdb scsi-build-read-cap-10 scratch scsi-length-read-cap-10-data scsi-dir-read
cdb scsi-param-size 1 retry-scsi-command
dup 0<> IF " read-capacity" dump-scsi-error 0 0 EXIT THEN
drop scratch scsi-get-capacity-10 1 +
;
: read-capacity-16 ( -- blocksize #blocks )
scsi-disk-debug? IF
." SCSI-DISK: read-capacity-16 " .s cr
THEN
scratch scsi-length-read-cap-16-data erase
cdb scsi-build-read-cap-16 scratch scsi-length-read-cap-16-data scsi-dir-read
cdb scsi-param-size 1 retry-scsi-command
dup 0<> IF " read-capacity-16" dump-scsi-error 0 0 EXIT THEN
drop scratch scsi-get-capacity-16 1 +
;
100 CONSTANT test-unit-retries
: test-unit-ready ( true | [ ascq asc sense-key false ] )
scsi-disk-debug? IF
." SCSI-DISK: test-unit-ready " .s cr
THEN
cdb scsi-build-test-unit-ready
0 0 0 cdb scsi-param-size test-unit-retries retry-scsi-command
0= IF true EXIT THEN
0= IF drop 0 0 4 false EXIT THEN
scsi-get-sense-data false
;
: start-stop-unit ( state# -- true | false )
scsi-disk-debug? IF
." SCSI-DISK: start-stop-unit " .s cr
THEN
cdb scsi-build-start-stop-unit
0 0 0 cdb scsi-param-size 10 retry-scsi-command
0= IF true ELSE 2drop false THEN
;
: compare-sense ( ascq asc key ascq2 asc2 key2 -- true | false )
3 pick =	    ( ascq asc key ascq2 asc2 keycmp )
swap 4 pick =   ( ascq asc key ascq2 keycmp asccmp )
rot 5 pick =    ( ascq asc key keycmp asccmp ascqcmp )
and and nip nip nip
;
0 CONSTANT CDROM-READY
1 CONSTANT CDROM-NOT-READY
2 CONSTANT CDROM-NO-DISK
3 CONSTANT CDROM-TRAY-OPEN
4 CONSTANT CDROM-INIT-REQUIRED
5 CONSTANT CDROM-TRAY-MAYBE-OPEN
: cdrom-try-close-tray ( -- )
scsi-const-load start-stop-unit drop
;
: cdrom-must-close-tray ( -- )
scsi-const-load start-stop-unit not IF
." Tray open !" cr -65 throw
THEN
;
: get-media-event ( -- true | false )
scsi-disk-debug? IF
." SCSI-DISK: get-media-event " .s cr
THEN
cdb scsi-build-get-media-event
scratch scsi-length-media-event scsi-dir-read cdb scsi-param-size 1 retry-scsi-command
0= IF true ELSE 2drop false THEN
;
: cdrom-status ( -- status )
test-unit-ready
IF CDROM-READY EXIT THEN
scsi-disk-debug? IF
." TestUnitReady sense: " 3dup . . . cr
THEN
3dup 1 4 2 compare-sense IF
3drop CDROM-NOT-READY EXIT
THEN
get-media-event IF
scratch w@ 4 >= IF
scratch 2 + c@ 04 = IF
scratch 5 + c@
dup 02 and 0<> IF drop 3drop CDROM-READY EXIT THEN
dup 01 and 0<> IF drop 3drop CDROM-TRAY-OPEN EXIT THEN
drop 3drop CDROM-NO-DISK EXIT
THEN
THEN
THEN
3dup 2 4 2 compare-sense IF
3drop CDROM-INIT-REQUIRED EXIT
THEN
over 4 = over 2 = and IF
3drop CDROM-READY EXIT
THEN
over 3a = IF
3drop CDROM-NO-DISK EXIT
THEN
3drop CDROM-TRAY-MAYBE-OPEN
;
: prep-cdrom ( -- ready? )
5 0 DO
cdrom-status CASE
CDROM-READY           OF UNLOOP true EXIT ENDOF
CDROM-NO-DISK         OF ." No medium !" cr UNLOOP false EXIT ENDOF
CDROM-TRAY-OPEN       OF cdrom-must-close-tray ENDOF
CDROM-INIT-REQUIRED   OF cdrom-try-close-tray ENDOF
CDROM-TRAY-MAYBE-OPEN OF cdrom-try-close-tray ENDOF
ENDCASE
d# 1000 ms
LOOP
." Drive not ready !" cr false
;
: prep-disk ( -- ready? )
test-unit-ready not IF
." SCSI-DISK: Disk not ready ! "
." Sense " dup .sense-text ." [" . ." ]"
."  ASC " . ."  ASCQ " . cr
false EXIT THEN true
;
: open ( -- true | false )
scsi-disk-debug? IF
." SCSI-DISK: open [" .s ." ] unit is " my-unit . . ."  [" .s ." ]" cr
THEN
my-unit " set-address" $call-parent
inquiry dup 0= IF drop false EXIT THEN
scsi-disk-debug? IF
." ---- inquiry: ----" cr
dup 100 dump cr
." ------------------" cr
THEN
dup inquiry-data>peripheral c@ e0 and 0 <> IF
inquiry-data>peripheral c@ 7f <> IF
." SCSI-DISK: Unsupported PQ != 0" cr
THEN
false EXIT
THEN
inquiry-data>peripheral c@ CASE
5   OF true to is_cdrom ENDOF
7   OF true to is_cdrom ENDOF
ENDCASE
scsi-disk-debug? IF
is_cdrom IF
." SCSI-DISK: device treated as CD-ROM" cr
ELSE
." SCSI-DISK: device treated as disk" cr
THEN
THEN
is_cdrom IF prep-cdrom ELSE prep-disk THEN
not IF false EXIT THEN
" max-transfer" $call-parent to max-transfer
read-capacity to max-block-num to block-size
max-block-num 100000000 = IF
read-capacity-16 to max-block-num to block-size
THEN
max-block-num 0= block-size 0= OR IF
." SCSI-DISK: Failed to get disk capacity!" cr
FALSE EXIT
THEN
scsi-disk-debug? IF
." Capacity: " max-block-num . ." blocks of " block-size . cr
THEN
0 0 " deblocker" $open-package dup deblocker ! dup IF 
" disk-label" find-package IF
my-args rot interpose
THEN
THEN 0<>
;
: close ( -- )
deblocker @ close-package ;
: seek ( pos.lo pos.hi -- status )
s" seek" deblocker @ $call-method ;
: read ( addr len -- actual )
s" read" deblocker @ $call-method ;
: write ( addr len -- actual )
s" write" deblocker @ $call-method
;
scsi-close
finish-device
ÿÿÿÿÿÿÿÿ ^8scsi-host-helpers.fs: check-retry-sense? ( sense-buf sense-len -- retry? )
8 < IF -1 EXIT THEN
dup sense-data>response-code c@ 7e and 70 = IF
dup sense-data>sense-key c@ e0 and IF drop -1 EXIT THEN
THEN
scsi-get-sense-data? IF 	( ascq asc sense-key )
dup 2 < IF 3drop 0 EXIT THEN
dup 2 = swap 6 = or nip nip IF 1 EXIT THEN
THEN
-1
;
0 INSTANCE VALUE rcmd-buf-addr
0 INSTANCE VALUE rcmd-buf-len
0 INSTANCE VALUE rcmd-dir
0 INSTANCE VALUE rcmd-cmd-addr
0 INSTANCE VALUE rcmd-cmd-len
: retry-scsi-command ( buf-addr buf-len dir cmd-addr cmd-len #retries -- ... )
>r \ stash #retries
to rcmd-cmd-len to rcmd-cmd-addr to rcmd-dir to rcmd-buf-len to rcmd-buf-addr
0  \ dummy status & sense
r> \ retreive #retries              ( stat #retries )
0 DO
0<> IF 2drop THEN
rcmd-buf-addr
rcmd-buf-len
rcmd-dir
rcmd-cmd-addr
rcmd-cmd-len
execute-scsi-command		( [ sense-buf sense-len ] stat )
dup 0= IF LEAVE THEN
dup -1 = IF LEAVE THEN
dup 2 = IF  			( sense-buf sense-len stat )
>r	\ stash stat		( sense-buf sense len )
2dup
check-retry-sense?	        ( sense-buf sense-len retry? )
r> swap \ unstash stat	( sense-buf sense-len stat retry? )
CASE
0 OF 3drop 0 LEAVE ENDOF	\ Swallow error, return 0
-1 OF LEAVE ENDOF		\ No retry
ENDCASE
ELSE \ Anything other than busy -> exit
dup 8 <> IF LEAVE THEN
THEN
a ms
LOOP
;
CREATE sector d# 512 allot
CREATE cdb 10 allot
: (inquiry) ( size -- buffer | NULL )
dup cdb scsi-build-inquiry
sector swap scsi-dir-read cdb scsi-param-size 10 retry-scsi-command
0= IF sector ELSE 2drop 0 THEN
;
: inquiry ( -- buffer | NULL )
d# 36 (inquiry) 0= IF 0 EXIT THEN
sector inquiry-data>add-length c@ 5 +
(inquiry)
;
: report-luns ( -- [ sector ] true | false )
200 cdb scsi-build-report-luns
sector 200 scsi-dir-read cdb scsi-param-size 10 retry-scsi-command
0= IF sector true ELSE drop false THEN
;
: make-disk-alias                               ( $name srplun -- )
>r 2dup r> -rot                             ( $name srplun $name)
find-alias 0<> IF 4drop exit THEN
get-node node>path
20 allot
" /disk@" string-cat                        ( $name srplun npath npathl )
rot base @ >r hex (u.) r> base ! string-cat ( $name $diskpath )
set-alias
;
ÿÿÿÿÿÿÿÿ°l8scsi-probe-helpers.fs: wrapped-inquiry ( -- true | false )
inquiry 0= IF false EXIT THEN
sector inquiry-data>peripheral c@ e0 and 0 =
;
: scsi-read-lun     ( addr -- lun true | false )
dup c@ C0 AND CASE
40 OF w@-be 3FFF AND TRUE ENDOF
0  OF w@-be          TRUE ENDOF
dup dup OF ." Unsupported LUN format = " . cr FALSE ENDOF
ENDCASE
;
: vscsi-report-luns ( -- array ndev )
dev-max-target 3 << alloc-mem dup
0                                    ( devarray devcur ndev )
dev-max-target 0 DO
i 0 dev-generate-srplun (set-target)
report-luns nip IF
sector l@                     ( devarray devcur ndev size )
sector 8 + swap               ( devarray devcur ndev lunarray size )
dup 8 + dup alloc-mem         ( devarray devcur ndev lunarray size size+ mem )
dup rot 0 fill                ( devarray devcur ndev lunarray size mem )
dup >r swap move r>           ( devarray devcur ndev mem )
dup sector l@ 3 >> 0 ?DO      ( devarray devcur ndev mem memcur )
dup dup scsi-read-lun IF
j swap dev-generate-srplun  swap x! 8 +
ELSE
2drop
THEN
LOOP drop
rot                           ( devarray ndev mem devcur )
dup >r x! r> 8 +              ( devarray ndev devcur )
swap 1 +
ELSE
dev-max-target 1 = IF
16 alloc-mem ( devarray devcur ndev mem )
dup 16 0 fill ( devarray devcur ndev mem )
dup 0 0 dev-generate-srplun swap x!  ( devarray devcur ndev mem )
rot x!  ( devarray ndev )
1 +
UNLOOP EXIT
THEN
THEN
LOOP
nip
;
: make-media-alias ( $name srplun -- )
>r
get-next-alias ?dup IF
r> make-disk-alias
ELSE
r> drop
THEN
;
: scsi-find-disks      ( -- )
."        SCSI: Looking for devices" cr
vscsi-report-luns
0 ?DO
dup x@
BEGIN
dup x@
dup 0= IF drop TRUE ELSE
(set-target) wrapped-inquiry IF
."           " current-target (u.) type ."  "
sector inquiry-data>peripheral c@ CASE
0   OF ." DISK     : " " disk"  current-target make-media-alias ENDOF
5   OF ." CD-ROM   : " " cdrom" current-target make-media-alias ENDOF
7   OF ." OPTICAL  : " " cdrom" current-target make-media-alias ENDOF
e   OF ." RED-BLOCK: " " disk"  current-target make-media-alias ENDOF
dup dup OF ." ? (" . 8 emit 29 emit 5 spaces ENDOF
ENDCASE
sector .inquiry-text cr
THEN
8 + FALSE
THEN
UNTIL drop
8 +
LOOP drop
;
ÿÿÿÿÿÿÿÿTSÅ0scsi-support.fsvocabulary scsi-words                  \ create new word list named 'scsi-words'
also scsi-words  definitions           \ place next definitions into new list
false  value   scsi-param-debug        \ common debugging flag
d# 0   value   scsi-param-size         \ length of CDB processed last
h# 0   value   scsi-param-control      \ control word for CDBs as defined in SAM-4
d# 0   value   scsi-param-errors       \ counter for detected errors
: scsi-inc-errors
scsi-param-errors 1 + to scsi-param-errors
;
00 CONSTANT scsi-cmd-test-unit-ready
STRUCT
/c	FIELD test-unit-ready>operation-code     \ 00h
4	FIELD test-unit-ready>reserved           \ unused
/c	FIELD test-unit-ready>control            \ control byte as specified in SAM-4
CONSTANT scsi-length-test-unit-ready
: scsi-build-test-unit-ready  ( cdb -- )
dup scsi-length-test-unit-ready erase  ( cdb )
scsi-param-control swap test-unit-ready>control c!  ( )
scsi-length-test-unit-ready to scsi-param-size   \ update CDB length
;
a0 CONSTANT scsi-cmd-report-luns
STRUCT
/c	FIELD report-luns>operation-code     \ a0h
1	FIELD report-luns>reserved           \ unused
/c      FIELD report-luns>select-report      \ report select byte
3       FIELD report-luns>reserved2          \ unused
/l      FIELD report-luns>alloc-length       \ report length
1	FIELD report-luns>reserved3          \ unused
/c	FIELD report-luns>control            \ control byte
CONSTANT scsi-length-report-luns
: scsi-build-report-luns ( alloc-len cdb -- )
dup scsi-length-report-luns erase              \ 12 bytes CDB
scsi-cmd-report-luns over	          ( alloc-len cdb cmd cdb )
report-luns>operation-code c!	          ( alloc-len cdb )
scsi-param-control over report-luns>control c! ( alloc-len cdb )
report-luns>alloc-length l!	  \ size of Data-In Buffer
scsi-length-report-luns to scsi-param-size     \ update CDB length
;
03 CONSTANT scsi-cmd-request-sense
STRUCT
/c	FIELD request-sense>operation-code     \ 03h
3	FIELD request-sense>reserved           \ unused
/c	FIELD request-sense>allocation-length  \ buffer-length for data response
/c	FIELD request-sense>control            \ control byte as specified in SAM-4
CONSTANT scsi-length-request-sense
: scsi-build-request-sense    ( alloc-len cdb -- )
>r                         ( alloc-len )  ( R: -- cdb )
r@ scsi-length-request-sense erase  ( alloc-len )
scsi-cmd-request-sense r@           ( alloc-len cmd cdb )
request-sense>operation-code c!     ( alloc-len )
dup d# 252 >                        \ buffer length too big ?
IF
scsi-inc-errors
drop d# 252                      \ replace with 252
ELSE
dup d# 18 <                      \ allocated buffer too small ?
IF
scsi-inc-errors
drop 0                        \ reject return data
THEN
THEN                                      ( alloclen )
r@ request-sense>allocation-length c!     (  )
scsi-param-control r> request-sense>control c!  ( alloc-len cdb )  ( R: cdb -- )
scsi-length-request-sense to scsi-param-size  \ update CDB length
;
70 CONSTANT scsi-response(request-sense-0)
71 CONSTANT scsi-response(request-sense-1)
STRUCT
/c FIELD sense-data>response-code   \ 70h (current errors) or 71h (deferred errors)
/c FIELD sense-data>obsolete
/c FIELD sense-data>sense-key       \ D3..D0 = sense key, D7 = EndOfMedium
/l FIELD sense-data>info
/c FIELD sense-data>alloc-length    \ <= 244 (for max size)
/l FIELD sense-data>command-info
/c FIELD sense-data>asc             \ additional sense key
/c FIELD sense-data>ascq            \ additional sense key qualifier
/c FIELD sense-data>unit-code
3  FIELD sense-data>key-specific
/c FIELD sense-data>add-sense-bytes \ start of appended extra bytes
CONSTANT scsi-length-sense-data
: scsi-get-sense-data                  ( addr -- ascq asc sense-key )   
>r                                  ( R: -- addr )
r@ sense-data>response-code c@ 7f and 72 >= IF
r@ 3 + c@                           ( ascq )
r@ 2 + c@                           ( ascq asc ) 
r> 1 + c@ 0f and                    ( ascq asc sense-key )
ELSE
r@ sense-data>ASCQ c@               ( ascq )
r@ sense-data>ASC c@                ( ascq asc )
r> sense-data>sense-key c@ 0f and   ( ascq asc sense-key ) ( R: addr -- )
THEN
;
: scsi-get-sense-data?                 ( addr -- false | ascq asc sense-key true )
dup
sense-data>response-code c@
7e AND dup 70 = swap 72 = or         \ Response code (some devices have MSB set)
IF
scsi-get-sense-data TRUE
ELSE
drop FALSE        \ drop addr
THEN
;
: scsi-get-sense-ID?                 ( addr -- false | ascq asc sense-key true )
dup
sense-data>response-code c@
7e AND 70 =          \ Response code (some devices have MSB set)
IF
scsi-get-sense-data        ( ascq asc sense-key )
10 lshift                  ( ascq asc sense-key16 )
swap 8 lshift or           ( ascq sense-key+asc )
swap or                    \ 24-bit sense-ID ( sense-key+asc+ascq )
TRUE
ELSE
drop FALSE        \ drop addr
THEN
;
12 CONSTANT scsi-cmd-inquiry
STRUCT
/c	FIELD inquiry>operation-code     \ 0x12
/c	FIELD inquiry>reserved           \ + EVPD-Bit (vital product data)
/c	FIELD inquiry>page-code          \ page code for vital product data (if used)
/w	FIELD inquiry>allocation-length  \ length of Data-In-Buffer
/c	FIELD inquiry>control            \ control byte as specified in SAM-4
CONSTANT scsi-length-inquiry
: scsi-build-inquiry                   ( alloc-len cdb -- )
dup scsi-length-inquiry erase       \ 6 bytes CDB
scsi-cmd-inquiry over				   ( alloc-len cdb cmd cdb )
inquiry>operation-code c!	         ( alloc-len cdb )
scsi-param-control over inquiry>control c! ( alloc-len cdb )
inquiry>allocation-length w!	      \ size of Data-In Buffer
scsi-length-inquiry to scsi-param-size    \ update CDB length
;
STRUCT
/c	   FIELD inquiry-data>peripheral       \ qualifier and device type
/c	   FIELD inquiry-data>reserved1
/c	   FIELD inquiry-data>version          \ supported SCSI version (1,2,3)
/c	   FIELD inquiry-data>data-format
/c	   FIELD inquiry-data>add-length       \ total block length - 4
/c	   FIELD inquiry-data>flags1
/c	   FIELD inquiry-data>flags2
/c	   FIELD inquiry-data>flags3
d# 8	FIELD inquiry-data>vendor-ident     \ vendor string
d# 16	FIELD inquiry-data>product-ident    \ device string
/l 	FIELD inquiry-data>product-revision \ revision string
d# 20	FIELD inquiry-data>vendor-specific  \ optional params
CONSTANT scsi-length-inquiry-data
25 CONSTANT scsi-cmd-read-capacity-10  \ command code
STRUCT                                 \ SCSI 10-byte CDB structure
/c	FIELD read-cap-10>operation-code
/c	FIELD read-cap-10>reserved1
/l	FIELD read-cap-10>lba
/w	FIELD read-cap-10>reserved2
/c	FIELD read-cap-10>reserved3
/c	FIELD read-cap-10>control
CONSTANT scsi-length-read-cap-10
: scsi-build-read-cap-10                     ( cdb -- )
dup scsi-length-read-cap-10 erase         ( cdb )
scsi-cmd-read-capacity-10 over            ( cdb cmd cdb )
read-cap-10>operation-code c!             ( cdb )
scsi-param-control swap read-cap-10>control c! ( )
scsi-length-read-cap-10 to scsi-param-size    \ update CDB length
;
STRUCT
/l	FIELD read-cap-10-data>max-lba
/l	FIELD read-cap-10-data>block-size
CONSTANT scsi-length-read-cap-10-data
: scsi-get-capacity-10                 ( addr -- block-size #blocks )
>r                                  ( addr -- ) ( R: -- addr )
r@ read-cap-10-data>block-size l@   ( block-size )
r> read-cap-10-data>max-lba l@      ( block-size #blocks ) ( R: addr -- )
;
9e CONSTANT scsi-cmd-read-capacity-16        \ command code
STRUCT                                       \ SCSI 16-byte CDB structure
/c	FIELD read-cap-16>operation-code
/c	FIELD read-cap-16>service-action
/l	FIELD read-cap-16>lba-high
/l	FIELD read-cap-16>lba-low
/l	FIELD read-cap-16>allocation-length    \ should be 32
/c	FIELD read-cap-16>reserved
/c	FIELD read-cap-16>control
CONSTANT scsi-length-read-cap-16
: scsi-build-read-cap-16  ( cdb -- )
>r r@                                     ( R: -- cdb )
scsi-length-read-cap-16 erase             (  )
scsi-cmd-read-capacity-16                 ( code )
r@ read-cap-16>operation-code c!          (  )
10 r@ read-cap-16>service-action c!
d# 32                                     \ response size 32 bytes
r@ read-cap-16>allocation-length l!       (  )
scsi-param-control r> read-cap-16>control c! ( R: cdb -- )
scsi-length-read-cap-16 to scsi-param-size \ update CDB length
;
STRUCT
/l	FIELD read-cap-16-data>max-lba-high    \ upper quadlet of Max-LBA
/l	FIELD read-cap-16-data>max-lba-low     \ lower quadlet of Max-LBA
/l	FIELD read-cap-16-data>block-size      \ logical block length in bytes
/c	FIELD read-cap-16-data>protect         \ type of protection (4 bits)
/c	FIELD read-cap-16-data>exponent        \ logical blocks per physical blocks
/w	FIELD read-cap-16-data>lowest-aligned  \ first LBA of a phsy. block
10 FIELD read-cap-16-data>reserved        \ 16 reserved bytes
CONSTANT scsi-length-read-cap-16-data        \ results in 32
: scsi-get-capacity-16                       ( addr -- block-size #blocks )
>r                                        ( R: -- addr )
r@ read-cap-16-data>block-size l@         ( block-size )
r@ read-cap-16-data>max-lba-high l@       ( block-size #blocks-high )
d# 32 lshift                              ( block-size #blocks-upper )
r> read-cap-16-data>max-lba-low l@ +      ( block-size #blocks ) ( R: addr -- )
;
5a CONSTANT scsi-cmd-mode-sense-10
STRUCT
/c	FIELD mode-sense-10>operation-code
/c	FIELD mode-sense-10>res-llbaa-dbd-res
/c	FIELD mode-sense-10>pc-page-code       \ page code + page control
/c	FIELD mode-sense-10>sub-page-code
3	FIELD mode-sense-10>reserved2
/w	FIELD mode-sense-10>allocation-length
/c	FIELD mode-sense-10>control
CONSTANT scsi-length-mode-sense-10
: scsi-build-mode-sense-10                   ( alloc-len subpage page cdb -- )
>r                                        ( alloc-len subpage page ) ( R: -- cdb )
r@ scsi-length-mode-sense-10 erase        \ 10 bytes CDB
scsi-cmd-mode-sense-10                    ( alloc-len subpage page cmd )
r@  mode-sense-10>operation-code c!		   ( alloc-len subpage page )
10 r@ mode-sense-10>res-llbaa-dbd-res c!  \ long LBAs accepted
r@ mode-sense-10>pc-page-code c!	         ( alloc-len subpage )
r@ mode-sense-10>sub-page-code c!	      ( alloc-len )
r@ mode-sense-10>allocation-length w!     ( )
scsi-param-control r> mode-sense-10>control c!  ( R: cdb -- )
scsi-length-mode-sense-10 to scsi-param-size  \ update CDB length
;
STRUCT
/w	FIELD mode-sense-10-data>head-length
/c	FIELD mode-sense-10-data>head-medium
/c	FIELD mode-sense-10-data>head-param
/c	FIELD mode-sense-10-data>head-longlba
/c	FIELD mode-sense-10-data>head-reserved
/w	FIELD mode-sense-10-data>head-descr-len
CONSTANT scsi-length-mode-sense-10-data
: .mode-sense-data   ( addr -- )
cr
dup mode-sense-10-data>head-length
w@ ." Mode Length: " .d space
dup mode-sense-10-data>head-medium
c@ ." / Medium Type: " .d space
dup mode-sense-10-data>head-longlba
c@ ." / Long LBA: " .d space
mode-sense-10-data>head-descr-len
w@ ." / Descr. Length: " .d
;
28 CONSTANT scsi-cmd-read-10
STRUCT
/c FIELD read-10>operation-code
/c FIELD read-10>protect
/l FIELD read-10>block-address      \ logical block address (32bits)
/c FIELD read-10>group
/w FIELD read-10>length             \ transfer length (16-bits)
/c FIELD read-10>control
CONSTANT scsi-length-read-10
: scsi-build-read-10                         ( block# #blocks cdb -- )
>r                                        ( block# #blocks )  ( R: -- cdb )
r@ scsi-length-read-10 erase             \ 10 bytes CDB
scsi-cmd-read-10 r@ read-10>operation-code c! ( block# #blocks )
r@ read-10>length w!                      ( block# )
r@ read-10>block-address l!               (  )
scsi-param-control r> read-10>control c!  ( R: cdb -- )
scsi-length-read-10 to scsi-param-size    \ update CDB length
;
a8 CONSTANT scsi-cmd-read-12
STRUCT
/c FIELD read-12>operation-code     \ code: a8
/c FIELD read-12>protect            \ RDPROTECT, DPO, FUA, FUA_NV
/l FIELD read-12>block-address      \ lba
/l FIELD read-12>length             \ transfer length (32bits)
/c FIELD read-12>group              \ group number
/c FIELD read-12>control
CONSTANT scsi-length-read-12
: scsi-build-read-12                         ( block# #blocks cdb -- )
>r                                        ( block# #blocks )  ( R: -- cdb )
r@ scsi-length-read-12 erase             \ 12 bytes CDB
scsi-cmd-read-12 r@ read-12>operation-code c! ( block# #blocks )
r@ read-12>length l!                      ( block# )
r@ read-12>block-address l!               (  )
scsi-param-control r> read-12>control c!  ( R: cdb -- )
scsi-length-read-12 to scsi-param-size    \ update CDB length
;
88 CONSTANT scsi-cmd-read-16
STRUCT
/c FIELD read-16>operation-code     \ code: 88
/c FIELD read-16>protect            \ RDPROTECT, DPO, FUA, FUA_NV
/x FIELD read-16>block-address      \ lba
/l FIELD read-16>length             \ transfer length (32bits)
/c FIELD read-16>group              \ group number
/c FIELD read-16>control
CONSTANT scsi-length-read-16
: scsi-build-read-16                         ( block# #blocks cdb -- )
>r                                        ( block# #blocks )  ( R: -- cdb )
r@ scsi-length-read-16 erase              \ 16 bytes CDB
scsi-cmd-read-16 r@ read-16>operation-code c! ( block# #blocks )
r@ read-16>length l!                      ( block# )
r@ read-16>block-address x!               (  )
scsi-param-control r> read-16>control c!  ( R: cdb -- )
scsi-length-read-16 to scsi-param-size    \ update CDB length
;
: scsi-build-read?   ( block# #blocks cdb -- length )
over              ( block# #blocks cdb #blocks )
fffe >            \ tx-length (#blocks) exceeds 16-bit limit ?
IF
scsi-build-read-12   ( block# #blocks cdb -- )
scsi-length-read-12  ( length )
ELSE                    ( block# #blocks cdb )
scsi-build-read-10   ( block# #blocks cdb -- )
scsi-length-read-10  ( length )
THEN
;
2A CONSTANT scsi-cmd-write-10
STRUCT
/c FIELD write-10>operation-code
/c FIELD write-10>protect
/l FIELD write-10>block-address            \ logical block address (32bits)
/c FIELD write-10>group
/w FIELD write-10>length                   \ transfer length (16-bits)
/c FIELD write-10>control
CONSTANT scsi-length-write-10
: scsi-build-write-10                         ( block# #blocks cdb -- )
>r                                         ( block# #blocks )  ( R: -- cdb )
r@ scsi-length-write-10 erase              \ 10 bytes CDB
scsi-cmd-write-10 r@ write-10>operation-code c! ( block# #blocks )
r@ write-10>length w!                      ( block# )
r@ write-10>block-address l!               (  )
scsi-param-control r> write-10>control c!  ( R: cdb -- )
scsi-length-write-10 to scsi-param-size    \ update CDB length
;
8A CONSTANT scsi-cmd-write-16
STRUCT
/c FIELD write-16>operation-code
/c FIELD write-16>protect                  \ RDPROTECT, DPO, FUA, FUA_NV
/x FIELD write-16>block-address            \ LBA
/l FIELD write-16>length                   \ Transfer length (32-bits)
/c FIELD write-16>group                    \ Group number
/c FIELD write-16>control
CONSTANT scsi-length-write-16
: scsi-build-write-16                         ( block# #blocks cdb -- )
>r                                         ( block# #blocks )  ( R: -- cdb )
r@ scsi-length-write-16 erase              \ 16 bytes CDB
scsi-cmd-write-16 r@ write-16>operation-code c! ( block# #blocks )
r@ write-16>length l!                      ( block# )
r@ write-16>block-address x!               (  )
scsi-param-control r> write-16>control c!  ( R: cdb -- )
scsi-length-write-16 to scsi-param-size    \ update CDB length
;
1b CONSTANT scsi-cmd-start-stop-unit
STRUCT
/c FIELD start-stop-unit>operation-code
/c FIELD start-stop-unit>immed
/w FIELD start-stop-unit>reserved
/c FIELD start-stop-unit>pow-condition
/c FIELD start-stop-unit>control
CONSTANT scsi-length-start-stop-unit
f1 CONSTANT scsi-const-active-power    \ param used for start-stop-unit
f2 CONSTANT scsi-const-idle-power      \ param used for start-stop-unit
f3 CONSTANT scsi-const-standby-power   \ param used for start-stop-unit
3  CONSTANT scsi-const-load            \ param used for start-stop-unit
2  CONSTANT scsi-const-eject           \ param used for start-stop-unit
1  CONSTANT scsi-const-start
0  CONSTANT scsi-const-stop
: scsi-build-start-stop-unit                 ( state# cdb -- )
>r                                        ( state# )  ( R: -- cdb )
r@ scsi-length-start-stop-unit erase      \ 6 bytes CDB
scsi-cmd-start-stop-unit r@ start-stop-unit>operation-code c!
dup 3 >
IF
4 lshift                         \ shift to upper nibble
THEN                                ( state )
r@ start-stop-unit>pow-condition c!       (  )
scsi-param-control r> start-stop-unit>control c!  ( R: cdb -- )
scsi-length-start-stop-unit to scsi-param-size  \ update CDB length
;
2b CONSTANT scsi-cmd-seek
STRUCT
/c FIELD seek>operation-code
/c FIELD seek>reserved1
/l FIELD seek>lba
3  FIELD seek>reserved2
/c FIELD seek>control
CONSTANT scsi-length-seek
: scsi-build-seek  ( lba cdb -- )
>r              ( lba )  ( R: -- cdb )
r@ scsi-length-seek erase           \ 10 bytes CDB
scsi-cmd-seek r@ seek>operation-code c!
r> seek>lba l!  (  )  ( R: cdb -- )
scsi-length-seek to scsi-param-size \ update CDB length
;
STRUCT
/w FIELD media-event-data-len
/c FIELD media-event-nea-class
/c FIELD media-event-supp-class
/l FIELD media-event-data
CONSTANT scsi-length-media-event
: scsi-build-get-media-event                     ( cdb -- )
dup c erase				         ( cdb )
4a over c!				         ( cdb )
01 over 1 + c!
10 over 4 + c!
08 over 8 + c!
drop
;
: .sense-text ( scode -- )
case
0    OF s" OK"               ENDOF
1    OF s" RECOVERED ERR"    ENDOF
2    OF s" NOT READY"        ENDOF
3    OF s" MEDIUM ERROR"     ENDOF
4    OF s" HARDWARE ERR"     ENDOF
5    OF s" ILLEGAL REQUEST"  ENDOF
6    OF s" UNIT ATTENTION"   ENDOF
7    OF s" DATA PROTECT"     ENDOF
8    OF s" BLANK CHECK"      ENDOF
9    OF s" VENDOR SPECIFIC"  ENDOF
a    OF s" COPY ABORTED"     ENDOF
b    OF s" ABORTED COMMAND"  ENDOF
d    OF s" VOLUME OVERFLOW"  ENDOF
e    OF s" MISCOMPARE"       ENDOF
dup  OF s" UNKNOWN"          ENDOF
endcase
5b emit type 5d emit
;
: .status-text  ( stat -- )
case
00  OF s" GOOD"                  ENDOF
02  OF s" CHECK CONDITION"       ENDOF
04  OF s" CONDITION MET"         ENDOF
08  OF s" BUSY"                  ENDOF
18  OF s" RESERVATION CONFLICT"  ENDOF
28  OF s" TASK SET FULL"         ENDOF
30  OF s" ACA ACTIVE"            ENDOF
40  OF s" TASK ABORTED"          ENDOF
dup OF s" UNKNOWN"               ENDOF
endcase
5b emit type 5d emit
;
: .dec3-2 ( prenum postnum -- )
swap
base @ >r                           \ save actual base setting
decimal                             \ show decimal values
4 .r 2e emit
dup 9 <= IF 30 emit THEN .d         \ 3 pre-decimal, right aligned
r> base !                           \ restore base
;
: .capacity-text  ( block-size #blocks -- )
scsi-param-debug                    \ debugging flag set ?
IF                                  \ show additional info
2dup
cr
." LBAs: " .d                    \ highest logical block number
." / Block-Size: " .d
." / Total Capacity: "
THEN
*                                   \ calculate total capacity
dup d# 1000000000000 >=             \ check terabyte limit
IF
d# 1000000000000 /mod
swap
d# 10000000000 /                 \ limit remainder to two digits
.dec3-2 ." TB"                   \ show terabytes as xxx.yy
ELSE
dup d# 1000000000 >=             \ check gigabyte limit
IF
d# 1000000000 /mod
swap
d# 10000000 /
.dec3-2 ." GB"                \ show gigabytes as xxx.yy
ELSE
dup d# 1000000 >=
IF
d# 1000000 /mod            \ check mega byte limit
swap
d# 10000 /
.dec3-2 ." MB"             \ show megabytes as xxx.yy
ELSE
dup d# 1000 >=             \ check kilo byte limit
IF
d# 1000 /mod
swap
d# 10 /
.dec3-2 ." kB"
ELSE
.d ."  Bytes"
THEN
THEN
THEN
THEN
;
: .inquiry-text  ( addr -- )
22 emit     \ enclose text with "
dup inquiry-data>vendor-ident      8 type space
dup inquiry-data>product-ident    10 type space
inquiry-data>product-revision  4 type
22 emit
;
: scsi-supp-init  ( -- )
false   to scsi-param-debug         \ no debug strings
h# 0   to scsi-param-size
h# 0   to scsi-param-control        \ common CDB control byte
d# 0   to scsi-param-errors         \ local errors (param limits)
;
true  CONSTANT scsi-dir-read
false CONSTANT scsi-dir-write
0 VALUE scsi-context                   \ addr of word list on top
: scsi-init  ( -- )
also scsi-words                     \ append scsi word-list
context  to scsi-context            \ save for close process
scsi-supp-init                      \ preset all scsi-param-xxx values
scsi-param-debug
IF
space ." SCSI-SUPPORT OPENED" cr
.wordlists
THEN
;
: scsi-close  ( -- )
scsi-param-debug
IF
space ." Closing SCSI-SUPPORT .. " cr
THEN
context scsi-context =              \ scsi word list still active ?
IF
scsi-param-errors 0<>          \ any errors occurred ?
IF
cr ." ** WARNING: " scsi-param-errors .d
." SCSI Errors occurred ** " cr
THEN
previous                         \ remove scsi word list on top
0 to scsi-context                \ prevent from being misinterpreted
ELSE
cr ." ** WARNING: Trying to close non-open SCSI-SUPPORT (1) ** " cr
THEN
scsi-param-debug
IF
.wordlists
THEN
;
s" scsi-init" $find drop               \ return execution pointer, when included
previous                               \ remove scsi word list from search path
definitions                            \ place next definitions into previous list
ÿÿÿÿÿÿÿÿq pâ0evaluator.fsvariable ip
variable fcode-end 
variable fcode-num
1 value fcode-spread
2 value fcode-offset
false value eva-debug?
true value fcode-debug?
defer fcode-rb@
defer fcode@
' c@ to fcode-rb@
create token-table 2000 cells allot    \ 1000h = 4096d
: ?offset16 ( -- true|false )
fcode-offset 2 =
;
: ?arch64 ( -- true|false )
cell 8 =
;
: ?bigendian ( -- true|false )
deadbeef fcode-num !
fcode-num ?arch64 IF 4 + THEN
c@ de =
;
: reset-fcode-end ( -- )
false fcode-end !
;
: get-ip ( -- n )
ip @
;
: set-ip ( n -- )
ip !
;
: next-ip ( -- )
get-ip 1+ set-ip
;
: jump-n-ip ( n -- )
get-ip + set-ip
;
: read-byte ( -- n )
get-ip fcode-rb@
;
: ?compile-mode ( -- on|off )
state @
;
: save-evaluator-state
get-ip               eva-debug? IF ." saved ip "           dup . cr THEN
fcode-end @          eva-debug? IF ." saved fcode-end "    dup . cr THEN
fcode-offset         eva-debug? IF ." saved fcode-offset " dup . cr THEN
fcode-spread         eva-debug? IF ." saved fcode-spread " dup . cr THEN
['] fcode@ behavior  eva-debug? IF ." saved fcode@ "       dup . cr THEN
;
: restore-evaluator-state
eva-debug? IF ." restored fcode@ "       dup . cr THEN  to fcode@
eva-debug? IF ." restored fcode-spread " dup . cr THEN  to fcode-spread
eva-debug? IF ." restored fcode-offset " dup . cr THEN  to fcode-offset
eva-debug? IF ." restored fcode-end "    dup . cr THEN  fcode-end !
eva-debug? IF ." restored ip "           dup . cr THEN  set-ip
;
: token-table-index ( fcode# -- addr )
cells token-table +
;
: join-immediate ( xt immediate? addr -- xt+immediate? addr )
-rot + swap
;
: split-immediate ( xt+immediate? -- xt immediate? )
dup 1 and 2dup - rot drop swap
;
: literal, ( n -- )
postpone literal
;
: fc-string,
postpone sliteral
dup c, bounds ?do i c@ c, loop
;
: set-token ( xt immediate? fcode# -- )
token-table-index join-immediate !
;
: get-token ( fcode# -- xt immediate? )
token-table-index @ split-immediate
;
?bigendian [IF]                       \ Big endian access functions first
: read-fcode-num16 ( -- n )
0 fcode-num !
?arch64 IF
read-byte fcode-num 6 + C!
next-ip
read-byte fcode-num 7 + C!
ELSE
read-byte fcode-num 2 + C!
next-ip
read-byte fcode-num 3 + C!
THEN
fcode-num @
;
: read-fcode-num32 ( -- n )
0 fcode-num !
?arch64 IF
read-byte fcode-num 4 + C!
next-ip
read-byte fcode-num 5 + C!
next-ip
read-byte fcode-num 6 + C!
next-ip
read-byte fcode-num 7 + C!
ELSE
read-byte fcode-num 0 + C!
next-ip
read-byte fcode-num 1 + C!
next-ip
read-byte fcode-num 2 + C!
next-ip
read-byte fcode-num 3 + C!
THEN
fcode-num @
;
[ELSE]                                \ Now the little endian access functions
: read-fcode-num16 ( -- n )
0 fcode-num !
?arch64 IF
read-byte fcode-num 7 + C!
next-ip
read-byte fcode-num 6 + C!
ELSE
read-byte fcode-num 1 + C!
next-ip
read-byte fcode-num 0 + C!
THEN
fcode-num @
;
: read-fcode-num32 ( adr -- n )
0 fcode-num !
?arch64 IF
read-byte fcode-num 7 + C!
next-ip
read-byte fcode-num 6 + C!
next-ip
read-byte fcode-num 5 + C!
next-ip
read-byte fcode-num 4 + C!
ELSE
read-byte fcode-num 3 + C!
next-ip
read-byte fcode-num 2 + C!
next-ip
read-byte fcode-num 1 + C!
next-ip
read-byte fcode-num 0 + C!
THEN
fcode-num @
;
[THEN]
: read-fcode# ( -- FCode# )
read-byte
dup 01 0F between IF drop read-fcode-num16 THEN
;
: read-header ( adr -- )
next-ip read-byte        drop
next-ip read-fcode-num16 drop
next-ip read-fcode-num32 drop
;
: read-fcode-string ( -- str len )
read-byte            \ get string length ( -- len )
next-ip get-ip       \ get string addr   ( -- len str )
swap                 \ type needs the parameters swapped ( -- str len )
dup 1- jump-n-ip     \ jump to the end of the string in FCode
;
-1 VALUE break-fcode-addr
0 VALUE break-fcode-steps
: evaluate-fcode ( -- )
BEGIN
get-ip break-fcode-addr = IF
TRUE fcode-end !
THEN
fcode-end @ 0=
WHILE
fcode@                               ( fcode# )
eva-debug? IF
dup
get-ip 8 u.r ." : "
." [" 3 u.r ." ] "
THEN
get-token 0= ?compile-mode AND IF    ( xt )
compile,
ELSE                                 \ immediate or "interpretation" mode
eva-debug? IF dup xt>name type space THEN
execute
THEN
eva-debug? IF .s cr THEN
break-fcode-steps IF
break-fcode-steps 1- TO break-fcode-steps
break-fcode-steps 0= IF
TRUE fcode-end !
THEN
THEN
next-ip
REPEAT
;
: steps-fcode  ( n -- )
to break-fcode-steps
break-fcode-addr >r -1 to break-fcode-addr
reset-fcode-end
evaluate-fcode
r> to break-fcode-addr
;
: step-fcode  ( -- )
1 steps-fcode
;
: fcode-revision ( -- n )
00030000 \ major * 65536 + minor
;
: b(lit) ( -- n )
next-ip read-fcode-num32
?compile-mode IF literal, THEN
;
: b(")
next-ip read-fcode-string
?compile-mode IF fc-string, align postpone count THEN
;
: b(')
next-ip read-fcode# get-token drop ?compile-mode IF literal, THEN
;
: ?jump-direction ( n -- )
dup 8000 >= IF
10000 -           \ Create cell-sized negative value
THEN
fcode-offset -       \ IP is already behind offset, so subtract offset size
;
: ?negative
8000 and
;
: dest-on-top
0 >r BEGIN dup @ 0= WHILE >r REPEAT
BEGIN r> dup WHILE swap REPEAT
drop
;
: read-fcode-offset
next-ip
?offset16 IF
read-fcode-num16
ELSE
read-byte
dup 80 and IF FF00 or THEN       \ Fake 16-bit signed offset
THEN
;
: b?branch ( flag -- )
?compile-mode IF
read-fcode-offset ?negative IF
dest-on-top postpone until
ELSE
postpone if
THEN
ELSE
( flag ) IF
fcode-offset jump-n-ip       \ Skip over offset value
ELSE
read-fcode-offset
?jump-direction jump-n-ip
THEN
THEN
; immediate
: bbranch ( -- )
?compile-mode IF
read-fcode-offset
?negative IF
dest-on-top postpone again
ELSE
postpone else
get-ip next-ip fcode@ B2 = IF
drop
ELSE
set-ip
THEN
THEN
ELSE
read-fcode-offset ?jump-direction jump-n-ip
THEN
; immediate
: b(<mark) ( -- )
?compile-mode IF postpone begin THEN
; immediate
: b(>resolve) ( -- )
?compile-mode IF postpone then THEN
; immediate
: b(;)
<semicolon> compile, reveal
postpone [
; immediate
: b(:) ( -- )
<colon> compile, ]
; immediate
: b(case) ( sel -- sel )
postpone case
; immediate
: b(endcase)
postpone endcase
; immediate
: b(of)
postpone of
read-fcode-offset drop   \ read and discard offset
; immediate
: b(endof)
postpone endof
read-fcode-offset drop
; immediate
: b(do)
postpone do
read-fcode-offset drop
; immediate
: b(?do)
postpone ?do
read-fcode-offset drop
; immediate
: b(loop)
postpone loop
read-fcode-offset drop
; immediate
: b(+loop)
postpone +loop
read-fcode-offset drop
; immediate
: b(leave)
postpone leave
; immediate
0 VALUE fc-instance?
: fc-instance  ( -- )   \ Mark next defining word as instance-specific.
TRUE TO fc-instance?
;
: new-token  \ unnamed local fcode function
align here next-ip read-fcode# 0 swap set-token
;
: external-token ( -- )  \ named local fcode function
next-ip read-fcode-string
header         ( str len -- )  \ create a header in the current dictionary entry
new-token
;
: new-token
eva-debug? IF
s" x" get-ip >r next-ip read-fcode# r> set-ip (u.) $cat strdup
header
THEN
new-token
;
: named-token
fcode-debug? IF
external-token
ELSE
next-ip read-fcode-string 2drop       \ Forget about the name
new-token
THEN
;
: b(to) ( val -- )
next-ip read-fcode#
get-token drop                           ( val xt )
dup @                                    ( val xt @xt )
dup <value> =  over <defer> = OR IF
drop
>body cell -
?compile-mode IF
literal, postpone !
ELSE
!
THEN
ELSE
<create> <> IF                         ( val xt )
TRUE ABORT" Invalid destination for FCODE b(to)"
THEN
dup cell+ @                           ( val xt @xt+1cell )
dup <instancevalue> <>  swap <instancedefer> <> AND IF
TRUE ABORT" Invalid destination for FCODE b(to)"
THEN
>body @                               ( val instance-offset )
?compile-mode IF
literal,  postpone >instance  postpone !
ELSE
>instance !
THEN
ELSE
THEN
; immediate
: b(value)
fc-instance? IF
<create> ,                \ Needed for "(instance?)" for example
<instancevalue> ,
(create-instance-var)
FALSE TO fc-instance?
ELSE
<value> , ,
THEN
reveal
;
: b(variable)
fc-instance? IF
<create> ,                \ Needed for "(instance?)"
<instancevariable> ,
0 (create-instance-var)
FALSE TO fc-instance?
ELSE
<variable> , 0 ,
THEN
reveal
;
: b(constant)
<constant> , , reveal
;
: undefined-defer
cr cr ." Uninitialized defer word has been executed!" cr cr
true fcode-end !
;
: b(defer)
fc-instance? IF
<create> ,                \ Needed for "(instance?)"
<instancedefer> ,
['] undefined-defer (create-instance-var)
reveal
FALSE TO fc-instance?
ELSE
<defer> , reveal
postpone undefined-defer
THEN
;
: b(create)
<variable> ,
postpone noop reveal
;
: b(field) ( E: addr -- addr+offset ) ( F: offset size -- offset+size )
<colon> , over literal,
postpone +
<semicolon> compile,
reveal
+
;
: b(buffer:) ( E: -- a-addr) ( F: size -- )
fc-instance? IF
<create> ,                \ Needed for "(instance?)"
<instancebuffer> ,
(create-instance-buf)
FALSE TO fc-instance?
ELSE
<buffer:> , allot
THEN
reveal
;
: suspend-fcode ( -- )
noop        \ has to be implemented more efficiently ;-)
;
: offset16 ( -- )
2 to fcode-offset
;
: version1 ( -- )
1 to fcode-spread
1 to fcode-offset
read-header
;
: start0 ( -- )
0 to fcode-spread
offset16
read-header
;
: start1 ( -- )
1 to fcode-spread
offset16
read-header
;
: start2 ( -- )
2 to fcode-spread
offset16
read-header
;
: start4 ( -- )
4 to fcode-spread
offset16
read-header
;
: end0 ( -- )
true fcode-end !
;
: end1 ( -- )
end0
;
: ferror ( -- )
clear end0
cr ." FCode# " fcode-num @ . ." not assigned!"
cr ." FCode evaluation aborted." cr
." ( -- S:" depth . ." R:" rdepth . ." ) " .s cr
abort
;
: reset-local-fcodes
FFF 800 DO ['] ferror 0 i set-token LOOP
;
: byte-load ( addr xt -- )
>r >r
save-evaluator-state
r> r>
reset-fcode-end
1 to fcode-spread
dup 1 = IF drop ['] rb@ THEN to fcode-rb@
set-ip
reset-local-fcodes
depth >r
evaluate-fcode
r> depth 1- <> IF
clear end0
cr ." Ambiguous stack depth after byte-load!"
cr ." FCode evaluation aborted." cr cr
ELSE
restore-evaluator-state
THEN
['] c@ to fcode-rb@
;
: fc-c@   ( addr -- byte )   dup MIN-RAM-SIZE > IF rb@ ELSE c@ THEN ;
: fc-w@   ( addr -- word )   dup MIN-RAM-SIZE > IF rw@ ELSE w@ THEN ;
: fc-<w@  ( addr -- word )   fc-w@ dup 8000 >= IF 10000 - THEN ;
: fc-l@   ( addr -- long )   dup MIN-RAM-SIZE > IF rl@ ELSE l@ THEN ;
: fc-<l@  ( addr -- long )   fc-l@ signed ;
: fc-x@   ( addr -- dlong )  dup MIN-RAM-SIZE > IF rx@ ELSE x@ THEN ;
: fc-c!   ( byte addr -- )   dup MIN-RAM-SIZE > IF rb! ELSE c! THEN ;
: fc-w!   ( word addr -- )   dup MIN-RAM-SIZE > IF rw! ELSE w! THEN ;
: fc-l!   ( long addr -- )   dup MIN-RAM-SIZE > IF rl! ELSE l! THEN ;
: fc-x!   ( dlong addr -- )  dup MIN-RAM-SIZE > IF rx! ELSE x! THEN ;
: fc-fill ( add len byte -- )  2 pick MIN-RAM-SIZE > IF rfill ELSE fill THEN ;
: fc-move ( src dst len -- )
2 pick MIN-RAM-SIZE >        \ Check src
2 pick MIN-RAM-SIZE >        \ Check dst
OR IF rmove ELSE move THEN
;
: free-virtual  ( virt size -- )
s" map-out" $call-parent
;
: map-low  ( phys.lo ... size -- virt )
my-space swap s" map-in" $call-parent
;
: mac-address  ( -- mac-str mac-len )
s" local-mac-address" get-my-property IF
0 0
THEN
;
VARIABLE #line
0 #line !
VARIABLE #out
0 #out !
: display-status  ( n -- )
." Device status: " . cr
;
VARIABLE group-code
0 group-code !
: dma-alloc  ( byte -- virtual )
s" dma-alloc" $call-parent
;
: my-params  ( -- addr len )
s" params" get-my-property IF
0 0
THEN
;
: sbus-intr>cpu  ( sbus-intr# -- cpu-intr# )
;
: intr  ( interrupt# vector -- )
>r sbus-intr>cpu encode-int r> encode-int+ s" intr" property
;
: driver  ( addr len -- )
encode-string s" name" property
;
: processor-type  ( -- cpu-type )
0
;
: firmware-version  ( -- n )
10000                          \ Just a dummy value
;
: fcode-version  ( -- n )
fcode-revision
;
: fc-abort ." FCode called abort: IP " get-ip . ( ." STACK: " .s ) depth dup 0< IF abort THEN . rdepth . cr  abort ;
: fc-0 ." 0(lit): STACK ( S: " depth . ." R: " rdepth . ." ): " depth 0> IF .s THEN 0 ;
: fc-1 ." 1(lit): STACK ( S: " depth . ." R: " rdepth . ." ): " depth 0> IF .s THEN 1 ;
: parse-1hex 1 hex-decode-unit ;
: fc-set-pci-mmio-tokens  ( -- )
['] rw@-le  0 232 set-token
['] rw!-le  0 233 set-token
['] rl@-le  0 234 set-token
['] rl!-le  0 235 set-token
['] rx@-le  0 22E set-token
['] rx!-le  0 22F set-token
;
: fc-set-normal-mmio-tokens  ( -- )
['] rw@  0 232 set-token
['] rw!  0 233 set-token
['] rl@  0 234 set-token
['] rl!  0 235 set-token
['] rx@  0 22E set-token
['] rx!  0 22F set-token
;
: reset-token-table
FFF 0 DO ['] ferror 0 i set-token LOOP
;
reset-token-table
' end0 0        00 set-token
' b(lit)      1 10 set-token
' b(')        1 11 set-token
' b(")        1 12 set-token
' bbranch     1 13 set-token
' b?branch    1 14 set-token
' b(loop)     1 15 set-token
' b(+loop)    1 16 set-token
' b(do)       1 17 set-token
' b(?do)      1 18 set-token
' i           0 19 set-token
' j           0 1A set-token
' b(leave)    1 1B set-token
' b(of)       1 1C set-token
' execute     0 1D set-token
' +           0 1E set-token
' -           0 1F set-token
' *           0 20 set-token
' /           0 21 set-token
' mod         0 22 set-token 
' and         0 23 set-token 
' or          0 24 set-token 
' xor         0 25 set-token 
' invert      0 26 set-token 
' lshift      0 27 set-token 
' rshift      0 28 set-token 
' >>a         0 29 set-token 
' /mod        0 2A set-token 
' u/mod       0 2B set-token
' negate      0 2C set-token 
' abs         0 2D set-token 
' min         0 2E set-token 
' max         0 2F set-token 
' >r          0 30 set-token 
' r>          0 31 set-token 
' r@          0 32 set-token 
' exit        0 33 set-token 
' 0=          0 34 set-token 
' 0<>         0 35 set-token 
' 0<          0 36 set-token 
' 0<=         0 37 set-token 
' 0>          0 38 set-token 
' 0>=         0 39 set-token 
' <           0 3A set-token
' >           0 3B set-token
' =           0 3C set-token
' <>          0 3D set-token
' u>          0 3E set-token
' u<=         0 3F set-token 
' u<          0 40 set-token 
' u>=         0 41 set-token 
' >=          0 42 set-token 
' <=          0 43 set-token 
' between     0 44 set-token 
' within      0 45 set-token 
' DROP        0 46 set-token
' DUP         0 47 set-token
' OVER        0 48 set-token
' SWAP        0 49 set-token
' ROT         0 4A set-token
' -ROT        0 4B set-token
' TUCK        0 4C set-token
' nip         0 4D set-token 
' pick        0 4E set-token 
' roll        0 4F set-token 
' ?dup        0 50 set-token 
' depth       0 51 set-token 
' 2drop       0 52 set-token 
' 2dup        0 53 set-token 
' 2over       0 54 set-token 
' 2swap       0 55 set-token 
' 2rot        0 56 set-token 
' 2/          0 57 set-token 
' u2/         0 58 set-token 
' 2*          0 59 set-token 
' /c          0 5A set-token
' /w          0 5B set-token 
' /l          0 5C set-token 
' /n          0 5D set-token 
' ca+         0 5E set-token 
' wa+         0 5F set-token 
' la+         0 60 set-token 
' na+         0 61 set-token 
' char+       0 62 set-token 
' wa1+        0 63 set-token 
' la1+        0 64 set-token 
' cell+       0 65 set-token 
' chars       0 66 set-token 
' /w*         0 67 set-token 
' /l*         0 68 set-token 
' cells       0 69 set-token 
' on          0 6A set-token 
' off         0 6B set-token 
' +!          0 6C set-token 
' @           0 6D set-token 
' fc-l@       0 6E set-token 
' fc-w@       0 6F set-token 
' fc-<w@      0 70 set-token 
' fc-c@       0 71 set-token 
' !           0 72 set-token 
' fc-l!       0 73 set-token 
' fc-w!       0 74 set-token 
' fc-c!       0 75 set-token 
' 2@          0 76 set-token 
' 2!          0 77 set-token 
' fc-move     0 78 set-token 
' fc-fill     0 79 set-token 
' comp        0 7A set-token 
' noop        0 7B set-token
' lwsplit     0 7C set-token 
' wljoin      0 7D set-token 
' lbsplit     0 7E set-token 
' bljoin      0 7F set-token 
' wbflip      0 80 set-token 
' upc         0 81 set-token 
' lcc         0 82 set-token 
' pack        0 83 set-token 
' count       0 84 set-token 
' body>       0 85 set-token 
' >body       0 86 set-token 
' fcode-revision 0 87 set-token 
' span        0 88 set-token 
' unloop      0 89 set-token 
' expect      0 8A set-token 
' alloc-mem   0 8B set-token
' free-mem    0 8C set-token
' key?        0 8D set-token 
' key         0 8E set-token 
' emit        0 8F set-token 
' type        0 90 set-token 
' (cr         0 91 set-token
' cr          0 92 set-token 
' #out        0 93 set-token
' #line       0 94 set-token
' hold        0 95 set-token 
' <#          0 96 set-token 
' u#>         0 97 set-token 
' sign        0 98 set-token 
' u#          0 99 set-token 
' u#s         0 9A set-token 
' u.          0 9B set-token 
' u.r         0 9C set-token 
' .           0 9D set-token 
' .r          0 9E set-token 
' .s          0 9F set-token 
' base        0 A0 set-token 
' $number     0 A2 set-token 
' digit       0 A3 set-token 
' -1          0 A4 set-token
'  0          0 A5 set-token
'  1          0 A6 set-token
'  2          0 A7 set-token
'  3          0 A8 set-token
' bl          0 A9 set-token
' bs          0 AA set-token 
' bell        0 AB set-token 
' bounds      0 AC set-token 
' here        0 AD set-token 
' aligned     0 AE set-token 
' wbsplit     0 AF set-token 
' bwjoin      0 B0 set-token 
' b(<mark)    1 B1 set-token
' b(>resolve) 1 B2 set-token
' new-token   0 B5 set-token 
' named-token 0 B6 set-token
' b(:)        1 B7 set-token
' b(value)    1 B8 set-token 
' b(variable) 1 B9 set-token 
' b(constant) 1 BA set-token 
' b(create)   1 BB set-token 
' b(defer)    1 BC set-token 
' b(buffer:)  1 BD set-token 
' b(field)    1 BE set-token 
' fc-instance 1 C0 set-token 
' b(;)        1 C2 set-token
' b(to)       1 C3 set-token 
' b(case)     1 C4 set-token
' b(endcase)  1 C5 set-token
' b(endof)    1 C6 set-token
' #           0 C7 set-token
' #s          0 C8 set-token
' #>          0 C9 set-token
' external-token 0 CA set-token 
' $find       0 CB set-token
' offset16    0 CC set-token 
' evaluate    0 CD set-token
' c,          0  D0 set-token
' w,          0  D1 set-token
' l,          0  D2 set-token
' ,           0  D3 set-token
' um*         0  D4 set-token
' um/mod      0  D5 set-token
' d+          0  D8 set-token
' d-          0  D9 set-token
' get-token   0  DA set-token 
' set-token   0  DB set-token 
' state       0  DC set-token  \ possibly broken
' compile,    0  DD set-token
' behavior    0  DE set-token 
' start0            0  F0 set-token
' start1            0  F1 set-token
' start2            0  F2 set-token
' start4            0  F3 set-token
' ferror            0  FC set-token
' version1          0  FD set-token
' end1              0  FF set-token
' dma-alloc         0 101 set-token    \ Obsolete
' my-address        0 102 set-token 
' my-space          0 103 set-token
' free-virtual      0 105 set-token
' my-params         0 10f set-token    \ Obsolete
' property          0 110 set-token
' encode-int        0 111 set-token
' encode+           0 112 set-token
' encode-phys       0 113 set-token
' encode-string     0 114 set-token
' encode-bytes      0 115 set-token
' reg               0 116 set-token
' intr              0 117 set-token    \ Obsolete
' driver            0 118 set-token    \ Obsolete
' model             0 119 set-token
' device-type       0 11A set-token
' parse-2int        0 11B set-token
' is-install        0 11C set-token    \ for framebuffer code
' is-remove         0 11D set-token    \ for framebuffer code
' is-selftest       0 11E set-token    \ for framebuffer code
' new-device        0 11F set-token
' diagnostic-mode?  0 120 set-token
' display-status    0 121 set-token    \ Maybe obsolete
' memory-test-suite 0 122 set-token
' group-code        0 123 set-token    \ Obsolete
' mask              0 124 set-token
' get-msecs         0 125 set-token
' ms                0 126 set-token
' finish-device     0 127 set-token
' decode-phys       0 128 set-token
' interpose         0 12B set-token    \ Recommended practice: Interposition
' map-low           0 130 set-token
' sbus-intr>cpu     0 131 set-token    \ Obsolete
' #lines            0 150 set-token
' #columns          0 151 set-token
' line#             0 152 set-token
' column#           0 153 set-token
' inverse?          0 154 set-token
' inverse-screen?   0 155 set-token
' draw-character    0 157 set-token
' reset-screen      0 158 set-token
' toggle-cursor     0 159 set-token
' erase-screen      0 15A set-token
' blink-screen      0 15B set-token
' invert-screen     0 15C set-token
' insert-characters 0 15D set-token
' delete-characters 0 15E set-token
' insert-lines      0 15F set-token
' delete-lines      0 160 set-token
' draw-logo         0 161 set-token
' frame-buffer-adr  0 162 set-token
' screen-height     0 163 set-token
' screen-width      0 164 set-token
' window-top        0 165 set-token
' window-left       0 166 set-token
' default-font      0 16A set-token
' set-font          0 16B set-token
' char-height       0 16C set-token
' char-width        0 16D set-token
' >font             0 16E set-token
' fontbytes         0 16F set-token
' fb8-draw-character 0 180 set-token
' fb8-reset-screen   0 181 set-token
' fb8-toggle-cursor  0 182 set-token
' fb8-erase-screen   0 183 set-token
' fb8-blink-screen   0 184 set-token
' fb8-invert-screen  0 185 set-token
' fb8-insert-characters 0 186 set-token
' fb8-delete-characters 0 187 set-token
' fb8-insert-lines   0 188 set-token
' fb8-delete-lines   0 189 set-token
' fb8-draw-logo      0 18A set-token
' fb8-install        0 18B set-token
' mac-address       0 1A4 set-token
' device-name       0 201 set-token
' my-args           0 202 set-token
' my-self           0 203 set-token
' find-package      0 204 set-token
' open-package      0 205 set-token
' close-package     0 206 set-token
' find-method       0 207 set-token
' call-package      0 208 set-token
' $call-parent      0 209 set-token
' my-parent         0 20A set-token
' ihandle>phandle   0 20B set-token
' my-unit           0 20D set-token
' $call-method      0 20E set-token
' $open-package     0 20F set-token
' processor-type    0 210 set-token       \ Obsolete
' firmware-version  0 211 set-token       \ Obsolete
' fcode-version     0 212 set-token       \ Obsolete
' (is-user-word)    0 214 set-token
' suspend-fcode     0 215 set-token
' fc-abort          0 216 set-token
' catch             0 217 set-token
' throw             0 218 set-token
' get-my-property   0 21A set-token
' decode-int        0 21B set-token
' decode-string     0 21C set-token
' get-inherited-property 0 21D set-token  
' delete-property   0 21E set-token  
' get-package-property 0 21F set-token
' cpeek             0 220 set-token 
' wpeek             0 221 set-token 
' lpeek             0 222 set-token 
' cpoke             0 223 set-token 
' wpoke             0 224 set-token 
' lpoke             0 225 set-token 
' lwflip            0 226 set-token 
' lbflip            0 227 set-token 
' lbflips           0 228 set-token
' rb@               0 230 set-token
' rb!               0 231 set-token
fc-set-normal-mmio-tokens                 \ Set rw@, rw!, rl@, rl!, rx@ and rx!
' wbflips           0 236 set-token 
' lwflips           0 237 set-token 
' child             0 23B set-token
' peer              0 23C set-token
' next-property     0 23D set-token
' byte-load         0 23E set-token
' set-args          0 23F set-token
' left-parse-string 0 240 set-token
' bxjoin            0 241 set-token
' fc-<l@            0 242 set-token
' lxjoin            0 243 set-token
' wxjoin            0 244 set-token
' x,                0 245 set-token
' fc-x@             0 246 set-token
' fc-x!             0 247 set-token
' /x                0 248 set-token
' /x*               0 249 set-token
' xa+               0 24A set-token
' xa1+              0 24B set-token
' xbflip            0 24C set-token
' xbflips           0 24D set-token
' xbsplit           0 24E set-token
' xlflip            0 24F set-token
' xlflips           0 250 set-token
' xlsplit           0 251 set-token
' xwflip            0 252 set-token
' xwflips           0 253 set-token
' xwsplit           0 254 set-token
80 cells CONSTANT LOCALS-STACK-SIZE
LOCALS-STACK-SIZE BUFFER: localsstackbuf
localsstackbuf VALUE localsstack
: fc-local@  ( n -- val )
cells localsstack swap - @
;
: fc-local-1-@  1 fc-local@ ;
: fc-local-2-@  2 fc-local@ ;
: fc-local-3-@  3 fc-local@ ;
: fc-local-4-@  4 fc-local@ ;
: fc-local-5-@  5 fc-local@ ;
: fc-local-6-@  6 fc-local@ ;
: fc-local-7-@  7 fc-local@ ;
: fc-local-8-@  8 fc-local@ ;
: fc-local!  ( val n -- )
cells localsstack swap - !
;
: fc-local-1-!  1 fc-local! ;
: fc-local-2-!  2 fc-local! ;
: fc-local-3-!  3 fc-local! ;
: fc-local-4-!  4 fc-local! ;
: fc-local-5-!  5 fc-local! ;
: fc-local-6-!  6 fc-local! ;
: fc-local-7-!  7 fc-local! ;
: fc-local-8-!  8 fc-local! ;
0 VALUE uses-locals?
: (fc-push-locals)  ( ... n -- )
8 cells localsstack + TO localsstack
localsstack localsstackbuf -
LOCALS-STACK-SIZE > ABORT" Locals stack exceeded!"
?dup IF
( ... n ) 1 swap DO
i fc-local!              \ Store pre-initialized locals
-1 +LOOP
THEN
;
: fc-push-locals  ( n -- )
uses-locals? ABORT" Definition pushes locals multiple times!"
true TO uses-locals?
( n ) ['] literal execute
['] (fc-push-locals) compile,
;
: fc-push-0-locals  0 fc-push-locals ;
: fc-push-1-locals  1 fc-push-locals ;
: fc-push-2-locals  2 fc-push-locals ;
: fc-push-3-locals  3 fc-push-locals ;
: fc-push-4-locals  4 fc-push-locals ;
: fc-push-5-locals  5 fc-push-locals ;
: fc-push-6-locals  6 fc-push-locals ;
: fc-push-7-locals  7 fc-push-locals ;
: fc-push-8-locals  8 fc-push-locals ;
: fc-pop-locals  ( -- )
localsstack 8 cells - TO localsstack
localsstack localsstackbuf - 0 < ABORT" Locals stack undeflow!"
;
: fc-locals-exit
uses-locals? IF
['] fc-pop-locals compile,
THEN
['] exit compile,
;
: fc-locals-b(;)
uses-locals? IF
['] fc-pop-locals compile,
THEN
false TO uses-locals?
['] b(;) execute
;
: fc-set-locals-tokens  ( -- )
['] fc-push-0-locals 1 407 set-token
['] fc-push-1-locals 1 408 set-token
['] fc-push-2-locals 1 409 set-token
['] fc-push-3-locals 1 40a set-token
['] fc-push-4-locals 1 40b set-token
['] fc-push-5-locals 1 40c set-token
['] fc-push-6-locals 1 40d set-token
['] fc-push-7-locals 1 40e set-token
['] fc-push-8-locals 1 40f set-token
['] fc-local-1-@ 0 410 set-token
['] fc-local-2-@ 0 411 set-token
['] fc-local-3-@ 0 412 set-token
['] fc-local-4-@ 0 413 set-token
['] fc-local-5-@ 0 414 set-token
['] fc-local-6-@ 0 415 set-token
['] fc-local-7-@ 0 416 set-token
['] fc-local-8-@ 0 417 set-token
['] fc-local-1-! 0 418 set-token
['] fc-local-2-! 0 419 set-token
['] fc-local-3-! 0 41a set-token
['] fc-local-4-! 0 41b set-token
['] fc-local-5-! 0 41c set-token
['] fc-local-6-! 0 41d set-token
['] fc-local-7-! 0 41e set-token
['] fc-local-8-! 0 41f set-token
['] fc-locals-exit 1 33 set-token
['] fc-locals-b(;) 1 c2 set-token
;
fc-set-locals-tokens
0 value buff
0 value buff-size
' read-fcode# to fcode@
: execute-rom-fcode ( addr len | false -- )
reset-fcode-end
?dup IF
diagnostic-mode? IF ." , executing ..." cr THEN
dup >r r@ alloc-mem dup >r swap rmove
r@ set-ip evaluate-fcode
diagnostic-mode? IF ." Done." cr THEN
r> r> free-mem
THEN
;
: rom-code-ignored  ( image-addr name len -- image-addr )
diagnostic-mode? IF
type ."  code found in image " dup .  ." , ignoring ..." cr
ELSE
2drop
THEN
;
: pci-find-rom ( baseaddr -- addr )
dup IF
dup rw@-le aa55 = IF
diagnostic-mode? IF ." Device ROM header found at " dup . cr THEN
ELSE
drop 0
THEN
THEN
;
: pci-find-fcode ( baseaddr -- addr len | false )
BEGIN
1ff NOT and                       \ Image must start at 512 byte boundary
pci-find-rom dup
WHILE
dup 18 + rw@-le +              ( pcir-addr )
dup rw@-le 4350 ( 'PC' ) <>    ( pcir-addr hasPC? )
over 2+ rw@-le 5249 ( 'IR' ) <> OR IF
diagnostic-mode? IF
." Invalid PCI Data structure, ignoring ROM contents" cr
THEN
drop false EXIT
THEN                           ( pcir-addr )
dup 14 + rb@ CASE              \ Get image code type
0 OF s" Intel x86 BIOS" rom-code-ignored ENDOF
1 OF
diagnostic-mode? IF
." Open Firmware FCode found in image at " dup . cr
THEN
dup 1ff NOT AND          \ Back to the ROM image header
dup 2+ rw@-le +          \ Pointer to FCODE (PCI bus binding ch.9)
swap 10 + rw@-le 200 *   \ Image length
EXIT
ENDOF
2 OF s" HP PA RISC" rom-code-ignored ENDOF
3 OF s" EFI" rom-code-ignored ENDOF
dup OF s" Unknown type" rom-code-ignored ENDOF
ENDCASE
dup 15 + rb@ 80 and IF         \ End of last image?
drop false EXIT
THEN
dup 10 + rw@-le  200 * +       \ Next image start
REPEAT
;
: pci-execute-fcode  ( baseaddr -- )
pci-find-fcode dup 0= IF
2drop EXIT
THEN                                 ( addr len )
fc-set-pci-mmio-tokens               \ Prepare PCI access functions
['] execute-rom-fcode CATCH IF
cr ." FCODE failed!" cr
2drop
THEN
fc-set-normal-mmio-tokens            \ Restore normal MMIO access functions
;
ÿÿÿÿÿÿÿÿ@8default-font.bin(($$~$$~$$*((

*0H00@8DD@"THT"    |(||00  @8DDDDDDDD88DD @x8DD8@@@HH~~@@@xx @@@xDDD8~B   8DDD8DDDD88DDD<D800000000 @ @@ ~~  "$BNRN@@$$$$~BBBB|BBB||BBB|<"`@@@@`"<xDBBBBBBDx~@@@~~@@@~~@@@~~@@@@<B@@@@NBB<BBBB~~BBBB<<$BDHP``PHDB@@@@@@@@@~Bf~ZBBBBBBBbbRRJJFFB$BBBBBB$pHDDHp@@@@$BBBBBJ$pHDDHpPHDB @@ ~~BBBBBBBBB<BBBBB$$$$BBBBBBBZfBBB$$$$BBBB$$~B  B~0        0@  <fB~ 8D<D:@@@@XdDDdX8D@@D8<LDDL<8Dx@D884LDL4D8@@@XdDDDDDH0@@@DHPpHDB08T****jX$$$$v""""XdDdX@@@4LDL4xD@@@@$$8$$$$$DDD((*****DD((D"" < <  $THDDD((ÿÿÿÿÿÿÿÿ x <0pci-phb.fs0 VALUE phb-debug?
1000 CONSTANT tce-ps		\ Default TCE page size is 4K
tce-ps 1- CONSTANT tce-mask
." Populating " pwd cr
: decode-unit ( addr len -- phys.lo ... phys.hi )
2 hex-decode-unit       \ decode string
b lshift swap           \ shift the devicenumber to the right spot
8 lshift or             \ add the functionnumber
0 0 rot                 \ make phys.lo = 0 = phys.mid
;
: encode-unit ( phys.lo phys-mid phys.hi -- unit-str unit-len )
nip nip                     \ forget the phys.lo and phys.mid
dup 8 rshift 7 and swap     \ calculate function number
B rshift 1F and             \ calculate device number
over IF 2 ELSE nip 1 THEN   \ create string with dev#,fn# or dev# only?
hex-encode-unit
;
0 VALUE my-puid
: setup-puid
s" reg" get-node get-property 0= IF
decode-64 to my-puid 2drop
THEN
;
setup-puid
: config-b@  puid >r my-puid TO puid rtas-config-b@ r> TO puid ;
: config-w@  puid >r my-puid TO puid rtas-config-w@ r> TO puid ;
: config-l@  puid >r my-puid TO puid rtas-config-l@ r> TO puid ;
: config-b!  puid >r my-puid TO puid rtas-config-b! r> TO puid ;
: config-w!  puid >r my-puid TO puid rtas-config-w! r> TO puid ;
: config-l!  puid >r my-puid TO puid rtas-config-l! r> TO puid ;
: map-in ( phys.lo phys.mid phys.hi size -- virt )
phb-debug? IF cr ." map-in called: " .s cr THEN
drop nip nip                         ( phys.hi )
dup FF AND dup 10 28 WITHIN NOT swap 30 <> AND IF
cr ." phys.hi = " . cr
ABORT" map-in with illegal config space address"
THEN
00FFFFFF AND                         \ Need only bus-dev-fn+register bits
dup config-l@                        ( phys.hi' bar.lo )
dup 7 AND 4 = IF                     \ Is it a 64-bit BAR?
swap 4 + config-l@ lxjoin         \ Add upper part of 64-bit BAR
ELSE
nip
THEN
F NOT AND                            \ Clear indicator bits
translate-my-address
phb-debug? IF ." map-in done: " .s cr THEN
;
: map-out ( virt size -- )
phb-debug? IF ." map-out called: " .s cr THEN
2drop 
;
: dma-alloc ( size -- virt )
phb-debug? IF cr ." dma-alloc called: " .s cr THEN
tce-ps #aligned
alloc-mem
dup tce-mask and IF
." Warning: dma-alloc got unaligned memory!" cr
THEN
;
: dma-free ( virt size -- )
phb-debug? IF cr ." dma-free called: " .s cr THEN
tce-ps #aligned
free-mem
;
0 VALUE dma-window-liobn        \ Logical I/O bus number
0 VALUE dma-window-base         \ Start address of window
0 VALUE dma-window-size         \ Size of the window
0 VALUE bm-handle               \ Bitmap allocator handle
: (init-dma-window-vars)  ( -- )
s" ibm,dma-window" calling-child get-property IF
s" ibm,dma-window" calling-child parent get-property 
ABORT" no dma-window property available"
THEN
decode-int TO dma-window-liobn
decode-64 TO dma-window-base
decode-64 TO dma-window-size
2drop
bm-handle 0= IF
dma-window-base dma-window-size tce-ps bm-allocator-init to bm-handle
dma-window-base 0= IF
bm-handle tce-ps bm-alloc drop
THEN
THEN
;
: (clear-dma-window-vars)  ( -- )
0 TO dma-window-liobn
0 TO dma-window-base
0 TO dma-window-size
;
: dma-align ( size virt -- aligned-size ) tce-mask and + tce-ps #aligned ;
: dma-trunc ( addr -- addr&~fff ) tce-mask not and ;
: dma-map-in  ( virt size cachable? -- devaddr )
phb-debug? IF cr ." dma-map-in called: " .s cr THEN
(init-dma-window-vars)
drop
over dma-align                     ( virt size ) \ size is aligned now
tuck                               ( size virt size )
bm-handle swap bm-alloc            ( size virt dev-addr ) \ dev-addr is aligned
dup 0 < IF
." Bitmap allocation Failed "
3drop
0 EXIT
THEN
swap                               ( size dev-addr virt )
2dup tce-mask and or >r            \ add page offset to the return value
dma-trunc 3 OR                     \ Truncate and add read and write perm
rot                                ( dev-addr virt size r: dev-addr )
0
?DO
2dup dma-window-liobn -rot     ( dev-addr virt liobn dev-addr virt r: dev-addr )
hv-put-tce ABORT" H_PUT_TCE failed"
tce-ps + swap tce-ps + swap    ( dev-addr' virt' r: dev-addr )
tce-ps +LOOP
(clear-dma-window-vars)
2drop
r>
;
: dma-map-out  ( virt devaddr size -- )
phb-debug? IF cr ." dma-map-out called: " .s cr THEN
(init-dma-window-vars)
rot drop                            ( devaddr size )
over dma-align
swap dma-trunc swap                 ( devaddr-trunc size-extended )
2dup bm-handle -rot bm-free
0
?DO
dup 0 dma-window-liobn -rot
hv-put-tce ABORT" H_PUT_TCE failed"
tce-ps +
tce-ps +LOOP
drop
(clear-dma-window-vars)
;
: dma-sync  ( virt devaddr size -- )
phb-debug? IF cr ." dma-sync called: " .s cr THEN
3drop
;
: open  true ;
: close ;
: phb-parse-ranges ( -- )
0  pci-next-io !
0  pci-max-io !
0  pci-next-mem !
0  pci-max-mem !
0  pci-next-mmio !
0  pci-max-mmio !
0  pci-next-mem64 !
0  pci-max-mem64 !
s" ranges" get-node get-property 0<> ABORT" ranges property not found"
BEGIN
dup
WHILE
decode-int                      \ Decode phys.hi
3000000 AND                     \ Filter out address space in phys.hi
CASE
1000000 OF                             \ I/O space?
decode-64 dup >r pci-next-io !      \ Decode PCI base address
decode-64 drop                      \ Forget the parent address
decode-64 r> + pci-max-io !         \ Decode size & calc max address
pci-next-io @ 0= IF
pci-next-io @ 10 + pci-next-io ! \ BARs must not be set to zero
THEN
ENDOF
2000000 OF                             \ 32-bit memory space?
decode-64 dup >r pci-next-mmio !    \ Decode base address
decode-64 drop                      \ Forget the parent address
decode-64 r> + pci-max-mmio !       \ calc max MMIO address
ENDOF
3000000 OF                             \ 64-bit memory space?
decode-64 dup >r pci-next-mem64 !
decode-64 drop                      \ Forget the parent address
decode-64 r> + pci-max-mem64 !
ENDOF
ENDCASE
REPEAT
2drop
pci-next-mem64 @ 0= IF
pci-next-mmio @ pci-next-mem !            \ Start of 32-bit prefetchable
pci-max-mmio @ pci-next-mmio @ - 2 /      \ Calculate new size
pci-next-mmio @ +                         \ The middle of the area
dup pci-max-mem !
pci-next-mmio !
THEN
phb-debug? IF
pci-var-out
THEN
;
: phb-pci-walk-bridge ( -- )
phb-debug? IF ."   Calling pci-walk-bridge " pwd cr THEN
get-node child ?dup 0= IF EXIT THEN    \ get and check if we have children
0 to pci-device-slots                  \ reset slot array to unpoppulated
BEGIN
dup                                \ Continue as long as there are children
WHILE
dup set-node                       \ Set child node as current node
my-space pci-set-slot              \ set the slot bit
my-space pci-htype@                \ read HEADER-Type
7f and                             \ Mask bit 7 - multifunction device
CASE
0 OF my-space pci-device-setup ENDOF  \ | set up the device
1 OF my-space pci-bridge-setup ENDOF  \ | set up the bridge
dup OF my-space [char] ? pci-out ENDOF
ENDCASE
peer
REPEAT drop
get-parent set-node
;
: phb-pci-bridge-probe ( addr -- )
dup pci-bridge-set-bases                      \ Set up all Base Registers
dup func-pci-bridge-range-props               \ Set up temporary "range"
my-space pci-bus-scnd@ TO pci-bus-number      \ Set correct current bus number
pci-device-vec-len 1+ TO pci-device-vec-len   \ increase the device-slot vector depth
pci-enable                                    \ enable mem/IO transactions
phb-pci-walk-bridge                           \ and walk the secondary bus
pci-device-vec-len 1- TO pci-device-vec-len   \ decrease the device-slot vector depth
pci-bridge-set-limits                         \ Set up all Limit Registers
;
: phb-pci-device-props ( addr -- )
dup pci-class-name device-name
dup pci-device-assigned-addresses-prop
drop
;
: phb-setup-children
puid >r                          \ Save old value of puid
my-puid TO puid                  \ Set current puid
phb-parse-ranges
1 TO pci-hotplug-enabled
s" qemu,mem-bar-min-align" get-node get-property 0= IF
decode-int TO pci-mem-bar-min-align
2drop
ELSE
10000 TO pci-mem-bar-min-align
THEN
s" qemu,phb-enumerated" get-node get-property 0<> IF
1 0 (probe-pci-host-bridge)
ELSE
2drop
['] phb-pci-bridge-probe TO func-pci-bridge-probe
['] phb-pci-device-props TO func-pci-device-props
phb-pci-walk-bridge          \ PHB device tree is already populated.
THEN
r> TO puid                       \ Restore previous puid
;
phb-setup-children
ÿÿÿÿÿÿÿÿ°}(rtas.fs371 cp
STRUCT
/l field rtas>token
/l field rtas>nargs
/l field rtas>nret
/l field rtas>args0
/l field rtas>args1
/l field rtas>args2
/l field rtas>args3
/l field rtas>args4
/l field rtas>args5
/l field rtas>args6
/l field rtas>args7
/l C * field rtas>args
/l field rtas>bla
CONSTANT /rtas-control-block
CREATE rtas-cb /rtas-control-block allot
rtas-cb /rtas-control-block erase
0 VALUE rtas-base
0 VALUE rtas-size
0 VALUE rtas-node
s" /rtas" find-node to rtas-node
373 cp
: enter-rtas ( -- )
rtas-cb rtas-base 0 rtas-base call-c drop
;
: rtas-get-token ( str len -- token | 0 )
rtas-node get-package-property IF 0 ELSE drop l@ THEN
;
: rtas-power-off   ( x y -- status )
[ s" power-off" rtas-get-token ] LITERAL rtas-cb rtas>token l!
2 rtas-cb rtas>nargs l!
1 rtas-cb rtas>nret l!
rtas-cb rtas>args0 l!
rtas-cb rtas>args1 l!
enter-rtas
rtas-cb rtas>args2 l@
;
: power-off  ( -- )  0 0 rtas-power-off ;
: rtas-system-reboot  ( -- status )
[ s" system-reboot" rtas-get-token ] LITERAL rtas-cb rtas>token l!
0 rtas-cb rtas>nargs l!
1 rtas-cb rtas>nret l!
rtas-cb rtas>args0 l!
enter-rtas
rtas-cb rtas>args1 l@
;
: rtas-start-cpu  ( pid loc r3 -- status )
[ s" start-cpu" rtas-get-token ] LITERAL rtas-cb rtas>token l!
3  rtas-cb rtas>nargs l!
1  rtas-cb rtas>nret l!
rtas-cb rtas>args2 l!
rtas-cb rtas>args1 l!
rtas-cb rtas>args0 l!
0 rtas-cb rtas>args3 l!
enter-rtas
rtas-cb rtas>args3 l@
;
: rtas-set-tce-bypass ( unit enable -- )
" ibm,set-tce-bypass" rtas-get-token rtas-cb rtas>token l!
2 rtas-cb rtas>nargs l!
0 rtas-cb rtas>nret l!
rtas-cb rtas>args1 l!
rtas-cb rtas>args0 l!
enter-rtas
;
: rtas-quiesce ( -- )
fdt-flatten-tree
dup hv-update-dt ?dup IF
dup -2 <> IF ." HV-UPDATE-DT error: " . cr ELSE drop THEN
THEN
fdt-flatten-tree-free
" quiesce" rtas-get-token rtas-cb rtas>token l!
0 rtas-cb rtas>nargs l!
0 rtas-cb rtas>nret l!
enter-rtas
;
0 value puid
: rtas-do-config-@ ( config-addr size -- value)
[ s" ibm,read-pci-config" rtas-get-token ] LITERAL rtas-cb rtas>token l!
4 rtas-cb rtas>nargs l!
2 rtas-cb rtas>nret l!
( addr size ) rtas-cb rtas>args3 l!
puid rtas-cb rtas>args2 l!
puid 20 rshift rtas-cb rtas>args1 l!
( addr ) rtas-cb rtas>args0 l!
enter-rtas
rtas-cb rtas>args4 l@ dup IF
drop ffffffff
ELSE
drop rtas-cb rtas>args5 l@
THEN
;
: rtas-do-config-! ( value config-addr size )
[ s" ibm,write-pci-config" rtas-get-token ] LITERAL rtas-cb rtas>token l!
5 rtas-cb rtas>nargs l!
1 rtas-cb rtas>nret l!
( value addr size ) rtas-cb rtas>args3 l!
puid rtas-cb rtas>args2 l!
puid 20 rshift rtas-cb rtas>args1 l!
( value addr ) rtas-cb rtas>args0 l!
( value ) rtas-cb rtas>args4 l!
enter-rtas
rtas-cb rtas>args5 l@ dup IF
." RTAS write config err " . cr
ELSE drop THEN
;
: rtas-config-b@ ( config-addr -- value )
1 rtas-do-config-@ ff and
;
: rtas-config-b! ( value config-addr -- )
1 rtas-do-config-!
;
: rtas-config-w@ ( config-addr -- value )
2 rtas-do-config-@ ffff and
;
: rtas-config-w! ( value config-addr -- )
2 rtas-do-config-!
;
: rtas-config-l@ ( config-addr -- value )
4 rtas-do-config-@ ffffffff and
;
: rtas-config-l! ( value config-addr -- )
4 rtas-do-config-!
;
: of-start-cpu rtas-start-cpu ;
' power-off to halt
' rtas-system-reboot to reboot
rtas-node set-node
: open true ;
: close ;
: store-rtas-loc ( adr )
s" /rtas" find-node >r
encode-int s" slof,rtas-base" r@ set-property
rtas-size encode-int s" slof,rtas-size" r> set-property
;
: instantiate-rtas ( adr -- entry )
dup store-rtas-loc
dup rtas-base swap rtas-size move
;
hv-rtas-get
s" rtas-size" rtas-node get-property
IF
dup encode-int s" rtas-size" rtas-node set-property
ELSE
decode-int nip nip
over 2dup < IF ." No enough space for RTAS: " . . cr abort THEN
2drop
THEN
to rtas-size
to rtas-base
device-end
374 cp
ÿÿÿÿÿÿÿÿØŸ0vtpm-sml.fs" /" find-device
new-device
false VALUE    vtpm-debug?
s" ibm,vtpm" 2dup device-name device-type
: separator-event ( start-pcr end-pcr -- )
tpm-add-event-separators                   ( errcode )
?dup IF
." VTPM: Error code from tpm-add-event-separators: " . cr
THEN
;
80 CONSTANT BCV_DEVICE_HDD
: measure-hdd-mbr ( addr length -- )
0 7 separator-event
BCV_DEVICE_HDD                             ( addr length bootdrv )
-rot                                       ( bootdrv addr length )
tpm-measure-bcv-mbr                        ( errcode )
?dup IF
." VTPM: Error code from tpm-measure-hdd: " . cr
THEN
;
: measure-gpt ( )
0 7 separator-event
tpm-measure-gpt
?dup IF
." VTPM: Error code from tpm-measure-gpt: " . cr
THEN
;
: leave-firmware ( -- )
tpm-leave-firmware                         ( errcode )
?dup IF
." VTPM: Error code from tpm-leave-firmware: " . cr
THEN
;
: measure-scrtm ( -- )
tpm-measure-scrtm                          ( errcode )
?dup IF
." VTPM: Error code from tpm-measure-scrtm: " . cr
THEN
;
: vtpm-menu
tpm-is-working IF
tpm20-menu
THEN
;
: open  true ;
: close ;
finish-device
device-end
s" /ibm,vtpm" find-node ?dup IF
s" measure-scrtm" rot $call-static
THEN
ÿÿÿÿÿÿÿÿp)8pci-device_1234_1111.fs." qemu vga" cr
s" qemu-vga.fs" included
ÿÿÿÿÿÿÿÿ8ñ8pci-device_1013_00b8.fsmy-space pci-device-generic-setup
d# 800 VALUE disp-width
d# 600 VALUE disp-height
d#   8 VALUE disp-depth
10 config-l@ translate-my-address f not AND  VALUE fb-base
-1 VALUE io-base
false VALUE is-installed?
: vga-io-xlate ( port -- addr )
io-base -1 = IF
dup translate-my-address fff not and to io-base
THEN
io-base +
;
: vga-w! ( value port -- )
vga-io-xlate rw!-le
;
: vga-w@ ( port -- value )
vga-io-xlate rw@-le
;
: vga-b! ( value port -- )
vga-io-xlate rb!
;
: vga-b@ ( port -- value )
vga-io-xlate rb@
;
: vga-crt@ ( index -- value )
3d4 vga-b!
3d5 vga-b@
;
: vga-crt! ( value index -- )
3d4 vga-b!
3d5 vga-b!
;
: vga-seq@ ( index -- value )
3c4 vga-b!
3c5 vga-b@
;
: vga-seq! ( value index -- )
3c4 vga-b!
3c5 vga-b!
;
: vga-att@ ( index -- value )
3c0 vga-b!
3c1 vga-b@
;
: vga-att! ( value index -- )
3c0 vga-b!
3c0 vga-b!
;
: vga-gfx@ ( index -- value )
3ce vga-b!
3cf vga-b@
;
: vga-gfx! ( value index -- )
3ce vga-b!
3cf vga-b!
;
: color! ( r g b number -- ) 
3c8 vga-b!
rot 2 >> 3c9 vga-b!
swap 2 >> 3c9 vga-b!
2 >> 3c9 vga-b!
;
: color@ ( number -- r g b ) 
3c8 vga-b!
3c9 vga-b@ 2 <<
3c9 vga-b@ 2 <<
3c9 vga-b@ 2 <<
;
: set-colors ( adr number #numbers -- )
over 3c8 vga-b!
swap DO
rb@ 2 >> 3c9 vga-b!
rb@ 2 >> 3c9 vga-b!
rb@ 2 >> 3c9 vga-b!
LOOP
3drop
;
: get-colors ( adr number #numbers -- )
3drop
;
include graphics.fs
: init-mode
3da vga-b@ drop \ reset flip flop
0f 3c2 vga-b!   \ color mode, ram enable, ...
12 06 vga-seq!  \ unlock extensions
05 06 vga-gfx!  \ graphic mode  
disp-depth CASE \ set depth
8 OF 01 07 vga-seq! ENDOF
f OF 07 07 vga-seq! ENDOF
10 OF 07 07 vga-seq! ENDOF
20 OF 09 07 vga-seq! ENDOF
ENDCASE
ff 02 vga-seq!  \ enable plane write
0a 04 vga-seq!  \ memory mode
03 17 vga-crt!  \ disable display
disp-width disp-depth 7 + 8 / * 3 >>
dup ff and 13 vga-crt!  \ bottom bits
4 >> 10 and 1b vga-crt! \ top bit
disp-width 3 >> 1 -                  01 vga-crt! \ H_DISP
disp-height 1 - ff and               12 vga-crt! \ V_DISP
disp-height 1 - 7 >> 2 and
disp-height 1 - 3 >> 40 and
or 10 or                             07 vga-crt! \ OFLOW
ff 18 vga-crt! \ LINE_COMPARE
40 09 vga-crt! \ MAX_SCAN
08 04 vga-crt! \ SYNC_START
0f 02 vga-crt! \ BLANK_START
00 0c vga-crt!
00 0d vga-crt!
40 05 vga-gfx! \ gfx mode
83 17 vga-crt! \ enable display
33 3c0 vga-b!  \ gfx in ar index
00 3c0 vga-b!
01 01 vga-seq! \ enable seq
;
: clear-screen
fb-base disp-width disp-height disp-depth 7 + 8 / * * 0 rfill
;
: read-settings
s" qemu,graphic-width" get-chosen IF
decode-int to disp-width 2drop
THEN
s" qemu,graphic-height" get-chosen IF
decode-int to disp-height 2drop
THEN
s" qemu,graphic-depth" get-chosen IF
decode-int nip nip     
dup 8 =
over f = or
over 10 = or
over 20 = or IF
to disp-depth
ELSE
." Unsupported bit depth, using 8bpp " drop cr
THEN
THEN
;
: add-legacy-reg
s" reg" get-node get-property IF
encode-start
ELSE
encode-bytes
THEN
my-space a1000000 or encode-int+ \ non-relocatable, aliased I/O space
1ce encode-64+ 4 encode-64+ \ addr size
my-space a1000000 or encode-int+ \ non-relocatable, aliased I/O space
3b0 encode-64+ c encode-64+ \ addr size
my-space a1000000 or encode-int+ \ non-relocatable, aliased I/O space
3c0 encode-64+ 20 encode-64+ \ addr size
my-space a2000000 or encode-int+ \ non-relocatable, <1MB Memory space
a0000 encode-64+ 20000 encode-64+ \ addr size
s" reg" property \ store "reg" property
;
: setup-properties
disp-width encode-int s" width" property
disp-height encode-int s" height" property
disp-width disp-depth 7 + 8 / * encode-int s" linebytes" property
disp-depth encode-int s" depth" property
s" ISO8859-1" encode-string s" character-set" property \ i hope this is ok...
s" display" device-type
;
: display-remove ( -- ) 
;
: display-install ( -- )
is-installed? NOT IF
." Installing QEMU fb" cr
fb-base to frame-buffer-adr
default-font 
set-font
disp-width disp-height
disp-width char-width / disp-height char-height /
disp-depth 7 + 8 /                      ( width height #lines #cols depth )
fb-install
true to is-installed?
THEN
;
: set-alias
s" screen" find-alias 0= IF
s" screen" get-node node>path set-alias
ELSE
drop
THEN 
;
." cirrus vga" cr
pci-master-enable
pci-mem-enable
pci-io-enable
add-legacy-reg
read-settings
init-mode
clear-screen
init-default-palette
setup-properties
' display-install is-install
' display-remove is-remove
set-alias
ÿÿÿÿÿÿÿÿ¸q8pci-device_8086_100e.fss" e1000 [ net ]" type cr
my-space pci-device-generic-setup
pci-io-enable
s" e1k.fs" included
pci-device-disable
ÿÿÿÿÿÿÿÿÕ(e1k.fss" network" device-type
INSTANCE VARIABLE obp-tftp-package
get-node CONSTANT my-phandle
10 config-l@ translate-my-address 3 not AND CONSTANT baseaddr
0 VALUE e1k-priv
0 VALUE open-count
: open  ( -- okay? )
open-count 0= IF
open IF
baseaddr
e1k-open dup not IF ." e1k-open failed" EXIT THEN
drop TO e1k-priv
true
ELSE
false
THEN
ELSE
true
THEN
my-args s" obp-tftp" $open-package obp-tftp-package !
open-count 1 + to open-count
;
: close  ( -- )
my-phandle set-node
open-count 0> IF
open-count 1 - dup to open-count
0= IF
e1k-priv e1k-close
close
THEN
THEN
s" close" obp-tftp-package @ $call-method
;
: read ( buf len -- actual )
dup IF
e1k-read
ELSE  
nip
THEN
;
: write ( buf len -- actual )
dup IF
e1k-write
ELSE
nip
THEN
;
: load  ( addr -- len )
s" load" obp-tftp-package @ $call-method
;
: ping  ( -- )
s" ping" obp-tftp-package @ $call-method
;
6 BUFFER: local-mac
: setup-mac ( -- )
pci-mem-enable
" vendor-id" get-node get-property IF EXIT THEN
decode-int nip nip
" device-id" get-node get-property IF EXIT THEN
decode-int nip nip
baseaddr
local-mac e1k-mac-setup IF
encode-bytes  " local-mac-address"  property
THEN
;
setup-mac
: setup-alias  ( -- )
" net" get-next-alias ?dup IF
get-node node>path set-alias
THEN
;
setup-alias
ÿÿÿÿÿÿÿÿ
°
u0qemu-vga.fsmy-space pci-device-generic-setup
d# 800 VALUE disp-width
d# 600 VALUE disp-height
d#   8 VALUE disp-depth
: map-in  " map-in" my-phandle parent $call-static ;
: map-out  " map-out" my-phandle parent $call-static ;
0 0  my-space h# 02000010 + 1  map-in VALUE fb-base
0 0  my-space h# 02000018 + 1 map-in VALUE reg-base
false VALUE is-installed?
: vga-w! ( value port -- )
3c0 - reg-base 400 + + rw!-le
;
: vga-w@ ( port -- value )
3c0 - reg-base 400 + + rw@-le
;
: vga-b! ( value port -- )
3c0 - reg-base 400 + + rb!
;
: vga-b@ ( port -- value )
3c0 - reg-base 400 + + rb@
;
: vbe!	( value index -- )
1 << reg-base 500 + + rw!-le
;
: vbe@	( index -- value )
1 << reg-base 500 + + rw@-le
;
: color! ( r g b number -- )
3c8 vga-b!
rot 3c9 vga-b!
swap 3c9 vga-b!
3c9 vga-b!
;
: color@ ( number -- r g b )
3c8 vga-b!
3c9 vga-b@
3c9 vga-b@
3c9 vga-b@
;
: set-colors ( adr number #numbers -- )
over 3c8 vga-b!
swap DO
rb@ 3c9 vga-b!
rb@ 3c9 vga-b!
rb@ 3c9 vga-b!
LOOP
3drop
;
: get-colors ( adr number #numbers -- )
3drop
;
include graphics.fs
0 CONSTANT VBE_DISPI_INDEX_ID
1 CONSTANT VBE_DISPI_INDEX_XRES
2 CONSTANT VBE_DISPI_INDEX_YRES
3 CONSTANT VBE_DISPI_INDEX_BPP
4 CONSTANT VBE_DISPI_INDEX_ENABLE
5 CONSTANT VBE_DISPI_INDEX_BANK
6 CONSTANT VBE_DISPI_INDEX_VIRT_WIDTH
7 CONSTANT VBE_DISPI_INDEX_VIRT_HEIGHT
8 CONSTANT VBE_DISPI_INDEX_X_OFFSET
9 CONSTANT VBE_DISPI_INDEX_Y_OFFSET
a CONSTANT VBE_DISPI_INDEX_NB
00 CONSTANT VBE_DISPI_DISABLED
01 CONSTANT VBE_DISPI_ENABLED
02 CONSTANT VBE_DISPI_GETCAPS
20 CONSTANT VBE_DISPI_8BIT_DAC
40 CONSTANT VBE_DISPI_LFB_ENABLED
80 CONSTANT VBE_DISPI_NOCLEARMEM
: init-mode
0 3c0 vga-b!
VBE_DISPI_DISABLED VBE_DISPI_INDEX_ENABLE vbe!
0 VBE_DISPI_INDEX_X_OFFSET vbe!
0 VBE_DISPI_INDEX_Y_OFFSET vbe!
disp-width VBE_DISPI_INDEX_XRES vbe!
disp-height VBE_DISPI_INDEX_YRES vbe!
disp-depth VBE_DISPI_INDEX_BPP vbe!
VBE_DISPI_ENABLED VBE_DISPI_8BIT_DAC or VBE_DISPI_INDEX_ENABLE vbe!
0 3c0 vga-b!
20 3c0 vga-b!
;
: clear-screen
fb-base disp-width disp-height disp-depth 7 + 8 / * * 0 rfill
;
: read-settings
s" qemu,graphic-width" get-chosen IF
decode-int to disp-width 2drop
THEN
s" qemu,graphic-height" get-chosen IF
decode-int to disp-height 2drop
THEN
s" qemu,graphic-depth" get-chosen IF
decode-int nip nip
dup 8 =
over f = or
over 10 = or
over 20 = or IF
to disp-depth
ELSE
." Unsupported bit depth, using 8bpp " drop cr
THEN
THEN
;
: setup-properties
disp-width encode-int s" width" property
disp-height encode-int s" height" property
disp-width disp-depth 7 + 8 / * encode-int s" linebytes" property
disp-depth encode-int s" depth" property
s" ISO8859-1" encode-string s" character-set" property \ i hope this is ok...
s" display" device-type
s" qemu,std-vga" encode-string s" compatible" property
;
: display-remove ( -- )
;
: slow-blink-screen ( -- )
invert-screen 20 ms invert-screen
;
: display-install ( -- )
is-installed? NOT IF
." Installing QEMU fb" cr
fb-base to frame-buffer-adr
clear-screen
default-font
set-font
disp-width disp-height
disp-width char-width / disp-height char-height /
disp-depth 7 + 8 /                      ( width height #lines #cols depth )
fb-install
['] slow-blink-screen to blink-screen
true to is-installed?
THEN
;
: set-alias
s" screen" find-alias 0= IF
s" screen" get-node node>path set-alias
ELSE
drop
THEN
;
pci-master-enable
pci-mem-enable
read-settings
init-mode
init-default-palette
setup-properties
' display-install is-install
' display-remove is-remove
set-alias
ÿÿÿÿÿÿÿÿ€E0pci-class_02.fss" network [ " type my-space pci-class-name type s"  ]" type
my-space pci-device-generic-setup
my-space pci-alias-net
s" network" device-type
cr
INSTANCE VARIABLE obp-tftp-package
: open  ( -- okay? )
open IF           \ enables PCI mem, io and Bus master and returns TRUE
my-args s" obp-tftp" $open-package obp-tftp-package ! true
ELSE
false
THEN ;
: close  ( -- )
obp-tftp-package @ close-package
close ;         \ disables PCI mem, io and Bus master
: load  ( addr -- len )
s" load" obp-tftp-package @ $call-method  ;
: ping  ( -- )  s" ping" obp-tftp-package @ $call-method  ;
ÿÿÿÿÿÿÿÿ@0pci-class_0c.fss" serial bus [ " type my-space pci-class-name type s"  ]" type cr
my-space pci-device-generic-setup
STRUCT
/n FIELD hcd>base
/n FIELD hcd>type
/n FIELD hcd>num
/n FIELD hcd>ops
/n FIELD hcd>priv
/n FIELD hcd>nextaddr
CONSTANT /hci-dev
: usb-setup-hcidev ( num hci-dev -- )
>r
10 config-l@ F AND case
0 OF 10 config-l@ translate-my-address ENDOF       \ 32-bit memory space
4 OF                                               \ 64-bit memory space
14 config-l@ 20 lshift                         \ Read two bars
10 config-l@ OR translate-my-address
ENDOF
ENDCASE
F not AND
( io-base ) r@ hcd>base !
08 config-l@ 8 rshift  0000000F0 AND 4 rshift
( usb-type ) r@ hcd>type !
( usb-num )  r@ hcd>num !
r> drop
;
: handle-usb-class  ( -- )
4 config-w@ 110 or 4 config-w!
pci-master-enable               \ set PCI Bus master bit and
pci-mem-enable                  \ memory space enable for USB scan
;
: handle-sbc-subclass  ( -- )
my-space pci-class@ ffff and CASE         \ get PCI sub-class and interface
0310 OF                      \ OHCI controller
handle-usb-class
set-ohci-alias
ENDOF
0320 OF                      \ EHCI controller
handle-usb-class
set-ehci-alias
ENDOF
0330 OF                      \ XHCI controller
handle-usb-class
set-xhci-alias
ENDOF
ENDCASE
;
handle-sbc-subclass
ÿÿÿÿÿÿÿÿˆK0dev-hci.fsVALUE usb_type \ USB type
device-type
s" usb"
rot
VALUE usb_num                           \ controller number
usb_num $cathex strdup			\ create alias name
2dup find-alias 0= IF
get-node node>path set-alias
ELSE 3drop THEN
/hci-dev BUFFER: hcidev
usb_num hcidev usb-setup-hcidev
TRUE VALUE first-time-init?
0 VALUE open-count
false VALUE dev-hci-debug?
1 encode-int s" #address-cells" property
0 encode-int s" #size-cells" property
: encode-unit ( port -- unit-str unit-len ) 1 hex-encode-unit ;
: decode-unit ( addr len -- port ) 1 hex-decode-unit ;
: get-hci-dev ( -- hcidev )
hcidev
;
: hc-cleanup ( -- )
my-phandle set-node
dev-hci-debug? IF ." USB-HCI: Cleaning up " pwd cr THEN
hcidev USB-HCD-EXIT
0 set-node
;
: open   ( -- true | false )
true
;
: close
;
first-time-init? IF
['] hc-cleanup add-quiesce-xt
false to first-time-init?
THEN
ÿÿÿÿÿÿÿÿè¯0slofdev.fsSTRUCT
/n FIELD slof-dev>udev
/l FIELD slof-dev>port
/l FIELD slof-dev>devaddr
/l FIELD slof-dev>hcitype
/l FIELD slof-dev>num
/l FIELD slof-dev>devtype
CONSTANT slof-usb-dev
ÿÿÿÿÿÿÿÿ€:8dev-parent-calls.fsget-node CONSTANT my-phandle
s" dma-function.fs" included
ÿÿÿÿÿÿÿÿp10dev-keyb.fsnew-device
VALUE sudev
false VALUE usb-keyb-debug?
s" slofdev.fs" included
sudev slof-dev>port l@ dup set-unit encode-phys " reg" property
sudev slof-dev>udev @ VALUE udev
s" usb-keyboard" device-name
s" keyboard" device-type
s" EN" encode-string s" language" property
s" keyboard" get-node node>path set-alias
s" dev-parent-calls.fs" included
0 VALUE open-count
: open   ( -- true | false )
usb-keyb-debug? IF ." USB-KEYB: Opening (count is " open-count . ." )" cr THEN
open-count 0= IF
udev USB-HID-INIT 0= IF
." USB keyboard setup failed " pwd cr false EXIT
THEN
THEN
open-count 1 + to open-count
true
;
: close
usb-keyb-debug? IF ." USB-KEYB: Closing (count is " open-count . ." )" cr THEN
open-count 0> IF
open-count 1 - dup to open-count
0= IF
my-phandle set-node
udev USB-HID-EXIT drop
0 set-node
THEN
THEN
;
: key-available? ( -- true|false )
udev USB-KEY-AVAILABLE IF TRUE ELSE FALSE THEN
;
: read                     ( addr len -- actual )
0= IF drop 0 EXIT THEN
udev USB-READ-KEYB ?dup IF swap c! 1 ELSE 0 swap c! 0 then
;
."     USB Keyboard " cr
finish-device
ÿÿÿÿÿÿÿÿÎ0dev-mouse.fsnew-device
VALUE sudev
s" slofdev.fs" included
sudev slof-dev>port l@ dup set-unit encode-phys " reg" property
sudev slof-dev>udev @ VALUE udev
s" usb-mouse" device-name
."     USB mouse " cr
finish-device
ÿÿÿÿÿÿÿÿX0dev-storage.fsnew-device
VALUE usbdev
s" slofdev.fs" included
false VALUE usb-disk-debug?
usbdev slof-dev>port l@ dup set-unit encode-phys " reg" property
s" storage" device-name
s" dev-parent-calls.fs" included
2 encode-int s" #address-cells" property
0 encode-int s" #size-cells" property
: decode-unit 2 hex64-decode-unit ;
: encode-unit 2 hex64-encode-unit ;
0 CONSTANT USB_PIPE_OUT
1 CONSTANT USB_PIPE_IN
usbdev slof-dev>udev @ VALUE udev
usbdev slof-dev>port l@ VALUE port
usbdev slof-dev>hcitype l@ VALUE hcitype
0 INSTANCE VALUE lun
10000 VALUE dev-max-transfer
0     VALUE resp-buffer
0     VALUE resp-size
0f CONSTANT SCSI-COMMAND-OFFSET
STRUCT
dev-max-transfer FIELD usb>data
40 FIELD usb>cmd
20 FIELD usb>csw
CONSTANT /dma-buf
0 VALUE dma-buf
0 VALUE dma-buf-phys
0 VALUE td-buf
0 VALUE td-buf-phys
1000 CONSTANT /td-buf
: (dma-buf-init)  ( -- )
/dma-buf dma-alloc TO dma-buf
dma-buf /dma-buf 0 dma-map-in TO dma-buf-phys
/td-buf dma-alloc TO td-buf
td-buf /td-buf 0 dma-map-in TO td-buf-phys
;
: (dma-buf-free)  ( -- )
td-buf td-buf-phys /td-buf dma-map-out
td-buf /td-buf dma-free
0 TO td-buf
0 TO td-buf-phys
dma-buf dma-buf-phys /dma-buf dma-map-out
dma-buf /dma-buf dma-free
0 TO dma-buf
0 TO dma-buf-phys
;
scsi-open
0 INSTANCE VALUE current-target
: do-bulk-command ( dir resp-buffer resp-size -- TRUE | FALSE )
TO resp-size
TO resp-buffer
udev USB_PIPE_OUT td-buf td-buf-phys dma-buf-phys usb>cmd 1F
usb-transfer-bulk 0= IF
drop FALSE EXIT
THEN
resp-size IF
d# 125 us
IF
udev USB_PIPE_IN
ELSE
udev USB_PIPE_OUT
THEN
td-buf td-buf-phys resp-buffer resp-size
usb-transfer-bulk 0= IF \ transfer data
usb-disk-debug? IF ." Data phase failed " cr THEN
THEN
ELSE
drop
THEN
d# 125 us
udev USB_PIPE_IN td-buf td-buf-phys dma-buf-phys usb>csw 0D
usb-transfer-bulk \ transfer CSW
;
STRUCT \ cbw
/l FIELD cbw>sig
/l FIELD cbw>tag
/l FIELD cbw>len
/c FIELD cbw>flags
/c FIELD cbw>lun     \ 0:3 bits
/c FIELD cbw>cblen   \ 0:4 bits
CONSTANT cbw-length
STRUCT \ csw
/l FIELD csw>sig
/l FIELD csw>tag
/l FIELD csw>data-residue
/c FIELD csw>status
CONSTANT cbw-length
0 VALUE cbw-addr
0 VALUE csw-addr
: build-cbw ( tag xfer-len dir lun cmd-len addr -- )
TO cbw-addr               ( tag xfer-len dir lun cmd-len )
cbw-addr cbw-length erase ( tag xfer-len dir lun cmd-len )
cbw-addr cbw>cblen c!     ( tag xfer-len dir lun )
cbw-addr cbw>lun c!       ( tag xfer-len dir )
IF 80 ELSE 0 THEN
cbw-addr cbw>flags c!     ( tag xfer-len )
cbw-addr cbw>len l!-le    ( tag )
cbw-addr cbw>tag l!-le    ( )
43425355 cbw-addr cbw>sig l!-le
;
0 INSTANCE VALUE usb-buf-addr
0 INSTANCE VALUE usb-buf-len
0 INSTANCE VALUE usb-dir
0 INSTANCE VALUE usb-cmd-addr
0 INSTANCE VALUE usb-cmd-len
1 VALUE tag
: execute-scsi-command ( buf-addr buf-len dir cmd-addr cmd-len -- ... )
to usb-cmd-len to usb-cmd-addr to usb-dir to usb-buf-len to usb-buf-addr
dma-buf usb>cmd 40 0 fill
dma-buf usb>csw 20 0 fill
tag usb-buf-len usb-dir lun usb-cmd-len dma-buf usb>cmd
build-cbw
1 tag + to tag
usb-cmd-addr
dma-buf usb>cmd SCSI-COMMAND-OFFSET +
usb-cmd-len
move
usb-dir not IF
usb-buf-addr dma-buf usb>data usb-buf-len move
THEN
usb-dir dma-buf-phys usb>data usb-buf-len
do-bulk-command 0= IF
." USB-DISK: Bulk command failed!" cr
0 0 -1 EXIT
THEN
usb-dir IF
dma-buf usb>data usb-buf-addr usb-buf-len move
THEN
dma-buf usb>csw to csw-addr
csw-addr csw>sig l@ 55534253 <> IF
." USB-DISK: CSW signature invalid " cr
0 0 -1 EXIT
THEN
csw-addr csw>status c@ CASE
0 OF ENDOF			\ Good
1 OF
usb-disk-debug? IF
." USB-DISK: CSW Data residue: "
csw-addr csw>data-residue l@-le . cr
THEN
0 0 8 EXIT ENDOF	\ Command failed, Retry
dup OF 0 0 -1 EXIT ENDOF	\ Anything else -> HW error
ENDCASE
csw-addr csw>status c@ dup 0<> IF
usb-disk-debug? IF
over scsi-get-sense-data
." USB-DISK: Sense key [ " dup . ." ] " .sense-text
."  ASC,ASCQ: " . . cr
THEN
rot
THEN
;
" scsi-host-helpers.fs" included
0 VALUE open-count
: usb-storage-init  (  -- TRUE )
td-buf 0= IF
usb-disk-debug? IF ." USB-DISK: Allocating buffer "  cr THEN
(dma-buf-init)
udev USB-MSC-INIT 0= IF
." USB-DISK: Unable to initialize MSC " cr
FALSE
ELSE
TRUE
THEN
THEN
;
: usb-storage-cleanup
td-buf 0<> IF
usb-disk-debug? IF ." USB-DISK: Freeing buffer " cr THEN
(dma-buf-free)
udev USB-MSC-EXIT 0= IF ." USB-DISK: Unable to exit MSC " cr THEN
THEN
;
: open
usb-disk-debug? IF ." USB-DISK: Opening (count is " open-count . ." )" cr THEN
open-count 0= IF
usb-storage-init IF
1 to open-count true
ELSE ." USB-DISK initialization failed !" cr false THEN
ELSE
open-count 1 + to open-count
true
THEN
;
: close
usb-disk-debug? IF ." USB-DISK: Closing (count is " open-count . ." )" cr THEN
open-count 0> IF
open-count 1 - dup to open-count
0= IF
usb-storage-cleanup
THEN
THEN
;
: (set-target)
dup 20 >> FFFF and to lun
dup 30 >> FF and to port
to current-target
usb-disk-debug? IF ." USB-DISK: udev " udev . ." lun:" lun . ." port:" port . cr THEN
;
: dev-generate-srplun ( target lun-id -- srplun )
swap drop port 0100 or 10 << or 20 <<
;
: max-transfer ( -- n )
dev-max-transfer
;
: set-address ( srplun.lo srplun.hi -- )
lxjoin (set-target)
usb-disk-debug? IF ." USB-DISK: udev " udev . ." lun:" lun . ." port:" port . cr THEN
;
1 CONSTANT #target
: dev-max-target ( -- #target )
#target
;
" scsi-probe-helpers.fs" included
scsi-close        \ no further scsi words required
: setup-alias
s" scsi" find-alias 0= IF
s" scsi" get-node node>path set-alias
ELSE
drop
THEN
;
: usb-storage-init-and-scan ( -- )
usb-disk-debug? IF ." Initializing usb-disk: udev " udev . cr THEN
0 0 get-node open-node ?dup 0= IF EXIT THEN
my-self >r
dup to my-self
hcitype
CASE
1 OF 4000 TO dev-max-transfer ENDOF \ OHCI
2 OF 10000 TO dev-max-transfer ENDOF \ EHCI
3 OF F000 TO dev-max-transfer ENDOF \ XHCI
ENDCASE
usb-storage-init
scsi-find-disks
setup-alias
usb-storage-cleanup
close-node
r> to my-self
;
."     USB Storage " cr
: usb-scsi-add-disk
" scsi-disk.fs" included
;
usb-scsi-add-disk
usb-storage-init-and-scan
finish-device
ÿÿÿÿÿÿÿÿ8ú0dev-hub.fsnew-device
VALUE sudev
s" slofdev.fs" included
sudev slof-dev>port l@ dup set-unit encode-phys " reg" property
sudev slof-dev>udev @ VALUE udev
s" hub" device-name
s" dev-parent-calls.fs" included
1 encode-int s" #address-cells" property
0 encode-int s" #size-cells" property
: decode-unit  1 hex-decode-unit ;
: encode-unit  1 hex-encode-unit ;
: usb-hub-init ( usbdev -- true | false )
udev USB-HUB-INIT
;
: open   ( -- true | false )
TRUE
;
: close
;
."     USB HUB " cr
usb-hub-init drop
finish-device
ÿÿÿÿÿÿÿÿÀy8pci-device_1af4_1000.fss" virtio [ net ]" type cr
my-space pci-device-generic-setup
pci-io-enable
s" virtio-net.fs" included
pci-device-disable
ÿÿÿÿÿÿÿÿh%8pci-device_1af4_1041.fss" pci-device_1af4_1000.fs" included
ÿÿÿÿÿÿÿÿàž8pci-device_1af4_1001.fss" virtio [ block ]" type cr
my-space pci-device-generic-setup
pci-master-enable
pci-mem-enable
pci-io-enable
s" virtio-block.fs" included
pci-device-disable
ÿÿÿÿÿÿÿÿh%8pci-device_1af4_1042.fss" pci-device_1af4_1001.fs" included
ÿÿÿÿÿÿÿÿà 8pci-device_1af4_1003.fss" virtio [ serial ]" type cr
my-space pci-device-generic-setup
pci-master-enable
pci-mem-enable
pci-io-enable
s" virtio-serial.fs" included
pci-device-disable
ÿÿÿÿÿÿÿÿh%8pci-device_1af4_1043.fss" pci-device_1af4_1003.fs" included
ÿÿÿÿÿÿÿÿàœ8pci-device_1af4_1004.fss" virtio [ scsi ]" type cr
my-space pci-device-generic-setup
pci-master-enable
pci-mem-enable
pci-io-enable
s" virtio-scsi.fs" included
pci-device-disable
ÿÿÿÿÿÿÿÿh%8pci-device_1af4_1048.fss" pci-device_1af4_1004.fs" included
ÿÿÿÿÿÿÿÿø·8pci-device_1af4_1009.fss" virtio [ network ]" type cr
my-space pci-device-generic-setup
s" virtio-9p" device-name
pci-master-enable
pci-mem-enable
pci-io-enable
s" virtio-fs.fs" included
pci-device-disable
ÿÿÿÿÿÿÿÿh%8pci-device_1af4_1049.fss" pci-device_1af4_1009.fs" included
ÿÿÿÿÿÿÿÿàš8pci-device_1af4_1050.fsmy-space pci-class@ 30000 = IF
s" virtio [ vga ]" type cr
s" qemu-vga.fs" included
ELSE
s" virtio [ gpu ]" type cr
my-space pci-device-generic-setup
THEN
ÿÿÿÿÿÿÿÿ°x0vio-hvterm.fs." Populating " pwd cr
: open true ;
: close ;
: write ( adr len -- actual )
tuck
0 ?DO
dup c@ my-unit SWAP hv-putchar
1 +
LOOP
drop
;
: read  ( adr len -- actual )
0= IF drop 0 EXIT THEN
my-unit hv-haschar 0= IF 0 swap c! -2 EXIT THEN
my-unit hv-getchar swap c! 1
;
: setup-alias
" hvterm" find-alias 0= IF
" hvterm" get-node node>path set-alias
ELSE
drop
THEN
;
setup-alias
ÿÿÿÿÿÿÿÿ X 0vio-vscsi.fs." Populating " pwd
false VALUE vscsi-debug?
0 VALUE vscsi-unit
: l2dma ( laddr - dma_addr)      
;
0    VALUE     crq-real-base
0    VALUE     crq-base
0    VALUE     crq-dma
0    VALUE     crq-offset
1000 CONSTANT  CRQ-SIZE
CREATE crq 10 allot
: crq-alloc ( -- )
CRQ-SIZE fff + alloc-mem to crq-real-base
crq-real-base fff + fffff000 AND to crq-base 0 to crq-offset
crq-base l2dma to crq-dma
;
: crq-free ( -- )
vscsi-unit hv-free-crq
crq-real-base CRQ-SIZE fff + free-mem 0 to crq-base 0 to crq-real-base
;
: crq-init ( -- res )
crq-alloc
vscsi-debug? IF
." VSCSI: allocated crq at " crq-base . cr
THEN
crq-base CRQ-SIZE erase
vscsi-unit crq-dma CRQ-SIZE hv-reg-crq
dup 0 <> IF
." VSCSI: Error " . ."  registering CRQ !" cr
crq-free
THEN
;
: crq-cleanup ( -- )
crq-base 0 = IF EXIT THEN
vscsi-debug? IF
." VSCSI: freeing crq at " crq-base . cr
THEN
crq-free
;
: crq-send ( msgaddr -- true | false )
vscsi-unit swap hv-send-crq 0 =
;
: crq-poll ( -- true | false)
crq-offset crq-base + dup
vscsi-debug? IF
." VSCSI: crq poll " dup .
THEN
c@
vscsi-debug? IF
."  value=" dup . cr
THEN
80 and 0 <> IF
dup crq 10 move
0 swap c!
crq-offset 10 + dup CRQ-SIZE >= IF drop 0 THEN to crq-offset
true
ELSE drop false THEN
;
: crq-wait ( -- true | false)
0 BEGIN drop crq-poll dup not WHILE d# 1 ms REPEAT
dup not IF
." VSCSI: Timeout waiting response !" cr EXIT
ELSE
vscsi-debug? IF
." VSCSI: got crq: " crq dup l@ . ."  " 4 + dup l@ . ."  "
4 + dup l@ . ."  " 4 + l@ . cr
THEN
THEN
;
01 CONSTANT VIOSRP_SRP_FORMAT
02 CONSTANT VIOSRP_MAD_FORMAT
03 CONSTANT VIOSRP_OS400_FORMAT
04 CONSTANT VIOSRP_AIX_FORMAT
06 CONSTANT VIOSRP_LINUX_FORMAT
07 CONSTANT VIOSRP_INLINE_FORMAT
struct
1 field >crq-valid
1 field >crq-format
1 field >crq-reserved
1 field >crq-status
2 field >crq-timeout
2 field >crq-iu-len
8 field >crq-iu-data-ptr
constant /crq
: srp-send-crq ( addr len -- )
80                crq >crq-valid c!
VIOSRP_SRP_FORMAT crq >crq-format c!
0                 crq >crq-reserved c!
0                 crq >crq-status c!
0                 crq >crq-timeout w!
( len )           crq >crq-iu-len w!
( addr ) l2dma    crq >crq-iu-data-ptr x!
crq crq-send
not IF
." VSCSI: Error sending CRQ !" cr
THEN
;
: srp-wait-crq ( -- [tag true] | false )
crq-wait not IF false EXIT THEN
crq >crq-format c@ VIOSRP_SRP_FORMAT <> IF
." VSCSI: Unsupported SRP response: "
crq >crq-format c@ . cr
false EXIT
THEN
crq >crq-iu-data-ptr x@ true
;
scsi-open
0 VALUE >srp_opcode
00 CONSTANT SRP_LOGIN_REQ
01 CONSTANT SRP_TSK_MGMT
02 CONSTANT SRP_CMD
03 CONSTANT SRP_I_LOGOUT
c0 CONSTANT SRP_LOGIN_RSP
c1 CONSTANT SRP_RSP
c2 CONSTANT SRP_LOGIN_REJ
80 CONSTANT SRP_T_LOGOUT
81 CONSTANT SRP_CRED_REQ
82 CONSTANT SRP_AER_REQ
41 CONSTANT SRP_CRED_RSP
42 CONSTANT SRP_AER_RSP
02 CONSTANT SRP_BUF_FORMAT_DIRECT
04 CONSTANT SRP_BUF_FORMAT_INDIRECT
struct
1 field >srp-login-opcode
3 +
8 field >srp-login-tag
4 field >srp-login-req-it-iu-len
4 +
2 field >srp-login-req-buf-fmt
1 field >srp-login-req-flags
5 +
10 field >srp-login-init-port-ids
10 field >srp-login-trgt-port-ids
constant /srp-login
struct
1 field >srp-lresp-opcode
3 +
4 field >srp-lresp-req-lim-delta
8 field >srp-lresp-tag
4 field >srp-lresp-max-it-iu-len
4 field >srp-lresp-max-ti-iu-len
2 field >srp-lresp-buf-fmt
1 field >srp-lresp-flags
constant /srp-login-resp
struct
1 field >srp-lrej-opcode
3 +
4 field >srp-lrej-reason
8 field >srp-lrej-tag
8 +
2 field >srp-lrej-buf-fmt
constant /srp-login-rej
00 CONSTANT SRP_NO_DATA_DESC
01 CONSTANT SRP_DATA_DESC_DIRECT
02 CONSTANT SRP_DATA_DESC_INDIRECT
struct
1 field >srp-cmd-opcode
1 field >srp-cmd-sol-not
3 +
1 field >srp-cmd-buf-fmt
1 field >srp-cmd-dout-desc-cnt
1 field >srp-cmd-din-desc-cnt
8 field >srp-cmd-tag
4 +
8 field >srp-cmd-lun
1 +
1 field >srp-cmd-task-attr
1 +
1 field >srp-cmd-add-cdb-len
10 field >srp-cmd-cdb
0 field >srp-cmd-cdb-add
constant /srp-cmd
struct
1 field >srp-rsp-opcode
1 field >srp-rsp-sol-not
2 +
4 field >srp-rsp-req-lim-delta
8 field >srp-rsp-tag
2 +
1 field >srp-rsp-flags
1 field >srp-rsp-status
4 field >srp-rsp-dout-res-cnt
4 field >srp-rsp-din-res-cnt
4 field >srp-rsp-sense-len
4 field >srp-rsp-resp-len
0 field >srp-rsp-data
constant /srp-rsp
01 CONSTANT SRP_RSP_FLAG_RSPVALID
02 CONSTANT SRP_RSP_FLAG_SNSVALID
04 CONSTANT SRP_RSP_FLAG_DOOVER
05 CONSTANT SRP_RSP_FLAG_DOUNDER
06 CONSTANT SRP_RSP_FLAG_DIOVER
07 CONSTANT SRP_RSP_FLAG_DIUNDER
CREATE srp 100 allot
0 VALUE srp-len
: srp-prep-cmd-nodata ( srplun -- )
srp /srp-cmd erase
SRP_CMD srp >srp-cmd-opcode c!
1 srp >srp-cmd-tag x!
srp >srp-cmd-lun x!         \ 8 bytes lun
/srp-cmd to srp-len   
;
: srp-prep-cmd-io ( addr len srplun -- )
srp-prep-cmd-nodata		( addr len )
swap l2dma			( len dmaaddr )
srp srp-len +    		( len dmaaddr descaddr )
dup >r x! r> 8 +		( len descaddr+8 )
dup 0 swap l! 4 +		( len descaddr+c )
l!    
srp-len 10 + to srp-len
;
: srp-prep-cmd-read ( addr len srplun -- )
srp-prep-cmd-io
01 srp >srp-cmd-buf-fmt c!	\ in direct buffer
1 srp >srp-cmd-din-desc-cnt c!
;
: srp-prep-cmd-write ( addr len srplun -- )
srp-prep-cmd-io
10 srp >srp-cmd-buf-fmt c!	\ out direct buffer
1 srp >srp-cmd-dout-desc-cnt c!
;
: srp-send-cmd ( -- )
vscsi-debug? IF
." VSCSI: Sending SCSI cmd " srp >srp-cmd-cdb c@ . cr
THEN
srp srp-len srp-send-crq
;
: srp-rsp-find-sense ( -- addr len true | false )
srp >srp-rsp-flags c@ SRP_RSP_FLAG_SNSVALID and 0= IF
false EXIT
THEN
srp >srp-rsp-data srp >srp-rsp-sense-len l@ true
;
: srp-wait-rsp ( -- stat )
srp-wait-crq not IF false EXIT THEN
dup 1 <> IF
." VSCSI: Invalid CRQ response tag, want 1 got " . cr
-1 EXIT
THEN drop
srp >srp-rsp-tag x@ dup 1 <> IF
." VSCSI: Invalid SRP response tag, want 1 got " . cr
-1 EXIT
THEN drop
srp >srp-rsp-status c@
vscsi-debug? IF
." VSCSI: Got response status: "
dup .status-text cr
THEN
;
8000000000000000 INSTANCE VALUE current-target
: execute-scsi-command ( buf-addr buf-len dir cmd-addr cmd-len -- ... )
>r >r				( buf-addr buf-len dir )
over 0= IF
3drop current-target srp-prep-cmd-nodata
ELSE
current-target swap IF srp-prep-cmd-read ELSE srp-prep-cmd-write THEN
THEN
r> r>
srp >srp-cmd-cdb swap move
srp-send-cmd
srp-wait-rsp
dup -1 = IF
0 0 rot EXIT
THEN
dup 0<> IF
srp-rsp-find-sense IF
vscsi-debug? IF
over scsi-get-sense-data
." VSCSI: Sense key [ " dup . ." ] " .sense-text
."  ASC,ASCQ: " . . cr
THEN
ELSE 0 0
." VSCSI: No sense data" cr
THEN
rot
THEN
;
" scsi-host-helpers.fs" included
TRUE VALUE first-time-init?
0 VALUE open-count
: vscsi-cleanup
vscsi-debug? IF ." VSCSI: Cleaning up" cr THEN
crq-cleanup
vscsi-unit 0 rtas-set-tce-bypass
;
: vscsi-init ( -- true | false )
vscsi-debug? IF ." VSCSI: Initializing" cr THEN
my-unit to vscsi-unit
vscsi-unit 1 rtas-set-tce-bypass
crq-init 0 <> IF false EXIT THEN
" "(C0 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00)" drop
crq-send not IF
." VSCSI: Error sending init command"
crq-cleanup false EXIT
THEN
crq-wait not IF
crq-cleanup false EXIT
THEN
crq c@ c0 <> crq 1 + c@ 02 <> or IF
." VSCSI: Initial handshake failed"
crq-cleanup false EXIT
THEN
first-time-init? IF
['] vscsi-cleanup add-quiesce-xt
false to first-time-init?
THEN
true
;
: open
vscsi-debug? IF ." VSCSI: Opening (count is " open-count . ." )" cr THEN
open-count 0= IF
vscsi-init IF
1 to open-count true
ELSE ." VSCSI initialization failed !" cr false THEN
ELSE
open-count 1 + to open-count
true
THEN
;
: close
vscsi-debug? IF ." VSCSI: Closing (count is " open-count . ." )" cr THEN
open-count 0> IF
open-count 1 - dup to open-count
0= IF
vscsi-cleanup
THEN
THEN
;
: (set-target)
to current-target
;
: dev-generate-srplun ( bus+target lun -- srplun )
swap dup 1 >> e0 and      ( lun bus+target bus )
swap 3f and 8 <<          ( lun bus target )
8000 or or or 30 <<
;
: set-address ( srplun.lo srplun.hi -- )
lxjoin (set-target)
;
: max-transfer ( -- n )
10000 \ Larger value seem to have problems with some CDROMs
;
: dev-max-target ( -- #max-target )
200
;
" scsi-probe-helpers.fs" included
scsi-close
: setup-alias
" scsi" find-alias 0= IF
" scsi" get-node node>path set-alias
ELSE
drop
THEN 
;
: vscsi-init-and-scan  ( -- )
0 0 get-node open-node ?dup 0= IF EXIT THEN
my-self >r
dup to my-self
scsi-find-disks
setup-alias
close-node
r> to my-self
;
: vscsi-add-disk
" scsi-disk.fs" included
;
vscsi-add-disk
vscsi-init-and-scan
ÿÿÿÿÿÿÿÿx88vio-vtpm-cdriver.fs." Populating " pwd cr
false VALUE vtpm-debug?
0     VALUE vtpm-unit
0     VALUE    log-base
40000 CONSTANT LOG-SIZE   \ 256k per VTPM FW spec.
e     CONSTANT VTPM_DRV_ERROR_SML_HANDED_OVER
LOG-SIZE BUFFER: log-base
: sml-get-allocated-size ( -- buffer-size)
LOG-SIZE
;
: sml-get-handover-size ( -- size)
tpm-get-logsize
;
: sml-handover ( dest size -- )
log-base    ( dest size src )
-rot        ( src dest size )
move
VTPM_DRV_ERROR_SML_HANDED_OVER tpm-driver-set-failure-reason
;
: get-failure-reason ( -- reason )
tpm-driver-get-failure-reason           ( reason )
;
: 2hash-ext-log ( pcr eventtype info info-len data data-len -- success?)
vtpm-debug? IF
." Call to 2hash-ext-log" cr
THEN
tpm-2hash-ext-log                      ( success? )
dup 0= IF
." VTPM: tpm-2hash-ext-log failed: " dup . cr
THEN
;
0 0 s" ibm,sml-efi-reformat-supported" property
: reformat-sml-to-efi-alignment ( -- success )
true
;
: open true ;
: close ;
: vtpm-cleanup ( -- )
vtpm-debug? IF ." VTPM: Disabling RTAS bypass" cr THEN
tpm-finalize
vtpm-unit 0 rtas-set-tce-bypass
;
: vtpm-init ( -- success )
0 0 get-node open-node ?dup 0= IF false EXIT THEN
my-self >r
dup to my-self
vtpm-debug? IF ." VTPM: Initializing for c-driver" cr THEN
my-unit to vtpm-unit
vtpm-unit 1 rtas-set-tce-bypass
['] vtpm-cleanup add-quiesce-xt
close-node
r> to my-self
tpm-start ?dup 0= IF
vtpm-debug? IF ." VTPM: Success from tpm-start" cr THEN
true
ELSE
." VTPM: Error code from tpm-start: " . cr
false
THEN
;
vtpm-init IF
log-base LOG-SIZE tpm-set-log-parameters
s" vtpm-sml.fs" included
ELSE
." VTPM: vtpm-init failed" cr
THEN
ÿÿÿÿÿÿÿÿ8ú0vio-veth.fs." Populating " pwd cr
" network" device-type
INSTANCE VARIABLE obp-tftp-package
0 VALUE veth-priv
0 VALUE open-count
: open  ( -- okay? )
open-count 0= IF
my-unit 1 rtas-set-tce-bypass
s" local-mac-address" get-node get-property not
s" reg" get-node get-property not 3 pick and IF
>r nip r>
libveth-open dup not IF ." libveth-open failed" EXIT THEN
drop TO veth-priv
THEN
THEN
my-args s" obp-tftp" $open-package obp-tftp-package !
open-count 1 + to open-count
true
;
: close  ( -- )
open-count 0> IF
open-count 1 - dup to open-count
0= IF
veth-priv libveth-close
my-unit 0 rtas-set-tce-bypass
THEN
THEN
s" close" obp-tftp-package @ $call-method
;
: read ( buf len -- actual )
dup IF
veth-priv libveth-read
ELSE
nip
THEN
;
: write ( buf len -- actual )
dup IF
veth-priv libveth-write
ELSE
nip
THEN
;
: load  ( addr -- len )
s" load" obp-tftp-package @ $call-method 
;
: ping  ( -- )
s" ping" obp-tftp-package @ $call-method
;
: setup-alias
" net" get-next-alias ?dup IF
get-node node>path set-alias
THEN
;
setup-alias
ÿÿÿÿÿÿÿÿ°u0rtas-nvram.fs." Populating " pwd cr
0 VALUE my-nvram-fetch
0 VALUE my-nvram-store
0 VALUE my-nvram-size
0 VALUE nvram-addr
: open true ;
: close ;
: write ( adr len -- actual )
nip
;
: read  ( adr len -- actual )
nip
;
: setup-alias
" nvram" find-alias 0= IF
" nvram" get-node node>path set-alias
ELSE
drop
THEN
;
" #bytes" get-node get-package-property 0= IF
decode-int to my-nvram-size 2drop
" nvram-fetch" rtas-get-token to my-nvram-fetch
" nvram-store" rtas-get-token to my-nvram-store
my-nvram-size to nvram-size
nvram-size alloc-mem to nvram-addr
my-nvram-fetch my-nvram-store nvram-size nvram-addr internal-nvram-init
THEN
setup-alias
ÿÿÿÿÿÿÿÿ@0virtio-net.fss" network" device-type
INSTANCE VARIABLE obp-tftp-package
virtio-setup-vd VALUE virtiodev
0 VALUE virtio-net-priv
0 VALUE open-count
6 BUFFER: local-mac
: setup-mac  ( -- )
s" local-mac-address" get-node get-property not IF 2drop EXIT THEN
6 0 DO
virtiodev i 1 virtio-get-config
local-mac i + c!
LOOP
local-mac 6 encode-bytes  s" local-mac-address"  property
;
: open  ( -- okay? )
open-count 0= IF
open IF
virtiodev virtio-net-open
not IF ." virtio-net-open failed" cr false EXIT THEN
TO virtio-net-priv
setup-mac true
ELSE
false
THEN
ELSE
true
THEN
my-args s" obp-tftp" $open-package obp-tftp-package !
open-count 1 + to open-count
;
: close  ( -- )
open-count 0> IF
open-count 1 - dup to open-count
0= IF
virtio-net-priv virtio-net-close
close
THEN
THEN
s" close" obp-tftp-package @ $call-method
;
: read ( buf len -- actual )
dup IF
virtio-net-priv virtio-net-read
ELSE
nip
THEN
;
: write ( buf len -- actual )
dup IF
virtio-net-priv virtio-net-write
ELSE
nip
THEN
;
: load  ( addr -- len )
s" load" obp-tftp-package @ $call-method 
;
: ping  ( -- )
s" ping" obp-tftp-package @ $call-method
;
: setup-alias  ( -- )
" net" get-next-alias ?dup IF
get-node node>path set-alias
THEN
;
setup-alias
: virtio-net-init ( -- )
0 0 get-node open-node
?dup IF close-node THEN
;
virtio-net-init
ÿÿÿÿÿÿÿÿ`8virtio-serial.fss" serial" device-type
FALSE VALUE initialized?
virtio-setup-vd VALUE virtiodev
: shutdown  ( -- )
initialized? IF
virtiodev virtio-serial-shutdown
FALSE to initialized?
0 to virtiodev
THEN
;
: virtio-serial-term-emit
virtiodev SWAP virtio-serial-putchar
;
: virtio-serial-term-key?  virtiodev virtio-serial-haschar ;
: virtio-serial-term-key   BEGIN virtio-serial-term-key? UNTIL virtiodev virtio-serial-getchar ;
: virtio-serial-close-stdout s" stdout" get-chosen IF decode-int nip nip close-dev THEN ;
: init  ( -- )
virtiodev virtio-serial-init drop
TRUE to initialized?
['] virtio-serial-close-stdout add-quiesce-xt
;
0 VALUE open-count
: open  ( -- okay? )
open-count 0= IF
open IF initialized? 0= IF init THEN
true
ELSE false exit
THEN
ELSE true THEN
open-count 1 + to open-count
;
: close
open-count 0> IF
open-count 1 - dup to open-count
0= IF shutdown THEN
THEN
close
;
: write ( addr len -- actual )
virtiodev 0= IF nip EXIT THEN
tuck
0 ?DO
dup c@ virtiodev SWAP virtio-serial-putchar
1 +
LOOP
drop
;
: read ( addr len -- actual )
0= IF drop 0 EXIT THEN
virtiodev 0= IF nip EXIT THEN
virtiodev virtio-serial-haschar 0= IF 0 swap c! -2 EXIT THEN
virtiodev virtio-serial-getchar swap c! 1
;
: setup-alias
" vsterm" find-alias 0= IF
" vsterm" get-node node>path set-alias
ELSE drop THEN
;
setup-alias
ÿÿÿÿÿÿÿÿÎ0virtio-block.fss" block" device-type
FALSE VALUE initialized?
200 VALUE block-size
8000 CONSTANT max-transfer 
INSTANCE VARIABLE deblocker
virtio-setup-vd VALUE virtiodev
: shutdown  ( -- )
initialized? IF
my-phandle node>path open-dev ?dup IF
virtiodev virtio-blk-shutdown
close-dev
THEN
FALSE to initialized?
THEN
;
: init  ( -- )
virtiodev virtio-blk-init to block-size
TRUE to initialized?
['] shutdown add-quiesce-xt
;
: read-blocks  ( addr block# #blocks -- #read )
virtiodev virtio-blk-read
;
: write-blocks  ( addr block# #blocks -- #written )
over 22 < IF
." virtio-blk ERROR: Write access to partition table is not allowed." cr
3drop 0 EXIT
THEN
virtiodev virtio-blk-write
;
: open  ( -- okay? )
open 0= IF false EXIT THEN
dup initialized? 0= AND IF
init
THEN
0 0 s" deblocker" $open-package dup deblocker ! dup IF
s" disk-label" find-package IF
my-args rot interpose
THEN
THEN
0<>
;
: close  ( -- )
deblocker @ close-package
close
;
: seek  ( pos.lo pos.hi -- status )
s" seek" deblocker @ $call-method
;
: read  ( addr len -- actual )
s" read" deblocker @ $call-method
;
: write ( addr len -- actual )
s" write" deblocker @ $call-method
;
: (set-alias)
s" disk" get-next-alias ?dup IF
get-node node>path set-alias
THEN
;
(set-alias)
ÿÿÿÿÿÿÿÿ8ú0virtio-fs.fs." Populating " pwd cr
s" network" device-type
0 VALUE virtfs-rx-buffer
0 VALUE virtfs-tx-buffer
FALSE VALUE initialized?
2000 CONSTANT VIRTFS-BUF-SIZE \ 8k
virtio-setup-vd VALUE virtiodev
: shutdown  ( -- )
initialized? 0= IF EXIT THEN
virtiodev virtio-fs-shutdown
virtfs-rx-buffer VIRTFS-BUF-SIZE free-mem
virtfs-tx-buffer VIRTFS-BUF-SIZE free-mem
FALSE to initialized?
;
: init  ( -- success )
VIRTFS-BUF-SIZE alloc-mem to virtfs-rx-buffer
VIRTFS-BUF-SIZE alloc-mem to virtfs-tx-buffer
virtiodev			( dev )
virtfs-tx-buffer		( dev tx )
virtfs-rx-buffer		( reg tx rx )
VIRTFS-BUF-SIZE		( reg tx rx size )   
virtio-fs-init		( success )
dup IF
TRUE to initialized?
['] shutdown add-quiesce-xt
THEN
;
: open  ( -- okay? )
open 0= IF false EXIT THEN
initialized? 0= IF
init 0= IF false EXIT THEN
THEN   
true
;
: load ( addr -- len )
virtiodev swap		( dev addr )   
my-args   			( dev addr str strlen )
1 +		\ hack to make the following allocate 1 more byte
\-to-/	\ convert path elements
1 - 2dup + 0 swap c! drop
virtio-fs-load		( length )
;
: close  ( -- )
initialized? IF
shutdown
THEN
close
;
: ping ( -- )
cr s" ping not supported for this device" type cr cr
;
: (set-alias)
" virtfs" find-alias 0= IF
" virtfs" get-node node>path set-alias
ELSE
drop
THEN
;
(set-alias)
ÿÿÿÿÿÿÿÿð±0dev-null.fsnew-device
" devnull-console" device-name
: open true ;
: close ;
: write ( adr len -- actual )
nip
;
: read  ( adr len -- actual )
2drop 0
;
: setup-alias
" devnull-console" find-alias 0= IF
" devnull-console" get-node node>path set-alias
ELSE
drop
THEN
;
: dummy-term-emit drop ;
: dummy-term-key  0 ;
: dummy-term-key? FALSE ;
' dummy-term-emit to emit
' dummy-term-key  to key
' dummy-term-key? to key?
setup-alias
finish-device
ÿÿÿÿÿÿÿÿ¨i0virtio-scsi.fs." Populating " pwd cr
FALSE CONSTANT virtio-scsi-debug
2 encode-int s" #address-cells" property
0 encode-int s" #size-cells" property
: decode-unit 2 hex64-decode-unit ;
: encode-unit 2 hex64-encode-unit ;
FALSE VALUE initialized?
virtio-setup-vd VALUE virtiodev
STRUCT \ virtio-scsi-config
/l FIELD vs-cfg>num-queues
/l FIELD vs-cfg>seg-max
/l FIELD vs-cfg>max-sectors
/l FIELD vs-cfg>cmd-per-lun
/l FIELD vs-cfg>event-info-size
/l FIELD vs-cfg>sense_size
/l FIELD vs-cfg>cdb-size
/w FIELD vs-cfg>max-channel
/w FIELD vs-cfg>max-target
/l FIELD vs-cfg>max-lun
CONSTANT vs-cfg-length
STRUCT \ virtio-scsi-req
8  FIELD vs-req>lun
8  FIELD vs-req>tag
/c FIELD vs-req>task-attr
/c FIELD vs-req>prio
/c FIELD vs-req>crn
20 FIELD vs-req>cdb
CONSTANT vs-req-length
STRUCT \ virtio-scsi-resp
/l FIELD vs-rsp>sense-len
/l FIELD vs-rsp>residual
/w FIELD vs-rsp>status-qualifier
/c FIELD vs-rsp>status
/c FIELD vs-rsp>response
60 FIELD vs-rsp>sense
CONSTANT vs-rsp-length
CREATE vs-req vs-req-length allot
CREATE vs-rsp vs-rsp-length allot
scsi-open
0 INSTANCE VALUE current-target
: execute-scsi-command ( buf-addr buf-len dir cmd-addr cmd-len -- ... )
vs-req vs-req-length erase
vs-rsp vs-rsp-length erase
current-target vs-req vs-req>lun x!
vs-req vs-req>cdb swap move
vs-req vs-rsp virtiodev
virtio-scsi-send
0 <> IF
." VIRTIO-SCSI: Queuing failure !" cr
0 0 -1 EXIT
THEN
vs-rsp vs-rsp>response c@ CASE
0 OF ENDOF			\ Good
5 OF drop 0 0 8 EXIT ENDOF	\ Busy
dup OF 0 0 -1 EXIT ENDOF	\ Anything else -> HW error
ENDCASE
vs-rsp vs-rsp>status c@ dup 0<> IF
vs-rsp vs-rsp>sense-len l@ dup 0= IF
." VIRTIO-SCSI: No sense data" cr
0 EXIT
THEN
vs-rsp vs-rsp>sense swap
virtio-scsi-debug IF
over scsi-get-sense-data
." VIRTIO-SCSI: Sense key [ " dup . ." ] " .sense-text
."  ASC,ASCQ: " . . cr
THEN
rot
THEN    
;
" scsi-host-helpers.fs" included
: max-transfer ( -- n )
10000 \ Larger value seem to have problems with some CDROMs
;
: (set-target)
to current-target
;
: dev-generate-srplun ( target lun-id -- srplun )
dup ff > IF 4000 or THEN    \ Use the LUN "flat space addressing method"
swap 0100 or 10 << or 20 <<
;
: set-address ( srplun.lo srplun.hi -- )
lxjoin (set-target)
;
100 CONSTANT #target
: dev-max-target ( -- #target )
#target
;
" scsi-probe-helpers.fs" included
scsi-close        \ no further scsi words required
: setup-alias
s" scsi" find-alias 0= IF
s" scsi" get-node node>path set-alias
ELSE
drop
THEN
;
: shutdown ( -- )
initialized? IF
my-phandle node>path open-dev ?dup IF
virtiodev virtio-scsi-shutdown
close-dev
THEN
FALSE to initialized?
THEN
;
: virtio-scsi-init-and-scan  ( -- )
0 0 get-node open-node ?dup 0= IF ." exiting " cr EXIT THEN
my-self >r
dup to my-self
virtiodev virtio-scsi-init
0= IF
scsi-find-disks
setup-alias
TRUE to initialized?
['] shutdown add-quiesce-xt
THEN
close-node
r> to my-self
;
: virtio-scsi-add-disk
" scsi-disk.fs" included
;
virtio-scsi-add-disk
virtio-scsi-init-and-scan
ÿÿÿÿÿÿÿÿ½0build_info.imgprintf t[CC]t%sn build_info.img; gcc -m64 -mbig -mabi=elfv1
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/powerpc64le-linux-gnu/10/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
Target: powerpc64le-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 10.3.0-1ubuntu1' --with-bugurl=file:///usr/share/doc/gcc-10/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-10 --program-prefix=powerpc64le-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-secureplt --with-cpu=power8 --enable-targets=powerpcle-linux --disable-multilib --enable-multiarch --disable-werror --with-long-double-128 --enable-offload-targets=nvptx-none=/build/gcc-10-TZ3qNq/gcc-10-10.3.0/debian/tmp-nvptx/usr --without-cuda-driver --enable-checking=release --build=powerpc64le-linux-gnu --host=powerpc64le-linux-gnu --target=powerpc64le-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-mutex
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 10.3.0 (Ubuntu 10.3.0-1ubuntu1) 
GNU ld (GNU Binutils for Ubuntu) 2.36.1
  Supported emulations:
   elf64lppc
   elf32lppc
   elf32lppclinux
   elf32lppcsim
   elf64ppc
   elf32ppc
   elf32ppclinux
   elf32ppcsim
ÿÿÿÿÿÿÿÿ+
back to top