From 35d1a33e252e8538e942d2756c1c7ef2f192647c Mon Sep 17 00:00:00 2001 From: crc Date: Thu, 23 May 2024 15:32:54 +0200 Subject: [PATCH] check in the source files, binaries, and update README & LICENSE --- LICENSE | 32 +- README.md | 38 +- binaries/CWSDPMI.exe | Bin 0 -> 21325 bytes binaries/ilo-68k-mac.bin | Bin 0 -> 23424 bytes binaries/ilo-aarch64-linux | Bin 0 -> 4072 bytes binaries/ilo-amd64-dragonfly | Bin 0 -> 2816 bytes binaries/ilo-amd64-freebsd | Bin 0 -> 2384 bytes binaries/ilo-amd64-haiku | Bin 0 -> 15344 bytes binaries/ilo-amd64-linux | Bin 0 -> 2312 bytes binaries/ilo-amd64-netbsd | Bin 0 -> 2528 bytes binaries/ilo-amd64-openbsd | Bin 0 -> 2528 bytes binaries/ilo-amd64-windows.exe | Bin 0 -> 6656 bytes binaries/ilo-arm64-darwin | Bin 0 -> 34496 bytes binaries/ilo-dotnet-windows.exe | Bin 0 -> 8192 bytes binaries/ilo-ipad-ish | Bin 0 -> 33732 bytes binaries/ilo-luna88k-openbsd | Bin 0 -> 9348 bytes binaries/ilo-pmax-netbsd | Bin 0 -> 16452 bytes binaries/ilo-teensy41.hex | 4230 +++++++++++++++++++++++++++++++ binaries/ilo-universal-darwin | Bin 0 -> 99920 bytes binaries/ilo-x86-dos-32bit.exe | Bin 0 -> 151832 bytes binaries/ilo-x86-dos.exe | Bin 0 -> 22008 bytes binaries/ilo-x86-freebsd | Bin 0 -> 5308 bytes binaries/ilo-x86-linux | Bin 0 -> 9196 bytes binaries/ilo-x86-netbsd | Bin 0 -> 11148 bytes binaries/ilo-x86-openbsd | Bin 0 -> 13720 bytes binaries/ilo-x86-windows.exe | Bin 0 -> 5632 bytes binaries/ilo.jar | Bin 0 -> 159956 bytes source/ilo-68k-mac.c | 1 + source/ilo-aarch64-linux.s | 1120 ++++++++ source/ilo-amd64-dragonfly.s | 422 +++ source/ilo-amd64-freebsd.s | 420 +++ source/ilo-amd64-linux.s | 405 +++ source/ilo-amd64-netbsd.s | 414 +++ source/ilo-amd64-openbsd.s | 439 ++++ source/ilo-banked.c | 205 ++ source/ilo-be.c | 215 ++ source/ilo-dos.c | 191 ++ source/ilo-js.html | 701 +++++ source/ilo-min.c | 71 + source/ilo-plan9.c | 205 ++ source/ilo-pthread.c | 183 ++ source/ilo-safer.c | 197 ++ source/ilo-teensy41.ino | 267 ++ source/ilo-windows.c | 141 ++ source/ilo.c | 184 ++ source/ilo.cl | 327 +++ source/ilo.cs | 161 ++ source/ilo.cxx | 187 ++ source/ilo.d | 232 ++ source/ilo.fnt | Bin 0 -> 4096 bytes source/ilo.go | 193 ++ source/ilo.ha | 239 ++ source/ilo.kt | 280 ++ source/ilo.lua | 343 +++ source/ilo.nim | 241 ++ source/ilo.py | 515 ++++ source/ilo.retro | 181 ++ source/ilo.rs | 368 +++ source/ilo.swift | 310 +++ source/ilo.ts | 516 ++++ source/mult-ilo.c | 264 ++ source/x11-ilo.c | 466 ++++ source/x11-mult-ilo.c | 522 ++++ 63 files changed, 15419 insertions(+), 7 deletions(-) create mode 100644 binaries/CWSDPMI.exe create mode 100644 binaries/ilo-68k-mac.bin create mode 100755 binaries/ilo-aarch64-linux create mode 100755 binaries/ilo-amd64-dragonfly create mode 100755 binaries/ilo-amd64-freebsd create mode 100755 binaries/ilo-amd64-haiku create mode 100755 binaries/ilo-amd64-linux create mode 100755 binaries/ilo-amd64-netbsd create mode 100755 binaries/ilo-amd64-openbsd create mode 100644 binaries/ilo-amd64-windows.exe create mode 100755 binaries/ilo-arm64-darwin create mode 100755 binaries/ilo-dotnet-windows.exe create mode 100755 binaries/ilo-ipad-ish create mode 100755 binaries/ilo-luna88k-openbsd create mode 100755 binaries/ilo-pmax-netbsd create mode 100644 binaries/ilo-teensy41.hex create mode 100755 binaries/ilo-universal-darwin create mode 100644 binaries/ilo-x86-dos-32bit.exe create mode 100644 binaries/ilo-x86-dos.exe create mode 100755 binaries/ilo-x86-freebsd create mode 100755 binaries/ilo-x86-linux create mode 100644 binaries/ilo-x86-netbsd create mode 100755 binaries/ilo-x86-openbsd create mode 100644 binaries/ilo-x86-windows.exe create mode 100644 binaries/ilo.jar create mode 100644 source/ilo-68k-mac.c create mode 100644 source/ilo-aarch64-linux.s create mode 100644 source/ilo-amd64-dragonfly.s create mode 100644 source/ilo-amd64-freebsd.s create mode 100644 source/ilo-amd64-linux.s create mode 100644 source/ilo-amd64-netbsd.s create mode 100644 source/ilo-amd64-openbsd.s create mode 100644 source/ilo-banked.c create mode 100644 source/ilo-be.c create mode 100644 source/ilo-dos.c create mode 100644 source/ilo-js.html create mode 100644 source/ilo-min.c create mode 100644 source/ilo-plan9.c create mode 100644 source/ilo-pthread.c create mode 100644 source/ilo-safer.c create mode 100644 source/ilo-teensy41.ino create mode 100644 source/ilo-windows.c create mode 100644 source/ilo.c create mode 100644 source/ilo.cl create mode 100644 source/ilo.cs create mode 100644 source/ilo.cxx create mode 100644 source/ilo.d create mode 100644 source/ilo.fnt create mode 100644 source/ilo.go create mode 100644 source/ilo.ha create mode 100644 source/ilo.kt create mode 100644 source/ilo.lua create mode 100644 source/ilo.nim create mode 100644 source/ilo.py create mode 100644 source/ilo.retro create mode 100644 source/ilo.rs create mode 100644 source/ilo.swift create mode 100644 source/ilo.ts create mode 100644 source/mult-ilo.c create mode 100644 source/x11-ilo.c create mode 100644 source/x11-mult-ilo.c diff --git a/LICENSE b/LICENSE index b9c199c..fb039d6 100644 --- a/LICENSE +++ b/LICENSE @@ -1,8 +1,30 @@ -ISC License: +================================================================ -Copyright (c) 2004-2010 by Internet Systems Consortium, Inc. ("ISC") -Copyright (c) 1995-2003 by Internet Software Consortium + _ ___ ____ _____ _ _ ____ _____ + | | |_ _/ ___| ____| \ | / ___|| ____| + | | | | | | _| | \| \___ \| _| + | |___ | | |___| |___| |\ |___) | |___ + |_____|___\____|_____|_| \_|____/|_____| -Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. + Konilo & ilo -THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + Copyright (c) Charles Childers + +================================================================ + +Permission to use, copy, modify, and/or distribute this +software for any purpose with or without fee is hereby +granted, provided that the copyright notice and this +permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS +ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO +EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN +AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +OF THIS SOFTWARE. + +================================================================ diff --git a/README.md b/README.md index 1f1fa4d..8df0407 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,37 @@ -# ilo-vm +================================================================ -The ilo virtual computer. This is mostly used with Konilo, a Forth based computing system. \ No newline at end of file + crc's _ _ + (_) | ___ + | | |/ _ \ a tiny virtual computer + | | | (_) | 64kw RAM, 32-bit, Dual Stack, MISC + |_|_|\___/ (c) charles childers + +================================================================ + +# Welcome! + +This is ilo, a little virtual computer. ilo is mostly used with +Konilo, a personal computing system written in Forth. + +A brief overview: + +- 65,536 memory locations ("cells") +- 32 bits per cell +- block storage device +- stack based architecture +- minimal instruction set (30 instructions) +- easy to implement and exend + +This supports a variety of host architectures. Precompiled +(mostly static) binaries are included for Linux, OpenBSD, +NetBSD, FreeBSD, MS-DOS, macOS, Haiku, Classic Mac Systems 5-7, +and Windows. It has been tested and confirmed to work on x86 +(8088+), amd64, arm64, and 68000 processors. Physical RAM +requirements are around 384K. + +In addition to the provided binaries, many implementations of +ilo are included. These include Assembly, C, C++, C#, Common +Lisp, D, Go, Hare, JavaScript, Kotlin, Lua, Nim, Python, +RetroForth, Rust, Swift, and TypeScript. + +================================================================ diff --git a/binaries/CWSDPMI.exe b/binaries/CWSDPMI.exe new file mode 100644 index 0000000000000000000000000000000000000000..68658929c4e5e71e5c157ed92cd3f00ad81d2780 GIT binary patch literal 21325 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 literal 0 HcmV?d00001 diff --git a/binaries/ilo-68k-mac.bin b/binaries/ilo-68k-mac.bin new file mode 100644 index 0000000000000000000000000000000000000000..a251dd901b4d1972782620a8dd2c508065c4ec45 GIT binary patch literal 23424 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 literal 0 HcmV?d00001 diff --git a/binaries/ilo-aarch64-linux b/binaries/ilo-aarch64-linux new file mode 100755 index 0000000000000000000000000000000000000000..871d449c40cfe06d0fc2ad419857bfd2eadb6dcd GIT binary patch literal 4072 zcmcInVQdsd6n=ZRrMtZX?MW;aNvZl{d#w#5Y61Omm152Vqcm!aia^!m$`!G+CR|G6 zfojHjO~T)%9Z})KI$JeF)xk1a{q^*$Mg0o`^H_flH!fL=10z&wqDiB*Zq#9`}I7% znU2p=880OV9UYWZt@mB}uxce>?+VzYAI4s2U!&fsFH3v%fYKR!?E?1vve0*W;EI0P zmh(%((dpWF0ld3k-jAN_5e`ICyS_jqXEXqzOnU96Lf{VacAE!Q8<<*ju_(lggu zPe?Kk=B*|2rrXIICnvN-gB9p@a;MTGa)*83`jhiThYWJFR7c+EiQN7u)@<^6nGV}; zGv**4d9KJ`$ZeA3*p6z9A3z&MzNX>-P^{W?a=Mjsnr-0m5ad{%^SU|~F?rv&5t`%k#_piE(juj;hv0 zmL;6cvcB>(&L-zEk7-Ad=kUW^>--|=7?*U6K*xOZSs&+%>nkm`-4t=cUgW)V{KVRb z2ixJsIy4qBIrbZ3QBzZVQMTKske_oPs?aV?>3h7|iEU_Xc1~QAPSmOYT<3fLgU%oR zna&oKPTwg2kAKOtfk#=Plsr{l~x=T5{Jx`b|=J0D^kaL!fHmw}!T z$5iq8LXgitv)4E``mg79`j%a3ZoY2})Cv^ep$KY)uopR4gWTiXEV(p=9_vx*R7jve14TxbP zb!>}3cgV3T1bv2N)1+jRd{0HOzQ*?g?ka6LT}=1l?Y4mGe#0GAMD%L-*s3JPOYV=I zU|;o+QgQw%$L77Tqw!B5CIMXSK2FlN$@Y-46Fcd0}P-BSP8H%Rs;6{L7)K$0ULpbfQNy{fG2^i zz%u~*tp#A;wFB(GJwP1j0`h&>KfGl%zpsTaJGC2VIr-n6=1Ta<0k9e zk9hN2RI3lRrcd^j4=DDz6>qJ?%s1yx&?DYjEYIIS$eBOjtGRS@%qI|QK3^JgU%R+A zX>9Z4_~myejm@5^PcCJ9e}wKsmk_s>owZFZJD-lW5tF-i?jWjdi?p@xYTwpGwe8RD zZl~I&wl=utx_>@sK%7Z@v!WexzH^5h%@xx3F?Xp>zuT08z`pRs?EKvC+!CA5edpRd X%gR4qdwQ-k;C@%*4A1zny!`tcOHpF^ literal 0 HcmV?d00001 diff --git a/binaries/ilo-amd64-dragonfly b/binaries/ilo-amd64-dragonfly new file mode 100755 index 0000000000000000000000000000000000000000..6ee67589c3ae82df25daff66be33f10f40639f0b GIT binary patch literal 2816 zcmbtWZ)jUp6u-%PT~phTYOUSeN~ev8c8dgySY}5qZMqj0Bu>OR|Af}2?O4}f^K=yl zRw9(gfsb^>T!o;n0Ml7nW-Rv;xS%veAEJlo!-qmmN9g192z`tmwpK8s z=lf<#y73eF3o_N@aE&;jo?)>*)#Y#^|8w;^u6}aZm~v`5vzlQ1 zxV9%;$L>^qA5nwVMnk-?ZhX`?F=v5S3J&{^>wC6lRt<){oDVhhsrI~Jsqg8-b%H$1-;hZ-1CtdoNu30V`rZImwLDCyP}2qX+>Rnv$Uag z)Jd|p!TPNY^!GN<h+;( zuu7XSx%#ffzb_F#ztMc6OEEe>g$@)dwA}zKb{@s|rSqMYT9JW2kIhNZepp3n_x=g( zg8%W^N9y*9RMaV(5Hzu;W{n;8pu1{Cj!MEn-t$~&e#7P9M(!z zo(bn-;-$Z_3@6`N!Lx`u_R@yq9G%Wa#-_7RAIlMBXS2r%***Bg3-kISUK0fFLq-og z_z0QIPLJ=7Mxyrt)@Vqulv%zvE7lU+vVG053cxvuNM!Rpi7E-QQ20ISb&^Q+4UIb7 zS37vD?}R4d8Th9}d~^Jp>fo&|?km3+%AwMknQ@X%kL7adoH{zIl5}Q#R2?NGl6(HR zIyweaon>@NaB5~wB~Vz`Fv4aCKq50)H4~Yfc{YM&-TPc-Hg_~TQ(o%-Fgw8+Yk~X5 zAf{DuD+@qXeVJkK~6>4%x8$}JdCIJm0{W&dw4s`s2ibOQYybcN literal 0 HcmV?d00001 diff --git a/binaries/ilo-amd64-freebsd b/binaries/ilo-amd64-freebsd new file mode 100755 index 0000000000000000000000000000000000000000..dcbcf30edc2afca4bf730696e16693993bdf216e GIT binary patch literal 2384 zcmb_eU5FD`6u!w!G^+`-qU(xvNx+oiPXobysMwVqvau7I!s?4#wGX@M)}m#>Oi{4Z zlo6K8Ft8MVC{#)xib5&27Pd>kHDMI-rQrHt>BCYVw6jgMg3!3ydV9{yy|WWHX?*B~ z+;i^toxgi$=G>gj6?TL}p$@`Fm~1B@&}UaCU8LWg3F(Y-1w=o2gG6AC5Sc82wd`UZ z-%paRBIFtj217^@24VDD7)h>rvdH~}B%L0Oa0GrO&X-nr_Cg-Uf?x<4^h2t))TPOz z*OIPMQ&qhlWulI+`eqBL=?!CxIz zcdEN~DUm(u9`#*y$ezO8W&SEp!UmmL#u&ZfVbi!{55B=+EX*mx!q&{bjjLfX4U3M7 zzOg``m+^q7Bs4h(sPhv{nTlrhM8L3Mz4{4=T;_p22)+-y!0N2$+wJ?}NjQ7a_cNHF zv{@*@+)}+C%gi`gfZXW0=!_ozPJY|!9WUc)I~#y8i+^iIEox8LqoZjhaS9?45>y4I z8Mdsl>r~2`@};1$k|?1M@>B{EfhbCXm=ffXTl3?seckwZ0>OU_!CpSLuXWH;zwBf(}FCI>Ayyeq@^EH>NG&XKF+nf7*q&ClYlhkBq zf&JIlFWUD43+G3xru2Dzo~~?BDx;4i-Sk-FVrFvEP4B%0VNtw4u4wE}z)$U*P;0i?4XCi;le z2a)aqM7`kiqtTCn=Qg$4($ZyDG@>oY(=>(i{)F}h|JQcq8^iN?Q211sL+t-it5_t8_v=1xL|fhN^l75(omv-gs!Og>ku z52FU_ITo${7STd~vO6yi4$yjoXP#ZpfBFxe(8pg*;j_vx=gd4~grtjyiuzG~c!a=( zbYNH?CTacPah;?`ibb&dKSm6KV9qcPHWW&_+7N;;Uh#xKbJ$<60u3>7=Zbs1#0~v> uoqP0iDa2Y(@IMCLdpP`ip5Oca{qE7OEmvKEbqn7hF8((pf*|NG*8eYCY*{V< literal 0 HcmV?d00001 diff --git a/binaries/ilo-amd64-haiku b/binaries/ilo-amd64-haiku new file mode 100755 index 0000000000000000000000000000000000000000..ef9954ea5889f68331cfb7558d973a8feec6f70c GIT binary patch literal 15344 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 Gq5lgy^kWkM literal 0 HcmV?d00001 diff --git a/binaries/ilo-amd64-linux b/binaries/ilo-amd64-linux new file mode 100755 index 0000000000000000000000000000000000000000..c8a4447e90d34784b36ea023801caa88be34ec9b GIT binary patch literal 2312 zcmbtWU1$?o6u!yKXw-yJY*ng~fDr{X%U~ar>e8W&PB215kiNERt*8{5f%+h9B|^Cj z0|nQG!m8}TvcCEAP)l&v38PjYtq+PI=z|)qe<&E;b-kW5b8kA?Hb(G5=A3)J^PPL| zxijbFr*w8(I24iyA7Sz%34wlTNy4+Vdrv}c&gBY-cCv{m@KlIQ=D=L`Y(Cyj5}qRD zG7JVo$cR7n)#@0yhZHW~Bo7|$PxTz`-+L%eP#x$$LP(32>o-qWHT>}~OttsLF*uK^ z&e<3kt$aViCYKzKDyED6?>>*K@q zxnBHC;hL;dIXO!lHQp)K*DX1jDZHp%$HNbF+I?(RvY!ErpQh`Rb^JyOZN!Y#I(6_g zdhroge6p}lXA#byw${(w*|f*VW=Z|oQOBIhy%~A(;sbuF0sdch_t;^YT-7@D(Fd--e>cB219peeYpV1&Zk zVmJQ+^vZq1?p%DdR1Q-qW6MpTxSEr-x1NH62Bq#T6ecKjhrks|ondb{fq!!k511;a%!Osz2NSnfHHXlxW6?AT6!b`oY~>mSCZ1_Bi+sCwVm zcB}Qgu8w`yORpjYwsJ61da4+q*X-`M8#`&GhM8g4GspkKY#jS-d<&#TV=A<~RK727 z4w&6N1iHz-ZnK-D%>74AlIqFl!Rb3k6!>`c*p6^?g%T)0dV(zXMfJ(e)p-+WXcN6s z^y4A!SnbE0(axn1Eudfr5`RQQU#|9R(U&@yJ9;qcEy%j*>N{^f~jmNNFTfDX4~Srfz3#Z z2v(vj*I_WCK2(L`gIMsPBC^H>ZNgYeA6*4YpX@_x>b5ErOsloyId|?&X5Eb`;)UFE z&i9>j?qBBI`${JFbWDl=Lwo{5Lpr(< zA(;W)DTU99kGJ=-Gs#m5m%Eaf1%DO3j*6s%g|?1@Y-D{~ioIA1IO-VoY{7YI-xwj6 z5;8e5T{QC3#e>h6m^xd0fsld6pL_A8H{Rlz{+p=cW}3e*%)@}1O3(QW_!@_gV7LRC z>f7$F+kJ#I&ILixQ*#D$^v(iKw<+LaXy5&WWX$XSI0X6_crpy! z&AwI_k{hk*9K$h-A@H#Fb$*r87U*IrcctDO>(Vv8a+> zC6AVZvkk|$TqT_?Ut2y7;}4B_hl5pv!!=|64Be9M;8!W{Bu;X<(`dMXQ!GF7Y8Wi= z_J+dxGwzm^Gi!TPcF5X0HEq7uys%=QSbpH&?ZSW1g+KXkJnYbgb>X*l;c3)nMEVBD`IoRu`U*?04`aqD{Aawr z3WPT=+TK|2v3es$<*cV{0L3?JId9jSP}88=U4y~|)vf@pQ0;7Q>mf|)=F)My=e(0f zZ9Qt6Y?}NWd=c1)KtBMV0I>9+?Ikz;3_&#cHad98{?PKkYP|kO5G+kc>QY4A?GB%| zwD~(${g-$-7&scQ|D@W|ufY#@50261vdC<3Hv8&dxDPLXSjDq20}XBoqjb3B%sLZ! zV$2ksf-zHY@})`R$Yf#0A;xTRa>AJ)hEq5OR=!k%xc{RiAPL@y;<~R$I#}&{RotTt zgbx2m(Ut-O*C66gNjg|?&m#!!fl#!14!7(<&=70A0mOTQCv3elc*F>oLTm*EpB#8Y hViWHT@eXOdH$s~Ea+L`jM#M&O5&viu1pS}${~PUxElvOc literal 0 HcmV?d00001 diff --git a/binaries/ilo-amd64-openbsd b/binaries/ilo-amd64-openbsd new file mode 100755 index 0000000000000000000000000000000000000000..6c14fd8ba9b1a6d5112de57790b0450dee7b02a9 GIT binary patch literal 2528 zcmb_eUx*V&7@uT!HF^natJf3tFks}aR0CVDsHo-EyXb~Sydo4Iz4TI*o|j^_C`Awn za!i+{De8k-kUsbae6W;qO%JLGt4N_QJq3$T`cNAit%A^Kt4_afb|x1kxfJQZe*b>o zpPAX+Z{}bkwJ8_~5IKV6U4q)0t|&M4b4tjLkPv|NlQm=(&{;%-hY*$9e7v7TxghzF zNG-WcgJz7I9#J9s+!Jw3e@#w6L0zL)J#M&&-?wjD1a+hy=gOG%A-y4EJ4+Bs6feY$^xKv%M zoCN!JuXqMDXI1%5*qG8ao-`4fvV-5K@40>BllUri&B;Br^3{-6)qcj|6=oh*-cwC> zg(?G%dZCFk;#6q@h_sFZ)zsGb_zba_BALIenpBOo%H!8J9W|EB-)mB5=b*cbwF(yb z6Ldwa(XTp}Zw)8;b;OR~B&MAP#0IM9fVk!dOM93H3X*VEw3wN{L2DKLXi1+a)qZWh zPkQm_8An3nDfZEAR`u?F|*N4_v~gW6?X4$aQVI`0D*X zgm;4>gEiouNlVaJ(yu{ddFLO-62?^J2jG=0Ko0dB`e}B0Wq)O6N7l7ayrIfqj3+QRk?e0Ni zf^L@qSLk+@yK*NcbyBgAHRmTghSEHg7Fjg%9r&VQAsV{Ca2^cRC6*gm^aljd$PsjK zBVE4cf>t^FH)GXN`9;0RH#>b7Onu_HS^hJWXWjck<=-_c@POU;@5Vt|dm%E(t|SjV z!+kjLbrIi%!E}wpbGvf(UVAuA;$vAm6VJlol+KOBcaLPoYyt<;$gn+3;&x^~Xz5%I z;{K1(0ZC@VBaiz+APU;_xhl_5ZUllKQsY<(3a&xMp9@4mgL58@Fc$l)PKCLy_ke`9 z`W-;tH$=kvJwrtF3ohA85b#XL6B38KZ^(N{{l4MD+*gR4VQm@PXqWMCHyS~HdH(+b D66r6K literal 0 HcmV?d00001 diff --git a/binaries/ilo-amd64-windows.exe b/binaries/ilo-amd64-windows.exe new file mode 100644 index 0000000000000000000000000000000000000000..b1fc733d038577c6dba5e171d57a24524f62dfa9 GIT binary patch literal 6656 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 literal 0 HcmV?d00001 diff --git a/binaries/ilo-arm64-darwin b/binaries/ilo-arm64-darwin new file mode 100755 index 0000000000000000000000000000000000000000..c33ff25dc578be7ded273e11d1bc306cb748058e GIT binary patch literal 34496 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 KYYuyle)wP4oOcNT literal 0 HcmV?d00001 diff --git a/binaries/ilo-dotnet-windows.exe b/binaries/ilo-dotnet-windows.exe new file mode 100755 index 0000000000000000000000000000000000000000..284b9f9815bffaea291de4d5af942822f3d30ec5 GIT binary patch literal 8192 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 literal 0 HcmV?d00001 diff --git a/binaries/ilo-ipad-ish b/binaries/ilo-ipad-ish new file mode 100755 index 0000000000000000000000000000000000000000..00a300b076ca83382d7977e97f67c506962e63c1 GIT binary patch literal 33732 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 Vs4jdFt?(yUB~a6m55dsqe*@f_N96zj literal 0 HcmV?d00001 diff --git a/binaries/ilo-luna88k-openbsd b/binaries/ilo-luna88k-openbsd new file mode 100755 index 0000000000000000000000000000000000000000..0dbff42810f809685bc23baafcab08ceabc299c1 GIT binary patch literal 9348 zcmeHNeNbE1l|N6C;R%F|V@Zf@669C{oWugUhMLxyFoeWpZ8n~MMXDi4NCFYQTuDyi z1~*FVG>#1|o4T#D$#%8aosbx{o+i!2t#`w0ybV*k6MM!<-LA8yt=GX_(ZP-$q$%e0 zcb=Z$g_6|nO!u$6nIHGu^L5WX_wzmU$eo++5_AI1Jvv$f8jR(WDAy9%k14XXWTzY| zB^wo>o|Ts6L(ULt(ok#-km-q543V%Z4OGBmu#6j18_WmEfUW|z=Q_)^_8by}?K5)Q z5a~+OAYl|H0A<8t-^@tCc(*yapd)j2mcic{dgnY}4GDXJ(KX}|?irfm! z%|zZu$dKAur8|c4^6ml+8Eng8>nJ%#_F~9a6_M?xbCiG6zmhmjZoMD;l-F&T8Use$ zx>U@)Bvs?KouJ1rPutx~k{%MLVs71WSw5GFna$9J%uoOw>nJ@g-RC8JQ=IgkZ@SKV z60Y-7B4E0l7|>1ph(58!PV^D-ES7s>B(VMKvOK<~zue$?5kC5@h3uc(LOccTIQR2} z$zM%^bfnkvc7yyL>%rzS+h3#2+Z zGR-#Q4U{d#%r>rbzuIhMU_SK!*fvY~7-Mq*{I5WJh{MitXyToVr{s1raqcYrWrsPQ z2_V?Xfw;*;2KArJP9K74RhuFbC@qbgdf5@`jWeL)d1%e{X(AS zbF0qJx&A2mO~ofLN$ zVjM&z?~o~TiAGJ#M=oZVug%569BcED8guJ72Y2gax+KQMh7yvwACt9lTdLMAURu3h z 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 literal 0 HcmV?d00001 diff --git a/binaries/ilo-teensy41.hex b/binaries/ilo-teensy41.hex new file mode 100644 index 0000000..e971cbc --- /dev/null +++ b/binaries/ilo-teensy41.hex @@ -0,0 +1,4230 @@ +:0200000460009A +:100000004643464200000156000000000103030081 +:1000100000000000000000000000000000000000E0 +:1000200000000000000000000000000000000000D0 +:1000300000000000000000000000000000000000C0 +:1000400000000000010408000000000000000000A3 +:100050000000800000000000000000000000000020 +:100060000000000000000000000000000000000090 +:100070000000000000000000000000000000000080 +:10008000EB04180A063204260000000000000000FD +:10009000050404240000000000000000000000002F +:1000A0000000000000000000000000000000000050 +:1000B0000604000000000000000000000000000036 +:1000C0000000000000000000000000000000000030 +:1000D00020041808000000000000000000000000DC +:1000E0000000000000000000000000000000000010 +:1000F0000000000000000000000000000000000000 +:10010000D8041808000000000000000000000000F3 +:100110000204180804200000000000000000000095 +:1001200000000000000000000000000000000000CF +:10013000600400000000000000000000000000005B +:1001400000000000000000000000000000000000AF +:10015000000000000000000000000000000000009F +:10016000000000000000000000000000000000008F +:10017000000000000000000000000000000000007F +:10018000000000000000000000000000000000006F +:10019000000000000000000000000000000000005F +:1001A000000000000000000000000000000000004F +:1001B000000000000000000000000000000000003F +:1001C000000100000010000001000000000000001D +:1001D000000001000000000000000000000000001E +:1001E000000000000000000000000000000000000F +:1001F00000000000000000000000000000000000FF +:10020000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +:10021000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +:10022000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +:10023000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +:10024000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +:10025000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +:10026000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +:10027000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +:10028000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +:10029000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +:1002A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +:1002B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +:1002C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +:1002D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +:1002E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +:1002F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +:10030000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +:10031000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +:10032000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +:10033000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +:10034000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +:10035000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +:10036000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +:10037000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +:10038000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +:10039000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +:1003A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +:1003B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +:1003C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +:1003D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +:1003E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +:1003F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +:10040000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +:10041000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +:10042000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +:10043000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +:10044000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +:10045000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +:10046000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +:10047000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +:10048000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +:10049000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +:1004A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +:1004B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +:1004C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +:1004D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +:1004E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +:1004F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +:10050000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +:10051000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +:10052000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +:10053000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +:10054000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +:10055000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +:10056000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +:10057000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +:10058000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +:10059000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +:1005A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +:1005B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +:1005C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +:1005D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +:1005E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +:1005F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +:10060000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +:10061000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +:10062000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +:10063000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +:10064000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +:10065000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +:10066000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +:10067000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +:10068000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +:10069000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +:1006A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +:1006B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +:1006C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +:1006D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +:1006E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +:1006F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +:10070000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +:10071000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +:10072000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +:10073000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +:10074000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +:10075000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +:10076000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +:10077000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +:10078000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +:10079000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +:1007A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +:1007B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +:1007C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +:1007D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +:1007E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +:1007F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +:10080000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +:10081000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +:10082000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +:10083000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +:10084000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +:10085000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +:10086000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +:10087000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +:10088000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +:10089000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +:1008A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +:1008B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +:1008C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +:1008D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +:1008E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +:1008F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +:10090000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +:10091000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +:10092000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +:10093000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +:10094000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +:10095000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +:10096000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +:10097000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +:10098000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +:10099000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +:1009A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +:1009B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +:1009C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +:1009D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +:1009E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +:1009F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +:100A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +:100A1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +:100A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +:100A3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +:100A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +:100A5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +:100A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +:100A7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +:100A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +:100A9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +:100AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +:100AB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +:100AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +:100AD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +:100AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +:100AF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +:100B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +:100B1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +:100B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +:100B3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +:100B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +:100B5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +:100B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +:100B7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +:100B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +:100B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +:100BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +:100BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +:100BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +:100BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +:100BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +:100BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +:100C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +:100C1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +:100C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +:100C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +:100C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +:100C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +:100C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +:100C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +:100C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +:100C9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +:100CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +:100CB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +:100CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +:100CD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +:100CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +:100CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +:100D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +:100D1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +:100D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +:100D3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +:100D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +:100D5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +:100D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +:100D7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +:100D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +:100D9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +:100DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +:100DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +:100DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +:100DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +:100DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +:100DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +:100E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +:100E1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +:100E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +:100E3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +:100E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +:100E5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +:100E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +:100E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +:100E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +:100E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +:100EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +:100EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +:100EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +:100ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +:100EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +:100EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +:100F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +:100F1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +:100F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +:100F3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +:100F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +:100F5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +:100F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +:100F7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +:100F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +:100F9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +:100FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +:100FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +:100FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +:100FD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +:100FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +:100FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +:10100000D10020432914006000000000000000000F +:10101000201000600010006000FC00600000000074 +:10102000000000600008010000000000FFFFFFFF5B +:10103000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +:10104000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +:10105000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +:10106000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +:10107000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +:10108000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +:10109000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +:1010A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +:1010B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +:1010C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +:1010D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +:1010E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +:1010F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +:10110000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +:10111000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +:10112000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +:10113000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +:10114000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +:10115000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +:10116000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +:10117000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +:10118000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +:10119000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +:1011A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +:1011B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +:1011C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +:1011D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +:1011E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +:1011F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +:10120000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +:10121000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +:10122000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +:10123000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +:10124000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +:10125000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +:10126000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +:10127000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +:10128000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +:10129000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +:1012A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +:1012B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +:1012C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +:1012D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +:1012E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +:1012F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +:10130000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +:10131000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +:10132000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +:10133000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +:10134000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +:10135000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +:10136000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +:10137000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +:10138000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +:10139000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +:1013A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +:1013B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +:1013C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +:1013D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +:1013E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +:1013F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +:10140000884207D0904205D251F8043B40F8043B93 +:101410008242F9D8704700BF884204D2002340F8C6 +:10142000043B8142FBD87047664B4FF42A01664A61 +:1014300066482DE9F0475A641864654A99639546F1 +:10144000BFF34F8FBFF36F8F00F004F9614B08209B +:10145000614A6249C3F854016148FFF7D1FF614A0C +:1014600061496248FFF7CCFF61496248FFF7D4FF4A +:10147000614C62494FF470000023614A086044F8EF +:1014800023200133B02BFAD15E4B80215E4A03F852 +:10149000011B9342FBD14F4D4FF080385B494FF019 +:1014A000FF325B4B0026DFF8A4A1DFF8A4911C609B +:1014B000C5F80481C5F800A1C5F8F480C5F8F0901E +:1014C0000B68544F43F4E0230B60FB693D4923F064 +:1014D0007F0343F04003FB617B6A23F07F0343F00B +:1014E00040037B628A66CA660A674A6700F0B8F8FA +:1014F000494A4A4B6320A2630321E363484A494BAC +:10150000106000F160401E6042F8041C00F6A170FB +:101510004549464AC3F8082D0B68454A43F0807395 +:101520000B601368434943F00103136003680B60C9 +:1015300000F0E6FAC5F804813F48C5F800A1C5F8F7 +:10154000F480C5F8F09000F08BFCF96E3B4A41F452 +:1015500040513B4BF9661660C2F80861C2F8186149 +:10156000C2F82861C2F838619A6BD20708D442F6F3 +:101570001562344959651A659A6B42F001029A6303 +:101580002F4A314C936843F00113936000F0DAF86E +:1015900000F016FC00F05CFC00F0E4FA00F05CF8EF +:1015A0002368132BFCD900F06BFB2368B3F5967FFF +:1015B000FBD300F053F800F043FC00F04DFC30BFCB +:1015C000FDE700BF00C00A40AFAAAAAA070020009A +:1015D0000000072000800D40A8BF0000481F0060E9 +:1015E00000000000C01A0020F4DE006000000020AF +:1015F000C0280020C01A00200018002088ED00E05C +:10160000C998000000E400E0A0E400E024ED00E060 +:1016100008ED00E000C00F407DAC000081AC000090 +:1016200014E000E018E000E0FCED00E00000202005 +:10163000001000E0EC2700200046C32300400840D3 +:1016400000400D400000C056F02700201B1018205D +:101650000C0D1113704700BF704700BF704700BFEB +:10166000F0B5244A0020244B4FF0100C234C1126D7 +:10167000DFF8C8E0122720600125C2F800C0C3F8D7 +:1016800000E01660DFF8B8E01D4EC3F800E01D4929 +:1016900017601E6041F015011B4F1C4E17601E6045 +:1016A0001B4F1C4E17601E601B4F11601B4E1C49C8 +:1016B0001F6016601B4F19601B4E1C4917601E608F +:1016C0001B4F11601B4E1C491F601660196025607E +:1016D000BFF34F8FBFF36F8FC3F8B001BFF34F8FCE +:1016E000BFF36F8F52F8883C43F4403342F8883C94 +:1016F000F0BD00BF9CED00E0A0ED00E094ED00E047 +:1017000009001000C028002013002000210002075B +:1017100014000020250008130900001016002020E6 +:1017200027000B131700004033001013180000604F +:101730002F000B07190000702F000B133F00001043 +:1017400025000803F0B58D4B18228D4E01208D49E0 +:1017500048F20C7E8C4D4FF0FF378C4C83B0C3F8B1 +:101760005C12C3F860520025C3F86412C3F86842E3 +:101770004FF40054C3F86C628549C3F87062C3F833 +:101780007462C3F87862834EDA661A675A679A679A +:10179000DA67C3F88020C3F88420C3F8882040F2B9 +:1017A0000562C1F82C03C1F83003C1F83403C1F855 +:1017B0003803C1F83C03C1F850032946B3697648A1 +:1017C0001840764B03437648B361D6F8843043F033 +:1017D0000C03C6F8843002260368334303600368B1 +:1017E00003EA0E0E6F4B4EEA0303DFF8F0E10360ED +:1017F0006D4B4760DEF808703B406C4F43F0005380 +:101800008360C36823F07803C360036A1F40684B9A +:101810003B43664F0362036A1F40654B3B43654F82 +:1018200043628762C762DEF8B830634F23F03F033C +:1018300043F00103C0F8B830DEF8BC30DFF884E1D3 +:1018400023F03F0343F00103C0F8BC300561046698 +:101850000767C0F8802044664767C0F884200468A2 +:10186000564B24F00204564A0460C0F818E0C661E2 +:1018700043F8041B9342FBD1494B1A68194642F0C6 +:1018800001021A600B68464A13F00103FAD14D4E6B +:10189000022540F2F56440F2664040F299414A4F19 +:1018A000966142F20146D56140F23545C2F80042E8 +:1018B00042F20124C2F810020120C2F8201211469F +:1018C000C2F8307207F15A47C2F8346207F513774D +:1018D000C2F840523D4E3E4DC2F85072C2F85462BA +:1018E000C2F86052C2F86442C2F8A030C2F8A43014 +:1018F000C2F8B0004B692A4ADD07FBD5012300245A +:101900004FF4803011465361C2F8A040C2F8A400E1 +:10191000C2F8B0304B69224ADC07FBD50123002412 +:101920004FF4003011465361C2F8A040C2F8A40041 +:10193000C2F8B0304B691A4AD807FBD501230024FE +:10194000244811465361C2F8A040C2F8A400C2F86E +:10195000B0304B69124ADB07FBD5D2F8003145F6AF +:101960000D5121209BB250618B4239D01A4B00227D +:101970001A605A609A60DA6003B0F0BD00801F40C0 +:10198000F9700100F9B00100F9100100F90001003F +:1019900000841F4000C00F40FFFCFF1F000300A099 +:1019A00000402A401200FFFFFF37F70000FFF07CE5 +:1019B00040000080FF000F836300020000422A40C5 +:1019C00000432A40F05AF05A9F041830063201268C +:1019D0003806180A040003006428002000802A400A +:1019E00000244FF4802001231146C2F8A040C2F821 +:1019F000A400C2F8B0304B693B4ADF07FBD5012396 +:101A00004FF40004002011465361C2F8A040C2F810 +:101A1000A400C2F8B0304B69334ADE07FBD501237E +:101A20004FF400044FF4803011465361C2F8A040D7 +:101A3000C2F8A400C2F8B0304B692B4ADD07FBD5D1 +:101A400001234FF400044FF4003011465361C2F8F3 +:101A5000A040C2F8A400C2F8B0304B69224ADC07AB +:101A6000FBD501234FF40004204811465361C2F80E +:101A7000A040C2F8A400C2F8B0304B691A4AD80797 +:101A8000FBD5D2F8003145F60D5121209BB25061B3 +:101A90008B4210D0164B08224FF400041A701549DF +:101AA0000020154A01230090521A1448224400F0E5 +:101AB000BFF903B0F0BD4FF400044FF480210123BF +:101AC0001046C2F8A040C2F8A410C2F8B030436972 +:101AD0000549DB07FBD50120054B10224FF0807430 +:101AE00048611A70DBE700BF00402A400400030091 +:101AF0000D28002000000070000000706428002005 +:101B0000F0B4174A40274FF480314FF480564FF419 +:101B100000554FF4404443F24200136913F0020FA2 +:101B200006D0946151619061136913F0020FF8D1EE +:101B300013F4005F01D15561EFE713F4805F01D129 +:101B40005661EAE7002BE8DA13F4803F01D0916197 +:101B5000E3E75B0601D45761DFE7F0BC704700BFE5 +:101B600000800D40394A03203949F3EE095A1368C1 +:101B70009FED386A23F00103DFED376AF0B413609C +:101B800000241061D1F8E030344FD8B2C3F30B21F8 +:101B90001B0D334E07EE100A05EE101A07EE903AB1 +:101BA000304BB8EEC55A304DB8EEC77A3060F8EE1B +:101BB000E77A29602D4937EE466A2D4E77EEC57AD1 +:101BC0002C4877EE666A2C4D37EE657A26EE276A4A +:101BD000C7ED007A66EEA76A176867EE277A83ED8D +:101BE000007AC6EE075A86EE876AC7EE876A35EE38 +:101BF000857AFCEEC77A36EE057A17EE903ABCEE9F +:101C0000C77A47EA035376EE857A136017EE103AE7 +:101C1000D2F81071FCEEE77A01EA0341394317EE7E +:101C2000903AC2F81011C3F30B03D2F810110B4312 +:101C3000C2F81031136843F0020313603470C0F827 +:101C400040510E4B0122F0BC1A60704780810D405C +:101C500000441F400000AA420000B442E0270020D8 +:101C6000D8270020DC270020D42700200000FF0F09 +:101C700040E400E0001800208D9A000008E100E038 +:101C8000304B40F6617270B5C3F8202140F2044534 +:101C900000F0CAF82C492D48D1F880202C4C42F095 +:101CA00003022C4BC1F88020C0F860512268134019 +:101CB0001BB9D0F8A8319A071AD0244B4FF0004135 +:101CC000234A51631A46D3F8401141F00201C3F888 +:101CD0004011D2F840319B07FBD44FF400301E492D +:101CE0001B4B4FF00042086019209A6300F0A4F8E3 +:101CF0001A4D0022164B4FF08041144C0A2699636E +:101D000028461A601146C4F8A8614FF4207200F00A +:101D10009BF84FF4810640F243114FF48000104BC2 +:101D2000104A2E602864C4F85851C4F84811C3F80A +:101D300004220D4A4FF4003101231160C4F84031F0 +:101D400070BD00BF00800D4000C00F4000002E405D +:101D500000900D40001C1E008CE200E000000020FE +:101D600000180020599C00000CE100E008B50E4B63 +:101D70001B6E9B0700D4FBBE72B60C4B00200C4AB6 +:101D8000C3F8400103F160430A49A3F55F231164DE +:101D90009D46BFF34F8F084A03F5E0430749126899 +:101DA000184619609368984700441F4000002E4071 +:101DB00000C00A40030020001C002000000012EBBD +:101DC000114B1249D86E0A4640F4403030B4D86600 +:101DD00040F23765D86EA02440F44070D8664D6458 +:101DE0008C64936C1B06FCD4094B40F23760A02135 +:101DF0001A4658649964936C13F08003FBD1054A2A +:101E0000137030BC704700BF00C00F4000400C4052 +:101E100000800C400C280020F8B500BFF8BC08BCBE +:101E20009E467047000000005FF800F0F9A3000034 +:101E30005FF800F00DB300005FF800F06996000055 +:101E40005FF800F0C5B300005FF800F009BA0000C9 +:101E50005FF800F005B000005FF800F085AE00000C +:101E60005FF800F0A5930000450000005D2200002F +:101E70001603550053004200200053006500720015 +:101E8000690061006C0000001803540065006500E3 +:101E90006E00730079006400750069006E006F00C9 +:101EA0000403090409024B00020100C032080B00C0 +:101EB00002020201000904000001020201000524DF +:101EC0000010010524010101042402060524060076 +:101ED000010705820310001009040100020A000036 +:101EE00000070503024000000705840240000000CF +:101EF00009024B00020100C032080B00020202017D +:101F0000000904000001020201000524001001057F +:101F100024010101042402060524060001070582AC +:101F20000310000509040100020A00000007050370 +:101F30000200020007058402000200000A060002F7 +:081F4000EF0201400100010065 +:101F48000000000000000000000000000000000089 +:101F58000000000000000000000000000000000079 +:101F680010B5054C237833B9044B13B10448AFF3CB +:101F780000800123237010BD481C002000000000D1 +:101F8800A4BF0000084B10B51BB108490848AFF3BF +:101F980000800848036803B910BD074B002BFBD02D +:101FA800BDE81040184700BF000000004C1C00208E +:101FB800A4BF0000C01A00200000000000207047E5 +:101FC800704700BF036D0BB101207047406D0030B2 +:101FD80018BF0120704700BF10B50446806D18B1C6 +:101FE8000BF0C0F90023A365236D2BB104F1180091 +:101FF800BDE8104006F020BC636D002BF6D110BD83 +:10200800F0B5002395B04FF47A74234F1A4605466D +:10201800183104A88DF804308DF80C3012931393FE +:102028000294009706F05CFC129B53B35C200026D8 +:102038000AF0D0FE9DF804300446184A04A9183066 +:102048002373029B22602361154A9DF80C30A2601D +:102058002375666006F0AEFB63684FF47A71114A27 +:102068000133A760A6652E712E732C616360A96089 +:102078002A600D4B04A8009306F0DEFB284615B035 +:10208800F0BD139B002BD1D1064A2B71AC602B738A +:102098002B612A60EDE700BFFC0500202006002028 +:1020A8007C060020D005002014050020036D13B124 +:1020B800184604F0C3BC406D08B102F031BA4FF0C5 +:1020C800FF307047836C00B583B063B118460122B6 +:1020D8000DF1070104F0E4FB01280CD19DF807007D +:1020E80003B05DF804FBC06C28B101220DF10701B3 +:1020F80002F03CF9F0E74FF0FF30F1E700B5836CF0 +:1021080083B08DF8071043B1184601220DF107017D +:1021180004F0B2FF03B05DF804FBC06C0028F9D0EE +:1021280001220DF1070103F043F903B05DF804FB48 +:10213800036DF0B50C4683B02BB318460DF10602BB +:1021480001A904F0E3F9D8B1BDF80430BDF80620C0 +:1021580003B9AAB102F01F06C3F343155912C2F31B +:10216800451703F01F037600013D01F5EA61D2121D +:1021780026706571A17123716770A27003B0F0BDFC +:10218800002003B0F0BD406D0028F9D00DF1060223 +:1021980001A902F06BF8D6E7036D9BB11A7812F02B +:1021A800700F00D1704710B504460021184604F09E +:1021B8009BFD606D28B100220023BDE8104002F0AD +:1021C800C5B910BD406D0028ECD090F8313013F03F +:1021D800500FE7D00022002302F0B8B938B5846D5B +:1021E8000CB1204638BD05464FF480700BF0B2F8AC +:1021F8000146A86580B1286D0C7028B14FF4807233 +:1022080006F026F8AC6DECE7686D40B14FF48072CB +:1022180003F09EFDAC6DE4E7024CAC65E1E70C46CB +:10222800DFE700BF0B2800208A79A2F150031B06C4 +:1022380021D402F26C72F0B54B7985B0046D01338C +:102248000D798E784F78DBB209784CB1039120462E +:10225800029702210196009504F066FE05B0F0BDD4 +:10226800406D0028FAD0039102218DE8E00002F0C9 +:102278005FFF05B0F0BD0020704700BFD0B5046D0A +:102288008CB1012B08BF002A01D30020D0BD114614 +:10229800204604F029FD0028F7D0204604F0B0FEBF +:1022A8000028F2D0D0BD446D002CEED0204602F0BC +:1022B8004DF90028E9D02046BDE8D04003F006B823 +:1022C800036DF0B50C4683B02BB318460DF106022A +:1022D80001A904F02BF9D8B1BDF80430BDF80620E7 +:1022E80003B9AAB102F01F06C3F343155912C2F38A +:1022F800451703F01F037600013D01F5EA61D2128C +:1023080026706571A17123716770A27003B0F0BD6A +:10231800002003B0F0BD406D0028F9D00DF1060291 +:1023280001A901F0B5FFD6E7036D13B15869002183 +:102338007047436D13B193E8030070471846194678 +:10234800704700BF036D13B1D86900217047436D12 +:1023580013B118695969704718461946704700BF84 +:10236800036D13B1184604F09BBA406D08B101F033 +:10237800FDBF4FF0FF307047836C13B1184604F06F +:102388005DBBC06C08B102F0CBB84FF0FF307047AE +:10239800036D33B11B7813F0700F14BF01200020B8 +:1023A8007047406D30B190F8313013F0500F14BFC2 +:1023B80001200020704700BF8A79A2F150031B0654 +:1023C80021D402F26C72F0B54B7985B0046D0133FB +:1023D8000D798E784F78DBB209784CB1039120469D +:1023E800029704210196009504F09EFD05B0F0BD0A +:1023F800406D0028FAD0039104218DE8E00002F036 +:1024080097FE05B0F0BD0020704700BF00690028A6 +:102418002FD00368184A1B6993420ED1026D6AB126 +:10242800137803F0080303F0FF0013B3D36950696E +:10243800181A48BF6FF0004070471847416DC9B17E +:1024480091F8313003F0080303F0FF008BB1D1E9B4 +:102458000423D1E9000130B4101A4FF000056FF0E1 +:10246800004463EB01018D4208BF844200D220463C +:1024780030BC7047084670472D070000036963B1F8 +:102488001A68074992698A4208D1186D08B104F0A0 +:1024980045BD586D08B102F0D7BC704718461047C3 +:1024A80079050000836C13B1184604F037BDC06C81 +:1024B80008B102F0C9BC7047036D13B1184604F0A7 +:1024C8002DBD406D08B102F0BFBC7047036973B100 +:1024D8001A68084952698A4207D1186D08B104F090 +:1024E800ADBA586D18B102F01BB8184610474FF036 +:1024F800FF3070476D010000036D13B1184604F0FA +:10250800BBBD406D08B102F053BF7047836C13B177 +:10251800184604F0B1BDC06C08B102F049BF70475D +:1025280003698BB10E4810B41C68E468844211D169 +:10253800186D18B15DF8044B04F09EBD586D28B1B4 +:102548005DF8044B02F034BF0020704700205DF8AE +:10255800044B7047184623465DF8044B184700BFE4 +:10256800B905000010B5036982B08DF80710BBB13A +:102578001968104ACC68944215D1186D30B10122FF +:102588000DF1070104F078FD02B010BD586D002868 +:10259800FAD001220DF1070102F00AFF02B010BDC6 +:1025A800184602B010BD01220DF107011846A047D8 +:1025B80002B010BDB9050000036923B31968134AB6 +:1025C80010B58C6882B0944214D1186D48B10122BC +:1025D8000DF1070104F064F990B19DF8070002B00D +:1025E80010BD586D0028F8D001220DF1070101F047 +:1025F800BDFEF1E7184601220DF10701A047EBE700 +:102608004FF0FF30EBE74FF0FF3070472104000038 +:10261800826C62B1137803F0080303F0FF000BB378 +:10262800D3695069181A48BF6FF000407047C16CF1 +:10263800C9B191F8313003F0080303F0FF008BB102 +:10264800D1E90423D1E9000130B4101A4FF0000594 +:102658006FF0004463EB01018D4208BF844200D251 +:10266800204630BC70470846704700BF026D62B113 +:10267800137803F0080303F0FF000BB3D369506924 +:10268800181A48BF6FF000407047416DC9B191F802 +:10269800313003F0080303F0FF008BB1D1E90423C4 +:1026A800D1E9000130B4101A4FF000056FF0004472 +:1026B80063EB01018D4208BF844200D2204630BC42 +:1026C80070470846704700BFD0B4039C16461F46A3 +:1026D80034B1012C1ED0022C0DD00020D0BC704784 +:1026E800046DDCB1012B08BF002AF6D22046114642 +:1026F800D0BC04F0F9BA036DB3B1DA69B61847F182 +:102708000007012F08BF002EE7D231461846D0BC7B +:1027180004F0EABA036D93B15A69EFE7406D0028F7 +:10272800DBD0D0BC01F012BF436D002BD5D01846CA +:10273800D3E9042392197B41D0BC01F007BF436D54 +:10274800002BCAD01846D3E9002392197B41E8E749 +:1027580038B504460C4B806D236018B10AF002FEB0 +:102768000023A365236D04F118054BB1284606F034 +:1027780063F8064B2846A36006F05EF8204638BD8D +:10278800636D002BF2D1F4E7200600201405002029 +:1027980038B504460E4B806D236018B10AF0E2FD8F +:1027A8000023A365236D04F118056BB1284606F0D4 +:1027B80043F8084B2846A36006F03EF820465C2103 +:1027C8000AF00AFB204638BD636D002BEED1F0E716 +:1027D800200600201405002070B5254B0546046925 +:1027E80003601CB16668013E66600EB1284670BD84 +:1027F8002368204ADB6A93422CD1A06D10B10AF0FD +:10280800B1FDA665236D5BB304F1180006F014F85A +:102818002C69002CEAD02368174A5B6893421CD1C4 +:10282800164BA06D236018B10AF09CFD0023A36528 +:10283800236D04F11806BBB1304605F0FDFF104BBF +:102848003046A36005F0F8FF20465C210AF0C4FA80 +:10285800284670BD20469847DAE720469847C5E7DE +:10286800636D002BD0D1D3E7636D002BE4D1E6E78D +:10287800D005002099000000510800002006002023 +:102888001405002070B5294B0446056903601DB185 +:102898006E68013E6E602EB1204614210AF09CFA43 +:1028A800204670BD2B68224ADB6A934230D1A86D5E +:1028B80010B10AF057FDAE652B6D7BB305F118001A +:1028C80005F0BAFF2569002DE6D02B68194A5B6828 +:1028D800934220D1184BA86D2B6018B10AF042FD25 +:1028E8000023AB652B6D05F11806DBB1304605F00A +:1028F800A3FF124B3046AB6005F09EFF28465C21D3 +:102908000AF06AFA204614210AF066FA204670BDD9 +:1029180028469847D6E728469847BDE76B6D002BB1 +:10292800CCD1CFE76B6D002BE0D1E2E7D0050020DA +:10293800990000005108000020060020140500201E +:1029480038B5044608460D460BF07AF82368024667 +:10295800294620465B689847054620460AF056F9FE +:10296800284438BD2DE9F04395B000236E4A6846E7 +:102978006E4906F05BF8129B002B00F0BC805C20CF +:1029880000240AF027FA9DF804200546684B694997 +:1029980004AE2A731830029AAB609DF80C30296097 +:1029A80031462A612B756C6005F004FF6B68624A3A +:1029B8000133AC65AA606B60DFF89C913046002457 +:1029C8005E4FCDF8009005F037FF0D215C480AF006 +:1029D8000DF85C482646DFF884810AF017F919E0FB +:1029E8002B689B6843454FD1286D002843D00422AB +:1029F800694603F055FF0098A212C4F30903A4EB3B +:102A0800822157F8222042F8210043B10134B4F55D +:102A1800803F0CD00096002DE2D12846ECE7013427 +:102A28000121494809F0E2FFB4F5803FF2D1ADB188 +:102A38002B68464EDB6AB3425AD1A86D18B10AF02A +:102A480091FC0023AB652B6D002B5AD005F11800C3 +:102A580005F0F2FE6C68013C6C60DCB10A2008F0FD +:102A6800A3FD10213A4809F0C1FF36480AF0CEF814 +:102A780015B0BDE8F083686D0028BDD00422694612 +:102A880001F074FC0098B7E7042269462846984785 +:102A98000098B1E72B68DB6AB34236D1A86D10B154 +:102AA8000AF060FCAC652B6D002B34D005F11800E2 +:102AB80005F0C2FE2B68274A5B68934228D11D4B5C +:102AC800A86D2B6018B10AF04DFC0023AB652B6D87 +:102AD80005F118041BB3204605F0AEFEC5F80890B2 +:102AE800204605F0A9FE28465C210AF075F9B5E7ED +:102AF80028469847AEE7139D002D7FF440AF04AEFB +:102B08005AE76B6D002BA1D1A4E728469847D1E777 +:102B180028469847A2E76B6D002BC7D1CAE76B6DB3 +:102B2800002BD8D1DAE700BFBC0A0020681C0020BF +:102B38007C06002020060020FC05002098260020A6 +:102B4800C40A0020BC110020D40A0020990000000B +:102B5800D80A0020510800001405002021040000B4 +:102B68000D4B002103F1800243F8041F9342FBD16F +:102B78000A4B002010B403F50071094C43F8040F08 +:102B88008B424FF00002F9D10649074B22600A60D8 +:102B98001A605DF8044B7047FC250020FC210020DA +:102BA80094260020A0270020E82700202DE9F047E0 +:102BB80096B00023824A02A8824905F037FF149B89 +:102BC800002B00F0D4805C2000260AF003F97E4A2E +:102BD80005469DF80C709DF8143006A97B4C1830FA +:102BE8002A60049A2F73AC602A612B756E6005F019 +:102BF800E1FD6B68764A06A80133DFF8E8A1AA6010 +:102C08006B60AE65CDF808A005F016FE7148724AF3 +:102C18000368296803F1FF3E9C1E0F6A52F82E10C4 +:102C2800DFF8C4E109030460774552F823400A46F7 +:102C38004FEAE17340F0AE80286D002800F08D80E7 +:102C4800012B08BF002A01D204F04EF8DFF89C815E +:102C58000027DFF89C9104F5806619E02B689B68D3 +:102C68004B4523D1286DC0B1042202A903F018FEF8 +:102C78000298002C2346B8BF04F2FF339B12A4EB42 +:102C88008322013458F82330A64243F8220013D097 +:102C98000297002DE2D12846EBE7686D0028E8D0BE +:102CA800042202A901F062FB0298E2E7042202A9C9 +:102CB800284698470298DCE7ADB12B68474EDB6A97 +:102CC800B34251D1A86D18B10AF04CFB0023AB6593 +:102CD8002B6D002B62D005F1180005F0ADFD6C6876 +:102CE800013C6C602CB10A2008F05EFC16B0BDE80F +:102CF800F0872B68DB6AB34254D1A86D10B10AF093 +:102D080031FBAC652B6D002B52D005F1180005F096 +:102D180093FD2B68324A5B68934246D12A4BA86DD3 +:102D28002B6018B10AF01EFB0023AB652B6D05F173 +:102D38001804002B40D0204605F07EFDC5F808A0F9 +:102D4800204605F079FD28465C210AF045F80A205E +:102D580008F02AFC16B0BDE8F087686D00283FF43B +:102D680075AF01F0F3FB71E728469847B7E7159D63 +:102D7800002D7FF428AFDFF86CA006A8CDF808A0D6 +:102D880005F05AFD134B14481A68911E50F822405A +:102D980019605BE700962846B84757E76B6D002B2C +:102DA80099D19CE728469847B3E7284698479AE779 +:102DB8006B6D002BA9D1ACE76B6D002BBBD1BDE7C8 +:102DC800EC0A0020681C0020200600207C06002059 +:102DD800FC050020E82700200026002099000000BC +:102DE80051080000140500208907000098260020DB +:102DF800210400002DE9F04397B044F20223824AEF +:102E080002A8824905F012FE149B002B00F0D28024 +:102E18005C20002609F0DEFF7D4A05469DF80C700F +:102E28009DF8143006A97B4C18302A60049A2F7339 +:102E3800AC602A612B756E6005F0BCFC6B68764A45 +:102E480006A80133DFF8E891AA606B60AE65CDF89B +:102E5800089005F0F1FC7148714A0368296803F18C +:102E6800FF3E9C1E0F6A52F82E10DFF8C8E10903D6 +:102E78000460774552F823400A464FEAE17340F070 +:102E8800AC80286D002800F08B80012B08BF002A39 +:102E980001D203F029FF634F04F58066DFF89881BB +:102EA80004E004F0E9F80134A64223D0002C2346BC +:102EB800B8BF04F2FF339B12A4EB832257F82330E8 +:102EC80053F822300293002DEDD02B68042202A97A +:102ED800DB6843452BD12B6D1846002BE1D16B6D78 +:102EE800042202A91846002BDDD0013402F060FA52 +:102EF800A642DBD1ADB12B684B4EDB6AB34256D14B +:102F0800A86D18B10AF02EFA0023AB652B6D002BC3 +:102F180067D005F1180005F08FFC6C68013C6C6007 +:102F280054B10A2008F040FB17B0BDE8F083042232 +:102F380002A928469847B6E72B68DB6AB34254D102 +:102F4800A86D10B10AF00EFAAC652B6D002B52D0AB +:102F580005F1180005F070FC2B68344A5B68934251 +:102F680046D12B4BA86D2B6018B10AF0FBF9002352 +:102F7800AB652B6D05F11804002B40D0204605F0F9 +:102F88005BFCC5F80890204605F056FC28465C21F5 +:102F980009F022FF0A2008F007FB17B0BDE8F0830C +:102FA800686D00283FF477AF01F0D0FA73E7284640 +:102FB8009847B2E7159D002D7FF42AAFDFF870908F +:102FC80006A8CDF8089005F037FC144B14481A6889 +:102FD800911E50F8224019605DE700962846B847D0 +:102FE80059E76B6D002B94D197E728469847B3E7CC +:102FF8002846984795E76B6D002BA9D1ACE76B6D18 +:10300800002BBBD1BDE700BFEC0A0020681C0020E4 +:10301800200600207C060020FC050020E827002070 +:103028000026002098260020990000005108000082 +:103038001405002089070000B9050000F8B5584CB0 +:10304800584D226855F82230511E013B2160182B3B +:1030580015D8DFE803F0151E27331414141414458B +:103068004D6114141414141414777F878F970D006E +:1030780008F08CF82368013345F823002360F8BD75 +:10308800023A15F8210001212260BDE8F84008F055 +:1030980057BB023A15F8210000212260BDE8F8402C +:1030A80008F04EBB931E55F82110033A15F823007B +:1030B800C9B22260BDE8F84008F04EBB023A15F8E4 +:1030C8002100374D226008F041FB364A2B68002862 +:1030D80060D001334FF0FF312B6042F82310F8BD68 +:1030E800023A55F821002260BDE8F84008F05CBAC1 +:1030F8002D4B023A2D4F22601C4618682C4E3A6818 +:1031080055F82130A6FB0212920C03FB02F2236849 +:103118001B1A9A42FBD8F8BD234B023A234E226071 +:103128001C461868336855F821101B0C214A01FB0E +:1031380003F35B08A2FB0332120A23681B1A9A42A4 +:10314800FBD8F8BD07F0D2FF2368013345F8230008 +:103158002360F8BD07F0DAFF2368013345F8230040 +:103168002360F8BD07F0E2FF2368013345F8230028 +:103178002360F8BD07F0EAFF2368013345F8230010 +:103188002360F8BD07F0F2FF2368013345F82300F8 +:103198002360F8BD01332B6042F82300F8BD00BF5F +:1031A800E827002000260020041000E06811002015 +:1031B80083DE1B43112397082DE9F043612283B076 +:1031C800002301388DF804208DF805301C2836D8E6 +:1031D800DFE810F02C02220219020C02FD01EE01B8 +:1031E800E301D001B701A60190017F016F015E01E3 +:1031F8004D0138011F0112010501F700E600D90051 +:10320800CC00BF00B200A500680038001D00BE4D0C +:10321800BE4E2A6856F82230511E032B296000F052 +:10322800678240F31C82062B00F05D8240F35382D4 +:10323800072B00F06382642B01D1FFF7FFFE03B078 +:10324800BDE8F083B049B14A0B68DD1E5C1E981ECC +:1032580052F823600D6052F8247052F82030002E86 +:10326800EDD01E44FF1AAA4CFA18002B1846B8BF16 +:1032780003F2FF30002A11464FEAA020B8BF02F23D +:10328800FF31A3EB802554F820008912013350F850 +:103298002500A2EB8122B34254F8211041F8220004 +:1032A800E2D1CCE7984D994E2B68D81EA3F10208BD +:1032B800591E56F82320286056F8213056F8280061 +:1032C800002A00F0248202EB030EC3EB000C4FF03F +:1032D800FF378F4C0CEB0302002B1846B8BF03F2E4 +:1032E800FF30002A1146B8BF02F2FF31801289125E +:1032F800A3EB802954F82000A2EB812254F8211076 +:10330800013350F8290051F82220824218BF0027C3 +:103318007345DFD1C5F8008046F828708FE77A48F2 +:103328007A4B01684A1E53F8214053F82210026074 +:10333800214143F8221082E77348744B01684A1E02 +:1033480053F8214053F822100260A14043F822109C +:1033580075E76D486D4B01684A1E53F8214053F8D4 +:1033680022100260614043F8221068E76648674B04 +:1033780001684A1E53F8214053F822100260214385 +:1033880043F822105BE76048604B01684A1E53F817 +:10339800214053F822100260214043F822104EE7E2 +:1033A800594A5A4B1168481E53F8212053F82050A7 +:1033B80095FBF2F402FB145243F8214043F8202015 +:1033C8003DE75148514B01684A1E53F8211053F804 +:1033D8002240026001FB04F143F822102FE74A481B +:1033E8004A4B01684A1E53F8214053F822100260E4 +:1033F800091B43F8221022E74348444B01684A1E40 +:1034080053F8211053F822400260214443F8221057 +:1034180015E73D4D3D482A6850F82230511E002BD3 +:103428001A4650F82110B8BF03F2FF3238489212FA +:10343800A3EB822350F8222042F823102B68023B8A +:103448002B60FCE6304B314E1968314856F8213074 +:10345800002B1A46B8BF03F2FF329212A3EB822365 +:1034680050F8222052F8233046F82130E7E6264863 +:10347800264B01684A1E53F8214053F82210026077 +:10348800A1424FF0FF31D8BF002143F82210D6E601 +:103498001D481E4B01684A1E53F8214053F822105C +:1034A8000260A1424FF0FF31A8BF002143F822106B +:1034B800C5E61548154B01684A1E53F8214053F8D4 +:1034C80022100260091B18BF4FF0FF3143F8221089 +:1034D800B5E60D480D4B01684A1E53F8214053F8D4 +:1034E80022100260A1424FF0FF3118BF002143F8BB +:1034F8002210A4E6074B084C1A680849501E54F8D5 +:10350800222018600A609AE6E8270020002600209A +:1035180098260020A02700200022002094260020C2 +:103528007C4A7D4913685C1E981E51F8233051F877 +:103538002410106000293FF482AE013B774A1360E3 +:103548007DE6744A744913685C1E981E51F823304E +:1035580051F82410106000293FF471AE7049013B06 +:103568006E480A68056801326E4C03600A6044F8C8 +:10357800225064E6674D684A2B68694852F8231060 +:103588005A1E664C0368013927680133654E2A6064 +:103598002160036046F8237051E65E495E4A0B6875 +:1035A8005E4852F82320013B013A0B60026046E670 +:1035B8005B49584A086813685A4C451E013354F849 +:1035C800204055480D60136040F8234037E65449C1 +:1035D800504A0B681068504E0133451E514C56F83E +:1035E80020000B60156044F8230028E6494A4A4B3E +:1035F8001268511E53F8220053F8214043F8224024 +:1036080043F821001BE6434B002443481A68511E27 +:1036180040F82240196012E63E493F4B0868421CB8 +:1036280053F820000A6043F8220008E63B4A3E4867 +:1036380011684B1C002B13601A46B8BF01F5806255 +:1036480034499212A3EB822350F822000A6850F8FA +:103658002300531C304A0B6042F82300EFE5012B8E +:1036680021D048DC002B7FF4EAAD56F8213002ACBB +:10367800023A04F8043D20462A600AF0E1F90146BE +:10368800204609F0B3F99DF804300A2B7FF4D7AD32 +:103698000D2320468DF804300AF0D2F90146204661 +:1036A80009F0A4F9CBE509F07BF9041EFBDD02AFB4 +:1036B80007F8044D38460AF0C3F90146384609F0C0 +:1036C80095F92B680D2C03F1010308BF0A242B6020 +:1036D80046F82340B3E5052B7FF4B1AD0F4B4FF00F +:1036E800FF321A60ABE50D4B4FF480321A60A6E545 +:1036F800FFF780FBA3E5FFF759FAA0E50848531C3C +:1037080046F8221002682B6046F8232097E54FF010 +:10371800FF37FFE5E8270020002600209426002038 +:10372800A0270020002200209826002070B5002243 +:103738001A4E1B4D134632600DE0C4F30720F8B94A +:10374800C4F3074010BB200E24D133680133B3F50E +:10375800803F336021DA002B1A46B8BF03F2FF32EC +:103768009212A3EB822355F8222052F8234014F03A +:10377800FF00E2D0FFF720FDC4F307200028DFD0C8 +:10378800FFF71AFDC4F307400028DCD0FFF714FD4B +:10379800200EDAD0FFF710FDD7E770BD9426002081 +:1037A800982600202DE9F043584D8FB040F2EE29BD +:1037B800574C2E68DFF89881564F04E0B3F5FA6F3E +:1037C80015D809F01FFB09F01DFB237843B198F8C1 +:1037D8000030DB0704D52B683A689B1A0E2B06D8F5 +:1037E8002B6822789B1B002AE8D14B45E9D94A4C23 +:1037F80013214A4809F0FAF8494804F5807509F098 +:1038080005FA4FF4805009F0A5FD44F8040FAC42C6 +:10381800F7D11521434809F0E9F8414809F0F6F9CC +:10382800414B0121414E187807F096FF1621404878 +:1038380009F0DCF83A4809F0E9F93046FE2100F0D1 +:103848002BFC38B93B213B4809F0D0F8344809F043 +:10385800DDF9FEE71621384809F0C8F8304809F0C4 +:10386800D5F9D6F884444CB300272146334A684634 +:103878003B466D468DF800708DF801708DF802702A +:1038880002F0E4FFA8B12E492548FFF759F8D6F809 +:103898008444264B1CB3002621462846294A334631 +:1038A8008DF800608DF801608DF8026002F0CEFF9F +:1038B80023E025491A48FFF743F8FEE7D6F88814AD +:1038C8000029F6D023461D4A68466D468DF83140DA +:1038D8008DF832408DF8334001F016F9D2E7D3F86D +:1038E800881471B128462346164A8DF831408DF860 +:1038F80032408DF8334001F007F910B10FB0BDE840 +:10390800F08312490648FFF71BF8FEE7F02700206E +:10391800152800207C28002094260020F40A002086 +:10392800BC110020080B0020FC150020641C00209E +:10393800200B0020380B0020740B0020BC0A00204C +:10394800BC0B0020EC0A00208C0B0020D40B0020BC +:103958001428002008B5FFF703F9FFF703F8BDE8BE +:103968000840FFF7E3BE00BF2DE9F843DDF82080EB +:10397800099FB3B116460C46054603EB010904E05E +:1039880020460134C0474C450BD02B6832462146AF +:1039980028461B6998473A4631460028F0D1BDE8C9 +:1039A800F8830120BDE8F8832DE9F843DDF820808D +:1039B800AAB11F460C46054602EB010901E04C4539 +:1039C8000DD02B68414620465E6AB847214602461C +:1039D80028460134B0470028F1D1BDE8F88301201A +:1039E800BDE8F8830020704700207047002070472A +:1039F8004FF0FF30704700BF704700BF30B583B04D +:103A080005460C4607F0E8FE1C4B984204D80023F4 +:103A18002B80238003B030BD694609F007F99DF873 +:103A280005309DF8062001339DF80410503ADBB2AA +:103A380092B20C2B98BF1F291CD87F2A1AD841EAAA +:103A4800431343EA422292B29DF802009DF8011006 +:103A58002A80172898BF3B299DF800300CD83B2BAB +:103A68000AD8490141EAC02141EA53039BB22380A5 +:103A780003B030BD0022E7E70023F8E7FFA5CE1228 +:103A8800012BF0B5054695B03BD0022B01F104019E +:103A980040F20223684618BF002304F0C7FF129BB8 +:103AA800002B37D05C2004AF09F094F99DF804206E +:103AB80004461F4B0026DFF888E022733946029A35 +:103AC8001830A3609DF80C3022612375C4F800E01B +:103AD800666004F06FFE63684FF47A71154801332D +:103AE800154AA6652E712E732C61A0606360A960CB +:103AF8002A60124B3846009304F09EFE284615B003 +:103B0800F0BD44F202230431684604F08FFF129B93 +:103B1800002BC7D1139B002BC4D14FF47A71064AEE +:103B28002B7104AF2B732B61A9602A60E1E700BFFA +:103B38007C060020FC050020D0050020140500208C +:103B48002006002070B5D0F884448EB01646C4B163 +:103B5800002504F589640A46684621462B468DF8F7 +:103B680000508DF801508DF8025002F009FE08B996 +:103B78000EB070BD32462146684602F095FF0EB081 +:103B880070BDD0F888040028F2D000F589650A468F +:103B98002346684629468DF831408DF832408DF825 +:103BA800334000F033FF0028E2D032462946684609 +:103BB80001F066FA0EB070BD30B5D0F884448FB00D +:103BC800A4B100250A466846214601238DF8005015 +:103BD8008DF801508DF8025002F038FE08B90FB088 +:103BE80030BD684603F0FEFE0FB030BDD0F8880443 +:103BF8000028F4D00A460123014668468DF8314072 +:103C08008DF832408DF8334000F07EFF0028E6D072 +:103C1800684600F0E3FF0FB030BD00BF30B5D0F804 +:103C280084448FB0A4B100250A46684621462B4635 +:103C38008DF800508DF801508DF8025002F006FE04 +:103C480008B90FB030BD684603F020F80FB030BD9A +:103C5800D0F888040028F4D00A462346014668466E +:103C68008DF831408DF832408DF8334000F04CFF2C +:103C78000028E6D0684601F011F80FB030BD00BF4B +:103C880030B5D0F884448FB07CB100250A460123B2 +:103C980004F5896168468DF800508DF801508DF85B +:103CA800025002F005FD0FB030BDD0F8880400289E +:103CB800F9D00A46012300F5896168468DF831403C +:103CC8008DF832408DF8334001F06EF90FB030BDF9 +:103CD80030B5D0F884448FB074B100250A466846E0 +:103CE80021462B468DF800508DF801508DF8025072 +:103CF80002F0ACFD0FB030BDD0F888040028F9D030 +:103D08000A462346014668468DF831408DF8324010 +:103D18008DF8334000F0F8FE0FB030BDF8B590F8DC +:103D2800D034002B46D0D0F884240446002A46D04C +:103D3800D369D0F890045F1E00283ED00368DB6B7F +:103D4800984730B1D4F8900430B303681B6C984797 +:103D5800A0B1D4F884240026002A4AD0104604F0E2 +:103D680033FC05463EB1D4F89004A8B1036800219D +:103D78005B6C984780B1D4F8842410E0D4F89004A0 +:103D880050B1036801215B6C984728B1D4F88424AA +:103D98000126002AE2D12CE00025D4F884247B1BDC +:103DA800F2B190794FF4007202FA00F080B2A0FBF1 +:103DB8000301F8BD00200021F8BD0646CEE7D0F883 +:103DC8008834F3B1D3F83074D4F890040028B5D10E +:103DD8001946A3B10646084602F0CAF90546C1E7E6 +:103DE800D4F88824002AE5D0D2F83C04A3FB0001CB +:103DF800F8BDD4F888140029EDD11546B2E71D4660 +:103E0800CDE71F46E0E700BF90F8D03463B1D0F8A3 +:103E1800842462B191794FF40073D0698B400138E2 +:103E28009BB2A3FB00017047002000217047D0F827 +:103E38008824002AF8D0D2F83034D2F83C04A3FB06 +:103E4800000170472DE9F041D0F8905492B04DB17F +:103E58001F462B6804462846DB699847B0F5405F43 +:103E6800064603D8002012B0BDE8F0814FF4007078 +:103E780009F070FA80460028F4D0B6F1806F07AEDA +:103E880002463B462946304644D804F089F807469E +:103E9800404609F067FA002FE4D02B6828461B6AD1 +:103EA800984794F8C054FF2D38D094F8C18401AADB +:103EB800D4F8C4C404ABD4F8C8E404F594678DF806 +:103EC80004508DF80580CDF808C0CDF80CE007CA7D +:103ED80083E807008DF81180CDF814C0CDF818E0FC +:103EE8008DF8105093E8070086E80700384696E8F2 +:103EF8000E0005F0A9FA94F8B134C4F890742BB9FF +:103F080001233946201D1A4604F01CFD012012B079 +:103F1800BDE8F08101F024FC0746B9E704F29443B8 +:103F280084F8C05494F8CC141D46184605F0E4FFF4 +:103F3800C4F89054284605F05FFB0028E6D1012319 +:103F4800D4F89014201D1A4604F0FCFCDEE700BFEC +:103F58002DE9F041D0F890648AB00446002E48D08C +:103F680090F8D034002B4AD190F8D134FE2B5AD097 +:103F780090F8D204362835D994F8C064FF2E71D051 +:103F880094F8C18403ADD4F8C4C406ABD4F8C8E42B +:103F980004F594678DF800608DF80180CDF804C0B1 +:103FA800CDF808E09DE8070085E807008DF80D804A +:103FB800CDF810C0CDF814E08DF80C6095E8070036 +:103FC80083E8070038460ECB05F03EFA94F8B13482 +:103FD800C4F890746BB901233946201D1A4604F0C1 +:103FE800B1FC07E007F0B2FB003018BF0120002841 +:103FF800C2D1002084F8D0040AB0BDE8F08190F85E +:10400800D134FE2B16D094F8D204362805D807F000 +:104018009DFB003018BF0120ECE73368304606A945 +:104028009B6C9847E6E71B4B9868C0F34040002814 +:10403800DFD0A1E7336830465B6D9847431C0546DF +:10404800E1D048B994F8D134FE2BD2D12E200321E7 +:1040580007F082FB2846CDE7012084F8D0040AB097 +:10406800BDE8F08104F2944594F8CC1484F8C06457 +:10407800284605F041FFC4F89054284605F0BCFADC +:104088000028B6D10123D4F89014201D1A4604F054 +:1040980059FCAFE7008000422DE9F0410E46044686 +:1040A8008AB03C4806F0A4FBFE2E84F8D16439D0CF +:1040B800362E03D900200AB0BDE8F0810025DFF8CC +:1040C800D8E001AA8DF804608DF8055004AF039577 +:1040D80007ABCDF808E004F5946884F8C06484F868 +:1040E800C154C4F8C854C4F8C4E407CA87E8070030 +:1040F8008DF81150CDF814E006958DF8106097E80A +:10410800070083E8070040460ECB05F09DF994F8B8 +:10411800B134C4F890842BB3284684F8D0040AB08C +:10412800BDE8F081002304F29445FF22194684F883 +:10413800CC3484F8C024284605F0DEFEC4F8905438 +:10414800284605F059FAA0B12E2300250321184668 +:1041580084F8D05484F8D23407F0FEFA28460AB01E +:10416800BDE8F08101234146201D1A4604F0EAFB10 +:10417800D3E70123D4F89014201D1A4604F0E2FB7B +:104188000028E1D001222E2384F8D02484F8D234E8 +:1041980091E700BFBD1A000040787D01F0B4184BCC +:1041A8000024184EFF25072117482927174AC3F866 +:1041B8009464174E18601846C3F8A824C3F8AC14C2 +:1041C80083F8B174C3F8A064C3F88444C3F888447E +:1041D800C3F8904483F89C4483F89D4483F8B5441D +:1041E80083F8BC4483F8CC4483F8D04483F8D15492 +:1041F80083F8D254074A0849F0BC09F071B800BFE7 +:10420800641C0020D0060020A006002000093D0004 +:104218003805002060110020B91A0000F0B500F13F +:10422800240385B005460E4601AC174693E80700FF +:1042380084E8070072012146286A01F025FF012859 +:1042480006D13A462146286A01F0E2FE05B0F0BDE3 +:10425800002005B0F0BD00BF10B5044600F0F4FD25 +:10426800002384F8313084F8333010BD38B50D465A +:10427800144600F124010022006A01F0C9FE034639 +:1042880028B1428901202A801B89238038BD38BD86 +:1042980038B50D46144600F124010022006A01F0E9 +:1042A800B7FE034628B1C28901202A809B89238052 +:1042B80038BD38BD90F831200AB10020704738B5B4 +:1042C8000D4611463822044609F03EFB40230120E2 +:1042D800256284F8313084F8330038BDF0B40C78A6 +:1042E800202C03D111F8014F202CFBD00E461E4F75 +:1042F800116091603578344601362F2D18BF002D96 +:1043080022D0A5F122041F2DE4B28CBF0021012187 +:104318001D2C0ED90124A14213D205F0BF013C295E +:104328000FD05C2D0DD02E2DE4D0202DE2D096603C +:10433800E0E727FA04F404F0010484F00104A14240 +:10434800EBD30020F0BC7047202D01D02F2D05D1D4 +:1043580014F8011F2029FBD02F29F9D01C60114621 +:10436800F0BC01F05BBD00BF010100312DE9F04F49 +:1043780090F8333083B00546DE0760D55C060E46FC +:10438800914640F1BD80D5E90001D5E9042310EB41 +:10439800090A41F1000B5B4508BF5245C0F0B680E1 +:1043A800B9F1000F74D0AA464C4640F2FF17FAE85C +:1043B80006012B6AD3F8382402EA0008C8F3080B70 +:1043C800B8F1000F6AD150EA010279D195F831208D +:1043D80051064CBFD3F83414E969A9614FEA582053 +:1043E8000239D3F82C24BC4293F845E4024401FA7C +:1043F8000EF111442ED9BBF1000F2BD1D3F81C229A +:10440800914227D0B4F5806F61D34FF0010C4FEA89 +:1044180054280CFA0EFEC0EB0E00804528BF8046DB +:1044280091423DD801EB0800824239D203F504706D +:104438000191009306F0CAF9009B019980BB95F899 +:1044480032304FF0FF3043F0020385F8323003B0CA +:10445800BDE8F08F03F50470002206F087F9002804 +:10446800EDD0CBF5007800EB0B013046A04528BF16 +:10447800A046424606F09CFE404600214644D5E947 +:10448800002380185941B4EB0804C5E9000190D114 +:104498000024C4EB090003B0BDE8F08FA9699DE7CB +:1044A800D3F8140232464346D0F800E0DEF814B0E0 +:1044B800D8470028C3D04FEA482800214046DDE706 +:1044C80095F83320520610D5A969013185E7D3F84C +:1044D8001402324603681B6998470028AFD04FF48E +:1044E800007000214FF40078C8E718465246A969C1 +:1044F80001F0AAFD0028A2DB0BD02B6AA9696DE7A1 +:1045080090F8313018073FF53EAF49E7C0EB020994 +:1045180046E795F8313013F0500FBAD18FE700BF56 +:10452800F0B583B00122044685690DF10701D0E991 +:104538000067FFF71BFF0128A5610CBF9DF8070066 +:104548004FF0FF30C4E9006703B0F0BD2DE9F04F2C +:1045580090F831E085B004468569BEF1000F36D089 +:1045680016461F46D0E90001994208BF904265D01F +:1045780056EA070330D10023A3610120C4E900678C +:1045880005B0BDE8F08F10F1FF3241F1FF3322FA98 +:104598000CFC03FA08F823FA0AFA50EA01034CEA79 +:1045A800080C4CEA0A0C4BD0E34549D3CCEB0B0B77 +:1045B800A94604F118085D464246002DDDD0A169E0 +:1045C800013D206A01F040FD0028F5DC4D46002041 +:1045D800A56105B0BDE8F08F1EF0080F27D1236A4A +:1045E80016F1FF3893F845C447F1FF39C2460393E3 +:1045F8000CF1090CCB4694F833905FFA8CFC19F057 +:10460800400FCCF120082AFA0CF2CDE900AB019B4F +:10461800ACF1200A03FA08FB23FA0AF342EA0B0278 +:1046280042EA030BAFD0E3695B44A361A5E7D4E991 +:104638000423BB4208BFB242C9D3D0E70120C8E770 +:104648001EF0400F02D1E369A361B1E7039BD3F8E1 +:104658003434F9E72DE9F04F8FB08146019390F893 +:1046680031302BB991F831300C4613F0500F08D186 +:104678000023184689F8313089F833300FB0BDE887 +:10468800F08F019B154603F00303012B06D0022B84 +:1046980000F0FF80002BEBD1012200E00222019BF9 +:1046A80003F0080313430293002D40F0DD80032735 +:1046B8000026029BB34643F040030393202206A939 +:1046C8002046FFF753FEF0B12028D1D19DF81830CD +:1046D800180645D4BBF1000F04D12268D4F818A0FD +:1046E800A2F12008BB4503D20BF1010B5FFA8BFB4B +:1046F800002B00F0D080202206A920460026FFF7D4 +:1047080035FE0028E0D1019B9905B1D5029B9A0797 +:10471800AED5002DACD0BB4580F0C6802B465E469A +:1047280055469A460AE02028A2D11EB92268A569F2 +:10473800A2F12008DEB2B74240F2B380202206A9D7 +:104748002046FFF713FE731C0028ECD12046D4F84E +:1047580018B000F0A9FB00288AD0C4F818B0EAE71E +:1047680056BBBB4538BF4FF0000B852BA6D1314651 +:1047780038224846012609F0E7F89DF81C309DF8D4 +:104788001920D90689F8302003F0370258BF42F0C3 +:10479800080289F831202368226AA169203BC9F8F8 +:1047A8002020C9F82830C9F8241094F83330C3F30E +:1047B800801389F82C3081E7C02B29D0C12B9AD1DE +:1047C8002A4606A9484601F09DFA002867D0AB8919 +:1047D800002B7FF473AFAA686B689A427FF46EAFC0 +:1047E800019B1F053FF544AF019B13F4884F40F030 +:1047F800AB8099F833309E0700F1A680019B5B05DA +:104808003FF536AF019B580400F1BC80012035E725 +:104818009DF819309DF808209B0789F8332003D5A7 +:104828009DF80C3089F833300B99DDE90823C9F875 +:104838001C10DDE90C01C9E90423C9E90201002DB6 +:10484800CED09DF81B304FF000002A6929689A42A3 +:10485800A88169607FF44FAFBDF81C60AB8AF61A77 +:10486800B6FA86F6760929E72B69664F0E33A7FB59 +:104878000337D4E90023FF08134307F10207FFB207 +:104888003FF416AF002100220023A161C4E90023F0 +:104898000EE7032203E7002D7FF435AFE8E606466E +:1048A8000CE75346AA461D4694F833B03822002137 +:1048B800484609F049F8CBF3801B0823226A0026F2 +:1048C80089F82CB0C9F824A0C9F8288089F83130B3 +:1048D8002B68C9F820206B60AE818FB307F1FF38D1 +:1048E80034465FFA88F8012221464846FFF796FCCD +:1048F800834600283FF4BCAE90F90030002BFFF649 +:10490800B7AE2022002109F01FF8002E43D0012C59 +:104918005ED0C1235C460BF11E0A8BF80030AB89D0 +:1049280028461BB96A68AB689A4205D005F06CFF47 +:1049380024F8020FA245F2D10136F4B2BC42D2D318 +:10494800484600F081FA99E699F8313013F0110FD2 +:104958007FF48EAE019B5D057FF554AF99F8333037 +:104968009C077FF585AE002200234846FFF7EEFD41 +:1049780000283FF47DAE484600F0A8FC00283FF42C +:1049880077AE43E74846D9E90423FFF7DFFD00285F +:104998007FF43CAF6CE685238BF800301A4B89F81E +:1049A80030808BF801801B681BB30DF113020DF1E9 +:1049B800160105A89847BDF81410BDF816209DF8F3 +:1049C8001330ABF80A10ABF808208BF81430B3E7B3 +:1049D800029BC0228BF8014063F07F038BF8002014 +:1049E80089F833302B698BF80330AB8AABF8043085 +:1049F800A2E745F22163ABF80A30ABF80E30ABF80A +:104A0800123099E789888888882100202DE9F043A9 +:104A1800064697B000200D4696F8311001928DF8A1 +:104A280051008DF852008DF85300ADF8140029B9E3 +:104A3800994695F8313013F0500F03D1002017B084 +:104A4800BDE8F083137814462F2B32D04FF00008BE +:104A5800214601AB02AA3046FFF740FC0028EDD002 +:104A6800019B1B78002B39D02946002302AA304627 +:104A7800FFF7F0FD0028E1D0344608AF06F1300E0C +:104A88002068103454F80C1C3D4654F8082C103794 +:104A980054F8043C74450FC5F2D1206808AD38605D +:104AA800304600F0D1F986F8318086F83380019CD1 +:104AB800CEE70134019421782F29FAD0B9B108A89A +:104AC800382200212F6A054608F03EFF40220123C4 +:104AD80010978DF851208DF85330B7E74B4602AA4E +:104AE80029463046FFF7B6FD17B0BDE8F0833822F7 +:104AF80030462C6A08F028FF40230120346286F8EB +:104B0800313086F833009AE719B101F58961FFF76A +:104B18007DBF0846704700BFF0B490F8314024B913 +:104B280091F8313013F0500F02D10020F0BC7047DB +:104B3800D1E90067002706F01F0656EA0703F4D1FB +:104B480013462246F0BCFFF785BD00BF8169F8B562 +:104B58000446006A01B10131012201F0A9F90128D6 +:104B680006462ED901230146206A1A4601F0FAF9B1 +:104B7800074630B3A3693BB394F83320510612D5E6 +:104B8800591C8E4226D022F04002E16984F8332075 +:104B980005E0206A01F09CFA294690B1A3694D1CF2 +:104BA80099422A46F5D34FF0FF323146206A01F088 +:104BB8008FFA30B1A16969B13246206A01F088FAEA +:104BC80040B900273846F8BD94F8333043F0400325 +:104BD80084F83330A6613846F8BD00BF90F833300A +:104BE8009A073BD5C1692DE9F0410546A9B90024CA +:104BF80008E00378E4B203F07F03037095F83030DF +:104C0800A3422DD32146012228460134FFF706FB93 +:104C18000028EED10020BDE8F0815B06006A37D598 +:104C280090F845240023D5E90267093216F1FF36CA +:104C3800D2B247F1FF37C2F1200EA2F1200426FAC2 +:104C480002F207FA0EFE27FA04F442EA0E022243A1 +:104C5800013201F087F90028C9D1DBE7002070474D +:104C680000232C6A85F83130204685F8333005F06A +:104C7800ADFD0028CED004F5047005F0A7FD00288E +:104C8800C8D0D4F840040368BDE8F0411B6A18474F +:104C980001F030FA0028AAD1BCE700BF90F8313003 +:104CA800D90601D40020704710B5002288B000232F +:104CB8000446FFF74BFC06E0202819D19DF8003088 +:104CC8001A0615D433B1202269462046FFF74EFB59 +:104CD8000028F1D194F833300822204643F002032B +:104CE80084F8312084F83330FFF778FF08B010BD1E +:104CF800002008B010BD00BF2DE9F043002583B0A7 +:104D08000746DFF84091A846002229463846FFF7B3 +:104D180085FA044630B10378C02B74D0C12B2CD04F +:104D2800852B09D097F83230002043F0010387F82B +:104D3800323003B0BDE8F08397F83130D9F800601D +:104D480003F03703838086B10DF103020DF10601EC +:104D580001A8B047BDF80620BDF804309DF803103F +:104D6800A28161752282E38163823A6A92F81032E5 +:104D780043F0010382F8103223784FEAC830A3F1D8 +:104D880085060022012140EA5808B6FA86F613FA89 +:104D980088F376091FFA83F80A444FEAC8330321D7 +:104DA8001F2A43EA58030AD8A05C012A10FA83F3A1 +:104DB8001FFA83F801D1002EEED10121ECE701356D +:104DC80097F83030EDB2AB429ED2012207F12401B0 +:104DD800386A01F01DF90028A4D03C6AA0F80280C6 +:104DE800204605F0F3FC00289CD004F5047005F07B +:104DF800EDFC002896D0D4F8400403681B6A984755 +:104E080000288FD095E797F8333013F0400F437898 +:104E180014BF43F0020323F002034370386AF969B0 +:104E2800D7E904236161C4E90223D7E90223C4E96D +:104E3800062390F8103243F0010380F810322378EB +:104E48009BE700BF8821002090F8312092B138B547 +:104E580090F8332011060FD4056A0446284605F059 +:104E6800B5FC88B994F83230002043F0010384F887 +:104E7800323038BD0120704702F07F0280F83320BD +:104E8800BDE83840FFF738BF05F5047005F09EFC13 +:104E98000028E7D0D5F8400403681B6A9847002823 +:104EA800E0D0012038BD00BFF8B590F83130054694 +:104EB8005A064FD480682B6AD3F83C341844B0F1B2 +:104EC800806F01D30020F8BD2846FFF73FFE002879 +:104ED800F8D0286A0122AE6990F84534023ED0F82D +:104EE8002C149E4012FA03F30E4415D000243119F5 +:104EF800052200F50470013405F038FC4FF4007207 +:104F080000210028DED008F01FFD286A012390F850 +:104F180045249340A342EAD895F831305B0614D46F +:104F280095F83330002763F07F0385F83330D0F8E5 +:104F38003C64D5E90223D5E9040192197B41801923 +:104F48007941C5E90223C5E904012846BDE8F840CE +:104F5800FFF77ABF006A01F0B9F9ACE710B591F82C +:104F6800314014F0500F01D1002010BD40F602234B +:104F78000446FFF76FFB0028F6D01023204684F87C +:104F88003130FFF791FF0028EED0A16900232046B9 +:104F98000022E161FFF7DAFAC123204684F83330B2 +:104FA800BDE81040FFF750BF2DE9F041064696B026 +:104FB80000200C4696F831100192ADF814008DF8D7 +:104FC80051008DF852008DF8530029B9984694F88D +:104FD800313013F0500F03D1002016B0BDE8F08136 +:104FE800137811462F2B34D001AB02AA3046FFF7B5 +:104FF80075F90028F0D0019B1B78002B37D00023CF +:1050080002AA21463046FFF725FB48B9B8F1000F40 +:10501800E2D0214602AA3046FFF7A0FF0028DBD0E5 +:10502800344608AF06F1300E2068103454F80C1CD2 +:105038003D4654F8082C103754F8043C74450FC505 +:10504800F2D1206808AC38603046FFF705F90199BD +:10505800CAE7013101910B782F2BFAD0216A08A8F1 +:10506800FFF728F90028B7D008AC0199BCE702AAD5 +:1050780021463046FFF772FF16B0BDE8F08100BF49 +:10508800F0B590F831409DB0002314F0180F8DF85A +:1050980031308DF832308DF833308DF869308DF835 +:1050A8006A308DF86B3003D00B6A046A9C4202D0D8 +:1050B80000201DB0F0BD044640F601236846FFF706 +:1050C800A5FC0028F4D0254604F1300E0EAF286860 +:1050D800103555F80C1C3E4655F8082C103755F875 +:1050E800043C75450FC6F2D1286809AA04F12403C7 +:1050F80038609DF8305007CA83E8070094F83330C9 +:10510800204684F8305063F07F0384F83330FFF78B +:105118009BFE0028CCD00021022208230EA815915E +:105128008DF86B208DF86930FFF758FDC1E700BF97 +:105138002DE9F04F90F8314083B01F4624079DF8C1 +:1051480030A09DF834909DF838B09DF83C3004D5D7 +:10515800A2F2BC7294B27F2C04D90026304603B068 +:10516800BDE8F08F7A1E0B2AF7D80AF1FF321E2A03 +:10517800F3D8BBF13B0F98BFB9F1170F8CBF0126CD +:1051880000263B2B88BF46F00106002EE5D101938F +:1051980005468846FFF758FE019B0028DDD05910C8 +:1051A80013F0010F4AEA471708F0010341EA4B11CF +:1051B800B24647EA442708BF4FF0000B41EAC92925 +:1051C80018BF4FF0640B3446BFB21FFA89F9019338 +:1051D800002251462846FFF721F80028BDD0027862 +:1051E800852A4FD0BAD3A2F1C0010129B6D84FEA17 +:1051F800C43EA2F1850300214EEA5404B3FA83F3B6 +:105208004FF0010E12FA84F45B09A4B27144E20370 +:105218004FF0030E1F2942EA54020AD8445C0129C0 +:1052280014FA82F294B201D1002BEFD14FF0010EA3 +:10523800ECE70AF1010395F830205FFA83FA52454A +:10524800C6D2012205F12401286A00F0E1FE0028F7 +:1052580083D02D6A4480284605F0B8FA00283FF428 +:105268007CAF05F5047005F0B1FA00283FF475AF7E +:10527800D5F8400403681B6A9847064600283FF49F +:105288006CAF6BE795F83120296A02F03702019B71 +:10529800828091F8102242F0010281F8102213B1A5 +:1052A800A0F81090478218F0020F04D080F814B0CC +:1052B800A0F80890478118F0040F04D080F815B0C2 +:1052C800A0F80C90C781027891E700BF90F83330BE +:1052D8009A0718D5F0B5C56983B08DB103F04003BE +:1052E800044603F0FF0683B98169002942D101957C +:1052F800C1612946206A00F0FDFE38BB002000E0AD +:10530800012003B0F0BD00207047006AA16990F841 +:105318004524D4E90267093216F1FF36D2B247F1C3 +:10532800FF37C2F1200EA2F1200326FA02F207FA93 +:105338000EFE27FA03F342EA0E021A430132B1B114 +:10534800013D4B1C691A01930A4402BB94F833309F +:105358002046D4E9006763F07F03C4E9026784F854 +:105368003330C4E90467FFF76FFD03B0F0BD019562 +:10537800E161EAE702AA006A42F8046D00F064FEFF +:105388000028BBDB0AD1019D002DDFD0B1E7002347 +:10539800019900F0E7FD0028D8D1AFE74FF0FF32C0 +:1053A800A169206A00F094FE0028ECD1A6E700BFAE +:1053B8002DE9F04F90F8333083B004469D070092F2 +:1053C80040F1B3801A07884600F1A880009B002BA3 +:1053D80000F01D812146009D4FF0010AF1E80623E7 +:1053E80093460191206AA169D0F8386406EA0B0651 +:1053F800C6F3080956BB002900F0CC8094F8333076 +:105408005B0640F1E08090F84524E3690932D4E96D +:1054180002BCD2B21BF1FF3BC2F1200EA2F1200761 +:105428004CF1FF3C2BFA02F20CFA0EFE2CFA07F7AD +:1054380042EA0E023A431A449142C0F0C180204623 +:10544800FFF784FB002870D0206AA169760A023928 +:10545800D0F82C7490F845E4374401FA0EF1394439 +:10546800B9F1000F6BD1B5F5007F2CBF00220122E6 +:10547800002A64D1B5F5806FC0F090800AFA0EFE5C +:105488006B0AD0F81CC2C6EB0E06B34228BF3346DF +:1054980061454FEA432708D85E18B44505D24FF056 +:1054A800FF3680F81022C0F81C62D0F81402424679 +:1054B8000668B66AB047002837D038460021B84495 +:1054C800ED1BD4E90023D4E9046712EB000B43EB8E +:1054D800010C674508BF5E45C4E900BC07D294F8D3 +:1054E800331061F07F01C4E904BC84F83310002D47 +:1054F8007FF478AF5A466346D4E90201994208BF5F +:10550800904278D3434B1B68002B7ED094F83330FD +:10551800009863F07F0384F833300DE0D0E904236A +:10552800FFF714F800287FF451AF94F832300020C8 +:1055380043F0010384F8323003B0BDE8F08FB9F1CD +:10554800000F25D1D4E90423D4E900679F4208BF9E +:10555800964234BF0122052200F5047005F006F9D1 +:105568000028E2D0C9F5007748444146AF4228BF39 +:105578002F46B9443A4605F01BFEB9F5007F9CD189 +:10558800206A00F5047005F021F9002895D1CCE7D0 +:105598000122E1E7E169F1B1A16157E7D0F81C32D6 +:1055A800994221D0D0F81402424603685B6A9847B2 +:1055B8000028BAD04FF4007000214FF400777EE73E +:1055C8000131A16142E7019A00F03EFD0028ACDB01 +:1055D8007FF43AAF33E72046FFF7B8FA0028A4D0A3 +:1055E800A169206AE16131E74FF0FF3380F81022AA +:1055F800C0F81C32D6E794F83310009861F07F01A8 +:10560800C4E9022384F8331096E7009894E7D4E9B4 +:10561800002371E78821002070B5044608460D462E +:1056280008F00EFA23680246294620465B68BDE862 +:105638007040184783680146C3F3080363B100202C +:105648000A69D0540133B3F5007FF9D1C8680A69F3 +:10565800036809685B6A1847012070478268034637 +:105668000069C2F3080230B4815440F2FF145D6847 +:105678009868A24201EB750100F101005960986039 +:1056880002D0012030BC7047D868196802684D1CE8 +:10569800546A1D601A69234630BC184738B50C4651 +:1056A800C9B20546FFF7DAFF00B938BD210A284616 +:1056B800BDE83840FFF7D2BF2DE9F8430023804604 +:1056C80001601E4683604360B0B205F0ABF9B0429A +:1056D800814605460DD001464046FFF7DFFFA0B3DF +:1056E8000136B6F5803FEFD34046BDE8F843FFF7F3 +:1056F800A1BF741CB4F5803F14D1C6F580374FF4B0 +:105708008034B7F5007F1AD2A9B240460135FFF7B9 +:10571800C5FFD0B1A542F7D32E46E2E70134B4F570 +:10572800803FEAD0A0B205F07DF9A042F6D0A71BD1 +:10573800B7F5007F03D2A642E6D34E46C4E74FF63C +:10574800FF714046FFF7AAFF10B90020BDE8F883B3 +:10575800B9B24046FFF7A2FF0028F6D02646C0E7B8 +:105768002DE9F04F81461F460B6889B0C9F80C1027 +:105778000846C9F810200E46DB6915469847B0F56B +:10578800801F12D2002F69D03B681522AE493846D7 +:105798005B6898473B6838460F22AC495B68002431 +:1057A8009847204609B0BDE8F08F0446002301223F +:1057B80001E0944203D901335200DBB2F9D11C2B2A +:1057C80051D90122A3F10B0848FA02F85FFA88F1CF +:1057D80002FA08F20691049201220133134102FAF7 +:1057E80003F303FA02F205939B0001920293029BD2 +:1057F80000214FF400722846E31A8A464FF0010B45 +:1058080023FA08F3039303FA08F8019B984408F075 +:105818009BF8FF230722FE2085F8BFB185F8C22137 +:105828004AF6552E85F8C301514685F8C4312A46F3 +:1058380085F8C531304685F8C0B185F8C1A1019B0E +:10584800D6F800C0C5F8C631C5F8CA81DCF82430DE +:10585800A5F8FEE19847D0B9002F9BD10024204637 +:1058680009B0BDE8F08F1A2B4FF0080800F22D821E +:105878004FF40043CDF8188002934FF4804301930E +:105888004FF4807304934FF400530593AFE75146E8 +:105898004FF40072284608F057F8059B76220198C5 +:1058A8002B6590216B654FF0410C039B4FF0540E14 +:1058B8006A704FF04502EB659DF818302864A865BA +:1058C800202085F86D306FF01403EA704FF058020D +:1058D800C5F844A0C5F848804FF00908C5F84CA0A1 +:1058E8006C664FF04604A5F86AA085F86EB04FF0D4 +:1058F800040B85F870A04FF4807A2B7005F17703BC +:10590800A97005F2FD112A71F42228726872A87232 +:105918006FF07F006C7185F806C085F807E0C5F860 +:1059280060B0A5F868A085F86C8085F86F0003F86A +:10593800012F9942FBD14FF000084AF655234446FF +:10594800A5F8FE31A8F16A03012B06D9B8F1700F4A +:1059580003D015F8083003EB740408F10108B8F512 +:10596800007FEFD133682A46019930465B6A984731 +:1059780000283FF471AF33682A46019930465B6AC4 +:105988000C31984700283FF467AF019B424600213D +:10599800284603F1010A07F0D7FF019A4AF6552372 +:1059A800CDF81C9005F2FF1802F1090B6A1EA5F844 +:1059B800FE31914606924B4613F8012F984502EBAB +:1059C8007404F9D133682A46514630465B6A9847D1 +:1059D80000283FF441AF33682A460AF10C013046EB +:1059E8005B6A984700283FF437AF0AF1010AD345AC +:1059F800E1D1019B4FF4007200212846DDF81C908C +:105A080003F10B0A07F0A0FF069B13F8012F984536 +:105A180002EB7404F9D133682A46594630465B6A6A +:105A2800984700283FF418AF33682A460BF10C0159 +:105A380030465B6A984700283FF40EAF0BF101032C +:105A4800534505D09B46DFE7040C0020640C00207A +:105A58002B1F05F5FE7243F8044F9A42FBD13368B9 +:105A680051462A4630465B6A984700283FF4F4AE10 +:105A780033680BF10D012A4630465B6A98470446A5 +:105A880000283FF4E9AE2FB13B680C22974938460D +:105A98005B689847039B4FF40072002128464FEA41 +:105AA8008308059B08F207289B46019B9B4407F047 +:105AB8004BFF4FEA5823F82005F11301FF229E46B9 +:105AC8002B46287003F8012F9942FBD17346002B0F +:105AD80031D03B1C4FF0000ACDF818904FEA9838A7 +:105AE80018BF0123F1460593234654469A4605E01C +:105AF800002C00F0F0800134A14519D001227C4926 +:105B08003846B4FBF8F308FB134323B9059B13B1DC +:105B18003B685B68984733682A4604EB0B013046BC +:105B28005B6A98470028E3D1002F7FF433AE95E6EF +:105B38005446DDF81890002F35D03B6802226D4995 +:105B480038465B689847039B03F10708049B4FEAB4 +:105B5800D80808F2FF1A4FEA5A2A9A453FF61AAEB1 +:105B68004FF400720021284607F0EEFE07232B7041 +:105B7800BAF1000F7CD04FF0000B07E0BBF1000F2B +:105B880000F0B0800BF1010BDA456FD033682A467C +:105B9800029930465B6A594498470028EED1002F95 +:105BA8007FF4F8AD5AE6039B03F10708049B4FEA1C +:105BB800D80808F2FF1A4FEA5A2A9A453FF64EAE1D +:105BC8004FF400723946284607F0BEFE07232B70B3 +:105BD800BAF1000FCFD1019B48464FEA430A049B14 +:105BE8000AEB0301FFF768FD00283FF437AED9F848 +:105BF8000830049AB3EB422F3FF630AE049B4FF4C3 +:105C08000072002128460AEB430A07F09DFE032292 +:105C18008123822102202A7085F8203000236863BE +:105C280085F84010D9F804106A656964D9F8082025 +:105C3800C5F83880AA65049AEB65002A3DD09846D5 +:105C480007E0B8F1000F31D008F10108049B98452E +:105C580033D033682A460AEB080130465B6A984716 +:105C68000028EED1002F7FF495ADF7E5002FB2D0D4 +:105C7800019B384620494FEA430AFFF7CDFC049BB5 +:105C880048460AEB0301FFF717FD00283FF482ADF1 +:105C9800D9F80830049AB3EB422F3FF67BAD002FBA +:105CA800ACD016493846FFF7B7FCA7E74FF40072A7 +:105CB8004146284607F048FEC6E7002F3FF471AD7D +:105CC80038460F49FFF7A8FC6BE54FF48072CDF812 +:105CD8001880049280E54FF400722146284607F0A8 +:105CE80033FE08E785F800B04CE700BF1C0C002025 +:105CF800D40A0020400C00202C0C0020440C00206A +:105D0800540C00202DE9F0410C46154601F11E08FF +:105D1800AB89284634F8026F1BB96A68AB689A42A7 +:105D28000ED004F071FD04F07DFE0746304604F005 +:105D380079FE874209D14445EAD10120BDE8F081C6 +:105D4800B6FA86F04009BDE8F0810020BDE8F08190 +:105D58002DE9F84F90F831308946002B45D090F85E +:105D680030308046012B53D9013A8A4602274FF03A +:105D7800000B8E18002239464046FEF74FFAA0B3B2 +:105D88000378C12B31D1044600F11E0519E000F556 +:105D980010539BB2B3F5806F27D24FEA8B2B1E4B63 +:105DA800C0F309000BEA0303184300F5803051469D +:105DB800324604F0A1FD8246B8B1AC424FF0000B68 +:105DC8001FD034F8020FBBF1000FE0D100F52053CB +:105DD8009BB2B3F5006F0ED30028E8D1C9EB0A00D7 +:105DE80000238AF80030BDE8F88F0023184689F8A8 +:105DF8000030BDE8F88FB3F5806FF6D2AC42834629 +:105E0800DFD1013798F83030FFB2BB42B2D2E5E7B4 +:105E18008A460020E4E700BF00FC0F00F8B50D46F5 +:105E280000234FF6FF762A681946AB811C466A6044 +:105E38002B6116E004F0E8FCB04221D004F0F2FD3A +:105E48002B69E203A9890712013342EA54022B6144 +:105E580052FA80F0C0F34E0343EAC03017FA80F4D8 +:105E6800A4B228460029E5D16A68AB689A42E1D114 +:105E78002869AC820138FE288CBF00200120F8BDBB +:105E88000020F8BD38B50C46D0F82414154600F5A6 +:105E98000470012201EBD41104F068FC034628B118 +:105EA800A4000120C4F308041D5138BD38BD00BF4B +:105EB8002DE9F84F804691468B46002943D08F1E26 +:105EC800D8F830349F423AD207F007050123C7F3C8 +:105ED800C80A03FA05F5EDB23E463C46D8F82C143C +:105EE8000022404601EB143104F040FCC0B110F828 +:105EF8000A100AE04A4529D0A74210D0D8F8302421 +:105F0800944216D213F0FF050CD001340D424FEA2B +:105F18004503A4EB0602EDD0A7422646EED10120A8 +:105F2800BDE8F88F0AF1010A0125BAF5007FDED134 +:105F380001E0002634464FF0000A0125CEE700278D +:105F48000125BA46C8E7D0F82074B9E7BBF1000FBD +:105F580004D1B9F1010F08BFC8F82064B01CBDE82E +:105F6800F88F00BF2DE9F047023915469A46D0F858 +:105F780030244B19934238D88046BAF1000F37D1F4 +:105F8800D0F82034994238BFC0F8201401F0070433 +:105F98000122D8F82C34C1F3C80602FA04F403EB42 +:105FA8001139E4B2012249464046914404F0DEFB2F +:105FB800D8B1871900F5007017F8012B224282EA40 +:105FC80004024FEA440414BF0126002656450CD0AB +:105FD800013D07F8012C17D014F0FF04EED18742D9 +:105FE80026464FF00104E7D1DCE70020BDE8F08742 +:105FF800D0F820048342C9D98142C7D8934228BF28 +:106008000023C8F82034C1E70120BDE8F08700BFAD +:1060180070B50E460446D0F8385400F50470496847 +:1060280033682940D4F82C54023B94F8454405EBD6 +:106038005121A340194404F099FB18B17368C3F3C4 +:106048000803184470BD00BF38B5D0F830340133A8 +:106058008B4216D30C46D0F82414154600F504706C +:10606800002201EBD41104F081FB50B1A100C1F36F +:10607800080143585A1C02D02B60012038BD00206B +:1060880038BD4FF0FF3038BD70B54C680D46D0F8BC +:1060980038340646A1182340696090F845441A44EC +:1060A8000934E4B222FA04F43CB12B7A3BB12B68F0 +:1060B80001332B60013C002CF7D1012070BD2A462A +:1060C80029683046FFF7C0FF0128F3D070BD00BF34 +:1060D80001290DD9D0F830340133994210B403D9CD +:1060E80000205DF8044B70475DF8044BFFF7CABE0B +:1060F800002070472DE9F0410C4682B005468846DD +:10610800214601AA2846FFF79FFF012C0746C0F346 +:10611800C0162146284626D9324626BBD5F8303443 +:1061280001339C421FD8FFF7ADFE04F1010E414632 +:106138003346C8EB0E02B0B1284647B1019CA645CC +:10614800DED0FFF70FFF70B1019CA046D8E7621CB4 +:106158003B4641462846C8EB0202FFF703FF10B151 +:1061680002B0BDE8F081002002B0BDE8F08100BFB8 +:106178002DE9F84300248046D0F82C6400F5047714 +:106188002546314600223846013604F0EFFA28B396 +:1061980000F1FF3ED8F830C405F580591EF8010F0C +:1061A800FF2813D048B10822012318424FEA4301BF +:1061B80018BF0134013ACBB2F7D10835AC4509D93B +:1061C8004D45DED01EF8010FFF28EBD10835083405 +:1061D800AC45F5D8C4EB0C00BDE8F883BDE8F883FE +:1061E8002DE9F041002304464FF0FF3600F504770F +:1061F8001546C0F8401441601A46C4F814123846CF +:10620800194684F84434237084F81032E660C4F8E0 +:106218001C6204F0ABFA042D0DD8064658B16DB9CE +:1062280005222949F01C07F079FC034618B996F8AD +:106238006C20092A1AD00020BDE8F0816B1E00EB03 +:10624800031393F8BE2112F07F02F4D193F8C23100 +:10625800002BF0D000EB05153846D5F8B651294685 +:1062680004F084FA06460028DAD1E4E7326D4FF0EC +:1062780001080146204602EB050E4246C4F824E414 +:10628800776DC4F82874B76D3D44C4F82C54F56D87 +:10629800C4F83054356EC4F8345496F86D50C4F8C8 +:1062A800203405F1090384F8455408FA03F35D1E08 +:1062B800C4F83C34C4F83854FFF7FAFD402340468C +:1062C80084F84434BDE8F081740C002070B582B0C5 +:1062D800D0F834140546002402AE46F8041D01E047 +:1062E80009D0019932462846FFF7AEFE002804F18E +:1062F8000104F5DA002495F845040930C0B204FA1F +:1063080000F002B070BD00BF38B50D460446242227 +:10631800002107F019FBA560EB79102B05D0202B85 +:1063280008D00C2B01D0002038BD20230120237079 +:10633800A07038BD402301202370A07038BD00BF75 +:10634800024638B552F8105F04468068294602F0C4 +:10635800AFF850B155B123690135AB42A37818BFE6 +:1063680003F0BF0363F07F03A37038BDA37843F045 +:106378004003F7E7F8B5037803F020032BB903F0DF +:10638800FF044169194B994202D900263046F8BDED +:106398000546FFF7D5FF06460028F6D0A8682F69FE +:1063A8008379023F426901799F40174441B913E05C +:1063B80007F0CAFA0134A868E4B20379A3420AD9FB +:1063C8000522E119283004F0D1F94FF400720021B8 +:1063D8000028EDD1D9E783794FF40072696902FA90 +:1063E80003F311FA83F36B61D0E700BFFFFD1F00D1 +:1063F80010B5044680680A462830A16904F0B6F949 +:1064080020B1A38803F00F0300EB431010BD00BFB9 +:1064180030B590F9023083B00446002B19DBA5682B +:1064280005F1280004F0D2F930B96378002043F070 +:106438000103637003B030BD05F50E7004F0C6F9B2 +:106448000028F2D0286803681B6A98470028ECD017 +:10645800F0E70121FFF7CCFF05460028E5D00378D7 +:10646800E52BE2D023781B0701D5E369C361236AD2 +:106478000B491A0C6B830B68AA8263B10DF10302F6 +:106488000DF1060101A89847BDF80430BDF80620B3 +:106498002B836B82EA82A37803F07F03A370BEE7A5 +:1064A8008821002010B50378044623B90023012071 +:1064B8002370A37010BDFFF7ABFF00232370A370F8 +:1064C80010BD00BF70B5037805460C46BBB9284619 +:1064D8000021FFF78DFF0346A8B1066801205D681B +:1064E8009968DA6826606560A160E2601E695D6986 +:1064F8009969DA6926616561A161E26170BDFFF79A +:1065080087FF0028E3D1002070BD00BF30B589B0F7 +:106518000D4614466946FFF7D5FF28B1BDF810208F +:10652800BDF80E302A80238009B030BD30B589B05F +:106538000D4614466946FFF7C5FF28B1BDF8182077 +:10654800BDF816302A80238009B030BD2DE9F0410E +:106558000C7888B014F0700F03D1002008B0BDE8A3 +:10656800F08140F6022305460C4601F077F8002832 +:10657800F3D0012210232846AA702B70FFF7FAFEE9 +:106588000028EAD02A692B782A62002B7FD10121C2 +:106598002846FFF72DFF07460028DED010230068A5 +:1065A8007968EE46FB724FF02E0CBA6808AEFB68AD +:1065B800B7F81480AEE80F00BA69FB6938697969E1 +:1065C80006F820CD0DF10A0C7F8BAEE80F0033469C +:1065D800202203F8012F6345FBD1A86801222B6A0A +:1065E80090F806E02830023B50F8141C03FA0EF32A +:1065F800194404F0BBF886460028AED0ADF81480E4 +:106608004FF02E08ADF81A7037460FCECEF80000BE +:10661800CEF80410CEF80820CEF80C308DF80180A2 +:106628000FCECEF81000CEF81410CEF81820CEF801 +:106638001C30236A1A0CADF81A30ADF814200FCFAD +:10664800CEF82000CEF82410CEF82820CEF82C3032 +:106658000FCFCEF83000CEF83410CEF83820CEF870 +:106668003C30AC6804F1280004F0B0F800283FF48E +:1066780074AF04F50E7004F0A9F800283FF46DAF6C +:10668800206803681B6A08B0BDE8F04118476B69C9 +:1066980033B1AB78002223F020032A616A61AB7022 +:1066A8002846FFF7B5FE00283FF457AF6FE700BF55 +:1066B8002DE9F041064694B000200C46317801924D +:1066C800ADF814008DF82C008DF82D008DF82E00F3 +:1066D80021B99846237813F0700F03D1002014B025 +:1066E800BDE8F081137811462F2B2ED0002701AB7F +:1066F80002AA304601F004F902AA21460023002824 +:10670800ECD0019D30462D78002D30D000F0A6FF4A +:1067180048B9B8F1000FE1D0214602AA3046FFF788 +:1067280015FF0028DAD035460BAC96F800E00FCDFF +:106738000FC40FCD2D680FC42560BEF1000F12D114 +:1067480037700BACB7700199D1E7013101910B7823 +:106758002F2BFAD0A1680BA8FFF7D6FD0028BDD0D3 +:106768000BAC0199C2E73046FFF752FEE8E702AAF0 +:1067780021463046FFF7EAFE14B0BDE8F08100BFBD +:106788002DE9F041064694B000200D46317801927B +:106798008DF808008DF809008DF80A00ADF838006A +:1067A80021B998462B7813F0700F03D1002014B04C +:1067B800BDE8F081137811462F2B2AD0002702E07C +:1067C80001993770B77001AB0BAA304601F098F801 +:1067D8000BAA294600230028E8D0019C30462478DB +:1067E80034B300F03BFF354602AC0028DED096F803 +:1067F80000E00FCD0FC40FCDD5F800C002AD0FC417 +:10680800C4F800C0BEF1000FDAD03046FFF700FE32 +:10681800D6E7013101910B782F2BFAD08BB1A968FB +:1068280002A8FFF771FD0028C0D002AD0199C5E7A5 +:1068380043460BAA2946304600F010FF14B0BDE8C5 +:10684800F081A9683046FFF75FFDB0E719B101F59F +:106858008961FFF795BF0846704700BF38B5CB6818 +:1068680043B902780AB1184638BD8968BDE838408E +:10687800FFF74ABD0D4624220021044607F064F8BC +:1068880001231022A37018462270AA68EB68A26040 +:10689800236238BD03780BB100207047FFF734BD81 +:1068A8002DE9F04F837883B00546DF0740F19080EB +:1068B8000F46017891460E0700F193808C0608D5A3 +:1068C800826843695289C3EB42139BB2994528BF3A +:1068D8009946B9F1000F00F0AA806B6988064E4608 +:1068E8004FF0000805F1100AAA68C3F3080440D560 +:1068F800116A01EB5321002C54D1B6F5007F51D316 +:10690800536B99424ED0B6F5806F73D328784FEA0F +:10691800562B800605D41079C8EB0000834528BFA4 +:10692800834699424FEA4B240DD801EB0B00834272 +:1069380009D202F128000191009203F047FF009A62 +:106948000199002844D0D06A5B463A46D0F800E066 +:10695800DEF814B0D84700283AD06B69361B2744B4 +:1069680023446B6163D02978C3F30804AA688806B6 +:10697800BED492F8058008EA5328002C38D1B8F123 +:10698800000F35D1002B3FD148064CBF136A2B6A44 +:106998002B619179023B50698B4008EB0001194447 +:1069A800002CAAD002F12800002203F0DFFE78B103 +:1069B800C4F5007301193846B34228BF33461A4656 +:1069C8001C4604F0F5FBC8E72B7813F0700F2FD1A5 +:1069D8006B784FF0FF3043F002036B7003B0BDE8F3 +:1069E800F08FC36942699B1A994528BF994670E799 +:1069F8002B69CEE7D06A3A4603681B699847002896 +:106A0800E6D04FF40074A8E7090705D5AB785B0614 +:106A180002D52B690133BBE710462969524601F0BC +:106A2800CFFC0028D4DBCFD0AA682B69B1E70026B9 +:106A3800C6EB090003B0BDE8F08F00BF70B582B0A7 +:106A48000122044646690DF107010569FFF728FF91 +:106A5800012866610CBF9DF807004FF0FF302561E3 +:106A680002B070BD436930B5C3F3431583B0044623 +:106A7800B5FA85F252098A4207D220334361A068E9 +:106A8800383000EB451003B030BD01220DF107018D +:106A9800FFF706FF40B2012803D163691F33636122 +:106AA800EDE70020EFE700BF2DE9F04305789BB044 +:106AB800002415F0180F8DF820408DF821408DF82E +:106AC80022408DF844408DF845408DF8464004D06A +:106AD800866803468D68AE4203D000201BB0BDE82F +:106AE800F0831D4690460E46FFF792FCAE4611AF66 +:106AF800BEE80F000FC7BEE80F00DEF800E00FC7C2 +:106B080021462846C7F800E0FFF772FC86460028B1 +:106B1800E3D000686F46DEF80410DEF80820DEF8DF +:106B28000C3095F800C00FC70CF0080CDEF8100008 +:106B3800DEF81410DEF818200CF0FF09DEF81C301F +:106B48000FC7BCF1000F00F096804246314640F670 +:106B5800012308A8FFF714FE0028BED00E9A0026CD +:106B6800BDF824300121AA612846AB809DF8232076 +:106B78000B9BEA70EB608DF820608DF82260FFF7C0 +:106B880037FC0028A9D01AAB9DF80B2053F85B7D81 +:106B9800C272D3F804E0C0F80D709F68C0F811E025 +:106BA800C0F81570D3F80CE01F8A9B7CC0F819E078 +:106BB800A0F81D70C377002C3BD0AF68A31E3246E7 +:106BC800BE7907F128007969B340194403F0CEFD76 +:106BD800002882D006466F4656F8200F7168B268C2 +:106BE800F3680FC730697169B269F3690FC7214645 +:106BF800A86801F0BFFC00283FF46FAFA968012224 +:106C08002B6A8C7901F12800023B4969A340194499 +:106C180003F0ACFD074600283FF45FAF6C460FCC8D +:106C280038627962BA62FB620FCC38637963BA63FF +:106C3800FB6300210222082311A819918DF8462030 +:106C48008DF8443000F0CEFE00283FF446AFAC6823 +:106C580004F1280003F0BAFD00283FF43EAF04F524 +:106C68000E7003F0B3FD00283FF437AF20680368C7 +:106C78001B6A984732E74B464246314608A8FFF759 +:106C880017FD00283FF429AF109C67E70378DA0660 +:106C98001AD5436910B5044633B18378002223F02E +:106CA800200302614261837001212046FFF7DAFE6A +:106CB80060B103786BB1E52BF6D02E2BF4D0C37AF4 +:106CC8001B07F1D4002010BD002070476378002B0B +:106CD800F8D1A3780822204643F002032270A3705B +:106CE800BDE8104000F07EBE2DE9F041037804466F +:106CF8000769B3B10D464169A9422CD045B98378DB +:106D0800056123F0200365610120A370BDE8F081CF +:106D180018070AD49A060BD5A3685B89B5EB431FFD +:106D280030D927610020BDE8F081E2699542F8D8A2 +:106D3800D4F808E06E1EA2789EF8060012F0400F04 +:106D480000F10900C0B226FA00F607D0216A1346FE +:106D58000E442661D5E70120BDE8F0814A1E22FADB +:106D680000F0864210D379B1361A04F1100806E013 +:106D78002169013EA06801F023FB0028D1DD4246CD +:106D8800002EF5D1A378BCE75B064CBFDEF82030B7 +:106D9800236A2361E9E700BF2DE9F0410D469046DB +:106DA8000021242204461F469DF8186006F0CCFDF9 +:106DB800A86808F00F03296A00F13802A060E160B2 +:106DC80002EB4312A4F80480D17A0D0711D401F024 +:106DD80017012170D37A13F0180F02D141F008017E +:106DE800217007F00303E670012B08D0022B2AD08C +:106DF80023B3002323701846A370BDE8F081022353 +:106E0800A370217811F0110FF3D159B207F48065FE +:106E180007F008030B43DBB2A370B2F814E0518B00 +:106E2800466B41EA0E41A66185B1D1B963F07F0393 +:106E3800A3707B040ED40120BDE8F08117F48065AF +:106E4800D7D10121E4E70323A370DAE72162D369EC +:106E5800E361EEE7E1692046FFF746FF0028EAD143 +:106E6800C7E701F087FB0028C3D0A378DEE700BF9F +:106E780003781BB90B7813F0700F01D1002070470D +:106E88002DE9F0434D6983B015F01F0632D19046C5 +:106E98000C460746B14611E0A3F1E502B2FA82F2C8 +:106EA8005209A2B990F80BE00EF0080101F0FF0CAE +:106EB80079B1BEF10F0F21D0164665690021204631 +:106EC800FFF7D0FDB0B10378A3B12E2BE4D1002693 +:106ED800F3E7D6B1421E0A304FEACC1312F8011F6D +:106EE80043EA5C0C904251FA8CFC5FFA8CFCF3D1BB +:106EF800CC450AD0002003B0BDE8F0835A06DCD5A3 +:106F080003F01F0690F80D90D7E700964346C5F3A7 +:106F18004F1221463846FFF73FFFECE703780BB1E5 +:106F2800FFF776BA012070472DE9F04F90F800E09E +:106F380081B01EF0080F9DF828909DF82CA09DF8B0 +:106F480030B09DF8348004D0A2F2BC7294B27F2C89 +:106F580003D9002001B0BDE8F08F5A1E0B2AF8D8DB +:106F680009F1FF321E2AF4D8BBF13B0F98BFBAF1E2 +:106F7800170FEED8B8F13B0FEBD806461D460F4663 +:106F8800FFF746FA0028E4D001213046FFF730FA2F +:106F98000028DED04FEA6801FB0749EA451541EAB7 +:106FA8004B1B45EA44244BEACA2AA4B21FFA8AFAC0 +:106FB80000D54482B90709D518F001080482A0F861 +:106FC8000EA018BF4FF0640880F80D807A0702D52C +:106FD8000483A0F816A0B46804F1280003F0F6FBB7 +:106FE8000028B6D004F50E7003F0F0FB0028B0D0EE +:106FF800206803681B6A01B0BDE8F04F184700BF5E +:1070080083789B071AD5036AB3B1016910B50446A2 +:1070180082B0F1B9019301621946A06801F0AAFA99 +:10702800A8B1A378616963F07F032278E161A37056 +:10703800EAB9012002B010BD012070470020704756 +:107048006FF070422169A06801F084FA58B90020F5 +:10705800F0E7002302AA806842F8043D01F0B0F985 +:107068000028F4DBECD1019B002BDAD0D4E72046D2 +:10707800FFF7CEF9DEE700BF2DE9F84F8378054624 +:107088009C076DD590461A070F4664D46A69D343A6 +:10709800984565D8B8F1000F00F0D08046464FF00B +:1070A800000A4FF0FF393CE0BBF1000F40D12969DD +:1070B80000297ED0AB785B0640F19B80EB69934258 +:1070C80040F297804B1C01392B6190F806E0436928 +:1070D80001FA0EF123441944B6F5007F47D2B6F5FC +:1070E800007F344628BF4FF40074EB69934202D9FD +:1070F800AB789B062DD50522283003F037FB78B3F3 +:107108005844A3442246394604F052F8BBF5007FA0 +:1071180000F08C806A69361B274422446A6100F0BB +:107128008D80A868C2F3080B447914EA5224BBD0B6 +:107138002B6990F806E0991E436901FA0EFEE118E2 +:107148007144BBF1000FC7D0CBF50074B44228BF1F +:1071580034460122D0E7C169FFF7C6FD002895D162 +:107168006B78002043F001036B70BDE8F88FB6F52B +:10717800806F31D390F804E0730A426BC4EB0E04BD +:10718800A34228BF23468A424FEA432407D303EB8E +:10719800010E724503D280F828A0C0F83490C06A66 +:1071A8003A46D0F800E0DEF828B0D8470028B1D138 +:1071B800D6E7296A61B32961023982794369B6F54C +:1071C800007F01FA02F11944D1D2CBF500746A6943 +:1071D800B44228BF344688E7436B8B4221D0C06A4B +:1071E8003A4603685B6A98470028B9D04FF40074A0 +:1071F80090E705F1100201F0E3F80028B0DB04D1B4 +:107208002846FFF79DF80028AAD02969A868D3E77F +:107218002846FFF795F80028A2D02969A8682962AE +:10722800CAE780F828A0C0F83490D8E7A8682830C2 +:1072380003F0CCFA00287FF46DAF91E7EB69934235 +:107248000CD30A4B1B6833B1AB78404663F07F031D +:10725800AB70BDE8F88F4046BDE8F88FAB78404684 +:10726800EA6163F07F03AB70BDE8F88F88210020E6 +:107278002DE9F04F07468DB0154606468A469946D1 +:1072880003AC4FF0000E0FCF0FC40FCFD7F800C0DC +:107298002F68A5F80CE06F600FC4C4F800C0B9F1FE +:1072A800000F35D04FF00108CDF80490C8EB0A0163 +:1072B80003A889B24901FFF717FD58B3002103A8B5 +:1072C800FFF7D0FB074628B30024E2B23946304620 +:1072D800013400F0CDFEAB89834628461BB96B68A4 +:1072E800AA6893421AD003F08FFA8146584603F0F1 +:1072F80099FB8346484603F095FB83450AD10D2C3C +:10730800E3D108F10108019B5FFA88F84345CDD223 +:10731800012000E000200DB0BDE8F08FBBFA8BF033 +:1073280040090DB0BDE8F08F2DE9F04F06468DB04D +:107338001546994600910DF10C0E02F1150400272F +:107348000FCEAEE80F000FCED6F800C005F120062C +:10735800AEE80F003B46CEF800C0DA0114F8011F72 +:1073680042EA5303B44251FA83F3DBB2F5D11F4624 +:1073780000262B68AE816B60B9F1000F56D049F03A +:1073880040034FF00108B2460193009B03A8C8EBE5 +:10739800030189B24901FFF7A7FC002853D0002157 +:1073A80003A8FFF75FFB00284DD0059AC145019956 +:1073B8004FF00F0E92F8283014BFC4468C4600F1E7 +:1073C800040B43F00103002482F8283080F80CA055 +:1073D8004773A0F81AA080F800C080F80BE00CE012 +:1073E8000A2C04F101040BF1020BE4B294BF2BF850 +:1073F800020CABF800000D2C12D0AB891BB96A68DF +:10740800AB689A4216D0284603F0FEF9042CE7D858 +:1074180001342BF8030C0BF1020BE4B20D2CECD168 +:1074280008F101085FFA88F8C145AED201200DB015 +:10743800BDE8F08F16B930460126E7E701364FF66A +:10744800FF70F6B2E2E700200DB0BDE8F08F00BF94 +:107458008446202062460CEB00012DE9F04752F8E3 +:10746800153BDCF8085002F8010F8A42FBD11A7864 +:107478002E2A14BF0120002003D113F8012F2E2A31 +:10748800FBD0691E99420DD915F8012C2E2A09D076 +:10749800AA1E02E00C782E2C04D09342114602F169 +:1074A800FF32F7D19D424FF000087DD907264FF0F3 +:1074B800080E4446C14608E0994209D10A26082424 +:1074C8004FF0100E01339D4225D91A782E2AF3D099 +:1074D800222A0BD07C2A09D0A2F15B07022F05D9FA +:1074E800A2F12A07052F30D82D2A2ED002F0C0028B +:1074F800802A3DD0B4421ED800205F22671C0CEBC6 +:10750800040AFCB28AF81620062CDBD801338CF862 +:1075180014409D42D9D89CF81630202B41D068B32E +:1075280019EA080F4FF0010018BF4FF002088CF855 +:107538001580BDE8F0870A2E1CD099422CBF002385 +:107548000123BBB918464B1EBCE7A2F13A07052F29 +:10755800CCD9A2F121075D2FC8D8B442EBD8A2F14B +:107568006107192F16D8203A4EEA0808D2B2C5E7A3 +:107578000020A7E79CF81630202B12D09CF8143076 +:1075880001207E21312263448CF815009975DA7543 +:10759800BDE8F087A2F14107192F98BF4EEA090903 +:1075A800ACE70020BDE8F087C146B4E72DE9F84F05 +:1075B800884605464FF0620900240F7D01F1160642 +:1075C800DFF894B04FF07E0A032FDBF8002028BFC5 +:1075D800032714443B1DA4B2DBB204F00F02581E6B +:1075E8002409092A02F1370198BF02F1300108EB9A +:1075F8000302C3B291759F42EFD308EB0703002142 +:10760800284683F816A0FFF76FFB01212846FFF7ED +:1076180029FA0B220346A8B190F800E0014630464B +:10762800BEF1000F14D0DB7A1B07EED406F05AF92E +:107638000028EAD109F1FF3919F0FF09C4D14846F9 +:10764800BDE8F88F6878B0FA80F04009BDE8F88F97 +:107658000120BDE8F88F00BFF02700202DE9F04F8A +:107668000C788DB014F0700F01D004781CB1002094 +:107678000DB0BDE8F08F14699F4E0C34557DA6FB04 +:107688000464C4F387040394AC0745D101274FF081 +:1076980000080E4615460693C246B3684446C146DE +:1076A80005F1160B09904146304604920893CDF82F +:1076B8001C80CDF81480FFF717FB75690021304650 +:1076C800C5F34F15FFF7CEF9002800F08D80037839 +:1076D800A3F1E502B2FA82F2520973B36ABBBC4263 +:1076E80038BF00242E2B25D022BBC17A0F295AD0AF +:1076F8000B071FD4B9F1000F40F0DD800B2259466B +:1077080006F0F0F80028D8D1049B5B7DD80740F13B +:10771800E88001230593D0E7039C671CFFB2B6E716 +:107728000AF1FF3A5FFA8AFA534503D1437B079976 +:10773800994249D04FF00009BFE7002C08BFA8467E +:10774800BC4201D20134E4B2002BCBD1069A1346D5 +:107758009A058CD503F00303013B012B87D8002C35 +:1077680008BFA846BC4203D348E0DCB2A74245D9CB +:1077780000213046FFF776F9631C0028F5D17378AD +:10778800002B7FF474AFA74238D9089D05E02B7908 +:1077980004EB0314E4B2A74230D93046FEF7EAFD01 +:1077A8000028F4D163E7B9F1000FB9D103F01F0A3B +:1077B800039A524581D1590602D4DDF80CA07CE722 +:1077C800437B914692460793BAF1010F7FF475AF58 +:1077D800691C4B46049A304689B2FFF749FD0028D8 +:1077E80008BF4FF0000968E77378002B7FF43FAFBC +:1077F800069A13469A057FF53AAFABE7059B33B176 +:1078080004993046FFF7D2FE00283FF430AF013F1D +:10781800049A30465FFA87F908EB09054B46ADB282 +:107828002946FFF781FD00283FF421AF6901304662 +:10783800FFF75AFA00283FF41AAF00213046FFF745 +:1078480011F9044600283FF412AF2022002106F067 +:107858007BF8049F294A3B4653F8160F5968206065 +:10786800616019899B7A2181A3727B7D176803F077 +:1078780018032373002F38D00DF12B020DF12E01C0 +:107888000BA8B847BDF82C10BDF82E209DF82B305A +:107898002182E2816373089A92F8283043F0010349 +:1078A80082F82830CDF800902A46069B3146099880 +:1078B800FFF772FADCE6BAF1010F7FF4D8AE441E86 +:1078C80013460A30D90114F8012F41EA5303A042A4 +:1078D80052FA83F3DBB2F5D11A46079B93427FF441 +:1078E800C6AE069B1905DDD5C1E645F221632382A4 +:1078F80023836382CFE700BF4FECC44E882100206A +:107908002DE9F0411F460B7882B00846202B14461B +:1079180003D110F8013F202BFBD0206005782F2DD4 +:1079280018BF002D0CBF012500253ED0A8462C4EBF +:1079380023E07F2A08F1010814D8D1B2A1F122036B +:107948001F29DBB28CBF4FF0000E4FF0010E1D2B2C +:107958001FD901239E4524D201F0BF013C2920D024 +:107968005C2A1ED02E2A04D0202A02D0C4F8108007 +:10797800A0600378CBB12F2B17D001AA011D03F00B +:107988000BF870B1019AB2F5803FD2D308F1020822 +:10799800E8E726FA03F303F0010383F001039E45A9 +:1079A800DAD3284602B0BDE8F0812369013BFE2BFB +:1079B80011D80378202B03D110F8013F202BFBD0DE +:1079C8002F2BF9D038602046FFF742FD05462846A0 +:1079D80002B0BDE8F0810025284602B0BDE8F0817C +:1079E800012100312DE9F04182788AB00023920705 +:1079F8008DF804308DF805308DF8063020D5016AF1 +:107A0800054611BB01212846FEF7F2FCC0B1411E14 +:107A180000F10A070024E20111F8016F42EA540359 +:107A28008F4256FA83F3DCB2F5D1E52700230770BD +:107A3800AE682B7006F12800AB7002F0C7FE50B993 +:107A4800002630460AB0BDE8F081806800F092FD5B +:107A58000028D7D1F4E706F50E7002F0B7FE00282B +:107A6800EED0306803681B6A984706460028E7D0BE +:107A7800EB78002BE5D0294601A8FEF7EFFE002899 +:107A8800DED0EB78002BDBD04FF0010820E001A816 +:107A9800FEF7E8FF08F101010028D1D0C37A0F2BC7 +:107AA800CED1027802F01F0398455FFA81F8C7D15A +:107AB800437BA342C4D10770A96891F8283043F0EA +:107AC800010381F8283053060ED4EB784345B7D329 +:107AD800A98801A8C8EB010189B24901FFF704F997 +:107AE80000210028D3D1ABE7AC6804F1280002F0EC +:107AF8006DFE0028A4D004F50E7002F067FE002881 +:107B08009ED0206803681B6A9847002898D098E799 +:107B1800486810B50C4668B10B894A8901339BB295 +:107B28009A420B8106D80368012203495B6898478B +:107B380000232381206810BDD40A0020F0B5044634 +:107B480087B00E4615460021406A4FF4007205F0D2 +:107B5800FBFE206A28B103680C2222495B6898471B +:107B6800206AE36903AA616A002704901846039112 +:107B780019686B0900926A1ECD6AE168ADF8163083 +:107B8800ADF814700131184BA847E8B1206A20B14C +:107B98000368022215495B689847102E626A4FF005 +:107BA800F8054FF0010314BF0C200420FF211570C5 +:107BB800626AD15401339842FAD1E069626A036873 +:107BC800E1685B6A984710B9002007B0F0BDE0692A +:107BD800A268E16803681144626A5B6A984707B063 +:107BE800F0BD00BF1C0C0020D15B0000400C002041 +:107BF800F8B5446A4FF40072002105462046EB2789 +:107C080005F0A2FE76262346902004F10A012022E0 +:107C18002770667003F8020F03F8012F8B42FBD11F +:107C28004FF40071F82302204AF65522A4F80B10ED +:107C380095F82B106173298D207463752B69E18188 +:107C4800E361AB69A4F8FE212362F8BD2DE9F04198 +:107C580004464FF400720021406A05F075FE656A1B +:107C680022694AF6552605F2BF10216802F0F6FD92 +:107C7800A369226905F2C31021681A44013A02F087 +:107C8800EDFD94F82A30002185F8C2312369E069B6 +:107C9800C5F8C6310368A769626A5B6AC5F8CA7124 +:107CA800A5F8FE61BDE8F041184700BFD0F814C040 +:107CB8004FF48071F8B5ACF5807390F82B600446EA +:107CC800456A4160B3FBF6F303F20112120A500051 +:107CD800A26000F1A1078F4274D94FF4C07200E08E +:107CE8007246C2EB0C0302F1800EB3FBF6F303F20B +:107CF8000111090A480000F1A1079742F0D8626013 +:107D0800A160D21BA3F6F57102F18007B1F5704F9F +:107D1800276108D3206A20B1036813222A495B68C7 +:107D280098470020F8BD21308132012103FB06006D +:107D3800E260B0F5803FA0612185204634BF04236E +:107D4800062384F82A30FFF781FF0028E9D020466F +:107D58008027FFF74DFFA2684FF4007129261B48C2 +:107D680005F12A03A5F8111005F13501EA82202250 +:107D780085F8247085F82660C5F8270003F8012FD8 +:107D88008B42FBD14120542131223623462685F8E7 +:107D9800370085F8381085F8366085F8392085F879 +:107DA8003A30E069626A036821695B6A984700288B +:107DB800B7D062682046E3681021D21ABDE8F840BF +:107DC800FFF7BCBE0A469CE77C0C002087D6120051 +:107DD800F8B504464FF4005242F209004FF48041CE +:107DE800D4F814C094F82BE0ACF580432261656A9E +:107DF8006160B3FBFEF303F18102D2095600A26071 +:107E08003044884214D94FF4C04100E03946C1EBF0 +:107E18000C0342F2090001F50057B3FBFEF303F12E +:107E28008102D209560030448842EFD86160A260CE +:107E38004FF6F472934208D8206A20B103681322DF +:107E480051495B6898470020F8BDA1F5005203FB33 +:107E58000E134E492046961BA3F500528B42B6B22C +:107E6800A26194BF0B230C2306F50052268584F8E3 +:107E78002A30E260FFF7EAFE0028E4D02046802797 +:107E8800FFF7B6FEA368022101224FF0060E29264D +:107E98006B6205F146033E48E96205F151012A8605 +:107EA8002022A5F832E085F8407085F84260C5F8D0 +:107EB800430003F8012F9942FBD14120542133227A +:107EC8003223462685F8530085F8541085F8526009 +:107ED80085F8552085F85630E069626A036821699B +:107EE8005B6A98470028AED0E069216903680631CB +:107EF800626A5B6A98470028A5D04FF40072002197 +:107F0800606A05F021FD234BE069C5F8FC31036880 +:107F180021695B6A0231626A9847002893D0E06958 +:107F2800216903680831626A5B6A984700288AD029 +:107F3800E3694FF0FF321848184928601846C5F819 +:107F4800E821C5F8EC21C5F8E4111B6821695B6AD2 +:107F58000131626A984700283FF475AFE0692169EA +:107F680003680731626A5B6A984700283FF46BAF81 +:107F7800A268204694F82B30202103EB4202BDE88A +:107F8800F840FFF7DBBD00BF7C0C00200004FB00BD +:107F980087D61200000055AA52526141727241619F +:107FA80038B504460D680846E16162622362EB69F0 +:107FB800984700F2FF736061DB0A062B236008D83C +:107FC800206A20B10368142226495B68984700207C +:107FD80038BD102B13D8022384F82B30B0F5800F4E +:107FE800204614D2FFF762FE0546206AADB108B3F9 +:107FF80003680D221C495B689847012038BD202B77 +:1080080014D9402B18D8082384F82B30E6E7FFF75B +:10801800DFFE0546206A002DE9D10028D7D0036885 +:108028000F2212495B689847284638BD042384F814 +:108038002B30D3E7012038BD802B06D9B3F5806FEC +:1080480007D8202384F82B30C8E7102384F82B3076 +:10805800C4E7B3F5004F94BF4023802384F82B3046 +:10806800BCE700BF900C0020A80C0020B80C002032 +:10807800042A0BD90A2A05D90C2A0CD801EB42028A +:10808800D088704701EB42029088704701EB4202AA +:10809800B2F8010070470020704700BFF0B50378C0 +:1080A80083B00D465BB113F060040DD0012A06D9E8 +:1080B8002F22002301200A704B7003B0F0BD00236B +:1080C80018462B7003B0F0BD21460192FEF790F9D7 +:1080D8000028F4D0214603464FF0080C2646019AA2 +:1080E8000FE0077B1CEA070F01D02034E4B2771CAD +:1080F800B646BA42E3D9FEB205F80E4001310C2962 +:108108000AD008291C780BD0A4F141070133192F94 +:10811800E7D9202CF2D0EAE700233046AB55D1E767 +:10812800202CF9D04FF0100C2E24E0E72DE9F04F69 +:108138004FF0000B8BB0037889468DF804B08DF8AA +:1081480005B08DF806B0002B61D0C3780546002B2A +:1081580064D0014601A81746FEF780FB002856D0D8 +:10816800E878002870D0013F4C464FF001084F4492 +:10817800A98801A8C8EB010189B24901FEF7B4FD3D +:10818800002844D0002101A8FEF76CFC0646002810 +:108198003DD0C37A0F2B3AD1037803F01F039845DB +:1081A80035D14FF0000A1CE000F510539BB2B3F52F +:1081B800806F2CD24FEA8B2B244BC0F309000BEABB +:1081C8000303184300F5803021463A4602F094FB39 +:1081D8000446E0B10AF1010A4FF0000BBAF10D0FA5 +:1081E8002AD05FFA8AF231462846FFF741FFBBF1F1 +:1081F800000FD9D100F520539BB2B3F5006F12D30D +:108208000028E1D1C9EB04000023237003E0002318 +:10821800184689F800300BB0BDE8F08FFFF73EFF35 +:108228000BB0BDE8F08FB3F5806FF0D20AF1010A08 +:108238008346BAF10D0FD4D108F10108EB785FFA43 +:1082480088F8434594D2DDE74C46DDE700FC0F0093 +:10825800FFF76CBF30B41468B4F5807F254628BF9B +:108268004FF4807501EB4500814207D231F8023B9B +:1082780013B95368013353608842F7D8641B1460FC +:1082880030BC704730B41468802C254628BF802540 +:1082980001EB8500814207D251F8043B13B95368BA +:1082A800013353608842F7D8641B146030BC7047B0 +:1082B8002DE9F843C37905460C461646202B06D00F +:1082C800102B1AD00C2B2FD00020BDE8F883037A8E +:1082D80000F50E70A969022B01EBD4110CBF032223 +:1082E800012202F043FA03460028EDD0A400012041 +:1082F80004F4FE741E51BDE8F883027AC1F3072125 +:10830800836900F50E70022A19440CBF032201226A +:1083180002F02CFA03460028D6D06400012004F4A9 +:10832800FF741E53BDE8F883C1F34E03027A8169D6 +:1083380000F50E7813FA84F3022A40469FB20CBF68 +:108348000322012201EB5729494602F00FFA0028BF +:10835800BAD014F00104C7F3080310D0C25C591C4A +:1083680002F00F02B1F5007F42EA0612C2540BD0A8 +:10837800C6F30716084406700120BDE8F8835A1CA6 +:10838800C654B2F5007F15D12B7A09F10101404698 +:10839800022B0CBF0322012202F0E8F9002893D037 +:1083A800360954B9035DC6F30316204423F00F03BE +:1083B8001E43E0E736091446F4E7F6B2DBE700BFF0 +:1083C800012972D92DE9F843C369994269D8C3795B +:1083D800174605460C46202B31D0102B41D00C2BCC +:1083E8005FD1C1F34E06037A816900F50E7816FA5B +:1083F80084F6022B4046B6B20CBF0222002201EBE3 +:108408005629494602F0B2F900284AD0C6F30806B0 +:10841800731C865DB3F5007F36D0C35CE20746EA7D +:1084280003234CBF1B11C3F30B03EA69934203D820 +:108438003B600120BDE8F8830020BDE8F883037A9B +:1084480000F50E70A969022B01EBD4110CBF0222B2 +:10845800002202F08BF920B3A40004F4FE7403593F +:10846800E3E7027AC1F30721836900F50E70022A57 +:1084780019440CBF0222002202F078F988B1640086 +:1084880004F4FF74035BD0E72B7A09F1010140463D +:10849800022B0CBF0222002202F068F908B1002367 +:1084A800BBE74FF0FF30BDE8F8834FF0FF3070476F +:1084B8002DE9F041C46882B005460F468C429046CB +:1084C80027D20C4600260134EB6901AA28469C42B3 +:1084D800214608D9C6B9EC68012601AA2846013404 +:1084E8009C422146F6D8A7420ED0FFF769FF002824 +:1084F8000ADBE8D0019B002BE5D106B1EC60012C2A +:1085080002D9EB699C4206D90026304602B0BDE884 +:10851800F0810126D7E76FF0704221462846FFF721 +:10852800C7FE06460028EFD05FB1012FECD9EB69F2 +:108538009F42E9D8394622462846FFF7B9FE002867 +:10854800E2D06B6A002B01DB013B6B62C8F800408C +:10855800DBE700BF01290BD910B4C469A14203D8D5 +:108568005DF8044BFFF7A4BE00205DF8044B70478C +:108578000020704770B5054682B00C460FE0FFF743 +:1085880097FE621EE0B16B6A002B03F10103A8BFDE +:108598006B62EB689C42019C38BFEA608EB1214651 +:1085A80001AA2846FFF70CFF012C0646C0F3C013AA +:1085B8002146284604D91A4613B9EB699C42DED9EC +:1085C800002002B070BD00BF436A002B01DB1846D3 +:1085D8007047F0B5C17985B005460C2924D0C36928 +:1085E800002490F838025A1C0394C3072C6902929D +:1085F80036D400204FF0FF33202905F5127285F894 +:108608003802C5F8443233D0286802AF1B4E2346DF +:108618000468A9698DE8C000A469A047C8B1039B94 +:108628006B62184605B0F0BDC7690137022F23D920 +:108638000224002605E002D0029B03B90136A742B6 +:108648000CD0214602AA28460134FFF7B9FE0028BB +:10865800F1DA4FF0FF33184605B0F0BD3346E0E7D6 +:1086680005F50E7002F0B2F80028F2D0E979C0E7FB +:10867800286802AF024ECAE70023D2E7156300005C +:1086880045630000F8B5044600234FF0FF3001268B +:1086980021601546E162C4F83C12E660E37184F893 +:1086A800283084F838326063C4F84402DAB1042A06 +:1086B80001D90020F8BD04F128061A4619463046AB +:1086C80002F054F86FF0704300F5DF712B441B0182 +:1086D800CA180028EDD010790028EAD0CB5C5B06D8 +:1086E800E7D1956801E004F12806304600222946C2 +:1086F80002F03CF80028DCD0B0F80B30B3F5007F6E +:10870800D7D1037C5A1E2372012AD2D8467B002374 +:10871800721E012E2671A371627149D001210A4689 +:1087280000E0194652004B1CD2B2DBB2964203D08D +:10873800092BF6D1A171BCE7A171C68A26610EB9D1 +:10874800466A2661C789B0F8113007EB050E6381C8 +:108758005B01C4F818E0077C03F2FF13B0F813209C +:1087680006FB07E707EB53232762636102B9026A36 +:10877800ED1A4FF0FF3340F6F4771544636225FA9B +:1087880001F35A1CBB42E26106D80C23E37126634D +:108798000120C4F84062F8BD4FF6F472934202D843 +:1087A8001023E371F3E7C26A20232262E371EEE744 +:1087B8001946C2E7F8B5002506460F4685638C6B57 +:1087C800C5638CB10146242000F0BAF805704570E5 +:1087D80004468570B063BD6B0FCD0FC40FCD0FC4B9 +:1087E8002B6823603046F8BDCB6B002BFAD00146CE +:1087F800382000F0A5F880F8314080F83240024671 +:1088080080F83340F063FB6B03F130011F681033CD +:1088180053F80C5C103253F8084C53F8040C8B4294 +:1088280042F8107C42F80C5C42F8084C42F8040C00 +:10883800ECD11B681360D5E710B50446806B28B1EE +:10884800FDF730FE10B10023A36310BDE06B28B123 +:10885800FBF702FD10B10023E36310BD002010BD3B +:10886800C9B32DE9F0410C46054698461746FFF76F +:10887800E3FFD4F88064AEB100262946242000F036 +:108888005FF8434606703A4646708670A863D4F887 +:108898008014FDF7DBFF10B10120BDE8F081A8636B +:1088A800BDE8F081D4F88434BBB12946382000F003 +:1088B80047F8434680F831603A4680F8326080F8DD +:1088C8003360E863D4F88414FCF71EF90028E3D178 +:1088D800E863BDE8F081002070470020BDE8F08122 +:1088E800F8B50D4617460446FFF7A6FFAE6B8EB1E6 +:1088F8002146242000F024F800213A4601704170F6 +:108908008170A063A96BFEF7B3FA08B10120F8BD26 +:10891800A063F8BDE86B88B12146382000F010F854 +:108928003A4680F8316080F8326080F83360E0635E +:10893800E96BFCF7F1F80028E8D1E063F8BD00BF67 +:10894800084670472DE9F041044600261F464FF4BB +:108958009060C4F888142146C4F880649046FFF7F4 +:10896800EFFF3A4680F84464054680F8796480F859 +:108978007A6480F87B64C4F88404D4F88814FDF71A +:108988002FFC08BB0026214640F26C40C4F88464E2 +:10899800FFF7D6FF0223C6713A4680F848640546B9 +:1089A80080F8496480F84A640372C4F88004D4F8F3 +:1089B8008814FFF767FEF0B90023194A1846C4F86F +:1089C80080341360BDE8F08105F589663046FBF711 +:1089D80043FC29463046FBF76DFC0028D2D0114BEA +:1089E8001A68BAB10E4BB8F1000F15D11A689AB1CE +:1089F8000120BDE8F08105F589663046FDF752FD96 +:108A080029463046FDF746FF0028D5D0064B1A68A0 +:108A1800002AE7D11D60E5E71C600120BDE8F08170 +:108A2800C421002090210020C8210020F8B500258D +:108A38004FF47A77064E044687600571057385649E +:108A4800C56440F8106BFFF70BFF2046F8BD00BF68 +:108A5800FC050020407C7047007D7047407D7047D2 +:108A680001207047007F704710B4046801236469CF +:108A7800A4465DF8044B604738B5036804460D46C4 +:108A88001B6A984700B1257738BD00BF2DE9F0472C +:108A98001E46C37C05460C46022B9146089F23D0F0 +:108AA8002B68214628461B6E984798B1AC61B9F1EE +:108AB800000F12D004EB090801E0A0450DD039469B +:108AC8002046B0472B6801462846DB6D013498479D +:108AD8000028F2D10020BDE8F087AB69287F4B441D +:108AE800AB6128B1BDE8F08783698B42D8D1DEE756 +:108AF8002B6828465B6EBDE8F0471847704700BFF3 +:108B0800043001F0BDBD00BF10B50446202104F0BB +:108B180063F9204610BD00BF2DE9F0411F46C37C14 +:108B280006460D46022B14461FD0336829463046A8 +:108B38001B6E984778B1B56187B1002501E0AF4257 +:108B48000CD03368214630460135DB6D04F50074DE +:108B580098470028F3D10020BDE8F081B369307F41 +:108B68001F44B76128B1BDE8F08183698B42DCD12D +:108B7800E2E7336830465B6EBDE8F041184700BF56 +:108B880038B5051D0446284601F0B2FC207C0021BA +:108B980001F0ACFC2846FF2101F092FD0123A374EB +:108BA80038BD00BF03685B6E184700BF38B5051DA8 +:108BB80004460121007C01F099FCFF21284601F0C0 +:108BC8007FFD284601F030FD0023A37438BD00BFA7 +:108BD800F8B5164E0746051D346804F51674A4B298 +:108BE80003E03368E31A1B040ED4284601F04CFD59 +:108BF800FF28F6D12846FD2101F062FDBB7C6BB948 +:108C080000230120FB74F8BD1E23B87C7B7400B9D7 +:108C1800F8BD3846FFF7CAFF0020F8BD3846FFF711 +:108C2800C5FF00230120FB74F8BD00BFF02700201A +:108C380038B5C37C012B16D0837C044663B9FFF793 +:108C48009FFF201D01F020FDA37CB0F1FF0518BF98 +:108C5800012553B9284638BD043001F015FDFF3809 +:108C680018BF012038BD002038BD2046FFF79EFF01 +:108C7800284638BD2DE9F041036882B0064688468B +:108C880001921B6A984718B9FF2002B0BDE8F0812D +:108C9800B37C002B3ED0B8F10C0F3FD0204F341DD1 +:108CA8003D6805F59675ADB203E03B68EB1A1A040A +:108CB8002CD4204601F0E8FCFF28F6D148F040010A +:108CC800204601AF02AD01F0FBFC15F8011D20465E +:108CD80001F0F6FCAF42F8D1B8F1000F20464FF092 +:108CE8000A0514BF8721952101F0EAFC204601F00E +:108CF800CBFC204601F0C8FC03063075C5D5013D04 +:108D0800ADB2002DF5D102B0BDE8F081B8F1000F89 +:108D1800BAD1D3E73046FFF733FFBCE7341DCDE7C0 +:108D2800F02700202DE9F04788B000250646071DEA +:108D380001AC85744574457584E80E009DF80400FF +:108D4800DDF80880307401F0CDFB307C012101F0A2 +:108D5800CDFB5949072205ABB160F26094E80700E2 +:108D680083E8070038460ECB01F044FCB37CF57469 +:108D7800002B67D00121307C0A2401F0B7FBFF21CA +:108D8800384601F09DFC611E11F0FF04F7D1214621 +:108D9800307C0A2501F0AAFB002230461146FFF775 +:108DA80069FF0128044605F1FF330DD013F0FF05D4 +:108DB800F2D101237374B07C18B13046FFF7F6FE88 +:108DC800002008B0BDE8F0874FF4D572082130467E +:108DD800FFF750FF420739D574753368DFF8E0A014 +:108DE8009B6D534545D1707D344D02282C680CBFCE +:108DF8004FF080494FF0000904F5FA64A4B203E08B +:108E08002B68E31A1B0431D4002237213046FFF7C0 +:108E180031FF4A4629213046FFF72CFF0028EFD1C1 +:108E280033689B6D534527D1707D022827D0B37CCA +:108E380013B13046FFF7BAFE0723C6F808800120B1 +:108E4800F360BEE73046FFF79BFE93E70223042456 +:108E58007375384601F018FC631E307513F0FF0473 +:108E6800F7D1AA28B9D006237374A4E7172373741B +:108E7800A1E730469847B7E730469847D5E700223C +:108E88003A213046FFF7F6FE10B11223737492E7C9 +:108E9800384601F0F9FB00F0C000C02809D0384678 +:108EA80001F0F2FB384601F0EFFB384601F0ECFB2D +:108EB800BDE703237375F2E7801A0600F027002048 +:108EC8001D6B0000F8B500220D463A210646FFF753 +:108ED800D1FE68B9371D2C1D384601F0D5FB04F8C2 +:108EE800010DA542F8D1B47C6CB901242046F8BD27 +:108EF8001223B47C7374002CF8D000243046FFF79A +:108F080055FE2046F8BD3046FFF750FE2046F8BD16 +:108F180003680A4630B59B6D83B0114D0446AB42D9 +:108F280014D1407D03284FF01901204618BF520282 +:108F3800FFF7A0FE28B10E23A07C637450B903B0DC +:108F480030BD02230120E37403B030BD019198477E +:108F5800019AE7E72046FFF729FE002003B030BD5D +:108F68001D6B00002DE9F8431A4E054688469146C8 +:108F78003468071D04F59674A4B203E03368E31A55 +:108F88001B0411D4384601F07FFBFF282875F5D063 +:108F9800FE280CD018236B74A87C18B12846FFF75C +:108FA80005FE0020BDE8F8831D236B74F4E74A46EC +:108FB8004146384601F074FB287510B125236B74BF +:108FC800EAE7384601F060FB384601F05DFB012016 +:108FD800BDE8F883F027002038B51546002204467E +:108FE800FFF748FE40B11B236374A07C18B12046EC +:108FF800FFF7DCFD002038BD294610222046FFF788 +:10900800B1FF0028F1D0A57C002DF4D02046FFF751 +:10901800CDFD284638BD00BF0A460921FFF7DCBF51 +:109028000A460A21FFF7D8BF0368244ADB6C93423B +:1090380030B585B02FD16A460921FFF7CDFF38B189 +:109048009DF8003013F0C00304D0402B26D0002038 +:1090580005B030BD9DF809409DF806309DF8072001 +:1090680004F003049DF80A0003F0030364009DF86C +:10907800051092009DF8085044EAD01001F00F0145 +:1090880042EA8323084443EA95130738013303FA75 +:1090980000F005B030BD69469847D0E79DF8093023 +:1090A8009DF807105A1C9DF8080001F03F0302EBD9 +:1090B800034303EB0020800205B030BDD9700000E7 +:1090C80003682DE9F041DB6C84B0324C05460F464D +:1090D8001646A3422ED16A460921FFF77DFF0446B2 +:1090E80084B19DF80A305A0616D56B7D032B01D042 +:1090F8007F0276023A4620212846FFF7BBFDE8B1F9 +:1091080026236B74AC7C1CB128460024FFF74EFD67 +:10911800204604B0BDE8F08103F03F039DF80B1032 +:10912800721C5B003A4343EAD1131342DDD0272374 +:109138006B74E7E7694698470446D1E73246212130 +:109148002846FFF797FD0028DAD10246262128464F +:10915800FFF790FD0028D3D10F4F42F2107605F1AA +:1091680004083B681E44B6B203E03B68F31A1B04CC +:109178000CD4404601F088FAFF28F6D1AB7C002BCE +:10918800C6D028461C46FFF711FDC1E728236B749B +:10919800B8E700BFD9700000F027002003680A462E +:1091A80030B59B6D83B0114D0446AB4214D1407D60 +:1091B80003284FF01201204618BF5202FFF75AFD4C +:1091C80028B10C23A07C637450B903B030BD0123CF +:1091D8001846E37403B030BD01919847019AE7E758 +:1091E8002046FFF7E3FC002003B030BD1D6B0000F4 +:1091F80070B500260C210446C6743246FFF73AFDC6 +:1092080028B10923A57C63745DB9284670BDA57C87 +:1092180015B90125284670BD2046FFF7C7FC28462A +:1092280070BD35462046FFF7C1FC284670BD00BF1B +:10923800C37C022B05D0012B01D001207047FFF71A +:10924800D7BFFFF7AFBC00BF2DE9F0479A46C37CF4 +:1092580006460C46012B1546DDF82080099F24D0D0 +:1092680021463046FFF79AFFA8B1B461BAF1000F62 +:1092780014D004EB0A0904E020460134C047A14594 +:109288000CD04FF4007229463046FFF76BFE3A4681 +:1092980029460028F0D10020BDE8F087B369307F67 +:1092A8005344B36128B1BDE8F08783698B42D7D1B5 +:1092B800DCE73046BDE8F047FFF79ABFF8B51F4630 +:1092C800C37C06460D46012B14461CD02946304661 +:1092D800FFF764FF78B1B5617FB1002501E0AF42C7 +:1092E8000BD04FF400722146304601351444FFF785 +:1092F80039FE0028F3D10020F8BDB369307F1F4440 +:10930800B76120B1F8BD83698B42DFD1E4E730460D +:10931800BDE8F840FFF76CBF70B5041D164605465A +:10932800204601F0CDF94FF400723146204601F095 +:10933800D1F92046FF2101F0C3F92046FF2101F0B1 +:10934800BFF9204601F0A0F900F01F032875052B8E +:1093580009D02023A87C6B7400B970BD2846FFF79C +:1093680025FC002070BD012070BD00BF2DE9F04133 +:10937800144D07468846061D2C6804F51674A4B2D9 +:1093880003E02B68E31A1B040ED4304601F07CF985 +:10939800FF28F6D14246FC213846FFF7BDFF70B9D9 +:1093A800B87C30B9BDE8F0812423B87C7B740028F0 +:1093B800F8D03846FFF7FAFB0020BDE8F081BDE899 +:1093C800F08100BFF0270020036870B59B6D82B064 +:1093D800154D04461646AB4222D1407D032820464F +:1093E80018BF49020A461821FFF744FC48B10D236B +:1093F8006374A07C18B12046FFF7D8FB002002B0A8 +:1094080070BD3246FE212046FFF786FF0028F0D0C7 +:10941800A57C002DF3D02046FFF7C8FB2846EEE7D1 +:10942800019198470199D9E71D6B000010B4047F9A +:109438001CB95DF8044BFFF7C7BF04680123A46A91 +:10944800A4465DF8044B604730B585B0054601ACCD +:1094580084E80E0094E80E00FFF764FC20B19DF844 +:10946800053003F001032B7705B030BD704700BF0E +:10947800084B0021084A094810B499631C6B146012 +:1094880012685DF8044B1A639A6C22F081029A64A0 +:109498000170704700002C4084210020072800201C +:1094A800034B04481B6B1840B0FA80F04009704722 +:1094B80000002C4001000F00024B586A00F0010028 +:1094C800704700BF00002C40034B586A80F0807042 +:1094D800C0F30060704700BF00002C40014B1878B3 +:1094E800704700BF07280020034B586A80F40060CB +:1094F800C0F3C020704700BF00002C40034B586ADF +:1095080080F48060C0F38020704700BF00002C40CA +:10951800034B04481B6B1840B0FA80F040097047B1 +:1095280000002C4002007F114FF47A722B4B2C491B +:1095380002FB00F0496AD3F800212A4BC1F3C2218B +:1095480002F03F020131A3FB0223F0B49B08264D31 +:10955800B5FBF3F5B5FBF1F5B0EB151F38D20122D9 +:1095680001E0FF2A05D852001301B5FBF3F3984236 +:10957800F7D351080F02B5FBF2F398422BD25400EF +:10958800012100E01C464E1CB5FBF4F3984202EBA7 +:1095980004031BD2102E3146F4D1F0234FF47A7213 +:1095A800124E134902FB04F412483246B5FBF4F597 +:1095B8000D60F16A084040F4602040EA0701194351 +:1095C800F162536A1B07FCD5F0BC70470B01E5E755 +:1095D80000270122CFE714460023DFE700800D4073 +:1095E80000C00F40ABAAAAAA00EC695E00002C409C +:1095F800382100200F00F0FF014B1878704700BF9A +:1096080016160020014B1868704700BF84210020FF +:1096180030B4054C0D460FCC286001206960AA6063 +:10962800EB6030BC704700BF5021002030B4054CBF +:109638000D460FCC286001206960AA60EB6030BC41 +:10964800704700BF60210020024B01201B680B609F +:10965800704700BF70210020704700BFF8B505466D +:10966800074F02F007F8064604E002F003F8801BF3 +:10967800B84203D8A84704460028F6D12046F8BDCA +:1096880040420F002DE9F041DFF8408005460E4FBB +:10969800C8F8000001F0EEFF064606E001F0EAFF18 +:1096A800801BB8420AD803F0ADFBA847044600283F +:1096B800F4D1C8F800002046BDE8F0810023204618 +:1096C800C8F80030BDE8F08140420F00802100203A +:1096D80010B504460C2103F07FFB204610BD00BFE7 +:1096E8000F4B002247F2B80141F2B800C3F8CC2171 +:1096F800C3F8D021C3F8BC21C3F8C021C3F8C421E2 +:10970800C3F8C821C3F8BC13C3F8C013C3F8AC131B +:10971800C3F8B003C3F8B413C3F8B813704700BF55 +:1097280000801F40054B1B7833B1054B1B78002B7D +:1097380014BF03200220704701207047032800202F +:109748000428002038B5044614480D46FFF786FF64 +:1097580008BB134BA1029D6007D5996CE2B221F0BA +:10976800FF019964996C0A439A6424F0FF040C4D34 +:109778000C48EC60FFF772FF68B92A6B0A4B1A6055 +:109788001A682A631A68D20705D51B6813F4702F64 +:1097980001D1012038BD002038BD00BF7975000017 +:1097A80000002C40617500008421002008B5074B9B +:1097B80007481968FFF7C6FF30B1064B186980F4EF +:1097C8008070C0F3002008BD012008BD742100206E +:1097D80000001A0D00002C4008B5044B0448196815 +:1097E800FFF7B0FF08B1034B186908BD74210020CA +:1097F80000001A0D00002C40144B70B50E4684B0C2 +:109808001968FFF79FFFF0B1114906F10F05002312 +:109818000A6900924C6901948C690294C9690391A0 +:1098280001E054F8102C03F003010133C90023F0C0 +:1098380003040F2B22FA01F204A905F8012D0C44A8 +:10984800EFD10023F37304B070BD00BF7421002072 +:1098580000002C40054B186810F0020005D01B686A +:1098680003481840B0FA80F040097047842100206E +:1098780000007F11F8B512F0030418BF0124002B73 +:1098880008BF44F0010444B11E4925201E4B40F294 +:10989800F51208701A600020F8BD06461B481D46E0 +:1098A8000F461446FFF7EEFE10BB2B04184A194D5D +:1098B8004FF0010E1A40184985F800E0174B42F4A2 +:1098C80000720860164D17491C605A609D630B783A +:1098D800B3B979023046FFF735FF0028DBD01248CC +:1098E800FFF7D0FE0028D6D1BDE8F840FFF7B2BF99 +:1098F80004490A20044B4FF4FC7208701A60CAE746 +:109908003946E7E716160020402100206D78000050 +:109918000000FF1F072800208421002000002C40A1 +:1099280002007F11042800209D750000194970B4B9 +:109938000B7813F0C00311D0402B02D0002070BC6C +:1099480070474B7ACC795A1C087A04F03F0302EB33 +:10995800034303EB002070BC800270474D7A8B797B +:10996800CA7905F00305887A03F003036D004C7982 +:1099780092000E7A45EAD01004F00F0142EA8323E0 +:10998800084443EA96130738013370BC03FA00F021 +:10999800704700BF60210020037ADB0703D50E4B18 +:1099A8001B6893B118470D4B1B7833B90C4B586A99 +:1099B80080F08070C0F300607047094B09481B6B4A +:1099C8001840B0FA80F040097047074B1878002813 +:1099D800F2D0FFF7EBBE00BF802100200528002051 +:1099E80000002C4002007F11022800202C4838B5C6 +:1099F800837A154603F040025AB903F03F0302F098 +:109A0800FF04C27A681C5B00084343EAD21303428E +:109A180021D1244B1B780BB949026D022248FFF76C +:109A280091FE044640B921490F20214B40F2EB2218 +:109A380008701A60204638BD29461E48FFF782FE86 +:109A4800044688B919491020194B40F2EE220870D3 +:109A580020461A6038BD15492720154B40F2E322ED +:109A6800087020461A6038BD00211348FFF76AFEC7 +:109A7800044638B90D4911200D4B40F2F122087007 +:109A88001A60D7E70D48FFF7E9FD0028D2D007494B +:109A98002820074B4FF43D72002408701A60C9E76C +:109AA800602100200428002000001A20161600203B +:109AB8004021002000001A2100001B266D780000BC +:109AC80010B50E480024FFF7C9FD0D490D4A0E4B8D +:109AD8000C70116B19601968116318B91A680B4B6F +:109AE800134043B10A491F240A4B40F27A2200204E +:109AF8000C701A6010BD012010BD00BFD1750000A8 +:109B08000528002000002C408421002000007F113F +:109B1800161600204021002038B5184C002118489E +:109B2800A36A23F48033A362FFF70CFE054640B90D +:109B380014490920144B40F23D2208701A60284647 +:109B480038BD1248FFF79EFD70B9636A9B07F6D5CA +:109B5800616B2846A36AE26A23F4803342F080628C +:109B6800E2626163A36238BD06490A20064B4FF4DE +:109B78001072002508701A60284638BD00002C4075 +:109B88000000DB0C1616002040210020897500001B +:109B980070B51E4E0D463378002B31D11C4B5A6AD6 +:109BA800D10507D49A6A22F480329A629A6A42F4FA +:109BB80000329A62164C1748A36A43F48033A362B2 +:109BC800FFF74CFD98B920462B1F05F5FE74426A35 +:109BD8005205FCD503F1400153F8042F9942026263 +:109BE800FAD18C420B46F2D10120307070BD0A497F +:109BF80021240A4B40F2D93200200C701A6070BD43 +:109C0800FFF75EFF0028C9D170BD00BF05280020FE +:109C180000002C40BD7500001616002040210020D1 +:109C280010B514480C46FFF72DFDC8B9124B4FF478 +:109C3800007012499A6A22F480329A6258600B784E +:109C480063B961020E48FFF77DFD30B90D490E2456 +:109C58000D4B4FF487620C701A6010BD2146F1E776 +:109C680008490A20084B40F22C42087000201A606C +:109C780010BD00BF6D78000000002C4004280020B3 +:109C880020003A191616002040210020F8B5064693 +:109C9800007A0C461546C0071F4613D483B10F44FB +:109CA80001E0BC420CD033682A46214630465B6A44 +:109CB80005F50075013498470028F2D10020F8BD59 +:109CC8000120F8BD900712D0002BF9D00F4401E015 +:109CD800A742F5D033682A46214630465B6A05F527 +:109CE8000075013498470028F2D10020F8BD0648D5 +:109CF800FFF7C0FD0028E3D104490E24044B40F2CD +:109D08001E420C701A60F8BD27003A19161600207A +:109D18004021002070B5037A1546ADF5007D0E464A +:109D2800DA0719D5AB0706D029464FF40072684602 +:109D38006D4601F03DFA2A46314601232148FFF7D6 +:109D480099FD30B920490D24204B40F2F2320C70B5 +:109D58001A600DF5007D70BD1D4B04461B78ABB92C +:109D6800637A022B08D0236820461B6A984798B963 +:109D780000200DF5007D70BD63689E4216D02368F3 +:109D880020461B6A98470028F2D005E0FFF798FEA6 +:109D98000028E5D10020ECE72368314620461B6EF9 +:109DA80098470028E4D00223666063722368294636 +:109DB8002046DB6D98470028DAD06368013363607A +:109DC800C7E700BF01003A181616002040210020FE +:109DD80005280020F8B50646007A0C461546C00747 +:109DE8001F4613D483B10F4401E0BC420CD0336842 +:109DF8002A46214630461B6905F500750134984707 +:109E08000028F2D10020F8BD0120F8BD900712D03B +:109E1800002BF9D00F4401E0A742F5D033682A4659 +:109E2800214630461B6905F500750134984700281E +:109E3800F2D10020F8BD0648FFF71CFD0028E3D149 +:109E480004490C24044B40F282320C701A60F8BDAD +:109E580037003A121616002040210020F8B50546B2 +:109E68001B480C46FFF7FAFB40B11A490A201A4B67 +:109E78004FF4CC72087000201A60F8BD174A012709 +:109E8800174B29461770174E174D184A30601C603B +:109E980017485D609A63FFF755FC38B90D490424EB +:109EA8000D4B40F29F120C701A60F8BD1148FFF775 +:109EB800E9FB18B9FFF7CEFC00B1F8BD054925202C +:109EC800054B4FF4D172087000201A60F8BD00BF2E +:109ED8006D78000016160020402100200728002079 +:109EE80000002C40842100204000010002007F1166 +:109EF80011003A069D7500002DE9F043B74A00238A +:109F0800B74D0524017291B02B704372D2F800014D +:109F1800B44F40F08000B44EDFF834833B703370A8 +:109F280088F80030C2F80001D2F80001AF4B20F0E9 +:109F38003F00AF49C2F80001D2F8000140F0180014 +:109F4800C2F80001D2F8000120F08000C2F8000138 +:109F5800D3F88020A74842F00C02C3F880205A6A40 +:109F680022F460525A62DA6942F48032DA615A6A3B +:109F780042F400625A620246C1F8CC41C1F8D041AD +:109F8800C1F8BC41C1F8C041C1F8C441C1F8C841D9 +:109F9800816C994B41F000418164C16A0B43C362F3 +:109FA800D36A944CD901FBD44FF4C870FFF7BCFABC +:109FB800FFF796FB9149924B924A6163C3F8F821E7 +:109FC800914B6020914A4FF48041187023461160EC +:109FD800E26A42F00062E262D96A11F00061FBD1E4 +:109FE8000846FFF7AFFB044600284DD003244FF482 +:109FF800D5718748FFF7A6FB00285CD1013CF6D154 +:10A0080098F80030834C002B08BF4FF4401401F03F +:10A0180031FBDFF84082814600217F48FFF792FB41 +:10A0280050B917217D4B40F29F22002429701A60F5 +:10A03800204611B0BDE8F08321467948FFF782FB3E +:10A048000028EED001F016FBC9EB0000694A404534 +:10A05800E7D81369002BDFDA1169724B19601369AD +:10A068005A0001D50123337000216F48FFF76AFBBE +:10A07800044698B90221694B4FF42A722046297088 +:10A088001A6011B0BDE8F0830121644B40F28E22C2 +:10A09800204629701A6011B0BDE8F083002163489A +:10A0A800FFF750FB0446C0B903215C4B40F2AB22DA +:10A0B80029701A60BCE74F4B1B69B3F5D57F07D0F1 +:10A0C8000621564B4FF42572002429701A60AFE719 +:10A0D8000123504C88F8003099E7464E544B3269BA +:10A0E800DFF87481134053495348C8F80030FFF72C +:10A0F80083FB044630B90721484B4FF42C72297072 +:10A108001A6095E74D494E48FFF776FB044630B98B +:10A118000821424B40F2B32229701A6088E7D8F828 +:10A1280000104848FFF70EFB044630B905213B4BA9 +:10A1380040F2B62229701A607AE7D8F8001036483B +:10A14800FFF700FB38B91421344B40F2BA2200243F +:10A1580029701A606CE702213B48FFF7F3FA0446BE +:10A168000028F0D0B36A4FF010126FF07F406946B4 +:10A1780023F00603B362B36A43F00203B362726466 +:10A18800FFF76CFE18B19DF80D309B0716D446F208 +:10A19800A810174B0522C3F8CC21C3F8D021C3F867 +:10A1A800BC21C3F8C021C3F8C421C3F8C821FFF7F4 +:10A1B800BBF9FFF795FA01233B7039E76946234855 +:10A1C800FFF74CFE0028E2D09DF8103003F00F0393 +:10A1D800012BDCD14CF25030DBE700BF00800D4092 +:10A1E80016160020022800200428002000C00F4076 +:10A1F80000801F4000002C40008000010B007F11F0 +:10A2080000180020317500006EE400E00CE100E069 +:10A2180000001A080000304000001A3740210020D2 +:10A2280000000229702100200000090200001A0322 +:10A238000000FFFF602100200000090950210020D4 +:10A248000000090A00001B0700001A06F1FFFF8042 +:10A258000328002040420F007421002038B5274B06 +:10A268000D465A6A94050DD49A6A22F480329A628D +:10A2780072B69A6A42F400329A629A6A42F480325A +:10A288009A6262B61E48FFF7E9F900282DD12B1F04 +:10A298001A4905F5FE754A6A1005FCD503F1400018 +:10A2A8000A6A164C43F8042F9842F9D185420346AE +:10A2B800F1D11448FFF7D2F970B9226B124B1A602A +:10A2C8001A6822631A68920717D51B680F48184046 +:10A2D800B0FA80F0400938BD0D491D200D4B40F201 +:10A2E8004232087000201A6038BD09491A24094B07 +:10A2F80040F2373200200C701A6038BD00002C4044 +:10A30800A9750000D17500008421002000007F118C +:10A31800161600204021002010B514480C46FFF7FF +:10A32800B1F9C8B9124B4FF4007012499A6A42F455 +:10A3380080329A6258600B7863B961020E48FFF761 +:10A3480001FA30B90D490C240D4B40F29E320C70C5 +:10A358001A6010BD2146F1E708490A20084B40F26F +:10A368009232087000201A6010BD00BF6D7800009E +:10A3780000002C400428002030003A121616002055 +:10A388004021002070B5037AADF5007D1546DC0745 +:10A3980011D5930720D0012329486A46FFF76AFAA6 +:10A3A80000B3694628464FF4007200F001FF01200F +:10A3B8000DF5007D70BD234B04460E461B7833BB5C +:10A3C800637A012B19D0236820461B6A984720BB63 +:10A3D80000200DF5007D70BD01231948FFF74AFAEA +:10A3E8000028E4D10B201849184B40F25532087068 +:10A3F80000201A600DF5007D70BD63689E4215D07F +:10A40800236820461B6A98470028E1D005E0FFF73B +:10A4180057FB0028D4D10020DBE731462046FFF760 +:10A428007BFF0028D4D0012366606372294620464A +:10A43800FFF714FF0028CBD0636801336360D9E7C6 +:10A4480011003A110528002016160020402100208E +:10A4580070B5144A00250E4645722946936A12487B +:10A4680023F480339362FFF76DF9044688B10EB97F +:10A47800204670BD0D48FFF705F90028F8D02C4696 +:10A488000B490A200B4B4FF46E72087020461A6075 +:10A4980070BD07490920074B4FF46D7208702046BC +:10A4A8001A6070BD00002C400000DB0C89750000AC +:10A4B8001616002040210020094B1B7810B50446D1 +:10A4C8004BB9637A0BB9012010BD20460121BDE8C4 +:10A4D8001040FFF7BDBFFFF7F3FA0028F1D110BD18 +:10A4E80005280020012101F037B900BF01F028B983 +:10A4F8000368416830B4DA7C8468002A28D072B6D0 +:10A50800DA7CD50706D533485A6905682A409A6225 +:10A518000260DA7C900706D52F489A6905682A40B8 +:10A52800DA620260DA7C550706D52C48DA690568D4 +:10A538002A401A630260DA7C100706D528481A6A8E +:10A5480005682A405A630260DA7CD2062BD462B6C8 +:10A558009A688A422ED0234A996092692248C2F3A7 +:10A568000115C2F3826250F825000132B0FBF2F007 +:10A57800B9B1B0FBF1F242B1B0FBF2F0884288BF4A +:10A588000132B2F5817F17D3184ADA601B680025BB +:10A59800032001211D6158621A641C66196130BCD0 +:10A5A80070470246E7E712485A6A05682A409A63E4 +:10A5B8000260CCE7DA68E9E7022A98BF0022E4D90A +:10A5C800023A5008010442EA002201F47F010A43DA +:10A5D800DBE700BF80E100E084E100E088E100E023 +:10A5E8008CE100E000C00F4038070020FF7F7F00AB +:10A5F80090E100E000B585B00DF1100E0EE90E00F7 +:10A60800039B33B10360184605B05DF804EB00F016 +:10A6180007BB044A13460260184605B05DF804EB10 +:10A6280000F0FEBA6C1100200268D37CE3B1D807B1 +:10A6380003D50E4B916A1960D37C990703D50C4B4F +:10A64800D16A1960D37C580703D50A4B116B19607E +:10A65800D37C190703D5084B516B1960D37CDB06F3 +:10A6680002D5926B054B1A60704700BF00E100E00D +:10A6780004E100E008E100E00CE100E010E100E0A6 +:10A68800006800F0E9BB00BF0268FF231268536648 +:10A69800D36D13F4F81FFBD0506FC0B2704700BFE2 +:10A6A80070B50C4616460546FF21204603F04CF9C6 +:10A6B800286833462246214600F0CAFB002070BDB8 +:10A6C80003681A685166D36D13F4F81FFBD0536FF3 +:10A6D800704700BF30B5551EADF5017D1346B5F581 +:10A6E800007F10D362B10268C818126811F8013BE4 +:10A6F8005366D36D13F4F81FFBD08142536FF5D125 +:10A708000DF5017D30BD14460546684600F050FD44 +:10A7180023466A466946286800F09AFB0DF5017DD4 +:10A7280030BD00BF70B50446406804F110060368E8 +:10A73800E16832465B6A984740B1237805469A0734 +:10A7480007D423F001032846237070BD002528464E +:10A7580070BD60683246A168E668036831445B6A88 +:10A7680098470028F2D02378EBE700BFF8B5436894 +:10A77800FBB1C368044615460F468B420ED00378DA +:10A78800DA0712D46B0716D504F11006002205F07B +:10A7980003053046E76015432570F8BD10F9102B06 +:10A7A80005F0030515432570F8BDFFF7BBFF00282A +:10A7B800E8D10020F8BD606804F110063946036846 +:10A7C80032461B6998470028E0D1F2E70378DB0797 +:10A7D80001D401207047FFF7A5BF00BF10B4034B99 +:10A7E800002414705DF8044B1B6818478C21002066 +:10A7F800024A0349034B1160186070478821002002 +:10A808009D8800008C2100208389B3B94268816843 +:10A818008A4201D31846704710B582B004461046E4 +:10A8280001AA00F0B9F860B1019A6060B2F5803F02 +:10A838000AD293B2184602B010BD0022828118468F +:10A8480070474FF6FF73F5E7930AC2F30902A3F5C1 +:10A858002153A2F510529BB2A281EBE7B1F5807F9C +:10A8680070B41DD810293FD840232026B2FBF3F13D +:10A87800B1F5806F1DD203FB11238C08C9B224F0F7 +:10A888003F048170B2FBF6F506FB1522B3FBF6F325 +:10A898000132DBB222430370D2B270BC42707047FF +:10A8A8003F231E4680290CD9B1F5FC7F0BD81B012C +:10A8B800DCE7FF21FE230A4603708170427070BCFA +:10A8C8007047DB00D2E7B1F57C7F04D9B1F5FC6FA6 +:10A8D80003D89B01CAE75B01C8E7B1F57C6F94BF59 +:10A8E800DB01C3EB0323C1E7202902D880232026FC +:10A8F800BCE720231E46D5E77F28A2EB010230B42F +:10A9080005D8002A44D00870481C30BC7047B0F500 +:10A91800006F0FD2012A3DD9840900F03F030A468F +:10A9280064F03F0063F07F0302F8020B10464B709F +:10A9380030BC7047B0F5803F12D2022A2AD9040BE6 +:10A94800C0F3851200F03F03C81C64F01F0462F0D6 +:10A958007F0263F07F030C704A708B7030BC7047C5 +:10A96800032A17D9850CC0F30534C0F3851200F00B +:10A978003F0065F00F0564F07F0460F07F0362F02C +:10A988007F020D70081D4C708A70CB7030BC704708 +:10A998001046BAE70020B8E788423BD2034630B4F5 +:10A9A8000478200603D41460581C30BC704704F0A7 +:10A9B800E000C02830D004F0F000E02823D004F0F4 +:10A9C800F800F0281CD104F0070404201844814240 +:10A9D80016D3591C11F8013B03F0C00503F03F03DF +:10A9E800802D43EA84140BD18142F3D1A4F1800174 +:10A9F8000B4B994204D8A4F55843B3F5006F06D21F +:10AA0800002030BC704704F00F040320DEE7146018 +:10AA180030BC70470020704704F01F040220D5E7BF +:10AA28007FFF10007E2808D8A0F16103192B8CBF86 +:10AA380000232023C01A80B2704730B40023352485 +:10AA4800234D04E035F82120824234D80B46E21A1F +:10AA5800012A03EB5201F5D89BB21D4935F8232092 +:10AA6800904218D24B2400231A4D04E035F82120D7 +:10AA7800824222D80B46E21A012A03EB5201F5D88A +:10AA88009BB2144A35F82310814202D102EB8303AA +:10AA9800588830BC704701EB8303821AD9788A4200 +:10AAA800E0DA93F90230012B0CD043B19BB2184481 +:10AAB80030BC80B270470C46C9E70C46DBE74EF263 +:10AAC800A033F4E702F00102801A80B2E1E700BF88 +:10AAD800B00300208402002010B4047F4160022CDF +:10AAE800C26003D05DF8044B02F006B883685DF8D5 +:10AAF800044B184770B440F20125046825611BB364 +:10AB08001E46F1B10D780131013B6566256FAD0731 +:10AB180006D4656F013EEDB212B1157001320468BA +:10AB28006569ED07F2D5002BEBD16EB101680B6FAB +:10AB38009B07FCD44B6FDBB20AB113700132013EA4 +:10AB4800F3E790F83C50DFE770BC7047F0B5304C45 +:10AB5800304BA06C656C0179226CD977297919770B +:10AB680001791977FAB1B2F5004F18D22B6892B271 +:10AB7800D98B0E043BD4DA83D98B89B2D982036886 +:10AB8800D98B09042CD4DA830021DA8B92B2DA82C9 +:10AB9800216402791F4BDA762A79DA76F0BD1E4BEA +:10ABA80013442364F5E7E06C0F25236840F2013E67 +:10ABB80001684FF47C579D6503260D681749DA61D3 +:10ABC8008D42C3F810E05F6184F83D6017D1037FC0 +:10ABD8004260022BC26017D0BDE8F04001F08CBF84 +:10ABE800D98BC2F3080201F47E410A43CBE7D98B23 +:10ABF800C2F3080601F47E413143D983BCE72B46F2 +:10AC08001146BDE8F04018478368BDE8F040184792 +:10AC18006C11002000800E400180FFFF998B00001E +:10AC28004368F0B593E88200DFF8FCE1B8260A68CB +:10AC38000225754C22EA0702744F0A60DEF81820D4 +:10AC48001440734A27430F24CEF81870077C1F441A +:10AC58003F7C02EB0717BF683E60477C1F4497F8AC +:10AC6800247002EB0717BF683E60877C1F4497F883 +:10AC7800387002EB0717BF683E600F685E683E4396 +:10AC88000E60017C5E1803EB8101367C4F6902EB94 +:10AC9800061149680F60417C5E180A3196F82460F5 +:10ACA80053F8217002EB061149680F60817CD3F8D4 +:10ACB80048E05E1803EB81011F6A96F83860C96B9B +:10ACC80002EB06125E6B52681160817C02681944BF +:10ACD80091F84410CEF80010017C1944097F3960BE +:10ACE800417C0B4493F83030336015619465C37C24 +:10ACF800002B29D072B6C37CDC0706D5454A4369C8 +:10AD080011680B4083621360C37C990706D5424AD9 +:10AD1800836911680B40C3621360C37C5A0706D568 +:10AD28003E4AC36911680B4003631360C37C1F0765 +:10AD380006D53B4A036A11680B4043631360C37C22 +:10AD4800DE064BD462B60268364D8368AB424CD0FF +:10AD5800354B85609B69354CC3F30116C3F382619B +:10AD6800334B54F826400131B4FBF1F1A3FB014306 +:10AD78001B0D29D1C3600026032507240121166174 +:10AD88005562136414661161C37CE3B1DD0703D512 +:10AD9800284B826A1A60C37C9C0703D5264BC26A7B +:10ADA8001A60C37C590703D5244B026B1A60C37C15 +:10ADB8001A0703D5224B426B1A60C37CDB0602D507 +:10ADC800826B204B1A60F0BDB1FBF3F1A94288BF3A +:10ADD8000133B3F5817F0AD31B4BCBE71B4A436A88 +:10ADE80011680B4083631360ACE7C368C3E7022BA9 +:10ADF80098BF0023BED9023B5C08210443EA042320 +:10AE080001F47F010B43B5E7CFFFFFE31000000813 +:10AE18004C07002080E100E084E100E088E100E0E8 +:10AE28008CE100E000093D0000C00F403807002019 +:10AE380083DE1B4300E100E004E100E008E100E0FC +:10AE48000CE100E010E100E0FF7F7F0090E100E00E +:10AE58000BB1FFF74FBE7047436893E806000968D7 +:10AE6800114200D1704710B5026804460020052140 +:10AE78001061227C1344187C00F06EFC6268637CCD +:10AE88000521134493F8240000F066FC6268A37C53 +:10AE980005211344BDE8104093F8380000F05CBC6D +:10AEA800624B634AA3FB003C624B4FEA1C4C2DE902 +:10AEB800F04FA3FB00480CF1040E5F4EA2FB0042CA +:10AEC8004FEA5818DFF87C91AEFB0667D20AA3FB5D +:10AED80008430025C7EB0E04A9FB02965B09DFF8BF +:10AEE8005C9107EB54044FF0640B36094FF4C87AB1 +:10AEF800A408C3EB0313C4EBC40406EB4606C4EB77 +:10AF08000E04C8EB0817A2EBC6062A46A8EB830373 +:10AF18000134A0EB87008E704B700870CC70EFB2D4 +:10AF280040F26D1407F2B27389FB030E13F00308A5 +:10AF38004FEAE370C0EB6E160DD1C0EBEE100BFBC1 +:10AF480016364FF4B7740AFB103026B9002840F2C1 +:10AF58006D1018BF0446224401359445DFD28F7125 +:10AF6800B8F1000F0CD13548DE17642580FB03408B +:10AF7800C6EB601405FB1434C4B34FF4B77402E095 +:10AF880040F26D14DE172D48121B64254FF4C87467 +:10AF980080FB0370C2EB0C0C0022C6EB6017C6EBFB +:10AFA800E016012005FB1737254D04FB163602E095 +:10AFB80001300132C0B2012AD4B224D0535D6345B6 +:10AFC8000BD80C28C3EB0C0CF2D10D240CF1010C9E +:10AFD8004C7181F804C0BDE8F08F01340CF1010C0C +:10AFE800E4B281F804C04C71BDE8F08FC6EBE01004 +:10AFF8004FF4C87540F26D1405FB1030002808BFE7 +:10B008004FF4B774BFE7B8F1000F09D167B9002E44 +:10B0180014BF1C231D239C4504D3C3EB0C0CC7E7AA +:10B028001C23F8E70224D1E71D23F4E707452EC2C5 +:10B03800C5B3A29189888888254992241F85EB5138 +:10B0480084040020ABAAAAAA10B503490446FFF756 +:10B0580027FF024B1C6010BD482100207C210020E6 +:10B06800F8B51B4C1B4D23682A681B4F9B1A386880 +:10B07800B3F57A7F0CD3013000E0084602F57A7206 +:10B088002368411C9B1AB3F57A7FF6D238602A6090 +:10B09800124E336898420FD3114B1B6863B198471F +:10B0A800104B50B910491A680B78386800330244BD +:10B0B80018BF012332600B70F8BD1B680221246899 +:10B0C800094A034438602C6033601170F8BD00BF32 +:10B0D800F02700203C210020782100204421002076 +:10B0E80090260020CC1100200628002008B5FFF784 +:10B0F800B7FF044B1B68984201D0FFF7A5FF024B2E +:10B10800987808BD7C2100204821002008B5FFF769 +:10B11800A7FF044B1B68984201D0FFF795FF024B2D +:10B12800587808BD7C2100204821002008B5FFF789 +:10B1380097FF044B1B68984201D0FFF785FF024B2D +:10B14800187808BD7C2100204821002008B5FFF7A9 +:10B1580087FF044B1B68984201D0FFF775FF024B2D +:10B16800187908BD7C2100204821002008B5FFF788 +:10B1780077FF044B1B68984201D0FFF765FF024B2D +:10B18800587908BD7C2100204821002008B5FFF728 +:10B1980067FF054B1B68984201D0FFF755FF034B2B +:10B1A800987900F2B27008BD7C2100204821002067 +:10B1B800844641EA000313F003036DD1403A41D3BA +:10B1C80051F8043B40F8043B51F8043B40F8043B79 +:10B1D80051F8043B40F8043B51F8043B40F8043B69 +:10B1E80051F8043B40F8043B51F8043B40F8043B59 +:10B1F80051F8043B40F8043B51F8043B40F8043B49 +:10B2080051F8043B40F8043B51F8043B40F8043B38 +:10B2180051F8043B40F8043B51F8043B40F8043B28 +:10B2280051F8043B40F8043B51F8043B40F8043B18 +:10B2380051F8043B40F8043B51F8043B40F8043B08 +:10B24800403ABDD2303211D351F8043B40F8043BA8 +:10B2580051F8043B40F8043B51F8043B40F8043BE8 +:10B2680051F8043B40F8043B103AEDD20C3205D3B8 +:10B2780051F8043B40F8043B043AF9D2043208D0B0 +:10B28800D2071CBF11F8013B00F8013B01D30B8822 +:10B2980003806046704700BF082A13D38B078DD000 +:10B2A80010F003038AD0C3F10403D21ADB071CBFD2 +:10B2B80011F8013B00F8013B80D331F8023B20F83C +:10B2C800023B7BE7043AD9D3013A11F8013B00F875 +:10B2D800013BF9D20B7803704B7843708B788370FD +:10B2E80060467047964A974B90422DE9F043964C3A +:10B2F800D3F814E09969E6681CD9944B984240F257 +:10B308001581934B40F22765924F0344924C1A0AD9 +:10B31800A7FB0232D30903EB830303EB830202F298 +:10B32800E243AB4228BF2B46A3F54873A4FB033581 +:10B33800ED0804E0894DA84294BF06250E25814AF0 +:10B3480006F01F07D2F88030AF4243F0C003C2F8BE +:10B3580080300AD27C4B26F01F061A462E43DE6048 +:10B368001368002BFCDA06F01F071EF0007331D1BA +:10B378007B4C7C4AD4F810C014460CEA0202A24264 +:10B388000ABF4FF0C0534FF4805200228EEA0304E4 +:10B3980014F0605F08D02EF0605E03F06053694CD3 +:10B3A80043EA0E0EC4F814E081EA020313F4405F86 +:10B3B80008D0644B21F4405111431A469961936CAB +:10B3C8001C07FCD44EF0007E5E4AC2F814E0936C71 +:10B3D8009906FCD40121644C0A4601FB02F300FBE8 +:10B3E80003F3A34209D8072A00F29580013201FB32 +:10B3F80002F300FB03F3A342F5D95C485C4C184404 +:10B40800A4FB00031B0D6C2B00F28B80352B00F284 +:10B418008F80DFF8888136235648DFF844C1564CC0 +:10B42800DCF80090B0FBF2F009EA04044445B0FBF4 +:10B43800F1F00BD043F400534FF480586446CCF835 +:10B448000080CCF800302368002BFCDADFF8F4C069 +:10B45800013ADCF8103003F00703934207D002F0FA +:10B4680007026446CCF81020A36CDB03FCD4013936 +:10B4780089028EEA010313F4E05F0CD0314B2EF4FD +:10B48800E05E01F4E0511A4641EA0E0EC3F814E0FA +:10B49800936C9907FCD4394B39490344DB09A1FB68 +:10B4A8000331090B042928BF04214B1E1B028EEA15 +:10B4B800030212F4407F07D02EF4407E03F4407359 +:10B4C800204A43EA0E0353611E4B5C691A4624F076 +:10B4D80000745C61936C9B06FCD42A4B4FF0FF32DE +:10B4E800294CBD42A3FB00E320604FEA9343274C5D +:10B4F800B2FBF3F3B0FBF1F1254A2160136008D2E7 +:10B50800114B26F01F061A462E43DE601368002BE7 +:10B51800FCDABDE8F08304293FF66FAF0131012260 +:10B528005BE7DFF87C806C231A4876E7122506E78C +:10B538001948DFF8708000FB03F043EA08086CE75D +:10B5480000A4781F00C00F40000008400046C32335 +:10B5580000BA3CDC23B24C001F85EB5100366E016B +:10B5680000800D4040300080FFB19F26808D5B0039 +:10B57800819F5E1600B29F267F3001807FD1F00840 +:10B588009F10E50083DE1B43681100206411002032 +:10B59800E427002000643F4D001BB70036200080E0 +:10B5A8006C20008000200080002857D001222DE95F +:10B5B800F04F85B083462A4C2A4D2B4EDDE902898F +:10B5C80054E8003F2868336844E800210029F7D18F +:10B5D800264FCDE902893A68D31A254A4FF47A7E74 +:10B5E800019712680127A3FB02234FF47A72984649 +:10B5F80000238B4208BF42452CBFC246F2460EFBD1 +:10B6080000AA54E8003F2A68316844E80073002B18 +:10B61800F7D101980068411A15484FF47A7E0068FE +:10B628000EFB02F2A1FB00014FF47A70CAEB020292 +:10B6380088460021994208BF40452CBF43467346BF +:10B648001A44724507D3BBF1010B0AF57A7AD8D1AF +:10B6580005B0BDE8F08F01F0D5FBD2E7704700BF19 +:10B6680060280020F0270020EC270020041000E0CC +:10B67800E42700202DE9F003124A0126124D134C4D +:10B6880052E8003F2968206842E80063002BF7D1A0 +:10B698000F4A16680F4F321A4FF000094FF47A78A4 +:10B6A8003E684FF47A709945A2FB066708BFB84513 +:10B6B8003C462CBF3C46044600FB0140BDE8F00375 +:10B6C800704700BF60280020F0270020EC270020EA +:10B6D800041000E0E427002000010F4B1A181B5843 +:10B6E80010B4D0685C68044205D059B1C3F884002E +:10B6F8005DF8044B7047936849B9084A5DF8044BF4 +:10B708001A607047C3F888005DF8044B7047044A14 +:10B718005DF8044B1A6070474C0700203830010070 +:10B7280038F001000001054B1A5819189268CB68C7 +:10B738001A4214BF01200020704700BF4C070020A8 +:10B74800362801D8FFF7C8BF704700BF362801D890 +:10B75800FFF7E8BF0020704736281CD800011A4AB6 +:10B76800012902EB0003105810B415D0042913D096 +:10B77800DC68426822EA040242609A68E9B1022958 +:10B788001ED003295B685DF8044B0CBF0F491049B4 +:10B79800116015221A607047DA680129446842EA84 +:10B7A800040242609A6808D040F6380111605B686C +:10B7B80015225DF8044B1A60704738211160F6E7CE +:10B7C80004491160F3E700BF4C070020383001003E +:10B7D8003800010038F001000A4B30B4586A1C46A2 +:10B7E800996A626AA36A994208BF9042104619464C +:10B7F8000CBF01250025002DF3D0D90B30BC41EA40 +:10B808004240704700400D4072B6EFF30583494D42 +:10B818006B60EFF30883484C2E4648484849494A2C +:10B8280024680068096812682961AC60E8606A6188 +:10B838009A69454CAA61DB69444FEB6100F0C8F88E +:10B8480085ED080AFFF7C8FF0B234FF0FF32686247 +:10B8580019462B604A40202102F00103013904FBFC +:10B8680003F383EA5202F7D1BE4202D056F8041F0E +:10B87800F0E730498A62BFF34F8F354B354A19607C +:10B888001A60BFF34F8FBFF36F8F334A0225334CD3 +:10B89800D36E334943F440533248D3662560D369A5 +:10B8A80023F07F0343F04003D3610B6883423ED803 +:10B8B8002A4A002101202C4E11604FF0FF33C2F8B4 +:10B8C80008110C46C2F800611546C2F8080107467F +:10B8D800DFF8C0E0254E26482649274ACEF8003032 +:10B8E800336003600B60136001E000F055F9D5F890 +:10B8F8000C211A4B002AF8D00134C5F80C714F2CD2 +:10B90800F3D91E4A02241E484FF00041C0F84041B6 +:10B918005163D3F80C2132B91A491B4A0A63D3F888 +:10B928000C010028FAD0194B194A1A60FEE7FFF7F4 +:10B93800D9FCBDE780FF272028ED00E02CED00E0D2 +:10B9480034ED00E038ED00E02083B8EDA4FF2720B7 +:10B9580070EF00E0A0FF272000C00F400040084023 +:10B9680068110020803DCD0B009F240084E100E099 +:10B9780088E100E08CE100E090E100E000900D40FB +:10B9880000002E4000800F40F100AD0B0CED00E0F0 +:10B998000400FA0580E100E0094A08B5136820B1FF +:10B9A80018440849884202D81060184608BD01F0BA +:10B9B800A3FC0C224FF0FF330260184608BD00BFFD +:10B9C800D01100200000282030BFFDE7FFF71CBF82 +:10B9D80012490B68114A5B07FBD513681049C3F37A +:10B9E8000B23104A07EE903A0B6892ED006AB8EE06 +:10B9F800E77A07EE903A0C4AF8EE677A0B4BD2EDED +:10BA0800006A77EE677A93ED007AB8EE477A67EEC8 +:10BA1800867A87EEA60A37EE400A704780810D4085 +:10BA2800D4270020DC270020E0270020D82700208A +:10BA3800836BF0B41BB1536843F40043536072B690 +:10BA4800446B5CB31C4B2260D3F8B0410C4215D157 +:10BA58001A4E376804E03468E41BB4F5166F0BD24D +:10BA6800D3F8404144F48044C3F84041D3F8B85176 +:10BA7800D3F840416404EED50D4003D0426362B66A +:10BA8800F0BC70470C4C8260C560D4F8B0311943E3 +:10BA9800C4F8B011426362B6F0BC7047064D8260CC +:10BAA800C460D5F8B0311943C5F8B01102634263D8 +:10BAB80062B6F0BC704700BF00002E40041000E0E2 +:10BAC80070B50646006B90B10246002403E0126888 +:10BAD8000134012A0CD0536813F08003F7D0326385 +:10BAE8002CB1B36B05689847013C2846F9D170BD65 +:10BAF80033637363F4E700BFF0B5E1B9214C224921 +:10BB08000020224B01224FF0011580260A601A46B8 +:10BB1800A1604E60E060C3F8BC51D3F8B0411C4D41 +:10BB280044F001048860C3F8B0412860D2F8B0310D +:10BB3800002BFBD1F0BD0904164B144D0126114C06 +:10BB480041F0800100221E60596000F5805CE264CB +:10BB580000F5005EA36400F54057D5F8B01100F574 +:10BB680080462A46986041F48031C3F80CC0C3F877 +:10BB780010E05F619E61C5F8B011D2F8B031002BBA +:10BB8800FBD1BCE7000000204028002000002E4028 +:10BB980088260020202800202DE9F04FB94C83B0DA +:10BBA800D4F8448118F0010FC4F844815ED0D4F869 +:10BBB800AC31002B55D04FF0011BDFF8EC92B24EA0 +:10BBC8002546DA46C4F8AC31B06AF26AD4F8403196 +:10BBD80043F40053C4F84031D4F840319F04F5D5FC +:10BBE800D5F8403123F40053C5F84031C5F8B4A165 +:10BBF800D4F8B43113F00113FAD181B240F281675D +:10BC0800C9F80030B94200F2AD80B1F5D06F80F0CC +:10BC1800DE81B1F5817F00F0608100F2E880802943 +:10BC280000F04E81822940F0DA8092B202F07F0162 +:10BC3800072900F2D48089009448954F0844016888 +:10BC480010063B707B7040F10182CA0301D50123C5 +:10BC58003B7002218E48FFF74FFFD4F8AC31002B20 +:10BC6800B0D1884AD2F8BC31002B49D118F0400F26 +:10BC780018D0844BD3F8AC111A46C3F8AC11D3F8DA +:10BC8800BC11C3F8BC11D2F8B0417E4B002CFAD1DC +:10BC98004FF0FF32C3F8B421D3F8843100F01EFD11 +:10BCA8007C4B1C6018F0807F03D07B4B1B6803B172 +:10BCB800984718F0007F03D0784B1B6803B198476A +:10BCC80018F0040F08D06F4BD3F8843113F40073C5 +:10BCD80045D0734B01221A706A4BD3F848211206DB +:10BCE8000BD518F0800F08D06E490A782AB1013AAE +:10BCF800D2B20A70002A00F0428203B0BDE8F08F89 +:10BD08006949C2F8BC310868034240F0E281614ADF +:10BD180015681D40AAD02F0C0FD05B4E4FF00109BB +:10BD280097FAA7F4B4FA84F406EBC41009FA04F4F9 +:10BD38004030FFF7C5FEA743F2D1ADB2002D95D034 +:10BD4800514E012795FAA5F4B4FA84F406EBC41011 +:10BD580007FA04F4FFF7B4FEA543F3D186E7504A87 +:10BD68001370B9E742F22107B94234D067D8B1F568 +:10BD7800086F00F01E81B1F5106F30D1C0F3074095 +:10BD88004A4A4B4910704B4F4B4A0193C5F8C8714A +:10BD9800C5F8CC11C5F8D02100F0A2FC474A019B98 +:10BDA80080210120B26451601060F364C5F8BCB111 +:10BDB800D5F8B011936041F48032C5F8B0213A4A01 +:10BDC8001360D4F8B031002BFBD1D4F8AC31002B80 +:10BDD8007FF4F8AE45E7110C072900F03B81C4F861 +:10BDE800C0B1D4F8AC31002B7FF4ECAE39E740F2A7 +:10BDF8000237B94200F0AD80B1F5A06FEFD12F4AFC +:10BE080080210127F364B26417605160C5F8BCB1A2 +:10BE1800D5F8B011936041F48033C5F8B031D4F847 +:10BE2800B031002BFBD1030C5B0643F08073C5F8DF +:10BE38005431D4F8AC31002B7FF4C4AE11E742F290 +:10BE48002123994279D042F221339942C7D11B4B21 +:10BE5800802200210120B36418605A60F164C4F89C +:10BE6800BCB1D4F8B021996042F48033C4F8B03141 +:10BE7800D4F8B031002BFBD1D4F8AC31002B7FF4CF +:10BE8800A1AEEEE600002E4000000020C0012E40CA +:10BE9800982700208C260020F4270020F82700206F +:10BEA80016280020172800208826002015280020A2 +:10BEB800C80002000200CC000200C8004028002090 +:10BEC800B64A0221104613705370FFF715FED4F8D6 +:10BED800AC31002B7FF476AEC3E692B202F07F035A +:10BEE800072B3FF67CAF12F0800F4FEA8303AC4A72 +:10BEF8004FF000014FF001001A44136814BF23F4F7 +:10BF0800803323F0010313608022A64BF164B364ED +:10BF180018605A60C4F8BCB1D4F8B021996042F4F2 +:10BF28008033C4F8B031D4F8B031002BFBD1D4F849 +:10BF3800AC31002B7FF446AE93E692B2002A86D14C +:10BF4800994BC0F30740994A1968994B11601870CA +:10BF58007DE792B202F07F03072B3FF640AF12F065 +:10BF6800800F4FEA83038E4A4FF000014FF0010023 +:10BF78001A44136814BF43F4803343F00103136079 +:10BF88008022884BF164B36418605A60C4F8BCB16D +:10BF9800D4F8B021996042F48033C4F8B031D4F8B1 +:10BFA800B031002BFBD1D4F8AC31002B7FF40AAEB2 +:10BFB80057E6804A0121794B127818461A70FFF724 +:10BFC8009BFDD4F8AC31002B7FF4FCAD49E67A4BED +:10BFD800596800293FF403AF000C1FFA82FE04E001 +:10BFE8000C33596800293FF4FAAE1F888742F7D10D +:10BFF8005F887745F4D1070A032F00F0BA801B89C0 +:10C00800120C934228BF1346B0F5007F00F0A280BF +:10C01800B0F5E06F00F08B80684F1A460193384600 +:10C02800FFF7C6F8019B27F01F021F44BFF34F8F8D +:10C0380063490A6020329742FAD8BFF34F8FBFF3A3 +:10C048006F8F5E481946FFF757FD06E6CB077FF569 +:10C0580000AEFCE55B4F4FF0010EF3605A495B4BB5 +:10C068003860C3F800E05960B3605949D5F8B001A9 +:10C078007A6001F5805740EA0E02996001F5005E8A +:10C0880001F5405001F58041C5F8B021DF60C3F8E3 +:10C0980010E058619961D4F8B031002BFBD1414AC6 +:10C0A800012048F28001F36410604FF48030B264DC +:10C0B8005160C5F8BCB1D5F8B011936041EA0003EE +:10C0C800C5F8B031C9F80000D4F8B031002BFBD165 +:10C0D800C3E53C4842F22104002605880E60A542CB +:10C0E80040687FF414AE81B200297FF410AE38495D +:10C0F800384C03C90D0C86282060A180A5717FF4F7 +:10C1080006AE72B63448017841F004010170D2F8E5 +:10C118004811080606D441F080018020C2F8440185 +:10C12800C2F8481162B62D4A50211170EFE52C482B +:10C138001A46224F90F800E02A492B480193BEF195 +:10C14800000F08BF01463846FFF732F80722019B67 +:10C158007A7068E722481A462349077821480193EC +:10C16800002F08BF01461548FFF722F8134F019B1F +:10C1780059E7120C0B78934228BF134648E7164933 +:10C188000A7802F0FB020A702AB9D3F8482122F093 +:10C198008002C3F8482101F09BFE00BF98270020C9 +:10C1A800C0012E4040280020F02700207C280020D5 +:10C1B8001428002015280020C80C0020000020208A +:10C1C80070EF00E0401C00208000070020280020BD +:10C1D800802600207428002010280020172800201E +:10C1E80016280020A41E0060F01E0060002AA0F19E +:10C1F80002022DE9F04714BF00274FF00057022A2A +:10C2080001D9BDE8F0874FEAC019DFF840A00D4614 +:10C2180004460AEB0906002140229846304601F000 +:10C2280093FB012047EA05414AF80910C6F838800F +:10C23800B060B8F1000FE4D0034BA0401C68204365 +:10C248001860BDE8F08700BF8C26002000000020A1 +:10C25800002AA0F102022DE9F04714BF00274FF091 +:10C268000057022A01D9BDE8F0874022C501DFF84E +:10C27800449088461544002104461E4609EB050AE9 +:10C28800504601F061FB012247EA084149F80510D0 +:10C29800CAF83860CAF80820002EE4D004F110006B +:10C2A800034B8240186802431A60BDE8F08700BF5C +:10C2B8008C2600200000002012048160C36142F037 +:10C2C8008002F0B44260012701F5805601F500555F +:10C2D80001F5405401F580420760C660056144617C +:10C2E8008261F0BC704700BF831E022B00D97047E3 +:10C2F800064B0A4630B400F11004012503EBC010C8 +:10C3080005FA04F1403030BCFFF792BB0000002072 +:10C31800831E022B00D9704710B4054B01240A462E +:10C3280004FA00F103EBC0105DF8044BFFF780BB83 +:10C338000000002040687047124A134BD2F82002D0 +:10C3480020F07F40984210B584B002D800EB8000FE +:10C3580040000E4C01A90A2200F0CCFD01A90023DF +:10C36800204611F8012B01333AB10A2B20F8022F8D +:10C37800F7D11623237004B010BD5B00DBB2237025 +:10C3880004B010BD00441F407F969800001600209E +:10C39800F8B514494FF40037134D034601EB402418 +:10C3A800124E134A05EB401521461760284632887D +:10C3B800FFF782FF318824F01F032144BFF34F8F1A +:10C3C8000C4A136020339942FBD8BFF34F8FBFF359 +:10C3D8006F8F03202946FFF79BFF074B4FF400326E +:10C3E8001A60F8BD60002020C01A0020FC27002039 +:10C3F8008CE100E05CEF00E00CE100E0244A4368D7 +:10C408002DE9F041C3F30E431488C569E41A002CE2 +:10C4180038DD2049204A0B781278DBB21F48204EBD +:10C42800934207D010F8038036F81870C7F50072E9 +:10C43800944212D9013300221A4F082B26F81540CE +:10C4480027F81520184E94BFDAB213460A703268DE +:10C45800C55414443460BDE8F081144B07EB482000 +:10C468002246274403EB45211844FEF7A1FE0E4A55 +:10C47800284626F8187013681C441460BDE8F0417B +:10C48800FFF786BF2846BDE8F041FFF781BF00BF30 +:10C49800FC2700200E2800200F280020C827002095 +:10C4A800A8270020B8270020A4270020600020200B +:10C4B8001E4B1A785AB902F0FF031D4A127832B19E +:10C4C8002DE9F0411B4D2A8812B9BDE8F08170476B +:10C4D800194EC2F50068194F31784246184C07EBDF +:10C4E800411704EBC12438462146FFF7E5FE08EB67 +:10C4F800040224F01F01BFF34F8F124B1960203143 +:10C508008A42FBD8BFF34F8FBFF36F8F04203946A1 +:10C51800FFF7EAFE3378084A0133DBB2032B88BF02 +:10C528000023137000232B80BDE8F081132800201E +:10C5380015280020FE27002012280020C01B0020FC +:10C548006010202070EF00E02DE9F04F85B00290D8 +:10C558000091002900F0AB800023564DDFF874816C +:10C56800DFF860A1544FDFF870B101930122534BFB +:10C578002A701C78524AB8F8003002EB441923BBE1 +:10C588001E461C464846FFF7D5FE10F080007ED0B8 +:10C59800BFF34F8F00229AF800304A492A7004B935 +:10C5A8003E68002B5AD13B689B1B782B79D89BF8A7 +:10C5B8000030002B52D000F025FC0124B8F80030E0 +:10C5C8002C70002BDED03D4A14781A46C3F5006063 +:10C5D800E402009E3C4920449642084442D30C445D +:10C5E8000299FEF7E5FD002321464FF40062484614 +:10C5F800FFF762FE24F01F0304F50064BFF34F8FBA +:10C60800324A136020339C42FAD8BFF34F8FBFF3EE +:10C618006F8F04204946FFF767FE284B274A1B788F +:10C62800009801332A49DBB2032B88BF002313701B +:10C638000022B8F80030A8F80020C01A009001982D +:10C6480018440190029818440290C1F88420BFF35E +:10C658004F8F00232B70009B002B87D1019805B0CA +:10C66800BDE8F08F009C0393019B22460299234466 +:10C678000193FEF79DFD039B4FF04041144A0020B3 +:10C688001B1B0090A8F80030C2F88410DFE74FF4B5 +:10C6980000630A4A8AF8000014781A46A8F800309D +:10C6A80096E7012301980B7005B0BDE8F08F00985C +:10C6B800D5E700BF13280020F0270020122800200B +:10C6C800C01B0020112800206010202070EF00E01F +:10C6D80000002E40FE27002015280020704700BFCC +:10C6E800314B2DE9F0411B78304F002B54D04FF4DB +:10C6F8000073DFF8EC803B80A8F80030002180222E +:10C708002B480D462B4E01F01FF92B4C2B4B29467D +:10C718004FF480722A4825702C461D8001F014F9C8 +:10C7280035602B4675602A46B560F5602549264E6A +:10C738002648DFF8B0E00D70102105700220356042 +:10C748007560B560F560CEF80050FFF781FDB8F868 +:10C7580000102A461E4B0320FFF748FD2B46398858 +:10C7680001220420FFF774FD20460134FFF710FE74 +:10C77800082CF9D1174B4A2217480021174C04609E +:10C78800C3F88410C3F88020D3F8482142F080729F +:10C79800C3F84821BDE8F0814023DFF844803B809E +:10C7A800A8F80030AAE700BF1628002000280020BB +:10C7B800C01B0020A827002012280020FE270020E8 +:10C7C800C01A00200E280020B82700200F280020BB +:10C7D800BDA4000000002E40F427002071A5000031 +:10C7E800FC270020A4270020314B4FF400322DE90C +:10C7F800F04F1A6083B02F4B89461C78002953D01C +:10C808002D4BE4B21B789C4250D082460027DFF8BB +:10C81800C0B00134294BC7EB09085046092C0193D5 +:10C82800274B28BF00241D5D244B33F815E0254B0A +:10C838000EEB452133F81560234BCEEB0606194461 +:10C84800B0453246374419D20EEB452142461944C9 +:10C85800FEF7AEFC019BDBF80010484633F81520C4 +:10C86800C8EB01019044CBF8001023F81580174B52 +:10C878004FF400321A6003B0BDE8F08FFEF798FC61 +:10C88800DBF80020E3B22846921BB244CBF8002024 +:10C89800084A1370FFF77CFDB94503D9064B1B788E +:10C8A8009C42B6D13846E2E70846E0E70020DEE7DA +:10C8B8008CE100E00F2800200E280020B827002077 +:10C8C800C8270020A8270020600020200CE100E0F5 +:10C8D800A42700200B4B0C4A1B781278DBB293423A +:10C8E8000DD0013309480A4A092B0A4928BF0023F9 +:10C8F800C35C31F8131002EB4323585C70474FF0C8 +:10C90800FF3070470F2800200E280020C82700207D +:10C9180060002020B8270020034B10B51C680CB914 +:10C9280000F070FA204610BDA42700202DE9F84F2A +:10C93800154E164D34782B78E4B29C4221D0DFF89E +:10C948005490DFF854B0DFF85480114F0134082CAC +:10C958005FFA84FA01D90024A24619F80410DBF81A +:10C96800002038F81130084637F811105B1AD31A2E +:10C97800CBF80030FFF70CFD86F800A02B789C421E +:10C98800E4D1BDE8F88F00BF0F2800200E28002052 +:10C99800B8270020C8270020A4270020A8270020A7 +:10C9A80000B583B001210DF10700FFF71DFF20B18D +:10C9B8009DF8070003B05DF804FB4FF0FF30F9E77E +:10C9C800094B00B583B01B788DF8070023B903F035 +:10C9D800FF0003B05DF804FB01210DF10700FFF72C +:10C9E800B3FD03B05DF804FB15280020044B1B7849 +:10C9F80003F0FF020BB1FFF7A7BD1046704700BF59 +:10CA0800152800202DE9F0410024DFF84480012397 +:10CA18000D4D27460D4E88F80030337828462035CE +:10CA2800A34204F1010405D0FFF784FC030658BFB4 +:10CA380007F50067042CF0D1BFF34F8F0023384669 +:10CA480088F80030BDE8F081C01B002012280020C3 +:10CA5800132800202DE9F843204B1B7813B1204DF3 +:10CA68002A880AB9BDE8F883DFF88880C2F500692A +:10CA78001C4E4FF0010E98F800104A461A4C00233D +:10CA880006EB4116194F04EBC124304687F800E045 +:10CA98002146FFF711FC09EB040224F01F01BFF344 +:10CAA8004F8F134B196020318A42FBD8BFF34F8F49 +:10CAB800BFF36F8F04203146FFF716FC98F800305B +:10CAC8000C4A0133DBB2032B88BF00231370002309 +:10CAD8002B80BFF34F8F3B70BDE8F88315280020EB +:10CAE800FE270020C01B00206010202013280020F3 +:10CAF80070EF00E01228002010B4EFF3108272B635 +:10CB0800437F33B9017F012908D0032910D00123BD +:10CB1800437702B962B65DF8044B7047114C21683F +:10CB2800A1B1114943610B68086083615861EEE760 +:10CB38000E4C216881B10E4943610B68086083611E +:10CB480058610C4B4FF080511960E0E7064B41618A +:10CB5800816120601860DAE7054B416181612060DE +:10CB68001860EEE794210020A02100209C210020DD +:10CB78009821002004ED00E070B5EFF3108172B643 +:10CB88000C4C23688BB10C4E00255A6922607AB18F +:10CB9800956101B962B65D7718469B689847EFF3CF +:10CBA800108172B62368002BEFD101B962B670BD4F +:10CBB8003260EEE79C21002098210020FFF7DCBFBF +:10CBC800044A054B1168054A19601368013313605C +:10CBD800704700BF041000E0EC270020F027002079 +:10CBE800F8B50E4671B17AB10746144600253B6880 +:10CBF800384616F8011B1B689847013C0544F6D1D6 +:10CC08002846F8BD0846F8BD1046F8BD10B5064CD4 +:10CC180082B003680222248801A95B68ADF8044049 +:10CC2800984702B010BD00BF800200205E4A5F4BEB +:10CC3800A2FB002C5E4A2DE9F04F4FEA1C4CA3FBE7 +:10CC48000074A2FB00725B4E64090CF1040ED20A58 +:10CC5800DFF86C81A3FB04730025AEFB06674FF079 +:10CC6800640BA8FB02865B09C7EB0E084FF4C87A71 +:10CC78003609DFF8449107EB5807C3EB0313BF08E5 +:10CC8800A4EB830306EB4606C7EBC7074B70C4EB60 +:10CC98000414A2EBC606C7EB0E0EA0EB84002A46CE +:10CCA8008E70087081F803E0EFB240F26D1407F25D +:10CCB800B27389FB030E13F003084FEAE370C0EB6D +:10CCC8006E160DD1C0EBEE100BFB16364FF4B77491 +:10CCD8000AFB103026B9002840F26D1018BF044630 +:10CCE800224401359445DFD246378F71B8F1000FE1 +:10CCF8000CD13148DE17642580FB0340C6EB601475 +:10CD080005FB14347CB34FF4B77402E040F26D14A1 +:10CD1800DE172948121B64254FF4C87480FB037082 +:10CD2800C2EB0C0C0022C6EB6017C6EBE016012024 +:10CD380005FB1737214D04FB163602E0013001329E +:10CD4800C0B2012AD4B21BD0535D634504D80C2865 +:10CD5800C3EB0C0CF2D104460CF1010C4C7181F8B8 +:10CD680004C0BDE8F08FC6EBE0104FF4C87540F280 +:10CD78006D1405FB1030002808BF4FF4B774C8E7DE +:10CD8800B8F1000F09D167B9002E14BF1C231D2369 +:10CD98009C4504D3C3EB0C0CD0E71C23F8E7012413 +:10CDA800DAE71D23F4E700BF07452EC28988888883 +:10CDB800C5B3A291254992241F85EB519004002008 +:10CDC800ABAAAAAA08B5F6F7EDFCF6F7C3FD00F082 +:10CDD80019F8FAE700F0BEBA00F0C4BAFFF7A6BD2A +:10CDE800FFF778BDFFF7DCBDFFF796BDFFF732BE52 +:10CDF800FFF708BE08461146FFF7F8BD0846FFF7DB +:10CE0800DFBD00BF2DE9F843324E337893B1324F7E +:10CE18003A787AB90122D9073A7037D49A0719D4DF +:10CE280000225B073A7005D52C4B1A6812B1EFF354 +:10CE380005820AB1BDE8F883EFF3108072B61A686C +:10CE48001AB1274C217800292FD00028F2D162B6D8 +:10CE5800BDE8F883DFF8948098F80020002ADFD036 +:10CE68000024DFF88C9005E0013498F80030E4B233 +:10CE7800A34213D959F824502B6828461B699847B0 +:10CE88000028F1D06B699B689847EDE7FFF744FDF0 +:10CE9800D0B9144B1B781BB93378BFE73378BFE799 +:10CEA800337803F0FE033370B8E70126556926701E +:10CEB8001D6065B1A96100B962B600259368104686 +:10CEC800557798472570B5E700F008FAE1E7064B73 +:10CED8001D60F0E7171600200A2800209421002082 +:10CEE80008280020461F0060A021002009280020F3 +:10CEF800A4210020F0B44E1E0025374600E001357D +:10CF0800B0FBF2F302FB130000F13704092800F12B +:10CF18003000E4B298BFC4B2184607F8014F002B9E +:10CF2800EDD14A1953704DB1013316F8014F1778F6 +:10CF3800E81A3770834202F80149F5DB0846F0BC6D +:10CF4800704700BFA4484FF00F0CA44B826F42F407 +:10CF58007F02F0B582670025D0F880204FF4704634 +:10CF68009F4C4FF4604E29464FF4806714432A467D +:10CF7800C0F88040A3F88C6148F2B826A3F88EC1A7 +:10CF8800A3F89051B3F8880180B240F0F000A3F8FC +:10CF9800880101EB4100914B0131002540011C46FD +:10CFA80004290344A3F804E0DF805A841A865A80CF +:10CFB8005A81DE815A82DA825A83DA83E9D1B4F857 +:10CFC80088014FF00F0C874B4FF4704680B229460A +:10CFD8004FF460472A4640EA0C004FF4806EA4F8EC +:10CFE8008801B4F8880180B240F47060A4F8880120 +:10CFF800A3F88C6148F2B826A3F88EC1A3F8905123 +:10D00800B3F8880180B240F0F000A3F8880101EB82 +:10D018004100744B0131002540011C46042903449A +:10D028009F80A3F806E05A841A865A805A81DE81C6 +:10D038005A82DA825A83DA83E9D1B4F888014FF048 +:10D048000F0C694B4FF4704680B229464FF4604785 +:10D058002A4640EA0C004FF4806EA4F88801B4F820 +:10D06800880180B240F47060A4F88801A3F88C614C +:10D0780048F2B826A3F88EC1A3F89051B3F88801F6 +:10D0880080B240F0F000A3F8880101EB4100564B54 +:10D098000131002540011C46042903449F80A3F860 +:10D0A80006E05A841A865A805A81DE815A82DA82C8 +:10D0B8005A83DA83E9D1B4F888014FF00F0C4B4B4F +:10D0C8004FF4704780B229464FF460462A4640EA3A +:10D0D8000C004FF4806EA4F88801B4F8880180B27F +:10D0E80040F47060A4F88801A3F88C7148F2B8275E +:10D0F800A3F88EC1A3F89051B3F8880180B240F02C +:10D10800F000A3F8880101EB4100384B01314001E0 +:10D118001C46042903449E80A3F806E05A841A8614 +:10D128005A805A81DF815A82DA825A83DA83EAD1B5 +:10D13800B4F888310F27002241F201069BB245F668 +:10D14800C05E114643F226053B43A4F88831B4F883 +:10D1580088319BB243F47063A4F888315001244BA2 +:10D1680001320344042A99815981DF819E82A3F800 +:10D1780006E0198019829D81F0D100220F2741F223 +:10D18800010645F6C055114643F226045001194BD5 +:10D1980001320344042A99815981DF819E82DD800E +:10D1A800198019829C81F1D100220F2741F20106D2 +:10D1B80045F6C055114643F2260450010E4B013284 +:10D1C8000344042A99815981DF819E82DD80198078 +:10D1D80019829C81F1D1F0BD00C00F4000C03D40D4 +:10D1E800000003FC00003E4000403E4000803E40FE +:10D1F80000C01D4000001E4000401E4008B50368E6 +:10D208004268BBB17AB1104BA3FB0213DB0803EBF6 +:10D218004303B2EB830303D0D21A4260F02A02D947 +:10D228000123184608BD00F067F81C22002302609D +:10D23800184608BD044BA3FB0213DB0803EB4303AA +:10D24800B2EB8303E8D1E9E7ABAAAAAA70B5044612 +:10D2580000283AD019B1B2FA82F56D09FDB12068FB +:10D2680008B1626832B900F047F81623002203605B +:10D27800104670BD1849A1FB0231C90801EB4101F4 +:10D28800B2EB8101EFD1A3680BB100F05DFB002385 +:10D298000122236010466360A360E36070BD1E46F0 +:10D2A800049B80E80600C360FFF7A8FF0246002839 +:10D2B800DED016B90122104670BD94E80500A660BC +:10D2C800294600F041FB0122D2E700F015F81623A9 +:10D2D80022460360CCE700BFABAAAAAA704700BFEA +:10D2E8000B460146184600F001B800BF13460A462F +:10D2F8000146022000F062BC014B1868704700BF6D +:10D30800E415002070B50F4E0F4D761BB61018BFF0 +:10D31800002405D0013455F8043B9847A642F9D1BA +:10D328000A4E0B4D761B00F0D7FDB61018BF00242F +:10D3380006D0013455F8043B9847A642F9D170BD90 +:10D3480070BD00BF681E0060681E0060701E00602F +:10D35800681E0060024B0146186800F00BB800BF59 +:10D36800E4150020024B0146186800F0C7BC00BF56 +:10D37800E41500202DE9F04F01F10B05162D83B0BF +:10D38800064640F29F8035F0070500F1BF80A942AC +:10D3980000F2BC8000F026FBB5F5FC7FC0F09C8253 +:10D3A8006B0A00F0BA80042B00F28381A80900F10F +:10D3B800390E4FEA4E033830C44F07EB8303A3F10D +:10D3C80008015C68A14207D1ACE0002A80F2AC8079 +:10D3D800E468A14200F0A680636823F003035A1BA7 +:10D3E8000F2AF2DDB9493C6901F1080E744500F0D5 +:10D3F800B381636823F003035A1B0F2A00F3998152 +:10D40800002AC1F814E0C1F810E080F29E80B3F55C +:10D41800007F80F06781DB0803F1010C01229B107B +:10D4280002FA03F34A6851F83C80C4F8088001EB1B +:10D43800CC091A43A9F10803E3604A6041F83C406B +:10D44800C8F80C40831001249C40944200F28A8062 +:10D45800144206D120F003006400144200F10400D5 +:10D46800FAD007EBC009CC468046DCF80C108C4596 +:10D4780007D173E1002A80F28181C9688C4500F0E8 +:10D488006D814B6823F003035A1B0F2AF2DD0C460B +:10D49800D1F80CC054F8088F4B1945F001054D60C0 +:10D4A80042F00101C8F80CC03046CCF808807B6116 +:10D4B8003B61C3F80CE0C3F808E059609A5000F0EB +:10D4C80093FA1FE0102921D800F08CFA10250623C2 +:10D4D80002207E4F07EB8303A3F108025C689442A5 +:10D4E80000F045816368E168A56823F003032344DD +:10D4F80030465A68E96042F001028D605A6000F0D7 +:10D5080073FA0834204603B0BDE8F08F00240C23DA +:10D518002046336003B0BDE8F08F80234FF0400E03 +:10D528003F2049E770465DE72344E1685A68A568EB +:10D5380042F00102E96030468D605A6000F054FA0A +:10D548000834204603B0BDE8F08F234430465A68BB +:10D5580042F001025A6000F047FA0834204603B04E +:10D56800BDE8F08FBC68636823F00308A84504D3BE +:10D57800C5EB08030F2B00F38C80554BDFF8609147 +:10D588001A68D9F8003001332A4404EB080A00F07D +:10D59800608102F580520F3222F47F6222F00F027E +:10D5A80011463046019200F021FAB0F1FF3F834660 +:10D5B800019A00F05881824500F2FC80454B1968B9 +:10D5C800DA451144196000F05381D9F80000DFF8FA +:10D5D80010E101301BBFCAEB0B0A5144CEF800B072 +:10D5E80019601BF0070100F01781C1F10800C1F5AF +:10D5F8008051834408315A44C2F30B02C2EB01093B +:10D6080049463046019300F0F1F9431C019B00F0B4 +:10D618003F81CBEB00024A4442F001021968C7F887 +:10D6280008B04944BC42CBF804201960DFF8A49044 +:10D6380016D0B8F10F0F40F2FD806268A8F10C0314 +:10D6480023F00703E01802F001024FF0050E1A4319 +:10D658000F2B6260C0F804E0C0F808E000F21C81FB +:10D668001D4BBC681A68914288BF19601B4B1A6829 +:10D678009142626888BF196022F003029542A2EBCA +:10D68800050301D80F2B04DC304600F0ADF9002467 +:10D6980038E7621943F0010345F00105656030463B +:10D6A800BA60536000F0A0F90834204603B0BDE822 +:10D6B800F08F142B71D9542B00F2A480280B00F1A1 +:10D6C8006F0E4FEA4E036E3076E600BFD41100208D +:10D6D800FC210020CC210020F4210020F82100208A +:10D6E800DC1500205A0A042A5ED9142A00F2B380F5 +:10D6F80002F15C0149005B3207EB810C57F82110FD +:10D70800DFF8DC81ACF1080C8C4500F088804A68B1 +:10D7180022F00302934202D289688C45F7D1D1F8EE +:10D728000CC07A68C4F80CC0A160CCF80840CC6082 +:10D7380088E6631942F0010745F001056560304647 +:10D748004B610B61C3F80CE0C3F808E05F609A50C6 +:10D75800083400F049F9D5E64A6873E608F101088B +:10D7680018F0030F0CF1080C7FF47FAE30E0DC6892 +:10D77800A34208BF02303FF435AEB3E60B440C4673 +:10D788005A68C96854F8085F42F001025A60304686 +:10D79800E9608D6000F028F9B4E603F15C0E03F14E +:10D7A8005B004FEA4E0307E69A0902F13901490086 +:10D7B8003832A1E7BC424A4B3FF400AF9C6862682C +:10D7C80022F003025AE759F80839994540F0828057 +:10D7D80010F0030F00F1FF30F5D17B6823EA040352 +:10D7E8007B6064009C423FF6BDAE002C3FF4BAAEAD +:10D7F8001C4240467FF435AE64001C4200F1040030 +:10D80800FAD02EE6B3F5AA7F18D8E80B00F1780E07 +:10D818004FEA4E037730CFE54FF48051EBE6012114 +:10D82800D8F80430921001FA02F21A43C8F804201A +:10D83800614677E70123CBF8043025E740F25452DC +:10D84800934220D8A80C00F17D0E4FEA4E037C309D +:10D85800B2E51032A4E6542A26D81A0B02F16F0159 +:10D8680049006E3248E7BC68626822F0030205E7A7 +:10D87800CAF30B0000287FF4A8AE4244BB6842F00C +:10D8880001025A60ECE6FE234FF07F0E7E2093E5FE +:10D8980001224FF00009C1E604F10801304600F00A +:10D8A8002DFAD9F80010DBE6B2F5AA7F05D8DA0B15 +:10D8B80002F17801490077321EE740F254518A425A +:10D8C80005D89A0C02F17D0149007C3214E7FE214B +:10D8D8007E2211E77B6884E7E808431C5B00F8E5D3 +:10D8E800D4110020032A70B426D940EA01039B070B +:10D8F80011D004780D78AC4222D10244431C05E0D3 +:10D9080013F8014B11F8015FAC4219D19342F7D1DA +:10D91800002070BC70470C4603461E682568AE425E +:10D928001846214603F1040304F10404E1D1043A42 +:10D93800032A18462146F0D8002ADAD11046E8E72B +:10D94800601B70BC704700BF70B4840746D0541E7B +:10D95800002A41D0CDB2034602E0621EE4B3144669 +:10D9680003F8015B9A07F8D1032C2ED9CDB245EA0A +:10D9780005250F2C45EA054519D903F1100226465D +:10D98800103E0F2E42F8105C42F80C5C42F8085C1E +:10D9980042F8045C02F11002F2D8A4F1100222F05D +:10D9A8000F0204F00F041032032C13440DD91E4645 +:10D9B8002246043A032A46F8045BFAD8221F22F0CA +:10D9C80003020432134404F003042CB1C9B21C440A +:10D9D80003F8011BA342FBD170BC704714460346F1 +:10D9E800C2E700BF704700BF704700BF38B5074C9B +:10D9F8000023054608462360FDF7CEFF431C00D0F0 +:10DA080038BD2368002BFBD02B6038BD8028002050 +:10DA180000000000000000000000000000000000FE +:10DA280000000000000000000000000000000000EE +:10DA380000000000000000000000000000000000DE +:10DA480090F800F06DE9024520F007016FF0000C36 +:10DA580010F0070491F820F040F049804FF00004DE +:10DA68006FF00700D1E9002391F840F000F10800B9 +:10DA780082FA4CF2A4FA8CF283FA4CF3A2FA8CF3F1 +:10DA88004BBBD1E9022382FA4CF200F10800A4FA58 +:10DA98008CF283FA4CF3A2FA8CF3E3B9D1E90423AC +:10DAA80082FA4CF200F10800A4FA8CF283FA4CF3E3 +:10DAB800A2FA8CF37BB9D1E9062301F1200182FA9D +:10DAC8004CF200F10800A4FA8CF283FA4CF3A2FAA3 +:10DAD8008CF3002BC6D0002A04BF04301A4612BAB1 +:10DAE800B2FA82F2FDE8024500EBD2007047D1E9B4 +:10DAF800002304F00305C4F100004FEAC50514F043 +:10DB0800040F91F840F00CFA05F562EA05021CBF13 +:10DB180063EA050362464FF00004A9E7002A41D0F2 +:10DB280040EA010313F00303F0B425D1032A23D9F3 +:10DB380004680D68AC421FD1043A35D0A4F1013510 +:10DB480025EA040414F0803F31D1071D0D1D0DE0B6 +:10DB580057F8043B0E68A3F10134B34224EA0304E6 +:10DB68000AD1043A20D014F0803F23D1032A294651 +:10DB7800384605F10405EBD803780C789C4202F18D +:10DB8800FF320CD182B114B916E06AB17BB110F83A +:10DB9800013F11F8014FA34202F1FF32F5D0181BE3 +:10DBA800F0BC7047104670471046F0BC70471846E6 +:10DBB800F0BC70470020F3E72046F1E72DE9F04775 +:10DBC800254C2568D5F84841064688469246994628 +:10DBD800C4B360681F2817DC431C76B104EB8005CA +:10DBE8000122C5F888A0D4F8881182401143022E7A +:10DBF800C4F88811C5F808911ED00230636044F853 +:10DC080020800020BDE8F087144B03B34FF4C870A0 +:10DC1800FFF7A0FB0446D0B1D5F84831002780E8CB +:10DC28008800C5F8484138460123C4F88871C4F80B +:10DC38008C71002EE1D0D1E7D4F88C110A43C4F8D6 +:10DC48008C21DAE705F5A674C5F84841C1E74FF01D +:10DC5800FF30BDE8F08700BF4807002015B400007A +:10DC6800F8B5234F0C460646FFF7BCFEBB685D6857 +:10DC780025F00305291B01F6EF7121F47F6121F0DE +:10DC88000F01A1F58054B4F5805F07DB0021304611 +:10DC9800FFF7ACFEBB682B44984204D03046FFF730 +:10DCA800A3FE0020F8BD61423046FFF79FFE013019 +:10DCB8000DD0104BBA6819682D1B45F00105304688 +:10DCC800091B55601960FFF78FFE0120F8BD002180 +:10DCD8003046FFF78BFEBA68831A0F2BDEDD064C41 +:10DCE8000449246843F00103001B53600860D5E72A +:10DCF800D4110020CC210020DC150020002945D0BB +:10DD08002DE9F0410D468046FFF76CFE55F8047C7E +:10DD18006A4927F00103A5F10804E2188E685068E3 +:10DD2800B24220F0030062D0FE0750600BD455F8D1 +:10DD3800087CE41B01F1080EA56875453B446FD0CB +:10DD4800E768EF60BD6015186D68ED0742D543F0D0 +:10DD580001026260E350B3F5007F18D2DB085A1C59 +:10DD68004D6851F83270A76001209B1000FA03F348 +:10DD780001EBC2001D430838E0604D6041F83240B5 +:10DD8800FC604046BDE8F041FFF72EBE70475A0AD6 +:10DD9800042A53D89A0902F139077F0002F138059D +:10DDA80001EB870051F827204449083890424DD0AC +:10DDB800516821F003018B4202D292689042F7D158 +:10DDC800D068E060A2608460D4604046BDE8F0415D +:10DDD800FFF70ABE95683A4FBD4203443FD0D0686A +:10DDE800E86043F0010285606260E350B3E7FF0733 +:10DDF800034407D455F8082CA41A1344A068E26811 +:10DE0800C26090602F4A126843F00100934260603C +:10DE18008C60B6D32C4B40461968FFF721FFB0E75A +:10DE280011184968C90744D49168D268CA60034484 +:10DE380043F0010091606060E350A2E7142A17D80C +:10DE480002F15C077F0002F15B05A9E7AA104B68A5 +:10DE5800012505FA02F213434B600246B1E743F08D +:10DE680001024C610C61E560A5606260E35088E7DF +:10DE7800542A06D81A0B02F16F077F0002F16E05CB +:10DE88008EE7B2F5AA7F06D8DA0B02F178077F0091 +:10DE980002F1770584E740F25450824206D89A0C82 +:10DEA80002F17D077F0002F17C0579E7FE277E25D8 +:10DEB80076E743F001026260E35062E7D411002084 +:10DEC800DC110020E0150020FC21002000000000EB +:10DED8005FF800F06D1D00605FF800F0191E00602B +:04DEE800F8B500BFCA +:08DEEC00FCF3FF7F01000000C0 +:10DEF400000000000000000000000000000000001E +:10DF0400000000000000000000000000000000000D +:10DF140000000000000000000000000000000000FD +:10DF240000000000000000000000000000000000ED +:10DF340000000000000000000000000000000000DD +:10DF440000000000000000000000000000000000CD +:10DF540000000000000000000000000000000000BD +:10DF640000000000000000000000000000000000AD +:10DF7400000000000000000000000000000000009D +:10DF8400000000000000000000000000000000008D +:10DF9400000000000000000000000000000000007D +:10DFA400000000000000000000000000000000006D +:10DFB400000000000000000000000000000000005D +:10DFC400000000000000000000000000000000004D +:10DFD400000000000000000000000000000000003D +:10DFE400000000000000000000000000000000002D +:10DFF400000000000000000000000000000000001D +:10E00400000000000000000000000000000000000C +:10E0140000000000000000000000000000000000FC +:10E0240000000000000000000000000000000000EC +:10E0340000000000000000000000000000000000DC +:10E0440000000000000000000000000000000000CC +:10E0540000000000000000000000000000000000BC +:10E0640000000000000000000000000000000000AC +:10E07400000000000000000000000000000000009C +:10E08400000000000000000000000000000000008C +:10E09400000000000000000000000000000000007C +:10E0A400000000000000000000000000000000006C +:10E0B400000000000000000000000000000000005C +:10E0C400000000000000000000000000000000004C +:10E0D400000000000000000000000000000000003C +:10E0E400000000000000000000000000000000002C +:10E0F400000000000000000000000000000000001C +:10E10400000000000000000000000000000000000B +:10E1140000000000000000000000000000000000FB +:10E1240000000000000000000000000000000000EB +:10E1340000000000000000000000000000000000DB +:10E1440000000000000000000000000000000000CB +:10E1540000000000000000000000000000000000BB +:10E1640000000000000000000000000000000000AB +:10E174000D0A0000FF007801800143028801870135 +:10E184008C018B01920191019501F601990198018D +:10E194009A013D029E012002A801A701AD01AC0134 +:10E1A400B001AF01B901B801BD01BC01BF01F70164 +:10E1B400C601C401C901C701CC01CA01DD018E0138 +:10E1C400F301F101F501F4013A02652C3C023B0232 +:10E1D4003E02662C4202410253028101540286012E +:10E1E4005602890157028A0159028F015B0290018C +:10E1F4006002930163029401680297016902960127 +:10E204006B02622C6F029C0172029D0175029F01D8 +:10E214007D02642C8002A6018302A9018802AE015A +:10E22400890244028A02B1018B02B2018C024502C6 +:10E234009202B7017B03FD037C03FE037D03FF030E +:10E24400AC038603C203A303CC038C03CD038E0368 +:10E25400CE038F03F203F903F803F703FB03FA0376 +:10E26400CF04C0047D1D632C511F591F531F5B1F16 +:10E27400551F5D1F571F5F1F781FF81F791FF91F58 +:10E28400B31FBC1FCC1FC31FE51FEC1FFC1FF31FD4 +:10E294004E21322184218321612C602C762C752C13 +:10E2A4006100E01AE000E017F800E0070001013027 +:10E2B40032010106390101104A01012E79010106DA +:10E2C40082010104A0010106B3010104CD01011082 +:10E2D400DE010112F8010128220201124602010A9C +:10E2E400AD03DB03B103E011C303E009D803011854 +:10E2F4003004E0205004B010600401228A04013686 +:10E30400C104010ED00401446105D026001E01960B +:10E31400A01E015A001F0808101F0806201F080825 +:10E32400301F0808401F0806601F0808701F4A02B3 +:10E33400721F5604761F64027A1F70027C1F7E02CD +:10E34400801F0808901F0808A01F0808B01F0802B3 +:10E35400D01F0802E01F08027021F010D024E61A32 +:10E36400302CD02F672C0106802C0164002D002650 +:10E3740041FFE01A1F1C1F1E1F1E1F1F1E1F1E1FF2 +:10E384001F1C1F1E1F1E1F1F1E1F1E1F6CC00F40A1 +:10E39400C0000000504F00000D8C00000CFF000076 +:10E3A40013000000000000000000000024851F404E +:10E3B4000BFF00001300000000000000000000003C +:10E3C40028851F400DFF000013000000000000001E +:10E3D4000000000020851F400A25240013000000CF +:10E3E40012000000120000000102030000000000FF +:10E3F4001C851F4000000000000000000000000019 +:10E4040000000000BD010000CD0500007D000000FB +:10E4140065050000D10600008501000039040000F4 +:10E424000000000000000000BD6B0000C96B00008C +:10E43400C16B0000F16C0000296B00007D730000CB +:10E4440009730000E9700000F1720000ED7400002F +:10E45400D96B00004D6B000081710000156B00004A +:10E46400196B0000216B0000256B0000396B000064 +:10E47400E1700000D9700000856F0000B11A00003F +:10E484001D6B00002D740000D16F0000916C000022 +:10E494000000000000000000BDAE0000B5AE0000AA +:10E4A400B1AE0000ADAE0000A9AE0000A5AE000004 +:10E4B400A1AE00009DAE00000000000000000000BE +:10E4C40025060000E10500007D0000003D05000078 +:10E4D400CD040000790600008D05000099080000B5 +:10E4E400450900000000000000000000BD0100001C +:10E4F400CD0500007D00000065050000D106000088 +:10E504008501000039040000000000000000000044 +:10E51400110800005108000021040000B9050000A2 +:10E524002D0700006D010000790500003D03000087 +:10E5340089070000E90300000504000099000000B9 +:10E54400850000009D02000051040000C10000008D +:10E5540059020000F101000081030000E9020000FB +:10E56400790400000000000000000000899A000007 +:10E57400A1AC00007D00000081000000899A000029 +:10E58400899A0000899A0000000000000000000041 +:10E59400411B0000911D0000411D0000051C0000EE +:10E5A400791C0000DD1C0000DD1D0000C91E0000F8 +:10E5B400051F000011200000000000000000000002 +:10E5C40019770000917700002D750000597A00003A +:10E5D40045840000957E0000291A0000ED790000B2 +:10E5E40079850000D57D00004D7D0000691A00008A +:10E5F400AD7A0000B9760000C5760000A51A0000C7 +:10E60400A91A0000AD1A0000D1760000ED760000D2 +:10E614000977000099780000E5770000517C00003C +:10E62400E17C0000D97B0000D8399D270054EA2AF8 +:10E6340000A4781F007B9A17380D002000000042C8 +:10E64400C8801F40B8821F4008000000000000423C +:10E65400C4801F40B4821F400400000000C0004278 +:10E6640024801F4014821F401000000000C000429C +:10E6740028801F4018821F402000000000C0004274 +:10E684002C801F401C821F404000000000C000423C +:10E6940034801F4024821F400001000000400042DB +:10E6A40064811F4054831F40000400000040004266 +:10E6B40080811F4070831F40000002000040004220 +:10E6C4007C811F406C831F40000001000040004219 +:10E6D40068811F4058831F4000080000004000422A +:10E6E4003C811F402C831F40010000000040004279 +:10E6F40044811F4034831F40040000000040004256 +:10E7040040811F4030831F4002000000004000424F +:10E7140048811F4038831F40080000000000004269 +:10E7240004811F40F4821F400000040000000042E6 +:10E7340008811F40F8821F400000080000000042CA +:10E7440018811F4008831F40000080000000004221 +:10E7540014811F4004831F40000040000000004259 +:10E7640000811F40F0821F400000020000000042B0 +:10E77400FC801F40EC821F400000010000000042AA +:10E7840024811F4014831F40000000040000004245 +:10E7940028811F4018831F40000000080000004229 +:10E7A4001C811F400C831F40000000010000004238 +:10E7B40020811F4010831F4000000002000000421F +:10E7C400EC801F40DC821F4000100000000000426B +:10E7D400F0801F40E0821F40002000000000004243 +:10E7E40034811F4024831F40000000400000004289 +:10E7F40038811F4028831F400000008000800042B1 +:10E8040094801F4084821F400000040000C0004226 +:10E8140090801F4080821F400000008000800042E2 +:10E82400A8801F4098821F400000800000800042A2 +:10E83400A4801F4094821F4000004000004000421A +:10E844006C811F405C831F400010000000C0004228 +:10E8540030801F4020821F408000000000400042A2 +:10E86400B0811F40A0831F400000002000400042F0 +:10E87400AC811F409C831F400000001000400042F8 +:10E8840084811F4074831F40000004000040004244 +:10E8940088811F4078831F40000008000000004268 +:10E8A4002C811F401C831F40000000100000004208 +:10E8B40030811F4020831F400000002000000042E0 +:10E8C4000C811F40FC821F40000010000000004229 +:10E8D40010811F4000831F40000020000080004280 +:10E8E400C8811F40B8831F400080000000800042A0 +:10E8F400C4811F40B4831F400040000000800042D8 +:10E90400C0811F40B0831F400020000000800042EF +:10E91400BC811F40AC831F400010000000800042F7 +:10E92400D0811F40C0831F400000020000800042CD +:10E93400CC811F40BC831F400000010000C0004286 +:10E9440074801F4064821F400000000100C0004228 +:10E9540080801F4070821F400000000800C00042F9 +:10E9640084801F4074821F400000001000C00042D9 +:10E974006C801F405C821F400000400000C00042C9 +:10E984007C801F406C821F400000000400C00042D5 +:10E9940078801F4068821F400000000200C00042CF +:10E9A40088801F4078821F4000000020696C6F2E11 +:10E9B400726F6D00696C6F3A206C6F616420726FC6 +:10E9C4006D0000002E0000000A696C6F3A20726F1F +:10E9D4006D206C6F6164656400000000696C6F2ECB +:10E9E400626C6F00696C6F3A207072657061726559 +:10E9F400206D656D6F727900696C6F3A2070726575 +:10EA04007061726520692F6F2070696E7300000059 +:10EA1400696C6F3A20636865636B20666F7220537C +:10EA2400442063617264000021212121206361720A +:10EA340064206661696C65642C206F72206E6F744B +:10EA44002070726573656E743B20636865636B2028 +:10EA54005344206361726420616E64207265737430 +:10EA640061727400696C6F3A20636865636B206639 +:10EA74006F7220696C6F2E726F6D0000212121214D +:10EA8400206D697373696E6720696C6F2E726F6D88 +:10EA94003B20636865636B20534420636172642088 +:10EAA400616E64207265737461727400696C6F3A8C +:10EAB40020636865636B20666F7220696C6F2E62D9 +:10EAC4006C6F000021212121206D697373696E67C9 +:10EAD40020696C6F2E626C6F3B20636865636B20EA +:10EAE4005344206361726420616E642072657374A0 +:10EAF4006172740044657669636520697320746F7C +:10EB04006F20736D616C6C0D0A000000577269749C +:10EB1400696E6720464154200000000057726974F2 +:10EB2400696E6720757063617365207461626C65DA +:10EB34000D0A000057726974696E6720726F6F74F2 +:10EB44000D0A0000466F726D617420646F6E650D6E +:10EB54000A000000466F726D6174206661696C651D +:10EB6400640D0A0045584641540000004261642087 +:10EB7400636C757374657220636F756E740D0A002F +:10EB84004361726420697320746F6F20736D616CCC +:10EB94006C2E0D0A00000000466F726D61742044F3 +:10EBA4006F6E650D0A000000466F726D6174204639 +:10EBB40061696C65640D0A0000010000E81500201D +:10EBC40012000000000600003C1F00600A00000064 +:10EBD40000020000F01E00604B000000000700006F +:10EBE400A41E00604B00000000030000A01E006093 +:10EBF4000000000001030904881E006000000000FA +:10EC040002030904701E00600000000003030904ED +:10EC140000160020000000000000000000000000BA +:10EC2400000000000000000000000000241000208C +:10EC34008C100020F41000200000000000000000F0 +:10EC440000000000000000000000000000000000C0 +:10EC540000000000000000000000000000000000B0 +:10EC640000000000000000000000000000000000A0 +:10EC74000000000000000000000000000000000090 +:10EC84000000000000000000000000000000000080 +:10EC94000000000000000000000000000000000070 +:10ECA4000000000000000000000000000000000060 +:10ECB4000000000000000000000000000000000050 +:10ECC4000000000000000000000000000000000040 +:10ECD40001000000000000000E33CDAB34126DE6DD +:10ECE400ECDE05000B000000000000000000000046 +:10ECF4000000000000000000000000000000000010 +:10ED040000000000000000000000000000000000FF +:10ED140000000000000000000000000000000000EF +:10ED240000000000000000000000000000000000DF +:10ED340000000000000000000000000000000000CF +:10ED440000000000000000000000000000000000BF +:10ED540000000000000000000000000000000000AF +:10ED6400000000000000000000000000000000009F +:10ED7400000000000000000000000000000000008F +:10ED8400000000000000000000000000000000007F +:10ED9400000000000000000000000000000000006F +:10EDA400000000000000000000000000000000005F +:10EDB400000000000000000000000000000000004F +:10EDC400000000000000000000000000000000003F +:10EDD400000000000000000000000000000000002F +:10EDE400000000000000000000000000000000001F +:10EDF400000000000000000000000000000000000F +:10EE040000000000000000000000000000000000FE +:10EE140000000000000000000000000000000000EE +:10EE240000000000000000000000000000000000DE +:10EE340000000000000000000000000000000000CE +:10EE440000000000000000000000000000000000BE +:10EE540000000000000000000000000000000000AE +:10EE6400000000000000000000000000000000009E +:10EE7400000000000000000000000000000000008E +:10EE8400000000000000000000000000000000007E +:10EE9400000000000000000000000000000000006E +:10EEA400000000000000000000000000000000005E +:10EEB400000000000000000000000000000000004E +:10EEC400000000000000000000000000000000003E +:10EED400000000000000000000000000000000002E +:10EEE400000000000000000000000000000000001E +:10EEF400000000000000000000000000000000000E +:10EF040000000000000000000000000000000000FD +:10EF140000000000000000000000000000000000ED +:10EF240000000000000000000000000000000000DD +:10EF340000000000000000000000000000000000CD +:10EF440000000000000000000000000000000000BD +:10EF540000000000000000000000000000000000AD +:10EF6400000000000000000000000000000000009D +:10EF7400000000000000000000000000000000008D +:10EF8400000000000000000000000000000000007D +:10EF9400000000000000000000000000000000006D +:10EFA400000000000000000000000000000000005D +:10EFB400000000000000000000000000000000004D +:10EFC400000000000000000000000000000000003D +:10EFD400000000000000000000000000000000002D +:10EFE400000000000000000000000000000000001D +:10EFF400000000000000000000000000000000000D +:10F0040000000000000000000000000000000000FC +:10F0140000000000000000000000000000000000EC +:10F0240000000000000000000000000000000000DC +:10F0340000000000000000000000000000000000CC +:10F0440000000000000000000000000000000000BC +:10F05400000000000029DE07007B9A1700003A40F8 +:10F064009C040020000000000000000000000000DC +:10F07400000000000000000000000000000000008C +:10F08400000000000000000000000000000000007C +:10F09400000000000000000000000000000000006C +:10F0A400000000000000000000000000A80500208F +:10F0B40000000000E8030000000000002C01000034 +:10F0C400603020200000000000000000D411002067 +:10F0D400D4110020DC110020DC110020E4110020F8 +:10F0E400E4110020EC110020EC110020F4110020A8 +:10F0F400F4110020FC110020FC1100200412002057 +:10F10400041200200C1200200C1200201412002003 +:10F11400141200201C1200201C12002024120020B3 +:10F12400241200202C1200202C1200203412002063 +:10F13400341200203C1200203C1200204412002013 +:10F14400441200204C1200204C12002054120020C3 +:10F15400541200205C1200205C1200206412002073 +:10F16400641200206C1200206C1200207412002023 +:10F17400741200207C1200207C12002084120020D3 +:10F18400841200208C1200208C1200209412002083 +:10F19400941200209C1200209C120020A412002033 +:10F1A400A4120020AC120020AC120020B4120020E3 +:10F1B400B4120020BC120020BC120020C412002093 +:10F1C400C4120020CC120020CC120020D412002043 +:10F1D400D4120020DC120020DC120020E4120020F3 +:10F1E400E4120020EC120020EC120020F4120020A3 +:10F1F400F4120020FC120020FC1200200413002052 +:10F20400041300200C1300200C13002014130020FE +:10F21400141300201C1300201C13002024130020AE +:10F22400241300202C1300202C130020341300205E +:10F23400341300203C1300203C130020441300200E +:10F24400441300204C1300204C13002054130020BE +:10F25400541300205C1300205C130020641300206E +:10F26400641300206C1300206C130020741300201E +:10F27400741300207C1300207C13002084130020CE +:10F28400841300208C1300208C130020941300207E +:10F29400941300209C1300209C130020A41300202E +:10F2A400A4130020AC130020AC130020B4130020DE +:10F2B400B4130020BC130020BC130020C41300208E +:10F2C400C4130020CC130020CC130020D41300203E +:10F2D400D4130020DC130020DC130020E4130020EE +:10F2E400E4130020EC130020EC130020F41300209E +:10F2F400F4130020FC130020FC130020041400204D +:10F30400041400200C1400200C14002014140020F9 +:10F31400141400201C1400201C14002024140020A9 +:10F32400241400202C1400202C1400203414002059 +:10F33400341400203C1400203C1400204414002009 +:10F34400441400204C1400204C14002054140020B9 +:10F35400541400205C1400205C1400206414002069 +:10F36400641400206C1400206C1400207414002019 +:10F37400741400207C1400207C14002084140020C9 +:10F38400841400208C1400208C1400209414002079 +:10F39400941400209C1400209C140020A414002029 +:10F3A400A4140020AC140020AC140020B4140020D9 +:10F3B400B4140020BC140020BC140020C414002089 +:10F3C400C4140020CC140020CC140020D414002039 +:10F3D400D4140020DC140020DC140020E4140020E9 +:10F3E400E4140020EC140020EC140020F414002099 +:10F3F400F4140020FC140020FC1400200415002048 +:10F40400041500200C1500200C15002014150020F4 +:10F41400141500201C1500201C15002024150020A4 +:10F42400241500202C1500202C1500203415002054 +:10F43400341500203C1500203C1500204415002004 +:10F44400441500204C1500204C15002054150020B4 +:10F45400541500205C1500205C1500206415002064 +:10F46400641500206C1500206C1500207415002014 +:10F47400741500207C1500207C15002084150020C4 +:10F48400841500208C1500208C1500209415002074 +:10F49400941500209C1500209C150020A415002024 +:10F4A400A4150020AC150020AC150020B4150020D4 +:10F4B400B4150020BC150020BC150020C415002084 +:10F4C400C4150020CC150020CC150020FFFFFFFF41 +:10F4D40000000200380D002012010002EF0201407A +:10F4E400C016830480020102030100000D00000025 +:10F4F4000C030000000000000000000000000000F9 +:10F5040000000000000029010000000000000000CD +:10F5140000000000000000000000000000000000E7 +:10F5240000000000000000000000000000000000D7 +:10F5340000000000000000000000000000000000C7 +:10F5440000000000000000000000000000000000B7 +:10F5540000000000000000000000000000000000A7 +:10F564000000000000000000000000000000000097 +:10F574000000000000000000000000000000000087 +:10F584000000000000000000000000000000000077 +:10F594000000000000000000000000000000000067 +:10F5A4000000000000000000000000000000000057 +:10F5B4000000000000000000000000000000000047 +:10F5C4000000000000000000000000000000000037 +:10F5D4000000000000000000000000000000000027 +:10F5E4000000000000000000000000000000000017 +:10F5F4000000000000000000000000000000000007 +:10F6040000000000000000000000000000000000F6 +:10F6140000000000000000000000000000000000E6 +:10F6240000000000000000000000000000000000D6 +:10F6340000000000000000000000000000000000C6 +:10F6440000000000000000000000000000000000B6 +:10F6540000000000000000000000000000000000A6 +:10F664000000000000000000000000000000000096 +:10F674000000000000000000000000000000000086 +:10F684000000000000000000000000000000000076 +:10F694000000000000000000000000000000000066 +:10F6A4000000000000000000000000000000000056 +:10F6B4000000000000000000000000000000000046 +:10F6C4000000000000000000000000000000000036 +:10F6D4000000000000000000000000000000000026 +:10F6E4000000000000000000000000000000000016 +:10F6F4000000000000000000000000000000000006 +:10F7040000000000000000000000000000000000F5 +:10F7140000000000000000000000000000000000E5 +:10F7240000000000000000000000000000000000D5 +:10F7340000000000000000000000000000000000C5 +:10F7440000000000000000000000000000000000B5 +:10F7540000000000000000000000000000000000A5 +:10F764000000000000000000000000000000000095 +:10F774000000000000000000000000000000000085 +:10F784000000000000000000000000000000000075 +:10F794000000000000000000000000000000000065 +:10F7A4000000000000000000000000000000000055 +:10F7B4000000000000000000000000000000000045 +:10F7C4000000000000000000000000000000000035 +:10F7D4000000000000000000000000000000000025 +:10F7E4000000000000000000000000000000000015 +:10F7F4000000000000000000000000000000000005 +:10F8040000000000000000000000000000000000F4 +:10F8140000000000000000000000000000000000E4 +:10F8240000000000000000000000000000000000D4 +:10F8340000000000000000000000000000000000C4 +:10F8440000000000000000000000000000000000B4 +:10F8540000000000000000000000000000000000A4 +:10F864000000000000000000000000000000000094 +:10F874000000000000000000000000000000000084 +:10F884000000000000000000000000000000000074 +:10F894000000000000000000000000000000000064 +:10F8A4000000000000000000000000000000000054 +:10F8B4000000000000000000000000000000000044 +:10F8C4000000000000000000000000000000000034 +:10F8D4000000000000000000000000000000000024 +:10F8E4000000000000000000000000000000000014 +:10F8F4000000000000000000000000000000000004 +:10F9040000000000000000000000000000000000F3 +:10F9140000000000000000000000000000000000E3 +:10F9240000000000000000000000000000000000D3 +:10F9340000000000000000000000000000000000C3 +:10F9440000000000000000000000000000000000B3 +:10F9540000000000000000000000000000000000A3 +:10F964000000000000000000000000000000000093 +:10F974000000000000000000000000000000000083 +:10F984000000000000000000000000000000000073 +:10F994000000000000000000000000000000000063 +:10F9A4000000000000000000000000000000000053 +:10F9B400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +:10F9C400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +:10F9D400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +:10F9E400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +:10F9F400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +:10FA0400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +:10FA1400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +:10FA2400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +:10FA3400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +:10FA4400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +:10FA5400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +:10FA6400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +:10FA7400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +:10FA8400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +:10FA9400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +:10FAA400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +:10FAB400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +:10FAC400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +:10FAD400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +:10FAE400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +:10FAF400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +:10FB0400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +:10FB1400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +:10FB2400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +:10FB3400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +:10FB4400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +:10FB5400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +:10FB6400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +:10FB7400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +:10FB8400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +:10FB9400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +:10FBA400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +:10FBB400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +:10FBC400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +:10FBD400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +:10FBE400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +:10FBF400FFFFFFFFFFFFFFFFFFFFFFFF000000000D +:10FC040000000000000000000000000000000000F0 +:10FC140000000000000000000000000000000000E0 +:10FC240000000000000000000000000000000000D0 +:10FC340000000000000000000000000000000000C0 +:10FC440000000000000000000000000000000000B0 +:10FC540000000000000000000000000000000000A0 +:10FC64000000000000000000000000000000000090 +:10FC74000000000000000000000000000000000080 +:10FC84000000000000000000000000000000000070 +:10FC94000000000000000000000000000000000060 +:10FCA4000000000000000000000000000000000050 +:10FCB4000000000000000000000000000000000040 +:10FCC4000000000000000000000000000000000030 +:10FCD4000000000000000000000000000000000020 +:10FCE4000000000000000000000000000000000010 +:10FCF4000000000000000000000000000000000000 +:10FD040000000000000000000000000000000000EF +:10FD140000000000000000000000000000000000DF +:10FD240000000000000000000000000000000000CF +:10FD340000000000000000000000000000000000BF +:10FD440000000000000000000000000000000000AF +:10FD5400000000000000000000000000000000009F +:10FD6400000000000000000000000000000000008F +:10FD7400000000000000000000000000000000007F +:10FD8400000000000000000000000000000000006F +:10FD9400000000000000000000000000000000005F +:10FDA400000000000000000000000000000000004F +:10FDB400000000000000000000000000000000003F +:10FDC400000000000000000000000000000000002F +:10FDD400000000000000000000000000000000001F +:10FDE400000000000000000000000000000000000F +:10FDF40000000000000000000000000000000000FF +:10FE040000000000000000000000000000000000EE +:10FE140000000000000000000000000000000000DE +:10FE240000000000000000000000000000000000CE +:10FE340000000000000000000000000000000000BE +:10FE440000000000000000000000000000000000AE +:10FE5400000000000000000000000000000000009E +:10FE6400000000000000000000000000000000008E +:10FE7400000000000000000000000000000000007E +:10FE8400000000000000000000000000000000006E +:10FE9400000000000000000000000000000000005E +:10FEA400000000000000000000000000000000004E +:10FEB400000000000000000000000000000000003E +:10FEC400000000000000000000000000000000002E +:10FED400000000000000000000000000000000001E +:10FEE400000000000000000000000000000000000E +:10FEF40000000000000000000000000000000000FE +:10FF040000000000000000000000000000000000ED +:10FF140000000000000000000000000000000000DD +:10FF240000000000000000000000000000000000CD +:10FF340000000000000000000000000000000000BD +:10FF440000000000000000000000000000000000AD +:10FF5400000000000000000000000000000000009D +:10FF6400000000000000000000000000000000008D +:10FF7400000000000000000000000000000000007D +:10FF8400000000000000000000000000000000006D +:10FF9400000000000000000000000000000000005D +:10FFA400000000000000000000000000000000004D +:10FFB400000000000000000000000000000000003D +:10FFC400000000000000000000000000000000002D +:10FFD400000000000000000000000000000000001D +:10FFE400000000000000000000000000000000000D +:0CFFF40000000000000000000000000001 +:02000004600199 +:1000000000000000000000000000000000000000F0 +:1000100000000000000000000000000000000000E0 +:1000200000000000000000000000000000000000D0 +:1000300000000000000000000000000000000000C0 +:1000400000000000000000000000000000000000B0 +:1000500000000000000000000000000000000000A0 +:100060000000000000000000000000000000000090 +:100070000000000000000000000000000000000080 +:100080000000000000000000000000000000000070 +:100090000000000000000000000000000000000060 +:1000A0000000000000000000000000000000000050 +:1000B0000000000000000000000000000000000040 +:1000C0000000000000000000000000000000000030 +:1000D0000000000000000000000000000000000020 +:1000E0000000000000000000000000000000000010 +:1000F0000000000000000000000000000000000000 +:1001000000000000000000000000000000000000EF +:1001100000000000000000000000000000000000DF +:1001200000000000000000000000000000000000CF +:1001300000000000000000000000000000000000BF +:1001400000000000000000000000000000000000AF +:10015000000000000000000000000000000000009F +:10016000000000000000000000000000000000008F +:10017000000000000000000000000000000000007F +:10018000000000000000000000000000000000006F +:10019000000000000000000000000000000000005F +:1001A000000000000000000000000000000000004F +:1001B000000000000000000000000000000000003F +:1001C000000000000000000000000000000000002F +:1001D000000000000000000000000000000000001F +:1001E000000000000000000000000000000000000F +:1001F00000000000000000000000000000000000FF +:1002000000000000000000000000000000000000EE +:1002100000000000000000000000000000000000DE +:1002200000000000000000000000000000000000CE +:1002300000000000000000000000000000000000BE +:1002400000000000000000000000000000000000AE +:10025000000000000000000000000000000000009E +:10026000000000000000000000000000000000008E +:10027000000000000000000000000000000000007E +:10028000000000000000000000000000000000006E +:10029000000000000000000000000000000000005E +:1002A000000000000000000000000000000000004E +:1002B000000000000000000000000000000000003E +:1002C000000000000000000000000000000000002E +:1002D000000000000000000000000000000000001E +:1002E000000000000000000000000000000000000E +:1002F00000000000000000000000000000000000FE +:1003000000000000000000000000000000000000ED +:1003100000000000000000000000000000000000DD +:1003200000000000000000000000000000000000CD +:1003300000000000000000000000000000000000BD +:1003400000000000000000000000000000000000AD +:10035000000000000000000000000000000000009D +:10036000000000000000000000000000000000008D +:10037000000000000000000000000000000000007D +:10038000000000000000000000000000000000006D +:10039000000000000000000000000000000000005D +:1003A000000000000000000000000000000000004D +:1003B000000000000000000000000000000000003D +:1003C000000000000000000000000000000000002D +:1003D000000000000000000000000000000000001D +:1003E000000000000000000000000000000000000D +:1003F00000000000000000000000000000000000FD +:1004000000000000000000000000000000000000EC +:1004100000000000000000000000000000000000DC +:1004200000000000000000000000000000000000CC +:1004300000000000000000000000000000000000BC +:1004400000000000000000000000000000000000AC +:10045000000000000000000000000000000000009C +:10046000000000000000000000000000000000008C +:10047000000000000000000000000000000000007C +:10048000000000000000000000000000000000006C +:10049000000000000000000000000000000000005C +:1004A000000000000000000000000000000000004C +:1004B000000000000000000000000000000000003C +:1004C000000000000000000000000000000000002C +:1004D000000000000000000000000000000000001C +:1004E000000000000000000000000000000000000C +:1004F00000000000000000000000000000000000FC +:1005000000000000000000000000000000000000EB +:1005100000000000000000000000000000000000DB +:1005200000000000000000000000000000000000CB +:1005300000000000000000000000000000000000BB +:1005400000000000000000000000000000000000AB +:10055000000000000000000000000000000000009B +:10056000000000000000000000000000000000008B +:10057000000000000000000000000000000000007B +:10058000000000000000000000000000000000006B +:10059000000000000000000000000000000000005B +:1005A000000000000000000000000000000000004B +:1005B000000000000000000000000000000000003B +:1005C000000000000000000000000000000000002B +:1005D000000000000000000000000000000000001B +:1005E000000000000000000000000000000000000B +:1005F00000000000000000000000000000000000FB +:1006000000000000000000000000000000000000EA +:1006100000000000000000000000000000000000DA +:1006200000000000000000000000000000000000CA +:1006300000000000000000000000000000000000BA +:1006400000000000000000000000000000000000AA +:10065000000000000000000000000000000000009A +:10066000000000000000000000000000000000008A +:10067000000000000000000000000000000000007A +:10068000000000000000000000000000000000006A +:10069000000000000000000000000000000000005A +:1006A000000000000000000000000000000000004A +:1006B000000000000000000000000000000000003A +:1006C000000000000000000000000000000000002A +:1006D000000000000000000000000000000000001A +:1006E000000000000000000000000000000000000A +:1006F00000000000000000000000000000000000FA +:1007000000000000000000000000000000000000E9 +:1007100000000000000000000000000000000000D9 +:1007200000000000000000000000000000000000C9 +:1007300000000000000000000000000000000000B9 +:1007400000000000000000000000000000000000A9 +:100750000000000000000000000000000000000099 +:100760000000000000000000000000000000000089 +:100770000000000000000000000000000000000079 +:100780000000000000000000000000000000000069 +:100790000000000000000000000000000000000059 +:1007A0000000000000000000000000000000000049 +:1007B0000000000000000000000000000000000039 +:1007C0000000000000000000000000000000000029 +:1007D0000000000000000000000000000000000019 +:1007E0000000000000000000000000000000000009 +:1007F00000000000000000000000000000000000F9 +:040000056000100087 +:00000001FF diff --git a/binaries/ilo-universal-darwin b/binaries/ilo-universal-darwin new file mode 100755 index 0000000000000000000000000000000000000000..d856431b0b93ec11afc26df26e093b2e31e1606c GIT binary patch literal 99920 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%0AJru6RU?PO>vZAkzm{Vx=WngJZ%O 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%0D09ltr`vVdQfq;Zm#QSBMKt`3OkHX3@Ki*6P zWumUb%|iOjthVqJN)@dL!aO71Ff4&RIE$UK!zbH0>EpFoNxPGwy7p9p{H7UsEKAiH z6fCN)ZVC);&^$94^(K38Mk@lcFs^|a5&v=yM$k?;)TA7Ra=Nkwfiz_jSaf}>tvP|5 zRUX5UNRb&`IW4+`fh9yiAj<3(8e*Z^RQr%*YJx!7uaQ36=>7@Pg!2>QlqLmBLmJu~1l zP=av|wxT`Y2)QU$x_H$kpgaXcv!KRoSQQ!gV}R1An@KhxdqpzNFhwg&3^f2_ZYWR< zP@82-pDpSc$9(xfDw}Pu#bGRNL1bF*FB5-CN<|Noy;T3oX5>*lK#7+%3^5*Wv_CDK zU*e}XrGuf(SQxR|ZU&9BUHYO#Dh~yUs#U)leP%?5d?1)Nx<=rKAR#5u1Q{`i2=bXw uU^1Pzay>dE(lS+{N^Mh+{dytSHDa_!dL2=O=%icZC()35)o{o@*Z&3Q>xxYP literal 0 HcmV?d00001 diff --git a/binaries/ilo-x86-dos.exe b/binaries/ilo-x86-dos.exe new file mode 100644 index 0000000000000000000000000000000000000000..b8c88f5e2e5cde25ce0ac746b462e19c172e6aa6 GIT binary patch literal 22008 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 literal 0 HcmV?d00001 diff --git a/binaries/ilo-x86-freebsd b/binaries/ilo-x86-freebsd new file mode 100755 index 0000000000000000000000000000000000000000..f584b0c65f190246e675273c4aa3f207072bcf99 GIT binary patch literal 5308 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 literal 0 HcmV?d00001 diff --git a/binaries/ilo-x86-linux b/binaries/ilo-x86-linux new file mode 100755 index 0000000000000000000000000000000000000000..95c77e6d5a08d310b049ae0e3a7ceb8abb4c645c GIT binary patch literal 9196 zcmeHNZ)_Ar6rXGNV4+v9N{fIso^U2LCdUxDNsBrrM10?K}C|I z)XiB!v^60SX(`bfNt8sJ8iToVz|j!W50D6f7(Y;)bx|>pP(fLLZ)Wc-2N=Gy)BJ8` z-tWzOZ{C~TbT|86#o|hb!@&|Qjioc1`S&Pl0s6DEB~!pW%*pcDWHw3g34OLhQO}Yd zppY<&Ngh3e4T3p|F@kd<@4=)OJkXlP7~zif#7Dss&<-gIJfp$xva!$x8m6|%5C|Ko zggv)2U}wP2fSmz519k@N4A>d4Ghk=H&VZc(I|C1S25RF@6_426cnps_6^!;{q>Y6y zUFD-l4L^W~?)>OTY~vpJ$4{B2IYe&=zNgHc-eKGxqUZX^YOfMm>{TNxyspzbVng(- zPBI#&--D;;^wc%e?w0i(Jf^B$0W+d>crem(XdbH-;$m&ApQe#owO-2>d@Szlg#>n3 z+)11q4OpXCtu|H@zM=*Pv4JLLE}#wbBJ3!9EUP0L@@la_klrB#Js@g$DHtu+%YEo0 z^?yTY#MppqDFvwsHmj@g`l>Z+>nHdaB850VOx*+@ zh+6nqDAvKJ@Ud0SQhY3-weazbU?=*hi&UsJRpIemcc&jUHN745MyHQ5UffT=R5?Ve z<;r*bRALm z&Z_@eYh?3ksacJ8R)nDci8o*}K?oPxg#{hC=y3Sm-BDxa zeW;$OdoX(AoTkXEv?bCPxy#5WQRD1=jO>pZ-$@E_!Dl49hiYbBRQk$fWESlbk%f7h zhGIZbT!y+osV3`&$Q@Eszku3CGR3uAVn(Eu=d!!VmoX!iaDOEk%e~QODZGliz&={C z_ePOeO0~vR%NA1o>*U^({-2iqjWu$2N%<5@UYR1#x8%MQ`5CX+u`xYWUL@r5wxrKR z0Q{v}I4m(cEHTdW zn>U4_Yt+T~6?Bf_!jtZuN5xukZ52}nu(-^)%uhifJU-doc>p}F#!xSABZCkwZ*l|~ zl$zK9>i9NNJeFm=8%Piiz8o_54^HBVTG7=wzG_Xqz64=g!_WR3{sm?JC4S;gI^4Ll zOv5k7^a|MU(v`P>YR(r!OI)k4s#U0#t>+UJw-^jVtp&7;(oKxG#T6OAY-`4C$4*J^;3#X1c@~hR4Tm+_lq^P&h&q2QocmvoCd;y#Reg~#> zD{3CF6lem%z(HUX_ysV5$9oiYE)W2Efl=TRkoK{nJ_+Oj^MOUcQeYLZX>*Hj-R73{ zueUQAwzV`fmTi^Av28hXyrVjva4E|B_`Yr3D>+dTFQJIY_s_tR2he>5dM@m{1G?4NOVVz| zuJo{yeldM2*(IwL8RhpGZ<{DjsKb;82*P&Tb<-@yIB6R>2wD50+8Gg7d&|-n_D++Y4qg#ee-?!YhT+Gn&+RF?=P5F z@T?{CBm|84+Jo((wot=5<_k5x6=FCK8yZ3l%-0xPyRogIxsmzSwYM|h`j+PA#w{W8 z`G740dI(j1S3=*a;4sm5Dv5@vXpiET^zeKuzgh7x_BoBMMrEKj6G-R{;JItS!`Mj@ ySS_J92Xhs`+W_&6OY3a;eG5&gdBm?gleFA#%}Foc8dFDH0>YNX_1!~{sDA-5RN^-P literal 0 HcmV?d00001 diff --git a/binaries/ilo-x86-netbsd b/binaries/ilo-x86-netbsd new file mode 100644 index 0000000000000000000000000000000000000000..b8de6899a3f6abadbdc843df1b483b8a872817d5 GIT binary patch literal 11148 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 literal 0 HcmV?d00001 diff --git a/binaries/ilo-x86-openbsd b/binaries/ilo-x86-openbsd new file mode 100755 index 0000000000000000000000000000000000000000..4b6c82465832bdbc08af726371e33082e6e357d0 GIT binary patch literal 13720 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 literal 0 HcmV?d00001 diff --git a/binaries/ilo-x86-windows.exe b/binaries/ilo-x86-windows.exe new file mode 100644 index 0000000000000000000000000000000000000000..4969bd74bf06b7b9e49e0b4b933fd46ce688d727 GIT binary patch literal 5632 zcmeHLeQX>@6`!@w?)h__)ah4>a-ohyB4fo31T|3UguGzUTv7PgK0G{dyeJo!icJva>C( zZ7(SMU)z4*$oOO=lT9Da#wQ}9@l-0Ei;N^9*+)~6@l<5s^Iwciq{k9{9UZMb5?a?7 z+pjd#87eciu}x{N<3+Y%*oC&6*ioksHS(Jtm$E2&;D0a0#JYqa>5;OaH9|}l0p3SM z?}L2}0(amVkbSwtR1WhN`9y6qT74K;gt0??WAR)ZQ_*Iu3z$Nt8`Sqi87umR@2h*z z{Oj}zX`J9qC;OvprdTyaCt4~uym%TMrNkARBwn4pS~%*6`XsfmsrcnYI+;zUfaA!T zO;4jQMQGDb6n?ERrVBxxH|^d#z;x?^%Gk_YyQ!^lZOtgE$D1H&i`P!{ARK~9@7^fW zA)s5oaO6e*=b|67j#aDG06Q=SC21#Bv$GEJs1NeX4x~hDC$Fv9cdAuWTeV&iv{Ju{ zUa^X<8amf1rE>d=P-H`n$K5XcDn*Z0qLd1h2>Os%#l=n$0nuL){ZO6x0crkIb>`*b z9P>{)5F&_In}5oMe;4x;?mU8ff1UY(M*M@Mk_k@o;JK3mZBOT1B;98 zHcQA9+IMH@t(Ysi_59n_>daioz5)oT+@KmegfeBMFS{W9n3SIPq#IS^&H!mA^%N(q z%~CC~?YyTNQjG@!RJlSy6Q6<4x)=|FaZY>|ukZ#_q7&2oRwQ7~eE!oat71%Nt^iYLa zxVHLM)!0SIUy{i8y2ywx^QoNkRN7QyPtB}9V9x5-N9$XjZo6uHTj)~W`8Rdl*1Nf3 z#>(!-H}Fk&Er_I3e^jiUS>&i-itnX>GYNZKb`!^+mRD}5ExTg_eq0Rjd>@eKdFxIdB*c^|o{rJs)^Vpng&#y)jMJb^b%`SVN=fF*>@nFpX zztYu7Qae-3*vr0L-M+wMFS|y4`)yx9nJyQ3^9F1bd^TEOqYz{x>)E(v12)e3Z1ls% z*&rL8o{d{ogKAqZ;a&Y&Y}`C`gJ;IhxH1i9>@>$;%OA=-b|%QuNz~IaVz+I;(kY*% zlRS13mMT1UD#+44&(c=a_yN{rJ-13fhL-gcL07CF3VK=m0_fH+F{0mY&7xn50~7>p z#dic~m+2#wM~K2(@0wSS-&_lom)CBQqgjJ6#}OFB$_U)98YARa zoAj$u`t{bo$WQ19PdDCqG48o;bUxz9ci@)(iQ7odCX4WAr$bR1AqbwBs z-w~g-L_&uo|Ig&zF^`Wz?KZ+00blHrESG3=q$-NBEf^u_3X`)`+sRqfT6bXNWV3F) z{!d?drdvg4=)?nJ@;XC3S=dvTD(mSo?%`N;9*&C~370B0=9G`wE9AeL?}e41f;^2Hh3wXs?#r*#BZX> z3id0GoX3(1AQ(L;Mxng6DDSp;?V_I7%4nB#OB1u*96SylCtibyJ1)ITTwBtuT@Jvj zvyLP0^8QY5&%u1MCp2W*(>C274dtUm?xxo_S9X>R#VniWdANEAr_IW&^(IxIjI&wm z4fJ$tS-gJ>_~|)R!fci&EbD?`(kjuZ{%2d1ZH^$+FMx57Cws#AfgbqD`irI(8hZv@ zW@_O=FJw%uy$}(!i)Op?T6pX^5_s5IM|H;_;t$*%`z6&SJs|0Qk{*(DOwuEgCMC^C znv--&(r-xmxTMDgB^UnxtdBrs#~5p6a2NHRTobW(J)=?Pcz`@7v9V+-ih|Fwdi zKY{-jv}Lqaw71ckasTT;>qgs()`QlM_Gz>)pxuvl7%h!P&j*1qG5NL8Y_4xCnFQc) zI+I8d%_ibwL`Re9$pm$dWyf=(lblQ>juK})Jpz(>G&c%zI3Y+TJD$otLbIdkR4$uN zK9Zrq@MI!49M5EibB|>N$S~w5;^V1!_V6SG5>w+jlDls-ll#ngGMC8G$mJ%cMiZIb R@R4|GESbpe!PNiq`7f&nsE7an literal 0 HcmV?d00001 diff --git a/binaries/ilo.jar b/binaries/ilo.jar new file mode 100644 index 0000000000000000000000000000000000000000..cda7b312bec7b3c5abd5a56f1835c9aee0f0caff GIT binary patch literal 159956 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�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 literal 0 HcmV?d00001 diff --git a/source/ilo-68k-mac.c b/source/ilo-68k-mac.c new file mode 100644 index 0000000..55fd8e8 --- /dev/null +++ b/source/ilo-68k-mac.c @@ -0,0 +1 @@ +/* ilo for System 6 / Mac 68k Copyright (c) 2022, Charles Childers Deriving from the ilo for MS-DOS, this makes use of an internally segmented memory model. The 68k CPU is big endian. Since the ilo images and blocks are stored in little endian a fix() function has been written and is used to convert between the formats as needed. As with all ilo systems, this needs an ilo.rom and ilo.blocks. It's likely to crash if these are not present. I'm building this using Think C 5.0.2, using the ANSI library. It's not tested with any other compiler on 68k. */ #include #include #define SLICES 8 #define SLICESIZE 8192 long ip, sp, rp, data[32], address[256]; long *memory[SLICES]; #define TOS data[sp] #define NOS data[sp-1] #define TORS address[rp] unsigned long fix(unsigned long v) { return (((v & 0x000000FF) << 24)| ((v & 0x0000FF00) << 8) | ((v & 0x00FF0000) >> 8) | ((v & 0xFF000000) >> 24)); } long pop() { sp--; return data[sp + 1]; } void push(long value) { sp++; data[sp] = value; } void store(long a, long v) { long slice = a / SLICESIZE; long actual = a - (slice * SLICESIZE); memory[slice][actual] = v; } long fetch(long a) { long slice = a / SLICESIZE; long actual = a - (slice * SLICESIZE); return memory[slice][actual]; } void prepare_vm() { for (ip = 0; ip < 32; ip++) data[ip] = 0; for (ip = 0; ip < 128; ip++) address[ip] = 0; ip = sp = rp = 0; } void load_image() { FILE *fp; long x, y, z; fp = fopen("ilo.rom", "rb"); for (y = 0; y < 65536; y++) { x = 0; fread(&x, 4, 1, fp); store(y, fix(x)); } fclose(fp); prepare_vm(); } void save_image() { FILE *fp; long i, x; fp = fopen("ilo.rom", "wb"); for (i = 0; i < 65536; i++) { x = fix(fetch(i)); fwrite(&x, 4, 1, fp); } fclose(fp); } void read_block() { FILE *f; long block, buffer, x, c; buffer = pop(); block = pop(); f = fopen("ilo.blocks", "r+b"); fseek(f, 4096 * block, SEEK_SET); for (x = 0; x < 1024; x++) { c = 0; fread(&c, 4, 1, f); store(buffer + x, fix(c)); } fclose(f); } void write_block() { FILE *f; long block, buffer, x, c; buffer = pop(); block = pop(); f = fopen("ilo.blocks", "r+b"); fseek(f, 4096 * block, SEEK_SET); for (x = 0; x < 1024; x++) { c = fix(fetch(buffer + x)); fwrite(&c, 4, 1, f); } fclose(f); } void process(long o) { long a, b, target, flag; long src, dest, len; switch (o) { case 0: break; case 1: ip++; push(fetch(ip)); break; case 2: push(TOS); break; case 3: data[sp] = 0; sp--; break; case 4: a = TOS; TOS = NOS; NOS = a; break; case 5: rp++; TORS = pop(); break; case 6: push(TORS); rp--; break; case 7: ip = pop() - 1; break; case 8: rp++; TORS = ip; ip = pop() - 1; break; case 9: target = pop(); flag = pop(); if (flag != 0) { rp++; TORS = ip; ip = target - 1; } break; case 10: target = pop(); flag = pop(); if (flag != 0) ip = target - 1; break; case 11: ip = TORS; rp--; break; case 12: NOS = (NOS == TOS) ? -1 : 0; sp--; break; case 13: NOS = (NOS != TOS) ? -1 : 0; sp--; break; case 14: NOS = (NOS < TOS) ? -1 : 0; sp--; break; case 15: NOS = (NOS > TOS) ? -1 : 0; sp--; break; case 16: TOS = fetch(TOS); break; case 17: store(TOS, NOS); sp--; sp--; break; case 18: NOS += TOS; sp--; break; case 19: NOS -= TOS; sp--; break; case 20: NOS *= TOS; sp--; break; case 21: a = TOS; b = NOS; TOS = b / a; NOS = b % a; break; case 22: NOS = TOS & NOS; sp--; break; case 23: NOS = TOS | NOS; sp--; break; case 24: NOS = TOS ^ NOS; sp--; break; case 25: NOS = NOS << TOS; sp--; break; case 26: NOS = NOS >> TOS; sp--; break; case 27: len = pop(); dest = pop(); src = pop(); flag = -1; while (len) { if (fetch(dest) != fetch(src)) flag = 0; len -= 1; src += 1; dest += 1; }; push(flag); break; case 28: len = pop(); dest = pop(); src = pop(); while (len) { store(dest, fetch(src)); len -= 1; src += 1; dest += 1; }; break; case 29: switch (pop()) { case 0: putc(pop(), stdout); break; case 1: push(getc(stdin)); break; case 2: read_block(); break; case 3: write_block(); break; case 4: save_image(); break; case 5: load_image(); ip = -1; break; case 6: ip = 65536; break; case 7: push(sp); push(rp); break; default: break; } break; default: break; } } void execute(long address) { long opcode, o; ip = address; while (ip < 65536) { opcode = fetch(ip); switch (opcode) { case 0: break; case 1793: ip = fetch(ip + 1) - 1; break; case 2049: process(1); process(8); break; case 67502597: push(NOS); break; default: o = opcode & 0xFF; if (o != 0) process(o); o = (opcode >> 8) & 0xFF; if (o != 0) process(o); o = (opcode >> 16) & 0xFF; if (o != 0) process(o); o = (opcode >> 24) & 0xFF; if (o != 0) process(o); break; } ip++; } } void main(long argc, char **argv) { long i; for (i = 0; i < SLICES; i++) memory[i] = malloc(SLICESIZE * sizeof(long)); load_image(); execute(0); for (i = 0; i < SLICES; i++) free(memory[i]); for (i = 1; sp >= i; i++) printf(" %d", data[i]); printf("\n"); } \ No newline at end of file diff --git a/source/ilo-aarch64-linux.s b/source/ilo-aarch64-linux.s new file mode 100644 index 0000000..4b0505c --- /dev/null +++ b/source/ilo-aarch64-linux.s @@ -0,0 +1,1120 @@ +/*************************************************************** + + crc's _ _ + (_) | ___ + | | |/ _ \ a tiny virtual computer + | | | (_) | 64kw RAM, 32-bit, Dual Stack, MISC + |_|_|\___/ (c) charles childers + + This is an implementation of ilo in aarch64 assembly. + + To build: + + as ilo-aarch64-linux.s -o ilo.o + ld -nostdlib -s ilo.o -o ilo + + **************************************************************/ + + .text + .globl _start + +// ------------------------------------------------------------- +// System Call Interface +// +// ilo makes use of a small number of system calls. These are: +// +// +-------------+--------+ +// | System Call | Number | +// +=============+========+ +// | openat (*) | 56 | +// | close | 57 | +// | read | 63 | +// | write | 64 | +// | lseek | 62 | +// | exit | 93 | +// +-------------+--------+ +// +// (*) On most systems, I use the open() system call. But, on +// aarch64, Linux does not implement open() as a system +// call. Instead, it uses openat(). I implement an os_open() +// to wrap the actual openat() call. +// ------------------------------------------------------------- + +os_openat: + mov x8, #56 + svc #0 + ret + +os_close: + mov x8, #57 + svc #0 + ret + +os_lseek: + mov x8, #62 + svc #0 + ret + +os_read: + mov x8, #63 + svc #0 + ret + +os_write: + mov x8, #64 + svc #0 + ret + +os_exit: + mov x0, #0 // exit, with return code 0 + mov x8, #93 + svc #0 + +os_open: + sub sp, sp, #32 + stp x29, x30, [sp, #16] // 16-byte Folded Spill + add x29, sp, #16 + str x0, [sp, #8] + str w1, [sp, #4] + ldr x1, [sp, #8] + ldr w2, [sp, #4] + mov w0, #-100 + bl os_openat + ldp x29, x30, [sp, #16] // 16-byte Folded Reload + add sp, sp, #32 + ret +// ------------------------------------------------------------- +pop: + adrp x8, sp + ldr w9, [x8, :lo12:sp] + subs w9, w9, #1 + str w9, [x8, :lo12:sp] + ldr w8, [x8, :lo12:sp] + add w9, w8, #1 + adrp x8, data + add x8, x8, :lo12:data + ldr w0, [x8, w9, sxtw #2] + ret +// ------------------------------------------------------------- +push: + sub sp, sp, #16 + str w0, [sp, #12] + adrp x9, sp + ldr w8, [x9, :lo12:sp] + add w8, w8, #1 + str w8, [x9, :lo12:sp] + ldr w8, [sp, #12] + ldrsw x10, [x9, :lo12:sp] + adrp x9, data + add x9, x9, :lo12:data + str w8, [x9, x10, lsl #2] + add sp, sp, #16 + ret +// ------------------------------------------------------------- +prepare_vm: + adrp x8, rp + str wzr, [x8, :lo12:rp] + adrp x8, sp + str wzr, [x8, :lo12:sp] + adrp x8, ip + str wzr, [x8, :lo12:ip] + ret +// ------------------------------------------------------------- +load_image: + sub sp, sp, #32 + stp x29, x30, [sp, #16] // 16-byte Folded Spill + add x29, sp, #16 + adrp x8, rom + ldr x0, [x8, :lo12:rom] + mov w1, wzr + mov w2, #438 + bl os_open + adrp x8, fp + str w0, [x8, :lo12:fp] + ldr w8, [x8, :lo12:fp] + subs w8, w8, #0 + cset w8, ne + tbnz w8, #0, .image_found + b .load_image_done +.image_found: + adrp x8, fp + str x8, [sp, #8] // 8-byte Folded Spill + ldr w0, [x8, :lo12:fp] + adrp x1, m + add x1, x1, :lo12:m + mov x2, #262144 + bl os_read + ldr x8, [sp, #8] // 8-byte Folded Reload + ldr w0, [x8, :lo12:fp] + bl os_close + bl prepare_vm +.load_image_done: + ldp x29, x30, [sp, #16] // 16-byte Folded Reload + add sp, sp, #32 + ret +// ------------------------------------------------------------- +save_image: + sub sp, sp, #32 + stp x29, x30, [sp, #16] // 16-byte Folded Spill + add x29, sp, #16 + adrp x8, rom + ldr x0, [x8, :lo12:rom] + mov w1, #1 + mov w2, #438 + bl os_open + adrp x8, fp + str x8, [sp, #8] // 8-byte Folded Spill + str w0, [x8, :lo12:fp] + ldr w0, [x8, :lo12:fp] + adrp x1, m + add x1, x1, :lo12:m + mov x2, #262144 + bl os_write + ldr x8, [sp, #8] // 8-byte Folded Reload + ldr w0, [x8, :lo12:fp] + bl os_close + ldp x29, x30, [sp, #16] // 16-byte Folded Reload + add sp, sp, #32 + ret +// ------------------------------------------------------------- +block_common: + stp x29, x30, [sp, #-16]! // 16-byte Folded Spill + mov x29, sp + bl pop + adrp x8, buffer + str w0, [x8, :lo12:buffer] + bl pop + adrp x8, block + str w0, [x8, :lo12:block] + adrp x9, fp + ldr w0, [x9, :lo12:fp] + ldr w9, [x8, :lo12:block] + mov w8, #4096 + mul w9, w8, w9 + // implicit-def: $x8 + mov w8, w9 + sxtw x1, w8 + mov w2, wzr + bl os_lseek + ldp x29, x30, [sp], #16 // 16-byte Folded Reload + ret +// ------------------------------------------------------------- +read_block: + sub sp, sp, #32 + stp x29, x30, [sp, #16] // 16-byte Folded Spill + add x29, sp, #16 + adrp x8, blocks + ldr x0, [x8, :lo12:blocks] + mov w1, wzr + mov w2, #438 + bl os_open + adrp x8, fp + str x8, [sp, #8] // 8-byte Folded Spill + str w0, [x8, :lo12:fp] + bl block_common + ldr x8, [sp, #8] // 8-byte Folded Reload + ldr w0, [x8, :lo12:fp] + adrp x8, buffer + ldrsw x9, [x8, :lo12:buffer] + adrp x8, m + add x8, x8, :lo12:m + add x1, x8, x9, lsl #2 + mov x2, #4096 + bl os_read + ldr x8, [sp, #8] // 8-byte Folded Reload + ldr w0, [x8, :lo12:fp] + bl os_close + ldp x29, x30, [sp, #16] // 16-byte Folded Reload + add sp, sp, #32 + ret +// ------------------------------------------------------------- +write_block: + sub sp, sp, #32 + stp x29, x30, [sp, #16] // 16-byte Folded Spill + add x29, sp, #16 + adrp x8, blocks + ldr x0, [x8, :lo12:blocks] + mov w1, #1 + mov w2, #438 + bl os_open + adrp x8, fp + str x8, [sp, #8] // 8-byte Folded Spill + str w0, [x8, :lo12:fp] + bl block_common + ldr x8, [sp, #8] // 8-byte Folded Reload + ldr w0, [x8, :lo12:fp] + adrp x8, buffer + ldrsw x9, [x8, :lo12:buffer] + adrp x8, m + add x8, x8, :lo12:m + add x1, x8, x9, lsl #2 + mov x2, #4096 + bl os_write + ldr x8, [sp, #8] // 8-byte Folded Reload + ldr w0, [x8, :lo12:fp] + bl os_close + ldp x29, x30, [sp, #16] // 16-byte Folded Reload + add sp, sp, #32 + ret +// ------------------------------------------------------------- +save_ip: + adrp x9, rp + ldr w8, [x9, :lo12:rp] + add w8, w8, #1 + str w8, [x9, :lo12:rp] + adrp x8, ip + ldr w8, [x8, :lo12:ip] + ldrsw x10, [x9, :lo12:rp] + adrp x9, address + add x9, x9, :lo12:address + str w8, [x9, x10, lsl #2] + ret +// ------------------------------------------------------------- +li: + stp x29, x30, [sp, #-16]! // 16-byte Folded Spill + mov x29, sp + adrp x8, ip + ldr w9, [x8, :lo12:ip] + add w9, w9, #1 + str w9, [x8, :lo12:ip] + ldrsw x9, [x8, :lo12:ip] + adrp x8, m + add x8, x8, :lo12:m + ldr w0, [x8, x9, lsl #2] + bl push + ldp x29, x30, [sp], #16 // 16-byte Folded Reload + ret +// ------------------------------------------------------------- +du: + stp x29, x30, [sp, #-16]! // 16-byte Folded Spill + mov x29, sp + adrp x8, sp + ldrsw x9, [x8, :lo12:sp] + adrp x8, data + add x8, x8, :lo12:data + ldr w0, [x8, x9, lsl #2] + bl push + ldp x29, x30, [sp], #16 // 16-byte Folded Reload + ret +// ------------------------------------------------------------- +dr: + adrp x9, sp + ldrsw x11, [x9, :lo12:sp] + adrp x10, data + add x10, x10, :lo12:data + mov w8, wzr + str w8, [x10, x11, lsl #2] + ldr w8, [x9, :lo12:sp] + subs w8, w8, #1 + str w8, [x9, :lo12:sp] + ret +// ------------------------------------------------------------- +sw: + adrp x10, sp + ldrsw x8, [x10, :lo12:sp] + adrp x9, data + add x9, x9, :lo12:data + ldr w11, [x9, x8, lsl #2] + adrp x8, a + str w11, [x8, :lo12:a] + ldr w11, [x10, :lo12:sp] + subs w11, w11, #1 + ldr w11, [x9, w11, sxtw #2] + ldrsw x12, [x10, :lo12:sp] + str w11, [x9, x12, lsl #2] + ldr w8, [x8, :lo12:a] + ldr w10, [x10, :lo12:sp] + subs w10, w10, #1 + str w8, [x9, w10, sxtw #2] + ret +// ------------------------------------------------------------- +pu: + sub sp, sp, #32 + stp x29, x30, [sp, #16] // 16-byte Folded Spill + add x29, sp, #16 + adrp x9, rp + str x9, [sp, #8] // 8-byte Folded Spill + ldr w8, [x9, :lo12:rp] + add w8, w8, #1 + str w8, [x9, :lo12:rp] + bl pop + ldr x8, [sp, #8] // 8-byte Folded Reload + ldrsw x9, [x8, :lo12:rp] + adrp x8, address + add x8, x8, :lo12:address + str w0, [x8, x9, lsl #2] + ldp x29, x30, [sp, #16] // 16-byte Folded Reload + add sp, sp, #32 + ret +// ------------------------------------------------------------- +po: + sub sp, sp, #32 + stp x29, x30, [sp, #16] // 16-byte Folded Spill + add x29, sp, #16 + adrp x8, rp + str x8, [sp, #8] // 8-byte Folded Spill + ldrsw x9, [x8, :lo12:rp] + adrp x8, address + add x8, x8, :lo12:address + ldr w0, [x8, x9, lsl #2] + bl push + ldr x9, [sp, #8] // 8-byte Folded Reload + ldr w8, [x9, :lo12:rp] + subs w8, w8, #1 + str w8, [x9, :lo12:rp] + ldp x29, x30, [sp, #16] // 16-byte Folded Reload + add sp, sp, #32 + ret +// ------------------------------------------------------------- +ju: + stp x29, x30, [sp, #-16]! // 16-byte Folded Spill + mov x29, sp + bl pop + subs w8, w0, #1 + adrp x9, ip + str w8, [x9, :lo12:ip] + ldp x29, x30, [sp], #16 // 16-byte Folded Reload + ret +// ------------------------------------------------------------- +ca: + stp x29, x30, [sp, #-16]! // 16-byte Folded Spill + mov x29, sp + bl save_ip + bl pop + subs w8, w0, #1 + adrp x9, ip + str w8, [x9, :lo12:ip] + ldp x29, x30, [sp], #16 // 16-byte Folded Reload + ret +// ------------------------------------------------------------- +cc: + stp x29, x30, [sp, #-16]! // 16-byte Folded Spill + mov x29, sp + bl pop + adrp x8, t + str w0, [x8, :lo12:t] + bl pop + subs w8, w0, #0 + cset w8, eq + tbnz w8, #0, .cc_skip_call +// if true + bl save_ip + adrp x8, t + ldr w8, [x8, :lo12:t] + subs w8, w8, #1 + adrp x9, ip + str w8, [x9, :lo12:ip] +.cc_skip_call: + ldp x29, x30, [sp], #16 // 16-byte Folded Reload + ret +// ------------------------------------------------------------- +cj: + stp x29, x30, [sp, #-16]! // 16-byte Folded Spill + mov x29, sp + bl pop + adrp x8, t + str w0, [x8, :lo12:t] + bl pop + subs w8, w0, #0 + cset w8, eq + tbnz w8, #0, .cj_done // flag is false, skip branch + // if flag is true + adrp x8, t + ldr w8, [x8, :lo12:t] + subs w8, w8, #1 + adrp x9, ip + str w8, [x9, :lo12:ip] +.cj_done: + ldp x29, x30, [sp], #16 // 16-byte Folded Reload + ret +// ------------------------------------------------------------- +re: + adrp x9, rp + ldrsw x10, [x9, :lo12:rp] + adrp x8, address + add x8, x8, :lo12:address + ldr w8, [x8, x10, lsl #2] + adrp x10, ip + str w8, [x10, :lo12:ip] + ldr w8, [x9, :lo12:rp] + subs w8, w8, #1 + str w8, [x9, :lo12:rp] + ret +// ------------------------------------------------------------- +eq: + adrp x9, sp + ldr w8, [x9, :lo12:sp] + subs w8, w8, #1 + adrp x10, data + add x10, x10, :lo12:data + ldr w8, [x10, w8, sxtw #2] + ldrsw x11, [x9, :lo12:sp] + ldr w11, [x10, x11, lsl #2] + subs w8, w8, w11 + cset w8, eq + and w11, w8, #0x1 + mov w8, wzr + ands w11, w11, #0x1 + csinv w8, w8, wzr, eq + ldr w11, [x9, :lo12:sp] + subs w11, w11, #1 + str w8, [x10, w11, sxtw #2] + ldr w8, [x9, :lo12:sp] + subs w8, w8, #1 + str w8, [x9, :lo12:sp] + ret +// ------------------------------------------------------------- +ne: + adrp x9, sp + ldr w8, [x9, :lo12:sp] + subs w8, w8, #1 + adrp x10, data + add x10, x10, :lo12:data + ldr w8, [x10, w8, sxtw #2] + ldrsw x11, [x9, :lo12:sp] + ldr w11, [x10, x11, lsl #2] + subs w8, w8, w11 + cset w8, ne + and w11, w8, #0x1 + mov w8, wzr + ands w11, w11, #0x1 + csinv w8, w8, wzr, eq + ldr w11, [x9, :lo12:sp] + subs w11, w11, #1 + str w8, [x10, w11, sxtw #2] + ldr w8, [x9, :lo12:sp] + subs w8, w8, #1 + str w8, [x9, :lo12:sp] + ret +// ------------------------------------------------------------- +lt: // @lt + adrp x9, sp + ldr w8, [x9, :lo12:sp] + subs w8, w8, #1 + adrp x10, data + add x10, x10, :lo12:data + ldr w8, [x10, w8, sxtw #2] + ldrsw x11, [x9, :lo12:sp] + ldr w11, [x10, x11, lsl #2] + subs w8, w8, w11 + cset w8, lt + and w11, w8, #0x1 + mov w8, wzr + ands w11, w11, #0x1 + csinv w8, w8, wzr, eq + ldr w11, [x9, :lo12:sp] + subs w11, w11, #1 + str w8, [x10, w11, sxtw #2] + ldr w8, [x9, :lo12:sp] + subs w8, w8, #1 + str w8, [x9, :lo12:sp] + ret +// ------------------------------------------------------------- +gt: + adrp x9, sp + ldr w8, [x9, :lo12:sp] + subs w8, w8, #1 + adrp x10, data + add x10, x10, :lo12:data + ldr w8, [x10, w8, sxtw #2] + ldrsw x11, [x9, :lo12:sp] + ldr w11, [x10, x11, lsl #2] + subs w8, w8, w11 + cset w8, gt + and w11, w8, #0x1 + mov w8, wzr + ands w11, w11, #0x1 + csinv w8, w8, wzr, eq + ldr w11, [x9, :lo12:sp] + subs w11, w11, #1 + str w8, [x10, w11, sxtw #2] + ldr w8, [x9, :lo12:sp] + subs w8, w8, #1 + str w8, [x9, :lo12:sp] + ret +// ------------------------------------------------------------- +fe: + adrp x10, sp + ldrsw x8, [x10, :lo12:sp] + adrp x9, data + add x9, x9, :lo12:data + ldrsw x11, [x9, x8, lsl #2] + adrp x8, m + add x8, x8, :lo12:m + ldr w8, [x8, x11, lsl #2] + ldrsw x10, [x10, :lo12:sp] + str w8, [x9, x10, lsl #2] + ret +// ------------------------------------------------------------- +st: + adrp x9, sp + ldr w8, [x9, :lo12:sp] + subs w8, w8, #1 + adrp x10, data + add x10, x10, :lo12:data + ldr w8, [x10, w8, sxtw #2] + ldrsw x11, [x9, :lo12:sp] + ldrsw x11, [x10, x11, lsl #2] + adrp x10, m + add x10, x10, :lo12:m + str w8, [x10, x11, lsl #2] + ldr w8, [x9, :lo12:sp] + subs w8, w8, #2 + str w8, [x9, :lo12:sp] + ret +// ------------------------------------------------------------- +ad: + adrp x9, sp + ldrsw x10, [x9, :lo12:sp] + adrp x8, data + add x8, x8, :lo12:data + ldr w11, [x8, x10, lsl #2] + ldr w10, [x9, :lo12:sp] + subs w10, w10, #1 + add x10, x8, w10, sxtw #2 + ldr w8, [x10] + add w8, w8, w11 + str w8, [x10] + ldr w8, [x9, :lo12:sp] + subs w8, w8, #1 + str w8, [x9, :lo12:sp] + ret +// ------------------------------------------------------------- +su: + adrp x9, sp + ldrsw x10, [x9, :lo12:sp] + adrp x8, data + add x8, x8, :lo12:data + ldr w11, [x8, x10, lsl #2] + ldr w10, [x9, :lo12:sp] + subs w10, w10, #1 + add x10, x8, w10, sxtw #2 + ldr w8, [x10] + subs w8, w8, w11 + str w8, [x10] + ldr w8, [x9, :lo12:sp] + subs w8, w8, #1 + str w8, [x9, :lo12:sp] + ret +// ------------------------------------------------------------- +mu: + adrp x9, sp + ldrsw x10, [x9, :lo12:sp] + adrp x8, data + add x8, x8, :lo12:data + ldr w11, [x8, x10, lsl #2] + ldr w10, [x9, :lo12:sp] + subs w10, w10, #1 + add x10, x8, w10, sxtw #2 + ldr w8, [x10] + mul w8, w8, w11 + str w8, [x10] + ldr w8, [x9, :lo12:sp] + subs w8, w8, #1 + str w8, [x9, :lo12:sp] + ret +// ------------------------------------------------------------- +di: + adrp x10, sp + ldrsw x8, [x10, :lo12:sp] + adrp x9, data + add x9, x9, :lo12:data + ldr w8, [x9, x8, lsl #2] + adrp x11, a + str w8, [x11, :lo12:a] + ldr w8, [x10, :lo12:sp] + subs w8, w8, #1 + ldr w12, [x9, w8, sxtw #2] + adrp x8, b + str w12, [x8, :lo12:b] + ldr w12, [x8, :lo12:b] + ldr w13, [x11, :lo12:a] + sdiv w12, w12, w13 + ldrsw x13, [x10, :lo12:sp] + str w12, [x9, x13, lsl #2] + ldr w8, [x8, :lo12:b] + ldr w12, [x11, :lo12:a] + sdiv w11, w8, w12 + mul w11, w11, w12 + subs w8, w8, w11 + ldr w10, [x10, :lo12:sp] + subs w10, w10, #1 + str w8, [x9, w10, sxtw #2] + ret +// ------------------------------------------------------------- +an: + adrp x9, sp + ldrsw x8, [x9, :lo12:sp] + adrp x10, data + add x10, x10, :lo12:data + ldr w8, [x10, x8, lsl #2] + ldr w11, [x9, :lo12:sp] + subs w11, w11, #1 + ldr w11, [x10, w11, sxtw #2] + and w8, w8, w11 + ldr w11, [x9, :lo12:sp] + subs w11, w11, #1 + str w8, [x10, w11, sxtw #2] + ldr w8, [x9, :lo12:sp] + subs w8, w8, #1 + str w8, [x9, :lo12:sp] + ret +// ------------------------------------------------------------- +or: + adrp x9, sp + ldrsw x8, [x9, :lo12:sp] + adrp x10, data + add x10, x10, :lo12:data + ldr w8, [x10, x8, lsl #2] + ldr w11, [x9, :lo12:sp] + subs w11, w11, #1 + ldr w11, [x10, w11, sxtw #2] + orr w8, w8, w11 + ldr w11, [x9, :lo12:sp] + subs w11, w11, #1 + str w8, [x10, w11, sxtw #2] + ldr w8, [x9, :lo12:sp] + subs w8, w8, #1 + str w8, [x9, :lo12:sp] + ret +// ------------------------------------------------------------- +xo: + adrp x9, sp + ldrsw x8, [x9, :lo12:sp] + adrp x10, data + add x10, x10, :lo12:data + ldr w8, [x10, x8, lsl #2] + ldr w11, [x9, :lo12:sp] + subs w11, w11, #1 + ldr w11, [x10, w11, sxtw #2] + eor w8, w8, w11 + ldr w11, [x9, :lo12:sp] + subs w11, w11, #1 + str w8, [x10, w11, sxtw #2] + ldr w8, [x9, :lo12:sp] + subs w8, w8, #1 + str w8, [x9, :lo12:sp] + ret +// ------------------------------------------------------------- +sl: + adrp x9, sp + ldr w8, [x9, :lo12:sp] + subs w8, w8, #1 + adrp x10, data + add x10, x10, :lo12:data + ldr w8, [x10, w8, sxtw #2] + ldrsw x11, [x9, :lo12:sp] + ldr w11, [x10, x11, lsl #2] + lsl w8, w8, w11 + ldr w11, [x9, :lo12:sp] + subs w11, w11, #1 + str w8, [x10, w11, sxtw #2] + ldr w8, [x9, :lo12:sp] + subs w8, w8, #1 + str w8, [x9, :lo12:sp] + ret +// ------------------------------------------------------------- +sr: + adrp x9, sp + ldr w8, [x9, :lo12:sp] + subs w8, w8, #1 + adrp x10, data + add x10, x10, :lo12:data + ldr w8, [x10, w8, sxtw #2] + ldrsw x11, [x9, :lo12:sp] + ldr w11, [x10, x11, lsl #2] + asr w8, w8, w11 + ldr w11, [x9, :lo12:sp] + subs w11, w11, #1 + str w8, [x10, w11, sxtw #2] + ldr w8, [x9, :lo12:sp] + subs w8, w8, #1 + str w8, [x9, :lo12:sp] + ret +// ------------------------------------------------------------- +cp: + stp x29, x30, [sp, #-16]! // 16-byte Folded Spill + mov x29, sp + bl pop + adrp x8, len + str w0, [x8, :lo12:len] + bl pop + adrp x8, dest + str w0, [x8, :lo12:dest] + bl pop + adrp x8, src + str w0, [x8, :lo12:src] + mov w0, #-1 + bl push +// b .LBB35_1 +.LBB35_1: // =>This Inner Loop Header: Depth=1 + adrp x8, len + ldr w8, [x8, :lo12:len] + subs w8, w8, #0 + cset w8, eq + tbnz w8, #0, .LBB35_5 +// b .LBB35_2 +.LBB35_2: // in Loop: Header=BB35_1 Depth=1 + adrp x8, dest + ldrsw x8, [x8, :lo12:dest] + adrp x9, m + add x9, x9, :lo12:m + ldr w8, [x9, x8, lsl #2] + adrp x10, src + ldrsw x10, [x10, :lo12:src] + ldr w9, [x9, x10, lsl #2] + subs w8, w8, w9 + cset w8, eq + tbnz w8, #0, .LBB35_4 +// b .LBB35_3 +.LBB35_3: // in Loop: Header=BB35_1 Depth=1 + adrp x8, sp + ldrsw x10, [x8, :lo12:sp] + adrp x9, data + add x9, x9, :lo12:data + mov w8, wzr + str w8, [x9, x10, lsl #2] +// b .LBB35_4 +.LBB35_4: // in Loop: Header=BB35_1 Depth=1 + adrp x9, len + ldr w8, [x9, :lo12:len] + subs w8, w8, #1 + str w8, [x9, :lo12:len] + adrp x9, src + ldr w8, [x9, :lo12:src] + add w8, w8, #1 + str w8, [x9, :lo12:src] + adrp x9, dest + ldr w8, [x9, :lo12:dest] + add w8, w8, #1 + str w8, [x9, :lo12:dest] + b .LBB35_1 +.LBB35_5: + ldp x29, x30, [sp], #16 // 16-byte Folded Reload + ret +// ------------------------------------------------------------- +cy: + stp x29, x30, [sp, #-16]! // 16-byte Folded Spill + mov x29, sp + bl pop + adrp x8, len + str w0, [x8, :lo12:len] + bl pop + adrp x8, dest + str w0, [x8, :lo12:dest] + bl pop + adrp x8, src + str w0, [x8, :lo12:src] +// b .LBB36_1 +.LBB36_1: // =>This Inner Loop Header: Depth=1 + adrp x8, len + ldr w8, [x8, :lo12:len] + subs w8, w8, #0 + cset w8, eq + tbnz w8, #0, .LBB36_3 +// b .LBB36_2 +.LBB36_2: // in Loop: Header=BB36_1 Depth=1 + adrp x10, src + ldrsw x8, [x10, :lo12:src] + adrp x11, m + add x11, x11, :lo12:m + ldr w8, [x11, x8, lsl #2] + adrp x9, dest + ldrsw x12, [x9, :lo12:dest] + str w8, [x11, x12, lsl #2] + adrp x11, len + ldr w8, [x11, :lo12:len] + subs w8, w8, #1 + str w8, [x11, :lo12:len] + ldr w8, [x10, :lo12:src] + add w8, w8, #1 + str w8, [x10, :lo12:src] + ldr w8, [x9, :lo12:dest] + add w8, w8, #1 + str w8, [x9, :lo12:dest] + b .LBB36_1 +.LBB36_3: + ldp x29, x30, [sp], #16 // 16-byte Folded Reload + ret +// ------------------------------------------------------------- +io: + sub sp, sp, #32 + stp x29, x30, [sp, #16] // 16-byte Folded Spill + add x29, sp, #16 + bl pop + subs w8, w0, #0 + // kill: def $x8 killed $w8 + str x8, [sp, #8] // 8-byte Folded Spill + subs x8, x8, #7 + cset w8, hi + tbnz w8, #0, .LBB37_10 + + ldr x11, [sp, #8] // 8-byte Folded Reload + adrp x10, .LJTI37_0 + add x10, x10, :lo12:.LJTI37_0 +.Ltmp1: + adr x8, .Ltmp1 + ldrsw x9, [x10, x11, lsl #2] + add x8, x8, x9 + br x8 +.LBB37_2: + bl pop + adrp x8, iob + adrp x1, iob + add x1, x1, :lo12:iob + strb w0, [x8, :lo12:iob] + mov w0, #1 + mov x2, #1 + bl os_write + b .LBB37_11 +.LBB37_3: + mov w0, wzr + adrp x8, iob + str x8, [sp] // 8-byte Folded Spill + adrp x1, iob + add x1, x1, :lo12:iob + mov x2, #1 + bl os_read + ldr x8, [sp] // 8-byte Folded Reload + ldrb w0, [x8, :lo12:iob] + bl push + b .LBB37_11 +.LBB37_4: + bl read_block + b .LBB37_11 +.LBB37_5: + bl write_block + b .LBB37_11 +.LBB37_6: + bl save_image + b .LBB37_11 +.LBB37_7: + bl load_image + mov w8, #-1 + adrp x9, ip + str w8, [x9, :lo12:ip] + b .LBB37_11 +.LBB37_8: + adrp x9, ip + mov w8, #65536 + str w8, [x9, :lo12:ip] + b .LBB37_11 +.LBB37_9: + adrp x8, sp + ldr w0, [x8, :lo12:sp] + bl push + adrp x8, rp + ldr w0, [x8, :lo12:rp] + bl push + b .LBB37_11 +.LBB37_10: + b .LBB37_11 +.LBB37_11: + ldp x29, x30, [sp, #16] // 16-byte Folded Reload + add sp, sp, #32 + ret +.LJTI37_0: + .word .LBB37_2-.Ltmp1 + .word .LBB37_3-.Ltmp1 + .word .LBB37_4-.Ltmp1 + .word .LBB37_5-.Ltmp1 + .word .LBB37_6-.Ltmp1 + .word .LBB37_7-.Ltmp1 + .word .LBB37_8-.Ltmp1 + .word .LBB37_9-.Ltmp1 +// ------------------------------------------------------------- +process: + sub sp, sp, #32 + stp x29, x30, [sp, #16] // 16-byte Folded Spill + add x29, sp, #16 + stur w0, [x29, #-4] + ldur w8, [x29, #-4] + subs w8, w8, #0 + // kill: def $x8 killed $w8 + str x8, [sp] // 8-byte Folded Spill + subs x8, x8, #29 + cset w8, hi + tbnz w8, #0, .LBB38_32 + + ldr x11, [sp] // 8-byte Folded Reload + adrp x10, .LJTI38_0 + add x10, x10, :lo12:.LJTI38_0 +.Ltmp2: + adr x8, .Ltmp2 + ldrsw x9, [x10, x11, lsl #2] + add x8, x8, x9 + br x8 +.LBB38_2: b .LBB38_33 +.LBB38_3: b li +.LBB38_4: b du +.LBB38_5: b dr +.LBB38_6: b sw +.LBB38_7: b pu +.LBB38_8: b po +.LBB38_9: b ju +.LBB38_10: b ca +.LBB38_11: b cc +.LBB38_12: b cj +.LBB38_13: b re +.LBB38_14: b eq +.LBB38_15: b ne +.LBB38_16: b lt +.LBB38_17: b gt +.LBB38_18: b fe +.LBB38_19: b st +.LBB38_20: b ad +.LBB38_21: b su +.LBB38_22: b mu +.LBB38_23: b di +.LBB38_24: b an +.LBB38_25: b or +.LBB38_26: b xo +.LBB38_27: b sl +.LBB38_28: b sr +.LBB38_29: b cp +.LBB38_30: b cy +.LBB38_31: b io +.LBB38_32: b .LBB38_33 +.LBB38_33: + ldp x29, x30, [sp, #16] // 16-byte Folded Reload + add sp, sp, #32 + ret + +.LJTI38_0: + .word .LBB38_2-.Ltmp2 + .word .LBB38_3-.Ltmp2 + .word .LBB38_4-.Ltmp2 + .word .LBB38_5-.Ltmp2 + .word .LBB38_6-.Ltmp2 + .word .LBB38_7-.Ltmp2 + .word .LBB38_8-.Ltmp2 + .word .LBB38_9-.Ltmp2 + .word .LBB38_10-.Ltmp2 + .word .LBB38_11-.Ltmp2 + .word .LBB38_12-.Ltmp2 + .word .LBB38_13-.Ltmp2 + .word .LBB38_14-.Ltmp2 + .word .LBB38_15-.Ltmp2 + .word .LBB38_16-.Ltmp2 + .word .LBB38_17-.Ltmp2 + .word .LBB38_18-.Ltmp2 + .word .LBB38_19-.Ltmp2 + .word .LBB38_20-.Ltmp2 + .word .LBB38_21-.Ltmp2 + .word .LBB38_22-.Ltmp2 + .word .LBB38_23-.Ltmp2 + .word .LBB38_24-.Ltmp2 + .word .LBB38_25-.Ltmp2 + .word .LBB38_26-.Ltmp2 + .word .LBB38_27-.Ltmp2 + .word .LBB38_28-.Ltmp2 + .word .LBB38_29-.Ltmp2 + .word .LBB38_30-.Ltmp2 + .word .LBB38_31-.Ltmp2 + +process_bundle: + sub sp, sp, #32 + stp x29, x30, [sp, #16] // 16-byte Folded Spill + add x29, sp, #16 + stur w0, [x29, #-4] + ldurb w0, [x29, #-4] + bl process + + ldur w8, [x29, #-4] + asr w8, w8, #8 + and w0, w8, #0xff + bl process + + ldur w8, [x29, #-4] + asr w8, w8, #16 + and w0, w8, #0xff + bl process + + ldur w8, [x29, #-4] + asr w8, w8, #24 + and w0, w8, #0xff + bl process + + ldp x29, x30, [sp, #16] // 16-byte Folded Reload + add sp, sp, #32 + ret +// ------------------------------------------------------------- +execute: + sub sp, sp, #32 + stp x29, x30, [sp, #16] // 16-byte Folded Spill + add x29, sp, #16 +// b .LBB40_1 +.LBB40_1: // =>This Inner Loop Header: Depth=1 + adrp x8, ip + ldr w8, [x8, :lo12:ip] + subs w8, w8, #16, lsl #12 // =65536 + cset w8, ge + tbnz w8, #0, .LBB40_3 +// b .LBB40_2 +.LBB40_2: // in Loop: Header=BB40_1 Depth=1 + adrp x8, ip + str x8, [sp, #8] // 8-byte Folded Spill + ldrsw x9, [x8, :lo12:ip] + adrp x8, m + add x8, x8, :lo12:m + ldr w0, [x8, x9, lsl #2] + bl process_bundle + ldr x9, [sp, #8] // 8-byte Folded Reload + ldr w8, [x9, :lo12:ip] + add w8, w8, #1 + str w8, [x9, :lo12:ip] + b .LBB40_1 +.LBB40_3: + ldp x29, x30, [sp, #16] // 16-byte Folded Reload + add sp, sp, #32 + ret +// ------------------------------------------------------------- +_start: + sub sp, sp, #32 + stp x29, x30, [sp, #16] // 16-byte Folded Spill + add x29, sp, #16 + stur w0, [x29, #-4] + str x1, [sp] + adrp x9, blocks + adrp x8, .blocks_name + add x8, x8, :lo12:.blocks_name + str x8, [x9, :lo12:blocks] + adrp x9, rom + adrp x8, .rom_name + add x8, x8, :lo12:.rom_name + str x8, [x9, :lo12:rom] + bl load_image + bl execute +// mov w0, wzr +// ldp x29, x30, [sp, #16] // 16-byte Folded Reload +// add sp, sp, #32 + b os_exit + +// ------------------------------------------------------------- +.blocks_name: .asciz "ilo.blocks" +.rom_name: .asciz "ilo.rom" +// ------------------------------------------------------------- + .bss + +sp: .word 0 // stack pointer +data: .zero 132 // data stack +rp: .word 0 // address pointer +address:.zero 1028 // address stack +ip: .word 0 // instruction pointer +m: .zero 262144 // memory + +fp: .word 0 // file id +buffer: .word 0 // address of block buffer +block: .word 0 // block number to read/write +a: .word 0 // scratch +t: .word 0 // scratch +b: .word 0 // scratch +len: .word 0 // scratch +dest: .word 0 // scratch +src: .word 0 // scratch +iob: .zero 2 // io buffr + + .p2align 3 +rom: .xword 0 // file name for rom + .p2align 3 +blocks: .xword 0 // file name for blocks diff --git a/source/ilo-amd64-dragonfly.s b/source/ilo-amd64-dragonfly.s new file mode 100644 index 0000000..04f0754 --- /dev/null +++ b/source/ilo-amd64-dragonfly.s @@ -0,0 +1,422 @@ +/* AMD64 ilo, (c) 2023 Christopher Leonard, MIT License */ + +/* cc -c ilo-amd64-freebsd.s -o ilo.o + ld -nostdlib ilo.o -o ilo +*/ + .global _start + + /* rax: top of stack */ + /* rbx: data stack */ + /* rbp: jump table address */ + /* r12: address stack */ + /* r13: instruction pointer */ + /* r14: opcode shift register */ + /* r15: memory */ + + .bss + + .align 8 +blocks: .skip 8 /* name of blocks file (ilo.blocks) */ +rom: .skip 8 /* name of image (ilo.rom) */ +dstack: .skip 32*4 +astack: .skip 256*4 +a: .skip 4 /* other variables for misc. purposes */ +b: .skip 4 +f: .skip 4 +s: .skip 4 +d: .skip 4 +l: .skip 4 +memory: .skip 65536*4 + + .section .rodata + +default_blocks: + .asciz "ilo.blocks" +default_rom: + .asciz "ilo.rom" + +io_table: + .byte 0 + .byte iob-ioa + .byte ioc-ioa + .byte iod-ioa + .byte ioe-ioa + .byte iof-ioa + .byte iog-ioa + .byte ioh-ioa + + .text + +dosys: push %r8 + push %r9 + push %r10 + push %r11 + push %rdx + syscall + pop %rdx + pop %r11 + pop %r10 + pop %r9 + pop %r8 + ret + +rdonly: mov $5, %eax /* sys_open */ + xor %esi, %esi /* O_RDONLY */ + mov $0666, %edx + call dosys + mov %eax, %edi + ret + +wronly: mov $5, %eax /* sys_open */ + mov $1, %esi /* O_WRONLY */ + mov $0666, %edx + call dosys + mov %eax, %edi + ret + +close: mov $6, %eax /* sys_close */ + call dosys + ret + +load_image: + mov rom(%rip), %rdi + call rdonly + or %eax, %eax + jz 1f + mov %r15, %rsi + mov $65536 * 4, %edx + mov $3, %eax /* sys_read */ + call dosys + call close + xor %eax, %eax + lea dstack-4(%rip), %rbx + lea astack-4(%rip), %r12 + xor %r13d, %r13d +1: ret + +save_image: + push %rax + mov rom(%rip), %rdi + call wronly + or %eax, %eax + jz 1f + mov %r15, %rsi + mov $65536 * 4, %edx + mov $4, %eax + call dosys + call close +1: pop %rax + ret + +block_common: + mov $199, %eax /* sys_lseek */ + mov (%rbx), %edx + shl $12, %edx + //xor %edx, %edx /* SEEK_SET */ + call dosys + mov $3, %eax /* sys_read */ + or %r10b, %r10b + jz 1f + mov $4, %al /* sys_write */ +1: lea (%r15,%r8,4), %rsi + mov $4096, %edx + call dosys + mov -4(%rbx), %esi + sub $8, %rbx + ret + + .align 32 +table: ret + .align 32 +li: add $4, %rbx + inc %r13d + mov %eax, (%rbx) + mov (%r15,%r13,4), %eax + ret + .align 32 +du: add $4, %rbx + mov %eax, (%rbx) + ret + .align 32 +dr: mov (%rbx), %eax + sub $4, %rbx + ret + .align 32 +sw: xchg (%rbx), %eax + ret + .align 32 +pu: add $4, %r12 + mov %eax, (%r12) + mov (%rbx), %eax + sub $4, %rbx + ret + .align 32 +po: add $4, %rbx + mov %eax, (%rbx) + mov (%r12), %eax + sub $4, %r12 + ret + .align 32 +ju: lea -1(%eax), %r13d + mov (%rbx), %eax + sub $4, %rbx + ret + .align 32 +ca: add $4, %r12 + mov %r13d, (%r12) + lea -1(%eax), %r13d + mov (%rbx), %eax + sub $4, %rbx + ret + .align 32 +cc: cmpl $0, (%rbx) + jz 1f + add $4, %r12 + mov %r13d, (%r12) + lea -1(%eax), %r13d +1: mov -4(%rbx), %eax + sub $8, %rbx + ret + .align 32 +cj: cmpl $0, (%rbx) + jz 1f + lea -1(%eax), %r13d +1: mov -4(%rbx), %eax + sub $8, %rbx + ret + .align 32 +re: mov (%r12), %r13d + sub $4, %r12 + ret + .align 32 +eq: cmp %eax, (%rbx) + sete %al + movzbl %al, %eax + neg %eax + sub $4, %rbx + ret + .align 32 +ne: cmp %eax, (%rbx) + setne %al + movzbl %al, %eax + neg %eax + sub $4, %rbx + ret + .align 32 +lt: cmp %eax, (%rbx) + setl %al + movzbl %al, %eax + neg %eax + sub $4, %rbx + ret + .align 32 +gt: cmp %eax, (%rbx) + setg %al + movzbl %al, %eax + neg %eax + sub $4, %rbx + ret + .align 32 +fe: mov (%r15,%rax,4), %eax + ret + .align 32 +st: mov (%rbx), %ecx + mov %ecx, (%r15,%rax,4) + mov -4(%rbx), %eax + sub $8, %rbx + ret + .align 32 +ad: add (%rbx), %eax + sub $4, %rbx + ret + .align 32 +su: sub (%rbx), %eax + neg %eax + sub $4, %rbx + ret + .align 32 +mu: mull (%rbx) + sub $4, %rbx + ret + .align 32 +di: mov %eax, %ecx + mov (%rbx), %eax + cdq + idiv %ecx + mov %edx, (%rbx) + ret + .align 32 +an: and (%rbx), %eax + sub $4, %rbx + ret + .align 32 +or: or (%rbx), %eax + sub $4, %rbx + ret + .align 32 +xo: xor (%rbx), %eax + sub $4, %rbx + ret + .align 32 +sl: mov %eax, %ecx + mov (%rbx), %eax + sub $4, %rbx + shl %cl, %eax + ret + .align 32 +sr: mov %eax, %ecx + mov (%rbx), %eax + sub $4, %rbx + sar %cl, %eax + ret + .align 32 +cp: mov %eax, %ecx + mov (%rbx), %edi + mov -4(%rbx), %esi + sub $8, %rbx + lea (%r15,%rdi,4), %rdi + lea (%r15,%rsi,4), %rsi + cmp %eax, %eax + .byte 0xF3, 0xA7 /* repe cmpsd */ + sete %al + movzbl %al, %eax + neg %eax + ret + .align 32 +cy: mov %eax, %ecx + mov (%rbx), %edi + mov -4(%rbx), %esi + mov -8(%rbx), %eax + sub $12, %rbx + lea (%r15,%rdi,4), %rdi + lea (%r15,%rsi,4), %rsi + repe movsd + ret + .align 32 +io: mov %eax, %ecx + mov (%rbx), %eax + sub $4, %rbx + cmp $7, %ecx + ja 1f + lea io_table(%rip), %rdx + movzbl (%rdx,%rcx), %ecx + lea ioa(%rip), %rdx + add %rdx, %rcx + jmp *%rcx +1: ret + +ioa: push %rax + mov $4, %eax /* sys_write */ + mov $1, %edi + mov %rsp, %rsi + mov $1, %edx + call dosys + pop %rax + mov (%rbx), %eax + sub $4, %rbx + ret +iob: add $4, %rbx + mov %eax, (%rbx) + mov $3, %eax /* sys_read */ + push %rax + xor %edi, %edi + mov %rsp, %rsi + mov $1, %edx + call dosys + pop %rax + ret +ioc: mov %eax, %r8d + mov blocks(%rip), %rdi + call rdonly + xor %r10d, %r10d + call block_common + call close + mov %esi, %eax + ret +iod: mov %eax, %r8d + mov blocks(%rip), %rdi + call wronly + mov $1, %r10b + call block_common + call close + mov %esi, %eax + ret +ioe: jmp save_image +iof: call load_image + xor %rax, %rax + xor %r13, %r13 + jmp _execute +iog: mov $65536, %r13d + ret +ioh: add $8, %rbx + mov %eax, -4(%rbx) + lea astack-4(%rip), %rdx + neg %edx + lea 4*32-8(%rbx,%rdx), %rax + shr $2, %eax + mov %eax, (%rbx) + lea (%r12,%rdx), %rax + shr $2, %eax + ret + +_start: xor %eax, %eax + add $8, %rsp + lea memory(%rip), %r15 + lea dstack-4(%rip), %rbx + lea astack-4(%rip), %r12 + xor %r13d, %r13d + lea table(%rip), %rbp + mov 8(%rsp), %rcx + or %rcx, %rcx + jz 1f + mov 16(%rsp), %rcx + or %rcx, %rcx + jz 1f + mov %rcx, blocks(%rip) + mov 24(%rsp), %rcx + or %rcx, %rcx + jz 2f + mov %rcx, rom(%rip) + jmp 3f +1: lea default_blocks(%rip), %rcx + mov %rcx, blocks(%rip) +2: lea default_rom(%rip), %rcx + mov %rcx, rom(%rip) +3: call load_image +_execute: + jmp 3f + .align 64 +2: mov (%r15,%r13,4), %r14d + movzbl %r14b, %edi + shr $8, %r14d + cmp $29, %edi + ja 1f + shl $5, %edi + add %rbp, %rdi + call *%rdi +1: movzbl %r14b, %edi + shr $8, %r14d + cmp $29, %edi + ja 1f + shl $5, %edi + add %rbp, %rdi + call *%rdi +1: movzbl %r14b, %edi + shr $8, %r14d + cmp $29, %edi + ja 1f + shl $5, %edi + add %rbp, %rdi + call *%rdi +1: mov %r14d, %edi + cmp $29, %edi + ja 1f + shl $5, %edi + add %rbp, %rdi + call *%rdi +1: inc %r13 +3: cmp $65536, %r13 + jl 2b + mov $1, %eax /* sys_exit */ + xor %edi, %edi + call dosys diff --git a/source/ilo-amd64-freebsd.s b/source/ilo-amd64-freebsd.s new file mode 100644 index 0000000..f0297a1 --- /dev/null +++ b/source/ilo-amd64-freebsd.s @@ -0,0 +1,420 @@ +/* AMD64 ilo, (c) 2023 Christopher Leonard, MIT License */ + +/* cc -c ilo-amd64-freebsd.s -o ilo.o + ld -nostdlib ilo.o -o ilo +*/ + .global _start + + /* rax: top of stack */ + /* rbx: data stack */ + /* rbp: jump table address */ + /* r12: address stack */ + /* r13: instruction pointer */ + /* r14: opcode shift register */ + /* r15: memory */ + + .bss + + .align 8 +blocks: .skip 8 /* name of blocks file (ilo.blocks) */ +rom: .skip 8 /* name of image (ilo.rom) */ +dstack: .skip 32*4 +astack: .skip 256*4 +a: .skip 4 /* other variables for misc. purposes */ +b: .skip 4 +f: .skip 4 +s: .skip 4 +d: .skip 4 +l: .skip 4 +memory: .skip 65536*4 + + .section .rodata + +default_blocks: + .asciz "ilo.blocks" +default_rom: + .asciz "ilo.rom" + +io_table: + .byte 0 + .byte iob-ioa + .byte ioc-ioa + .byte iod-ioa + .byte ioe-ioa + .byte iof-ioa + .byte iog-ioa + .byte ioh-ioa + + .text + +dosys: push %r8 + push %r9 + push %r10 + push %rdx + syscall + pop %rdx + pop %r10 + pop %r9 + pop %r8 + ret + +rdonly: mov $5, %eax /* sys_open */ + xor %esi, %esi /* O_RDONLY */ + mov $0666, %edx + call dosys + mov %eax, %edi + ret + +wronly: mov $5, %eax /* sys_open */ + mov $1, %esi /* O_WRONLY */ + mov $0666, %edx + call dosys + mov %eax, %edi + ret + +close: mov $6, %eax /* sys_close */ + call dosys + ret + +load_image: + mov rom(%rip), %rdi + call rdonly + or %eax, %eax + jz 1f + mov %r15, %rsi + mov $65536 * 4, %edx + mov $3, %eax /* sys_read */ + call dosys + call close + xor %eax, %eax + lea dstack-4(%rip), %rbx + lea astack-4(%rip), %r12 + xor %r13d, %r13d +1: ret + +save_image: + push %rax + mov rom(%rip), %rdi + call wronly + or %eax, %eax + jz 1f + mov %r15, %rsi + mov $65536 * 4, %edx + mov $4, %eax + call dosys + call close +1: pop %rax + ret + +block_common: + mov $0x1DE, %eax /* sys_lseek */ + mov (%rbx), %esi + shl $12, %esi + xor %edx, %edx /* SEEK_SET */ + call dosys + mov $3, %eax /* sys_read */ + or %r10b, %r10b + jz 1f + mov $4, %al /* sys_write */ +1: lea (%r15,%r8,4), %rsi + mov $4096, %edx + call dosys + mov -4(%rbx), %esi + sub $8, %rbx + ret + + .align 32 +table: ret + .align 32 +li: add $4, %rbx + inc %r13d + mov %eax, (%rbx) + mov (%r15,%r13,4), %eax + ret + .align 32 +du: add $4, %rbx + mov %eax, (%rbx) + ret + .align 32 +dr: mov (%rbx), %eax + sub $4, %rbx + ret + .align 32 +sw: xchg (%rbx), %eax + ret + .align 32 +pu: add $4, %r12 + mov %eax, (%r12) + mov (%rbx), %eax + sub $4, %rbx + ret + .align 32 +po: add $4, %rbx + mov %eax, (%rbx) + mov (%r12), %eax + sub $4, %r12 + ret + .align 32 +ju: lea -1(%eax), %r13d + mov (%rbx), %eax + sub $4, %rbx + ret + .align 32 +ca: add $4, %r12 + mov %r13d, (%r12) + lea -1(%eax), %r13d + mov (%rbx), %eax + sub $4, %rbx + ret + .align 32 +cc: cmpl $0, (%rbx) + jz 1f + add $4, %r12 + mov %r13d, (%r12) + lea -1(%eax), %r13d +1: mov -4(%rbx), %eax + sub $8, %rbx + ret + .align 32 +cj: cmpl $0, (%rbx) + jz 1f + lea -1(%eax), %r13d +1: mov -4(%rbx), %eax + sub $8, %rbx + ret + .align 32 +re: mov (%r12), %r13d + sub $4, %r12 + ret + .align 32 +eq: cmp %eax, (%rbx) + sete %al + movzbl %al, %eax + neg %eax + sub $4, %rbx + ret + .align 32 +ne: cmp %eax, (%rbx) + setne %al + movzbl %al, %eax + neg %eax + sub $4, %rbx + ret + .align 32 +lt: cmp %eax, (%rbx) + setl %al + movzbl %al, %eax + neg %eax + sub $4, %rbx + ret + .align 32 +gt: cmp %eax, (%rbx) + setg %al + movzbl %al, %eax + neg %eax + sub $4, %rbx + ret + .align 32 +fe: mov (%r15,%rax,4), %eax + ret + .align 32 +st: mov (%rbx), %ecx + mov %ecx, (%r15,%rax,4) + mov -4(%rbx), %eax + sub $8, %rbx + ret + .align 32 +ad: add (%rbx), %eax + sub $4, %rbx + ret + .align 32 +su: sub (%rbx), %eax + neg %eax + sub $4, %rbx + ret + .align 32 +mu: mull (%rbx) + sub $4, %rbx + ret + .align 32 +di: mov %eax, %ecx + mov (%rbx), %eax + cdq + idiv %ecx + mov %edx, (%rbx) + ret + .align 32 +an: and (%rbx), %eax + sub $4, %rbx + ret + .align 32 +or: or (%rbx), %eax + sub $4, %rbx + ret + .align 32 +xo: xor (%rbx), %eax + sub $4, %rbx + ret + .align 32 +sl: mov %eax, %ecx + mov (%rbx), %eax + sub $4, %rbx + shl %cl, %eax + ret + .align 32 +sr: mov %eax, %ecx + mov (%rbx), %eax + sub $4, %rbx + sar %cl, %eax + ret + .align 32 +cp: mov %eax, %ecx + mov (%rbx), %edi + mov -4(%rbx), %esi + sub $8, %rbx + lea (%r15,%rdi,4), %rdi + lea (%r15,%rsi,4), %rsi + cmp %eax, %eax + .byte 0xF3, 0xA7 /* repe cmpsd */ + sete %al + movzbl %al, %eax + neg %eax + ret + .align 32 +cy: mov %eax, %ecx + mov (%rbx), %edi + mov -4(%rbx), %esi + mov -8(%rbx), %eax + sub $12, %rbx + lea (%r15,%rdi,4), %rdi + lea (%r15,%rsi,4), %rsi + repe movsd + ret + .align 32 +io: mov %eax, %ecx + mov (%rbx), %eax + sub $4, %rbx + cmp $7, %ecx + ja 1f + lea io_table(%rip), %rdx + movzbl (%rdx,%rcx), %ecx + lea ioa(%rip), %rdx + add %rdx, %rcx + jmp *%rcx +1: ret + +ioa: push %rax + mov $4, %eax /* sys_write */ + mov $1, %edi + mov %rsp, %rsi + mov $1, %edx + call dosys + pop %rax + mov (%rbx), %eax + sub $4, %rbx + ret +iob: add $4, %rbx + mov %eax, (%rbx) + mov $3, %eax /* sys_read */ + push %rax + xor %edi, %edi + mov %rsp, %rsi + mov $1, %edx + call dosys + pop %rax + ret +ioc: mov %eax, %r8d + mov blocks(%rip), %rdi + call rdonly + xor %r10d, %r10d + call block_common + call close + mov %esi, %eax + ret +iod: mov %eax, %r8d + mov blocks(%rip), %rdi + call wronly + mov $1, %r10b + call block_common + call close + mov %esi, %eax + ret +ioe: jmp save_image +iof: call load_image + xor %rax, %rax + xor %r13, %r13 + jmp _execute +iog: mov $65536, %r13d + ret +ioh: add $8, %rbx + mov %eax, -4(%rbx) + lea astack-4(%rip), %rdx + neg %edx + lea 4*32-8(%rbx,%rdx), %rax + shr $2, %eax + mov %eax, (%rbx) + lea (%r12,%rdx), %rax + shr $2, %eax + ret + +_start: xor %eax, %eax + add $8, %rsp + lea memory(%rip), %r15 + lea dstack-4(%rip), %rbx + lea astack-4(%rip), %r12 + xor %r13d, %r13d + lea table(%rip), %rbp + mov 8(%rsp), %rcx + or %rcx, %rcx + jz 1f + mov 16(%rsp), %rcx + or %rcx, %rcx + jz 1f + mov %rcx, blocks(%rip) + mov 24(%rsp), %rcx + or %rcx, %rcx + jz 2f + mov %rcx, rom(%rip) + jmp 3f +1: lea default_blocks(%rip), %rcx + mov %rcx, blocks(%rip) +2: lea default_rom(%rip), %rcx + mov %rcx, rom(%rip) +3: call load_image +_execute: + jmp 3f + .align 64 +2: mov (%r15,%r13,4), %r14d + movzbl %r14b, %edi + shr $8, %r14d + cmp $29, %edi + ja 1f + shl $5, %edi + add %rbp, %rdi + call *%rdi +1: movzbl %r14b, %edi + shr $8, %r14d + cmp $29, %edi + ja 1f + shl $5, %edi + add %rbp, %rdi + call *%rdi +1: movzbl %r14b, %edi + shr $8, %r14d + cmp $29, %edi + ja 1f + shl $5, %edi + add %rbp, %rdi + call *%rdi +1: mov %r14d, %edi + cmp $29, %edi + ja 1f + shl $5, %edi + add %rbp, %rdi + call *%rdi +1: inc %r13 +3: cmp $65536, %r13 + jl 2b + mov $1, %eax /* sys_exit */ + xor %edi, %edi + call dosys diff --git a/source/ilo-amd64-linux.s b/source/ilo-amd64-linux.s new file mode 100644 index 0000000..0be7ca7 --- /dev/null +++ b/source/ilo-amd64-linux.s @@ -0,0 +1,405 @@ +/* AMD64 ilo, (c) 2023 Christopher Leonard, MIT License */ + + .global _start + + /* rax: top of stack */ + /* rbx: data stack */ + /* rbp: jump table address */ + /* r12: address stack */ + /* r13: instruction pointer */ + /* r14: opcode shift register */ + /* r15: memory */ + + .bss + + .align 8 +blocks: .skip 8 /* name of blocks file (ilo.blocks) */ +rom: .skip 8 /* name of image (ilo.rom) */ +dstack: .skip 32*4 +astack: .skip 256*4 +a: .skip 4 /* other variables for misc. purposes */ +b: .skip 4 +f: .skip 4 +s: .skip 4 +d: .skip 4 +l: .skip 4 +memory: .skip 65536*4 + + .section .rodata + +default_blocks: + .asciz "ilo.blocks" +default_rom: + .asciz "ilo.rom" + +io_table: + .byte 0 + .byte iob-ioa + .byte ioc-ioa + .byte iod-ioa + .byte ioe-ioa + .byte iof-ioa + .byte iog-ioa + .byte ioh-ioa + + .text + +rdonly: mov $2, %eax /* sys_open */ + xor %esi, %esi /* O_RDONLY */ + mov $0666, %edx + syscall + mov %eax, %edi + ret + +wronly: mov $2, %eax /* sys_open */ + mov $1, %esi /* O_WRONLY */ + mov $0666, %edx + syscall + mov %eax, %edi + ret + +close: mov $3, %eax /* sys_close */ + syscall + ret + +load_image: + mov rom(%rip), %rdi + call rdonly + or %eax, %eax + jz 1f + mov %r15, %rsi + mov $65536 * 4, %edx + xor %eax, %eax /* sys_read */ + syscall + call close + xor %eax, %eax + lea dstack-4(%rip), %rbx + lea astack-4(%rip), %r12 + xor %r13d, %r13d +1: ret + +save_image: + push %rax + mov rom(%rip), %rdi + call wronly + or %eax, %eax + jz 1f + mov %r15, %rsi + mov $65536 * 4, %edx + mov $1, %eax + syscall + call close +1: pop %rax + ret + +block_common: + mov $8, %eax /* sys_lseek */ + mov (%rbx), %esi + shl $12, %esi + xor %edx, %edx /* SEEK_SET */ + syscall + xor %eax, %eax /* sys_read */ + or %r10b, %r10b + jz 1f + mov $1, %al /* sys_write */ +1: lea (%r15,%r8,4), %rsi + mov $4096, %edx + syscall + mov -4(%rbx), %esi + sub $8, %rbx + ret + + .align 32 +table: ret + .align 32 +li: add $4, %rbx + inc %r13d + mov %eax, (%rbx) + mov (%r15,%r13,4), %eax + ret + .align 32 +du: add $4, %rbx + mov %eax, (%rbx) + ret + .align 32 +dr: mov (%rbx), %eax + sub $4, %rbx + ret + .align 32 +sw: xchg (%rbx), %eax + ret + .align 32 +pu: add $4, %r12 + mov %eax, (%r12) + mov (%rbx), %eax + sub $4, %rbx + ret + .align 32 +po: add $4, %rbx + mov %eax, (%rbx) + mov (%r12), %eax + sub $4, %r12 + ret + .align 32 +ju: lea -1(%eax), %r13d + mov (%rbx), %eax + sub $4, %rbx + ret + .align 32 +ca: add $4, %r12 + mov %r13d, (%r12) + lea -1(%eax), %r13d + mov (%rbx), %eax + sub $4, %rbx + ret + .align 32 +cc: cmpl $0, (%rbx) + jz 1f + add $4, %r12 + mov %r13d, (%r12) + lea -1(%eax), %r13d +1: mov -4(%rbx), %eax + sub $8, %rbx + ret + .align 32 +cj: cmpl $0, (%rbx) + jz 1f + lea -1(%eax), %r13d +1: mov -4(%rbx), %eax + sub $8, %rbx + ret + .align 32 +re: mov (%r12), %r13d + sub $4, %r12 + ret + .align 32 +eq: cmp %eax, (%rbx) + sete %al + movzbl %al, %eax + neg %eax + sub $4, %rbx + ret + .align 32 +ne: cmp %eax, (%rbx) + setne %al + movzbl %al, %eax + neg %eax + sub $4, %rbx + ret + .align 32 +lt: cmp %eax, (%rbx) + setl %al + movzbl %al, %eax + neg %eax + sub $4, %rbx + ret + .align 32 +gt: cmp %eax, (%rbx) + setg %al + movzbl %al, %eax + neg %eax + sub $4, %rbx + ret + .align 32 +fe: mov (%r15,%rax,4), %eax + ret + .align 32 +st: mov (%rbx), %ecx + mov %ecx, (%r15,%rax,4) + mov -4(%rbx), %eax + sub $8, %rbx + ret + .align 32 +ad: add (%rbx), %eax + sub $4, %rbx + ret + .align 32 +su: sub (%rbx), %eax + neg %eax + sub $4, %rbx + ret + .align 32 +mu: mull (%rbx) + sub $4, %rbx + ret + .align 32 +di: mov %eax, %ecx + mov (%rbx), %eax + cdq + idiv %ecx + mov %edx, (%rbx) + ret + .align 32 +an: and (%rbx), %eax + sub $4, %rbx + ret + .align 32 +or: or (%rbx), %eax + sub $4, %rbx + ret + .align 32 +xo: xor (%rbx), %eax + sub $4, %rbx + ret + .align 32 +sl: mov %eax, %ecx + mov (%rbx), %eax + sub $4, %rbx + shl %cl, %eax + ret + .align 32 +sr: mov %eax, %ecx + mov (%rbx), %eax + sub $4, %rbx + sar %cl, %eax + ret + .align 32 +cp: mov %eax, %ecx + mov (%rbx), %edi + mov -4(%rbx), %esi + sub $8, %rbx + lea (%r15,%rdi,4), %rdi + lea (%r15,%rsi,4), %rsi + cmp %eax, %eax + repe cmpsd + sete %al + movzbl %al, %eax + neg %eax + ret + .align 32 +cy: mov %eax, %ecx + mov (%rbx), %edi + mov -4(%rbx), %esi + mov -8(%rbx), %eax + sub $12, %rbx + lea (%r15,%rdi,4), %rdi + lea (%r15,%rsi,4), %rsi + repe movsd + ret + .align 32 +io: mov %eax, %ecx + mov (%rbx), %eax + sub $4, %rbx + cmp $7, %ecx + ja 1f + lea io_table(%rip), %rdx + movzbl (%rdx,%rcx), %ecx + lea ioa(%rip), %rdx + add %rdx, %rcx + jmp *%rcx +1: ret + +ioa: push %rax + mov $1, %eax /* sys_write */ + mov %eax, %edi + mov %rsp, %rsi + mov $1, %edx + syscall + pop %rax + mov (%rbx), %eax + sub $4, %rbx + ret +iob: add $4, %rbx + mov %eax, (%rbx) + xor %eax, %eax /* sys_read */ + push %rax + xor %edi, %edi + mov %rsp, %rsi + mov $1, %edx + syscall + pop %rax + ret +ioc: mov %eax, %r8d + mov blocks(%rip), %rdi + call rdonly + xor %r10d, %r10d + call block_common + call close + mov %esi, %eax + ret +iod: mov %eax, %r8d + mov blocks(%rip), %rdi + call wronly + mov $1, %r10b + call block_common + call close + mov %esi, %eax + ret +ioe: jmp save_image +iof: call load_image + xor %rax, %rax + xor %r13, %r13 + jmp _execute +iog: mov $65536, %r13d + ret +ioh: add $8, %rbx + mov %eax, -4(%rbx) + lea astack-4(%rip), %rdx + neg %edx + lea 4*32-8(%rbx,%rdx), %rax + shr $2, %eax + mov %eax, (%rbx) + lea (%r12,%rdx), %rax + shr $2, %eax + ret + +_start: xor %eax, %eax + lea memory(%rip), %r15 + lea dstack-4(%rip), %rbx + lea astack-4(%rip), %r12 + xor %r13d, %r13d + lea table(%rip), %rbp + mov 8(%rsp), %rcx + or %rcx, %rcx + jz 1f + mov 16(%rsp), %rcx + or %rcx, %rcx + jz 1f + mov %rcx, blocks(%rip) + mov 24(%rsp), %rcx + or %rcx, %rcx + jz 2f + mov %rcx, rom(%rip) + jmp 3f +1: lea default_blocks(%rip), %rcx + mov %rcx, blocks(%rip) +2: lea default_rom(%rip), %rcx + mov %rcx, rom(%rip) +3: call load_image +_execute: + jmp 3f + .align 64 +2: mov (%r15,%r13,4), %r14d + movzbl %r14b, %edi + shr $8, %r14d + cmp $29, %edi + ja 1f + shl $5, %edi + add %rbp, %rdi + call *%rdi +1: movzbl %r14b, %edi + shr $8, %r14d + cmp $29, %edi + ja 1f + shl $5, %edi + add %rbp, %rdi + call *%rdi +1: movzbl %r14b, %edi + shr $8, %r14d + cmp $29, %edi + ja 1f + shl $5, %edi + add %rbp, %rdi + call *%rdi +1: mov %r14d, %edi + cmp $29, %edi + ja 1f + shl $5, %edi + add %rbp, %rdi + call *%rdi +1: inc %r13 +3: cmp $65536, %r13 + jl 2b + mov $60, %eax /* sys_exit */ + xor %edi, %edi + syscall diff --git a/source/ilo-amd64-netbsd.s b/source/ilo-amd64-netbsd.s new file mode 100644 index 0000000..cc37aa5 --- /dev/null +++ b/source/ilo-amd64-netbsd.s @@ -0,0 +1,414 @@ +/* AMD64 ilo, (c) 2023 Christopher Leonard, MIT License */ + + .global _start + + /* rax: top of stack */ + /* rbx: data stack */ + /* rbp: jump table address */ + /* r12: address stack */ + /* r13: instruction pointer */ + /* r14: opcode shift register */ + /* r15: memory */ + +.section ".note.netbsd.ident", "a" +.long 2f-1f +.long 4f-3f +.long 1 +1: .asciz "NetBSD" +2: .p2align 2 +3: .long 199905 +4: .p2align 2 + + .bss + + .align 8 +blocks: .skip 8 /* name of blocks file (ilo.blocks) */ +rom: .skip 8 /* name of image (ilo.rom) */ +dstack: .skip 32*4 +astack: .skip 256*4 +a: .skip 4 /* other variables for misc. purposes */ +b: .skip 4 +f: .skip 4 +s: .skip 4 +d: .skip 4 +l: .skip 4 +memory: .skip 65536*4 + + .section .rodata + +default_blocks: + .asciz "ilo.blocks" +default_rom: + .asciz "ilo.rom" + +io_table: + .byte 0 + .byte iob-ioa + .byte ioc-ioa + .byte iod-ioa + .byte ioe-ioa + .byte iof-ioa + .byte iog-ioa + .byte ioh-ioa + + .text + +rdonly: mov $5, %eax /* sys_open */ + xor %esi, %esi /* O_RDONLY */ + mov $0666, %edx + syscall + mov %eax, %edi + ret + +wronly: mov $5, %eax /* sys_open */ + mov $1, %esi /* O_WRONLY */ + mov $0666, %edx + syscall + mov %eax, %edi + ret + +close: mov $6, %eax /* sys_close */ + syscall + ret + +load_image: + mov rom(%rip), %rdi + call rdonly + or %eax, %eax + jz 1f + mov %r15, %rsi + mov $65536 * 4, %edx + mov $3, %eax /* sys_read */ + syscall + call close + xor %eax, %eax + lea dstack-4(%rip), %rbx + lea astack-4(%rip), %r12 + xor %r13d, %r13d +1: ret + +save_image: + push %rax + mov rom(%rip), %rdi + call wronly + or %eax, %eax + jz 1f + mov %r15, %rsi + mov $65536 * 4, %edx + mov $4, %eax + syscall + call close +1: pop %rax + ret + +block_common: + mov $19, %eax /* sys_lseek */ + mov (%rbx), %esi + shl $12, %esi + xor %edx, %edx /* SEEK_SET */ + syscall + mov $3, %eax /* sys_read */ + or %r10b, %r10b + jz 1f + mov $4, %al /* sys_write */ +1: lea (%r15,%r8,4), %rsi + mov $4096, %edx + syscall + mov -4(%rbx), %esi + sub $8, %rbx + ret + + .align 32 +table: ret + .align 32 +li: add $4, %rbx + inc %r13d + mov %eax, (%rbx) + mov (%r15,%r13,4), %eax + ret + .align 32 +du: add $4, %rbx + mov %eax, (%rbx) + ret + .align 32 +dr: mov (%rbx), %eax + sub $4, %rbx + ret + .align 32 +sw: xchg (%rbx), %eax + ret + .align 32 +pu: add $4, %r12 + mov %eax, (%r12) + mov (%rbx), %eax + sub $4, %rbx + ret + .align 32 +po: add $4, %rbx + mov %eax, (%rbx) + mov (%r12), %eax + sub $4, %r12 + ret + .align 32 +ju: lea -1(%eax), %r13d + mov (%rbx), %eax + sub $4, %rbx + ret + .align 32 +ca: add $4, %r12 + mov %r13d, (%r12) + lea -1(%eax), %r13d + mov (%rbx), %eax + sub $4, %rbx + ret + .align 32 +cc: cmpl $0, (%rbx) + jz 1f + add $4, %r12 + mov %r13d, (%r12) + lea -1(%eax), %r13d +1: mov -4(%rbx), %eax + sub $8, %rbx + ret + .align 32 +cj: cmpl $0, (%rbx) + jz 1f + lea -1(%eax), %r13d +1: mov -4(%rbx), %eax + sub $8, %rbx + ret + .align 32 +re: mov (%r12), %r13d + sub $4, %r12 + ret + .align 32 +eq: cmp %eax, (%rbx) + sete %al + movzbl %al, %eax + neg %eax + sub $4, %rbx + ret + .align 32 +ne: cmp %eax, (%rbx) + setne %al + movzbl %al, %eax + neg %eax + sub $4, %rbx + ret + .align 32 +lt: cmp %eax, (%rbx) + setl %al + movzbl %al, %eax + neg %eax + sub $4, %rbx + ret + .align 32 +gt: cmp %eax, (%rbx) + setg %al + movzbl %al, %eax + neg %eax + sub $4, %rbx + ret + .align 32 +fe: mov (%r15,%rax,4), %eax + ret + .align 32 +st: mov (%rbx), %ecx + mov %ecx, (%r15,%rax,4) + mov -4(%rbx), %eax + sub $8, %rbx + ret + .align 32 +ad: add (%rbx), %eax + sub $4, %rbx + ret + .align 32 +su: sub (%rbx), %eax + neg %eax + sub $4, %rbx + ret + .align 32 +mu: mull (%rbx) + sub $4, %rbx + ret + .align 32 +di: mov %eax, %ecx + mov (%rbx), %eax + cdq + idiv %ecx + mov %edx, (%rbx) + ret + .align 32 +an: and (%rbx), %eax + sub $4, %rbx + ret + .align 32 +or: or (%rbx), %eax + sub $4, %rbx + ret + .align 32 +xo: xor (%rbx), %eax + sub $4, %rbx + ret + .align 32 +sl: mov %eax, %ecx + mov (%rbx), %eax + sub $4, %rbx + shl %cl, %eax + ret + .align 32 +sr: mov %eax, %ecx + mov (%rbx), %eax + sub $4, %rbx + sar %cl, %eax + ret + .align 32 +cp: mov %eax, %ecx + mov (%rbx), %edi + mov -4(%rbx), %esi + sub $8, %rbx + lea (%r15,%rdi,4), %rdi + lea (%r15,%rsi,4), %rsi + cmp %eax, %eax + repe cmpsd + sete %al + movzbl %al, %eax + neg %eax + ret + .align 32 +cy: mov %eax, %ecx + mov (%rbx), %edi + mov -4(%rbx), %esi + mov -8(%rbx), %eax + sub $12, %rbx + lea (%r15,%rdi,4), %rdi + lea (%r15,%rsi,4), %rsi + repe movsd + ret + .align 32 +io: mov %eax, %ecx + mov (%rbx), %eax + sub $4, %rbx + cmp $7, %ecx + ja 1f + lea io_table(%rip), %rdx + movzbl (%rdx,%rcx), %ecx + lea ioa(%rip), %rdx + add %rdx, %rcx + jmp *%rcx +1: ret + +ioa: push %rax + mov $4, %eax /* sys_write */ + mov $1, %edi + mov %rsp, %rsi + mov $1, %edx + syscall + pop %rax + mov (%rbx), %eax + sub $4, %rbx + ret +iob: add $4, %rbx + mov %eax, (%rbx) + mov $3, %eax /* sys_read */ + push %rax + xor %edi, %edi + mov %rsp, %rsi + mov $1, %edx + syscall + pop %rax + ret +ioc: mov %eax, %r8d + mov blocks(%rip), %rdi + call rdonly + xor %r10d, %r10d + call block_common + call close + mov %esi, %eax + ret +iod: mov %eax, %r8d + mov blocks(%rip), %rdi + call wronly + mov $1, %r10b + call block_common + call close + mov %esi, %eax + ret +ioe: jmp save_image +iof: call load_image + xor %rax, %rax + xor %r13, %r13 + jmp _execute +iog: mov $65536, %r13d + ret +ioh: add $8, %rbx + mov %eax, -4(%rbx) + lea astack-4(%rip), %rdx + neg %edx + lea 4*32-8(%rbx,%rdx), %rax + shr $2, %eax + mov %eax, (%rbx) + lea (%r12,%rdx), %rax + shr $2, %eax + ret + +_start: xor %eax, %eax + lea memory(%rip), %r15 + lea dstack-4(%rip), %rbx + lea astack-4(%rip), %r12 + xor %r13d, %r13d + lea table(%rip), %rbp + mov 8(%rsp), %rcx + or %rcx, %rcx + jz 1f + mov 16(%rsp), %rcx + or %rcx, %rcx + jz 1f + mov %rcx, blocks(%rip) + mov 24(%rsp), %rcx + or %rcx, %rcx + jz 2f + mov %rcx, rom(%rip) + jmp 3f +1: lea default_blocks(%rip), %rcx + mov %rcx, blocks(%rip) +2: lea default_rom(%rip), %rcx + mov %rcx, rom(%rip) +3: call load_image +_execute: + jmp 3f + .align 64 +2: mov (%r15,%r13,4), %r14d + movzbl %r14b, %edi + shr $8, %r14d + cmp $29, %edi + ja 1f + shl $5, %edi + add %rbp, %rdi + call *%rdi +1: movzbl %r14b, %edi + shr $8, %r14d + cmp $29, %edi + ja 1f + shl $5, %edi + add %rbp, %rdi + call *%rdi +1: movzbl %r14b, %edi + shr $8, %r14d + cmp $29, %edi + ja 1f + shl $5, %edi + add %rbp, %rdi + call *%rdi +1: mov %r14d, %edi + cmp $29, %edi + ja 1f + shl $5, %edi + add %rbp, %rdi + call *%rdi +1: inc %r13 +3: cmp $65536, %r13 + jl 2b + mov $1, %eax /* sys_exit */ + xor %edi, %edi + syscall diff --git a/source/ilo-amd64-openbsd.s b/source/ilo-amd64-openbsd.s new file mode 100644 index 0000000..cd2ef07 --- /dev/null +++ b/source/ilo-amd64-openbsd.s @@ -0,0 +1,439 @@ +/* AMD64 ilo, (c) 2023 Christopher Leonard, MIT License */ + + .global _start + + /* rax: top of stack */ + /* rbx: data stack */ + /* rbp: jump table address */ + /* r12: address stack */ + /* r13: instruction pointer */ + /* r14: opcode shift register */ + /* r15: memory */ + +.section ".note.openbsd.ident", "a" + + .p2align 2 + .long 0x8 + .long 0x4 + .long 0x1 + .ascii "OpenBSD\0" + .long 0x0 + .p2align 2 + +.section ".openbsd.syscalls" +.long rd0 +.long $5 +.long rd1 +.long $5 +.long rd2 +.long $6 +.long rd3 +.long $3 +.long rd4 +.long $4 +.long rd5 +.long $0xA6 +.long rd6 +.long $3 +.long rd6 +.long $4 +.long rd7 +.long $4 +.long rd8 +.long $3 +.long rd9 +.long $1 + + .bss + + .align 8 +blocks: .skip 8 /* name of blocks file (ilo.blocks) */ +rom: .skip 8 /* name of image (ilo.rom) */ +dstack: .skip 32*4 +astack: .skip 256*4 +a: .skip 4 /* other variables for misc. purposes */ +b: .skip 4 +f: .skip 4 +s: .skip 4 +d: .skip 4 +l: .skip 4 +memory: .skip 65536*4 + + .section .rodata + +default_blocks: + .asciz "ilo.blocks" +default_rom: + .asciz "ilo.rom" + +io_table: + .byte 0 + .byte iob-ioa + .byte ioc-ioa + .byte iod-ioa + .byte ioe-ioa + .byte iof-ioa + .byte iog-ioa + .byte ioh-ioa + + .text + +rdonly: mov $5, %eax /* sys_open */ + xor %esi, %esi /* O_RDONLY */ + mov $0666, %edx +rd0: syscall + mov %eax, %edi + ret + +wronly: mov $5, %eax /* sys_open */ + mov $1, %esi /* O_WRONLY */ + mov $0666, %edx +rd1: syscall + mov %eax, %edi + ret + +close: mov $6, %eax /* sys_close */ +rd2: syscall + ret + +load_image: + mov rom(%rip), %rdi + call rdonly + or %eax, %eax + jz 1f + mov %r15, %rsi + mov $65536 * 4, %edx + mov $3, %eax /* sys_read */ +rd3: syscall + call close + xor %eax, %eax + lea dstack-4(%rip), %rbx + lea astack-4(%rip), %r12 + xor %r13d, %r13d +1: ret + +save_image: + push %rax + mov rom(%rip), %rdi + call wronly + or %eax, %eax + jz 1f + mov %r15, %rsi + mov $65536 * 4, %edx + mov $4, %eax +rd4: syscall + call close +1: pop %rax + ret + +block_common: + mov $0xA6, %eax /* sys_lseek */ + mov (%rbx), %esi + shl $12, %esi + xor %edx, %edx /* SEEK_SET */ +rd5: syscall + mov $3, %eax /* sys_read */ + or %r10b, %r10b + jz 1f + mov $4, %al /* sys_write */ +1: lea (%r15,%r8,4), %rsi + mov $4096, %edx +rd6: syscall + mov -4(%rbx), %esi + sub $8, %rbx + ret + + .align 32 +table: ret + .align 32 +li: add $4, %rbx + inc %r13d + mov %eax, (%rbx) + mov (%r15,%r13,4), %eax + ret + .align 32 +du: add $4, %rbx + mov %eax, (%rbx) + ret + .align 32 +dr: mov (%rbx), %eax + sub $4, %rbx + ret + .align 32 +sw: xchg (%rbx), %eax + ret + .align 32 +pu: add $4, %r12 + mov %eax, (%r12) + mov (%rbx), %eax + sub $4, %rbx + ret + .align 32 +po: add $4, %rbx + mov %eax, (%rbx) + mov (%r12), %eax + sub $4, %r12 + ret + .align 32 +ju: lea -1(%eax), %r13d + mov (%rbx), %eax + sub $4, %rbx + ret + .align 32 +ca: add $4, %r12 + mov %r13d, (%r12) + lea -1(%eax), %r13d + mov (%rbx), %eax + sub $4, %rbx + ret + .align 32 +cc: cmpl $0, (%rbx) + jz 1f + add $4, %r12 + mov %r13d, (%r12) + lea -1(%eax), %r13d +1: mov -4(%rbx), %eax + sub $8, %rbx + ret + .align 32 +cj: cmpl $0, (%rbx) + jz 1f + lea -1(%eax), %r13d +1: mov -4(%rbx), %eax + sub $8, %rbx + ret + .align 32 +re: mov (%r12), %r13d + sub $4, %r12 + ret + .align 32 +eq: cmp %eax, (%rbx) + sete %al + movzbl %al, %eax + neg %eax + sub $4, %rbx + ret + .align 32 +ne: cmp %eax, (%rbx) + setne %al + movzbl %al, %eax + neg %eax + sub $4, %rbx + ret + .align 32 +lt: cmp %eax, (%rbx) + setl %al + movzbl %al, %eax + neg %eax + sub $4, %rbx + ret + .align 32 +gt: cmp %eax, (%rbx) + setg %al + movzbl %al, %eax + neg %eax + sub $4, %rbx + ret + .align 32 +fe: mov (%r15,%rax,4), %eax + ret + .align 32 +st: mov (%rbx), %ecx + mov %ecx, (%r15,%rax,4) + mov -4(%rbx), %eax + sub $8, %rbx + ret + .align 32 +ad: add (%rbx), %eax + sub $4, %rbx + ret + .align 32 +su: sub (%rbx), %eax + neg %eax + sub $4, %rbx + ret + .align 32 +mu: mull (%rbx) + sub $4, %rbx + ret + .align 32 +di: mov %eax, %ecx + mov (%rbx), %eax + cdq + idiv %ecx + mov %edx, (%rbx) + ret + .align 32 +an: and (%rbx), %eax + sub $4, %rbx + ret + .align 32 +or: or (%rbx), %eax + sub $4, %rbx + ret + .align 32 +xo: xor (%rbx), %eax + sub $4, %rbx + ret + .align 32 +sl: mov %eax, %ecx + mov (%rbx), %eax + sub $4, %rbx + shl %cl, %eax + ret + .align 32 +sr: mov %eax, %ecx + mov (%rbx), %eax + sub $4, %rbx + sar %cl, %eax + ret + .align 32 +cp: mov %eax, %ecx + mov (%rbx), %edi + mov -4(%rbx), %esi + sub $8, %rbx + lea (%r15,%rdi,4), %rdi + lea (%r15,%rsi,4), %rsi + cmp %eax, %eax + repe cmpsd + sete %al + movzbl %al, %eax + neg %eax + ret + .align 32 +cy: mov %eax, %ecx + mov (%rbx), %edi + mov -4(%rbx), %esi + mov -8(%rbx), %eax + sub $12, %rbx + lea (%r15,%rdi,4), %rdi + lea (%r15,%rsi,4), %rsi + repe movsd + ret + .align 32 +io: mov %eax, %ecx + mov (%rbx), %eax + sub $4, %rbx + cmp $7, %ecx + ja 1f + lea io_table(%rip), %rdx + movzbl (%rdx,%rcx), %ecx + lea ioa(%rip), %rdx + add %rdx, %rcx + jmp *%rcx +1: ret + +ioa: push %rax + mov $4, %eax /* sys_write */ + mov $1, %edi + mov %rsp, %rsi + mov $1, %edx +rd7: syscall + pop %rax + mov (%rbx), %eax + sub $4, %rbx + ret +iob: add $4, %rbx + mov %eax, (%rbx) + mov $3, %eax /* sys_read */ + push %rax + xor %edi, %edi + mov %rsp, %rsi + mov $1, %edx +rd8: syscall + pop %rax + ret +ioc: mov %eax, %r8d + mov blocks(%rip), %rdi + call rdonly + xor %r10d, %r10d + call block_common + call close + mov %esi, %eax + ret +iod: mov %eax, %r8d + mov blocks(%rip), %rdi + call wronly + mov $1, %r10b + call block_common + call close + mov %esi, %eax + ret +ioe: jmp save_image +iof: call load_image + xor %rax, %rax + xor %r13, %r13 + jmp _execute +iog: mov $65536, %r13d + ret +ioh: add $8, %rbx + mov %eax, -4(%rbx) + lea astack-4(%rip), %rdx + neg %edx + lea 4*32-8(%rbx,%rdx), %rax + shr $2, %eax + mov %eax, (%rbx) + lea (%r12,%rdx), %rax + shr $2, %eax + ret + +_start: xor %eax, %eax + lea memory(%rip), %r15 + lea dstack-4(%rip), %rbx + lea astack-4(%rip), %r12 + xor %r13d, %r13d + lea table(%rip), %rbp + mov 8(%rsp), %rcx + or %rcx, %rcx + jz 1f + mov 16(%rsp), %rcx + or %rcx, %rcx + jz 1f + mov %rcx, blocks(%rip) + mov 24(%rsp), %rcx + or %rcx, %rcx + jz 2f + mov %rcx, rom(%rip) + jmp 3f +1: lea default_blocks(%rip), %rcx + mov %rcx, blocks(%rip) +2: lea default_rom(%rip), %rcx + mov %rcx, rom(%rip) +3: call load_image +_execute: + jmp 3f + .align 64 +2: mov (%r15,%r13,4), %r14d + movzbl %r14b, %edi + shr $8, %r14d + cmp $29, %edi + ja 1f + shl $5, %edi + add %rbp, %rdi + call *%rdi +1: movzbl %r14b, %edi + shr $8, %r14d + cmp $29, %edi + ja 1f + shl $5, %edi + add %rbp, %rdi + call *%rdi +1: movzbl %r14b, %edi + shr $8, %r14d + cmp $29, %edi + ja 1f + shl $5, %edi + add %rbp, %rdi + call *%rdi +1: mov %r14d, %edi + cmp $29, %edi + ja 1f + shl $5, %edi + add %rbp, %rdi + call *%rdi +1: inc %r13 +3: cmp $65536, %r13 + jl 2b + mov $1, %eax /* sys_exit */ + xor %edi, %edi +rd9: syscall diff --git a/source/ilo-banked.c b/source/ilo-banked.c new file mode 100644 index 0000000..56154e0 --- /dev/null +++ b/source/ilo-banked.c @@ -0,0 +1,205 @@ +/*************************************************************** + crc's _ _ + (_) | ___ + | | |/ _ \ a tiny virtual computer + | | | (_) | 64kw RAM, 32-bit, Dual Stack, MISC + |_|_|\___/ ilo.c (c) charles childers + **************************************************************/ + +/* This implementation uses memory separated into multiple + banks. This makes it easier to run on systems with less + RAM. */ + +#include +#include + +#define SLICES 64 +#define SLICESIZE (65536/SLICES) + +int ip, sp, rp, data[33], address[257]; +char *blocks, *rom; + +#ifdef MALLOC +int *memory[SLICES]; +#else +int memory[SLICES][SLICESIZE]; +#endif + +#define TOS data[sp] +#define NOS data[sp-1] +#define TORS address[rp] + +int stack_pop() { + sp--; + return data[sp + 1]; +} + +void stack_push(int value) { + sp++; + data[sp] = value; +} + +void store(int a, int v) { + int slice = a / SLICESIZE; + int actual = a - (slice * SLICESIZE); + memory[slice][actual] = v; +} + +int fetch(int a) { + int slice = a / SLICESIZE; + int actual = a - (slice * SLICESIZE); + return memory[slice][actual]; +} + +void prepare_vm() { + for (ip = 0; ip < 32; ip++) data[ip] = 0; + for (ip = 0; ip < 128; ip++) address[ip] = 0; + ip = sp = rp = 0; +} + +void load_image() { + FILE *fp; + int x, y; + fp = fopen(rom, "rb"); + for (y = 0; y < 65536; y++) { + x = 0; + fread(&x, 4, 1, fp); + store(y, x); + } + fclose(fp); + prepare_vm(); +} + +void save_image() { + FILE *fp; + int i; + fp = fopen(rom, "wb"); + for (i = 0; i < SLICES; i++) + fwrite(&memory[i], sizeof(int), SLICESIZE, fp); + fclose(fp); +} + +void read_block() { + FILE *f; + int block, buffer, x, c; + buffer = stack_pop(); + block = stack_pop(); + f = fopen(blocks, "r+b"); + fseek(f, 4096 * block, SEEK_SET); + for (x = 0; x < 1024; x++) { + c = 0; + fread(&c, 4, 1, f); + store(buffer + x, c); + } + fclose(f); +} + +void write_block() { + FILE *f; + int block, buffer, x, c; + buffer = stack_pop(); + block = stack_pop(); + f = fopen(blocks, "r+b"); + fseek(f, 4096 * block, SEEK_SET); + for (x = 0; x < 1024; x++) { + c = fetch(buffer + x); + fwrite(&c, 4, 1, f); + } + fclose(f); +} + +void process(int o) { + int a, b, target, flag; + int src, dest, len; + switch (o) { + case 0: break; + case 1: ip++; stack_push(fetch(ip)); break; + case 2: stack_push(TOS); break; + case 3: data[sp] = 0; sp--; break; + case 4: a = TOS; TOS = NOS; NOS = a; break; + case 5: rp++; TORS = stack_pop(); break; + case 6: stack_push(TORS); rp--; break; + case 7: ip = stack_pop() - 1; break; + case 8: rp++; TORS = ip; ip = stack_pop() - 1; break; + case 9: target = stack_pop(); flag = stack_pop(); + if (flag != 0) { rp++; TORS = ip; ip = target - 1; } + break; + case 10: target = stack_pop(); flag = stack_pop(); + if (flag != 0) ip = target - 1; break; + case 11: ip = TORS; rp--; break; + case 12: NOS = (NOS == TOS) ? -1 : 0; sp--; break; + case 13: NOS = (NOS != TOS) ? -1 : 0; sp--; break; + case 14: NOS = (NOS < TOS) ? -1 : 0; sp--; break; + case 15: NOS = (NOS > TOS) ? -1 : 0; sp--; break; + case 16: TOS = fetch(TOS); break; + case 17: store(TOS, NOS); sp--; sp--; break; + case 18: NOS += TOS; sp--; break; + case 19: NOS -= TOS; sp--; break; + case 20: NOS *= TOS; sp--; break; + case 21: a = TOS; b = NOS; TOS = b / a; NOS = b % a; break; + case 22: NOS = TOS & NOS; sp--; break; + case 23: NOS = TOS | NOS; sp--; break; + case 24: NOS = TOS ^ NOS; sp--; break; + case 25: NOS = NOS << TOS; sp--; break; + case 26: NOS = NOS >> TOS; sp--; break; + case 27: len = stack_pop(); dest = stack_pop(); + src = stack_pop(); flag = -1; + while (len) { + if (fetch(dest) != fetch(src)) flag = 0; + len -= 1; src += 1; dest += 1; + }; stack_push(flag); break; + case 28: len = stack_pop(); dest = stack_pop(); + src = stack_pop(); + while (len) { + store(dest, fetch(src)); + len -= 1; src += 1; dest += 1; + }; break; + case 29: switch (stack_pop()) { + case 0: putc(stack_pop(), stdout); break; + case 1: stack_push(getc(stdin)); break; + case 2: read_block(); break; + case 3: write_block(); break; + case 4: save_image(); break; + case 5: load_image(); ip = -1; break; + case 6: ip = 65536; break; + case 7: stack_push(sp); stack_push(rp); break; + default: break; + } break; + default: break; + } +} + +void process_opcode_bundle(int opcode) { + process(opcode & 0xFF); + process((opcode >> 8) & 0xFF); + process((opcode >> 16) & 0xFF); + process((opcode >> 24) & 0xFF); +} + +void execute(int address) { + ip = address; + while (ip < 65536) { + process_opcode_bundle(fetch(ip)); + ip++; + } +} + +int main(int argc, char **argv) { + int i; + + blocks = (argc > 1) ? argv[1] : "ilo.blocks"; + rom = (argc > 2) ? argv[2] : "ilo.rom"; + +#ifdef MALLOC + for (i = 0; i < SLICES; i++) + memory[i] = malloc(SLICESIZE * sizeof(int)); +#endif + load_image(); + execute(0); +#ifdef MALLOC + for (i = 0; i < SLICES; i++) + free(memory[i]); +#endif + for (i = 1; sp >= i; i++) printf(" %d", data[i]); + printf("\n"); +} diff --git a/source/ilo-be.c b/source/ilo-be.c new file mode 100644 index 0000000..5709929 --- /dev/null +++ b/source/ilo-be.c @@ -0,0 +1,215 @@ +/*************************************************************** + crc's _ _ + (_) | ___ + | | |/ _ \ a tiny virtual computer + | | | (_) | 64kw RAM, 32-bit, Dual Stack, MISC + |_|_|\___/ ilo-be.c (c) charles childers + + ilo was developed on little endian hosts, and both the ROM and + blocks are stored in little endian. This implementation adds + alternative ROM & block functions to handle the byteswapping + needed on big endian hosts. + **************************************************************/ + +#include +#include +#include + +#define T ds[sp] /* Top of Data Stack */ +#define N ds[sp-1] /* Next on Data Stack */ +#define R as[rp] /* Top of Address Stack */ +#define V void +#define I int +#define C char + +I ip, /* instruction pointer */ + sp, /* data stack pointer */ + rp, /* address stack pointer */ + ds[33], /* data stack */ + as[257], /* address stack */ + m[65536]; /* memory */ + +C *blocks, /* name of block file (ilo.blocks) */ + *rom; /* name of image (ilo.rom) */ + +/* the other variables are used by the various + functions for misc. purposes */ + +I a, b, f, s, d, l; +C i[1]; + +unsigned long byteswap(unsigned long v) { + return (((v & 0x000000FF) << 24)| + ((v & 0x0000FF00) << 8) | + ((v & 0x00FF0000) >> 8) | + ((v & 0xFF000000) >> 24)); +} + +V push(I v) { ds[sp + 1] = v; sp += 1; } +I pop() { sp -= 1; return ds[sp + 1]; } + +V load_image() { + FILE *fp; + long x, y, z; + fp = fopen(rom, "rb"); + for (y = 0; y < 65536; y++) { + x = 0; + fread(&x, 4, 1, fp); + m[y] = byteswap(x); + } + fclose(fp); + ip = sp = rp = 0; +} + +V save_image() { + FILE *fp; + long i, x; + fp = fopen(rom, "wb"); + for (i = 0; i < 65536; i++) { + x = byteswap(m[i]); + fwrite(&x, 4, 1, fp); + } + fclose(fp); +} + +V read_block() { + FILE *f; + long block, buffer, x, c; + buffer = pop(); + block = pop(); + f = fopen(blocks, "r+b"); + fseek(f, 4096 * block, SEEK_SET); + for (x = 0; x < 1024; x++) { + c = 0; + fread(&c, 4, 1, f); + m[buffer + x] = byteswap(c); + } + fclose(f); +} + +V write_block() { + FILE *f; + long block, buffer, x, c; + buffer = pop(); + block = pop(); + f = fopen(blocks, "r+b"); + fseek(f, 4096 * block, SEEK_SET); + for (x = 0; x < 1024; x++) { + c = byteswap(m[buffer + x]); + fwrite(&c, 4, 1, f); + } + fclose(f); +} + +V save_ip() { rp += 1; R = ip; } +V symmetric() { if (b >= 0 && N < 0) { T += 1; N -= b; } } + +V li() { ip += 1; push(m[ip]); } +V du() { push(T); } +V dr() { ds[sp] = 0; sp -= 1; } +V sw() { a = T; T = N; N = a; } +V pu() { rp += 1; R = pop(); } +V po() { push(R); rp -= 1; } +V ju() { ip = pop() - 1; } +V ca() { save_ip(); ip = pop() - 1; } +V cc() { a = pop(); if (pop()) { save_ip(); ip = a - 1; } } +V cj() { a = pop(); if (pop()) { ip = a - 1; } } +V re() { ip = R; rp -= 1; } +V eq() { N = (N == T) ? -1 : 0; sp -= 1; } +V ne() { N = (N != T) ? -1 : 0; sp -= 1; } +V lt() { N = (N < T) ? -1 : 0; sp -= 1; } +V gt() { N = (N > T) ? -1 : 0; sp -= 1; } +V fe() { T = m[T]; } +V st() { m[T] = N; sp -= 2; } +V ad() { N += T; sp -= 1; } +V su() { N -= T; sp -= 1; } +V mu() { N *= T; sp -= 1; } +V di() { a = T; b = N; T = b / a; N = b % a; symmetric(); } +V an() { N = T & N; sp -= 1; } +V or() { N = T | N; sp -= 1; } +V xo() { N = T ^ N; sp -= 1; } +V sl() { N = N << T; sp -= 1; } +V sr() { N = N >> T; sp -= 1; } +V cp() { l = pop(); d = pop(); s = T; T = -1; + while (l) { if (m[d] != m[s]) { T = 0; } + l -= 1; s += 1; d += 1; } } +V cy() { l = pop(); d = pop(); s = pop(); + while (l) { m[d] = m[s]; l -= 1; s += 1; d += 1; } } +V ioa() { i[0] = (char)pop(); write(1, &i, 1); } +V iob() { read(0, &i, 1); push(i[0]); } +V ioc() { read_block(); } +V iod() { write_block(); } +V ioe() { save_image(); } +V iof() { load_image(); ip = -1; } +V iog() { ip = 65536; } +V ioh() { push(sp); push(rp); } +V io() { + switch (pop()) { + case 0: ioa(); break; case 1: iob(); break; + case 2: ioc(); break; case 3: iod(); break; + case 4: ioe(); break; case 5: iof(); break; + case 6: iog(); break; case 7: ioh(); break; + default: break; + } +} + +/* Using a switch here instead of a jump table to avoid */ +/* some issues w/relocation stuff when building w/o libc */ + +V process(I o) { + switch (o) { + case 0: break; case 1: li(); break; + case 2: du(); break; case 3: dr(); break; + case 4: sw(); break; case 5: pu(); break; + case 6: po(); break; case 7: ju(); break; + case 8: ca(); break; case 9: cc(); break; + case 10: cj(); break; case 11: re(); break; + case 12: eq(); break; case 13: ne(); break; + case 14: lt(); break; case 15: gt(); break; + case 16: fe(); break; case 17: st(); break; + case 18: ad(); break; case 19: su(); break; + case 20: mu(); break; case 21: di(); break; + case 22: an(); break; case 23: or(); break; + case 24: xo(); break; case 25: sl(); break; + case 26: sr(); break; case 27: cp(); break; + case 28: cy(); break; case 29: io(); break; + default: break; + } +} + +V process_bundle(I opcode) { + process(opcode & 0xFF); + process((opcode >> 8) & 0xFF); + process((opcode >> 16) & 0xFF); + process((opcode >> 24) & 0xFF); +} + +V execute() { + while (ip < 65536) { + process_bundle(m[ip]); + ip += 1; + } +} + +#ifndef NOSTDLIB + +I main(I argc, C **argv) { + blocks = (argc > 1) ? argv[1] : "ilo.blocks"; + rom = (argc > 2) ? argv[2] : "ilo.rom"; + load_image(); + execute(); + for (; sp > 0; sp -= 1) printf(" %d", ds[sp]); printf("\n"); + return 0; +} + +#else + +I main(I argc, C **argv) { + blocks = "ilo.blocks"; + rom = "ilo.rom"; + load_image(); + execute(); + return 0; +} + +#endif diff --git a/source/ilo-dos.c b/source/ilo-dos.c new file mode 100644 index 0000000..d3fb668 --- /dev/null +++ b/source/ilo-dos.c @@ -0,0 +1,191 @@ +/*************************************************************** + crc's _ _ + (_) | ___ + | | |/ _ \ a tiny virtual computer + | | | (_) | 64kw RAM, 32-bit, Dual Stack, MISC + |_|_|\___/ ilo.c (c) charles childers + **************************************************************/ + +/* This implementation uses memory separated into multiple + banks. This makes it easier to run on systems with less + RAM. */ + +#include +#include + +#define SLICES 8 +#define SLICESIZE 8192 + +long ip, sp, rp, data[33], address[257]; +long *memory[SLICES]; + +#define TOS data[sp] +#define NOS data[sp-1] +#define TORS address[rp] + +long pop() { + sp--; + return data[sp + 1]; +} + +void push(long value) { + sp++; + data[sp] = value; +} + +void store(long a, long v) { + long slice = a / SLICESIZE; + long actual = a - (slice * SLICESIZE); + memory[slice][actual] = v; +} + +long fetch(long a) { + long slice = a / SLICESIZE; + long actual = a - (slice * SLICESIZE); + return memory[slice][actual]; +} + +void prepare_vm() { + for (ip = 0; ip < 32; ip++) data[ip] = 0; + for (ip = 0; ip < 128; ip++) address[ip] = 0; + ip = sp = rp = 0; +} + +void load_image() { + FILE *fp; + long x, y; + fp = fopen("ilo.rom", "rb"); + for (y = 0; y < 65536; y++) { + x = 0; + fread(&x, 4, 1, fp); + store(y, x); + } + fclose(fp); + prepare_vm(); +} + +void save_image() { + FILE *fp; + long i; + fp = fopen("ilo.rom", "wb"); + for (i = 0; i < SLICES; i++) + fwrite(&memory[i], sizeof(long), SLICESIZE, fp); + fclose(fp); +} + +void read_block() { + FILE *f; + long block, buffer, x, c; + buffer = pop(); + block = pop(); + f = fopen("ilo.blo", "r+b"); + fseek(f, 4096 * block, SEEK_SET); + for (x = 0; x < 1024; x++) { + c = 0; + fread(&c, 4, 1, f); + store(buffer + x, c); + } + fclose(f); +} + +void write_block() { + FILE *f; + long block, buffer, x, c; + buffer = pop(); + block = pop(); + f = fopen("ilo.blo", "r+b"); + fseek(f, 4096 * block, SEEK_SET); + for (x = 0; x < 1024; x++) { + c = fetch(buffer + x); + fwrite(&c, 4, 1, f); + } + fclose(f); +} + +void process(long o) { + long a, b, target, flag; + long src, dest, len; + switch (o) { + case 0: break; + case 1: ip++; push(fetch(ip)); break; + case 2: push(TOS); break; + case 3: data[sp] = 0; sp--; break; + case 4: a = TOS; TOS = NOS; NOS = a; break; + case 5: rp++; TORS = pop(); break; + case 6: push(TORS); rp--; break; + case 7: ip = pop() - 1; break; + case 8: rp++; TORS = ip; ip = pop() - 1; break; + case 9: target = pop(); flag = pop(); + if (flag != 0) { rp++; TORS = ip; ip = target - 1; } + break; + case 10: target = pop(); flag = pop(); + if (flag != 0) ip = target - 1; break; + case 11: ip = TORS; rp--; break; + case 12: NOS = (NOS == TOS) ? -1 : 0; sp--; break; + case 13: NOS = (NOS != TOS) ? -1 : 0; sp--; break; + case 14: NOS = (NOS < TOS) ? -1 : 0; sp--; break; + case 15: NOS = (NOS > TOS) ? -1 : 0; sp--; break; + case 16: TOS = fetch(TOS); break; + case 17: store(TOS, NOS); sp--; sp--; break; + case 18: NOS += TOS; sp--; break; + case 19: NOS -= TOS; sp--; break; + case 20: NOS *= TOS; sp--; break; + case 21: a = TOS; b = NOS; TOS = b / a; NOS = b % a; break; + case 22: NOS = TOS & NOS; sp--; break; + case 23: NOS = TOS | NOS; sp--; break; + case 24: NOS = TOS ^ NOS; sp--; break; + case 25: NOS = NOS << TOS; sp--; break; + case 26: NOS = NOS >> TOS; sp--; break; + case 27: len = pop(); dest = pop(); + src = pop(); flag = -1; + while (len) { + if (fetch(dest) != fetch(src)) flag = 0; + len -= 1; src += 1; dest += 1; + }; push(flag); break; + case 28: len = pop(); dest = pop(); + src = pop(); + while (len) { + store(dest, fetch(src)); + len -= 1; src += 1; dest += 1; + }; break; + case 29: switch (pop()) { + case 0: putc(pop(), stdout); break; + case 1: push(getc(stdin)); break; + case 2: read_block(); break; + case 3: write_block(); break; + case 4: save_image(); break; + case 5: load_image(); ip = -1; break; + case 6: ip = 65536; break; + case 7: push(sp); push(rp); break; + default: break; + } break; + default: break; + } +} + +void process_opcode_bundle(long opcode) { + process(opcode & 0xFF); + process((opcode >> 8) & 0xFF); + process((opcode >> 16) & 0xFF); + process((opcode >> 24) & 0xFF); +} + +void execute(long address) { + ip = address; + while (ip < 65536) { + process_opcode_bundle(fetch(ip)); + ip++; + } +} + +int main(long argc, char **argv) { + long i; + for (i = 0; i < SLICES; i++) + memory[i] = malloc(SLICESIZE * sizeof(long)); + load_image(); + execute(0); + for (i = 0; i < SLICES; i++) + free(memory[i]); + for (i = 1; sp >= i; i++) printf(" %d", data[i]); + printf("\n"); +} diff --git a/source/ilo-js.html b/source/ilo-js.html new file mode 100644 index 0000000..b57fe37 --- /dev/null +++ b/source/ilo-js.html @@ -0,0 +1,701 @@ + + + +ilo.js :: Konilo in the Browser + + + + + + + + + + + (using default image & blocks) +


+ +
+ + +
+ Use your own image & blocks.


+ ROM ::::
+ Blocks :
+
+ +
+ --CONFIG--


+ Max lines ::::::::::::::
+ Cycles Between Updates :
+
COLORS + + + + + + + +
+
+
+ + +
+ + + + + + + + diff --git a/source/ilo-min.c b/source/ilo-min.c new file mode 100644 index 0000000..2b1d959 --- /dev/null +++ b/source/ilo-min.c @@ -0,0 +1,71 @@ +/* ilo-min.c (c) charles childers */ +#include +#include +#include +#define V void +#define I int +#define C char +#define T s[sp] +#define N s[sp-1] +#define R r[rp] +#define G s[(--sp)+1] +#define D sp-- +#define P(x) s[++sp]=x +#define F(x,y) f=open(rf,x,0666);y;close(f) +#define B(x,y) f=open(bf,x,0666);b_s();y;close(f) +#define W(x) while(c){x;c--;a++;b++;} +#define X(x) inst[(o>>x)&0xFF]() +#define RUN while(ip<65536) +#define DR "ilo.rom" +#define DB "ilo.blocks" +I ip,sp,rp,s[33],r[257],m[65536],a,b,c,f,o; C *bf,*rf; +V rst() {ip=sp=rp=0;} +V i_l() {F(O_RDONLY,read(f,&m,262144)); rst();} +V i_w() {F(O_WRONLY,write(f,&m,262144));} +V b_s() {a=G; b=G; lseek(f,4096*b,SEEK_SET);} +V b_l() {B(O_RDONLY,read(f,m+a,4096));} +V b_w() {B(O_WRONLY,write(f,m+a,4096));} +V p() {c=G; b=G; a=G;} +V no() {} +V li() {ip++; P(m[ip]);} +V du() {a=T; P(a);} +V dr() {s[sp]=0; D;} +V sw() {a=T; T=N; N=a;} +V pu() {rp++; R=G;} +V po() {P(R); rp--;} +V ju() {ip=G-1;} +V ca() {rp++; R=ip; ip=G-1;} +V cc() {a=G; if (G != 0) {rp++; R=ip; ip=a-1;}} +V cj() {a=G; if (G != 0) ip=a-1;} +V re() {ip=R; rp--;} +V eq() {N=(N == T) ? -1 : 0; D;} +V ne() {N=(N != T) ? -1 : 0; D;} +V lt() {N=(N < T) ? -1 : 0; D;} +V gt() {N=(N > T) ? -1 : 0; D;} +V fe() {T = m[T];} +V st() {m[T]=N; D; D;} +V ad() {N += T; D;} +V su() {N -= T; D;} +V mu() {N *= T; D;} +V di() {a=T; b=N; T=b/a; N=b%a;} +V an() {N=T & N; D;} +V or() {N=T | N; D;} +V xo() {N=T ^ N; D;} +V sl() {N=T << N; D;} +V sr() {N=T >> N; D;} +V cp() {p(); P(-1); W(if(m[b]!=m[a])T=0);} +V cy() {p(); W(m[b]=m[a])} +V i0() {putc(G,stdout);} +V i1() {P(getc(stdin));} +V i5() {i_l(); ip=-1;} +V i6() {ip=65536;} +V i7() {a=sp; P(a); P(rp);} +V (*ix[8])() = {i0, i1, b_l, b_w, i_w, i5, i6, i7}; +V io() {ix[G]();} +V (*inst[30])()={ + no, li, du, dr, sw, pu, po, ju, ca, cc, cj, re, eq, ne, lt, + gt, fe, st, ad, su, mu, di, an, or, xo, sl, sr, cp, cy, io}; +V execute() {RUN{o=m[ip]; X(0); X(8); X(16); X(24); ip++;}} +V ds() {for (;sp>0;D) printf("#%d: %d\n", sp, s[sp]);} +V run() {i_l(); execute(); ds();} +I main(I n, C **v) {bf=(n>1)?v[1]:DB; rf=(n>2)?v[2]:DR; run();} diff --git a/source/ilo-plan9.c b/source/ilo-plan9.c new file mode 100644 index 0000000..d43a6d5 --- /dev/null +++ b/source/ilo-plan9.c @@ -0,0 +1,205 @@ +/*********************************** + ilo-plan9.c (C) Jim Taylor + + Example compilation (amd64): + 6c ilo-plan9.c + 6l -o ilo ilo-plan9.6 + + May want to run it with vt. +***********************************/ + +#include +#include + +#define T ds[sp] /* Top of Data Stack */ +#define N ds[sp-1] /* Next on Data Stack */ +#define R as[rp] /* Top of Address Stack */ +#define INST(c_name); void c_name(void) /* Shorthand for VM INSTructions */ + +int ip, /* instruction pointer */ + sp, /* data stack pointer */ + rp, /* address stack pointer */ + ds[33], /* data stack */ + as[257], /* address stack */ + m[65536]; /* memory */ + +char *blocks, /* name of block file (ilo.blocks) */ + *rom; /* name of image (ilo.rom) */ + +int a, b, fd, s, d, l; +char i[1]; + +void +push(int v) +{ + ds[sp+1] = v; + sp += 1; +} + +int +pop(void) +{ + sp -= 1; + return ds[sp+1]; +} + +void +load_image(void) +{ + fd = open(rom, OREAD); + if(!fd) + return; + read(fd, &m, 65536*4); + close(fd); + ip = sp = rp = 0; +} + +void +save_image(void) +{ + fd = open(rom, OWRITE); + write(fd, &m, 65536*4); + close(fd); +} + +void +block_common(void) +{ + b = pop(); /* block buffer */ + a = pop(); /* block number */ + seek(fd, 4096*a, 0); +} + +void +read_block(void) +{ + fd = open(blocks, OREAD); + block_common(); + read(fd, m+b, 4096); + close(fd); +} + +void +write_block(void) +{ + fd = open(blocks, OWRITE); + block_common(); + write(fd, m+b, 4096); + close(fd); +} + +void save_ip(void) { rp += 1; R = ip; } +void symmetric(void) { if (b >= 0 && N < 0) { T += 1; N -= b; } } + +INST(li) { ip += 1; push(m[ip]); } +INST(du) { push(T); } +INST(dr) { ds[sp] = 0; sp -= 1; } +INST(sw) { a = T; T = N; N = a; } +INST(pu) { rp += 1; R = pop(); } +INST(po) { push(R); rp -= 1; } +INST(ju) { ip = pop() - 1; } +INST(ca) { save_ip(); ip = pop() - 1; } +INST(cc) { a = pop(); if (pop()) { save_ip(); ip = a - 1; } } +INST(cj) { a = pop(); if (pop()) { ip = a - 1; } } +INST(re) { ip = R; rp -= 1; } +INST(eq) { N = (N == T) ? -1 : 0; sp -= 1; } +INST(ne) { N = (N != T) ? -1 : 0; sp -= 1; } +INST(lt) { N = (N < T) ? -1 : 0; sp -= 1; } +INST(gt) { N = (N > T) ? -1 : 0; sp -= 1; } +INST(fe) { T = m[T]; } +INST(st) { m[T] = N; sp -= 2; } +INST(ad) { N += T; sp -= 1; } +INST(su) { N -= T; sp -= 1; } +INST(mu) { N *= T; sp -= 1; } +INST(di) { a = T; b = N; T = b / a; N = b % a; symmetric(); } +INST(an) { N = T & N; sp -= 1; } +INST(or) { N = T | N; sp -= 1; } +INST(xo) { N = T ^ N; sp -= 1; } +INST(sl) { N = N << T; sp -= 1; } +INST(sr) { N = N >> T; sp -= 1; } +INST(cp) +{ + l = pop(); d = pop(); + s = T; T = -1; + while(l) { + if (m[d] != m[s]) + T = 0; + l -= 1; s += 1; d += 1; + } +} +INST(cy) +{ + l = pop(); d = pop(); s = pop(); + while(l) { + m[d] = m[s]; l -= 1; s += 1; d += 1; + } +} +INST(ioa) { i[0] = (char)pop(); write(1, &i, 1); } +INST(iob) { read(0, &i, 1); push(i[0]); } +INST(ioc) { read_block(); } +INST(iod) { write_block(); } +INST(ioe) { save_image(); } +INST(iof) { load_image(); ip = -1; } +INST(iog) { ip = 65536; } +INST(ioh) { push(sp); push(rp); } +INST(io) +{ + switch (pop()) { + case 0: ioa(); break; case 1: iob(); break; + case 2: ioc(); break; case 3: iod(); break; + case 4: ioe(); break; case 5: iof(); break; + case 6: iog(); break; case 7: ioh(); break; + default: break; + } +} + +void +process(int o) +{ + switch (o) { + case 0: break; case 1: li(); break; + case 2: du(); break; case 3: dr(); break; + case 4: sw(); break; case 5: pu(); break; + case 6: po(); break; case 7: ju(); break; + case 8: ca(); break; case 9: cc(); break; + case 10: cj(); break; case 11: re(); break; + case 12: eq(); break; case 13: ne(); break; + case 14: lt(); break; case 15: gt(); break; + case 16: fe(); break; case 17: st(); break; + case 18: ad(); break; case 19: su(); break; + case 20: mu(); break; case 21: di(); break; + case 22: an(); break; case 23: or(); break; + case 24: xo(); break; case 25: sl(); break; + case 26: sr(); break; case 27: cp(); break; + case 28: cy(); break; case 29: io(); break; + default: break; + } +} + +void +process_bundle(int opcode) +{ + process(opcode & 0xFF); + process((opcode >> 8) & 0xFF); + process((opcode >> 16) & 0xFF); + process((opcode >> 24) & 0xFF); +} + +void +execute(void) +{ + while(ip < 65536) { + process_bundle(m[ip]); + ip += 1; + } +} + +void +main() +{ + blocks = "ilo.blocks"; + rom = "ilo.rom"; + load_image(); + execute(); + exits(nil); +} diff --git a/source/ilo-pthread.c b/source/ilo-pthread.c new file mode 100644 index 0000000..15e0a49 --- /dev/null +++ b/source/ilo-pthread.c @@ -0,0 +1,183 @@ +/*************************************************************** + crc's _ _ + (_) | ___ + | | |/ _ \ a tiny virtual computer + | | | (_) | 64kw RAM, 32-bit, Dual Stack, MISC + |_|_|\___/ ilo.c (c) charles childers + **************************************************************/ + +/* cc -lpthread ilo-pthread.c -o ilo */ + +#include +#include +#include +#include +#include + +int ip, sp, rp, data[33], address[257], memory[65536]; +int a, b, t, fp, block, buffer, src, dest, len; +char *blocks, *rom, iob[2]; + +pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + +#define T data[sp] +#define N data[sp-1] +#define R address[rp] +#define V void + +int pop() { return data[(--sp) + 1]; } +V push(int value) { data[++sp] = value; } + +V prepare_vm() { ip = sp = rp = 0; } + +V load_image() { + fp = open(rom, O_RDONLY, 0666); + if (!fp) { return; }; + read(fp, &memory, 65536 * 4); + close(fp); + prepare_vm(); +} + +V save_image() { + fp = open(rom, O_WRONLY, 0666); + write(fp, &memory, 65536 * 4); + close(fp); +} + +V read_block() { + buffer = pop(); + block = pop(); + fp = open(blocks, O_RDONLY, 0666); + lseek(fp, 4096 * block, SEEK_SET); + read(fp, memory + buffer, 4096); + close(fp); +} + +V write_block() { + buffer = pop(); + block = pop(); + fp = open(blocks, O_WRONLY, 0666); + lseek(fp, 4096 * block, SEEK_SET); + write(fp, memory + buffer, 4096); + close(fp); +} + +V li() { ip++; push(memory[ip]); } +V du() { push(T); } +V dr() { data[sp] = 0; sp--; } +V sw() { a = T; T = N; N = a; } +V pu() { rp++; R = pop(); } +V po() { push(R); rp--; } +V ju() { ip = pop() - 1; } +V ca() { rp++; R = ip; ip = pop() - 1; } +V cc() { t = pop(); if (pop()) { rp++; R = ip; ip = t - 1; } } +V cj() { t = pop(); if (pop()) { ip = t - 1; } } +V re() { ip = R; rp--; } +V eq() { N = (N == T) ? -1 : 0; sp--; } +V ne() { N = (N != T) ? -1 : 0; sp--; } +V lt() { N = (N < T) ? -1 : 0; sp--; } +V gt() { N = (N > T) ? -1 : 0; sp--; } +V fe() { T = memory[T]; } +V st() { memory[T] = N; sp--; sp--; } +V ad() { N += T; sp--; } +V su() { N -= T; sp--; } +V mu() { N *= T; sp--; } +V di() { a = T; b = N; T = b / a; N = b % a; } +V an() { N = T & N; sp--; } +V or() { N = T | N; sp--; } +V xo() { N = T ^ N; sp--; } +V sl() { N = N << T; sp--; } +V sr() { N = N >> T; sp--; } +V cp() { len = pop(); dest = pop(); src = pop(); push(-1); + while (len) { + if (memory[dest] != memory[src]) T = 0; + len -= 1; src += 1; dest += 1; + } + } +V cy() { len = pop(); dest = pop(); src = pop(); + while (len) { + memory[dest] = memory[src]; + len -= 1; src += 1; dest += 1; + } + } +V io() { + switch (pop()) { + case 0: + iob[0] = pop(); write(1, &iob, 1); + break; + case 1: push(getchar()); break; + case 2: read_block(); break; + case 3: write_block(); break; + case 4: save_image(); break; + case 5: load_image(); ip = -1; break; + case 6: ip = 65536; exit(0); break; + case 7: push(sp); push(rp); break; + default: break; + } +} + +V process(int o) { + switch (o) { + case 0: break; case 1: li(); break; + case 2: du(); break; case 3: dr(); break; + case 4: sw(); break; case 5: pu(); break; + case 6: po(); break; case 7: ju(); break; + case 8: ca(); break; case 9: cc(); break; + case 10: cj(); break; case 11: re(); break; + case 12: eq(); break; case 13: ne(); break; + case 14: lt(); break; case 15: gt(); break; + case 16: fe(); break; case 17: st(); break; + case 18: ad(); break; case 19: su(); break; + case 20: mu(); break; case 21: di(); break; + case 22: an(); break; case 23: or(); break; + case 24: xo(); break; case 25: sl(); break; + case 26: sr(); break; case 27: cp(); break; + case 28: cy(); break; case 29: io(); break; + default: break; + } +} + +V process_bundle(int opcode) { + process(opcode & 0xFF); + process((opcode >> 8) & 0xFF); + process((opcode >> 16) & 0xFF); + process((opcode >> 24) & 0xFF); +} + +V *execute(V *unused) { + while (ip < 65536) { + pthread_mutex_lock(&mutex); + process_bundle(memory[ip]); + ip++; + pthread_mutex_unlock(&mutex); + pthread_yield(); + } + return 0; +} + +V *guard(V *unused) { + while (1) { + if (sp < 0) { printf("E: data stack underflow\n"); exit(1); } + if (sp > 31) { printf("E: data stack overflow\n"); exit(2); } + if (rp < 0) { printf("E: address stack underflow\n"); exit(3); } + if (rp > 255) { printf("E: address stack overflow\n"); exit(4); } + pthread_yield(); + } + return 0; +} + +int main(int argc, char **argv) { + blocks = (argc > 1) ? argv[1] : "ilo.blocks"; + rom = (argc > 2) ? argv[2] : "ilo.rom"; + load_image(); + + pthread_t cpu, stack_guard; + int e1 = pthread_create(&cpu, NULL, execute, NULL); + int e2 = pthread_create(&stack_guard, NULL, guard, NULL); +// while(1) {pthread_yield();}; + + if (!e2) { + pthread_join(stack_guard, NULL); + pthread_join(cpu, NULL); + } +} diff --git a/source/ilo-safer.c b/source/ilo-safer.c new file mode 100644 index 0000000..97bc5a2 --- /dev/null +++ b/source/ilo-safer.c @@ -0,0 +1,197 @@ +/*************************************************************** + crc's _ _ + (_) | ___ + | | |/ _ \ a tiny virtual computer + | | | (_) | 64kw RAM, 32-bit, Dual Stack, MISC + |_|_|\___/ ilo.c (c) charles childers + **************************************************************/ + +#include +#include +#include +#include + +#define T ds[sp] /* Top of Data Stack */ +#define N ds[sp-1] /* Next on Data Stack */ +#define R as[rp] /* Top of Address Stack */ +#define V void +#define I int +#define C char + +I ip, /* instruction pointer */ + sp, /* data stack pointer */ + rp, /* address stack pointer */ + ds[33], /* data stack */ + as[257], /* address stack */ + m[65536]; /* memory */ + +C *blocks, /* name of block file (ilo.blocks) */ + *rom; /* name of image (ilo.rom) */ + +/* the other variables are used by the various + functions for misc. purposes */ + +I a, b, f, s, d, l; +C i[1]; + +V p(char *s) { while(*s) putchar(*s++); } +V e(char *s) { p("E:"); p(s); p("\n"); exit(1); } +V dso() { if ((sp + 1) > 32) { e("DSO"); } } +V dsu() { if ((sp - 1) < 0) { e("DSU"); } } +V rso() { if ((rp + 1) > 256) { e("RSO"); } } +V rsu() { if ((rp - 1) < 0) { e("RSU"); } } +V dbz() { if (T == 0) { e("DBZ"); } } +V mem() { if (T < 0 || T > 65535) { e("MEM"); } } +V uli() { if (f == -1) { e("ULI"); } } +V usi() { if (f == -1) { e("URI"); } } +V urb() { if (f == -1) { e("URB"); } } +V uwb() { if (f == -1) { e("UWB"); } } +V push(I v) { dso(); ds[sp + 1] = v; sp += 1; } +I pop() { dsu(); sp -= 1; return ds[sp + 1]; } + +V load_image() { + f = open(rom, O_RDONLY, 0666); + uli(); + read(f, &m, 65536 * 4); + close(f); + ip = sp = rp = 0; +} + +V save_image() { + f = open(rom, O_WRONLY, 0666); + usi(); + write(f, &m, 65536 * 4); + close(f); +} + +V block_common() { + b = pop(); /* block buffer */ + a = pop(); /* block number */ + lseek(f, 4096 * a, SEEK_SET); +} + +V read_block() { + f = open(blocks, O_RDONLY, 0666); + urb(); + block_common(); + read(f, m + b, 4096); + close(f); +} + +V write_block() { + f = open(blocks, O_WRONLY, 0666); + uwb(); + block_common(); + write(f, m + b, 4096); + close(f); +} + +V save_ip() { rso(); rp += 1; R = ip; } +V symmetric() { if (b >= 0 && N < 0) { T += 1; N -= b; } } + +V li() { ip += 1; push(m[ip]); } +V du() { push(T); } +V dr() { ds[sp] = 0; sp -= 1; } +V sw() { a = T; T = N; N = a; } +V pu() { rso(); rp += 1; R = pop(); } +V po() { rsu(); push(R); rp -= 1; } +V ju() { ip = pop() - 1; } +V ca() { save_ip(); ip = pop() - 1; } +V cc() { a = pop(); if (pop()) { save_ip(); ip = a - 1; } } +V cj() { a = pop(); if (pop()) { ip = a - 1; } } +V re() { rsu(); ip = R; rp -= 1; } +V eq() { N = (N == T) ? -1 : 0; sp -= 1; } +V ne() { N = (N != T) ? -1 : 0; sp -= 1; } +V lt() { N = (N < T) ? -1 : 0; sp -= 1; } +V gt() { N = (N > T) ? -1 : 0; sp -= 1; } +V fe() { mem(); T = m[T]; } +V st() { mem(); m[T] = N; sp -= 2; } +V ad() { N += T; sp -= 1; } +V su() { N -= T; sp -= 1; } +V mu() { N *= T; sp -= 1; } +V di() { dbz(); + a = T; b = N; T = b / a; N = b % a; symmetric(); } +V an() { N = T & N; sp -= 1; } +V or() { N = T | N; sp -= 1; } +V xo() { N = T ^ N; sp -= 1; } +V sl() { N = N << T; sp -= 1; } +V sr() { N = N >> T; sp -= 1; } +V cp() { l = pop(); d = pop(); s = T; T = -1; + while (l) { if (m[d] != m[s]) { T = 0; } + l -= 1; s += 1; d += 1; } } +V cy() { l = pop(); d = pop(); s = pop(); + while (l) { m[d] = m[s]; l -= 1; s += 1; d += 1; } } +V ioa() { i[0] = (char)pop(); write(1, &i, 1); } +V iob() { read(0, &i, 1); push(i[0]); } +V ioc() { read_block(); } +V iod() { write_block(); } +V ioe() { save_image(); } +V iof() { load_image(); ip = -1; } +V iog() { ip = 65536; } +V ioh() { push(sp); push(rp); } +V io() { + switch (pop()) { + case 0: ioa(); break; case 1: iob(); break; + case 2: ioc(); break; case 3: iod(); break; + case 4: ioe(); break; case 5: iof(); break; + case 6: iog(); break; case 7: ioh(); break; + default: break; + } +} + +/* Using a switch here instead of a jump table to avoid */ +/* some issues w/relocation stuff when building w/o libc */ + +V process(I o) { + switch (o) { + case 0: break; case 1: li(); break; + case 2: du(); break; case 3: dr(); break; + case 4: sw(); break; case 5: pu(); break; + case 6: po(); break; case 7: ju(); break; + case 8: ca(); break; case 9: cc(); break; + case 10: cj(); break; case 11: re(); break; + case 12: eq(); break; case 13: ne(); break; + case 14: lt(); break; case 15: gt(); break; + case 16: fe(); break; case 17: st(); break; + case 18: ad(); break; case 19: su(); break; + case 20: mu(); break; case 21: di(); break; + case 22: an(); break; case 23: or(); break; + case 24: xo(); break; case 25: sl(); break; + case 26: sr(); break; case 27: cp(); break; + case 28: cy(); break; case 29: io(); break; + default: break; + } +} + +#define INST(n) ((opcode >> n) & 0xFF) != 0 + +V process_bundle(I opcode) { + if (INST(0)) process(opcode & 0xFF); + if (INST(8)) process((opcode >> 8) & 0xFF); + if (INST(16)) process((opcode >> 16) & 0xFF); + if (INST(24)) process((opcode >> 24) & 0xFF); +} + +V execute() { + while (ip < 65536) { + process_bundle(m[ip]); + ip += 1; + } +} + +V add_restrictions() { +#ifdef __OpenBSD__ + unveil(blocks, "rw"); + unveil(rom, "rw"); + pledge("stdio rpath wpath", NULL); +#endif +} + +I main(I argc, C **argv) { + blocks = (argc > 1) ? argv[1] : "ilo.blocks"; + rom = (argc > 2) ? argv[2] : "ilo.rom"; + add_restrictions(); + load_image(); + execute(); + return 0; +} diff --git a/source/ilo-teensy41.ino b/source/ilo-teensy41.ino new file mode 100644 index 0000000..11c1f28 --- /dev/null +++ b/source/ilo-teensy41.ino @@ -0,0 +1,267 @@ +// ============================================================= +// crc's _ _ +// (_) | ___ +// | | |/ _ \ a tiny virtual computer +// | | | (_) | 64kw RAM, 32-bit, Dual Stack, MISC +// |_|_|\___/ ilo-teensy41.ino (c) charles childers +// ============================================================ +// This is an ilo for the Teensy 4.1. It derives from the +// ilo-banked.c, as with the DOS & Mac System 5/6/7 ports. +// +// Requirements: +// +// - Teensy 4.1 +// - FAT formatted SD card containing these files: +// - ilo.rom (the system image) +// - ilo.blo (the data blocks) +// - A serial terminal interface +// +// ============================================================ + +#include +#include + +#define VERBOSE + +#define SLICES 64 +#define SLICESIZE (65536/SLICES) + +int ip, sp, rp, data[33], address[257]; +char *blocks, *rom; +extern int image[]; + +int *memory[SLICES]; + +#define TOS data[sp] +#define NOS data[sp-1] +#define TORS address[rp] + +#define I int +#define V void + +I pop() { sp--; return data[sp + 1]; } +V push(int value) { sp++; data[sp] = value; } + +V store(int a, int v) { + int slice = a / SLICESIZE; + int actual = a - (slice * SLICESIZE); + memory[slice][actual] = v; +} + +int fetch(int a) { + int slice = a / SLICESIZE; + int actual = a - (slice * SLICESIZE); + return memory[slice][actual]; +} + +V xlog(const char *s, int eol) { +#ifdef VERBOSE + if (eol) + Serial.println(s); + else + Serial.print(s); +#endif +} + +V load_image() { + File rom = SD.open("ilo.rom", FILE_READ); + int data; + xlog("ilo: load rom", 1); + for (int x = 0; x < 65536; x++) { + data = 0; + rom.read(&data, 4); + store(x, data); + if ((x % 1024) == 0) xlog(".", 0); + } + rom.close(); + delay(10); + xlog("\nilo: rom loaded", 1); +} + +V prepare_vm() { + for (ip = 0; ip < 32; ip++) data[ip] = 0; + for (ip = 0; ip < 128; ip++) address[ip] = 0; + ip = sp = rp = 0; +} + +V read_block() { + File blocks = SD.open("ilo.blo", FILE_READ); + int data; + int buf = pop(); + int blk = pop(); + blocks.seek(4096 * blk); + for (int x = 0; x < 1024; x++) { + data = 0; + blocks.read(&data, 4); + store(buf + x, data); + } + blocks.close(); + delay(10); +} + +V write_block() { + File blocks = SD.open("ilo.blo", FILE_WRITE); + int data; + int buf = pop(); + int blk = pop(); + blocks.seek(4096 * blk); + for (int x = 0; x < 1024; x++) { + data = fetch(buf + x); + blocks.write(&data, 4); + } + blocks.close(); + delay(10); +} + +int led = 13; + +V teensy_io() { + int a, b, c, d, e, f; + switch (pop()) { + case 1: digitalWrite(pop(), HIGH); + break; + case 2: digitalWrite(pop(), LOW); + break; + case 3: a = pop(); + b = pop(); + pinMode(b, a); + break; + case 4: digitalRead(pop()) ? push(-1) : push(0); + break; + case 10: delay(pop()); + break; + case 11: delayMicroseconds(pop()); + break; + case 12: delayNanoseconds(pop()); + break; + case 20: push(hour()); + break; + case 21: push(minute()); + break; + case 22: push(second()); + break; + case 23: push(day()); + break; + case 24: push(month()); + break; + case 25: push(year()); + break; + } +} + +V process(int o) { + int a, b, target, flag; + int src, dest, len, kkk; + char outstr[2] = {'a', 0}; + switch (o) { + case 0: break; + case 1: ip++; push(fetch(ip)); break; + case 2: push(TOS); break; + case 3: data[sp] = 0; sp--; break; + case 4: a = TOS; TOS = NOS; NOS = a; break; + case 5: rp++; TORS = pop(); break; + case 6: push(TORS); rp--; break; + case 7: ip = pop() - 1; break; + case 8: rp++; TORS = ip; ip = pop() - 1; break; + case 9: target = pop(); flag = pop(); + if (flag != 0) { rp++; TORS = ip; ip = target - 1; } + break; + case 10: target = pop(); flag = pop(); + if (flag != 0) ip = target - 1; break; + case 11: ip = TORS; rp--; break; + case 12: NOS = (NOS == TOS) ? -1 : 0; sp--; break; + case 13: NOS = (NOS != TOS) ? -1 : 0; sp--; break; + case 14: NOS = (NOS < TOS) ? -1 : 0; sp--; break; + case 15: NOS = (NOS > TOS) ? -1 : 0; sp--; break; + case 16: TOS = fetch(TOS); break; + case 17: store(TOS, NOS); sp--; sp--; break; + case 18: NOS += TOS; sp--; break; + case 19: NOS -= TOS; sp--; break; + case 20: NOS *= TOS; sp--; break; + case 21: a = TOS; b = NOS; TOS = b / a; NOS = b % a; break; + case 22: NOS = TOS & NOS; sp--; break; + case 23: NOS = TOS | NOS; sp--; break; + case 24: NOS = TOS ^ NOS; sp--; break; + case 25: NOS = NOS << TOS; sp--; break; + case 26: NOS = NOS >> TOS; sp--; break; + case 27: len = pop(); dest = pop(); + src = pop(); flag = -1; + while (len) { + if (fetch(dest) != fetch(src)) flag = 0; + len -= 1; src += 1; dest += 1; + }; push(flag); break; + case 28: len = pop(); dest = pop(); + src = pop(); + while (len) { + store(dest, fetch(src)); + len -= 1; src += 1; dest += 1; + }; break; + case 29: switch (pop()) { + case 0: outstr[0] = pop(); Serial.print(outstr); + if (outstr[0] == 10) { outstr[0] = 13; Serial.print(outstr); } break; + case 1: kkk = 0; while (kkk <= 0) { kkk = Serial.read(); } + outstr[0] = kkk; Serial.print(outstr); + if (kkk == 13) { kkk = 10; } + push(kkk); break; + case 2: read_block(); break; + case 3: write_block(); break; + case 4: break; + case 5: ip = -1; break; + case 6: ip = 65536; break; + case 7: push(sp); push(rp); break; + case 100: teensy_io(); break; + default: break; + } break; + default: break; + } +} + +V execute() { + int opcode, o; + ip = 0; + while (ip < 65536) { + opcode = fetch(ip); + o = opcode & 0xFF; if (o) process(o); + o = (opcode >> 8) & 0xFF; if (o) process(o); + o = (opcode >> 16) & 0xFF; if (o) process(o); + o = (opcode >> 24) & 0xFF; if (o) process(o); + ip++; + } +} + +// the setup routine runs once when you press reset: +V setup() { + Serial.begin(9600); + xlog("ilo: prepare memory", 1); + int i; + for (i = 0; i < SLICES; i++) + memory[i] = (int *)malloc(SLICESIZE * sizeof(int)); + + xlog("ilo: prepare i/o pins", 1); + pinMode(led, OUTPUT); + + xlog("ilo: check for SD card", 1); + if (!SD.begin(BUILTIN_SDCARD)) { + xlog("!!!! card failed, or not present; check SD card and restart", 1); + while (1); + } + + xlog("ilo: check for ilo.rom", 1); + if (!SD.exists("ilo.rom")) { + xlog("!!!! missing ilo.rom; check SD card and restart", 1); + while (1); + } + + xlog("ilo: check for ilo.blo", 1); + if (!SD.exists("ilo.blo")) { + xlog("!!!! missing ilo.blo; check SD card and restart", 1); + while (1); + } +} + +// the loop routine runs over and over again forever: +V loop() { + prepare_vm(); + load_image(); + execute(); +} diff --git a/source/ilo-windows.c b/source/ilo-windows.c new file mode 100644 index 0000000..5c38865 --- /dev/null +++ b/source/ilo-windows.c @@ -0,0 +1,141 @@ +/* ilo-windows.c (c) 2022, charles childers */ + +#include +#include + +int ip, sp, rp, data[33], address[257], memory[65536]; +char *blocks, *rom; + +#define T data[sp] +#define N data[sp-1] +#define R address[rp] + +int pop() { return data[(--sp) + 1]; } +void push(int value) { data[++sp] = value; } + +void prepare_vm() { ip = sp = rp = 0; } + +void load_image() { + int fp; + fp = open(rom, O_RDONLY, 0666); + if (!fp) return; + read(fp, &memory, 65536 * sizeof(int)); + close(fp); + prepare_vm(); +} + +void save_image() { + int fp; + fp = open(rom, O_WRONLY, 0666); + write(fp, &memory, 65536 * sizeof(int)); + close(fp); +} + +void read_block() { + int f, block, buffer; + buffer = pop(); + block = pop(); + f = open(blocks, O_RDONLY, 0666); + lseek(f, 4096 * block, SEEK_SET); + read(f, memory + buffer, 1024 * 4); + close(f); +} + +void write_block() { + int f, block, buffer; + buffer = pop(); + block = pop(); + f = open(blocks, O_WRONLY, 0666); + lseek(f, 4096 * block, SEEK_SET); + write(f, memory + buffer, 4096); + close(f); +} + +void process(int o) { + int a, b, target, src, dest, len; + switch (o) { + case 0: break; + case 1: ip++; push(memory[ip]); break; + case 2: push(T); break; + case 3: data[sp] = 0; sp--; break; + case 4: a = T; T = N; N = a; break; + case 5: rp++; R = pop(); break; + case 6: push(R); rp--; break; + case 7: ip = pop() - 1; break; + case 8: rp++; R = ip; ip = pop() - 1; break; + case 9: target = pop(); + if (pop() != 0) { rp++; R = ip; ip = target - 1; } + break; + case 10: target = pop(); + if (pop() != 0) ip = target - 1; break; + case 11: ip = R; rp--; break; + case 12: N = (N == T) ? -1 : 0; sp--; break; + case 13: N = (N != T) ? -1 : 0; sp--; break; + case 14: N = (N < T) ? -1 : 0; sp--; break; + case 15: N = (N > T) ? -1 : 0; sp--; break; + case 16: T = memory[T]; break; + case 17: memory[T] = N; sp--; sp--; break; + case 18: N += T; sp--; break; + case 19: N -= T; sp--; break; + case 20: N *= T; sp--; break; + case 21: a = T; b = N; T = b / a; N = b % a; break; + case 22: N = T & N; sp--; break; + case 23: N = T | N; sp--; break; + case 24: N = T ^ N; sp--; break; + case 25: N = N << T; sp--; break; + case 26: N = N >> T; sp--; break; + case 27: len = pop(); dest = pop(); + src = pop(); push(-1); + while (len) { + if (memory[dest] != memory[src]) T = 0; + len -= 1; src += 1; dest += 1; + } + break; + case 28: len = pop(); dest = pop(); + src = pop(); + while (len) { + memory[dest] = memory[src]; + len -= 1; src += 1; dest += 1; + } + break; + case 29: switch (pop()) { + case 0: putc(pop(), stdout); break; + case 1: push(getc(stdin)); break; + case 2: read_block(); break; + case 3: write_block(); break; + case 4: save_image(); break; + case 5: load_image(); ip = -1; break; + case 6: ip = 65536; break; + case 7: push(sp); push(rp); break; + default: break; + } + break; + default: break; + } +} + +void process_bundle(int opcode) { + process(opcode & 0xFF); + process((opcode >> 8) & 0xFF); + process((opcode >> 16) & 0xFF); + process((opcode >> 24) & 0xFF); +} + +void execute() { + while (ip < 65536) { + process_bundle(memory[ip]); + ip++; + } +} + +void dump_stack() { + for (; sp > 0; sp--) printf(" %d", data[sp]); printf("\n"); +} + +int main(int argc, char **argv) { + blocks = (argc > 1) ? argv[1] : "ilo.blocks"; + rom = (argc > 2) ? argv[2] : "ilo.rom"; + load_image(); + execute(); + dump_stack(); +} diff --git a/source/ilo.c b/source/ilo.c new file mode 100644 index 0000000..01a8d46 --- /dev/null +++ b/source/ilo.c @@ -0,0 +1,184 @@ +/*************************************************************** + crc's _ _ + (_) | ___ + | | |/ _ \ a tiny virtual computer + | | | (_) | 64kw RAM, 32-bit, Dual Stack, MISC + |_|_|\___/ ilo.c (c) charles childers + **************************************************************/ + +#include +#include +#include + +#define T ds[sp] /* Top of Data Stack */ +#define N ds[sp-1] /* Next on Data Stack */ +#define R as[rp] /* Top of Address Stack */ +#define V void +#define I int +#define C char + +I ip, /* instruction pointer */ + sp, /* data stack pointer */ + rp, /* address stack pointer */ + ds[33], /* data stack */ + as[257], /* address stack */ + m[65536]; /* memory */ + +C *blocks, /* name of block file (ilo.blocks) */ + *rom; /* name of image (ilo.rom) */ + +/* the other variables are used by the various + functions for misc. purposes */ + +I a, b, f, s, d, l; +C i[1]; + +V push(I v) { ds[sp + 1] = v; sp += 1; } +I pop() { sp -= 1; return ds[sp + 1]; } + +V load_image() { + f = open(rom, O_RDONLY, 0666); + if (!f) { return; }; + read(f, &m, 65536 * 4); + close(f); + ip = sp = rp = 0; +} + +V save_image() { + f = open(rom, O_WRONLY, 0666); + write(f, &m, 65536 * 4); + close(f); +} + +V block_common() { + b = pop(); /* block buffer */ + a = pop(); /* block number */ + lseek(f, 4096 * a, SEEK_SET); +} + +V read_block() { + f = open(blocks, O_RDONLY, 0666); + block_common(); + read(f, m + b, 4096); + close(f); +} + +V write_block() { + f = open(blocks, O_WRONLY, 0666); + block_common(); + write(f, m + b, 4096); + close(f); +} + +V save_ip() { rp += 1; R = ip; } +V symmetric() { if (b >= 0 && N < 0) { T += 1; N -= b; } } + +V li() { ip += 1; push(m[ip]); } +V du() { push(T); } +V dr() { ds[sp] = 0; sp -= 1; } +V sw() { a = T; T = N; N = a; } +V pu() { rp += 1; R = pop(); } +V po() { push(R); rp -= 1; } +V ju() { ip = pop() - 1; } +V ca() { save_ip(); ip = pop() - 1; } +V cc() { a = pop(); if (pop()) { save_ip(); ip = a - 1; } } +V cj() { a = pop(); if (pop()) { ip = a - 1; } } +V re() { ip = R; rp -= 1; } +V eq() { N = (N == T) ? -1 : 0; sp -= 1; } +V ne() { N = (N != T) ? -1 : 0; sp -= 1; } +V lt() { N = (N < T) ? -1 : 0; sp -= 1; } +V gt() { N = (N > T) ? -1 : 0; sp -= 1; } +V fe() { T = m[T]; } +V st() { m[T] = N; sp -= 2; } +V ad() { N += T; sp -= 1; } +V su() { N -= T; sp -= 1; } +V mu() { N *= T; sp -= 1; } +V di() { a = T; b = N; T = b / a; N = b % a; symmetric(); } +V an() { N = T & N; sp -= 1; } +V or() { N = T | N; sp -= 1; } +V xo() { N = T ^ N; sp -= 1; } +V sl() { N = N << T; sp -= 1; } +V sr() { N = N >> T; sp -= 1; } +V cp() { l = pop(); d = pop(); s = T; T = -1; + while (l) { if (m[d] != m[s]) { T = 0; } + l -= 1; s += 1; d += 1; } } +V cy() { l = pop(); d = pop(); s = pop(); + while (l) { m[d] = m[s]; l -= 1; s += 1; d += 1; } } +V ioa() { i[0] = (char)pop(); write(1, &i, 1); } +V iob() { read(0, &i, 1); push(i[0]); } +V ioc() { read_block(); } +V iod() { write_block(); } +V ioe() { save_image(); } +V iof() { load_image(); ip = -1; } +V iog() { ip = 65536; } +V ioh() { push(sp); push(rp); } +V io() { + switch (pop()) { + case 0: ioa(); break; case 1: iob(); break; + case 2: ioc(); break; case 3: iod(); break; + case 4: ioe(); break; case 5: iof(); break; + case 6: iog(); break; case 7: ioh(); break; + default: break; + } +} + +/* Using a switch here instead of a jump table to avoid */ +/* some issues w/relocation stuff when building w/o libc */ + +V process(I o) { + switch (o) { + case 0: break; case 1: li(); break; + case 2: du(); break; case 3: dr(); break; + case 4: sw(); break; case 5: pu(); break; + case 6: po(); break; case 7: ju(); break; + case 8: ca(); break; case 9: cc(); break; + case 10: cj(); break; case 11: re(); break; + case 12: eq(); break; case 13: ne(); break; + case 14: lt(); break; case 15: gt(); break; + case 16: fe(); break; case 17: st(); break; + case 18: ad(); break; case 19: su(); break; + case 20: mu(); break; case 21: di(); break; + case 22: an(); break; case 23: or(); break; + case 24: xo(); break; case 25: sl(); break; + case 26: sr(); break; case 27: cp(); break; + case 28: cy(); break; case 29: io(); break; + default: break; + } +} + +V process_bundle(I opcode) { + process(opcode & 0xFF); + process((opcode >> 8) & 0xFF); + process((opcode >> 16) & 0xFF); + process((opcode >> 24) & 0xFF); +} + +V execute() { + while (ip < 65536) { + process_bundle(m[ip]); + ip += 1; + } +} + +#ifndef NOSTDLIB + +I main(I argc, C **argv) { + blocks = (argc > 1) ? argv[1] : "ilo.blocks"; + rom = (argc > 2) ? argv[2] : "ilo.rom"; + load_image(); + execute(); + for (; sp > 0; sp -= 1) printf(" %d", ds[sp]); printf("\n"); + return 0; +} + +#else + +I main(I argc, C **argv) { + blocks = "ilo.blocks"; + rom = "ilo.rom"; + load_image(); + execute(); + return 0; +} + +#endif diff --git a/source/ilo.cl b/source/ilo.cl new file mode 100644 index 0000000..90bb02f --- /dev/null +++ b/source/ilo.cl @@ -0,0 +1,327 @@ +;; ************************************************************* +;; crc's _ _ +;; (_) | ___ +;; | | |/ _ \ a tiny virtual computer +;; | | | (_) | 64kw RAM, 32-bit, Dual Stack, MISC +;; |_|_|\___/ ilo.cl (c) charles childers +;; ************************************************************* + +(declaim (optimize (speed 3) (space 0) (safety 0) (debug 0))) + +(defvar ip 0) ; instruction pointer +(defvar sp 0) ; data stack pointer +(defvar rp 0) ; address stack pointer +(defvar ds (make-array 33)) ; data stack +(defvar as (make-array 257)) ; address stack +(defvar m (make-array 65536)) ; memory + +(defvar blk (make-array 1024)) ; block buffer (i/o) +(defvar blocks "ilo.blocks") ; block file name +(defvar rom "ilo.rom") ; rom file name + +(defvar a 0) +(defvar b 0) +(defvar f 0) +(defvar s 0) +(defvar d 0) +(defvar l 0) +(defvar i (make-array 4)) +(defvar z 0) + +(defun fixint (n) + (let* ((max-value (expt 2 31)) + (unsigned-n (logand n #xffffffff))) + (cond ((> unsigned-n max-value) + (- unsigned-n (* max-value 2))) + ((< unsigned-n (- max-value)) + (+ unsigned-n (* max-value 2))) + (t unsigned-n)))) + +(defun _push (v) + (setf (aref ds (1+ sp)) (fixint v)) + (incf sp)) + +(defun _pop () + (decf sp) + (aref ds (1+ sp))) + +(defun read-integers-into-array (array filename offset) + (with-open-file (stream filename + :element-type '(unsigned-byte 8) + :direction :input) + (file-position stream offset) + (loop for i below (length array) + do (setf (svref array i) + (let ((bytes (make-array 4 + :element-type '(unsigned-byte 8)))) + (read-sequence bytes stream) + (fixint (logior (ash (aref bytes 0) 0) + (ash (aref bytes 1) 8) + (ash (aref bytes 2) 16) + (ash (aref bytes 3) 24)))))))) + +(defun load-image () + (read-integers-into-array m rom 0)) + +(defun save-image ()) + +(defun read-block () + (setq b (_pop) + a (_pop)) + (read-integers-into-array blk blocks (* 4096 a)) + (replace m blk :start1 b :end1 (+ b 1024))) + +(defun copy-block-from-m (org start-index) + (let ((end-index (+ start-index 1024))) + (copy-seq (subseq org start-index end-index)))) + +(defun little-endian (integer) + (let ((bytes (make-array 4 + :element-type '(unsigned-byte 8)))) + (setf (aref bytes 0) (ldb (byte 8 0) integer)) + (setf (aref bytes 1) (ldb (byte 8 8) integer)) + (setf (aref bytes 2) (ldb (byte 8 16) integer)) + (setf (aref bytes 3) (ldb (byte 8 24) integer)) + bytes)) + +(defun write-block () + (setq b (_pop) + a (_pop)) + (with-open-file + (out-stream blocks + :direction :output + :if-exists :append + :element-type '(unsigned-byte 8)) + (file-position out-stream (* 4096 a)) + (loop for integer across (copy-block-from-m m b) do + (write-sequence (little-endian integer) out-stream)))) + +(defun save-ip () + (incf rp) + (setf (aref as rp) ip)) + +(defun symmetric () + (when (and (>= b 0) (< (aref ds (1- sp)) 0)) + (progn + (incf (aref ds sp)) + (decf (aref ds (1- sp)) b)))) + +(defun li () + (incf ip) + (_push (aref m ip))) + +(defun du () + (_push (aref ds sp))) + +(defun dr () + (setf (aref ds sp) 0) + (decf sp)) + +(defun sw () + (setq a (aref ds sp)) + (setf (aref ds sp) (aref ds (1- sp)) + (aref ds (1- sp)) a)) + +(defun pu () + (incf rp) + (setf (aref as rp) (_pop))) + +(defun po () + (_push (aref as rp)) + (decf rp)) + +(defun ju () + (setq ip (- (_pop) 1))) + +(defun ca () + (save-ip) + (setq ip (- (_pop) 1))) + +(defun cc () + (setq a (_pop)) + (when (not (zerop (_pop))) + (save-ip) + (setq ip (- a 1)))) + +(defun cj () + (setq a (_pop)) + (when (not (zerop (_pop))) + (setq ip (- a 1)))) + +(defun re () + (setq ip (aref as rp)) + (decf rp)) + +(defun _eq () + (setf (aref ds (1- sp)) (if (= (aref ds (1- sp)) (aref ds sp)) -1 0)) + (decf sp)) + +(defun ne () + (setf (aref ds (1- sp)) (if (/= (aref ds (1- sp)) (aref ds sp)) -1 0)) + (decf sp)) + +(defun lt () + (setf (aref ds (1- sp)) (if (< (aref ds (1- sp)) (aref ds sp)) -1 0)) + (decf sp)) + +(defun gt () + (setf (aref ds (1- sp)) (if (> (aref ds (1- sp)) (aref ds sp)) -1 0)) + (decf sp)) + +(defun fe () + (setf (aref ds sp) (aref m (aref ds sp)))) + +(defun st () + (setf (aref m (aref ds sp)) (aref ds (1- sp))) + (decf sp 2)) + +(defun ad () + (setf (aref ds (1- sp)) (fixint (+ (aref ds (1- sp)) (aref ds sp)))) + (decf sp)) + +(defun su () + (setf (aref ds (1- sp)) (fixint (- (aref ds (1- sp)) (aref ds sp)))) + (decf sp)) + +(defun mu () + (setf (aref ds (1- sp)) (fixint (* (aref ds (1- sp)) (aref ds sp)))) + (decf sp)) + +(defun di () + (setf a (aref ds sp) + b (aref ds (1- sp)) + (aref ds sp) (fixint (floor b a)) + (aref ds (1- sp)) (fixint (mod b a))) + (symmetric)) + +(defun an () + (setf (aref ds (1- sp)) (fixint (logand (aref ds (1- sp)) (aref ds sp)))) + (decf sp)) + +(defun _or () + (setf (aref ds (1- sp)) (fixint (logior (aref ds (1- sp)) (aref ds sp)))) + (decf sp)) + +(defun xo () + (setf (aref ds (1- sp)) (fixint (logxor (aref ds (1- sp)) (aref ds sp)))) + (decf sp)) + +(defun sl () + (setf (aref ds (1- sp)) (fixint (ash (aref ds (1- sp)) (aref ds sp)))) + (decf sp)) + +(defun sr () + (setf (aref ds (1- sp)) (fixint (ash (aref ds (1- sp)) (- (aref ds sp))))) + (decf sp)) + +(defun cp () + (setf l (_pop) + d (_pop) + s (aref ds sp) + (aref ds sp) -1) + (loop repeat l do + (when (not (= (aref m d) (aref m s))) + (setf (aref ds sp) 0)) + (decf l) + (decf s) + (decf d))) + +(defun cy () + (setf l (_pop) + d (_pop) + s (_pop)) + (loop repeat l do + (setf (aref m d) (aref m s)) + (incf d) + (incf s))) + +(defun ioa () + (setf d (_pop)) + (write-char (code-char d) *standard-output*)) + +(defun iob () + (setf d (read-char *standard-input*)) + (_push (char-code d))) + +(defun ioc () + (read-block)) + +(defun iod () + (write-block)) + +(defun ioe () + (save-image)) + +(defun iof () + (load-image) + (setf ip -1)) + +(defun iog () + (setf ip 65536)) + +(defun ioh () + (_push sp) + (_push rp)) + +(defun io () + (case (_pop) + (0 (ioa)) + (1 (iob)) + (2 (ioc)) + (3 (iod)) + (4 (ioe)) + (5 (iof)) + (6 (iog)) + (7 (ioh)))) + +(defun process (o) + (case o + (0) + (1 (li)) + (2 (du)) + (3 (dr)) + (4 (sw)) + (5 (pu)) + (6 (po)) + (7 (ju)) + (8 (ca)) + (9 (cc)) + (10 (cj)) + (11 (re)) + (12 (_eq)) + (13 (ne)) + (14 (lt)) + (15 (gt)) + (16 (fe)) + (17 (st)) + (18 (ad)) + (19 (su)) + (20 (mu)) + (21 (di)) + (22 (an)) + (23 (_or)) + (24 (xo)) + (25 (sl)) + (26 (sr)) + (27 (cp)) + (28 (cy)) + (29 (io)) + (otherwise nil))) + +(defun process-bundle (opcode) + (process (logand opcode #xFF)) + (process (logand (ash opcode -8) #xFF)) + (process (logand (ash opcode -16) #xFF)) + (process (logand (ash opcode -24) #xFF))) + +(defun _execute () + (loop while (< ip 65536) do + (process-bundle (aref m ip)) + (incf ip))) + +(defun main () + (load-image) + (_execute)) + +(main) +(quit) diff --git a/source/ilo.cs b/source/ilo.cs new file mode 100644 index 0000000..24e77cb --- /dev/null +++ b/source/ilo.cs @@ -0,0 +1,161 @@ +// ilo.cs, (c) charles childers + +using System; +using System.IO; +using System.Text; + +namespace ilo { + class VM { + + public int sp, rp, ip; + public int[] d, a, m; + + public VM() { + sp = 0; + rp = 0; + ip = 0; + d = new int[33]; + a = new int[257]; + m = new int[65536]; + load_rom(); + } + + public void load_rom() { + int i = 0; + if (!File.Exists("ilo.rom")) { + Console.Write("ilo.rom missing"); + Environment.Exit(1); + } + BinaryReader rom = new BinaryReader(File.Open("ilo.rom", FileMode.Open)); + while (i < 65536) { m[i] = rom.ReadInt32(); i++; } + rom.Close(); + } + + public void read_block() { + int buffer = d[sp]; sp--; + int block = d[sp]; sp--; + int i = 0; + BinaryReader blocks = new BinaryReader(File.Open("ilo.blocks", FileMode.Open)); + blocks.BaseStream.Seek(4096 * block, SeekOrigin.Begin); + while (i < 1024) { m[buffer + i] = blocks.ReadInt32(); i++; } + blocks.Close(); + } + + public void write_block() { + int buffer = d[sp]; sp--; + int block = d[sp]; sp--; + int i = 0; + BinaryWriter blocks = new BinaryWriter(File.Open("ilo.blocks", FileMode.Open, FileAccess.ReadWrite)); + blocks.BaseStream.Seek(4096 * block, SeekOrigin.Begin); + while (i < 1024) { blocks.Write(m[buffer + i]); i++; } + blocks.Close(); + } + + public void push(int x) { sp++; d[sp] = x; } + public int pop() { sp--; return d[sp + 1]; } + + public void no() { } + public void li() { ip++; sp++; d[sp] = m[ip]; } + public void du() { sp++; d[sp] = d[sp - 1]; } + public void dr() { sp--; } + public void sw() { int x = d[sp], y = d[sp - 1]; d[sp] = y; d[sp - 1] = x; } + public void pu() { rp++; a[rp] = d[sp]; sp--; } + public void po() { sp++; d[sp] = a[rp]; rp--; } + public void ju() { ip = d[sp] - 1; sp--; } + public void ca() { rp++; a[rp] = ip; ju(); } + public void cc() { if (d[sp - 1] != 0) { rp++; a[rp] = ip; ip = d[sp] - 1; } sp -= 2; } + public void cj() { if (d[sp - 1] != 0) { ip = d[sp] - 1; } sp -= 2; } + public void re() { ip = a[rp]; rp--; } + public void eq() { d[sp - 1] = (d[sp - 1] == d[sp]) ? -1 : 0; sp--; } + public void ne() { d[sp - 1] = (d[sp - 1] != d[sp]) ? -1 : 0; sp--; } + public void lt() { d[sp - 1] = (d[sp - 1] < d[sp]) ? -1 : 0; sp--; } + public void gt() { d[sp - 1] = (d[sp - 1] > d[sp]) ? -1 : 0; sp--; } + public void fe() { d[sp] = m[d[sp]]; } + public void st() { m[d[sp]] = d[sp - 1]; sp -= 2; } + public void ad() { d[sp - 1] += d[sp]; sp--; } + public void su() { d[sp - 1] -= d[sp]; sp--; } + public void mu() { d[sp - 1] *= d[sp]; sp--; } + public void di() { int x = d[sp], y = d[sp - 1]; d[sp] = y / x; d[sp - 1] = y % x; } + public void an() { d[sp - 1] = d[sp] & d[sp - 1]; sp--; } + public void or() { d[sp - 1] = d[sp] | d[sp - 1]; sp--; } + public void xo() { d[sp - 1] = d[sp] ^ d[sp - 1]; sp--; } + public void sl() { d[sp - 1] = d[sp] << d[sp - 1]; sp--; } + public void sr() { d[sp - 1] = d[sp] >>= d[sp - 1]; sp--; } + public void cp() { + int len = d[sp]; sp--; + int dest = d[sp]; sp--; + int src = d[sp]; sp--; + sp++; d[sp] = -1; + while (len > 0) { + if (m[dest] != m[src]) { d[sp] = 0; } + len -= 1; src += 1; dest += 1; + } + } + public void cy() { + int len = d[sp]; sp--; + int dest = d[sp]; sp--; + int src = d[sp]; sp--; + while (len > 0) { + m[dest] = m[src]; + len -= 1; src += 1; dest += 1; + } + } + + public void iowr() { Console.Write((char)d[sp]); sp--; } + public void iord() { ConsoleKeyInfo x = Console.ReadKey(); sp++; d[sp] = (int)x.KeyChar; if (d[sp] == 13) { d[sp] = 10; } } + public void iorb() { read_block(); } + public void iowb() { write_block(); } + public void iosi() { } + public void ioli() { load_rom(); ip = -1; } + public void ioen() { ip = 65536; } + public void iost() { sp++; d[sp] = sp - 1; sp++; d[sp] = rp; } + + public void io() { + int act = d[sp]; sp--; + switch (act) { + case 0: iowr(); break; case 1: iord(); break; + case 2: iorb(); break; case 3: iowb(); break; + case 4: iosi(); break; case 5: ioli(); break; + case 6: ioen(); break; case 7: iost(); break; + } + } + + public void process(int o) { + switch(o) { + case 0: no(); break; case 1: li(); break; + case 2: du(); break; case 3: dr(); break; + case 4: sw(); break; case 5: pu(); break; + case 6: po(); break; case 7: ju(); break; + case 8: ca(); break; case 9: cc(); break; + case 10: cj(); break; case 11: re(); break; + case 12: eq(); break; case 13: ne(); break; + case 14: lt(); break; case 15: gt(); break; + case 16: fe(); break; case 17: st(); break; + case 18: ad(); break; case 19: su(); break; + case 20: mu(); break; case 21: di(); break; + case 22: an(); break; case 23: or(); break; + case 24: xo(); break; case 25: sl(); break; + case 26: sr(); break; case 27: cp(); break; + case 28: cy(); break; case 29: io(); break; + } + } + + public void execute() { + int raw = 0; + ip = 0; + while (ip < 65536) { + raw = m[ip]; + for (int i = 0; i < 4; i++) { + process(raw & 0xFF); + raw = raw >> 8; + } + ip++; + } + } + + public static void Main(string[] args) { + VM ilo = new VM(); + ilo.execute(); + } + } +} diff --git a/source/ilo.cxx b/source/ilo.cxx new file mode 100644 index 0000000..3ec4b4c --- /dev/null +++ b/source/ilo.cxx @@ -0,0 +1,187 @@ +/*************************************************************** + crc's _ _ + (_) | ___ + | | |/ _ \ a tiny virtual computer + | | | (_) | 64kw RAM, 32-bit, Dual Stack, MISC + |_|_|\___/ ilo.cxx (c) charles childers + **************************************************************/ + +#include +#include +#include +#include + +/* ip instruction pointer + sp data stack pointer + rp address stack pointer + ds data stack (32 values) + as address stack (256 values) + m memory (65,536 values) + rom name of image (default to ilo.rom) + blocks name of block file (default to ilo.blocks) + + the other variables are used by the various functions for + misc. purposes +*/ + +int ip, sp, rp, ds[33], as[257], m[65536]; +int a, b, t, fp, block, buffer, src, dest, len; +char *blocks, *rom, iob[2]; + +/* T is top of stack + N is next on stack + R is top of address stack + V is void +*/ + +#define T ds[sp] +#define N ds[sp-1] +#define R as[rp] +#define V void + +int pop() { sp -= 1; return ds[sp + 1]; } +V push(int value) { sp += 1; ds[sp] = value; } + +V prepare_vm() { ip = sp = rp = 0; } + +V load_image() { + fp = open(rom, O_RDONLY, 0666); + if (!fp) { return; }; + read(fp, &m, 65536 * 4); + close(fp); + prepare_vm(); +} + +V save_image() { + fp = open(rom, O_WRONLY, 0666); + write(fp, &m, 65536 * 4); + close(fp); +} + +V block_common() { + buffer = pop(); + block = pop(); + lseek(fp, 4096 * block, SEEK_SET); +} + +V read_block() { + fp = open(blocks, O_RDONLY, 0666); + block_common(); + read(fp, m + buffer, 4096); + close(fp); +} + +V write_block() { + fp = open(blocks, O_WRONLY, 0666); + block_common(); + write(fp, m + buffer, 4096); + close(fp); +} + +V save_ip() { rp += 1; R = ip; } +V symmetric() { if (b >= 0 && N < 0) { T++; N -= b; } } + +V li() { ip += 1; push(m[ip]); } +V du() { push(T); } +V dr() { ds[sp] = 0; sp -= 1; } +V sw() { a = T; T = N; N = a; } +V pu() { rp += 1; R = pop(); } +V po() { push(R); rp -= 1; } +V ju() { ip = pop() - 1; } +V ca() { save_ip(); ip = pop() - 1; } +V cc() { t = pop(); if (pop()) { save_ip(); ip = t - 1; } } +V cj() { t = pop(); if (pop()) { ip = t - 1; } } +V re() { ip = R; rp -= 1; } +V eq() { N = (N == T) ? -1 : 0; sp -= 1; } +V ne() { N = (N != T) ? -1 : 0; sp -= 1; } +V lt() { N = (N < T) ? -1 : 0; sp -= 1; } +V gt() { N = (N > T) ? -1 : 0; sp -= 1; } +V fe() { T = m[T]; } +V st() { m[T] = N; sp -= 2; } +V ad() { N += T; sp -= 1; } +V su() { N -= T; sp -= 1; } +V mu() { N *= T; sp -= 1; } +V di() { a = T; b = N; T = b / a; N = b % a; symmetric(); } +V an() { N = T & N; sp -= 1; } +V or_() { N = T | N; sp -= 1; } +V xo() { N = T ^ N; sp -= 1; } +V sl() { N = N << T; sp -= 1; } +V sr() { N = N >> T; sp -= 1; } +V cp() { len = pop(); dest = pop(); src = pop(); push(-1); + while (len) { + if (m[dest] != m[src]) { T = 0; } + len -= 1; src += 1; dest += 1; + } + } +V cy() { len = pop(); dest = pop(); src = pop(); + while (len) { + m[dest] = m[src]; + len -= 1; src += 1; dest += 1; + } + } +V iowr() { iob[0] = pop(); write(1, &iob, 1); } +V iord() { read(0, &iob, 1); push(iob[0]); } +V iorb() { read_block(); } +V iowb() { write_block(); } +V iosi() { save_image(); } +V ioli() { load_image(); ip = -1; } +V ioen() { ip = 65536; } +V iost() { push(sp); push(rp); } +V io() { + switch (pop()) { + case 0: iowr(); break; case 1: iord(); break; + case 2: iorb(); break; case 3: iowb(); break; + case 4: iosi(); break; case 5: ioli(); break; + case 6: ioen(); break; case 7: iost(); break; + default: break; + } +} + +/* Using a switch here instead of a jump table to avoid */ +/* some issues w/relocation stuff when building w/o libc */ + +V process(int o) { + switch (o) { + case 0: break; case 1: li(); break; + case 2: du(); break; case 3: dr(); break; + case 4: sw(); break; case 5: pu(); break; + case 6: po(); break; case 7: ju(); break; + case 8: ca(); break; case 9: cc(); break; + case 10: cj(); break; case 11: re(); break; + case 12: eq(); break; case 13: ne(); break; + case 14: lt(); break; case 15: gt(); break; + case 16: fe(); break; case 17: st(); break; + case 18: ad(); break; case 19: su(); break; + case 20: mu(); break; case 21: di(); break; + case 22: an(); break; case 23: or_(); break; + case 24: xo(); break; case 25: sl(); break; + case 26: sr(); break; case 27: cp(); break; + case 28: cy(); break; case 29: io(); break; + default: break; + } +} + +V process_bundle(int opcode) { + process(opcode & 0xFF); + process((opcode >> 8) & 0xFF); + process((opcode >> 16) & 0xFF); + process((opcode >> 24) & 0xFF); +} + +V execute() { + while (ip < 65536) { + process_bundle(m[ip]); + ip += 1; + } +} + +int main(int argc, char **argv) { + blocks = (argc > 1) ? argv[1] : (char *)"ilo.blocks"; + rom = (argc > 2) ? argv[2] : (char *)"ilo.rom"; + load_image(); + execute(); + for (; sp > 0; sp -= 1) + std::cout << ds[sp] << ' '; + std::cout << '\n'; + return 0; +} diff --git a/source/ilo.d b/source/ilo.d new file mode 100644 index 0000000..5d5b534 --- /dev/null +++ b/source/ilo.d @@ -0,0 +1,232 @@ +/*************************************************************** + crc's _ _ + (_) | ___ + | | |/ _ \ a tiny virtual computer + | | | (_) | 64kw RAM, 32-bit, Dual Stack, MISC + |_|_|\___/ ilo.d (c) charles childers + **************************************************************/ + +import std.stdio; + +Stack data, addr; /* data & address stacks */ +RAM memory; /* system memory */ +int ip; /* instruction pointer */ +string blocks; /* name of block file (ilo.blocks) */ +string rom; /* name of image (ilo.rom) */ + +void load_image() { + data = new Stack(33); + addr = new Stack(257); + memory = new RAM(); + FILE *file = fopen(rom.ptr, "rb"); + if (file is null) { return; } + fread(memory.pointer(), 1, 65536 * 4, file); + fclose(file); + ip = 0; +} + +void save_image() { + FILE *file = fopen(rom.ptr, "wb"); + fwrite(memory.pointer(), 1, 65536 * 4, file); + fclose(file); +} + +void read_block() { + int[1024] block; + FILE *file = fopen(blocks.ptr, "rb"); + if (file is null) { return; } + int b = data.pop(); /* block buffer */ + int a = data.pop(); /* block number */ + fseek(file, 4096 * a, SEEK_SET); + fread(block.ptr, 1, 4096, file); + foreach(i; 0 .. 1024) { memory.store(b + i, block[i]); } + fclose(file); +} + +void write_block() { + int[1024] block; + FILE *file = fopen(blocks.ptr, "r+b"); + if (file is null) { return; } + int b = data.pop(); /* block buffer */ + int a = data.pop(); /* block number */ + fseek(file, 4096 * a, SEEK_SET); + foreach(i; 0 .. 1024) { block[i] = memory.fetch(b + i); } + fwrite(block.ptr, 1, 4096, file); + fclose(file); +} + +void li() { ip += 1; data.push(memory.fetch(ip)); } +void du() { data.dup(); } +void dr() { data.pop(); } +void sw() { data.swap(); } +void pu() { addr.push(data.pop()); } +void po() { data.push(addr.pop()); } +void ju() { ip = data.pop() - 1; } +void ca() { addr.push(ip); ip = data.pop() - 1; } +void cc() { int a = data.pop(); if (data.pop()) { addr.push(ip); ip = a - 1; } } +void cj() { int a = data.pop(); if (data.pop()) { ip = a - 1; } } +void re() { ip = addr.pop(); } +void eq() { data.swap(); data.push((data.pop() == data.pop()) ? -1 : 0); } +void ne() { data.swap(); data.push((data.pop() != data.pop()) ? -1 : 0); } +void lt() { data.swap(); data.push((data.pop() < data.pop()) ? -1 : 0); } +void gt() { data.swap(); data.push((data.pop() > data.pop()) ? -1 : 0); } +void fe() { data.push(memory.fetch(data.pop())); } +void st() { int a = data.pop(); memory.store(a, data.pop()); } +void ad() { data.swap(); data.push(data.pop() + data.pop()); } +void su() { data.swap(); data.push(data.pop() - data.pop()); } +void mu() { data.swap(); data.push(data.pop() * data.pop()); } +void di() { int a = data.pop(); int b = data.pop(); data.push(b % a); data.push(b / a); } +void an() { data.push(data.pop() & data.pop()); } +void or() { data.push(data.pop() | data.pop()); } +void xo() { data.push(data.pop() ^ data.pop()); } +void sl() { data.swap(); data.push(data.pop() << data.pop()); } +void sr() { data.swap(); data.push(data.pop() >> data.pop()); } +void cp() { int l = data.pop(); int d = data.pop(); int s = data.pop(); data.push(-1); + while (l) { if (memory.fetch(d) != memory.fetch(s)) { data.pop(); data.push(0); } + l -= 1; s += 1; d += 1; } } +void cy() { int l = data.pop(); int d = data.pop(); int s = data.pop(); + while (l) { memory.store(d, memory.fetch(s)); l -= 1; s += 1; d += 1; } } +void ioa() { writef("%c", cast(char)data.pop()); } +void iob() { data.push(getchar()); } +void ioc() { read_block(); } +void iod() { write_block(); } +void ioe() { save_image(); } +void iof() { load_image(); ip = -1; } +void iog() { ip = 65536; } +void ioh() { data.push(data.depth()); data.push(addr.depth()); } +void io() { + switch (data.pop()) { + case 0: ioa(); break; case 1: iob(); break; + case 2: ioc(); break; case 3: iod(); break; + case 4: ioe(); break; case 5: iof(); break; + case 6: iog(); break; case 7: ioh(); break; + default: break; + } +} + +void process(int o) { + switch (o) { + case 0: break; case 1: li(); break; + case 2: du(); break; case 3: dr(); break; + case 4: sw(); break; case 5: pu(); break; + case 6: po(); break; case 7: ju(); break; + case 8: ca(); break; case 9: cc(); break; + case 10: cj(); break; case 11: re(); break; + case 12: eq(); break; case 13: ne(); break; + case 14: lt(); break; case 15: gt(); break; + case 16: fe(); break; case 17: st(); break; + case 18: ad(); break; case 19: su(); break; + case 20: mu(); break; case 21: di(); break; + case 22: an(); break; case 23: or(); break; + case 24: xo(); break; case 25: sl(); break; + case 26: sr(); break; case 27: cp(); break; + case 28: cy(); break; case 29: io(); break; + default: break; + } +} + +void process_bundle(int opcode) { + process(opcode & 0xFF); + process((opcode >> 8) & 0xFF); + process((opcode >> 16) & 0xFF); + process((opcode >> 24) & 0xFF); +} + +void execute() { + while (ip < 65536) { + process_bundle(memory.fetch(ip)); + ip += 1; + } +} + +void main(string[] args) { + blocks = "ilo.blocks"; + rom = "ilo.rom"; + load_image(); + execute(); + data.print(); + writef("\n"); +} + +class RAM { + private int[65536] data; + + this() { + } + + int fetch(int a) { + if (a < 0 || a > 65535) + throw new Exception("Invalid memory access"); + return data[a]; + } + + void store(int a, int v) { + if (a < 0 || a > 65535) + throw new Exception("Invalid memory access"); + data[a] = v; + } + + int* pointer() { + return data.ptr; + } +} + +class Stack { + private int[] stack; + private int top; + private int capacity; + + this(int capacity) { + this.capacity = capacity; + stack = new int[capacity]; + top = -1; + } + + bool isEmpty() { + return top == -1; + } + + bool isFull() { + return top == capacity - 1; + } + + void push(int value) { + if (isFull()) + throw new Exception("Stack overflow"); + stack[++top] = value; + } + + int pop() { + if (isEmpty()) + throw new Exception("Stack underflow"); + return stack[top--]; + } + + void dup() { + if (isEmpty()) + throw new Exception("Stack is empty"); + + if (isFull()) + throw new Exception("Stack overflow"); + push(stack[top]); + } + + void swap() { + if (top < 1) + throw new Exception("Insufficient elements to swap"); + + int temp = stack[top]; + stack[top] = stack[top - 1]; + stack[top - 1] = temp; + } + + int depth() { + return top + 1; + } + + void print() { + for (int i = top; i >= 0; i--) { + writeln(stack[i]); + } + } +} diff --git a/source/ilo.fnt b/source/ilo.fnt new file mode 100644 index 0000000000000000000000000000000000000000..9a98ece7d1ff5ad3e396e364c65ddf0f01e78cc3 GIT binary patch literal 4096 zcmZWs&uimW5Ekp;HB{@E9*U@qyodY&27@s~*h}c8x1RT8>Z11GCZ>U4x<={tPbicU zdfr3Nz4WpmR-i1buqg}0Ad{v9l1rhcfz+_U>NjuR=!bVg^z_Zlo0&H=?>*Ttw#hko ze)Hn&`PqTP630u<;+y2g)7UWF1mroE%(S3VfX>q-d1{G1iSroKEJtROsU*1xf*XEQ zHXZliz~$+R8=Sp-c^0Tw!`OZJ$m$J)Ae^#)F9-t9vh0bDr(#w=s8lMG^;pSkR^y|O zKl<>Se?PCrOXa&}Q1L5yxf1 z$nyTPIF3*E>-D|3kQMNslAjK%2mlh!9%8SK>JTa&3Mj}#UyPZ%5l8D)s z7cV9ayB^1$&gbvHx~A3n`i;(CqvJZ=(Rp~d&t{O9ygk6y0Mu$(syrCXGRPD?7sb-4 zmU)(if(wvQ^cB{*78#8)qr78QtXk{w;EAuq)JwrUzLkD58_vj7q{If~r80~Ubpn&n zw0fmd+JESmj(dJ_SJvxouKeX)PVTrN7-1Mq*j^IQ+OTS!2FOSGeg+ONPRgmij$Fcr z5%mfSY>#3?`YcoX2N#iM)m9><#QMD<769ks-)`SSvQ+$fiD=&=6on&XuM(QH^x>qp3Sr(MZ6VI&-99?vJK)g*e~<)yu0^EjA4V-^y# zyvx-WT)RE+eOW)s1MTy9e4Lu-4QK0AZns-4XGI~W^8Qfimy`+EpT)OV$O_AmN1af{ zrfKLUMQRH{Ka3XZzoq_NNq=@CTqD1!Jy zEH4<_96Ugcm)DUS4J`OBIKbQ*cAoa+7|f2uum_LcuU#_@&usedI`i{<62`8jNmeh#~?I?r7CN+93X z-X5KA8Ey^i70!%|zCwK2dWBtF5BzC+X*}AW4BPdR{2}rJiG5+N zwrF>YL{H|av2+qe(S^RhabCQNUIoEy!PjB)Ho$Hqk~t;s+68^WxVgfS)*ASK(&fQ) zx>|tr<`Mi6N4#f`!b8@OS5 z_(qoRX>boQ|Ae*ie6TZ}{c$~g@*Q(*d>woA1H;xDbQLJlSbr{O9iV?+==0Q|Pis2$ z1mhhmHd9=!*QIK?F}HrKEWySScZPv8GP{xS>8DqkDHOC7JDXj4K)+xXpN${0{_^e` Yw|O>q5?QS;Wcw>N{q_W9D!I4+0f^i8+yDRo literal 0 HcmV?d00001 diff --git a/source/ilo.go b/source/ilo.go new file mode 100644 index 0000000..d0781fb --- /dev/null +++ b/source/ilo.go @@ -0,0 +1,193 @@ +// ilo.go, (c) charles childers + +package main + +import ( + "encoding/binary" + "fmt" + "os" +) + +var d [33]int32 +var a [257]int32 +var m [65536]int32 +var sp = 0 +var rp = 0 +var ip = 0 + +func pop() int32 { sp--; return d[sp + 1] } +func push(x int32) { sp++; d[sp] = x } + +func prepare_vm() { ip = 0; sp = 0; rp = 0; } + +func load_image() { + f, err := os.OpenFile("ilo.rom", os.O_RDONLY, 0) + if err != nil { + return + } + defer f.Close() + buf := make([]byte, 4) + var i int = 0 + for i < 65536 { + f.Read(buf) + m[i] = int32(binary.LittleEndian.Uint32(buf[:4])) + i++ + } + prepare_vm() +} + +func save_image() { +} + +func read_block() { + var buffer = pop() + var block = pop() + var blocks = "ilo.blocks" + if f, err := os.OpenFile(blocks, os.O_RDWR, 0666); err == nil { + f.Seek(int64(block * 4096), 0) + buf := make([]byte, 4) + var i int = 0 + for i < 1024 { + f.Read(buf) + m[int(buffer) + i] = int32(binary.LittleEndian.Uint32(buf[:4])) + i++ + } + f.Close() + } +} + +func write_block() { + var buffer = pop() + var block = pop() + var blocks = "ilo.blocks" + if f, err := os.OpenFile(blocks, os.O_RDWR, 0666); err == nil { + f.Seek(int64(block * 4096), 0) + var buf = m[buffer:buffer+1024] + binary.Write(f, binary.LittleEndian, buf) + f.Close() + } +} + +func no() { } +func li() { ip++; push(m[ip]) } +func du() { push(d[sp]) } +func dr() { sp-- } +func sw() { var y = pop(); var x = pop(); push(y); push(x); } +func pu() { rp++; a[rp] = pop() } +func po() { push(a[rp]); rp-- } +func ju() { ip = int(pop() - 1) } +func ca() { rp++; a[rp] = int32(ip); ju() } +func cc() { sw(); if (pop() != 0) { ca() } else { dr() } } +func cj() { sw(); if (pop() != 0) { ju() } else { dr() } } +func re() { ip = int(a[rp]); rp-- } +func eq() { var y = pop(); var x = pop(); if (x == y) { push(-1) } else { push(0) } } +func ne() { var y = pop(); var x = pop(); if (x != y) { push(-1) } else { push(0) } } +func lt() { var y = pop(); var x = pop(); if (x < y) { push(-1) } else { push(0) } } +func gt() { var y = pop(); var x = pop(); if (x > y) { push(-1) } else { push(0) } } +func fe() { var t = pop(); push(m[t]) } +func st() { var t = pop(); m[t] = pop() } +func ad() { var y = pop(); var x = pop(); push(x + y) } +func su() { var y = pop(); var x = pop(); push(x - y) } +func mu() { var y = pop(); var x = pop(); push(x * y) } +func di() { var y = pop(); var x = pop(); push(x % y); push(x / y) } +func an() { var y = pop(); var x = pop(); push(x & y) } +func or() { var y = pop(); var x = pop(); push(x | y) } +func xo() { var y = pop(); var x = pop(); push(x ^ y) } +func sl() { var y = pop(); var x = pop(); push(x << y) } +func sr() { var y = pop(); var x = pop(); push(x >> y) } +func cp() { + var len = pop() + var dest = pop() + var src = pop() + push(-1) + for len > 0 { + if m[dest] != m[src] { d[sp] = 0 } + len--; src++; dest++ + } +} +func cy() { + var len = pop() + var dest = pop() + var src = pop() + for len > 0 { + m[dest] = m[src] + len--; src++; dest++ + } +} +func iowr() { fmt.Printf("%c", pop()) } +func iord() { + var b []byte = make([]byte, 1) + os.Stdin.Read(b) + var c int = int(b[0]) + push(int32(c)) +} +func iorb() { read_block() } +func iowb() { write_block() } +func iosi() { save_image() } +func ioli() { load_image(); ip = -1 } +func ioen() { ip = 65536 } +func iost() { push(int32(sp)); push(int32(rp)) } +func io() { + var o = pop() + if o == 0 { iowr() } + if o == 1 { iord() } + if o == 2 { iorb() } + if o == 3 { iowb() } + if o == 4 { iosi() } + if o == 5 { ioli() } + if o == 6 { ioen() } + if o == 7 { iost() } +} + +func process(o int32) { + if o == 0 { no() } + if o == 1 { li() } + if o == 2 { du() } + if o == 3 { dr() } + if o == 4 { sw() } + if o == 5 { pu() } + if o == 6 { po() } + if o == 7 { ju() } + if o == 8 { ca() } + if o == 9 { cc() } + if o == 10 { cj() } + if o == 11 { re() } + if o == 12 { eq() } + if o == 13 { ne() } + if o == 14 { lt() } + if o == 15 { gt() } + if o == 16 { fe() } + if o == 17 { st() } + if o == 18 { ad() } + if o == 19 { su() } + if o == 20 { mu() } + if o == 21 { di() } + if o == 22 { an() } + if o == 23 { or() } + if o == 24 { xo() } + if o == 25 { sl() } + if o == 26 { sr() } + if o == 27 { cp() } + if o == 28 { cy() } + if o == 29 { io() } +} + +func process_bundle(o int32) { + process(o & 0xFF) + process((o >> 8) & 0xFF) + process((o >> 16) & 0xFF) + process((o >> 24) & 0xFF) +} + +func execute() { + for ip < 65536 { + process_bundle(m[ip]) + ip++ + } +} + + +func main() { + load_image() + execute() +} diff --git a/source/ilo.ha b/source/ilo.ha new file mode 100644 index 0000000..e6fe36d --- /dev/null +++ b/source/ilo.ha @@ -0,0 +1,239 @@ +// ilo.ha, an ilo in hare + +use bufio; +use fmt; +use fs; +use io; +use math; +use os; + +let ds: [33]i32 = [0...]; +let rs: [257]i32 = [0...]; +let m: [65536]i32 = [0...]; +let sp: i32 = 0; +let rp: i32 = 0; +let ip: i32 = 0; +let a: i32 = 0; +let b: i32 = 0; +let c: i32 = 0; + +fn initialize() void = { + sp = 0; + rp = 0; + ip = 0; + load(); +}; + +fn load() void = { + const input = match (os::open("ilo.rom")) { + case let file: io::file => + yield file; + case let err: fs::error => + fmt::fatalf("Error opening {}: {}", + os::args[1], fs::strerror(err)); + }; + defer io::close(input)!; + let rdbuf: [os::BUFSZ]u8 = [0...]; + let input = &bufio::init(input, rdbuf, []); + let i = 0; + let buf: [4]u8 = [0, 0, 0, 0]; + for (!(io::read(input, buf)! is io::EOF)) { + let x: u32 = m[i]:u32; + x = x + (buf[3]:u32 << 24); + x = x + (buf[2]:u32 << 16); + x = x + (buf[1]:u32 << 8); + x = x + (buf[0]:u32 << 0); + m[i] = x:i32; + i = i + 1; + }; +}; + +fn read_block(block:i32, buffer:i32) void = { + const block_store = match (os::open("ilo.blocks")) { + case let file: io::file => + yield file; + case let err: fs::error => + fmt::fatalf("Error opening {}: {}", + "ilo.blocks", fs::strerror(err)); + }; + defer io::close(block_store)!; + + let rdbuf: [os::BUFSZ]u8 = [0...]; + let block_store = &bufio::init(block_store, rdbuf, []); + + let i: i32 = 0; + let buf: [4096]u8 = [0...]; + + // this is not an optimal way, need to figure out + // io::seek + // io::seek(block_store, block * 4096, io::whence::SET)!; + let za:i32 = 0; + for (za < block) { + io::read(block_store, buf)!; + za = za + 1; + }; + + let cell: [4]u8 = [0...]; + + // read in the block + for (i < 1024) { + io::read(block_store, cell)!; + let x: u32 = 0; + x = x + (cell[3]:u32 << 24); + x = x + (cell[2]:u32 << 16); + x = x + (cell[1]:u32 << 8); + x = x + (cell[0]:u32 << 0); + let t:i32 = buffer + i; + m[t] = x:i32; + i = i + 1; + }; +}; + +fn write_block(block:i32, buffer:i32) void = { + const block_store = match (os::open("ilo.blocks", fs::flag::RDWR)) { + case let file: io::file => + yield file; + case let err: fs::error => + fmt::fatalf("Error opening {}: {}", + "ilo.blocks", fs::strerror(err)); + }; + defer io::close(block_store)!; + + let rdbuf: [os::BUFSZ]u8 = [0...]; + let wrbuf: [os::BUFSZ]u8 = [0...]; + let block_store = &bufio::init(block_store, rdbuf, wrbuf); + + let i: i32 = 0; + let buf: [4096]u8 = [0...]; + + let za:i32 = 0; + for (za < block) { + io::read(block_store, buf)!; + za = za + 1; + }; + + let cell: [4]u8 = [0...]; + + // read in the block + for (i < 1024) { + let t:i32 = buffer + i; + let x: u32 = m[t]:u32; + cell[3] = ((x >> 24) & 0xFF):u8; + cell[2] = ((x >> 16) & 0xFF):u8; + cell[1] = ((x >> 8) & 0xFF):u8; + cell[0] = ((x >> 0) & 0xFF):u8; + io::write(block_store, cell)!; + i = i + 1; + }; + io::close(block_store)!; +}; + +fn push(v: i32) void = { sp = sp + 1; ds[sp] = v; }; +fn pop() i32 = { sp = sp - 1; return ds[sp + 1]; }; +fn save_ip() void = { rp = rp + 1; rs[rp] = ip; }; + +fn no() void = { return; }; +fn li() void = { ip = ip + 1; push(m[ip]); }; +fn du() void = { push(ds[sp]); }; +fn dr() void = { pop(); }; +fn sw() void = { a = pop(); b = pop(); push(a); push(b); }; +fn pu() void = { rp = rp + 1; rs[rp] = pop(); }; +fn po() void = { push(rs[rp]); rp = rp - 1; }; +fn ju() void = { ip = pop() - 1; }; +fn ca() void = { save_ip(); ip = pop() - 1; }; +fn cc() void = { a = pop(); if (pop() != 0) { save_ip(); ip = a - 1; }; }; +fn cj() void = { a = pop(); if (pop() != 0) { ip = a - 1; }; }; +fn re() void = { ip = rs[rp]; rp = rp - 1; }; +fn eq() void = { a = pop(); b = pop(); + if (a == b) { push(-1); } else { push(0); }; }; +fn ne() void = { a = pop(); b = pop(); + if (a != b) { push(-1); } else { push(0); }; }; +fn lt() void = { a = pop(); b = pop(); + if (b < a) { push(-1); } else { push(0); }; }; +fn gt() void = { a = pop(); b = pop(); + if (b > a) { push(-1); } else { push(0); }; }; +fn fe() void = { ds[sp] = m[ds[sp]]; }; +fn st() void = { m[ds[sp]] = ds[sp - 1]; sp = sp - 2; }; +fn ad() void = { ds[sp - 1] = ds[sp - 1] + ds[sp]; pop(); }; +fn su() void = { ds[sp - 1] = ds[sp - 1] - ds[sp]; pop(); }; +fn mu() void = { ds[sp - 1] = ds[sp - 1] * ds[sp]; pop(); }; +fn di() void = { a = ds[sp]; b = ds[sp - 1]; + ds[sp] = b / a; ds[sp - 1] = b % a; }; +fn an() void = { ds[sp - 1] = ds[sp - 1] & ds[sp]; pop(); }; +fn or() void = { ds[sp - 1] = ds[sp - 1] | ds[sp]; pop(); }; +fn xo() void = { ds[sp - 1] = ds[sp - 1] ^ ds[sp]; pop(); }; +fn sl() void = { ds[sp - 1] = ds[sp - 1] << ds[sp]; pop(); }; +fn sr() void = { ds[sp - 1] = ds[sp - 1] >> ds[sp]; pop(); }; +fn cp() void = { + a = pop(); b = pop(); c = pop(); push(-1); + for (a > 0; a = a - 1) { + if (m[b] != m[c]) { ds[sp] = 0; }; + b = b + 1; + c = c + 1; + }; +}; +fn cy() void = { + a = pop(); b = pop(); c = pop(); + for (a > 0; a = a - 1) { + m[b] = m[c]; + b = b + 1; + c = c + 1; + }; +}; +fn io() void = { + switch (pop()) { + case => return; + case 0 => fmt::printf("{}", pop():rune)!; return; + case 1 => let buf: [1]u8 = [0]; + io::read(os::stdin, buf)!; + let z:i32 = buf[0]:i32; + push(z); return; + case 2 => let buf = pop(); let blk = pop(); + read_block(blk, buf); + return; + case 3 => let buf = pop(); let blk = pop(); + write_block(blk, buf); + return; + case 4 => return; + case 5 => initialize(); ip = -1; return; + case 6 => fmt::fatal("BYE!"); + case 7 => push(sp); push(rp); return; + }; +}; + +fn process(o: i32) void = { + switch (o) { + case => return; + case 0 => return; case 1 => return li(); + case 2 => return du(); case 3 => return dr(); + case 4 => return sw(); case 5 => return pu(); + case 6 => return po(); case 7 => return ju(); + case 8 => return ca(); case 9 => return cc(); + case 10 => return cj(); case 11 => return re(); + case 12 => return eq(); case 13 => return ne(); + case 14 => return lt(); case 15 => return gt(); + case 16 => return fe(); case 17 => return st(); + case 18 => return ad(); case 19 => return su(); + case 20 => return mu(); case 21 => return di(); + case 22 => return an(); case 23 => return or(); + case 24 => return xo(); case 25 => return sl(); + case 26 => return sr(); case 27 => return cp(); + case 28 => return cy(); case 29 => return io(); + }; +}; + +fn execute() void = { + for (ip < 65536) { + let opcode = m[ip]; + process(opcode & 0xFF); + process((opcode >> 8) & 0xFF); + process((opcode >> 16) & 0xFF); + process((opcode >> 24) & 0xFF); + ip = ip + 1; + }; +}; + +export fn main() void = { + initialize(); + execute(); +}; diff --git a/source/ilo.kt b/source/ilo.kt new file mode 100644 index 0000000..bbf0cd0 --- /dev/null +++ b/source/ilo.kt @@ -0,0 +1,280 @@ +// ------------------------------------------------------------- +// ilo.kt, (c) charles childers +// +// build: +// +// kotlinc ilo.kt -include-runtime -d ilo.jar +// +// run: +// +// kotlin ilo.jar +// ------------------------------------------------------------- + +import java.io.File + +var blocks = IntArray(1024*1024*4) +var input = "" +var ip = 0 +var m = IntArray(65536) +var d = Stack() +var a = Stack() + +fun ino() {} +fun ili() { ip++; d.push(m[ip]) } +fun idu() { d.push(d.tos()) } +fun idr() { d.pop() } +fun isw() { var x = d.pop(); var y = d.pop(); d.push(x); d.push(y) } +fun ipu() { a.push(d.pop()) } +fun ipo() { d.push(a.pop()) } +fun iju() { ip = d.pop() - 1 } +fun ica() { a.push(ip); iju() } +fun icc() { val t = d.pop(); if (d.pop() != 0) { a.push(ip); ip = t - 1 } } +fun icj() { val t = d.pop(); if (d.pop() != 0) { ip = t - 1 } } +fun ire() { ip = a.pop() } +fun ieq() { val x = d.pop(); val y = d.pop(); if (y == x) { d.push(-1) } else { d.push(0) } } +fun ine() { val x = d.pop(); val y = d.pop(); if (y != x) { d.push(-1) } else { d.push(0) } } +fun ilt() { val x = d.pop(); val y = d.pop(); if (y < x) { d.push(-1) } else { d.push(0) } } +fun igt() { val x = d.pop(); val y = d.pop(); if (y > x) { d.push(-1) } else { d.push(0) } } +fun ife() { val t = d.pop(); d.push(m[t]) } +fun ist() { val t = d.pop(); m[t] = d.pop() } +fun iad() { val x = d.pop(); val y = d.pop(); d.push(y + x) } +fun isu() { val x = d.pop(); val y = d.pop(); d.push(y - x) } +fun imu() { val x = d.pop(); val y = d.pop(); d.push(y * x) } +fun idi() { val x = d.pop(); val y = d.pop(); d.push(y % x); d.push(y / x) } +fun ian() { val x = d.pop(); val y = d.pop(); d.push(y and x) } +fun ior() { val x = d.pop(); val y = d.pop(); d.push(y or x) } +fun ixo() { val x = d.pop(); val y = d.pop(); d.push(y xor x) } +fun isl() { val x = d.pop(); val y = d.pop(); d.push(y shl x) } +fun isr() { val x = d.pop(); val y = d.pop(); d.push(y shr x) } +fun icp() { + var l = d.pop() + var t = d.pop() + var s = d.pop() + d.push(-1) + while (l > 0) { + if (m[t] != m[s]) { d.pop(); d.push(0) } + t++; s++; l-- + } +} +fun icy() { + var l = d.pop() + var t = d.pop() + var s = d.pop() + while (l > 0) { + m[t] = m[s] + t++; s++; l-- + } +} +fun iio() { + when (d.pop()) { + 0 -> io_co() + 1 -> io_ci() + 2 -> io_rb() + 3 -> io_wb() + 4 -> io_si() + 5 -> io_pc() + 6 -> io_of() + 7 -> io_sd() + } +} + +fun io_co() { print(d.pop().toChar()) } +fun io_ci() { + if (input.length > 0) { + val c = input.first() + val v = c.code + d.push(v) + input = input.drop(1) + } else { + d.push(32) + } +} +fun io_rb() { read_block() } +fun io_wb() { write_block() } +fun io_si() { } +fun io_pc() { boot(); ip = -1 } +fun io_of() { ip = 65536 } +fun io_sd() { d.push(d.depth()); d.push(a.depth()) } + +// ------------------------------------------------------------- +// ------------------------------------------------------------- + +fun load_blocks() { + val bs = File("./ilo.blocks") + val bytes:ByteArray = bs.readBytes() + var i = 0 + var o = 0 + while (i < (1024*1024)) { + val x = (bytes[o++].toInt() and 0xff shl 24) or + (bytes[o++].toInt() and 0xff shl 16) or + (bytes[o++].toInt() and 0xff shl 8) or + (bytes[o++].toInt() and 0xff) + blocks[i] = fix(x.toLong()) + i++ + } +} + +fun read_block() { + load_blocks() + val buffer = d.pop() + val block = d.pop() + var i = 0 + while (i < 1024) { + m[buffer + i] = blocks[(block * 1024) + i] + i++ + } +} + +fun write_block() { + val buffer = d.pop() + val block = d.pop() + + // update `blocks` cache + var i = 0 + while (i < 1024) { + blocks[(block * 1024) + i] = m[buffer + i] + i++ + } + + // write `blocks` cache back to disk + val bs = File("./ilo.blocks") + var dump: ByteArray = ByteArray(1024*1024*4) + + i = 0 + var o = 0 + while (i < (1024*1024)) { + val cell = fix(blocks[i].toLong()) + dump[o++] = ((cell shr 24) and 0xFF).toByte() + dump[o++] = ((cell shr 16) and 0xFF).toByte() + dump[o++] = ((cell shr 8) and 0xFF).toByte() + dump[o++] = (cell and 0xFF).toByte() + i++ + } + bs.writeBytes(dump) +} + +fun process_instruction(op: Int) { + when (op) { + 0 -> ino() + 1 -> ili() + 2 -> idu() + 3 -> idr() + 4 -> isw() + 5 -> ipu() + 6 -> ipo() + 7 -> iju() + 8 -> ica() + 9 -> icc() + 10 -> icj() + 11 -> ire() + 12 -> ieq() + 13 -> ine() + 14 -> ilt() + 15 -> igt() + 16 -> ife() + 17 -> ist() + 18 -> iad() + 19 -> isu() + 20 -> imu() + 21 -> idi() + 22 -> ian() + 23 -> ior() + 24 -> ixo() + 25 -> isl() + 26 -> isr() + 27 -> icp() + 28 -> icy() + 29 -> iio() + else -> { + println("Invalid instruction!") + print("IP:") + print(ip) + print(" OC:") + println(op) + } + } +} + +fun process() { + while (input.length > 0 && ip < 65536) { + val cur = ip + process_instruction(m[cur] and 0xFF) + process_instruction((m[cur] shr 8) and 0xFF) + process_instruction((m[cur] shr 16) and 0xFF) + process_instruction((m[cur] shr 24) and 0xFF) + ip++ + } +} + +fun boot() { + load_image() + load_blocks() + ip = 0 + d.empty() + a.empty() + input = " " + process() +} + +fun load_image() { + val bs = File("./ilo.rom") + val bytes:ByteArray = bs.readBytes() + var i = 0 + var o = 0 + while (i < 65536) { + val x = (bytes[o++].toInt() and 0xff shl 24) or + (bytes[o++].toInt() and 0xff shl 16) or + (bytes[o++].toInt() and 0xff shl 8) or + (bytes[o++].toInt() and 0xff) + m[i] = fix(x.toLong()) + i++ + } +} + +// The JVM is a big endian system. ilo stores data & rom in +// little endian. This routine converts the data between these +// when necessary. + +fun fix(v: Long): Int { + return (((v and 0x000000FF) shl 24) or + ((v and 0x0000FF00) shl 8) or + ((v and 0x00FF0000) shr 8) or + ((v and 0xFF000000) shr 24)).toInt() +} + +fun main(args: Array) { + boot() + while (ip < 65536) { + input = readln() + input = " " + input + " \n" + process() + } +} + + +class Stack { + var sp = 0 + var data = IntArray(256) + + fun push(v: Int) { + sp++ + data[sp] = v + } + + fun pop(): Int { + sp-- + return data[sp + 1] + } + + fun tos(): Int { + return data[sp] + } + + fun empty() { + sp = 0 + } + + fun depth(): Int { + return sp + } +} diff --git a/source/ilo.lua b/source/ilo.lua new file mode 100644 index 0000000..8d21f83 --- /dev/null +++ b/source/ilo.lua @@ -0,0 +1,343 @@ +-- ilo.lua +-- Partially derived from Ngaro in Lua +-- Copyright (c) 2010 - 2023, Charles Childers +-- +-- This is only tested on Lua 5.4 and requires 32-bit +-- integers. (set `#define LUA_32BITS 1` in luaconf.h when +-- building Lua) + +-- Variables +local ip = 0 -- instruction pointer +local sp = 0 -- stack pointer +local rp = 0 -- return pointer +local stack = {} -- data stack +local address = {} -- return stack +local memory = {} -- simulated ram + +-- Support Code +local function file_size(filename) + local fh = assert(io.open(filename, 'rb')) + local len = assert(fh:seek('end')) + fh:close() + return len +end + +local function constrain(n) + return (n > 0x7FFFFFFF) and (n - 0x100000000) or n +end + +local function save_image() + local image = io.open('ilo.rom', 'wb') + local i = 0 + while i < 65536 do + image:write(string.pack(' stack[sp] then + stack[sp - 1] = -1 + else + stack[sp - 1] = 0 + end + sp = sp - 1 + end, + [16] = function() -- fe (fetch) + stack[sp] = memory[stack[sp]] + end, + [17] = function() -- st (store) + memory[stack[sp]] = stack[sp - 1] + sp = sp - 2 + end, + [18] = function() -- ad (add) + stack[sp - 1] = stack[sp - 1] + stack[sp] + sp = sp - 1 + end, + [19] = function() -- su (subtract) + stack[sp - 1] = stack[sp - 1] - stack[sp] + sp = sp - 1 + end, + [20] = function() -- mu (multiply) + stack[sp - 1] = stack[sp - 1] * stack[sp] + sp = sp - 1 + end, + [21] = function() -- di (divide & remainder) + local b = stack[sp] + local a = stack[sp - 1] + local x = math.abs(b) + local y = math.abs(a) + local q = constrain(y // x) + local r = constrain(y % x) + if a < 0 and b < 0 then + r = r * -1 + elseif a > 0 and b < 0 then + q = q * -1 + elseif a < 0 and b > 0 then + r = r * -1 + q = q * -1 + end + stack[sp] = q + stack[sp - 1] = r + end, + [22] = function() -- an (and) + stack[sp - 1] = stack[sp - 1] & stack[sp] + sp = sp - 1 + end, + [23] = function() -- or (or) + stack[sp - 1] = stack[sp - 1] | stack[sp] + sp = sp - 1 + end, + [24] = function() -- xo (xor) + stack[sp - 1] = stack[sp - 1] ~ stack[sp] + sp = sp - 1 + end, + [25] = function() -- sl (shift left) + stack[sp - 1] = stack[sp - 1] << stack[sp] + sp = sp - 1 + end, + [26] = function() -- sr (shift right) + stack[sp - 1] = stack[sp - 1] >> stack[sp] + sp = sp - 1 + end, + [27] = function() -- cp (compare) + local a = stack[sp] -- length + local b = stack[sp - 1] -- dest + local c = stack[sp - 2] -- source + local d = -1 -- flag + sp = sp - 3 + while a > 0 do + if memory[b] ~= memory[c] then + d = 0 + end + a = a - 1 + b = b + 1 + c = c + 1 + end + sp = sp + 1 + stack[sp] = d + end, + [28] = function() -- cy (copy) + local a = stack[sp] -- length + local b = stack[sp - 1] -- dest + local c = stack[sp - 2] -- source + sp = sp - 3 + while a > 0 do + memory[b] = memory[c] + a = a - 1 + b = b + 1 + c = c + 1 + end + end, + [29] = function() -- io + local d = stack[sp] + sp = sp - 1 + if d == 0 then + io.write(string.char(stack[sp])) + sp = sp - 1 + elseif d == 1 then + sp = sp + 1 + stack[sp] = string.byte(io.read(1)) + elseif d == 2 then + read_block() + elseif d == 3 then + write_block() + elseif d == 4 then + save_image() + elseif d == 5 then + load_image("ilo.rom") + ip = -1 + sp = 0 + rp = 0 + elseif d == 6 then + ip = 65536 + elseif d == 7 then + sp = sp + 1 + stack[sp] = sp - 1 + sp = sp + 1 + stack[sp] = rp + end + end +} + +-- ------------------------------------------------------------- +-- process opcodes +local function process_opcode(opcode) + if opcode == 0 then return end -- skip NOP instructions + local op_fn = opcodes[opcode] + if op_fn then op_fn() end +end + +local function process_opcodes() + local opcode = memory[ip] + process_opcode(opcode & 0xFF) + process_opcode(opcode>>8 & 0xFF) + process_opcode(opcode>>16 & 0xFF) + process_opcode(opcode>>24 & 0xFF) +end + +-- Load image into memory +-- \ cells = size of image file (in cells) +-- \ image = pointer to retroImage file +local function load_image(file) + local cells = file_size(file) / 4 + local image = io.open(file, 'rb') + local i = 0 + while i < cells do + memory[i] = string.unpack(' 0 do + print(stack[sp]) + sp = sp - 1 + end +end + +local function process_instructions() + while ip < 65536 do + process_opcodes() + ip = ip + 1 + end +end + +local function main() + load_image("ilo.rom") + process_instructions() + dump_stack() +end + +main() diff --git a/source/ilo.nim b/source/ilo.nim new file mode 100644 index 0000000..abe775f --- /dev/null +++ b/source/ilo.nim @@ -0,0 +1,241 @@ +# ************************************************************** +# crc's _ _ +# (_) | ___ +# | | |/ _ \ a tiny virtual computer +# | | | (_) | 64kw RAM, 32-bit, Dual Stack, MISC +# |_|_|\___/ ilo.nim (c) charles childers +# ************************************************************** + +# nim c -r vm/ilo.nim + +{.push overflowChecks: off.} + +var + ip, sp, rp: int32 + s: array[33, int32] + r: array[257, int32] + m: array[65536, int32] + +let + rom = "ilo.rom" + blocks = "ilo.blocks" + +proc load_image() = + let f = open(rom) + defer: f.close() + discard f.readBuffer(addr m[0], sizeof(m)) + +proc read_block() = + let f = open(blocks) + let buf = s[sp] + let blk = s[sp - 1] + sp = sp - 2 + defer: f.close() + f.setFilePos(blk * 4096) + discard f.readBuffer(addr m[buf], 4096) + +proc write_block() = + let f = open(blocks, fmReadWriteExisting) + let buf = s[sp] + let blk = s[sp - 1] + sp = sp - 2 + defer: f.close() + f.setFilePos(blk * 4096) + discard f.writeBuffer(addr m[buf], 4096) + +proc save_image() = + return + +proc opcode(o: int32) = + case o: + of 0: # .. + return + of 1: # li + ip = ip + 1 + sp = sp + 1 + s[sp] = m[ip] + of 2: # du + sp = sp + 1 + s[sp] = s[sp - 1] + of 3: # dr + sp = sp - 1 + of 4: # sw + let a = s[sp] + let b = s[sp - 1] + s[sp] = b + s[sp - 1] = a + of 5: # pu + rp = rp + 1 + r[rp] = s[sp] + sp = sp - 1 + of 6: # po + sp = sp + 1 + s[sp] = r[rp] + rp = rp - 1 + of 7: # ju + ip = s[sp] - 1 + sp = sp - 1 + of 8: # ca + rp = rp + 1 + r[rp] = ip + ip = s[sp] - 1 + sp = sp - 1 + of 9: # cc + let target = s[sp] + let flag = s[sp - 1] + sp = sp - 2 + if flag != 0: + rp = rp + 1 + r[rp] = ip + ip = target - 1 + of 10: # cj + let target = s[sp] + let flag = s[sp - 1] + sp = sp - 2 + if flag != 0: + ip = target - 1 + of 11: # re + ip = r[rp] + rp = rp - 1 + of 12: # eq + let b = s[sp] + let a = s[sp - 1] + sp = sp - 1 + if a == b: + s[sp] = -1 + else: + s[sp] = 0 + of 13: # ne + let b = s[sp] + let a = s[sp - 1] + sp = sp - 1 + if a != b: + s[sp] = -1 + else: + s[sp] = 0 + of 14: # lt + let b = s[sp] + let a = s[sp - 1] + sp = sp - 1 + if a < b: + s[sp] = -1 + else: + s[sp] = 0 + of 15: # gt + let b = s[sp] + let a = s[sp - 1] + sp = sp - 1 + if a > b: + s[sp] = -1 + else: + s[sp] = 0 + of 16: # fe + s[sp] = m[s[sp]] + of 17: # st + m[s[sp]] = s[sp - 1] + sp = sp - 2 + of 18: # ad + s[sp - 1] = s[sp - 1] + s[sp] + sp = sp - 1 + of 19: # su + s[sp - 1] = s[sp - 1] - s[sp] + sp = sp - 1 + of 20: # mu + s[sp - 1] = s[sp - 1] * s[sp] + sp = sp - 1 + of 21: # di + let b = s[sp] + let a = s[sp - 1] + s[sp] = a div b + s[sp - 1] = a mod b + of 22: # an + s[sp - 1] = s[sp - 1] and s[sp] + sp = sp - 1 + of 23: # or + s[sp - 1] = s[sp - 1] or s[sp] + sp = sp - 1 + of 24: # xo + s[sp - 1] = s[sp - 1] xor s[sp] + sp = sp - 1 + of 25: # sl + s[sp - 1] = s[sp - 1] shl s[sp] + sp = sp - 1 + of 26: # sr + s[sp - 1] = s[sp - 1] shr s[sp] + sp = sp - 1 + of 27: # cp + var length: int32 = s[sp] + var dest: int32 = s[sp - 1] + var src: int32 = s[sp - 2] + var flag: int32 = -1 + sp = sp - 2 + while length != 0: + if m[dest] != m[src]: + flag = 0 + dest = dest + 1 + src = src + 1 + length = length - 1 + s[sp] = flag + of 28: # cy + var length: int32 = s[sp] + var dest: int32 = s[sp - 1] + var src: int32 = s[sp - 2] + sp = sp - 3 + while length != 0: + m[dest] = m[src] + dest = dest + 1 + src = src + 1 + length = length - 1 + of 29: # io + let dev = s[sp] + sp = sp - 1 + case dev: + of 0: + if s[sp] != 0: + stdout.write $(char(s[sp])) + sp = sp - 1 + of 1: + var buf: array[1, byte] + discard stdin.readBytes(buf, 0, 1) + sp = sp + 1 + s[sp] = int32(buf[0]) + of 2: + read_block() + of 3: + write_block() + of 4: + echo "save_image()" + of 5: + load_image() + ip = 0 + sp = 0 + rp = 0 + of 6: + ip = 65536 + of 7: + sp = sp + 1 + s[sp] = sp - 1 + sp = sp + 1 + s[sp] = rp + else: + echo "unsupported io:", dev + else: + echo "wtf?" + +proc process() = + while ip < 65536: + let a = m[ip] and 255 + let b = (m[ip] shr 8) and 255 + let c = (m[ip] shr 16) and 255 + let d = (m[ip] shr 24) and 255 + opcode(a) + opcode(b) + opcode(c) + opcode(d) + ip = ip + 1 + +ip = 0 +sp = 0 +rp = 0 +load_image() +process() diff --git a/source/ilo.py b/source/ilo.py new file mode 100644 index 0000000..bbcd155 --- /dev/null +++ b/source/ilo.py @@ -0,0 +1,515 @@ +# ************************************************************** +# crc's _ _ +# (_) | ___ +# | | |/ _ \ a tiny virtual computer +# | | | (_) | 64kw RAM, 32-bit, Dual Stack, MISC +# |_|_|\___/ ilo.py (c) charles childers +# (c) arland childers +# ************************************************************** + +#Ilo.py v2.2b + +#Changes: +# Split debug modes: +# 'instrs': Counts overall time, and counts each instruction/bundle. +# 'timing': Just gives elapsed time. +# 'cProfile': Using cProfile, measure time & time for all instructions+overhead. Does not count time for unoptimised bundles. +# Added more optimised instruction bundles, focusing on DTC. +# Optimised many instructions, removing uneeded vars. Added raw_lit to not limit it when it is not needed. +# Faster block unpacking. The uncached blocks seem to only be ~1.7x slower instead of ~2x, now. +# Sorted some of the instructions listing, in the hopes it may make an improvement. It did not seem to. +# Added calls to limit the rom and blocks as they get put into memory. + + +#--- CONFIG +BLOCK_FILE = 'ilo.blocks' +ROM_FILE = 'ilo.rom' +BLOCK_CACHE = True + +DEBUG = False +# False for nothing +# 'timing' just gives elapsed time. Negligible time loss +# 'Instrs' counts instructions & bundles, but ~2.3x slower +# 'cProfile' for cProfile, but ~3.25x slower + + +#--- ILO + +import os + +def limit(val): + val &= 0xffffffff + if val & 0x80000000: + val -= 0x100000000 + return val + +def div_mod(a, b): + x = abs(a) + y = abs(b) + q, r = divmod(x, y) + if a < 0 and b < 0: + r *= -1 + elif a > 0 and b < 0: + q *= -1 + elif a < 0 and b > 0: + r *= -1 + q *= -1 + return q, r + + +class Stack: + def __init__(self, size): + self.sp = 0 + self.data = [0] * size + self.max = size + + def lit(self, val): + self.sp += 1 + self.data[self.sp] = ((val & 0xffffffff)-0x100000000) if val & 0x80000000 else (val & 0xffffffff) + + def raw_lit(self, val): + self.sp += 1 + self.data[self.sp] = val + + def pop(self): + self.sp -= 1 + return self.data[self.sp + 1] + + def top(self): + return self.data[self.sp] + + def second(self): + return self.data[self.sp - 1] + + def depth(self): + return self.sp + + +class BlockTools_NoCache: + def __init__(self, block_file, rom_file, data_stack, memory): + self.BLOCK_FILE = block_file + self.ROM_FILE = rom_file + self.data_stack = data_stack + self.memory = memory + + def block_unpack(self, block): + return [(limit(block[i] | (block[i + 1] << 8) | (block[i + 2] << 16) | (block[i + 3] << 24))) for i in range(0, len(block), 4)] + + def block_pack(self, *values): + return b''.join(val.to_bytes(4, 'little', signed=True) for val in values) + + def read_block(self): + buffer = self.data_stack.pop() + block = self.data_stack.pop() + with open(self.BLOCK_FILE, 'r+b') as f: + f.seek(4096 * block) + self.memory[buffer: buffer + 1024] = list(self.block_unpack(f.read(4096))) + + def block_write(self): + buffer = self.data_stack.pop() + block = self.data_stack.pop() + with open(self.BLOCK_FILE, 'r+b') as f: + f.seek(4096 * block) + f.write(self.block_pack(*self.memory[buffer: buffer + 1024])) + + def load_image(self): + with open(self.ROM_FILE, 'rb') as f: + raw_data = f.read(4 * 65536) + self.memory[:] = [limit(int.from_bytes(raw_data[i:i + 4], 'little')) for i in range(0, len(raw_data), 4)] + + def save_image(self): + with open(self.ROM_FILE, 'wb') as f: + for value in self.memory[:65536]: + f.write(value.to_bytes(4, 'little')) + + + +class BlockTools(BlockTools_NoCache): # caches blocks. + def __init__(self, block_file, rom_file, data_stack, memory): + self.BLOCK_FILE = block_file + self.ROM_FILE = rom_file + self.data_stack = data_stack + self.memory = memory + self.block_time = os.path.getmtime(block_file) + self.blocks = [] + + def read_block(self): + if self.block_time != os.path.getmtime(self.BLOCK_FILE): + self.read_all_blocks() + self.block_time = os.path.getmtime(self.BLOCK_FILE) + buffer = self.data_stack.pop() + self.memory[buffer: buffer + 1024] = self.blocks[self.data_stack.pop()] + + def read_all_blocks(self): + with open(self.BLOCK_FILE, 'rb') as f: + all_block_data = f.read() + self.blocks = [list(self.block_unpack(all_block_data[i:i+4096])) for i in range(0, len(all_block_data), 4096)] + return self.blocks + + +class ilo: + def __init__(self, block_file='ilo.blocks', rom_file='ilo.rom', cache_blocks=False): + self.ip = 0 + self.memory = [0] + self.input_buffer = [] + self.data = Stack(33) + self.address = Stack(257) + if cache_blocks: + self.block_tools = BlockTools(block_file, rom_file, self.data, self.memory) + else: + self.block_tools = BlockTools_NoCache(block_file, rom_file, self.data, self.memory) + self.instructions = { + 1: self.i01, + 4: self.i04, + 11: self.i11, + 6: self.i06, + 2: self.i02, + 5: self.i05, + 18: self.i18, + 2049: self.i2049, + 2832: self.i2832, + 10: self.i10, + 68288770: self.i68288770, + 8: self.i08, + 17563906: self.i17563906, + 7: self.i07, + 524545: self.i524545, + 3: self.i03, + 459014: self.i459014, + 9: self.i09, + 12: self.i12, + 13: self.i13, + 14: self.i14, + 15: self.i15, + 16: self.i16, + 17: self.i17, + 19: self.i19, + 20: self.i20, + 21: self.i21, + 22: self.i22, + 23: self.i23, + 24: self.i24, + 25: self.i25, + 26: self.i26, + 27: self.i27, + 28: self.i28, + 29: self.i29, + 1793: self.i1793, + 459009: self.i459009, + 67502597: self.i67502597, + 100926722: self.i100926722, + 302059522: self.i302059522, + 2818: self.i2818, + 219156993: self.i219156993, + 33689603: self.i33689603, + 167840769: self.i167840769, + 525572: self.i525572, + 134284806: self.i134284806 + } + + def i00(self): # nop + pass + + def i01(self): # lit + self.ip += 1 + self.data.lit(self.memory[self.ip]) + + def i02(self): # dup + self.data.raw_lit(self.data.top()) + + def i03(self): # drop + self.data.pop() + + def i04(self): # swap + a = self.data.pop() + b = self.data.pop() + self.data.raw_lit(a) + self.data.raw_lit(b) + + def i05(self): # push + self.address.raw_lit(self.data.pop()) + + def i06(self): # pop + self.data.raw_lit(self.address.pop()) + + def i07(self): # jump + self.ip = self.data.pop() - 1 + + def i08(self): # call + self.address.raw_lit(self.ip) + self.ip = self.data.pop() - 1 + + def i09(self): # ccall + target = self.data.pop() + flag = self.data.pop() + if flag != 0: + self.address.raw_lit(self.ip) + self.ip = target - 1 + + def i10(self): # cjump + target = self.data.pop() + flag = self.data.pop() + if flag != 0: + self.ip = target - 1 + + def i11(self): # return + self.ip = self.address.pop() + + def i12(self): # equal + self.data.raw_lit(-(self.data.pop() == self.data.pop())) + + def i13(self): # not equal + self.data.raw_lit(-(self.data.pop() != self.data.pop())) + + def i14(self): # less than + b = self.data.pop() + a = self.data.pop() + self.data.raw_lit(-(a < b)) + + def i15(self): # greater than + b = self.data.pop() + a = self.data.pop() + self.data.raw_lit(-(a > b)) + + def i16(self): # fetch + self.data.raw_lit(self.memory[self.data.pop()]) + + def i17(self): # store + a = self.data.pop() + self.memory[a] = self.data.pop() + + def i18(self): # add + self.data.lit(self.data.pop() + self.data.pop()) + + def i19(self): # subtract + b = self.data.pop() + self.data.lit(self.data.pop() - b) + + def i20(self): # multiply + self.data.lit(self.data.pop() * self.data.pop()) + + def i21(self): # divmod + a = self.data.pop() + a, b = div_mod(self.data.pop(), a) + self.data.raw_lit(b) + self.data.raw_lit(a) + + def i22(self): # and + self.data.raw_lit(self.data.pop() & self.data.pop()) + + def i23(self): # or + self.data.raw_lit(self.data.pop() | self.data.pop()) + + def i24(self): # xor + self.data.raw_lit(self.data.pop() ^ self.data.pop()) + + def i25(self): # shift left + b = self.data.pop() + self.data.lit(self.data.pop() << b) + + def i26(self): # shift right + b = self.data.pop() + self.data.raw_lit(self.data.pop() >> b) + + def i27(self): # compare memory + l = self.data.pop() + dest = self.data.pop() + src = self.data.pop() + self.data.raw_lit(-(self.memory[dest: dest + l] == self.memory[src: src + l])) + + def i28(self): # copy memory + l = self.data.pop() + dest = self.data.pop() + src = self.data.pop() + self.memory[dest: dest + l] = self.memory[src: src + l] + + def i29(self): # io + i = self.data.pop() + if i == 0: + print(chr(self.data.pop()), end='') + elif i == 1: + if not len(self.input_buffer): + self.input_buffer = ['\n'] + list(input())[::-1] + self.data.lit(ord(self.input_buffer.pop())) + elif i == 2: + self.block_tools.read_block() + elif i == 3: + self.block_tools.block_write() + elif i == 4: + self.block_tools.save_image() + elif i == 5: + self.block_tools.load_image() + self.ip = -1 + elif i == 6: + self.ip = 65535 + elif i == 7: + self.data.lit(self.data.depth()) + self.data.lit(self.address.depth()) + + def i2049(self): # lica.... + self.address.lit(self.ip + 1) + self.ip = self.memory[self.ip + 1] - 1 + + def i1793(self): # liju.... + self.ip = self.memory[self.ip + 1] - 1 + + def i524545(self): # lilica.. + self.data.lit(self.memory[self.ip + 1]) + self.address.lit(self.ip + 2) + self.ip = self.memory[self.ip + 2] - 1 + + def i459009(self): # liliju.. + self.data.lit(self.memory[self.ip + 1]) + self.ip = self.memory[self.ip + 2] - 1 + + def i67502597(self): # puduposw 'over' + self.data.lit(self.data.second()) + + def i17563906(self): # dulieqli + self.data.lit(-(self.memory[self.ip + 1] == self.data.top())) + self.data.lit(self.memory[self.ip + 2]) + self.ip += 2 + + def i100926722(self): # dupuswpo 'tuck' + a = self.data.pop() + b = self.data.pop() + self.data.lit(a) + self.data.lit(b) + self.data.lit(a) + + def i302059522(self): # dufeliad + self.data.lit(self.memory[self.data.top()] + self.memory[self.ip + 1]) + self.ip += 1 + + def i2818(self): # dure.... + self.data.raw_lit(self.data.top()) + self.ip = self.address.pop() + + def i219156993(self): # liadfene + self.ip += 1 + self.data.lit(-(limit(self.memory[self.memory[self.ip] + self.data.pop()]) != self.data.pop())) + + def i33689603(self): # drfedudu + self.data.pop() + m = self.memory[self.data.pop()] + self.data.lit(m) + self.data.lit(m) + self.data.lit(m) + + def i167840769(self): # lieqlicj + self.ip += 2 + if -(self.memory[self.ip-1] == self.data.pop()) != 0: + self.ip = self.memory[self.ip] - 1 + + def i2832(self): # fere.... + self.data.raw_lit(self.memory[self.data.pop()]) + self.ip = self.address.pop() + + def i68288770(self): #duliadsw + self.data.raw_lit(self.data.top()) + self.ip += 1 + self.data.lit(limit(self.memory[self.ip]) + self.data.pop()) + a = self.data.pop() + b = self.data.pop() + self.data.raw_lit(a) + self.data.raw_lit(b) + + def i525572(self): # swpuca.. + a = self.data.pop() + self.address.raw_lit(self.data.pop()) + self.data.raw_lit(a) + self.address.raw_lit(self.ip) + self.ip = self.data.pop() - 1 + + def i459014(self): # poliju.. + self.data.raw_lit(self.address.pop()) + self.ip = self.memory[self.ip+1] - 1 + + def i134284806(self): # popolica + self.data.raw_lit(self.address.pop()) + self.data.raw_lit(self.address.pop()) + self.ip += 1 + self.address.lit(self.ip) + self.ip = self.memory[self.ip] - 1 + + def print_opcode_bundle(self, opcode): + print(opcode & 0xFF, end=' ') + print((opcode >> 8) & 0xFF, end=' ') + print((opcode >> 16) & 0xFF, end=' ') + print((opcode >> 24) & 0xFF, end=': ') + + def process(self, c): + if c in self.instructions: + self.instructions[c]() + + def execute(self, start): + self.ip = start + while self.ip < 65536: + m = self.memory[self.ip] + if m in self.instructions: + self.instructions[m]() + else: + self.process(m & 0xFF) + self.process((m >> 8) & 0xFF) + self.process((m >> 16) & 0xFF) + self.process((m >> 24) & 0xFF) + self.ip += 1 + + def debug_execute(self, start): + data = {} + self.ip = start + while self.ip < 65536: + m = self.memory[self.ip] + if m in self.instructions: + self.instructions[m]() + else: + self.process(m & 0xFF) + self.process((m >> 8) & 0xFF) + self.process((m >> 16) & 0xFF) + self.process((m >> 24) & 0xFF) + data[str(m & 0xFF)] = data.get(str(m & 0xFF), 0) + 1 + data[str((m >> 8) & 0xFF)] = data.get(str((m >> 8) & 0xFF), 0) + 1 + data[str((m >> 16) & 0xFF)] = data.get(str((m >> 16) & 0xFF), 0) + 1 + data[str((m >> 24) & 0xFF)] = data.get(str((m >> 24) & 0xFF), 0) + 1 + data[str(m)] = data.get(str(m), 0) + 1 + self.ip += 1 + return data + + def main(self, debug=False): + self.block_tools.load_image() + if BLOCK_CACHE: + self.block_tools.read_all_blocks() + if debug: + return self.debug_execute(0) + else: + self.execute(0) + +def sort_dict(input_dict): + sorted_items = sorted(input_dict.items(), key=lambda x: x[1], reverse=True) + sorted_dict = dict(sorted_items) + return sorted_dict + +if __name__ == '__main__': + if DEBUG: + if DEBUG.lower() == 'instrs': + import time + start_time = time.time() + k = ilo(BLOCK_FILE, ROM_FILE, BLOCK_CACHE) + data = k.main(True) + end_time = time.time() + print(str(sort_dict(data)).replace(',', '\n').strip('{}')) + print('\nElapsed Time: ', end_time - start_time) + elif DEBUG.lower() == 'timing': + import time + start_time = time.time() + ilo(BLOCK_FILE, ROM_FILE, BLOCK_CACHE).main() + end_time = time.time() + print('\nElapsed Time: ', end_time - start_time) + elif DEBUG.lower() == 'cprofile': + import cProfile + cProfile.run('ilo(BLOCK_FILE, ROM_FILE, BLOCK_CACHE).main()', sort='tottime') + else: + print('Unknown debug mode') + else: + ilo(BLOCK_FILE, ROM_FILE, BLOCK_CACHE).main() + diff --git a/source/ilo.retro b/source/ilo.retro new file mode 100644 index 0000000..57040d0 --- /dev/null +++ b/source/ilo.retro @@ -0,0 +1,181 @@ +This is an implementation of the ilo computer. It's written in +RetroForth. I wrote this mostly to satisfy a personal desire to +run Konilo under RetroForth. + +The ilo computer is quite similar to the nga computer that Retro +runs on. Both are dual stack minimal instruction set computers +with similar instruction sets. But ilo is, by design, a smaller, +simpler system. + +ilo presents the following: + +- 65,5536 cells of memory +- 32-bit cells are the only addressable memory unit +- data stack of 32 values +- address stack of 256 addresses +- keyboard input +- serial display +- block storage +- blocks are 1,024 cells in size +- 30 instructions + + +# Memory And Loading The ROM + +A standard ilo system will provide exactly 65,536 cells of RAM. +I create a label pointing to this and allocate the space. + +~~~ +'IMAGE d:create #65536 allot +~~~ + +On startup, ilo loads a ROM (typically named "ilo.rom") into +memory. This will always be a full memory image, so the size +will be 65,536 cells. Loading this takes advantage of Retro's +`block:` vocabulary, reading in the ROM as a series of 64 1K +blocks. Doing this is significantly faster than reading the +ROM in byte by byte and assembling the bytes into cells. + +~~~ +:load-image (s-) + block:set-file + #64 [ I IMAGE I #1024 * + block:read ] indexed-times ; + +'ilo.rom load-image +~~~ + +# Stacks & Registers + +I create labels and allocate space for the two stacks. And also +create registers for the stack pointers and instruction pointer. +Using these, I then implement several words for moving values +to and from these. The `>s` and `s>` operate on the data stack +whereas `>r` and `r>` operate on the address stack. + +It'd be faster to just use the RetroForth stacks directly, but +this is cleaner and less error prone. It also makes debugging +easier as the ilo stacks are now separate entities. + +The last thing I define here is `[IP]`, which returns the value +in memory at the instruction pointer. This is strictly for +readability and could be inlined in the two places it's used. + +~~~ +'DataStack d:create #33 allot +'ReturnStack d:create #257 allot + +'SP var +'RP var +'IP var + +:>s (n-) &DataStack @SP + store &SP v:inc ; +:s> (-n) &SP v:dec &DataStack @SP + fetch ; +:>r (n-) &ReturnStack @RP + store &RP v:inc ; +:r> (-n) &RP v:dec &ReturnStack @RP + fetch ; + +:[IP] IMAGE @IP + fetch ; +~~~ + +# A Utility Word + +RetroForth doesn't have a word to directly compare two blocks +of memory. Until I rectify this, I define one here. + +~~~ +:compare (sdl-f) + #-1 swap + [ [ dup-pair &fetch bi@ eq? ] dip and [ &n:inc bi@ ] dip ] + times &drop-pair dip ; +~~~ + +# The ilo Instructions + +Now I'm ready to implement the ilo instruction set. I chose to +follow my (very) similar approach from retro-extend(1) and the +Autopsy debugger. This creates one word per instruction and then +fills in a jump table of pointers. + +If you are familiar with Retro, it should be pretty easy to +follow these. Mostly just move values onto the RetroForth stack, +do an operation, then put results back. + +The longest one of these is the I/O instruction, which has 8 +possible actions. I implemented this using a `case` structure. + +~~~ +:i:no ; +:i:li &IP v:inc [IP] >s ; +:i:du s> dup >s >s ; +:i:dr s> drop ; +:i:sw s> s> swap >s >s ; +:i:pu s> >r ; +:i:po r> >s ; +:i:ju s> n:dec !IP ; +:i:ca @IP >r i:ju ; +:i:cc s> s> [ >s i:ca ] &drop choose ; +:i:cj s> s> [ >s i:ju ] &drop choose ; +:i:re r> !IP ; +:i:eq s> s> eq? >s ; +:i:ne s> s> -eq? >s ; +:i:lt s> s> swap lt? >s ; +:i:gt s> s> swap gt? >s ; +:i:fe s> IMAGE + fetch >s ; +:i:st s> s> swap IMAGE + store ; +:i:ad s> s> + >s ; +:i:su s> s> swap - >s ; +:i:mu s> s> * >s ; +:i:di s> s> swap /mod swap >s >s ; +:i:an s> s> and >s ; +:i:or s> s> or >s ; +:i:xo s> s> xor >s ; +:i:sl s> s> swap n:abs n:negate shift >s ; +:i:sr s> s> swap n:abs shift >s ; +:i:cp s> s> s> [ IMAGE + ] bi@ 'abc 'cba reorder compare >s ; +:i:cy s> s> s> [ IMAGE + ] bi@ 'abc 'cba reorder copy ; +:i:io s> + #0 [ s> c:put ] case + #1 [ c:get >s ] case + #2 [ s> s> swap IMAGE + block:read ] case + #3 [ s> s> swap IMAGE + block:write ] case + #4 [ dump-stack ] case + #5 [ #-1 !IP ] case + #6 [ #65536 !IP ] case + #7 [ @SP >s @RP >s ] case + drop ; + +'Instructions d:create + &i:no , &i:li , &i:du , &i:dr , &i:sw , &i:pu , + &i:po , &i:ju , &i:ca , &i:cc , &i:cj , &i:re , + &i:eq , &i:ne , &i:lt , &i:gt , &i:fe , &i:st , + &i:ad , &i:su , &i:mu , &i:di , &i:an , &i:or , + &i:xo , &i:sl , &i:sr , &i:cp , &i:cy , &i:io , +~~~ + +# Instruction Processor + +~~~ +{{ + :mask #255 and ; + :next #8 shift ; +---reveal--- + :unpack (n-dcba) + dup mask swap next + dup mask swap next + dup mask swap next + 'abcd 'dcba reorder ; +}} + +:process-opcodes (n-) + unpack + &Instructions + fetch call + &Instructions + fetch call + &Instructions + fetch call + &Instructions + fetch call ; + +:process (-) + [ [IP] process-opcodes &IP v:inc @IP #0 #65535 n:between? ] while ; + +'ilo.blocks block:set-file + +process +~~~ diff --git a/source/ilo.rs b/source/ilo.rs new file mode 100644 index 0000000..b78a2ea --- /dev/null +++ b/source/ilo.rs @@ -0,0 +1,368 @@ +// ilo.rs, (c) charles childers, (c) 2024 Matt Keeter + +use std::convert::TryInto; +use std::fs::{File, OpenOptions}; +use std::io; +use std::io::{Read, Seek, SeekFrom, Write}; + +struct Ilo { + /// memory + memory: [i32; 65536], + /// data stack + data: [i32; 33], + /// address stack + addr: [i32; 257], + /// data stack pointer + sp: usize, + /// address stack pointer + rp: usize, + /// instruction pointer + ip: usize, +} + +impl Default for Ilo { + fn default() -> Self { + Self { + memory: [0; 65536], + data: [0; 33], + addr: [0; 257], + sp: 0, + rp: 0, + ip: 0, + } + } +} + +impl Ilo { + fn load_image(&mut self) { + match std::fs::read("ilo.rom") { + Ok(image) => { + for (i, c) in image.chunks(4).enumerate() { + self.store(i32::from_le_bytes(c.try_into().unwrap()), i); + } + } + Err(e) => { + panic!("could not load 'ilo.rom': {}", e); + } + } + } + + fn read_block(&mut self, block: i32, buffer: i32) -> io::Result<()> { + let mut f = File::open("ilo.blocks")?; + let mut data = [0; 4096]; + f.seek(SeekFrom::Start(4096 * (block as u64)))?; + f.read_exact(&mut data)?; + for (i, c) in data.chunks(4).enumerate() { + let x = c[0] as i32; + self.store(x, (buffer as usize) + i); + } + Ok(()) + } + + fn write_block(&self, block: i32, buffer: i32) -> io::Result<()> { + let mut f = OpenOptions::new() + .read(true) + .write(true) + .open("ilo.blocks")?; + let mut data = [0; 4096]; + for x in 0..1024 { + let v = self.fetch((buffer as usize) + x); + data[(x * 4)..][..4].copy_from_slice(&v.to_le_bytes()); + } + f.seek(SeekFrom::Start(4096 * (block as u64)))?; + f.write_all(&data)?; + Ok(()) + } + + fn push(&mut self, x: i32) { + self.sp += 1; + self.data[self.sp] = x; + } + fn pop(&mut self) -> i32 { + self.sp -= 1; + self.data[self.sp + 1] + } + + fn fetch(&self, a: usize) -> i32 { + self.memory[a] + } + fn store(&mut self, v: i32, a: usize) { + self.memory[a] = v; + } + + fn reset(&mut self) { + self.ip = 0; + self.sp = 0; + self.rp = 0; + } + fn next(&mut self) { + self.ip += 1; + } + + fn li(&mut self) { + self.next(); + self.push(self.fetch(self.here())); + } + fn du(&mut self) { + self.push(self.data[self.sp]); + } + fn dr(&mut self) { + self.pop(); + } + fn sw(&mut self) { + let x = self.pop(); + let y = self.pop(); + self.push(x); + self.push(y); + } + fn pu(&mut self) { + self.rp += 1; + self.addr[self.rp] = self.pop(); + } + fn po(&mut self) { + self.push(self.addr[self.rp]); + self.rp -= 1; + } + fn ju(&mut self) { + self.ip = (self.pop() - 1) as usize; + } + fn ca(&mut self) { + self.rp += 1; + self.addr[self.rp] = (self.ip) as i32; + self.ip = (self.pop() - 1) as usize; + } + fn cc(&mut self) { + let t = self.pop(); + if self.pop() != 0 { + self.push(t); + self.ca(); + } + } + fn cj(&mut self) { + let t = self.pop(); + if self.pop() != 0 { + self.push(t); + self.ju(); + } + } + fn re(&mut self) { + self.ip = (self.addr[self.rp]) as usize; + self.rp -= 1; + } + fn eq(&mut self) { + let y = self.pop(); + let x = self.pop(); + self.push(if x == y { -1 } else { 0 }); + } + fn ne(&mut self) { + let y = self.pop(); + let x = self.pop(); + self.push(if x != y { -1 } else { 0 }); + } + fn lt(&mut self) { + let y = self.pop(); + let x = self.pop(); + self.push(if x < y { -1 } else { 0 }); + } + fn gt(&mut self) { + let y = self.pop(); + let x = self.pop(); + self.push(if x > y { -1 } else { 0 }); + } + fn fe(&mut self) { + let x = self.pop() as usize; + self.push(self.fetch(x)); + } + fn st(&mut self) { + let x = self.pop() as usize; + let v = self.pop(); + self.store(v, x); + } + fn ad(&mut self) { + let y = self.pop(); + let x = self.pop(); + self.push(x.wrapping_add(y)); + } + fn su(&mut self) { + let y = self.pop(); + let x = self.pop(); + self.push(x.wrapping_sub(y)); + } + fn mu(&mut self) { + let y = self.pop(); + let x = self.pop(); + self.push(x.wrapping_mul(y)); + } + fn di(&mut self) { + let y = self.pop(); + let x = self.pop(); + self.push(x.wrapping_rem(y)); + self.push(x.wrapping_div(y)); + } + fn an(&mut self) { + let y = self.pop(); + let x = self.pop(); + self.push(x & y); + } + fn or(&mut self) { + let y = self.pop(); + let x = self.pop(); + self.push(x | y); + } + fn xo(&mut self) { + let y = self.pop(); + let x = self.pop(); + self.push(x ^ y); + } + fn sl(&mut self) { + let y = self.pop(); + let x = self.pop(); + self.push(x.wrapping_shl(y.try_into().unwrap())); + } + fn sr(&mut self) { + let y = self.pop(); + let x = self.pop(); + self.push(x.wrapping_shr(y.try_into().unwrap())); + } + fn cp(&mut self) { + let len = self.pop() as usize; + let dest = self.pop() as usize; + let src = self.pop() as usize; + let slice1 = &self.memory[src..(src + len)]; + let slice2 = &self.memory[dest..(dest + len)]; + if slice1 == slice2 { + self.push(-1); + } else { + self.push(0); + } + } + fn cy(&mut self) { + let mut len = self.pop(); + let mut dest = self.pop() as usize; + let mut src = self.pop() as usize; + while len > 0 { + self.store(self.fetch(src), dest); + len -= 1; + src += 1; + dest += 1; + } + } + fn io(&mut self) { + let dev = self.pop(); + match dev { + 0 => { + let mut c = self.pop(); + if c == 0 { + c = 32; + } + let mut stdout = std::io::stdout().lock(); + stdout.write_all(&[c as u8]).unwrap(); + stdout.flush().unwrap(); + } + 1 => match std::io::stdin().lock().bytes().next().unwrap() { + Ok(127) => self.push(8), + Ok(val) => self.push(val as i32), + Err(_) => std::process::exit(1), + }, + 2 => { + let buffer = self.pop(); + let block = self.pop(); + if let Err(e) = self.read_block(block, buffer) { + panic!("could not read 'ilo.blocks': {}", e); + } + } + 3 => { + let buffer = self.pop(); + let block = self.pop(); + if let Err(e) = self.write_block(block, buffer) { + panic!("could not write 'ilo.blocks': {}", e); + } + } + 4 => {} + 5 => { + self.load_image(); + self.ip = 70000; + } + 6 => { + self.ip = 65536; + } + 7 => { + self.push(self.sp as i32); + self.push(self.rp as i32); + } + _ => (), + } + } + + fn process(&mut self, inst: u8) { + match inst { + 0 => (), // nop + 1 => self.li(), + 2 => self.du(), + 3 => self.dr(), + 4 => self.sw(), + 5 => self.pu(), + 6 => self.po(), + 7 => self.ju(), + 8 => self.ca(), + 9 => self.cc(), + 10 => self.cj(), + 11 => self.re(), + 12 => self.eq(), + 13 => self.ne(), + 14 => self.lt(), + 15 => self.gt(), + 16 => self.fe(), + 17 => self.st(), + 18 => self.ad(), + 19 => self.su(), + 20 => self.mu(), + 21 => self.di(), + 22 => self.an(), + 23 => self.or(), + 24 => self.xo(), + 25 => self.sl(), + 26 => self.sr(), + 27 => self.cp(), + 28 => self.cy(), + 29 => self.io(), + _ => (), + } + } + + fn not_done(&self) -> bool { + self.ip < 65536 + } + fn here(&self) -> usize { + self.ip + } + + fn execute(&mut self) { + self.reset(); + while self.not_done() { + let opcode = self.fetch(self.here()); + for op in opcode.to_le_bytes() { + self.process(op); + } + if self.here() == 70000 { + self.reset(); + } else { + self.next(); + } + } + } + + fn dump_stack(&mut self) { + while self.sp > 0 { + let x = self.pop(); + println!("{x}"); + } + } +} + +fn main() { + let mut ilo = Ilo::default(); + ilo.load_image(); + ilo.execute(); + ilo.dump_stack(); +} diff --git a/source/ilo.swift b/source/ilo.swift new file mode 100644 index 0000000..3fd75d3 --- /dev/null +++ b/source/ilo.swift @@ -0,0 +1,310 @@ +// ------------------------------------------------------------- +// ilo.swift, (c) charles childers +// ------------------------------------------------------------- +// compile with: +// +// swiftc -O vm/ilo.swift -o ilo +// ------------------------------------------------------------- + +import Foundation + + +// ------------------------------------------------------------- +// Configuration +// ------------------------------------------------------------- + +let imageSize: Int = 65536 +let stackSize: Int = 33 +let addressSize: Int = 257 + + +// ------------------------------------------------------------- +// Globals +// ------------------------------------------------------------- + +// +----------+------------------------------------------------+ +// | Name | Contains | +// +==========+================================================+ +// | input | input buffer ("keyboard") | +// | ip | instruction pointer | +// | memory | random access memory | +// | data | data stack | +// | address | address stack | +// +----------+------------------------------------------------+ + +var input: String = "" +var ip: Int = 0 +var memory = [Int32](repeating: 0, count: imageSize) +var data = Stack(stackSize) +var address = Stack(addressSize) + + +// ------------------------------------------------------------- +// Support Functions +// ------------------------------------------------------------- + +func getInt32FromData(data: NSData, offset: Int) -> Int32 { + let raw = NSRange(location: offset * 4, length: 4) + var i = [Int32](repeating: 0, count: 1) + data.getBytes(&i, range: raw) + return Int32(i[0]) +} + + +// ------------------------------------------------------------- +// Instructions +// ------------------------------------------------------------- + +func inst_no() { } +func inst_li() { ip += 1; data.push(memory[ip]) } +func inst_du() { data.push(data.tos()) } +func inst_dr() { data.drop() } +func inst_sw() { data.swap() } +func inst_pu() { address.push(data.pop()) } +func inst_po() { data.push(address.pop()) } +func inst_ju() { ip = Int(data.pop() - 1) } +func inst_ca() { address.push(Int32(ip)); ip = Int(data.pop() - 1) } +func inst_cc() { let dest = data.pop(); if (data.pop() != 0) { address.push(Int32(ip)); ip = Int(dest - 1) } } +func inst_cj() { let dest = data.pop(); if (data.pop() != 0) { ip = Int(dest - 1) } } +func inst_re() { ip = Int(address.pop()) } +func inst_eq() { let tos = data.pop(), nos = data.pop(); data.push((nos == tos) ? -1 : 0) } +func inst_ne() { let tos = data.pop(), nos = data.pop(); data.push((nos != tos) ? -1 : 0) } +func inst_lt() { let tos = data.pop(), nos = data.pop(); data.push((nos < tos) ? -1 : 0) } +func inst_gt() { let tos = data.pop(), nos = data.pop(); data.push((nos > tos) ? -1 : 0) } +func inst_fe() { let target = Int(data.pop()); data.push(memory[target]) } +func inst_st() { let addr = data.pop(), value = data.pop(); memory[Int(addr)] = value } +func inst_ad() { let tos = data.pop(), nos = data.pop(); data.push(nos &+ tos) } +func inst_su() { let tos = data.pop(), nos = data.pop(); data.push(nos &- tos) } +func inst_mu() { let tos = data.pop(), nos = data.pop(); data.push(nos &* tos) } +func inst_di() { let a = data.pop(), b = data.pop(); data.push(b % a); data.push(b / a) } +func inst_an() { let tos = data.pop(), nos = data.pop(); data.push(tos & nos) } +func inst_or() { let tos = data.pop(), nos = data.pop(); data.push(nos | tos) } +func inst_xo() { let tos = data.pop(), nos = data.pop(); data.push(nos ^ tos) } +func inst_sl() { let tos = data.pop(), nos = data.pop(); data.push(nos << tos) } +func inst_sr() { let tos = data.pop(), nos = data.pop(); data.push(nos >> tos) } +func inst_cp() { + var len = Int(data.pop()) + var dest = Int(data.pop()) + var src = Int(data.pop()) + while (len != 0) { + if (memory[dest] != memory[src]) { data.push(0); return } + len -= 1 + dest += 1 + src += 1 + } + data.push(-1) +} +func inst_cy() { + var len = Int(data.pop()) + var dest = Int(data.pop()) + var src = Int(data.pop()) + while (len != 0) { + memory[dest] = memory[src] + len -= 1 + dest += 1 + src += 1 + } +} +func inst_io() { + let device = Int(data.pop()) + let devices: [(()->Void)] = [ + io_cput, io_cget, io_rb, io_wb, + io_si, io_pc, io_of, io_sd] + if device < 0 || device > 7 { return } + devices[device]() +} + + +// ------------------------------------------------------------- +// I/O Operations +// ------------------------------------------------------------- + +// +----------+------------------------------------------------+ +// | Function | Action | +// +==========+================================================+ +// | io_cput | Display a character to standard output | +// | io_cget | Read character from standard input source | +// | io_rb | Read block from storage | +// | io_wb | Write block to storage | +// | io_si | Save image (not implemented) | +// | io_pc | Reset ilo to default state, restarting | +// | io_of | Power off (exit) ilo | +// | is_sd | Return stack depths | +// +----------+------------------------------------------------+ + +func io_cput() { + let v = UnicodeScalar(Int(data.pop())) ?? UnicodeScalar(32) + print(Character(v!), terminator: "") +} +func io_cget() { + if (input.count > 0) { + let c = input.first! + guard let v = c.asciiValue else { return } + data.push(Int32(v)) + input = String(input.dropFirst()) + } else { + data.push(32) + } +} +func io_rb() { + let buffer = data.pop(), block = data.pop() + load_block(Int(block), to: Int(buffer)) +} +func io_wb() { + let buffer = data.pop(), block = data.pop() + write_block(Int(block), to: Int(buffer)) +} +func io_si() { } +func io_pc() { + load_image() + data.empty() + address.empty() + ip = -1 +} +func io_of() { ip = 65536; exit(0) } +func io_sd() { + data.push(Int32(data.depth())) + data.push(Int32(address.depth())) +} + + +// ------------------------------------------------------------- +// Block I/O +// ------------------------------------------------------------- + +func blocks() -> URL { + return URL(fileURLWithPath: "./ilo.blocks") +} + +func load_block(_ block: Int, to: Int) { + let storage = blocks() + let fd = try! FileHandle(forReadingFrom: storage) + fd.seek(toFileOffset: UInt64(block * 4096)) + let data = fd.readData(ofLength: 4096) as NSData + for i in 0 ... 1023 { + memory[to + i] = getInt32FromData(data: data, offset: i) + } + fd.closeFile() +} + +func write_block(_ block: Int, to: Int) { + let storage = blocks() + let fd = try! FileHandle(forUpdating: storage) + fd.seek(toFileOffset: UInt64(block * 4096)) + for i in 0 ... 1023 { + let word = Data(bytes: &memory[to + i], count: 4) + fd.write(word) + } + fd.closeFile() +} + + +// ------------------------------------------------------------- +// Instruction Processing +// ------------------------------------------------------------- + +func process_instruction(opcode: Int32) { + let instructions: [(()->Void)] = [ + inst_no, inst_li, inst_du, inst_dr, inst_sw, + inst_pu, inst_po, inst_ju, inst_ca, inst_cc, + inst_cj, inst_re, inst_eq, inst_ne, inst_lt, + inst_gt, inst_fe, inst_st, inst_ad, inst_su, + inst_mu, inst_di, inst_an, inst_or, inst_xo, + inst_sl, inst_sr, inst_cp, inst_cy, inst_io] + // skip `no` and invalid opcodes + if opcode < 1 || opcode > 29 { return } + instructions[Int(opcode)]() +} + +func process() { + while input.count > 0 { + for inst in memory[ip].bytes { + process_instruction(opcode: Int32(inst)) + } + ip += 1 + } +} + + +// ------------------------------------------------------------- +// Initialization +// ------------------------------------------------------------- + +func load_image() { + let fileURL = URL(fileURLWithPath: "./ilo.rom") + let data = NSData(contentsOf: fileURL)! + var i: Int = 0 + while (i < 65536) { + memory[i] = getInt32FromData(data: data, offset: i) + i += 1 + } +} + +func bootstrap() { + if memory[0] == 0 { + load_image() + ip = 0 + data.empty() + address.empty() + } + input = " " + process() +} + + +// ------------------------------------------------------------- +// Stacks +// ------------------------------------------------------------- + +class Stack { + private var limit: Int + private var data: [Int32] + private var sp: Int = 0 + init(_ size: Int) { + data = [Int32](repeating: 0, count: size) + limit = size + } + public func tos() -> Int32 { return data[sp] } + public func nos() -> Int32 { return data[sp - 1] } + public func push(_ n: Int32) { sp += 1; data[sp] = n } + public func pop() -> Int32 { sp -= 1; return data[sp + 1] } + public func drop() { sp -= 1 } + public func swap() { let a = data[sp]; let b = data[sp - 1]; data[sp] = b; data[sp - 1] = a } + public func depth() -> Int { return sp } + public func item(_ n: Int) -> Int32 { return data[n] } + public func empty() { sp = 0 } +} + + +// ------------------------------------------------------------- +// Extensions to Existing Classes +// ------------------------------------------------------------- + +extension FixedWidthInteger where Self: SignedInteger { + var bytes: [Int8] { + var _endian = littleEndian + let bytePtr = withUnsafePointer(to: &_endian) { + $0.withMemoryRebound(to: Int8.self, capacity: MemoryLayout.size) { + UnsafeBufferPointer(start: $0, count: MemoryLayout.size) + } + } + return [Int8](bytePtr) + } +} + + +// ------------------------------------------------------------- +// Top-level System +// ------------------------------------------------------------- + +func main() { + bootstrap() + while ip < 65535 { + input = readLine() ?? "" + input = " \(input) \n" + process() + } +} + +main() + diff --git a/source/ilo.ts b/source/ilo.ts new file mode 100644 index 0000000..d6ba37b --- /dev/null +++ b/source/ilo.ts @@ -0,0 +1,516 @@ +/* ilo.ts, an ilo in TypeScript. (c) Rick Carlino */ + +/* Run via `npx ts-node ilo.ts`. + + If you get errors, try running `npx tsc --init` first. */ + +type OutputCallback = (char: string) => void; + +function enforce32BitSignedInteger(value: number) { + const int32Max = Math.pow(2, 31) - 1; + const int32Min = -Math.pow(2, 31); + value = value | 0; + value = ((value - int32Min) % (int32Max - int32Min + 1)) + int32Min; + return value; +} + +export class Konilo { + private m: Int32Array; + private blocks: Int32Array; + private ds: Int32Array; + private as: Int32Array; + + private ip: number; + private sp: number; + private rp: number; + + private a: number; + private b: number; + private f: number; + private s: number; + private d: number; + private l: number; + + private cycles: number; + + private input: string; + private outputHandler: OutputCallback; + + constructor(public romURL: string, public blockURL: string) { + this.m = new Int32Array(65536); + this.blocks = new Int32Array(1024 * 1024); + this.ds = new Int32Array(33); + this.as = new Int32Array(257); + + this.ip = 0; + this.sp = 0; + this.rp = 0; + + this.a = 0; + this.b = 0; + this.f = 0; + this.s = 0; + this.d = 0; + this.l = 0; + this.cycles = 25000; + + this.input = ""; + this.outputHandler = (char: string) => {}; + } + + async initialize(): Promise { + await Promise.all([ + this.loadFile(this.romURL, this.m), + this.loadFile(this.blockURL, this.blocks), + ]); + } + + async loadFile(url: string, target: Int32Array): Promise { + await fetch(url) + .then((response) => response.arrayBuffer()) + .then((buffer) => { + const dataView = new DataView(buffer); + for (let i = 0; i < target.length; i++) { + target[i] = dataView.getInt32(i * 4, true); + } + }) + .catch((error) => { + console.error("Error loading the file:", error); + }); + } + + async execute(): Promise { + console.log("Hello from Konilo!"); + let ticks = 0; + while (this.ip < 65536 && this.input.length >= 1 && !isNaN(this.ip)) { + const o = this.m[this.ip]; + this.process(o & 0xff); + this.process((o >> 8) & 0xff); + this.process((o >> 16) & 0xff); + this.process((o >> 24) & 0xff); + this.ip = this.ip + 1; + ticks += 1; + if (ticks % this.cycles === 0) { + ticks = 0; + await this.sleep(0); + } + } + await this.sleep(0); + console.log("Goodbye from Konilo!"); + } + + async sleep(ms: number): Promise { + return new Promise((resolve) => setTimeout(resolve, ms)); + } + + loadROM(): void { + this.loadFile(this.romURL, this.m); + } + + loadBlocks(): void { + this.loadFile(this.blockURL, this.blocks); + } + + setOutputHandler(callback: OutputCallback): void { + this.outputHandler = callback; + } + + send(str: string): void { + this.input += str; + } + + process(o: number) { + switch (o) { + case 0: + break; + case 1: + this.li(); + break; + case 2: + this.du(); + break; + case 3: + this.dr(); + break; + case 4: + this.sw(); + break; + case 5: + this.pu(); + break; + case 6: + this.po(); + break; + case 7: + this.ju(); + break; + case 8: + this.ca(); + break; + case 9: + this.cc(); + break; + case 10: + this.cj(); + break; + case 11: + this.re(); + break; + case 12: + this.eq(); + break; + case 13: + this.ne(); + break; + case 14: + this.lt(); + break; + case 15: + this.gt(); + break; + case 16: + this.fe(); + break; + case 17: + this.st(); + break; + case 18: + this.ad(); + break; + case 19: + this.su(); + break; + case 20: + this.mu(); + break; + case 21: + this.di(); + break; + case 22: + this.an(); + break; + case 23: + this.or(); + break; + case 24: + this.xo(); + break; + case 25: + this.sl(); + break; + case 26: + this.sr(); + break; + case 27: + this.cp(); + break; + case 28: + this.cy(); + break; + case 29: + this.io(); + break; + default: + break; + } + this.guard(); + } + + guard() { + this.ds[this.sp] = enforce32BitSignedInteger(this.ds[this.sp]); + if (this.sp >= 2) { + this.ds[this.sp - 1] = enforce32BitSignedInteger(this.ds[this.sp - 1]); + } + } + + save_ip() { + this.rp += 1; + this.as[this.rp] = this.ip; + } + pop() { + this.sp -= 1; + return this.ds[this.sp + 1]; + } + + push(v: number) { + this.ds[this.sp + 1] = v; + this.sp += 1; + } + + symmetric() { + if (this.b >= 0 && this.ds[this.sp - 1] < 0) { + this.ds[this.sp] += 1; + this.ds[this.sp - 1] -= this.b; + } + } + + li() { + this.ip += 1; + this.push(this.m[this.ip]); + } + + du() { + this.push(this.ds[this.sp]); + } + + dr() { + this.ds[this.sp] = 0; + this.sp -= 1; + } + + sw() { + const a = this.ds[this.sp]; + this.ds[this.sp] = this.ds[this.sp - 1]; + this.ds[this.sp - 1] = a; + } + + pu() { + this.rp += 1; + this.as[this.rp] = this.pop(); + } + + po() { + this.push(this.as[this.rp]); + this.rp -= 1; + } + + ju() { + this.ip = this.pop() - 1; + } + + ca() { + this.save_ip(); + this.ip = this.pop() - 1; + } + + cc() { + const a = this.pop(); + if (this.pop()) { + this.save_ip(); + this.ip = a - 1; + } + } + + cj() { + const a = this.pop(); + if (this.pop()) { + this.ip = a - 1; + } + } + + re() { + this.ip = this.as[this.rp]; + this.rp -= 1; + } + + eq() { + this.ds[this.sp - 1] = this.ds[this.sp - 1] == this.ds[this.sp] ? -1 : 0; + this.sp -= 1; + } + + ne() { + this.ds[this.sp - 1] = this.ds[this.sp - 1] != this.ds[this.sp] ? -1 : 0; + this.sp -= 1; + } + + lt() { + this.ds[this.sp - 1] = this.ds[this.sp - 1] < this.ds[this.sp] ? -1 : 0; + this.sp -= 1; + } + + gt() { + this.ds[this.sp - 1] = this.ds[this.sp - 1] > this.ds[this.sp] ? -1 : 0; + this.sp -= 1; + } + + fe() { + this.ds[this.sp] = this.m[this.ds[this.sp]]; + } + + st() { + this.m[this.ds[this.sp]] = this.ds[this.sp - 1]; + this.sp -= 2; + } + + ad() { + this.ds[this.sp - 1] += this.ds[this.sp]; + this.sp -= 1; + } + + su() { + this.ds[this.sp - 1] -= this.ds[this.sp]; + this.sp -= 1; + } + + mu() { + this.ds[this.sp - 1] *= this.ds[this.sp]; + this.sp -= 1; + } + + di() { + this.a = this.ds[this.sp]; + this.b = this.ds[this.sp - 1]; + this.ds[this.sp] = Math.floor(this.b / this.a); + this.ds[this.sp - 1] = this.b % this.a; + this.symmetric(); + } + + an() { + this.ds[this.sp - 1] = this.ds[this.sp] & this.ds[this.sp - 1]; + this.sp -= 1; + } + + or() { + this.ds[this.sp - 1] = this.ds[this.sp] | this.ds[this.sp - 1]; + this.sp -= 1; + } + + xo() { + this.ds[this.sp - 1] = this.ds[this.sp] ^ this.ds[this.sp - 1]; + this.sp -= 1; + } + + sl() { + this.ds[this.sp - 1] = this.ds[this.sp - 1] << this.ds[this.sp]; + this.sp -= 1; + } + + sr() { + this.ds[this.sp - 1] = this.ds[this.sp - 1] >> this.ds[this.sp]; + this.sp -= 1; + } + + cp() { + let l = this.pop(); + let d = this.pop(); + let s = this.ds[this.sp]; + this.ds[this.sp] = -1; + + while (l) { + if (this.m[d] !== this.m[s]) { + this.ds[this.sp] = 0; + } + l -= 1; + s += 1; + d += 1; + } + } + + io() { + const dev = this.pop(); + switch (dev) { + case 0: + this.ioa(); + break; + case 1: + this.iob(); + break; + case 2: + this.ioc(); + break; + case 3: + this.iod(); + break; + case 4: + this.ioe(); + break; + case 5: + this.iof(); + break; + case 6: + this.iog(); + break; + case 7: + this.ioh(); + break; + default: + console.log("wtf? " + dev); + break; + } + } + + cy() { + let l = this.pop(); + let d = this.pop(); + let s = this.pop(); + + while (l) { + this.m[d] = this.m[s]; + l -= 1; + s += 1; + d += 1; + } + } + + ioa() { + const c = String.fromCharCode(this.pop()); + this.outputHandler(c); + } + + iob() { + this.a = this.input.charCodeAt(0); + this.input = this.input.slice(1); + this.push(this.a); + } + + ioc() { + const buf = this.pop(); + const blk = this.pop(); + let i = 0; + while (i < 1024) { + this.m[buf + i] = this.blocks[blk * 1024 + i]; + i += 1; + } + } + + iod() { + const buf = this.pop(); + const blk = this.pop(); + let i = 0; + while (i < 1024) { + this.blocks[blk * 1024 + i] = this.m[buf + i]; + i += 1; + } + } + + ioe() {} + + iof() { + this.ip = -1; + this.sp = 0; + this.rp = 0; + this.loadFile(this.romURL, this.m); + } + + iog() { + this.ip = 65536; + this.input = ""; + } + + ioh() { + this.push(this.sp); + this.push(this.rp); + } +} + +(async () => { + const vm = new Konilo( + "http://forth.works/demo/ilo.rom", + "http://forth.works/demo/ilo.blocks" + ); + + let outputBuffer = ""; + + vm.setOutputHandler((char: string) => { + if (char === "\n") { + console.log(outputBuffer); + outputBuffer = ""; + } else { + outputBuffer += char; + } + }); + + await vm.initialize(); + vm.send("list\n\n"); + vm.execute(); +})(); diff --git a/source/mult-ilo.c b/source/mult-ilo.c new file mode 100644 index 0000000..6e4c6e8 --- /dev/null +++ b/source/mult-ilo.c @@ -0,0 +1,264 @@ +/*************************************************************** + crc's _ _ ___ _ + _ __ ___ _ _| | |_ / (_) | ___ + | '_ ` _ \| | | | | __| / /| | |/ _ \ + | | | | | | |_| | | |_ / / | | | (_) | + |_| |_| |_|\__,_|_|\__/_/ |_|_|\___/ + (c) charles childers + + This is a special implementation of my ilo computer, with many + copies of ilo running under a single process. Under this you + can quickly switch between ilo instances. + + - `bye` will act like `restart` on the current computer + - ctrl+c restarts the current computer + - ctrl+n switches to the next ilo + - ctrl+p switches to the previous ilo + - ctrl+a shuts down mult/ilo + - switching can only be done when the system is waiting for + input + + **************************************************************/ + +#include +#include +#include +#include +#include +#include + +#define V void +#define I int +#define C char + +#define ILOS 5 + +struct termios old_term, new_term; +typedef struct ilo ilo; + +struct ilo { + I ip, /* instruction pointer */ + sp, /* data stack pointer */ + rp, /* address stack pointer */ + ds[33], /* data stack */ + as[257], /* address stack */ + m[65536]; /* memory */ + C *blocks, /* name of block file (ilo.blocks) */ + *rom; /* name of image (ilo.rom) */ + I a, b, f, s, d, l; + C i[1]; +}; + +struct ilo systems[ILOS]; + +I cur, cancel; + +#define DS v->ds +#define AS v->as +#define SP v->sp +#define RP v->rp +#define IP v->ip +#define M v->m +#define A v->a +#define B v->b +#define S v->s +#define D v->d +#define L v->l +#define T DS[SP] /* Top of Data Stack */ +#define N DS[SP-1] /* Next on Data Stack */ +#define R AS[RP] /* Top of Address Stack */ + +V iof(ilo *); + +V push(ilo *v, I n) { DS[SP + 1] = n; SP += 1; } +I pop(ilo *v) { SP -= 1; return DS[SP + 1]; } + +V load_image(ilo *v) { + v->f = open(v->rom, O_RDONLY, 0666); + if (!v->f) { return; }; + read(v->f, &M, 65536 * 4); + close(v->f); + v->i[0] = 32; + IP = SP = RP = 0; +} + +V save_image(ilo *v) { + v->f = open(v->rom, O_WRONLY, 0666); + write(v->f, &M, 65536 * 4); + close(v->f); +} + +V block_common(ilo *v) { + B = pop(v); /* block buffer */ + A = pop(v); /* block number */ + lseek(v->f, 4096 * A, SEEK_SET); +} + +V read_block(ilo *v) { + v->f = open(v->blocks, O_RDONLY, 0666); + block_common(v); + read(v->f, M + B, 4096); + close(v->f); +} + +V write_block(ilo *v) { + v->f = open(v->blocks, O_WRONLY, 0666); + block_common(v); + write(v->f, M + B, 4096); + close(v->f); +} + +V save_ip(ilo *v) { RP += 1; R = IP; } +V symmetric(ilo *v) { + if (B >= 0 && N < 0) { T += 1; N -= B; } } + +V li(ilo *v) { IP += 1; push(v, M[IP]); } +V du(ilo *v) { push(v, T); } +V dr(ilo *v) { DS[SP] = 0; SP -= 1; } +V sw(ilo *v) { A = T; T = N; N = A; } +V pu(ilo *v) { RP += 1; R = pop(v); } +V po(ilo *v) { push(v, R); RP -= 1; } +V ju(ilo *v) { IP = pop(v) - 1; } +V ca(ilo *v) { save_ip(v); IP = pop(v) - 1; } +V cc(ilo *v) { A = pop(v); + if (pop(v)) { save_ip(v); + IP = A - 1; } } +V cj(ilo *v) { A = pop(v); + if (pop(v)) { IP = A - 1; } } +V re(ilo *v) { IP = R; RP -= 1; } +V eq(ilo *v) { N = (N == T) ? -1 : 0; SP -= 1; } +V ne(ilo *v) { N = (N != T) ? -1 : 0; SP -= 1; } +V lt(ilo *v) { N = (N < T) ? -1 : 0; SP -= 1; } +V gt(ilo *v) { N = (N > T) ? -1 : 0; SP -= 1; } +V fe(ilo *v) { T = M[T]; } +V st(ilo *v) { M[T] = N; SP -= 2; } +V ad(ilo *v) { N += T; SP -= 1; } +V su(ilo *v) { N -= T; SP -= 1; } +V mu(ilo *v) { N *= T; SP -= 1; } +V di(ilo *v) { A = T; B = N; + if (A == 0) { cancel = 1; iof(v); return; } + T = B / A; N = B % A; + symmetric(v); } +V an(ilo *v) { N = T & N; SP -= 1; } +V or(ilo *v) { N = T | N; SP -= 1; } +V xo(ilo *v) { N = T ^ N; SP -= 1; } +V sl(ilo *v) { N = N << T; SP -= 1; } +V sr(ilo *v) { N = N >> T; SP -= 1; } +V cp(ilo *v) { L = pop(v); D = pop(v); S = T; T = -1; + while (L) { + if (M[D] != M[S]) { T = 0; } + L -= 1; S += 1; D += 1; } } +V cy(ilo *v) { L = pop(v); D = pop(v); S = pop(v); + while (L) { + M[D] = M[S]; + L -= 1; S += 1; D += 1; } } + +V pre(V) { cur -= 1; if (cur < 0) cur = ILOS - 1; } +V nxt(V) { cur += 1; if (cur > (ILOS - 1)) cur = 0; } + +V msgs(V) { printf("\n*** SWITCH TO %d ***\n", cur); } +V msgx(V) { printf("\n*** SHUTDOWN REQUESTED ***\n"); + tcsetattr(STDIN_FILENO,TCSANOW, &old_term); + exit(1); } +V msgr(V) { printf("\n*** RESTART %d ***\n", cur); } + +V ioa(ilo *v) { v->i[0] = (char)pop(v); write(1, &v->i, 1); } +V iob(ilo *v) { read(0, &v->i, 1); push(v, v->i[0]); + if (v->i[0] == 14) { T = 32; nxt(); msgs(); } + if (v->i[0] == 16) { T = 32; pre(); msgs(); } + if (v->i[0] == 3) { T = 32; msgr(); iof(v); + cancel = 1; } + if (v->i[0] == 1) { T = 32; msgx(); } + if (v->i[0] == 8 || v->i[0] == 127) { + v->i[0] = '\b'; write(1, &v->i, 1); + v->i[0] = ' '; write(1, &v->i, 1); + v->i[0] = '\b'; write(1, &v->i, 1); + } else { write(1, &v->i, 1); } } +V ioc(ilo *v) { read_block(v); } +V iod(ilo *v) { write_block(v); } +V ioe(ilo *v) { save_image(v); } +V iof(ilo *v) { load_image(v); IP = -1; } +V iog(ilo *v) { iof(v); } +V ioh(ilo *v) { push(v, SP); push(v, RP); } + +V io(ilo *v) { + switch (pop(v)) { + case 0: ioa(v); break; case 1: iob(v); break; + case 2: ioc(v); break; case 3: iod(v); break; + case 4: ioe(v); break; case 5: iof(v); break; + case 6: iog(v); break; case 7: ioh(v); break; + default: break; + } +} + +V process(ilo *v, I o) { + switch (o) { + case 0: break; case 1: li(v); break; + case 2: du(v); break; case 3: dr(v); break; + case 4: sw(v); break; case 5: pu(v); break; + case 6: po(v); break; case 7: ju(v); break; + case 8: ca(v); break; case 9: cc(v); break; + case 10: cj(v); break; case 11: re(v); break; + case 12: eq(v); break; case 13: ne(v); break; + case 14: lt(v); break; case 15: gt(v); break; + case 16: fe(v); break; case 17: st(v); break; + case 18: ad(v); break; case 19: su(v); break; + case 20: mu(v); break; case 21: di(v); break; + case 22: an(v); break; case 23: or(v); break; + case 24: xo(v); break; case 25: sl(v); break; + case 26: sr(v); break; case 27: cp(v); break; + case 28: cy(v); break; case 29: io(v); break; + default: break; + } +} + +V process_bundle(ilo *v, I opcode) { + if (cancel) return; process(v, opcode & 0xFF); + if (cancel) return; process(v, (opcode >> 8) & 0xFF); + if (cancel) return; process(v, (opcode >> 16) & 0xFF); + if (cancel) return; process(v, (opcode >> 24) & 0xFF); +} + +V execute(V) { + ilo *v = &systems[cur]; + while (IP < 65536) { + cancel = 0; + process_bundle(v, M[IP]); + IP += 1; + v = &systems[cur]; + } +} + +V handle_sigint(I sig) { + printf("\n*** SIGINT (%d) : RESTARTING %d ***\n", sig, cur); + cancel = 1; + iof(&systems[cur]); +} + +I main(I argc, C **argv) { + ilo *v; + I i; + + cur = 0; + for (i = 0; i < ILOS; i++) { + v = &systems[i]; + v->blocks = (argc > 1) ? argv[1] : "ilo.blocks"; + v->rom = (argc > 2) ? argv[2] : "ilo.rom"; + load_image(v); + } + if (signal(SIGINT, handle_sigint) == SIG_ERR) { + perror("signal"); + return 1; + } + + tcgetattr(STDIN_FILENO, &old_term); + new_term = old_term; + new_term.c_lflag &=(~ICANON & ~ECHO); + tcsetattr(STDIN_FILENO, TCSANOW, &new_term); + + execute(); + + tcsetattr(STDIN_FILENO, TCSANOW, &old_term); + + return 0; +} diff --git a/source/x11-ilo.c b/source/x11-ilo.c new file mode 100644 index 0000000..1c37fab --- /dev/null +++ b/source/x11-ilo.c @@ -0,0 +1,466 @@ +/*************************************************************** + crc's _ _ __ + (_) | ___ / /_ __ + | | |/ _ \ / /\ \/ / a tiny virtual computer + | | | (_) / / > < 64kw RAM, 32-bit, Dual Stack, MISC + |_|_|\___/_/ /_/\_\ ilo-x.c (c) charles childers + **************************************************************/ + +/* cc -o ilo-x vm/ilo-x.c `pkg-config --cflags x11 --libs` */ + +/* Local Configuration */ + +#define BLOCKS "ilo.blocks" +#define ROM "ilo.rom" +#define FONT "ilo.fnt" +#define FG 0xFFFFFF +#define BG 0x000000 +#define CURSOR 0x00FFFF +#define FW 640 +#define FH 384 +#define FONT_H 16 +#define FONT_W 8 + +#include +#include +#include +#include +#include +#include + +#define T ds[sp] /* Top of Data Stack */ +#define N ds[sp-1] /* Next on Data Stack */ +#define R as[rp] /* Top of Address Stack */ +#define V void +#define I int +#define C char + +I ip, /* instruction pointer */ + sp, /* data stack pointer */ + rp, /* address stack pointer */ + ds[33], /* data stack */ + as[257], /* address stack */ + m[65536], /* memory */ + ok; + +C *blocks, /* name of block file (ilo.blocks) */ + *rom; /* name of image (ilo.rom) */ + +I a, b, f, s, d, l; /* these others are used */ +C i[1]; /* for misc. purposes */ + +#define TERM_W (FW / FONT_W) +#define TERM_H (FH / FONT_H) + +I frame[(FW * FH)/32]; /* frame buffer for display */ +I font[4096]; /* font bitmap */ +I tx, ty; /* text cursor location */ + +/* variables for Arland's DEC subset */ +I acc[32], acc_i = 0, ground = 0, on = 0; + +/* variables for X11 stuff */ +Display *disp; +Window win; +GC gc; +XEvent event; +C text[255]; + +V dputc(I); +V redraw(); +V iof(); + +V p(char *s) { while(*s) dputc(*s++); } +V e(char *s) { p("E:"); p(s); p("\n"); ok = 1; iof(); } +V dso() { if ((sp + 1) > 32) { e("DSO"); } } +V dsu() { if ((sp - 1) < 0) { e("DSU"); } } +V rso() { if ((rp + 1) > 256) { e("RSO"); } } +V rsu() { if ((rp - 1) < 0) { e("RSU"); } } +V dbz() { if (T == 0) { e("DBZ"); } } +V mem() { if (T < 0 || T > 65535) { e("MEM"); } } +V uli() { if (f == -1) { e("ULI"); } } +V ulf() { if (f == -1) { e("ULF"); } } +V usi() { if (f == -1) { e("URI"); } } +V urb() { if (f == -1) { e("URB"); } } +V uwb() { if (f == -1) { e("UWB"); } } +V push(I v) { dso(); ds[sp + 1] = v; sp += 1; } +I pop() { dsu(); sp -= 1; return ds[sp + 1]; } + +V cursor() { + XSetForeground(disp, gc, CURSOR); + XFillRectangle(disp, win, gc, tx, ty, FONT_W, FONT_H); + XFlush(disp); +} + +I wait_key() { + while (1) { + XNextEvent(disp, &event); + if (event.type == KeyPress) { + KeySym key = XLookupKeysym(&event.xkey, 0); + XLookupString(&event.xkey, text, 255, &key, 0); + if (text[0] == 13) text[0] = 10; + if (text[0] != 0) return (I) text[0]; + } + if (event.type == Expose) { redraw(); } + } +} + +V load_font() { + f = open(FONT, O_RDONLY, 0666); + ulf(); + if (!f) { return; }; + read(f, &font, 4096); + close(f); +} + +V pixel(I x, I y, I c) { + I index = y * FW + x; + if (c == 0) { + frame[(index / 32)] &= ~(1 << (31 - index % 32)); + XSetForeground(disp, gc, BG); + } else { + frame[(index / 32)] |= 1 << (31 - index % 32); + XSetForeground(disp, gc, FG); + } + XDrawPoint(disp, win, gc, x, y); +} + +I get_pixel(I x, I y) { + I index = y * FW + x; + I bit_pos = 31 - index % 32; + I mask = 1 << bit_pos; + return (frame[(index / 32)] & mask) >> bit_pos; +} + +V redraw() { + for (I x = 0; x < FW; x++) { + for (I y = 0; y < FH; y++) { + XSetForeground(disp, gc, get_pixel(x, y) ? FG : BG); + XDrawPoint(disp, win, gc, x, y); + } + } + cursor(); +} + +V scroll() { + I memsize = (FH * FW) / 32; + I last_row = (FW * FONT_H) / 32; + for (I i = 0; i < memsize - last_row; i++) { + frame[i] = frame[i + last_row]; + } + for (I i = memsize - last_row; i < memsize; i++) { + frame[i] = 0; + } + redraw(); +} + +unsigned C reverse(unsigned C b) { + b = (b & 0xF0) >> 4 | (b & 0x0F) << 4; + b = (b & 0xCC) >> 2 | (b & 0x33) << 2; + b = (b & 0xAA) >> 1 | (b & 0x55) << 1; + return b; +} + +V handle_special_character(I c) { + if (c == 8 || c == 127) { /* BACKSPACE/DELETE */ + if (tx - FONT_W >= 0) { + tx -= FONT_W ; + dputc(' '); + tx -= FONT_W; + redraw(); + } + } else if (c == 9) { /* TAB */ + I ts = tx / FONT_W; + for (I i = ts; i < ((ts + 7) / 8) * 8; i++) { dputc(' '); } + } else if (c == 10 || c == 13) { /* CR or LF */ + ty += FONT_H; + tx = 0; + redraw(); + } +} + +V handle_regular_character(C *bitmap) { + I x, y, set; + for (x = 0; x < FONT_H; x++) { + for (y = 0; y < FONT_W; y++) { + set = reverse(bitmap[x]) & 1 << y; + pixel(tx + y, ty + x, set ? 1 : 0); + } + } + tx += FONT_W; +} + +V advance_cursor_and_scroll() { + if (tx >= FW) { tx = 0; ty += FONT_H; } + if (ty > (FH - FONT_H)) { ty -= FONT_H; scroll(); } +} + +V dputc(I c) { + C *bitmap = (C *)font + (c * ((FONT_H * FONT_W) / 8)); + + handle_special_character(c); + + if (!(c == 8 || c == 127 || c == 9 || c == 10 || c == 13)) { + handle_regular_character(bitmap); + } + + advance_cursor_and_scroll(); + cursor(); +} + +I acc_pop() { + I k = acc_i; + if (acc_i > 0) { + acc_i -= 1; + if (acc_i == -1) { + acc_i = 0; + } + } + return acc[k]; +} + +V acc_reset() { + for (I x = 0; x < 32; x++) { acc[x] = 0; } + ground = on = 0; +} + +V gt_up(I n) { ty -= FONT_H; if (ty < 0) ty = 0; } +V gt_down(I n) { ty += FONT_H; if (ty > 24 * FONT_H) ty = 24 * FONT_H; } +V gt_left(I n) { tx -= FONT_W; if (tx < 0) tx = 0; } +V gt_right(I n) { tx += FONT_W; if (tx > 79 * FONT_W) ty = 79 * FONT_W; } +V gt_move_cursor() { + if (acc_i >= 1) { + I a = (acc_pop() - 1) * FONT_W; + I b = (acc_pop() - 1) * FONT_H; + ty = b; if (ty < 0) ty = 0; if (ty > FONT_H * 24) ty = FONT_H * 24; + tx = a; if (tx < 0) tx = 0; if (tx > FONT_W * 79) tx = FONT_W * 79; + acc_reset(); + return; + } + /* home */ + tx = 0; ty = 0; + acc_reset(); +} + +V gt_reset() { acc_reset(); } +V gt_next() { acc_i += 1; acc[acc_i] = 0; } +V gt_clear() { + acc_reset(); + for (I x = 0; x < (FW * FH) / 32; x++) frame[x] = 0; + tx = ty = 0; + redraw(); +} +V gt_set_attr() { acc_reset(); } + +V term_putc(I c) { + if (c == 27) { + on = -2; + return; + } + switch (on) { + case 0: + dputc(c); + return; + case -2: + if (c == '[') { + on = -1; + return; + } + on = 0; + dputc(c); + return; + } + if (c >= '0' && c <= '9') { + acc[acc_i] *= 10; + acc[acc_i] += c - 48; + if (c == '3') { + ground = 0; + } + if (c == '4') { + ground = 1; + } + } else { + switch (c) { + case 'A': gt_up(acc_pop()); break; + case 'B': gt_down(acc_pop()); break; + case 'C': gt_left(acc_pop()); break; + case 'D': gt_right(acc_pop()); break; + case 'm': gt_set_attr(); break; + case ';': gt_next(); break; + case 'H': gt_move_cursor(); break; + case 'J': gt_clear(); break; + default: on = 0; + dputc(c); + } + } +} + +V load_image() { + f = open(rom, O_RDONLY, 0666); + uli(); + if (!f) { return; }; + read(f, &m, 65536 * 4); + close(f); + ip = sp = rp = 0; +} + +V save_image() { + f = open(rom, O_WRONLY, 0666); + usi(); + write(f, &m, 65536 * 4); + close(f); +} + +V block_common() { + b = pop(); /* block buffer */ + a = pop(); /* block number */ + lseek(f, 4096 * a, SEEK_SET); +} + +V read_block() { + f = open(blocks, O_RDONLY, 0666); + urb(); + block_common(); + read(f, m + b, 4096); + close(f); +} + +V write_block() { + f = open(blocks, O_WRONLY, 0666); + uwb(); + block_common(); + write(f, m + b, 4096); + close(f); +} + +V save_ip() { rso(); rp += 1; R = ip; } +V symmetric() { if (b >= 0 && N < 0) { T += 1; N -= b; } } + +V li() { ip += 1; push(m[ip]); } +V du() { push(T); } +V dr() { pop(); } +V sw() { a = T; T = N; N = a; } +V pu() { rp += 1; R = pop(); } +V po() { push(R); rp -= 1; } +V ju() { ip = pop() - 1; } +V ca() { save_ip(); ip = pop() - 1; } +V cc() { a = pop(); if (pop()) { save_ip(); ip = a - 1; } } +V cj() { a = pop(); if (pop()) { ip = a - 1; } } +V re() { ip = R; rp -= 1; } +V eq() { N = (N == T) ? -1 : 0; sp -= 1; } +V ne() { N = (N != T) ? -1 : 0; sp -= 1; } +V lt() { N = (N < T) ? -1 : 0; sp -= 1; } +V gt() { N = (N > T) ? -1 : 0; sp -= 1; } +V fe() { mem(); T = m[T]; } +V st() { mem(); m[T] = N; sp -= 2; } +V ad() { N += T; sp -= 1; } +V su() { N -= T; sp -= 1; } +V mu() { N *= T; sp -= 1; } +V di() { dbz(); + a = T; b = N; T = b / a; N = b % a; symmetric(); } +V an() { N = T & N; sp -= 1; } +V or() { N = T | N; sp -= 1; } +V xo() { N = T ^ N; sp -= 1; } +V sl() { N = N << T; sp -= 1; } +V sr() { N = N >> T; sp -= 1; } +V cp() { l = pop(); d = pop(); s = T; T = -1; + while (l) { if (m[d] != m[s]) { T = 0; } + l -= 1; s += 1; d += 1; } } +V cy() { l = pop(); d = pop(); s = pop(); + while (l) { m[d] = m[s]; l -= 1; s += 1; d += 1; } } +V ioa() { term_putc(pop()); } +V iob() { push(wait_key()); term_putc(T); } +V ioc() { read_block(); } +V iod() { write_block(); } +V ioe() { save_image(); } +V iof() { load_image(); ip = -1; } +V iog() { ip = 65536; } +V ioh() { push(sp); push(rp); } +V iox() { I c = pop(); I y = pop(); I x = pop(); + pixel(x, y, c); } +V ioy() { I y = pop(); I x = pop(); push(get_pixel(x, y)); } +V ioz() { I x, y, wx, wy, mask; Window w; + XQueryPointer(disp, win, &w, &w, &x, &y, &wx, &wy, &mask); + push(x); push(y); if (mask & Button1Mask) push(-1); else push(0); } +V io() { + switch (pop()) { + case 0: ioa(); break; case 1: iob(); break; + case 2: ioc(); break; case 3: iod(); break; + case 4: ioe(); break; case 5: iof(); break; + case 6: iog(); break; case 7: ioh(); break; + case 33: iox(); break; case 34: ioy(); break; + case 35: ioz(); break; + default: break; + } +} + +V process(I o) { + switch (o) { + case 0: break; case 1: li(); break; + case 2: du(); break; case 3: dr(); break; + case 4: sw(); break; case 5: pu(); break; + case 6: po(); break; case 7: ju(); break; + case 8: ca(); break; case 9: cc(); break; + case 10: cj(); break; case 11: re(); break; + case 12: eq(); break; case 13: ne(); break; + case 14: lt(); break; case 15: gt(); break; + case 16: fe(); break; case 17: st(); break; + case 18: ad(); break; case 19: su(); break; + case 20: mu(); break; case 21: di(); break; + case 22: an(); break; case 23: or(); break; + case 24: xo(); break; case 25: sl(); break; + case 26: sr(); break; case 27: cp(); break; + case 28: cy(); break; case 29: io(); break; + default: break; + } +} + +#define VALID(n) (ok == 0) && ((opcode >> n) & 0xFF) + +V execute() { + I opcode; + while (ip < 65536) { + opcode = m[ip]; + ok = 0; + if (VALID(0)) process(opcode & 0xFF); + if (VALID(8)) process((opcode >> 8) & 0xFF); + if (VALID(16)) process((opcode >> 16) & 0xFF); + if (VALID(24)) process((opcode >> 24) & 0xFF); + ip += 1; + } +} + +I main(I argc, C **argv) { + blocks = (argc > 1) ? argv[1] : BLOCKS; + rom = (argc > 2) ? argv[2] : ROM; + ok = 0; + +/* +#ifdef __OpenBSD__ + pledge("stdio rpath wpath unix video", NULL); +#endif +*/ + + load_image(); + + load_font(); + + disp = XOpenDisplay(NULL); + win = XCreateSimpleWindow(disp, RootWindow(disp, 0), + 0, 0, FW, FH, 0, 0x0, 0x0); + XSelectInput(disp, win, ExposureMask | KeyPressMask | ButtonPressMask | ButtonReleaseMask); + XStoreName(disp, win, "x/ilo"); + gc = DefaultGC(disp, DefaultScreen(disp)); + XMapWindow(disp, win); + XFlush(disp); + XMoveWindow(disp, win, (DisplayWidth(disp, DefaultScreen(disp)) - FW) / 2, + (DisplayHeight(disp, DefaultScreen(disp)) - FH) / 2); + + execute(); + + XUnmapWindow(disp, win); + XDestroyWindow(disp, win); + XCloseDisplay(disp); + + return 0; +} diff --git a/source/x11-mult-ilo.c b/source/x11-mult-ilo.c new file mode 100644 index 0000000..e6c42ce --- /dev/null +++ b/source/x11-mult-ilo.c @@ -0,0 +1,522 @@ +/*************************************************************** + crc's _ _ ___ _ __ + _ __ ___ _ _| | |_ / (_) | ___ / /_ __ + | '_ ` _ \| | | | | __| / /| | |/ _ \ / /\ \/ / + | | | | | | |_| | | |_ / / | | | (_) / / > < + |_| |_| |_|\__,_|_|\__/_/ |_|_|\___/_/ /_/\_\ + (c) charles childers + + This is a special implementation of my ilo computer, with many + copies of ilo running under a single process. Under this you + can quickly switch between ilo instances. + + - `bye` will act like `restart` on the current computer + - ctrl+c restarts the current computer + - ctrl+n switches to the next ilo + - ctrl+p switches to the previous ilo + - ctrl+a shuts down mult/ilo + - switching can only be done when the system is waiting for + input + + **************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +#define BLOCKS "ilo.blocks" +#define ROM "ilo.rom" +#define FONT "ilo.fnt" +#define FG 0xFFFFFF +#define BG 0x000000 +/* Orange = 0xFFAA00, Red = 0xFF0000, Cyan = 0x00FFFF */ +#define CURSOR 0xFFAA00 +#define FW 640 +#define FH 384 +#define FONT_H 16 +#define FONT_W 8 + +#define V void +#define I int +#define C char + +#define ILOS 3 + +typedef struct ilo ilo; + +struct ilo { + I ip, /* instruction pointer */ + sp, /* data stack pointer */ + rp, /* address stack pointer */ + ds[33], /* data stack */ + as[257], /* address stack */ + m[65536]; /* memory */ + C *blocks, /* name of block file (ilo.blocks) */ + *rom; /* name of image (ilo.rom) */ + I a, b, f, s, d, l, ok; + C i[1]; +}; + +#define TERM_W (FW / FONT_W) +#define TERM_H (FH / FONT_H) + +I frame[(FW * FH)/32]; /* frame buffer for display */ +I font[4096]; /* font bitmap */ +I tx, ty; /* text cursor location */ + +/* variables for Arland's DEC subset */ +I acc[32], acc_i = 0, ground = 0, on = 0; + +/* variables for X11 stuff */ +Display *disp; +Window win; +GC gc; +XEvent event; +C text[255]; + +V dputc(I); +V redraw(); + +struct ilo systems[ILOS]; + +I cur; + +#define DS v->ds +#define AS v->as +#define SP v->sp +#define RP v->rp +#define IP v->ip +#define M v->m +#define A v->a +#define B v->b +#define S v->s +#define D v->d +#define L v->l +#define T DS[SP] /* Top of Data Stack */ +#define N DS[SP-1] /* Next on Data Stack */ +#define R AS[RP] /* Top of Address Stack */ +#define F v->f + +V iof(ilo *); + +V p(char *s) { while(*s) dputc(*s++); } +V e(ilo *v, char *s) { p("E:"); p(s); p("\n"); v->ok = 1; iof(v); } +V dso(ilo *v) { if ((SP + 1) > 32) { e(v, "DSO"); } } +V dsu(ilo *v) { if ((SP - 1) < 0) { e(v, "DSU"); } } +V rso(ilo *v) { if ((RP + 1) > 256) { e(v, "RSO"); } } +V rsu(ilo *v) { if ((RP - 1) < 0) { e(v, "RSU"); } } +V dbz(ilo *v) { if (T == 0) { e(v, "DBZ"); } } +V mem(ilo *v) { if (T < 0 || T > 65535) { e(v, "MEM"); } } +V uli(ilo *v) { if (F == -1) { e(v, "ULI"); } } +V ulf(ilo *v) { if (F == -1) { e(v, "ULF"); } } +V usi(ilo *v) { if (F == -1) { e(v, "URI"); } } +V urb(ilo *v) { if (F == -1) { e(v, "URB"); } } +V uwb(ilo *v) { if (F == -1) { e(v, "UWB"); } } + +V push(ilo *v, I n) { dso(v); DS[SP + 1] = n; SP += 1; } +I pop(ilo *v) { dsu(v); SP -= 1; return DS[SP + 1]; } + +V cursor() { + XSetForeground(disp, gc, CURSOR); + XFillRectangle(disp, win, gc, tx, ty, FONT_W, FONT_H); + XFlush(disp); +} + +I wait_key() { + while (1) { + XNextEvent(disp, &event); + if (event.type == KeyPress) { + KeySym key = XLookupKeysym(&event.xkey, 0); + XLookupString(&event.xkey, text, 255, &key, 0); + if (text[0] == 13) text[0] = 10; + if (text[0] != 0) return (I) text[0]; + } + if (event.type == Expose) { redraw(); cursor(); } + } +} + +V load_font(ilo *v) { + F = open(FONT, O_RDONLY, 0666); + ulf(v); + if (!F) { return; }; + read(F, &font, 4096); + close(F); +} + +V pixel(I x, I y, I c) { + I index = y * FW + x; + if (c == 0) { + frame[(index / 32)] &= ~(1 << (31 - index % 32)); + XSetForeground(disp, gc, BG); + } else { + frame[(index / 32)] |= 1 << (31 - index % 32); + XSetForeground(disp, gc, FG); + } + XDrawPoint(disp, win, gc, x, y); +} + +I get_pixel(I x, I y) { + I index = y * FW + x; + I bit_pos = 31 - index % 32; + I mask = 1 << bit_pos; + return (frame[(index / 32)] & mask) >> bit_pos; +} + +V redraw() { + for (I x = 0; x < FW; x++) { + for (I y = 0; y < FH; y++) { + XSetForeground(disp, gc, get_pixel(x, y) ? FG : BG); + XDrawPoint(disp, win, gc, x, y); + } + } +} + +V scroll() { + I memsize = (FH * FW) / 32; + I last_row = (FW * FONT_H) / 32; + for (I i = 0; i < memsize - last_row; i++) { + frame[i] = frame[i + last_row]; + } + for (I i = memsize - last_row; i < memsize; i++) { + frame[i] = 0; + } + redraw(); +} + +unsigned C reverse(unsigned C b) { + b = (b & 0xF0) >> 4 | (b & 0x0F) << 4; + b = (b & 0xCC) >> 2 | (b & 0x33) << 2; + b = (b & 0xAA) >> 1 | (b & 0x55) << 1; + return b; +} + +V handle_special_character(I c) { + if (c == 8 || c == 127) { /* BACKSPACE/DELETE */ + if (tx - FONT_W >= 0) { + tx -= FONT_W ; + dputc(' '); + tx -= FONT_W; + } + } else if (c == 9) { /* TAB */ + I ts = tx / FONT_W; + for (I i = ts; i < ((ts + 7) / 8) * 8; i++) { dputc(' '); } + } else if (c == 10 || c == 13) { /* CR or LF */ + ty += FONT_H; + tx = 0; + } +} + +V handle_regular_character(C *bitmap) { + I x, y, set; + for (x = 0; x < FONT_H; x++) { + for (y = 0; y < FONT_W; y++) { + set = reverse(bitmap[x]) & 1 << y; + pixel(tx + y, ty + x, set ? 1 : 0); + } + } + tx += FONT_W; +} + +V advance_cursor_and_scroll() { + if (tx >= FW) { tx = 0; ty += FONT_H; } + if (ty > (FH - FONT_H)) { ty -= FONT_H; scroll(); } +} + +V dputc(I c) { + C *bitmap = (C *)font + (c * ((FONT_H * FONT_W) / 8)); + + handle_special_character(c); + + if (!(c == 8 || c == 127 || c == 9 || c == 10 || c == 13)) { + handle_regular_character(bitmap); + } + + advance_cursor_and_scroll(); +} + +I acc_pop() { + I k = acc_i; + if (acc_i > 0) { + acc_i -= 1; + if (acc_i == -1) { + acc_i = 0; + } + } + return acc[k]; +} + +V acc_reset() { + for (I x = 0; x < 32; x++) { acc[x] = 0; } + ground = on = 0; +} + +V gt_up(I n) { ty -= FONT_H; if (ty < 0) ty = 0; } +V gt_down(I n) { ty += FONT_H; if (ty > 24 * FONT_H) ty = 24 * FONT_H; } +V gt_left(I n) { tx -= FONT_W; if (tx < 0) tx = 0; } +V gt_right(I n) { tx += FONT_W; if (tx > 79 * FONT_W) ty = 79 * FONT_W; } +V gt_move_cursor() { + if (acc_i >= 1) { + I a = (acc_pop() - 1) * FONT_W; + I b = (acc_pop() - 1) * FONT_H; + ty = b; if (ty < 0) ty = 0; if (ty > FONT_H * 24) ty = FONT_H * 24; + tx = a; if (tx < 0) tx = 0; if (tx > FONT_W * 79) tx = FONT_W * 79; + acc_reset(); + return; + } + /* home */ + tx = 0; ty = 0; + acc_reset(); +} + +V gt_reset() { acc_reset(); } +V gt_next() { acc_i += 1; acc[acc_i] = 0; } +V gt_clear() { + acc_reset(); + for (I x = 0; x < (FW * FH) / 32; x++) frame[x] = 0; + tx = ty = 0; + redraw(); +} +V gt_set_attr() { acc_reset(); } + +V term_putc(I c) { + if (c == 27) { + on = -2; + return; + } + switch (on) { + case 0: + dputc(c); + return; + case -2: + if (c == '[') { + on = -1; + return; + } + on = 0; + dputc(c); + return; + } + if (c >= '0' && c <= '9') { + acc[acc_i] *= 10; + acc[acc_i] += c - 48; + if (c == '3') { + ground = 0; + } + if (c == '4') { + ground = 1; + } + } else { + switch (c) { + case 'A': gt_up(acc_pop()); break; + case 'B': gt_down(acc_pop()); break; + case 'C': gt_left(acc_pop()); break; + case 'D': gt_right(acc_pop()); break; + case 'm': gt_set_attr(); break; + case ';': gt_next(); break; + case 'H': gt_move_cursor(); break; + case 'J': gt_clear(); break; + default: on = 0; + dputc(c); + } + } +} + +V load_image(ilo *v) { + F = open(v->rom, O_RDONLY, 0666); + if (!F) { return; }; + read(F, &M, 65536 * 4); + close(F); + IP = SP = RP = 0; +} + +V save_image(ilo *v) { + v->f = open(v->rom, O_WRONLY, 0666); + write(v->f, &M, 65536 * 4); + close(v->f); +} + +V block_common(ilo *v) { + B = pop(v); /* block buffer */ + A = pop(v); /* block number */ + lseek(v->f, 4096 * A, SEEK_SET); +} + +V read_block(ilo *v) { + v->f = open(v->blocks, O_RDONLY, 0666); + block_common(v); + read(v->f, M + B, 4096); + close(v->f); +} + +V write_block(ilo *v) { + v->f = open(v->blocks, O_WRONLY, 0666); + block_common(v); + write(v->f, M + B, 4096); + close(v->f); +} + +V save_ip(ilo *v) { RP += 1; R = IP; } +V symmetric(ilo *v) { + if (B >= 0 && N < 0) { T += 1; N -= B; } } + +V li(ilo *v) { IP += 1; push(v, M[IP]); } +V du(ilo *v) { push(v, T); } +V dr(ilo *v) { DS[SP] = 0; SP -= 1; } +V sw(ilo *v) { A = T; T = N; N = A; } +V pu(ilo *v) { RP += 1; R = pop(v); } +V po(ilo *v) { push(v, R); RP -= 1; } +V ju(ilo *v) { IP = pop(v) - 1; } +V ca(ilo *v) { save_ip(v); IP = pop(v) - 1; } +V cc(ilo *v) { A = pop(v); + if (pop(v)) { save_ip(v); + IP = A - 1; } } +V cj(ilo *v) { A = pop(v); + if (pop(v)) { IP = A - 1; } } +V re(ilo *v) { IP = R; RP -= 1; } +V eq(ilo *v) { N = (N == T) ? -1 : 0; SP -= 1; } +V ne(ilo *v) { N = (N != T) ? -1 : 0; SP -= 1; } +V lt(ilo *v) { N = (N < T) ? -1 : 0; SP -= 1; } +V gt(ilo *v) { N = (N > T) ? -1 : 0; SP -= 1; } +V fe(ilo *v) { T = M[T]; } +V st(ilo *v) { M[T] = N; SP -= 2; } +V ad(ilo *v) { N += T; SP -= 1; } +V su(ilo *v) { N -= T; SP -= 1; } +V mu(ilo *v) { N *= T; SP -= 1; } +V di(ilo *v) { A = T; B = N; + if (A == 0) { v->ok = 1; iof(v); return; } + T = B / A; N = B % A; + symmetric(v); } +V an(ilo *v) { N = T & N; SP -= 1; } +V or(ilo *v) { N = T | N; SP -= 1; } +V xo(ilo *v) { N = T ^ N; SP -= 1; } +V sl(ilo *v) { N = N << T; SP -= 1; } +V sr(ilo *v) { N = N >> T; SP -= 1; } +V cp(ilo *v) { L = pop(v); D = pop(v); S = T; T = -1; + while (L) { + if (M[D] != M[S]) { T = 0; } + L -= 1; S += 1; D += 1; } } +V cy(ilo *v) { L = pop(v); D = pop(v); S = pop(v); + while (L) { + M[D] = M[S]; + L -= 1; S += 1; D += 1; } } + +V pre(V) { cur -= 1; if (cur < 0) cur = ILOS - 1; } +V nxt(V) { cur += 1; if (cur > (ILOS - 1)) cur = 0; } + +V msgs(V) { printf("\n*** SWITCH TO %d ***\n", cur); } +V msgx(V) { printf("\n*** SHUTDOWN REQUESTED ***\n"); + exit(1); } +V msgr(V) { printf("\n*** RESTART %d ***\n", cur); } + +V term_putc(I c); + +V ioa(ilo *v) { term_putc(pop(v)); } +V iob(ilo *v) { redraw(); cursor(); + v->i[0] = wait_key(); push(v, v->i[0]); term_putc(T); + if (v->i[0] == 14) { T = 32; nxt(); msgs(); } + if (v->i[0] == 16) { T = 32; pre(); msgs(); } + if (v->i[0] == 3) { T = 32; msgr(); iof(v); + v->ok = 1; } + if (v->i[0] == 1) { T = 32; msgx(); } } +V ioc(ilo *v) { read_block(v); } +V iod(ilo *v) { write_block(v); } +V ioe(ilo *v) { save_image(v); } +V iof(ilo *v) { load_image(v); IP = -1; } +V iog(ilo *v) { iof(v); } +V ioh(ilo *v) { push(v, SP); push(v, RP); } +V iox(ilo *v) { I c = pop(v); I y = pop(v); I x = pop(v); + pixel(x, y, c); } +V ioy(ilo *v) { I y = pop(v); I x = pop(v); push(v, get_pixel(x, y)); } +V ioz(ilo *v) { I x, y, wx, wy, mask; Window w; + XQueryPointer(disp, win, &w, &w, &x, &y, &wx, &wy, &mask); + push(v, x); push(v, y); if (mask & Button1Mask) push(v, -1); else push(v, 0); } + +V io(ilo *v) { + switch (pop(v)) { + case 0: ioa(v); break; case 1: iob(v); break; + case 2: ioc(v); break; case 3: iod(v); break; + case 4: ioe(v); break; case 5: iof(v); break; + case 6: iog(v); break; case 7: ioh(v); break; + case 33: iox(v); break; case 34: ioy(v); break; + case 35: ioz(v); break; + default: break; + } +} + +V process(ilo *v, I o) { + switch (o) { + case 0: break; case 1: li(v); break; + case 2: du(v); break; case 3: dr(v); break; + case 4: sw(v); break; case 5: pu(v); break; + case 6: po(v); break; case 7: ju(v); break; + case 8: ca(v); break; case 9: cc(v); break; + case 10: cj(v); break; case 11: re(v); break; + case 12: eq(v); break; case 13: ne(v); break; + case 14: lt(v); break; case 15: gt(v); break; + case 16: fe(v); break; case 17: st(v); break; + case 18: ad(v); break; case 19: su(v); break; + case 20: mu(v); break; case 21: di(v); break; + case 22: an(v); break; case 23: or(v); break; + case 24: xo(v); break; case 25: sl(v); break; + case 26: sr(v); break; case 27: cp(v); break; + case 28: cy(v); break; case 29: io(v); break; + default: break; + } +} + +#define VALID(n) (v->ok == 0) && ((opcode >> n) & 0xFF) + +V execute() { + I opcode; + ilo *v = &systems[cur]; + while (IP < 65536) { + opcode = M[IP]; + v->ok = 0; + if (VALID(0)) process(v, opcode & 0xFF); + if (VALID(8)) process(v, (opcode >> 8) & 0xFF); + if (VALID(16)) process(v, (opcode >> 16) & 0xFF); + if (VALID(24)) process(v, (opcode >> 24) & 0xFF); + IP += 1; + v = &systems[cur]; + } +} + +V load_font(ilo *); + +I main(I argc, C **argv) { + ilo *v; + I i; + + cur = 0; + for (i = 0; i < ILOS; i++) { + v = &systems[i]; + v->blocks = (argc > 1) ? argv[1] : BLOCKS; + v->rom = (argc > 2) ? argv[2] : ROM; + load_image(v); + } + + load_font(&systems[0]); + + disp = XOpenDisplay(NULL); + win = XCreateSimpleWindow(disp, RootWindow(disp, 0), + 0, 0, FW, FH, 0, 0x0, 0x0); + XSelectInput(disp, win, ExposureMask | KeyPressMask | ButtonPressMask | ButtonReleaseMask); + XStoreName(disp, win, "x/ilo"); + gc = DefaultGC(disp, DefaultScreen(disp)); + XMapWindow(disp, win); + XFlush(disp); + XMoveWindow(disp, win, (DisplayWidth(disp, DefaultScreen(disp)) - FW) / 2, + (DisplayHeight(disp, DefaultScreen(disp)) - FH) / 2); + + execute(); + + XUnmapWindow(disp, win); + XDestroyWindow(disp, win); + XCloseDisplay(disp); + + return 0; +}